1//==================================================Search area==================// 2(function ($) { 3 "use strict"; 4 5 /* Open a dynamically loaded jQuery UI date picker once its AJAX-injected 6 initialization script has attached the widget. */ 7 function wbtm_open_date_picker(input, attempts) { 8 attempts = typeof attempts === 'number' ? attempts : 12; 9 if (!input || !input.length) { 10 return; 11 } 12 if ($.fn.datepicker && input.hasClass('hasDatepicker')) { 13 window.setTimeout(function () { 14 input.trigger('focus'); 15 input.datepicker('show'); 16 }, 0); 17 return; 18 } 19 if (attempts > 0) { 20 window.setTimeout(function () { 21 wbtm_open_date_picker(input, attempts - 1); 22 }, 50); 23 } 24 } 25 26 $(document).on("click", "#wbtm_area button.get_wbtm_bus_list", function (e) { 27 e.preventDefault(); 28 let searchArea = $(this).closest('.wbtm_search_area'); 29 let parent = searchArea.closest('#wbtm_area'); 30 let start = searchArea.find('input[name="bus_start_route"]').first(); 31 let end = searchArea.find('input[name="bus_end_route"]').first(); 32 let j_date = searchArea.find('input[name="j_date"]').first(); 33 if (!mp_check_required(start)) { 34 start.trigger('click'); 35 return false; 36 } 37 if (!mp_check_required(end)) { 38 end.trigger('click'); 39 return false; 40 } 41 if (!mp_check_required(j_date)) { 42 j_date.siblings('input').focus(); 43 return false; 44 } else { 45 let r_date = searchArea.find('input[name="r_date"]').first(); 46 let isReturnSearch = searchArea.closest('#etc_panel_return').length > 0; 47 if (isReturnSearch && (!r_date.length || !r_date.val())) { 48 return false; 49 } 50 let post_id = searchArea.find('[name="wbtm_post_id"]').first().val(); 51 $.ajax({ 52 type: 'POST', 53 url: mp_ajax_url, 54 data: { 55 "action": "get_wbtm_bus_list", 56 "start_route": start.val(), 57 "end_route": end.val(), 58 "j_date": j_date.val(), 59 "r_date": r_date.length ? r_date.val() : '', 60 "post_id": post_id, 61 }, 62 beforeSend: function () { 63 dLoader(parent); 64 }, 65 success: function (data) { 66 parent.find('.wbtm_search_result').html(data).promise().done(function () { 67 dLoaderRemove(parent); 68 loadBgImage(); 69 }); 70 }, 71 error: function (response) { 72 console.log(response); 73 } 74 }); 75 } 76 }); 77 $(document).on("click", "#wbtm_area button.wbtm_next_date", function () { 78 let date = $(this).data('date'); 79 let parent = $(this).closest('#wbtm_area'); 80 let searchArea = parent.find('.etc_tab_panel.etc_panel_active .wbtm_search_area').first(); 81 if (!searchArea.length) { searchArea = parent.find('.wbtm_search_area:visible').first(); } 82 if (!searchArea.length) { searchArea = parent.find('.wbtm_search_area').first(); } 83 let name = $(this).closest('#wbtm_return_container').length > 0 ? 'r_date' : 'j_date'; 84 searchArea.find('input[name=' + name + ']').first().val(date).trigger('change').promise().done(function () { 85 searchArea.find('.get_wbtm_bus_list').first().trigger('click'); 86 }); 87 }); 88 $(document).on("mp_change", "div.wbtm_search_area .wbtm_start_point input.formControl", function () { 89 let current = $(this); 90 let start_route = current.val(); 91 let parent = current.closest('.wbtm_search_area'); 92 let target = parent.find('.wbtm_dropping_point'); 93 parent.find('.wbtm_dropping_point .mp_input_select_list').remove(); 94 target.find('input.formControl').val(''); 95 dLoader_xs(parent); 96 let exit_route = 0; 97 parent.find('.wbtm_start_point .mp_input_select_list li').each(function () { 98 let current_route = $(this).data('value'); 99 if (current_route === start_route) { 100 exit_route = 1; 101 } 102 }).promise().done(function () { 103 if (exit_route > 0) { 104 let post_id = parent.find('[name="wbtm_post_id"]').val(); 105 $.ajax({ 106 type: 'POST', 107 url: mp_ajax_url, 108 data: { 109 "action": "get_wbtm_dropping_point", 110 "start_route": start_route, 111 "post_id": post_id, 112 }, 113 success: function (data) { 114 target.append(data).promise().done(function () { 115 wbtm_load_journey_date(parent, post_id, start_route); 116 }).promise().done(function () { 117 dLoaderRemove(parent); 118 target.find('input.formControl').trigger('click'); 119 }); 120 }, 121 error: function (response) { 122 dLoaderRemove(parent); 123 target.html('<div class="_warningButton_xs">The seat layout could not be loaded. Please refresh and try again.</div>'); 124 console.log(response); 125 } 126 }); 127 } else { 128 dLoaderRemove(parent); 129 mp_alert(target); 130 current.val('').trigger('click'); 131 } 132 }); 133 //alert(start_route); 134 }); 135 $(document).on("mp_change", "div.wbtm_search_area .wbtm_dropping_point input.formControl", function () { 136 let current = $(this); 137 let end_route = current.val(); 138 let parent = current.closest('.wbtm_search_area'); 139 let exit_route = 0; 140 parent.find('.wbtm_dropping_point .mp_input_select_list li').each(function () { 141 let current_route = $(this).data('value'); 142 if (current_route === end_route) { 143 exit_route = 1; 144 } 145 }).promise().done(function () { 146 if (exit_route > 0) { 147 parent.find('input[name="j_date"]').siblings('input').focus(); 148 } else { 149 current.val('').trigger('click'); 150 } 151 }); 152 //alert(start_route); 153 }); 154 function wbtm_load_journey_date(parent, post_id, start_route) { 155 let target = parent.find('.wbtm_journey_date'); 156 $.ajax({ 157 type: 'POST', 158 url: mp_ajax_url, 159 data: { 160 "action": "get_wbtm_journey_date", 161 "start_route": start_route, 162 "post_id": post_id, 163 "picker_context": parent.closest('.etc_tab_panel').data('tab') || '', 164 }, 165 success: function (data) { 166 target.html(data); 167 }, 168 error: function (response) { 169 console.log(response); 170 } 171 }); 172 }
173 $(document).on("change", "#wbtm_area input[name='j_date']", function () { 174 let date = $(this).val(); 175 let parent = $(this).closest('.wbtm_search_area'); 176 let target = parent.find('.wbtm_return_date'); 177 if (target.length > 0 && date) { 178 let end_route = parent.find('input[name="bus_end_route"]').first().val(); 179 let post_id = parent.find('[name="wbtm_post_id"]').first().val(); 180 //alert(date); 181 //alert(end_route); 182 $.ajax({ 183 type: 'POST', 184 url: mp_ajax_url, 185 data: { 186 "action": "get_wbtm_return_date", 187 "end_route": end_route, 188 "j_date": date, 189 "post_id": post_id, 190 "picker_context": parent.closest('.etc_tab_panel').data('tab') || '', 191 }, 192 beforeSend: function () { 193 dLoader_xs(target); 194 }, 195 success: function (data) { 196 target.html(data); 197 dLoaderRemove(target); 198 199 /* Return-tab flow: immediately continue from the selected 200 departure date into the newly generated return picker. */ 201 if (parent.closest('#etc_panel_return').length) { 202 var returnInput = target.find('.wbtm_return_date_input').first(); 203 wbtm_open_date_picker(returnInput); 204 } 205 }, 206 error: function (response) { 207 console.log(response); 208 } 209 }); 210 } 211 }); 212 $(document).on("click", "#wbtm_area .wbtm_journey_date_input", function () { 213 let parent = $(this).closest('.wbtm_search_area'); 214 let start = parent.find('input[name="bus_start_route"]').first().val(); 215 if (!start) { 216 mp_alert($(this)); 217 } 218 }); 219}(jQuery)); 220//====================================================================// 221(function ($) { 222 "use strict"; 223 $(document).on("click", "#get_wbtm_bus_details", function () { 224 let parent = $(this).closest('.wbtm_bus_list_area'); 225 let post_id = $(this).attr('data-bus_id'); 226 let target = parent.find('tr[data-row_id=' + post_id + ']').find('td.wbtm_bus_details'); 227 if ($(this).hasClass('mActive')) { 228 target.find('>div').slideUp('fast'); 229 mp_all_content_change($(this)); 230 } else { 231 parent.find('#get_wbtm_bus_details.mActive').each(function () { 232 $(this).trigger('click'); 233 }); 234 let start = parent.find('input[name="wbtm_start_route"]').val(); 235 let end = parent.find('input[name="wbtm_end_route"]').val(); 236 let date = parent.find('input[name="wbtm_date"]').val(); 237 if (start && end && date && post_id) { 238 $.ajax({ 239 type: 'POST', 240 url: mp_ajax_url, 241 data: { 242 "action": "get_wbtm_bus_details", 243 "start_route": start, 244 "end_route": end, 245 "post_id": post_id, 246 "date": date, 247 }, 248 beforeSend: function () { 249 dLoader(parent); 250 }, 251 success: function (data) { 252 target.html(data); 253 dLoaderRemove(parent); 254 loadBgImage(); 255 }, 256 error: function (response) { 257 console.log(response); 258 } 259 }); 260 } 261 mp_all_content_change($(this)); 262 } 263 }); 264}(jQuery)); 265//====================================================================// 266(function ($) { 267 "use strict"; 268 function wbtm_price_calculation(parent) { 269 let total_qty = wbtm_seat_qty(parent); 270 wbtm_seat_calculation(parent, total_qty); 271 wbtm_attendee_management(parent, total_qty); 272 let target_summary = parent.find('.wbtm_total'); 273 let target_sub_total = parent.find('.wbtm_sub_total'); 274 let total = wbtm_ticket_price(parent); 275 target_sub_total.html(mp_price_format(total)); 276 if (total_qty > 0) { 277 parent.find('.wbtm_ex_service_area').slideDown('fast'); 278 parent.find('.wbtm_form_submit_area').slideDown('fast'); 279 total = total + wbtm_ex_service_price(parent); 280 target_summary.html(mp_price_format(total)); 281 } else { 282 parent.find('.wbtm_ex_service_area').slideUp('fast'); 283 parent.find('.wbtm_form_submit_area').slideUp('fast'); 284 target_summary.html(mp_price_format(total)); 285 } 286 } 287 function wbtm_ticket_price(parent) { 288 let total = 0; 289 if (parent.find('.wbtm_seat_plan_area').length > 0) { 290 parent.find('.seat_available.seat_selected').each(function () { 291 total = total + parseFloat($(this).attr('data-seat_price')); 292 }); 293 } else { 294 parent.find('[name="wbtm_seat_qty[]"]').each(function () { 295 let qty = parseInt($(this).val()); 296 let price = parseFloat($(this).attr('data-price')); 297 price = price && price >= 0 ? price : 0; 298 total = total + price * qty; 299 }); 300 } 301 return total; 302 } 303 function wbtm_seat_qty(parent) { 304 let total_qty = 0; 305 if (parent.find('.wbtm_seat_plan_area').length > 0) { 306 parent.find('.seat_available.seat_selected').each(function () { 307 total_qty++; 308 }); 309 } else { 310 parent.find('[name="wbtm_seat_qty[]"]').each(function () { 311 total_qty = total_qty + parseInt($(this).val()); 312 }); 313 } 314 return total_qty; 315 } 316 function wbtm_ex_service_price(parent) { 317 let total = 0 318 parent.find('[name="extra_service_qty[]"]').each(function () { 319 let ex_qty = parseInt($(this).val()); 320 let ex_price = $(this).attr('data-price'); 321 ex_price = ex_price && ex_price >= 0 ? ex_price : 0; 322 total = total + parseFloat(ex_price) * ex_qty; 323 }); 324 return total; 325 }
326 $(document).on('change', '.wbtm_registration_area [name="wbtm_seat_qty[]"]', function () { 327 let parent = $(this).closest('.wbtm_registration_area'); 328 wbtm_price_calculation(parent); 329 }); 330 $(document).on('change', '.wbtm_registration_area [name="extra_service_qty[]"]', function () { 331 let parent = $(this).closest('.wbtm_registration_area'); 332 wbtm_price_calculation(parent); 333 }); 334 $(document).on('click', '.wbtm_registration_area .seat_available', function () { 335 let current = $(this); 336 let parent = current.closest('.wbtm_registration_area'); 337 if (!current.hasClass('seat_selected')) { 338 wbtm_maybe_warn_non_optimal_seat(parent, current); 339 } else { 340 wbtm_clear_recommendation_notice(parent); 341 } 342 if (current.hasClass('seat_selected')) { 343 let target = current.closest('.mp_seat_item').find('.wbtm_seat_item_list li:first-child'); 344 if (target.length > 0) { 345 let seat_label = target.attr('data-seat_label'); 346 let seat_price = target.attr('data-seat_price'); 347 let seat_type = target.attr('data-seat_type'); 348 current.attr('data-seat_label', seat_label).attr('data-seat_price', seat_price).attr('data-seat_type', seat_type); 349 } 350 } 351 current.toggleClass('seat_selected').promise().done(function () { 352 wbtm_price_calculation(parent); 353 }); 354 }); 355 $(document).on('click', '.wbtm_registration_area .wbtm_seat_item_list li', function () { 356 let current = $(this); 357 let target = current.closest('.mp_seat_item').find('.seat_available'); 358 let seat_label = current.attr('data-seat_label'); 359 let seat_price = current.attr('data-seat_price'); 360 let seat_type = current.attr('data-seat_type'); 361 let parent = current.closest('.wbtm_registration_area'); 362 target.attr('data-seat_label', seat_label).attr('data-seat_price', seat_price).attr('data-seat_type', seat_type).promise().done(function () { 363 if (target.hasClass('seat_selected')) { 364 wbtm_price_calculation(parent); 365 } else { 366 target.trigger('click'); 367 } 368 }); 369 }); 370 $(document).on('click', '.wbtm_registration_area .wbtm_selected_seat_details .mp_item_remove', function () { 371 let current = $(this); 372 let current_tr = current.closest('tr'); 373 let seat_name = current_tr.attr('data-seat_name'); 374 let seat_type = current_tr.attr('data-seat_type'); 375 let parent = current.closest('.wbtm_registration_area'); 376 parent.find('.seat_available.seat_selected').each(function () { 377 if ($(this).attr('data-seat_name') === seat_name && $(this).attr('data-seat_type') === seat_type) { 378 $(this).trigger('click'); 379 return false; 380 } 381 }); 382 }); 383 function wbtm_seat_calculation(parent, total_qty) { 384 if (parent.find('.wbtm_seat_plan_area').length > 0) { 385 let upper_area = parent.find('.wbtm_seat_plan_lower'); 386 if (upper_area.length > 0) { 387 let upper_target = parent.find('[name="wbtm_selected_seat"]'); 388 let upper_target_type = parent.find('[name="wbtm_selected_seat_type"]'); 389 let seats = ''; 390 let seats_type = ''; 391 upper_area.find('.seat_available.seat_selected').each(function () { 392 seats = seats ? seats + ',' + $(this).attr('data-seat_name') : $(this).attr('data-seat_name'); 393 seats_type = seats_type ? seats_type + ',' + $(this).attr('data-seat_type') : $(this).attr('data-seat_type'); 394 }).promise().done(function () { 395 upper_target.val(seats); 396 upper_target_type.val(seats_type); 397 }); 398 } 399 let lower_area = parent.find('.wbtm_seat_plan_upper'); 400 if (lower_area.length > 0) { 401 let lower_target = parent.find('[name="wbtm_selected_seat_dd"]'); 402 let lower_target_type = parent.find('[name="wbtm_selected_seat_dd_type"]'); 403 let seats_dd = ''; 404 let seats_dd_type = ''; 405 lower_area.find('.seat_available.seat_selected').each(function () { 406 seats_dd = seats_dd ? seats_dd + ',' + $(this).attr('data-seat_name') : $(this).attr('data-seat_name'); 407 seats_dd_type = seats_dd_type ? seats_dd_type + ',' + $(this).attr('data-seat_type') : $(this).attr('data-seat_type'); 408 }).promise().done(function () { 409 lower_target.val(seats_dd); 410 lower_target_type.val(seats_dd_type); 411 }); 412 } 413 wbtm_selected_seat_details(parent, total_qty) 414 } 415 } 416 function wbtm_selected_seat_details(parent, total_qty) { 417 if (parent.find('.wbtm_seat_plan_area').length > 0) { 418 let target = parent.find('.wbtm_selected_seat_details .wbtm_item_insert'); 419 if (total_qty > 0) { 420 let item_length = target.find('.wbtm_remove_area').length; 421 if (item_length !== total_qty) { 422 let hidden_target_tr = parent.find('.wbtm_item_hidden .wbtm_remove_area'); 423 parent.find('.seat_available.seat_selected').each(function () { 424 let seat_name = $(this).attr('data-seat_name'); 425 if (target.find('[data-seat_name="' + seat_name + '"]').length === 0) { 426 let seat_label = $(this).attr('data-seat_label'); 427 let seat_price = $(this).attr('data-seat_price'); 428 let seat_type = $(this).attr('data-seat_type'); 429 hidden_target_tr.attr('data-seat_type', seat_type).attr('data-seat_name', seat_name).promise().done(function () { 430 hidden_target_tr.find('.insert_seat_label').html(seat_label); 431 hidden_target_tr.find('.insert_seat_name').html(seat_name); 432 hidden_target_tr.find('.insert_seat_price').html(mp_price_format(seat_price)); 433 }).promise().done(function () { 434 target.append(hidden_target_tr.clone()); 435 }); 436 } 437 }).promise().done(function () { 438 item_length = target.find('.wbtm_remove_area').length; 439 if (item_length !== total_qty) { 440 target.find('.wbtm_remove_area').each(function () { 441 let seat_name = $(this).attr('data-seat_name'); 442 if (parent.find('.seat_available.seat_selected[data-seat_name="' + seat_name + '"]').length === 0) { 443 $(this).remove(); 444 } 445 }); 446 } 447 }); 448 } 449 } else { 450 target.html(''); 451 } 452 } 453 } 454 455 function wbtm_get_booking_mode(parent) { 456 var mode = parent.find('#wbtm_booking_mode').val() || 'normal'; 457 return mode === 'seat_blocking' ? 'seat_blocking' : 'normal'; 458 } 459 460 function wbtm_clear_duplicate_passenger_state(parent) { 461 parent.find('.wbtm-duplicate-passenger').removeClass('wbtm-duplicate-passenger'); 462 var notice = parent.find('.wbtm-passenger-duplicate-notice'); 463 if (notice.length) { 464 notice.hide().text(''); 465 } 466 } 467 468 469 470 function wbtm_is_internal_recommendation_user(parent) { 471 return parent.find('.wbtm-seat-recommendation-notice').length > 0; 472 } 473 function wbtm_clear_recommendation_notice(parent) { 474 var notice = parent.find('.wbtm-seat-recommendation-notice'); 475 if (notice.length) { 476 notice.stop(true, true).hide().text(''); 477 } 478 } 479 480 function wbtm_show_recommendation_notice(parent, message) { 481 var notice = parent.find('.wbtm-seat-recommendation-notice'); 482 if (notice.length) { 483 notice.text(message).stop(true, true).fadeIn(150); 484 } 485 } 486 487 function wbtm_get_best_available_recommendation(parent) { 488 var maxScore = 0; 489 parent.find('.seat_available').not('.seat_selected').each(function(){ 490 var score = parseInt($(this).attr('data-recommendation-score'), 10); 491 if (!isNaN(score) && score > maxScore) { 492 maxScore = score; 493 } 494 }); 495 return maxScore; 496 } 497 498 function wbtm_maybe_warn_non_optimal_seat(parent, current) { 499 if (!wbtm_is_internal_recommendation_user(parent)) { 500 return; 501 } 502 var currentScore = parseInt(current.attr('data-recommendation-score'), 10); 503 if (isNaN(currentScore)) { 504 currentScore = 0; 505 } 506 var bestAvailable = wbtm_get_best_available_recommendation(parent); 507 if (bestAvailable > currentScore) { 508 var label = bestAvailable >= 3 ? 'â â â ' : (bestAvailable === 2 ? 'â â ' : 'â '); 509 wbtm_show_recommendation_notice(parent, 'Better fit recommended seats are available for this trip (' + label + '). Using them helps preserve fully vacant seats for longer journeys.'); 510 } else { 511 wbtm_clear_recommendation_notice(parent); 512 } 513 } 514 515 function wbtm_validate_duplicate_passengers(parent) { 516 if (wbtm_get_booking_mode(parent) === 'seat_blocking') { 517 wbtm_clear_duplicate_passenger_state(parent); 518 return true; 519 } 520 var rows = []; 521 var duplicates = []; 522 parent.find('.wbtm_attendee_area .wbtm_attendee_item').each(function(){ 523 var item = $(this); 524 var first = $.trim(item.find('input[name="wbtm_first_name[]"]').val() || ''); 525 var last = $.trim(item.find('input[name="wbtm_last_name[]"]').val() || ''); 526 var phone = $.trim(item.find('input[name="wbtm_reg_phone[]"]').val() || ''); 527 var key = first.toLowerCase() + '|' + last.toLowerCase() + '|' + phone.replace(/\D+/g, ''); 528 rows.push({item:item, first:first, last:last, phone:phone, key:key}); 529 }); 530 wbtm_clear_duplicate_passenger_state(parent); 531 for (var i = 0; i < rows.length; i++) { 532 if (!rows[i].first || !rows[i].last || !rows[i].phone) { continue; } 533 for (var j = i + 1; j < rows.length; j++) { 534 if (rows[i].key && rows[i].key === rows[j].key) { 535 duplicates.push(rows[i].item, rows[j].item); 536 } 537 } 538 } 539 if (duplicates.length) {
540 $.each(duplicates, function(_, item){ 541 item.find('input[name="wbtm_first_name[]"], input[name="wbtm_last_name[]"], input[name="wbtm_reg_phone[]"]').addClass('wbtm-duplicate-passenger'); 542 }); 543 var notice = parent.find('.wbtm-passenger-duplicate-notice'); 544 if (notice.length) { 545 notice.text('Customer records cannot be identical.').show(); 546 } 547 return false; 548 } 549 return true; 550 } 551 552 function wbtm_attendee_management(parent, total_qty) { 553 let form_target = parent.find('.wbtm_attendee_area'); 554 if (wbtm_get_booking_mode(parent) === 'seat_blocking') { 555 form_target.html('').hide(); 556 wbtm_clear_duplicate_passenger_state(parent); 557 wbtm_clear_recommendation_notice(parent); 558 return; 559 } 560 if (form_target.length > 0 && total_qty > 0) { 561 form_target.slideDown(250); 562 let form_length = form_target.find('.wbtm_attendee_item').length; 563 if (form_length !== total_qty) { 564 let hidden_target = parent.find('.wbtm_hidden_form'); 565 if (parent.find('.wbtm_seat_plan_area').length > 0) { 566 parent.find('.seat_available.seat_selected').each(function () { 567 let seat_name = $(this).attr('data-seat_name'); 568 if (form_target.find('[data-seat_name="' + seat_name + '"]').length === 0) { 569 hidden_target.find('.wbtm_attendee_item').attr('data-seat_name', seat_name); 570 hidden_target.find('.wbtm_seat_name').html(seat_name).promise().done(function () { 571 form_target.append(hidden_target.html()); 572 }).promise().done(function () { 573 mp_load_date_picker(parent); 574 }); 575 } 576 }).promise().done(function () { 577 form_length = form_target.find('.wbtm_attendee_item').length; 578 if (form_length !== total_qty) { 579 form_target.find('.wbtm_attendee_item').each(function () { 580 let seat_name = $(this).attr('data-seat_name'); 581 if (parent.find('.seat_available.seat_selected[data-seat_name="' + seat_name + '"]').length === 0) { 582 $(this).remove(); 583 } 584 }); 585 } 586 }); 587 } else { 588 if (form_length > total_qty) { 589 for (let i = form_length; i > total_qty; i--) { 590 form_target.find('.wbtm_attendee_item:last-child').slideUp(250).remove(); 591 } 592 } else { 593 for (let i = form_length; i < total_qty; i++) { 594 hidden_target.find('.wbtm_seat_name').html(i + 1).promise().done(function () { 595 form_target.append(hidden_target.html()); 596 }).promise().done(function () { 597 mp_load_date_picker(parent); 598 }); 599 } 600 } 601 } 602 } 603 } else { 604 form_target.html('').slideUp(250); 605 } 606 } 607 608 $(document).on('change', '#wbtm_booking_mode', function(){ 609 let parent = $(this).closest('.wbtm_registration_area, .wbtm_single_result, .wbtm_bus_details, form, body'); 610 let selectedSeats = parent.find('.seat_available.seat_selected').length; 611 if (selectedSeats > 0 || parent.find('.wbtm_seat_plan_area').length > 0) { 612 wbtm_price_calculation(parent); 613 } else { 614 let total_qty = parseInt(parent.find('.wbtm_total_seat').text(), 10); 615 if (isNaN(total_qty)) { 616 total_qty = 0; 617 } 618 wbtm_attendee_management(parent, total_qty || 0); 619 } 620 }); 621 622 $(document).on('input change', 'input[name="wbtm_first_name[]"], input[name="wbtm_last_name[]"], input[name="wbtm_reg_phone[]"]', function(){ 623 let parent = $(this).closest('.wbtm_registration_area, .wbtm_single_result, .wbtm_bus_details, form, body'); 624 wbtm_validate_duplicate_passengers(parent); 625 }); 626 627 function wbtm_has_missing_attendee_forms(parent) { 628 if (wbtm_get_booking_mode(parent) === 'seat_blocking') { 629 return false; 630 } 631 let selectedSeats = parent.find('.seat_available.seat_selected').length; 632 if (selectedSeats < 1) { 633 return false; 634 } 635 return parent.find('.wbtm_attendee_area .wbtm_attendee_item').length < selectedSeats; 636 } 637 638 function wbtm_show_missing_attendee_notice(parent) { 639 let notice = parent.find('.wbtm-passenger-duplicate-notice'); 640 if (notice.length) { 641 notice.text('Please complete passenger details for each selected seat.').show(); 642 } 643 } 644 645 $(document).on('click', '.wbtm_form_submit_area button[name="add-to-cart"]', function(e){ 646 let parent = $(this).closest('.wbtm_registration_area, .wbtm_single_result, .wbtm_bus_details, form'); 647 if (parent.length && wbtm_has_missing_attendee_forms(parent)) { 648 wbtm_show_missing_attendee_notice(parent); 649 e.preventDefault(); 650 return false;
651 } 652 if (parent.length && !wbtm_validate_duplicate_passengers(parent)) { 653 e.preventDefault(); 654 return false; 655 } 656 }); 657 658 $(document).on('submit', 'form.cart, form', function(e){ 659 let form = $(this); 660 if (form.find('.wbtm_form_submit_area').length && wbtm_has_missing_attendee_forms(form)) { 661 wbtm_show_missing_attendee_notice(form); 662 e.preventDefault(); 663 return false; 664 } 665 if (form.find('.wbtm_form_submit_area').length && !wbtm_validate_duplicate_passengers(form)) { 666 e.preventDefault(); 667 return false; 668 } 669 }); 670}(jQuery)); 671//============================================================================Extracity round-trip coordinator================// 672(function ($) { 673 "use strict"; 674 675 function etcMoneyToNumber(text) { 676 var raw = (text || '').toString().replace(/[^0-9.\-]+/g, ''); 677 var num = parseFloat(raw); 678 return isNaN(num) ? 0 : num; 679 } 680 function etcFormatMoney(num) { 681 num = parseFloat(num); 682 if (isNaN(num)) { num = 0; } 683 return '$' + num.toFixed(2); 684 } 685 function etcEscape(text) { 686 return $('<div/>').text(text || '').html(); 687 } 688 function etcGetArea(el) { 689 return $(el).closest('#wbtm_area'); 690 } 691 function etcGetSearchScope(area) { 692 var scope = area.find('.etc_tab_panel.etc_panel_active .wbtm_search_area').first(); 693 if (!scope.length) { scope = area.find('.wbtm_search_area:visible').first(); } 694 if (!scope.length) { scope = area.find('.wbtm_search_area').first(); } 695 return scope; 696 } 697 function etcGetSearchValues(area) { 698 var scope = etcGetSearchScope(area); 699 return { 700 post_id: scope.find('[name="wbtm_post_id"]').first().val() || '', 701 start_route: scope.find('input[name="bus_start_route"]').first().val() || '', 702 end_route: scope.find('input[name="bus_end_route"]').first().val() || '', 703 j_date: scope.find('input[name="j_date"]').first().val() || '', 704 r_date: scope.find('input[name="r_date"]').first().val() || '' 705 }; 706 } 707 function etcEnsureHidden(form, name, value) { 708 var input = form.find('input[name="' + name + '"]'); 709 if (!input.length) { input = $('<input type="hidden" />').attr('name', name).appendTo(form); } 710 input.val(value); 711 } 712 function etcSerializeFormWithButton(form, button) { 713 var data = form.serialize(); 714 var btn = $(button); 715 if (btn.length && btn.attr('name') && btn.val()) { 716 data += (data ? '&' : '') + encodeURIComponent(btn.attr('name')) + '=' + encodeURIComponent(btn.val()); 717 } 718 var product = form.find('input[name="etc_wc_product_id"]').val() || btn.val() || ''; 719 if (product && data.indexOf('etc_wc_product_id=') === -1) { 720 data += (data ? '&' : '') + 'etc_wc_product_id=' + encodeURIComponent(product); 721 } 722 return data; 723 } 724 function etcLegSummaryFromForm(form) { 725 var seats = []; 726 var upper = form.find('input[name="wbtm_selected_seat"]').val() || ''; 727 var deck = form.find('input[name="wbtm_selected_seat_dd"]').val() || ''; 728 if (upper) { seats.push(upper); } 729 if (deck) { seats.push(deck); } 730 if (!seats.length) { 731 form.find('[name="wbtm_seat_qty[]"]').each(function(index){ 732 var qty = parseInt($(this).val(), 10); 733 if (qty > 0) { seats.push('Qty ' + qty); } 734 }); 735 } 736 return { 737 bp: form.find('input[name="wbtm_bp_place"]').val() || '', 738 dp: form.find('input[name="wbtm_dp_place"]').val() || '', 739 seats: seats.join(', '), 740 total: etcMoneyToNumber(form.find('.wbtm_total').text()) 741 }; 742 } 743 function etcDecodeSerializedForm(serialized) { 744 var data = {}; 745 (serialized || '').split('&').forEach(function(pair){ 746 if (!pair) { return; } 747 var parts = pair.split('='); 748 var key = decodeURIComponent((parts.shift() || '').replace(/\+/g, ' ')); 749 var value = decodeURIComponent((parts.join('=') || '').replace(/\+/g, ' ')); 750 if (!key) { return; } 751 if (!data[key]) { data[key] = []; } 752 data[key].push(value); 753 }); 754 return data; 755 } 756 function etcPassengerLabel(passenger, index) { 757 var first = passenger.wbtm_first_name || ''; 758 var last = passenger.wbtm_last_name || ''; 759 var phone = passenger.wbtm_reg_phone || ''; 760 var name = $.trim(first + ' ' + last);
761 if (!name && phone) { name = phone; } 762 if (!name) { name = 'Passenger ' + (index + 1); } 763 if (phone && name.indexOf(phone) === -1) { name += ' â ' + phone; } 764 return name; 765 } 766 function etcPassengersFromSerialized(serialized) { 767 var data = etcDecodeSerializedForm(serialized); 768 var fields = ['wbtm_first_name','wbtm_last_name','wbtm_reg_phone','wbtm_reg_email','wbtm_reg_address','wbtm_user_gender']; 769 var max = 0; 770 fields.forEach(function(field){ 771 var values = data[field + '[]'] || data[field] || []; 772 if (values.length > max) { max = values.length; } 773 }); 774 var passengers = []; 775 for (var i = 0; i < max; i++) { 776 var passenger = {}; 777 var hasValue = false; 778 fields.forEach(function(field){ 779 var values = data[field + '[]'] || data[field] || []; 780 var value = values[i] || ''; 781 passenger[field] = value; 782 if ($.trim(value)) { hasValue = true; } 783 }); 784 if (hasValue) { 785 passenger.label = etcPassengerLabel(passenger, passengers.length); 786 passengers.push(passenger); 787 } 788 } 789 return passengers; 790 } 791 function etcFillPassengerItem(item, passenger, clearWhenEmpty) { 792 var fields = ['wbtm_first_name','wbtm_last_name','wbtm_reg_phone','wbtm_reg_email','wbtm_reg_address','wbtm_user_gender']; 793 fields.forEach(function(field){ 794 var target = item.find('[name="' + field + '[]"], [name="' + field + '"]').first(); 795 if (!target.length) { return; } 796 if (!passenger && !clearWhenEmpty) { return; } 797 target.val(passenger ? (passenger[field] || '') : '').trigger('input').trigger('change'); 798 }); 799 } 800 function etcPassengerItemHasUserText(item) { 801 var hasText = false; 802 item.find('input[name^="wbtm_"], textarea[name^="wbtm_"], select[name^="wbtm_"]').each(function(){ 803 if ($.trim($(this).val() || '')) { hasText = true; return false; } 804 }); 805 return hasText; 806 } 807 function etcBuildPassengerReuseControl(item, passengers, autoIndex, sameCount) { 808 var control = item.find('.etc_return_passenger_reuse'); 809 if (!control.length) { 810 control = $('<div class="etc_return_passenger_reuse"><label><span>Return passenger</span><select class="etc_return_passenger_select"></select></label><small></small></div>'); 811 item.find('.mpPanelHeader').after(control); 812 } 813 var select = control.find('select'); 814 var previous = select.val(); 815 select.empty(); 816 select.append('<option value="">Add / edit different passenger</option>'); 817 $.each(passengers, function(index, passenger){ 818 select.append($('<option/>').attr('value', String(index)).text(passenger.label || ('Passenger ' + (index + 1)))); 819 }); 820 if (sameCount && autoIndex >= 0 && autoIndex < passengers.length && !item.attr('data-etc-return-passenger-touched')) { 821 select.val(String(autoIndex)); 822 control.find('small').text('Passenger details copied from the outbound trip. You can still edit them.'); 823 } else if (previous && passengers[parseInt(previous, 10)]) { 824 select.val(previous); 825 control.find('small').text('Using details from the outbound trip. You can still edit them.'); 826 } else { 827 select.val(''); 828 control.find('small').text('Choose an outbound passenger or enter different details.'); 829 } 830 } 831 function etcApplyReturnPassengerReuse(area, form) { 832 var state = area.data('etcRoundTripState') || null; 833 if (!state || !state.outboundPassengers || !state.outboundPassengers.length || !area.hasClass('etc_round_trip_return_stage')) { return; } 834 var items = form.find('.wbtm_attendee_area .wbtm_attendee_item'); 835 if (!items.length) { return; } 836 var sameCount = items.length === state.outboundPassengers.length; 837 items.each(function(index){ 838 var item = $(this); 839 var wasBlank = !etcPassengerItemHasUserText(item); 840 etcBuildPassengerReuseControl(item, state.outboundPassengers, index, sameCount); 841 if (sameCount && !item.attr('data-etc-return-passenger-filled') && wasBlank) { 842 etcFillPassengerItem(item, state.outboundPassengers[index], false); 843 item.attr('data-etc-return-passenger-filled', '1'); 844 } 845 }); 846 } 847 function etcScheduleReturnPassengerReuse(el) { 848 var area = etcGetArea(el); 849 if (!area.hasClass('etc_round_trip_return_stage')) { return; } 850 window.setTimeout(function(){ 851 area.find('.wbtm_registration_area form').each(function(){ 852 etcApplyReturnPassengerReuse(area, $(this)); 853 }); 854 }, 320); 855 } 856 function etcRenderPanel(area) { 857 var state = area.data('etcRoundTripState') || null; 858 var panel = area.find('.etc_round_trip_flow_panel'); 859 if (!state) { panel.remove(); return; } 860 if (!panel.length) { 861 panel = $('<div class="etc_round_trip_flow_panel _dLayout_dShadow_1_mT" role="status"></div>'); 862 etcGetSearchScope(area).after(panel); 863 } 864 var outbound = state.outboundSummary || {}; 865 var ret = state.returnSummary || {}; 866 var total = (parseFloat(outbound.total) || 0) + (parseFloat(ret.total) || 0); 867 var returnHtml = ret.bp ? 868 '<div class="etc_round_trip_leg"><span class="etc_leg_badge">Return</span><strong>' + etcEscape(ret.bp) + ' â ' + etcEscape(ret.dp) + '</strong><span>Seats: ' + etcEscape(ret.seats || 'Selected') + '</span><span>' + etcFormatMoney(ret.total || 0) + '</span></div>' : 869 '<div class="etc_round_trip_leg etc_pending"><span class="etc_leg_badge">Return</span><strong>Select return bus and seats next</strong><span>Return date: ' + etcEscape(state.search ? state.search.r_date : '') + '</span></div>'; 870 panel.html( 871 '<div class="etc_round_trip_panel_head"><div><span class="etc_round_trip_kicker">Round trip booking</span><h4>Build both trips before checkout</h4></div><button type="button" class="etc_round_trip_edit_outbound">Edit outbound</button></div>' + 872 '<div class="etc_round_trip_legs">' + 873 '<div class="etc_round_trip_leg"><span class="etc_leg_badge">Outbound</span><strong>' + etcEscape(outbound.bp || '') + ' â ' + etcEscape(outbound.dp || '') + '</strong><span>Seats: ' + etcEscape(outbound.seats || 'Selected') + '</span><span>
873' + etcFormatMoney(outbound.total || 0) + '</span></div>' + 874 returnHtml + '</div>' + 875 '<div class="etc_round_trip_total"><span>Combined total</span><strong>' + etcFormatMoney(total) + '</strong></div>' 876 ); 877 } 878 function etcResetRoundTrip(area) { 879 area.removeClass('etc_round_trip_return_stage etc_round_trip_active'); 880 area.removeData('etcRoundTripState'); 881 area.find('.etc_round_trip_flow_panel').remove(); 882 } 883 function etcUpdateSubmitText(form) { 884 var area = etcGetArea(form); 885 var button = form.find('.etc_round_trip_submit'); 886 if (!button.length) { return; } 887 var search = etcGetSearchValues(area); 888 var text = button.attr('data-single-text') || button.text(); 889 if (area.hasClass('etc_round_trip_return_stage')) { 890 text = button.attr('data-final-text') || 'Proceed to Pay'; 891 } else if (search.r_date) { 892 text = button.attr('data-return-text') || 'Continue to Return Trip'; 893 } 894 button.text(text); 895 } 896 function etcLoadReturnResults(area) { 897 var state = area.data('etcRoundTripState'); 898 if (!state || !state.search) { return; } 899 var search = state.search; 900 $.ajax({ 901 type: 'POST', url: mp_ajax_url, 902 data: { action:'get_wbtm_bus_list', start_route:search.end_route, end_route:search.start_route, j_date:search.r_date, r_date:'', post_id:search.post_id }, 903 beforeSend:function(){ dLoader(area); }, 904 success:function(data){ 905 area.addClass('etc_round_trip_active etc_round_trip_return_stage'); 906 area.find('.wbtm_search_result').html('<div class="etc_round_trip_return_heading"><span>Step 2</span><strong>Select your return trip</strong><em>' + etcEscape(search.end_route) + ' â ' + etcEscape(search.start_route) + '</em></div>' + data).promise().done(function(){ 907 dLoaderRemove(area); loadBgImage(); etcRenderPanel(area); 908 }); 909 }, 910 error:function(){ dLoaderRemove(area); alert('Could not load return trip results. Please try again.'); } 911 }); 912 } 913 914 $(document).on('click', '#wbtm_area button.get_wbtm_bus_list', function () { etcResetRoundTrip(etcGetArea(this)); }); 915 $(document).on('click change input', '.wbtm_registration_area', function () { etcUpdateSubmitText($(this).find('form').first()); }); 916 $(document).on('click change input', '.etc_round_trip_return_stage .wbtm_registration_area .seat_available, .etc_round_trip_return_stage .wbtm_registration_area [name="wbtm_seat_qty[]"], .etc_round_trip_return_stage .wbtm_registration_area .wbtm_seat_item_list li', function(){ 917 etcScheduleReturnPassengerReuse(this); 918 }); 919 $(document).on('change', '.etc_round_trip_return_stage .etc_return_passenger_select', function(){ 920 var select = $(this); 921 var item = select.closest('.wbtm_attendee_item'); 922 var area = etcGetArea(select); 923 var state = area.data('etcRoundTripState') || null; 924 var index = parseInt(select.val(), 10); 925 item.attr('data-etc-return-passenger-touched', '1'); 926 if (state && state.outboundPassengers && state.outboundPassengers[index]) { 927 etcFillPassengerItem(item, state.outboundPassengers[index], false); 928 item.attr('data-etc-return-passenger-filled', '1'); 929 select.closest('.etc_return_passenger_reuse').find('small').text('Using details from the outbound trip. You can still edit them.'); 930 } else { 931 etcFillPassengerItem(item, null, true); 932 item.removeAttr('data-etc-return-passenger-filled'); 933 select.closest('.etc_return_passenger_reuse').find('small').text('Enter different details for this return passenger.'); 934 } 935 }); 936 $(document).on('input change', '.etc_round_trip_return_stage .wbtm_attendee_item input, .etc_round_trip_return_stage .wbtm_attendee_item textarea, .etc_round_trip_return_stage .wbtm_attendee_item select', function(){ 937 if (!$(this).hasClass('etc_return_passenger_select')) { 938 $(this).closest('.wbtm_attendee_item').attr('data-etc-return-passenger-touched', '1'); 939 } 940 }); 941 $(document).on('click', '.etc_round_trip_edit_outbound', function () { 942 var area = etcGetArea(this), state = area.data('etcRoundTripState') || null; 943 if (!state || !state.search) { return; } 944 var search = state.search; etcResetRoundTrip(area); 945 $.ajax({ type:'POST', url:mp_ajax_url, data:{ action:'get_wbtm_bus_list', start_route:search.start_route, end_route:search.end_route, j_date:search.j_date, r_date:search.r_date, post_id:search.post_id }, beforeSend:function(){ dLoader(area); }, success:function(data){ area.find('.wbtm_search_result').html(data).promise().done(function(){ dLoaderRemove(area); loadBgImage(); }); }, error:function(){ dLoaderRemove(area); } }); 946 }); 947 $(document).on('click', '.wbtm_form_submit_area button[name="add-to-cart"]', function (e) { 948 if (e.isDefaultPrevented && e.isDefaultPrevented()) { return; } 949 var button = $(this), form = button.closest('form'); 950 if (!form.length) { return; } 951 var area = etcGetArea(form), search = etcGetSearchValues(area); 952 if (!search.r_date) { return; } 953 if (typeof form[0].checkValidity === 'function' && !form[0].checkValidity()) { return; } 954 if (!area.hasClass('etc_round_trip_return_stage')) { 955 e.preventDefault(); 956 var outboundSerialized = etcSerializeFormWithButton(form, button);
957 var state = { search:search, outboundSerialized:outboundSerialized, outboundSummary:etcLegSummaryFromForm(form), outboundPassengers:etcPassengersFromSerialized(outboundSerialized) }; 958 area.data('etcRoundTripState', state).addClass('etc_round_trip_active'); 959 etcRenderPanel(area); etcLoadReturnResults(area); return false; 960 } 961 var state = area.data('etcRoundTripState') || null; 962 if (!state || !state.outboundSerialized) { return; } 963 e.preventDefault(); 964 state.returnSummary = etcLegSummaryFromForm(form); area.data('etcRoundTripState', state); etcRenderPanel(area); 965 var groupId = 'rt_' + (new Date().getTime()) + '_' + Math.random().toString(36).slice(2, 10); 966 var combinedTotal = (parseFloat(state.outboundSummary.total) || 0) + (parseFloat(state.returnSummary.total) || 0); 967 button.prop('disabled', true).addClass('etc_processing').text('Preparing checkout...'); 968 $.ajax({ type:'POST', url:mp_ajax_url, dataType:'json', data:{ action:'etc_add_round_trip_leg', form_data:state.outboundSerialized, group_id:groupId, leg:'outbound', paired_leg_reference:'return', round_trip_total:combinedTotal.toFixed(2) }, success:function(response){ 969 if (!response || !response.success) { button.prop('disabled', false).removeClass('etc_processing'); etcUpdateSubmitText(form); alert((response && response.data && response.data.message) ? response.data.message : 'Could not add outbound trip. Please try again.'); return; } 970 etcEnsureHidden(form, 'etc_round_trip_group_id', groupId); etcEnsureHidden(form, 'etc_trip_leg', 'return'); etcEnsureHidden(form, 'etc_paired_leg_reference', 'outbound'); etcEnsureHidden(form, 'etc_round_trip_requested', '1'); etcEnsureHidden(form, 'etc_round_trip_total', combinedTotal.toFixed(2)); etcEnsureHidden(form, 'add-to-cart', button.val() || form.find('input[name="etc_wc_product_id"]').val() || ''); 971 if (form[0] && typeof form[0].submit === 'function') { form[0].submit(); } 972 }, error:function(){ button.prop('disabled', false).removeClass('etc_processing'); etcUpdateSubmitText(form); alert('Could not prepare the round trip checkout. Please try again.'); } }); 973 return false; 974 }); 975}(jQuery)); 976 977/* Extracity v9.0 â Tab switching: One-Way / Return / Ticket Lookup */ 978(function ($) { 979 'use strict'; 980 981 /* ââ activate a tab by key ââ */ 982 function etcActivateTab(area, key) { 983 area.find('.etc_tab_item').each(function () { 984 var isActive = $(this).data('tab') === key; 985 $(this).toggleClass('etc_tab_active', isActive); 986 }); 987 area.find('.etc_tab_panel').each(function () { 988 var isActive = $(this).data('tab') === key; 989 $(this).toggleClass('etc_panel_active', isActive); 990 }); 991 /* persist across soft reloads */ 992 try { sessionStorage.setItem('etc_active_tab', key); } catch (e) {} 993 } 994 995 /* ââ tab click â lock scroll position so panel height change does not jump the page ââ */ 996 $(document).on('click', '#wbtm_area .etc_tab_item', function () { 997 var area = $(this).closest('#wbtm_area'); 998 var scrollY = window.pageYOffset || document.documentElement.scrollTop; 999 var areaTop = area.offset().top; 1000 1001 etcActivateTab(area, $(this).data('tab')); 1002 1003 /* If the area top is above the current scroll position the page may 1004 reflow and shift â restore the exact scroll position immediately. */ 1005 window.scrollTo({ top: scrollY, behavior: 'instant' }); 1006 1007 /* Belt-and-suspenders: re-apply after any deferred reflows */ 1008 requestAnimationFrame(function () { 1009 window.scrollTo({ top: scrollY, behavior: 'instant' }); 1010 }); 1011 }); 1012 1013 /* ââ restore last tab on page load ââ */ 1014 $(document).ready(function () { 1015 $('#wbtm_area').each(function () { 1016 var area = $(this); 1017 var saved = ''; 1018 try { saved = sessionStorage.getItem('etc_active_tab') || ''; } catch (e) {} 1019 var validTabs = ['oneway', 'return', 'lookup']; 1020 var initial = validTabs.indexOf(saved) !== -1 ? saved : 'oneway'; 1021 etcActivateTab(area, initial); 1022 }); 1023 }); 1024 1025}(jQuery)); 1026 1027/* Extracity v9.17 â Return date validation and picker continuation */ 1028(function ($) { 1029 'use strict'; 1030 1031 function openReturnPicker(input) { 1032 if (!input.length) { 1033 return; 1034 } 1035 input.trigger('focus'); 1036 if ($.fn.datepicker && input.hasClass('hasDatepicker')) { 1037 input.datepicker('show'); 1038 } 1039 } 1040 1041 function clearReturnDateError(panel) { 1042 var visible = panel.find('.wbtm_return_date .wbtm_return_date_input').first(); 1043 panel.find('.etc_return_date_error').removeClass('etc_visible'); 1044 visible.removeClass('etc_return_date_missing').attr('aria-invalid', 'false'); 1045 } 1046 1047 $(document).on('change input', '#etc_panel_return .wbtm_return_date input[name="r_date"], #etc_panel_return .wbtm_return_date_input', function () { 1048 clearReturnDateError($(this).closest('#etc_panel_return')); 1049 }); 1050 1051 $(document).on('click', '#etc_panel_return .get_wbtm_bus_list', function (e) { 1052 var panel = $(this).closest('#etc_panel_return'); 1053 var field = panel.find('.wbtm_return_date').first(); 1054 var rHidden = field.find('input[name="r_date"]').first(); 1055 var rVisible = field.find('.wbtm_return_date_input').first(); 1056 var errMsg = field.find('.etc_return_date_error').first(); 1057 1058 /* Backward-safe fallback in case cached markup does not yet contain 1059 the server-rendered validation element. */ 1060 if (!errMsg.length) { 1061 field.append( 1062 '<span class="etc_return_date_error" role="alert" aria-live="polite">Please select a return date.</span>' 1063 ); 1064 errMsg = field.find('.etc_return_date_error').first(); 1065 } 1066 1067 var val = rHidden.val() ? rHidden.val().trim() : ''; 1068 1069 if (!val) { 1070 e.stopImmediatePropagation(); 1071 rVisible.addClass('etc_return_date_missing').attr('aria-invalid', 'true'); 1072 errMsg.addClass('etc_visible'); 1073 openReturnPicker(rVisible); 1074 return false;
1075 } 1076 1077 clearReturnDateError(panel); 1078 }); 1079 1080}(jQuery));
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.