@seatlayer/js 0.50.1 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +371 -251
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +371 -251
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2659,6 +2659,10 @@ var DEFAULT_MAX_SELECTION2 = 10;
|
|
|
2659
2659
|
var EXTEND_PROMPT_MS = 6e4;
|
|
2660
2660
|
var MAX_3D_SEATS_DEFAULT = 6e4;
|
|
2661
2661
|
var MAX_3D_SECTION_PILLS = 12;
|
|
2662
|
+
function tfStatic(key, fallback) {
|
|
2663
|
+
const v = (0, import_core2.t)(key);
|
|
2664
|
+
return v === key ? fallback : v;
|
|
2665
|
+
}
|
|
2662
2666
|
function pointInPolygon(x, y, poly) {
|
|
2663
2667
|
let inside = false;
|
|
2664
2668
|
for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
|
|
@@ -2833,11 +2837,30 @@ var CSS2 = (
|
|
|
2833
2837
|
.sl-picker[data-layout="narrow"] .sl-map{min-height:0;flex:1}
|
|
2834
2838
|
.sl-picker[data-layout="narrow"] .sl-side{width:100%;border-left:0;border-top:1px solid var(--sl-line);
|
|
2835
2839
|
flex:none;height:min(72%,480px);overflow:hidden;transition:height .3s cubic-bezier(.2,.8,.2,1);overscroll-behavior:contain}
|
|
2836
|
-
.sl-picker[data-layout="narrow"][data-sheet="open"][data-has-selection="false"] .sl-side{height:min(
|
|
2840
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"][data-has-selection="false"] .sl-side{height:min(380px,64%)}
|
|
2841
|
+
/* With the price list expanded the sheet takes the with-selection height so
|
|
2842
|
+
the tray (cart + best-seats) is never crushed under the fixed-size list. */
|
|
2843
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"][data-prices-open="true"] .sl-side{height:min(480px,74%)}
|
|
2837
2844
|
.sl-picker[data-layout="narrow"][data-sheet="peek"] .sl-side{height:76px;overflow:hidden}
|
|
2838
2845
|
.sl-picker[data-layout="narrow"][data-sheet="peek"] .sl-side > :not(.sl-sheet-head){display:none}
|
|
2839
|
-
.sl-picker[data-layout="narrow"] .sl-tray{flex:1;min-height:
|
|
2846
|
+
.sl-picker[data-layout="narrow"] .sl-tray{flex:1;min-height:96px;overflow-y:auto;overscroll-behavior:contain}
|
|
2847
|
+
.sl-picker[data-layout="narrow"][data-prices-open="true"] .sl-tray{min-height:48px}
|
|
2848
|
+
.sl-picker[data-layout="narrow"] .sl-prices{max-height:150px;overflow-y:auto;overscroll-behavior:contain}
|
|
2840
2849
|
.sl-picker[data-layout="narrow"] .sl-foot{position:static;background:var(--sl-bg)}
|
|
2850
|
+
/* NARROW FOOT SAYS EVERYTHING ONCE (owner report: with a hold the footer ate
|
|
2851
|
+
~190px and the ticket list got a sliver). The sheet head already carries
|
|
2852
|
+
"N tickets \xB7 $total" and the header pill already ticks the clock \u2014 so the
|
|
2853
|
+
total row hides, the secured note collapses to one compact line, and the
|
|
2854
|
+
badge tucks in. The tray gets the pixels; a thin scrollbar shows there is
|
|
2855
|
+
more to scroll. */
|
|
2856
|
+
.sl-picker[data-layout="narrow"] .sl-total{display:none}
|
|
2857
|
+
.sl-picker[data-layout="narrow"] .sl-foot{padding:8px 12px 8px}
|
|
2858
|
+
.sl-picker[data-layout="narrow"] .sl-hold-note{margin-bottom:6px;padding:5px 9px}
|
|
2859
|
+
.sl-picker[data-layout="narrow"] .sl-hold-note svg{display:none}
|
|
2860
|
+
.sl-picker[data-layout="narrow"] .sl-hold-note b{display:inline;margin-right:6px;font-size:11px}
|
|
2861
|
+
.sl-picker[data-layout="narrow"] .sl-hold-copy{display:inline;white-space:normal;font-size:10.5px}
|
|
2862
|
+
.sl-picker[data-layout="narrow"] .sl-powered{margin-top:4px;padding:2px 8px;font-size:11px}
|
|
2863
|
+
.sl-picker[data-layout="narrow"] .sl-tray{scrollbar-width:thin}
|
|
2841
2864
|
.sl-picker[data-layout="narrow"] .sl-foot.empty{display:none}
|
|
2842
2865
|
.sl-picker[data-layout="narrow"] .sl-sheet-head{order:0}
|
|
2843
2866
|
.sl-picker[data-layout="narrow"] .sl-seats-sec{display:none}
|
|
@@ -2845,6 +2868,7 @@ var CSS2 = (
|
|
|
2845
2868
|
.sl-picker[data-layout="narrow"] .sl-filtersec{order:3}
|
|
2846
2869
|
.sl-picker[data-layout="narrow"] .sl-filters{order:4}
|
|
2847
2870
|
.sl-picker[data-layout="narrow"] .sl-prices-sec{order:5}
|
|
2871
|
+
.sl-picker[data-layout="narrow"] .sl-prices-hint{order:6}
|
|
2848
2872
|
.sl-picker[data-layout="narrow"] .sl-pricef{order:6}
|
|
2849
2873
|
.sl-picker[data-layout="narrow"] .sl-prices{order:7}
|
|
2850
2874
|
.sl-picker[data-layout="narrow"] .sl-foot{order:8}
|
|
@@ -2852,6 +2876,7 @@ var CSS2 = (
|
|
|
2852
2876
|
.sl-picker[data-layout="narrow"] .sl-filtersec,
|
|
2853
2877
|
.sl-picker[data-layout="narrow"] .sl-filters,
|
|
2854
2878
|
.sl-picker[data-layout="narrow"] .sl-prices-sec,
|
|
2879
|
+
.sl-picker[data-layout="narrow"] .sl-prices-hint,
|
|
2855
2880
|
.sl-picker[data-layout="narrow"] .sl-prices{display:none!important}
|
|
2856
2881
|
.sl-picker[data-layout="narrow"][data-has-selection="true"] .sl-filtersec,
|
|
2857
2882
|
.sl-picker[data-layout="narrow"][data-has-selection="true"] .sl-filters,
|
|
@@ -2869,7 +2894,13 @@ var CSS2 = (
|
|
|
2869
2894
|
head is the tap/swipe toggle target (min 44px), so it reads as one control. */
|
|
2870
2895
|
.sl-sheet-head{display:none;flex-direction:column;justify-content:center;padding:6px 12px 8px;min-height:56px;
|
|
2871
2896
|
cursor:pointer;touch-action:none;user-select:none;-webkit-user-select:none;flex:none}
|
|
2872
|
-
.sl-picker[data-layout="narrow"] .sl-sheet-head{display:flex;min-height:
|
|
2897
|
+
.sl-picker[data-layout="narrow"] .sl-sheet-head{display:flex;min-height:52px;padding:3px 10px 5px}
|
|
2898
|
+
/* OPEN sheet: the head is context, not controls \u2014 the pill it carries at peek
|
|
2899
|
+
("Best seats"/"Continue") duplicates the card and CTA right below it, and
|
|
2900
|
+
every saved pixel is tray room (owner call 2026-08-14). */
|
|
2901
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-sheet-head{min-height:42px}
|
|
2902
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-sheet-bar{min-height:32px}
|
|
2903
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-sheet-peek .go{display:none}
|
|
2873
2904
|
.sl-picker[data-layout="narrow"][data-sheet="peek"] .sl-sheet-head{height:100%}
|
|
2874
2905
|
.sl-sheet-grab{width:36px;height:4px;border-radius:999px;background:var(--sl-muted);opacity:.55;margin:1px auto 5px}
|
|
2875
2906
|
.sl-sheet-bar{display:flex;align-items:center;gap:8px;min-height:44px}
|
|
@@ -2910,9 +2941,19 @@ var CSS2 = (
|
|
|
2910
2941
|
sheet brings it back, exactly like the filters row above. The tray hint comes
|
|
2911
2942
|
back with it: the first-time buyer on a phone needs the instruction more than
|
|
2912
2943
|
the desktop buyer, not less. */
|
|
2913
|
-
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-prices-sec{display:flex!important}
|
|
2914
|
-
|
|
2944
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"][data-prices-open="true"] .sl-prices-sec{display:flex!important}
|
|
2945
|
+
/* MOBILE SPACE BELONGS TO THE CART (owner call 2026-08-14): the price list is
|
|
2946
|
+
one tap away behind the "Ticket prices" row, not a permanent tenant. Zone
|
|
2947
|
+
flags and section taps already answer "what does it cost" in context. */
|
|
2948
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"][data-prices-open="true"] .sl-prices-hint{display:block!important}
|
|
2949
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"][data-prices-open="true"] .sl-prices{display:flex!important}
|
|
2915
2950
|
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-tray-hint{display:block!important}
|
|
2951
|
+
/* The row reads as the toggle it is on narrow: chevron + pointer. */
|
|
2952
|
+
.sl-picker[data-layout="narrow"] .sl-prices-sec{cursor:pointer}
|
|
2953
|
+
.sl-picker[data-layout="narrow"] .sl-prices-sec::after{content:'';width:8px;height:8px;flex:none;margin-left:auto;
|
|
2954
|
+
border-right:2px solid var(--sl-muted);border-bottom:2px solid var(--sl-muted);
|
|
2955
|
+
transform:rotate(45deg);transition:transform .2s cubic-bezier(.2,.8,.2,1)}
|
|
2956
|
+
.sl-picker[data-layout="narrow"][data-prices-open="true"] .sl-prices-sec::after{transform:rotate(-135deg)}
|
|
2916
2957
|
.sl-cbbtn{width:32px;height:32px;border-radius:999px;background:var(--sl-surface);border:1px solid var(--sl-line);
|
|
2917
2958
|
color:var(--sl-text);display:flex;align-items:center;justify-content:center;transition:border-color .15s}
|
|
2918
2959
|
.sl-cbbtn:hover{border-color:var(--sl-muted)}
|
|
@@ -2931,7 +2972,13 @@ var CSS2 = (
|
|
|
2931
2972
|
.sl-sec{padding:14px 14px 4px;font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--sl-muted);font-weight:700}
|
|
2932
2973
|
.sl-prices-sec{display:flex;align-items:center;justify-content:space-between;gap:10px;padding-top:13px}
|
|
2933
2974
|
.sl-price-select{min-height:32px;max-width:130px;padding:5px 28px 5px 9px;border:1px solid var(--sl-line);border-radius:9px;
|
|
2934
|
-
background:var(--sl-surface);color:var(--sl-text);font:inherit;font-size:11px;font-weight:750;letter-spacing:0;text-transform:none}
|
|
2975
|
+
background-color:var(--sl-surface);color:var(--sl-text);font:inherit;font-size:11px;font-weight:750;letter-spacing:0;text-transform:none}
|
|
2976
|
+
/* One sentence that teaches the whole colour code \u2014 a first-time buyer sees
|
|
2977
|
+
"Head Tables \xB7 $165" and coloured dots with nothing connecting them. Gone
|
|
2978
|
+
the moment they have seats (they've learned it) and while sales are closed. */
|
|
2979
|
+
.sl-prices-hint{padding:0 14px 7px;font-size:11px;line-height:1.45;color:var(--sl-muted)}
|
|
2980
|
+
.sl-picker[data-has-selection="true"] .sl-prices-hint,
|
|
2981
|
+
.sl-picker[data-sales-closed="true"] .sl-prices-hint{display:none}
|
|
2935
2982
|
.sl-prices{display:flex;flex-direction:column;padding:4px 14px 8px;border-bottom:1px solid var(--sl-line)}
|
|
2936
2983
|
.sl-prices-sec,.sl-prices,.sl-seats-sec{flex:none}
|
|
2937
2984
|
.sl-price-row{display:flex;align-items:center;gap:7px;min-height:28px;font-size:12px;
|
|
@@ -3091,11 +3138,11 @@ var CSS2 = (
|
|
|
3091
3138
|
color:var(--sl-text);font-size:17px;font-weight:700;display:flex;align-items:center;justify-content:center;transition:border-color .15s}
|
|
3092
3139
|
.sl-zoom button:hover{border-color:var(--sl-muted)}
|
|
3093
3140
|
.sl-zoom svg{width:14px;height:14px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
3094
|
-
/* Full-screen promotion
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
region beside Map|3D
|
|
3098
|
-
|
|
3141
|
+
/* Full-screen promotion: the capability existed (native + iOS overlay +
|
|
3142
|
+
framed-host paths) but hid as the 4th unlabelled glyph in a corner stack \u2014
|
|
3143
|
+
even the owner could not pick it out. dockLayoutChrome docks the SAME
|
|
3144
|
+
button into the top-right region beside Map|3D on EVERY layout and this
|
|
3145
|
+
class dresses it as a labelled pill. */
|
|
3099
3146
|
.sl-zfs-lbl{display:none}
|
|
3100
3147
|
.sl-fs-pill.sl-fs-pill{display:inline-flex;align-items:center;justify-content:center;width:auto;min-height:40px;height:auto;
|
|
3101
3148
|
padding:0 13px;gap:6px;border-radius:999px;font-size:11px;font-weight:800;
|
|
@@ -3103,6 +3150,16 @@ var CSS2 = (
|
|
|
3103
3150
|
.sl-fs-pill.sl-fs-pill:hover{border-color:var(--sl-muted)}
|
|
3104
3151
|
.sl-fs-pill svg{width:14px;height:14px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
3105
3152
|
.sl-fs-pill .sl-zfs-lbl{display:inline;letter-spacing:.02em;white-space:nowrap}
|
|
3153
|
+
/* In the header, icons carry it (owner call): square Full screen glyph, and
|
|
3154
|
+
on narrow a price-tag toggle that opens the sheet with the list expanded. */
|
|
3155
|
+
.sl-head .sl-fs-pill{min-height:34px;min-width:34px;width:34px;padding:0;flex:none}
|
|
3156
|
+
.sl-head .sl-fs-pill .sl-zfs-lbl{display:none}
|
|
3157
|
+
.sl-prices-btn{display:none;align-items:center;justify-content:center;width:34px;min-height:34px;flex:none;
|
|
3158
|
+
border-radius:999px;background:var(--sl-surface);border:1px solid var(--sl-line);color:var(--sl-text);transition:border-color .15s}
|
|
3159
|
+
.sl-prices-btn:hover{border-color:var(--sl-muted)}
|
|
3160
|
+
.sl-prices-btn svg{width:15px;height:15px;stroke:currentColor;stroke-width:1.8;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
3161
|
+
.sl-prices-btn[aria-pressed="true"]{background:var(--sl-accent);color:var(--sl-accent-ink);border-color:transparent}
|
|
3162
|
+
.sl-picker[data-layout="narrow"] .sl-prices-btn{display:inline-flex}
|
|
3106
3163
|
|
|
3107
3164
|
/* toast + boot states (toast flows in the bottom-center region) */
|
|
3108
3165
|
.sl-toast{transform:translateY(6px) scale(.98);max-width:100%;
|
|
@@ -3230,8 +3287,21 @@ var CSS2 = (
|
|
|
3230
3287
|
.sl-confirm-add svg{width:16px;height:16px;stroke:currentColor;stroke-width:2.8;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
3231
3288
|
.sl-confirm-cancel{background:color-mix(in srgb,var(--sl-line) 44%,transparent)!important;border:1px solid var(--sl-line)!important;color:var(--sl-muted)!important}
|
|
3232
3289
|
.sl-confirm-cancel:hover{color:var(--sl-text)}
|
|
3233
|
-
.sl-picker[data-layout="narrow"] .sl-confirm{left:50%!important;top:auto!important;bottom:14px;width:min(
|
|
3290
|
+
.sl-picker[data-layout="narrow"] .sl-confirm{left:50%!important;top:auto!important;bottom:14px;width:min(310px,calc(100% - 24px));
|
|
3234
3291
|
transform:translateX(-50%);animation:slConfirmMobileIn .24s cubic-bezier(.2,.8,.2,1) both}
|
|
3292
|
+
/* Phone-size confirm card (owner call 2026-08-14): same content \u2014 identity,
|
|
3293
|
+
price band, view photo, 3D link \u2014 on a tighter grid. The values stay large
|
|
3294
|
+
enough to double-check against the map; buttons keep tap-size. */
|
|
3295
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-field{padding:9px 9px 8px}
|
|
3296
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-value{font-size:15px}
|
|
3297
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-cat{padding:8px 10px}
|
|
3298
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-cat-name{font-size:12.5px}
|
|
3299
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-price{font-size:15px}
|
|
3300
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-body{padding:9px 10px 10px}
|
|
3301
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-thumbwrap{height:62px;margin-bottom:6px}
|
|
3302
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-3d{margin-top:7px;padding:6px}
|
|
3303
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-row{margin-top:8px}
|
|
3304
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-row button{min-height:42px}
|
|
3235
3305
|
|
|
3236
3306
|
/* Atomic whole/variable-table chooser. Lives inside the widget so the same
|
|
3237
3307
|
accessible dialog works in inline, modal, desktop and 390px mobile hosts. */
|
|
@@ -3307,8 +3377,11 @@ var CSS2 = (
|
|
|
3307
3377
|
.sl-ba-premium.on{color:var(--sl-premium-ink);background:linear-gradient(135deg,#f0cf6b,#e0b23f);border-color:transparent;
|
|
3308
3378
|
box-shadow:0 6px 16px color-mix(in srgb,var(--sl-premium) 26%,transparent)}
|
|
3309
3379
|
.sl-ba-premium.on .star{color:#5a4410}
|
|
3310
|
-
.sl-ba select
|
|
3311
|
-
|
|
3380
|
+
.sl-ba select,.sl-price-select{appearance:none;-webkit-appearance:none;
|
|
3381
|
+
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23949ca9' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
3382
|
+
background-repeat:no-repeat;background-position:right 10px center}
|
|
3383
|
+
.sl-ba select{background-color:var(--sl-surface);color:var(--sl-text);border:1px solid var(--sl-line);border-radius:8px;
|
|
3384
|
+
font:inherit;font-size:11px;padding:7px 26px 7px 8px;min-width:0;width:100%;max-width:none}
|
|
3312
3385
|
.sl-ba-qty{display:flex;align-items:center;gap:7px;padding:3px;border:1px solid var(--sl-line);border-radius:9px;background:var(--sl-surface)}
|
|
3313
3386
|
.sl-ba-qty button{width:25px;height:25px;border-radius:7px;background:color-mix(in srgb,var(--sl-line) 35%,transparent);border:0;
|
|
3314
3387
|
font-size:14px;font-weight:800;display:flex;align-items:center;justify-content:center}
|
|
@@ -3338,9 +3411,23 @@ var CSS2 = (
|
|
|
3338
3411
|
.sl-picker[data-layout="narrow"] .sl-ba-copy{display:none}
|
|
3339
3412
|
.sl-picker[data-layout="narrow"] .sl-ba-copy .wide{display:none}
|
|
3340
3413
|
.sl-picker[data-layout="narrow"] .sl-ba-copy .narrow{display:inline}
|
|
3341
|
-
.sl-picker[data-layout="narrow"] .sl-ba
|
|
3414
|
+
.sl-picker[data-layout="narrow"] .sl-ba{grid-template-columns:auto minmax(0,1fr)}
|
|
3415
|
+
.sl-picker[data-layout="narrow"] .sl-ba select{grid-column:1/-1;min-height:38px}
|
|
3342
3416
|
.sl-picker[data-layout="narrow"] .sl-ba-qty button{width:30px;height:30px}
|
|
3343
|
-
|
|
3417
|
+
/* Quantity and Go share ONE row: a full-width row holding only "\u2212 2 +" was
|
|
3418
|
+
dead space, and the Find button still gets the lion's share. */
|
|
3419
|
+
.sl-picker[data-layout="narrow"] .sl-ba-qty{grid-column:1}
|
|
3420
|
+
.sl-picker[data-layout="narrow"] .sl-ba-go{grid-column:2;min-height:40px}
|
|
3421
|
+
/* Re-entry to best-available once the cart has seats (the card yields its
|
|
3422
|
+
space to chips, but the accelerator must stay reachable) + the quiet way
|
|
3423
|
+
back out of a reopened card. */
|
|
3424
|
+
.sl-ba-reopen{align-self:flex-start;display:inline-flex;align-items:center;gap:6px;min-height:32px;padding:5px 12px;margin-top:2px;
|
|
3425
|
+
border:1px dashed color-mix(in srgb,var(--sl-accent) 40%,var(--sl-line));border-radius:999px;
|
|
3426
|
+
color:var(--sl-accent);font-size:11.5px;font-weight:750;transition:border-color .15s,background .15s}
|
|
3427
|
+
.sl-ba-reopen:hover,.sl-ba-reopen:focus-visible{background:color-mix(in srgb,var(--sl-accent) 8%,transparent)}
|
|
3428
|
+
.sl-ba-back{grid-column:1/-1;justify-self:start;min-height:30px;padding:3px 0;color:var(--sl-muted);
|
|
3429
|
+
font-size:11px;font-weight:700;text-decoration:underline;text-underline-offset:3px;transition:color .15s}
|
|
3430
|
+
.sl-ba-back:hover,.sl-ba-back:focus-visible{color:var(--sl-text)}
|
|
3344
3431
|
|
|
3345
3432
|
/* Sales-closed is a designed state, not a set of disables: one statement in
|
|
3346
3433
|
the tray where the buying flow was, carrying the event's own date so the
|
|
@@ -3359,9 +3446,9 @@ var CSS2 = (
|
|
|
3359
3446
|
(the cart chip's remove/view rail) instead get real height on narrow. */
|
|
3360
3447
|
@media (pointer:coarse){
|
|
3361
3448
|
.sl-zoom button,.sl-cbbtn,.sl-close,.sl-ga-qty button,.sl-ba-qty button,.sl-price-more,
|
|
3362
|
-
.sl-hold-change,.sl-seccard-x,.sl-fs-pill,.sl-side-toggle{position:relative}
|
|
3449
|
+
.sl-hold-change,.sl-seccard-x,.sl-fs-pill,.sl-side-toggle,.sl-ba-reopen{position:relative}
|
|
3363
3450
|
.sl-zoom button::after,.sl-cbbtn::after,.sl-close::after,.sl-ga-qty button::after,.sl-ba-qty button::after,
|
|
3364
|
-
.sl-price-more::after,.sl-hold-change::after,.sl-seccard-x::after,.sl-fs-pill::after,.sl-side-toggle::after{
|
|
3451
|
+
.sl-price-more::after,.sl-hold-change::after,.sl-seccard-x::after,.sl-fs-pill::after,.sl-side-toggle::after,.sl-ba-reopen::after{
|
|
3365
3452
|
content:'';position:absolute;top:50%;left:50%;width:max(100%,44px);height:max(100%,44px);
|
|
3366
3453
|
transform:translate(-50%,-50%)}
|
|
3367
3454
|
/* The chip rail stacks remove over view in ~53px \u2014 pseudo-targets would
|
|
@@ -3464,12 +3551,6 @@ var CSS2 = (
|
|
|
3464
3551
|
border-radius:999px;font:700 11.5px/1 inherit;color:#eef1f8;background:rgba(12,18,32,.86);
|
|
3465
3552
|
border:1px solid rgba(150,165,205,.45);backdrop-filter:blur(6px);cursor:pointer}
|
|
3466
3553
|
.sl-view3d-nav select:focus-visible{outline:2px solid var(--sl-accent);outline-offset:2px}
|
|
3467
|
-
.sl-view3d-nav .sl-view3d-locator{display:grid;grid-template-columns:minmax(150px,1.25fr) minmax(110px,.8fr) minmax(105px,.7fr) auto;
|
|
3468
|
-
width:min(720px,100%);overflow:visible}
|
|
3469
|
-
.sl-view3d-nav.is-seat-focused .sl-view3d-locator{display:none}
|
|
3470
|
-
.sl-view3d-locator select{width:100%;min-width:0}
|
|
3471
|
-
.sl-picker[data-layout="narrow"] .sl-view3d-nav .sl-view3d-locator{display:flex;width:100%;overflow-x:auto}
|
|
3472
|
-
.sl-picker[data-layout="narrow"] .sl-view3d-locator select{flex:0 0 155px}
|
|
3473
3554
|
/* On phones the library owns the bottom edge for seat/panorama/overview actions.
|
|
3474
3555
|
Keep venue navigation in a separate top rail so those control families never
|
|
3475
3556
|
stack over one another. */
|
|
@@ -3479,9 +3560,6 @@ var CSS2 = (
|
|
|
3479
3560
|
.sl-picker[data-layout="narrow"] .sl-view3d-nav.is-open{left:12px;top:68px;max-width:calc(100% - 24px);padding:8px;
|
|
3480
3561
|
border:1px solid rgba(150,165,205,.35);border-radius:14px;background:rgba(8,12,22,.9);backdrop-filter:blur(10px)}
|
|
3481
3562
|
.sl-picker[data-layout="narrow"] .sl-view3d-nav.is-open>div{display:flex}
|
|
3482
|
-
.sl-picker[data-layout="narrow"] .sl-view3d-nav.is-open .sl-view3d-locator{display:grid;grid-template-columns:1fr 1fr;width:100%;overflow:visible}
|
|
3483
|
-
.sl-picker[data-layout="narrow"] .sl-view3d-nav.is-open .sl-view3d-locator select{width:100%;min-width:0;flex:auto}
|
|
3484
|
-
.sl-picker[data-layout="narrow"] .sl-view3d-nav.is-open .sl-view3d-locator button{width:100%}
|
|
3485
3563
|
/* Seat-eye is a decision state, not another venue-navigation state. Once the
|
|
3486
3564
|
buyer arrives, clear the floor/area/locator rails and the module's duplicate
|
|
3487
3565
|
Overview action. The picker-owned Back button becomes the one predictable
|
|
@@ -3907,6 +3985,15 @@ var SeatPicker = class _SeatPicker {
|
|
|
3907
3985
|
this.baZone = "";
|
|
3908
3986
|
/** "★ Best seats" premium quick-pick toggle — biases best-available to premium seats. */
|
|
3909
3987
|
this.baPremium = false;
|
|
3988
|
+
/**
|
|
3989
|
+
* The buyer re-opened the best-seats form with seats already in the cart
|
|
3990
|
+
* ("I picked one, actually find us three together"). The card normally
|
|
3991
|
+
* yields this space to the ticket chips the moment anything is selected —
|
|
3992
|
+
* which removed the accelerator at exactly the moment a one-handed phone
|
|
3993
|
+
* buyer wants it. Cleared when the cart empties, a hold lands, or the
|
|
3994
|
+
* buyer backs out.
|
|
3995
|
+
*/
|
|
3996
|
+
this.baReopen = false;
|
|
3910
3997
|
this.bestAvailableConfirm = false;
|
|
3911
3998
|
this.releasingHold = false;
|
|
3912
3999
|
/** Event sales window is closed (read-only load state / live close). */
|
|
@@ -3979,9 +4066,12 @@ var SeatPicker = class _SeatPicker {
|
|
|
3979
4066
|
this.fsEscHandler = null;
|
|
3980
4067
|
/** Host-level event chrome owns the duplicate identity outside full screen. */
|
|
3981
4068
|
this.eventDetailsHidden = false;
|
|
4069
|
+
/** True while the hold note reads "N more selected" — the tick must not overwrite it. */
|
|
4070
|
+
this.holdCopyPending = false;
|
|
3982
4071
|
/** Wide-layout ticket panel collapsed (map owns the full width). */
|
|
3983
4072
|
this.sideCollapsed = false;
|
|
3984
4073
|
this.sideToggleEl = null;
|
|
4074
|
+
this.pricesBtnEl = null;
|
|
3985
4075
|
/** True once we've asked the host page to pin us fullscreen (framed, no native). */
|
|
3986
4076
|
this.framedFs = false;
|
|
3987
4077
|
/** Last height (px) posted to a host frame; dedupes redundant reports. */
|
|
@@ -4094,7 +4184,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4094
4184
|
if (this.tableDialog?.physicalSeatIds.includes(seat.id)) this.dismissTableDialog();
|
|
4095
4185
|
},
|
|
4096
4186
|
onSelectionLimit: () => {
|
|
4097
|
-
this.toast(
|
|
4187
|
+
this.toast((0, import_core2.t)("picker.maxTicketsForOrder", { count: this.maxTickets }), "warning");
|
|
4098
4188
|
},
|
|
4099
4189
|
onViewChange: () => {
|
|
4100
4190
|
this.reanchorConfirm();
|
|
@@ -4210,8 +4300,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
4210
4300
|
return `<span class="sl-cx-mark" role="img" aria-label="${title}" title="${title}">\u25D0</span>`;
|
|
4211
4301
|
}
|
|
4212
4302
|
wheelchairProvisionLabel(type) {
|
|
4213
|
-
if (type === "no-seat") return "Empty wheelchair space";
|
|
4214
|
-
if (type === "seat-present") return "Accessible physical seat";
|
|
4303
|
+
if (type === "no-seat") return this.tf("picker.emptyWheelchairSpace", "Empty wheelchair space");
|
|
4304
|
+
if (type === "seat-present") return this.tf("picker.accessiblePhysicalSeat", "Accessible physical seat");
|
|
4215
4305
|
return "";
|
|
4216
4306
|
}
|
|
4217
4307
|
wheelchairConfirmHtml(type) {
|
|
@@ -4292,9 +4382,9 @@ var SeatPicker = class _SeatPicker {
|
|
|
4292
4382
|
const hideEventDetails = this.eventDetailsHidden && !active;
|
|
4293
4383
|
this.root?.setAttribute("data-event-details-hidden", String(hideEventDetails));
|
|
4294
4384
|
this.els.zfs?.setAttribute("aria-pressed", String(active));
|
|
4295
|
-
this.els.zfs?.setAttribute("title", active ? "Exit full screen" : "Full screen");
|
|
4385
|
+
this.els.zfs?.setAttribute("title", active ? this.tf("picker.exitFullScreen", "Exit full screen") : this.tf("picker.fullScreen", "Full screen"));
|
|
4296
4386
|
const zfsLabel = this.els.zfs?.querySelector(".sl-zfs-lbl");
|
|
4297
|
-
if (zfsLabel) zfsLabel.textContent = active ? "Exit full screen" : "Full screen";
|
|
4387
|
+
if (zfsLabel) zfsLabel.textContent = active ? this.tf("picker.exitFullScreen", "Exit full screen") : this.tf("picker.fullScreen", "Full screen");
|
|
4298
4388
|
this.view3dEl?.querySelector(".sl-view3d-fs")?.setAttribute("aria-pressed", String(active));
|
|
4299
4389
|
}
|
|
4300
4390
|
/**
|
|
@@ -4359,7 +4449,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4359
4449
|
frame.className = "sl-modal-frame";
|
|
4360
4450
|
frame.setAttribute("role", "dialog");
|
|
4361
4451
|
frame.setAttribute("aria-modal", "true");
|
|
4362
|
-
frame.setAttribute("aria-label", "Seat selection");
|
|
4452
|
+
frame.setAttribute("aria-label", tfStatic("picker.seatSelection", "Seat selection"));
|
|
4363
4453
|
frame.tabIndex = -1;
|
|
4364
4454
|
scrim.appendChild(frame);
|
|
4365
4455
|
document.body.appendChild(scrim);
|
|
@@ -4519,7 +4609,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4519
4609
|
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/></svg>
|
|
4520
4610
|
<span data-ref="closedPillText"></span>
|
|
4521
4611
|
</span>
|
|
4522
|
-
<button type="button" class="sl-close" data-ref="close" aria-label="Close">
|
|
4612
|
+
<button type="button" class="sl-close" data-ref="close" aria-label="${this.tf("picker.close", "Close")}">
|
|
4523
4613
|
<svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
|
4524
4614
|
</button>
|
|
4525
4615
|
</div>
|
|
@@ -4527,17 +4617,17 @@ var SeatPicker = class _SeatPicker {
|
|
|
4527
4617
|
<div class="sl-map">
|
|
4528
4618
|
<div class="sl-map-host" data-ref="map"></div>
|
|
4529
4619
|
<div class="sl-zoom" data-ref="zoom">
|
|
4530
|
-
<button type="button" aria-label="Zoom in" title="Zoom in" data-ref="zin">+</button>
|
|
4531
|
-
<button type="button" aria-label="Zoom out" title="Zoom out" data-ref="zout">\u2212</button>
|
|
4532
|
-
<button type="button" aria-label="Fit to screen" title="Fit to screen" data-ref="zfit">
|
|
4620
|
+
<button type="button" aria-label="${this.tf("picker.zoomIn", "Zoom in")}" title="${this.tf("picker.zoomIn", "Zoom in")}" data-ref="zin">+</button>
|
|
4621
|
+
<button type="button" aria-label="${this.tf("picker.zoomOut", "Zoom out")}" title="${this.tf("picker.zoomOut", "Zoom out")}" data-ref="zout">\u2212</button>
|
|
4622
|
+
<button type="button" aria-label="${this.tf("picker.fitToScreen", "Fit to screen")}" title="${this.tf("picker.fitToScreen", "Fit to screen")}" data-ref="zfit">
|
|
4533
4623
|
<svg viewBox="0 0 24 24"><path d="M8 3H5a2 2 0 0 0-2 2v3M16 3h3a2 2 0 0 1 2 2v3M8 21H5a2 2 0 0 1-2-2v-3M16 21h3a2 2 0 0 0 2-2v-3"/></svg>
|
|
4534
4624
|
</button>
|
|
4535
|
-
<button type="button" aria-label="Full screen" title="Full screen" aria-pressed="false" data-ref="zfs">
|
|
4625
|
+
<button type="button" aria-label="${this.tf("picker.fullScreen", "Full screen")}" title="${this.tf("picker.fullScreen", "Full screen")}" aria-pressed="false" data-ref="zfs">
|
|
4536
4626
|
<svg viewBox="0 0 24 24"><path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/></svg>
|
|
4537
|
-
<span class="sl-zfs-lbl" aria-hidden="true"
|
|
4627
|
+
<span class="sl-zfs-lbl" aria-hidden="true">${this.tf("picker.fullScreen", "Full screen")}</span>
|
|
4538
4628
|
</button>
|
|
4539
4629
|
</div>
|
|
4540
|
-
<div class="sl-boot" data-ref="boot"><span class="sl-boot-spin"></span
|
|
4630
|
+
<div class="sl-boot" data-ref="boot"><span class="sl-boot-spin"></span>${this.tf("picker.loadingSeatMap", "Loading seat map\u2026")}</div>
|
|
4541
4631
|
<div class="sl-toast" data-ref="toast" role="status" aria-live="polite"></div>
|
|
4542
4632
|
</div>
|
|
4543
4633
|
<div class="sl-side" data-ref="side">
|
|
@@ -4545,24 +4635,25 @@ var SeatPicker = class _SeatPicker {
|
|
|
4545
4635
|
<div class="sl-sheet-grab"></div>
|
|
4546
4636
|
<div class="sl-sheet-bar">
|
|
4547
4637
|
<div class="sl-sheet-peek" data-ref="peek"></div>
|
|
4548
|
-
<button type="button" class="sl-sheet-toggle" data-ref="sheetToggle" aria-label="Open ticket panel" aria-expanded="false">
|
|
4638
|
+
<button type="button" class="sl-sheet-toggle" data-ref="sheetToggle" aria-label="${this.tf("picker.openTicketPanel", "Open ticket panel")}" aria-expanded="false">
|
|
4549
4639
|
<svg viewBox="0 0 24 24"><path d="M6 15l6-6 6 6"/></svg>
|
|
4550
4640
|
</button>
|
|
4551
4641
|
</div>
|
|
4552
4642
|
</div>
|
|
4553
|
-
<div class="sl-sec sl-filtersec" data-ref="filtersSec"
|
|
4643
|
+
<div class="sl-sec sl-filtersec" data-ref="filtersSec">${this.tf("picker.filters", "Filters")}</div>
|
|
4554
4644
|
<div class="sl-filters" data-ref="filters"></div>
|
|
4555
4645
|
<div class="sl-offer" data-ref="offer" role="status" aria-live="polite"></div>
|
|
4556
|
-
<div class="sl-sec sl-prices-sec" data-ref="pricesSec"><span
|
|
4646
|
+
<div class="sl-sec sl-prices-sec" data-ref="pricesSec"><span>${this.tf("picker.ticketPrices", "Ticket prices")}</span></div>
|
|
4647
|
+
<div class="sl-prices-hint" data-ref="pricesHint"></div>
|
|
4557
4648
|
<div class="sl-prices" data-ref="prices"></div>
|
|
4558
|
-
<div class="sl-live" data-ref="live" role="status" aria-live="polite"><span class="dot" aria-hidden="true"></span><span data-ref="liveText"
|
|
4559
|
-
<div class="sl-sec sl-seats-sec"><span
|
|
4649
|
+
<div class="sl-live" data-ref="live" role="status" aria-live="polite"><span class="dot" aria-hidden="true"></span><span data-ref="liveText">${this.tf("picker.liveAvailability", "Live availability \u2014 seats update in real time")}</span></div>
|
|
4650
|
+
<div class="sl-sec sl-seats-sec"><span>${this.tf("picker.yourSeats", "Your seats")}</span><span class="sl-seat-summary" data-ref="seatSummary"></span></div>
|
|
4560
4651
|
<div class="sl-tray" data-ref="tray"></div>
|
|
4561
4652
|
<div class="sl-foot" data-ref="foot">
|
|
4562
4653
|
<div class="sl-hold-note" data-ref="holdNote" role="status" aria-live="polite">
|
|
4563
4654
|
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
|
|
4564
|
-
<span><b data-ref="holdTitle"
|
|
4565
|
-
<button type="button" class="sl-hold-change" data-ref="holdChange" aria-label="Release held tickets and choose different seats"
|
|
4655
|
+
<span><b data-ref="holdTitle">${this.tf("picker.seatsSecured", "Seats secured")}</b><span class="sl-hold-copy" data-ref="holdCopy">${this.tf("picker.notChargedYet", "You won\u2019t be charged yet.")}</span></span>
|
|
4656
|
+
<button type="button" class="sl-hold-change" data-ref="holdChange" aria-label="${this.tf("picker.releaseHeldTickets", "Release held tickets and choose different seats")}">${this.tf("picker.change", "Change")}</button>
|
|
4566
4657
|
</div>
|
|
4567
4658
|
<div class="sl-total"><span data-ref="count"></span><b data-ref="total"></b></div>
|
|
4568
4659
|
<button type="button" class="sl-cta" data-ref="cta" disabled></button>
|
|
@@ -4613,7 +4704,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4613
4704
|
const setSheet = (open) => {
|
|
4614
4705
|
root.dataset.sheet = open ? "open" : "peek";
|
|
4615
4706
|
toggle?.setAttribute("aria-expanded", String(open));
|
|
4616
|
-
toggle?.setAttribute("aria-label", open ? "Collapse ticket panel" : "Open ticket panel");
|
|
4707
|
+
toggle?.setAttribute("aria-label", open ? this.tf("picker.collapseTicketPanel", "Collapse ticket panel") : this.tf("picker.openTicketPanel", "Open ticket panel"));
|
|
4617
4708
|
};
|
|
4618
4709
|
setSheet(root.dataset.sheet === "open");
|
|
4619
4710
|
toggle?.addEventListener("click", (e) => {
|
|
@@ -4659,6 +4750,39 @@ var SeatPicker = class _SeatPicker {
|
|
|
4659
4750
|
head.releasePointerCapture?.(e.pointerId);
|
|
4660
4751
|
});
|
|
4661
4752
|
}
|
|
4753
|
+
const togglePrices = () => {
|
|
4754
|
+
if (this.root?.dataset.layout !== "narrow") return;
|
|
4755
|
+
const open = this.root.getAttribute("data-prices-open") === "true";
|
|
4756
|
+
this.root.setAttribute("data-prices-open", String(!open));
|
|
4757
|
+
this.els.pricesSec?.setAttribute("aria-expanded", String(!open));
|
|
4758
|
+
this.pricesBtnEl?.setAttribute("aria-pressed", String(!open));
|
|
4759
|
+
if (!open && this.root.dataset.sheet !== "open") {
|
|
4760
|
+
this.root.dataset.sheet = "open";
|
|
4761
|
+
const sheetToggle = this.els.sheetToggle;
|
|
4762
|
+
sheetToggle?.setAttribute("aria-expanded", "true");
|
|
4763
|
+
sheetToggle?.setAttribute("aria-label", "Collapse ticket panel");
|
|
4764
|
+
}
|
|
4765
|
+
};
|
|
4766
|
+
this.els.pricesSec?.addEventListener("click", (e) => {
|
|
4767
|
+
if (e.target.closest("select,button")) return;
|
|
4768
|
+
togglePrices();
|
|
4769
|
+
});
|
|
4770
|
+
this.els.pricesSec?.addEventListener("keydown", (e) => {
|
|
4771
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
4772
|
+
if (e.target.closest("select,button")) return;
|
|
4773
|
+
e.preventDefault();
|
|
4774
|
+
togglePrices();
|
|
4775
|
+
});
|
|
4776
|
+
const pricesBtn = document.createElement("button");
|
|
4777
|
+
pricesBtn.type = "button";
|
|
4778
|
+
pricesBtn.className = "sl-prices-btn";
|
|
4779
|
+
pricesBtn.setAttribute("aria-label", this.tf("picker.ticketPrices", "Ticket prices"));
|
|
4780
|
+
pricesBtn.setAttribute("title", this.tf("picker.ticketPrices", "Ticket prices"));
|
|
4781
|
+
pricesBtn.setAttribute("aria-pressed", "false");
|
|
4782
|
+
pricesBtn.innerHTML = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20.6 13.4 13.4 20.6a2 2 0 0 1-2.8 0L3 13V5a2 2 0 0 1 2-2h8l7.6 7.6a2 2 0 0 1 0 2.8z"/><circle cx="7.5" cy="7.5" r="1.3"/></svg>';
|
|
4783
|
+
pricesBtn.addEventListener("click", () => togglePrices());
|
|
4784
|
+
this.els.headInfo?.parentElement?.insertBefore(pricesBtn, this.els.hold ?? null);
|
|
4785
|
+
this.pricesBtnEl = pricesBtn;
|
|
4662
4786
|
this.tipEl = document.createElement("div");
|
|
4663
4787
|
this.tipEl.setAttribute("role", "tooltip");
|
|
4664
4788
|
this.tipEl.className = "sl-tip";
|
|
@@ -4676,7 +4800,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4676
4800
|
const info = await this.controller.render(canvasHost);
|
|
4677
4801
|
if (this.destroyed) return this;
|
|
4678
4802
|
if (!info) {
|
|
4679
|
-
this.els.boot.innerHTML =
|
|
4803
|
+
this.els.boot.innerHTML = `<div class="sl-boot-title">${this.tf("picker.mapDidNotLoad", "The seat map didn\u2019t load")}</div><div>${this.tf("picker.checkConnection", "Check your connection and try again.")}</div><button type="button" class="sl-boot-retry">${this.tf("picker.accessRetry", "Try again")}</button>`;
|
|
4680
4804
|
this.els.boot.querySelector("button").addEventListener("click", () => {
|
|
4681
4805
|
const container = this.opts.container;
|
|
4682
4806
|
const opts = this.opts;
|
|
@@ -4711,6 +4835,12 @@ var SeatPicker = class _SeatPicker {
|
|
|
4711
4835
|
const when = info.startsAt ? formatWhen(info.startsAt, info.timezone ?? null, this.opts.locale) : "";
|
|
4712
4836
|
this.eventWhenText = when || null;
|
|
4713
4837
|
this.els.meta.textContent = [info.venue, when].filter(Boolean).join(" \xB7 ");
|
|
4838
|
+
if (this.els.pricesHint) {
|
|
4839
|
+
this.els.pricesHint.textContent = this.tf(
|
|
4840
|
+
"picker.priceHint",
|
|
4841
|
+
"Colours on the map are ticket types \u2014 tap one below to show just those seats."
|
|
4842
|
+
);
|
|
4843
|
+
}
|
|
4714
4844
|
this.buildBadge(chartTheme);
|
|
4715
4845
|
const present = /* @__PURE__ */ new Set();
|
|
4716
4846
|
let hasLimitedView = false;
|
|
@@ -4737,7 +4867,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4737
4867
|
const mk = (key, label) => `<button type="button" class="sl-chip-f${key === "all" ? " on" : ""}" data-a11y="1" data-f="${key}">${label}</button>`;
|
|
4738
4868
|
chips.insertAdjacentHTML(
|
|
4739
4869
|
"beforeend",
|
|
4740
|
-
mk("all", "All seats") + import_core2.ACCESSIBILITY_TYPES.filter(({ key }) => present.has(key)).map(({ key, short, icon }) => mk(key, `${icon} ${short}`)).join("")
|
|
4870
|
+
mk("all", this.tf("picker.allSeats", "All seats")) + import_core2.ACCESSIBILITY_TYPES.filter(({ key }) => present.has(key)).map(({ key, short, icon }) => mk(key, `${icon} ${short}`)).join("")
|
|
4741
4871
|
);
|
|
4742
4872
|
const active = /* @__PURE__ */ new Set();
|
|
4743
4873
|
const syncChips = () => {
|
|
@@ -4783,7 +4913,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4783
4913
|
cb.type = "button";
|
|
4784
4914
|
cb.className = "sl-cbbtn";
|
|
4785
4915
|
this.cbEl = cb;
|
|
4786
|
-
cb.setAttribute("aria-label", "Toggle colorblind-friendly colors");
|
|
4916
|
+
cb.setAttribute("aria-label", this.tf("picker.toggleColorblindColors", "Toggle colorblind-friendly colors"));
|
|
4787
4917
|
cb.setAttribute("aria-pressed", String(this.cbSafe));
|
|
4788
4918
|
cb.innerHTML = '<svg viewBox="0 0 24 24"><path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg>';
|
|
4789
4919
|
this.els.zfit.parentElement.appendChild(cb);
|
|
@@ -4869,8 +4999,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
4869
4999
|
if (!btn) return;
|
|
4870
5000
|
const collapsed = this.sideCollapsed;
|
|
4871
5001
|
btn.setAttribute("aria-expanded", String(!collapsed));
|
|
4872
|
-
btn.setAttribute("aria-label", collapsed ? "Show the ticket panel" : "Hide the ticket panel");
|
|
4873
|
-
btn.innerHTML = collapsed ?
|
|
5002
|
+
btn.setAttribute("aria-label", collapsed ? this.tf("picker.showTicketPanel", "Show the ticket panel") : this.tf("picker.hideTicketPanel", "Hide the ticket panel"));
|
|
5003
|
+
btn.innerHTML = collapsed ? `<svg viewBox="0 0 24 24"><path d="M15 6l-6 6 6 6"/></svg><span>${this.tf("picker.tickets", "Tickets")}</span>` : `<svg viewBox="0 0 24 24"><path d="M9 6l6 6-6 6"/></svg><span>${this.tf("picker.hidePanel", "Hide panel")}</span>`;
|
|
4874
5004
|
}
|
|
4875
5005
|
/**
|
|
4876
5006
|
* Collapse or reopen the wide-layout ticket panel in place (host-drivable —
|
|
@@ -4896,13 +5026,24 @@ var SeatPicker = class _SeatPicker {
|
|
|
4896
5026
|
const narrow = this.root?.dataset.layout === "narrow";
|
|
4897
5027
|
this.applyPanelCollapsed();
|
|
4898
5028
|
const zfs = this.els.zfs;
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
5029
|
+
const head = this.els.headInfo?.parentElement;
|
|
5030
|
+
if (zfs && head && zfs.parentElement !== head) {
|
|
5031
|
+
zfs.classList.add("sl-fs-pill");
|
|
5032
|
+
head.insertBefore(zfs, this.els.hold ?? null);
|
|
5033
|
+
}
|
|
5034
|
+
const pricesSec = this.els.pricesSec;
|
|
5035
|
+
if (pricesSec) {
|
|
5036
|
+
if (narrow) {
|
|
5037
|
+
pricesSec.setAttribute("role", "button");
|
|
5038
|
+
pricesSec.tabIndex = 0;
|
|
5039
|
+
pricesSec.setAttribute(
|
|
5040
|
+
"aria-expanded",
|
|
5041
|
+
String(this.root?.getAttribute("data-prices-open") === "true")
|
|
5042
|
+
);
|
|
5043
|
+
} else {
|
|
5044
|
+
pricesSec.removeAttribute("role");
|
|
5045
|
+
pricesSec.removeAttribute("aria-expanded");
|
|
5046
|
+
pricesSec.tabIndex = -1;
|
|
4906
5047
|
}
|
|
4907
5048
|
}
|
|
4908
5049
|
const filters = this.els.filters;
|
|
@@ -4929,7 +5070,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4929
5070
|
this.extendEl = el2;
|
|
4930
5071
|
this.els.extendTxt = el2.querySelector('[data-ref="extendTxt"]');
|
|
4931
5072
|
this.els.extendBtn = el2.querySelector('[data-ref="extendBtn"]');
|
|
4932
|
-
this.els.extendBtn.textContent = "Add time";
|
|
5073
|
+
this.els.extendBtn.textContent = this.tf("picker.addTime", "Add time");
|
|
4933
5074
|
this.els.extendBtn.addEventListener("click", () => void this.handleExtend());
|
|
4934
5075
|
}
|
|
4935
5076
|
/** Success overlay + onBooked fire when the held seats settle to booked. */
|
|
@@ -4938,7 +5079,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4938
5079
|
el2.className = "sl-booked";
|
|
4939
5080
|
el2.setAttribute("role", "status");
|
|
4940
5081
|
el2.setAttribute("aria-live", "polite");
|
|
4941
|
-
el2.innerHTML = `<div class="sl-booked-badge"><svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg></div><div class="sl-booked-title"
|
|
5082
|
+
el2.innerHTML = `<div class="sl-booked-badge"><svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg></div><div class="sl-booked-title">${this.tf("picker.allSetTitle", "You're all set")}</div><div class="sl-booked-sub" data-ref="bookedSub"></div>`;
|
|
4942
5083
|
this.root.appendChild(el2);
|
|
4943
5084
|
this.bookedEl = el2;
|
|
4944
5085
|
this.els.bookedSub = el2.querySelector('[data-ref="bookedSub"]');
|
|
@@ -4949,8 +5090,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4949
5090
|
* host `messages` override (which makes `t()` return the override, not the key).
|
|
4950
5091
|
*/
|
|
4951
5092
|
tf(key, fallback) {
|
|
4952
|
-
|
|
4953
|
-
return v === key ? fallback : v;
|
|
5093
|
+
return tfStatic(key, fallback);
|
|
4954
5094
|
}
|
|
4955
5095
|
/** Sold-out overlay — an informational state with no unavailable action. */
|
|
4956
5096
|
buildSoldoutOverlay() {
|
|
@@ -5135,7 +5275,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
5135
5275
|
}
|
|
5136
5276
|
canAddTicket() {
|
|
5137
5277
|
if (this.totalTicketCount() < this.maxTickets) return true;
|
|
5138
|
-
this.toast(
|
|
5278
|
+
this.toast((0, import_core2.t)("picker.maxTicketsForOrder", { count: this.maxTickets }), "warning");
|
|
5139
5279
|
return false;
|
|
5140
5280
|
}
|
|
5141
5281
|
pendingGATotal(gaAreas) {
|
|
@@ -5158,30 +5298,32 @@ var SeatPicker = class _SeatPicker {
|
|
|
5158
5298
|
}
|
|
5159
5299
|
if (this.confirmSeat || this.tableDialog && !this.tableDialogHeld) {
|
|
5160
5300
|
cta.disabled = true;
|
|
5161
|
-
cta.textContent = this.tableDialog ? "Confirm your table" : "Confirm or cancel this seat";
|
|
5301
|
+
cta.textContent = this.tableDialog ? this.tf("picker.confirmYourTable", "Confirm your table") : this.tf("picker.confirmOrCancelSeat", "Confirm or cancel this seat");
|
|
5162
5302
|
return;
|
|
5163
5303
|
}
|
|
5164
5304
|
if (this.ctaPhase === "holding") {
|
|
5165
5305
|
cta.disabled = true;
|
|
5166
|
-
cta.innerHTML =
|
|
5306
|
+
cta.innerHTML = `<span class="sl-cta-spin" aria-hidden="true"></span>${this.tf("picker.securingSeats", "Securing your seats\u2026")}`;
|
|
5167
5307
|
return;
|
|
5168
5308
|
}
|
|
5169
5309
|
if (this.ctaPhase === "checkout") {
|
|
5170
5310
|
cta.disabled = true;
|
|
5171
|
-
cta.innerHTML =
|
|
5311
|
+
cta.innerHTML = `<span class="sl-cta-spin" aria-hidden="true"></span>${this.tf("picker.openingCheckout", "Opening secure checkout\u2026")}`;
|
|
5172
5312
|
return;
|
|
5173
5313
|
}
|
|
5174
5314
|
cta.disabled = count === 0;
|
|
5175
|
-
cta.textContent = this.hold ? pending ?
|
|
5315
|
+
cta.textContent = this.hold ? pending ? (0, import_core2.t)("picker.secureMoreAndCheckout", { count: pending }) : this.tf("picker.continueToCheckout", "Continue to checkout") : count ? this.tf("picker.holdSeatsAndCheckout", "Hold seats & checkout") : this.tf("picker.selectSeats", "Select seats");
|
|
5176
5316
|
}
|
|
5177
5317
|
setCtaPhase(phase) {
|
|
5178
5318
|
this.ctaPhase = phase;
|
|
5179
5319
|
this.syncCta();
|
|
5320
|
+
this.renderPeek(this.lastTrayCount, this.lastTrayTotal, this.pendingSelectionCount());
|
|
5180
5321
|
if (phase === "checkout") {
|
|
5181
5322
|
this.scheduleMotion(() => {
|
|
5182
5323
|
if (this.ctaPhase !== "checkout") return;
|
|
5183
5324
|
this.ctaPhase = "idle";
|
|
5184
5325
|
this.syncCta();
|
|
5326
|
+
this.renderPeek(this.lastTrayCount, this.lastTrayTotal, this.pendingSelectionCount());
|
|
5185
5327
|
}, 1100);
|
|
5186
5328
|
}
|
|
5187
5329
|
}
|
|
@@ -5231,7 +5373,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
5231
5373
|
this.syncTray();
|
|
5232
5374
|
this.emitHoldChange();
|
|
5233
5375
|
this.opts.onHoldRestored?.(restored, restored.seats ?? [], this.buildHandoff(restored));
|
|
5234
|
-
if (automatic) this.toast("Your held tickets have been restored.", "success");
|
|
5376
|
+
if (automatic) this.toast(this.tf("picker.heldTicketsRestored", "Your held tickets have been restored."), "success");
|
|
5235
5377
|
return restored;
|
|
5236
5378
|
} catch (error) {
|
|
5237
5379
|
const status = error?.status;
|
|
@@ -5449,8 +5591,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
5449
5591
|
if (bands.length < 2) return;
|
|
5450
5592
|
const select = document.createElement("select");
|
|
5451
5593
|
select.className = "sl-price-select";
|
|
5452
|
-
select.setAttribute("aria-label", "Filter and focus seats by price");
|
|
5453
|
-
select.innerHTML = `<option value="all"
|
|
5594
|
+
select.setAttribute("aria-label", this.tf("picker.filterAndFocusByPrice", "Filter and focus seats by price"));
|
|
5595
|
+
select.innerHTML = `<option value="all">${this.tf("picker.allPrices", "All prices")}</option>` + bands.map((band) => `<option value="${band.id}">${band.label}</option>`).join("");
|
|
5454
5596
|
this.els.pricesSec.appendChild(select);
|
|
5455
5597
|
select.addEventListener("change", () => {
|
|
5456
5598
|
const band = bands.find((candidate) => candidate.id === select.value);
|
|
@@ -5477,8 +5619,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
5477
5619
|
const projection = document.createElement("div");
|
|
5478
5620
|
projection.className = "sl-projection";
|
|
5479
5621
|
projection.setAttribute("role", "group");
|
|
5480
|
-
projection.setAttribute("aria-label", "Venue view");
|
|
5481
|
-
projection.innerHTML =
|
|
5622
|
+
projection.setAttribute("aria-label", this.tf("picker.venueView", "Venue view"));
|
|
5623
|
+
projection.innerHTML = `<button type="button" data-view="map" aria-pressed="true" title="${this.tf("picker.flat2dMap", "Flat 2D map")}">${this.tf("picker.map", "Map")}</button><button type="button" data-view="venue3d" aria-pressed="false" title="${this.tf("picker.interactive3dVenueView", "Interactive 3D venue view")}">3D</button>`;
|
|
5482
5624
|
projection.querySelectorAll("button").forEach((button) => {
|
|
5483
5625
|
button.addEventListener("click", () => {
|
|
5484
5626
|
this.setBuyerView(button.dataset.view);
|
|
@@ -5601,6 +5743,10 @@ var SeatPicker = class _SeatPicker {
|
|
|
5601
5743
|
renderSectionCard(summary) {
|
|
5602
5744
|
if (!this.els.map) return;
|
|
5603
5745
|
this.secCardEl?.remove();
|
|
5746
|
+
if (this.root?.dataset.layout === "narrow" && (this.hold || this.committedSelection().length || this.pendingGACount())) {
|
|
5747
|
+
this.lastSection = null;
|
|
5748
|
+
return;
|
|
5749
|
+
}
|
|
5604
5750
|
const paid = summary.categories.length ? summary.categories.map((c) => this.paidPrice(c.key, null, c.price)) : [summary.priceMin, summary.priceMax];
|
|
5605
5751
|
const paidMin = Math.min(...paid);
|
|
5606
5752
|
const paidMax = Math.max(...paid);
|
|
@@ -5701,13 +5847,13 @@ var SeatPicker = class _SeatPicker {
|
|
|
5701
5847
|
}
|
|
5702
5848
|
const cat = this.controller.doc?.categories.find((c) => c.key === seat.categoryKey);
|
|
5703
5849
|
const status = this.controller.getStatus(seat.id) ?? "free";
|
|
5704
|
-
const statusText = status === "free" ? "available" : status === "held" ? "on hold" : "taken";
|
|
5850
|
+
const statusText = status === "free" ? this.tf("picker.statusAvailable", "available") : status === "held" ? this.tf("picker.statusOnHold", "on hold") : this.tf("picker.statusTaken2", "taken");
|
|
5705
5851
|
const price = cat ? this.catPrice(cat) : void 0;
|
|
5706
5852
|
const table = this.controller.tableSelection(seat.id);
|
|
5707
5853
|
const details = table ?? this.controller.seatDetails(seat.id);
|
|
5708
5854
|
const typeWord = this.rowTypeWord(details);
|
|
5709
5855
|
const buyerName = details?.rowLabel ?? details?.displayLabel ?? seat.displayLabel ?? seat.label;
|
|
5710
|
-
const identity = table ? `${typeWord} ${buyerName}, ${table.bookingMode === "variable" ?
|
|
5856
|
+
const identity = table ? `${typeWord} ${buyerName}, ${table.bookingMode === "variable" ? (0, import_core2.t)("picker.minToMaxGuests", { min: table.minOccupancy, max: table.maxOccupancy }) : (0, import_core2.t)("picker.capacityGuests", { count: table.capacity })}` : details?.objectType === "booth" ? `${typeWord} ${buyerName}` : details?.objectType === "table" ? `${typeWord} ${buyerName}, ${(0, import_core2.t)("picker.seatNumberLower", { label: details.seatNumber ?? seat.label })}` : (0, import_core2.t)("picker.seatLabel", { label: details?.displayLabel ?? seat.displayLabel ?? seat.label });
|
|
5711
5857
|
this.srEl.textContent = `${identity}, ${cat?.label ?? seat.categoryKey}${price != null ? `, ${this.money(price)}` : ""}, ${statusText}`;
|
|
5712
5858
|
}
|
|
5713
5859
|
// ---- atomic table confirmation / guest quantity ---------------------------
|
|
@@ -5728,7 +5874,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
5728
5874
|
const typeWord = this.rowTypeWord(table);
|
|
5729
5875
|
const el2 = document.createElement("div");
|
|
5730
5876
|
el2.className = "sl-table-scrim";
|
|
5731
|
-
el2.innerHTML = `<section class="sl-table-dialog" role="dialog" aria-modal="true" aria-labelledby="sl-table-title" aria-describedby="sl-table-copy"><div class="sl-table-head"><div class="sl-table-eyebrow">${esc(variable ?
|
|
5877
|
+
el2.innerHTML = `<section class="sl-table-dialog" role="dialog" aria-modal="true" aria-labelledby="sl-table-title" aria-describedby="sl-table-copy"><div class="sl-table-head"><div class="sl-table-eyebrow">${esc(variable ? (0, import_core2.t)("picker.flexiblePartyTypeWord", { typeWord }) : (0, import_core2.t)("picker.wholeTypeWord", { typeWord }))}</div><h2 class="sl-table-title" id="sl-table-title">${esc(table.displayLabel ?? table.label)}</h2><p class="sl-table-copy" id="sl-table-copy">${variable ? this.tf("picker.chooseGuestsCopy", "Choose how many guests will sit together. This table is held exclusively for your party.") : (0, import_core2.t)("picker.allPlacesBookedTogether", { count: table.capacity })}</p></div><div class="sl-table-body"><div class="sl-table-summary"><span>${esc(cat?.label ?? table.categoryKey)}</span><b data-table-unit>${(0, import_core2.t)("picker.perGuestPrice", { price: this.money(this.paidPrice(table.categoryKey, table.tierId ?? null, table.price)) })}</b><span class="muted">${this.tf("picker.tableCapacity", "Table capacity")}</span><span>${(0, import_core2.t)("picker.guestsCount", { count: table.capacity })}</span><span class="muted">${this.tf("picker.total", "Total")}</span><b data-table-total></b></div>` + (variable ? `<label class="sl-table-qtylabel" id="sl-table-qty-label">${this.tf("picker.numberOfGuests", "Number of guests")}</label><div class="sl-table-stepper" role="group" aria-labelledby="sl-table-qty-label"><button type="button" data-table-step="-1" aria-label="${this.tf("picker.fewerGuests", "Fewer guests")}">\u2212</button><output aria-live="polite" data-table-qty>${table.quantity}</output><button type="button" data-table-step="1" aria-label="${this.tf("picker.moreGuests", "More guests")}">+</button></div><div class="sl-table-range">${(0, import_core2.t)("picker.chooseMinMaxGuests", { min: table.minOccupancy, max: table.maxOccupancy })}</div>` : `<input type="hidden" data-table-qty value="${table.capacity}">`) + `<div class="sl-table-actions"><button type="button" class="sl-table-cancel">${(0, import_core2.t)("common.cancel")}</button><button type="button" class="sl-table-confirm">${held ? this.tf("picker.updateTable", "Update table") : variable ? this.tf("picker.selectTable", "Select table") : this.tf("picker.selectWholeTable", "Select whole table")}</button></div></div></section>`;
|
|
5732
5878
|
this.root.appendChild(el2);
|
|
5733
5879
|
this.tableDialogEl = el2;
|
|
5734
5880
|
this.renderTableDialogState();
|
|
@@ -5787,17 +5933,17 @@ var SeatPicker = class _SeatPicker {
|
|
|
5787
5933
|
const button = this.tableDialogEl?.querySelector(".sl-table-confirm");
|
|
5788
5934
|
if (button) {
|
|
5789
5935
|
button.disabled = true;
|
|
5790
|
-
button.textContent = held ? "Updating\u2026" : "Selecting\u2026";
|
|
5936
|
+
button.textContent = held ? this.tf("picker.updatingEllipsis", "Updating\u2026") : this.tf("picker.selectingEllipsis", "Selecting\u2026");
|
|
5791
5937
|
}
|
|
5792
5938
|
if (held) {
|
|
5793
5939
|
try {
|
|
5794
5940
|
const updated = await this.controller.replaceTableQuantity(table.label, table.quantity, this.opts.holdTtlMs);
|
|
5795
5941
|
if (!updated) {
|
|
5796
|
-
this.toast("That guest count could not be secured. Your current table hold is unchanged.", "warning");
|
|
5942
|
+
this.toast(this.tf("picker.guestCountCouldNotBeSecured", "That guest count could not be secured. Your current table hold is unchanged."), "warning");
|
|
5797
5943
|
this.renderTableDialogState();
|
|
5798
5944
|
if (button) {
|
|
5799
5945
|
button.disabled = false;
|
|
5800
|
-
button.textContent = "Update table";
|
|
5946
|
+
button.textContent = this.tf("picker.updateTable", "Update table");
|
|
5801
5947
|
}
|
|
5802
5948
|
return;
|
|
5803
5949
|
}
|
|
@@ -5811,13 +5957,13 @@ var SeatPicker = class _SeatPicker {
|
|
|
5811
5957
|
this.dismissTableDialog();
|
|
5812
5958
|
this.syncTray();
|
|
5813
5959
|
this.emitHoldChange();
|
|
5814
|
-
this.toast(
|
|
5960
|
+
this.toast((0, import_core2.t)("picker.tableUpdatedForGuests", { label: table.label, count: table.quantity }), "success");
|
|
5815
5961
|
} catch (error) {
|
|
5816
5962
|
this.opts.onError?.(error);
|
|
5817
|
-
this.toast("That guest count is no longer available. Your current hold is unchanged.", "error");
|
|
5963
|
+
this.toast(this.tf("picker.guestCountNoLongerAvailable", "That guest count is no longer available. Your current hold is unchanged."), "error");
|
|
5818
5964
|
if (button) {
|
|
5819
5965
|
button.disabled = false;
|
|
5820
|
-
button.textContent = "Update table";
|
|
5966
|
+
button.textContent = this.tf("picker.updateTable", "Update table");
|
|
5821
5967
|
}
|
|
5822
5968
|
}
|
|
5823
5969
|
return;
|
|
@@ -5825,7 +5971,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
5825
5971
|
if (!this.controller.setTableQuantity(table.label, table.quantity)) {
|
|
5826
5972
|
if (button) {
|
|
5827
5973
|
button.disabled = false;
|
|
5828
|
-
button.textContent = table.bookingMode === "variable" ? "Select table" : "Select whole table";
|
|
5974
|
+
button.textContent = table.bookingMode === "variable" ? this.tf("picker.selectTable", "Select table") : this.tf("picker.selectWholeTable", "Select whole table");
|
|
5829
5975
|
}
|
|
5830
5976
|
return;
|
|
5831
5977
|
}
|
|
@@ -5871,16 +6017,16 @@ var SeatPicker = class _SeatPicker {
|
|
|
5871
6017
|
'"': """
|
|
5872
6018
|
})[char]);
|
|
5873
6019
|
const identityFields = [
|
|
5874
|
-
details?.sectionLabel ? `<div class="sl-confirm-field"><span class="sl-confirm-key"
|
|
6020
|
+
details?.sectionLabel ? `<div class="sl-confirm-field"><span class="sl-confirm-key">${this.tf("picker.section", "Section")}</span><span class="sl-confirm-value">${safe(details.sectionLabel)}</span></div>` : "",
|
|
5875
6021
|
details?.rowLabel || details?.objectType === "booth" ? `<div class="sl-confirm-field"><span class="sl-confirm-key">${safe(this.rowTypeWord(details))}</span><span class="sl-confirm-value">${safe(this.rowShort(details) ?? details?.displayLabel ?? seat.displayLabel ?? seat.label)}</span></div>` : "",
|
|
5876
|
-
details?.objectType !== "booth" ? `<div class="sl-confirm-field"><span class="sl-confirm-key"
|
|
6022
|
+
details?.objectType !== "booth" ? `<div class="sl-confirm-field"><span class="sl-confirm-key">${this.tf("picker.seat", "Seat")}</span><span class="sl-confirm-value">${safe(details?.seatNumber ?? details?.displayLabel ?? seat.displayLabel ?? seat.label)}</span></div>` : ""
|
|
5877
6023
|
].filter(Boolean).join("");
|
|
5878
6024
|
const el2 = document.createElement("div");
|
|
5879
6025
|
el2.className = "sl-confirm";
|
|
5880
6026
|
el2.setAttribute("role", "dialog");
|
|
5881
|
-
el2.setAttribute("aria-label",
|
|
6027
|
+
el2.setAttribute("aria-label", (0, import_core2.t)("picker.confirmSeatLabel", { label: seat.label }));
|
|
5882
6028
|
el2.style.setProperty("--sl-cat", cat?.color ?? "#6e7bff");
|
|
5883
|
-
el2.innerHTML = `<div class="sl-confirm-grid">` + identityFields + `</div><div class="sl-confirm-cat"><span class="sl-dot" style="background:${cat?.color ?? "#6e7bff"}"></span><span class="sl-confirm-cat-name">${safe(details?.categoryLabel ?? cat?.label ?? seat.categoryKey)}</span>` + (price != null ? `<span class="sl-confirm-price">${this.money(price)}</span>` : "") + `</div><div class="sl-confirm-body">` + this.wheelchairConfirmHtml(details?.wheelchairSpaceType) + this.commercialConfirmHtml(seat.commercial) + (this.seatViewEnabled() && this.buyerView !== "venue3d" ? this.confirmThumbHtml(seat) : "") + (this.buyerView === "venue3d" ? `${this.seatConfidenceConfirmHtml(seat, `${details?.displayLabel ?? seat.displayLabel ?? seat.label} \xB7 ${price == null ? this.tf("picker.priceNotSupplied", "Price not supplied") : this.money(price)}`)}<div class="sl-confirm-inspect-row">${this.view3dCompareConfirmHtml(seat)}${this.see3dConfirmHtml()}</div>` : this.see3dConfirmHtml()) + `<div class="sl-confirm-row"><button type="button" class="sl-confirm-cancel"
|
|
6029
|
+
el2.innerHTML = `<div class="sl-confirm-grid">` + identityFields + `</div><div class="sl-confirm-cat"><span class="sl-dot" style="background:${cat?.color ?? "#6e7bff"}"></span><span class="sl-confirm-cat-name">${safe(details?.categoryLabel ?? cat?.label ?? seat.categoryKey)}</span>` + (price != null ? `<span class="sl-confirm-price">${this.money(price)}</span>` : "") + `</div><div class="sl-confirm-body">` + this.wheelchairConfirmHtml(details?.wheelchairSpaceType) + this.commercialConfirmHtml(seat.commercial) + (this.seatViewEnabled() && this.buyerView !== "venue3d" ? this.confirmThumbHtml(seat) : "") + (this.buyerView === "venue3d" ? `${this.seatConfidenceConfirmHtml(seat, `${details?.displayLabel ?? seat.displayLabel ?? seat.label} \xB7 ${price == null ? this.tf("picker.priceNotSupplied", "Price not supplied") : this.money(price)}`)}<div class="sl-confirm-inspect-row">${this.view3dCompareConfirmHtml(seat)}${this.see3dConfirmHtml()}</div>` : this.see3dConfirmHtml()) + `<div class="sl-confirm-row"><button type="button" class="sl-confirm-cancel">${(0, import_core2.t)("common.cancel")}</button><button type="button" class="sl-confirm-add"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5l4 4L19 7"/></svg>${this.tf("picker.select", "Select")}</button></div></div>`;
|
|
5884
6030
|
this.els.map.appendChild(el2);
|
|
5885
6031
|
this.confirmEl = el2;
|
|
5886
6032
|
const thumb = el2.querySelector(".sl-confirm-thumb");
|
|
@@ -6033,7 +6179,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6033
6179
|
el2.className = "sl-view";
|
|
6034
6180
|
el2.setAttribute("role", "dialog");
|
|
6035
6181
|
el2.setAttribute("aria-label", (0, import_core2.t)("picker.viewFromSeat", { label: seat.label }));
|
|
6036
|
-
el2.innerHTML = `<div class="sl-view-head"><span class="sl-view-title">${(0, import_core2.t)("picker.viewFromSeat", { label: seat.label })}</span><span class="sl-view-cap">${caption}</span><button type="button" class="sl-view-x" aria-label="Close"><svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button></div><div class="sl-view-pano"><span class="sl-view-badge">${real ? (0, import_core2.t)("picker.real360") : (0, import_core2.t)("picker.preview")}</span><span class="sl-view-hint"
|
|
6182
|
+
el2.innerHTML = `<div class="sl-view-head"><span class="sl-view-title">${(0, import_core2.t)("picker.viewFromSeat", { label: seat.label })}</span><span class="sl-view-cap">${caption}</span><button type="button" class="sl-view-x" aria-label="${this.tf("picker.close", "Close")}"><svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button></div><div class="sl-view-pano"><span class="sl-view-badge">${real ? (0, import_core2.t)("picker.real360") : (0, import_core2.t)("picker.preview")}</span><span class="sl-view-hint">${this.tf("picker.dragToLookAround", "Drag to look around \xB7 scroll to zoom")}</span></div>`;
|
|
6037
6183
|
this.root.appendChild(el2);
|
|
6038
6184
|
this.viewEl = el2;
|
|
6039
6185
|
const pano = el2.querySelector(".sl-view-pano");
|
|
@@ -6229,27 +6375,27 @@ var SeatPicker = class _SeatPicker {
|
|
|
6229
6375
|
copy.className = "sl-offer-copy";
|
|
6230
6376
|
const kicker = document.createElement("span");
|
|
6231
6377
|
kicker.className = "sl-offer-kicker";
|
|
6232
|
-
kicker.textContent = active ? "Current ticket offer" : "Upcoming ticket offer";
|
|
6378
|
+
kicker.textContent = active ? this.tf("picker.currentTicketOffer", "Current ticket offer") : this.tf("picker.upcomingTicketOffer", "Upcoming ticket offer");
|
|
6233
6379
|
const name = document.createElement("strong");
|
|
6234
6380
|
name.className = "sl-offer-name";
|
|
6235
|
-
name.textContent = offer.name || (active ? "Current offer" : "Scheduled offer");
|
|
6381
|
+
name.textContent = offer.name || (active ? this.tf("picker.currentOffer", "Current offer") : this.tf("picker.scheduledOffer", "Scheduled offer"));
|
|
6236
6382
|
const line = document.createElement("span");
|
|
6237
6383
|
line.className = "sl-offer-line";
|
|
6238
6384
|
const facts = [];
|
|
6239
6385
|
if (active && availability.fromPrice != null) facts.push(this.money(availability.fromPrice / 100));
|
|
6240
|
-
if (active && offer.remaining != null) facts.push(
|
|
6241
|
-
if (active && offer.endsAt != null) facts.push(
|
|
6242
|
-
if (upcoming?.startsAt != null) facts.push(
|
|
6386
|
+
if (active && offer.remaining != null) facts.push((0, import_core2.t)("picker.offerRemainingAvailable", { count: offer.remaining }));
|
|
6387
|
+
if (active && offer.endsAt != null) facts.push((0, import_core2.t)("picker.offerUntil", { time: formatWhen(offer.endsAt, this.eventTimezone, this.opts.locale) }));
|
|
6388
|
+
if (upcoming?.startsAt != null) facts.push((0, import_core2.t)("picker.offerStarts", { time: formatWhen(upcoming.startsAt, this.eventTimezone, this.opts.locale) }));
|
|
6243
6389
|
line.textContent = facts.join(" \xB7 ");
|
|
6244
6390
|
copy.append(kicker, name, line);
|
|
6245
6391
|
const info = document.createElement("details");
|
|
6246
6392
|
info.className = "sl-offer-info";
|
|
6247
6393
|
const summary = document.createElement("summary");
|
|
6248
|
-
summary.setAttribute("aria-label",
|
|
6394
|
+
summary.setAttribute("aria-label", (0, import_core2.t)("picker.howOfferWorks", { name: name.textContent ?? "" }));
|
|
6249
6395
|
summary.textContent = "i";
|
|
6250
6396
|
const detail = document.createElement("div");
|
|
6251
6397
|
detail.className = "sl-offer-detail";
|
|
6252
|
-
detail.textContent = active ?
|
|
6398
|
+
detail.textContent = active ? this.tf("picker.offerDetailActive", "This price applies automatically to eligible seats. Tickets in active carts temporarily reduce the available quantity; released or expired holds return it. When the offer ends, the next matching offer or normal ticket price takes over.") : this.tf("picker.offerDetailUpcoming", "Tickets are available at their normal price now. This scheduled offer will apply automatically to eligible seats when it starts.");
|
|
6253
6399
|
info.append(summary, detail);
|
|
6254
6400
|
main.append(copy, info);
|
|
6255
6401
|
host.replaceChildren(main);
|
|
@@ -6285,8 +6431,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
6285
6431
|
const previous = offer?.previousPrice != null && offer.previousPrice > offer.price ? offer.previousPrice : null;
|
|
6286
6432
|
const active = this.focusedCatKey === c.key;
|
|
6287
6433
|
const dim = this.priceBandKeys != null && !this.priceBandKeys.has(c.key);
|
|
6288
|
-
return `<div class="sl-price-row${dim ? " sl-dim" : ""}${active ? " sl-active" : ""}" data-cat="${escapeOption(c.key)}" role="button" tabindex="0" aria-pressed="${active}" title="${escapeOption(active ? "Show all seats" :
|
|
6289
|
-
}).join("") + (overflow > 1 ? `<button type="button" class="sl-price-more" aria-expanded="${!collapsed}">` + (collapsed ?
|
|
6434
|
+
return `<div class="sl-price-row${dim ? " sl-dim" : ""}${active ? " sl-active" : ""}" data-cat="${escapeOption(c.key)}" role="button" tabindex="0" aria-pressed="${active}" title="${escapeOption(active ? this.tf("picker.showAllSeats", "Show all seats") : (0, import_core2.t)("picker.showLabelSeatsOnMap", { label: c.label }))}"><span class="sl-dot" style="background:${escapeOption(c.color)}"></span><span class="sl-price-label">${escapeOption(c.label)}` + (offer?.offerName ? `<small class="sl-price-offer">${escapeOption(offer.offerName)}</small>` : "") + `</span><span class="sl-price-left">${(0, import_core2.tCount)("picker.leftCount", left[c.key] ?? 0)}</span>` + (previous != null ? `<span class="sl-price-was">${escapeOption(this.money(previous))}</span>` : "") + (price != null ? `<span class="sl-price-amt">${this.money(price)}</span>` : "") + `</div>`;
|
|
6435
|
+
}).join("") + (overflow > 1 ? `<button type="button" class="sl-price-more" aria-expanded="${!collapsed}">` + (collapsed ? (0, import_core2.t)("picker.showAllTicketTypes", { count: doc.categories.length }) : this.tf("picker.showFewer", "Show fewer")) + `</button>` : "") + `<div class="sl-status-key" aria-label="${this.tf("picker.seatStatusLegend", "Seat status legend")}"><span class="sl-status-item"><i class="sl-status-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><rect x="5" y="10" width="14" height="10" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg></i>${this.tf("picker.temporarilyHeld", "Temporarily held")}</span><span class="sl-status-item"><i class="sl-status-icon sold" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M7 17L17 7"/></svg></i>${this.tf("picker.sold", "Sold")}</span></div>`;
|
|
6290
6436
|
this.els.prices.querySelectorAll(".sl-price-row").forEach((row) => {
|
|
6291
6437
|
row.addEventListener("mouseenter", () => this.controller.getRenderer()?.setCategoryHighlight?.(row.dataset.cat ?? null));
|
|
6292
6438
|
row.addEventListener("mouseleave", () => this.controller.getRenderer()?.setCategoryHighlight?.(null));
|
|
@@ -6344,7 +6490,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6344
6490
|
const now = left[cat.key] ?? 0;
|
|
6345
6491
|
if (before === void 0 || now >= before) continue;
|
|
6346
6492
|
const taken = before - now;
|
|
6347
|
-
textEl.textContent =
|
|
6493
|
+
textEl.textContent = (0, import_core2.tCount)("picker.seatsJustTakenInCategory", taken, { label: cat.label, left: now });
|
|
6348
6494
|
this.els.live?.classList.remove("on");
|
|
6349
6495
|
void this.els.live?.offsetWidth;
|
|
6350
6496
|
this.els.live?.classList.add("on");
|
|
@@ -6362,12 +6508,17 @@ var SeatPicker = class _SeatPicker {
|
|
|
6362
6508
|
const gone = this.controller.getSelection().filter((s) => !ownLabels.has(s.label) && (this.controller.getStatus(s.id) ?? "free") !== "free");
|
|
6363
6509
|
if (!gone.length) return;
|
|
6364
6510
|
this.controller.deselect(gone.map((s) => s.id));
|
|
6365
|
-
this.toast(
|
|
6511
|
+
this.toast((0, import_core2.t)("picker.seatJustTakenByAnother", { label: gone[0].label }), "error");
|
|
6366
6512
|
}
|
|
6367
6513
|
syncTray() {
|
|
6368
6514
|
if (!this.els.tray) return;
|
|
6369
6515
|
this.updateSelectionCapacity();
|
|
6370
6516
|
const seats = this.committedSelection();
|
|
6517
|
+
if (this.root?.dataset.layout === "narrow" && this.secCardEl && (this.hold || seats.length || this.pendingGACount())) {
|
|
6518
|
+
this.secCardEl.remove();
|
|
6519
|
+
this.secCardEl = null;
|
|
6520
|
+
this.lastSection = null;
|
|
6521
|
+
}
|
|
6371
6522
|
const gaAreas = this.controller.getGAAreas();
|
|
6372
6523
|
const heldItems = this.hold?.items ?? [];
|
|
6373
6524
|
const parts = [];
|
|
@@ -6378,18 +6529,22 @@ var SeatPicker = class _SeatPicker {
|
|
|
6378
6529
|
`<div class="sl-closed-note" role="status"><b>${this.tf("picker.salesClosedPill", "Sales are closed")}</b><span>${this.tf("picker.salesClosedCopy", "Ticket sales for this event have ended.")}${closedWhen}</span></div>`
|
|
6379
6530
|
);
|
|
6380
6531
|
} else if (!seats.length && !heldItems.length && !gaAreas.length) {
|
|
6381
|
-
parts.push(`<div class="sl-tray-hint"
|
|
6532
|
+
parts.push(`<div class="sl-tray-hint">${this.tf("picker.trayHintTapOrBest", "Tap a seat on the map, or let us pick the best available for you.")}</div>`);
|
|
6382
6533
|
} else if (!seats.length && !heldItems.length) {
|
|
6383
|
-
parts.push(`<div class="sl-tray-hint"
|
|
6534
|
+
parts.push(`<div class="sl-tray-hint">${this.tf("picker.trayHintTapOrStanding", "Tap a seat on the map \u2014 or grab standing tickets below.")}</div>`);
|
|
6384
6535
|
}
|
|
6385
6536
|
const noPicks = !seats.length && !heldItems.length && !this.pendingGACount();
|
|
6386
|
-
if (
|
|
6537
|
+
if (noPicks) this.baReopen = false;
|
|
6538
|
+
if (!this.salesClosed && !this.hold && (noPicks || this.baReopen || this.bestAvailableBusy || this.bestAvailableConfirm)) {
|
|
6387
6539
|
const cats = this.controller.doc?.categories ?? [];
|
|
6388
6540
|
const zones = this.controller.getBestAvailableZones();
|
|
6389
6541
|
if (this.baZone && !zones.some((zone) => zone.id === this.baZone)) this.baZone = "";
|
|
6390
|
-
parts.push(this.bestAvailableConfirm ? `<div class="sl-ba" role="alert"><div class="sl-ba-title"><span class="spark" aria-hidden="true">\u2726</span
|
|
6542
|
+
parts.push(this.bestAvailableConfirm ? `<div class="sl-ba" role="alert"><div class="sl-ba-title"><span class="spark" aria-hidden="true">\u2726</span>${this.tf("picker.replaceCurrentChoices", "Replace your current choices?")}</div><div class="sl-ba-replace"><b>${(0, import_core2.t)("picker.willFindSeatsTogether", { count: this.baQty })}</b><span>${this.tf("picker.manualTicketsRemovedNote", "Your manually selected tickets will be removed only after a new group is secured.")}</span></div><div class="sl-ba-actions"><button type="button" data-ba-cancel>${this.tf("picker.keepMine", "Keep mine")}</button><button type="button" class="replace" data-ba-replace>${this.tf("picker.findNewSeats", "Find new seats")}</button></div></div>` : `<div class="sl-ba"><div class="sl-ba-title"><span class="spark" aria-hidden="true">\u2726</span>${this.tf("picker.findBestSeatsTogether", "Find the best seats together")}</div><div class="sl-ba-copy"><span class="wide">${this.tf("picker.willChooseClosestGroup", "We\u2019ll choose the closest available group for you.")}</span><span class="narrow">${this.tf("picker.closestGroupChosenInstantly", "Closest available group, chosen instantly.")}</span></div>` + // Premium quick-pick — present only when the chart actually has premium
|
|
6391
6543
|
// seats (same present-only philosophy as the a11y filter chips).
|
|
6392
|
-
(this.controller.hasPremiumSeats() ? `<button type="button" class="sl-ba-premium${this.baPremium ? " on" : ""}" data-ba-premium aria-pressed="${this.baPremium ? "true" : "false"}"><span class="star" aria-hidden="true">\u2605</span>${this.tf("picker.bestSeatsPremium", "Best seats")}</button>` : "") + (cats.length > 1 ? `<select aria-label="Preferred ticket type" data-ba-cat><option value=""
|
|
6544
|
+
(this.controller.hasPremiumSeats() ? `<button type="button" class="sl-ba-premium${this.baPremium ? " on" : ""}" data-ba-premium aria-pressed="${this.baPremium ? "true" : "false"}"><span class="star" aria-hidden="true">\u2605</span>${this.tf("picker.bestSeatsPremium", "Best seats")}</button>` : "") + (cats.length > 1 ? `<select aria-label="${this.tf("picker.preferredTicketType", "Preferred ticket type")}" data-ba-cat><option value="">${this.tf("picker.anyTicketType", "Any ticket type")}</option>` + cats.map((c) => `<option value="${c.key}"${this.baCat === c.key ? " selected" : ""}>${c.label}</option>`).join("") + `</select>` : `<span aria-hidden="true"></span>`) + (zones.length ? `<select aria-label="${this.tf("picker.preferredVenueZone", "Preferred venue zone")}" data-ba-zone><option value="">${this.tf("picker.anyVenueZone", "Any venue zone")}</option>` + zones.map((zone) => `<option value="${escapeOption(zone.id)}"${this.baZone === zone.id ? " selected" : ""}>${escapeOption(zone.label)}</option>`).join("") + `</select>` : "") + `<div class="sl-ba-qty"><button type="button" data-ba="-1" aria-label="${this.tf("picker.fewerSeats", "Fewer seats")}">\u2212</button><span>${this.baQty}</span><button type="button" data-ba="1" aria-label="${this.tf("picker.moreSeats", "More seats")}">+</button></div><button type="button" class="sl-ba-go${this.bestAvailableBusy ? " sl-busy" : ""}"${this.bestAvailableBusy ? " disabled" : ""}>` + (this.bestAvailableBusy ? `<span class="sl-ba-spin" aria-hidden="true"></span>${this.tf("picker.findingBestSeats", "Finding the best seats\u2026")}` : (0, import_core2.tCount)("picker.findBestSeatsCount", this.baQty)) + `</button>` + // Reopened over an existing selection: the buyer needs the way back
|
|
6545
|
+
// stated as plainly as the way forward (Go routes through the
|
|
6546
|
+
// "Replace your current choices?" confirm, so nothing is lost yet).
|
|
6547
|
+
(this.baReopen ? `<button type="button" class="sl-ba-back" data-ba-close>${this.tf("picker.keepMyPicks", "Keep my picks")}</button>` : "") + `</div>`);
|
|
6393
6548
|
}
|
|
6394
6549
|
const idGrid = (seatId, label, objectType, quantity = 1, objectId, identity) => {
|
|
6395
6550
|
const esc = (value) => String(value ?? "\u2014").replace(/[&<>"]/g, (char) => ({
|
|
@@ -6401,21 +6556,21 @@ var SeatPicker = class _SeatPicker {
|
|
|
6401
6556
|
const d = seatId ? this.controller.seatDetails(seatId) : null;
|
|
6402
6557
|
const area = objectType === "ga" ? gaAreas.find((candidate) => candidate.id === objectId) : void 0;
|
|
6403
6558
|
const effectiveType = objectType === "ga" ? "ga" : d?.objectType ?? objectType;
|
|
6404
|
-
const typeWord = identity?.displayType?.trim() || d?.displayType?.trim() || area?.displayType?.trim() || (effectiveType === "table" ? "Table" : effectiveType === "booth" ? "Booth" : effectiveType === "ga" ? "General admission" : "Row");
|
|
6559
|
+
const typeWord = identity?.displayType?.trim() || d?.displayType?.trim() || area?.displayType?.trim() || (effectiveType === "table" ? this.tf("picker.table", "Table") : effectiveType === "booth" ? this.tf("picker.booth", "Booth") : effectiveType === "ga" ? this.tf("picker.generalAdmission", "General admission") : this.tf("picker.row", "Row"));
|
|
6405
6560
|
const buyerName = identity?.rowLabel ?? identity?.displayLabel ?? d?.rowLabel ?? d?.displayLabel ?? area?.displayLabel ?? area?.label ?? label;
|
|
6406
6561
|
if (effectiveType === "table" && identity?.bookingMode) {
|
|
6407
|
-
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(buyerName)}</span></span><span class="fld mid"><span class="sl-chip-eb"
|
|
6562
|
+
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(buyerName)}</span></span><span class="fld mid"><span class="sl-chip-eb">${this.tf("picker.guests", "Guests")}</span><span class="val">${quantity}</span></span></div>`;
|
|
6408
6563
|
}
|
|
6409
6564
|
if (effectiveType === "ga") {
|
|
6410
|
-
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(buyerName)}</span></span>` + (quantity > 1 ? `<span class="fld mid"><span class="sl-chip-eb"
|
|
6565
|
+
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(buyerName)}</span></span>` + (quantity > 1 ? `<span class="fld mid"><span class="sl-chip-eb">${this.tf("picker.tickets", "Tickets")}</span><span class="val">${quantity}</span></span>` : "") + `</div>`;
|
|
6411
6566
|
}
|
|
6412
6567
|
if (effectiveType === "booth") {
|
|
6413
|
-
return `<div class="sl-chip-id">` + (d?.sectionLabel ? `<span class="fld sec"><span class="sl-chip-eb"
|
|
6568
|
+
return `<div class="sl-chip-id">` + (d?.sectionLabel ? `<span class="fld sec"><span class="sl-chip-eb">${this.tf("picker.section", "Section")}</span><span class="val">${esc(d.sectionLabel)}</span></span>` : "") + `<span class="fld mid"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(buyerName)}</span></span></div>`;
|
|
6414
6569
|
}
|
|
6415
6570
|
if (!d?.sectionLabel && !d?.rowLabel && !d?.seatNumber) {
|
|
6416
|
-
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb"
|
|
6571
|
+
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb">${this.tf("picker.seat", "Seat")}</span><span class="val">${esc(buyerName)}</span></span></div>`;
|
|
6417
6572
|
}
|
|
6418
|
-
return `<div class="sl-chip-id">` + (d.sectionLabel ? `<span class="fld sec"><span class="sl-chip-eb"
|
|
6573
|
+
return `<div class="sl-chip-id">` + (d.sectionLabel ? `<span class="fld sec"><span class="sl-chip-eb">${this.tf("picker.section", "Section")}</span><span class="val">${esc(d.sectionLabel)}</span></span>` : "") + (d.rowLabel ? `<span class="fld mid"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(this.rowShort(d))}</span></span>` : "") + (d.seatNumber ? `<span class="fld mid"><span class="sl-chip-eb">${this.tf("picker.seat", "Seat")}</span><span class="val">${esc(d.seatNumber)}</span></span>` : "") + `</div>`;
|
|
6419
6574
|
};
|
|
6420
6575
|
const iconRail = (rmAria, viewLabel) => `<div class="sl-chip-rail"><button type="button" class="rm" aria-label="${rmAria}"><svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>` + (viewLabel ? `<button type="button" class="view" data-view-label="${viewLabel}" aria-label="${(0, import_core2.t)("picker.viewFromSeat", { label: viewLabel })}"><svg viewBox="0 0 24 24"><path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg></button>` : "") + `</div>`;
|
|
6421
6576
|
for (const item of heldItems) {
|
|
@@ -6427,7 +6582,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6427
6582
|
const table = item.objectType === "table" ? this.controller.tableSelection(item.label) : null;
|
|
6428
6583
|
const canView2 = this.seatViewEnabled() && !!heldSeat && item.objectType !== "table";
|
|
6429
6584
|
parts.push(
|
|
6430
|
-
`<div class="sl-chip sl-held${this.lastTrayKeys.has(itemKey) ? "" : " sl-enter"}" data-key="${itemKey}" data-held="${encodeURIComponent(item.label)}"${heldSeat ? ` data-locate="${heldSeat.id}"` : ""}><div class="sl-chip-main">` + idGrid(heldSeat?.id ?? null, item.label, item.objectType, item.quantity ?? 1, item.objectId, table ?? void 0) + `<div class="sl-chip-sub"><span class="sl-ticket-state held" aria-label="Held for you" title="Held for you"><svg viewBox="0 0 24 24"><rect x="5" y="10" width="14" height="10" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg></span><span class="cat">${cat?.label ?? item.categoryKey}${tierName ? ` \xB7 ${tierName}` : ""}</span>` + (table?.bookingMode === "variable" ? `<button type="button" class="sl-table-edit" data-table-edit="${encodeURIComponent(item.label)}">${item.quantity ?? 1}
|
|
6585
|
+
`<div class="sl-chip sl-held${this.lastTrayKeys.has(itemKey) ? "" : " sl-enter"}" data-key="${itemKey}" data-held="${encodeURIComponent(item.label)}"${heldSeat ? ` data-locate="${heldSeat.id}"` : ""}><div class="sl-chip-main">` + idGrid(heldSeat?.id ?? null, item.label, item.objectType, item.quantity ?? 1, item.objectId, table ?? void 0) + `<div class="sl-chip-sub"><span class="sl-ticket-state held" aria-label="${this.tf("picker.heldForYou", "Held for you")}" title="${this.tf("picker.heldForYou", "Held for you")}"><svg viewBox="0 0 24 24"><rect x="5" y="10" width="14" height="10" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg></span><span class="cat">${cat?.label ?? item.categoryKey}${tierName ? ` \xB7 ${tierName}` : ""}</span>` + (table?.bookingMode === "variable" ? `<button type="button" class="sl-table-edit" data-table-edit="${encodeURIComponent(item.label)}">${(0, import_core2.t)("picker.guestsCountEdit", { count: item.quantity ?? 1 })}</button>` : "") + this.wheelchairChipMarker(heldSeat?.wheelchairSpaceType) + this.commercialChipMarker(heldSeat?.commercial) + `<span class="amt">${this.money(this.paidPrice(item.categoryKey, item.tierId, item.unitPrice) * (item.quantity ?? 1))}</span></div></div>` + iconRail((0, import_core2.t)("picker.removeHeldTicketLabel", { label: item.label }), canView2 ? item.label : null) + `</div>`
|
|
6431
6586
|
);
|
|
6432
6587
|
}
|
|
6433
6588
|
const heldLabels = new Set(heldItems.map((item) => item.label));
|
|
@@ -6438,13 +6593,18 @@ var SeatPicker = class _SeatPicker {
|
|
|
6438
6593
|
const cat = this.controller.doc?.categories.find((c) => c.key === s.categoryKey);
|
|
6439
6594
|
const tierSelect = s.tiers && s.tiers.length ? `<select class="tier" data-tier="${s.id}" aria-label="${(0, import_core2.t)("picker.ticketTierFor", { label: s.label })}">` + s.tiers.map((ti) => `<option value="${ti.id}"${ti.id === s.tierId ? " selected" : ""}>${ti.name} \xB7 ${this.money(this.paidPrice(s.categoryKey, ti.id, ti.price))}</option>`).join("") + `</select>` : "";
|
|
6440
6595
|
parts.push(
|
|
6441
|
-
`<div class="sl-chip${this.lastTrayKeys.has(itemKey) ? "" : " sl-enter"}" data-key="${itemKey}" data-seat="${s.id}" data-locate="${s.id}"><div class="sl-chip-main">` + idGrid(s.id, s.label, s.objectType, s.quantity ?? 1, s.objectId, s) + `<div class="sl-chip-sub"><span class="sl-ticket-state" aria-label="Selected" title="Selected"><svg viewBox="0 0 24 24"><path d="M5 12l4 4L19 6"/></svg></span><span class="cat">${cat?.label ?? s.categoryKey}</span>` + (s.objectType === "table" && s.bookingMode === "variable" ? `<button type="button" class="sl-table-edit" data-table-edit="${encodeURIComponent(s.label)}">${s.quantity ?? 1}
|
|
6596
|
+
`<div class="sl-chip${this.lastTrayKeys.has(itemKey) ? "" : " sl-enter"}" data-key="${itemKey}" data-seat="${s.id}" data-locate="${s.id}"><div class="sl-chip-main">` + idGrid(s.id, s.label, s.objectType, s.quantity ?? 1, s.objectId, s) + `<div class="sl-chip-sub"><span class="sl-ticket-state" aria-label="${this.tf("picker.selected", "Selected")}" title="${this.tf("picker.selected", "Selected")}"><svg viewBox="0 0 24 24"><path d="M5 12l4 4L19 6"/></svg></span><span class="cat">${cat?.label ?? s.categoryKey}</span>` + (s.objectType === "table" && s.bookingMode === "variable" ? `<button type="button" class="sl-table-edit" data-table-edit="${encodeURIComponent(s.label)}">${(0, import_core2.t)("picker.guestsCountEdit", { count: s.quantity ?? 1 })}</button>` : "") + `${this.wheelchairChipMarker(s.wheelchairSpaceType)}${this.commercialChipMarker(s.commercial)}${tierSelect}<span class="amt">${this.money(this.paidPrice(s.categoryKey, s.tierId ?? null, s.price) * (s.quantity ?? 1))}</span></div></div>` + iconRail((0, import_core2.t)("picker.removeSeatLabel", { label: s.label }), canView && s.objectType !== "table" ? s.label : null) + `</div>`
|
|
6442
6597
|
);
|
|
6443
6598
|
}
|
|
6444
6599
|
for (const area of gaAreas) {
|
|
6445
6600
|
const qty = this.gaQty.get(area.id) ?? 0;
|
|
6446
6601
|
parts.push(
|
|
6447
|
-
`<div class="sl-ga" data-ga="${area.id}"><div class="sl-ga-info"><div class="sl-ga-name">${area.displayLabel ?? area.label}</div><div class="sl-ga-sub">${area.displayType ?? "General admission"} \xB7 ${this.money(this.paidPrice(area.categoryKey, null, area.price))} \xB7 ${area.available}
|
|
6602
|
+
`<div class="sl-ga" data-ga="${area.id}"><div class="sl-ga-info"><div class="sl-ga-name">${area.displayLabel ?? area.label}</div><div class="sl-ga-sub">${area.displayType ?? this.tf("picker.generalAdmission", "General admission")} \xB7 ${this.money(this.paidPrice(area.categoryKey, null, area.price))} \xB7 ${(0, import_core2.tCount)("picker.leftCount", area.available)}</div></div><div class="sl-ga-qty"><button type="button" data-d="-1" aria-label="${this.tf("picker.fewer", "Fewer")}">\u2212</button><span>${qty}</span><button type="button" data-d="1" aria-label="${this.tf("picker.more", "More")}">+</button></div></div>`
|
|
6603
|
+
);
|
|
6604
|
+
}
|
|
6605
|
+
if (!this.salesClosed && !this.hold && !noPicks && !this.baReopen && !this.bestAvailableBusy && !this.bestAvailableConfirm) {
|
|
6606
|
+
parts.push(
|
|
6607
|
+
`<button type="button" class="sl-ba-reopen" data-ba-reopen><span aria-hidden="true">\u2726</span>${this.tf("picker.findTogetherInstead", "Find seats together instead")}</button>`
|
|
6448
6608
|
);
|
|
6449
6609
|
}
|
|
6450
6610
|
this.els.tray.innerHTML = parts.join("");
|
|
@@ -6479,6 +6639,16 @@ var SeatPicker = class _SeatPicker {
|
|
|
6479
6639
|
this.syncTray();
|
|
6480
6640
|
this.els.tray.querySelector(".sl-ba-go")?.focus();
|
|
6481
6641
|
});
|
|
6642
|
+
this.els.tray.querySelector("[data-ba-reopen]")?.addEventListener("click", () => {
|
|
6643
|
+
this.baReopen = true;
|
|
6644
|
+
this.syncTray();
|
|
6645
|
+
this.els.tray.querySelector(".sl-ba-go")?.focus();
|
|
6646
|
+
});
|
|
6647
|
+
this.els.tray.querySelector("[data-ba-close]")?.addEventListener("click", () => {
|
|
6648
|
+
this.baReopen = false;
|
|
6649
|
+
this.syncTray();
|
|
6650
|
+
this.els.tray.querySelector("[data-ba-reopen]")?.focus();
|
|
6651
|
+
});
|
|
6482
6652
|
this.els.tray.querySelector("[data-ba-replace]")?.addEventListener("click", () => {
|
|
6483
6653
|
this.bestAvailableConfirm = false;
|
|
6484
6654
|
void this.bestAvailable(this.baQty, this.baCat || void 0, { preferPremium: this.baPremium, zoneId: this.baZone || void 0 });
|
|
@@ -6491,15 +6661,15 @@ var SeatPicker = class _SeatPicker {
|
|
|
6491
6661
|
return;
|
|
6492
6662
|
}
|
|
6493
6663
|
const id = chip.dataset.seat;
|
|
6494
|
-
const label = this.controller.getSelection().find((sel) => sel.id === id)?.label ?? "Seat";
|
|
6664
|
+
const label = this.controller.getSelection().find((sel) => sel.id === id)?.label ?? this.tf("picker.seat", "Seat");
|
|
6495
6665
|
const remove = () => {
|
|
6496
6666
|
this.controller.deselect([id]);
|
|
6497
|
-
this.toast(
|
|
6498
|
-
label: "Undo",
|
|
6667
|
+
this.toast((0, import_core2.t)("picker.labelRemoved", { label }), "neutral", {
|
|
6668
|
+
label: this.tf("picker.undo", "Undo"),
|
|
6499
6669
|
onClick: () => {
|
|
6500
6670
|
const restored = this.controller.select([id]);
|
|
6501
6671
|
this.toast(
|
|
6502
|
-
restored.length ?
|
|
6672
|
+
restored.length ? (0, import_core2.t)("picker.labelRestored", { label }) : (0, import_core2.t)("picker.labelNoLongerAvailable", { label }),
|
|
6503
6673
|
restored.length ? "success" : "warning"
|
|
6504
6674
|
);
|
|
6505
6675
|
}
|
|
@@ -6571,30 +6741,31 @@ var SeatPicker = class _SeatPicker {
|
|
|
6571
6741
|
const pendingCount = this.pendingSelectionCount();
|
|
6572
6742
|
const previousCount = this.lastTrayCount;
|
|
6573
6743
|
const previousTotal = this.lastTrayTotal;
|
|
6574
|
-
this.els.count.textContent = count ?
|
|
6744
|
+
this.els.count.textContent = count ? (0, import_core2.tCount)("picker.ticketsCount", count) : this.tf("picker.noSeatsSelected", "No seats selected");
|
|
6575
6745
|
this.els.total.textContent = count ? this.money(total) : "";
|
|
6576
6746
|
this.root?.setAttribute("data-has-selection", String(count > 0));
|
|
6577
6747
|
this.root?.setAttribute(
|
|
6578
6748
|
"data-ba-active",
|
|
6579
|
-
String(this.bestAvailableConfirm || this.bestAvailableBusy)
|
|
6749
|
+
String(this.bestAvailableConfirm || this.bestAvailableBusy || this.baReopen)
|
|
6580
6750
|
);
|
|
6581
6751
|
this.els.foot?.classList.toggle("empty", count === 0);
|
|
6582
6752
|
if (this.els.seatSummary) {
|
|
6583
|
-
this.els.seatSummary.textContent = count ?
|
|
6753
|
+
this.els.seatSummary.textContent = count ? (0, import_core2.tCount)("picker.seatsSelectedCount", count) : "";
|
|
6584
6754
|
}
|
|
6585
6755
|
this.syncCta(count, pendingCount);
|
|
6586
6756
|
if (this.hold) {
|
|
6587
6757
|
const securedCount = heldCount || this.hold.seats?.length || 0;
|
|
6588
6758
|
if (this.els.holdTitle) {
|
|
6589
|
-
this.els.holdTitle.textContent =
|
|
6759
|
+
this.els.holdTitle.textContent = (0, import_core2.t)("picker.securedCount", { count: securedCount });
|
|
6590
6760
|
}
|
|
6591
6761
|
if (this.els.holdCopy) {
|
|
6592
|
-
this.
|
|
6762
|
+
this.holdCopyPending = pendingCount > 0;
|
|
6763
|
+
this.els.holdCopy.textContent = pendingCount ? (0, import_core2.t)("picker.moreSelectedCount", { count: pendingCount }) : this.holdReassuranceText();
|
|
6593
6764
|
}
|
|
6594
6765
|
const change = this.els.holdChange;
|
|
6595
6766
|
if (change) {
|
|
6596
6767
|
change.disabled = this.releasingHold;
|
|
6597
|
-
change.textContent = this.releasingHold ? "Releasing\u2026" : "Change";
|
|
6768
|
+
change.textContent = this.releasingHold ? this.tf("picker.releasingEllipsis", "Releasing\u2026") : this.tf("picker.change", "Change");
|
|
6598
6769
|
}
|
|
6599
6770
|
}
|
|
6600
6771
|
if (count !== previousCount) this.animateOnce(this.els.count, "sl-value-pop", 380);
|
|
@@ -6603,21 +6774,39 @@ var SeatPicker = class _SeatPicker {
|
|
|
6603
6774
|
this.animateOnce(this.els.cta, "sl-ready", 520);
|
|
6604
6775
|
if (this.sideCollapsed && this.root?.dataset.layout !== "narrow") this.setPanelCollapsed(false);
|
|
6605
6776
|
}
|
|
6606
|
-
|
|
6607
|
-
if (count) {
|
|
6608
|
-
const holding = !!this.hold && !pendingCount;
|
|
6609
|
-
this.els.peek.innerHTML = `<span>${count} ${count === 1 ? "ticket" : "tickets"} \xB7 ${this.money(total)}</span><button type="button" class="go sl-sheet-go" data-act="${holding ? "checkout" : "open"}">${this.hold ? pendingCount ? "Secure more" : "Continue" : "Review"}</button>`;
|
|
6610
|
-
} else if (this.salesClosed) {
|
|
6611
|
-
this.els.peek.innerHTML = `<span>${this.tf("picker.salesClosedPill", "Sales are closed")}</span>`;
|
|
6612
|
-
} else {
|
|
6613
|
-
const prices = (this.controller.doc?.categories ?? []).map((c) => this.catPrice(c)).filter((p) => p != null);
|
|
6614
|
-
this.els.peek.innerHTML = (prices.length ? `<span>From ${this.money(Math.min(...prices))}</span>` : "<span>Pick your seats</span>") + `<button type="button" class="go sl-sheet-go" data-act="open">\u2726 Best seats</button>`;
|
|
6615
|
-
}
|
|
6616
|
-
}
|
|
6777
|
+
this.renderPeek(count, total, pendingCount);
|
|
6617
6778
|
this.lastTrayCount = count;
|
|
6618
6779
|
this.lastTrayTotal = total;
|
|
6619
6780
|
this.opts.onSelectionChange?.(seats);
|
|
6620
6781
|
}
|
|
6782
|
+
/**
|
|
6783
|
+
* The bottom-sheet's collapsed one-liner. Called from syncTray on every
|
|
6784
|
+
* repaint AND from setCtaPhase: while the widget is securing seats or
|
|
6785
|
+
* opening checkout, the peek is the phone buyer's ONLY line of sight, and a
|
|
6786
|
+
* pill still reading "Continue" at the moment money is about to move is the
|
|
6787
|
+
* emotional trapdoor the audit flagged. The phase lines restate what is
|
|
6788
|
+
* secured and promise no charge yet.
|
|
6789
|
+
*/
|
|
6790
|
+
renderPeek(count, total, pendingCount) {
|
|
6791
|
+
if (!this.els.peek) return;
|
|
6792
|
+
if (count && this.ctaPhase === "holding") {
|
|
6793
|
+
this.els.peek.innerHTML = `<span>${this.tf("picker.securingSeats", "Securing your seats\u2026")}</span>`;
|
|
6794
|
+
return;
|
|
6795
|
+
}
|
|
6796
|
+
if (count && this.ctaPhase === "checkout") {
|
|
6797
|
+
this.els.peek.innerHTML = `<span>${(0, import_core2.t)("picker.peekSecured", { count, total: this.money(total) })}</span>`;
|
|
6798
|
+
return;
|
|
6799
|
+
}
|
|
6800
|
+
if (count) {
|
|
6801
|
+
const toCheckout = !!this.hold;
|
|
6802
|
+
this.els.peek.innerHTML = `<span>${(0, import_core2.tCount)("picker.peekTicketsTotal", count, { total: this.money(total) })}</span><button type="button" class="go sl-sheet-go" data-act="${toCheckout ? "checkout" : "open"}">${this.hold ? pendingCount ? this.tf("picker.secureMore", "Secure more") : this.tf("picker.continue", "Continue") : this.tf("picker.review", "Review")}</button>`;
|
|
6803
|
+
} else if (this.salesClosed) {
|
|
6804
|
+
this.els.peek.innerHTML = `<span>${this.tf("picker.salesClosedPill", "Sales are closed")}</span>`;
|
|
6805
|
+
} else {
|
|
6806
|
+
const prices = (this.controller.doc?.categories ?? []).map((c) => this.catPrice(c)).filter((p) => p != null);
|
|
6807
|
+
this.els.peek.innerHTML = (prices.length ? `<span>${(0, import_core2.t)("picker.peekFromPrice", { price: this.money(Math.min(...prices)) })}</span>` : `<span>${this.tf("picker.pickYourSeats", "Pick your seats")}</span>`) + `<button type="button" class="go sl-sheet-go" data-act="open">${this.tf("picker.bestSeatsStar", "\u2726 Best seats")}</button>`;
|
|
6808
|
+
}
|
|
6809
|
+
}
|
|
6621
6810
|
async removeHeldLabel(label, chip) {
|
|
6622
6811
|
if (!label || this.releasingLabels.has(label)) return false;
|
|
6623
6812
|
this.releasingLabels.add(label);
|
|
@@ -6628,7 +6817,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6628
6817
|
const preserveAcrossNavigation = this.handedOff;
|
|
6629
6818
|
const released = await this.controller.releaseLabels([label]);
|
|
6630
6819
|
if (!released) {
|
|
6631
|
-
this.toast(
|
|
6820
|
+
this.toast((0, import_core2.t)("picker.couldNotRemoveLabel", { label }), "error");
|
|
6632
6821
|
return false;
|
|
6633
6822
|
}
|
|
6634
6823
|
const remaining = this.controller.currentHold();
|
|
@@ -6644,7 +6833,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6644
6833
|
}
|
|
6645
6834
|
this.syncTray();
|
|
6646
6835
|
this.emitHoldChange();
|
|
6647
|
-
this.toast(
|
|
6836
|
+
this.toast((0, import_core2.t)("picker.labelRemovedFromHold", { label }), "success");
|
|
6648
6837
|
return true;
|
|
6649
6838
|
} finally {
|
|
6650
6839
|
this.releasingLabels.delete(label);
|
|
@@ -6658,23 +6847,23 @@ var SeatPicker = class _SeatPicker {
|
|
|
6658
6847
|
const button = this.els.holdChange;
|
|
6659
6848
|
if (button) {
|
|
6660
6849
|
button.disabled = true;
|
|
6661
|
-
button.textContent = "Releasing\u2026";
|
|
6850
|
+
button.textContent = this.tf("picker.releasingEllipsis", "Releasing\u2026");
|
|
6662
6851
|
}
|
|
6663
6852
|
try {
|
|
6664
6853
|
await this.release();
|
|
6665
|
-
if (!this.hold) this.toast("Held tickets released. Choose your new seats.", "success");
|
|
6854
|
+
if (!this.hold) this.toast(this.tf("picker.heldTicketsReleased", "Held tickets released. Choose your new seats."), "success");
|
|
6666
6855
|
} finally {
|
|
6667
6856
|
this.releasingHold = false;
|
|
6668
6857
|
if (button?.isConnected) {
|
|
6669
6858
|
button.disabled = false;
|
|
6670
|
-
button.textContent = "Change";
|
|
6859
|
+
button.textContent = this.tf("picker.change", "Change");
|
|
6671
6860
|
}
|
|
6672
6861
|
}
|
|
6673
6862
|
}
|
|
6674
6863
|
async handleCta() {
|
|
6675
6864
|
if (this.salesClosed) return;
|
|
6676
6865
|
if (this.totalTicketCount() > this.maxTickets) {
|
|
6677
|
-
this.toast(
|
|
6866
|
+
this.toast((0, import_core2.t)("picker.removeTicketsUntilOrFewer", { count: this.maxTickets }), "warning");
|
|
6678
6867
|
return;
|
|
6679
6868
|
}
|
|
6680
6869
|
const committed = this.committedSelection();
|
|
@@ -6700,7 +6889,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6700
6889
|
hold = h ? { holdId: h.holdId, expiresAt: h.expiresAt, seats: h.seats, items: h.items } : hold;
|
|
6701
6890
|
}
|
|
6702
6891
|
if (!hold) {
|
|
6703
|
-
this.toast("One or more seats were just taken. Please pick again.", "error");
|
|
6892
|
+
this.toast(this.tf("picker.seatsJustTaken", "One or more seats were just taken. Please pick again."), "error");
|
|
6704
6893
|
this.setCtaPhase("idle");
|
|
6705
6894
|
this.syncTray();
|
|
6706
6895
|
return;
|
|
@@ -6717,7 +6906,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6717
6906
|
const problem = err;
|
|
6718
6907
|
const labels = (problem.conflicts ?? []).map((conflict) => conflict.label).filter(Boolean).slice(0, 3);
|
|
6719
6908
|
if (problem.reason === "event_closed") this.setSalesClosed(true);
|
|
6720
|
-
const message = problem.reason === "event_closed" ? "Seat sales have closed for this event." : labels.length ?
|
|
6909
|
+
const message = problem.reason === "event_closed" ? this.tf("picker.seatSalesClosedForEvent", "Seat sales have closed for this event.") : labels.length ? labels.length === 1 ? (0, import_core2.t)("picker.labelsNoLongerAvailable.one", { labels: labels.join(", ") }) : (0, import_core2.t)("picker.labelsNoLongerAvailable.other", { labels: labels.join(", ") }) : this.tf("picker.seatsJustTaken", "One or more seats were just taken. Please pick again.");
|
|
6721
6910
|
this.toast(message, "error");
|
|
6722
6911
|
this.setCtaPhase("idle");
|
|
6723
6912
|
} finally {
|
|
@@ -6726,12 +6915,19 @@ var SeatPicker = class _SeatPicker {
|
|
|
6726
6915
|
this.syncTray();
|
|
6727
6916
|
}
|
|
6728
6917
|
}
|
|
6918
|
+
/** "Yours for m:ss — you won't be charged yet." — the hold note's promise. */
|
|
6919
|
+
holdReassuranceText() {
|
|
6920
|
+
const ms = Math.max(0, this.holdExpiresAt - Date.now());
|
|
6921
|
+
const m = Math.floor(ms / 6e4);
|
|
6922
|
+
const s = String(Math.floor(ms % 6e4 / 1e3)).padStart(2, "0");
|
|
6923
|
+
return (0, import_core2.t)("picker.holdReassurance", { time: `${m}:${s}` });
|
|
6924
|
+
}
|
|
6729
6925
|
startHoldTimer(expiresAt) {
|
|
6730
6926
|
this.stopHoldTimer();
|
|
6731
6927
|
this.holdExpiresAt = expiresAt;
|
|
6732
6928
|
if (this.hold) this.rememberHold(this.hold);
|
|
6733
6929
|
const pill = this.els.hold;
|
|
6734
|
-
pill.innerHTML =
|
|
6930
|
+
pill.innerHTML = `<span class="sl-hold-dot" aria-hidden="true"></span><span>${this.tf("picker.held", "Held")}</span><span class="sl-hold-time" data-ref="holdTime"></span>`;
|
|
6735
6931
|
const time = pill.querySelector('[data-ref="holdTime"]');
|
|
6736
6932
|
this.els.holdNote?.classList.add("on");
|
|
6737
6933
|
const tick = () => {
|
|
@@ -6739,6 +6935,9 @@ var SeatPicker = class _SeatPicker {
|
|
|
6739
6935
|
const m = Math.floor(ms / 6e4);
|
|
6740
6936
|
const s = String(Math.floor(ms % 6e4 / 1e3)).padStart(2, "0");
|
|
6741
6937
|
if (time) time.textContent = `${m}:${s}`;
|
|
6938
|
+
if (!this.holdCopyPending && this.els.holdCopy) {
|
|
6939
|
+
this.els.holdCopy.textContent = this.holdReassuranceText();
|
|
6940
|
+
}
|
|
6742
6941
|
pill.classList.add("on");
|
|
6743
6942
|
pill.classList.toggle("is-expiring", ms > 0 && ms <= EXTEND_PROMPT_MS);
|
|
6744
6943
|
this.setExtendPrompt(ms > 0 && ms <= EXTEND_PROMPT_MS, ms);
|
|
@@ -6758,8 +6957,10 @@ var SeatPicker = class _SeatPicker {
|
|
|
6758
6957
|
setExtendPrompt(show, ms) {
|
|
6759
6958
|
if (!this.extendEl) return;
|
|
6760
6959
|
if (show && this.controller.currentHold() && !this.bookedShown) {
|
|
6761
|
-
const
|
|
6762
|
-
|
|
6960
|
+
const totalSecs = Math.ceil(ms / 1e3);
|
|
6961
|
+
const m = Math.floor(totalSecs / 60);
|
|
6962
|
+
const s = String(totalSecs % 60).padStart(2, "0");
|
|
6963
|
+
this.els.extendTxt.innerHTML = (0, import_core2.t)("picker.seatsHeldForNeedMoreTime", { time: `${m}:${s}` });
|
|
6763
6964
|
this.extendEl.classList.add("on");
|
|
6764
6965
|
} else {
|
|
6765
6966
|
this.extendEl.classList.remove("on");
|
|
@@ -6769,7 +6970,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6769
6970
|
const btn = this.els.extendBtn;
|
|
6770
6971
|
btn.disabled = true;
|
|
6771
6972
|
const prev = btn.textContent;
|
|
6772
|
-
btn.textContent = "Adding\u2026";
|
|
6973
|
+
btn.textContent = this.tf("picker.addingEllipsis", "Adding\u2026");
|
|
6773
6974
|
try {
|
|
6774
6975
|
const h = await this.controller.extendHold(this.opts.holdTtlMs);
|
|
6775
6976
|
if (h) {
|
|
@@ -6778,13 +6979,13 @@ var SeatPicker = class _SeatPicker {
|
|
|
6778
6979
|
this.extendEl?.classList.remove("on");
|
|
6779
6980
|
this.rememberHold(this.hold);
|
|
6780
6981
|
this.emitHoldChange();
|
|
6781
|
-
this.toast("More time added \u2014 your seats are still held.", "success");
|
|
6982
|
+
this.toast(this.tf("picker.moreTimeAdded", "More time added \u2014 your seats are still held."), "success");
|
|
6782
6983
|
} else {
|
|
6783
|
-
this.toast("Couldn't add more time \u2014 please head to checkout now.", "warning");
|
|
6984
|
+
this.toast(this.tf("picker.couldNotAddMoreTime", "Couldn't add more time \u2014 please head to checkout now."), "warning");
|
|
6784
6985
|
}
|
|
6785
6986
|
} catch (err) {
|
|
6786
6987
|
this.opts.onError?.(err);
|
|
6787
|
-
this.toast("Couldn't add more time \u2014 please head to checkout now.", "warning");
|
|
6988
|
+
this.toast(this.tf("picker.couldNotAddMoreTime", "Couldn't add more time \u2014 please head to checkout now."), "warning");
|
|
6788
6989
|
} finally {
|
|
6789
6990
|
btn.disabled = false;
|
|
6790
6991
|
btn.textContent = prev;
|
|
@@ -6811,7 +7012,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6811
7012
|
this.forgetHold();
|
|
6812
7013
|
const n = handoff.lineItems.reduce((sum, i) => sum + i.quantity, 0);
|
|
6813
7014
|
if (this.els.bookedSub) {
|
|
6814
|
-
this.els.bookedSub.innerHTML = `<span class="sl-booked-seats">${n} ${
|
|
7015
|
+
this.els.bookedSub.innerHTML = `<span class="sl-booked-seats">${(0, import_core2.tCount)("picker.ticketsCount", n)}</span> ${this.tf("picker.confirmedAndOnWay", "confirmed. A confirmation is on its way.")}`;
|
|
6815
7016
|
}
|
|
6816
7017
|
this.bookedEl?.classList.add("on");
|
|
6817
7018
|
this.opts.onBooked?.(handoff);
|
|
@@ -6893,7 +7094,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6893
7094
|
({ mountCheckout: mountCheckout2 } = await loadHostedCheckout());
|
|
6894
7095
|
} catch (err) {
|
|
6895
7096
|
this.opts.onError?.(err);
|
|
6896
|
-
this.toast("Checkout could not be opened. Your seats are still held \u2014 please try again.", "error");
|
|
7097
|
+
this.toast(this.tf("picker.checkoutCouldNotBeOpened", "Checkout could not be opened. Your seats are still held \u2014 please try again."), "error");
|
|
6897
7098
|
this.setCtaPhase("idle");
|
|
6898
7099
|
return;
|
|
6899
7100
|
}
|
|
@@ -7008,9 +7209,9 @@ var SeatPicker = class _SeatPicker {
|
|
|
7008
7209
|
rowTypeWord(details) {
|
|
7009
7210
|
const authored = details?.displayType?.trim() || details?.rowType?.trim();
|
|
7010
7211
|
if (authored) return authored;
|
|
7011
|
-
if (details?.objectType === "table") return "Table";
|
|
7012
|
-
if (details?.objectType === "booth") return "Booth";
|
|
7013
|
-
return "Row";
|
|
7212
|
+
if (details?.objectType === "table") return this.tf("picker.table", "Table");
|
|
7213
|
+
if (details?.objectType === "booth") return this.tf("picker.booth", "Booth");
|
|
7214
|
+
return this.tf("picker.row", "Row");
|
|
7014
7215
|
}
|
|
7015
7216
|
rowShort(details) {
|
|
7016
7217
|
const row = details?.rowLabel;
|
|
@@ -7033,7 +7234,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7033
7234
|
const isGroupedTable = details.objectType === "table" && !!details.bookingMode;
|
|
7034
7235
|
const isBooth = details.objectType === "booth";
|
|
7035
7236
|
const hasLoc = details.sectionLabel || details.rowLabel || details.seatNumber;
|
|
7036
|
-
const grid = isGroupedTable ? `<div class="sl-tip-grid"><div class="sl-tip-field"><span class="sl-tip-key">${esc(this.rowTypeWord(details))}</span><span class="sl-tip-val">${esc(details.rowLabel ?? details.displayLabel ?? details.label)}</span></div><div class="sl-tip-field"><span class="sl-tip-key"
|
|
7237
|
+
const grid = isGroupedTable ? `<div class="sl-tip-grid"><div class="sl-tip-field"><span class="sl-tip-key">${esc(this.rowTypeWord(details))}</span><span class="sl-tip-val">${esc(details.rowLabel ?? details.displayLabel ?? details.label)}</span></div><div class="sl-tip-field"><span class="sl-tip-key">${this.tf("picker.guests", "Guests")}</span><span class="sl-tip-val">${details.bookingMode === "variable" ? `${details.minOccupancy}\u2013${details.maxOccupancy}` : details.capacity}</span></div></div>` : isBooth ? `<div class="sl-tip-grid">` + (details.sectionLabel ? `<div class="sl-tip-field"><span class="sl-tip-key">${this.tf("picker.section", "Section")}</span><span class="sl-tip-val">${esc(details.sectionLabel)}</span></div>` : "") + `<div class="sl-tip-field"><span class="sl-tip-key">${esc(this.rowTypeWord(details))}</span><span class="sl-tip-val">${esc(details.rowLabel ?? details.displayLabel ?? details.label)}</span></div></div>` : hasLoc ? `<div class="sl-tip-grid">` + (details.sectionLabel ? `<div class="sl-tip-field"><span class="sl-tip-key">${this.tf("picker.section", "Section")}</span><span class="sl-tip-val">${esc(details.sectionLabel)}</span></div>` : "") + (details.rowLabel ? `<div class="sl-tip-field"><span class="sl-tip-key">${esc(this.rowTypeWord(details))}</span><span class="sl-tip-val">${esc(this.rowShort(details))}</span></div>` : "") + (details.seatNumber ? `<div class="sl-tip-field"><span class="sl-tip-key">${this.tf("picker.seat", "Seat")}</span><span class="sl-tip-val">${esc(details.seatNumber)}</span></div>` : "") + `</div>` : `<div class="sl-tip-grid one"><div class="sl-tip-field"><span class="sl-tip-key">${this.tf("picker.seat", "Seat")}</span><span class="sl-tip-val">${esc(details.displayLabel ?? details.label)}</span></div></div>`;
|
|
7037
7238
|
const statusLine = details.status === "free" ? "" : `<div class="sl-tip-status">${details.status === "held" ? (0, import_core2.t)("map.statusHeld") : (0, import_core2.t)("map.statusTaken")}</div>`;
|
|
7038
7239
|
const limited = this.limitedViewLabel(details.commercial);
|
|
7039
7240
|
const cxLine = limited ? `<div class="sl-tip-cx"><span class="g" aria-hidden="true">\u25D0</span>${esc(limited)}</div>` : "";
|
|
@@ -7324,7 +7525,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7324
7525
|
const identity = details?.displayLabel ?? seat.displayLabel ?? seat.label;
|
|
7325
7526
|
const section = details?.sectionLabel;
|
|
7326
7527
|
const row = this.rowShort(details);
|
|
7327
|
-
const location2 = [section, row ?
|
|
7528
|
+
const location2 = [section, row ? (0, import_core2.t)("picker.rowLabel", { label: row }) : null, identity].filter(Boolean).join(" \xB7 ");
|
|
7328
7529
|
const copy = status === "held" ? {
|
|
7329
7530
|
title: this.tf("picker.temporarilyHeld", "Temporarily held"),
|
|
7330
7531
|
message: this.tf("picker.heldSeatExplanation", "Another buyer is holding this seat. It may become available again.")
|
|
@@ -7420,7 +7621,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7420
7621
|
chip = document.createElement("div");
|
|
7421
7622
|
chip.className = "sl-view3d-compare-saved";
|
|
7422
7623
|
chip.setAttribute("role", "group");
|
|
7423
|
-
chip.setAttribute("aria-label", "Saved seat comparison");
|
|
7624
|
+
chip.setAttribute("aria-label", this.tf("picker.savedSeatComparison", "Saved seat comparison"));
|
|
7424
7625
|
const main2 = document.createElement("button");
|
|
7425
7626
|
main2.type = "button";
|
|
7426
7627
|
main2.className = "main";
|
|
@@ -7432,7 +7633,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7432
7633
|
clear.type = "button";
|
|
7433
7634
|
clear.className = "clear";
|
|
7434
7635
|
clear.textContent = "\xD7";
|
|
7435
|
-
clear.setAttribute("aria-label", "Clear saved seat comparison");
|
|
7636
|
+
clear.setAttribute("aria-label", this.tf("picker.clearSavedSeatComparison", "Clear saved seat comparison"));
|
|
7436
7637
|
clear.addEventListener("click", () => this.clearView3dComparison());
|
|
7437
7638
|
chip.append(main2, clear);
|
|
7438
7639
|
overlay.appendChild(chip);
|
|
@@ -7441,8 +7642,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
7441
7642
|
const count = this.view3dCompareSeatIds.length;
|
|
7442
7643
|
const main = chip.querySelector(".main");
|
|
7443
7644
|
if (main) {
|
|
7444
|
-
main.textContent = count > 1 ?
|
|
7445
|
-
main.setAttribute("aria-label", count > 1 ?
|
|
7645
|
+
main.textContent = count > 1 ? (0, import_core2.t)("picker.compareCount", { count }) : this.tf("picker.oneSeatSaved", "1 seat saved");
|
|
7646
|
+
main.setAttribute("aria-label", count > 1 ? (0, import_core2.t)("picker.openComparisonOfSeats", { count }) : this.tf("picker.oneSeatSavedChooseAnother", "One seat saved; choose another to compare"));
|
|
7446
7647
|
}
|
|
7447
7648
|
}
|
|
7448
7649
|
view3dComparisonSnapshot(seatId) {
|
|
@@ -7719,8 +7920,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7719
7920
|
const wantFloors = floors.length > 1;
|
|
7720
7921
|
const wantZones = zones.length > 1;
|
|
7721
7922
|
const wantSections = sections.length > 1;
|
|
7722
|
-
|
|
7723
|
-
if (!wantFloors && !wantZones && !wantSections && !wantLocator) return;
|
|
7923
|
+
if (!wantFloors && !wantZones && !wantSections) return;
|
|
7724
7924
|
const nav = document.createElement("div");
|
|
7725
7925
|
nav.className = "sl-view3d-nav";
|
|
7726
7926
|
const finderToggle = document.createElement("button");
|
|
@@ -7730,7 +7930,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7730
7930
|
const setFinderOpen = (open) => {
|
|
7731
7931
|
nav.classList.toggle("is-open", open);
|
|
7732
7932
|
finderToggle.setAttribute("aria-expanded", String(open));
|
|
7733
|
-
finderToggle.textContent = open ? "Close
|
|
7933
|
+
finderToggle.textContent = open ? this.tf("picker.closeVenueNav", "Close") : wantFloors && (wantZones || wantSections) ? this.tf("picker.levelsAndAreas", "Levels & areas") : wantFloors ? this.tf("picker.levels", "Levels") : this.tf("picker.areas", "Areas");
|
|
7734
7934
|
};
|
|
7735
7935
|
finderToggle.addEventListener("click", () => setFinderOpen(!nav.classList.contains("is-open")));
|
|
7736
7936
|
nav.addEventListener("keydown", (event) => {
|
|
@@ -7767,7 +7967,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7767
7967
|
row.appendChild(b);
|
|
7768
7968
|
};
|
|
7769
7969
|
add(this.tf("picker.allLevels", "All levels"), null);
|
|
7770
|
-
for (const f of floors) add(f.label ||
|
|
7970
|
+
for (const f of floors) add(f.label || (0, import_core2.t)("picker.levelNumber", { number: f.index + 1 }), f.index);
|
|
7771
7971
|
nav.appendChild(row);
|
|
7772
7972
|
}
|
|
7773
7973
|
if (wantZones || wantSections) {
|
|
@@ -7810,86 +8010,6 @@ var SeatPicker = class _SeatPicker {
|
|
|
7810
8010
|
}
|
|
7811
8011
|
nav.appendChild(row);
|
|
7812
8012
|
}
|
|
7813
|
-
if (wantLocator) {
|
|
7814
|
-
const locator = document.createElement("div");
|
|
7815
|
-
locator.className = "sl-view3d-locator";
|
|
7816
|
-
locator.setAttribute("role", "group");
|
|
7817
|
-
locator.setAttribute("aria-label", "Find an exact seat in 3D");
|
|
7818
|
-
const sectionSelect = document.createElement("select");
|
|
7819
|
-
sectionSelect.setAttribute("aria-label", "Choose section in 3D");
|
|
7820
|
-
const rowSelect = document.createElement("select");
|
|
7821
|
-
rowSelect.setAttribute("aria-label", "Choose row in 3D");
|
|
7822
|
-
const seatSelect = document.createElement("select");
|
|
7823
|
-
seatSelect.setAttribute("aria-label", "Choose seat in 3D");
|
|
7824
|
-
const view = document.createElement("button");
|
|
7825
|
-
view.type = "button";
|
|
7826
|
-
view.textContent = "Inspect seat";
|
|
7827
|
-
view.disabled = true;
|
|
7828
|
-
const fill = (select, placeholder, entries) => {
|
|
7829
|
-
select.replaceChildren();
|
|
7830
|
-
const first = document.createElement("option");
|
|
7831
|
-
first.value = "";
|
|
7832
|
-
first.textContent = placeholder;
|
|
7833
|
-
select.appendChild(first);
|
|
7834
|
-
for (const entry of entries) {
|
|
7835
|
-
const option = document.createElement("option");
|
|
7836
|
-
option.value = entry.id;
|
|
7837
|
-
option.textContent = entry.label;
|
|
7838
|
-
select.appendChild(option);
|
|
7839
|
-
}
|
|
7840
|
-
select.value = "";
|
|
7841
|
-
};
|
|
7842
|
-
fill(sectionSelect, "1. Section", allSections.map((section) => ({
|
|
7843
|
-
id: section.id,
|
|
7844
|
-
label: `${section.label} \xB7 ${section.seatCount.toLocaleString()} seats`
|
|
7845
|
-
})));
|
|
7846
|
-
fill(rowSelect, "2. Row", []);
|
|
7847
|
-
fill(seatSelect, "3. Seat", []);
|
|
7848
|
-
rowSelect.disabled = true;
|
|
7849
|
-
seatSelect.disabled = true;
|
|
7850
|
-
sectionSelect.addEventListener("change", () => {
|
|
7851
|
-
const sectionId = sectionSelect.value;
|
|
7852
|
-
view.disabled = true;
|
|
7853
|
-
fill(seatSelect, "3. Seat", []);
|
|
7854
|
-
seatSelect.disabled = true;
|
|
7855
|
-
if (!sectionId || !handle.focusSection(sectionId)) {
|
|
7856
|
-
fill(rowSelect, "2. Row", []);
|
|
7857
|
-
rowSelect.disabled = true;
|
|
7858
|
-
return;
|
|
7859
|
-
}
|
|
7860
|
-
const rows = handle.rows(sectionId);
|
|
7861
|
-
fill(rowSelect, "2. Row", rows.map((row) => ({
|
|
7862
|
-
id: row.id,
|
|
7863
|
-
label: `${row.label} \xB7 ${row.seatCount} seats`
|
|
7864
|
-
})));
|
|
7865
|
-
rowSelect.disabled = rows.length === 0;
|
|
7866
|
-
});
|
|
7867
|
-
rowSelect.addEventListener("change", () => {
|
|
7868
|
-
const rowId = rowSelect.value;
|
|
7869
|
-
view.disabled = true;
|
|
7870
|
-
if (!rowId || !handle.focusRow(rowId)) {
|
|
7871
|
-
fill(seatSelect, "3. Seat", []);
|
|
7872
|
-
seatSelect.disabled = true;
|
|
7873
|
-
return;
|
|
7874
|
-
}
|
|
7875
|
-
const seats = handle.seatsInRow(rowId);
|
|
7876
|
-
fill(seatSelect, "3. Seat", seats);
|
|
7877
|
-
seatSelect.disabled = seats.length === 0;
|
|
7878
|
-
});
|
|
7879
|
-
seatSelect.addEventListener("change", () => {
|
|
7880
|
-
const seatId = seatSelect.value;
|
|
7881
|
-
view.disabled = !seatId;
|
|
7882
|
-
});
|
|
7883
|
-
view.addEventListener("click", () => {
|
|
7884
|
-
const seatId = seatSelect.value;
|
|
7885
|
-
if (seatId) {
|
|
7886
|
-
setFinderOpen(false);
|
|
7887
|
-
this.onView3dSeatPick(seatId);
|
|
7888
|
-
}
|
|
7889
|
-
});
|
|
7890
|
-
locator.append(sectionSelect, rowSelect, seatSelect, view);
|
|
7891
|
-
nav.appendChild(locator);
|
|
7892
|
-
}
|
|
7893
8013
|
overlay.appendChild(nav);
|
|
7894
8014
|
}
|
|
7895
8015
|
async enter3d(flySeatId) {
|
|
@@ -7905,7 +8025,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7905
8025
|
const overlay = document.createElement("div");
|
|
7906
8026
|
overlay.className = "sl-view3d";
|
|
7907
8027
|
overlay.setAttribute("role", "group");
|
|
7908
|
-
overlay.setAttribute("aria-label", "Interactive 3D venue view");
|
|
8028
|
+
overlay.setAttribute("aria-label", this.tf("picker.interactive3dVenueView", "Interactive 3D venue view"));
|
|
7909
8029
|
const back = document.createElement("button");
|
|
7910
8030
|
back.type = "button";
|
|
7911
8031
|
back.className = "sl-view3d-back";
|
|
@@ -7931,7 +8051,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7931
8051
|
fullscreen.type = "button";
|
|
7932
8052
|
fullscreen.className = "sl-view3d-fs";
|
|
7933
8053
|
fullscreen.textContent = "\u26F6";
|
|
7934
|
-
fullscreen.setAttribute("aria-label", "Full screen");
|
|
8054
|
+
fullscreen.setAttribute("aria-label", this.tf("picker.fullScreen", "Full screen"));
|
|
7935
8055
|
fullscreen.setAttribute("aria-pressed", String(!!document.fullscreenElement || this.fsFallback || this.framedFs));
|
|
7936
8056
|
fullscreen.addEventListener("click", () => this.toggleFullscreen());
|
|
7937
8057
|
overlay.appendChild(fullscreen);
|
|
@@ -7968,7 +8088,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7968
8088
|
onSeatInspect: (id) => this.onView3dSeatPick(id),
|
|
7969
8089
|
onSectionFocusChange: (sectionId) => {
|
|
7970
8090
|
const select = overlay.querySelector(
|
|
7971
|
-
'select[
|
|
8091
|
+
'select[data-locator="section"]'
|
|
7972
8092
|
);
|
|
7973
8093
|
const next = sectionId ?? "";
|
|
7974
8094
|
if (!select || select.value === next) return;
|
|
@@ -8065,7 +8185,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
8065
8185
|
if (button) {
|
|
8066
8186
|
button.disabled = true;
|
|
8067
8187
|
button.classList.add("sl-busy");
|
|
8068
|
-
button.innerHTML =
|
|
8188
|
+
button.innerHTML = `<span class="sl-ba-spin" aria-hidden="true"></span>${this.tf("picker.findingEllipsis", "Finding\u2026")}`;
|
|
8069
8189
|
}
|
|
8070
8190
|
try {
|
|
8071
8191
|
const h = await this.controller.bestAvailable(qty, categoryKey, { ...opts, ttlMs: this.opts.holdTtlMs });
|
|
@@ -8087,7 +8207,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
8087
8207
|
} catch (err) {
|
|
8088
8208
|
this.opts.onError?.(err);
|
|
8089
8209
|
const reason = err?.reason;
|
|
8090
|
-
const message = reason === "not_enough_together" ?
|
|
8210
|
+
const message = reason === "not_enough_together" ? (0, import_core2.t)("picker.couldNotFindSeatsTogether", { count: qty }) : reason === "sold_out" ? this.tf("picker.ticketTypeSoldOut", "That ticket type is sold out. Try another ticket type.") : reason === "event_closed" ? this.tf("picker.seatSalesClosedForEvent", "Seat sales have closed for this event.") : this.tf("picker.seatsNoLongerAvailableTryAnother", "Those seats are no longer available. Try another quantity or ticket type.");
|
|
8091
8211
|
this.toast(message, "error");
|
|
8092
8212
|
return null;
|
|
8093
8213
|
} finally {
|
|
@@ -8116,7 +8236,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
8116
8236
|
}
|
|
8117
8237
|
}
|
|
8118
8238
|
if (!released) {
|
|
8119
|
-
this.toast("Couldn't release your tickets. Your hold is unchanged.", "error");
|
|
8239
|
+
this.toast(this.tf("picker.couldNotReleaseTickets", "Couldn't release your tickets. Your hold is unchanged."), "error");
|
|
8120
8240
|
return;
|
|
8121
8241
|
}
|
|
8122
8242
|
this.hold = null;
|