"use strict"; /** * DataGrid Component (Phase 1) * * Due to the more dynamic nature of this component, we are handling load / render lifecycles * directly in this class rather than using the on_load lifecycle event * * **Features**: * - Ajax data fetching * - Sorting (click headers) * - Pagination (next/prev/page select) * - Row selection (checkboxes) * - CSV export (selected rows, current page) * - URL state synchronization * * **Usage**: * ```html * * ``` * * **Required Args**: * - `api` - Controller class name with datagrid_fetch() Ajax endpoint * * **Optional Args**: * - `per_page` - Default rows per page (default: 25) * - `sort` - Default sort column (default: first column) * - `order` - Default sort order (default: 'asc') */ class DataGrid_Abstract extends Component { // Initialize data before first render on_create() { let that = this; // Initialize data state immediately so template can render that.data.rows = []; that.data.loading = true; that.data.is_empty = false; that.data.loaded = false; that.data.total_pages = 0; } // Calls when datagrid first initialized async on_ready() { var _that$args$per_page, _that$args$sort, _that$args$order; let that = this; if (!that.args.data_source) { console.error('Datagrid ' + that.component_name() + ' requires args.data_source set to a Ajax_Endpoint object'); return; } // Store defaults for later comparison that.data.default_page = 1; that.data.default_per_page = (_that$args$per_page = that.args.per_page) !== null && _that$args$per_page !== void 0 ? _that$args$per_page : 15; that.data.default_sort = (_that$args$sort = that.args.sort) !== null && _that$args$sort !== void 0 ? _that$args$sort : null; that.data.default_order = (_that$args$order = that.args.order) !== null && _that$args$order !== void 0 ? _that$args$order : 'asc'; that.data.default_filter = ''; // Set configured values that.data.per_page = that.data.default_per_page; // Initialize state from URL hash if present, otherwise use defaults const hash_page = Rsx.get_page_state(that._cid + '_page'); const hash_sort = Rsx.get_page_state(that._cid + '_sort'); const hash_order = Rsx.get_page_state(that._cid + '_order'); const hash_filter = Rsx.get_page_state(that._cid + '_filter'); that.data.page = hash_page ? int(hash_page) : that.data.default_page; that.data.sort = hash_sort || that.data.default_sort; that.data.order = hash_order || that.data.default_order; that.data.filter = hash_filter || that.data.default_filter; that.register_render_callbacks(); that.register_filter_handlers(); // If hash had a filter value, populate the filter input if (that.data.filter) { const $filter = that.$sid('filter_input'); if ($filter && $filter.length > 0) { $filter.val(that.data.filter); } } // Measure row height and set fixed tbody height (all in one frame) await that.measure_and_set_fixed_height(); // Fetch the initial page (respects hash state) that.load_page(that.data.page); } // Update header only if sort/order changed update_header() { let that = this; // Track last rendered state if (!that._last_header_state) { that._last_header_state = {}; } const current = { sort: that.data.sort, order: that.data.order }; // Only render if values changed if (that._last_header_state.sort !== current.sort || that._last_header_state.order !== current.order) { that._last_header_state = current; that.id('datagrid_table_header').render(); } } // Update pagination only if values changed update_pagination() { let that = this; // Track last rendered state if (!that._last_pagination_state) { that._last_pagination_state = {}; } const current = { page: that.data.page, per_page: that.data.per_page, total: that.data.total, total_pages: that.data.total_pages }; // Only render if values changed if (that._last_pagination_state.page !== current.page || that._last_pagination_state.per_page !== current.per_page || that._last_pagination_state.total !== current.total || that._last_pagination_state.total_pages !== current.total_pages) { that._last_pagination_state = current; that.id('pagination_info').render(); that.id('pagination_controls').render(); } } // Load data for specified page and re-render data async load_page(page) { let that = this; // Set loading state that.data.loading = true; that.data.page = page; // Update UI with requested values (optimistic update) that.update_header(); that.update_pagination(); // Only render loading state if no data yet (initial load) if (that.data.rows.length === 0) { that.id('datagrid_table_body').render(); } const response = await Ajax.call(that.args.data_source, { page: page, per_page: that.data.per_page, sort: that.data.sort, order: that.data.order, filter: that.data.filter }); // Update data that.data.loading = false; that.data.loaded = true; that.data.rows = response.records; that.data.page = response.page; that.data.per_page = response.per_page; that.data.total = response.total; that.data.total_pages = response.total_pages; that.data.sort = response.sort; that.data.order = response.order; that.data.is_empty = response.records.length === 0; // Persist state to URL hash for bookmarking/sharing // Only set values that differ from defaults (null removes the key) const state = {}; state[that._cid + '_page'] = that.data.page !== that.data.default_page ? that.data.page : null; state[that._cid + '_sort'] = that.data.sort !== that.data.default_sort ? that.data.sort : null; state[that._cid + '_order'] = that.data.order !== that.data.default_order ? that.data.order : null; state[that._cid + '_filter'] = that.data.filter !== that.data.default_filter ? that.data.filter : null; Rsx.set_all_page_state(state); // Update UI with server response (only renders if changed) that.id('datagrid_table_body').render(); that.update_header(); that.update_pagination(); // Scroll to top of datagrid if it's not currently visible that.scroll_to_top_if_needed(); } // The callbacks in this function fire after each targeted component re-renders register_render_callbacks() { let that = this; // Attach row click handler - re-runs every time datagrid_table_body renders that.id('datagrid_table_body').on('render', function () { console.log('DGTB_R'); // Step 1: Wrap cells in data-href rows with anchor tags $(this).find('tr[data-href]').each(function () { let $row = $(this); let href = $row.attr('data-href'); $row.find('td').each(function () { // let $col = $(this); // // Skip if cell already contains interactive elements // if ($col.find('a, button, input, select, textarea').length > 0) { // return; // } // // Wrap entire cell contents in an anchor (preserve DOM nodes for component lifecycle) // let $anchor = $('', { // href: href, // class: 'datagrid-row-link' // }); // // Move existing child nodes into anchor (preserves components and their state) // $col.contents().appendTo($anchor); // // Add anchor to cell // $col.append($anchor); }); }); // Step 2: Find all cells with single anchor as only child and apply full-width styling $(this).find('td').each(function () { let $col = $(this); let $children = $col.children(); // Check if cell contains exactly one direct child that is an anchor if ($children.length === 1 && $children.first().is('a')) { // Add class to transfer padding from cell to anchor $col.addClass('has-full-link'); } // Check if cell contains only text (no child elements) else if ($children.length === 0) { // Add class to apply vertical padding to text-only cells $col.addClass('has-only-text'); } }); }); // Attach sortable header click handler - re-runs every time datagrid_table_header renders that.id('datagrid_table_header').on('render', function () { // Transform th[data-sortby] elements by wrapping contents in clickable link $(this).find('th[data-sortby]').each(function () { let $th = $(this); let sortby = $th.attr('data-sortby'); // TODO: Find out why this on('render') callback is being called twice/on already-processed HTML // This unwrap logic shouldn't be necessary - template should render fresh each time // For now, unwrap already-wrapped content to prevent double-wrapping let $existing_link = $th.find('a.sortable-header'); let contents; if ($existing_link.length > 0) { // Unwrap - get the text content without the wrapper and arrows contents = $existing_link.clone().find('i.bi').remove().end().html(); } else { contents = $th.html(); } // Build the arrow icon HTML if this column is currently sorted let arrow = ''; if (that.data.sort === sortby) { arrow = that.data.order === 'desc' ? '' : ''; } // Replace contents with wrapped link (fresh wrapper every time) $th.html(`${contents}${arrow}`); }); // Attach click handlers to the sortable links we just created $(this).find('a.sortable-header[data-sortby]').on('click', function (e) { e.preventDefault(); const sortby = $(this).attr('data-sortby'); that.sort_by(sortby); }); }); // Attach pagination click handler - re-runs every time pagination_controls renders that.id('pagination_controls').on('render', function () { $(this).find('.page-link').on('click', function (e) { e.preventDefault(); const $link = $(this); const page = int($link.attr('data-page')); // Ignore disabled/ellipsis clicks if (!page || isNaN(page) || $link.parent().hasClass('disabled')) { return; } // Load the requested page that.load_page(page); }); }); // Attach clear filter button handler - re-runs every time datagrid_table_body renders that.id('datagrid_table_body').on('render', function () { const $clear_btn = that.$sid('clear_filter_btn'); if ($clear_btn && $clear_btn.length > 0) { $clear_btn.on('click', function (e) { e.preventDefault(); that.clear_filter(); }); } }); } // Sort by specified column, toggling order if already sorted by that column sort_by(column) { let that = this; // Toggle order if clicking same column, otherwise default to asc if (that.data.sort === column) { that.data.order = that.data.order === 'asc' ? 'desc' : 'asc'; } else { that.data.sort = column; that.data.order = 'asc'; } // Reload current page with new sort that.id('datagrid_table_header').render(); that.load_page(that.data.page); } // Register filter input handlers register_filter_handlers() { let that = this; // Find filter input by common identifiers let $filter = that.$sid('filter_input'); if (!$filter || $filter.length === 0) { $filter = that.$.find('input[type="search"], input[type="text"].filter-input'); } if ($filter && $filter.length > 0) { $filter.on('input keyup', function () { const filter_value = $(this).val(); that.filter_changed(filter_value); }); } } filter_changed(filter) { let that = this; that.data.filter = filter; that.load_page(1); } // Scroll to datagrid top if the top edge is not currently visible in viewport scroll_to_top_if_needed() { let that = this; const $datagrid = that.$; const datagridTop = $datagrid.offset().top; const scrollTop = $(window).scrollTop(); // If datagrid top is above the current viewport, scroll to show it if (datagridTop < scrollTop) { // If datagrid is within 300px of page top, scroll to 0 if (datagridTop <= 300) { window.scrollTo({ top: 0, behavior: 'instant' }); } else { // Scroll to 20px above datagrid window.scrollTo({ top: datagridTop - 20, behavior: 'instant' }); } } } // Measure actual row height and set fixed tbody min-height // All happens in one animation frame so user doesn't see it async measure_and_set_fixed_height() { let that = this; // Wait for next animation frame to ensure DOM is ready await sleep(0); const $tbody = that.id('datagrid_table_body').$; // Temporarily render a single measurement row const $measurement_row = $('').css('visibility', 'hidden').html('Measuring...'); $tbody.append($measurement_row); // Measure the row height const row_height = $measurement_row.outerHeight(); // Remove measurement row $measurement_row.remove(); // Calculate and set min-height based on per_page const min_height = row_height * that.data.per_page; $tbody.css('min-height', min_height + 'px'); // Store for future reference that.data.row_height = row_height; that.data.tbody_min_height = min_height; } // Clear filter and reset to page 1 clear_filter() { let that = this; that.data.filter = ''; // Clear the filter input const $filter = that.$sid('filter_input'); if ($filter && $filter.length > 0) { $filter.val(''); } // Reload from page 1 that.load_page(1); } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJEYXRhR3JpZF9BYnN0cmFjdCIsIkpxaHRtbF9Db21wb25lbnQiLCJvbl9jcmVhdGUiLCJ0aGF0IiwiZGF0YSIsInJvd3MiLCJsb2FkaW5nIiwiaXNfZW1wdHkiLCJsb2FkZWQiLCJ0b3RhbF9wYWdlcyIsIm9uX3JlYWR5IiwiX3RoYXQkYXJncyRwZXJfcGFnZSIsIl90aGF0JGFyZ3Mkc29ydCIsIl90aGF0JGFyZ3Mkb3JkZXIiLCJhcmdzIiwiZGF0YV9zb3VyY2UiLCJjb25zb2xlIiwiZXJyb3IiLCJjb21wb25lbnRfbmFtZSIsImRlZmF1bHRfcGFnZSIsImRlZmF1bHRfcGVyX3BhZ2UiLCJwZXJfcGFnZSIsImRlZmF1bHRfc29ydCIsInNvcnQiLCJkZWZhdWx0X29yZGVyIiwib3JkZXIiLCJkZWZhdWx0X2ZpbHRlciIsImhhc2hfcGFnZSIsIlJzeCIsImdldF9wYWdlX3N0YXRlIiwiX2NpZCIsImhhc2hfc29ydCIsImhhc2hfb3JkZXIiLCJoYXNoX2ZpbHRlciIsInBhZ2UiLCJpbnQiLCJmaWx0ZXIiLCJyZWdpc3Rlcl9yZW5kZXJfY2FsbGJhY2tzIiwicmVnaXN0ZXJfZmlsdGVyX2hhbmRsZXJzIiwiJGZpbHRlciIsIiRpZCIsImxlbmd0aCIsInZhbCIsIm1lYXN1cmVfYW5kX3NldF9maXhlZF9oZWlnaHQiLCJsb2FkX3BhZ2UiLCJ1cGRhdGVfaGVhZGVyIiwiX2xhc3RfaGVhZGVyX3N0YXRlIiwiY3VycmVudCIsImlkIiwicmVuZGVyIiwidXBkYXRlX3BhZ2luYXRpb24iLCJfbGFzdF9wYWdpbmF0aW9uX3N0YXRlIiwidG90YWwiLCJyZXNwb25zZSIsIkFqYXgiLCJjYWxsIiwicmVjb3JkcyIsInN0YXRlIiwic2V0X2FsbF9wYWdlX3N0YXRlIiwic2Nyb2xsX3RvX3RvcF9pZl9uZWVkZWQiLCJvbiIsImxvZyIsIiQiLCJmaW5kIiwiZWFjaCIsIiRyb3ciLCJocmVmIiwiYXR0ciIsIiRjb2wiLCIkY2hpbGRyZW4iLCJjaGlsZHJlbiIsImZpcnN0IiwiaXMiLCJhZGRDbGFzcyIsIiR0aCIsInNvcnRieSIsIiRleGlzdGluZ19saW5rIiwiY29udGVudHMiLCJjbG9uZSIsInJlbW92ZSIsImVuZCIsImh0bWwiLCJhcnJvdyIsImUiLCJwcmV2ZW50RGVmYXVsdCIsInNvcnRfYnkiLCIkbGluayIsImlzTmFOIiwicGFyZW50IiwiaGFzQ2xhc3MiLCIkY2xlYXJfYnRuIiwiY2xlYXJfZmlsdGVyIiwiY29sdW1uIiwiZmlsdGVyX3ZhbHVlIiwiZmlsdGVyX2NoYW5nZWQiLCIkZGF0YWdyaWQiLCJkYXRhZ3JpZFRvcCIsIm9mZnNldCIsInRvcCIsInNjcm9sbFRvcCIsIndpbmRvdyIsInNjcm9sbFRvIiwiYmVoYXZpb3IiLCJzbGVlcCIsIiR0Ym9keSIsIiRtZWFzdXJlbWVudF9yb3ciLCJjc3MiLCJhcHBlbmQiLCJyb3dfaGVpZ2h0Iiwib3V0ZXJIZWlnaHQiLCJtaW5faGVpZ2h0IiwidGJvZHlfbWluX2hlaWdodCJdLCJzb3VyY2VzIjpbInJzeC90aGVtZS9jb21wb25lbnRzL2RhdGFncmlkL2RhdGFncmlkX2Fic3RyYWN0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRGF0YUdyaWQgQ29tcG9uZW50IChQaGFzZSAxKVxuICpcbiAqIER1ZSB0byB0aGUgbW9yZSBkeW5hbWljIG5hdHVyZSBvZiB0aGlzIGNvbXBvbmVudCwgd2UgYXJlIGhhbmRsaW5nIGxvYWQgLyByZW5kZXIgbGlmZWN5Y2xlc1xuICogZGlyZWN0bHkgaW4gdGhpcyBjbGFzcyByYXRoZXIgdGhhbiB1c2luZyB0aGUgb25fbG9hZCBsaWZlY3ljbGUgZXZlbnRcbiAqXG4gKiAqKkZlYXR1cmVzKio6XG4gKiAtIEFqYXggZGF0YSBmZXRjaGluZ1xuICogLSBTb3J0aW5nIChjbGljayBoZWFkZXJzKVxuICogLSBQYWdpbmF0aW9uIChuZXh0L3ByZXYvcGFnZSBzZWxlY3QpXG4gKiAtIFJvdyBzZWxlY3Rpb24gKGNoZWNrYm94ZXMpXG4gKiAtIENTViBleHBvcnQgKHNlbGVjdGVkIHJvd3MsIGN1cnJlbnQgcGFnZSlcbiAqIC0gVVJMIHN0YXRlIHN5bmNocm9uaXphdGlvblxuICpcbiAqICoqVXNhZ2UqKjpcbiAqIGBgYGh0bWxcbiAqIDxDb250YWN0c19EYXRhR3JpZCAkYXBpPVwiRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlclwiIC8+XG4gKiBgYGBcbiAqXG4gKiAqKlJlcXVpcmVkIEFyZ3MqKjpcbiAqIC0gYGFwaWAgLSBDb250cm9sbGVyIGNsYXNzIG5hbWUgd2l0aCBkYXRhZ3JpZF9mZXRjaCgpIEFqYXggZW5kcG9pbnRcbiAqXG4gKiAqKk9wdGlvbmFsIEFyZ3MqKjpcbiAqIC0gYHBlcl9wYWdlYCAtIERlZmF1bHQgcm93cyBwZXIgcGFnZSAoZGVmYXVsdDogMjUpXG4gKiAtIGBzb3J0YCAtIERlZmF1bHQgc29ydCBjb2x1bW4gKGRlZmF1bHQ6IGZpcnN0IGNvbHVtbilcbiAqIC0gYG9yZGVyYCAtIERlZmF1bHQgc29ydCBvcmRlciAoZGVmYXVsdDogJ2FzYycpXG4gKi9cbmNsYXNzIERhdGFHcmlkX0Fic3RyYWN0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gSW5pdGlhbGl6ZSBkYXRhIGJlZm9yZSBmaXJzdCByZW5kZXJcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBJbml0aWFsaXplIGRhdGEgc3RhdGUgaW1tZWRpYXRlbHkgc28gdGVtcGxhdGUgY2FuIHJlbmRlclxuICAgICAgICB0aGF0LmRhdGEucm93cyA9IFtdO1xuICAgICAgICB0aGF0LmRhdGEubG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoYXQuZGF0YS5pc19lbXB0eSA9IGZhbHNlO1xuICAgICAgICB0aGF0LmRhdGEubG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoYXQuZGF0YS50b3RhbF9wYWdlcyA9IDA7XG4gICAgfVxuXG4gICAgLy8gQ2FsbHMgd2hlbiBkYXRhZ3JpZCBmaXJzdCBpbml0aWFsaXplZFxuICAgIGFzeW5jIG9uX3JlYWR5KCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgaWYgKCF0aGF0LmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0RhdGFncmlkICcgKyB0aGF0LmNvbXBvbmVudF9uYW1lKCkgKyAnIHJlcXVpcmVzIGFyZ3MuZGF0YV9zb3VyY2Ugc2V0IHRvIGEgQWpheF9FbmRwb2ludCBvYmplY3QnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0b3JlIGRlZmF1bHRzIGZvciBsYXRlciBjb21wYXJpc29uXG4gICAgICAgIHRoYXQuZGF0YS5kZWZhdWx0X3BhZ2UgPSAxO1xuICAgICAgICB0aGF0LmRhdGEuZGVmYXVsdF9wZXJfcGFnZSA9IHRoYXQuYXJncy5wZXJfcGFnZSA/PyAxNTtcbiAgICAgICAgdGhhdC5kYXRhLmRlZmF1bHRfc29ydCA9IHRoYXQuYXJncy5zb3J0ID8/IG51bGw7XG4gICAgICAgIHRoYXQuZGF0YS5kZWZhdWx0X29yZGVyID0gdGhhdC5hcmdzLm9yZGVyID8/ICdhc2MnO1xuICAgICAgICB0aGF0LmRhdGEuZGVmYXVsdF9maWx0ZXIgPSAnJztcblxuICAgICAgICAvLyBTZXQgY29uZmlndXJlZCB2YWx1ZXNcbiAgICAgICAgdGhhdC5kYXRhLnBlcl9wYWdlID0gdGhhdC5kYXRhLmRlZmF1bHRfcGVyX3BhZ2U7XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBzdGF0ZSBmcm9tIFVSTCBoYXNoIGlmIHByZXNlbnQsIG90aGVyd2lzZSB1c2UgZGVmYXVsdHNcbiAgICAgICAgY29uc3QgaGFzaF9wYWdlID0gUnN4LmdldF9wYWdlX3N0YXRlKHRoYXQuX2NpZCArICdfcGFnZScpO1xuICAgICAgICBjb25zdCBoYXNoX3NvcnQgPSBSc3guZ2V0X3BhZ2Vfc3RhdGUodGhhdC5fY2lkICsgJ19zb3J0Jyk7XG4gICAgICAgIGNvbnN0IGhhc2hfb3JkZXIgPSBSc3guZ2V0X3BhZ2Vfc3RhdGUodGhhdC5fY2lkICsgJ19vcmRlcicpO1xuICAgICAgICBjb25zdCBoYXNoX2ZpbHRlciA9IFJzeC5nZXRfcGFnZV9zdGF0ZSh0aGF0Ll9jaWQgKyAnX2ZpbHRlcicpO1xuXG4gICAgICAgIHRoYXQuZGF0YS5wYWdlID0gaGFzaF9wYWdlID8gaW50KGhhc2hfcGFnZSkgOiB0aGF0LmRhdGEuZGVmYXVsdF9wYWdlO1xuICAgICAgICB0aGF0LmRhdGEuc29ydCA9IGhhc2hfc29ydCB8fCB0aGF0LmRhdGEuZGVmYXVsdF9zb3J0O1xuICAgICAgICB0aGF0LmRhdGEub3JkZXIgPSBoYXNoX29yZGVyIHx8IHRoYXQuZGF0YS5kZWZhdWx0X29yZGVyO1xuICAgICAgICB0aGF0LmRhdGEuZmlsdGVyID0gaGFzaF9maWx0ZXIgfHwgdGhhdC5kYXRhLmRlZmF1bHRfZmlsdGVyO1xuXG4gICAgICAgIHRoYXQucmVnaXN0ZXJfcmVuZGVyX2NhbGxiYWNrcygpO1xuICAgICAgICB0aGF0LnJlZ2lzdGVyX2ZpbHRlcl9oYW5kbGVycygpO1xuXG4gICAgICAgIC8vIElmIGhhc2ggaGFkIGEgZmlsdGVyIHZhbHVlLCBwb3B1bGF0ZSB0aGUgZmlsdGVyIGlucHV0XG4gICAgICAgIGlmICh0aGF0LmRhdGEuZmlsdGVyKSB7XG4gICAgICAgICAgICBjb25zdCAkZmlsdGVyID0gdGhhdC4kaWQoJ2ZpbHRlcl9pbnB1dCcpO1xuICAgICAgICAgICAgaWYgKCRmaWx0ZXIgJiYgJGZpbHRlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgJGZpbHRlci52YWwodGhhdC5kYXRhLmZpbHRlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNZWFzdXJlIHJvdyBoZWlnaHQgYW5kIHNldCBmaXhlZCB0Ym9keSBoZWlnaHQgKGFsbCBpbiBvbmUgZnJhbWUpXG4gICAgICAgIGF3YWl0IHRoYXQubWVhc3VyZV9hbmRfc2V0X2ZpeGVkX2hlaWdodCgpO1xuXG4gICAgICAgIC8vIEZldGNoIHRoZSBpbml0aWFsIHBhZ2UgKHJlc3BlY3RzIGhhc2ggc3RhdGUpXG4gICAgICAgIHRoYXQubG9hZF9wYWdlKHRoYXQuZGF0YS5wYWdlKTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgaGVhZGVyIG9ubHkgaWYgc29ydC9vcmRlciBjaGFuZ2VkXG4gICAgdXBkYXRlX2hlYWRlcigpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFRyYWNrIGxhc3QgcmVuZGVyZWQgc3RhdGVcbiAgICAgICAgaWYgKCF0aGF0Ll9sYXN0X2hlYWRlcl9zdGF0ZSkge1xuICAgICAgICAgICAgdGhhdC5fbGFzdF9oZWFkZXJfc3RhdGUgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB7XG4gICAgICAgICAgICBzb3J0OiB0aGF0LmRhdGEuc29ydCxcbiAgICAgICAgICAgIG9yZGVyOiB0aGF0LmRhdGEub3JkZXIsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gT25seSByZW5kZXIgaWYgdmFsdWVzIGNoYW5nZWRcbiAgICAgICAgaWYgKHRoYXQuX2xhc3RfaGVhZGVyX3N0YXRlLnNvcnQgIT09IGN1cnJlbnQuc29ydCB8fCB0aGF0Ll9sYXN0X2hlYWRlcl9zdGF0ZS5vcmRlciAhPT0gY3VycmVudC5vcmRlcikge1xuICAgICAgICAgICAgdGhhdC5fbGFzdF9oZWFkZXJfc3RhdGUgPSBjdXJyZW50O1xuICAgICAgICAgICAgdGhhdC5pZCgnZGF0YWdyaWRfdGFibGVfaGVhZGVyJykucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgcGFnaW5hdGlvbiBvbmx5IGlmIHZhbHVlcyBjaGFuZ2VkXG4gICAgdXBkYXRlX3BhZ2luYXRpb24oKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBUcmFjayBsYXN0IHJlbmRlcmVkIHN0YXRlXG4gICAgICAgIGlmICghdGhhdC5fbGFzdF9wYWdpbmF0aW9uX3N0YXRlKSB7XG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB7XG4gICAgICAgICAgICBwYWdlOiB0aGF0LmRhdGEucGFnZSxcbiAgICAgICAgICAgIHBlcl9wYWdlOiB0aGF0LmRhdGEucGVyX3BhZ2UsXG4gICAgICAgICAgICB0b3RhbDogdGhhdC5kYXRhLnRvdGFsLFxuICAgICAgICAgICAgdG90YWxfcGFnZXM6IHRoYXQuZGF0YS50b3RhbF9wYWdlcyxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBPbmx5IHJlbmRlciBpZiB2YWx1ZXMgY2hhbmdlZFxuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUucGFnZSAhPT0gY3VycmVudC5wYWdlIHx8XG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUucGVyX3BhZ2UgIT09IGN1cnJlbnQucGVyX3BhZ2UgfHxcbiAgICAgICAgICAgIHRoYXQuX2xhc3RfcGFnaW5hdGlvbl9zdGF0ZS50b3RhbCAhPT0gY3VycmVudC50b3RhbCB8fFxuICAgICAgICAgICAgdGhhdC5fbGFzdF9wYWdpbmF0aW9uX3N0YXRlLnRvdGFsX3BhZ2VzICE9PSBjdXJyZW50LnRvdGFsX3BhZ2VzXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhhdC5fbGFzdF9wYWdpbmF0aW9uX3N0YXRlID0gY3VycmVudDtcbiAgICAgICAgICAgIHRoYXQuaWQoJ3BhZ2luYXRpb25faW5mbycpLnJlbmRlcigpO1xuICAgICAgICAgICAgdGhhdC5pZCgncGFnaW5hdGlvbl9jb250cm9scycpLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTG9hZCBkYXRhIGZvciBzcGVjaWZpZWQgcGFnZSBhbmQgcmUtcmVuZGVyIGRhdGFcbiAgICBhc3luYyBsb2FkX3BhZ2UocGFnZSkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gU2V0IGxvYWRpbmcgc3RhdGVcbiAgICAgICAgdGhhdC5kYXRhLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGF0LmRhdGEucGFnZSA9IHBhZ2U7XG5cbiAgICAgICAgLy8gVXBkYXRlIFVJIHdpdGggcmVxdWVzdGVkIHZhbHVlcyAob3B0aW1pc3RpYyB1cGRhdGUpXG4gICAgICAgIHRoYXQudXBkYXRlX2hlYWRlcigpO1xuICAgICAgICB0aGF0LnVwZGF0ZV9wYWdpbmF0aW9uKCk7XG5cbiAgICAgICAgLy8gT25seSByZW5kZXIgbG9hZGluZyBzdGF0ZSBpZiBubyBkYXRhIHlldCAoaW5pdGlhbCBsb2FkKVxuICAgICAgICBpZiAodGhhdC5kYXRhLnJvd3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9ib2R5JykucmVuZGVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IEFqYXguY2FsbCh0aGF0LmFyZ3MuZGF0YV9zb3VyY2UsIHtcbiAgICAgICAgICAgIHBhZ2U6IHBhZ2UsXG4gICAgICAgICAgICBwZXJfcGFnZTogdGhhdC5kYXRhLnBlcl9wYWdlLFxuICAgICAgICAgICAgc29ydDogdGhhdC5kYXRhLnNvcnQsXG4gICAgICAgICAgICBvcmRlcjogdGhhdC5kYXRhLm9yZGVyLFxuICAgICAgICAgICAgZmlsdGVyOiB0aGF0LmRhdGEuZmlsdGVyLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBVcGRhdGUgZGF0YVxuICAgICAgICB0aGF0LmRhdGEubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGF0LmRhdGEubG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgdGhhdC5kYXRhLnJvd3MgPSByZXNwb25zZS5yZWNvcmRzO1xuICAgICAgICB0aGF0LmRhdGEucGFnZSA9IHJlc3BvbnNlLnBhZ2U7XG4gICAgICAgIHRoYXQuZGF0YS5wZXJfcGFnZSA9IHJlc3BvbnNlLnBlcl9wYWdlO1xuICAgICAgICB0aGF0LmRhdGEudG90YWwgPSByZXNwb25zZS50b3RhbDtcbiAgICAgICAgdGhhdC5kYXRhLnRvdGFsX3BhZ2VzID0gcmVzcG9uc2UudG90YWxfcGFnZXM7XG4gICAgICAgIHRoYXQuZGF0YS5zb3J0ID0gcmVzcG9uc2Uuc29ydDtcbiAgICAgICAgdGhhdC5kYXRhLm9yZGVyID0gcmVzcG9uc2Uub3JkZXI7XG4gICAgICAgIHRoYXQuZGF0YS5pc19lbXB0eSA9IHJlc3BvbnNlLnJlY29yZHMubGVuZ3RoID09PSAwO1xuXG4gICAgICAgIC8vIFBlcnNpc3Qgc3RhdGUgdG8gVVJMIGhhc2ggZm9yIGJvb2ttYXJraW5nL3NoYXJpbmdcbiAgICAgICAgLy8gT25seSBzZXQgdmFsdWVzIHRoYXQgZGlmZmVyIGZyb20gZGVmYXVsdHMgKG51bGwgcmVtb3ZlcyB0aGUga2V5KVxuICAgICAgICBjb25zdCBzdGF0ZSA9IHt9O1xuICAgICAgICBzdGF0ZVt0aGF0Ll9jaWQgKyAnX3BhZ2UnXSA9IHRoYXQuZGF0YS5wYWdlICE9PSB0aGF0LmRhdGEuZGVmYXVsdF9wYWdlID8gdGhhdC5kYXRhLnBhZ2UgOiBudWxsO1xuICAgICAgICBzdGF0ZVt0aGF0Ll9jaWQgKyAnX3NvcnQnXSA9IHRoYXQuZGF0YS5zb3J0ICE9PSB0aGF0LmRhdGEuZGVmYXVsdF9zb3J0ID8gdGhhdC5kYXRhLnNvcnQgOiBudWxsO1xuICAgICAgICBzdGF0ZVt0aGF0Ll9jaWQgKyAnX29yZGVyJ10gPSB0aGF0LmRhdGEub3JkZXIgIT09IHRoYXQuZGF0YS5kZWZhdWx0X29yZGVyID8gdGhhdC5kYXRhLm9yZGVyIDogbnVsbDtcbiAgICAgICAgc3RhdGVbdGhhdC5fY2lkICsgJ19maWx0ZXInXSA9IHRoYXQuZGF0YS5maWx0ZXIgIT09IHRoYXQuZGF0YS5kZWZhdWx0X2ZpbHRlciA/IHRoYXQuZGF0YS5maWx0ZXIgOiBudWxsO1xuXG4gICAgICAgIFJzeC5zZXRfYWxsX3BhZ2Vfc3RhdGUoc3RhdGUpO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBVSSB3aXRoIHNlcnZlciByZXNwb25zZSAob25seSByZW5kZXJzIGlmIGNoYW5nZWQpXG4gICAgICAgIHRoYXQuaWQoJ2RhdGFncmlkX3RhYmxlX2JvZHknKS5yZW5kZXIoKTtcbiAgICAgICAgdGhhdC51cGRhdGVfaGVhZGVyKCk7XG4gICAgICAgIHRoYXQudXBkYXRlX3BhZ2luYXRpb24oKTtcblxuICAgICAgICAvLyBTY3JvbGwgdG8gdG9wIG9mIGRhdGFncmlkIGlmIGl0J3Mgbm90IGN1cnJlbnRseSB2aXNpYmxlXG4gICAgICAgIHRoYXQuc2Nyb2xsX3RvX3RvcF9pZl9uZWVkZWQoKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgY2FsbGJhY2tzIGluIHRoaXMgZnVuY3Rpb24gZmlyZSBhZnRlciBlYWNoIHRhcmdldGVkIGNvbXBvbmVudCByZS1yZW5kZXJzXG4gICAgcmVnaXN0ZXJfcmVuZGVyX2NhbGxiYWNrcygpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIEF0dGFjaCByb3cgY2xpY2sgaGFuZGxlciAtIHJlLXJ1bnMgZXZlcnkgdGltZSBkYXRhZ3JpZF90YWJsZV9ib2R5IHJlbmRlcnNcbiAgICAgICAgdGhhdC5pZCgnZGF0YWdyaWRfdGFibGVfYm9keScpLm9uKCdyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnREdUQl9SJyk7XG4gICAgICAgICAgICAvLyBTdGVwIDE6IFdyYXAgY2VsbHMgaW4gZGF0YS1ocmVmIHJvd3Mgd2l0aCBhbmNob3IgdGFnc1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCd0cltkYXRhLWhyZWZdJylcbiAgICAgICAgICAgICAgICAuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCAkcm93ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhyZWYgPSAkcm93LmF0dHIoJ2RhdGEtaHJlZicpO1xuXG4gICAgICAgICAgICAgICAgICAgICRyb3cuZmluZCgndGQnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxldCAkY29sID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIFNraXAgaWYgY2VsbCBhbHJlYWR5IGNvbnRhaW5zIGludGVyYWN0aXZlIGVsZW1lbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiAoJGNvbC5maW5kKCdhLCBidXR0b24sIGlucHV0LCBzZWxlY3QsIHRleHRhcmVhJykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIFdyYXAgZW50aXJlIGNlbGwgY29udGVudHMgaW4gYW4gYW5jaG9yIChwcmVzZXJ2ZSBET00gbm9kZXMgZm9yIGNvbXBvbmVudCBsaWZlY3ljbGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBsZXQgJGFuY2hvciA9ICQoJzxhPicsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICBocmVmOiBocmVmLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIGNsYXNzOiAnZGF0YWdyaWQtcm93LWxpbmsnXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIE1vdmUgZXhpc3RpbmcgY2hpbGQgbm9kZXMgaW50byBhbmNob3IgKHByZXNlcnZlcyBjb21wb25lbnRzIGFuZCB0aGVpciBzdGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICRjb2wuY29udGVudHMoKS5hcHBlbmRUbygkYW5jaG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIEFkZCBhbmNob3IgdG8gY2VsbFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gJGNvbC5hcHBlbmQoJGFuY2hvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBTdGVwIDI6IEZpbmQgYWxsIGNlbGxzIHdpdGggc2luZ2xlIGFuY2hvciBhcyBvbmx5IGNoaWxkIGFuZCBhcHBseSBmdWxsLXdpZHRoIHN0eWxpbmdcbiAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgndGQnKVxuICAgICAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0ICRjb2wgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgJGNoaWxkcmVuID0gJGNvbC5jaGlsZHJlbigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGNlbGwgY29udGFpbnMgZXhhY3RseSBvbmUgZGlyZWN0IGNoaWxkIHRoYXQgaXMgYW4gYW5jaG9yXG4gICAgICAgICAgICAgICAgICAgIGlmICgkY2hpbGRyZW4ubGVuZ3RoID09PSAxICYmICRjaGlsZHJlbi5maXJzdCgpLmlzKCdhJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCBjbGFzcyB0byB0cmFuc2ZlciBwYWRkaW5nIGZyb20gY2VsbCB0byBhbmNob3JcbiAgICAgICAgICAgICAgICAgICAgICAgICRjb2wuYWRkQ2xhc3MoJ2hhcy1mdWxsLWxpbmsnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBjZWxsIGNvbnRhaW5zIG9ubHkgdGV4dCAobm8gY2hpbGQgZWxlbWVudHMpXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCRjaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCBjbGFzcyB0byBhcHBseSB2ZXJ0aWNhbCBwYWRkaW5nIHRvIHRleHQtb25seSBjZWxsc1xuICAgICAgICAgICAgICAgICAgICAgICAgJGNvbC5hZGRDbGFzcygnaGFzLW9ubHktdGV4dCcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEF0dGFjaCBzb3J0YWJsZSBoZWFkZXIgY2xpY2sgaGFuZGxlciAtIHJlLXJ1bnMgZXZlcnkgdGltZSBkYXRhZ3JpZF90YWJsZV9oZWFkZXIgcmVuZGVyc1xuICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9oZWFkZXInKS5vbigncmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gVHJhbnNmb3JtIHRoW2RhdGEtc29ydGJ5XSBlbGVtZW50cyBieSB3cmFwcGluZyBjb250ZW50cyBpbiBjbGlja2FibGUgbGlua1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCd0aFtkYXRhLXNvcnRieV0nKVxuICAgICAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0ICR0aCA9ICQodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBzb3J0YnkgPSAkdGguYXR0cignZGF0YS1zb3J0YnknKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBGaW5kIG91dCB3aHkgdGhpcyBvbigncmVuZGVyJykgY2FsbGJhY2sgaXMgYmVpbmcgY2FsbGVkIHR3aWNlL29uIGFscmVhZHktcHJvY2Vzc2VkIEhUTUxcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyB1bndyYXAgbG9naWMgc2hvdWxkbid0IGJlIG5lY2Vzc2FyeSAtIHRlbXBsYXRlIHNob3VsZCByZW5kZXIgZnJlc2ggZWFjaCB0aW1lXG4gICAgICAgICAgICAgICAgICAgIC8vIEZvciBub3csIHVud3JhcCBhbHJlYWR5LXdyYXBwZWQgY29udGVudCB0byBwcmV2ZW50IGRvdWJsZS13cmFwcGluZ1xuICAgICAgICAgICAgICAgICAgICBsZXQgJGV4aXN0aW5nX2xpbmsgPSAkdGguZmluZCgnYS5zb3J0YWJsZS1oZWFkZXInKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbnRlbnRzO1xuICAgICAgICAgICAgICAgICAgICBpZiAoJGV4aXN0aW5nX2xpbmsubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVW53cmFwIC0gZ2V0IHRoZSB0ZXh0IGNvbnRlbnQgd2l0aG91dCB0aGUgd3JhcHBlciBhbmQgYXJyb3dzXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50cyA9ICRleGlzdGluZ19saW5rLmNsb25lKCkuZmluZCgnaS5iaScpLnJlbW92ZSgpLmVuZCgpLmh0bWwoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gJHRoLmh0bWwoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1aWxkIHRoZSBhcnJvdyBpY29uIEhUTUwgaWYgdGhpcyBjb2x1bW4gaXMgY3VycmVudGx5IHNvcnRlZFxuICAgICAgICAgICAgICAgICAgICBsZXQgYXJyb3cgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuZGF0YS5zb3J0ID09PSBzb3J0YnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycm93ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmRhdGEub3JkZXIgPT09ICdkZXNjJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICc8aSBjbGFzcz1cImJpIGJpLWNoZXZyb24tdXAgbXMtMVwiPjwvaT4nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJzxpIGNsYXNzPVwiYmkgYmktY2hldnJvbi1kb3duIG1zLTFcIj48L2k+JztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UgY29udGVudHMgd2l0aCB3cmFwcGVkIGxpbmsgKGZyZXNoIHdyYXBwZXIgZXZlcnkgdGltZSlcbiAgICAgICAgICAgICAgICAgICAgJHRoLmh0bWwoYDxhIGhyZWY9XCIjXCIgY2xhc3M9XCJzb3J0YWJsZS1oZWFkZXJcIiBkYXRhLXNvcnRieT1cIiR7c29ydGJ5fVwiPiR7Y29udGVudHN9JHthcnJvd308L2E+YCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEF0dGFjaCBjbGljayBoYW5kbGVycyB0byB0aGUgc29ydGFibGUgbGlua3Mgd2UganVzdCBjcmVhdGVkXG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLmZpbmQoJ2Euc29ydGFibGUtaGVhZGVyW2RhdGEtc29ydGJ5XScpXG4gICAgICAgICAgICAgICAgLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc29ydGJ5ID0gJCh0aGlzKS5hdHRyKCdkYXRhLXNvcnRieScpO1xuICAgICAgICAgICAgICAgICAgICB0aGF0LnNvcnRfYnkoc29ydGJ5KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQXR0YWNoIHBhZ2luYXRpb24gY2xpY2sgaGFuZGxlciAtIHJlLXJ1bnMgZXZlcnkgdGltZSBwYWdpbmF0aW9uX2NvbnRyb2xzIHJlbmRlcnNcbiAgICAgICAgdGhhdC5pZCgncGFnaW5hdGlvbl9jb250cm9scycpLm9uKCdyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLmZpbmQoJy5wYWdlLWxpbmsnKVxuICAgICAgICAgICAgICAgIC5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgJGxpbmsgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYWdlID0gaW50KCRsaW5rLmF0dHIoJ2RhdGEtcGFnZScpKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgZGlzYWJsZWQvZWxsaXBzaXMgY2xpY2tzXG4gICAgICAgICAgICAgICAgICAgIGlmICghcGFnZSB8fCBpc05hTihwYWdlKSB8fCAkbGluay5wYXJlbnQoKS5oYXNDbGFzcygnZGlzYWJsZWQnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gTG9hZCB0aGUgcmVxdWVzdGVkIHBhZ2VcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5sb2FkX3BhZ2UocGFnZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEF0dGFjaCBjbGVhciBmaWx0ZXIgYnV0dG9uIGhhbmRsZXIgLSByZS1ydW5zIGV2ZXJ5IHRpbWUgZGF0YWdyaWRfdGFibGVfYm9keSByZW5kZXJzXG4gICAgICAgIHRoYXQuaWQoJ2RhdGFncmlkX3RhYmxlX2JvZHknKS5vbigncmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgJGNsZWFyX2J0biA9IHRoYXQuJGlkKCdjbGVhcl9maWx0ZXJfYnRuJyk7XG4gICAgICAgICAgICBpZiAoJGNsZWFyX2J0biAmJiAkY2xlYXJfYnRuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAkY2xlYXJfYnRuLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5jbGVhcl9maWx0ZXIoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gU29ydCBieSBzcGVjaWZpZWQgY29sdW1uLCB0b2dnbGluZyBvcmRlciBpZiBhbHJlYWR5IHNvcnRlZCBieSB0aGF0IGNvbHVtblxuICAgIHNvcnRfYnkoY29sdW1uKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBUb2dnbGUgb3JkZXIgaWYgY2xpY2tpbmcgc2FtZSBjb2x1bW4sIG90aGVyd2lzZSBkZWZhdWx0IHRvIGFzY1xuICAgICAgICBpZiAodGhhdC5kYXRhLnNvcnQgPT09IGNvbHVtbikge1xuICAgICAgICAgICAgdGhhdC5kYXRhLm9yZGVyID0gdGhhdC5kYXRhLm9yZGVyID09PSAnYXNjJyA/ICdkZXNjJyA6ICdhc2MnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhhdC5kYXRhLnNvcnQgPSBjb2x1bW47XG4gICAgICAgICAgICB0aGF0LmRhdGEub3JkZXIgPSAnYXNjJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlbG9hZCBjdXJyZW50IHBhZ2Ugd2l0aCBuZXcgc29ydFxuICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9oZWFkZXInKS5yZW5kZXIoKTtcbiAgICAgICAgdGhhdC5sb2FkX3BhZ2UodGhhdC5kYXRhLnBhZ2UpO1xuICAgIH1cblxuICAgIC8vIFJlZ2lzdGVyIGZpbHRlciBpbnB1dCBoYW5kbGVyc1xuICAgIHJlZ2lzdGVyX2ZpbHRlcl9oYW5kbGVycygpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIEZpbmQgZmlsdGVyIGlucHV0IGJ5IGNvbW1vbiBpZGVudGlmaWVyc1xuICAgICAgICBsZXQgJGZpbHRlciA9IHRoYXQuJGlkKCdmaWx0ZXJfaW5wdXQnKTtcbiAgICAgICAgaWYgKCEkZmlsdGVyIHx8ICRmaWx0ZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAkZmlsdGVyID0gdGhhdC4kLmZpbmQoJ2lucHV0W3R5cGU9XCJzZWFyY2hcIl0sIGlucHV0W3R5cGU9XCJ0ZXh0XCJdLmZpbHRlci1pbnB1dCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCRmaWx0ZXIgJiYgJGZpbHRlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAkZmlsdGVyLm9uKCdpbnB1dCBrZXl1cCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJfdmFsdWUgPSAkKHRoaXMpLnZhbCgpO1xuICAgICAgICAgICAgICAgIHRoYXQuZmlsdGVyX2NoYW5nZWQoZmlsdGVyX3ZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZmlsdGVyX2NoYW5nZWQoZmlsdGVyKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICB0aGF0LmRhdGEuZmlsdGVyID0gZmlsdGVyO1xuICAgICAgICB0aGF0LmxvYWRfcGFnZSgxKTtcbiAgICB9XG5cbiAgICAvLyBTY3JvbGwgdG8gZGF0YWdyaWQgdG9wIGlmIHRoZSB0b3AgZWRnZSBpcyBub3QgY3VycmVudGx5IHZpc2libGUgaW4gdmlld3BvcnRcbiAgICBzY3JvbGxfdG9fdG9wX2lmX25lZWRlZCgpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIGNvbnN0ICRkYXRhZ3JpZCA9IHRoYXQuJDtcbiAgICAgICAgY29uc3QgZGF0YWdyaWRUb3AgPSAkZGF0YWdyaWQub2Zmc2V0KCkudG9wO1xuICAgICAgICBjb25zdCBzY3JvbGxUb3AgPSAkKHdpbmRvdykuc2Nyb2xsVG9wKCk7XG5cbiAgICAgICAgLy8gSWYgZGF0YWdyaWQgdG9wIGlzIGFib3ZlIHRoZSBjdXJyZW50IHZpZXdwb3J0LCBzY3JvbGwgdG8gc2hvdyBpdFxuICAgICAgICBpZiAoZGF0YWdyaWRUb3AgPCBzY3JvbGxUb3ApIHtcbiAgICAgICAgICAgIC8vIElmIGRhdGFncmlkIGlzIHdpdGhpbiAzMDBweCBvZiBwYWdlIHRvcCwgc2Nyb2xsIHRvIDBcbiAgICAgICAgICAgIGlmIChkYXRhZ3JpZFRvcCA8PSAzMDApIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oeyB0b3A6IDAsIGJlaGF2aW9yOiAnaW5zdGFudCcgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFNjcm9sbCB0byAyMHB4IGFib3ZlIGRhdGFncmlkXG4gICAgICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKHsgdG9wOiBkYXRhZ3JpZFRvcCAtIDIwLCBiZWhhdmlvcjogJ2luc3RhbnQnIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTWVhc3VyZSBhY3R1YWwgcm93IGhlaWdodCBhbmQgc2V0IGZpeGVkIHRib2R5IG1pbi1oZWlnaHRcbiAgICAvLyBBbGwgaGFwcGVucyBpbiBvbmUgYW5pbWF0aW9uIGZyYW1lIHNvIHVzZXIgZG9lc24ndCBzZWUgaXRcbiAgICBhc3luYyBtZWFzdXJlX2FuZF9zZXRfZml4ZWRfaGVpZ2h0KCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgbmV4dCBhbmltYXRpb24gZnJhbWUgdG8gZW5zdXJlIERPTSBpcyByZWFkeVxuICAgICAgICBhd2FpdCBzbGVlcCgwKTtcblxuICAgICAgICBjb25zdCAkdGJvZHkgPSB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9ib2R5JykuJDtcblxuICAgICAgICAvLyBUZW1wb3JhcmlseSByZW5kZXIgYSBzaW5nbGUgbWVhc3VyZW1lbnQgcm93XG4gICAgICAgIGNvbnN0ICRtZWFzdXJlbWVudF9yb3cgPSAkKCc8dHI+JykuY3NzKCd2aXNpYmlsaXR5JywgJ2hpZGRlbicpLmh0bWwoJzx0ZD5NZWFzdXJpbmcuLi48L3RkPicpO1xuICAgICAgICAkdGJvZHkuYXBwZW5kKCRtZWFzdXJlbWVudF9yb3cpO1xuXG4gICAgICAgIC8vIE1lYXN1cmUgdGhlIHJvdyBoZWlnaHRcbiAgICAgICAgY29uc3Qgcm93X2hlaWdodCA9ICRtZWFzdXJlbWVudF9yb3cub3V0ZXJIZWlnaHQoKTtcblxuICAgICAgICAvLyBSZW1vdmUgbWVhc3VyZW1lbnQgcm93XG4gICAgICAgICRtZWFzdXJlbWVudF9yb3cucmVtb3ZlKCk7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIGFuZCBzZXQgbWluLWhlaWdodCBiYXNlZCBvbiBwZXJfcGFnZVxuICAgICAgICBjb25zdCBtaW5faGVpZ2h0ID0gcm93X2hlaWdodCAqIHRoYXQuZGF0YS5wZXJfcGFnZTtcbiAgICAgICAgJHRib2R5LmNzcygnbWluLWhlaWdodCcsIG1pbl9oZWlnaHQgKyAncHgnKTtcblxuICAgICAgICAvLyBTdG9yZSBmb3IgZnV0dXJlIHJlZmVyZW5jZVxuICAgICAgICB0aGF0LmRhdGEucm93X2hlaWdodCA9IHJvd19oZWlnaHQ7XG4gICAgICAgIHRoYXQuZGF0YS50Ym9keV9taW5faGVpZ2h0ID0gbWluX2hlaWdodDtcbiAgICB9XG5cbiAgICAvLyBDbGVhciBmaWx0ZXIgYW5kIHJlc2V0IHRvIHBhZ2UgMVxuICAgIGNsZWFyX2ZpbHRlcigpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIHRoYXQuZGF0YS5maWx0ZXIgPSAnJztcblxuICAgICAgICAvLyBDbGVhciB0aGUgZmlsdGVyIGlucHV0XG4gICAgICAgIGNvbnN0ICRmaWx0ZXIgPSB0aGF0LiRpZCgnZmlsdGVyX2lucHV0Jyk7XG4gICAgICAgIGlmICgkZmlsdGVyICYmICRmaWx0ZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgJGZpbHRlci52YWwoJycpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVsb2FkIGZyb20gcGFnZSAxXG4gICAgICAgIHRoYXQubG9hZF9wYWdlKDEpO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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