@seatlayer/js 0.94.0 → 0.95.1
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/README.md +9 -0
- package/dist/{channelsMode-DYwJ6sfR.d.cts → channelsMode-BOkMjgGL.d.cts} +98 -3
- package/dist/{channelsMode-DYwJ6sfR.d.ts → channelsMode-BOkMjgGL.d.ts} +98 -3
- package/dist/index.cjs +18 -18
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +17 -17
- package/dist/manager.cjs +114 -88
- package/dist/manager.d.cts +2 -2
- package/dist/manager.d.ts +2 -2
- package/dist/manager.js +87 -61
- package/package.json +2 -2
package/dist/manager.cjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
"use strict";var _e=Object.defineProperty;var ys=Object.getOwnPropertyDescriptor;var xs=Object.getOwnPropertyNames;var ks=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 it=(o,e)=>{for(var t in e)_e(o,t,{get:e[t],enumerable:!0})},ws=(o,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of xs(e))!ks.call(o,n)&&n!==t&&_e(o,n,{get:()=>e[n],enumerable:!(s=ys(e,n))||s.enumerable});return o};var Ss=o=>ws(_e({},"__esModule",{value:!0}),o);function W(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 at(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 re=z(()=>{"use strict"});async function rt(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 w(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 me(o,e,t=0){return typeof o=="number"&&Number.isFinite(o)?o:typeof e=="number"&&Number.isFinite(e)?e:t}function ct(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 dt(o){let e=A(o),t=me(e.bookedValue,e.bookedRevenue);return{...e,bookedValue:t,bookedRevenue:t}}function Cs(o){let e=A(o),t=A(e.report),s=Array.isArray(t.byCategory)?t.byCategory.map(i=>{let a=A(i),l=me(a.bookedValue,a.bookedRevenue);return{...a,bookedValue:l,bookedRevenue:l}}):[],n=Array.isArray(t.bySection)?t.bySection.map(dt):void 0;return{...e,report:{...t,byCategory:s,...n?{bySection:n}:{}}}}function Ts(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:me(t.gross,s.gross),bySection:i.map(dt)},l=A(e.velocity),r=Array.isArray(l.bySection)?l.bySection.map(c=>{let d=A(c),h=me(d.bookedValue,d.grossRevenue);return{...d,bookedValue:h,grossRevenue:h}}):[];return{...e,bookedValue:a,revenue:a,velocity:{...l,bySection:r}}}function Ms(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=ct(c.bookedValue,c.revenue);return{...r,attribution:{...c,bookedValue:d,revenue:d}}}):[],i=A(t.totals),a=ct(i.bookedValue,i.revenue);return{...e,report:{...t,includesBookedValue:s,includesRevenue:s,rows:n,totals:{...i,bookedValue:a,revenue:a}}}}function Ne(o){let e=A(o),t=typeof e.includesBookedValue=="boolean"?e.includesBookedValue:e.includesRevenue===!0;return{...e,includesBookedValue:t,includesRevenue:t}}var w,Y,pe=z(()=>{"use strict";w=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}};Y=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=>rt(a))}async authBlob(e){let t=await fetch(`${this.base}${e}`,{method:"GET",headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});return t.ok||await rt(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 w(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(Cs)}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(Ts)}channelReport(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/report`).then(Ms)}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:Ne(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(Ne):[]}})}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:Ne(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 w(t.status,`request_failed_${t.status}`);return t.blob()}}});function Is(){try{return window.matchMedia?.("(prefers-color-scheme: dark)").matches===!0}catch{return!1}}function Ue(o){if(o)return o==="auto"?Is()?"dark":"light":o}function vt(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 ft,je,Ke=z(()=>{"use strict";ft=require("@seatlayer/core/core/color"),je={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 xt(o){return o?o.mode:"open"}function kt(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 wt(o){return new Date(o-new Date().getTimezoneOffset()*6e4).toISOString().slice(0,16)}function St(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 We(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 ge(o){return o==="blocked"?"not_for_sale":o}function Tt(o,e){let t=o??{},s=e?je[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 Mt(o){return o?je[o].map:null}function Et(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 fe(o,e){return(0,yt.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 yt,Hs,H,be,Lt,Ct,ve=z(()=>{"use strict";yt=require("@seatlayer/core");Ke();Hs=["free","booked","held","blocked"],H={free:"#6e7bff",booked:"#9ca3af",held:"#f4b740",blocked:"#475569"},be={free:"Free",booked:"Sold",held:"Held",blocked:"Blocked"},Lt=[`<span class="slm-legmark" style="background:${H.free}"></span> Free = category colour`,`<span class="slm-legmark" style="background:${H.booked}"></span> ${be.booked}`,`<span class="slm-legmark" style="background:${H.held}"></span> ${be.held}`,`<span class="slm-legcross" style="color:${H.blocked}">\u2715</span> ${be.blocked}`].join(" \xB7 "),Ct=Hs.map(o=>({key:o,label:be[o],color:H[o]}))});function Bs(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 xe(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 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`
|
|
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
|
-
</div>`}function
|
|
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
7
|
<span class="slm-sellabel">${b(o.noun??"selected")}</span>
|
|
8
8
|
${o.breakdown??""}${e}
|
|
9
|
-
</div>`}var
|
|
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?
|
|
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,f=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
15
|
data-ch-category="${b(c.key)}"${h?" disabled":""}>
|
|
16
16
|
<span class="box" aria-hidden="true">\u2713</span>
|
|
17
17
|
<span class="dot" style="background:${b(c.color??"#6e7bff")}" aria-hidden="true"></span>
|
|
@@ -38,20 +38,20 @@
|
|
|
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]"),g=p.querySelector("[data-ch-error]"),C=p.querySelector("[data-ch-scope-list]"),
|
|
42
|
-
<button type="button" class="slm-ch-groupcheck" role="checkbox" aria-checked="${
|
|
43
|
-
aria-label="Select all ${$.length.toLocaleString()} rows in ${b(B)}" data-ch-scope-group="${
|
|
41
|
+
</div>`,p=>{let v=new Set,y=p.querySelector("[data-ch-add-scope]"),g=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,g);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
|
+
<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 ${b(B)}" data-ch-scope-group="${te}">
|
|
44
44
|
<span class="box" aria-hidden="true">\u2713</span><span>${b(B)}</span>
|
|
45
|
-
<span class="meta">${$.length.toLocaleString()} rows \xB7 ${
|
|
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="${
|
|
48
|
-
data-ch-scope-toggle="${
|
|
49
|
-
</div>`),I.push(...
|
|
47
|
+
<button type="button" class="slm-ch-grouptoggle" aria-expanded="${se}" aria-label="${se?"Hide":"Show"} rows in ${b(B)}"
|
|
48
|
+
data-ch-scope-toggle="${te}">${se?"Hide":"Show"}</button>
|
|
49
|
+
</div>`),I.push(...ne.map(D=>`<button type="button" class="slm-ch-seatitem" role="checkbox"
|
|
50
50
|
aria-checked="${l.has(D.id)}" data-ch-scope-id="${b(D.id)}">
|
|
51
51
|
<span class="box" aria-hidden="true">\u2713</span><span>${b(D.label)}</span>
|
|
52
52
|
<span class="meta">${D.labels.length.toLocaleString()} seat${D.labels.length===1?"":"s"}</span>
|
|
53
|
-
</button>`)),
|
|
54
|
-
Use Drag box or the seat list instead.</div>`),
|
|
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${b(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 f=[...i.entries()].map(([m,p])=>`
|
|
55
55
|
<div class="slm-ch-seatgroup"><span>${b(m)}</span></div>
|
|
56
56
|
${p.map(v=>`<button type="button" class="slm-ch-seatitem" role="checkbox"
|
|
57
57
|
aria-checked="false" data-ch-scope-id="${b(v.id)}">
|
|
@@ -67,23 +67,23 @@
|
|
|
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 g=y.dataset.chScopeId;l.has(g)?l.delete(g):l.add(g),y.setAttribute("aria-checked",String(l.has(g))),d(p,v)})}),p.addEventListener("click",h),d(p,v)})}openSeatList(e=""){let t=new Set(this.host.selectionLabels()),s=e.trim().toLocaleLowerCase(),n=g=>!s||g.toLocaleLowerCase().includes(s),i=this.rows(),a=new Map;for(let g of i)for(let C of g.labels)a.set(C,g);let l=new Map,r=new Map,c=0,d=0;for(let g of this.host.seats()){if(!n(g.label)||(c+=1,c>this.seatListLimit))continue;d+=1;let C=this.host.sectionOfLabel(g.label),
|
|
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 g=y.dataset.chScopeId;l.has(g)?l.delete(g):l.add(g),y.setAttribute("aria-checked",String(l.has(g))),d(p,v)})}),p.addEventListener("click",h),d(p,v)})}openSeatList(e=""){let t=new Set(this.host.selectionLabels()),s=e.trim().toLocaleLowerCase(),n=g=>!s||g.toLocaleLowerCase().includes(s),i=this.rows(),a=new Map;for(let g of i)for(let C of g.labels)a.set(C,g);let l=new Map,r=new Map,c=0,d=0;for(let g of this.host.seats()){if(!n(g.label)||(c+=1,c>this.seatListLimit))continue;d+=1;let C=this.host.sectionOfLabel(g.label),w=C?.id??"",L=l.get(w)??{label:C?.label??"Other seats",lines:[],loose:[]};l.set(w,L);let T=a.get(g.label);if(!T){L.loose.push(g.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(g.label)}let h=g=>this.host.seatMeta?.(g)??this.host.statusOf(g)??"free",f=(g,C)=>{let w=this.host.statusOf(g)??"free",L=C&&g.startsWith(`${C}-`)?g.slice(C.length+1):g;return`<button type="button" class="slm-ch-seatchip is-${b(w)}" role="checkbox"
|
|
71
71
|
aria-checked="${t.has(g)}" aria-label="${b(g)} \xB7 ${b(h(g))}" title="${b(g)} \xB7 ${b(h(g))}"
|
|
72
|
-
data-ch-seat="${b(g)}">${b(L)}</button>`},m=g=>{let C=g.seats.filter(
|
|
72
|
+
data-ch-seat="${b(g)}">${b(L)}</button>`},m=g=>{let C=g.seats.filter(w=>t.has(w)).length;return C===0?"false":C===g.seats.length?"true":"mixed"},p=[...l.entries()].map(([g,C])=>`
|
|
73
73
|
<div class="slm-ch-seatgroup">
|
|
74
74
|
<span>${b(C.label)}</span>
|
|
75
75
|
${g?`<button type="button" data-ch-section="${b(g)}">Select section</button>`:""}
|
|
76
76
|
</div>
|
|
77
|
-
${C.lines.map(
|
|
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(
|
|
80
|
-
aria-label="Row ${b(
|
|
81
|
-
<span class="box" aria-hidden="true">\u2713</span><span class="name">${b(
|
|
82
|
-
<span class="meta">${
|
|
79
|
+
<button type="button" class="slm-ch-rowcheck" role="checkbox" aria-checked="${m(w)}" data-ch-row="${b(w.id)}"
|
|
80
|
+
aria-label="Row ${b(w.label)} \xB7 ${w.seats.length} seats">
|
|
81
|
+
<span class="box" aria-hidden="true">\u2713</span><span class="name">${b(w.label)}</span>
|
|
82
|
+
<span class="meta">${w.seats.length.toLocaleString()}</span>
|
|
83
83
|
</button>
|
|
84
|
-
<div class="slm-ch-seatchips">${
|
|
84
|
+
<div class="slm-ch-seatchips">${w.seats.map(L=>f(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(
|
|
86
|
+
${C.loose.length?`<div class="slm-ch-seatrow loose"><div class="slm-ch-seatchips">${C.loose.map(w=>f(w,null)).join("")}</div></div>`:""}`).join(""),v=s?`<div class="slm-empty">Nothing matches \u201C${b(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">
|
|
@@ -93,24 +93,24 @@
|
|
|
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>
|
|
95
95
|
<div class="slm-ch-seatlist grid">${d?p:v}</div>
|
|
96
|
-
${c>this.seatListLimit?`<div class="foot"><button type="button" class="slm-btn ghost" data-ch-more>Show ${Math.min(
|
|
96
|
+
${c>this.seatListLimit?`<div class="foot"><button type="button" class="slm-btn ghost" data-ch-more>Show ${Math.min(xe,c-this.seatListLimit).toLocaleString()} more seats</button></div>`:""}
|
|
97
97
|
<div class="foot slm-ch-seatfoot">
|
|
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>`,g=>{let C=L=>{this.host.clearSelection(),L.size&&this.host.selectByLabels([...L]),this.openSeatList(e)};g.querySelectorAll("[data-ch-seat]").forEach(L=>{L.addEventListener("click",()=>{let
|
|
101
|
+
</div>`,g=>{let C=L=>{this.host.clearSelection(),L.size&&this.host.selectByLabels([...L]),this.openSeatList(e)};g.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)})}),g.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)})}),g.querySelectorAll("[data-ch-section]").forEach(L=>{L.addEventListener("click",()=>{this.host.selectSection(L.dataset.chSection),this.openSeatList(e)})}),g.querySelector("[data-ch-clear-all]")?.addEventListener("click",()=>C(new Set)),g.querySelector("[data-ch-more]")?.addEventListener("click",()=>{this.seatListLimit+=xe,this.openSeatList(e)});let w=g.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=[],f=[];for(let p of e){if(a.has(p))continue;a.add(p);let v=s(p);if(!v){f.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(f)}}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]+/,""))}
|
|
105
105
|
${e.why?`<span class="why">\u2014 ${u(e.why)}</span>`:""}</span>
|
|
106
106
|
${e.peek?`<span class="peek">${u(e.peek)}</span>`:"<span></span>"}
|
|
107
|
-
</div>`).join("")}function u(o){return String(o??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function
|
|
107
|
+
</div>`).join("")}function u(o){return String(o??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function os(o){return new Date(o-new Date(o).getTimezoneOffset()*6e4).toISOString().slice(0,16)}function tt(o,e){let t=o.querySelector(e)?.value.trim()??"",s=Number(t);return t!==""&&Number.isInteger(s)?s:null}function ls(o,e){let t=typeof navigator>"u"?null:navigator.clipboard;return t?.writeText?t.writeText(e).then(()=>!0,()=>is(o,e)):Promise.resolve(is(o,e))}function is(o,e){let t=o.querySelector("[data-ch-lk-sink]");if(t&&typeof document.execCommand=="function")try{t.value=e,t.select(),t.setSelectionRange(0,e.length);let s=document.execCommand("copy");if(t.value="",s)return!0}catch{t.value=""}return Qs(o),!1}function Qs(o){let e=o.querySelector("[data-ch-lk-url]");if(e)try{let t=document.createRange();t.selectNodeContents(e);let s=window.getSelection();s?.removeAllRanges(),s?.addRange(t)}catch{}}var as,Fe=z(()=>{"use strict";as=`
|
|
108
108
|
<p class="slm-eyebrow" style="margin-top:18px">On your website</p>
|
|
109
109
|
<p class="slm-hint">There is nothing more to set up on this screen. Your own server mints a short-lived buyer
|
|
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
|
|
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,f=o.view==="preview"?o.previewProjection:null,m=f?new Set(f.available===!1?[]:f.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 g of o.host.seats()){let C=o.host.statusOf(g.label)??"free",w=o.allocation.get(g.label)??R;if(w!==R){let E=p.get(w)??{x:0,y:0,n:0};E.x+=g.x,E.y+=g.y,E.n+=1,p.set(w,E)}if(!c){let E=o.host.sectionOfLabel(g.label),M=E?o.host.worldToScreen({x:g.x,y:g.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(g.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:g.x,y:g.y});if(x&&!(x.x<-d||x.y<-d||x.x>n+d||x.y>i+d)){if(y){let E=o.host.sectionOfLabel(g.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(g.label)&&d>=22&&on(l,g.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);
|
|
@@ -362,11 +362,11 @@
|
|
|
362
362
|
.slm-ch-staged.shake{outline:2px solid #e5484d;outline-offset:2px}
|
|
363
363
|
.slm-ch-staged.done{outline:2px solid #5bd39b;outline-offset:2px}
|
|
364
364
|
}
|
|
365
|
-
`});var
|
|
365
|
+
`});var us={};ot(us,{CHANNELS_CSS:()=>ms,ChannelsMode:()=>re,bucketRowsHtml:()=>ee});var mn,_,re,st=z(()=>{"use strict";ce();Ge();ze();ue();hs();Fe();ps();Fe();mn=3e4,_=5e3,re=class{constructor(e,t){this.active=!1;this.list=null;this.allocation=new Map;this.assignmentVersion=0;this.loadError=null;this.loading=!0;this.view="inspect";this.mapIntent="pan";this.focusedSectionId=null;this.showArchived=!1;this.detailChannelId=null;this.assignOpen=!1;this.targetChannelId="";this.conflict=!1;this.dialog=null;this.detent="medium";this.links=[];this.linksChannelId=null;this.linksState="idle";this.listSeq=0;this.linksSeq=0;this.previewAudience=[];this.previewIncludePublic=!1;this.previewProjection=null;this.previewState="idle";this.pollTimer=null;this.layer=null;this.canvas=null;this.overlayVisible=!0;this.ctx=void 0;this.bannerEl=null;this.stagedEl=null;this.liveEl=null;this.scrimEl=null;this.lastFocus=null;this.stagedDoneTimer=null;this.lastSelectionCount=0;this.lastCounts=new Map;this.railHtml=null;this.allocationVersion=null;this.onVisibility=null;this.host=e,this.caps=t;let s={selectionLabels:()=>e.selectionLabels(),selectByLabels:n=>e.selectByLabels(n),clearSelection:()=>e.clearSelection(),selectSection:n=>e.selectSection(n),sections:()=>e.sections(),labelsInSection:n=>e.labelsInSection(n),rows:()=>e.rows(),categories:()=>e.categories(),labelsInCategory:n=>e.labelsInCategory(n),seats:()=>e.seats(),statusOf:n=>e.statusOf(n),sectionOfLabel:n=>e.sectionOfLabel(n),seatMeta:n=>{let i=this.allocation.get(n)??R;return`${this.nameOf(i)??P} \xB7 ${e.statusOf(n)??"free"}`},openDialog:(n,i)=>this.renderScrim(n,i),closeDialog:()=>this.closeDialog(),cap:_};this.chooser=new N(s)}enter(){this.active||(this.active=!0,this.mapIntent="pan",this.assignOpen=!1,this.focusedSectionId=null,this.chooser.reset(),this.railHtml=null,this.ensureLayer(),this.host.root.classList.add("ch-mode"),this.applySheetClasses(),this.host.sections().length>1&&this.host.showSectionOverview(),this.paintRail(),this.onInteractionChange?.(),this.refresh(),this.pollTimer=setInterval(()=>{typeof document<"u"&&document.hidden||this.refresh({quiet:!0})},mn),typeof document<"u"&&typeof document.addEventListener=="function"&&(this.onVisibility=()=>{this.active&&!document.hidden&&this.refresh({quiet:!0})},document.addEventListener("visibilitychange",this.onVisibility)))}leave(){this.active&&(this.active=!1,this.pollTimer&&clearInterval(this.pollTimer),this.pollTimer=null,this.onVisibility&&typeof document<"u"&&document.removeEventListener("visibilitychange",this.onVisibility),this.onVisibility=null,this.railHtml=null,this.closeDialog({restoreFocus:!1}),this.links=[],this.linksChannelId=null,this.linksState="idle",this.layer?.classList.remove("on"),this.host.root.classList.remove("ch-mode","ch-preview","ch-sheet","detent-collapsed","detent-medium","detent-full"),this.setBanner(!1),this.setStaged(null))}destroy(){this.leave(),this.stagedDoneTimer&&clearTimeout(this.stagedDoneTimer),this.layer?.remove(),this.layer=null,this.bannerEl?.remove(),this.bannerEl=null}setCapabilities(e){this.caps=e,this.active&&this.paintRail()}isActive(){return this.active}canSelect(){return this.caps.manage&&this.view==="inspect"}usesMarqueeSelection(){return this.canSelect()&&this.mapIntent==="assign"}handleSectionFocus(e){this.active&&(this.focusedSectionId=e,this.paintRail())}applyRealtimeHint(){this.active&&this.refresh({quiet:!0})}handleSelectionChange(){this.active&&(this.paintSelection(),this.paintStagedBar())}handleViewChange(){this.active&&this.paintOverlay()}handleLayoutChange(){this.active&&(this.applySheetClasses(),this.paintOverlay())}async refresh(e={}){if(!this.caps.view)return;let t=++this.listSeq,s=()=>t!==this.listSeq;try{let n=await this.host.api.channels(this.host.eventKey,{includeArchived:this.showArchived});if(s())return;if(this.list=n,this.assignmentVersion=n.assignmentVersion,this.loadError=null,this.targetChannelId||(this.targetChannelId=n.channels.find(i=>i.state==="active")?.id??R),this.allocationVersion!==n.assignmentVersion){if(await this.loadAllocation(t),s())return;this.allocationVersion=n.assignmentVersion}if(this.detailChannelId&&await this.loadLinks(this.detailChannelId),s())return;this.loading=!1,this.active&&(this.paintRail(),this.paintOverlay())}catch(n){if(s())return;this.loading=!1,n instanceof S&&n.status===403&&(this.caps={view:!1,manage:!1}),this.loadError=n,e.quiet||this.host.onError(n),this.active&&this.paintRail()}}async loadAllocation(e){let t=new Map,s;for(let n=0;n<200;n+=1){if(e!==void 0&&e!==this.listSeq)return;let i=await this.host.api.channelAllocation(this.host.eventKey,{afterLabel:s,limit:1e3});for(let a of i.allocations)O(a.channelId)||t.set(a.label,a.channelId);if(this.assignmentVersion=i.assignmentVersion,!i.nextAfterLabel)break;s=i.nextAfterLabel}e!==void 0&&e!==this.listSeq||(this.allocation=t)}channelById(e){if(O(e))return{id:R,name:this.list?.publicSale?.name??P,marker:"P",color:null};let t=this.list?.channels.find(s=>s.id===e);return t?{id:e,name:t.name,marker:t.marker,color:t.color}:null}nameOf(e){return this.channelById(e)?.name??null}channelNameForLabel(e){return this.list?this.nameOf(this.allocation.get(e)??R):null}markerFor(e){let t=Math.max(0,this.list?.channels.findIndex(n=>n.id===e)??0),s=this.channelById(e);return Te(s??{id:e,name:"?",marker:null,color:null},t)}assignableChannels(){return[{id:R,name:this.list?.publicSale.name??P},...(this.list?.channels??[]).filter(e=>e.state!=="archived").map(e=>({id:e.id,name:e.name}))]}currentPlan(){let e=this.host.selectionLabels(),t=Re({labels:e,targetChannelId:this.targetChannelId,allocation:this.allocation,statusOf:s=>this.host.statusOf(s),nameOf:s=>this.nameOf(s)});return{labels:e,buckets:t,target:this.targetChannelId}}ensureLayer(){if(this.layer)return;let e=document.createElement("div");e.className="slm-ch-layer",e.innerHTML=`
|
|
366
366
|
<canvas class="slm-ch-canvas" data-ch="canvas" aria-hidden="true"></canvas>
|
|
367
367
|
<div class="slm-ch-banner" data-ch="banner" role="status"></div>
|
|
368
368
|
<div class="slm-ch-staged" data-ch="staged" role="group" aria-label="Staged channel changes"></div>
|
|
369
|
-
<div class="slm-ch-live" data-ch="live" role="status" aria-live="polite"></div>`,this.host.mapLayer.appendChild(e),this.layer=e,this.canvas=e.querySelector('[data-ch="canvas"]'),this.bannerEl=e.querySelector('[data-ch="banner"]'),this.bannerEl&&this.host.pillLane&&this.host.pillLane.appendChild(this.bannerEl),this.stagedEl=e.querySelector('[data-ch="staged"]'),this.liveEl=e.querySelector('[data-ch="live"]'),requestAnimationFrame(()=>e.classList.add("on"))}announce(e){this.liveEl&&(this.liveEl.textContent=e)}setOverlayVisible(e){if(this.overlayVisible===e)return;if(this.overlayVisible=e,e){this.active&&this.paintOverlay();return}let t=this.canvas;t&&(this.ctx??null)?.clearRect(0,0,t.width,t.height),this.layer?.querySelectorAll(".slm-ch-flag").forEach(s=>s.remove())}paintOverlay(){let e=this.canvas,t=this.layer;!e||!t||!this.overlayVisible||
|
|
369
|
+
<div class="slm-ch-live" data-ch="live" role="status" aria-live="polite"></div>`,this.host.mapLayer.appendChild(e),this.layer=e,this.canvas=e.querySelector('[data-ch="canvas"]'),this.bannerEl=e.querySelector('[data-ch="banner"]'),this.bannerEl&&this.host.pillLane&&this.host.pillLane.appendChild(this.bannerEl),this.stagedEl=e.querySelector('[data-ch="staged"]'),this.liveEl=e.querySelector('[data-ch="live"]'),requestAnimationFrame(()=>e.classList.add("on"))}announce(e){this.liveEl&&(this.liveEl.textContent=e)}setOverlayVisible(e){if(this.overlayVisible===e)return;if(this.overlayVisible=e,e){this.active&&this.paintOverlay();return}let t=this.canvas;t&&(this.ctx??null)?.clearRect(0,0,t.width,t.height),this.layer?.querySelectorAll(".slm-ch-flag").forEach(s=>s.remove())}paintOverlay(){let e=this.canvas,t=this.layer;!e||!t||!this.overlayVisible||ds({layer:t,canvas:e,resolveCtx:()=>{if(this.ctx===void 0)try{this.ctx=e.getContext("2d")}catch{this.ctx=null}return this.ctx},host:this.host,view:this.view,previewProjection:this.previewProjection,allocation:this.allocation,focusedSectionId:this.focusedSectionId,list:this.list,markerFor:s=>this.markerFor(s),onSectionTargetClick:s=>{this.focusedSectionId=s,this.host.focusSection(s),this.paintRail()}})}setStaged(e,t=""){let s=this.stagedEl;if(s){if(!e){s.classList.remove("on","done","shake"),s.innerHTML="";return}s.innerHTML=e,s.className=`slm-ch-staged on${t?` ${t}`:""}`}}paintStagedBar(){if(!this.active||this.view==="preview"||!this.caps.manage){this.setStaged(null);return}let{labels:e,buckets:t}=this.currentPlan();if(this.host.onStagedChange?.(Q(t)),!e.length){this.setStaged(null);return}let s=this.nameOf(this.targetChannelId)??P,n=Q(t),i=e.length>_,a=t.skippedHeld.count+t.skippedBooked.count,l=[`<b>${e.length.toLocaleString()}</b> selected`,`<b>+${n.toLocaleString()}</b> to ${u(s)}`];t.alreadyInTarget.count&&l.push(`<b>${t.alreadyInTarget.count.toLocaleString()}</b> already in`),a&&l.push(`<b>${a.toLocaleString()}</b> can't move now`),this.setStaged(`
|
|
370
370
|
<span>${l.join(" \xB7 ")}</span>
|
|
371
371
|
<span class="grow"></span>
|
|
372
372
|
<button type="button" class="drop" data-ch-act="discard">Discard</button>
|
|
@@ -374,7 +374,7 @@
|
|
|
374
374
|
${i?`Maximum ${_.toLocaleString()} seats`:"Review changes"}
|
|
375
375
|
</button>`),this.stagedEl?.querySelectorAll("[data-ch-act]").forEach(r=>{r.addEventListener("click",()=>{r.dataset.chAct==="discard"?this.host.clearSelection():this.openDialog({kind:"review"})})})}setBanner(e,t="",s){let n=this.bannerEl;if(!n)return;if(this.host.root.classList.toggle("ch-preview",e),!e){n.classList.remove("on"),n.innerHTML="";return}let i=this.previewAudience.length===1?this.markerFor(this.previewAudience[0]):{color:"var(--slm-accent)",letter:""},a=s==null?"":` \xB7 ${s.toLocaleString()} ${s===1?"seat":"seats"} available now`;n.innerHTML=`<span class="dot" style="background:${u(i.color)}"></span>
|
|
376
376
|
Previewing buyer access \xB7 ${u(t)}${a} \xB7 read-only
|
|
377
|
-
<button type="button" data-ch-act="exit-preview">Exit preview</button>`,n.classList.add("on"),n.querySelector('[data-ch-act="exit-preview"]')?.addEventListener("click",()=>this.setView("inspect"))}setView(e){if(this.view=e,e==="inspect")this.previewProjection=null,this.previewState="idle",this.setBanner(!1);else{if(!this.previewAudience.length){let t=this.list?.channels.find(s=>s.state==="active");this.previewAudience=[t?t.id:R]}this.loadPreview()}this.paintRail(),this.paintOverlay(),this.paintStagedBar(),this.onInteractionChange?.()}async loadPreview(){let e=[...this.previewAudience],t=e.map(s=>this.nameOf(s)??P).join(" + ");this.setBanner(!0,t),this.previewProjection=null,this.previewState="loading",this.active&&this.paintRail();try{this.previewProjection=await this.host.api.channelPreview(this.host.eventKey,e,{includePublic:this.previewIncludePublic||e.some(O)}),this.previewState="ready";let s=this.previewProjection.available===!1?void 0:this.previewProjection.counts?.eligible??this.previewProjection.eligible?.length;this.setBanner(!0,t,s)}catch(s){let n=s instanceof
|
|
377
|
+
<button type="button" data-ch-act="exit-preview">Exit preview</button>`,n.classList.add("on"),n.querySelector('[data-ch-act="exit-preview"]')?.addEventListener("click",()=>this.setView("inspect"))}setView(e){if(this.view=e,e==="inspect")this.previewProjection=null,this.previewState="idle",this.setBanner(!1);else{if(!this.previewAudience.length){let t=this.list?.channels.find(s=>s.state==="active");this.previewAudience=[t?t.id:R]}this.loadPreview()}this.paintRail(),this.paintOverlay(),this.paintStagedBar(),this.onInteractionChange?.()}async loadPreview(){let e=[...this.previewAudience],t=e.map(s=>this.nameOf(s)??P).join(" + ");this.setBanner(!0,t),this.previewProjection=null,this.previewState="loading",this.active&&this.paintRail();try{this.previewProjection=await this.host.api.channelPreview(this.host.eventKey,e,{includePublic:this.previewIncludePublic||e.some(O)}),this.previewState="ready";let s=this.previewProjection.available===!1?void 0:this.previewProjection.counts?.eligible??this.previewProjection.eligible?.length;this.setBanner(!0,t,s)}catch(s){let n=s instanceof S?s.status:0;this.previewState=n===404||n===405||n===501?"unsupported":"error",this.previewProjection=null,this.previewState==="error"&&this.host.onError(s)}this.active&&(this.paintRail(),this.paintOverlay())}setRailHtml(e){if(e===this.railHtml)return!1;let t=this.host.rail,s=t.scrollTop;return t.innerHTML=e,this.railHtml=e,s&&(t.scrollTop=s),!0}paintRail(){if(!this.active)return;let e=this.host.rail;if(!this.caps.view){this.setRailHtml(`<p class="slm-eyebrow">Sales channels</p>
|
|
378
378
|
<p class="slm-hint">You need channel-management permission on this event to see allocations.</p>`);return}if(this.loading&&!this.list){this.setRailHtml(`<p class="slm-eyebrow">Sales channels</p>
|
|
379
379
|
<div class="slm-ch-busy" role="status" data-ch-state="list-loading">Loading channels and allocations\u2026</div>`);return}if(!this.list&&this.loadError){this.setRailHtml(`<p class="slm-eyebrow">Sales channels</p>
|
|
380
380
|
<div class="slm-ch-alert err" role="alert" data-ch-state="list-error"><span>\u26A0</span>
|
|
@@ -397,11 +397,11 @@
|
|
|
397
397
|
<span class="slm-ch-head">
|
|
398
398
|
<span class="slm-ch-mk${i}" style="background:${u(s.color)}" aria-hidden="true">${u(s.letter)}</span>
|
|
399
399
|
<span class="slm-ch-name">${u(e.name)}</span>
|
|
400
|
-
<span class="slm-ch-badge ${n}">${u(
|
|
400
|
+
<span class="slm-ch-badge ${n}">${u(Oe(t.builtin?"builtin":e.state))}</span>
|
|
401
401
|
${r}
|
|
402
402
|
</span>
|
|
403
403
|
${this.countsHtml(e.counts,e.id||"public")}
|
|
404
|
-
${t.builtin?"":`<span class="slm-ch-access">${u(
|
|
404
|
+
${t.builtin?"":`<span class="slm-ch-access">${u(He(e.access))}</span>`}
|
|
405
405
|
</div>`}listRailHtml(){let e=this.list,t=e.channels.filter(r=>r.state==="archived").length,s=e.channels.filter(r=>this.showArchived||r.state!=="archived"),n=[this.channelRowHtml(e.publicSale,{builtin:!0}),...s.map((r,c)=>this.channelRowHtml(r,{index:c}))].join(""),i=s.length?"":`<p class="slm-note" data-ch-state="list-empty">${t&&!this.showArchived?`No open channels \u2014 every seat is on public sale. ${t.toLocaleString()} archived channel${t===1?" is":"s are"} hidden below.`:"No private channels yet \u2014 every seat is on public sale."}</p>`,a=this.caps.manage?'<button type="button" class="slm-btn slm-ch-new" data-ch-act="create">+ New channel</button>':"",l=this.caps.manage?"":'<p class="slm-note">You can see how inventory is allocated. Changing it needs channel-management permission.</p>';return`
|
|
406
406
|
<div class="slm-ch-listhead"><h2>Sales channels</h2>${a}</div>
|
|
407
407
|
<div class="slm-ch-list">${n}</div>
|
|
@@ -423,7 +423,7 @@
|
|
|
423
423
|
<p class="slm-eyebrow" style="margin-top:12px">Choose seats</p>
|
|
424
424
|
${this.chooser.chipsHtml({intents:`<button type="button" class="${s}" data-ch-act="drag-select">Drag box</button>`})}
|
|
425
425
|
<p class="slm-note" style="margin-bottom:18px">Choose a destination, then add whole sections,
|
|
426
|
-
rows, a dragged area, a category, or individual seats. Find selects what it matches on Enter.</p>`}selectionRailHtml(e){let t=
|
|
426
|
+
rows, a dragged area, a category, or individual seats. Find selects what it matches on Enter.</p>`}selectionRailHtml(e){let t=Ee(e,this.allocation,this.list),s=this.conflict?`<div class="slm-ch-alert err" role="alert"><span>\u26A0</span>
|
|
427
427
|
<span><b>Assignments changed while you were editing.</b> Nothing was applied.
|
|
428
428
|
Your ${e.length.toLocaleString()}-seat selection is kept.
|
|
429
429
|
<button type="button" data-ch-act="refresh-review">Refresh and review \u2192</button></span></div>`:"",n=e.length!==this.lastSelectionCount?" bump":"";this.lastSelectionCount=e.length;let i=e.length>_,a=t.map(l=>{let r=this.markerFor(l.channelId);return`<div class="slm-ch-selsrc-row">
|
|
@@ -467,9 +467,9 @@
|
|
|
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(
|
|
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 f=r===t;return`<div class="slm-ch-dist${f?" on":""}" data-ch-route="${u(r)}">
|
|
471
471
|
<b>${u(q(r))}${f?'<span class="cur">Current route</span>':""}</b>
|
|
472
|
-
<span class="why">${u(
|
|
472
|
+
<span class="why">${u(Pe(r))}</span>
|
|
473
473
|
${f&&!d?"":`<button type="button" class="slm-btn${h&&!f?"":" ghost"}"
|
|
474
474
|
data-ch-act="${u(c)}">${u(d)}</button>`}
|
|
475
475
|
</div>`};return`
|
|
@@ -480,17 +480,17 @@
|
|
|
480
480
|
${l("internal","route-internal",t==="internal"?"":"Hand to your staff",!1)}
|
|
481
481
|
${l("none","route-none",t==="none"?"":"Keep as reserve",!1)}
|
|
482
482
|
${this.hostedLinksHtml()}
|
|
483
|
-
${t==="server"?
|
|
483
|
+
${t==="server"?as:""}`}async loadLinks(e){if(!this.caps.view)return;let t=++this.linksSeq,s=()=>t!==this.linksSeq||this.linksChannelId!==e;this.linksChannelId!==e&&(this.links=[],this.linksChannelId=e,this.linksState="loading");try{let n=await this.host.api.accessLinks(this.host.eventKey,e);if(s())return;this.links=n.links??[],this.linksState="ready"}catch(n){if(s())return;let i=n instanceof S?n.status:0;this.links=[],this.linksState=i===404||i===405||i===501?"unsupported":"error",this.linksState==="error"&&this.host.onError(n)}}hostedLinksHtml(){let e='<p class="slm-eyebrow" style="margin-top:18px">Buyer links</p>';return this.linksState==="unsupported"?`${e}<div class="slm-ch-alert warn" data-ch-state="links-unsupported"><span>\u2139</span>
|
|
484
484
|
<span><b>Buyer links need a newer server.</b> Everything else on this channel works normally.</span></div>`:this.linksState==="error"?`${e}<div class="slm-ch-alert err" role="alert" data-ch-state="links-error"><span>\u26A0</span>
|
|
485
485
|
<span><b>Couldn't load this channel's links.</b> This is a failed read, not an empty list \u2014
|
|
486
486
|
any live link is still working.
|
|
487
487
|
<button type="button" data-ch-act="link-reload">Try again</button></span></div>`:this.linksState==="idle"||this.linksState==="loading"&&!this.links.length?`${e}<div class="slm-ch-busy" role="status" data-ch-state="links-loading">Loading buyer links\u2026</div>`:this.links.length?`${e}
|
|
488
488
|
${this.links.map(t=>this.linkCardHtml(t)).join("")}
|
|
489
489
|
<p class="slm-note">A link is shown once, when you create it. SeatLayer keeps only a fingerprint of it, so it
|
|
490
|
-
can never be shown again \u2014 if a link is lost, rotate it and send the fresh one.</p>`:""}linkCardHtml(e){let t=
|
|
490
|
+
can never be shown again \u2014 if a link is lost, rotate it and send the fresh one.</p>`:""}linkCardHtml(e){let t=De(e),s=e.maxRedemptions>0?Math.min(100,Math.round(e.redemptions/e.maxRedemptions*100)):0,n=le(e).map(r=>`<div class="slm-ch-lkrow"><span class="k">${u(r.k)}</span>
|
|
491
491
|
<span class="v">${u(r.v)}</span></div>`).join(""),i=e.activeSessions?`<div class="slm-ch-lkrow"><span class="k">Buyers inside now</span>
|
|
492
492
|
<span class="v">${e.activeSessions.toLocaleString()}</span></div>`:"",a=e.lastRedeemedAt?`<div class="slm-ch-lkrow"><span class="k">Last opened</span>
|
|
493
|
-
<span class="v">${u(new Date(e.lastRedeemedAt).toLocaleString())}</span></div>`:"",l=this.caps.manage&&
|
|
493
|
+
<span class="v">${u(new Date(e.lastRedeemedAt).toLocaleString())}</span></div>`:"",l=this.caps.manage&&oe(e)?`<div class="slm-ch-row2">
|
|
494
494
|
<button type="button" class="slm-btn ghost" data-ch-rotate="${u(e.id)}">Rotate</button>
|
|
495
495
|
<button type="button" class="slm-btn ghost" data-ch-revoke="${u(e.id)}">Revoke</button>
|
|
496
496
|
</div>`:"";return`<div class="slm-ch-link">
|
|
@@ -532,7 +532,7 @@
|
|
|
532
532
|
<div class="r"><span class="sw" style="background:#3a4051"></span> Unavailable to this audience (one neutral state)</div>
|
|
533
533
|
<div class="r"><span class="sw" style="background:#22a06b"></span> Sold \u2014 same as any buyer sees</div>
|
|
534
534
|
</div>
|
|
535
|
-
${c}`}paintSelection(){this.caps.manage&&this.host.selectionLabels().length&&(this.assignOpen=!0),this.view==="inspect"&&!this.detailChannelId&&this.paintRail()}wireRail(){let e=this.host.rail;e.querySelectorAll("[data-ch-view]").forEach(a=>{a.addEventListener("click",()=>this.setView(a.dataset.chView))}),e.querySelectorAll("[data-ch-map]").forEach(a=>{a.addEventListener("click",()=>{this.mapIntent=a.dataset.chMap==="assign"?"assign":"pan",this.mapIntent==="assign"&&(this.assignOpen=!0),this.paintRail(),this.onInteractionChange?.()})}),e.querySelectorAll("[data-ch-open]").forEach(a=>{let l=()=>this.openChannel(a.dataset.chOpen);a.addEventListener("click",l),a.addEventListener("keydown",r=>{r.key!=="Enter"&&r.key!==" "&&r.key!=="Spacebar"||(r.preventDefault(),l())})}),e.querySelectorAll("[data-ch-menu]").forEach(a=>{a.addEventListener("click",l=>{l.stopPropagation(),this.openDialog({kind:"menu",channelId:a.dataset.chMenu})}),a.addEventListener("keydown",l=>{l.stopPropagation()})}),e.querySelectorAll("[data-ch-rotate]").forEach(a=>{a.addEventListener("click",()=>this.openDialog({kind:"linkRotate",channelId:this.detailChannelId,linkId:a.dataset.chRotate}))}),e.querySelectorAll("[data-ch-revoke]").forEach(a=>{a.addEventListener("click",()=>this.openDialog({kind:"linkRevoke",channelId:this.detailChannelId,linkId:a.dataset.chRevoke}))});let t=e.querySelector("[data-ch-target]");t?.addEventListener("change",()=>{this.targetChannelId=t.value,this.conflict=!1,this.paintRail()});let s=e.querySelector("[data-ch-audience]");s?.addEventListener("change",()=>{this.previewAudience=[s.value],this.loadPreview()});let n=e.querySelector("[data-ch-includepublic]");n?.addEventListener("change",()=>{this.previewIncludePublic=n.checked,this.loadPreview()}),e.querySelector(".slm-ch-grab")?.addEventListener("click",()=>this.cycleDetent()),e.querySelectorAll("[data-ch-act]").forEach(a=>{a.addEventListener("click",()=>this.railAction(a.dataset.chAct))}),this.chooser.wireFind(e)}openChannel(e){this.detailChannelId=e,this.paintRail(),this.loadLinks(e).then(()=>this.paintRail())}railAction(e){switch(e){case"sections":this.focusedSectionId=null,this.host.showSectionOverview(),this.paintRail();break;case"create":this.openDialog({kind:"create"});break;case"review":this.openDialog({kind:"review"});break;case"rename":this.openDialog({kind:"rename",channelId:this.detailChannelId});break;case"pricing":this.openDialog({kind:"pricing",channelId:this.detailChannelId});break;case"archive":this.openDialog({kind:"archive",channelId:this.detailChannelId});break;case"seatlist":this.openDialog({kind:"seatlist"});break;case"pause":this.togglePause();break;case"discard":this.host.clearSelection();break;case"back":this.detailChannelId=null,this.linksChannelId=null,this.links=[],this.linksState="idle",this.paintRail();break;case"link-create":this.openDialog({kind:"linkCreate",channelId:this.detailChannelId});break;case"embed-code":this.chooseWebsiteIntegration();break;case"route-internal":this.setAccessIntent("internal");break;case"route-none":this.setAccessIntent("none");break;case"link-reload":this.detailChannelId&&this.reloadLinks();break;case"retry":this.refresh();break;case"toggle-archived":this.showArchived=!this.showArchived,this.refresh();break;case"refresh-review":this.conflict=!1,this.refresh().then(()=>this.openDialog({kind:"review"}));break;case"pick-sections":this.openDialog({kind:"scope",scope:"sections"});break;case"pick-rows":this.openDialog({kind:"scope",scope:"rows"});break;case"drag-select":this.mapIntent="assign",this.paintRail(),this.onInteractionChange?.();break;case"pick-category":this.pickCategory();break;case"assign-open":this.assignOpen=!0,this.mapIntent="assign",this.paintRail(),this.onInteractionChange?.();break;case"assign-close":this.assignOpen=!1,this.mapIntent="pan",this.paintRail(),this.onInteractionChange?.();break;case"preview-retry":this.loadPreview();break;default:break}}pickCategory(){this.chooser.openCategory()}renderScopeDialog(e){e.scope==="rows"?this.chooser.openRows():this.chooser.openSections()}openDialog(e){this.dialog=e,this.renderDialog()}renderDialog(){let e=this.dialog;e&&(e.kind==="create"?this.renderCreateDialog(e):e.kind==="review"?this.renderReviewDialog(e):e.kind==="scope"?this.renderScopeDialog(e):e.kind==="archive"?this.renderArchiveDialog(e):e.kind==="rename"?this.renderRenameDialog(e):e.kind==="pricing"?this.renderPricingDialog(e):e.kind==="seatlist"?this.renderSeatListDialog():e.kind==="menu"?this.renderMenuDialog(e):e.kind==="linkCreate"?this.renderLinkCreateDialog(e):e.kind==="linkRotate"?this.renderLinkRotateDialog(e):e.kind==="linkRevoke"?this.renderLinkRevokeDialog(e):e.kind==="intentSwitch"&&this.renderIntentSwitchDialog(e))}renderIntentSwitchDialog(e){let t=this.list?.channels.find(a=>a.id===e.channelId),s=e.intentTo;if(!t||!s||!this.caps.manage){this.closeDialog();return}let{headline:n,consequences:i}=
|
|
535
|
+
${c}`}paintSelection(){this.caps.manage&&this.host.selectionLabels().length&&(this.assignOpen=!0),this.view==="inspect"&&!this.detailChannelId&&this.paintRail()}wireRail(){let e=this.host.rail;e.querySelectorAll("[data-ch-view]").forEach(a=>{a.addEventListener("click",()=>this.setView(a.dataset.chView))}),e.querySelectorAll("[data-ch-map]").forEach(a=>{a.addEventListener("click",()=>{this.mapIntent=a.dataset.chMap==="assign"?"assign":"pan",this.mapIntent==="assign"&&(this.assignOpen=!0),this.paintRail(),this.onInteractionChange?.()})}),e.querySelectorAll("[data-ch-open]").forEach(a=>{let l=()=>this.openChannel(a.dataset.chOpen);a.addEventListener("click",l),a.addEventListener("keydown",r=>{r.key!=="Enter"&&r.key!==" "&&r.key!=="Spacebar"||(r.preventDefault(),l())})}),e.querySelectorAll("[data-ch-menu]").forEach(a=>{a.addEventListener("click",l=>{l.stopPropagation(),this.openDialog({kind:"menu",channelId:a.dataset.chMenu})}),a.addEventListener("keydown",l=>{l.stopPropagation()})}),e.querySelectorAll("[data-ch-rotate]").forEach(a=>{a.addEventListener("click",()=>this.openDialog({kind:"linkRotate",channelId:this.detailChannelId,linkId:a.dataset.chRotate}))}),e.querySelectorAll("[data-ch-revoke]").forEach(a=>{a.addEventListener("click",()=>this.openDialog({kind:"linkRevoke",channelId:this.detailChannelId,linkId:a.dataset.chRevoke}))});let t=e.querySelector("[data-ch-target]");t?.addEventListener("change",()=>{this.targetChannelId=t.value,this.conflict=!1,this.paintRail()});let s=e.querySelector("[data-ch-audience]");s?.addEventListener("change",()=>{this.previewAudience=[s.value],this.loadPreview()});let n=e.querySelector("[data-ch-includepublic]");n?.addEventListener("change",()=>{this.previewIncludePublic=n.checked,this.loadPreview()}),e.querySelector(".slm-ch-grab")?.addEventListener("click",()=>this.cycleDetent()),e.querySelectorAll("[data-ch-act]").forEach(a=>{a.addEventListener("click",()=>this.railAction(a.dataset.chAct))}),this.chooser.wireFind(e)}openChannel(e){this.detailChannelId=e,this.paintRail(),this.loadLinks(e).then(()=>this.paintRail())}railAction(e){switch(e){case"sections":this.focusedSectionId=null,this.host.showSectionOverview(),this.paintRail();break;case"create":this.openDialog({kind:"create"});break;case"review":this.openDialog({kind:"review"});break;case"rename":this.openDialog({kind:"rename",channelId:this.detailChannelId});break;case"pricing":this.openDialog({kind:"pricing",channelId:this.detailChannelId});break;case"archive":this.openDialog({kind:"archive",channelId:this.detailChannelId});break;case"seatlist":this.openDialog({kind:"seatlist"});break;case"pause":this.togglePause();break;case"discard":this.host.clearSelection();break;case"back":this.detailChannelId=null,this.linksChannelId=null,this.links=[],this.linksState="idle",this.paintRail();break;case"link-create":this.openDialog({kind:"linkCreate",channelId:this.detailChannelId});break;case"embed-code":this.chooseWebsiteIntegration();break;case"route-internal":this.setAccessIntent("internal");break;case"route-none":this.setAccessIntent("none");break;case"link-reload":this.detailChannelId&&this.reloadLinks();break;case"retry":this.refresh();break;case"toggle-archived":this.showArchived=!this.showArchived,this.refresh();break;case"refresh-review":this.conflict=!1,this.refresh().then(()=>this.openDialog({kind:"review"}));break;case"pick-sections":this.openDialog({kind:"scope",scope:"sections"});break;case"pick-rows":this.openDialog({kind:"scope",scope:"rows"});break;case"drag-select":this.mapIntent="assign",this.paintRail(),this.onInteractionChange?.();break;case"pick-category":this.pickCategory();break;case"assign-open":this.assignOpen=!0,this.mapIntent="assign",this.paintRail(),this.onInteractionChange?.();break;case"assign-close":this.assignOpen=!1,this.mapIntent="pan",this.paintRail(),this.onInteractionChange?.();break;case"preview-retry":this.loadPreview();break;default:break}}pickCategory(){this.chooser.openCategory()}renderScopeDialog(e){e.scope==="rows"?this.chooser.openRows():this.chooser.openSections()}openDialog(e){this.dialog=e,this.renderDialog()}renderDialog(){let e=this.dialog;e&&(e.kind==="create"?this.renderCreateDialog(e):e.kind==="review"?this.renderReviewDialog(e):e.kind==="scope"?this.renderScopeDialog(e):e.kind==="archive"?this.renderArchiveDialog(e):e.kind==="rename"?this.renderRenameDialog(e):e.kind==="pricing"?this.renderPricingDialog(e):e.kind==="seatlist"?this.renderSeatListDialog():e.kind==="menu"?this.renderMenuDialog(e):e.kind==="linkCreate"?this.renderLinkCreateDialog(e):e.kind==="linkRotate"?this.renderLinkRotateDialog(e):e.kind==="linkRevoke"?this.renderLinkRevokeDialog(e):e.kind==="intentSwitch"&&this.renderIntentSwitchDialog(e))}renderIntentSwitchDialog(e){let t=this.list?.channels.find(a=>a.id===e.channelId),s=e.intentTo;if(!t||!s||!this.caps.manage){this.closeDialog();return}let{headline:n,consequences:i}=Be(e.switchBlocked);this.renderScrim(`
|
|
536
536
|
<h3 id="slm-ch-dlg-title">Change how ${u(t.name)} reaches buyers?</h3>
|
|
537
537
|
<p class="sub">${u(n)}</p>
|
|
538
538
|
<div class="slm-ch-alert warn" role="alert"><span>\u26A0</span><span>
|
|
@@ -546,7 +546,7 @@
|
|
|
546
546
|
<button type="button" class="slm-btn" data-ch-intent-ack${e.busy?" disabled":""}>
|
|
547
547
|
${e.busy?"Changing\u2026":`Change to "${u(q(s))}"`}</button>
|
|
548
548
|
</div>`,a=>{a.querySelector("[data-ch-intent-ack]")?.addEventListener("click",()=>{this.acknowledgeIntentSwitch(s,e.pendingLink??null)})})}async acknowledgeIntentSwitch(e,t){let s=this.detailChannelId;if(!s){this.closeDialog();return}if(this.dialog&&(this.dialog.busy=!0,this.renderDialog()),!await this.setAccessIntent(e,{acknowledgeLiveAccess:!0})){this.dialog?.kind==="intentSwitch"&&(this.dialog.busy=!1,this.renderDialog());return}if(!t){this.closeDialog();return}this.dialog?.kind==="intentSwitch"&&(this.dialog.busy=!1,this.renderDialog()),await this.mintLink(s,t)}renderScrim(e,t){let s=this.scrimEl;s||(this.lastFocus=document.activeElement??null),s?.remove();let n=document.createElement("div");n.className="slm-ch-scrim",n.innerHTML=`<div class="slm-ch-dialog" role="dialog" aria-modal="true"
|
|
549
|
-
aria-labelledby="slm-ch-dlg-title" tabindex="-1">${e}</div>`,this.host.root.appendChild(n),this.scrimEl=n;let i=n.firstElementChild;i.querySelectorAll("[data-ch-close]").forEach(l=>{l.addEventListener("click",()=>this.closeDialog())}),n.addEventListener("keydown",l=>{if(l.key==="Escape"){l.stopPropagation(),this.closeDialog();return}if(l.key!=="Tab")return;let r=[...i.querySelectorAll('summary,button:not([disabled]),select:not([hidden]),input,textarea,a[href],[tabindex]:not([tabindex="-1"])')];if(!r.length)return;let c=r[0],d=r[r.length-1];l.shiftKey&&document.activeElement===c?(l.preventDefault(),d.focus()):!l.shiftKey&&document.activeElement===d&&(l.preventDefault(),c.focus())}),t(i),
|
|
549
|
+
aria-labelledby="slm-ch-dlg-title" tabindex="-1">${e}</div>`,this.host.root.appendChild(n),this.scrimEl=n;let i=n.firstElementChild;i.querySelectorAll("[data-ch-close]").forEach(l=>{l.addEventListener("click",()=>this.closeDialog())}),n.addEventListener("keydown",l=>{if(l.key==="Escape"){l.stopPropagation(),this.closeDialog();return}if(l.key!=="Tab")return;let r=[...i.querySelectorAll('summary,button:not([disabled]),select:not([hidden]),input,textarea,a[href],[tabindex]:not([tabindex="-1"])')];if(!r.length)return;let c=r[0],d=r[r.length-1];l.shiftKey&&document.activeElement===c?(l.preventDefault(),d.focus()):!l.shiftKey&&document.activeElement===d&&(l.preventDefault(),c.focus())}),t(i),Y(i),(i.querySelector("input,summary,button")??i).focus()}closeDialog(e={}){this.dialog=null,this.scrimEl?.remove(),this.scrimEl=null,e.restoreFocus!==!1&&this.lastFocus?.focus?.(),this.lastFocus=null}renderCreateDialog(e){let t=(this.list?.channels??[]).map(n=>V(n.marker||n.name,"")),s=ie("",t);this.renderScrim(`
|
|
550
550
|
<h3 id="slm-ch-dlg-title">Create channel</h3>
|
|
551
551
|
<p class="sub">A named allocation only the right audience can buy from. You'll pick the seats next.</p>
|
|
552
552
|
<div class="slm-field">
|
|
@@ -571,12 +571,12 @@
|
|
|
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=
|
|
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),f=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"}`}
|
|
578
578
|
</button>
|
|
579
|
-
</div>`,m=!n
|
|
579
|
+
</div>`,m=!n&&$e(s)?'<p class="slm-note">Applying moves inventory out of another private channel. That is the line marked above.</p>':"",p=c?`<div class="slm-ch-alert warn"><span>\u2139</span><span>Nothing in this selection can move right now \u2014
|
|
580
580
|
every seat is in a buyer's checkout, already sold, or already in ${u(a)}.</span></div>`:"",v=d?`<div class="slm-ch-alert warn" role="alert"><span>\u2139</span><span><b>Choose fewer seats.</b>
|
|
581
581
|
One Apply can cover at most ${_.toLocaleString()} seats.</span></div>`:"";this.renderScrim(`
|
|
582
582
|
<h3 id="slm-ch-dlg-title">${n?`Moved ${n.applied.toLocaleString()} seat${n.applied===1?"":"s"} to ${u(a)}`:`Move ${t.length.toLocaleString()} selected seat${t.length===1?"":"s"} to ${u(a)}`}</h3>
|
|
@@ -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
|
-
${f}`,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
|
|
589
|
+
${f}`,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,7 +614,7 @@
|
|
|
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
|
|
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,f=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)}"
|
|
@@ -631,9 +631,9 @@
|
|
|
631
631
|
<button type="button" class="slm-btn" data-ch-price-save ${e.busy||!i?"disabled":""}>
|
|
632
632
|
${e.busy?"Saving\u2026":"Save prices"}
|
|
633
633
|
</button>
|
|
634
|
-
</div>`,a=>{a.querySelector("[data-ch-price-save]")?.addEventListener("click",()=>{let l=[];for(let r of a.querySelectorAll("[data-ch-price-category]")){let c=r.value.trim();if(!c)continue;let d=Number(c);if(!Number.isFinite(d)||d<0||d>1e6){r.focus(),this.showDialogError("Enter a price from 0 to 1,000,000, or leave the field blank.");return}l.push({categoryKey:r.dataset.chPriceCategory,tierId:r.dataset.chPriceTier||null,price:d})}this.saveChannelPricing(t,l)})})}async saveChannelPricing(e,t){let s=this.host.api.updateChannelPricing;if(!(!s||!this.dialog||this.dialog.kind!=="pricing")){this.dialog={...this.dialog,busy:!0,error:null},this.renderDialog();try{await s.call(this.host.api,this.host.eventKey,e.id,t,e.pricingVersion??0),this.closeDialog(),await this.refresh(),this.host.toast(t.length?`Custom prices saved for ${e.name}.`:`${e.name} now uses event prices.`,"ok")}catch(n){if(n instanceof
|
|
634
|
+
</div>`,a=>{a.querySelector("[data-ch-price-save]")?.addEventListener("click",()=>{let l=[];for(let r of a.querySelectorAll("[data-ch-price-category]")){let c=r.value.trim();if(!c)continue;let d=Number(c);if(!Number.isFinite(d)||d<0||d>1e6){r.focus(),this.showDialogError("Enter a price from 0 to 1,000,000, or leave the field blank.");return}l.push({categoryKey:r.dataset.chPriceCategory,tierId:r.dataset.chPriceTier||null,price:d})}this.saveChannelPricing(t,l)})})}async saveChannelPricing(e,t){let s=this.host.api.updateChannelPricing;if(!(!s||!this.dialog||this.dialog.kind!=="pricing")){this.dialog={...this.dialog,busy:!0,error:null},this.renderDialog();try{await s.call(this.host.api,this.host.eventKey,e.id,t,e.pricingVersion??0),this.closeDialog(),await this.refresh(),this.host.toast(t.length?`Custom prices saved for ${e.name}.`:`${e.name} now uses event prices.`,"ok")}catch(n){if(n instanceof S&&n.code==="channel_pricing_conflict"){await this.refresh({quiet:!0}),this.dialog={kind:"pricing",channelId:e.id,error:"Prices changed in another window. Latest values are shown \u2014 review and save again."},this.renderDialog();return}this.dialog={kind:"pricing",channelId:e.id,error:n instanceof S&&n.serverMessage?n.serverMessage:"Couldn't save these prices. Try again."},this.renderDialog(),this.host.onError(n)}}}async chooseWebsiteIntegration(){this.detailChannelId&&await this.setAccessIntent("server")}async setAccessIntent(e,t={}){let s=this.detailChannelId;if(!s||!this.caps.manage)return!1;try{let n=await this.host.api.setChannelAccessIntent(this.host.eventKey,s,e,t);return await this.refresh(),this.host.toast(this.intentSavedCopy(e,n?.intentSwitch),"ok"),!0}catch(n){return n instanceof S&&n.code==="channel_intent_switch_blocked"?(this.openDialog({kind:"intentSwitch",channelId:s,intentTo:e,switchBlocked:n.details}),!1):n instanceof S&&n.code==="channel_access_intent_forbids"?(this.host.toast(J(n.details),"err"),!1):(this.host.toast("Couldn't change how this channel reaches buyers.","err"),this.host.onError(n),!1)}}intentSavedCopy(e,t){let s=e==="server"?"Set to your website or app. The embed code is on the Embed page.":e==="internal"?"Only your own staff can sell this channel now.":e==="hosted_link"?"Set to buyer links. Create one to let buyers in.":"Kept as a protected reserve. No route can sell these seats.";if(!t)return s;let n=t.closedLinks?` ${t.closedLinks.toLocaleString()} buyer link${t.closedLinks===1?"":"s"} closed.`:"",i=t.keptSessions?` ${t.keptSessions.toLocaleString()} buyer${t.keptSessions===1?"":"s"} already in a checkout can still finish.`:"";return`${s}${n}${i}`}async togglePause(e=this.detailChannelId){let t=this.list?.channels.find(n=>n.id===e);if(!t||!this.caps.manage)return;let s=t.state!=="paused";try{await this.host.api.setChannelPaused(this.host.eventKey,t.id,s),await this.refresh(),this.host.toast(s?`${t.name} paused. Existing checkouts can finish; no new buyer access is issued.`:`${t.name} resumed.`,"ok")}catch(n){this.host.toast("Couldn't change that channel.","err"),this.host.onError(n)}}renderArchiveDialog(e){let t=this.list?.channels.find(l=>l.id===e.channelId);if(!t){this.closeDialog();return}let s=e.archiveBlocked??null,n=!s&&t.counts.held>0,i=this.assignableChannels().filter(l=>l.id!==t.id),a=s?`<div class="slm-ch-alert warn" role="alert"><span>\u23F3</span>
|
|
635
635
|
<span><b>${(s.heldUnits??s.activeHolds??0).toLocaleString()} seats are in a buyer's checkout right now.</b>
|
|
636
|
-
Archive is unavailable while seats are held \u2014 try again ${u(
|
|
636
|
+
Archive is unavailable while seats are held \u2014 try again ${u(Ie(s))}.</span></div>`:n?`<div class="slm-ch-alert warn"><span>\u23F3</span>
|
|
637
637
|
<span>${t.counts.held.toLocaleString()} seats are in a buyer's checkout right now.
|
|
638
638
|
Archive is refused while any seat is held \u2014 you can try, and we'll tell you when to come back.</span></div>`:"";this.renderScrim(`
|
|
639
639
|
<h3 id="slm-ch-dlg-title">Archive ${u(t.name)}</h3>
|
|
@@ -653,7 +653,7 @@
|
|
|
653
653
|
<div class="foot">
|
|
654
654
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
655
655
|
<button type="button" class="slm-btn danger" data-ch-archive ${s?"disabled":""}>Archive channel</button>
|
|
656
|
-
</div>`,l=>{l.querySelector("[data-ch-archive]")?.addEventListener("click",()=>{let r=l.querySelector("#slm-ch-dest")?.value??"";this.archive(t.id,r||null)})})}async archive(e,t){try{await this.host.api.archiveChannel(this.host.eventKey,e,t),this.closeDialog(),this.detailChannelId=null,await this.refresh(),this.host.toast("Channel archived. Its remaining seats moved to the destination you chose.","ok")}catch(s){if(s instanceof
|
|
656
|
+
</div>`,l=>{l.querySelector("[data-ch-archive]")?.addEventListener("click",()=>{let r=l.querySelector("#slm-ch-dest")?.value??"";this.archive(t.id,r||null)})})}async archive(e,t){try{await this.host.api.archiveChannel(this.host.eventKey,e,t),this.closeDialog(),this.detailChannelId=null,await this.refresh(),this.host.toast("Channel archived. Its remaining seats moved to the destination you chose.","ok")}catch(s){if(s instanceof S&&s.status===409&&s.code==="channel_archive_blocked_by_holds"){this.dialog={kind:"archive",channelId:e,archiveBlocked:s.details??{}},this.renderDialog();return}this.showDialogError("Couldn't archive that channel. Try again."),this.host.onError(s)}}renderSeatListDialog(){this.chooser.openSeatList()}async reloadLinks(){let e=this.detailChannelId;e&&(this.linksState=this.links.length?this.linksState:"loading",await this.loadLinks(e),this.paintRail())}async reloadAfterLinkChange(e){if(this.detailChannelId===e){await this.refresh({quiet:!0});return}await this.loadLinks(e),this.active&&this.paintRail()}linkById(e){return this.links.find(t=>t.id===e)??null}renderLinkCreateDialog(e){let t=this.list?.channels.find(s=>s.id===e.channelId);if(!t||!this.caps.manage){this.closeDialog();return}this.renderScrim(`
|
|
657
657
|
<h3 id="slm-ch-dlg-title">Create a buyer link for ${u(t.name)}</h3>
|
|
658
658
|
<p class="sub">Anyone who opens the link can buy from this channel's allocation \u2014 and only from it.
|
|
659
659
|
You'll see the link once, right after you create it.</p>
|
|
@@ -676,13 +676,13 @@
|
|
|
676
676
|
<div class="slm-field">
|
|
677
677
|
<label for="slm-ch-lk-redemptions">How many people can use it</label>
|
|
678
678
|
<input class="slm-input" type="number" id="slm-ch-lk-redemptions" inputmode="numeric"
|
|
679
|
-
value="${
|
|
679
|
+
value="${ae.maxRedemptions}" />
|
|
680
680
|
<p class="slm-note">Each buyer who opens the link uses one.</p>
|
|
681
681
|
</div>
|
|
682
682
|
<div class="slm-field">
|
|
683
683
|
<label for="slm-ch-lk-quantity">Seats per buyer</label>
|
|
684
684
|
<input class="slm-input" type="number" id="slm-ch-lk-quantity" inputmode="numeric"
|
|
685
|
-
value="${
|
|
685
|
+
value="${ae.maxQuantity}" />
|
|
686
686
|
</div>
|
|
687
687
|
<label class="slm-note" style="display:flex;gap:8px;align-items:center;margin:2px 0 6px">
|
|
688
688
|
<input type="checkbox" id="slm-ch-lk-public" />
|
|
@@ -692,8 +692,8 @@
|
|
|
692
692
|
<div class="foot">
|
|
693
693
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
694
694
|
<button type="button" class="slm-btn" data-ch-lk-create>Create link</button>
|
|
695
|
-
</div>`,s=>{let n=s.querySelector("[data-ch-lk-expiry]"),i=s.querySelector("[data-ch-lk-when-field]"),a=s.querySelector("#slm-ch-lk-when");n.addEventListener("change",()=>{let l=n.value==="custom";i.hidden=!l,l&&!a.value&&(a.value=
|
|
696
|
-
<b>The old link has stopped working.</b> ${e.endedSessions?`${e.endedSessions.toLocaleString()} buyer${e.endedSessions===1?"":"s"} lost access immediately.`:"Buyers who already came in can finish; every new visit needs this link."}</span></div>`:"",i=
|
|
695
|
+
</div>`,s=>{let n=s.querySelector("[data-ch-lk-expiry]"),i=s.querySelector("[data-ch-lk-when-field]"),a=s.querySelector("#slm-ch-lk-when");n.addEventListener("change",()=>{let l=n.value==="custom";i.hidden=!l,l&&!a.value&&(a.value=os(Date.now()+7*864e5))}),s.querySelector("[data-ch-lk-create]")?.addEventListener("click",()=>{let l=tt(s,"#slm-ch-lk-redemptions"),r=tt(s,"#slm-ch-lk-quantity");if(l==null||r==null){this.showDialogError("Those two settings need to be whole numbers.");return}let c;if(n.value==="custom"&&(c=Date.parse(a.value),!Number.isFinite(c))){this.showDialogError("Pick the date and time the link should stop working.");return}this.createLink(t.id,{label:s.querySelector("#slm-ch-lk-label")?.value.trim()||null,includePublic:s.querySelector("#slm-ch-lk-public")?.checked??!1,...c===void 0?{}:{expiresAt:c},maxRedemptions:l,maxQuantity:r})})})}async createLink(e,t){await this.ensureHostedLinkRoute(e,t)&&await this.mintLink(e,t)}async mintLink(e,t){try{let s=await this.host.api.createAccessLink(this.host.eventKey,e,t);this.revealLink(s,{channelId:e}),await this.reloadAfterLinkChange(e)}catch(s){this.showDialogError(U(s instanceof S?s:void 0)),s instanceof S||this.host.onError(s)}}async ensureHostedLinkRoute(e,t){if((this.list?.channels.find(n=>n.id===e)?.access?.intent??"none")==="hosted_link")return!0;try{return await this.host.api.setChannelAccessIntent(this.host.eventKey,e,"hosted_link"),await this.refresh(),!0}catch(n){return n instanceof S&&n.code==="channel_intent_switch_blocked"?(this.openDialog({kind:"intentSwitch",channelId:e,intentTo:"hosted_link",switchBlocked:n.details,pendingLink:t}),!1):(this.showDialogError(n instanceof S&&n.code==="channel_access_intent_forbids"?J(n.details):"Couldn't set this channel up for buyer links. Try again."),n instanceof S||this.host.onError(n),!1)}}revealLink(e,t){let s=e.url;this.dialog=null;let n=t.rotated?`<div class="slm-ch-alert warn" role="status"><span>\u26A0</span><span>
|
|
696
|
+
<b>The old link has stopped working.</b> ${e.endedSessions?`${e.endedSessions.toLocaleString()} buyer${e.endedSessions===1?"":"s"} lost access immediately.`:"Buyers who already came in can finish; every new visit needs this link."}</span></div>`:"",i=le(e.link).map(a=>`<div class="slm-ch-lkrow"><span class="k">${u(a.k)}</span>
|
|
697
697
|
<span class="v">${u(a.v)}</span></div>`).join("");this.renderScrim(`
|
|
698
698
|
<h3 id="slm-ch-dlg-title">Copy this link now</h3>
|
|
699
699
|
<p class="sub">This is the only time SeatLayer can show it. We keep just a fingerprint, so it cannot be
|
|
@@ -711,7 +711,7 @@
|
|
|
711
711
|
${i}
|
|
712
712
|
<div class="foot">
|
|
713
713
|
<button type="button" class="slm-btn" data-ch-close data-ch-lk-done>I've copied it</button>
|
|
714
|
-
</div>`,a=>{let l=a.querySelector("[data-ch-lk-copy]"),r=null;l?.addEventListener("click",()=>{
|
|
714
|
+
</div>`,a=>{let l=a.querySelector("[data-ch-lk-copy]"),r=null;l?.addEventListener("click",()=>{ls(a,s).then(c=>{if(!c){l.textContent="Copy",l.classList.remove("copied"),this.announce("Copying was blocked. The link is selected \u2014 copy it by hand.");return}l.textContent="Copied",l.classList.add("copied"),this.announce("Buyer link copied."),r&&clearTimeout(r),r=setTimeout(()=>{l.textContent="Copy",l.classList.remove("copied")},1500)})})}),this.announce("Your buyer link is ready and is shown once.")}renderLinkRotateDialog(e){let t=this.linkById(e.linkId);if(!t||!this.caps.manage){this.closeDialog();return}let s=t.activeSessions??0,n=s?`<div class="slm-ch-alert warn"><span>\u26A0</span>
|
|
715
715
|
<span><b>${s.toLocaleString()} buyer${s===1?"":"s"}</b> got in with the current link
|
|
716
716
|
and still ${s===1?"has":"have"} active access.</span></div>`:"";this.renderScrim(`
|
|
717
717
|
<h3 id="slm-ch-dlg-title">Rotate the ${u(t.label||"buyer")} link?</h3>
|
|
@@ -733,7 +733,7 @@
|
|
|
733
733
|
<div class="foot">
|
|
734
734
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
735
735
|
<button type="button" class="slm-btn" data-ch-lk-rotate disabled>Rotate and copy new link</button>
|
|
736
|
-
</div>`,i=>{let a=i.querySelector("[data-ch-lk-rotate]");i.querySelectorAll("[data-ch-rot]").forEach(l=>{l.addEventListener("change",()=>{a.disabled=!1})}),a.addEventListener("click",()=>{let l=[...i.querySelectorAll("[data-ch-rot]")].find(r=>r.checked);if(!l){this.showDialogError(
|
|
736
|
+
</div>`,i=>{let a=i.querySelector("[data-ch-lk-rotate]");i.querySelectorAll("[data-ch-rot]").forEach(l=>{l.addEventListener("change",()=>{a.disabled=!1})}),a.addEventListener("click",()=>{let l=[...i.querySelectorAll("[data-ch-rot]")].find(r=>r.checked);if(!l){this.showDialogError(U({code:"end_active_sessions_required"}));return}this.rotateLink(e.channelId,t.id,l.value==="end")})})}async rotateLink(e,t,s){try{let n=await this.host.api.rotateAccessLink(this.host.eventKey,e,t,s);this.revealLink(n,{channelId:e,rotated:!0}),await this.reloadAfterLinkChange(e)}catch(n){this.showDialogError(U(n instanceof S?n:void 0)),n instanceof S||this.host.onError(n)}}renderLinkRevokeDialog(e){let t=this.linkById(e.linkId);if(!t||!this.caps.manage){this.closeDialog();return}let s=t.activeSessions??0;this.renderScrim(`
|
|
737
737
|
<h3 id="slm-ch-dlg-title">Revoke the ${u(t.label||"buyer")} link?</h3>
|
|
738
738
|
<p class="sub">It stops opening immediately and cannot be restored \u2014 there is no undo, and no way to
|
|
739
739
|
bring the same URL back. Seats already bought through it keep their sale.</p>
|
|
@@ -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(
|
|
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 f=document.createElement("span");if(f.className="slm-activity-seats",f.textContent=a.labels.join(", "),r.append(d,h,f),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"),f=()=>{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 g of["in","out"])t.querySelector(`[data-nav="${g}"]`).hidden=!y},c),this.search.addEventListener("keydown",y=>{y.key==="Escape"&&f()},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
|
|
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 f=h[0],m=h[h.length-1];d.shiftKey&&document.activeElement===f?(d.preventDefault(),m.focus()):!d.shiftKey&&document.activeElement===m&&(d.preventDefault(),f.focus())}),t(a),
|
|
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"),f=()=>{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 g of["in","out"])t.querySelector(`[data-nav="${g}"]`).hidden=!y},c),this.search.addEventListener("keydown",y=>{y.key==="Escape"&&f()},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 f=h[0],m=h[h.length-1];d.shiftKey&&document.activeElement===f?(d.preventDefault(),m.focus()):!d.shiftKey&&document.activeElement===m&&(d.preventDefault(),f.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;
|
|
@@ -843,7 +843,7 @@
|
|
|
843
843
|
.slm-ch-scope-empty{padding:18px 12px;color:var(--slm-muted);font-size:11.5px;text-align:center}
|
|
844
844
|
@media(max-width:560px){.slm-ch-scopebar{grid-template-columns:1fr}.slm-ch-scopesummary{padding-bottom:0}}
|
|
845
845
|
@media (prefers-reduced-motion:reduce){.slm-ch-scrim,.slm-ch-dialog{animation:none!important}}
|
|
846
|
-
`;var
|
|
846
|
+
`;var bt="seatlayer-manager-style",gt="seatlayer-manager-channels-style",Bs=`${ut}
|
|
847
847
|
/* The floor was 480px, which trapped the cockpit in any host shorter than that:
|
|
848
848
|
every ancestor here is overflow:hidden, so the bottom of the rail (Create
|
|
849
849
|
channel, Show archived) was rendered but clipped away by the host and could
|
|
@@ -890,6 +890,7 @@
|
|
|
890
890
|
.slm-navigation-results{position:absolute;top:100%;left:0;right:0;max-height:240px;overflow:auto;padding:6px;background:var(--slm-surface);border:1px solid var(--slm-line);border-radius:8px;box-shadow:0 8px 24px #0003}
|
|
891
891
|
.slm-navigation-results button{display:block;width:100%;text-align:left;margin-bottom:3px}
|
|
892
892
|
.slm.details-hidden .slm-rail{display:none}
|
|
893
|
+
.slm.slm-minimal .slm-bar,.slm.slm-minimal .slm-rail,.slm.slm-minimal .slm-railhead,.slm.slm-minimal .slm-navigation-tools,.slm.slm-minimal .slm-blocklegend,.slm.slm-minimal .slm-minimap-mount,.slm.slm-minimal .slm-hint,.slm.slm-minimal .slm-eyebrow,.slm.slm-minimal .slm-note{display:none}
|
|
893
894
|
.slm button:focus-visible,.slm input:focus-visible{outline:2px solid var(--slm-accent);outline-offset:2px}
|
|
894
895
|
.slm[data-theme="light"] .slm-scope.read{color:#465169}
|
|
895
896
|
.slm[data-theme="light"] .slm-scope.event,.slm[data-theme="light"] .slm-tablelock,.slm[data-theme="light"] .slm-kpidelta.down{color:#805500!important}
|
|
@@ -987,6 +988,13 @@
|
|
|
987
988
|
.slm-follow-status,.slm-heat-status{position:absolute;bottom:14px;right:12px;max-width:calc(100% - 120px);padding:6px 9px;border:1px solid var(--slm-line);border-radius:8px;background:var(--slm-bg);color:var(--slm-text);font-size:11px;z-index:5;pointer-events:none}
|
|
988
989
|
.slm-heat-status{bottom:48px}
|
|
989
990
|
.slm-barbtn.follow.on{background:rgba(34,160,107,.13);border-color:#22a06b;color:#5bd39b}
|
|
991
|
+
/* Full screen wears the View summary's box. It is a real <button>, so the
|
|
992
|
+
".slm button" reset outranks the plain .slm-barbtn border \u2014 hence the
|
|
993
|
+
extra .slm here. Label hidden on the compact bar; the name is aria-label. */
|
|
994
|
+
.slm .slm-barbtn.slm-fullscreen{display:inline-flex;align-items:center;gap:6px;flex:none;white-space:nowrap;min-height:30px;padding:5px 10px;
|
|
995
|
+
border:1px solid var(--slm-line);border-radius:8px;font-size:12px}
|
|
996
|
+
.slm .slm-barbtn.slm-fullscreen:hover{border-color:var(--slm-muted)}
|
|
997
|
+
.slm-fullscreen-icon{display:inline-flex}
|
|
990
998
|
|
|
991
999
|
/* body */
|
|
992
1000
|
.slm-body{display:flex;flex:1;min-height:0}
|
|
@@ -1003,6 +1011,15 @@
|
|
|
1003
1011
|
background:color-mix(in srgb,var(--slm-surface) 88%,transparent);border:1px solid var(--slm-line);backdrop-filter:blur(8px);white-space:nowrap}
|
|
1004
1012
|
.slm-blocklegend span{display:inline-flex;align-items:center;gap:5px}
|
|
1005
1013
|
.slm-blocklegend i{width:9px;height:9px;border-radius:3px;display:inline-block}
|
|
1014
|
+
/* Bottom-left of the map, clear of the zoom column and minimap on the right. */
|
|
1015
|
+
.slm-blocklegend{position:absolute;left:12px;bottom:12px;z-index:5;align-items:center;flex-wrap:wrap;justify-content:flex-start;max-width:calc(100% - 250px);white-space:normal;row-gap:6px}
|
|
1016
|
+
.slm.compact .slm-blocklegend{left:8px;bottom:8px;max-width:calc(100% - 96px)}
|
|
1017
|
+
.slm-blocklegend i.seat{border-radius:50%}
|
|
1018
|
+
.slm-legend-items{display:inline-flex;flex-wrap:wrap;align-items:center;gap:6px 10px}
|
|
1019
|
+
.slm-colourby{display:inline-flex;padding:2px;border-radius:999px;background:var(--slm-line);gap:2px}
|
|
1020
|
+
.slm .slm-colourby button{border:0;border-radius:999px;padding:3px 9px;font:inherit;font-size:10.5px;font-weight:700;color:var(--slm-muted);background:transparent;cursor:pointer}
|
|
1021
|
+
.slm .slm-colourby button.on{color:var(--slm-text);background:var(--slm-surface);box-shadow:0 1px 2px rgba(0,0,0,.12)}
|
|
1022
|
+
.slm .slm-colourby button:focus-visible{outline:2px solid var(--slm-accent,#6e7bff);outline-offset:1px}
|
|
1006
1023
|
.slm-blocklegend[hidden]{display:none}
|
|
1007
1024
|
.slm-zoom{display:flex;flex-direction:column;gap:5px;align-items:flex-end}
|
|
1008
1025
|
.slm .slm-zoombtn{width:34px;height:34px;padding:0;border-radius:10px;border:1px solid var(--slm-line);background:color-mix(in srgb,var(--slm-surface) 88%,transparent);
|
|
@@ -1147,7 +1164,7 @@
|
|
|
1147
1164
|
.slm-find-count{display:block;min-height:16px;margin-top:4px;font-size:11px;color:var(--slm-muted);font-variant-numeric:tabular-nums}
|
|
1148
1165
|
.slm-find-count:empty{display:none}
|
|
1149
1166
|
/* Reading aids in the bar (plan item 5, slice D): the bar's Find and the View menu. */
|
|
1150
|
-
.slm-findbar{flex:0 1 250px;min-width:
|
|
1167
|
+
.slm-findbar{flex:0 1 250px;min-width:120px}
|
|
1151
1168
|
.slm-findbar .slm-find{margin:0}
|
|
1152
1169
|
.slm-findbar .slm-find .slm-input{min-height:30px;padding:5px 9px 5px 30px;border-radius:8px;font-size:12px}
|
|
1153
1170
|
.slm-findbar .slm-find::before{left:10px;width:12px;height:12px}
|
|
@@ -1247,7 +1264,7 @@
|
|
|
1247
1264
|
.slm-toast.ok{background:#1f7a4d;color:#fff;border-color:#1f7a4d}
|
|
1248
1265
|
|
|
1249
1266
|
/* control-room actions + insights */
|
|
1250
|
-
.slm-bar-actions{display:flex;align-items:center;justify-self:end;gap:5px
|
|
1267
|
+
.slm-bar-actions{display:flex;align-items:center;justify-self:end;gap:5px}
|
|
1251
1268
|
.slm-barbtn.on{background:rgba(244,183,64,.13);border-color:#f4b740;color:var(--slm-text)}
|
|
1252
1269
|
.slm-sectionlist{display:flex;flex-direction:column;gap:8px;margin-top:4px}
|
|
1253
1270
|
.slm-sectionlist + .slm-eyebrow{margin-top:18px}
|
|
@@ -1376,8 +1393,9 @@
|
|
|
1376
1393
|
.slm.compact .slm-modes{display:none}
|
|
1377
1394
|
.slm.compact .slm-tools{display:block;width:100%;padding:9px 13px;min-height:44px;border:1px solid var(--slm-line);
|
|
1378
1395
|
border-radius:10px;background:var(--slm-surface);color:var(--slm-text);font-size:13px;font-weight:800}
|
|
1379
|
-
.slm.compact .slm-live{justify-self:end}.slm.compact .slm-bar-actions{grid-column:1/-1;justify-self:stretch}
|
|
1380
|
-
.slm.compact .slm-barbtn{flex:1;padding:6px 9px}
|
|
1396
|
+
.slm.compact .slm-live{justify-self:end}.slm.compact .slm-bar-actions{grid-column:1/-1;justify-self:stretch;flex-wrap:wrap}
|
|
1397
|
+
.slm.compact .slm-barbtn{flex:1;padding:6px 9px}
|
|
1398
|
+
.slm.compact .slm-barbtn.slm-fullscreen{flex:none;justify-content:center;min-width:34px}.slm.compact .slm-fullscreen-label{display:none}.slm.compact .slm-kpis{grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}
|
|
1381
1399
|
.slm.compact .slm-kpi[data-kpi="viewing-map"],.slm.compact .slm-kpi[data-kpi="active-holds"],
|
|
1382
1400
|
.slm.compact .slm-kpi[data-kpi="booked-pct"],.slm.compact .slm-kpi[data-kpi="booked-value"]{display:none}
|
|
1383
1401
|
/* Reduced motion, as a BLANKET over the cockpit subtree rather than a list of
|
|
@@ -1397,7 +1415,7 @@
|
|
|
1397
1415
|
transition:none!important;
|
|
1398
1416
|
scroll-behavior:auto!important}
|
|
1399
1417
|
}
|
|
1400
|
-
`;function bt(){if(typeof document>"u"||document.getElementById(pt))return;let o=document.createElement("style");o.id=pt,o.textContent=As,document.head.appendChild(o)}function gt(o){if(typeof document>"u"||document.getElementById(ut))return;let e=document.createElement("style");e.id=ut,e.textContent=o,document.head.appendChild(e)}Ye();var It=require("@seatlayer/core"),G=require("@seatlayer/core/picker/minimapGeometry");var At=require("@seatlayer/core"),Os=require("@seatlayer/core/core/cdnAsset");var zs=require("@seatlayer/core/core/cdnAsset");function F(o,e){let t=(0,At.t)(o);return t===o?e:t}function Fs(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 Vs(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 Ht(o,e){let t=new Ge(o);return t.build(e),t}var Ge=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,G.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}=Fs(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||Vs(i.visible,i.bounds))return;let a=(0,G.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,G.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,It.pointInPolygon)(t,s.outline)){this.host.controller.focusSection(s.id);return}this.host.controller.clearSectionFocus(),this.host.controller.panToWorld(t)}}};function Pt(o){return o.focusedSection!==null?o.deeperThanSectionFrame===!1?"venue":"section":o.atVenueFit!==void 0?o.atVenueFit?"none":"venue":o.seatsRevealed?"venue":"none"}function Bt(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 Dt(o){let t=Pt({focusedSection:o.focused?o.focused.label:null,seatsRevealed:o.seatsRevealed,atVenueFit:o.atVenueFit})==="none";return{crumb:o.focused?o.floor?`${o.floor} \xB7 ${Bt(o.focused)}`:Bt(o.focused):o.floor??"Venue",crumbShown:!!o.focused||!!o.floor,zoomInEnabled:!o.atCeiling,zoomOutEnabled:!t,venueEnabled:!t}}function Ot(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 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`
|
|
1401
1419
|
<div class="slm-mapchrome" data-ref="mapchrome">
|
|
1402
1420
|
${o.legend??""}
|
|
1403
1421
|
<div class="slm-crumb" data-ref="crumb" role="status" hidden></div>
|
|
@@ -1407,10 +1425,16 @@
|
|
|
1407
1425
|
<button type="button" class="slm-zoombtn slm-zoombtn-venue" data-ref="zfit" title="Whole venue">Venue</button>
|
|
1408
1426
|
</div>
|
|
1409
1427
|
<div class="slm-minimap-mount" data-ref="minimap"></div>
|
|
1410
|
-
</div>`}function
|
|
1428
|
+
</div>`}function Vt(o,e){o.crumb&&(o.crumb.textContent=e.crumb,o.crumb.hidden=!e.crumbShown);let t=(s,n)=>{s&&(s.disabled=!n,s.setAttribute("aria-disabled",String(!n)))};t(o.zin,e.zoomInEnabled),t(o.zout,e.zoomOutEnabled),t(o.zfit,e.venueEnabled)}var j={plenty:{min:.5,color:"#22a06b",label:"Plenty left",detail:"over half"},tight:{min:.15,color:"#f4b740",label:"Filling up",detail:"under half"},gone:{min:0,color:"#d9534f",label:"Nearly gone",detail:"under 15%"}},Z={free:"#5b6db0",held:"#f4b740",sold:"#9ca3af"};function Us(o,e){let t=e>0?o/e:0;return t>=j.plenty.min?"plenty":t>=j.tight.min?"tight":"gone"}function Ks(o,e,t,s=Date.now()){return o?.mode==="closed"||t?"Closed":o?.mode==="timed"&&o.revealAt&&o.revealAt>s?`Hidden until ${Ws(o.revealAt,s)}`:o?.mode==="threshold"&&e?`Hidden until ${o.thresholdPct??0}% sold`:o?.mode==="hidden"||e?"Hidden":null}function Ws(o,e){let t=new Date(o),s=t.toLocaleTimeString(void 0,{hour:"numeric",minute:t.getMinutes()?"2-digit":void 0}),n=(o-e)/864e5;return n<1&&t.getDate()===new Date(e).getDate()?s:n<6?`${t.toLocaleDateString(void 0,{weekday:"short"})} ${s}`:t.toLocaleDateString(void 0,{day:"numeric",month:"short"})}function qt(o,e){let t=o.state==="sold-out"?"Sold out":Ks(e.rule,e.hiddenNow,e.closedNow);return{tint:t==="Closed"||t==="Sold out"?null:e.colourBy==="type"?e.typeTint??null:j[Us(o.free,o.total)].color,stateWord:t}}function _t(){return`<div class="slm-blocklegend" data-ref="blocklegend" role="group" aria-label="Map colours">
|
|
1429
|
+
<span class="slm-colourby" role="radiogroup" aria-label="Colour by">
|
|
1430
|
+
<button type="button" role="radio" data-colour-by="full" aria-checked="true">How full</button>
|
|
1431
|
+
<button type="button" role="radio" data-colour-by="type" aria-checked="false">Ticket type</button>
|
|
1432
|
+
</span>
|
|
1433
|
+
<span class="slm-legend-items" data-ref="legenditems"></span>
|
|
1434
|
+
</div>`}function Ys(o){let e=o.seats;return o.colourBy==="full"&&!e?[...Object.keys(j).map(t=>({label:`${j[t].label} \xB7 ${j[t].detail}`,color:j[t].color,seat:!1})),{label:"Sold out",color:Z.sold,seat:!1}]:o.colourBy==="full"?[{label:"Free",color:Z.free,seat:!0},{label:"Held",color:Z.held,seat:!0},{label:"Sold",color:Z.sold,seat:!0}]:[...o.types.map(t=>({label:t.label,color:t.color,seat:e})),...e?[{label:"Held",color:Z.held,seat:!0}]:[],{label:e?"Sold":"Sold out",color:Z.sold,seat:e}]}function Nt(o,e){o.querySelectorAll("[data-colour-by]").forEach(s=>{let n=s.dataset.colourBy===e.colourBy;s.setAttribute("aria-checked",String(n)),s.classList.toggle("on",n)});let t=o.querySelector('[data-ref="legenditems"]');t&&t.replaceChildren(...Ys(e).map(s=>{let n=document.createElement("span"),i=document.createElement("i");return i.style.background=s.color,s.seat&&i.classList.add("seat"),n.append(i,document.createTextNode(s.label)),n}))}var jt=[{key:"seatLabels",label:"Seat labels",letter:"S",hint:"Seat numbers where the zoom can carry them"},{key:"rowLabels",label:"Row labels",letter:"R",hint:"Row letters beside each row"},{key:"channelColours",label:"Channel colours",letter:"H",hint:"Channel flags and tints \u2014 the Channels tool\u2019s overlay"},{key:"momentum",label:"Booking momentum",letter:"M",hint:"Warm the sections booking fastest in the selected window"}],Ut="seatlayer.controlRoom.mapView";function we(){return{seatLabels:!0,rowLabels:!0,categoryColours:!1,channelColours:!0,momentum:!1}}function Kt(o){return o==="g"?"categoryColours":jt.find(t=>t.letter.toLowerCase()===o)?.key??null}function Wt(o=Gt()){let e=we();if(!o)return e;try{let t=o.getItem(Ut);if(!t)return e;let s=JSON.parse(t),n={...e};for(let i of Object.keys(e))typeof s[i]=="boolean"&&(n[i]=s[i]);return n}catch{return e}}function Yt(o,e=Gt()){if(e)try{e.setItem(Ut,JSON.stringify(o))}catch{}}function Gt(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function Xt(o,e){e.renderer?.setLabelLayers?.({seatLabels:o.seatLabels,rowLabels:o.rowLabels}),e.renderer?.setCategoryColours?.(o.categoryColours),e.channelsOverlay(o.channelColours)}function Zt(){return`
|
|
1411
1435
|
<details class="slm-view" data-ref="view">
|
|
1412
1436
|
<summary class="slm-barbtn slm-view-summary" aria-haspopup="menu" title="How the map reads: labels, colours, momentum">View <span class="slm-view-caret" aria-hidden="true">\u25BE</span></summary>
|
|
1413
|
-
<div class="slm-view-menu" role="menu" aria-label="Map view">${
|
|
1437
|
+
<div class="slm-view-menu" role="menu" aria-label="Map view">${jt.map(e=>`
|
|
1414
1438
|
<button type="button" class="slm-view-item" role="menuitemcheckbox" data-view="${e.key}" aria-checked="false" title="${e.hint}">
|
|
1415
1439
|
<span class="slm-view-check" aria-hidden="true"></span>
|
|
1416
1440
|
<span class="slm-view-label">${e.label}</span>
|
|
@@ -1418,12 +1442,12 @@
|
|
|
1418
1442
|
</button>`).join("")}
|
|
1419
1443
|
<div class="slm-view-note" data-ref="viewnote" hidden></div>
|
|
1420
1444
|
</div>
|
|
1421
|
-
</details>`}function
|
|
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,f=!1)=>{let m=o.availabilityRules[d.id]??null,p=o.effectiveClosed.has(d.id)||f,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)},f=!!o.availabilityRules[c.id],m=o.availabilityRules[c.id]?.mode==="closed";r("zone",h,!1);for(let p of d)r("section",p,f,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>
|
|
1422
1446
|
<summary aria-label="Availability for ${b(o.label)}" ${e?'aria-disabled="true"':""}>${i.find(d=>d[0]===t)[1]}<span aria-hidden="true">\u2304</span></summary>
|
|
1423
1447
|
<div class="slm-availchoices" aria-label="Availability options for ${b(o.label)}">
|
|
1424
1448
|
${i.map(([d,h,f])=>`<button type="button" data-avail-id="${b(o.id)}" data-avail-value="${d}" aria-pressed="${t===d}"${n}><span><b>${h}</b><small>${f}</small></span><span aria-hidden="true">${t===d?"\u2713":""}</span></button>`).join("")}
|
|
1425
1449
|
</div>
|
|
1426
|
-
</details>`,l="";if(!o.followsZone&&t==="timed"){let d=o.rule?.revealAt?b(
|
|
1450
|
+
</details>`,l="";if(!o.followsZone&&t==="timed"){let d=o.rule?.revealAt?b(Lt(o.rule.revealAt)):"";l=`<div class="slm-availdetail">
|
|
1427
1451
|
<input type="datetime-local" class="slm-input" data-avail-reveal="${b(o.id)}" value="${d}"${n} aria-label="Reveal time for ${b(o.label)}" />
|
|
1428
1452
|
</div>`}else if(!o.followsZone&&t==="threshold"){let d=o.rule?.thresholdPct??80;l=`<div class="slm-availdetail">
|
|
1429
1453
|
<span class="slm-availpctlabel">Reveal at</span>
|
|
@@ -1437,19 +1461,19 @@
|
|
|
1437
1461
|
</div>
|
|
1438
1462
|
${a}
|
|
1439
1463
|
${l}
|
|
1440
|
-
</div>`}var rn="https://api.seatlayer.io",Fe=200,ms=16,ps=4,us=[{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."}]}],cn=3;function dn(o){let e=o?.status;return e===401||e===403}var hn=Object.fromEntries(us.flatMap(o=>o.tools.map(e=>[e.shortcut.toLowerCase(),e.mode]))),Ve=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.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=ke();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.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?Nt(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=hn[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.sectionOptions=[];We(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 Y(e.apiBase??rn,e.token),this.organizerAssetUrls=new ue(this.key,(t,s)=>this.withAuthRetry(()=>this.api.asset(t,s))),this.host=St(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(){bt(),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(()=>(tt(),hs));if(this.closed||!this.channelCaps.view||(this.channels||(gt(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)??S.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)??S.UNGROUPED_ID;return{id:i,label:this.sectionLabelById.get(i)??"Other seats"}},openDialog:(s,n)=>{this.chooserDialog=ht(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=xe({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 $t({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)??S.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)??S.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};Object.keys(t).some(n=>t[n]!==this.mapView[n])&&(this.mapView=t,Ut(t),t.momentum!==this.heatEnabled&&this.setHeatOverlay(t.momentum),this.applyMapView(),this.paintMapViewMenu())}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(){Wt(this.mapView,{renderer:this.renderer,channelsOverlay:e=>this.channels?.setOverlayVisible(e)})}paintMapViewMenu(){let e=this.els.view;e&&Gt(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=Ue(this.themeMode);for(let[t,s]of Object.entries(Tt(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=vt(()=>{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=Mt(Ue(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){We(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>=cn||dn(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.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=`
|
|
1441
1465
|
<strong id="slm-ended-title">This session ended</strong>
|
|
1442
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>
|
|
1443
|
-
<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 w&&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 w&&i.code==="table_inventory_in_use";this.toastErr(a?"Release held, booked, or blocked table inventory before changing its booking mode.":"Couldn't update table booking. No table mode was changed."),this.opts.onError?.(i)}finally{this.tableBookingSaving=!1,this.mode==="tables"&&this.renderTablesRail()}}}async reloadEventChart(){let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1;let t=await this.organizerAssetUrls.prepareRendererChart(e.doc);this.renderer?.destroy(),this.renderer=null,this.doc=t,this.labelToId.clear(),this.labelToSeat.clear(),this.allIds=[],this.gaUnitLabelSet.clear(),this.status.clear(),this.counts={held:0,booked:0,blocked:0},this.serverBaseline=null,this.lastSelectionLabels.clear(),this.buildUnitUniverse(t),this.buildRenderer(),this.buildSectionOptions(),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}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&&(a.hidden=e.getRung?.()==="seats"||!e.getMinimapSnapshot?.().sections.length),zt(this.els,Dt({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}))}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=Ht({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 S.SeatmapRenderer(this.mapHost,{manageMode:!0,organizerGlyph:{apply:S.applyOrganizerSeatGlyph,clear:S.clearOrganizerSeatGlyph,isPainted:S.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(),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=>Ft(t,{rule:this.availabilityRules[t.id],hiddenNow:this.effectiveHidden.has(t.id),closedNow:this.effectiveClosed.has(t.id)}),openAtSectionsWhenDense:!0}),this.renderer.setChart(this.themedDoc()),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)??S.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}"
|
|
1444
|
-
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){for(let t of(0,S.expandChart)(e))this.labelToId.set(t.label,t.id),this.labelToSeat.set(t.label,t),this.allIds.push(t.id);for(let t of(0,S.gaAreasOf)(e))for(let s of(0,S.gaUnitLabels)(t))this.labelToId.has(s)||this.gaUnitLabelSet.add(s)}unitTotal(){return this.allIds.length+this.gaUnitLabelSet.size}knownLabels(){return[...this.labelToId.keys(),...this.gaUnitLabelSet]}repaintAll(){let e=this.renderer;if(!e)return;this.allIds.length&&e.setStatus(this.allIds,"free");let t={free:[],held:[],booked:[],not_for_sale:[]};for(let[s,n]of this.status.entries()){let i=this.labelToId.get(s);i&&t[ge(n)].push(i)}["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.labelToId.get(l.label);d&&(this.renderer?.setStatus([d],ge(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);let i=this.labelToId.get(n);i&&s.push(i)}s.length&&this.renderer?.setStatus(s,ge(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!==S.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,ms)){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,ps))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,ms).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,ps))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>
|
|
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>
|
|
1445
1469
|
<span class="slm-liveeventcopy">${b(n)} \xB7 ${e.count.toLocaleString()} ${i} ${b(e.verb)}</span>
|
|
1446
|
-
<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.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>
|
|
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=`
|
|
1447
1471
|
<div class="slm-bar">
|
|
1448
1472
|
<div class="slm-modes" data-ref="modes" role="tablist" aria-label="Control room tools">
|
|
1449
|
-
${
|
|
1450
|
-
<span class="slm-modegroup-label" aria-hidden="true">${b(
|
|
1451
|
-
${
|
|
1452
|
-
title="${b(
|
|
1473
|
+
${vs.map(i=>`<div class="slm-modegroup" data-group="${i.key}" role="presentation" hidden>
|
|
1474
|
+
<span class="slm-modegroup-label" aria-hidden="true">${b(i.label)}</span>
|
|
1475
|
+
${i.tools.map(a=>`<button class="slm-mode" role="tab" data-mode="${a.mode}"
|
|
1476
|
+
title="${b(a.title)} (${a.shortcut})" aria-keyshortcuts="${a.shortcut}" hidden>${b(a.label)}</button>`).join("")}
|
|
1453
1477
|
</div>`).join("")}
|
|
1454
1478
|
</div>
|
|
1455
1479
|
<select class="slm-tools" data-ref="tools" aria-label="Control room tools"></select>
|
|
@@ -1457,9 +1481,10 @@
|
|
|
1457
1481
|
<div class="slm-bar-actions">
|
|
1458
1482
|
<button class="slm-barbtn follow" data-ref="follow" aria-label="Follow live" aria-pressed="false"
|
|
1459
1483
|
title="Stay on the current map view unless enabled">Auto-follow</button>
|
|
1460
|
-
<div data-ref="findbar" class="slm-findbar">${
|
|
1461
|
-
${
|
|
1462
|
-
<button class="slm-barbtn" data-ref="fullscreen" title="Full screen (F)" aria-
|
|
1484
|
+
<div data-ref="findbar" class="slm-findbar">${ke({compact:!0})}</div>
|
|
1485
|
+
${Zt()}
|
|
1486
|
+
<button type="button" class="slm-barbtn slm-fullscreen" data-ref="fullscreen" title="Full screen (F)" aria-label="Full screen"
|
|
1487
|
+
aria-keyshortcuts="F"><span class="slm-fullscreen-icon" aria-hidden="true">${nt.enter}</span><span class="slm-fullscreen-label">Full screen</span></button>
|
|
1463
1488
|
</div>
|
|
1464
1489
|
<div class="slm-kpis" data-ref="kpis"></div>
|
|
1465
1490
|
</div>
|
|
@@ -1472,13 +1497,14 @@
|
|
|
1472
1497
|
</div>
|
|
1473
1498
|
<div class="slm-heat-status" data-ref="heatstatus" role="status" hidden></div>
|
|
1474
1499
|
<div class="slm-follow-status" data-ref="followstatus" role="status" hidden></div>
|
|
1475
|
-
${
|
|
1500
|
+
${Ft()}
|
|
1501
|
+
${_t()}
|
|
1476
1502
|
</div>
|
|
1477
1503
|
<aside class="slm-rail"><div class="slm-railscroll" data-ref="rail"></div></aside>
|
|
1478
1504
|
</div>
|
|
1479
1505
|
<div class="slm-toast" data-ref="toast"></div>
|
|
1480
|
-
`,this.host.appendChild(e),this.root=e,this.selectObserver=new MutationObserver(()=>{let
|
|
1481
|
-
<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(){this.els.fullscreen
|
|
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="${b(s.label)}">${s.tools.map(n=>`<option value="${n.mode}"${n.mode===this.mode?" selected":""}>${b(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">${b(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="${b(a.title)}">
|
|
1482
1508
|
<b>${a.dot?`<span class="dot" style="background:${a.dot}"></span>`:""}${a.n}</b><span>${a.l}</span>
|
|
1483
1509
|
${d?`<span class="slm-kpidelta${d.down?" down":""}">${d.text}</span>`:""}
|
|
1484
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=`
|
|
@@ -1500,8 +1526,8 @@
|
|
|
1500
1526
|
</div>
|
|
1501
1527
|
<div class="slm-sectionlist" data-ref="sections"></div>
|
|
1502
1528
|
</div>
|
|
1503
|
-
`,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
|
|
1504
|
-
<span class="slm-sectiontop"><span>${b(n.sectionLabel)}</span><span title="Configured value of currently booked inventory">${
|
|
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="${b(n.sectionId)}" title="Focus ${b(n.sectionLabel)} on the map">
|
|
1530
|
+
<span class="slm-sectiontop"><span>${b(n.sectionLabel)}</span><span title="Configured value of currently booked inventory">${ve(n.bookedValue,e.currency)}</span></span>
|
|
1505
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>
|
|
1506
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=`
|
|
1507
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.")}
|
|
@@ -1556,14 +1582,14 @@
|
|
|
1556
1582
|
</div>`).join("")}</div>
|
|
1557
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(f=>!f.locked).map(f=>f.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=`
|
|
1558
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.")}
|
|
1559
|
-
<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)??
|
|
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=`
|
|
1560
1586
|
<div class="slm-seat-heading"><h2>${b(t.label)}</h2><span data-seat-status>${n[s]}</span></div>
|
|
1561
1587
|
<p class="slm-note">${b(a)} \xB7 ${b(l?.label??t.categoryKey)}</p>
|
|
1562
|
-
<div data-ref="seat-history"></div>`;let r=this.els.rail.querySelector('[data-ref="seat-history"]');this.seatHistoryPanel=new
|
|
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=`
|
|
1563
1589
|
${this.railHeader("Sections","event","Draw sections or zones in the designer to schedule availability per area. This chart has none yet.")}
|
|
1564
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=`
|
|
1565
1591
|
${this.railHeader("Sections","event","Decide when each zone or section goes on sale for this event. Keep it hidden, reveal it at a set time, or <b>auto-reveal once the rest sells past a threshold</b>. Hidden seats vanish for buyers; closed seats stay on the map (flat grey) but can't be bought.")}
|
|
1566
|
-
<div class="slm-availlist" data-ref="availlist">${e.map(l=>
|
|
1592
|
+
<div class="slm-availlist" data-ref="availlist">${e.map(l=>es(l,this.availabilitySaving)).join("")}</div>
|
|
1567
1593
|
<div class="slm-availsummary">
|
|
1568
1594
|
<span class="slm-availdot${a?" warn":""}"></span>
|
|
1569
1595
|
<span>${b(i)}</span>
|
|
@@ -1571,10 +1597,10 @@
|
|
|
1571
1597
|
<div class="slm-availcallout">
|
|
1572
1598
|
<span class="slm-availstar" aria-hidden="true">\u2726</span>
|
|
1573
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>
|
|
1574
|
-
</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=
|
|
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>
|
|
1575
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="${b(l.id)}">${b(l.label)}</option>`).join("");this.els.rail.innerHTML=`
|
|
1576
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>
|
|
1577
|
-
<p class="slm-note">${
|
|
1603
|
+
<p class="slm-note">${Mt}</p>
|
|
1578
1604
|
<div data-block-editor ${this.blockBrowse?"hidden":""}>
|
|
1579
1605
|
<p class="slm-eyebrow slm-step"><span class="slm-stepnum">1</span>Choose seats</p>
|
|
1580
1606
|
<p class="slm-selecthelp">Zoom into a section, then drag a box or draw a lasso on the map, tap a row label for the whole row, press \u2318A for all of it, or pick below.</p>
|
|
@@ -1615,5 +1641,5 @@
|
|
|
1615
1641
|
<button class="slm-btn ghost" data-ref="markall" style="width:100%" disabled>Put all blocked seats on sale</button>
|
|
1616
1642
|
<p class="slm-note slm-allnote" data-ref="markallnote">For a full reset only. You will be asked to confirm.</p>
|
|
1617
1643
|
</div></details>
|
|
1618
|
-
`,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)??
|
|
1619
|
-
<details><summary>Choose seats</summary>${f.map(g=>`<div class="slm-block-seatline"><button type="button" class="slm-blockeditem${n.has(g.label)?" on":""}" data-blocked-label="${b(g.label)}" aria-pressed="${n.has(g.label)}"><span class="slm-blockedcheck" aria-hidden="true">\u2713</span><span>${b(g.label)}</span></button><button type="button" data-block-seat-find="${b(g.label)}" aria-label="Show ${b(g.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>`)}};
|
|
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 f=r.closest("[data-blocked-label]");f?.dataset.blockedLabel?this.toggleLabels([f.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){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 f=r.get(h.rowId)??[];f.push(h),r.set(h.rowId,f)}this.els.blockedshowing.textContent=`${t.length.toLocaleString()} seats \xB7 ${r.size} rows`,this.els.blockedlist.innerHTML=[...r.entries()].slice(0,this.blockedResultLimit).map(([h,f])=>{let m=this.sectionByObject.get(h)??k.UNGROUPED_ID,p=this.sectionLabelById.get(m)??"Other seats",v=this.doc?.objects.find(g=>g.id===h),y=v&&"label"in v?v.label:f[0].label;return`<div class="slm-block-group"><div class="slm-block-grouphead"><button type="button" data-block-locate="${b(h)}" title="Show this row and nearby seats on the map"><b>${b(y)}</b><small>${b(p)} \xB7 ${f.length} blocked</small></button><button type="button" data-block-group="${b(h)}">Select row</button></div>
|
|
1645
|
+
<details><summary>Choose seats</summary>${f.map(g=>`<div class="slm-block-seatline"><button type="button" class="slm-blockeditem${n.has(g.label)?" on":""}" data-blocked-label="${b(g.label)}" aria-pressed="${n.has(g.label)}"><span class="slm-blockedcheck" aria-hidden="true">\u2713</span><span>${b(g.label)}</span></button><button type="button" data-block-seat-find="${b(g.label)}" aria-label="Show ${b(g.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});
|