| 1 |
"use strict"; |
| 2 |
|
| 3 |
/* global jQuery, wpbc_booking_modes_config, wpbc_admin_show_message */ |
| 4 |
(function ($) { |
| 5 |
'use strict'; |
| 6 |
|
| 7 |
var switch_busy = false; |
| 8 |
var switch_message_storage_key = 'wpbc_booking_modes_v3_switch_success'; |
| 9 |
var switch_message_max_age = 120000; |
| 10 |
|
| 11 |
/** |
| 12 |
* Read a user-facing error from a WordPress AJAX response. |
| 13 |
* |
| 14 |
* @param {Object|undefined} response Parsed AJAX response. |
| 15 |
* @param {string|undefined} fallback Optional fallback message. |
| 16 |
* @return {string} Safe error text. |
| 17 |
*/ |
| 18 |
function get_error_message(response, fallback) { |
| 19 |
if (response && response.data && typeof response.data.message === 'string' && response.data.message.length) { |
| 20 |
return response.data.message; |
| 21 |
} |
| 22 |
return fallback || wpbc_booking_modes_config.i18n.error; |
| 23 |
} |
| 24 |
|
| 25 |
/** |
| 26 |
* Show a mode-switch error through the existing Booking Calendar notifier. |
| 27 |
* |
| 28 |
* @param {string} message Error message. |
| 29 |
* @param {number|undefined} delay Optional display duration in milliseconds. |
| 30 |
* @return {void} |
| 31 |
*/ |
| 32 |
function show_error(message, delay) { |
| 33 |
if (typeof window.wpbc_admin_show_message === 'function') { |
| 34 |
window.wpbc_admin_show_message(message, 'error', delay || 10000, false); |
| 35 |
return; |
| 36 |
} |
| 37 |
window.alert(message); |
| 38 |
} |
| 39 |
|
| 40 |
/** |
| 41 |
* Show a successful QuickStart message through the existing notifier. |
| 42 |
* |
| 43 |
* @param {string} message Success message. |
| 44 |
* @return {void} |
| 45 |
*/ |
| 46 |
function show_success(message) { |
| 47 |
if (typeof window.wpbc_admin_show_message === 'function') { |
| 48 |
window.wpbc_admin_show_message(message, 'success', 10000, false); |
| 49 |
return; |
| 50 |
} |
| 51 |
window.alert(message); |
| 52 |
} |
| 53 |
|
| 54 |
/** |
| 55 |
* Show non-blocking mode-switch progress through the admin notifier. |
| 56 |
* |
| 57 |
* The request must continue immediately, so this intentionally has no alert |
| 58 |
* fallback when the shared Booking Calendar notifier is unavailable. |
| 59 |
* |
| 60 |
* @param {string} message Progress message. |
| 61 |
* @return {void} |
| 62 |
*/ |
| 63 |
function show_info(message) { |
| 64 |
if (typeof window.wpbc_admin_show_message === 'function') { |
| 65 |
window.wpbc_admin_show_message(message, 'info', 10000, false); |
| 66 |
} |
| 67 |
} |
| 68 |
|
| 69 |
/** |
| 70 |
* Show the server-confirmed mode activation before redirecting. |
| 71 |
* |
| 72 |
* @param {string} message Success message. |
| 73 |
* @return {void} |
| 74 |
*/ |
| 75 |
function show_switch_success(message) { |
| 76 |
if (message && typeof window.wpbc_admin_show_message === 'function') { |
| 77 |
window.wpbc_admin_show_message(message, 'success', 1500, false); |
| 78 |
} |
| 79 |
} |
| 80 |
|
| 81 |
/** |
| 82 |
* Save the activated mode for a V1-compatible notice on the final page. |
| 83 |
* |
| 84 |
* V3 uses a signed full-administration landing before the final destination, |
| 85 |
* so an in-page notice shown before navigation would otherwise disappear. |
| 86 |
* Session storage keeps this presentation-only state out of WordPress data |
| 87 |
* and naturally isolates it to the tab that initiated the switch. |
| 88 |
* |
| 89 |
* @param {string} mode_id Activated mode identifier. |
| 90 |
* @return {void} |
| 91 |
*/ |
| 92 |
function store_switch_success(mode_id) { |
| 93 |
var normalized_mode_id = typeof mode_id === 'string' ? mode_id : ''; |
| 94 |
if (!normalized_mode_id) { |
| 95 |
return; |
| 96 |
} |
| 97 |
try { |
| 98 |
window.sessionStorage.setItem(switch_message_storage_key, JSON.stringify({ |
| 99 |
mode_id: normalized_mode_id, |
| 100 |
created_at: Date.now() |
| 101 |
})); |
| 102 |
} catch (error) { |
| 103 |
// A blocked or full browser store must never prevent mode switching. |
| 104 |
} |
| 105 |
} |
| 106 |
|
| 107 |
/** |
| 108 |
* Show and consume the pending switch message on the final WPBC page. |
| 109 |
* |
| 110 |
* The record is removed before validation or display so refreshes, malformed |
| 111 |
* values, account changes, and stale records cannot replay it. Matching the |
| 112 |
* localized selected mode prevents a notice from leaking into another mode. |
| 113 |
* |
| 114 |
* @return {void} |
| 115 |
*/ |
| 116 |
function show_pending_switch_success() { |
| 117 |
var serialized_message; |
| 118 |
var pending_message; |
| 119 |
var current_mode_id = String(wpbc_booking_modes_config.selected_mode_id || ''); |
| 120 |
var success_message = wpbc_booking_modes_config.i18n.switch_success || ''; |
| 121 |
try { |
| 122 |
serialized_message = window.sessionStorage.getItem(switch_message_storage_key); |
| 123 |
window.sessionStorage.removeItem(switch_message_storage_key); |
| 124 |
} catch (error) { |
| 125 |
return; |
| 126 |
} |
| 127 |
if (!serialized_message || !current_mode_id || typeof success_message !== 'string' || !success_message) { |
| 128 |
return; |
| 129 |
} |
| 130 |
try { |
| 131 |
pending_message = JSON.parse(serialized_message); |
| 132 |
} catch (error) { |
| 133 |
return; |
| 134 |
} |
| 135 |
if (!pending_message || pending_message.mode_id !== current_mode_id || typeof pending_message.created_at !== 'number' || pending_message.created_at > Date.now() || Date.now() - pending_message.created_at > switch_message_max_age) { |
| 136 |
return; |
| 137 |
} |
| 138 |
show_switch_success(success_message); |
| 139 |
} |
| 140 |
|
| 141 |
/** |
| 142 |
* Toggle the shared switching state and all dropdown choices. |
| 143 |
* |
| 144 |
* @param {jQuery} $selector Mode selector container. |
| 145 |
* @param {boolean} is_busy Whether a mode-switch request is active. |
| 146 |
* @return {void} |
| 147 |
*/ |
| 148 |
function set_switching_state($selector, is_busy) { |
| 149 |
switch_busy = is_busy; |
| 150 |
$selector.toggleClass('is-switching', is_busy); |
| 151 |
if (is_busy) { |
| 152 |
$selector.attr('aria-busy', 'true'); |
| 153 |
$selector.find('.wpbc_booking_mode_option').attr('aria-disabled', 'true'); |
| 154 |
return; |
| 155 |
} |
| 156 |
$selector.removeAttr('aria-busy'); |
| 157 |
$selector.find('.wpbc_booking_mode_option').removeAttr('aria-disabled'); |
| 158 |
} |
| 159 |
|
| 160 |
/** |
| 161 |
* Persist a selected mode and follow the server-approved redirect. |
| 162 |
* |
| 163 |
* @param {Event} event Click event for a selector option. |
| 164 |
* @return {void} |
| 165 |
*/ |
| 166 |
function switch_mode(event) { |
| 167 |
var $option = $(event.currentTarget); |
| 168 |
var $selector = $option.closest('.wpbc_booking_modes_selector'); |
| 169 |
var mode_id = String($option.data('mode-id') || ''); |
| 170 |
event.preventDefault(); |
| 171 |
if (switch_busy || !mode_id || $option.hasClass('is-current')) { |
| 172 |
return; |
| 173 |
} |
| 174 |
set_switching_state($selector, true); |
| 175 |
show_info(wpbc_booking_modes_config.i18n.saving || 'Switching Booking Calendar mode...'); |
| 176 |
$.ajax({ |
| 177 |
url: wpbc_booking_modes_config.ajax_url, |
| 178 |
method: 'POST', |
| 179 |
dataType: 'json', |
| 180 |
data: { |
| 181 |
action: wpbc_booking_modes_config.action, |
| 182 |
nonce: wpbc_booking_modes_config.nonce, |
| 183 |
mode_id: mode_id, |
| 184 |
origin_url: window.location.href.split('#')[0], |
| 185 |
fragment: window.location.hash ? window.location.hash.substring(1) : '' |
| 186 |
} |
| 187 |
}).done(function (response) { |
| 188 |
if (!response || response.success !== true || !response.data || typeof response.data.redirect_url !== 'string' || !response.data.redirect_url.length) { |
| 189 |
set_switching_state($selector, false); |
| 190 |
show_error(get_error_message(response), 7000); |
| 191 |
return; |
| 192 |
} |
| 193 |
show_switch_success(response.data.message || wpbc_booking_modes_config.i18n.switched); |
| 194 |
store_switch_success(mode_id); |
| 195 |
window.location.assign(response.data.redirect_url); |
| 196 |
}).fail(function (xhr) { |
| 197 |
set_switching_state($selector, false); |
| 198 |
show_error(get_error_message(xhr.responseJSON), 7000); |
| 199 |
}); |
| 200 |
} |
| 201 |
|
| 202 |
/** |
| 203 |
* Run a separately confirmed, state-changing QuickStart operation. |
| 204 |
* |
| 205 |
* @param {Event} event Click event for a QuickStart button. |
| 206 |
* @return {void} |
| 207 |
*/ |
| 208 |
function run_quickstart(event) { |
| 209 |
var $button = $(event.currentTarget); |
| 210 |
var $actions = $button.closest('.wpbc_booking_modes_quickstart_actions'); |
| 211 |
var mode_id = String($button.data('mode-id') || ''); |
| 212 |
var quickstart = wpbc_booking_modes_config.quickstart || {}; |
| 213 |
event.preventDefault(); |
| 214 |
if (!mode_id || !quickstart.action || !quickstart.nonce || $button.prop('disabled')) { |
| 215 |
return; |
| 216 |
} |
| 217 |
if (!window.confirm(wpbc_booking_modes_config.i18n.quickstart_confirm)) { |
| 218 |
return; |
| 219 |
} |
| 220 |
$button.prop('disabled', true).attr('aria-busy', 'true'); |
| 221 |
$.ajax({ |
| 222 |
url: wpbc_booking_modes_config.ajax_url, |
| 223 |
method: 'POST', |
| 224 |
dataType: 'json', |
| 225 |
data: { |
| 226 |
action: quickstart.action, |
| 227 |
nonce: quickstart.nonce, |
| 228 |
mode_id: mode_id |
| 229 |
} |
| 230 |
}).done(function (response) { |
| 231 |
var $test_page; |
| 232 |
if (!response || response.success !== true || !response.data || typeof response.data.test_url !== 'string' || !response.data.test_url.length) { |
| 233 |
show_error(get_error_message(response, wpbc_booking_modes_config.i18n.quickstart_error)); |
| 234 |
return; |
| 235 |
} |
| 236 |
$test_page = $actions.find('.wpbc_booking_modes_test_page'); |
| 237 |
$test_page.attr('href', response.data.test_url).removeClass('is-hidden').trigger('focus'); |
| 238 |
show_success(response.data.message || wpbc_booking_modes_config.i18n.test_page); |
| 239 |
}).fail(function (xhr) { |
| 240 |
show_error(get_error_message(xhr.responseJSON, wpbc_booking_modes_config.i18n.quickstart_error)); |
| 241 |
}).always(function () { |
| 242 |
$button.prop('disabled', false).removeAttr('aria-busy'); |
| 243 |
}); |
| 244 |
} |
| 245 |
$(document).on('click', '.wpbc_booking_mode_option', switch_mode); |
| 246 |
$(document).on('click', '.wpbc_booking_modes_quickstart_button', run_quickstart); |
| 247 |
$(show_pending_switch_success); |
| 248 |
})(jQuery); |
| 249 |
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5jbHVkZXMvYm9va2luZ19tb2Rlc192My9fb3V0L2Jvb2tpbmdfbW9kZXMuanMiLCJuYW1lcyI6WyIkIiwic3dpdGNoX2J1c3kiLCJzd2l0Y2hfbWVzc2FnZV9zdG9yYWdlX2tleSIsInN3aXRjaF9tZXNzYWdlX21heF9hZ2UiLCJnZXRfZXJyb3JfbWVzc2FnZSIsInJlc3BvbnNlIiwiZmFsbGJhY2siLCJkYXRhIiwibWVzc2FnZSIsImxlbmd0aCIsIndwYmNfYm9va2luZ19tb2Rlc19jb25maWciLCJpMThuIiwiZXJyb3IiLCJzaG93X2Vycm9yIiwiZGVsYXkiLCJ3aW5kb3ciLCJ3cGJjX2FkbWluX3Nob3dfbWVzc2FnZSIsImFsZXJ0Iiwic2hvd19zdWNjZXNzIiwic2hvd19pbmZvIiwic2hvd19zd2l0Y2hfc3VjY2VzcyIsInN0b3JlX3N3aXRjaF9zdWNjZXNzIiwibW9kZV9pZCIsIm5vcm1hbGl6ZWRfbW9kZV9pZCIsInNlc3Npb25TdG9yYWdlIiwic2V0SXRlbSIsIkpTT04iLCJzdHJpbmdpZnkiLCJjcmVhdGVkX2F0IiwiRGF0ZSIsIm5vdyIsInNob3dfcGVuZGluZ19zd2l0Y2hfc3VjY2VzcyIsInNlcmlhbGl6ZWRfbWVzc2FnZSIsInBlbmRpbmdfbWVzc2FnZSIsImN1cnJlbnRfbW9kZV9pZCIsIlN0cmluZyIsInNlbGVjdGVkX21vZGVfaWQiLCJzdWNjZXNzX21lc3NhZ2UiLCJzd2l0Y2hfc3VjY2VzcyIsImdldEl0ZW0iLCJyZW1vdmVJdGVtIiwicGFyc2UiLCJzZXRfc3dpdGNoaW5nX3N0YXRlIiwiJHNlbGVjdG9yIiwiaXNfYnVzeSIsInRvZ2dsZUNsYXNzIiwiYXR0ciIsImZpbmQiLCJyZW1vdmVBdHRyIiwic3dpdGNoX21vZGUiLCJldmVudCIsIiRvcHRpb24iLCJjdXJyZW50VGFyZ2V0IiwiY2xvc2VzdCIsInByZXZlbnREZWZhdWx0IiwiaGFzQ2xhc3MiLCJzYXZpbmciLCJhamF4IiwidXJsIiwiYWpheF91cmwiLCJtZXRob2QiLCJkYXRhVHlwZSIsImFjdGlvbiIsIm5vbmNlIiwib3JpZ2luX3VybCIsImxvY2F0aW9uIiwiaHJlZiIsInNwbGl0IiwiZnJhZ21lbnQiLCJoYXNoIiwic3Vic3RyaW5nIiwiZG9uZSIsInN1Y2Nlc3MiLCJyZWRpcmVjdF91cmwiLCJzd2l0Y2hlZCIsImFzc2lnbiIsImZhaWwiLCJ4aHIiLCJyZXNwb25zZUpTT04iLCJydW5fcXVpY2tzdGFydCIsIiRidXR0b24iLCIkYWN0aW9ucyIsInF1aWNrc3RhcnQiLCJwcm9wIiwiY29uZmlybSIsInF1aWNrc3RhcnRfY29uZmlybSIsIiR0ZXN0X3BhZ2UiLCJ0ZXN0X3VybCIsInF1aWNrc3RhcnRfZXJyb3IiLCJyZW1vdmVDbGFzcyIsInRyaWdnZXIiLCJ0ZXN0X3BhZ2UiLCJhbHdheXMiLCJkb2N1bWVudCIsIm9uIiwialF1ZXJ5Il0sInNvdXJjZXMiOlsiaW5jbHVkZXMvYm9va2luZ19tb2Rlc192My9fc3JjL2Jvb2tpbmdfbW9kZXMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZ2xvYmFsIGpRdWVyeSwgd3BiY19ib29raW5nX21vZGVzX2NvbmZpZywgd3BiY19hZG1pbl9zaG93X21lc3NhZ2UgKi9cbihmdW5jdGlvbiAoJCkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIHN3aXRjaF9idXN5ID0gZmFsc2U7XG5cdHZhciBzd2l0Y2hfbWVzc2FnZV9zdG9yYWdlX2tleSA9ICd3cGJjX2Jvb2tpbmdfbW9kZXNfdjNfc3dpdGNoX3N1Y2Nlc3MnO1xuXHR2YXIgc3dpdGNoX21lc3NhZ2VfbWF4X2FnZSA9IDEyMDAwMDtcblxuXHQvKipcblx0ICogUmVhZCBhIHVzZXItZmFjaW5nIGVycm9yIGZyb20gYSBXb3JkUHJlc3MgQUpBWCByZXNwb25zZS5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R8dW5kZWZpbmVkfSByZXNwb25zZSBQYXJzZWQgQUpBWCByZXNwb25zZS5cblx0ICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBmYWxsYmFjayBPcHRpb25hbCBmYWxsYmFjayBtZXNzYWdlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFNhZmUgZXJyb3IgdGV4dC5cblx0ICovXG5cdGZ1bmN0aW9uIGdldF9lcnJvcl9tZXNzYWdlKHJlc3BvbnNlLCBmYWxsYmFjaykge1xuXHRcdGlmIChcblx0XHRcdHJlc3BvbnNlXG5cdFx0XHQmJiByZXNwb25zZS5kYXRhXG5cdFx0XHQmJiB0eXBlb2YgcmVzcG9uc2UuZGF0YS5tZXNzYWdlID09PSAnc3RyaW5nJ1xuXHRcdFx0JiYgcmVzcG9uc2UuZGF0YS5tZXNzYWdlLmxlbmd0aFxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIHJlc3BvbnNlLmRhdGEubWVzc2FnZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsbGJhY2sgfHwgd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLmVycm9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNob3cgYSBtb2RlLXN3aXRjaCBlcnJvciB0aHJvdWdoIHRoZSBleGlzdGluZyBCb29raW5nIENhbGVuZGFyIG5vdGlmaWVyLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBFcnJvciBtZXNzYWdlLlxuXHQgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IGRlbGF5IE9wdGlvbmFsIGRpc3BsYXkgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKi9cblx0ZnVuY3Rpb24gc2hvd19lcnJvcihtZXNzYWdlLCBkZWxheSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93LndwYmNfYWRtaW5fc2hvd19tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHR3aW5kb3cud3BiY19hZG1pbl9zaG93X21lc3NhZ2UobWVzc2FnZSwgJ2Vycm9yJywgZGVsYXkgfHwgMTAwMDAsIGZhbHNlKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR3aW5kb3cuYWxlcnQobWVzc2FnZSk7XG5cdH1cblxuXHQvKipcblx0ICogU2hvdyBhIHN1Y2Nlc3NmdWwgUXVpY2tTdGFydCBtZXNzYWdlIHRocm91Z2ggdGhlIGV4aXN0aW5nIG5vdGlmaWVyLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBTdWNjZXNzIG1lc3NhZ2UuXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqL1xuXHRmdW5jdGlvbiBzaG93X3N1Y2Nlc3MobWVzc2FnZSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93LndwYmNfYWRtaW5fc2hvd19tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHR3aW5kb3cud3BiY19hZG1pbl9zaG93X21lc3NhZ2UobWVzc2FnZSwgJ3N1Y2Nlc3MnLCAxMDAwMCwgZmFsc2UpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHdpbmRvdy5hbGVydChtZXNzYWdlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTaG93IG5vbi1ibG9ja2luZyBtb2RlLXN3aXRjaCBwcm9ncmVzcyB0aHJvdWdoIHRoZSBhZG1pbiBub3RpZmllci5cblx0ICpcblx0ICogVGhlIHJlcXVlc3QgbXVzdCBjb250aW51ZSBpbW1lZGlhdGVseSwgc28gdGhpcyBpbnRlbnRpb25hbGx5IGhhcyBubyBhbGVydFxuXHQgKiBmYWxsYmFjayB3aGVuIHRoZSBzaGFyZWQgQm9va2luZyBDYWxlbmRhciBub3RpZmllciBpcyB1bmF2YWlsYWJsZS5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgUHJvZ3Jlc3MgbWVzc2FnZS5cblx0ICogQHJldHVybiB7dm9pZH1cblx0ICovXG5cdGZ1bmN0aW9uIHNob3dfaW5mbyhtZXNzYWdlKSB7XG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cud3BiY19hZG1pbl9zaG93X21lc3NhZ2UgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdHdpbmRvdy53cGJjX2FkbWluX3Nob3dfbWVzc2FnZShtZXNzYWdlLCAnaW5mbycsIDEwMDAwLCBmYWxzZSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNob3cgdGhlIHNlcnZlci1jb25maXJtZWQgbW9kZSBhY3RpdmF0aW9uIGJlZm9yZSByZWRpcmVjdGluZy5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgU3VjY2VzcyBtZXNzYWdlLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKi9cblx0ZnVuY3Rpb24gc2hvd19zd2l0Y2hfc3VjY2VzcyhtZXNzYWdlKSB7XG5cdFx0aWYgKG1lc3NhZ2UgJiYgdHlwZW9mIHdpbmRvdy53cGJjX2FkbWluX3Nob3dfbWVzc2FnZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0d2luZG93LndwYmNfYWRtaW5fc2hvd19tZXNzYWdlKG1lc3NhZ2UsICdzdWNjZXNzJywgMTUwMCwgZmFsc2UpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTYXZlIHRoZSBhY3RpdmF0ZWQgbW9kZSBmb3IgYSBWMS1jb21wYXRpYmxlIG5vdGljZSBvbiB0aGUgZmluYWwgcGFnZS5cblx0ICpcblx0ICogVjMgdXNlcyBhIHNpZ25lZCBmdWxsLWFkbWluaXN0cmF0aW9uIGxhbmRpbmcgYmVmb3JlIHRoZSBmaW5hbCBkZXN0aW5hdGlvbixcblx0ICogc28gYW4gaW4tcGFnZSBub3RpY2Ugc2hvd24gYmVmb3JlIG5hdmlnYXRpb24gd291bGQgb3RoZXJ3aXNlIGRpc2FwcGVhci5cblx0ICogU2Vzc2lvbiBzdG9yYWdlIGtlZXBzIHRoaXMgcHJlc2VudGF0aW9uLW9ubHkgc3RhdGUgb3V0IG9mIFdvcmRQcmVzcyBkYXRhXG5cdCAqIGFuZCBuYXR1cmFsbHkgaXNvbGF0ZXMgaXQgdG8gdGhlIHRhYiB0aGF0IGluaXRpYXRlZCB0aGUgc3dpdGNoLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbW9kZV9pZCBBY3RpdmF0ZWQgbW9kZSBpZGVudGlmaWVyLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKi9cblx0ZnVuY3Rpb24gc3RvcmVfc3dpdGNoX3N1Y2Nlc3MobW9kZV9pZCkge1xuXHRcdHZhciBub3JtYWxpemVkX21vZGVfaWQgPSB0eXBlb2YgbW9kZV9pZCA9PT0gJ3N0cmluZycgPyBtb2RlX2lkIDogJyc7XG5cblx0XHRpZiAoIW5vcm1hbGl6ZWRfbW9kZV9pZCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRyeSB7XG5cdFx0XHR3aW5kb3cuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShcblx0XHRcdFx0c3dpdGNoX21lc3NhZ2Vfc3RvcmFnZV9rZXksXG5cdFx0XHRcdEpTT04uc3RyaW5naWZ5KHtcblx0XHRcdFx0XHRtb2RlX2lkOiBub3JtYWxpemVkX21vZGVfaWQsXG5cdFx0XHRcdFx0Y3JlYXRlZF9hdDogRGF0ZS5ub3coKVxuXHRcdFx0XHR9KVxuXHRcdFx0KTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0Ly8gQSBibG9ja2VkIG9yIGZ1bGwgYnJvd3NlciBzdG9yZSBtdXN0IG5ldmVyIHByZXZlbnQgbW9kZSBzd2l0Y2hpbmcuXG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNob3cgYW5kIGNvbnN1bWUgdGhlIHBlbmRpbmcgc3dpdGNoIG1lc3NhZ2Ugb24gdGhlIGZpbmFsIFdQQkMgcGFnZS5cblx0ICpcblx0ICogVGhlIHJlY29yZCBpcyByZW1vdmVkIGJlZm9yZSB2YWxpZGF0aW9uIG9yIGRpc3BsYXkgc28gcmVmcmVzaGVzLCBtYWxmb3JtZWRcblx0ICogdmFsdWVzLCBhY2NvdW50IGNoYW5nZXMsIGFuZCBzdGFsZSByZWNvcmRzIGNhbm5vdCByZXBsYXkgaXQuIE1hdGNoaW5nIHRoZVxuXHQgKiBsb2NhbGl6ZWQgc2VsZWN0ZWQgbW9kZSBwcmV2ZW50cyBhIG5vdGljZSBmcm9tIGxlYWtpbmcgaW50byBhbm90aGVyIG1vZGUuXG5cdCAqXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqL1xuXHRmdW5jdGlvbiBzaG93X3BlbmRpbmdfc3dpdGNoX3N1Y2Nlc3MoKSB7XG5cdFx0dmFyIHNlcmlhbGl6ZWRfbWVzc2FnZTtcblx0XHR2YXIgcGVuZGluZ19tZXNzYWdlO1xuXHRcdHZhciBjdXJyZW50X21vZGVfaWQgPSBTdHJpbmcod3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5zZWxlY3RlZF9tb2RlX2lkIHx8ICcnKTtcblx0XHR2YXIgc3VjY2Vzc19tZXNzYWdlID0gd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLnN3aXRjaF9zdWNjZXNzIHx8ICcnO1xuXG5cdFx0dHJ5IHtcblx0XHRcdHNlcmlhbGl6ZWRfbWVzc2FnZSA9IHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKHN3aXRjaF9tZXNzYWdlX3N0b3JhZ2Vfa2V5KTtcblx0XHRcdHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5yZW1vdmVJdGVtKHN3aXRjaF9tZXNzYWdlX3N0b3JhZ2Vfa2V5KTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICghc2VyaWFsaXplZF9tZXNzYWdlIHx8ICFjdXJyZW50X21vZGVfaWQgfHwgdHlwZW9mIHN1Y2Nlc3NfbWVzc2FnZSAhPT0gJ3N0cmluZycgfHwgIXN1Y2Nlc3NfbWVzc2FnZSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRyeSB7XG5cdFx0XHRwZW5kaW5nX21lc3NhZ2UgPSBKU09OLnBhcnNlKHNlcmlhbGl6ZWRfbWVzc2FnZSk7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoXG5cdFx0XHQhcGVuZGluZ19tZXNzYWdlXG5cdFx0XHR8fCBwZW5kaW5nX21lc3NhZ2UubW9kZV9pZCAhPT0gY3VycmVudF9tb2RlX2lkXG5cdFx0XHR8fCB0eXBlb2YgcGVuZGluZ19tZXNzYWdlLmNyZWF0ZWRfYXQgIT09ICdudW1iZXInXG5cdFx0XHR8fCBwZW5kaW5nX21lc3NhZ2UuY3JlYXRlZF9hdCA+IERhdGUubm93KClcblx0XHRcdHx8IERhdGUubm93KCkgLSBwZW5kaW5nX21lc3NhZ2UuY3JlYXRlZF9hdCA+IHN3aXRjaF9tZXNzYWdlX21heF9hZ2Vcblx0XHQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRzaG93X3N3aXRjaF9zdWNjZXNzKHN1Y2Nlc3NfbWVzc2FnZSk7XG5cdH1cblxuXHQvKipcblx0ICogVG9nZ2xlIHRoZSBzaGFyZWQgc3dpdGNoaW5nIHN0YXRlIGFuZCBhbGwgZHJvcGRvd24gY2hvaWNlcy5cblx0ICpcblx0ICogQHBhcmFtIHtqUXVlcnl9ICRzZWxlY3RvciBNb2RlIHNlbGVjdG9yIGNvbnRhaW5lci5cblx0ICogQHBhcmFtIHtib29sZWFufSBpc19idXN5IFdoZXRoZXIgYSBtb2RlLXN3aXRjaCByZXF1ZXN0IGlzIGFjdGl2ZS5cblx0ICogQHJldHVybiB7dm9pZH1cblx0ICovXG5cdGZ1bmN0aW9uIHNldF9zd2l0Y2hpbmdfc3RhdGUoJHNlbGVjdG9yLCBpc19idXN5KSB7XG5cdFx0c3dpdGNoX2J1c3kgPSBpc19idXN5O1xuXHRcdCRzZWxlY3Rvci50b2dnbGVDbGFzcygnaXMtc3dpdGNoaW5nJywgaXNfYnVzeSk7XG5cblx0XHRpZiAoaXNfYnVzeSkge1xuXHRcdFx0JHNlbGVjdG9yLmF0dHIoJ2FyaWEtYnVzeScsICd0cnVlJyk7XG5cdFx0XHQkc2VsZWN0b3IuZmluZCgnLndwYmNfYm9va2luZ19tb2RlX29wdGlvbicpLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCAndHJ1ZScpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCRzZWxlY3Rvci5yZW1vdmVBdHRyKCdhcmlhLWJ1c3knKTtcblx0XHQkc2VsZWN0b3IuZmluZCgnLndwYmNfYm9va2luZ19tb2RlX29wdGlvbicpLnJlbW92ZUF0dHIoJ2FyaWEtZGlzYWJsZWQnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQZXJzaXN0IGEgc2VsZWN0ZWQgbW9kZSBhbmQgZm9sbG93IHRoZSBzZXJ2ZXItYXBwcm92ZWQgcmVkaXJlY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IENsaWNrIGV2ZW50IGZvciBhIHNlbGVjdG9yIG9wdGlvbi5cblx0ICogQHJldHVybiB7dm9pZH1cblx0ICovXG5cdGZ1bmN0aW9uIHN3aXRjaF9tb2RlKGV2ZW50KSB7XG5cdFx0dmFyICRvcHRpb24gPSAkKGV2ZW50LmN1cnJlbnRUYXJnZXQpO1xuXHRcdHZhciAkc2VsZWN0b3IgPSAkb3B0aW9uLmNsb3Nlc3QoJy53cGJjX2Jvb2tpbmdfbW9kZXNfc2VsZWN0b3InKTtcblx0XHR2YXIgbW9kZV9pZCA9IFN0cmluZygkb3B0aW9uLmRhdGEoJ21vZGUtaWQnKSB8fCAnJyk7XG5cblx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG5cdFx0aWYgKHN3aXRjaF9idXN5IHx8ICFtb2RlX2lkIHx8ICRvcHRpb24uaGFzQ2xhc3MoJ2lzLWN1cnJlbnQnKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHNldF9zd2l0Y2hpbmdfc3RhdGUoJHNlbGVjdG9yLCB0cnVlKTtcblx0XHRzaG93X2luZm8od3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLnNhdmluZyB8fCAnU3dpdGNoaW5nIEJvb2tpbmcgQ2FsZW5kYXIgbW9kZS4uLicpO1xuXG5cdFx0JC5hamF4KHtcblx0XHRcdHVybDogd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5hamF4X3VybCxcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcblx0XHRcdGRhdGE6IHtcblx0XHRcdFx0YWN0aW9uOiB3cGJjX2Jvb2tpbmdfbW9kZXNfY29uZmlnLmFjdGlvbixcblx0XHRcdFx0bm9uY2U6IHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcubm9uY2UsXG5cdFx0XHRcdG1vZGVfaWQ6IG1vZGVfaWQsXG5cdFx0XHRcdG9yaWdpbl91cmw6IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KCcjJylbMF0sXG5cdFx0XHRcdGZyYWdtZW50OiB3aW5kb3cubG9jYXRpb24uaGFzaCA/IHdpbmRvdy5sb2NhdGlvbi5oYXNoLnN1YnN0cmluZygxKSA6ICcnXG5cdFx0XHR9XG5cdFx0fSkuZG9uZShmdW5jdGlvbiAocmVzcG9uc2UpIHtcblx0XHRcdGlmIChcblx0XHRcdFx0IXJlc3BvbnNlXG5cdFx0XHRcdHx8IHJlc3BvbnNlLnN1Y2Nlc3MgIT09IHRydWVcblx0XHRcdFx0fHwgIXJlc3BvbnNlLmRhdGFcblx0XHRcdFx0fHwgdHlwZW9mIHJlc3BvbnNlLmRhdGEucmVkaXJlY3RfdXJsICE9PSAnc3RyaW5nJ1xuXHRcdFx0XHR8fCAhcmVzcG9uc2UuZGF0YS5yZWRpcmVjdF91cmwubGVuZ3RoXG5cdFx0XHQpIHtcblx0XHRcdFx0c2V0X3N3aXRjaGluZ19zdGF0ZSgkc2VsZWN0b3IsIGZhbHNlKTtcblx0XHRcdFx0c2hvd19lcnJvcihnZXRfZXJyb3JfbWVzc2FnZShyZXNwb25zZSksIDcwMDApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHNob3dfc3dpdGNoX3N1Y2Nlc3MocmVzcG9uc2UuZGF0YS5tZXNzYWdlIHx8IHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcuaTE4bi5zd2l0Y2hlZCk7XG5cdFx0XHRzdG9yZV9zd2l0Y2hfc3VjY2Vzcyhtb2RlX2lkKTtcblx0XHRcdHdpbmRvdy5sb2NhdGlvbi5hc3NpZ24ocmVzcG9uc2UuZGF0YS5yZWRpcmVjdF91cmwpO1xuXHRcdH0pLmZhaWwoZnVuY3Rpb24gKHhocikge1xuXHRcdFx0c2V0X3N3aXRjaGluZ19zdGF0ZSgkc2VsZWN0b3IsIGZhbHNlKTtcblx0XHRcdHNob3dfZXJyb3IoZ2V0X2Vycm9yX21lc3NhZ2UoeGhyLnJlc3BvbnNlSlNPTiksIDcwMDApO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJ1biBhIHNlcGFyYXRlbHkgY29uZmlybWVkLCBzdGF0ZS1jaGFuZ2luZyBRdWlja1N0YXJ0IG9wZXJhdGlvbi5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnQgQ2xpY2sgZXZlbnQgZm9yIGEgUXVpY2tTdGFydCBidXR0b24uXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqL1xuXHRmdW5jdGlvbiBydW5fcXVpY2tzdGFydChldmVudCkge1xuXHRcdHZhciAkYnV0dG9uID0gJChldmVudC5jdXJyZW50VGFyZ2V0KTtcblx0XHR2YXIgJGFjdGlvbnMgPSAkYnV0dG9uLmNsb3Nlc3QoJy53cGJjX2Jvb2tpbmdfbW9kZXNfcXVpY2tzdGFydF9hY3Rpb25zJyk7XG5cdFx0dmFyIG1vZGVfaWQgPSBTdHJpbmcoJGJ1dHRvbi5kYXRhKCdtb2RlLWlkJykgfHwgJycpO1xuXHRcdHZhciBxdWlja3N0YXJ0ID0gd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5xdWlja3N0YXJ0IHx8IHt9O1xuXG5cdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuXHRcdGlmICghbW9kZV9pZCB8fCAhcXVpY2tzdGFydC5hY3Rpb24gfHwgIXF1aWNrc3RhcnQubm9uY2UgfHwgJGJ1dHRvbi5wcm9wKCdkaXNhYmxlZCcpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCF3aW5kb3cuY29uZmlybSh3cGJjX2Jvb2tpbmdfbW9kZXNfY29uZmlnLmkxOG4ucXVpY2tzdGFydF9jb25maXJtKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCRidXR0b24ucHJvcCgnZGlzYWJsZWQnLCB0cnVlKS5hdHRyKCdhcmlhLWJ1c3knLCAndHJ1ZScpO1xuXG5cdFx0JC5hamF4KHtcblx0XHRcdHVybDogd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5hamF4X3VybCxcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcblx0XHRcdGRhdGE6IHtcblx0XHRcdFx0YWN0aW9uOiBxdWlja3N0YXJ0LmFjdGlvbixcblx0XHRcdFx0bm9uY2U6IHF1aWNrc3RhcnQubm9uY2UsXG5cdFx0XHRcdG1vZGVfaWQ6IG1vZGVfaWRcblx0XHRcdH1cblx0XHR9KS5kb25lKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXHRcdFx0dmFyICR0ZXN0X3BhZ2U7XG5cblx0XHRcdGlmIChcblx0XHRcdFx0IXJlc3BvbnNlXG5cdFx0XHRcdHx8IHJlc3BvbnNlLnN1Y2Nlc3MgIT09IHRydWVcblx0XHRcdFx0fHwgIXJlc3BvbnNlLmRhdGFcblx0XHRcdFx0fHwgdHlwZW9mIHJlc3BvbnNlLmRhdGEudGVzdF91cmwgIT09ICdzdHJpbmcnXG5cdFx0XHRcdHx8ICFyZXNwb25zZS5kYXRhLnRlc3RfdXJsLmxlbmd0aFxuXHRcdFx0KSB7XG5cdFx0XHRcdHNob3dfZXJyb3IoZ2V0X2Vycm9yX21lc3NhZ2UocmVzcG9uc2UsIHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcuaTE4bi5xdWlja3N0YXJ0X2Vycm9yKSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0JHRlc3RfcGFnZSA9ICRhY3Rpb25zLmZpbmQoJy53cGJjX2Jvb2tpbmdfbW9kZXNfdGVzdF9wYWdlJyk7XG5cdFx0XHQkdGVzdF9wYWdlLmF0dHIoJ2hyZWYnLCByZXNwb25zZS5kYXRhLnRlc3RfdXJsKS5yZW1vdmVDbGFzcygnaXMtaGlkZGVuJykudHJpZ2dlcignZm9jdXMnKTtcblx0XHRcdHNob3dfc3VjY2VzcyhyZXNwb25zZS5kYXRhLm1lc3NhZ2UgfHwgd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLnRlc3RfcGFnZSk7XG5cdFx0fSkuZmFpbChmdW5jdGlvbiAoeGhyKSB7XG5cdFx0XHRzaG93X2Vycm9yKGdldF9lcnJvcl9tZXNzYWdlKHhoci5yZXNwb25zZUpTT04sIHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcuaTE4bi5xdWlja3N0YXJ0X2Vycm9yKSk7XG5cdFx0fSkuYWx3YXlzKGZ1bmN0aW9uICgpIHtcblx0XHRcdCRidXR0b24ucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSkucmVtb3ZlQXR0cignYXJpYS1idXN5Jyk7XG5cdFx0fSk7XG5cdH1cblxuXHQkKGRvY3VtZW50KS5vbignY2xpY2snLCAnLndwYmNfYm9va2luZ19tb2RlX29wdGlvbicsIHN3aXRjaF9tb2RlKTtcblx0JChkb2N1bWVudCkub24oJ2NsaWNrJywgJy53cGJjX2Jvb2tpbmdfbW9kZXNfcXVpY2tzdGFydF9idXR0b24nLCBydW5fcXVpY2tzdGFydCk7XG5cdCQoc2hvd19wZW5kaW5nX3N3aXRjaF9zdWNjZXNzKTtcbn0oalF1ZXJ5KSk7XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQyxXQUFVQSxDQUFDLEVBQUU7RUFDYixZQUFZOztFQUVaLElBQUlDLFdBQVcsR0FBRyxLQUFLO0VBQ3ZCLElBQUlDLDBCQUEwQixHQUFHLHNDQUFzQztFQUN2RSxJQUFJQyxzQkFBc0IsR0FBRyxNQUFNOztFQUVuQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNDLFNBQVNDLGlCQUFpQkEsQ0FBQ0MsUUFBUSxFQUFFQyxRQUFRLEVBQUU7SUFDOUMsSUFDQ0QsUUFBUSxJQUNMQSxRQUFRLENBQUNFLElBQUksSUFDYixPQUFPRixRQUFRLENBQUNFLElBQUksQ0FBQ0MsT0FBTyxLQUFLLFFBQVEsSUFDekNILFFBQVEsQ0FBQ0UsSUFBSSxDQUFDQyxPQUFPLENBQUNDLE1BQU0sRUFDOUI7TUFDRCxPQUFPSixRQUFRLENBQUNFLElBQUksQ0FBQ0MsT0FBTztJQUM3QjtJQUVBLE9BQU9GLFFBQVEsSUFBSUkseUJBQXlCLENBQUNDLElBQUksQ0FBQ0MsS0FBSztFQUN4RDs7RUFFQTtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNDLFNBQVNDLFVBQVVBLENBQUNMLE9BQU8sRUFBRU0sS0FBSyxFQUFFO0lBQ25DLElBQUksT0FBT0MsTUFBTSxDQUFDQyx1QkFBdUIsS0FBSyxVQUFVLEVBQUU7TUFDekRELE1BQU0sQ0FBQ0MsdUJBQXVCLENBQUNSLE9BQU8sRUFBRSxPQUFPLEVBQUVNLEtBQUssSUFBSSxLQUFLLEVBQUUsS0FBSyxDQUFDO01BQ3ZFO0lBQ0Q7SUFFQUMsTUFBTSxDQUFDRSxLQUFLLENBQUNULE9BQU8sQ0FBQztFQUN0Qjs7RUFFQTtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDQyxTQUFTVSxZQUFZQSxDQUFDVixPQUFPLEVBQUU7SUFDOUIsSUFB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 |
| 250 |
|