PageSourceSearch

https://www.cincyticket.com/include/widgets/events/PerformanceList.js?v3

js cincyticket.com collected 2026-09-25 18:52:26 UTC 51,634 bytes, 894 lines download raw bytes

1//  ShoWare performance list display functions and AJAX calls:
2//      pages require the scripot element and #swPerformanceList container
3//      default settings can be achieved 
4
5//  functions:
6//clearPerformanceList() - clears the list object
7//doPerformanceList() - lists performances based on performanceListArgs{}
8//plLoadMore() - loads next page, page is tracked as loaded, but can be manipulated via performanceListArgs.page
9//fetchMessages() - AJAX reqeust populates messages{} object for performance list sales messages
10//fetchPerformances(args) - fetches performance, function fetchs AND builds performances via callback once list is fetched to buildPerformances(data)
11//    REQUIRES messages{} from fetchMessages();
12//buildPerformances(performances) - writes performance list items to page 
13
14//  initial run of fetchMessages() and fetchPerformances() performed automatically at end of page.
15
16var PerformanceList = $("#swPerformanceList");
17var siteURL = $("#swPerformanceListScript").attr('src').split("/");
18var initialLoad = true, listName;
19siteURL = "//" + siteURL[2] //protocol relative url
20
21var args = {},
22    messages = {},
23    loadedPerformances = [];
24
25function htmlEscape(str) {
26    if (str === null || str === undefined) {
27        return '';
28    }
29    return String(str).replace(/[&<>"']/g, function (ch) {
30        switch (ch) {
31            case '&': return '&amp;';
32            case '<': return '&lt;';
33            case '>': return '&gt;';
34            case '"': return '&quot;';
35            case "'": return '&#39;';
36            default: return ch;
37        }
38    });
39}
40
41if ($("#epPerformanceList").length) {
42    listName = "Event Page Performance List";
43} else {
44    listName = "Landing Page Performance List";
45}
46
47//build initial arguments from object
48performanceListArgs = {
49    //ARGS: '[FROMDATE]', '[TODATE]', [VENUE], '[CITY]', [EVENT], [CATEGORY], '[SEARCHSTRING]', [SEARCHTYPE], [NUMRESULTS], [ISMEMBER], [ISCORPORATEPARTNER], [SHOWHIDDEN], [SHOWPACKAGES], page
50    "fromDate": typeof PerformanceList.data("fromdate") !== 'undefined' ? PerformanceList.data("fromdate") : '',
51    "toDate": typeof PerformanceList.data("todate") !== 'undefined' ? PerformanceList.data("todate") : '',
52    "venue": typeof PerformanceList.data("venue") !== ('undefined') ? PerformanceList.data("venue") : 0,
53    "city": typeof PerformanceList.data("city") !== 'undefined' ? PerformanceList.data("city") : '',
54    "event": typeof PerformanceList.data("event") !== 'undefined' ? PerformanceList.data("event") : 0,
55    "category": typeof PerformanceList.data("category") !== 'undefined' ? PerformanceList.data("category") : 0,
56    "searchString": typeof PerformanceList.data("searchstring") !== 'undefined' ? PerformanceList.data("searchstring") : '',
57    "searchType": typeof PerformanceList.data("searchtype") !== 'undefined' ? PerformanceList.data("searchtype") : 0,
58    "showHidden": typeof PerformanceList.data("showhidden") !== 'undefined' ? PerformanceList.data("showhidden") : 0,
59    "coupon": typeof PerformanceList.data("coupon") !== 'undefined' ? PerformanceList.data("coupon") : '',
60    "showPackages": typeof PerformanceList.data("showpackages") !== 'undefined' ? PerformanceList.data("showpackages") : 1,
61    "listStyle": typeof PerformanceList.data("style") !== 'undefined' ? PerformanceList.data("style") : "default",
62
63    "listPageSize": typeof PerformanceList.data("listpagesize") !== 'undefined' ? PerformanceList.data("listpagesize") : "default",
64    "listMaxSize": typeof PerformanceList.data("listmaxsize") !== 'undefined' ? PerformanceList.data("listmaxsize") : 0,
65
66    "page": typeof PerformanceList.data("page") !== 'undefined' ? PerformanceList.data("page") : 1,
67
68    "corporatepartnerpage" : typeof PerformanceList.data("corporatepartnerpage") !== 'undefined' ? PerformanceList.data("corporatepartnerpage") : 0
69}
70
71//clear performance list and reset to a default list for update when the user calls doPerformancelist
72function clearPerformanceList() {
73
74    //set default options
75    performanceListArgs.fromDate = '';
76    performanceListArgs.toDate = '';
77    performanceListArgs.venue = 0;
78    performanceListArgs.city = '';
79    performanceListArgs.event = 0;
80    performanceListArgs.category = 0;
81    performanceListArgs.searchString = '';
82    performanceListArgs.searchType = 0;
83    performanceListArgs.showHidden = 0;
84    performanceListArgs.showPackages = 1;
85
86    performanceListArgs.listPageSize = "default";
87    performanceListArgs.listMaxSize = 0;
88
89    performanceListArgs.page = 1;
90
91    performanceListArgs.corporatepartnerpage = 0;
92
93    //remove the items from the list
94    PerformanceList.empty();
95
96    //remove any load more buttons
97    if ($("#loadMorePerformancesButton").length) {
98        $("#loadMorePerformancesButton").remove();
99    }
100}
101
102//function to call performance list with custom arguments after default load
103//usage:    the performance list should be part of the dom already, this allows the user
104//          to clearPerformanceList() and then rebuild performance lists based on new parameters.
105//          The performanceListArgs object should be manipulated before this function is called.
106//          without calling clearPerformanceList(), items will be appended to the list, and page number
107//          will be maintained.
108function doPerformanceList() {
109    fetchPerformances(performanceListArgs);
110}
111
112function plLoadMore(e) {
113    performanceListArgs.page = performanceListArgs.page + 1;
114    fetchPerformances(performanceListArgs);
115    //set button to loading if it exists
116    if ($("#loadMorePerformancesButton").length) {
117        $("#loadMorePerformancesButton .sw-icon-spinner").show();
118        $("#loadMorePerformancesButton .active-text").hide();
119    }
120}
121
122
123function swFormatDate(date) {
124    var dateRegex = /(.+)\s\d+:\d+:\d+.+/;
125    return date.replace(dateRegex, '$1');
126}
127
128function swFormatTime(date, endDate, showTimeRange) {
129    if (typeof endDate == "undefined") endDate = "";
130    if (typeof showTimeRange == "undefined") showTimeRange = 0;
131    var timeString = "";
132    var timeRegex = /.+\s(\d+:\d+):\d+(.+)/;
133    timeString = date.replace(timeRegex, '$1 $2');
134    if (showTimeRange) {
135        timeString += '-' + endDate.replace(timeRegex, '$1 $2');
136        timeString = timeString.split(' ').join(''); //save on spaces
137    }
138    return timeString
139}
140
141
142var performanceTemplate = buildPerformanceTemplate(performanceListArgs.listStyle);
143
144function fetchPerformances(args) {
145    //we're fetchin' performances, add a load more button if one doesn't exist to notify the patron that a list is loading
146    if ($("#loadMorePerformancesButton").length == 0) {
147        PerformanceList.parent().append('<button tabindex="0" id="loadMorePerformancesButton" class="button load-more-button sw-button-muted" onclick="plLoadMore();" style="width:100%;"><span class="active-text" style="display:none;" title="Load More Results">load more...</span><i class="sw-icon sw-icon-spinner"></i></button>');
148    }
149    //ARGS: '[FROMDATE]', '[TODATE]', [VENUE], '[CITY]', [EVENT], [CATEGORY], '[SEARCHSTRING]', [SEARCHTYPE], [NUMRESULTS], [ISMEMBER], [ISCORPORATEPARTNER], [SHOWHIDDEN], [SHOWPACKAGES]
150    //page -1 will result in the performance list not being called, allowing for performance lists to be set up without creating overhead.
151    if (args.page != -1) {
152        $.getJSON(siteURL + "/include/widgets/events/performancelist.asp", {
153                fromDate: args.fromDate,
154                toDate: args.toDate,
155                venue: args.venue,
156                city: args.city,
157                //event would be a terrible term to use
158                swEvent: args.event,
159                category: args.category,
160                searchString: args.searchString,
161                searchType: args.searchType,
162                showHidden: args.showHidden,
163                showPackages: args.showPackages,
164                action: "perf",
165                listPageSize: args.listPageSize,
166                listMaxSize: args.listMaxSize,
167                page: args.page,
168                cp: args.corporatepartnerpage
169            })
170            //performances = data;
171            .done(function(data) {
172                buildPerformances(data);
173            })
174            .fail(function(jqxhr, textStatus, error) {
175                var err = textStatus + ", " + error;
176                console.log("Request Failed: " + err);
177            })
178
179    } else {
180        initialLoad = false;
181    }
182}
183
184function buildPerformances(performances) {
185    //  Builds performance list items and appends them to the global performance list container
186    //      Called by fetchPErformances() function
187    //      performances object returned from /include/widgets/events/performancelist.asp 
188    //          - we can test this at   [url]/include/widgets/events/performancelist.asp?action=perf&page=1   - Other arguments available
189    //      each performance is built off of the performanceTemplate string
190    //*****************************************************************************************************************************************
191    //      ITEMS ADDED TO PERFOMANCE LISTS MUST BE ADDED TO THE TEMPLATE AND THEN REPLACED HERE - OTHERWISE THE TEMPLATE IS USELESS
192    //*****************************************************************************************************************************************
193    var loc = [], focusPerf,
194        perf, perfMarkup, packageBundleLink;
195    $(".no-event-msg").remove();
196    focusPerf = false;
197    if($(".pl-item").length){
198        focusPerf = $(".pl-item")[$(".pl-item").length - 1];
199    }
200    //Makes sure the performance list only shows when requested.
201    //Initial loads of the perormance list should be visibile only if they are set to be on the loading page
202    //following loads are assumed to be searches, and the list will be shown.
203    if (!initialLoad) {
204        $(".pl-wrap").show();
205        $(".event-performance-list-wrap .performance-list, #epPerformanceList .load-more-button").show();
206    }
207    initialLoad = false;
208    var indexOffset = loadedPerformances.length;
209    if (performances.performance.length === 0) {
210        $("#loadMorePerformancesButton").remove();
211        $(".no-perf-msg").remove();
212		PerformanceList.append("<span class='no-perf-msg'>(no performances)</span>");
213    }
214
215    var cpParameter = ""
216    cpParameter = (performanceListArgs.corporatepartnerpage=="1")?"&cp=1":"";
217
218    for (i = 0; i < performances.performance.length; i++) {
219        perfMarkup = performanceTemplate;
220        perf = performances.performance[i];
221        loc = perf.VenueLocation.split("|");
222        loadedPerformances.push(perf);
223        var itemCategory = "performance";
224        if (perf.EventID == -1) {
225            itemCategory = "bundle";
226        } else if (perf.isPackage) {
227            itemCategory = "package";
228        }
229        //add items to enhanced ecommerce as impressions
230        try {
231            swEnhancedEcommerce.addImpressions(perf.PerformanceName, perf.PerformanceCode, '', itemCategory, listName, i + indexOffset + 1);
232        } catch (e) { }
233
234        var backPage = window.location.pathname.replace("/", "").replace(".asp", "");
235        if (backPage == "") {
236            backPage = "default"
237        }
238        //bundles do not have an event name
239        if (perf.EventID == -1) {
240            //bundles do not have an event name
241            perfMarkup = perfMarkup.replace(/%EVENT%/g, perf.PerformanceName);
242            if (performances.settings.UseFlexBundles) {
243                perfMarkup = perfMarkup.replace(/%EVENTLINK%/g, 'BundleSelectTier.asp?BundleID=' + perf.PerformanceID);
244            } else {
245                perfMarkup = perfMarkup.replace(/%EVENTLINK%/g, 'BundlePurchase_Qty.asp?BundleID=' + perf.PerformanceID);
246            }
247        } else {
248            perfMarkup = perfMarkup.replace(/%EVENT%/g, perf.Event);
249            perfMarkup = perfMarkup.replace(/%EVENTLINK%/g, 'eventperformances.asp?evt=' + perf.EventID);
250        }
251        perfMarkup = perfMarkup.replace("%INDEX%", i + indexOffset);
252        if (perf.IsSalesPeriodStarted && !perf.IsSalesPeriodEnded && perf.SaleIcon == "buy tickets") {
253            //performance on sale, populate any performancelinks
254            var addCoupon = ''
255            if (performanceListArgs.coupon != '') {
256                addCoupon = '&coupon=' + performanceListArgs.coupon;
257            }
258            if (perf.EventID != -1) {
259                if(perf.InteractiveSeatmapActive === 1){
260                    //render full venue seating chart
261                     if (perf.SingleAreaVenueAreaID != 0 && !performances.settings.RedirectToGeneralMapOnAutoJump && performances.settings.PerfAutoJumpToSection == 1) {
262                        perfMarkup = perfMarkup.replace(/%PERFORMANCELINK%/g, '/orderticketsarea.asp?p=' + perf.PerformanceID + '&a=' + perf.SingleAreaVenueAreaID + '&src=' + backPage + addCoupon + cpParameter);
263                    } else {
264                        perfMarkup = perfMarkup.replace(/%PERFORMANCELINK%/g, '/ordertickets.asp?p=' + perf.PerformanceID + '&src=' + backPage + addCoupon + cpParameter);
265                    }
266                    
267                }else{
268                    //Handle single vs multi area
269                    if (perf.SingleAreaVenueAreaID != 0 && !performances.settings.RedirectToGeneralMapOnAutoJump && performances.settings.PerfAutoJumpToSection == 1) {
270                        perfMarkup = perfMarkup.replace(/%PERFORMANCELINK%/g, '/orderticketsarea.asp?p=' + perf.PerformanceID + '&a=' + perf.SingleAreaVenueAreaID + '&src=' + backPage + addCoupon + cpParameter);
271                    } else {
272                        perfMarkup = perfMarkup.replace(/%PERFORMANCELINK%/g, '/ordertickets.asp?p=' + perf.PerformanceID + '&src=' + backPage + addCoupon + cpParameter);
273                    }
274                }
275            } else {
276                if (performances.settings.UseFlexBundles) {
277                    perfMarkup = perfMarkup.replace(/%PERFORMANCELINK%/g, '/BundleSelectTier.asp?BundleID=' + perf.PerformanceID);
278                } else {
279                    perfMarkup = perfMarkup.replace(/%PERFORMANCELINK%/g, '/BundlePurchase_Qty.asp?BundleID=' + perf.PerformanceID);
280                }
281            }
282            perfMarkup = perfMarkup.replace(/%PERFDATEONCLICK%/g, '');
283        } else {
284            //performance not on sale, interrupt links
285            perfMarkup = perfMarkup.replace("%PERFORMANCELINK%", '');
286            perfMarkup = perfMarkup.replace(/%PERFDATEONCLICK%/g, 'return false;');
287        }
288        if (perf.Event != perf.PerformanceName && perf.EventID != -1) {
289            perfMarkup = perfMarkup.replace(/%PERFORMANCENAME%/g, perf.PerformanceName);
290        } else {
291            //Performance name is the same as event name, no event name is needed, or this is a bundle and has no event name
292            perfMarkup = perfMarkup.replace('%PERFORMANCENAME%', '').replace('tabindex="0"',"");
293        }
294        if (perf.PerformanceImage.toLowerCase() != "blank.gif" && perf.PerformanceImage != "" && perf.Image1.toLowerCase() != "blank.gif" && perf.Image1 != "") {
295
296        }
297        if (perf.PerformanceImage.toLowerCase() != "blank.gif" && perf.PerformanceImage != "") {
298            //performance image specfied, use that
299            perfMarkup = perfMarkup.replace('block-date-item', 'block-date-item has-image');
300            perfMarkup = perfMarkup.replace(/%PERFORMANCEIMAGE%/g, "/UPLImage/" + perf.PerformanceImage);
301        }
302        if (perf.Image1.toLowerCase() != "blank.gif" && perf.Image1 != "") {
303            //an event image exists, display if no performance image was found
304            perfMarkup = perfMarkup.replace('block-date-item', 'block-date-item has-image');
305            perfMarkup = perfMarkup.replace(/%PERFORMANCEIMAGE%/g, "/UPLImage/" + perf.Image1);
306        }
307        //replace any remaining image tokens in case neither image was specified
308        perfMarkup = perfMarkup.replace(/%PERFORMANCEIMAGE%/g, "/UPLImage/" + perf.Image1);
309        //bundle venue, city, and state values are not defined based on various locations being possible, and should not display without proper refactor
310        if (perf.EventID == -1) {
311            perfMarkup = perfMarkup.replace("%VENUENAME%", "");
312            perfMarkup = perfMarkup.replace("%CITY%", "");
313            perfMarkup = perfMarkup.replace("%STATE%", "");
314            //remove the leftover comma
315            perfMarkup = perfMarkup.replace("<span>,</span>", "");
316        }
317        perfMarkup = perfMarkup.replace("%VENUENAME%", perf.Venue);
318        perfMarkup = perfMarkup.replace("%SALESTATUSITEM%", setSaleStatus(perf, performances.settings));
319        
320        var limitedAvailabilityWrap = '';
321            if (
322                (perf.AvailableTicketsPercentage < perf.LimitedAvailabilityTrigger) &&
323                (
324                    (performances.settings.LimitedInventoryTitle && performances.settings.LimitedInventoryTitle.trim() !== '') ||
325                    (performances.settings.LimitedInventoryAdditionalDescription && performances.settings.LimitedInventoryAdditionalDescription.trim() !== '')
326                )
327            ) {
328                limitedAvailabilityWrap = '<div class="ondemand-performance-item-wrap">';
329                if (performances.settings.LimitedInventoryTitle && performances.settings.LimitedInventoryTitle.trim() !== '') {
330                    var escapedLimitedTitle = htmlEscape(performances.settings.LimitedInventoryTitle);
331                    limitedAvailabilityWrap += '<span class="indemand-title">' + escapedLimitedTitle + '</span>';
332                }
333                if (performances.settings.LimitedInventoryAdditionalDescription && performances.settings.LimitedInventoryAdditionalDescription.trim() !== '') {
334                    var escapedLimitedDesc = htmlEscape(performances.settings.LimitedInventoryAdditionalDescription);
335                    limitedAvailabilityWrap += ' <i class="fa fa-info-circle" title="' + escapedLimitedDesc + '"></i>';
336                }
337                limitedAvailabilityWrap += '</div>';
338            }
339            perfMarkup = perfMarkup.replace(/%LIMITEDAVAILABILITY%/g, limitedAvailabilityWrap);
340            
341        if(perf.DefaultViewShowPrice == 1){
342            if (perf.PerformanceMinPrice.toFixed(2) === perf.PerformanceMaxPrice.toFixed(2)) {
343                var ticketsPriceRange = '<div class="pl-pricerange-wrap"><span class="pricerange-alias">%DEFAULTVIEWPRICERANGELABELALIAS%</span> <span class="pricerange-min">
343%CURRENCYSYMBOL%%MINIMUMPRICE%</span></div>' 
344            } else {
345                var ticketsPriceRange = '<div class="pl-pricerange-wrap"><span class="pricerange-alias">%DEFAULTVIEWPRICERANGELABELALIAS%</span> <span class="pricerange-min">%CURRENCYSYMBOL%%MINIMUMPRICE%</span> <span class="pricerange-hash"> / </span> <span class="pricerange-max">%CURRENCYSYMBOL%%MAXIMUMPRICE%</span></div>'       
346            }
347        } else {
348            var ticketsPriceRange = ''
349        }
350        
351        perfMarkup = perfMarkup.replace("%DEFAULTVIEWSHOWPRICERANGE%", ticketsPriceRange);
352        perfMarkup = perfMarkup.replace("%DEFAULTVIEWPRICERANGELABELALIAS%", perf.DefaultViewPriceRangeLabelAlias);
353        perfMarkup = perfMarkup.replace(/%CURRENCYSYMBOL%/g, '$');
354        perfMarkup = perfMarkup.replace("%MINIMUMPRICE%", perf.PerformanceMinPrice.toFixed(2));
355        perfMarkup = perfMarkup.replace("%MAXIMUMPRICE%", perf.PerformanceMaxPrice.toFixed(2));
356
357        if(perf.DefaultViewShowTicketsAvailable == 1){
358            var ticketsAvailable = '<div class="pl-availabletickets"><span class="ticketsavailable-alias">%DEFAULTVIEWTICKETSAVAILABLEALIAS%</span> <span class="numberoftickets">%AVAILABLETICKETS%</span></div>'       
359        } else {
360            var ticketsAvailable = ''
361        }
362        perfMarkup = perfMarkup.replace("%DEFAULTVIEWSHOWTICKETSAVAILABLE%", ticketsAvailable);
363        perfMarkup = perfMarkup.replace("%AVAILABLETICKETS%", perf.AvailableTickets);
364        perfMarkup = perfMarkup.replace("%DEFAULTVIEWTICKETSAVAILABLEALIAS%", perf.DefaultViewTicketsAvailableAlias);
365
366       
367
368        if(perf.HasStream){
369            if(perf.StreamingOnly == 1){
370                var streamNote = '<div class="streaming-note"><a class="streaming-popup" href="Javascript:popUp(\'Streaming Details\',\'StreamingDetails.asp?p=%PVALUE%\', 400, 480,\'no\',\'yes\',\'no\',\'no\')"><img class="sw-icon streaming-icon" src="/images/stream-icon.svg" alt="Streaming Available">Streaming Only</a></div>';
371            }else{
372                var streamNote = '<div class="streaming-note"><a class="streaming-popup" href="Javascript:popUp(\'Streaming Details\',\'StreamingDetails.asp?p=%PVALUE%\', 400, 480,\'no\',\'yes\',\'no\',\'no\')"><img class="sw-icon streaming-icon" src="/images/stream-icon.svg" alt="Streaming Available">Streaming Available</a></div>';
373            }
374            perfMarkup = perfMarkup.replace("%STREAMNOTE%", streamNote);
375            perfMarkup = perfMarkup.replace("%PVALUE%", perf.PerformanceID)
376        }else{
377            perfMarkup = perfMarkup.replace("%STREAMNOTE%", '');
378        }
379        perfMarkup = perfMarkup.replace("%GOOGLEDATE%", perf.PerformanceDateTime);
380        if (perf.MultiDayPerformanceDate == 0 || perf.isPackage) {
381            perfMarkup = perfMarkup.replace("%PERFORMANCEDATE%", swFormatDate(perf.PerformanceDateTime));
382            perfMarkup = perfMarkup.replace("%PERFORMANCESHORTDATE%", perf.PerformanceDateTime.split(",")[1].split(' ')[1].replace(",", "").substring(0, 3) + " " + perf.PerformanceDateTime.split(",")[1].split(' ')[2].replace(",", ""));
383
384
385            if (perf.ShowTimeZone && !performances.settings.ShowEndTime) {
386                if (perf.PerformanceStartTimeAlias==""){
387                    perfMarkup = perfMarkup.replace("%PERFORMANCETIME%", swFormatTime(perf.PerformanceDateTime) + ' ' + perf.TimeZone);
388                }else{
389                    perfMarkup = perfMarkup.replace("%PERFORMANCETIME%", perf.PerformanceStartTimeAlias);
390                }
391            } else {
392                if (perf.PerformanceStartTimeAlias==""){
393                    perfMarkup = perfMarkup.replace("%PERFORMANCETIME%", '<span class="show-end-time-' + performances.settings.ShowEndTime + '">' + swFormatTime(perf.PerformanceDateTime, perf.PerformanceEndDateTime, performances.settings.ShowEndTime)) + '</span>';
394                }else{
395                    perfMarkup = perfMarkup.replace("%PERFORMANCETIME%", perf.PerformanceStartTimeAlias);
396                }
397                
398            }
399            perfMarkup = perfMarkup.replace("%PERFORMANCESHORTWEEKDAY%", perf.PerformanceDateTime.split(",")[0].substring(0, 3))
400            perfMarkup = perfMarkup.replace("%PERFORMANCEMONTHDAY%", perf.PerformanceDateTime.split(",")[1].split(' ')[2].replace(",", ""))
401            perfMarkup = perfMarkup.replace("%PERFORMANCESHORTMONTH%", perf.PerformanceDateTime.split(",")[1].split(' ')[1].replace(",", "").substring(0, 3))
402        } else {
403            var perfDateRangeDates = perf.MultiDayPerformanceDate.split(" - ");
404            try {
405                //remove year part of dates for easier reading, and to reduce chances of layout breaking due to narrow design and long dates - Example: "2/16 - 2/20"
406                perfDateRangeDates[0] = perfDateRangeDates[0].replace(/(\/20)[0-9]\w+/, '');
406 //multi-day performance start date in mm/dd format - not valid in single-day performances
407                perfDateRangeDates[1] = perfDateRangeDates[1].replace(/(\/20)[0-9]\w+/, ''); //multi-day performance end date in mm/dd format - not valid in single-day performances
408            } catch (e) {
409                console.log("Date Range String Invalid");
410                var perfDateRangeDates = new Array(2);
411                perfDateRangeDates = ["", ""];
412            }
413            perfMarkup = perfMarkup.replace("%PERFORMANCEDATE%", perf.MultiDayPerformanceDate);
414            perfMarkup = perfMarkup.replace('<span class="pl-time">%PERFORMANCETIME%</span>', '');
415            perfMarkup = perfMarkup.replace('block-date-item', 'block-date-item is-multi-day');
416            perfMarkup = perfMarkup.replace("%PERFORMANCESTARTDATE%", perfDateRangeDates[0]);
417            perfMarkup = perfMarkup.replace("%PERFORMANCEENDDATE%", perfDateRangeDates[1]);
418        }
419
420        packageBundleLink = '';
421        if (perf.isPackage) {
422            perfMarkup = perfMarkup.replace("%ISPACKAGE%", "is-package");
423            packageBundleLink = '<span class="package-link"><a href="Javascript:popUp(\'Package Details\',\'PackageDetailPopUp.asp?evt=' + perf.PerformanceID + '\', 400, 480,\'no\',\'yes\',\'no\',\'no\')"><span class="package-text-wrap">This is a ' + performances.settings.SysMsgPackageAlias + '. </span>Click here for Details</a>';
424        } else {
425            perfMarkup = perfMarkup.replace("%ISPACKAGE%", "");
426        }
427        if (perf.EventID == -1) {
428            perfMarkup = perfMarkup.replace("%ISBUNDLE%", "is-bundle");
429            packageBundleLink = '<span class="package-link"><a href="Javascript:popUp(\'Bundle Details\',\'BundleDetailPopUp.asp?BundleID=' + perf.PerformanceID + '\', 400, 480,\'no\',\'yes\',\'no\',\'no\')"><span class="bundle-text-wrap">This is a ' + performances.settings.SysMsgBundleAlias + '. </span>Click here for Details</a>';
430        } else {
431            perfMarkup = perfMarkup.replace("%ISBUNDLE%", "");
432        }
433        perfMarkup = perfMarkup.replace("%PACKAGEBUNDLELINK%", packageBundleLink);
434
435        //remove the moreinfo link if this is a package or a bundle
436        if (perf.isPackage || perf.EventID == -1 || perf.UseEventDescription == 1) {
437            perfMarkup = perfMarkup.replace('"pl-popup-link"', '"pl-popup-link no-show"');
438        }
439        if (perf.EventID == -1) {
440            perfMarkup = perfMarkup.replace("%POPUPLINK%", "BundleDetailPopUp.asp?BundleID=" + perf.PerformanceID)
441        } else if (perf.isPackage) {
442            perfMarkup = perfMarkup.replace("%POPUPLINK%", 'PackageDetailPopUp.asp?evt=' + perf.PerformanceID)
443        } else {
444            perfMarkup = perfMarkup.replace("%POPUPLINK%", 'PerformanceDetailPopUp.asp?evt=' + perf.PerformanceID)
445        }
446
447
448        perfMarkup = perfMarkup.replace("%CITY%", loc[0]);
449        perfMarkup = perfMarkup.replace("%STATE%", loc[1]);
450        
451        if (setMessages(perf, performances.settings) == "") {
452            perfMarkup = perfMarkup.replace('tabindex="0" class="pl-note pl-earlybooking-note"', '').replace("%EARLYBOOKING%", "");
453
454        } else {
455        perfMarkup = perfMarkup.replace("%EARLYBOOKING%", setMessages(perf, performances.settings));
456        }
457        if (perf.PeriodRestrictedMessage == "") {
458            perfMarkup = perfMarkup.replace('tabindex="0" class="pl-note pl-restricted-note"', '').replace("%PERIODRESTRICTED%", "")
459        } else {
460        perfMarkup = perfMarkup.replace("%PERIODRESTRICTED%", perf.PeriodRestrictedMessage);
461        }
462
463        //delete empty message containers
464        perfMarkup = perfMarkup.replace(/(\<span class\=\"pl\-note\"><\/span>)/g, '');
465
466        PerformanceList.append(perfMarkup);
467        //add qualifier buttons if needed
468        perf.qualifiers = perf.qualifiers || [];
469        if (perf.qualifiers.length) {
470            var plItem = $($(".pl-item")[$(".pl-item").length - 1]);
471            addQualifiers(plItem, perf.qualifiers, performances.settings, perf);
472        }
473    }
474    extractIcons();
475    if (focusPerf) {
476        $(focusPerf).find(":tabbable").focus();
477    }
478
479    //set load more button to active if it exists
480    if ($("#loadMorePerformancesButton").length) {
481        $("#loadMorePerformancesButton .sw-icon-spinner").hide();
482        $("#loadMorePerformancesButton .active-text").show();
483    }
484    //check if we've reached the end of the performances
485    if (performances.settings.endOfList) {
486        //remove any load more buttons
487        if ($("#loadMorePerformancesButton").length) {
488            $("#loadMorePerformancesButton").remove();
489        }
490    } else {
491        //if the performancelist doesn't have a load more button, add one
492    if ($("#loadMorePerformancesButton").length == 0 && performances.performance.length > 0) {
493            PerformanceList.parent().append('<a id="loadMorePerformancesButton" class="button load-more-button sw-button-muted" onclick="plLoadMore();"><span class="active-text">load more...</span><i class="sw-icon sw-icon-spinner"></i></a>');
494        }
495    }
496
497    PerformanceList.data("perf-count", performances.perfCount);
498    //EventPerformances.asp check for event calendar if events are too many
499    if (typeof displayEventPerformancesCalendar == 'function') {
500        //send over performancelist size data explicitly
501        displayEventPerformancesCalendar(performances.perfCount)
502    }
503    if (typeof updateCalendarDateByCategory == 'function') {
504        updateCalendarDateByCategory($("#categorySelect").val() !== 'undefined' ? $("#categorySelect").val() : 0);
505    }
506    //send enhanced ecommerce impressions
507    try {
508        swEnhancedEcommerce.sendImpressions();
509        swEnhancedEcommerce.clearImpressions();
510    } catch (e) { }
511
512}
513
514function setSaleStatus(perf, settings) {
515
516    var isRestrictedToMembers = (perf.AccessRestricted == 1 || perf.EventAccessRestricted == 1);
517    var isAllowedByMembershipLevel = perf.hasAccessLevel;
518    var accessMemberRestrictions = perf.AccessMemberRestriction;
519    var isPerformanceConfiguredToSell = (perf.SaleIcon == "buy tickets" || (perf.IsMentaEnabled && perf.MentaMarketplace && perf.MentaMarketplace.buttonVisible));
520    var isInEarlyBookingPhase = (perf.EarlyBooking == 1 && perf.EarlyBookingPhase == 1)
521
522    if (perf.IsSalesPeriodEnded) {
523        //if available at the gate or free show status
524        if ((perf.ManualStatus == 9 || perf.ManualStatus == 10) || (perf.ManualStatus == 1 ))
525            return renderStatus(perf.SaleIcon, perf, settings);
526        else{
527			var salesEndedMsg="sale stopped";
528			if (settings.CustomSalesEndedSoldOutMsg){
529				salesEndedMsg=settings.CustomSalesEndedSoldOutMsg;
530			}
531            return '<div class="pl-sale-status" tabindex="0" describedby="early-booking-info-%%COUNT%% access-restricted-info-%%COUNT%%">'+salesEndedMsg+'</div>'; //sale over
532		}
533    } else {
534        if (isPerformanceConfiguredToSell) {
535            if (perf.IsSalesPeriodStarted) {
536                //Performance is in the sale period and configured to allow sales
537                //so check restrictions       
538                if ((accessMemberRestrictions == 0) || ((accessMemberRestrictions == 1) && (isRestrictedToMembers && settings.isMember)) || (!isRestrictedToMembers)) {
539                    //membership required for purchase of event or performance
540                    return renderButton(perf, settings);
541                } else if ((accessMemberRestrictions == 2) && (isAllowedByMembershipLevel)) {
542                    //Level required according to the Levels allowedn in the Event Access restriction settings
543                    return renderButton(perf, settings);
544                } else {
545                    return renderStatus(settings.MembershipMsgMemberAlias + 's only', perf, settings);
546                }
547            } else {
548
549                //Sale has not yet started so see if we can offer early booking
550                if (perf.hasEarlyBookingAccess && (perf.EarlyBookingPhase != 0 || (perf.EarlyBookingForLevels & isAllowedByMembershipLevel))) {
551                    return renderButton(perf, settings);
552
553                } else {
554                    //non-member or early booking not enabled
555                    return renderStatus(perf.BSaleIcon, perf, settings);
556
557                }
558            }
559        } else {
560            //a manual status has been set on the performance that is
561            //preventing sales to take place
562            if (perf.IsSalesPeriodStarted)
563                return renderStatus(perf.SaleIcon, perf, settings);
564            else
565                return renderStatus(perf.BSaleIcon, perf, settings);
566        }
567    }
568}
569
570function renderButton(perf, settings) {
571    //<a itemprop="url" href="%BUYLINK%" class="button buy-tickets" title="Click here to Purchase">%BUTTONTEXT%</a>
572    var btnText, perfURL;
573
574    btnText = settings.BuyTicketsButtonText; //DEFAULT
575    if(perf.StreamingOnly){
576        btnText = "Purchase Stream"
577    }
578    if (perf.AlternateBuyButtonText != "") {
579        btnText = perf.AlternateBuyButtonText;
580    } else {
581        if (perf.EventID == -1) {
582            btnText = 'Buy ' + settings.SysMsgBundleAlias;
583        }
584    }
585    if(perf.IsMentaEnabled && perf.MentaMarketplace && perf.MentaMarketplace.buttonVisible){
586        btnText = perf.MentaMarketplace.buttonText;
587    }
588    var cpParameter = ""
589    cpParameter = (performanceListArgs.corporatepartnerpage=="1")?"&cp=1":"";
590
591    if (perf.RedirectionEnabled) {
592        var BuyTicketsRedirectLink = "/redirect.asp?id=" + perf.PerformanceID;
593        return '<a describedby="early-booking-info-%%COUNT%% access-restricted-info-%%COUNT%%" itemprop="url" href="' + BuyTicketsRedirectLink + '" class="button buy-tickets redirect-button" title="Click here to purchase elsewhere">' + btnText + '</a>'
594    } else {
595        var addCoupon = ''
596        if (performanceListArgs.coupon != '') {
597            addCoupon = '&coupon=' + performanceListArgs.coupon;
598        }
599        var backPage = window.location.pathname.replace("/", "").replace(".asp", "");
600        if (backPage == "") {
601            backPage = "default"
602        }
603        if (perf.EventID != -1) {
604            if(perf.InteractiveSeatmapActive === 1 && perf.SingleAreaVenueAreaID == 0){    
605                perfURL = '/orderticketsvenue.asp?p=' + perf.PerformanceID + addCoupon + cpParameter;
606            }else{
607                //Handle single vs multi area                
608                if (perf.SingleAreaVenueAreaID != 0 && !settings.RedirectToGeneralMapOnAutoJump && settings.PerfAutoJumpToSection == 1) {
609                    perfURL = '/orderticketsarea.asp?p=' + perf.PerformanceID + '&a=' + perf.SingleAreaVenueAreaID + '&src=' + backPage + addCoupon + cpParameter;
610                } else {
611                    perfURL = '/ordertickets.asp?p=' + perf.PerformanceID + '&src=' + backPage + addCoupon + cpParameter;
612                }
613            }
614        } else {
615            if (settings.UseFlexBundles) {
616                perfURL = '/BundleSelectTier.asp?BundleID=' + perf.PerformanceID;
617            } else {
618                perfURL = '/BundlePurchase_Qty.asp?BundleID=' + perf.PerformanceID;
619            }
620        }
621        if(perf.StreamingOnly == 1 && perf.HasStream){
622            perfURL = '/orderstream.asp?p=' + perf.PerformanceID;
623        }
624        perfURL = settings.ProtocolRelativeURL + perfURL;
625        return '<a describedby="early-booking-info-%%COUNT%% access-restricted-info-%%COUNT%%" itemprop="url" href="' + perfURL + '" class="button buy-tickets" title="Click here to ' + btnText + '">' + btnText + '</span></a>'
626    }
627}
628
629function renderStatus(status, perf, settings) {
630    perf.qualifiers = perf.qualifiers || [];
631    if ((!perf.IsSalesPeriodStarted && perf.BSalePhone) || (perf.IsSalesPeriodStarted && perf.SalePhone)) {
632        return '<a describedby="early-booking-info-%%COUNT%% access-restricted-info-%%COUNT%%" tabindex="0" class="pl-sale-status" href="tel:' + settings.CallCenterPhone + '" >' + status + '<br>' + settings.CallCenterPhone + '</a>';
633    } else {
634        if (String(status).trim().toLowerCase() === "sold out" && perf.qualifiers.length > 0) { 
635            return '';
636        } else {
637            return '<div tabindex="0" describedby="early-booking-info-%%COUNT%% access-restricted-info-%%COUNT%%" class="pl-sale-status sold-out-status" >' + status + '</div>';
638        }
639        
640    }
641}
642
643function setMessages(perf, settings) {
644
645    var message = "";
646    var isRestrictedToMembers = (perf.AccessRestricted == 1 || perf.EventAccessRestricted == 1);
647
648    if (perf.IsSalesPeriodEnded) {
649        if (perf.ManualStatus == 9 || perf.ManualStatus == 10) //if it's free or available at the gate and the sales period is ended don't show message
650            message = "";
651        else {
652            if (settings.afterSaleSatus == 4)
653                message = "Online sale stopped on " + swFormatDate(perf.SalesEnd) + " at " + swFormatTime(perf.SalesEnd, "", 0) + " " + perf.TimeZone;
654            else
655                message = "";
656        }
657    } else {
658        if (perf.IsSalesPeriodStarted) {
659            if (isRestrictedToMembers) {
660                if (settings.isMember) {
661                    message = settings.MembershipMsgMemberAlias + "s only!";
662                } else {
663                    //you need a membership to buy tickets message..does not currently exist
664                }
665            } else {
666                //you can buy tickets message..does not currently exist
667            }
668        } else {
669            //not on sale yet, so show the early booking message provided by sproc 
670            //EventPerformance_PerformanceListing		
671            //NOTE: The early booking message will contain both the early booking
672            //message and the message that is displayed when early booking
673            //is not enabled
674            if (perf.ManualStatus == 9 || perf.ManualStatus == 10) //if it's free or available at the gate don't show early booking message
675                message = "";
676            else
677                message = perf.EarlyBookingMessage;
678        }
679    }
680
681    message = message.replace(/%EBSTARTDATE%/g, swFormatDate(perf.EarlyBookingStart));
682    message = message.replace(/%EBSTARTTIME%/g, swFormatTime(perf.EarlyBookingStart, "", 0));
683    message = message.replace(/%REGSTARTDATE%/g, swFormatDate(perf.SalesStart));
684    message = message.replace(/%REGSTARTTIME%/g, swFormatTime(perf.SalesStart, "", 0));
685    message = message.replace(/%TZONE%/g, perf.TimeZone);
686
687    return message;
688}
689function addQualifiers(plContainer, qualifierSet, settings, performance) {
690    
691    var qualifierDiv = document.createElement("div");
692    qualifierDiv.setAttribute("class", "qualifier-wrap clear");
693    var qualifierMessage = document.createElement("span");
694    qualifierMessage.setAttribute("class", "qualifier-message");
695    qualifierMessage.innerHTML = settings.QualifierMessage;
696    $(qualifierDiv).append(qualifierMessage);
697    for (var i = 0; i < qualifierSet.length; i++) {
698        //multiple qualifers can apply to an individual performance.
699        qual = qualifierSet[i];
700        if (qual.HasCardAccess > 0) {
701            //render the paymenttype display text qualifier
702            renderQualifier(qualifierDiv, qual.QualifierID, performance.PerformanceID, "payment", qual.PTDisplayText);
703        }
704        if (qual.HasPassword > 0) {
705            //render the paymenttype display text qualifier
706            renderQualifier(qualifierDiv, qual.QualifierID, performance.PerformanceID, "password", qual.PWDisplayText);
707        }
708        if (qual.HasAccessCodes > 0 && settings.AccessCodesEnabled) {
709            //render the paymenttype display text qualifier
710            renderQualifier(qualifierDiv, qual.QualifierID, performance.PerformanceID, "accesscode", qual.ACDisplayText);
711        }
712        if (qual.MembershipRestrictionTypeID > 0 && settings.MembershipsEnabled) {
713            //render the paymenttype display text qualifier
714            renderQualifier(qualifierDiv, qual.QualifierID, performance.PerformanceID, "membership", qual.MBDisplayText);
715        }
716    }
717    $(plContainer).append(qualifierDiv);
718}
719
720function renderQualifier(container, qualifierID, performanceID, qualifierType, qualifierButtonText) {
721    if (qualifierButtonText == "")
722        qualifierButtonText = "Premium Access"
723    var qualifierLink = ["PremiumTickets.asp?performanceid=", performanceID, "&qualifierid=", qualifierID, "&qualifiertype=", qualifierType].join("");
724    var qualifierButton = document.createElement("button");
725    qualifierButton.setAttribute("class", "button qualifier-buy-button");
726    qualifierButton.setAttribute("onclick", "window.location.href='" + qualifierLink + "'");
727    qualifierButton.innerHTML = qualifierButtonText;
728    $(container).append(qualifierButton);
729}
730
731//initial call to perform list on load
732fetchPerformances(performanceListArgs);
733
734
735function buildPerformanceTemplate(templateType) {
736    var templateString = ''
737    
738    switch (templateType) {
739        case "PerformanceBlockDateList":
740            templateString += '     <div class="pl-item block-date-item %ISPACKAGE% %ISBUNDLE%" data-index="%INDEX%">'
741            templateString += '			<a class="performance-block-date-link" href="%PERFORMANCELINK%" onclick="%PERFDATEONCLICK%">'
742            templateString += '			    <div class="pl-date-block">'
743            templateString += '			        <div class="pl-date-block-image" style=\'background-image:url("%PERFORMANCEIMAGE%")\'></div>'
744            templateString += '				    <div class="pl-weekday">'
745            templateString += '					    %PERFORMANCESHORTWEEKDAY%'
746            templateString += '				    </div>'
747            templateString += '				    <div class="pl-monthday">'
748            templateString += '					    %PERFORMANCEMONTHDAY%'
749            templateString += '				    </div>'
750            templateString += '				    <div class="pl-month">'
751            templateString += '					    %PERFORMANCESHORTMONTH%'
752            templateString += '				    </div>'
753            templateString += '			    </div>'
754            templateString += '			    <div class="pl-date-block multi-day-dates">'
755            templateString += '			        <div class="pl-date-block-image" style=\'background-image:url("%PERFORMANCEIMAGE%")\'></div>'
756            templateString += '				    <div class="pl-start-date multi-date">'
757            templateString += '					    %PERFORMANCESTARTDATE%'
758            templateString += '				    </div>'
759            templateString += '                 <div class="multi-day-date-divide">to</div>'
760            templateString += '				    <div class="pl-end-date multi-date">'
761            templateString += '					    %PERFORMANCEENDDATE%'
762            templateString += '				    </div>'
763            templateString += '			    </div>'
764            templateString += '			</a>'
765            templateString += '			<div class="pl-first-col">'
766            templateString += '				<h3 class="pl-event-name"><a tabindex="0" class="pl-event-link" href="%EVENTLINK%">%EVENT%</a></h3>'
767            templateString += '				<h3 class="pl-performance-name">%PERFORMANCENAME%</h3>'
768            templateString += '				<a class="pl-popup-link" href="Javascript:popUp(\'More Info\',\'%POPUPLINK%\', 400, 480,\'no\',\'yes\',\'no\',\'no\')">more info</a>'
769            templateString += '                %PACKAGEBUNDLELINK%'
770            templateString += '			</div><!--END .first-col END-->'
771            templateString += '			<div class="pl-second-col">'
772            templateString += '             %STREAMNOTE%'
773            templateString += '				%SALESTATUSITEM%'
774            templateString += '				<span class="pl-time">%PERFORMANCETIME%</span>'
775            templateString += '				<div class="pl-venue" tabindex="0">'
776            templateString += '					<span>%VENUENAME%</span>'
777            templateString += '					<span>%CITY%,</span> <span>%STATE%</span>'
778            templateString += '				</div>'
779            templateString += '			</div><!--.END second-col END-->'
780            templateString += '			<div class="pl-bottom">'
781            templateString += '				<div tabindes="0" class="pl-note">%EARLYBOOKING%</div>'
782            templateString += '			</div>'
783            templateString += '			<div class="pl-bottom">'
784            templateString += '				<div tabindex="0" class="pl-note">%PERIODRESTRICTED%</div>'
785            templateString += '			</
785div>'
786            templateString += '			<div style="clear:right;"></div>'
787            templateString += '		</div>';
788            break;
789        case "PerformanceBlockTimeList":
790            templateString += '     <div class="pl-item block-time-item %ISPACKAGE% %ISBUNDLE%" data-index="%INDEX%">'
791            templateString += '			<a class="performance-block-time-link" href="%PERFORMANCELINK%" onclick="%PERFDATEONCLICK%">'
792            //this is the date block for single-day performances, if this is a multi-date performance this section will be deleted
793            templateString += '			    <div class="pl-time-block">'
794            templateString += '			        <div class="pl-time-block-image" style=\'background-image:url("%PERFORMANCEIMAGE%")\'></div>'
795            templateString += '				    <div class="pl-weekday">'
796            templateString += '					    %PERFORMANCESHORTWEEKDAY%'
797            templateString += '				    </div>'
798            templateString += '				    <div class="pl-time">'
799            templateString += '					    %PERFORMANCETIME%'
800            templateString += '				    </div>'
801            templateString += '				    <div class="pl-month">'
802            templateString += '					    %PERFORMANCESHORTDATE%'
803            templateString += '				    </div>'
804            templateString += '			    </div>'
805            //this is the date block for multi-day performances, if this is a single-day performance, this section will be delted
806            templateString += '			    <div class="pl-time-block multi-day-dates">'
807            templateString += '				    <div class="pl-start-date multi-date">'
808            templateString += '					    %PERFORMANCESTARTDATE%'
809            templateString += '				    </div>'
810            templateString += '                 <div class="multi-day-date-divide">to</div>'
811            templateString += '				    <div class="pl-end-date multi-date">'
812            templateString += '					    %PERFORMANCEENDDATE%'
813            templateString += '				    </div>'
814            templateString += '			    </div>'
815            templateString += '			</a>'
816            templateString += '			<div class="pl-first-col">'
817            templateString += '				<h3 class="pl-event-name"><a tabindex="0" class="pl-event-link" href="%EVENTLINK%">%EVENT%</a></h3>'
818            templateString += '				<h3 class="pl-performance-name">%PERFORMANCENAME%</h3>'
819            templateString += '				<a class="pl-popup-link" href="Javascript:popUp(\'More Info\',\'%POPUPLINK%\', 400, 480,\'no\',\'yes\',\'no\',\'no\')">more info</a>'
820            templateString += '                %PACKAGEBUNDLELINK%'
821            templateString += '			</div><!--END .first-col END-->'
822            templateString += '			<div class="pl-second-col">'
823            templateString += '             %STREAMNOTE%'
824            templateString += '				%SALESTATUSITEM%'
825            templateString += '				<div class="pl-venue" tabindex="0">'
826            templateString += '					<span>%VENUENAME%</span>'
827            templateString += '					<span>%CITY%,</span> <span>%STATE%</span>'
828            templateString += '				</div>'
829            templateString += '			</div><!--.END second-col END-->'
830            templateString += '			<div class="pl-bottom">'
831            templateString += '				<span tabindex="0" class="pl-note">%EARLYBOOKING%</span>'
832            templateString += '			</div>'
833            templateString += '			<div class="pl-bottom">'
834            templateString += '				<span tabindex="0" class="pl-note">%PERIODRESTRICTED%</span>'
835            templateString += '			</div>'
836            templateString += '			<div style="clear:right;"></div>'
837            templateString += '		</div>';
838            break;    
839        default:
840            templateString += '     <div class="pl-item default-item %ISPACKAGE% %ISBUNDLE%"  data-index="%INDEX%">'
841            templateString += '			<div class="pl-first-col">'
842            templateString += '				<h3 class="pl-event-name"><a tabindex="0" class="pl-event-link" href="%EVENTLINK%" aria-describedby="perf-name-%%COUNT%% perf-date-%%COUNT%%">%EVENT%</a></h3>'
843            templateString += '				<h3 id="perf-name-%%COUNT%%" class="pl-performance-name" tabindex="0">%PERFORMANCENAME%</h3>'
844            templateString += '				<a class="pl-popup-link" href="Javascript:popUp(\'More Info\',\'%POPUPLINK%\', 400, 480,\'no\',\'yes\',\'no\',\'no\')">more info</a>'
845            templateString += '                %PACKAGEBUNDLELINK%'
846            templateString += '			</div><!--END .first-col END-->'
847            templateString += '			<div class="pl-second-col">'
848            templateString += '				<div tabindex="0" id="perf-date-%%COUNT%%" class="pl-datetime">'
849            templateString += '					<span class="pl-date">'
850            templateString += '						<time>%PERFORMANCEDATE%</time>'
851            templateString += '					</span>'
852            templateString += '					<span class="pl-time">%PERFORMANCETIME%</span>'
853            templateString += '				</div>'
854            templateString += '				<span tabindex="0" class="pl-venue">'
855            templateString += '					<span>%VENUENAME%</span>'
856            templateString += '					<span>%CITY%,</span> <span>%STATE%</span>'
857            templateString += '				</span>'
858            templateString += '				%DEFAULTVIEWSHOWPRICERANGE%'
859            templateString += '				%DEFAULTVIEWSHOWTICKETSAVAILABLE%'
860            templateString += '             %STREAMNOTE%'
861            templateString += '				%LIMITEDAVAILABILITY%'
862            templateString += '				%SALESTATUSITEM%'
863            templateString += '			</div><!--.END second-col END-->'
864            templateString += '			<div id="early-booking-info-%%COUNT%%" class="pl-bottom">'
865            templateString += '				<span tabindex="0" class="pl-note pl-earlybooking-note">%EARLYBOOKING%</span>'
866            templateString += '			</div>'
867            templateString += '			<div id="access-restricted-info-%%COUNT%%" class="pl-bottom">'
868            templateString += '				<span tabindex="0" class="pl-note pl-restricted-note">%PERIODRESTRICTED%</span>'
869            templateString += '			</div>'
870            templateString += '			<div style="clear:right;"></div>'
871            templateString += '		</div>';
872            break;
873    }
874
875    return templateString;
876}
877
878//functions to report clicks
879$("#swPerformanceList").on('click', '.pl-event-link, a.buy-tickets', function (e) {
880    var myIndex = $(this).closest(".pl-item").data("index");
881    var itemCategory = "performance";
882    try {
883        var product = loadedPerformances[myIndex];
884        if (product.EventID == -1) {
885            itemCategory = "bundle";
886        } else if (product.isPackage) {
887            itemCategory = "package";
888        }
889        swEnhancedEcommerce.addProducts(product.PerformanceName, product.PerformanceCode, '', itemCategory, myIndex + 1);
890        swEnhancedEcommerce.sendProducts(listName);
891        swEnhancedEcommerce.clearProducts();
892    } catch (e) { console.log(e) }
893    
894});

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.