@seatlayer/js 0.90.0 → 0.92.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.
package/dist/manager.js CHANGED
@@ -1,13 +1,14 @@
1
- import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D as Ee,a as F,b as k,c as H,d as ie,e as ae,f as oe,g as le,h as ne,i as re,j as ce,k as de,l as he,m as pe,n as me,o as ue,p as be,q as ge,r as ve,s as fe,t as ye,u as xe,v as ke,w as Se,x as we,y as Le,z as Te}from"./chunk-H7F4LMNV.js";import"./chunk-OSZ7DOEH.js";var j={hold:"Held",release:"Released",expire:"Expired",book:"Booked",unbook:"Cancelled",block:"Blocked",unblock:"Unblocked"},S=class{constructor(e,t){this.host=e;this.fetchPage=t;this.closed=!1;this.busy=!1;this.generation=0;this.entries=[];this.next=null;this.summary=document.createElement("div");this.list=document.createElement("div");this.message=document.createElement("div");this.older=document.createElement("button");this.latest=document.createElement("button");e.className="slm-seat-history",this.summary.className="slm-history-counts",this.list.className="slm-history-list",this.list.setAttribute("role","region"),this.list.setAttribute("aria-label","Seat history"),this.list.tabIndex=0,this.message.className="slm-note",this.message.setAttribute("role","status"),this.older.className=this.latest.className="slm-btn ghost",this.older.textContent="Load older",this.older.hidden=!0,this.latest.textContent="New activity \xB7 Show latest",this.latest.hidden=!0,this.older.onclick=()=>{this.load(!0)},this.latest.onclick=()=>{this.list.scrollTop=0,this.latest.hidden=!0,this.load()},e.append(this.summary,this.latest,this.list,this.message,this.older),this.load()}destroy(){this.closed=!0,this.generation++}refresh(){this.busy||this.load(!1,!0)}async load(e=!1,t=!1){if(this.closed||this.busy||e&&!this.next)return;this.busy=!0,this.older.disabled=!0;let s=this.generation;t||(this.message.textContent="Loading history\u2026");try{let i=await this.fetchPage(e?this.next:void 0,this.action);if(this.closed||s!==this.generation)return;if(this.paintCounts(i),t&&this.entries.length&&i.entries[0]?.id!==this.entries[0]?.id&&this.list.scrollTop>24){this.latest.hidden=!1;return}let a=!t||i.entries[0]?.id!==this.entries[0]?.id;e?(this.entries=[...this.entries,...i.entries.filter(o=>!this.entries.some(l=>l.id===o.id))],this.next=i.nextBefore):a&&(this.entries=i.entries,this.next=i.nextBefore),a&&this.paintRows(),this.older.hidden=this.next===null,this.message.textContent=this.entries.length?"":"No recorded activity for this seat."}catch{if(!this.closed){this.message.textContent="History could not be loaded. ";let i=document.createElement("button");i.className="slm-btn ghost",i.textContent="Retry",i.onclick=()=>{this.load(e)},this.message.append(i)}}finally{this.busy=!1,this.older.disabled=!1}}paintCounts(e){let t=[{action:"",count:e.total},...e.counts];this.summary.replaceChildren(...t.map(({action:s,count:i})=>{let a=document.createElement("button");return a.type="button",a.textContent=s?`${j[s]??s} ${i}`:`${i} changes`,a.setAttribute("aria-pressed",String((this.action??"")===s)),a.onclick=()=>{this.busy||(this.action=s||void 0,this.entries=[],this.next=null,this.list.scrollTop=0,this.latest.hidden=!0,this.load())},a}))}paintRows(){let e=this.list.scrollTop;this.list.replaceChildren(...this.entries.map(t=>{let s=document.createElement("div");s.className="slm-history-row",s.dataset.action=t.action;let i=document.createElement("time");i.dateTime=new Date(t.at).toISOString(),i.textContent=new Date(t.at).toLocaleString(void 0,{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}),i.title=new Date(t.at).toString();let a=document.createElement("strong");return a.textContent=j[t.action]??t.action,s.append(i,a),s})),this.list.scrollTop=e}};var Re={held:"HOLD",booked:"BOOK",expired:"EXPIRE",released:"RELEASE",cancelled:"CANCEL",blocked:"BLOCK",unblocked:"ON SALE",available:"FREE"},P={held:"Held",booked:"Booked",expired:"Hold expired",released:"Hold released",cancelled:"Booking cancelled",blocked:"Blocked",unblocked:"Back on sale",available:"Available again"},w=class{constructor(e,t,s){this.host=e;this.locate=s;this.items=[];this.shown=new Set;this.paused=!1;this.limit=100;this.signature="unrendered";this.abort=new AbortController;e.innerHTML='<button class="slm-new-activity" hidden></button><div class="slm-activity-list" role="region" aria-label="Recent activity" tabindex="0"></div><button class="slm-more-activity" hidden>Show more activity</button>',this.list=e.querySelector(".slm-activity-list"),this.newer=e.querySelector(".slm-new-activity"),this.more=e.querySelector(".slm-more-activity");let i={signal:this.abort.signal},a=()=>{this.paused=!1,this.signature="unrendered",this.list.scrollTop=0,this.render()};this.list.addEventListener("scroll",()=>{this.list.scrollTop>24&&(this.paused=!0)},i),this.list.addEventListener("focusin",()=>{this.paused=!0},i),this.list.addEventListener("toggle",o=>{o.target.open&&(this.paused=!0)},{...i,capture:!0}),this.newer.addEventListener("click",a,i),this.more.addEventListener("click",()=>{this.limit=200,this.signature="unrendered",this.render(!0)},i)}update(e){this.items=e,this.render()}render(e=!1){let t=this.items,s=t.filter(o=>!this.shown.has(o.id)).length;if(this.newer.hidden=!this.paused,this.newer.textContent=s?`${s} new activit${s===1?"y":"ies"} \xB7 Back to live`:"Reading earlier activity \xB7 Back to live",this.paused&&!e)return;let i=t.slice(0,this.limit),a=i.map(o=>`${o.id}:${o.verb}`).join("|");if(a!==this.signature){if(this.signature=a,this.shown=new Set(t.map(o=>o.id)),this.list.replaceChildren(),!i.length){let o=document.createElement("p");o.className="slm-activity-empty",o.textContent=this.items.length?"No activity matches these filters.":"Waiting for activity. Holds, bookings and releases will appear here.",this.list.append(o)}for(let o of i){let l=document.createElement("article");l.className="slm-activity-entry",l.dataset.status=o.status;let r=document.createElement("button");r.type="button",r.className="slm-activity-row";let c=`${P[o.verb]??o.verb} \xB7 ${o.count} seat${o.count===1?"":"s"} \xB7 ${o.sectionLabels?.join(", ")||"Event inventory"} \xB7 ${o.labels.join(", ")} \xB7 ${new Date(o.at).toLocaleString()}`;r.title=`${c} \u2014 click to show seats on the map`,r.setAttribute("aria-label",`Show seats on map: ${c}`),r.addEventListener("click",()=>this.locate(o.id));let n=document.createElement("time");n.dateTime=new Date(o.at).toISOString(),n.textContent=new Date(o.at).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});let d=document.createElement("strong");d.textContent=Re[o.verb]??o.verb,d.title=P[o.verb]??o.verb;let m=document.createElement("span");if(m.className="slm-activity-seats",m.textContent=o.labels.join(", "),r.append(n,d,m),l.append(r),o.count>1){let b=document.createElement("details");b.className="slm-activity-details";let g=document.createElement("summary");g.textContent="\u22EF",g.setAttribute("aria-label",`Show all ${o.count} seats`);let v=document.createElement("p");v.textContent=c,b.append(g,v),l.append(b)}this.list.append(l)}this.more.hidden=t.length<=this.limit}}destroy(){this.abort.abort()}};var L=class{constructor(e){this.host=e;this.moving=!1;this.space=!1;this.abort=new AbortController;let t=document.createElement("div");t.className="slm-navigation";let s=u=>`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${u}</svg>`,i=s('<path d="M8 13V6a2 2 0 0 1 4 0v6-8a2 2 0 0 1 4 0v8-6a2 2 0 0 1 4 0v10c0 4-3 6-7 6-3 0-5-2-7-5l-3-4a2 2 0 0 1 3-2l2 2Z"/>'),a=s('<path d="m5 3 14 10-7 1-3 7-4-18Z"/>'),o=s('<circle cx="10.5" cy="10.5" r="6.5"/><path d="m16 16 5 5"/>'),l=s('<path d="M7 6h10M12 1v10M7 18h10"/>'),r=s('<rect x="3" y="4" width="18" height="16" rx="2"/><path d="M15 4v16"/>');t.innerHTML=`<div class="slm-navigation-tools" role="group" aria-label="Map navigation">
1
+ import{c as H,d as B,f as j}from"./chunk-RZ2VKZ44.js";import{A as Re,B as Ae,D as $e,a as P,b as S,c as z,d as le,e as ne,f as re,g as ce,h as de,i as he,j as pe,k as me,l as ue,m as be,n as ge,o as ve,p as fe,q as ye,r as xe,s as ke,t as Se,u as we,v as Le,w as Te,x as Me,y as Ce,z as Ee}from"./chunk-5VGXB6GJ.js";import"./chunk-OSZ7DOEH.js";var D={hold:"Held",release:"Released",expire:"Expired",book:"Booked",unbook:"Cancelled",block:"Blocked",unblock:"Unblocked"},w=class{constructor(e,t){this.host=e;this.fetchPage=t;this.closed=!1;this.busy=!1;this.generation=0;this.entries=[];this.next=null;this.summary=document.createElement("div");this.list=document.createElement("div");this.message=document.createElement("div");this.older=document.createElement("button");this.latest=document.createElement("button");e.className="slm-seat-history",this.summary.className="slm-history-counts",this.list.className="slm-history-list",this.list.setAttribute("role","region"),this.list.setAttribute("aria-label","Seat history"),this.list.tabIndex=0,this.message.className="slm-note",this.message.setAttribute("role","status"),this.older.className=this.latest.className="slm-btn ghost",this.older.textContent="Load older",this.older.hidden=!0,this.latest.textContent="New activity \xB7 Show latest",this.latest.hidden=!0,this.older.onclick=()=>{this.load(!0)},this.latest.onclick=()=>{this.list.scrollTop=0,this.latest.hidden=!0,this.load()},e.append(this.summary,this.latest,this.list,this.message,this.older),this.load()}destroy(){this.closed=!0,this.generation++}refresh(){this.busy||this.load(!1,!0)}async load(e=!1,t=!1){if(this.closed||this.busy||e&&!this.next)return;this.busy=!0,this.older.disabled=!0;let s=this.generation;t||(this.message.textContent="Loading history\u2026");try{let i=await this.fetchPage(e?this.next:void 0,this.action);if(this.closed||s!==this.generation)return;if(this.paintCounts(i),t&&this.entries.length&&i.entries[0]?.id!==this.entries[0]?.id&&this.list.scrollTop>24){this.latest.hidden=!1;return}let a=!t||i.entries[0]?.id!==this.entries[0]?.id;e?(this.entries=[...this.entries,...i.entries.filter(o=>!this.entries.some(l=>l.id===o.id))],this.next=i.nextBefore):a&&(this.entries=i.entries,this.next=i.nextBefore),a&&this.paintRows(),this.older.hidden=this.next===null,this.message.textContent=this.entries.length?"":"No recorded activity for this seat."}catch{if(!this.closed){this.message.textContent="History could not be loaded. ";let i=document.createElement("button");i.className="slm-btn ghost",i.textContent="Retry",i.onclick=()=>{this.load(e)},this.message.append(i)}}finally{this.busy=!1,this.older.disabled=!1}}paintCounts(e){let t=[{action:"",count:e.total},...e.counts];this.summary.replaceChildren(...t.map(({action:s,count:i})=>{let a=document.createElement("button");return a.type="button",a.textContent=s?`${D[s]??s} ${i}`:`${i} changes`,a.setAttribute("aria-pressed",String((this.action??"")===s)),a.onclick=()=>{this.busy||(this.action=s||void 0,this.entries=[],this.next=null,this.list.scrollTop=0,this.latest.hidden=!0,this.load())},a}))}paintRows(){let e=this.list.scrollTop;this.list.replaceChildren(...this.entries.map(t=>{let s=document.createElement("div");s.className="slm-history-row",s.dataset.action=t.action;let i=document.createElement("time");i.dateTime=new Date(t.at).toISOString(),i.textContent=new Date(t.at).toLocaleString(void 0,{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}),i.title=new Date(t.at).toString();let a=document.createElement("strong");return a.textContent=D[t.action]??t.action,s.append(i,a),s})),this.list.scrollTop=e}};var He={held:"HOLD",booked:"BOOK",expired:"EXPIRE",released:"RELEASE",cancelled:"CANCEL",blocked:"BLOCK",unblocked:"ON SALE",available:"FREE"},N={held:"Held",booked:"Booked",expired:"Hold expired",released:"Hold released",cancelled:"Booking cancelled",blocked:"Blocked",unblocked:"Back on sale",available:"Available again"},L=class{constructor(e,t,s){this.host=e;this.locate=s;this.items=[];this.shown=new Set;this.paused=!1;this.limit=100;this.signature="unrendered";this.abort=new AbortController;e.innerHTML='<button class="slm-new-activity" hidden></button><div class="slm-activity-list" role="region" aria-label="Recent activity" tabindex="0"></div><button class="slm-more-activity" hidden>Show more activity</button>',this.list=e.querySelector(".slm-activity-list"),this.newer=e.querySelector(".slm-new-activity"),this.more=e.querySelector(".slm-more-activity");let i={signal:this.abort.signal},a=()=>{this.paused=!1,this.signature="unrendered",this.list.scrollTop=0,this.render()};this.list.addEventListener("scroll",()=>{this.list.scrollTop>24&&(this.paused=!0)},i),this.list.addEventListener("focusin",()=>{this.paused=!0},i),this.list.addEventListener("toggle",o=>{o.target.open&&(this.paused=!0)},{...i,capture:!0}),this.newer.addEventListener("click",a,i),this.more.addEventListener("click",()=>{this.limit=200,this.signature="unrendered",this.render(!0)},i)}update(e){this.items=e,this.render()}render(e=!1){let t=this.items,s=t.filter(o=>!this.shown.has(o.id)).length;if(this.newer.hidden=!this.paused,this.newer.textContent=s?`${s} new activit${s===1?"y":"ies"} \xB7 Back to live`:"Reading earlier activity \xB7 Back to live",this.paused&&!e)return;let i=t.slice(0,this.limit),a=i.map(o=>`${o.id}:${o.verb}`).join("|");if(a!==this.signature){if(this.signature=a,this.shown=new Set(t.map(o=>o.id)),this.list.replaceChildren(),!i.length){let o=document.createElement("p");o.className="slm-activity-empty",o.textContent=this.items.length?"No activity matches these filters.":"Waiting for activity. Holds, bookings and releases will appear here.",this.list.append(o)}for(let o of i){let l=document.createElement("article");l.className="slm-activity-entry",l.dataset.status=o.status;let r=document.createElement("button");r.type="button",r.className="slm-activity-row";let c=`${N[o.verb]??o.verb} \xB7 ${o.count} seat${o.count===1?"":"s"} \xB7 ${o.sectionLabels?.join(", ")||"Event inventory"} \xB7 ${o.labels.join(", ")} \xB7 ${new Date(o.at).toLocaleString()}`;r.title=`${c} \u2014 click to show seats on the map`,r.setAttribute("aria-label",`Show seats on map: ${c}`),r.addEventListener("click",()=>this.locate(o.id));let n=document.createElement("time");n.dateTime=new Date(o.at).toISOString(),n.textContent=new Date(o.at).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});let d=document.createElement("strong");d.textContent=He[o.verb]??o.verb,d.title=N[o.verb]??o.verb;let m=document.createElement("span");if(m.className="slm-activity-seats",m.textContent=o.labels.join(", "),r.append(n,d,m),l.append(r),o.count>1){let b=document.createElement("details");b.className="slm-activity-details";let g=document.createElement("summary");g.textContent="\u22EF",g.setAttribute("aria-label",`Show all ${o.count} seats`);let v=document.createElement("p");v.textContent=c,b.append(g,v),l.append(b)}this.list.append(l)}this.more.hidden=t.length<=this.limit}}destroy(){this.abort.abort()}};var T=class{constructor(e){this.host=e;this.moving=!1;this.space=!1;this.monitor=!1;this.selected=0;this.abort=new AbortController;let t=document.createElement("div");t.className="slm-navigation";let s=u=>`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${u}</svg>`,i=s('<path d="M8 13V6a2 2 0 0 1 4 0v6-8a2 2 0 0 1 4 0v8-6a2 2 0 0 1 4 0v10c0 4-3 6-7 6-3 0-5-2-7-5l-3-4a2 2 0 0 1 3-2l2 2Z"/>'),a=s('<path d="m5 3 14 10-7 1-3 7-4-18Z"/>'),o=s('<circle cx="10.5" cy="10.5" r="6.5"/><path d="m16 16 5 5"/>'),l=s('<path d="M7 6h10M12 1v10M7 18h10"/>'),r=s('<rect x="3" y="4" width="18" height="16" rx="2"/><path d="M15 4v16"/>');t.innerHTML=`<div class="slm-navigation-tools" role="group" aria-label="Map navigation">
2
2
  <button type="button" data-nav="move" aria-label="Move" aria-pressed="false" title="Drag to move the map; hold Space temporarily">${i}</button>
3
- <button type="button" data-nav="select" aria-label="Select" aria-pressed="true" title="Drag to select seats">${a}</button>
3
+ <button type="button" data-nav="select" aria-label="Select" aria-pressed="true" title="Drag to select seats \xB7 drag empty floor to move">${a}</button>
4
4
  <button type="button" data-nav="search" aria-label="Search" title="Search seats, rows or sections" aria-expanded="false">${o}</button>
5
5
  <button type="button" data-nav="zoom" aria-label="Zoom" title="Zoom controls" aria-expanded="false">${l}</button>
6
6
  <button type="button" hidden data-nav="out" aria-label="Zoom out">\u2212</button>
7
7
  <button type="button" hidden data-nav="in" aria-label="Zoom in">+</button>
8
8
  <span class="slm-navigation-count" role="status" aria-live="polite">0 selected</span>
9
+ <button type="button" class="slm-navigation-clear" data-nav="clear" hidden title="Clear the selection">Clear</button>
9
10
  <button type="button" data-nav="rail" aria-label="Hide details" title="Hide details" aria-expanded="true">${r}</button>
10
- </div><div class="slm-navigation-search" hidden><input type="search" aria-label="Find section, row or seat" placeholder="Find section, row or seat"><div class="slm-navigation-results" hidden></div></div>`,e.map.after(t),this.bar=t,this.move=t.querySelector('[data-nav="move"]'),this.select=t.querySelector('[data-nav="select"]'),this.search=t.querySelector("input"),this.results=t.querySelector(".slm-navigation-results"),this.location=document.createElement("div"),this.location.className="slm-location",this.location.hidden=!0,this.location.setAttribute("role","status"),e.map.after(this.location);let c={signal:this.abort.signal},n=t.querySelector('[data-nav="search"]'),d=t.querySelector(".slm-navigation-search"),m=()=>{d.hidden=!0,this.results.hidden=!0,n.setAttribute("aria-expanded","false"),n.focus()};n.addEventListener("click",()=>{let u=d.hidden;d.hidden=!u,n.setAttribute("aria-expanded",String(u)),u&&this.search.focus()},c);let b=t.querySelector('[data-nav="zoom"]');b.addEventListener("click",()=>{let u=b.getAttribute("aria-expanded")!=="true";b.setAttribute("aria-expanded",String(u));for(let f of["in","out"])t.querySelector(`[data-nav="${f}"]`).hidden=!u},c),this.search.addEventListener("keydown",u=>{u.key==="Escape"&&m()},c),this.move.addEventListener("click",()=>this.setMoving(!0),c),this.select.addEventListener("click",()=>this.setMoving(!1),c),t.querySelector('[data-nav="in"]').addEventListener("click",()=>{this.location.hidden=!0,e.pauseFollow(),e.zoomIn()},c),t.querySelector('[data-nav="out"]').addEventListener("click",()=>{this.location.hidden=!0,e.pauseFollow(),e.zoomOut()},c);let g=t.querySelector('[data-nav="rail"]');g.addEventListener("click",()=>{let u=e.root.classList.toggle("details-hidden");g.setAttribute("aria-expanded",String(!u)),g.setAttribute("aria-label",u?"Show details":"Hide details"),g.title=u?"Show details":"Hide details"},c),this.search.addEventListener("input",()=>this.find(),c),this.search.addEventListener("keydown",u=>{u.key==="Escape"&&(this.results.hidden=!0),u.key==="ArrowDown"&&(u.preventDefault(),this.results.querySelector("button")?.focus())},c),e.map.addEventListener("pointerdown",()=>{this.location.hidden=!0,e.pauseFollow(),e.root.focus({preventScroll:!0}),this.results.hidden=!0},{...c,capture:!0}),e.root.querySelector(".slm-rail")?.addEventListener("pointerdown",()=>e.pauseFollow(),{...c,capture:!0}),e.map.addEventListener("wheel",()=>{this.location.hidden=!0,e.pauseFollow()},{...c,passive:!0,capture:!0}),e.root.addEventListener("keydown",u=>{u.target?.closest('input,textarea,select,button,[contenteditable="true"]')||u.code!=="Space"||u.ctrlKey||u.metaKey||u.altKey||(u.preventDefault(),this.space||(this.space=!0,e.pauseFollow(),e.setMoving(!0)))},c);let v=()=>{this.space&&(this.space=!1,e.setMoving(this.moving))};window.addEventListener("keyup",u=>{u.code==="Space"&&v()},c),window.addEventListener("blur",v,c),window.addEventListener("resize",()=>{this.location.hidden=!0},c),e.root.querySelector('[data-ref="zfit"]')?.addEventListener("click",()=>{this.location.hidden=!0},c),e.root.addEventListener("focusout",u=>{e.root.contains(u.relatedTarget)||v()},c)}setMoving(e){this.moving=e,this.host.pauseFollow(),this.host.setMoving(e||this.space),this.move.setAttribute("aria-pressed",String(e)),this.select.setAttribute("aria-pressed",String(!e))}update(e,t=!1){this.bar.querySelector(".slm-navigation-count").hidden=t,this.move.hidden=!e,this.select.hidden=!e}selectionChanged(e){this.bar.querySelector(".slm-navigation-count").textContent=`${e.toLocaleString()} selected`}find(){let e=this.search.value.trim();if(this.results.replaceChildren(),this.results.hidden=!e,!e)return;let t=this.host.targets(e);for(let s of t){let i=document.createElement("button");i.type="button",i.textContent=`${s.label} \xB7 ${s.detail}`,i.addEventListener("click",()=>{this.host.pauseFollow(),s.locate(),this.location.textContent=`${s.label} \xB7 ${s.detail}`,this.location.hidden=!1,this.results.hidden=!0,this.host.root.focus({preventScroll:!0})}),this.results.append(i)}t.length||(this.results.textContent="No matching section, row or seat.")}destroy(){this.abort.abort(),this.bar.remove(),this.location.remove()}};import{SeatmapRenderer as Oe,expandChart as Fe,computeSections as je,floorsOf as J,gaAreasOf as Pe,gaUnitLabels as De,UNGROUPED_ID as y}from"@seatlayer/core";var Ae=/^[a-zA-Z0-9._-]+$/;function $e(h){let e;try{e=new URL(h,"https://seatlayer.invalid")}catch{return null}if(e.search||e.hash)return null;let t=/^\/v1\/events\/([^/]+)\/assets\/([^/]+)$/.exec(e.pathname);if(!t)return null;try{let s=decodeURIComponent(t[1]),i=decodeURIComponent(t[2]);return!s||!Ae.test(i)?null:{eventKey:s,asset:i}}catch{return null}}function He(h){try{return/^\/v1\/events\/[^/]+\/assets(?:\/|$)/.test(new URL(h,"https://seatlayer.invalid").pathname)}catch{return!1}}var T=class{constructor(e,t){this.eventKey=e;this.load=t;this.pending=new Map;this.created=new Set;this.disposed=!1}resolve(e){let t=$e(e);if(!t)return Promise.resolve(He(e)?null:e);if(t.eventKey!==this.eventKey||this.disposed)return Promise.resolve(null);let s=`${t.eventKey}/${t.asset}`,i=this.pending.get(s);if(i)return i;let a=this.load(t.eventKey,t.asset).then(o=>{let l=URL.createObjectURL(o);return this.disposed?(URL.revokeObjectURL(l),null):(this.created.add(l),l)}).catch(o=>{throw this.pending.delete(s),o});return this.pending.set(s,a),a}async prepareRendererChart(e){let t=async a=>{if(!a?.url)return;let o=await this.resolve(a.url);if(!o)throw new Error("organizer_event_asset_scope_mismatch");a.url=o},s=async a=>{for(let o of a){if(o.type!=="decorImage")continue;let l=o,r=await this.resolve(l.href);if(!r)throw new Error("organizer_event_asset_scope_mismatch");l.href=r}},i=async a=>{await t(a.backgroundImage),await s(a.objects)};await i(e);for(let a of e.floors??[])await i(a);return e}dispose(){if(!this.disposed){this.disposed=!0;for(let e of this.created)URL.revokeObjectURL(e);this.created.clear(),this.pending.clear()}}};var D="seatlayer-manager-style",N="seatlayer-manager-channels-style",Be=`
11
+ </div><div class="slm-navigation-search" hidden><input type="search" aria-label="Find section, row or seat" placeholder="Find section, row or seat"><div class="slm-navigation-results" hidden></div></div>`,e.map.after(t),this.bar=t,this.move=t.querySelector('[data-nav="move"]'),this.select=t.querySelector('[data-nav="select"]'),this.search=t.querySelector("input"),this.count=t.querySelector(".slm-navigation-count"),this.clear=t.querySelector('[data-nav="clear"]'),this.results=t.querySelector(".slm-navigation-results"),this.location=document.createElement("div"),this.location.className="slm-location",this.location.hidden=!0,this.location.setAttribute("role","status"),e.map.after(this.location);let c={signal:this.abort.signal},n=t.querySelector('[data-nav="search"]'),d=t.querySelector(".slm-navigation-search"),m=()=>{d.hidden=!0,this.results.hidden=!0,n.setAttribute("aria-expanded","false"),n.focus()};n.addEventListener("click",()=>{let u=d.hidden;d.hidden=!u,n.setAttribute("aria-expanded",String(u)),u&&this.search.focus()},c);let b=t.querySelector('[data-nav="zoom"]');b.addEventListener("click",()=>{let u=b.getAttribute("aria-expanded")!=="true";b.setAttribute("aria-expanded",String(u));for(let f of["in","out"])t.querySelector(`[data-nav="${f}"]`).hidden=!u},c),this.search.addEventListener("keydown",u=>{u.key==="Escape"&&m()},c),this.move.addEventListener("click",()=>this.setMoving(!0),c),this.select.addEventListener("click",()=>this.setMoving(!1),c),this.clear.addEventListener("click",()=>this.host.clearSelection(),c),t.querySelector('[data-nav="in"]').addEventListener("click",()=>{this.location.hidden=!0,e.pauseFollow(),e.zoomIn()},c),t.querySelector('[data-nav="out"]').addEventListener("click",()=>{this.location.hidden=!0,e.pauseFollow(),e.zoomOut()},c);let g=t.querySelector('[data-nav="rail"]');g.addEventListener("click",()=>{let u=e.root.classList.toggle("details-hidden");g.setAttribute("aria-expanded",String(!u)),g.setAttribute("aria-label",u?"Show details":"Hide details"),g.title=u?"Show details":"Hide details"},c),this.search.addEventListener("input",()=>this.find(),c),this.search.addEventListener("keydown",u=>{u.key==="Escape"&&(this.results.hidden=!0),u.key==="ArrowDown"&&(u.preventDefault(),this.results.querySelector("button")?.focus())},c),e.map.addEventListener("pointerdown",()=>{this.location.hidden=!0,e.pauseFollow(),e.root.focus({preventScroll:!0}),this.results.hidden=!0},{...c,capture:!0}),e.root.querySelector(".slm-rail")?.addEventListener("pointerdown",()=>e.pauseFollow(),{...c,capture:!0}),e.map.addEventListener("wheel",()=>{this.location.hidden=!0,e.pauseFollow()},{...c,passive:!0,capture:!0}),e.root.addEventListener("keydown",u=>{u.target?.closest('input,textarea,select,button,[contenteditable="true"]')||u.code!=="Space"||u.ctrlKey||u.metaKey||u.altKey||(u.preventDefault(),this.space||(this.space=!0,e.pauseFollow(),e.setMoving(!0)))},c);let v=()=>{this.space&&(this.space=!1,e.setMoving(this.moving))};window.addEventListener("keyup",u=>{u.code==="Space"&&v()},c),window.addEventListener("blur",v,c),window.addEventListener("resize",()=>{this.location.hidden=!0},c),e.root.querySelector('[data-ref="zfit"]')?.addEventListener("click",()=>{this.location.hidden=!0},c),e.root.addEventListener("focusout",u=>{e.root.contains(u.relatedTarget)||v()},c)}setMoving(e){this.moving=e,this.host.pauseFollow(),this.host.setMoving(e||this.space),this.move.setAttribute("aria-pressed",String(e)),this.select.setAttribute("aria-pressed",String(!e))}update(e,t=!1){this.monitor=t,this.count.hidden=t,this.paintClear(),this.move.hidden=!e,this.select.hidden=!e}selectionChanged(e){this.selected=e,this.count.textContent=`${e.toLocaleString()} selected`,this.paintClear()}paintClear(){this.clear.hidden=this.monitor||this.selected<1}find(){let e=this.search.value.trim();if(this.results.replaceChildren(),this.results.hidden=!e,!e)return;let t=this.host.targets(e);for(let s of t){let i=document.createElement("button");i.type="button",i.textContent=`${s.label} \xB7 ${s.detail}`,i.addEventListener("click",()=>{this.host.pauseFollow(),s.locate(),this.location.textContent=`${s.label} \xB7 ${s.detail}`,this.location.hidden=!1,this.results.hidden=!0,this.host.root.focus({preventScroll:!0})}),this.results.append(i)}t.length||(this.results.textContent="No matching section, row or seat.")}destroy(){this.abort.abort(),this.bar.remove(),this.location.remove()}};import{SeatmapRenderer as De,applyOrganizerSeatGlyph as Ne,clearOrganizerSeatGlyph as qe,isOrganizerGlyphPainted as _e,expandChart as Ve,computeSections as Ue,floorsOf as se,gaAreasOf as Ke,gaUnitLabels as Ge,UNGROUPED_ID as x}from"@seatlayer/core";var Be=/^[a-zA-Z0-9._-]+$/;function ze(h){let e;try{e=new URL(h,"https://seatlayer.invalid")}catch{return null}if(e.search||e.hash)return null;let t=/^\/v1\/events\/([^/]+)\/assets\/([^/]+)$/.exec(e.pathname);if(!t)return null;try{let s=decodeURIComponent(t[1]),i=decodeURIComponent(t[2]);return!s||!Be.test(i)?null:{eventKey:s,asset:i}}catch{return null}}function Ie(h){try{return/^\/v1\/events\/[^/]+\/assets(?:\/|$)/.test(new URL(h,"https://seatlayer.invalid").pathname)}catch{return!1}}var M=class{constructor(e,t){this.eventKey=e;this.load=t;this.pending=new Map;this.created=new Set;this.disposed=!1}resolve(e){let t=ze(e);if(!t)return Promise.resolve(Ie(e)?null:e);if(t.eventKey!==this.eventKey||this.disposed)return Promise.resolve(null);let s=`${t.eventKey}/${t.asset}`,i=this.pending.get(s);if(i)return i;let a=this.load(t.eventKey,t.asset).then(o=>{let l=URL.createObjectURL(o);return this.disposed?(URL.revokeObjectURL(l),null):(this.created.add(l),l)}).catch(o=>{throw this.pending.delete(s),o});return this.pending.set(s,a),a}async prepareRendererChart(e){let t=async a=>{if(!a?.url)return;let o=await this.resolve(a.url);if(!o)throw new Error("organizer_event_asset_scope_mismatch");a.url=o},s=async a=>{for(let o of a){if(o.type!=="decorImage")continue;let l=o,r=await this.resolve(l.href);if(!r)throw new Error("organizer_event_asset_scope_mismatch");l.href=r}},i=async a=>{await t(a.backgroundImage),await s(a.objects)};await i(e);for(let a of e.floors??[])await i(a);return e}dispose(){if(!this.disposed){this.disposed=!0;for(let e of this.created)URL.revokeObjectURL(e);this.created.clear(),this.pending.clear()}}};var q="seatlayer-manager-style",_="seatlayer-manager-channels-style",Oe=`
11
12
  /* The floor was 480px, which trapped the cockpit in any host shorter than that:
12
13
  every ancestor here is overflow:hidden, so the bottom of the rail (Create
13
14
  channel, Show archived) was rendered but clipped away by the host and could
@@ -42,6 +43,9 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
42
43
  .slm .slm-navigation .slm-navigation-tools button{width:32px;height:32px;min-width:32px;min-height:32px;padding:0;border:0;border-radius:5px;background:transparent;box-shadow:none;color:var(--slm-muted);cursor:pointer}
43
44
  .slm .slm-navigation .slm-navigation-tools button:hover{background:var(--slm-tint);color:var(--slm-text)}
44
45
  .slm .slm-navigation .slm-navigation-tools button[aria-pressed=true],.slm .slm-navigation .slm-navigation-tools button[data-nav=search][aria-expanded=true],.slm .slm-navigation .slm-navigation-tools button[data-nav=zoom][aria-expanded=true]{background:var(--slm-accent);color:var(--slm-accent-ink)}
46
+ /* the count's companion \u2014 a word, not a 32px icon well */
47
+ .slm .slm-navigation .slm-navigation-tools button.slm-navigation-clear{width:auto;min-width:0;height:26px;min-height:26px;
48
+ padding:0 9px;border-radius:999px;font-size:11.5px;font-weight:800;color:var(--slm-accent);background:var(--slm-tint)}
45
49
  .slm .slm-navigation .slm-navigation-tools button[data-nav=rail]{margin-left:4px;position:relative}
46
50
  .slm .slm-navigation .slm-navigation-tools button[data-nav=rail]::before{content:'';position:absolute;left:-4px;top:7px;bottom:7px;width:1px;background:var(--slm-line)}
47
51
  .slm .slm-navigation .slm-navigation-tools button:focus-visible{outline:2px solid var(--slm-accent);outline-offset:1px}
@@ -156,17 +160,28 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
156
160
  .slm-hud{position:absolute;left:12px;bottom:12px;display:flex;gap:8px}
157
161
  .slm .slm-hud-chip{padding:6px 11px;border-radius:999px;font-size:12px;font-weight:700;background:var(--slm-surface);
158
162
  border:1px solid var(--slm-line);color:var(--slm-text)}
159
- .slm-zoomhint{position:absolute;left:50%;top:14px;transform:translateX(-50%);padding:6px 13px;border-radius:999px;
160
- background:rgba(0,0,0,.55);color:#fff;font-size:12px;font-weight:700;pointer-events:none;opacity:0;
163
+ /* ONE top-centre lane. The zoom hint, the live-event pill and the Channels
164
+ preview banner were each pinned to left:50%;top:14px, so any two of them
165
+ showing at once sat on top of each other and the block-mode nudge only
166
+ moved the collision. They stack here instead, in whatever combination is
167
+ actually on screen. */
168
+ .slm-lane{position:absolute;left:50%;top:14px;transform:translateX(-50%);z-index:6;display:flex;flex-direction:column;
169
+ align-items:center;gap:8px;max-width:min(560px,calc(100% - 32px));pointer-events:none}
170
+ /* Only what is SHOWING takes a slot: a faded-out pill left in the flow would
171
+ push the others down by its own height plus the gap. Taken out of flow
172
+ rather than display:none'd, so the fade in and out still runs. */
173
+ .slm-lane>:not(.on){position:absolute;top:0;pointer-events:none}
174
+ .slm-zoomhint{padding:6px 13px;border-radius:999px;
175
+ background:color-mix(in srgb,var(--slm-surface) 92%,transparent);color:var(--slm-text);
176
+ border:1px solid var(--slm-line);font-size:12px;font-weight:700;pointer-events:none;opacity:0;
161
177
  transition:opacity var(--slm-mo-base) var(--slm-mo-out)}
162
178
  .slm-zoomhint.on{opacity:1}
163
- .slm-liveevent{position:absolute;left:50%;top:14px;z-index:4;display:flex;align-items:center;gap:8px;max-width:min(560px,calc(100% - 32px));
179
+ .slm-liveevent{display:flex;align-items:center;gap:8px;max-width:100%;
164
180
  padding:8px 12px;border:1px solid var(--slm-line);border-radius:999px;background:color-mix(in srgb,var(--slm-surface) 92%,transparent);
165
- box-shadow:0 10px 34px rgba(0,0,0,.32);opacity:0;transform:translate(-50%,-8px);pointer-events:none;
181
+ box-shadow:0 10px 34px rgba(0,0,0,.32);opacity:0;transform:translateY(-8px);pointer-events:none;
166
182
  transition:opacity var(--slm-mo-quick) var(--slm-mo-out),transform var(--slm-mo-base) var(--slm-mo-out);
167
183
  backdrop-filter:blur(10px)}
168
- .slm-liveevent.on{opacity:1;transform:translate(-50%,0)}
169
- .slm.block-mode .slm-liveevent{top:52px}
184
+ .slm-liveevent.on{opacity:1;transform:none}
170
185
  .slm-liveeventdot{width:8px;height:8px;border-radius:50%;flex:none}.slm-liveeventcopy{min-width:0;overflow:hidden;text-overflow:ellipsis;
171
186
  white-space:nowrap;font-size:12px;font-weight:800}.slm-liveeventhint{color:var(--slm-muted);font-size:10px;white-space:nowrap}
172
187
  .slm-rail{width:320px;flex:none;border-left:1px solid var(--slm-line);display:flex;flex-direction:column;min-height:0}
@@ -187,6 +202,10 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
187
202
  .slm-legend{display:flex;flex-direction:column;gap:2px;margin-bottom:16px}
188
203
  .slm-legrow{display:flex;align-items:center;gap:9px;padding:7px 2px;border-bottom:1px solid var(--slm-line)}
189
204
  .slm-legdot{width:10px;height:10px;border-radius:50%;flex:none}
205
+ /* The status key inside a note line: a swatch, and blocked's light disc with
206
+ its cross \u2014 the same two marks the map paints. */
207
+ .slm-legmark{display:inline-block;width:9px;height:9px;border-radius:50%;vertical-align:middle}
208
+ .slm-legcross{display:inline-block;width:12px;height:12px;line-height:12px;text-align:center;border-radius:50%;background:#f1f4f9;font-size:9px;font-weight:800;vertical-align:middle}
190
209
  .slm-leglabel{flex:1;font-size:13px;font-weight:600}
191
210
  .slm-legcount{font-size:13px;font-weight:800;font-variant-numeric:tabular-nums}
192
211
 
@@ -275,6 +294,8 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
275
294
  background:var(--slm-surface);color:var(--slm-text);border:1px solid var(--slm-line);z-index:5}
276
295
  .slm-toast.on{opacity:1}
277
296
  .slm-toast.err{background:#c0392b;color:#fff;border-color:#c0392b}
297
+ /* err/ok keep their semantic grounds, and state an ink that reads on both of
298
+ them \u2014 these are states, not chrome, so they do not follow the theme. */
278
299
  .slm-toast.ok{background:#1f7a4d;color:#fff;border-color:#1f7a4d}
279
300
 
280
301
  /* control-room actions + insights */
@@ -428,12 +449,12 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
428
449
  transition:none!important;
429
450
  scroll-behavior:auto!important}
430
451
  }
431
- `;function q(){if(typeof document>"u"||document.getElementById(D))return;let h=document.createElement("style");h.id=D,h.textContent=Be,document.head.appendChild(h)}function V(h){if(typeof document>"u"||document.getElementById(N))return;let e=document.createElement("style");e.id=N,e.textContent=h,document.head.appendChild(e)}import{formatMoney as Ie}from"@seatlayer/core";function _(h){return h?h.mode:"open"}function U(h,e,t){switch(h){case"open":return null;case"hidden":return{mode:"hidden",labels:e};case"closed":return{mode:"closed",labels:e};case"timed":return{mode:"timed",revealAt:t?.revealAt??Date.now()+36e5,labels:e};case"threshold":return{mode:"threshold",thresholdPct:t?.thresholdPct??80,labels:e}}}function K(h){return new Date(h-new Date().getTimezoneOffset()*6e4).toISOString().slice(0,16)}function W(h){if(typeof h=="string"){let e=document.querySelector(h);if(!e)throw new Error(`seatmanager: container "${h}" not found`);return e}if(!(h instanceof HTMLElement))throw new Error("seatmanager: container must be a CSS selector or an HTMLElement");return h}function B(h){if(!h.startsWith("mse_"))throw new Error("seatmanager: token must be a short-lived event-scoped mse_ grant minted by your backend; tenant secret keys are unsupported in browsers")}function M(h){return h==="blocked"?"not_for_sale":h}var G=[{key:"free",label:"Free",color:"#6e7bff"},{key:"held",label:"Held",color:"#f4b740"},{key:"booked",label:"Booked",color:"#22a06b"},{key:"blocked",label:"Blocked",color:"#8b94ac"}];function Z(h,e){let t=h??{},s=e?A[e]:null,i=e==="light";return{"--slm-bg":t.background??s?.background??"#0e1017","--slm-surface":s?.surface??"#181b24","--slm-text":s?.text??"#eef1f7","--slm-muted":s?.muted??"#8b93a7","--slm-line":s?.line??"rgba(255,255,255,.09)","--slm-tint":i?"rgba(23,32,51,.05)":"rgba(255,255,255,.035)","--slm-tint-strong":i?"rgba(23,32,51,.09)":"rgba(255,255,255,.07)","--slm-accent":t.accent??(i?"#4654c8":"#6e7bff"),"--slm-accent-ink":t.accentInk??"#ffffff","--slm-font":"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif","--slm-radius":"14px"}}function Y(h){return h?A[h].map:null}function X(h,e){let t=Math.max(0,Math.round((e-h)/1e3));if(t<5)return"just now";if(t<60)return`${t}s ago`;let s=Math.round(t/60);return s<60?`${s}m ago`:`${Math.round(s/60)}h ago`}function C(h,e){return Ie(h,e,{maximumFractionDigits:0,fallback:(t,s)=>`${s} ${Math.round(t).toLocaleString()}`})}function p(h){return String(h??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}import{UNGROUPED_ID as ze}from"@seatlayer/core";function I(h){return Object.entries(h).filter(([,e])=>e.mode==="closed").map(([e])=>e)}function E(h){let e=h.sectionsBase;if(!e)return{rows:[],hiddenSections:0,closedSections:0};let t=h.doc?.zones??[],s=new Map,i=[];for(let c of e.sections)if(c.zone&&t.some(n=>n.id===c.zone)){let n=s.get(c.zone)??[];n.push(c),s.set(c.zone,n)}else i.push(c);let a=[],o=0,l=0,r=(c,n,d,m=!1)=>{let b=h.availabilityRules[n.id]??null,g=h.effectiveClosed.has(n.id)||m,v=h.effectiveHidden.has(n.id)||d&&!g;c==="section"&&v&&(o+=1),c==="section"&&g&&(l+=1),a.push({kind:c,id:n.id,label:n.label,seatCount:n.seatCount,seatLabels:n.seatLabels,rule:b,hidden:v,closed:g,followsZone:c==="section"&&d})};for(let c of t){let n=s.get(c.id);if(!n||!n.length)continue;let d={id:c.id,label:c.label||"Zone",seatCount:n.reduce((g,v)=>g+v.seatCount,0),seatLabels:n.flatMap(g=>g.seatLabels)},m=!!h.availabilityRules[c.id],b=h.availabilityRules[c.id]?.mode==="closed";r("zone",d,!1);for(let g of n)r("section",g,m,b)}for(let c of i)r("section",c,!1);if(e.ungrouped){let c=e.ungrouped;r("section",{id:ze,label:c.label,seatCount:c.seatCount,seatLabels:c.seatLabels},!1)}return{rows:a,hiddenSections:o,closedSections:l}}function Q(h,e){let t=_(h.rule),s=`slm-availrow${h.kind==="zone"?" zone":""}${h.hidden?" hidden":""}${h.closed?" closed":""}`,i=e?" disabled":"",a=[["open","Open","Available to buy"],["closed","Closed","Visible on the map, unavailable to buy"],["hidden","Hidden","Removed from the buyer map"],["timed","Scheduled reveal","Open at a specific date and time"],["threshold","Demand-based reveal","Open when sales reach a percentage"]],o=h.followsZone?'<span class="slm-availfollows">Follows zone</span>':`<details class="slm-availpicker" data-avail-picker>
452
+ `;function V(){if(typeof document>"u"||document.getElementById(q))return;let h=document.createElement("style");h.id=q,h.textContent=Oe,document.head.appendChild(h)}function U(h){if(typeof document>"u"||document.getElementById(_))return;let e=document.createElement("style");e.id=_,e.textContent=h,document.head.appendChild(e)}import{formatMoney as Fe}from"@seatlayer/core";function K(h){return h?h.mode:"open"}function G(h,e,t){switch(h){case"open":return null;case"hidden":return{mode:"hidden",labels:e};case"closed":return{mode:"closed",labels:e};case"timed":return{mode:"timed",revealAt:t?.revealAt??Date.now()+36e5,labels:e};case"threshold":return{mode:"threshold",thresholdPct:t?.thresholdPct??80,labels:e}}}function W(h){return new Date(h-new Date().getTimezoneOffset()*6e4).toISOString().slice(0,16)}function Z(h){if(typeof h=="string"){let e=document.querySelector(h);if(!e)throw new Error(`seatmanager: container "${h}" not found`);return e}if(!(h instanceof HTMLElement))throw new Error("seatmanager: container must be a CSS selector or an HTMLElement");return h}function I(h){if(!h.startsWith("mse_"))throw new Error("seatmanager: token must be a short-lived event-scoped mse_ grant minted by your backend; tenant secret keys are unsupported in browsers")}function E(h){return h==="blocked"?"not_for_sale":h}var je=["free","booked","held","blocked"],y={free:"#6e7bff",booked:"#9ca3af",held:"#f4b740",blocked:"#475569"},C={free:"Free",booked:"Sold",held:"Held",blocked:"Blocked"},Y=[`<span class="slm-legmark" style="background:${y.free}"></span> Free = category colour`,`<span class="slm-legmark" style="background:${y.booked}"></span> ${C.booked}`,`<span class="slm-legmark" style="background:${y.held}"></span> ${C.held}`,`<span class="slm-legcross" style="color:${y.blocked}">\u2715</span> ${C.blocked}`].join(" \xB7 "),X=je.map(h=>({key:h,label:C[h],color:y[h]}));function Q(h,e){let t=h??{},s=e?H[e]:null,i=e==="light";return{"--slm-bg":t.background??s?.background??"#0e1017","--slm-surface":s?.surface??"#181b24","--slm-text":s?.text??"#eef1f7","--slm-muted":s?.muted??"#8b93a7","--slm-line":s?.line??"rgba(255,255,255,.09)","--slm-tint":i?"rgba(23,32,51,.05)":"rgba(255,255,255,.035)","--slm-tint-strong":i?"rgba(23,32,51,.09)":"rgba(255,255,255,.07)","--slm-accent":t.accent??(i?"#4654c8":"#6e7bff"),"--slm-accent-ink":t.accentInk??"#ffffff","--slm-font":"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif","--slm-radius":"14px"}}function J(h){return h?H[h].map:null}function ee(h,e){let t=Math.max(0,Math.round((e-h)/1e3));if(t<5)return"just now";if(t<60)return`${t}s ago`;let s=Math.round(t/60);return s<60?`${s}m ago`:`${Math.round(s/60)}h ago`}function R(h,e){return Fe(h,e,{maximumFractionDigits:0,fallback:(t,s)=>`${s} ${Math.round(t).toLocaleString()}`})}function p(h){return String(h??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}import{UNGROUPED_ID as Pe}from"@seatlayer/core";function O(h){return Object.entries(h).filter(([,e])=>e.mode==="closed").map(([e])=>e)}function A(h){let e=h.sectionsBase;if(!e)return{rows:[],hiddenSections:0,closedSections:0};let t=h.doc?.zones??[],s=new Map,i=[];for(let c of e.sections)if(c.zone&&t.some(n=>n.id===c.zone)){let n=s.get(c.zone)??[];n.push(c),s.set(c.zone,n)}else i.push(c);let a=[],o=0,l=0,r=(c,n,d,m=!1)=>{let b=h.availabilityRules[n.id]??null,g=h.effectiveClosed.has(n.id)||m,v=h.effectiveHidden.has(n.id)||d&&!g;c==="section"&&v&&(o+=1),c==="section"&&g&&(l+=1),a.push({kind:c,id:n.id,label:n.label,seatCount:n.seatCount,seatLabels:n.seatLabels,rule:b,hidden:v,closed:g,followsZone:c==="section"&&d})};for(let c of t){let n=s.get(c.id);if(!n||!n.length)continue;let d={id:c.id,label:c.label||"Zone",seatCount:n.reduce((g,v)=>g+v.seatCount,0),seatLabels:n.flatMap(g=>g.seatLabels)},m=!!h.availabilityRules[c.id],b=h.availabilityRules[c.id]?.mode==="closed";r("zone",d,!1);for(let g of n)r("section",g,m,b)}for(let c of i)r("section",c,!1);if(e.ungrouped){let c=e.ungrouped;r("section",{id:Pe,label:c.label,seatCount:c.seatCount,seatLabels:c.seatLabels},!1)}return{rows:a,hiddenSections:o,closedSections:l}}function te(h,e){let t=K(h.rule),s=`slm-availrow${h.kind==="zone"?" zone":""}${h.hidden?" hidden":""}${h.closed?" closed":""}`,i=e?" disabled":"",a=[["open","Open","Available to buy"],["closed","Closed","Visible on the map, unavailable to buy"],["hidden","Hidden","Removed from the buyer map"],["timed","Scheduled reveal","Open at a specific date and time"],["threshold","Demand-based reveal","Open when sales reach a percentage"]],o=h.followsZone?'<span class="slm-availfollows">Follows zone</span>':`<details class="slm-availpicker" data-avail-picker>
432
453
  <summary aria-label="Availability for ${p(h.label)}" ${e?'aria-disabled="true"':""}>${a.find(n=>n[0]===t)[1]}<span aria-hidden="true">\u2304</span></summary>
433
454
  <div class="slm-availchoices" aria-label="Availability options for ${p(h.label)}">
434
455
  ${a.map(([n,d,m])=>`<button type="button" data-avail-id="${p(h.id)}" data-avail-value="${n}" aria-pressed="${t===n}"${i}><span><b>${d}</b><small>${m}</small></span><span aria-hidden="true">${t===n?"\u2713":""}</span></button>`).join("")}
435
456
  </div>
436
- </details>`,l="";if(!h.followsZone&&t==="timed"){let n=h.rule?.revealAt?p(K(h.rule.revealAt)):"";l=`<div class="slm-availdetail">
457
+ </details>`,l="";if(!h.followsZone&&t==="timed"){let n=h.rule?.revealAt?p(W(h.rule.revealAt)):"";l=`<div class="slm-availdetail">
437
458
  <input type="datetime-local" class="slm-input" data-avail-reveal="${p(h.id)}" value="${n}"${i} aria-label="Reveal time for ${p(h.label)}" />
438
459
  </div>`}else if(!h.followsZone&&t==="threshold"){let n=h.rule?.thresholdPct??80;l=`<div class="slm-availdetail">
439
460
  <span class="slm-availpctlabel">Reveal at</span>
@@ -447,12 +468,12 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
447
468
  </div>
448
469
  ${o}
449
470
  ${l}
450
- </div>`}var Ne="https://api.seatlayer.io",R=200,ee=16,te=4,se=[{key:"watch",label:"Watch",tools:[{mode:"view",label:"Monitor",shortcut:"M",title:"Live board \u2014 inventory, activity and booking momentum. Read-only."},{mode:"inspect",label:"Inspect",shortcut:"I",title:"Click one seat to read its live status and booking context. Read-only."}]},{key:"manage",label:"Manage",tools:[{mode:"block",label:"Block",shortcut:"B",title:"Take seats off sale for this event, or put them back."},{mode:"sections",label:"Sections",shortcut:"S",title:"Open, close or hide sections for this event, on a schedule or on demand."},{mode:"categories",label:"Categories",shortcut:"G",title:"Move seats to a different price category for this event only."},{mode:"tables",label:"Tables",shortcut:"T",title:"Sell each table per chair or as one whole-table booking."},{mode:"channels",label:"Channels",shortcut:"C",title:"Allocate inventory to sales channels and share their links."}]},{key:"host",label:"Host tools",tools:[{mode:"select",label:"Select",shortcut:"X",title:"Select seats for your own back-office operation. The selection is handed to your app; nothing changes here."},{mode:"filterSections",label:"Filter",shortcut:"L",title:"Filter the map to one section for your own reporting."}]}],qe=Object.fromEntries(se.flatMap(h=>h.tools.map(e=>[e.shortcut.toLowerCase(),e.mode]))),z=class{constructor(e){this.els={};this.renderer=null;this.doc=null;this.selectObserver=null;this.seatHistoryPanel=null;this.activityPanel=null;this.navigation=null;this.movingMap=!1;this.socketSnapshotSeen=!1;this.monitorRefreshTimer=null;this.themeMode=null;this.colorSchemeStop=null;this.inventoryModelVersion=1;this.selectableObjectLabels=new Set;this.lastSelectionLabels=new Set;this.selectionWasValid=null;this.initialSelectionApplied=!1;this.labelToId=new Map;this.labelToSeat=new Map;this.allIds=[];this.gaUnitLabelSet=new Set;this.status=new Map;this.counts={held:0,booked:0,blocked:0};this.modelVersion=0;this.currency="USD";this.authoritativeCurrency=null;this.authoritativeGrossRevenue=0;this.revenueStatus="loading";this.revenueRequest=0;this.controlRoomSnapshot=null;this.serverBaseline=null;this.livePresence=null;this.liveGross=null;this.paintHandle=null;this.trendWindowMinutes=15;this.heatEnabled=!1;this.lastKpiValues=new Map;this.activeKpiDeltas=new Map;this.ws=null;this.reconnectTimer=null;this.attempt=0;this.closed=!1;this.connectionStatus="reconnecting";this.lastMessageAt=null;this.ready=!1;this.feed=[];this.feedTimer=null;this.toastTimer=null;this.liveEventTimer=null;this.kpiCleanupTimer=null;this.followLiveTimer=null;this.followSeatTimer=null;this.releaseAt=null;this.layoutObserver=null;this.tokenExpiresAt=null;this.tokenRefreshTimer=null;this.tokenRefreshInFlight=!1;this.sectionByObject=new Map;this.sectionLabelById=new Map;this.sectionsBase=null;this.filteredSectionLabel=null;this.availabilityRules={};this.effectiveHidden=new Set;this.effectiveClosed=new Set;this.availabilitySaving=!1;this.lastSyncedAt=null;this.blockBrowse=!1;this.blockedQuery="";this.blockedSection="";this.blockedResultLimit=100;this.unblockAllConfirmTimer=null;this.channels=null;this.channelCaps={view:!1,manage:!1};this.categoryCanManage=!1;this.tableCanManage=!1;this.tableBookingSaving=!1;this.channelCapabilityResolution=0;this.channelsLoading=null;this.onFullscreenChange=()=>{this.paintFullscreenButton(),this.updateContainerLayout(),this.renderer?.forceDraw()};this.onKeyDown=e=>{if(e.metaKey||e.ctrlKey||e.altKey||e.target?.matches('input,select,textarea,[contenteditable="true"]'))return;let s=e.key.toLowerCase(),i=qe[s];if(i){if(!this.toolAvailable(i))return;this.setMode(i)}else if(s==="f")this.toggleFullscreen();else if(s==="escape"){if(!this.channels?.handleBack())return}else return;e.preventDefault()};this.onRailClick=e=>{let t=e.target,s=t?.closest("[data-section-focus]");if(s?.dataset.sectionFocus){this.locateSection(s.dataset.sectionFocus);return}let i=t?.closest("[data-feed-id]");i?.dataset.feedId&&this.locateActivity(i.dataset.feedId)};this.sectionOptions=[];B(e.token),this.assertSelectionOptions(e.maxSelectedObjects,e.numberOfPlacesToSelect),this.opts=e,this.key=e.eventKey,this.mode=e.mode??"view",this.selectableObjectLabels=new Set(e.selectableObjects??[]),this.categoryCanManage=new Set(e.capabilities??[]).has("event:categories:manage"),this.tableCanManage=new Set(e.capabilities??[]).has("event:tables:manage"),this.keepLive=e.keepLiveWhileHidden??!0,this.themeMode=e.themeMode??null,this.followLive=e.followLive??!1,this.currency=e.currency??"USD",this.tokenExpiresAt=e.tokenExpiresAt??null,this.api=new H(e.apiBase??Ne,e.token),this.organizerAssetUrls=new T(this.key,(t,s)=>this.withAuthRetry(()=>this.api.asset(t,s))),this.host=W(e.container)}assertSelectionOptions(e,t){let s=i=>i===void 0||Number.isInteger(i)&&i>0;if(!s(e))throw new TypeError("maxSelectedObjects must be a positive integer");if(!s(t))throw new TypeError("numberOfPlacesToSelect must be a positive integer");if(e!==void 0&&t!==void 0&&e<t)throw new TypeError("maxSelectedObjects cannot be lower than numberOfPlacesToSelect")}async render(){q(),this.buildChrome();try{let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1,this.doc=await this.organizerAssetUrls.prepareRendererChart(e.doc),this.authoritativeCurrency=e.event.currency??null,this.currency=this.authoritativeCurrency??this.opts.currency??this.currency,this.buildUnitUniverse(this.doc),this.buildRenderer(),this.buildSectionOptions(),this.settleMode();let[,t]=await Promise.all([this.resnapshot(),this.refreshControlRoom().catch(s=>this.opts.onError?.(s)),this.refreshAvailability()]);t?.activity?this.seedFeed(t.activity):this.api.log(this.key,{limit:24}).then(s=>this.seedFeed(s.entries)).catch(()=>{}),this.connect(),this.startFeedClock(),this.ready=!0,await this.resolveChannelCapabilities(),this.setMode(this.mode),this.applyInitialSelection(),this.scheduleTokenRefresh(),this.opts.onReady?.()}catch(e){this.fail(e)}return this}setMode(e){this.toolAvailable(e)||(e="view"),e==="channels"&&!this.channels&&this.ensureChannels();let t=e!==this.mode,s=this.mode==="channels",i=this.mode==="filterSections";this.mode=e,t&&e!=="view"&&this.setFollowLive(!1),!this.renderer&&this.doc?this.buildRenderer():this.updateRendererInteraction(),t&&(this.renderer?.clearSelection(),this.syncSelection()),s&&e!=="channels"&&this.channels?.leave(),this.paintModeTabs(),this.paintRail(),this.applySectionCanvasTreatment(),i&&e!=="filterSections"&&this.renderer?.zoomToFit(),e==="channels"&&this.channels?.enter(),e==="select"&&this.applyInitialSelection(),t&&this.opts.onModeChange?.(e)}async resolveChannelCapabilities(){let e=++this.channelCapabilityResolution,t=this.opts.capabilities,s;if(t){let i=new Set(t);s={view:i.has("event:channels:view"),manage:i.has("event:channels:view")&&i.has("event:channels:manage")}}else s={view:!1,manage:!1};if(!s.view&&!t)try{await this.api.channels(this.key),s={view:!0,manage:!1}}catch{s={view:!1,manage:!1}}if(e===this.channelCapabilityResolution){if(this.channelCaps=s,!this.channelCaps.view){this.channels?.destroy(),this.channels=null,this.mode==="channels"?this.setMode("view"):this.paintModeTabs();return}this.channels?.setCapabilities(this.channelCaps),this.paintModeTabs()}}ensureChannels(){if(this.channelsLoading)return this.channelsLoading;if(this.channels)return Promise.resolve();let e=(async()=>{try{let t=await import("./channelsMode-JQPW2SVE.js");if(this.closed||!this.channelCaps.view||(this.channels||(V(t.CHANNELS_CSS),this.channels=new t.ChannelsMode(this.buildChannelsHost(),this.channelCaps),this.channels.onInteractionChange=()=>this.updateRendererInteraction()),this.mode!=="channels"))return;this.updateRendererInteraction(),this.paintRail(),this.channels.enter()}catch(t){if(this.closed)return;this.channelsLoading=null,this.mode==="channels"&&this.paintRail(),this.opts.onError?.(t)}})();return this.channelsLoading=e,e}buildChannelsHost(){return{eventKey:this.key,api:this.api,rail:this.els.rail,mapLayer:this.root.querySelector(".slm-map"),root:this.root,seats:()=>[...this.labelToSeat.values()].map(e=>({id:e.id,label:e.label,x:e.x,y:e.y})),statusOf:e=>this.status.get(e)??(this.labelToSeat.has(e)?"free":void 0),selectionLabels:()=>this.selectionLabels(),selectByLabels:e=>{this.selectByLabels(e)},clearSelection:()=>this.clearSelection(),selectSection:e=>{this.selectSection(e)},sections:()=>this.sectionOptions,labelsInSection:e=>this.renderer?.getSelectableInSection(e).map(t=>t.label)??[],rows:()=>{let e=new Map((this.doc?.objects??[]).map(s=>[s.id,s])),t=new Map;for(let s of this.labelToSeat.values()){let i=e.get(s.rowId);if(!i||i.type!=="row"&&i.type!=="table")continue;let a=s.logicalRowId??s.rowId,o=this.sectionByObject.get(s.rowId)??y,l=t.get(a)??{id:a,label:i.type==="row"?i.segmentedRow?.displayLabel??i.displayLabel??i.label:i.displayLabel??i.label,sectionId:o,sectionLabel:this.sectionLabelById.get(o)??"Other seats",labels:[]};l.labels.push(s.label),t.set(a,l)}return[...t.values()].sort((s,i)=>s.sectionLabel.localeCompare(i.sectionLabel,void 0,{numeric:!0,sensitivity:"base"})||s.label.localeCompare(i.label,void 0,{numeric:!0,sensitivity:"base"}))},categories:()=>(this.doc?.categories??[]).map(e=>({key:e.key,label:e.label??e.key,color:e.color,price:e.price,tiers:e.tiers?.map(t=>({id:t.id,name:t.name,price:t.price}))})),labelsInCategory:e=>[...this.labelToSeat.entries()].filter(([,t])=>t.categoryKey===e).map(([t])=>t),sectionOfLabel:e=>{let t=this.labelToSeat.get(e);if(!t)return null;let s=this.sectionByObject.get(t.rowId)??y;return{id:s,label:this.sectionLabelById.get(s)??"Other seats"}},worldToScreen:e=>this.renderer?.worldToScreen(e)??null,seatPixelSize:()=>this.seatPixelSize(),isSeatDetail:()=>this.renderer?.getRung?.()==="seats",showSectionOverview:()=>{this.renderer?.clearSectionFocus(),this.renderer?.setRung?.("sections")},focusSection:e=>this.renderer?.focusSection(e),isCompact:()=>!!this.root?.classList.contains("compact"),setMapInert:e=>{this.mapHost.toggleAttribute("inert",e),this.mapHost.setAttribute("aria-hidden",String(e))},toast:(e,t)=>this.toast(e,t),onError:e=>this.opts.onError?.(e)}}seatPixelSize(){let e=this.renderer?.getVisibleWorldRect?.(),t=this.mapHost?.clientWidth??0;return!e?.width||!t?6:Math.max(3,t/e.width*18)}setHeatOverlay(e){this.heatEnabled=e,this.applyHeatOverlay(),this.paintHeatButton()}setFollowLive(e){let t=this.followLive!==e;this.followLive=e,e||(this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=null,this.followSeatTimer=null),this.paintFollowLiveButton(),t&&this.opts.onFollowLiveChange?.(e)}setKeepLiveWhileHidden(e){this.keepLive=e??!0,this.opts.keepLiveWhileHidden=e}setCurrency(e){this.opts.currency=e,!this.authoritativeCurrency&&(this.currency=e??"USD",this.ready&&this.recomputeTallies())}setTheme(e){this.opts.theme=e,this.applyThemeVars()}applyThemeVars(){if(!this.root)return;let e=$(this.themeMode);for(let[t,s]of Object.entries(Z(this.opts.theme,e)))this.root.style.setProperty(t,s);e?this.root.dataset.theme=e:delete this.root.dataset.theme}watchThemeMode(){this.colorSchemeStop?.(),this.colorSchemeStop=null,this.themeMode==="auto"&&(this.colorSchemeStop=O(()=>{this.closed||this.repaintForThemeMode()}))}repaintForThemeMode(){this.applyThemeVars();let e=this.renderer;if(!e||!this.doc)return;let t=e.getSelection().map(a=>a.id),s=e.getCameraPose(),i=e.getFocusedSection();e.setChart(this.themedDoc()),this.repaintAll(),this.applyHeatOverlay(),t.length&&e.select(t),i&&e.focusSection(i),e.setCameraPose(s),this.updateZoomHint()}setThemeMode(e){let t=e??null;this.closed||t===this.themeMode||(this.themeMode=t,this.opts.themeMode=t??void 0,this.watchThemeMode(),this.repaintForThemeMode())}getThemeMode(){return this.themeMode}themedDoc(){let e=this.doc,t=Y($(this.themeMode));return t?{...e,theme:{...e.theme??{},background:t}}:e}setCapabilities(e){this.opts.capabilities=e,this.categoryCanManage=new Set(e??[]).has("event:categories:manage"),this.tableCanManage=new Set(e??[]).has("event:tables:manage"),!this.categoryCanManage&&this.mode==="categories"||!this.tableCanManage&&this.mode==="tables"?this.setMode("view"):this.paintModeTabs(),this.ready&&this.resolveChannelCapabilities()}setTokenRefresh(e){this.opts.onTokenRefresh=e,this.scheduleTokenRefresh()}setTrendWindow(e){let t=Number.isFinite(e)?Math.floor(e):15;return this.trendWindowMinutes=Math.max(5,Math.min(60,t)),this.paintTrendWindow(),this.refreshControlRoom()}async enterFullscreen(){!this.root?.requestFullscreen||this.isFullscreen()||(await this.root.requestFullscreen(),this.root.focus({preventScroll:!0}))}async exitFullscreen(){typeof document>"u"||!this.isFullscreen()||await document.exitFullscreen()}isFullscreen(){return typeof document<"u"&&document.fullscreenElement===this.root}toggleFullscreen(){(this.isFullscreen()?this.exitFullscreen():this.enterFullscreen()).catch(t=>this.opts.onError?.(t))}setToken(e,t){B(e),this.api.setToken(e),this.opts.token=e,this.opts.tokenExpiresAt=t,this.tokenExpiresAt=t??null,this.scheduleTokenRefresh(),this.ready&&this.resolveChannelCapabilities()}scheduleTokenRefresh(){this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.tokenRefreshTimer=null;let e=this.opts.onTokenRefresh,t=this.tokenExpiresAt;if(this.closed||!e||!t||!Number.isFinite(t))return;let s=t-Date.now(),i=Math.min(12e4,Math.max(3e4,s*.2)),a=Math.max(0,s-i);this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},a)}async rotateToken(){if(!(this.closed||this.tokenRefreshInFlight||!this.opts.onTokenRefresh)){this.tokenRefreshInFlight=!0;try{let e=await this.opts.onTokenRefresh();if(!e?.token||!Number.isFinite(e.expiresAt))throw new Error("invalid_token_refresh_result");this.setToken(e.token,e.expiresAt)}catch(e){this.opts.onError?.(e),this.closed||(this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},3e4))}finally{this.tokenRefreshInFlight=!1}}}async block(e,t={}){let s=(e??this.selectionLabels()).filter(a=>this.status.get(a)==="free");if(!s.length)return;let i=t.releaseAt??this.releaseAt??void 0;this.setSeatsLocal(s,"blocked");try{await this.api.block(this.key,s,{...t,releaseAt:i}),this.clearSelection(),this.done("block",s,i?`Blocked ${s.length} \u2014 auto-release ${new Date(i).toLocaleString()}.`:`Blocked ${s.length} seat${s.length===1?"":"s"}.`)}catch(a){this.setSeatsLocal(s,"free"),this.toastErr(a instanceof k&&a.status===409?"Some seats were just taken. Try again.":"Couldn't block those seats."),this.opts.onError?.(a)}}async unblock(e){let t=(e??this.selectionLabels()).filter(s=>this.status.get(s)==="blocked");if(t.length){this.setSeatsLocal(t,"free");try{await this.api.unblock(this.key,t),this.clearSelection(),this.done("unblock",t,`Unblocked ${t.length} seat${t.length===1?"":"s"}.`)}catch(s){this.setSeatsLocal(t,"blocked"),this.toastErr("Couldn't unblock those seats."),this.opts.onError?.(s)}}}async unblockAll(){let e=[...this.status.entries()].filter(([,t])=>t==="blocked").map(([t])=>t);if(e.length){this.setSeatsLocal(e,"free");try{let t=await this.api.unblockAll(this.key);this.clearSelection(),this.done("unblockAll",e,`Unblocked ${t.freed} seat${t.freed===1?"":"s"}.`)}catch(t){await this.resnapshot(),this.toastErr("Couldn't mark everything for sale."),this.opts.onError?.(t)}}}async cancelBooking(e,t){let s=e.filter(i=>this.status.get(i)==="booked");if(!(!s.length||!t)){this.setSeatsLocal(s,"free");try{await this.api.unbook(this.key,s,t),this.clearSelection(),this.done("cancelBooking",s,`Released ${s.length} booked unit${s.length===1?"":"s"}.`)}catch(i){this.setSeatsLocal(s,"booked"),this.toastErr("Couldn't release that booked inventory. Check the booking reference."),this.opts.onError?.(i)}}}async setCategory(e,t){let s=this.doc?.categories.find(a=>a.key===e),i=[...new Set(t??this.selectionLabels())].filter(a=>this.labelToSeat.has(a));if(!(!s||!i.length))try{let a=await this.withAuthRetry(()=>this.api.setCategory(this.key,i,e)),o={};for(let l of a.labels){let r=this.labelToSeat.get(l),c=this.labelToId.get(l);r&&(r.categoryKey=e),c&&(o[c]=e)}this.renderer?.setSeatCategories?.(o),this.clearSelection(),this.done("setCategory",a.labels,`Assigned ${a.labels.length.toLocaleString()} object${a.labels.length===1?"":"s"} to ${s.label??s.key}.`)}catch(a){this.toastErr("Couldn't update those event categories."),this.opts.onError?.(a)}}async setTableBooking(e,t,s={}){let i=[...new Set(e)].filter(Boolean);if(!(!i.length||this.tableBookingSaving)){if(this.inventoryModelVersion!==2){this.toastErr("Table booking controls require inventory model 2 for this event.");return}this.tableBookingSaving=!0,this.mode==="tables"&&this.renderTablesRail();try{let a=await this.withAuthRetry(()=>this.api.setTableBooking(this.key,i,t,s));await this.reloadEventChart(),this.done("setTableBooking",a.tableIds,`Updated ${a.tableIds.length.toLocaleString()} table${a.tableIds.length===1?"":"s"} to ${t==="individual"?"per-chair":t==="whole"?"whole-table":"flexible-group"} booking.`)}catch(a){let o=a instanceof k&&a.code==="table_inventory_in_use";this.toastErr(o?"Release held, booked, or blocked table inventory before changing its booking mode.":"Couldn't update table booking. No table mode was changed."),this.opts.onError?.(a)}finally{this.tableBookingSaving=!1,this.mode==="tables"&&this.renderTablesRail()}}}async reloadEventChart(){let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1;let t=await this.organizerAssetUrls.prepareRendererChart(e.doc);this.renderer?.destroy(),this.renderer=null,this.doc=t,this.labelToId.clear(),this.labelToSeat.clear(),this.allIds=[],this.gaUnitLabelSet.clear(),this.status.clear(),this.counts={held:0,booked:0,blocked:0},this.serverBaseline=null,this.lastSelectionLabels.clear(),this.buildUnitUniverse(t),this.buildRenderer(),this.buildSectionOptions(),this.settleMode(),await Promise.all([this.resnapshot(),this.refreshAvailability()]),this.paintRail()}selectAll(){if(this.mode==="select")return this.selectByLabels([...this.labelToSeat.values()].filter(t=>this.canSelectObject(t)).map(t=>t.label));let e=this.renderer?.selectAllSelectable()??[];return this.syncSelection(),e}selectSection(e){if(!this.renderer)return[];let t=this.renderer.getSelectableInSection(e);return this.renderer.selectByLabels(t.map(s=>s.label)),this.syncSelection(),this.renderer.getSelection()}setFilteredSection(e){let t=e.trim(),s=this.filterableSections().filter(o=>o.label===t);if(!s.length)throw new Error(`Unknown event section: ${e}`);let i=t!==this.filteredSectionLabel;this.filteredSectionLabel=t,this.mode==="filterSections"&&(this.applyFilteredSectionCanvas(s),this.renderFilterSectionsRail());let a=s.map(({id:o,label:l,seatCount:r,zone:c})=>({id:o,label:l,seatCount:r,...c?{zone:c}:{}}));return i&&this.opts.onFilteredSectionChange?.(a),a}clearFilteredSection(){let e=this.filteredSectionLabel!==null;this.filteredSectionLabel=null,this.renderer?.setDimmedSections(null),this.renderer?.clearSectionFocus(),this.renderer?.zoomToFit(),this.mode==="filterSections"&&this.renderFilterSectionsRail(),e&&this.opts.onFilteredSectionChange?.([])}getFilteredSections(){return this.filteredSectionLabel?this.filterableSections().filter(e=>e.label===this.filteredSectionLabel).map(({id:e,label:t,seatCount:s,zone:i})=>({id:e,label:t,seatCount:s,...i?{zone:i}:{}})):[]}selectByLabels(e){let t=e;if(this.mode==="select"){let s=new Set(this.selectionLabels()),i=this.selectionCap(),a=[...new Set(e)].filter(l=>!s.has(l)).map(l=>this.labelToSeat.get(l)).filter(l=>!!l&&this.canSelectObject(l)),o=Math.max(0,i-s.size);a.length>o&&this.opts.onSelectionLimit?.(i),t=a.slice(0,o).map(l=>l.label)}return this.renderer?.selectByLabels(t),this.syncSelection(),this.getSelection()}selectObjects(e){return this.selectByLabels(e)}deselectObjects(e){let t=e.map(s=>this.labelToId.get(s)).filter(s=>!!s);return this.renderer?.deselect(t),this.syncSelection(),this.getSelection()}selectCategories(e){let t=new Set(e);return this.selectByLabels([...this.labelToSeat.values()].filter(s=>t.has(s.categoryKey)).map(s=>s.label))}deselectCategories(e){let t=new Set(e);return this.deselectObjects(this.getSelection().filter(s=>t.has(s.categoryKey)).map(s=>s.label))}setSelectableObjects(e){this.opts.selectableObjects=[...e],this.selectableObjectLabels=new Set(e),this.reconcileSelectPolicy()}setUnavailableObjectsSelectable(e){this.opts.unavailableObjectsSelectable=e,this.reconcileSelectPolicy()}setObjectSelectable(e){this.opts.isObjectSelectable=e,this.reconcileSelectPolicy()}setMaxSelectedObjects(e){this.assertSelectionOptions(e,this.opts.numberOfPlacesToSelect),this.opts.maxSelectedObjects=e,this.trimSelectionToCap(),this.updateRendererInteraction(),this.syncSelection()}setNumberOfPlacesToSelect(e){this.assertSelectionOptions(this.opts.maxSelectedObjects,e),this.opts.numberOfPlacesToSelect=e,this.selectionWasValid=null,this.trimSelectionToCap(),this.updateRendererInteraction(),this.syncSelection()}getSelectionValidity(){let e=this.opts.numberOfPlacesToSelect;if(e===void 0)return null;let t=this.getSelection(),s=t.length;return{isValid:s===e,count:s,required:e,remaining:Math.max(0,e-s),objects:t}}clearSelection(){this.renderer?.clearSelection(),this.syncSelection()}getSelection(){return this.renderer?.getSelection()??[]}getReport(){return this.api.report(this.key).then(e=>(this.applyReportRevenue(e),e))}getControlRoomSnapshot(e=this.trendWindowMinutes){return this.setTrendWindow(e)}getConnection(){return{status:this.connectionStatus,lastMessageAt:this.lastMessageAt}}getLog(e={}){return this.api.log(this.key,e)}async setHoldTtl(e){try{await this.api.setHoldTtl(this.key,e),this.done("setHoldTtl",[],e?`Hold window set to ${Math.round(e/6e4)} min.`:"Hold window reset.")}catch(t){this.toastErr("Couldn't update the hold window."),this.opts.onError?.(t)}}zoomToFit(){if(this.mode==="filterSections"&&this.filteredSectionLabel){this.clearFilteredSection();return}this.renderer?.clearSectionFocus(),this.renderer?.zoomToFit()}destroy(){if(this.selectObserver?.disconnect(),this.closed=!0,this.monitorRefreshTimer&&clearTimeout(this.monitorRefreshTimer),this.monitorRefreshTimer=null,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.feedTimer&&clearInterval(this.feedTimer),this.toastTimer&&clearTimeout(this.toastTimer),this.liveEventTimer&&clearTimeout(this.liveEventTimer),this.kpiCleanupTimer&&clearTimeout(this.kpiCleanupTimer),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.paintHandle!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.paintHandle),this.paintHandle=null,this.channels?.destroy(),this.channels=null,this.channelsLoading=null,this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.layoutObserver?.disconnect(),this.layoutObserver=null,this.colorSchemeStop?.(),this.colorSchemeStop=null,this.root?.removeEventListener("keydown",this.onKeyDown),this.els.rail?.removeEventListener("click",this.onRailClick),typeof document<"u"&&document.removeEventListener("fullscreenchange",this.onFullscreenChange),this.ws){try{this.ws.close()}catch{}this.ws=null}this.seatHistoryPanel?.destroy(),this.seatHistoryPanel=null,this.activityPanel?.destroy(),this.activityPanel=null,this.navigation?.destroy(),this.navigation=null,this.renderer?.destroy(),this.renderer=null,this.organizerAssetUrls.dispose(),this.root&&this.root.parentNode===this.host&&this.host.removeChild(this.root)}buildRenderer(){if(!this.doc)return;let e=this.isBulkSelectMode();this.renderer=new Oe(this.mapHost,{manageMode:!0,marqueeSelect:e&&!this.movingMap,maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses(),currency:this.currency,onSelect:t=>this.handleSeatSelect(t),onDeselect:()=>this.syncSelection(),onSelectionLimit:t=>this.opts.onSelectionLimit?.(t),onMarquee:()=>this.syncSelection(),onSectionTap:t=>{if(this.mode==="filterSections"){let s=this.filterableSections().find(i=>i.id===t);s&&this.setFilteredSection(s.label);return}this.renderer?.focusSection(t),this.channels?.handleSectionFocus(t)},onViewChange:()=>{this.updateZoomHint(),this.channels?.handleViewChange()}}),this.renderer.setChart(this.themedDoc()),this.repaintAll(),this.applyHeatOverlay(),this.updateZoomHint()}isBulkSelectMode(){return this.mode==="block"||this.mode==="categories"||this.mode==="channels"&&this.channels?.usesMarqueeSelection()===!0}selectableStatuses(){return this.mode==="block"?["free","not_for_sale"]:this.mode==="select"||this.mode==="categories"||this.mode==="inspect"||this.isBulkSelectMode()||this.mode==="channels"&&this.channels?.canSelect()===!0?["free","held","booked","not_for_sale"]:[]}updateRendererInteraction(){let e=this.isBulkSelectMode();this.renderer?.setManageInteraction({manageMode:!0,organizerStatus:this.mode!=="channels",marqueeSelect:e&&!this.movingMap,maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses()}),this.navigation?.update(e,this.mode==="view"),this.updateZoomHint()}handleSeatSelect(e){if(this.mode==="select"&&!this.canSelectObject(e)){this.renderer?.deselect([e.id]),this.syncSelection();return}if(this.mode==="inspect"){let t=this.getSelection().filter(s=>s.id!==e.id).map(s=>s.id);t.length&&this.renderer?.deselect(t)}this.syncSelection()}buildUnitUniverse(e){for(let t of Fe(e))this.labelToId.set(t.label,t.id),this.labelToSeat.set(t.label,t),this.allIds.push(t.id);for(let t of Pe(e))for(let s of De(t))this.labelToId.has(s)||this.gaUnitLabelSet.add(s)}unitTotal(){return this.allIds.length+this.gaUnitLabelSet.size}knownLabels(){return[...this.labelToId.keys(),...this.gaUnitLabelSet]}repaintAll(){let e=this.renderer;if(!e)return;this.allIds.length&&e.setStatus(this.allIds,"free");let t={free:[],held:[],booked:[],not_for_sale:[]};for(let[s,i]of this.status.entries()){let a=this.labelToId.get(s);a&&t[M(i)].push(a)}["held","booked","not_for_sale"].forEach(s=>{t[s].length&&e.setStatus(t[s],s)})}async connect(){if(this.closed)return;let e;try{if(e=(await this.withAuthRetry(()=>this.api.subscribeTicket(this.key))).protocols,!e.length)throw new Error("manage_subscribe_ticket_missing")}catch(s){this.setLive(!1),this.opts.onError?.(s),this.scheduleReconnect();return}if(this.closed)return;let t;try{t=new WebSocket(this.api.socketUrl(this.key),e)}catch(s){this.opts.onError?.(s),this.scheduleReconnect();return}this.ws=t,this.socketSnapshotSeen=!1,t.onopen=()=>{this.attempt=0,this.setLive(!0),this.resnapshot().then(()=>this.refreshControlRoom()).catch(s=>this.opts.onError?.(s)),this.refreshAvailability()},t.onmessage=s=>this.onMessage(s),t.onclose=()=>{this.ws===t&&(this.ws=null),this.setLive(!1),this.scheduleReconnect()},t.onerror=()=>{try{t.close()}catch{}}}scheduleReconnect(){if(this.closed||this.reconnectTimer)return;let e=Math.min(1e3*2**Math.min(this.attempt++,5),15e3);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}onMessage(e){let t;try{t=JSON.parse(typeof e.data=="string"?e.data:"")}catch{return}if(!t||typeof t!="object")return;this.lastMessageAt=Date.now();let s=t;if((Array.isArray(s.hidden)||Array.isArray(s.closed))&&this.updateEffectiveAvailability(s.hidden,s.closed),s.type==="presence"){typeof s.shoppingSessions=="number"&&typeof s.activeHolds=="number"&&(this.livePresence={at:Date.now(),value:{shoppingSessions:s.shoppingSessions,activeHolds:s.activeHolds}},this.controlRoomSnapshot&&(this.controlRoomSnapshot={...this.controlRoomSnapshot,presence:this.livePresence.value},this.opts.onControlRoom?.(this.controlRoomSnapshot)),this.lastSyncedAt=Date.now(),this.recomputeTallies(),this.paintMonitorInsights());return}if(s.type!=="hidden"){if(s.seats&&typeof s.seats=="object")this.applySocketSnapshot(s.seats,typeof s.default=="string"?s.default:void 0);else if(Array.isArray(s.changes)){let i=[],a=new Map;for(let l of s.changes){let r=["free","held","booked","blocked"].includes(l.status)?l.status:"free",c=this.status.get(l.label)??"free";if(c===r)continue;this.setStatusLabel(l.label,r,c);let n=this.labelToId.get(l.label);n&&(this.renderer?.setStatus([n],M(r)),i.push(n));let d=this.verbFor(c,r),m=`${d}:${r}`,b=a.get(m)??{labels:[],verb:d,status:r};b.labels.push(l.label),a.set(m,b)}for(let l of a.values()){let r=this.pushActivity(l.labels,l.verb,l.status);r&&this.paintSpatialActivity(r)}a.size&&this.scheduleMonitorRefresh(),i.length&&(this.lastSyncedAt=Date.now(),this.afterPaint());let o=typeof s.bookedValue?.gross=="number"?s.bookedValue.gross:s.revenue?.gross;typeof o=="number"&&Number.isFinite(o)&&this.applyLiveGross(o),this.recomputeTallies()}}}applyLiveGross(e){if(this.liveGross={at:Date.now(),value:e},this.authoritativeGrossRevenue=e,this.revenueStatus="current",this.controlRoomSnapshot){let s={...this.controlRoomSnapshot.bookedValue??this.controlRoomSnapshot.revenue,gross:e};this.controlRoomSnapshot={...this.controlRoomSnapshot,bookedValue:s,revenue:s},this.opts.onControlRoom?.(this.controlRoomSnapshot)}}setStatusLabel(e,t,s=this.status.get(e)??"free"){this.status.set(e,t),s!==t&&(s!=="free"&&(this.counts[s]-=1),t!=="free"&&(this.counts[t]+=1))}applySocketSnapshot(e,t){let s=this.socketSnapshotSeen?this.status:null;if(this.applySnapshot(e,t),this.socketSnapshotSeen=!0,!s)return;let i=new Map;for(let a of new Set([...s.keys(),...this.status.keys()])){let o=s.get(a)??"free",l=this.status.get(a)??"free";if(o===l)continue;let r=this.verbFor(o,l),c=`${r}:${l}`,n=i.get(c)??{labels:[],verb:r,status:l};n.labels.push(a),i.set(c,n)}for(let a of i.values()){let o=this.pushActivity(a.labels,a.verb,a.status);o&&this.paintSpatialActivity(o)}i.size&&this.scheduleMonitorRefresh()}scheduleMonitorRefresh(){this.monitorRefreshTimer||(this.monitorRefreshTimer=setTimeout(()=>{this.monitorRefreshTimer=null,this.closed||this.refreshControlRoom().catch(e=>this.opts.onError?.(e))},150))}async resnapshot(){try{let e=await this.api.objects(this.key);this.applySnapshot(e.seats),this.updateEffectiveAvailability(e.hidden,e.closed),this.lastMessageAt=Date.now()}catch{}}applySnapshot(e,t){let s=a=>["free","held","booked","blocked"].includes(a)?a:"free",i=new Map;if(t!==void 0){let a=s(t);for(let o of this.knownLabels())i.set(o,a)}for(let[a,o]of Object.entries(e))i.set(a,s(o));this.status=i,this.modelVersion+=1,this.recountAll(),this.lastSyncedAt=Date.now(),this.repaintAll(),this.afterPaint(),this.recomputeTallies()}recountAll(){let e={held:0,booked:0,blocked:0};for(let t of this.status.values())t!=="free"&&(e[t]+=1);this.counts=e}setSeatsLocal(e,t){let s=[];for(let i of e){this.setStatusLabel(i,t);let a=this.labelToId.get(i);a&&s.push(a)}s.length&&this.renderer?.setStatus(s,M(t)),this.afterPaint(),this.recomputeTallies()}afterPaint(){this.keepLive&&typeof document<"u"&&document.hidden&&this.renderer?.forceDraw()}activityColor(e){return e==="held"?"#f4b740":e==="booked"?"#22a06b":e==="blocked"?"#8b94ac":"#6e7bff"}sectionsForLabels(e){let t=new Set;for(let i of e){let a=this.labelToSeat.get(i);if(!a)continue;let o=this.sectionByObject.get(a.rowId);o&&o!==y&&t.add(o)}let s=[...t];return{ids:s,labels:s.map(i=>this.sectionLabelById.get(i)??i)}}pulseSeatLabels(e,t){let s=this.activityColor(t);for(let i of e.slice(0,ee)){let a=this.labelToId.get(i);a&&this.renderer?.flashSeat(a,s)}}paintSpatialActivity(e){let t=e.sectionIds??this.sectionsForLabels(e.labels).ids,s=this.renderer?.getFocusedSection()??null;if(this.followLive&&t.length===1&&(e.status==="held"||e.status==="booked")){let a=this.root?.querySelector('[data-ref="followstatus"]');a&&(a.textContent=`Following ${e.labels.length===1?e.labels[0]:`${e.labels.length} seats`} \xB7 ${e.status}`),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=setTimeout(()=>{this.followLiveTimer=null,this.focusActivitySeats(e.labels,t[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(e.labels,e.status)},520)},220);return}if(!s&&t.length){let a=this.activityColor(e.status);for(let o of t.slice(0,te))this.renderer?.flashSection(o,a);return}(!t.length||s&&t.includes(s))&&this.pulseSeatLabels(e.labels,e.status)}locateSection(e){this.renderer?.focusSection(e)}focusActivitySeats(e,t){this.renderer?.focusSection(t);let s=e.slice(0,ee).map(r=>this.labelToSeat.get(r)).filter(r=>!!r);if(!s.length)return;let i=s.map(r=>r.x),a=s.map(r=>r.y),o=Math.min(...i),l=Math.min(...a);this.renderer?.focusRegion({x:o-150,y:l-100,width:Math.max(...i)-o+300,height:Math.max(...a)-l+200})}locateActivity(e){let t=this.feed.find(i=>i.id===e);if(!t)return;let s=t.sectionIds??this.sectionsForLabels(t.labels).ids;if(this.followSeatTimer&&clearTimeout(this.followSeatTimer),s.length===1){this.focusActivitySeats(t.labels,s[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(t.labels,t.status)},520);return}this.zoomToFit(),this.followSeatTimer=setTimeout(()=>{if(this.followSeatTimer=null,s.length){let i=this.activityColor(t.status);for(let a of s.slice(0,te))this.renderer?.flashSection(a,i)}else this.pulseSeatLabels(t.labels,t.status)},280)}showLiveEvent(e){let t=this.els.liveevent;if(!t)return;let s=e.sectionLabels??[],i=s.length===1?s[0]:s.length>1?`${s.length} sections`:e.label,a=e.count===1?"seat":"seats";t.innerHTML=`<span class="slm-liveeventdot" style="background:${this.activityColor(e.status)}"></span>
471
+ </div>`}var We="https://api.seatlayer.io",$=200,ie=16,ae=4,oe=[{key:"watch",label:"Watch",tools:[{mode:"view",label:"Monitor",shortcut:"M",title:"Live board \u2014 inventory, activity and booking momentum. Read-only."},{mode:"inspect",label:"Inspect",shortcut:"I",title:"Click one seat to read its live status and booking context. Read-only."}]},{key:"manage",label:"Manage",tools:[{mode:"block",label:"Block",shortcut:"B",title:"Take seats off sale for this event, or put them back."},{mode:"sections",label:"Sections",shortcut:"S",title:"Open, close or hide sections for this event, on a schedule or on demand."},{mode:"categories",label:"Categories",shortcut:"G",title:"Move seats to a different price category for this event only."},{mode:"tables",label:"Tables",shortcut:"T",title:"Sell each table per chair or as one whole-table booking."},{mode:"channels",label:"Channels",shortcut:"C",title:"Allocate inventory to sales channels and share their links."}]},{key:"host",label:"Host tools",tools:[{mode:"select",label:"Select",shortcut:"X",title:"Select seats for your own back-office operation. The selection is handed to your app; nothing changes here."},{mode:"filterSections",label:"Filter",shortcut:"L",title:"Filter the map to one section for your own reporting."}]}],Ze=Object.fromEntries(oe.flatMap(h=>h.tools.map(e=>[e.shortcut.toLowerCase(),e.mode]))),F=class{constructor(e){this.els={};this.renderer=null;this.doc=null;this.selectObserver=null;this.seatHistoryPanel=null;this.activityPanel=null;this.navigation=null;this.movingMap=!1;this.socketSnapshotSeen=!1;this.monitorRefreshTimer=null;this.themeMode=null;this.colorSchemeStop=null;this.inventoryModelVersion=1;this.selectableObjectLabels=new Set;this.lastSelectionLabels=new Set;this.selectionWasValid=null;this.initialSelectionApplied=!1;this.labelToId=new Map;this.labelToSeat=new Map;this.allIds=[];this.gaUnitLabelSet=new Set;this.status=new Map;this.counts={held:0,booked:0,blocked:0};this.modelVersion=0;this.currency="USD";this.authoritativeCurrency=null;this.authoritativeGrossRevenue=0;this.revenueStatus="loading";this.revenueRequest=0;this.controlRoomSnapshot=null;this.serverBaseline=null;this.livePresence=null;this.liveGross=null;this.paintHandle=null;this.trendWindowMinutes=15;this.heatEnabled=!1;this.lastKpiValues=new Map;this.activeKpiDeltas=new Map;this.ws=null;this.reconnectTimer=null;this.attempt=0;this.closed=!1;this.connectionStatus="reconnecting";this.lastMessageAt=null;this.ready=!1;this.feed=[];this.feedTimer=null;this.toastTimer=null;this.liveEventTimer=null;this.kpiCleanupTimer=null;this.followLiveTimer=null;this.followSeatTimer=null;this.releaseAt=null;this.layoutObserver=null;this.tokenExpiresAt=null;this.tokenRefreshTimer=null;this.tokenRefreshInFlight=!1;this.sectionByObject=new Map;this.sectionLabelById=new Map;this.sectionsBase=null;this.filteredSectionLabel=null;this.availabilityRules={};this.effectiveHidden=new Set;this.effectiveClosed=new Set;this.availabilitySaving=!1;this.lastSyncedAt=null;this.blockBrowse=!1;this.blockedQuery="";this.blockedSection="";this.blockedResultLimit=100;this.unblockAllConfirmTimer=null;this.channels=null;this.channelCaps={view:!1,manage:!1};this.categoryCanManage=!1;this.tableCanManage=!1;this.tableBookingSaving=!1;this.channelCapabilityResolution=0;this.channelsLoading=null;this.onFullscreenChange=()=>{this.paintFullscreenButton(),this.updateContainerLayout(),this.renderer?.forceDraw()};this.onKeyDown=e=>{if(e.metaKey||e.ctrlKey||e.altKey||e.target?.matches('input,select,textarea,[contenteditable="true"]'))return;let s=e.key.toLowerCase(),i=Ze[s];if(i){if(!this.toolAvailable(i))return;this.setMode(i)}else if(s==="f")this.toggleFullscreen();else if(s==="escape"){if(!this.channels?.handleBack())if(this.getSelection().length)this.clearSelection();else return}else return;e.preventDefault()};this.onRailClick=e=>{let t=e.target,s=t?.closest("[data-section-focus]");if(s?.dataset.sectionFocus){this.locateSection(s.dataset.sectionFocus);return}let i=t?.closest("[data-feed-id]");i?.dataset.feedId&&this.locateActivity(i.dataset.feedId)};this.sectionOptions=[];I(e.token),this.assertSelectionOptions(e.maxSelectedObjects,e.numberOfPlacesToSelect),this.opts=e,this.key=e.eventKey,this.mode=e.mode??"view",this.selectableObjectLabels=new Set(e.selectableObjects??[]),this.categoryCanManage=new Set(e.capabilities??[]).has("event:categories:manage"),this.tableCanManage=new Set(e.capabilities??[]).has("event:tables:manage"),this.keepLive=e.keepLiveWhileHidden??!0,this.themeMode=e.themeMode??null,this.followLive=e.followLive??!1,this.currency=e.currency??"USD",this.tokenExpiresAt=e.tokenExpiresAt??null,this.api=new z(e.apiBase??We,e.token),this.organizerAssetUrls=new M(this.key,(t,s)=>this.withAuthRetry(()=>this.api.asset(t,s))),this.host=Z(e.container)}assertSelectionOptions(e,t){let s=i=>i===void 0||Number.isInteger(i)&&i>0;if(!s(e))throw new TypeError("maxSelectedObjects must be a positive integer");if(!s(t))throw new TypeError("numberOfPlacesToSelect must be a positive integer");if(e!==void 0&&t!==void 0&&e<t)throw new TypeError("maxSelectedObjects cannot be lower than numberOfPlacesToSelect")}async render(){V(),this.buildChrome();try{let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1,this.doc=await this.organizerAssetUrls.prepareRendererChart(e.doc),this.authoritativeCurrency=e.event.currency??null,this.currency=this.authoritativeCurrency??this.opts.currency??this.currency,this.buildUnitUniverse(this.doc),this.buildRenderer(),this.buildSectionOptions(),this.settleMode();let[,t]=await Promise.all([this.resnapshot(),this.refreshControlRoom().catch(s=>this.opts.onError?.(s)),this.refreshAvailability()]);t?.activity?this.seedFeed(t.activity):this.api.log(this.key,{limit:24}).then(s=>this.seedFeed(s.entries)).catch(()=>{}),this.connect(),this.startFeedClock(),this.ready=!0,await this.resolveChannelCapabilities(),this.setMode(this.mode),this.applyInitialSelection(),this.scheduleTokenRefresh(),this.opts.onReady?.()}catch(e){this.fail(e)}return this}setMode(e){this.toolAvailable(e)||(e="view"),e==="channels"&&!this.channels&&this.ensureChannels();let t=e!==this.mode,s=this.mode==="channels",i=this.mode==="filterSections";this.mode=e,t&&e!=="view"&&this.setFollowLive(!1),!this.renderer&&this.doc?this.buildRenderer():this.updateRendererInteraction(),t&&(this.renderer?.clearSelection(),this.syncSelection()),s&&e!=="channels"&&this.channels?.leave(),this.paintModeTabs(),this.paintRail(),this.applySectionCanvasTreatment(),i&&e!=="filterSections"&&this.renderer?.zoomToFit(),e==="channels"&&this.channels?.enter(),e==="select"&&this.applyInitialSelection(),t&&this.opts.onModeChange?.(e)}async resolveChannelCapabilities(){let e=++this.channelCapabilityResolution,t=this.opts.capabilities,s;if(t){let i=new Set(t);s={view:i.has("event:channels:view"),manage:i.has("event:channels:view")&&i.has("event:channels:manage")}}else s={view:!1,manage:!1};if(!s.view&&!t)try{await this.api.channels(this.key),s={view:!0,manage:!1}}catch{s={view:!1,manage:!1}}if(e===this.channelCapabilityResolution){if(this.channelCaps=s,!this.channelCaps.view){this.channels?.destroy(),this.channels=null,this.mode==="channels"?this.setMode("view"):this.paintModeTabs();return}this.channels?.setCapabilities(this.channelCaps),this.paintModeTabs()}}ensureChannels(){if(this.channelsLoading)return this.channelsLoading;if(this.channels)return Promise.resolve();let e=(async()=>{try{let t=await import("./channelsMode-KZU235GN.js");if(this.closed||!this.channelCaps.view||(this.channels||(U(t.CHANNELS_CSS),this.channels=new t.ChannelsMode(this.buildChannelsHost(),this.channelCaps),this.channels.onInteractionChange=()=>this.updateRendererInteraction()),this.mode!=="channels"))return;this.updateRendererInteraction(),this.paintRail(),this.channels.enter()}catch(t){if(this.closed)return;this.channelsLoading=null,this.mode==="channels"&&this.paintRail(),this.opts.onError?.(t)}})();return this.channelsLoading=e,e}buildChannelsHost(){return{eventKey:this.key,api:this.api,rail:this.els.rail,mapLayer:this.root.querySelector(".slm-map"),pillLane:this.els.lane,root:this.root,seats:()=>[...this.labelToSeat.values()].map(e=>({id:e.id,label:e.label,x:e.x,y:e.y})),statusOf:e=>this.status.get(e)??(this.labelToSeat.has(e)?"free":void 0),selectionLabels:()=>this.selectionLabels(),selectByLabels:e=>{this.selectByLabels(e)},clearSelection:()=>this.clearSelection(),selectSection:e=>{this.selectSection(e)},sections:()=>this.sectionOptions,labelsInSection:e=>this.renderer?.getSelectableInSection(e).map(t=>t.label)??[],rows:()=>{let e=new Map((this.doc?.objects??[]).map(s=>[s.id,s])),t=new Map;for(let s of this.labelToSeat.values()){let i=e.get(s.rowId);if(!i||i.type!=="row"&&i.type!=="table")continue;let a=s.logicalRowId??s.rowId,o=this.sectionByObject.get(s.rowId)??x,l=t.get(a)??{id:a,label:i.type==="row"?i.segmentedRow?.displayLabel??i.displayLabel??i.label:i.displayLabel??i.label,sectionId:o,sectionLabel:this.sectionLabelById.get(o)??"Other seats",labels:[]};l.labels.push(s.label),t.set(a,l)}return[...t.values()].sort((s,i)=>s.sectionLabel.localeCompare(i.sectionLabel,void 0,{numeric:!0,sensitivity:"base"})||s.label.localeCompare(i.label,void 0,{numeric:!0,sensitivity:"base"}))},categories:()=>(this.doc?.categories??[]).map(e=>({key:e.key,label:e.label??e.key,color:e.color,price:e.price,tiers:e.tiers?.map(t=>({id:t.id,name:t.name,price:t.price}))})),labelsInCategory:e=>[...this.labelToSeat.entries()].filter(([,t])=>t.categoryKey===e).map(([t])=>t),sectionOfLabel:e=>{let t=this.labelToSeat.get(e);if(!t)return null;let s=this.sectionByObject.get(t.rowId)??x;return{id:s,label:this.sectionLabelById.get(s)??"Other seats"}},worldToScreen:e=>this.renderer?.worldToScreen(e)??null,seatPixelSize:()=>this.seatPixelSize(),isSeatDetail:()=>this.renderer?.getRung?.()==="seats",showSectionOverview:()=>{this.renderer?.clearSectionFocus(),this.renderer?.setRung?.("sections")},focusSection:e=>this.renderer?.focusSection(e),isCompact:()=>!!this.root?.classList.contains("compact"),setMapInert:e=>{this.mapHost.toggleAttribute("inert",e),this.mapHost.setAttribute("aria-hidden",String(e))},toast:(e,t)=>this.toast(e,t),onError:e=>this.opts.onError?.(e)}}seatPixelSize(){let e=this.renderer?.getVisibleWorldRect?.(),t=this.mapHost?.clientWidth??0;return!e?.width||!t?6:Math.max(3,t/e.width*18)}setHeatOverlay(e){this.heatEnabled=e,this.applyHeatOverlay(),this.paintHeatButton()}setFollowLive(e){let t=this.followLive!==e;this.followLive=e,e||(this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=null,this.followSeatTimer=null),this.paintFollowLiveButton(),t&&this.opts.onFollowLiveChange?.(e)}setKeepLiveWhileHidden(e){this.keepLive=e??!0,this.opts.keepLiveWhileHidden=e}setCurrency(e){this.opts.currency=e,!this.authoritativeCurrency&&(this.currency=e??"USD",this.ready&&this.recomputeTallies())}setTheme(e){this.opts.theme=e,this.applyThemeVars()}applyThemeVars(){if(!this.root)return;let e=B(this.themeMode);for(let[t,s]of Object.entries(Q(this.opts.theme,e)))this.root.style.setProperty(t,s);e?this.root.dataset.theme=e:delete this.root.dataset.theme}watchThemeMode(){this.colorSchemeStop?.(),this.colorSchemeStop=null,this.themeMode==="auto"&&(this.colorSchemeStop=j(()=>{this.closed||this.repaintForThemeMode()}))}repaintForThemeMode(){this.applyThemeVars();let e=this.renderer;if(!e||!this.doc)return;let t=e.getSelection().map(a=>a.id),s=e.getCameraPose(),i=e.getFocusedSection();e.setChart(this.themedDoc()),this.repaintAll(),this.applyHeatOverlay(),t.length&&e.select(t),i&&e.focusSection(i),e.setCameraPose(s),this.updateZoomHint()}setThemeMode(e){let t=e??null;this.closed||t===this.themeMode||(this.themeMode=t,this.opts.themeMode=t??void 0,this.watchThemeMode(),this.repaintForThemeMode())}getThemeMode(){return this.themeMode}themedDoc(){let e=this.doc,t=J(B(this.themeMode));return t?{...e,theme:{...e.theme??{},background:t}}:e}setCapabilities(e){this.opts.capabilities=e,this.categoryCanManage=new Set(e??[]).has("event:categories:manage"),this.tableCanManage=new Set(e??[]).has("event:tables:manage"),!this.categoryCanManage&&this.mode==="categories"||!this.tableCanManage&&this.mode==="tables"?this.setMode("view"):this.paintModeTabs(),this.ready&&this.resolveChannelCapabilities()}setTokenRefresh(e){this.opts.onTokenRefresh=e,this.scheduleTokenRefresh()}setTrendWindow(e){let t=Number.isFinite(e)?Math.floor(e):15;return this.trendWindowMinutes=Math.max(5,Math.min(60,t)),this.paintTrendWindow(),this.refreshControlRoom()}async enterFullscreen(){!this.root?.requestFullscreen||this.isFullscreen()||(await this.root.requestFullscreen(),this.root.focus({preventScroll:!0}))}async exitFullscreen(){typeof document>"u"||!this.isFullscreen()||await document.exitFullscreen()}isFullscreen(){return typeof document<"u"&&document.fullscreenElement===this.root}toggleFullscreen(){(this.isFullscreen()?this.exitFullscreen():this.enterFullscreen()).catch(t=>this.opts.onError?.(t))}setToken(e,t){I(e),this.api.setToken(e),this.opts.token=e,this.opts.tokenExpiresAt=t,this.tokenExpiresAt=t??null,this.scheduleTokenRefresh(),this.ready&&this.resolveChannelCapabilities()}scheduleTokenRefresh(){this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.tokenRefreshTimer=null;let e=this.opts.onTokenRefresh,t=this.tokenExpiresAt;if(this.closed||!e||!t||!Number.isFinite(t))return;let s=t-Date.now(),i=Math.min(12e4,Math.max(3e4,s*.2)),a=Math.max(0,s-i);this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},a)}async rotateToken(){if(!(this.closed||this.tokenRefreshInFlight||!this.opts.onTokenRefresh)){this.tokenRefreshInFlight=!0;try{let e=await this.opts.onTokenRefresh();if(!e?.token||!Number.isFinite(e.expiresAt))throw new Error("invalid_token_refresh_result");this.setToken(e.token,e.expiresAt)}catch(e){this.opts.onError?.(e),this.closed||(this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},3e4))}finally{this.tokenRefreshInFlight=!1}}}async block(e,t={}){let s=(e??this.selectionLabels()).filter(a=>this.status.get(a)==="free");if(!s.length)return;let i=t.releaseAt??this.releaseAt??void 0;this.setSeatsLocal(s,"blocked");try{await this.api.block(this.key,s,{...t,releaseAt:i}),this.clearSelection(),this.done("block",s,i?`Blocked ${s.length} \u2014 auto-release ${new Date(i).toLocaleString()}.`:`Blocked ${s.length} seat${s.length===1?"":"s"}.`)}catch(a){this.setSeatsLocal(s,"free"),this.toastErr(a instanceof S&&a.status===409?"Some seats were just taken. Try again.":"Couldn't block those seats."),this.opts.onError?.(a)}}async unblock(e){let t=(e??this.selectionLabels()).filter(s=>this.status.get(s)==="blocked");if(t.length){this.setSeatsLocal(t,"free");try{await this.api.unblock(this.key,t),this.clearSelection(),this.done("unblock",t,`Unblocked ${t.length} seat${t.length===1?"":"s"}.`)}catch(s){this.setSeatsLocal(t,"blocked"),this.toastErr("Couldn't unblock those seats."),this.opts.onError?.(s)}}}async unblockAll(){let e=[...this.status.entries()].filter(([,t])=>t==="blocked").map(([t])=>t);if(e.length){this.setSeatsLocal(e,"free");try{let t=await this.api.unblockAll(this.key);this.clearSelection(),this.done("unblockAll",e,`Unblocked ${t.freed} seat${t.freed===1?"":"s"}.`)}catch(t){await this.resnapshot(),this.toastErr("Couldn't mark everything for sale."),this.opts.onError?.(t)}}}async cancelBooking(e,t){let s=e.filter(i=>this.status.get(i)==="booked");if(!(!s.length||!t)){this.setSeatsLocal(s,"free");try{await this.api.unbook(this.key,s,t),this.clearSelection(),this.done("cancelBooking",s,`Released ${s.length} booked unit${s.length===1?"":"s"}.`)}catch(i){this.setSeatsLocal(s,"booked"),this.toastErr("Couldn't release that booked inventory. Check the booking reference."),this.opts.onError?.(i)}}}async setCategory(e,t){let s=this.doc?.categories.find(a=>a.key===e),i=[...new Set(t??this.selectionLabels())].filter(a=>this.labelToSeat.has(a));if(!(!s||!i.length))try{let a=await this.withAuthRetry(()=>this.api.setCategory(this.key,i,e)),o={};for(let l of a.labels){let r=this.labelToSeat.get(l),c=this.labelToId.get(l);r&&(r.categoryKey=e),c&&(o[c]=e)}this.renderer?.setSeatCategories?.(o),this.clearSelection(),this.done("setCategory",a.labels,`Assigned ${a.labels.length.toLocaleString()} object${a.labels.length===1?"":"s"} to ${s.label??s.key}.`)}catch(a){this.toastErr("Couldn't update those event categories."),this.opts.onError?.(a)}}async setTableBooking(e,t,s={}){let i=[...new Set(e)].filter(Boolean);if(!(!i.length||this.tableBookingSaving)){if(this.inventoryModelVersion!==2){this.toastErr("Table booking controls require inventory model 2 for this event.");return}this.tableBookingSaving=!0,this.mode==="tables"&&this.renderTablesRail();try{let a=await this.withAuthRetry(()=>this.api.setTableBooking(this.key,i,t,s));await this.reloadEventChart(),this.done("setTableBooking",a.tableIds,`Updated ${a.tableIds.length.toLocaleString()} table${a.tableIds.length===1?"":"s"} to ${t==="individual"?"per-chair":t==="whole"?"whole-table":"flexible-group"} booking.`)}catch(a){let o=a instanceof S&&a.code==="table_inventory_in_use";this.toastErr(o?"Release held, booked, or blocked table inventory before changing its booking mode.":"Couldn't update table booking. No table mode was changed."),this.opts.onError?.(a)}finally{this.tableBookingSaving=!1,this.mode==="tables"&&this.renderTablesRail()}}}async reloadEventChart(){let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1;let t=await this.organizerAssetUrls.prepareRendererChart(e.doc);this.renderer?.destroy(),this.renderer=null,this.doc=t,this.labelToId.clear(),this.labelToSeat.clear(),this.allIds=[],this.gaUnitLabelSet.clear(),this.status.clear(),this.counts={held:0,booked:0,blocked:0},this.serverBaseline=null,this.lastSelectionLabels.clear(),this.buildUnitUniverse(t),this.buildRenderer(),this.buildSectionOptions(),this.settleMode(),await Promise.all([this.resnapshot(),this.refreshAvailability()]),this.paintRail()}selectAll(){if(this.mode==="select")return this.selectByLabels([...this.labelToSeat.values()].filter(t=>this.canSelectObject(t)).map(t=>t.label));let e=this.renderer?.selectAllSelectable()??[];return this.syncSelection(),e}selectSection(e){if(!this.renderer)return[];let t=this.renderer.getSelectableInSection(e);return this.renderer.selectByLabels(t.map(s=>s.label)),this.syncSelection(),this.renderer.getSelection()}setFilteredSection(e){let t=e.trim(),s=this.filterableSections().filter(o=>o.label===t);if(!s.length)throw new Error(`Unknown event section: ${e}`);let i=t!==this.filteredSectionLabel;this.filteredSectionLabel=t,this.mode==="filterSections"&&(this.applyFilteredSectionCanvas(s),this.renderFilterSectionsRail());let a=s.map(({id:o,label:l,seatCount:r,zone:c})=>({id:o,label:l,seatCount:r,...c?{zone:c}:{}}));return i&&this.opts.onFilteredSectionChange?.(a),a}clearFilteredSection(){let e=this.filteredSectionLabel!==null;this.filteredSectionLabel=null,this.renderer?.setDimmedSections(null),this.renderer?.clearSectionFocus(),this.renderer?.zoomToFit(),this.mode==="filterSections"&&this.renderFilterSectionsRail(),e&&this.opts.onFilteredSectionChange?.([])}getFilteredSections(){return this.filteredSectionLabel?this.filterableSections().filter(e=>e.label===this.filteredSectionLabel).map(({id:e,label:t,seatCount:s,zone:i})=>({id:e,label:t,seatCount:s,...i?{zone:i}:{}})):[]}selectByLabels(e){let t=e;if(this.mode==="select"){let s=new Set(this.selectionLabels()),i=this.selectionCap(),a=[...new Set(e)].filter(l=>!s.has(l)).map(l=>this.labelToSeat.get(l)).filter(l=>!!l&&this.canSelectObject(l)),o=Math.max(0,i-s.size);a.length>o&&this.opts.onSelectionLimit?.(i),t=a.slice(0,o).map(l=>l.label)}return this.renderer?.selectByLabels(t),this.syncSelection(),this.getSelection()}selectObjects(e){return this.selectByLabels(e)}deselectObjects(e){let t=e.map(s=>this.labelToId.get(s)).filter(s=>!!s);return this.renderer?.deselect(t),this.syncSelection(),this.getSelection()}selectCategories(e){let t=new Set(e);return this.selectByLabels([...this.labelToSeat.values()].filter(s=>t.has(s.categoryKey)).map(s=>s.label))}deselectCategories(e){let t=new Set(e);return this.deselectObjects(this.getSelection().filter(s=>t.has(s.categoryKey)).map(s=>s.label))}setSelectableObjects(e){this.opts.selectableObjects=[...e],this.selectableObjectLabels=new Set(e),this.reconcileSelectPolicy()}setUnavailableObjectsSelectable(e){this.opts.unavailableObjectsSelectable=e,this.reconcileSelectPolicy()}setObjectSelectable(e){this.opts.isObjectSelectable=e,this.reconcileSelectPolicy()}setMaxSelectedObjects(e){this.assertSelectionOptions(e,this.opts.numberOfPlacesToSelect),this.opts.maxSelectedObjects=e,this.trimSelectionToCap(),this.updateRendererInteraction(),this.syncSelection()}setNumberOfPlacesToSelect(e){this.assertSelectionOptions(this.opts.maxSelectedObjects,e),this.opts.numberOfPlacesToSelect=e,this.selectionWasValid=null,this.trimSelectionToCap(),this.updateRendererInteraction(),this.syncSelection()}getSelectionValidity(){let e=this.opts.numberOfPlacesToSelect;if(e===void 0)return null;let t=this.getSelection(),s=t.length;return{isValid:s===e,count:s,required:e,remaining:Math.max(0,e-s),objects:t}}clearSelection(){this.renderer?.clearSelection(),this.syncSelection()}getSelection(){return this.renderer?.getSelection()??[]}getReport(){return this.api.report(this.key).then(e=>(this.applyReportRevenue(e),e))}getControlRoomSnapshot(e=this.trendWindowMinutes){return this.setTrendWindow(e)}getConnection(){return{status:this.connectionStatus,lastMessageAt:this.lastMessageAt}}getLog(e={}){return this.api.log(this.key,e)}async setHoldTtl(e){try{await this.api.setHoldTtl(this.key,e),this.done("setHoldTtl",[],e?`Hold window set to ${Math.round(e/6e4)} min.`:"Hold window reset.")}catch(t){this.toastErr("Couldn't update the hold window."),this.opts.onError?.(t)}}zoomToFit(){if(this.mode==="filterSections"&&this.filteredSectionLabel){this.clearFilteredSection();return}this.renderer?.clearSectionFocus(),this.renderer?.zoomToFit()}destroy(){if(this.selectObserver?.disconnect(),this.closed=!0,this.monitorRefreshTimer&&clearTimeout(this.monitorRefreshTimer),this.monitorRefreshTimer=null,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.feedTimer&&clearInterval(this.feedTimer),this.toastTimer&&clearTimeout(this.toastTimer),this.liveEventTimer&&clearTimeout(this.liveEventTimer),this.kpiCleanupTimer&&clearTimeout(this.kpiCleanupTimer),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.paintHandle!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.paintHandle),this.paintHandle=null,this.channels?.destroy(),this.channels=null,this.channelsLoading=null,this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.layoutObserver?.disconnect(),this.layoutObserver=null,this.colorSchemeStop?.(),this.colorSchemeStop=null,this.root?.removeEventListener("keydown",this.onKeyDown),this.els.rail?.removeEventListener("click",this.onRailClick),typeof document<"u"&&document.removeEventListener("fullscreenchange",this.onFullscreenChange),this.ws){try{this.ws.close()}catch{}this.ws=null}this.seatHistoryPanel?.destroy(),this.seatHistoryPanel=null,this.activityPanel?.destroy(),this.activityPanel=null,this.navigation?.destroy(),this.navigation=null,this.renderer?.destroy(),this.renderer=null,this.organizerAssetUrls.dispose(),this.root&&this.root.parentNode===this.host&&this.host.removeChild(this.root)}buildRenderer(){if(!this.doc)return;let e=this.isBulkSelectMode();this.renderer=new De(this.mapHost,{manageMode:!0,organizerGlyph:{apply:Ne,clear:qe,isPainted:_e},marqueeSelect:e&&!this.movingMap,maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses(),currency:this.currency,onSelect:t=>this.handleSeatSelect(t),onDeselect:()=>this.syncSelection(),onSelectionLimit:t=>this.opts.onSelectionLimit?.(t),onMarquee:()=>this.syncSelection(),onSectionTap:t=>{if(this.mode==="filterSections"){let s=this.filterableSections().find(i=>i.id===t);s&&this.setFilteredSection(s.label);return}this.renderer?.focusSection(t),this.channels?.handleSectionFocus(t)},onViewChange:()=>{this.updateZoomHint(),this.channels?.handleViewChange()}}),this.renderer.setChart(this.themedDoc()),this.repaintAll(),this.applyHeatOverlay(),this.updateZoomHint()}isBulkSelectMode(){return this.mode==="block"||this.mode==="categories"||this.mode==="channels"&&this.channels?.usesMarqueeSelection()===!0}selectableStatuses(){return this.mode==="block"?["free","not_for_sale"]:this.mode==="select"||this.mode==="categories"||this.mode==="inspect"||this.isBulkSelectMode()||this.mode==="channels"&&this.channels?.canSelect()===!0?["free","held","booked","not_for_sale"]:[]}updateRendererInteraction(){let e=this.isBulkSelectMode();this.renderer?.setManageInteraction({manageMode:!0,organizerStatus:this.mode!=="channels",marqueeSelect:e&&!this.movingMap,maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses()}),this.navigation?.update(e,this.mode==="view"),this.updateZoomHint()}handleSeatSelect(e){if(this.mode==="select"&&!this.canSelectObject(e)){this.renderer?.deselect([e.id]),this.syncSelection();return}if(this.mode==="inspect"){let t=this.getSelection().filter(s=>s.id!==e.id).map(s=>s.id);t.length&&this.renderer?.deselect(t)}this.syncSelection()}buildUnitUniverse(e){for(let t of Ve(e))this.labelToId.set(t.label,t.id),this.labelToSeat.set(t.label,t),this.allIds.push(t.id);for(let t of Ke(e))for(let s of Ge(t))this.labelToId.has(s)||this.gaUnitLabelSet.add(s)}unitTotal(){return this.allIds.length+this.gaUnitLabelSet.size}knownLabels(){return[...this.labelToId.keys(),...this.gaUnitLabelSet]}repaintAll(){let e=this.renderer;if(!e)return;this.allIds.length&&e.setStatus(this.allIds,"free");let t={free:[],held:[],booked:[],not_for_sale:[]};for(let[s,i]of this.status.entries()){let a=this.labelToId.get(s);a&&t[E(i)].push(a)}["held","booked","not_for_sale"].forEach(s=>{t[s].length&&e.setStatus(t[s],s)})}async connect(){if(this.closed)return;let e;try{if(e=(await this.withAuthRetry(()=>this.api.subscribeTicket(this.key))).protocols,!e.length)throw new Error("manage_subscribe_ticket_missing")}catch(s){this.setLive(!1),this.opts.onError?.(s),this.scheduleReconnect();return}if(this.closed)return;let t;try{t=new WebSocket(this.api.socketUrl(this.key),e)}catch(s){this.opts.onError?.(s),this.scheduleReconnect();return}this.ws=t,this.socketSnapshotSeen=!1,t.onopen=()=>{this.attempt=0,this.setLive(!0),this.resnapshot().then(()=>this.refreshControlRoom()).catch(s=>this.opts.onError?.(s)),this.refreshAvailability()},t.onmessage=s=>this.onMessage(s),t.onclose=()=>{this.ws===t&&(this.ws=null),this.setLive(!1),this.scheduleReconnect()},t.onerror=()=>{try{t.close()}catch{}}}scheduleReconnect(){if(this.closed||this.reconnectTimer)return;let e=Math.min(1e3*2**Math.min(this.attempt++,5),15e3);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}onMessage(e){let t;try{t=JSON.parse(typeof e.data=="string"?e.data:"")}catch{return}if(!t||typeof t!="object")return;this.lastMessageAt=Date.now();let s=t;if((Array.isArray(s.hidden)||Array.isArray(s.closed))&&this.updateEffectiveAvailability(s.hidden,s.closed),s.type==="presence"){typeof s.shoppingSessions=="number"&&typeof s.activeHolds=="number"&&(this.livePresence={at:Date.now(),value:{shoppingSessions:s.shoppingSessions,activeHolds:s.activeHolds}},this.controlRoomSnapshot&&(this.controlRoomSnapshot={...this.controlRoomSnapshot,presence:this.livePresence.value},this.opts.onControlRoom?.(this.controlRoomSnapshot)),this.lastSyncedAt=Date.now(),this.recomputeTallies(),this.paintMonitorInsights());return}if(s.type!=="hidden"){if(s.seats&&typeof s.seats=="object")this.applySocketSnapshot(s.seats,typeof s.default=="string"?s.default:void 0);else if(Array.isArray(s.changes)){let i=[],a=new Map;for(let l of s.changes){let r=["free","held","booked","blocked"].includes(l.status)?l.status:"free",c=this.status.get(l.label)??"free";if(c===r)continue;this.setStatusLabel(l.label,r,c);let n=this.labelToId.get(l.label);n&&(this.renderer?.setStatus([n],E(r)),i.push(n));let d=this.verbFor(c,r),m=`${d}:${r}`,b=a.get(m)??{labels:[],verb:d,status:r};b.labels.push(l.label),a.set(m,b)}for(let l of a.values()){let r=this.pushActivity(l.labels,l.verb,l.status);r&&this.paintSpatialActivity(r)}a.size&&this.scheduleMonitorRefresh(),i.length&&(this.lastSyncedAt=Date.now(),this.afterPaint());let o=typeof s.bookedValue?.gross=="number"?s.bookedValue.gross:s.revenue?.gross;typeof o=="number"&&Number.isFinite(o)&&this.applyLiveGross(o),this.recomputeTallies()}}}applyLiveGross(e){if(this.liveGross={at:Date.now(),value:e},this.authoritativeGrossRevenue=e,this.revenueStatus="current",this.controlRoomSnapshot){let s={...this.controlRoomSnapshot.bookedValue??this.controlRoomSnapshot.revenue,gross:e};this.controlRoomSnapshot={...this.controlRoomSnapshot,bookedValue:s,revenue:s},this.opts.onControlRoom?.(this.controlRoomSnapshot)}}setStatusLabel(e,t,s=this.status.get(e)??"free"){this.status.set(e,t),s!==t&&(s!=="free"&&(this.counts[s]-=1),t!=="free"&&(this.counts[t]+=1))}applySocketSnapshot(e,t){let s=this.socketSnapshotSeen?this.status:null;if(this.applySnapshot(e,t),this.socketSnapshotSeen=!0,!s)return;let i=new Map;for(let a of new Set([...s.keys(),...this.status.keys()])){let o=s.get(a)??"free",l=this.status.get(a)??"free";if(o===l)continue;let r=this.verbFor(o,l),c=`${r}:${l}`,n=i.get(c)??{labels:[],verb:r,status:l};n.labels.push(a),i.set(c,n)}for(let a of i.values()){let o=this.pushActivity(a.labels,a.verb,a.status);o&&this.paintSpatialActivity(o)}i.size&&this.scheduleMonitorRefresh()}scheduleMonitorRefresh(){this.monitorRefreshTimer||(this.monitorRefreshTimer=setTimeout(()=>{this.monitorRefreshTimer=null,this.closed||this.refreshControlRoom().catch(e=>this.opts.onError?.(e))},150))}async resnapshot(){try{let e=await this.api.objects(this.key);this.applySnapshot(e.seats),this.updateEffectiveAvailability(e.hidden,e.closed),this.lastMessageAt=Date.now()}catch{}}applySnapshot(e,t){let s=a=>["free","held","booked","blocked"].includes(a)?a:"free",i=new Map;if(t!==void 0){let a=s(t);for(let o of this.knownLabels())i.set(o,a)}for(let[a,o]of Object.entries(e))i.set(a,s(o));this.status=i,this.modelVersion+=1,this.recountAll(),this.lastSyncedAt=Date.now(),this.repaintAll(),this.afterPaint(),this.recomputeTallies()}recountAll(){let e={held:0,booked:0,blocked:0};for(let t of this.status.values())t!=="free"&&(e[t]+=1);this.counts=e}setSeatsLocal(e,t){let s=[];for(let i of e){this.setStatusLabel(i,t);let a=this.labelToId.get(i);a&&s.push(a)}s.length&&this.renderer?.setStatus(s,E(t)),this.afterPaint(),this.recomputeTallies()}afterPaint(){this.keepLive&&typeof document<"u"&&document.hidden&&this.renderer?.forceDraw()}activityColor(e){return e==="held"?y.held:e==="booked"?y.booked:e==="blocked"?y.blocked:y.free}sectionsForLabels(e){let t=new Set;for(let i of e){let a=this.labelToSeat.get(i);if(!a)continue;let o=this.sectionByObject.get(a.rowId);o&&o!==x&&t.add(o)}let s=[...t];return{ids:s,labels:s.map(i=>this.sectionLabelById.get(i)??i)}}pulseSeatLabels(e,t){let s=this.activityColor(t);for(let i of e.slice(0,ie)){let a=this.labelToId.get(i);a&&this.renderer?.flashSeat(a,s)}}paintSpatialActivity(e){let t=e.sectionIds??this.sectionsForLabels(e.labels).ids,s=this.renderer?.getFocusedSection()??null;if(this.followLive&&t.length===1&&(e.status==="held"||e.status==="booked")){let a=this.root?.querySelector('[data-ref="followstatus"]');a&&(a.textContent=`Following ${e.labels.length===1?e.labels[0]:`${e.labels.length} seats`} \xB7 ${e.status}`),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=setTimeout(()=>{this.followLiveTimer=null,this.focusActivitySeats(e.labels,t[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(e.labels,e.status)},520)},220);return}if(!s&&t.length){let a=this.activityColor(e.status);for(let o of t.slice(0,ae))this.renderer?.flashSection(o,a);return}(!t.length||s&&t.includes(s))&&this.pulseSeatLabels(e.labels,e.status)}locateSection(e){this.renderer?.focusSection(e)}focusActivitySeats(e,t){this.renderer?.focusSection(t);let s=e.slice(0,ie).map(r=>this.labelToSeat.get(r)).filter(r=>!!r);if(!s.length)return;let i=s.map(r=>r.x),a=s.map(r=>r.y),o=Math.min(...i),l=Math.min(...a);this.renderer?.focusRegion({x:o-150,y:l-100,width:Math.max(...i)-o+300,height:Math.max(...a)-l+200})}locateActivity(e){let t=this.feed.find(i=>i.id===e);if(!t)return;let s=t.sectionIds??this.sectionsForLabels(t.labels).ids;if(this.followSeatTimer&&clearTimeout(this.followSeatTimer),s.length===1){this.focusActivitySeats(t.labels,s[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(t.labels,t.status)},520);return}this.zoomToFit(),this.followSeatTimer=setTimeout(()=>{if(this.followSeatTimer=null,s.length){let i=this.activityColor(t.status);for(let a of s.slice(0,ae))this.renderer?.flashSection(a,i)}else this.pulseSeatLabels(t.labels,t.status)},280)}showLiveEvent(e){let t=this.els.liveevent;if(!t)return;let s=e.sectionLabels??[],i=s.length===1?s[0]:s.length>1?`${s.length} sections`:e.label,a=e.count===1?"seat":"seats";t.innerHTML=`<span class="slm-liveeventdot" style="background:${this.activityColor(e.status)}"></span>
451
472
  <span class="slm-liveeventcopy">${p(i)} \xB7 ${e.count.toLocaleString()} ${a} ${p(e.verb)}</span>
452
- <span class="slm-liveeventhint">Live</span>`,t.classList.add("on"),this.liveEventTimer&&clearTimeout(this.liveEventTimer),this.liveEventTimer=setTimeout(()=>{this.liveEventTimer=null,t.classList.remove("on"),t.innerHTML=""},2800)}applyReportRevenue(e){this.authoritativeGrossRevenue=e.report.byCategory.reduce((t,s)=>{let i=Number.isFinite(s.bookedValue)?s.bookedValue:s.bookedRevenue;return t+(Number.isFinite(i)?i:0)},0),this.revenueStatus="current",this.recomputeTallies()}async refreshControlRoom(){let e=++this.revenueRequest,t=Date.now();try{let s=await this.api.controlRoom(this.key,this.trendWindowMinutes),i=s.bookedValue??s.revenue??{gross:0,bySection:[]},a=(i.bySection??[]).map(r=>{let c=Number.isFinite(r.bookedValue)?r.bookedValue:r.bookedRevenue;return{...r,bookedValue:c??0,bookedRevenue:c??0}}),o={...i,bySection:a},l={...s,bookedValue:o,revenue:o};if(e===this.revenueRequest){if(this.livePresence&&this.livePresence.at>=t?l={...l,presence:this.livePresence.value}:this.livePresence=null,this.liveGross&&this.liveGross.at>=t){let n={...l.bookedValue,gross:this.liveGross.value};l={...l,bookedValue:n,revenue:n}}else this.liveGross=null;this.controlRoomSnapshot=l,l.activity&&this.seedFeed(l.activity),this.rebaseServerTotals(l),this.lastSyncedAt=Date.now(),this.authoritativeGrossRevenue=l.bookedValue.gross,this.authoritativeCurrency=l.currency,this.currency=l.currency,this.revenueStatus="current",this.recomputeTallies(),this.applyHeatOverlay(),this.paintMonitorInsights(),this.seatHistoryPanel?.refresh();let r=this.getSelection().slice(-1)[0],c=this.els.rail?.querySelector("[data-seat-status]");r&&c&&(c.textContent=this.status.get(r.label)??"free"),this.opts.onControlRoom?.(l)}return l}catch(s){throw e===this.revenueRequest&&(this.revenueStatus="stale",this.recomputeTallies()),s}}rebaseServerTotals(e){let t=e.totals;if(!t||["free","held","booked","blocked"].some(s=>!Number.isFinite(t[s]))){this.serverBaseline=null;return}this.serverBaseline={model:this.modelVersion,server:{free:t.free,held:t.held,booked:t.booked,blocked:t.blocked},client:this.clientTallies()}}clientTallies(){let{held:e,booked:t,blocked:s}=this.counts;return{held:e,booked:t,blocked:s,free:Math.max(0,this.unitTotal()-e-t-s)}}buildTallies(){let e=this.clientTallies(),t=this.serverBaseline?.model===this.modelVersion?this.serverBaseline:null,s=l=>t?Math.max(0,t.server[l]+(e[l]-t.client[l])):e[l],i=this.controlRoomSnapshot?.event?.seatTotal,a={free:s("free"),held:s("held"),booked:s("booked"),blocked:s("blocked"),total:Number.isFinite(i)?i:this.unitTotal(),capacityPct:0,sellThroughPct:0,bookedValue:this.authoritativeGrossRevenue,grossRevenue:this.authoritativeGrossRevenue,bookedValueStatus:this.revenueStatus,revenueStatus:this.revenueStatus,currency:this.currency};a.capacityPct=a.total?Math.round(a.booked/a.total*100):0;let o=a.total-a.blocked;return a.sellThroughPct=o>0?Math.round(a.booked/o*100):0,a}recomputeTallies(){if(!this.closed){if(typeof requestAnimationFrame!="function"){this.flushTallies();return}this.paintHandle===null&&(this.paintHandle=requestAnimationFrame(()=>{this.paintHandle=null,this.flushTallies()}))}}flushTallies(){if(this.closed)return;let e=this.buildTallies();this.paintKpis(e),this.mode==="view"?(this.paintLegend(e),this.paintMonitorInsights()):this.mode==="inspect"?this.renderInspectRail(this.getSelection()):this.mode==="block"?this.paintSelBar(this.getSelection()):this.mode==="channels"&&this.channels?.handleSelectionChange(),this.opts.onTallies?.(e)}verbFor(e,t){return t==="held"?"held":t==="booked"?"booked":t==="blocked"?"blocked":t==="free"?e==="blocked"?"unblocked":e==="booked"?"cancelled":"available":t}pushActivity(e,t,s,i=Date.now()){let a=e[0];if(!a)return null;let o=this.sectionsForLabels(e),l={id:`${a}:${i}:${Math.random().toString(36).slice(2,6)}`,at:i,label:a,labels:[...e],count:e.length,verb:t,status:s,sectionIds:o.ids,sectionLabels:o.labels};return this.controlRoomSnapshot?.activity||this.feed.unshift(l),this.feed.length>R&&(this.feed.length=R),this.mode==="view"&&this.paintFeed(),this.showLiveEvent(l),this.opts.onActivity?.(l),l}seedFeed(e){this.controlRoomSnapshot?.activity&&(this.feed=this.feed.filter(i=>i.id.startsWith("log:")));let t={hold:"held",book:"booked",release:"released",expire:"expired",block:"blocked",unblock:"unblocked",unbook:"cancelled"},s={hold:"held",book:"booked",release:"free",expire:"free",block:"blocked",unblock:"free",unbook:"free"};for(let i of e){if(this.feed.some(r=>r.id===`log:${i.id}`))continue;let a=i.labels[0];if(!a)continue;let o=this.sectionsForLabels(i.labels),l={id:`log:${i.id}`,at:i.at,label:a,labels:[...i.labels],count:i.labels.length,verb:t[i.action]??i.action,status:s[i.action]??"free",sectionIds:o.ids,sectionLabels:o.labels};this.feed.push(l),this.opts.onActivity?.(l)}this.feed.sort((i,a)=>a.at-i.at),this.feed.length>R&&(this.feed.length=R),this.mode==="view"&&this.paintFeed()}startFeedClock(){this.feedTimer=setInterval(()=>{this.mode==="view"&&(this.paintFeed(),this.paintMonitorInsights())},1e4)}selectionCap(){return this.mode!=="select"?1e6:this.opts.numberOfPlacesToSelect??this.opts.maxSelectedObjects??1e6}canSelectObject(e){let t=this.status.get(e.label)??"free",s=this.opts.unavailableObjectsSelectable??!0,i=t==="free"||s||this.selectableObjectLabels.has(e.label);if(!this.opts.isObjectSelectable)return i;try{return this.opts.isObjectSelectable(e,i)===!0}catch(a){return this.opts.onError?.(a),!1}}applyInitialSelection(){this.initialSelectionApplied||this.mode!=="select"||!this.renderer||(this.initialSelectionApplied=!0,this.selectByLabels(this.opts.selectedObjects??[]))}trimSelectionToCap(){if(this.mode!=="select")return;let e=this.getSelection(),t=this.selectionCap();e.length<=t||this.renderer?.deselect(e.slice(t).map(s=>s.id))}reconcileSelectPolicy(){if(this.mode!=="select")return;let e=this.getSelection().filter(t=>!this.canSelectObject(t));e.length&&this.renderer?.deselect(e.map(t=>t.id)),this.trimSelectionToCap(),this.syncSelection()}selectionLabels(){return this.getSelection().map(e=>e.label)}syncSelection(){let e=this.getSelection();this.mode==="block"?this.paintSelBar(e):this.mode==="inspect"?this.renderInspectRail(e):this.mode==="select"?this.paintSelectSelection(e):this.mode==="categories"?this.paintCategorySelection(e):this.mode==="channels"&&this.channels?.handleSelectionChange();let t=new Map(e.map(s=>[s.label,s]));if(this.mode==="select"){for(let[i,a]of t)this.lastSelectionLabels.has(i)||this.opts.onObjectSelected?.(a);for(let i of this.lastSelectionLabels)if(!t.has(i)){let a=this.labelToSeat.get(i);a&&this.opts.onObjectDeselected?.(a)}let s=this.getSelectionValidity();s&&(this.opts.onSelectionValidityChange?.(s),this.selectionWasValid!==s.isValid&&(s.isValid?this.opts.onSelectionValid?.(s):this.opts.onSelectionInvalid?.(s)),this.selectionWasValid=s.isValid)}this.lastSelectionLabels=new Set(t.keys()),this.navigation?.selectionChanged(e.length),this.opts.onSelectionChange?.(e)}buildChrome(){let e=document.createElement("div");e.className="slm",e.tabIndex=0,e.setAttribute("role","region"),e.setAttribute("aria-label","SeatLayer live control room"),e.innerHTML=`
473
+ <span class="slm-liveeventhint">Live</span>`,t.classList.add("on"),this.liveEventTimer&&clearTimeout(this.liveEventTimer),this.liveEventTimer=setTimeout(()=>{this.liveEventTimer=null,t.classList.remove("on"),t.innerHTML=""},2800)}applyReportRevenue(e){this.authoritativeGrossRevenue=e.report.byCategory.reduce((t,s)=>{let i=Number.isFinite(s.bookedValue)?s.bookedValue:s.bookedRevenue;return t+(Number.isFinite(i)?i:0)},0),this.revenueStatus="current",this.recomputeTallies()}async refreshControlRoom(){let e=++this.revenueRequest,t=Date.now();try{let s=await this.api.controlRoom(this.key,this.trendWindowMinutes),i=s.bookedValue??s.revenue??{gross:0,bySection:[]},a=(i.bySection??[]).map(r=>{let c=Number.isFinite(r.bookedValue)?r.bookedValue:r.bookedRevenue;return{...r,bookedValue:c??0,bookedRevenue:c??0}}),o={...i,bySection:a},l={...s,bookedValue:o,revenue:o};if(e===this.revenueRequest){if(this.livePresence&&this.livePresence.at>=t?l={...l,presence:this.livePresence.value}:this.livePresence=null,this.liveGross&&this.liveGross.at>=t){let n={...l.bookedValue,gross:this.liveGross.value};l={...l,bookedValue:n,revenue:n}}else this.liveGross=null;this.controlRoomSnapshot=l,l.activity&&this.seedFeed(l.activity),this.rebaseServerTotals(l),this.lastSyncedAt=Date.now(),this.authoritativeGrossRevenue=l.bookedValue.gross,this.authoritativeCurrency=l.currency,this.currency=l.currency,this.revenueStatus="current",this.recomputeTallies(),this.applyHeatOverlay(),this.paintMonitorInsights(),this.seatHistoryPanel?.refresh();let r=this.getSelection().slice(-1)[0],c=this.els.rail?.querySelector("[data-seat-status]");r&&c&&(c.textContent=this.status.get(r.label)??"free"),this.opts.onControlRoom?.(l)}return l}catch(s){throw e===this.revenueRequest&&(this.revenueStatus="stale",this.recomputeTallies()),s}}rebaseServerTotals(e){let t=e.totals;if(!t||["free","held","booked","blocked"].some(s=>!Number.isFinite(t[s]))){this.serverBaseline=null;return}this.serverBaseline={model:this.modelVersion,server:{free:t.free,held:t.held,booked:t.booked,blocked:t.blocked},client:this.clientTallies()}}clientTallies(){let{held:e,booked:t,blocked:s}=this.counts;return{held:e,booked:t,blocked:s,free:Math.max(0,this.unitTotal()-e-t-s)}}buildTallies(){let e=this.clientTallies(),t=this.serverBaseline?.model===this.modelVersion?this.serverBaseline:null,s=l=>t?Math.max(0,t.server[l]+(e[l]-t.client[l])):e[l],i=this.controlRoomSnapshot?.event?.seatTotal,a={free:s("free"),held:s("held"),booked:s("booked"),blocked:s("blocked"),total:Number.isFinite(i)?i:this.unitTotal(),capacityPct:0,sellThroughPct:0,bookedValue:this.authoritativeGrossRevenue,grossRevenue:this.authoritativeGrossRevenue,bookedValueStatus:this.revenueStatus,revenueStatus:this.revenueStatus,currency:this.currency};a.capacityPct=a.total?Math.round(a.booked/a.total*100):0;let o=a.total-a.blocked;return a.sellThroughPct=o>0?Math.round(a.booked/o*100):0,a}recomputeTallies(){if(!this.closed){if(typeof requestAnimationFrame!="function"){this.flushTallies();return}this.paintHandle===null&&(this.paintHandle=requestAnimationFrame(()=>{this.paintHandle=null,this.flushTallies()}))}}flushTallies(){if(this.closed)return;let e=this.buildTallies();this.paintKpis(e),this.mode==="view"?(this.paintLegend(e),this.paintMonitorInsights()):this.mode==="inspect"?this.renderInspectRail(this.getSelection()):this.mode==="block"?this.paintSelBar(this.getSelection()):this.mode==="channels"&&this.channels?.handleSelectionChange(),this.opts.onTallies?.(e)}verbFor(e,t){return t==="held"?"held":t==="booked"?"booked":t==="blocked"?"blocked":t==="free"?e==="blocked"?"unblocked":e==="booked"?"cancelled":"available":t}pushActivity(e,t,s,i=Date.now()){let a=e[0];if(!a)return null;let o=this.sectionsForLabels(e),l={id:`${a}:${i}:${Math.random().toString(36).slice(2,6)}`,at:i,label:a,labels:[...e],count:e.length,verb:t,status:s,sectionIds:o.ids,sectionLabels:o.labels};return this.controlRoomSnapshot?.activity||this.feed.unshift(l),this.feed.length>$&&(this.feed.length=$),this.mode==="view"&&this.paintFeed(),this.showLiveEvent(l),this.opts.onActivity?.(l),l}seedFeed(e){this.controlRoomSnapshot?.activity&&(this.feed=this.feed.filter(i=>i.id.startsWith("log:")));let t={hold:"held",book:"booked",release:"released",expire:"expired",block:"blocked",unblock:"unblocked",unbook:"cancelled"},s={hold:"held",book:"booked",release:"free",expire:"free",block:"blocked",unblock:"free",unbook:"free"};for(let i of e){if(this.feed.some(r=>r.id===`log:${i.id}`))continue;let a=i.labels[0];if(!a)continue;let o=this.sectionsForLabels(i.labels),l={id:`log:${i.id}`,at:i.at,label:a,labels:[...i.labels],count:i.labels.length,verb:t[i.action]??i.action,status:s[i.action]??"free",sectionIds:o.ids,sectionLabels:o.labels};this.feed.push(l),this.opts.onActivity?.(l)}this.feed.sort((i,a)=>a.at-i.at),this.feed.length>$&&(this.feed.length=$),this.mode==="view"&&this.paintFeed()}startFeedClock(){this.feedTimer=setInterval(()=>{this.mode==="view"&&(this.paintFeed(),this.paintMonitorInsights())},1e4)}selectionCap(){return this.mode!=="select"?1e6:this.opts.numberOfPlacesToSelect??this.opts.maxSelectedObjects??1e6}canSelectObject(e){let t=this.status.get(e.label)??"free",s=this.opts.unavailableObjectsSelectable??!0,i=t==="free"||s||this.selectableObjectLabels.has(e.label);if(!this.opts.isObjectSelectable)return i;try{return this.opts.isObjectSelectable(e,i)===!0}catch(a){return this.opts.onError?.(a),!1}}applyInitialSelection(){this.initialSelectionApplied||this.mode!=="select"||!this.renderer||(this.initialSelectionApplied=!0,this.selectByLabels(this.opts.selectedObjects??[]))}trimSelectionToCap(){if(this.mode!=="select")return;let e=this.getSelection(),t=this.selectionCap();e.length<=t||this.renderer?.deselect(e.slice(t).map(s=>s.id))}reconcileSelectPolicy(){if(this.mode!=="select")return;let e=this.getSelection().filter(t=>!this.canSelectObject(t));e.length&&this.renderer?.deselect(e.map(t=>t.id)),this.trimSelectionToCap(),this.syncSelection()}selectionLabels(){return this.getSelection().map(e=>e.label)}syncSelection(){let e=this.getSelection();this.mode==="block"?this.paintSelBar(e):this.mode==="inspect"?this.renderInspectRail(e):this.mode==="select"?this.paintSelectSelection(e):this.mode==="categories"?this.paintCategorySelection(e):this.mode==="channels"&&this.channels?.handleSelectionChange();let t=new Map(e.map(s=>[s.label,s]));if(this.mode==="select"){for(let[i,a]of t)this.lastSelectionLabels.has(i)||this.opts.onObjectSelected?.(a);for(let i of this.lastSelectionLabels)if(!t.has(i)){let a=this.labelToSeat.get(i);a&&this.opts.onObjectDeselected?.(a)}let s=this.getSelectionValidity();s&&(this.opts.onSelectionValidityChange?.(s),this.selectionWasValid!==s.isValid&&(s.isValid?this.opts.onSelectionValid?.(s):this.opts.onSelectionInvalid?.(s)),this.selectionWasValid=s.isValid)}this.lastSelectionLabels=new Set(t.keys()),this.navigation?.selectionChanged(e.length),this.opts.onSelectionChange?.(e)}buildChrome(){let e=document.createElement("div");e.className="slm",e.tabIndex=0,e.setAttribute("role","region"),e.setAttribute("aria-label","SeatLayer live control room"),e.innerHTML=`
453
474
  <div class="slm-bar">
454
475
  <div class="slm-modes" data-ref="modes" role="tablist" aria-label="Control room tools">
455
- ${se.map(i=>`<div class="slm-modegroup" data-group="${i.key}" role="presentation" hidden>
476
+ ${oe.map(i=>`<div class="slm-modegroup" data-group="${i.key}" role="presentation" hidden>
456
477
  <span class="slm-modegroup-label" aria-hidden="true">${p(i.label)}</span>
457
478
  ${i.tools.map(a=>`<button class="slm-mode" role="tab" data-mode="${a.mode}"
458
479
  title="${p(a.title)} (${a.shortcut})" aria-keyshortcuts="${a.shortcut}" hidden>${p(a.label)}</button>`).join("")}
@@ -473,8 +494,10 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
473
494
  <div class="slm-body">
474
495
  <div class="slm-map">
475
496
  <div class="slm-map-host" data-ref="maphost"></div>
476
- <div class="slm-zoomhint" data-ref="zoomhint">Zoom in to marquee-select</div>
477
- <div class="slm-liveevent" data-ref="liveevent" role="status" aria-live="polite"></div>
497
+ <div class="slm-lane" data-ref="lane">
498
+ <div class="slm-zoomhint" data-ref="zoomhint">Zoom in to select seats</div>
499
+ <div class="slm-liveevent" data-ref="liveevent" role="status" aria-live="polite"></div>
500
+ </div>
478
501
  <div class="slm-heat-status" data-ref="heatstatus" role="status" hidden></div>
479
502
  <div class="slm-follow-status" data-ref="followstatus" role="status" hidden></div>
480
503
  <div class="slm-hud"><button class="slm-hud-chip" data-ref="zfit">Zoom to fit</button></div>
@@ -482,8 +505,8 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
482
505
  <aside class="slm-rail"><div class="slm-railscroll" data-ref="rail"></div></aside>
483
506
  </div>
484
507
  <div class="slm-toast" data-ref="toast"></div>
485
- `,this.host.appendChild(e),this.root=e,this.selectObserver=new MutationObserver(()=>{let i=e.querySelector(".slm-rail");i&&F(i)});let t=e.querySelector(".slm-rail");t&&this.selectObserver.observe(t,{childList:!0,subtree:!0}),this.applyThemeVars(),this.watchThemeMode(),this.updateContainerLayout(),typeof ResizeObserver<"u"&&(this.layoutObserver=new ResizeObserver(()=>this.updateContainerLayout()),this.layoutObserver.observe(e));let s=i=>e.querySelector(`[data-ref="${i}"]`);this.mapHost=s("maphost"),this.els={modes:s("modes"),tools:s("tools"),livetext:s("livetext"),kpis:s("kpis"),follow:s("follow"),heat:s("heat"),fullscreen:s("fullscreen"),zoomhint:s("zoomhint"),liveevent:s("liveevent"),rail:s("rail"),toast:s("toast"),zfit:s("zfit")},this.els.modes.querySelectorAll("[data-mode]").forEach(i=>i.addEventListener("click",()=>this.setMode(i.dataset.mode))),this.els.tools.addEventListener("change",()=>this.setMode(this.els.tools.value)),this.els.zfit.addEventListener("click",()=>{this.setFollowLive(!1),this.zoomToFit()}),this.els.follow.addEventListener("click",()=>this.setFollowLive(!this.followLive)),this.els.heat.addEventListener("click",()=>this.setHeatOverlay(!this.heatEnabled)),this.els.fullscreen.addEventListener("click",()=>this.toggleFullscreen()),e.addEventListener("keydown",this.onKeyDown),this.els.rail.addEventListener("click",this.onRailClick),document.addEventListener("fullscreenchange",this.onFullscreenChange),this.paintModeTabs(),this.paintFollowLiveButton(),this.paintHeatButton(),this.paintFullscreenButton(),this.navigation=new L({root:e,map:this.mapHost,setMoving:i=>{this.movingMap=i,this.updateRendererInteraction()},pauseFollow:()=>{this.followLive&&this.setFollowLive(!1)},zoomIn:()=>this.renderer?.zoomIn(),zoomOut:()=>this.renderer?.zoomOut(),targets:i=>this.navigationTargets(i)}),this.navigation.update(this.isBulkSelectMode(),this.mode==="view")}navigationTargets(e){let t=e.toLocaleLowerCase(),s=[];for(let a of this.sectionOptions)if(a.label.toLocaleLowerCase().includes(t)&&s.push({label:a.label,detail:"Section",locate:()=>this.locateSection(a.id)}),s.length>=20)return s;let i=new Map;for(let a of this.labelToSeat.values()){let o=i.get(a.rowId)??{minX:a.x,minY:a.y,maxX:a.x,maxY:a.y};o.minX=Math.min(o.minX,a.x),o.minY=Math.min(o.minY,a.y),o.maxX=Math.max(o.maxX,a.x),o.maxY=Math.max(o.maxY,a.y),i.set(a.rowId,o)}for(let a of this.doc?J(this.doc).flatMap(o=>o.objects):[]){if(a.type!=="row"||!(a.displayLabel??a.label).toLocaleLowerCase().includes(t))continue;let o=i.get(a.id);if(!o)continue;let{minX:l,minY:r,maxX:c,maxY:n}=o;if(s.push({label:a.displayLabel??a.label,detail:"Row",locate:()=>{let d=this.sectionByObject.get(a.id);d&&this.renderer?.focusSection(d),this.renderer?.focusRegion({x:l-30,y:r-30,width:c-l+60,height:n-r+60},{minScale:1.2,animate:!1})}}),s.length>=20)return s}for(let a of this.labelToSeat.values())if(a.label.toLocaleLowerCase().includes(t)&&(s.push({label:a.label,detail:"Seat",locate:()=>{let o=this.sectionByObject.get(a.rowId);o&&this.renderer?.focusSection(o),this.renderer?.focusRegion({x:a.x-180,y:a.y-120,width:360,height:240},{animate:!1,minScale:1.5}),this.renderer?.flashSeat(a.id,this.activityColor(this.status.get(a.label)??"free"))}}),s.length>=20))break;return s}updateContainerLayout(){let e=this.root?.getBoundingClientRect().width||this.host.clientWidth;this.root?.classList.toggle("compact",e>0&&e<800),this.channels?.handleLayoutChange()}filterableSections(){return this.sectionsBase?[...this.sectionsBase.sections,...this.sectionsBase.ungrouped?[this.sectionsBase.ungrouped]:[]]:[]}applyFilteredSectionCanvas(e=this.filterableSections().filter(t=>t.label===this.filteredSectionLabel)){if(!this.renderer||this.mode!=="filterSections"||!e.length)return;let t=new Set(e.map(n=>n.id)),s=this.filterableSections().filter(n=>!t.has(n.id)).map(n=>n.id);this.renderer.clearSectionFocus(),this.renderer.setClosedSections(null),this.renderer.setDimmedSections(s);let i=e.flatMap(n=>n.seatLabels).map(n=>this.labelToSeat.get(n)).filter(n=>!!n&&Number.isFinite(n.x)&&Number.isFinite(n.y));if(!i.length){this.renderer.focusRegion(e[0].id);return}let a=Math.min(...i.map(n=>n.x)),o=Math.min(...i.map(n=>n.y)),l=Math.max(...i.map(n=>n.x)),r=Math.max(...i.map(n=>n.y)),c=Math.max(40,Math.max(l-a,r-o)*.08);this.renderer.focusRegion({x:a-c,y:o-c,width:Math.max(1,l-a)+c*2,height:Math.max(1,r-o)+c*2})}buildSectionOptions(){if(this.doc)try{let e=je(this.doc);this.sectionsBase=e,this.sectionOptions=[],this.sectionByObject=new Map(e.objectToSection),this.sectionLabelById.clear();for(let t of e.sections)this.sectionOptions.push({id:t.id,label:t.label}),this.sectionLabelById.set(t.id,t.label);e.ungrouped&&(this.sectionOptions.push({id:y,label:e.ungrouped.label}),this.sectionLabelById.set(y,e.ungrouped.label))}catch{}}toolAvailable(e){return e==="view"?!0:e==="channels"&&!this.channelCaps.view||e==="categories"&&!this.categoryCanManage||e==="tables"&&(!this.tableCanManage||!this.tables().length)?!1:!this.opts.tools||this.opts.tools.includes(e)}settleMode(){this.toolAvailable(this.mode)?this.paintModeTabs():this.setMode("view")}tables(){return(this.doc?J(this.doc):[]).flatMap(e=>e.objects).filter(e=>e.type==="table")}paintModeTabs(){let e=[];this.els.modes?.querySelectorAll(".slm-modegroup").forEach(s=>{let i=[];s.querySelectorAll("[data-mode]").forEach(a=>{let o=a.dataset.mode,l=this.toolAvailable(o);if(a.hidden=!l,!l)return;i.push({mode:o,label:a.textContent??o});let r=o===this.mode;a.classList.toggle("on",r),a.setAttribute("aria-selected",String(r)),a.tabIndex=r?0:-1}),s.hidden=i.length===0,i.length&&e.push({label:s.querySelector(".slm-modegroup-label")?.textContent??"",tools:i})});let t=this.els.tools;t&&(t.innerHTML=e.map(s=>`<optgroup label="${p(s.label)}">${s.tools.map(i=>`<option value="${i.mode}"${i.mode===this.mode?" selected":""}>${p(i.label)}</option>`).join("")}</optgroup>`).join(""),t.value=this.mode),this.root?.classList.toggle("block-mode",this.mode==="block")}railHeader(e,t,s){let i=t==="read"?"Read-only":t==="event"?"This event only":"Your app";return`<div class="slm-railhead"><p class="slm-eyebrow">${p(e)}</p><span class="slm-scope ${t}">${i}</span></div>
486
- <p class="slm-hint">${s}</p>`}paintFollowLiveButton(){let e=this.els.follow;if(!e)return;e.classList.toggle("on",this.followLive),e.setAttribute("aria-pressed",String(this.followLive)),e.textContent="Auto-follow";let t=this.root?.querySelector('[data-ref="followstatus"]');t&&(t.hidden=!this.followLive,t.textContent="Waiting for new holds or bookings"),e.setAttribute("title",this.followLive?"Following new holds and bookings. Turn off to keep the current view.":"Stay on the current map view. Enable to follow new holds and bookings.")}paintHeatButton(){let e=this.els.heat;e&&(e.classList.toggle("on",this.heatEnabled),e.setAttribute("aria-pressed",String(this.heatEnabled)),e.setAttribute("aria-label",`Booking momentum overlay ${this.heatEnabled?"on":"off"}`),e.setAttribute("title",`${this.heatEnabled?"Hide":"Highlight"} sections booking fastest in the selected time window`),e.textContent="Heatmap",this.paintMomentumHelp())}paintMomentumHelp(){let e=this.root?.querySelector('[data-ref="heatstatus"]');if(e){e.hidden=!this.heatEnabled;let a=this.controlRoomSnapshot?.velocity.bySection.some(o=>o.netBooked>0);e.textContent=this.controlRoomSnapshot?a?`Booking heatmap \xB7 last ${this.trendWindowMinutes}m \xB7 warmer = higher net booking rate`:`No positive net bookings in the last ${this.trendWindowMinutes}m`:"Loading booking heatmap\u2026"}let t=this.els.rail?.querySelector('[data-ref="momentumhelp"]');if(!t)return;t.hidden=!this.heatEnabled;let s=t.querySelector('[data-ref="momentumcopy"]');if(!s)return;let i=this.controlRoomSnapshot?.velocity.bySection.some(a=>a.netBooked>0);s.textContent=i?"Warmer sections have more completed bookings, adjusted for section size. Holds and viewers are not counted.":`No completed bookings in the last ${this.trendWindowMinutes} minutes.`}paintFullscreenButton(){this.els.fullscreen&&(this.els.fullscreen.textContent=this.isFullscreen()?"Exit full screen":"Full screen")}paintTrendWindow(){this.els.rail?.querySelectorAll("[data-window]").forEach(e=>{let t=Number(e.dataset.window);e.classList.toggle("on",t===this.trendWindowMinutes)})}setLive(e){this.root?.classList.toggle("live",e),this.els.livetext&&(this.els.livetext.textContent=e?"LIVE":"RECONNECTING"),this.paintMonitorInsights();let t=e?"live":"reconnecting";if(t!==this.connectionStatus){this.connectionStatus=t;try{this.opts.onConnectionChange?.(this.getConnection())}catch(s){this.opts.onError?.(s)}}}updateZoomHint(){let e=this.els.zoomhint;if(!e)return;let t=this.isBulkSelectMode()&&!this.movingMap&&this.renderer?.getRung?.()!=="seats";e.classList.toggle("on",!!t)}formatKpiDelta(e,t,s){let i=t>0?"+":"\u2212",a=Math.abs(t);return e==="booked-value"?`${i}${C(a,s)}`:e==="booked-pct"?`${i}${a.toLocaleString()}pt`:`${i}${a.toLocaleString()}`}paintKpis(e){if(!this.els.kpis)return;let t=e.bookedValueStatus==="current"?C(e.bookedValue,e.currency):"\u2014",s=this.presenceCounts(),i=[{key:"booked-inventory",raw:e.booked,n:e.booked.toLocaleString(),l:"Booked inventory",dot:"#22a06b",title:"Inventory units booked"},{key:"held-seats",raw:e.held,n:e.held.toLocaleString(),l:"Held inventory",dot:"#f4b740",title:"Inventory currently held"},{key:"free-seats",raw:e.free,n:e.free.toLocaleString(),l:"Available",dot:"#6e7bff",title:"Inventory available to book"},{key:"blocked",raw:e.blocked,n:e.blocked.toLocaleString(),l:"Blocked",dot:"#8b94ac",title:"Inventory withheld from booking"},{key:"viewing-map",raw:s?.shoppingSessions??null,n:s?s.shoppingSessions.toLocaleString():"\u2014",l:"Viewing map",title:"Active map sessions right now"},{key:"active-holds",raw:s?.activeHolds??null,n:s?s.activeHolds.toLocaleString():"\u2014",l:"Active holds",title:"Sessions currently holding inventory"},{key:"booked-pct",raw:e.capacityPct,n:`${e.capacityPct}%`,l:"Booked",title:"Booked inventory as a share of the whole event"},{key:"booked-value",raw:e.bookedValueStatus==="current"?e.bookedValue:null,n:t,l:"Booked value",title:"Configured value attached to booked inventory"}],a=!1;this.els.kpis.innerHTML=i.map(o=>{let l=this.lastKpiValues.get(o.key),r=o.raw!=null&&l!=null&&o.raw!==l,c=r?o.raw-l:0;r&&(a=!0,this.activeKpiDeltas.set(o.key,{text:this.formatKpiDelta(o.key,c,e.currency),down:c<0})),o.raw!=null&&this.lastKpiValues.set(o.key,o.raw);let n=this.activeKpiDeltas.get(o.key);return`<div class="slm-kpi${n?" changed":""}" data-kpi="${o.key}" title="${p(o.title)}">
508
+ `,this.host.appendChild(e),this.root=e,this.selectObserver=new MutationObserver(()=>{let i=e.querySelector(".slm-rail");i&&P(i)});let t=e.querySelector(".slm-rail");t&&this.selectObserver.observe(t,{childList:!0,subtree:!0}),this.applyThemeVars(),this.watchThemeMode(),this.updateContainerLayout(),typeof ResizeObserver<"u"&&(this.layoutObserver=new ResizeObserver(()=>this.updateContainerLayout()),this.layoutObserver.observe(e));let s=i=>e.querySelector(`[data-ref="${i}"]`);this.mapHost=s("maphost"),this.els={modes:s("modes"),tools:s("tools"),livetext:s("livetext"),kpis:s("kpis"),follow:s("follow"),heat:s("heat"),fullscreen:s("fullscreen"),lane:s("lane"),zoomhint:s("zoomhint"),liveevent:s("liveevent"),rail:s("rail"),toast:s("toast"),zfit:s("zfit")},this.els.modes.querySelectorAll("[data-mode]").forEach(i=>i.addEventListener("click",()=>this.setMode(i.dataset.mode))),this.els.tools.addEventListener("change",()=>this.setMode(this.els.tools.value)),this.els.zfit.addEventListener("click",()=>{this.setFollowLive(!1),this.zoomToFit()}),this.els.follow.addEventListener("click",()=>this.setFollowLive(!this.followLive)),this.els.heat.addEventListener("click",()=>this.setHeatOverlay(!this.heatEnabled)),this.els.fullscreen.addEventListener("click",()=>this.toggleFullscreen()),e.addEventListener("keydown",this.onKeyDown),this.els.rail.addEventListener("click",this.onRailClick),document.addEventListener("fullscreenchange",this.onFullscreenChange),this.paintModeTabs(),this.paintFollowLiveButton(),this.paintHeatButton(),this.paintFullscreenButton(),this.navigation=new T({root:e,map:this.mapHost,setMoving:i=>{this.movingMap=i,this.updateRendererInteraction()},pauseFollow:()=>{this.followLive&&this.setFollowLive(!1)},clearSelection:()=>this.clearSelection(),zoomIn:()=>this.renderer?.zoomIn(),zoomOut:()=>this.renderer?.zoomOut(),targets:i=>this.navigationTargets(i)}),this.navigation.update(this.isBulkSelectMode(),this.mode==="view")}navigationTargets(e){let t=e.toLocaleLowerCase(),s=[];for(let a of this.sectionOptions)if(a.label.toLocaleLowerCase().includes(t)&&s.push({label:a.label,detail:"Section",locate:()=>this.locateSection(a.id)}),s.length>=20)return s;let i=new Map;for(let a of this.labelToSeat.values()){let o=i.get(a.rowId)??{minX:a.x,minY:a.y,maxX:a.x,maxY:a.y};o.minX=Math.min(o.minX,a.x),o.minY=Math.min(o.minY,a.y),o.maxX=Math.max(o.maxX,a.x),o.maxY=Math.max(o.maxY,a.y),i.set(a.rowId,o)}for(let a of this.doc?se(this.doc).flatMap(o=>o.objects):[]){if(a.type!=="row"||!(a.displayLabel??a.label).toLocaleLowerCase().includes(t))continue;let o=i.get(a.id);if(!o)continue;let{minX:l,minY:r,maxX:c,maxY:n}=o;if(s.push({label:a.displayLabel??a.label,detail:"Row",locate:()=>{let d=this.sectionByObject.get(a.id);d&&this.renderer?.focusSection(d),this.renderer?.focusRegion({x:l-30,y:r-30,width:c-l+60,height:n-r+60},{minScale:1.2,animate:!1})}}),s.length>=20)return s}for(let a of this.labelToSeat.values())if(a.label.toLocaleLowerCase().includes(t)&&(s.push({label:a.label,detail:"Seat",locate:()=>{let o=this.sectionByObject.get(a.rowId);o&&this.renderer?.focusSection(o),this.renderer?.focusRegion({x:a.x-180,y:a.y-120,width:360,height:240},{animate:!1,minScale:1.5}),this.renderer?.flashSeat(a.id,this.activityColor(this.status.get(a.label)??"free"))}}),s.length>=20))break;return s}updateContainerLayout(){let e=this.root?.getBoundingClientRect().width||this.host.clientWidth;this.root?.classList.toggle("compact",e>0&&e<800),this.channels?.handleLayoutChange()}filterableSections(){return this.sectionsBase?[...this.sectionsBase.sections,...this.sectionsBase.ungrouped?[this.sectionsBase.ungrouped]:[]]:[]}applyFilteredSectionCanvas(e=this.filterableSections().filter(t=>t.label===this.filteredSectionLabel)){if(!this.renderer||this.mode!=="filterSections"||!e.length)return;let t=new Set(e.map(n=>n.id)),s=this.filterableSections().filter(n=>!t.has(n.id)).map(n=>n.id);this.renderer.clearSectionFocus(),this.renderer.setClosedSections(null),this.renderer.setDimmedSections(s);let i=e.flatMap(n=>n.seatLabels).map(n=>this.labelToSeat.get(n)).filter(n=>!!n&&Number.isFinite(n.x)&&Number.isFinite(n.y));if(!i.length){this.renderer.focusRegion(e[0].id);return}let a=Math.min(...i.map(n=>n.x)),o=Math.min(...i.map(n=>n.y)),l=Math.max(...i.map(n=>n.x)),r=Math.max(...i.map(n=>n.y)),c=Math.max(40,Math.max(l-a,r-o)*.08);this.renderer.focusRegion({x:a-c,y:o-c,width:Math.max(1,l-a)+c*2,height:Math.max(1,r-o)+c*2})}buildSectionOptions(){if(this.doc)try{let e=Ue(this.doc);this.sectionsBase=e,this.sectionOptions=[],this.sectionByObject=new Map(e.objectToSection),this.sectionLabelById.clear();for(let t of e.sections)this.sectionOptions.push({id:t.id,label:t.label}),this.sectionLabelById.set(t.id,t.label);e.ungrouped&&(this.sectionOptions.push({id:x,label:e.ungrouped.label}),this.sectionLabelById.set(x,e.ungrouped.label))}catch{}}toolAvailable(e){return e==="view"?!0:e==="channels"&&!this.channelCaps.view||e==="categories"&&!this.categoryCanManage||e==="tables"&&(!this.tableCanManage||!this.tables().length)?!1:!this.opts.tools||this.opts.tools.includes(e)}settleMode(){this.toolAvailable(this.mode)?this.paintModeTabs():this.setMode("view")}tables(){return(this.doc?se(this.doc):[]).flatMap(e=>e.objects).filter(e=>e.type==="table")}paintModeTabs(){let e=[];this.els.modes?.querySelectorAll(".slm-modegroup").forEach(s=>{let i=[];s.querySelectorAll("[data-mode]").forEach(a=>{let o=a.dataset.mode,l=this.toolAvailable(o);if(a.hidden=!l,!l)return;i.push({mode:o,label:a.textContent??o});let r=o===this.mode;a.classList.toggle("on",r),a.setAttribute("aria-selected",String(r)),a.tabIndex=r?0:-1}),s.hidden=i.length===0,i.length&&e.push({label:s.querySelector(".slm-modegroup-label")?.textContent??"",tools:i})});let t=this.els.tools;t&&(t.innerHTML=e.map(s=>`<optgroup label="${p(s.label)}">${s.tools.map(i=>`<option value="${i.mode}"${i.mode===this.mode?" selected":""}>${p(i.label)}</option>`).join("")}</optgroup>`).join(""),t.value=this.mode),this.root?.classList.toggle("block-mode",this.mode==="block")}railHeader(e,t,s){let i=t==="read"?"Read-only":t==="event"?"This event only":"Your app";return`<div class="slm-railhead"><p class="slm-eyebrow">${p(e)}</p><span class="slm-scope ${t}">${i}</span></div>
509
+ <p class="slm-hint">${s}</p>`}paintFollowLiveButton(){let e=this.els.follow;if(!e)return;e.classList.toggle("on",this.followLive),e.setAttribute("aria-pressed",String(this.followLive)),e.textContent="Auto-follow";let t=this.root?.querySelector('[data-ref="followstatus"]');t&&(t.hidden=!this.followLive,t.textContent="Waiting for new holds or bookings"),e.setAttribute("title",this.followLive?"Following new holds and bookings. Turn off to keep the current view.":"Stay on the current map view. Enable to follow new holds and bookings.")}paintHeatButton(){let e=this.els.heat;e&&(e.classList.toggle("on",this.heatEnabled),e.setAttribute("aria-pressed",String(this.heatEnabled)),e.setAttribute("aria-label",`Booking momentum overlay ${this.heatEnabled?"on":"off"}`),e.setAttribute("title",`${this.heatEnabled?"Hide":"Highlight"} sections booking fastest in the selected time window`),e.textContent="Heatmap",this.paintMomentumHelp())}paintMomentumHelp(){let e=this.root?.querySelector('[data-ref="heatstatus"]');if(e){e.hidden=!this.heatEnabled;let a=this.controlRoomSnapshot?.velocity.bySection.some(o=>o.netBooked>0);e.textContent=this.controlRoomSnapshot?a?`Booking heatmap \xB7 last ${this.trendWindowMinutes}m \xB7 warmer = higher net booking rate`:`No positive net bookings in the last ${this.trendWindowMinutes}m`:"Loading booking heatmap\u2026"}let t=this.els.rail?.querySelector('[data-ref="momentumhelp"]');if(!t)return;t.hidden=!this.heatEnabled;let s=t.querySelector('[data-ref="momentumcopy"]');if(!s)return;let i=this.controlRoomSnapshot?.velocity.bySection.some(a=>a.netBooked>0);s.textContent=i?"Warmer sections have more completed bookings, adjusted for section size. Holds and viewers are not counted.":`No completed bookings in the last ${this.trendWindowMinutes} minutes.`}paintFullscreenButton(){this.els.fullscreen&&(this.els.fullscreen.textContent=this.isFullscreen()?"Exit full screen":"Full screen")}paintTrendWindow(){this.els.rail?.querySelectorAll("[data-window]").forEach(e=>{let t=Number(e.dataset.window);e.classList.toggle("on",t===this.trendWindowMinutes)})}setLive(e){this.root?.classList.toggle("live",e),this.els.livetext&&(this.els.livetext.textContent=e?"LIVE":"RECONNECTING"),this.paintMonitorInsights();let t=e?"live":"reconnecting";if(t!==this.connectionStatus){this.connectionStatus=t;try{this.opts.onConnectionChange?.(this.getConnection())}catch(s){this.opts.onError?.(s)}}}updateZoomHint(){let e=this.els.zoomhint;if(!e)return;let t=this.isBulkSelectMode()&&!this.movingMap&&this.renderer?.getRung?.()!=="seats";e.classList.toggle("on",!!t)}formatKpiDelta(e,t,s){let i=t>0?"+":"\u2212",a=Math.abs(t);return e==="booked-value"?`${i}${R(a,s)}`:e==="booked-pct"?`${i}${a.toLocaleString()}pt`:`${i}${a.toLocaleString()}`}paintKpis(e){if(!this.els.kpis)return;let t=e.bookedValueStatus==="current"?R(e.bookedValue,e.currency):"\u2014",s=this.presenceCounts(),i=[{key:"booked-inventory",raw:e.booked,n:e.booked.toLocaleString(),l:"Booked inventory",dot:y.booked,title:"Inventory units booked"},{key:"held-seats",raw:e.held,n:e.held.toLocaleString(),l:"Held inventory",dot:y.held,title:"Inventory currently held"},{key:"free-seats",raw:e.free,n:e.free.toLocaleString(),l:"Available",dot:y.free,title:"Inventory available to book"},{key:"blocked",raw:e.blocked,n:e.blocked.toLocaleString(),l:"Blocked",dot:y.blocked,title:"Inventory withheld from booking"},{key:"viewing-map",raw:s?.shoppingSessions??null,n:s?s.shoppingSessions.toLocaleString():"\u2014",l:"Viewing map",title:"Active map sessions right now"},{key:"active-holds",raw:s?.activeHolds??null,n:s?s.activeHolds.toLocaleString():"\u2014",l:"Active holds",title:"Sessions currently holding inventory"},{key:"booked-pct",raw:e.capacityPct,n:`${e.capacityPct}%`,l:"Booked",title:"Booked inventory as a share of the whole event"},{key:"booked-value",raw:e.bookedValueStatus==="current"?e.bookedValue:null,n:t,l:"Booked value",title:"Configured value attached to booked inventory"}],a=!1;this.els.kpis.innerHTML=i.map(o=>{let l=this.lastKpiValues.get(o.key),r=o.raw!=null&&l!=null&&o.raw!==l,c=r?o.raw-l:0;r&&(a=!0,this.activeKpiDeltas.set(o.key,{text:this.formatKpiDelta(o.key,c,e.currency),down:c<0})),o.raw!=null&&this.lastKpiValues.set(o.key,o.raw);let n=this.activeKpiDeltas.get(o.key);return`<div class="slm-kpi${n?" changed":""}" data-kpi="${o.key}" title="${p(o.title)}">
487
510
  <b>${o.dot?`<span class="dot" style="background:${o.dot}"></span>`:""}${o.n}</b><span>${o.l}</span>
488
511
  ${n?`<span class="slm-kpidelta${n.down?" down":""}">${n.text}</span>`:""}
489
512
  </div>`}).join(""),a&&(this.kpiCleanupTimer&&clearTimeout(this.kpiCleanupTimer),this.kpiCleanupTimer=setTimeout(()=>{this.kpiCleanupTimer=null,this.activeKpiDeltas.clear(),this.els.kpis?.querySelectorAll(".slm-kpidelta").forEach(o=>o.remove()),this.els.kpis?.querySelectorAll(".slm-kpi.changed").forEach(o=>o.classList.remove("changed"))},1500))}paintRail(){this.root?.classList.toggle("monitor-view",this.mode==="view"||this.mode==="inspect"),this.seatHistoryPanel?.destroy(),this.seatHistoryPanel=null,this.activityPanel?.destroy(),this.activityPanel=null,this.mode==="view"?this.renderViewRail():this.mode==="inspect"?this.renderInspectRail(this.getSelection()):this.mode==="select"?this.renderSelectRail():this.mode==="filterSections"?this.renderFilterSectionsRail():this.mode==="sections"?this.renderSectionsRail():this.mode==="categories"?this.renderCategoriesRail():this.mode==="tables"?this.renderTablesRail():this.mode==="channels"?this.channels?this.channels.paintRail():this.channelsLoading?this.els.rail.innerHTML='<div class="slm-empty" role="status">Loading sales channels\u2026</div>':this.els.rail.innerHTML='<div class="slm-empty" role="alert">Sales channels could not be loaded. Switch away and back to try again.</div>':this.renderBlockRail(),this.updateZoomHint()}renderViewRail(){this.els.rail.innerHTML=`
@@ -505,8 +528,8 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
505
528
  </div>
506
529
  <div class="slm-sectionlist" data-ref="sections"></div>
507
530
  </div>
508
- `,this.els.presence=this.els.rail.querySelector('[data-ref="presence"]'),this.els.legend=this.els.rail.querySelector('[data-ref="legend"]'),this.els.sections=this.els.rail.querySelector('[data-ref="sections"]'),this.els.feed=this.els.rail.querySelector('[data-ref="feed"]'),this.activityPanel=new w(this.els.feed,this.sectionOptions,e=>{this.setFollowLive(!1),this.locateActivity(e)}),this.els.rail.querySelectorAll("[data-monitor-tab]").forEach(e=>e.addEventListener("click",()=>{let t=e.dataset.monitorTab;this.els.rail.querySelectorAll("[data-monitor-tab]").forEach(s=>s.setAttribute("aria-selected",String(s.dataset.monitorTab===t))),this.els.rail.querySelectorAll("[data-monitor-panel]").forEach(s=>{s.hidden=s.dataset.monitorPanel!==t})})),this.els.rail.querySelectorAll("[data-window]").forEach(e=>e.addEventListener("click",()=>{let t=Number(e.dataset.window);this.setTrendWindow(t).catch(s=>this.opts.onError?.(s))})),this.recomputeTallies(),this.paintMonitorInsights(),this.paintTrendWindow(),this.paintMomentumHelp(),this.paintFeed()}presenceCounts(){return this.livePresence?.value??this.controlRoomSnapshot?.presence??null}paintMonitorInsights(){if(this.mode!=="view")return;let e=this.controlRoomSnapshot;if(this.els.presence){let i=this.root?.classList.contains("live"),a=this.lastSyncedAt?X(this.lastSyncedAt,Date.now()):"waiting";this.els.presence.textContent=i?"\u25CF Live":"Reconnecting",this.els.presence.title=`Last data received: ${a}`}if(!this.els.sections)return;if(!e){this.els.sections.innerHTML='<div class="slm-empty">Loading authoritative section metrics\u2026</div>';return}let t=new Map(e.velocity.bySection.map(i=>[i.sectionId,i])),s=[...e.bookedValue.bySection].sort((i,a)=>{let o=t.get(i.sectionId)?.netBooked??0;return(t.get(a.sectionId)?.netBooked??0)-o||a.bookedValue-i.bookedValue});this.els.sections.innerHTML=s.length?s.map(i=>{let a=t.get(i.sectionId),o=a?.netBooked??0,l=`${o>0?"+":""}${o}`,r=a?.trend==="rising"||a?.trend==="cooling"?a.trend:"steady";return`<button type="button" class="slm-sectionrow" data-section-focus="${p(i.sectionId)}" title="Focus ${p(i.sectionLabel)} on the map">
509
- <span class="slm-sectiontop"><span>${p(i.sectionLabel)}</span><span title="Configured value of currently booked inventory">${C(i.bookedValue,e.currency)}</span></span>
531
+ `,this.els.presence=this.els.rail.querySelector('[data-ref="presence"]'),this.els.legend=this.els.rail.querySelector('[data-ref="legend"]'),this.els.sections=this.els.rail.querySelector('[data-ref="sections"]'),this.els.feed=this.els.rail.querySelector('[data-ref="feed"]'),this.activityPanel=new L(this.els.feed,this.sectionOptions,e=>{this.setFollowLive(!1),this.locateActivity(e)}),this.els.rail.querySelectorAll("[data-monitor-tab]").forEach(e=>e.addEventListener("click",()=>{let t=e.dataset.monitorTab;this.els.rail.querySelectorAll("[data-monitor-tab]").forEach(s=>s.setAttribute("aria-selected",String(s.dataset.monitorTab===t))),this.els.rail.querySelectorAll("[data-monitor-panel]").forEach(s=>{s.hidden=s.dataset.monitorPanel!==t})})),this.els.rail.querySelectorAll("[data-window]").forEach(e=>e.addEventListener("click",()=>{let t=Number(e.dataset.window);this.setTrendWindow(t).catch(s=>this.opts.onError?.(s))})),this.recomputeTallies(),this.paintMonitorInsights(),this.paintTrendWindow(),this.paintMomentumHelp(),this.paintFeed()}presenceCounts(){return this.livePresence?.value??this.controlRoomSnapshot?.presence??null}paintMonitorInsights(){if(this.mode!=="view")return;let e=this.controlRoomSnapshot;if(this.els.presence){let i=this.root?.classList.contains("live"),a=this.lastSyncedAt?ee(this.lastSyncedAt,Date.now()):"waiting";this.els.presence.textContent=i?"\u25CF Live":"Reconnecting",this.els.presence.title=`Last data received: ${a}`}if(!this.els.sections)return;if(!e){this.els.sections.innerHTML='<div class="slm-empty">Loading authoritative section metrics\u2026</div>';return}let t=new Map(e.velocity.bySection.map(i=>[i.sectionId,i])),s=[...e.bookedValue.bySection].sort((i,a)=>{let o=t.get(i.sectionId)?.netBooked??0;return(t.get(a.sectionId)?.netBooked??0)-o||a.bookedValue-i.bookedValue});this.els.sections.innerHTML=s.length?s.map(i=>{let a=t.get(i.sectionId),o=a?.netBooked??0,l=`${o>0?"+":""}${o}`,r=a?.trend==="rising"||a?.trend==="cooling"?a.trend:"steady";return`<button type="button" class="slm-sectionrow" data-section-focus="${p(i.sectionId)}" title="Focus ${p(i.sectionLabel)} on the map">
532
+ <span class="slm-sectiontop"><span>${p(i.sectionLabel)}</span><span title="Configured value of currently booked inventory">${R(i.bookedValue,e.currency)}</span></span>
510
533
  <span class="slm-sectionmeta"><span>${i.booked.toLocaleString()}/${i.total.toLocaleString()} booked \xB7 ${l} net in ${e.velocity.windowMinutes}m</span><span class="slm-trend ${r}">${r}</span><span class="slm-sectionlocate">Locate</span></span>
511
534
  </button>`}).join(""):'<div class="slm-empty">No section metrics are available for this chart.</div>',this.paintTrendWindow(),this.paintMomentumHelp()}applyHeatOverlay(){let e=this.controlRoomSnapshot;if(!this.heatEnabled||!e){this.renderer?.setSectionHeat(null);return}let t=new Map(e.bookedValue.bySection.map(o=>[o.sectionId,Math.max(1,o.total)])),s=e.velocity.bySection.map(o=>({sectionId:o.sectionId,rate:Math.max(0,o.netBooked)/(t.get(o.sectionId)??1)/e.velocity.windowMinutes})),i=Math.max(0,...s.map(o=>o.rate)),a={};for(let o of s)a[o.sectionId]=i>0?Math.sqrt(o.rate/i):0;this.renderer?.setSectionHeat(a)}renderSelectRail(){let e=this.doc?.categories??[],t=this.opts.numberOfPlacesToSelect,s=this.selectionCap();this.els.rail.innerHTML=`
512
535
  ${this.railHeader("Select","host","Pick seats for your own back-office operation \u2014 the selection is handed to your app. This tool is read-only inside the control room: it never books, releases or blocks seats by itself.")}
@@ -559,7 +582,7 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
559
582
  ${this.railHeader("Tables","event",t)}
560
583
  <div class="slm-empty">This event still uses the older inventory model, which cannot switch tables between per-chair and whole-table selling. Upgrade the event's inventory model to unlock this tool.</div>`;return}if(!e.length){this.els.rail.innerHTML=`
561
584
  ${this.railHeader("Tables","event",t)}
562
- <div class="slm-empty">This chart has no tables. Add tables in the designer and they will appear here.</div>`;return}let s=d=>d.variableOccupancy?"variable":d.bookAsWhole?"whole":"individual",i=d=>{let m=0,b=0,g=0;for(let[u,f]of this.labelToSeat){if(f.rowId!==d.id)continue;let x=this.status.get(u);x==="held"?m++:x==="booked"?b++:x==="blocked"&&g++}let v=[b&&`${b} booked`,m&&`${m} held`,g&&`${g} blocked`].filter(Boolean);return v.length?v.join(" \xB7 "):null},a=e.map(d=>({table:d,current:s(d),locked:i(d)})),o=a.filter(d=>d.current==="individual").length,l=a.filter(d=>d.current==="whole").length,r=a.length-o-l,c=[`${o.toLocaleString()} per chair`,`${l.toLocaleString()} whole table`,r?`${r.toLocaleString()} flexible group`:""].filter(Boolean).join(" \xB7 "),n=this.tableBookingSaving;this.els.rail.innerHTML=`
585
+ <div class="slm-empty">This chart has no tables. Add tables in the designer and they will appear here.</div>`;return}let s=d=>d.variableOccupancy?"variable":d.bookAsWhole?"whole":"individual",i=d=>{let m=0,b=0,g=0;for(let[u,f]of this.labelToSeat){if(f.rowId!==d.id)continue;let k=this.status.get(u);k==="held"?m++:k==="booked"?b++:k==="blocked"&&g++}let v=[b&&`${b} booked`,m&&`${m} held`,g&&`${g} blocked`].filter(Boolean);return v.length?v.join(" \xB7 "):null},a=e.map(d=>({table:d,current:s(d),locked:i(d)})),o=a.filter(d=>d.current==="individual").length,l=a.filter(d=>d.current==="whole").length,r=a.length-o-l,c=[`${o.toLocaleString()} per chair`,`${l.toLocaleString()} whole table`,r?`${r.toLocaleString()} flexible group`:""].filter(Boolean).join(" \xB7 "),n=this.tableBookingSaving;this.els.rail.innerHTML=`
563
586
  ${this.railHeader("Tables","event",t)}
564
587
  <div class="slm-tablesummary"><b>${a.length.toLocaleString()} ${a.length===1?"table":"tables"}</b><span>${p(c)}</span></div>
565
588
  <p class="slm-eyebrow" style="margin-top:12px">Set every table at once</p>
@@ -579,14 +602,14 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
579
602
  </div>`).join("")}</div>
580
603
  <p class="slm-note">Changes apply immediately to this event. Flexible group sizes (minimum and maximum guests) are set through the API, never guessed here.</p>`,this.els.rail.querySelectorAll("[data-table-all]").forEach(d=>{d.addEventListener("click",()=>{this.setTableBooking(a.filter(m=>!m.locked).map(m=>m.table.id),d.dataset.tableAll)})}),this.els.rail.querySelectorAll("[data-table-mode]").forEach(d=>{d.addEventListener("change",()=>{this.setTableBooking([d.dataset.tableMode],d.value)})})}renderInspectRail(e){let t=e[e.length-1];if(!t){this.els.rail.innerHTML=`
581
604
  ${this.railHeader("Inspect","read","Click one seat on the map to read its live status, category, section and booking context. Nothing changes in this view.")}
582
- <div class="slm-empty">Select a seat on the map.</div>`;return}let s=this.status.get(t.label)??"free",i={free:"Free",held:"Held",booked:"Booked",blocked:"Blocked"},a=this.sectionByObject.get(t.rowId)??y,o=this.sectionLabelById.get(a)??"Other seats",l=this.doc?.categories.find(c=>c.key===t.categoryKey);this.els.rail.innerHTML=`
605
+ <div class="slm-empty">Select a seat on the map.</div>`;return}let s=this.status.get(t.label)??"free",i={free:"Free",held:"Held",booked:"Booked",blocked:"Blocked"},a=this.sectionByObject.get(t.rowId)??x,o=this.sectionLabelById.get(a)??"Other seats",l=this.doc?.categories.find(c=>c.key===t.categoryKey);this.els.rail.innerHTML=`
583
606
  <div class="slm-seat-heading"><h2>${p(t.label)}</h2><span data-seat-status>${i[s]}</span></div>
584
607
  <p class="slm-note">${p(o)} \xB7 ${p(l?.label??t.categoryKey)}</p>
585
- <div data-ref="seat-history"></div>`;let r=this.els.rail.querySelector('[data-ref="seat-history"]');this.seatHistoryPanel=new S(r,(c,n)=>this.withAuthRetry(()=>this.api.seatHistory(this.key,t.label,c,n)))}async refreshAvailability(){try{let e=await this.withAuthRetry(()=>this.api.availability(this.key));this.availabilityRules=e.rules??{},this.effectiveClosed=new Set(I(this.availabilityRules)),this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment()}catch(e){this.opts.onError?.(e)}}async withAuthRetry(e){try{return await e()}catch(t){if(t instanceof k&&t.status===401&&this.opts.onTokenRefresh&&!this.tokenRefreshInFlight)return await this.rotateToken(),e();throw t}}updateEffectiveAvailability(e,t){let s=!1;Array.isArray(e)&&(this.effectiveHidden=new Set(e.filter(i=>typeof i=="string")),s=!0),Array.isArray(t)&&(this.effectiveClosed=new Set(t.filter(i=>typeof i=="string")),s=!0),s&&(this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment())}applySectionCanvasTreatment(){this.renderer&&(this.mode==="sections"?(this.renderer.setDimmedSections([...this.effectiveHidden]),this.renderer.setClosedSections([...this.effectiveClosed])):this.mode==="filterSections"&&this.filteredSectionLabel?this.applyFilteredSectionCanvas():(this.renderer.setDimmedSections(null),this.renderer.setClosedSections(null)))}sectionRowsInput(){return{sectionsBase:this.sectionsBase,doc:this.doc,availabilityRules:this.availabilityRules,effectiveHidden:this.effectiveHidden,effectiveClosed:this.effectiveClosed}}renderSectionsRail(){let{rows:e,hiddenSections:t,closedSections:s}=E(this.sectionRowsInput());if(!e.length){this.els.rail.innerHTML=`
608
+ <div data-ref="seat-history"></div>`;let r=this.els.rail.querySelector('[data-ref="seat-history"]');this.seatHistoryPanel=new w(r,(c,n)=>this.withAuthRetry(()=>this.api.seatHistory(this.key,t.label,c,n)))}async refreshAvailability(){try{let e=await this.withAuthRetry(()=>this.api.availability(this.key));this.availabilityRules=e.rules??{},this.effectiveClosed=new Set(O(this.availabilityRules)),this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment()}catch(e){this.opts.onError?.(e)}}async withAuthRetry(e){try{return await e()}catch(t){if(t instanceof S&&t.status===401&&this.opts.onTokenRefresh&&!this.tokenRefreshInFlight)return await this.rotateToken(),e();throw t}}updateEffectiveAvailability(e,t){let s=!1;Array.isArray(e)&&(this.effectiveHidden=new Set(e.filter(i=>typeof i=="string")),s=!0),Array.isArray(t)&&(this.effectiveClosed=new Set(t.filter(i=>typeof i=="string")),s=!0),s&&(this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment())}applySectionCanvasTreatment(){this.renderer&&(this.mode==="sections"?(this.renderer.setDimmedSections([...this.effectiveHidden]),this.renderer.setClosedSections([...this.effectiveClosed])):this.mode==="filterSections"&&this.filteredSectionLabel?this.applyFilteredSectionCanvas():(this.renderer.setDimmedSections(null),this.renderer.setClosedSections(null)))}sectionRowsInput(){return{sectionsBase:this.sectionsBase,doc:this.doc,availabilityRules:this.availabilityRules,effectiveHidden:this.effectiveHidden,effectiveClosed:this.effectiveClosed}}renderSectionsRail(){let{rows:e,hiddenSections:t,closedSections:s}=A(this.sectionRowsInput());if(!e.length){this.els.rail.innerHTML=`
586
609
  ${this.railHeader("Sections","event","Draw sections or zones in the designer to schedule availability per area. This chart has none yet.")}
587
610
  <div class="slm-empty">No sections on this chart.</div>`;return}let i=[];t&&i.push(`${t} hidden`),s&&i.push(`${s} closed`);let a=i.length?i.join(" \xB7 "):"All sections open and on sale",o=t>0||s>0;this.els.rail.innerHTML=`
588
611
  ${this.railHeader("Sections","event","Decide when each zone or section goes on sale for this event. Keep it hidden, reveal it at a set time, or <b>auto-reveal once the rest sells past a threshold</b>. Hidden seats vanish for buyers; closed seats stay on the map (flat grey) but can't be bought.")}
589
- <div class="slm-availlist" data-ref="availlist">${e.map(l=>Q(l,this.availabilitySaving)).join("")}</div>
612
+ <div class="slm-availlist" data-ref="availlist">${e.map(l=>te(l,this.availabilitySaving)).join("")}</div>
590
613
  <div class="slm-availsummary">
591
614
  <span class="slm-availdot${o?" warn":""}"></span>
592
615
  <span>${p(a)}</span>
@@ -594,7 +617,7 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
594
617
  <div class="slm-availcallout">
595
618
  <span class="slm-availstar" aria-hidden="true">\u2726</span>
596
619
  <p><b>Auto-reveal at % sold</b> is demand-triggered release: the balcony opens itself the moment the stalls cross the threshold \u2014 no one has to be watching.</p>
597
- </div>`,this.wireSectionRail(),this.applySectionCanvasTreatment()}wireSectionRail(){let e=this.els.rail;e&&(e.querySelectorAll("[data-avail-id]").forEach(t=>{t.addEventListener("click",()=>this.setSectionMode(t.dataset.availId,t.dataset.availValue))}),e.querySelectorAll("[data-avail-picker]").forEach(t=>{t.querySelector("summary").addEventListener("click",s=>{this.availabilitySaving&&s.preventDefault(),e.querySelectorAll("[data-avail-picker]").forEach(i=>{i!==t&&(i.open=!1)})}),t.addEventListener("focusout",s=>{t.contains(s.relatedTarget)||(t.open=!1)}),t.addEventListener("keydown",s=>{if(s.key==="Escape"&&(t.open=!1,t.querySelector("summary").focus(),s.preventDefault()),s.key==="ArrowDown"||s.key==="ArrowUp"){if(this.availabilitySaving)return;s.preventDefault(),t.open=!0;let i=[...t.querySelectorAll("button")],a=i.indexOf(document.activeElement);i[(a+(s.key==="ArrowDown"?1:i.length-1)+i.length)%i.length]?.focus()}})}),e.querySelectorAll("[data-avail-reveal]").forEach(t=>{t.addEventListener("change",()=>{let s=new Date(t.value).getTime();Number.isFinite(s)&&this.setSectionRulePatch(t.dataset.availReveal,{revealAt:s})})}),e.querySelectorAll("[data-avail-pct]").forEach(t=>{t.addEventListener("change",()=>{let s=Math.max(1,Math.min(100,Number(t.value)||0));this.setSectionRulePatch(t.dataset.availPct,{thresholdPct:s})})}))}setSectionMode(e,t){let s=E(this.sectionRowsInput()).rows.find(l=>l.id===e),i=s?.seatLabels??this.availabilityRules[e]?.labels??[],a={...this.availabilityRules},o=U(t,i,this.availabilityRules[e]);if(o?a[e]=o:delete a[e],s?.kind==="zone"&&this.sectionsBase)for(let l of this.sectionsBase.sections)l.zone===e&&delete a[l.id];this.persistAvailability(a)}setSectionRulePatch(e,t){let s=this.availabilityRules[e];if(!s)return;let a=E(this.sectionRowsInput()).rows.find(o=>o.id===e)?.seatLabels??s.labels??[];this.persistAvailability({...this.availabilityRules,[e]:{...s,...t,labels:a}})}async persistAvailability(e){let t=this.availabilityRules;this.availabilityRules=e,this.availabilitySaving=!0,this.mode==="sections"&&this.renderSectionsRail();try{let s=await this.withAuthRetry(()=>this.api.setAvailability(this.key,e));this.availabilityRules=s.rules,this.effectiveHidden=new Set(s.hidden),this.effectiveClosed=new Set(I(s.rules)),this.availabilitySaving=!1,this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment()}catch(s){this.availabilityRules=t,this.availabilitySaving=!1,this.mode==="sections"&&this.renderSectionsRail(),this.toastErr("Couldn't update availability. Try again."),this.opts.onError?.(s)}}paintLegend(e){this.els.legend&&(this.els.legend.innerHTML=G.map(t=>`<div class="slm-legrow"><span class="slm-legdot" style="background:${t.color}"></span>
620
+ </div>`,this.wireSectionRail(),this.applySectionCanvasTreatment()}wireSectionRail(){let e=this.els.rail;e&&(e.querySelectorAll("[data-avail-id]").forEach(t=>{t.addEventListener("click",()=>this.setSectionMode(t.dataset.availId,t.dataset.availValue))}),e.querySelectorAll("[data-avail-picker]").forEach(t=>{t.querySelector("summary").addEventListener("click",s=>{this.availabilitySaving&&s.preventDefault(),e.querySelectorAll("[data-avail-picker]").forEach(i=>{i!==t&&(i.open=!1)})}),t.addEventListener("focusout",s=>{t.contains(s.relatedTarget)||(t.open=!1)}),t.addEventListener("keydown",s=>{if(s.key==="Escape"&&(t.open=!1,t.querySelector("summary").focus(),s.preventDefault()),s.key==="ArrowDown"||s.key==="ArrowUp"){if(this.availabilitySaving)return;s.preventDefault(),t.open=!0;let i=[...t.querySelectorAll("button")],a=i.indexOf(document.activeElement);i[(a+(s.key==="ArrowDown"?1:i.length-1)+i.length)%i.length]?.focus()}})}),e.querySelectorAll("[data-avail-reveal]").forEach(t=>{t.addEventListener("change",()=>{let s=new Date(t.value).getTime();Number.isFinite(s)&&this.setSectionRulePatch(t.dataset.availReveal,{revealAt:s})})}),e.querySelectorAll("[data-avail-pct]").forEach(t=>{t.addEventListener("change",()=>{let s=Math.max(1,Math.min(100,Number(t.value)||0));this.setSectionRulePatch(t.dataset.availPct,{thresholdPct:s})})}))}setSectionMode(e,t){let s=A(this.sectionRowsInput()).rows.find(l=>l.id===e),i=s?.seatLabels??this.availabilityRules[e]?.labels??[],a={...this.availabilityRules},o=G(t,i,this.availabilityRules[e]);if(o?a[e]=o:delete a[e],s?.kind==="zone"&&this.sectionsBase)for(let l of this.sectionsBase.sections)l.zone===e&&delete a[l.id];this.persistAvailability(a)}setSectionRulePatch(e,t){let s=this.availabilityRules[e];if(!s)return;let a=A(this.sectionRowsInput()).rows.find(o=>o.id===e)?.seatLabels??s.labels??[];this.persistAvailability({...this.availabilityRules,[e]:{...s,...t,labels:a}})}async persistAvailability(e){let t=this.availabilityRules;this.availabilityRules=e,this.availabilitySaving=!0,this.mode==="sections"&&this.renderSectionsRail();try{let s=await this.withAuthRetry(()=>this.api.setAvailability(this.key,e));this.availabilityRules=s.rules,this.effectiveHidden=new Set(s.hidden),this.effectiveClosed=new Set(O(s.rules)),this.availabilitySaving=!1,this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment()}catch(s){this.availabilityRules=t,this.availabilitySaving=!1,this.mode==="sections"&&this.renderSectionsRail(),this.toastErr("Couldn't update availability. Try again."),this.opts.onError?.(s)}}paintLegend(e){this.els.legend&&(this.els.legend.innerHTML=X.map(t=>`<div class="slm-legrow"><span class="slm-legdot" style="background:${t.color}"></span>
598
621
  <span class="slm-leglabel">${t.label}</span><span class="slm-legcount">${e[t.key].toLocaleString()}</span></div>`).join(""))}paintFeed(){this.activityPanel?.update(this.feed)}renderBlockRail(){let t=(this.doc?.categories??[]).map(n=>`<button class="slm-chip" type="button" data-cat="${p(n.key)}" aria-pressed="false">
599
622
  <span class="dot" style="background:${p(n.color??"#6e7bff")}"></span>
600
623
  <span>${p(n.label??n.key)}</span>
@@ -604,7 +627,7 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
604
627
  <select class="slm-select" data-ref="section"><option value="">Choose a section\u2026</option>
605
628
  ${this.sectionOptions.map(n=>`<option value="${p(n.id)}">${p(n.label)}</option>`).join("")}</select></div>`:"",i=this.sectionOptions.map(n=>`<option value="${p(n.id)}">${p(n.label)}</option>`).join("");this.els.rail.innerHTML=`
606
629
  <div class="slm-monitor-tabs" role="tablist" aria-label="Blocking tools"><button role="tab" data-block-tab="edit" aria-selected="${!this.blockBrowse}">Block seats</button><button role="tab" data-block-tab="browse" aria-selected="${this.blockBrowse}">Find blocked</button></div>
607
- <p class="slm-note">\u25A7 Blocked \xB7 \u25CF Green: booked \xB7 \u25CF Gold: held</p>
630
+ <p class="slm-note">${Y}</p>
608
631
  <div class="slm-selbar" aria-live="polite"><span class="slm-selnum" data-ref="selnum">0</span><span class="slm-sellabel" data-ref="selmeta">selected</span></div>
609
632
  <div class="slm-row">
610
633
  <button class="slm-btn" data-ref="doblock" disabled>Block</button>
@@ -647,5 +670,5 @@ import{c as A,d as $,f as O}from"./chunk-RZ2VKZ44.js";import{A as Me,B as Ce,D a
647
670
  <button class="slm-btn ghost" data-ref="markall" style="width:100%" disabled>Put all blocked seats on sale</button>
648
671
  <p class="slm-note slm-allnote" data-ref="markallnote">For a full reset only. You will be asked to confirm.</p>
649
672
  </div></details>
650
- `,this.els.rail.querySelectorAll("[data-block-tab]").forEach(n=>n.addEventListener("click",()=>{this.blockBrowse=n.dataset.blockTab==="browse",this.renderBlockRail()}));let a=n=>this.els.rail.querySelector(`[data-ref="${n}"]`);this.els.selnum=a("selnum"),this.els.doblock=a("doblock"),this.els.dounblock=a("dounblock"),this.els.selmeta=a("selmeta"),this.els.blockedcount=a("blockedcount"),this.els.blockedshowing=a("blockedshowing"),this.els.blockedlist=a("blockedlist"),this.els.selblocked=a("selblocked"),this.els.markall=a("markall"),this.els.markallnote=a("markallnote"),a("doblock").addEventListener("click",()=>{this.block()}),a("dounblock").addEventListener("click",()=>{this.unblock()}),a("selall").addEventListener("click",()=>this.selectAll()),a("clearsel").addEventListener("click",()=>this.clearSelection()),a("markall").addEventListener("click",()=>this.confirmUnblockAll()),this.els.rail.querySelectorAll("[data-cat]").forEach(n=>n.addEventListener("click",()=>this.toggleCategory(n.dataset.cat)));let o=this.els.rail.querySelector('[data-ref="section"]');o?.addEventListener("change",()=>{o.value&&(this.selectSection(o.value),o.value="")});let l=a("blockedsearch"),r=a("blockedsection");l.value=this.blockedQuery,r.value=this.blockedSection,l.addEventListener("input",()=>{this.blockedQuery=l.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),r.addEventListener("change",()=>{this.blockedSection=r.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),a("selblocked").addEventListener("click",()=>{this.toggleLabels(this.filteredBlockedSeats().map(n=>n.label))}),a("blockedlist").addEventListener("click",n=>{let d=n.target,m=d.closest("[data-block-seat-find]");if(m?.dataset.blockSeatFind){let u=this.labelToSeat.get(m.dataset.blockSeatFind);u&&(this.setFollowLive(!1),this.focusActivitySeats([u.label],this.sectionByObject.get(u.rowId)??y));return}let b=d.closest("[data-block-locate]"),g=d.closest("[data-block-group]");if(b||g){let u=b?.dataset.blockLocate??g?.dataset.blockGroup,f=this.filteredBlockedSeats().filter(x=>x.rowId===u);b&&f.length&&(this.setFollowLive(!1),this.focusActivitySeats(f.map(x=>x.label),this.sectionByObject.get(f[0].rowId)??y)),g&&this.toggleLabels(f.map(x=>x.label));return}let v=d.closest("[data-blocked-label]");v?.dataset.blockedLabel?this.toggleLabels([v.dataset.blockedLabel]):d.closest("[data-blocked-more]")&&(this.blockedResultLimit+=100,this.paintBlockedInventory())});let c=a("release");c.addEventListener("change",()=>{let n=c.value?new Date(c.value).getTime():NaN;this.releaseAt=Number.isFinite(n)&&n>Date.now()?n:null;let d=a("releasenote");d.textContent=this.releaseAt?`New blocks auto-release ${new Date(this.releaseAt).toLocaleString()}.`:c.value?"Pick a time in the future.":"Leave empty to block permanently."}),this.paintSelBar(this.getSelection())}toggleCategory(e){let t=[];for(let[s,i]of this.labelToSeat.entries())i.categoryKey===e&&this.isBlockSelectable(s)&&t.push(s);this.toggleLabels(t)}toggleLabels(e){if(!this.renderer)return;let t=e.filter(a=>this.labelToSeat.has(a)&&this.isBlockSelectable(a));if(!t.length)return;let s=new Set(this.selectionLabels());if(t.every(a=>s.has(a))){let a=t.map(o=>this.labelToId.get(o)).filter(o=>!!o);this.renderer.deselect(a)}else this.renderer.selectByLabels(t);this.syncSelection()}isBlockSelectable(e){let t=this.status.get(e)??"free";return t==="free"||t==="blocked"}paintSelBar(e){if(!this.els.selnum)return;this.els.selnum.textContent=e.length.toLocaleString();let t=e.filter(o=>(this.status.get(o.label)??"free")==="free").length,s=e.filter(o=>this.status.get(o.label)==="blocked").length;this.els.selmeta.textContent=e.length?`${t.toLocaleString()} available \xB7 ${s.toLocaleString()} blocked`:"selected";let i=this.els.doblock,a=this.els.dounblock;i.disabled=t===0,a.disabled=s===0,i.textContent=t?`Block ${t.toLocaleString()}`:"Block selected",a.textContent=s?`Put ${s.toLocaleString()} on sale`:"Put back on sale",this.paintCategoryControls(e),this.paintBlockedInventory()}paintCategoryControls(e){let t=new Set(e.map(s=>s.label));this.els.rail?.querySelectorAll("[data-cat]").forEach(s=>{let i=s.dataset.cat,a=[];for(let[n,d]of this.labelToSeat.entries())d.categoryKey===i&&this.isBlockSelectable(n)&&a.push(n);let o=a.filter(n=>t.has(n)).length,l=a.length>0&&o===a.length,r=o>0&&!l;s.disabled=a.length===0,s.classList.toggle("on",l),s.classList.toggle("partial",r),s.setAttribute("aria-pressed",l?"true":r?"mixed":"false"),s.setAttribute("title",l?`Remove all ${a.length.toLocaleString()} seats in this category from the selection`:r?`Select the remaining ${(a.length-o).toLocaleString()} seats in this category`:`Select all ${a.length.toLocaleString()} seats in this category`);let c=s.querySelector("[data-cat-count]");c&&(c.textContent=o?`${o.toLocaleString()}/${a.length.toLocaleString()}`:a.length.toLocaleString())})}filteredBlockedSeats(){let e=this.blockedQuery.trim().toLocaleLowerCase(),t=[];for(let[s,i]of this.labelToSeat.entries()){if(this.status.get(s)!=="blocked")continue;let a=this.sectionByObject.get(i.rowId)??y;if(!(this.blockedSection&&a!==this.blockedSection)){if(e){let o=this.doc?.categories.find(d=>d.key===i.categoryKey)?.label??i.categoryKey,l=this.sectionLabelById.get(a)??"Other seats",r=this.doc?.objects.find(d=>d.id===i.rowId),c=r?.type==="row"||r?.type==="table"?r.label:"";if(!`${s} ${o} ${l} ${c}`.toLocaleLowerCase().includes(e))continue}t.push(i)}}return t.sort((s,i)=>s.label.localeCompare(i.label,void 0,{numeric:!0,sensitivity:"base"}))}paintBlockedInventory(){if(!this.els.blockedlist)return;let e=[...this.status.entries()].filter(([,d])=>d==="blocked").length,t=this.filteredBlockedSeats(),s=t.slice(0,this.blockedResultLimit),i=new Set(this.selectionLabels()),a=t.filter(d=>i.has(d.label)).length,o=t.length>0&&a===t.length;this.els.blockedcount.textContent=e.toLocaleString(),this.els.blockedshowing.textContent=t.length?`Showing ${s.length.toLocaleString()} of ${t.length.toLocaleString()}`:e?"No matches":"No blocked seats";let l=this.els.selblocked;l.disabled=t.length===0,l.textContent=o?`Remove ${t.length.toLocaleString()} results`:`Select ${t.length.toLocaleString()} results`;let r=new Map;for(let d of t){let m=r.get(d.rowId)??[];m.push(d),r.set(d.rowId,m)}this.els.blockedshowing.textContent=`${t.length.toLocaleString()} seats \xB7 ${r.size} rows`,this.els.blockedlist.innerHTML=[...r.entries()].slice(0,this.blockedResultLimit).map(([d,m])=>{let b=this.sectionByObject.get(d)??y,g=this.sectionLabelById.get(b)??"Other seats",v=this.doc?.objects.find(f=>f.id===d),u=v&&"label"in v?v.label:m[0].label;return`<div class="slm-block-group"><div class="slm-block-grouphead"><button type="button" data-block-locate="${p(d)}" title="Show this row and nearby seats on the map"><b>${p(u)}</b><small>${p(g)} \xB7 ${m.length} blocked</small></button><button type="button" data-block-group="${p(d)}">Select row</button></div>
651
- <details><summary>Choose seats</summary>${m.map(f=>`<div class="slm-block-seatline"><button type="button" class="slm-blockeditem${i.has(f.label)?" on":""}" data-blocked-label="${p(f.label)}" aria-pressed="${i.has(f.label)}"><span class="slm-blockedcheck" aria-hidden="true">\u2713</span><span>${p(f.label)}</span></button><button type="button" data-block-seat-find="${p(f.label)}" aria-label="Show ${p(f.label)} and nearby seats">Show</button></div>`).join("")}</details></div>`}).join("")||'<div class="slm-blockedempty">No blocked seats match.</div>',r.size>this.blockedResultLimit&&(this.els.blockedlist.innerHTML+="<button data-blocked-more>Show more rows</button>");let c=this.els.markall,n=c.dataset.confirm==="true";c.disabled=e===0,c.textContent=n?`Confirm: put all ${e.toLocaleString()} on sale`:`Put all ${e.toLocaleString()} blocked seats on sale`}confirmUnblockAll(){let e=this.els.markall;if(!(!e||e.disabled)){if(e.dataset.confirm==="true"){this.resetUnblockAllConfirm(),this.unblockAll();return}e.dataset.confirm="true",e.classList.add("danger"),this.els.markallnote.textContent="This changes every blocked seat. Click the red button again to confirm.",this.paintBlockedInventory(),this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.unblockAllConfirmTimer=setTimeout(()=>this.resetUnblockAllConfirm(),6e3)}}resetUnblockAllConfirm(){this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.unblockAllConfirmTimer=null;let e=this.els.markall;e&&(delete e.dataset.confirm,e.classList.remove("danger"),this.els.markallnote&&(this.els.markallnote.textContent="For a full reset only. You will be asked to confirm."),this.paintBlockedInventory())}done(e,t,s){if(this.toastOk(s),t.length){let i=e==="block"?this.pushActivity(t,"blocked","blocked"):e==="unblock"||e==="unblockAll"?this.pushActivity(t,"unblocked","free"):e==="cancelBooking"?this.pushActivity(t,"cancelled","free"):null;i&&this.paintSpatialActivity(i)}e!=="setHoldTtl"&&this.refreshControlRoom().catch(i=>this.opts.onError?.(i)),this.opts.onActionComplete?.({action:e,labels:t,count:t.length})}toastOk(e){this.toast(e,"ok")}toastErr(e){this.toast(e,"err")}toast(e,t){let s=this.els.toast;s&&(s.textContent=e,s.className=`slm-toast on ${t}`,this.toastTimer&&clearTimeout(this.toastTimer),this.toastTimer=setTimeout(()=>{s.className="slm-toast"},3200))}fail(e){this.opts.onError?.(e),this.els.rail&&(this.els.rail.innerHTML=`<div class="slm-empty">Couldn't load this event. Check the event key and token.</div>`)}};export{xe as ACCESS_LINK_DEFAULTS,Ee as ChannelsMode,H as ManageApi,k as ManageApiError,ie as PUBLIC_CHANNEL_ID,ae as PUBLIC_CHANNEL_NAME,z as SeatManager,ve as accessIntentDescription,ge as accessIntentLabel,be as accessLine,ke as accessLinkBadge,Le as accessLinkErrorCopy,Se as accessLinkIsLive,we as accessLinkPolicyLines,me as bucketRows,Ce as bucketRowsHtml,Te as dropReviewRows,fe as intentForbidsCopy,ye as intentSwitchBlockedCopy,oe as isPublicChannelId,le as markerLetter,re as markerOf,he as mutationCount,pe as needsMoveConfirmation,de as planAssignment,ue as retryAfterCopy,ce as selectionSources,Me as stateBadge,ne as suggestMarker};
673
+ `,this.els.rail.querySelectorAll("[data-block-tab]").forEach(n=>n.addEventListener("click",()=>{this.blockBrowse=n.dataset.blockTab==="browse",this.renderBlockRail()}));let a=n=>this.els.rail.querySelector(`[data-ref="${n}"]`);this.els.selnum=a("selnum"),this.els.doblock=a("doblock"),this.els.dounblock=a("dounblock"),this.els.selmeta=a("selmeta"),this.els.blockedcount=a("blockedcount"),this.els.blockedshowing=a("blockedshowing"),this.els.blockedlist=a("blockedlist"),this.els.selblocked=a("selblocked"),this.els.markall=a("markall"),this.els.markallnote=a("markallnote"),a("doblock").addEventListener("click",()=>{this.block()}),a("dounblock").addEventListener("click",()=>{this.unblock()}),a("selall").addEventListener("click",()=>this.selectAll()),a("clearsel").addEventListener("click",()=>this.clearSelection()),a("markall").addEventListener("click",()=>this.confirmUnblockAll()),this.els.rail.querySelectorAll("[data-cat]").forEach(n=>n.addEventListener("click",()=>this.toggleCategory(n.dataset.cat)));let o=this.els.rail.querySelector('[data-ref="section"]');o?.addEventListener("change",()=>{o.value&&(this.selectSection(o.value),o.value="")});let l=a("blockedsearch"),r=a("blockedsection");l.value=this.blockedQuery,r.value=this.blockedSection,l.addEventListener("input",()=>{this.blockedQuery=l.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),r.addEventListener("change",()=>{this.blockedSection=r.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),a("selblocked").addEventListener("click",()=>{this.toggleLabels(this.filteredBlockedSeats().map(n=>n.label))}),a("blockedlist").addEventListener("click",n=>{let d=n.target,m=d.closest("[data-block-seat-find]");if(m?.dataset.blockSeatFind){let u=this.labelToSeat.get(m.dataset.blockSeatFind);u&&(this.setFollowLive(!1),this.focusActivitySeats([u.label],this.sectionByObject.get(u.rowId)??x));return}let b=d.closest("[data-block-locate]"),g=d.closest("[data-block-group]");if(b||g){let u=b?.dataset.blockLocate??g?.dataset.blockGroup,f=this.filteredBlockedSeats().filter(k=>k.rowId===u);b&&f.length&&(this.setFollowLive(!1),this.focusActivitySeats(f.map(k=>k.label),this.sectionByObject.get(f[0].rowId)??x)),g&&this.toggleLabels(f.map(k=>k.label));return}let v=d.closest("[data-blocked-label]");v?.dataset.blockedLabel?this.toggleLabels([v.dataset.blockedLabel]):d.closest("[data-blocked-more]")&&(this.blockedResultLimit+=100,this.paintBlockedInventory())});let c=a("release");c.addEventListener("change",()=>{let n=c.value?new Date(c.value).getTime():NaN;this.releaseAt=Number.isFinite(n)&&n>Date.now()?n:null;let d=a("releasenote");d.textContent=this.releaseAt?`New blocks auto-release ${new Date(this.releaseAt).toLocaleString()}.`:c.value?"Pick a time in the future.":"Leave empty to block permanently."}),this.paintSelBar(this.getSelection())}toggleCategory(e){let t=[];for(let[s,i]of this.labelToSeat.entries())i.categoryKey===e&&this.isBlockSelectable(s)&&t.push(s);this.toggleLabels(t)}toggleLabels(e){if(!this.renderer)return;let t=e.filter(a=>this.labelToSeat.has(a)&&this.isBlockSelectable(a));if(!t.length)return;let s=new Set(this.selectionLabels());if(t.every(a=>s.has(a))){let a=t.map(o=>this.labelToId.get(o)).filter(o=>!!o);this.renderer.deselect(a)}else this.renderer.selectByLabels(t);this.syncSelection()}isBlockSelectable(e){let t=this.status.get(e)??"free";return t==="free"||t==="blocked"}paintSelBar(e){if(!this.els.selnum)return;this.els.selnum.textContent=e.length.toLocaleString();let t=e.filter(o=>(this.status.get(o.label)??"free")==="free").length,s=e.filter(o=>this.status.get(o.label)==="blocked").length;this.els.selmeta.textContent=e.length?`${t.toLocaleString()} available \xB7 ${s.toLocaleString()} blocked`:"selected";let i=this.els.doblock,a=this.els.dounblock;i.disabled=t===0,a.disabled=s===0,i.textContent=t?`Block ${t.toLocaleString()}`:"Block selected",a.textContent=s?`Put ${s.toLocaleString()} on sale`:"Put back on sale",this.paintCategoryControls(e),this.paintBlockedInventory()}paintCategoryControls(e){let t=new Set(e.map(s=>s.label));this.els.rail?.querySelectorAll("[data-cat]").forEach(s=>{let i=s.dataset.cat,a=[];for(let[n,d]of this.labelToSeat.entries())d.categoryKey===i&&this.isBlockSelectable(n)&&a.push(n);let o=a.filter(n=>t.has(n)).length,l=a.length>0&&o===a.length,r=o>0&&!l;s.disabled=a.length===0,s.classList.toggle("on",l),s.classList.toggle("partial",r),s.setAttribute("aria-pressed",l?"true":r?"mixed":"false"),s.setAttribute("title",l?`Remove all ${a.length.toLocaleString()} seats in this category from the selection`:r?`Select the remaining ${(a.length-o).toLocaleString()} seats in this category`:`Select all ${a.length.toLocaleString()} seats in this category`);let c=s.querySelector("[data-cat-count]");c&&(c.textContent=o?`${o.toLocaleString()}/${a.length.toLocaleString()}`:a.length.toLocaleString())})}filteredBlockedSeats(){let e=this.blockedQuery.trim().toLocaleLowerCase(),t=[];for(let[s,i]of this.labelToSeat.entries()){if(this.status.get(s)!=="blocked")continue;let a=this.sectionByObject.get(i.rowId)??x;if(!(this.blockedSection&&a!==this.blockedSection)){if(e){let o=this.doc?.categories.find(d=>d.key===i.categoryKey)?.label??i.categoryKey,l=this.sectionLabelById.get(a)??"Other seats",r=this.doc?.objects.find(d=>d.id===i.rowId),c=r?.type==="row"||r?.type==="table"?r.label:"";if(!`${s} ${o} ${l} ${c}`.toLocaleLowerCase().includes(e))continue}t.push(i)}}return t.sort((s,i)=>s.label.localeCompare(i.label,void 0,{numeric:!0,sensitivity:"base"}))}paintBlockedInventory(){if(!this.els.blockedlist)return;let e=[...this.status.entries()].filter(([,d])=>d==="blocked").length,t=this.filteredBlockedSeats(),s=t.slice(0,this.blockedResultLimit),i=new Set(this.selectionLabels()),a=t.filter(d=>i.has(d.label)).length,o=t.length>0&&a===t.length;this.els.blockedcount.textContent=e.toLocaleString(),this.els.blockedshowing.textContent=t.length?`Showing ${s.length.toLocaleString()} of ${t.length.toLocaleString()}`:e?"No matches":"No blocked seats";let l=this.els.selblocked;l.disabled=t.length===0,l.textContent=o?`Remove ${t.length.toLocaleString()} results`:`Select ${t.length.toLocaleString()} results`;let r=new Map;for(let d of t){let m=r.get(d.rowId)??[];m.push(d),r.set(d.rowId,m)}this.els.blockedshowing.textContent=`${t.length.toLocaleString()} seats \xB7 ${r.size} rows`,this.els.blockedlist.innerHTML=[...r.entries()].slice(0,this.blockedResultLimit).map(([d,m])=>{let b=this.sectionByObject.get(d)??x,g=this.sectionLabelById.get(b)??"Other seats",v=this.doc?.objects.find(f=>f.id===d),u=v&&"label"in v?v.label:m[0].label;return`<div class="slm-block-group"><div class="slm-block-grouphead"><button type="button" data-block-locate="${p(d)}" title="Show this row and nearby seats on the map"><b>${p(u)}</b><small>${p(g)} \xB7 ${m.length} blocked</small></button><button type="button" data-block-group="${p(d)}">Select row</button></div>
674
+ <details><summary>Choose seats</summary>${m.map(f=>`<div class="slm-block-seatline"><button type="button" class="slm-blockeditem${i.has(f.label)?" on":""}" data-blocked-label="${p(f.label)}" aria-pressed="${i.has(f.label)}"><span class="slm-blockedcheck" aria-hidden="true">\u2713</span><span>${p(f.label)}</span></button><button type="button" data-block-seat-find="${p(f.label)}" aria-label="Show ${p(f.label)} and nearby seats">Show</button></div>`).join("")}</details></div>`}).join("")||'<div class="slm-blockedempty">No blocked seats match.</div>',r.size>this.blockedResultLimit&&(this.els.blockedlist.innerHTML+="<button data-blocked-more>Show more rows</button>");let c=this.els.markall,n=c.dataset.confirm==="true";c.disabled=e===0,c.textContent=n?`Confirm: put all ${e.toLocaleString()} on sale`:`Put all ${e.toLocaleString()} blocked seats on sale`}confirmUnblockAll(){let e=this.els.markall;if(!(!e||e.disabled)){if(e.dataset.confirm==="true"){this.resetUnblockAllConfirm(),this.unblockAll();return}e.dataset.confirm="true",e.classList.add("danger"),this.els.markallnote.textContent="This changes every blocked seat. Click the red button again to confirm.",this.paintBlockedInventory(),this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.unblockAllConfirmTimer=setTimeout(()=>this.resetUnblockAllConfirm(),6e3)}}resetUnblockAllConfirm(){this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.unblockAllConfirmTimer=null;let e=this.els.markall;e&&(delete e.dataset.confirm,e.classList.remove("danger"),this.els.markallnote&&(this.els.markallnote.textContent="For a full reset only. You will be asked to confirm."),this.paintBlockedInventory())}done(e,t,s){if(this.toastOk(s),t.length){let i=e==="block"?this.pushActivity(t,"blocked","blocked"):e==="unblock"||e==="unblockAll"?this.pushActivity(t,"unblocked","free"):e==="cancelBooking"?this.pushActivity(t,"cancelled","free"):null;i&&this.paintSpatialActivity(i)}e!=="setHoldTtl"&&this.refreshControlRoom().catch(i=>this.opts.onError?.(i)),this.opts.onActionComplete?.({action:e,labels:t,count:t.length})}toastOk(e){this.toast(e,"ok")}toastErr(e){this.toast(e,"err")}toast(e,t){let s=this.els.toast;s&&(s.textContent=e,s.className=`slm-toast on ${t}`,this.toastTimer&&clearTimeout(this.toastTimer),this.toastTimer=setTimeout(()=>{s.className="slm-toast"},3200))}fail(e){this.opts.onError?.(e),this.els.rail&&(this.els.rail.innerHTML=`<div class="slm-empty">Couldn't load this event. Check the event key and token.</div>`)}};export{we as ACCESS_LINK_DEFAULTS,$e as ChannelsMode,z as ManageApi,S as ManageApiError,le as PUBLIC_CHANNEL_ID,ne as PUBLIC_CHANNEL_NAME,F as SeatManager,xe as accessIntentDescription,ye as accessIntentLabel,fe as accessLine,Le as accessLinkBadge,Ce as accessLinkErrorCopy,Te as accessLinkIsLive,Me as accessLinkPolicyLines,ge as bucketRows,Ae as bucketRowsHtml,Ee as dropReviewRows,ke as intentForbidsCopy,Se as intentSwitchBlockedCopy,re as isPublicChannelId,ce as markerLetter,he as markerOf,ue as mutationCount,be as needsMoveConfirmation,me as planAssignment,ve as retryAfterCopy,pe as selectionSources,Re as stateBadge,de as suggestMarker};