hotsheet 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,43 +1,43 @@
1
- "use strict";(()=>{var bn=Object.defineProperty;var kn=(e,t,n)=>t in e?bn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var ue=(e,t,n)=>kn(e,typeof t!="symbol"?t+"":t,n);var Pe=!1;function H(){Pe=!0}function bt(){let e=new Map;return document.querySelectorAll(".ticket-row[data-id], .column-card[data-id]").forEach(t=>{let n=t.dataset.id;e.set(n,t.getBoundingClientRect())}),e}function Ee(e){if(Pe){Pe=!1;return}e.size!==0&&document.querySelectorAll(".ticket-row[data-id], .column-card[data-id]").forEach(t=>{let n=t,a=n.dataset.id,o=e.get(a);if(!o)return;let i=n.getBoundingClientRect(),l=o.left-i.left,c=o.top-i.top;if(Math.abs(l)<1&&Math.abs(c)<1)return;n.style.transform=`translate(${l}px, ${c}px)`,n.offsetHeight,n.style.transition="transform 200ms ease-out",n.style.transform="";let d=()=>{n.style.transition=""};n.addEventListener("transitionend",d,{once:!0}),setTimeout(d,250)})}function v(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function kt(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function wt(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var J=class{constructor(t){ue(this,"__html");this.__html=t}toString(){return this.__html}};function D(e){return new J(e)}var wn=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function Re(e){return e==null||typeof e=="boolean"?"":e instanceof J?e.__html:typeof e=="string"?kt(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(Re).join(""):""}var En={className:"class",htmlFor:"for",httpEquiv:"http-equiv",acceptCharset:"accept-charset",accessKey:"accesskey",autoCapitalize:"autocapitalize",autoComplete:"autocomplete",autoFocus:"autofocus",autoPlay:"autoplay",colSpan:"colspan",contentEditable:"contenteditable",crossOrigin:"crossorigin",dateTime:"datetime",defaultChecked:"checked",defaultValue:"value",encType:"enctype",formAction:"formaction",formEncType:"formenctype",formMethod:"formmethod",formNoValidate:"formnovalidate",formTarget:"formtarget",hrefLang:"hreflang",inputMode:"inputmode",maxLength:"maxlength",minLength:"minlength",noModule:"nomodule",noValidate:"novalidate",readOnly:"readonly",referrerPolicy:"referrerpolicy",rowSpan:"rowspan",spellCheck:"spellcheck",srcDoc:"srcdoc",srcLang:"srclang",srcSet:"srcset",tabIndex:"tabindex",useMap:"usemap",strokeWidth:"stroke-width",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",strokeMiterlimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",fillOpacity:"fill-opacity",fillRule:"fill-rule",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",floodColor:"flood-color",floodOpacity:"flood-opacity",lightingColor:"lighting-color",stopColor:"stop-color",stopOpacity:"stop-opacity",shapeRendering:"shape-rendering",imageRendering:"image-rendering",textRendering:"text-rendering",pointerEvents:"pointer-events",vectorEffect:"vector-effect",paintOrder:"paint-order",fontFamily:"font-family",fontSize:"font-size",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",fontStretch:"font-stretch",textAnchor:"text-anchor",textDecoration:"text-decoration",dominantBaseline:"dominant-baseline",alignmentBaseline:"alignment-baseline",baselineShift:"baseline-shift",letterSpacing:"letter-spacing",wordSpacing:"word-spacing",writingMode:"writing-mode",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",markerStart:"marker-start",markerMid:"marker-mid",markerEnd:"marker-end",gradientUnits:"gradientUnits",gradientTransform:"gradientTransform",spreadMethod:"spreadMethod",patternUnits:"patternUnits",patternContentUnits:"patternContentUnits",patternTransform:"patternTransform",maskUnits:"maskUnits",maskContentUnits:"maskContentUnits",filterUnits:"filterUnits",primitiveUnits:"primitiveUnits",clipPathUnits:"clipPathUnits",xlinkHref:"xlink:href",xlinkShow:"xlink:show",xlinkActuate:"xlink:actuate",xlinkType:"xlink:type",xlinkRole:"xlink:role",xlinkTitle:"xlink:title",xlinkArcrole:"xlink:arcrole",xmlBase:"xml:base",xmlLang:"xml:lang",xmlSpace:"xml:space",xmlns:"xmlns",xmlnsXlink:"xmlns:xlink",stdDeviation:"stdDeviation",baseFrequency:"baseFrequency",numOctaves:"numOctaves",kernelMatrix:"kernelMatrix",surfaceScale:"surfaceScale",specularConstant:"specularConstant",specularExponent:"specularExponent",diffuseConstant:"diffuseConstant",pointsAtX:"pointsAtX",pointsAtY:"pointsAtY",pointsAtZ:"pointsAtZ",limitingConeAngle:"limitingConeAngle",tableValues:"tableValues"};function Tn(e,t){let n=En[e]??e;if(t==null||t===!1)return"";if(t===!0)return` ${n}`;let a;return t instanceof J?a=t.__html:typeof t=="number"?a=String(t):typeof t=="string"?a=wt(t):a="",` ${n}="${a}"`}function r(e,t){if(typeof e=="function")return e(t);let{children:n,...a}=t,o=Object.entries(a).map(([l,c])=>Tn(l,c)).join("");if(wn.has(e))return new J(`<${e}${o}>`);let i=n!=null?Re(n):"";return new J(`<${e}${o}>${i}</${e}>`)}function pe({children:e}){return new J(e!=null?Re(e):"")}function Et(e){document.getElementById("network-error-popup")?.remove();let t=v(r("div",{id:"network-error-popup",className:"error-popup",children:r("div",{className:"error-popup-content",children:[r("strong",{children:"Connection Error"}),r("p",{children:e}),r("button",{children:"Dismiss"})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function f(e,t={}){try{return(await fetch("/api"+e,{headers:t.body!==void 0?{"Content-Type":"application/json"}:{},method:t.method,body:t.body!==void 0?JSON.stringify(t.body):void 0})).json()}catch(n){throw Et("Unable to reach the server. It may have been stopped."),n}}async function Tt(e,t){try{let n=new FormData;return n.append("file",t),(await fetch("/api"+e,{method:"POST",body:n})).json()}catch(n){throw Et("Unable to reach the server. It may have been stopped."),n}}var xn={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},s={tickets:[],customViews:[],categories:[{id:"issue",label:"Issue",shortLabel:"ISS",color:"#6b7280",shortcutKey:"i",description:""},{id:"bug",label:"Bug",shortLabel:"BUG",color:"#ef4444",shortcutKey:"b",description:""},{id:"feature",label:"Feature",shortLabel:"FEA",color:"#22c55e",shortcutKey:"f",description:""},{id:"requirement_change",label:"Req Change",shortLabel:"REQ",color:"#f97316",shortcutKey:"r",description:""},{id:"task",label:"Task",shortLabel:"TSK",color:"#3b82f6",shortcutKey:"k",description:""},{id:"investigation",label:"Investigation",shortLabel:"INV",color:"#8b5cf6",shortcutKey:"g",description:""}],selectedIds:new Set,lastClickedId:null,activeTicketId:null,view:"all",layout:"list",sortBy:"created",sortDir:"desc",search:"",settings:{...xn},backupPreview:null},Ln='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20"/><path d="m8 18 4 4 4-4"/><path d="m8 6 4-4 4 4"/></svg>',In={highest:"\u2B06\u2B06",high:"\u2B06",default:Ln,low:"\u2B07",lowest:"\u2B07\u2B07"},Cn={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},xt='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 7 17l-5-5"/><path d="m22 10-7.5 7.5L13 16"/></svg>',Sn={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:xt,backlog:"\u25A1",archive:"\u25A0"},qe=xt;function C(e){return s.categories.find(n=>n.id===e)?.color||"#6b7280"}function K(e){return s.categories.find(n=>n.id===e)?.shortLabel||e.slice(0,3).toUpperCase()}function A(e){return In[e]||"\u2014"}function P(e){return Cn[e]||"#6b7280"}function z(e){return Sn[e]||"\u25CB"}function V(e){if(!e||e==="[]")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.filter(n=>typeof n=="string"&&n.trim())}catch{}return[]}function ge(e,t){let n=document.getElementById("detail-tags");if(n){n.innerHTML="";for(let a of e){let o=v(r("span",{className:"tag-chip",children:[a,t?null:r("button",{className:"tag-chip-remove","data-tag":a,title:"Remove tag",children:"\xD7"})]}));t||o.querySelector(".tag-chip-remove").addEventListener("click",async()=>{if(s.activeTicketId==null)return;let i=s.tickets.find(d=>d.id===s.activeTicketId);if(!i)return;let c=V(i.tags).filter(d=>d!==a);await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{tags:JSON.stringify(c)}}),i.tags=JSON.stringify(c),ge(c,!1)}),n.appendChild(o)}}}var Mn={not_started:"Not Started",started:"Started",completed:"Completed",verified:"Verified",backlog:"Backlog",archive:"Archive"},$n={highest:"Highest",high:"High",default:"Default",low:"Low",lowest:"Lowest"};function fe(e){let t=document.getElementById("detail-category");t.dataset.value=e;let n=s.categories.find(o=>o.id===e),a=C(e);t.innerHTML=`<span class="cat-dot" style="background:${a}"></span> ${n?.label||e}`}function Te(e){let t=document.getElementById("detail-priority");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon" style="color:${P(e)}">${A(e)}</span> ${$n[e]||e}`}function xe(e){let t=document.getElementById("detail-status");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon">${z(e)}</span> ${Mn[e]||e}`}function te(e){s.activeTicketId=e,Oe(e)}function Ct(){s.selectedIds.clear(),s.activeTicketId=null,ne();let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function ne(){let e=s.view==="trash",t=!!s.backupPreview?.active,n=document.getElementById("detail-panel"),a=document.getElementById("detail-resize-handle"),o=document.getElementById("detail-header"),i=document.getElementById("detail-body"),l=document.getElementById("detail-placeholder"),c=document.getElementById("detail-placeholder-text");if(e){n.style.display="none",a&&(a.style.display="none"),s.activeTicketId=null;return}if(n.style.display="flex",a&&(a.style.display=""),s.selectedIds.size===1){let d=Array.from(s.selectedIds)[0];n.classList.remove("detail-disabled"),o.style.display="",i.style.display="",l.style.display="none",s.activeTicketId!==d&&(s.activeTicketId=d,t?Nn(d):Oe(d))}else s.activeTicketId=null,n.classList.add("detail-disabled"),o.style.display="none",i.style.display="none",l.style.display="",s.selectedIds.size===0?c.textContent="Nothing selected":c.textContent=`${s.selectedIds.size} items selected`}function St(e){let t=document.getElementById("detail-title"),n=document.getElementById("detail-details"),a=document.getElementById("detail-category"),o=document.getElementById("detail-priority"),i=document.getElementById("detail-status"),l=document.getElementById("detail-upnext"),c=document.querySelector(".upload-btn");t.readOnly=e,n.readOnly=e,a.disabled=e,o.disabled=e,i.disabled=e,l.disabled=e,c&&(c.style.display=e?"none":"")}function Nn(e){let t=s.backupPreview?.tickets.find(l=>l.id===e);if(!t||s.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,fe(t.category),Te(t.priority),xe(t.status);let n=document.getElementById("detail-upnext");n.textContent=t.up_next?"\u2605":"\u2606",n.classList.toggle("active",t.up_next),document.getElementById("detail-details").value=t.details,St(!0),document.getElementById("detail-attachments").innerHTML="",ge(V(t.tags),!0);let a=document.getElementById("detail-notes"),o=Mt(t.notes);o.length>0?a.innerHTML=r(pe,{children:o.map(l=>r("div",{className:"note-entry",children:[l.created_at?r("div",{className:"note-timestamp",children:new Date(l.created_at).toLocaleString()}):null,r("div",{className:"note-text",children:l.text})]}))}).toString():a.innerHTML="";let i=document.getElementById("detail-meta");i.innerHTML=r(pe,{children:[r("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),r("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?r("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?r("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function ye(){s.activeTicketId!=null&&Oe(s.activeTicketId)}async function Oe(e){let t=await f(`/tickets/${e}`);if(s.activeTicketId!==e)return;St(!1),document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,fe(t.category),Te(t.priority),xe(t.status);let n=document.getElementById("detail-upnext");n.textContent=t.up_next?"\u2605":"\u2606",n.classList.toggle("active",t.up_next),document.getElementById("detail-details").value=t.details;let a=document.getElementById("detail-attachments");t.attachments.length>0?a.innerHTML=r(pe,{children:t.attachments.map(i=>r("div",{className:"attachment-item",children:[r("span",{className:"attachment-name",children:i.original_filename}),r("button",{className:"attachment-reveal","data-att-id":String(i.id),title:"Show in file manager",children:r("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:r("path",{d:"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"})})}),r("button",{className:"attachment-delete","data-att-id":String(i.id),title:"Remove",children:"\xD7"})]}))}).toString():a.innerHTML="",ge(V(t.tags),!1),Ue(t.id,Mt(t.notes));let o=document.getElementById("detail-meta");o.innerHTML=r(pe,{children:[r("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),r("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?r("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?r("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function Lt(e,t){let n=s.tickets.find(a=>a.id===e);n&&(n.notes=JSON.stringify(t))}function Ue(e,t){let n=document.getElementById("detail-notes");if(n){if(n.innerHTML="",t.length===0){n.innerHTML='<div class="notes-empty">No notes added</div>';return}for(let a of t){let o=v(r("div",{className:"note-entry",children:[a.created_at?r("div",{className:"note-timestamp",children:new Date(a.created_at).toLocaleString()}):null,r("div",{className:"note-text",children:a.text})]}));o.addEventListener("click",()=>{let i=o.querySelector(".note-text");if(o.querySelector(".note-edit-area"))return;let l=document.createElement("textarea");l.className="note-edit-area",l.value=a.text,l.rows=3,i.style.display="none",o.appendChild(l),l.focus();let c=async()=>{let d=l.value.trim();if(d&&d!==a.text){let u=s.tickets.find(m=>m.id===e),p=t.map(m=>m.id===a.id?{...m,text:d}:m);u&&me(u,"Edit note",JSON.stringify(p)),await f(`/tickets/${e}/notes/${a.id}`,{method:"PATCH",body:{text:d}}),a.text=d,Lt(e,t)}Ue(e,t)};l.addEventListener("blur",()=>{c()}),l.addEventListener("keydown",d=>{d.key==="Enter"&&(d.metaKey||d.ctrlKey)&&(d.preventDefault(),c()),d.key==="Escape"&&(d.stopPropagation(),l.blur())})}),o.addEventListener("contextmenu",i=>{i.preventDefault(),document.querySelectorAll(".note-context-menu").forEach(c=>c.remove());let l=v(r("div",{className:"note-context-menu context-menu",style:`top:${i.clientY}px;left:${i.clientX}px`,children:r("div",{className:"context-menu-item danger",children:r("span",{className:"context-menu-label",children:"Delete Note"})})}));l.querySelector(".context-menu-item").addEventListener("click",async c=>{c.stopPropagation(),l.remove();let d=s.tickets.find(m=>m.id===e),u=t.filter(m=>m.id!==a.id);d&&me(d,"Delete note",JSON.stringify(u)),await f(`/tickets/${e}/notes/${a.id}`,{method:"DELETE"});let p=t.indexOf(a);p>=0&&t.splice(p,1),Lt(e,t),Ue(e,t)}),document.body.appendChild(l),setTimeout(()=>{let c=()=>{l.remove(),document.removeEventListener("click",c)};document.addEventListener("click",c)},0)}),n.appendChild(o)}}}var Bn=0;function It(){return`cn_${Date.now().toString(36)}_${(Bn++).toString(36)}`}function Mt(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.map(n=>({id:n.id||It(),text:n.text,created_at:n.created_at}))}catch{}return e.trim()?[{id:It(),text:e,created_at:""}]:[]}async function Le(){try{let e=await f("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function Ve(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function Ke(){let e=document.getElementById("detail-panel");s.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${s.settings.detail_height}px`):(e.style.height="",e.style.width=`${s.settings.detail_width}px`)}function $t(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),n=document.getElementById("content-area"),a=!1;e.addEventListener("mousedown",o=>{o.preventDefault(),a=!0,document.body.style.cursor=s.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",o=>{if(!a)return;let i=n.getBoundingClientRect();if(s.settings.detail_position==="bottom"){let l=Math.max(150,Math.min(500,i.bottom-o.clientY));s.settings.detail_height=l,t.style.height=`${l}px`}else{let l=Math.max(250,Math.min(600,i.right-o.clientX));s.settings.detail_width=l,t.style.width=`${l}px`}}),document.addEventListener("mouseup",()=>{a&&(a=!1,document.body.style.cursor="",document.body.style.userSelect="",s.settings.detail_position==="bottom"?f("/settings",{method:"PATCH",body:{detail_height:String(s.settings.detail_height)}}):f("/settings",{method:"PATCH",body:{detail_width:String(s.settings.detail_width)}}))})}var ze=class{constructor(){ue(this,"undoStack",[]);ue(this,"redoStack",[])}push(t){console.log("[undo] push:",t.label,"stack depth:",this.undoStack.length+1,"before:",JSON.stringify(t.before),"after:",JSON.stringify(t.after)),this.undoStack.push(t),this.undoStack.length>1e3&&this.undoStack.shift(),this.redoStack=[]}coalesce(t){if(t.coalescingKey==null||t.coalescingKey==="")return!1;let n=this.peekUndo();return!n||n.coalescingKey!==t.coalescingKey||t.timestamp-n.timestamp>=5e3?!1:(n.after=t.after,!0)}popUndo(){let t=this.undoStack.pop();return t&&this.redoStack.push(t),t}popRedo(){let t=this.redoStack.pop();return t&&this.undoStack.push(t),t}peekUndo(){return this.undoStack[this.undoStack.length-1]}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}},M=new ze;function F(e,t=!1){let n={id:e.id,title:e.title,details:e.details,category:e.category,priority:e.priority,status:e.status,up_next:e.up_next};return t&&(n.notes=e.notes),n}async function R(e,t,n){let a=F(e),o=await f(`/tickets/${e.id}`,{method:"PATCH",body:t}),i=F(o);return M.push({label:n,timestamp:Date.now(),before:[a],after:[i]}),o}function Ie(e,t,n){let a=`${e.id}:${t}`,o=Date.now(),i={...F(e),[t]:n},l={label:`Edit ${t}`,timestamp:o,before:[F(e)],after:[i],coalescingKey:a};M.coalesce(l)||M.push(l)}async function I(e,t,n){let a=e.map(i=>F(i));await f("/tickets/batch",{method:"POST",body:t});let o=a.map(i=>{let l={...i};return t.action==="category"?l.category=t.value:t.action==="priority"?l.priority=t.value:t.action==="status"?l.status=t.value:t.action==="up_next"?l.up_next=t.value:t.action==="delete"&&(l.status="deleted"),l});M.push({label:n,timestamp:Date.now(),before:a,after:o})}async function Fe(e,t,n){let a=e.map(i=>F(i));for(let i of t)await f("/tickets/batch",{method:"POST",body:i});let o=a.map(i=>{let l={...i};for(let c of t)c.ids.includes(i.id)&&(c.action==="status"?l.status=c.value:c.action==="up_next"?l.up_next=c.value:c.action==="category"?l.category=c.value:c.action==="priority"?l.priority=c.value:c.action==="delete"&&(l.status="deleted"));return l});M.push({label:n,timestamp:Date.now(),before:a,after:o})}async function Ce(e){let t=F(e);await f(`/tickets/${e.id}`,{method:"DELETE"});let n={...t,status:"deleted"};M.push({label:"Delete ticket",timestamp:Date.now(),before:[t],after:[n]})}async function Nt(e){let t=F(e);await f(`/tickets/${e.id}/restore`,{method:"POST"});let n={...t,status:"not_started"};M.push({label:"Restore ticket",timestamp:Date.now(),before:[t],after:[n]})}async function Bt(e){for(let t of e)t.status==="deleted"?await f(`/tickets/${t.id}`,{method:"DELETE"}):(await f(`/tickets/${t.id}`,{method:"PATCH",body:{title:t.title,details:t.details,category:t.category,priority:t.priority,status:t.status,up_next:t.up_next}}),t.notes!==void 0&&await f(`/tickets/${t.id}/notes-bulk`,{method:"PUT",body:{notes:t.notes}}))}var Y=!1;async function _t(){if(console.log("[undo] performUndo, inFlight:",Y,"canUndo:",M.canUndo()),Y){console.log("[undo] skipped \u2014 already in flight");return}let e=M.popUndo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying before-state:",e.label,JSON.stringify(e.before)),Y=!0;try{await Bt(e.before),console.log("[undo] applySnapshots done, reloading tickets"),await w(),setTimeout(()=>ye(),50)}finally{Y=!1}}async function Ht(){if(console.log("[undo] performRedo, inFlight:",Y,"canRedo:",M.canRedo()),Y){console.log("[undo] skipped \u2014 already in flight");return}let e=M.popRedo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying after-state:",e.label,JSON.stringify(e.after)),Y=!0;try{await Bt(e.after),console.log("[undo] applySnapshots done, reloading tickets"),await w(),setTimeout(()=>ye(),50)}finally{Y=!1}}function me(e,t,n){let a=F(e,!0),o={...F(e,!0),notes:n};M.push({label:t,timestamp:Date.now(),before:[a],after:[o]})}function Dt(){return M.canUndo()}function At(){return M.canRedo()}function Je(e,t){e.preventDefault(),G(),s.selectedIds.has(t.id)||(s.selectedIds.clear(),s.selectedIds.add(t.id),s.lastClickedId=t.id,L());let n=v(r("div",{className:"context-menu",style:`top:${e.clientY}px;left:${e.clientX}px`}));We(n,"Category",s.categories.map(i=>({label:i.label,icon:`<span class="dropdown-dot" style="background-color:${i.color}"></span>`,active:t.category===i.id,action:()=>ae("category",i.id)}))),We(n,"Priority",[{value:"highest",label:"Highest"},{value:"high",label:"High"},{value:"default",label:"Default"},{value:"low",label:"Low"},{value:"lowest",label:"Lowest"}].map(i=>({label:i.label,icon:A(i.value),iconColor:P(i.value),active:t.priority===i.value,action:()=>ae("priority",i.value)}))),We(n,"Status",[{value:"not_started",label:"Not Started"},{value:"started",label:"Started"},{value:"completed",label:"Completed"},{value:"verified",label:"Verified"}].map(i=>({label:i.label,icon:z(i.value),active:t.status===i.value,action:()=>ae("status",i.value)}))),se(n,t.up_next?"\u2605 Up Next":"\u2606 Up Next",()=>{ae("up_next",!t.up_next)}),je(n),se(n,"Tags...",()=>{document.dispatchEvent(new CustomEvent("hotsheet:show-tags-dialog"))}),se(n,"Duplicate",async()=>{let i=Array.from(s.selectedIds),l=await f("/tickets/duplicate",{method:"POST",body:{ids:i}});s.selectedIds.clear();for(let c of l)s.selectedIds.add(c.id);w()}),je(n),se(n,"Move to Backlog",()=>ae("status","backlog")),se(n,"Archive",()=>ae("status","archive")),je(n),se(n,"Delete",async()=>{if(s.selectedIds.size===1)await Ce(t);else{let i=Array.from(s.selectedIds),l=s.tickets.filter(c=>s.selectedIds.has(c.id));await I(l,{ids:i,action:"delete"},"Delete")}s.selectedIds.clear(),w()},!0),document.body.appendChild(n),_n(n),setTimeout(()=>{document.addEventListener("click",G),document.addEventListener("contextmenu",G)},0)}function G(){document.querySelectorAll(".context-menu").forEach(e=>e.remove()),document.removeEventListener("click",G),document.removeEventListener("contextmenu",G)}function _n(e){let t=e.getBoundingClientRect();t.right>window.innerWidth-8&&(e.style.left=`${window.innerWidth-t.width-8}px`),t.bottom>window.innerHeight-8&&(e.style.top=`${window.innerHeight-t.height-8}px`)}async function ae(e,t){let n=Array.from(s.selectedIds),a=s.tickets.filter(o=>s.selectedIds.has(o.id));if(n.length===1){let o=a[0];await R(o,{[e]:t},`Change ${e}`)}else await I(a,{ids:n,action:e,value:t},`Change ${e}`);w()}function We(e,t,n){let a=v(r("div",{className:"context-menu-item has-submenu",children:[r("span",{className:"context-menu-label",children:t}),r("span",{className:"context-menu-arrow",children:"\u25B8"})]})),o=v(r("div",{className:"context-submenu"}));for(let i of n){let l=v(r("div",{className:`context-menu-item${i.active?" active":""}`,children:[i.icon?r("span",{className:"dropdown-icon",style:i.iconColor?`color:${i.iconColor}`:"",children:D(i.icon)}):null,r("span",{className:"context-menu-label",children:i.label})]}));l.addEventListener("click",c=>{c.stopPropagation(),i.action(),G()}),o.appendChild(l)}a.appendChild(o),e.appendChild(a)}function se(e,t,n,a=!1){let o=v(r("div",{className:`context-menu-item${a?" danger":""}`,children:r("span",{className:"context-menu-label",children:t})}));o.addEventListener("click",i=>{i.stopPropagation(),G(),n()}),e.appendChild(o)}function je(e){e.appendChild(v(r("div",{className:"context-menu-separator"})))}function $(e,t){let n=t.getBoundingClientRect(),a=e.getBoundingClientRect(),o=window.innerWidth,i=window.innerHeight,l=n.left;l+a.width>o-8&&(l=n.right-a.width),l<8&&(l=8);let c=n.bottom+4;c+a.height>i-8&&(c=n.top-a.height-4),c<8&&(c=8),e.style.left=`${l}px`,e.style.top=`${c}px`}function N(e,t){let n=v(r("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(d=>d.separator?r("div",{className:"dropdown-separator"}):r("button",{className:`dropdown-item${d.active?" active":""}`,"data-key":d.key,children:[d.color?r("span",{className:"dropdown-dot",style:`background-color:${d.color}`}):null,d.icon?r("span",{className:"dropdown-icon",style:d.iconColor?`color:${d.iconColor}`:"",children:D(d.icon)}):null,r("span",{className:"dropdown-label",children:d.label}),d.shortcut?r("kbd",{className:"dropdown-kbd",children:d.shortcut}):null]}))})),a=t.filter(d=>!d.separator);n.querySelectorAll(".dropdown-item").forEach((d,u)=>{d.addEventListener("click",()=>{a[u].action(),n.remove()})});function i(d){let u=t.find(p=>d.key.toLowerCase()===p.key.toLowerCase());u?(d.preventDefault(),d.stopPropagation(),u.action(),l()):d.key==="Escape"&&(d.preventDefault(),l())}function l(){n.remove(),document.removeEventListener("keydown",i,!0),document.removeEventListener("click",c)}function c(){l()}return document.addEventListener("keydown",i,!0),setTimeout(()=>{document.addEventListener("click",c)},0),n}function B(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var oe=null;function Ge(){oe&&(clearTimeout(oe),oe=null)}var ve=!1,he=null,Ye="",U=[];function Se(){return s.categories.map(e=>({key:e.shortcutKey,value:e.id,label:e.label}))}var Xe=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}];function Hn(){let e=document.activeElement;if(!e||!(e instanceof HTMLElement))return null;let t=e.closest(".ticket-row");if(!t)return null;if(t.classList.contains("draft-row"))return"draft";let n=t.dataset.id;return n!==void 0&&n!==""?parseInt(n,10):null}function Dn(e){e!=null&&(ve=!0,e==="draft"?W():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),ve=!1)}function Me(){let e=s.view;return e.startsWith("custom:")?!0:e!=="completed"&&e!=="verified"&&e!=="trash"&&e!=="backlog"&&e!=="archive"}function qt(){return s.view==="up-next"||s.view==="open"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"}]:s.view==="non-verified"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"},{status:"completed",label:"Completed"}]:[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"},{status:"completed",label:"Completed"},{status:"verified",label:"Verified"}]}function L(){let e=bt(),t=!!s.backupPreview?.active;if(s.layout==="columns"&&Me()){if(t){Pn(),Ee(e);return}qn(),Ee(e);return}let n=s.view==="trash",a=t?null:Hn(),o=null;if(a!=null&&a!=="draft"){let c=document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`);c&&(o=c.value)}let i=document.getElementById("ticket-list"),l=i.scrollTop;if(i.innerHTML="",i.classList.remove("ticket-list-columns"),!n&&!t&&i.appendChild(Kt()),s.tickets.length===0){let c=n?"Trash is empty":t?"No tickets match this view":"";c&&i.appendChild(v(r("div",{className:"ticket-list-empty",children:c})))}for(let c of s.tickets)t?i.appendChild(An(c)):n?i.appendChild(zn(c)):i.appendChild(Kn(c));if(i.scrollTop=l,t){let c=document.getElementById("batch-toolbar");c&&(c.style.display="none"),be(),ne()}else{let c=document.getElementById("batch-toolbar");if(c&&(c.style.display=""),a!=null&&a!=="draft"&&o!=null){let d=document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`);d&&d.value!==o&&(d.value=o)}Dn(a),ie()}Le(),Ee(e)}function An(e){let t=s.selectedIds.has(e.id),n=e.status==="completed"||e.status==="verified",a=e.status==="verified",o=v(r("div",{className:`ticket-row${t?" selected":""}${n?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("span",{className:"ticket-checkbox-spacer"}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)};cursor:default`,title:e.category,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:`ticket-status-btn${a?" verified":""}`,style:"cursor:default",children:D(a?qe:z(e.status))}),r("span",{className:"ticket-title-input",style:"cursor:default",children:e.title}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,title:e.priority,children:D(A(e.priority))}),r("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}));return o.addEventListener("click",()=>{s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),ne()}),o}function Ut(e){let t={scrollLeft:0,columns:{}},n=e.querySelector(".columns-container");return n&&(t.scrollLeft=n.scrollLeft,n.querySelectorAll(".column[data-status]").forEach(a=>{let o=a.dataset.status,i=a.querySelector(".column-body");i&&(t.columns[o]=i.scrollTop)})),t}function Ot(e,t){let n=e.querySelector(".columns-container");n&&(n.scrollLeft=t.scrollLeft,n.querySelectorAll(".column[data-status]").forEach(a=>{let o=a.dataset.status,i=a.querySelector(".column-body");i&&t.columns[o]!=null&&(i.scrollTop=t.columns[o])}))}function Pn(){let e=document.getElementById("ticket-list"),t=Ut(e);e.innerHTML="",e.classList.add("ticket-list-columns");let n=qt(),a=v(r("div",{className:"columns-container"}));for(let i of n){let l=s.tickets.filter(u=>u.status===i.status),c=v(r("div",{className:"column","data-status":i.status,children:[r("div",{className:"column-header",children:[r("span",{className:"column-title",children:i.label}),r("span",{className:"column-count",children:String(l.length)})]}),r("div",{className:"column-body"})]})),d=c.querySelector(".column-body");for(let u of l)d.appendChild(Rn(u));a.appendChild(c)}e.appendChild(a),Ot(e,t);let o=document.getElementById("batch-toolbar");o&&(o.style.display="none"),Le()}function Rn(e){let t=s.selectedIds.has(e.id),n=v(r("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("div",{className:"column-card-header",children:[r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,children:D(A(e.priority))}),r("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}),r("div",{className:"column-card-title",children:e.title})]}));return n.addEventListener("click",()=>{s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,Vt(),ne()}),n}function qn(){let e=document.getElementById("ticket-list"),t=Ut(e);e.innerHTML="",e.classList.add("ticket-list-columns"),e.appendChild(Kt());let n=qt(),a=v(r("div",{className:"columns-container"}));for(let o of n){let i=s.tickets.filter(d=>d.status===o.status),l=v(r("div",{className:"column","data-status":o.status,children:[r("div",{className:"column-header",children:[r("span",{className:"column-title",children:o.label}),r("span",{className:"column-count",children:String(i.length)})]}),r("div",{className:"column-body"})]})),c=l.querySelector(".column-body");for(let d of i)c.appendChild(Un(d));c.addEventListener("dragover",d=>{d.preventDefault(),d.dataTransfer.dropEffect="move",l.classList.add("column-drop-target")}),c.addEventListener("dragleave",d=>{let u=d.relatedTarget;(!u||!c.contains(u))&&l.classList.remove("column-drop-target")}),c.addEventListener("drop",d=>{d.preventDefault(),l.classList.remove("column-drop-target");let u=U;if(U=[],u.length===0)return;let p=s.tickets.filter(m=>u.includes(m.id));H(),I(p,{ids:u,action:"status",value:o.status},"Change status").then(()=>{w()})}),a.appendChild(l)}e.appendChild(a),Ot(e,t),ie(),Le()}function Un(e){let t=s.selectedIds.has(e.id),n=v(r("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("div",{className:"column-card-header",children:[r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,children:D(A(e.priority))}),r("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}),r("div",{className:"column-card-title",children:e.title})]})),a=n.querySelector(".ticket-category-badge");a.addEventListener("click",i=>{i.stopPropagation(),jt(a,e)});let o=n.querySelector(".ticket-priority-indicator");return o.addEventListener("click",i=>{i.stopPropagation(),Jt(o,e)}),n.querySelector(".ticket-star").addEventListener("click",i=>{i.stopPropagation(),Wt(e)}),n.addEventListener("contextmenu",i=>{Je(i,e)}),n.draggable=!0,n.addEventListener("dragstart",i=>{s.selectedIds.has(e.id)&&s.selectedIds.size>1?U=Array.from(s.selectedIds):U=[e.id],i.dataTransfer.setData("text/plain",JSON.stringify(U)),i.dataTransfer.effectAllowed="move"}),n.addEventListener("dragend",()=>{U=[]}),n.addEventListener("click",i=>{if(i.metaKey||i.ctrlKey)s.selectedIds.has(e.id)?s.selectedIds.delete(e.id):s.selectedIds.add(e.id),s.lastClickedId=e.id;else if(i.shiftKey&&s.lastClickedId!=null){let l=s.tickets.find(c=>c.id===s.lastClickedId);if(l&&l.status===e.status){let d=s.tickets.filter(m=>m.status===e.status).map(m=>m.id),u=d.indexOf(s.lastClickedId),p=d.indexOf(e.id);if(u!==-1&&p!==-1){let m=Math.min(u,p),g=Math.max(u,p);s.selectedIds.clear();for(let y=m;y<=g;y++)s.selectedIds.add(d[y])}}else s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id}else s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id;Vt(),ie()}),n}function Vt(){document.querySelectorAll(".column-card[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10);s.selectedIds.has(t)?e.classList.add("selected"):e.classList.remove("selected")})}function Kt(){let e=zt(),t=s.view.startsWith("category:"),n=v(r("div",{className:"ticket-row draft-row",children:[r("span",{className:"ticket-checkbox-spacer"}),r("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),r("span",{className:"ticket-category-badge draft-badge",style:`background-color:${C(e)}${t?"":";cursor:pointer;opacity:1"}`,children:K(e)}),r("span",{className:"ticket-number draft-number"}),r("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket...",value:Ye}),r("span",{className:"ticket-priority-indicator draft-placeholder"}),r("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let o=n.querySelector(".ticket-category-badge");o.addEventListener("click",i=>{i.stopPropagation(),Vn(o)})}let a=n.querySelector(".draft-input");return a.addEventListener("input",()=>{Ye=a.value}),a.addEventListener("keydown",async o=>{if(o.key==="Enter"&&a.value.trim()){o.preventDefault();let i=a.value.trim();Ye="",a.value="";let l=On();he&&!s.view.startsWith("category:")&&(l.category=he);let c=await f("/tickets",{method:"POST",body:{title:i,defaults:l}});c&&(s.selectedIds.clear(),s.selectedIds.add(c.id)),await w(),W()}else o.key==="ArrowDown"&&(o.preventDefault(),s.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${s.tickets[0].id}"] .ticket-title-input`)?.focus())}),n}function W(){document.querySelector(".draft-row .draft-input")?.focus()}function On(){let e=s.view;return e==="up-next"?{up_next:!0}:e==="open"?{}:e==="completed"?{status:"completed"}:e==="backlog"?{status:"backlog"}:e==="archive"?{status:"archive"}:e.startsWith("category:")?{category:e.split(":")[1]}:e.startsWith("priority:")?{priority:e.split(":")[1]}:{}}function zt(){if(he)return he;let e=s.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function Vn(e){B();let n=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=zt(),o=N(e,Se().map(i=>({label:i.label,key:i.key,shortcut:`${n}${i.key.toUpperCase()}`,color:C(i.value),active:a===i.value,action:()=>{he=i.value,L(),W()}})));document.body.appendChild(o),$(o,e),o.style.visibility=""}function Kn(e){let t=s.selectedIds.has(e.id),n=e.status==="completed"||e.status==="verified",a=e.status==="verified",o=v(r("div",{className:`ticket-row${t?" selected":""}${n?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,title:e.category,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("button",{className:`ticket-status-btn${a?" verified":""}`,title:e.status.replace("_"," "),children:D(a?qe:z(e.status))}),r("input",{type:"text",className:"ticket-title-input",value:e.title}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,title:e.priority,children:D(A(e.priority))}),r("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}));o.addEventListener("mousedown",u=>{let p=u.target;p.tagName!=="INPUT"&&p.tagName!=="BUTTON"&&(o.draggable=!0)}),o.addEventListener("mouseup",()=>{o.draggable=!1}),o.addEventListener("dragend",()=>{o.draggable=!1,U=[]}),o.addEventListener("contextmenu",u=>{Je(u,e)}),o.addEventListener("dragstart",u=>{s.selectedIds.has(e.id)&&s.selectedIds.size>1?U=Array.from(s.selectedIds):U=[e.id],u.dataTransfer.setData("text/plain",JSON.stringify(U)),u.dataTransfer.effectAllowed="move"}),o.addEventListener("mousedown",u=>{(u.metaKey||u.ctrlKey||u.shiftKey)&&(u.preventDefault(),Ft(u,e)&&u.stopPropagation())});let i=o.querySelector(".ticket-checkbox");i.addEventListener("click",u=>u.stopPropagation()),i.addEventListener("change",()=>{i.checked?s.selectedIds.add(e.id):s.selectedIds.delete(e.id),s.lastClickedId=e.id,L()}),o.querySelector(".ticket-status-btn").addEventListener("click",u=>{u.stopPropagation(),Jn(e)});let l=o.querySelector(".ticket-category-badge");l.addEventListener("click",u=>{u.stopPropagation(),jt(l,e)});let c=o.querySelector(".ticket-title-input");c.addEventListener("focus",()=>{ve||s.selectedIds.size===1&&s.selectedIds.has(e.id)||(s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),ie())}),c.addEventListener("input",()=>{Ie(e,"title",c.value),Xn(e.id,{title:c.value})}),c.addEventListener("keydown",u=>{Fn(u,e,c)});let d=o.querySelector(".ticket-priority-indicator");return d.addEventListener("click",u=>{u.stopPropagation(),Jt(d,e)}),o.querySelector(".ticket-star").addEventListener("click",u=>{u.stopPropagation(),Wt(e)}),o}function zn(e){let t=s.selectedIds.has(e.id),n=e.deleted_at?new Date(e.deleted_at):null,a=v(r("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[r("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),r("span",{className:"ticket-number",title:n?`Deleted: ${n.toLocaleString()}`:"",children:n?n.toLocaleDateString():""}),r("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));a.addEventListener("mousedown",i=>{(i.metaKey||i.ctrlKey||i.shiftKey)&&(i.preventDefault(),Ft(i,e)&&i.stopPropagation())});let o=a.querySelector(".ticket-checkbox");return o.addEventListener("click",i=>i.stopPropagation()),o.addEventListener("change",()=>{o.checked?s.selectedIds.add(e.id):s.selectedIds.delete(e.id),s.lastClickedId=e.id,L()}),a.querySelector(".trash-title").addEventListener("click",()=>{s.selectedIds.size===1&&s.selectedIds.has(e.id)||(s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),ie())}),a.querySelector(".btn").addEventListener("click",async i=>{i.stopPropagation(),await Nt(e),w()}),a}function Ft(e,t){let n=e.metaKey||e.ctrlKey,a=e.shiftKey;if(n)s.selectedIds.has(t.id)?s.selectedIds.delete(t.id):s.selectedIds.add(t.id),s.lastClickedId=t.id,L();else if(a&&s.lastClickedId!=null){let o=s.tickets.map(c=>c.id),i=o.indexOf(s.lastClickedId),l=o.indexOf(t.id);if(i!==-1&&l!==-1){let c=Math.min(i,l),d=Math.max(i,l);s.selectedIds.clear();for(let u=c;u<=d;u++)s.selectedIds.add(o[u])}L()}else return!1;return!0}function Fn(e,t,n){if(e.key==="Enter")e.preventDefault(),W();else if(e.key==="Backspace"&&n.value==="")e.preventDefault(),Yn(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),Pt(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),Pt(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),Wn(t.id);else if(e.key==="ArrowUp")e.preventDefault(),jn(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&Se().some(a=>a.key===e.key)){e.preventDefault();let a=Se().find(o=>o.key===e.key);Rt(t,"category",a.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&Xe.some(a=>a.key===e.key)){e.preventDefault();let a=Xe.find(o=>o.key===e.key);Rt(t,"priority",a.value)}}function Wn(e){let t=s.tickets.findIndex(n=>n.id===e);t<s.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${s.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function jn(e){let t=s.tickets.findIndex(n=>n.id===e);t>0?document.querySelector(`.ticket-row[data-id="${s.tickets[t-1].id}"] .ticket-title-input`)?.focus():W()}function Pt(e,t){let a=s.tickets.findIndex(l=>l.id===e)+t;if(a<0||a>=s.tickets.length)return;let o=s.tickets[a].id;s.selectedIds.add(e),s.selectedIds.has(o)?s.selectedIds.delete(e):s.selectedIds.add(o),ve=!0,document.querySelector(`.ticket-row[data-id="${o}"] .ticket-title-input`)?.focus(),ve=!1,be(),ie()}async function Jn(e){let n={not_started:"started",started:"completed",completed:"verified",verified:"not_started",backlog:"not_started",archive:"not_started"}[e.status]||"not_started",a=await R(e,{status:n},"Change status");Object.assign(e,a),L()}async function Wt(e){!e.up_next&&(e.status==="completed"||e.status==="verified")?await R(e,{status:"not_started",up_next:!0},"Toggle up next"):await R(e,{up_next:!e.up_next},"Toggle up next"),w(),document.dispatchEvent(new CustomEvent("hotsheet:upnext-changed"))}async function Rt(e,t,n){let a=await R(e,{[t]:n},`Change ${t}`);Object.assign(e,a),L()}async function Yn(e){let t=s.tickets.findIndex(a=>a.id===e),n=s.tickets.find(a=>a.id===e);if(n?await Ce(n):await f(`/tickets/${e}`,{method:"DELETE"}),s.tickets=s.tickets.filter(a=>a.id!==e),s.selectedIds.delete(e),L(),t>0&&s.tickets.length>0){let a=Math.min(t-1,s.tickets.length-1);document.querySelector(`.ticket-row[data-id="${s.tickets[a].id}"] .ticket-title-input`)?.focus()}else W()}function Xn(e,t){oe&&clearTimeout(oe),oe=setTimeout(()=>{f(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function jt(e,t){B();let a=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",o=N(e,Se().map(i=>({label:i.label,key:i.key,shortcut:`${a}${i.key.toUpperCase()}`,color:C(i.value),active:t.category===i.value,action:async()=>{let l=await R(t,{category:i.value},"Change category");Object.assign(t,l),L()}})));document.body.appendChild(o),$(o,e),o.style.visibility=""}function Jt(e,t){B();let n=N(e,Xe.map(a=>({label:a.label,key:a.key,shortcut:`Alt+${a.key}`,icon:A(a.value),iconColor:P(a.value),active:t.priority===a.value,action:async()=>{let o=await R(t,{priority:a.value},"Change priority");Object.assign(t,o),L()}})));document.body.appendChild(n),$(n,e),n.style.visibility=""}function be(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),n=e.querySelector(".ticket-checkbox");s.selectedIds.has(t)?(e.classList.add("selected"),n&&(n.checked=!0)):(e.classList.remove("selected"),n&&(n.checked=!1))})}function ie(){let e=s.selectedIds.size,t=s.tickets.length,n=e>0,a=s.view==="trash",o=document.getElementById("batch-select-all");o.checked=t>0&&e===t,o.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=n?`${e} selected`:"";let i=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete","batch-more"];for(let p of i){let m=document.getElementById(p);m.style.display=a?"none":"",a||(m.disabled=!n)}let l=document.getElementById("batch-restore"),c=document.getElementById("batch-empty-trash");if(a){let p=document.getElementById("batch-toolbar");l||(l=v(r("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),l.addEventListener("click",async()=>{await f("/tickets/batch",{method:"POST",body:{ids:Array.from(s.selectedIds),action:"restore"}}),s.selectedIds.clear(),w()}),p.insertBefore(l,document.getElementById("batch-count"))),l.disabled=!n,l.style.display="",c||(c=v(r("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),c.addEventListener("click",async()=>{await f("/trash/empty",{method:"POST"}),s.selectedIds.clear(),w()}),p.insertBefore(c,document.getElementById("batch-count"))),c.disabled=t===0,c.style.display=""}else l&&(l.style.display="none"),c&&(c.style.display="none");let d=document.querySelector(".batch-star-icon"),u=document.getElementById("batch-upnext");if(!a&&d&&n){let p=s.tickets.filter(y=>s.selectedIds.has(y.id)),m=p.every(y=>y.up_next),g=p.every(y=>!y.up_next);m?(d.textContent="\u2605",u.classList.add("active"),u.classList.remove("mixed")):g?(d.textContent="\u2606",u.classList.remove("active","mixed")):(d.innerHTML=r("span",{className:"star-mixed-wrap",children:[r("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),u.classList.remove("active"),u.classList.add("mixed"))}else d&&(d.textContent="\u2606",u.classList.remove("active","mixed"));ne()}async function w(){if(s.backupPreview?.active){Gn();return}if(s.view.startsWith("custom:")){let n=s.view.slice(7),a=s.customViews.find(o=>o.id===n);a?s.tickets=await f("/tickets/query",{method:"POST",body:{logic:a.logic,conditions:a.conditions,sort_by:s.sortBy,sort_dir:s.sortDir}}):s.tickets=[],L();return}let e=new URLSearchParams;s.view==="trash"?e.set("status","deleted"):s.view==="up-next"?e.set("up_next","true"):s.view==="open"?e.set("status","open"):s.view==="completed"?e.set("status","completed"):s.view==="non-verified"?e.set("status","non_verified"):s.view==="verified"?e.set("status","verified"):s.view==="backlog"?e.set("status","backlog"):s.view==="archive"?e.set("status","archive"):s.view.startsWith("category:")?e.set("category",s.view.split(":")[1]):s.view.startsWith("priority:")?e.set("priority",s.view.split(":")[1]):e.set("status","active"),s.search&&e.set("search",s.search),e.set("sort_by",s.sortBy),e.set("sort_dir",s.sortDir);let t=e.toString();s.tickets=await f(`/tickets${t?"?"+t:""}`),L()}function Gn(){let e=[...s.backupPreview?.tickets||[]];if(s.view==="trash")e=e.filter(t=>t.status==="deleted");else if(s.view==="up-next")e=e.filter(t=>t.up_next&&t.status!=="deleted");else if(s.view==="open")e=e.filter(t=>t.status==="not_started"||t.status==="started");else if(s.view==="completed")e=e.filter(t=>t.status==="completed");else if(s.view==="non-verified")e=e.filter(t=>t.status!=="verified"&&t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");else if(s.view==="verified")e=e.filter(t=>t.status==="verified");else if(s.view==="backlog")e=e.filter(t=>t.status==="backlog");else if(s.view==="archive")e=e.filter(t=>t.status==="archive");else if(s.view.startsWith("category:")){let t=s.view.split(":")[1];e=e.filter(n=>n.category===t&&n.status!=="deleted"&&n.status!=="backlog"&&n.status!=="archive")}else if(s.view.startsWith("priority:")){let t=s.view.split(":")[1];e=e.filter(n=>n.priority===t&&n.status!=="deleted"&&n.status!=="backlog"&&n.status!=="archive")}else e=e.filter(t=>t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");if(s.search){let t=s.search.toLowerCase();e=e.filter(n=>n.title.toLowerCase().includes(t)||n.ticket_number.toLowerCase().includes(t)||n.details&&n.details.toLowerCase().includes(t))}s.tickets=e,L()}function Zn(e){let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/6e4);if(n<1)return"just now";if(n<60)return`${n}m ago`;let a=Math.floor(n/60);return a<24?`${a}h ago`:`${Math.floor(a/24)}d ago`}function Qn(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function ea(e){return e==="5min"?"Recent (every 5 min)":e==="hourly"?"Hourly":e==="daily"?"Daily":e}async function Ze(){var t;let e=document.getElementById("backup-list");if(e)try{let n=await f("/backups");if(n.backups.length===0){e.textContent="No backups yet. First backup will be created shortly.";return}let a={};for(let o of n.backups)(a[t=o.tier]||(a[t]=[])).push(o);e.innerHTML="";for(let o of["5min","hourly","daily"]){let i=a[o];if(!(!i||i.length===0)){e.appendChild(v(r("div",{className:"backup-tier-label",children:ea(o)})));for(let l of i){let c=v(r("div",{className:"backup-row","data-tier":l.tier,"data-filename":l.filename,children:[r("span",{className:"backup-row-time",children:Zn(l.createdAt)}),r("span",{className:"backup-row-meta",children:[new Date(l.createdAt).toLocaleString()," \xB7 ",Qn(l.sizeBytes)]})]}));c.addEventListener("click",()=>{ta(l.tier,l.filename,l.createdAt)}),e.appendChild(c)}}}}catch{e.textContent="Failed to load backups."}}async function ta(e,t,n){let a=document.getElementById("settings-overlay");a.style.display="none";let o=document.getElementById("backup-preview-banner"),i=document.getElementById("backup-preview-label");i.textContent="Loading backup preview...",o.style.display="flex";try{let l=await f(`/backups/preview/${e}/${t}`);s.backupPreview={active:!0,tickets:l.tickets,timestamp:n,tier:e,filename:t},s.selectedIds.clear(),s.activeTicketId=null,i.textContent=`Previewing backup from ${new Date(n).toLocaleString()} (${l.stats.total} tickets, ${l.stats.open} open) \u2014 read-only`,w()}catch{i.textContent="Failed to load backup preview.",setTimeout(()=>{o.style.display="none"},3e3)}}async function na(){let e=document.getElementById("backup-preview-banner");e.style.display="none",s.backupPreview=null,s.selectedIds.clear(),s.activeTicketId=null,await f("/backups/preview/cleanup",{method:"POST"}),w()}async function aa(){if(!s.backupPreview)return;let e=document.getElementById("backup-restore-btn");e.textContent="Restoring...",e.disabled=!0;try{await f("/backups/restore",{method:"POST",body:{tier:s.backupPreview.tier,filename:s.backupPreview.filename}}),window.location.reload()}catch{e.textContent="Restore failed",e.disabled=!1,setTimeout(()=>{e.textContent="Restore This Backup"},3e3)}}function Yt(){document.getElementById("backup-cancel-btn")?.addEventListener("click",()=>{na()}),document.getElementById("backup-restore-btn")?.addEventListener("click",()=>{aa()});let e=document.getElementById("backup-now-btn");e?.addEventListener("click",async()=>{e.textContent="Backing up...",e.disabled=!0;try{(await f("/backups/now",{method:"POST"})).error?e.textContent="In progress...":(e.textContent="Done!",Ze())}catch{e.textContent="Failed"}setTimeout(()=>{e.textContent="Backup Now",e.disabled=!1},1500)})}var Ne,Z=null;function Zt(e){Ne=e,document.getElementById("add-custom-view-btn").addEventListener("click",t=>{t.stopPropagation(),tt()})}async function Qt(){try{let e=await f("/settings");if(e.custom_views){let t=JSON.parse(e.custom_views);Array.isArray(t)&&(s.customViews=t)}}catch{}Qe()}function Qe(){let e=document.getElementById("custom-views-container");if(e&&(e.innerHTML="",s.customViews.length!==0)){e.appendChild(v(r("div",{className:"sidebar-divider"})));for(let t=0;t<s.customViews.length;t++){let n=s.customViews[t],a=v(r("button",{className:`sidebar-item sidebar-custom-view${s.view===`custom:${n.id}`?" active":""}`,"data-view":`custom:${n.id}`,"data-cv-index":String(t),draggable:"true",children:n.name}));a.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active")),a.classList.add("active"),s.view=`custom:${n.id}`,s.selectedIds.clear(),H(),Ne()}),a.addEventListener("dblclick",o=>{o.preventDefault(),tt(n)}),a.addEventListener("contextmenu",o=>{o.preventDefault(),ia(a,n)}),a.addEventListener("dragstart",o=>{Z=t,o.dataTransfer.setData("text/plain",String(t)),o.dataTransfer.effectAllowed="move",setTimeout(()=>a.classList.add("dragging"),0)}),a.addEventListener("dragend",()=>{a.classList.remove("dragging"),Z=null}),a.addEventListener("dragover",o=>{Z!==null&&(o.preventDefault(),o.dataTransfer.dropEffect="move",a.classList.add("drop-target"))}),a.addEventListener("dragleave",()=>{a.classList.remove("drop-target")}),a.addEventListener("drop",o=>{if(o.preventDefault(),a.classList.remove("drop-target"),Z===null||Z===t)return;let[i]=s.customViews.splice(Z,1);s.customViews.splice(t,0,i),Z=null,et()}),e.appendChild(a)}}}var sa='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/></svg>',oa='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/></svg>';function ia(e,t){B();let n=N(e,[{label:"Edit",key:"e",icon:sa,action:()=>tt(t)},{label:"Delete",key:"d",icon:oa,action:()=>ra(t.id)}]);document.body.appendChild(n),$(n,e),n.style.visibility=""}async function et(){await f("/settings",{method:"PATCH",body:{custom_views:JSON.stringify(s.customViews)}}),Qe()}async function ra(e){s.customViews=s.customViews.filter(t=>t.id!==e),s.view===`custom:${e}`&&(s.view="all",document.querySelectorAll(".sidebar-item").forEach(t=>{t.classList.toggle("active",t.dataset.view==="all")}),Ne()),await et()}var $e=[{value:"category",label:"Category",type:"select"},{value:"priority",label:"Priority",type:"ordinal"},{value:"status",label:"Status",type:"ordinal"},{value:"title",label:"Title",type:"text"},{value:"details",label:"Details",type:"text"},{value:"up_next",label:"Up Next",type:"boolean"},{value:"tags",label:"Tags",type:"text"}];function Xt(e){return e==="ordinal"?[{value:"equals",label:"="},{value:"not_equals",label:"\u2260"},{value:"lt",label:"<"},{value:"lte",label:"\u2264"},{value:"gt",label:">"},{value:"gte",label:"\u2265"}]:e==="select"?[{value:"equals",label:"is"},{value:"not_equals",label:"is not"}]:e==="boolean"?[{value:"equals",label:"is"}]:[{value:"contains",label:"contains"},{value:"not_contains",label:"does not contain"}]}var la=["highest","high","default","low","lowest"],ca=["not_started","started","completed","verified","backlog","archive"];function Gt(e){return e==="category"?s.categories.map(t=>t.id):e==="priority"?la:e==="status"?ca:e==="up_next"?["true","false"]:null}function da(e,t){return e==="category"?s.categories.find(a=>a.id===t)?.label||t:e==="status"?t.replace(/_/g," "):e==="up_next"?t==="true"?"Yes":"No":t}function tt(e){let t=!!e,n=e?e.conditions.map(d=>({...d})):[],a=e?.logic||"all",o=e?.name||"",i=v(r("div",{className:"custom-view-editor-overlay",children:r("div",{className:"custom-view-editor",children:[r("div",{className:"custom-view-editor-header",children:[r("span",{children:t?"Edit Custom View":"New Custom View"}),r("button",{className:"detail-close",id:"cv-editor-close",children:"\xD7"})]}),r("div",{className:"custom-view-editor-body",children:[r("div",{className:"settings-field",children:[r("label",{children:"Name"}),r("input",{type:"text",id:"cv-name",value:o,placeholder:"View name..."})]}),r("div",{className:"cv-logic-row",children:[r("span",{children:"Match"}),r("label",{children:[r("input",{type:"radio",name:"cv-logic",value:"all",checked:a==="all"})," All of"]}),r("label",{children:[r("input",{type:"radio",name:"cv-logic",value:"any",checked:a==="any"})," Any of"]})]}),r("div",{id:"cv-conditions"}),r("button",{className:"btn btn-sm",id:"cv-add-condition",style:"margin-top:8px",children:"+ Add Condition"})]}),r("div",{className:"custom-view-editor-footer",children:[r("button",{className:"btn btn-sm",id:"cv-cancel",children:"Cancel"}),r("button",{className:"btn btn-sm btn-accent",id:"cv-save",children:"Save"})]})]})}));function l(){let d=i.querySelector("#cv-conditions");d.innerHTML="",n.forEach((u,p)=>{let m=$e.find(T=>T.value===u.field)||$e[0],g=Xt(m.type),y=Gt(u.field),b=v(r("div",{className:"cv-condition-row",children:[r("select",{className:"cv-field-select",children:$e.map(T=>r("option",{value:T.value,selected:T.value===u.field,children:T.label}))}),r("select",{className:"cv-op-select",children:g.map(T=>r("option",{value:T.value,selected:T.value===u.operator,children:T.label}))}),y?r("select",{className:"cv-value-select",children:y.map(T=>r("option",{value:T,selected:T===u.value,children:da(u.field,T)}))}):r("input",{type:"text",className:"cv-value-input",value:u.value,placeholder:"Value..."}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]})),E=b.querySelector(".cv-field-select"),x=b.querySelector(".cv-op-select"),k=b.querySelector(".cv-value-select")||b.querySelector(".cv-value-input");E.addEventListener("change",()=>{let T=E.value,_=$e.find(ee=>ee.value===T),ce=Xt(_.type);n[p].field=T,n[p].operator=ce[0].value;let Q=Gt(T);n[p].value=Q?Q[0]:"",l()}),x.addEventListener("change",()=>{n[p].operator=x.value}),k.addEventListener("change",()=>{n[p].value=k.value}),k.tagName==="INPUT"&&k.addEventListener("input",()=>{n[p].value=k.value}),b.querySelector(".category-delete-btn").addEventListener("click",()=>{n.splice(p,1),l()}),d.appendChild(b)})}l(),document.body.appendChild(i),i.querySelector("#cv-name").focus(),i.querySelectorAll('input[name="cv-logic"]').forEach(d=>{d.addEventListener("change",()=>{a=d.value})}),i.querySelector("#cv-add-condition").addEventListener("click",()=>{n.push({field:"category",operator:"equals",value:s.categories[0]?.id||"issue"}),l()});let c=()=>i.remove();i.querySelector("#cv-editor-close").addEventListener("click",c),i.querySelector("#cv-cancel").addEventListener("click",c),i.addEventListener("click",d=>{d.target===i&&c()}),i.querySelector("#cv-save").addEventListener("click",async()=>{if(o=i.querySelector("#cv-name").value.trim(),!o){i.querySelector("#cv-name").focus();return}let d={id:e?.id||o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||`view-${Date.now()}`,name:o,logic:a,conditions:n.filter(u=>u.value!=="")};if(t){let u=s.customViews.findIndex(p=>p.id===e.id);u>=0?s.customViews[u]=d:s.customViews.push(d)}else s.customViews.push(d);await et(),document.querySelectorAll(".sidebar-item").forEach(u=>u.classList.remove("active")),s.view=`custom:${d.id}`,s.selectedIds.clear(),Qe(),Ne(),c()})}var re=30;async function at(e){e.innerHTML='<div class="dashboard-loading">Loading dashboard...</div>';try{let t=await f(`/dashboard?days=${re}`);e.innerHTML="",e.appendChild(ua(t))}catch{e.innerHTML='<div class="dashboard-loading">Failed to load dashboard data.</div>'}}function ua(e){let t=v(r("div",{className:"dashboard"})),n=v(r("div",{className:"dashboard-range-bar",children:[r("button",{className:`btn btn-sm${re===7?" active":""}`,"data-days":"7",children:"7 days"}),r("button",{className:`btn btn-sm${re===30?" active":""}`,"data-days":"30",children:"30 days"}),r("button",{className:`btn btn-sm${re===90?" active":""}`,"data-days":"90",children:"90 days"})]}));n.querySelectorAll("button").forEach(m=>{m.addEventListener("click",()=>{re=parseInt(m.dataset.days,10);let g=document.getElementById("dashboard-container");g&&at(g)})}),t.appendChild(n);let a=e.kpi,o=a.completedLastWeek>0?Math.round((a.completedThisWeek-a.completedLastWeek)/a.completedLastWeek*100):0,i=o>0?"\u2191":o<0?"\u2193":"",l=a.createdThisWeek>0?(a.completedThisWeek/a.createdThisWeek).toFixed(1):"\u2014";t.appendChild(v(r("div",{className:"dashboard-kpi-row",children:[r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(a.completedThisWeek)}),r("div",{className:"kpi-label",children:"Completed this week"}),i?r("div",{className:`kpi-trend${o>0?" up":" down"}`,children:[i," ",Math.abs(o),"%"]}):null]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:a.medianCycleTimeDays!==null?`${a.medianCycleTimeDays}d`:"\u2014"}),r("div",{className:"kpi-label",children:"Median cycle time"})]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(a.wipCount)}),r("div",{className:"kpi-label",children:"In progress"})]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(l)}),r("div",{className:"kpi-label",children:"Completed / created"})]})]})));let c=v(r("div",{className:"dashboard-grid"})),d=ke("Throughput","Items completed per day. Shows your sustainable delivery pace.",pa(e.throughput));nt(d,e.throughput.map(m=>({date:m.date,lines:[{label:"Completed",color:"#3b82f6",value:m.completed}]}))),c.appendChild(d);let u=ke("Created vs Completed","Compares items created (orange) vs completed (green) over time. When created outpaces completed, the backlog grows.",ma(e.throughput));nt(u,e.throughput.map(m=>({date:m.date,lines:[{label:"Completed",color:"#22c55e",value:m.completed},{label:"Created",color:"#f97316",value:m.created}]}))),c.appendChild(u);let p=ke("Cumulative Flow","Stacked area showing ticket counts by status over time. Widening bands indicate bottlenecks. A healthy flow has consistent band widths.",ga(e.snapshots));return nt(p,e.snapshots.map(m=>({date:m.date,lines:[{label:"Not Started",color:"#6b7280",value:m.data.not_started},{label:"Started",color:"#3b82f6",value:m.data.started},{label:"Completed",color:"#22c55e",value:m.data.completed},{label:"Verified",color:"#8b5cf6",value:m.data.verified}]}))),c.appendChild(p),c.appendChild(ke("Category Breakdown","Distribution of tickets by category. Left: currently open. Right: all tickets active in the selected time period.",fa(e.categoryBreakdown,e.categoryPeriod))),c.appendChild(ke("Cycle Time","Each dot is a completed ticket plotted by completion date and days to complete. Dashed lines show 50th and 85th percentile delivery times.",ya(e.cycleTime))),t.appendChild(c),t}function ke(e,t,n){let a=v(r("div",{className:"dashboard-chart-card",children:[r("div",{className:"dashboard-chart-header",children:[r("span",{className:"dashboard-chart-title",children:e}),r("button",{className:"dashboard-info-btn",title:"About this chart",children:r("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r("circle",{cx:"12",cy:"12",r:"10"}),r("path",{d:"M12 16v-4"}),r("path",{d:"M12 8h.01"})]})})]}),r("div",{className:"dashboard-chart-info",style:"display:none",children:t}),r("div",{className:"dashboard-chart-body",children:D(n)})]})),o=a.querySelector(".dashboard-info-btn"),i=a.querySelector(".dashboard-chart-info");return o.addEventListener("click",l=>{l.stopPropagation(),i.style.display=i.style.display==="none"?"":"none"}),a}function nt(e,t){let n=e.querySelector(".dashboard-chart-body");if(!n||t.length===0)return;let a=document.createElement("div");a.className="chart-cursor",a.style.display="none",n.style.position="relative",n.appendChild(a);let o=document.createElement("div");o.className="chart-tooltip",o.style.display="none",n.appendChild(o);let i=n.querySelector("svg");i&&(i.addEventListener("mousemove",l=>{let c=i.getBoundingClientRect(),d=n.getBoundingClientRect(),u=c.left-d.left,p=c.top-d.top,m=q/c.width,g=O/c.height,y=(l.clientX-c.left)*m,b=q-h.left-h.right,E=Math.max(0,Math.min(1,(y-h.left)/b)),x=Math.round(E*(t.length-1));if(x<0||x>=t.length)return;let k=h.left+x/Math.max(t.length-1,1)*b,T=u+k/m,_=p+h.top/g,ce=(O-h.top-h.bottom)/g;a.style.display="",a.style.left=`${T}px`,a.style.top=`${_}px`,a.style.height=`${ce}px`;let Q=t[x];o.style.display="",o.innerHTML=`<div class="chart-tooltip-date">${st(Q.date)}</div>${Q.lines.map(de=>`<div class="chart-tooltip-row"><span class="chart-legend-dot" style="background:${de.color}"></span>${de.label}: <b>${de.value}</b></div>`).join("")}`;let ee=T+10;ee+120>d.width?o.style.left=`${T-120}px`:o.style.left=`${ee}px`,o.style.top=`${l.clientY-d.top-10}px`}),i.addEventListener("mouseleave",()=>{a.style.display="none",o.style.display="none"}))}var q=400,O=180,h={top:10,right:10,bottom:25,left:35};function pa(e){if(e.length===0)return'<div class="chart-empty">No data</div>';let t=e.map(c=>c.completed),n=Math.max(...t,1),a=q-h.left-h.right,o=O-h.top-h.bottom,i=Math.max(2,a/e.length-2),l="";for(let c=0;c<e.length;c++){let d=h.left+c/e.length*a,u=t[c]/n*o,p=h.top+o-u,m=st(e[c].date);l+=`<rect x="${d}" y="${p}" width="${i}" height="${u}" fill="#3b82f6" rx="1" opacity="0.8" class="chart-hover"><title>${m}: ${t[c]} completed</title></rect>`}return`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
2
- ${ot(n,o)}
1
+ "use strict";(()=>{var kn=Object.defineProperty;var wn=(e,t,n)=>t in e?kn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var pe=(e,t,n)=>wn(e,typeof t!="symbol"?t+"":t,n);var Re=!1;function H(){Re=!0}function kt(){let e=new Map;return document.querySelectorAll(".ticket-row[data-id], .column-card[data-id]").forEach(t=>{let n=t.dataset.id;e.set(n,t.getBoundingClientRect())}),e}function Te(e){if(Re){Re=!1;return}e.size!==0&&document.querySelectorAll(".ticket-row[data-id], .column-card[data-id]").forEach(t=>{let n=t,a=n.dataset.id,o=e.get(a);if(!o)return;let i=n.getBoundingClientRect(),l=o.left-i.left,c=o.top-i.top;if(Math.abs(l)<1&&Math.abs(c)<1)return;n.style.transform=`translate(${l}px, ${c}px)`,n.offsetHeight,n.style.transition="transform 200ms ease-out",n.style.transform="";let d=()=>{n.style.transition=""};n.addEventListener("transitionend",d,{once:!0}),setTimeout(d,250)})}function v(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function wt(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Et(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var J=class{constructor(t){pe(this,"__html");this.__html=t}toString(){return this.__html}};function D(e){return new J(e)}var En=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function qe(e){return e==null||typeof e=="boolean"?"":e instanceof J?e.__html:typeof e=="string"?wt(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(qe).join(""):""}var Tn={className:"class",htmlFor:"for",httpEquiv:"http-equiv",acceptCharset:"accept-charset",accessKey:"accesskey",autoCapitalize:"autocapitalize",autoComplete:"autocomplete",autoFocus:"autofocus",autoPlay:"autoplay",colSpan:"colspan",contentEditable:"contenteditable",crossOrigin:"crossorigin",dateTime:"datetime",defaultChecked:"checked",defaultValue:"value",encType:"enctype",formAction:"formaction",formEncType:"formenctype",formMethod:"formmethod",formNoValidate:"formnovalidate",formTarget:"formtarget",hrefLang:"hreflang",inputMode:"inputmode",maxLength:"maxlength",minLength:"minlength",noModule:"nomodule",noValidate:"novalidate",readOnly:"readonly",referrerPolicy:"referrerpolicy",rowSpan:"rowspan",spellCheck:"spellcheck",srcDoc:"srcdoc",srcLang:"srclang",srcSet:"srcset",tabIndex:"tabindex",useMap:"usemap",strokeWidth:"stroke-width",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",strokeMiterlimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",fillOpacity:"fill-opacity",fillRule:"fill-rule",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",floodColor:"flood-color",floodOpacity:"flood-opacity",lightingColor:"lighting-color",stopColor:"stop-color",stopOpacity:"stop-opacity",shapeRendering:"shape-rendering",imageRendering:"image-rendering",textRendering:"text-rendering",pointerEvents:"pointer-events",vectorEffect:"vector-effect",paintOrder:"paint-order",fontFamily:"font-family",fontSize:"font-size",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",fontStretch:"font-stretch",textAnchor:"text-anchor",textDecoration:"text-decoration",dominantBaseline:"dominant-baseline",alignmentBaseline:"alignment-baseline",baselineShift:"baseline-shift",letterSpacing:"letter-spacing",wordSpacing:"word-spacing",writingMode:"writing-mode",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",markerStart:"marker-start",markerMid:"marker-mid",markerEnd:"marker-end",gradientUnits:"gradientUnits",gradientTransform:"gradientTransform",spreadMethod:"spreadMethod",patternUnits:"patternUnits",patternContentUnits:"patternContentUnits",patternTransform:"patternTransform",maskUnits:"maskUnits",maskContentUnits:"maskContentUnits",filterUnits:"filterUnits",primitiveUnits:"primitiveUnits",clipPathUnits:"clipPathUnits",xlinkHref:"xlink:href",xlinkShow:"xlink:show",xlinkActuate:"xlink:actuate",xlinkType:"xlink:type",xlinkRole:"xlink:role",xlinkTitle:"xlink:title",xlinkArcrole:"xlink:arcrole",xmlBase:"xml:base",xmlLang:"xml:lang",xmlSpace:"xml:space",xmlns:"xmlns",xmlnsXlink:"xmlns:xlink",stdDeviation:"stdDeviation",baseFrequency:"baseFrequency",numOctaves:"numOctaves",kernelMatrix:"kernelMatrix",surfaceScale:"surfaceScale",specularConstant:"specularConstant",specularExponent:"specularExponent",diffuseConstant:"diffuseConstant",pointsAtX:"pointsAtX",pointsAtY:"pointsAtY",pointsAtZ:"pointsAtZ",limitingConeAngle:"limitingConeAngle",tableValues:"tableValues"};function xn(e,t){let n=Tn[e]??e;if(t==null||t===!1)return"";if(t===!0)return` ${n}`;let a;return t instanceof J?a=t.__html:typeof t=="number"?a=String(t):typeof t=="string"?a=Et(t):a="",` ${n}="${a}"`}function r(e,t){if(typeof e=="function")return e(t);let{children:n,...a}=t,o=Object.entries(a).map(([l,c])=>xn(l,c)).join("");if(En.has(e))return new J(`<${e}${o}>`);let i=n!=null?qe(n):"";return new J(`<${e}${o}>${i}</${e}>`)}function me({children:e}){return new J(e!=null?qe(e):"")}function Tt(e){document.getElementById("network-error-popup")?.remove();let t=v(r("div",{id:"network-error-popup",className:"error-popup",children:r("div",{className:"error-popup-content",children:[r("strong",{children:"Connection Error"}),r("p",{children:e}),r("button",{children:"Dismiss"})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function f(e,t={}){try{return(await fetch("/api"+e,{headers:t.body!==void 0?{"Content-Type":"application/json"}:{},method:t.method,body:t.body!==void 0?JSON.stringify(t.body):void 0})).json()}catch(n){throw Tt("Unable to reach the server. It may have been stopped."),n}}async function xt(e,t){try{let n=new FormData;return n.append("file",t),(await fetch("/api"+e,{method:"POST",body:n})).json()}catch(n){throw Tt("Unable to reach the server. It may have been stopped."),n}}var Ln={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},s={tickets:[],customViews:[],categories:[{id:"issue",label:"Issue",shortLabel:"ISS",color:"#6b7280",shortcutKey:"i",description:""},{id:"bug",label:"Bug",shortLabel:"BUG",color:"#ef4444",shortcutKey:"b",description:""},{id:"feature",label:"Feature",shortLabel:"FEA",color:"#22c55e",shortcutKey:"f",description:""},{id:"requirement_change",label:"Req Change",shortLabel:"REQ",color:"#f97316",shortcutKey:"r",description:""},{id:"task",label:"Task",shortLabel:"TSK",color:"#3b82f6",shortcutKey:"k",description:""},{id:"investigation",label:"Investigation",shortLabel:"INV",color:"#8b5cf6",shortcutKey:"g",description:""}],selectedIds:new Set,lastClickedId:null,activeTicketId:null,view:"all",layout:"list",sortBy:"created",sortDir:"desc",search:"",settings:{...Ln},backupPreview:null},In='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20"/><path d="m8 18 4 4 4-4"/><path d="m8 6 4-4 4 4"/></svg>',Cn={highest:"\u2B06\u2B06",high:"\u2B06",default:In,low:"\u2B07",lowest:"\u2B07\u2B07"},Sn={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},Lt='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 7 17l-5-5"/><path d="m22 10-7.5 7.5L13 16"/></svg>',Mn={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:Lt,backlog:"\u25A1",archive:"\u25A0"},Ue=Lt;function C(e){return s.categories.find(n=>n.id===e)?.color||"#6b7280"}function K(e){return s.categories.find(n=>n.id===e)?.shortLabel||e.slice(0,3).toUpperCase()}function A(e){return Cn[e]||"\u2014"}function P(e){return Sn[e]||"#6b7280"}function z(e){return Mn[e]||"\u25CB"}function V(e){if(!e||e==="[]")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.filter(n=>typeof n=="string"&&n.trim())}catch{}return[]}function fe(e,t){let n=document.getElementById("detail-tags");if(n){n.innerHTML="";for(let a of e){let o=v(r("span",{className:"tag-chip",children:[a,t?null:r("button",{className:"tag-chip-remove","data-tag":a,title:"Remove tag",children:"\xD7"})]}));t||o.querySelector(".tag-chip-remove").addEventListener("click",async()=>{if(s.activeTicketId==null)return;let i=s.tickets.find(d=>d.id===s.activeTicketId);if(!i)return;let c=V(i.tags).filter(d=>d!==a);await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{tags:JSON.stringify(c)}}),i.tags=JSON.stringify(c),fe(c,!1)}),n.appendChild(o)}}}var $n={not_started:"Not Started",started:"Started",completed:"Completed",verified:"Verified",backlog:"Backlog",archive:"Archive"},Nn={highest:"Highest",high:"High",default:"Default",low:"Low",lowest:"Lowest"};function ye(e){let t=document.getElementById("detail-category");t.dataset.value=e;let n=s.categories.find(o=>o.id===e),a=C(e);t.innerHTML=`<span class="cat-dot" style="background:${a}"></span> ${n?.label||e}`}function xe(e){let t=document.getElementById("detail-priority");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon" style="color:${P(e)}">${A(e)}</span> ${Nn[e]||e}`}function Le(e){let t=document.getElementById("detail-status");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon">${z(e)}</span> ${$n[e]||e}`}function te(e){s.activeTicketId=e,Ve(e)}function St(){s.selectedIds.clear(),s.activeTicketId=null,ne();let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function ne(){let e=s.view==="trash",t=!!s.backupPreview?.active,n=document.getElementById("detail-panel"),a=document.getElementById("detail-resize-handle"),o=document.getElementById("detail-header"),i=document.getElementById("detail-body"),l=document.getElementById("detail-placeholder"),c=document.getElementById("detail-placeholder-text");if(e){n.style.display="none",a&&(a.style.display="none"),s.activeTicketId=null;return}if(n.style.display="flex",a&&(a.style.display=""),s.selectedIds.size===1){let d=Array.from(s.selectedIds)[0];n.classList.remove("detail-disabled"),o.style.display="",i.style.display="",l.style.display="none",s.activeTicketId!==d&&(s.activeTicketId=d,t?Bn(d):Ve(d))}else s.activeTicketId=null,n.classList.add("detail-disabled"),o.style.display="none",i.style.display="none",l.style.display="",s.selectedIds.size===0?c.textContent="Nothing selected":c.textContent=`${s.selectedIds.size} items selected`}function Mt(e){let t=document.getElementById("detail-title"),n=document.getElementById("detail-details"),a=document.getElementById("detail-category"),o=document.getElementById("detail-priority"),i=document.getElementById("detail-status"),l=document.getElementById("detail-upnext"),c=document.querySelector(".upload-btn");t.readOnly=e,n.readOnly=e,a.disabled=e,o.disabled=e,i.disabled=e,l.disabled=e,c&&(c.style.display=e?"none":"")}function Bn(e){let t=s.backupPreview?.tickets.find(l=>l.id===e);if(!t||s.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,ye(t.category),xe(t.priority),Le(t.status);let n=document.getElementById("detail-upnext");n.textContent=t.up_next?"\u2605":"\u2606",n.classList.toggle("active",t.up_next),document.getElementById("detail-details").value=t.details,Mt(!0),document.getElementById("detail-attachments").innerHTML="",fe(V(t.tags),!0);let a=document.getElementById("detail-notes"),o=$t(t.notes);o.length>0?a.innerHTML=r(me,{children:o.map(l=>r("div",{className:"note-entry",children:[l.created_at?r("div",{className:"note-timestamp",children:new Date(l.created_at).toLocaleString()}):null,r("div",{className:"note-text",children:l.text})]}))}).toString():a.innerHTML="";let i=document.getElementById("detail-meta");i.innerHTML=r(me,{children:[r("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),r("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?r("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?r("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function ae(){s.activeTicketId!=null&&Ve(s.activeTicketId)}async function Ve(e){let t=await f(`/tickets/${e}`);if(s.activeTicketId!==e)return;Mt(!1),document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,ye(t.category),xe(t.priority),Le(t.status);let n=document.getElementById("detail-upnext");n.textContent=t.up_next?"\u2605":"\u2606",n.classList.toggle("active",t.up_next),document.getElementById("detail-details").value=t.details;let a=document.getElementById("detail-attachments");t.attachments.length>0?a.innerHTML=r(me,{children:t.attachments.map(i=>r("div",{className:"attachment-item",children:[r("span",{className:"attachment-name",children:i.original_filename}),r("button",{className:"attachment-reveal","data-att-id":String(i.id),title:"Show in file manager",children:r("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:r("path",{d:"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"})})}),r("button",{className:"attachment-delete","data-att-id":String(i.id),title:"Remove",children:"\xD7"})]}))}).toString():a.innerHTML="",fe(V(t.tags),!1),Oe(t.id,$t(t.notes));let o=document.getElementById("detail-meta");o.innerHTML=r(me,{children:[r("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),r("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?r("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?r("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function It(e,t){let n=s.tickets.find(a=>a.id===e);n&&(n.notes=JSON.stringify(t))}function Oe(e,t){let n=document.getElementById("detail-notes");if(n){if(n.innerHTML="",t.length===0){n.innerHTML='<div class="notes-empty">No notes added</div>';return}for(let a of t){let o=v(r("div",{className:"note-entry",children:[a.created_at?r("div",{className:"note-timestamp",children:new Date(a.created_at).toLocaleString()}):null,r("div",{className:"note-text",children:a.text})]}));o.addEventListener("click",()=>{let i=o.querySelector(".note-text");if(o.querySelector(".note-edit-area"))return;let l=document.createElement("textarea");l.className="note-edit-area",l.value=a.text,l.rows=3,i.style.display="none",o.appendChild(l),l.focus();let c=async()=>{let d=l.value.trim();if(d&&d!==a.text){let u=s.tickets.find(m=>m.id===e),p=t.map(m=>m.id===a.id?{...m,text:d}:m);u&&ge(u,"Edit note",JSON.stringify(p)),await f(`/tickets/${e}/notes/${a.id}`,{method:"PATCH",body:{text:d}}),a.text=d,It(e,t)}Oe(e,t)};l.addEventListener("blur",()=>{c()}),l.addEventListener("keydown",d=>{d.key==="Enter"&&(d.metaKey||d.ctrlKey)&&(d.preventDefault(),c()),d.key==="Escape"&&(d.stopPropagation(),l.blur())})}),o.addEventListener("contextmenu",i=>{i.preventDefault(),document.querySelectorAll(".note-context-menu").forEach(c=>c.remove());let l=v(r("div",{className:"note-context-menu context-menu",style:`top:${i.clientY}px;left:${i.clientX}px`,children:r("div",{className:"context-menu-item danger",children:r("span",{className:"context-menu-label",children:"Delete Note"})})}));l.querySelector(".context-menu-item").addEventListener("click",async c=>{c.stopPropagation(),l.remove();let d=s.tickets.find(m=>m.id===e),u=t.filter(m=>m.id!==a.id);d&&ge(d,"Delete note",JSON.stringify(u)),await f(`/tickets/${e}/notes/${a.id}`,{method:"DELETE"});let p=t.indexOf(a);p>=0&&t.splice(p,1),It(e,t),Oe(e,t)}),document.body.appendChild(l),setTimeout(()=>{let c=()=>{l.remove(),document.removeEventListener("click",c)};document.addEventListener("click",c)},0)}),n.appendChild(o)}}}var _n=0;function Ct(){return`cn_${Date.now().toString(36)}_${(_n++).toString(36)}`}function $t(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.map(n=>({id:n.id||Ct(),text:n.text,created_at:n.created_at}))}catch{}return e.trim()?[{id:Ct(),text:e,created_at:""}]:[]}async function Ie(){try{let e=await f("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function Ke(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function ze(){let e=document.getElementById("detail-panel");s.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${s.settings.detail_height}px`):(e.style.height="",e.style.width=`${s.settings.detail_width}px`)}function Nt(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),n=document.getElementById("content-area"),a=!1;e.addEventListener("mousedown",o=>{o.preventDefault(),a=!0,document.body.style.cursor=s.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",o=>{if(!a)return;let i=n.getBoundingClientRect();if(s.settings.detail_position==="bottom"){let l=Math.max(150,Math.min(500,i.bottom-o.clientY));s.settings.detail_height=l,t.style.height=`${l}px`}else{let l=Math.max(250,Math.min(600,i.right-o.clientX));s.settings.detail_width=l,t.style.width=`${l}px`}}),document.addEventListener("mouseup",()=>{a&&(a=!1,document.body.style.cursor="",document.body.style.userSelect="",s.settings.detail_position==="bottom"?f("/settings",{method:"PATCH",body:{detail_height:String(s.settings.detail_height)}}):f("/settings",{method:"PATCH",body:{detail_width:String(s.settings.detail_width)}}))})}var Fe=class{constructor(){pe(this,"undoStack",[]);pe(this,"redoStack",[])}push(t){console.log("[undo] push:",t.label,"stack depth:",this.undoStack.length+1,"before:",JSON.stringify(t.before),"after:",JSON.stringify(t.after)),this.undoStack.push(t),this.undoStack.length>1e3&&this.undoStack.shift(),this.redoStack=[]}coalesce(t){if(t.coalescingKey==null||t.coalescingKey==="")return!1;let n=this.peekUndo();return!n||n.coalescingKey!==t.coalescingKey||t.timestamp-n.timestamp>=5e3?!1:(n.after=t.after,!0)}popUndo(){let t=this.undoStack.pop();return t&&this.redoStack.push(t),t}popRedo(){let t=this.redoStack.pop();return t&&this.undoStack.push(t),t}peekUndo(){return this.undoStack[this.undoStack.length-1]}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}},M=new Fe;function F(e,t=!1){let n={id:e.id,title:e.title,details:e.details,category:e.category,priority:e.priority,status:e.status,up_next:e.up_next};return t&&(n.notes=e.notes),n}async function R(e,t,n){let a=F(e),o=await f(`/tickets/${e.id}`,{method:"PATCH",body:t}),i=F(o);return M.push({label:n,timestamp:Date.now(),before:[a],after:[i]}),o}function Ce(e,t,n){let a=`${e.id}:${t}`,o=Date.now(),i={...F(e),[t]:n},l={label:`Edit ${t}`,timestamp:o,before:[F(e)],after:[i],coalescingKey:a};M.coalesce(l)||M.push(l)}async function I(e,t,n){let a=e.map(i=>F(i));await f("/tickets/batch",{method:"POST",body:t});let o=a.map(i=>{let l={...i};return t.action==="category"?l.category=t.value:t.action==="priority"?l.priority=t.value:t.action==="status"?l.status=t.value:t.action==="up_next"?l.up_next=t.value:t.action==="delete"&&(l.status="deleted"),l});M.push({label:n,timestamp:Date.now(),before:a,after:o})}async function We(e,t,n){let a=e.map(i=>F(i));for(let i of t)await f("/tickets/batch",{method:"POST",body:i});let o=a.map(i=>{let l={...i};for(let c of t)c.ids.includes(i.id)&&(c.action==="status"?l.status=c.value:c.action==="up_next"?l.up_next=c.value:c.action==="category"?l.category=c.value:c.action==="priority"?l.priority=c.value:c.action==="delete"&&(l.status="deleted"));return l});M.push({label:n,timestamp:Date.now(),before:a,after:o})}async function Se(e){let t=F(e);await f(`/tickets/${e.id}`,{method:"DELETE"});let n={...t,status:"deleted"};M.push({label:"Delete ticket",timestamp:Date.now(),before:[t],after:[n]})}async function Bt(e){let t=F(e);await f(`/tickets/${e.id}/restore`,{method:"POST"});let n={...t,status:"not_started"};M.push({label:"Restore ticket",timestamp:Date.now(),before:[t],after:[n]})}async function _t(e){for(let t of e)t.status==="deleted"?await f(`/tickets/${t.id}`,{method:"DELETE"}):(await f(`/tickets/${t.id}`,{method:"PATCH",body:{title:t.title,details:t.details,category:t.category,priority:t.priority,status:t.status,up_next:t.up_next}}),t.notes!==void 0&&await f(`/tickets/${t.id}/notes-bulk`,{method:"PUT",body:{notes:t.notes}}))}var Y=!1;async function Ht(){if(console.log("[undo] performUndo, inFlight:",Y,"canUndo:",M.canUndo()),Y){console.log("[undo] skipped \u2014 already in flight");return}let e=M.popUndo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying before-state:",e.label,JSON.stringify(e.before)),Y=!0;try{await _t(e.before),console.log("[undo] applySnapshots done, reloading tickets"),await w(),setTimeout(()=>ae(),50)}finally{Y=!1}}async function Dt(){if(console.log("[undo] performRedo, inFlight:",Y,"canRedo:",M.canRedo()),Y){console.log("[undo] skipped \u2014 already in flight");return}let e=M.popRedo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying after-state:",e.label,JSON.stringify(e.after)),Y=!0;try{await _t(e.after),console.log("[undo] applySnapshots done, reloading tickets"),await w(),setTimeout(()=>ae(),50)}finally{Y=!1}}function ge(e,t,n){let a=F(e,!0),o={...F(e,!0),notes:n};M.push({label:t,timestamp:Date.now(),before:[a],after:[o]})}function At(){return M.canUndo()}function Pt(){return M.canRedo()}function Ye(e,t){e.preventDefault(),G(),s.selectedIds.has(t.id)||(s.selectedIds.clear(),s.selectedIds.add(t.id),s.lastClickedId=t.id,L());let n=v(r("div",{className:"context-menu",style:`top:${e.clientY}px;left:${e.clientX}px`}));je(n,"Category",s.categories.map(i=>({label:i.label,icon:`<span class="dropdown-dot" style="background-color:${i.color}"></span>`,active:t.category===i.id,action:()=>se("category",i.id)}))),je(n,"Priority",[{value:"highest",label:"Highest"},{value:"high",label:"High"},{value:"default",label:"Default"},{value:"low",label:"Low"},{value:"lowest",label:"Lowest"}].map(i=>({label:i.label,icon:A(i.value),iconColor:P(i.value),active:t.priority===i.value,action:()=>se("priority",i.value)}))),je(n,"Status",[{value:"not_started",label:"Not Started"},{value:"started",label:"Started"},{value:"completed",label:"Completed"},{value:"verified",label:"Verified"}].map(i=>({label:i.label,icon:z(i.value),active:t.status===i.value,action:()=>se("status",i.value)}))),oe(n,t.up_next?"\u2605 Up Next":"\u2606 Up Next",()=>{se("up_next",!t.up_next)}),Je(n),oe(n,"Tags...",()=>{document.dispatchEvent(new CustomEvent("hotsheet:show-tags-dialog"))}),oe(n,"Duplicate",async()=>{let i=Array.from(s.selectedIds),l=await f("/tickets/duplicate",{method:"POST",body:{ids:i}});s.selectedIds.clear();for(let c of l)s.selectedIds.add(c.id);w()}),Je(n),oe(n,"Move to Backlog",()=>se("status","backlog")),oe(n,"Archive",()=>se("status","archive")),Je(n),oe(n,"Delete",async()=>{if(s.selectedIds.size===1)await Se(t);else{let i=Array.from(s.selectedIds),l=s.tickets.filter(c=>s.selectedIds.has(c.id));await I(l,{ids:i,action:"delete"},"Delete")}s.selectedIds.clear(),w()},!0),document.body.appendChild(n),Hn(n),setTimeout(()=>{document.addEventListener("click",G),document.addEventListener("contextmenu",G)},0)}function G(){document.querySelectorAll(".context-menu").forEach(e=>e.remove()),document.removeEventListener("click",G),document.removeEventListener("contextmenu",G)}function Hn(e){let t=e.getBoundingClientRect();t.right>window.innerWidth-8&&(e.style.left=`${window.innerWidth-t.width-8}px`),t.bottom>window.innerHeight-8&&(e.style.top=`${window.innerHeight-t.height-8}px`)}async function se(e,t){let n=Array.from(s.selectedIds),a=s.tickets.filter(o=>s.selectedIds.has(o.id));if(n.length===1){let o=a[0];await R(o,{[e]:t},`Change ${e}`)}else await I(a,{ids:n,action:e,value:t},`Change ${e}`);w()}function je(e,t,n){let a=v(r("div",{className:"context-menu-item has-submenu",children:[r("span",{className:"context-menu-label",children:t}),r("span",{className:"context-menu-arrow",children:"\u25B8"})]})),o=v(r("div",{className:"context-submenu"}));for(let i of n){let l=v(r("div",{className:`context-menu-item${i.active?" active":""}`,children:[i.icon?r("span",{className:"dropdown-icon",style:i.iconColor?`color:${i.iconColor}`:"",children:D(i.icon)}):null,r("span",{className:"context-menu-label",children:i.label})]}));l.addEventListener("click",c=>{c.stopPropagation(),i.action(),G()}),o.appendChild(l)}a.appendChild(o),e.appendChild(a)}function oe(e,t,n,a=!1){let o=v(r("div",{className:`context-menu-item${a?" danger":""}`,children:r("span",{className:"context-menu-label",children:t})}));o.addEventListener("click",i=>{i.stopPropagation(),G(),n()}),e.appendChild(o)}function Je(e){e.appendChild(v(r("div",{className:"context-menu-separator"})))}function $(e,t){let n=t.getBoundingClientRect(),a=e.getBoundingClientRect(),o=window.innerWidth,i=window.innerHeight,l=n.left;l+a.width>o-8&&(l=n.right-a.width),l<8&&(l=8);let c=n.bottom+4;c+a.height>i-8&&(c=n.top-a.height-4),c<8&&(c=8),e.style.left=`${l}px`,e.style.top=`${c}px`}function N(e,t){let n=v(r("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(d=>d.separator?r("div",{className:"dropdown-separator"}):r("button",{className:`dropdown-item${d.active?" active":""}`,"data-key":d.key,children:[d.color?r("span",{className:"dropdown-dot",style:`background-color:${d.color}`}):null,d.icon?r("span",{className:"dropdown-icon",style:d.iconColor?`color:${d.iconColor}`:"",children:D(d.icon)}):null,r("span",{className:"dropdown-label",children:d.label}),d.shortcut?r("kbd",{className:"dropdown-kbd",children:d.shortcut}):null]}))})),a=t.filter(d=>!d.separator);n.querySelectorAll(".dropdown-item").forEach((d,u)=>{d.addEventListener("click",()=>{a[u].action(),n.remove()})});function i(d){let u=t.find(p=>d.key.toLowerCase()===p.key.toLowerCase());u?(d.preventDefault(),d.stopPropagation(),u.action(),l()):d.key==="Escape"&&(d.preventDefault(),l())}function l(){n.remove(),document.removeEventListener("keydown",i,!0),document.removeEventListener("click",c)}function c(){l()}return document.addEventListener("keydown",i,!0),setTimeout(()=>{document.addEventListener("click",c)},0),n}function B(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var ie=null;function Ze(){ie&&(clearTimeout(ie),ie=null)}var ve=!1,he=null,Xe="",U=[];function Me(){return s.categories.map(e=>({key:e.shortcutKey,value:e.id,label:e.label}))}var Ge=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}];function Dn(){let e=document.activeElement;if(!e||!(e instanceof HTMLElement))return null;let t=e.closest(".ticket-row");if(!t)return null;if(t.classList.contains("draft-row"))return"draft";let n=t.dataset.id;return n!==void 0&&n!==""?parseInt(n,10):null}function An(e){e!=null&&(ve=!0,e==="draft"?W():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),ve=!1)}function $e(){let e=s.view;return e.startsWith("custom:")?!0:e!=="completed"&&e!=="verified"&&e!=="trash"&&e!=="backlog"&&e!=="archive"}function Ut(){return s.view==="up-next"||s.view==="open"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"}]:s.view==="non-verified"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"},{status:"completed",label:"Completed"}]:[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"},{status:"completed",label:"Completed"},{status:"verified",label:"Verified"}]}function L(){let e=kt(),t=!!s.backupPreview?.active;if(s.layout==="columns"&&$e()){if(t){Rn(),Te(e);return}Un(),Te(e);return}let n=s.view==="trash",a=t?null:Dn(),o=null;if(a!=null&&a!=="draft"){let c=document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`);c&&(o=c.value)}let i=document.getElementById("ticket-list"),l=i.scrollTop;if(i.innerHTML="",i.classList.remove("ticket-list-columns"),!n&&!t&&i.appendChild(zt()),s.tickets.length===0){let c=n?"Trash is empty":t?"No tickets match this view":"";c&&i.appendChild(v(r("div",{className:"ticket-list-empty",children:c})))}for(let c of s.tickets)t?i.appendChild(Pn(c)):n?i.appendChild(Fn(c)):i.appendChild(zn(c));if(i.scrollTop=l,t){let c=document.getElementById("batch-toolbar");c&&(c.style.display="none"),be(),ne()}else{let c=document.getElementById("batch-toolbar");if(c&&(c.style.display=""),a!=null&&a!=="draft"&&o!=null){let d=document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`);d&&d.value!==o&&(d.value=o)}An(a),re()}Ie(),Te(e)}function Pn(e){let t=s.selectedIds.has(e.id),n=e.status==="completed"||e.status==="verified",a=e.status==="verified",o=v(r("div",{className:`ticket-row${t?" selected":""}${n?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("span",{className:"ticket-checkbox-spacer"}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)};cursor:default`,title:e.category,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:`ticket-status-btn${a?" verified":""}`,style:"cursor:default",children:D(a?Ue:z(e.status))}),r("span",{className:"ticket-title-input",style:"cursor:default",children:e.title}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,title:e.priority,children:D(A(e.priority))}),r("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}));return o.addEventListener("click",()=>{s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),ne()}),o}function Ot(e){let t={scrollLeft:0,columns:{}},n=e.querySelector(".columns-container");return n&&(t.scrollLeft=n.scrollLeft,n.querySelectorAll(".column[data-status]").forEach(a=>{let o=a.dataset.status,i=a.querySelector(".column-body");i&&(t.columns[o]=i.scrollTop)})),t}function Vt(e,t){let n=e.querySelector(".columns-container");n&&(n.scrollLeft=t.scrollLeft,n.querySelectorAll(".column[data-status]").forEach(a=>{let o=a.dataset.status,i=a.querySelector(".column-body");i&&t.columns[o]!=null&&(i.scrollTop=t.columns[o])}))}function Rn(){let e=document.getElementById("ticket-list"),t=Ot(e);e.innerHTML="",e.classList.add("ticket-list-columns");let n=Ut(),a=v(r("div",{className:"columns-container"}));for(let i of n){let l=s.tickets.filter(u=>u.status===i.status),c=v(r("div",{className:"column","data-status":i.status,children:[r("div",{className:"column-header",children:[r("span",{className:"column-title",children:i.label}),r("span",{className:"column-count",children:String(l.length)})]}),r("div",{className:"column-body"})]})),d=c.querySelector(".column-body");for(let u of l)d.appendChild(qn(u));a.appendChild(c)}e.appendChild(a),Vt(e,t);let o=document.getElementById("batch-toolbar");o&&(o.style.display="none"),Ie()}function qn(e){let t=s.selectedIds.has(e.id),n=v(r("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("div",{className:"column-card-header",children:[r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,children:D(A(e.priority))}),r("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}),r("div",{className:"column-card-title",children:e.title})]}));return n.addEventListener("click",()=>{s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,Kt(),ne()}),n}function Un(){let e=document.getElementById("ticket-list"),t=Ot(e);e.innerHTML="",e.classList.add("ticket-list-columns"),e.appendChild(zt());let n=Ut(),a=v(r("div",{className:"columns-container"}));for(let o of n){let i=s.tickets.filter(d=>d.status===o.status),l=v(r("div",{className:"column","data-status":o.status,children:[r("div",{className:"column-header",children:[r("span",{className:"column-title",children:o.label}),r("span",{className:"column-count",children:String(i.length)})]}),r("div",{className:"column-body"})]})),c=l.querySelector(".column-body");for(let d of i)c.appendChild(On(d));c.addEventListener("dragover",d=>{d.preventDefault(),d.dataTransfer.dropEffect="move",l.classList.add("column-drop-target")}),c.addEventListener("dragleave",d=>{let u=d.relatedTarget;(!u||!c.contains(u))&&l.classList.remove("column-drop-target")}),c.addEventListener("drop",d=>{d.preventDefault(),l.classList.remove("column-drop-target");let u=U;if(U=[],u.length===0)return;let p=s.tickets.filter(m=>u.includes(m.id));H(),I(p,{ids:u,action:"status",value:o.status},"Change status").then(()=>{w()})}),a.appendChild(l)}e.appendChild(a),Vt(e,t),re(),Ie()}function On(e){let t=s.selectedIds.has(e.id),n=v(r("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("div",{className:"column-card-header",children:[r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,children:D(A(e.priority))}),r("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}),r("div",{className:"column-card-title",children:e.title})]})),a=n.querySelector(".ticket-category-badge");a.addEventListener("click",i=>{i.stopPropagation(),Jt(a,e)});let o=n.querySelector(".ticket-priority-indicator");return o.addEventListener("click",i=>{i.stopPropagation(),Yt(o,e)}),n.querySelector(".ticket-star").addEventListener("click",i=>{i.stopPropagation(),jt(e)}),n.addEventListener("contextmenu",i=>{Ye(i,e)}),n.draggable=!0,n.addEventListener("dragstart",i=>{s.selectedIds.has(e.id)&&s.selectedIds.size>1?U=Array.from(s.selectedIds):U=[e.id],i.dataTransfer.setData("text/plain",JSON.stringify(U)),i.dataTransfer.effectAllowed="move"}),n.addEventListener("dragend",()=>{U=[]}),n.addEventListener("click",i=>{if(i.metaKey||i.ctrlKey)s.selectedIds.has(e.id)?s.selectedIds.delete(e.id):s.selectedIds.add(e.id),s.lastClickedId=e.id;else if(i.shiftKey&&s.lastClickedId!=null){let l=s.tickets.find(c=>c.id===s.lastClickedId);if(l&&l.status===e.status){let d=s.tickets.filter(m=>m.status===e.status).map(m=>m.id),u=d.indexOf(s.lastClickedId),p=d.indexOf(e.id);if(u!==-1&&p!==-1){let m=Math.min(u,p),g=Math.max(u,p);s.selectedIds.clear();for(let y=m;y<=g;y++)s.selectedIds.add(d[y])}}else s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id}else s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id;Kt(),re()}),n}function Kt(){document.querySelectorAll(".column-card[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10);s.selectedIds.has(t)?e.classList.add("selected"):e.classList.remove("selected")})}function zt(){let e=Ft(),t=s.view.startsWith("category:"),n=v(r("div",{className:"ticket-row draft-row",children:[r("span",{className:"ticket-checkbox-spacer"}),r("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),r("span",{className:"ticket-category-badge draft-badge",style:`background-color:${C(e)}${t?"":";cursor:pointer;opacity:1"}`,children:K(e)}),r("span",{className:"ticket-number draft-number"}),r("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket...",value:Xe}),r("span",{className:"ticket-priority-indicator draft-placeholder"}),r("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let o=n.querySelector(".ticket-category-badge");o.addEventListener("click",i=>{i.stopPropagation(),Kn(o)})}let a=n.querySelector(".draft-input");return a.addEventListener("input",()=>{Xe=a.value}),a.addEventListener("keydown",async o=>{if(o.key==="Enter"&&a.value.trim()){o.preventDefault();let i=a.value.trim();Xe="",a.value="";let l=Vn();he&&!s.view.startsWith("category:")&&(l.category=he);let c=await f("/tickets",{method:"POST",body:{title:i,defaults:l}});c&&(s.selectedIds.clear(),s.selectedIds.add(c.id)),await w(),W()}else o.key==="ArrowDown"&&(o.preventDefault(),s.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${s.tickets[0].id}"] .ticket-title-input`)?.focus())}),n}function W(){document.querySelector(".draft-row .draft-input")?.focus()}function Vn(){let e=s.view;return e==="up-next"?{up_next:!0}:e==="open"?{}:e==="completed"?{status:"completed"}:e==="backlog"?{status:"backlog"}:e==="archive"?{status:"archive"}:e.startsWith("category:")?{category:e.split(":")[1]}:e.startsWith("priority:")?{priority:e.split(":")[1]}:{}}function Ft(){if(he)return he;let e=s.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function Kn(e){B();let n=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=Ft(),o=N(e,Me().map(i=>({label:i.label,key:i.key,shortcut:`${n}${i.key.toUpperCase()}`,color:C(i.value),active:a===i.value,action:()=>{he=i.value,L(),W()}})));document.body.appendChild(o),$(o,e),o.style.visibility=""}function zn(e){let t=s.selectedIds.has(e.id),n=e.status==="completed"||e.status==="verified",a=e.status==="verified",o=v(r("div",{className:`ticket-row${t?" selected":""}${n?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,title:e.category,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("button",{className:`ticket-status-btn${a?" verified":""}`,title:e.status.replace("_"," "),children:D(a?Ue:z(e.status))}),r("input",{type:"text",className:"ticket-title-input",value:e.title}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,title:e.priority,children:D(A(e.priority))}),r("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}));o.addEventListener("mousedown",u=>{let p=u.target;p.tagName!=="INPUT"&&p.tagName!=="BUTTON"&&(o.draggable=!0)}),o.addEventListener("mouseup",()=>{o.draggable=!1}),o.addEventListener("dragend",()=>{o.draggable=!1,U=[]}),o.addEventListener("contextmenu",u=>{Ye(u,e)}),o.addEventListener("dragstart",u=>{s.selectedIds.has(e.id)&&s.selectedIds.size>1?U=Array.from(s.selectedIds):U=[e.id],u.dataTransfer.setData("text/plain",JSON.stringify(U)),u.dataTransfer.effectAllowed="move"}),o.addEventListener("mousedown",u=>{(u.metaKey||u.ctrlKey||u.shiftKey)&&(u.preventDefault(),Wt(u,e)&&u.stopPropagation())});let i=o.querySelector(".ticket-checkbox");i.addEventListener("click",u=>u.stopPropagation()),i.addEventListener("change",()=>{i.checked?s.selectedIds.add(e.id):s.selectedIds.delete(e.id),s.lastClickedId=e.id,L()}),o.querySelector(".ticket-status-btn").addEventListener("click",u=>{u.stopPropagation(),Yn(e)});let l=o.querySelector(".ticket-category-badge");l.addEventListener("click",u=>{u.stopPropagation(),Jt(l,e)});let c=o.querySelector(".ticket-title-input");c.addEventListener("focus",()=>{ve||s.selectedIds.size===1&&s.selectedIds.has(e.id)||(s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),re())}),c.addEventListener("input",()=>{Ce(e,"title",c.value),Gn(e.id,{title:c.value})}),c.addEventListener("keydown",u=>{Wn(u,e,c)});let d=o.querySelector(".ticket-priority-indicator");return d.addEventListener("click",u=>{u.stopPropagation(),Yt(d,e)}),o.querySelector(".ticket-star").addEventListener("click",u=>{u.stopPropagation(),jt(e)}),o}function Fn(e){let t=s.selectedIds.has(e.id),n=e.deleted_at?new Date(e.deleted_at):null,a=v(r("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[r("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),r("span",{className:"ticket-number",title:n?`Deleted: ${n.toLocaleString()}`:"",children:n?n.toLocaleDateString():""}),r("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));a.addEventListener("mousedown",i=>{(i.metaKey||i.ctrlKey||i.shiftKey)&&(i.preventDefault(),Wt(i,e)&&i.stopPropagation())});let o=a.querySelector(".ticket-checkbox");return o.addEventListener("click",i=>i.stopPropagation()),o.addEventListener("change",()=>{o.checked?s.selectedIds.add(e.id):s.selectedIds.delete(e.id),s.lastClickedId=e.id,L()}),a.querySelector(".trash-title").addEventListener("click",()=>{s.selectedIds.size===1&&s.selectedIds.has(e.id)||(s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),re())}),a.querySelector(".btn").addEventListener("click",async i=>{i.stopPropagation(),await Bt(e),w()}),a}function Wt(e,t){let n=e.metaKey||e.ctrlKey,a=e.shiftKey;if(n)s.selectedIds.has(t.id)?s.selectedIds.delete(t.id):s.selectedIds.add(t.id),s.lastClickedId=t.id,L();else if(a&&s.lastClickedId!=null){let o=s.tickets.map(c=>c.id),i=o.indexOf(s.lastClickedId),l=o.indexOf(t.id);if(i!==-1&&l!==-1){let c=Math.min(i,l),d=Math.max(i,l);s.selectedIds.clear();for(let u=c;u<=d;u++)s.selectedIds.add(o[u])}L()}else return!1;return!0}function Wn(e,t,n){if(e.key==="Enter")e.preventDefault(),W();else if(e.key==="Backspace"&&n.value==="")e.preventDefault(),Xn(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),Rt(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),Rt(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),jn(t.id);else if(e.key==="ArrowUp")e.preventDefault(),Jn(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&Me().some(a=>a.key===e.key)){e.preventDefault();let a=Me().find(o=>o.key===e.key);qt(t,"category",a.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&Ge.some(a=>a.key===e.key)){e.preventDefault();let a=Ge.find(o=>o.key===e.key);qt(t,"priority",a.value)}}function jn(e){let t=s.tickets.findIndex(n=>n.id===e);t<s.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${s.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function Jn(e){let t=s.tickets.findIndex(n=>n.id===e);t>0?document.querySelector(`.ticket-row[data-id="${s.tickets[t-1].id}"] .ticket-title-input`)?.focus():W()}function Rt(e,t){let a=s.tickets.findIndex(l=>l.id===e)+t;if(a<0||a>=s.tickets.length)return;let o=s.tickets[a].id;s.selectedIds.add(e),s.selectedIds.has(o)?s.selectedIds.delete(e):s.selectedIds.add(o),ve=!0,document.querySelector(`.ticket-row[data-id="${o}"] .ticket-title-input`)?.focus(),ve=!1,be(),re()}async function Yn(e){let n={not_started:"started",started:"completed",completed:"verified",verified:"not_started",backlog:"not_started",archive:"not_started"}[e.status]||"not_started",a=await R(e,{status:n},"Change status");Object.assign(e,a),L()}async function jt(e){!e.up_next&&(e.status==="completed"||e.status==="verified")?await R(e,{status:"not_started",up_next:!0},"Toggle up next"):await R(e,{up_next:!e.up_next},"Toggle up next"),w(),document.dispatchEvent(new CustomEvent("hotsheet:upnext-changed"))}async function qt(e,t,n){let a=await R(e,{[t]:n},`Change ${t}`);Object.assign(e,a),L()}async function Xn(e){let t=s.tickets.findIndex(a=>a.id===e),n=s.tickets.find(a=>a.id===e);if(n?await Se(n):await f(`/tickets/${e}`,{method:"DELETE"}),s.tickets=s.tickets.filter(a=>a.id!==e),s.selectedIds.delete(e),L(),t>0&&s.tickets.length>0){let a=Math.min(t-1,s.tickets.length-1);document.querySelector(`.ticket-row[data-id="${s.tickets[a].id}"] .ticket-title-input`)?.focus()}else W()}function Gn(e,t){ie&&clearTimeout(ie),ie=setTimeout(()=>{f(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function Jt(e,t){B();let a=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",o=N(e,Me().map(i=>({label:i.label,key:i.key,shortcut:`${a}${i.key.toUpperCase()}`,color:C(i.value),active:t.category===i.value,action:async()=>{let l=await R(t,{category:i.value},"Change category");Object.assign(t,l),L()}})));document.body.appendChild(o),$(o,e),o.style.visibility=""}function Yt(e,t){B();let n=N(e,Ge.map(a=>({label:a.label,key:a.key,shortcut:`Alt+${a.key}`,icon:A(a.value),iconColor:P(a.value),active:t.priority===a.value,action:async()=>{let o=await R(t,{priority:a.value},"Change priority");Object.assign(t,o),L()}})));document.body.appendChild(n),$(n,e),n.style.visibility=""}function be(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),n=e.querySelector(".ticket-checkbox");s.selectedIds.has(t)?(e.classList.add("selected"),n&&(n.checked=!0)):(e.classList.remove("selected"),n&&(n.checked=!1))})}function re(){let e=s.selectedIds.size,t=s.tickets.length,n=e>0,a=s.view==="trash",o=document.getElementById("batch-select-all");o.checked=t>0&&e===t,o.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=n?`${e} selected`:"";let i=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete","batch-more"];for(let p of i){let m=document.getElementById(p);m.style.display=a?"none":"",a||(m.disabled=!n)}let l=document.getElementById("batch-restore"),c=document.getElementById("batch-empty-trash");if(a){let p=document.getElementById("batch-toolbar");l||(l=v(r("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),l.addEventListener("click",async()=>{await f("/tickets/batch",{method:"POST",body:{ids:Array.from(s.selectedIds),action:"restore"}}),s.selectedIds.clear(),w()}),p.insertBefore(l,document.getElementById("batch-count"))),l.disabled=!n,l.style.display="",c||(c=v(r("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),c.addEventListener("click",async()=>{await f("/trash/empty",{method:"POST"}),s.selectedIds.clear(),w()}),p.insertBefore(c,document.getElementById("batch-count"))),c.disabled=t===0,c.style.display=""}else l&&(l.style.display="none"),c&&(c.style.display="none");let d=document.querySelector(".batch-star-icon"),u=document.getElementById("batch-upnext");if(!a&&d&&n){let p=s.tickets.filter(y=>s.selectedIds.has(y.id)),m=p.every(y=>y.up_next),g=p.every(y=>!y.up_next);m?(d.textContent="\u2605",u.classList.add("active"),u.classList.remove("mixed")):g?(d.textContent="\u2606",u.classList.remove("active","mixed")):(d.innerHTML=r("span",{className:"star-mixed-wrap",children:[r("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),u.classList.remove("active"),u.classList.add("mixed"))}else d&&(d.textContent="\u2606",u.classList.remove("active","mixed"));ne()}async function w(){if(s.backupPreview?.active){Zn();return}if(s.view.startsWith("custom:")){let n=s.view.slice(7),a=s.customViews.find(o=>o.id===n);a?s.tickets=await f("/tickets/query",{method:"POST",body:{logic:a.logic,conditions:a.conditions,sort_by:s.sortBy,sort_dir:s.sortDir}}):s.tickets=[],L();return}let e=new URLSearchParams;s.view==="trash"?e.set("status","deleted"):s.view==="up-next"?e.set("up_next","true"):s.view==="open"?e.set("status","open"):s.view==="completed"?e.set("status","completed"):s.view==="non-verified"?e.set("status","non_verified"):s.view==="verified"?e.set("status","verified"):s.view==="backlog"?e.set("status","backlog"):s.view==="archive"?e.set("status","archive"):s.view.startsWith("category:")?e.set("category",s.view.split(":")[1]):s.view.startsWith("priority:")?e.set("priority",s.view.split(":")[1]):e.set("status","active"),s.search&&e.set("search",s.search),e.set("sort_by",s.sortBy),e.set("sort_dir",s.sortDir);let t=e.toString();s.tickets=await f(`/tickets${t?"?"+t:""}`),L()}function Zn(){let e=[...s.backupPreview?.tickets||[]];if(s.view==="trash")e=e.filter(t=>t.status==="deleted");else if(s.view==="up-next")e=e.filter(t=>t.up_next&&t.status!=="deleted");else if(s.view==="open")e=e.filter(t=>t.status==="not_started"||t.status==="started");else if(s.view==="completed")e=e.filter(t=>t.status==="completed");else if(s.view==="non-verified")e=e.filter(t=>t.status!=="verified"&&t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");else if(s.view==="verified")e=e.filter(t=>t.status==="verified");else if(s.view==="backlog")e=e.filter(t=>t.status==="backlog");else if(s.view==="archive")e=e.filter(t=>t.status==="archive");else if(s.view.startsWith("category:")){let t=s.view.split(":")[1];e=e.filter(n=>n.category===t&&n.status!=="deleted"&&n.status!=="backlog"&&n.status!=="archive")}else if(s.view.startsWith("priority:")){let t=s.view.split(":")[1];e=e.filter(n=>n.priority===t&&n.status!=="deleted"&&n.status!=="backlog"&&n.status!=="archive")}else e=e.filter(t=>t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");if(s.search){let t=s.search.toLowerCase();e=e.filter(n=>n.title.toLowerCase().includes(t)||n.ticket_number.toLowerCase().includes(t)||n.details&&n.details.toLowerCase().includes(t))}s.tickets=e,L()}function Qn(e){let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/6e4);if(n<1)return"just now";if(n<60)return`${n}m ago`;let a=Math.floor(n/60);return a<24?`${a}h ago`:`${Math.floor(a/24)}d ago`}function ea(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function ta(e){return e==="5min"?"Recent (every 5 min)":e==="hourly"?"Hourly":e==="daily"?"Daily":e}async function Qe(){var t;let e=document.getElementById("backup-list");if(e)try{let n=await f("/backups");if(n.backups.length===0){e.textContent="No backups yet. First backup will be created shortly.";return}let a={};for(let o of n.backups)(a[t=o.tier]||(a[t]=[])).push(o);e.innerHTML="";for(let o of["5min","hourly","daily"]){let i=a[o];if(!(!i||i.length===0)){e.appendChild(v(r("div",{className:"backup-tier-label",children:ta(o)})));for(let l of i){let c=v(r("div",{className:"backup-row","data-tier":l.tier,"data-filename":l.filename,children:[r("span",{className:"backup-row-time",children:Qn(l.createdAt)}),r("span",{className:"backup-row-meta",children:[new Date(l.createdAt).toLocaleString()," \xB7 ",ea(l.sizeBytes)]})]}));c.addEventListener("click",()=>{na(l.tier,l.filename,l.createdAt)}),e.appendChild(c)}}}}catch{e.textContent="Failed to load backups."}}async function na(e,t,n){let a=document.getElementById("settings-overlay");a.style.display="none";let o=document.getElementById("backup-preview-banner"),i=document.getElementById("backup-preview-label");i.textContent="Loading backup preview...",o.style.display="flex";try{let l=await f(`/backups/preview/${e}/${t}`);s.backupPreview={active:!0,tickets:l.tickets,timestamp:n,tier:e,filename:t},s.selectedIds.clear(),s.activeTicketId=null,i.textContent=`Previewing backup from ${new Date(n).toLocaleString()} (${l.stats.total} tickets, ${l.stats.open} open) \u2014 read-only`,w()}catch{i.textContent="Failed to load backup preview.",setTimeout(()=>{o.style.display="none"},3e3)}}async function aa(){let e=document.getElementById("backup-preview-banner");e.style.display="none",s.backupPreview=null,s.selectedIds.clear(),s.activeTicketId=null,await f("/backups/preview/cleanup",{method:"POST"}),w()}async function sa(){if(!s.backupPreview)return;let e=document.getElementById("backup-restore-btn");e.textContent="Restoring...",e.disabled=!0;try{await f("/backups/restore",{method:"POST",body:{tier:s.backupPreview.tier,filename:s.backupPreview.filename}}),window.location.reload()}catch{e.textContent="Restore failed",e.disabled=!1,setTimeout(()=>{e.textContent="Restore This Backup"},3e3)}}function Xt(){document.getElementById("backup-cancel-btn")?.addEventListener("click",()=>{aa()}),document.getElementById("backup-restore-btn")?.addEventListener("click",()=>{sa()});let e=document.getElementById("backup-now-btn");e?.addEventListener("click",async()=>{e.textContent="Backing up...",e.disabled=!0;try{(await f("/backups/now",{method:"POST"})).error?e.textContent="In progress...":(e.textContent="Done!",Qe())}catch{e.textContent="Failed"}setTimeout(()=>{e.textContent="Backup Now",e.disabled=!1},1500)})}var Be,Z=null;function Qt(e){Be=e,document.getElementById("add-custom-view-btn").addEventListener("click",t=>{t.stopPropagation(),nt()})}async function en(){try{let e=await f("/settings");if(e.custom_views){let t=JSON.parse(e.custom_views);Array.isArray(t)&&(s.customViews=t)}}catch{}et()}function et(){let e=document.getElementById("custom-views-container");if(e&&(e.innerHTML="",s.customViews.length!==0)){e.appendChild(v(r("div",{className:"sidebar-divider"})));for(let t=0;t<s.customViews.length;t++){let n=s.customViews[t],a=v(r("button",{className:`sidebar-item sidebar-custom-view${s.view===`custom:${n.id}`?" active":""}`,"data-view":`custom:${n.id}`,"data-cv-index":String(t),draggable:"true",children:n.name}));a.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active")),a.classList.add("active"),s.view=`custom:${n.id}`,s.selectedIds.clear(),H(),Be()}),a.addEventListener("dblclick",o=>{o.preventDefault(),nt(n)}),a.addEventListener("contextmenu",o=>{o.preventDefault(),ra(a,n)}),a.addEventListener("dragstart",o=>{Z=t,o.dataTransfer.setData("text/plain",String(t)),o.dataTransfer.effectAllowed="move",setTimeout(()=>a.classList.add("dragging"),0)}),a.addEventListener("dragend",()=>{a.classList.remove("dragging"),Z=null}),a.addEventListener("dragover",o=>{Z!==null&&(o.preventDefault(),o.dataTransfer.dropEffect="move",a.classList.add("drop-target"))}),a.addEventListener("dragleave",()=>{a.classList.remove("drop-target")}),a.addEventListener("drop",o=>{if(o.preventDefault(),a.classList.remove("drop-target"),Z===null||Z===t)return;let[i]=s.customViews.splice(Z,1);s.customViews.splice(t,0,i),Z=null,tt()}),e.appendChild(a)}}}var oa='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/></svg>',ia='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/></svg>';function ra(e,t){B();let n=N(e,[{label:"Edit",key:"e",icon:oa,action:()=>nt(t)},{label:"Delete",key:"d",icon:ia,action:()=>la(t.id)}]);document.body.appendChild(n),$(n,e),n.style.visibility=""}async function tt(){await f("/settings",{method:"PATCH",body:{custom_views:JSON.stringify(s.customViews)}}),et()}async function la(e){s.customViews=s.customViews.filter(t=>t.id!==e),s.view===`custom:${e}`&&(s.view="all",document.querySelectorAll(".sidebar-item").forEach(t=>{t.classList.toggle("active",t.dataset.view==="all")}),Be()),await tt()}var Ne=[{value:"category",label:"Category",type:"select"},{value:"priority",label:"Priority",type:"ordinal"},{value:"status",label:"Status",type:"ordinal"},{value:"title",label:"Title",type:"text"},{value:"details",label:"Details",type:"text"},{value:"up_next",label:"Up Next",type:"boolean"},{value:"tags",label:"Tags",type:"text"}];function Gt(e){return e==="ordinal"?[{value:"equals",label:"="},{value:"not_equals",label:"\u2260"},{value:"lt",label:"<"},{value:"lte",label:"\u2264"},{value:"gt",label:">"},{value:"gte",label:"\u2265"}]:e==="select"?[{value:"equals",label:"is"},{value:"not_equals",label:"is not"}]:e==="boolean"?[{value:"equals",label:"is"}]:[{value:"contains",label:"contains"},{value:"not_contains",label:"does not contain"}]}var ca=["highest","high","default","low","lowest"],da=["not_started","started","completed","verified","backlog","archive"];function Zt(e){return e==="category"?s.categories.map(t=>t.id):e==="priority"?ca:e==="status"?da:e==="up_next"?["true","false"]:null}function ua(e,t){return e==="category"?s.categories.find(a=>a.id===t)?.label||t:e==="status"?t.replace(/_/g," "):e==="up_next"?t==="true"?"Yes":"No":t}function nt(e){let t=!!e,n=e?e.conditions.map(d=>({...d})):[],a=e?.logic||"all",o=e?.name||"",i=v(r("div",{className:"custom-view-editor-overlay",children:r("div",{className:"custom-view-editor",children:[r("div",{className:"custom-view-editor-header",children:[r("span",{children:t?"Edit Custom View":"New Custom View"}),r("button",{className:"detail-close",id:"cv-editor-close",children:"\xD7"})]}),r("div",{className:"custom-view-editor-body",children:[r("div",{className:"settings-field",children:[r("label",{children:"Name"}),r("input",{type:"text",id:"cv-name",value:o,placeholder:"View name..."})]}),r("div",{className:"cv-logic-row",children:[r("span",{children:"Match"}),r("label",{children:[r("input",{type:"radio",name:"cv-logic",value:"all",checked:a==="all"})," All of"]}),r("label",{children:[r("input",{type:"radio",name:"cv-logic",value:"any",checked:a==="any"})," Any of"]})]}),r("div",{id:"cv-conditions"}),r("button",{className:"btn btn-sm",id:"cv-add-condition",style:"margin-top:8px",children:"+ Add Condition"})]}),r("div",{className:"custom-view-editor-footer",children:[r("button",{className:"btn btn-sm",id:"cv-cancel",children:"Cancel"}),r("button",{className:"btn btn-sm btn-accent",id:"cv-save",children:"Save"})]})]})}));function l(){let d=i.querySelector("#cv-conditions");d.innerHTML="",n.forEach((u,p)=>{let m=Ne.find(T=>T.value===u.field)||Ne[0],g=Gt(m.type),y=Zt(u.field),b=v(r("div",{className:"cv-condition-row",children:[r("select",{className:"cv-field-select",children:Ne.map(T=>r("option",{value:T.value,selected:T.value===u.field,children:T.label}))}),r("select",{className:"cv-op-select",children:g.map(T=>r("option",{value:T.value,selected:T.value===u.operator,children:T.label}))}),y?r("select",{className:"cv-value-select",children:y.map(T=>r("option",{value:T,selected:T===u.value,children:ua(u.field,T)}))}):r("input",{type:"text",className:"cv-value-input",value:u.value,placeholder:"Value..."}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]})),E=b.querySelector(".cv-field-select"),x=b.querySelector(".cv-op-select"),k=b.querySelector(".cv-value-select")||b.querySelector(".cv-value-input");E.addEventListener("change",()=>{let T=E.value,_=Ne.find(ee=>ee.value===T),de=Gt(_.type);n[p].field=T,n[p].operator=de[0].value;let Q=Zt(T);n[p].value=Q?Q[0]:"",l()}),x.addEventListener("change",()=>{n[p].operator=x.value}),k.addEventListener("change",()=>{n[p].value=k.value}),k.tagName==="INPUT"&&k.addEventListener("input",()=>{n[p].value=k.value}),b.querySelector(".category-delete-btn").addEventListener("click",()=>{n.splice(p,1),l()}),d.appendChild(b)})}l(),document.body.appendChild(i),i.querySelector("#cv-name").focus(),i.querySelectorAll('input[name="cv-logic"]').forEach(d=>{d.addEventListener("change",()=>{a=d.value})}),i.querySelector("#cv-add-condition").addEventListener("click",()=>{n.push({field:"category",operator:"equals",value:s.categories[0]?.id||"issue"}),l()});let c=()=>i.remove();i.querySelector("#cv-editor-close").addEventListener("click",c),i.querySelector("#cv-cancel").addEventListener("click",c),i.addEventListener("click",d=>{d.target===i&&c()}),i.querySelector("#cv-save").addEventListener("click",async()=>{if(o=i.querySelector("#cv-name").value.trim(),!o){i.querySelector("#cv-name").focus();return}let d={id:e?.id||o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||`view-${Date.now()}`,name:o,logic:a,conditions:n.filter(u=>u.value!=="")};if(t){let u=s.customViews.findIndex(p=>p.id===e.id);u>=0?s.customViews[u]=d:s.customViews.push(d)}else s.customViews.push(d);await tt(),document.querySelectorAll(".sidebar-item").forEach(u=>u.classList.remove("active")),s.view=`custom:${d.id}`,s.selectedIds.clear(),et(),Be(),c()})}var le=30;async function st(e){e.innerHTML='<div class="dashboard-loading">Loading dashboard...</div>';try{let t=await f(`/dashboard?days=${le}`);e.innerHTML="",e.appendChild(pa(t))}catch{e.innerHTML='<div class="dashboard-loading">Failed to load dashboard data.</div>'}}function pa(e){let t=v(r("div",{className:"dashboard"})),n=v(r("div",{className:"dashboard-range-bar",children:[r("button",{className:`btn btn-sm${le===7?" active":""}`,"data-days":"7",children:"7 days"}),r("button",{className:`btn btn-sm${le===30?" active":""}`,"data-days":"30",children:"30 days"}),r("button",{className:`btn btn-sm${le===90?" active":""}`,"data-days":"90",children:"90 days"})]}));n.querySelectorAll("button").forEach(m=>{m.addEventListener("click",()=>{le=parseInt(m.dataset.days,10);let g=document.getElementById("dashboard-container");g&&st(g)})}),t.appendChild(n);let a=e.kpi,o=a.completedLastWeek>0?Math.round((a.completedThisWeek-a.completedLastWeek)/a.completedLastWeek*100):0,i=o>0?"\u2191":o<0?"\u2193":"",l=a.createdThisWeek>0?(a.completedThisWeek/a.createdThisWeek).toFixed(1):"\u2014";t.appendChild(v(r("div",{className:"dashboard-kpi-row",children:[r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(a.completedThisWeek)}),r("div",{className:"kpi-label",children:"Completed this week"}),i?r("div",{className:`kpi-trend${o>0?" up":" down"}`,children:[i," ",Math.abs(o),"%"]}):null]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:a.medianCycleTimeDays!==null?`${a.medianCycleTimeDays}d`:"\u2014"}),r("div",{className:"kpi-label",children:"Median cycle time"})]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(a.wipCount)}),r("div",{className:"kpi-label",children:"In progress"})]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(l)}),r("div",{className:"kpi-label",children:"Completed / created"})]})]})));let c=v(r("div",{className:"dashboard-grid"})),d=ke("Throughput","Items completed per day. Shows your sustainable delivery pace.",ma(e.throughput));at(d,e.throughput.map(m=>({date:m.date,lines:[{label:"Completed",color:"#3b82f6",value:m.completed}]}))),c.appendChild(d);let u=ke("Created vs Completed","Compares items created (orange) vs completed (green) over time. When created outpaces completed, the backlog grows.",ga(e.throughput));at(u,e.throughput.map(m=>({date:m.date,lines:[{label:"Completed",color:"#22c55e",value:m.completed},{label:"Created",color:"#f97316",value:m.created}]}))),c.appendChild(u);let p=ke("Cumulative Flow","Stacked area showing ticket counts by status over time. Widening bands indicate bottlenecks. A healthy flow has consistent band widths.",fa(e.snapshots));return at(p,e.snapshots.map(m=>({date:m.date,lines:[{label:"Not Started",color:"#6b7280",value:m.data.not_started},{label:"Started",color:"#3b82f6",value:m.data.started},{label:"Completed",color:"#22c55e",value:m.data.completed},{label:"Verified",color:"#8b5cf6",value:m.data.verified}]}))),c.appendChild(p),c.appendChild(ke("Category Breakdown","Distribution of tickets by category. Left: currently open. Right: all tickets active in the selected time period.",ya(e.categoryBreakdown,e.categoryPeriod))),c.appendChild(ke("Cycle Time","Each dot is a completed ticket plotted by completion date and days to complete. Dashed lines show 50th and 85th percentile delivery times.",va(e.cycleTime))),t.appendChild(c),t}function ke(e,t,n){let a=v(r("div",{className:"dashboard-chart-card",children:[r("div",{className:"dashboard-chart-header",children:[r("span",{className:"dashboard-chart-title",children:e}),r("button",{className:"dashboard-info-btn",title:"About this chart",children:r("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r("circle",{cx:"12",cy:"12",r:"10"}),r("path",{d:"M12 16v-4"}),r("path",{d:"M12 8h.01"})]})})]}),r("div",{className:"dashboard-chart-info",style:"display:none",children:t}),r("div",{className:"dashboard-chart-body",children:D(n)})]})),o=a.querySelector(".dashboard-info-btn"),i=a.querySelector(".dashboard-chart-info");return o.addEventListener("click",l=>{l.stopPropagation(),i.style.display=i.style.display==="none"?"":"none"}),a}function at(e,t){let n=e.querySelector(".dashboard-chart-body");if(!n||t.length===0)return;let a=document.createElement("div");a.className="chart-cursor",a.style.display="none",n.style.position="relative",n.appendChild(a);let o=document.createElement("div");o.className="chart-tooltip",o.style.display="none",n.appendChild(o);let i=n.querySelector("svg");i&&(i.addEventListener("mousemove",l=>{let c=i.getBoundingClientRect(),d=n.getBoundingClientRect(),u=c.left-d.left,p=c.top-d.top,m=q/c.width,g=O/c.height,y=(l.clientX-c.left)*m,b=q-h.left-h.right,E=Math.max(0,Math.min(1,(y-h.left)/b)),x=Math.round(E*(t.length-1));if(x<0||x>=t.length)return;let k=h.left+x/Math.max(t.length-1,1)*b,T=u+k/m,_=p+h.top/g,de=(O-h.top-h.bottom)/g;a.style.display="",a.style.left=`${T}px`,a.style.top=`${_}px`,a.style.height=`${de}px`;let Q=t[x];o.style.display="",o.innerHTML=`<div class="chart-tooltip-date">${ot(Q.date)}</div>${Q.lines.map(ue=>`<div class="chart-tooltip-row"><span class="chart-legend-dot" style="background:${ue.color}"></span>${ue.label}: <b>${ue.value}</b></div>`).join("")}`;let ee=T+10;ee+120>d.width?o.style.left=`${T-120}px`:o.style.left=`${ee}px`,o.style.top=`${l.clientY-d.top-10}px`}),i.addEventListener("mouseleave",()=>{a.style.display="none",o.style.display="none"}))}var q=400,O=180,h={top:10,right:10,bottom:25,left:35};function ma(e){if(e.length===0)return'<div class="chart-empty">No data</div>';let t=e.map(c=>c.completed),n=Math.max(...t,1),a=q-h.left-h.right,o=O-h.top-h.bottom,i=Math.max(2,a/e.length-2),l="";for(let c=0;c<e.length;c++){let d=h.left+c/e.length*a,u=t[c]/n*o,p=h.top+o-u,m=ot(e[c].date);l+=`<rect x="${d}" y="${p}" width="${i}" height="${u}" fill="#3b82f6" rx="1" opacity="0.8" class="chart-hover"><title>${m}: ${t[c]} completed</title></rect>`}return`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
2
+ ${it(n,o)}
3
3
  ${l}
4
- ${Be(e.map(c=>c.date))}
5
- </svg>`}function ma(e){if(e.length<2)return'<div class="chart-empty">Not enough data</div>';let t=Math.max(...e.map(l=>Math.max(l.completed,l.created)),1),n=q-h.left-h.right,a=O-h.top-h.bottom,o='<div class="chart-legend"><span class="chart-legend-item"><span class="chart-legend-dot" style="background:#22c55e"></span>Completed</span><span class="chart-legend-item"><span class="chart-legend-dot" style="background:#f97316"></span>Created</span></div>',i=`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
6
- ${ot(t,a)}
7
- <path d="${tn(e.map(l=>l.created),t,n,a)}" fill="none" stroke="#f97316" stroke-width="2" opacity="0.7"/>
8
- <path d="${tn(e.map(l=>l.completed),t,n,a)}" fill="none" stroke="#22c55e" stroke-width="2"/>
9
- ${Be(e.map(l=>l.date))}
10
- </svg>`;return o+i}function ga(e){if(e.length<2)return'<div class="chart-empty">Not enough data</div>';let t=["verified","completed","started","not_started"],n={not_started:"#6b7280",started:"#3b82f6",completed:"#22c55e",verified:"#8b5cf6"},a={not_started:"Not Started",started:"Started",completed:"Completed",verified:"Verified"},o=`<div class="chart-legend">${t.map(g=>`<span class="chart-legend-item"><span class="chart-legend-dot" style="background:${n[g]}"></span>${a[g]}</span>`).join("")}</div>`,i=e.map(g=>{let y=0;return t.map(b=>(y+=g.data[b]||0,y))}),l=Math.max(...i.map(g=>g[g.length-1]),1),c=q-h.left-h.right,d=O-h.top-h.bottom,u=e.length,p="";for(let g=t.length-1;g>=0;g--){let y=i.map((E,x)=>{let k=h.left+x/(u-1)*c,T=h.top+d-E[g]/l*d;return`${k},${T}`}),b=g>0?i.map((E,x)=>{let k=h.left+x/(u-1)*c,T=h.top+d-E[g-1]/l*d;return`${k},${T}`}).reverse():[`${h.left+c},${h.top+d}`,`${h.left},${h.top+d}`];p+=`<polygon points="${y.join(" ")} ${b.join(" ")}" fill="${n[t[g]]}" opacity="0.6"/>`}let m=`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
4
+ ${_e(e.map(c=>c.date))}
5
+ </svg>`}function ga(e){if(e.length<2)return'<div class="chart-empty">Not enough data</div>';let t=Math.max(...e.map(l=>Math.max(l.completed,l.created)),1),n=q-h.left-h.right,a=O-h.top-h.bottom,o='<div class="chart-legend"><span class="chart-legend-item"><span class="chart-legend-dot" style="background:#22c55e"></span>Completed</span><span class="chart-legend-item"><span class="chart-legend-dot" style="background:#f97316"></span>Created</span></div>',i=`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
6
+ ${it(t,a)}
7
+ <path d="${nn(e.map(l=>l.created),t,n,a)}" fill="none" stroke="#f97316" stroke-width="2" opacity="0.7"/>
8
+ <path d="${nn(e.map(l=>l.completed),t,n,a)}" fill="none" stroke="#22c55e" stroke-width="2"/>
9
+ ${_e(e.map(l=>l.date))}
10
+ </svg>`;return o+i}function fa(e){if(e.length<2)return'<div class="chart-empty">Not enough data</div>';let t=["verified","completed","started","not_started"],n={not_started:"#6b7280",started:"#3b82f6",completed:"#22c55e",verified:"#8b5cf6"},a={not_started:"Not Started",started:"Started",completed:"Completed",verified:"Verified"},o=`<div class="chart-legend">${t.map(g=>`<span class="chart-legend-item"><span class="chart-legend-dot" style="background:${n[g]}"></span>${a[g]}</span>`).join("")}</div>`,i=e.map(g=>{let y=0;return t.map(b=>(y+=g.data[b]||0,y))}),l=Math.max(...i.map(g=>g[g.length-1]),1),c=q-h.left-h.right,d=O-h.top-h.bottom,u=e.length,p="";for(let g=t.length-1;g>=0;g--){let y=i.map((E,x)=>{let k=h.left+x/(u-1)*c,T=h.top+d-E[g]/l*d;return`${k},${T}`}),b=g>0?i.map((E,x)=>{let k=h.left+x/(u-1)*c,T=h.top+d-E[g-1]/l*d;return`${k},${T}`}).reverse():[`${h.left+c},${h.top+d}`,`${h.left},${h.top+d}`];p+=`<polygon points="${y.join(" ")} ${b.join(" ")}" fill="${n[t[g]]}" opacity="0.6"/>`}let m=`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
11
11
  ${p}
12
- ${Be(e.map(g=>g.date))}
13
- </svg>`;return o+m}function fa(e,t){let n=new Map;for(let c of[...e,...t])if(!n.has(c.category)){let d=s.categories.find(u=>u.id===c.category);n.set(c.category,{color:C(c.category),label:d?.label||c.category})}let a=`<div class="chart-legend">${Array.from(n.values()).map(c=>`<span class="chart-legend-item"><span class="chart-legend-dot" style="background:${c.color}"></span>${c.label}</span>`).join("")}</div>`,o=en(e,"Open",90),i=en(t,`${re}d active`,290),l=`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">${o}${i}</svg>`;return a+l}function en(e,t,n){if(e.length===0)return`<text x="${n}" y="95" text-anchor="middle" fill="#9ca3af" font-size="11">No data</text>`;let a=e.reduce((u,p)=>u+p.count,0),o=95,i=60,l=38,c=-Math.PI/2,d="";for(let u of e){let p=u.count/a*Math.PI*2,m=n+i*Math.cos(c),g=o+i*Math.sin(c),y=n+i*Math.cos(c+p),b=o+i*Math.sin(c+p),E=n+l*Math.cos(c+p),x=o+l*Math.sin(c+p),k=n+l*Math.cos(c),T=o+l*Math.sin(c),_=p>Math.PI?1:0,ce=C(u.category),ee=s.categories.find(de=>de.id===u.category)?.label||u.category;d+=`<path d="M ${m} ${g} A ${i} ${i} 0 ${_} 1 ${y} ${b} L ${E} ${x} A ${l} ${l} 0 ${_} 0 ${k} ${T} Z" fill="${ce}" opacity="0.8" class="chart-hover"><title>${ee}: ${u.count}</title></path>`,c+=p}return d+=`<text x="${n}" y="${o+4}" text-anchor="middle" fill="currentColor" font-size="16" font-weight="600">${a}</text>`,d+=`<text x="${n}" y="${o+17}" text-anchor="middle" fill="#6b7280" font-size="9">${t}</text>`,d}function ya(e){if(e.length===0)return'<div class="chart-empty">No completed tickets</div>';let t=Math.max(...e.map(E=>E.days),1),n=q-h.left-h.right,a=O-h.top-h.bottom,o=e.map(E=>new Date(E.completed_at).getTime()),i=Math.min(...o),c=Math.max(...o)-i||1,d="";for(let E of e){let x=h.left+(new Date(E.completed_at).getTime()-i)/c*n,k=h.top+a-E.days/t*a;d+=`<circle cx="${x}" cy="${k}" r="4" fill="#3b82f6" opacity="0.5" class="chart-hover"><title>${E.ticket_number}: ${E.title}
12
+ ${_e(e.map(g=>g.date))}
13
+ </svg>`;return o+m}function ya(e,t){let n=new Map;for(let c of[...e,...t])if(!n.has(c.category)){let d=s.categories.find(u=>u.id===c.category);n.set(c.category,{color:C(c.category),label:d?.label||c.category})}let a=`<div class="chart-legend">${Array.from(n.values()).map(c=>`<span class="chart-legend-item"><span class="chart-legend-dot" style="background:${c.color}"></span>${c.label}</span>`).join("")}</div>`,o=tn(e,"Open",90),i=tn(t,`${le}d active`,290),l=`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">${o}${i}</svg>`;return a+l}function tn(e,t,n){if(e.length===0)return`<text x="${n}" y="95" text-anchor="middle" fill="#9ca3af" font-size="11">No data</text>`;let a=e.reduce((u,p)=>u+p.count,0),o=95,i=60,l=38,c=-Math.PI/2,d="";for(let u of e){let p=u.count/a*Math.PI*2,m=n+i*Math.cos(c),g=o+i*Math.sin(c),y=n+i*Math.cos(c+p),b=o+i*Math.sin(c+p),E=n+l*Math.cos(c+p),x=o+l*Math.sin(c+p),k=n+l*Math.cos(c),T=o+l*Math.sin(c),_=p>Math.PI?1:0,de=C(u.category),ee=s.categories.find(ue=>ue.id===u.category)?.label||u.category;d+=`<path d="M ${m} ${g} A ${i} ${i} 0 ${_} 1 ${y} ${b} L ${E} ${x} A ${l} ${l} 0 ${_} 0 ${k} ${T} Z" fill="${de}" opacity="0.8" class="chart-hover"><title>${ee}: ${u.count}</title></path>`,c+=p}return d+=`<text x="${n}" y="${o+4}" text-anchor="middle" fill="currentColor" font-size="16" font-weight="600">${a}</text>`,d+=`<text x="${n}" y="${o+17}" text-anchor="middle" fill="#6b7280" font-size="9">${t}</text>`,d}function va(e){if(e.length===0)return'<div class="chart-empty">No completed tickets</div>';let t=Math.max(...e.map(E=>E.days),1),n=q-h.left-h.right,a=O-h.top-h.bottom,o=e.map(E=>new Date(E.completed_at).getTime()),i=Math.min(...o),c=Math.max(...o)-i||1,d="";for(let E of e){let x=h.left+(new Date(E.completed_at).getTime()-i)/c*n,k=h.top+a-E.days/t*a;d+=`<circle cx="${x}" cy="${k}" r="4" fill="#3b82f6" opacity="0.5" class="chart-hover"><title>${E.ticket_number}: ${E.title}
14
14
  ${E.days} days</title></circle>`}let u=e.map(E=>E.days).sort((E,x)=>E-x),p=u[Math.floor(u.length*.5)],m=u[Math.floor(u.length*.85)],g=h.top+a-p/t*a,y=h.top+a-m/t*a,b=`
15
15
  <line x1="${h.left}" y1="${g}" x2="${h.left+n}" y2="${g}" stroke="#22c55e" stroke-dasharray="4,4" opacity="0.6"/>
16
16
  <text x="${h.left+n+2}" y="${g+3}" fill="#22c55e" font-size="9">50% (${p}d)</text>
17
17
  <line x1="${h.left}" y1="${y}" x2="${h.left+n}" y2="${y}" stroke="#f97316" stroke-dasharray="4,4" opacity="0.6"/>
18
18
  <text x="${h.left+n+2}" y="${y+3}" fill="#f97316" font-size="9">85% (${m}d)</text>
19
19
  `;return`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
20
- ${ot(t,a,"d")}
20
+ ${it(t,a,"d")}
21
21
  ${d}
22
22
  ${b}
23
- ${Be(e.map(E=>E.completed_at.slice(0,10)))}
24
- </svg>`}function st(e){let t=new Date(e);return`${t.getMonth()+1}/${t.getDate()}`}function tn(e,t,n,a){return e.map((o,i)=>{let l=h.left+i/(e.length-1)*n,c=h.top+a-o/t*a;return`${i===0?"M":"L"} ${l} ${c}`}).join(" ")}function ot(e,t,n=""){let o="";for(let i=0;i<=4;i++){let l=Math.round(e/4*i),c=h.top+t-i/4*t;o+=`<line x1="${h.left}" y1="${c}" x2="${q-h.right}" y2="${c}" stroke="#e5e7eb" stroke-width="0.5"/>`,o+=`<text x="${h.left-4}" y="${c+3}" text-anchor="end" fill="#9ca3af" font-size="9">${l}${n}</text>`}return o}function Be(e){if(e.length===0)return"";let t=O,n=q-h.left-h.right,a="",o=e.length<=7?e.map((i,l)=>l):[0,Math.floor(e.length/2),e.length-1];for(let i of o){let l=h.left+i/Math.max(e.length-1,1)*n;a+=`<text x="${l}" y="${t-4}" text-anchor="middle" fill="#9ca3af" font-size="9">${st(e[i])}</text>`}return a}async function nn(){let e=v(r("div",{className:"sidebar-dashboard-widget",id:"sidebar-dashboard-widget"}));try{let t=await f("/dashboard?days=7"),n=t.kpi,a=n.completedLastWeek>0?Math.round((n.completedThisWeek-n.completedLastWeek)/n.completedLastWeek*100):0,o=a>0?"\u2191":a<0?"\u2193":"",i=t.throughput.slice(-7),l=Math.max(...i.map(d=>d.completed),1),c=i.map((d,u)=>{let p=d.completed/l*20;return`<rect x="${u*14}" y="${20-p}" width="10" height="${p}" fill="#3b82f6" rx="1" opacity="0.7"/>`}).join("");e.innerHTML=`
23
+ ${_e(e.map(E=>E.completed_at.slice(0,10)))}
24
+ </svg>`}function ot(e){let t=new Date(e);return`${t.getMonth()+1}/${t.getDate()}`}function nn(e,t,n,a){return e.map((o,i)=>{let l=h.left+i/(e.length-1)*n,c=h.top+a-o/t*a;return`${i===0?"M":"L"} ${l} ${c}`}).join(" ")}function it(e,t,n=""){let o="";for(let i=0;i<=4;i++){let l=Math.round(e/4*i),c=h.top+t-i/4*t;o+=`<line x1="${h.left}" y1="${c}" x2="${q-h.right}" y2="${c}" stroke="#e5e7eb" stroke-width="0.5"/>`,o+=`<text x="${h.left-4}" y="${c+3}" text-anchor="end" fill="#9ca3af" font-size="9">${l}${n}</text>`}return o}function _e(e){if(e.length===0)return"";let t=O,n=q-h.left-h.right,a="",o=e.length<=7?e.map((i,l)=>l):[0,Math.floor(e.length/2),e.length-1];for(let i of o){let l=h.left+i/Math.max(e.length-1,1)*n;a+=`<text x="${l}" y="${t-4}" text-anchor="middle" fill="#9ca3af" font-size="9">${ot(e[i])}</text>`}return a}async function an(){let e=v(r("div",{className:"sidebar-dashboard-widget",id:"sidebar-dashboard-widget"}));try{let t=await f("/dashboard?days=7"),n=t.kpi,a=n.completedLastWeek>0?Math.round((n.completedThisWeek-n.completedLastWeek)/n.completedLastWeek*100):0,o=a>0?"\u2191":a<0?"\u2193":"",i=t.throughput.slice(-7),l=Math.max(...i.map(d=>d.completed),1),c=i.map((d,u)=>{let p=d.completed/l*20;return`<rect x="${u*14}" y="${20-p}" width="10" height="${p}" fill="#3b82f6" rx="1" opacity="0.7"/>`}).join("");e.innerHTML=`
25
25
  <div class="sidebar-widget-spark"><svg viewBox="0 0 98 20" width="98" height="20">${c}</svg></div>
26
26
  <div class="sidebar-widget-stats">
27
27
  <span class="sidebar-widget-value">${n.completedThisWeek} completed</span>
28
28
  ${o?`<span class="sidebar-widget-trend ${a>0?"up":"down"}">${o}${Math.abs(a)}%</span>`:""}
29
29
  </div>
30
30
  <div class="sidebar-widget-wip">${n.wipCount} in progress</div>
31
- `}catch{e.innerHTML='<div class="sidebar-widget-stats">Dashboard</div>'}return e}function it(){let e=s.view==="dashboard",t=s.selectedIds.size>0,n=s.activeTicketId!=null,a=v(r("div",{className:"print-dialog-overlay",children:r("div",{className:"print-dialog",children:[r("div",{className:"print-dialog-header",children:[r("span",{children:"Print"}),r("button",{className:"detail-close",id:"print-close",children:"\xD7"})]}),r("div",{className:"print-dialog-body",children:[r("div",{className:"settings-field",children:[r("label",{children:"What to print"}),r("select",{id:"print-scope",children:[e?r("option",{value:"dashboard",children:"Dashboard"}):null,e?null:r("option",{value:"view",children:"All tickets in current view"}),!e&&t?r("option",{value:"selected",children:["Selected tickets (",String(s.selectedIds.size),")"]}):null,!e&&n?r("option",{value:"current",children:"Current ticket detail"}):null]})]}),r("div",{className:"settings-field",id:"print-format-field",children:[r("label",{children:"Format"}),r("select",{id:"print-format",children:[r("option",{value:"checklist",children:"Checklist (titles only)"}),r("option",{value:"summary",children:"Summary (title, category, priority, status)"}),r("option",{value:"full",children:"Full details"})]})]})]}),r("div",{className:"print-dialog-footer",children:[r("button",{className:"btn btn-sm",id:"print-cancel",children:"Cancel"}),r("button",{className:"btn btn-sm btn-accent",id:"print-go",children:"Print"})]})]})})),o=a.querySelector("#print-scope"),i=a.querySelector("#print-format-field"),l=()=>{i.style.display=o.value==="dashboard"?"none":""};o.addEventListener("change",l),l();let c=()=>a.remove();a.querySelector("#print-close").addEventListener("click",c),a.querySelector("#print-cancel").addEventListener("click",c),a.addEventListener("click",d=>{d.target===a&&c()}),a.querySelector("#print-go").addEventListener("click",()=>{let d=o.value,u=a.querySelector("#print-format").value;if(c(),d==="dashboard")ha();else{let p=va(d);ba(p,u)}}),document.body.appendChild(a)}function va(e){if(e==="selected")return s.tickets.filter(t=>s.selectedIds.has(t.id));if(e==="current"&&s.activeTicketId!=null){let t=s.tickets.find(n=>n.id===s.activeTicketId);return t?[t]:[]}return s.tickets}function an(e){let t=`<!DOCTYPE html><html><head>
31
+ `}catch{e.innerHTML='<div class="sidebar-widget-stats">Dashboard</div>'}return e}function rt(){let e=s.view==="dashboard",t=s.selectedIds.size>0,n=s.activeTicketId!=null,a=v(r("div",{className:"print-dialog-overlay",children:r("div",{className:"print-dialog",children:[r("div",{className:"print-dialog-header",children:[r("span",{children:"Print"}),r("button",{className:"detail-close",id:"print-close",children:"\xD7"})]}),r("div",{className:"print-dialog-body",children:[r("div",{className:"settings-field",children:[r("label",{children:"What to print"}),r("select",{id:"print-scope",children:[e?r("option",{value:"dashboard",children:"Dashboard"}):null,e?null:r("option",{value:"view",children:"All tickets in current view"}),!e&&t?r("option",{value:"selected",children:["Selected tickets (",String(s.selectedIds.size),")"]}):null,!e&&n?r("option",{value:"current",children:"Current ticket detail"}):null]})]}),r("div",{className:"settings-field",id:"print-format-field",children:[r("label",{children:"Format"}),r("select",{id:"print-format",children:[r("option",{value:"checklist",children:"Checklist (titles only)"}),r("option",{value:"summary",children:"Summary (title, category, priority, status)"}),r("option",{value:"full",children:"Full details"})]})]})]}),r("div",{className:"print-dialog-footer",children:[r("button",{className:"btn btn-sm",id:"print-cancel",children:"Cancel"}),r("button",{className:"btn btn-sm btn-accent",id:"print-go",children:"Print"})]})]})})),o=a.querySelector("#print-scope"),i=a.querySelector("#print-format-field"),l=()=>{i.style.display=o.value==="dashboard"?"none":""};o.addEventListener("change",l),l();let c=()=>a.remove();a.querySelector("#print-close").addEventListener("click",c),a.querySelector("#print-cancel").addEventListener("click",c),a.addEventListener("click",d=>{d.target===a&&c()}),a.querySelector("#print-go").addEventListener("click",()=>{let d=o.value,u=a.querySelector("#print-format").value;if(c(),d==="dashboard")ba();else{let p=ha(d);ka(p,u)}}),document.body.appendChild(a)}function ha(e){if(e==="selected")return s.tickets.filter(t=>s.selectedIds.has(t.id));if(e==="current"&&s.activeTicketId!=null){let t=s.tickets.find(n=>n.id===s.activeTicketId);return t?[t]:[]}return s.tickets}function sn(e){let t=`<!DOCTYPE html><html><head>
32
32
  <meta charset="utf-8">
33
33
  <title>Hot Sheet</title>
34
- <style>${rt()}</style>
35
- </head><body>${e}</body></html>`;f("/print",{method:"POST",body:{html:t}})}function ha(){let e=document.getElementById("dashboard-container");e&&an(`<style>${rt()}
34
+ <style>${lt()}</style>
35
+ </head><body>${e}</body></html>`;f("/print",{method:"POST",body:{html:t}})}function ba(){let e=document.getElementById("dashboard-container");e&&sn(`<style>${lt()}
36
36
  .dashboard-grid { grid-template-columns: 1fr 1fr; }
37
37
  .dashboard-kpi-row { grid-template-columns: repeat(4, 1fr); }
38
38
  .dashboard-chart-body svg { max-width: 100%; }
39
39
  .chart-cursor, .chart-tooltip, .dashboard-info-btn, .dashboard-range-bar, .dashboard-chart-info { display: none !important; }
40
- </style>${e.innerHTML}`)}function ba(e,t){let n="";t==="checklist"?n=`<h2>Checklist</h2><div class="print-checklist">${e.map(a=>`<div class="print-check-item"><span class="print-checkbox">\u25A1</span><span>${S(a.ticket_number)}: ${S(a.title)}</span></div>`).join("")}</div>`:t==="summary"?n=`<h2>Ticket Summary</h2><table class="print-table">
40
+ </style>${e.innerHTML}`)}function ka(e,t){let n="";t==="checklist"?n=`<h2>Checklist</h2><div class="print-checklist">${e.map(a=>`<div class="print-check-item"><span class="print-checkbox">\u25A1</span><span>${S(a.ticket_number)}: ${S(a.title)}</span></div>`).join("")}</div>`:t==="summary"?n=`<h2>Ticket Summary</h2><table class="print-table">
41
41
  <thead><tr><th>Ticket</th><th>Title</th><th>Category</th><th>Priority</th><th>Status</th><th>Up Next</th></tr></thead>
42
42
  <tbody>${e.map(a=>{let o=s.categories.find(i=>i.id===a.category);return`<tr>
43
43
  <td>${S(a.ticket_number)}</td>
@@ -59,7 +59,7 @@ ${E.days} days</title></circle>`}let u=e.map(E=>E.days).sort((E,x)=>E-x),p=u[Mat
59
59
  </div>
60
60
  ${a.details.trim()?`<div class="print-ticket-details">${S(a.details)}</div>`:""}
61
61
  ${l.length>0?`<div class="print-ticket-notes"><strong>Notes:</strong>${l.map(c=>`<div class="print-note">${c.created_at?`<span class="print-note-time">${new Date(c.created_at).toLocaleString()}</span>`:""}${S(c.text)}</div>`).join("")}</div>`:""}
62
- </div>`}).join(""),an(`<style>${rt()}</style>${n}`)}function S(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function rt(){return`
62
+ </div>`}).join(""),sn(`<style>${lt()}</style>${n}`)}function S(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function lt(){return`
63
63
  * { box-sizing: border-box; margin: 0; padding: 0; }
64
64
  body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 12px; color: #111; padding: 20px; }
65
65
  h2 { font-size: 16px; margin-bottom: 12px; }
@@ -94,7 +94,7 @@ ${E.days} days</title></circle>`}let u=e.map(E=>E.days).sort((E,x)=>E-x),p=u[Mat
94
94
  .chart-legend-item { display: inline-flex; align-items: center; gap: 4px; }
95
95
  .chart-legend-dot { width: 8px; height: 8px; border-radius: 50%; }
96
96
  @media print { body { padding: 0; } }
97
- `}async function ka(){try{await wa(),await Ea(),await Qt(),Ta(),H(),await w(),_a(),$a(),Na(),Ha(),Da(),Ua(),Oa(),za(),xa(),Yt(),Sa(),Ma(),Zt(()=>{w()}),$t(),Fa(),Ia(),document.addEventListener("hotsheet:render",()=>L()),document.addEventListener("hotsheet:show-tags-dialog",()=>{hn()}),document.addEventListener("hotsheet:upnext-changed",()=>vt()),document.getElementById("print-btn")?.addEventListener("click",it),gn(),qa(),W()}catch(e){console.error("Hot Sheet init failed:",e);let t=document.getElementById("ticket-list");t&&(t.innerHTML=`<div style="padding:20px;color:red">Init error: ${e}</div>`)}}async function wa(){try{let e=await f("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(s.settings.detail_position=e.detail_position),e.detail_width&&(s.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(s.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(s.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(s.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30),(e.layout==="list"||e.layout==="columns")&&(s.layout=e.layout)}catch{}Ve(s.settings.detail_position),Ke()}async function Ea(){try{let e=await f("/categories");e.length>0&&(s.categories=e)}catch{}gt()}function gt(){let e=document.getElementById("sidebar-categories");if(e){let t=e.querySelector(".sidebar-label");e.innerHTML="",t&&e.appendChild(t);for(let n of s.categories){let a=v(r("button",{className:`sidebar-item${s.view===`category:${n.id}`?" active":""}`,"data-view":`category:${n.id}`,children:[r("span",{className:"cat-dot",style:`background:${n.color}`})," ",n.label]}));a.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active")),a.classList.add("active"),s.view=`category:${n.id}`,s.selectedIds.clear(),ht(),H(),w()}),e.appendChild(a)}}if(s.activeTicketId!=null){let t=s.tickets.find(n=>n.id===s.activeTicketId);t&&fe(t.category)}}async function Ta(){try{let e=await f("/file-settings");if(e.appName){document.title=e.appName;let t=document.querySelector(".app-title h1");t&&(t.textContent=e.appName)}}catch{}}function xa(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close"),n=document.getElementById("settings-btn"),a=document.querySelectorAll(".settings-tab"),o=document.querySelectorAll(".settings-tab-panel");a.forEach(k=>{k.addEventListener("click",()=>{let T=k.dataset.tab;a.forEach(_=>_.classList.remove("active")),o.forEach(_=>_.classList.remove("active")),k.classList.add("active"),document.querySelector(`.settings-tab-panel[data-panel="${T}"]`)?.classList.add("active")})}),n.addEventListener("click",()=>{document.getElementById("settings-trash-days").value=String(s.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(s.settings.verified_cleanup_days),e.style.display="flex",Ze(),f("/file-settings").then(k=>{document.getElementById("settings-app-name").value=k.appName||"",document.getElementById("settings-backup-dir").value=k.backupDir||""})}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",k=>{k.target===e&&(e.style.display="none")});let i=document.getElementById("settings-trash-days"),l=null;i.addEventListener("input",()=>{l&&clearTimeout(l),l=setTimeout(()=>{let k=Math.max(1,parseInt(i.value,10)||3);i.value=String(k),s.settings.trash_cleanup_days=k,f("/settings",{method:"PATCH",body:{trash_cleanup_days:String(k)}})},500)});let c=document.getElementById("settings-verified-days"),d=null;c.addEventListener("input",()=>{d&&clearTimeout(d),d=setTimeout(()=>{let k=Math.max(1,parseInt(c.value,10)||30);c.value=String(k),s.settings.verified_cleanup_days=k,f("/settings",{method:"PATCH",body:{verified_cleanup_days:String(k)}})},500)});let u=document.getElementById("settings-app-name"),p=document.getElementById("settings-app-name-hint"),m=null;u.addEventListener("input",()=>{m&&clearTimeout(m),m=setTimeout(()=>{let k=u.value.trim();f("/file-settings",{method:"PATCH",body:{appName:k}}).then(()=>{let T=k||"Hot Sheet";document.title=T;let _=document.querySelector(".app-title h1");_&&(_.textContent=T),p.textContent=k?"Saved. Restart the desktop app to update the title bar.":"Using default name."})},800)});let g=document.getElementById("check-updates-btn"),y=document.getElementById("check-updates-status");g.addEventListener("click",async()=>{let k=ft();if(k){g.disabled=!0,g.textContent="Checking...",y.textContent="";try{let T=await k("check_for_update");T?(y.textContent=`Update available: v${T}`,document.getElementById("settings-overlay").style.display="none",pn(T)):y.textContent="Your software is up to date."}catch{y.textContent="Could not check for updates."}g.textContent="Check for Updates",g.disabled=!1}});let b=document.getElementById("settings-backup-dir"),E=document.getElementById("settings-backup-dir-hint"),x=null;b.addEventListener("input",()=>{x&&clearTimeout(x),x=setTimeout(()=>{let k=b.value.trim();f("/file-settings",{method:"PATCH",body:{backupDir:k}}).then(()=>{E.textContent=k?"Saved. New backups will use this location.":"Using default location inside the data directory."})},800)}),Aa(),La()}function He(){let e=document.getElementById("category-list");e.innerHTML="";for(let t=0;t<s.categories.length;t++){let n=s.categories[t],a=v(r("div",{className:"category-row",children:[r("input",{type:"color",className:"category-color-input",value:n.color,title:"Color"}),r("input",{type:"text",className:"category-label-input",value:n.label,placeholder:"Label",title:"Display name"}),r("input",{type:"text",className:"category-short-input",value:n.shortLabel,placeholder:"ABR",title:"Short label (3 chars)",maxlength:"4"}),r("input",{type:"text",className:"category-key-input",value:n.shortcutKey,placeholder:"k",title:"Keyboard shortcut",maxlength:"1"}),r("input",{type:"text",className:"category-desc-input",value:n.description,placeholder:"Description...",title:"Description (for AI tools)"}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]})),o=a.querySelectorAll("input"),[i,l,c,d,u]=o,p=()=>{on()};i.addEventListener("input",()=>{s.categories[t].color=i.value,p()}),l.addEventListener("input",()=>{s.categories[t].label=l.value,(!n.id||n.id==="")&&(s.categories[t].id=l.value.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")),p()}),c.addEventListener("input",()=>{s.categories[t].shortLabel=c.value.toUpperCase(),p()}),d.addEventListener("input",()=>{let m=d.value.toLowerCase().slice(0,1);d.value=m,s.categories[t].shortcutKey=m,sn(),p()}),u.addEventListener("input",()=>{s.categories[t].description=u.value,p()}),a.querySelector(".category-delete-btn").addEventListener("click",()=>{s.categories.splice(t,1),He(),on()}),e.appendChild(a)}sn()}function sn(){let e=document.querySelectorAll(".category-key-input"),t=new Map;s.categories.forEach((n,a)=>{if(n.shortcutKey){let o=n.shortcutKey.toLowerCase();t.has(o)||t.set(o,[]),t.get(o).push(a)}}),e.forEach((n,a)=>{let o=s.categories[a]?.shortcutKey?.toLowerCase();o&&t.get(o).length>1?n.classList.add("category-key-conflict"):n.classList.remove("category-key-conflict")})}var lt=null;function on(){lt&&clearTimeout(lt),lt=setTimeout(async()=>{await f("/categories",{method:"PUT",body:s.categories}),gt()},500)}function La(){document.getElementById("category-add-btn").addEventListener("click",()=>{s.categories.push({id:"",label:"",shortLabel:"",color:"#6b7280",shortcutKey:"",description:""}),He();let n=document.querySelectorAll(".category-row");n[n.length-1]?.querySelector(".category-label-input")?.focus()});let e=document.getElementById("category-preset-select");f("/category-presets").then(n=>{for(let a of n)e.appendChild(v(r("option",{value:a.id,children:a.name})))}),e.addEventListener("change",async()=>{if(!e.value)return;let a=(await f("/category-presets")).find(o=>o.id===e.value);a&&(s.categories=[...a.categories],await f("/categories",{method:"PUT",body:s.categories}),He(),gt()),e.value=""}),document.getElementById("settings-btn").addEventListener("click",()=>{He()})}async function Ia(){let e=ft();if(!e)return;let t=document.getElementById("settings-updates-section");t&&(t.style.display="");let n=document.getElementById("settings-tab-updates");n&&(n.style.display="");let a=[0,3e3,1e4];for(let o of a){o>0&&await new Promise(i=>setTimeout(i,o));try{let i=await e("get_pending_update");if(i){pn(i);return}}catch{return}}}function ft(){return window.__TAURI__?.core?.invoke??null}function pn(e){let t=document.getElementById("update-banner");if(!t)return;let n=document.getElementById("update-banner-label");n&&(n.textContent=`Update available: v${e}`),t.style.display="flex";let a=document.getElementById("update-install-btn");a?.addEventListener("click",async()=>{if(a){a.textContent="Installing...",a.disabled=!0;try{await ft()?.("install_update"),n&&(n.textContent="Update installed! Restart the app to apply."),a.style.display="none"}catch{a.textContent="Install Failed",a.disabled=!1}}}),document.getElementById("update-banner-dismiss")?.addEventListener("click",()=>{t.style.display="none"})}function Ca(){let e=document.getElementById("skills-banner");if(!e)return;e.style.display="flex",document.getElementById("skills-banner-dismiss")?.addEventListener("click",()=>{e.style.display="none"})}function Sa(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),n=document.getElementById("copy-prompt-label"),a=document.getElementById("copy-prompt-icon"),o="";f("/worklist-info").then(i=>{o=i.prompt,e.style.display="",i.skillCreated&&Ca()}),t.addEventListener("click",()=>{o!==""&&navigator.clipboard.writeText(o).then(()=>{n.textContent="Copied!",a.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>',setTimeout(()=>{n.textContent="Copy AI prompt",a.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>'},1500)})})}function Ma(){let e=document.getElementById("glassbox-btn"),t=document.getElementById("glassbox-icon");f("/glassbox/status").then(({available:n})=>{n&&(t.src="/static/assets/glassbox-icon.png",e.style.display="")}).catch(()=>{}),e.addEventListener("click",()=>{f("/glassbox/launch",{method:"POST"})})}function ut(){let e=document.getElementById("layout-toggle"),t=Me(),n=e.querySelector('[data-layout="columns"]');n.disabled=!t,n.style.opacity=t?"":"0.3";let a=s.layout==="columns"&&!t?"list":s.layout;e.querySelectorAll(".layout-btn").forEach(o=>{o.classList.toggle("active",o.dataset.layout===a)})}function $a(){document.getElementById("layout-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let n=t.dataset.layout;n==="columns"&&!Me()||(s.layout=n,H(),ut(),L(),f("/settings",{method:"PATCH",body:{layout:n}}))})}),ut()}function rn(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.classList.toggle("active",t.dataset.position===s.settings.detail_position)})}function Na(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let n=t.dataset.position;s.settings.detail_position=n,Ve(n),Ke(),rn(),f("/settings",{method:"PATCH",body:{detail_position:n}})})}),rn()}function mn(e){return e==="up-next"?{action:"up_next",value:!0}:e==="open"?{action:"status",value:"not_started"}:e==="completed"?{action:"status",value:"completed"}:e==="verified"?{action:"status",value:"verified"}:e==="backlog"?{action:"status",value:"backlog"}:e==="archive"?{action:"status",value:"archive"}:e==="trash"?{action:"delete",value:null}:e.startsWith("category:")?{action:"category",value:e.split(":")[1]}:e.startsWith("priority:")?{action:"priority",value:e.split(":")[1]}:null}async function Ba(e,t){let n=mn(e);if(!n)return;let a=s.tickets.filter(o=>t.includes(o.id));n.action==="delete"?await I(a,{ids:t,action:"delete"},"Delete tickets"):await I(a,{ids:t,action:n.action,value:n.value},`Change ${n.action}`),H(),w()}function _a(){document.querySelectorAll(".sidebar-item[data-view]").forEach(t=>{t.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(a=>a.classList.remove("active")),t.classList.add("active"),s.view=t.dataset.view,s.selectedIds.clear(),ht(),H(),ut(),w()});let n=t.dataset.view;mn(n)&&(t.addEventListener("dragover",a=>{a.preventDefault(),a.dataTransfer.dropEffect="move",t.classList.add("drop-target")}),t.addEventListener("dragleave",()=>{t.classList.remove("drop-target")}),t.addEventListener("drop",a=>{a.preventDefault(),t.classList.remove("drop-target");let o=[...U];o.length!==0&&Ba(n,o)}))})}function Ha(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,n]=e.value.split(":");s.sortBy=t,s.sortDir=n,H(),w()})}var ct=null;function Da(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{ct&&clearTimeout(ct),ct=setTimeout(()=>{s.search=e.value,H(),w()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",s.search="",H(),w())})}var X=[];function Aa(){let e=document.getElementById("settings-tab-experimental"),t=document.getElementById("settings-experimental-panel"),n=document.getElementById("settings-channel-enabled"),a=document.getElementById("settings-channel-hint"),o=document.getElementById("settings-channel-instructions"),i=document.getElementById("settings-channel-copy-btn"),l=document.getElementById("settings-channel-cmd"),c=document.getElementById("settings-custom-commands-section");document.getElementById("settings-btn").addEventListener("click",()=>{fetch("/api/channel/claude-check").then(d=>d.ok?d.json():null).then(d=>{if(!d||!d.installed){e.style.display="none",t.style.display="none";return}e.style.display="",t.style.display="",d.meetsMinimum?(a.textContent="Push worklist events to a running Claude Code session via MCP channels.",n.disabled=!1):(a.textContent=`Claude Code ${d.version||"unknown"} detected but v2.1.80+ is required. Please upgrade Claude Code.`,n.disabled=!0),pt()}).catch(()=>{e.style.display="none",t.style.display="none"})}),fetch("/api/channel/status").then(d=>d.ok?d.json():null).then(d=>{d&&(n.checked=d.enabled,d.enabled&&(o.style.display="",c.style.display=""))}).catch(()=>{}),f("/settings").then(d=>{if(d.custom_commands)try{X=JSON.parse(d.custom_commands)}catch{}De()}),n.addEventListener("change",async()=>{n.checked?(await f("/channel/enable",{method:"POST"}),o.style.display="",c.style.display=""):(await f("/channel/disable",{method:"POST"}),o.style.display="none",c.style.display="none"),gn(),De()}),i?.addEventListener("click",()=>{let d=l?.textContent||"";navigator.clipboard.writeText(d).then(()=>{i&&(i.textContent="Copied!",setTimeout(()=>{i.textContent="Copy"},1500))})}),document.getElementById("settings-add-command-btn")?.addEventListener("click",()=>{X.push({name:"",prompt:""}),pt()})}function pt(){let e=document.getElementById("settings-commands-list");if(e){e.innerHTML="";for(let t=0;t<X.length;t++){let n=X[t],a=v(r("div",{className:"settings-command-row",children:[r("div",{className:"settings-command-row-header",children:[r("input",{type:"text",value:n.name,placeholder:"Button label..."}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]}),r("label",{children:"Prompt sent to Claude:"}),r("textarea",{placeholder:"Tell Claude what to do...",children:n.prompt})]})),o=a.querySelector("input"),i=a.querySelector("textarea"),l=()=>{X[t]={name:o.value,prompt:i.value},ln()};o.addEventListener("input",l),i.addEventListener("input",l),a.querySelector(".category-delete-btn").addEventListener("click",()=>{X.splice(t,1),pt(),ln()}),e.appendChild(a)}}}async function ln(){await f("/settings",{method:"PATCH",body:{custom_commands:JSON.stringify(X)}}),De()}function De(){let e=document.getElementById("channel-commands-container");if(!e)return;e.innerHTML="";let t=document.getElementById("channel-play-section");if(!(!t||t.style.display==="none"))for(let n of X){if(!n.name.trim()||!n.prompt.trim())continue;let a=v(r("button",{className:"channel-command-btn",children:n.name}));a.addEventListener("click",()=>{yt(n.prompt)}),e.appendChild(a)}}var we=!1,_e=null,Ae=!1;function mt(e){Ae=e;let t=document.getElementById("channel-status-indicator");if(!t)return;let n=document.getElementById("channel-play-section");if(!n||n.style.display==="none"){t.style.display="none";return}e?(t.style.display="",t.className="channel-status-indicator busy",t.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg> Claude working'):(t.style.display="",t.className="channel-status-indicator",t.innerHTML="\u2713 Claude idle",setTimeout(()=>{!Ae&&t&&(t.style.display="none")},5e3))}var le=null;function yt(e){mt(!0),f("/channel/trigger",{method:"POST",body:{message:e}}),le&&clearTimeout(le),le=setTimeout(()=>{Ae&&mt(!1)},12e4)}async function gn(){let e={enabled:!1,alive:!1};try{let l=await fetch("/api/channel/status");l.ok&&(e=await l.json())}catch{}let t=document.getElementById("channel-play-section"),n=document.getElementById("channel-play-btn"),a=document.getElementById("channel-play-icon"),o=document.getElementById("channel-auto-icon");if(!e.enabled){t.style.display="none";return}t.style.display="",De();let i=null;n.addEventListener("click",()=>{i?(clearTimeout(i),i=null,cn(n,a,o)):i=setTimeout(()=>{i=null,we?cn(n,a,o):(n.classList.add("pulsing"),setTimeout(()=>n.classList.remove("pulsing"),600),yt())},250)})}function cn(e,t,n){we=!we,we?(e.classList.add("auto-mode"),t.style.display="none",n.style.display=""):(e.classList.remove("auto-mode"),t.style.display="",n.style.display="none")}function vt(){we&&(_e&&clearTimeout(_e),_e=setTimeout(()=>{_e=null,yt()},5e3))}function ht(){let e=document.getElementById("dashboard-container");e&&(e.id="ticket-list",e.innerHTML="",Ra())}var fn=["search-input","layout-toggle","sort-select","detail-position-toggle","glassbox-btn"];function Pa(){s.view="dashboard",document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active"));for(let o of fn){let i=document.getElementById(o);if(i){let l=i.closest(".search-box, .layout-toggle, .sort-controls")||i;l.style.display="none"}}let e=document.getElementById("batch-toolbar");e&&(e.style.display="none");let t=document.getElementById("detail-panel");t&&(t.style.display="none");let n=document.getElementById("detail-resize-handle");n&&(n.style.display="none");let a=document.getElementById("ticket-list");a.innerHTML="",a.id="dashboard-container",a.classList.remove("ticket-list-columns"),at(a)}function Ra(){for(let e of fn){let t=document.getElementById(e);if(t){let n=t.closest(".search-box, .layout-toggle, .sort-controls")||t;n.style.display=""}}ht()}async function qa(){let e=await nn(),t=document.getElementById("stats-bar");t&&t.after(e),e.addEventListener("click",()=>Pa())}var yn=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}],vn=[{key:"n",value:"not_started",label:"Not Started"},{key:"s",value:"started",label:"Started"},{key:"c",value:"completed",label:"Completed"},{key:"v",value:"verified",label:"Verified"},{key:"b",value:"backlog",label:"Backlog"},{key:"a",value:"archive",label:"Archive"}];function Ua(){let e=document.getElementById("batch-category");e.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(e,s.categories.map(l=>({label:l.label,key:l.shortcutKey,color:l.color,action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"category",value:l.id},"Batch change category"),w()}})));document.body.appendChild(i),$(i,e),i.style.visibility=""});let t=document.getElementById("batch-priority");t.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(t,yn.map(l=>({label:l.label,key:l.key,icon:A(l.value),iconColor:P(l.value),action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"priority",value:l.value},"Batch change priority"),w()}})));document.body.appendChild(i),$(i,t),i.style.visibility=""});let n=document.getElementById("batch-status");n.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(n,vn.map(l=>({label:l.label,key:l.key,icon:z(l.value),action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"status",value:l.value},"Batch change status"),w()}})));document.body.appendChild(i),$(i,n),i.style.visibility=""}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let o=s.tickets.filter(d=>s.selectedIds.has(d.id)),l=!o.every(d=>d.up_next),c=Array.from(s.selectedIds);if(l){let d=o.filter(u=>u.status==="completed"||u.status==="verified");if(d.length>0){let u=[{ids:d.map(p=>p.id),action:"status",value:"not_started"},{ids:c,action:"up_next",value:!0}];await Fe(o,u,"Batch toggle up next")}else await I(o,{ids:c,action:"up_next",value:!0},"Batch toggle up next")}else await I(o,{ids:c,action:"up_next",value:!1},"Batch toggle up next");w(),vt()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let o=Array.from(s.selectedIds),i=s.tickets.filter(l=>s.selectedIds.has(l.id));await I(i,{ids:o,action:"delete"},"Batch delete"),s.selectedIds.clear(),w()});let a=document.getElementById("batch-more");a.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(a,[{label:"Tags...",key:"t",action:()=>{hn()}},{label:"Duplicate",key:"d",action:async()=>{let l=Array.from(s.selectedIds),c=await f("/tickets/duplicate",{method:"POST",body:{ids:l}});s.selectedIds.clear();for(let d of c)s.selectedIds.add(d.id);w()}},{label:"",key:"",separator:!0,action:()=>{}},{label:"Move to Backlog",key:"b",action:async()=>{let l=Array.from(s.selectedIds),c=s.tickets.filter(d=>s.selectedIds.has(d.id));await I(c,{ids:l,action:"status",value:"backlog"},"Move to backlog"),s.selectedIds.clear(),w()}},{label:"Archive",key:"a",action:async()=>{let l=Array.from(s.selectedIds),c=s.tickets.filter(d=>s.selectedIds.has(d.id));await I(c,{ids:l,action:"status",value:"archive"},"Archive"),s.selectedIds.clear(),w()}}]);document.body.appendChild(i),$(i,a),i.style.visibility=""}),document.getElementById("batch-select-all").addEventListener("change",o=>{if(o.target.checked)for(let l of s.tickets)s.selectedIds.add(l.id);else s.selectedIds.clear();L()})}var j=null;function Oa(){document.getElementById("detail-close").addEventListener("click",Ct);let e=["detail-title","detail-details"];for(let u of e){let p=document.getElementById(u);p.addEventListener("input",()=>{let m=s.tickets.find(g=>g.id===s.activeTicketId);if(m){let g=u.replace("detail-","");Ie(m,g,p.value)}j&&clearTimeout(j),j=setTimeout(()=>{if(s.activeTicketId==null)return;let g=u.replace("detail-","");f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{[g]:p.value}}).then(()=>{w()})},300)})}async function t(u,p){if(s.activeTicketId==null)return;let m=s.tickets.find(g=>g.id===s.activeTicketId);m?await R(m,{[u]:p},`Change ${u}`):await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{[u]:p}}),w(),te(s.activeTicketId)}document.getElementById("detail-category").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,s.categories.map(y=>({label:y.label,key:y.shortcutKey,color:y.color,active:y.id===m,action:()=>{fe(y.id),t("category",y.id)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-priority").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,yn.map(y=>({label:y.label,key:y.key,icon:A(y.value),iconColor:P(y.value),active:y.value===m,action:()=>{Te(y.value),t("priority",y.value)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-status").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,vn.map(y=>({label:y.label,key:y.key,icon:z(y.value),active:y.value===m,action:()=>{xe(y.value),t("status",y.value)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-upnext").addEventListener("click",async()=>{if(s.activeTicketId==null)return;let u=s.tickets.find(p=>p.id===s.activeTicketId);u?!u.up_next&&(u.status==="completed"||u.status==="verified")?await R(u,{status:"not_started",up_next:!0},"Toggle up next"):await R(u,{up_next:!u.up_next},"Toggle up next"):await f(`/tickets/${s.activeTicketId}/up-next`,{method:"POST"}),w(),vt(),te(s.activeTicketId)}),document.getElementById("detail-add-note-btn")?.addEventListener("click",async()=>{if(s.activeTicketId==null)return;let u=s.tickets.find(p=>p.id===s.activeTicketId);if(u){let p=u.notes;await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{notes:"(new note)"}});let m=await f(`/tickets/${s.activeTicketId}`);me({...u,notes:p},"Add note",m.notes),u.notes=m.notes}te(s.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async u=>{let p=u.target,m=p.files?.[0];!m||s.activeTicketId==null||(await Tt(`/tickets/${s.activeTicketId}/attachments`,m),p.value="",te(s.activeTicketId),w())}),document.getElementById("detail-attachments").addEventListener("click",async u=>{let p=u.target,m=p.closest(".attachment-reveal");if(m){let b=m.dataset.attId;b&&f(`/attachments/${b}/reveal`,{method:"POST"});return}let g=p.closest(".attachment-delete");if(g===null)return;let y=g.dataset.attId;y===void 0||y===""||(await f(`/attachments/${y}`,{method:"DELETE"}),s.activeTicketId!=null&&te(s.activeTicketId))});let n=document.getElementById("detail-tag-input"),a=null,o=-1,i=[];f("/tags").then(u=>{i=u});function l(){a?.remove(),a=null,o=-1}function c(){l();let u=n.value.trim().toLowerCase();if(!u)return;let p=s.tickets.find(b=>b.id===s.activeTicketId),m=p?V(p.tags):[],g=i.filter(b=>b.toLowerCase().includes(u)&&!m.includes(b));if(g.length===0)return;a=v(r("div",{className:"tag-autocomplete"}));for(let b=0;b<g.length;b++){let E=v(r("div",{className:"tag-autocomplete-item",children:g[b]}));E.addEventListener("mousedown",x=>{x.preventDefault(),n.value=g[b],l(),d()}),a.appendChild(E)}let y=n.getBoundingClientRect();a.style.position="fixed",a.style.left=`${y.left}px`,a.style.top=`${y.bottom+2}px`,a.style.width=`${y.width}px`,document.body.appendChild(a)}async function d(){let u=n.value.trim();if(!u||s.activeTicketId==null)return;let p=s.tickets.find(y=>y.id===s.activeTicketId);if(!p)return;let m=V(p.tags);if(m.includes(u)){n.value="";return}let g=[...m,u];n.value="",l(),await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{tags:JSON.stringify(g)}}),p.tags=JSON.stringify(g),ge(g,!1),i.includes(u)||i.push(u)}n.addEventListener("input",()=>{c()}),n.addEventListener("blur",()=>{l()}),n.addEventListener("keydown",u=>{if(u.key==="Enter"){if(u.preventDefault(),a&&o>=0){let p=a.querySelectorAll(".tag-autocomplete-item");n.value=p[o]?.textContent||n.value}l(),d()}else if(u.key==="Escape")l();else if(u.key==="ArrowDown"&&a){u.preventDefault();let p=a.querySelectorAll(".tag-autocomplete-item");o=Math.min(o+1,p.length-1),p.forEach((m,g)=>m.classList.toggle("active",g===o))}else if(u.key==="ArrowUp"&&a){u.preventDefault();let p=a.querySelectorAll(".tag-autocomplete-item");o=Math.max(o-1,0),p.forEach((m,g)=>m.classList.toggle("active",g===o))}})}async function hn(){let e=s.tickets.filter(p=>s.selectedIds.has(p.id));if(e.length===0)return;let t=await f("/tags");for(let p of e)for(let m of V(p.tags))t.includes(m)||t.push(m);t.sort();let n=new Map;for(let p of t){let m=e.filter(g=>V(g.tags).includes(p)).length;m===e.length?n.set(p,"checked"):m===0?n.set(p,"unchecked"):n.set(p,"mixed")}let a=new Map(n),o=new Map(n),i=v(r("div",{className:"tags-dialog-overlay",children:r("div",{className:"tags-dialog",children:[r("div",{className:"tags-dialog-header",children:[r("span",{children:"Tags"}),r("button",{className:"detail-close",id:"tags-dialog-close",children:"\xD7"})]}),r("div",{className:"tags-dialog-body",id:"tags-dialog-body"}),r("div",{className:"tags-dialog-new",children:[r("input",{type:"text",id:"tags-dialog-new-input",placeholder:"New tag..."}),r("button",{className:"btn btn-sm",id:"tags-dialog-add-btn",children:"Add"})]}),r("div",{className:"tags-dialog-footer",children:[r("button",{className:"btn btn-sm",id:"tags-dialog-cancel",children:"Cancel"}),r("button",{className:"btn btn-sm btn-accent",id:"tags-dialog-done",children:"Done"})]})]})}));function l(){let p=i.querySelector("#tags-dialog-body");p.innerHTML="";for(let m of t){let g=o.get(m),y=v(r("label",{className:"tags-dialog-row",children:[r("input",{type:"checkbox",checked:g==="checked"}),r("span",{children:m})]})),b=y.querySelector("input");g==="mixed"&&(b.indeterminate=!0),b.addEventListener("change",()=>{o.set(m,b.checked?"checked":"unchecked")}),p.appendChild(y)}t.length===0&&(p.innerHTML='<div style="padding:12px 16px;color:var(--text-muted);font-size:13px">No tags yet. Create one below.</div>')}l(),document.body.appendChild(i);let c=i.querySelector("#tags-dialog-new-input"),d=()=>{let p=c.value.trim();if(!p||t.includes(p)){c.value="";return}t.push(p),t.sort(),o.set(p,"checked"),a.set(p,"unchecked"),c.value="",l()};i.querySelector("#tags-dialog-add-btn").addEventListener("click",d),c.addEventListener("keydown",p=>{p.key==="Enter"&&(p.preventDefault(),d())});let u=()=>i.remove();i.querySelector("#tags-dialog-close").addEventListener("click",u),i.querySelector("#tags-dialog-cancel").addEventListener("click",u),i.addEventListener("click",p=>{p.target===i&&u()}),i.querySelector("#tags-dialog-done").addEventListener("click",async()=>{let p=[],m=[];for(let g of t){let y=a.get(g),b=o.get(g);y!==b&&(b==="checked"?p.push(g):b==="unchecked"&&m.push(g))}if(p.length>0||m.length>0){for(let g of e){let y=V(g.tags),b=[...y];for(let E of p)b.includes(E)||b.push(E);for(let E of m)b=b.filter(x=>x!==E);JSON.stringify(b)!==JSON.stringify(y)&&await f(`/tickets/${g.id}`,{method:"PATCH",body:{tags:JSON.stringify(b)}})}w(),ye()}u()})}function Va(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}function Ka(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let n=Va(e.notes);if(n.length>0){t.push("");for(let a of n)t.push(`- ${a.text}`)}return t.join(`
98
- `)}function dn(){console.log("[undo] triggerUndo called, canUndo:",Dt()),j&&(clearTimeout(j),j=null),Ge(),_t().then(()=>console.log("[undo] performUndo completed")).catch(e=>console.error("[undo] performUndo error:",e))}function un(){console.log("[undo] triggerRedo called, canRedo:",At()),j&&(clearTimeout(j),j=null),Ge(),Ht().then(()=>console.log("[undo] performRedo completed")).catch(e=>console.error("[undo] performRedo error:",e))}function za(){window.addEventListener("app:undo",dn),window.addEventListener("app:redo",un),document.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="z"&&(e.preventDefault(),e.stopPropagation(),e.shiftKey?un():dn())},!0),document.addEventListener("keydown",e=>{let t=e.target.tagName,n=t==="INPUT"||t==="TEXTAREA"||t==="SELECT",a=document.getElementById("settings-overlay");if(e.key==="Escape"&&a.style.display!=="none"){a.style.display="none";return}if(e.key==="Escape"){let o=document.activeElement;if(o&&(o.tagName==="INPUT"||o.tagName==="TEXTAREA")&&o.closest(".detail-panel, .detail-body")){o.blur();return}s.selectedIds.size>0&&(s.selectedIds.clear(),L());return}if((e.metaKey||e.ctrlKey)&&e.key==="a"&&!n){e.preventDefault(),s.selectedIds.clear();for(let o of s.tickets)s.selectedIds.add(o.id);L();return}if((e.metaKey||e.ctrlKey)&&e.key==="d"){if(s.selectedIds.size>0){e.preventDefault();let o=s.tickets.filter(d=>s.selectedIds.has(d.id)),l=!o.every(d=>d.up_next),c=Array.from(s.selectedIds);if(l){let d=o.filter(u=>u.status==="completed"||u.status==="verified");if(d.length>0){Fe(o,[{ids:d.map(u=>u.id),action:"status",value:"not_started"},{ids:c,action:"up_next",value:!0}],"Toggle up next").then(()=>{w()});return}}I(o,{ids:c,action:"up_next",value:l},"Toggle up next").then(()=>{w()})}return}if((e.metaKey||e.ctrlKey)&&e.key==="c"&&s.selectedIds.size>0&&!(n&&!e.altKey)){let o=!e.altKey&&window.getSelection();if(!(o&&!o.isCollapsed&&o.toString().trim()!=="")){e.preventDefault();let l=s.tickets.filter(c=>s.selectedIds.has(c.id)).map(Ka).join(`
97
+ `}async function wa(){try{await Ea(),await Ta(),await en(),xa(),H(),await w(),Ha(),Na(),Ba(),Da(),Aa(),Wa(),ja(),Xa(),La(),Xt(),Ma(),$a(),Qt(()=>{w()}),Nt(),Ga(),Ca(),document.addEventListener("hotsheet:render",()=>L()),document.addEventListener("hotsheet:show-tags-dialog",()=>{bn()}),document.addEventListener("hotsheet:upnext-changed",()=>ht()),document.getElementById("print-btn")?.addEventListener("click",rt),fn(),Fa(),W()}catch(e){console.error("Hot Sheet init failed:",e);let t=document.getElementById("ticket-list");t&&(t.innerHTML=`<div style="padding:20px;color:red">Init error: ${e}</div>`)}}async function Ea(){try{let e=await f("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(s.settings.detail_position=e.detail_position),e.detail_width&&(s.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(s.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(s.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(s.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30),(e.layout==="list"||e.layout==="columns")&&(s.layout=e.layout)}catch{}Ke(s.settings.detail_position),ze()}async function Ta(){try{let e=await f("/categories");e.length>0&&(s.categories=e)}catch{}ft()}function ft(){let e=document.getElementById("sidebar-categories");if(e){let t=e.querySelector(".sidebar-label");e.innerHTML="",t&&e.appendChild(t);for(let n of s.categories){let a=v(r("button",{className:`sidebar-item${s.view===`category:${n.id}`?" active":""}`,"data-view":`category:${n.id}`,children:[r("span",{className:"cat-dot",style:`background:${n.color}`})," ",n.label]}));a.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active")),a.classList.add("active"),s.view=`category:${n.id}`,s.selectedIds.clear(),bt(),H(),w()}),e.appendChild(a)}}if(s.activeTicketId!=null){let t=s.tickets.find(n=>n.id===s.activeTicketId);t&&ye(t.category)}}async function xa(){try{let e=await f("/file-settings");if(e.appName){document.title=e.appName;let t=document.querySelector(".app-title h1");t&&(t.textContent=e.appName)}}catch{}}function La(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close"),n=document.getElementById("settings-btn"),a=document.querySelectorAll(".settings-tab"),o=document.querySelectorAll(".settings-tab-panel");a.forEach(k=>{k.addEventListener("click",()=>{let T=k.dataset.tab;a.forEach(_=>_.classList.remove("active")),o.forEach(_=>_.classList.remove("active")),k.classList.add("active"),document.querySelector(`.settings-tab-panel[data-panel="${T}"]`)?.classList.add("active")})}),n.addEventListener("click",()=>{document.getElementById("settings-trash-days").value=String(s.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(s.settings.verified_cleanup_days),e.style.display="flex",Qe(),f("/file-settings").then(k=>{document.getElementById("settings-app-name").value=k.appName||"",document.getElementById("settings-backup-dir").value=k.backupDir||""})}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",k=>{k.target===e&&(e.style.display="none")});let i=document.getElementById("settings-trash-days"),l=null;i.addEventListener("input",()=>{l&&clearTimeout(l),l=setTimeout(()=>{let k=Math.max(1,parseInt(i.value,10)||3);i.value=String(k),s.settings.trash_cleanup_days=k,f("/settings",{method:"PATCH",body:{trash_cleanup_days:String(k)}})},500)});let c=document.getElementById("settings-verified-days"),d=null;c.addEventListener("input",()=>{d&&clearTimeout(d),d=setTimeout(()=>{let k=Math.max(1,parseInt(c.value,10)||30);c.value=String(k),s.settings.verified_cleanup_days=k,f("/settings",{method:"PATCH",body:{verified_cleanup_days:String(k)}})},500)});let u=document.getElementById("settings-app-name"),p=document.getElementById("settings-app-name-hint"),m=null;u.addEventListener("input",()=>{m&&clearTimeout(m),m=setTimeout(()=>{let k=u.value.trim();f("/file-settings",{method:"PATCH",body:{appName:k}}).then(()=>{let T=k||"Hot Sheet";document.title=T;let _=document.querySelector(".app-title h1");_&&(_.textContent=T),p.textContent=k?"Saved. Restart the desktop app to update the title bar.":"Using default name."})},800)});let g=document.getElementById("check-updates-btn"),y=document.getElementById("check-updates-status");g.addEventListener("click",async()=>{let k=yt();if(k){g.disabled=!0,g.textContent="Checking...",y.textContent="";try{let T=await k("check_for_update");T?(y.textContent=`Update available: v${T}`,document.getElementById("settings-overlay").style.display="none",mn(T)):y.textContent="Your software is up to date."}catch{y.textContent="Could not check for updates."}g.textContent="Check for Updates",g.disabled=!1}});let b=document.getElementById("settings-backup-dir"),E=document.getElementById("settings-backup-dir-hint"),x=null;b.addEventListener("input",()=>{x&&clearTimeout(x),x=setTimeout(()=>{let k=b.value.trim();f("/file-settings",{method:"PATCH",body:{backupDir:k}}).then(()=>{E.textContent=k?"Saved. New backups will use this location.":"Using default location inside the data directory."})},800)}),Pa(),Ia()}function De(){let e=document.getElementById("category-list");e.innerHTML="";for(let t=0;t<s.categories.length;t++){let n=s.categories[t],a=v(r("div",{className:"category-row",children:[r("input",{type:"color",className:"category-color-input",value:n.color,title:"Color"}),r("input",{type:"text",className:"category-label-input",value:n.label,placeholder:"Label",title:"Display name"}),r("input",{type:"text",className:"category-short-input",value:n.shortLabel,placeholder:"ABR",title:"Short label (3 chars)",maxlength:"4"}),r("input",{type:"text",className:"category-key-input",value:n.shortcutKey,placeholder:"k",title:"Keyboard shortcut",maxlength:"1"}),r("input",{type:"text",className:"category-desc-input",value:n.description,placeholder:"Description...",title:"Description (for AI tools)"}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]})),o=a.querySelectorAll("input"),[i,l,c,d,u]=o,p=()=>{rn()};i.addEventListener("input",()=>{s.categories[t].color=i.value,p()}),l.addEventListener("input",()=>{s.categories[t].label=l.value,(!n.id||n.id==="")&&(s.categories[t].id=l.value.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")),p()}),c.addEventListener("input",()=>{s.categories[t].shortLabel=c.value.toUpperCase(),p()}),d.addEventListener("input",()=>{let m=d.value.toLowerCase().slice(0,1);d.value=m,s.categories[t].shortcutKey=m,on(),p()}),u.addEventListener("input",()=>{s.categories[t].description=u.value,p()}),a.querySelector(".category-delete-btn").addEventListener("click",()=>{s.categories.splice(t,1),De(),rn()}),e.appendChild(a)}on()}function on(){let e=document.querySelectorAll(".category-key-input"),t=new Map;s.categories.forEach((n,a)=>{if(n.shortcutKey){let o=n.shortcutKey.toLowerCase();t.has(o)||t.set(o,[]),t.get(o).push(a)}}),e.forEach((n,a)=>{let o=s.categories[a]?.shortcutKey?.toLowerCase();o&&t.get(o).length>1?n.classList.add("category-key-conflict"):n.classList.remove("category-key-conflict")})}var ct=null;function rn(){ct&&clearTimeout(ct),ct=setTimeout(async()=>{await f("/categories",{method:"PUT",body:s.categories}),ft()},500)}function Ia(){document.getElementById("category-add-btn").addEventListener("click",()=>{s.categories.push({id:"",label:"",shortLabel:"",color:"#6b7280",shortcutKey:"",description:""}),De();let n=document.querySelectorAll(".category-row");n[n.length-1]?.querySelector(".category-label-input")?.focus()});let e=document.getElementById("category-preset-select");f("/category-presets").then(n=>{for(let a of n)e.appendChild(v(r("option",{value:a.id,children:a.name})))}),e.addEventListener("change",async()=>{if(!e.value)return;let a=(await f("/category-presets")).find(o=>o.id===e.value);a&&(s.categories=[...a.categories],await f("/categories",{method:"PUT",body:s.categories}),De(),ft()),e.value=""}),document.getElementById("settings-btn").addEventListener("click",()=>{De()})}async function Ca(){let e=yt();if(!e)return;let t=document.getElementById("settings-updates-section");t&&(t.style.display="");let n=document.getElementById("settings-tab-updates");n&&(n.style.display="");let a=[0,3e3,1e4];for(let o of a){o>0&&await new Promise(i=>setTimeout(i,o));try{let i=await e("get_pending_update");if(i){mn(i);return}}catch{return}}}function yt(){return window.__TAURI__?.core?.invoke??null}function mn(e){let t=document.getElementById("update-banner");if(!t)return;let n=document.getElementById("update-banner-label");n&&(n.textContent=`Update available: v${e}`),t.style.display="flex";let a=document.getElementById("update-install-btn");a?.addEventListener("click",async()=>{if(a){a.textContent="Installing...",a.disabled=!0;try{await yt()?.("install_update"),n&&(n.textContent="Update installed! Restart the app to apply."),a.style.display="none"}catch{a.textContent="Install Failed",a.disabled=!1}}}),document.getElementById("update-banner-dismiss")?.addEventListener("click",()=>{t.style.display="none"})}function Sa(){let e=document.getElementById("skills-banner");if(!e)return;e.style.display="flex",document.getElementById("skills-banner-dismiss")?.addEventListener("click",()=>{e.style.display="none"})}function Ma(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),n=document.getElementById("copy-prompt-label"),a=document.getElementById("copy-prompt-icon"),o="";f("/worklist-info").then(i=>{o=i.prompt,e.style.display="",i.skillCreated&&Sa()}),t.addEventListener("click",()=>{o!==""&&navigator.clipboard.writeText(o).then(()=>{n.textContent="Copied!",a.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>',setTimeout(()=>{n.textContent="Copy AI prompt",a.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>'},1500)})})}function $a(){let e=document.getElementById("glassbox-btn"),t=document.getElementById("glassbox-icon");f("/glassbox/status").then(({available:n})=>{n&&(t.src="/static/assets/glassbox-icon.png",e.style.display="")}).catch(()=>{}),e.addEventListener("click",()=>{f("/glassbox/launch",{method:"POST"})})}function pt(){let e=document.getElementById("layout-toggle"),t=$e(),n=e.querySelector('[data-layout="columns"]');n.disabled=!t,n.style.opacity=t?"":"0.3";let a=s.layout==="columns"&&!t?"list":s.layout;e.querySelectorAll(".layout-btn").forEach(o=>{o.classList.toggle("active",o.dataset.layout===a)})}function Na(){document.getElementById("layout-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let n=t.dataset.layout;n==="columns"&&!$e()||(s.layout=n,H(),pt(),L(),f("/settings",{method:"PATCH",body:{layout:n}}))})}),pt()}function ln(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.classList.toggle("active",t.dataset.position===s.settings.detail_position)})}function Ba(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let n=t.dataset.position;s.settings.detail_position=n,Ke(n),ze(),ln(),f("/settings",{method:"PATCH",body:{detail_position:n}})})}),ln()}function gn(e){return e==="up-next"?{action:"up_next",value:!0}:e==="open"?{action:"status",value:"not_started"}:e==="completed"?{action:"status",value:"completed"}:e==="verified"?{action:"status",value:"verified"}:e==="backlog"?{action:"status",value:"backlog"}:e==="archive"?{action:"status",value:"archive"}:e==="trash"?{action:"delete",value:null}:e.startsWith("category:")?{action:"category",value:e.split(":")[1]}:e.startsWith("priority:")?{action:"priority",value:e.split(":")[1]}:null}async function _a(e,t){let n=gn(e);if(!n)return;let a=s.tickets.filter(o=>t.includes(o.id));n.action==="delete"?await I(a,{ids:t,action:"delete"},"Delete tickets"):await I(a,{ids:t,action:n.action,value:n.value},`Change ${n.action}`),H(),w()}function Ha(){document.querySelectorAll(".sidebar-item[data-view]").forEach(t=>{t.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(a=>a.classList.remove("active")),t.classList.add("active"),s.view=t.dataset.view,s.selectedIds.clear(),bt(),H(),pt(),w()});let n=t.dataset.view;gn(n)&&(t.addEventListener("dragover",a=>{a.preventDefault(),a.dataTransfer.dropEffect="move",t.classList.add("drop-target")}),t.addEventListener("dragleave",()=>{t.classList.remove("drop-target")}),t.addEventListener("drop",a=>{a.preventDefault(),t.classList.remove("drop-target");let o=[...U];o.length!==0&&_a(n,o)}))})}function Da(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,n]=e.value.split(":");s.sortBy=t,s.sortDir=n,H(),w()})}var dt=null;function Aa(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{dt&&clearTimeout(dt),dt=setTimeout(()=>{s.search=e.value,H(),w()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",s.search="",H(),w())})}var X=[];function Pa(){let e=document.getElementById("settings-tab-experimental"),t=document.getElementById("settings-experimental-panel"),n=document.getElementById("settings-channel-enabled"),a=document.getElementById("settings-channel-hint"),o=document.getElementById("settings-channel-instructions"),i=document.getElementById("settings-channel-copy-btn"),l=document.getElementById("settings-channel-cmd"),c=document.getElementById("settings-custom-commands-section");document.getElementById("settings-btn").addEventListener("click",()=>{fetch("/api/channel/claude-check").then(d=>d.ok?d.json():null).then(d=>{if(!d||!d.installed){e.style.display="none",t.style.display="none";return}e.style.display="",t.style.display="",d.meetsMinimum?(a.textContent="Push worklist events to a running Claude Code session via MCP channels.",n.disabled=!1):(a.textContent=`Claude Code ${d.version||"unknown"} detected but v2.1.80+ is required. Please upgrade Claude Code.`,n.disabled=!0),mt()}).catch(()=>{e.style.display="none",t.style.display="none"})}),fetch("/api/channel/status").then(d=>d.ok?d.json():null).then(d=>{d&&(n.checked=d.enabled,d.enabled&&(o.style.display="",c.style.display=""))}).catch(()=>{}),f("/settings").then(d=>{if(d.custom_commands)try{X=JSON.parse(d.custom_commands)}catch{}Ae()}),n.addEventListener("change",async()=>{n.checked?(await f("/channel/enable",{method:"POST"}),o.style.display="",c.style.display=""):(await f("/channel/disable",{method:"POST"}),o.style.display="none",c.style.display="none"),fn(),Ae()}),i?.addEventListener("click",()=>{let d=l?.textContent||"";navigator.clipboard.writeText(d).then(()=>{i&&(i.textContent="Copied!",setTimeout(()=>{i.textContent="Copy"},1500))})}),document.getElementById("settings-add-command-btn")?.addEventListener("click",()=>{X.push({name:"",prompt:""}),mt()})}function mt(){let e=document.getElementById("settings-commands-list");if(e){e.innerHTML="";for(let t=0;t<X.length;t++){let n=X[t],a=v(r("div",{className:"settings-command-row",children:[r("div",{className:"settings-command-row-header",children:[r("input",{type:"text",value:n.name,placeholder:"Button label..."}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]}),r("label",{children:"Prompt sent to Claude:"}),r("textarea",{placeholder:"Tell Claude what to do...",children:n.prompt})]})),o=a.querySelector("input"),i=a.querySelector("textarea"),l=()=>{X[t]={name:o.value,prompt:i.value},cn()};o.addEventListener("input",l),i.addEventListener("input",l),a.querySelector(".category-delete-btn").addEventListener("click",()=>{X.splice(t,1),mt(),cn()}),e.appendChild(a)}}}async function cn(){await f("/settings",{method:"PATCH",body:{custom_commands:JSON.stringify(X)}}),Ae()}function Ae(){let e=document.getElementById("channel-commands-container");if(!e)return;e.innerHTML="";let t=document.getElementById("channel-play-section");if(!(!t||t.style.display==="none"))for(let n of X){if(!n.name.trim()||!n.prompt.trim())continue;let a=v(r("button",{className:"channel-command-btn",children:n.name}));a.addEventListener("click",()=>{vt(n.prompt)}),e.appendChild(a)}}var we=null;function Ra(){we||(we=setInterval(async()=>{try{let e=await fetch("/api/channel/permission");if(!e.ok)return;let t=await e.json();t.pending&&Ua(t.pending)}catch{}},2e3))}function qa(){we&&(clearInterval(we),we=null)}function Ua(e){let t=document.getElementById("permission-overlay");if(!t||t.style.display!=="none")return;let n=document.getElementById("permission-overlay-detail");if(n){let i=`<div class="permission-tool">${e.tool_name}: ${e.description}</div>`;e.input_preview&&(i+=`<pre class="permission-preview">${e.input_preview.replace(/&/g,"&amp;").replace(/</g,"&lt;")}</pre>`),n.innerHTML=i}t.style.display="";function a(i){fetch("/api/channel/permission/respond",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({request_id:e.request_id,behavior:i})}),t.style.display="none"}function o(){fetch("/api/channel/permission/dismiss",{method:"POST"}),t.style.display="none"}document.getElementById("permission-allow-btn")?.addEventListener("click",()=>a("allow"),{once:!0}),document.getElementById("permission-deny-btn")?.addEventListener("click",()=>a("deny"),{once:!0}),document.getElementById("permission-dismiss-btn")?.addEventListener("click",o,{once:!0})}var Ee=!1,He=null,Pe=!1;function gt(e){Pe=e;let t=document.getElementById("channel-status-indicator");if(!t)return;let n=document.getElementById("channel-play-section");if(!n||n.style.display==="none"){t.style.display="none";return}e?(t.style.display="",t.className="channel-status-indicator busy",t.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg> Claude working'):(t.style.display="",t.className="channel-status-indicator",t.innerHTML="\u2713 Claude idle",setTimeout(()=>{!Pe&&t&&(t.style.display="none")},5e3))}var ce=null;function vt(e){gt(!0),f("/channel/trigger",{method:"POST",body:{message:e}}),ce&&clearTimeout(ce),ce=setTimeout(()=>{Pe&&gt(!1)},12e4)}async function Oa(e){try{if((await f("/stats")).up_next===0){Va();return}}catch{}e.classList.add("pulsing"),setTimeout(()=>e.classList.remove("pulsing"),600),vt()}function Va(){let e=document.getElementById("no-upnext-alert");e&&e.remove();let t=v(r("div",{id:"no-upnext-alert",className:"no-upnext-alert",children:[r("span",{children:"No Up Next items to process"}),r("button",{className:"no-upnext-dismiss",children:"\xD7"})]}));t.querySelector(".no-upnext-dismiss").addEventListener("click",()=>t.remove()),setTimeout(()=>t.remove(),4e3);let n=document.getElementById("channel-play-section");n&&n.after(t)}async function fn(){let e={enabled:!1,alive:!1};try{let l=await fetch("/api/channel/status");l.ok&&(e=await l.json())}catch{}let t=document.getElementById("channel-play-section"),n=document.getElementById("channel-play-btn"),a=document.getElementById("channel-play-icon"),o=document.getElementById("channel-auto-icon");if(!e.enabled){t.style.display="none",qa();return}t.style.display="",Ae(),Ra();let i=null;n.addEventListener("click",()=>{i?(clearTimeout(i),i=null,dn(n,a,o)):i=setTimeout(()=>{i=null,Ee?dn(n,a,o):Oa(n)},250)})}function dn(e,t,n){Ee=!Ee,Ee?(e.classList.add("auto-mode"),t.style.display="none",n.style.display=""):(e.classList.remove("auto-mode"),t.style.display="",n.style.display="none")}function ht(){Ee&&(He&&clearTimeout(He),He=setTimeout(()=>{He=null,vt()},5e3))}function bt(){let e=document.getElementById("dashboard-container");e&&(e.id="ticket-list",e.innerHTML="",za())}var yn=["search-input","layout-toggle","sort-select","detail-position-toggle","glassbox-btn"];function Ka(){s.view="dashboard",document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active"));for(let o of yn){let i=document.getElementById(o);if(i){let l=i.closest(".search-box, .layout-toggle, .sort-controls")||i;l.style.display="none"}}let e=document.getElementById("batch-toolbar");e&&(e.style.display="none");let t=document.getElementById("detail-panel");t&&(t.style.display="none");let n=document.getElementById("detail-resize-handle");n&&(n.style.display="none");let a=document.getElementById("ticket-list");a.innerHTML="",a.id="dashboard-container",a.classList.remove("ticket-list-columns"),st(a)}function za(){for(let e of yn){let t=document.getElementById(e);if(t){let n=t.closest(".search-box, .layout-toggle, .sort-controls")||t;n.style.display=""}}bt()}async function Fa(){let e=await an(),t=document.getElementById("stats-bar");t&&t.after(e),e.addEventListener("click",()=>Ka())}var vn=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}],hn=[{key:"n",value:"not_started",label:"Not Started"},{key:"s",value:"started",label:"Started"},{key:"c",value:"completed",label:"Completed"},{key:"v",value:"verified",label:"Verified"},{key:"b",value:"backlog",label:"Backlog"},{key:"a",value:"archive",label:"Archive"}];function Wa(){let e=document.getElementById("batch-category");e.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(e,s.categories.map(l=>({label:l.label,key:l.shortcutKey,color:l.color,action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"category",value:l.id},"Batch change category"),w()}})));document.body.appendChild(i),$(i,e),i.style.visibility=""});let t=document.getElementById("batch-priority");t.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(t,vn.map(l=>({label:l.label,key:l.key,icon:A(l.value),iconColor:P(l.value),action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"priority",value:l.value},"Batch change priority"),w()}})));document.body.appendChild(i),$(i,t),i.style.visibility=""});let n=document.getElementById("batch-status");n.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(n,hn.map(l=>({label:l.label,key:l.key,icon:z(l.value),action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"status",value:l.value},"Batch change status"),w()}})));document.body.appendChild(i),$(i,n),i.style.visibility=""}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let o=s.tickets.filter(d=>s.selectedIds.has(d.id)),l=!o.every(d=>d.up_next),c=Array.from(s.selectedIds);if(l){let d=o.filter(u=>u.status==="completed"||u.status==="verified");if(d.length>0){let u=[{ids:d.map(p=>p.id),action:"status",value:"not_started"},{ids:c,action:"up_next",value:!0}];await We(o,u,"Batch toggle up next")}else await I(o,{ids:c,action:"up_next",value:!0},"Batch toggle up next")}else await I(o,{ids:c,action:"up_next",value:!1},"Batch toggle up next");w(),ht()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let o=Array.from(s.selectedIds),i=s.tickets.filter(l=>s.selectedIds.has(l.id));await I(i,{ids:o,action:"delete"},"Batch delete"),s.selectedIds.clear(),w()});let a=document.getElementById("batch-more");a.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(a,[{label:"Tags...",key:"t",action:()=>{bn()}},{label:"Duplicate",key:"d",action:async()=>{let l=Array.from(s.selectedIds),c=await f("/tickets/duplicate",{method:"POST",body:{ids:l}});s.selectedIds.clear();for(let d of c)s.selectedIds.add(d.id);w()}},{label:"",key:"",separator:!0,action:()=>{}},{label:"Move to Backlog",key:"b",action:async()=>{let l=Array.from(s.selectedIds),c=s.tickets.filter(d=>s.selectedIds.has(d.id));await I(c,{ids:l,action:"status",value:"backlog"},"Move to backlog"),s.selectedIds.clear(),w()}},{label:"Archive",key:"a",action:async()=>{let l=Array.from(s.selectedIds),c=s.tickets.filter(d=>s.selectedIds.has(d.id));await I(c,{ids:l,action:"status",value:"archive"},"Archive"),s.selectedIds.clear(),w()}}]);document.body.appendChild(i),$(i,a),i.style.visibility=""}),document.getElementById("batch-select-all").addEventListener("change",o=>{if(o.target.checked)for(let l of s.tickets)s.selectedIds.add(l.id);else s.selectedIds.clear();L()})}var j=null;function ja(){document.getElementById("detail-close").addEventListener("click",St);let e=["detail-title","detail-details"];for(let u of e){let p=document.getElementById(u);p.addEventListener("input",()=>{let m=s.tickets.find(g=>g.id===s.activeTicketId);if(m){let g=u.replace("detail-","");Ce(m,g,p.value)}j&&clearTimeout(j),j=setTimeout(()=>{if(s.activeTicketId==null)return;let g=u.replace("detail-","");f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{[g]:p.value}}).then(()=>{w()})},300)})}async function t(u,p){if(s.activeTicketId==null)return;let m=s.tickets.find(g=>g.id===s.activeTicketId);m?await R(m,{[u]:p},`Change ${u}`):await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{[u]:p}}),w(),te(s.activeTicketId)}document.getElementById("detail-category").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,s.categories.map(y=>({label:y.label,key:y.shortcutKey,color:y.color,active:y.id===m,action:()=>{ye(y.id),t("category",y.id)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-priority").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,vn.map(y=>({label:y.label,key:y.key,icon:A(y.value),iconColor:P(y.value),active:y.value===m,action:()=>{xe(y.value),t("priority",y.value)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-status").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,hn.map(y=>({label:y.label,key:y.key,icon:z(y.value),active:y.value===m,action:()=>{Le(y.value),t("status",y.value)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-upnext").addEventListener("click",async()=>{if(s.activeTicketId==null)return;let u=s.tickets.find(p=>p.id===s.activeTicketId);u?!u.up_next&&(u.status==="completed"||u.status==="verified")?await R(u,{status:"not_started",up_next:!0},"Toggle up next"):await R(u,{up_next:!u.up_next},"Toggle up next"):await f(`/tickets/${s.activeTicketId}/up-next`,{method:"POST"}),w(),ht(),te(s.activeTicketId)}),document.getElementById("detail-add-note-btn")?.addEventListener("click",async()=>{if(s.activeTicketId==null)return;let u=s.tickets.find(p=>p.id===s.activeTicketId);if(u){let p=u.notes;await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{notes:"(new note)"}});let m=await f(`/tickets/${s.activeTicketId}`);ge({...u,notes:p},"Add note",m.notes),u.notes=m.notes}te(s.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async u=>{let p=u.target,m=p.files?.[0];!m||s.activeTicketId==null||(await xt(`/tickets/${s.activeTicketId}/attachments`,m),p.value="",te(s.activeTicketId),w())}),document.getElementById("detail-attachments").addEventListener("click",async u=>{let p=u.target,m=p.closest(".attachment-reveal");if(m){let b=m.dataset.attId;b&&f(`/attachments/${b}/reveal`,{method:"POST"});return}let g=p.closest(".attachment-delete");if(g===null)return;let y=g.dataset.attId;y===void 0||y===""||(await f(`/attachments/${y}`,{method:"DELETE"}),s.activeTicketId!=null&&te(s.activeTicketId))});let n=document.getElementById("detail-tag-input"),a=null,o=-1,i=[];f("/tags").then(u=>{i=u});function l(){a?.remove(),a=null,o=-1}function c(){l();let u=n.value.trim().toLowerCase();if(!u)return;let p=s.tickets.find(b=>b.id===s.activeTicketId),m=p?V(p.tags):[],g=i.filter(b=>b.toLowerCase().includes(u)&&!m.includes(b));if(g.length===0)return;a=v(r("div",{className:"tag-autocomplete"}));for(let b=0;b<g.length;b++){let E=v(r("div",{className:"tag-autocomplete-item",children:g[b]}));E.addEventListener("mousedown",x=>{x.preventDefault(),n.value=g[b],l(),d()}),a.appendChild(E)}let y=n.getBoundingClientRect();a.style.position="fixed",a.style.left=`${y.left}px`,a.style.top=`${y.bottom+2}px`,a.style.width=`${y.width}px`,document.body.appendChild(a)}async function d(){let u=n.value.trim();if(!u||s.activeTicketId==null)return;let p=s.tickets.find(y=>y.id===s.activeTicketId);if(!p)return;let m=V(p.tags);if(m.includes(u)){n.value="";return}let g=[...m,u];n.value="",l(),await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{tags:JSON.stringify(g)}}),p.tags=JSON.stringify(g),fe(g,!1),i.includes(u)||i.push(u)}n.addEventListener("input",()=>{c()}),n.addEventListener("blur",()=>{l()}),n.addEventListener("keydown",u=>{if(u.key==="Enter"){if(u.preventDefault(),a&&o>=0){let p=a.querySelectorAll(".tag-autocomplete-item");n.value=p[o]?.textContent||n.value}l(),d()}else if(u.key==="Escape")l();else if(u.key==="ArrowDown"&&a){u.preventDefault();let p=a.querySelectorAll(".tag-autocomplete-item");o=Math.min(o+1,p.length-1),p.forEach((m,g)=>m.classList.toggle("active",g===o))}else if(u.key==="ArrowUp"&&a){u.preventDefault();let p=a.querySelectorAll(".tag-autocomplete-item");o=Math.max(o-1,0),p.forEach((m,g)=>m.classList.toggle("active",g===o))}})}async function bn(){let e=s.tickets.filter(p=>s.selectedIds.has(p.id));if(e.length===0)return;let t=await f("/tags");for(let p of e)for(let m of V(p.tags))t.includes(m)||t.push(m);t.sort();let n=new Map;for(let p of t){let m=e.filter(g=>V(g.tags).includes(p)).length;m===e.length?n.set(p,"checked"):m===0?n.set(p,"unchecked"):n.set(p,"mixed")}let a=new Map(n),o=new Map(n),i=v(r("div",{className:"tags-dialog-overlay",children:r("div",{className:"tags-dialog",children:[r("div",{className:"tags-dialog-header",children:[r("span",{children:"Tags"}),r("button",{className:"detail-close",id:"tags-dialog-close",children:"\xD7"})]}),r("div",{className:"tags-dialog-body",id:"tags-dialog-body"}),r("div",{className:"tags-dialog-new",children:[r("input",{type:"text",id:"tags-dialog-new-input",placeholder:"New tag..."}),r("button",{className:"btn btn-sm",id:"tags-dialog-add-btn",children:"Add"})]}),r("div",{className:"tags-dialog-footer",children:[r("button",{className:"btn btn-sm",id:"tags-dialog-cancel",children:"Cancel"}),r("button",{className:"btn btn-sm btn-accent",id:"tags-dialog-done",children:"Done"})]})]})}));function l(){let p=i.querySelector("#tags-dialog-body");p.innerHTML="";for(let m of t){let g=o.get(m),y=v(r("label",{className:"tags-dialog-row",children:[r("input",{type:"checkbox",checked:g==="checked"}),r("span",{children:m})]})),b=y.querySelector("input");g==="mixed"&&(b.indeterminate=!0),b.addEventListener("change",()=>{o.set(m,b.checked?"checked":"unchecked")}),p.appendChild(y)}t.length===0&&(p.innerHTML='<div style="padding:12px 16px;color:var(--text-muted);font-size:13px">No tags yet. Create one below.</div>')}l(),document.body.appendChild(i);let c=i.querySelector("#tags-dialog-new-input"),d=()=>{let p=c.value.trim();if(!p||t.includes(p)){c.value="";return}t.push(p),t.sort(),o.set(p,"checked"),a.set(p,"unchecked"),c.value="",l()};i.querySelector("#tags-dialog-add-btn").addEventListener("click",d),c.addEventListener("keydown",p=>{p.key==="Enter"&&(p.preventDefault(),d())});let u=()=>i.remove();i.querySelector("#tags-dialog-close").addEventListener("click",u),i.querySelector("#tags-dialog-cancel").addEventListener("click",u),i.addEventListener("click",p=>{p.target===i&&u()}),i.querySelector("#tags-dialog-done").addEventListener("click",async()=>{let p=[],m=[];for(let g of t){let y=a.get(g),b=o.get(g);y!==b&&(b==="checked"?p.push(g):b==="unchecked"&&m.push(g))}if(p.length>0||m.length>0){for(let g of e){let y=V(g.tags),b=[...y];for(let E of p)b.includes(E)||b.push(E);for(let E of m)b=b.filter(x=>x!==E);JSON.stringify(b)!==JSON.stringify(y)&&await f(`/tickets/${g.id}`,{method:"PATCH",body:{tags:JSON.stringify(b)}})}w(),ae()}u()})}function Ja(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}function Ya(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let n=Ja(e.notes);if(n.length>0){t.push("");for(let a of n)t.push(`- ${a.text}`)}return t.join(`
98
+ `)}function un(){console.log("[undo] triggerUndo called, canUndo:",At()),j&&(clearTimeout(j),j=null),Ze(),Ht().then(()=>console.log("[undo] performUndo completed")).catch(e=>console.error("[undo] performUndo error:",e))}function pn(){console.log("[undo] triggerRedo called, canRedo:",Pt()),j&&(clearTimeout(j),j=null),Ze(),Dt().then(()=>console.log("[undo] performRedo completed")).catch(e=>console.error("[undo] performRedo error:",e))}function Xa(){window.addEventListener("app:undo",un),window.addEventListener("app:redo",pn),document.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="z"&&(e.preventDefault(),e.stopPropagation(),e.shiftKey?pn():un())},!0),document.addEventListener("keydown",e=>{let t=e.target.tagName,n=t==="INPUT"||t==="TEXTAREA"||t==="SELECT",a=document.getElementById("settings-overlay");if(e.key==="Escape"&&a.style.display!=="none"){a.style.display="none";return}if(e.key==="Escape"){let o=document.activeElement;if(o&&(o.tagName==="INPUT"||o.tagName==="TEXTAREA")&&o.closest(".detail-panel, .detail-body")){o.blur();return}s.selectedIds.size>0&&(s.selectedIds.clear(),L());return}if((e.metaKey||e.ctrlKey)&&e.key==="a"&&!n){e.preventDefault(),s.selectedIds.clear();for(let o of s.tickets)s.selectedIds.add(o.id);L();return}if((e.metaKey||e.ctrlKey)&&e.key==="d"){if(s.selectedIds.size>0){e.preventDefault();let o=s.tickets.filter(d=>s.selectedIds.has(d.id)),l=!o.every(d=>d.up_next),c=Array.from(s.selectedIds);if(l){let d=o.filter(u=>u.status==="completed"||u.status==="verified");if(d.length>0){We(o,[{ids:d.map(u=>u.id),action:"status",value:"not_started"},{ids:c,action:"up_next",value:!0}],"Toggle up next").then(()=>{w()});return}}I(o,{ids:c,action:"up_next",value:l},"Toggle up next").then(()=>{w()})}return}if((e.metaKey||e.ctrlKey)&&e.key==="c"&&s.selectedIds.size>0&&!(n&&!e.altKey)){let o=!e.altKey&&window.getSelection();if(!(o&&!o.isCollapsed&&o.toString().trim()!=="")){e.preventDefault();let l=s.tickets.filter(c=>s.selectedIds.has(c.id)).map(Ya).join(`
99
99
 
100
- `);navigator.clipboard.writeText(l);return}}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),W();return}if((e.metaKey||e.ctrlKey)&&e.key==="p"){e.preventDefault(),it();return}if((e.metaKey||e.ctrlKey)&&e.key==="f"){e.preventDefault(),document.getElementById("search-input").focus();return}if(e.key==="n"&&!n){e.preventDefault(),W();return}if((e.key==="Delete"||e.key==="Backspace")&&!n&&s.selectedIds.size>0){e.preventDefault();let o=Array.from(s.selectedIds),i=s.tickets.filter(l=>s.selectedIds.has(l.id));I(i,{ids:o,action:"delete"},"Delete").then(()=>{s.selectedIds.clear(),w()});return}})}var dt=0;function Fa(){async function e(){try{let t=await f(`/poll?version=${dt}`);t.version>dt&&(dt=t.version,s.backupPreview?.active||w(),Ae&&fetch("/api/channel/status").then(n=>n.ok?n.json():null).then(n=>{n?.done&&(mt(!1),le&&(clearTimeout(le),le=null))}).catch(()=>{}))}catch{await new Promise(t=>setTimeout(t,5e3))}setTimeout(e,100)}e()}ka();})();
100
+ `);navigator.clipboard.writeText(l);return}}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),W();return}if((e.metaKey||e.ctrlKey)&&e.key==="p"){e.preventDefault(),rt();return}if((e.metaKey||e.ctrlKey)&&e.key==="f"){e.preventDefault(),document.getElementById("search-input").focus();return}if(e.key==="n"&&!n){e.preventDefault(),W();return}if((e.key==="Delete"||e.key==="Backspace")&&!n&&s.selectedIds.size>0){e.preventDefault();let o=Array.from(s.selectedIds),i=s.tickets.filter(l=>s.selectedIds.has(l.id));I(i,{ids:o,action:"delete"},"Delete").then(()=>{s.selectedIds.clear(),w()});return}})}var ut=0;function Ga(){async function e(){try{let t=await f(`/poll?version=${ut}`);t.version>ut&&(ut=t.version,s.backupPreview?.active||(w(),ae()),Pe&&fetch("/api/channel/status").then(n=>n.ok?n.json():null).then(n=>{n?.done&&(gt(!1),ce&&(clearTimeout(ce),ce=null))}).catch(()=>{}))}catch{await new Promise(t=>setTimeout(t,5e3))}setTimeout(e,100)}e()}wa();})();