# booking/11.9/includes/booking_modes_v3/_out/booking_modes.js

Booking Calendar, version 11.9. 250 lines.

- Page: https://pluginprobe.com/plugins/booking/11.9/code/includes/booking_modes_v3/_out/booking_modes.js
- Raw: https://pluginprobe.com/plugins/booking/11.9/raw/includes/booking_modes_v3/_out/booking_modes.js
- Modified: 2026-09-10T16:09:30+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/booking/11.9/code/includes/booking_modes_v3/_out/booking_modes.js#L10-L20`.

```javascript
"use strict";

/* global jQuery, wpbc_booking_modes_config, wpbc_admin_show_message */
(function ($) {
  'use strict';

  var switch_busy = false;
  var switch_message_storage_key = 'wpbc_booking_modes_v3_switch_success';
  var switch_message_max_age = 120000;

  /**
   * Read a user-facing error from a WordPress AJAX response.
   *
   * @param {Object|undefined} response Parsed AJAX response.
   * @param {string|undefined} fallback Optional fallback message.
   * @return {string} Safe error text.
   */
  function get_error_message(response, fallback) {
    if (response && response.data && typeof response.data.message === 'string' && response.data.message.length) {
      return response.data.message;
    }
    return fallback || wpbc_booking_modes_config.i18n.error;
  }

  /**
   * Show a mode-switch error through the existing Booking Calendar notifier.
   *
   * @param {string} message Error message.
   * @param {number|undefined} delay Optional display duration in milliseconds.
   * @return {void}
   */
  function show_error(message, delay) {
    if (typeof window.wpbc_admin_show_message === 'function') {
      window.wpbc_admin_show_message(message, 'error', delay || 10000, false);
      return;
    }
    window.alert(message);
  }

  /**
   * Show a successful QuickStart message through the existing notifier.
   *
   * @param {string} message Success message.
   * @return {void}
   */
  function show_success(message) {
    if (typeof window.wpbc_admin_show_message === 'function') {
      window.wpbc_admin_show_message(message, 'success', 10000, false);
      return;
    }
    window.alert(message);
  }

  /**
   * Show non-blocking mode-switch progress through the admin notifier.
   *
   * The request must continue immediately, so this intentionally has no alert
   * fallback when the shared Booking Calendar notifier is unavailable.
   *
   * @param {string} message Progress message.
   * @return {void}
   */
  function show_info(message) {
    if (typeof window.wpbc_admin_show_message === 'function') {
      window.wpbc_admin_show_message(message, 'info', 10000, false);
    }
  }

  /**
   * Show the server-confirmed mode activation before redirecting.
   *
   * @param {string} message Success message.
   * @return {void}
   */
  function show_switch_success(message) {
    if (message && typeof window.wpbc_admin_show_message === 'function') {
      window.wpbc_admin_show_message(message, 'success', 1500, false);
    }
  }

  /**
   * Save the activated mode for a V1-compatible notice on the final page.
   *
   * V3 uses a signed full-administration landing before the final destination,
   * so an in-page notice shown before navigation would otherwise disappear.
   * Session storage keeps this presentation-only state out of WordPress data
   * and naturally isolates it to the tab that initiated the switch.
   *
   * @param {string} mode_id Activated mode identifier.
   * @return {void}
   */
  function store_switch_success(mode_id) {
    var normalized_mode_id = typeof mode_id === 'string' ? mode_id : '';
    if (!normalized_mode_id) {
      return;
    }
    try {
      window.sessionStorage.setItem(switch_message_storage_key, JSON.stringify({
        mode_id: normalized_mode_id,
        created_at: Date.now()
      }));
    } catch (error) {
      // A blocked or full browser store must never prevent mode switching.
    }
  }

  /**
   * Show and consume the pending switch message on the final WPBC page.
   *
   * The record is removed before validation or display so refreshes, malformed
   * values, account changes, and stale records cannot replay it. Matching the
   * localized selected mode prevents a notice from leaking into another mode.
   *
   * @return {void}
   */
  function show_pending_switch_success() {
    var serialized_message;
    var pending_message;
    var current_mode_id = String(wpbc_booking_modes_config.selected_mode_id || '');
    var success_message = wpbc_booking_modes_config.i18n.switch_success || '';
    try {
      serialized_message = window.sessionStorage.getItem(switch_message_storage_key);
      window.sessionStorage.removeItem(switch_message_storage_key);
    } catch (error) {
      return;
    }
    if (!serialized_message || !current_mode_id || typeof success_message !== 'string' || !success_message) {
      return;
    }
    try {
      pending_message = JSON.parse(serialized_message);
    } catch (error) {
      return;
    }
    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) {
      return;
    }
    show_switch_success(success_message);
  }

  /**
   * Toggle the shared switching state and all dropdown choices.
   *
   * @param {jQuery} $selector Mode selector container.
   * @param {boolean} is_busy Whether a mode-switch request is active.
   * @return {void}
   */
  function set_switching_state($selector, is_busy) {
    switch_busy = is_busy;
    $selector.toggleClass('is-switching', is_busy);
    if (is_busy) {
      $selector.attr('aria-busy', 'true');
      $selector.find('.wpbc_booking_mode_option').attr('aria-disabled', 'true');
      return;
    }
    $selector.removeAttr('aria-busy');
    $selector.find('.wpbc_booking_mode_option').removeAttr('aria-disabled');
  }

  /**
   * Persist a selected mode and follow the server-approved redirect.
   *
   * @param {Event} event Click event for a selector option.
   * @return {void}
   */
  function switch_mode(event) {
    var $option = $(event.currentTarget);
    var $selector = $option.closest('.wpbc_booking_modes_selector');
    var mode_id = String($option.data('mode-id') || '');
    event.preventDefault();
    if (switch_busy || !mode_id || $option.hasClass('is-current')) {
      return;
    }
    set_switching_state($selector, true);
    show_info(wpbc_booking_modes_config.i18n.saving || 'Switching Booking Calendar mode...');
    $.ajax({
      url: wpbc_booking_modes_config.ajax_url,
      method: 'POST',
      dataType: 'json',
      data: {
        action: wpbc_booking_modes_config.action,
        nonce: wpbc_booking_modes_config.nonce,
        mode_id: mode_id,
        origin_url: window.location.href.split('#')[0],
        fragment: window.location.hash ? window.location.hash.substring(1) : ''
      }
    }).done(function (response) {
      if (!response || response.success !== true || !response.data || typeof response.data.redirect_url !== 'string' || !response.data.redirect_url.length) {
        set_switching_state($selector, false);
        show_error(get_error_message(response), 7000);
        return;
      }
      show_switch_success(response.data.message || wpbc_booking_modes_config.i18n.switched);
      store_switch_success(mode_id);
      window.location.assign(response.data.redirect_url);
    }).fail(function (xhr) {
      set_switching_state($selector, false);
      show_error(get_error_message(xhr.responseJSON), 7000);
    });
  }

  /**
   * Run a separately confirmed, state-changing QuickStart operation.
   *
   * @param {Event} event Click event for a QuickStart button.
   * @return {void}
   */
  function run_quickstart(event) {
    var $button = $(event.currentTarget);
    var $actions = $button.closest('.wpbc_booking_modes_quickstart_actions');
    var mode_id = String($button.data('mode-id') || '');
    var quickstart = wpbc_booking_modes_config.quickstart || {};
    event.preventDefault();
    if (!mode_id || !quickstart.action || !quickstart.nonce || $button.prop('disabled')) {
      return;
    }
    if (!window.confirm(wpbc_booking_modes_config.i18n.quickstart_confirm)) {
      return;
    }
    $button.prop('disabled', true).attr('aria-busy', 'true');
    $.ajax({
      url: wpbc_booking_modes_config.ajax_url,
      method: 'POST',
      dataType: 'json',
      data: {
        action: quickstart.action,
        nonce: quickstart.nonce,
        mode_id: mode_id
      }
    }).done(function (response) {
      var $test_page;
      if (!response || response.success !== true || !response.data || typeof response.data.test_url !== 'string' || !response.data.test_url.length) {
        show_error(get_error_message(response, wpbc_booking_modes_config.i18n.quickstart_error));
        return;
      }
      $test_page = $actions.find('.wpbc_booking_modes_test_page');
      $test_page.attr('href', response.data.test_url).removeClass('is-hidden').trigger('focus');
      show_success(response.data.message || wpbc_booking_modes_config.i18n.test_page);
    }).fail(function (xhr) {
      show_error(get_error_message(xhr.responseJSON, wpbc_booking_modes_config.i18n.quickstart_error));
    }).always(function () {
      $button.prop('disabled', false).removeAttr('aria-busy');
    });
  }
  $(document).on('click', '.wpbc_booking_mode_option', switch_mode);
  $(document).on('click', '.wpbc_booking_modes_quickstart_button', run_quickstart);
  $(show_pending_switch_success);
})(jQuery);
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5jbHVkZXMvYm9va2luZ19tb2Rlc192My9fb3V0L2Jvb2tpbmdfbW9kZXMuanMiLCJuYW1lcyI6WyIkIiwic3dpdGNoX2J1c3kiLCJzd2l0Y2hfbWVzc2FnZV9zdG9yYWdlX2tleSIsInN3aXRjaF9tZXNzYWdlX21heF9hZ2UiLCJnZXRfZXJyb3JfbWVzc2FnZSIsInJlc3BvbnNlIiwiZmFsbGJhY2siLCJkYXRhIiwibWVzc2FnZSIsImxlbmd0aCIsIndwYmNfYm9va2luZ19tb2Rlc19jb25maWciLCJpMThuIiwiZXJyb3IiLCJzaG93X2Vycm9yIiwiZGVsYXkiLCJ3aW5kb3ciLCJ3cGJjX2FkbWluX3Nob3dfbWVzc2FnZSIsImFsZXJ0Iiwic2hvd19zdWNjZXNzIiwic2hvd19pbmZvIiwic2hvd19zd2l0Y2hfc3VjY2VzcyIsInN0b3JlX3N3aXRjaF9zdWNjZXNzIiwibW9kZV9pZCIsIm5vcm1hbGl6ZWRfbW9kZV9pZCIsInNlc3Npb25TdG9yYWdlIiwic2V0SXRlbSIsIkpTT04iLCJzdHJpbmdpZnkiLCJjcmVhdGVkX2F0IiwiRGF0ZSIsIm5vdyIsInNob3dfcGVuZGluZ19zd2l0Y2hfc3VjY2VzcyIsInNlcmlhbGl6ZWRfbWVzc2FnZSIsInBlbmRpbmdfbWVzc2FnZSIsImN1cnJlbnRfbW9kZV9pZCIsIlN0cmluZyIsInNlbGVjdGVkX21vZGVfaWQiLCJzdWNjZXNzX21lc3NhZ2UiLCJzd2l0Y2hfc3VjY2VzcyIsImdldEl0ZW0iLCJyZW1vdmVJdGVtIiwicGFyc2UiLCJzZXRfc3dpdGNoaW5nX3N0YXRlIiwiJHNlbGVjdG9yIiwiaXNfYnVzeSIsInRvZ2dsZUNsYXNzIiwiYXR0ciIsImZpbmQiLCJyZW1vdmVBdHRyIiwic3dpdGNoX21vZGUiLCJldmVudCIsIiRvcHRpb24iLCJjdXJyZW50VGFyZ2V0IiwiY2xvc2VzdCIsInByZXZlbnREZWZhdWx0IiwiaGFzQ2xhc3MiLCJzYXZpbmciLCJhamF4IiwidXJsIiwiYWpheF91cmwiLCJtZXRob2QiLCJkYXRhVHlwZSIsImFjdGlvbiIsIm5vbmNlIiwib3JpZ2luX3VybCIsImxvY2F0aW9uIiwiaHJlZiIsInNwbGl0IiwiZnJhZ21lbnQiLCJoYXNoIiwic3Vic3RyaW5nIiwiZG9uZSIsInN1Y2Nlc3MiLCJyZWRpcmVjdF91cmwiLCJzd2l0Y2hlZCIsImFzc2lnbiIsImZhaWwiLCJ4aHIiLCJyZXNwb25zZUpTT04iLCJydW5fcXVpY2tzdGFydCIsIiRidXR0b24iLCIkYWN0aW9ucyIsInF1aWNrc3RhcnQiLCJwcm9wIiwiY29uZmlybSIsInF1aWNrc3RhcnRfY29uZmlybSIsIiR0ZXN0X3BhZ2UiLCJ0ZXN0X3VybCIsInF1aWNrc3RhcnRfZXJyb3IiLCJyZW1vdmVDbGFzcyIsInRyaWdnZXIiLCJ0ZXN0X3BhZ2UiLCJhbHdheXMiLCJkb2N1bWVudCIsIm9uIiwialF1ZXJ5Il0sInNvdXJjZXMiOlsiaW5jbHVkZXMvYm9va2luZ19tb2Rlc192My9fc3JjL2Jvb2tpbmdfbW9kZXMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZ2xvYmFsIGpRdWVyeSwgd3BiY19ib29raW5nX21vZGVzX2NvbmZpZywgd3BiY19hZG1pbl9zaG93X21lc3NhZ2UgKi9cbihmdW5jdGlvbiAoJCkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIHN3aXRjaF9idXN5ID0gZmFsc2U7XG5cdHZhciBzd2l0Y2hfbWVzc2FnZV9zdG9yYWdlX2tleSA9ICd3cGJjX2Jvb2tpbmdfbW9kZXNfdjNfc3dpdGNoX3N1Y2Nlc3MnO1xuXHR2YXIgc3dpdGNoX21lc3NhZ2VfbWF4X2FnZSA9IDEyMDAwMDtcblxuXHQvKipcblx0ICogUmVhZCBhIHVzZXItZmFjaW5nIGVycm9yIGZyb20gYSBXb3JkUHJlc3MgQUpBWCByZXNwb25zZS5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R8dW5kZWZpbmVkfSByZXNwb25zZSBQYXJzZWQgQUpBWCByZXNwb25zZS5cblx0ICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBmYWxsYmFjayBPcHRpb25hbCBmYWxsYmFjayBtZXNzYWdlLlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IFNhZmUgZXJyb3IgdGV4dC5cblx0ICovXG5cdGZ1bmN0aW9uIGdldF9lcnJvcl9tZXNzYWdlKHJlc3BvbnNlLCBmYWxsYmFjaykge1xuXHRcdGlmIChcblx0XHRcdHJlc3BvbnNlXG5cdFx0XHQmJiByZXNwb25zZS5kYXRhXG5cdFx0XHQmJiB0eXBlb2YgcmVzcG9uc2UuZGF0YS5tZXNzYWdlID09PSAnc3RyaW5nJ1xuXHRcdFx0JiYgcmVzcG9uc2UuZGF0YS5tZXNzYWdlLmxlbmd0aFxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIHJlc3BvbnNlLmRhdGEubWVzc2FnZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsbGJhY2sgfHwgd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLmVycm9yO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNob3cgYSBtb2RlLXN3aXRjaCBlcnJvciB0aHJvdWdoIHRoZSBleGlzdGluZyBCb29raW5nIENhbGVuZGFyIG5vdGlmaWVyLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBFcnJvciBtZXNzYWdlLlxuXHQgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IGRlbGF5IE9wdGlvbmFsIGRpc3BsYXkgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKi9cblx0ZnVuY3Rpb24gc2hvd19lcnJvcihtZXNzYWdlLCBkZWxheSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93LndwYmNfYWRtaW5fc2hvd19tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHR3aW5kb3cud3BiY19hZG1pbl9zaG93X21lc3NhZ2UobWVzc2FnZSwgJ2Vycm9yJywgZGVsYXkgfHwgMTAwMDAsIGZhbHNlKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR3aW5kb3cuYWxlcnQobWVzc2FnZSk7XG5cdH1cblxuXHQvKipcblx0ICogU2hvdyBhIHN1Y2Nlc3NmdWwgUXVpY2tTdGFydCBtZXNzYWdlIHRocm91Z2ggdGhlIGV4aXN0aW5nIG5vdGlmaWVyLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBTdWNjZXNzIG1lc3NhZ2UuXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqL1xuXHRmdW5jdGlvbiBzaG93X3N1Y2Nlc3MobWVzc2FnZSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93LndwYmNfYWRtaW5fc2hvd19tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHR3aW5kb3cud3BiY19hZG1pbl9zaG93X21lc3NhZ2UobWVzc2FnZSwgJ3N1Y2Nlc3MnLCAxMDAwMCwgZmFsc2UpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHdpbmRvdy5hbGVydChtZXNzYWdlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTaG93IG5vbi1ibG9ja2luZyBtb2RlLXN3aXRjaCBwcm9ncmVzcyB0aHJvdWdoIHRoZSBhZG1pbiBub3RpZmllci5cblx0ICpcblx0ICogVGhlIHJlcXVlc3QgbXVzdCBjb250aW51ZSBpbW1lZGlhdGVseSwgc28gdGhpcyBpbnRlbnRpb25hbGx5IGhhcyBubyBhbGVydFxuXHQgKiBmYWxsYmFjayB3aGVuIHRoZSBzaGFyZWQgQm9va2luZyBDYWxlbmRhciBub3RpZmllciBpcyB1bmF2YWlsYWJsZS5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgUHJvZ3Jlc3MgbWVzc2FnZS5cblx0ICogQHJldHVybiB7dm9pZH1cblx0ICovXG5cdGZ1bmN0aW9uIHNob3dfaW5mbyhtZXNzYWdlKSB7XG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cud3BiY19hZG1pbl9zaG93X21lc3NhZ2UgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdHdpbmRvdy53cGJjX2FkbWluX3Nob3dfbWVzc2FnZShtZXNzYWdlLCAnaW5mbycsIDEwMDAwLCBmYWxzZSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNob3cgdGhlIHNlcnZlci1jb25maXJtZWQgbW9kZSBhY3RpdmF0aW9uIGJlZm9yZSByZWRpcmVjdGluZy5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgU3VjY2VzcyBtZXNzYWdlLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKi9cblx0ZnVuY3Rpb24gc2hvd19zd2l0Y2hfc3VjY2VzcyhtZXNzYWdlKSB7XG5cdFx0aWYgKG1lc3NhZ2UgJiYgdHlwZW9mIHdpbmRvdy53cGJjX2FkbWluX3Nob3dfbWVzc2FnZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0d2luZG93LndwYmNfYWRtaW5fc2hvd19tZXNzYWdlKG1lc3NhZ2UsICdzdWNjZXNzJywgMTUwMCwgZmFsc2UpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTYXZlIHRoZSBhY3RpdmF0ZWQgbW9kZSBmb3IgYSBWMS1jb21wYXRpYmxlIG5vdGljZSBvbiB0aGUgZmluYWwgcGFnZS5cblx0ICpcblx0ICogVjMgdXNlcyBhIHNpZ25lZCBmdWxsLWFkbWluaXN0cmF0aW9uIGxhbmRpbmcgYmVmb3JlIHRoZSBmaW5hbCBkZXN0aW5hdGlvbixcblx0ICogc28gYW4gaW4tcGFnZSBub3RpY2Ugc2hvd24gYmVmb3JlIG5hdmlnYXRpb24gd291bGQgb3RoZXJ3aXNlIGRpc2FwcGVhci5cblx0ICogU2Vzc2lvbiBzdG9yYWdlIGtlZXBzIHRoaXMgcHJlc2VudGF0aW9uLW9ubHkgc3RhdGUgb3V0IG9mIFdvcmRQcmVzcyBkYXRhXG5cdCAqIGFuZCBuYXR1cmFsbHkgaXNvbGF0ZXMgaXQgdG8gdGhlIHRhYiB0aGF0IGluaXRpYXRlZCB0aGUgc3dpdGNoLlxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gbW9kZV9pZCBBY3RpdmF0ZWQgbW9kZSBpZGVudGlmaWVyLlxuXHQgKiBAcmV0dXJuIHt2b2lkfVxuXHQgKi9cblx0ZnVuY3Rpb24gc3RvcmVfc3dpdGNoX3N1Y2Nlc3MobW9kZV9pZCkge1xuXHRcdHZhciBub3JtYWxpemVkX21vZGVfaWQgPSB0eXBlb2YgbW9kZV9pZCA9PT0gJ3N0cmluZycgPyBtb2RlX2lkIDogJyc7XG5cblx0XHRpZiAoIW5vcm1hbGl6ZWRfbW9kZV9pZCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRyeSB7XG5cdFx0XHR3aW5kb3cuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShcblx0XHRcdFx0c3dpdGNoX21lc3NhZ2Vfc3RvcmFnZV9rZXksXG5cdFx0XHRcdEpTT04uc3RyaW5naWZ5KHtcblx0XHRcdFx0XHRtb2RlX2lkOiBub3JtYWxpemVkX21vZGVfaWQsXG5cdFx0XHRcdFx0Y3JlYXRlZF9hdDogRGF0ZS5ub3coKVxuXHRcdFx0XHR9KVxuXHRcdFx0KTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0Ly8gQSBibG9ja2VkIG9yIGZ1bGwgYnJvd3NlciBzdG9yZSBtdXN0IG5ldmVyIHByZXZlbnQgbW9kZSBzd2l0Y2hpbmcuXG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFNob3cgYW5kIGNvbnN1bWUgdGhlIHBlbmRpbmcgc3dpdGNoIG1lc3NhZ2Ugb24gdGhlIGZpbmFsIFdQQkMgcGFnZS5cblx0ICpcblx0ICogVGhlIHJlY29yZCBpcyByZW1vdmVkIGJlZm9yZSB2YWxpZGF0aW9uIG9yIGRpc3BsYXkgc28gcmVmcmVzaGVzLCBtYWxmb3JtZWRcblx0ICogdmFsdWVzLCBhY2NvdW50IGNoYW5nZXMsIGFuZCBzdGFsZSByZWNvcmRzIGNhbm5vdCByZXBsYXkgaXQuIE1hdGNoaW5nIHRoZVxuXHQgKiBsb2NhbGl6ZWQgc2VsZWN0ZWQgbW9kZSBwcmV2ZW50cyBhIG5vdGljZSBmcm9tIGxlYWtpbmcgaW50byBhbm90aGVyIG1vZGUuXG5cdCAqXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqL1xuXHRmdW5jdGlvbiBzaG93X3BlbmRpbmdfc3dpdGNoX3N1Y2Nlc3MoKSB7XG5cdFx0dmFyIHNlcmlhbGl6ZWRfbWVzc2FnZTtcblx0XHR2YXIgcGVuZGluZ19tZXNzYWdlO1xuXHRcdHZhciBjdXJyZW50X21vZGVfaWQgPSBTdHJpbmcod3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5zZWxlY3RlZF9tb2RlX2lkIHx8ICcnKTtcblx0XHR2YXIgc3VjY2Vzc19tZXNzYWdlID0gd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLnN3aXRjaF9zdWNjZXNzIHx8ICcnO1xuXG5cdFx0dHJ5IHtcblx0XHRcdHNlcmlhbGl6ZWRfbWVzc2FnZSA9IHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKHN3aXRjaF9tZXNzYWdlX3N0b3JhZ2Vfa2V5KTtcblx0XHRcdHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5yZW1vdmVJdGVtKHN3aXRjaF9tZXNzYWdlX3N0b3JhZ2Vfa2V5KTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICghc2VyaWFsaXplZF9tZXNzYWdlIHx8ICFjdXJyZW50X21vZGVfaWQgfHwgdHlwZW9mIHN1Y2Nlc3NfbWVzc2FnZSAhPT0gJ3N0cmluZycgfHwgIXN1Y2Nlc3NfbWVzc2FnZSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRyeSB7XG5cdFx0XHRwZW5kaW5nX21lc3NhZ2UgPSBKU09OLnBhcnNlKHNlcmlhbGl6ZWRfbWVzc2FnZSk7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoXG5cdFx0XHQhcGVuZGluZ19tZXNzYWdlXG5cdFx0XHR8fCBwZW5kaW5nX21lc3NhZ2UubW9kZV9pZCAhPT0gY3VycmVudF9tb2RlX2lkXG5cdFx0XHR8fCB0eXBlb2YgcGVuZGluZ19tZXNzYWdlLmNyZWF0ZWRfYXQgIT09ICdudW1iZXInXG5cdFx0XHR8fCBwZW5kaW5nX21lc3NhZ2UuY3JlYXRlZF9hdCA+IERhdGUubm93KClcblx0XHRcdHx8IERhdGUubm93KCkgLSBwZW5kaW5nX21lc3NhZ2UuY3JlYXRlZF9hdCA+IHN3aXRjaF9tZXNzYWdlX21heF9hZ2Vcblx0XHQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRzaG93X3N3aXRjaF9zdWNjZXNzKHN1Y2Nlc3NfbWVzc2FnZSk7XG5cdH1cblxuXHQvKipcblx0ICogVG9nZ2xlIHRoZSBzaGFyZWQgc3dpdGNoaW5nIHN0YXRlIGFuZCBhbGwgZHJvcGRvd24gY2hvaWNlcy5cblx0ICpcblx0ICogQHBhcmFtIHtqUXVlcnl9ICRzZWxlY3RvciBNb2RlIHNlbGVjdG9yIGNvbnRhaW5lci5cblx0ICogQHBhcmFtIHtib29sZWFufSBpc19idXN5IFdoZXRoZXIgYSBtb2RlLXN3aXRjaCByZXF1ZXN0IGlzIGFjdGl2ZS5cblx0ICogQHJldHVybiB7dm9pZH1cblx0ICovXG5cdGZ1bmN0aW9uIHNldF9zd2l0Y2hpbmdfc3RhdGUoJHNlbGVjdG9yLCBpc19idXN5KSB7XG5cdFx0c3dpdGNoX2J1c3kgPSBpc19idXN5O1xuXHRcdCRzZWxlY3Rvci50b2dnbGVDbGFzcygnaXMtc3dpdGNoaW5nJywgaXNfYnVzeSk7XG5cblx0XHRpZiAoaXNfYnVzeSkge1xuXHRcdFx0JHNlbGVjdG9yLmF0dHIoJ2FyaWEtYnVzeScsICd0cnVlJyk7XG5cdFx0XHQkc2VsZWN0b3IuZmluZCgnLndwYmNfYm9va2luZ19tb2RlX29wdGlvbicpLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCAndHJ1ZScpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCRzZWxlY3Rvci5yZW1vdmVBdHRyKCdhcmlhLWJ1c3knKTtcblx0XHQkc2VsZWN0b3IuZmluZCgnLndwYmNfYm9va2luZ19tb2RlX29wdGlvbicpLnJlbW92ZUF0dHIoJ2FyaWEtZGlzYWJsZWQnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQZXJzaXN0IGEgc2VsZWN0ZWQgbW9kZSBhbmQgZm9sbG93IHRoZSBzZXJ2ZXItYXBwcm92ZWQgcmVkaXJlY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IENsaWNrIGV2ZW50IGZvciBhIHNlbGVjdG9yIG9wdGlvbi5cblx0ICogQHJldHVybiB7dm9pZH1cblx0ICovXG5cdGZ1bmN0aW9uIHN3aXRjaF9tb2RlKGV2ZW50KSB7XG5cdFx0dmFyICRvcHRpb24gPSAkKGV2ZW50LmN1cnJlbnRUYXJnZXQpO1xuXHRcdHZhciAkc2VsZWN0b3IgPSAkb3B0aW9uLmNsb3Nlc3QoJy53cGJjX2Jvb2tpbmdfbW9kZXNfc2VsZWN0b3InKTtcblx0XHR2YXIgbW9kZV9pZCA9IFN0cmluZygkb3B0aW9uLmRhdGEoJ21vZGUtaWQnKSB8fCAnJyk7XG5cblx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG5cdFx0aWYgKHN3aXRjaF9idXN5IHx8ICFtb2RlX2lkIHx8ICRvcHRpb24uaGFzQ2xhc3MoJ2lzLWN1cnJlbnQnKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHNldF9zd2l0Y2hpbmdfc3RhdGUoJHNlbGVjdG9yLCB0cnVlKTtcblx0XHRzaG93X2luZm8od3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLnNhdmluZyB8fCAnU3dpdGNoaW5nIEJvb2tpbmcgQ2FsZW5kYXIgbW9kZS4uLicpO1xuXG5cdFx0JC5hamF4KHtcblx0XHRcdHVybDogd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5hamF4X3VybCxcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcblx0XHRcdGRhdGE6IHtcblx0XHRcdFx0YWN0aW9uOiB3cGJjX2Jvb2tpbmdfbW9kZXNfY29uZmlnLmFjdGlvbixcblx0XHRcdFx0bm9uY2U6IHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcubm9uY2UsXG5cdFx0XHRcdG1vZGVfaWQ6IG1vZGVfaWQsXG5cdFx0XHRcdG9yaWdpbl91cmw6IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KCcjJylbMF0sXG5cdFx0XHRcdGZyYWdtZW50OiB3aW5kb3cubG9jYXRpb24uaGFzaCA/IHdpbmRvdy5sb2NhdGlvbi5oYXNoLnN1YnN0cmluZygxKSA6ICcnXG5cdFx0XHR9XG5cdFx0fSkuZG9uZShmdW5jdGlvbiAocmVzcG9uc2UpIHtcblx0XHRcdGlmIChcblx0XHRcdFx0IXJlc3BvbnNlXG5cdFx0XHRcdHx8IHJlc3BvbnNlLnN1Y2Nlc3MgIT09IHRydWVcblx0XHRcdFx0fHwgIXJlc3BvbnNlLmRhdGFcblx0XHRcdFx0fHwgdHlwZW9mIHJlc3BvbnNlLmRhdGEucmVkaXJlY3RfdXJsICE9PSAnc3RyaW5nJ1xuXHRcdFx0XHR8fCAhcmVzcG9uc2UuZGF0YS5yZWRpcmVjdF91cmwubGVuZ3RoXG5cdFx0XHQpIHtcblx0XHRcdFx0c2V0X3N3aXRjaGluZ19zdGF0ZSgkc2VsZWN0b3IsIGZhbHNlKTtcblx0XHRcdFx0c2hvd19lcnJvcihnZXRfZXJyb3JfbWVzc2FnZShyZXNwb25zZSksIDcwMDApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHNob3dfc3dpdGNoX3N1Y2Nlc3MocmVzcG9uc2UuZGF0YS5tZXNzYWdlIHx8IHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcuaTE4bi5zd2l0Y2hlZCk7XG5cdFx0XHRzdG9yZV9zd2l0Y2hfc3VjY2Vzcyhtb2RlX2lkKTtcblx0XHRcdHdpbmRvdy5sb2NhdGlvbi5hc3NpZ24ocmVzcG9uc2UuZGF0YS5yZWRpcmVjdF91cmwpO1xuXHRcdH0pLmZhaWwoZnVuY3Rpb24gKHhocikge1xuXHRcdFx0c2V0X3N3aXRjaGluZ19zdGF0ZSgkc2VsZWN0b3IsIGZhbHNlKTtcblx0XHRcdHNob3dfZXJyb3IoZ2V0X2Vycm9yX21lc3NhZ2UoeGhyLnJlc3BvbnNlSlNPTiksIDcwMDApO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJ1biBhIHNlcGFyYXRlbHkgY29uZmlybWVkLCBzdGF0ZS1jaGFuZ2luZyBRdWlja1N0YXJ0IG9wZXJhdGlvbi5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnQgQ2xpY2sgZXZlbnQgZm9yIGEgUXVpY2tTdGFydCBidXR0b24uXG5cdCAqIEByZXR1cm4ge3ZvaWR9XG5cdCAqL1xuXHRmdW5jdGlvbiBydW5fcXVpY2tzdGFydChldmVudCkge1xuXHRcdHZhciAkYnV0dG9uID0gJChldmVudC5jdXJyZW50VGFyZ2V0KTtcblx0XHR2YXIgJGFjdGlvbnMgPSAkYnV0dG9uLmNsb3Nlc3QoJy53cGJjX2Jvb2tpbmdfbW9kZXNfcXVpY2tzdGFydF9hY3Rpb25zJyk7XG5cdFx0dmFyIG1vZGVfaWQgPSBTdHJpbmcoJGJ1dHRvbi5kYXRhKCdtb2RlLWlkJykgfHwgJycpO1xuXHRcdHZhciBxdWlja3N0YXJ0ID0gd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5xdWlja3N0YXJ0IHx8IHt9O1xuXG5cdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuXHRcdGlmICghbW9kZV9pZCB8fCAhcXVpY2tzdGFydC5hY3Rpb24gfHwgIXF1aWNrc3RhcnQubm9uY2UgfHwgJGJ1dHRvbi5wcm9wKCdkaXNhYmxlZCcpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCF3aW5kb3cuY29uZmlybSh3cGJjX2Jvb2tpbmdfbW9kZXNfY29uZmlnLmkxOG4ucXVpY2tzdGFydF9jb25maXJtKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCRidXR0b24ucHJvcCgnZGlzYWJsZWQnLCB0cnVlKS5hdHRyKCdhcmlhLWJ1c3knLCAndHJ1ZScpO1xuXG5cdFx0JC5hamF4KHtcblx0XHRcdHVybDogd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5hamF4X3VybCxcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0ZGF0YVR5cGU6ICdqc29uJyxcblx0XHRcdGRhdGE6IHtcblx0XHRcdFx0YWN0aW9uOiBxdWlja3N0YXJ0LmFjdGlvbixcblx0XHRcdFx0bm9uY2U6IHF1aWNrc3RhcnQubm9uY2UsXG5cdFx0XHRcdG1vZGVfaWQ6IG1vZGVfaWRcblx0XHRcdH1cblx0XHR9KS5kb25lKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXHRcdFx0dmFyICR0ZXN0X3BhZ2U7XG5cblx0XHRcdGlmIChcblx0XHRcdFx0IXJlc3BvbnNlXG5cdFx0XHRcdHx8IHJlc3BvbnNlLnN1Y2Nlc3MgIT09IHRydWVcblx0XHRcdFx0fHwgIXJlc3BvbnNlLmRhdGFcblx0XHRcdFx0fHwgdHlwZW9mIHJlc3BvbnNlLmRhdGEudGVzdF91cmwgIT09ICdzdHJpbmcnXG5cdFx0XHRcdHx8ICFyZXNwb25zZS5kYXRhLnRlc3RfdXJsLmxlbmd0aFxuXHRcdFx0KSB7XG5cdFx0XHRcdHNob3dfZXJyb3IoZ2V0X2Vycm9yX21lc3NhZ2UocmVzcG9uc2UsIHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcuaTE4bi5xdWlja3N0YXJ0X2Vycm9yKSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0JHRlc3RfcGFnZSA9ICRhY3Rpb25zLmZpbmQoJy53cGJjX2Jvb2tpbmdfbW9kZXNfdGVzdF9wYWdlJyk7XG5cdFx0XHQkdGVzdF9wYWdlLmF0dHIoJ2hyZWYnLCByZXNwb25zZS5kYXRhLnRlc3RfdXJsKS5yZW1vdmVDbGFzcygnaXMtaGlkZGVuJykudHJpZ2dlcignZm9jdXMnKTtcblx0XHRcdHNob3dfc3VjY2VzcyhyZXNwb25zZS5kYXRhLm1lc3NhZ2UgfHwgd3BiY19ib29raW5nX21vZGVzX2NvbmZpZy5pMThuLnRlc3RfcGFnZSk7XG5cdFx0fSkuZmFpbChmdW5jdGlvbiAoeGhyKSB7XG5cdFx0XHRzaG93X2Vycm9yKGdldF9lcnJvcl9tZXNzYWdlKHhoci5yZXNwb25zZUpTT04sIHdwYmNfYm9va2luZ19tb2Rlc19jb25maWcuaTE4bi5xdWlja3N0YXJ0X2Vycm9yKSk7XG5cdFx0fSkuYWx3YXlzKGZ1bmN0aW9uICgpIHtcblx0XHRcdCRidXR0b24ucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSkucmVtb3ZlQXR0cignYXJpYS1idXN5Jyk7XG5cdFx0fSk7XG5cdH1cblxuXHQkKGRvY3VtZW50KS5vbignY2xpY2snLCAnLndwYmNfYm9va2luZ19tb2RlX29wdGlvbicsIHN3aXRjaF9tb2RlKTtcblx0JChkb2N1bWVudCkub24oJ2NsaWNrJywgJy53cGJjX2Jvb2tpbmdfbW9kZXNfcXVpY2tzdGFydF9idXR0b24nLCBydW5fcXVpY2tzdGFydCk7XG5cdCQoc2hvd19wZW5kaW5nX3N3aXRjaF9zdWNjZXNzKTtcbn0oalF1ZXJ5KSk7XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQyxXQUFVQSxDQUFDLEVBQUU7RUFDYixZQUFZOztFQUVaLElBQUlDLFdBQVcsR0FBRyxLQUFLO0VBQ3ZCLElBQUlDLDBCQUEwQixHQUFHLHNDQUFzQztFQUN2RSxJQUFJQyxzQkFBc0IsR0FBRyxNQUFNOztFQUVuQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNDLFNBQVNDLGlCQUFpQkEsQ0FBQ0MsUUFBUSxFQUFFQyxRQUFRLEVBQUU7SUFDOUMsSUFDQ0QsUUFBUSxJQUNMQSxRQUFRLENBQUNFLElBQUksSUFDYixPQUFPRixRQUFRLENBQUNFLElBQUksQ0FBQ0MsT0FBTyxLQUFLLFFBQVEsSUFDekNILFFBQVEsQ0FBQ0UsSUFBSSxDQUFDQyxPQUFPLENBQUNDLE1BQU0sRUFDOUI7TUFDRCxPQUFPSixRQUFRLENBQUNFLElBQUksQ0FBQ0MsT0FBTztJQUM3QjtJQUVBLE9BQU9GLFFBQVEsSUFBSUkseUJBQXlCLENBQUNDLElBQUksQ0FBQ0MsS0FBSztFQUN4RDs7RUFFQTtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNDLFNBQVNDLFVBQVVBLENBQUNMLE9BQU8sRUFBRU0sS0FBSyxFQUFFO0lBQ25DLElBQUksT0FBT0MsTUFBTSxDQUFDQyx1QkFBdUIsS0FBSyxVQUFVLEVBQUU7TUFDekRELE1BQU0sQ0FBQ0MsdUJBQXVCLENBQUNSLE9BQU8sRUFBRSxPQUFPLEVBQUVNLEtBQUssSUFBSSxLQUFLLEVBQUUsS0FBSyxDQUFDO01BQ3ZFO0lBQ0Q7SUFFQUMsTUFBTSxDQUFDRSxLQUFLLENBQUNULE9BQU8sQ0FBQztFQUN0Qjs7RUFFQTtBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDQyxTQUFTVSxZQUFZQSxDQUFDVixPQUFPLEVBQUU7SUFDOUIsSUFB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

```
