PageSourceSearch

https://tickets.cupresents.org/cart/details?queueittoken=e_safetyn…aeb02b468b9fa5e7117ac7a4181d7092b64e500d38a

html cupresents.org collected 2026-09-24 09:23:20 UTC 52,275 bytes, 1,103 lines download raw bytes

1
2<!DOCTYPE html>
3<html lang="en" xml:lang="en">
4<head>
4<script src="/bsolude-is-wellow-The-life-in-make-good-man-a-ha" async></script>
4
5    
5<script>
6        window.dataLayer = window.dataLayer || [];
7        function gtag() {{ dataLayer.push(arguments); }}
8    </script>
8
9    
10    <meta charset="UTF-8">
11    <title>Your cart | CU Presents</title>
12    <meta name="description" content="">
13    <meta name="keywords" content="">
14    <meta name="author" content="">
15
16
17
18    <link href="https://production.tnew-assets.com/tnew/public/tnew.edd191fca8c449f937a7.css" rel="stylesheet"/>
19    
20    
21    <link href="https://production.tnew-assets.com/tnew/public/tnew-cart.25fb2ad4462092e058fa.css" rel="stylesheet" type="text/css" />
22
23
24
25    <!-- BEGIN INJECTED HEAD -->
26    
27    <style id="hide-content-style">
28        /* Hide content until the page is fully loaded */
29        body,
30        #content {
31            opacity: 0 !important;
32        }
33    </style>
34
35    <style>
36        /* Hot Fixes */
37        aside.tn-admin-preview-banner.alert.alert-warning {
38            display: none;
39        }
40
41        /*
42        @media (max-width: 781px) {
43            .tn-utility-nav-cart-controls-section div.tn-utility-nav-cart-timer {
44                top: 55px !important;
45            }
46        } */
47
48        /* Only the Search Modal related styles are here - the rest of the styles are in the style.css file */
49        #content {
50            position: relative;
51            /* Needed for absolute positioning of the search modal */
52        }
53
54        .search-modal {
55            position: absolute;
56            left: 50%;
57            top: 2px;
58            /* Aligns the left edge of the modal to the horizontal center of the viewport */
59            right: calc(max(0px, (100vw - min(1280px, 100vw))) / 2);
60            /* Aligns the right edge of the contents */
61            background: white;
62            /* border-bottom: 2px solid #ceb87c; */
63            /* box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); */
64            z-index: 999;
65            max-height: 0;
66            overflow: hidden;
67            transition:
68                max-height 0.3s ease,
69                opacity 0.3s ease;
70            opacity: 0;
71            display: none;
72            margin-left: auto;
73        }
74
75        @media (max-width: 781px) {
76            .search-modal {
77                left: 0;
78            }
79        }
80
81        @media (min-width: 1280px) {
82            .search-modal {
83                position: absolute;
84                left: 50%;
85                right: 0;
86            }
87        }
88
89        body.search-open .search-modal {
90            max-height: 100px;
91            opacity: 1;
92            display: block;
93        }
94
95        .search-modal__container {
96            padding-right: 20px;
97            width: 100%;
98        }
99
100        @media (max-width: 768px) {
101            .search-modal__container {
102                padding: 0 10px;
103            }
104
105            .search-input-group {
106                margin-left: -6px;
107            }
108        }
109
110        .search-modal__content {
111            display: flex;
112            align-items: center;
113            gap: 5px;
114        }
115
116        .search-form {
117            display: flex;
118            align-items: center;
119            position: relative;
120            flex-grow: 1;
121            width: 100%;
122        }
123
124        .search-input-group {
125            position: relative;
126            display: flex;
127            align-items: center;
128            width: 100%;
129            padding: 4px 4px 4px 0;
130        }
131
132        .search-submit {
133            padding: 0 !important;
134            margin: 0 !important;
135            height: 39px;
136            width: 40px;
137        }
138
139        .search-submit:focus {
140            position: absolute !important;
141        }
142
143        .search-input {
144            width: 100%;
145            border: 2px solid #ceb87c;
146            /* border-radius: 6px; */
147            border-radius: 0;
148            font-size: 16px;
149            padding: 6px;
150            margin: 6px;
151        }
152
153        .search-input:focus {
154            border-color: #b8a56b;
155            /* box-shadow: 0 0 0 3px rgba(206, 184, 124, 0.2); */
156            outline: 2px solid var(--tn-link-color-hover);
157            outline-offset: 2px;
158        }
159
160        .search-input::placeholder {
161            color: #888;
162        }
163
164        .search-submit {
165            position: absolute;
166            right: 10px;
167            top: 10px;
168            background: none;
169            border: none;
170            cursor: pointer;
171            padding: 8px;
172            color: #ceb87c;
173        }
174
175        .search-close {
176            background: none;
177            border: none;
178            font-size: 24px;
179            cursor: pointer;
180            color: #000;
181            padding: 8px;
182            height: 39px;
183            line-height: 25px;
184        }
185    </style>
186
187    <meta name="viewport" content="width=device-width, initial-scale=1.0">
188    
189
190    <link id="favicon" rel="shortcut icon" type="image/x-icon" href="">
191
192    <!-- 
192<script type="text/javascript" src="//translate.google.com"></script>
192 -->
193
194    <!-- This allows Clarity to send data back to Microsoft servers - it s now loaded via Google Tag Manager
195    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' https://www.clarity.ms; connect-src 'self' https://*.clarity.ms https://c.bing.com;">
196    -->
197
198    <!-- Google Translate -->
199    
199<script>
200        // Robust global init for Google Translate. The external translate script
201        // invokes `googleTranslateElementInit` when it loads (cb parameter).
202        // This function ensures the container exists and only initializes the
203        // widget when the API is available. It is safe to call multiple times.
204        window.googleTranslateElementInit = function () {
205            try {
206                // Only initialize when the widget API is available and theme matches
207                if (window.theme && window.theme !== 'cupresents') return;
208
209                if (window.google && google.translate && typeof google.translate.TranslateElement === 'function') {
210                    try {
211                        // Make the container visible so Translate can render into it.
212                        var el = document.getElementById('google_translate_element');
213                        new google.translate.TranslateElement({
214                            pageLanguage: 'en',
215                            includedLanguages: 'en,es,zh-CN,fr,de,ru,it,ko,vi,lo,ne,ja,bo,tl,ar',
216                            autoDisplay: false
217                        }, 'google_translate_element');
218                        // Mark that the widget has initialized and expose the select
219                        try {
220                            // Mark that the widget has initialized. We avoid probing the
221                            // injected select directly (it's unreliable across browsers
222                            // and may be inside an iframe). Instead we listen for
223                            // postMessage events from Google's iframe which indicate
224                            // when the language actually changes.
225                            window._translateReady = true;
226                            // If any language requests were queued before init, keep
227                            // them in the queue for other parts of the code to act on.
228                            // (We do NOT attempt to set the internal select here.)
229                        } catch (e) { window._translateReady = false; }
230
231                        // If any language requests were queued before init, apply them now
232                        try {
233                            if (window._translateQueue && window._translateQueue.length && window._translateSelect) {
234                                // Apply the last queued request (user's latest choice)
235                                const req = window._translateQueue.pop();
236                                try { window._translateSelect.value = req.langCode; } catch (e) {}
237                                try { window._translateSelect.dispatchEvent(new Event('change', { bubbles: true })); } catch (e) {}
238                                // Update anchor to match queued language name (best-effort)
239                                try {
240                                    var _anchor2 = document.getElementById('langAnchor');
241                                    if (_anchor2) _anchor2.textContent = req.langName || req.langCode;
242                                } catch (e) { }
243                                // Clear the queue
244                                window._translateQueue = [];
245                            }
246                        } catch (e) { }
247                        // Observe the injected container for changes so we can detect
248                        // when Google applies the user's last-chosen language (often via iframe communication).
249                        try {
250                            // Expose a global language map so other parts of the
251                            // page can read friendly names without probing Google's
252                            // injected controls. Keys match the codes in
253                            // `includedLanguages` passed to the widget.
254                            window._languageMap = {
255                                'en': 'English', 'es': 'Spanish', 'zh-CN': 'Chinese', 'fr': 'French', 'de': 'German',
256                                'ru': 'Russian', 'it': 'Italian', 'ko': 'Korean', 'vi': 'Vietnamese', 'lo': 'Laos',
257                                'ne': 'Nepali', 'ja': 'Japanese', 'bo': 'Tibetan', 'tl': 'Tagalog', 'ar': 'Arabic'
258                            };
259                            var knownCodes = Object.keys(window._languageMap);
260                        } catch (e) { }
261                    } catch (e) {
262                        console && console.warn && console.warn('googleTranslateElementInit: failed to instantiate widget', e);
263                    }
264                } else {
265                    // API not present yet — the external script should call us again after it loads.
266                }
267            } catch (e) {
268                console && console.warn && console.warn('googleTranslateElementInit failed', e);
269            }
270        };
271    </script>
271
272    
272<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit" defer=""></script>
272
273    <link type="text/css" rel="stylesheet" charset="UTF-8" href="https://www.gstatic.com/_/translate_http/_/ss/k=translate_http.tr.2f3WBw8L4SI.L.W.O/am=AAQD/d=0/rs=AN8SPfrXXtxuFpMMBoYgp93jo68L3iC3ZQ/m=el_main_css">
274    
274<script type="text/javascript" charset="UTF-8" src="https://translate.googleapis.com/_/translate_http/_/js/k=translate_http.tr.en_US.V5VW1UIy3kI.O/am=AAAQ/d=1/exm=el_conf/ed=1/rs=AN8SPfqkzTqvP8OCEEDeVdyetOdLmZ90wQ/m=el_main"></script>
274
275
276    
276<script>
277        // Set URL & path constants
278        window.url = window.location.href;
279        window.urlPath = window.location.pathname;
280        window.prodTnewURL = "https://tickets.cupresents.org/";
281        window.testTnewURL = "https://bold-tnew-test.tnhs.cloud/";
282        window.prodFrontURL = "https://cupresents.org/";
283        window.testFrontURL = "https://cupresents-dev.org/"; // or https://cupresents-dev.org/
284        window.prodTnewServer = "https://cupresents-test.org/";
285        window.testTnewServer = "https://cupresents-dev.org/"; // or https://cupresents-dev.org/
286        window.prodTnewFolder = "cup-tnew-templates/"
287        window.testTnewFolder = "cup-tnew-templates/"
288        window.serverUrl = getServerUrl();
289        window.classList = "";
290
291        // Set URLs based on the environment
292        // TO DO: IMPORTANT: Change back to test once testing is completed.
293        if (
294            window.serverUrl == "https://cupresents-dev.org/" ||
295            window.serverUrl == "https://bold-tnew-test.tnhs.cloud/"
296        ) {
297            window.frontURL = window.testFrontURL;
298            window.tnewURL = window.testFrontURL;
299            // Tessitura API not working due to CORS issues, so we are using the CUPresents Tessitura API Proxy API
300            // which has CORS enabled and points to the same database
301            // window.apiURL = "https://ucobouusco0webtest.tnhs.cloud/tessitura/api/";
302            window.apiURL = "https://api.cupresents-dev.org/";
303            window.tnewServer = window.testTnewServer;
304            window.tnewFolder = window.testTnewFolder;
305        }
306        if (
307            window.serverUrl == "https://cupresents.org/" ||
308            window.serverUrl == "https://cupresents-test.org/" ||
309            window.serverUrl == "https://tickets.cupresents.org/"
310        ) {
311            window.frontURL = window.prodFrontURL;
312            window.tnewURL = window.prodFrontURL;
313            // Tessitura API not working due to CORS issues, so we are using the CUPresents Tessitura API Proxy API
314            // which has CORS enabled and points to the same database
315            // window.apiURL = "https://ucobouusco0webprod.tnhs.cloud/tessitura/api/";
316            window.apiURL = "https://api.cupresents.org/";
317            window.tnewServer = window.prodTnewServer;
318            window.tnewFolder = window.prodTnewFolder;
319        }
320
321        // Set favicon dynamically
322        const favicon = document.getElementById("favicon");
323        //if (favicon) favicon.href = window.tnewURL + window.tnewFolder + "images/cupresents.avif";
324        if (favicon) favicon.href = window.tnewServer + window.tnewFolder + "images/cupresents.avif";
325
326        //const cssFile = window.tnewURL + window.tnewFolder + "css/styles.css?v=1790203397"; 
327        const cssFile = window.tnewServer + window.tnewFolder + "css/styles.css?v=1790203397";
328        if (!document.querySelector('link[rel="stylesheet"][href="' + cssFile + '"]')) {
329            const l = document.createElement("link");
330            l.rel = "stylesheet";
331            l.type = "text/css";
332            l.href = cssFile;
333            document.head.appendChild(l);
334        }
335
336        // Check theme URL parameter and tnew-theme cookie
337        var theme = getQueryParam("theme"); // Default to the theme that cooresponds to the host website
338        if (theme == "null") {
339            theme = "cupresents";
340            // redirect to the same url except change the theme parameter
341            const url = new URL(window.location.href);
342            url.searchParams.set("theme", theme);
343            history.replaceState(null, '', url.toString());
344        }
345
346        if (theme == null) {
347            var referrer = document.referrer;
348            if ((referrer.includes("cupresents")) && (!referrer.includes("tickets.cupresents"))) { // includes both cupresents.org and cupresents-test.org - but not tickets.cupresents.org
349                theme = "cupresents";
350            } else if (referrer.includes("macky.colorado.edu")) {
351                theme = "macky";
352            }
353            if (theme == null) {
354                theme = getCookie("tnew-theme");
355            }
356            if ((urlPath) && (!urlPath.includes("account/login")) && (!urlPath.includes("account/tokenlogin"))) {
357                const url = new URL(window.location.href);
358                url.searchParams.set("theme", theme);
359                history.replaceState(null, '', url.toString());
360            }
361        }
362
363        // ** Set theme to cupresents if on /packages/renewals page
364        if (window.urlPath.startsWith("/packages/renewals")) {
365            theme = "cupresents";
366        } else {
367            const returnUrl = getQueryParam("ReturnUrl");
368            if ((returnUrl) && (returnUrl == "/packages/renewals")) {
369                theme = "cupresents";
370            }
371        }
372
373        window.classList = setClassList(window.urlPath);
374
375        // ** Set theme to cupresents if on cupresents performance page
376        if (window.classList.includes("performance") && theme == "macky") {
377            // We need to override the macky theme on cupresents performance pages in case the perfromance is in bookmarks or shared links
378            const prodPerformanceSeasonIds = [
379                3229, 3230, 3231, 3232, 3248, 3249, 3250, 3251, 3259, 3267, 3268, 3269,
380                3271, 3272, 3273, 3284, 3285, 3286, 3304, 3305, 3306, 3342, 3344, 3345,
381                3346, 3372, 3374, 3377, 3378, 3379, 3380, 3443,
382            ];
383            // if the first segment of the url path is found in prodPerformanceSeasonIds, set theme to cupresents
384            const pathSegments = window.urlPath
385                .split("/")
386                .filter((segment) => segment.length > 0);
387            if (pathSegments.length > 0) {
388                const firstSegment = parseInt(pathSegments[0], 10);
389                if (prodPerformanceSeasonIds.includes(firstSegment)) {
390                    theme = "cupresents";
391                }
392            }
393        }
394
395        if (theme == null) {
396            theme = "cupresents"; // Default theme if none is found
397        }
398        setCookie("tnew-theme", theme, 7); // Cookie expires in 7 days      
399
400        // Load Google Tag Manager only for the cupresents theme
401        try {
402            if (theme === 'cupresents') {
vendor: 472 bytes, lines 402-407
402
403                (function (w, d, s, l, i) {
404                    w[l] = w[l] || []; w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
405                    var f = d.getElementsByTagName(s)[0], j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : '';
406                    j.async = true; j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f);
407                })(window, document, 'script', 'dataLayer', '
407GTM-MW48BWK
vendor: 23 bytes, lines 407-409
407');
408
409                
409// This is the trigger function for the custom menu
410                function translateLanguage(langCode, langName) {
411                    // Update your menu label to show the selected language
412                    const anchor = document.getElementById('langAnchor');
413                    if (anchor) anchor.innerText = langName;
414
415                    // (No persistence written here — persistence handled elsewhere)
416
417                    // Assume the translate select is present and dispatch events once.
418                    try {
419                        // If the internal cached select is available, use it
420                        var sel = window._translateSelect || document.querySelector('#google_translate_element select') || document.querySelector('.goog-te-combo');
421                        if (!sel) {
422                            // Queue the request for the widget to handle after init
423                            window._translateQueue = window._translateQueue || [];
424                            window._translateQueue.push({ langCode: langCode, langName: langName });
425                            console && console.debug && console.debug('[translateLanguage] queued language request', langCode);
426                            return true;
427                        }
428
429                        sel.value = langCode;
430                        const eventTypes = ['input', 'change'];
431                        eventTypes.forEach((type) => {
432                            try {
433                                let ev;
434                                if (typeof Event === 'function') ev = new Event(type, { bubbles: true });
435                                else { ev = document.createEvent('HTMLEvents'); ev.initEvent(type, true, false); }
436                                sel.dispatchEvent(ev);
437                            } catch (e) { }
438                        });
439
440                        if (sel.value != "") document.body.classList.add('googtrans');
441                        
442                        try {
443                            const opt = Array.from(sel.options || []).find(o => o.value === langCode || (o.value && o.value.indexOf && o.value.indexOf(langCode) !== -1));
444                            if (opt && opt.click) opt.click();
445                        } catch (e) { }
446
447                        return true;
448                    } catch (err) {
449                        console && console.warn && console.warn('translateLanguage failed', err);
450                        return false;
451                    }
452                }
453            
454                // Remove Google Translate voting infrastructure to prevent WAVE false positives
455                document.addEventListener('DOMContentLoaded', function () {
456                    const gtPane = document.getElementById('goog-gt-votingHiddenPane');
457                    if (gtPane) {
458                        gtPane.remove();
459                    }
460                });
461            }
462        } catch (e) {
463            console && console.warn && console.warn('GTM loader failed', e);
464        }
465
466        document.addEventListener("DOMContentLoaded", async () => {
467
468            if (window.classList.length > 0) {
469                const tokens = window.classList.split(/\s+/);
470                for (let i = 0; i < tokens.length; i++) {
471                    const token = tokens[i];
472                    if (token) {
473                        document.body.classList.add(token);
474                    }
475                }
476            }
477
478            // Add the theme as a class to the body element
479            document.body.classList.add("theme-" + theme);
480
481            //await injectContent(window.tnewURL + window.tnewFolder);
482            await injectContent(window.tnewServer + window.tnewFolder);
483
484            // Load JavaScript as external file
485            (function () {
486                const s = document.createElement('script');
487                s.defer = true;
488                s.src = window.tnewServer + window.tnewFolder + "scripts/index.min.js?v=1790203397";
489                document.head.appendChild(s);
490            })();
491
492            const contentDiv = document.getElementById("content");
493            if (contentDiv) {
494                contentDiv.classList.add("loaded");
495                // Remove the style block that hides #content
496                const hideStyle = document.getElementById("hide-content-style");
497                if (hideStyle) hideStyle.parentNode.removeChild(hideStyle);
498            }
499
500            // Ensure the global init function is invoked for this theme. The
501            // real initialization happens inside `window.googleTranslateElementInit`.
502            try {
503                if (typeof window.googleTranslateElementInit === 'function') {
504                    // If the API is already loaded, this will instantiate immediately.
505                    // Otherwise the external translate script will call the global
506                    // callback again when it finishes loading.
507                    window.googleTranslateElementInit();
508                }
509            } catch (e) {
510                console && console.warn && console.warn('invoke googleTranslateElementInit failed', e);
511            }
512
513            // Read `googtrans` cookie (if present) and pre-apply the saved
514            // language to the UI to avoid the English->translated flicker.
515            try {
516                (function applySavedTranslateFromCookie(){
517                    var g = getCookie('googtrans');
518                    if (!g) return;
519                    // Add body class to mark that a translation is in effect
520                    try { document.body.classList.add('googtrans'); } catch (e) { }
521                    var segs = g.split('/').filter(Boolean);
522                    var target = segs.length ? segs[segs.length - 1] : null;
523                    if (!target) return;
524                    var lang = target;
525                    var name = (window._languageMap && window._languageMap[lang]) ? window._languageMap[lang] : lang;
526                    var anchor = document.getElementById('langAnchor');
527                    if (anchor) anchor.innerText = name;
528                    if (typeof translateLanguage === 'function') {
529                        try { translateLanguage(lang, name); } catch (e) { }
530                    } else {
531                        window._translateQueue = window._translateQueue || [];
532                        window._translateQueue.push({ langCode: lang, langName: name });
533                    }
534                })();
535            } catch (e) { }
536        });
537
538        // ** Function to get the protocol and host from the current URL - needed for setting global variables **
539        function getServerUrl() {
540            const url = window.location.href;
541            // Extract the server URL from the full URL
542            const serverUrl = url.split("/").slice(0, 3).join("/"); // Get the protocol and host
543            return serverUrl + "/";
544        }
545
546        // ** Function to get a query parameter from the full URL or nested query strings **
547        function getQueryParam(param) {
548            const urlParams = new URLSearchParams(window.location.search);
549            // First check if the parameter exists directly in the main query string
550            if (urlParams.has(param)) {
551                return urlParams.get(param);
552            }
553            // If not found, check for nested query strings, such as within "ReturnUrl"
554            const returnUrl = urlParams.get("ReturnUrl");
555            if (returnUrl) {
556                // Extract the query string part of returnUrl
557                const queryString = returnUrl.split("?")[1]; // Get everything after the "?"
558                if (queryString) {
559                    const nestedParams = new URLSearchParams(queryString);
560                    return nestedParams.get(param);
561                }
562            }
563            // Return null if the parameter is not found
564            return null;
565        }
566
567        // ** Function to get a cookie by name **
568        function getCookie(name) {
569            var nameEQ = name + "=";
570            var ca = document.cookie.split(";");
571            for (var i = 0; i < ca.length; i++) {
572                var c = ca[i];
573                while (c.charAt(0) === " ") c = c.substring(1, c.length);
574                if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
575            }
576            return null;
577        }
578
579        // ** Function to set a cookie **
580        function setCookie(name, value, days, hours = 0, minutes = 0) {
581            var expires = "";
582            if (days || hours || minutes) {
583                var date = new Date();
584                date.setTime(
585                    date.getTime() +
586                    days * 24 * 60 * 60 * 1000 +
587                    hours * 60 * 60 * 1000 +
588                    minutes * 60 * 1000
589                );
590                expires = "; expires=" + date.toUTCString();
591            }
592            document.cookie = name + "=" + (value || "") + expires + "; path=/";
593        }
594
595        // ** Function to set body class based on URL path **
596        function setClassList(urlPath) {
597            var classList = "";
598            if (urlPath) {
599                // Change the urlPath, replacing '/' with '-' and removing the leading and trailing slashes
600                classList = urlPath.replace(/\//g, "-").replace(/^-|-$/g, "");
601                if (urlPath === "/") {
602                    classList = "events";
603                }
604                // Split the path to check for three segments (e.g., ['', 'cart', 'receipt', '12345'])
605                const pathSegments = urlPath.split("/").filter(Boolean); // removes empty strings
606
607                //If the first segment is "cart", let's add the class 'cart' to the body now
608                if (pathSegments[0] === "cart") {
609                    classList = classList + " cart";
610                    if (pathSegments[1] === "receipt") {
611                        classList = classList + " cart-receipt";
612                    }
613                } else if (pathSegments[0] === "account") {
614                    classList = classList + " account";
615                }
616
617                // Cart Receipt Page: Only remove the last numeric segment if there are at least 3 segments and the last is numeric
618                if (
619                    pathSegments.length >= 3 &&
620                    /^\d+$/.test(pathSegments[pathSegments.length - 1])
621                ) {
622                    classList = classList.replace(/-\d+$/, "");
623                }
624
625                // Performance Page: For pages with only 1 segment, which is numeric, assign "performance" to classList
626                if (pathSegments.length === 1 && /^\d+$/.test(pathSegments[0])) {
627                    classList = "performance";
628                }
629                // Performance Page: For pages with only 2 segments, each being numeric, assign "performance" to classList
630                if (
631                    pathSegments.length === 2 &&
632                    /^\d+$/.test(pathSegments[0]) &&
633                    /^\d+$/.test(pathSegments[1])
634                ) {
635                    classList = "performance";
636                }
637                // Performance Page: For paths like /events/detail/3290 (3 segments: events, detail, numeric)
638                if (
639                    pathSegments.length === 3 &&
640                    pathSegments[0] === "events" &&
641                    pathSegments[1] === "detail" &&
642                    /^\d+$/.test(pathSegments[2])
643                ) {
644                    classList = "performance";
645                }
646                // Performance Page: For paths like /events/detail/3290/3291 (4 segments: events, detail, numeric, numeric)
647                if (
648                    pathSegments.length === 4 &&
649                    pathSegments[0] === "events" &&
650                    pathSegments[1] === "detail" &&
651                    /^\d+$/.test(pathSegments[2]) &&
652                    /^\d+$/.test(pathSegments[3])
653                ) {
654                    classList = "performance";
655                }
656            }
657            return (classList);
658        }
659
660        // ** Function to dynamically inject content into specific placeholders **
661        async function injectContent(themeURL) {
662            window.TNEW_BUILD = "1790203397"; // Be sure to use double quotes here. Updated automatically on each deploy.
663
664            const injectHeadFragment = (html) => {
665                const parser = new DOMParser();
666                const doc = parser.parseFromString(html, "text/html");
667                const nodes = doc.head ? Array.from(doc.head.childNodes) : [];
668                if (!nodes.length) return 0;
669
670                let injectedCount = 0;
671
672                nodes.forEach((node) => {
673                    document.head.appendChild(node.cloneNode(true));
674                    injectedCount++;
675                });
676
677                return injectedCount;
678            };
679
680            /* replace fetchWithCache with this improved variant */
681            const fetchWithCache = async (url, opts = {}) => {
682                const key = `tnew:${window.TNEW_BUILD}:${url}`; // versioned key prevents stale caches
683                try {
684                    const cached = sessionStorage.getItem(key);
685                    if (cached) return cached;
686                } catch (e) {
687                    // sessionStorage unavailable or quota exceeded — continue to network fetch
688                }
689
690                const res = await fetch(url, { cache: "no-cache", ...opts });
691                if (!res.ok) throw new Error(`Failed to fetch ${url}: ${res.status}`);
692                const txt = await res.text();
693
694                try {
695                    // avoid storing very large strings (safety check)
696                    if (txt.length < 200000) sessionStorage.setItem(key, txt);
697                } catch (e) {
698                    // ignore quota/other errors — don't break rendering
699                }
700                return txt;
701            };
702
703            try {
704                const headInject = document.getElementById("head-inject");
705                if (headInject) {
706                    const url = `${themeURL}${theme}-theme-header.html?v=${window.TNEW_BUILD}`;
707                    const headerHtml = await fetchWithCache(url);
708                    injectHeadFragment(headerHtml);
709                    headInject.innerHTML = "";
710                }
711
712                const bodyTopInject = document.getElementById("body-top-inject");
713                if (bodyTopInject) {
714                    const url = `${themeURL}${theme}-theme-body-top.html?v=${window.TNEW_BUILD}`;
715                    bodyTopInject.innerHTML = await fetchWithCache(url);
716                }
717
718                const footerInject = document.getElementById("footer-inject");
719                if (footerInject) {
720                    const url = `${themeURL}${theme}-theme-footer.html?v=${window.TNEW_BUILD}`;
721                    footerInject.innerHTML = await fetchWithCache(url);
722                }
723            } catch (error) {
724                console.error("Error injecting content:", error);
725            } finally {
726                // Remove loading indicator class when injection completes
727                try {
728                    document.documentElement.classList.remove("js-loading");
729                } catch (e) { }
730            }
731        }
732
733        // ===== Menu caret / submenu toggle module =====
734        // Ensures clicking a caret (or its pseudo-element) toggles only the associated submenu
735        ;(function () {
736        function closeSiblingSubmenus(li) {
737            if (!li || !li.parentElement) return
738            const siblings = Array.from(li.parentElement.children).filter(
739            (child) => child !== li && child.classList.contains('menu-item')
740            )
741            siblings.forEach((sib) => {
742            const sibSub = sib.querySelector('.sub-menu-container')
743            if (sibSub && sibSub.style.display !== 'none') {
744                sibSub.style.display = 'none'
745                sibSub.classList.remove('submenu-open')
746                const sibAnchor = sib.querySelector('.menu-link')
747                if (sibAnchor) sibAnchor.setAttribute('aria-expanded', 'false')
748            }
749            })
750        }
751
752        function toggleSubmenuForCaret(caret) {
753            const li = caret.closest('li')
754            if (!li) return
755            const submenu = li.querySelector('.sub-menu-container')
756            const anchor = li.querySelector('.menu-link')
757
758            // If there's no submenu, do nothing
759            if (!submenu) return
760
761            // Close sibling submenus first to avoid triggering previous submenu
762            //closeSiblingSubmenus(li)
763
764            const isOpen = window.getComputedStyle(submenu).display !== 'none'
765            if (isOpen) {
766            submenu.style.display = 'none'
767            submenu.classList.remove('submenu-open')
768            // remove open class on caret to revert pseudo-element transform
769            try { caret.classList.remove('menarrow-open') } catch (e) {}
770            if (anchor) anchor.setAttribute('aria-expanded', 'false')
771            } else {
772            submenu.style.display = 'block'
773            submenu.classList.add('submenu-open')
774            // add open class on caret to apply pseudo-element transform
775            try { caret.classList.add('menarrow-open') } catch (e) {}
776            if (anchor) anchor.setAttribute('aria-expanded', 'true')
777            }
778        }
779
780        document.addEventListener('click', function (e) {
781            const caret = e.target.closest && e.target.closest('.adx-caret-down.menarrow')
782            if (!caret) return
783            e.preventDefault()
784            e.stopPropagation()
785            toggleSubmenuForCaret(caret)
786        })
787
788        // Keyboard support for accessibility
789        document.addEventListener('keydown', function (e) {
790            if (e.key !== 'Enter' && e.key !== ' ') return
791            const active = document.activeElement
792            if (!active) return
793            if (active.classList && active.classList.contains('adx-caret-down') && active.classList.contains('menarrow')) {
794            e.preventDefault()
795            toggleSubmenuForCaret(active)
796            }
797        })
798        })()
799
800        // ** Function to Handle mobile menu toggle **
801        function toggleMobileMenu(event = null) {
802            if (event) {
803                event.preventDefault(); // Prevent link navigation
804            }
805
806            //Find the element .adx-hamburger
807            const hamburger = document.querySelector('.adx-hamburger');
808            if (!hamburger) return;
809
810            //check if expanded
811            const isExpanded = hamburger.classList.contains('mobile-menu-open');
812            
813            // Toggle the mobile menu open/close state
814            hamburger.classList.toggle('mobile-menu-open');
815
816            navmenu = document.querySelector('nav.navmenu');
817            if (navmenu) navmenu.classList.toggle('mobile-menu-open');
818
819            if (isExpanded) {
820                // Get the primary menu and set its position to static
821                const primaryMenu = document.querySelector(".primary-menu");
822                if (primaryMenu) primaryMenu.style.position = "static";
823            } else {
824                // Get the primary menu and set its position to fixed
825                const primaryMenu = document.querySelector(".primary-menu");
826                if (primaryMenu) primaryMenu.style.position = "fixed";
827            }
828        }
829    
830    </script>
830
831
832    <!-- END INJECTED HEAD -->
vendor: 77 bytes, lines 832-834
832
833    
834        <script async src="https://www.googletagmanager.com/gtag/js?id=
834G-H465QVKWXL
vendor: 12 bytes, line 834
834"></script>
835</head>
836<body>
837    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8PvrOawJPbFBm853VeoUrRXroWBD4wIX1upiVEfG-F2YpBDPEgl4aziJQCYGMl34xXQAk_fasgd5FwdFHfhi-pLwxRUEfahfM02Jy4O-FEJ3I8Hv7Oq7XgrqqFiORjVm4jTIKClXhUYXNRT5kxq2vttH-Dc-AUX4db3WRXkNyB7OaeHKQSAAzUBcK8qjzKJj5A" />
838<div style="display: none;" data-tn-component-property="32a0f2f8-6d0e-4f70-bb20-c03b3e9d24ad_FormSubmissionErrorMessage">Please correct the following error(s):</div><div style="display: none;" data-tn-component-property="aa1924f3-4985-41ce-aab1-77e385f42ecc_Heading">Are you sure you want to remove this item?</div><div style="display: none;" data-tn-component-property="aa1924f3-4985-41ce-aab1-77e385f42ecc_Body">If you are removing seats, you may not be able to reserve the same seats again.</div><div style="display: none;" data-tn-component-property="aa1924f3-4985-41ce-aab1-77e385f42ecc_DeleteItemButtonText">Remove Item</div><div style="display: none;" data-tn-component-property="aa1924f3-4985-41ce-aab1-77e385f42ecc_CancelButtonText">Cancel</div><div style="display: none;" data-tn-component-property="aa1924f3-4985-41ce-aab1-77e385f42ecc_RemoveNonInventoryItemSectionText">The item will be removed from your cart.</div>
839
840    <!-- BEGIN INJECTED HEADER -->
841    
842    <!-- Placeholder for header -->
843    <div id="head-inject">Loading header...</div> <!-- removed class="fade-in" -->
844
845    <!-- Placeholder for body top -->
846    <div id="body-top-inject">Loading body top content...</div> <!-- removed class="fade-in" -->
847
848    <!-- Main content -->
849    <div class="article-page-wrap">
850        <div id="content" class="article-page-content"> <!-- removed class="fade-in" -->
851            <div class="site-message" style="opacity: 0; display: none;">
852                <p>Site messages go here.</p>
853                <button class="btn site-message__close-btn" data-close="" aria-label="Close the alert message"> ×
854                </button>
855            </div>
856            <div id="search-modal" class="search-modal" aria-hidden="true">
857                <div class="search-modal__container">
858                    <div class="search-modal__content">
859                        <form class="search-form" role="search" method="get" action="https://cupresents.org/search/">
860                            <div class="search-input-group">
861                                <input type="text" name="search" placeholder="Search events, artists, series..."
862                                    class="search-input" aria-label="Search" />
863                                <button alt="Search" type="submit" class="search-submit">
864                                    <svg tabindex="-1" width="40" height="40" viewBox="0 0 40 40"
865                                        xmlns="http://www.w3.org/2000/svg" style="height: 25px; width: 25px;">
866                                        <circle cx="17.143" cy="18.571" r="8.571" fill="none" stroke="#000"
867                                            stroke-width="2"></circle>
868                                        <line x1="23.5" y1="24.9" x2="30.5" y2="31.9" stroke="#000" stroke-width="2"
869                                            stroke-linecap="round"></line>
870                                    </svg>
871                                    <span class="sr-only">Search</span>
872                                </button>
873                            </div>
874                        </form>
875                        <button alt="Close search" class="search-close" aria-label="Close search">
876                            ×
877                        </button>
878                    </div>
879                </div>
880            </div>
881            <div class="ast-container tnew-content" style="display: block !important;">
882                
883    <!-- END INJECTED HEADER -->
884
885
886
887
888
889
890
891
892<div class="tn-utility-nav">
893
894    <div class="tn-utility-nav-account-section__container">
895            <nav class="tn-utility-nav-account-section tn-utility-nav-account-section--logged-out" aria-labelledby="tn-utility-nav-account-heading">
896                <h2 id="tn-utility-nav-account-heading" class="sr-only">Account</h2>
897
898        <a class="tn-utility-nav-account-login-link btn btn-primary btn-sm" href="/account/login?returnurl=%2Fcart%2Fdetail
898s%3Fqueueittoken%3De_safetynet%7Ets_1790241980%7Ece_true%7Ert_safetynet%7Eh_8ad0494a4944a555e2f8eaeb02b468b9fa5e7117ac7a4181d7092b64e500d38a">
899            <svg aria-hidden="true" class="tn-icon tn-icon--person-fill tn-utility-nav-account-login-link__user-icon"><use xlink:href="/_images/sprites.svg#person-fill" /></svg>
900            Log In
901        </a>
902            </nav>
903    </div>
904
905
906    <section class="tn-utility-nav-cart-controls-section" aria-labelledby="tn-utility-nav-cart-controls-heading">
907        <h2 id="tn-utility-nav-cart-controls-heading" class="sr-only">Cart</h2>
908        <div class="tn-utility-nav-cart-timer" role="timer" >
909            <svg aria-hidden="true" class="tn-icon tn-icon--clock tn-utility-nav-cart-timer__icon"><use xlink:href="/_images/sprites.svg#clock" /></svg>
910            <span class="tn-utility-nav-cart-timer__label">
911                Time Remaining
912            </span>
913            <span class="tn-utility-nav-cart-timer__time"
914                  id="tn-count-down-timer"
915                  style="visibility: hidden;"
916                  data-tn-milliseconds-remaining="0">
917                00:00
918            </span>
919        </div>
920
921            <div class="tn-utility-nav-promo-code-section">
922                    <h3 class="sr-only">Enter Promo Code</h3>
923                    <form class="tn-utility-nav-inline-promo-code-form">
924                        <label class="tn-utility-nav-inline-promo-code-form__label" for="tn-utility-nav-inline-promo-code-form-input">Promo Code</label>
925
926                        <div class="tn-utility-nav-inline-promo-code-form__input-container">
927                            <input id="tn-utility-nav-inline-promo-code-form-input" class="tn-utility-nav-inline-promo-code-form__input form-control input-sm" required>
928                            <button type="submit" class="tn-utility-nav-inline-promo-code-form__btn-submit btn btn-primary btn-sm">
929                                <span class="tn-utility-nav-inline-promo-code-form__btn-submit-label">Submit</span>
930                            </button>
931
932                            <div class="tn-utility-nav-inline-promo-code-form__help-block-container">
933                                <div id="tn-utility-nav-inline-promo-code-form-help-block" class="tn-utility-nav-inline-promo-code-form__help-block">
934                                    <svg aria-hidden="true" class="tn-icon tn-icon--x-circle-fill tn-utility-nav-inline-promo-code-form__help-block-icon"><use xlink:href="/_images/sprites.svg#x-circle-fill" /></svg>
935                                    <span aria-live="assertive" class="tn-utility-nav-inline-promo-code-form__help-block-text"></span>
936                                </div>
937                            </div>
938                        </div>
939                    </form>
940                    <button type="button" class="tn-utility-nav-modal-promo-code-form__btn-open-modal btn btn-primary btn-sm">
941                        Promo Code
942                    </button>
943                    <form id="tn-utility-nav-modal-promo-code-form" novalidate style="display: none;">
944		<div class="form-group" data-control-group-for="ApplyPromoCode.PromoCode">
945<label class="control-label tn-promo-code" for="ApplyPromoCode_PromoCode"><span>Promo Code</span><span aria-hidden="true" class="tn-required-field">Required</span></label><input autocomplete="off" class=" form-control tn-promo-code" data-tn-form-control="true" id="ApplyPromoCode_PromoCode" name="ApplyPromoCode.PromoCode" required="required" type="text" value="" />		</div>
946                    </form>
947
948            </div>
949
950        <a href="/cart/details" class="tn-utility-nav-cart-link btn btn-primary btn-sm" aria-label="View Cart, 0 items">
951            <svg aria-hidden="true" class="tn-icon tn-icon--cart-fill tn-utility-nav-cart-link__icon"><use xlink:href="/_images/sprites.svg#cart-fill" /></svg>
952            <span class="tn-utility-nav-cart-link__label">View Cart</span>
953            <span class="tn-utility-nav-cart-link__quantity-badge">0</span>
954        </a>
955    </section>
956</div>
957
958
959
960<div style="display: none;" data-tn-component-property="2e16b93d-fa49-4b05-b981-9897dc177655_ExpiredModalTitle">Your cart has expired.</div><div style="display: none;" data-tn-component-property="2e16b93d-fa49-4b05-b981-9897dc177655_ExpiredModalText">
960Your order contained expired items and your shopping cart has been emptied.</div><div style="display: none;" data-tn-component-property="2e16b93d-fa49-4b05-b981-9897dc177655_ExpiredModalButton">Close</div><div style="display: none;" data-tn-component-property="2e16b93d-fa49-4b05-b981-9897dc177655_PromoCodeEntrySubhead">Enter Promo Code</div>
961    <main class="tn-cart-details-page" data-tn-page-type="6856252f-fc91-48fc-a119-9cf83a568d31">
962
963        
964
965
966<section class="tn-header-component">
967    <h1 class="tn-header-component__heading tn-heading " id="tn-page-heading">
968        Shopping Cart
969    </h1>
970
971    
972<div id="tn-error-message-template"></div>
973
974
975<div id="tn-alert-message-template"></div>
976
977
978
979        <div class="tn-header-component__sub-text tn-heading-sub-text">
980            <div class="theme">
981<div class="theme-cupresents" style="display:block;">
982<p><strong>For CU Boulder Faculty, Staff or Student discounts, add an "Adult" ticket to your cart and sign in with your colorado.edu email. Your discount shows at checkout (max 4 tickets/performance, excludes Holiday Festival, CSF Previews, Takács Digital and season tickets). More info on our <a href="https://cupresents.org/ticket-info/discounts/" target="_blank">discount page</a>.</strong><br />
983<br />
984Want to see where you're sitting? <a href="https://cupresents.org/your-visit/" rel="noopener" target="_blank">Check out our venue seating maps!</a></p>
985</div>
986
987<div class="theme-macky" style="display:none;">
988<p>Want to see where you're sitting? <a href="https://www.colorado.edu/macky/your-visit/seating-chart" rel="noopener" target="_blank">Check out our seating chart!</a></p>
989</div>
990</div>
991
992        </div>
993</section>
994
995
996
997
998
999
1000
1001
1002
1003<section class="tn-cart-component" aria-label="Cart Contents">
1004
1005        <div class="tn-empty-cart-message">
1006            Your cart is currently empty.
1007        </div>
1008</section>
1009
1010<div class="tn-cart-buttons">
1011    <div class="tn-cart-buttons__item-container">
1012        <a href="/events" class="tn-cart-buttons__secondary-action">
1013            Continue Shopping
1014        </a>
1015    </div>
1016        <div class="tn-cart-buttons__item-container">
1017                <button type="button" disabled class="tn-cart-buttons__primary-action btn btn-primary">
1018                    Check Out
1019                </button>
1020        </div>
1021</div>
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032    </main>
1033
1034    <!-- BEGIN INJECTED FOOTER -->
1035    
1036            </div>
1037        </div>
1038    </div>
1039
1040    <!-- Placeholder for footer -->
1041    <div id="footer-inject">Loading footer...</div> <!-- removed class="fade-in" -->
1042
1043    <!-- END INJECTED FOOTER -->
1044
1045    
1045<script src="https://production.tnew-assets.com/tnew/public/tnew-runtime.fbce9f756f163e3756fb.js"></script>
1045
1046    
1046<script src="https://production.tnew-assets.com/tnew/public/tnew-vendor.39238606c1acf31e864b.js"></script>
1046
1047    
1047<script src="https://production.tnew-assets.com/tnew/public/tnew.1724239e89aad2569486.js"></script>
1047
1048
1049    
1049<script>
1050        tnew.app.init({"appVersion":"16.0.48.8","tessituraVersion":"16.0.31.98728","environment":"production","rootUrl":"https://tickets.cupresents.org/","bcp47LanguageTag":"en-US","iso4217CurrencyCode":"USD","analyticsConfiguration":{"userId":0,"measurementIds":["G-H465QVKWXL","G-QJ8KBZM7GY"],"isGA4DatalayerEnabled":false,"isEnabled":true},"rumSettings":null,"calendarViewConfig":{"viewAsDayLabel":"Day","viewAsWeekLabel":"Week","viewAsMonthLabel":"Month","firstDayOfWeek":0,"weekdaysLabel":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"monthsLabel":["January","February","March","April","May","June","July","August","September","October","November","December"]}});
1051    </script>
1051
1052
1053    
1053<script>
1054        (function() {
1055            var orderDataModel = {"modeOfSale":0,"number":0,"fees":0.0,"total":0.0,"cartItems":[]};
1056
1057            var productDataModel = {"packageId":0,"productionSeasonId":0,"performanceId":0,"productTypeDescription":null,"contributionTypeId":0,"fundId":0,"onAccountPaymentMethodId":0,"giftCertificatePaymentMethodId":0,"membershipOrganizationId":0,"membershipLevelId":0};
1058
1059            var sessionDataModel = {"customerNumber":0,"sessionKey":"b2cnuxTjNo0JdoMfl5dynlazNBlLw3QmNXqHd5faQUxIrWvKUzutRn3+jFCZ66J8F8gl97Mm1Z+R8YSapirArtSrVPSactM5JCR//hfU99w2N+RBJ3ODZljadq/Nv6Xyx+UUy8LLsKf//EoMW/M0+DRmG3WuwltCxTApoEmXzmo=","modeOfSale":16,"isGuest":false,"isAnonymous":true,"sourceId":1,"isRenewalOrder":false};
1060
1061            var provider = new tnew.lib.GoogleDataLayerProvider(orderDataModel, productDataModel, sessionDataModel);
1062
1063            window.dataLayer = window.dataLayer || [];
1064
1065            var session = provider.getSession();
1066
1067            window.dataLayer.push(session);
1068
1069            var product = provider.getProduct();
1070
1071            window.dataLayer.push(product);
1072
1073            var order = provider.transformOrder();
1074
1075            if (order) {
1076                window.dataLayer.push(order);
1077            }
1078        })();
1079    </script>
1079
1080
1081
1082    
1083    
1084    
1084<script src="https://production.tnew-assets.com/tnew/public/tnew-cart-details.92971a8c37d350d2350c.js"></script>
1084
1085
1086    
1086<script>
1087        (function () {
1088            var jsPageData = {"isPaymentPlanSelectionVisible":false,"isPaymentPlanApplied":false,"ga4DatalayerItems":null,"removeFromCartAnalyticsMap":null};
1089
1090            window.tnew.page.initialize(jsPageData);
1091        })();
1092    </script>
1092
1093
1094
1095
1096    <!--
1097        
1098Session MOS: 16 / Original MOS: 16
1099Promo:  (1)
1100
1101    -->
1102<script type="text/javascript" src="/_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3&ns=2&cb=327295637" async></script>
1102</body>
1103</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.