@seatlayer/js 0.96.0 → 0.98.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/{channelsMode-BOkMjgGL.d.cts → channelsMode-BkAe2N3o.d.cts} +30 -0
- package/dist/{channelsMode-BOkMjgGL.d.ts → channelsMode-BkAe2N3o.d.ts} +30 -0
- package/dist/index.cjs +18 -18
- package/dist/index.d.cts +42 -2
- package/dist/index.d.ts +42 -2
- package/dist/index.js +17 -17
- package/dist/manager.cjs +85 -85
- package/dist/manager.d.cts +2 -2
- package/dist/manager.d.ts +2 -2
- package/dist/manager.js +9 -9
- package/package.json +2 -2
package/dist/manager.cjs
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
"use strict";var Ne=Object.defineProperty;var Ss=Object.getOwnPropertyDescriptor;var Ls=Object.getOwnPropertyNames;var Cs=Object.prototype.hasOwnProperty;var z=(o,e,t)=>()=>{if(t)throw t[0];try{return o&&(e=o(o=0)),e}catch(s){throw t=[s],s}};var ot=(o,e)=>{for(var t in e)Ne(o,t,{get:e[t],enumerable:!0})},Ms=(o,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ls(e))!Cs.call(o,n)&&n!==t&&Ne(o,n,{get:()=>e[n],enumerable:!(s=Ss(e,n))||s.enumerable});return o};var Ts=o=>Ms(Ne({},"__esModule",{value:!0}),o);function Y(o){o.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dataset.themed="true";let t=document.createElement("details");t.className="slm-themed-picker";let s=document.createElement("summary"),n=document.createElement("div");n.className="slm-themed-options";let i=e.getAttribute("aria-label")||Array.from(e.labels??[]).map(l=>l.textContent).join(" ")||"Choose option";s.setAttribute("aria-label",i.trim()),t.append(s,n),e.after(t),e.hidden=!0;let a=()=>{s.textContent=e.selectedOptions[0]?.textContent??"Choose\u2026",s.setAttribute("aria-disabled",String(e.disabled)),n.replaceChildren(...Array.from(e.options).map(l=>{let r=document.createElement("button");return r.type="button",r.textContent=l.textContent,r.setAttribute("aria-label",l.textContent??""),r.disabled=e.disabled||l.disabled,r.setAttribute("aria-pressed",String(l.selected)),r.onclick=()=>{e.value=l.value,t.open=!1,a(),s.focus(),e.dispatchEvent(new Event("change",{bubbles:!0})),a()},r}))};a(),e.addEventListener("change",a),s.onclick=l=>{if(e.disabled){l.preventDefault();return}a(),o.querySelectorAll(".slm-themed-picker").forEach(r=>{r!==t&&(r.open=!1)})},t.addEventListener("focusout",l=>{t.contains(l.relatedTarget)||(t.open=!1)}),t.addEventListener("keydown",l=>{if(l.key==="Escape"&&(l.preventDefault(),l.stopPropagation(),t.open=!1,s.focus()),l.key==="ArrowDown"||l.key==="ArrowUp"){if(e.disabled)return;l.preventDefault(),t.open=!0;let r=Array.from(n.querySelectorAll("button:not(:disabled)")),c=r.indexOf(document.activeElement);r[(c+(l.key==="ArrowDown"?1:r.length-1)+r.length)%r.length]?.focus()}})})}function lt(o){o.querySelectorAll('input[type="date"],input[type="datetime-local"],input[type="time"]').forEach(e=>{e.dataset.slmPicker!=="1"&&(e.dataset.slmPicker="1",e.addEventListener("click",()=>{if(!(e.disabled||e.readOnly))try{e.showPicker?.()}catch{}}))})}var ce=z(()=>{"use strict"});async function dt(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 S(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 A(o){return o&&typeof o=="object"?o:{}}function pe(o,e,t=0){return typeof o=="number"&&Number.isFinite(o)?o:typeof e=="number"&&Number.isFinite(e)?e:t}function ht(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 mt(o){let e=A(o),t=pe(e.bookedValue,e.bookedRevenue);return{...e,bookedValue:t,bookedRevenue:t}}function Rs(o){let e=A(o),t=A(e.report),s=Array.isArray(t.byCategory)?t.byCategory.map(i=>{let a=A(i),l=pe(a.bookedValue,a.bookedRevenue);return{...a,bookedValue:l,bookedRevenue:l}}):[],n=Array.isArray(t.bySection)?t.bySection.map(mt):void 0;return{...e,report:{...t,byCategory:s,...n?{bySection:n}:{}}}}function $s(o){let e=A(o),t=A(e.bookedValue),s=A(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:pe(t.gross,s.gross),bySection:i.map(mt)},l=A(e.velocity),r=Array.isArray(l.bySection)?l.bySection.map(c=>{let d=A(c),h=pe(d.bookedValue,d.grossRevenue);return{...d,bookedValue:h,grossRevenue:h}}):[];return{...e,bookedValue:a,revenue:a,velocity:{...l,bySection:r}}}function As(o){let e=A(o),t=A(e.report),s=typeof t.includesBookedValue=="boolean"?t.includesBookedValue:t.includesRevenue===!0,n=Array.isArray(t.rows)?t.rows.map(l=>{let r=A(l),c=A(r.attribution),d=ht(c.bookedValue,c.revenue);return{...r,attribution:{...c,bookedValue:d,revenue:d}}}):[],i=A(t.totals),a=ht(i.bookedValue,i.revenue);return{...e,report:{...t,includesBookedValue:s,includesRevenue:s,rows:n,totals:{...i,bookedValue:a,revenue:a}}}}function je(o){let e=A(o),t=typeof e.includesBookedValue=="boolean"?e.includesBookedValue:e.includesRevenue===!0;return{...e,includesBookedValue:t,includesRevenue:t}}var S,G,ue=z(()=>{"use strict";S=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}};G=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=>dt(a))}async authBlob(e){let t=await fetch(`${this.base}${e}`,{method:"GET",headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});return t.ok||await dt(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 S(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}})}categoryDifferences(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/category-assignments`)}resetCategoriesToChart(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/category-assignments`,{method:"POST",body:{mode:"chart",...t?{labels:t}:{}}})}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(Rs)}seatHistory(e,t,s,n){let i=new URLSearchParams({label:t});return s&&i.set("before",String(s)),n&&i.set("action",n),this.auth(`/v1/events/${encodeURIComponent(e)}/seat-history?${i}`)}controlRoom(e,t=15){return this.auth(`/v1/events/${encodeURIComponent(e)}/control-room?window=${t}`).then($s)}channelReport(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/report`).then(As)}createChannelReportLink(e,t,s={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`,{method:"POST",body:s}).then(n=>{let i=A(n);return{...i,link:je(i.link)}})}channelReportLinks(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`).then(s=>{let n=A(s);return{links:Array.isArray(n.links)?n.links.map(je):[]}})}revokeChannelReportLink(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links/${encodeURIComponent(s)}`,{method:"DELETE"}).then(n=>{let i=A(n);return{...i,link:je(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 S(t.status,`request_failed_${t.status}`);return t.blob()}}});function Ds(){try{return window.matchMedia?.("(prefers-color-scheme: dark)").matches===!0}catch{return!1}}function Ke(o){if(o)return o==="auto"?Ds()?"dark":"light":o}function xt(o){let e;try{e=window.matchMedia?.("(prefers-color-scheme: dark)")}catch{return()=>{}}if(!e)return()=>{};let t=s=>o(s.matches);return typeof e.addEventListener=="function"?e.addEventListener("change",t):e.addListener?.(t),()=>{typeof e.removeEventListener=="function"?e.removeEventListener("change",t):e.removeListener?.(t)}}var yt,Ue,We=z(()=>{"use strict";yt=require("@seatlayer/core/core/color"),Ue={light:{background:"#ffffff",surface:"#f6f7fb",text:"#172033",muted:"#667085",line:"rgba(23,32,51,.16)",map:"#e9edf4"},dark:{background:"#0f1522",surface:"#1a2234",text:"#eef1f8",muted:"#a5aec2",line:"rgba(165,174,194,.24)",map:"#0f1522"}}});function wt(o){return o?o.mode:"open"}function St(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 Lt(o){return new Date(o-new Date().getTimezoneOffset()*6e4).toISOString().slice(0,16)}function Ct(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 Ye(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 fe(o){return o==="blocked"?"not_for_sale":o}function Et(o,e){let t=o??{},s=e?Ue[e]:null,n=e==="light";return{"--slm-bg":t.background??s?.background??"#0e1017","--slm-surface":s?.surface??"#181b24","--slm-text":s?.text??"#eef1f7","--slm-muted":s?.muted??"#8b93a7","--slm-line":s?.line??"rgba(255,255,255,.09)","--slm-tint":n?"rgba(23,32,51,.05)":"rgba(255,255,255,.035)","--slm-tint-strong":n?"rgba(23,32,51,.09)":"rgba(255,255,255,.07)","--slm-accent":t.accent??(n?"#4654c8":"#6e7bff"),"--slm-accent-ink":t.accentInk??"#ffffff","--slm-font":"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif","--slm-radius":"14px"}}function Rt(o){return o?Ue[o].map:null}function $t(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 ve(o,e){return(0,kt.formatMoney)(o,e,{maximumFractionDigits:0,fallback:(t,s)=>`${s} ${Math.round(t).toLocaleString()}`})}function b(o){return String(o??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var kt,Os,H,ge,Mt,Tt,ye=z(()=>{"use strict";kt=require("@seatlayer/core");We();Os=["free","booked","held","blocked"],H={free:"#6e7bff",booked:"#9ca3af",held:"#f4b740",blocked:"#475569"},ge={free:"Free",booked:"Sold",held:"Held",blocked:"Blocked"},Mt=[`<span class="slm-legmark" style="background:${H.free}"></span> Free = category colour`,`<span class="slm-legmark" style="background:${H.booked}"></span> ${ge.booked}`,`<span class="slm-legmark" style="background:${H.held}"></span> ${ge.held}`,`<span class="slm-legcross" style="color:${H.blocked}">\u2715</span> ${ge.blocked}`].join(" \xB7 "),Tt=Os.map(o=>({key:o,label:ge[o],color:H[o]}))});function Fs(o,e){if(!o.labels.length)return"Nothing found";let t=[];o.sections&&t.push(`${o.sections.toLocaleString()} section${o.sections===1?"":"s"}`),o.rows&&t.push(`${o.rows.toLocaleString()} row${o.rows===1?"":"s"}`);let s=`${o.labels.length.toLocaleString()} seat${o.labels.length===1?"":"s"} found`,n=t.length?`${t.join(" \xB7 ")} \xB7 ${s}`:s;return e?`${n} \xB7 Enter to ${e==="frame"?"show":"select"}`:n}function ke(o={}){return`
|
|
1
|
+
"use strict";var Ne=Object.defineProperty;var Ss=Object.getOwnPropertyDescriptor;var Ls=Object.getOwnPropertyNames;var Cs=Object.prototype.hasOwnProperty;var z=(o,e,t)=>()=>{if(t)throw t[0];try{return o&&(e=o(o=0)),e}catch(s){throw t=[s],s}};var ot=(o,e)=>{for(var t in e)Ne(o,t,{get:e[t],enumerable:!0})},Ms=(o,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ls(e))!Cs.call(o,n)&&n!==t&&Ne(o,n,{get:()=>e[n],enumerable:!(s=Ss(e,n))||s.enumerable});return o};var Ts=o=>Ms(Ne({},"__esModule",{value:!0}),o);function Y(o){o.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dataset.themed="true";let t=document.createElement("details");t.className="slm-themed-picker";let s=document.createElement("summary"),n=document.createElement("div");n.className="slm-themed-options";let i=e.getAttribute("aria-label")||Array.from(e.labels??[]).map(l=>l.textContent).join(" ")||"Choose option";s.setAttribute("aria-label",i.trim()),t.append(s,n),e.after(t),e.hidden=!0;let a=()=>{s.textContent=e.selectedOptions[0]?.textContent??"Choose\u2026",s.setAttribute("aria-disabled",String(e.disabled)),n.replaceChildren(...Array.from(e.options).map(l=>{let r=document.createElement("button");return r.type="button",r.textContent=l.textContent,r.setAttribute("aria-label",l.textContent??""),r.disabled=e.disabled||l.disabled,r.setAttribute("aria-pressed",String(l.selected)),r.onclick=()=>{e.value=l.value,t.open=!1,a(),s.focus(),e.dispatchEvent(new Event("change",{bubbles:!0})),a()},r}))};a(),e.addEventListener("change",a),s.onclick=l=>{if(e.disabled){l.preventDefault();return}a(),o.querySelectorAll(".slm-themed-picker").forEach(r=>{r!==t&&(r.open=!1)})},t.addEventListener("focusout",l=>{t.contains(l.relatedTarget)||(t.open=!1)}),t.addEventListener("keydown",l=>{if(l.key==="Escape"&&(l.preventDefault(),l.stopPropagation(),t.open=!1,s.focus()),l.key==="ArrowDown"||l.key==="ArrowUp"){if(e.disabled)return;l.preventDefault(),t.open=!0;let r=Array.from(n.querySelectorAll("button:not(:disabled)")),c=r.indexOf(document.activeElement);r[(c+(l.key==="ArrowDown"?1:r.length-1)+r.length)%r.length]?.focus()}})})}function lt(o){o.querySelectorAll('input[type="date"],input[type="datetime-local"],input[type="time"]').forEach(e=>{e.dataset.slmPicker!=="1"&&(e.dataset.slmPicker="1",e.addEventListener("click",()=>{if(!(e.disabled||e.readOnly))try{e.showPicker?.()}catch{}}))})}var ce=z(()=>{"use strict"});async function dt(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 S(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 A(o){return o&&typeof o=="object"?o:{}}function pe(o,e,t=0){return typeof o=="number"&&Number.isFinite(o)?o:typeof e=="number"&&Number.isFinite(e)?e:t}function ht(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 mt(o){let e=A(o),t=pe(e.bookedValue,e.bookedRevenue);return{...e,bookedValue:t,bookedRevenue:t}}function Rs(o){let e=A(o),t=A(e.report),s=Array.isArray(t.byCategory)?t.byCategory.map(i=>{let a=A(i),l=pe(a.bookedValue,a.bookedRevenue);return{...a,bookedValue:l,bookedRevenue:l}}):[],n=Array.isArray(t.bySection)?t.bySection.map(mt):void 0;return{...e,report:{...t,byCategory:s,...n?{bySection:n}:{}}}}function $s(o){let e=A(o),t=A(e.bookedValue),s=A(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:pe(t.gross,s.gross),bySection:i.map(mt)},l=A(e.velocity),r=Array.isArray(l.bySection)?l.bySection.map(c=>{let d=A(c),h=pe(d.bookedValue,d.grossRevenue);return{...d,bookedValue:h,grossRevenue:h}}):[];return{...e,bookedValue:a,revenue:a,velocity:{...l,bySection:r}}}function As(o){let e=A(o),t=A(e.report),s=typeof t.includesBookedValue=="boolean"?t.includesBookedValue:t.includesRevenue===!0,n=Array.isArray(t.rows)?t.rows.map(l=>{let r=A(l),c=A(r.attribution),d=ht(c.bookedValue,c.revenue);return{...r,attribution:{...c,bookedValue:d,revenue:d}}}):[],i=A(t.totals),a=ht(i.bookedValue,i.revenue);return{...e,report:{...t,includesBookedValue:s,includesRevenue:s,rows:n,totals:{...i,bookedValue:a,revenue:a}}}}function je(o){let e=A(o),t=typeof e.includesBookedValue=="boolean"?e.includesBookedValue:e.includesRevenue===!0;return{...e,includesBookedValue:t,includesRevenue:t}}var S,G,ue=z(()=>{"use strict";S=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}};G=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=>dt(a))}async authBlob(e){let t=await fetch(`${this.base}${e}`,{method:"GET",headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});return t.ok||await dt(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 S(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}})}categoryDifferences(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/category-assignments`)}resetCategoriesToChart(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/category-assignments`,{method:"POST",body:{mode:"chart",...t?{labels:t}:{}}})}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(Rs)}seatHistory(e,t,s,n){let i=new URLSearchParams({label:t});return s&&i.set("before",String(s)),n&&i.set("action",n),this.auth(`/v1/events/${encodeURIComponent(e)}/seat-history?${i}`)}controlRoom(e,t=15){return this.auth(`/v1/events/${encodeURIComponent(e)}/control-room?window=${t}`).then($s)}channelReport(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/report`).then(As)}createChannelReportLink(e,t,s={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`,{method:"POST",body:s}).then(n=>{let i=A(n);return{...i,link:je(i.link)}})}channelReportLinks(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`).then(s=>{let n=A(s);return{links:Array.isArray(n.links)?n.links.map(je):[]}})}revokeChannelReportLink(e,t,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links/${encodeURIComponent(s)}`,{method:"DELETE"}).then(n=>{let i=A(n);return{...i,link:je(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 S(t.status,`request_failed_${t.status}`);return t.blob()}}});function Ds(){try{return window.matchMedia?.("(prefers-color-scheme: dark)").matches===!0}catch{return!1}}function Ke(o){if(o)return o==="auto"?Ds()?"dark":"light":o}function xt(o){let e;try{e=window.matchMedia?.("(prefers-color-scheme: dark)")}catch{return()=>{}}if(!e)return()=>{};let t=s=>o(s.matches);return typeof e.addEventListener=="function"?e.addEventListener("change",t):e.addListener?.(t),()=>{typeof e.removeEventListener=="function"?e.removeEventListener("change",t):e.removeListener?.(t)}}var yt,Ue,We=z(()=>{"use strict";yt=require("@seatlayer/core/core/color"),Ue={light:{background:"#ffffff",surface:"#f6f7fb",text:"#172033",muted:"#667085",line:"rgba(23,32,51,.16)",map:"#e9edf4"},dark:{background:"#0f1522",surface:"#1a2234",text:"#eef1f8",muted:"#a5aec2",line:"rgba(165,174,194,.24)",map:"#0f1522"}}});function wt(o){return o?o.mode:"open"}function St(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 Lt(o){return new Date(o-new Date().getTimezoneOffset()*6e4).toISOString().slice(0,16)}function Ct(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 Ye(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 fe(o){return o==="blocked"?"not_for_sale":o}function Et(o,e){let t=o??{},s=e?Ue[e]:null,n=e==="light";return{"--slm-bg":t.background??s?.background??"#0e1017","--slm-surface":s?.surface??"#181b24","--slm-text":s?.text??"#eef1f7","--slm-muted":s?.muted??"#8b93a7","--slm-line":s?.line??"rgba(255,255,255,.09)","--slm-tint":n?"rgba(23,32,51,.05)":"rgba(255,255,255,.035)","--slm-tint-strong":n?"rgba(23,32,51,.09)":"rgba(255,255,255,.07)","--slm-accent":t.accent??(n?"#4654c8":"#6e7bff"),"--slm-accent-ink":t.accentInk??"#ffffff","--slm-font":"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif","--slm-radius":"14px"}}function Rt(o){return o?Ue[o].map:null}function $t(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 ve(o,e){return(0,kt.formatMoney)(o,e,{maximumFractionDigits:0,fallback:(t,s)=>`${s} ${Math.round(t).toLocaleString()}`})}function g(o){return String(o??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var kt,Os,H,ge,Mt,Tt,ye=z(()=>{"use strict";kt=require("@seatlayer/core");We();Os=["free","booked","held","blocked"],H={free:"#6e7bff",booked:"#9ca3af",held:"#f4b740",blocked:"#475569"},ge={free:"Free",booked:"Sold",held:"Held",blocked:"Blocked"},Mt=[`<span class="slm-legmark" style="background:${H.free}"></span> Free = category colour`,`<span class="slm-legmark" style="background:${H.booked}"></span> ${ge.booked}`,`<span class="slm-legmark" style="background:${H.held}"></span> ${ge.held}`,`<span class="slm-legcross" style="color:${H.blocked}">\u2715</span> ${ge.blocked}`].join(" \xB7 "),Tt=Os.map(o=>({key:o,label:ge[o],color:H[o]}))});function Fs(o,e){if(!o.labels.length)return"Nothing found";let t=[];o.sections&&t.push(`${o.sections.toLocaleString()} section${o.sections===1?"":"s"}`),o.rows&&t.push(`${o.rows.toLocaleString()} row${o.rows===1?"":"s"}`);let s=`${o.labels.length.toLocaleString()} seat${o.labels.length===1?"":"s"} found`,n=t.length?`${t.join(" \xB7 ")} \xB7 ${s}`:s;return e?`${n} \xB7 Enter to ${e==="frame"?"show":"select"}`:n}function ke(o={}){return`
|
|
2
2
|
<div class="slm-find${o.compact?" slm-find-bar":""}" data-ch-find>
|
|
3
3
|
<input type="search" class="slm-input" data-ch-find-input placeholder="Find seat, row or section" aria-label="Find seat, row or section" autocomplete="off"${o.compact?' aria-keyshortcuts="/"':""}>
|
|
4
4
|
<span class="slm-find-count" data-ch-find-count role="status"></span>
|
|
5
5
|
</div>`}function At(o,e){return o.toLocaleLowerCase().split(/\s+/).some(t=>e.length>=2?t.startsWith(e):t===e)}function Vs(o,e){let t=o.trim().toLocaleLowerCase();if(!t)return{labels:[],seats:0,rows:0,sections:0};let s=new Set,n=0,i=0;for(let d of e.sections)if(At(d.label,t)){n+=1;for(let h of d.labels)s.add(h)}let a=t.split(/\s+/),l=a[a.length-1],r=a.slice(0,-1).join(" ");for(let d of e.rows)if(d.label.toLocaleLowerCase()===l&&!(r&&!At(d.sectionLabel,r))){i+=1;for(let h of d.labels)s.add(h)}let c=0;for(let d of e.seatLabels){let h=d.toLocaleLowerCase();(h===t||h.startsWith(`${t}-`))&&(s.has(d)||(c+=1),s.add(d))}return{labels:[...s],seats:c,rows:i,sections:n}}function It(o){let e=o.clearAttr?`<button type="button" class="slm-linkbtn slm-selclear" ${o.clearAttr}${o.count?"":" disabled"}>Clear</button>`:"";return`<div class="slm-selbar" aria-live="polite">
|
|
6
6
|
<span class="slm-selnum${o.bump?" bump":""}">${o.count.toLocaleString()}</span>
|
|
7
|
-
<span class="slm-sellabel">${
|
|
7
|
+
<span class="slm-sellabel">${g(o.noun??"selected")}</span>
|
|
8
8
|
${o.breakdown??""}${e}
|
|
9
9
|
</div>`}var xe,zs,N,Ge=z(()=>{"use strict";ye();xe=300,zs=200;N=class{constructor(e){this.host=e;this.seatListLimit=xe;this.rowsCache=null}rows(){return this.rowsCache||(this.rowsCache=this.host.rows()),this.rowsCache}reset(){this.rowsCache=null,this.seatListLimit=xe}chipsHtml(e={}){let t=this.host.sections().length?'<button type="button" class="slm-btn ghost" data-ch-act="pick-sections">Section</button>':"",s=this.rows().length?'<button type="button" class="slm-btn ghost" data-ch-act="pick-rows">Rows\u2026</button>':"",n=this.host.categories().length?'<button type="button" class="slm-btn ghost" data-ch-act="pick-category">Category</button>':"",i=e.find===!1?"":ke();return`
|
|
10
10
|
<div class="slm-chooser" data-ch-chooser>
|
|
11
11
|
<div class="slm-ch-row2">${e.intents??""}${t}${s}</div>
|
|
12
12
|
<div class="slm-ch-row2">${n}<button type="button" class="slm-btn ghost" data-ch-act="seatlist">Seat list \u2328</button></div>
|
|
13
13
|
${i}
|
|
14
|
-
</div>`}wire(e,t={}){this.wireChips(e),this.wireFind(e,t)}wireChips(e){e.querySelectorAll("[data-ch-act]").forEach(t=>{let s=t.dataset.chAct;s==="pick-sections"?t.addEventListener("click",()=>this.openSections()):s==="pick-rows"?t.addEventListener("click",()=>this.openRows()):s==="pick-category"?t.addEventListener("click",()=>this.openCategory()):s==="seatlist"&&t.addEventListener("click",()=>this.openSeatList())})}handleAction(e){if(e==="pick-sections")this.openSections();else if(e==="pick-rows")this.openRows();else if(e==="pick-category")this.openCategory();else if(e==="seatlist")this.openSeatList();else return!1;return!0}wireFind(e,t={}){let s=e.querySelector("[data-ch-find-input]"),n=e.querySelector("[data-ch-find-count]");if(!s||!n)return;let i={labels:[],seats:0,rows:0,sections:0},a=()=>{let l=s.value.trim();i=this.find(s.value),n.textContent=l?Fs(i,t.enter??"select"):"",this.host.highlight?.(l?i.labels:null),t.onFind?.(i)};s.addEventListener("input",a),s.addEventListener("keydown",l=>{if(l.key==="Escape"&&s.value){l.preventDefault(),l.stopPropagation(),s.value="",a();return}if(l.key!=="Enter"||(l.preventDefault(),!i.labels.length))return;if(t.enter==="frame"){this.host.frame?.(i.labels),n.textContent=`${i.labels.length.toLocaleString()} on the map`;return}let r=new Set([...this.host.selectionLabels(),...i.labels]);if(this.host.cap!=null&&r.size>this.host.cap){n.textContent=`That would make ${r.size.toLocaleString()} selected seats \u2014 the limit is ${this.host.cap.toLocaleString()}.`;return}this.host.selectByLabels(i.labels),n.textContent=`${i.labels.length.toLocaleString()} selected`}),s.addEventListener("search",a)}find(e){return Vs(e,{sections:this.host.sections().map(t=>({...t,labels:this.host.labelsInSection(t.id)})),rows:this.rows(),seatLabels:this.host.seats().map(t=>t.label)})}openCategory(){let e=this.host.categories();if(!e.length)return;let t=this.host.cap??1/0,s=e.map(c=>({key:c.key,label:c.label,color:c.color,labels:this.host.labelsInCategory(c.key)})),n=new Map(s.map(c=>[c.key,c])),i=new Set,a=new Set(this.host.selectionLabels()),l=()=>{let c=new Set(a);for(let d of i)for(let h of n.get(d)?.labels??[])c.add(h);return c},r=s.map(c=>{let d=c.labels.filter(m=>a.has(m)).length,h=c.labels.length===0,
|
|
15
|
-
data-ch-category="${
|
|
14
|
+
</div>`}wire(e,t={}){this.wireChips(e),this.wireFind(e,t)}wireChips(e){e.querySelectorAll("[data-ch-act]").forEach(t=>{let s=t.dataset.chAct;s==="pick-sections"?t.addEventListener("click",()=>this.openSections()):s==="pick-rows"?t.addEventListener("click",()=>this.openRows()):s==="pick-category"?t.addEventListener("click",()=>this.openCategory()):s==="seatlist"&&t.addEventListener("click",()=>this.openSeatList())})}handleAction(e){if(e==="pick-sections")this.openSections();else if(e==="pick-rows")this.openRows();else if(e==="pick-category")this.openCategory();else if(e==="seatlist")this.openSeatList();else return!1;return!0}wireFind(e,t={}){let s=e.querySelector("[data-ch-find-input]"),n=e.querySelector("[data-ch-find-count]");if(!s||!n)return;let i={labels:[],seats:0,rows:0,sections:0},a=()=>{let l=s.value.trim();i=this.find(s.value),n.textContent=l?Fs(i,t.enter??"select"):"",this.host.highlight?.(l?i.labels:null),t.onFind?.(i)};s.addEventListener("input",a),s.addEventListener("keydown",l=>{if(l.key==="Escape"&&s.value){l.preventDefault(),l.stopPropagation(),s.value="",a();return}if(l.key!=="Enter"||(l.preventDefault(),!i.labels.length))return;if(t.enter==="frame"){this.host.frame?.(i.labels),n.textContent=`${i.labels.length.toLocaleString()} on the map`;return}let r=new Set([...this.host.selectionLabels(),...i.labels]);if(this.host.cap!=null&&r.size>this.host.cap){n.textContent=`That would make ${r.size.toLocaleString()} selected seats \u2014 the limit is ${this.host.cap.toLocaleString()}.`;return}this.host.selectByLabels(i.labels),n.textContent=`${i.labels.length.toLocaleString()} selected`}),s.addEventListener("search",a)}find(e){return Vs(e,{sections:this.host.sections().map(t=>({...t,labels:this.host.labelsInSection(t.id)})),rows:this.rows(),seatLabels:this.host.seats().map(t=>t.label)})}openCategory(){let e=this.host.categories();if(!e.length)return;let t=this.host.cap??1/0,s=e.map(c=>({key:c.key,label:c.label,color:c.color,labels:this.host.labelsInCategory(c.key)})),n=new Map(s.map(c=>[c.key,c])),i=new Set,a=new Set(this.host.selectionLabels()),l=()=>{let c=new Set(a);for(let d of i)for(let h of n.get(d)?.labels??[])c.add(h);return c},r=s.map(c=>{let d=c.labels.filter(m=>a.has(m)).length,h=c.labels.length===0,b=h?"not on this map":d?`${d.toLocaleString()} of ${c.labels.length.toLocaleString()} selected`:`${c.labels.length.toLocaleString()} seat${c.labels.length===1?"":"s"}`;return`<button type="button" class="slm-ch-seatitem" role="checkbox" aria-checked="false"
|
|
15
|
+
data-ch-category="${g(c.key)}"${h?" disabled":""}>
|
|
16
16
|
<span class="box" aria-hidden="true">\u2713</span>
|
|
17
|
-
<span class="dot" style="background:${
|
|
18
|
-
<span>${
|
|
19
|
-
<span class="meta">${b
|
|
17
|
+
<span class="dot" style="background:${g(c.color??"#6e7bff")}" aria-hidden="true"></span>
|
|
18
|
+
<span>${g(c.label)}</span>
|
|
19
|
+
<span class="meta">${g(b)}</span>
|
|
20
20
|
</button>`}).join("");this.host.openDialog(`
|
|
21
21
|
<h3 id="slm-ch-dlg-title">Choose categories</h3>
|
|
22
22
|
<p class="sub">Every seat in a ticked category is added to the seats already selected on the map.</p>
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<div class="foot">
|
|
26
26
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
27
27
|
<button type="button" class="slm-btn" data-ch-add-scope disabled>Add seats</button>
|
|
28
|
-
</div>`,c=>{let d=c.querySelector("[data-ch-add-scope]"),h=c.querySelector("[data-ch-error]"),
|
|
28
|
+
</div>`,c=>{let d=c.querySelector("[data-ch-add-scope]"),h=c.querySelector("[data-ch-error]"),b=()=>{let m=l(),p=m.size-a.size,v=m.size>t;d.disabled=p===0||v,d.textContent=v?`Maximum ${t.toLocaleString()} seats`:`Add ${p.toLocaleString()} seat${p===1?"":"s"}`,h.hidden=!v,h.textContent=v?`That would make ${m.size.toLocaleString()} selected seats. Choose fewer categories.`:""};c.querySelectorAll("[data-ch-category]").forEach(m=>{m.addEventListener("click",()=>{let p=m.dataset.chCategory;i.has(p)?i.delete(p):i.add(p),m.setAttribute("aria-checked",String(i.has(p))),b()})}),d.addEventListener("click",()=>{let m=[...l()];!i.size||m.length>t||(this.host.closeDialog(),this.host.selectByLabels(m))}),b()})}openSections(){this.openScope("sections")}openRows(){this.openScope("rows")}openScope(e){let t=this.host.cap??1/0,n=(e==="sections"?this.host.sections().map(m=>({id:m.id,label:m.label,group:"Sections",labels:this.host.labelsInSection(m.id)})):this.rows().map(m=>({id:m.id,label:m.label,group:m.sectionLabel,labels:m.labels}))).filter(m=>m.labels.length>0),i=new Map;for(let m of n){let p=i.get(m.group)??[];p.push(m),i.set(m.group,p)}let a=new Map(n.map(m=>[m.id,m])),l=new Set,r=new Set(this.host.selectionLabels()),c=()=>{let m=new Set(r);for(let p of l)for(let v of a.get(p)?.labels??[])m.add(v);return m},d=(m,p)=>{let v=c(),y=v.size-r.size,f=v.size>t;m.disabled=y===0||f,m.textContent=f?`Maximum ${t.toLocaleString()} seats`:`Add ${y.toLocaleString()} seat${y===1?"":"s"}`,p.hidden=!f,p.textContent=f?`That would make ${v.size.toLocaleString()} selected seats. Choose fewer rows or sections.`:""},h=()=>{let m=[...c()];!l.size||m.length>t||(this.host.closeDialog(),this.host.selectByLabels(m))};if(e==="rows"){let m=[...i.entries()];this.host.openDialog(`
|
|
29
29
|
<h3 id="slm-ch-dlg-title">Choose rows</h3>
|
|
30
30
|
<p class="sub">Sections stay collapsed for speed. Select a whole section, expand only the rows you need, or search across every row.</p>
|
|
31
31
|
<div class="slm-ch-scopebar">
|
|
@@ -38,57 +38,57 @@
|
|
|
38
38
|
<div class="foot">
|
|
39
39
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
40
40
|
<button type="button" class="slm-btn" data-ch-add-scope disabled>Add seats</button>
|
|
41
|
-
</div>`,p=>{let v=new Set,y=p.querySelector("[data-ch-add-scope]"),
|
|
41
|
+
</div>`,p=>{let v=new Set,y=p.querySelector("[data-ch-add-scope]"),f=p.querySelector("[data-ch-error]"),C=p.querySelector("[data-ch-scope-list]"),w=p.querySelector("[data-ch-scope-search]"),L=p.querySelector("[data-ch-scope-summary]"),T=p.querySelector("[data-ch-scope-filter]"),x="",E=()=>{d(y,f);let I=c().size-r.size;L.textContent=`${l.size.toLocaleString()} row${l.size===1?"":"s"} \xB7 ${I.toLocaleString()} seat${I===1?"":"s"} added`},M=()=>{let I=[],it=0,_e=0;m.forEach(([B,$],te)=>{let K=B.toLocaleLowerCase(),W=x?$.filter(D=>`${K} ${D.label.toLocaleLowerCase()}`.includes(x)):$;if(x&&!W.length)return;it+=W.length;let at=$.every(D=>l.has(D.id)),ys=!at&&$.some(D=>l.has(D.id)),se=!!x||v.has(te),xs=Math.max(0,zs-_e),ne=se?W.slice(0,xs):[];_e+=ne.length;let ks=$.reduce((D,ws)=>D+ws.labels.length,0);I.push(`<div class="slm-ch-scopegroup">
|
|
42
42
|
<button type="button" class="slm-ch-groupcheck" role="checkbox" aria-checked="${at?"true":ys?"mixed":"false"}"
|
|
43
|
-
aria-label="Select all ${$.length.toLocaleString()} rows in ${
|
|
44
|
-
<span class="box" aria-hidden="true">\u2713</span><span>${
|
|
43
|
+
aria-label="Select all ${$.length.toLocaleString()} rows in ${g(B)}" data-ch-scope-group="${te}">
|
|
44
|
+
<span class="box" aria-hidden="true">\u2713</span><span>${g(B)}</span>
|
|
45
45
|
<span class="meta">${$.length.toLocaleString()} rows \xB7 ${ks.toLocaleString()} seats</span>
|
|
46
46
|
</button>
|
|
47
|
-
<button type="button" class="slm-ch-grouptoggle" aria-expanded="${se}" aria-label="${se?"Hide":"Show"} rows in ${
|
|
47
|
+
<button type="button" class="slm-ch-grouptoggle" aria-expanded="${se}" aria-label="${se?"Hide":"Show"} rows in ${g(B)}"
|
|
48
48
|
data-ch-scope-toggle="${te}">${se?"Hide":"Show"}</button>
|
|
49
49
|
</div>`),I.push(...ne.map(D=>`<button type="button" class="slm-ch-seatitem" role="checkbox"
|
|
50
|
-
aria-checked="${l.has(D.id)}" data-ch-scope-id="${
|
|
51
|
-
<span class="box" aria-hidden="true">\u2713</span><span>${
|
|
50
|
+
aria-checked="${l.has(D.id)}" data-ch-scope-id="${g(D.id)}">
|
|
51
|
+
<span class="box" aria-hidden="true">\u2713</span><span>${g(D.label)}</span>
|
|
52
52
|
<span class="meta">${D.labels.length.toLocaleString()} seat${D.labels.length===1?"":"s"}</span>
|
|
53
|
-
</button>`)),se&&W.length>ne.length&&I.push(`<p class="slm-ch-scopehint">${(W.length-ne.length).toLocaleString()} more row${W.length-ne.length===1?"":"s"}. Search to narrow the list.</p>`)}),C.innerHTML=I.join("")||(x?`<div class="slm-ch-scope-empty" data-ch-state="scope-nomatch">No sections or rows match \u201C${
|
|
54
|
-
Use Drag box or the seat list instead.</div>`),T.textContent=x?`Showing ${_e.toLocaleString()} of ${it.toLocaleString()} matching rows. Section checkboxes still select every row in that section.`:"Showing section groups. Expand one or search to see rows.",C.querySelectorAll("[data-ch-scope-group]").forEach(B=>B.addEventListener("click",()=>{let $=m[Number(B.dataset.chScopeGroup)]?.[1]??[],te=$.every(K=>l.has(K.id));for(let K of $)te?l.delete(K.id):l.add(K.id);M(),E()})),C.querySelectorAll("[data-ch-scope-toggle]").forEach(B=>B.addEventListener("click",()=>{let $=Number(B.dataset.chScopeToggle);v.has($)?v.delete($):v.add($),M()})),C.querySelectorAll("[data-ch-scope-id]").forEach(B=>B.addEventListener("click",()=>{let $=B.dataset.chScopeId;l.has($)?l.delete($):l.add($),M(),E()}))};w.addEventListener("input",()=>{x=w.value.trim().toLocaleLowerCase(),M(),E()}),y.addEventListener("click",h),M(),E()});return}let
|
|
55
|
-
<div class="slm-ch-seatgroup"><span>${
|
|
53
|
+
</button>`)),se&&W.length>ne.length&&I.push(`<p class="slm-ch-scopehint">${(W.length-ne.length).toLocaleString()} more row${W.length-ne.length===1?"":"s"}. Search to narrow the list.</p>`)}),C.innerHTML=I.join("")||(x?`<div class="slm-ch-scope-empty" data-ch-state="scope-nomatch">No sections or rows match \u201C${g(x)}\u201D.</div>`:`<div class="slm-ch-scope-empty" data-ch-state="scope-empty">This chart has no rows with selectable seats.
|
|
54
|
+
Use Drag box or the seat list instead.</div>`),T.textContent=x?`Showing ${_e.toLocaleString()} of ${it.toLocaleString()} matching rows. Section checkboxes still select every row in that section.`:"Showing section groups. Expand one or search to see rows.",C.querySelectorAll("[data-ch-scope-group]").forEach(B=>B.addEventListener("click",()=>{let $=m[Number(B.dataset.chScopeGroup)]?.[1]??[],te=$.every(K=>l.has(K.id));for(let K of $)te?l.delete(K.id):l.add(K.id);M(),E()})),C.querySelectorAll("[data-ch-scope-toggle]").forEach(B=>B.addEventListener("click",()=>{let $=Number(B.dataset.chScopeToggle);v.has($)?v.delete($):v.add($),M()})),C.querySelectorAll("[data-ch-scope-id]").forEach(B=>B.addEventListener("click",()=>{let $=B.dataset.chScopeId;l.has($)?l.delete($):l.add($),M(),E()}))};w.addEventListener("input",()=>{x=w.value.trim().toLocaleLowerCase(),M(),E()}),y.addEventListener("click",h),M(),E()});return}let b=[...i.entries()].map(([m,p])=>`
|
|
55
|
+
<div class="slm-ch-seatgroup"><span>${g(m)}</span></div>
|
|
56
56
|
${p.map(v=>`<button type="button" class="slm-ch-seatitem" role="checkbox"
|
|
57
|
-
aria-checked="false" data-ch-scope-id="${
|
|
57
|
+
aria-checked="false" data-ch-scope-id="${g(v.id)}">
|
|
58
58
|
<span class="box" aria-hidden="true">\u2713</span>
|
|
59
|
-
<span>${
|
|
59
|
+
<span>${g(v.label)}</span>
|
|
60
60
|
<span class="meta">${v.labels.length.toLocaleString()} seat${v.labels.length===1?"":"s"}</span>
|
|
61
61
|
</button>`).join("")}`).join("");this.host.openDialog(`
|
|
62
62
|
<h3 id="slm-ch-dlg-title">Choose sections</h3>
|
|
63
63
|
<p class="sub">Choose one or more. They are added to the seats already selected on the map.</p>
|
|
64
|
-
<div class="slm-ch-seatlist">${
|
|
64
|
+
<div class="slm-ch-seatlist">${b||`<div class="slm-ch-scope-empty" data-ch-state="scope-empty">This chart has no sections with selectable seats.
|
|
65
65
|
Use Drag box or the seat list instead.</div>`}</div>
|
|
66
66
|
<p class="slm-ch-err" data-ch-error hidden></p>
|
|
67
67
|
<div class="foot">
|
|
68
68
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
69
69
|
<button type="button" class="slm-btn" data-ch-add-scope disabled>Add seats</button>
|
|
70
|
-
</div>`,m=>{let p=m.querySelector("[data-ch-add-scope]"),v=m.querySelector("[data-ch-error]");m.querySelectorAll("[data-ch-scope-id]").forEach(y=>{y.addEventListener("click",()=>{let
|
|
71
|
-
aria-checked="${t.has(
|
|
72
|
-
data-ch-seat="${
|
|
70
|
+
</div>`,m=>{let p=m.querySelector("[data-ch-add-scope]"),v=m.querySelector("[data-ch-error]");m.querySelectorAll("[data-ch-scope-id]").forEach(y=>{y.addEventListener("click",()=>{let f=y.dataset.chScopeId;l.has(f)?l.delete(f):l.add(f),y.setAttribute("aria-checked",String(l.has(f))),d(p,v)})}),p.addEventListener("click",h),d(p,v)})}openSeatList(e=""){let t=new Set(this.host.selectionLabels()),s=e.trim().toLocaleLowerCase(),n=f=>!s||f.toLocaleLowerCase().includes(s),i=this.rows(),a=new Map;for(let f of i)for(let C of f.labels)a.set(C,f);let l=new Map,r=new Map,c=0,d=0;for(let f of this.host.seats()){if(!n(f.label)||(c+=1,c>this.seatListLimit))continue;d+=1;let C=this.host.sectionOfLabel(f.label),w=C?.id??"",L=l.get(w)??{label:C?.label??"Other seats",lines:[],loose:[]};l.set(w,L);let T=a.get(f.label);if(!T){L.loose.push(f.label);continue}let x=r.get(T.id)??{id:T.id,label:T.label,seats:[]};r.has(T.id)||(r.set(T.id,x),L.lines.push(x)),x.seats.push(f.label)}let h=f=>this.host.seatMeta?.(f)??this.host.statusOf(f)??"free",b=(f,C)=>{let w=this.host.statusOf(f)??"free",L=C&&f.startsWith(`${C}-`)?f.slice(C.length+1):f;return`<button type="button" class="slm-ch-seatchip is-${g(w)}" role="checkbox"
|
|
71
|
+
aria-checked="${t.has(f)}" aria-label="${g(f)} \xB7 ${g(h(f))}" title="${g(f)} \xB7 ${g(h(f))}"
|
|
72
|
+
data-ch-seat="${g(f)}">${g(L)}</button>`},m=f=>{let C=f.seats.filter(w=>t.has(w)).length;return C===0?"false":C===f.seats.length?"true":"mixed"},p=[...l.entries()].map(([f,C])=>`
|
|
73
73
|
<div class="slm-ch-seatgroup">
|
|
74
|
-
<span>${
|
|
75
|
-
${
|
|
74
|
+
<span>${g(C.label)}</span>
|
|
75
|
+
${f?`<button type="button" data-ch-section="${g(f)}">Select section</button>`:""}
|
|
76
76
|
</div>
|
|
77
77
|
${C.lines.map(w=>`
|
|
78
78
|
<div class="slm-ch-seatrow">
|
|
79
|
-
<button type="button" class="slm-ch-rowcheck" role="checkbox" aria-checked="${m(w)}" data-ch-row="${
|
|
80
|
-
aria-label="Row ${
|
|
81
|
-
<span class="box" aria-hidden="true">\u2713</span><span class="name">${
|
|
79
|
+
<button type="button" class="slm-ch-rowcheck" role="checkbox" aria-checked="${m(w)}" data-ch-row="${g(w.id)}"
|
|
80
|
+
aria-label="Row ${g(w.label)} \xB7 ${w.seats.length} seats">
|
|
81
|
+
<span class="box" aria-hidden="true">\u2713</span><span class="name">${g(w.label)}</span>
|
|
82
82
|
<span class="meta">${w.seats.length.toLocaleString()}</span>
|
|
83
83
|
</button>
|
|
84
|
-
<div class="slm-ch-seatchips">${w.seats.map(L=>
|
|
84
|
+
<div class="slm-ch-seatchips">${w.seats.map(L=>b(L,w.label)).join("")}</div>
|
|
85
85
|
</div>`).join("")}
|
|
86
|
-
${C.loose.length?`<div class="slm-ch-seatrow loose"><div class="slm-ch-seatchips">${C.loose.map(w=>
|
|
86
|
+
${C.loose.length?`<div class="slm-ch-seatrow loose"><div class="slm-ch-seatchips">${C.loose.map(w=>b(w,null)).join("")}</div></div>`:""}`).join(""),v=s?`<div class="slm-empty">Nothing matches \u201C${g(e.trim())}\u201D.</div>`:'<div class="slm-empty">No seats on this chart.</div>',y=t.size?`${t.size.toLocaleString()} selected`:"Nothing selected yet";this.host.openDialog(`
|
|
87
87
|
<h3 id="slm-ch-dlg-title">Seat list</h3>
|
|
88
88
|
<p class="sub">The same selection as the map, as checkboxes: a row takes its whole row, a seat toggles itself. Space or Enter toggles.</p>
|
|
89
89
|
<div class="slm-ch-seatlist-tools">
|
|
90
90
|
<div class="slm-find" data-ch-seatfilter>
|
|
91
|
-
<input type="search" class="slm-input" data-ch-seatfilter-input placeholder="Filter seats" aria-label="Filter seats" autocomplete="off" value="${
|
|
91
|
+
<input type="search" class="slm-input" data-ch-seatfilter-input placeholder="Filter seats" aria-label="Filter seats" autocomplete="off" value="${g(e)}">
|
|
92
92
|
</div>
|
|
93
93
|
<div class="slm-ch-seatlegend" aria-hidden="true"><i class="is-free"></i>free <i class="is-held"></i>held <i class="is-booked"></i>booked <i class="is-blocked"></i>blocked</div>
|
|
94
94
|
</div>
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
<span class="slm-ch-seatcount" data-ch-seatcount role="status">${y}</span>
|
|
99
99
|
<button type="button" class="quiet" data-ch-clear-all ${t.size?"":"disabled"}>Clear</button>
|
|
100
100
|
<button type="button" class="slm-btn" data-ch-close>Done</button>
|
|
101
|
-
</div>`,
|
|
101
|
+
</div>`,f=>{let C=L=>{this.host.clearSelection(),L.size&&this.host.selectByLabels([...L]),this.openSeatList(e)};f.querySelectorAll("[data-ch-seat]").forEach(L=>{L.addEventListener("click",()=>{let T=L.dataset.chSeat,x=new Set(this.host.selectionLabels());x.has(T)?x.delete(T):x.add(T),C(x)})}),f.querySelectorAll("[data-ch-row]").forEach(L=>{L.addEventListener("click",()=>{let T=r.get(L.dataset.chRow);if(!T)return;let x=new Set(this.host.selectionLabels()),E=T.seats.every(M=>x.has(M));for(let M of T.seats)E?x.delete(M):x.add(M);C(x)})}),f.querySelectorAll("[data-ch-section]").forEach(L=>{L.addEventListener("click",()=>{this.host.selectSection(L.dataset.chSection),this.openSeatList(e)})}),f.querySelector("[data-ch-clear-all]")?.addEventListener("click",()=>C(new Set)),f.querySelector("[data-ch-more]")?.addEventListener("click",()=>{this.seatListLimit+=xe,this.openSeatList(e)});let w=f.querySelector("[data-ch-seatfilter-input]");if(w){let L=null;w.addEventListener("input",()=>{L&&clearTimeout(L),L=setTimeout(()=>{this.openSeatList(w.value);let T=this.lastDialogInput();T&&(T.focus(),T.setSelectionRange(T.value.length,T.value.length))},120)}),e&&(w.focus(),w.setSelectionRange(w.value.length,w.value.length))}})}lastDialogInput(){return document.querySelector(".slm-ch-dialog [data-ch-seatfilter-input]")}}});function O(o){return o==null||o===""||o===R}function V(o,e){let t=(o??"").trim();return((/\p{L}/u.exec(t)?.[0]??t[0]??"")||e).toUpperCase().slice(0,1)}function ie(o,e){let t=new Set([...e].map(i=>V(i,"")).filter(Boolean)),s=V(o,"");return{letter:ts.includes(s)&&!t.has(s)?s:[...ts].find(i=>!t.has(i))??(s||"X"),color:Me[t.size%Me.length]}}function Te(o,e=0){return O(o.id)?{letter:V(o.marker,"P"),color:o.color||Gs}:{letter:V(o.marker||o.name,"?"),color:o.color||Me[e%Me.length]}}function Ee(o,e,t){let s=new Map;for(let a of o){let l=Je(e.get(a));s.set(l,(s.get(l)??0)+1)}let n=[{id:R,name:t?.publicSale?.name??P},...(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:O(a)?P:"Another channel",count:l});return i}function Je(o){return O(o)?R:o}function Qe(o){return{count:o.length,labels:o.slice(0,ss),truncated:o.length>ss}}function Re(o){let{labels:e,allocation:t,statusOf:s,nameOf:n}=o,i=Je(o.targetChannelId),a=new Set,l=0,r=0,c=new Map,d=[],h=[],b=[];for(let p of e){if(a.has(p))continue;a.add(p);let v=s(p);if(!v){b.push(p);continue}let y=Je(t.get(p));if(y===i){r+=1;continue}if(v==="held"){d.push(p);continue}if(v==="booked"){h.push(p);continue}y===R?l+=1:c.set(y,(c.get(y)??0)+1)}let m=[...c.entries()].map(([p,v])=>({channelId:p,name:n(p),count:v}));return{changedFromPublic:{count:l},movedFromOtherChannel:{count:m.reduce((p,v)=>p+v.count,0),channels:m},alreadyInTarget:{count:r},skippedHeld:Qe(d),skippedBooked:Qe(h),notFound:Qe(b)}}function Q(o){return o.changedFromPublic.count+o.movedFromOtherChannel.count}function $e(o){return o.movedFromOtherChannel.count>0}function Ae(o,e){let t=[];o.changedFromPublic.count&&t.push({kind:"add",icon:"+",count:o.changedFromPublic.count,text:`${o.changedFromPublic.count.toLocaleString()} from ${P}`});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:Ce(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:Ce(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:Ce(o.notFound)}),t}function Ce(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 Ie(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 He(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 q(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 Pe(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 Xs(o){return o==="hosted_link"?"hosted_link":o==="server"?"server":o==="staff"?"internal":null}function J(o){let e=et(o?.accessIntent),t=Xs(o?.route),s=`This channel is set to "${q(e)}"`;return t?`${s}, so it cannot do that. Switch it to "${q(t)}" first.`:`${s}, so it cannot do that. Choose a different route for this channel first.`}function et(o){return o==="internal"||o==="server"||o==="hosted_link"||o==="none"?o:"none"}function Le(o,e,t){return`${o.toLocaleString()} ${o===1?e:t}`}function Be(o){let e=Math.max(0,o?.liveAccessLinks??0),t=Math.max(0,o?.activeSessions??0),s=et(o?.from),n=et(o?.to),a=`${[e?Le(e,"buyer link is live","buyer links are live"):null,t?Le(t,"buyer is in a checkout","buyers are in a checkout"):null].filter(Boolean).join(", and ")||"Buyers are inside this channel"} on "${q(s)}". Moving it to "${q(n)}" changes what happens to them.`,l=[];return e&&l.push(`${Le(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(`${Le(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 De(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 oe(o){return o.state==="active"&&o.status==="active"}function Zs(o){return Number.isFinite(o)?new Date(o).toLocaleString(void 0,{day:"numeric",month:"short",year:"numeric",hour:"numeric",minute:"2-digit"}):"\u2014"}function le(o){return[{k:"Expires",v:Zs(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 U(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 J(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 ns(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?Ce({count:e.count,labels:e.labels,truncated:e.truncated??!1}):void 0}))}function Oe(o){return o==="builtin"?"Built-in":o==="active"?"Active":o==="paused"?"Paused":"Archived"}var R,P,Me,Gs,ts,ss,ae,ze=z(()=>{"use strict";R="public",P="Public sale";Me=["#a78bfa","#2dd4bf","#fb923c","#60a5fa","#f472b6","#a3e635","#f87171","#38bdf8","#c084fc","#facc15"],Gs="#f4b740",ts="ABCDEFGHJKLMNPQRSTUVWXYZ";ss=12;ae={maxRedemptions:100,maxQuantity:4}});function ee(o){return o.map((e,t)=>`
|
|
102
102
|
<div class="slm-ch-bucket" style="animation-delay:${Math.min(t,4)*30}ms">
|
|
103
103
|
<span class="ico ${e.kind}" aria-hidden="true">${u(e.icon)}</span>
|
|
104
104
|
<span><b>${e.count.toLocaleString()}</b> ${u(e.text.replace(/^[\d,.\s]+/,""))}
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
access session for this channel with the SeatLayer server SDK and hands it to the widget. A channel name
|
|
111
111
|
on its own never grants access.</p>
|
|
112
112
|
<p class="slm-note"><a class="slm-linkbtn" href="https://docs.seatlayer.io/server-api/channels"
|
|
113
|
-
target="_blank" rel="noreferrer noopener">Read the website integration guide \u2192</a></p>`});function an(o){return o?.dataset?.theme==="light"?nn:sn}function ds(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=an(o.host.root),c=o.host.isSeatDetail(),d=Math.max(3,o.host.seatPixelSize()),h=d/2,
|
|
113
|
+
target="_blank" rel="noreferrer noopener">Read the website integration guide \u2192</a></p>`});function an(o){return o?.dataset?.theme==="light"?nn:sn}function ds(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=an(o.host.root),c=o.host.isSeatDetail(),d=Math.max(3,o.host.seatPixelSize()),h=d/2,b=o.view==="preview"?o.previewProjection:null,m=b?new Set(b.available===!1?[]:b.eligible??[]):null,p=new Map,v=!c&&o.host.sections().length>1?new Map:null,y=o.view==="preview"&&c&&d<=15?new Map:null;for(let f of o.host.seats()){let C=o.host.statusOf(f.label)??"free",w=o.allocation.get(f.label)??R;if(w!==R){let E=p.get(w)??{x:0,y:0,n:0};E.x+=f.x,E.y+=f.y,E.n+=1,p.set(w,E)}if(!c){let E=o.host.sectionOfLabel(f.label),M=E?o.host.worldToScreen({x:f.x,y:f.y}):null;if(v&&E&&M){let I=v.get(E.id)??{label:E.label,minX:M.x,minY:M.y,maxX:M.x,maxY:M.y};I.minX=Math.min(I.minX,M.x),I.minY=Math.min(I.minY,M.y),I.maxX=Math.max(I.maxX,M.x),I.maxY=Math.max(I.maxY,M.y),v.set(E.id,I)}continue}if(C!=="free")continue;let L=null,T=null;if(o.view==="preview"?m?.has(f.label)?(L=en,T=tn):(L=r.unavailableFill,T=r.unavailableStroke):w!==R&&(L=o.markerFor(w).color,T=r.allocationStroke),!L)continue;let x=o.host.worldToScreen({x:f.x,y:f.y});if(x&&!(x.x<-d||x.y<-d||x.x>n+d||x.y>i+d)){if(y){let E=o.host.sectionOfLabel(f.label);if(E){let M=y.get(E.id)??{label:E.label,minX:x.x,minY:x.y,maxX:x.x,maxY:x.y};M.minX=Math.min(M.minX,x.x),M.minY=Math.min(M.minY,x.y),M.maxX=Math.max(M.maxX,x.x),M.maxY=Math.max(M.maxY,x.y),y.set(E.id,M)}}if(l.fillStyle=L,o.view==="preview"||w!==R){let E=Math.max(2,h+Math.min(1.5,h*.06));l.globalAlpha=1,l.beginPath(),l.arc(x.x,x.y,E,0,Math.PI*2),l.fill(),l.strokeStyle=T??L,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"&&m?.has(f.label)&&d>=22&&on(l,f.label,x.x,x.y,E)}else l.globalAlpha=.85,l.fillRect(x.x-h,x.y-h,d,d)}}l.globalAlpha=1,y&&dn(l,y,r),ln(v,o),hn(p,o,l)}function on(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 ln(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`),cn(l,e,()=>e.onSectionTargetClick(s)),t.appendChild(l)}}function rn(o,e){let t={button:0,buttons:1,clientX:e.x,clientY:e.y,bubbles:!0,cancelable:!0,composed:!0};return typeof PointerEvent=="function"?new PointerEvent("pointerdown",{...t,pointerId:o.pointerId,pointerType:o.pointerType,isPrimary:!0}):new MouseEvent("pointerdown",t)}function cs(o){return o.host.mapLayer.querySelector(".slm-map-host")??o.host.mapLayer}function cn(o,e,t){o.addEventListener("wheel",r=>{let c=cs(e);c!==o&&(r.preventDefault(),c.dispatchEvent(new WheelEvent("wheel",{deltaX:r.deltaX,deltaY:r.deltaY,deltaZ:r.deltaZ,deltaMode:r.deltaMode,clientX:r.clientX,clientY:r.clientY,ctrlKey:r.ctrlKey,shiftKey:r.shiftKey,altKey:r.altKey,metaKey:r.metaKey,bubbles:!0,cancelable:!0,composed:!0})))},{passive:!1});let s=null,n=!1,i=()=>{s=null,e.layer?.classList.remove("panning"),window.removeEventListener("pointermove",a,!0),window.removeEventListener("pointerup",l,!0),window.removeEventListener("pointercancel",l,!0)};function a(r){if(!s||n||Math.abs(r.clientX-s.x)<rs&&Math.abs(r.clientY-s.y)<rs)return;n=!0;let c=s;e.layer?.classList.add("panning");let d=document.elementFromPoint?.(c.x,c.y)??null;(d&&d!==o?d:cs(e)).dispatchEvent(rn(r,c))}function l(){i()}o.addEventListener("pointerdown",r=>{n=!1,s={x:r.clientX,y:r.clientY},window.addEventListener("pointermove",a,!0),window.addEventListener("pointerup",l,!0),window.addEventListener("pointercancel",l,!0)}),o.addEventListener("click",r=>{if(n){n=!1,r.preventDefault(),r.stopPropagation();return}t()})}function dn(o,e,t){for(let s of e.values()){let n=s.maxX-s.minX,i=s.maxY-s.minY;if(n<52||i<26)continue;let a=(s.minX+s.maxX)/2,l=(s.minY+s.maxY)/2,r=Math.max(11,Math.min(15,i*.16));o.font=`800 ${r}px var(--slm-font, system-ui, sans-serif)`;let c=Math.min(n-8,o.measureText(s.label).width+18),d=r+10;o.fillStyle=t.sectionPlate,o.fillRect(a-c/2,l-d/2,c,d),o.fillStyle=t.sectionPlateInk,o.textAlign="center",o.textBaseline="middle",o.fillText(s.label,a,l)}}function hn(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,Js);for(let[i,a]of n){let l=e.list?.channels.find(h=>h.id===i);if(!l)continue;let r=e.host.worldToScreen({x:a.x/a.n,y:a.y/a.n});if(!r)continue;let c=e.markerFor(i),d=document.createElement("span");d.className="slm-ch-flag",d.style.left=`${r.x}px`,d.style.top=`${r.y}px`,d.innerHTML=`<span class="mk" style="background:${u(c.color)}">${u(c.letter)}</span>${u(l.name)}${l.state==="paused"?" \xB7 Paused":""}`,s.appendChild(d)}}var Js,en,tn,sn,nn,rs,hs=z(()=>{"use strict";ze();Fe();Js=8,en="#6e7bff",tn="#b9c0ff",sn={unavailableFill:"#303846",unavailableStroke:"#4b5669",allocationStroke:"#101723",sectionPlate:"rgba(11,16,28,.88)",sectionPlateInk:"#f8fafc"},nn={unavailableFill:"rgba(156,163,175,.55)",unavailableStroke:"rgba(107,114,128,.65)",allocationStroke:"#ffffff",sectionPlate:"rgba(255,255,255,.9)",sectionPlateInk:"#172033"};rs=4});var ms,ps=z(()=>{"use strict";ms=`
|
|
114
114
|
.slm{--slm-ch-marker-ink:#0e1017;
|
|
115
115
|
--slm-mo-instant:80ms;--slm-mo-quick:140ms;--slm-mo-base:200ms;--slm-mo-slow:320ms;--slm-mo-ambient:2000ms;
|
|
116
116
|
--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);
|
|
@@ -467,10 +467,10 @@
|
|
|
467
467
|
<div class="slm-ch-list">${this.channelRowHtml(s)}</div>
|
|
468
468
|
${l}
|
|
469
469
|
${i}
|
|
470
|
-
${n}`}distributeHtml(e){let t=e.access?.intent??"none",s=e.access?.hasActiveGrants===!0,n=this.linksState!=="unsupported",i=this.links.some(oe),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,c,d,h)=>{let
|
|
471
|
-
<b>${u(q(r))}${
|
|
470
|
+
${n}`}distributeHtml(e){let t=e.access?.intent??"none",s=e.access?.hasActiveGrants===!0,n=this.linksState!=="unsupported",i=this.links.some(oe),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,c,d,h)=>{let b=r===t;return`<div class="slm-ch-dist${b?" on":""}" data-ch-route="${u(r)}">
|
|
471
|
+
<b>${u(q(r))}${b?'<span class="cur">Current route</span>':""}</b>
|
|
472
472
|
<span class="why">${u(Pe(r))}</span>
|
|
473
|
-
${
|
|
473
|
+
${b&&!d?"":`<button type="button" class="slm-btn${h&&!b?"":" ghost"}"
|
|
474
474
|
data-ch-act="${u(c)}">${u(d)}</button>`}
|
|
475
475
|
</div>`};return`
|
|
476
476
|
<p class="slm-eyebrow" style="margin-top:14px">Distribute</p>
|
|
@@ -571,7 +571,7 @@
|
|
|
571
571
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
572
572
|
<button type="button" class="slm-btn ghost" data-ch-create="plain">Create without allocating</button>
|
|
573
573
|
<button type="button" class="slm-btn" data-ch-create="allocate">Create and allocate seats</button>
|
|
574
|
-
</div>`,n=>{let i=n.querySelector("#slm-ch-name"),a=n.querySelector("[data-ch-marker]");i.addEventListener("input",()=>{let l=ie(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:V(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 S?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)??P,l=Ae(i,a),r=n?n.applied:Q(s),c=!n&&t.length>0&&r===0,d=!n&&t.length>_,h=ee(l),
|
|
574
|
+
</div>`,n=>{let i=n.querySelector("#slm-ch-name"),a=n.querySelector("[data-ch-marker]");i.addEventListener("input",()=>{let l=ie(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:V(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 S?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)??P,l=Ae(i,a),r=n?n.applied:Q(s),c=!n&&t.length>0&&r===0,d=!n&&t.length>_,h=ee(l),b=n?'<div class="foot"><button type="button" class="slm-btn" data-ch-close>Done</button></div>':`<div class="foot">
|
|
575
575
|
<button type="button" class="quiet" data-ch-close>Back</button>
|
|
576
576
|
<button type="button" class="slm-btn" data-ch-apply ${c||d||e.busy?"disabled":""}>
|
|
577
577
|
${e.busy?"Applying\u2026":`Apply ${r.toLocaleString()} change${r===1?"":"s"}`}
|
|
@@ -586,7 +586,7 @@
|
|
|
586
586
|
${h||'<div class="slm-empty">Nothing selected.</div>'}
|
|
587
587
|
${m}
|
|
588
588
|
<p class="slm-ch-err" data-ch-error ${e.error?"":"hidden"}>${u(e.error??"")}</p>
|
|
589
|
-
${
|
|
589
|
+
${b}`,y=>{y.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>_){this.showDialogError(`Choose at most ${_.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:O(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 S&&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 S&&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)??P,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>
|
|
590
590
|
<span>Assigned <b>${e.applied.toLocaleString()}</b> seat${e.applied===1?"":"s"} to ${u(t)}
|
|
591
591
|
${s?` \xB7 ${s.toLocaleString()} skipped`:""}</span>
|
|
592
592
|
<span class="grow"></span>
|
|
@@ -614,12 +614,12 @@
|
|
|
614
614
|
<div class="foot">
|
|
615
615
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
616
616
|
<button type="button" class="slm-btn" data-ch-rename>Save name</button>
|
|
617
|
-
</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 S&&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 c=r?.id??null,d=`${a.key}\0${c??""}`,h=r?.price??a.price??0,
|
|
617
|
+
</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 S&&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 c=r?.id??null,d=`${a.key}\0${c??""}`,h=r?.price??a.price??0,b=n.get(d),m=r?`${a.label} \xB7 ${r.name}`:a.label;return`<label class="slm-ch-price-row">
|
|
618
618
|
<span><b>${u(m)}</b><small>Event price ${u(String(h))}</small></span>
|
|
619
619
|
<input class="slm-input" type="number" min="0" max="1000000" step="0.01"
|
|
620
620
|
inputmode="decimal" aria-label="Custom price for ${u(m)}"
|
|
621
621
|
data-ch-price-category="${u(a.key)}" data-ch-price-tier="${u(c??"")}"
|
|
622
|
-
placeholder="${u(String(h))}" value="${
|
|
622
|
+
placeholder="${u(String(h))}" value="${b===void 0?"":u(String(b))}"
|
|
623
623
|
${e.busy?"disabled":""} />
|
|
624
624
|
</label>`})).join("");this.renderScrim(`
|
|
625
625
|
<h3 id="slm-ch-dlg-title">Prices for ${u(t.name)}</h3>
|
|
@@ -747,7 +747,7 @@
|
|
|
747
747
|
<div class="foot">
|
|
748
748
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
749
749
|
<button type="button" class="slm-btn danger" data-ch-lk-revoke>Revoke link</button>
|
|
750
|
-
</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(U(n instanceof S?n:void 0)),n instanceof S||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 fn={};ot(fn,{ACCESS_LINK_DEFAULTS:()=>ae,ChannelsMode:()=>re,ManageApi:()=>G,ManageApiError:()=>S,PUBLIC_CHANNEL_ID:()=>R,PUBLIC_CHANNEL_NAME:()=>P,SeatManager:()=>qe,accessIntentDescription:()=>Pe,accessIntentLabel:()=>q,accessLine:()=>He,accessLinkBadge:()=>De,accessLinkErrorCopy:()=>U,accessLinkIsLive:()=>oe,accessLinkPolicyLines:()=>le,bucketRows:()=>Ae,bucketRowsHtml:()=>ee,dropReviewRows:()=>ns,intentForbidsCopy:()=>J,intentSwitchBlockedCopy:()=>Be,isPublicChannelId:()=>O,markerLetter:()=>V,markerOf:()=>Te,mutationCount:()=>Q,needsMoveConfirmation:()=>$e,planAssignment:()=>Re,retryAfterCopy:()=>Ie,selectionSources:()=>Ee,stateBadge:()=>Oe,suggestMarker:()=>ie});module.exports=Ts(fn);ce();var rt={hold:"Held",release:"Released",expire:"Expired",book:"Booked",unbook:"Cancelled",block:"Blocked",unblock:"Unblocked"},de=class{constructor(e,t){this.host=e;this.fetchPage=t;this.closed=!1;this.busy=!1;this.generation=0;this.entries=[];this.next=null;this.summary=document.createElement("div");this.list=document.createElement("div");this.message=document.createElement("div");this.older=document.createElement("button");this.latest=document.createElement("button");e.className="slm-seat-history",this.summary.className="slm-history-counts",this.list.className="slm-history-list",this.list.setAttribute("role","region"),this.list.setAttribute("aria-label","Seat history"),this.list.tabIndex=0,this.message.className="slm-note",this.message.setAttribute("role","status"),this.older.className=this.latest.className="slm-btn ghost",this.older.textContent="Load older",this.older.hidden=!0,this.latest.textContent="New activity \xB7 Show latest",this.latest.hidden=!0,this.older.onclick=()=>{this.load(!0)},this.latest.onclick=()=>{this.list.scrollTop=0,this.latest.hidden=!0,this.load()},e.append(this.summary,this.latest,this.list,this.message,this.older),this.load()}destroy(){this.closed=!0,this.generation++}refresh(){this.busy||this.load(!1,!0)}async load(e=!1,t=!1){if(this.closed||this.busy||e&&!this.next)return;this.busy=!0,this.older.disabled=!0;let s=this.generation;t||(this.message.textContent="Loading history\u2026");try{let n=await this.fetchPage(e?this.next:void 0,this.action);if(this.closed||s!==this.generation)return;if(this.paintCounts(n),t&&this.entries.length&&n.entries[0]?.id!==this.entries[0]?.id&&this.list.scrollTop>24){this.latest.hidden=!1;return}let i=!t||n.entries[0]?.id!==this.entries[0]?.id;e?(this.entries=[...this.entries,...n.entries.filter(a=>!this.entries.some(l=>l.id===a.id))],this.next=n.nextBefore):i&&(this.entries=n.entries,this.next=n.nextBefore),i&&this.paintRows(),this.older.hidden=this.next===null,this.message.textContent=this.entries.length?"":"No recorded activity for this seat."}catch{if(!this.closed){this.message.textContent="History could not be loaded. ";let n=document.createElement("button");n.className="slm-btn ghost",n.textContent="Retry",n.onclick=()=>{this.load(e)},this.message.append(n)}}finally{this.busy=!1,this.older.disabled=!1}}paintCounts(e){let t=[{action:"",count:e.total},...e.counts];this.summary.replaceChildren(...t.map(({action:s,count:n})=>{let i=document.createElement("button");return i.type="button",i.textContent=s?`${rt[s]??s} ${n}`:`${n} changes`,i.setAttribute("aria-pressed",String((this.action??"")===s)),i.onclick=()=>{this.busy||(this.action=s||void 0,this.entries=[],this.next=null,this.list.scrollTop=0,this.latest.hidden=!0,this.load())},i}))}paintRows(){let e=this.list.scrollTop;this.list.replaceChildren(...this.entries.map(t=>{let s=document.createElement("div");s.className="slm-history-row",s.dataset.action=t.action;let n=document.createElement("time");n.dateTime=new Date(t.at).toISOString(),n.textContent=new Date(t.at).toLocaleString(void 0,{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}),n.title=new Date(t.at).toString();let i=document.createElement("strong");return i.textContent=rt[t.action]??t.action,s.append(n,i),s})),this.list.scrollTop=e}};var Es={held:"HOLD",booked:"BOOK",expired:"EXPIRE",released:"RELEASE",cancelled:"CANCEL",blocked:"BLOCK",unblocked:"ON SALE",available:"FREE"},ct={held:"Held",booked:"Booked",expired:"Hold expired",released:"Hold released",cancelled:"Booking cancelled",blocked:"Blocked",unblocked:"Back on sale",available:"Available again"},he=class{constructor(e,t,s){this.host=e;this.locate=s;this.items=[];this.shown=new Set;this.paused=!1;this.limit=100;this.signature="unrendered";this.abort=new AbortController;e.innerHTML='<button class="slm-new-activity" hidden></button><div class="slm-activity-list" role="region" aria-label="Recent activity" tabindex="0"></div><button class="slm-more-activity" hidden>Show more activity</button>',this.list=e.querySelector(".slm-activity-list"),this.newer=e.querySelector(".slm-new-activity"),this.more=e.querySelector(".slm-more-activity");let n={signal:this.abort.signal},i=()=>{this.paused=!1,this.signature="unrendered",this.list.scrollTop=0,this.render()};this.list.addEventListener("scroll",()=>{this.list.scrollTop>24&&(this.paused=!0)},n),this.list.addEventListener("focusin",()=>{this.paused=!0},n),this.list.addEventListener("toggle",a=>{a.target.open&&(this.paused=!0)},{...n,capture:!0}),this.newer.addEventListener("click",i,n),this.more.addEventListener("click",()=>{this.limit=200,this.signature="unrendered",this.render(!0)},n)}update(e){this.items=e,this.render()}render(e=!1){let t=this.items,s=t.filter(a=>!this.shown.has(a.id)).length;if(this.newer.hidden=!this.paused,this.newer.textContent=s?`${s} new activit${s===1?"y":"ies"} \xB7 Back to live`:"Reading earlier activity \xB7 Back to live",this.paused&&!e)return;let n=t.slice(0,this.limit),i=n.map(a=>`${a.id}:${a.verb}`).join("|");if(i!==this.signature){if(this.signature=i,this.shown=new Set(t.map(a=>a.id)),this.list.replaceChildren(),!n.length){let a=document.createElement("p");a.className="slm-activity-empty",a.textContent=this.items.length?"No activity matches these filters.":"Waiting for activity. Holds, bookings and releases will appear here.",this.list.append(a)}for(let a of n){let l=document.createElement("article");l.className="slm-activity-entry",l.dataset.status=a.status;let r=document.createElement("button");r.type="button",r.className="slm-activity-row";let c=`${ct[a.verb]??a.verb} \xB7 ${a.count} seat${a.count===1?"":"s"} \xB7 ${a.sectionLabels?.join(", ")||"Event inventory"} \xB7 ${a.labels.join(", ")} \xB7 ${new Date(a.at).toLocaleString()}`;r.title=`${c} \u2014 click to show seats on the map`,r.setAttribute("aria-label",`Show seats on map: ${c}`),r.addEventListener("click",()=>this.locate(a.id));let d=document.createElement("time");d.dateTime=new Date(a.at).toISOString(),d.textContent=new Date(a.at).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});let h=document.createElement("strong");h.textContent=Es[a.verb]??a.verb,h.title=ct[a.verb]??a.verb;let
|
|
750
|
+
</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(U(n instanceof S?n:void 0)),n instanceof S||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 fn={};ot(fn,{ACCESS_LINK_DEFAULTS:()=>ae,ChannelsMode:()=>re,ManageApi:()=>G,ManageApiError:()=>S,PUBLIC_CHANNEL_ID:()=>R,PUBLIC_CHANNEL_NAME:()=>P,SeatManager:()=>qe,accessIntentDescription:()=>Pe,accessIntentLabel:()=>q,accessLine:()=>He,accessLinkBadge:()=>De,accessLinkErrorCopy:()=>U,accessLinkIsLive:()=>oe,accessLinkPolicyLines:()=>le,bucketRows:()=>Ae,bucketRowsHtml:()=>ee,dropReviewRows:()=>ns,intentForbidsCopy:()=>J,intentSwitchBlockedCopy:()=>Be,isPublicChannelId:()=>O,markerLetter:()=>V,markerOf:()=>Te,mutationCount:()=>Q,needsMoveConfirmation:()=>$e,planAssignment:()=>Re,retryAfterCopy:()=>Ie,selectionSources:()=>Ee,stateBadge:()=>Oe,suggestMarker:()=>ie});module.exports=Ts(fn);ce();var rt={hold:"Held",release:"Released",expire:"Expired",book:"Booked",unbook:"Cancelled",block:"Blocked",unblock:"Unblocked"},de=class{constructor(e,t){this.host=e;this.fetchPage=t;this.closed=!1;this.busy=!1;this.generation=0;this.entries=[];this.next=null;this.summary=document.createElement("div");this.list=document.createElement("div");this.message=document.createElement("div");this.older=document.createElement("button");this.latest=document.createElement("button");e.className="slm-seat-history",this.summary.className="slm-history-counts",this.list.className="slm-history-list",this.list.setAttribute("role","region"),this.list.setAttribute("aria-label","Seat history"),this.list.tabIndex=0,this.message.className="slm-note",this.message.setAttribute("role","status"),this.older.className=this.latest.className="slm-btn ghost",this.older.textContent="Load older",this.older.hidden=!0,this.latest.textContent="New activity \xB7 Show latest",this.latest.hidden=!0,this.older.onclick=()=>{this.load(!0)},this.latest.onclick=()=>{this.list.scrollTop=0,this.latest.hidden=!0,this.load()},e.append(this.summary,this.latest,this.list,this.message,this.older),this.load()}destroy(){this.closed=!0,this.generation++}refresh(){this.busy||this.load(!1,!0)}async load(e=!1,t=!1){if(this.closed||this.busy||e&&!this.next)return;this.busy=!0,this.older.disabled=!0;let s=this.generation;t||(this.message.textContent="Loading history\u2026");try{let n=await this.fetchPage(e?this.next:void 0,this.action);if(this.closed||s!==this.generation)return;if(this.paintCounts(n),t&&this.entries.length&&n.entries[0]?.id!==this.entries[0]?.id&&this.list.scrollTop>24){this.latest.hidden=!1;return}let i=!t||n.entries[0]?.id!==this.entries[0]?.id;e?(this.entries=[...this.entries,...n.entries.filter(a=>!this.entries.some(l=>l.id===a.id))],this.next=n.nextBefore):i&&(this.entries=n.entries,this.next=n.nextBefore),i&&this.paintRows(),this.older.hidden=this.next===null,this.message.textContent=this.entries.length?"":"No recorded activity for this seat."}catch{if(!this.closed){this.message.textContent="History could not be loaded. ";let n=document.createElement("button");n.className="slm-btn ghost",n.textContent="Retry",n.onclick=()=>{this.load(e)},this.message.append(n)}}finally{this.busy=!1,this.older.disabled=!1}}paintCounts(e){let t=[{action:"",count:e.total},...e.counts];this.summary.replaceChildren(...t.map(({action:s,count:n})=>{let i=document.createElement("button");return i.type="button",i.textContent=s?`${rt[s]??s} ${n}`:`${n} changes`,i.setAttribute("aria-pressed",String((this.action??"")===s)),i.onclick=()=>{this.busy||(this.action=s||void 0,this.entries=[],this.next=null,this.list.scrollTop=0,this.latest.hidden=!0,this.load())},i}))}paintRows(){let e=this.list.scrollTop;this.list.replaceChildren(...this.entries.map(t=>{let s=document.createElement("div");s.className="slm-history-row",s.dataset.action=t.action;let n=document.createElement("time");n.dateTime=new Date(t.at).toISOString(),n.textContent=new Date(t.at).toLocaleString(void 0,{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}),n.title=new Date(t.at).toString();let i=document.createElement("strong");return i.textContent=rt[t.action]??t.action,s.append(n,i),s})),this.list.scrollTop=e}};var Es={held:"HOLD",booked:"BOOK",expired:"EXPIRE",released:"RELEASE",cancelled:"CANCEL",blocked:"BLOCK",unblocked:"ON SALE",available:"FREE"},ct={held:"Held",booked:"Booked",expired:"Hold expired",released:"Hold released",cancelled:"Booking cancelled",blocked:"Blocked",unblocked:"Back on sale",available:"Available again"},he=class{constructor(e,t,s){this.host=e;this.locate=s;this.items=[];this.shown=new Set;this.paused=!1;this.limit=100;this.signature="unrendered";this.abort=new AbortController;e.innerHTML='<button class="slm-new-activity" hidden></button><div class="slm-activity-list" role="region" aria-label="Recent activity" tabindex="0"></div><button class="slm-more-activity" hidden>Show more activity</button>',this.list=e.querySelector(".slm-activity-list"),this.newer=e.querySelector(".slm-new-activity"),this.more=e.querySelector(".slm-more-activity");let n={signal:this.abort.signal},i=()=>{this.paused=!1,this.signature="unrendered",this.list.scrollTop=0,this.render()};this.list.addEventListener("scroll",()=>{this.list.scrollTop>24&&(this.paused=!0)},n),this.list.addEventListener("focusin",()=>{this.paused=!0},n),this.list.addEventListener("toggle",a=>{a.target.open&&(this.paused=!0)},{...n,capture:!0}),this.newer.addEventListener("click",i,n),this.more.addEventListener("click",()=>{this.limit=200,this.signature="unrendered",this.render(!0)},n)}update(e){this.items=e,this.render()}render(e=!1){let t=this.items,s=t.filter(a=>!this.shown.has(a.id)).length;if(this.newer.hidden=!this.paused,this.newer.textContent=s?`${s} new activit${s===1?"y":"ies"} \xB7 Back to live`:"Reading earlier activity \xB7 Back to live",this.paused&&!e)return;let n=t.slice(0,this.limit),i=n.map(a=>`${a.id}:${a.verb}`).join("|");if(i!==this.signature){if(this.signature=i,this.shown=new Set(t.map(a=>a.id)),this.list.replaceChildren(),!n.length){let a=document.createElement("p");a.className="slm-activity-empty",a.textContent=this.items.length?"No activity matches these filters.":"Waiting for activity. Holds, bookings and releases will appear here.",this.list.append(a)}for(let a of n){let l=document.createElement("article");l.className="slm-activity-entry",l.dataset.status=a.status;let r=document.createElement("button");r.type="button",r.className="slm-activity-row";let c=`${ct[a.verb]??a.verb} \xB7 ${a.count} seat${a.count===1?"":"s"} \xB7 ${a.sectionLabels?.join(", ")||"Event inventory"} \xB7 ${a.labels.join(", ")} \xB7 ${new Date(a.at).toLocaleString()}`;r.title=`${c} \u2014 click to show seats on the map`,r.setAttribute("aria-label",`Show seats on map: ${c}`),r.addEventListener("click",()=>this.locate(a.id));let d=document.createElement("time");d.dateTime=new Date(a.at).toISOString(),d.textContent=new Date(a.at).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});let h=document.createElement("strong");h.textContent=Es[a.verb]??a.verb,h.title=ct[a.verb]??a.verb;let b=document.createElement("span");if(b.className="slm-activity-seats",b.textContent=a.labels.join(", "),r.append(d,h,b),l.append(r),a.count>1){let m=document.createElement("details");m.className="slm-activity-details";let p=document.createElement("summary");p.textContent="\u22EF",p.setAttribute("aria-label",`Show all ${a.count} seats`);let v=document.createElement("p");v.textContent=c,m.append(p,v),l.append(m)}this.list.append(l)}this.more.hidden=t.length<=this.limit}}destroy(){this.abort.abort()}};var me=class{constructor(e){this.host=e;this.moving=!1;this.space=!1;this.monitor=!1;this.selected=0;this.abort=new AbortController;let t=document.createElement("div");t.className="slm-navigation";let s=y=>`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${y}</svg>`,n=s('<path d="M8 13V6a2 2 0 0 1 4 0v6-8a2 2 0 0 1 4 0v8-6a2 2 0 0 1 4 0v10c0 4-3 6-7 6-3 0-5-2-7-5l-3-4a2 2 0 0 1 3-2l2 2Z"/>'),i=s('<path d="m5 3 14 10-7 1-3 7-4-18Z"/>'),a=s('<circle cx="10.5" cy="10.5" r="6.5"/><path d="m16 16 5 5"/>'),l=s('<path d="M7 6h10M12 1v10M7 18h10"/>'),r=s('<rect x="3" y="4" width="18" height="16" rx="2"/><path d="M15 4v16"/>');t.innerHTML=`<div class="slm-navigation-tools" role="group" aria-label="Map navigation">
|
|
751
751
|
<button type="button" data-nav="move" aria-label="Move" aria-pressed="false" title="Drag to move the map; hold Space temporarily">${n}</button>
|
|
752
752
|
<button type="button" data-nav="select" aria-label="Select" aria-pressed="true" title="Drag to select seats \xB7 drag empty floor to move">${i}</button>
|
|
753
753
|
<button type="button" data-nav="search" aria-label="Search" title="Search seats, rows or sections" aria-expanded="false">${a}</button>
|
|
@@ -757,8 +757,8 @@
|
|
|
757
757
|
<span class="slm-navigation-count" role="status" aria-live="polite">0 selected</span>
|
|
758
758
|
<button type="button" class="slm-navigation-clear" data-nav="clear" hidden title="Clear the selection">Clear</button>
|
|
759
759
|
<button type="button" data-nav="rail" aria-label="Hide details" title="Hide details" aria-expanded="true">${r}</button>
|
|
760
|
-
</div><div class="slm-navigation-search" hidden><input type="search" aria-label="Find section, row or seat" placeholder="Find section, row or seat"><div class="slm-navigation-results" hidden></div></div>`,e.map.after(t),this.bar=t,this.move=t.querySelector('[data-nav="move"]'),this.select=t.querySelector('[data-nav="select"]'),this.search=t.querySelector("input"),this.count=t.querySelector(".slm-navigation-count"),this.clear=t.querySelector('[data-nav="clear"]'),this.results=t.querySelector(".slm-navigation-results"),this.location=document.createElement("div"),this.location.className="slm-location",this.location.hidden=!0,this.location.setAttribute("role","status"),e.map.after(this.location);let c={signal:this.abort.signal},d=t.querySelector('[data-nav="search"]'),h=t.querySelector(".slm-navigation-search"),
|
|
761
|
-
aria-labelledby="slm-ch-dlg-title" tabindex="-1">${e}</div>`,o.appendChild(i);let a=i.firstElementChild,l=!1,r={scrim:i,dialog:a,close:({restoreFocus:d=!0}={})=>{l||(l=!0,i.remove(),d&&n?.focus?.(),s.onClose?.())}};return a.querySelectorAll("[data-ch-close]").forEach(d=>{d.addEventListener("click",()=>r.close())}),i.addEventListener("keydown",d=>{if(d.key==="Escape"){d.stopPropagation(),r.close();return}if(d.key!=="Tab")return;let h=[...a.querySelectorAll('summary,button:not([disabled]),select:not([hidden]),input,textarea,a[href],[tabindex]:not([tabindex="-1"])')];if(!h.length)return;let
|
|
760
|
+
</div><div class="slm-navigation-search" hidden><input type="search" aria-label="Find section, row or seat" placeholder="Find section, row or seat"><div class="slm-navigation-results" hidden></div></div>`,e.map.after(t),this.bar=t,this.move=t.querySelector('[data-nav="move"]'),this.select=t.querySelector('[data-nav="select"]'),this.search=t.querySelector("input"),this.count=t.querySelector(".slm-navigation-count"),this.clear=t.querySelector('[data-nav="clear"]'),this.results=t.querySelector(".slm-navigation-results"),this.location=document.createElement("div"),this.location.className="slm-location",this.location.hidden=!0,this.location.setAttribute("role","status"),e.map.after(this.location);let c={signal:this.abort.signal},d=t.querySelector('[data-nav="search"]'),h=t.querySelector(".slm-navigation-search"),b=()=>{h.hidden=!0,this.results.hidden=!0,d.setAttribute("aria-expanded","false"),d.focus()};d.addEventListener("click",()=>{let y=h.hidden;h.hidden=!y,d.setAttribute("aria-expanded",String(y)),y&&this.search.focus()},c);let m=t.querySelector('[data-nav="zoom"]');m.addEventListener("click",()=>{let y=m.getAttribute("aria-expanded")!=="true";m.setAttribute("aria-expanded",String(y));for(let f of["in","out"])t.querySelector(`[data-nav="${f}"]`).hidden=!y},c),this.search.addEventListener("keydown",y=>{y.key==="Escape"&&b()},c),this.move.addEventListener("click",()=>this.setMoving(!0),c),this.select.addEventListener("click",()=>this.setMoving(!1),c),this.clear.addEventListener("click",()=>this.host.clearSelection(),c),t.querySelector('[data-nav="in"]').addEventListener("click",()=>{this.location.hidden=!0,e.pauseFollow(),e.zoomIn()},c),t.querySelector('[data-nav="out"]').addEventListener("click",()=>{this.location.hidden=!0,e.pauseFollow(),e.zoomOut()},c);let p=t.querySelector('[data-nav="rail"]');p.addEventListener("click",()=>{let y=e.root.classList.toggle("details-hidden");p.setAttribute("aria-expanded",String(!y)),p.setAttribute("aria-label",y?"Show details":"Hide details"),p.title=y?"Show details":"Hide details"},c),this.search.addEventListener("input",()=>this.find(),c),this.search.addEventListener("keydown",y=>{y.key==="Escape"&&(this.results.hidden=!0),y.key==="ArrowDown"&&(y.preventDefault(),this.results.querySelector("button")?.focus())},c),e.map.addEventListener("pointerdown",()=>{this.location.hidden=!0,e.pauseFollow(),e.root.focus({preventScroll:!0}),this.results.hidden=!0},{...c,capture:!0}),e.root.querySelector(".slm-rail")?.addEventListener("pointerdown",()=>e.pauseFollow(),{...c,capture:!0}),e.map.addEventListener("wheel",()=>{this.location.hidden=!0,e.pauseFollow()},{...c,passive:!0,capture:!0}),e.root.addEventListener("keydown",y=>{y.target?.closest('input,textarea,select,button,[contenteditable="true"]')||y.code!=="Space"||y.ctrlKey||y.metaKey||y.altKey||(y.preventDefault(),this.space||(this.space=!0,e.pauseFollow(),e.setMoving(!0)))},c);let v=()=>{this.space&&(this.space=!1,e.setMoving(this.moving))};window.addEventListener("keyup",y=>{y.code==="Space"&&v()},c),window.addEventListener("blur",v,c),window.addEventListener("resize",()=>{this.location.hidden=!0},c),e.root.querySelector('[data-ref="zfit"]')?.addEventListener("click",()=>{this.location.hidden=!0},c),e.root.addEventListener("focusout",y=>{e.root.contains(y.relatedTarget)||v()},c)}setMoving(e){this.moving=e,this.host.pauseFollow(),this.host.setMoving(e||this.space),this.move.setAttribute("aria-pressed",String(e)),this.select.setAttribute("aria-pressed",String(!e))}update(e,t=!1){this.monitor=t,this.count.hidden=t,this.paintClear(),this.move.hidden=!e,this.select.hidden=!e}selectionChanged(e){this.selected=e,this.count.textContent=`${e.toLocaleString()} selected`,this.paintClear()}paintClear(){this.clear.hidden=this.monitor||this.selected<1}find(){let e=this.search.value.trim();if(this.results.replaceChildren(),this.results.hidden=!e,!e)return;let t=this.host.targets(e);for(let s of t){let n=document.createElement("button");n.type="button",n.textContent=`${s.label} \xB7 ${s.detail}`,n.addEventListener("click",()=>{this.host.pauseFollow(),s.locate(),this.location.textContent=`${s.label} \xB7 ${s.detail}`,this.location.hidden=!1,this.results.hidden=!0,this.host.root.focus({preventScroll:!0})}),this.results.append(n)}t.length||(this.results.textContent="No matching section, row or seat.")}destroy(){this.abort.abort(),this.bar.remove(),this.location.remove()}};var k=require("@seatlayer/core");ue();var Is=/^[a-zA-Z0-9._-]+$/;function Hs(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||!Is.test(n)?null:{eventKey:s,asset:n}}catch{return null}}function Ps(o){try{return/^\/v1\/events\/[^/]+\/assets(?:\/|$)/.test(new URL(o,"https://seatlayer.invalid").pathname)}catch{return!1}}var be=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=Hs(e);if(!t)return Promise.resolve(Ps(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()}}};ce();function pt(o,e,t,s={}){let n=s.previous?null:document.activeElement??null;s.previous?.scrim.remove();let i=document.createElement("div");i.className="slm-ch-scrim",i.innerHTML=`<div class="slm-ch-dialog" role="dialog" aria-modal="true"
|
|
761
|
+
aria-labelledby="slm-ch-dlg-title" tabindex="-1">${e}</div>`,o.appendChild(i);let a=i.firstElementChild,l=!1,r={scrim:i,dialog:a,close:({restoreFocus:d=!0}={})=>{l||(l=!0,i.remove(),d&&n?.focus?.(),s.onClose?.())}};return a.querySelectorAll("[data-ch-close]").forEach(d=>{d.addEventListener("click",()=>r.close())}),i.addEventListener("keydown",d=>{if(d.key==="Escape"){d.stopPropagation(),r.close();return}if(d.key!=="Tab")return;let h=[...a.querySelectorAll('summary,button:not([disabled]),select:not([hidden]),input,textarea,a[href],[tabindex]:not([tabindex="-1"])')];if(!h.length)return;let b=h[0],m=h[h.length-1];d.shiftKey&&document.activeElement===b?(d.preventDefault(),m.focus()):!d.shiftKey&&document.activeElement===m&&(d.preventDefault(),b.focus())}),t(a),Y(a),(a.querySelector("input,summary,button")??a).focus(),r}var ut=`
|
|
762
762
|
.slm{--slm-ch-scrim:rgba(0,0,0,.58)}
|
|
763
763
|
.slm[data-theme=light]{--slm-ch-scrim:rgba(23,32,51,.42)}
|
|
764
764
|
.slm-ch-scrim{position:absolute;inset:0;z-index:12;background:var(--slm-ch-scrim);display:grid;place-items:center;
|
|
@@ -1415,7 +1415,7 @@
|
|
|
1415
1415
|
transition:none!important;
|
|
1416
1416
|
scroll-behavior:auto!important}
|
|
1417
1417
|
}
|
|
1418
|
-
`;function ft(){if(typeof document>"u"||document.getElementById(bt))return;let o=document.createElement("style");o.id=bt,o.textContent=Bs,document.head.appendChild(o)}function vt(o){if(typeof document>"u"||document.getElementById(gt))return;let e=document.createElement("style");e.id=gt,e.textContent=o,document.head.appendChild(e)}Ge();var Pt=require("@seatlayer/core"),X=require("@seatlayer/core/picker/minimapGeometry");var Ht=require("@seatlayer/core"),qs=require("@seatlayer/core/core/cdnAsset");var _s=require("@seatlayer/core/core/cdnAsset");function F(o,e){let t=(0,Ht.t)(o);return t===o?e:t}function Ns(o){let e={inactive:0,available:1,selected:2},t=new Map;for(let n of o){let i=t.get(n.id);(!i||e[n.state]>e[i])&&t.set(n.id,n.state)}let s={selected:0,available:0,inactive:0};for(let n of t.values())s[n]+=1;return s}function js(o,e){return o.x<=e.x&&o.y<=e.y&&o.x+o.width>=e.x+e.width&&o.y+o.height>=e.y+e.height}function Bt(o,e){let t=new Xe(o);return t.build(e),t}var Xe=class{constructor(e){this.host=e;this.miniCanvas=null;this.miniBase=null;this.miniWrap=null;this.miniToggle=null;this.miniLabel=null;this.miniTf=null;this.miniDrag=null;this.miniSuppressClick=!1;this.userClosed=!1}dispose(){this.miniToggle?.remove(),this.miniWrap?.remove(),this.miniToggle=null,this.miniWrap=null,this.miniCanvas=null,this.miniBase=null,this.miniLabel=null,this.miniTf=null,this.miniDrag=null,this.host.root()?.removeAttribute("data-minimap-open")}build(e){if(!this.host.controller.getViewport())return;let s=document.createElement("button");s.type="button",s.className="sl-minimap-toggle",s.setAttribute("aria-label",F("picker.openVenueMap","Open venue overview map")),s.setAttribute("aria-expanded","false"),s.innerHTML='<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 6l5-2 8 3 5-2v13l-5 2-8-3-5 2zM8 4v13M16 7v13"/></svg>',e.appendChild(s),this.miniToggle=s;let n=document.createElement("div");n.className="sl-minimap",n.setAttribute("role","group");let i=document.createElement("div");i.className="sl-minimap-bar";let a=document.createElement("span");a.className="sl-minimap-label";let l=document.createElement("span");l.className="sl-minimap-key",l.setAttribute("aria-label",F("picker.minimapStateKey","Focused, selected, available, and inactive sections")),l.innerHTML='<i class="focused" title="Focused"></i><i class="selected" title="Selected"></i><i title="Available"></i><i class="inactive" title="Inactive"></i>';let r=document.createElement("button");r.type="button",r.className="sl-minimap-close",r.setAttribute("aria-label",F("picker.closeVenueMap","Close venue overview map")),r.textContent="\xD7",i.append(a,l,r);let c=document.createElement("canvas");c.tabIndex=0,c.setAttribute("role","application"),c.setAttribute("aria-label",F("picker.venueMapInstructions","Venue overview map. Drag the viewport, click a section, or use arrow keys to pan.")),n.append(i,c),e.appendChild(n),this.miniWrap=n,this.miniLabel=a,this.miniCanvas=c;let d=document.createElement("canvas");this.miniBase=d,s.addEventListener("click",()=>{let h=this.host.root()?.dataset.minimapOpen==="true";this.userClosed=h,this.setMinimapOpen(!h)}),r.addEventListener("click",()=>{this.userClosed=!0,this.setMinimapOpen(!1)}),c.addEventListener("click",h=>{if(this.miniSuppressClick){this.miniSuppressClick=!1;return}this.minimapJump(h)}),c.addEventListener("pointerdown",h=>this.minimapPointerDown(h)),c.addEventListener("pointermove",h=>this.minimapPointerMove(h)),c.addEventListener("pointerup",h=>this.minimapPointerUp(h)),c.addEventListener("pointercancel",h=>this.minimapPointerUp(h)),c.addEventListener("keydown",h=>this.minimapKeydown(h)),this.layoutMinimap(),this.syncMinimapLabel(),this.drawMinimapStatic(),this.drawMinimapRect()}setAutoOpen(e){if(this.miniWrap){if(!e){this.userClosed=!1,this.host.root()?.dataset.minimapOpen==="true"&&this.setMinimapOpen(!1,!1);return}this.userClosed||this.host.root()?.dataset.minimapOpen==="true"||this.setMinimapOpen(!0,!1)}}setMinimapOpen(e,t=!0){this.host.root()?.setAttribute("data-minimap-open",String(e)),this.miniToggle?.setAttribute("aria-expanded",String(e)),t&&(e?this.miniCanvas?.focus():this.miniToggle?.focus())}layoutMinimap(){let e=this.miniCanvas,t=this.miniBase,s=this.host.controller.getViewport()?.bounds;if(!e||!t||!s||!(s.width>0&&s.height>0))return;let n=196,i=146,a=6,l=s.width/Math.max(1,s.height),r=n,c=Math.round(n/l);c>i&&(c=i,r=Math.round(i*l)),r=Math.max(64,r),c=Math.max(48,c);let d=Math.min(2,window.devicePixelRatio||1);e.width=Math.round(r*d),e.height=Math.round(c*d),e.style.width=`${r}px`,e.style.height=`${c}px`,t.width=e.width,t.height=e.height,this.miniTf=(0,X.createMinimapTransform)(s,e.width,e.height,d,a)}syncMinimapLabel(){if(!this.miniLabel||!this.miniWrap)return;let e=this.host.controller.getFloors(),t=this.host.controller.isFloorOverview()?F("picker.allFloors","All floors"):e.find(d=>d.id===this.host.controller.getActiveFloorId())?.name??F("picker.venueOverview","Venue overview"),s=this.host.controller.getMinimapSnapshot().sections,i=s.find(d=>d.active)?.label??this.host.focusedSectionLabel(),a=i?`${t} \xB7 ${i}`:t;this.miniLabel.textContent=a;let{selected:l,available:r,inactive:c}=Ns(s);this.miniWrap.setAttribute("aria-label",s.length?`${a}. ${l} selected, ${r} available, ${c} inactive sections.`:a),this.miniCanvas?.setAttribute("aria-label",s.length?`${a}. ${l} selected, ${r} available, ${c} inactive sections. ${F("picker.venueMapInstructions","The outlined region is the visible map area. Drag it, click a section, or use arrow keys to pan.")}`:`${a}. ${F("picker.venueMapInstructions","The outlined region is the visible map area. Drag it, click elsewhere, or use arrow keys to pan.")}`)}refreshMinimap(){this.miniBase&&(this.layoutMinimap(),this.syncMinimapLabel(),this.drawMinimapStatic(),this.drawMinimapRect())}drawMinimapStatic(){let e=this.miniBase,t=this.miniTf;if(!e||!t)return;let s=e.getContext("2d");if(!s)return;s.clearRect(0,0,e.width,e.height);let n=h=>h*t.scale+t.offX,i=h=>h*t.scale+t.offY,a=this.host.cssVar("--sl-line")||"rgba(139,147,167,.5)",l=this.host.cssVar("--sl-muted")||"#8b93a7",r=this.host.cssVar("--sl-accent")||"#6e7bff",c=this.host.cssVar("--sl-success")||"#22a06b",d=this.host.controller.getMinimapSnapshot();for(let h of d.sections){if(h.outline.length<3)continue;s.beginPath(),h.outline.forEach((m,p)=>p===0?s.moveTo(n(m.x),i(m.y)):s.lineTo(n(m.x),i(m.y))),s.closePath();let f=h.paint;if(s.globalAlpha=h.state==="inactive"?.5:.92,f?s.fillStyle=f.fill:(s.globalAlpha=h.state==="inactive"?.18:h.state==="selected"?.72:.34,s.fillStyle=h.state==="inactive"?l:h.state==="selected"?r:c),s.fill(),s.globalAlpha=.82,s.lineWidth=Math.max(1,t.dpr),s.strokeStyle=f?.stroke||a,s.stroke(),h.owned){s.globalAlpha=1,s.lineWidth=Math.max(2,t.dpr*1.5),s.strokeStyle=r,s.stroke();let m=h.outline.reduce((p,v)=>({x:p.x+v.x,y:p.y+v.y}),{x:0,y:0});s.beginPath(),s.arc(n(m.x/h.outline.length),i(m.y/h.outline.length),Math.max(1.5,t.dpr*1.6),0,Math.PI*2),s.fillStyle=r,s.fill(),s.beginPath(),h.outline.forEach((p,v)=>v===0?s.moveTo(n(p.x),i(p.y)):s.lineTo(n(p.x),i(p.y))),s.closePath()}h.active&&(s.globalAlpha=1,s.lineJoin="round",s.lineWidth=Math.max(4,t.dpr*3.5),s.strokeStyle=this.host.cssVar("--sl-surface")||"#fff",s.stroke(),s.lineWidth=Math.max(2,t.dpr*1.75),s.strokeStyle=r,s.stroke())}if(s.globalAlpha=1,!d.sections.length){let h=Math.max(1,t.dpr),f=new Map,m=p=>{let v=f.get(p);if(v)return v;let y=this.host.tint?.(p)||c;return f.set(p,y),y};for(let p of d.seats)s.globalAlpha=p.state==="inactive"?.22:.78,s.fillStyle=p.state==="inactive"?l:p.state==="selected"?r:m(p.categoryKey),s.beginPath(),s.arc(n(p.x),i(p.y),h,0,Math.PI*2),s.fill();s.globalAlpha=1}}drawMinimapRect(){let e=this.miniCanvas,t=this.miniBase,s=this.miniTf;if(!e||!t||!s)return;let n=e.getContext("2d");if(!n)return;n.clearRect(0,0,e.width,e.height),n.drawImage(t,0,0);let i=this.host.controller.getViewport();if(!i||js(i.visible,i.bounds))return;let a=(0,X.minimapViewportPlan)(i.visible,s,e.width,e.height,Math.max(2,s.dpr*2)),l=this.host.cssVar("--sl-text")||"#12151c",r=this.host.cssVar("--sl-surface")||"#fff";n.save(),n.globalAlpha=.1,n.fillStyle=l,n.fillRect(a.raw.x,a.raw.y,a.raw.width,a.raw.height),n.globalAlpha=.9,n.lineJoin="round",n.lineWidth=Math.max(4,s.dpr*3.25),n.strokeStyle=r,n.strokeRect(a.raw.x,a.raw.y,a.raw.width,a.raw.height),n.globalAlpha=1,n.lineWidth=Math.max(2,s.dpr*1.75),n.strokeStyle=l,n.strokeRect(a.raw.x,a.raw.y,a.raw.width,a.raw.height),a.clipped&&Object.values(a.clippedEdges).some(Boolean)&&(n.setLineDash([Math.max(3,s.dpr*3),Math.max(2,s.dpr*2)]),n.strokeRect(a.clipped.x,a.clipped.y,a.clipped.width,a.clipped.height)),n.restore()}minimapWorldPoint(e){let t=this.miniCanvas,s=this.miniTf;if(!t||!s)return null;let n=t.getBoundingClientRect(),i=(e.clientX-n.left)*(t.width/Math.max(1,n.width)),a=(e.clientY-n.top)*(t.height/Math.max(1,n.height));return{...(0,X.minimapPointToWorld)({x:i,y:a},s),px:i,py:a}}minimapPointerDown(e){let t=this.minimapWorldPoint(e),s=this.host.controller.getViewport()?.visible;!t||!s||!(t.x>=s.x&&t.x<=s.x+s.width&&t.y>=s.y&&t.y<=s.y+s.height)||(this.miniDrag={pointerId:e.pointerId,offsetX:t.x-(s.x+s.width/2),offsetY:t.y-(s.y+s.height/2),startX:e.clientX,startY:e.clientY,moved:!1},this.miniCanvas?.setPointerCapture(e.pointerId),this.miniCanvas?.classList.add("sl-dragging"),e.preventDefault())}minimapPointerMove(e){let t=this.miniDrag;if(!t||t.pointerId!==e.pointerId)return;let s=this.minimapWorldPoint(e);s&&(!t.moved&&Math.hypot(e.clientX-t.startX,e.clientY-t.startY)>2&&(t.moved=!0,this.host.controller.clearSectionFocus()),this.host.controller.panToWorld({x:s.x-t.offsetX,y:s.y-t.offsetY}),e.preventDefault())}minimapPointerUp(e){let t=this.miniDrag;!t||t.pointerId!==e.pointerId||(this.miniSuppressClick=t.moved,this.miniDrag=null,this.miniCanvas?.classList.remove("sl-dragging"),this.miniCanvas?.hasPointerCapture(e.pointerId)&&this.miniCanvas.releasePointerCapture(e.pointerId))}minimapKeydown(e){let t=this.host.controller.getViewport()?.visible;if(!t)return;if(e.key==="Home"){this.host.controller.overview(),e.preventDefault();return}let s=e.key==="ArrowLeft"?-t.width*.2:e.key==="ArrowRight"?t.width*.2:0,n=e.key==="ArrowUp"?-t.height*.2:e.key==="ArrowDown"?t.height*.2:0;!s&&!n||(this.host.controller.clearSectionFocus(),this.host.controller.panToWorld({x:t.x+t.width/2+s,y:t.y+t.height/2+n}),e.preventDefault())}minimapJump(e){let t=this.minimapWorldPoint(e);if(t){for(let s of this.host.controller.getMinimapSnapshot().sections)if(!(s.state==="inactive"||s.outline.length<3)&&(0,Pt.pointInPolygon)(t,s.outline)){this.host.controller.focusSection(s.id);return}this.host.controller.clearSectionFocus(),this.host.controller.panToWorld(t)}}};function Dt(o){return o.focusedSection!==null?o.deeperThanSectionFrame===!1?"venue":"section":o.atVenueFit!==void 0?o.atVenueFit?"none":"venue":o.seatsRevealed?"venue":"none"}function Ot(o){return o.total==null||o.free==null?o.label:o.free<=0?`${o.label} \xB7 sold out`:`${o.label} \xB7 ${o.free.toLocaleString()} of ${o.total.toLocaleString()} free`}function zt(o){let t=Dt({focusedSection:o.focused?o.focused.label:null,seatsRevealed:o.seatsRevealed,atVenueFit:o.atVenueFit})==="none";return{crumb:o.focused?o.floor?`${o.floor} \xB7 ${Ot(o.focused)}`:Ot(o.focused):o.floor??"Venue",crumbShown:!!o.focused||!!o.floor,zoomInEnabled:!o.atCeiling,zoomOutEnabled:!t,venueEnabled:!t}}function Ft(o={}){return`
|
|
1418
|
+
`;function ft(){if(typeof document>"u"||document.getElementById(bt))return;let o=document.createElement("style");o.id=bt,o.textContent=Bs,document.head.appendChild(o)}function vt(o){if(typeof document>"u"||document.getElementById(gt))return;let e=document.createElement("style");e.id=gt,e.textContent=o,document.head.appendChild(e)}Ge();var Pt=require("@seatlayer/core"),X=require("@seatlayer/core/picker/minimapGeometry");var Ht=require("@seatlayer/core"),qs=require("@seatlayer/core/core/cdnAsset");var _s=require("@seatlayer/core/core/cdnAsset");function F(o,e){let t=(0,Ht.t)(o);return t===o?e:t}function Ns(o){let e={inactive:0,available:1,selected:2},t=new Map;for(let n of o){let i=t.get(n.id);(!i||e[n.state]>e[i])&&t.set(n.id,n.state)}let s={selected:0,available:0,inactive:0};for(let n of t.values())s[n]+=1;return s}function js(o,e){return o.x<=e.x&&o.y<=e.y&&o.x+o.width>=e.x+e.width&&o.y+o.height>=e.y+e.height}function Bt(o,e){let t=new Xe(o);return t.build(e),t}var Xe=class{constructor(e){this.host=e;this.miniCanvas=null;this.miniBase=null;this.miniWrap=null;this.miniToggle=null;this.miniLabel=null;this.miniTf=null;this.miniDrag=null;this.miniSuppressClick=!1;this.userClosed=!1}dispose(){this.miniToggle?.remove(),this.miniWrap?.remove(),this.miniToggle=null,this.miniWrap=null,this.miniCanvas=null,this.miniBase=null,this.miniLabel=null,this.miniTf=null,this.miniDrag=null,this.host.root()?.removeAttribute("data-minimap-open")}build(e){if(!this.host.controller.getViewport())return;let s=document.createElement("button");s.type="button",s.className="sl-minimap-toggle",s.setAttribute("aria-label",F("picker.openVenueMap","Open venue overview map")),s.setAttribute("aria-expanded","false"),s.innerHTML='<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 6l5-2 8 3 5-2v13l-5 2-8-3-5 2zM8 4v13M16 7v13"/></svg>',e.appendChild(s),this.miniToggle=s;let n=document.createElement("div");n.className="sl-minimap",n.setAttribute("role","group");let i=document.createElement("div");i.className="sl-minimap-bar";let a=document.createElement("span");a.className="sl-minimap-label";let l=document.createElement("span");l.className="sl-minimap-key",l.setAttribute("aria-label",F("picker.minimapStateKey","Focused, selected, available, and inactive sections")),l.innerHTML='<i class="focused" title="Focused"></i><i class="selected" title="Selected"></i><i title="Available"></i><i class="inactive" title="Inactive"></i>';let r=document.createElement("button");r.type="button",r.className="sl-minimap-close",r.setAttribute("aria-label",F("picker.closeVenueMap","Close venue overview map")),r.textContent="\xD7",i.append(a,l,r);let c=document.createElement("canvas");c.tabIndex=0,c.setAttribute("role","application"),c.setAttribute("aria-label",F("picker.venueMapInstructions","Venue overview map. Drag the viewport, click a section, or use arrow keys to pan.")),n.append(i,c),e.appendChild(n),this.miniWrap=n,this.miniLabel=a,this.miniCanvas=c;let d=document.createElement("canvas");this.miniBase=d,s.addEventListener("click",()=>{let h=this.host.root()?.dataset.minimapOpen==="true";this.userClosed=h,this.setMinimapOpen(!h)}),r.addEventListener("click",()=>{this.userClosed=!0,this.setMinimapOpen(!1)}),c.addEventListener("click",h=>{if(this.miniSuppressClick){this.miniSuppressClick=!1;return}this.minimapJump(h)}),c.addEventListener("pointerdown",h=>this.minimapPointerDown(h)),c.addEventListener("pointermove",h=>this.minimapPointerMove(h)),c.addEventListener("pointerup",h=>this.minimapPointerUp(h)),c.addEventListener("pointercancel",h=>this.minimapPointerUp(h)),c.addEventListener("keydown",h=>this.minimapKeydown(h)),this.layoutMinimap(),this.syncMinimapLabel(),this.drawMinimapStatic(),this.drawMinimapRect()}setAutoOpen(e){if(this.miniWrap){if(!e){this.userClosed=!1,this.host.root()?.dataset.minimapOpen==="true"&&this.setMinimapOpen(!1,!1);return}this.userClosed||this.host.root()?.dataset.minimapOpen==="true"||this.setMinimapOpen(!0,!1)}}setMinimapOpen(e,t=!0){this.host.root()?.setAttribute("data-minimap-open",String(e)),this.miniToggle?.setAttribute("aria-expanded",String(e)),t&&(e?this.miniCanvas?.focus():this.miniToggle?.focus())}layoutMinimap(){let e=this.miniCanvas,t=this.miniBase,s=this.host.controller.getViewport()?.bounds;if(!e||!t||!s||!(s.width>0&&s.height>0))return;let n=196,i=146,a=6,l=s.width/Math.max(1,s.height),r=n,c=Math.round(n/l);c>i&&(c=i,r=Math.round(i*l)),r=Math.max(64,r),c=Math.max(48,c);let d=Math.min(2,window.devicePixelRatio||1);e.width=Math.round(r*d),e.height=Math.round(c*d),e.style.width=`${r}px`,e.style.height=`${c}px`,t.width=e.width,t.height=e.height,this.miniTf=(0,X.createMinimapTransform)(s,e.width,e.height,d,a)}syncMinimapLabel(){if(!this.miniLabel||!this.miniWrap)return;let e=this.host.controller.getFloors(),t=this.host.controller.isFloorOverview()?F("picker.allFloors","All floors"):e.find(d=>d.id===this.host.controller.getActiveFloorId())?.name??F("picker.venueOverview","Venue overview"),s=this.host.controller.getMinimapSnapshot().sections,i=s.find(d=>d.active)?.label??this.host.focusedSectionLabel(),a=i?`${t} \xB7 ${i}`:t;this.miniLabel.textContent=a;let{selected:l,available:r,inactive:c}=Ns(s);this.miniWrap.setAttribute("aria-label",s.length?`${a}. ${l} selected, ${r} available, ${c} inactive sections.`:a),this.miniCanvas?.setAttribute("aria-label",s.length?`${a}. ${l} selected, ${r} available, ${c} inactive sections. ${F("picker.venueMapInstructions","The outlined region is the visible map area. Drag it, click a section, or use arrow keys to pan.")}`:`${a}. ${F("picker.venueMapInstructions","The outlined region is the visible map area. Drag it, click elsewhere, or use arrow keys to pan.")}`)}refreshMinimap(){this.miniBase&&(this.layoutMinimap(),this.syncMinimapLabel(),this.drawMinimapStatic(),this.drawMinimapRect())}drawMinimapStatic(){let e=this.miniBase,t=this.miniTf;if(!e||!t)return;let s=e.getContext("2d");if(!s)return;s.clearRect(0,0,e.width,e.height);let n=h=>h*t.scale+t.offX,i=h=>h*t.scale+t.offY,a=this.host.cssVar("--sl-line")||"rgba(139,147,167,.5)",l=this.host.cssVar("--sl-muted")||"#8b93a7",r=this.host.cssVar("--sl-accent")||"#6e7bff",c=this.host.cssVar("--sl-success")||"#22a06b",d=this.host.controller.getMinimapSnapshot();for(let h of d.sections){if(h.outline.length<3)continue;s.beginPath(),h.outline.forEach((m,p)=>p===0?s.moveTo(n(m.x),i(m.y)):s.lineTo(n(m.x),i(m.y))),s.closePath();let b=h.paint;if(s.globalAlpha=h.state==="inactive"?.5:.92,b?s.fillStyle=b.fill:(s.globalAlpha=h.state==="inactive"?.18:h.state==="selected"?.72:.34,s.fillStyle=h.state==="inactive"?l:h.state==="selected"?r:c),s.fill(),s.globalAlpha=.82,s.lineWidth=Math.max(1,t.dpr),s.strokeStyle=b?.stroke||a,s.stroke(),h.owned){s.globalAlpha=1,s.lineWidth=Math.max(2,t.dpr*1.5),s.strokeStyle=r,s.stroke();let m=h.outline.reduce((p,v)=>({x:p.x+v.x,y:p.y+v.y}),{x:0,y:0});s.beginPath(),s.arc(n(m.x/h.outline.length),i(m.y/h.outline.length),Math.max(1.5,t.dpr*1.6),0,Math.PI*2),s.fillStyle=r,s.fill(),s.beginPath(),h.outline.forEach((p,v)=>v===0?s.moveTo(n(p.x),i(p.y)):s.lineTo(n(p.x),i(p.y))),s.closePath()}h.active&&(s.globalAlpha=1,s.lineJoin="round",s.lineWidth=Math.max(4,t.dpr*3.5),s.strokeStyle=this.host.cssVar("--sl-surface")||"#fff",s.stroke(),s.lineWidth=Math.max(2,t.dpr*1.75),s.strokeStyle=r,s.stroke())}if(s.globalAlpha=1,!d.sections.length){let h=Math.max(1,t.dpr),b=new Map,m=p=>{let v=b.get(p);if(v)return v;let y=this.host.tint?.(p)||c;return b.set(p,y),y};for(let p of d.seats)s.globalAlpha=p.state==="inactive"?.22:.78,s.fillStyle=p.state==="inactive"?l:p.state==="selected"?r:m(p.categoryKey),s.beginPath(),s.arc(n(p.x),i(p.y),h,0,Math.PI*2),s.fill();s.globalAlpha=1}}drawMinimapRect(){let e=this.miniCanvas,t=this.miniBase,s=this.miniTf;if(!e||!t||!s)return;let n=e.getContext("2d");if(!n)return;n.clearRect(0,0,e.width,e.height),n.drawImage(t,0,0);let i=this.host.controller.getViewport();if(!i||js(i.visible,i.bounds))return;let a=(0,X.minimapViewportPlan)(i.visible,s,e.width,e.height,Math.max(2,s.dpr*2)),l=this.host.cssVar("--sl-text")||"#12151c",r=this.host.cssVar("--sl-surface")||"#fff";n.save(),n.globalAlpha=.1,n.fillStyle=l,n.fillRect(a.raw.x,a.raw.y,a.raw.width,a.raw.height),n.globalAlpha=.9,n.lineJoin="round",n.lineWidth=Math.max(4,s.dpr*3.25),n.strokeStyle=r,n.strokeRect(a.raw.x,a.raw.y,a.raw.width,a.raw.height),n.globalAlpha=1,n.lineWidth=Math.max(2,s.dpr*1.75),n.strokeStyle=l,n.strokeRect(a.raw.x,a.raw.y,a.raw.width,a.raw.height),a.clipped&&Object.values(a.clippedEdges).some(Boolean)&&(n.setLineDash([Math.max(3,s.dpr*3),Math.max(2,s.dpr*2)]),n.strokeRect(a.clipped.x,a.clipped.y,a.clipped.width,a.clipped.height)),n.restore()}minimapWorldPoint(e){let t=this.miniCanvas,s=this.miniTf;if(!t||!s)return null;let n=t.getBoundingClientRect(),i=(e.clientX-n.left)*(t.width/Math.max(1,n.width)),a=(e.clientY-n.top)*(t.height/Math.max(1,n.height));return{...(0,X.minimapPointToWorld)({x:i,y:a},s),px:i,py:a}}minimapPointerDown(e){let t=this.minimapWorldPoint(e),s=this.host.controller.getViewport()?.visible;!t||!s||!(t.x>=s.x&&t.x<=s.x+s.width&&t.y>=s.y&&t.y<=s.y+s.height)||(this.miniDrag={pointerId:e.pointerId,offsetX:t.x-(s.x+s.width/2),offsetY:t.y-(s.y+s.height/2),startX:e.clientX,startY:e.clientY,moved:!1},this.miniCanvas?.setPointerCapture(e.pointerId),this.miniCanvas?.classList.add("sl-dragging"),e.preventDefault())}minimapPointerMove(e){let t=this.miniDrag;if(!t||t.pointerId!==e.pointerId)return;let s=this.minimapWorldPoint(e);s&&(!t.moved&&Math.hypot(e.clientX-t.startX,e.clientY-t.startY)>2&&(t.moved=!0,this.host.controller.clearSectionFocus()),this.host.controller.panToWorld({x:s.x-t.offsetX,y:s.y-t.offsetY}),e.preventDefault())}minimapPointerUp(e){let t=this.miniDrag;!t||t.pointerId!==e.pointerId||(this.miniSuppressClick=t.moved,this.miniDrag=null,this.miniCanvas?.classList.remove("sl-dragging"),this.miniCanvas?.hasPointerCapture(e.pointerId)&&this.miniCanvas.releasePointerCapture(e.pointerId))}minimapKeydown(e){let t=this.host.controller.getViewport()?.visible;if(!t)return;if(e.key==="Home"){this.host.controller.overview(),e.preventDefault();return}let s=e.key==="ArrowLeft"?-t.width*.2:e.key==="ArrowRight"?t.width*.2:0,n=e.key==="ArrowUp"?-t.height*.2:e.key==="ArrowDown"?t.height*.2:0;!s&&!n||(this.host.controller.clearSectionFocus(),this.host.controller.panToWorld({x:t.x+t.width/2+s,y:t.y+t.height/2+n}),e.preventDefault())}minimapJump(e){let t=this.minimapWorldPoint(e);if(t){for(let s of this.host.controller.getMinimapSnapshot().sections)if(!(s.state==="inactive"||s.outline.length<3)&&(0,Pt.pointInPolygon)(t,s.outline)){this.host.controller.focusSection(s.id);return}this.host.controller.clearSectionFocus(),this.host.controller.panToWorld(t)}}};function Dt(o){return o.focusedSection!==null?o.deeperThanSectionFrame===!1?"venue":"section":o.atVenueFit!==void 0?o.atVenueFit?"none":"venue":o.seatsRevealed?"venue":"none"}function Ot(o){return o.total==null||o.free==null?o.label:o.free<=0?`${o.label} \xB7 sold out`:`${o.label} \xB7 ${o.free.toLocaleString()} of ${o.total.toLocaleString()} free`}function zt(o){let t=Dt({focusedSection:o.focused?o.focused.label:null,seatsRevealed:o.seatsRevealed,atVenueFit:o.atVenueFit})==="none";return{crumb:o.focused?o.floor?`${o.floor} \xB7 ${Ot(o.focused)}`:Ot(o.focused):o.floor??"Venue",crumbShown:!!o.focused||!!o.floor,zoomInEnabled:!o.atCeiling,zoomOutEnabled:!t,venueEnabled:!t}}function Ft(o={}){return`
|
|
1419
1419
|
<div class="slm-mapchrome" data-ref="mapchrome">
|
|
1420
1420
|
${o.legend??""}
|
|
1421
1421
|
<div class="slm-crumb" data-ref="crumb" role="status" hidden></div>
|
|
@@ -1442,38 +1442,38 @@
|
|
|
1442
1442
|
</button>`).join("")}
|
|
1443
1443
|
<div class="slm-view-note" data-ref="viewnote" hidden></div>
|
|
1444
1444
|
</div>
|
|
1445
|
-
</details>`}function Qt(o,e,t){let s=we(),n=!1;o.querySelectorAll("[data-view]").forEach(l=>{let r=l.dataset.view,c=e[r];l.setAttribute("aria-checked",String(c)),l.classList.toggle("on",c);let d=r==="channelColours"&&!t.channelColoursAvailable;l.disabled=d,l.setAttribute("aria-disabled",String(d)),!d&&c!==s[r]&&(n=!0)}),o.querySelector("summary")?.classList.toggle("away",n);let a=o.querySelector('[data-ref="viewnote"]');if(a){let l=[];t.channelColoursAvailable||l.push("Channel colours: open the Channels tool."),t.momentumLoading&&l.push("Booking momentum: loading the first snapshot\u2026"),a.hidden=!l.length,a.textContent=l.join(" ")}}ye();We();var Jt=require("@seatlayer/core");ye();function Ze(o){return Object.entries(o).filter(([,e])=>e.mode==="closed").map(([e])=>e)}function Se(o){let e=o.sectionsBase;if(!e)return{rows:[],hiddenSections:0,closedSections:0};let t=o.doc?.zones??[],s=new Map,n=[];for(let c of e.sections)if(c.zone&&t.some(d=>d.id===c.zone)){let d=s.get(c.zone)??[];d.push(c),s.set(c.zone,d)}else n.push(c);let i=[],a=0,l=0,r=(c,d,h,
|
|
1446
|
-
<summary aria-label="Availability for ${
|
|
1447
|
-
<div class="slm-availchoices" aria-label="Availability options for ${
|
|
1448
|
-
${i.map(([d,h,
|
|
1445
|
+
</details>`}function Qt(o,e,t){let s=we(),n=!1;o.querySelectorAll("[data-view]").forEach(l=>{let r=l.dataset.view,c=e[r];l.setAttribute("aria-checked",String(c)),l.classList.toggle("on",c);let d=r==="channelColours"&&!t.channelColoursAvailable;l.disabled=d,l.setAttribute("aria-disabled",String(d)),!d&&c!==s[r]&&(n=!0)}),o.querySelector("summary")?.classList.toggle("away",n);let a=o.querySelector('[data-ref="viewnote"]');if(a){let l=[];t.channelColoursAvailable||l.push("Channel colours: open the Channels tool."),t.momentumLoading&&l.push("Booking momentum: loading the first snapshot\u2026"),a.hidden=!l.length,a.textContent=l.join(" ")}}ye();We();var Jt=require("@seatlayer/core");ye();function Ze(o){return Object.entries(o).filter(([,e])=>e.mode==="closed").map(([e])=>e)}function Se(o){let e=o.sectionsBase;if(!e)return{rows:[],hiddenSections:0,closedSections:0};let t=o.doc?.zones??[],s=new Map,n=[];for(let c of e.sections)if(c.zone&&t.some(d=>d.id===c.zone)){let d=s.get(c.zone)??[];d.push(c),s.set(c.zone,d)}else n.push(c);let i=[],a=0,l=0,r=(c,d,h,b=!1)=>{let m=o.availabilityRules[d.id]??null,p=o.effectiveClosed.has(d.id)||b,v=o.effectiveHidden.has(d.id)||h&&!p;c==="section"&&v&&(a+=1),c==="section"&&p&&(l+=1),i.push({kind:c,id:d.id,label:d.label,seatCount:d.seatCount,seatLabels:d.seatLabels,rule:m,hidden:v,closed:p,followsZone:c==="section"&&h})};for(let c of t){let d=s.get(c.id);if(!d||!d.length)continue;let h={id:c.id,label:c.label||"Zone",seatCount:d.reduce((p,v)=>p+v.seatCount,0),seatLabels:d.flatMap(p=>p.seatLabels)},b=!!o.availabilityRules[c.id],m=o.availabilityRules[c.id]?.mode==="closed";r("zone",h,!1);for(let p of d)r("section",p,b,m)}for(let c of n)r("section",c,!1);if(e.ungrouped){let c=e.ungrouped;r("section",{id:Jt.UNGROUPED_ID,label:c.label,seatCount:c.seatCount,seatLabels:c.seatLabels},!1)}return{rows:i,hiddenSections:a,closedSections:l}}function es(o,e){let t=wt(o.rule),s=`slm-availrow${o.kind==="zone"?" zone":""}${o.hidden?" hidden":""}${o.closed?" closed":""}`,n=e?" disabled":"",i=[["open","Open","Available to buy"],["closed","Closed","Visible on the map, unavailable to buy"],["hidden","Hidden","Removed from the buyer map"],["timed","Scheduled reveal","Open at a specific date and time"],["threshold","Demand-based reveal","Open when sales reach a percentage"]],a=o.followsZone?'<span class="slm-availfollows">Follows zone</span>':`<details class="slm-availpicker" data-avail-picker>
|
|
1446
|
+
<summary aria-label="Availability for ${g(o.label)}" ${e?'aria-disabled="true"':""}>${i.find(d=>d[0]===t)[1]}<span aria-hidden="true">\u2304</span></summary>
|
|
1447
|
+
<div class="slm-availchoices" aria-label="Availability options for ${g(o.label)}">
|
|
1448
|
+
${i.map(([d,h,b])=>`<button type="button" data-avail-id="${g(o.id)}" data-avail-value="${d}" aria-pressed="${t===d}"${n}><span><b>${h}</b><small>${b}</small></span><span aria-hidden="true">${t===d?"\u2713":""}</span></button>`).join("")}
|
|
1449
1449
|
</div>
|
|
1450
|
-
</details>`,l="";if(!o.followsZone&&t==="timed"){let d=o.rule?.revealAt?
|
|
1451
|
-
<input type="datetime-local" class="slm-input" data-avail-reveal="${
|
|
1450
|
+
</details>`,l="";if(!o.followsZone&&t==="timed"){let d=o.rule?.revealAt?g(Lt(o.rule.revealAt)):"";l=`<div class="slm-availdetail">
|
|
1451
|
+
<input type="datetime-local" class="slm-input" data-avail-reveal="${g(o.id)}" value="${d}"${n} aria-label="Reveal time for ${g(o.label)}" />
|
|
1452
1452
|
</div>`}else if(!o.followsZone&&t==="threshold"){let d=o.rule?.thresholdPct??80;l=`<div class="slm-availdetail">
|
|
1453
1453
|
<span class="slm-availpctlabel">Reveal at</span>
|
|
1454
|
-
<input type="number" min="1" max="100" class="slm-input slm-availpct" data-avail-pct="${
|
|
1454
|
+
<input type="number" min="1" max="100" class="slm-input slm-availpct" data-avail-pct="${g(o.id)}" value="${g(d)}"${n} aria-label="Percent sold to reveal ${g(o.label)}" />
|
|
1455
1455
|
<span class="slm-availpctlabel">% sold</span>
|
|
1456
1456
|
</div>`}let r=o.closed?'<span class="slm-availbadge closed">Closed</span>':o.hidden?'<span class="slm-availbadge hidden">Hidden</span>':"",c=o.kind==="zone"?`<span class="slm-availcaret" aria-hidden="true">${o.hidden?"\u25B8":"\u25BE"}</span>`:"";return`<div class="${s}">
|
|
1457
1457
|
<div class="slm-availhead">
|
|
1458
|
-
<span class="slm-availlabel">${c}${
|
|
1458
|
+
<span class="slm-availlabel">${c}${g(o.label)}</span>
|
|
1459
1459
|
${r}
|
|
1460
1460
|
<span class="slm-availcount">${o.seatCount.toLocaleString()}</span>
|
|
1461
1461
|
</div>
|
|
1462
1462
|
${a}
|
|
1463
1463
|
${l}
|
|
1464
|
-
</div>`}var pn="https://api.seatlayer.io",Ve=200,bs=16,gs=4,vs=[{key:"watch",label:"Watch",tools:[{mode:"view",label:"Monitor",shortcut:"M",title:"Live board \u2014 inventory, activity and booking momentum. Read-only."},{mode:"inspect",label:"Inspect",shortcut:"I",title:"Click one seat to read its live status and booking context. Read-only."}]},{key:"manage",label:"Manage",tools:[{mode:"block",label:"Block",shortcut:"B",title:"Take seats off sale for this event, or put them back."},{mode:"sections",label:"Sections",shortcut:"S",title:"Open, close or hide sections for this event, on a schedule or on demand."},{mode:"categories",label:"Categories",shortcut:"G",title:"Move seats to a different price category for this event only."},{mode:"tables",label:"Tables",shortcut:"T",title:"Sell each table per chair or as one whole-table booking."},{mode:"channels",label:"Channels",shortcut:"C",title:"Allocate inventory to sales channels and share their links."}]},{key:"host",label:"Host tools",tools:[{mode:"select",label:"Select",shortcut:"X",title:"Select seats for your own back-office operation. The selection is handed to your app; nothing changes here."},{mode:"filterSections",label:"Filter",shortcut:"L",title:"Filter the map to one section for your own reporting."}]}],un=3;function bn(o){let e=o?.status;return e===401||e===403}var fs=o=>`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${o}</svg>`,nt={enter:fs('<path d="M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5"/>'),exit:fs('<path d="M9 4v5H4M20 9h-5V4M15 20v-5h5M4 15h5v5"/>')},gn=Object.fromEntries(vs.flatMap(o=>o.tools.map(e=>[e.shortcut.toLowerCase(),e.mode]))),qe=class{constructor(e){this.els={};this.renderer=null;this.doc=null;this.selectObserver=null;this.seatHistoryPanel=null;this.activityPanel=null;this.navigation=null;this.movingMap=!1;this.marqueeShape="box";this.socketSnapshotSeen=!1;this.monitorRefreshTimer=null;this.themeMode=null;this.colorSchemeStop=null;this.inventoryModelVersion=1;this.selectableObjectLabels=new Set;this.lastSelectionLabels=new Set;this.selectionWasValid=null;this.initialSelectionApplied=!1;this.labelToId=new Map;this.labelToSeat=new Map;this.allIds=[];this.gaUnitLabelSet=new Set;this.tableChairIds=new Map;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.mapView=we();this.barFind=null;this.minimap=null;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.chromeClearance=-1;this.chromeClearanceWidth=-1;this.tokenExpiresAt=null;this.tokenRefreshTimer=null;this.tokenRefreshInFlight=!1;this.tokenRefreshFailures=0;this.sessionEnded=!1;this.sectionByObject=new Map;this.sectionLabelById=new Map;this.sectionsBase=null;this.filteredSectionLabel=null;this.availabilityRules={};this.effectiveHidden=new Set;this.effectiveClosed=new Set;this.availabilitySaving=!1;this.lastSyncedAt=null;this.blockBrowse=!1;this.blockedQuery="";this.blockedSection="";this.blockedResultLimit=100;this.unblockAllConfirmTimer=null;this.channels=null;this.chooser=null;this.chooserDialog=null;this.categoryDifferences=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(),n=e.shiftKey?Kt(s):null;if(n){this.toggleMapView(n),e.preventDefault();return}if(s==="/"){let a=this.els.findbar?.querySelector("[data-ch-find-input]");a&&(a.focus(),a.select(),e.preventDefault());return}let i=gn[s];if(i){if(!this.toolAvailable(i))return;this.setMode(i)}else if(s==="f")this.toggleFullscreen();else if(s==="escape"){let a=this.els.view;if(a?.open)a.open=!1,a.querySelector("summary")?.focus();else if(!this.channels?.handleBack())if(this.getSelection().length)this.clearSelection();else return}else return;e.preventDefault()};this.onRailClick=e=>{let t=e.target,s=t?.closest("[data-section-focus]");if(s?.dataset.sectionFocus){this.locateSection(s.dataset.sectionFocus);return}let n=t?.closest("[data-feed-id]");n?.dataset.feedId&&this.locateActivity(n.dataset.feedId)};this.typeKeyBySection=null;this.typeKeyBase=null;this.sectionOptions=[];Ye(e.token),this.assertSelectionOptions(e.maxSelectedObjects,e.numberOfPlacesToSelect),this.opts=e,this.key=e.eventKey,this.mode=e.mode??"view",this.selectableObjectLabels=new Set(e.selectableObjects??[]),this.categoryCanManage=new Set(e.capabilities??[]).has("event:categories:manage"),this.tableCanManage=new Set(e.capabilities??[]).has("event:tables:manage"),this.keepLive=e.keepLiveWhileHidden??!0,this.themeMode=e.themeMode??null,this.followLive=e.followLive??!1,this.currency=e.currency??"USD",this.tokenExpiresAt=e.tokenExpiresAt??null,this.api=new G(e.apiBase??pn,e.token),this.organizerAssetUrls=new be(this.key,(t,s)=>this.withAuthRetry(()=>this.api.asset(t,s))),this.host=Ct(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(){ft(),this.buildChrome();try{let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1,this.doc=await this.organizerAssetUrls.prepareRendererChart(e.doc),this.authoritativeCurrency=e.event.currency??null,this.currency=this.authoritativeCurrency??this.opts.currency??this.currency,this.buildUnitUniverse(this.doc),this.buildRenderer(),this.buildSectionOptions(),this.settleMode();let[,t]=await Promise.all([this.resnapshot(),this.refreshControlRoom().catch(s=>this.opts.onError?.(s)),this.refreshAvailability()]);t?.activity?this.seedFeed(t.activity):this.api.log(this.key,{limit:24}).then(s=>this.seedFeed(s.entries)).catch(()=>{}),this.connect(),this.startFeedClock(),this.ready=!0,await this.resolveChannelCapabilities(),this.setMode(this.mode),this.applyInitialSelection(),this.scheduleTokenRefresh(),this.opts.onReady?.()}catch(e){this.fail(e)}return this}setMode(e){this.toolAvailable(e)||(e="view"),e==="channels"&&!this.channels&&this.ensureChannels();let t=e!==this.mode,s=this.mode==="channels",n=this.mode==="filterSections";this.mode=e,t&&e!=="view"&&this.setFollowLive(!1),!this.renderer&&this.doc?this.buildRenderer():this.updateRendererInteraction(),t&&(this.renderer?.clearSelection(),this.syncSelection()),s&&e!=="channels"&&this.channels?.leave(),t&&(this.highlightLabels(null),this.wireBarFind()),this.paintModeTabs(),this.paintRail(),this.paintMapViewMenu(),this.applyMapView(),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(()=>(st(),us));if(this.closed||!this.channelCaps.view||(this.channels||(vt(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(),this.applyMapView(),this.paintMapViewMenu()}catch(t){if(this.closed)return;this.channelsLoading=null,this.mode==="channels"&&this.paintRail(),this.opts.onError?.(t)}})();return this.channelsLoading=e,e}buildChooserHost(){let e=s=>{let n=this.labelToSeat.get(s);return n?this.mode==="block"?this.isBlockSelectable(s):this.mode==="select"?this.canSelectObject(n):!0:!1};return{selectionLabels:()=>this.selectionLabels(),selectByLabels:s=>{this.selectByLabels(s)},clearSelection:()=>this.clearSelection(),selectSection:s=>{this.selectSection(s)},sections:()=>this.sectionOptions,labelsInSection:s=>(this.renderer?.getSelectableInSection(s)??[]).map(n=>n.label).filter(e),rows:()=>{let s=new Map((this.doc?.objects??[]).map(i=>[i.id,i])),n=new Map;for(let i of this.labelToSeat.values()){if(!e(i.label))continue;let a=s.get(i.rowId);if(!a||a.type!=="row"&&a.type!=="table")continue;let l=i.logicalRowId??i.rowId,r=this.sectionByObject.get(i.rowId)??k.UNGROUPED_ID,c=n.get(l)??{id:l,label:a.type==="row"?a.segmentedRow?.displayLabel??a.displayLabel??a.label:a.displayLabel??a.label,sectionId:r,sectionLabel:this.sectionLabelById.get(r)??"Other seats",labels:[]};c.labels.push(i.label),n.set(l,c)}return[...n.values()].sort((i,a)=>i.sectionLabel.localeCompare(a.sectionLabel,void 0,{numeric:!0,sensitivity:"base"})||i.label.localeCompare(a.label,void 0,{numeric:!0,sensitivity:"base"}))},categories:()=>(this.doc?.categories??[]).map(s=>({key:s.key,label:s.label??s.key,color:s.color})),labelsInCategory:s=>[...this.labelToSeat.values()].filter(n=>n.categoryKey===s&&e(n.label)).map(n=>n.label),seats:()=>[...this.labelToSeat.values()].filter(s=>e(s.label)).map(s=>({label:s.label})),statusOf:s=>this.status.get(s)??(this.labelToSeat.has(s)?"free":void 0),sectionOfLabel:s=>{let n=this.labelToSeat.get(s);if(!n)return null;let i=this.sectionByObject.get(n.rowId)??k.UNGROUPED_ID;return{id:i,label:this.sectionLabelById.get(i)??"Other seats"}},openDialog:(s,n)=>{this.chooserDialog=pt(this.root,s,n,{previous:this.chooserDialog,onClose:()=>{this.chooserDialog=null}})},closeDialog:()=>this.chooserDialog?.close(),highlight:s=>this.highlightLabels(s),...this.mode==="select"?{cap:this.selectionCap()}:{}}}wireBarFind(){let e=this.els.findbar;e&&(e.innerHTML=ke({compact:!0}),this.barFind=new N({...this.buildChooserHost(),seats:()=>[...this.labelToSeat.values()].map(t=>({label:t.label})),frame:t=>this.frameLabels(t)}),this.barFind.wireFind(e,{enter:this.isChoosingTool()?"select":"frame"}))}isChoosingTool(){return this.isBulkSelectMode()||this.mode==="select"}frameLabels(e){let t=e.map(s=>this.labelToSeat.get(s)?.id).filter(s=>!!s);t.length&&(this.setFollowLive(!1),this.renderer?.focusSeats?.(t,{animate:!0}))}highlightLabels(e){if(!e){this.renderer?.setSeatHighlight?.(null);return}this.renderer?.setSeatHighlight?.(e.map(t=>this.labelToSeat.get(t)?.id).filter(t=>!!t))}toolChooser(){return this.chooserDialog?.close({restoreFocus:!1}),this.chooser=new N(this.buildChooserHost()),this.chooser}toolSelectionBar(e,t,s,n){return It({count:0,noun:"selected",breakdown:`<span class="slm-selactions"><button type="button" class="slm-linkbtn" data-ref="${n}">Select all</button></span>`,clearAttr:`data-ref="${s}"`}).replace('class="slm-selnum"',`class="slm-selnum" data-ref="${e}"`).replace('class="slm-sellabel"',`class="slm-sellabel" data-ref="${t}"`)}buildChannelsHost(){return{eventKey:this.key,api:this.api,rail:this.els.rail,mapLayer:this.root.querySelector(".slm-map"),pillLane:this.els.lane,root:this.root,seats:()=>[...this.labelToSeat.values()].map(e=>({id:e.id,label:e.label,x:e.x,y:e.y})),statusOf:e=>this.status.get(e)??(this.labelToSeat.has(e)?"free":void 0),selectionLabels:()=>this.selectionLabels(),selectByLabels:e=>{this.selectByLabels(e)},clearSelection:()=>this.clearSelection(),selectSection:e=>{this.selectSection(e)},sections:()=>this.sectionOptions,labelsInSection:e=>this.renderer?.getSelectableInSection(e).map(t=>t.label)??[],rows:()=>{let e=new Map((this.doc?.objects??[]).map(s=>[s.id,s])),t=new Map;for(let s of this.labelToSeat.values()){let 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)??k.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,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)??k.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.mapView.momentum!==e&&this.setMapView({momentum:e}),this.applyHeatOverlay(),this.paintHeatButton()}setMapView(e){let t={...this.mapView,...e};if(!Object.keys(t).some(i=>t[i]!==this.mapView[i]))return;let n=t.categoryColours!==this.mapView.categoryColours;this.mapView=t,Yt(t),t.momentum!==this.heatEnabled&&this.setHeatOverlay(t.momentum),this.applyMapView(),this.paintMapViewMenu(),n&&(this.refreshBlockPaint(),this.paintMapChrome())}getColourBy(){return this.mapView.categoryColours?"type":"full"}setColourBy(e){this.setMapView({categoryColours:e==="type"})}getMapView(){return{...this.mapView}}toggleMapView(e){e==="channelColours"&&!this.channelColoursAvailable()||this.setMapView({[e]:!this.mapView[e]})}channelColoursAvailable(){return this.mode==="channels"&&this.channels!=null}applyMapView(){Xt(this.mapView,{renderer:this.renderer,channelsOverlay:e=>this.channels?.setOverlayVisible(e)})}paintMapViewMenu(){let e=this.els.view;e&&Qt(e,this.mapView,{channelColoursAvailable:this.channelColoursAvailable(),momentumLoading:this.mapView.momentum&&!this.controlRoomSnapshot})}setFollowLive(e){let t=this.followLive!==e;this.followLive=e,e||(this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=null,this.followSeatTimer=null),this.paintFollowLiveButton(),t&&this.opts.onFollowLiveChange?.(e)}setKeepLiveWhileHidden(e){this.keepLive=e??!0,this.opts.keepLiveWhileHidden=e}setCurrency(e){this.opts.currency=e,!this.authoritativeCurrency&&(this.currency=e??"USD",this.ready&&this.recomputeTallies())}setTheme(e){this.opts.theme=e,this.applyThemeVars()}applyThemeVars(){if(!this.root)return;let e=Ke(this.themeMode);for(let[t,s]of Object.entries(Et(this.opts.theme,e)))this.root.style.setProperty(t,s);e?this.root.dataset.theme=e:delete this.root.dataset.theme}watchThemeMode(){this.colorSchemeStop?.(),this.colorSchemeStop=null,this.themeMode==="auto"&&(this.colorSchemeStop=xt(()=>{this.closed||this.repaintForThemeMode()}))}repaintForThemeMode(){this.applyThemeVars();let e=this.renderer;if(!e||!this.doc)return;let t=e.getSelection().map(i=>i.id),s=e.getCameraPose(),n=e.getFocusedSection();e.setChart(this.themedDoc()),this.repaintAll(),this.applyHeatOverlay(),t.length&&e.select(t),n&&e.focusSection(n),e.setCameraPose(s),this.updateZoomHint()}setThemeMode(e){let t=e??null;this.closed||t===this.themeMode||(this.themeMode=t,this.opts.themeMode=t??void 0,this.watchThemeMode(),this.repaintForThemeMode())}getThemeMode(){return this.themeMode}themedDoc(){let e=this.doc,t=Rt(Ke(this.themeMode));return t?{...e,theme:{...e.theme??{},background:t}}:e}setCapabilities(e){this.opts.capabilities=e,this.categoryCanManage=new Set(e??[]).has("event:categories:manage"),this.tableCanManage=new Set(e??[]).has("event:tables:manage"),!this.categoryCanManage&&this.mode==="categories"||!this.tableCanManage&&this.mode==="tables"?this.setMode("view"):this.paintModeTabs(),this.ready&&this.resolveChannelCapabilities()}setTokenRefresh(e){this.opts.onTokenRefresh=e,this.scheduleTokenRefresh()}setTrendWindow(e){let t=Number.isFinite(e)?Math.floor(e):15;return this.trendWindowMinutes=Math.max(5,Math.min(60,t)),this.paintTrendWindow(),this.refreshControlRoom()}async enterFullscreen(){!this.root?.requestFullscreen||this.isFullscreen()||(await this.root.requestFullscreen(),this.root.focus({preventScroll:!0}))}async exitFullscreen(){typeof document>"u"||!this.isFullscreen()||await document.exitFullscreen()}isFullscreen(){return typeof document<"u"&&document.fullscreenElement===this.root}toggleFullscreen(){(this.isFullscreen()?this.exitFullscreen():this.enterFullscreen()).catch(t=>this.opts.onError?.(t))}setToken(e,t){Ye(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.sessionEnded||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.tokenRefreshFailures=0,this.setToken(e.token,e.expiresAt)}catch(e){this.opts.onError?.(e),this.tokenRefreshFailures+=1,!this.closed&&(this.tokenRefreshFailures>=un||bn(e))?this.endSession():this.closed||(this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},3e4))}finally{this.tokenRefreshInFlight=!1}}}endSession(){if(this.sessionEnded)return;this.sessionEnded=!0,this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.tokenRefreshTimer=null,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.monitorRefreshTimer&&clearTimeout(this.monitorRefreshTimer),this.monitorRefreshTimer=null;let e=this.ws;if(this.ws=null,e){e.onclose=null;try{e.close()}catch{}}this.setLive(!1),this.paintSessionEnded()}async retrySession(){if(this.closed||!this.sessionEnded)return!this.sessionEnded;if(!this.opts.onTokenRefresh)return!1;this.sessionEnded=!1,this.tokenRefreshFailures=0;let e=this.root?.querySelector('[data-ref="ended"]');return e?.setAttribute("data-busy","true"),await this.rotateToken(),this.sessionEnded?(e?.removeAttribute("data-busy"),!1):(e?.remove(),this.attempt=0,this.connect(),!0)}paintSessionEnded(){let e=this.els.lane;if(!e||e.querySelector('[data-ref="ended"]'))return;let t=document.createElement("div");t.className="slm-ended",t.setAttribute("data-ref","ended"),t.setAttribute("role","alertdialog"),t.setAttribute("aria-labelledby","slm-ended-title"),t.innerHTML=`
|
|
1464
|
+
</div>`}var pn="https://api.seatlayer.io",Ve=200,bs=16,gs=4,vs=[{key:"watch",label:"Watch",tools:[{mode:"view",label:"Monitor",shortcut:"M",title:"Live board \u2014 inventory, activity and booking momentum. Read-only."},{mode:"inspect",label:"Inspect",shortcut:"I",title:"Click one seat to read its live status and booking context. Read-only."}]},{key:"manage",label:"Manage",tools:[{mode:"block",label:"Block",shortcut:"B",title:"Take seats off sale for this event, or put them back."},{mode:"sections",label:"Sections",shortcut:"S",title:"Open, close or hide sections for this event, on a schedule or on demand."},{mode:"categories",label:"Categories",shortcut:"G",title:"Move seats to a different price category for this event only."},{mode:"tables",label:"Tables",shortcut:"T",title:"Sell each table per chair or as one whole-table booking."},{mode:"channels",label:"Channels",shortcut:"C",title:"Allocate inventory to sales channels and share their links."}]},{key:"host",label:"Host tools",tools:[{mode:"select",label:"Select",shortcut:"X",title:"Select seats for your own back-office operation. The selection is handed to your app; nothing changes here."},{mode:"filterSections",label:"Filter",shortcut:"L",title:"Filter the map to one section for your own reporting."}]}],un=3;function bn(o){let e=o?.status;return e===401||e===403}var fs=o=>`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${o}</svg>`,nt={enter:fs('<path d="M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5"/>'),exit:fs('<path d="M9 4v5H4M20 9h-5V4M15 20v-5h5M4 15h5v5"/>')},gn=Object.fromEntries(vs.flatMap(o=>o.tools.map(e=>[e.shortcut.toLowerCase(),e.mode]))),qe=class{constructor(e){this.els={};this.renderer=null;this.doc=null;this.selectObserver=null;this.seatHistoryPanel=null;this.activityPanel=null;this.navigation=null;this.movingMap=!1;this.marqueeShape="box";this.socketSnapshotSeen=!1;this.monitorRefreshTimer=null;this.themeMode=null;this.colorSchemeStop=null;this.inventoryModelVersion=1;this.selectableObjectLabels=new Set;this.unavailableLabels=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.tableChairIds=new Map;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.mapView=we();this.barFind=null;this.minimap=null;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.chromeClearance=-1;this.chromeClearanceWidth=-1;this.tokenExpiresAt=null;this.tokenRefreshTimer=null;this.tokenRefreshInFlight=!1;this.tokenRefreshFailures=0;this.sessionEnded=!1;this.sectionByObject=new Map;this.sectionLabelById=new Map;this.sectionsBase=null;this.filteredSectionLabel=null;this.availabilityRules={};this.effectiveHidden=new Set;this.effectiveClosed=new Set;this.availabilitySaving=!1;this.lastSyncedAt=null;this.blockBrowse=!1;this.blockedQuery="";this.blockedSection="";this.blockedResultLimit=100;this.unblockAllConfirmTimer=null;this.channels=null;this.chooser=null;this.chooserDialog=null;this.categoryDifferences=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(),n=e.shiftKey?Kt(s):null;if(n){this.toggleMapView(n),e.preventDefault();return}if(s==="/"){let a=this.els.findbar?.querySelector("[data-ch-find-input]");a&&(a.focus(),a.select(),e.preventDefault());return}let i=gn[s];if(i){if(!this.toolAvailable(i))return;this.setMode(i)}else if(s==="f")this.toggleFullscreen();else if(s==="escape"){let a=this.els.view;if(a?.open)a.open=!1,a.querySelector("summary")?.focus();else if(!this.channels?.handleBack())if(this.getSelection().length)this.clearSelection();else return}else return;e.preventDefault()};this.onRailClick=e=>{let t=e.target,s=t?.closest("[data-section-focus]");if(s?.dataset.sectionFocus){this.locateSection(s.dataset.sectionFocus);return}let n=t?.closest("[data-feed-id]");n?.dataset.feedId&&this.locateActivity(n.dataset.feedId)};this.typeKeyBySection=null;this.typeKeyBase=null;this.sectionOptions=[];Ye(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.unavailableLabels=new Set(e.unavailableObjects??[]),this.categoryCanManage=new Set(e.capabilities??[]).has("event:categories:manage"),this.tableCanManage=new Set(e.capabilities??[]).has("event:tables:manage"),this.keepLive=e.keepLiveWhileHidden??!0,this.themeMode=e.themeMode??null,this.followLive=e.followLive??!1,this.currency=e.currency??"USD",this.tokenExpiresAt=e.tokenExpiresAt??null,this.api=new G(e.apiBase??pn,e.token),this.organizerAssetUrls=new be(this.key,(t,s)=>this.withAuthRetry(()=>this.api.asset(t,s))),this.host=Ct(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(){ft(),this.buildChrome();try{let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1,this.doc=await this.organizerAssetUrls.prepareRendererChart(e.doc),this.authoritativeCurrency=e.event.currency??null,this.currency=this.authoritativeCurrency??this.opts.currency??this.currency,this.buildUnitUniverse(this.doc),this.buildRenderer(),this.buildSectionOptions(),this.settleMode();let[,t]=await Promise.all([this.resnapshot(),this.refreshControlRoom().catch(s=>this.opts.onError?.(s)),this.refreshAvailability()]);t?.activity?this.seedFeed(t.activity):this.api.log(this.key,{limit:24}).then(s=>this.seedFeed(s.entries)).catch(()=>{}),this.connect(),this.startFeedClock(),this.ready=!0,await this.resolveChannelCapabilities(),this.setMode(this.mode),this.applyInitialSelection(),this.scheduleTokenRefresh(),this.opts.onReady?.()}catch(e){this.fail(e)}return this}setMode(e){this.toolAvailable(e)||(e="view"),e==="channels"&&!this.channels&&this.ensureChannels();let t=e!==this.mode,s=this.mode==="channels",n=this.mode==="filterSections";this.mode=e,t&&e!=="view"&&this.setFollowLive(!1),!this.renderer&&this.doc?this.buildRenderer():this.updateRendererInteraction(),t&&(this.renderer?.clearSelection(),this.syncSelection()),s&&e!=="channels"&&this.channels?.leave(),t&&(this.highlightLabels(null),this.wireBarFind()),this.paintModeTabs(),this.paintRail(),this.paintMapViewMenu(),this.applyMapView(),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(()=>(st(),us));if(this.closed||!this.channelCaps.view||(this.channels||(vt(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(),this.applyMapView(),this.paintMapViewMenu()}catch(t){if(this.closed)return;this.channelsLoading=null,this.mode==="channels"&&this.paintRail(),this.opts.onError?.(t)}})();return this.channelsLoading=e,e}buildChooserHost(){let e=s=>{let n=this.labelToSeat.get(s);return n?this.mode==="block"?this.isBlockSelectable(s):this.mode==="select"?this.canSelectObject(n):!0:!1};return{selectionLabels:()=>this.selectionLabels(),selectByLabels:s=>{this.selectByLabels(s)},clearSelection:()=>this.clearSelection(),selectSection:s=>{this.selectSection(s)},sections:()=>this.sectionOptions,labelsInSection:s=>(this.renderer?.getSelectableInSection(s)??[]).map(n=>n.label).filter(e),rows:()=>{let s=new Map((this.doc?.objects??[]).map(i=>[i.id,i])),n=new Map;for(let i of this.labelToSeat.values()){if(!e(i.label))continue;let a=s.get(i.rowId);if(!a||a.type!=="row"&&a.type!=="table")continue;let l=i.logicalRowId??i.rowId,r=this.sectionByObject.get(i.rowId)??k.UNGROUPED_ID,c=n.get(l)??{id:l,label:a.type==="row"?a.segmentedRow?.displayLabel??a.displayLabel??a.label:a.displayLabel??a.label,sectionId:r,sectionLabel:this.sectionLabelById.get(r)??"Other seats",labels:[]};c.labels.push(i.label),n.set(l,c)}return[...n.values()].sort((i,a)=>i.sectionLabel.localeCompare(a.sectionLabel,void 0,{numeric:!0,sensitivity:"base"})||i.label.localeCompare(a.label,void 0,{numeric:!0,sensitivity:"base"}))},categories:()=>(this.doc?.categories??[]).map(s=>({key:s.key,label:s.label??s.key,color:s.color})),labelsInCategory:s=>[...this.labelToSeat.values()].filter(n=>n.categoryKey===s&&e(n.label)).map(n=>n.label),seats:()=>[...this.labelToSeat.values()].filter(s=>e(s.label)).map(s=>({label:s.label})),statusOf:s=>this.status.get(s)??(this.labelToSeat.has(s)?"free":void 0),sectionOfLabel:s=>{let n=this.labelToSeat.get(s);if(!n)return null;let i=this.sectionByObject.get(n.rowId)??k.UNGROUPED_ID;return{id:i,label:this.sectionLabelById.get(i)??"Other seats"}},openDialog:(s,n)=>{this.chooserDialog=pt(this.root,s,n,{previous:this.chooserDialog,onClose:()=>{this.chooserDialog=null}})},closeDialog:()=>this.chooserDialog?.close(),highlight:s=>this.highlightLabels(s),...this.mode==="select"?{cap:this.selectionCap()}:{}}}wireBarFind(){let e=this.els.findbar;e&&(e.innerHTML=ke({compact:!0}),this.barFind=new N({...this.buildChooserHost(),seats:()=>[...this.labelToSeat.values()].map(t=>({label:t.label})),frame:t=>this.frameLabels(t)}),this.barFind.wireFind(e,{enter:this.isChoosingTool()?"select":"frame"}))}isChoosingTool(){return this.isBulkSelectMode()||this.mode==="select"}frameLabels(e){let t=e.map(s=>this.labelToSeat.get(s)?.id).filter(s=>!!s);t.length&&(this.setFollowLive(!1),this.renderer?.focusSeats?.(t,{animate:!0}))}highlightLabels(e){if(!e){this.renderer?.setSeatHighlight?.(null);return}this.renderer?.setSeatHighlight?.(e.map(t=>this.labelToSeat.get(t)?.id).filter(t=>!!t))}toolChooser(){return this.chooserDialog?.close({restoreFocus:!1}),this.chooser=new N(this.buildChooserHost()),this.chooser}toolSelectionBar(e,t,s,n){return It({count:0,noun:"selected",breakdown:`<span class="slm-selactions"><button type="button" class="slm-linkbtn" data-ref="${n}">Select all</button></span>`,clearAttr:`data-ref="${s}"`}).replace('class="slm-selnum"',`class="slm-selnum" data-ref="${e}"`).replace('class="slm-sellabel"',`class="slm-sellabel" data-ref="${t}"`)}buildChannelsHost(){return{eventKey:this.key,api:this.api,rail:this.els.rail,mapLayer:this.root.querySelector(".slm-map"),pillLane:this.els.lane,root:this.root,seats:()=>[...this.labelToSeat.values()].map(e=>({id:e.id,label:e.label,x:e.x,y:e.y})),statusOf:e=>this.status.get(e)??(this.labelToSeat.has(e)?"free":void 0),selectionLabels:()=>this.selectionLabels(),selectByLabels:e=>{this.selectByLabels(e)},clearSelection:()=>this.clearSelection(),selectSection:e=>{this.selectSection(e)},sections:()=>this.sectionOptions,labelsInSection:e=>this.renderer?.getSelectableInSection(e).map(t=>t.label)??[],rows:()=>{let e=new Map((this.doc?.objects??[]).map(s=>[s.id,s])),t=new Map;for(let s of this.labelToSeat.values()){let 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)??k.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,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)??k.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.mapView.momentum!==e&&this.setMapView({momentum:e}),this.applyHeatOverlay(),this.paintHeatButton()}setMapView(e){let t={...this.mapView,...e};if(!Object.keys(t).some(i=>t[i]!==this.mapView[i]))return;let n=t.categoryColours!==this.mapView.categoryColours;this.mapView=t,Yt(t),t.momentum!==this.heatEnabled&&this.setHeatOverlay(t.momentum),this.applyMapView(),this.paintMapViewMenu(),n&&(this.refreshBlockPaint(),this.paintMapChrome())}getColourBy(){return this.mapView.categoryColours?"type":"full"}setColourBy(e){this.setMapView({categoryColours:e==="type"})}getMapView(){return{...this.mapView}}toggleMapView(e){e==="channelColours"&&!this.channelColoursAvailable()||this.setMapView({[e]:!this.mapView[e]})}channelColoursAvailable(){return this.mode==="channels"&&this.channels!=null}applyMapView(){Xt(this.mapView,{renderer:this.renderer,channelsOverlay:e=>this.channels?.setOverlayVisible(e)})}paintMapViewMenu(){let e=this.els.view;e&&Qt(e,this.mapView,{channelColoursAvailable:this.channelColoursAvailable(),momentumLoading:this.mapView.momentum&&!this.controlRoomSnapshot})}setFollowLive(e){let t=this.followLive!==e;this.followLive=e,e||(this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=null,this.followSeatTimer=null),this.paintFollowLiveButton(),t&&this.opts.onFollowLiveChange?.(e)}setKeepLiveWhileHidden(e){this.keepLive=e??!0,this.opts.keepLiveWhileHidden=e}setCurrency(e){this.opts.currency=e,!this.authoritativeCurrency&&(this.currency=e??"USD",this.ready&&this.recomputeTallies())}setTheme(e){this.opts.theme=e,this.applyThemeVars()}applyThemeVars(){if(!this.root)return;let e=Ke(this.themeMode);for(let[t,s]of Object.entries(Et(this.opts.theme,e)))this.root.style.setProperty(t,s);e?this.root.dataset.theme=e:delete this.root.dataset.theme}watchThemeMode(){this.colorSchemeStop?.(),this.colorSchemeStop=null,this.themeMode==="auto"&&(this.colorSchemeStop=xt(()=>{this.closed||this.repaintForThemeMode()}))}repaintForThemeMode(){this.applyThemeVars();let e=this.renderer;if(!e||!this.doc)return;let t=e.getSelection().map(i=>i.id),s=e.getCameraPose(),n=e.getFocusedSection();e.setChart(this.themedDoc()),this.repaintAll(),this.applyHeatOverlay(),t.length&&e.select(t),n&&e.focusSection(n),e.setCameraPose(s),this.updateZoomHint()}setThemeMode(e){let t=e??null;this.closed||t===this.themeMode||(this.themeMode=t,this.opts.themeMode=t??void 0,this.watchThemeMode(),this.repaintForThemeMode())}getThemeMode(){return this.themeMode}themedDoc(){let e=this.doc,t=Rt(Ke(this.themeMode));return t?{...e,theme:{...e.theme??{},background:t}}:e}setCapabilities(e){this.opts.capabilities=e,this.categoryCanManage=new Set(e??[]).has("event:categories:manage"),this.tableCanManage=new Set(e??[]).has("event:tables:manage"),!this.categoryCanManage&&this.mode==="categories"||!this.tableCanManage&&this.mode==="tables"?this.setMode("view"):this.paintModeTabs(),this.ready&&this.resolveChannelCapabilities()}setTokenRefresh(e){this.opts.onTokenRefresh=e,this.scheduleTokenRefresh()}setTrendWindow(e){let t=Number.isFinite(e)?Math.floor(e):15;return this.trendWindowMinutes=Math.max(5,Math.min(60,t)),this.paintTrendWindow(),this.refreshControlRoom()}async enterFullscreen(){!this.root?.requestFullscreen||this.isFullscreen()||(await this.root.requestFullscreen(),this.root.focus({preventScroll:!0}))}async exitFullscreen(){typeof document>"u"||!this.isFullscreen()||await document.exitFullscreen()}isFullscreen(){return typeof document<"u"&&document.fullscreenElement===this.root}toggleFullscreen(){(this.isFullscreen()?this.exitFullscreen():this.enterFullscreen()).catch(t=>this.opts.onError?.(t))}setToken(e,t){Ye(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.sessionEnded||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.tokenRefreshFailures=0,this.setToken(e.token,e.expiresAt)}catch(e){this.opts.onError?.(e),this.tokenRefreshFailures+=1,!this.closed&&(this.tokenRefreshFailures>=un||bn(e))?this.endSession():this.closed||(this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},3e4))}finally{this.tokenRefreshInFlight=!1}}}endSession(){if(this.sessionEnded)return;this.sessionEnded=!0,this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.tokenRefreshTimer=null,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.monitorRefreshTimer&&clearTimeout(this.monitorRefreshTimer),this.monitorRefreshTimer=null;let e=this.ws;if(this.ws=null,e){e.onclose=null;try{e.close()}catch{}}this.setLive(!1),this.paintSessionEnded()}async retrySession(){if(this.closed||!this.sessionEnded)return!this.sessionEnded;if(!this.opts.onTokenRefresh)return!1;this.sessionEnded=!1,this.tokenRefreshFailures=0;let e=this.root?.querySelector('[data-ref="ended"]');return e?.setAttribute("data-busy","true"),await this.rotateToken(),this.sessionEnded?(e?.removeAttribute("data-busy"),!1):(e?.remove(),this.attempt=0,this.connect(),!0)}paintSessionEnded(){let e=this.els.lane;if(!e||e.querySelector('[data-ref="ended"]'))return;let t=document.createElement("div");t.className="slm-ended",t.setAttribute("data-ref","ended"),t.setAttribute("role","alertdialog"),t.setAttribute("aria-labelledby","slm-ended-title"),t.innerHTML=`
|
|
1465
1465
|
<strong id="slm-ended-title">This session ended</strong>
|
|
1466
1466
|
<span>The map is as it was when the connection stopped. Sign in again, then try again to pick the live stream back up.</span>
|
|
1467
|
-
<button type="button" class="slm-btn" data-ref="ended-retry">Try again</button>`,t.querySelector('[data-ref="ended-retry"]').addEventListener("click",()=>{this.retrySession()}),e.appendChild(t)}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 S&&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),c=this.labelToId.get(l);r&&(r.categoryKey=e),c&&(a[c]=e)}this.renderer?.setSeatCategories?.(a),this.clearSelection(),this.mode==="categories"&&this.loadCategoryDifferences(),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 S&&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.tableChairIds.clear(),this.status.clear(),this.counts={held:0,booked:0,blocked:0},this.serverBaseline=null,this.lastSelectionLabels.clear(),this.buildUnitUniverse(t),this.buildRenderer(),this.buildSectionOptions(),this.settleMode(),await Promise.all([this.resnapshot(),this.refreshAvailability()]),this.paintRail()}selectAll(){if(this.mode==="select")return this.selectByLabels([...this.labelToSeat.values()].filter(t=>this.canSelectObject(t)).map(t=>t.label));let e=this.renderer?.selectAllSelectable()??[];return this.syncSelection(),e}selectSection(e){if(!this.renderer)return[];let t=this.renderer.getSelectableInSection(e);return this.renderer.selectByLabels(t.map(s=>s.label)),this.syncSelection(),this.renderer.getSelection()}setFilteredSection(e){let t=e.trim(),s=this.filterableSections().filter(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:c})=>({id:a,label:l,seatCount:r,...c?{zone:c}:{}}));return n&&this.opts.onFilteredSectionChange?.(i),i}focusSection(e){let t=e.trim(),s=this.filterableSections().filter(n=>n.label===t);return!this.renderer||!s.length?[]:(this.frameSections(s),s.map(({id:n,label:i,seatCount:a,zone:l})=>({id:n,label:i,seatCount:a,...l?{zone:l}:{}})))}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()}zoomOutStep(){let e=this.renderer;if(!e)return;if(!e.zoomOutLevel)return void e.zoomOut();let t=!!e.getFocusedSection?.();e.zoomOutLevel()==="venue"&&t&&e.clearSectionFocus()}paintMapChrome(){let e=this.renderer;if(!e||!this.els.crumb)return;let t=e.getFocusedSection?.()??null,s=t?e.getMinimapSnapshot?.().sections.find(l=>l.id===t)??null:null,n=e.getFloors?.()??[],i=n.length>1?e.isFloorOverview?.()?"All floors":n.find(l=>l.id===e.getActiveFloorId?.())?.name??null:null,a=this.els.blocklegend;a&&Nt(a,{colourBy:this.getColourBy(),seats:e.getRung?.()==="seats",types:this.legendTypes()}),Vt(this.els,zt({focused:s?{label:s.label,free:s.free,total:s.total}:null,floor:i,seatsRevealed:e.seatsRevealed?.()??!0,atVenueFit:e.atVenueFit?.(),atCeiling:e.canZoomIn?.()===!1||e.seatsPickable?.()===!0}))}sectionTypeKeys(){if(this.typeKeyBySection&&this.typeKeyBase===this.sectionsBase)return this.typeKeyBySection;let e=new Map;for(let t of this.filterableSections()){let s=new Map;for(let i of t.seatLabels){let a=this.labelToSeat.get(i)?.categoryKey;a&&s.set(a,(s.get(a)??0)+1)}let n=null;for(let[i,a]of s)(!n||a>s.get(n))&&(n=i);n&&e.set(t.id,n)}return this.typeKeyBySection=e,this.typeKeyBase=this.sectionsBase,e}sectionTypeTint(e){let t=this.sectionTypeKeys().get(e);return t?this.renderer?.categoryDisplayColor?.(t)??null:null}legendTypes(){let e=new Set;for(let t of this.labelToSeat.values())e.add(t.categoryKey);return(this.doc?.categories??[]).filter(t=>e.has(t.key)).map(t=>({label:t.label,color:this.renderer?.categoryDisplayColor?.(t.key)??t.color}))}refreshBlockPaint(){this.renderer?.refreshBlockPaint?.(),this.minimap?.refreshMinimap()}mapCamera(){return{getViewport:()=>{let e=this.renderer;return!e?.getVisibleWorldRect||!e.getWorldBounds?null:{visible:e.getVisibleWorldRect(),bounds:e.getWorldBounds()}},getMinimapSnapshot:()=>this.renderer?.getMinimapSnapshot?.()??{sections:[],seats:[]},panToWorld:e=>{this.setFollowLive(!1),this.renderer?.panToWorld?.(e)},clearSectionFocus:()=>this.renderer?.clearSectionFocus?.(),focusSection:e=>{this.setFollowLive(!1),this.renderer?.focusSection(e),this.channels?.handleSectionFocus(e)},overview:()=>{this.setFollowLive(!1),this.zoomToFit()},getFloors:()=>this.renderer?.getFloors?.()??[],getActiveFloorId:()=>this.renderer?.getActiveFloorId?.()??"",isFloorOverview:()=>this.renderer?.isFloorOverview?.()??!1,getRenderer:()=>this.renderer}}syncMinimap(){let e=this.els.minimapMount,t=!!this.root?.classList.contains("compact");if(!e||!this.renderer||t){this.minimap?.dispose(),this.minimap=null;return}if(this.minimap){this.minimap.refreshMinimap();return}this.minimap=Bt({controller:this.mapCamera(),root:()=>this.root,cssVar:s=>this.cssVar(s.replace(/^--sl-/,"--slm-")),focusedSectionLabel:()=>{},tint:s=>this.renderer?.categoryDisplayColor?.(s)||void 0},e),this.minimap.refreshMinimap()}cssVar(e){return this.root?getComputedStyle(this.root).getPropertyValue(e).trim():""}destroy(){if(this.selectObserver?.disconnect(),this.closed=!0,this.minimap?.dispose(),this.minimap=null,this.monitorRefreshTimer&&clearTimeout(this.monitorRefreshTimer),this.monitorRefreshTimer=null,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.feedTimer&&clearInterval(this.feedTimer),this.toastTimer&&clearTimeout(this.toastTimer),this.liveEventTimer&&clearTimeout(this.liveEventTimer),this.kpiCleanupTimer&&clearTimeout(this.kpiCleanupTimer),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.paintHandle!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.paintHandle),this.paintHandle=null,this.channels?.destroy(),this.channels=null,this.channelsLoading=null,this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.layoutObserver?.disconnect(),this.layoutObserver=null,this.colorSchemeStop?.(),this.colorSchemeStop=null,this.root?.removeEventListener("keydown",this.onKeyDown),this.els.rail?.removeEventListener("click",this.onRailClick),typeof document<"u"&&document.removeEventListener("fullscreenchange",this.onFullscreenChange),this.ws){try{this.ws.close()}catch{}this.ws=null}this.seatHistoryPanel?.destroy(),this.seatHistoryPanel=null,this.activityPanel?.destroy(),this.activityPanel=null,this.navigation?.destroy(),this.navigation=null,this.renderer?.destroy(),this.renderer=null,this.organizerAssetUrls.dispose(),this.root&&this.root.parentNode===this.host&&this.host.removeChild(this.root)}buildRenderer(){if(!this.doc)return;let e=this.isBulkSelectMode();this.renderer=new k.SeatmapRenderer(this.mapHost,{manageMode:!0,organizerGlyph:{apply:k.applyOrganizerSeatGlyph,clear:k.clearOrganizerSeatGlyph,isPainted:k.isOrganizerGlyphPainted},marqueeSelect:e&&!this.movingMap,marqueeShape:this.marqueeShape,rowLabelSelect:this.rowLabelSelectable(),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(),onGAClick:t=>{if(this.mode!=="select"||!this.opts.onAreaClick||!this.doc)return;let s=(0,k.gaAreasOf)(this.doc).find(n=>n.id===t);s&&this.opts.onAreaClick({id:s.id,label:s.label,name:s.displayLabel?.trim()||s.label})},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.paintMapChrome(),this.minimap?.drawMinimapRect(),this.channels?.handleViewChange()},onFocusedSectionChange:()=>{this.paintMapChrome(),this.minimap?.refreshMinimap()},hoverFacts:t=>this.hoverFactsFor(t),blockPaint:t=>qt(t,{rule:this.availabilityRules[t.id],hiddenNow:this.effectiveHidden.has(t.id),closedNow:this.effectiveClosed.has(t.id),colourBy:this.getColourBy(),typeTint:this.sectionTypeTint(t.id)}),openAtSectionsWhenDense:!0}),this.renderer.setChart(this.themedDoc()),this.chromeClearance=-1,this.applyChromeClearance(),this.repaintAll(),this.applyHeatOverlay(),this.applyMapView(),this.updateZoomHint(),this.minimap?.dispose(),this.minimap=null,this.syncMinimap(),this.paintMapChrome()}hoverFactsFor(e){let t=[...this.labelToSeat.values()].find(d=>d.id===e);if(!t)return null;let s=this.status.get(t.label)??"free",i=[{caption:"Status",value:{free:"Free",held:"Held",booked:"Booked",blocked:"Blocked"}[s]}],a=this.channels?.channelNameForLabel(t.label)??null;a&&i.push({caption:"Channel",value:a});let l=this.sectionByObject.get(t.rowId)??k.UNGROUPED_ID,r=this.doc?.categories.find(d=>d.key===t.categoryKey),c=s==="free"&&!this.effectiveHidden.has(l)&&!this.effectiveClosed.has(l)&&r?.notForSale!==!0;return i.push({caption:"For sale",value:c?"Yes":s==="free"?"No":"\u2014"}),i}rowLabelSelectable(){return this.isBulkSelectMode()||this.mode==="select"}marqueeShapeChipsHtml(){let e=(t,s)=>`<button type="button" class="slm-btn${this.marqueeShape===t?"":" ghost"}" data-ref="shape-${t}"
|
|
1468
|
-
aria-pressed="${this.marqueeShape===t}" title="${t==="box"?"Drag a rectangle over seats":"Draw a loop around seats"}">${s}</button>`;return`${e("box","Drag box")}${e("lasso","Lasso")}`}wireMarqueeShapeChips(){this.els.rail.querySelectorAll('[data-ref^="shape-"]').forEach(e=>{e.addEventListener("click",()=>{let t=e.dataset.ref==="shape-lasso"?"lasso":"box";t!==this.marqueeShape&&(this.marqueeShape=t,this.updateRendererInteraction(),this.els.rail.querySelectorAll('[data-ref^="shape-"]').forEach(s=>{let n=s.dataset.ref===`shape-${t}`;s.classList.toggle("ghost",!n),s.setAttribute("aria-pressed",String(n))}))})})}isBulkSelectMode(){return this.mode==="block"||this.mode==="categories"||this.mode==="channels"&&this.channels?.usesMarqueeSelection()===!0}selectableStatuses(){return this.mode==="block"?["free","not_for_sale"]:this.mode==="select"||this.mode==="categories"||this.mode==="inspect"||this.isBulkSelectMode()||this.mode==="channels"&&this.channels?.canSelect()===!0?["free","held","booked","not_for_sale"]:[]}updateRendererInteraction(){let e=this.isBulkSelectMode();this.renderer?.setManageInteraction({manageMode:!0,organizerStatus:this.mode!=="channels",marqueeSelect:e&&!this.movingMap,marqueeShape:this.marqueeShape,rowLabelSelect:this.rowLabelSelectable(),maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses()}),this.navigation?.update(e,this.mode==="view"),this.updateZoomHint()}handleSeatSelect(e){if(this.mode==="select"&&!this.canSelectObject(e)){this.renderer?.deselect([e.id]),this.syncSelection();return}if(this.mode==="inspect"){let t=this.getSelection().filter(s=>s.id!==e.id).map(s=>s.id);t.length&&this.renderer?.deselect(t)}this.syncSelection()}buildUnitUniverse(e){let t=new Map;for(let n of(0,k.allObjects)(e))n.type==="table"&&t.set(n.id,n.label);let s=new Map;for(let n of(0,k.expandChart)(e))if(this.labelToId.set(n.label,n.id),this.labelToSeat.set(n.label,n),this.allIds.push(n.id),t.has(n.rowId)){let i=s.get(n.rowId)??[];i.push(n.id),s.set(n.rowId,i)}for(let[n,i]of s){let a=t.get(n);this.labelToId.has(a)||this.tableChairIds.set(a,i)}for(let n of(0,k.gaAreasOf)(e))for(let i of(0,k.gaUnitLabels)(n))this.labelToId.has(i)||this.gaUnitLabelSet.add(i)}unitTotal(){return this.allIds.length+this.gaUnitLabelSet.size}paintIds(e){let t=this.labelToId.get(e);return t?[t]:this.tableChairIds.get(e)??[]}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())t[fe(n)].push(...this.paintIds(s));["held","booked","not_for_sale"].forEach(s=>{t[s].length&&e.setStatus(t[s],s)})}async connect(){if(this.closed||this.sessionEnded)return;let e;try{if(e=(await this.withAuthRetry(()=>this.api.subscribeTicket(this.key))).protocols,!e.length)throw new Error("manage_subscribe_ticket_missing")}catch(s){this.setLive(!1),this.opts.onError?.(s),this.scheduleReconnect();return}if(this.closed)return;let t;try{t=new WebSocket(this.api.socketUrl(this.key),e)}catch(s){this.opts.onError?.(s),this.scheduleReconnect();return}this.ws=t,this.socketSnapshotSeen=!1,t.onopen=()=>{this.attempt=0,this.setLive(!0),this.resnapshot().then(()=>this.refreshControlRoom()).catch(s=>this.opts.onError?.(s)),this.refreshAvailability()},t.onmessage=s=>this.onMessage(s),t.onclose=()=>{this.ws===t&&(this.ws=null),this.setLive(!1),this.scheduleReconnect()},t.onerror=()=>{try{t.close()}catch{}}}scheduleReconnect(){if(this.closed||this.sessionEnded||this.reconnectTimer)return;let e=Math.min(1e3*2**Math.min(this.attempt++,5),15e3);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}onMessage(e){let t;try{t=JSON.parse(typeof e.data=="string"?e.data:"")}catch{return}if(!t||typeof t!="object")return;this.lastMessageAt=Date.now();let s=t;if((Array.isArray(s.hidden)||Array.isArray(s.closed))&&this.updateEffectiveAvailability(s.hidden,s.closed),s.type==="presence"){typeof s.shoppingSessions=="number"&&typeof s.activeHolds=="number"&&(this.livePresence={at:Date.now(),value:{shoppingSessions:s.shoppingSessions,activeHolds:s.activeHolds}},this.controlRoomSnapshot&&(this.controlRoomSnapshot={...this.controlRoomSnapshot,presence:this.livePresence.value},this.opts.onControlRoom?.(this.controlRoomSnapshot)),this.lastSyncedAt=Date.now(),this.recomputeTallies(),this.paintMonitorInsights());return}if(s.type!=="hidden"){if(s.seats&&typeof s.seats=="object")this.applySocketSnapshot(s.seats,typeof s.default=="string"?s.default:void 0);else if(Array.isArray(s.changes)){let n=[],i=new Map;for(let l of s.changes){let r=["free","held","booked","blocked"].includes(l.status)?l.status:"free",c=this.status.get(l.label)??"free";if(c===r)continue;this.setStatusLabel(l.label,r,c);let d=this.paintIds(l.label);d.length&&(this.renderer?.setStatus(d,fe(r)),n.push(...d));let h=this.verbFor(c,r),f=`${h}:${r}`,m=i.get(f)??{labels:[],verb:h,status:r};m.labels.push(l.label),i.set(f,m)}for(let l of i.values()){let r=this.pushActivity(l.labels,l.verb,l.status);r&&this.paintSpatialActivity(r)}i.size&&this.scheduleMonitorRefresh(),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))}applySocketSnapshot(e,t){let s=this.socketSnapshotSeen?this.status:null;if(this.applySnapshot(e,t),this.socketSnapshotSeen=!0,!s)return;let n=new Map;for(let i of new Set([...s.keys(),...this.status.keys()])){let a=s.get(i)??"free",l=this.status.get(i)??"free";if(a===l)continue;let r=this.verbFor(a,l),c=`${r}:${l}`,d=n.get(c)??{labels:[],verb:r,status:l};d.labels.push(i),n.set(c,d)}for(let i of n.values()){let a=this.pushActivity(i.labels,i.verb,i.status);a&&this.paintSpatialActivity(a)}n.size&&this.scheduleMonitorRefresh()}scheduleMonitorRefresh(){this.monitorRefreshTimer||(this.monitorRefreshTimer=setTimeout(()=>{this.monitorRefreshTimer=null,this.closed||this.refreshControlRoom().catch(e=>this.opts.onError?.(e))},150))}async resnapshot(){try{let e=await this.api.objects(this.key);this.applySnapshot(e.seats),this.updateEffectiveAvailability(e.hidden,e.closed),this.lastMessageAt=Date.now()}catch{}}applySnapshot(e,t){let s=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),s.push(...this.paintIds(n));s.length&&this.renderer?.setStatus(s,fe(t)),this.afterPaint(),this.recomputeTallies()}afterPaint(){this.keepLive&&typeof document<"u"&&document.hidden&&this.renderer?.forceDraw()}activityColor(e){return e==="held"?H.held:e==="booked"?H.booked:e==="blocked"?H.blocked:H.free}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!==k.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,bs)){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;if(this.followLive&&t.length===1&&(e.status==="held"||e.status==="booked")){let i=this.root?.querySelector('[data-ref="followstatus"]');i&&(i.textContent=`Following ${e.labels.length===1?e.labels[0]:`${e.labels.length} seats`} \xB7 ${e.status}`),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=setTimeout(()=>{this.followLiveTimer=null,this.focusActivitySeats(e.labels,t[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(e.labels,e.status)},520)},220);return}if(!s&&t.length){let i=this.activityColor(e.status);for(let a of t.slice(0,gs))this.renderer?.flashSection(a,i);return}(!t.length||s&&t.includes(s))&&this.pulseSeatLabels(e.labels,e.status)}locateSection(e){this.renderer?.focusSection(e)}focusActivitySeats(e,t){this.renderer?.focusSection(t);let s=e.slice(0,bs).map(r=>this.labelToSeat.get(r)).filter(r=>!!r);if(!s.length)return;let n=s.map(r=>r.x),i=s.map(r=>r.y),a=Math.min(...n),l=Math.min(...i);this.renderer?.focusRegion({x:a-150,y:l-100,width:Math.max(...n)-a+300,height:Math.max(...i)-l+200})}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.focusActivitySeats(t.labels,s[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(t.labels,t.status)},520);return}this.zoomToFit(),this.followSeatTimer=setTimeout(()=>{if(this.followSeatTimer=null,s.length){let n=this.activityColor(t.status);for(let i of s.slice(0,gs))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>
|
|
1469
|
-
<span class="slm-liveeventcopy">${
|
|
1470
|
-
<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 c=Number.isFinite(r.bookedValue)?r.bookedValue:r.bookedRevenue;return{...r,bookedValue:c??0,bookedRevenue:c??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 d={...l.bookedValue,gross:this.liveGross.value};l={...l,bookedValue:d,revenue:d}}else this.liveGross=null;this.controlRoomSnapshot=l,l.activity&&this.seedFeed(l.activity),this.rebaseServerTotals(l),this.lastSyncedAt=Date.now(),this.authoritativeGrossRevenue=l.bookedValue.gross,this.authoritativeCurrency=l.currency,this.currency=l.currency,this.revenueStatus="current",this.recomputeTallies(),this.applyHeatOverlay(),this.paintMonitorInsights(),this.seatHistoryPanel?.refresh();let r=this.getSelection().slice(-1)[0],c=this.els.rail?.querySelector("[data-seat-status]");r&&c&&(c.textContent=this.status.get(r.label)??"free"),this.opts.onControlRoom?.(l)}return l}catch(s){throw e===this.revenueRequest&&(this.revenueStatus="stale",this.recomputeTallies()),s}}rebaseServerTotals(e){let t=e.totals;if(!t||["free","held","booked","blocked"].some(s=>!Number.isFinite(t[s]))){this.serverBaseline=null;return}this.serverBaseline={model:this.modelVersion,server:{free:t.free,held:t.held,booked:t.booked,blocked:t.blocked},client:this.clientTallies()}}clientTallies(){let{held:e,booked:t,blocked:s}=this.counts;return{held:e,booked:t,blocked:s,free:Math.max(0,this.unitTotal()-e-t-s)}}buildTallies(){let e=this.clientTallies(),t=this.serverBaseline?.model===this.modelVersion?this.serverBaseline:null,s=l=>t?Math.max(0,t.server[l]+(e[l]-t.client[l])):e[l],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.minimap?.refreshMinimap(),this.mode==="view"?(this.paintLegend(e),this.paintMonitorInsights()):this.mode==="inspect"?this.renderInspectRail(this.getSelection()):this.mode==="block"?this.paintSelBar(this.getSelection()):this.mode==="channels"&&this.channels?.handleSelectionChange(),this.opts.onTallies?.(e)}verbFor(e,t){return t==="held"?"held":t==="booked"?"booked":t==="blocked"?"blocked":t==="free"?e==="blocked"?"unblocked":e==="booked"?"cancelled":"available":t}pushActivity(e,t,s,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.controlRoomSnapshot?.activity||this.feed.unshift(l),this.feed.length>Ve&&(this.feed.length=Ve),this.mode==="view"&&this.paintFeed(),this.showLiveEvent(l),this.opts.onActivity?.(l),l}seedFeed(e){this.controlRoomSnapshot?.activity&&(this.feed=this.feed.filter(n=>n.id.startsWith("log:")));let t={hold:"held",book:"booked",release:"released",expire:"expired",block:"blocked",unblock:"unblocked",unbook:"cancelled"},s={hold:"held",book:"booked",release:"free",expire:"free",block:"blocked",unblock:"free",unbook:"free"};for(let n of e){if(this.feed.some(r=>r.id===`log:${n.id}`))continue;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>Ve&&(this.feed.length=Ve),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.navigation?.selectionChanged(e.length),this.opts.onSelectionChange?.(e)}buildChrome(){let e=document.createElement("div"),t=this.opts.chrome==="minimal";e.className=t?"slm slm-minimal":"slm",e.tabIndex=0,e.setAttribute("role","region"),e.setAttribute("aria-label",t?"Seat map":"SeatLayer live control room"),e.innerHTML=`
|
|
1467
|
+
<button type="button" class="slm-btn" data-ref="ended-retry">Try again</button>`,t.querySelector('[data-ref="ended-retry"]').addEventListener("click",()=>{this.retrySession()}),e.appendChild(t)}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 S&&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),c=this.labelToId.get(l);r&&(r.categoryKey=e),c&&(a[c]=e)}this.renderer?.setSeatCategories?.(a),this.clearSelection(),this.mode==="categories"&&this.loadCategoryDifferences(),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 S&&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.tableChairIds.clear(),this.status.clear(),this.counts={held:0,booked:0,blocked:0},this.serverBaseline=null,this.lastSelectionLabels.clear(),this.buildUnitUniverse(t),this.buildRenderer(),this.buildSectionOptions(),this.settleMode(),await Promise.all([this.resnapshot(),this.refreshAvailability()]),this.paintRail()}selectAll(){if(this.mode==="select")return this.selectByLabels([...this.labelToSeat.values()].filter(t=>this.canSelectObject(t)).map(t=>t.label));let e=this.renderer?.selectAllSelectable()??[];return this.syncSelection(),e}selectSection(e){if(!this.renderer)return[];let t=this.renderer.getSelectableInSection(e);return this.renderer.selectByLabels(t.map(s=>s.label)),this.syncSelection(),this.renderer.getSelection()}setFilteredSection(e){let t=e.trim(),s=this.filterableSections().filter(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:c})=>({id:a,label:l,seatCount:r,...c?{zone:c}:{}}));return n&&this.opts.onFilteredSectionChange?.(i),i}focusSection(e){let t=e.trim(),s=this.filterableSections().filter(n=>n.label===t);return!this.renderer||!s.length?[]:(this.frameSections(s),s.map(({id:n,label:i,seatCount:a,zone:l})=>({id:n,label:i,seatCount:a,...l?{zone:l}:{}})))}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()}setUnavailableObjects(e,t){this.opts.unavailableObjectsReason=t;let s=new Set(e),n=[...s].filter(a=>!this.unavailableLabels.has(a)).concat([...this.unavailableLabels].filter(a=>!s.has(a)));if(!n.length)return;if(this.opts.unavailableObjects=[...s],this.unavailableLabels=s,this.renderer){let a=new Map;for(let l of n){let r=this.paintIds(l);if(!r.length)continue;let c=this.renderStatusOf(l,this.status.get(l)??"free");a.set(c,[...a.get(c)??[],...r])}for(let[l,r]of a)this.renderer.setStatus(r,l);this.afterPaint()}let i=this.getSelection().filter(a=>this.isHostUnavailable(a.label));i.length&&(this.renderer?.deselect(i.map(a=>a.id)),this.syncSelection())}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()}zoomOutStep(){let e=this.renderer;if(!e)return;if(!e.zoomOutLevel)return void e.zoomOut();let t=!!e.getFocusedSection?.();e.zoomOutLevel()==="venue"&&t&&e.clearSectionFocus()}paintMapChrome(){let e=this.renderer;if(!e||!this.els.crumb)return;let t=e.getFocusedSection?.()??null,s=t?e.getMinimapSnapshot?.().sections.find(l=>l.id===t)??null:null,n=e.getFloors?.()??[],i=n.length>1?e.isFloorOverview?.()?"All floors":n.find(l=>l.id===e.getActiveFloorId?.())?.name??null:null,a=this.els.blocklegend;a&&Nt(a,{colourBy:this.getColourBy(),seats:e.getRung?.()==="seats",types:this.legendTypes()}),Vt(this.els,zt({focused:s?{label:s.label,free:s.free,total:s.total}:null,floor:i,seatsRevealed:e.seatsRevealed?.()??!0,atVenueFit:e.atVenueFit?.(),atCeiling:e.canZoomIn?.()===!1||e.seatsPickable?.()===!0}))}sectionTypeKeys(){if(this.typeKeyBySection&&this.typeKeyBase===this.sectionsBase)return this.typeKeyBySection;let e=new Map;for(let t of this.filterableSections()){let s=new Map;for(let i of t.seatLabels){let a=this.labelToSeat.get(i)?.categoryKey;a&&s.set(a,(s.get(a)??0)+1)}let n=null;for(let[i,a]of s)(!n||a>s.get(n))&&(n=i);n&&e.set(t.id,n)}return this.typeKeyBySection=e,this.typeKeyBase=this.sectionsBase,e}sectionTypeTint(e){let t=this.sectionTypeKeys().get(e);return t?this.renderer?.categoryDisplayColor?.(t)??null:null}legendTypes(){let e=new Set;for(let t of this.labelToSeat.values())e.add(t.categoryKey);return(this.doc?.categories??[]).filter(t=>e.has(t.key)).map(t=>({label:t.label,color:this.renderer?.categoryDisplayColor?.(t.key)??t.color}))}refreshBlockPaint(){this.renderer?.refreshBlockPaint?.(),this.minimap?.refreshMinimap()}mapCamera(){return{getViewport:()=>{let e=this.renderer;return!e?.getVisibleWorldRect||!e.getWorldBounds?null:{visible:e.getVisibleWorldRect(),bounds:e.getWorldBounds()}},getMinimapSnapshot:()=>this.renderer?.getMinimapSnapshot?.()??{sections:[],seats:[]},panToWorld:e=>{this.setFollowLive(!1),this.renderer?.panToWorld?.(e)},clearSectionFocus:()=>this.renderer?.clearSectionFocus?.(),focusSection:e=>{this.setFollowLive(!1),this.renderer?.focusSection(e),this.channels?.handleSectionFocus(e)},overview:()=>{this.setFollowLive(!1),this.zoomToFit()},getFloors:()=>this.renderer?.getFloors?.()??[],getActiveFloorId:()=>this.renderer?.getActiveFloorId?.()??"",isFloorOverview:()=>this.renderer?.isFloorOverview?.()??!1,getRenderer:()=>this.renderer}}syncMinimap(){let e=this.els.minimapMount,t=!!this.root?.classList.contains("compact");if(!e||!this.renderer||t){this.minimap?.dispose(),this.minimap=null;return}if(this.minimap){this.minimap.refreshMinimap();return}this.minimap=Bt({controller:this.mapCamera(),root:()=>this.root,cssVar:s=>this.cssVar(s.replace(/^--sl-/,"--slm-")),focusedSectionLabel:()=>{},tint:s=>this.renderer?.categoryDisplayColor?.(s)||void 0},e),this.minimap.refreshMinimap()}cssVar(e){return this.root?getComputedStyle(this.root).getPropertyValue(e).trim():""}destroy(){if(this.selectObserver?.disconnect(),this.closed=!0,this.minimap?.dispose(),this.minimap=null,this.monitorRefreshTimer&&clearTimeout(this.monitorRefreshTimer),this.monitorRefreshTimer=null,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.feedTimer&&clearInterval(this.feedTimer),this.toastTimer&&clearTimeout(this.toastTimer),this.liveEventTimer&&clearTimeout(this.liveEventTimer),this.kpiCleanupTimer&&clearTimeout(this.kpiCleanupTimer),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.paintHandle!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.paintHandle),this.paintHandle=null,this.channels?.destroy(),this.channels=null,this.channelsLoading=null,this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.layoutObserver?.disconnect(),this.layoutObserver=null,this.colorSchemeStop?.(),this.colorSchemeStop=null,this.root?.removeEventListener("keydown",this.onKeyDown),this.els.rail?.removeEventListener("click",this.onRailClick),typeof document<"u"&&document.removeEventListener("fullscreenchange",this.onFullscreenChange),this.ws){try{this.ws.close()}catch{}this.ws=null}this.seatHistoryPanel?.destroy(),this.seatHistoryPanel=null,this.activityPanel?.destroy(),this.activityPanel=null,this.navigation?.destroy(),this.navigation=null,this.renderer?.destroy(),this.renderer=null,this.organizerAssetUrls.dispose(),this.root&&this.root.parentNode===this.host&&this.host.removeChild(this.root)}buildRenderer(){if(!this.doc)return;let e=this.isBulkSelectMode();this.renderer=new k.SeatmapRenderer(this.mapHost,{manageMode:!0,organizerGlyph:{apply:k.applyOrganizerSeatGlyph,clear:k.clearOrganizerSeatGlyph,isPainted:k.isOrganizerGlyphPainted},marqueeSelect:e&&!this.movingMap,marqueeShape:this.marqueeShape,rowLabelSelect:this.rowLabelSelectable(),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.mode==="select"?this.reconcileSelectPolicy():this.syncSelection(),onGAClick:t=>{if(this.mode!=="select"||!this.opts.onAreaClick||!this.doc)return;let s=(0,k.gaAreasOf)(this.doc).find(n=>n.id===t);s&&this.opts.onAreaClick({id:s.id,label:s.label,name:s.displayLabel?.trim()||s.label})},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.paintMapChrome(),this.minimap?.drawMinimapRect(),this.channels?.handleViewChange()},onFocusedSectionChange:()=>{this.paintMapChrome(),this.minimap?.refreshMinimap()},hoverFacts:t=>this.hoverFactsFor(t),blockPaint:t=>qt(t,{rule:this.availabilityRules[t.id],hiddenNow:this.effectiveHidden.has(t.id),closedNow:this.effectiveClosed.has(t.id),colourBy:this.getColourBy(),typeTint:this.sectionTypeTint(t.id)}),openAtSectionsWhenDense:!0}),this.renderer.setChart(this.themedDoc()),this.chromeClearance=-1,this.applyChromeClearance(),this.repaintAll(),this.applyHeatOverlay(),this.applyMapView(),this.updateZoomHint(),this.minimap?.dispose(),this.minimap=null,this.syncMinimap(),this.paintMapChrome()}hoverFactsFor(e){let t=[...this.labelToSeat.values()].find(b=>b.id===e);if(!t)return null;let s=this.status.get(t.label)??"free",n={free:"Free",held:"Held",booked:"Booked",blocked:"Blocked"},i=s==="free"&&this.isHostUnavailable(t.label),l=[{caption:"Status",value:i?this.opts.unavailableObjectsReason?.trim()||"Unavailable":n[s]}],r=this.channels?.channelNameForLabel(t.label)??null;r&&l.push({caption:"Channel",value:r});let c=this.sectionByObject.get(t.rowId)??k.UNGROUPED_ID,d=this.doc?.categories.find(b=>b.key===t.categoryKey),h=s==="free"&&!i&&!this.effectiveHidden.has(c)&&!this.effectiveClosed.has(c)&&d?.notForSale!==!0;return l.push({caption:"For sale",value:h?"Yes":s==="free"&&!i?"No":"\u2014"}),l}rowLabelSelectable(){return this.isBulkSelectMode()||this.mode==="select"}marqueeShapeChipsHtml(){let e=(t,s)=>`<button type="button" class="slm-btn${this.marqueeShape===t?"":" ghost"}" data-ref="shape-${t}"
|
|
1468
|
+
aria-pressed="${this.marqueeShape===t}" title="${t==="box"?"Drag a rectangle over seats":"Draw a loop around seats"}">${s}</button>`;return`${e("box","Drag box")}${e("lasso","Lasso")}`}wireMarqueeShapeChips(){this.els.rail.querySelectorAll('[data-ref^="shape-"]').forEach(e=>{e.addEventListener("click",()=>{let t=e.dataset.ref==="shape-lasso"?"lasso":"box";t!==this.marqueeShape&&(this.marqueeShape=t,this.updateRendererInteraction(),this.els.rail.querySelectorAll('[data-ref^="shape-"]').forEach(s=>{let n=s.dataset.ref===`shape-${t}`;s.classList.toggle("ghost",!n),s.setAttribute("aria-pressed",String(n))}))})})}isBulkSelectMode(){return this.mode==="block"||this.mode==="categories"||this.mode==="channels"&&this.channels?.usesMarqueeSelection()===!0}selectableStatuses(){return this.mode==="block"?["free","not_for_sale"]:this.mode==="select"||this.mode==="categories"||this.mode==="inspect"||this.isBulkSelectMode()||this.mode==="channels"&&this.channels?.canSelect()===!0?["free","held","booked","not_for_sale"]:[]}updateRendererInteraction(){let e=this.isBulkSelectMode();this.renderer?.setManageInteraction({manageMode:!0,organizerStatus:this.mode!=="channels",marqueeSelect:e&&!this.movingMap,marqueeShape:this.marqueeShape,rowLabelSelect:this.rowLabelSelectable(),maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses()}),this.navigation?.update(e,this.mode==="view"),this.updateZoomHint()}handleSeatSelect(e){if(this.mode==="select"&&!this.canSelectObject(e)){this.renderer?.deselect([e.id]),this.syncSelection();return}if(this.mode==="inspect"){let t=this.getSelection().filter(s=>s.id!==e.id).map(s=>s.id);t.length&&this.renderer?.deselect(t)}this.syncSelection()}buildUnitUniverse(e){let t=new Map;for(let n of(0,k.allObjects)(e))n.type==="table"&&t.set(n.id,n.label);let s=new Map;for(let n of(0,k.expandChart)(e))if(this.labelToId.set(n.label,n.id),this.labelToSeat.set(n.label,n),this.allIds.push(n.id),t.has(n.rowId)){let i=s.get(n.rowId)??[];i.push(n.id),s.set(n.rowId,i)}for(let[n,i]of s){let a=t.get(n);this.labelToId.has(a)||this.tableChairIds.set(a,i)}for(let n of(0,k.gaAreasOf)(e))for(let i of(0,k.gaUnitLabels)(n))this.labelToId.has(i)||this.gaUnitLabelSet.add(i)}unitTotal(){return this.allIds.length+this.gaUnitLabelSet.size}paintIds(e){let t=this.labelToId.get(e);return t?[t]:this.tableChairIds.get(e)??[]}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())t[this.renderStatusOf(s,n)].push(...this.paintIds(s));for(let s of this.unavailableLabels)this.status.has(s)||t.held.push(...this.paintIds(s));["held","booked","not_for_sale"].forEach(s=>{t[s].length&&e.setStatus(t[s],s)})}async connect(){if(this.closed||this.sessionEnded)return;let e;try{if(e=(await this.withAuthRetry(()=>this.api.subscribeTicket(this.key))).protocols,!e.length)throw new Error("manage_subscribe_ticket_missing")}catch(s){this.setLive(!1),this.opts.onError?.(s),this.scheduleReconnect();return}if(this.closed)return;let t;try{t=new WebSocket(this.api.socketUrl(this.key),e)}catch(s){this.opts.onError?.(s),this.scheduleReconnect();return}this.ws=t,this.socketSnapshotSeen=!1,t.onopen=()=>{this.attempt=0,this.setLive(!0),this.resnapshot().then(()=>this.refreshControlRoom()).catch(s=>this.opts.onError?.(s)),this.refreshAvailability()},t.onmessage=s=>this.onMessage(s),t.onclose=()=>{this.ws===t&&(this.ws=null),this.setLive(!1),this.scheduleReconnect()},t.onerror=()=>{try{t.close()}catch{}}}scheduleReconnect(){if(this.closed||this.sessionEnded||this.reconnectTimer)return;let e=Math.min(1e3*2**Math.min(this.attempt++,5),15e3);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}onMessage(e){let t;try{t=JSON.parse(typeof e.data=="string"?e.data:"")}catch{return}if(!t||typeof t!="object")return;this.lastMessageAt=Date.now();let s=t;if((Array.isArray(s.hidden)||Array.isArray(s.closed))&&this.updateEffectiveAvailability(s.hidden,s.closed),s.type==="presence"){typeof s.shoppingSessions=="number"&&typeof s.activeHolds=="number"&&(this.livePresence={at:Date.now(),value:{shoppingSessions:s.shoppingSessions,activeHolds:s.activeHolds}},this.controlRoomSnapshot&&(this.controlRoomSnapshot={...this.controlRoomSnapshot,presence:this.livePresence.value},this.opts.onControlRoom?.(this.controlRoomSnapshot)),this.lastSyncedAt=Date.now(),this.recomputeTallies(),this.paintMonitorInsights());return}if(s.type!=="hidden"){if(s.seats&&typeof s.seats=="object")this.applySocketSnapshot(s.seats,typeof s.default=="string"?s.default:void 0);else if(Array.isArray(s.changes)){let n=[],i=new Map;for(let l of s.changes){let r=["free","held","booked","blocked"].includes(l.status)?l.status:"free",c=this.status.get(l.label)??"free";if(c===r)continue;this.setStatusLabel(l.label,r,c);let d=this.paintIds(l.label);d.length&&(this.renderer?.setStatus(d,this.renderStatusOf(l.label,r)),n.push(...d));let h=this.verbFor(c,r),b=`${h}:${r}`,m=i.get(b)??{labels:[],verb:h,status:r};m.labels.push(l.label),i.set(b,m)}for(let l of i.values()){let r=this.pushActivity(l.labels,l.verb,l.status);r&&this.paintSpatialActivity(r)}i.size&&this.scheduleMonitorRefresh(),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))}applySocketSnapshot(e,t){let s=this.socketSnapshotSeen?this.status:null;if(this.applySnapshot(e,t),this.socketSnapshotSeen=!0,!s)return;let n=new Map;for(let i of new Set([...s.keys(),...this.status.keys()])){let a=s.get(i)??"free",l=this.status.get(i)??"free";if(a===l)continue;let r=this.verbFor(a,l),c=`${r}:${l}`,d=n.get(c)??{labels:[],verb:r,status:l};d.labels.push(i),n.set(c,d)}for(let i of n.values()){let a=this.pushActivity(i.labels,i.verb,i.status);a&&this.paintSpatialActivity(a)}n.size&&this.scheduleMonitorRefresh()}scheduleMonitorRefresh(){this.monitorRefreshTimer||(this.monitorRefreshTimer=setTimeout(()=>{this.monitorRefreshTimer=null,this.closed||this.refreshControlRoom().catch(e=>this.opts.onError?.(e))},150))}async resnapshot(){try{let e=await this.api.objects(this.key);this.applySnapshot(e.seats),this.updateEffectiveAvailability(e.hidden,e.closed),this.lastMessageAt=Date.now()}catch{}}applySnapshot(e,t){let s=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=[],n=[];for(let i of e)this.setStatusLabel(i,t),(this.renderStatusOf(i,t)===fe(t)?s:n).push(...this.paintIds(i));s.length&&this.renderer?.setStatus(s,fe(t)),n.length&&this.renderer?.setStatus(n,"held"),this.afterPaint(),this.recomputeTallies()}afterPaint(){this.keepLive&&typeof document<"u"&&document.hidden&&this.renderer?.forceDraw()}activityColor(e){return e==="held"?H.held:e==="booked"?H.booked:e==="blocked"?H.blocked:H.free}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!==k.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,bs)){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;if(this.followLive&&t.length===1&&(e.status==="held"||e.status==="booked")){let i=this.root?.querySelector('[data-ref="followstatus"]');i&&(i.textContent=`Following ${e.labels.length===1?e.labels[0]:`${e.labels.length} seats`} \xB7 ${e.status}`),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=setTimeout(()=>{this.followLiveTimer=null,this.focusActivitySeats(e.labels,t[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(e.labels,e.status)},520)},220);return}if(!s&&t.length){let i=this.activityColor(e.status);for(let a of t.slice(0,gs))this.renderer?.flashSection(a,i);return}(!t.length||s&&t.includes(s))&&this.pulseSeatLabels(e.labels,e.status)}locateSection(e){this.renderer?.focusSection(e)}focusActivitySeats(e,t){this.renderer?.focusSection(t);let s=e.slice(0,bs).map(r=>this.labelToSeat.get(r)).filter(r=>!!r);if(!s.length)return;let n=s.map(r=>r.x),i=s.map(r=>r.y),a=Math.min(...n),l=Math.min(...i);this.renderer?.focusRegion({x:a-150,y:l-100,width:Math.max(...n)-a+300,height:Math.max(...i)-l+200})}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.focusActivitySeats(t.labels,s[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(t.labels,t.status)},520);return}this.zoomToFit(),this.followSeatTimer=setTimeout(()=>{if(this.followSeatTimer=null,s.length){let n=this.activityColor(t.status);for(let i of s.slice(0,gs))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>
|
|
1469
|
+
<span class="slm-liveeventcopy">${g(n)} \xB7 ${e.count.toLocaleString()} ${i} ${g(e.verb)}</span>
|
|
1470
|
+
<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 c=Number.isFinite(r.bookedValue)?r.bookedValue:r.bookedRevenue;return{...r,bookedValue:c??0,bookedRevenue:c??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 d={...l.bookedValue,gross:this.liveGross.value};l={...l,bookedValue:d,revenue:d}}else this.liveGross=null;this.controlRoomSnapshot=l,l.activity&&this.seedFeed(l.activity),this.rebaseServerTotals(l),this.lastSyncedAt=Date.now(),this.authoritativeGrossRevenue=l.bookedValue.gross,this.authoritativeCurrency=l.currency,this.currency=l.currency,this.revenueStatus="current",this.recomputeTallies(),this.applyHeatOverlay(),this.paintMonitorInsights(),this.seatHistoryPanel?.refresh();let r=this.getSelection().slice(-1)[0],c=this.els.rail?.querySelector("[data-seat-status]");r&&c&&(c.textContent=this.status.get(r.label)??"free"),this.opts.onControlRoom?.(l)}return l}catch(s){throw e===this.revenueRequest&&(this.revenueStatus="stale",this.recomputeTallies()),s}}rebaseServerTotals(e){let t=e.totals;if(!t||["free","held","booked","blocked"].some(s=>!Number.isFinite(t[s]))){this.serverBaseline=null;return}this.serverBaseline={model:this.modelVersion,server:{free:t.free,held:t.held,booked:t.booked,blocked:t.blocked},client:this.clientTallies()}}clientTallies(){let{held:e,booked:t,blocked:s}=this.counts;return{held:e,booked:t,blocked:s,free:Math.max(0,this.unitTotal()-e-t-s)}}buildTallies(){let e=this.clientTallies(),t=this.serverBaseline?.model===this.modelVersion?this.serverBaseline:null,s=l=>t?Math.max(0,t.server[l]+(e[l]-t.client[l])):e[l],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.minimap?.refreshMinimap(),this.mode==="view"?(this.paintLegend(e),this.paintMonitorInsights()):this.mode==="inspect"?this.renderInspectRail(this.getSelection()):this.mode==="block"?this.paintSelBar(this.getSelection()):this.mode==="channels"&&this.channels?.handleSelectionChange(),this.opts.onTallies?.(e)}verbFor(e,t){return t==="held"?"held":t==="booked"?"booked":t==="blocked"?"blocked":t==="free"?e==="blocked"?"unblocked":e==="booked"?"cancelled":"available":t}pushActivity(e,t,s,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.controlRoomSnapshot?.activity||this.feed.unshift(l),this.feed.length>Ve&&(this.feed.length=Ve),this.mode==="view"&&this.paintFeed(),this.showLiveEvent(l),this.opts.onActivity?.(l),l}seedFeed(e){this.controlRoomSnapshot?.activity&&(this.feed=this.feed.filter(n=>n.id.startsWith("log:")));let t={hold:"held",book:"booked",release:"released",expire:"expired",block:"blocked",unblock:"unblocked",unbook:"cancelled"},s={hold:"held",book:"booked",release:"free",expire:"free",block:"blocked",unblock:"free",unbook:"free"};for(let n of e){if(this.feed.some(r=>r.id===`log:${n.id}`))continue;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>Ve&&(this.feed.length=Ve),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}isHostUnavailable(e){return this.unavailableLabels.has(e)}renderStatusOf(e,t){return t==="free"&&this.unavailableLabels.has(e)?"held":fe(t)}canSelectObject(e){if(this.isHostUnavailable(e.label))return!1;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.navigation?.selectionChanged(e.length),this.opts.onSelectionChange?.(e)}buildChrome(){let e=document.createElement("div"),t=this.opts.chrome==="minimal";e.className=t?"slm slm-minimal":"slm",e.tabIndex=0,e.setAttribute("role","region"),e.setAttribute("aria-label",t?"Seat map":"SeatLayer live control room"),e.innerHTML=`
|
|
1471
1471
|
<div class="slm-bar">
|
|
1472
1472
|
<div class="slm-modes" data-ref="modes" role="tablist" aria-label="Control room tools">
|
|
1473
1473
|
${vs.map(i=>`<div class="slm-modegroup" data-group="${i.key}" role="presentation" hidden>
|
|
1474
|
-
<span class="slm-modegroup-label" aria-hidden="true">${
|
|
1474
|
+
<span class="slm-modegroup-label" aria-hidden="true">${g(i.label)}</span>
|
|
1475
1475
|
${i.tools.map(a=>`<button class="slm-mode" role="tab" data-mode="${a.mode}"
|
|
1476
|
-
title="${
|
|
1476
|
+
title="${g(a.title)} (${a.shortcut})" aria-keyshortcuts="${a.shortcut}" hidden>${g(a.label)}</button>`).join("")}
|
|
1477
1477
|
</div>`).join("")}
|
|
1478
1478
|
</div>
|
|
1479
1479
|
<select class="slm-tools" data-ref="tools" aria-label="Control room tools"></select>
|
|
@@ -1503,8 +1503,8 @@
|
|
|
1503
1503
|
<aside class="slm-rail"><div class="slm-railscroll" data-ref="rail"></div></aside>
|
|
1504
1504
|
</div>
|
|
1505
1505
|
<div class="slm-toast" data-ref="toast"></div>
|
|
1506
|
-
`,this.host.appendChild(e),this.root=e,this.selectObserver=new MutationObserver(()=>{let i=e.querySelector(".slm-rail");i&&(Y(i),lt(i))});let s=e.querySelector(".slm-rail");s&&this.selectObserver.observe(s,{childList:!0,subtree:!0}),this.applyThemeVars(),this.watchThemeMode(),this.updateContainerLayout(),typeof ResizeObserver<"u"&&(this.layoutObserver=new ResizeObserver(()=>this.updateContainerLayout()),this.layoutObserver.observe(e));let n=i=>e.querySelector(`[data-ref="${i}"]`);this.mapHost=n("maphost"),this.els={modes:n("modes"),tools:n("tools"),livetext:n("livetext"),kpis:n("kpis"),follow:n("follow"),view:n("view"),findbar:n("findbar"),fullscreen:n("fullscreen"),lane:n("lane"),zoomhint:n("zoomhint"),liveevent:n("liveevent"),rail:n("rail"),toast:n("toast"),mapchrome:n("mapchrome"),crumb:n("crumb"),zin:n("zin"),zout:n("zout"),zfit:n("zfit"),minimapMount:n("minimap"),blocklegend:n("blocklegend")},this.els.modes.querySelectorAll("[data-mode]").forEach(i=>i.addEventListener("click",()=>this.setMode(i.dataset.mode))),this.els.tools.addEventListener("change",()=>this.setMode(this.els.tools.value)),this.els.zfit.addEventListener("click",()=>{this.setFollowLive(!1),this.zoomToFit()}),this.els.zin.addEventListener("click",()=>{this.setFollowLive(!1),this.renderer?.zoomIn()}),this.els.zout.addEventListener("click",()=>{this.setFollowLive(!1),this.zoomOutStep()}),this.els.follow.addEventListener("click",()=>this.setFollowLive(!this.followLive)),this.els.blocklegend?.addEventListener("click",i=>{let a=i.target?.closest("[data-colour-by]");a?.dataset.colourBy&&this.setColourBy(a.dataset.colourBy)}),this.els.view.addEventListener("click",i=>{let a=i.target?.closest("[data-view]");a?.dataset.view&&this.toggleMapView(a.dataset.view)}),e.addEventListener("pointerdown",i=>{let a=this.els.view;a.open&&!a.contains(i.target)&&(a.open=!1)}),this.mapView=Wt(),this.opts.colourBy&&(this.mapView={...this.mapView,categoryColours:this.opts.colourBy==="type"}),this.heatEnabled=this.mapView.momentum,this.applyMapView(),this.wireBarFind(),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.paintMapViewMenu(),this.paintFullscreenButton(),this.navigation=new me({root:e,map:this.mapHost,setMoving:i=>{this.movingMap=i,this.updateRendererInteraction()},pauseFollow:()=>{this.followLive&&this.setFollowLive(!1)},clearSelection:()=>this.clearSelection(),zoomIn:()=>this.renderer?.zoomIn(),zoomOut:()=>this.renderer?.zoomOut(),targets:i=>this.navigationTargets(i)}),this.navigation.update(this.isBulkSelectMode(),this.mode==="view")}navigationTargets(e){let t=e.toLocaleLowerCase(),s=[];for(let i of this.sectionOptions)if(i.label.toLocaleLowerCase().includes(t)&&s.push({label:i.label,detail:"Section",locate:()=>this.locateSection(i.id)}),s.length>=20)return s;let n=new Map;for(let i of this.labelToSeat.values()){let a=n.get(i.rowId)??{minX:i.x,minY:i.y,maxX:i.x,maxY:i.y};a.minX=Math.min(a.minX,i.x),a.minY=Math.min(a.minY,i.y),a.maxX=Math.max(a.maxX,i.x),a.maxY=Math.max(a.maxY,i.y),n.set(i.rowId,a)}for(let i of this.doc?(0,k.floorsOf)(this.doc).flatMap(a=>a.objects):[]){if(i.type!=="row"||!(i.displayLabel??i.label).toLocaleLowerCase().includes(t))continue;let a=n.get(i.id);if(!a)continue;let{minX:l,minY:r,maxX:c,maxY:d}=a;if(s.push({label:i.displayLabel??i.label,detail:"Row",locate:()=>{let h=this.sectionByObject.get(i.id);h&&this.renderer?.focusSection(h),this.renderer?.focusRegion({x:l-30,y:r-30,width:c-l+60,height:d-r+60},{minScale:1.2,animate:!1})}}),s.length>=20)return s}for(let i of this.labelToSeat.values())if(i.label.toLocaleLowerCase().includes(t)&&(s.push({label:i.label,detail:"Seat",locate:()=>{let a=this.sectionByObject.get(i.rowId);a&&this.renderer?.focusSection(a),this.renderer?.focusRegion({x:i.x-180,y:i.y-120,width:360,height:240},{animate:!1,minScale:1.5}),this.renderer?.flashSeat(i.id,this.activityColor(this.status.get(i.label)??"free"))}}),s.length>=20))break;return s}applyChromeClearance(){if(this.opts.chrome!=="minimal"||!this.renderer)return;let e=this.els.mapchrome,t=e?.parentElement;if(!e||!t)return;let s=e.getBoundingClientRect(),n=t.getBoundingClientRect(),i=e.offsetHeight>0&&n.bottom>s.top,a=i?Math.ceil(n.bottom-s.top)+8:0,l=i?Math.ceil(n.right-s.left)+8:0;a===this.chromeClearance&&l===this.chromeClearanceWidth||(this.chromeClearance=a,this.chromeClearanceWidth=l,this.renderer.setFitClearance(a,l))}updateContainerLayout(){let e=this.root?.getBoundingClientRect().width||this.host.clientWidth;this.root?.classList.toggle("compact",e>0&&e<800),this.applyChromeClearance(),this.channels?.handleLayoutChange(),this.syncMinimap()}filterableSections(){return this.sectionsBase?[...this.sectionsBase.sections,...this.sectionsBase.ungrouped?[this.sectionsBase.ungrouped]:[]]:[]}applyFilteredSectionCanvas(e=this.filterableSections().filter(t=>t.label===this.filteredSectionLabel)){if(!this.renderer||this.mode!=="filterSections"||!e.length)return;let t=new Set(e.map(n=>n.id)),s=this.filterableSections().filter(n=>!t.has(n.id)).map(n=>n.id);this.renderer.clearSectionFocus(),this.renderer.setClosedSections(null),this.renderer.setDimmedSections(s),this.frameSections(e)}frameSections(e){if(!this.renderer||!e.length)return;let t=e.flatMap(r=>r.seatLabels).map(r=>this.labelToSeat.get(r)).filter(r=>!!r&&Number.isFinite(r.x)&&Number.isFinite(r.y));if(!t.length){this.renderer.focusRegion(e[0].id);return}let s=Math.min(...t.map(r=>r.x)),n=Math.min(...t.map(r=>r.y)),i=Math.max(...t.map(r=>r.x)),a=Math.max(...t.map(r=>r.y)),l=Math.max(40,Math.max(i-s,a-n)*.08);this.renderer.focusRegion({x:s-l,y:n-l,width:Math.max(1,i-s)+l*2,height:Math.max(1,a-n)+l*2})}buildSectionOptions(){if(this.doc)try{let e=(0,k.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:k.UNGROUPED_ID,label:e.ungrouped.label}),this.sectionLabelById.set(k.UNGROUPED_ID,e.ungrouped.label))}catch{}}toolAvailable(e){return e==="view"?!0:e==="channels"&&!this.channelCaps.view||e==="categories"&&!this.categoryCanManage||e==="tables"&&(!this.tableCanManage||!this.tables().length)?!1:!this.opts.tools||this.opts.tools.includes(e)}settleMode(){this.toolAvailable(this.mode)?this.paintModeTabs():this.setMode("view")}tables(){return(this.doc?(0,k.floorsOf)(this.doc):[]).flatMap(e=>e.objects).filter(e=>e.type==="table")}paintModeTabs(){let e=[];this.els.modes?.querySelectorAll(".slm-modegroup").forEach(s=>{let n=[];s.querySelectorAll("[data-mode]").forEach(i=>{let a=i.dataset.mode,l=this.toolAvailable(a);if(i.hidden=!l,!l)return;n.push({mode:a,label:i.textContent??a});let r=a===this.mode;i.classList.toggle("on",r),i.setAttribute("aria-selected",String(r)),i.tabIndex=r?0:-1}),s.hidden=n.length===0,n.length&&e.push({label:s.querySelector(".slm-modegroup-label")?.textContent??"",tools:n})});let t=this.els.tools;t&&(t.innerHTML=e.map(s=>`<optgroup label="${
|
|
1507
|
-
<p class="slm-hint">${s}</p>`}paintFollowLiveButton(){let e=this.els.follow;if(!e)return;e.classList.toggle("on",this.followLive),e.setAttribute("aria-pressed",String(this.followLive)),e.textContent="Auto-follow";let t=this.root?.querySelector('[data-ref="followstatus"]');t&&(t.hidden=!this.followLive,t.textContent="Waiting for new holds or bookings"),e.setAttribute("title",this.followLive?"Following new holds and bookings. Turn off to keep the current view.":"Stay on the current map view. Enable to follow new holds and bookings.")}paintHeatButton(){this.paintMapViewMenu(),this.paintMomentumHelp()}paintMomentumHelp(){let e=this.root?.querySelector('[data-ref="heatstatus"]');if(e){e.hidden=!this.heatEnabled;let i=this.controlRoomSnapshot?.velocity.bySection.some(a=>a.netBooked>0);e.textContent=this.controlRoomSnapshot?i?`Booking heatmap \xB7 last ${this.trendWindowMinutes}m \xB7 warmer = higher net booking rate`:`No positive net bookings in the last ${this.trendWindowMinutes}m`:"Loading booking heatmap\u2026"}let t=this.els.rail?.querySelector('[data-ref="momentumhelp"]');if(!t)return;t.hidden=!this.heatEnabled;let s=t.querySelector('[data-ref="momentumcopy"]');if(!s)return;let n=this.controlRoomSnapshot?.velocity.bySection.some(i=>i.netBooked>0);s.textContent=n?"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(){let e=this.els.fullscreen;if(!e)return;let t=this.isFullscreen(),s=t?"Exit full screen":"Full screen";e.setAttribute("aria-label",s),e.title=`${s} (F)`;let n=e.querySelector(".slm-fullscreen-label");n&&(n.textContent=s);let i=e.querySelector(".slm-fullscreen-icon");i&&(i.innerHTML=t?nt.exit:nt.enter)}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":this.sessionEnded?"ended":"reconnecting";if(this.els.livetext&&!e&&this.sessionEnded&&(this.els.livetext.textContent="ENDED"),t!==this.connectionStatus){this.connectionStatus=t;try{this.opts.onConnectionChange?.(this.getConnection())}catch(s){this.opts.onError?.(s)}}}updateZoomHint(){let e=this.els.zoomhint;if(!e)return;let t=this.isBulkSelectMode()&&!this.movingMap&&this.renderer?.getRung?.()!=="seats";e.classList.toggle("on",!!t)}formatKpiDelta(e,t,s){let n=t>0?"+":"\u2212",i=Math.abs(t);return e==="booked-value"?`${n}${ve(i,s)}`:e==="booked-pct"?`${n}${i.toLocaleString()}pt`:`${n}${i.toLocaleString()}`}paintKpis(e){if(!this.els.kpis)return;let t=e.bookedValueStatus==="current"?ve(e.bookedValue,e.currency):"\u2014",s=this.presenceCounts(),n=[{key:"booked-inventory",raw:e.booked,n:e.booked.toLocaleString(),l:"Booked inventory",dot:H.booked,title:"Inventory units booked"},{key:"held-seats",raw:e.held,n:e.held.toLocaleString(),l:"Held inventory",dot:H.held,title:"Inventory currently held"},{key:"free-seats",raw:e.free,n:e.free.toLocaleString(),l:"Available",dot:H.free,title:"Inventory available to book"},{key:"blocked",raw:e.blocked,n:e.blocked.toLocaleString(),l:"Blocked",dot:H.blocked,title:"Inventory withheld from booking"},{key:"viewing-map",raw:s?.shoppingSessions??null,n:s?s.shoppingSessions.toLocaleString():"\u2014",l:"Viewing map",title:"Active map sessions right now"},{key:"active-holds",raw:s?.activeHolds??null,n:s?s.activeHolds.toLocaleString():"\u2014",l:"Active holds",title:"Sessions currently holding inventory"},{key:"booked-pct",raw:e.capacityPct,n:`${e.capacityPct}%`,l:"Booked",title:"Booked inventory as a share of the whole event"},{key:"booked-value",raw:e.bookedValueStatus==="current"?e.bookedValue:null,n:t,l:"Booked value",title:"Configured value attached to booked inventory"}],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,c=r?a.raw-l:0;r&&(i=!0,this.activeKpiDeltas.set(a.key,{text:this.formatKpiDelta(a.key,c,e.currency),down:c<0})),a.raw!=null&&this.lastKpiValues.set(a.key,a.raw);let d=this.activeKpiDeltas.get(a.key);return`<div class="slm-kpi${d?" changed":""}" data-kpi="${a.key}" title="${
|
|
1506
|
+
`,this.host.appendChild(e),this.root=e,this.selectObserver=new MutationObserver(()=>{let i=e.querySelector(".slm-rail");i&&(Y(i),lt(i))});let s=e.querySelector(".slm-rail");s&&this.selectObserver.observe(s,{childList:!0,subtree:!0}),this.applyThemeVars(),this.watchThemeMode(),this.updateContainerLayout(),typeof ResizeObserver<"u"&&(this.layoutObserver=new ResizeObserver(()=>this.updateContainerLayout()),this.layoutObserver.observe(e));let n=i=>e.querySelector(`[data-ref="${i}"]`);this.mapHost=n("maphost"),this.els={modes:n("modes"),tools:n("tools"),livetext:n("livetext"),kpis:n("kpis"),follow:n("follow"),view:n("view"),findbar:n("findbar"),fullscreen:n("fullscreen"),lane:n("lane"),zoomhint:n("zoomhint"),liveevent:n("liveevent"),rail:n("rail"),toast:n("toast"),mapchrome:n("mapchrome"),crumb:n("crumb"),zin:n("zin"),zout:n("zout"),zfit:n("zfit"),minimapMount:n("minimap"),blocklegend:n("blocklegend")},this.els.modes.querySelectorAll("[data-mode]").forEach(i=>i.addEventListener("click",()=>this.setMode(i.dataset.mode))),this.els.tools.addEventListener("change",()=>this.setMode(this.els.tools.value)),this.els.zfit.addEventListener("click",()=>{this.setFollowLive(!1),this.zoomToFit()}),this.els.zin.addEventListener("click",()=>{this.setFollowLive(!1),this.renderer?.zoomIn()}),this.els.zout.addEventListener("click",()=>{this.setFollowLive(!1),this.zoomOutStep()}),this.els.follow.addEventListener("click",()=>this.setFollowLive(!this.followLive)),this.els.blocklegend?.addEventListener("click",i=>{let a=i.target?.closest("[data-colour-by]");a?.dataset.colourBy&&this.setColourBy(a.dataset.colourBy)}),this.els.view.addEventListener("click",i=>{let a=i.target?.closest("[data-view]");a?.dataset.view&&this.toggleMapView(a.dataset.view)}),e.addEventListener("pointerdown",i=>{let a=this.els.view;a.open&&!a.contains(i.target)&&(a.open=!1)}),this.mapView=Wt(),this.opts.colourBy&&(this.mapView={...this.mapView,categoryColours:this.opts.colourBy==="type"}),this.heatEnabled=this.mapView.momentum,this.applyMapView(),this.wireBarFind(),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.paintMapViewMenu(),this.paintFullscreenButton(),this.navigation=new me({root:e,map:this.mapHost,setMoving:i=>{this.movingMap=i,this.updateRendererInteraction()},pauseFollow:()=>{this.followLive&&this.setFollowLive(!1)},clearSelection:()=>this.clearSelection(),zoomIn:()=>this.renderer?.zoomIn(),zoomOut:()=>this.renderer?.zoomOut(),targets:i=>this.navigationTargets(i)}),this.navigation.update(this.isBulkSelectMode(),this.mode==="view")}navigationTargets(e){let t=e.toLocaleLowerCase(),s=[];for(let i of this.sectionOptions)if(i.label.toLocaleLowerCase().includes(t)&&s.push({label:i.label,detail:"Section",locate:()=>this.locateSection(i.id)}),s.length>=20)return s;let n=new Map;for(let i of this.labelToSeat.values()){let a=n.get(i.rowId)??{minX:i.x,minY:i.y,maxX:i.x,maxY:i.y};a.minX=Math.min(a.minX,i.x),a.minY=Math.min(a.minY,i.y),a.maxX=Math.max(a.maxX,i.x),a.maxY=Math.max(a.maxY,i.y),n.set(i.rowId,a)}for(let i of this.doc?(0,k.floorsOf)(this.doc).flatMap(a=>a.objects):[]){if(i.type!=="row"||!(i.displayLabel??i.label).toLocaleLowerCase().includes(t))continue;let a=n.get(i.id);if(!a)continue;let{minX:l,minY:r,maxX:c,maxY:d}=a;if(s.push({label:i.displayLabel??i.label,detail:"Row",locate:()=>{let h=this.sectionByObject.get(i.id);h&&this.renderer?.focusSection(h),this.renderer?.focusRegion({x:l-30,y:r-30,width:c-l+60,height:d-r+60},{minScale:1.2,animate:!1})}}),s.length>=20)return s}for(let i of this.labelToSeat.values())if(i.label.toLocaleLowerCase().includes(t)&&(s.push({label:i.label,detail:"Seat",locate:()=>{let a=this.sectionByObject.get(i.rowId);a&&this.renderer?.focusSection(a),this.renderer?.focusRegion({x:i.x-180,y:i.y-120,width:360,height:240},{animate:!1,minScale:1.5}),this.renderer?.flashSeat(i.id,this.activityColor(this.status.get(i.label)??"free"))}}),s.length>=20))break;return s}applyChromeClearance(){if(this.opts.chrome!=="minimal"||!this.renderer)return;let e=this.els.mapchrome,t=e?.parentElement;if(!e||!t)return;let s=e.getBoundingClientRect(),n=t.getBoundingClientRect(),i=e.offsetHeight>0&&n.bottom>s.top,a=i?Math.ceil(n.bottom-s.top)+8:0,l=i?Math.ceil(n.right-s.left)+8:0;a===this.chromeClearance&&l===this.chromeClearanceWidth||(this.chromeClearance=a,this.chromeClearanceWidth=l,this.renderer.setFitClearance(a,l))}updateContainerLayout(){let e=this.root?.getBoundingClientRect().width||this.host.clientWidth;this.root?.classList.toggle("compact",e>0&&e<800),this.applyChromeClearance(),this.channels?.handleLayoutChange(),this.syncMinimap()}filterableSections(){return this.sectionsBase?[...this.sectionsBase.sections,...this.sectionsBase.ungrouped?[this.sectionsBase.ungrouped]:[]]:[]}applyFilteredSectionCanvas(e=this.filterableSections().filter(t=>t.label===this.filteredSectionLabel)){if(!this.renderer||this.mode!=="filterSections"||!e.length)return;let t=new Set(e.map(n=>n.id)),s=this.filterableSections().filter(n=>!t.has(n.id)).map(n=>n.id);this.renderer.clearSectionFocus(),this.renderer.setClosedSections(null),this.renderer.setDimmedSections(s),this.frameSections(e)}frameSections(e){if(!this.renderer||!e.length)return;let t=e.flatMap(r=>r.seatLabels).map(r=>this.labelToSeat.get(r)).filter(r=>!!r&&Number.isFinite(r.x)&&Number.isFinite(r.y));if(!t.length){this.renderer.focusRegion(e[0].id);return}let s=Math.min(...t.map(r=>r.x)),n=Math.min(...t.map(r=>r.y)),i=Math.max(...t.map(r=>r.x)),a=Math.max(...t.map(r=>r.y)),l=Math.max(40,Math.max(i-s,a-n)*.08);this.renderer.focusRegion({x:s-l,y:n-l,width:Math.max(1,i-s)+l*2,height:Math.max(1,a-n)+l*2})}buildSectionOptions(){if(this.doc)try{let e=(0,k.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:k.UNGROUPED_ID,label:e.ungrouped.label}),this.sectionLabelById.set(k.UNGROUPED_ID,e.ungrouped.label))}catch{}}toolAvailable(e){return e==="view"?!0:e==="channels"&&!this.channelCaps.view||e==="categories"&&!this.categoryCanManage||e==="tables"&&(!this.tableCanManage||!this.tables().length)?!1:!this.opts.tools||this.opts.tools.includes(e)}settleMode(){this.toolAvailable(this.mode)?this.paintModeTabs():this.setMode("view")}tables(){return(this.doc?(0,k.floorsOf)(this.doc):[]).flatMap(e=>e.objects).filter(e=>e.type==="table")}paintModeTabs(){let e=[];this.els.modes?.querySelectorAll(".slm-modegroup").forEach(s=>{let n=[];s.querySelectorAll("[data-mode]").forEach(i=>{let a=i.dataset.mode,l=this.toolAvailable(a);if(i.hidden=!l,!l)return;n.push({mode:a,label:i.textContent??a});let r=a===this.mode;i.classList.toggle("on",r),i.setAttribute("aria-selected",String(r)),i.tabIndex=r?0:-1}),s.hidden=n.length===0,n.length&&e.push({label:s.querySelector(".slm-modegroup-label")?.textContent??"",tools:n})});let t=this.els.tools;t&&(t.innerHTML=e.map(s=>`<optgroup label="${g(s.label)}">${s.tools.map(n=>`<option value="${n.mode}"${n.mode===this.mode?" selected":""}>${g(n.label)}</option>`).join("")}</optgroup>`).join(""),t.value=this.mode),this.root?.classList.toggle("block-mode",this.mode==="block")}railHeader(e,t,s){let n=t==="read"?"Read-only":t==="event"?"This event only":"Your app";return`<div class="slm-railhead"><p class="slm-eyebrow">${g(e)}</p><span class="slm-scope ${t}">${n}</span></div>
|
|
1507
|
+
<p class="slm-hint">${s}</p>`}paintFollowLiveButton(){let e=this.els.follow;if(!e)return;e.classList.toggle("on",this.followLive),e.setAttribute("aria-pressed",String(this.followLive)),e.textContent="Auto-follow";let t=this.root?.querySelector('[data-ref="followstatus"]');t&&(t.hidden=!this.followLive,t.textContent="Waiting for new holds or bookings"),e.setAttribute("title",this.followLive?"Following new holds and bookings. Turn off to keep the current view.":"Stay on the current map view. Enable to follow new holds and bookings.")}paintHeatButton(){this.paintMapViewMenu(),this.paintMomentumHelp()}paintMomentumHelp(){let e=this.root?.querySelector('[data-ref="heatstatus"]');if(e){e.hidden=!this.heatEnabled;let i=this.controlRoomSnapshot?.velocity.bySection.some(a=>a.netBooked>0);e.textContent=this.controlRoomSnapshot?i?`Booking heatmap \xB7 last ${this.trendWindowMinutes}m \xB7 warmer = higher net booking rate`:`No positive net bookings in the last ${this.trendWindowMinutes}m`:"Loading booking heatmap\u2026"}let t=this.els.rail?.querySelector('[data-ref="momentumhelp"]');if(!t)return;t.hidden=!this.heatEnabled;let s=t.querySelector('[data-ref="momentumcopy"]');if(!s)return;let n=this.controlRoomSnapshot?.velocity.bySection.some(i=>i.netBooked>0);s.textContent=n?"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(){let e=this.els.fullscreen;if(!e)return;let t=this.isFullscreen(),s=t?"Exit full screen":"Full screen";e.setAttribute("aria-label",s),e.title=`${s} (F)`;let n=e.querySelector(".slm-fullscreen-label");n&&(n.textContent=s);let i=e.querySelector(".slm-fullscreen-icon");i&&(i.innerHTML=t?nt.exit:nt.enter)}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":this.sessionEnded?"ended":"reconnecting";if(this.els.livetext&&!e&&this.sessionEnded&&(this.els.livetext.textContent="ENDED"),t!==this.connectionStatus){this.connectionStatus=t;try{this.opts.onConnectionChange?.(this.getConnection())}catch(s){this.opts.onError?.(s)}}}updateZoomHint(){let e=this.els.zoomhint;if(!e)return;let t=this.isBulkSelectMode()&&!this.movingMap&&this.renderer?.getRung?.()!=="seats";e.classList.toggle("on",!!t)}formatKpiDelta(e,t,s){let n=t>0?"+":"\u2212",i=Math.abs(t);return e==="booked-value"?`${n}${ve(i,s)}`:e==="booked-pct"?`${n}${i.toLocaleString()}pt`:`${n}${i.toLocaleString()}`}paintKpis(e){if(!this.els.kpis)return;let t=e.bookedValueStatus==="current"?ve(e.bookedValue,e.currency):"\u2014",s=this.presenceCounts(),n=[{key:"booked-inventory",raw:e.booked,n:e.booked.toLocaleString(),l:"Booked inventory",dot:H.booked,title:"Inventory units booked"},{key:"held-seats",raw:e.held,n:e.held.toLocaleString(),l:"Held inventory",dot:H.held,title:"Inventory currently held"},{key:"free-seats",raw:e.free,n:e.free.toLocaleString(),l:"Available",dot:H.free,title:"Inventory available to book"},{key:"blocked",raw:e.blocked,n:e.blocked.toLocaleString(),l:"Blocked",dot:H.blocked,title:"Inventory withheld from booking"},{key:"viewing-map",raw:s?.shoppingSessions??null,n:s?s.shoppingSessions.toLocaleString():"\u2014",l:"Viewing map",title:"Active map sessions right now"},{key:"active-holds",raw:s?.activeHolds??null,n:s?s.activeHolds.toLocaleString():"\u2014",l:"Active holds",title:"Sessions currently holding inventory"},{key:"booked-pct",raw:e.capacityPct,n:`${e.capacityPct}%`,l:"Booked",title:"Booked inventory as a share of the whole event"},{key:"booked-value",raw:e.bookedValueStatus==="current"?e.bookedValue:null,n:t,l:"Booked value",title:"Configured value attached to booked inventory"}],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,c=r?a.raw-l:0;r&&(i=!0,this.activeKpiDeltas.set(a.key,{text:this.formatKpiDelta(a.key,c,e.currency),down:c<0})),a.raw!=null&&this.lastKpiValues.set(a.key,a.raw);let d=this.activeKpiDeltas.get(a.key);return`<div class="slm-kpi${d?" changed":""}" data-kpi="${a.key}" title="${g(a.title)}">
|
|
1508
1508
|
<b>${a.dot?`<span class="dot" style="background:${a.dot}"></span>`:""}${a.n}</b><span>${a.l}</span>
|
|
1509
1509
|
${d?`<span class="slm-kpidelta${d.down?" down":""}">${d.text}</span>`:""}
|
|
1510
1510
|
</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.root?.classList.toggle("monitor-view",this.mode==="view"||this.mode==="inspect"),this.seatHistoryPanel?.destroy(),this.seatHistoryPanel=null,this.activityPanel?.destroy(),this.activityPanel=null,this.mode==="view"?this.renderViewRail():this.mode==="inspect"?this.renderInspectRail(this.getSelection()):this.mode==="select"?this.renderSelectRail():this.mode==="filterSections"?this.renderFilterSectionsRail():this.mode==="sections"?this.renderSectionsRail():this.mode==="categories"?this.renderCategoriesRail():this.mode==="tables"?this.renderTablesRail():this.mode==="channels"?this.channels?this.channels.paintRail():this.channelsLoading?this.els.rail.innerHTML='<div class="slm-empty" role="status">Loading sales channels\u2026</div>':this.els.rail.innerHTML='<div class="slm-empty" role="alert">Sales channels could not be loaded. Switch away and back to try again.</div>':this.renderBlockRail(),this.updateZoomHint()}renderViewRail(){this.els.rail.innerHTML=`
|
|
@@ -1526,8 +1526,8 @@
|
|
|
1526
1526
|
</div>
|
|
1527
1527
|
<div class="slm-sectionlist" data-ref="sections"></div>
|
|
1528
1528
|
</div>
|
|
1529
|
-
`,this.els.presence=this.els.rail.querySelector('[data-ref="presence"]'),this.els.legend=this.els.rail.querySelector('[data-ref="legend"]'),this.els.sections=this.els.rail.querySelector('[data-ref="sections"]'),this.els.feed=this.els.rail.querySelector('[data-ref="feed"]'),this.activityPanel=new he(this.els.feed,this.sectionOptions,e=>{this.setFollowLive(!1),this.locateActivity(e)}),this.els.rail.querySelectorAll("[data-monitor-tab]").forEach(e=>e.addEventListener("click",()=>{let t=e.dataset.monitorTab;this.els.rail.querySelectorAll("[data-monitor-tab]").forEach(s=>s.setAttribute("aria-selected",String(s.dataset.monitorTab===t))),this.els.rail.querySelectorAll("[data-monitor-panel]").forEach(s=>{s.hidden=s.dataset.monitorPanel!==t})})),this.els.rail.querySelectorAll("[data-window]").forEach(e=>e.addEventListener("click",()=>{let t=Number(e.dataset.window);this.setTrendWindow(t).catch(s=>this.opts.onError?.(s))})),this.recomputeTallies(),this.paintMonitorInsights(),this.paintTrendWindow(),this.paintMomentumHelp(),this.paintFeed()}presenceCounts(){return this.livePresence?.value??this.controlRoomSnapshot?.presence??null}paintMonitorInsights(){if(this.mode!=="view")return;let e=this.controlRoomSnapshot;if(this.els.presence){let n=this.root?.classList.contains("live"),i=this.lastSyncedAt?$t(this.lastSyncedAt,Date.now()):"waiting";this.els.presence.textContent=n?"\u25CF Live":"Reconnecting",this.els.presence.title=`Last data received: ${i}`}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="${
|
|
1530
|
-
<span class="slm-sectiontop"><span>${
|
|
1529
|
+
`,this.els.presence=this.els.rail.querySelector('[data-ref="presence"]'),this.els.legend=this.els.rail.querySelector('[data-ref="legend"]'),this.els.sections=this.els.rail.querySelector('[data-ref="sections"]'),this.els.feed=this.els.rail.querySelector('[data-ref="feed"]'),this.activityPanel=new he(this.els.feed,this.sectionOptions,e=>{this.setFollowLive(!1),this.locateActivity(e)}),this.els.rail.querySelectorAll("[data-monitor-tab]").forEach(e=>e.addEventListener("click",()=>{let t=e.dataset.monitorTab;this.els.rail.querySelectorAll("[data-monitor-tab]").forEach(s=>s.setAttribute("aria-selected",String(s.dataset.monitorTab===t))),this.els.rail.querySelectorAll("[data-monitor-panel]").forEach(s=>{s.hidden=s.dataset.monitorPanel!==t})})),this.els.rail.querySelectorAll("[data-window]").forEach(e=>e.addEventListener("click",()=>{let t=Number(e.dataset.window);this.setTrendWindow(t).catch(s=>this.opts.onError?.(s))})),this.recomputeTallies(),this.paintMonitorInsights(),this.paintTrendWindow(),this.paintMomentumHelp(),this.paintFeed()}presenceCounts(){return this.livePresence?.value??this.controlRoomSnapshot?.presence??null}paintMonitorInsights(){if(this.mode!=="view")return;let e=this.controlRoomSnapshot;if(this.els.presence){let n=this.root?.classList.contains("live"),i=this.lastSyncedAt?$t(this.lastSyncedAt,Date.now()):"waiting";this.els.presence.textContent=n?"\u25CF Live":"Reconnecting",this.els.presence.title=`Last data received: ${i}`}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="${g(n.sectionId)}" title="Focus ${g(n.sectionLabel)} on the map">
|
|
1530
|
+
<span class="slm-sectiontop"><span>${g(n.sectionLabel)}</span><span title="Configured value of currently booked inventory">${ve(n.bookedValue,e.currency)}</span></span>
|
|
1531
1531
|
<span class="slm-sectionmeta"><span>${n.booked.toLocaleString()}/${n.total.toLocaleString()} booked \xB7 ${l} net in ${e.velocity.windowMinutes}m</span><span class="slm-trend ${r}">${r}</span><span class="slm-sectionlocate">Locate</span></span>
|
|
1532
1532
|
</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.opts.numberOfPlacesToSelect,t=this.selectionCap(),s=this.toolChooser();this.els.rail.innerHTML=`
|
|
1533
1533
|
${this.railHeader("Select","host","Pick seats for your own back-office operation \u2014 the selection is handed to your app. This tool is read-only inside the control room: it never books, releases or blocks seats by itself.")}
|
|
@@ -1537,8 +1537,8 @@
|
|
|
1537
1537
|
${this.toolSelectionBar("selectnum","selectmeta","selectclear","selectall")}
|
|
1538
1538
|
<p class="slm-note" data-ref="selectvalidity">${e?`Select exactly ${e.toLocaleString()} object${e===1?"":"s"}.`:`Up to ${t.toLocaleString()} objects may be selected.`}</p>`,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()),s.wire(this.els.rail),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.`)}renderFilterSectionsRail(){let e=new Map;for(let t of this.filterableSections())e.set(t.label,[...e.get(t.label)??[],t]);this.els.rail.innerHTML=`
|
|
1539
1539
|
${this.railHeader("Filter sections","host","Narrow the map to one section for your own reporting. Sections sharing a label stay together and the map frames their combined inventory. Nothing changes for buyers.")}
|
|
1540
|
-
${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="${
|
|
1541
|
-
<span class="slm-sectiontop"><span>${
|
|
1540
|
+
${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="${g(t)}" aria-pressed="${n}">
|
|
1541
|
+
<span class="slm-sectiontop"><span>${g(t)}</span><span>${i.toLocaleString()}</span></span>
|
|
1542
1542
|
<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>
|
|
1543
1543
|
</button>`}).join("")}</div>
|
|
1544
1544
|
<button type="button" class="slm-btn ghost" data-clear-filter ${this.filteredSectionLabel?"":"disabled"}>Clear filter</button>`:'<div class="slm-empty">This chart has no filterable sections.</div>'}`,this.els.rail.querySelectorAll("[data-filter-section]").forEach(t=>{t.addEventListener("click",()=>this.setFilteredSection(t.dataset.filterSection))}),this.els.rail.querySelector("[data-clear-filter]")?.addEventListener("click",()=>this.clearFilteredSection())}categorySeats(e){return[...this.labelToSeat.values()].filter(t=>t.categoryKey===e&&this.canSelectObject(t))}renderCategoriesRail(){let e=this.doc?.categories??[],t=this.toolChooser();this.els.rail.innerHTML=`
|
|
@@ -1550,41 +1550,41 @@
|
|
|
1550
1550
|
<p class="slm-eyebrow slm-step" style="margin-top:14px"><span class="slm-stepnum">2</span>Move them to</p>
|
|
1551
1551
|
<p class="slm-selecthelp" data-ref="categoryhelp">Select seats first \u2014 then pick the category they should sell under.</p>
|
|
1552
1552
|
<div class="slm-categoryassign">${e.length?e.map(n=>`
|
|
1553
|
-
<button type="button" class="slm-categoryrow" data-assign-category="${
|
|
1554
|
-
<span class="dot" style="background:${
|
|
1555
|
-
<span class="slm-categorycopy"><b>${
|
|
1553
|
+
<button type="button" class="slm-categoryrow" data-assign-category="${g(n.key)}" disabled>
|
|
1554
|
+
<span class="dot" style="background:${g(n.color??"#6e7bff")}"></span>
|
|
1555
|
+
<span class="slm-categorycopy"><b>${g(n.label??n.key)}</b><small data-cat-current>0 seats now</small></span>
|
|
1556
1556
|
<span class="slm-categoryact" data-cat-action>Move here</span>
|
|
1557
1557
|
</button>`).join(""):'<span class="slm-empty">This chart has no categories.</span>'}</div>
|
|
1558
1558
|
<div class="slm-catreset">
|
|
1559
1559
|
<button type="button" class="slm-btn ghost" data-ref="categoryreset" disabled>Reset to chart defaults</button>
|
|
1560
1560
|
<p class="slm-note" data-ref="categoryresetnote">Checking what differs from the chart\u2026</p>
|
|
1561
|
-
</div>`;let s=n=>this.els.rail.querySelector(`[data-ref="${n}"]`);this.els.categorynum=s("categorynum"),this.els.categorymeta=s("categorymeta"),this.els.categoryhelp=s("categoryhelp"),this.els.categoryclear=s("categoryclear"),s("categoryall").addEventListener("click",()=>this.selectAll()),this.els.categoryclear.addEventListener("click",()=>this.clearSelection()),this.els.rail.querySelectorAll("[data-assign-category]").forEach(n=>{n.addEventListener("click",()=>{this.setCategory(n.dataset.assignCategory)})}),s("categoryreset").addEventListener("click",()=>{this.resetCategoriesToChart()}),t.wire(this.els.rail),this.wireMarqueeShapeChips(),this.paintCategorySelection(this.getSelection()),this.loadCategoryDifferences()}async loadCategoryDifferences(){let e=this.els.rail;if(!e||this.closed)return;let t=e.querySelector('[data-ref="categoryreset"]'),s=e.querySelector('[data-ref="categoryresetnote"]');if(!(!t||!s))try{let n=await this.withAuthRetry(()=>this.api.categoryDifferences(this.key));if(!t.isConnected)return;this.categoryDifferences=n.differing,this.paintCategoryReset()}catch(n){if(!t.isConnected)return;s.textContent="Could not check the chart\u2019s defaults. Reset is unavailable until it can.",this.opts.onError?.(n)}}paintCategoryReset(){let e=this.els.rail;if(!e)return;let t=e.querySelector('[data-ref="categoryreset"]'),s=e.querySelector('[data-ref="categoryresetnote"]');if(!t||!s)return;let n=this.categoryDifferences;n!=null&&(t.disabled=n===0,t.textContent=n?`Reset to chart defaults \xB7 ${n.toLocaleString()} seat${n===1?"":"s"}`:"Reset to chart defaults",s.textContent=n?"Puts every seat this event moved back in its chart category. Held and booked seats keep the price they were sold at.":"Every seat sells under its chart category.")}async resetCategoriesToChart(){let e=this.els.rail.querySelector('[data-ref="categoryreset"]');e&&(e.disabled=!0,e.textContent="Resetting\u2026");try{let t=await this.withAuthRetry(()=>this.api.resetCategoriesToChart(this.key));t.changed&&await this.reloadEventChart(),this.categoryDifferences=0,this.clearSelection(),this.mode==="categories"&&this.paintRail(),this.paintCategoryReset(),this.done("resetCategories",t.labels,t.changed?`Put ${t.labels.length.toLocaleString()} seat${t.labels.length===1?"":"s"} back on the chart\u2019s categories.`:"Every seat already sells under its chart category.")}catch(t){this.paintCategoryReset(),this.toastErr("Couldn\u2019t reset those categories. Nothing changed."),this.opts.onError?.(t)}}paintCategorySelection(e){if(!this.els.categorynum)return;let t=e.length;this.els.categorynum.textContent=t.toLocaleString(),this.els.categoryclear.disabled=t===0;let s=new Map;for(let i of e)s.set(i.categoryKey,(s.get(i.categoryKey)??0)+1);let n=i=>this.doc?.categories.find(a=>a.key===i)?.label??i;this.els.categorymeta&&(this.els.categorymeta.textContent=t===0?"selected":`${t===1?"seat":"seats"} selected \xB7 ${[...s].map(([i,a])=>`${a.toLocaleString()} ${n(i)}`).join(", ")}`),this.els.categoryhelp&&(this.els.categoryhelp.textContent=t===0?"Select seats first \u2014 then pick the category they should sell under.":`Choose the category the ${t===1?"selected seat":`${t.toLocaleString()} selected seats`} should sell under. Applies immediately.`),this.els.rail?.querySelectorAll("[data-assign-category]").forEach(i=>{let a=i.dataset.assignCategory,l=[...this.labelToSeat.values()].filter(
|
|
1561
|
+
</div>`;let s=n=>this.els.rail.querySelector(`[data-ref="${n}"]`);this.els.categorynum=s("categorynum"),this.els.categorymeta=s("categorymeta"),this.els.categoryhelp=s("categoryhelp"),this.els.categoryclear=s("categoryclear"),s("categoryall").addEventListener("click",()=>this.selectAll()),this.els.categoryclear.addEventListener("click",()=>this.clearSelection()),this.els.rail.querySelectorAll("[data-assign-category]").forEach(n=>{n.addEventListener("click",()=>{this.setCategory(n.dataset.assignCategory)})}),s("categoryreset").addEventListener("click",()=>{this.resetCategoriesToChart()}),t.wire(this.els.rail),this.wireMarqueeShapeChips(),this.paintCategorySelection(this.getSelection()),this.loadCategoryDifferences()}async loadCategoryDifferences(){let e=this.els.rail;if(!e||this.closed)return;let t=e.querySelector('[data-ref="categoryreset"]'),s=e.querySelector('[data-ref="categoryresetnote"]');if(!(!t||!s))try{let n=await this.withAuthRetry(()=>this.api.categoryDifferences(this.key));if(!t.isConnected)return;this.categoryDifferences=n.differing,this.paintCategoryReset()}catch(n){if(!t.isConnected)return;s.textContent="Could not check the chart\u2019s defaults. Reset is unavailable until it can.",this.opts.onError?.(n)}}paintCategoryReset(){let e=this.els.rail;if(!e)return;let t=e.querySelector('[data-ref="categoryreset"]'),s=e.querySelector('[data-ref="categoryresetnote"]');if(!t||!s)return;let n=this.categoryDifferences;n!=null&&(t.disabled=n===0,t.textContent=n?`Reset to chart defaults \xB7 ${n.toLocaleString()} seat${n===1?"":"s"}`:"Reset to chart defaults",s.textContent=n?"Puts every seat this event moved back in its chart category. Held and booked seats keep the price they were sold at.":"Every seat sells under its chart category.")}async resetCategoriesToChart(){let e=this.els.rail.querySelector('[data-ref="categoryreset"]');e&&(e.disabled=!0,e.textContent="Resetting\u2026");try{let t=await this.withAuthRetry(()=>this.api.resetCategoriesToChart(this.key));t.changed&&await this.reloadEventChart(),this.categoryDifferences=0,this.clearSelection(),this.mode==="categories"&&this.paintRail(),this.paintCategoryReset(),this.done("resetCategories",t.labels,t.changed?`Put ${t.labels.length.toLocaleString()} seat${t.labels.length===1?"":"s"} back on the chart\u2019s categories.`:"Every seat already sells under its chart category.")}catch(t){this.paintCategoryReset(),this.toastErr("Couldn\u2019t reset those categories. Nothing changed."),this.opts.onError?.(t)}}paintCategorySelection(e){if(!this.els.categorynum)return;let t=e.length;this.els.categorynum.textContent=t.toLocaleString(),this.els.categoryclear.disabled=t===0;let s=new Map;for(let i of e)s.set(i.categoryKey,(s.get(i.categoryKey)??0)+1);let n=i=>this.doc?.categories.find(a=>a.key===i)?.label??i;this.els.categorymeta&&(this.els.categorymeta.textContent=t===0?"selected":`${t===1?"seat":"seats"} selected \xB7 ${[...s].map(([i,a])=>`${a.toLocaleString()} ${n(i)}`).join(", ")}`),this.els.categoryhelp&&(this.els.categoryhelp.textContent=t===0?"Select seats first \u2014 then pick the category they should sell under.":`Choose the category the ${t===1?"selected seat":`${t.toLocaleString()} selected seats`} should sell under. Applies immediately.`),this.els.rail?.querySelectorAll("[data-assign-category]").forEach(i=>{let a=i.dataset.assignCategory,l=[...this.labelToSeat.values()].filter(b=>b.categoryKey===a).length,r=s.get(a)??0,c=t>0&&r===t;i.disabled=t===0||c,i.classList.toggle("current",c);let d=i.querySelector("[data-cat-current]");d&&(d.textContent=`${l.toLocaleString()} ${l===1?"seat":"seats"} now`);let h=i.querySelector("[data-cat-action]");h&&(h.textContent=t===0?"Move here":c?"Already here":`Move ${(t-r).toLocaleString()} here`)})}renderTablesRail(){let e=this.tables(),t="Decide how each table sells for this event: every chair on its own, or the whole table as one booking. A table with held, booked, or blocked chairs is locked until that inventory is released, and channel allocations are kept.";if(this.inventoryModelVersion!==2){this.els.rail.innerHTML=`
|
|
1562
1562
|
${this.railHeader("Tables","event",t)}
|
|
1563
1563
|
<div class="slm-empty">This event still uses the older inventory model, which cannot switch tables between per-chair and whole-table selling. Upgrade the event's inventory model to unlock this tool.</div>`;return}if(!e.length){this.els.rail.innerHTML=`
|
|
1564
1564
|
${this.railHeader("Tables","event",t)}
|
|
1565
|
-
<div class="slm-empty">This chart has no tables. Add tables in the designer and they will appear here.</div>`;return}let s=h=>h.variableOccupancy?"variable":h.bookAsWhole?"whole":"individual",n=h=>{let
|
|
1565
|
+
<div class="slm-empty">This chart has no tables. Add tables in the designer and they will appear here.</div>`;return}let s=h=>h.variableOccupancy?"variable":h.bookAsWhole?"whole":"individual",n=h=>{let b=0,m=0,p=0;for(let[y,f]of this.labelToSeat){if(f.rowId!==h.id)continue;let C=this.status.get(y);C==="held"?b++:C==="booked"?m++:C==="blocked"&&p++}let v=[m&&`${m} booked`,b&&`${b} held`,p&&`${p} blocked`].filter(Boolean);return v.length?v.join(" \xB7 "):null},i=e.map(h=>({table:h,current:s(h),locked:n(h)})),a=i.filter(h=>h.current==="individual").length,l=i.filter(h=>h.current==="whole").length,r=i.length-a-l,c=[`${a.toLocaleString()} per chair`,`${l.toLocaleString()} whole table`,r?`${r.toLocaleString()} flexible group`:""].filter(Boolean).join(" \xB7 "),d=this.tableBookingSaving;this.els.rail.innerHTML=`
|
|
1566
1566
|
${this.railHeader("Tables","event",t)}
|
|
1567
|
-
<div class="slm-tablesummary"><b>${i.length.toLocaleString()} ${i.length===1?"table":"tables"}</b><span>${
|
|
1567
|
+
<div class="slm-tablesummary"><b>${i.length.toLocaleString()} ${i.length===1?"table":"tables"}</b><span>${g(c)}</span></div>
|
|
1568
1568
|
<p class="slm-eyebrow" style="margin-top:12px">Set every table at once</p>
|
|
1569
1569
|
<div class="slm-row">
|
|
1570
1570
|
<button class="slm-btn ghost" data-table-all="individual"${d?" disabled":""} title="Sell every chair on its own">All per chair</button>
|
|
1571
1571
|
<button class="slm-btn ghost" data-table-all="whole"${d?" disabled":""} title="Sell every table as one booking">All whole table</button>
|
|
1572
1572
|
</div>
|
|
1573
1573
|
<p class="slm-eyebrow" style="margin-top:12px">Or one table at a time</p>
|
|
1574
|
-
<div class="slm-tablelist">${i.map(({table:h,current:
|
|
1575
|
-
<span class="slm-tablecopy"><b>${
|
|
1576
|
-
<select class="slm-select" data-table-mode="${
|
|
1577
|
-
${d||m?"disabled":""} ${m?`title="Release the ${
|
|
1578
|
-
<option value="individual"${
|
|
1579
|
-
<option value="whole"${
|
|
1580
|
-
${
|
|
1574
|
+
<div class="slm-tablelist">${i.map(({table:h,current:b,locked:m})=>`<div class="slm-tablerow${m?" locked":""}">
|
|
1575
|
+
<span class="slm-tablecopy"><b>${g(h.displayLabel??h.label)}</b><small>${h.seatCount.toLocaleString()} chairs${m?` \xB7 <span class="slm-tablelock">Locked: ${g(m)}</span>`:""}</small></span>
|
|
1576
|
+
<select class="slm-select" data-table-mode="${g(h.id)}" aria-label="Booking mode for ${g(h.displayLabel??h.label)}"
|
|
1577
|
+
${d||m?"disabled":""} ${m?`title="Release the ${g(m)} chairs before changing how this table sells"`:""}>
|
|
1578
|
+
<option value="individual"${b==="individual"?" selected":""}>Per chair</option>
|
|
1579
|
+
<option value="whole"${b==="whole"?" selected":""}>Whole table</option>
|
|
1580
|
+
${b==="variable"?'<option value="variable" selected>Flexible group</option>':""}
|
|
1581
1581
|
</select>
|
|
1582
1582
|
</div>`).join("")}</div>
|
|
1583
|
-
<p class="slm-note">Changes apply immediately to this event. Flexible group sizes (minimum and maximum guests) are set through the API, never guessed here.</p>`,this.els.rail.querySelectorAll("[data-table-all]").forEach(h=>{h.addEventListener("click",()=>{this.setTableBooking(i.filter(
|
|
1583
|
+
<p class="slm-note">Changes apply immediately to this event. Flexible group sizes (minimum and maximum guests) are set through the API, never guessed here.</p>`,this.els.rail.querySelectorAll("[data-table-all]").forEach(h=>{h.addEventListener("click",()=>{this.setTableBooking(i.filter(b=>!b.locked).map(b=>b.table.id),h.dataset.tableAll)})}),this.els.rail.querySelectorAll("[data-table-mode]").forEach(h=>{h.addEventListener("change",()=>{this.setTableBooking([h.dataset.tableMode],h.value)})})}renderInspectRail(e){let t=e[e.length-1];if(!t){this.els.rail.innerHTML=`
|
|
1584
1584
|
${this.railHeader("Inspect","read","Click one seat on the map to read its live status, category, section and booking context. Nothing changes in this view.")}
|
|
1585
1585
|
<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)??k.UNGROUPED_ID,a=this.sectionLabelById.get(i)??"Other seats",l=this.doc?.categories.find(c=>c.key===t.categoryKey);this.els.rail.innerHTML=`
|
|
1586
|
-
<div class="slm-seat-heading"><h2>${
|
|
1587
|
-
<p class="slm-note">${
|
|
1586
|
+
<div class="slm-seat-heading"><h2>${g(t.label)}</h2><span data-seat-status>${n[s]}</span></div>
|
|
1587
|
+
<p class="slm-note">${g(a)} \xB7 ${g(l?.label??t.categoryKey)}</p>
|
|
1588
1588
|
<div data-ref="seat-history"></div>`;let r=this.els.rail.querySelector('[data-ref="seat-history"]');this.seatHistoryPanel=new de(r,(c,d)=>this.withAuthRetry(()=>this.api.seatHistory(this.key,t.label,c,d)))}async refreshAvailability(){try{let e=await this.withAuthRetry(()=>this.api.availability(this.key));this.availabilityRules=e.rules??{},this.effectiveClosed=new Set(Ze(this.availabilityRules)),this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment()}catch(e){this.opts.onError?.(e)}}async withAuthRetry(e){try{return await e()}catch(t){if(t instanceof S&&t.status===401&&this.opts.onTokenRefresh&&!this.tokenRefreshInFlight){if(await this.rotateToken(),this.sessionEnded)throw t;return e()}throw t instanceof S&&t.status===401&&!this.opts.onTokenRefresh&&this.endSession(),t}}updateEffectiveAvailability(e,t){let s=!1;Array.isArray(e)&&(this.effectiveHidden=new Set(e.filter(n=>typeof n=="string")),s=!0),Array.isArray(t)&&(this.effectiveClosed=new Set(t.filter(n=>typeof n=="string")),s=!0),s&&(this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment())}applySectionCanvasTreatment(){this.renderer&&(this.refreshBlockPaint(),this.mode==="sections"?(this.renderer.setDimmedSections([...this.effectiveHidden]),this.renderer.setClosedSections([...this.effectiveClosed])):this.mode==="filterSections"&&this.filteredSectionLabel?this.applyFilteredSectionCanvas():(this.renderer.setDimmedSections(null),this.renderer.setClosedSections(null)))}sectionRowsInput(){return{sectionsBase:this.sectionsBase,doc:this.doc,availabilityRules:this.availabilityRules,effectiveHidden:this.effectiveHidden,effectiveClosed:this.effectiveClosed}}renderSectionsRail(){let{rows:e,hiddenSections:t,closedSections:s}=Se(this.sectionRowsInput());if(!e.length){this.els.rail.innerHTML=`
|
|
1589
1589
|
${this.railHeader("Sections","event","Draw sections or zones in the designer to schedule availability per area. This chart has none yet.")}
|
|
1590
1590
|
<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=`
|
|
@@ -1592,13 +1592,13 @@
|
|
|
1592
1592
|
<div class="slm-availlist" data-ref="availlist">${e.map(l=>es(l,this.availabilitySaving)).join("")}</div>
|
|
1593
1593
|
<div class="slm-availsummary">
|
|
1594
1594
|
<span class="slm-availdot${a?" warn":""}"></span>
|
|
1595
|
-
<span>${
|
|
1595
|
+
<span>${g(i)}</span>
|
|
1596
1596
|
</div>
|
|
1597
1597
|
<div class="slm-availcallout">
|
|
1598
1598
|
<span class="slm-availstar" aria-hidden="true">\u2726</span>
|
|
1599
1599
|
<p><b>Auto-reveal at % sold</b> is demand-triggered release: the balcony opens itself the moment the stalls cross the threshold \u2014 no one has to be watching.</p>
|
|
1600
1600
|
</div>`,this.wireSectionRail(),this.applySectionCanvasTreatment()}wireSectionRail(){let e=this.els.rail;e&&(e.querySelectorAll("[data-avail-id]").forEach(t=>{t.addEventListener("click",()=>this.setSectionMode(t.dataset.availId,t.dataset.availValue))}),e.querySelectorAll("[data-avail-picker]").forEach(t=>{t.querySelector("summary").addEventListener("click",s=>{this.availabilitySaving&&s.preventDefault(),e.querySelectorAll("[data-avail-picker]").forEach(n=>{n!==t&&(n.open=!1)})}),t.addEventListener("focusout",s=>{t.contains(s.relatedTarget)||(t.open=!1)}),t.addEventListener("keydown",s=>{if(s.key==="Escape"&&(t.open=!1,t.querySelector("summary").focus(),s.preventDefault()),s.key==="ArrowDown"||s.key==="ArrowUp"){if(this.availabilitySaving)return;s.preventDefault(),t.open=!0;let n=[...t.querySelectorAll("button")],i=n.indexOf(document.activeElement);n[(i+(s.key==="ArrowDown"?1:n.length-1)+n.length)%n.length]?.focus()}})}),e.querySelectorAll("[data-avail-reveal]").forEach(t=>{t.addEventListener("change",()=>{let s=new Date(t.value).getTime();Number.isFinite(s)&&this.setSectionRulePatch(t.dataset.availReveal,{revealAt:s})})}),e.querySelectorAll("[data-avail-pct]").forEach(t=>{t.addEventListener("change",()=>{let s=Math.max(1,Math.min(100,Number(t.value)||0));this.setSectionRulePatch(t.dataset.availPct,{thresholdPct:s})})}))}setSectionMode(e,t){let s=Se(this.sectionRowsInput()).rows.find(l=>l.id===e),n=s?.seatLabels??this.availabilityRules[e]?.labels??[],i={...this.availabilityRules},a=St(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=Se(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(Ze(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=Tt.map(t=>`<div class="slm-legrow"><span class="slm-legdot" style="background:${t.color}"></span>
|
|
1601
|
-
<span class="slm-leglabel">${t.label}</span><span class="slm-legcount">${e[t.key].toLocaleString()}</span></div>`).join(""))}paintFeed(){this.activityPanel?.update(this.feed)}renderBlockRail(){let e=this.toolChooser(),t=this.sectionOptions.map(l=>`<option value="${
|
|
1601
|
+
<span class="slm-leglabel">${t.label}</span><span class="slm-legcount">${e[t.key].toLocaleString()}</span></div>`).join(""))}paintFeed(){this.activityPanel?.update(this.feed)}renderBlockRail(){let e=this.toolChooser(),t=this.sectionOptions.map(l=>`<option value="${g(l.id)}">${g(l.label)}</option>`).join("");this.els.rail.innerHTML=`
|
|
1602
1602
|
<div class="slm-monitor-tabs" role="tablist" aria-label="Blocking tools"><button role="tab" data-block-tab="edit" aria-selected="${!this.blockBrowse}">Block seats</button><button role="tab" data-block-tab="browse" aria-selected="${this.blockBrowse}">Find blocked</button></div>
|
|
1603
1603
|
<p class="slm-note">${Mt}</p>
|
|
1604
1604
|
<div data-block-editor ${this.blockBrowse?"hidden":""}>
|
|
@@ -1641,5 +1641,5 @@
|
|
|
1641
1641
|
<button class="slm-btn ghost" data-ref="markall" style="width:100%" disabled>Put all blocked seats on sale</button>
|
|
1642
1642
|
<p class="slm-note slm-allnote" data-ref="markallnote">For a full reset only. You will be asked to confirm.</p>
|
|
1643
1643
|
</div></details>
|
|
1644
|
-
`,this.els.rail.querySelectorAll("[data-block-tab]").forEach(l=>l.addEventListener("click",()=>{this.blockBrowse=l.dataset.blockTab==="browse",this.renderBlockRail()}));let s=l=>this.els.rail.querySelector(`[data-ref="${l}"]`);this.els.selnum=s("selnum"),this.els.doblock=s("doblock"),this.els.dounblock=s("dounblock"),this.els.selmeta=s("selmeta"),this.els.blockedcount=s("blockedcount"),this.els.blockedshowing=s("blockedshowing"),this.els.blockedlist=s("blockedlist"),this.els.selblocked=s("selblocked"),this.els.markall=s("markall"),this.els.markallnote=s("markallnote"),s("doblock").addEventListener("click",()=>{this.block()}),s("dounblock").addEventListener("click",()=>{this.unblock()}),s("selall").addEventListener("click",()=>this.selectAll()),s("clearsel").addEventListener("click",()=>this.clearSelection()),s("markall").addEventListener("click",()=>this.confirmUnblockAll()),e.wire(this.els.rail),this.wireMarqueeShapeChips();let n=s("blockedsearch"),i=s("blockedsection");n.value=this.blockedQuery,i.value=this.blockedSection,n.addEventListener("input",()=>{this.blockedQuery=n.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),i.addEventListener("change",()=>{this.blockedSection=i.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),s("selblocked").addEventListener("click",()=>{this.toggleLabels(this.filteredBlockedSeats().map(l=>l.label))}),s("blockedlist").addEventListener("click",l=>{let r=l.target,c=r.closest("[data-block-seat-find]");if(c?.dataset.blockSeatFind){let m=this.labelToSeat.get(c.dataset.blockSeatFind);m&&(this.setFollowLive(!1),this.focusActivitySeats([m.label],this.sectionByObject.get(m.rowId)??k.UNGROUPED_ID));return}let d=r.closest("[data-block-locate]"),h=r.closest("[data-block-group]");if(d||h){let m=d?.dataset.blockLocate??h?.dataset.blockGroup,p=this.filteredBlockedSeats().filter(v=>v.rowId===m);d&&p.length&&(this.setFollowLive(!1),this.focusActivitySeats(p.map(v=>v.label),this.sectionByObject.get(p[0].rowId)??k.UNGROUPED_ID)),h&&this.toggleLabels(p.map(v=>v.label));return}let
|
|
1645
|
-
<details><summary>Choose seats</summary>${
|
|
1644
|
+
`,this.els.rail.querySelectorAll("[data-block-tab]").forEach(l=>l.addEventListener("click",()=>{this.blockBrowse=l.dataset.blockTab==="browse",this.renderBlockRail()}));let s=l=>this.els.rail.querySelector(`[data-ref="${l}"]`);this.els.selnum=s("selnum"),this.els.doblock=s("doblock"),this.els.dounblock=s("dounblock"),this.els.selmeta=s("selmeta"),this.els.blockedcount=s("blockedcount"),this.els.blockedshowing=s("blockedshowing"),this.els.blockedlist=s("blockedlist"),this.els.selblocked=s("selblocked"),this.els.markall=s("markall"),this.els.markallnote=s("markallnote"),s("doblock").addEventListener("click",()=>{this.block()}),s("dounblock").addEventListener("click",()=>{this.unblock()}),s("selall").addEventListener("click",()=>this.selectAll()),s("clearsel").addEventListener("click",()=>this.clearSelection()),s("markall").addEventListener("click",()=>this.confirmUnblockAll()),e.wire(this.els.rail),this.wireMarqueeShapeChips();let n=s("blockedsearch"),i=s("blockedsection");n.value=this.blockedQuery,i.value=this.blockedSection,n.addEventListener("input",()=>{this.blockedQuery=n.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),i.addEventListener("change",()=>{this.blockedSection=i.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),s("selblocked").addEventListener("click",()=>{this.toggleLabels(this.filteredBlockedSeats().map(l=>l.label))}),s("blockedlist").addEventListener("click",l=>{let r=l.target,c=r.closest("[data-block-seat-find]");if(c?.dataset.blockSeatFind){let m=this.labelToSeat.get(c.dataset.blockSeatFind);m&&(this.setFollowLive(!1),this.focusActivitySeats([m.label],this.sectionByObject.get(m.rowId)??k.UNGROUPED_ID));return}let d=r.closest("[data-block-locate]"),h=r.closest("[data-block-group]");if(d||h){let m=d?.dataset.blockLocate??h?.dataset.blockGroup,p=this.filteredBlockedSeats().filter(v=>v.rowId===m);d&&p.length&&(this.setFollowLive(!1),this.focusActivitySeats(p.map(v=>v.label),this.sectionByObject.get(p[0].rowId)??k.UNGROUPED_ID)),h&&this.toggleLabels(p.map(v=>v.label));return}let b=r.closest("[data-blocked-label]");b?.dataset.blockedLabel?this.toggleLabels([b.dataset.blockedLabel]):r.closest("[data-blocked-more]")&&(this.blockedResultLimit+=100,this.paintBlockedInventory())});let a=s("release");a.addEventListener("change",()=>{let l=a.value?new Date(a.value).getTime():NaN;this.releaseAt=Number.isFinite(l)&&l>Date.now()?l:null;let r=s("releasenote");r.textContent=this.releaseAt?`New blocks auto-release ${new Date(this.releaseAt).toLocaleString()}.`:a.value?"Pick a time in the future.":"Leave empty to block permanently."}),this.paintSelBar(this.getSelection())}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){if(this.isHostUnavailable(e))return!1;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.paintBlockedInventory()}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)??k.UNGROUPED_ID;if(!(this.blockedSection&&i!==this.blockedSection)){if(e){let a=this.doc?.categories.find(h=>h.key===n.categoryKey)?.label??n.categoryKey,l=this.sectionLabelById.get(i)??"Other seats",r=this.doc?.objects.find(h=>h.id===n.rowId),c=r?.type==="row"||r?.type==="table"?r.label:"";if(!`${s} ${a} ${l} ${c}`.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(([,h])=>h==="blocked").length,t=this.filteredBlockedSeats(),s=t.slice(0,this.blockedResultLimit),n=new Set(this.selectionLabels()),i=t.filter(h=>n.has(h.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`;let r=new Map;for(let h of t){let b=r.get(h.rowId)??[];b.push(h),r.set(h.rowId,b)}this.els.blockedshowing.textContent=`${t.length.toLocaleString()} seats \xB7 ${r.size} rows`,this.els.blockedlist.innerHTML=[...r.entries()].slice(0,this.blockedResultLimit).map(([h,b])=>{let m=this.sectionByObject.get(h)??k.UNGROUPED_ID,p=this.sectionLabelById.get(m)??"Other seats",v=this.doc?.objects.find(f=>f.id===h),y=v&&"label"in v?v.label:b[0].label;return`<div class="slm-block-group"><div class="slm-block-grouphead"><button type="button" data-block-locate="${g(h)}" title="Show this row and nearby seats on the map"><b>${g(y)}</b><small>${g(p)} \xB7 ${b.length} blocked</small></button><button type="button" data-block-group="${g(h)}">Select row</button></div>
|
|
1645
|
+
<details><summary>Choose seats</summary>${b.map(f=>`<div class="slm-block-seatline"><button type="button" class="slm-blockeditem${n.has(f.label)?" on":""}" data-blocked-label="${g(f.label)}" aria-pressed="${n.has(f.label)}"><span class="slm-blockedcheck" aria-hidden="true">\u2713</span><span>${g(f.label)}</span></button><button type="button" data-block-seat-find="${g(f.label)}" aria-label="Show ${g(f.label)} and nearby seats">Show</button></div>`).join("")}</details></div>`}).join("")||'<div class="slm-blockedempty">No blocked seats match.</div>',r.size>this.blockedResultLimit&&(this.els.blockedlist.innerHTML+="<button data-blocked-more>Show more rows</button>");let c=this.els.markall,d=c.dataset.confirm==="true";c.disabled=e===0,c.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>`)}};st();ze();ue();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});
|