hotsheet 0.3.0 → 0.5.0

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,4 +1,100 @@
1
- "use strict";(()=>{var ct=Object.defineProperty;var dt=(e,t,s)=>t in e?ct(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var z=(e,t,s)=>dt(e,typeof t!="symbol"?t+"":t,s);function y(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function we(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function Le(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var P=class{constructor(t){z(this,"__html");this.__html=t}toString(){return this.__html}};function H(e){return new P(e)}var ut=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function ie(e){return e==null||typeof e=="boolean"?"":e instanceof P?e.__html:typeof e=="string"?we(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(ie).join(""):""}var pt={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 mt(e,t){let s=pt[e]??e;if(t==null||t===!1)return"";if(t===!0)return` ${s}`;let a;return t instanceof P?a=t.__html:typeof t=="number"?a=String(t):typeof t=="string"?a=Le(t):a="",` ${s}="${a}"`}function c(e,t){if(typeof e=="function")return e(t);let{children:s,...a}=t,i=Object.entries(a).map(([o,l])=>mt(o,l)).join("");if(ut.has(e))return new P(`<${e}${i}>`);let r=s!=null?ie(s):"";return new P(`<${e}${i}>${r}</${e}>`)}function q({children:e}){return new P(e!=null?ie(e):"")}function xe(e){document.getElementById("network-error-popup")?.remove();let t=y(c("div",{id:"network-error-popup",className:"error-popup",children:c("div",{className:"error-popup-content",children:[c("strong",{children:"Connection Error"}),c("p",{children:e}),c("button",{children:"Dismiss"})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function p(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(s){throw xe("Unable to reach the server. It may have been stopped."),s}}async function Se(e,t){try{let s=new FormData;return s.append("file",t),(await fetch("/api"+e,{method:"POST",body:s})).json()}catch(s){throw xe("Unable to reach the server. It may have been stopped."),s}}var ft={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},n={tickets:[],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:{...ft},backupPreview:null},gt='<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>',yt={highest:"\u2B06\u2B06",high:"\u2B06",default:gt,low:"\u2B07",lowest:"\u2B07\u2B07"},vt={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},Ce='<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>',ht={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:Ce,backlog:"\u25A1",archive:"\u25A0"},oe=Ce;function x(e){return n.categories.find(s=>s.id===e)?.color||"#6b7280"}function U(e){return n.categories.find(s=>s.id===e)?.shortLabel||e.slice(0,3).toUpperCase()}function S(e){return yt[e]||"\u2014"}function C(e){return vt[e]||"#6b7280"}function A(e){return ht[e]||"\u25CB"}var bt={not_started:"Not Started",started:"Started",completed:"Completed",verified:"Verified",backlog:"Backlog",archive:"Archive"},kt={highest:"Highest",high:"High",default:"Default",low:"Low",lowest:"Lowest"};function j(e){let t=document.getElementById("detail-category");t.dataset.value=e;let s=n.categories.find(i=>i.id===e),a=x(e);t.innerHTML=`<span class="cat-dot" style="background:${a}"></span> ${s?.label||e}`}function X(e){let t=document.getElementById("detail-priority");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon" style="color:${C(e)}">${S(e)}</span> ${kt[e]||e}`}function Z(e){let t=document.getElementById("detail-status");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon">${A(e)}</span> ${bt[e]||e}`}function W(e){n.activeTicketId=e,le(e)}function Be(){n.selectedIds.clear(),n.activeTicketId=null,O();let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function O(){let e=n.view==="trash",t=!!n.backupPreview?.active,s=document.getElementById("detail-panel"),a=document.getElementById("detail-resize-handle"),i=document.getElementById("detail-header"),r=document.getElementById("detail-body"),o=document.getElementById("detail-placeholder"),l=document.getElementById("detail-placeholder-text");if(e){s.style.display="none",a&&(a.style.display="none"),n.activeTicketId=null;return}if(s.style.display="flex",a&&(a.style.display=""),n.selectedIds.size===1){let d=Array.from(n.selectedIds)[0];s.classList.remove("detail-disabled"),i.style.display="",r.style.display="",o.style.display="none",n.activeTicketId!==d&&(n.activeTicketId=d,t?Et(d):le(d))}else n.activeTicketId=null,s.classList.add("detail-disabled"),i.style.display="none",r.style.display="none",o.style.display="",n.selectedIds.size===0?l.textContent="Nothing selected":l.textContent=`${n.selectedIds.size} items selected`}function _e(e){let t=document.getElementById("detail-title"),s=document.getElementById("detail-details"),a=document.getElementById("detail-category"),i=document.getElementById("detail-priority"),r=document.getElementById("detail-status"),o=document.getElementById("detail-upnext"),l=document.querySelector(".upload-btn");t.readOnly=e,s.readOnly=e,a.disabled=e,i.disabled=e,r.disabled=e,o.disabled=e,l&&(l.style.display=e?"none":"")}function Et(e){let t=n.backupPreview?.tickets.find(l=>l.id===e);if(!t||n.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,j(t.category),X(t.priority),Z(t.status);let s=document.getElementById("detail-upnext");s.textContent=t.up_next?"\u2605":"\u2606",s.classList.toggle("active",t.up_next),document.getElementById("detail-details").value=t.details,_e(!0),document.getElementById("detail-attachments").innerHTML="";let a=document.getElementById("detail-notes-section"),i=document.getElementById("detail-notes"),r=Me(t.notes);r.length>0?(a.style.display="",i.innerHTML=c(q,{children:r.map(l=>c("div",{className:"note-entry",children:[l.created_at?c("div",{className:"note-timestamp",children:new Date(l.created_at).toLocaleString()}):null,c("div",{className:"note-text",children:l.text})]}))}).toString()):(a.style.display="none",i.innerHTML="");let o=document.getElementById("detail-meta");o.innerHTML=c(q,{children:[c("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),c("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?c("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?c("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function re(){n.activeTicketId!=null&&le(n.activeTicketId)}async function le(e){let t=await p(`/tickets/${e}`);if(n.activeTicketId!==e)return;_e(!1),document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,j(t.category),X(t.priority),Z(t.status);let s=document.getElementById("detail-upnext");s.textContent=t.up_next?"\u2605":"\u2606",s.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=c(q,{children:t.attachments.map(d=>c("div",{className:"attachment-item",children:[c("span",{className:"attachment-name",children:d.original_filename}),c("button",{className:"attachment-reveal","data-att-id":String(d.id),title:"Show in file manager",children:c("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:c("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"})})}),c("button",{className:"attachment-delete","data-att-id":String(d.id),title:"Remove",children:"\xD7"})]}))}).toString():a.innerHTML="";let i=document.getElementById("detail-notes-section"),r=document.getElementById("detail-notes"),o=Me(t.notes);o.length>0?(i.style.display="",r.innerHTML=c(q,{children:o.map(d=>c("div",{className:"note-entry",children:[d.created_at?c("div",{className:"note-timestamp",children:new Date(d.created_at).toLocaleString()}):null,c("div",{className:"note-text",children:d.text})]}))}).toString()):(i.style.display="none",r.innerHTML="");let l=document.getElementById("detail-meta");l.innerHTML=c(q,{children:[c("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),c("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?c("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?c("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function Me(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:""}]:[]}async function Q(){try{let e=await p("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function ce(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function de(){let e=document.getElementById("detail-panel");n.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${n.settings.detail_height}px`):(e.style.height="",e.style.width=`${n.settings.detail_width}px`)}function He(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),s=document.getElementById("content-area"),a=!1;e.addEventListener("mousedown",i=>{i.preventDefault(),a=!0,document.body.style.cursor=n.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",i=>{if(!a)return;let r=s.getBoundingClientRect();if(n.settings.detail_position==="bottom"){let o=Math.max(150,Math.min(500,r.bottom-i.clientY));n.settings.detail_height=o,t.style.height=`${o}px`}else{let o=Math.max(250,Math.min(600,r.right-i.clientX));n.settings.detail_width=o,t.style.width=`${o}px`}}),document.addEventListener("mouseup",()=>{a&&(a=!1,document.body.style.cursor="",document.body.style.userSelect="",n.settings.detail_position==="bottom"?p("/settings",{method:"PATCH",body:{detail_height:String(n.settings.detail_height)}}):p("/settings",{method:"PATCH",body:{detail_width:String(n.settings.detail_width)}}))})}function T(e,t){let s=t.getBoundingClientRect(),a=e.getBoundingClientRect(),i=window.innerWidth,r=window.innerHeight,o=s.left;o+a.width>i-8&&(o=s.right-a.width),o<8&&(o=8);let l=s.bottom+4;l+a.height>r-8&&(l=s.top-a.height-4),l<8&&(l=8),e.style.left=`${o}px`,e.style.top=`${l}px`}function I(e,t){let s=y(c("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(l=>c("button",{className:`dropdown-item${l.active?" active":""}`,"data-key":l.key,children:[l.color?c("span",{className:"dropdown-dot",style:`background-color:${l.color}`}):null,l.icon?c("span",{className:"dropdown-icon",style:l.iconColor?`color:${l.iconColor}`:"",children:H(l.icon)}):null,c("span",{className:"dropdown-label",children:l.label}),l.shortcut?c("kbd",{className:"dropdown-kbd",children:l.shortcut}):null]}))}));s.querySelectorAll(".dropdown-item").forEach((l,d)=>{l.addEventListener("click",()=>{t[d].action(),s.remove()})});function i(l){let d=t.find(u=>l.key.toLowerCase()===u.key.toLowerCase());d?(l.preventDefault(),l.stopPropagation(),d.action(),r()):l.key==="Escape"&&(l.preventDefault(),r())}function r(){s.remove(),document.removeEventListener("keydown",i,!0),document.removeEventListener("click",o)}function o(){r()}return document.addEventListener("keydown",i,!0),setTimeout(()=>{document.addEventListener("click",o)},0),s}function w(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var ue=class{constructor(){z(this,"undoStack",[]);z(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 s=this.peekUndo();return!s||s.coalescingKey!==t.coalescingKey||t.timestamp-s.timestamp>=5e3?!1:(s.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}},k=new ue;function R(e){return{id:e.id,title:e.title,details:e.details,category:e.category,priority:e.priority,status:e.status,up_next:e.up_next}}async function B(e,t,s){let a=R(e),i=await p(`/tickets/${e.id}`,{method:"PATCH",body:t}),r=R(i);return k.push({label:s,timestamp:Date.now(),before:[a],after:[r]}),i}function ee(e,t,s){let a=`${e.id}:${t}`,i=Date.now(),r={...R(e),[t]:s},o={label:`Edit ${t}`,timestamp:i,before:[R(e)],after:[r],coalescingKey:a};k.coalesce(o)||k.push(o)}async function E(e,t,s){let a=e.map(R);await p("/tickets/batch",{method:"POST",body:t});let i=a.map(r=>{let o={...r};return t.action==="category"?o.category=t.value:t.action==="priority"?o.priority=t.value:t.action==="status"?o.status=t.value:t.action==="up_next"?o.up_next=t.value:t.action==="delete"&&(o.status="deleted"),o});k.push({label:s,timestamp:Date.now(),before:a,after:i})}async function pe(e,t,s){let a=e.map(R);for(let r of t)await p("/tickets/batch",{method:"POST",body:r});let i=a.map(r=>{let o={...r};for(let l of t)l.ids.includes(r.id)&&(l.action==="status"?o.status=l.value:l.action==="up_next"?o.up_next=l.value:l.action==="category"?o.category=l.value:l.action==="priority"?o.priority=l.value:l.action==="delete"&&(o.status="deleted"));return o});k.push({label:s,timestamp:Date.now(),before:a,after:i})}async function Ne(e){let t=R(e);await p(`/tickets/${e.id}`,{method:"DELETE"});let s={...t,status:"deleted"};k.push({label:"Delete ticket",timestamp:Date.now(),before:[t],after:[s]})}async function De(e){let t=R(e);await p(`/tickets/${e.id}/restore`,{method:"POST"});let s={...t,status:"not_started"};k.push({label:"Restore ticket",timestamp:Date.now(),before:[t],after:[s]})}async function Pe(e){for(let t of e)t.status==="deleted"?await p(`/tickets/${t.id}`,{method:"DELETE"}):await p(`/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}})}var $=!1;async function Ae(){if(console.log("[undo] performUndo, inFlight:",$,"canUndo:",k.canUndo()),$){console.log("[undo] skipped \u2014 already in flight");return}let e=k.popUndo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying before-state:",e.label,JSON.stringify(e.before)),$=!0;try{await Pe(e.before),console.log("[undo] applySnapshots done, reloading tickets"),await m(),re()}finally{$=!1}}async function $e(){if(console.log("[undo] performRedo, inFlight:",$,"canRedo:",k.canRedo()),$){console.log("[undo] skipped \u2014 already in flight");return}let e=k.popRedo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying after-state:",e.label,JSON.stringify(e.after)),$=!0;try{await Pe(e.after),console.log("[undo] applySnapshots done, reloading tickets"),await m(),re()}finally{$=!1}}function Re(){return k.canUndo()}function Ue(){return k.canRedo()}var V=null;function ge(){V&&(clearTimeout(V),V=null)}var J=!1,Y=null,me="",L=[];function te(){return n.categories.map(e=>({key:e.shortcutKey,value:e.id,label:e.label}))}var fe=[{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 Tt(){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 s=t.dataset.id;return s!==void 0&&s!==""?parseInt(s,10):null}function It(e){e!=null&&(J=!0,e==="draft"?_():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),J=!1)}function ne(){let e=n.view;return e!=="completed"&&e!=="verified"&&e!=="trash"&&e!=="backlog"&&e!=="archive"}function Oe(){return n.view==="up-next"||n.view==="open"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"}]:n.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 h(){let e=!!n.backupPreview?.active;if(n.layout==="columns"&&ne()){if(e){Lt();return}St();return}let t=n.view==="trash",s=e?null:Tt(),a=null;if(s!=null&&s!=="draft"){let o=document.querySelector(`.ticket-row[data-id="${s}"] .ticket-title-input`);o&&(a=o.value)}let i=document.getElementById("ticket-list"),r=i.scrollTop;if(i.innerHTML="",i.classList.remove("ticket-list-columns"),!t&&!e&&i.appendChild(je()),n.tickets.length===0){let o=t?"Trash is empty":e?"No tickets match this view":"";o&&i.appendChild(y(c("div",{className:"ticket-list-empty",children:o})))}for(let o of n.tickets)e?i.appendChild(wt(o)):t?i.appendChild(Ht(o)):i.appendChild(Mt(o));if(i.scrollTop=r,e){let o=document.getElementById("batch-toolbar");o&&(o.style.display="none"),G(),O()}else{let o=document.getElementById("batch-toolbar");if(o&&(o.style.display=""),s!=null&&s!=="draft"&&a!=null){let l=document.querySelector(`.ticket-row[data-id="${s}"] .ticket-title-input`);l&&l.value!==a&&(l.value=a)}It(s),F()}Q()}function wt(e){let t=n.selectedIds.has(e.id),s=e.status==="completed"||e.status==="verified",a=e.status==="verified",i=y(c("div",{className:`ticket-row${t?" selected":""}${s?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("span",{className:"ticket-checkbox-spacer"}),c("span",{className:"ticket-category-badge",style:`background-color:${x(e.category)};cursor:default`,title:e.category,children:U(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:`ticket-status-btn${a?" verified":""}`,style:"cursor:default",children:H(a?oe:A(e.status))}),c("span",{className:"ticket-title-input",style:"cursor:default",children:e.title}),c("span",{className:"ticket-priority-indicator",style:`color:${C(e.priority)};cursor:default`,title:e.priority,children:H(S(e.priority))}),c("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}));return i.addEventListener("click",()=>{n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,G(),O()}),i}function Ve(e){let t={scrollLeft:0,columns:{}},s=e.querySelector(".columns-container");return s&&(t.scrollLeft=s.scrollLeft,s.querySelectorAll(".column[data-status]").forEach(a=>{let i=a.dataset.status,r=a.querySelector(".column-body");r&&(t.columns[i]=r.scrollTop)})),t}function Fe(e,t){let s=e.querySelector(".columns-container");s&&(s.scrollLeft=t.scrollLeft,s.querySelectorAll(".column[data-status]").forEach(a=>{let i=a.dataset.status,r=a.querySelector(".column-body");r&&t.columns[i]!=null&&(r.scrollTop=t.columns[i])}))}function Lt(){let e=document.getElementById("ticket-list"),t=Ve(e);e.innerHTML="",e.classList.add("ticket-list-columns");let s=Oe(),a=y(c("div",{className:"columns-container"}));for(let r of s){let o=n.tickets.filter(u=>u.status===r.status),l=y(c("div",{className:"column","data-status":r.status,children:[c("div",{className:"column-header",children:[c("span",{className:"column-title",children:r.label}),c("span",{className:"column-count",children:String(o.length)})]}),c("div",{className:"column-body"})]})),d=l.querySelector(".column-body");for(let u of o)d.appendChild(xt(u));a.appendChild(l)}e.appendChild(a),Fe(e,t);let i=document.getElementById("batch-toolbar");i&&(i.style.display="none"),Q()}function xt(e){let t=n.selectedIds.has(e.id),s=y(c("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("div",{className:"column-card-header",children:[c("span",{className:"ticket-category-badge",style:`background-color:${x(e.category)}`,children:U(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-priority-indicator",style:`color:${C(e.priority)};cursor:default`,children:H(S(e.priority))}),c("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}),c("div",{className:"column-card-title",children:e.title})]}));return s.addEventListener("click",()=>{n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,ze(),O()}),s}function St(){let e=document.getElementById("ticket-list"),t=Ve(e);e.innerHTML="",e.classList.add("ticket-list-columns"),e.appendChild(je());let s=Oe(),a=y(c("div",{className:"columns-container"}));for(let i of s){let r=n.tickets.filter(d=>d.status===i.status),o=y(c("div",{className:"column","data-status":i.status,children:[c("div",{className:"column-header",children:[c("span",{className:"column-title",children:i.label}),c("span",{className:"column-count",children:String(r.length)})]}),c("div",{className:"column-body"})]})),l=o.querySelector(".column-body");for(let d of r)l.appendChild(Ct(d));l.addEventListener("dragover",d=>{d.preventDefault(),d.dataTransfer.dropEffect="move",o.classList.add("column-drop-target")}),l.addEventListener("dragleave",d=>{let u=d.relatedTarget;(!u||!l.contains(u))&&o.classList.remove("column-drop-target")}),l.addEventListener("drop",d=>{d.preventDefault(),o.classList.remove("column-drop-target");let u=L;if(L=[],u.length===0)return;let f=n.tickets.filter(v=>u.includes(v.id));E(f,{ids:u,action:"status",value:i.status},"Change status").then(()=>{m()})}),a.appendChild(o)}e.appendChild(a),Fe(e,t),F(),Q()}function Ct(e){let t=n.selectedIds.has(e.id),s=y(c("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("div",{className:"column-card-header",children:[c("span",{className:"ticket-category-badge",style:`background-color:${x(e.category)}`,children:U(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-priority-indicator",style:`color:${C(e.priority)}`,children:H(S(e.priority))}),c("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"})]}),c("div",{className:"column-card-title",children:e.title})]})),a=s.querySelector(".ticket-category-badge");a.addEventListener("click",r=>{r.stopPropagation(),Ge(a,e)});let i=s.querySelector(".ticket-priority-indicator");return i.addEventListener("click",r=>{r.stopPropagation(),Xe(i,e)}),s.querySelector(".ticket-star").addEventListener("click",r=>{r.stopPropagation(),Ye(e)}),s.draggable=!0,s.addEventListener("dragstart",r=>{n.selectedIds.has(e.id)&&n.selectedIds.size>1?L=Array.from(n.selectedIds):L=[e.id],r.dataTransfer.setData("text/plain",JSON.stringify(L)),r.dataTransfer.effectAllowed="move"}),s.addEventListener("dragend",()=>{L=[]}),s.addEventListener("click",r=>{if(r.metaKey||r.ctrlKey)n.selectedIds.has(e.id)?n.selectedIds.delete(e.id):n.selectedIds.add(e.id),n.lastClickedId=e.id;else if(r.shiftKey&&n.lastClickedId!=null){let o=n.tickets.find(l=>l.id===n.lastClickedId);if(o&&o.status===e.status){let d=n.tickets.filter(v=>v.status===e.status).map(v=>v.id),u=d.indexOf(n.lastClickedId),f=d.indexOf(e.id);if(u!==-1&&f!==-1){let v=Math.min(u,f),M=Math.max(u,f);n.selectedIds.clear();for(let b=v;b<=M;b++)n.selectedIds.add(d[b])}}else n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id}else n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id;ze(),F()}),s}function ze(){document.querySelectorAll(".column-card[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10);n.selectedIds.has(t)?e.classList.add("selected"):e.classList.remove("selected")})}function je(){let e=We(),t=n.view.startsWith("category:"),s=y(c("div",{className:"ticket-row draft-row",children:[c("span",{className:"ticket-checkbox-spacer"}),c("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),c("span",{className:"ticket-category-badge draft-badge",style:`background-color:${x(e)}${t?"":";cursor:pointer;opacity:1"}`,children:U(e)}),c("span",{className:"ticket-number draft-number"}),c("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket...",value:me}),c("span",{className:"ticket-priority-indicator draft-placeholder"}),c("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let i=s.querySelector(".ticket-category-badge");i.addEventListener("click",r=>{r.stopPropagation(),_t(i)})}let a=s.querySelector(".draft-input");return a.addEventListener("input",()=>{me=a.value}),a.addEventListener("keydown",async i=>{if(i.key==="Enter"&&a.value.trim()){i.preventDefault();let r=a.value.trim();me="",a.value="";let o=Bt();Y&&!n.view.startsWith("category:")&&(o.category=Y);let l=await p("/tickets",{method:"POST",body:{title:r,defaults:o}});l&&(n.selectedIds.clear(),n.selectedIds.add(l.id)),await m(),_()}else i.key==="ArrowDown"&&(i.preventDefault(),n.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${n.tickets[0].id}"] .ticket-title-input`)?.focus())}),s}function _(){document.querySelector(".draft-row .draft-input")?.focus()}function Bt(){let e=n.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 We(){if(Y)return Y;let e=n.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function _t(e){w();let s=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=We(),i=I(e,te().map(r=>({label:r.label,key:r.key,shortcut:`${s}${r.key.toUpperCase()}`,color:x(r.value),active:a===r.value,action:()=>{Y=r.value,h(),_()}})));document.body.appendChild(i),T(i,e),i.style.visibility=""}function Mt(e){let t=n.selectedIds.has(e.id),s=e.status==="completed"||e.status==="verified",a=e.status==="verified",i=y(c("div",{className:`ticket-row${t?" selected":""}${s?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),c("span",{className:"ticket-category-badge",style:`background-color:${x(e.category)}`,title:e.category,children:U(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("button",{className:`ticket-status-btn${a?" verified":""}`,title:e.status.replace("_"," "),children:H(a?oe:A(e.status))}),c("input",{type:"text",className:"ticket-title-input",value:e.title}),c("span",{className:"ticket-priority-indicator",style:`color:${C(e.priority)}`,title:e.priority,children:H(S(e.priority))}),c("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"})]}));i.addEventListener("mousedown",u=>{let f=u.target;f.tagName!=="INPUT"&&f.tagName!=="BUTTON"&&(i.draggable=!0)}),i.addEventListener("mouseup",()=>{i.draggable=!1}),i.addEventListener("dragend",()=>{i.draggable=!1,L=[]}),i.addEventListener("dragstart",u=>{n.selectedIds.has(e.id)&&n.selectedIds.size>1?L=Array.from(n.selectedIds):L=[e.id],u.dataTransfer.setData("text/plain",JSON.stringify(L)),u.dataTransfer.effectAllowed="move"}),i.addEventListener("mousedown",u=>{(u.metaKey||u.ctrlKey||u.shiftKey)&&(u.preventDefault(),Je(u,e)&&u.stopPropagation())});let r=i.querySelector(".ticket-checkbox");r.addEventListener("click",u=>u.stopPropagation()),r.addEventListener("change",()=>{r.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,h()}),i.querySelector(".ticket-status-btn").addEventListener("click",u=>{u.stopPropagation(),At(e)});let o=i.querySelector(".ticket-category-badge");o.addEventListener("click",u=>{u.stopPropagation(),Ge(o,e)});let l=i.querySelector(".ticket-title-input");l.addEventListener("focus",()=>{J||n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,G(),F())}),l.addEventListener("input",()=>{ee(e,"title",l.value),Rt(e.id,{title:l.value})}),l.addEventListener("keydown",u=>{Nt(u,e,l)});let d=i.querySelector(".ticket-priority-indicator");return d.addEventListener("click",u=>{u.stopPropagation(),Xe(d,e)}),i.querySelector(".ticket-star").addEventListener("click",u=>{u.stopPropagation(),Ye(e)}),i}function Ht(e){let t=n.selectedIds.has(e.id),s=e.deleted_at?new Date(e.deleted_at):null,a=y(c("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[c("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),c("span",{className:"ticket-category-badge",style:`background-color:${x(e.category)}`,children:U(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),c("span",{className:"ticket-number",title:s?`Deleted: ${s.toLocaleString()}`:"",children:s?s.toLocaleDateString():""}),c("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));a.addEventListener("mousedown",r=>{(r.metaKey||r.ctrlKey||r.shiftKey)&&(r.preventDefault(),Je(r,e)&&r.stopPropagation())});let i=a.querySelector(".ticket-checkbox");return i.addEventListener("click",r=>r.stopPropagation()),i.addEventListener("change",()=>{i.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,h()}),a.querySelector(".trash-title").addEventListener("click",()=>{n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,G(),F())}),a.querySelector(".btn").addEventListener("click",async r=>{r.stopPropagation(),await De(e),m()}),a}function Je(e,t){let s=e.metaKey||e.ctrlKey,a=e.shiftKey;if(s)n.selectedIds.has(t.id)?n.selectedIds.delete(t.id):n.selectedIds.add(t.id),n.lastClickedId=t.id,h();else if(a&&n.lastClickedId!=null){let i=n.tickets.map(l=>l.id),r=i.indexOf(n.lastClickedId),o=i.indexOf(t.id);if(r!==-1&&o!==-1){let l=Math.min(r,o),d=Math.max(r,o);n.selectedIds.clear();for(let u=l;u<=d;u++)n.selectedIds.add(i[u])}h()}else return!1;return!0}function Nt(e,t,s){if(e.key==="Enter")e.preventDefault(),_();else if(e.key==="Backspace"&&s.value==="")e.preventDefault(),$t(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),Ke(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),Ke(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),Dt(t.id);else if(e.key==="ArrowUp")e.preventDefault(),Pt(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&te().some(a=>a.key===e.key)){e.preventDefault();let a=te().find(i=>i.key===e.key);qe(t,"category",a.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&fe.some(a=>a.key===e.key)){e.preventDefault();let a=fe.find(i=>i.key===e.key);qe(t,"priority",a.value)}}function Dt(e){let t=n.tickets.findIndex(s=>s.id===e);t<n.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${n.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function Pt(e){let t=n.tickets.findIndex(s=>s.id===e);t>0?document.querySelector(`.ticket-row[data-id="${n.tickets[t-1].id}"] .ticket-title-input`)?.focus():_()}function Ke(e,t){let a=n.tickets.findIndex(o=>o.id===e)+t;if(a<0||a>=n.tickets.length)return;let i=n.tickets[a].id;n.selectedIds.add(e),n.selectedIds.has(i)?n.selectedIds.delete(e):n.selectedIds.add(i),J=!0,document.querySelector(`.ticket-row[data-id="${i}"] .ticket-title-input`)?.focus(),J=!1,G(),F()}async function At(e){let s={not_started:"started",started:"completed",completed:"verified",verified:"not_started",backlog:"not_started",archive:"not_started"}[e.status]||"not_started",a=await B(e,{status:s},"Change status");Object.assign(e,a),h()}async function Ye(e){!e.up_next&&(e.status==="completed"||e.status==="verified")?await B(e,{status:"not_started",up_next:!0},"Toggle up next"):await B(e,{up_next:!e.up_next},"Toggle up next"),m()}async function qe(e,t,s){let a=await B(e,{[t]:s},`Change ${t}`);Object.assign(e,a),h()}async function $t(e){let t=n.tickets.findIndex(a=>a.id===e),s=n.tickets.find(a=>a.id===e);if(s?await Ne(s):await p(`/tickets/${e}`,{method:"DELETE"}),n.tickets=n.tickets.filter(a=>a.id!==e),n.selectedIds.delete(e),h(),t>0&&n.tickets.length>0){let a=Math.min(t-1,n.tickets.length-1);document.querySelector(`.ticket-row[data-id="${n.tickets[a].id}"] .ticket-title-input`)?.focus()}else _()}function Rt(e,t){V&&clearTimeout(V),V=setTimeout(()=>{p(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function Ge(e,t){w();let a=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",i=I(e,te().map(r=>({label:r.label,key:r.key,shortcut:`${a}${r.key.toUpperCase()}`,color:x(r.value),active:t.category===r.value,action:async()=>{let o=await B(t,{category:r.value},"Change category");Object.assign(t,o),h()}})));document.body.appendChild(i),T(i,e),i.style.visibility=""}function Xe(e,t){w();let s=I(e,fe.map(a=>({label:a.label,key:a.key,shortcut:`Alt+${a.key}`,icon:S(a.value),iconColor:C(a.value),active:t.priority===a.value,action:async()=>{let i=await B(t,{priority:a.value},"Change priority");Object.assign(t,i),h()}})));document.body.appendChild(s),T(s,e),s.style.visibility=""}function G(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),s=e.querySelector(".ticket-checkbox");n.selectedIds.has(t)?(e.classList.add("selected"),s&&(s.checked=!0)):(e.classList.remove("selected"),s&&(s.checked=!1))})}function F(){let e=n.selectedIds.size,t=n.tickets.length,s=e>0,a=n.view==="trash",i=document.getElementById("batch-select-all");i.checked=t>0&&e===t,i.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=s?`${e} selected`:"";let r=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete","batch-more"];for(let f of r){let v=document.getElementById(f);v.style.display=a?"none":"",a||(v.disabled=!s)}let o=document.getElementById("batch-restore"),l=document.getElementById("batch-empty-trash");if(a){let f=document.getElementById("batch-toolbar");o||(o=y(c("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),o.addEventListener("click",async()=>{await p("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"restore"}}),n.selectedIds.clear(),m()}),f.insertBefore(o,document.getElementById("batch-count"))),o.disabled=!s,o.style.display="",l||(l=y(c("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),l.addEventListener("click",async()=>{await p("/trash/empty",{method:"POST"}),n.selectedIds.clear(),m()}),f.insertBefore(l,document.getElementById("batch-count"))),l.disabled=t===0,l.style.display=""}else o&&(o.style.display="none"),l&&(l.style.display="none");let d=document.querySelector(".batch-star-icon"),u=document.getElementById("batch-upnext");if(!a&&d&&s){let f=n.tickets.filter(b=>n.selectedIds.has(b.id)),v=f.every(b=>b.up_next),M=f.every(b=>!b.up_next);v?(d.textContent="\u2605",u.classList.add("active"),u.classList.remove("mixed")):M?(d.textContent="\u2606",u.classList.remove("active","mixed")):(d.innerHTML=c("span",{className:"star-mixed-wrap",children:[c("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"));O()}async function m(){if(n.backupPreview?.active){Ut();return}let e=new URLSearchParams;n.view==="trash"?e.set("status","deleted"):n.view==="up-next"?e.set("up_next","true"):n.view==="open"?e.set("status","open"):n.view==="completed"?e.set("status","completed"):n.view==="non-verified"?e.set("status","non_verified"):n.view==="verified"?e.set("status","verified"):n.view==="backlog"?e.set("status","backlog"):n.view==="archive"?e.set("status","archive"):n.view.startsWith("category:")?e.set("category",n.view.split(":")[1]):n.view.startsWith("priority:")?e.set("priority",n.view.split(":")[1]):e.set("status","active"),n.search&&e.set("search",n.search),e.set("sort_by",n.sortBy),e.set("sort_dir",n.sortDir);let t=e.toString();n.tickets=await p(`/tickets${t?"?"+t:""}`),h()}function Ut(){let e=[...n.backupPreview?.tickets||[]];if(n.view==="trash")e=e.filter(t=>t.status==="deleted");else if(n.view==="up-next")e=e.filter(t=>t.up_next&&t.status!=="deleted");else if(n.view==="open")e=e.filter(t=>t.status==="not_started"||t.status==="started");else if(n.view==="completed")e=e.filter(t=>t.status==="completed");else if(n.view==="non-verified")e=e.filter(t=>t.status!=="verified"&&t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");else if(n.view==="verified")e=e.filter(t=>t.status==="verified");else if(n.view==="backlog")e=e.filter(t=>t.status==="backlog");else if(n.view==="archive")e=e.filter(t=>t.status==="archive");else if(n.view.startsWith("category:")){let t=n.view.split(":")[1];e=e.filter(s=>s.category===t&&s.status!=="deleted"&&s.status!=="backlog"&&s.status!=="archive")}else if(n.view.startsWith("priority:")){let t=n.view.split(":")[1];e=e.filter(s=>s.priority===t&&s.status!=="deleted"&&s.status!=="backlog"&&s.status!=="archive")}else e=e.filter(t=>t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");if(n.search){let t=n.search.toLowerCase();e=e.filter(s=>s.title.toLowerCase().includes(t)||s.ticket_number.toLowerCase().includes(t)||s.details&&s.details.toLowerCase().includes(t))}n.tickets=e,h()}function Kt(e){let t=Date.now()-new Date(e).getTime(),s=Math.floor(t/6e4);if(s<1)return"just now";if(s<60)return`${s}m ago`;let a=Math.floor(s/60);return a<24?`${a}h ago`:`${Math.floor(a/24)}d ago`}function qt(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function Ot(e){return e==="5min"?"Recent (every 5 min)":e==="hourly"?"Hourly":e==="daily"?"Daily":e}async function ye(){var t;let e=document.getElementById("backup-list");if(e)try{let s=await p("/backups");if(s.backups.length===0){e.textContent="No backups yet. First backup will be created shortly.";return}let a={};for(let i of s.backups)(a[t=i.tier]||(a[t]=[])).push(i);e.innerHTML="";for(let i of["5min","hourly","daily"]){let r=a[i];if(!(!r||r.length===0)){e.appendChild(y(c("div",{className:"backup-tier-label",children:Ot(i)})));for(let o of r){let l=y(c("div",{className:"backup-row","data-tier":o.tier,"data-filename":o.filename,children:[c("span",{className:"backup-row-time",children:Kt(o.createdAt)}),c("span",{className:"backup-row-meta",children:[new Date(o.createdAt).toLocaleString()," \xB7 ",qt(o.sizeBytes)]})]}));l.addEventListener("click",()=>{Vt(o.tier,o.filename,o.createdAt)}),e.appendChild(l)}}}}catch{e.textContent="Failed to load backups."}}async function Vt(e,t,s){let a=document.getElementById("settings-overlay");a.style.display="none";let i=document.getElementById("backup-preview-banner"),r=document.getElementById("backup-preview-label");r.textContent="Loading backup preview...",i.style.display="flex";try{let o=await p(`/backups/preview/${e}/${t}`);n.backupPreview={active:!0,tickets:o.tickets,timestamp:s,tier:e,filename:t},n.selectedIds.clear(),n.activeTicketId=null,r.textContent=`Previewing backup from ${new Date(s).toLocaleString()} (${o.stats.total} tickets, ${o.stats.open} open) \u2014 read-only`,m()}catch{r.textContent="Failed to load backup preview.",setTimeout(()=>{i.style.display="none"},3e3)}}async function Ft(){let e=document.getElementById("backup-preview-banner");e.style.display="none",n.backupPreview=null,n.selectedIds.clear(),n.activeTicketId=null,await p("/backups/preview/cleanup",{method:"POST"}),m()}async function zt(){if(!n.backupPreview)return;let e=document.getElementById("backup-restore-btn");e.textContent="Restoring...",e.disabled=!0;try{await p("/backups/restore",{method:"POST",body:{tier:n.backupPreview.tier,filename:n.backupPreview.filename}}),window.location.reload()}catch{e.textContent="Restore failed",e.disabled=!1,setTimeout(()=>{e.textContent="Restore This Backup"},3e3)}}function Ze(){document.getElementById("backup-cancel-btn")?.addEventListener("click",()=>{Ft()}),document.getElementById("backup-restore-btn")?.addEventListener("click",()=>{zt()});let e=document.getElementById("backup-now-btn");e?.addEventListener("click",async()=>{e.textContent="Backing up...",e.disabled=!0;try{(await p("/backups/now",{method:"POST"})).error?e.textContent="In progress...":(e.textContent="Done!",ye())}catch{e.textContent="Failed"}setTimeout(()=>{e.textContent="Backup Now",e.disabled=!1},1500)})}async function jt(){await Wt(),await Jt(),Yt(),await m(),on(),nn(),sn(),rn(),ln(),cn(),dn(),mn(),Gt(),Ze(),en(),tn(),He(),fn(),Zt(),document.addEventListener("hotsheet:render",()=>h()),_()}async function Wt(){try{let e=await p("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(n.settings.detail_position=e.detail_position),e.detail_width&&(n.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(n.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(n.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(n.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30),(e.layout==="list"||e.layout==="columns")&&(n.layout=e.layout)}catch{}ce(n.settings.detail_position),de()}async function Jt(){try{let e=await p("/categories");e.length>0&&(n.categories=e)}catch{}Ee()}function Ee(){let e=document.querySelector(".sidebar-section:nth-child(3)");if(e){let t=e.querySelector(".sidebar-label");e.innerHTML="",t&&e.appendChild(t);for(let s of n.categories){let a=y(c("button",{className:`sidebar-item${n.view===`category:${s.id}`?" active":""}`,"data-view":`category:${s.id}`,children:[c("span",{className:"cat-dot",style:`background:${s.color}`})," ",s.label]}));a.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(i=>i.classList.remove("active")),a.classList.add("active"),n.view=`category:${s.id}`,n.selectedIds.clear(),m()}),e.appendChild(a)}}if(n.activeTicketId!=null){let t=n.tickets.find(s=>s.id===n.activeTicketId);t&&j(t.category)}}async function Yt(){try{let e=await p("/file-settings");if(e.appName){document.title=e.appName;let t=document.querySelector(".app-title h1");t&&(t.textContent=e.appName)}}catch{}}function Gt(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close"),s=document.getElementById("settings-btn"),a=document.querySelectorAll(".settings-tab"),i=document.querySelectorAll(".settings-tab-panel");a.forEach(g=>{g.addEventListener("click",()=>{let D=g.dataset.tab;a.forEach(K=>K.classList.remove("active")),i.forEach(K=>K.classList.remove("active")),g.classList.add("active"),document.querySelector(`.settings-tab-panel[data-panel="${D}"]`)?.classList.add("active")})}),s.addEventListener("click",()=>{document.getElementById("settings-trash-days").value=String(n.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(n.settings.verified_cleanup_days),e.style.display="flex",ye(),p("/file-settings").then(g=>{document.getElementById("settings-app-name").value=g.appName||"",document.getElementById("settings-backup-dir").value=g.backupDir||""})}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",g=>{g.target===e&&(e.style.display="none")});let r=document.getElementById("settings-trash-days"),o=null;r.addEventListener("input",()=>{o&&clearTimeout(o),o=setTimeout(()=>{let g=Math.max(1,parseInt(r.value,10)||3);r.value=String(g),n.settings.trash_cleanup_days=g,p("/settings",{method:"PATCH",body:{trash_cleanup_days:String(g)}})},500)});let l=document.getElementById("settings-verified-days"),d=null;l.addEventListener("input",()=>{d&&clearTimeout(d),d=setTimeout(()=>{let g=Math.max(1,parseInt(l.value,10)||30);l.value=String(g),n.settings.verified_cleanup_days=g,p("/settings",{method:"PATCH",body:{verified_cleanup_days:String(g)}})},500)});let u=document.getElementById("settings-app-name"),f=document.getElementById("settings-app-name-hint"),v=null;u.addEventListener("input",()=>{v&&clearTimeout(v),v=setTimeout(()=>{let g=u.value.trim();p("/file-settings",{method:"PATCH",body:{appName:g}}).then(()=>{let D=g||"Hot Sheet";document.title=D;let K=document.querySelector(".app-title h1");K&&(K.textContent=D),f.textContent=g?"Saved. Restart the desktop app to update the title bar.":"Using default name."})},800)});let M=document.getElementById("check-updates-btn"),b=document.getElementById("check-updates-status");M.addEventListener("click",async()=>{let g=Te();if(g){M.disabled=!0,M.textContent="Checking...",b.textContent="";try{let D=await g("check_for_update");D?(b.textContent=`Update available: v${D}`,document.getElementById("settings-overlay").style.display="none",at(D)):b.textContent="Your software is up to date."}catch{b.textContent="Could not check for updates."}M.textContent="Check for Updates",M.disabled=!1}});let Ie=document.getElementById("settings-backup-dir"),lt=document.getElementById("settings-backup-dir-hint"),ae=null;Ie.addEventListener("input",()=>{ae&&clearTimeout(ae),ae=setTimeout(()=>{let g=Ie.value.trim();p("/file-settings",{method:"PATCH",body:{backupDir:g}}).then(()=>{lt.textContent=g?"Saved. New backups will use this location.":"Using default location inside the data directory."})},800)}),Xt()}function se(){let e=document.getElementById("category-list");e.innerHTML="";for(let t=0;t<n.categories.length;t++){let s=n.categories[t],a=y(c("div",{className:"category-row",children:[c("input",{type:"color",className:"category-color-input",value:s.color,title:"Color"}),c("input",{type:"text",className:"category-label-input",value:s.label,placeholder:"Label",title:"Display name"}),c("input",{type:"text",className:"category-short-input",value:s.shortLabel,placeholder:"ABR",title:"Short label (3 chars)",maxlength:"4"}),c("input",{type:"text",className:"category-key-input",value:s.shortcutKey,placeholder:"k",title:"Keyboard shortcut",maxlength:"1"}),c("input",{type:"text",className:"category-desc-input",value:s.description,placeholder:"Description...",title:"Description (for AI tools)"}),c("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]})),i=a.querySelectorAll("input"),[r,o,l,d,u]=i,f=()=>{et()};r.addEventListener("input",()=>{n.categories[t].color=r.value,f()}),o.addEventListener("input",()=>{n.categories[t].label=o.value,(!s.id||s.id==="")&&(n.categories[t].id=o.value.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")),f()}),l.addEventListener("input",()=>{n.categories[t].shortLabel=l.value.toUpperCase(),f()}),d.addEventListener("input",()=>{let v=d.value.toLowerCase().slice(0,1);d.value=v,n.categories[t].shortcutKey=v,Qe(),f()}),u.addEventListener("input",()=>{n.categories[t].description=u.value,f()}),a.querySelector(".category-delete-btn").addEventListener("click",()=>{n.categories.splice(t,1),se(),et()}),e.appendChild(a)}Qe()}function Qe(){let e=document.querySelectorAll(".category-key-input"),t=new Map;n.categories.forEach((s,a)=>{if(s.shortcutKey){let i=s.shortcutKey.toLowerCase();t.has(i)||t.set(i,[]),t.get(i).push(a)}}),e.forEach((s,a)=>{let i=n.categories[a]?.shortcutKey?.toLowerCase();i&&t.get(i).length>1?s.classList.add("category-key-conflict"):s.classList.remove("category-key-conflict")})}var ve=null;function et(){ve&&clearTimeout(ve),ve=setTimeout(async()=>{await p("/categories",{method:"PUT",body:n.categories}),Ee()},500)}function Xt(){document.getElementById("category-add-btn").addEventListener("click",()=>{n.categories.push({id:"",label:"",shortLabel:"",color:"#6b7280",shortcutKey:"",description:""}),se();let s=document.querySelectorAll(".category-row");s[s.length-1]?.querySelector(".category-label-input")?.focus()});let e=document.getElementById("category-preset-select");p("/category-presets").then(s=>{for(let a of s)e.appendChild(y(c("option",{value:a.id,children:a.name})))}),e.addEventListener("change",async()=>{if(!e.value)return;let a=(await p("/category-presets")).find(i=>i.id===e.value);a&&(n.categories=[...a.categories],await p("/categories",{method:"PUT",body:n.categories}),se(),Ee()),e.value=""}),document.getElementById("settings-btn").addEventListener("click",()=>{se()})}async function Zt(){let e=Te();if(!e)return;let t=document.getElementById("settings-updates-section");t&&(t.style.display="");let s=document.getElementById("settings-tab-updates");s&&(s.style.display="");let a=[0,3e3,1e4];for(let i of a){i>0&&await new Promise(r=>setTimeout(r,i));try{let r=await e("get_pending_update");if(r){at(r);return}}catch{return}}}function Te(){return window.__TAURI__?.core?.invoke??null}function at(e){let t=document.getElementById("update-banner");if(!t)return;let s=document.getElementById("update-banner-label");s&&(s.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 Te()?.("install_update"),s&&(s.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 Qt(){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 en(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),s=document.getElementById("copy-prompt-label"),a=document.getElementById("copy-prompt-icon"),i="";p("/worklist-info").then(r=>{i=r.prompt,e.style.display="",r.skillCreated&&Qt()}),t.addEventListener("click",()=>{i!==""&&navigator.clipboard.writeText(i).then(()=>{s.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(()=>{s.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 tn(){let e=document.getElementById("glassbox-btn"),t=document.getElementById("glassbox-icon");p("/glassbox/status").then(({available:s})=>{s&&(t.src="/static/assets/glassbox-icon.png",e.style.display="")}).catch(()=>{}),e.addEventListener("click",()=>{p("/glassbox/launch",{method:"POST"})})}function ke(){let e=document.getElementById("layout-toggle"),t=ne(),s=e.querySelector('[data-layout="columns"]');s.disabled=!t,s.style.opacity=t?"":"0.3";let a=n.layout==="columns"&&!t?"list":n.layout;e.querySelectorAll(".layout-btn").forEach(i=>{i.classList.toggle("active",i.dataset.layout===a)})}function nn(){document.getElementById("layout-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let s=t.dataset.layout;s==="columns"&&!ne()||(n.layout=s,ke(),h(),p("/settings",{method:"PATCH",body:{layout:s}}))})}),ke()}function tt(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.classList.toggle("active",t.dataset.position===n.settings.detail_position)})}function sn(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let s=t.dataset.position;n.settings.detail_position=s,ce(s),de(),tt(),p("/settings",{method:"PATCH",body:{detail_position:s}})})}),tt()}function it(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 an(e,t){let s=it(e);if(!s)return;let a=n.tickets.filter(i=>t.includes(i.id));s.action==="delete"?await E(a,{ids:t,action:"delete"},"Delete tickets"):await E(a,{ids:t,action:s.action,value:s.value},`Change ${s.action}`),m()}function on(){let e=document.querySelectorAll(".sidebar-item[data-view]");e.forEach(t=>{t.addEventListener("click",()=>{e.forEach(a=>{a.classList.remove("active")}),t.classList.add("active"),n.view=t.dataset.view,n.selectedIds.clear(),ke(),m()});let s=t.dataset.view;it(s)&&(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 i=[...L];i.length!==0&&an(s,i)}))})}function rn(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,s]=e.value.split(":");n.sortBy=t,n.sortDir=s,m()})}var he=null;function ln(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{he&&clearTimeout(he),he=setTimeout(()=>{n.search=e.value,m()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",n.search="",m())})}var ot=[{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"}],rt=[{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 cn(){let e=document.getElementById("batch-category");e.addEventListener("click",i=>{i.stopPropagation(),w();let r=I(e,n.categories.map(o=>({label:o.label,key:o.shortcutKey,color:o.color,action:async()=>{let l=Array.from(n.selectedIds),d=n.tickets.filter(u=>n.selectedIds.has(u.id));await E(d,{ids:l,action:"category",value:o.id},"Batch change category"),m()}})));document.body.appendChild(r),T(r,e),r.style.visibility=""});let t=document.getElementById("batch-priority");t.addEventListener("click",i=>{i.stopPropagation(),w();let r=I(t,ot.map(o=>({label:o.label,key:o.key,icon:S(o.value),iconColor:C(o.value),action:async()=>{let l=Array.from(n.selectedIds),d=n.tickets.filter(u=>n.selectedIds.has(u.id));await E(d,{ids:l,action:"priority",value:o.value},"Batch change priority"),m()}})));document.body.appendChild(r),T(r,t),r.style.visibility=""});let s=document.getElementById("batch-status");s.addEventListener("click",i=>{i.stopPropagation(),w();let r=I(s,rt.map(o=>({label:o.label,key:o.key,icon:A(o.value),action:async()=>{let l=Array.from(n.selectedIds),d=n.tickets.filter(u=>n.selectedIds.has(u.id));await E(d,{ids:l,action:"status",value:o.value},"Batch change status"),m()}})));document.body.appendChild(r),T(r,s),r.style.visibility=""}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let i=n.tickets.filter(d=>n.selectedIds.has(d.id)),o=!i.every(d=>d.up_next),l=Array.from(n.selectedIds);if(o){let d=i.filter(u=>u.status==="completed"||u.status==="verified");if(d.length>0){let u=[{ids:d.map(f=>f.id),action:"status",value:"not_started"},{ids:l,action:"up_next",value:!0}];await pe(i,u,"Batch toggle up next")}else await E(i,{ids:l,action:"up_next",value:!0},"Batch toggle up next")}else await E(i,{ids:l,action:"up_next",value:!1},"Batch toggle up next");m()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let i=Array.from(n.selectedIds),r=n.tickets.filter(o=>n.selectedIds.has(o.id));await E(r,{ids:i,action:"delete"},"Batch delete"),n.selectedIds.clear(),m()});let a=document.getElementById("batch-more");a.addEventListener("click",i=>{i.stopPropagation(),w();let r=I(a,[{label:"Duplicate",key:"d",action:async()=>{let o=Array.from(n.selectedIds),l=await p("/tickets/duplicate",{method:"POST",body:{ids:o}});n.selectedIds.clear();for(let d of l)n.selectedIds.add(d.id);m()}},{label:"Move to Backlog",key:"b",action:async()=>{let o=Array.from(n.selectedIds),l=n.tickets.filter(d=>n.selectedIds.has(d.id));await E(l,{ids:o,action:"status",value:"backlog"},"Move to backlog"),n.selectedIds.clear(),m()}},{label:"Archive",key:"a",action:async()=>{let o=Array.from(n.selectedIds),l=n.tickets.filter(d=>n.selectedIds.has(d.id));await E(l,{ids:o,action:"status",value:"archive"},"Archive"),n.selectedIds.clear(),m()}}]);document.body.appendChild(r),T(r,a),r.style.visibility=""}),document.getElementById("batch-select-all").addEventListener("change",i=>{if(i.target.checked)for(let o of n.tickets)n.selectedIds.add(o.id);else n.selectedIds.clear();h()})}var N=null;function dn(){document.getElementById("detail-close").addEventListener("click",Be);let e=["detail-title","detail-details"];for(let s of e){let a=document.getElementById(s);a.addEventListener("input",()=>{let i=n.tickets.find(r=>r.id===n.activeTicketId);if(i){let r=s.replace("detail-","");ee(i,r,a.value)}N&&clearTimeout(N),N=setTimeout(()=>{if(n.activeTicketId==null)return;let r=s.replace("detail-","");p(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[r]:a.value}}).then(()=>{m()})},300)})}async function t(s,a){if(n.activeTicketId==null)return;let i=n.tickets.find(r=>r.id===n.activeTicketId);i?await B(i,{[s]:a},`Change ${s}`):await p(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[s]:a}}),m(),W(n.activeTicketId)}document.getElementById("detail-category").addEventListener("click",s=>{s.stopPropagation();let a=s.currentTarget;if(a.disabled)return;w();let i=a.dataset.value||"",r=I(a,n.categories.map(o=>({label:o.label,key:o.shortcutKey,color:o.color,active:o.id===i,action:()=>{j(o.id),t("category",o.id)}})));document.body.appendChild(r),T(r,a),r.style.visibility=""}),document.getElementById("detail-priority").addEventListener("click",s=>{s.stopPropagation();let a=s.currentTarget;if(a.disabled)return;w();let i=a.dataset.value||"",r=I(a,ot.map(o=>({label:o.label,key:o.key,icon:S(o.value),iconColor:C(o.value),active:o.value===i,action:()=>{X(o.value),t("priority",o.value)}})));document.body.appendChild(r),T(r,a),r.style.visibility=""}),document.getElementById("detail-status").addEventListener("click",s=>{s.stopPropagation();let a=s.currentTarget;if(a.disabled)return;w();let i=a.dataset.value||"",r=I(a,rt.map(o=>({label:o.label,key:o.key,icon:A(o.value),active:o.value===i,action:()=>{Z(o.value),t("status",o.value)}})));document.body.appendChild(r),T(r,a),r.style.visibility=""}),document.getElementById("detail-upnext").addEventListener("click",async()=>{if(n.activeTicketId==null)return;let s=n.tickets.find(a=>a.id===n.activeTicketId);s?!s.up_next&&(s.status==="completed"||s.status==="verified")?await B(s,{status:"not_started",up_next:!0},"Toggle up next"):await B(s,{up_next:!s.up_next},"Toggle up next"):await p(`/tickets/${n.activeTicketId}/up-next`,{method:"POST"}),m(),W(n.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async s=>{let a=s.target,i=a.files?.[0];!i||n.activeTicketId==null||(await Se(`/tickets/${n.activeTicketId}/attachments`,i),a.value="",W(n.activeTicketId),m())}),document.getElementById("detail-attachments").addEventListener("click",async s=>{let a=s.target,i=a.closest(".attachment-reveal");if(i){let l=i.dataset.attId;l&&p(`/attachments/${l}/reveal`,{method:"POST"});return}let r=a.closest(".attachment-delete");if(r===null)return;let o=r.dataset.attId;o===void 0||o===""||(await p(`/attachments/${o}`,{method:"DELETE"}),n.activeTicketId!=null&&W(n.activeTicketId))})}function un(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 pn(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let s=un(e.notes);if(s.length>0){t.push("");for(let a of s)t.push(`- ${a.text}`)}return t.join(`
2
- `)}function nt(){console.log("[undo] triggerUndo called, canUndo:",Re()),N&&(clearTimeout(N),N=null),ge(),Ae().then(()=>console.log("[undo] performUndo completed")).catch(e=>console.error("[undo] performUndo error:",e))}function st(){console.log("[undo] triggerRedo called, canRedo:",Ue()),N&&(clearTimeout(N),N=null),ge(),$e().then(()=>console.log("[undo] performRedo completed")).catch(e=>console.error("[undo] performRedo error:",e))}function mn(){window.addEventListener("app:undo",nt),window.addEventListener("app:redo",st),document.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="z"&&(e.preventDefault(),e.stopPropagation(),e.shiftKey?st():nt())},!0),document.addEventListener("keydown",e=>{let t=e.target.tagName,s=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"){n.selectedIds.size>0&&(n.selectedIds.clear(),h());return}if((e.metaKey||e.ctrlKey)&&e.key==="a"&&!s){e.preventDefault(),n.selectedIds.clear();for(let i of n.tickets)n.selectedIds.add(i.id);h();return}if((e.metaKey||e.ctrlKey)&&e.key==="d"){if(n.selectedIds.size>0){e.preventDefault();let i=n.tickets.filter(d=>n.selectedIds.has(d.id)),o=!i.every(d=>d.up_next),l=Array.from(n.selectedIds);if(o){let d=i.filter(u=>u.status==="completed"||u.status==="verified");if(d.length>0){pe(i,[{ids:d.map(u=>u.id),action:"status",value:"not_started"},{ids:l,action:"up_next",value:!0}],"Toggle up next").then(()=>{m()});return}}E(i,{ids:l,action:"up_next",value:o},"Toggle up next").then(()=>{m()})}return}if((e.metaKey||e.ctrlKey)&&e.key==="c"&&n.selectedIds.size>0&&!(s&&!e.altKey)){let i=!e.altKey&&window.getSelection();if(!(i&&!i.isCollapsed&&i.toString().trim()!=="")){e.preventDefault();let o=n.tickets.filter(l=>n.selectedIds.has(l.id)).map(pn).join(`
1
+ "use strict";(()=>{var hn=Object.defineProperty;var bn=(e,t,n)=>t in e?hn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var me=(e,t,n)=>bn(e,typeof t!="symbol"?t+"":t,n);var Re=!1;function H(){Re=!0}function ht(){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 xe(e){if(Re){Re=!1;return}e.size!==0&&document.querySelectorAll(".ticket-row[data-id], .column-card[data-id]").forEach(t=>{let n=t,s=n.dataset.id,o=e.get(s);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 u=()=>{n.style.transition=""};n.addEventListener("transitionend",u,{once:!0}),setTimeout(u,250)})}function v(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function bt(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function kt(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var Q=class{constructor(t){me(this,"__html");this.__html=t}toString(){return this.__html}};function D(e){return new Q(e)}var kn=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 Q?e.__html:typeof e=="string"?bt(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(qe).join(""):""}var wn={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 En(e,t){let n=wn[e]??e;if(t==null||t===!1)return"";if(t===!0)return` ${n}`;let s;return t instanceof Q?s=t.__html:typeof t=="number"?s=String(t):typeof t=="string"?s=kt(t):s="",` ${n}="${s}"`}function r(e,t){if(typeof e=="function")return e(t);let{children:n,...s}=t,o=Object.entries(s).map(([l,c])=>En(l,c)).join("");if(kn.has(e))return new Q(`<${e}${o}>`);let i=n!=null?qe(n):"";return new Q(`<${e}${o}>${i}</${e}>`)}function ge({children:e}){return new Q(e!=null?qe(e):"")}function wt(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 wt("Unable to reach the server. It may have been stopped."),n}}async function Et(e,t){try{let n=new FormData;return n.append("file",t),(await fetch("/api"+e,{method:"POST",body:n})).json()}catch(n){throw wt("Unable to reach the server. It may have been stopped."),n}}var Tn={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},a={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:{...Tn},backupPreview:null},xn='<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>',Ln={highest:"\u2B06\u2B06",high:"\u2B06",default:xn,low:"\u2B07",lowest:"\u2B07\u2B07"},In={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},Tt='<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>',Cn={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:Tt,backlog:"\u25A1",archive:"\u25A0"},Ue=Tt;function S(e){return a.categories.find(n=>n.id===e)?.color||"#6b7280"}function z(e){return a.categories.find(n=>n.id===e)?.shortLabel||e.slice(0,3).toUpperCase()}function A(e){return Ln[e]||"\u2014"}function P(e){return In[e]||"#6b7280"}function F(e){return Cn[e]||"\u25CB"}function K(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 ye(e,t){let n=document.getElementById("detail-tags");if(n){n.innerHTML="";for(let s of e){let o=v(r("span",{className:"tag-chip",children:[s,t?null:r("button",{className:"tag-chip-remove","data-tag":s,title:"Remove tag",children:"\xD7"})]}));t||o.querySelector(".tag-chip-remove").addEventListener("click",async()=>{if(a.activeTicketId==null)return;let i=a.tickets.find(u=>u.id===a.activeTicketId);if(!i)return;let c=K(i.tags).filter(u=>u!==s);await f(`/tickets/${a.activeTicketId}`,{method:"PATCH",body:{tags:JSON.stringify(c)}}),i.tags=JSON.stringify(c),ye(c,!1)}),n.appendChild(o)}}}var Sn={not_started:"Not Started",started:"Started",completed:"Completed",verified:"Verified",backlog:"Backlog",archive:"Archive"},Mn={highest:"Highest",high:"High",default:"Default",low:"Low",lowest:"Lowest"};function ve(e){let t=document.getElementById("detail-category");t.dataset.value=e;let n=a.categories.find(o=>o.id===e),s=S(e);t.innerHTML=`<span class="cat-dot" style="background:${s}"></span> ${n?.label||e}`}function Le(e){let t=document.getElementById("detail-priority");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon" style="color:${P(e)}">${A(e)}</span> ${Mn[e]||e}`}function Ie(e){let t=document.getElementById("detail-status");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon">${F(e)}</span> ${Sn[e]||e}`}function oe(e){a.activeTicketId=e,Ve(e)}function It(){a.selectedIds.clear(),a.activeTicketId=null,ie();let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function ie(){let e=a.view==="trash",t=!!a.backupPreview?.active,n=document.getElementById("detail-panel"),s=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",s&&(s.style.display="none"),a.activeTicketId=null;return}if(n.style.display="flex",s&&(s.style.display=""),a.selectedIds.size===1){let u=Array.from(a.selectedIds)[0];n.classList.remove("detail-disabled"),o.style.display="",i.style.display="",l.style.display="none",a.activeTicketId!==u&&(a.activeTicketId=u,t?$n(u):Ve(u))}else a.activeTicketId=null,n.classList.add("detail-disabled"),o.style.display="none",i.style.display="none",l.style.display="",a.selectedIds.size===0?c.textContent="Nothing selected":c.textContent=`${a.selectedIds.size} items selected`}function Ct(e){let t=document.getElementById("detail-title"),n=document.getElementById("detail-details"),s=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,s.disabled=e,o.disabled=e,i.disabled=e,l.disabled=e,c&&(c.style.display=e?"none":"")}function $n(e){let t=a.backupPreview?.tickets.find(l=>l.id===e);if(!t||a.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,ve(t.category),Le(t.priority),Ie(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,Ct(!0),document.getElementById("detail-attachments").innerHTML="",ye(K(t.tags),!0);let s=document.getElementById("detail-notes"),o=St(t.notes);o.length>0?s.innerHTML=r(ge,{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():s.innerHTML="";let i=document.getElementById("detail-meta");i.innerHTML=r(ge,{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 he(){a.activeTicketId!=null&&Ve(a.activeTicketId)}async function Ve(e){let t=await f(`/tickets/${e}`);if(a.activeTicketId!==e)return;Ct(!1),document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,ve(t.category),Le(t.priority),Ie(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 s=document.getElementById("detail-attachments");t.attachments.length>0?s.innerHTML=r(ge,{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():s.innerHTML="",ye(K(t.tags),!1),Oe(t.id,St(t.notes));let o=document.getElementById("detail-meta");o.innerHTML=r(ge,{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 xt(e,t){let n=a.tickets.find(s=>s.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 s of t){let o=v(r("div",{className:"note-entry",children:[s.created_at?r("div",{className:"note-timestamp",children:new Date(s.created_at).toLocaleString()}):null,r("div",{className:"note-text",children:s.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=s.text,l.rows=3,i.style.display="none",o.appendChild(l),l.focus();let c=async()=>{let u=l.value.trim();if(u&&u!==s.text){let d=a.tickets.find(m=>m.id===e),p=t.map(m=>m.id===s.id?{...m,text:u}:m);d&&fe(d,"Edit note",JSON.stringify(p)),await f(`/tickets/${e}/notes/${s.id}`,{method:"PATCH",body:{text:u}}),s.text=u,xt(e,t)}Oe(e,t)};l.addEventListener("blur",()=>{c()}),l.addEventListener("keydown",u=>{u.key==="Enter"&&(u.metaKey||u.ctrlKey)&&(u.preventDefault(),c()),u.key==="Escape"&&(u.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 u=a.tickets.find(m=>m.id===e),d=t.filter(m=>m.id!==s.id);u&&fe(u,"Delete note",JSON.stringify(d)),await f(`/tickets/${e}/notes/${s.id}`,{method:"DELETE"});let p=t.indexOf(s);p>=0&&t.splice(p,1),xt(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 Nn=0;function Lt(){return`cn_${Date.now().toString(36)}_${(Nn++).toString(36)}`}function St(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.map(n=>({id:n.id||Lt(),text:n.text,created_at:n.created_at}))}catch{}return e.trim()?[{id:Lt(),text:e,created_at:""}]:[]}async function Ce(){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");a.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${a.settings.detail_height}px`):(e.style.height="",e.style.width=`${a.settings.detail_width}px`)}function Mt(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),n=document.getElementById("content-area"),s=!1;e.addEventListener("mousedown",o=>{o.preventDefault(),s=!0,document.body.style.cursor=a.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",o=>{if(!s)return;let i=n.getBoundingClientRect();if(a.settings.detail_position==="bottom"){let l=Math.max(150,Math.min(500,i.bottom-o.clientY));a.settings.detail_height=l,t.style.height=`${l}px`}else{let l=Math.max(250,Math.min(600,i.right-o.clientX));a.settings.detail_width=l,t.style.width=`${l}px`}}),document.addEventListener("mouseup",()=>{s&&(s=!1,document.body.style.cursor="",document.body.style.userSelect="",a.settings.detail_position==="bottom"?f("/settings",{method:"PATCH",body:{detail_height:String(a.settings.detail_height)}}):f("/settings",{method:"PATCH",body:{detail_width:String(a.settings.detail_width)}}))})}var Fe=class{constructor(){me(this,"undoStack",[]);me(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}},$=new Fe;function W(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 s=W(e),o=await f(`/tickets/${e.id}`,{method:"PATCH",body:t}),i=W(o);return $.push({label:n,timestamp:Date.now(),before:[s],after:[i]}),o}function Se(e,t,n){let s=`${e.id}:${t}`,o=Date.now(),i={...W(e),[t]:n},l={label:`Edit ${t}`,timestamp:o,before:[W(e)],after:[i],coalescingKey:s};$.coalesce(l)||$.push(l)}async function C(e,t,n){let s=e.map(i=>W(i));await f("/tickets/batch",{method:"POST",body:t});let o=s.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});$.push({label:n,timestamp:Date.now(),before:s,after:o})}async function We(e,t,n){let s=e.map(i=>W(i));for(let i of t)await f("/tickets/batch",{method:"POST",body:i});let o=s.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});$.push({label:n,timestamp:Date.now(),before:s,after:o})}async function Me(e){let t=W(e);await f(`/tickets/${e.id}`,{method:"DELETE"});let n={...t,status:"deleted"};$.push({label:"Delete ticket",timestamp:Date.now(),before:[t],after:[n]})}async function $t(e){let t=W(e);await f(`/tickets/${e.id}/restore`,{method:"POST"});let n={...t,status:"not_started"};$.push({label:"Restore ticket",timestamp:Date.now(),before:[t],after:[n]})}async function Nt(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 ee=!1;async function Bt(){if(console.log("[undo] performUndo, inFlight:",ee,"canUndo:",$.canUndo()),ee){console.log("[undo] skipped \u2014 already in flight");return}let e=$.popUndo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying before-state:",e.label,JSON.stringify(e.before)),ee=!0;try{await Nt(e.before),console.log("[undo] applySnapshots done, reloading tickets"),await w(),setTimeout(()=>he(),50)}finally{ee=!1}}async function _t(){if(console.log("[undo] performRedo, inFlight:",ee,"canRedo:",$.canRedo()),ee){console.log("[undo] skipped \u2014 already in flight");return}let e=$.popRedo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying after-state:",e.label,JSON.stringify(e.after)),ee=!0;try{await Nt(e.after),console.log("[undo] applySnapshots done, reloading tickets"),await w(),setTimeout(()=>he(),50)}finally{ee=!1}}function fe(e,t,n){let s=W(e,!0),o={...W(e,!0),notes:n};$.push({label:t,timestamp:Date.now(),before:[s],after:[o]})}function Ht(){return $.canUndo()}function Dt(){return $.canRedo()}function Ye(e,t){e.preventDefault(),te(),a.selectedIds.has(t.id)||(a.selectedIds.clear(),a.selectedIds.add(t.id),a.lastClickedId=t.id,L());let n=v(r("div",{className:"context-menu",style:`top:${e.clientY}px;left:${e.clientX}px`}));je(n,"Category",a.categories.map(i=>({label:i.label,icon:`<span class="dropdown-dot" style="background-color:${i.color}"></span>`,active:t.category===i.id,action:()=>re("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:()=>re("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:F(i.value),active:t.status===i.value,action:()=>re("status",i.value)}))),le(n,t.up_next?"\u2605 Up Next":"\u2606 Up Next",()=>{re("up_next",!t.up_next)}),Je(n),le(n,"Tags...",()=>{document.dispatchEvent(new CustomEvent("hotsheet:show-tags-dialog"))}),le(n,"Duplicate",async()=>{let i=Array.from(a.selectedIds),l=await f("/tickets/duplicate",{method:"POST",body:{ids:i}});a.selectedIds.clear();for(let c of l)a.selectedIds.add(c.id);w()}),Je(n),le(n,"Move to Backlog",()=>re("status","backlog")),le(n,"Archive",()=>re("status","archive")),Je(n),le(n,"Delete",async()=>{if(a.selectedIds.size===1)await Me(t);else{let i=Array.from(a.selectedIds),l=a.tickets.filter(c=>a.selectedIds.has(c.id));await C(l,{ids:i,action:"delete"},"Delete")}a.selectedIds.clear(),w()},!0),document.body.appendChild(n),Bn(n),setTimeout(()=>{document.addEventListener("click",te),document.addEventListener("contextmenu",te)},0)}function te(){document.querySelectorAll(".context-menu").forEach(e=>e.remove()),document.removeEventListener("click",te),document.removeEventListener("contextmenu",te)}function Bn(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 re(e,t){let n=Array.from(a.selectedIds),s=a.tickets.filter(o=>a.selectedIds.has(o.id));if(n.length===1){let o=s[0];await R(o,{[e]:t},`Change ${e}`)}else await C(s,{ids:n,action:e,value:t},`Change ${e}`);w()}function je(e,t,n){let s=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(),te()}),o.appendChild(l)}s.appendChild(o),e.appendChild(s)}function le(e,t,n,s=!1){let o=v(r("div",{className:`context-menu-item${s?" danger":""}`,children:r("span",{className:"context-menu-label",children:t})}));o.addEventListener("click",i=>{i.stopPropagation(),te(),n()}),e.appendChild(o)}function Je(e){e.appendChild(v(r("div",{className:"context-menu-separator"})))}function N(e,t){let n=t.getBoundingClientRect(),s=e.getBoundingClientRect(),o=window.innerWidth,i=window.innerHeight,l=n.left;l+s.width>o-8&&(l=n.right-s.width),l<8&&(l=8);let c=n.bottom+4;c+s.height>i-8&&(c=n.top-s.height-4),c<8&&(c=8),e.style.left=`${l}px`,e.style.top=`${c}px`}function B(e,t){let n=v(r("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(u=>u.separator?r("div",{className:"dropdown-separator"}):r("button",{className:`dropdown-item${u.active?" active":""}`,"data-key":u.key,children:[u.color?r("span",{className:"dropdown-dot",style:`background-color:${u.color}`}):null,u.icon?r("span",{className:"dropdown-icon",style:u.iconColor?`color:${u.iconColor}`:"",children:D(u.icon)}):null,r("span",{className:"dropdown-label",children:u.label}),u.shortcut?r("kbd",{className:"dropdown-kbd",children:u.shortcut}):null]}))})),s=t.filter(u=>!u.separator);n.querySelectorAll(".dropdown-item").forEach((u,d)=>{u.addEventListener("click",()=>{s[d].action(),n.remove()})});function i(u){let d=t.find(p=>u.key.toLowerCase()===p.key.toLowerCase());d?(u.preventDefault(),u.stopPropagation(),d.action(),l()):u.key==="Escape"&&(u.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 _(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var ce=null;function Ze(){ce&&(clearTimeout(ce),ce=null)}var be=!1,ke=null,Xe="",U=[];function $e(){return a.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 _n(){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 Hn(e){e!=null&&(be=!0,e==="draft"?j():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),be=!1)}function Ne(){let e=a.view;return e.startsWith("custom:")?!0:e!=="completed"&&e!=="verified"&&e!=="trash"&&e!=="backlog"&&e!=="archive"}function Rt(){return a.view==="up-next"||a.view==="open"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"}]:a.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=ht(),t=!!a.backupPreview?.active;if(a.layout==="columns"&&Ne()){if(t){An(),xe(e);return}Rn(),xe(e);return}let n=a.view==="trash",s=t?null:_n(),o=null;if(s!=null&&s!=="draft"){let c=document.querySelector(`.ticket-row[data-id="${s}"] .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(Vt()),a.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 a.tickets)t?i.appendChild(Dn(c)):n?i.appendChild(Kn(c)):i.appendChild(Vn(c));if(i.scrollTop=l,t){let c=document.getElementById("batch-toolbar");c&&(c.style.display="none"),we(),ie()}else{let c=document.getElementById("batch-toolbar");if(c&&(c.style.display=""),s!=null&&s!=="draft"&&o!=null){let u=document.querySelector(`.ticket-row[data-id="${s}"] .ticket-title-input`);u&&u.value!==o&&(u.value=o)}Hn(s),de()}Ce(),xe(e)}function Dn(e){let t=a.selectedIds.has(e.id),n=e.status==="completed"||e.status==="verified",s=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:${S(e.category)};cursor:default`,title:e.category,children:z(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:`ticket-status-btn${s?" verified":""}`,style:"cursor:default",children:D(s?Ue:F(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",()=>{a.selectedIds.clear(),a.selectedIds.add(e.id),a.lastClickedId=e.id,we(),ie()}),o}function qt(e){let t={scrollLeft:0,columns:{}},n=e.querySelector(".columns-container");return n&&(t.scrollLeft=n.scrollLeft,n.querySelectorAll(".column[data-status]").forEach(s=>{let o=s.dataset.status,i=s.querySelector(".column-body");i&&(t.columns[o]=i.scrollTop)})),t}function Ut(e,t){let n=e.querySelector(".columns-container");n&&(n.scrollLeft=t.scrollLeft,n.querySelectorAll(".column[data-status]").forEach(s=>{let o=s.dataset.status,i=s.querySelector(".column-body");i&&t.columns[o]!=null&&(i.scrollTop=t.columns[o])}))}function An(){let e=document.getElementById("ticket-list"),t=qt(e);e.innerHTML="",e.classList.add("ticket-list-columns");let n=Rt(),s=v(r("div",{className:"columns-container"}));for(let i of n){let l=a.tickets.filter(d=>d.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"})]})),u=c.querySelector(".column-body");for(let d of l)u.appendChild(Pn(d));s.appendChild(c)}e.appendChild(s),Ut(e,t);let o=document.getElementById("batch-toolbar");o&&(o.style.display="none"),Ce()}function Pn(e){let t=a.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:${S(e.category)}`,children:z(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",()=>{a.selectedIds.clear(),a.selectedIds.add(e.id),a.lastClickedId=e.id,Ot(),ie()}),n}function Rn(){let e=document.getElementById("ticket-list"),t=qt(e);e.innerHTML="",e.classList.add("ticket-list-columns"),e.appendChild(Vt());let n=Rt(),s=v(r("div",{className:"columns-container"}));for(let o of n){let i=a.tickets.filter(u=>u.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 u of i)c.appendChild(qn(u));c.addEventListener("dragover",u=>{u.preventDefault(),u.dataTransfer.dropEffect="move",l.classList.add("column-drop-target")}),c.addEventListener("dragleave",u=>{let d=u.relatedTarget;(!d||!c.contains(d))&&l.classList.remove("column-drop-target")}),c.addEventListener("drop",u=>{u.preventDefault(),l.classList.remove("column-drop-target");let d=U;if(U=[],d.length===0)return;let p=a.tickets.filter(m=>d.includes(m.id));H(),C(p,{ids:d,action:"status",value:o.status},"Change status").then(()=>{w()})}),s.appendChild(l)}e.appendChild(s),Ut(e,t),de(),Ce()}function qn(e){let t=a.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:${S(e.category)}`,children:z(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})]})),s=n.querySelector(".ticket-category-badge");s.addEventListener("click",i=>{i.stopPropagation(),Wt(s,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(),Ft(e)}),n.addEventListener("contextmenu",i=>{Ye(i,e)}),n.draggable=!0,n.addEventListener("dragstart",i=>{a.selectedIds.has(e.id)&&a.selectedIds.size>1?U=Array.from(a.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)a.selectedIds.has(e.id)?a.selectedIds.delete(e.id):a.selectedIds.add(e.id),a.lastClickedId=e.id;else if(i.shiftKey&&a.lastClickedId!=null){let l=a.tickets.find(c=>c.id===a.lastClickedId);if(l&&l.status===e.status){let u=a.tickets.filter(m=>m.status===e.status).map(m=>m.id),d=u.indexOf(a.lastClickedId),p=u.indexOf(e.id);if(d!==-1&&p!==-1){let m=Math.min(d,p),g=Math.max(d,p);a.selectedIds.clear();for(let y=m;y<=g;y++)a.selectedIds.add(u[y])}}else a.selectedIds.clear(),a.selectedIds.add(e.id),a.lastClickedId=e.id}else a.selectedIds.clear(),a.selectedIds.add(e.id),a.lastClickedId=e.id;Ot(),de()}),n}function Ot(){document.querySelectorAll(".column-card[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10);a.selectedIds.has(t)?e.classList.add("selected"):e.classList.remove("selected")})}function Vt(){let e=Kt(),t=a.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:${S(e)}${t?"":";cursor:pointer;opacity:1"}`,children:z(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(),On(o)})}let s=n.querySelector(".draft-input");return s.addEventListener("input",()=>{Xe=s.value}),s.addEventListener("keydown",async o=>{if(o.key==="Enter"&&s.value.trim()){o.preventDefault();let i=s.value.trim();Xe="",s.value="";let l=Un();ke&&!a.view.startsWith("category:")&&(l.category=ke);let c=await f("/tickets",{method:"POST",body:{title:i,defaults:l}});c&&(a.selectedIds.clear(),a.selectedIds.add(c.id)),await w(),j()}else o.key==="ArrowDown"&&(o.preventDefault(),a.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${a.tickets[0].id}"] .ticket-title-input`)?.focus())}),n}function j(){document.querySelector(".draft-row .draft-input")?.focus()}function Un(){let e=a.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 Kt(){if(ke)return ke;let e=a.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function On(e){_();let n=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",s=Kt(),o=B(e,$e().map(i=>({label:i.label,key:i.key,shortcut:`${n}${i.key.toUpperCase()}`,color:S(i.value),active:s===i.value,action:()=>{ke=i.value,L(),j()}})));document.body.appendChild(o),N(o,e),o.style.visibility=""}function Vn(e){let t=a.selectedIds.has(e.id),n=e.status==="completed"||e.status==="verified",s=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:${S(e.category)}`,title:e.category,children:z(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("button",{className:`ticket-status-btn${s?" verified":""}`,title:e.status.replace("_"," "),children:D(s?Ue:F(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",d=>{let p=d.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",d=>{Ye(d,e)}),o.addEventListener("dragstart",d=>{a.selectedIds.has(e.id)&&a.selectedIds.size>1?U=Array.from(a.selectedIds):U=[e.id],d.dataTransfer.setData("text/plain",JSON.stringify(U)),d.dataTransfer.effectAllowed="move"}),o.addEventListener("mousedown",d=>{(d.metaKey||d.ctrlKey||d.shiftKey)&&(d.preventDefault(),zt(d,e)&&d.stopPropagation())});let i=o.querySelector(".ticket-checkbox");i.addEventListener("click",d=>d.stopPropagation()),i.addEventListener("change",()=>{i.checked?a.selectedIds.add(e.id):a.selectedIds.delete(e.id),a.lastClickedId=e.id,L()}),o.querySelector(".ticket-status-btn").addEventListener("click",d=>{d.stopPropagation(),jn(e)});let l=o.querySelector(".ticket-category-badge");l.addEventListener("click",d=>{d.stopPropagation(),Wt(l,e)});let c=o.querySelector(".ticket-title-input");c.addEventListener("focus",()=>{be||a.selectedIds.size===1&&a.selectedIds.has(e.id)||(a.selectedIds.clear(),a.selectedIds.add(e.id),a.lastClickedId=e.id,we(),de())}),c.addEventListener("input",()=>{Se(e,"title",c.value),Yn(e.id,{title:c.value})}),c.addEventListener("keydown",d=>{zn(d,e,c)});let u=o.querySelector(".ticket-priority-indicator");return u.addEventListener("click",d=>{d.stopPropagation(),jt(u,e)}),o.querySelector(".ticket-star").addEventListener("click",d=>{d.stopPropagation(),Ft(e)}),o}function Kn(e){let t=a.selectedIds.has(e.id),n=e.deleted_at?new Date(e.deleted_at):null,s=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:${S(e.category)}`,children:z(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"})]}));s.addEventListener("mousedown",i=>{(i.metaKey||i.ctrlKey||i.shiftKey)&&(i.preventDefault(),zt(i,e)&&i.stopPropagation())});let o=s.querySelector(".ticket-checkbox");return o.addEventListener("click",i=>i.stopPropagation()),o.addEventListener("change",()=>{o.checked?a.selectedIds.add(e.id):a.selectedIds.delete(e.id),a.lastClickedId=e.id,L()}),s.querySelector(".trash-title").addEventListener("click",()=>{a.selectedIds.size===1&&a.selectedIds.has(e.id)||(a.selectedIds.clear(),a.selectedIds.add(e.id),a.lastClickedId=e.id,we(),de())}),s.querySelector(".btn").addEventListener("click",async i=>{i.stopPropagation(),await $t(e),w()}),s}function zt(e,t){let n=e.metaKey||e.ctrlKey,s=e.shiftKey;if(n)a.selectedIds.has(t.id)?a.selectedIds.delete(t.id):a.selectedIds.add(t.id),a.lastClickedId=t.id,L();else if(s&&a.lastClickedId!=null){let o=a.tickets.map(c=>c.id),i=o.indexOf(a.lastClickedId),l=o.indexOf(t.id);if(i!==-1&&l!==-1){let c=Math.min(i,l),u=Math.max(i,l);a.selectedIds.clear();for(let d=c;d<=u;d++)a.selectedIds.add(o[d])}L()}else return!1;return!0}function zn(e,t,n){if(e.key==="Enter")e.preventDefault(),j();else if(e.key==="Backspace"&&n.value==="")e.preventDefault(),Jn(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),At(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),At(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),Fn(t.id);else if(e.key==="ArrowUp")e.preventDefault(),Wn(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&$e().some(s=>s.key===e.key)){e.preventDefault();let s=$e().find(o=>o.key===e.key);Pt(t,"category",s.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&Ge.some(s=>s.key===e.key)){e.preventDefault();let s=Ge.find(o=>o.key===e.key);Pt(t,"priority",s.value)}}function Fn(e){let t=a.tickets.findIndex(n=>n.id===e);t<a.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${a.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function Wn(e){let t=a.tickets.findIndex(n=>n.id===e);t>0?document.querySelector(`.ticket-row[data-id="${a.tickets[t-1].id}"] .ticket-title-input`)?.focus():j()}function At(e,t){let s=a.tickets.findIndex(l=>l.id===e)+t;if(s<0||s>=a.tickets.length)return;let o=a.tickets[s].id;a.selectedIds.add(e),a.selectedIds.has(o)?a.selectedIds.delete(e):a.selectedIds.add(o),be=!0,document.querySelector(`.ticket-row[data-id="${o}"] .ticket-title-input`)?.focus(),be=!1,we(),de()}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",s=await R(e,{status:n},"Change status");Object.assign(e,s),L()}async function Ft(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 Pt(e,t,n){let s=await R(e,{[t]:n},`Change ${t}`);Object.assign(e,s),L()}async function Jn(e){let t=a.tickets.findIndex(s=>s.id===e),n=a.tickets.find(s=>s.id===e);if(n?await Me(n):await f(`/tickets/${e}`,{method:"DELETE"}),a.tickets=a.tickets.filter(s=>s.id!==e),a.selectedIds.delete(e),L(),t>0&&a.tickets.length>0){let s=Math.min(t-1,a.tickets.length-1);document.querySelector(`.ticket-row[data-id="${a.tickets[s].id}"] .ticket-title-input`)?.focus()}else j()}function Yn(e,t){ce&&clearTimeout(ce),ce=setTimeout(()=>{f(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function Wt(e,t){_();let s=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",o=B(e,$e().map(i=>({label:i.label,key:i.key,shortcut:`${s}${i.key.toUpperCase()}`,color:S(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),N(o,e),o.style.visibility=""}function jt(e,t){_();let n=B(e,Ge.map(s=>({label:s.label,key:s.key,shortcut:`Alt+${s.key}`,icon:A(s.value),iconColor:P(s.value),active:t.priority===s.value,action:async()=>{let o=await R(t,{priority:s.value},"Change priority");Object.assign(t,o),L()}})));document.body.appendChild(n),N(n,e),n.style.visibility=""}function we(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),n=e.querySelector(".ticket-checkbox");a.selectedIds.has(t)?(e.classList.add("selected"),n&&(n.checked=!0)):(e.classList.remove("selected"),n&&(n.checked=!1))})}function de(){let e=a.selectedIds.size,t=a.tickets.length,n=e>0,s=a.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=s?"none":"",s||(m.disabled=!n)}let l=document.getElementById("batch-restore"),c=document.getElementById("batch-empty-trash");if(s){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(a.selectedIds),action:"restore"}}),a.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"}),a.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 u=document.querySelector(".batch-star-icon"),d=document.getElementById("batch-upnext");if(!s&&u&&n){let p=a.tickets.filter(y=>a.selectedIds.has(y.id)),m=p.every(y=>y.up_next),g=p.every(y=>!y.up_next);m?(u.textContent="\u2605",d.classList.add("active"),d.classList.remove("mixed")):g?(u.textContent="\u2606",d.classList.remove("active","mixed")):(u.innerHTML=r("span",{className:"star-mixed-wrap",children:[r("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),d.classList.remove("active"),d.classList.add("mixed"))}else u&&(u.textContent="\u2606",d.classList.remove("active","mixed"));ie()}async function w(){if(a.backupPreview?.active){Xn();return}if(a.view.startsWith("custom:")){let n=a.view.slice(7),s=a.customViews.find(o=>o.id===n);s?a.tickets=await f("/tickets/query",{method:"POST",body:{logic:s.logic,conditions:s.conditions,sort_by:a.sortBy,sort_dir:a.sortDir}}):a.tickets=[],L();return}let e=new URLSearchParams;a.view==="trash"?e.set("status","deleted"):a.view==="up-next"?e.set("up_next","true"):a.view==="open"?e.set("status","open"):a.view==="completed"?e.set("status","completed"):a.view==="non-verified"?e.set("status","non_verified"):a.view==="verified"?e.set("status","verified"):a.view==="backlog"?e.set("status","backlog"):a.view==="archive"?e.set("status","archive"):a.view.startsWith("category:")?e.set("category",a.view.split(":")[1]):a.view.startsWith("priority:")?e.set("priority",a.view.split(":")[1]):e.set("status","active"),a.search&&e.set("search",a.search),e.set("sort_by",a.sortBy),e.set("sort_dir",a.sortDir);let t=e.toString();a.tickets=await f(`/tickets${t?"?"+t:""}`),L()}function Xn(){let e=[...a.backupPreview?.tickets||[]];if(a.view==="trash")e=e.filter(t=>t.status==="deleted");else if(a.view==="up-next")e=e.filter(t=>t.up_next&&t.status!=="deleted");else if(a.view==="open")e=e.filter(t=>t.status==="not_started"||t.status==="started");else if(a.view==="completed")e=e.filter(t=>t.status==="completed");else if(a.view==="non-verified")e=e.filter(t=>t.status!=="verified"&&t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");else if(a.view==="verified")e=e.filter(t=>t.status==="verified");else if(a.view==="backlog")e=e.filter(t=>t.status==="backlog");else if(a.view==="archive")e=e.filter(t=>t.status==="archive");else if(a.view.startsWith("category:")){let t=a.view.split(":")[1];e=e.filter(n=>n.category===t&&n.status!=="deleted"&&n.status!=="backlog"&&n.status!=="archive")}else if(a.view.startsWith("priority:")){let t=a.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(a.search){let t=a.search.toLowerCase();e=e.filter(n=>n.title.toLowerCase().includes(t)||n.ticket_number.toLowerCase().includes(t)||n.details&&n.details.toLowerCase().includes(t))}a.tickets=e,L()}function Gn(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 s=Math.floor(n/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}function Zn(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function Qn(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 s={};for(let o of n.backups)(s[t=o.tier]||(s[t]=[])).push(o);e.innerHTML="";for(let o of["5min","hourly","daily"]){let i=s[o];if(!(!i||i.length===0)){e.appendChild(v(r("div",{className:"backup-tier-label",children:Qn(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:Gn(l.createdAt)}),r("span",{className:"backup-row-meta",children:[new Date(l.createdAt).toLocaleString()," \xB7 ",Zn(l.sizeBytes)]})]}));c.addEventListener("click",()=>{ea(l.tier,l.filename,l.createdAt)}),e.appendChild(c)}}}}catch{e.textContent="Failed to load backups."}}async function ea(e,t,n){let s=document.getElementById("settings-overlay");s.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}`);a.backupPreview={active:!0,tickets:l.tickets,timestamp:n,tier:e,filename:t},a.selectedIds.clear(),a.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 ta(){let e=document.getElementById("backup-preview-banner");e.style.display="none",a.backupPreview=null,a.selectedIds.clear(),a.activeTicketId=null,await f("/backups/preview/cleanup",{method:"POST"}),w()}async function na(){if(!a.backupPreview)return;let e=document.getElementById("backup-restore-btn");e.textContent="Restoring...",e.disabled=!0;try{await f("/backups/restore",{method:"POST",body:{tier:a.backupPreview.tier,filename:a.backupPreview.filename}}),window.location.reload()}catch{e.textContent="Restore failed",e.disabled=!1,setTimeout(()=>{e.textContent="Restore This Backup"},3e3)}}function Jt(){document.getElementById("backup-cancel-btn")?.addEventListener("click",()=>{ta()}),document.getElementById("backup-restore-btn")?.addEventListener("click",()=>{na()});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 _e,ne=null;function Gt(e){_e=e,document.getElementById("add-custom-view-btn").addEventListener("click",t=>{t.stopPropagation(),nt()})}async function Zt(){try{let e=await f("/settings");if(e.custom_views){let t=JSON.parse(e.custom_views);Array.isArray(t)&&(a.customViews=t)}}catch{}et()}function et(){let e=document.getElementById("custom-views-container");if(e&&(e.innerHTML="",a.customViews.length!==0)){e.appendChild(v(r("div",{className:"sidebar-divider"})));for(let t=0;t<a.customViews.length;t++){let n=a.customViews[t],s=v(r("button",{className:`sidebar-item sidebar-custom-view${a.view===`custom:${n.id}`?" active":""}`,"data-view":`custom:${n.id}`,"data-cv-index":String(t),draggable:"true",children:n.name}));s.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active")),s.classList.add("active"),a.view=`custom:${n.id}`,a.selectedIds.clear(),H(),_e()}),s.addEventListener("dblclick",o=>{o.preventDefault(),nt(n)}),s.addEventListener("contextmenu",o=>{o.preventDefault(),oa(s,n)}),s.addEventListener("dragstart",o=>{ne=t,o.dataTransfer.setData("text/plain",String(t)),o.dataTransfer.effectAllowed="move",setTimeout(()=>s.classList.add("dragging"),0)}),s.addEventListener("dragend",()=>{s.classList.remove("dragging"),ne=null}),s.addEventListener("dragover",o=>{ne!==null&&(o.preventDefault(),o.dataTransfer.dropEffect="move",s.classList.add("drop-target"))}),s.addEventListener("dragleave",()=>{s.classList.remove("drop-target")}),s.addEventListener("drop",o=>{if(o.preventDefault(),s.classList.remove("drop-target"),ne===null||ne===t)return;let[i]=a.customViews.splice(ne,1);a.customViews.splice(t,0,i),ne=null,tt()}),e.appendChild(s)}}}var aa='<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>',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="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 oa(e,t){_();let n=B(e,[{label:"Edit",key:"e",icon:aa,action:()=>nt(t)},{label:"Delete",key:"d",icon:sa,action:()=>ia(t.id)}]);document.body.appendChild(n),N(n,e),n.style.visibility=""}async function tt(){await f("/settings",{method:"PATCH",body:{custom_views:JSON.stringify(a.customViews)}}),et()}async function ia(e){a.customViews=a.customViews.filter(t=>t.id!==e),a.view===`custom:${e}`&&(a.view="all",document.querySelectorAll(".sidebar-item").forEach(t=>{t.classList.toggle("active",t.dataset.view==="all")}),_e()),await tt()}var Be=[{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 Yt(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 ra=["highest","high","default","low","lowest"],la=["not_started","started","completed","verified","backlog","archive"];function Xt(e){return e==="category"?a.categories.map(t=>t.id):e==="priority"?ra:e==="status"?la:e==="up_next"?["true","false"]:null}function ca(e,t){return e==="category"?a.categories.find(s=>s.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(u=>({...u})):[],s=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:s==="all"})," All of"]}),r("label",{children:[r("input",{type:"radio",name:"cv-logic",value:"any",checked:s==="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 u=i.querySelector("#cv-conditions");u.innerHTML="",n.forEach((d,p)=>{let m=Be.find(T=>T.value===d.field)||Be[0],g=Yt(m.type),y=Xt(d.field),b=v(r("div",{className:"cv-condition-row",children:[r("select",{className:"cv-field-select",children:Be.map(T=>r("option",{value:T.value,selected:T.value===d.field,children:T.label}))}),r("select",{className:"cv-op-select",children:g.map(T=>r("option",{value:T.value,selected:T.value===d.operator,children:T.label}))}),y?r("select",{className:"cv-value-select",children:y.map(T=>r("option",{value:T,selected:T===d.value,children:ca(d.field,T)}))}):r("input",{type:"text",className:"cv-value-input",value:d.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"),I=b.querySelector(".cv-value-select")||b.querySelector(".cv-value-input");E.addEventListener("change",()=>{let T=E.value,J=Be.find(G=>G.value===T),Y=Yt(J.type);n[p].field=T,n[p].operator=Y[0].value;let V=Xt(T);n[p].value=V?V[0]:"",l()}),x.addEventListener("change",()=>{n[p].operator=x.value}),I.addEventListener("change",()=>{n[p].value=I.value}),I.tagName==="INPUT"&&I.addEventListener("input",()=>{n[p].value=I.value}),b.querySelector(".category-delete-btn").addEventListener("click",()=>{n.splice(p,1),l()}),u.appendChild(b)})}l(),document.body.appendChild(i),i.querySelector("#cv-name").focus(),i.querySelectorAll('input[name="cv-logic"]').forEach(u=>{u.addEventListener("change",()=>{s=u.value})}),i.querySelector("#cv-add-condition").addEventListener("click",()=>{n.push({field:"category",operator:"equals",value:a.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",u=>{u.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 u={id:e?.id||o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||`view-${Date.now()}`,name:o,logic:s,conditions:n.filter(d=>d.value!=="")};if(t){let d=a.customViews.findIndex(p=>p.id===e.id);d>=0?a.customViews[d]=u:a.customViews.push(u)}else a.customViews.push(u);await tt(),document.querySelectorAll(".sidebar-item").forEach(d=>d.classList.remove("active")),a.view=`custom:${u.id}`,a.selectedIds.clear(),et(),_e(),c()})}var ue=30;async function st(e){e.innerHTML='<div class="dashboard-loading">Loading dashboard...</div>';try{let t=await f(`/dashboard?days=${ue}`);e.innerHTML="",e.appendChild(da(t))}catch{e.innerHTML='<div class="dashboard-loading">Failed to load dashboard data.</div>'}}function da(e){let t=v(r("div",{className:"dashboard"})),n=v(r("div",{className:"dashboard-range-bar",children:[r("button",{className:`btn btn-sm${ue===7?" active":""}`,"data-days":"7",children:"7 days"}),r("button",{className:`btn btn-sm${ue===30?" active":""}`,"data-days":"30",children:"30 days"}),r("button",{className:`btn btn-sm${ue===90?" active":""}`,"data-days":"90",children:"90 days"})]}));n.querySelectorAll("button").forEach(m=>{m.addEventListener("click",()=>{ue=parseInt(m.dataset.days,10);let g=document.getElementById("dashboard-container");g&&st(g)})}),t.appendChild(n);let s=e.kpi,o=s.completedLastWeek>0?Math.round((s.completedThisWeek-s.completedLastWeek)/s.completedLastWeek*100):0,i=o>0?"\u2191":o<0?"\u2193":"",l=s.createdThisWeek>0?(s.completedThisWeek/s.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(s.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:s.medianCycleTimeDays!==null?`${s.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(s.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"})),u=Ee("Throughput","Items completed per day. Shows your sustainable delivery pace.",ua(e.throughput));at(u,e.throughput.map(m=>({date:m.date,lines:[{label:"Completed",color:"#3b82f6",value:m.completed}]}))),c.appendChild(u);let d=Ee("Created vs Completed","Compares items created (orange) vs completed (green) over time. When created outpaces completed, the backlog grows.",pa(e.throughput));at(d,e.throughput.map(m=>({date:m.date,lines:[{label:"Completed",color:"#22c55e",value:m.completed},{label:"Created",color:"#f97316",value:m.created}]}))),c.appendChild(d);let p=Ee("Cumulative Flow","Stacked area showing ticket counts by status over time. Widening bands indicate bottlenecks. A healthy flow has consistent band widths.",ma(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(Ee("Category Breakdown","Distribution of tickets by category. Left: currently open. Right: all tickets active in the selected time period.",ga(e.categoryBreakdown,e.categoryPeriod))),c.appendChild(Ee("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.",fa(e.cycleTime))),t.appendChild(c),t}function Ee(e,t,n){let s=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=s.querySelector(".dashboard-info-btn"),i=s.querySelector(".dashboard-chart-info");return o.addEventListener("click",l=>{l.stopPropagation(),i.style.display=i.style.display==="none"?"":"none"}),s}function at(e,t){let n=e.querySelector(".dashboard-chart-body");if(!n||t.length===0)return;let s=document.createElement("div");s.className="chart-cursor",s.style.display="none",n.style.position="relative",n.appendChild(s);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(),u=n.getBoundingClientRect(),d=c.left-u.left,p=c.top-u.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 I=h.left+x/Math.max(t.length-1,1)*b,T=d+I/m,J=p+h.top/g,Y=(O-h.top-h.bottom)/g;s.style.display="",s.style.left=`${T}px`,s.style.top=`${J}px`,s.style.height=`${Y}px`;let V=t[x];o.style.display="",o.innerHTML=`<div class="chart-tooltip-date">${ot(V.date)}</div>${V.lines.map(ae=>`<div class="chart-tooltip-row"><span class="chart-legend-dot" style="background:${ae.color}"></span>${ae.label}: <b>${ae.value}</b></div>`).join("")}`;let G=T+10;G+120>u.width?o.style.left=`${T-120}px`:o.style.left=`${G}px`,o.style.top=`${l.clientY-u.top-10}px`}),i.addEventListener("mouseleave",()=>{s.style.display="none",o.style.display="none"}))}var q=400,O=180,h={top:10,right:10,bottom:25,left:35};function ua(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),s=q-h.left-h.right,o=O-h.top-h.bottom,i=Math.max(2,s/e.length-2),l="";for(let c=0;c<e.length;c++){let u=h.left+c/e.length*s,d=t[c]/n*o,p=h.top+o-d,m=ot(e[c].date);l+=`<rect x="${u}" y="${p}" width="${i}" height="${d}" 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
+ ${l}
4
+ ${He(e.map(c=>c.date))}
5
+ </svg>`}function pa(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,s=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,s)}
7
+ <path d="${en(e.map(l=>l.created),t,n,s)}" fill="none" stroke="#f97316" stroke-width="2" opacity="0.7"/>
8
+ <path d="${en(e.map(l=>l.completed),t,n,s)}" fill="none" stroke="#22c55e" stroke-width="2"/>
9
+ ${He(e.map(l=>l.date))}
10
+ </svg>`;return o+i}function ma(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"},s={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>${s[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,u=O-h.top-h.bottom,d=e.length,p="";for(let g=t.length-1;g>=0;g--){let y=i.map((E,x)=>{let I=h.left+x/(d-1)*c,T=h.top+u-E[g]/l*u;return`${I},${T}`}),b=g>0?i.map((E,x)=>{let I=h.left+x/(d-1)*c,T=h.top+u-E[g-1]/l*u;return`${I},${T}`}).reverse():[`${h.left+c},${h.top+u}`,`${h.left},${h.top+u}`];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
+ ${p}
12
+ ${He(e.map(g=>g.date))}
13
+ </svg>`;return o+m}function ga(e,t){let n=new Map;for(let c of[...e,...t])if(!n.has(c.category)){let u=a.categories.find(d=>d.id===c.category);n.set(c.category,{color:S(c.category),label:u?.label||c.category})}let s=`<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=Qt(e,"Open",90),i=Qt(t,`${ue}d active`,290),l=`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">${o}${i}</svg>`;return s+l}function Qt(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 s=e.reduce((d,p)=>d+p.count,0),o=95,i=60,l=38,c=-Math.PI/2,u="";for(let d of e){let p=d.count/s*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),I=n+l*Math.cos(c),T=o+l*Math.sin(c),J=p>Math.PI?1:0,Y=S(d.category),G=a.categories.find(ae=>ae.id===d.category)?.label||d.category;u+=`<path d="M ${m} ${g} A ${i} ${i} 0 ${J} 1 ${y} ${b} L ${E} ${x} A ${l} ${l} 0 ${J} 0 ${I} ${T} Z" fill="${Y}" opacity="0.8" class="chart-hover"><title>${G}: ${d.count}</title></path>`,c+=p}return u+=`<text x="${n}" y="${o+4}" text-anchor="middle" fill="currentColor" font-size="16" font-weight="600">${s}</text>`,u+=`<text x="${n}" y="${o+17}" text-anchor="middle" fill="#6b7280" font-size="9">${t}</text>`,u}function fa(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,s=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,u="";for(let E of e){let x=h.left+(new Date(E.completed_at).getTime()-i)/c*n,I=h.top+s-E.days/t*s;u+=`<circle cx="${x}" cy="${I}" r="4" fill="#3b82f6" opacity="0.5" class="chart-hover"><title>${E.ticket_number}: ${E.title}
14
+ ${E.days} days</title></circle>`}let d=e.map(E=>E.days).sort((E,x)=>E-x),p=d[Math.floor(d.length*.5)],m=d[Math.floor(d.length*.85)],g=h.top+s-p/t*s,y=h.top+s-m/t*s,b=`
15
+ <line x1="${h.left}" y1="${g}" x2="${h.left+n}" y2="${g}" stroke="#22c55e" stroke-dasharray="4,4" opacity="0.6"/>
16
+ <text x="${h.left+n+2}" y="${g+3}" fill="#22c55e" font-size="9">50% (${p}d)</text>
17
+ <line x1="${h.left}" y1="${y}" x2="${h.left+n}" y2="${y}" stroke="#f97316" stroke-dasharray="4,4" opacity="0.6"/>
18
+ <text x="${h.left+n+2}" y="${y+3}" fill="#f97316" font-size="9">85% (${m}d)</text>
19
+ `;return`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
20
+ ${it(t,s,"d")}
21
+ ${u}
22
+ ${b}
23
+ ${He(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 en(e,t,n,s){return e.map((o,i)=>{let l=h.left+i/(e.length-1)*n,c=h.top+s-o/t*s;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 He(e){if(e.length===0)return"";let t=O,n=q-h.left-h.right,s="",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;s+=`<text x="${l}" y="${t-4}" text-anchor="middle" fill="#9ca3af" font-size="9">${ot(e[i])}</text>`}return s}async function tn(){let e=v(r("div",{className:"sidebar-dashboard-widget",id:"sidebar-dashboard-widget"}));try{let t=await f("/dashboard?days=7"),n=t.kpi,s=n.completedLastWeek>0?Math.round((n.completedThisWeek-n.completedLastWeek)/n.completedLastWeek*100):0,o=s>0?"\u2191":s<0?"\u2193":"",i=t.throughput.slice(-7),l=Math.max(...i.map(u=>u.completed),1),c=i.map((u,d)=>{let p=u.completed/l*20;return`<rect x="${d*14}" y="${20-p}" width="10" height="${p}" fill="#3b82f6" rx="1" opacity="0.7"/>`}).join("");e.innerHTML=`
25
+ <div class="sidebar-widget-spark"><svg viewBox="0 0 98 20" width="98" height="20">${c}</svg></div>
26
+ <div class="sidebar-widget-stats">
27
+ <span class="sidebar-widget-value">${n.completedThisWeek} completed</span>
28
+ ${o?`<span class="sidebar-widget-trend ${s>0?"up":"down"}">${o}${Math.abs(s)}%</span>`:""}
29
+ </div>
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 rt(){let e=a.view==="dashboard",t=a.selectedIds.size>0,n=a.activeTicketId!=null,s=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(a.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=s.querySelector("#print-scope"),i=s.querySelector("#print-format-field"),l=()=>{i.style.display=o.value==="dashboard"?"none":""};o.addEventListener("change",l),l();let c=()=>s.remove();s.querySelector("#print-close").addEventListener("click",c),s.querySelector("#print-cancel").addEventListener("click",c),s.addEventListener("click",u=>{u.target===s&&c()}),s.querySelector("#print-go").addEventListener("click",()=>{let u=o.value,d=s.querySelector("#print-format").value;if(c(),u==="dashboard")va();else{let p=ya(u);ha(p,d)}}),document.body.appendChild(s)}function ya(e){if(e==="selected")return a.tickets.filter(t=>a.selectedIds.has(t.id));if(e==="current"&&a.activeTicketId!=null){let t=a.tickets.find(n=>n.id===a.activeTicketId);return t?[t]:[]}return a.tickets}function nn(e){let t=`<!DOCTYPE html><html><head>
32
+ <meta charset="utf-8">
33
+ <title>Hot Sheet</title>
34
+ <style>${lt()}</style>
35
+ </head><body>${e}</body></html>`;f("/print",{method:"POST",body:{html:t}})}function va(){let e=document.getElementById("dashboard-container");e&&nn(`<style>${lt()}
36
+ .dashboard-grid { grid-template-columns: 1fr 1fr; }
37
+ .dashboard-kpi-row { grid-template-columns: repeat(4, 1fr); }
38
+ .dashboard-chart-body svg { max-width: 100%; }
39
+ .chart-cursor, .chart-tooltip, .dashboard-info-btn, .dashboard-range-bar, .dashboard-chart-info { display: none !important; }
40
+ </style>${e.innerHTML}`)}function ha(e,t){let n="";t==="checklist"?n=`<h2>Checklist</h2><div class="print-checklist">${e.map(s=>`<div class="print-check-item"><span class="print-checkbox">\u25A1</span><span>${M(s.ticket_number)}: ${M(s.title)}</span></div>`).join("")}</div>`:t==="summary"?n=`<h2>Ticket Summary</h2><table class="print-table">
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
+ <tbody>${e.map(s=>{let o=a.categories.find(i=>i.id===s.category);return`<tr>
43
+ <td>${M(s.ticket_number)}</td>
44
+ <td>${M(s.title)}</td>
45
+ <td><span class="print-cat" style="background:${S(s.category)}">${M(z(s.category))}</span> ${M(o?.label||s.category)}</td>
46
+ <td>${M(s.priority)}</td>
47
+ <td>${M(s.status.replace(/_/g," "))}</td>
48
+ <td>${s.up_next?"\u2605":""}</td>
49
+ </tr>`}).join("")}</tbody>
50
+ </table>`:n=e.map(s=>{let o=a.categories.find(c=>c.id===s.category),i=K(s.tags),l=[];try{l=JSON.parse(s.notes)}catch{}return Array.isArray(l)||(l=[]),`<div class="print-ticket">
51
+ <div class="print-ticket-header">
52
+ <span class="print-cat" style="background:${S(s.category)}">${M(z(s.category))}</span>
53
+ <strong>${M(s.ticket_number)}</strong>: ${M(s.title)}
54
+ ${s.up_next?'<span class="print-star">\u2605</span>':""}
55
+ </div>
56
+ <div class="print-ticket-meta">
57
+ ${M(o?.label||s.category)} \xB7 ${M(s.priority)} \xB7 ${M(s.status.replace(/_/g," "))}
58
+ ${i.length>0?" \xB7 "+i.map(c=>`<span class="print-tag">${M(c)}</span>`).join(" "):""}
59
+ </div>
60
+ ${s.details.trim()?`<div class="print-ticket-details">${M(s.details)}</div>`:""}
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>`:""}${M(c.text)}</div>`).join("")}</div>`:""}
62
+ </div>`}).join(""),nn(`<style>${lt()}</style>${n}`)}function M(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function lt(){return`
63
+ * { box-sizing: border-box; margin: 0; padding: 0; }
64
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 12px; color: #111; padding: 20px; }
65
+ h2 { font-size: 16px; margin-bottom: 12px; }
66
+ .print-checklist { display: flex; flex-direction: column; gap: 6px; }
67
+ .print-check-item { display: flex; align-items: center; gap: 8px; font-size: 13px; }
68
+ .print-checkbox { font-size: 16px; color: #999; }
69
+ .print-table { width: 100%; border-collapse: collapse; font-size: 12px; }
70
+ .print-table th, .print-table td { padding: 6px 8px; border: 1px solid #ddd; text-align: left; }
71
+ .print-table th { background: #f5f5f5; font-weight: 600; }
72
+ .print-cat { display: inline-block; padding: 1px 5px; border-radius: 3px; font-size: 9px; font-weight: 600; color: white; text-transform: uppercase; vertical-align: middle; }
73
+ .print-star { color: #eab308; }
74
+ .print-tag { display: inline-block; padding: 1px 6px; background: #f0f0f0; border-radius: 10px; font-size: 10px; }
75
+ .print-ticket { margin-bottom: 16px; padding-bottom: 16px; border-bottom: 1px solid #eee; }
76
+ .print-ticket-header { font-size: 14px; margin-bottom: 4px; }
77
+ .print-ticket-meta { font-size: 11px; color: #666; margin-bottom: 6px; }
78
+ .print-ticket-details { white-space: pre-wrap; font-size: 12px; margin-bottom: 6px; background: #fafafa; padding: 8px; border-radius: 4px; }
79
+ .print-ticket-notes { font-size: 11px; }
80
+ .print-note { margin-top: 4px; padding: 4px 8px; background: #f5f5f5; border-left: 3px solid #3b82f6; border-radius: 3px; }
81
+ .print-note-time { color: #999; font-size: 10px; display: block; margin-bottom: 2px; }
82
+ .dashboard-kpi-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 16px; }
83
+ .dashboard-kpi-card { padding: 12px; border: 1px solid #ddd; border-radius: 6px; text-align: center; }
84
+ .kpi-value { font-size: 24px; font-weight: 700; }
85
+ .kpi-label { font-size: 11px; color: #666; }
86
+ .kpi-trend { font-size: 11px; }
87
+ .kpi-trend.up { color: #22c55e; }
88
+ .kpi-trend.down { color: #ef4444; }
89
+ .dashboard-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
90
+ .dashboard-chart-card { border: 1px solid #ddd; border-radius: 6px; overflow: hidden; }
91
+ .dashboard-chart-header { padding: 8px 12px; border-bottom: 1px solid #ddd; font-size: 12px; font-weight: 600; }
92
+ .dashboard-chart-body { padding: 8px; }
93
+ .chart-legend { display: flex; flex-wrap: wrap; gap: 6px 12px; padding-bottom: 6px; font-size: 10px; }
94
+ .chart-legend-item { display: inline-flex; align-items: center; gap: 4px; }
95
+ .chart-legend-dot { width: 8px; height: 8px; border-radius: 50%; }
96
+ @media print { body { padding: 0; } }
97
+ `}async function ba(){try{await ka(),await wa(),await Zt(),Ea(),H(),await w(),Ba(),Ma(),$a(),_a(),Ha(),Ra(),qa(),Va(),Ta(),Jt(),Ca(),Sa(),Gt(()=>{w()}),Mt(),Ka(),La(),document.addEventListener("hotsheet:render",()=>L()),document.addEventListener("hotsheet:show-tags-dialog",()=>{vn()}),document.addEventListener("hotsheet:upnext-changed",()=>yt()),document.getElementById("print-btn")?.addEventListener("click",rt),mn(),Pa(),j()}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 ka(){try{let e=await f("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(a.settings.detail_position=e.detail_position),e.detail_width&&(a.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(a.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(a.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(a.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30),(e.layout==="list"||e.layout==="columns")&&(a.layout=e.layout)}catch{}Ke(a.settings.detail_position),ze()}async function wa(){try{let e=await f("/categories");e.length>0&&(a.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 a.categories){let s=v(r("button",{className:`sidebar-item${a.view===`category:${n.id}`?" active":""}`,"data-view":`category:${n.id}`,children:[r("span",{className:"cat-dot",style:`background:${n.color}`})," ",n.label]}));s.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active")),s.classList.add("active"),a.view=`category:${n.id}`,a.selectedIds.clear(),vt(),H(),w()}),e.appendChild(s)}}if(a.activeTicketId!=null){let t=a.tickets.find(n=>n.id===a.activeTicketId);t&&ve(t.category)}}async function Ea(){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 Ta(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close"),n=document.getElementById("settings-btn"),s=document.querySelectorAll(".settings-tab"),o=document.querySelectorAll(".settings-tab-panel");s.forEach(k=>{k.addEventListener("click",()=>{let Z=k.dataset.tab;s.forEach(se=>se.classList.remove("active")),o.forEach(se=>se.classList.remove("active")),k.classList.add("active"),document.querySelector(`.settings-tab-panel[data-panel="${Z}"]`)?.classList.add("active")})}),n.addEventListener("click",()=>{document.getElementById("settings-trash-days").value=String(a.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(a.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),a.settings.trash_cleanup_days=k,f("/settings",{method:"PATCH",body:{trash_cleanup_days:String(k)}})},500)});let c=document.getElementById("settings-verified-days"),u=null;c.addEventListener("input",()=>{u&&clearTimeout(u),u=setTimeout(()=>{let k=Math.max(1,parseInt(c.value,10)||30);c.value=String(k),a.settings.verified_cleanup_days=k,f("/settings",{method:"PATCH",body:{verified_cleanup_days:String(k)}})},500)});let d=document.getElementById("settings-app-name"),p=document.getElementById("settings-app-name-hint"),m=null;d.addEventListener("input",()=>{m&&clearTimeout(m),m=setTimeout(()=>{let k=d.value.trim();f("/file-settings",{method:"PATCH",body:{appName:k}}).then(()=>{let Z=k||"Hot Sheet";document.title=Z;let se=document.querySelector(".app-title h1");se&&(se.textContent=Z),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 Z=await k("check_for_update");Z?(y.textContent=`Update available: v${Z}`,document.getElementById("settings-overlay").style.display="none",dn(Z)):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)});let I=document.getElementById("settings-channel-section"),T=document.getElementById("settings-channel-enabled"),J=document.getElementById("settings-channel-hint"),Y=document.getElementById("settings-channel-instructions"),V=document.getElementById("settings-channel-copy-btn"),G=document.getElementById("settings-channel-cmd");document.getElementById("settings-btn").addEventListener("click",()=>{fetch("/api/channel/claude-check").then(k=>k.ok?k.json():null).then(k=>{if(!k||!k.installed){I.style.display="none";return}I.style.display="",k.meetsMinimum?(J.textContent="Push worklist events to a running Claude Code session via MCP channels.",T.disabled=!1):(J.textContent=`Claude Code ${k.version||"unknown"} detected but v2.1.80+ is required. Please upgrade Claude Code.`,T.disabled=!0)}).catch(()=>{I.style.display="none"})}),fetch("/api/channel/status").then(k=>k.ok?k.json():null).then(k=>{k&&(T.checked=k.enabled,k.enabled&&(Y.style.display=""))}).catch(()=>{}),T.addEventListener("change",async()=>{T.checked?(await f("/channel/enable",{method:"POST"}),Y.style.display=""):(await f("/channel/disable",{method:"POST"}),Y.style.display="none"),mn()}),V?.addEventListener("click",()=>{let k=G?.textContent||"";navigator.clipboard.writeText(k).then(()=>{V&&(V.textContent="Copied!",setTimeout(()=>{V.textContent="Copy"},1500))})}),xa()}function Ae(){let e=document.getElementById("category-list");e.innerHTML="";for(let t=0;t<a.categories.length;t++){let n=a.categories[t],s=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=s.querySelectorAll("input"),[i,l,c,u,d]=o,p=()=>{sn()};i.addEventListener("input",()=>{a.categories[t].color=i.value,p()}),l.addEventListener("input",()=>{a.categories[t].label=l.value,(!n.id||n.id==="")&&(a.categories[t].id=l.value.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")),p()}),c.addEventListener("input",()=>{a.categories[t].shortLabel=c.value.toUpperCase(),p()}),u.addEventListener("input",()=>{let m=u.value.toLowerCase().slice(0,1);u.value=m,a.categories[t].shortcutKey=m,an(),p()}),d.addEventListener("input",()=>{a.categories[t].description=d.value,p()}),s.querySelector(".category-delete-btn").addEventListener("click",()=>{a.categories.splice(t,1),Ae(),sn()}),e.appendChild(s)}an()}function an(){let e=document.querySelectorAll(".category-key-input"),t=new Map;a.categories.forEach((n,s)=>{if(n.shortcutKey){let o=n.shortcutKey.toLowerCase();t.has(o)||t.set(o,[]),t.get(o).push(s)}}),e.forEach((n,s)=>{let o=a.categories[s]?.shortcutKey?.toLowerCase();o&&t.get(o).length>1?n.classList.add("category-key-conflict"):n.classList.remove("category-key-conflict")})}var ct=null;function sn(){ct&&clearTimeout(ct),ct=setTimeout(async()=>{await f("/categories",{method:"PUT",body:a.categories}),gt()},500)}function xa(){document.getElementById("category-add-btn").addEventListener("click",()=>{a.categories.push({id:"",label:"",shortLabel:"",color:"#6b7280",shortcutKey:"",description:""}),Ae();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 s of n)e.appendChild(v(r("option",{value:s.id,children:s.name})))}),e.addEventListener("change",async()=>{if(!e.value)return;let s=(await f("/category-presets")).find(o=>o.id===e.value);s&&(a.categories=[...s.categories],await f("/categories",{method:"PUT",body:a.categories}),Ae(),gt()),e.value=""}),document.getElementById("settings-btn").addEventListener("click",()=>{Ae()})}async function La(){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 s=[0,3e3,1e4];for(let o of s){o>0&&await new Promise(i=>setTimeout(i,o));try{let i=await e("get_pending_update");if(i){dn(i);return}}catch{return}}}function ft(){return window.__TAURI__?.core?.invoke??null}function dn(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 s=document.getElementById("update-install-btn");s?.addEventListener("click",async()=>{if(s){s.textContent="Installing...",s.disabled=!0;try{await ft()?.("install_update"),n&&(n.textContent="Update installed! Restart the app to apply."),s.style.display="none"}catch{s.textContent="Install Failed",s.disabled=!1}}}),document.getElementById("update-banner-dismiss")?.addEventListener("click",()=>{t.style.display="none"})}function Ia(){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 Ca(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),n=document.getElementById("copy-prompt-label"),s=document.getElementById("copy-prompt-icon"),o="";f("/worklist-info").then(i=>{o=i.prompt,e.style.display="",i.skillCreated&&Ia()}),t.addEventListener("click",()=>{o!==""&&navigator.clipboard.writeText(o).then(()=>{n.textContent="Copied!",s.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",s.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 Sa(){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=Ne(),n=e.querySelector('[data-layout="columns"]');n.disabled=!t,n.style.opacity=t?"":"0.3";let s=a.layout==="columns"&&!t?"list":a.layout;e.querySelectorAll(".layout-btn").forEach(o=>{o.classList.toggle("active",o.dataset.layout===s)})}function Ma(){document.getElementById("layout-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let n=t.dataset.layout;n==="columns"&&!Ne()||(a.layout=n,H(),pt(),L(),f("/settings",{method:"PATCH",body:{layout:n}}))})}),pt()}function on(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.classList.toggle("active",t.dataset.position===a.settings.detail_position)})}function $a(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let n=t.dataset.position;a.settings.detail_position=n,Ke(n),ze(),on(),f("/settings",{method:"PATCH",body:{detail_position:n}})})}),on()}function un(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 Na(e,t){let n=un(e);if(!n)return;let s=a.tickets.filter(o=>t.includes(o.id));n.action==="delete"?await C(s,{ids:t,action:"delete"},"Delete tickets"):await C(s,{ids:t,action:n.action,value:n.value},`Change ${n.action}`),H(),w()}function Ba(){document.querySelectorAll(".sidebar-item[data-view]").forEach(t=>{t.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(s=>s.classList.remove("active")),t.classList.add("active"),a.view=t.dataset.view,a.selectedIds.clear(),vt(),H(),pt(),w()});let n=t.dataset.view;un(n)&&(t.addEventListener("dragover",s=>{s.preventDefault(),s.dataTransfer.dropEffect="move",t.classList.add("drop-target")}),t.addEventListener("dragleave",()=>{t.classList.remove("drop-target")}),t.addEventListener("drop",s=>{s.preventDefault(),t.classList.remove("drop-target");let o=[...U];o.length!==0&&Na(n,o)}))})}function _a(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,n]=e.value.split(":");a.sortBy=t,a.sortDir=n,H(),w()})}var dt=null;function Ha(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{dt&&clearTimeout(dt),dt=setTimeout(()=>{a.search=e.value,H(),w()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",a.search="",H(),w())})}var Te=!1,De=null,Pe=!1;function mt(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 pe=null;function pn(){mt(!0),f("/channel/trigger",{method:"POST",body:{}}),pe&&clearTimeout(pe),pe=setTimeout(()=>{Pe&&mt(!1)},12e4)}async function mn(){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"),s=document.getElementById("channel-play-icon"),o=document.getElementById("channel-auto-icon");if(!e.enabled){t.style.display="none";return}t.style.display="";let i=null;n.addEventListener("click",()=>{i?(clearTimeout(i),i=null,rn(n,s,o)):i=setTimeout(()=>{i=null,Te?rn(n,s,o):(n.classList.add("pulsing"),setTimeout(()=>n.classList.remove("pulsing"),600),pn())},250)})}function rn(e,t,n){Te=!Te,Te?(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 yt(){Te&&(De&&clearTimeout(De),De=setTimeout(()=>{De=null,pn()},5e3))}function vt(){let e=document.getElementById("dashboard-container");e&&(e.id="ticket-list",e.innerHTML="",Aa())}var gn=["search-input","layout-toggle","sort-select","detail-position-toggle","glassbox-btn"];function Da(){a.view="dashboard",document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active"));for(let o of gn){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 s=document.getElementById("ticket-list");s.innerHTML="",s.id="dashboard-container",s.classList.remove("ticket-list-columns"),st(s)}function Aa(){for(let e of gn){let t=document.getElementById(e);if(t){let n=t.closest(".search-box, .layout-toggle, .sort-controls")||t;n.style.display=""}}vt()}async function Pa(){let e=await tn(),t=document.getElementById("stats-bar");t&&t.after(e),e.addEventListener("click",()=>Da())}var fn=[{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"}],yn=[{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 Ra(){let e=document.getElementById("batch-category");e.addEventListener("click",o=>{o.stopPropagation(),_();let i=B(e,a.categories.map(l=>({label:l.label,key:l.shortcutKey,color:l.color,action:async()=>{let c=Array.from(a.selectedIds),u=a.tickets.filter(d=>a.selectedIds.has(d.id));await C(u,{ids:c,action:"category",value:l.id},"Batch change category"),w()}})));document.body.appendChild(i),N(i,e),i.style.visibility=""});let t=document.getElementById("batch-priority");t.addEventListener("click",o=>{o.stopPropagation(),_();let i=B(t,fn.map(l=>({label:l.label,key:l.key,icon:A(l.value),iconColor:P(l.value),action:async()=>{let c=Array.from(a.selectedIds),u=a.tickets.filter(d=>a.selectedIds.has(d.id));await C(u,{ids:c,action:"priority",value:l.value},"Batch change priority"),w()}})));document.body.appendChild(i),N(i,t),i.style.visibility=""});let n=document.getElementById("batch-status");n.addEventListener("click",o=>{o.stopPropagation(),_();let i=B(n,yn.map(l=>({label:l.label,key:l.key,icon:F(l.value),action:async()=>{let c=Array.from(a.selectedIds),u=a.tickets.filter(d=>a.selectedIds.has(d.id));await C(u,{ids:c,action:"status",value:l.value},"Batch change status"),w()}})));document.body.appendChild(i),N(i,n),i.style.visibility=""}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let o=a.tickets.filter(u=>a.selectedIds.has(u.id)),l=!o.every(u=>u.up_next),c=Array.from(a.selectedIds);if(l){let u=o.filter(d=>d.status==="completed"||d.status==="verified");if(u.length>0){let d=[{ids:u.map(p=>p.id),action:"status",value:"not_started"},{ids:c,action:"up_next",value:!0}];await We(o,d,"Batch toggle up next")}else await C(o,{ids:c,action:"up_next",value:!0},"Batch toggle up next")}else await C(o,{ids:c,action:"up_next",value:!1},"Batch toggle up next");w(),yt()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let o=Array.from(a.selectedIds),i=a.tickets.filter(l=>a.selectedIds.has(l.id));await C(i,{ids:o,action:"delete"},"Batch delete"),a.selectedIds.clear(),w()});let s=document.getElementById("batch-more");s.addEventListener("click",o=>{o.stopPropagation(),_();let i=B(s,[{label:"Tags...",key:"t",action:()=>{vn()}},{label:"Duplicate",key:"d",action:async()=>{let l=Array.from(a.selectedIds),c=await f("/tickets/duplicate",{method:"POST",body:{ids:l}});a.selectedIds.clear();for(let u of c)a.selectedIds.add(u.id);w()}},{label:"",key:"",separator:!0,action:()=>{}},{label:"Move to Backlog",key:"b",action:async()=>{let l=Array.from(a.selectedIds),c=a.tickets.filter(u=>a.selectedIds.has(u.id));await C(c,{ids:l,action:"status",value:"backlog"},"Move to backlog"),a.selectedIds.clear(),w()}},{label:"Archive",key:"a",action:async()=>{let l=Array.from(a.selectedIds),c=a.tickets.filter(u=>a.selectedIds.has(u.id));await C(c,{ids:l,action:"status",value:"archive"},"Archive"),a.selectedIds.clear(),w()}}]);document.body.appendChild(i),N(i,s),i.style.visibility=""}),document.getElementById("batch-select-all").addEventListener("change",o=>{if(o.target.checked)for(let l of a.tickets)a.selectedIds.add(l.id);else a.selectedIds.clear();L()})}var X=null;function qa(){document.getElementById("detail-close").addEventListener("click",It);let e=["detail-title","detail-details"];for(let d of e){let p=document.getElementById(d);p.addEventListener("input",()=>{let m=a.tickets.find(g=>g.id===a.activeTicketId);if(m){let g=d.replace("detail-","");Se(m,g,p.value)}X&&clearTimeout(X),X=setTimeout(()=>{if(a.activeTicketId==null)return;let g=d.replace("detail-","");f(`/tickets/${a.activeTicketId}`,{method:"PATCH",body:{[g]:p.value}}).then(()=>{w()})},300)})}async function t(d,p){if(a.activeTicketId==null)return;let m=a.tickets.find(g=>g.id===a.activeTicketId);m?await R(m,{[d]:p},`Change ${d}`):await f(`/tickets/${a.activeTicketId}`,{method:"PATCH",body:{[d]:p}}),w(),oe(a.activeTicketId)}document.getElementById("detail-category").addEventListener("click",d=>{d.stopPropagation();let p=d.currentTarget;if(p.disabled)return;_();let m=p.dataset.value||"",g=B(p,a.categories.map(y=>({label:y.label,key:y.shortcutKey,color:y.color,active:y.id===m,action:()=>{ve(y.id),t("category",y.id)}})));document.body.appendChild(g),N(g,p),g.style.visibility=""}),document.getElementById("detail-priority").addEventListener("click",d=>{d.stopPropagation();let p=d.currentTarget;if(p.disabled)return;_();let m=p.dataset.value||"",g=B(p,fn.map(y=>({label:y.label,key:y.key,icon:A(y.value),iconColor:P(y.value),active:y.value===m,action:()=>{Le(y.value),t("priority",y.value)}})));document.body.appendChild(g),N(g,p),g.style.visibility=""}),document.getElementById("detail-status").addEventListener("click",d=>{d.stopPropagation();let p=d.currentTarget;if(p.disabled)return;_();let m=p.dataset.value||"",g=B(p,yn.map(y=>({label:y.label,key:y.key,icon:F(y.value),active:y.value===m,action:()=>{Ie(y.value),t("status",y.value)}})));document.body.appendChild(g),N(g,p),g.style.visibility=""}),document.getElementById("detail-upnext").addEventListener("click",async()=>{if(a.activeTicketId==null)return;let d=a.tickets.find(p=>p.id===a.activeTicketId);d?!d.up_next&&(d.status==="completed"||d.status==="verified")?await R(d,{status:"not_started",up_next:!0},"Toggle up next"):await R(d,{up_next:!d.up_next},"Toggle up next"):await f(`/tickets/${a.activeTicketId}/up-next`,{method:"POST"}),w(),yt(),oe(a.activeTicketId)}),document.getElementById("detail-add-note-btn")?.addEventListener("click",async()=>{if(a.activeTicketId==null)return;let d=a.tickets.find(p=>p.id===a.activeTicketId);if(d){let p=d.notes;await f(`/tickets/${a.activeTicketId}`,{method:"PATCH",body:{notes:"(new note)"}});let m=await f(`/tickets/${a.activeTicketId}`);fe({...d,notes:p},"Add note",m.notes),d.notes=m.notes}oe(a.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async d=>{let p=d.target,m=p.files?.[0];!m||a.activeTicketId==null||(await Et(`/tickets/${a.activeTicketId}/attachments`,m),p.value="",oe(a.activeTicketId),w())}),document.getElementById("detail-attachments").addEventListener("click",async d=>{let p=d.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"}),a.activeTicketId!=null&&oe(a.activeTicketId))});let n=document.getElementById("detail-tag-input"),s=null,o=-1,i=[];f("/tags").then(d=>{i=d});function l(){s?.remove(),s=null,o=-1}function c(){l();let d=n.value.trim().toLowerCase();if(!d)return;let p=a.tickets.find(b=>b.id===a.activeTicketId),m=p?K(p.tags):[],g=i.filter(b=>b.toLowerCase().includes(d)&&!m.includes(b));if(g.length===0)return;s=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(),u()}),s.appendChild(E)}let y=n.getBoundingClientRect();s.style.position="fixed",s.style.left=`${y.left}px`,s.style.top=`${y.bottom+2}px`,s.style.width=`${y.width}px`,document.body.appendChild(s)}async function u(){let d=n.value.trim();if(!d||a.activeTicketId==null)return;let p=a.tickets.find(y=>y.id===a.activeTicketId);if(!p)return;let m=K(p.tags);if(m.includes(d)){n.value="";return}let g=[...m,d];n.value="",l(),await f(`/tickets/${a.activeTicketId}`,{method:"PATCH",body:{tags:JSON.stringify(g)}}),p.tags=JSON.stringify(g),ye(g,!1),i.includes(d)||i.push(d)}n.addEventListener("input",()=>{c()}),n.addEventListener("blur",()=>{l()}),n.addEventListener("keydown",d=>{if(d.key==="Enter"){if(d.preventDefault(),s&&o>=0){let p=s.querySelectorAll(".tag-autocomplete-item");n.value=p[o]?.textContent||n.value}l(),u()}else if(d.key==="Escape")l();else if(d.key==="ArrowDown"&&s){d.preventDefault();let p=s.querySelectorAll(".tag-autocomplete-item");o=Math.min(o+1,p.length-1),p.forEach((m,g)=>m.classList.toggle("active",g===o))}else if(d.key==="ArrowUp"&&s){d.preventDefault();let p=s.querySelectorAll(".tag-autocomplete-item");o=Math.max(o-1,0),p.forEach((m,g)=>m.classList.toggle("active",g===o))}})}async function vn(){let e=a.tickets.filter(p=>a.selectedIds.has(p.id));if(e.length===0)return;let t=await f("/tags");for(let p of e)for(let m of K(p.tags))t.includes(m)||t.push(m);t.sort();let n=new Map;for(let p of t){let m=e.filter(g=>K(g.tags).includes(p)).length;m===e.length?n.set(p,"checked"):m===0?n.set(p,"unchecked"):n.set(p,"mixed")}let s=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"),u=()=>{let p=c.value.trim();if(!p||t.includes(p)){c.value="";return}t.push(p),t.sort(),o.set(p,"checked"),s.set(p,"unchecked"),c.value="",l()};i.querySelector("#tags-dialog-add-btn").addEventListener("click",u),c.addEventListener("keydown",p=>{p.key==="Enter"&&(p.preventDefault(),u())});let d=()=>i.remove();i.querySelector("#tags-dialog-close").addEventListener("click",d),i.querySelector("#tags-dialog-cancel").addEventListener("click",d),i.addEventListener("click",p=>{p.target===i&&d()}),i.querySelector("#tags-dialog-done").addEventListener("click",async()=>{let p=[],m=[];for(let g of t){let y=s.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=K(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(),he()}d()})}function Ua(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 Oa(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let n=Ua(e.notes);if(n.length>0){t.push("");for(let s of n)t.push(`- ${s.text}`)}return t.join(`
98
+ `)}function ln(){console.log("[undo] triggerUndo called, canUndo:",Ht()),X&&(clearTimeout(X),X=null),Ze(),Bt().then(()=>console.log("[undo] performUndo completed")).catch(e=>console.error("[undo] performUndo error:",e))}function cn(){console.log("[undo] triggerRedo called, canRedo:",Dt()),X&&(clearTimeout(X),X=null),Ze(),_t().then(()=>console.log("[undo] performRedo completed")).catch(e=>console.error("[undo] performRedo error:",e))}function Va(){window.addEventListener("app:undo",ln),window.addEventListener("app:redo",cn),document.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="z"&&(e.preventDefault(),e.stopPropagation(),e.shiftKey?cn():ln())},!0),document.addEventListener("keydown",e=>{let t=e.target.tagName,n=t==="INPUT"||t==="TEXTAREA"||t==="SELECT",s=document.getElementById("settings-overlay");if(e.key==="Escape"&&s.style.display!=="none"){s.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}a.selectedIds.size>0&&(a.selectedIds.clear(),L());return}if((e.metaKey||e.ctrlKey)&&e.key==="a"&&!n){e.preventDefault(),a.selectedIds.clear();for(let o of a.tickets)a.selectedIds.add(o.id);L();return}if((e.metaKey||e.ctrlKey)&&e.key==="d"){if(a.selectedIds.size>0){e.preventDefault();let o=a.tickets.filter(u=>a.selectedIds.has(u.id)),l=!o.every(u=>u.up_next),c=Array.from(a.selectedIds);if(l){let u=o.filter(d=>d.status==="completed"||d.status==="verified");if(u.length>0){We(o,[{ids:u.map(d=>d.id),action:"status",value:"not_started"},{ids:c,action:"up_next",value:!0}],"Toggle up next").then(()=>{w()});return}}C(o,{ids:c,action:"up_next",value:l},"Toggle up next").then(()=>{w()})}return}if((e.metaKey||e.ctrlKey)&&e.key==="c"&&a.selectedIds.size>0&&!(n&&!e.altKey)){let o=!e.altKey&&window.getSelection();if(!(o&&!o.isCollapsed&&o.toString().trim()!=="")){e.preventDefault();let l=a.tickets.filter(c=>a.selectedIds.has(c.id)).map(Oa).join(`
3
99
 
4
- `);navigator.clipboard.writeText(o);return}}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),_();return}if((e.metaKey||e.ctrlKey)&&e.key==="f"){e.preventDefault(),document.getElementById("search-input").focus();return}if(e.key==="n"&&!s){e.preventDefault(),_();return}})}var be=0;function fn(){async function e(){try{let t=await p(`/poll?version=${be}`);t.version>be&&(be=t.version,n.backupPreview?.active||m())}catch{await new Promise(t=>setTimeout(t,5e3))}setTimeout(e,100)}e()}jt();})();
100
+ `);navigator.clipboard.writeText(l);return}}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),j();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(),j();return}if((e.key==="Delete"||e.key==="Backspace")&&!n&&a.selectedIds.size>0){e.preventDefault();let o=Array.from(a.selectedIds),i=a.tickets.filter(l=>a.selectedIds.has(l.id));C(i,{ids:o,action:"delete"},"Delete").then(()=>{a.selectedIds.clear(),w()});return}})}var ut=0;function Ka(){async function e(){try{let t=await f(`/poll?version=${ut}`);t.version>ut&&(ut=t.version,a.backupPreview?.active||w(),Pe&&fetch("/api/channel/status").then(n=>n.ok?n.json():null).then(n=>{n?.done&&(mt(!1),pe&&(clearTimeout(pe),pe=null))}).catch(()=>{}))}catch{await new Promise(t=>setTimeout(t,5e3))}setTimeout(e,100)}e()}ba();})();