"use strict"; // @JS-THIS-01-EXCEPTION /** * jQuery helper extensions for the RSX framework * These extensions add utility methods to jQuery's prototype * Note: 'this' references in jQuery extensions refer to jQuery objects by design */ class Rsx_Jq_Helpers { /** * Initialize jQuery extensions when the framework core is defined * This method is called during framework initialization */ static _on_framework_core_define() { // Returns true if jquery selector matched an element $.fn.exists = function () { return this.length > 0; }; // Returns true if jquery element is visible $.fn.is_visible = function () { return this.is(':visible'); }; // Scrolls to the target element, only scrolls up. Todo: Create a version // of this that also scrolls only down, or both $.fn.scroll_up_to = function () { let speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (!this.exists()) { // console.warn("Could not find target element to scroll to"); return; } if (!this.is_in_dom()) { // console.warn("Target element for scroll is not on dom"); return; } let e_top = Math.round(this.offset().top); let s_top = $('body').scrollTop(); if (e_top < 0) { let target = s_top + e_top; $('html, body').animate({ scrollTop: target }, speed); } }; // $().is(":focus") - check if element has focus $.expr[':'].focus = function (elem) { return elem === document.activeElement && (elem.type || elem.href); }; // Save native click behavior before override $.fn._click_native = $.fn.click; // Override .click() to call preventDefault by default // This prevents accidental page navigation/form submission - the correct behavior 95% of the time $.fn.click = function (handler) { // If no handler provided, trigger click event (jQuery .click() with no args) if (typeof handler === 'undefined') { return this._click_native(); } // Attach click handler with automatic preventDefault return this.on('click', function (e) { // Save original preventDefault const original_preventDefault = e.preventDefault.bind(e); // Override preventDefault to show warning when called explicitly e.preventDefault = function () { console.warn('event.preventDefault() is called automatically by RSpade .click() handlers and can be removed.'); return original_preventDefault(); }; // Call preventDefault before handler original_preventDefault(); return handler.call(this, e); }); }; // Escape hatch: click handler without preventDefault for the 5% case $.fn.click_allow_default = function (handler) { if (typeof handler === 'undefined') { return this._click_native(); } return this._click_native(handler); }; // Returns true if the jquery element exists in and is attached to the DOM $.fn.is_in_dom = function () { let $element = this; let _ancestor = function (HTMLobj) { while (HTMLobj.parentElement) { HTMLobj = HTMLobj.parentElement; } return HTMLobj; }; return _ancestor($element[0]) === document.documentElement; }; // Returns true if the element is visible in the viewport $.fn.is_in_viewport = function () { let scrolltop = $(window).scrollTop() > 0 ? $(window).scrollTop() : $('body').scrollTop(); let $element = this; const top_of_element = $element.offset().top; const bottom_of_element = $element.offset().top + $element.outerHeight(); const bottom_of_screen = scrolltop + $(window).innerHeight(); const top_of_screen = scrolltop; if (bottom_of_screen > top_of_element && top_of_screen < bottom_of_element) { return true; } else { return false; } }; // Gets the tagname of a jquery element $.fn.tagname = function () { return this.prop('tagName').toLowerCase(); }; // Returns true if a href is not same domain $.fn.is_external = function () { const host = window.location.host; const link = $('', { href: this.attr('href') })[0].hostname; return link !== host; }; // HTML5 form validation wrappers $.fn.checkValidity = function () { if (this.length === 0) return false; return this[0].checkValidity(); }; $.fn.reportValidity = function () { if (this.length === 0) return false; return this[0].reportValidity(); }; $.fn.requestSubmit = function () { if (this.length === 0) return this; this[0].requestSubmit(); return this; }; // Find related components by searching up the ancestor tree // Like .closest() but searches within ancestors instead of matching them $.fn.closest_sibling = function (selector) { let $current = this; let $parent = $current.parent(); // Keep going up the tree until we hit body while ($parent.length > 0 && !$parent.is('body')) { // Search within this parent for the selector let $found = $parent.find(selector); if ($found.length > 0) { return $found; } // Move up one level $parent = $parent.parent(); } // If we reached body, search within body as well if ($parent.is('body')) { let $found = $parent.find(selector); if ($found.length > 0) { return $found; } } // Return empty jQuery object if nothing found return $(); }; // Override $.ajax to prevent direct AJAX calls to local server // Developers must use the Ajax endpoint pattern: await Controller.method(params) const native_ajax = $.ajax; $.ajax = function (url, options) { // Handle both $.ajax(url, options) and $.ajax(options) signatures let settings; if (typeof url === 'string') { settings = options || {}; settings.url = url; } else { settings = url || {}; } // Check if this is a local request (relative URL or same domain) const request_url = settings.url || ''; const is_relative = !request_url.match(/^https?:\/\//); const is_same_domain = request_url.startsWith(window.location.origin); const is_local_request = is_relative || is_same_domain; // Allow framework Ajax.call() to function if (settings.__local_integration === true) { return native_ajax.call(this, settings); } // Allow file upload endpoint - requires native $.ajax for FormData support const is_file_upload = request_url === '/_upload' || request_url.endsWith('/_upload'); if (is_file_upload) { return native_ajax.call(this, settings); } // Block local AJAX requests that don't use the Ajax endpoint pattern if (is_local_request) { // Try to parse controller and action from URL let controller_name = null; let action_name = null; const url_match = request_url.match(/\/_rsx_api\/([^\/]+)\/([^\/\?]+)/); if (url_match) { controller_name = url_match[1]; action_name = url_match[2]; } let error_message = 'AJAX requests to localhost via $.ajax() are prohibited.\n\n'; if (controller_name && action_name) { error_message += `Instead of:\n`; error_message += ` $.ajax({url: '${request_url}', ...})\n\n`; error_message += `Use:\n`; error_message += ` await ${controller_name}.${action_name}(parameters)\n\n`; } else { error_message += `Use the Ajax endpoint pattern:\n`; error_message += ` await Controller_Name.action_name(parameters)\n\n`; } error_message += `The controller method must have the #[Ajax_Endpoint] attribute.`; shouldnt_happen(error_message); } // Allow external requests (different domain) return native_ajax.call(this, settings); }; } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSc3hfSnFfSGVscGVycyIsIl9vbl9mcmFtZXdvcmtfY29yZV9kZWZpbmUiLCIkIiwiZm4iLCJleGlzdHMiLCJsZW5ndGgiLCJpc192aXNpYmxlIiwiaXMiLCJzY3JvbGxfdXBfdG8iLCJzcGVlZCIsImFyZ3VtZW50cyIsInVuZGVmaW5lZCIsImlzX2luX2RvbSIsImVfdG9wIiwiTWF0aCIsInJvdW5kIiwib2Zmc2V0IiwidG9wIiwic190b3AiLCJzY3JvbGxUb3AiLCJ0YXJnZXQiLCJhbmltYXRlIiwiZXhwciIsImZvY3VzIiwiZWxlbSIsImRvY3VtZW50IiwiYWN0aXZlRWxlbWVudCIsInR5cGUiLCJocmVmIiwiX2NsaWNrX25hdGl2ZSIsImNsaWNrIiwiaGFuZGxlciIsIm9uIiwiZSIsIm9yaWdpbmFsX3ByZXZlbnREZWZhdWx0IiwicHJldmVudERlZmF1bHQiLCJiaW5kIiwiY29uc29sZSIsIndhcm4iLCJjYWxsIiwiY2xpY2tfYWxsb3dfZGVmYXVsdCIsIiRlbGVtZW50IiwiX2FuY2VzdG9yIiwiSFRNTG9iaiIsInBhcmVudEVsZW1lbnQiLCJkb2N1bWVudEVsZW1lbnQiLCJpc19pbl92aWV3cG9ydCIsInNjcm9sbHRvcCIsIndpbmRvdyIsInRvcF9vZl9lbGVtZW50IiwiYm90dG9tX29mX2VsZW1lbnQiLCJvdXRlckhlaWdodCIsImJvdHRvbV9vZl9zY3JlZW4iLCJpbm5lckhlaWdodCIsInRvcF9vZl9zY3JlZW4iLCJ0YWduYW1lIiwicHJvcCIsInRvTG93ZXJDYXNlIiwiaXNfZXh0ZXJuYWwiLCJob3N0IiwibG9jYXRpb24iLCJsaW5rIiwiYXR0ciIsImhvc3RuYW1lIiwiY2hlY2tWYWxpZGl0eSIsInJlcG9ydFZhbGlkaXR5IiwicmVxdWVzdFN1Ym1pdCIsImNsb3Nlc3Rfc2libGluZyIsInNlbGVjdG9yIiwiJGN1cnJlbnQiLCIkcGFyZW50IiwicGFyZW50IiwiJGZvdW5kIiwiZmluZCIsIm5hdGl2ZV9hamF4IiwiYWpheCIsInVybCIsIm9wdGlvbnMiLCJzZXR0aW5ncyIsInJlcXVlc3RfdXJsIiwiaXNfcmVsYXRpdmUiLCJtYXRjaCIsImlzX3NhbWVfZG9tYWluIiwic3RhcnRzV2l0aCIsIm9yaWdpbiIsImlzX2xvY2FsX3JlcXVlc3QiLCJfX2xvY2FsX2ludGVncmF0aW9uIiwiaXNfZmlsZV91cGxvYWQiLCJlbmRzV2l0aCIsImNvbnRyb2xsZXJfbmFtZSIsImFjdGlvbl9uYW1lIiwidXJsX21hdGNoIiwiZXJyb3JfbWVzc2FnZSIsInNob3VsZG50X2hhcHBlbiJdLCJzb3VyY2VzIjpbImFwcC9SU3BhZGUvQ29yZS9Kcy9Sc3hfSnFfSGVscGVycy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBASlMtVEhJUy0wMS1FWENFUFRJT05cbi8qKlxuICogalF1ZXJ5IGhlbHBlciBleHRlbnNpb25zIGZvciB0aGUgUlNYIGZyYW1ld29ya1xuICogVGhlc2UgZXh0ZW5zaW9ucyBhZGQgdXRpbGl0eSBtZXRob2RzIHRvIGpRdWVyeSdzIHByb3RvdHlwZVxuICogTm90ZTogJ3RoaXMnIHJlZmVyZW5jZXMgaW4galF1ZXJ5IGV4dGVuc2lvbnMgcmVmZXIgdG8galF1ZXJ5IG9iamVjdHMgYnkgZGVzaWduXG4gKi9cbmNsYXNzIFJzeF9KcV9IZWxwZXJzIHtcbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIGpRdWVyeSBleHRlbnNpb25zIHdoZW4gdGhlIGZyYW1ld29yayBjb3JlIGlzIGRlZmluZWRcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgZHVyaW5nIGZyYW1ld29yayBpbml0aWFsaXphdGlvblxuICAgICAqL1xuICAgIHN0YXRpYyBfb25fZnJhbWV3b3JrX2NvcmVfZGVmaW5lKCkge1xuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYganF1ZXJ5IHNlbGVjdG9yIG1hdGNoZWQgYW4gZWxlbWVudFxuICAgICAgICAkLmZuLmV4aXN0cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxlbmd0aCA+IDA7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmV0dXJucyB0cnVlIGlmIGpxdWVyeSBlbGVtZW50IGlzIHZpc2libGVcbiAgICAgICAgJC5mbi5pc192aXNpYmxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXMoJzp2aXNpYmxlJyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2Nyb2xscyB0byB0aGUgdGFyZ2V0IGVsZW1lbnQsIG9ubHkgc2Nyb2xscyB1cC4gIFRvZG86IENyZWF0ZSBhIHZlcnNpb25cbiAgICAgICAgLy8gb2YgdGhpcyB0aGF0IGFsc28gc2Nyb2xscyBvbmx5IGRvd24sIG9yIGJvdGhcbiAgICAgICAgJC5mbi5zY3JvbGxfdXBfdG8gPSBmdW5jdGlvbiAoc3BlZWQgPSAwKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLndhcm4oXCJDb3VsZCBub3QgZmluZCB0YXJnZXQgZWxlbWVudCB0byBzY3JvbGwgdG9cIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNfaW5fZG9tKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLndhcm4oXCJUYXJnZXQgZWxlbWVudCBmb3Igc2Nyb2xsIGlzIG5vdCBvbiBkb21cIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgZV90b3AgPSBNYXRoLnJvdW5kKHRoaXMub2Zmc2V0KCkudG9wKTtcbiAgICAgICAgICAgIGxldCBzX3RvcCA9ICQoJ2JvZHknKS5zY3JvbGxUb3AoKTtcbiAgICAgICAgICAgIGlmIChlX3RvcCA8IDApIHtcbiAgICAgICAgICAgICAgICBsZXQgdGFyZ2V0ID0gc190b3AgKyBlX3RvcDtcbiAgICAgICAgICAgICAgICAkKCdodG1sLCBib2R5JykuYW5pbWF0ZShcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsVG9wOiB0YXJnZXQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHNwZWVkXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyAkKCkuaXMoXCI6Zm9jdXNcIikgLSBjaGVjayBpZiBlbGVtZW50IGhhcyBmb2N1c1xuICAgICAgICAkLmV4cHJbJzonXS5mb2N1cyA9IGZ1bmN0aW9uIChlbGVtKSB7XG4gICAgICAgICAgICByZXR1cm4gZWxlbSA9PT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAmJiAoZWxlbS50eXBlIHx8IGVsZW0uaHJlZik7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2F2ZSBuYXRpdmUgY2xpY2sgYmVoYXZpb3IgYmVmb3JlIG92ZXJyaWRlXG4gICAgICAgICQuZm4uX2NsaWNrX25hdGl2ZSA9ICQuZm4uY2xpY2s7XG5cbiAgICAgICAgLy8gT3ZlcnJpZGUgLmNsaWNrKCkgdG8gY2FsbCBwcmV2ZW50RGVmYXVsdCBieSBkZWZhdWx0XG4gICAgICAgIC8vIFRoaXMgcHJldmVudHMgYWNjaWRlbnRhbCBwYWdlIG5hdmlnYXRpb24vZm9ybSBzdWJtaXNzaW9uIC0gdGhlIGNvcnJlY3QgYmVoYXZpb3IgOTUlIG9mIHRoZSB0aW1lXG4gICAgICAgICQuZm4uY2xpY2sgPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICAgICAgLy8gSWYgbm8gaGFuZGxlciBwcm92aWRlZCwgdHJpZ2dlciBjbGljayBldmVudCAoalF1ZXJ5IC5jbGljaygpIHdpdGggbm8gYXJncylcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2xpY2tfbmF0aXZlKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEF0dGFjaCBjbGljayBoYW5kbGVyIHdpdGggYXV0b21hdGljIHByZXZlbnREZWZhdWx0XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIC8vIFNhdmUgb3JpZ2luYWwgcHJldmVudERlZmF1bHRcbiAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW5hbF9wcmV2ZW50RGVmYXVsdCA9IGUucHJldmVudERlZmF1bHQuYmluZChlKTtcblxuICAgICAgICAgICAgICAgIC8vIE92ZXJyaWRlIHByZXZlbnREZWZhdWx0IHRvIHNob3cgd2FybmluZyB3aGVuIGNhbGxlZCBleHBsaWNpdGx5XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ2V2ZW50LnByZXZlbnREZWZhdWx0KCkgaXMgY2FsbGVkIGF1dG9tYXRpY2FsbHkgYnkgUlNwYWRlIC5jbGljaygpIGhhbmRsZXJzIGFuZCBjYW4gYmUgcmVtb3ZlZC4nKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsX3ByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIC8vIENhbGwgcHJldmVudERlZmF1bHQgYmVmb3JlIGhhbmRsZXJcbiAgICAgICAgICAgICAgICBvcmlnaW5hbF9wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXIuY2FsbCh0aGlzLCBlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEVzY2FwZSBoYXRjaDogY2xpY2sgaGFuZGxlciB3aXRob3V0IHByZXZlbnREZWZhdWx0IGZvciB0aGUgNSUgY2FzZVxuICAgICAgICAkLmZuLmNsaWNrX2FsbG93X2RlZmF1bHQgPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9jbGlja19uYXRpdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jbGlja19uYXRpdmUoaGFuZGxlcik7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBqcXVlcnkgZWxlbWVudCBleGlzdHMgaW4gYW5kIGlzIGF0dGFjaGVkIHRvIHRoZSBET01cbiAgICAgICAgJC5mbi5pc19pbl9kb20gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgJGVsZW1lbnQgPSB0aGlzO1xuICAgICAgICAgICAgbGV0IF9hbmNlc3RvciA9IGZ1bmN0aW9uIChIVE1Mb2JqKSB7XG4gICAgICAgICAgICAgICAgd2hpbGUgKEhUTUxvYmoucGFyZW50RWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICBIVE1Mb2JqID0gSFRNTG9iai5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gSFRNTG9iajtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4gX2FuY2VzdG9yKCRlbGVtZW50WzBdKSA9PT0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZWxlbWVudCBpcyB2aXNpYmxlIGluIHRoZSB2aWV3cG9ydFxuICAgICAgICAkLmZuLmlzX2luX3ZpZXdwb3J0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IHNjcm9sbHRvcCA9ICQod2luZG93KS5zY3JvbGxUb3AoKSA+IDAgPyAkKHdpbmRvdykuc2Nyb2xsVG9wKCkgOiAkKCdib2R5Jykuc2Nyb2xsVG9wKCk7XG5cbiAgICAgICAgICAgIGxldCAkZWxlbWVudCA9IHRoaXM7XG5cbiAgICAgICAgICAgIGNvbnN0IHRvcF9vZl9lbGVtZW50ID0gJGVsZW1lbnQub2Zmc2V0KCkudG9wO1xuICAgICAgICAgICAgY29uc3QgYm90dG9tX29mX2VsZW1lbnQgPSAkZWxlbWVudC5vZmZzZXQoKS50b3AgKyAkZWxlbWVudC5vdXRlckhlaWdodCgpO1xuICAgICAgICAgICAgY29uc3QgYm90dG9tX29mX3NjcmVlbiA9IHNjcm9sbHRvcCArICQod2luZG93KS5pbm5lckhlaWdodCgpO1xuICAgICAgICAgICAgY29uc3QgdG9wX29mX3NjcmVlbiA9IHNjcm9sbHRvcDtcblxuICAgICAgICAgICAgaWYgKGJvdHRvbV9vZl9zY3JlZW4gPiB0b3Bfb2ZfZWxlbWVudCAmJiB0b3Bfb2Zfc2NyZWVuIDwgYm90dG9tX29mX2VsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEdldHMgdGhlIHRhZ25hbWUgb2YgYSBqcXVlcnkgZWxlbWVudFxuICAgICAgICAkLmZuLnRhZ25hbWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9wKCd0YWdOYW1lJykudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgYSBocmVmIGlzIG5vdCBzYW1lIGRvbWFpblxuICAgICAgICAkLmZuLmlzX2V4dGVybmFsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgaG9zdCA9IHdpbmRvdy5sb2NhdGlvbi5ob3N0O1xuICAgICAgICAgICAgY29uc3QgbGluayA9ICQoJzxhPicsIHtcbiAgICAgICAgICAgICAgICBocmVmOiB0aGlzLmF0dHIoJ2hyZWYnKSxcbiAgICAgICAgICAgIH0pWzBdLmhvc3RuYW1lO1xuICAgICAgICAgICAgcmV0dXJuIGxpbmsgIT09IGhvc3Q7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSFRNTDUgZm9ybSB2YWxpZGF0aW9uIHdyYXBwZXJzXG4gICAgICAgICQuZm4uY2hlY2tWYWxpZGl0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbMF0uY2hlY2tWYWxpZGl0eSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgICQuZm4ucmVwb3J0VmFsaWRpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzWzBdLnJlcG9ydFZhbGlkaXR5KCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgJC5mbi5yZXF1ZXN0U3VibWl0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIHRoaXNbMF0ucmVxdWVzdFN1Ym1pdCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gRmluZCByZWxhdGVkIGNvbXBvbmVudHMgYnkgc2VhcmNoaW5nIHVwIHRoZSBhbmNlc3RvciB0cmVlXG4gICAgICAgIC8vIExpa2UgLmNsb3Nlc3QoKSBidXQgc2VhcmNoZXMgd2l0aGluIGFuY2VzdG9ycyBpbnN0ZWFkIG9mIG1hdGNoaW5nIHRoZW1cbiAgICAgICAgJC5mbi5jbG9zZXN0X3NpYmxpbmcgPSBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcbiAgICAgICAgICAgIGxldCAkY3VycmVudCA9IHRoaXM7XG4gICAgICAgICAgICBsZXQgJHBhcmVudCA9ICRjdXJyZW50LnBhcmVudCgpO1xuXG4gICAgICAgICAgICAvLyBLZWVwIGdvaW5nIHVwIHRoZSB0cmVlIHVudGlsIHdlIGhpdCBib2R5XG4gICAgICAgICAgICB3aGlsZSAoJHBhcmVudC5sZW5ndGggPiAwICYmICEkcGFyZW50LmlzKCdib2R5JykpIHtcbiAgICAgICAgICAgICAgICAvLyBTZWFyY2ggd2l0aGluIHRoaXMgcGFyZW50IGZvciB0aGUgc2VsZWN0b3JcbiAgICAgICAgICAgICAgICBsZXQgJGZvdW5kID0gJHBhcmVudC5maW5kKHNlbGVjdG9yKTtcbiAgICAgICAgICAgICAgICBpZiAoJGZvdW5kLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmb3VuZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBNb3ZlIHVwIG9uZSBsZXZlbFxuICAgICAgICAgICAgICAgICRwYXJlbnQgPSAkcGFyZW50LnBhcmVudCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB3ZSByZWFjaGVkIGJvZHksIHNlYXJjaCB3aXRoaW4gYm9keSBhcyB3ZWxsXG4gICAgICAgICAgICBpZiAoJHBhcmVudC5pcygnYm9keScpKSB7XG4gICAgICAgICAgICAgICAgbGV0ICRmb3VuZCA9ICRwYXJlbnQuZmluZChzZWxlY3Rvcik7XG4gICAgICAgICAgICAgICAgaWYgKCRmb3VuZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAkZm91bmQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZXR1cm4gZW1wdHkgalF1ZXJ5IG9iamVjdCBpZiBub3RoaW5nIGZvdW5kXG4gICAgICAgICAgICByZXR1cm4gJCgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIE92ZXJyaWRlICQuYWpheCB0byBwcmV2ZW50IGRpcmVjdCBBSkFYIGNhbGxzIHRvIGxvY2FsIHNlcnZlclxuICAgICAgICAvLyBEZXZlbG9wZXJzIG11c3QgdXNlIHRoZSBBamF4IGVuZHBvaW50IHBhdHRlcm46IGF3YWl0IENvbnRyb2xsZXIubWV0aG9kKHBhcmFtcylcbiAgICAgICAgY29uc3QgbmF0aXZlX2FqYXggPSAkLmFqYXg7XG4gICAgICAgICQuYWpheCA9IGZ1bmN0aW9uICh1cmwsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBib3RoICQuYWpheCh1cmwsIG9wdGlvbnMpIGFuZCAkLmFqYXgob3B0aW9ucykgc2lnbmF0dXJlc1xuICAgICAgICAgICAgbGV0IHNldHRpbmdzO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB1cmwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgc2V0dGluZ3MgPSBvcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgICAgIHNldHRpbmdzLnVybCA9IHVybDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0dGluZ3MgPSB1cmwgfHwge307XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBsb2NhbCByZXF1ZXN0IChyZWxhdGl2ZSBVUkwgb3Igc2FtZSBkb21haW4pXG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0X3VybCA9IHNldHRpbmdzLnVybCB8fCAnJztcbiAgICAgICAgICAgIGNvbnN0IGlzX3JlbGF0aXZlID0gIXJlcXVlc3RfdXJsLm1hdGNoKC9eaHR0cHM/OlxcL1xcLy8pO1xuICAgICAgICAgICAgY29uc3QgaXNfc2FtZV9kb21haW4gPSByZXF1ZXN0X3VybC5zdGFydHNXaXRoKHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4pO1xuICAgICAgICAgICAgY29uc3QgaXNfbG9jYWxfcmVxdWVzdCA9IGlzX3JlbGF0aXZlIHx8IGlzX3NhbWVfZG9tYWluO1xuXG4gICAgICAgICAgICAvLyBBbGxvdyBmcmFtZXdvcmsgQWpheC5jYWxsKCkgdG8gZnVuY3Rpb25cbiAgICAgICAgICAgIGlmIChzZXR0aW5ncy5fX2xvY2FsX2ludGVncmF0aW9uID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZV9hamF4LmNhbGwodGhpcywgc2V0dGluZ3MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBbGxvdyBmaWxlIHVwbG9hZCBlbmRwb2ludCAtIHJlcXVpcmVzIG5hdGl2ZSAkLmFqYXggZm9yIEZvcm1EYXRhIHN1cHBvcnRcbiAgICAgICAgICAgIGNvbnN0IGlzX2ZpbGVfdXBsb2FkID0gcmVxdWVzdF91cmwgPT09ICcvX3VwbG9hZCcgfHwgcmVxdWVzdF91cmwuZW5kc1dpdGgoJy9fdXBsb2FkJyk7XG4gICAgICAgICAgICBpZiAoaXNfZmlsZV91cGxvYWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlX2FqYXguY2FsbCh0aGlzLCBzZXR0aW5ncyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEJsb2NrIGxvY2FsIEFKQVggcmVxdWVzdHMgdGhhdCBkb24ndCB1c2UgdGhlIEFqYXggZW5kcG9pbnQgcGF0dGVyblxuICAgICAgICAgICAgaWYgKGlzX2xvY2FsX3JlcXVlc3QpIHtcbiAgICAgICAgICAgICAgICAvLyBUcnkgdG8gcGFyc2UgY29udHJvbGxlciBhbmQgYWN0aW9uIGZyb20gVVJMXG4gICAgICAgICAgICAgICAgbGV0IGNvbnRyb2xsZXJfbmFtZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgbGV0IGFjdGlvbl9uYW1lID0gbnVsbDtcbiAgICAgICAgICAgICAgICBjb25zdCB1cmxfbWF0Y2ggPSByZXF1ZXN0X3VybC5tYXRjaCgvXFwvX3JzeF9hcGlcXC8oW15cXC9dKylcXC8oW15cXC9cXD9dKykvKTtcbiAgICAgICAgICAgICAgICBpZiAodXJsX21hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXJfbmFtZSA9IHVybF9tYXRjaFsxXTtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uX25hbWUgPSB1cmxfbWF0Y2hbMl07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IGVycm9yX21lc3NhZ2UgPSAnQUpBWCByZXF1ZXN0cyB0byBsb2NhbGhvc3QgdmlhICQuYWpheCgpIGFyZSBwcm9oaWJpdGVkLlxcblxcbic7XG5cbiAgICAgICAgICAgICAgICBpZiAoY29udHJvbGxlcl9uYW1lICYmIGFjdGlvbl9uYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2UgKz0gYEluc3RlYWQgb2Y6XFxuYDtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JfbWVzc2FnZSArPSBgICAkLmFqYXgoe3VybDogJyR7cmVxdWVzdF91cmx9JywgLi4ufSlcXG5cXG5gO1xuICAgICAgICAgICAgICAgICAgICBlcnJvcl9tZXNzYWdlICs9IGBVc2U6XFxuYDtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JfbWVzc2FnZSArPSBgICBhd2FpdCAke2NvbnRyb2xsZXJfbmFtZX0uJHthY3Rpb25fbmFtZX0ocGFyYW1ldGVycylcXG5cXG5gO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2UgKz0gYFVzZSB0aGUgQWpheCBlbmRwb2ludCBwYXR0ZXJuOlxcbmA7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2UgKz0gYCAgYXdhaXQgQ29udHJvbGxlcl9OYW1lLmFjdGlvbl9uYW1lKHBhcmFtZXRlcnMpXFxuXFxuYDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBlcnJvcl9tZXNzYWdlICs9IGBUaGUgY29udHJvbGxlciBtZXRob2QgbXVzdCBoYXZlIHRoZSAjW0FqYXhfRW5kcG9pbnRdIGF0dHJpYnV0ZS5gO1xuXG4gICAgICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKGVycm9yX21lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBbGxvdyBleHRlcm5hbCByZXF1ZXN0cyAoZGlmZmVyZW50IGRvbWFpbilcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVfYWpheC5jYWxsKHRoaXMsIHNldHRpbmdzKTtcbiAg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