@ticketlayer/live 0.4.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -174,6 +174,22 @@ Surface:
174
174
  overrides), so framework-specific fetch options pass straight through.
175
175
  `opts.noCache` bypasses the in-memory cache for one call.
176
176
 
177
+ Every request carries `TL-Version`, `TL-Client` and `User-Agent`. `TL-Client`
178
+ is the header every Ticketlayer SDK sets, on every runtime, because a browser
179
+ cannot set `User-Agent`: the fetch spec makes it a forbidden header name and
180
+ the browser drops it without saying so. This entry only ever runs in Node or on
181
+ an edge runtime, so it sets both and sends the same identity in each
182
+ (`ticketlayer-live/<version> (node/<v>)`). Pass `userAgent` to name your own
183
+ program instead; `TL-Client` still identifies the SDK build either way.
184
+
185
+ ```ts
186
+ const live = createServerClient({
187
+ apiUrl: process.env.LIVE_API_INTERNAL_URL!,
188
+ publishableKey: process.env.LIVE_PUBLISHABLE_KEY!,
189
+ userAgent: 'acme-box-office/2.1',
190
+ });
191
+ ```
192
+
177
193
  ## Scripts
178
194
 
179
195
  From the repository root, after `pnpm install`:
@@ -1 +1 @@
1
- {"version":3,"file":"clientHeader.d.ts","sourceRoot":"","sources":["../src/clientHeader.ts"],"names":[],"mappings":"AAWA,yDAAyD;AACzD,wBAAgB,eAAe,IAAI,MAAM,CAOxC;AAED,eAAO,MAAM,iBAAiB,QAA0F,CAAC"}
1
+ {"version":3,"file":"clientHeader.d.ts","sourceRoot":"","sources":["../src/clientHeader.ts"],"names":[],"mappings":"AAkBA,yDAAyD;AACzD,wBAAgB,eAAe,IAAI,MAAM,CAOxC;AAED,eAAO,MAAM,iBAAiB,QAA0F,CAAC"}
@@ -1,7 +1,14 @@
1
1
  /**
2
2
  * The TL-Client request header: `ticketlayer-live/<version> (<runtime>)`.
3
3
  *
4
- * Lets the API attribute traffic to an SDK build. The version comes from
4
+ * Lets the API attribute traffic to an SDK build. It exists because a browser
5
+ * cannot set User-Agent - the fetch spec lists it as a forbidden header name -
6
+ * so every SDK sends its identity in a header a browser is allowed to set.
7
+ * A runtime that can set both sends the same identity in each: the server entry
8
+ * (src/server.ts) does, as does the Go SDK (TKT-80). The browser entry must not,
9
+ * or it would set a header the browser drops without saying so.
10
+ *
11
+ * The version comes from
5
12
  * src/version.ts, written from package.json by the prebuild script, so it is
6
13
  * always the version npm published. Hand-written; the generated client
7
14
  * (src/client.ts) gains an equivalent on its next regeneration from
@@ -1 +1 @@
1
- {"version":3,"file":"clientHeader.js","sourceRoot":"","sources":["../src/clientHeader.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAErD,yDAAyD;AACzD,MAAM,UAAU,eAAe;IAC7B,MAAM,CAAC,GAAG,UAAiC,CAAC;IAC5C,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,KAAK,aAAa;QAAE,OAAO,cAAc,CAAC;IAClE,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,WAAW;QAAE,OAAO,SAAS,CAAC;IAC3F,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI;QAAE,OAAO,QAAQ,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxE,IAAI,CAAC,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC;IACjC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,WAAW,KAAK,eAAe,EAAE,GAAG,CAAC"}
1
+ {"version":3,"file":"clientHeader.js","sourceRoot":"","sources":["../src/clientHeader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAErD,yDAAyD;AACzD,MAAM,UAAU,eAAe;IAC7B,MAAM,CAAC,GAAG,UAAiC,CAAC;IAC5C,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,KAAK,aAAa;QAAE,OAAO,cAAc,CAAC;IAClE,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,WAAW;QAAE,OAAO,SAAS,CAAC;IAC3F,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI;QAAE,OAAO,QAAQ,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxE,IAAI,CAAC,CAAC,WAAW;QAAE,OAAO,MAAM,CAAC;IACjC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,WAAW,KAAK,eAAe,EAAE,GAAG,CAAC"}
package/dist/server.d.ts CHANGED
@@ -16,6 +16,13 @@
16
16
  * `session.create()` is available for callers that need a Live session id (for
17
17
  * example to hand off to a WebView checkout); catalogue reads never need one.
18
18
  *
19
+ * Every request carries `TL-Client` and, because this entry only ever runs in
20
+ * Node or on an edge runtime, `User-Agent` as well (TKT-80). The browser entry
21
+ * sends `TL-Client` alone: the fetch spec makes User-Agent a forbidden header
22
+ * name, so a browser silently drops one, and a header that looks set but never
23
+ * arrives is worse than no header at all. `userAgent` in the options replaces
24
+ * the default; TL-Client still names this SDK build either way.
25
+ *
19
26
  * Nothing here is imported by the browser entry (src/index.ts) or the CDN
20
27
  * build (src/auto.ts), so the browser bundle is unchanged by this module.
21
28
  */
@@ -50,6 +57,15 @@ export interface ServerClientOptions {
50
57
  credentialTtlMs?: number;
51
58
  /** Override the dated API version sent as TL-Version. */
52
59
  apiVersion?: string;
60
+ /**
61
+ * Override the User-Agent header.
62
+ *
63
+ * Defaults to the same identity this client sends as TL-Client, so a request
64
+ * names its SDK whether the server reads one header or the other. TL-Client
65
+ * always identifies this SDK regardless of what is set here, so a caller who
66
+ * names their own program does not hide which SDK build made the call.
67
+ */
68
+ userAgent?: string;
53
69
  /** RequestInit merged into every request (headers are merged, not replaced). */
54
70
  requestInit?: RequestInit;
55
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -16,6 +16,13 @@
16
16
  * `session.create()` is available for callers that need a Live session id (for
17
17
  * example to hand off to a WebView checkout); catalogue reads never need one.
18
18
  *
19
+ * Every request carries `TL-Client` and, because this entry only ever runs in
20
+ * Node or on an edge runtime, `User-Agent` as well (TKT-80). The browser entry
21
+ * sends `TL-Client` alone: the fetch spec makes User-Agent a forbidden header
22
+ * name, so a browser silently drops one, and a header that looks set but never
23
+ * arrives is worse than no header at all. `userAgent` in the options replaces
24
+ * the default; TL-Client still names this SDK build either way.
25
+ *
19
26
  * Nothing here is imported by the browser entry (src/index.ts) or the CDN
20
27
  * build (src/auto.ts), so the browser bundle is unchanged by this module.
21
28
  */
@@ -94,6 +101,7 @@ export function createServerClient(options) {
94
101
  return fetch(input, init);
95
102
  });
96
103
  const apiVersion = options.apiVersion ?? API_DATED_VERSION;
104
+ const userAgent = options.userAgent || SDK_CLIENT_HEADER;
97
105
  const fixedKey = options.publishableKey ?? options.channelKey;
98
106
  const domain = options.domain;
99
107
  if (!fixedKey && !domain) {
@@ -107,6 +115,7 @@ export function createServerClient(options) {
107
115
  Accept: 'application/json',
108
116
  'TL-Version': apiVersion,
109
117
  'TL-Client': SDK_CLIENT_HEADER,
118
+ 'User-Agent': userAgent,
110
119
  });
111
120
  const resolveKey = (force = false) => {
112
121
  if (fixedKey)
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- "use strict";var TicketlayerLive=(()=>{var q=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var ce=Object.getOwnPropertyNames;var ue=Object.prototype.hasOwnProperty;var de=(t,e)=>{for(var a in e)q(t,a,{get:e[a],enumerable:!0})},le=(t,e,a,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of ce(e))!ue.call(t,o)&&o!==a&&q(t,o,{get:()=>e[o],enumerable:!(r=ie(e,o))||r.enumerable});return t};var fe=t=>le(q({},"__esModule",{value:!0}),t);var ve={};de(ve,{TicketlayerLive:()=>v,boot:()=>ae,createLiveClient:()=>B});var z="@ticketlayer/live",j="0.4.0";var K="2026-06-13";function me(){var e,a,r;let t=globalThis;return((e=t.navigator)==null?void 0:e.product)==="ReactNative"?"react-native":typeof t.window!="undefined"&&typeof t.document!="undefined"?"browser":(r=(a=t.process)==null?void 0:a.versions)!=null&&r.node?`node/${t.process.versions.node}`:t.EdgeRuntime?"edge":"unknown"}var he=`${z.replace(/^@/,"").replace("/","-")}/${j} (${me()})`;function ge(){let t=null;return{get:()=>t,set:e=>{t=e},clear:()=>{t=null}}}var _=class extends Error{constructor(e,a,r){super(e),this.code=a,this.status=r,this.name="LiveAPIError"}},N=class{constructor(e){var a,r,o,c;this.salesListings={list:async()=>await this.request("/sales/listings",{method:"GET"})},this.salesCustomerAuth={magicLink:async s=>(await this.request("/sales/customer-auth/magic-link",{method:"POST",body:JSON.stringify(s)})).sent},this.salesCustomerTokens={create:async s=>await this.request("/sales/customer-tokens",{method:"POST",body:JSON.stringify(s)}),refresh:async()=>await this.request("/sales/customer-tokens/refresh",{method:"POST"})},this.salesCarts={create:async s=>(await this.request("/sales/carts",{method:"POST",body:JSON.stringify(s)})).cart,get:async s=>(await this.request(`/sales/carts/${s}`,{method:"GET"})).cart,addItem:async(s,n)=>(await this.request(`/sales/carts/${s}/items`,{method:"POST",body:JSON.stringify(n)})).cart,removeItem:async(s,n)=>(await this.request(`/sales/carts/${s}/items/${n}`,{method:"DELETE"})).cart,checkout:async(s,n)=>await this.request(`/sales/carts/${s}/checkout`,{method:"POST",body:JSON.stringify(n)})},this.salesMyOrders={list:async()=>(await this.request("/sales/my-orders",{method:"GET"})).orders},this.salesOrders={get:async s=>(await this.request(`/sales/orders/${s}`,{method:"GET"})).order,ticketPdf:async(s,n)=>await this.request(`/sales/orders/${s}/passes/${n}/ticket.pdf`,{method:"GET"})},this.salesOrderPayments={create:async(s,n)=>(await this.request(`/sales/orders/${s}/payments`,{method:"POST",body:JSON.stringify(n)})).payment},this.salesRefundRequests={create:async(s,n)=>(await this.request(`/sales/orders/${s}/refund-requests`,{method:"POST",body:JSON.stringify(n)})).request},this.salesCustomers={create:async s=>(await this.request("/sales/customers",{method:"POST",body:JSON.stringify(s)})).customer,get:async s=>(await this.request(`/sales/customers/${s}`,{method:"GET"})).customer,update:async(s,n)=>(await this.request(`/sales/customers/${s}`,{method:"PATCH",body:JSON.stringify(n)})).customer},this.salesPresaleCodes={redeem:async s=>await this.request("/sales/presale-codes/redeem",{method:"POST",body:JSON.stringify(s)})},this.sales={resolveChannel:async s=>{let n=new URLSearchParams;(s==null?void 0:s.domain)!==void 0&&n.append("domain",String(s.domain));let i=n.toString(),d=i?`/sales/channel?${i}`:"/sales/channel";return await this.request(d,{method:"GET"})},get:async s=>(await this.request(`/sales/events/${s}`,{method:"GET"})).event,getTheme:async()=>(await this.request("/sales/theme",{method:"GET"})).theme},this.session={start:async s=>await this.request("/session",{method:"POST",body:JSON.stringify(s)}),current:async()=>await this.request("/session",{method:"GET"}),end:async()=>await this.request("/session",{method:"DELETE"}),attachOrderAccess:async s=>await this.request("/session/order-access",{method:"POST",body:JSON.stringify(s)})},this.queue={status:async()=>await this.request("/queue/status",{method:"GET"}),join:async()=>await this.request("/queue/join",{method:"POST"})},this.baseUrl=e.baseUrl.replace(/\/$/,""),this.sessionMode=(a=e.sessionMode)!=null?a:"cookie",this.publishableKey=e.publishableKey,this.tokenStorage=(r=e.tokenStorage)!=null?r:ge(),this.apiVersion=(o=e.apiVersion)!=null?o:K,this.headers=(c=e.headers)!=null?c:{}}async setSessionToken(e){await this.tokenStorage.set(e)}async getSessionToken(){return this.tokenStorage.get()}async clearSession(){await this.tokenStorage.clear()}async request(e,a={}){var i,d,u;let r=`${this.baseUrl}${e}`,o={"Content-Type":"application/json","TL-Version":this.apiVersion,"TL-Client":he,...this.headers,...a.headers};if(this.publishableKey&&(o.Authorization=`Bearer ${this.publishableKey}`),this.sessionMode==="token"){let l=await this.tokenStorage.get();l&&(o["X-Live-Session"]=l)}let c=await fetch(r,{...a,headers:o,credentials:this.sessionMode==="cookie"?"include":"same-origin"}),s=await c.text(),n=s?JSON.parse(s):null;if(!c.ok){let l=(i=n==null?void 0:n.error)!=null?i:{};throw new _((d=l.message)!=null?d:`Request failed (${c.status})`,(u=l.code)!=null?u:"REQUEST_FAILED",c.status)}return n&&n.status==="success"&&n.data!==void 0?n.data:n}};var P="Ticketlayer",pe="ticketlayer:ready";function ye(t){let e=window;if(e[P])return e[P];let a={client:null,sdk:null,version:t,_resolvers:[],getClient(){return this.client},getSDK(){return this.sdk},ready(){return this.client?Promise.resolve(this.client):new Promise(r=>this._resolvers.push(r))}};return e[P]=a,a}function J(t,e,a){if(typeof window=="undefined")return;let r=ye(a);r.client&&r.client!==t&&console.warn("[live] A Ticketlayer client is already on window.Ticketlayer; replacing it. Create a single client per page."),r.client=t,r.sdk=e;let o=r._resolvers;r._resolvers=[],o.forEach(c=>c(t)),window.dispatchEvent(new CustomEvent(pe,{detail:t}))}var V="https://cdn.ticketlayer.com/elements/v1/ticketlayer-elements/ticketlayer-elements.esm.js",be="tl-event-list",Y=new Map,we=/\/v\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?\//,ke=/^(?:sha(?:256|384|512)-[A-Za-z0-9+/]+={0,2})(?:\s+sha(?:256|384|512)-[A-Za-z0-9+/]+={0,2})*$/,M=class extends Error{constructor(e){super(`[live] ${e}`),this.name="ElementsIntegrityError"}},H=!1;function X(t={}){var s,n;if(!t.elements)return Promise.resolve();let e=((s=t.elementsIntegrity)==null?void 0:s.trim())||void 0;if(e&&!t.elementsUrl)throw new M("elementsIntegrity was given without elementsUrl. The default Elements URL is a floating path that every release rewrites, so a hash pinned to it cannot keep matching. Pass the pinned elementsUrl that the hash is for (see /versions.json on the CDN).");if(e&&!ke.test(e))throw new M(`elementsIntegrity is not a subresource integrity value: ${JSON.stringify(t.elementsIntegrity)}. Expected one or more of sha256-, sha384- or sha512- followed by base64, as /versions.json publishes it.`);if(t.elementsUrl&&!e&&we.test(t.elementsUrl))throw new M(`elementsUrl ${t.elementsUrl} names an exact version, which is the CDN's pinned tier, but no elementsIntegrity came with it. A pinned URL exists to be verified; loading it unchecked would be weaker than the floating path. Pass the sha384 from /versions.json as elementsIntegrity (data-elements-integrity on the embed script), or use a floating /v1/ URL.`);if(typeof window=="undefined"||typeof document=="undefined")return Promise.resolve();let a=window.customElements;if(a!=null&&a.get(be))return Promise.resolve();let r=(n=t.elementsUrl)!=null?n:V;!t.elementsUrl&&!H&&(H=!0,console.warn(`[live] Loading Elements unverified from the floating default ${V}. Floating paths are rewritten by every release and cannot carry a subresource integrity hash. To verify the bundle, pin it: set elementsUrl (data-elements-url) to the pinned path from /versions.json and elementsIntegrity (data-elements-integrity) to the sha384 beside it.`));let o=Y.get(r);if(o)return o;let c=new Promise((i,d)=>{let u=document.createElement("script");u.type="module",u.src=r,u.async=!0,e&&(u.integrity=e,u.crossOrigin="anonymous"),u.dataset.ticketlayerElements="auto",u.onload=()=>i(),u.onerror=()=>d(new Error(`[live] Failed to load Elements from ${r}`)),document.head.appendChild(u)});return Y.set(r,c),c}var U={"color-primary":"primary","color-primary-foreground":"primary-foreground","color-secondary":"secondary","color-secondary-foreground":"secondary-foreground","color-accent":"accent","color-accent-foreground":"accent-foreground","color-background":"background","color-foreground":"foreground","color-card":"card","color-muted":"muted","color-muted-foreground":"muted-foreground","color-border":"border","color-border-hover":"border-hover","color-input":"input","color-ring":"ring","color-success":"success","color-success-foreground":"success-foreground","color-warning":"warning","color-warning-foreground":"warning-foreground","color-warning-bg":"warning-bg","color-error":"error",destructive:"error","color-destructive":"error","color-error-foreground":"error-foreground","destructive-foreground":"error-foreground","color-destructive-foreground":"error-foreground","color-error-bg":"error-bg","destructive-bg":"error-bg","color-destructive-bg":"error-bg","base-size":"font-size-base",radius:"radius-md"},A={primary:"#6366f1","primary-foreground":"#ffffff",secondary:"#f3f4f6","secondary-foreground":"#111827",accent:"#ec4899","accent-foreground":"#ffffff",background:"#ffffff",foreground:"#111827",card:"#ffffff",muted:"#f9fafb","muted-foreground":"#6b7280",border:"#e5e7eb","border-hover":"#9ca3af",input:"#e5e7eb",ring:"#6366f1",success:"#10b981","success-foreground":"#ffffff",warning:"#f59e0b","warning-foreground":"#ffffff","warning-bg":"#fef3c7",error:"#ef4444","error-foreground":"#ffffff","error-bg":"#fee2e2","font-family":"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif","font-family-mono":"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace","font-size-base":"16px","font-scale":"1.25","radius-none":"0px","radius-sm":"0.25rem","radius-md":"0.5rem","radius-lg":"0.75rem","radius-full":"9999px","spacing-1":"0.25rem","spacing-2":"0.5rem","spacing-3":"0.75rem","spacing-4":"1rem","spacing-5":"1.25rem","spacing-6":"1.5rem","spacing-8":"2rem","duration-fast":"120ms","duration-normal":"200ms","duration-slow":"320ms","easing-standard":"cubic-bezier(0.2, 0, 0, 1)","easing-emphasised":"cubic-bezier(0.3, 0, 0, 1)"};var $={primary:"colors.primary","primary-foreground":"colors.primaryForeground",secondary:"colors.secondary","secondary-foreground":"colors.secondaryForeground",accent:"colors.accent","accent-foreground":"colors.accentForeground",background:"colors.background",foreground:"colors.foreground",muted:"colors.muted","muted-foreground":"colors.mutedForeground",border:"colors.border",input:"colors.input",ring:"colors.ring",success:"colors.success","success-foreground":"colors.successForeground",warning:"colors.warning","warning-foreground":"colors.warningForeground",error:"colors.destructive","error-foreground":"colors.destructiveForeground","font-family":"typography.fontFamily","font-family-mono":"typography.fontFamilyMono","font-size-base":"typography.baseSize","font-scale":"typography.scaleRatio","radius-none":"shape.radiusNone","radius-sm":"shape.radiusSm","radius-md":"shape.radiusMd","radius-lg":"shape.radiusLg","radius-full":"shape.radiusFull"};function R(t){return`--tl-${t}`}function Z(t){var a;let e={};if(!t)return e;for(let[r,o]of Object.entries($)){let[c,s]=o.split("."),n=(a=t[c])==null?void 0:a[s];n==null||n===""||(e[R(r)]=String(n))}for(let[r,o]of Object.entries(U)){let c=e[R(o)];c!==void 0&&(e[R(r)]=c)}return e}var Q="tl-checkout-overlay";function W(t,e={}){if(typeof window=="undefined"||typeof document=="undefined")return()=>{};let a=null,r=()=>{var n;(n=document.getElementById(Q))==null||n.remove(),a&&(window.removeEventListener("message",a),a=null)},o=async n=>{let i=await t.getSessionToken().catch(()=>null),d=(e.embedBaseUrl||window.location.origin).replace(/\/$/,""),u=new URLSearchParams;i&&u.set("session",i),u.set("parent_origin",window.location.origin);let l=`${d}/embed/checkout?${u.toString()}`,f=new URL(l).origin;r();let g=document.createElement("div");g.id=Q,g.style.cssText="position:fixed;inset:0;z-index:2147483647;background:rgba(15,23,42,0.55);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:16px;";let h=document.createElement("div");h.style.cssText="width:100%;max-width:960px;display:flex;flex-direction:column;gap:10px;";let b=document.createElement("iframe");b.src=l,b.allow="payment",b.style.cssText=`width:100%;height:88vh;max-height:760px;border:1px solid var(--tl-border, ${A.border});border-radius:16px;background:#fff;box-shadow:0 24px 64px rgba(0,0,0,0.45);`,h.appendChild(b),g.appendChild(h),g.addEventListener("click",w=>{var m;(w.target===g||w.target===h)&&(r(),(m=n.onClose)==null||m.call(n))}),document.body.appendChild(g),a=w=>{var I,x,C;if(w.origin!==f)return;let m=w.data;if(!(!m||typeof m!="object"))switch(m.type){case"tl:complete":{let S=m.order&&typeof m.order=="object"?m.order:{},O=m.orderId?{...S,id:m.orderId,orderNumber:m.orderReference,...m.accessToken?{accessToken:m.accessToken}:{}}:m.order;(I=n.onComplete)==null||I.call(n,O),t.emit("checkout:completed",O),r();break}case"tl:close":case"tl:cancel":(x=n.onClose)==null||x.call(n),r();break;case"tl:error":{let S=new Error(m.message||m.code||"Checkout failed");m.code&&(S.code=m.code),(C=n.onError)==null||C.call(n,S);break}}},window.addEventListener("message",a)},c=t.on("ui:checkout-requested",n=>void o(n!=null?n:{})),s=t.on("ui:modal-close-requested",()=>r());return()=>{c(),s(),r()}}function ee(t,e={}){if(typeof window=="undefined"||typeof document=="undefined")return()=>{};let a=e.tag||"tl-buy-modal",r=null,o=null,c=()=>{r&&(r.remove(),r=null),o=null},s=d=>{if(!(d!=null&&d.eventId))return;c(),o=d;let u=document.createElement(a);u.setAttribute("event-id",d.eventId),d.occurrenceId&&u.setAttribute("occurrence-id",d.occurrenceId),u.addEventListener("tlClose",()=>{var f;let l=o;c(),(f=l==null?void 0:l.onClose)==null||f.call(l)}),u.addEventListener("tlError",l=>{var g,h;let f=((g=l.detail)==null?void 0:g.message)||"Could not load this event";(h=o==null?void 0:o.onError)==null||h.call(o,new Error(f))}),u.addEventListener("tlCheckout",()=>{let l=o;c(),t.emit("ui:checkout-requested",{onComplete:l==null?void 0:l.onComplete,onError:l==null?void 0:l.onError,onClose:l==null?void 0:l.onClose})}),document.body.appendChild(u),r=u},n=t.on("ui:event-modal-requested",d=>s(d!=null?d:{})),i=t.on("ui:modal-close-requested",()=>c());return()=>{n(),i(),c()}}var re=t=>t&&typeof t=="object"?t:{};function k(t){return typeof t=="number"?Number.isInteger(t)?t:null:typeof t=="string"&&/^-?\d+$/.test(t)?Number(t):null}var D=t=>typeof t.type=="string"?t.type:"ticket",Ee=t=>!["fee","tax","discount"].includes(D(t));function Se(t,e){return t===null?e:t>0||e}function te(t){var w,m,I,x,C,S,O,G;let e=re(t),a=Array.isArray(e.items)?e.items.map(re):[],r=(m=(w=k(e.itemsSubtotal))!=null?w:k(e.subtotal))!=null?m:a.filter(Ee).reduce((y,L)=>{var E;return y+((E=k(L.subtotal))!=null?E:0)},0),o=a.filter(y=>D(y)==="fee"),c=o.length?o.reduce((y,L)=>{var E;return y+((E=k(L.subtotal))!=null?E:0)},0):null,s=(x=(I=k(e.totalFees))!=null?I:k(e.fees))!=null?x:c,n=typeof e.feeLabel=="string"&&e.feeLabel?e.feeLabel:null,i=o.map(y=>y.name).find(y=>typeof y=="string"&&y),d=(C=n!=null?n:i)!=null?C:null,u=a.filter(y=>D(y)==="discount"),l=u.length?u.reduce((y,L)=>{var E;return y+Math.abs((E=k(L.subtotal))!=null?E:0)},0):null,f=(O=(S=k(e.totalDiscounts))!=null?S:k(e.discount))!=null?O:l,g=(G=k(e.totalTax))!=null?G:0,h=k(e.total),b=h!=null?h:r+(s!=null?s:0)+g-(f!=null?f:0);return{currency:typeof e.currency=="string"?e.currency:null,subtotal:r,fees:s!=null?s:0,discount:f!=null?f:0,total:b,hasFees:Se(s,d!==null||o.length>0),feeLabel:d,totalFromServer:h!==null}}var T=t=>{var c;if(!t||typeof t!="object")return t;let e=t,a=((c=e.items)!=null?c:[]).map(s=>{var u,l,f;let n=s,i=(u=n.quantity)!=null?u:0,d=(l=n.subtotal)!=null?l:n.unitPrice*i;return{...n,totalPrice:(f=n.totalPrice)!=null?f:d}}),r=a.reduce((s,n)=>{var i;return s+((i=n.quantity)!=null?i:0)},0),o=te(e);return{...e,items:a,itemCount:r,subtotal:o.subtotal,fees:o.fees,discount:o.discount,total:o.total,hasFees:o.hasFees,feeLabel:o.feeLabel}};function se(t){let e=new Map,a=(i,d)=>{let u=e.get(i);if(!(u!=null&&u.categoryId))throw new Error(`[live] No category known for ticket type ${i}. Load the occurrence's ticket types (getTicketTypes) before adding it to the cart.`);return{categoryId:u.categoryId,occurrenceId:d||u.occurrenceId}},r={async list(i){var l;let d=await t.events.list(),u=((l=d==null?void 0:d.listings)!=null?l:[]).map(f=>{var g,h,b;return{id:(g=f.eventId)!=null?g:f.id,name:(h=f.name)!=null?h:"",...f.shortDescription?{shortDescription:f.shortDescription}:{},...f.imageUrl?{imageUrl:f.imageUrl}:{},...f.venueName?{venue:{id:"",name:f.venueName,city:(b=f.venueCity)!=null?b:""}}:{},...f.nextOccurrenceAt?{nextOccurrence:{startsAt:f.nextOccurrenceAt}}:{},availabilityStatus:"available"}});return i!=null&&i.limit&&(u=u.slice(0,i.limit)),{items:u}},get:i=>t.events.get(i),async getTicketTypes(i,d){var g,h,b,w;let u=await t.events.get(i),l=(b=(g=u==null?void 0:u.occurrences)==null?void 0:g.find(m=>m.id===d))!=null?b:(h=u==null?void 0:u.occurrences)==null?void 0:h[0];return((w=l==null?void 0:l.ticketTypes)!=null?w:[]).map(m=>(l&&e.set(m.ticketTypeId,{categoryId:m.categoryId,occurrenceId:l.id}),{id:m.ticketTypeId,name:m.ticketTypeName,description:m.description,price:m.unitPrice,currency:m.currency,categoryId:m.categoryId,categoryName:m.categoryName,maxPerOrder:10,available:999}))}},o={get:async()=>{var i;return T((i=t.cart.current)!=null?i:await t.cart.refresh())},on:(i,d)=>t.on(i,u=>d(i==="cart:updated"?T(u):u)),off:(i,d)=>t.off(i,d),addItem:async(i,d,u)=>{let{categoryId:l,occurrenceId:f}=a(i,u);return T(await t.cart.add({eventOccurrenceId:f,categoryId:l,ticketTypeId:i,quantity:d}))},addItems:async i=>{let d=t.cart.current;for(let u of i)d=await o.addItem(u.ticketTypeId,u.quantity,u.occurrenceId);return d},removeItem:async i=>T(await t.cart.remove(i)),addSeat:async(i,d,u)=>{let{categoryId:l,occurrenceId:f}=a(d,u);return T(await t.cart.add({eventOccurrenceId:f,categoryId:l,ticketTypeId:d,eventLayoutSeatIds:[i]}))},removeSeat:async(i,d)=>{var u;return console.warn("[live] removeSeat is a no-op until cart items expose seat ids; use removeItem(itemId)."),T((u=await t.cart.refresh())!=null?u:t.cart.current)}},c={mine:()=>t.orders.mine(),get:i=>t.orders.get(i),ticketPdf:(i,d)=>t.orders.ticketPdf(i,d)},s={get customer(){return t.auth.customer},get authenticated(){return t.auth.authenticated},requestMagicLink:i=>t.auth.requestMagicLink(i),exchange:i=>t.auth.exchange(i),logout:()=>t.auth.logout()},n={redeem:i=>t.presale.redeem(i)};return{getEventsManager:()=>r,getCartManager:()=>o,getOrdersManager:()=>c,getAuthManager:()=>s,getPresaleManager:()=>n,on:(i,d)=>t.on(i,d),off:(i,d)=>t.off(i,d),event:i=>({openModal:(d={})=>t.emit("ui:event-modal-requested",{eventId:i,...d})}),checkout:{openModal:(i={})=>t.emit("ui:checkout-requested",i),closeModal:()=>t.emit("ui:modal-close-requested")},closeModal:()=>t.emit("ui:modal-close-requested")}}var F=class{constructor(){this.handlers=new Map}on(e,a){return this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(a),()=>this.off(e,a)}off(e,a){var r;(r=this.handlers.get(e))==null||r.delete(a)}emit(e,a){var r;(r=this.handlers.get(e))==null||r.forEach(o=>{try{o(a)}catch(c){console.error(`[live] handler for ${e} threw`,c)}})}};var oe="tl-theme-vars";function ne(t){if(!t||typeof document=="undefined")return;let e=Object.entries(Z(t)).map(([r,o])=>`${r}: ${o};`),a=document.getElementById(oe);a||(a=document.createElement("style"),a.id=oe,document.head.appendChild(a)),a.textContent=`:root {
1
+ "use strict";var TicketlayerLive=(()=>{var q=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var ce=Object.getOwnPropertyNames;var ue=Object.prototype.hasOwnProperty;var de=(t,e)=>{for(var a in e)q(t,a,{get:e[a],enumerable:!0})},le=(t,e,a,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of ce(e))!ue.call(t,o)&&o!==a&&q(t,o,{get:()=>e[o],enumerable:!(r=ie(e,o))||r.enumerable});return t};var fe=t=>le(q({},"__esModule",{value:!0}),t);var ve={};de(ve,{TicketlayerLive:()=>v,boot:()=>ae,createLiveClient:()=>B});var z="@ticketlayer/live",j="1.0.0";var K="2026-06-13";function me(){var e,a,r;let t=globalThis;return((e=t.navigator)==null?void 0:e.product)==="ReactNative"?"react-native":typeof t.window!="undefined"&&typeof t.document!="undefined"?"browser":(r=(a=t.process)==null?void 0:a.versions)!=null&&r.node?`node/${t.process.versions.node}`:t.EdgeRuntime?"edge":"unknown"}var he=`${z.replace(/^@/,"").replace("/","-")}/${j} (${me()})`;function ge(){let t=null;return{get:()=>t,set:e=>{t=e},clear:()=>{t=null}}}var _=class extends Error{constructor(e,a,r){super(e),this.code=a,this.status=r,this.name="LiveAPIError"}},N=class{constructor(e){var a,r,o,c;this.salesListings={list:async()=>await this.request("/sales/listings",{method:"GET"})},this.salesCustomerAuth={magicLink:async s=>(await this.request("/sales/customer-auth/magic-link",{method:"POST",body:JSON.stringify(s)})).sent},this.salesCustomerTokens={create:async s=>await this.request("/sales/customer-tokens",{method:"POST",body:JSON.stringify(s)}),refresh:async()=>await this.request("/sales/customer-tokens/refresh",{method:"POST"})},this.salesCarts={create:async s=>(await this.request("/sales/carts",{method:"POST",body:JSON.stringify(s)})).cart,get:async s=>(await this.request(`/sales/carts/${s}`,{method:"GET"})).cart,addItem:async(s,n)=>(await this.request(`/sales/carts/${s}/items`,{method:"POST",body:JSON.stringify(n)})).cart,removeItem:async(s,n)=>(await this.request(`/sales/carts/${s}/items/${n}`,{method:"DELETE"})).cart,checkout:async(s,n)=>await this.request(`/sales/carts/${s}/checkout`,{method:"POST",body:JSON.stringify(n)})},this.salesMyOrders={list:async()=>(await this.request("/sales/my-orders",{method:"GET"})).orders},this.salesOrders={get:async s=>(await this.request(`/sales/orders/${s}`,{method:"GET"})).order,ticketPdf:async(s,n)=>await this.request(`/sales/orders/${s}/passes/${n}/ticket.pdf`,{method:"GET"})},this.salesOrderPayments={create:async(s,n)=>(await this.request(`/sales/orders/${s}/payments`,{method:"POST",body:JSON.stringify(n)})).payment},this.salesRefundRequests={create:async(s,n)=>(await this.request(`/sales/orders/${s}/refund-requests`,{method:"POST",body:JSON.stringify(n)})).request},this.salesCustomers={create:async s=>(await this.request("/sales/customers",{method:"POST",body:JSON.stringify(s)})).customer,get:async s=>(await this.request(`/sales/customers/${s}`,{method:"GET"})).customer,update:async(s,n)=>(await this.request(`/sales/customers/${s}`,{method:"PATCH",body:JSON.stringify(n)})).customer},this.salesPresaleCodes={redeem:async s=>await this.request("/sales/presale-codes/redeem",{method:"POST",body:JSON.stringify(s)})},this.sales={resolveChannel:async s=>{let n=new URLSearchParams;(s==null?void 0:s.domain)!==void 0&&n.append("domain",String(s.domain));let i=n.toString(),d=i?`/sales/channel?${i}`:"/sales/channel";return await this.request(d,{method:"GET"})},get:async s=>(await this.request(`/sales/events/${s}`,{method:"GET"})).event,getTheme:async()=>(await this.request("/sales/theme",{method:"GET"})).theme},this.session={start:async s=>await this.request("/session",{method:"POST",body:JSON.stringify(s)}),current:async()=>await this.request("/session",{method:"GET"}),end:async()=>await this.request("/session",{method:"DELETE"}),attachOrderAccess:async s=>await this.request("/session/order-access",{method:"POST",body:JSON.stringify(s)})},this.queue={status:async()=>await this.request("/queue/status",{method:"GET"}),join:async()=>await this.request("/queue/join",{method:"POST"})},this.baseUrl=e.baseUrl.replace(/\/$/,""),this.sessionMode=(a=e.sessionMode)!=null?a:"cookie",this.publishableKey=e.publishableKey,this.tokenStorage=(r=e.tokenStorage)!=null?r:ge(),this.apiVersion=(o=e.apiVersion)!=null?o:K,this.headers=(c=e.headers)!=null?c:{}}async setSessionToken(e){await this.tokenStorage.set(e)}async getSessionToken(){return this.tokenStorage.get()}async clearSession(){await this.tokenStorage.clear()}async request(e,a={}){var i,d,u;let r=`${this.baseUrl}${e}`,o={"Content-Type":"application/json","TL-Version":this.apiVersion,"TL-Client":he,...this.headers,...a.headers};if(this.publishableKey&&(o.Authorization=`Bearer ${this.publishableKey}`),this.sessionMode==="token"){let l=await this.tokenStorage.get();l&&(o["X-Live-Session"]=l)}let c=await fetch(r,{...a,headers:o,credentials:this.sessionMode==="cookie"?"include":"same-origin"}),s=await c.text(),n=s?JSON.parse(s):null;if(!c.ok){let l=(i=n==null?void 0:n.error)!=null?i:{};throw new _((d=l.message)!=null?d:`Request failed (${c.status})`,(u=l.code)!=null?u:"REQUEST_FAILED",c.status)}return n&&n.status==="success"&&n.data!==void 0?n.data:n}};var P="Ticketlayer",pe="ticketlayer:ready";function ye(t){let e=window;if(e[P])return e[P];let a={client:null,sdk:null,version:t,_resolvers:[],getClient(){return this.client},getSDK(){return this.sdk},ready(){return this.client?Promise.resolve(this.client):new Promise(r=>this._resolvers.push(r))}};return e[P]=a,a}function J(t,e,a){if(typeof window=="undefined")return;let r=ye(a);r.client&&r.client!==t&&console.warn("[live] A Ticketlayer client is already on window.Ticketlayer; replacing it. Create a single client per page."),r.client=t,r.sdk=e;let o=r._resolvers;r._resolvers=[],o.forEach(c=>c(t)),window.dispatchEvent(new CustomEvent(pe,{detail:t}))}var V="https://cdn.ticketlayer.com/elements/v1/ticketlayer-elements/ticketlayer-elements.esm.js",be="tl-event-list",Y=new Map,we=/\/v\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?\//,ke=/^(?:sha(?:256|384|512)-[A-Za-z0-9+/]+={0,2})(?:\s+sha(?:256|384|512)-[A-Za-z0-9+/]+={0,2})*$/,M=class extends Error{constructor(e){super(`[live] ${e}`),this.name="ElementsIntegrityError"}},H=!1;function X(t={}){var s,n;if(!t.elements)return Promise.resolve();let e=((s=t.elementsIntegrity)==null?void 0:s.trim())||void 0;if(e&&!t.elementsUrl)throw new M("elementsIntegrity was given without elementsUrl. The default Elements URL is a floating path that every release rewrites, so a hash pinned to it cannot keep matching. Pass the pinned elementsUrl that the hash is for (see /versions.json on the CDN).");if(e&&!ke.test(e))throw new M(`elementsIntegrity is not a subresource integrity value: ${JSON.stringify(t.elementsIntegrity)}. Expected one or more of sha256-, sha384- or sha512- followed by base64, as /versions.json publishes it.`);if(t.elementsUrl&&!e&&we.test(t.elementsUrl))throw new M(`elementsUrl ${t.elementsUrl} names an exact version, which is the CDN's pinned tier, but no elementsIntegrity came with it. A pinned URL exists to be verified; loading it unchecked would be weaker than the floating path. Pass the sha384 from /versions.json as elementsIntegrity (data-elements-integrity on the embed script), or use a floating /v1/ URL.`);if(typeof window=="undefined"||typeof document=="undefined")return Promise.resolve();let a=window.customElements;if(a!=null&&a.get(be))return Promise.resolve();let r=(n=t.elementsUrl)!=null?n:V;!t.elementsUrl&&!H&&(H=!0,console.warn(`[live] Loading Elements unverified from the floating default ${V}. Floating paths are rewritten by every release and cannot carry a subresource integrity hash. To verify the bundle, pin it: set elementsUrl (data-elements-url) to the pinned path from /versions.json and elementsIntegrity (data-elements-integrity) to the sha384 beside it.`));let o=Y.get(r);if(o)return o;let c=new Promise((i,d)=>{let u=document.createElement("script");u.type="module",u.src=r,u.async=!0,e&&(u.integrity=e,u.crossOrigin="anonymous"),u.dataset.ticketlayerElements="auto",u.onload=()=>i(),u.onerror=()=>d(new Error(`[live] Failed to load Elements from ${r}`)),document.head.appendChild(u)});return Y.set(r,c),c}var U={"color-primary":"primary","color-primary-foreground":"primary-foreground","color-secondary":"secondary","color-secondary-foreground":"secondary-foreground","color-accent":"accent","color-accent-foreground":"accent-foreground","color-background":"background","color-foreground":"foreground","color-card":"card","color-muted":"muted","color-muted-foreground":"muted-foreground","color-border":"border","color-border-hover":"border-hover","color-input":"input","color-ring":"ring","color-success":"success","color-success-foreground":"success-foreground","color-warning":"warning","color-warning-foreground":"warning-foreground","color-warning-bg":"warning-bg","color-error":"error",destructive:"error","color-destructive":"error","color-error-foreground":"error-foreground","destructive-foreground":"error-foreground","color-destructive-foreground":"error-foreground","color-error-bg":"error-bg","destructive-bg":"error-bg","color-destructive-bg":"error-bg","color-info":"info","color-info-foreground":"info-foreground","color-info-bg":"info-bg","base-size":"font-size-base",radius:"radius-md"},A={primary:"#6366f1","primary-foreground":"#ffffff",secondary:"#f3f4f6","secondary-foreground":"#111827",accent:"#ec4899","accent-foreground":"#ffffff",background:"#ffffff",foreground:"#111827",card:"#ffffff",muted:"#f9fafb","muted-foreground":"#6b7280",border:"#e5e7eb","border-hover":"#9ca3af",input:"#e5e7eb",ring:"#6366f1",success:"#10b981","success-foreground":"#ffffff",warning:"#f59e0b","warning-foreground":"#ffffff","warning-bg":"#fef3c7",error:"#ef4444","error-foreground":"#ffffff","error-bg":"#fee2e2",info:"#3b82f6","info-foreground":"#ffffff","info-bg":"#dbeafe","font-family":"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif","font-family-mono":"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace","font-size-base":"16px","font-scale":"1.25","radius-none":"0px","radius-sm":"0.25rem","radius-md":"0.5rem","radius-lg":"0.75rem","radius-full":"9999px","spacing-1":"0.25rem","spacing-2":"0.5rem","spacing-3":"0.75rem","spacing-4":"1rem","spacing-5":"1.25rem","spacing-6":"1.5rem","spacing-8":"2rem","duration-fast":"120ms","duration-normal":"200ms","duration-slow":"320ms","easing-standard":"cubic-bezier(0.2, 0, 0, 1)","easing-emphasised":"cubic-bezier(0.3, 0, 0, 1)"};var $={primary:"colors.primary","primary-foreground":"colors.primaryForeground",secondary:"colors.secondary","secondary-foreground":"colors.secondaryForeground",accent:"colors.accent","accent-foreground":"colors.accentForeground",background:"colors.background",foreground:"colors.foreground",muted:"colors.muted","muted-foreground":"colors.mutedForeground",border:"colors.border",input:"colors.input",ring:"colors.ring",success:"colors.success","success-foreground":"colors.successForeground",warning:"colors.warning","warning-foreground":"colors.warningForeground",error:"colors.destructive","error-foreground":"colors.destructiveForeground","font-family":"typography.fontFamily","font-family-mono":"typography.fontFamilyMono","font-size-base":"typography.baseSize","font-scale":"typography.scaleRatio","radius-none":"shape.radiusNone","radius-sm":"shape.radiusSm","radius-md":"shape.radiusMd","radius-lg":"shape.radiusLg","radius-full":"shape.radiusFull"};function R(t){return`--tl-${t}`}function Z(t){var a;let e={};if(!t)return e;for(let[r,o]of Object.entries($)){let[c,s]=o.split("."),n=(a=t[c])==null?void 0:a[s];n==null||n===""||(e[R(r)]=String(n))}for(let[r,o]of Object.entries(U)){let c=e[R(o)];c!==void 0&&(e[R(r)]=c)}return e}var Q="tl-checkout-overlay";function W(t,e={}){if(typeof window=="undefined"||typeof document=="undefined")return()=>{};let a=null,r=()=>{var n;(n=document.getElementById(Q))==null||n.remove(),a&&(window.removeEventListener("message",a),a=null)},o=async n=>{let i=await t.getSessionToken().catch(()=>null),d=(e.embedBaseUrl||window.location.origin).replace(/\/$/,""),u=new URLSearchParams;i&&u.set("session",i),u.set("parent_origin",window.location.origin);let l=`${d}/embed/checkout?${u.toString()}`,f=new URL(l).origin;r();let g=document.createElement("div");g.id=Q,g.style.cssText="position:fixed;inset:0;z-index:2147483647;background:rgba(15,23,42,0.55);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:16px;";let h=document.createElement("div");h.style.cssText="width:100%;max-width:960px;display:flex;flex-direction:column;gap:10px;";let b=document.createElement("iframe");b.src=l,b.allow="payment",b.style.cssText=`width:100%;height:88vh;max-height:760px;border:1px solid var(--tl-border, ${A.border});border-radius:16px;background:#fff;box-shadow:0 24px 64px rgba(0,0,0,0.45);`,h.appendChild(b),g.appendChild(h),g.addEventListener("click",w=>{var m;(w.target===g||w.target===h)&&(r(),(m=n.onClose)==null||m.call(n))}),document.body.appendChild(g),a=w=>{var I,x,C;if(w.origin!==f)return;let m=w.data;if(!(!m||typeof m!="object"))switch(m.type){case"tl:complete":{let S=m.order&&typeof m.order=="object"?m.order:{},O=m.orderId?{...S,id:m.orderId,orderNumber:m.orderReference,...m.accessToken?{accessToken:m.accessToken}:{}}:m.order;(I=n.onComplete)==null||I.call(n,O),t.emit("checkout:completed",O),r();break}case"tl:close":case"tl:cancel":(x=n.onClose)==null||x.call(n),r();break;case"tl:error":{let S=new Error(m.message||m.code||"Checkout failed");m.code&&(S.code=m.code),(C=n.onError)==null||C.call(n,S);break}}},window.addEventListener("message",a)},c=t.on("ui:checkout-requested",n=>void o(n!=null?n:{})),s=t.on("ui:modal-close-requested",()=>r());return()=>{c(),s(),r()}}function ee(t,e={}){if(typeof window=="undefined"||typeof document=="undefined")return()=>{};let a=e.tag||"tl-buy-modal",r=null,o=null,c=()=>{r&&(r.remove(),r=null),o=null},s=d=>{if(!(d!=null&&d.eventId))return;c(),o=d;let u=document.createElement(a);u.setAttribute("event-id",d.eventId),d.occurrenceId&&u.setAttribute("occurrence-id",d.occurrenceId),u.addEventListener("tlClose",()=>{var f;let l=o;c(),(f=l==null?void 0:l.onClose)==null||f.call(l)}),u.addEventListener("tlError",l=>{var g,h;let f=((g=l.detail)==null?void 0:g.message)||"Could not load this event";(h=o==null?void 0:o.onError)==null||h.call(o,new Error(f))}),u.addEventListener("tlCheckout",()=>{let l=o;c(),t.emit("ui:checkout-requested",{onComplete:l==null?void 0:l.onComplete,onError:l==null?void 0:l.onError,onClose:l==null?void 0:l.onClose})}),document.body.appendChild(u),r=u},n=t.on("ui:event-modal-requested",d=>s(d!=null?d:{})),i=t.on("ui:modal-close-requested",()=>c());return()=>{n(),i(),c()}}var re=t=>t&&typeof t=="object"?t:{};function k(t){return typeof t=="number"?Number.isInteger(t)?t:null:typeof t=="string"&&/^-?\d+$/.test(t)?Number(t):null}var D=t=>typeof t.type=="string"?t.type:"ticket",Ee=t=>!["fee","tax","discount"].includes(D(t));function Se(t,e){return t===null?e:t>0||e}function te(t){var w,m,I,x,C,S,O,G;let e=re(t),a=Array.isArray(e.items)?e.items.map(re):[],r=(m=(w=k(e.itemsSubtotal))!=null?w:k(e.subtotal))!=null?m:a.filter(Ee).reduce((y,L)=>{var E;return y+((E=k(L.subtotal))!=null?E:0)},0),o=a.filter(y=>D(y)==="fee"),c=o.length?o.reduce((y,L)=>{var E;return y+((E=k(L.subtotal))!=null?E:0)},0):null,s=(x=(I=k(e.totalFees))!=null?I:k(e.fees))!=null?x:c,n=typeof e.feeLabel=="string"&&e.feeLabel?e.feeLabel:null,i=o.map(y=>y.name).find(y=>typeof y=="string"&&y),d=(C=n!=null?n:i)!=null?C:null,u=a.filter(y=>D(y)==="discount"),l=u.length?u.reduce((y,L)=>{var E;return y+Math.abs((E=k(L.subtotal))!=null?E:0)},0):null,f=(O=(S=k(e.totalDiscounts))!=null?S:k(e.discount))!=null?O:l,g=(G=k(e.totalTax))!=null?G:0,h=k(e.total),b=h!=null?h:r+(s!=null?s:0)+g-(f!=null?f:0);return{currency:typeof e.currency=="string"?e.currency:null,subtotal:r,fees:s!=null?s:0,discount:f!=null?f:0,total:b,hasFees:Se(s,d!==null||o.length>0),feeLabel:d,totalFromServer:h!==null}}var T=t=>{var c;if(!t||typeof t!="object")return t;let e=t,a=((c=e.items)!=null?c:[]).map(s=>{var u,l,f;let n=s,i=(u=n.quantity)!=null?u:0,d=(l=n.subtotal)!=null?l:n.unitPrice*i;return{...n,totalPrice:(f=n.totalPrice)!=null?f:d}}),r=a.reduce((s,n)=>{var i;return s+((i=n.quantity)!=null?i:0)},0),o=te(e);return{...e,items:a,itemCount:r,subtotal:o.subtotal,fees:o.fees,discount:o.discount,total:o.total,hasFees:o.hasFees,feeLabel:o.feeLabel}};function se(t){let e=new Map,a=(i,d)=>{let u=e.get(i);if(!(u!=null&&u.categoryId))throw new Error(`[live] No category known for ticket type ${i}. Load the occurrence's ticket types (getTicketTypes) before adding it to the cart.`);return{categoryId:u.categoryId,occurrenceId:d||u.occurrenceId}},r={async list(i){var l;let d=await t.events.list(),u=((l=d==null?void 0:d.listings)!=null?l:[]).map(f=>{var g,h,b;return{id:(g=f.eventId)!=null?g:f.id,name:(h=f.name)!=null?h:"",...f.shortDescription?{shortDescription:f.shortDescription}:{},...f.imageUrl?{imageUrl:f.imageUrl}:{},...f.venueName?{venue:{id:"",name:f.venueName,city:(b=f.venueCity)!=null?b:""}}:{},...f.nextOccurrenceAt?{nextOccurrence:{startsAt:f.nextOccurrenceAt}}:{},availabilityStatus:"available"}});return i!=null&&i.limit&&(u=u.slice(0,i.limit)),{items:u}},get:i=>t.events.get(i),async getTicketTypes(i,d){var g,h,b,w;let u=await t.events.get(i),l=(b=(g=u==null?void 0:u.occurrences)==null?void 0:g.find(m=>m.id===d))!=null?b:(h=u==null?void 0:u.occurrences)==null?void 0:h[0];return((w=l==null?void 0:l.ticketTypes)!=null?w:[]).map(m=>(l&&e.set(m.ticketTypeId,{categoryId:m.categoryId,occurrenceId:l.id}),{id:m.ticketTypeId,name:m.ticketTypeName,description:m.description,price:m.unitPrice,currency:m.currency,categoryId:m.categoryId,categoryName:m.categoryName,maxPerOrder:10,available:999}))}},o={get:async()=>{var i;return T((i=t.cart.current)!=null?i:await t.cart.refresh())},on:(i,d)=>t.on(i,u=>d(i==="cart:updated"?T(u):u)),off:(i,d)=>t.off(i,d),addItem:async(i,d,u)=>{let{categoryId:l,occurrenceId:f}=a(i,u);return T(await t.cart.add({eventOccurrenceId:f,categoryId:l,ticketTypeId:i,quantity:d}))},addItems:async i=>{let d=t.cart.current;for(let u of i)d=await o.addItem(u.ticketTypeId,u.quantity,u.occurrenceId);return d},removeItem:async i=>T(await t.cart.remove(i)),addSeat:async(i,d,u)=>{let{categoryId:l,occurrenceId:f}=a(d,u);return T(await t.cart.add({eventOccurrenceId:f,categoryId:l,ticketTypeId:d,eventLayoutSeatIds:[i]}))},removeSeat:async(i,d)=>{var u;return console.warn("[live] removeSeat is a no-op until cart items expose seat ids; use removeItem(itemId)."),T((u=await t.cart.refresh())!=null?u:t.cart.current)}},c={mine:()=>t.orders.mine(),get:i=>t.orders.get(i),ticketPdf:(i,d)=>t.orders.ticketPdf(i,d)},s={get customer(){return t.auth.customer},get authenticated(){return t.auth.authenticated},requestMagicLink:i=>t.auth.requestMagicLink(i),exchange:i=>t.auth.exchange(i),logout:()=>t.auth.logout()},n={redeem:i=>t.presale.redeem(i)};return{getEventsManager:()=>r,getCartManager:()=>o,getOrdersManager:()=>c,getAuthManager:()=>s,getPresaleManager:()=>n,on:(i,d)=>t.on(i,d),off:(i,d)=>t.off(i,d),event:i=>({openModal:(d={})=>t.emit("ui:event-modal-requested",{eventId:i,...d})}),checkout:{openModal:(i={})=>t.emit("ui:checkout-requested",i),closeModal:()=>t.emit("ui:modal-close-requested")},closeModal:()=>t.emit("ui:modal-close-requested")}}var F=class{constructor(){this.handlers=new Map}on(e,a){return this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(a),()=>this.off(e,a)}off(e,a){var r;(r=this.handlers.get(e))==null||r.delete(a)}emit(e,a){var r;(r=this.handlers.get(e))==null||r.forEach(o=>{try{o(a)}catch(c){console.error(`[live] handler for ${e} threw`,c)}})}};var oe="tl-theme-vars";function ne(t){if(!t||typeof document=="undefined")return;let e=Object.entries(Z(t)).map(([r,o])=>`${r}: ${o};`),a=document.getElementById(oe);a||(a=document.createElement("style"),a.id=oe,document.head.appendChild(a)),a.textContent=`:root {
2
2
  ${e.join(`
3
3
  `)}
4
4
  }`}var p=(t,e)=>t&&typeof t=="object"&&!Array.isArray(t)&&e in t?t[e]:t,v=class{constructor(e,a){this.emitter=new F,this._sessionStarted=!1,this._sessionStarting=null,this._session={channelId:null,customer:null,authenticated:!1},this._cart=null,this._cartId=null,this.client=e,this.sessionMode=a.sessionMode,this.publishableKey=a.publishableKey,this.domain=a.domain,this.baseUrl=a.baseUrl.replace(/\/$/,"");let r=this;this.events={list:()=>r.client.salesListings.list(),get:o=>r.client.sales.get(o).then(c=>p(c,"event"))},this.theme={get:()=>r.client.sales.getTheme().then(o=>p(o,"theme")),apply:async()=>{let o=await r.theme.get();return ne(o),o}},this.cart={get current(){return r._cart},get id(){return r._cartId},ensure:async()=>{var o;if(!r._cartId){await r.ensureSession();let c=await r.client.salesCarts.create({}),s=p(c,"cart");r._cartId=(o=s==null?void 0:s.id)!=null?o:null,r._setCart(s)}return r._cartId},add:async o=>{let c=await r.cart.ensure();try{let s=await r.client.salesCarts.addItem(c,o);return r._setCart(p(s,"cart")),r._cart}catch(s){if(!r._isCartGone(s))throw s;r._resetCart();let n=await r.cart.ensure(),i=await r.client.salesCarts.addItem(n,o);return r._setCart(p(i,"cart")),r._cart}},remove:async o=>{if(!r._cartId)return r._cart;try{let c=await r.client.salesCarts.removeItem(r._cartId,o);return r._setCart(p(c,"cart")),r._cart}catch(c){if(!r._isCartGone(c))throw c;return r._resetCart(),r._cart}},refresh:async()=>{if(!r._cartId)return r._cart;try{let o=await r.client.salesCarts.get(r._cartId);return r._setCart(p(o,"cart")),r._cart}catch(o){if(!r._isCartGone(o))throw o;return r._resetCart(),r._cart}},checkout:async(o={})=>{if(!r._cartId)throw new Error("No cart to check out");try{let c=await r.client.salesCarts.checkout(r._cartId,o);return r._cartId=null,r._setCart(null),r.emitter.emit("checkout:completed",p(c,"order")),c}catch(c){throw r._isCartGone(c)?(r._resetCart(),new _("Your cart has expired. Please add your tickets again.","CART_EXPIRED",409)):c}}},this.auth={get customer(){return r._session.customer},get authenticated(){return r._session.authenticated},requestMagicLink:o=>r.client.salesCustomerAuth.magicLink(o),exchange:async o=>{var n;await r.ensureSession();let c=typeof o=="string"?{type:"magic_link",code:o}:o,s=await r.client.salesCustomerTokens.create({proof:c});return r._session={...r._session,customer:(n=p(s,"customer"))!=null?n:null,authenticated:!0},r.emitter.emit("auth:changed",r._session),s},logout:async()=>{await r.client.session.end().catch(()=>{}),r._session={channelId:r._session.channelId,customer:null,authenticated:!1},r._cart=null,r._cartId=null,r.emitter.emit("auth:changed",r._session)}},this.orders={mine:()=>r.client.salesMyOrders.list().then(o=>p(o,"orders")),get:o=>r.client.salesOrders.get(o).then(c=>p(c,"order")),ticketPdf:async(o,c)=>{let s={};if(r.publishableKey&&(s.Authorization=`Bearer ${r.publishableKey}`),r.sessionMode==="token"){let i=await r.client.getSessionToken();i&&(s["X-Live-Session"]=i)}let n=await fetch(`${r.baseUrl}/sales/orders/${o}/passes/${c}/ticket.pdf`,{headers:s,credentials:r.sessionMode==="cookie"?"include":"same-origin"});if(!n.ok)throw new _(`Failed to download ticket (${n.status})`,"TICKET_PDF_FAILED",n.status);return n.blob()}},this.payments={begin:(o,c={})=>r.client.salesOrderPayments.create(o,c).then(s=>p(s,"payment"))},this.presale={redeem:async o=>{let c=await r.client.salesPresaleCodes.redeem({code:o.trim()});return r._cartId&&await r.cart.refresh().catch(()=>{}),c}},this.queue={status:()=>r.client.queue.status(),join:()=>r.client.queue.join()}}on(e,a){return this.emitter.on(e,a)}off(e,a){this.emitter.off(e,a)}emit(e,a){this.emitter.emit(e,a)}get session(){return this._session}get hasSession(){return this._sessionStarted}async ensureSession(){if(!this._sessionStarted){if(this._sessionStarting)return this._sessionStarting;this._sessionStarting=(async()=>{let e={};this.sessionMode==="token"&&this.publishableKey?e.channelKey=this.publishableKey:this.domain?e.domain=this.domain:this.publishableKey&&(e.channelKey=this.publishableKey);let a=await this.client.session.start(e);if(this.sessionMode==="token"){let r=p(a,"sessionToken");r&&await this.client.setSessionToken(r)}this._sessionStarted=!0,await this.refreshSession()})();try{await this._sessionStarting}finally{this._sessionStarting=null}}}async start(e={}){return e.domain&&(this.domain=e.domain),this.ensureSession()}async resumeIfExists(){if(this._sessionStarted)return!0;try{return await this.refreshSession(),this._sessionStarted=!0,!0}catch{return!1}}async resume(e){await this.client.setSessionToken(e),this._sessionStarted=!0,await this.refreshSession()}getSessionToken(){return this.client.getSessionToken()}async refreshSession(){var r,o,c,s;let e=await this.client.session.current();this._session={channelId:(o=(r=p(e,"channel"))==null?void 0:r.id)!=null?o:null,customer:(c=p(e,"customer"))!=null?c:null,authenticated:!!p(e,"authenticated")};let a=(s=p(e,"cartId"))!=null?s:null;a&&(this._cartId=a,await this.cart.refresh()),this.emitter.emit("session:changed",this._session)}_resetSessionStarted(){this._sessionStarted=!1,this._sessionStarting=null}_setCart(e){this._cart=e!=null?e:null,this.emitter.emit("cart:updated",this._cart)}_isCartGone(e){return e instanceof _?e.code==="CART_EXPIRED"||e.code==="CART_NOT_ACTIVE"||e.code==="CART_NOT_FOUND"||e.status===404:!1}_resetCart(){this._cartId=null,this._setCart(null)}};async function _e(t,e){var a;try{let r=await fetch(`${t.replace(/\/$/,"")}/channel?domain=${encodeURIComponent(e)}`,{headers:{accept:"application/json"}});if(!r.ok)return;let o=await r.json();return(a=o==null?void 0:o.data)==null?void 0:a.publishableKey}catch{return}}async function B(t){var i,d,u;let e=(i=t.domain)!=null?i:typeof window!="undefined"?window.location.host:void 0,a=t.publishableKey;!a&&!t.sessionToken&&e&&(a=await _e(t.baseUrl,e));let r=!!t.publishableKey||!!t.sessionToken,o=(d=t.sessionMode)!=null?d:r?"token":"cookie",c=new N({...t,sessionMode:o,...a?{publishableKey:a}:{}}),s=new v(c,{sessionMode:o,baseUrl:t.baseUrl,...a?{publishableKey:a}:{},...e?{domain:e}:{}});t.publish!==!1&&typeof window!="undefined"&&J(s,se(s),K),((u=t.checkout)==null?void 0:u.mode)==="modal"&&typeof window!="undefined"&&W(s,t.checkout),t.buyModal!==!1&&t.publish!==!1&&typeof window!="undefined"&&ee(s);let n=X(t).catch(l=>{console.error("[live] Elements auto-load failed",l)});return t.autoStart!==!1&&(t.sessionToken?await s.resume(t.sessionToken):o==="cookie"&&typeof window!="undefined"&&await s.resumeIfExists().catch(()=>{}),t.applyTheme!==!1&&typeof window!="undefined"&&await s.theme.apply().catch(()=>{})),await n,s}function Te(){var a;if(typeof document=="undefined")return null;let t=(a=document.currentScript)!=null?a:document.querySelector("script[data-publishable-key]");if(!t)return null;let e=t.dataset;return{publishableKey:e.publishableKey,apiUrl:e.apiUrl,elementsUrl:e.elementsUrl,elementsIntegrity:e.elementsIntegrity,checkoutBase:e.checkoutBase,autoElements:e.elements!=="false"}}function ae(){var r,o;if(typeof window=="undefined")return Promise.resolve(null);let t=window;if(t.__tlBooted)return(o=(r=t.ticketlayer)==null?void 0:r.ready)!=null?o:Promise.resolve(null);let e=Te();if(!(e!=null&&e.publishableKey))return Promise.resolve(null);if(!e.apiUrl)return console.error("[ticketlayer] Missing data-api-url on the embed script; cannot auto-init."),Promise.resolve(null);t.__tlBooted=!0;let a=B({baseUrl:e.apiUrl,publishableKey:e.publishableKey,elements:e.autoElements,...e.elementsUrl?{elementsUrl:e.elementsUrl}:{},...e.elementsIntegrity?{elementsIntegrity:e.elementsIntegrity}:{},checkout:{mode:"modal",...e.checkoutBase?{embedBaseUrl:e.checkoutBase}:{}}}).catch(c=>(console.error("[ticketlayer] Failed to initialise:",c),null));return t.ticketlayer={ready:a},a}ae();return fe(ve);})();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/auto.ts", "../src/version.ts", "../src/client.ts", "../src/state/registry.ts", "../src/state/loadElements.ts", "../../theme/src/generated/tokens.ts", "../../theme/src/index.ts", "../src/state/checkoutModal.ts", "../src/state/buyModal.ts", "../src/core/cartTotals.ts", "../src/elements.ts", "../src/state/emitter.ts", "../src/state/theme.ts", "../src/core/liveClient.ts", "../src/createLiveClient.ts"],
4
- "sourcesContent": ["/**\n * Drop-in auto-init for the CDN/UMD build (`dist/ticketlayer.js`).\n *\n * This is the \"one line of code\" embed - what a Webflow/Framer/any site drops in:\n *\n * <script src=\"https://cdn.ticketlayer.com/v1/ticketlayer.js\"\n * data-publishable-key=\"tlpk_...\"\n * data-api-url=\"https://live-api.ticketlayer.com\"\n * data-checkout-base=\"https://checkout.ticketlayer.com\"></script>\n *\n * `data-elements-url` and `data-elements-integrity` travel together and are\n * what an installed site is pinned with (the Webflow Integration Service\n * writes both). An exact-version `data-elements-url` without the hash is\n * refused rather than loaded unverified - see state/loadElements.ts.\n *\n * On load it boots a Live client from the script tag's data-* attributes:\n * publishes `window.Ticketlayer` (so `@ticketlayer/elements` bind), injects the\n * Elements bundle, and installs the hosted iframe checkout modal. Plain HTML\n * custom-element tags (`<tl-event-list>`, `<tl-buy-tickets-button event-id>`)\n * then just work - no bundler, no framework.\n *\n * The IIFE also exposes the SDK on `window.TicketlayerLive` (createLiveClient,\n * boot) for sites that want manual control instead of the data-attribute path.\n *\n * NOTE: index.ts (the npm/bundler entry) does NOT import this module, so only\n * the CDN build auto-boots. Booting is idempotent and a no-op without a key.\n */\nimport { createLiveClient, TicketlayerLive } from './createLiveClient.js';\n\ninterface BootWindow {\n Ticketlayer?: unknown;\n ticketlayer?: { ready: Promise<TicketlayerLive | null> };\n __tlBooted?: boolean;\n}\n\ninterface DropInConfig {\n publishableKey?: string;\n apiUrl?: string;\n elementsUrl?: string;\n elementsIntegrity?: string;\n checkoutBase?: string;\n autoElements: boolean;\n}\n\n/** Read config off the embedding <script> tag's data-* attributes. */\nfunction readConfig(): DropInConfig | null {\n if (typeof document === 'undefined') return null;\n const el =\n (document.currentScript as HTMLScriptElement | null) ??\n document.querySelector<HTMLScriptElement>('script[data-publishable-key]');\n if (!el) return null;\n const d = el.dataset;\n return {\n publishableKey: d.publishableKey,\n apiUrl: d.apiUrl,\n elementsUrl: d.elementsUrl,\n elementsIntegrity: d.elementsIntegrity,\n checkoutBase: d.checkoutBase,\n // Inject @ticketlayer/elements unless explicitly opted out (data-elements=\"false\").\n autoElements: d.elements !== 'false',\n };\n}\n\n/**\n * Boot a Live client from the script tag's data-* attributes. Returns the\n * client (or null when there's no publishable key / not in a browser). Safe to\n * call once; subsequent calls no-op.\n */\nexport function boot(): Promise<TicketlayerLive | null> {\n if (typeof window === 'undefined') return Promise.resolve(null);\n const w = window as unknown as BootWindow;\n if (w.__tlBooted) return w.ticketlayer?.ready ?? Promise.resolve(null);\n\n const cfg = readConfig();\n if (!cfg?.publishableKey) return Promise.resolve(null); // manual usage - nothing to boot\n if (!cfg.apiUrl) {\n console.error('[ticketlayer] Missing data-api-url on the embed script; cannot auto-init.');\n return Promise.resolve(null);\n }\n\n w.__tlBooted = true;\n const ready = createLiveClient({\n baseUrl: cfg.apiUrl,\n publishableKey: cfg.publishableKey,\n elements: cfg.autoElements,\n ...(cfg.elementsUrl ? { elementsUrl: cfg.elementsUrl } : {}),\n ...(cfg.elementsIntegrity ? { elementsIntegrity: cfg.elementsIntegrity } : {}),\n checkout: { mode: 'modal', ...(cfg.checkoutBase ? { embedBaseUrl: cfg.checkoutBase } : {}) },\n }).catch((err) => {\n console.error('[ticketlayer] Failed to initialise:', err);\n return null;\n });\n\n w.ticketlayer = { ready };\n return ready;\n}\n\n// Manual-use surface on the global (the IIFE's globalName is TicketlayerLive).\nexport { createLiveClient, TicketlayerLive };\n\n// Auto-boot on load.\nvoid boot();\n", "/**\n * GENERATED FILE - written from package.json by the prebuild script.\n * Do not edit; do not commit.\n */\nexport const SDK_NAME = \"@ticketlayer/live\";\nexport const SDK_VERSION = \"0.4.0\";\n", "/**\n * GENERATED FILE - do not edit by hand.\n * @ticketlayer/live client generated from the backstage sales surface\n * (spec 1.0.0) + live-api (0.1.0)\n * by backstage-sdk-tooling 0.1.0 on 2026-09-15T10:18:42.096Z.\n * Regenerate with `tt sdk live`.\n */\nimport type { components } from './generated/types';\nimport { SDK_NAME, SDK_VERSION } from './version.js';\n\ntype AttachOrderAccessBody = components['schemas']['AttachOrderAccessBody'];\ntype CreateSalesOrderPaymentResponse = components['schemas']['CreateSalesOrderPaymentResponse'];\ntype CreateSalesRefundRequestResponse = components['schemas']['CreateSalesRefundRequestResponse'];\ntype CreateSessionBody = components['schemas']['CreateSessionBody'];\ntype GetSalesListingsResponse = components['schemas']['GetSalesListingsResponse'];\ntype GetSalesOrderResponse = components['schemas']['GetSalesOrderResponse'];\ntype ListMySalesOrdersResponse = components['schemas']['ListMySalesOrdersResponse'];\ntype RedeemSalesPresaleCodeResponse = components['schemas']['RedeemSalesPresaleCodeResponse'];\ntype SalesCartResponse = components['schemas']['SalesCartResponse'];\ntype SalesCheckoutResponse = components['schemas']['SalesCheckoutResponse'];\ntype SalesCustomerResponse = components['schemas']['SalesCustomerResponse'];\ntype SalesCustomerTokenResponse = components['schemas']['SalesCustomerTokenResponse'];\ntype SalesEventDetailResponse = components['schemas']['SalesEventDetailResponse'];\ntype SalesMagicLinkResponse = components['schemas']['SalesMagicLinkResponse'];\ntype SalesResolveChannelResponse = components['schemas']['SalesResolveChannelResponse'];\ntype SalesThemeResponse = components['schemas']['SalesThemeResponse'];\n\n/**\n * The dated API version (TL-Version) this SDK speaks. Stamped at generation\n * time; the Live/sales surface keeps serving this version's behaviour even as\n * the API evolves. See https://docs.ticketlayer.com/api/versions\n */\nexport const API_DATED_VERSION = '2026-06-13';\n\n/** Best-effort description of the JavaScript runtime, for the TL-Client header. */\nfunction describeRuntime(): string {\n const g = globalThis as Record<string, any>;\n if (g.navigator?.product === 'ReactNative') return 'react-native';\n if (typeof g.window !== 'undefined' && typeof g.document !== 'undefined') return 'browser';\n if (g.process?.versions?.node) return `node/${g.process.versions.node}`;\n if (g.EdgeRuntime) return 'edge';\n return 'unknown';\n}\n\n/**\n * Identifies this SDK build to the API, sent as the TL-Client request header:\n * `ticketlayer-live/<package version> (<runtime>)`. SDK_VERSION comes from\n * src/version.ts, which the package's prebuild writes from package.json so the\n * header always names the version npm published.\n */\nexport const SDK_CLIENT_HEADER = `${SDK_NAME.replace(/^@/, '').replace('/', '-')}/${SDK_VERSION} (${describeRuntime()})`;\n\n/** Pluggable token storage so the SDK runs in browser, React Native, etc. */\nexport interface LiveTokenStorage {\n get(): string | null | Promise<string | null>;\n set(token: string): void | Promise<void>;\n clear(): void | Promise<void>;\n}\n\n/** In-memory storage (default; embeds/SSR). */\nexport function memoryTokenStorage(): LiveTokenStorage {\n let token: string | null = null;\n return {\n get: () => token,\n set: (t) => {\n token = t;\n },\n clear: () => {\n token = null;\n },\n };\n}\n\nexport interface LiveClientConfig {\n /** Base URL of a Live deployment (or the sales surface directly). */\n baseUrl: string;\n /**\n * Session transport:\n * - 'cookie' (hosted web): the live_session httpOnly cookie travels\n * automatically with credentials: 'include'; no token is held client-side.\n * - 'token' (embeds / React Native / native): the session id is held by the\n * SDK and sent as the X-Live-Session header.\n */\n sessionMode?: 'cookie' | 'token';\n /** For embeds/native: the channel's publishable key (tlpk_\u2026). */\n publishableKey?: string;\n /** Token storage for 'token' session mode (defaults to in-memory). */\n tokenStorage?: LiveTokenStorage;\n /** Override the dated API version sent as TL-Version. */\n apiVersion?: string;\n /** Extra headers sent on every request (merged under per-call headers). */\n headers?: Record<string, string>;\n}\n\nexport class LiveAPIError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly status: number\n ) {\n super(message);\n this.name = 'LiveAPIError';\n }\n}\n\n/**\n * Generated Live client. Mirrors the sales surface (byte-for-byte views) plus\n * the Live-only /session and /queue operations. Auth is the Live session\n * (cookie on hosted web; X-Live-Session header elsewhere) + the channel\n * publishable key for embeds. Browser ergonomics live in createLiveClient.\n */\nexport class LiveClient {\n private baseUrl: string;\n private sessionMode: 'cookie' | 'token';\n private publishableKey?: string;\n private tokenStorage: LiveTokenStorage;\n private apiVersion: string;\n private headers: Record<string, string>;\n\n constructor(config: LiveClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.sessionMode = config.sessionMode ?? 'cookie';\n this.publishableKey = config.publishableKey;\n this.tokenStorage = config.tokenStorage ?? memoryTokenStorage();\n this.apiVersion = config.apiVersion ?? API_DATED_VERSION;\n this.headers = config.headers ?? {};\n }\n\n /** Store the Live session id (token mode). Called after POST /session. */\n async setSessionToken(token: string): Promise<void> {\n await this.tokenStorage.set(token);\n }\n\n /** The current session token (token mode), if any - used for embed handoff. */\n async getSessionToken(): Promise<string | null> {\n return this.tokenStorage.get();\n }\n\n async clearSession(): Promise<void> {\n await this.tokenStorage.clear();\n }\n\n /**\n * Make a request to the Live deployment. Live serves at the root (no /v1\n * prefix). Injects the publishable key + session header + TL-Version, and\n * unwraps the JSend envelope.\n */\n private async request<T>(path: string, options: RequestInit = {}): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'TL-Version': this.apiVersion,\n 'TL-Client': SDK_CLIENT_HEADER,\n ...this.headers,\n ...(options.headers as Record<string, string> | undefined),\n };\n\n if (this.publishableKey) {\n headers['Authorization'] = `Bearer ${this.publishableKey}`;\n }\n\n if (this.sessionMode === 'token') {\n const token = await this.tokenStorage.get();\n if (token) headers['X-Live-Session'] = token;\n }\n\n const response = await fetch(url, {\n ...options,\n headers,\n // Hosted web relies on the session cookie travelling with the request\n credentials: this.sessionMode === 'cookie' ? 'include' : 'same-origin',\n });\n\n const text = await response.text();\n const json = text ? JSON.parse(text) : null;\n\n if (!response.ok) {\n const error = json?.error ?? {};\n throw new LiveAPIError(\n error.message ?? `Request failed (${response.status})`,\n error.code ?? 'REQUEST_FAILED',\n response.status\n );\n }\n\n // Unwrap JSend: { status, data, metadata } \u2192 data\n if (json && json.status === 'success' && json.data !== undefined) {\n return json.data as T;\n }\n return json as T;\n }\n\n /**\n * Sales Listings methods\n */\n salesListings = {\n /**\n * List active listings\n * What is on sale through this channel right now. The channel is resolved from the key, never from a parameter.\n * @operationId listSalesListings\n */\n list: async () => {\n const response = await this.request<GetSalesListingsResponse>(`/sales/listings`, {\n method: 'GET'\n });\n\n return response;\n }\n };\n\n /**\n * Sales Customer Auth methods\n */\n salesCustomerAuth = {\n /**\n * Request magic link\n * Start a magic-link sign-in for a customer. Always reports success - account existence is never revealed.\n * @operationId requestSalesMagicLink\n */\n magicLink: async (request: { email?: string; phone?: string }) => {\n const response = await this.request<SalesMagicLinkResponse>(`/sales/customer-auth/magic-link`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.sent;\n }\n };\n\n /**\n * Sales Customer Tokens methods\n */\n salesCustomerTokens = {\n /**\n * Exchange identity proof for customer token\n * Exchange an identity proof (magic-link code or partner assertion) for a short-lived customer token bound to this channel. Identity is exchanged, never asserted.\n * @operationId createSalesCustomerToken\n */\n create: async (request: { proof: any }) => {\n const response = await this.request<SalesCustomerTokenResponse>(`/sales/customer-tokens`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response;\n },\n\n /**\n * Refresh a customer token\n * Re-signs a still-valid customer token (presented via X-Customer-Token) for a fresh 30 minutes, carrying the original 24-hour absolute ceiling forward. Once the ceiling passes the customer must re-authenticate.\n * @operationId refreshSalesCustomerToken\n */\n refresh: async () => {\n const response = await this.request<SalesCustomerTokenResponse>(`/sales/customer-tokens/refresh`, {\n method: 'POST'\n });\n\n return response;\n }\n };\n\n /**\n * Sales Carts methods\n */\n salesCarts = {\n /**\n * Create cart\n * Create a cart on this channel. Customer identity comes only from a verified customer token, never from the body.\n * @operationId createSalesCart\n */\n create: async (request: { metadata?: Record<string, any> }) => {\n const response = await this.request<SalesCartResponse>(`/sales/carts`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.cart;\n },\n\n /**\n * Get cart\n * Get a cart with its items\n * @operationId getSalesCart\n */\n get: async (cartId: string) => {\n const response = await this.request<SalesCartResponse>(`/sales/carts/${cartId}`, {\n method: 'GET'\n });\n\n return response.cart;\n },\n\n /**\n * Add cart item\n * Add an item to the cart, taking a real inventory reservation with the channel's TTL\n * @operationId addSalesCartItem\n */\n addItem: async (cartId: string, request: { eventOccurrenceId: string; categoryId: string; ticketTypeId: string; quantity?: number; eventLayoutAreaId?: string; eventLayoutSeatIds?: string[] }) => {\n const response = await this.request<SalesCartResponse>(`/sales/carts/${cartId}/items`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.cart;\n },\n\n /**\n * Remove cart item\n * Remove an item from the cart, releasing its reservation\n * @operationId removeSalesCartItem\n */\n removeItem: async (cartId: string, itemId: string) => {\n const response = await this.request<SalesCartResponse>(`/sales/carts/${cartId}/items/${itemId}`, {\n method: 'DELETE'\n });\n\n return response.cart;\n },\n\n /**\n * Checkout cart\n * Convert the cart into an order. Returns an order access token for possession-based guest access (confirmation page, payment status polling).\n * @operationId checkoutSalesCart\n */\n checkout: async (cartId: string, request: { customerNotes?: string; metadata?: Record<string, any>; customer?: { email: string; firstName?: string; lastName?: string; phone?: string; marketingConsent?: boolean } }) => {\n const response = await this.request<SalesCheckoutResponse>(`/sales/carts/${cartId}/checkout`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response;\n }\n };\n\n /**\n * Sales My Orders methods\n */\n salesMyOrders = {\n /**\n * List my orders\n * The verified customer's own orders. Requires a customer token - orders cannot be listed with key or possession credentials alone.\n * @operationId listMySalesOrders\n */\n list: async () => {\n const response = await this.request<ListMySalesOrdersResponse>(`/sales/my-orders`, {\n method: 'GET'\n });\n\n return response.orders;\n }\n };\n\n /**\n * Sales Orders methods\n */\n salesOrders = {\n /**\n * Get order\n * Get an order on this channel. Access requires a secret key (own channel), an X-Order-Access-Token header (guest possession) or a customer token (own orders).\n * @operationId getSalesOrder\n */\n get: async (orderId: string) => {\n const response = await this.request<GetSalesOrderResponse>(`/sales/orders/${orderId}`, {\n method: 'GET'\n });\n\n return response.order;\n },\n\n /**\n * Download a ticket PDF\n * Render and stream a pass as a PDF ticket (application/pdf) for the holder. Order-access gated. Browsers fetch this directly rather than through the typed SDK.\n * @operationId getSalesOrderTicketPdf\n */\n ticketPdf: async (orderId: string, passId: string) => {\n const response = await this.request<any>(`/sales/orders/${orderId}/passes/${passId}/ticket.pdf`, {\n method: 'GET'\n });\n\n return response;\n }\n };\n\n /**\n * Sales Order Payments methods\n */\n salesOrderPayments = {\n /**\n * Create order payment\n * Initiate payment for the order's outstanding balance through the channel's payment provider\n * @operationId createSalesOrderPayment\n */\n create: async (orderId: string, request: { paymentType?: 'online_card' | 'online_bank_transfer' | 'online_wallet'; returnUrl?: string }) => {\n const response = await this.request<CreateSalesOrderPaymentResponse>(`/sales/orders/${orderId}/payments`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.payment;\n }\n };\n\n /**\n * Sales Refund Requests methods\n */\n salesRefundRequests = {\n /**\n * Request refund or exchange\n * File a refund or exchange request for the order within the resolved refund policy. Requester identity is derived from the credential, never from the body.\n * @operationId createSalesOrderRefundRequest\n */\n create: async (orderId: string, request: { type: 'refund' | 'exchange'; reason?: string }) => {\n const response = await this.request<CreateSalesRefundRequestResponse>(`/sales/orders/${orderId}/refund-requests`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.request;\n }\n };\n\n /**\n * Sales Customers methods\n */\n salesCustomers = {\n /**\n * Create customer\n * Provenance-scoped channel CRM (secret keys only). Reuses the org's existing record for the email and grants the channel access; there is no list or search.\n * @operationId createSalesCustomer\n */\n create: async (request: { email: string; firstName?: string; lastName?: string; phone?: string; marketingConsent?: boolean }) => {\n const response = await this.request<SalesCustomerResponse>(`/sales/customers`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.customer;\n },\n\n /**\n * Get customer\n * Get a customer the channel holds an access grant for (created through it, or who bought through it)\n * @operationId getSalesCustomer\n */\n get: async (customerId: string) => {\n const response = await this.request<SalesCustomerResponse>(`/sales/customers/${customerId}`, {\n method: 'GET'\n });\n\n return response.customer;\n },\n\n /**\n * Update customer\n * Update a customer the channel holds an access grant for. The update surface is deliberately small - email changes go through the org's staff.\n * @operationId updateSalesCustomer\n */\n update: async (customerId: string, request: { firstName?: string; lastName?: string; phone?: string }) => {\n const response = await this.request<SalesCustomerResponse>(`/sales/customers/${customerId}`, {\n method: 'PATCH',\n body: JSON.stringify(request)\n });\n\n return response.customer;\n }\n };\n\n /**\n * Sales Presale Codes methods\n */\n salesPresaleCodes = {\n /**\n * Redeem presale code\n * A verified customer redeems a presale code for its benefit; gated pricing unlocks immediately. Requires a customer token.\n * @operationId redeemSalesPresaleCode\n */\n redeem: async (request: { code: string }) => {\n const response = await this.request<RedeemSalesPresaleCodeResponse>(`/sales/presale-codes/redeem`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response;\n }\n };\n\n /**\n * Sales methods\n */\n sales = {\n /**\n * Resolve a channel by domain\n * Public tenant resolution for hosted surfaces: maps a hostname (the channel's configured subdomain or custom domain) to its channel summary and publishable key. No authentication; rate-limited.\n * @operationId resolveSalesChannel\n */\n resolveChannel: async (options?: { domain: string }) => {\n const params = new URLSearchParams();\n if (options?.domain !== undefined) params.append('domain', String(options.domain));\n const queryString = params.toString();\n const requestPath = queryString ? `/sales/channel?${queryString}` : `/sales/channel`;\n\n const response = await this.request<SalesResolveChannelResponse>(requestPath, {\n method: 'GET'\n });\n\n return response;\n },\n\n /**\n * Get event catalogue detail\n * Catalogue detail for an event listed on this channel: occurrences with their priced ticket-type offers. Benefit-gated types are included only when the request carries a customer token holding the benefit. Returns 404 if the event is not listed on this channel.\n * @operationId getSalesEvent\n */\n get: async (eventId: string) => {\n const response = await this.request<SalesEventDetailResponse>(`/sales/events/${eventId}`, {\n method: 'GET'\n });\n\n return response.event;\n },\n\n /**\n * Get channel theme\n * The channel's resolved (inheritance-merged) theme for SSR injection. Returns 404 if the channel has neither its own theme nor an organisation base theme.\n * @operationId getSalesTheme\n */\n getTheme: async () => {\n const response = await this.request<SalesThemeResponse>(`/sales/theme`, {\n method: 'GET'\n });\n\n return response.theme;\n }\n };\n\n /**\n * Session methods\n */\n session = {\n /**\n * Bootstrap a Live session\n * Resolves the channel and mints a session that holds the channel\u2019s publishable key server-side. Hosted callers (channel resolved from the Host header or an explicit `domain`) receive an httpOnly cookie; embed callers (providing a `channelKey`) receive the session id in the body.\n * @operationId createLiveSession\n */\n start: async (request: CreateSessionBody) => {\n const response = await this.request<any>(`/session`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response;\n },\n\n /**\n * Get the current session\n * Returns the current session\u2019s customer and cart state.\n * @operationId getLiveSession\n */\n current: async () => {\n const response = await this.request<any>(`/session`, {\n method: 'GET'\n });\n\n return response;\n },\n\n /**\n * Destroy the current session\n * Signs out and drops the current session.\n * @operationId deleteLiveSession\n */\n end: async () => {\n const response = await this.request<any>(`/session`, {\n method: 'DELETE'\n });\n\n return response;\n },\n\n /**\n * Attach an order access token to the session\n * Proves possession of an order by reading it upstream with the emailed order access token, then holds the token in the session so `GET /sales/orders/{orderId}` (and ticket downloads) work without the browser keeping it. Creates the session on a cold open, exactly like `POST /session`.\n * @operationId attachLiveOrderAccess\n */\n attachOrderAccess: async (request: AttachOrderAccessBody) => {\n const response = await this.request<any>(`/session/order-access`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response;\n }\n };\n\n /**\n * Queue methods\n */\n queue = {\n /**\n * Get waiting-room status\n * Returns the waiting-room status for the current session. The waiting room lives only in Live; when disabled the queue is transparent and every session is admitted.\n * @operationId getLiveQueueStatus\n */\n status: async () => {\n const response = await this.request<any>(`/queue/status`, {\n method: 'GET'\n });\n\n return response;\n },\n\n /**\n * Join the waiting room\n * Joins the current session to the waiting room. While the queue is disabled this is a no-op that reports immediate admission.\n * @operationId joinLiveQueue\n */\n join: async () => {\n const response = await this.request<any>(`/queue/join`, {\n method: 'POST'\n });\n\n return response;\n }\n };\n}\n", "/**\n * The `window.Ticketlayer` global registry.\n *\n * One stateful Live client per page, published on a well-known global so that\n * Elements (a separate bundle, possibly CDN-loaded) can find and bind to it\n * WITHOUT importing @ticketlayer/live. The contract is deliberately tiny and\n * stable - it's the public integration surface for snippet/Webflow embeds:\n *\n * - `getClient()` - the rich stateful facade (events/cart/auth/theme/bus).\n * - `getSDK()` - the Elements-shaped connector view of that same client.\n * - `ready()` - resolves when the client is published (immediately if it\n * already is); Elements await this instead of polling.\n *\n * Publishing also dispatches a `ticketlayer:ready` CustomEvent on window, so a\n * pure-DOM listener (no promise plumbing) can react too.\n */\n\nexport const TICKETLAYER_GLOBAL_KEY = 'Ticketlayer' as const;\nexport const TICKETLAYER_READY_EVENT = 'ticketlayer:ready' as const;\n\nexport interface TicketlayerGlobal<Client = unknown, Sdk = unknown> {\n /** The singleton stateful client (facade). */\n client: Client | null;\n /** Elements-shaped connector view of the same client. */\n sdk: Sdk | null;\n getClient(): Client | null;\n getSDK(): Sdk | null;\n /** Resolves with the client once published; immediate if already present. */\n ready(): Promise<Client>;\n version: string;\n}\n\ninterface InternalGlobal<Client, Sdk> extends TicketlayerGlobal<Client, Sdk> {\n _resolvers: Array<(c: Client) => void>;\n}\n\ndeclare global {\n interface Window {\n Ticketlayer?: TicketlayerGlobal;\n }\n}\n\nfunction ensureRegistry<Client, Sdk>(version: string): InternalGlobal<Client, Sdk> {\n const w = window as unknown as { [TICKETLAYER_GLOBAL_KEY]?: InternalGlobal<Client, Sdk> };\n if (w[TICKETLAYER_GLOBAL_KEY]) return w[TICKETLAYER_GLOBAL_KEY]!;\n\n const reg: InternalGlobal<Client, Sdk> = {\n client: null,\n sdk: null,\n version,\n _resolvers: [],\n getClient() {\n return this.client;\n },\n getSDK() {\n return this.sdk;\n },\n ready() {\n if (this.client) return Promise.resolve(this.client);\n return new Promise<Client>((resolve) => this._resolvers.push(resolve));\n },\n };\n w[TICKETLAYER_GLOBAL_KEY] = reg;\n return reg;\n}\n\n/** Publish the singleton client + connector. Browser-only; safe to call once. */\nexport function publishClient<Client, Sdk>(client: Client, sdk: Sdk, version: string): void {\n if (typeof window === 'undefined') return;\n const reg = ensureRegistry<Client, Sdk>(version);\n\n if (reg.client && reg.client !== client) {\n console.warn(\n '[live] A Ticketlayer client is already on window.Ticketlayer; replacing it. ' +\n 'Create a single client per page.'\n );\n }\n\n reg.client = client;\n reg.sdk = sdk;\n const resolvers = reg._resolvers;\n reg._resolvers = [];\n resolvers.forEach((r) => r(client));\n\n window.dispatchEvent(new CustomEvent(TICKETLAYER_READY_EVENT, { detail: client }));\n}\n\n/** Read the current client, if any (host convenience; Elements use ready()). */\nexport function getPublishedClient<Client>(): Client | null {\n if (typeof window === 'undefined') return null;\n return (window.Ticketlayer?.getClient() as Client | null) ?? null;\n}\n", "/**\n * Optionally pull in @ticketlayer/elements at runtime so a single Live include\n * gives you the components too - the \"one line of code\" snippet path.\n *\n * No-op when: not in a browser, the custom elements are already defined (a\n * bundler-based host like HBO imports them directly), or an injection for this\n * URL is already in flight. The default URL points at the Elements ESM entry on\n * the Ticketlayer CDN; pass `elementsUrl` to target a pinned build or a local\n * one in dev.\n *\n * ## Subresource integrity, and when it is required (TKT-160)\n *\n * The page's own `<script>` tag is integrity-checked by the browser, but the\n * Elements bundle this module then injects is a second, much larger download -\n * the one that actually renders the checkout. Injecting it with no `integrity`\n * left it unverified, which made the pinning the Webflow Integration Service\n * writes into every installed site (`data-elements-url` +\n * `data-elements-integrity`) worth nothing past the first script tag.\n *\n * The rule this module enforces, in full:\n *\n * 1. **A hash with no URL is refused.** `elementsIntegrity` without\n * `elementsUrl` could only be pinning the floating default, whose bytes are\n * rewritten by every release, so the hash is wrong the moment one lands.\n * 2. **A malformed hash is refused.** It has to look like\n * `sha256-`/`sha384-`/`sha512-` followed by base64, optionally several\n * space-separated, as the HTML spec defines the attribute. A typo that the\n * browser ignores is worse than no hash at all, because it reads as\n * protection.\n * 3. **An exact-version URL with no hash is refused.** A path carrying a full\n * `v<major>.<minor>.<patch>` segment is the CDN's pinned tier: those bytes\n * are written once and never rewritten, `/versions.json` publishes their\n * `sha384`, and pinning without verifying is the degradation this exists to\n * stop. This is exactly the shape the Webflow Integration Service writes.\n * 4. **Everything else loads unverified, deliberately.** The floating tiers\n * (`/v1/`, `/v0.3/`) and a local dev server change under the URL by design;\n * an integrity hash on one of them fails the moment a release lands\n * (`cdn/README.md`, \"Pinning, and subresource integrity\"). They cannot be\n * verified, so requiring it would only stop them working.\n *\n * `DEFAULT_ELEMENTS_URL` is a floating path and therefore falls into case 4.\n * The default is kept, because removing it would break the documented one-line\n * embed and every site that already omits `data-elements-url`, but it is no\n * longer silent: taking it logs once, naming the pinned alternative. A site\n * that wants the bundle verified pins it.\n *\n * `crossOrigin` is set alongside `integrity` and is not optional: a\n * cross-origin script without CORS is opaque to the page, and the browser\n * refuses to check an `integrity` it cannot read the bytes for.\n */\nconst DEFAULT_ELEMENTS_URL =\n 'https://cdn.ticketlayer.com/elements/v1/ticketlayer-elements/ticketlayer-elements.esm.js';\n\nconst SENTINEL_TAG = 'tl-event-list';\nconst inFlight = new Map<string, Promise<void>>();\n\n/**\n * A path segment naming a full major.minor.patch - the CDN's pinned tier\n * (`cdn/build-tree.mjs` is where the scheme is decided). `/v1/` and `/v0.3/`\n * are the floating tiers and deliberately do not match.\n */\nconst PINNED_PATH = /\\/v\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?\\//;\n\n/** The `integrity` attribute as HTML defines it: one or more hash expressions. */\nconst INTEGRITY = /^(?:sha(?:256|384|512)-[A-Za-z0-9+/]+={0,2})(?:\\s+sha(?:256|384|512)-[A-Za-z0-9+/]+={0,2})*$/;\n\nexport interface LoadElementsOptions {\n /** Enable runtime injection (default false - most hosts import Elements directly). */\n elements?: boolean;\n /**\n * Override the Elements ESM bundle URL: a pinned CDN build, or a local dist\n * in dev. An exact-version URL must come with `elementsIntegrity`.\n */\n elementsUrl?: string;\n /**\n * Subresource integrity for `elementsUrl`, as `/versions.json` publishes it\n * (`sha384-...`). Required for an exact-version URL, refused without one.\n */\n elementsIntegrity?: string;\n}\n\n/** Thrown when the options ask for something that cannot be verified. */\nexport class ElementsIntegrityError extends Error {\n constructor(message: string) {\n super(`[live] ${message}`);\n this.name = 'ElementsIntegrityError';\n }\n}\n\nlet warnedAboutDefault = false;\n\nexport function loadElements(opts: LoadElementsOptions = {}): Promise<void> {\n if (!opts.elements) return Promise.resolve();\n\n const integrity = opts.elementsIntegrity?.trim() || undefined;\n\n // The refusals come before the browser and already-registered checks, so a\n // misconfigured host hears about it in Node, in SSR and in a test - not only\n // on the one page where the elements had not already been defined.\n if (integrity && !opts.elementsUrl) {\n throw new ElementsIntegrityError(\n 'elementsIntegrity was given without elementsUrl. The default Elements URL is a floating ' +\n 'path that every release rewrites, so a hash pinned to it cannot keep matching. Pass the ' +\n 'pinned elementsUrl that the hash is for (see /versions.json on the CDN).'\n );\n }\n if (integrity && !INTEGRITY.test(integrity)) {\n throw new ElementsIntegrityError(\n `elementsIntegrity is not a subresource integrity value: ${JSON.stringify(opts.elementsIntegrity)}. ` +\n 'Expected one or more of sha256-, sha384- or sha512- followed by base64, as /versions.json publishes it.'\n );\n }\n if (opts.elementsUrl && !integrity && PINNED_PATH.test(opts.elementsUrl)) {\n throw new ElementsIntegrityError(\n `elementsUrl ${opts.elementsUrl} names an exact version, which is the CDN's pinned tier, but no ` +\n 'elementsIntegrity came with it. A pinned URL exists to be verified; loading it unchecked would ' +\n 'be weaker than the floating path. Pass the sha384 from /versions.json as elementsIntegrity ' +\n '(data-elements-integrity on the embed script), or use a floating /v1/ URL.'\n );\n }\n\n if (typeof window === 'undefined' || typeof document === 'undefined') return Promise.resolve();\n\n // Already registered (bundler import or a prior load) - nothing to do.\n const ce = (window as unknown as { customElements?: CustomElementRegistry }).customElements;\n if (ce?.get(SENTINEL_TAG)) return Promise.resolve();\n\n const url = opts.elementsUrl ?? DEFAULT_ELEMENTS_URL;\n\n if (!opts.elementsUrl && !warnedAboutDefault) {\n warnedAboutDefault = true;\n console.warn(\n `[live] Loading Elements unverified from the floating default ${DEFAULT_ELEMENTS_URL}. ` +\n 'Floating paths are rewritten by every release and cannot carry a subresource integrity hash. ' +\n 'To verify the bundle, pin it: set elementsUrl (data-elements-url) to the pinned path from ' +\n '/versions.json and elementsIntegrity (data-elements-integrity) to the sha384 beside it.'\n );\n }\n\n const existing = inFlight.get(url);\n if (existing) return existing;\n\n const p = new Promise<void>((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'module';\n script.src = url;\n script.async = true;\n if (integrity) {\n script.integrity = integrity;\n // Without CORS the response is opaque and the browser cannot check the\n // hash at all, so these two are set together or not at all.\n script.crossOrigin = 'anonymous';\n }\n script.dataset.ticketlayerElements = 'auto';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(`[live] Failed to load Elements from ${url}`));\n document.head.appendChild(script);\n });\n\n inFlight.set(url, p);\n return p;\n}\n", "/* Generated from tokens.json by packages/theme/scripts/generate.mjs. Do not edit. */\n/**\n * Typed access to the token set. Generated from packages/theme/tokens.json;\n * change a token there and regenerate.\n */\n\n/** Every token name, in declaration order. */\nexport const TOKEN_NAMES = [\n 'primary',\n 'primary-foreground',\n 'secondary',\n 'secondary-foreground',\n 'accent',\n 'accent-foreground',\n 'background',\n 'foreground',\n 'card',\n 'muted',\n 'muted-foreground',\n 'border',\n 'border-hover',\n 'input',\n 'ring',\n 'success',\n 'success-foreground',\n 'warning',\n 'warning-foreground',\n 'warning-bg',\n 'error',\n 'error-foreground',\n 'error-bg',\n 'font-family',\n 'font-family-mono',\n 'font-size-base',\n 'font-scale',\n 'radius-none',\n 'radius-sm',\n 'radius-md',\n 'radius-lg',\n 'radius-full',\n 'spacing-1',\n 'spacing-2',\n 'spacing-3',\n 'spacing-4',\n 'spacing-5',\n 'spacing-6',\n 'spacing-8',\n 'duration-fast',\n 'duration-normal',\n 'duration-slow',\n 'easing-standard',\n 'easing-emphasised',\n] as const;\n\n/** A token name. Renaming a token in tokens.json changes this union, and every consumer that named the old one stops compiling. */\nexport type TokenName = (typeof TOKEN_NAMES)[number];\n\n/** Alias name -> the token it resolves to. */\nexport const TOKEN_ALIASES = {\n 'color-primary': 'primary',\n 'color-primary-foreground': 'primary-foreground',\n 'color-secondary': 'secondary',\n 'color-secondary-foreground': 'secondary-foreground',\n 'color-accent': 'accent',\n 'color-accent-foreground': 'accent-foreground',\n 'color-background': 'background',\n 'color-foreground': 'foreground',\n 'color-card': 'card',\n 'color-muted': 'muted',\n 'color-muted-foreground': 'muted-foreground',\n 'color-border': 'border',\n 'color-border-hover': 'border-hover',\n 'color-input': 'input',\n 'color-ring': 'ring',\n 'color-success': 'success',\n 'color-success-foreground': 'success-foreground',\n 'color-warning': 'warning',\n 'color-warning-foreground': 'warning-foreground',\n 'color-warning-bg': 'warning-bg',\n 'color-error': 'error',\n 'destructive': 'error',\n 'color-destructive': 'error',\n 'color-error-foreground': 'error-foreground',\n 'destructive-foreground': 'error-foreground',\n 'color-destructive-foreground': 'error-foreground',\n 'color-error-bg': 'error-bg',\n 'destructive-bg': 'error-bg',\n 'color-destructive-bg': 'error-bg',\n 'base-size': 'font-size-base',\n 'radius': 'radius-md',\n} as const;\n\nexport type TokenAlias = keyof typeof TOKEN_ALIASES;\n\n/** The default (light) value of every token, by token name. */\nexport const TOKEN_DEFAULTS: Record<TokenName, string> = {\n 'primary': '#6366f1',\n 'primary-foreground': '#ffffff',\n 'secondary': '#f3f4f6',\n 'secondary-foreground': '#111827',\n 'accent': '#ec4899',\n 'accent-foreground': '#ffffff',\n 'background': '#ffffff',\n 'foreground': '#111827',\n 'card': '#ffffff',\n 'muted': '#f9fafb',\n 'muted-foreground': '#6b7280',\n 'border': '#e5e7eb',\n 'border-hover': '#9ca3af',\n 'input': '#e5e7eb',\n 'ring': '#6366f1',\n 'success': '#10b981',\n 'success-foreground': '#ffffff',\n 'warning': '#f59e0b',\n 'warning-foreground': '#ffffff',\n 'warning-bg': '#fef3c7',\n 'error': '#ef4444',\n 'error-foreground': '#ffffff',\n 'error-bg': '#fee2e2',\n 'font-family': 'system-ui, -apple-system, BlinkMacSystemFont, \\'Segoe UI\\', Roboto, sans-serif',\n 'font-family-mono': 'ui-monospace, SFMono-Regular, \\'SF Mono\\', Menlo, monospace',\n 'font-size-base': '16px',\n 'font-scale': '1.25',\n 'radius-none': '0px',\n 'radius-sm': '0.25rem',\n 'radius-md': '0.5rem',\n 'radius-lg': '0.75rem',\n 'radius-full': '9999px',\n 'spacing-1': '0.25rem',\n 'spacing-2': '0.5rem',\n 'spacing-3': '0.75rem',\n 'spacing-4': '1rem',\n 'spacing-5': '1.25rem',\n 'spacing-6': '1.5rem',\n 'spacing-8': '2rem',\n 'duration-fast': '120ms',\n 'duration-normal': '200ms',\n 'duration-slow': '320ms',\n 'easing-standard': 'cubic-bezier(0.2, 0, 0, 1)',\n 'easing-emphasised': 'cubic-bezier(0.3, 0, 0, 1)',\n};\n\n/** The dark value of every token that has one. */\nexport const TOKEN_DARK: Partial<Record<TokenName, string>> = {\n 'primary': '#818cf8',\n 'primary-foreground': '#111827',\n 'secondary': '#1f2937',\n 'secondary-foreground': '#f9fafb',\n 'accent': '#f472b6',\n 'accent-foreground': '#111827',\n 'background': '#0b0f19',\n 'foreground': '#f9fafb',\n 'card': '#111827',\n 'muted': '#111827',\n 'muted-foreground': '#9ca3af',\n 'border': '#374151',\n 'border-hover': '#4b5563',\n 'input': '#374151',\n 'ring': '#818cf8',\n 'success': '#34d399',\n 'success-foreground': '#062a1d',\n 'warning': '#fbbf24',\n 'warning-foreground': '#2a1a02',\n 'warning-bg': '#422006',\n 'error': '#f87171',\n 'error-foreground': '#2a0a0a',\n 'error-bg': '#450a0a',\n};\n\n/** The theme-document key that feeds each token, for the tokens the theme API can set. */\nexport const TOKEN_THEME_KEYS: Partial<Record<TokenName, string>> = {\n 'primary': 'colors.primary',\n 'primary-foreground': 'colors.primaryForeground',\n 'secondary': 'colors.secondary',\n 'secondary-foreground': 'colors.secondaryForeground',\n 'accent': 'colors.accent',\n 'accent-foreground': 'colors.accentForeground',\n 'background': 'colors.background',\n 'foreground': 'colors.foreground',\n 'muted': 'colors.muted',\n 'muted-foreground': 'colors.mutedForeground',\n 'border': 'colors.border',\n 'input': 'colors.input',\n 'ring': 'colors.ring',\n 'success': 'colors.success',\n 'success-foreground': 'colors.successForeground',\n 'warning': 'colors.warning',\n 'warning-foreground': 'colors.warningForeground',\n 'error': 'colors.destructive',\n 'error-foreground': 'colors.destructiveForeground',\n 'font-family': 'typography.fontFamily',\n 'font-family-mono': 'typography.fontFamilyMono',\n 'font-size-base': 'typography.baseSize',\n 'font-scale': 'typography.scaleRatio',\n 'radius-none': 'shape.radiusNone',\n 'radius-sm': 'shape.radiusSm',\n 'radius-md': 'shape.radiusMd',\n 'radius-lg': 'shape.radiusLg',\n 'radius-full': 'shape.radiusFull',\n};\n\n/** The group each token belongs to. */\nexport const TOKEN_GROUPS: Record<TokenName, string> = {\n 'primary': 'color',\n 'primary-foreground': 'color',\n 'secondary': 'color',\n 'secondary-foreground': 'color',\n 'accent': 'color',\n 'accent-foreground': 'color',\n 'background': 'color',\n 'foreground': 'color',\n 'card': 'color',\n 'muted': 'color',\n 'muted-foreground': 'color',\n 'border': 'color',\n 'border-hover': 'color',\n 'input': 'color',\n 'ring': 'color',\n 'success': 'color',\n 'success-foreground': 'color',\n 'warning': 'color',\n 'warning-foreground': 'color',\n 'warning-bg': 'color',\n 'error': 'color',\n 'error-foreground': 'color',\n 'error-bg': 'color',\n 'font-family': 'typography',\n 'font-family-mono': 'typography',\n 'font-size-base': 'typography',\n 'font-scale': 'typography',\n 'radius-none': 'radius',\n 'radius-sm': 'radius',\n 'radius-md': 'radius',\n 'radius-lg': 'radius',\n 'radius-full': 'radius',\n 'spacing-1': 'spacing',\n 'spacing-2': 'spacing',\n 'spacing-3': 'spacing',\n 'spacing-4': 'spacing',\n 'spacing-5': 'spacing',\n 'spacing-6': 'spacing',\n 'spacing-8': 'spacing',\n 'duration-fast': 'motion',\n 'duration-normal': 'motion',\n 'duration-slow': 'motion',\n 'easing-standard': 'motion',\n 'easing-emphasised': 'motion',\n};\n\n/**\n * The typed theme object a native harness renders from: the same tokens, grouped,\n * with camelCase keys and no CSS anywhere near them.\n */\nexport const lightTheme = {\n color: {\n 'primary': '#6366f1',\n 'primaryForeground': '#ffffff',\n 'secondary': '#f3f4f6',\n 'secondaryForeground': '#111827',\n 'accent': '#ec4899',\n 'accentForeground': '#ffffff',\n 'background': '#ffffff',\n 'foreground': '#111827',\n 'card': '#ffffff',\n 'muted': '#f9fafb',\n 'mutedForeground': '#6b7280',\n 'border': '#e5e7eb',\n 'borderHover': '#9ca3af',\n 'input': '#e5e7eb',\n 'ring': '#6366f1',\n 'success': '#10b981',\n 'successForeground': '#ffffff',\n 'warning': '#f59e0b',\n 'warningForeground': '#ffffff',\n 'warningBg': '#fef3c7',\n 'error': '#ef4444',\n 'errorForeground': '#ffffff',\n 'errorBg': '#fee2e2',\n },\n typography: {\n 'fontFamily': 'system-ui, -apple-system, BlinkMacSystemFont, \\'Segoe UI\\', Roboto, sans-serif',\n 'fontFamilyMono': 'ui-monospace, SFMono-Regular, \\'SF Mono\\', Menlo, monospace',\n 'fontSizeBase': '16px',\n 'fontScale': '1.25',\n },\n radius: {\n 'none': '0px',\n 'sm': '0.25rem',\n 'md': '0.5rem',\n 'lg': '0.75rem',\n 'full': '9999px',\n },\n spacing: {\n '1': '0.25rem',\n '2': '0.5rem',\n '3': '0.75rem',\n '4': '1rem',\n '5': '1.25rem',\n '6': '1.5rem',\n '8': '2rem',\n },\n motion: {\n 'durationFast': '120ms',\n 'durationNormal': '200ms',\n 'durationSlow': '320ms',\n 'easingStandard': 'cubic-bezier(0.2, 0, 0, 1)',\n 'easingEmphasised': 'cubic-bezier(0.3, 0, 0, 1)',\n },\n} as const;\n\nexport const darkTheme = {\n color: {\n 'primary': '#818cf8',\n 'primaryForeground': '#111827',\n 'secondary': '#1f2937',\n 'secondaryForeground': '#f9fafb',\n 'accent': '#f472b6',\n 'accentForeground': '#111827',\n 'background': '#0b0f19',\n 'foreground': '#f9fafb',\n 'card': '#111827',\n 'muted': '#111827',\n 'mutedForeground': '#9ca3af',\n 'border': '#374151',\n 'borderHover': '#4b5563',\n 'input': '#374151',\n 'ring': '#818cf8',\n 'success': '#34d399',\n 'successForeground': '#062a1d',\n 'warning': '#fbbf24',\n 'warningForeground': '#2a1a02',\n 'warningBg': '#422006',\n 'error': '#f87171',\n 'errorForeground': '#2a0a0a',\n 'errorBg': '#450a0a',\n },\n typography: {\n 'fontFamily': 'system-ui, -apple-system, BlinkMacSystemFont, \\'Segoe UI\\', Roboto, sans-serif',\n 'fontFamilyMono': 'ui-monospace, SFMono-Regular, \\'SF Mono\\', Menlo, monospace',\n 'fontSizeBase': '16px',\n 'fontScale': '1.25',\n },\n radius: {\n 'none': '0px',\n 'sm': '0.25rem',\n 'md': '0.5rem',\n 'lg': '0.75rem',\n 'full': '9999px',\n },\n spacing: {\n '1': '0.25rem',\n '2': '0.5rem',\n '3': '0.75rem',\n '4': '1rem',\n '5': '1.25rem',\n '6': '1.5rem',\n '8': '2rem',\n },\n motion: {\n 'durationFast': '120ms',\n 'durationNormal': '200ms',\n 'durationSlow': '320ms',\n 'easingStandard': 'cubic-bezier(0.2, 0, 0, 1)',\n 'easingEmphasised': 'cubic-bezier(0.3, 0, 0, 1)',\n },\n} as const;\n\nexport type NativeTheme = typeof lightTheme;\n", "/**\n * `@ticketlayer/theme`: the token set every Ticketlayer Live harness renders from.\n *\n * `tokens.json` is the source. Everything exported here, the `:root` stylesheet\n * the Elements load, the JSON schema the theme editor and the sales-channel\n * theme API validate against and `TOKENS.md` are generated from it by\n * `scripts/generate.mjs`. There is exactly one place a token's default value is\n * written down, and it is not this file.\n *\n * This package holds no runtime of its own: no DOM, no React, no network. The\n * harness decides how to apply what it reads here. On the web that is\n * `@ticketlayer/live`'s `applyTheme`, which turns a channel theme into the\n * declarations `themeToCssVars` returns and writes them onto `:root`.\n */\nexport {\n TOKEN_NAMES,\n TOKEN_ALIASES,\n TOKEN_DEFAULTS,\n TOKEN_DARK,\n TOKEN_THEME_KEYS,\n TOKEN_GROUPS,\n lightTheme,\n darkTheme,\n} from './generated/tokens.js';\nexport type { TokenName, TokenAlias, NativeTheme } from './generated/tokens.js';\n\nimport {\n TOKEN_ALIASES,\n TOKEN_DEFAULTS,\n TOKEN_THEME_KEYS,\n type TokenName,\n} from './generated/tokens.js';\n\n/** The custom property a token name is written as: `primary` -> `--tl-primary`. */\nexport function cssVar(name: string): string {\n return `--tl-${name}`;\n}\n\n/** The default value of a token, or of an alias, by name. */\nexport function tokenDefault(name: string): string | undefined {\n const resolved = (TOKEN_ALIASES as Record<string, TokenName>)[name] ?? name;\n return TOKEN_DEFAULTS[resolved as TokenName];\n}\n\n/** Is this a token name, or an alias of one? */\nexport function isTokenName(name: string): boolean {\n return name in TOKEN_DEFAULTS || name in TOKEN_ALIASES;\n}\n\n/**\n * A theme document as `GET /sales/theme` returns it. Every section is loose on\n * purpose: the schema is enforced by the API, and a client that refused an\n * unknown key would break the next time a token was added.\n */\nexport interface ThemeDocument {\n colors?: Record<string, unknown>;\n typography?: Record<string, unknown>;\n shape?: Record<string, unknown>;\n brand?: Record<string, unknown>;\n design?: Record<string, unknown> | null;\n}\n\n/**\n * Turn a channel theme into the custom properties that override the defaults.\n *\n * Only declared tokens are read, and every alias a token answers to is written\n * out beside it, so a host that asks for `--tl-color-primary` or the theme\n * editor's `--tl-base-size` gets the channel's value and not the default.\n * Anything the theme carries that is not a token is ignored: the token set is\n * the contract, and a new one is added in `tokens.json`.\n */\nexport function themeToCssVars(theme: ThemeDocument | null | undefined): Record<string, string> {\n const vars: Record<string, string> = {};\n if (!theme) return vars;\n\n for (const [token, themeKey] of Object.entries(TOKEN_THEME_KEYS)) {\n const [section, key] = themeKey.split('.');\n const value = (theme as Record<string, Record<string, unknown> | null | undefined>)[section]?.[key];\n if (value === undefined || value === null || value === '') continue;\n vars[cssVar(token)] = String(value);\n }\n\n for (const [alias, token] of Object.entries(TOKEN_ALIASES)) {\n const value = vars[cssVar(token)];\n if (value !== undefined) vars[cssVar(alias)] = value;\n }\n\n return vars;\n}\n\n/** The same declarations as the body of a CSS rule. */\nexport function themeToCssText(theme: ThemeDocument | null | undefined): string {\n return Object.entries(themeToCssVars(theme))\n .map(([name, value]) => `${name}: ${value};`)\n .join('\\n');\n}\n", "/**\n * Checkout modal manager (third-party embeds).\n *\n * On a third-party site, Elements build the cart in-page and emit\n * `ui:checkout-requested`. This opens the hosted checkout in an iframe overlay\n * pointing at HBO's `/embed/checkout`, handing off the current session token so\n * the iframe sees the same cart (and so card data stays on HBO's origin - PCI\n * isolation). It bridges the `tl:*` postMessage protocol back to the caller's\n * onComplete/onError/onClose callbacks (which rode in on the intent payload).\n *\n * The iframe URL carries `parent_origin=<this page's origin>` so HBO can pin\n * its postMessage target to us (it never posts to '*'), and incoming messages\n * are only accepted from the checkout's own origin. The message set is\n * documented in HBO's docs/embed-checkout-contract.md.\n *\n * HBO itself does NOT use this - it handles `ui:checkout-requested` by\n * navigating in-page to /checkout.\n */\nimport { TOKEN_DEFAULTS } from '@ticketlayer/theme';\nimport type { TicketlayerLive } from '../createLiveClient.js';\n\nexport interface CheckoutModalOptions {\n /** Base URL of the HBO instance serving /embed/checkout. Defaults to origin. */\n embedBaseUrl?: string;\n}\n\n/** Inbound `tl:*` envelope (see HBO docs/embed-checkout-contract.md). */\ninterface EmbedMessage {\n type?: string;\n version?: number;\n orderId?: string;\n orderReference?: string;\n accessToken?: string;\n /** Pre-v1 payload of tl:complete. */\n order?: unknown;\n code?: string;\n message?: string;\n height?: number;\n}\n\ninterface CheckoutIntent {\n onComplete?: (order: unknown) => void;\n onError?: (error: Error) => void;\n onClose?: () => void;\n}\n\nconst OVERLAY_ID = 'tl-checkout-overlay';\n\n\n/** Wire the modal to the bus; returns an uninstall function. */\nexport function installCheckoutModal(\n tl: TicketlayerLive,\n opts: CheckoutModalOptions = {}\n): () => void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return () => {};\n\n let onMessage: ((e: MessageEvent) => void) | null = null;\n\n const close = () => {\n document.getElementById(OVERLAY_ID)?.remove();\n if (onMessage) {\n window.removeEventListener('message', onMessage);\n onMessage = null;\n }\n };\n\n const open = async (intent: CheckoutIntent) => {\n const token = await tl.getSessionToken().catch(() => null);\n const base = (opts.embedBaseUrl || window.location.origin).replace(/\\/$/, '');\n const query = new URLSearchParams();\n if (token) query.set('session', token);\n // Lets HBO pin its postMessage target origin to this page.\n query.set('parent_origin', window.location.origin);\n const url = `${base}/embed/checkout?${query.toString()}`;\n const frameOrigin = new URL(url).origin;\n\n close();\n\n const overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n // Blurred, dimmed backdrop so the underlying site recedes behind the modal.\n overlay.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;background:rgba(15,23,42,0.55);' +\n 'backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);' +\n 'display:flex;flex-direction:column;align-items:center;justify-content:center;' +\n 'gap:12px;padding:16px;';\n\n // Column wrapper: the modal panel + a floating chrome footer beneath it.\n const wrapper = document.createElement('div');\n wrapper.style.cssText =\n 'width:100%;max-width:960px;display:flex;flex-direction:column;gap:10px;';\n\n const frame = document.createElement('iframe');\n frame.src = url;\n frame.allow = 'payment';\n // Wide enough for the two-column checkout (form left, order summary right);\n // the embedded page stacks to one column on narrow viewports. Subtle theme\n // border (matches the buy-tickets modal) + a soft lift off the backdrop.\n //\n // This one keeps a fallback, unlike the Elements' stylesheets: the overlay\n // is drawn on a host page that may have no Elements and therefore no token\n // stylesheet at all. The fallback is still not a second source - it is read\n // from the same token table.\n frame.style.cssText =\n `width:100%;height:88vh;max-height:760px;border:1px solid var(--tl-border, ${TOKEN_DEFAULTS.border});` +\n 'border-radius:16px;background:#fff;box-shadow:0 24px 64px rgba(0,0,0,0.45);';\n\n // No chrome of our own around the iframe.\n //\n // The overlay is a transport: an iframe onto the hosted checkout plus the\n // postMessage bridge. It used to draw a \"Powered by Ticketlayer\" footer\n // beneath the frame, which put attribution at the wrong layer - duplicated\n // by the page inside, and absent for anyone who opens /embed/checkout\n // directly rather than through this overlay. The checkout page renders it\n // now, where the buyer actually is.\n wrapper.appendChild(frame);\n overlay.appendChild(wrapper);\n\n overlay.addEventListener('click', (e) => {\n if (e.target === overlay || e.target === wrapper) {\n close();\n intent.onClose?.();\n }\n });\n document.body.appendChild(overlay);\n\n onMessage = (e: MessageEvent) => {\n // Only the checkout page's own origin may drive the modal.\n if (e.origin !== frameOrigin) return;\n const msg = e.data as EmbedMessage | null;\n if (!msg || typeof msg !== 'object') return;\n switch (msg.type) {\n case 'tl:complete': {\n // v1 carries orderId/orderReference/accessToken at the top level and\n // keeps the pre-v1 `order` object; merge so both shapes are served.\n const legacy = (msg.order && typeof msg.order === 'object' ? msg.order : {}) as object;\n const order: unknown = msg.orderId\n ? {\n ...legacy,\n id: msg.orderId,\n orderNumber: msg.orderReference,\n ...(msg.accessToken ? { accessToken: msg.accessToken } : {}),\n }\n : msg.order;\n intent.onComplete?.(order);\n tl.emit('checkout:completed', order);\n close();\n break;\n }\n case 'tl:close':\n case 'tl:cancel':\n intent.onClose?.();\n close();\n break;\n case 'tl:error': {\n const err = new Error(msg.message || msg.code || 'Checkout failed');\n if (msg.code) (err as Error & { code?: string }).code = msg.code;\n intent.onError?.(err);\n break;\n }\n // tl:ready and tl:height are informational; the overlay has a fixed size.\n }\n };\n window.addEventListener('message', onMessage);\n };\n\n const offCheckout = tl.on('ui:checkout-requested', (p) => void open((p as CheckoutIntent) ?? {}));\n const offClose = tl.on('ui:modal-close-requested', () => close());\n\n return () => {\n offCheckout();\n offClose();\n close();\n };\n}\n", "/**\n * Buy-tickets modal manager (in-page, native Elements).\n *\n * The buy funnel (occurrence \u2192 ticket selection \u2192 add to cart) is pure\n * browse/cart with no PCI surface, so - unlike checkout - it does NOT need a\n * cross-origin iframe. This manager simply mounts the `<tl-buy-modal>` Element\n * on demand when something emits `ui:event-modal-requested` (a\n * `tl-buy-tickets-button`, a calendar date click, etc.) and removes it on close.\n * Because the modal is a normal Element bound to the same `window.Ticketlayer`,\n * it works identically on HBO and on any third-party embed.\n *\n * When the user proceeds to checkout, the manager hands the funnel over by\n * re-emitting `ui:checkout-requested` (forwarding the original caller's\n * callbacks): on a third-party embed the checkout modal opens the hosted\n * checkout in an iframe; on HBO the host navigates to /checkout in-page.\n */\nimport type { TicketlayerLive } from '../createLiveClient.js';\n\nexport interface BuyModalOptions {\n /** Override the custom-element tag (default `tl-buy-modal`). */\n tag?: string;\n}\n\ninterface BuyIntent {\n eventId: string;\n occurrenceId?: string;\n onComplete?: (order: unknown) => void;\n onError?: (error: Error) => void;\n onClose?: () => void;\n}\n\n/** Wire the buy modal to the bus; returns an uninstall function. */\nexport function installBuyModal(tl: TicketlayerLive, opts: BuyModalOptions = {}): () => void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return () => {};\n\n const TAG = opts.tag || 'tl-buy-modal';\n let el: HTMLElement | null = null;\n let current: BuyIntent | null = null;\n\n const remove = () => {\n if (el) {\n el.remove();\n el = null;\n }\n current = null;\n };\n\n const open = (intent: BuyIntent) => {\n if (!intent?.eventId) return;\n remove();\n current = intent;\n\n const node = document.createElement(TAG);\n // Set as attributes (strings) so they apply before the element upgrades.\n node.setAttribute('event-id', intent.eventId);\n if (intent.occurrenceId) node.setAttribute('occurrence-id', intent.occurrenceId);\n\n node.addEventListener('tlClose', () => {\n const i = current;\n remove();\n i?.onClose?.();\n });\n\n node.addEventListener('tlError', (e: Event) => {\n const message =\n (e as CustomEvent<{ message?: string }>).detail?.message || 'Could not load this event';\n current?.onError?.(new Error(message));\n });\n\n node.addEventListener('tlCheckout', () => {\n const i = current;\n remove();\n // Hand off to the checkout intent, forwarding the caller's callbacks so a\n // third-party site's onComplete still fires when the order completes.\n tl.emit('ui:checkout-requested', {\n onComplete: i?.onComplete,\n onError: i?.onError,\n onClose: i?.onClose,\n });\n });\n\n document.body.appendChild(node);\n el = node;\n };\n\n const offOpen = tl.on('ui:event-modal-requested', (p) => open((p as BuyIntent) ?? ({} as BuyIntent)));\n const offClose = tl.on('ui:modal-close-requested', () => remove());\n\n return () => {\n offOpen();\n offClose();\n remove();\n };\n}\n", "/**\n * Cart money, read from the response rather than assumed.\n *\n * The Elements connector used to publish `fees: 0` and `total = subtotal` on\n * every cart, which is a claim the client had no business making: a channel\n * with a fee profile charges a booking fee at checkout, so a cart that says\n * \"fees 0, total = subtotal\" tells the buyer a total they will not be charged.\n * This module reads whatever the sales surface reports and says plainly when\n * it reports nothing.\n *\n * ## What the surface reports today\n *\n * `SalesCart` (backstage-api `src/domains/sales/http/views/index.ts`, mirrored\n * byte for byte by live-api) is `{ id, status, currency, expiresAt, orderId,\n * items[], itemsSubtotal }`. There is no fee field, no discount field and no\n * total: fees are computed when the cart is checked out, from the channel's\n * fee profile, and land on the ORDER (`totalFees` plus a `type: 'fee'` line\n * item named after the profile's `serviceFeeLabel`). So on today's responses\n * this returns `hasFees: false` and no fee line is rendered - which is correct,\n * and unlike `fees: 0` it does not assert that the buyer pays no fee. The\n * moment a cart response carries the fields, the cart shows the line with no\n * further change here.\n *\n * ## Money\n *\n * Integer minor units everywhere on this platform (2500 = 25.00), so the\n * arithmetic here is integer addition only. A value that is not an integer is\n * not minor units, so it is treated as ABSENT rather than rounded or floated:\n * money never goes through floating point in this module.\n */\n\n/** Shown when the surface names no fee of its own. */\nexport const FEE_LABEL_FALLBACK = 'Booking fee';\n\nexport interface CartTotals {\n /** ISO currency code as the cart reports it, or null when it has none yet. */\n currency: string | null;\n /** Ticket lines, in minor units. */\n subtotal: number;\n /** Fees the surface reports, in minor units. 0 when it reports none. */\n fees: number;\n /** Discount the surface reports, as a positive magnitude in minor units. */\n discount: number;\n /** What the buyer pays: the server's figure whenever it gives one. */\n total: number;\n /**\n * Whether to render a fee line. A fee of zero is not the same as no fee:\n * see {@link expressesFee}.\n */\n hasFees: boolean;\n /** The fee's name as the surface gives it, or null when it names none. */\n feeLabel: string | null;\n /** True when the total came from the response rather than being derived. */\n totalFromServer: boolean;\n}\n\ntype Bag = Record<string, unknown>;\n\nconst bag = (v: unknown): Bag => (v && typeof v === 'object' ? (v as Bag) : {});\n\n/**\n * Minor units, or null when the value is not minor units. Integers and\n * all-digit strings only: a decimal like 12.5 or \"12.50\" is a major-unit\n * amount or a rounding error waiting to happen, and either way it is not\n * something this module will do arithmetic on.\n */\nexport function minorUnits(value: unknown): number | null {\n if (typeof value === 'number') return Number.isInteger(value) ? value : null;\n if (typeof value === 'string' && /^-?\\d+$/.test(value)) return Number(value);\n return null;\n}\n\nconst lineType = (line: Bag): string => (typeof line.type === 'string' ? line.type : 'ticket');\n\n/** Ticket lines: everything the surface has not typed as a fee, tax or discount. */\nconst isTicketLine = (line: Bag): boolean => !['fee', 'tax', 'discount'].includes(lineType(line));\n\n/**\n * The rule, in one place.\n *\n * Render a fee line when the response EXPRESSES a fee: a fee figure above\n * zero, or a fee the surface has named (a `type: 'fee'` line, or a fee label)\n * even when it computes to zero. A response with no fee figure at all, or a\n * bare zero nothing names, expresses no fee and renders no line - a channel\n * with no fee profile looks exactly as it does today, and we never invent a\n * \"Booking fee 0.00\" row the surface did not put there.\n */\nfunction expressesFee(fees: number | null, named: boolean): boolean {\n if (fees === null) return named;\n return fees > 0 || named;\n}\n\n/**\n * Read `subtotal`, `fees`, `discount` and `total` off a cart-shaped response.\n *\n * Field names are backstage-api's, because live-api never reshapes a body:\n * `itemsSubtotal` is what the cart view calls its ticket subtotal today, and\n * `totalFees` / `totalDiscounts` / `total` are what the order view calls the\n * rest - the names a cart view would reuse when it starts carrying them.\n * `fees`, `discount` and `subtotal` are accepted as aliases so a host that\n * already massaged the shape keeps working.\n */\nexport function deriveCartTotals(cart: unknown): CartTotals {\n const c = bag(cart);\n const lines = Array.isArray(c.items) ? c.items.map(bag) : [];\n\n const subtotal =\n minorUnits(c.itemsSubtotal) ??\n minorUnits(c.subtotal) ??\n lines.filter(isTicketLine).reduce((sum, line) => sum + (minorUnits(line.subtotal) ?? 0), 0);\n\n const feeLines = lines.filter((line) => lineType(line) === 'fee');\n const feeLineTotal = feeLines.length\n ? feeLines.reduce((sum, line) => sum + (minorUnits(line.subtotal) ?? 0), 0)\n : null;\n const fees = minorUnits(c.totalFees) ?? minorUnits(c.fees) ?? feeLineTotal;\n\n const labelled = typeof c.feeLabel === 'string' && c.feeLabel ? c.feeLabel : null;\n const namedLine = feeLines.map((line) => line.name).find((n) => typeof n === 'string' && n) as\n | string\n | undefined;\n const feeLabel = labelled ?? namedLine ?? null;\n\n const discountLines = lines.filter((line) => lineType(line) === 'discount');\n const discountLineTotal = discountLines.length\n ? discountLines.reduce((sum, line) => sum + Math.abs(minorUnits(line.subtotal) ?? 0), 0)\n : null;\n const discount = minorUnits(c.totalDiscounts) ?? minorUnits(c.discount) ?? discountLineTotal;\n\n const tax = minorUnits(c.totalTax) ?? 0;\n\n // The server's total is what the buyer is charged. Only derive one when the\n // response carries none, and say which happened so a caller can tell.\n const serverTotal = minorUnits(c.total);\n const total = serverTotal ?? subtotal + (fees ?? 0) + tax - (discount ?? 0);\n\n return {\n currency: typeof c.currency === 'string' ? c.currency : null,\n subtotal,\n fees: fees ?? 0,\n discount: discount ?? 0,\n total,\n hasFees: expressesFee(fees, feeLabel !== null || feeLines.length > 0),\n feeLabel,\n totalFromServer: serverTotal !== null,\n };\n}\n", "/**\n * Elements connector - adapts the stateful {@link TicketlayerLive} facade to the\n * structural interface `@ticketlayer/elements` components consume.\n *\n * Elements never import @ticketlayer/live directly: they bind to a generic\n * shape published on a window global (`setSDK(...)`), so the SDK and the\n * components can ship as separate bundles (e.g. the Elements CDN build). This\n * adapter is the bridge a host (HBO, a promoter site) installs:\n *\n * import { createLiveClient, createElementsConnector } from '@ticketlayer/live';\n * import { setSDK } from '@ticketlayer/elements';\n * const tl = await createLiveClient({ ... });\n * setSDK(createElementsConnector(tl));\n *\n * Two responsibilities the components expect that the facade doesn't expose 1:1:\n * - cart line items need a `categoryId` the components never pass; we resolve\n * it from the ticketTypeId captured when `getTicketTypes()` was called (the\n * ticket selector always loads types before adding - so the cache is warm).\n * - modal verbs (`event(id).openModal()`, `checkout.openModal()`, `closeModal()`)\n * are UI INTENTS: the SDK renders no UI, it relays them onto the shared bus\n * (ui:event-modal-requested / ui:checkout-requested / ui:modal-close-requested)\n * and the host opens the modal. Caller callbacks ride along in the payload.\n */\nimport type { TicketlayerLive, PresaleRedemption } from './createLiveClient.js';\nimport { deriveCartTotals } from './core/cartTotals.js';\n\ninterface CartLike {\n items?: Array<{ quantity?: number }>;\n [k: string]: unknown;\n}\n\nexport interface ModalOptions {\n occurrenceId?: string;\n onComplete?: (order: unknown) => void;\n onError?: (error: Error) => void;\n onClose?: () => void;\n}\n\nexport interface ElementsConnector {\n getEventsManager(): {\n list(options?: { limit?: number; category?: string }): Promise<{ items: unknown[] }>;\n get(eventId: string): Promise<unknown>;\n getTicketTypes(eventId: string, occurrenceId: string): Promise<unknown[]>;\n };\n getCartManager(): {\n get(): Promise<unknown>;\n on(event: string, cb: (data: unknown) => void): () => void;\n off(event: string, cb: (data: unknown) => void): void;\n addItem(ticketTypeId: string, quantity: number, occurrenceId: string): Promise<unknown>;\n addItems(items: Array<{ ticketTypeId: string; quantity: number; occurrenceId: string }>): Promise<unknown>;\n removeItem(itemId: string): Promise<unknown>;\n addSeat(seatId: string, ticketTypeId: string, occurrenceId: string): Promise<unknown>;\n removeSeat(seatId: string, occurrenceId: string): Promise<unknown>;\n };\n getOrdersManager(): {\n mine(): Promise<unknown>;\n get(orderId: string): Promise<unknown>;\n ticketPdf(orderId: string, passId: string): Promise<Blob>;\n };\n /** Magic-link sign-in (tl-login, tl-my-orders). Never sees a password. */\n getAuthManager(): {\n readonly customer: unknown | null;\n readonly authenticated: boolean;\n requestMagicLink(contact: { email?: string; phone?: string }): Promise<unknown>;\n exchange(code: string): Promise<unknown>;\n logout(): Promise<void>;\n };\n /** Presale / promo codes (tl-promo-code). */\n getPresaleManager(): {\n redeem(code: string): Promise<PresaleRedemption>;\n };\n on(event: string, cb: (data: unknown) => void): () => void;\n off(event: string, cb: (data: unknown) => void): void;\n event(eventId: string): { openModal(options?: ModalOptions): void };\n checkout: { openModal(options?: ModalOptions): void; closeModal(): void };\n closeModal(): void;\n}\n\n/**\n * Adapt the sales-surface cart view to the shape Elements consume. The sales\n * view exposes `itemsSubtotal` + per-item `subtotal`; the components (tl-cart,\n * badges) were written against `subtotal`/`total`/`fees` + per-item\n * `totalPrice`. Add those aliases (and itemCount) without dropping the\n * originals - otherwise tl-cart formats undefined \u2192 \u00A3NaN.\n *\n * The money comes from {@link deriveCartTotals}, which reads the response\n * instead of asserting `fees: 0`: `fees`, `discount` and `feeLabel` are\n * whatever the surface reports, `hasFees` is the render-a-fee-line rule, and\n * `total` is the server's figure whenever the response carries one. Money\n * stays minor units.\n */\nconst withCount = (cart: unknown): unknown => {\n if (!cart || typeof cart !== 'object') return cart;\n const c = cart as CartLike & { itemsSubtotal?: number };\n const items: Array<Record<string, unknown>> = (c.items ?? []).map((i) => {\n const it = i as Record<string, unknown>;\n const qty = (it.quantity as number) ?? 0;\n const line = (it.subtotal as number) ?? (it.unitPrice as number) * qty;\n return { ...it, totalPrice: it.totalPrice ?? line };\n });\n const itemCount = items.reduce((sum, i) => sum + ((i.quantity as number) ?? 0), 0);\n const totals = deriveCartTotals(c);\n return {\n ...c,\n items,\n itemCount,\n subtotal: totals.subtotal,\n fees: totals.fees,\n discount: totals.discount,\n total: totals.total,\n hasFees: totals.hasFees,\n feeLabel: totals.feeLabel,\n };\n};\n\nexport function createElementsConnector(tl: TicketlayerLive): ElementsConnector {\n // ticketTypeId \u2192 { categoryId, occurrenceId }, captured on getTicketTypes so\n // addItem/addSeat can supply the categoryId the cart API requires.\n const ttMeta = new Map<string, { categoryId: string; occurrenceId: string }>();\n\n const resolve = (ticketTypeId: string, occurrenceId?: string) => {\n const meta = ttMeta.get(ticketTypeId);\n if (!meta?.categoryId) {\n throw new Error(\n `[live] No category known for ticket type ${ticketTypeId}. ` +\n `Load the occurrence's ticket types (getTicketTypes) before adding it to the cart.`\n );\n }\n return { categoryId: meta.categoryId, occurrenceId: occurrenceId || meta.occurrenceId };\n };\n\n const eventsManager = {\n async list(options?: { limit?: number; category?: string }) {\n const res = (await tl.events.list()) as {\n listings?: Array<{\n id: string;\n eventId?: string;\n name?: string | null;\n shortDescription?: string | null;\n imageUrl?: string | null;\n venueName?: string | null;\n venueCity?: string | null;\n nextOccurrenceAt?: string | null;\n }>;\n } | null;\n // Adapt the sales-surface LISTING shape to the structural shape\n // tl-event-card consumes. Two shape gaps the card otherwise renders blank:\n // - venue/date are flat (venueName/venueCity/nextOccurrenceAt) on the\n // listing but nested (venue.{name,city} / nextOccurrence.startsAt) on\n // the card.\n // - the card reads `imageUrl`; the listing already carries it (surface\n // explicitly rather than relying on a passthrough spread).\n // A listing's own id is the channel-listing id (lst_/schl_), but cards\n // navigate by EVENT id, so we surface eventId as `id`.\n let items = (res?.listings ?? []).map((l) => ({\n id: l.eventId ?? l.id,\n name: l.name ?? '',\n ...(l.shortDescription ? { shortDescription: l.shortDescription } : {}),\n ...(l.imageUrl ? { imageUrl: l.imageUrl } : {}),\n ...(l.venueName\n ? { venue: { id: '', name: l.venueName, city: l.venueCity ?? '' } }\n : {}),\n ...(l.nextOccurrenceAt ? { nextOccurrence: { startsAt: l.nextOccurrenceAt } } : {}),\n availabilityStatus: 'available' as const,\n }));\n if (options?.limit) items = items.slice(0, options.limit);\n return { items };\n },\n get: (eventId: string) => tl.events.get(eventId),\n async getTicketTypes(eventId: string, occurrenceId: string) {\n const ev = (await tl.events.get(eventId)) as {\n occurrences?: Array<{\n id: string;\n ticketTypes?: Array<{\n ticketTypeId: string;\n ticketTypeName: string;\n description: string | null;\n categoryId: string;\n categoryName: string;\n unitPrice: number;\n currency: string;\n }>;\n }>;\n } | null;\n const occ =\n ev?.occurrences?.find((o) => o.id === occurrenceId) ?? ev?.occurrences?.[0];\n const tts = occ?.ticketTypes ?? [];\n return tts.map((tt) => {\n if (occ) ttMeta.set(tt.ticketTypeId, { categoryId: tt.categoryId, occurrenceId: occ.id });\n return {\n id: tt.ticketTypeId,\n name: tt.ticketTypeName,\n description: tt.description,\n price: tt.unitPrice, // minor units; components divide by 100 to display\n currency: tt.currency,\n categoryId: tt.categoryId,\n categoryName: tt.categoryName,\n // The sales surface view doesn't expose per-order limits/remaining yet;\n // sensible defaults until the catalogue view carries them.\n maxPerOrder: 10,\n available: 999,\n };\n });\n },\n };\n\n const cartManager = {\n // Cache-first. The SDK keeps `_cart` authoritative - mutations update it and\n // every `cart:updated` carries the full cart - so Elements reading the cart\n // must NOT each trigger a GET. We return the cached cart and only fetch when\n // nothing is cached yet. This stops the fetch storm when several cart-aware\n // Elements mount, and breaks any cart:updated \u2192 get() \u2192 refresh \u2192\n // cart:updated feedback loop (which was tripping the rate limiter).\n get: async () => withCount(tl.cart.current ?? (await tl.cart.refresh())),\n on: (event: string, cb: (data: unknown) => void) =>\n tl.on(event as never, (p) => cb(event === 'cart:updated' ? withCount(p) : p)),\n off: (event: string, cb: (data: unknown) => void) => tl.off(event as never, cb),\n addItem: async (ticketTypeId: string, quantity: number, occurrenceId: string) => {\n const { categoryId, occurrenceId: occ } = resolve(ticketTypeId, occurrenceId);\n return withCount(await tl.cart.add({ eventOccurrenceId: occ, categoryId, ticketTypeId, quantity }));\n },\n addItems: async (items: Array<{ ticketTypeId: string; quantity: number; occurrenceId: string }>) => {\n let last: unknown = tl.cart.current;\n for (const it of items) last = await cartManager.addItem(it.ticketTypeId, it.quantity, it.occurrenceId);\n return last;\n },\n removeItem: async (itemId: string) => withCount(await tl.cart.remove(itemId)),\n addSeat: async (seatId: string, ticketTypeId: string, occurrenceId: string) => {\n const { categoryId, occurrenceId: occ } = resolve(ticketTypeId, occurrenceId);\n return withCount(\n await tl.cart.add({ eventOccurrenceId: occ, categoryId, ticketTypeId, eventLayoutSeatIds: [seatId] })\n );\n },\n removeSeat: async (_seatId: string, _occurrenceId: string) => {\n // The cart line-item view doesn't expose seat ids, so seat\u2192lineItem can't\n // be mapped here yet. Seat removal flows through removeItem(itemId) until\n // the view carries seat references.\n console.warn('[live] removeSeat is a no-op until cart items expose seat ids; use removeItem(itemId).');\n return withCount((await tl.cart.refresh()) ?? tl.cart.current);\n },\n };\n\n const ordersManager = {\n mine: () => tl.orders.mine(),\n get: (orderId: string) => tl.orders.get(orderId),\n ticketPdf: (orderId: string, passId: string) => tl.orders.ticketPdf(orderId, passId),\n };\n\n // Getters read the facade's session state live, so a component that asks\n // after auth:changed sees the new customer without holding its own copy.\n const authManager = {\n get customer() {\n return tl.auth.customer;\n },\n get authenticated() {\n return tl.auth.authenticated;\n },\n requestMagicLink: (contact: { email?: string; phone?: string }) => tl.auth.requestMagicLink(contact),\n exchange: (code: string) => tl.auth.exchange(code),\n logout: () => tl.auth.logout(),\n };\n\n const presaleManager = {\n redeem: (code: string) => tl.presale.redeem(code),\n };\n\n return {\n getEventsManager: () => eventsManager,\n getCartManager: () => cartManager,\n getOrdersManager: () => ordersManager,\n getAuthManager: () => authManager,\n getPresaleManager: () => presaleManager,\n on: (event: string, cb: (data: unknown) => void) => tl.on(event as never, cb),\n off: (event: string, cb: (data: unknown) => void) => tl.off(event as never, cb),\n event: (eventId: string) => ({\n openModal: (options: ModalOptions = {}) => tl.emit('ui:event-modal-requested', { eventId, ...options }),\n }),\n checkout: {\n openModal: (options: ModalOptions = {}) => tl.emit('ui:checkout-requested', options),\n closeModal: () => tl.emit('ui:modal-close-requested'),\n },\n closeModal: () => tl.emit('ui:modal-close-requested'),\n };\n}\n", "/**\n * Bidirectional event bus shared by the SDK, Elements, and the host app.\n *\n * Two directions:\n * - STATE events the SDK pushes OUT so Elements re-render (cart:updated, \u2026).\n * - UI INTENTS Elements/host push IN for someone else to act on\n * (ui:checkout-requested, ui:event-modal-requested, \u2026) - e.g. a\n * tl-buy-tickets-button emits ui:event-modal-requested and HBO opens the\n * modal. The SDK itself doesn't render UI; it just relays.\n */\nexport type LiveEvent =\n // State (SDK \u2192 subscribers)\n | 'session:changed'\n | 'cart:updated'\n | 'auth:changed'\n | 'checkout:completed'\n | 'error'\n // UI intents (Elements/host \u2192 subscribers)\n | 'ui:event-modal-requested'\n | 'ui:checkout-requested'\n | 'ui:cart-requested'\n | 'ui:login-requested'\n | 'ui:modal-close-requested';\n\ntype Handler = (payload?: unknown) => void;\n\nexport class Emitter {\n private handlers = new Map<LiveEvent, Set<Handler>>();\n\n /** Subscribe; returns an unsubscribe function. */\n on(event: LiveEvent, handler: Handler): () => void {\n if (!this.handlers.has(event)) this.handlers.set(event, new Set());\n this.handlers.get(event)!.add(handler);\n return () => this.off(event, handler);\n }\n\n off(event: LiveEvent, handler: Handler): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n emit(event: LiveEvent, payload?: unknown): void {\n this.handlers.get(event)?.forEach((h) => {\n try {\n h(payload);\n } catch (err) {\n console.error(`[live] handler for ${event} threw`, err);\n }\n });\n }\n}\n", "/**\n * Apply a resolved channel theme to the document as CSS custom properties\n * (browser only; SSR-safe no-op).\n *\n * This is the web harness's half of the token contract, and the only place in\n * this client that writes a `--tl-*` name. What each name is, what it defaults\n * to and which key of the theme document feeds it are not decided here: they\n * come from `@ticketlayer/theme`, which is also where the Elements' defaults\n * come from. `themeToCssVars` returns the declarations, including every alias a\n * token answers to, so a host reading `--tl-color-primary` or the Backstage\n * theme designer's `--tl-base-size` gets the channel's value too.\n *\n * Only the defaults are overridden. A key the theme carries that is not a\n * declared token is ignored; a new one is added in packages/theme/tokens.json,\n * where the Elements and a native harness see it as well.\n */\nimport { themeToCssVars, type ThemeDocument } from '@ticketlayer/theme';\n\nconst STYLE_ID = 'tl-theme-vars';\n\nexport type ResolvedTheme = ThemeDocument;\n\nexport function applyTheme(theme: ResolvedTheme | null | undefined): void {\n if (!theme || typeof document === 'undefined') return;\n\n const vars = Object.entries(themeToCssVars(theme)).map(([name, value]) => `${name}: ${value};`);\n\n let style = document.getElementById(STYLE_ID) as HTMLStyleElement | null;\n if (!style) {\n style = document.createElement('style');\n style.id = STYLE_ID;\n document.head.appendChild(style);\n }\n style.textContent = `:root {\\n ${vars.join('\\n ')}\\n}`;\n}\n", "/**\n * Runtime-neutral core of the Live client.\n *\n * Nothing in this module reads `window`, `document` or `location`: it is the\n * shared state layer (session, cart, auth, orders, the event bus) that both\n * adapters build on - `createLiveClient` (browser: cookie or token transport,\n * page defaults, window publishing, modals) and `createNativeLiveClient`\n * (React Native: injected token storage, X-Live-Session header, no page).\n * `theme.apply()` delegates to applyTheme, which is a no-op without a document.\n */\nimport { LiveClient, LiveAPIError } from '../client.js';\nimport { Emitter, type LiveEvent } from '../state/emitter.js';\nimport { applyTheme } from '../state/theme.js';\n\n/**\n * Stateful ergonomic layer over the generated LiveClient.\n *\n * The generated client is stateless REST; Elements and HBO need a stateful,\n * reactive surface (a session-owned cart, cart:updated events, theme\n * application, auth state). This class provides that, COORDINATING with the\n * live-api session - which owns the cartId server-side - rather than holding a\n * second source of truth: on start it loads the session's existing cart, and\n * cart mutations both update local state AND ride the same session upstream.\n */\n\nexport interface SessionState {\n channelId: string | null;\n customer: unknown | null;\n authenticated: boolean;\n}\n\n/** Result of redeeming a presale/promo code (POST /sales/presale-codes/redeem). */\nexport interface PresaleRedemption {\n benefit: string;\n alreadyHeld: boolean;\n}\n\nexport interface CartItemInput {\n eventOccurrenceId: string;\n categoryId: string;\n ticketTypeId: string;\n quantity?: number;\n eventLayoutAreaId?: string;\n eventLayoutSeatIds?: string[];\n}\n\n/**\n * Pull a named field from a response, tolerating the generator's\n * single-property auto-unwrapping: some methods return `{ cart }`, others\n * already return the cart itself. If `key` is present we use it; otherwise the\n * value is assumed to be the already-unwrapped payload.\n */\nconst field = <T>(obj: unknown, key: string): T | undefined => {\n if (obj && typeof obj === 'object' && !Array.isArray(obj) && key in obj) {\n return (obj as Record<string, unknown>)[key] as T;\n }\n return obj as T | undefined;\n};\n\nexport class TicketlayerLive {\n /** The underlying generated client (escape hatch for un-wrapped calls). */\n readonly client: LiveClient;\n\n private emitter = new Emitter();\n private sessionMode: 'cookie' | 'token';\n private publishableKey: string | undefined;\n private domain: string | undefined;\n private baseUrl: string;\n // A session is created LAZILY - only when something mutates state (cart/login).\n // Browsing uses the publishable key as read auth, so most visitors never get\n // a session (no per-visitor Redis write).\n private _sessionStarted = false;\n private _sessionStarting: Promise<void> | null = null;\n\n private _session: SessionState = { channelId: null, customer: null, authenticated: false };\n private _cart: unknown | null = null;\n private _cartId: string | null = null;\n\n // Namespaces are built in the constructor so their getters/methods close over\n // the instance (`self`) correctly - object-literal getters don't bind `this`.\n readonly events!: { list: () => Promise<unknown>; get: (eventId: string) => Promise<unknown> };\n readonly theme!: { get: () => Promise<unknown>; apply: () => Promise<unknown> };\n readonly cart!: {\n readonly current: unknown | null;\n readonly id: string | null;\n ensure: () => Promise<string>;\n add: (item: CartItemInput) => Promise<unknown>;\n remove: (itemId: string) => Promise<unknown>;\n refresh: () => Promise<unknown>;\n checkout: (opts?: { customerNotes?: string }) => Promise<unknown>;\n };\n readonly auth!: {\n readonly customer: unknown | null;\n readonly authenticated: boolean;\n requestMagicLink: (contact: { email?: string; phone?: string }) => Promise<unknown>;\n exchange: (proof: string | { type: string; code?: string; assertion?: string }) => Promise<unknown>;\n logout: () => Promise<void>;\n };\n readonly orders!: {\n mine: () => Promise<unknown>;\n get: (orderId: string) => Promise<unknown>;\n ticketPdf: (orderId: string, passId: string) => Promise<Blob>;\n };\n readonly payments!: {\n begin: (orderId: string, opts?: { paymentType?: string; returnUrl?: string }) => Promise<unknown>;\n };\n readonly presale!: {\n redeem: (code: string) => Promise<PresaleRedemption>;\n };\n readonly queue!: { status: () => Promise<unknown>; join: () => Promise<unknown> };\n\n constructor(\n client: LiveClient,\n opts: { sessionMode: 'cookie' | 'token'; publishableKey?: string; domain?: string; baseUrl: string }\n ) {\n this.client = client;\n this.sessionMode = opts.sessionMode;\n this.publishableKey = opts.publishableKey;\n this.domain = opts.domain;\n this.baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n const self = this;\n\n this.events = {\n list: () => self.client.salesListings.list(),\n get: (eventId) => self.client.sales.get(eventId).then((d) => field(d, 'event')),\n };\n\n this.theme = {\n get: () => self.client.sales.getTheme().then((d) => field(d, 'theme')),\n apply: async () => {\n const theme = await self.theme.get();\n applyTheme(theme as never);\n return theme;\n },\n };\n\n this.cart = {\n get current() {\n return self._cart;\n },\n get id() {\n return self._cartId;\n },\n ensure: async () => {\n if (!self._cartId) {\n // First mutation \u2192 create the session lazily, then the cart.\n await self.ensureSession();\n const res = await self.client.salesCarts.create({});\n const cart = field<{ id: string }>(res, 'cart');\n self._cartId = cart?.id ?? null;\n self._setCart(cart);\n }\n return self._cartId!;\n },\n add: async (item) => {\n const id = await self.cart.ensure();\n try {\n const res = await self.client.salesCarts.addItem(id, item);\n self._setCart(field(res, 'cart'));\n return self._cart;\n } catch (err) {\n if (!self._isCartGone(err)) throw err;\n // The server-side reservation lapsed under us. Drop the dead cart,\n // mint a fresh one and re-add - adding tickets should just work.\n self._resetCart();\n const freshId = await self.cart.ensure();\n const res = await self.client.salesCarts.addItem(freshId, item);\n self._setCart(field(res, 'cart'));\n return self._cart;\n }\n },\n remove: async (itemId) => {\n if (!self._cartId) return self._cart;\n try {\n const res = await self.client.salesCarts.removeItem(self._cartId, itemId);\n self._setCart(field(res, 'cart'));\n return self._cart;\n } catch (err) {\n if (!self._isCartGone(err)) throw err;\n // Nothing to remove from an expired cart - clear it locally and let\n // the UI fall through to an empty cart rather than surfacing an error.\n self._resetCart();\n return self._cart;\n }\n },\n refresh: async () => {\n if (!self._cartId) return self._cart;\n try {\n const res = await self.client.salesCarts.get(self._cartId);\n self._setCart(field(res, 'cart'));\n return self._cart;\n } catch (err) {\n if (!self._isCartGone(err)) throw err;\n // A stale cartId carried in from a prior session/page load. Forget it\n // so the next mutation starts a clean cart.\n self._resetCart();\n return self._cart;\n }\n },\n checkout: async (opts = {}) => {\n if (!self._cartId) throw new Error('No cart to check out');\n try {\n const res = await self.client.salesCarts.checkout(self._cartId, opts as never);\n self._cartId = null;\n self._setCart(null);\n self.emitter.emit('checkout:completed', field(res, 'order'));\n return res; // { cart, order, orderAccessToken }\n } catch (err) {\n if (!self._isCartGone(err)) throw err;\n // Can't check out an expired cart - clear it and surface a clear,\n // actionable error instead of the raw 409.\n self._resetCart();\n throw new LiveAPIError(\n 'Your cart has expired. Please add your tickets again.',\n 'CART_EXPIRED',\n 409,\n );\n }\n },\n };\n\n this.auth = {\n get customer() {\n return self._session.customer;\n },\n get authenticated() {\n return self._session.authenticated;\n },\n requestMagicLink: (contact) => self.client.salesCustomerAuth.magicLink(contact),\n exchange: async (proof) => {\n // Exchanging a proof binds a customer to THIS session \u2192 ensure one exists.\n await self.ensureSession();\n const body = typeof proof === 'string' ? { type: 'magic_link', code: proof } : proof;\n const res = await self.client.salesCustomerTokens.create({ proof: body });\n self._session = {\n ...self._session,\n customer: field(res, 'customer') ?? null,\n authenticated: true,\n };\n self.emitter.emit('auth:changed', self._session);\n return res;\n },\n logout: async () => {\n await self.client.session.end().catch(() => undefined);\n self._session = { channelId: self._session.channelId, customer: null, authenticated: false };\n self._cart = null;\n self._cartId = null;\n self.emitter.emit('auth:changed', self._session);\n },\n };\n\n this.orders = {\n mine: () => self.client.salesMyOrders.list().then((d) => field(d, 'orders')),\n get: (orderId) => self.client.salesOrders.get(orderId).then((d) => field(d, 'order')),\n // Binary download - bypasses the generated (JSON) client; fetches the PDF\n // with the same session credentials.\n ticketPdf: async (orderId, passId) => {\n const headers: Record<string, string> = {};\n if (self.publishableKey) headers['Authorization'] = `Bearer ${self.publishableKey}`;\n if (self.sessionMode === 'token') {\n const token = await self.client.getSessionToken();\n if (token) headers['X-Live-Session'] = token;\n }\n const res = await fetch(\n `${self.baseUrl}/sales/orders/${orderId}/passes/${passId}/ticket.pdf`,\n { headers, credentials: self.sessionMode === 'cookie' ? 'include' : 'same-origin' },\n );\n if (!res.ok) throw new LiveAPIError(`Failed to download ticket (${res.status})`, 'TICKET_PDF_FAILED', res.status);\n return res.blob();\n },\n };\n\n this.payments = {\n begin: (orderId, opts = {}) =>\n self.client.salesOrderPayments.create(orderId, opts as never).then((d) => field(d, 'payment')),\n };\n\n this.presale = {\n // POST /sales/presale-codes/redeem - needs a signed-in customer. Gated\n // pricing unlocks immediately, so re-read the cart and let cart:updated\n // carry the new totals to subscribers. A failed refresh must not undo a\n // redemption that already succeeded.\n redeem: async (code) => {\n const res = (await self.client.salesPresaleCodes.redeem({ code: code.trim() })) as PresaleRedemption;\n if (self._cartId) await self.cart.refresh().catch(() => undefined);\n return res;\n },\n };\n\n this.queue = {\n status: () => self.client.queue.status(),\n join: () => self.client.queue.join(),\n };\n }\n\n /** Subscribe to a state event or UI intent; returns an unsubscribe fn. */\n on(event: LiveEvent, handler: (payload?: unknown) => void): () => void {\n return this.emitter.on(event, handler);\n }\n off(event: LiveEvent, handler: (payload?: unknown) => void): void {\n this.emitter.off(event, handler);\n }\n /**\n * Push an event onto the shared bus. Used by Elements/host to raise UI\n * intents (e.g. ui:checkout-requested) that the host app acts on - the SDK\n * relays but does not render UI itself.\n */\n emit(event: LiveEvent, payload?: unknown): void {\n this.emitter.emit(event, payload);\n }\n\n get session(): Readonly<SessionState> {\n return this._session;\n }\n\n /** True once a session has been created/resumed (i.e. a mutation has happened). */\n get hasSession(): boolean {\n return this._sessionStarted;\n }\n\n /**\n * Create the Live session on demand and hydrate state - idempotent and\n * single-flight. Called lazily before the first mutation (cart/login); NOT on\n * page load, so browsing never creates a session. Channel is identified by the\n * publishable key (embed) or the storefront domain (hosted).\n */\n async ensureSession(): Promise<void> {\n if (this._sessionStarted) return;\n if (this._sessionStarting) return this._sessionStarting;\n\n this._sessionStarting = (async () => {\n // Embed (token transport) authenticates the session by publishable key;\n // hosted (cookie transport) by storefront domain.\n const startBody: Record<string, string> = {};\n if (this.sessionMode === 'token' && this.publishableKey) {\n startBody.channelKey = this.publishableKey;\n } else if (this.domain) {\n startBody.domain = this.domain;\n } else if (this.publishableKey) {\n startBody.channelKey = this.publishableKey;\n }\n\n const started = await this.client.session.start(startBody as never);\n if (this.sessionMode === 'token') {\n const token = field<string>(started, 'sessionToken');\n if (token) await this.client.setSessionToken(token);\n }\n this._sessionStarted = true;\n await this.refreshSession();\n })();\n\n try {\n await this._sessionStarting;\n } finally {\n this._sessionStarting = null;\n }\n }\n\n /** @deprecated Use ensureSession(); kept for back-compat. */\n async start(opts: { domain?: string } = {}): Promise<void> {\n if (opts.domain) this.domain = opts.domain;\n return this.ensureSession();\n }\n\n /**\n * Rehydrate an ALREADY-EXISTING session (hosted/cookie transport) without\n * creating one. On a page load/refresh the client is lazily session-less, but\n * a returning visitor may still hold the `live_session` cookie with a cart\n * server-side. This probes `GET /session` (a cheap read - it 401s when no\n * session exists, and never writes one): on success it binds this client to\n * that session and pulls the cart back in; on 401 it stays session-less so\n * browsing still creates no session. Marking `_sessionStarted` on success is\n * load-bearing - otherwise the next mutation's ensureSession() would POST a\n * fresh session and orphan the existing cart.\n *\n * @returns true if an existing session was resumed.\n */\n async resumeIfExists(): Promise<boolean> {\n if (this._sessionStarted) return true;\n try {\n await this.refreshSession();\n this._sessionStarted = true;\n return true;\n } catch {\n // 401 NO_SESSION (or transient) \u2192 no session to resume; remain lazy.\n return false;\n }\n }\n\n /**\n * Resume an EXISTING session by token instead of bootstrapping a new one.\n * Used by the embedded checkout iframe: the third-party page hands off its\n * session token so the iframe sees the same cart/channel (token transport).\n */\n async resume(token: string): Promise<void> {\n await this.client.setSessionToken(token);\n this._sessionStarted = true;\n await this.refreshSession();\n }\n\n /** The current session token (token mode), for handing off to an embed iframe. */\n getSessionToken(): Promise<string | null> {\n return this.client.getSessionToken();\n }\n\n /** Re-read session state (customer, auth, cart) from the live-api session. */\n async refreshSession(): Promise<void> {\n const cur = await this.client.session.current();\n this._session = {\n channelId: field<{ id: string }>(cur, 'channel')?.id ?? null,\n customer: field(cur, 'customer') ?? null,\n authenticated: !!field<boolean>(cur, 'authenticated'),\n };\n const cartId = field<string>(cur, 'cartId') ?? null;\n if (cartId) {\n this._cartId = cartId;\n await this.cart.refresh();\n }\n this.emitter.emit('session:changed', this._session);\n }\n\n /**\n * Forget that a session was started, so the next mutation or sign-in mints a\n * fresh one. For adapters whose process outlives the session (a native app\n * signing out, a stored token the API rejected); a browser page reloads instead.\n */\n protected _resetSessionStarted(): void {\n this._sessionStarted = false;\n this._sessionStarting = null;\n }\n\n private _setCart(cart: unknown): void {\n this._cart = cart ?? null;\n this.emitter.emit('cart:updated', this._cart);\n }\n\n /**\n * True when an API error means the server-side cart is no longer usable -\n * it expired (reservation TTL lapsed), was already checked out, or can't be\n * found. The SDK holds the cartId in memory and rehydrates it from the\n * server session on load, so a lapsed cart would otherwise wedge every\n * subsequent add/remove/checkout with a 409.\n */\n private _isCartGone(err: unknown): boolean {\n if (!(err instanceof LiveAPIError)) return false;\n return (\n err.code === 'CART_EXPIRED' ||\n err.code === 'CART_NOT_ACTIVE' ||\n err.code === 'CART_NOT_FOUND' ||\n err.status === 404\n );\n }\n\n /** Forget all local cart state and notify subscribers the cart is now empty. */\n private _resetCart(): void {\n this._cartId = null;\n this._setCart(null);\n }\n}\n", "import { LiveClient, type LiveClientConfig } from './client.js';\nimport { publishClient } from './state/registry.js';\nimport { loadElements, type LoadElementsOptions } from './state/loadElements.js';\nimport { installCheckoutModal, type CheckoutModalOptions } from './state/checkoutModal.js';\nimport { installBuyModal } from './state/buyModal.js';\nimport { createElementsConnector } from './elements.js';\nimport { API_DATED_VERSION } from './client.js';\nimport { TicketlayerLive } from './core/liveClient.js';\n\n/**\n * Browser adapter over the runtime-neutral core in ./core/liveClient.ts:\n * resolves the channel from the page host, picks the session transport\n * (cookie for a hosted storefront, token for embeds), publishes the client on\n * `window.Ticketlayer`, applies the theme and mounts the modals. The class\n * itself is re-exported here so existing imports keep working.\n */\nexport { TicketlayerLive };\nexport type { PresaleRedemption, SessionState, CartItemInput } from './core/liveClient.js';\n\nexport interface CreateLiveClientOptions extends LiveClientConfig, LoadElementsOptions {\n /** Storefront host to resolve the channel from (hosted mode). Defaults to the page host. */\n domain?: string;\n /** Bootstrap the session immediately (default true). */\n autoStart?: boolean;\n /** Fetch + apply the channel theme on start (default true in the browser). */\n applyTheme?: boolean;\n /**\n * Publish this client on `window.Ticketlayer` so Elements can find + bind to\n * it (default true in the browser). Set false to keep the client private.\n */\n publish?: boolean;\n /**\n * Resume an existing session by token (token transport) instead of\n * bootstrapping a new one. Used by the embedded checkout iframe to inherit\n * the parent page's cart/session. Forces sessionMode 'token'.\n */\n sessionToken?: string;\n /**\n * Checkout rendering. 'modal' (third-party embeds) auto-opens the hosted\n * checkout in an iframe overlay on `ui:checkout-requested`. Omit on HBO,\n * which handles that intent by navigating to /checkout in-page.\n */\n checkout?: { mode: 'modal' } & CheckoutModalOptions;\n /**\n * Mount the in-page buy-tickets modal (occurrence \u2192 ticket selection) on\n * `ui:event-modal-requested`. Native Elements overlay, no iframe - works on\n * HBO and embeds alike. Defaults to true in the browser for the published\n * client; set false to opt out.\n */\n buyModal?: boolean;\n}\n\n\n/** Resolve a hosted storefront's publishable key by domain (GET /channel). */\nasync function resolveChannelKey(baseUrl: string, domain: string): Promise<string | undefined> {\n try {\n const res = await fetch(\n `${baseUrl.replace(/\\/$/, '')}/channel?domain=${encodeURIComponent(domain)}`,\n { headers: { accept: 'application/json' } }\n );\n if (!res.ok) return undefined;\n const json = (await res.json()) as { data?: { publishableKey?: string } };\n return json?.data?.publishableKey;\n } catch {\n return undefined;\n }\n}\n\nexport async function createLiveClient(options: CreateLiveClientOptions): Promise<TicketlayerLive> {\n const domain =\n options.domain ?? (typeof window !== 'undefined' ? window.location.host : undefined);\n\n // Resolve the channel's publishable key - the READ credential. Embeds pass it\n // directly; a hosted storefront resolves it ONCE by domain and then uses it\n // for all reads (no per-read domain lookup, no session). Browsing never\n // creates a session - that happens lazily on the first mutation/login.\n let publishableKey = options.publishableKey;\n if (!publishableKey && !options.sessionToken && domain) {\n publishableKey = await resolveChannelKey(options.baseUrl, domain);\n }\n\n // Transport: embed/handoff use the header (token); a hosted storefront uses\n // the cookie for its (lazily-created) session.\n const isEmbed = !!options.publishableKey || !!options.sessionToken;\n const sessionMode = options.sessionMode ?? (isEmbed ? 'token' : 'cookie');\n const client = new LiveClient({\n ...options,\n sessionMode,\n ...(publishableKey ? { publishableKey } : {}),\n });\n const tl = new TicketlayerLive(client, {\n sessionMode,\n baseUrl: options.baseUrl,\n ...(publishableKey ? { publishableKey } : {}),\n ...(domain ? { domain } : {}),\n });\n\n // Publish the singleton + Elements connector so Elements bind immediately.\n if (options.publish !== false && typeof window !== 'undefined') {\n publishClient(tl, createElementsConnector(tl), API_DATED_VERSION);\n }\n\n // Third-party embeds: auto-open the hosted checkout iframe on checkout intents.\n if (options.checkout?.mode === 'modal' && typeof window !== 'undefined') {\n installCheckoutModal(tl, options.checkout);\n }\n\n // In-page buy-tickets modal (occurrence \u2192 ticket selection). Native Elements\n // overlay mounted on `ui:event-modal-requested`; works on HBO and embeds. Tied\n // to the published client (the one driving on-page UI), opt out via buyModal.\n if (options.buyModal !== false && options.publish !== false && typeof window !== 'undefined') {\n installBuyModal(tl);\n }\n\n // loadElements REJECTS when the network or the bundle fails, which is\n // logged and survivable, and THROWS synchronously when the options ask for\n // something that cannot be verified (an exact-version elementsUrl with no\n // elementsIntegrity, a hash with no URL). That throw is deliberately outside\n // the catch: a host that pinned the bundle and lost the hash gets a failed\n // createLiveClient, not a quietly unverified checkout. See\n // state/loadElements.ts for the rule in full.\n const elementsLoad = loadElements(options).catch((err) => {\n console.error('[live] Elements auto-load failed', err);\n });\n\n if (options.autoStart !== false) {\n // Embed iframe resumes a handed-off session; everyone else stays\n // session-less until the first mutation. Theme applies via the pk.\n if (options.sessionToken) {\n await tl.resume(options.sessionToken);\n } else if (sessionMode === 'cookie' && typeof window !== 'undefined') {\n // Hosted browser: if a session cookie already exists (a returning visitor\n // mid-purchase, or a refresh/deep-link), rehydrate its cart without\n // creating a session. A brand-new visitor 401s here and stays lazy.\n await tl.resumeIfExists().catch(() => undefined);\n }\n if (options.applyTheme !== false && typeof window !== 'undefined') {\n await tl.theme.apply().catch(() => undefined);\n }\n }\n\n await elementsLoad;\n return tl;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Drop-in auto-init for the CDN/UMD build (`dist/ticketlayer.js`).\n *\n * This is the \"one line of code\" embed - what a Webflow/Framer/any site drops in:\n *\n * <script src=\"https://cdn.ticketlayer.com/v1/ticketlayer.js\"\n * data-publishable-key=\"tlpk_...\"\n * data-api-url=\"https://live-api.ticketlayer.com\"\n * data-checkout-base=\"https://checkout.ticketlayer.com\"></script>\n *\n * `data-elements-url` and `data-elements-integrity` travel together and are\n * what an installed site is pinned with (the Webflow Integration Service\n * writes both). An exact-version `data-elements-url` without the hash is\n * refused rather than loaded unverified - see state/loadElements.ts.\n *\n * On load it boots a Live client from the script tag's data-* attributes:\n * publishes `window.Ticketlayer` (so `@ticketlayer/elements` bind), injects the\n * Elements bundle, and installs the hosted iframe checkout modal. Plain HTML\n * custom-element tags (`<tl-event-list>`, `<tl-buy-tickets-button event-id>`)\n * then just work - no bundler, no framework.\n *\n * The IIFE also exposes the SDK on `window.TicketlayerLive` (createLiveClient,\n * boot) for sites that want manual control instead of the data-attribute path.\n *\n * NOTE: index.ts (the npm/bundler entry) does NOT import this module, so only\n * the CDN build auto-boots. Booting is idempotent and a no-op without a key.\n */\nimport { createLiveClient, TicketlayerLive } from './createLiveClient.js';\n\ninterface BootWindow {\n Ticketlayer?: unknown;\n ticketlayer?: { ready: Promise<TicketlayerLive | null> };\n __tlBooted?: boolean;\n}\n\ninterface DropInConfig {\n publishableKey?: string;\n apiUrl?: string;\n elementsUrl?: string;\n elementsIntegrity?: string;\n checkoutBase?: string;\n autoElements: boolean;\n}\n\n/** Read config off the embedding <script> tag's data-* attributes. */\nfunction readConfig(): DropInConfig | null {\n if (typeof document === 'undefined') return null;\n const el =\n (document.currentScript as HTMLScriptElement | null) ??\n document.querySelector<HTMLScriptElement>('script[data-publishable-key]');\n if (!el) return null;\n const d = el.dataset;\n return {\n publishableKey: d.publishableKey,\n apiUrl: d.apiUrl,\n elementsUrl: d.elementsUrl,\n elementsIntegrity: d.elementsIntegrity,\n checkoutBase: d.checkoutBase,\n // Inject @ticketlayer/elements unless explicitly opted out (data-elements=\"false\").\n autoElements: d.elements !== 'false',\n };\n}\n\n/**\n * Boot a Live client from the script tag's data-* attributes. Returns the\n * client (or null when there's no publishable key / not in a browser). Safe to\n * call once; subsequent calls no-op.\n */\nexport function boot(): Promise<TicketlayerLive | null> {\n if (typeof window === 'undefined') return Promise.resolve(null);\n const w = window as unknown as BootWindow;\n if (w.__tlBooted) return w.ticketlayer?.ready ?? Promise.resolve(null);\n\n const cfg = readConfig();\n if (!cfg?.publishableKey) return Promise.resolve(null); // manual usage - nothing to boot\n if (!cfg.apiUrl) {\n console.error('[ticketlayer] Missing data-api-url on the embed script; cannot auto-init.');\n return Promise.resolve(null);\n }\n\n w.__tlBooted = true;\n const ready = createLiveClient({\n baseUrl: cfg.apiUrl,\n publishableKey: cfg.publishableKey,\n elements: cfg.autoElements,\n ...(cfg.elementsUrl ? { elementsUrl: cfg.elementsUrl } : {}),\n ...(cfg.elementsIntegrity ? { elementsIntegrity: cfg.elementsIntegrity } : {}),\n checkout: { mode: 'modal', ...(cfg.checkoutBase ? { embedBaseUrl: cfg.checkoutBase } : {}) },\n }).catch((err) => {\n console.error('[ticketlayer] Failed to initialise:', err);\n return null;\n });\n\n w.ticketlayer = { ready };\n return ready;\n}\n\n// Manual-use surface on the global (the IIFE's globalName is TicketlayerLive).\nexport { createLiveClient, TicketlayerLive };\n\n// Auto-boot on load.\nvoid boot();\n", "/**\n * GENERATED FILE - written from package.json by the prebuild script.\n * Do not edit; do not commit.\n */\nexport const SDK_NAME = \"@ticketlayer/live\";\nexport const SDK_VERSION = \"1.0.0\";\n", "/**\n * GENERATED FILE - do not edit by hand.\n * @ticketlayer/live client generated from the backstage sales surface\n * (spec 1.0.0) + live-api (0.1.0)\n * by backstage-sdk-tooling 0.1.0 on 2026-09-15T10:18:42.096Z.\n * Regenerate with `tt sdk live`.\n */\nimport type { components } from './generated/types';\nimport { SDK_NAME, SDK_VERSION } from './version.js';\n\ntype AttachOrderAccessBody = components['schemas']['AttachOrderAccessBody'];\ntype CreateSalesOrderPaymentResponse = components['schemas']['CreateSalesOrderPaymentResponse'];\ntype CreateSalesRefundRequestResponse = components['schemas']['CreateSalesRefundRequestResponse'];\ntype CreateSessionBody = components['schemas']['CreateSessionBody'];\ntype GetSalesListingsResponse = components['schemas']['GetSalesListingsResponse'];\ntype GetSalesOrderResponse = components['schemas']['GetSalesOrderResponse'];\ntype ListMySalesOrdersResponse = components['schemas']['ListMySalesOrdersResponse'];\ntype RedeemSalesPresaleCodeResponse = components['schemas']['RedeemSalesPresaleCodeResponse'];\ntype SalesCartResponse = components['schemas']['SalesCartResponse'];\ntype SalesCheckoutResponse = components['schemas']['SalesCheckoutResponse'];\ntype SalesCustomerResponse = components['schemas']['SalesCustomerResponse'];\ntype SalesCustomerTokenResponse = components['schemas']['SalesCustomerTokenResponse'];\ntype SalesEventDetailResponse = components['schemas']['SalesEventDetailResponse'];\ntype SalesMagicLinkResponse = components['schemas']['SalesMagicLinkResponse'];\ntype SalesResolveChannelResponse = components['schemas']['SalesResolveChannelResponse'];\ntype SalesThemeResponse = components['schemas']['SalesThemeResponse'];\n\n/**\n * The dated API version (TL-Version) this SDK speaks. Stamped at generation\n * time; the Live/sales surface keeps serving this version's behaviour even as\n * the API evolves. See https://docs.ticketlayer.com/api/versions\n */\nexport const API_DATED_VERSION = '2026-06-13';\n\n/** Best-effort description of the JavaScript runtime, for the TL-Client header. */\nfunction describeRuntime(): string {\n const g = globalThis as Record<string, any>;\n if (g.navigator?.product === 'ReactNative') return 'react-native';\n if (typeof g.window !== 'undefined' && typeof g.document !== 'undefined') return 'browser';\n if (g.process?.versions?.node) return `node/${g.process.versions.node}`;\n if (g.EdgeRuntime) return 'edge';\n return 'unknown';\n}\n\n/**\n * Identifies this SDK build to the API, sent as the TL-Client request header:\n * `ticketlayer-live/<package version> (<runtime>)`. SDK_VERSION comes from\n * src/version.ts, which the package's prebuild writes from package.json so the\n * header always names the version npm published.\n */\nexport const SDK_CLIENT_HEADER = `${SDK_NAME.replace(/^@/, '').replace('/', '-')}/${SDK_VERSION} (${describeRuntime()})`;\n\n/** Pluggable token storage so the SDK runs in browser, React Native, etc. */\nexport interface LiveTokenStorage {\n get(): string | null | Promise<string | null>;\n set(token: string): void | Promise<void>;\n clear(): void | Promise<void>;\n}\n\n/** In-memory storage (default; embeds/SSR). */\nexport function memoryTokenStorage(): LiveTokenStorage {\n let token: string | null = null;\n return {\n get: () => token,\n set: (t) => {\n token = t;\n },\n clear: () => {\n token = null;\n },\n };\n}\n\nexport interface LiveClientConfig {\n /** Base URL of a Live deployment (or the sales surface directly). */\n baseUrl: string;\n /**\n * Session transport:\n * - 'cookie' (hosted web): the live_session httpOnly cookie travels\n * automatically with credentials: 'include'; no token is held client-side.\n * - 'token' (embeds / React Native / native): the session id is held by the\n * SDK and sent as the X-Live-Session header.\n */\n sessionMode?: 'cookie' | 'token';\n /** For embeds/native: the channel's publishable key (tlpk_\u2026). */\n publishableKey?: string;\n /** Token storage for 'token' session mode (defaults to in-memory). */\n tokenStorage?: LiveTokenStorage;\n /** Override the dated API version sent as TL-Version. */\n apiVersion?: string;\n /** Extra headers sent on every request (merged under per-call headers). */\n headers?: Record<string, string>;\n}\n\nexport class LiveAPIError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly status: number\n ) {\n super(message);\n this.name = 'LiveAPIError';\n }\n}\n\n/**\n * Generated Live client. Mirrors the sales surface (byte-for-byte views) plus\n * the Live-only /session and /queue operations. Auth is the Live session\n * (cookie on hosted web; X-Live-Session header elsewhere) + the channel\n * publishable key for embeds. Browser ergonomics live in createLiveClient.\n */\nexport class LiveClient {\n private baseUrl: string;\n private sessionMode: 'cookie' | 'token';\n private publishableKey?: string;\n private tokenStorage: LiveTokenStorage;\n private apiVersion: string;\n private headers: Record<string, string>;\n\n constructor(config: LiveClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.sessionMode = config.sessionMode ?? 'cookie';\n this.publishableKey = config.publishableKey;\n this.tokenStorage = config.tokenStorage ?? memoryTokenStorage();\n this.apiVersion = config.apiVersion ?? API_DATED_VERSION;\n this.headers = config.headers ?? {};\n }\n\n /** Store the Live session id (token mode). Called after POST /session. */\n async setSessionToken(token: string): Promise<void> {\n await this.tokenStorage.set(token);\n }\n\n /** The current session token (token mode), if any - used for embed handoff. */\n async getSessionToken(): Promise<string | null> {\n return this.tokenStorage.get();\n }\n\n async clearSession(): Promise<void> {\n await this.tokenStorage.clear();\n }\n\n /**\n * Make a request to the Live deployment. Live serves at the root (no /v1\n * prefix). Injects the publishable key + session header + TL-Version, and\n * unwraps the JSend envelope.\n */\n private async request<T>(path: string, options: RequestInit = {}): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'TL-Version': this.apiVersion,\n 'TL-Client': SDK_CLIENT_HEADER,\n ...this.headers,\n ...(options.headers as Record<string, string> | undefined),\n };\n\n if (this.publishableKey) {\n headers['Authorization'] = `Bearer ${this.publishableKey}`;\n }\n\n if (this.sessionMode === 'token') {\n const token = await this.tokenStorage.get();\n if (token) headers['X-Live-Session'] = token;\n }\n\n const response = await fetch(url, {\n ...options,\n headers,\n // Hosted web relies on the session cookie travelling with the request\n credentials: this.sessionMode === 'cookie' ? 'include' : 'same-origin',\n });\n\n const text = await response.text();\n const json = text ? JSON.parse(text) : null;\n\n if (!response.ok) {\n const error = json?.error ?? {};\n throw new LiveAPIError(\n error.message ?? `Request failed (${response.status})`,\n error.code ?? 'REQUEST_FAILED',\n response.status\n );\n }\n\n // Unwrap JSend: { status, data, metadata } \u2192 data\n if (json && json.status === 'success' && json.data !== undefined) {\n return json.data as T;\n }\n return json as T;\n }\n\n /**\n * Sales Listings methods\n */\n salesListings = {\n /**\n * List active listings\n * What is on sale through this channel right now. The channel is resolved from the key, never from a parameter.\n * @operationId listSalesListings\n */\n list: async () => {\n const response = await this.request<GetSalesListingsResponse>(`/sales/listings`, {\n method: 'GET'\n });\n\n return response;\n }\n };\n\n /**\n * Sales Customer Auth methods\n */\n salesCustomerAuth = {\n /**\n * Request magic link\n * Start a magic-link sign-in for a customer. Always reports success - account existence is never revealed.\n * @operationId requestSalesMagicLink\n */\n magicLink: async (request: { email?: string; phone?: string }) => {\n const response = await this.request<SalesMagicLinkResponse>(`/sales/customer-auth/magic-link`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.sent;\n }\n };\n\n /**\n * Sales Customer Tokens methods\n */\n salesCustomerTokens = {\n /**\n * Exchange identity proof for customer token\n * Exchange an identity proof (magic-link code or partner assertion) for a short-lived customer token bound to this channel. Identity is exchanged, never asserted.\n * @operationId createSalesCustomerToken\n */\n create: async (request: { proof: any }) => {\n const response = await this.request<SalesCustomerTokenResponse>(`/sales/customer-tokens`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response;\n },\n\n /**\n * Refresh a customer token\n * Re-signs a still-valid customer token (presented via X-Customer-Token) for a fresh 30 minutes, carrying the original 24-hour absolute ceiling forward. Once the ceiling passes the customer must re-authenticate.\n * @operationId refreshSalesCustomerToken\n */\n refresh: async () => {\n const response = await this.request<SalesCustomerTokenResponse>(`/sales/customer-tokens/refresh`, {\n method: 'POST'\n });\n\n return response;\n }\n };\n\n /**\n * Sales Carts methods\n */\n salesCarts = {\n /**\n * Create cart\n * Create a cart on this channel. Customer identity comes only from a verified customer token, never from the body.\n * @operationId createSalesCart\n */\n create: async (request: { metadata?: Record<string, any> }) => {\n const response = await this.request<SalesCartResponse>(`/sales/carts`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.cart;\n },\n\n /**\n * Get cart\n * Get a cart with its items\n * @operationId getSalesCart\n */\n get: async (cartId: string) => {\n const response = await this.request<SalesCartResponse>(`/sales/carts/${cartId}`, {\n method: 'GET'\n });\n\n return response.cart;\n },\n\n /**\n * Add cart item\n * Add an item to the cart, taking a real inventory reservation with the channel's TTL\n * @operationId addSalesCartItem\n */\n addItem: async (cartId: string, request: { eventOccurrenceId: string; categoryId: string; ticketTypeId: string; quantity?: number; eventLayoutAreaId?: string; eventLayoutSeatIds?: string[] }) => {\n const response = await this.request<SalesCartResponse>(`/sales/carts/${cartId}/items`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.cart;\n },\n\n /**\n * Remove cart item\n * Remove an item from the cart, releasing its reservation\n * @operationId removeSalesCartItem\n */\n removeItem: async (cartId: string, itemId: string) => {\n const response = await this.request<SalesCartResponse>(`/sales/carts/${cartId}/items/${itemId}`, {\n method: 'DELETE'\n });\n\n return response.cart;\n },\n\n /**\n * Checkout cart\n * Convert the cart into an order. Returns an order access token for possession-based guest access (confirmation page, payment status polling).\n * @operationId checkoutSalesCart\n */\n checkout: async (cartId: string, request: { customerNotes?: string; metadata?: Record<string, any>; customer?: { email: string; firstName?: string; lastName?: string; phone?: string; marketingConsent?: boolean } }) => {\n const response = await this.request<SalesCheckoutResponse>(`/sales/carts/${cartId}/checkout`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response;\n }\n };\n\n /**\n * Sales My Orders methods\n */\n salesMyOrders = {\n /**\n * List my orders\n * The verified customer's own orders. Requires a customer token - orders cannot be listed with key or possession credentials alone.\n * @operationId listMySalesOrders\n */\n list: async () => {\n const response = await this.request<ListMySalesOrdersResponse>(`/sales/my-orders`, {\n method: 'GET'\n });\n\n return response.orders;\n }\n };\n\n /**\n * Sales Orders methods\n */\n salesOrders = {\n /**\n * Get order\n * Get an order on this channel. Access requires a secret key (own channel), an X-Order-Access-Token header (guest possession) or a customer token (own orders).\n * @operationId getSalesOrder\n */\n get: async (orderId: string) => {\n const response = await this.request<GetSalesOrderResponse>(`/sales/orders/${orderId}`, {\n method: 'GET'\n });\n\n return response.order;\n },\n\n /**\n * Download a ticket PDF\n * Render and stream a pass as a PDF ticket (application/pdf) for the holder. Order-access gated. Browsers fetch this directly rather than through the typed SDK.\n * @operationId getSalesOrderTicketPdf\n */\n ticketPdf: async (orderId: string, passId: string) => {\n const response = await this.request<any>(`/sales/orders/${orderId}/passes/${passId}/ticket.pdf`, {\n method: 'GET'\n });\n\n return response;\n }\n };\n\n /**\n * Sales Order Payments methods\n */\n salesOrderPayments = {\n /**\n * Create order payment\n * Initiate payment for the order's outstanding balance through the channel's payment provider\n * @operationId createSalesOrderPayment\n */\n create: async (orderId: string, request: { paymentType?: 'online_card' | 'online_bank_transfer' | 'online_wallet'; returnUrl?: string }) => {\n const response = await this.request<CreateSalesOrderPaymentResponse>(`/sales/orders/${orderId}/payments`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.payment;\n }\n };\n\n /**\n * Sales Refund Requests methods\n */\n salesRefundRequests = {\n /**\n * Request refund or exchange\n * File a refund or exchange request for the order within the resolved refund policy. Requester identity is derived from the credential, never from the body.\n * @operationId createSalesOrderRefundRequest\n */\n create: async (orderId: string, request: { type: 'refund' | 'exchange'; reason?: string }) => {\n const response = await this.request<CreateSalesRefundRequestResponse>(`/sales/orders/${orderId}/refund-requests`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.request;\n }\n };\n\n /**\n * Sales Customers methods\n */\n salesCustomers = {\n /**\n * Create customer\n * Provenance-scoped channel CRM (secret keys only). Reuses the org's existing record for the email and grants the channel access; there is no list or search.\n * @operationId createSalesCustomer\n */\n create: async (request: { email: string; firstName?: string; lastName?: string; phone?: string; marketingConsent?: boolean }) => {\n const response = await this.request<SalesCustomerResponse>(`/sales/customers`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response.customer;\n },\n\n /**\n * Get customer\n * Get a customer the channel holds an access grant for (created through it, or who bought through it)\n * @operationId getSalesCustomer\n */\n get: async (customerId: string) => {\n const response = await this.request<SalesCustomerResponse>(`/sales/customers/${customerId}`, {\n method: 'GET'\n });\n\n return response.customer;\n },\n\n /**\n * Update customer\n * Update a customer the channel holds an access grant for. The update surface is deliberately small - email changes go through the org's staff.\n * @operationId updateSalesCustomer\n */\n update: async (customerId: string, request: { firstName?: string; lastName?: string; phone?: string }) => {\n const response = await this.request<SalesCustomerResponse>(`/sales/customers/${customerId}`, {\n method: 'PATCH',\n body: JSON.stringify(request)\n });\n\n return response.customer;\n }\n };\n\n /**\n * Sales Presale Codes methods\n */\n salesPresaleCodes = {\n /**\n * Redeem presale code\n * A verified customer redeems a presale code for its benefit; gated pricing unlocks immediately. Requires a customer token.\n * @operationId redeemSalesPresaleCode\n */\n redeem: async (request: { code: string }) => {\n const response = await this.request<RedeemSalesPresaleCodeResponse>(`/sales/presale-codes/redeem`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response;\n }\n };\n\n /**\n * Sales methods\n */\n sales = {\n /**\n * Resolve a channel by domain\n * Public tenant resolution for hosted surfaces: maps a hostname (the channel's configured subdomain or custom domain) to its channel summary and publishable key. No authentication; rate-limited.\n * @operationId resolveSalesChannel\n */\n resolveChannel: async (options?: { domain: string }) => {\n const params = new URLSearchParams();\n if (options?.domain !== undefined) params.append('domain', String(options.domain));\n const queryString = params.toString();\n const requestPath = queryString ? `/sales/channel?${queryString}` : `/sales/channel`;\n\n const response = await this.request<SalesResolveChannelResponse>(requestPath, {\n method: 'GET'\n });\n\n return response;\n },\n\n /**\n * Get event catalogue detail\n * Catalogue detail for an event listed on this channel: occurrences with their priced ticket-type offers. Benefit-gated types are included only when the request carries a customer token holding the benefit. Returns 404 if the event is not listed on this channel.\n * @operationId getSalesEvent\n */\n get: async (eventId: string) => {\n const response = await this.request<SalesEventDetailResponse>(`/sales/events/${eventId}`, {\n method: 'GET'\n });\n\n return response.event;\n },\n\n /**\n * Get channel theme\n * The channel's resolved (inheritance-merged) theme for SSR injection. Returns 404 if the channel has neither its own theme nor an organisation base theme.\n * @operationId getSalesTheme\n */\n getTheme: async () => {\n const response = await this.request<SalesThemeResponse>(`/sales/theme`, {\n method: 'GET'\n });\n\n return response.theme;\n }\n };\n\n /**\n * Session methods\n */\n session = {\n /**\n * Bootstrap a Live session\n * Resolves the channel and mints a session that holds the channel\u2019s publishable key server-side. Hosted callers (channel resolved from the Host header or an explicit `domain`) receive an httpOnly cookie; embed callers (providing a `channelKey`) receive the session id in the body.\n * @operationId createLiveSession\n */\n start: async (request: CreateSessionBody) => {\n const response = await this.request<any>(`/session`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response;\n },\n\n /**\n * Get the current session\n * Returns the current session\u2019s customer and cart state.\n * @operationId getLiveSession\n */\n current: async () => {\n const response = await this.request<any>(`/session`, {\n method: 'GET'\n });\n\n return response;\n },\n\n /**\n * Destroy the current session\n * Signs out and drops the current session.\n * @operationId deleteLiveSession\n */\n end: async () => {\n const response = await this.request<any>(`/session`, {\n method: 'DELETE'\n });\n\n return response;\n },\n\n /**\n * Attach an order access token to the session\n * Proves possession of an order by reading it upstream with the emailed order access token, then holds the token in the session so `GET /sales/orders/{orderId}` (and ticket downloads) work without the browser keeping it. Creates the session on a cold open, exactly like `POST /session`.\n * @operationId attachLiveOrderAccess\n */\n attachOrderAccess: async (request: AttachOrderAccessBody) => {\n const response = await this.request<any>(`/session/order-access`, {\n method: 'POST',\n body: JSON.stringify(request)\n });\n\n return response;\n }\n };\n\n /**\n * Queue methods\n */\n queue = {\n /**\n * Get waiting-room status\n * Returns the waiting-room status for the current session. The waiting room lives only in Live; when disabled the queue is transparent and every session is admitted.\n * @operationId getLiveQueueStatus\n */\n status: async () => {\n const response = await this.request<any>(`/queue/status`, {\n method: 'GET'\n });\n\n return response;\n },\n\n /**\n * Join the waiting room\n * Joins the current session to the waiting room. While the queue is disabled this is a no-op that reports immediate admission.\n * @operationId joinLiveQueue\n */\n join: async () => {\n const response = await this.request<any>(`/queue/join`, {\n method: 'POST'\n });\n\n return response;\n }\n };\n}\n", "/**\n * The `window.Ticketlayer` global registry.\n *\n * One stateful Live client per page, published on a well-known global so that\n * Elements (a separate bundle, possibly CDN-loaded) can find and bind to it\n * WITHOUT importing @ticketlayer/live. The contract is deliberately tiny and\n * stable - it's the public integration surface for snippet/Webflow embeds:\n *\n * - `getClient()` - the rich stateful facade (events/cart/auth/theme/bus).\n * - `getSDK()` - the Elements-shaped connector view of that same client.\n * - `ready()` - resolves when the client is published (immediately if it\n * already is); Elements await this instead of polling.\n *\n * Publishing also dispatches a `ticketlayer:ready` CustomEvent on window, so a\n * pure-DOM listener (no promise plumbing) can react too.\n */\n\nexport const TICKETLAYER_GLOBAL_KEY = 'Ticketlayer' as const;\nexport const TICKETLAYER_READY_EVENT = 'ticketlayer:ready' as const;\n\nexport interface TicketlayerGlobal<Client = unknown, Sdk = unknown> {\n /** The singleton stateful client (facade). */\n client: Client | null;\n /** Elements-shaped connector view of the same client. */\n sdk: Sdk | null;\n getClient(): Client | null;\n getSDK(): Sdk | null;\n /** Resolves with the client once published; immediate if already present. */\n ready(): Promise<Client>;\n version: string;\n}\n\ninterface InternalGlobal<Client, Sdk> extends TicketlayerGlobal<Client, Sdk> {\n _resolvers: Array<(c: Client) => void>;\n}\n\ndeclare global {\n interface Window {\n Ticketlayer?: TicketlayerGlobal;\n }\n}\n\nfunction ensureRegistry<Client, Sdk>(version: string): InternalGlobal<Client, Sdk> {\n const w = window as unknown as { [TICKETLAYER_GLOBAL_KEY]?: InternalGlobal<Client, Sdk> };\n if (w[TICKETLAYER_GLOBAL_KEY]) return w[TICKETLAYER_GLOBAL_KEY]!;\n\n const reg: InternalGlobal<Client, Sdk> = {\n client: null,\n sdk: null,\n version,\n _resolvers: [],\n getClient() {\n return this.client;\n },\n getSDK() {\n return this.sdk;\n },\n ready() {\n if (this.client) return Promise.resolve(this.client);\n return new Promise<Client>((resolve) => this._resolvers.push(resolve));\n },\n };\n w[TICKETLAYER_GLOBAL_KEY] = reg;\n return reg;\n}\n\n/** Publish the singleton client + connector. Browser-only; safe to call once. */\nexport function publishClient<Client, Sdk>(client: Client, sdk: Sdk, version: string): void {\n if (typeof window === 'undefined') return;\n const reg = ensureRegistry<Client, Sdk>(version);\n\n if (reg.client && reg.client !== client) {\n console.warn(\n '[live] A Ticketlayer client is already on window.Ticketlayer; replacing it. ' +\n 'Create a single client per page.'\n );\n }\n\n reg.client = client;\n reg.sdk = sdk;\n const resolvers = reg._resolvers;\n reg._resolvers = [];\n resolvers.forEach((r) => r(client));\n\n window.dispatchEvent(new CustomEvent(TICKETLAYER_READY_EVENT, { detail: client }));\n}\n\n/** Read the current client, if any (host convenience; Elements use ready()). */\nexport function getPublishedClient<Client>(): Client | null {\n if (typeof window === 'undefined') return null;\n return (window.Ticketlayer?.getClient() as Client | null) ?? null;\n}\n", "/**\n * Optionally pull in @ticketlayer/elements at runtime so a single Live include\n * gives you the components too - the \"one line of code\" snippet path.\n *\n * No-op when: not in a browser, the custom elements are already defined (a\n * bundler-based host like HBO imports them directly), or an injection for this\n * URL is already in flight. The default URL points at the Elements ESM entry on\n * the Ticketlayer CDN; pass `elementsUrl` to target a pinned build or a local\n * one in dev.\n *\n * ## Subresource integrity, and when it is required (TKT-160)\n *\n * The page's own `<script>` tag is integrity-checked by the browser, but the\n * Elements bundle this module then injects is a second, much larger download -\n * the one that actually renders the checkout. Injecting it with no `integrity`\n * left it unverified, which made the pinning the Webflow Integration Service\n * writes into every installed site (`data-elements-url` +\n * `data-elements-integrity`) worth nothing past the first script tag.\n *\n * The rule this module enforces, in full:\n *\n * 1. **A hash with no URL is refused.** `elementsIntegrity` without\n * `elementsUrl` could only be pinning the floating default, whose bytes are\n * rewritten by every release, so the hash is wrong the moment one lands.\n * 2. **A malformed hash is refused.** It has to look like\n * `sha256-`/`sha384-`/`sha512-` followed by base64, optionally several\n * space-separated, as the HTML spec defines the attribute. A typo that the\n * browser ignores is worse than no hash at all, because it reads as\n * protection.\n * 3. **An exact-version URL with no hash is refused.** A path carrying a full\n * `v<major>.<minor>.<patch>` segment is the CDN's pinned tier: those bytes\n * are written once and never rewritten, `/versions.json` publishes their\n * `sha384`, and pinning without verifying is the degradation this exists to\n * stop. This is exactly the shape the Webflow Integration Service writes.\n * 4. **Everything else loads unverified, deliberately.** The floating tiers\n * (`/v1/`, `/v0.3/`) and a local dev server change under the URL by design;\n * an integrity hash on one of them fails the moment a release lands\n * (`cdn/README.md`, \"Pinning, and subresource integrity\"). They cannot be\n * verified, so requiring it would only stop them working.\n *\n * `DEFAULT_ELEMENTS_URL` is a floating path and therefore falls into case 4.\n * The default is kept, because removing it would break the documented one-line\n * embed and every site that already omits `data-elements-url`, but it is no\n * longer silent: taking it logs once, naming the pinned alternative. A site\n * that wants the bundle verified pins it.\n *\n * `crossOrigin` is set alongside `integrity` and is not optional: a\n * cross-origin script without CORS is opaque to the page, and the browser\n * refuses to check an `integrity` it cannot read the bytes for.\n */\nconst DEFAULT_ELEMENTS_URL =\n 'https://cdn.ticketlayer.com/elements/v1/ticketlayer-elements/ticketlayer-elements.esm.js';\n\nconst SENTINEL_TAG = 'tl-event-list';\nconst inFlight = new Map<string, Promise<void>>();\n\n/**\n * A path segment naming a full major.minor.patch - the CDN's pinned tier\n * (`cdn/build-tree.mjs` is where the scheme is decided). `/v1/` and `/v0.3/`\n * are the floating tiers and deliberately do not match.\n */\nconst PINNED_PATH = /\\/v\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?\\//;\n\n/** The `integrity` attribute as HTML defines it: one or more hash expressions. */\nconst INTEGRITY = /^(?:sha(?:256|384|512)-[A-Za-z0-9+/]+={0,2})(?:\\s+sha(?:256|384|512)-[A-Za-z0-9+/]+={0,2})*$/;\n\nexport interface LoadElementsOptions {\n /** Enable runtime injection (default false - most hosts import Elements directly). */\n elements?: boolean;\n /**\n * Override the Elements ESM bundle URL: a pinned CDN build, or a local dist\n * in dev. An exact-version URL must come with `elementsIntegrity`.\n */\n elementsUrl?: string;\n /**\n * Subresource integrity for `elementsUrl`, as `/versions.json` publishes it\n * (`sha384-...`). Required for an exact-version URL, refused without one.\n */\n elementsIntegrity?: string;\n}\n\n/** Thrown when the options ask for something that cannot be verified. */\nexport class ElementsIntegrityError extends Error {\n constructor(message: string) {\n super(`[live] ${message}`);\n this.name = 'ElementsIntegrityError';\n }\n}\n\nlet warnedAboutDefault = false;\n\nexport function loadElements(opts: LoadElementsOptions = {}): Promise<void> {\n if (!opts.elements) return Promise.resolve();\n\n const integrity = opts.elementsIntegrity?.trim() || undefined;\n\n // The refusals come before the browser and already-registered checks, so a\n // misconfigured host hears about it in Node, in SSR and in a test - not only\n // on the one page where the elements had not already been defined.\n if (integrity && !opts.elementsUrl) {\n throw new ElementsIntegrityError(\n 'elementsIntegrity was given without elementsUrl. The default Elements URL is a floating ' +\n 'path that every release rewrites, so a hash pinned to it cannot keep matching. Pass the ' +\n 'pinned elementsUrl that the hash is for (see /versions.json on the CDN).'\n );\n }\n if (integrity && !INTEGRITY.test(integrity)) {\n throw new ElementsIntegrityError(\n `elementsIntegrity is not a subresource integrity value: ${JSON.stringify(opts.elementsIntegrity)}. ` +\n 'Expected one or more of sha256-, sha384- or sha512- followed by base64, as /versions.json publishes it.'\n );\n }\n if (opts.elementsUrl && !integrity && PINNED_PATH.test(opts.elementsUrl)) {\n throw new ElementsIntegrityError(\n `elementsUrl ${opts.elementsUrl} names an exact version, which is the CDN's pinned tier, but no ` +\n 'elementsIntegrity came with it. A pinned URL exists to be verified; loading it unchecked would ' +\n 'be weaker than the floating path. Pass the sha384 from /versions.json as elementsIntegrity ' +\n '(data-elements-integrity on the embed script), or use a floating /v1/ URL.'\n );\n }\n\n if (typeof window === 'undefined' || typeof document === 'undefined') return Promise.resolve();\n\n // Already registered (bundler import or a prior load) - nothing to do.\n const ce = (window as unknown as { customElements?: CustomElementRegistry }).customElements;\n if (ce?.get(SENTINEL_TAG)) return Promise.resolve();\n\n const url = opts.elementsUrl ?? DEFAULT_ELEMENTS_URL;\n\n if (!opts.elementsUrl && !warnedAboutDefault) {\n warnedAboutDefault = true;\n console.warn(\n `[live] Loading Elements unverified from the floating default ${DEFAULT_ELEMENTS_URL}. ` +\n 'Floating paths are rewritten by every release and cannot carry a subresource integrity hash. ' +\n 'To verify the bundle, pin it: set elementsUrl (data-elements-url) to the pinned path from ' +\n '/versions.json and elementsIntegrity (data-elements-integrity) to the sha384 beside it.'\n );\n }\n\n const existing = inFlight.get(url);\n if (existing) return existing;\n\n const p = new Promise<void>((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'module';\n script.src = url;\n script.async = true;\n if (integrity) {\n script.integrity = integrity;\n // Without CORS the response is opaque and the browser cannot check the\n // hash at all, so these two are set together or not at all.\n script.crossOrigin = 'anonymous';\n }\n script.dataset.ticketlayerElements = 'auto';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(`[live] Failed to load Elements from ${url}`));\n document.head.appendChild(script);\n });\n\n inFlight.set(url, p);\n return p;\n}\n", "/* Generated from tokens.json by packages/theme/scripts/generate.mjs. Do not edit. */\n/**\n * Typed access to the token set. Generated from packages/theme/tokens.json;\n * change a token there and regenerate.\n */\n\n/** Every token name, in declaration order. */\nexport const TOKEN_NAMES = [\n 'primary',\n 'primary-foreground',\n 'secondary',\n 'secondary-foreground',\n 'accent',\n 'accent-foreground',\n 'background',\n 'foreground',\n 'card',\n 'muted',\n 'muted-foreground',\n 'border',\n 'border-hover',\n 'input',\n 'ring',\n 'success',\n 'success-foreground',\n 'warning',\n 'warning-foreground',\n 'warning-bg',\n 'error',\n 'error-foreground',\n 'error-bg',\n 'info',\n 'info-foreground',\n 'info-bg',\n 'font-family',\n 'font-family-mono',\n 'font-size-base',\n 'font-scale',\n 'radius-none',\n 'radius-sm',\n 'radius-md',\n 'radius-lg',\n 'radius-full',\n 'spacing-1',\n 'spacing-2',\n 'spacing-3',\n 'spacing-4',\n 'spacing-5',\n 'spacing-6',\n 'spacing-8',\n 'duration-fast',\n 'duration-normal',\n 'duration-slow',\n 'easing-standard',\n 'easing-emphasised',\n] as const;\n\n/** A token name. Renaming a token in tokens.json changes this union, and every consumer that named the old one stops compiling. */\nexport type TokenName = (typeof TOKEN_NAMES)[number];\n\n/** Alias name -> the token it resolves to. */\nexport const TOKEN_ALIASES = {\n 'color-primary': 'primary',\n 'color-primary-foreground': 'primary-foreground',\n 'color-secondary': 'secondary',\n 'color-secondary-foreground': 'secondary-foreground',\n 'color-accent': 'accent',\n 'color-accent-foreground': 'accent-foreground',\n 'color-background': 'background',\n 'color-foreground': 'foreground',\n 'color-card': 'card',\n 'color-muted': 'muted',\n 'color-muted-foreground': 'muted-foreground',\n 'color-border': 'border',\n 'color-border-hover': 'border-hover',\n 'color-input': 'input',\n 'color-ring': 'ring',\n 'color-success': 'success',\n 'color-success-foreground': 'success-foreground',\n 'color-warning': 'warning',\n 'color-warning-foreground': 'warning-foreground',\n 'color-warning-bg': 'warning-bg',\n 'color-error': 'error',\n 'destructive': 'error',\n 'color-destructive': 'error',\n 'color-error-foreground': 'error-foreground',\n 'destructive-foreground': 'error-foreground',\n 'color-destructive-foreground': 'error-foreground',\n 'color-error-bg': 'error-bg',\n 'destructive-bg': 'error-bg',\n 'color-destructive-bg': 'error-bg',\n 'color-info': 'info',\n 'color-info-foreground': 'info-foreground',\n 'color-info-bg': 'info-bg',\n 'base-size': 'font-size-base',\n 'radius': 'radius-md',\n} as const;\n\nexport type TokenAlias = keyof typeof TOKEN_ALIASES;\n\n/** The default (light) value of every token, by token name. */\nexport const TOKEN_DEFAULTS: Record<TokenName, string> = {\n 'primary': '#6366f1',\n 'primary-foreground': '#ffffff',\n 'secondary': '#f3f4f6',\n 'secondary-foreground': '#111827',\n 'accent': '#ec4899',\n 'accent-foreground': '#ffffff',\n 'background': '#ffffff',\n 'foreground': '#111827',\n 'card': '#ffffff',\n 'muted': '#f9fafb',\n 'muted-foreground': '#6b7280',\n 'border': '#e5e7eb',\n 'border-hover': '#9ca3af',\n 'input': '#e5e7eb',\n 'ring': '#6366f1',\n 'success': '#10b981',\n 'success-foreground': '#ffffff',\n 'warning': '#f59e0b',\n 'warning-foreground': '#ffffff',\n 'warning-bg': '#fef3c7',\n 'error': '#ef4444',\n 'error-foreground': '#ffffff',\n 'error-bg': '#fee2e2',\n 'info': '#3b82f6',\n 'info-foreground': '#ffffff',\n 'info-bg': '#dbeafe',\n 'font-family': 'system-ui, -apple-system, BlinkMacSystemFont, \\'Segoe UI\\', Roboto, sans-serif',\n 'font-family-mono': 'ui-monospace, SFMono-Regular, \\'SF Mono\\', Menlo, monospace',\n 'font-size-base': '16px',\n 'font-scale': '1.25',\n 'radius-none': '0px',\n 'radius-sm': '0.25rem',\n 'radius-md': '0.5rem',\n 'radius-lg': '0.75rem',\n 'radius-full': '9999px',\n 'spacing-1': '0.25rem',\n 'spacing-2': '0.5rem',\n 'spacing-3': '0.75rem',\n 'spacing-4': '1rem',\n 'spacing-5': '1.25rem',\n 'spacing-6': '1.5rem',\n 'spacing-8': '2rem',\n 'duration-fast': '120ms',\n 'duration-normal': '200ms',\n 'duration-slow': '320ms',\n 'easing-standard': 'cubic-bezier(0.2, 0, 0, 1)',\n 'easing-emphasised': 'cubic-bezier(0.3, 0, 0, 1)',\n};\n\n/** The dark value of every token that has one. */\nexport const TOKEN_DARK: Partial<Record<TokenName, string>> = {\n 'primary': '#818cf8',\n 'primary-foreground': '#111827',\n 'secondary': '#1f2937',\n 'secondary-foreground': '#f9fafb',\n 'accent': '#f472b6',\n 'accent-foreground': '#111827',\n 'background': '#0b0f19',\n 'foreground': '#f9fafb',\n 'card': '#111827',\n 'muted': '#111827',\n 'muted-foreground': '#9ca3af',\n 'border': '#374151',\n 'border-hover': '#4b5563',\n 'input': '#374151',\n 'ring': '#818cf8',\n 'success': '#34d399',\n 'success-foreground': '#062a1d',\n 'warning': '#fbbf24',\n 'warning-foreground': '#2a1a02',\n 'warning-bg': '#422006',\n 'error': '#f87171',\n 'error-foreground': '#2a0a0a',\n 'error-bg': '#450a0a',\n 'info': '#60a5fa',\n 'info-foreground': '#0a1a2a',\n 'info-bg': '#172554',\n};\n\n/** The theme-document key that feeds each token, for the tokens the theme API can set. */\nexport const TOKEN_THEME_KEYS: Partial<Record<TokenName, string>> = {\n 'primary': 'colors.primary',\n 'primary-foreground': 'colors.primaryForeground',\n 'secondary': 'colors.secondary',\n 'secondary-foreground': 'colors.secondaryForeground',\n 'accent': 'colors.accent',\n 'accent-foreground': 'colors.accentForeground',\n 'background': 'colors.background',\n 'foreground': 'colors.foreground',\n 'muted': 'colors.muted',\n 'muted-foreground': 'colors.mutedForeground',\n 'border': 'colors.border',\n 'input': 'colors.input',\n 'ring': 'colors.ring',\n 'success': 'colors.success',\n 'success-foreground': 'colors.successForeground',\n 'warning': 'colors.warning',\n 'warning-foreground': 'colors.warningForeground',\n 'error': 'colors.destructive',\n 'error-foreground': 'colors.destructiveForeground',\n 'font-family': 'typography.fontFamily',\n 'font-family-mono': 'typography.fontFamilyMono',\n 'font-size-base': 'typography.baseSize',\n 'font-scale': 'typography.scaleRatio',\n 'radius-none': 'shape.radiusNone',\n 'radius-sm': 'shape.radiusSm',\n 'radius-md': 'shape.radiusMd',\n 'radius-lg': 'shape.radiusLg',\n 'radius-full': 'shape.radiusFull',\n};\n\n/** The group each token belongs to. */\nexport const TOKEN_GROUPS: Record<TokenName, string> = {\n 'primary': 'color',\n 'primary-foreground': 'color',\n 'secondary': 'color',\n 'secondary-foreground': 'color',\n 'accent': 'color',\n 'accent-foreground': 'color',\n 'background': 'color',\n 'foreground': 'color',\n 'card': 'color',\n 'muted': 'color',\n 'muted-foreground': 'color',\n 'border': 'color',\n 'border-hover': 'color',\n 'input': 'color',\n 'ring': 'color',\n 'success': 'color',\n 'success-foreground': 'color',\n 'warning': 'color',\n 'warning-foreground': 'color',\n 'warning-bg': 'color',\n 'error': 'color',\n 'error-foreground': 'color',\n 'error-bg': 'color',\n 'info': 'color',\n 'info-foreground': 'color',\n 'info-bg': 'color',\n 'font-family': 'typography',\n 'font-family-mono': 'typography',\n 'font-size-base': 'typography',\n 'font-scale': 'typography',\n 'radius-none': 'radius',\n 'radius-sm': 'radius',\n 'radius-md': 'radius',\n 'radius-lg': 'radius',\n 'radius-full': 'radius',\n 'spacing-1': 'spacing',\n 'spacing-2': 'spacing',\n 'spacing-3': 'spacing',\n 'spacing-4': 'spacing',\n 'spacing-5': 'spacing',\n 'spacing-6': 'spacing',\n 'spacing-8': 'spacing',\n 'duration-fast': 'motion',\n 'duration-normal': 'motion',\n 'duration-slow': 'motion',\n 'easing-standard': 'motion',\n 'easing-emphasised': 'motion',\n};\n\n/**\n * The typed theme object a native harness renders from: the same tokens, grouped,\n * with camelCase keys and no CSS anywhere near them.\n */\nexport const lightTheme = {\n color: {\n 'primary': '#6366f1',\n 'primaryForeground': '#ffffff',\n 'secondary': '#f3f4f6',\n 'secondaryForeground': '#111827',\n 'accent': '#ec4899',\n 'accentForeground': '#ffffff',\n 'background': '#ffffff',\n 'foreground': '#111827',\n 'card': '#ffffff',\n 'muted': '#f9fafb',\n 'mutedForeground': '#6b7280',\n 'border': '#e5e7eb',\n 'borderHover': '#9ca3af',\n 'input': '#e5e7eb',\n 'ring': '#6366f1',\n 'success': '#10b981',\n 'successForeground': '#ffffff',\n 'warning': '#f59e0b',\n 'warningForeground': '#ffffff',\n 'warningBg': '#fef3c7',\n 'error': '#ef4444',\n 'errorForeground': '#ffffff',\n 'errorBg': '#fee2e2',\n 'info': '#3b82f6',\n 'infoForeground': '#ffffff',\n 'infoBg': '#dbeafe',\n },\n typography: {\n 'fontFamily': 'system-ui, -apple-system, BlinkMacSystemFont, \\'Segoe UI\\', Roboto, sans-serif',\n 'fontFamilyMono': 'ui-monospace, SFMono-Regular, \\'SF Mono\\', Menlo, monospace',\n 'fontSizeBase': '16px',\n 'fontScale': '1.25',\n },\n radius: {\n 'none': '0px',\n 'sm': '0.25rem',\n 'md': '0.5rem',\n 'lg': '0.75rem',\n 'full': '9999px',\n },\n spacing: {\n '1': '0.25rem',\n '2': '0.5rem',\n '3': '0.75rem',\n '4': '1rem',\n '5': '1.25rem',\n '6': '1.5rem',\n '8': '2rem',\n },\n motion: {\n 'durationFast': '120ms',\n 'durationNormal': '200ms',\n 'durationSlow': '320ms',\n 'easingStandard': 'cubic-bezier(0.2, 0, 0, 1)',\n 'easingEmphasised': 'cubic-bezier(0.3, 0, 0, 1)',\n },\n} as const;\n\nexport const darkTheme = {\n color: {\n 'primary': '#818cf8',\n 'primaryForeground': '#111827',\n 'secondary': '#1f2937',\n 'secondaryForeground': '#f9fafb',\n 'accent': '#f472b6',\n 'accentForeground': '#111827',\n 'background': '#0b0f19',\n 'foreground': '#f9fafb',\n 'card': '#111827',\n 'muted': '#111827',\n 'mutedForeground': '#9ca3af',\n 'border': '#374151',\n 'borderHover': '#4b5563',\n 'input': '#374151',\n 'ring': '#818cf8',\n 'success': '#34d399',\n 'successForeground': '#062a1d',\n 'warning': '#fbbf24',\n 'warningForeground': '#2a1a02',\n 'warningBg': '#422006',\n 'error': '#f87171',\n 'errorForeground': '#2a0a0a',\n 'errorBg': '#450a0a',\n 'info': '#60a5fa',\n 'infoForeground': '#0a1a2a',\n 'infoBg': '#172554',\n },\n typography: {\n 'fontFamily': 'system-ui, -apple-system, BlinkMacSystemFont, \\'Segoe UI\\', Roboto, sans-serif',\n 'fontFamilyMono': 'ui-monospace, SFMono-Regular, \\'SF Mono\\', Menlo, monospace',\n 'fontSizeBase': '16px',\n 'fontScale': '1.25',\n },\n radius: {\n 'none': '0px',\n 'sm': '0.25rem',\n 'md': '0.5rem',\n 'lg': '0.75rem',\n 'full': '9999px',\n },\n spacing: {\n '1': '0.25rem',\n '2': '0.5rem',\n '3': '0.75rem',\n '4': '1rem',\n '5': '1.25rem',\n '6': '1.5rem',\n '8': '2rem',\n },\n motion: {\n 'durationFast': '120ms',\n 'durationNormal': '200ms',\n 'durationSlow': '320ms',\n 'easingStandard': 'cubic-bezier(0.2, 0, 0, 1)',\n 'easingEmphasised': 'cubic-bezier(0.3, 0, 0, 1)',\n },\n} as const;\n\nexport type NativeTheme = typeof lightTheme;\n", "/**\n * `@ticketlayer/theme`: the token set every Ticketlayer Live harness renders from.\n *\n * `tokens.json` is the source. Everything exported here, the `:root` stylesheet\n * the Elements load, the JSON schema the theme editor and the sales-channel\n * theme API validate against and `TOKENS.md` are generated from it by\n * `scripts/generate.mjs`. There is exactly one place a token's default value is\n * written down, and it is not this file.\n *\n * This package holds no runtime of its own: no DOM, no React, no network. The\n * harness decides how to apply what it reads here. On the web that is\n * `@ticketlayer/live`'s `applyTheme`, which turns a channel theme into the\n * declarations `themeToCssVars` returns and writes them onto `:root`.\n */\nexport {\n TOKEN_NAMES,\n TOKEN_ALIASES,\n TOKEN_DEFAULTS,\n TOKEN_DARK,\n TOKEN_THEME_KEYS,\n TOKEN_GROUPS,\n lightTheme,\n darkTheme,\n} from './generated/tokens.js';\nexport type { TokenName, TokenAlias, NativeTheme } from './generated/tokens.js';\n\nimport {\n TOKEN_ALIASES,\n TOKEN_DEFAULTS,\n TOKEN_THEME_KEYS,\n type TokenName,\n} from './generated/tokens.js';\n\n/** The custom property a token name is written as: `primary` -> `--tl-primary`. */\nexport function cssVar(name: string): string {\n return `--tl-${name}`;\n}\n\n/** The default value of a token, or of an alias, by name. */\nexport function tokenDefault(name: string): string | undefined {\n const resolved = (TOKEN_ALIASES as Record<string, TokenName>)[name] ?? name;\n return TOKEN_DEFAULTS[resolved as TokenName];\n}\n\n/** Is this a token name, or an alias of one? */\nexport function isTokenName(name: string): boolean {\n return name in TOKEN_DEFAULTS || name in TOKEN_ALIASES;\n}\n\n/**\n * A theme document as `GET /sales/theme` returns it. Every section is loose on\n * purpose: the schema is enforced by the API, and a client that refused an\n * unknown key would break the next time a token was added.\n */\nexport interface ThemeDocument {\n colors?: Record<string, unknown>;\n typography?: Record<string, unknown>;\n shape?: Record<string, unknown>;\n brand?: Record<string, unknown>;\n design?: Record<string, unknown> | null;\n}\n\n/**\n * Turn a channel theme into the custom properties that override the defaults.\n *\n * Only declared tokens are read, and every alias a token answers to is written\n * out beside it, so a host that asks for `--tl-color-primary` or the theme\n * editor's `--tl-base-size` gets the channel's value and not the default.\n * Anything the theme carries that is not a token is ignored: the token set is\n * the contract, and a new one is added in `tokens.json`.\n */\nexport function themeToCssVars(theme: ThemeDocument | null | undefined): Record<string, string> {\n const vars: Record<string, string> = {};\n if (!theme) return vars;\n\n for (const [token, themeKey] of Object.entries(TOKEN_THEME_KEYS)) {\n const [section, key] = themeKey.split('.');\n const value = (theme as Record<string, Record<string, unknown> | null | undefined>)[section]?.[key];\n if (value === undefined || value === null || value === '') continue;\n vars[cssVar(token)] = String(value);\n }\n\n for (const [alias, token] of Object.entries(TOKEN_ALIASES)) {\n const value = vars[cssVar(token)];\n if (value !== undefined) vars[cssVar(alias)] = value;\n }\n\n return vars;\n}\n\n/** The same declarations as the body of a CSS rule. */\nexport function themeToCssText(theme: ThemeDocument | null | undefined): string {\n return Object.entries(themeToCssVars(theme))\n .map(([name, value]) => `${name}: ${value};`)\n .join('\\n');\n}\n", "/**\n * Checkout modal manager (third-party embeds).\n *\n * On a third-party site, Elements build the cart in-page and emit\n * `ui:checkout-requested`. This opens the hosted checkout in an iframe overlay\n * pointing at HBO's `/embed/checkout`, handing off the current session token so\n * the iframe sees the same cart (and so card data stays on HBO's origin - PCI\n * isolation). It bridges the `tl:*` postMessage protocol back to the caller's\n * onComplete/onError/onClose callbacks (which rode in on the intent payload).\n *\n * The iframe URL carries `parent_origin=<this page's origin>` so HBO can pin\n * its postMessage target to us (it never posts to '*'), and incoming messages\n * are only accepted from the checkout's own origin. The message set is\n * documented in HBO's docs/embed-checkout-contract.md.\n *\n * HBO itself does NOT use this - it handles `ui:checkout-requested` by\n * navigating in-page to /checkout.\n */\nimport { TOKEN_DEFAULTS } from '@ticketlayer/theme';\nimport type { TicketlayerLive } from '../createLiveClient.js';\n\nexport interface CheckoutModalOptions {\n /** Base URL of the HBO instance serving /embed/checkout. Defaults to origin. */\n embedBaseUrl?: string;\n}\n\n/** Inbound `tl:*` envelope (see HBO docs/embed-checkout-contract.md). */\ninterface EmbedMessage {\n type?: string;\n version?: number;\n orderId?: string;\n orderReference?: string;\n accessToken?: string;\n /** Pre-v1 payload of tl:complete. */\n order?: unknown;\n code?: string;\n message?: string;\n height?: number;\n}\n\ninterface CheckoutIntent {\n onComplete?: (order: unknown) => void;\n onError?: (error: Error) => void;\n onClose?: () => void;\n}\n\nconst OVERLAY_ID = 'tl-checkout-overlay';\n\n\n/** Wire the modal to the bus; returns an uninstall function. */\nexport function installCheckoutModal(\n tl: TicketlayerLive,\n opts: CheckoutModalOptions = {}\n): () => void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return () => {};\n\n let onMessage: ((e: MessageEvent) => void) | null = null;\n\n const close = () => {\n document.getElementById(OVERLAY_ID)?.remove();\n if (onMessage) {\n window.removeEventListener('message', onMessage);\n onMessage = null;\n }\n };\n\n const open = async (intent: CheckoutIntent) => {\n const token = await tl.getSessionToken().catch(() => null);\n const base = (opts.embedBaseUrl || window.location.origin).replace(/\\/$/, '');\n const query = new URLSearchParams();\n if (token) query.set('session', token);\n // Lets HBO pin its postMessage target origin to this page.\n query.set('parent_origin', window.location.origin);\n const url = `${base}/embed/checkout?${query.toString()}`;\n const frameOrigin = new URL(url).origin;\n\n close();\n\n const overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n // Blurred, dimmed backdrop so the underlying site recedes behind the modal.\n overlay.style.cssText =\n 'position:fixed;inset:0;z-index:2147483647;background:rgba(15,23,42,0.55);' +\n 'backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);' +\n 'display:flex;flex-direction:column;align-items:center;justify-content:center;' +\n 'gap:12px;padding:16px;';\n\n // Column wrapper: the modal panel + a floating chrome footer beneath it.\n const wrapper = document.createElement('div');\n wrapper.style.cssText =\n 'width:100%;max-width:960px;display:flex;flex-direction:column;gap:10px;';\n\n const frame = document.createElement('iframe');\n frame.src = url;\n frame.allow = 'payment';\n // Wide enough for the two-column checkout (form left, order summary right);\n // the embedded page stacks to one column on narrow viewports. Subtle theme\n // border (matches the buy-tickets modal) + a soft lift off the backdrop.\n //\n // This one keeps a fallback, unlike the Elements' stylesheets: the overlay\n // is drawn on a host page that may have no Elements and therefore no token\n // stylesheet at all. The fallback is still not a second source - it is read\n // from the same token table.\n frame.style.cssText =\n `width:100%;height:88vh;max-height:760px;border:1px solid var(--tl-border, ${TOKEN_DEFAULTS.border});` +\n 'border-radius:16px;background:#fff;box-shadow:0 24px 64px rgba(0,0,0,0.45);';\n\n // No chrome of our own around the iframe.\n //\n // The overlay is a transport: an iframe onto the hosted checkout plus the\n // postMessage bridge. It used to draw a \"Powered by Ticketlayer\" footer\n // beneath the frame, which put attribution at the wrong layer - duplicated\n // by the page inside, and absent for anyone who opens /embed/checkout\n // directly rather than through this overlay. The checkout page renders it\n // now, where the buyer actually is.\n wrapper.appendChild(frame);\n overlay.appendChild(wrapper);\n\n overlay.addEventListener('click', (e) => {\n if (e.target === overlay || e.target === wrapper) {\n close();\n intent.onClose?.();\n }\n });\n document.body.appendChild(overlay);\n\n onMessage = (e: MessageEvent) => {\n // Only the checkout page's own origin may drive the modal.\n if (e.origin !== frameOrigin) return;\n const msg = e.data as EmbedMessage | null;\n if (!msg || typeof msg !== 'object') return;\n switch (msg.type) {\n case 'tl:complete': {\n // v1 carries orderId/orderReference/accessToken at the top level and\n // keeps the pre-v1 `order` object; merge so both shapes are served.\n const legacy = (msg.order && typeof msg.order === 'object' ? msg.order : {}) as object;\n const order: unknown = msg.orderId\n ? {\n ...legacy,\n id: msg.orderId,\n orderNumber: msg.orderReference,\n ...(msg.accessToken ? { accessToken: msg.accessToken } : {}),\n }\n : msg.order;\n intent.onComplete?.(order);\n tl.emit('checkout:completed', order);\n close();\n break;\n }\n case 'tl:close':\n case 'tl:cancel':\n intent.onClose?.();\n close();\n break;\n case 'tl:error': {\n const err = new Error(msg.message || msg.code || 'Checkout failed');\n if (msg.code) (err as Error & { code?: string }).code = msg.code;\n intent.onError?.(err);\n break;\n }\n // tl:ready and tl:height are informational; the overlay has a fixed size.\n }\n };\n window.addEventListener('message', onMessage);\n };\n\n const offCheckout = tl.on('ui:checkout-requested', (p) => void open((p as CheckoutIntent) ?? {}));\n const offClose = tl.on('ui:modal-close-requested', () => close());\n\n return () => {\n offCheckout();\n offClose();\n close();\n };\n}\n", "/**\n * Buy-tickets modal manager (in-page, native Elements).\n *\n * The buy funnel (occurrence \u2192 ticket selection \u2192 add to cart) is pure\n * browse/cart with no PCI surface, so - unlike checkout - it does NOT need a\n * cross-origin iframe. This manager simply mounts the `<tl-buy-modal>` Element\n * on demand when something emits `ui:event-modal-requested` (a\n * `tl-buy-tickets-button`, a calendar date click, etc.) and removes it on close.\n * Because the modal is a normal Element bound to the same `window.Ticketlayer`,\n * it works identically on HBO and on any third-party embed.\n *\n * When the user proceeds to checkout, the manager hands the funnel over by\n * re-emitting `ui:checkout-requested` (forwarding the original caller's\n * callbacks): on a third-party embed the checkout modal opens the hosted\n * checkout in an iframe; on HBO the host navigates to /checkout in-page.\n */\nimport type { TicketlayerLive } from '../createLiveClient.js';\n\nexport interface BuyModalOptions {\n /** Override the custom-element tag (default `tl-buy-modal`). */\n tag?: string;\n}\n\ninterface BuyIntent {\n eventId: string;\n occurrenceId?: string;\n onComplete?: (order: unknown) => void;\n onError?: (error: Error) => void;\n onClose?: () => void;\n}\n\n/** Wire the buy modal to the bus; returns an uninstall function. */\nexport function installBuyModal(tl: TicketlayerLive, opts: BuyModalOptions = {}): () => void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return () => {};\n\n const TAG = opts.tag || 'tl-buy-modal';\n let el: HTMLElement | null = null;\n let current: BuyIntent | null = null;\n\n const remove = () => {\n if (el) {\n el.remove();\n el = null;\n }\n current = null;\n };\n\n const open = (intent: BuyIntent) => {\n if (!intent?.eventId) return;\n remove();\n current = intent;\n\n const node = document.createElement(TAG);\n // Set as attributes (strings) so they apply before the element upgrades.\n node.setAttribute('event-id', intent.eventId);\n if (intent.occurrenceId) node.setAttribute('occurrence-id', intent.occurrenceId);\n\n node.addEventListener('tlClose', () => {\n const i = current;\n remove();\n i?.onClose?.();\n });\n\n node.addEventListener('tlError', (e: Event) => {\n const message =\n (e as CustomEvent<{ message?: string }>).detail?.message || 'Could not load this event';\n current?.onError?.(new Error(message));\n });\n\n node.addEventListener('tlCheckout', () => {\n const i = current;\n remove();\n // Hand off to the checkout intent, forwarding the caller's callbacks so a\n // third-party site's onComplete still fires when the order completes.\n tl.emit('ui:checkout-requested', {\n onComplete: i?.onComplete,\n onError: i?.onError,\n onClose: i?.onClose,\n });\n });\n\n document.body.appendChild(node);\n el = node;\n };\n\n const offOpen = tl.on('ui:event-modal-requested', (p) => open((p as BuyIntent) ?? ({} as BuyIntent)));\n const offClose = tl.on('ui:modal-close-requested', () => remove());\n\n return () => {\n offOpen();\n offClose();\n remove();\n };\n}\n", "/**\n * Cart money, read from the response rather than assumed.\n *\n * The Elements connector used to publish `fees: 0` and `total = subtotal` on\n * every cart, which is a claim the client had no business making: a channel\n * with a fee profile charges a booking fee at checkout, so a cart that says\n * \"fees 0, total = subtotal\" tells the buyer a total they will not be charged.\n * This module reads whatever the sales surface reports and says plainly when\n * it reports nothing.\n *\n * ## What the surface reports today\n *\n * `SalesCart` (backstage-api `src/domains/sales/http/views/index.ts`, mirrored\n * byte for byte by live-api) is `{ id, status, currency, expiresAt, orderId,\n * items[], itemsSubtotal }`. There is no fee field, no discount field and no\n * total: fees are computed when the cart is checked out, from the channel's\n * fee profile, and land on the ORDER (`totalFees` plus a `type: 'fee'` line\n * item named after the profile's `serviceFeeLabel`). So on today's responses\n * this returns `hasFees: false` and no fee line is rendered - which is correct,\n * and unlike `fees: 0` it does not assert that the buyer pays no fee. The\n * moment a cart response carries the fields, the cart shows the line with no\n * further change here.\n *\n * ## Money\n *\n * Integer minor units everywhere on this platform (2500 = 25.00), so the\n * arithmetic here is integer addition only. A value that is not an integer is\n * not minor units, so it is treated as ABSENT rather than rounded or floated:\n * money never goes through floating point in this module.\n */\n\n/** Shown when the surface names no fee of its own. */\nexport const FEE_LABEL_FALLBACK = 'Booking fee';\n\nexport interface CartTotals {\n /** ISO currency code as the cart reports it, or null when it has none yet. */\n currency: string | null;\n /** Ticket lines, in minor units. */\n subtotal: number;\n /** Fees the surface reports, in minor units. 0 when it reports none. */\n fees: number;\n /** Discount the surface reports, as a positive magnitude in minor units. */\n discount: number;\n /** What the buyer pays: the server's figure whenever it gives one. */\n total: number;\n /**\n * Whether to render a fee line. A fee of zero is not the same as no fee:\n * see {@link expressesFee}.\n */\n hasFees: boolean;\n /** The fee's name as the surface gives it, or null when it names none. */\n feeLabel: string | null;\n /** True when the total came from the response rather than being derived. */\n totalFromServer: boolean;\n}\n\ntype Bag = Record<string, unknown>;\n\nconst bag = (v: unknown): Bag => (v && typeof v === 'object' ? (v as Bag) : {});\n\n/**\n * Minor units, or null when the value is not minor units. Integers and\n * all-digit strings only: a decimal like 12.5 or \"12.50\" is a major-unit\n * amount or a rounding error waiting to happen, and either way it is not\n * something this module will do arithmetic on.\n */\nexport function minorUnits(value: unknown): number | null {\n if (typeof value === 'number') return Number.isInteger(value) ? value : null;\n if (typeof value === 'string' && /^-?\\d+$/.test(value)) return Number(value);\n return null;\n}\n\nconst lineType = (line: Bag): string => (typeof line.type === 'string' ? line.type : 'ticket');\n\n/** Ticket lines: everything the surface has not typed as a fee, tax or discount. */\nconst isTicketLine = (line: Bag): boolean => !['fee', 'tax', 'discount'].includes(lineType(line));\n\n/**\n * The rule, in one place.\n *\n * Render a fee line when the response EXPRESSES a fee: a fee figure above\n * zero, or a fee the surface has named (a `type: 'fee'` line, or a fee label)\n * even when it computes to zero. A response with no fee figure at all, or a\n * bare zero nothing names, expresses no fee and renders no line - a channel\n * with no fee profile looks exactly as it does today, and we never invent a\n * \"Booking fee 0.00\" row the surface did not put there.\n */\nfunction expressesFee(fees: number | null, named: boolean): boolean {\n if (fees === null) return named;\n return fees > 0 || named;\n}\n\n/**\n * Read `subtotal`, `fees`, `discount` and `total` off a cart-shaped response.\n *\n * Field names are backstage-api's, because live-api never reshapes a body:\n * `itemsSubtotal` is what the cart view calls its ticket subtotal today, and\n * `totalFees` / `totalDiscounts` / `total` are what the order view calls the\n * rest - the names a cart view would reuse when it starts carrying them.\n * `fees`, `discount` and `subtotal` are accepted as aliases so a host that\n * already massaged the shape keeps working.\n */\nexport function deriveCartTotals(cart: unknown): CartTotals {\n const c = bag(cart);\n const lines = Array.isArray(c.items) ? c.items.map(bag) : [];\n\n const subtotal =\n minorUnits(c.itemsSubtotal) ??\n minorUnits(c.subtotal) ??\n lines.filter(isTicketLine).reduce((sum, line) => sum + (minorUnits(line.subtotal) ?? 0), 0);\n\n const feeLines = lines.filter((line) => lineType(line) === 'fee');\n const feeLineTotal = feeLines.length\n ? feeLines.reduce((sum, line) => sum + (minorUnits(line.subtotal) ?? 0), 0)\n : null;\n const fees = minorUnits(c.totalFees) ?? minorUnits(c.fees) ?? feeLineTotal;\n\n const labelled = typeof c.feeLabel === 'string' && c.feeLabel ? c.feeLabel : null;\n const namedLine = feeLines.map((line) => line.name).find((n) => typeof n === 'string' && n) as\n | string\n | undefined;\n const feeLabel = labelled ?? namedLine ?? null;\n\n const discountLines = lines.filter((line) => lineType(line) === 'discount');\n const discountLineTotal = discountLines.length\n ? discountLines.reduce((sum, line) => sum + Math.abs(minorUnits(line.subtotal) ?? 0), 0)\n : null;\n const discount = minorUnits(c.totalDiscounts) ?? minorUnits(c.discount) ?? discountLineTotal;\n\n const tax = minorUnits(c.totalTax) ?? 0;\n\n // The server's total is what the buyer is charged. Only derive one when the\n // response carries none, and say which happened so a caller can tell.\n const serverTotal = minorUnits(c.total);\n const total = serverTotal ?? subtotal + (fees ?? 0) + tax - (discount ?? 0);\n\n return {\n currency: typeof c.currency === 'string' ? c.currency : null,\n subtotal,\n fees: fees ?? 0,\n discount: discount ?? 0,\n total,\n hasFees: expressesFee(fees, feeLabel !== null || feeLines.length > 0),\n feeLabel,\n totalFromServer: serverTotal !== null,\n };\n}\n", "/**\n * Elements connector - adapts the stateful {@link TicketlayerLive} facade to the\n * structural interface `@ticketlayer/elements` components consume.\n *\n * Elements never import @ticketlayer/live directly: they bind to a generic\n * shape published on a window global (`setSDK(...)`), so the SDK and the\n * components can ship as separate bundles (e.g. the Elements CDN build). This\n * adapter is the bridge a host (HBO, a promoter site) installs:\n *\n * import { createLiveClient, createElementsConnector } from '@ticketlayer/live';\n * import { setSDK } from '@ticketlayer/elements';\n * const tl = await createLiveClient({ ... });\n * setSDK(createElementsConnector(tl));\n *\n * Two responsibilities the components expect that the facade doesn't expose 1:1:\n * - cart line items need a `categoryId` the components never pass; we resolve\n * it from the ticketTypeId captured when `getTicketTypes()` was called (the\n * ticket selector always loads types before adding - so the cache is warm).\n * - modal verbs (`event(id).openModal()`, `checkout.openModal()`, `closeModal()`)\n * are UI INTENTS: the SDK renders no UI, it relays them onto the shared bus\n * (ui:event-modal-requested / ui:checkout-requested / ui:modal-close-requested)\n * and the host opens the modal. Caller callbacks ride along in the payload.\n */\nimport type { TicketlayerLive, PresaleRedemption } from './createLiveClient.js';\nimport { deriveCartTotals } from './core/cartTotals.js';\n\ninterface CartLike {\n items?: Array<{ quantity?: number }>;\n [k: string]: unknown;\n}\n\nexport interface ModalOptions {\n occurrenceId?: string;\n onComplete?: (order: unknown) => void;\n onError?: (error: Error) => void;\n onClose?: () => void;\n}\n\nexport interface ElementsConnector {\n getEventsManager(): {\n list(options?: { limit?: number; category?: string }): Promise<{ items: unknown[] }>;\n get(eventId: string): Promise<unknown>;\n getTicketTypes(eventId: string, occurrenceId: string): Promise<unknown[]>;\n };\n getCartManager(): {\n get(): Promise<unknown>;\n on(event: string, cb: (data: unknown) => void): () => void;\n off(event: string, cb: (data: unknown) => void): void;\n addItem(ticketTypeId: string, quantity: number, occurrenceId: string): Promise<unknown>;\n addItems(items: Array<{ ticketTypeId: string; quantity: number; occurrenceId: string }>): Promise<unknown>;\n removeItem(itemId: string): Promise<unknown>;\n addSeat(seatId: string, ticketTypeId: string, occurrenceId: string): Promise<unknown>;\n removeSeat(seatId: string, occurrenceId: string): Promise<unknown>;\n };\n getOrdersManager(): {\n mine(): Promise<unknown>;\n get(orderId: string): Promise<unknown>;\n ticketPdf(orderId: string, passId: string): Promise<Blob>;\n };\n /** Magic-link sign-in (tl-login, tl-my-orders). Never sees a password. */\n getAuthManager(): {\n readonly customer: unknown | null;\n readonly authenticated: boolean;\n requestMagicLink(contact: { email?: string; phone?: string }): Promise<unknown>;\n exchange(code: string): Promise<unknown>;\n logout(): Promise<void>;\n };\n /** Presale / promo codes (tl-promo-code). */\n getPresaleManager(): {\n redeem(code: string): Promise<PresaleRedemption>;\n };\n on(event: string, cb: (data: unknown) => void): () => void;\n off(event: string, cb: (data: unknown) => void): void;\n event(eventId: string): { openModal(options?: ModalOptions): void };\n checkout: { openModal(options?: ModalOptions): void; closeModal(): void };\n closeModal(): void;\n}\n\n/**\n * Adapt the sales-surface cart view to the shape Elements consume. The sales\n * view exposes `itemsSubtotal` + per-item `subtotal`; the components (tl-cart,\n * badges) were written against `subtotal`/`total`/`fees` + per-item\n * `totalPrice`. Add those aliases (and itemCount) without dropping the\n * originals - otherwise tl-cart formats undefined \u2192 \u00A3NaN.\n *\n * The money comes from {@link deriveCartTotals}, which reads the response\n * instead of asserting `fees: 0`: `fees`, `discount` and `feeLabel` are\n * whatever the surface reports, `hasFees` is the render-a-fee-line rule, and\n * `total` is the server's figure whenever the response carries one. Money\n * stays minor units.\n */\nconst withCount = (cart: unknown): unknown => {\n if (!cart || typeof cart !== 'object') return cart;\n const c = cart as CartLike & { itemsSubtotal?: number };\n const items: Array<Record<string, unknown>> = (c.items ?? []).map((i) => {\n const it = i as Record<string, unknown>;\n const qty = (it.quantity as number) ?? 0;\n const line = (it.subtotal as number) ?? (it.unitPrice as number) * qty;\n return { ...it, totalPrice: it.totalPrice ?? line };\n });\n const itemCount = items.reduce((sum, i) => sum + ((i.quantity as number) ?? 0), 0);\n const totals = deriveCartTotals(c);\n return {\n ...c,\n items,\n itemCount,\n subtotal: totals.subtotal,\n fees: totals.fees,\n discount: totals.discount,\n total: totals.total,\n hasFees: totals.hasFees,\n feeLabel: totals.feeLabel,\n };\n};\n\nexport function createElementsConnector(tl: TicketlayerLive): ElementsConnector {\n // ticketTypeId \u2192 { categoryId, occurrenceId }, captured on getTicketTypes so\n // addItem/addSeat can supply the categoryId the cart API requires.\n const ttMeta = new Map<string, { categoryId: string; occurrenceId: string }>();\n\n const resolve = (ticketTypeId: string, occurrenceId?: string) => {\n const meta = ttMeta.get(ticketTypeId);\n if (!meta?.categoryId) {\n throw new Error(\n `[live] No category known for ticket type ${ticketTypeId}. ` +\n `Load the occurrence's ticket types (getTicketTypes) before adding it to the cart.`\n );\n }\n return { categoryId: meta.categoryId, occurrenceId: occurrenceId || meta.occurrenceId };\n };\n\n const eventsManager = {\n async list(options?: { limit?: number; category?: string }) {\n const res = (await tl.events.list()) as {\n listings?: Array<{\n id: string;\n eventId?: string;\n name?: string | null;\n shortDescription?: string | null;\n imageUrl?: string | null;\n venueName?: string | null;\n venueCity?: string | null;\n nextOccurrenceAt?: string | null;\n }>;\n } | null;\n // Adapt the sales-surface LISTING shape to the structural shape\n // tl-event-card consumes. Two shape gaps the card otherwise renders blank:\n // - venue/date are flat (venueName/venueCity/nextOccurrenceAt) on the\n // listing but nested (venue.{name,city} / nextOccurrence.startsAt) on\n // the card.\n // - the card reads `imageUrl`; the listing already carries it (surface\n // explicitly rather than relying on a passthrough spread).\n // A listing's own id is the channel-listing id (lst_/schl_), but cards\n // navigate by EVENT id, so we surface eventId as `id`.\n let items = (res?.listings ?? []).map((l) => ({\n id: l.eventId ?? l.id,\n name: l.name ?? '',\n ...(l.shortDescription ? { shortDescription: l.shortDescription } : {}),\n ...(l.imageUrl ? { imageUrl: l.imageUrl } : {}),\n ...(l.venueName\n ? { venue: { id: '', name: l.venueName, city: l.venueCity ?? '' } }\n : {}),\n ...(l.nextOccurrenceAt ? { nextOccurrence: { startsAt: l.nextOccurrenceAt } } : {}),\n availabilityStatus: 'available' as const,\n }));\n if (options?.limit) items = items.slice(0, options.limit);\n return { items };\n },\n get: (eventId: string) => tl.events.get(eventId),\n async getTicketTypes(eventId: string, occurrenceId: string) {\n const ev = (await tl.events.get(eventId)) as {\n occurrences?: Array<{\n id: string;\n ticketTypes?: Array<{\n ticketTypeId: string;\n ticketTypeName: string;\n description: string | null;\n categoryId: string;\n categoryName: string;\n unitPrice: number;\n currency: string;\n }>;\n }>;\n } | null;\n const occ =\n ev?.occurrences?.find((o) => o.id === occurrenceId) ?? ev?.occurrences?.[0];\n const tts = occ?.ticketTypes ?? [];\n return tts.map((tt) => {\n if (occ) ttMeta.set(tt.ticketTypeId, { categoryId: tt.categoryId, occurrenceId: occ.id });\n return {\n id: tt.ticketTypeId,\n name: tt.ticketTypeName,\n description: tt.description,\n price: tt.unitPrice, // minor units; components divide by 100 to display\n currency: tt.currency,\n categoryId: tt.categoryId,\n categoryName: tt.categoryName,\n // The sales surface view doesn't expose per-order limits/remaining yet;\n // sensible defaults until the catalogue view carries them.\n maxPerOrder: 10,\n available: 999,\n };\n });\n },\n };\n\n const cartManager = {\n // Cache-first. The SDK keeps `_cart` authoritative - mutations update it and\n // every `cart:updated` carries the full cart - so Elements reading the cart\n // must NOT each trigger a GET. We return the cached cart and only fetch when\n // nothing is cached yet. This stops the fetch storm when several cart-aware\n // Elements mount, and breaks any cart:updated \u2192 get() \u2192 refresh \u2192\n // cart:updated feedback loop (which was tripping the rate limiter).\n get: async () => withCount(tl.cart.current ?? (await tl.cart.refresh())),\n on: (event: string, cb: (data: unknown) => void) =>\n tl.on(event as never, (p) => cb(event === 'cart:updated' ? withCount(p) : p)),\n off: (event: string, cb: (data: unknown) => void) => tl.off(event as never, cb),\n addItem: async (ticketTypeId: string, quantity: number, occurrenceId: string) => {\n const { categoryId, occurrenceId: occ } = resolve(ticketTypeId, occurrenceId);\n return withCount(await tl.cart.add({ eventOccurrenceId: occ, categoryId, ticketTypeId, quantity }));\n },\n addItems: async (items: Array<{ ticketTypeId: string; quantity: number; occurrenceId: string }>) => {\n let last: unknown = tl.cart.current;\n for (const it of items) last = await cartManager.addItem(it.ticketTypeId, it.quantity, it.occurrenceId);\n return last;\n },\n removeItem: async (itemId: string) => withCount(await tl.cart.remove(itemId)),\n addSeat: async (seatId: string, ticketTypeId: string, occurrenceId: string) => {\n const { categoryId, occurrenceId: occ } = resolve(ticketTypeId, occurrenceId);\n return withCount(\n await tl.cart.add({ eventOccurrenceId: occ, categoryId, ticketTypeId, eventLayoutSeatIds: [seatId] })\n );\n },\n removeSeat: async (_seatId: string, _occurrenceId: string) => {\n // The cart line-item view doesn't expose seat ids, so seat\u2192lineItem can't\n // be mapped here yet. Seat removal flows through removeItem(itemId) until\n // the view carries seat references.\n console.warn('[live] removeSeat is a no-op until cart items expose seat ids; use removeItem(itemId).');\n return withCount((await tl.cart.refresh()) ?? tl.cart.current);\n },\n };\n\n const ordersManager = {\n mine: () => tl.orders.mine(),\n get: (orderId: string) => tl.orders.get(orderId),\n ticketPdf: (orderId: string, passId: string) => tl.orders.ticketPdf(orderId, passId),\n };\n\n // Getters read the facade's session state live, so a component that asks\n // after auth:changed sees the new customer without holding its own copy.\n const authManager = {\n get customer() {\n return tl.auth.customer;\n },\n get authenticated() {\n return tl.auth.authenticated;\n },\n requestMagicLink: (contact: { email?: string; phone?: string }) => tl.auth.requestMagicLink(contact),\n exchange: (code: string) => tl.auth.exchange(code),\n logout: () => tl.auth.logout(),\n };\n\n const presaleManager = {\n redeem: (code: string) => tl.presale.redeem(code),\n };\n\n return {\n getEventsManager: () => eventsManager,\n getCartManager: () => cartManager,\n getOrdersManager: () => ordersManager,\n getAuthManager: () => authManager,\n getPresaleManager: () => presaleManager,\n on: (event: string, cb: (data: unknown) => void) => tl.on(event as never, cb),\n off: (event: string, cb: (data: unknown) => void) => tl.off(event as never, cb),\n event: (eventId: string) => ({\n openModal: (options: ModalOptions = {}) => tl.emit('ui:event-modal-requested', { eventId, ...options }),\n }),\n checkout: {\n openModal: (options: ModalOptions = {}) => tl.emit('ui:checkout-requested', options),\n closeModal: () => tl.emit('ui:modal-close-requested'),\n },\n closeModal: () => tl.emit('ui:modal-close-requested'),\n };\n}\n", "/**\n * Bidirectional event bus shared by the SDK, Elements, and the host app.\n *\n * Two directions:\n * - STATE events the SDK pushes OUT so Elements re-render (cart:updated, \u2026).\n * - UI INTENTS Elements/host push IN for someone else to act on\n * (ui:checkout-requested, ui:event-modal-requested, \u2026) - e.g. a\n * tl-buy-tickets-button emits ui:event-modal-requested and HBO opens the\n * modal. The SDK itself doesn't render UI; it just relays.\n */\nexport type LiveEvent =\n // State (SDK \u2192 subscribers)\n | 'session:changed'\n | 'cart:updated'\n | 'auth:changed'\n | 'checkout:completed'\n | 'error'\n // UI intents (Elements/host \u2192 subscribers)\n | 'ui:event-modal-requested'\n | 'ui:checkout-requested'\n | 'ui:cart-requested'\n | 'ui:login-requested'\n | 'ui:modal-close-requested';\n\ntype Handler = (payload?: unknown) => void;\n\nexport class Emitter {\n private handlers = new Map<LiveEvent, Set<Handler>>();\n\n /** Subscribe; returns an unsubscribe function. */\n on(event: LiveEvent, handler: Handler): () => void {\n if (!this.handlers.has(event)) this.handlers.set(event, new Set());\n this.handlers.get(event)!.add(handler);\n return () => this.off(event, handler);\n }\n\n off(event: LiveEvent, handler: Handler): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n emit(event: LiveEvent, payload?: unknown): void {\n this.handlers.get(event)?.forEach((h) => {\n try {\n h(payload);\n } catch (err) {\n console.error(`[live] handler for ${event} threw`, err);\n }\n });\n }\n}\n", "/**\n * Apply a resolved channel theme to the document as CSS custom properties\n * (browser only; SSR-safe no-op).\n *\n * This is the web harness's half of the token contract, and the only place in\n * this client that writes a `--tl-*` name. What each name is, what it defaults\n * to and which key of the theme document feeds it are not decided here: they\n * come from `@ticketlayer/theme`, which is also where the Elements' defaults\n * come from. `themeToCssVars` returns the declarations, including every alias a\n * token answers to, so a host reading `--tl-color-primary` or the Backstage\n * theme designer's `--tl-base-size` gets the channel's value too.\n *\n * Only the defaults are overridden. A key the theme carries that is not a\n * declared token is ignored; a new one is added in packages/theme/tokens.json,\n * where the Elements and a native harness see it as well.\n */\nimport { themeToCssVars, type ThemeDocument } from '@ticketlayer/theme';\n\nconst STYLE_ID = 'tl-theme-vars';\n\nexport type ResolvedTheme = ThemeDocument;\n\nexport function applyTheme(theme: ResolvedTheme | null | undefined): void {\n if (!theme || typeof document === 'undefined') return;\n\n const vars = Object.entries(themeToCssVars(theme)).map(([name, value]) => `${name}: ${value};`);\n\n let style = document.getElementById(STYLE_ID) as HTMLStyleElement | null;\n if (!style) {\n style = document.createElement('style');\n style.id = STYLE_ID;\n document.head.appendChild(style);\n }\n style.textContent = `:root {\\n ${vars.join('\\n ')}\\n}`;\n}\n", "/**\n * Runtime-neutral core of the Live client.\n *\n * Nothing in this module reads `window`, `document` or `location`: it is the\n * shared state layer (session, cart, auth, orders, the event bus) that both\n * adapters build on - `createLiveClient` (browser: cookie or token transport,\n * page defaults, window publishing, modals) and `createNativeLiveClient`\n * (React Native: injected token storage, X-Live-Session header, no page).\n * `theme.apply()` delegates to applyTheme, which is a no-op without a document.\n */\nimport { LiveClient, LiveAPIError } from '../client.js';\nimport { Emitter, type LiveEvent } from '../state/emitter.js';\nimport { applyTheme } from '../state/theme.js';\n\n/**\n * Stateful ergonomic layer over the generated LiveClient.\n *\n * The generated client is stateless REST; Elements and HBO need a stateful,\n * reactive surface (a session-owned cart, cart:updated events, theme\n * application, auth state). This class provides that, COORDINATING with the\n * live-api session - which owns the cartId server-side - rather than holding a\n * second source of truth: on start it loads the session's existing cart, and\n * cart mutations both update local state AND ride the same session upstream.\n */\n\nexport interface SessionState {\n channelId: string | null;\n customer: unknown | null;\n authenticated: boolean;\n}\n\n/** Result of redeeming a presale/promo code (POST /sales/presale-codes/redeem). */\nexport interface PresaleRedemption {\n benefit: string;\n alreadyHeld: boolean;\n}\n\nexport interface CartItemInput {\n eventOccurrenceId: string;\n categoryId: string;\n ticketTypeId: string;\n quantity?: number;\n eventLayoutAreaId?: string;\n eventLayoutSeatIds?: string[];\n}\n\n/**\n * Pull a named field from a response, tolerating the generator's\n * single-property auto-unwrapping: some methods return `{ cart }`, others\n * already return the cart itself. If `key` is present we use it; otherwise the\n * value is assumed to be the already-unwrapped payload.\n */\nconst field = <T>(obj: unknown, key: string): T | undefined => {\n if (obj && typeof obj === 'object' && !Array.isArray(obj) && key in obj) {\n return (obj as Record<string, unknown>)[key] as T;\n }\n return obj as T | undefined;\n};\n\nexport class TicketlayerLive {\n /** The underlying generated client (escape hatch for un-wrapped calls). */\n readonly client: LiveClient;\n\n private emitter = new Emitter();\n private sessionMode: 'cookie' | 'token';\n private publishableKey: string | undefined;\n private domain: string | undefined;\n private baseUrl: string;\n // A session is created LAZILY - only when something mutates state (cart/login).\n // Browsing uses the publishable key as read auth, so most visitors never get\n // a session (no per-visitor Redis write).\n private _sessionStarted = false;\n private _sessionStarting: Promise<void> | null = null;\n\n private _session: SessionState = { channelId: null, customer: null, authenticated: false };\n private _cart: unknown | null = null;\n private _cartId: string | null = null;\n\n // Namespaces are built in the constructor so their getters/methods close over\n // the instance (`self`) correctly - object-literal getters don't bind `this`.\n readonly events!: { list: () => Promise<unknown>; get: (eventId: string) => Promise<unknown> };\n readonly theme!: { get: () => Promise<unknown>; apply: () => Promise<unknown> };\n readonly cart!: {\n readonly current: unknown | null;\n readonly id: string | null;\n ensure: () => Promise<string>;\n add: (item: CartItemInput) => Promise<unknown>;\n remove: (itemId: string) => Promise<unknown>;\n refresh: () => Promise<unknown>;\n checkout: (opts?: { customerNotes?: string }) => Promise<unknown>;\n };\n readonly auth!: {\n readonly customer: unknown | null;\n readonly authenticated: boolean;\n requestMagicLink: (contact: { email?: string; phone?: string }) => Promise<unknown>;\n exchange: (proof: string | { type: string; code?: string; assertion?: string }) => Promise<unknown>;\n logout: () => Promise<void>;\n };\n readonly orders!: {\n mine: () => Promise<unknown>;\n get: (orderId: string) => Promise<unknown>;\n ticketPdf: (orderId: string, passId: string) => Promise<Blob>;\n };\n readonly payments!: {\n begin: (orderId: string, opts?: { paymentType?: string; returnUrl?: string }) => Promise<unknown>;\n };\n readonly presale!: {\n redeem: (code: string) => Promise<PresaleRedemption>;\n };\n readonly queue!: { status: () => Promise<unknown>; join: () => Promise<unknown> };\n\n constructor(\n client: LiveClient,\n opts: { sessionMode: 'cookie' | 'token'; publishableKey?: string; domain?: string; baseUrl: string }\n ) {\n this.client = client;\n this.sessionMode = opts.sessionMode;\n this.publishableKey = opts.publishableKey;\n this.domain = opts.domain;\n this.baseUrl = opts.baseUrl.replace(/\\/$/, '');\n\n const self = this;\n\n this.events = {\n list: () => self.client.salesListings.list(),\n get: (eventId) => self.client.sales.get(eventId).then((d) => field(d, 'event')),\n };\n\n this.theme = {\n get: () => self.client.sales.getTheme().then((d) => field(d, 'theme')),\n apply: async () => {\n const theme = await self.theme.get();\n applyTheme(theme as never);\n return theme;\n },\n };\n\n this.cart = {\n get current() {\n return self._cart;\n },\n get id() {\n return self._cartId;\n },\n ensure: async () => {\n if (!self._cartId) {\n // First mutation \u2192 create the session lazily, then the cart.\n await self.ensureSession();\n const res = await self.client.salesCarts.create({});\n const cart = field<{ id: string }>(res, 'cart');\n self._cartId = cart?.id ?? null;\n self._setCart(cart);\n }\n return self._cartId!;\n },\n add: async (item) => {\n const id = await self.cart.ensure();\n try {\n const res = await self.client.salesCarts.addItem(id, item);\n self._setCart(field(res, 'cart'));\n return self._cart;\n } catch (err) {\n if (!self._isCartGone(err)) throw err;\n // The server-side reservation lapsed under us. Drop the dead cart,\n // mint a fresh one and re-add - adding tickets should just work.\n self._resetCart();\n const freshId = await self.cart.ensure();\n const res = await self.client.salesCarts.addItem(freshId, item);\n self._setCart(field(res, 'cart'));\n return self._cart;\n }\n },\n remove: async (itemId) => {\n if (!self._cartId) return self._cart;\n try {\n const res = await self.client.salesCarts.removeItem(self._cartId, itemId);\n self._setCart(field(res, 'cart'));\n return self._cart;\n } catch (err) {\n if (!self._isCartGone(err)) throw err;\n // Nothing to remove from an expired cart - clear it locally and let\n // the UI fall through to an empty cart rather than surfacing an error.\n self._resetCart();\n return self._cart;\n }\n },\n refresh: async () => {\n if (!self._cartId) return self._cart;\n try {\n const res = await self.client.salesCarts.get(self._cartId);\n self._setCart(field(res, 'cart'));\n return self._cart;\n } catch (err) {\n if (!self._isCartGone(err)) throw err;\n // A stale cartId carried in from a prior session/page load. Forget it\n // so the next mutation starts a clean cart.\n self._resetCart();\n return self._cart;\n }\n },\n checkout: async (opts = {}) => {\n if (!self._cartId) throw new Error('No cart to check out');\n try {\n const res = await self.client.salesCarts.checkout(self._cartId, opts as never);\n self._cartId = null;\n self._setCart(null);\n self.emitter.emit('checkout:completed', field(res, 'order'));\n return res; // { cart, order, orderAccessToken }\n } catch (err) {\n if (!self._isCartGone(err)) throw err;\n // Can't check out an expired cart - clear it and surface a clear,\n // actionable error instead of the raw 409.\n self._resetCart();\n throw new LiveAPIError(\n 'Your cart has expired. Please add your tickets again.',\n 'CART_EXPIRED',\n 409,\n );\n }\n },\n };\n\n this.auth = {\n get customer() {\n return self._session.customer;\n },\n get authenticated() {\n return self._session.authenticated;\n },\n requestMagicLink: (contact) => self.client.salesCustomerAuth.magicLink(contact),\n exchange: async (proof) => {\n // Exchanging a proof binds a customer to THIS session \u2192 ensure one exists.\n await self.ensureSession();\n const body = typeof proof === 'string' ? { type: 'magic_link', code: proof } : proof;\n const res = await self.client.salesCustomerTokens.create({ proof: body });\n self._session = {\n ...self._session,\n customer: field(res, 'customer') ?? null,\n authenticated: true,\n };\n self.emitter.emit('auth:changed', self._session);\n return res;\n },\n logout: async () => {\n await self.client.session.end().catch(() => undefined);\n self._session = { channelId: self._session.channelId, customer: null, authenticated: false };\n self._cart = null;\n self._cartId = null;\n self.emitter.emit('auth:changed', self._session);\n },\n };\n\n this.orders = {\n mine: () => self.client.salesMyOrders.list().then((d) => field(d, 'orders')),\n get: (orderId) => self.client.salesOrders.get(orderId).then((d) => field(d, 'order')),\n // Binary download - bypasses the generated (JSON) client; fetches the PDF\n // with the same session credentials.\n ticketPdf: async (orderId, passId) => {\n const headers: Record<string, string> = {};\n if (self.publishableKey) headers['Authorization'] = `Bearer ${self.publishableKey}`;\n if (self.sessionMode === 'token') {\n const token = await self.client.getSessionToken();\n if (token) headers['X-Live-Session'] = token;\n }\n const res = await fetch(\n `${self.baseUrl}/sales/orders/${orderId}/passes/${passId}/ticket.pdf`,\n { headers, credentials: self.sessionMode === 'cookie' ? 'include' : 'same-origin' },\n );\n if (!res.ok) throw new LiveAPIError(`Failed to download ticket (${res.status})`, 'TICKET_PDF_FAILED', res.status);\n return res.blob();\n },\n };\n\n this.payments = {\n begin: (orderId, opts = {}) =>\n self.client.salesOrderPayments.create(orderId, opts as never).then((d) => field(d, 'payment')),\n };\n\n this.presale = {\n // POST /sales/presale-codes/redeem - needs a signed-in customer. Gated\n // pricing unlocks immediately, so re-read the cart and let cart:updated\n // carry the new totals to subscribers. A failed refresh must not undo a\n // redemption that already succeeded.\n redeem: async (code) => {\n const res = (await self.client.salesPresaleCodes.redeem({ code: code.trim() })) as PresaleRedemption;\n if (self._cartId) await self.cart.refresh().catch(() => undefined);\n return res;\n },\n };\n\n this.queue = {\n status: () => self.client.queue.status(),\n join: () => self.client.queue.join(),\n };\n }\n\n /** Subscribe to a state event or UI intent; returns an unsubscribe fn. */\n on(event: LiveEvent, handler: (payload?: unknown) => void): () => void {\n return this.emitter.on(event, handler);\n }\n off(event: LiveEvent, handler: (payload?: unknown) => void): void {\n this.emitter.off(event, handler);\n }\n /**\n * Push an event onto the shared bus. Used by Elements/host to raise UI\n * intents (e.g. ui:checkout-requested) that the host app acts on - the SDK\n * relays but does not render UI itself.\n */\n emit(event: LiveEvent, payload?: unknown): void {\n this.emitter.emit(event, payload);\n }\n\n get session(): Readonly<SessionState> {\n return this._session;\n }\n\n /** True once a session has been created/resumed (i.e. a mutation has happened). */\n get hasSession(): boolean {\n return this._sessionStarted;\n }\n\n /**\n * Create the Live session on demand and hydrate state - idempotent and\n * single-flight. Called lazily before the first mutation (cart/login); NOT on\n * page load, so browsing never creates a session. Channel is identified by the\n * publishable key (embed) or the storefront domain (hosted).\n */\n async ensureSession(): Promise<void> {\n if (this._sessionStarted) return;\n if (this._sessionStarting) return this._sessionStarting;\n\n this._sessionStarting = (async () => {\n // Embed (token transport) authenticates the session by publishable key;\n // hosted (cookie transport) by storefront domain.\n const startBody: Record<string, string> = {};\n if (this.sessionMode === 'token' && this.publishableKey) {\n startBody.channelKey = this.publishableKey;\n } else if (this.domain) {\n startBody.domain = this.domain;\n } else if (this.publishableKey) {\n startBody.channelKey = this.publishableKey;\n }\n\n const started = await this.client.session.start(startBody as never);\n if (this.sessionMode === 'token') {\n const token = field<string>(started, 'sessionToken');\n if (token) await this.client.setSessionToken(token);\n }\n this._sessionStarted = true;\n await this.refreshSession();\n })();\n\n try {\n await this._sessionStarting;\n } finally {\n this._sessionStarting = null;\n }\n }\n\n /** @deprecated Use ensureSession(); kept for back-compat. */\n async start(opts: { domain?: string } = {}): Promise<void> {\n if (opts.domain) this.domain = opts.domain;\n return this.ensureSession();\n }\n\n /**\n * Rehydrate an ALREADY-EXISTING session (hosted/cookie transport) without\n * creating one. On a page load/refresh the client is lazily session-less, but\n * a returning visitor may still hold the `live_session` cookie with a cart\n * server-side. This probes `GET /session` (a cheap read - it 401s when no\n * session exists, and never writes one): on success it binds this client to\n * that session and pulls the cart back in; on 401 it stays session-less so\n * browsing still creates no session. Marking `_sessionStarted` on success is\n * load-bearing - otherwise the next mutation's ensureSession() would POST a\n * fresh session and orphan the existing cart.\n *\n * @returns true if an existing session was resumed.\n */\n async resumeIfExists(): Promise<boolean> {\n if (this._sessionStarted) return true;\n try {\n await this.refreshSession();\n this._sessionStarted = true;\n return true;\n } catch {\n // 401 NO_SESSION (or transient) \u2192 no session to resume; remain lazy.\n return false;\n }\n }\n\n /**\n * Resume an EXISTING session by token instead of bootstrapping a new one.\n * Used by the embedded checkout iframe: the third-party page hands off its\n * session token so the iframe sees the same cart/channel (token transport).\n */\n async resume(token: string): Promise<void> {\n await this.client.setSessionToken(token);\n this._sessionStarted = true;\n await this.refreshSession();\n }\n\n /** The current session token (token mode), for handing off to an embed iframe. */\n getSessionToken(): Promise<string | null> {\n return this.client.getSessionToken();\n }\n\n /** Re-read session state (customer, auth, cart) from the live-api session. */\n async refreshSession(): Promise<void> {\n const cur = await this.client.session.current();\n this._session = {\n channelId: field<{ id: string }>(cur, 'channel')?.id ?? null,\n customer: field(cur, 'customer') ?? null,\n authenticated: !!field<boolean>(cur, 'authenticated'),\n };\n const cartId = field<string>(cur, 'cartId') ?? null;\n if (cartId) {\n this._cartId = cartId;\n await this.cart.refresh();\n }\n this.emitter.emit('session:changed', this._session);\n }\n\n /**\n * Forget that a session was started, so the next mutation or sign-in mints a\n * fresh one. For adapters whose process outlives the session (a native app\n * signing out, a stored token the API rejected); a browser page reloads instead.\n */\n protected _resetSessionStarted(): void {\n this._sessionStarted = false;\n this._sessionStarting = null;\n }\n\n private _setCart(cart: unknown): void {\n this._cart = cart ?? null;\n this.emitter.emit('cart:updated', this._cart);\n }\n\n /**\n * True when an API error means the server-side cart is no longer usable -\n * it expired (reservation TTL lapsed), was already checked out, or can't be\n * found. The SDK holds the cartId in memory and rehydrates it from the\n * server session on load, so a lapsed cart would otherwise wedge every\n * subsequent add/remove/checkout with a 409.\n */\n private _isCartGone(err: unknown): boolean {\n if (!(err instanceof LiveAPIError)) return false;\n return (\n err.code === 'CART_EXPIRED' ||\n err.code === 'CART_NOT_ACTIVE' ||\n err.code === 'CART_NOT_FOUND' ||\n err.status === 404\n );\n }\n\n /** Forget all local cart state and notify subscribers the cart is now empty. */\n private _resetCart(): void {\n this._cartId = null;\n this._setCart(null);\n }\n}\n", "import { LiveClient, type LiveClientConfig } from './client.js';\nimport { publishClient } from './state/registry.js';\nimport { loadElements, type LoadElementsOptions } from './state/loadElements.js';\nimport { installCheckoutModal, type CheckoutModalOptions } from './state/checkoutModal.js';\nimport { installBuyModal } from './state/buyModal.js';\nimport { createElementsConnector } from './elements.js';\nimport { API_DATED_VERSION } from './client.js';\nimport { TicketlayerLive } from './core/liveClient.js';\n\n/**\n * Browser adapter over the runtime-neutral core in ./core/liveClient.ts:\n * resolves the channel from the page host, picks the session transport\n * (cookie for a hosted storefront, token for embeds), publishes the client on\n * `window.Ticketlayer`, applies the theme and mounts the modals. The class\n * itself is re-exported here so existing imports keep working.\n */\nexport { TicketlayerLive };\nexport type { PresaleRedemption, SessionState, CartItemInput } from './core/liveClient.js';\n\nexport interface CreateLiveClientOptions extends LiveClientConfig, LoadElementsOptions {\n /** Storefront host to resolve the channel from (hosted mode). Defaults to the page host. */\n domain?: string;\n /** Bootstrap the session immediately (default true). */\n autoStart?: boolean;\n /** Fetch + apply the channel theme on start (default true in the browser). */\n applyTheme?: boolean;\n /**\n * Publish this client on `window.Ticketlayer` so Elements can find + bind to\n * it (default true in the browser). Set false to keep the client private.\n */\n publish?: boolean;\n /**\n * Resume an existing session by token (token transport) instead of\n * bootstrapping a new one. Used by the embedded checkout iframe to inherit\n * the parent page's cart/session. Forces sessionMode 'token'.\n */\n sessionToken?: string;\n /**\n * Checkout rendering. 'modal' (third-party embeds) auto-opens the hosted\n * checkout in an iframe overlay on `ui:checkout-requested`. Omit on HBO,\n * which handles that intent by navigating to /checkout in-page.\n */\n checkout?: { mode: 'modal' } & CheckoutModalOptions;\n /**\n * Mount the in-page buy-tickets modal (occurrence \u2192 ticket selection) on\n * `ui:event-modal-requested`. Native Elements overlay, no iframe - works on\n * HBO and embeds alike. Defaults to true in the browser for the published\n * client; set false to opt out.\n */\n buyModal?: boolean;\n}\n\n\n/** Resolve a hosted storefront's publishable key by domain (GET /channel). */\nasync function resolveChannelKey(baseUrl: string, domain: string): Promise<string | undefined> {\n try {\n const res = await fetch(\n `${baseUrl.replace(/\\/$/, '')}/channel?domain=${encodeURIComponent(domain)}`,\n { headers: { accept: 'application/json' } }\n );\n if (!res.ok) return undefined;\n const json = (await res.json()) as { data?: { publishableKey?: string } };\n return json?.data?.publishableKey;\n } catch {\n return undefined;\n }\n}\n\nexport async function createLiveClient(options: CreateLiveClientOptions): Promise<TicketlayerLive> {\n const domain =\n options.domain ?? (typeof window !== 'undefined' ? window.location.host : undefined);\n\n // Resolve the channel's publishable key - the READ credential. Embeds pass it\n // directly; a hosted storefront resolves it ONCE by domain and then uses it\n // for all reads (no per-read domain lookup, no session). Browsing never\n // creates a session - that happens lazily on the first mutation/login.\n let publishableKey = options.publishableKey;\n if (!publishableKey && !options.sessionToken && domain) {\n publishableKey = await resolveChannelKey(options.baseUrl, domain);\n }\n\n // Transport: embed/handoff use the header (token); a hosted storefront uses\n // the cookie for its (lazily-created) session.\n const isEmbed = !!options.publishableKey || !!options.sessionToken;\n const sessionMode = options.sessionMode ?? (isEmbed ? 'token' : 'cookie');\n const client = new LiveClient({\n ...options,\n sessionMode,\n ...(publishableKey ? { publishableKey } : {}),\n });\n const tl = new TicketlayerLive(client, {\n sessionMode,\n baseUrl: options.baseUrl,\n ...(publishableKey ? { publishableKey } : {}),\n ...(domain ? { domain } : {}),\n });\n\n // Publish the singleton + Elements connector so Elements bind immediately.\n if (options.publish !== false && typeof window !== 'undefined') {\n publishClient(tl, createElementsConnector(tl), API_DATED_VERSION);\n }\n\n // Third-party embeds: auto-open the hosted checkout iframe on checkout intents.\n if (options.checkout?.mode === 'modal' && typeof window !== 'undefined') {\n installCheckoutModal(tl, options.checkout);\n }\n\n // In-page buy-tickets modal (occurrence \u2192 ticket selection). Native Elements\n // overlay mounted on `ui:event-modal-requested`; works on HBO and embeds. Tied\n // to the published client (the one driving on-page UI), opt out via buyModal.\n if (options.buyModal !== false && options.publish !== false && typeof window !== 'undefined') {\n installBuyModal(tl);\n }\n\n // loadElements REJECTS when the network or the bundle fails, which is\n // logged and survivable, and THROWS synchronously when the options ask for\n // something that cannot be verified (an exact-version elementsUrl with no\n // elementsIntegrity, a hash with no URL). That throw is deliberately outside\n // the catch: a host that pinned the bundle and lost the hash gets a failed\n // createLiveClient, not a quietly unverified checkout. See\n // state/loadElements.ts for the rule in full.\n const elementsLoad = loadElements(options).catch((err) => {\n console.error('[live] Elements auto-load failed', err);\n });\n\n if (options.autoStart !== false) {\n // Embed iframe resumes a handed-off session; everyone else stays\n // session-less until the first mutation. Theme applies via the pk.\n if (options.sessionToken) {\n await tl.resume(options.sessionToken);\n } else if (sessionMode === 'cookie' && typeof window !== 'undefined') {\n // Hosted browser: if a session cookie already exists (a returning visitor\n // mid-purchase, or a refresh/deep-link), rehydrate its cart without\n // creating a session. A brand-new visitor 401s here and stays lazy.\n await tl.resumeIfExists().catch(() => undefined);\n }\n if (options.applyTheme !== false && typeof window !== 'undefined') {\n await tl.theme.apply().catch(() => undefined);\n }\n }\n\n await elementsLoad;\n return tl;\n}\n"],
5
+ "mappings": "6cAAA,IAAAA,GAAA,GAAAC,GAAAD,GAAA,qBAAAE,EAAA,SAAAC,GAAA,qBAAAC,ICIO,IAAMC,EAAW,oBACXC,EAAc,QC2BpB,IAAMC,EAAoB,aAGjC,SAASC,IAAe,CA3BxB,IAAAC,EAAAC,EAAAC,EA4BE,IAAMC,EAAI,WACV,QAAIH,EAAAG,EAAE,YAAF,YAAAH,EAAa,WAAY,cAAsB,eAC/C,OAAOG,EAAE,QAAW,aAAe,OAAOA,EAAE,UAAa,YAAoB,WAC7ED,GAAAD,EAAAE,EAAE,UAAF,YAAAF,EAAW,WAAX,MAAAC,EAAqB,KAAa,QAAQC,EAAE,QAAQ,SAAS,IAAI,GACjEA,EAAE,YAAoB,OACnB,SACT,CAQO,IAAMC,GAAoB,GAAGC,EAAS,QAAQ,KAAM,EAAE,EAAE,QAAQ,IAAK,GAAG,CAAC,IAAIC,CAAW,KAAKP,GAAe,CAAE,IAU/G,SAAUQ,IAAkB,CAChC,IAAIC,EAAuB,KAC3B,MAAO,CACL,IAAK,IAAMA,EACX,IAAMC,GAAK,CACTD,EAAQC,CACV,EACA,MAAO,IAAK,CACVD,EAAQ,IACV,EAEJ,CAuBM,IAAOE,EAAP,cAA4B,KAAK,CACrC,YACEC,EACgBC,EACAC,EAAc,CAE9B,MAAMF,CAAO,EAHG,KAAA,KAAAC,EACA,KAAA,OAAAC,EAGhB,KAAK,KAAO,cACd,GASWC,EAAP,KAAiB,CAQrB,YAAYC,EAAwB,CA/GtC,IAAAf,EAAAC,EAAAC,EAAAc,EA4LE,KAAA,cAAgB,CAMV,KAAM,SACS,MAAM,KAAK,QAAkC,kBAAmB,CAC/E,OAAQ,MACT,GASL,KAAA,kBAAoB,CAMd,UAAW,MAAOC,IACH,MAAM,KAAK,QAAgC,kCAAmC,CAC7F,OAAQ,OACR,KAAM,KAAK,UAAUA,CAAO,EAC7B,GAEe,MAOpB,KAAA,oBAAsB,CAMhB,OAAQ,MAAOA,GACA,MAAM,KAAK,QAAoC,yBAA0B,CACxF,OAAQ,OACR,KAAM,KAAK,UAAUA,CAAO,EAC7B,EAUC,QAAS,SACM,MAAM,KAAK,QAAoC,iCAAkC,CAChG,OAAQ,OACT,GASL,KAAA,WAAa,CAMP,OAAQ,MAAOA,IACA,MAAM,KAAK,QAA2B,eAAgB,CACrE,OAAQ,OACR,KAAM,KAAK,UAAUA,CAAO,EAC7B,GAEe,KAQd,IAAK,MAAOC,IACG,MAAM,KAAK,QAA2B,gBAAgBA,CAAM,GAAI,CAC/E,OAAQ,MACT,GAEe,KAQd,QAAS,MAAOA,EAAgBD,KACjB,MAAM,KAAK,QAA2B,gBAAgBC,CAAM,SAAU,CACrF,OAAQ,OACR,KAAM,KAAK,UAAUD,CAAO,EAC7B,GAEe,KAQd,WAAY,MAAOC,EAAgBC,KACpB,MAAM,KAAK,QAA2B,gBAAgBD,CAAM,UAAUC,CAAM,GAAI,CAC/F,OAAQ,SACT,GAEe,KAQd,SAAU,MAAOD,EAAgBD,IAClB,MAAM,KAAK,QAA+B,gBAAgBC,CAAM,YAAa,CAC5F,OAAQ,OACR,KAAM,KAAK,UAAUD,CAAO,EAC7B,GASL,KAAA,cAAgB,CAMV,KAAM,UACS,MAAM,KAAK,QAAmC,mBAAoB,CACjF,OAAQ,MACT,GAEe,QAOpB,KAAA,YAAc,CAMR,IAAK,MAAOG,IACG,MAAM,KAAK,QAA+B,iBAAiBA,CAAO,GAAI,CACrF,OAAQ,MACT,GAEe,MAQd,UAAW,MAAOA,EAAiBC,IACpB,MAAM,KAAK,QAAa,iBAAiBD,CAAO,WAAWC,CAAM,cAAe,CAC/F,OAAQ,MACT,GASL,KAAA,mBAAqB,CAMf,OAAQ,MAAOD,EAAiBH,KACjB,MAAM,KAAK,QAAyC,iBAAiBG,CAAO,YAAa,CACxG,OAAQ,OACR,KAAM,KAAK,UAAUH,CAAO,EAC7B,GAEe,SAOpB,KAAA,oBAAsB,CAMhB,OAAQ,MAAOG,EAAiBH,KACjB,MAAM,KAAK,QAA0C,iBAAiBG,CAAO,mBAAoB,CAChH,OAAQ,OACR,KAAM,KAAK,UAAUH,CAAO,EAC7B,GAEe,SAOpB,KAAA,eAAiB,CAMX,OAAQ,MAAOA,IACA,MAAM,KAAK,QAA+B,mBAAoB,CAC7E,OAAQ,OACR,KAAM,KAAK,UAAUA,CAAO,EAC7B,GAEe,SAQd,IAAK,MAAOK,IACG,MAAM,KAAK,QAA+B,oBAAoBA,CAAU,GAAI,CAC3F,OAAQ,MACT,GAEe,SAQd,OAAQ,MAAOA,EAAoBL,KACpB,MAAM,KAAK,QAA+B,oBAAoBK,CAAU,GAAI,CAC3F,OAAQ,QACR,KAAM,KAAK,UAAUL,CAAO,EAC7B,GAEe,UAOpB,KAAA,kBAAoB,CAMd,OAAQ,MAAOA,GACA,MAAM,KAAK,QAAwC,8BAA+B,CACjG,OAAQ,OACR,KAAM,KAAK,UAAUA,CAAO,EAC7B,GASL,KAAA,MAAQ,CAMF,eAAgB,MAAOM,GAAgC,CACzD,IAAMC,EAAS,IAAI,iBACfD,GAAA,YAAAA,EAAS,UAAW,QAAWC,EAAO,OAAO,SAAU,OAAOD,EAAQ,MAAM,CAAC,EACjF,IAAME,EAAcD,EAAO,SAAQ,EAC7BE,EAAcD,EAAc,kBAAkBA,CAAW,GAAK,iBAMpE,OAJiB,MAAM,KAAK,QAAqCC,EAAa,CAC5E,OAAQ,MACT,CAGC,EAOA,IAAK,MAAOC,IACG,MAAM,KAAK,QAAkC,iBAAiBA,CAAO,GAAI,CACxF,OAAQ,MACT,GAEe,MAQd,SAAU,UACK,MAAM,KAAK,QAA4B,eAAgB,CACtE,OAAQ,MACT,GAEe,OAOpB,KAAA,QAAU,CAMJ,MAAO,MAAOV,GACC,MAAM,KAAK,QAAa,WAAY,CACnD,OAAQ,OACR,KAAM,KAAK,UAAUA,CAAO,EAC7B,EAUC,QAAS,SACM,MAAM,KAAK,QAAa,WAAY,CACnD,OAAQ,MACT,EAUC,IAAK,SACU,MAAM,KAAK,QAAa,WAAY,CACnD,OAAQ,SACT,EAUC,kBAAmB,MAAOA,GACX,MAAM,KAAK,QAAa,wBAAyB,CAChE,OAAQ,OACR,KAAM,KAAK,UAAUA,CAAO,EAC7B,GASL,KAAA,MAAQ,CAMF,OAAQ,SACO,MAAM,KAAK,QAAa,gBAAiB,CACxD,OAAQ,MACT,EAUC,KAAM,SACS,MAAM,KAAK,QAAa,cAAe,CACtD,OAAQ,OACT,GApfH,KAAK,QAAUF,EAAO,QAAQ,QAAQ,MAAO,EAAE,EAC/C,KAAK,aAAcf,EAAAe,EAAO,cAAP,KAAAf,EAAsB,SACzC,KAAK,eAAiBe,EAAO,eAC7B,KAAK,cAAed,EAAAc,EAAO,eAAP,KAAAd,EAAuBM,GAAkB,EAC7D,KAAK,YAAaL,EAAAa,EAAO,aAAP,KAAAb,EAAqBJ,EACvC,KAAK,SAAUkB,EAAAD,EAAO,UAAP,KAAAC,EAAkB,CAAA,CACnC,CAGA,MAAM,gBAAgBR,EAAa,CACjC,MAAM,KAAK,aAAa,IAAIA,CAAK,CACnC,CAGA,MAAM,iBAAe,CACnB,OAAO,KAAK,aAAa,IAAG,CAC9B,CAEA,MAAM,cAAY,CAChB,MAAM,KAAK,aAAa,MAAK,CAC/B,CAOQ,MAAM,QAAWoB,EAAcL,EAAuB,CAAA,EAAE,CA3IlE,IAAAvB,EAAAC,EAAAC,EA4II,IAAM2B,EAAM,GAAG,KAAK,OAAO,GAAGD,CAAI,GAE5BE,EAAkC,CACtC,eAAgB,mBAChB,aAAc,KAAK,WACnB,YAAa1B,GACb,GAAG,KAAK,QACR,GAAImB,EAAQ,SAOd,GAJI,KAAK,iBACPO,EAAQ,cAAmB,UAAU,KAAK,cAAc,IAGtD,KAAK,cAAgB,QAAS,CAChC,IAAMtB,EAAQ,MAAM,KAAK,aAAa,IAAG,EACrCA,IAAOsB,EAAQ,gBAAgB,EAAItB,EACzC,CAEA,IAAMuB,EAAW,MAAM,MAAMF,EAAK,CAChC,GAAGN,EACH,QAAAO,EAEA,YAAa,KAAK,cAAgB,SAAW,UAAY,cAC1D,EAEKE,EAAO,MAAMD,EAAS,KAAI,EAC1BE,EAAOD,EAAO,KAAK,MAAMA,CAAI,EAAI,KAEvC,GAAI,CAACD,EAAS,GAAI,CAChB,IAAMG,GAAQlC,EAAAiC,GAAA,YAAAA,EAAM,QAAN,KAAAjC,EAAe,CAAA,EAC7B,MAAM,IAAIU,GACRT,EAAAiC,EAAM,UAAN,KAAAjC,EAAiB,mBAAmB8B,EAAS,MAAM,KACnD7B,EAAAgC,EAAM,OAAN,KAAAhC,EAAc,iBACd6B,EAAS,MAAM,CAEnB,CAGA,OAAIE,GAAQA,EAAK,SAAW,WAAaA,EAAK,OAAS,OAC9CA,EAAK,KAEPA,CACT,GC9KK,IAAME,EAAyB,cACzBC,GAA0B,oBAwBvC,SAASC,GAA4BC,EAAe,CAClD,IAAMC,EAAI,OACV,GAAIA,EAAEJ,CAAsB,EAAG,OAAOI,EAAEJ,CAAsB,EAE9D,IAAMK,EAAmC,CACvC,OAAQ,KACR,IAAK,KACL,QAAAF,EACA,WAAY,CAAA,EACZ,WAAS,CACP,OAAO,KAAK,MACd,EACA,QAAM,CACJ,OAAO,KAAK,GACd,EACA,OAAK,CACH,OAAI,KAAK,OAAe,QAAQ,QAAQ,KAAK,MAAM,EAC5C,IAAI,QAAiBG,GAAY,KAAK,WAAW,KAAKA,CAAO,CAAC,CACvE,GAEF,OAAAF,EAAEJ,CAAsB,EAAIK,EACrBA,CACT,CAGM,SAAUE,EAA2BC,EAAgBC,EAAUN,EAAe,CAClF,GAAI,OAAO,QAAW,YAAa,OACnC,IAAME,EAAMH,GAA4BC,CAAO,EAE3CE,EAAI,QAAUA,EAAI,SAAWG,GAC/B,QAAQ,KACN,8GACoC,EAIxCH,EAAI,OAASG,EACbH,EAAI,IAAMI,EACV,IAAMC,EAAYL,EAAI,WACtBA,EAAI,WAAa,CAAA,EACjBK,EAAU,QAASC,GAAMA,EAAEH,CAAM,CAAC,EAElC,OAAO,cAAc,IAAI,YAAYP,GAAyB,CAAE,OAAQO,CAAM,CAAE,CAAC,CACnF,CCnCA,IAAMI,EACJ,2FAEIC,GAAe,gBACfC,EAAW,IAAI,IAOfC,GAAc,4CAGdC,GAAY,+FAkBLC,EAAP,cAAsC,KAAK,CAC/C,YAAYC,EAAe,CACzB,MAAM,UAAUA,CAAO,EAAE,EACzB,KAAK,KAAO,wBACd,GAGEC,EAAqB,GAEnB,SAAUC,EAAaC,EAA4B,CAAA,EAAE,CA3F3D,IAAAC,EAAAC,EA4FE,GAAI,CAACF,EAAK,SAAU,OAAO,QAAQ,QAAO,EAE1C,IAAMG,IAAYF,EAAAD,EAAK,oBAAL,YAAAC,EAAwB,SAAU,OAKpD,GAAIE,GAAa,CAACH,EAAK,YACrB,MAAM,IAAIJ,EACR,0PAE4E,EAGhF,GAAIO,GAAa,CAACR,GAAU,KAAKQ,CAAS,EACxC,MAAM,IAAIP,EACR,2DAA2D,KAAK,UAAUI,EAAK,iBAAiB,CAAC,2GACU,EAG/G,GAAIA,EAAK,aAAe,CAACG,GAAaT,GAAY,KAAKM,EAAK,WAAW,EACrE,MAAM,IAAIJ,EACR,eAAeI,EAAK,WAAW,sUAG+C,EAIlF,GAAI,OAAO,QAAW,aAAe,OAAO,UAAa,YAAa,OAAO,QAAQ,QAAO,EAG5F,IAAMI,EAAM,OAAiE,eAC7E,GAAIA,GAAA,MAAAA,EAAI,IAAIZ,IAAe,OAAO,QAAQ,QAAO,EAEjD,IAAMa,GAAMH,EAAAF,EAAK,cAAL,KAAAE,EAAoBX,EAE5B,CAACS,EAAK,aAAe,CAACF,IACxBA,EAAqB,GACrB,QAAQ,KACN,gEAAgEP,CAAoB,kRAGO,GAI/F,IAAMe,EAAWb,EAAS,IAAIY,CAAG,EACjC,GAAIC,EAAU,OAAOA,EAErB,IAAMC,EAAI,IAAI,QAAc,CAACC,EAASC,IAAU,CAC9C,IAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,KAAO,SACdA,EAAO,IAAML,EACbK,EAAO,MAAQ,GACXP,IACFO,EAAO,UAAYP,EAGnBO,EAAO,YAAc,aAEvBA,EAAO,QAAQ,oBAAsB,OACrCA,EAAO,OAAS,IAAMF,EAAO,EAC7BE,EAAO,QAAU,IAAMD,EAAO,IAAI,MAAM,uCAAuCJ,CAAG,EAAE,CAAC,EACrF,SAAS,KAAK,YAAYK,CAAM,CAClC,CAAC,EAED,OAAAjB,EAAS,IAAIY,EAAKE,CAAC,EACZA,CACT,CCpGO,IAAMI,EAAgB,CAC3B,gBAAiB,UACjB,2BAA4B,qBAC5B,kBAAmB,YACnB,6BAA8B,uBAC9B,eAAgB,SAChB,0BAA2B,oBAC3B,mBAAoB,aACpB,mBAAoB,aACpB,aAAc,OACd,cAAe,QACf,yBAA0B,mBAC1B,eAAgB,SAChB,qBAAsB,eACtB,cAAe,QACf,aAAc,OACd,gBAAiB,UACjB,2BAA4B,qBAC5B,gBAAiB,UACjB,2BAA4B,qBAC5B,mBAAoB,aACpB,cAAe,QACf,YAAe,QACf,oBAAqB,QACrB,yBAA0B,mBAC1B,yBAA0B,mBAC1B,+BAAgC,mBAChC,iBAAkB,WAClB,iBAAkB,WAClB,uBAAwB,WACxB,aAAc,OACd,wBAAyB,kBACzB,gBAAiB,UACjB,YAAa,iBACb,OAAU,aAMCC,EAA4C,CACvD,QAAW,UACX,qBAAsB,UACtB,UAAa,UACb,uBAAwB,UACxB,OAAU,UACV,oBAAqB,UACrB,WAAc,UACd,WAAc,UACd,KAAQ,UACR,MAAS,UACT,mBAAoB,UACpB,OAAU,UACV,eAAgB,UAChB,MAAS,UACT,KAAQ,UACR,QAAW,UACX,qBAAsB,UACtB,QAAW,UACX,qBAAsB,UACtB,aAAc,UACd,MAAS,UACT,mBAAoB,UACpB,WAAY,UACZ,KAAQ,UACR,kBAAmB,UACnB,UAAW,UACX,cAAe,+EACf,mBAAoB,4DACpB,iBAAkB,OAClB,aAAc,OACd,cAAe,MACf,YAAa,UACb,YAAa,SACb,YAAa,UACb,cAAe,SACf,YAAa,UACb,YAAa,SACb,YAAa,UACb,YAAa,OACb,YAAa,UACb,YAAa,SACb,YAAa,OACb,gBAAiB,QACjB,kBAAmB,QACnB,gBAAiB,QACjB,kBAAmB,6BACnB,oBAAqB,8BAkChB,IAAMC,EAAuD,CAClE,QAAW,iBACX,qBAAsB,2BACtB,UAAa,mBACb,uBAAwB,6BACxB,OAAU,gBACV,oBAAqB,0BACrB,WAAc,oBACd,WAAc,oBACd,MAAS,eACT,mBAAoB,yBACpB,OAAU,gBACV,MAAS,eACT,KAAQ,cACR,QAAW,iBACX,qBAAsB,2BACtB,QAAW,iBACX,qBAAsB,2BACtB,MAAS,qBACT,mBAAoB,+BACpB,cAAe,wBACf,mBAAoB,4BACpB,iBAAkB,sBAClB,aAAc,wBACd,cAAe,mBACf,YAAa,iBACb,YAAa,iBACb,YAAa,iBACb,cAAe,oBChLX,SAAUC,EAAOC,EAAY,CACjC,MAAO,QAAQA,CAAI,EACrB,CAmCM,SAAUC,EAAeC,EAAuC,CAvEtE,IAAAC,EAwEE,IAAMC,EAA+B,CAAA,EACrC,GAAI,CAACF,EAAO,OAAOE,EAEnB,OAAW,CAACC,EAAOC,CAAQ,IAAK,OAAO,QAAQC,CAAgB,EAAG,CAChE,GAAM,CAACC,EAASC,CAAG,EAAIH,EAAS,MAAM,GAAG,EACnCI,GAASP,EAAAD,EAAqEM,CAAO,IAA5E,YAAAL,EAAgFM,GACpEC,GAAU,MAAQA,IAAU,KACvDN,EAAKO,EAAON,CAAK,CAAC,EAAI,OAAOK,CAAK,EACpC,CAEA,OAAW,CAACE,EAAOP,CAAK,IAAK,OAAO,QAAQQ,CAAa,EAAG,CAC1D,IAAMH,EAAQN,EAAKO,EAAON,CAAK,CAAC,EAC5BK,IAAU,SAAWN,EAAKO,EAAOC,CAAK,CAAC,EAAIF,EACjD,CAEA,OAAON,CACT,CC1CA,IAAMU,EAAa,sBAIb,SAAUC,EACdC,EACAC,EAA6B,CAAA,EAAE,CAE/B,GAAI,OAAO,QAAW,aAAe,OAAO,UAAa,YAAa,MAAO,IAAK,CAAE,EAEpF,IAAIC,EAAgD,KAE9CC,EAAQ,IAAK,CA1DrB,IAAAC,GA2DIA,EAAA,SAAS,eAAeN,CAAU,IAAlC,MAAAM,EAAqC,SACjCF,IACF,OAAO,oBAAoB,UAAWA,CAAS,EAC/CA,EAAY,KAEhB,EAEMG,EAAO,MAAOC,GAA0B,CAC5C,IAAMC,EAAQ,MAAMP,EAAG,gBAAe,EAAG,MAAM,IAAM,IAAI,EACnDQ,GAAQP,EAAK,cAAgB,OAAO,SAAS,QAAQ,QAAQ,MAAO,EAAE,EACtEQ,EAAQ,IAAI,gBACdF,GAAOE,EAAM,IAAI,UAAWF,CAAK,EAErCE,EAAM,IAAI,gBAAiB,OAAO,SAAS,MAAM,EACjD,IAAMC,EAAM,GAAGF,CAAI,mBAAmBC,EAAM,SAAQ,CAAE,GAChDE,EAAc,IAAI,IAAID,CAAG,EAAE,OAEjCP,EAAK,EAEL,IAAMS,EAAU,SAAS,cAAc,KAAK,EAC5CA,EAAQ,GAAKd,EAEbc,EAAQ,MAAM,QACZ,2OAMF,IAAMC,EAAU,SAAS,cAAc,KAAK,EAC5CA,EAAQ,MAAM,QACZ,0EAEF,IAAMC,EAAQ,SAAS,cAAc,QAAQ,EAC7CA,EAAM,IAAMJ,EACZI,EAAM,MAAQ,UASdA,EAAM,MAAM,QACV,6EAA6EC,EAAe,MAAM,gFAWpGF,EAAQ,YAAYC,CAAK,EACzBF,EAAQ,YAAYC,CAAO,EAE3BD,EAAQ,iBAAiB,QAAUI,GAAK,CAtH5C,IAAAZ,GAuHUY,EAAE,SAAWJ,GAAWI,EAAE,SAAWH,KACvCV,EAAK,GACLC,EAAAE,EAAO,UAAP,MAAAF,EAAA,KAAAE,GAEJ,CAAC,EACD,SAAS,KAAK,YAAYM,CAAO,EAEjCV,EAAac,GAAmB,CA9HpC,IAAAZ,EAAAa,EAAAC,EAgIM,GAAIF,EAAE,SAAWL,EAAa,OAC9B,IAAMQ,EAAMH,EAAE,KACd,GAAI,GAACG,GAAO,OAAOA,GAAQ,UAC3B,OAAQA,EAAI,KAAM,CAChB,IAAK,cAAe,CAGlB,IAAMC,EAAUD,EAAI,OAAS,OAAOA,EAAI,OAAU,SAAWA,EAAI,MAAQ,CAAA,EACnEE,EAAiBF,EAAI,QACvB,CACE,GAAGC,EACH,GAAID,EAAI,QACR,YAAaA,EAAI,eACjB,GAAIA,EAAI,YAAc,CAAE,YAAaA,EAAI,WAAW,EAAK,CAAA,GAE3DA,EAAI,OACRf,EAAAE,EAAO,aAAP,MAAAF,EAAA,KAAAE,EAAoBe,GACpBrB,EAAG,KAAK,qBAAsBqB,CAAK,EACnClB,EAAK,EACL,KACF,CACA,IAAK,WACL,IAAK,aACHc,EAAAX,EAAO,UAAP,MAAAW,EAAA,KAAAX,GACAH,EAAK,EACL,MACF,IAAK,WAAY,CACf,IAAMmB,EAAM,IAAI,MAAMH,EAAI,SAAWA,EAAI,MAAQ,iBAAiB,EAC9DA,EAAI,OAAOG,EAAkC,KAAOH,EAAI,OAC5DD,EAAAZ,EAAO,UAAP,MAAAY,EAAA,KAAAZ,EAAiBgB,GACjB,KACF,CAEF,CACF,EACA,OAAO,iBAAiB,UAAWpB,CAAS,CAC9C,EAEMqB,EAAcvB,EAAG,GAAG,wBAA0BwB,GAAM,KAAKnB,EAAMmB,GAAA,KAAAA,EAAwB,CAAA,CAAE,CAAC,EAC1FC,EAAWzB,EAAG,GAAG,2BAA4B,IAAMG,EAAK,CAAE,EAEhE,MAAO,IAAK,CACVoB,EAAW,EACXE,EAAQ,EACRtB,EAAK,CACP,CACF,CC9IM,SAAUuB,GAAgBC,EAAqBC,EAAwB,CAAA,EAAE,CAC7E,GAAI,OAAO,QAAW,aAAe,OAAO,UAAa,YAAa,MAAO,IAAK,CAAE,EAEpF,IAAMC,EAAMD,EAAK,KAAO,eACpBE,EAAyB,KACzBC,EAA4B,KAE1BC,EAAS,IAAK,CACdF,IACFA,EAAG,OAAM,EACTA,EAAK,MAEPC,EAAU,IACZ,EAEME,EAAQC,GAAqB,CACjC,GAAI,EAACA,GAAA,MAAAA,EAAQ,SAAS,OACtBF,EAAM,EACND,EAAUG,EAEV,IAAMC,EAAO,SAAS,cAAcN,CAAG,EAEvCM,EAAK,aAAa,WAAYD,EAAO,OAAO,EACxCA,EAAO,cAAcC,EAAK,aAAa,gBAAiBD,EAAO,YAAY,EAE/EC,EAAK,iBAAiB,UAAW,IAAK,CA1B1C,IAAAC,EA2BM,IAAMC,EAAIN,EACVC,EAAM,GACNI,EAAAC,GAAA,YAAAA,EAAG,UAAH,MAAAD,EAAA,KAAAC,EACF,CAAC,EAEDF,EAAK,iBAAiB,UAAYG,GAAY,CAhClD,IAAAF,EAAAG,EAiCM,IAAMC,IACHJ,EAAAE,EAAwC,SAAxC,YAAAF,EAAgD,UAAW,6BAC9DG,EAAAR,GAAA,YAAAA,EAAS,UAAT,MAAAQ,EAAA,KAAAR,EAAmB,IAAI,MAAMS,CAAO,EACtC,CAAC,EAEDL,EAAK,iBAAiB,aAAc,IAAK,CACvC,IAAME,EAAIN,EACVC,EAAM,EAGNL,EAAG,KAAK,wBAAyB,CAC/B,WAAYU,GAAA,YAAAA,EAAG,WACf,QAASA,GAAA,YAAAA,EAAG,QACZ,QAASA,GAAA,YAAAA,EAAG,QACb,CACH,CAAC,EAED,SAAS,KAAK,YAAYF,CAAI,EAC9BL,EAAKK,CACP,EAEMM,EAAUd,EAAG,GAAG,2BAA6Be,GAAMT,EAAMS,GAAA,KAAAA,EAAoB,CAAA,CAAgB,CAAC,EAC9FC,EAAWhB,EAAG,GAAG,2BAA4B,IAAMK,EAAM,CAAE,EAEjE,MAAO,IAAK,CACVS,EAAO,EACPE,EAAQ,EACRX,EAAM,CACR,CACF,CCnCA,IAAMY,GAAOC,GAAqBA,GAAK,OAAOA,GAAM,SAAYA,EAAY,CAAA,EAQtE,SAAUC,EAAWC,EAAc,CACvC,OAAI,OAAOA,GAAU,SAAiB,OAAO,UAAUA,CAAK,EAAIA,EAAQ,KACpE,OAAOA,GAAU,UAAY,UAAU,KAAKA,CAAK,EAAU,OAAOA,CAAK,EACpE,IACT,CAEA,IAAMC,EAAYC,GAAuB,OAAOA,EAAK,MAAS,SAAWA,EAAK,KAAO,SAG/EC,GAAgBD,GAAuB,CAAC,CAAC,MAAO,MAAO,UAAU,EAAE,SAASD,EAASC,CAAI,CAAC,EAYhG,SAASE,GAAaC,EAAqBC,EAAc,CACvD,OAAID,IAAS,KAAaC,EACnBD,EAAO,GAAKC,CACrB,CAYM,SAAUC,GAAiBC,EAAa,CAtG9C,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAuGE,IAAMC,EAAIpB,GAAIW,CAAI,EACZU,EAAQ,MAAM,QAAQD,EAAE,KAAK,EAAIA,EAAE,MAAM,IAAIpB,EAAG,EAAI,CAAA,EAEpDsB,GACJT,GAAAD,EAAAV,EAAWkB,EAAE,aAAa,IAA1B,KAAAR,EACAV,EAAWkB,EAAE,QAAQ,IADrB,KAAAP,EAEAQ,EAAM,OAAOf,EAAY,EAAE,OAAO,CAACiB,EAAKlB,IAAM,CA7GlD,IAAAO,EA6GqD,OAAAW,IAAOX,EAAAV,EAAWG,EAAK,QAAQ,IAAxB,KAAAO,EAA6B,IAAI,CAAC,EAEtFY,EAAWH,EAAM,OAAQhB,GAASD,EAASC,CAAI,IAAM,KAAK,EAC1DoB,EAAeD,EAAS,OAC1BA,EAAS,OAAO,CAACD,EAAKlB,IAAM,CAjHlC,IAAAO,EAiHqC,OAAAW,IAAOX,EAAAV,EAAWG,EAAK,QAAQ,IAAxB,KAAAO,EAA6B,IAAI,CAAC,EACxE,KACEJ,GAAOO,GAAAD,EAAAZ,EAAWkB,EAAE,SAAS,IAAtB,KAAAN,EAA2BZ,EAAWkB,EAAE,IAAI,IAA5C,KAAAL,EAAiDU,EAExDC,EAAW,OAAON,EAAE,UAAa,UAAYA,EAAE,SAAWA,EAAE,SAAW,KACvEO,EAAYH,EAAS,IAAKnB,GAASA,EAAK,IAAI,EAAE,KAAMuB,GAAM,OAAOA,GAAM,UAAYA,CAAC,EAGpFC,GAAWb,EAAAU,GAAA,KAAAA,EAAYC,IAAZ,KAAAX,EAAyB,KAEpCc,EAAgBT,EAAM,OAAQhB,GAASD,EAASC,CAAI,IAAM,UAAU,EACpE0B,EAAoBD,EAAc,OACpCA,EAAc,OAAO,CAACP,EAAKlB,IAAM,CA7HvC,IAAAO,EA6H0C,OAAAW,EAAM,KAAK,KAAIX,EAAAV,EAAWG,EAAK,QAAQ,IAAxB,KAAAO,EAA6B,CAAC,GAAG,CAAC,EACrF,KACEoB,GAAWd,GAAAD,EAAAf,EAAWkB,EAAE,cAAc,IAA3B,KAAAH,EAAgCf,EAAWkB,EAAE,QAAQ,IAArD,KAAAF,EAA0Da,EAErEE,GAAMd,EAAAjB,EAAWkB,EAAE,QAAQ,IAArB,KAAAD,EAA0B,EAIhCe,EAAchC,EAAWkB,EAAE,KAAK,EAChCe,EAAQD,GAAA,KAAAA,EAAeZ,GAAYd,GAAA,KAAAA,EAAQ,GAAKyB,GAAOD,GAAA,KAAAA,EAAY,GAEzE,MAAO,CACL,SAAU,OAAOZ,EAAE,UAAa,SAAWA,EAAE,SAAW,KACxD,SAAAE,EACA,KAAMd,GAAA,KAAAA,EAAQ,EACd,SAAUwB,GAAA,KAAAA,EAAY,EACtB,MAAAG,EACA,QAAS5B,GAAaC,EAAMqB,IAAa,MAAQL,EAAS,OAAS,CAAC,EACpE,SAAAK,EACA,gBAAiBK,IAAgB,KAErC,CCvDA,IAAME,EAAaC,GAA0B,CAnE7C,IAAAC,EAoEE,GAAI,CAACD,GAAQ,OAAOA,GAAS,SAAU,OAAOA,EAC9C,IAAME,EAAIF,EACJG,IAAyCF,EAAAC,EAAE,QAAF,KAAAD,EAAW,CAAA,GAAI,IAAKG,GAAK,CAtE1E,IAAAH,EAAAI,EAAAC,EAuEI,IAAMC,EAAKH,EACLI,GAAOP,EAAAM,EAAG,WAAH,KAAAN,EAA0B,EACjCQ,GAAQJ,EAAAE,EAAG,WAAH,KAAAF,EAA2BE,EAAG,UAAuBC,EACnE,MAAO,CAAE,GAAGD,EAAI,YAAYD,EAAAC,EAAG,aAAH,KAAAD,EAAiBG,CAAI,CACnD,CAAC,EACKC,EAAYP,EAAM,OAAO,CAACQ,EAAKP,IAAG,CA5E1C,IAAAH,EA4E6C,OAAAU,IAAQV,EAAAG,EAAE,WAAF,KAAAH,EAAyB,IAAI,CAAC,EAC3EW,EAASC,GAAiBX,CAAC,EACjC,MAAO,CACL,GAAGA,EACH,MAAAC,EACA,UAAAO,EACA,SAAUE,EAAO,SACjB,KAAMA,EAAO,KACb,SAAUA,EAAO,SACjB,MAAOA,EAAO,MACd,QAASA,EAAO,QAChB,SAAUA,EAAO,SAErB,EAEM,SAAUE,GAAwBC,EAAmB,CAGzD,IAAMC,EAAS,IAAI,IAEbC,EAAU,CAACC,EAAsBC,IAAyB,CAC9D,IAAMC,EAAOJ,EAAO,IAAIE,CAAY,EACpC,GAAI,EAACE,GAAA,MAAAA,EAAM,YACT,MAAM,IAAI,MACR,4CAA4CF,CAAY,qFAC6B,EAGzF,MAAO,CAAE,WAAYE,EAAK,WAAY,aAAcD,GAAgBC,EAAK,YAAY,CACvF,EAEMC,EAAgB,CACpB,MAAM,KAAKC,EAA+C,CA5G9D,IAAArB,EA6GM,IAAMsB,EAAO,MAAMR,EAAG,OAAO,KAAI,EAqB7BZ,IAASF,EAAAsB,GAAA,YAAAA,EAAK,WAAL,KAAAtB,EAAiB,CAAA,GAAI,IAAKuB,GAAG,CAlIhD,IAAAvB,EAAAI,EAAAC,EAkIoD,OAC5C,IAAIL,EAAAuB,EAAE,UAAF,KAAAvB,EAAauB,EAAE,GACnB,MAAMnB,EAAAmB,EAAE,OAAF,KAAAnB,EAAU,GAChB,GAAImB,EAAE,iBAAmB,CAAE,iBAAkBA,EAAE,gBAAgB,EAAK,CAAA,EACpE,GAAIA,EAAE,SAAW,CAAE,SAAUA,EAAE,QAAQ,EAAK,CAAA,EAC5C,GAAIA,EAAE,UACF,CAAE,MAAO,CAAE,GAAI,GAAI,KAAMA,EAAE,UAAW,MAAMlB,EAAAkB,EAAE,YAAF,KAAAlB,EAAe,EAAE,CAAE,EAC/D,CAAA,EACJ,GAAIkB,EAAE,iBAAmB,CAAE,eAAgB,CAAE,SAAUA,EAAE,gBAAgB,CAAE,EAAK,CAAA,EAChF,mBAAoB,aACpB,EACF,OAAIF,GAAA,MAAAA,EAAS,QAAOnB,EAAQA,EAAM,MAAM,EAAGmB,EAAQ,KAAK,GACjD,CAAE,MAAAnB,CAAK,CAChB,EACA,IAAMsB,GAAoBV,EAAG,OAAO,IAAIU,CAAO,EAC/C,MAAM,eAAeA,EAAiBN,EAAoB,CAjJ9D,IAAAlB,EAAAI,EAAAC,EAAAoB,EAkJM,IAAMC,EAAM,MAAMZ,EAAG,OAAO,IAAIU,CAAO,EAcjCG,GACJtB,GAAAL,EAAA0B,GAAA,YAAAA,EAAI,cAAJ,YAAA1B,EAAiB,KAAM4B,GAAMA,EAAE,KAAOV,KAAtC,KAAAb,GAAuDD,EAAAsB,GAAA,YAAAA,EAAI,cAAJ,YAAAtB,EAAkB,GAE3E,QADYqB,EAAAE,GAAA,YAAAA,EAAK,cAAL,KAAAF,EAAoB,CAAA,GACrB,IAAKI,IACVF,GAAKZ,EAAO,IAAIc,EAAG,aAAc,CAAE,WAAYA,EAAG,WAAY,aAAcF,EAAI,EAAE,CAAE,EACjF,CACL,GAAIE,EAAG,aACP,KAAMA,EAAG,eACT,YAAaA,EAAG,YAChB,MAAOA,EAAG,UACV,SAAUA,EAAG,SACb,WAAYA,EAAG,WACf,aAAcA,EAAG,aAGjB,YAAa,GACb,UAAW,KAEd,CACH,GAGIC,EAAc,CAOlB,IAAK,SAAS,CA7LlB,IAAA9B,EA6LqB,OAAAF,GAAUE,EAAAc,EAAG,KAAK,UAAR,KAAAd,EAAoB,MAAMc,EAAG,KAAK,QAAO,CAAG,GACvE,GAAI,CAACiB,EAAeC,IAClBlB,EAAG,GAAGiB,EAAiBE,GAAMD,EAAGD,IAAU,eAAiBjC,EAAUmC,CAAC,EAAIA,CAAC,CAAC,EAC9E,IAAK,CAACF,EAAeC,IAAgClB,EAAG,IAAIiB,EAAgBC,CAAE,EAC9E,QAAS,MAAOf,EAAsBiB,EAAkBhB,IAAwB,CAC9E,GAAM,CAAE,WAAAiB,EAAY,aAAcR,CAAG,EAAKX,EAAQC,EAAcC,CAAY,EAC5E,OAAOpB,EAAU,MAAMgB,EAAG,KAAK,IAAI,CAAE,kBAAmBa,EAAK,WAAAQ,EAAY,aAAAlB,EAAc,SAAAiB,CAAQ,CAAE,CAAC,CACpG,EACA,SAAU,MAAOhC,GAAkF,CACjG,IAAIkC,EAAgBtB,EAAG,KAAK,QAC5B,QAAWR,KAAMJ,EAAOkC,EAAO,MAAMN,EAAY,QAAQxB,EAAG,aAAcA,EAAG,SAAUA,EAAG,YAAY,EACtG,OAAO8B,CACT,EACA,WAAY,MAAOC,GAAmBvC,EAAU,MAAMgB,EAAG,KAAK,OAAOuB,CAAM,CAAC,EAC5E,QAAS,MAAOC,EAAgBrB,EAAsBC,IAAwB,CAC5E,GAAM,CAAE,WAAAiB,EAAY,aAAcR,CAAG,EAAKX,EAAQC,EAAcC,CAAY,EAC5E,OAAOpB,EACL,MAAMgB,EAAG,KAAK,IAAI,CAAE,kBAAmBa,EAAK,WAAAQ,EAAY,aAAAlB,EAAc,mBAAoB,CAACqB,CAAM,CAAC,CAAE,CAAC,CAEzG,EACA,WAAY,MAAOC,EAAiBC,IAAyB,CAjNjE,IAAAxC,EAqNM,eAAQ,KAAK,wFAAwF,EAC9FF,GAAWE,EAAA,MAAMc,EAAG,KAAK,QAAO,IAArB,KAAAd,EAA4Bc,EAAG,KAAK,OAAO,CAC/D,GAGI2B,EAAgB,CACpB,KAAM,IAAM3B,EAAG,OAAO,KAAI,EAC1B,IAAM4B,GAAoB5B,EAAG,OAAO,IAAI4B,CAAO,EAC/C,UAAW,CAACA,EAAiBC,IAAmB7B,EAAG,OAAO,UAAU4B,EAASC,CAAM,GAK/EC,EAAc,CAClB,IAAI,UAAQ,CACV,OAAO9B,EAAG,KAAK,QACjB,EACA,IAAI,eAAa,CACf,OAAOA,EAAG,KAAK,aACjB,EACA,iBAAmB+B,GAAgD/B,EAAG,KAAK,iBAAiB+B,CAAO,EACnG,SAAWC,GAAiBhC,EAAG,KAAK,SAASgC,CAAI,EACjD,OAAQ,IAAMhC,EAAG,KAAK,OAAM,GAGxBiC,EAAiB,CACrB,OAASD,GAAiBhC,EAAG,QAAQ,OAAOgC,CAAI,GAGlD,MAAO,CACL,iBAAkB,IAAM1B,EACxB,eAAgB,IAAMU,EACtB,iBAAkB,IAAMW,EACxB,eAAgB,IAAMG,EACtB,kBAAmB,IAAMG,EACzB,GAAI,CAAChB,EAAeC,IAAgClB,EAAG,GAAGiB,EAAgBC,CAAE,EAC5E,IAAK,CAACD,EAAeC,IAAgClB,EAAG,IAAIiB,EAAgBC,CAAE,EAC9E,MAAQR,IAAqB,CAC3B,UAAW,CAACH,EAAwB,CAAA,IAAOP,EAAG,KAAK,2BAA4B,CAAE,QAAAU,EAAS,GAAGH,CAAO,CAAE,IAExG,SAAU,CACR,UAAW,CAACA,EAAwB,CAAA,IAAOP,EAAG,KAAK,wBAAyBO,CAAO,EACnF,WAAY,IAAMP,EAAG,KAAK,0BAA0B,GAEtD,WAAY,IAAMA,EAAG,KAAK,0BAA0B,EAExD,CCjQM,IAAOkC,EAAP,KAAc,CAApB,aAAA,CACU,KAAA,SAAW,IAAI,GAsBzB,CAnBE,GAAGC,EAAkBC,EAAgB,CACnC,OAAK,KAAK,SAAS,IAAID,CAAK,GAAG,KAAK,SAAS,IAAIA,EAAO,IAAI,GAAK,EACjE,KAAK,SAAS,IAAIA,CAAK,EAAG,IAAIC,CAAO,EAC9B,IAAM,KAAK,IAAID,EAAOC,CAAO,CACtC,CAEA,IAAID,EAAkBC,EAAgB,CAVxC,IAAAC,GAWIA,EAAA,KAAK,SAAS,IAAIF,CAAK,IAAvB,MAAAE,EAA0B,OAAOD,EACnC,CAEA,KAAKD,EAAkBG,EAAiB,CAd1C,IAAAD,GAeIA,EAAA,KAAK,SAAS,IAAIF,CAAK,IAAvB,MAAAE,EAA0B,QAASE,GAAK,CACtC,GAAI,CACFA,EAAED,CAAO,CACX,OAASE,EAAK,CACZ,QAAQ,MAAM,sBAAsBL,CAAK,SAAUK,CAAG,CACxD,CACF,EACF,GC9BF,IAAMC,GAAW,gBAIX,SAAUC,GAAWC,EAAuC,CAChE,GAAI,CAACA,GAAS,OAAO,UAAa,YAAa,OAE/C,IAAMC,EAAO,OAAO,QAAQC,EAAeF,CAAK,CAAC,EAAE,IAAI,CAAC,CAACG,EAAMC,CAAK,IAAM,GAAGD,CAAI,KAAKC,CAAK,GAAG,EAE1FC,EAAQ,SAAS,eAAeP,EAAQ,EACvCO,IACHA,EAAQ,SAAS,cAAc,OAAO,EACtCA,EAAM,GAAKP,GACX,SAAS,KAAK,YAAYO,CAAK,GAEjCA,EAAM,YAAc;IAAcJ,EAAK,KAAK;GAAM,CAAC;EACrD,CCkBA,IAAMK,EAAQ,CAAIC,EAAcC,IAC1BD,GAAO,OAAOA,GAAQ,UAAY,CAAC,MAAM,QAAQA,CAAG,GAAKC,KAAOD,EAC1DA,EAAgCC,CAAG,EAEtCD,EAGIE,EAAP,KAAsB,CAoD1B,YACEC,EACAC,EAAoG,CAlD9F,KAAA,QAAU,IAAIC,EAQd,KAAA,gBAAkB,GAClB,KAAA,iBAAyC,KAEzC,KAAA,SAAyB,CAAE,UAAW,KAAM,SAAU,KAAM,cAAe,EAAK,EAChF,KAAA,MAAwB,KACxB,KAAA,QAAyB,KAuC/B,KAAK,OAASF,EACd,KAAK,YAAcC,EAAK,YACxB,KAAK,eAAiBA,EAAK,eAC3B,KAAK,OAASA,EAAK,OACnB,KAAK,QAAUA,EAAK,QAAQ,QAAQ,MAAO,EAAE,EAE7C,IAAME,EAAO,KAEb,KAAK,OAAS,CACZ,KAAM,IAAMA,EAAK,OAAO,cAAc,KAAI,EAC1C,IAAMC,GAAYD,EAAK,OAAO,MAAM,IAAIC,CAAO,EAAE,KAAMC,GAAMT,EAAMS,EAAG,OAAO,CAAC,GAGhF,KAAK,MAAQ,CACX,IAAK,IAAMF,EAAK,OAAO,MAAM,SAAQ,EAAG,KAAME,GAAMT,EAAMS,EAAG,OAAO,CAAC,EACrE,MAAO,SAAW,CAChB,IAAMC,EAAQ,MAAMH,EAAK,MAAM,IAAG,EAClC,OAAAI,GAAWD,CAAc,EAClBA,CACT,GAGF,KAAK,KAAO,CACV,IAAI,SAAO,CACT,OAAOH,EAAK,KACd,EACA,IAAI,IAAE,CACJ,OAAOA,EAAK,OACd,EACA,OAAQ,SAAW,CAhJzB,IAAAK,EAiJQ,GAAI,CAACL,EAAK,QAAS,CAEjB,MAAMA,EAAK,cAAa,EACxB,IAAMM,EAAM,MAAMN,EAAK,OAAO,WAAW,OAAO,CAAA,CAAE,EAC5CO,EAAOd,EAAsBa,EAAK,MAAM,EAC9CN,EAAK,SAAUK,EAAAE,GAAA,YAAAA,EAAM,KAAN,KAAAF,EAAY,KAC3BL,EAAK,SAASO,CAAI,CACpB,CACA,OAAOP,EAAK,OACd,EACA,IAAK,MAAOQ,GAAQ,CAClB,IAAMC,EAAK,MAAMT,EAAK,KAAK,OAAM,EACjC,GAAI,CACF,IAAMM,EAAM,MAAMN,EAAK,OAAO,WAAW,QAAQS,EAAID,CAAI,EACzD,OAAAR,EAAK,SAASP,EAAMa,EAAK,MAAM,CAAC,EACzBN,EAAK,KACd,OAASU,EAAK,CACZ,GAAI,CAACV,EAAK,YAAYU,CAAG,EAAG,MAAMA,EAGlCV,EAAK,WAAU,EACf,IAAMW,EAAU,MAAMX,EAAK,KAAK,OAAM,EAChCM,EAAM,MAAMN,EAAK,OAAO,WAAW,QAAQW,EAASH,CAAI,EAC9D,OAAAR,EAAK,SAASP,EAAMa,EAAK,MAAM,CAAC,EACzBN,EAAK,KACd,CACF,EACA,OAAQ,MAAOY,GAAU,CACvB,GAAI,CAACZ,EAAK,QAAS,OAAOA,EAAK,MAC/B,GAAI,CACF,IAAMM,EAAM,MAAMN,EAAK,OAAO,WAAW,WAAWA,EAAK,QAASY,CAAM,EACxE,OAAAZ,EAAK,SAASP,EAAMa,EAAK,MAAM,CAAC,EACzBN,EAAK,KACd,OAASU,EAAK,CACZ,GAAI,CAACV,EAAK,YAAYU,CAAG,EAAG,MAAMA,EAGlC,OAAAV,EAAK,WAAU,EACRA,EAAK,KACd,CACF,EACA,QAAS,SAAW,CAClB,GAAI,CAACA,EAAK,QAAS,OAAOA,EAAK,MAC/B,GAAI,CACF,IAAMM,EAAM,MAAMN,EAAK,OAAO,WAAW,IAAIA,EAAK,OAAO,EACzD,OAAAA,EAAK,SAASP,EAAMa,EAAK,MAAM,CAAC,EACzBN,EAAK,KACd,OAASU,EAAK,CACZ,GAAI,CAACV,EAAK,YAAYU,CAAG,EAAG,MAAMA,EAGlC,OAAAV,EAAK,WAAU,EACRA,EAAK,KACd,CACF,EACA,SAAU,MAAOF,EAAO,CAAA,IAAM,CAC5B,GAAI,CAACE,EAAK,QAAS,MAAM,IAAI,MAAM,sBAAsB,EACzD,GAAI,CACF,IAAMM,EAAM,MAAMN,EAAK,OAAO,WAAW,SAASA,EAAK,QAASF,CAAa,EAC7E,OAAAE,EAAK,QAAU,KACfA,EAAK,SAAS,IAAI,EAClBA,EAAK,QAAQ,KAAK,qBAAsBP,EAAMa,EAAK,OAAO,CAAC,EACpDA,CACT,OAASI,EAAK,CACZ,MAAKV,EAAK,YAAYU,CAAG,GAGzBV,EAAK,WAAU,EACT,IAAIa,EACR,wDACA,eACA,GAAG,GAP6BH,CASpC,CACF,GAGF,KAAK,KAAO,CACV,IAAI,UAAQ,CACV,OAAOV,EAAK,SAAS,QACvB,EACA,IAAI,eAAa,CACf,OAAOA,EAAK,SAAS,aACvB,EACA,iBAAmBc,GAAYd,EAAK,OAAO,kBAAkB,UAAUc,CAAO,EAC9E,SAAU,MAAOC,GAAS,CAtOhC,IAAAV,EAwOQ,MAAML,EAAK,cAAa,EACxB,IAAMgB,EAAO,OAAOD,GAAU,SAAW,CAAE,KAAM,aAAc,KAAMA,CAAK,EAAKA,EACzET,EAAM,MAAMN,EAAK,OAAO,oBAAoB,OAAO,CAAE,MAAOgB,CAAI,CAAE,EACxE,OAAAhB,EAAK,SAAW,CACd,GAAGA,EAAK,SACR,UAAUK,EAAAZ,EAAMa,EAAK,UAAU,IAArB,KAAAD,EAA0B,KACpC,cAAe,IAEjBL,EAAK,QAAQ,KAAK,eAAgBA,EAAK,QAAQ,EACxCM,CACT,EACA,OAAQ,SAAW,CACjB,MAAMN,EAAK,OAAO,QAAQ,IAAG,EAAG,MAAM,IAAG,EAAY,EACrDA,EAAK,SAAW,CAAE,UAAWA,EAAK,SAAS,UAAW,SAAU,KAAM,cAAe,EAAK,EAC1FA,EAAK,MAAQ,KACbA,EAAK,QAAU,KACfA,EAAK,QAAQ,KAAK,eAAgBA,EAAK,QAAQ,CACjD,GAGF,KAAK,OAAS,CACZ,KAAM,IAAMA,EAAK,OAAO,cAAc,KAAI,EAAG,KAAME,GAAMT,EAAMS,EAAG,QAAQ,CAAC,EAC3E,IAAMe,GAAYjB,EAAK,OAAO,YAAY,IAAIiB,CAAO,EAAE,KAAMf,GAAMT,EAAMS,EAAG,OAAO,CAAC,EAGpF,UAAW,MAAOe,EAASC,IAAU,CACnC,IAAMC,EAAkC,CAAA,EAExC,GADInB,EAAK,iBAAgBmB,EAAQ,cAAmB,UAAUnB,EAAK,cAAc,IAC7EA,EAAK,cAAgB,QAAS,CAChC,IAAMoB,EAAQ,MAAMpB,EAAK,OAAO,gBAAe,EAC3CoB,IAAOD,EAAQ,gBAAgB,EAAIC,EACzC,CACA,IAAMd,EAAM,MAAM,MAChB,GAAGN,EAAK,OAAO,iBAAiBiB,CAAO,WAAWC,CAAM,cACxD,CAAE,QAAAC,EAAS,YAAanB,EAAK,cAAgB,SAAW,UAAY,aAAa,CAAE,EAErF,GAAI,CAACM,EAAI,GAAI,MAAM,IAAIO,EAAa,8BAA8BP,EAAI,MAAM,IAAK,oBAAqBA,EAAI,MAAM,EAChH,OAAOA,EAAI,KAAI,CACjB,GAGF,KAAK,SAAW,CACd,MAAO,CAACW,EAASnB,EAAO,CAAA,IACtBE,EAAK,OAAO,mBAAmB,OAAOiB,EAASnB,CAAa,EAAE,KAAMI,GAAMT,EAAMS,EAAG,SAAS,CAAC,GAGjG,KAAK,QAAU,CAKb,OAAQ,MAAOmB,GAAQ,CACrB,IAAMf,EAAO,MAAMN,EAAK,OAAO,kBAAkB,OAAO,CAAE,KAAMqB,EAAK,KAAI,CAAE,CAAE,EAC7E,OAAIrB,EAAK,SAAS,MAAMA,EAAK,KAAK,QAAO,EAAG,MAAM,IAAG,EAAY,EAC1DM,CACT,GAGF,KAAK,MAAQ,CACX,OAAQ,IAAMN,EAAK,OAAO,MAAM,OAAM,EACtC,KAAM,IAAMA,EAAK,OAAO,MAAM,KAAI,EAEtC,CAGA,GAAGsB,EAAkBC,EAAoC,CACvD,OAAO,KAAK,QAAQ,GAAGD,EAAOC,CAAO,CACvC,CACA,IAAID,EAAkBC,EAAoC,CACxD,KAAK,QAAQ,IAAID,EAAOC,CAAO,CACjC,CAMA,KAAKD,EAAkBE,EAAiB,CACtC,KAAK,QAAQ,KAAKF,EAAOE,CAAO,CAClC,CAEA,IAAI,SAAO,CACT,OAAO,KAAK,QACd,CAGA,IAAI,YAAU,CACZ,OAAO,KAAK,eACd,CAQA,MAAM,eAAa,CACjB,GAAI,MAAK,gBACT,IAAI,KAAK,iBAAkB,OAAO,KAAK,iBAEvC,KAAK,kBAAoB,SAAW,CAGlC,IAAMC,EAAoC,CAAA,EACtC,KAAK,cAAgB,SAAW,KAAK,eACvCA,EAAU,WAAa,KAAK,eACnB,KAAK,OACdA,EAAU,OAAS,KAAK,OACf,KAAK,iBACdA,EAAU,WAAa,KAAK,gBAG9B,IAAMC,EAAU,MAAM,KAAK,OAAO,QAAQ,MAAMD,CAAkB,EAClE,GAAI,KAAK,cAAgB,QAAS,CAChC,IAAML,EAAQ3B,EAAciC,EAAS,cAAc,EAC/CN,GAAO,MAAM,KAAK,OAAO,gBAAgBA,CAAK,CACpD,CACA,KAAK,gBAAkB,GACvB,MAAM,KAAK,eAAc,CAC3B,GAAE,EAEF,GAAI,CACF,MAAM,KAAK,gBACb,SACE,KAAK,iBAAmB,IAC1B,EACF,CAGA,MAAM,MAAMtB,EAA4B,CAAA,EAAE,CACxC,OAAIA,EAAK,SAAQ,KAAK,OAASA,EAAK,QAC7B,KAAK,cAAa,CAC3B,CAeA,MAAM,gBAAc,CAClB,GAAI,KAAK,gBAAiB,MAAO,GACjC,GAAI,CACF,aAAM,KAAK,eAAc,EACzB,KAAK,gBAAkB,GAChB,EACT,MAAQ,CAEN,MAAO,EACT,CACF,CAOA,MAAM,OAAOsB,EAAa,CACxB,MAAM,KAAK,OAAO,gBAAgBA,CAAK,EACvC,KAAK,gBAAkB,GACvB,MAAM,KAAK,eAAc,CAC3B,CAGA,iBAAe,CACb,OAAO,KAAK,OAAO,gBAAe,CACpC,CAGA,MAAM,gBAAc,CAvZtB,IAAAf,EAAAsB,EAAAC,EAAAC,EAwZI,IAAMC,EAAM,MAAM,KAAK,OAAO,QAAQ,QAAO,EAC7C,KAAK,SAAW,CACd,WAAWH,GAAAtB,EAAAZ,EAAsBqC,EAAK,SAAS,IAApC,YAAAzB,EAAuC,KAAvC,KAAAsB,EAA6C,KACxD,UAAUC,EAAAnC,EAAMqC,EAAK,UAAU,IAArB,KAAAF,EAA0B,KACpC,cAAe,CAAC,CAACnC,EAAeqC,EAAK,eAAe,GAEtD,IAAMC,GAASF,EAAApC,EAAcqC,EAAK,QAAQ,IAA3B,KAAAD,EAAgC,KAC3CE,IACF,KAAK,QAAUA,EACf,MAAM,KAAK,KAAK,QAAO,GAEzB,KAAK,QAAQ,KAAK,kBAAmB,KAAK,QAAQ,CACpD,CAOU,sBAAoB,CAC5B,KAAK,gBAAkB,GACvB,KAAK,iBAAmB,IAC1B,CAEQ,SAASxB,EAAa,CAC5B,KAAK,MAAQA,GAAA,KAAAA,EAAQ,KACrB,KAAK,QAAQ,KAAK,eAAgB,KAAK,KAAK,CAC9C,CASQ,YAAYG,EAAY,CAC9B,OAAMA,aAAeG,EAEnBH,EAAI,OAAS,gBACbA,EAAI,OAAS,mBACbA,EAAI,OAAS,kBACbA,EAAI,SAAW,IAL0B,EAO7C,CAGQ,YAAU,CAChB,KAAK,QAAU,KACf,KAAK,SAAS,IAAI,CACpB,GCpZF,eAAesB,GAAkBC,EAAiBC,EAAc,CAtDhE,IAAAC,EAuDE,GAAI,CACF,IAAMC,EAAM,MAAM,MAChB,GAAGH,EAAQ,QAAQ,MAAO,EAAE,CAAC,mBAAmB,mBAAmBC,CAAM,CAAC,GAC1E,CAAE,QAAS,CAAE,OAAQ,kBAAkB,CAAE,CAAE,EAE7C,GAAI,CAACE,EAAI,GAAI,OACb,IAAMC,EAAQ,MAAMD,EAAI,KAAI,EAC5B,OAAOD,EAAAE,GAAA,YAAAA,EAAM,OAAN,YAAAF,EAAY,cACrB,MAAQ,CACN,MACF,CACF,CAEA,eAAsBG,EAAiBC,EAAgC,CApEvE,IAAAJ,EAAAK,EAAAC,EAqEE,IAAMP,GACJC,EAAAI,EAAQ,SAAR,KAAAJ,EAAmB,OAAO,QAAW,YAAc,OAAO,SAAS,KAAO,OAMxEO,EAAiBH,EAAQ,eACzB,CAACG,GAAkB,CAACH,EAAQ,cAAgBL,IAC9CQ,EAAiB,MAAMV,GAAkBO,EAAQ,QAASL,CAAM,GAKlE,IAAMS,EAAU,CAAC,CAACJ,EAAQ,gBAAkB,CAAC,CAACA,EAAQ,aAChDK,GAAcJ,EAAAD,EAAQ,cAAR,KAAAC,EAAwBG,EAAU,QAAU,SAC1DE,EAAS,IAAIC,EAAW,CAC5B,GAAGP,EACH,YAAAK,EACA,GAAIF,EAAiB,CAAE,eAAAA,CAAc,EAAK,CAAA,EAC3C,EACKK,EAAK,IAAIC,EAAgBH,EAAQ,CACrC,YAAAD,EACA,QAASL,EAAQ,QACjB,GAAIG,EAAiB,CAAE,eAAAA,CAAc,EAAK,CAAA,EAC1C,GAAIR,EAAS,CAAE,OAAAA,CAAM,EAAK,CAAA,EAC3B,EAGGK,EAAQ,UAAY,IAAS,OAAO,QAAW,aACjDU,EAAcF,EAAIG,GAAwBH,CAAE,EAAGI,CAAiB,IAI9DV,EAAAF,EAAQ,WAAR,YAAAE,EAAkB,QAAS,SAAW,OAAO,QAAW,aAC1DW,EAAqBL,EAAIR,EAAQ,QAAQ,EAMvCA,EAAQ,WAAa,IAASA,EAAQ,UAAY,IAAS,OAAO,QAAW,aAC/Ec,GAAgBN,CAAE,EAUpB,IAAMO,EAAeC,EAAahB,CAAO,EAAE,MAAOiB,GAAO,CACvD,QAAQ,MAAM,mCAAoCA,CAAG,CACvD,CAAC,EAED,OAAIjB,EAAQ,YAAc,KAGpBA,EAAQ,aACV,MAAMQ,EAAG,OAAOR,EAAQ,YAAY,EAC3BK,IAAgB,UAAY,OAAO,QAAW,aAIvD,MAAMG,EAAG,eAAc,EAAG,MAAM,IAAG,EAAY,EAE7CR,EAAQ,aAAe,IAAS,OAAO,QAAW,aACpD,MAAMQ,EAAG,MAAM,MAAK,EAAG,MAAM,IAAG,EAAY,GAIhD,MAAMO,EACCP,CACT,CdlGA,SAASU,IAAU,CA7CnB,IAAAC,EA8CE,GAAI,OAAO,UAAa,YAAa,OAAO,KAC5C,IAAMC,GACHD,EAAA,SAAS,gBAAT,KAAAA,EACD,SAAS,cAAiC,8BAA8B,EAC1E,GAAI,CAACC,EAAI,OAAO,KAChB,IAAMC,EAAID,EAAG,QACb,MAAO,CACL,eAAgBC,EAAE,eAClB,OAAQA,EAAE,OACV,YAAaA,EAAE,YACf,kBAAmBA,EAAE,kBACrB,aAAcA,EAAE,aAEhB,aAAcA,EAAE,WAAa,QAEjC,CAOM,SAAUC,IAAI,CApEpB,IAAAH,EAAAI,EAqEE,GAAI,OAAO,QAAW,YAAa,OAAO,QAAQ,QAAQ,IAAI,EAC9D,IAAMC,EAAI,OACV,GAAIA,EAAE,WAAY,OAAOD,GAAAJ,EAAAK,EAAE,cAAF,YAAAL,EAAe,QAAf,KAAAI,EAAwB,QAAQ,QAAQ,IAAI,EAErE,IAAME,EAAMP,GAAU,EACtB,GAAI,EAACO,GAAA,MAAAA,EAAK,gBAAgB,OAAO,QAAQ,QAAQ,IAAI,EACrD,GAAI,CAACA,EAAI,OACP,eAAQ,MAAM,2EAA2E,EAClF,QAAQ,QAAQ,IAAI,EAG7BD,EAAE,WAAa,GACf,IAAME,EAAQC,EAAiB,CAC7B,QAASF,EAAI,OACb,eAAgBA,EAAI,eACpB,SAAUA,EAAI,aACd,GAAIA,EAAI,YAAc,CAAE,YAAaA,EAAI,WAAW,EAAK,CAAA,EACzD,GAAIA,EAAI,kBAAoB,CAAE,kBAAmBA,EAAI,iBAAiB,EAAK,CAAA,EAC3E,SAAU,CAAE,KAAM,QAAS,GAAIA,EAAI,aAAe,CAAE,aAAcA,EAAI,YAAY,EAAK,CAAA,CAAG,EAC3F,EAAE,MAAOG,IACR,QAAQ,MAAM,sCAAuCA,CAAG,EACjD,KACR,EAED,OAAAJ,EAAE,YAAc,CAAE,MAAAE,CAAK,EAChBA,CACT,CAMKG,GAAI",
6
6
  "names": ["auto_exports", "__export", "TicketlayerLive", "boot", "createLiveClient", "SDK_NAME", "SDK_VERSION", "API_DATED_VERSION", "describeRuntime", "_a", "_b", "_c", "g", "SDK_CLIENT_HEADER", "SDK_NAME", "SDK_VERSION", "memoryTokenStorage", "token", "t", "LiveAPIError", "message", "code", "status", "LiveClient", "config", "_d", "request", "cartId", "itemId", "orderId", "passId", "customerId", "options", "params", "queryString", "requestPath", "eventId", "path", "url", "headers", "response", "text", "json", "error", "TICKETLAYER_GLOBAL_KEY", "TICKETLAYER_READY_EVENT", "ensureRegistry", "version", "w", "reg", "resolve", "publishClient", "client", "sdk", "resolvers", "r", "DEFAULT_ELEMENTS_URL", "SENTINEL_TAG", "inFlight", "PINNED_PATH", "INTEGRITY", "ElementsIntegrityError", "message", "warnedAboutDefault", "loadElements", "opts", "_a", "_b", "integrity", "ce", "url", "existing", "p", "resolve", "reject", "script", "TOKEN_ALIASES", "TOKEN_DEFAULTS", "TOKEN_THEME_KEYS", "cssVar", "name", "themeToCssVars", "theme", "_a", "vars", "token", "themeKey", "TOKEN_THEME_KEYS", "section", "key", "value", "cssVar", "alias", "TOKEN_ALIASES", "OVERLAY_ID", "installCheckoutModal", "tl", "opts", "onMessage", "close", "_a", "open", "intent", "token", "base", "query", "url", "frameOrigin", "overlay", "wrapper", "frame", "TOKEN_DEFAULTS", "e", "_b", "_c", "msg", "legacy", "order", "err", "offCheckout", "p", "offClose", "installBuyModal", "tl", "opts", "TAG", "el", "current", "remove", "open", "intent", "node", "_a", "i", "e", "_b", "message", "offOpen", "p", "offClose", "bag", "v", "minorUnits", "value", "lineType", "line", "isTicketLine", "expressesFee", "fees", "named", "deriveCartTotals", "cart", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "c", "lines", "subtotal", "sum", "feeLines", "feeLineTotal", "labelled", "namedLine", "n", "feeLabel", "discountLines", "discountLineTotal", "discount", "tax", "serverTotal", "total", "withCount", "cart", "_a", "c", "items", "i", "_b", "_c", "it", "qty", "line", "itemCount", "sum", "totals", "deriveCartTotals", "createElementsConnector", "tl", "ttMeta", "resolve", "ticketTypeId", "occurrenceId", "meta", "eventsManager", "options", "res", "l", "eventId", "_d", "ev", "occ", "o", "tt", "cartManager", "event", "cb", "p", "quantity", "categoryId", "last", "itemId", "seatId", "_seatId", "_occurrenceId", "ordersManager", "orderId", "passId", "authManager", "contact", "code", "presaleManager", "Emitter", "event", "handler", "_a", "payload", "h", "err", "STYLE_ID", "applyTheme", "theme", "vars", "themeToCssVars", "name", "value", "style", "field", "obj", "key", "TicketlayerLive", "client", "opts", "Emitter", "self", "eventId", "d", "theme", "applyTheme", "_a", "res", "cart", "item", "id", "err", "freshId", "itemId", "LiveAPIError", "contact", "proof", "body", "orderId", "passId", "headers", "token", "code", "event", "handler", "payload", "startBody", "started", "_b", "_c", "_d", "cur", "cartId", "resolveChannelKey", "baseUrl", "domain", "_a", "res", "json", "createLiveClient", "options", "_b", "_c", "publishableKey", "isEmbed", "sessionMode", "client", "LiveClient", "tl", "TicketlayerLive", "publishClient", "createElementsConnector", "API_DATED_VERSION", "installCheckoutModal", "installBuyModal", "elementsLoad", "loadElements", "err", "readConfig", "_a", "el", "d", "boot", "_b", "w", "cfg", "ready", "createLiveClient", "err", "boot"]
7
7
  }
package/dist/version.d.ts CHANGED
@@ -3,5 +3,5 @@
3
3
  * Do not edit; do not commit.
4
4
  */
5
5
  export declare const SDK_NAME = "@ticketlayer/live";
6
- export declare const SDK_VERSION = "0.4.0";
6
+ export declare const SDK_VERSION = "1.0.0";
7
7
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -3,5 +3,5 @@
3
3
  * Do not edit; do not commit.
4
4
  */
5
5
  export const SDK_NAME = "@ticketlayer/live";
6
- export const SDK_VERSION = "0.4.0";
6
+ export const SDK_VERSION = "1.0.0";
7
7
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ticketlayer/live",
3
- "version": "0.4.0",
3
+ "version": "1.0.0",
4
4
  "description": "Ticketlayer Live SDK - buyer-facing client (browser + React Native)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -57,7 +57,7 @@
57
57
  "generator": "backstage-sdk-tooling 0.1.0"
58
58
  },
59
59
  "dependencies": {
60
- "@ticketlayer/theme": "^0.1.0"
60
+ "@ticketlayer/theme": "^0.2.0"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@types/node": "^22.15.30",