@seatlayer/js 0.55.0 → 0.56.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.cjs CHANGED
@@ -1,16 +1,16 @@
1
- "use strict";var $e=Object.defineProperty;var ft=Object.getOwnPropertyDescriptor;var yt=Object.getOwnPropertyNames;var kt=Object.prototype.hasOwnProperty;var N=(o,e,t)=>()=>{if(t)throw t[0];try{return o&&(e=o(o=0)),e}catch(s){throw t=[s],s}};var qe=(o,e)=>{for(var t in e)$e(o,t,{get:e[t],enumerable:!0})},wt=(o,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of yt(e))!kt.call(o,n)&&n!==t&&$e(o,n,{get:()=>e[n],enumerable:!(s=ft(e,n))||s.enumerable});return o};var St=o=>wt($e({},"__esModule",{value:!0}),o);async function _e(o){let t=(o.headers.get("content-type")??"").includes("application/json")?await o.json().catch(()=>null):null;if(!o.ok){let s=t;throw new f(o.status,s?.error??`request_failed_${o.status}`,s?.code,s?.conflicts,s?.details,typeof s?.message=="string"?s.message:void 0)}return t}function $(o){return o&&typeof o=="object"?o:{}}function ie(o,e,t=0){return typeof o=="number"&&Number.isFinite(o)?o:typeof e=="number"&&Number.isFinite(e)?e:t}function je(o,e){return o===null?null:typeof o=="number"&&Number.isFinite(o)?o:o!==void 0?null:typeof e=="number"&&Number.isFinite(e)?e:null}function Ve(o){let e=$(o),t=ie(e.bookedValue,e.bookedRevenue);return{...e,bookedValue:t,bookedRevenue:t}}function xt(o){let e=$(o),t=$(e.report),s=Array.isArray(t.byCategory)?t.byCategory.map(i=>{let a=$(i),l=ie(a.bookedValue,a.bookedRevenue);return{...a,bookedValue:l,bookedRevenue:l}}):[],n=Array.isArray(t.bySection)?t.bySection.map(Ve):void 0;return{...e,report:{...t,byCategory:s,...n?{bySection:n}:{}}}}function Lt(o){let e=$(o),t=$(e.bookedValue),s=$(e.revenue),n=Object.keys(t).length?t:s,i=Array.isArray(t.bySection)?t.bySection:Array.isArray(s.bySection)?s.bySection:[],a={...n,gross:ie(t.gross,s.gross),bySection:i.map(Ve)},l=$(e.velocity),r=Array.isArray(l.bySection)?l.bySection.map(d=>{let c=$(d),p=ie(c.bookedValue,c.grossRevenue);return{...c,bookedValue:p,grossRevenue:p}}):[];return{...e,bookedValue:a,revenue:a,velocity:{...l,bySection:r}}}function Ct(o){let e=$(o),t=$(e.report),s=typeof t.includesBookedValue=="boolean"?t.includesBookedValue:t.includesRevenue===!0,n=Array.isArray(t.rows)?t.rows.map(l=>{let r=$(l),d=$(r.attribution),c=je(d.bookedValue,d.revenue);return{...r,attribution:{...d,bookedValue:c,revenue:c}}}):[],i=$(t.totals),a=je(i.bookedValue,i.revenue);return{...e,report:{...t,includesBookedValue:s,includesRevenue:s,rows:n,totals:{...i,bookedValue:a,revenue:a}}}}function Te(o){let e=$(o),t=typeof e.includesBookedValue=="boolean"?e.includesBookedValue:e.includesRevenue===!0;return{...e,includesBookedValue:t,includesRevenue:t}}var f,U,ae=N(()=>{"use strict";f=class extends Error{constructor(e,t,s,n,i,a){super(t),this.name="ManageApiError",this.status=e,this.code=s,this.conflicts=n,this.details=i,this.serverMessage=a}};U=class{constructor(e,t){this.base=e.replace(/\/+$/,""),this.token=t}setToken(e){this.token=e}auth(e,t={}){let s=t.method??"GET",n={Authorization:`Bearer ${this.token}`},i;return t.body!==void 0&&(n["Content-Type"]="application/json",i=JSON.stringify(t.body)),fetch(`${this.base}${e}`,{method:s,headers:n,body:i,credentials:"omit"}).then(a=>_e(a))}async authBlob(e){let t=await fetch(`${this.base}${e}`,{method:"GET",headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});return t.ok||await _e(t),t.blob()}chart(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/chart`)}asset(e,t){return/^[a-zA-Z0-9._-]+$/.test(t)?this.authBlob(`/v1/events/${encodeURIComponent(e)}/assets/${encodeURIComponent(t)}`):Promise.reject(new f(404,"not_found","not_found"))}objects(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/objects`)}subscribeTicket(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/subscribe-tickets`,{method:"POST"})}socketUrl(e){return`${this.base.replace(/^http/,"ws")}/pub/events/${encodeURIComponent(e)}/subscribe?surface=manager`}block(e,t,s={}){let n={labels:t};return typeof s.releaseAt=="number"&&(n.releaseAt=s.releaseAt),s.reason&&(n.reason=s.reason),this.auth(`/v1/events/${encodeURIComponent(e)}/block`,{method:"POST",body:n})}unblock(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/unblock`,{method:"POST",body:{labels:t}})}unblockAll(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/unblock-all`,{method:"POST"})}unbook(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/unbook`,{method:"POST",body:{labels:t,bookingRef:s}})}setHoldTtl(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/hold-ttl`,{method:"POST",body:{holdTtlMs:t}})}setCategory(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/category-assignments`,{method:"POST",body:{labels:t,categoryKey:s}})}setTableBooking(e,t,s,n={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/table-booking`,{method:"POST",body:{tableIds:t,mode:s,...n}})}bookings(e,t={}){let s=new URLSearchParams;t.q&&s.set("q",t.q),t.state&&s.set("state",t.state),t.cursor&&s.set("cursor",t.cursor),t.limit!=null&&s.set("limit",String(t.limit));let n=s.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/bookings${n?`?${n}`:""}`)}booking(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/bookings/${encodeURIComponent(t)}`)}listBookings(e,t={}){return this.bookings(e,t)}retrieveBooking(e,t){return this.booking(e,t)}availability(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/availability`)}setAvailability(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/availability`,{method:"POST",body:{rules:t}})}channels(e,t={}){let s=t.includeArchived?"?includeArchived=1":"";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels${s}`)}channelAllocation(e,t={}){let s=new URLSearchParams;t.afterLabel&&s.set("afterLabel",t.afterLabel),t.limit!=null&&s.set("limit",String(t.limit));let n=s.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/allocation${n?`?${n}`:""}`)}channelAudit(e,t={}){let s=new URLSearchParams;t.limit!=null&&s.set("limit",String(t.limit)),t.before!=null&&s.set("before",String(t.before));let n=s.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/audit${n?`?${n}`:""}`)}createChannel(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels`,{method:"POST",body:t})}renameChannel(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{name:s}})}setChannelPaused(e,t,s){let n=s?"pause":"unpause";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/${n}`,{method:"POST",body:{}})}archiveChannel(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/archive`,{method:"POST",body:{destination:s}})}applyChannelAssignment(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/assignments`,{method:"POST",body:{targetChannelId:t.targetChannelId||null,labels:t.labels,assignmentVersion:t.assignmentVersion}})}channelPreview(e,t,s={}){let n=new URLSearchParams;t.length&&n.set("channelIds",t.join(",")),s.includePublic!=null&&n.set("includePublic",s.includePublic?"1":"0");let i=n.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/preview${i?`?${i}`:""}`)}setChannelAccessIntent(e,t,s,n={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{accessIntent:s,...n.acknowledgeLiveAccess?{acknowledgeLiveAccess:!0}:{},...n.reason?{reason:n.reason}:{}}})}createAccessLink(e,t,s={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links`,{method:"POST",body:s})}accessLinks(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links`)}rotateAccessLink(e,t,s,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links/${encodeURIComponent(s)}/rotate`,{method:"POST",body:{endActiveSessions:n}})}revokeAccessLink(e,t,s,n=!1){let i=n?"?endActiveSessions=1":"";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links/${encodeURIComponent(s)}${i}`,{method:"DELETE"})}report(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/report`).then(xt)}controlRoom(e,t=15){return this.auth(`/v1/events/${encodeURIComponent(e)}/control-room?window=${t}`).then(Lt)}channelReport(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/report`).then(Ct)}createChannelReportLink(e,t,s={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`,{method:"POST",body:s}).then(n=>{let i=$(n);return{...i,link:Te(i.link)}})}channelReportLinks(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`).then(s=>{let n=$(s);return{links:Array.isArray(n.links)?n.links.map(Te):[]}})}revokeChannelReportLink(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links/${encodeURIComponent(s)}`,{method:"DELETE"}).then(n=>{let i=$(n);return{...i,link:Te(i.link)}})}log(e,t={}){let s=new URLSearchParams;t.limit!=null&&s.set("limit",String(t.limit)),t.before!=null&&s.set("before",String(t.before));let n=s.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/log${n?`?${n}`:""}`)}async reportCsv(e){let t=await fetch(`${this.base}/v1/events/${encodeURIComponent(e)}/report.csv`,{headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});if(!t.ok)throw new f(t.status,`request_failed_${t.status}`);return t.blob()}}});function B(o){return o==null||o===""||o===C}function O(o,e){let t=(o??"").trim();return((/\p{L}/u.exec(t)?.[0]??t[0]??"")||e).toUpperCase().slice(0,1)}function J(o,e){let t=new Set([...e].map(i=>O(i,"")).filter(Boolean)),s=O(o,"");return{letter:st.includes(s)&&!t.has(s)?s:[...st].find(i=>!t.has(i))??(s||"X"),color:he[t.size%he.length]}}function pe(o,e=0){return B(o.id)?{letter:O(o.marker,"P"),color:o.color||Et}:{letter:O(o.marker||o.name,"?"),color:o.color||he[e%he.length]}}function ue(o,e,t){let s=new Map;for(let a of o){let l=Pe(e.get(a));s.set(l,(s.get(l)??0)+1)}let n=[{id:C,name:t?.publicSale?.name??T},...(t?.channels??[]).map(a=>({id:a.id,name:a.name}))],i=[];for(let a of n){let l=s.get(a.id);l&&i.push({channelId:a.id,name:a.name,count:l}),s.delete(a.id)}for(let[a,l]of s)i.push({channelId:a,name:B(a)?T:"Another channel",count:l});return i}function Pe(o){return B(o)?C:o}function Be(o){return{count:o.length,labels:o.slice(0,nt),truncated:o.length>nt}}function me(o){let{labels:e,allocation:t,statusOf:s,nameOf:n}=o,i=Pe(o.targetChannelId),a=new Set,l=0,r=0,d=new Map,c=[],p=[],g=[];for(let b of e){if(a.has(b))continue;a.add(b);let m=s(b);if(!m){g.push(b);continue}let v=Pe(t.get(b));if(v===i){r+=1;continue}if(m==="held"){c.push(b);continue}if(m==="booked"){p.push(b);continue}v===C?l+=1:d.set(v,(d.get(v)??0)+1)}let w=[...d.entries()].map(([b,m])=>({channelId:b,name:n(b),count:m}));return{changedFromPublic:{count:l},movedFromOtherChannel:{count:w.reduce((b,m)=>b+m.count,0),channels:w},alreadyInTarget:{count:r},skippedHeld:Be(c),skippedBooked:Be(p),notFound:Be(g)}}function K(o){return o.changedFromPublic.count+o.movedFromOtherChannel.count}function be(o){return o.movedFromOtherChannel.count>0}function ge(o,e){let t=[];o.changedFromPublic.count&&t.push({kind:"add",icon:"+",count:o.changedFromPublic.count,text:`${o.changedFromPublic.count.toLocaleString()} from ${T}`});for(let s of o.movedFromOtherChannel.channels)t.push({kind:"move",icon:"\u21C4",count:s.count,text:`${s.count.toLocaleString()} moved out of ${s.name??"another channel"}`,why:"needs this confirmation"});return o.alreadyInTarget.count&&t.push({kind:"same",icon:"=",count:o.alreadyInTarget.count,text:`${o.alreadyInTarget.count.toLocaleString()} already in ${e}`,why:"unchanged"}),o.skippedHeld.count&&t.push({kind:"skip",icon:"\u23F8",count:o.skippedHeld.count,text:`${o.skippedHeld.count.toLocaleString()} in a buyer's checkout`,why:"can't move while held",peek:de(o.skippedHeld)}),o.skippedBooked.count&&t.push({kind:"skip",icon:"\u{1F512}",count:o.skippedBooked.count,text:`${o.skippedBooked.count.toLocaleString()} already sold`,why:"sales are never rewritten",peek:de(o.skippedBooked)}),o.notFound.count&&t.push({kind:"skip",icon:"?",count:o.notFound.count,text:`${o.notFound.count.toLocaleString()} not on this map`,why:"these seats are no longer part of the event",peek:de(o.notFound)}),t}function de(o){if(!o.labels.length)return;let e=o.labels.slice(0,4).join(", ");return o.truncated||o.labels.length>4?`${e}\u2026`:e}function ve(o){let e=o?.retryAfterMs??(o?.latestHoldExpiresAt?Math.max(0,o.latestHoldExpiresAt-Date.now()):0);if(!e)return"in a moment";let t=Math.ceil(e/6e4);return t<=1?"in about a minute":`in about ${t} minutes`}function fe(o){if(!o||!o.intent)return"\u2014";let e=o.intent==="server"?"Website integration":o.intent==="hosted_link"?"Buyer link":o.intent==="internal"?"Your staff sell these":"Protected reserve",t=o.hasActiveGrants?"in use now":o.lastMintAt?`last used ${new Date(o.lastMintAt).toLocaleDateString()}`:null,s=o.detail??t;return s?`${e} \xB7 ${s}`:e}function z(o){return o==="internal"?"Sell through your own staff":o==="server"?"Integrate a website or app":o==="hosted_link"?"Sell with a buyer link":"Keep as protected reserve"}function ye(o){switch(o){case"internal":return"Only your own box office can sell these seats, through your secret key. Buyer links and website integrations are refused.";case"server":return"Your website's backend mints each buyer a short-lived session for these seats. Buyer links are refused; the code lives on the Embed page.";case"hosted_link":return"SeatLayer makes a link you send to a named group. They open it and buy only these seats. No other route can sell them.";default:return"Nobody can buy these seats. Every way of letting a buyer in \u2014 a buyer link, your website, even your own staff \u2014 is refused while this is the route. The seats stay out of public sale."}}function Mt(o){return o==="hosted_link"?"hosted_link":o==="server"?"server":o==="staff"?"internal":null}function Y(o){let e=He(o?.accessIntent),t=Mt(o?.route),s=`This channel is set to "${z(e)}"`;return t?`${s}, so it cannot do that. Switch it to "${z(t)}" first.`:`${s}, so it cannot do that. Choose a different route for this channel first.`}function He(o){return o==="internal"||o==="server"||o==="hosted_link"||o==="none"?o:"none"}function ce(o,e,t){return`${o.toLocaleString()} ${o===1?e:t}`}function ke(o){let e=Math.max(0,o?.liveAccessLinks??0),t=Math.max(0,o?.activeSessions??0),s=He(o?.from),n=He(o?.to),a=`${[e?ce(e,"buyer link is live","buyer links are live"):null,t?ce(t,"buyer is in a checkout","buyers are in a checkout"):null].filter(Boolean).join(", and ")||"Buyers are inside this channel"} on "${z(s)}". Moving it to "${z(n)}" changes what happens to them.`,l=[];return e&&l.push(`${ce(e,"buyer link closes","buyer links close")} immediately. Anyone who has not opened it yet never will \u2014 send a new link if you still need one.`),t&&l.push(`${ce(t,"buyer who is already in a checkout keeps","buyers who are already in a checkout keep")} their seats and can finish paying. Nobody is thrown out. No new buyers come in this way, so the old route empties on its own within 12 hours.`),{headline:a,consequences:l}}function we(o){switch(o.status??o.state){case"active":return{text:"Active",kind:"active"};case"expired":return{text:"Expired",kind:"archived"};case"exhausted":return{text:"All used",kind:"paused"};case"rotated":return{text:"Replaced",kind:"archived"};default:return{text:"Revoked",kind:"archived"}}}function te(o){return o.state==="active"&&o.status==="active"}function It(o){return Number.isFinite(o)?new Date(o).toLocaleString(void 0,{day:"numeric",month:"short",year:"numeric",hour:"numeric",minute:"2-digit"}):"\u2014"}function se(o){return[{k:"Expires",v:It(o.expiresAt)},{k:"Redemptions",v:`${o.redemptions.toLocaleString()} of ${o.maxRedemptions.toLocaleString()} used`},{k:"Seats per buyer",v:`${o.maxQuantity.toLocaleString()} seat${o.maxQuantity===1?"":"s"} maximum`},{k:"Covers",v:o.includePublic?"This channel's allocation and Public sale seats":"This channel's allocation only"}]}function _(o){let e=o?.serverMessage?.trim();switch(o?.code){case"invalid_expiry":case"invalid_max_redemptions":case"invalid_max_quantity":case"invalid_session_ttl":case"invalid_label":return e||"That setting is outside what a hosted link allows. Adjust it and try again.";case"too_many_access_links":return e||"This channel already has as many live links as it can hold. Revoke one before creating another.";case"access_link_not_active":return"That link is no longer active, so it cannot be rotated or revoked.";case"channel_unavailable":return"This channel is paused or archived, so it cannot let new buyers in. Resume it first.";case"channel_access_intent_forbids":return Y(o?.details);case"end_active_sessions_required":return"Choose what happens to the buyers who already came in through this link.";case"not_found":return"That link is no longer here. Refresh and try again.";default:return o?.status===403?"Hosted access links need channel-management permission.":e||"That did not go through. Try again."}}function it(o){return(o?.channels??[]).map(e=>({kind:"skip",icon:"\u26A0",count:e.count,text:`${e.count.toLocaleString()} would leave ${e.name??"a channel"}`,why:"the new chart no longer has these seats",peek:e.labels?.length?de({count:e.count,labels:e.labels,truncated:e.truncated??!1}):void 0}))}function Se(o){return o==="builtin"?"Built-in":o==="active"?"Active":o==="paused"?"Paused":"Archived"}var C,T,he,Et,st,nt,ee,xe=N(()=>{"use strict";C="public",T="Public sale";he=["#a78bfa","#2dd4bf","#fb923c","#60a5fa","#f472b6","#a3e635","#f87171","#38bdf8","#c084fc","#facc15"],Et="#f4b740",st="ABCDEFGHJKLMNPQRSTUVWXYZ";nt=12;ee={maxRedemptions:100,maxQuantity:4}});function W(o){return o.map((e,t)=>`
1
+ "use strict";var $e=Object.defineProperty;var ft=Object.getOwnPropertyDescriptor;var yt=Object.getOwnPropertyNames;var kt=Object.prototype.hasOwnProperty;var N=(l,e,t)=>()=>{if(t)throw t[0];try{return l&&(e=l(l=0)),e}catch(s){throw t=[s],s}};var qe=(l,e)=>{for(var t in e)$e(l,t,{get:e[t],enumerable:!0})},wt=(l,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of yt(e))!kt.call(l,n)&&n!==t&&$e(l,n,{get:()=>e[n],enumerable:!(s=ft(e,n))||s.enumerable});return l};var xt=l=>wt($e({},"__esModule",{value:!0}),l);async function _e(l){let t=(l.headers.get("content-type")??"").includes("application/json")?await l.json().catch(()=>null):null;if(!l.ok){let s=t;throw new f(l.status,s?.error??`request_failed_${l.status}`,s?.code,s?.conflicts,s?.details,typeof s?.message=="string"?s.message:void 0)}return t}function $(l){return l&&typeof l=="object"?l:{}}function ie(l,e,t=0){return typeof l=="number"&&Number.isFinite(l)?l:typeof e=="number"&&Number.isFinite(e)?e:t}function je(l,e){return l===null?null:typeof l=="number"&&Number.isFinite(l)?l:l!==void 0?null:typeof e=="number"&&Number.isFinite(e)?e:null}function Ve(l){let e=$(l),t=ie(e.bookedValue,e.bookedRevenue);return{...e,bookedValue:t,bookedRevenue:t}}function St(l){let e=$(l),t=$(e.report),s=Array.isArray(t.byCategory)?t.byCategory.map(i=>{let a=$(i),o=ie(a.bookedValue,a.bookedRevenue);return{...a,bookedValue:o,bookedRevenue:o}}):[],n=Array.isArray(t.bySection)?t.bySection.map(Ve):void 0;return{...e,report:{...t,byCategory:s,...n?{bySection:n}:{}}}}function Lt(l){let e=$(l),t=$(e.bookedValue),s=$(e.revenue),n=Object.keys(t).length?t:s,i=Array.isArray(t.bySection)?t.bySection:Array.isArray(s.bySection)?s.bySection:[],a={...n,gross:ie(t.gross,s.gross),bySection:i.map(Ve)},o=$(e.velocity),r=Array.isArray(o.bySection)?o.bySection.map(d=>{let c=$(d),p=ie(c.bookedValue,c.grossRevenue);return{...c,bookedValue:p,grossRevenue:p}}):[];return{...e,bookedValue:a,revenue:a,velocity:{...o,bySection:r}}}function Ct(l){let e=$(l),t=$(e.report),s=typeof t.includesBookedValue=="boolean"?t.includesBookedValue:t.includesRevenue===!0,n=Array.isArray(t.rows)?t.rows.map(o=>{let r=$(o),d=$(r.attribution),c=je(d.bookedValue,d.revenue);return{...r,attribution:{...d,bookedValue:c,revenue:c}}}):[],i=$(t.totals),a=je(i.bookedValue,i.revenue);return{...e,report:{...t,includesBookedValue:s,includesRevenue:s,rows:n,totals:{...i,bookedValue:a,revenue:a}}}}function Te(l){let e=$(l),t=typeof e.includesBookedValue=="boolean"?e.includesBookedValue:e.includesRevenue===!0;return{...e,includesBookedValue:t,includesRevenue:t}}var f,U,ae=N(()=>{"use strict";f=class extends Error{constructor(e,t,s,n,i,a){super(t),this.name="ManageApiError",this.status=e,this.code=s,this.conflicts=n,this.details=i,this.serverMessage=a}};U=class{constructor(e,t){this.base=e.replace(/\/+$/,""),this.token=t}setToken(e){this.token=e}auth(e,t={}){let s=t.method??"GET",n={Authorization:`Bearer ${this.token}`},i;return t.body!==void 0&&(n["Content-Type"]="application/json",i=JSON.stringify(t.body)),fetch(`${this.base}${e}`,{method:s,headers:n,body:i,credentials:"omit"}).then(a=>_e(a))}async authBlob(e){let t=await fetch(`${this.base}${e}`,{method:"GET",headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});return t.ok||await _e(t),t.blob()}chart(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/chart`)}asset(e,t){return/^[a-zA-Z0-9._-]+$/.test(t)?this.authBlob(`/v1/events/${encodeURIComponent(e)}/assets/${encodeURIComponent(t)}`):Promise.reject(new f(404,"not_found","not_found"))}objects(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/objects`)}subscribeTicket(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/subscribe-tickets`,{method:"POST"})}socketUrl(e){return`${this.base.replace(/^http/,"ws")}/pub/events/${encodeURIComponent(e)}/subscribe?surface=manager`}block(e,t,s={}){let n={labels:t};return typeof s.releaseAt=="number"&&(n.releaseAt=s.releaseAt),s.reason&&(n.reason=s.reason),this.auth(`/v1/events/${encodeURIComponent(e)}/block`,{method:"POST",body:n})}unblock(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/unblock`,{method:"POST",body:{labels:t}})}unblockAll(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/unblock-all`,{method:"POST"})}unbook(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/unbook`,{method:"POST",body:{labels:t,bookingRef:s}})}setHoldTtl(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/hold-ttl`,{method:"POST",body:{holdTtlMs:t}})}setCategory(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/category-assignments`,{method:"POST",body:{labels:t,categoryKey:s}})}setTableBooking(e,t,s,n={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/table-booking`,{method:"POST",body:{tableIds:t,mode:s,...n}})}bookings(e,t={}){let s=new URLSearchParams;t.q&&s.set("q",t.q),t.state&&s.set("state",t.state),t.cursor&&s.set("cursor",t.cursor),t.limit!=null&&s.set("limit",String(t.limit));let n=s.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/bookings${n?`?${n}`:""}`)}booking(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/bookings/${encodeURIComponent(t)}`)}listBookings(e,t={}){return this.bookings(e,t)}retrieveBooking(e,t){return this.booking(e,t)}availability(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/availability`)}setAvailability(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/availability`,{method:"POST",body:{rules:t}})}channels(e,t={}){let s=t.includeArchived?"?includeArchived=1":"";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels${s}`)}channelAllocation(e,t={}){let s=new URLSearchParams;t.afterLabel&&s.set("afterLabel",t.afterLabel),t.limit!=null&&s.set("limit",String(t.limit));let n=s.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/allocation${n?`?${n}`:""}`)}channelAudit(e,t={}){let s=new URLSearchParams;t.limit!=null&&s.set("limit",String(t.limit)),t.before!=null&&s.set("before",String(t.before));let n=s.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/audit${n?`?${n}`:""}`)}createChannel(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels`,{method:"POST",body:t})}renameChannel(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{name:s}})}updateChannelPricing(e,t,s,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{priceOverrides:s,expectedPricingVersion:n}})}setChannelPaused(e,t,s){let n=s?"pause":"unpause";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/${n}`,{method:"POST",body:{}})}archiveChannel(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/archive`,{method:"POST",body:{destination:s}})}applyChannelAssignment(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/assignments`,{method:"POST",body:{targetChannelId:t.targetChannelId||null,labels:t.labels,assignmentVersion:t.assignmentVersion}})}channelPreview(e,t,s={}){let n=new URLSearchParams;t.length&&n.set("channelIds",t.join(",")),s.includePublic!=null&&n.set("includePublic",s.includePublic?"1":"0");let i=n.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/preview${i?`?${i}`:""}`)}setChannelAccessIntent(e,t,s,n={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{accessIntent:s,...n.acknowledgeLiveAccess?{acknowledgeLiveAccess:!0}:{},...n.reason?{reason:n.reason}:{}}})}createAccessLink(e,t,s={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links`,{method:"POST",body:s})}accessLinks(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links`)}rotateAccessLink(e,t,s,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links/${encodeURIComponent(s)}/rotate`,{method:"POST",body:{endActiveSessions:n}})}revokeAccessLink(e,t,s,n=!1){let i=n?"?endActiveSessions=1":"";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links/${encodeURIComponent(s)}${i}`,{method:"DELETE"})}report(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/report`).then(St)}controlRoom(e,t=15){return this.auth(`/v1/events/${encodeURIComponent(e)}/control-room?window=${t}`).then(Lt)}channelReport(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/report`).then(Ct)}createChannelReportLink(e,t,s={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`,{method:"POST",body:s}).then(n=>{let i=$(n);return{...i,link:Te(i.link)}})}channelReportLinks(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`).then(s=>{let n=$(s);return{links:Array.isArray(n.links)?n.links.map(Te):[]}})}revokeChannelReportLink(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links/${encodeURIComponent(s)}`,{method:"DELETE"}).then(n=>{let i=$(n);return{...i,link:Te(i.link)}})}log(e,t={}){let s=new URLSearchParams;t.limit!=null&&s.set("limit",String(t.limit)),t.before!=null&&s.set("before",String(t.before));let n=s.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/log${n?`?${n}`:""}`)}async reportCsv(e){let t=await fetch(`${this.base}/v1/events/${encodeURIComponent(e)}/report.csv`,{headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});if(!t.ok)throw new f(t.status,`request_failed_${t.status}`);return t.blob()}}});function P(l){return l==null||l===""||l===C}function O(l,e){let t=(l??"").trim();return((/\p{L}/u.exec(t)?.[0]??t[0]??"")||e).toUpperCase().slice(0,1)}function J(l,e){let t=new Set([...e].map(i=>O(i,"")).filter(Boolean)),s=O(l,"");return{letter:st.includes(s)&&!t.has(s)?s:[...st].find(i=>!t.has(i))??(s||"X"),color:he[t.size%he.length]}}function pe(l,e=0){return P(l.id)?{letter:O(l.marker,"P"),color:l.color||Et}:{letter:O(l.marker||l.name,"?"),color:l.color||he[e%he.length]}}function ue(l,e,t){let s=new Map;for(let a of l){let o=Be(e.get(a));s.set(o,(s.get(o)??0)+1)}let n=[{id:C,name:t?.publicSale?.name??T},...(t?.channels??[]).map(a=>({id:a.id,name:a.name}))],i=[];for(let a of n){let o=s.get(a.id);o&&i.push({channelId:a.id,name:a.name,count:o}),s.delete(a.id)}for(let[a,o]of s)i.push({channelId:a,name:P(a)?T:"Another channel",count:o});return i}function Be(l){return P(l)?C:l}function Pe(l){return{count:l.length,labels:l.slice(0,nt),truncated:l.length>nt}}function me(l){let{labels:e,allocation:t,statusOf:s,nameOf:n}=l,i=Be(l.targetChannelId),a=new Set,o=0,r=0,d=new Map,c=[],p=[],b=[];for(let g of e){if(a.has(g))continue;a.add(g);let m=s(g);if(!m){b.push(g);continue}let v=Be(t.get(g));if(v===i){r+=1;continue}if(m==="held"){c.push(g);continue}if(m==="booked"){p.push(g);continue}v===C?o+=1:d.set(v,(d.get(v)??0)+1)}let y=[...d.entries()].map(([g,m])=>({channelId:g,name:n(g),count:m}));return{changedFromPublic:{count:o},movedFromOtherChannel:{count:y.reduce((g,m)=>g+m.count,0),channels:y},alreadyInTarget:{count:r},skippedHeld:Pe(c),skippedBooked:Pe(p),notFound:Pe(b)}}function K(l){return l.changedFromPublic.count+l.movedFromOtherChannel.count}function be(l){return l.movedFromOtherChannel.count>0}function ge(l,e){let t=[];l.changedFromPublic.count&&t.push({kind:"add",icon:"+",count:l.changedFromPublic.count,text:`${l.changedFromPublic.count.toLocaleString()} from ${T}`});for(let s of l.movedFromOtherChannel.channels)t.push({kind:"move",icon:"\u21C4",count:s.count,text:`${s.count.toLocaleString()} moved out of ${s.name??"another channel"}`,why:"needs this confirmation"});return l.alreadyInTarget.count&&t.push({kind:"same",icon:"=",count:l.alreadyInTarget.count,text:`${l.alreadyInTarget.count.toLocaleString()} already in ${e}`,why:"unchanged"}),l.skippedHeld.count&&t.push({kind:"skip",icon:"\u23F8",count:l.skippedHeld.count,text:`${l.skippedHeld.count.toLocaleString()} in a buyer's checkout`,why:"can't move while held",peek:de(l.skippedHeld)}),l.skippedBooked.count&&t.push({kind:"skip",icon:"\u{1F512}",count:l.skippedBooked.count,text:`${l.skippedBooked.count.toLocaleString()} already sold`,why:"sales are never rewritten",peek:de(l.skippedBooked)}),l.notFound.count&&t.push({kind:"skip",icon:"?",count:l.notFound.count,text:`${l.notFound.count.toLocaleString()} not on this map`,why:"these seats are no longer part of the event",peek:de(l.notFound)}),t}function de(l){if(!l.labels.length)return;let e=l.labels.slice(0,4).join(", ");return l.truncated||l.labels.length>4?`${e}\u2026`:e}function ve(l){let e=l?.retryAfterMs??(l?.latestHoldExpiresAt?Math.max(0,l.latestHoldExpiresAt-Date.now()):0);if(!e)return"in a moment";let t=Math.ceil(e/6e4);return t<=1?"in about a minute":`in about ${t} minutes`}function fe(l){if(!l||!l.intent)return"\u2014";let e=l.intent==="server"?"Website integration":l.intent==="hosted_link"?"Buyer link":l.intent==="internal"?"Your staff sell these":"Protected reserve",t=l.hasActiveGrants?"in use now":l.lastMintAt?`last used ${new Date(l.lastMintAt).toLocaleDateString()}`:null,s=l.detail??t;return s?`${e} \xB7 ${s}`:e}function z(l){return l==="internal"?"Sell through your own staff":l==="server"?"Integrate a website or app":l==="hosted_link"?"Sell with a buyer link":"Keep as protected reserve"}function ye(l){switch(l){case"internal":return"Only your own box office can sell these seats, through your secret key. Buyer links and website integrations are refused.";case"server":return"Your website's backend mints each buyer a short-lived session for these seats. Buyer links are refused; the code lives on the Embed page.";case"hosted_link":return"SeatLayer makes a link you send to a named group. They open it and buy only these seats. No other route can sell them.";default:return"Nobody can buy these seats. Every way of letting a buyer in \u2014 a buyer link, your website, even your own staff \u2014 is refused while this is the route. The seats stay out of public sale."}}function Mt(l){return l==="hosted_link"?"hosted_link":l==="server"?"server":l==="staff"?"internal":null}function Y(l){let e=He(l?.accessIntent),t=Mt(l?.route),s=`This channel is set to "${z(e)}"`;return t?`${s}, so it cannot do that. Switch it to "${z(t)}" first.`:`${s}, so it cannot do that. Choose a different route for this channel first.`}function He(l){return l==="internal"||l==="server"||l==="hosted_link"||l==="none"?l:"none"}function ce(l,e,t){return`${l.toLocaleString()} ${l===1?e:t}`}function ke(l){let e=Math.max(0,l?.liveAccessLinks??0),t=Math.max(0,l?.activeSessions??0),s=He(l?.from),n=He(l?.to),a=`${[e?ce(e,"buyer link is live","buyer links are live"):null,t?ce(t,"buyer is in a checkout","buyers are in a checkout"):null].filter(Boolean).join(", and ")||"Buyers are inside this channel"} on "${z(s)}". Moving it to "${z(n)}" changes what happens to them.`,o=[];return e&&o.push(`${ce(e,"buyer link closes","buyer links close")} immediately. Anyone who has not opened it yet never will \u2014 send a new link if you still need one.`),t&&o.push(`${ce(t,"buyer who is already in a checkout keeps","buyers who are already in a checkout keep")} their seats and can finish paying. Nobody is thrown out. No new buyers come in this way, so the old route empties on its own within 12 hours.`),{headline:a,consequences:o}}function we(l){switch(l.status??l.state){case"active":return{text:"Active",kind:"active"};case"expired":return{text:"Expired",kind:"archived"};case"exhausted":return{text:"All used",kind:"paused"};case"rotated":return{text:"Replaced",kind:"archived"};default:return{text:"Revoked",kind:"archived"}}}function te(l){return l.state==="active"&&l.status==="active"}function It(l){return Number.isFinite(l)?new Date(l).toLocaleString(void 0,{day:"numeric",month:"short",year:"numeric",hour:"numeric",minute:"2-digit"}):"\u2014"}function se(l){return[{k:"Expires",v:It(l.expiresAt)},{k:"Redemptions",v:`${l.redemptions.toLocaleString()} of ${l.maxRedemptions.toLocaleString()} used`},{k:"Seats per buyer",v:`${l.maxQuantity.toLocaleString()} seat${l.maxQuantity===1?"":"s"} maximum`},{k:"Covers",v:l.includePublic?"This channel's allocation and Public sale seats":"This channel's allocation only"}]}function _(l){let e=l?.serverMessage?.trim();switch(l?.code){case"invalid_expiry":case"invalid_max_redemptions":case"invalid_max_quantity":case"invalid_session_ttl":case"invalid_label":return e||"That setting is outside what a hosted link allows. Adjust it and try again.";case"too_many_access_links":return e||"This channel already has as many live links as it can hold. Revoke one before creating another.";case"access_link_not_active":return"That link is no longer active, so it cannot be rotated or revoked.";case"channel_unavailable":return"This channel is paused or archived, so it cannot let new buyers in. Resume it first.";case"channel_access_intent_forbids":return Y(l?.details);case"end_active_sessions_required":return"Choose what happens to the buyers who already came in through this link.";case"not_found":return"That link is no longer here. Refresh and try again.";default:return l?.status===403?"Hosted access links need channel-management permission.":e||"That did not go through. Try again."}}function it(l){return(l?.channels??[]).map(e=>({kind:"skip",icon:"\u26A0",count:e.count,text:`${e.count.toLocaleString()} would leave ${e.name??"a channel"}`,why:"the new chart no longer has these seats",peek:e.labels?.length?de({count:e.count,labels:e.labels,truncated:e.truncated??!1}):void 0}))}function xe(l){return l==="builtin"?"Built-in":l==="active"?"Active":l==="paused"?"Paused":"Archived"}var C,T,he,Et,st,nt,ee,Se=N(()=>{"use strict";C="public",T="Public sale";he=["#a78bfa","#2dd4bf","#fb923c","#60a5fa","#f472b6","#a3e635","#f87171","#38bdf8","#c084fc","#facc15"],Et="#f4b740",st="ABCDEFGHJKLMNPQRSTUVWXYZ";nt=12;ee={maxRedemptions:100,maxQuantity:4}});function W(l){return l.map((e,t)=>`
2
2
  <div class="slm-ch-bucket" style="animation-delay:${Math.min(t,4)*30}ms">
3
3
  <span class="ico ${e.kind}" aria-hidden="true">${h(e.icon)}</span>
4
4
  <span><b>${e.count.toLocaleString()}</b> ${h(e.text.replace(/^[\d,.\s]+/,""))}
5
5
  ${e.why?`<span class="why">\u2014 ${h(e.why)}</span>`:""}</span>
6
6
  ${e.peek?`<span class="peek">${h(e.peek)}</span>`:"<span></span>"}
7
- </div>`).join("")}function h(o){return String(o??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function ot(o){return new Date(o-new Date(o).getTimezoneOffset()*6e4).toISOString().slice(0,16)}function De(o,e){let t=o.querySelector(e)?.value.trim()??"",s=Number(t);return t!==""&&Number.isInteger(s)?s:null}function Oe(o){let e=o.querySelector("[data-ch-lk-url]");if(e)try{let t=document.createRange();t.selectNodeContents(e);let s=window.getSelection();s?.removeAllRanges(),s?.addRange(t)}catch{}}var at,Le=N(()=>{"use strict";at=`
7
+ </div>`).join("")}function h(l){return String(l??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function ot(l){return new Date(l-new Date(l).getTimezoneOffset()*6e4).toISOString().slice(0,16)}function De(l,e){let t=l.querySelector(e)?.value.trim()??"",s=Number(t);return t!==""&&Number.isInteger(s)?s:null}function Oe(l){let e=l.querySelector("[data-ch-lk-url]");if(e)try{let t=document.createRange();t.selectNodeContents(e);let s=window.getSelection();s?.removeAllRanges(),s?.addRange(t)}catch{}}var at,Le=N(()=>{"use strict";at=`
8
8
  <p class="slm-eyebrow" style="margin-top:18px">On your website</p>
9
9
  <p class="slm-hint">There is nothing more to set up on this screen. Your own server mints a short-lived buyer
10
10
  access session for this channel with the SeatLayer server SDK and hands it to the widget. A channel name
11
11
  on its own never grants access.</p>
12
12
  <p class="slm-note"><a class="slm-linkbtn" href="https://docs.seatlayer.io/server-api/channels"
13
- target="_blank" rel="noreferrer noopener">Read the website integration guide \u2192</a></p>`});function lt(o){let e=o.canvas,t=o.layer;if(!e||!t)return;let s=o.host.mapLayer.getBoundingClientRect(),n=Math.max(1,Math.round(s.width)),i=Math.max(1,Math.round(s.height)),a=typeof devicePixelRatio=="number"?Math.min(3,Math.max(1,devicePixelRatio)):1;(e.width!==n*a||e.height!==i*a)&&(e.width=n*a,e.height=i*a);let l=o.resolveCtx();if(!l)return;l.setTransform(a,0,0,a,0,0),l.clearRect(0,0,n,i);let r=o.host.isSeatDetail(),d=Math.max(3,o.host.seatPixelSize()),c=d/2,p=o.view==="preview"?o.previewProjection:null,g=p?new Set(p.available===!1?[]:p.eligible??[]):null,w=new Map,b=!r&&o.host.sections().length>1?new Map:null,m=o.view==="preview"&&r&&d<=15?new Map:null;for(let v of o.host.seats()){let P=o.host.statusOf(v.label)??"free",F=o.allocation.get(v.label)??C;if(F!==C){let S=w.get(F)??{x:0,y:0,n:0};S.x+=v.x,S.y+=v.y,S.n+=1,w.set(F,S)}if(!r){let S=o.host.sectionOfLabel(v.label),k=S?o.host.worldToScreen({x:v.x,y:v.y}):null;if(b&&S&&k){let y=b.get(S.id)??{label:S.label,minX:k.x,minY:k.y,maxX:k.x,maxY:k.y};y.minX=Math.min(y.minX,k.x),y.minY=Math.min(y.minY,k.y),y.maxX=Math.max(y.maxX,k.x),y.maxY=Math.max(y.maxY,k.y),b.set(S.id,y)}continue}if(P!=="free")continue;let q=null,E=null;if(o.view==="preview"?g?.has(v.label)?(q=Pt,E=Ht):(q=Dt,E=Ot):F!==C&&(q=o.markerFor(F).color,E=zt),!q)continue;let x=o.host.worldToScreen({x:v.x,y:v.y});if(x&&!(x.x<-d||x.y<-d||x.x>n+d||x.y>i+d)){if(m){let S=o.host.sectionOfLabel(v.label);if(S){let k=m.get(S.id)??{label:S.label,minX:x.x,minY:x.y,maxX:x.x,maxY:x.y};k.minX=Math.min(k.minX,x.x),k.minY=Math.min(k.minY,x.y),k.maxX=Math.max(k.maxX,x.x),k.maxY=Math.max(k.maxY,x.y),m.set(S.id,k)}}if(l.fillStyle=q,o.view==="preview"||F!==C){let S=Math.max(2,c+Math.min(1.5,c*.06));l.globalAlpha=1,l.beginPath(),l.arc(x.x,x.y,S,0,Math.PI*2),l.fill(),l.strokeStyle=E??q,l.lineWidth=o.view==="preview"?Math.max(1,Math.min(1.75,d*.13)):Math.max(1,Math.min(1.5,d*.1)),l.stroke(),o.view==="preview"&&g?.has(v.label)&&d>=22&&Ft(l,v.label,x.x,x.y,S)}else l.globalAlpha=.85,l.fillRect(x.x-c,x.y-c,d,d)}}l.globalAlpha=1,m&&_t(l,m),qt(b,o),jt(w,o,l)}function Ft(o,e,t,s,n){let i=n*1.55,a=Math.min(13,Math.max(7,n*.55)),l=6;for(;a>=l&&(o.font=`800 ${a}px var(--slm-font, system-ui, sans-serif)`,!(o.measureText(e).width<=i));)a-=.5;a<l||(o.fillStyle="#ffffff",o.textAlign="center",o.textBaseline="middle",o.fillText(e,t,s))}function qt(o,e){let t=e.layer;if(t&&(t.querySelectorAll(".slm-ch-section-target").forEach(s=>s.remove()),!!o))for(let[s,n]of o){let i=n.maxX-n.minX,a=n.maxY-n.minY;if(i<20||a<20)continue;let l=document.createElement("button");l.type="button",l.className="slm-ch-section-target",l.style.left=`${n.minX-8}px`,l.style.top=`${n.minY-8}px`,l.style.width=`${i+16}px`,l.style.height=`${a+16}px`,l.setAttribute("aria-label",`Open ${n.label} seats`),l.addEventListener("click",()=>e.onSectionTargetClick(s)),t.appendChild(l)}}function _t(o,e){for(let t of e.values()){let s=t.maxX-t.minX,n=t.maxY-t.minY;if(s<52||n<26)continue;let i=(t.minX+t.maxX)/2,a=(t.minY+t.maxY)/2,l=Math.max(11,Math.min(15,n*.16));o.font=`800 ${l}px var(--slm-font, system-ui, sans-serif)`;let r=Math.min(s-8,o.measureText(t.label).width+18),d=l+10;o.fillStyle="rgba(11, 16, 28, .88)",o.fillRect(i-r/2,a-d/2,r,d),o.fillStyle="#f8fafc",o.textAlign="center",o.textBaseline="middle",o.fillText(t.label,i,a)}}function jt(o,e,t){let s=e.layer;if(!s||(s.querySelectorAll(".slm-ch-flag").forEach(i=>i.remove()),e.view==="preview"))return;let n=[...o.entries()].sort((i,a)=>a[1].n-i[1].n).slice(0,Bt);for(let[i,a]of n){let l=e.list?.channels.find(p=>p.id===i);if(!l)continue;let r=e.host.worldToScreen({x:a.x/a.n,y:a.y/a.n});if(!r)continue;let d=e.markerFor(i),c=document.createElement("span");c.className="slm-ch-flag",c.style.left=`${r.x}px`,c.style.top=`${r.y}px`,c.innerHTML=`<span class="mk" style="background:${h(d.color)}">${h(d.letter)}</span>${h(l.name)}${l.state==="paused"?" \xB7 Paused":""}`,s.appendChild(c)}}var Bt,Pt,Ht,Dt,Ot,zt,rt=N(()=>{"use strict";xe();Le();Bt=8,Pt="#6e7bff",Ht="#b9c0ff",Dt="#303846",Ot="#4b5669",zt="#101723"});var ct,dt=N(()=>{"use strict";ct=`
13
+ target="_blank" rel="noreferrer noopener">Read the website integration guide \u2192</a></p>`});function lt(l){let e=l.canvas,t=l.layer;if(!e||!t)return;let s=l.host.mapLayer.getBoundingClientRect(),n=Math.max(1,Math.round(s.width)),i=Math.max(1,Math.round(s.height)),a=typeof devicePixelRatio=="number"?Math.min(3,Math.max(1,devicePixelRatio)):1;(e.width!==n*a||e.height!==i*a)&&(e.width=n*a,e.height=i*a);let o=l.resolveCtx();if(!o)return;o.setTransform(a,0,0,a,0,0),o.clearRect(0,0,n,i);let r=l.host.isSeatDetail(),d=Math.max(3,l.host.seatPixelSize()),c=d/2,p=l.view==="preview"?l.previewProjection:null,b=p?new Set(p.available===!1?[]:p.eligible??[]):null,y=new Map,g=!r&&l.host.sections().length>1?new Map:null,m=l.view==="preview"&&r&&d<=15?new Map:null;for(let v of l.host.seats()){let B=l.host.statusOf(v.label)??"free",F=l.allocation.get(v.label)??C;if(F!==C){let x=y.get(F)??{x:0,y:0,n:0};x.x+=v.x,x.y+=v.y,x.n+=1,y.set(F,x)}if(!r){let x=l.host.sectionOfLabel(v.label),w=x?l.host.worldToScreen({x:v.x,y:v.y}):null;if(g&&x&&w){let k=g.get(x.id)??{label:x.label,minX:w.x,minY:w.y,maxX:w.x,maxY:w.y};k.minX=Math.min(k.minX,w.x),k.minY=Math.min(k.minY,w.y),k.maxX=Math.max(k.maxX,w.x),k.maxY=Math.max(k.maxY,w.y),g.set(x.id,k)}continue}if(B!=="free")continue;let q=null,E=null;if(l.view==="preview"?b?.has(v.label)?(q=Bt,E=Ht):(q=Dt,E=Ot):F!==C&&(q=l.markerFor(F).color,E=zt),!q)continue;let S=l.host.worldToScreen({x:v.x,y:v.y});if(S&&!(S.x<-d||S.y<-d||S.x>n+d||S.y>i+d)){if(m){let x=l.host.sectionOfLabel(v.label);if(x){let w=m.get(x.id)??{label:x.label,minX:S.x,minY:S.y,maxX:S.x,maxY:S.y};w.minX=Math.min(w.minX,S.x),w.minY=Math.min(w.minY,S.y),w.maxX=Math.max(w.maxX,S.x),w.maxY=Math.max(w.maxY,S.y),m.set(x.id,w)}}if(o.fillStyle=q,l.view==="preview"||F!==C){let x=Math.max(2,c+Math.min(1.5,c*.06));o.globalAlpha=1,o.beginPath(),o.arc(S.x,S.y,x,0,Math.PI*2),o.fill(),o.strokeStyle=E??q,o.lineWidth=l.view==="preview"?Math.max(1,Math.min(1.75,d*.13)):Math.max(1,Math.min(1.5,d*.1)),o.stroke(),l.view==="preview"&&b?.has(v.label)&&d>=22&&Ft(o,v.label,S.x,S.y,x)}else o.globalAlpha=.85,o.fillRect(S.x-c,S.y-c,d,d)}}o.globalAlpha=1,m&&_t(o,m),qt(g,l),jt(y,l,o)}function Ft(l,e,t,s,n){let i=n*1.55,a=Math.min(13,Math.max(7,n*.55)),o=6;for(;a>=o&&(l.font=`800 ${a}px var(--slm-font, system-ui, sans-serif)`,!(l.measureText(e).width<=i));)a-=.5;a<o||(l.fillStyle="#ffffff",l.textAlign="center",l.textBaseline="middle",l.fillText(e,t,s))}function qt(l,e){let t=e.layer;if(t&&(t.querySelectorAll(".slm-ch-section-target").forEach(s=>s.remove()),!!l))for(let[s,n]of l){let i=n.maxX-n.minX,a=n.maxY-n.minY;if(i<20||a<20)continue;let o=document.createElement("button");o.type="button",o.className="slm-ch-section-target",o.style.left=`${n.minX-8}px`,o.style.top=`${n.minY-8}px`,o.style.width=`${i+16}px`,o.style.height=`${a+16}px`,o.setAttribute("aria-label",`Open ${n.label} seats`),o.addEventListener("click",()=>e.onSectionTargetClick(s)),t.appendChild(o)}}function _t(l,e){for(let t of e.values()){let s=t.maxX-t.minX,n=t.maxY-t.minY;if(s<52||n<26)continue;let i=(t.minX+t.maxX)/2,a=(t.minY+t.maxY)/2,o=Math.max(11,Math.min(15,n*.16));l.font=`800 ${o}px var(--slm-font, system-ui, sans-serif)`;let r=Math.min(s-8,l.measureText(t.label).width+18),d=o+10;l.fillStyle="rgba(11, 16, 28, .88)",l.fillRect(i-r/2,a-d/2,r,d),l.fillStyle="#f8fafc",l.textAlign="center",l.textBaseline="middle",l.fillText(t.label,i,a)}}function jt(l,e,t){let s=e.layer;if(!s||(s.querySelectorAll(".slm-ch-flag").forEach(i=>i.remove()),e.view==="preview"))return;let n=[...l.entries()].sort((i,a)=>a[1].n-i[1].n).slice(0,Pt);for(let[i,a]of n){let o=e.list?.channels.find(p=>p.id===i);if(!o)continue;let r=e.host.worldToScreen({x:a.x/a.n,y:a.y/a.n});if(!r)continue;let d=e.markerFor(i),c=document.createElement("span");c.className="slm-ch-flag",c.style.left=`${r.x}px`,c.style.top=`${r.y}px`,c.innerHTML=`<span class="mk" style="background:${h(d.color)}">${h(d.letter)}</span>${h(o.name)}${o.state==="paused"?" \xB7 Paused":""}`,s.appendChild(c)}}var Pt,Bt,Ht,Dt,Ot,zt,rt=N(()=>{"use strict";Se();Le();Pt=8,Bt="#6e7bff",Ht="#b9c0ff",Dt="#303846",Ot="#4b5669",zt="#101723"});var ct,dt=N(()=>{"use strict";ct=`
14
14
  .slm{--slm-mo-instant:80ms;--slm-mo-quick:140ms;--slm-mo-base:200ms;--slm-mo-slow:320ms;--slm-mo-ambient:2000ms;
15
15
  --slm-mo-out:cubic-bezier(.2,.8,.2,1);--slm-mo-in-out:cubic-bezier(.4,0,.2,1);--slm-mo-exit:cubic-bezier(.4,0,1,1);
16
16
  --slm-mo-spring:cubic-bezier(.34,1.3,.64,1)}
@@ -116,6 +116,10 @@
116
116
  .slm-ch-selnum.bump{animation:slm-ch-bump var(--slm-mo-base) var(--slm-mo-spring)}
117
117
  .slm-ch-row2{display:flex;gap:8px;margin-top:8px}
118
118
  .slm-ch-row2 .slm-btn{flex:1;min-width:0}
119
+ .slm-ch-price-summary{display:flex;align-items:center;gap:10px;padding:11px;border:1px solid var(--slm-line);
120
+ border-radius:10px;background:var(--slm-surface);font-size:11.5px;line-height:1.45;color:var(--slm-muted)}
121
+ .slm-ch-price-summary span{flex:1;min-width:0}
122
+ .slm-ch-price-summary .slm-btn{flex:none;min-height:36px;padding:7px 10px}
119
123
  /* distribute routes \u2014 four choices, each with the one sentence that explains it.
120
124
  The current one is NAMED in its own card, never signalled by colour alone. */
121
125
  .slm-ch-dist{display:flex;flex-direction:column;gap:6px;padding:12px;margin-bottom:8px;border:1px solid var(--slm-line);
@@ -167,6 +171,14 @@
167
171
  border-radius:10px;background:rgba(244,183,64,.06);font-family:ui-monospace,Menlo,monospace;font-size:11px;
168
172
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
169
173
  .slm-ch-err{color:#f1a4a6;font-size:11.5px;margin-top:6px}
174
+ .slm-ch-price-list{display:flex;flex-direction:column;gap:7px}
175
+ .slm-ch-price-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(100px,132px);align-items:center;gap:12px;
176
+ padding:9px 0;border-bottom:1px solid var(--slm-line)}
177
+ .slm-ch-price-row:last-child{border-bottom:0}
178
+ .slm-ch-price-row>span{min-width:0;display:flex;flex-direction:column;gap:3px}
179
+ .slm-ch-price-row b{font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
180
+ .slm-ch-price-row small{font-size:10.5px;color:var(--slm-muted);font-weight:500}
181
+ .slm-ch-price-row .slm-input{margin:0;text-align:right;font-variant-numeric:tabular-nums}
170
182
 
171
183
  /* buyer links \u2014 STATUS only; there is no Copy control on this card */
172
184
  .slm-ch-link{padding:10px 11px;border:1px solid var(--slm-line);border-radius:10px;background:var(--slm-surface);
@@ -241,19 +253,19 @@
241
253
  .slm-ch-staged.shake{outline:2px solid #e5484d;outline-offset:2px}
242
254
  .slm-ch-staged.done{outline:2px solid #5bd39b;outline-offset:2px}
243
255
  }
244
- `});var pt={};qe(pt,{CHANNELS_CSS:()=>ct,ChannelsMode:()=>ne,bucketRowsHtml:()=>W});var Vt,ht,A,ne,ze=N(()=>{"use strict";xe();ae();rt();Le();dt();Le();Vt=3e4,ht=300,A=5e3,ne=class{constructor(e,t){this.active=!1;this.list=null;this.allocation=new Map;this.assignmentVersion=0;this.loadError=null;this.loading=!0;this.view="inspect";this.mapIntent="pan";this.focusedSectionId=null;this.showArchived=!1;this.detailChannelId=null;this.assignOpen=!1;this.targetChannelId="";this.conflict=!1;this.dialog=null;this.detent="medium";this.seatListLimit=ht;this.links=[];this.linksChannelId=null;this.linksState="idle";this.listSeq=0;this.linksSeq=0;this.previewAudience=[];this.previewIncludePublic=!1;this.previewProjection=null;this.previewState="idle";this.pollTimer=null;this.layer=null;this.canvas=null;this.ctx=void 0;this.bannerEl=null;this.stagedEl=null;this.liveEl=null;this.scrimEl=null;this.lastFocus=null;this.stagedDoneTimer=null;this.lastSelectionCount=0;this.lastCounts=new Map;this.assignmentRowsCache=null;this.railHtml=null;this.allocationVersion=null;this.onVisibility=null;this.host=e,this.caps=t}enter(){this.active||(this.active=!0,this.mapIntent="pan",this.assignOpen=!1,this.focusedSectionId=null,this.assignmentRowsCache=null,this.railHtml=null,this.ensureLayer(),this.host.root.classList.add("ch-mode"),this.applySheetClasses(),this.host.sections().length>1&&this.host.showSectionOverview(),this.paintRail(),this.onInteractionChange?.(),this.refresh(),this.pollTimer=setInterval(()=>{typeof document<"u"&&document.hidden||this.refresh({quiet:!0})},Vt),typeof document<"u"&&typeof document.addEventListener=="function"&&(this.onVisibility=()=>{this.active&&!document.hidden&&this.refresh({quiet:!0})},document.addEventListener("visibilitychange",this.onVisibility)))}leave(){this.active&&(this.active=!1,this.pollTimer&&clearInterval(this.pollTimer),this.pollTimer=null,this.onVisibility&&typeof document<"u"&&document.removeEventListener("visibilitychange",this.onVisibility),this.onVisibility=null,this.railHtml=null,this.closeDialog({restoreFocus:!1}),this.links=[],this.linksChannelId=null,this.linksState="idle",this.layer?.classList.remove("on"),this.host.root.classList.remove("ch-mode","ch-preview","ch-sheet","detent-collapsed","detent-medium","detent-full"),this.setBanner(!1),this.setStaged(null))}destroy(){this.leave(),this.stagedDoneTimer&&clearTimeout(this.stagedDoneTimer),this.layer?.remove(),this.layer=null}setCapabilities(e){this.caps=e,this.active&&this.paintRail()}isActive(){return this.active}canSelect(){return this.caps.manage&&this.view==="inspect"}usesMarqueeSelection(){return this.canSelect()&&this.mapIntent==="assign"}handleSectionFocus(e){this.active&&(this.focusedSectionId=e,this.paintRail())}applyRealtimeHint(){this.active&&this.refresh({quiet:!0})}handleSelectionChange(){this.active&&(this.paintSelection(),this.paintStagedBar())}handleViewChange(){this.active&&this.paintOverlay()}handleLayoutChange(){this.active&&(this.applySheetClasses(),this.paintOverlay())}async refresh(e={}){if(!this.caps.view)return;let t=++this.listSeq,s=()=>t!==this.listSeq;try{let n=await this.host.api.channels(this.host.eventKey,{includeArchived:this.showArchived});if(s())return;if(this.list=n,this.assignmentVersion=n.assignmentVersion,this.loadError=null,this.targetChannelId||(this.targetChannelId=n.channels.find(i=>i.state==="active")?.id??C),this.allocationVersion!==n.assignmentVersion){if(await this.loadAllocation(t),s())return;this.allocationVersion=n.assignmentVersion}if(this.detailChannelId&&await this.loadLinks(this.detailChannelId),s())return;this.loading=!1,this.active&&(this.paintRail(),this.paintOverlay())}catch(n){if(s())return;this.loading=!1,n instanceof f&&n.status===403&&(this.caps={view:!1,manage:!1}),this.loadError=n,e.quiet||this.host.onError(n),this.active&&this.paintRail()}}async loadAllocation(e){let t=new Map,s;for(let n=0;n<200;n+=1){if(e!==void 0&&e!==this.listSeq)return;let i=await this.host.api.channelAllocation(this.host.eventKey,{afterLabel:s,limit:1e3});for(let a of i.allocations)B(a.channelId)||t.set(a.label,a.channelId);if(this.assignmentVersion=i.assignmentVersion,!i.nextAfterLabel)break;s=i.nextAfterLabel}e!==void 0&&e!==this.listSeq||(this.allocation=t)}channelById(e){if(B(e))return{id:C,name:this.list?.publicSale?.name??T,marker:"P",color:null};let t=this.list?.channels.find(s=>s.id===e);return t?{id:e,name:t.name,marker:t.marker,color:t.color}:null}nameOf(e){return this.channelById(e)?.name??null}markerFor(e){let t=Math.max(0,this.list?.channels.findIndex(n=>n.id===e)??0),s=this.channelById(e);return pe(s??{id:e,name:"?",marker:null,color:null},t)}assignableChannels(){return[{id:C,name:this.list?.publicSale.name??T},...(this.list?.channels??[]).filter(e=>e.state!=="archived").map(e=>({id:e.id,name:e.name}))]}currentPlan(){let e=this.host.selectionLabels(),t=me({labels:e,targetChannelId:this.targetChannelId,allocation:this.allocation,statusOf:s=>this.host.statusOf(s),nameOf:s=>this.nameOf(s)});return{labels:e,buckets:t,target:this.targetChannelId}}ensureLayer(){if(this.layer)return;let e=document.createElement("div");e.className="slm-ch-layer",e.innerHTML=`
256
+ `});var pt={};qe(pt,{CHANNELS_CSS:()=>ct,ChannelsMode:()=>ne,bucketRowsHtml:()=>W});var Vt,ht,A,ne,ze=N(()=>{"use strict";Se();ae();rt();Le();dt();Le();Vt=3e4,ht=300,A=5e3,ne=class{constructor(e,t){this.active=!1;this.list=null;this.allocation=new Map;this.assignmentVersion=0;this.loadError=null;this.loading=!0;this.view="inspect";this.mapIntent="pan";this.focusedSectionId=null;this.showArchived=!1;this.detailChannelId=null;this.assignOpen=!1;this.targetChannelId="";this.conflict=!1;this.dialog=null;this.detent="medium";this.seatListLimit=ht;this.links=[];this.linksChannelId=null;this.linksState="idle";this.listSeq=0;this.linksSeq=0;this.previewAudience=[];this.previewIncludePublic=!1;this.previewProjection=null;this.previewState="idle";this.pollTimer=null;this.layer=null;this.canvas=null;this.ctx=void 0;this.bannerEl=null;this.stagedEl=null;this.liveEl=null;this.scrimEl=null;this.lastFocus=null;this.stagedDoneTimer=null;this.lastSelectionCount=0;this.lastCounts=new Map;this.assignmentRowsCache=null;this.railHtml=null;this.allocationVersion=null;this.onVisibility=null;this.host=e,this.caps=t}enter(){this.active||(this.active=!0,this.mapIntent="pan",this.assignOpen=!1,this.focusedSectionId=null,this.assignmentRowsCache=null,this.railHtml=null,this.ensureLayer(),this.host.root.classList.add("ch-mode"),this.applySheetClasses(),this.host.sections().length>1&&this.host.showSectionOverview(),this.paintRail(),this.onInteractionChange?.(),this.refresh(),this.pollTimer=setInterval(()=>{typeof document<"u"&&document.hidden||this.refresh({quiet:!0})},Vt),typeof document<"u"&&typeof document.addEventListener=="function"&&(this.onVisibility=()=>{this.active&&!document.hidden&&this.refresh({quiet:!0})},document.addEventListener("visibilitychange",this.onVisibility)))}leave(){this.active&&(this.active=!1,this.pollTimer&&clearInterval(this.pollTimer),this.pollTimer=null,this.onVisibility&&typeof document<"u"&&document.removeEventListener("visibilitychange",this.onVisibility),this.onVisibility=null,this.railHtml=null,this.closeDialog({restoreFocus:!1}),this.links=[],this.linksChannelId=null,this.linksState="idle",this.layer?.classList.remove("on"),this.host.root.classList.remove("ch-mode","ch-preview","ch-sheet","detent-collapsed","detent-medium","detent-full"),this.setBanner(!1),this.setStaged(null))}destroy(){this.leave(),this.stagedDoneTimer&&clearTimeout(this.stagedDoneTimer),this.layer?.remove(),this.layer=null}setCapabilities(e){this.caps=e,this.active&&this.paintRail()}isActive(){return this.active}canSelect(){return this.caps.manage&&this.view==="inspect"}usesMarqueeSelection(){return this.canSelect()&&this.mapIntent==="assign"}handleSectionFocus(e){this.active&&(this.focusedSectionId=e,this.paintRail())}applyRealtimeHint(){this.active&&this.refresh({quiet:!0})}handleSelectionChange(){this.active&&(this.paintSelection(),this.paintStagedBar())}handleViewChange(){this.active&&this.paintOverlay()}handleLayoutChange(){this.active&&(this.applySheetClasses(),this.paintOverlay())}async refresh(e={}){if(!this.caps.view)return;let t=++this.listSeq,s=()=>t!==this.listSeq;try{let n=await this.host.api.channels(this.host.eventKey,{includeArchived:this.showArchived});if(s())return;if(this.list=n,this.assignmentVersion=n.assignmentVersion,this.loadError=null,this.targetChannelId||(this.targetChannelId=n.channels.find(i=>i.state==="active")?.id??C),this.allocationVersion!==n.assignmentVersion){if(await this.loadAllocation(t),s())return;this.allocationVersion=n.assignmentVersion}if(this.detailChannelId&&await this.loadLinks(this.detailChannelId),s())return;this.loading=!1,this.active&&(this.paintRail(),this.paintOverlay())}catch(n){if(s())return;this.loading=!1,n instanceof f&&n.status===403&&(this.caps={view:!1,manage:!1}),this.loadError=n,e.quiet||this.host.onError(n),this.active&&this.paintRail()}}async loadAllocation(e){let t=new Map,s;for(let n=0;n<200;n+=1){if(e!==void 0&&e!==this.listSeq)return;let i=await this.host.api.channelAllocation(this.host.eventKey,{afterLabel:s,limit:1e3});for(let a of i.allocations)P(a.channelId)||t.set(a.label,a.channelId);if(this.assignmentVersion=i.assignmentVersion,!i.nextAfterLabel)break;s=i.nextAfterLabel}e!==void 0&&e!==this.listSeq||(this.allocation=t)}channelById(e){if(P(e))return{id:C,name:this.list?.publicSale?.name??T,marker:"P",color:null};let t=this.list?.channels.find(s=>s.id===e);return t?{id:e,name:t.name,marker:t.marker,color:t.color}:null}nameOf(e){return this.channelById(e)?.name??null}markerFor(e){let t=Math.max(0,this.list?.channels.findIndex(n=>n.id===e)??0),s=this.channelById(e);return pe(s??{id:e,name:"?",marker:null,color:null},t)}assignableChannels(){return[{id:C,name:this.list?.publicSale.name??T},...(this.list?.channels??[]).filter(e=>e.state!=="archived").map(e=>({id:e.id,name:e.name}))]}currentPlan(){let e=this.host.selectionLabels(),t=me({labels:e,targetChannelId:this.targetChannelId,allocation:this.allocation,statusOf:s=>this.host.statusOf(s),nameOf:s=>this.nameOf(s)});return{labels:e,buckets:t,target:this.targetChannelId}}ensureLayer(){if(this.layer)return;let e=document.createElement("div");e.className="slm-ch-layer",e.innerHTML=`
245
257
  <canvas class="slm-ch-canvas" data-ch="canvas" aria-hidden="true"></canvas>
246
258
  <div class="slm-ch-banner" data-ch="banner" role="status"></div>
247
259
  <div class="slm-ch-staged" data-ch="staged" role="group" aria-label="Staged channel changes"></div>
248
- <div class="slm-ch-live" data-ch="live" role="status" aria-live="polite"></div>`,this.host.mapLayer.appendChild(e),this.layer=e,this.canvas=e.querySelector('[data-ch="canvas"]'),this.bannerEl=e.querySelector('[data-ch="banner"]'),this.stagedEl=e.querySelector('[data-ch="staged"]'),this.liveEl=e.querySelector('[data-ch="live"]'),requestAnimationFrame(()=>e.classList.add("on"))}announce(e){this.liveEl&&(this.liveEl.textContent=e)}paintOverlay(){let e=this.canvas,t=this.layer;!e||!t||lt({layer:t,canvas:e,resolveCtx:()=>{if(this.ctx===void 0)try{this.ctx=e.getContext("2d")}catch{this.ctx=null}return this.ctx},host:this.host,view:this.view,previewProjection:this.previewProjection,allocation:this.allocation,focusedSectionId:this.focusedSectionId,list:this.list,markerFor:s=>this.markerFor(s),onSectionTargetClick:s=>{this.focusedSectionId=s,this.host.focusSection(s),this.paintRail()}})}setStaged(e,t=""){let s=this.stagedEl;if(s){if(!e){s.classList.remove("on","done","shake"),s.innerHTML="";return}s.innerHTML=e,s.className=`slm-ch-staged on${t?` ${t}`:""}`}}paintStagedBar(){if(!this.active||this.view==="preview"||!this.caps.manage){this.setStaged(null);return}let{labels:e,buckets:t}=this.currentPlan();if(this.host.onStagedChange?.(K(t)),!e.length){this.setStaged(null);return}let s=this.nameOf(this.targetChannelId)??T,n=K(t),i=e.length>A,a=t.skippedHeld.count+t.skippedBooked.count,l=[`<b>${e.length.toLocaleString()}</b> selected`,`<b>+${n.toLocaleString()}</b> to ${h(s)}`];t.alreadyInTarget.count&&l.push(`<b>${t.alreadyInTarget.count.toLocaleString()}</b> already in`),a&&l.push(`<b>${a.toLocaleString()}</b> can't move now`),this.setStaged(`
249
- <span>${l.join(" \xB7 ")}</span>
260
+ <div class="slm-ch-live" data-ch="live" role="status" aria-live="polite"></div>`,this.host.mapLayer.appendChild(e),this.layer=e,this.canvas=e.querySelector('[data-ch="canvas"]'),this.bannerEl=e.querySelector('[data-ch="banner"]'),this.stagedEl=e.querySelector('[data-ch="staged"]'),this.liveEl=e.querySelector('[data-ch="live"]'),requestAnimationFrame(()=>e.classList.add("on"))}announce(e){this.liveEl&&(this.liveEl.textContent=e)}paintOverlay(){let e=this.canvas,t=this.layer;!e||!t||lt({layer:t,canvas:e,resolveCtx:()=>{if(this.ctx===void 0)try{this.ctx=e.getContext("2d")}catch{this.ctx=null}return this.ctx},host:this.host,view:this.view,previewProjection:this.previewProjection,allocation:this.allocation,focusedSectionId:this.focusedSectionId,list:this.list,markerFor:s=>this.markerFor(s),onSectionTargetClick:s=>{this.focusedSectionId=s,this.host.focusSection(s),this.paintRail()}})}setStaged(e,t=""){let s=this.stagedEl;if(s){if(!e){s.classList.remove("on","done","shake"),s.innerHTML="";return}s.innerHTML=e,s.className=`slm-ch-staged on${t?` ${t}`:""}`}}paintStagedBar(){if(!this.active||this.view==="preview"||!this.caps.manage){this.setStaged(null);return}let{labels:e,buckets:t}=this.currentPlan();if(this.host.onStagedChange?.(K(t)),!e.length){this.setStaged(null);return}let s=this.nameOf(this.targetChannelId)??T,n=K(t),i=e.length>A,a=t.skippedHeld.count+t.skippedBooked.count,o=[`<b>${e.length.toLocaleString()}</b> selected`,`<b>+${n.toLocaleString()}</b> to ${h(s)}`];t.alreadyInTarget.count&&o.push(`<b>${t.alreadyInTarget.count.toLocaleString()}</b> already in`),a&&o.push(`<b>${a.toLocaleString()}</b> can't move now`),this.setStaged(`
261
+ <span>${o.join(" \xB7 ")}</span>
250
262
  <span class="grow"></span>
251
263
  <button type="button" class="drop" data-ch-act="discard">Discard</button>
252
264
  <button type="button" class="go" data-ch-act="review"${i?" disabled":""}>
253
265
  ${i?`Maximum ${A.toLocaleString()} seats`:"Review changes"}
254
266
  </button>`),this.stagedEl?.querySelectorAll("[data-ch-act]").forEach(r=>{r.addEventListener("click",()=>{r.dataset.chAct==="discard"?this.host.clearSelection():this.openDialog({kind:"review"})})})}setBanner(e,t="",s){let n=this.bannerEl;if(!n)return;if(this.host.root.classList.toggle("ch-preview",e),!e){n.classList.remove("on"),n.innerHTML="";return}let i=this.previewAudience.length===1?this.markerFor(this.previewAudience[0]):{color:"var(--slm-accent)",letter:""},a=s==null?"":` \xB7 ${s.toLocaleString()} ${s===1?"seat":"seats"} available now`;n.innerHTML=`<span class="dot" style="background:${h(i.color)}"></span>
255
267
  Previewing buyer access \xB7 ${h(t)}${a} \xB7 read-only
256
- <button type="button" data-ch-act="exit-preview">Exit preview</button>`,n.classList.add("on"),n.querySelector('[data-ch-act="exit-preview"]')?.addEventListener("click",()=>this.setView("inspect"))}setView(e){if(this.view=e,e==="inspect")this.previewProjection=null,this.previewState="idle",this.setBanner(!1);else{if(!this.previewAudience.length){let t=this.list?.channels.find(s=>s.state==="active");this.previewAudience=[t?t.id:C]}this.loadPreview()}this.paintRail(),this.paintOverlay(),this.paintStagedBar(),this.onInteractionChange?.()}async loadPreview(){let e=[...this.previewAudience],t=e.map(s=>this.nameOf(s)??T).join(" + ");this.setBanner(!0,t),this.previewProjection=null,this.previewState="loading",this.active&&this.paintRail();try{this.previewProjection=await this.host.api.channelPreview(this.host.eventKey,e,{includePublic:this.previewIncludePublic||e.some(B)}),this.previewState="ready";let s=this.previewProjection.available===!1?void 0:this.previewProjection.counts?.eligible??this.previewProjection.eligible?.length;this.setBanner(!0,t,s)}catch(s){let n=s instanceof f?s.status:0;this.previewState=n===404||n===405||n===501?"unsupported":"error",this.previewProjection=null,this.previewState==="error"&&this.host.onError(s)}this.active&&(this.paintRail(),this.paintOverlay())}setRailHtml(e){if(e===this.railHtml)return!1;let t=this.host.rail,s=t.scrollTop;return t.innerHTML=e,this.railHtml=e,s&&(t.scrollTop=s),!0}paintRail(){if(!this.active)return;let e=this.host.rail;if(!this.caps.view){this.setRailHtml(`<p class="slm-eyebrow">Sales channels</p>
268
+ <button type="button" data-ch-act="exit-preview">Exit preview</button>`,n.classList.add("on"),n.querySelector('[data-ch-act="exit-preview"]')?.addEventListener("click",()=>this.setView("inspect"))}setView(e){if(this.view=e,e==="inspect")this.previewProjection=null,this.previewState="idle",this.setBanner(!1);else{if(!this.previewAudience.length){let t=this.list?.channels.find(s=>s.state==="active");this.previewAudience=[t?t.id:C]}this.loadPreview()}this.paintRail(),this.paintOverlay(),this.paintStagedBar(),this.onInteractionChange?.()}async loadPreview(){let e=[...this.previewAudience],t=e.map(s=>this.nameOf(s)??T).join(" + ");this.setBanner(!0,t),this.previewProjection=null,this.previewState="loading",this.active&&this.paintRail();try{this.previewProjection=await this.host.api.channelPreview(this.host.eventKey,e,{includePublic:this.previewIncludePublic||e.some(P)}),this.previewState="ready";let s=this.previewProjection.available===!1?void 0:this.previewProjection.counts?.eligible??this.previewProjection.eligible?.length;this.setBanner(!0,t,s)}catch(s){let n=s instanceof f?s.status:0;this.previewState=n===404||n===405||n===501?"unsupported":"error",this.previewProjection=null,this.previewState==="error"&&this.host.onError(s)}this.active&&(this.paintRail(),this.paintOverlay())}setRailHtml(e){if(e===this.railHtml)return!1;let t=this.host.rail,s=t.scrollTop;return t.innerHTML=e,this.railHtml=e,s&&(t.scrollTop=s),!0}paintRail(){if(!this.active)return;let e=this.host.rail;if(!this.caps.view){this.setRailHtml(`<p class="slm-eyebrow">Sales channels</p>
257
269
  <p class="slm-hint">You need channel-management permission on this event to see allocations.</p>`);return}if(this.loading&&!this.list){this.setRailHtml(`<p class="slm-eyebrow">Sales channels</p>
258
270
  <div class="slm-ch-busy" role="status" data-ch-state="list-loading">Loading channels and allocations\u2026</div>`);return}if(!this.list&&this.loadError){this.setRailHtml(`<p class="slm-eyebrow">Sales channels</p>
259
271
  <div class="slm-ch-alert err" role="alert" data-ch-state="list-error"><span>\u26A0</span>
@@ -272,29 +284,29 @@
272
284
  <div class="slm-ch-mapnav-head"><span>${e?`Viewing ${h(e)}`:"Section overview"}</span>
273
285
  <button type="button" data-ch-act="sections">All sections</button></div>
274
286
  ${n}
275
- </div>`}countsHtml(e,t){let s=(n,i,a,l="")=>{let r=this.lastCounts.get(`${t}:${n}`),d=r!=null&&r!==i?" bump":"";return this.lastCounts.set(`${t}:${n}`,i),`<span class="${l}"><b class="${d.trim()}">${i.toLocaleString()}</b> ${a}</span>`};return`<span class="slm-ch-counts">
287
+ </div>`}countsHtml(e,t){let s=(n,i,a,o="")=>{let r=this.lastCounts.get(`${t}:${n}`),d=r!=null&&r!==i?" bump":"";return this.lastCounts.set(`${t}:${n}`,i),`<span class="${o}"><b class="${d.trim()}">${i.toLocaleString()}</b> ${a}</span>`};return`<span class="slm-ch-counts">
276
288
  ${s("allocated",e.allocated,"allocated")}
277
289
  ${s("free",e.free,"free","free")}
278
290
  ${s("booked",e.booked,"sold")}
279
291
  ${e.held?s("held",e.held,"held"):""}
280
- </span>`}channelRowHtml(e,t={}){let s=this.markerFor(e.id),n=t.builtin?"builtin":e.state,i=e.state==="paused"||e.state==="archived"?" dim":"",a=!t.builtin&&this.caps.manage&&this.detailChannelId!==e.id,l=`slm-ch-row${t.builtin?" public":""}${e.state==="archived"?" archived":""}${this.detailChannelId===e.id?" on":""}${a?" open":""}`,r=!t.builtin&&this.caps.manage?`<button type="button" class="slm-ch-more" data-ch-menu="${h(e.id)}"
292
+ </span>`}channelRowHtml(e,t={}){let s=this.markerFor(e.id),n=t.builtin?"builtin":e.state,i=e.state==="paused"||e.state==="archived"?" dim":"",a=!t.builtin&&this.caps.manage&&this.detailChannelId!==e.id,o=`slm-ch-row${t.builtin?" public":""}${e.state==="archived"?" archived":""}${this.detailChannelId===e.id?" on":""}${a?" open":""}`,r=!t.builtin&&this.caps.manage?`<button type="button" class="slm-ch-more" data-ch-menu="${h(e.id)}"
281
293
  aria-label="More actions for ${h(e.name)}" aria-haspopup="dialog">\u22EF</button>`:"",d=a?` role="button" tabindex="0" data-ch-open="${h(e.id)}"
282
- aria-label="Open ${h(e.name)}"`:"";return`<div class="${l}"${d}>
294
+ aria-label="Open ${h(e.name)}"`:"";return`<div class="${o}"${d}>
283
295
  <span class="slm-ch-head">
284
296
  <span class="slm-ch-mk${i}" style="background:${h(s.color)}" aria-hidden="true">${h(s.letter)}</span>
285
297
  <span class="slm-ch-name">${h(e.name)}</span>
286
- <span class="slm-ch-badge ${n}">${h(Se(t.builtin?"builtin":e.state))}</span>
298
+ <span class="slm-ch-badge ${n}">${h(xe(t.builtin?"builtin":e.state))}</span>
287
299
  ${r}
288
300
  </span>
289
301
  ${this.countsHtml(e.counts,e.id||"public")}
290
302
  ${t.builtin?"":`<span class="slm-ch-access">${h(fe(e.access))}</span>`}
291
- </div>`}listRailHtml(){let e=this.list,t=e.channels.filter(r=>r.state==="archived").length,s=e.channels.filter(r=>this.showArchived||r.state!=="archived"),n=[this.channelRowHtml(e.publicSale,{builtin:!0}),...s.map((r,d)=>this.channelRowHtml(r,{index:d}))].join(""),i=s.length?"":`<p class="slm-note" data-ch-state="list-empty">${t&&!this.showArchived?`No open channels \u2014 every seat is on public sale. ${t.toLocaleString()} archived channel${t===1?" is":"s are"} hidden below.`:"No private channels yet \u2014 every seat is on public sale."}</p>`,a=this.caps.manage?'<button type="button" class="slm-btn ghost" style="width:100%" data-ch-act="create">+ Create channel</button>':"",l=this.caps.manage?"":'<p class="slm-note">You can see how inventory is allocated. Changing it needs channel-management permission.</p>';return`
303
+ </div>`}listRailHtml(){let e=this.list,t=e.channels.filter(r=>r.state==="archived").length,s=e.channels.filter(r=>this.showArchived||r.state!=="archived"),n=[this.channelRowHtml(e.publicSale,{builtin:!0}),...s.map((r,d)=>this.channelRowHtml(r,{index:d}))].join(""),i=s.length?"":`<p class="slm-note" data-ch-state="list-empty">${t&&!this.showArchived?`No open channels \u2014 every seat is on public sale. ${t.toLocaleString()} archived channel${t===1?" is":"s are"} hidden below.`:"No private channels yet \u2014 every seat is on public sale."}</p>`,a=this.caps.manage?'<button type="button" class="slm-btn ghost" style="width:100%" data-ch-act="create">+ Create channel</button>':"",o=this.caps.manage?"":'<p class="slm-note">You can see how inventory is allocated. Changing it needs channel-management permission.</p>';return`
292
304
  <p class="slm-eyebrow">Sales channels</p>
293
305
  <p class="slm-hint">Channel colours and names are only visible to organizers, never to buyers.</p>
294
306
  <div class="slm-ch-list">${n}</div>
295
307
  ${i}
296
308
  ${a}
297
- ${l}
309
+ ${o}
298
310
  ${this.assignEntryHtml()}
299
311
  <p class="slm-note" style="margin-top:10px">
300
312
  <button type="button" class="slm-linkbtn" data-ch-act="toggle-archived" aria-pressed="${this.showArchived}"
@@ -303,7 +315,7 @@
303
315
  <button type="button" class="slm-btn ghost" style="width:100%;margin-top:8px"
304
316
  data-ch-act="assign-open" aria-expanded="false">Assign seats to a channel</button>
305
317
  <p class="slm-note">Move whole sections, rows, a dragged area or single seats out of public sale
306
- and into a channel. Nothing moves until you review and apply.</p>`:""}assignmentToolsHtml(e={}){let t=this.assignableChannels().map(l=>`<option value="${h(l.id)}"${l.id===this.targetChannelId?" selected":""}>${h(l.name)}</option>`).join(""),s=this.host.sections().length?'<button type="button" class="slm-btn ghost" data-ch-act="pick-sections">Sections</button>':"",n=this.assignmentRows().length?'<button type="button" class="slm-btn ghost" data-ch-act="pick-rows">Rows</button>':"",i=this.mapIntent==="assign"?"slm-btn":"slm-btn ghost";return`
318
+ and into a channel. Nothing moves until you review and apply.</p>`:""}assignmentToolsHtml(e={}){let t=this.assignableChannels().map(o=>`<option value="${h(o.id)}"${o.id===this.targetChannelId?" selected":""}>${h(o.name)}</option>`).join(""),s=this.host.sections().length?'<button type="button" class="slm-btn ghost" data-ch-act="pick-sections">Sections</button>':"",n=this.assignmentRows().length?'<button type="button" class="slm-btn ghost" data-ch-act="pick-rows">Rows</button>':"",i=this.mapIntent==="assign"?"slm-btn":"slm-btn ghost";return`
307
319
  <p class="slm-eyebrow">${e.collapsible?`<button type="button" class="slm-linkbtn" data-ch-act="assign-close"
308
320
  aria-expanded="true" style="float:right;font-weight:800">Done</button>`:""}Assign inventory</p>
309
321
  <div class="slm-field">
@@ -323,9 +335,9 @@
323
335
  multiple rows, a dragged area, or individual seats.</p>`}selectionRailHtml(e){let t=ue(e,this.allocation,this.list),s=this.conflict?`<div class="slm-ch-alert err" role="alert"><span>\u26A0</span>
324
336
  <span><b>Assignments changed while you were editing.</b> Nothing was applied.
325
337
  Your ${e.length.toLocaleString()}-seat selection is kept.
326
- <button type="button" data-ch-act="refresh-review">Refresh and review \u2192</button></span></div>`:"",n=e.length!==this.lastSelectionCount?" bump":"";this.lastSelectionCount=e.length;let i=e.length>A,a=t.map(l=>{let r=this.markerFor(l.channelId);return`<div class="slm-ch-selsrc-row">
338
+ <button type="button" data-ch-act="refresh-review">Refresh and review \u2192</button></span></div>`:"",n=e.length!==this.lastSelectionCount?" bump":"";this.lastSelectionCount=e.length;let i=e.length>A,a=t.map(o=>{let r=this.markerFor(o.channelId);return`<div class="slm-ch-selsrc-row">
327
339
  <span class="mk" style="background:${h(r.color)}" aria-hidden="true">${h(r.letter)}</span>
328
- <b>${l.count.toLocaleString()}</b><span>${h(l.name)}</span></div>`}).join("");return`
340
+ <b>${o.count.toLocaleString()}</b><span>${h(o.name)}</span></div>`}).join("");return`
329
341
  ${s}
330
342
  ${this.assignmentToolsHtml()}
331
343
  <div class="slm-selbar"><span class="slm-selnum slm-ch-selnum${n}">${e.length.toLocaleString()}</span>
@@ -342,7 +354,7 @@
342
354
  </div>
343
355
  <p class="slm-note">The seat list offers the same selection with checkboxes for keyboard and screen-reader use.</p>`}detailRailHtml(e){let t=`<p class="slm-eyebrow">
344
356
  <button type="button" class="slm-linkbtn" data-ch-act="back" style="text-align:left">\u2039 All channels</button>
345
- </p>`,s=this.list?.channels.find(a=>a.id===e);if(!s)return`${t}
357
+ </p>`,s=this.list?.channels.find(r=>r.id===e);if(!s)return`${t}
346
358
  <div class="slm-ch-alert warn" role="status" data-ch-state="detail-gone"><span>\u2139</span>
347
359
  <span><b>This channel is no longer on this event.</b> It was archived or removed while you had it open.
348
360
  ${this.showArchived?"":"Archived channels are hidden \u2014 use \u201CShow archived\u201D on the list to see it."}</span></div>`;let n=this.caps.manage?`
@@ -352,23 +364,30 @@
352
364
  <button type="button" class="slm-btn ghost" data-ch-act="pause">${s.state==="paused"?"Resume":"Pause"}</button>
353
365
  <button type="button" class="slm-btn ghost" data-ch-act="archive">Archive\u2026</button>
354
366
  </div>
355
- <p class="slm-note">Archive returns the allocation to a destination you choose. Nothing is ever deleted silently.</p>`:"",i=this.caps.manage?this.distributeHtml(s):"";return`
367
+ <p class="slm-note">Archive returns the allocation to a destination you choose. Nothing is ever deleted silently.</p>`:"",i=this.caps.manage?this.distributeHtml(s):"",a=s.priceOverrides?.length??0,o=this.caps.manage&&this.host.api.updateChannelPricing?`
368
+ <p class="slm-eyebrow" style="margin-top:14px">Prices</p>
369
+ <div class="slm-ch-price-summary">
370
+ <span>${a?`${a.toLocaleString()} custom price${a===1?"":"s"} override the event price for this channel.`:"This channel uses the event prices."}</span>
371
+ <button type="button" class="slm-btn ghost" data-ch-act="pricing">Edit prices</button>
372
+ </div>
373
+ <p class="slm-note">Only buyers admitted to this channel see and pay these prices. Existing holds keep the price already promised.</p>`:"";return`
356
374
  ${t}
357
375
  <p class="slm-eyebrow">Channel \xB7 ${h(s.name)}</p>
358
376
  <div class="slm-ch-list">${this.channelRowHtml(s)}</div>
377
+ ${o}
359
378
  ${i}
360
- ${n}`}distributeHtml(e){let t=e.access?.intent??"none",s=e.access?.hasActiveGrants===!0,n=this.linksState!=="unsupported",i=this.links.some(te),a=t==="none"?"Protected reserve \u2014 no route can sell these seats. Every buyer path is refused.":t==="internal"?"Your staff sell these seats. No buyer-facing route is open.":s?t==="server"?"Your website is letting buyers in. Only they can buy these seats.":"A buyer link is live. Only people with that link can buy these seats.":t==="server"?"Set up for your website \u2014 no buyer has come through yet. Seats stay reserved.":"Set up for buyer links \u2014 no buyer has come through yet. Seats stay reserved.",l=(r,d,c,p)=>{let g=r===t;return`<div class="slm-ch-dist${g?" on":""}" data-ch-route="${h(r)}">
361
- <b>${h(z(r))}${g?'<span class="cur">Current route</span>':""}</b>
379
+ ${n}`}distributeHtml(e){let t=e.access?.intent??"none",s=e.access?.hasActiveGrants===!0,n=this.linksState!=="unsupported",i=this.links.some(te),a=t==="none"?"Protected reserve \u2014 no route can sell these seats. Every buyer path is refused.":t==="internal"?"Your staff sell these seats. No buyer-facing route is open.":s?t==="server"?"Your website is letting buyers in. Only they can buy these seats.":"A buyer link is live. Only people with that link can buy these seats.":t==="server"?"Set up for your website \u2014 no buyer has come through yet. Seats stay reserved.":"Set up for buyer links \u2014 no buyer has come through yet. Seats stay reserved.",o=(r,d,c,p)=>{let b=r===t;return`<div class="slm-ch-dist${b?" on":""}" data-ch-route="${h(r)}">
380
+ <b>${h(z(r))}${b?'<span class="cur">Current route</span>':""}</b>
362
381
  <span class="why">${h(ye(r))}</span>
363
- ${g&&!c?"":`<button type="button" class="slm-btn${p&&!g?"":" ghost"}"
382
+ ${b&&!c?"":`<button type="button" class="slm-btn${p&&!b?"":" ghost"}"
364
383
  data-ch-act="${h(d)}">${h(c)}</button>`}
365
384
  </div>`};return`
366
385
  <p class="slm-eyebrow" style="margin-top:14px">Distribute</p>
367
386
  <p class="slm-hint">${h(a)}</p>
368
- ${n?l("hosted_link","link-create",i?"Create another buyer link":"Create buyer link",!0):""}
369
- ${l("server","embed-code",t==="server"?"Get embed code":"Use a website or app",!1)}
370
- ${l("internal","route-internal",t==="internal"?"":"Hand to your staff",!1)}
371
- ${l("none","route-none",t==="none"?"":"Keep as reserve",!1)}
387
+ ${n?o("hosted_link","link-create",i?"Create another buyer link":"Create buyer link",!0):""}
388
+ ${o("server","embed-code",t==="server"?"Get embed code":"Use a website or app",!1)}
389
+ ${o("internal","route-internal",t==="internal"?"":"Hand to your staff",!1)}
390
+ ${o("none","route-none",t==="none"?"":"Keep as reserve",!1)}
372
391
  ${this.hostedLinksHtml()}
373
392
  ${t==="server"?at:""}`}async loadLinks(e){if(!this.caps.view)return;let t=++this.linksSeq,s=()=>t!==this.linksSeq||this.linksChannelId!==e;this.linksChannelId!==e&&(this.links=[],this.linksChannelId=e,this.linksState="loading");try{let n=await this.host.api.accessLinks(this.host.eventKey,e);if(s())return;this.links=n.links??[],this.linksState="ready"}catch(n){if(s())return;let i=n instanceof f?n.status:0;this.links=[],this.linksState=i===404||i===405||i===501?"unsupported":"error",this.linksState==="error"&&this.host.onError(n)}}hostedLinksHtml(){let e='<p class="slm-eyebrow" style="margin-top:18px">Buyer links</p>';return this.linksState==="unsupported"?`${e}<div class="slm-ch-alert warn" data-ch-state="links-unsupported"><span>\u2139</span>
374
393
  <span><b>Buyer links need a newer server.</b> Everything else on this channel works normally.</span></div>`:this.linksState==="error"?`${e}<div class="slm-ch-alert err" role="alert" data-ch-state="links-error"><span>\u26A0</span>
@@ -380,7 +399,7 @@
380
399
  can never be shown again \u2014 if a link is lost, rotate it and send the fresh one.</p>`:""}linkCardHtml(e){let t=we(e),s=e.maxRedemptions>0?Math.min(100,Math.round(e.redemptions/e.maxRedemptions*100)):0,n=se(e).map(r=>`<div class="slm-ch-lkrow"><span class="k">${h(r.k)}</span>
381
400
  <span class="v">${h(r.v)}</span></div>`).join(""),i=e.activeSessions?`<div class="slm-ch-lkrow"><span class="k">Buyers inside now</span>
382
401
  <span class="v">${e.activeSessions.toLocaleString()}</span></div>`:"",a=e.lastRedeemedAt?`<div class="slm-ch-lkrow"><span class="k">Last opened</span>
383
- <span class="v">${h(new Date(e.lastRedeemedAt).toLocaleString())}</span></div>`:"",l=this.caps.manage&&te(e)?`<div class="slm-ch-row2">
402
+ <span class="v">${h(new Date(e.lastRedeemedAt).toLocaleString())}</span></div>`:"",o=this.caps.manage&&te(e)?`<div class="slm-ch-row2">
384
403
  <button type="button" class="slm-btn ghost" data-ch-rotate="${h(e.id)}">Rotate</button>
385
404
  <button type="button" class="slm-btn ghost" data-ch-revoke="${h(e.id)}">Revoke</button>
386
405
  </div>`:"";return`<div class="slm-ch-link">
@@ -394,16 +413,16 @@
394
413
  ${n}${i}${a}
395
414
  <div class="slm-ch-lkrow"><span class="k">The URL</span>
396
415
  <span class="v">Revealed once at creation \u2014 not recoverable</span></div>
397
- ${l}
416
+ ${o}
398
417
  </div>`}previewRailHtml(){let e=[{id:C,name:this.list?.publicSale.name??T},...(this.list?.channels??[]).filter(p=>p.state!=="archived").map(p=>({id:p.id,name:p.name}))],t=this.previewAudience[0]??C,s=e.map(p=>`<option value="${h(p.id)}"${p.id===t?" selected":""}>${h(p.name)}</option>`).join(""),n=this.previewState==="unsupported"?`<div class="slm-ch-alert warn" data-ch-state="preview-unsupported"><span>\u2139</span>
399
418
  <span><b>Preview needs a newer server.</b> Allocation management works normally;
400
419
  the buyer-view simulation will appear once this event's API is updated.</span></div>`:"",i=this.previewState==="loading"?'<div class="slm-ch-busy" role="status" data-ch-state="preview-loading">Asking the server what this audience sees\u2026</div>':"",a=this.previewState==="error"?`<div class="slm-ch-alert err" role="alert" data-ch-state="preview-error"><span>\u26A0</span>
401
420
  <span><b>Couldn't load the buyer preview.</b> Nothing is wrong with this audience's seats \u2014
402
421
  the simulation itself failed to load.
403
- <button type="button" data-ch-act="preview-retry">Try again</button></span></div>`:"",l=this.previewProjection?.available===!1?`<div class="slm-ch-alert warn" role="status"><span>\u23F8</span>
422
+ <button type="button" data-ch-act="preview-retry">Try again</button></span></div>`:"",o=this.previewProjection?.available===!1?`<div class="slm-ch-alert warn" role="status"><span>\u23F8</span>
404
423
  <span><b>This private sale is not available.</b> ${h((this.previewProjection.unavailable??[]).map(p=>`${this.nameOf(p.channelId)??"This channel"} is ${p.state}`).join("; ")||"The audience cannot buy right now")}.
405
424
  A buyer arriving with this access sees this message, not these seats.</span></div>`:"",r=this.previewProjection?.counts?.eligible??this.previewProjection?.eligible?.length,d=r!=null&&this.previewProjection?.available!==!1?`<div class="slm-ch-alert info"><span>\u2713</span><span><b>${r.toLocaleString()} ${r===1?"seat is":"seats are"} available now.</b>
406
- This is the exact buyer-visible allocation.${this.previewProjection?.includePublic===!1?" Public sale seats are <b>not</b> included in this access.":""}</span></div>`:"",c=B(t)?"":`
425
+ This is the exact buyer-visible allocation.${this.previewProjection?.includePublic===!1?" Public sale seats are <b>not</b> included in this access.":""}</span></div>`:"",c=P(t)?"":`
407
426
  <label class="slm-note" style="display:flex;gap:8px;align-items:center;margin:10px 0">
408
427
  <input type="checkbox" data-ch-includepublic ${this.previewIncludePublic?"checked":""} />
409
428
  Also include Public sale seats in this grant
@@ -416,13 +435,13 @@
416
435
  ${c}
417
436
  <p class="slm-hint">This is the same projection the buyer SDK receives for this audience \u2014 not a local
418
437
  approximation. It is read-only: clicks open seat details, and no holds are created.</p>
419
- ${i}${a}${n}${l}
438
+ ${i}${a}${n}${o}
420
439
  <div class="slm-ch-legend">
421
440
  <div class="r"><span class="sw" style="background:#6e7bff"></span> Eligible &amp; free \u2014 buyable by this audience</div>
422
441
  <div class="r"><span class="sw" style="background:#3a4051"></span> Unavailable to this audience (one neutral state)</div>
423
442
  <div class="r"><span class="sw" style="background:#22a06b"></span> Sold \u2014 same as any buyer sees</div>
424
443
  </div>
425
- ${d}`}paintSelection(){this.caps.manage&&this.host.selectionLabels().length&&(this.assignOpen=!0),this.view==="inspect"&&!this.detailChannelId&&this.paintRail()}wireRail(){let e=this.host.rail;e.querySelectorAll("[data-ch-view]").forEach(a=>{a.addEventListener("click",()=>this.setView(a.dataset.chView))}),e.querySelectorAll("[data-ch-map]").forEach(a=>{a.addEventListener("click",()=>{this.mapIntent=a.dataset.chMap==="assign"?"assign":"pan",this.mapIntent==="assign"&&(this.assignOpen=!0),this.paintRail(),this.onInteractionChange?.()})}),e.querySelectorAll("[data-ch-open]").forEach(a=>{let l=()=>this.openChannel(a.dataset.chOpen);a.addEventListener("click",l),a.addEventListener("keydown",r=>{r.key!=="Enter"&&r.key!==" "&&r.key!=="Spacebar"||(r.preventDefault(),l())})}),e.querySelectorAll("[data-ch-menu]").forEach(a=>{a.addEventListener("click",l=>{l.stopPropagation(),this.openDialog({kind:"menu",channelId:a.dataset.chMenu})}),a.addEventListener("keydown",l=>{l.stopPropagation()})}),e.querySelectorAll("[data-ch-rotate]").forEach(a=>{a.addEventListener("click",()=>this.openDialog({kind:"linkRotate",channelId:this.detailChannelId,linkId:a.dataset.chRotate}))}),e.querySelectorAll("[data-ch-revoke]").forEach(a=>{a.addEventListener("click",()=>this.openDialog({kind:"linkRevoke",channelId:this.detailChannelId,linkId:a.dataset.chRevoke}))});let t=e.querySelector("[data-ch-target]");t?.addEventListener("change",()=>{this.targetChannelId=t.value,this.conflict=!1,this.paintRail()});let s=e.querySelector("[data-ch-audience]");s?.addEventListener("change",()=>{this.previewAudience=[s.value],this.loadPreview()});let n=e.querySelector("[data-ch-includepublic]");n?.addEventListener("change",()=>{this.previewIncludePublic=n.checked,this.loadPreview()}),e.querySelector(".slm-ch-grab")?.addEventListener("click",()=>this.cycleDetent()),e.querySelectorAll("[data-ch-act]").forEach(a=>{a.addEventListener("click",()=>this.railAction(a.dataset.chAct))})}openChannel(e){this.detailChannelId=e,this.paintRail(),this.loadLinks(e).then(()=>this.paintRail())}railAction(e){switch(e){case"sections":this.focusedSectionId=null,this.host.showSectionOverview(),this.paintRail();break;case"create":this.openDialog({kind:"create"});break;case"review":this.openDialog({kind:"review"});break;case"rename":this.openDialog({kind:"rename",channelId:this.detailChannelId});break;case"archive":this.openDialog({kind:"archive",channelId:this.detailChannelId});break;case"seatlist":this.openDialog({kind:"seatlist"});break;case"pause":this.togglePause();break;case"discard":this.host.clearSelection();break;case"back":this.detailChannelId=null,this.linksChannelId=null,this.links=[],this.linksState="idle",this.paintRail();break;case"link-create":this.openDialog({kind:"linkCreate",channelId:this.detailChannelId});break;case"embed-code":this.chooseWebsiteIntegration();break;case"route-internal":this.setAccessIntent("internal");break;case"route-none":this.setAccessIntent("none");break;case"link-reload":this.detailChannelId&&this.reloadLinks();break;case"retry":this.refresh();break;case"toggle-archived":this.showArchived=!this.showArchived,this.refresh();break;case"refresh-review":this.conflict=!1,this.refresh().then(()=>this.openDialog({kind:"review"}));break;case"pick-sections":this.openDialog({kind:"scope",scope:"sections"});break;case"pick-rows":this.openDialog({kind:"scope",scope:"rows"});break;case"drag-select":this.mapIntent="assign",this.paintRail(),this.onInteractionChange?.();break;case"pick-category":this.pickCategory();break;case"assign-open":this.assignOpen=!0,this.paintRail();break;case"assign-close":this.assignOpen=!1,this.mapIntent="pan",this.paintRail(),this.onInteractionChange?.();break;case"preview-retry":this.loadPreview();break;default:break}}assignmentRows(){return this.assignmentRowsCache||(this.assignmentRowsCache=this.host.rows()),this.assignmentRowsCache}pickCategory(){let e=this.host.categories();e.length&&this.promptChoice("Select a whole category",e.map(t=>({value:t.key,label:t.label})),t=>{this.host.selectByLabels(this.host.labelsInCategory(t))})}promptChoice(e,t,s){this.renderScrim(`
444
+ ${d}`}paintSelection(){this.caps.manage&&this.host.selectionLabels().length&&(this.assignOpen=!0),this.view==="inspect"&&!this.detailChannelId&&this.paintRail()}wireRail(){let e=this.host.rail;e.querySelectorAll("[data-ch-view]").forEach(a=>{a.addEventListener("click",()=>this.setView(a.dataset.chView))}),e.querySelectorAll("[data-ch-map]").forEach(a=>{a.addEventListener("click",()=>{this.mapIntent=a.dataset.chMap==="assign"?"assign":"pan",this.mapIntent==="assign"&&(this.assignOpen=!0),this.paintRail(),this.onInteractionChange?.()})}),e.querySelectorAll("[data-ch-open]").forEach(a=>{let o=()=>this.openChannel(a.dataset.chOpen);a.addEventListener("click",o),a.addEventListener("keydown",r=>{r.key!=="Enter"&&r.key!==" "&&r.key!=="Spacebar"||(r.preventDefault(),o())})}),e.querySelectorAll("[data-ch-menu]").forEach(a=>{a.addEventListener("click",o=>{o.stopPropagation(),this.openDialog({kind:"menu",channelId:a.dataset.chMenu})}),a.addEventListener("keydown",o=>{o.stopPropagation()})}),e.querySelectorAll("[data-ch-rotate]").forEach(a=>{a.addEventListener("click",()=>this.openDialog({kind:"linkRotate",channelId:this.detailChannelId,linkId:a.dataset.chRotate}))}),e.querySelectorAll("[data-ch-revoke]").forEach(a=>{a.addEventListener("click",()=>this.openDialog({kind:"linkRevoke",channelId:this.detailChannelId,linkId:a.dataset.chRevoke}))});let t=e.querySelector("[data-ch-target]");t?.addEventListener("change",()=>{this.targetChannelId=t.value,this.conflict=!1,this.paintRail()});let s=e.querySelector("[data-ch-audience]");s?.addEventListener("change",()=>{this.previewAudience=[s.value],this.loadPreview()});let n=e.querySelector("[data-ch-includepublic]");n?.addEventListener("change",()=>{this.previewIncludePublic=n.checked,this.loadPreview()}),e.querySelector(".slm-ch-grab")?.addEventListener("click",()=>this.cycleDetent()),e.querySelectorAll("[data-ch-act]").forEach(a=>{a.addEventListener("click",()=>this.railAction(a.dataset.chAct))})}openChannel(e){this.detailChannelId=e,this.paintRail(),this.loadLinks(e).then(()=>this.paintRail())}railAction(e){switch(e){case"sections":this.focusedSectionId=null,this.host.showSectionOverview(),this.paintRail();break;case"create":this.openDialog({kind:"create"});break;case"review":this.openDialog({kind:"review"});break;case"rename":this.openDialog({kind:"rename",channelId:this.detailChannelId});break;case"pricing":this.openDialog({kind:"pricing",channelId:this.detailChannelId});break;case"archive":this.openDialog({kind:"archive",channelId:this.detailChannelId});break;case"seatlist":this.openDialog({kind:"seatlist"});break;case"pause":this.togglePause();break;case"discard":this.host.clearSelection();break;case"back":this.detailChannelId=null,this.linksChannelId=null,this.links=[],this.linksState="idle",this.paintRail();break;case"link-create":this.openDialog({kind:"linkCreate",channelId:this.detailChannelId});break;case"embed-code":this.chooseWebsiteIntegration();break;case"route-internal":this.setAccessIntent("internal");break;case"route-none":this.setAccessIntent("none");break;case"link-reload":this.detailChannelId&&this.reloadLinks();break;case"retry":this.refresh();break;case"toggle-archived":this.showArchived=!this.showArchived,this.refresh();break;case"refresh-review":this.conflict=!1,this.refresh().then(()=>this.openDialog({kind:"review"}));break;case"pick-sections":this.openDialog({kind:"scope",scope:"sections"});break;case"pick-rows":this.openDialog({kind:"scope",scope:"rows"});break;case"drag-select":this.mapIntent="assign",this.paintRail(),this.onInteractionChange?.();break;case"pick-category":this.pickCategory();break;case"assign-open":this.assignOpen=!0,this.paintRail();break;case"assign-close":this.assignOpen=!1,this.mapIntent="pan",this.paintRail(),this.onInteractionChange?.();break;case"preview-retry":this.loadPreview();break;default:break}}assignmentRows(){return this.assignmentRowsCache||(this.assignmentRowsCache=this.host.rows()),this.assignmentRowsCache}pickCategory(){let e=this.host.categories();e.length&&this.promptChoice("Select a whole category",e.map(t=>({value:t.key,label:t.label})),t=>{this.host.selectByLabels(this.host.labelsInCategory(t))})}promptChoice(e,t,s){this.renderScrim(`
426
445
  <h3 id="slm-ch-dlg-title">${h(e)}</h3>
427
446
  <div class="slm-field">
428
447
  <label for="slm-ch-choice">Choose one</label>
@@ -433,7 +452,7 @@
433
452
  <div class="foot">
434
453
  <button type="button" class="quiet" data-ch-close>Cancel</button>
435
454
  <button type="button" class="slm-btn" data-ch-confirm>Select</button>
436
- </div>`,n=>{n.querySelector("[data-ch-confirm]")?.addEventListener("click",()=>{let a=n.querySelector("#slm-ch-choice")?.value;this.closeDialog(),a&&s(a)})})}renderScopeDialog(e){let t=e.scope==="rows"?"rows":"sections",n=(t==="sections"?this.host.sections().map(l=>({id:l.id,label:l.label,group:"Sections",labels:this.host.labelsInSection(l.id)})):this.assignmentRows().map(l=>({id:l.id,label:l.label,group:l.sectionLabel,labels:l.labels}))).filter(l=>l.labels.length>0),i=new Map;for(let l of n){let r=i.get(l.group)??[];r.push(l),i.set(l.group,r)}if(t==="rows"){let l=[...i.entries()];this.renderScrim(`
455
+ </div>`,n=>{n.querySelector("[data-ch-confirm]")?.addEventListener("click",()=>{let a=n.querySelector("#slm-ch-choice")?.value;this.closeDialog(),a&&s(a)})})}renderScopeDialog(e){let t=e.scope==="rows"?"rows":"sections",n=(t==="sections"?this.host.sections().map(o=>({id:o.id,label:o.label,group:"Sections",labels:this.host.labelsInSection(o.id)})):this.assignmentRows().map(o=>({id:o.id,label:o.label,group:o.sectionLabel,labels:o.labels}))).filter(o=>o.labels.length>0),i=new Map;for(let o of n){let r=i.get(o.group)??[];r.push(o),i.set(o.group,r)}if(t==="rows"){let o=[...i.entries()];this.renderScrim(`
437
456
  <h3 id="slm-ch-dlg-title">Add multiple rows</h3>
438
457
  <p class="sub">Sections stay collapsed for speed. Select a whole section, expand only the rows you need, or search across every row.</p>
439
458
  <div class="slm-ch-scopebar">
@@ -446,7 +465,7 @@
446
465
  <div class="foot">
447
466
  <button type="button" class="quiet" data-ch-close>Cancel</button>
448
467
  <button type="button" class="slm-btn" data-ch-add-scope disabled>Add seats</button>
449
- </div>`,r=>{let d=new Map(n.map(y=>[y.id,y])),c=new Set,p=new Set,g=new Set(this.host.selectionLabels()),w=r.querySelector("[data-ch-add-scope]"),b=r.querySelector("[data-ch-error]"),m=r.querySelector("[data-ch-scope-list]"),v=r.querySelector("[data-ch-scope-search]"),P=r.querySelector("[data-ch-scope-summary]"),F=r.querySelector("[data-ch-scope-filter]"),q=200,E="",x=()=>{let y=new Set(g);for(let H of c)for(let D of d.get(H)?.labels??[])y.add(D);return y},S=()=>{let y=x(),H=y.size-g.size,D=y.size>A;w.disabled=H===0||D,w.textContent=D?`Maximum ${A.toLocaleString()} seats`:`Add ${H.toLocaleString()} seat${H===1?"":"s"}`,b.hidden=!D,b.textContent=D?`That would make ${y.size.toLocaleString()} selected seats. Choose fewer rows or sections.`:"",P.textContent=`${c.size.toLocaleString()} row${c.size===1?"":"s"} \xB7 ${H.toLocaleString()} seat${H===1?"":"s"} added`},k=()=>{let y=[],H=0,D=0;l.forEach(([M,R],G)=>{let j=M.toLocaleLowerCase(),V=E?R.filter(I=>`${j} ${I.label.toLocaleLowerCase()}`.includes(E)):R;if(E&&!V.length)return;H+=V.length;let Fe=R.every(I=>c.has(I.id)),mt=!Fe&&R.some(I=>c.has(I.id)),X=!!E||p.has(G),bt=Math.max(0,q-D),Q=X?V.slice(0,bt):[];D+=Q.length;let gt=R.reduce((I,vt)=>I+vt.labels.length,0);y.push(`<div class="slm-ch-scopegroup">
468
+ </div>`,r=>{let d=new Map(n.map(k=>[k.id,k])),c=new Set,p=new Set,b=new Set(this.host.selectionLabels()),y=r.querySelector("[data-ch-add-scope]"),g=r.querySelector("[data-ch-error]"),m=r.querySelector("[data-ch-scope-list]"),v=r.querySelector("[data-ch-scope-search]"),B=r.querySelector("[data-ch-scope-summary]"),F=r.querySelector("[data-ch-scope-filter]"),q=200,E="",S=()=>{let k=new Set(b);for(let H of c)for(let D of d.get(H)?.labels??[])k.add(D);return k},x=()=>{let k=S(),H=k.size-b.size,D=k.size>A;y.disabled=H===0||D,y.textContent=D?`Maximum ${A.toLocaleString()} seats`:`Add ${H.toLocaleString()} seat${H===1?"":"s"}`,g.hidden=!D,g.textContent=D?`That would make ${k.size.toLocaleString()} selected seats. Choose fewer rows or sections.`:"",B.textContent=`${c.size.toLocaleString()} row${c.size===1?"":"s"} \xB7 ${H.toLocaleString()} seat${H===1?"":"s"} added`},w=()=>{let k=[],H=0,D=0;o.forEach(([M,R],G)=>{let j=M.toLocaleLowerCase(),V=E?R.filter(I=>`${j} ${I.label.toLocaleLowerCase()}`.includes(E)):R;if(E&&!V.length)return;H+=V.length;let Fe=R.every(I=>c.has(I.id)),mt=!Fe&&R.some(I=>c.has(I.id)),X=!!E||p.has(G),bt=Math.max(0,q-D),Q=X?V.slice(0,bt):[];D+=Q.length;let gt=R.reduce((I,vt)=>I+vt.labels.length,0);k.push(`<div class="slm-ch-scopegroup">
450
469
  <button type="button" class="slm-ch-groupcheck" role="checkbox" aria-checked="${Fe?"true":mt?"mixed":"false"}"
451
470
  aria-label="Select all ${R.length.toLocaleString()} rows in ${h(M)}" data-ch-scope-group="${G}">
452
471
  <span class="box" aria-hidden="true">\u2713</span><span>${h(M)}</span>
@@ -454,13 +473,13 @@
454
473
  </button>
455
474
  <button type="button" class="slm-ch-grouptoggle" aria-expanded="${X}" aria-label="${X?"Hide":"Show"} rows in ${h(M)}"
456
475
  data-ch-scope-toggle="${G}">${X?"Hide":"Show"}</button>
457
- </div>`),y.push(...Q.map(I=>`<button type="button" class="slm-ch-seatitem" role="checkbox"
476
+ </div>`),k.push(...Q.map(I=>`<button type="button" class="slm-ch-seatitem" role="checkbox"
458
477
  aria-checked="${c.has(I.id)}" data-ch-scope-id="${h(I.id)}">
459
478
  <span class="box" aria-hidden="true">\u2713</span><span>${h(I.label)}</span>
460
479
  <span class="meta">${I.labels.length.toLocaleString()} seat${I.labels.length===1?"":"s"}</span>
461
- </button>`)),X&&V.length>Q.length&&y.push(`<p class="slm-ch-scopehint">${(V.length-Q.length).toLocaleString()} more row${V.length-Q.length===1?"":"s"}. Search to narrow the list.</p>`)}),m.innerHTML=y.join("")||(E?`<div class="slm-ch-scope-empty" data-ch-state="scope-nomatch">No sections or rows match \u201C${h(E)}\u201D.</div>`:`<div class="slm-ch-scope-empty" data-ch-state="scope-empty">This chart has no rows with selectable seats.
462
- Use Drag box or the seat list instead.</div>`),F.textContent=E?`Showing ${D.toLocaleString()} of ${H.toLocaleString()} matching rows. Section checkboxes still select every row in that section.`:"Showing section groups. Expand one or search to see rows.",m.querySelectorAll("[data-ch-scope-group]").forEach(M=>M.addEventListener("click",()=>{let R=l[Number(M.dataset.chScopeGroup)]?.[1]??[],G=R.every(j=>c.has(j.id));for(let j of R)G?c.delete(j.id):c.add(j.id);k(),S()})),m.querySelectorAll("[data-ch-scope-toggle]").forEach(M=>M.addEventListener("click",()=>{let R=Number(M.dataset.chScopeToggle);p.has(R)?p.delete(R):p.add(R),k()})),m.querySelectorAll("[data-ch-scope-id]").forEach(M=>M.addEventListener("click",()=>{let R=M.dataset.chScopeId;c.has(R)?c.delete(R):c.add(R),k(),S()}))};v.addEventListener("input",()=>{E=v.value.trim().toLocaleLowerCase(),k(),S()}),w.addEventListener("click",()=>{let y=[...x()];!c.size||y.length>A||(this.closeDialog(),this.host.selectByLabels(y))}),k(),S()});return}let a=[...i.entries()].map(([l,r])=>`
463
- <div class="slm-ch-seatgroup"><span>${h(l)}</span></div>
480
+ </button>`)),X&&V.length>Q.length&&k.push(`<p class="slm-ch-scopehint">${(V.length-Q.length).toLocaleString()} more row${V.length-Q.length===1?"":"s"}. Search to narrow the list.</p>`)}),m.innerHTML=k.join("")||(E?`<div class="slm-ch-scope-empty" data-ch-state="scope-nomatch">No sections or rows match \u201C${h(E)}\u201D.</div>`:`<div class="slm-ch-scope-empty" data-ch-state="scope-empty">This chart has no rows with selectable seats.
481
+ Use Drag box or the seat list instead.</div>`),F.textContent=E?`Showing ${D.toLocaleString()} of ${H.toLocaleString()} matching rows. Section checkboxes still select every row in that section.`:"Showing section groups. Expand one or search to see rows.",m.querySelectorAll("[data-ch-scope-group]").forEach(M=>M.addEventListener("click",()=>{let R=o[Number(M.dataset.chScopeGroup)]?.[1]??[],G=R.every(j=>c.has(j.id));for(let j of R)G?c.delete(j.id):c.add(j.id);w(),x()})),m.querySelectorAll("[data-ch-scope-toggle]").forEach(M=>M.addEventListener("click",()=>{let R=Number(M.dataset.chScopeToggle);p.has(R)?p.delete(R):p.add(R),w()})),m.querySelectorAll("[data-ch-scope-id]").forEach(M=>M.addEventListener("click",()=>{let R=M.dataset.chScopeId;c.has(R)?c.delete(R):c.add(R),w(),x()}))};v.addEventListener("input",()=>{E=v.value.trim().toLocaleLowerCase(),w(),x()}),y.addEventListener("click",()=>{let k=[...S()];!c.size||k.length>A||(this.closeDialog(),this.host.selectByLabels(k))}),w(),x()});return}let a=[...i.entries()].map(([o,r])=>`
482
+ <div class="slm-ch-seatgroup"><span>${h(o)}</span></div>
464
483
  ${r.map(d=>`<button type="button" class="slm-ch-seatitem" role="checkbox"
465
484
  aria-checked="false" data-ch-scope-id="${h(d.id)}">
466
485
  <span class="box" aria-hidden="true">\u2713</span>
@@ -475,7 +494,7 @@
475
494
  <div class="foot">
476
495
  <button type="button" class="quiet" data-ch-close>Cancel</button>
477
496
  <button type="button" class="slm-btn" data-ch-add-scope disabled>Add seats</button>
478
- </div>`,l=>{let r=new Map(n.map(m=>[m.id,m])),d=new Set,c=new Set(this.host.selectionLabels()),p=l.querySelector("[data-ch-add-scope]"),g=l.querySelector("[data-ch-error]"),w=()=>{let m=new Set(c);for(let v of d)for(let P of r.get(v)?.labels??[])m.add(P);return m},b=()=>{let m=w(),v=m.size-c.size,P=m.size>A;p.disabled=v===0||P,p.textContent=P?`Maximum ${A.toLocaleString()} seats`:`Add ${v.toLocaleString()} seat${v===1?"":"s"}`,g.hidden=!P,g.textContent=P?`That would make ${m.size.toLocaleString()} selected seats. Choose fewer rows or sections.`:""};l.querySelectorAll("[data-ch-scope-id]").forEach(m=>{m.addEventListener("click",()=>{let v=m.dataset.chScopeId;d.has(v)?d.delete(v):d.add(v),m.setAttribute("aria-checked",String(d.has(v))),b()})}),p.addEventListener("click",()=>{let m=[...w()];!d.size||m.length>A||(this.closeDialog(),this.host.selectByLabels(m))}),b()})}openDialog(e){this.dialog=e,this.renderDialog()}renderDialog(){let e=this.dialog;e&&(e.kind==="create"?this.renderCreateDialog(e):e.kind==="review"?this.renderReviewDialog(e):e.kind==="scope"?this.renderScopeDialog(e):e.kind==="archive"?this.renderArchiveDialog(e):e.kind==="rename"?this.renderRenameDialog(e):e.kind==="seatlist"?this.renderSeatListDialog():e.kind==="menu"?this.renderMenuDialog(e):e.kind==="linkCreate"?this.renderLinkCreateDialog(e):e.kind==="linkRotate"?this.renderLinkRotateDialog(e):e.kind==="linkRevoke"?this.renderLinkRevokeDialog(e):e.kind==="intentSwitch"&&this.renderIntentSwitchDialog(e))}renderIntentSwitchDialog(e){let t=this.list?.channels.find(a=>a.id===e.channelId),s=e.intentTo;if(!t||!s||!this.caps.manage){this.closeDialog();return}let{headline:n,consequences:i}=ke(e.switchBlocked);this.renderScrim(`
497
+ </div>`,o=>{let r=new Map(n.map(m=>[m.id,m])),d=new Set,c=new Set(this.host.selectionLabels()),p=o.querySelector("[data-ch-add-scope]"),b=o.querySelector("[data-ch-error]"),y=()=>{let m=new Set(c);for(let v of d)for(let B of r.get(v)?.labels??[])m.add(B);return m},g=()=>{let m=y(),v=m.size-c.size,B=m.size>A;p.disabled=v===0||B,p.textContent=B?`Maximum ${A.toLocaleString()} seats`:`Add ${v.toLocaleString()} seat${v===1?"":"s"}`,b.hidden=!B,b.textContent=B?`That would make ${m.size.toLocaleString()} selected seats. Choose fewer rows or sections.`:""};o.querySelectorAll("[data-ch-scope-id]").forEach(m=>{m.addEventListener("click",()=>{let v=m.dataset.chScopeId;d.has(v)?d.delete(v):d.add(v),m.setAttribute("aria-checked",String(d.has(v))),g()})}),p.addEventListener("click",()=>{let m=[...y()];!d.size||m.length>A||(this.closeDialog(),this.host.selectByLabels(m))}),g()})}openDialog(e){this.dialog=e,this.renderDialog()}renderDialog(){let e=this.dialog;e&&(e.kind==="create"?this.renderCreateDialog(e):e.kind==="review"?this.renderReviewDialog(e):e.kind==="scope"?this.renderScopeDialog(e):e.kind==="archive"?this.renderArchiveDialog(e):e.kind==="rename"?this.renderRenameDialog(e):e.kind==="pricing"?this.renderPricingDialog(e):e.kind==="seatlist"?this.renderSeatListDialog():e.kind==="menu"?this.renderMenuDialog(e):e.kind==="linkCreate"?this.renderLinkCreateDialog(e):e.kind==="linkRotate"?this.renderLinkRotateDialog(e):e.kind==="linkRevoke"?this.renderLinkRevokeDialog(e):e.kind==="intentSwitch"&&this.renderIntentSwitchDialog(e))}renderIntentSwitchDialog(e){let t=this.list?.channels.find(a=>a.id===e.channelId),s=e.intentTo;if(!t||!s||!this.caps.manage){this.closeDialog();return}let{headline:n,consequences:i}=ke(e.switchBlocked);this.renderScrim(`
479
498
  <h3 id="slm-ch-dlg-title">Change how ${h(t.name)} reaches buyers?</h3>
480
499
  <p class="sub">${h(n)}</p>
481
500
  <div class="slm-ch-alert warn" role="alert"><span>\u26A0</span><span>
@@ -489,7 +508,7 @@
489
508
  <button type="button" class="slm-btn" data-ch-intent-ack${e.busy?" disabled":""}>
490
509
  ${e.busy?"Changing\u2026":`Change to "${h(z(s))}"`}</button>
491
510
  </div>`,a=>{a.querySelector("[data-ch-intent-ack]")?.addEventListener("click",()=>{this.acknowledgeIntentSwitch(s,e.pendingLink??null)})})}async acknowledgeIntentSwitch(e,t){let s=this.detailChannelId;if(!s){this.closeDialog();return}if(this.dialog&&(this.dialog.busy=!0,this.renderDialog()),!await this.setAccessIntent(e,{acknowledgeLiveAccess:!0})){this.dialog?.kind==="intentSwitch"&&(this.dialog.busy=!1,this.renderDialog());return}if(!t){this.closeDialog();return}this.dialog?.kind==="intentSwitch"&&(this.dialog.busy=!1,this.renderDialog()),await this.mintLink(s,t)}renderScrim(e,t){let s=this.scrimEl;s||(this.lastFocus=document.activeElement??null),s?.remove();let n=document.createElement("div");n.className="slm-ch-scrim",n.innerHTML=`<div class="slm-ch-dialog" role="dialog" aria-modal="true"
492
- aria-labelledby="slm-ch-dlg-title" tabindex="-1">${e}</div>`,this.host.root.appendChild(n),this.scrimEl=n;let i=n.firstElementChild;i.querySelectorAll("[data-ch-close]").forEach(l=>{l.addEventListener("click",()=>this.closeDialog())}),n.addEventListener("keydown",l=>{if(l.key==="Escape"){l.stopPropagation(),this.closeDialog();return}if(l.key!=="Tab")return;let r=[...i.querySelectorAll('button:not([disabled]),select,input,textarea,a[href],[tabindex]:not([tabindex="-1"])')];if(!r.length)return;let d=r[0],c=r[r.length-1];l.shiftKey&&document.activeElement===d?(l.preventDefault(),c.focus()):!l.shiftKey&&document.activeElement===c&&(l.preventDefault(),d.focus())}),t(i),(i.querySelector("input,select,button")??i).focus()}closeDialog(e={}){this.dialog=null,this.scrimEl?.remove(),this.scrimEl=null,e.restoreFocus!==!1&&this.lastFocus?.focus?.(),this.lastFocus=null}renderCreateDialog(e){let t=(this.list?.channels??[]).map(n=>O(n.marker||n.name,"")),s=J("",t);this.renderScrim(`
511
+ aria-labelledby="slm-ch-dlg-title" tabindex="-1">${e}</div>`,this.host.root.appendChild(n),this.scrimEl=n;let i=n.firstElementChild;i.querySelectorAll("[data-ch-close]").forEach(o=>{o.addEventListener("click",()=>this.closeDialog())}),n.addEventListener("keydown",o=>{if(o.key==="Escape"){o.stopPropagation(),this.closeDialog();return}if(o.key!=="Tab")return;let r=[...i.querySelectorAll('button:not([disabled]),select,input,textarea,a[href],[tabindex]:not([tabindex="-1"])')];if(!r.length)return;let d=r[0],c=r[r.length-1];o.shiftKey&&document.activeElement===d?(o.preventDefault(),c.focus()):!o.shiftKey&&document.activeElement===c&&(o.preventDefault(),d.focus())}),t(i),(i.querySelector("input,select,button")??i).focus()}closeDialog(e={}){this.dialog=null,this.scrimEl?.remove(),this.scrimEl=null,e.restoreFocus!==!1&&this.lastFocus?.focus?.(),this.lastFocus=null}renderCreateDialog(e){let t=(this.list?.channels??[]).map(n=>O(n.marker||n.name,"")),s=J("",t);this.renderScrim(`
493
512
  <h3 id="slm-ch-dlg-title">Create channel</h3>
494
513
  <p class="sub">A named allocation only the right audience can buy from. You'll pick the seats next.</p>
495
514
  <div class="slm-field">
@@ -514,22 +533,22 @@
514
533
  <button type="button" class="quiet" data-ch-close>Cancel</button>
515
534
  <button type="button" class="slm-btn ghost" data-ch-create="plain">Create without allocating</button>
516
535
  <button type="button" class="slm-btn" data-ch-create="allocate">Create and allocate seats</button>
517
- </div>`,n=>{let i=n.querySelector("#slm-ch-name"),a=n.querySelector("[data-ch-marker]");i.addEventListener("input",()=>{let l=J(i.value,t);a.textContent=l.letter,a.style.background=l.color}),n.querySelectorAll("[data-ch-create]").forEach(l=>{l.addEventListener("click",()=>{let r=l.dataset.chCreate==="allocate";this.createChannel(i.value,a.textContent??"",a.style.background,n.querySelector("#slm-ch-ref")?.value??"",r)})})})}async createChannel(e,t,s,n,i){let a=e.trim();if(!a){this.showDialogError("Give the channel a name your team will recognise.");return}try{let l=await this.host.api.createChannel(this.host.eventKey,{name:a,marker:O(t,"")||null,color:s||null,externalRef:n.trim()||null});this.closeDialog(),await this.refresh(),this.targetChannelId=l.channel.id,this.detailChannelId=i?null:l.channel.id,this.announce(`Channel ${a} created with 0 seats allocated.`),this.host.toast(i?`${a} created. Select seats on the map to allocate them.`:`${a} created.`,"ok"),this.paintRail()}catch(l){let r=l instanceof f?l.code:void 0;this.showDialogError(r==="channel_name_taken"?"That name is already used on this event. Pick another.":"Couldn't create the channel. Try again."),this.host.onError(l)}}showDialogError(e){let t=this.scrimEl?.querySelector("[data-ch-error]");t&&(t.textContent=e,t.hidden=!1)}renderReviewDialog(e){let{labels:t,buckets:s}=this.currentPlan(),n=e.applied,i=n?n.buckets:s,a=this.nameOf(n?.targetChannelId??this.targetChannelId)??T,l=ge(i,a),r=n?n.applied:K(s),d=!n&&t.length>0&&r===0,c=!n&&t.length>A,p=W(l),g=n?'<div class="foot"><button type="button" class="slm-btn" data-ch-close>Done</button></div>':`<div class="foot">
536
+ </div>`,n=>{let i=n.querySelector("#slm-ch-name"),a=n.querySelector("[data-ch-marker]");i.addEventListener("input",()=>{let o=J(i.value,t);a.textContent=o.letter,a.style.background=o.color}),n.querySelectorAll("[data-ch-create]").forEach(o=>{o.addEventListener("click",()=>{let r=o.dataset.chCreate==="allocate";this.createChannel(i.value,a.textContent??"",a.style.background,n.querySelector("#slm-ch-ref")?.value??"",r)})})})}async createChannel(e,t,s,n,i){let a=e.trim();if(!a){this.showDialogError("Give the channel a name your team will recognise.");return}try{let o=await this.host.api.createChannel(this.host.eventKey,{name:a,marker:O(t,"")||null,color:s||null,externalRef:n.trim()||null});this.closeDialog(),await this.refresh(),this.targetChannelId=o.channel.id,this.detailChannelId=i?null:o.channel.id,this.announce(`Channel ${a} created with 0 seats allocated.`),this.host.toast(i?`${a} created. Select seats on the map to allocate them.`:`${a} created.`,"ok"),this.paintRail()}catch(o){let r=o instanceof f?o.code:void 0;this.showDialogError(r==="channel_name_taken"?"That name is already used on this event. Pick another.":"Couldn't create the channel. Try again."),this.host.onError(o)}}showDialogError(e){let t=this.scrimEl?.querySelector("[data-ch-error]");t&&(t.textContent=e,t.hidden=!1)}renderReviewDialog(e){let{labels:t,buckets:s}=this.currentPlan(),n=e.applied,i=n?n.buckets:s,a=this.nameOf(n?.targetChannelId??this.targetChannelId)??T,o=ge(i,a),r=n?n.applied:K(s),d=!n&&t.length>0&&r===0,c=!n&&t.length>A,p=W(o),b=n?'<div class="foot"><button type="button" class="slm-btn" data-ch-close>Done</button></div>':`<div class="foot">
518
537
  <button type="button" class="quiet" data-ch-close>Back</button>
519
538
  <button type="button" class="slm-btn" data-ch-apply ${d||c||e.busy?"disabled":""}>
520
539
  ${e.busy?"Applying\u2026":`Apply ${r.toLocaleString()} change${r===1?"":"s"}`}
521
540
  </button>
522
- </div>`,w=!n&&be(s)?'<p class="slm-note">Applying moves inventory out of another private channel. That is the line marked above.</p>':"",b=d?`<div class="slm-ch-alert warn"><span>\u2139</span><span>Nothing in this selection can move right now \u2014
541
+ </div>`,y=!n&&be(s)?'<p class="slm-note">Applying moves inventory out of another private channel. That is the line marked above.</p>':"",g=d?`<div class="slm-ch-alert warn"><span>\u2139</span><span>Nothing in this selection can move right now \u2014
523
542
  every seat is in a buyer's checkout, already sold, or already in ${h(a)}.</span></div>`:"",m=c?`<div class="slm-ch-alert warn" role="alert"><span>\u2139</span><span><b>Choose fewer seats.</b>
524
543
  One Apply can cover at most ${A.toLocaleString()} seats.</span></div>`:"";this.renderScrim(`
525
544
  <h3 id="slm-ch-dlg-title">${n?`Moved ${n.applied.toLocaleString()} seat${n.applied===1?"":"s"} to ${h(a)}`:`Move ${t.length.toLocaleString()} selected seat${t.length===1?"":"s"} to ${h(a)}`}</h3>
526
545
  <p class="sub">${n?"These are the exact counts the server applied.":"Every selected seat is in exactly one line below."}</p>
527
- ${b}
546
+ ${g}
528
547
  ${m}
529
548
  ${p||'<div class="slm-empty">Nothing selected.</div>'}
530
- ${w}
549
+ ${y}
531
550
  <p class="slm-ch-err" data-ch-error ${e.error?"":"hidden"}>${h(e.error??"")}</p>
532
- ${g}`,v=>{v.querySelector("[data-ch-apply]")?.addEventListener("click",()=>{this.apply()})}),n&&this.announce(`Applied ${n.applied} change${n.applied===1?"":"s"} to ${a}.`)}async apply(){if(!this.dialog||!this.caps.manage)return;let{labels:e}=this.currentPlan();if(e.length){if(e.length>A){this.showDialogError(`Choose at most ${A.toLocaleString()} seats for one Apply.`);return}this.dialog={...this.dialog,busy:!0,error:null},this.renderDialog();try{let t=await this.host.api.applyChannelAssignment(this.host.eventKey,{targetChannelId:B(this.targetChannelId)?null:this.targetChannelId,labels:e,assignmentVersion:this.assignmentVersion});this.assignmentVersion=t.assignmentVersion,this.conflict=!1,await this.refresh({quiet:!0}),this.closeDialog({restoreFocus:!1}),this.host.clearSelection(),this.showApplied(t)}catch(t){if(t instanceof f&&t.status===409&&t.code==="channel_assignment_conflict"){this.conflict=!0,this.closeDialog(),this.shakeStaged(),this.paintRail(),this.announce("Assignments changed while you were editing. Nothing was applied and your selection is kept.");return}if(t instanceof f&&t.status===403){this.caps={view:this.caps.view,manage:!1},this.closeDialog(),this.paintRail(),this.host.toast("Changing channels needs channel-management permission.","err");return}this.dialog={kind:"review",busy:!1,error:"Couldn't apply those changes. Try again."},this.renderDialog(),this.host.onError(t)}}}showApplied(e){let t=this.nameOf(e.targetChannelId)??T,s=e.buckets.skippedHeld.count+e.buckets.skippedBooked.count+e.buckets.notFound.count;this.setStaged(`<span class="slm-ch-tick" aria-hidden="true">\u2713</span>
551
+ ${b}`,v=>{v.querySelector("[data-ch-apply]")?.addEventListener("click",()=>{this.apply()})}),n&&this.announce(`Applied ${n.applied} change${n.applied===1?"":"s"} to ${a}.`)}async apply(){if(!this.dialog||!this.caps.manage)return;let{labels:e}=this.currentPlan();if(e.length){if(e.length>A){this.showDialogError(`Choose at most ${A.toLocaleString()} seats for one Apply.`);return}this.dialog={...this.dialog,busy:!0,error:null},this.renderDialog();try{let t=await this.host.api.applyChannelAssignment(this.host.eventKey,{targetChannelId:P(this.targetChannelId)?null:this.targetChannelId,labels:e,assignmentVersion:this.assignmentVersion});this.assignmentVersion=t.assignmentVersion,this.conflict=!1,await this.refresh({quiet:!0}),this.closeDialog({restoreFocus:!1}),this.host.clearSelection(),this.showApplied(t)}catch(t){if(t instanceof f&&t.status===409&&t.code==="channel_assignment_conflict"){this.conflict=!0,this.closeDialog(),this.shakeStaged(),this.paintRail(),this.announce("Assignments changed while you were editing. Nothing was applied and your selection is kept.");return}if(t instanceof f&&t.status===403){this.caps={view:this.caps.view,manage:!1},this.closeDialog(),this.paintRail(),this.host.toast("Changing channels needs channel-management permission.","err");return}this.dialog={kind:"review",busy:!1,error:"Couldn't apply those changes. Try again."},this.renderDialog(),this.host.onError(t)}}}showApplied(e){let t=this.nameOf(e.targetChannelId)??T,s=e.buckets.skippedHeld.count+e.buckets.skippedBooked.count+e.buckets.notFound.count;this.setStaged(`<span class="slm-ch-tick" aria-hidden="true">\u2713</span>
533
552
  <span>Assigned <b>${e.applied.toLocaleString()}</b> seat${e.applied===1?"":"s"} to ${h(t)}
534
553
  ${s?` \xB7 ${s.toLocaleString()} skipped`:""}</span>
535
554
  <span class="grow"></span>
@@ -557,7 +576,24 @@
557
576
  <div class="foot">
558
577
  <button type="button" class="quiet" data-ch-close>Cancel</button>
559
578
  <button type="button" class="slm-btn" data-ch-rename>Save name</button>
560
- </div>`,s=>{s.querySelector("[data-ch-rename]")?.addEventListener("click",()=>{let n=s.querySelector("#slm-ch-newname")?.value??"";if(!n.trim()){this.showDialogError("A channel needs a name.");return}this.host.api.renameChannel(this.host.eventKey,t.id,n.trim()).then(()=>(this.closeDialog(),this.refresh())).catch(i=>{this.showDialogError(i instanceof f&&i.code==="channel_name_taken"?"That name is already used on this event.":"Couldn't rename the channel."),this.host.onError(i)})})})}async chooseWebsiteIntegration(){this.detailChannelId&&await this.setAccessIntent("server")}async setAccessIntent(e,t={}){let s=this.detailChannelId;if(!s||!this.caps.manage)return!1;try{let n=await this.host.api.setChannelAccessIntent(this.host.eventKey,s,e,t);return await this.refresh(),this.host.toast(this.intentSavedCopy(e,n?.intentSwitch),"ok"),!0}catch(n){return n instanceof f&&n.code==="channel_intent_switch_blocked"?(this.openDialog({kind:"intentSwitch",channelId:s,intentTo:e,switchBlocked:n.details}),!1):n instanceof f&&n.code==="channel_access_intent_forbids"?(this.host.toast(Y(n.details),"err"),!1):(this.host.toast("Couldn't change how this channel reaches buyers.","err"),this.host.onError(n),!1)}}intentSavedCopy(e,t){let s=e==="server"?"Set to your website or app. The embed code is on the Embed page.":e==="internal"?"Only your own staff can sell this channel now.":e==="hosted_link"?"Set to buyer links. Create one to let buyers in.":"Kept as a protected reserve. No route can sell these seats.";if(!t)return s;let n=t.closedLinks?` ${t.closedLinks.toLocaleString()} buyer link${t.closedLinks===1?"":"s"} closed.`:"",i=t.keptSessions?` ${t.keptSessions.toLocaleString()} buyer${t.keptSessions===1?"":"s"} already in a checkout can still finish.`:"";return`${s}${n}${i}`}async togglePause(e=this.detailChannelId){let t=this.list?.channels.find(n=>n.id===e);if(!t||!this.caps.manage)return;let s=t.state!=="paused";try{await this.host.api.setChannelPaused(this.host.eventKey,t.id,s),await this.refresh(),this.host.toast(s?`${t.name} paused. Existing checkouts can finish; no new buyer access is issued.`:`${t.name} resumed.`,"ok")}catch(n){this.host.toast("Couldn't change that channel.","err"),this.host.onError(n)}}renderArchiveDialog(e){let t=this.list?.channels.find(l=>l.id===e.channelId);if(!t){this.closeDialog();return}let s=e.archiveBlocked??null,n=!s&&t.counts.held>0,i=this.assignableChannels().filter(l=>l.id!==t.id),a=s?`<div class="slm-ch-alert warn" role="alert"><span>\u23F3</span>
579
+ </div>`,s=>{s.querySelector("[data-ch-rename]")?.addEventListener("click",()=>{let n=s.querySelector("#slm-ch-newname")?.value??"";if(!n.trim()){this.showDialogError("A channel needs a name.");return}this.host.api.renameChannel(this.host.eventKey,t.id,n.trim()).then(()=>(this.closeDialog(),this.refresh())).catch(i=>{this.showDialogError(i instanceof f&&i.code==="channel_name_taken"?"That name is already used on this event.":"Couldn't rename the channel."),this.host.onError(i)})})})}renderPricingDialog(e){let t=this.list?.channels.find(a=>a.id===e.channelId),s=this.host.api.updateChannelPricing;if(!t||!s||!this.caps.manage){this.closeDialog();return}let n=new Map((t.priceOverrides??[]).map(a=>[`${a.categoryKey}\0${a.tierId??""}`,a.price])),i=this.host.categories().flatMap(a=>(a.tiers?.length?a.tiers:[null]).map(r=>{let d=r?.id??null,c=`${a.key}\0${d??""}`,p=r?.price??a.price??0,b=n.get(c),y=r?`${a.label} \xB7 ${r.name}`:a.label;return`<label class="slm-ch-price-row">
580
+ <span><b>${h(y)}</b><small>Event price ${h(String(p))}</small></span>
581
+ <input class="slm-input" type="number" min="0" max="1000000" step="0.01"
582
+ inputmode="decimal" aria-label="Custom price for ${h(y)}"
583
+ data-ch-price-category="${h(a.key)}" data-ch-price-tier="${h(d??"")}"
584
+ placeholder="${h(String(p))}" value="${b===void 0?"":h(String(b))}"
585
+ ${e.busy?"disabled":""} />
586
+ </label>`})).join("");this.renderScrim(`
587
+ <h3 id="slm-ch-dlg-title">Prices for ${h(t.name)}</h3>
588
+ <p class="sub">Set only the prices that differ for this audience. Leave a field blank to use the event price.</p>
589
+ <div class="slm-ch-price-list">${i||'<p class="slm-empty">This event has no priced categories.</p>'}</div>
590
+ <p class="slm-ch-err" data-ch-error ${e.error?"":"hidden"}>${h(e.error??"")}</p>
591
+ <div class="foot">
592
+ <button type="button" class="quiet" data-ch-close ${e.busy?"disabled":""}>Cancel</button>
593
+ <button type="button" class="slm-btn" data-ch-price-save ${e.busy||!i?"disabled":""}>
594
+ ${e.busy?"Saving\u2026":"Save prices"}
595
+ </button>
596
+ </div>`,a=>{a.querySelector("[data-ch-price-save]")?.addEventListener("click",()=>{let o=[];for(let r of a.querySelectorAll("[data-ch-price-category]")){let d=r.value.trim();if(!d)continue;let c=Number(d);if(!Number.isFinite(c)||c<0||c>1e6){r.focus(),this.showDialogError("Enter a price from 0 to 1,000,000, or leave the field blank.");return}o.push({categoryKey:r.dataset.chPriceCategory,tierId:r.dataset.chPriceTier||null,price:c})}this.saveChannelPricing(t,o)})})}async saveChannelPricing(e,t){let s=this.host.api.updateChannelPricing;if(!(!s||!this.dialog||this.dialog.kind!=="pricing")){this.dialog={...this.dialog,busy:!0,error:null},this.renderDialog();try{await s.call(this.host.api,this.host.eventKey,e.id,t,e.pricingVersion??0),this.closeDialog(),await this.refresh(),this.host.toast(t.length?`Custom prices saved for ${e.name}.`:`${e.name} now uses event prices.`,"ok")}catch(n){if(n instanceof f&&n.code==="channel_pricing_conflict"){await this.refresh({quiet:!0}),this.dialog={kind:"pricing",channelId:e.id,error:"Prices changed in another window. Latest values are shown \u2014 review and save again."},this.renderDialog();return}this.dialog={kind:"pricing",channelId:e.id,error:n instanceof f&&n.serverMessage?n.serverMessage:"Couldn't save these prices. Try again."},this.renderDialog(),this.host.onError(n)}}}async chooseWebsiteIntegration(){this.detailChannelId&&await this.setAccessIntent("server")}async setAccessIntent(e,t={}){let s=this.detailChannelId;if(!s||!this.caps.manage)return!1;try{let n=await this.host.api.setChannelAccessIntent(this.host.eventKey,s,e,t);return await this.refresh(),this.host.toast(this.intentSavedCopy(e,n?.intentSwitch),"ok"),!0}catch(n){return n instanceof f&&n.code==="channel_intent_switch_blocked"?(this.openDialog({kind:"intentSwitch",channelId:s,intentTo:e,switchBlocked:n.details}),!1):n instanceof f&&n.code==="channel_access_intent_forbids"?(this.host.toast(Y(n.details),"err"),!1):(this.host.toast("Couldn't change how this channel reaches buyers.","err"),this.host.onError(n),!1)}}intentSavedCopy(e,t){let s=e==="server"?"Set to your website or app. The embed code is on the Embed page.":e==="internal"?"Only your own staff can sell this channel now.":e==="hosted_link"?"Set to buyer links. Create one to let buyers in.":"Kept as a protected reserve. No route can sell these seats.";if(!t)return s;let n=t.closedLinks?` ${t.closedLinks.toLocaleString()} buyer link${t.closedLinks===1?"":"s"} closed.`:"",i=t.keptSessions?` ${t.keptSessions.toLocaleString()} buyer${t.keptSessions===1?"":"s"} already in a checkout can still finish.`:"";return`${s}${n}${i}`}async togglePause(e=this.detailChannelId){let t=this.list?.channels.find(n=>n.id===e);if(!t||!this.caps.manage)return;let s=t.state!=="paused";try{await this.host.api.setChannelPaused(this.host.eventKey,t.id,s),await this.refresh(),this.host.toast(s?`${t.name} paused. Existing checkouts can finish; no new buyer access is issued.`:`${t.name} resumed.`,"ok")}catch(n){this.host.toast("Couldn't change that channel.","err"),this.host.onError(n)}}renderArchiveDialog(e){let t=this.list?.channels.find(o=>o.id===e.channelId);if(!t){this.closeDialog();return}let s=e.archiveBlocked??null,n=!s&&t.counts.held>0,i=this.assignableChannels().filter(o=>o.id!==t.id),a=s?`<div class="slm-ch-alert warn" role="alert"><span>\u23F3</span>
561
597
  <span><b>${(s.heldUnits??s.activeHolds??0).toLocaleString()} seats are in a buyer's checkout right now.</b>
562
598
  Archive is unavailable while seats are held \u2014 try again ${h(ve(s))}.</span></div>`:n?`<div class="slm-ch-alert warn"><span>\u23F3</span>
563
599
  <span>${t.counts.held.toLocaleString()} seats are in a buyer's checkout right now.
@@ -569,7 +605,7 @@
569
605
  <div class="slm-field">
570
606
  <label for="slm-ch-dest">Move the ${t.counts.free.toLocaleString()} remaining free seats to</label>
571
607
  <select class="slm-select" id="slm-ch-dest">
572
- ${i.map(l=>`<option value="${h(l.id)}">${h(l.name)}</option>`).join("")}
608
+ ${i.map(o=>`<option value="${h(o.id)}">${h(o.name)}</option>`).join("")}
573
609
  </select>
574
610
  </div>
575
611
  <p class="slm-note">${t.counts.booked.toLocaleString()} sold seats keep "${h(t.name)}" on their sale
@@ -579,22 +615,22 @@
579
615
  <div class="foot">
580
616
  <button type="button" class="quiet" data-ch-close>Cancel</button>
581
617
  <button type="button" class="slm-btn danger" data-ch-archive ${s?"disabled":""}>Archive channel</button>
582
- </div>`,l=>{l.querySelector("[data-ch-archive]")?.addEventListener("click",()=>{let r=l.querySelector("#slm-ch-dest")?.value??"";this.archive(t.id,r||null)})})}async archive(e,t){try{await this.host.api.archiveChannel(this.host.eventKey,e,t),this.closeDialog(),this.detailChannelId=null,await this.refresh(),this.host.toast("Channel archived. Its remaining seats moved to the destination you chose.","ok")}catch(s){if(s instanceof f&&s.status===409&&s.code==="channel_archive_blocked_by_holds"){this.dialog={kind:"archive",channelId:e,archiveBlocked:s.details??{}},this.renderDialog();return}this.showDialogError("Couldn't archive that channel. Try again."),this.host.onError(s)}}renderSeatListDialog(){let e=new Set(this.host.selectionLabels()),t=new Map,s=0;for(let i of this.host.seats()){if(s+=1,s>this.seatListLimit)break;let a=this.host.sectionOfLabel(i.label),l=a?.id??"",r=t.get(l)??{label:a?.label??"Other seats",seats:[]};r.seats.push({label:i.label,status:this.host.statusOf(i.label)??"free"}),t.set(l,r)}let n=[...t.entries()].map(([i,a])=>`
618
+ </div>`,o=>{o.querySelector("[data-ch-archive]")?.addEventListener("click",()=>{let r=o.querySelector("#slm-ch-dest")?.value??"";this.archive(t.id,r||null)})})}async archive(e,t){try{await this.host.api.archiveChannel(this.host.eventKey,e,t),this.closeDialog(),this.detailChannelId=null,await this.refresh(),this.host.toast("Channel archived. Its remaining seats moved to the destination you chose.","ok")}catch(s){if(s instanceof f&&s.status===409&&s.code==="channel_archive_blocked_by_holds"){this.dialog={kind:"archive",channelId:e,archiveBlocked:s.details??{}},this.renderDialog();return}this.showDialogError("Couldn't archive that channel. Try again."),this.host.onError(s)}}renderSeatListDialog(){let e=new Set(this.host.selectionLabels()),t=new Map,s=0;for(let i of this.host.seats()){if(s+=1,s>this.seatListLimit)break;let a=this.host.sectionOfLabel(i.label),o=a?.id??"",r=t.get(o)??{label:a?.label??"Other seats",seats:[]};r.seats.push({label:i.label,status:this.host.statusOf(i.label)??"free"}),t.set(o,r)}let n=[...t.entries()].map(([i,a])=>`
583
619
  <div class="slm-ch-seatgroup">
584
620
  <span>${h(a.label)}</span>
585
621
  ${i?`<button type="button" data-ch-section="${h(i)}">Select section</button>`:""}
586
622
  </div>
587
- ${a.seats.map(l=>{let r=this.allocation.get(l.label)??C,d=this.nameOf(r)??T;return`<button type="button" class="slm-ch-seatitem" role="checkbox"
588
- aria-checked="${e.has(l.label)}" data-ch-seat="${h(l.label)}">
623
+ ${a.seats.map(o=>{let r=this.allocation.get(o.label)??C,d=this.nameOf(r)??T;return`<button type="button" class="slm-ch-seatitem" role="checkbox"
624
+ aria-checked="${e.has(o.label)}" data-ch-seat="${h(o.label)}">
589
625
  <span class="box" aria-hidden="true">\u2713</span>
590
- <span>${h(l.label)}</span>
591
- <span class="meta">${h(d)} \xB7 ${h(l.status)}</span>
626
+ <span>${h(o.label)}</span>
627
+ <span class="meta">${h(d)} \xB7 ${h(o.status)}</span>
592
628
  </button>`}).join("")}`).join("");this.renderScrim(`
593
629
  <h3 id="slm-ch-dlg-title">Seat list</h3>
594
630
  <p class="sub">The same selection as the map, with checkboxes. Space or Enter toggles a seat.</p>
595
631
  <div class="slm-ch-seatlist">${n||'<div class="slm-empty">No seats on this chart.</div>'}</div>
596
632
  ${s>this.seatListLimit?'<div class="foot"><button type="button" class="slm-btn ghost" data-ch-more>Show more seats</button></div>':""}
597
- <div class="foot"><button type="button" class="slm-btn" data-ch-close>Done</button></div>`,i=>{i.querySelectorAll("[data-ch-seat]").forEach(a=>{a.addEventListener("click",()=>{let l=a.dataset.chSeat,r=new Set(this.host.selectionLabels());r.has(l)?r.delete(l):r.add(l),this.host.clearSelection(),r.size&&this.host.selectByLabels([...r]),this.renderSeatListDialog()})}),i.querySelectorAll("[data-ch-section]").forEach(a=>{a.addEventListener("click",()=>{this.host.selectSection(a.dataset.chSection),this.renderSeatListDialog()})}),i.querySelector("[data-ch-more]")?.addEventListener("click",()=>{this.seatListLimit+=ht,this.renderSeatListDialog()})})}async reloadLinks(){let e=this.detailChannelId;e&&(this.linksState=this.links.length?this.linksState:"loading",await this.loadLinks(e),this.paintRail())}async reloadAfterLinkChange(e){if(this.detailChannelId===e){await this.refresh({quiet:!0});return}await this.loadLinks(e),this.active&&this.paintRail()}linkById(e){return this.links.find(t=>t.id===e)??null}renderLinkCreateDialog(e){let t=this.list?.channels.find(s=>s.id===e.channelId);if(!t||!this.caps.manage){this.closeDialog();return}this.renderScrim(`
633
+ <div class="foot"><button type="button" class="slm-btn" data-ch-close>Done</button></div>`,i=>{i.querySelectorAll("[data-ch-seat]").forEach(a=>{a.addEventListener("click",()=>{let o=a.dataset.chSeat,r=new Set(this.host.selectionLabels());r.has(o)?r.delete(o):r.add(o),this.host.clearSelection(),r.size&&this.host.selectByLabels([...r]),this.renderSeatListDialog()})}),i.querySelectorAll("[data-ch-section]").forEach(a=>{a.addEventListener("click",()=>{this.host.selectSection(a.dataset.chSection),this.renderSeatListDialog()})}),i.querySelector("[data-ch-more]")?.addEventListener("click",()=>{this.seatListLimit+=ht,this.renderSeatListDialog()})})}async reloadLinks(){let e=this.detailChannelId;e&&(this.linksState=this.links.length?this.linksState:"loading",await this.loadLinks(e),this.paintRail())}async reloadAfterLinkChange(e){if(this.detailChannelId===e){await this.refresh({quiet:!0});return}await this.loadLinks(e),this.active&&this.paintRail()}linkById(e){return this.links.find(t=>t.id===e)??null}renderLinkCreateDialog(e){let t=this.list?.channels.find(s=>s.id===e.channelId);if(!t||!this.caps.manage){this.closeDialog();return}this.renderScrim(`
598
634
  <h3 id="slm-ch-dlg-title">Create a buyer link for ${h(t.name)}</h3>
599
635
  <p class="sub">Anyone who opens the link can buy from this channel's allocation \u2014 and only from it.
600
636
  You'll see the link once, right after you create it.</p>
@@ -633,7 +669,7 @@
633
669
  <div class="foot">
634
670
  <button type="button" class="quiet" data-ch-close>Cancel</button>
635
671
  <button type="button" class="slm-btn" data-ch-lk-create>Create link</button>
636
- </div>`,s=>{let n=s.querySelector("[data-ch-lk-expiry]"),i=s.querySelector("[data-ch-lk-when-field]"),a=s.querySelector("#slm-ch-lk-when");n.addEventListener("change",()=>{let l=n.value==="custom";i.hidden=!l,l&&!a.value&&(a.value=ot(Date.now()+7*864e5))}),s.querySelector("[data-ch-lk-create]")?.addEventListener("click",()=>{let l=De(s,"#slm-ch-lk-redemptions"),r=De(s,"#slm-ch-lk-quantity");if(l==null||r==null){this.showDialogError("Those two settings need to be whole numbers.");return}let d;if(n.value==="custom"&&(d=Date.parse(a.value),!Number.isFinite(d))){this.showDialogError("Pick the date and time the link should stop working.");return}this.createLink(t.id,{label:s.querySelector("#slm-ch-lk-label")?.value.trim()||null,includePublic:s.querySelector("#slm-ch-lk-public")?.checked??!1,...d===void 0?{}:{expiresAt:d},maxRedemptions:l,maxQuantity:r})})})}async createLink(e,t){await this.ensureHostedLinkRoute(e,t)&&await this.mintLink(e,t)}async mintLink(e,t){try{let s=await this.host.api.createAccessLink(this.host.eventKey,e,t);this.revealLink(s,{channelId:e}),await this.reloadAfterLinkChange(e)}catch(s){this.showDialogError(_(s instanceof f?s:void 0)),s instanceof f||this.host.onError(s)}}async ensureHostedLinkRoute(e,t){if((this.list?.channels.find(n=>n.id===e)?.access?.intent??"none")==="hosted_link")return!0;try{return await this.host.api.setChannelAccessIntent(this.host.eventKey,e,"hosted_link"),await this.refresh(),!0}catch(n){return n instanceof f&&n.code==="channel_intent_switch_blocked"?(this.openDialog({kind:"intentSwitch",channelId:e,intentTo:"hosted_link",switchBlocked:n.details,pendingLink:t}),!1):(this.showDialogError(n instanceof f&&n.code==="channel_access_intent_forbids"?Y(n.details):"Couldn't set this channel up for buyer links. Try again."),n instanceof f||this.host.onError(n),!1)}}revealLink(e,t){let s=e.url;this.dialog=null;let n=t.rotated?`<div class="slm-ch-alert warn" role="status"><span>\u26A0</span><span>
672
+ </div>`,s=>{let n=s.querySelector("[data-ch-lk-expiry]"),i=s.querySelector("[data-ch-lk-when-field]"),a=s.querySelector("#slm-ch-lk-when");n.addEventListener("change",()=>{let o=n.value==="custom";i.hidden=!o,o&&!a.value&&(a.value=ot(Date.now()+7*864e5))}),s.querySelector("[data-ch-lk-create]")?.addEventListener("click",()=>{let o=De(s,"#slm-ch-lk-redemptions"),r=De(s,"#slm-ch-lk-quantity");if(o==null||r==null){this.showDialogError("Those two settings need to be whole numbers.");return}let d;if(n.value==="custom"&&(d=Date.parse(a.value),!Number.isFinite(d))){this.showDialogError("Pick the date and time the link should stop working.");return}this.createLink(t.id,{label:s.querySelector("#slm-ch-lk-label")?.value.trim()||null,includePublic:s.querySelector("#slm-ch-lk-public")?.checked??!1,...d===void 0?{}:{expiresAt:d},maxRedemptions:o,maxQuantity:r})})})}async createLink(e,t){await this.ensureHostedLinkRoute(e,t)&&await this.mintLink(e,t)}async mintLink(e,t){try{let s=await this.host.api.createAccessLink(this.host.eventKey,e,t);this.revealLink(s,{channelId:e}),await this.reloadAfterLinkChange(e)}catch(s){this.showDialogError(_(s instanceof f?s:void 0)),s instanceof f||this.host.onError(s)}}async ensureHostedLinkRoute(e,t){if((this.list?.channels.find(n=>n.id===e)?.access?.intent??"none")==="hosted_link")return!0;try{return await this.host.api.setChannelAccessIntent(this.host.eventKey,e,"hosted_link"),await this.refresh(),!0}catch(n){return n instanceof f&&n.code==="channel_intent_switch_blocked"?(this.openDialog({kind:"intentSwitch",channelId:e,intentTo:"hosted_link",switchBlocked:n.details,pendingLink:t}),!1):(this.showDialogError(n instanceof f&&n.code==="channel_access_intent_forbids"?Y(n.details):"Couldn't set this channel up for buyer links. Try again."),n instanceof f||this.host.onError(n),!1)}}revealLink(e,t){let s=e.url;this.dialog=null;let n=t.rotated?`<div class="slm-ch-alert warn" role="status"><span>\u26A0</span><span>
637
673
  <b>The old link has stopped working.</b> ${e.endedSessions?`${e.endedSessions.toLocaleString()} buyer${e.endedSessions===1?"":"s"} lost access immediately.`:"Buyers who already came in can finish; every new visit needs this link."}</span></div>`:"",i=se(e.link).map(a=>`<div class="slm-ch-lkrow"><span class="k">${h(a.k)}</span>
638
674
  <span class="v">${h(a.v)}</span></div>`).join("");this.renderScrim(`
639
675
  <h3 id="slm-ch-dlg-title">Copy this link now</h3>
@@ -651,7 +687,7 @@
651
687
  ${i}
652
688
  <div class="foot">
653
689
  <button type="button" class="slm-btn" data-ch-close data-ch-lk-done>I've copied it</button>
654
- </div>`,a=>{let l=a.querySelector("[data-ch-lk-copy]");l?.addEventListener("click",()=>{let r=()=>{l.textContent="Copied",this.announce("Buyer link copied.")},d=typeof navigator>"u"?null:navigator.clipboard;if(d?.writeText){d.writeText(s).then(r,()=>Oe(a));return}Oe(a)})}),this.announce("Your buyer link is ready and is shown once.")}renderLinkRotateDialog(e){let t=this.linkById(e.linkId);if(!t||!this.caps.manage){this.closeDialog();return}let s=t.activeSessions??0,n=s?`<div class="slm-ch-alert warn"><span>\u26A0</span>
690
+ </div>`,a=>{let o=a.querySelector("[data-ch-lk-copy]");o?.addEventListener("click",()=>{let r=()=>{o.textContent="Copied",this.announce("Buyer link copied.")},d=typeof navigator>"u"?null:navigator.clipboard;if(d?.writeText){d.writeText(s).then(r,()=>Oe(a));return}Oe(a)})}),this.announce("Your buyer link is ready and is shown once.")}renderLinkRotateDialog(e){let t=this.linkById(e.linkId);if(!t||!this.caps.manage){this.closeDialog();return}let s=t.activeSessions??0,n=s?`<div class="slm-ch-alert warn"><span>\u26A0</span>
655
691
  <span><b>${s.toLocaleString()} buyer${s===1?"":"s"}</b> got in with the current link
656
692
  and still ${s===1?"has":"have"} active access.</span></div>`:"";this.renderScrim(`
657
693
  <h3 id="slm-ch-dlg-title">Rotate the ${h(t.label||"buyer")} link?</h3>
@@ -673,7 +709,7 @@
673
709
  <div class="foot">
674
710
  <button type="button" class="quiet" data-ch-close>Cancel</button>
675
711
  <button type="button" class="slm-btn" data-ch-lk-rotate disabled>Rotate and copy new link</button>
676
- </div>`,i=>{let a=i.querySelector("[data-ch-lk-rotate]");i.querySelectorAll("[data-ch-rot]").forEach(l=>{l.addEventListener("change",()=>{a.disabled=!1})}),a.addEventListener("click",()=>{let l=[...i.querySelectorAll("[data-ch-rot]")].find(r=>r.checked);if(!l){this.showDialogError(_({code:"end_active_sessions_required"}));return}this.rotateLink(e.channelId,t.id,l.value==="end")})})}async rotateLink(e,t,s){try{let n=await this.host.api.rotateAccessLink(this.host.eventKey,e,t,s);this.revealLink(n,{channelId:e,rotated:!0}),await this.reloadAfterLinkChange(e)}catch(n){this.showDialogError(_(n instanceof f?n:void 0)),n instanceof f||this.host.onError(n)}}renderLinkRevokeDialog(e){let t=this.linkById(e.linkId);if(!t||!this.caps.manage){this.closeDialog();return}let s=t.activeSessions??0;this.renderScrim(`
712
+ </div>`,i=>{let a=i.querySelector("[data-ch-lk-rotate]");i.querySelectorAll("[data-ch-rot]").forEach(o=>{o.addEventListener("change",()=>{a.disabled=!1})}),a.addEventListener("click",()=>{let o=[...i.querySelectorAll("[data-ch-rot]")].find(r=>r.checked);if(!o){this.showDialogError(_({code:"end_active_sessions_required"}));return}this.rotateLink(e.channelId,t.id,o.value==="end")})})}async rotateLink(e,t,s){try{let n=await this.host.api.rotateAccessLink(this.host.eventKey,e,t,s);this.revealLink(n,{channelId:e,rotated:!0}),await this.reloadAfterLinkChange(e)}catch(n){this.showDialogError(_(n instanceof f?n:void 0)),n instanceof f||this.host.onError(n)}}renderLinkRevokeDialog(e){let t=this.linkById(e.linkId);if(!t||!this.caps.manage){this.closeDialog();return}let s=t.activeSessions??0;this.renderScrim(`
677
713
  <h3 id="slm-ch-dlg-title">Revoke the ${h(t.label||"buyer")} link?</h3>
678
714
  <p class="sub">It stops opening immediately and cannot be restored \u2014 there is no undo, and no way to
679
715
  bring the same URL back. Seats already bought through it keep their sale.</p>
@@ -687,7 +723,7 @@
687
723
  <div class="foot">
688
724
  <button type="button" class="quiet" data-ch-close>Cancel</button>
689
725
  <button type="button" class="slm-btn danger" data-ch-lk-revoke>Revoke link</button>
690
- </div>`,n=>{n.querySelector("[data-ch-lk-revoke]")?.addEventListener("click",()=>{let i=n.querySelector("[data-ch-lk-endsessions]")?.checked??!1;this.revokeLink(e.channelId,t.id,i)})})}async revokeLink(e,t,s){try{let n=await this.host.api.revokeAccessLink(this.host.eventKey,e,t,s);this.closeDialog(),await this.reloadAfterLinkChange(e),this.host.toast(n.endedSessions?`Link revoked. ${n.endedSessions.toLocaleString()} buyer${n.endedSessions===1?"":"s"} lost access.`:"Link revoked. It no longer opens for anyone.","ok")}catch(n){this.showDialogError(_(n instanceof f?n:void 0)),n instanceof f||this.host.onError(n)}}applySheetClasses(){let e=this.host.root,t=this.host.isCompact();e.classList.toggle("ch-sheet",t&&this.active);for(let s of["collapsed","medium","full"])e.classList.toggle(`detent-${s}`,t&&this.active&&this.detent===s);this.host.setMapInert(t&&this.active&&this.detent==="full")}cycleDetent(){let e=["collapsed","medium","full"];this.detent=e[(e.indexOf(this.detent)+1)%e.length],this.applySheetClasses()}handleBack(){return this.scrimEl?(this.closeDialog(),!0):this.host.isCompact()&&this.detent==="full"?(this.detent="medium",this.applySheetClasses(),!0):!1}}});var Kt={};qe(Kt,{ACCESS_LINK_DEFAULTS:()=>ee,ChannelsMode:()=>ne,ManageApi:()=>U,ManageApiError:()=>f,PUBLIC_CHANNEL_ID:()=>C,PUBLIC_CHANNEL_NAME:()=>T,SeatManager:()=>Re,accessIntentDescription:()=>ye,accessIntentLabel:()=>z,accessLine:()=>fe,accessLinkBadge:()=>we,accessLinkErrorCopy:()=>_,accessLinkIsLive:()=>te,accessLinkPolicyLines:()=>se,bucketRows:()=>ge,bucketRowsHtml:()=>W,dropReviewRows:()=>it,intentForbidsCopy:()=>Y,intentSwitchBlockedCopy:()=>ke,isPublicChannelId:()=>B,markerLetter:()=>O,markerOf:()=>pe,mutationCount:()=>K,needsMoveConfirmation:()=>be,planAssignment:()=>me,retryAfterCopy:()=>ve,selectionSources:()=>ue,stateBadge:()=>Se,suggestMarker:()=>J});module.exports=St(Kt);var L=require("@seatlayer/core");ae();var Rt=/^[a-zA-Z0-9._-]+$/;function $t(o){let e;try{e=new URL(o,"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]),n=decodeURIComponent(t[2]);return!s||!Rt.test(n)?null:{eventKey:s,asset:n}}catch{return null}}function Tt(o){try{return/^\/v1\/events\/[^/]+\/assets(?:\/|$)/.test(new URL(o,"https://seatlayer.invalid").pathname)}catch{return!1}}var oe=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=$t(e);if(!t)return Promise.resolve(Tt(e)?null:e);if(t.eventKey!==this.eventKey||this.disposed)return Promise.resolve(null);let s=`${t.eventKey}/${t.asset}`,n=this.pending.get(s);if(n)return n;let i=this.load(t.eventKey,t.asset).then(a=>{let l=URL.createObjectURL(a);return this.disposed?(URL.revokeObjectURL(l),null):(this.created.add(l),l)}).catch(a=>{throw this.pending.delete(s),a});return this.pending.set(s,i),i}async prepareRendererChart(e){let t=async i=>{if(!i?.url)return;let a=await this.resolve(i.url);if(!a)throw new Error("organizer_event_asset_scope_mismatch");i.url=a},s=async i=>{for(let a of i){if(a.type!=="decorImage")continue;let l=a,r=await this.resolve(l.href);if(!r)throw new Error("organizer_event_asset_scope_mismatch");l.href=r}},n=async i=>{await t(i.backgroundImage),await s(i.objects)};await n(e);for(let i of e.floors??[])await n(i);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 Ne="seatlayer-manager-style",Ue="seatlayer-manager-channels-style",At=`
726
+ </div>`,n=>{n.querySelector("[data-ch-lk-revoke]")?.addEventListener("click",()=>{let i=n.querySelector("[data-ch-lk-endsessions]")?.checked??!1;this.revokeLink(e.channelId,t.id,i)})})}async revokeLink(e,t,s){try{let n=await this.host.api.revokeAccessLink(this.host.eventKey,e,t,s);this.closeDialog(),await this.reloadAfterLinkChange(e),this.host.toast(n.endedSessions?`Link revoked. ${n.endedSessions.toLocaleString()} buyer${n.endedSessions===1?"":"s"} lost access.`:"Link revoked. It no longer opens for anyone.","ok")}catch(n){this.showDialogError(_(n instanceof f?n:void 0)),n instanceof f||this.host.onError(n)}}applySheetClasses(){let e=this.host.root,t=this.host.isCompact();e.classList.toggle("ch-sheet",t&&this.active);for(let s of["collapsed","medium","full"])e.classList.toggle(`detent-${s}`,t&&this.active&&this.detent===s);this.host.setMapInert(t&&this.active&&this.detent==="full")}cycleDetent(){let e=["collapsed","medium","full"];this.detent=e[(e.indexOf(this.detent)+1)%e.length],this.applySheetClasses()}handleBack(){return this.scrimEl?(this.closeDialog(),!0):this.host.isCompact()&&this.detent==="full"?(this.detent="medium",this.applySheetClasses(),!0):!1}}});var Kt={};qe(Kt,{ACCESS_LINK_DEFAULTS:()=>ee,ChannelsMode:()=>ne,ManageApi:()=>U,ManageApiError:()=>f,PUBLIC_CHANNEL_ID:()=>C,PUBLIC_CHANNEL_NAME:()=>T,SeatManager:()=>Re,accessIntentDescription:()=>ye,accessIntentLabel:()=>z,accessLine:()=>fe,accessLinkBadge:()=>we,accessLinkErrorCopy:()=>_,accessLinkIsLive:()=>te,accessLinkPolicyLines:()=>se,bucketRows:()=>ge,bucketRowsHtml:()=>W,dropReviewRows:()=>it,intentForbidsCopy:()=>Y,intentSwitchBlockedCopy:()=>ke,isPublicChannelId:()=>P,markerLetter:()=>O,markerOf:()=>pe,mutationCount:()=>K,needsMoveConfirmation:()=>be,planAssignment:()=>me,retryAfterCopy:()=>ve,selectionSources:()=>ue,stateBadge:()=>xe,suggestMarker:()=>J});module.exports=xt(Kt);var L=require("@seatlayer/core");ae();var Rt=/^[a-zA-Z0-9._-]+$/;function $t(l){let e;try{e=new URL(l,"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]),n=decodeURIComponent(t[2]);return!s||!Rt.test(n)?null:{eventKey:s,asset:n}}catch{return null}}function Tt(l){try{return/^\/v1\/events\/[^/]+\/assets(?:\/|$)/.test(new URL(l,"https://seatlayer.invalid").pathname)}catch{return!1}}var oe=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=$t(e);if(!t)return Promise.resolve(Tt(e)?null:e);if(t.eventKey!==this.eventKey||this.disposed)return Promise.resolve(null);let s=`${t.eventKey}/${t.asset}`,n=this.pending.get(s);if(n)return n;let i=this.load(t.eventKey,t.asset).then(a=>{let o=URL.createObjectURL(a);return this.disposed?(URL.revokeObjectURL(o),null):(this.created.add(o),o)}).catch(a=>{throw this.pending.delete(s),a});return this.pending.set(s,i),i}async prepareRendererChart(e){let t=async i=>{if(!i?.url)return;let a=await this.resolve(i.url);if(!a)throw new Error("organizer_event_asset_scope_mismatch");i.url=a},s=async i=>{for(let a of i){if(a.type!=="decorImage")continue;let o=a,r=await this.resolve(o.href);if(!r)throw new Error("organizer_event_asset_scope_mismatch");o.href=r}},n=async i=>{await t(i.backgroundImage),await s(i.objects)};await n(e);for(let i of e.floors??[])await n(i);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 Ne="seatlayer-manager-style",Ue="seatlayer-manager-channels-style",At=`
691
727
  /* The floor was 480px, which trapped the cockpit in any host shorter than that:
692
728
  every ancestor here is overflow:hidden, so the bottom of the rail (Create
693
729
  channel, Show archived) was rendered but clipped away by the host and could
@@ -960,31 +996,31 @@
960
996
  transition:none!important;
961
997
  scroll-behavior:auto!important}
962
998
  }
963
- `;function Ke(){if(typeof document>"u"||document.getElementById(Ne))return;let o=document.createElement("style");o.id=Ne,o.textContent=At,document.head.appendChild(o)}function Ye(o){if(typeof document>"u"||document.getElementById(Ue))return;let e=document.createElement("style");e.id=Ue,e.textContent=o,document.head.appendChild(e)}var We=require("@seatlayer/core");function Ge(o){return o?o.mode:"open"}function Xe(o,e,t){switch(o){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 Qe(o){return new Date(o-new Date().getTimezoneOffset()*6e4).toISOString().slice(0,16)}function Ze(o){if(typeof o=="string"){let e=document.querySelector(o);if(!e)throw new Error(`seatmanager: container "${o}" not found`);return e}if(!(o instanceof HTMLElement))throw new Error("seatmanager: container must be a CSS selector or an HTMLElement");return o}function Ae(o){if(!o.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 le(o){return o==="blocked"?"not_for_sale":o}var Je=[{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 Ee(o){let e=o??{};return{"--slm-bg":e.background??"#0e1017","--slm-surface":"#181b24","--slm-text":"#eef1f7","--slm-muted":"#8b93a7","--slm-line":"rgba(255,255,255,.09)","--slm-accent":e.accent??"#6e7bff","--slm-accent-ink":e.accentInk??"#ffffff","--slm-font":"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif","--slm-radius":"14px"}}function Me(o,e){let t=Math.max(0,Math.round((e-o)/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 Z(o,e){return(0,We.formatMoney)(o,e,{maximumFractionDigits:0,fallback:(t,s)=>`${s} ${Math.round(t).toLocaleString()}`})}function u(o){return String(o??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}var et=require("@seatlayer/core");function Ie(o){return Object.entries(o).filter(([,e])=>e.mode==="closed").map(([e])=>e)}function re(o){let e=o.sectionsBase;if(!e)return{rows:[],hiddenSections:0,closedSections:0};let t=o.doc?.zones??[],s=new Map,n=[];for(let d of e.sections)if(d.zone&&t.some(c=>c.id===d.zone)){let c=s.get(d.zone)??[];c.push(d),s.set(d.zone,c)}else n.push(d);let i=[],a=0,l=0,r=(d,c,p,g=!1)=>{let w=o.availabilityRules[c.id]??null,b=o.effectiveClosed.has(c.id)||g,m=o.effectiveHidden.has(c.id)||p&&!b;d==="section"&&m&&(a+=1),d==="section"&&b&&(l+=1),i.push({kind:d,id:c.id,label:c.label,seatCount:c.seatCount,seatLabels:c.seatLabels,rule:w,hidden:m,closed:b,followsZone:d==="section"&&p})};for(let d of t){let c=s.get(d.id);if(!c||!c.length)continue;let p={id:d.id,label:d.label||"Zone",seatCount:c.reduce((b,m)=>b+m.seatCount,0),seatLabels:c.flatMap(b=>b.seatLabels)},g=!!o.availabilityRules[d.id],w=o.availabilityRules[d.id]?.mode==="closed";r("zone",p,!1);for(let b of c)r("section",b,g,w)}for(let d of n)r("section",d,!1);if(e.ungrouped){let d=e.ungrouped;r("section",{id:et.UNGROUPED_ID,label:d.label,seatCount:d.seatCount,seatLabels:d.seatLabels},!1)}return{rows:i,hiddenSections:a,closedSections:l}}function tt(o,e){let t=Ge(o.rule),s=`slm-availrow${o.kind==="zone"?" zone":""}${o.hidden?" hidden":""}${o.closed?" closed":""}`,n=e?" disabled":"",i=(c,p)=>`<option value="${c}"${t===c?" selected":""}>${p}</option>`,a=o.followsZone?'<span class="slm-availfollows">Follows zone</span>':`<span class="slm-availselwrap">
964
- <select class="slm-select slm-availmode${t!=="open"?" on":""}" data-avail-id="${u(o.id)}"${n} aria-label="Availability for ${u(o.label)}">
999
+ `;function Ke(){if(typeof document>"u"||document.getElementById(Ne))return;let l=document.createElement("style");l.id=Ne,l.textContent=At,document.head.appendChild(l)}function Ye(l){if(typeof document>"u"||document.getElementById(Ue))return;let e=document.createElement("style");e.id=Ue,e.textContent=l,document.head.appendChild(e)}var We=require("@seatlayer/core");function Ge(l){return l?l.mode:"open"}function Xe(l,e,t){switch(l){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 Qe(l){return new Date(l-new Date().getTimezoneOffset()*6e4).toISOString().slice(0,16)}function Ze(l){if(typeof l=="string"){let e=document.querySelector(l);if(!e)throw new Error(`seatmanager: container "${l}" not found`);return e}if(!(l instanceof HTMLElement))throw new Error("seatmanager: container must be a CSS selector or an HTMLElement");return l}function Ae(l){if(!l.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 le(l){return l==="blocked"?"not_for_sale":l}var Je=[{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 Ee(l){let e=l??{};return{"--slm-bg":e.background??"#0e1017","--slm-surface":"#181b24","--slm-text":"#eef1f7","--slm-muted":"#8b93a7","--slm-line":"rgba(255,255,255,.09)","--slm-accent":e.accent??"#6e7bff","--slm-accent-ink":e.accentInk??"#ffffff","--slm-font":"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif","--slm-radius":"14px"}}function Me(l,e){let t=Math.max(0,Math.round((e-l)/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 Z(l,e){return(0,We.formatMoney)(l,e,{maximumFractionDigits:0,fallback:(t,s)=>`${s} ${Math.round(t).toLocaleString()}`})}function u(l){return String(l??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}var et=require("@seatlayer/core");function Ie(l){return Object.entries(l).filter(([,e])=>e.mode==="closed").map(([e])=>e)}function re(l){let e=l.sectionsBase;if(!e)return{rows:[],hiddenSections:0,closedSections:0};let t=l.doc?.zones??[],s=new Map,n=[];for(let d of e.sections)if(d.zone&&t.some(c=>c.id===d.zone)){let c=s.get(d.zone)??[];c.push(d),s.set(d.zone,c)}else n.push(d);let i=[],a=0,o=0,r=(d,c,p,b=!1)=>{let y=l.availabilityRules[c.id]??null,g=l.effectiveClosed.has(c.id)||b,m=l.effectiveHidden.has(c.id)||p&&!g;d==="section"&&m&&(a+=1),d==="section"&&g&&(o+=1),i.push({kind:d,id:c.id,label:c.label,seatCount:c.seatCount,seatLabels:c.seatLabels,rule:y,hidden:m,closed:g,followsZone:d==="section"&&p})};for(let d of t){let c=s.get(d.id);if(!c||!c.length)continue;let p={id:d.id,label:d.label||"Zone",seatCount:c.reduce((g,m)=>g+m.seatCount,0),seatLabels:c.flatMap(g=>g.seatLabels)},b=!!l.availabilityRules[d.id],y=l.availabilityRules[d.id]?.mode==="closed";r("zone",p,!1);for(let g of c)r("section",g,b,y)}for(let d of n)r("section",d,!1);if(e.ungrouped){let d=e.ungrouped;r("section",{id:et.UNGROUPED_ID,label:d.label,seatCount:d.seatCount,seatLabels:d.seatLabels},!1)}return{rows:i,hiddenSections:a,closedSections:o}}function tt(l,e){let t=Ge(l.rule),s=`slm-availrow${l.kind==="zone"?" zone":""}${l.hidden?" hidden":""}${l.closed?" closed":""}`,n=e?" disabled":"",i=(c,p)=>`<option value="${c}"${t===c?" selected":""}>${p}</option>`,a=l.followsZone?'<span class="slm-availfollows">Follows zone</span>':`<span class="slm-availselwrap">
1000
+ <select class="slm-select slm-availmode${t!=="open"?" on":""}" data-avail-id="${u(l.id)}"${n} aria-label="Availability for ${u(l.label)}">
965
1001
  ${i("open","Open \u2014 on sale")}
966
1002
  ${i("closed","Closed \u2014 visible, not on sale")}
967
1003
  ${i("hidden","Hidden \u2014 off the buyer map")}
968
1004
  ${i("timed","Reveal at a time")}
969
1005
  ${i("threshold","Auto-reveal at % sold")}
970
1006
  </select>
971
- </span>`,l="";if(!o.followsZone&&t==="timed"){let c=o.rule?.revealAt?u(Qe(o.rule.revealAt)):"";l=`<div class="slm-availdetail">
972
- <input type="datetime-local" class="slm-input" data-avail-reveal="${u(o.id)}" value="${c}"${n} aria-label="Reveal time for ${u(o.label)}" />
973
- </div>`}else if(!o.followsZone&&t==="threshold"){let c=o.rule?.thresholdPct??80;l=`<div class="slm-availdetail">
1007
+ </span>`,o="";if(!l.followsZone&&t==="timed"){let c=l.rule?.revealAt?u(Qe(l.rule.revealAt)):"";o=`<div class="slm-availdetail">
1008
+ <input type="datetime-local" class="slm-input" data-avail-reveal="${u(l.id)}" value="${c}"${n} aria-label="Reveal time for ${u(l.label)}" />
1009
+ </div>`}else if(!l.followsZone&&t==="threshold"){let c=l.rule?.thresholdPct??80;o=`<div class="slm-availdetail">
974
1010
  <span class="slm-availpctlabel">Reveal at</span>
975
- <input type="number" min="1" max="100" class="slm-input slm-availpct" data-avail-pct="${u(o.id)}" value="${u(c)}"${n} aria-label="Percent sold to reveal ${u(o.label)}" />
1011
+ <input type="number" min="1" max="100" class="slm-input slm-availpct" data-avail-pct="${u(l.id)}" value="${u(c)}"${n} aria-label="Percent sold to reveal ${u(l.label)}" />
976
1012
  <span class="slm-availpctlabel">% sold</span>
977
- </div>`}let r=o.closed?'<span class="slm-availbadge closed">Closed</span>':o.hidden?'<span class="slm-availbadge hidden">Hidden</span>':"",d=o.kind==="zone"?`<span class="slm-availcaret" aria-hidden="true">${o.hidden?"\u25B8":"\u25BE"}</span>`:"";return`<div class="${s}">
1013
+ </div>`}let r=l.closed?'<span class="slm-availbadge closed">Closed</span>':l.hidden?'<span class="slm-availbadge hidden">Hidden</span>':"",d=l.kind==="zone"?`<span class="slm-availcaret" aria-hidden="true">${l.hidden?"\u25B8":"\u25BE"}</span>`:"";return`<div class="${s}">
978
1014
  <div class="slm-availhead">
979
- <span class="slm-availlabel">${d}${u(o.label)}</span>
1015
+ <span class="slm-availlabel">${d}${u(l.label)}</span>
980
1016
  ${r}
981
- <span class="slm-availcount">${o.seatCount.toLocaleString()}</span>
1017
+ <span class="slm-availcount">${l.seatCount.toLocaleString()}</span>
982
1018
  ${a}
983
1019
  </div>
984
- ${l}
985
- </div>`}var Nt="https://api.seatlayer.io",Ce=80,Ut=16,ut=4,Re=class{constructor(e){this.els={};this.renderer=null;this.doc=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.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();if(s==="m")this.setMode("view");else if(s==="i")this.setMode("inspect");else if(s==="x")this.setMode("select");else if(s==="l")this.setMode("filterSections");else if(s==="b")this.setMode("block");else if(s==="s")this.setMode("sections");else if(s==="g")if(this.categoryCanManage)this.setMode("categories");else return;else if(s==="t")if(this.tableCanManage)this.setMode("tables");else return;else if(s==="c"){if(!this.channelCaps.view)return;this.setMode("channels")}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 n=t?.closest("[data-feed-id]");n?.dataset.feedId&&this.locateActivity(n.dataset.feedId)};this.sectionOptions=[];Ae(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.followLive=e.followLive??!1,this.currency=e.currency??"USD",this.tokenExpiresAt=e.tokenExpiresAt??null,this.api=new U(e.apiBase??Nt,e.token),this.organizerAssetUrls=new oe(this.key,(t,s)=>this.withAuthRetry(()=>this.api.asset(t,s))),this.host=Ze(e.container)}assertSelectionOptions(e,t){let s=n=>n===void 0||Number.isInteger(n)&&n>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(){Ke(),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();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){e==="channels"&&!this.channelCaps.view&&(e="view"),e==="categories"&&!this.categoryCanManage&&(e="view"),e==="tables"&&!this.tableCanManage&&(e="view"),e==="channels"&&!this.channels&&this.ensureChannels();let t=e!==this.mode,s=this.mode==="channels",n=this.mode==="filterSections";this.mode=e,!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(),n&&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 n=new Set(t);s={view:n.has("event:channels:view"),manage:n.has("event:channels:view")&&n.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 Promise.resolve().then(()=>(ze(),pt));if(this.closed||!this.channelCaps.view||(this.channels||(Ye(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 n=e.get(s.rowId);if(!n||n.type!=="row"&&n.type!=="table")continue;let i=s.logicalRowId??s.rowId,a=this.sectionByObject.get(s.rowId)??L.UNGROUPED_ID,l=t.get(i)??{id:i,label:n.type==="row"?n.segmentedRow?.displayLabel??n.displayLabel??n.label:n.displayLabel??n.label,sectionId:a,sectionLabel:this.sectionLabelById.get(a)??"Other seats",labels:[]};l.labels.push(s.label),t.set(i,l)}return[...t.values()].sort((s,n)=>s.sectionLabel.localeCompare(n.sectionLabel,void 0,{numeric:!0,sensitivity:"base"})||s.label.localeCompare(n.label,void 0,{numeric:!0,sensitivity:"base"}))},categories:()=>(this.doc?.categories??[]).map(e=>({key:e.key,label:e.label??e.key,color:e.color})),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)??L.UNGROUPED_ID;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){if(this.opts.theme=e,!!this.root)for(let[t,s]of Object.entries(Ee(e)))this.root.style.setProperty(t,s)}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){Ae(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(),n=Math.min(12e4,Math.max(3e4,s*.2)),i=Math.max(0,s-n);this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},i)}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(i=>this.status.get(i)==="free");if(!s.length)return;let n=t.releaseAt??this.releaseAt??void 0;this.setSeatsLocal(s,"blocked");try{await this.api.block(this.key,s,{...t,releaseAt:n}),this.clearSelection(),this.done("block",s,n?`Blocked ${s.length} \u2014 auto-release ${new Date(n).toLocaleString()}.`:`Blocked ${s.length} seat${s.length===1?"":"s"}.`)}catch(i){this.setSeatsLocal(s,"free"),this.toastErr(i instanceof f&&i.status===409?"Some seats were just taken. Try again.":"Couldn't block those seats."),this.opts.onError?.(i)}}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(n=>this.status.get(n)==="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(n){this.setSeatsLocal(s,"booked"),this.toastErr("Couldn't release that booked inventory. Check the booking reference."),this.opts.onError?.(n)}}}async setCategory(e,t){let s=this.doc?.categories.find(i=>i.key===e),n=[...new Set(t??this.selectionLabels())].filter(i=>this.labelToSeat.has(i));if(!(!s||!n.length))try{let i=await this.withAuthRetry(()=>this.api.setCategory(this.key,n,e)),a={};for(let l of i.labels){let r=this.labelToSeat.get(l),d=this.labelToId.get(l);r&&(r.categoryKey=e),d&&(a[d]=e)}this.renderer?.setSeatCategories?.(a),this.clearSelection(),this.done("setCategory",i.labels,`Assigned ${i.labels.length.toLocaleString()} object${i.labels.length===1?"":"s"} to ${s.label??s.key}.`)}catch(i){this.toastErr("Couldn't update those event categories."),this.opts.onError?.(i)}}async setTableBooking(e,t,s={}){let n=[...new Set(e)].filter(Boolean);if(!(!n.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 i=await this.withAuthRetry(()=>this.api.setTableBooking(this.key,n,t,s));await this.reloadEventChart(),this.done("setTableBooking",i.tableIds,`Updated ${i.tableIds.length.toLocaleString()} table${i.tableIds.length===1?"":"s"} to ${t==="individual"?"per-chair":t==="whole"?"whole-table":"flexible-group"} booking.`)}catch(i){let a=i instanceof f&&i.code==="table_inventory_in_use";this.toastErr(a?"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?.(i)}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(),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(a=>a.label===t);if(!s.length)throw new Error(`Unknown event section: ${e}`);let n=t!==this.filteredSectionLabel;this.filteredSectionLabel=t,this.mode==="filterSections"&&(this.applyFilteredSectionCanvas(s),this.renderFilterSectionsRail());let i=s.map(({id:a,label:l,seatCount:r,zone:d})=>({id:a,label:l,seatCount:r,...d?{zone:d}:{}}));return n&&this.opts.onFilteredSectionChange?.(i),i}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:n})=>({id:e,label:t,seatCount:s,...n?{zone:n}:{}})):[]}selectByLabels(e){let t=e;if(this.mode==="select"){let s=new Set(this.selectionLabels()),n=this.selectionCap(),i=[...new Set(e)].filter(l=>!s.has(l)).map(l=>this.labelToSeat.get(l)).filter(l=>!!l&&this.canSelectObject(l)),a=Math.max(0,n-s.size);i.length>a&&this.opts.onSelectionLimit?.(n),t=i.slice(0,a).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.closed=!0,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.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.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 L.SeatmapRenderer(this.mapHost,{manageMode:!0,marqueeSelect:e,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(n=>n.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.doc),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,marqueeSelect:e,maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses()}),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(0,L.expandChart)(e))this.labelToId.set(t.label,t.id),this.labelToSeat.set(t.label,t),this.allIds.push(t.id);for(let t of(0,L.gaAreasOf)(e))for(let s of(0,L.gaUnitLabels)(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,n]of this.status.entries()){let i=this.labelToId.get(s);i&&t[le(n)].push(i)}["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,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.applySnapshot(s.seats,typeof s.default=="string"?s.default:void 0);else if(Array.isArray(s.changes)){let n=[],i=new Map;for(let l of s.changes){let r=["free","held","booked","blocked"].includes(l.status)?l.status:"free",d=this.status.get(l.label)??"free";if(d===r)continue;this.setStatusLabel(l.label,r,d);let c=this.labelToId.get(l.label);c&&(this.renderer?.setStatus([c],le(r)),n.push(c));let p=this.verbFor(d,r),g=`${p}:${r}`,w=i.get(g)??{labels:[],verb:p,status:r};w.labels.push(l.label),i.set(g,w)}for(let l of i.values()){let r=this.pushActivity(l.labels,l.verb,l.status);r&&this.paintSpatialActivity(r)}n.length&&(this.lastSyncedAt=Date.now(),this.afterPaint());let a=typeof s.bookedValue?.gross=="number"?s.bookedValue.gross:s.revenue?.gross;typeof a=="number"&&Number.isFinite(a)&&this.applyLiveGross(a),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))}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=i=>["free","held","booked","blocked"].includes(i)?i:"free",n=new Map;if(t!==void 0){let i=s(t);for(let a of this.knownLabels())n.set(a,i)}for(let[i,a]of Object.entries(e))n.set(i,s(a));this.status=n,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 n of e){this.setStatusLabel(n,t);let i=this.labelToId.get(n);i&&s.push(i)}s.length&&this.renderer?.setStatus(s,le(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 n of e){let i=this.labelToSeat.get(n);if(!i)continue;let a=this.sectionByObject.get(i.rowId);a&&a!==L.UNGROUPED_ID&&t.add(a)}let s=[...t];return{ids:s,labels:s.map(n=>this.sectionLabelById.get(n)??n)}}pulseSeatLabels(e,t){let s=this.activityColor(t);for(let n of e.slice(0,Ut)){let i=this.labelToId.get(n);i&&this.renderer?.flashSeat(i,s)}}paintSpatialActivity(e){let t=e.sectionIds??this.sectionsForLabels(e.labels).ids,s=this.renderer?.getFocusedSection()??null,n=this.followLive&&t.length===1&&(e.status==="held"||e.status==="booked");if(n&&s===t[0]){this.pulseSeatLabels(e.labels,e.status);return}if(n){this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=setTimeout(()=>{this.followLiveTimer=null,this.renderer?.focusSection(t[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(e.labels,e.status)},520)},220);return}if(!s&&t.length){let i=this.activityColor(e.status);for(let a of t.slice(0,ut))this.renderer?.flashSection(a,i);return}(!t.length||s&&t.includes(s))&&this.pulseSeatLabels(e.labels,e.status)}locateSection(e){this.renderer?.focusSection(e)}locateActivity(e){let t=this.feed.find(n=>n.id===e);if(!t)return;let s=t.sectionIds??this.sectionsForLabels(t.labels).ids;if(this.followSeatTimer&&clearTimeout(this.followSeatTimer),s.length===1){this.locateSection(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 n=this.activityColor(t.status);for(let i of s.slice(0,ut))this.renderer?.flashSection(i,n)}else this.pulseSeatLabels(t.labels,t.status)},280)}showLiveEvent(e){let t=this.els.liveevent;if(!t)return;let s=e.sectionLabels??[],n=s.length===1?s[0]:s.length>1?`${s.length} sections`:e.label,i=e.count===1?"seat":"seats";t.innerHTML=`<span class="slm-liveeventdot" style="background:${this.activityColor(e.status)}"></span>
1020
+ ${o}
1021
+ </div>`}var Nt="https://api.seatlayer.io",Ce=80,Ut=16,ut=4,Re=class{constructor(e){this.els={};this.renderer=null;this.doc=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.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();if(s==="m")this.setMode("view");else if(s==="i")this.setMode("inspect");else if(s==="x")this.setMode("select");else if(s==="l")this.setMode("filterSections");else if(s==="b")this.setMode("block");else if(s==="s")this.setMode("sections");else if(s==="g")if(this.categoryCanManage)this.setMode("categories");else return;else if(s==="t")if(this.tableCanManage)this.setMode("tables");else return;else if(s==="c"){if(!this.channelCaps.view)return;this.setMode("channels")}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 n=t?.closest("[data-feed-id]");n?.dataset.feedId&&this.locateActivity(n.dataset.feedId)};this.sectionOptions=[];Ae(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.followLive=e.followLive??!1,this.currency=e.currency??"USD",this.tokenExpiresAt=e.tokenExpiresAt??null,this.api=new U(e.apiBase??Nt,e.token),this.organizerAssetUrls=new oe(this.key,(t,s)=>this.withAuthRetry(()=>this.api.asset(t,s))),this.host=Ze(e.container)}assertSelectionOptions(e,t){let s=n=>n===void 0||Number.isInteger(n)&&n>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(){Ke(),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();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){e==="channels"&&!this.channelCaps.view&&(e="view"),e==="categories"&&!this.categoryCanManage&&(e="view"),e==="tables"&&!this.tableCanManage&&(e="view"),e==="channels"&&!this.channels&&this.ensureChannels();let t=e!==this.mode,s=this.mode==="channels",n=this.mode==="filterSections";this.mode=e,!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(),n&&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 n=new Set(t);s={view:n.has("event:channels:view"),manage:n.has("event:channels:view")&&n.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 Promise.resolve().then(()=>(ze(),pt));if(this.closed||!this.channelCaps.view||(this.channels||(Ye(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 n=e.get(s.rowId);if(!n||n.type!=="row"&&n.type!=="table")continue;let i=s.logicalRowId??s.rowId,a=this.sectionByObject.get(s.rowId)??L.UNGROUPED_ID,o=t.get(i)??{id:i,label:n.type==="row"?n.segmentedRow?.displayLabel??n.displayLabel??n.label:n.displayLabel??n.label,sectionId:a,sectionLabel:this.sectionLabelById.get(a)??"Other seats",labels:[]};o.labels.push(s.label),t.set(i,o)}return[...t.values()].sort((s,n)=>s.sectionLabel.localeCompare(n.sectionLabel,void 0,{numeric:!0,sensitivity:"base"})||s.label.localeCompare(n.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)??L.UNGROUPED_ID;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){if(this.opts.theme=e,!!this.root)for(let[t,s]of Object.entries(Ee(e)))this.root.style.setProperty(t,s)}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){Ae(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(),n=Math.min(12e4,Math.max(3e4,s*.2)),i=Math.max(0,s-n);this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},i)}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(i=>this.status.get(i)==="free");if(!s.length)return;let n=t.releaseAt??this.releaseAt??void 0;this.setSeatsLocal(s,"blocked");try{await this.api.block(this.key,s,{...t,releaseAt:n}),this.clearSelection(),this.done("block",s,n?`Blocked ${s.length} \u2014 auto-release ${new Date(n).toLocaleString()}.`:`Blocked ${s.length} seat${s.length===1?"":"s"}.`)}catch(i){this.setSeatsLocal(s,"free"),this.toastErr(i instanceof f&&i.status===409?"Some seats were just taken. Try again.":"Couldn't block those seats."),this.opts.onError?.(i)}}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(n=>this.status.get(n)==="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(n){this.setSeatsLocal(s,"booked"),this.toastErr("Couldn't release that booked inventory. Check the booking reference."),this.opts.onError?.(n)}}}async setCategory(e,t){let s=this.doc?.categories.find(i=>i.key===e),n=[...new Set(t??this.selectionLabels())].filter(i=>this.labelToSeat.has(i));if(!(!s||!n.length))try{let i=await this.withAuthRetry(()=>this.api.setCategory(this.key,n,e)),a={};for(let o of i.labels){let r=this.labelToSeat.get(o),d=this.labelToId.get(o);r&&(r.categoryKey=e),d&&(a[d]=e)}this.renderer?.setSeatCategories?.(a),this.clearSelection(),this.done("setCategory",i.labels,`Assigned ${i.labels.length.toLocaleString()} object${i.labels.length===1?"":"s"} to ${s.label??s.key}.`)}catch(i){this.toastErr("Couldn't update those event categories."),this.opts.onError?.(i)}}async setTableBooking(e,t,s={}){let n=[...new Set(e)].filter(Boolean);if(!(!n.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 i=await this.withAuthRetry(()=>this.api.setTableBooking(this.key,n,t,s));await this.reloadEventChart(),this.done("setTableBooking",i.tableIds,`Updated ${i.tableIds.length.toLocaleString()} table${i.tableIds.length===1?"":"s"} to ${t==="individual"?"per-chair":t==="whole"?"whole-table":"flexible-group"} booking.`)}catch(i){let a=i instanceof f&&i.code==="table_inventory_in_use";this.toastErr(a?"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?.(i)}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(),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(a=>a.label===t);if(!s.length)throw new Error(`Unknown event section: ${e}`);let n=t!==this.filteredSectionLabel;this.filteredSectionLabel=t,this.mode==="filterSections"&&(this.applyFilteredSectionCanvas(s),this.renderFilterSectionsRail());let i=s.map(({id:a,label:o,seatCount:r,zone:d})=>({id:a,label:o,seatCount:r,...d?{zone:d}:{}}));return n&&this.opts.onFilteredSectionChange?.(i),i}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:n})=>({id:e,label:t,seatCount:s,...n?{zone:n}:{}})):[]}selectByLabels(e){let t=e;if(this.mode==="select"){let s=new Set(this.selectionLabels()),n=this.selectionCap(),i=[...new Set(e)].filter(o=>!s.has(o)).map(o=>this.labelToSeat.get(o)).filter(o=>!!o&&this.canSelectObject(o)),a=Math.max(0,n-s.size);i.length>a&&this.opts.onSelectionLimit?.(n),t=i.slice(0,a).map(o=>o.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.closed=!0,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.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.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 L.SeatmapRenderer(this.mapHost,{manageMode:!0,marqueeSelect:e,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(n=>n.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.doc),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,marqueeSelect:e,maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses()}),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(0,L.expandChart)(e))this.labelToId.set(t.label,t.id),this.labelToSeat.set(t.label,t),this.allIds.push(t.id);for(let t of(0,L.gaAreasOf)(e))for(let s of(0,L.gaUnitLabels)(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,n]of this.status.entries()){let i=this.labelToId.get(s);i&&t[le(n)].push(i)}["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,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.applySnapshot(s.seats,typeof s.default=="string"?s.default:void 0);else if(Array.isArray(s.changes)){let n=[],i=new Map;for(let o of s.changes){let r=["free","held","booked","blocked"].includes(o.status)?o.status:"free",d=this.status.get(o.label)??"free";if(d===r)continue;this.setStatusLabel(o.label,r,d);let c=this.labelToId.get(o.label);c&&(this.renderer?.setStatus([c],le(r)),n.push(c));let p=this.verbFor(d,r),b=`${p}:${r}`,y=i.get(b)??{labels:[],verb:p,status:r};y.labels.push(o.label),i.set(b,y)}for(let o of i.values()){let r=this.pushActivity(o.labels,o.verb,o.status);r&&this.paintSpatialActivity(r)}n.length&&(this.lastSyncedAt=Date.now(),this.afterPaint());let a=typeof s.bookedValue?.gross=="number"?s.bookedValue.gross:s.revenue?.gross;typeof a=="number"&&Number.isFinite(a)&&this.applyLiveGross(a),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))}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=i=>["free","held","booked","blocked"].includes(i)?i:"free",n=new Map;if(t!==void 0){let i=s(t);for(let a of this.knownLabels())n.set(a,i)}for(let[i,a]of Object.entries(e))n.set(i,s(a));this.status=n,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 n of e){this.setStatusLabel(n,t);let i=this.labelToId.get(n);i&&s.push(i)}s.length&&this.renderer?.setStatus(s,le(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 n of e){let i=this.labelToSeat.get(n);if(!i)continue;let a=this.sectionByObject.get(i.rowId);a&&a!==L.UNGROUPED_ID&&t.add(a)}let s=[...t];return{ids:s,labels:s.map(n=>this.sectionLabelById.get(n)??n)}}pulseSeatLabels(e,t){let s=this.activityColor(t);for(let n of e.slice(0,Ut)){let i=this.labelToId.get(n);i&&this.renderer?.flashSeat(i,s)}}paintSpatialActivity(e){let t=e.sectionIds??this.sectionsForLabels(e.labels).ids,s=this.renderer?.getFocusedSection()??null,n=this.followLive&&t.length===1&&(e.status==="held"||e.status==="booked");if(n&&s===t[0]){this.pulseSeatLabels(e.labels,e.status);return}if(n){this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=setTimeout(()=>{this.followLiveTimer=null,this.renderer?.focusSection(t[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(e.labels,e.status)},520)},220);return}if(!s&&t.length){let i=this.activityColor(e.status);for(let a of t.slice(0,ut))this.renderer?.flashSection(a,i);return}(!t.length||s&&t.includes(s))&&this.pulseSeatLabels(e.labels,e.status)}locateSection(e){this.renderer?.focusSection(e)}locateActivity(e){let t=this.feed.find(n=>n.id===e);if(!t)return;let s=t.sectionIds??this.sectionsForLabels(t.labels).ids;if(this.followSeatTimer&&clearTimeout(this.followSeatTimer),s.length===1){this.locateSection(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 n=this.activityColor(t.status);for(let i of s.slice(0,ut))this.renderer?.flashSection(i,n)}else this.pulseSeatLabels(t.labels,t.status)},280)}showLiveEvent(e){let t=this.els.liveevent;if(!t)return;let s=e.sectionLabels??[],n=s.length===1?s[0]:s.length>1?`${s.length} sections`:e.label,i=e.count===1?"seat":"seats";t.innerHTML=`<span class="slm-liveeventdot" style="background:${this.activityColor(e.status)}"></span>
986
1022
  <span class="slm-liveeventcopy">${u(n)} \xB7 ${e.count.toLocaleString()} ${i} ${u(e.verb)}</span>
987
- <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 n=Number.isFinite(s.bookedValue)?s.bookedValue:s.bookedRevenue;return t+(Number.isFinite(n)?n: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),n=s.bookedValue??s.revenue??{gross:0,bySection:[]},i=(n.bySection??[]).map(r=>{let d=Number.isFinite(r.bookedValue)?r.bookedValue:r.bookedRevenue;return{...r,bookedValue:d??0,bookedRevenue:d??0}}),a={...n,bySection:i},l={...s,bookedValue:a,revenue:a};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 r={...l.bookedValue,gross:this.liveGross.value};l={...l,bookedValue:r,revenue:r}}else this.liveGross=null;this.controlRoomSnapshot=l,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.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],n=this.controlRoomSnapshot?.event?.seatTotal,i={free:s("free"),held:s("held"),booked:s("booked"),blocked:s("blocked"),total:Number.isFinite(n)?n:this.unitTotal(),capacityPct:0,sellThroughPct:0,bookedValue:this.authoritativeGrossRevenue,grossRevenue:this.authoritativeGrossRevenue,bookedValueStatus:this.revenueStatus,revenueStatus:this.revenueStatus,currency:this.currency};i.capacityPct=i.total?Math.round(i.booked/i.total*100):0;let a=i.total-i.blocked;return i.sellThroughPct=a>0?Math.round(i.booked/a*100):0,i}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":"released":t}pushActivity(e,t,s,n=Date.now()){let i=e[0];if(!i)return null;let a=this.sectionsForLabels(e),l={id:`${i}:${n}:${Math.random().toString(36).slice(2,6)}`,at:n,label:i,labels:[...e],count:e.length,verb:t,status:s,sectionIds:a.ids,sectionLabels:a.labels};return this.feed.unshift(l),this.feed.length>Ce&&(this.feed.length=Ce),this.mode==="view"&&this.paintFeed(),this.showLiveEvent(l),this.opts.onActivity?.(l),l}seedFeed(e){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 n of e){let i=n.labels[0];if(!i)continue;let a=this.sectionsForLabels(n.labels),l={id:`log:${n.id}`,at:n.at,label:i,labels:[...n.labels],count:n.labels.length,verb:t[n.action]??n.action,status:s[n.action]??"free",sectionIds:a.ids,sectionLabels:a.labels};this.feed.push(l),this.opts.onActivity?.(l)}this.feed.sort((n,i)=>i.at-n.at),this.feed.length>Ce&&(this.feed.length=Ce),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,n=t==="free"||s||this.selectableObjectLabels.has(e.label);if(!this.opts.isObjectSelectable)return n;try{return this.opts.isObjectSelectable(e,n)===!0}catch(i){return this.opts.onError?.(i),!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[n,i]of t)this.lastSelectionLabels.has(n)||this.opts.onObjectSelected?.(i);for(let n of this.lastSelectionLabels)if(!t.has(n)){let i=this.labelToSeat.get(n);i&&this.opts.onObjectDeselected?.(i)}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.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");let t=Ee(this.opts.theme);for(let[n,i]of Object.entries(t))e.style.setProperty(n,i);e.innerHTML=`
1023
+ <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 n=Number.isFinite(s.bookedValue)?s.bookedValue:s.bookedRevenue;return t+(Number.isFinite(n)?n: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),n=s.bookedValue??s.revenue??{gross:0,bySection:[]},i=(n.bySection??[]).map(r=>{let d=Number.isFinite(r.bookedValue)?r.bookedValue:r.bookedRevenue;return{...r,bookedValue:d??0,bookedRevenue:d??0}}),a={...n,bySection:i},o={...s,bookedValue:a,revenue:a};if(e===this.revenueRequest){if(this.livePresence&&this.livePresence.at>=t?o={...o,presence:this.livePresence.value}:this.livePresence=null,this.liveGross&&this.liveGross.at>=t){let r={...o.bookedValue,gross:this.liveGross.value};o={...o,bookedValue:r,revenue:r}}else this.liveGross=null;this.controlRoomSnapshot=o,this.rebaseServerTotals(o),this.lastSyncedAt=Date.now(),this.authoritativeGrossRevenue=o.bookedValue.gross,this.authoritativeCurrency=o.currency,this.currency=o.currency,this.revenueStatus="current",this.recomputeTallies(),this.applyHeatOverlay(),this.paintMonitorInsights(),this.opts.onControlRoom?.(o)}return o}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=o=>t?Math.max(0,t.server[o]+(e[o]-t.client[o])):e[o],n=this.controlRoomSnapshot?.event?.seatTotal,i={free:s("free"),held:s("held"),booked:s("booked"),blocked:s("blocked"),total:Number.isFinite(n)?n:this.unitTotal(),capacityPct:0,sellThroughPct:0,bookedValue:this.authoritativeGrossRevenue,grossRevenue:this.authoritativeGrossRevenue,bookedValueStatus:this.revenueStatus,revenueStatus:this.revenueStatus,currency:this.currency};i.capacityPct=i.total?Math.round(i.booked/i.total*100):0;let a=i.total-i.blocked;return i.sellThroughPct=a>0?Math.round(i.booked/a*100):0,i}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":"released":t}pushActivity(e,t,s,n=Date.now()){let i=e[0];if(!i)return null;let a=this.sectionsForLabels(e),o={id:`${i}:${n}:${Math.random().toString(36).slice(2,6)}`,at:n,label:i,labels:[...e],count:e.length,verb:t,status:s,sectionIds:a.ids,sectionLabels:a.labels};return this.feed.unshift(o),this.feed.length>Ce&&(this.feed.length=Ce),this.mode==="view"&&this.paintFeed(),this.showLiveEvent(o),this.opts.onActivity?.(o),o}seedFeed(e){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 n of e){let i=n.labels[0];if(!i)continue;let a=this.sectionsForLabels(n.labels),o={id:`log:${n.id}`,at:n.at,label:i,labels:[...n.labels],count:n.labels.length,verb:t[n.action]??n.action,status:s[n.action]??"free",sectionIds:a.ids,sectionLabels:a.labels};this.feed.push(o),this.opts.onActivity?.(o)}this.feed.sort((n,i)=>i.at-n.at),this.feed.length>Ce&&(this.feed.length=Ce),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,n=t==="free"||s||this.selectableObjectLabels.has(e.label);if(!this.opts.isObjectSelectable)return n;try{return this.opts.isObjectSelectable(e,n)===!0}catch(i){return this.opts.onError?.(i),!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[n,i]of t)this.lastSelectionLabels.has(n)||this.opts.onObjectSelected?.(i);for(let n of this.lastSelectionLabels)if(!t.has(n)){let i=this.labelToSeat.get(n);i&&this.opts.onObjectDeselected?.(i)}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.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");let t=Ee(this.opts.theme);for(let[n,i]of Object.entries(t))e.style.setProperty(n,i);e.innerHTML=`
988
1024
  <div class="slm-bar">
989
1025
  <div class="slm-modes" data-ref="modes" role="tablist" aria-label="Manager tools">
990
1026
  <button class="slm-mode" role="tab" data-mode="view" title="Monitor (M)" aria-keyshortcuts="M">Monitor</button>
@@ -1019,7 +1055,7 @@
1019
1055
  <aside class="slm-rail"><div class="slm-railscroll" data-ref="rail"></div></aside>
1020
1056
  </div>
1021
1057
  <div class="slm-toast" data-ref="toast"></div>
1022
- `,this.host.appendChild(e),this.root=e,this.updateContainerLayout(),typeof ResizeObserver<"u"&&(this.layoutObserver=new ResizeObserver(()=>this.updateContainerLayout()),this.layoutObserver.observe(e));let s=n=>e.querySelector(`[data-ref="${n}"]`);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(n=>n.addEventListener("click",()=>this.setMode(n.dataset.mode))),this.els.tools.addEventListener("change",()=>this.setMode(this.els.tools.value)),this.els.zfit.addEventListener("click",()=>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()}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(c=>c.id)),s=this.filterableSections().filter(c=>!t.has(c.id)).map(c=>c.id);this.renderer.clearSectionFocus(),this.renderer.setClosedSections(null),this.renderer.setDimmedSections(s);let n=e.flatMap(c=>c.seatLabels).map(c=>this.labelToSeat.get(c)).filter(c=>!!c&&Number.isFinite(c.x)&&Number.isFinite(c.y));if(!n.length){this.renderer.focusRegion(e[0].id);return}let i=Math.min(...n.map(c=>c.x)),a=Math.min(...n.map(c=>c.y)),l=Math.max(...n.map(c=>c.x)),r=Math.max(...n.map(c=>c.y)),d=Math.max(40,Math.max(l-i,r-a)*.08);this.renderer.focusRegion({x:i-d,y:a-d,width:Math.max(1,l-i)+d*2,height:Math.max(1,r-a)+d*2})}buildSectionOptions(){if(this.doc)try{let e=(0,L.computeSections)(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:L.UNGROUPED_ID,label:e.ungrouped.label}),this.sectionLabelById.set(L.UNGROUPED_ID,e.ungrouped.label))}catch{}}paintModeTabs(){let e=[];this.els.modes?.querySelectorAll("[data-mode]").forEach(s=>{let n=s,i=n.dataset.mode,a=i==="channels"?this.channelCaps.view:i==="categories"?this.categoryCanManage:i==="tables"?this.tableCanManage:!0;if(n.hidden=!a,!a)return;e.push({mode:i,label:n.textContent??i});let l=i===this.mode;n.classList.toggle("on",l),n.setAttribute("aria-selected",String(l)),n.tabIndex=l?0:-1});let t=this.els.tools;t&&(t.innerHTML=e.map(s=>`<option value="${s.mode}"${s.mode===this.mode?" selected":""}>${u(s.label)}</option>`).join(""),t.value=this.mode),this.root?.classList.toggle("block-mode",this.mode==="block")}paintFollowLiveButton(){let e=this.els.follow;e&&(e.classList.toggle("on",this.followLive),e.setAttribute("aria-pressed",String(this.followLive)),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="Booking momentum",this.paintMomentumHelp())}paintMomentumHelp(){let e=this.els.rail?.querySelector('[data-ref="momentumhelp"]');if(!e)return;e.hidden=!this.heatEnabled;let t=e.querySelector('[data-ref="momentumcopy"]');if(!t)return;let s=this.controlRoomSnapshot?.velocity.bySection.some(n=>n.netBooked>0);t.textContent=s?"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.mode==="block"&&this.renderer?.getRung?.()!=="seats";e.classList.toggle("on",!!t)}formatKpiDelta(e,t,s){let n=t>0?"+":"\u2212",i=Math.abs(t);return e==="booked-value"?`${n}${Z(i,s)}`:e==="booked-pct"?`${n}${i.toLocaleString()}pt`:`${n}${i.toLocaleString()}`}paintKpis(e){if(!this.els.kpis)return;let t=e.bookedValueStatus==="current"?Z(e.bookedValue,e.currency):"\u2014",s=this.presenceCounts(),n=[{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"}],i=!1;this.els.kpis.innerHTML=n.map(a=>{let l=this.lastKpiValues.get(a.key),r=a.raw!=null&&l!=null&&a.raw!==l,d=r?a.raw-l:0;r&&(i=!0,this.activeKpiDeltas.set(a.key,{text:this.formatKpiDelta(a.key,d,e.currency),down:d<0})),a.raw!=null&&this.lastKpiValues.set(a.key,a.raw);let c=this.activeKpiDeltas.get(a.key);return`<div class="slm-kpi${c?" changed":""}" data-kpi="${a.key}" title="${u(a.title)}">
1058
+ `,this.host.appendChild(e),this.root=e,this.updateContainerLayout(),typeof ResizeObserver<"u"&&(this.layoutObserver=new ResizeObserver(()=>this.updateContainerLayout()),this.layoutObserver.observe(e));let s=n=>e.querySelector(`[data-ref="${n}"]`);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(n=>n.addEventListener("click",()=>this.setMode(n.dataset.mode))),this.els.tools.addEventListener("change",()=>this.setMode(this.els.tools.value)),this.els.zfit.addEventListener("click",()=>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()}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(c=>c.id)),s=this.filterableSections().filter(c=>!t.has(c.id)).map(c=>c.id);this.renderer.clearSectionFocus(),this.renderer.setClosedSections(null),this.renderer.setDimmedSections(s);let n=e.flatMap(c=>c.seatLabels).map(c=>this.labelToSeat.get(c)).filter(c=>!!c&&Number.isFinite(c.x)&&Number.isFinite(c.y));if(!n.length){this.renderer.focusRegion(e[0].id);return}let i=Math.min(...n.map(c=>c.x)),a=Math.min(...n.map(c=>c.y)),o=Math.max(...n.map(c=>c.x)),r=Math.max(...n.map(c=>c.y)),d=Math.max(40,Math.max(o-i,r-a)*.08);this.renderer.focusRegion({x:i-d,y:a-d,width:Math.max(1,o-i)+d*2,height:Math.max(1,r-a)+d*2})}buildSectionOptions(){if(this.doc)try{let e=(0,L.computeSections)(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:L.UNGROUPED_ID,label:e.ungrouped.label}),this.sectionLabelById.set(L.UNGROUPED_ID,e.ungrouped.label))}catch{}}paintModeTabs(){let e=[];this.els.modes?.querySelectorAll("[data-mode]").forEach(s=>{let n=s,i=n.dataset.mode,a=i==="channels"?this.channelCaps.view:i==="categories"?this.categoryCanManage:i==="tables"?this.tableCanManage:!0;if(n.hidden=!a,!a)return;e.push({mode:i,label:n.textContent??i});let o=i===this.mode;n.classList.toggle("on",o),n.setAttribute("aria-selected",String(o)),n.tabIndex=o?0:-1});let t=this.els.tools;t&&(t.innerHTML=e.map(s=>`<option value="${s.mode}"${s.mode===this.mode?" selected":""}>${u(s.label)}</option>`).join(""),t.value=this.mode),this.root?.classList.toggle("block-mode",this.mode==="block")}paintFollowLiveButton(){let e=this.els.follow;e&&(e.classList.toggle("on",this.followLive),e.setAttribute("aria-pressed",String(this.followLive)),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="Booking momentum",this.paintMomentumHelp())}paintMomentumHelp(){let e=this.els.rail?.querySelector('[data-ref="momentumhelp"]');if(!e)return;e.hidden=!this.heatEnabled;let t=e.querySelector('[data-ref="momentumcopy"]');if(!t)return;let s=this.controlRoomSnapshot?.velocity.bySection.some(n=>n.netBooked>0);t.textContent=s?"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.mode==="block"&&this.renderer?.getRung?.()!=="seats";e.classList.toggle("on",!!t)}formatKpiDelta(e,t,s){let n=t>0?"+":"\u2212",i=Math.abs(t);return e==="booked-value"?`${n}${Z(i,s)}`:e==="booked-pct"?`${n}${i.toLocaleString()}pt`:`${n}${i.toLocaleString()}`}paintKpis(e){if(!this.els.kpis)return;let t=e.bookedValueStatus==="current"?Z(e.bookedValue,e.currency):"\u2014",s=this.presenceCounts(),n=[{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"}],i=!1;this.els.kpis.innerHTML=n.map(a=>{let o=this.lastKpiValues.get(a.key),r=a.raw!=null&&o!=null&&a.raw!==o,d=r?a.raw-o:0;r&&(i=!0,this.activeKpiDeltas.set(a.key,{text:this.formatKpiDelta(a.key,d,e.currency),down:d<0})),a.raw!=null&&this.lastKpiValues.set(a.key,a.raw);let c=this.activeKpiDeltas.get(a.key);return`<div class="slm-kpi${c?" changed":""}" data-kpi="${a.key}" title="${u(a.title)}">
1023
1059
  <b>${a.dot?`<span class="dot" style="background:${a.dot}"></span>`:""}${a.n}</b><span>${a.l}</span>
1024
1060
  ${c?`<span class="slm-kpidelta${c.down?" down":""}">${c.text}</span>`:""}
1025
1061
  </div>`}).join(""),i&&(this.kpiCleanupTimer&&clearTimeout(this.kpiCleanupTimer),this.kpiCleanupTimer=setTimeout(()=>{this.kpiCleanupTimer=null,this.activeKpiDeltas.clear(),this.els.kpis?.querySelectorAll(".slm-kpidelta").forEach(a=>a.remove()),this.els.kpis?.querySelectorAll(".slm-kpi.changed").forEach(a=>a.classList.remove("changed"))},1500))}paintRail(){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=`
@@ -1044,9 +1080,9 @@
1044
1080
  <div class="slm-healthitem" title="Active map sessions right now"><b>${a?a.shoppingSessions.toLocaleString():"\u2014"}</b><span>Viewing map</span></div>
1045
1081
  <div class="slm-healthitem" title="Sessions currently holding inventory"><b>${a?a.activeHolds.toLocaleString():"\u2014"}</b><span>Active holds</span></div>
1046
1082
  <div class="slm-healthitem"><b>${n?"Healthy":"Reconnecting"}</b><span>Live connection</span></div>
1047
- <div class="slm-healthitem"><b>${i}</b><span>Last sync</span></div>`}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(n=>[n.sectionId,n])),s=[...e.bookedValue.bySection].sort((n,i)=>{let a=t.get(n.sectionId)?.netBooked??0;return(t.get(i.sectionId)?.netBooked??0)-a||i.bookedValue-n.bookedValue});this.els.sections.innerHTML=s.length?s.map(n=>{let i=t.get(n.sectionId),a=i?.netBooked??0,l=`${a>0?"+":""}${a}`,r=i?.trend==="rising"||i?.trend==="cooling"?i.trend:"steady";return`<button type="button" class="slm-sectionrow" data-section-focus="${u(n.sectionId)}" title="Focus ${u(n.sectionLabel)} on the map">
1083
+ <div class="slm-healthitem"><b>${i}</b><span>Last sync</span></div>`}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(n=>[n.sectionId,n])),s=[...e.bookedValue.bySection].sort((n,i)=>{let a=t.get(n.sectionId)?.netBooked??0;return(t.get(i.sectionId)?.netBooked??0)-a||i.bookedValue-n.bookedValue});this.els.sections.innerHTML=s.length?s.map(n=>{let i=t.get(n.sectionId),a=i?.netBooked??0,o=`${a>0?"+":""}${a}`,r=i?.trend==="rising"||i?.trend==="cooling"?i.trend:"steady";return`<button type="button" class="slm-sectionrow" data-section-focus="${u(n.sectionId)}" title="Focus ${u(n.sectionLabel)} on the map">
1048
1084
  <span class="slm-sectiontop"><span>${u(n.sectionLabel)}</span><span>${Z(n.bookedValue,e.currency)}</span></span>
1049
- <span class="slm-sectionmeta"><span>${n.booked.toLocaleString()}/${n.total.toLocaleString()} booked \xB7 ${l} in ${e.velocity.windowMinutes}m</span><span class="slm-trend ${r}">${r}</span><span class="slm-sectionlocate">Locate</span></span>
1085
+ <span class="slm-sectionmeta"><span>${n.booked.toLocaleString()}/${n.total.toLocaleString()} booked \xB7 ${o} in ${e.velocity.windowMinutes}m</span><span class="slm-trend ${r}">${r}</span><span class="slm-sectionlocate">Locate</span></span>
1050
1086
  </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(a=>[a.sectionId,Math.max(1,a.total)])),s=e.velocity.bySection.map(a=>({sectionId:a.sectionId,rate:Math.max(0,a.netBooked)/(t.get(a.sectionId)??1)/e.velocity.windowMinutes})),n=Math.max(0,...s.map(a=>a.rate)),i={};for(let a of s)i[a.sectionId]=n>0?Math.sqrt(a.rate/n):0;this.renderer?.setSectionHeat(i)}renderSelectRail(){let e=this.doc?.categories??[],t=this.opts.numberOfPlacesToSelect,s=this.selectionCap();this.els.rail.innerHTML=`
1051
1087
  <p class="slm-eyebrow">Custom selection</p>
1052
1088
  <p class="slm-hint">Select inventory for a host-defined back-office operation. This tool is read-only and never books, releases, or blocks seats by itself.</p>
@@ -1063,10 +1099,10 @@
1063
1099
  <span>${u(n.label??n.key)}</span>
1064
1100
  <span class="slm-chipcount" data-cat-count>0</span>
1065
1101
  <span class="slm-chipcheck" aria-hidden="true">\u2713</span>
1066
- </button>`).join("")}</div>`:""}`,this.els.selectnum=this.els.rail.querySelector('[data-ref="selectnum"]'),this.els.selectmeta=this.els.rail.querySelector('[data-ref="selectmeta"]'),this.els.selectvalidity=this.els.rail.querySelector('[data-ref="selectvalidity"]'),this.els.selectclear=this.els.rail.querySelector('[data-ref="selectclear"]'),this.els.rail.querySelector('[data-ref="selectall"]')?.addEventListener("click",()=>this.selectAll()),this.els.selectclear.addEventListener("click",()=>this.clearSelection()),this.els.rail.querySelectorAll("[data-select-cat]").forEach(n=>{n.addEventListener("click",()=>{let i=n.dataset.selectCat,a=[...this.labelToSeat.values()].filter(r=>r.categoryKey===i&&this.canSelectObject(r)),l=new Set(this.selectionLabels());a.length>0&&a.every(r=>l.has(r.label))?this.deselectCategories([i]):this.selectCategories([i])})}),this.paintSelectSelection(this.getSelection())}paintSelectSelection(e){if(!this.els.selectnum||!this.els.selectmeta)return;let t=e.length;this.els.selectnum.textContent=t.toLocaleString(),this.els.selectmeta.textContent=t===1?"object selected":"objects selected",this.els.selectclear.disabled=t===0;let s=this.getSelectionValidity();this.els.selectvalidity&&(this.els.selectvalidity.textContent=s?s.isValid?`Ready \u2014 exactly ${s.required.toLocaleString()} selected.`:`Select ${s.remaining.toLocaleString()} more to continue.`:`${Math.max(0,this.selectionCap()-t).toLocaleString()} selections remaining.`);let n=new Set(e.map(i=>i.label));this.els.rail?.querySelectorAll("[data-select-cat]").forEach(i=>{let a=i.dataset.selectCat,l=[...this.labelToSeat.values()].filter(p=>p.categoryKey===a&&this.canSelectObject(p)),r=l.filter(p=>n.has(p.label)).length,d=l.length>0&&r===l.length;i.classList.toggle("on",d),i.setAttribute("aria-pressed",String(d));let c=i.querySelector("[data-cat-count]");c&&(c.textContent=r?`${r}/${l.length}`:l.length.toLocaleString()),i.disabled=l.length===0})}renderFilterSectionsRail(){let e=new Map;for(let t of this.filterableSections())e.set(t.label,[...e.get(t.label)??[],t]);this.els.rail.innerHTML=`
1102
+ </button>`).join("")}</div>`:""}`,this.els.selectnum=this.els.rail.querySelector('[data-ref="selectnum"]'),this.els.selectmeta=this.els.rail.querySelector('[data-ref="selectmeta"]'),this.els.selectvalidity=this.els.rail.querySelector('[data-ref="selectvalidity"]'),this.els.selectclear=this.els.rail.querySelector('[data-ref="selectclear"]'),this.els.rail.querySelector('[data-ref="selectall"]')?.addEventListener("click",()=>this.selectAll()),this.els.selectclear.addEventListener("click",()=>this.clearSelection()),this.els.rail.querySelectorAll("[data-select-cat]").forEach(n=>{n.addEventListener("click",()=>{let i=n.dataset.selectCat,a=[...this.labelToSeat.values()].filter(r=>r.categoryKey===i&&this.canSelectObject(r)),o=new Set(this.selectionLabels());a.length>0&&a.every(r=>o.has(r.label))?this.deselectCategories([i]):this.selectCategories([i])})}),this.paintSelectSelection(this.getSelection())}paintSelectSelection(e){if(!this.els.selectnum||!this.els.selectmeta)return;let t=e.length;this.els.selectnum.textContent=t.toLocaleString(),this.els.selectmeta.textContent=t===1?"object selected":"objects selected",this.els.selectclear.disabled=t===0;let s=this.getSelectionValidity();this.els.selectvalidity&&(this.els.selectvalidity.textContent=s?s.isValid?`Ready \u2014 exactly ${s.required.toLocaleString()} selected.`:`Select ${s.remaining.toLocaleString()} more to continue.`:`${Math.max(0,this.selectionCap()-t).toLocaleString()} selections remaining.`);let n=new Set(e.map(i=>i.label));this.els.rail?.querySelectorAll("[data-select-cat]").forEach(i=>{let a=i.dataset.selectCat,o=[...this.labelToSeat.values()].filter(p=>p.categoryKey===a&&this.canSelectObject(p)),r=o.filter(p=>n.has(p.label)).length,d=o.length>0&&r===o.length;i.classList.toggle("on",d),i.setAttribute("aria-pressed",String(d));let c=i.querySelector("[data-cat-count]");c&&(c.textContent=r?`${r}/${o.length}`:o.length.toLocaleString()),i.disabled=o.length===0})}renderFilterSectionsRail(){let e=new Map;for(let t of this.filterableSections())e.set(t.label,[...e.get(t.label)??[],t]);this.els.rail.innerHTML=`
1067
1103
  <p class="slm-eyebrow">Filter sections</p>
1068
1104
  <p class="slm-hint">Choose a section for host-owned reporting. Matching sections with the same label stay together and the map frames their combined inventory.</p>
1069
- ${e.size?`<div class="slm-sectionlist">${[...e].map(([t,s])=>{let n=t===this.filteredSectionLabel,i=s.reduce((a,l)=>a+l.seatCount,0);return`<button type="button" class="slm-sectionrow${n?" on":""}" data-filter-section="${u(t)}" aria-pressed="${n}">
1105
+ ${e.size?`<div class="slm-sectionlist">${[...e].map(([t,s])=>{let n=t===this.filteredSectionLabel,i=s.reduce((a,o)=>a+o.seatCount,0);return`<button type="button" class="slm-sectionrow${n?" on":""}" data-filter-section="${u(t)}" aria-pressed="${n}">
1070
1106
  <span class="slm-sectiontop"><span>${u(t)}</span><span>${i.toLocaleString()}</span></span>
1071
1107
  <span class="slm-sectionmeta"><span>${s.length===1?"One section":`${s.length.toLocaleString()} matching sections`}</span><span class="slm-sectionlocate">${n?"Filtered":"Filter"}</span></span>
1072
1108
  </button>`}).join("")}</div>
@@ -1108,7 +1144,7 @@
1108
1144
  <p class="slm-note">Flexible-group bounds remain available through <code>setTableBooking()</code>; the packaged rail never invents guest limits.</p>`,this.els.rail.querySelectorAll("[data-table-all]").forEach(s=>{s.addEventListener("click",()=>{this.setTableBooking(e.map(n=>n.id),s.dataset.tableAll)})}),this.els.rail.querySelectorAll("[data-table-mode]").forEach(s=>{s.addEventListener("change",()=>{this.setTableBooking([s.dataset.tableMode],s.value)})})}renderInspectRail(e){let t=e[e.length-1];if(!t){this.els.rail.innerHTML=`
1109
1145
  <p class="slm-eyebrow">Inspect seats</p>
1110
1146
  <p class="slm-hint">Select a seat to see its availability and booking context. Nothing changes in this view.</p>
1111
- <div class="slm-empty">Select a seat on the map.</div>`;return}let s=this.status.get(t.label)??"free",n={free:"Free",held:"Held",booked:"Booked",blocked:"Blocked"},i=this.sectionByObject.get(t.rowId)??L.UNGROUPED_ID,a=this.sectionLabelById.get(i)??"Other seats",l=this.doc?.categories.find(g=>g.key===t.categoryKey),r=this.controlRoomSnapshot?.bookedValue.bySection.find(g=>g.sectionId===i),d=this.doc?.objects.find(g=>g.id===t.rowId),c=d?.type==="row"?{label:"Row",value:d.label}:d?.type==="table"?{label:"Table",value:d.label}:t.kind==="booth"?{label:"Type",value:"Booth"}:null,p=t.kind==="booth"?"Booth":"Seat";this.els.rail.innerHTML=`
1147
+ <div class="slm-empty">Select a seat on the map.</div>`;return}let s=this.status.get(t.label)??"free",n={free:"Free",held:"Held",booked:"Booked",blocked:"Blocked"},i=this.sectionByObject.get(t.rowId)??L.UNGROUPED_ID,a=this.sectionLabelById.get(i)??"Other seats",o=this.doc?.categories.find(b=>b.key===t.categoryKey),r=this.controlRoomSnapshot?.bookedValue.bySection.find(b=>b.sectionId===i),d=this.doc?.objects.find(b=>b.id===t.rowId),c=d?.type==="row"?{label:"Row",value:d.label}:d?.type==="table"?{label:"Table",value:d.label}:t.kind==="booth"?{label:"Type",value:"Booth"}:null,p=t.kind==="booth"?"Booth":"Seat";this.els.rail.innerHTML=`
1112
1148
  <p class="slm-eyebrow">${p} details</p>
1113
1149
  <p class="slm-hint">Live availability and section performance.</p>
1114
1150
  <div class="slm-inspect-card">
@@ -1117,7 +1153,7 @@
1117
1153
  <div><span>Status</span><b>${n[s]}</b></div>
1118
1154
  <div><span>Section</span><b>${u(a)}</b></div>
1119
1155
  ${c?`<div><span>${c.label}</span><b>${u(c.value)}</b></div>`:""}
1120
- <div><span>Category</span><b>${u(l?.label??t.categoryKey)}</b></div>
1156
+ <div><span>Category</span><b>${u(o?.label??t.categoryKey)}</b></div>
1121
1157
  <div><span>Booked in section</span><b>${r?`${r.booked} of ${r.total}`:"\u2014"}</b></div>
1122
1158
  <div><span>Section booked value</span><b>${r&&this.controlRoomSnapshot?Z(r.bookedValue,this.controlRoomSnapshot.currency):"\u2014"}</b></div>
1123
1159
  </div>
@@ -1127,7 +1163,7 @@
1127
1163
  <div class="slm-empty">No sections on this chart.</div>`;return}let n=[];t&&n.push(`${t} hidden`),s&&n.push(`${s} closed`);let i=n.length?n.join(" \xB7 "):"All sections open and on sale",a=t>0||s>0;this.els.rail.innerHTML=`
1128
1164
  <p class="slm-eyebrow">Availability windows</p>
1129
1165
  <p class="slm-hint">Control when each zone or section goes on sale. 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.</p>
1130
- <div class="slm-availlist" data-ref="availlist">${e.map(l=>tt(l,this.availabilitySaving)).join("")}</div>
1166
+ <div class="slm-availlist" data-ref="availlist">${e.map(o=>tt(o,this.availabilitySaving)).join("")}</div>
1131
1167
  <div class="slm-availsummary">
1132
1168
  <span class="slm-availdot${a?" warn":""}"></span>
1133
1169
  <span>${u(i)}</span>
@@ -1135,7 +1171,7 @@
1135
1171
  <div class="slm-availcallout">
1136
1172
  <span class="slm-availstar" aria-hidden="true">\u2726</span>
1137
1173
  <p><b>Auto-reveal at % sold</b> is our differentiator \u2014 demand-triggered release: the balcony opens itself the moment the stalls hit the threshold. Neither seats.io nor Ticketmaster ships this.</p>
1138
- </div>`,this.wireSectionRail(),this.applySectionCanvasTreatment()}wireSectionRail(){let e=this.els.rail;e&&(e.querySelectorAll("[data-avail-id]").forEach(t=>{t.addEventListener("change",()=>this.setSectionMode(t.dataset.availId,t.value))}),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=re(this.sectionRowsInput()).rows.find(l=>l.id===e),n=s?.seatLabels??this.availabilityRules[e]?.labels??[],i={...this.availabilityRules},a=Xe(t,n,this.availabilityRules[e]);if(a?i[e]=a:delete i[e],s?.kind==="zone"&&this.sectionsBase)for(let l of this.sectionsBase.sections)l.zone===e&&delete i[l.id];this.persistAvailability(i)}setSectionRulePatch(e,t){let s=this.availabilityRules[e];if(!s)return;let i=re(this.sectionRowsInput()).rows.find(a=>a.id===e)?.seatLabels??s.labels??[];this.persistAvailability({...this.availabilityRules,[e]:{...s,...t,labels:i}})}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(Ie(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=Je.map(t=>`<div class="slm-legrow"><span class="slm-legdot" style="background:${t.color}"></span>
1174
+ </div>`,this.wireSectionRail(),this.applySectionCanvasTreatment()}wireSectionRail(){let e=this.els.rail;e&&(e.querySelectorAll("[data-avail-id]").forEach(t=>{t.addEventListener("change",()=>this.setSectionMode(t.dataset.availId,t.value))}),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=re(this.sectionRowsInput()).rows.find(o=>o.id===e),n=s?.seatLabels??this.availabilityRules[e]?.labels??[],i={...this.availabilityRules},a=Xe(t,n,this.availabilityRules[e]);if(a?i[e]=a:delete i[e],s?.kind==="zone"&&this.sectionsBase)for(let o of this.sectionsBase.sections)o.zone===e&&delete i[o.id];this.persistAvailability(i)}setSectionRulePatch(e,t){let s=this.availabilityRules[e];if(!s)return;let i=re(this.sectionRowsInput()).rows.find(a=>a.id===e)?.seatLabels??s.labels??[];this.persistAvailability({...this.availabilityRules,[e]:{...s,...t,labels:i}})}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(Ie(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=Je.map(t=>`<div class="slm-legrow"><span class="slm-legdot" style="background:${t.color}"></span>
1139
1175
  <span class="slm-leglabel">${t.label}</span><span class="slm-legcount">${e[t.key].toLocaleString()}</span></div>`).join(""))}paintFeed(){if(!this.els.feed)return;if(!this.feed.length){this.els.feed.innerHTML=`<div class="slm-empty">No activity yet \u2014 it'll stream in live.</div>`;return}let e=Date.now(),t={free:"#6e7bff",held:"#f4b740",booked:"#22a06b",blocked:"#8b94ac"};this.els.feed.innerHTML=this.feed.map(s=>{let n=s.count>1?` +${s.count-1}`:"",i=s.sectionLabels??[],a=i.length===1?i[0]:i.length>1?`${i.length} sections`:"";return`<button type="button" class="slm-feedrow" data-feed-id="${u(s.id)}" title="Locate this activity on the map">
1140
1176
  <span class="slm-feeddot" style="background:${t[s.status]}"></span>
1141
1177
  <span class="slm-feedtext">${a?`<span class="slm-feedsection">${u(a)}</span>`:""}${s.count===1?"Seat":"Seats"} <b>${u(s.label)}${n}</b> ${u(s.verb)}</span>
@@ -1190,8 +1226,8 @@
1190
1226
  <button class="slm-btn ghost" data-ref="markall" style="width:100%" disabled>Put all blocked seats on sale</button>
1191
1227
  <p class="slm-note slm-allnote" data-ref="markallnote">For a full reset only. You will be asked to confirm.</p>
1192
1228
  </div>
1193
- `;let i=c=>this.els.rail.querySelector(`[data-ref="${c}"]`);this.els.selnum=i("selnum"),this.els.doblock=i("doblock"),this.els.dounblock=i("dounblock"),this.els.selmeta=i("selmeta"),this.els.blockedcount=i("blockedcount"),this.els.blockedshowing=i("blockedshowing"),this.els.blockedlist=i("blockedlist"),this.els.selblocked=i("selblocked"),this.els.markall=i("markall"),this.els.markallnote=i("markallnote"),i("doblock").addEventListener("click",()=>{this.block()}),i("dounblock").addEventListener("click",()=>{this.unblock()}),i("selall").addEventListener("click",()=>this.selectAll()),i("clearsel").addEventListener("click",()=>this.clearSelection()),i("markall").addEventListener("click",()=>this.confirmUnblockAll()),this.els.rail.querySelectorAll("[data-cat]").forEach(c=>c.addEventListener("click",()=>this.toggleCategory(c.dataset.cat)));let a=this.els.rail.querySelector('[data-ref="section"]');a?.addEventListener("change",()=>{a.value&&(this.selectSection(a.value),a.value="")});let l=i("blockedsearch"),r=i("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()}),i("selblocked").addEventListener("click",()=>{this.toggleLabels(this.filteredBlockedSeats().map(c=>c.label))}),i("blockedlist").addEventListener("click",c=>{let p=c.target,g=p.closest("[data-blocked-label]");g?.dataset.blockedLabel?this.toggleLabels([g.dataset.blockedLabel]):p.closest("[data-blocked-more]")&&(this.blockedResultLimit+=100,this.paintBlockedInventory())});let d=i("release");d.addEventListener("change",()=>{let c=d.value?new Date(d.value).getTime():NaN;this.releaseAt=Number.isFinite(c)&&c>Date.now()?c:null;let p=i("releasenote");p.textContent=this.releaseAt?`New blocks auto-release ${new Date(this.releaseAt).toLocaleString()}.`:d.value?"Pick a time in the future.":"Leave empty to block permanently."}),this.paintSelBar(this.getSelection())}toggleCategory(e){let t=[];for(let[s,n]of this.labelToSeat.entries())n.categoryKey===e&&this.isBlockSelectable(s)&&t.push(s);this.toggleLabels(t)}toggleLabels(e){if(!this.renderer)return;let t=e.filter(i=>this.labelToSeat.has(i)&&this.isBlockSelectable(i));if(!t.length)return;let s=new Set(this.selectionLabels());if(t.every(i=>s.has(i))){let i=t.map(a=>this.labelToId.get(a)).filter(a=>!!a);this.renderer.deselect(i)}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(a=>(this.status.get(a.label)??"free")==="free").length,s=e.filter(a=>this.status.get(a.label)==="blocked").length;this.els.selmeta.textContent=e.length?`${t.toLocaleString()} available \xB7 ${s.toLocaleString()} blocked`:"selected";let n=this.els.doblock,i=this.els.dounblock;n.disabled=t===0,i.disabled=s===0,n.textContent=t?`Block ${t.toLocaleString()}`:"Block selected",i.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 n=s.dataset.cat,i=[];for(let[c,p]of this.labelToSeat.entries())p.categoryKey===n&&this.isBlockSelectable(c)&&i.push(c);let a=i.filter(c=>t.has(c)).length,l=i.length>0&&a===i.length,r=a>0&&!l;s.disabled=i.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 ${i.length.toLocaleString()} seats in this category from the selection`:r?`Select the remaining ${(i.length-a).toLocaleString()} seats in this category`:`Select all ${i.length.toLocaleString()} seats in this category`);let d=s.querySelector("[data-cat-count]");d&&(d.textContent=a?`${a.toLocaleString()}/${i.length.toLocaleString()}`:i.length.toLocaleString())})}filteredBlockedSeats(){let e=this.blockedQuery.trim().toLocaleLowerCase(),t=[];for(let[s,n]of this.labelToSeat.entries()){if(this.status.get(s)!=="blocked")continue;let i=this.sectionByObject.get(n.rowId)??L.UNGROUPED_ID;if(!(this.blockedSection&&i!==this.blockedSection)){if(e){let a=this.doc?.categories.find(p=>p.key===n.categoryKey)?.label??n.categoryKey,l=this.sectionLabelById.get(i)??"Other seats",r=this.doc?.objects.find(p=>p.id===n.rowId),d=r?.type==="row"||r?.type==="table"?r.label:"";if(!`${s} ${a} ${l} ${d}`.toLocaleLowerCase().includes(e))continue}t.push(n)}}return t.sort((s,n)=>s.label.localeCompare(n.label,void 0,{numeric:!0,sensitivity:"base"}))}paintBlockedInventory(){if(!this.els.blockedlist)return;let e=[...this.status.entries()].filter(([,c])=>c==="blocked").length,t=this.filteredBlockedSeats(),s=t.slice(0,this.blockedResultLimit),n=new Set(this.selectionLabels()),i=t.filter(c=>n.has(c.label)).length,a=t.length>0&&i===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=a?`Remove ${t.length.toLocaleString()} results`:`Select ${t.length.toLocaleString()} results`,this.els.blockedlist.innerHTML=s.length?s.map(c=>{let p=this.sectionByObject.get(c.rowId)??L.UNGROUPED_ID,g=this.sectionLabelById.get(p)??"Other seats",w=this.doc?.categories.find(m=>m.key===c.categoryKey)?.label??c.categoryKey,b=n.has(c.label);return`<button type="button" class="slm-blockeditem${b?" on":""}" data-blocked-label="${u(c.label)}" aria-pressed="${b}">
1229
+ `;let i=c=>this.els.rail.querySelector(`[data-ref="${c}"]`);this.els.selnum=i("selnum"),this.els.doblock=i("doblock"),this.els.dounblock=i("dounblock"),this.els.selmeta=i("selmeta"),this.els.blockedcount=i("blockedcount"),this.els.blockedshowing=i("blockedshowing"),this.els.blockedlist=i("blockedlist"),this.els.selblocked=i("selblocked"),this.els.markall=i("markall"),this.els.markallnote=i("markallnote"),i("doblock").addEventListener("click",()=>{this.block()}),i("dounblock").addEventListener("click",()=>{this.unblock()}),i("selall").addEventListener("click",()=>this.selectAll()),i("clearsel").addEventListener("click",()=>this.clearSelection()),i("markall").addEventListener("click",()=>this.confirmUnblockAll()),this.els.rail.querySelectorAll("[data-cat]").forEach(c=>c.addEventListener("click",()=>this.toggleCategory(c.dataset.cat)));let a=this.els.rail.querySelector('[data-ref="section"]');a?.addEventListener("change",()=>{a.value&&(this.selectSection(a.value),a.value="")});let o=i("blockedsearch"),r=i("blockedsection");o.value=this.blockedQuery,r.value=this.blockedSection,o.addEventListener("input",()=>{this.blockedQuery=o.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),r.addEventListener("change",()=>{this.blockedSection=r.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),i("selblocked").addEventListener("click",()=>{this.toggleLabels(this.filteredBlockedSeats().map(c=>c.label))}),i("blockedlist").addEventListener("click",c=>{let p=c.target,b=p.closest("[data-blocked-label]");b?.dataset.blockedLabel?this.toggleLabels([b.dataset.blockedLabel]):p.closest("[data-blocked-more]")&&(this.blockedResultLimit+=100,this.paintBlockedInventory())});let d=i("release");d.addEventListener("change",()=>{let c=d.value?new Date(d.value).getTime():NaN;this.releaseAt=Number.isFinite(c)&&c>Date.now()?c:null;let p=i("releasenote");p.textContent=this.releaseAt?`New blocks auto-release ${new Date(this.releaseAt).toLocaleString()}.`:d.value?"Pick a time in the future.":"Leave empty to block permanently."}),this.paintSelBar(this.getSelection())}toggleCategory(e){let t=[];for(let[s,n]of this.labelToSeat.entries())n.categoryKey===e&&this.isBlockSelectable(s)&&t.push(s);this.toggleLabels(t)}toggleLabels(e){if(!this.renderer)return;let t=e.filter(i=>this.labelToSeat.has(i)&&this.isBlockSelectable(i));if(!t.length)return;let s=new Set(this.selectionLabels());if(t.every(i=>s.has(i))){let i=t.map(a=>this.labelToId.get(a)).filter(a=>!!a);this.renderer.deselect(i)}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(a=>(this.status.get(a.label)??"free")==="free").length,s=e.filter(a=>this.status.get(a.label)==="blocked").length;this.els.selmeta.textContent=e.length?`${t.toLocaleString()} available \xB7 ${s.toLocaleString()} blocked`:"selected";let n=this.els.doblock,i=this.els.dounblock;n.disabled=t===0,i.disabled=s===0,n.textContent=t?`Block ${t.toLocaleString()}`:"Block selected",i.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 n=s.dataset.cat,i=[];for(let[c,p]of this.labelToSeat.entries())p.categoryKey===n&&this.isBlockSelectable(c)&&i.push(c);let a=i.filter(c=>t.has(c)).length,o=i.length>0&&a===i.length,r=a>0&&!o;s.disabled=i.length===0,s.classList.toggle("on",o),s.classList.toggle("partial",r),s.setAttribute("aria-pressed",o?"true":r?"mixed":"false"),s.setAttribute("title",o?`Remove all ${i.length.toLocaleString()} seats in this category from the selection`:r?`Select the remaining ${(i.length-a).toLocaleString()} seats in this category`:`Select all ${i.length.toLocaleString()} seats in this category`);let d=s.querySelector("[data-cat-count]");d&&(d.textContent=a?`${a.toLocaleString()}/${i.length.toLocaleString()}`:i.length.toLocaleString())})}filteredBlockedSeats(){let e=this.blockedQuery.trim().toLocaleLowerCase(),t=[];for(let[s,n]of this.labelToSeat.entries()){if(this.status.get(s)!=="blocked")continue;let i=this.sectionByObject.get(n.rowId)??L.UNGROUPED_ID;if(!(this.blockedSection&&i!==this.blockedSection)){if(e){let a=this.doc?.categories.find(p=>p.key===n.categoryKey)?.label??n.categoryKey,o=this.sectionLabelById.get(i)??"Other seats",r=this.doc?.objects.find(p=>p.id===n.rowId),d=r?.type==="row"||r?.type==="table"?r.label:"";if(!`${s} ${a} ${o} ${d}`.toLocaleLowerCase().includes(e))continue}t.push(n)}}return t.sort((s,n)=>s.label.localeCompare(n.label,void 0,{numeric:!0,sensitivity:"base"}))}paintBlockedInventory(){if(!this.els.blockedlist)return;let e=[...this.status.entries()].filter(([,c])=>c==="blocked").length,t=this.filteredBlockedSeats(),s=t.slice(0,this.blockedResultLimit),n=new Set(this.selectionLabels()),i=t.filter(c=>n.has(c.label)).length,a=t.length>0&&i===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 o=this.els.selblocked;o.disabled=t.length===0,o.textContent=a?`Remove ${t.length.toLocaleString()} results`:`Select ${t.length.toLocaleString()} results`,this.els.blockedlist.innerHTML=s.length?s.map(c=>{let p=this.sectionByObject.get(c.rowId)??L.UNGROUPED_ID,b=this.sectionLabelById.get(p)??"Other seats",y=this.doc?.categories.find(m=>m.key===c.categoryKey)?.label??c.categoryKey,g=n.has(c.label);return`<button type="button" class="slm-blockeditem${g?" on":""}" data-blocked-label="${u(c.label)}" aria-pressed="${g}">
1194
1230
  <span class="slm-blockedcheck" aria-hidden="true">\u2713</span>
1195
1231
  <span class="slm-blockedcopy"><span class="slm-blockedlabel">${u(c.label)}</span>
1196
- <span class="slm-blockedmeta">${u(g)} \xB7 ${u(w)}</span></span>
1197
- </button>`}).join("")+(t.length>s.length?'<button type="button" class="slm-blockedmore" data-blocked-more>Show 100 more</button>':""):`<div class="slm-blockedempty">${e?"No blocked seats match this search or section.":"No seats are blocked. Newly blocked seats will appear here."}</div>`;let r=this.els.markall,d=r.dataset.confirm==="true";r.disabled=e===0,r.textContent=d?`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 n=e==="block"?this.pushActivity(t,"blocked","blocked"):e==="unblock"||e==="unblockAll"?this.pushActivity(t,"unblocked","free"):e==="cancelBooking"?this.pushActivity(t,"cancelled","free"):null;n&&this.paintSpatialActivity(n)}e!=="setHoldTtl"&&this.refreshControlRoom().catch(n=>this.opts.onError?.(n)),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>`)}};ze();xe();ae();0&&(module.exports={ACCESS_LINK_DEFAULTS,ChannelsMode,ManageApi,ManageApiError,PUBLIC_CHANNEL_ID,PUBLIC_CHANNEL_NAME,SeatManager,accessIntentDescription,accessIntentLabel,accessLine,accessLinkBadge,accessLinkErrorCopy,accessLinkIsLive,accessLinkPolicyLines,bucketRows,bucketRowsHtml,dropReviewRows,intentForbidsCopy,intentSwitchBlockedCopy,isPublicChannelId,markerLetter,markerOf,mutationCount,needsMoveConfirmation,planAssignment,retryAfterCopy,selectionSources,stateBadge,suggestMarker});
1232
+ <span class="slm-blockedmeta">${u(b)} \xB7 ${u(y)}</span></span>
1233
+ </button>`}).join("")+(t.length>s.length?'<button type="button" class="slm-blockedmore" data-blocked-more>Show 100 more</button>':""):`<div class="slm-blockedempty">${e?"No blocked seats match this search or section.":"No seats are blocked. Newly blocked seats will appear here."}</div>`;let r=this.els.markall,d=r.dataset.confirm==="true";r.disabled=e===0,r.textContent=d?`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 n=e==="block"?this.pushActivity(t,"blocked","blocked"):e==="unblock"||e==="unblockAll"?this.pushActivity(t,"unblocked","free"):e==="cancelBooking"?this.pushActivity(t,"cancelled","free"):null;n&&this.paintSpatialActivity(n)}e!=="setHoldTtl"&&this.refreshControlRoom().catch(n=>this.opts.onError?.(n)),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>`)}};ze();Se();ae();0&&(module.exports={ACCESS_LINK_DEFAULTS,ChannelsMode,ManageApi,ManageApiError,PUBLIC_CHANNEL_ID,PUBLIC_CHANNEL_NAME,SeatManager,accessIntentDescription,accessIntentLabel,accessLine,accessLinkBadge,accessLinkErrorCopy,accessLinkIsLive,accessLinkPolicyLines,bucketRows,bucketRowsHtml,dropReviewRows,intentForbidsCopy,intentSwitchBlockedCopy,isPublicChannelId,markerLetter,markerOf,mutationCount,needsMoveConfirmation,planAssignment,retryAfterCopy,selectionSources,stateBadge,suggestMarker});