TimeTrex/interface/html5/dist/awesomebox-AComboBox.bundle.js

1 line
241 KiB
JavaScript

(self.webpackChunktimetrex=self.webpackChunktimetrex||[]).push([["awesomebox-AComboBox"],{2897:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/* provided dependency */ var _ = __webpack_require__(9050);\n/* provided dependency */ var jQuery = __webpack_require__(9755);\n( function( $ ) {\n\n\t$.fn.AComboBox = function( options ) {\n\t\tvar opts = $.extend( {}, $.fn.AComboBox.defaults, options );\n\n\t\tvar label_span = null;\n\n\t\tvar a_dropdown = null;\n\n\t\tvar layout_name = '';\n\n\t\tvar pager_data = null; //use to reset pager data when open dropdown\n\n\t\tvar api_class = null;\n\n\t\tvar api = null; //Related TTAPI.API instance, use to get data\n\n\t\tvar default_columns = null;\t //Default coluns when no layout saved\n\n\t\tvar allow_multiple_selection = false;\n\n\t\tvar do_not_get_real_data = false; //Get full data when only pass id to select Value.\n\n\t\tvar get_real_data_on_multi = false; //Usually only get real data when select has a single value. But punch tags require manual_id of all records.\n\n\t\tvar set_any = false;\n\n\t\tvar set_empty = false;\n\n\t\tvar set_special_empty = false;\n\n\t\tvar set_open = false;\n\n\t\tvar set_default = false;\n\n\t\tvar set_all = false;\n\n\t\tvar select_item = null;\n\n\t\tvar select_items = null;\n\n\t\tvar field = '';\n\n\t\tvar validation_field;\n\n\t\tvar user_generic_api = null;\n\n\t\tvar display_columns = null; //Display columns in ADropDown in jGrid model format\n\n\t\tvar possible_display_columns = null; //Only these columns can be shown when init dispaly columns.\n\n\t\tvar list_view_default_columns = null; //Only these columns can be shown when init dispaly columns.\n\n\t\tvar display_columns_in_columnEditor = null; //Display columns in edit columns\n\n\t\tvar all_columns = null; // All columns when edit columns\n\n\t\tvar column_editor = null;\n\n\t\tvar source_data = null; // This will never change when search in search input. Set it back to dropdown every time when open\n\n\t\tvar id = '';\n\n\t\tvar get_real_data_when_open = false;\n\n\t\tvar set_select_items_when_set_data_provider = false;\n\n\t\tvar $this = null;\n\n\t\tvar a_dropdown_div = null;\n\n\t\tvar is_mouse_over = false;\n\n\t\tvar row_per_page = 0;\n\n\t\tvar show_all = false;\n\n\t\tvar args = null;\n\n\t\tGlobal.addCss( 'global/widgets/awesomebox/AComboBox.css' );\n\n\t\tvar show_search_inputs = true;\n\n\t\tvar tree_mode = false;\n\n\t\tvar on_tree_grid_row_select = false;\n\n\t\tvar key = 'id';\n\n\t\tvar error_string = '';\n\n\t\tvar error_tip_box;\n\n\t\t$this = this;\n\n\t\tvar mass_edit_mode = false;\n\n\t\tvar check_box = null;\n\n\t\tvar enabled = true;\n\n\t\tvar allow_drag_to_order = false;\n\n\t\tvar navigation_mode = false;\n\n\t\tvar args_from_saved_layout = null;\n\n\t\tvar default_args = null;\n\t\t//Use this in Navigation Mode, Keep search filter when open. Don't clean it in onClose if navigation_mode\n\t\t// Now we di this in both navigation and normal (2014/6/7)\n\t\tvar cached_search_inputs_filter = null;\n\n\t\tvar cached_select_grid_search_inputs_filter = null;\n\n\t\tvar cached_sort_filter = null; //Same as above\n\n\t\tvar cached_selected_grid_sort_filter = null; //Same as above\n\n\t\tvar script_name = '';\n\n\t\tvar navigation_mode_source_data_before_open = null;\n\n\t\tvar set_default_args_manually = false; //If set default args outside\n\n\t\tvar addition_source_function = null;\n\n\t\tvar custom_key_name = null;\n\n\t\tvar setRealValueCallBack = null; //Set real data call back function\n\n\t\tvar custom_first_label = null;\n\n\t\tvar added_items = null;\n\n\t\tvar column_option_key = 'columns';\n\n\t\t// set this when close, don't allow awesomebox open until 0.3 sec, this prevent awesomebox close in mousedown, and open in click.\n\t\tvar dontOpenTimer = null;\n\n\t\tvar dontOpen = false;\n\n\t\tvar total_header_width;\n\n\t\t//if init source data right after initcolumns complete\n\t\tvar init_data_immediately = false;\n\n\t\tvar unselect_grid_search_result;\n\n\t\t// don't do column filter base on display columns, use all instead\n\t\t//Use in report edit view. load saved report navigation\n\t\tvar always_search_full_columns = false;\n\n\t\t//Save what letter user current use to do the search\n\t\tvar quick_search_dic = {};\n\n\t\t//Save multi key typed when quick search\n\t\tvar quick_search_typed_keys = '';\n\n\t\tvar select_grid_search_result;\n\n\t\t//use to juedge if need to clear quick_search_typed_keys\n\t\tvar quick_search_timer;\n\n\t\tvar current_open_page = 1;\n\n\t\t//deal with result when doing dropdown search, TimesheetAuthorizationViewControl need this.\n\t\tvar extendDataProcessWhenSearch;\n\n\t\tvar always_include_columns = false;\n//\n//\t\t//Used for modify search result when doing Paging or Searching, For example, used in AccrualBalanceViewController to set correct ids\n//\t\tthis.customSearchResultHandler = null;\n\n\t\t//Used for modify search filter when open awesomebox or do search/sorting and paging. First used in Timehsheet absency_policy awesomebox\n\t\tthis.customSearchFilter = null;\n\n\t\tthis.getCurrentOpenPage = function() {\n\t\t\treturn current_open_page;\n\t\t};\n\n\t\tthis.getPagerData = function() {\n\t\t\treturn pager_data;\n\t\t};\n\n\t\tthis.getHeaderWidth = function() {\n\t\t\treturn total_header_width;\n\t\t};\n\n\t\tthis.setKey = function( val ) {\n\t\t\tkey = val;\n\t\t};\n\n\t\tthis.getDisplayColumns = function() {\n\t\t\treturn display_columns;\n\t\t};\n\n\t\tthis.getLayout = function() {\n\n\t\t\treturn ALayoutCache.layout_dic[layout_name];\n\t\t};\n\n\t\tthis.getAPI = function() {\n\t\t\treturn api;\n\t\t};\n\n\t\tthis.getScriptName = function() {\n\n\t\t\tscript_name = Global.getScriptNameByAPI( api_class );\n\n\t\t\treturn script_name;\n\t\t};\n\n\t\tthis.setCachedSortFilter = function( val ) {\n\t\t\tcached_sort_filter = val;\n\t\t};\n\n\t\tthis.setCachedSelectedGridSortFilter = function( val ) {\n\t\t\tcached_selected_grid_sort_filter = val;\n\t\t};\n\n\t\tthis.setCachedSearchInputsFilter = function( val ) {\n\t\t\tcached_search_inputs_filter = val;\n\t\t};\n\n\t\tthis.setCachedSelectGridSearchInputsFilter = function( val ) {\n\t\t\tcached_select_grid_search_inputs_filter = val;\n\t\t};\n\n\t\tthis.setAllowMultipleSelection = function( val ) {\n\t\t\tallow_multiple_selection = val;\n\n\t\t\tif ( val == true ) {\n\t\t\t\tif ( select_item ) {\n\t\t\t\t\tselect_items = [select_item];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( select_items && select_items.length > 0 ) {\n\t\t\t\t\tselect_item = select_items[0];\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getEnabled = function() {\n\t\t\treturn enabled;\n\t\t};\n\n\t\tthis.setEnabled = function( val ) {\n\t\t\tenabled = val;\n\t\t\tif ( val === false || val === '' ) {\n\t\t\t\t$this.addClass( 'a-combobox-readonly' );\n\t\t\t\tif ( check_box ) {\n\t\t\t\t\tcheck_box.hide();\n\t\t\t\t}\n\t\t\t\tif ( !this.children().eq( 1 ).text() ) {\n\t\t\t\t\tthis.children().eq( 1 ).text( $.i18n._( 'N/A' ) );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$this.removeClass( 'a-combobox-readonly' );\n\n\t\t\t\tif ( check_box ) {\n\t\t\t\t\tcheck_box.show();\n\t\t\t\t}\n\t\t\t\tif ( !this.children().eq( 1 ).text() === $.i18n._( 'N/A' ) ) {\n\t\t\t\t\tthis.children().eq( 1 ).text( '' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.setCheckBox = function( val ) {\n\t\t\tif ( check_box ) {\n\t\t\t\tcheck_box.children().eq( 0 )[0].checked = val;\n\t\t\t}\n\t\t};\n\n\t\tthis.isChecked = function() {\n\t\t\tif ( check_box ) {\n\t\t\t\tif ( check_box.children().eq( 0 )[0].checked === true ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t};\n\n\t\tthis.setMassEditMode = function( val ) {\n\t\t\tmass_edit_mode = val;\n\n\t\t\tif ( mass_edit_mode ) {\n\t\t\t\tcheck_box = $( ' <div class=\"mass-edit-checkbox-wrapper\"><input type=\"checkbox\" class=\"mass-edit-checkbox\"></input>' +\n\t\t\t\t\t'<label for=\"checkbox-input-1\" class=\"input-helper input-helper--checkbox\"></label></div>' );\n\t\t\t\tcheck_box.insertBefore( $( this ) );\n\n\t\t\t\tcheck_box.change( function() {\n\t\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t\t} );\n\n\t\t\t} else {\n\t\t\t\tif ( check_box ) {\n\t\t\t\t\tcheck_box.remove();\n\t\t\t\t\tcheck_box = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getItemByIndex = function( index ) {\n\t\t\tvar target_source_data;\n\n\t\t\tif ( navigation_mode && !source_data ) {\n\t\t\t\ttarget_source_data = navigation_mode_source_data_before_open;\n\t\t\t} else {\n\t\t\t\ttarget_source_data = source_data;\n\n\t\t\t\t//Only for single mode\n\t\t\t\tif ( unselect_grid_search_result && unselect_grid_search_result.length > 0 ) {\n\t\t\t\t\ttarget_source_data = unselect_grid_search_result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !target_source_data ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tvar result = null;\n\t\t\tresult = target_source_data[index];\n\t\t\treturn result;\n\n\t\t};\n\n\t\tthis.getSelectIndex = function() {\n\n\t\t\tvar target_source_data;\n\n\t\t\tif ( navigation_mode && !source_data ) {\n\t\t\t\ttarget_source_data = navigation_mode_source_data_before_open;\n\t\t\t} else {\n\t\t\t\ttarget_source_data = source_data;\n\n\t\t\t\t//Only for single mode\n\t\t\t\tif ( unselect_grid_search_result && unselect_grid_search_result.length > 0 ) {\n\t\t\t\t\ttarget_source_data = unselect_grid_search_result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !select_item || !target_source_data ) { // can't get correct index if source_data is null\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tvar len = target_source_data.length;\n\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\tvar item = target_source_data[i];\n\t\t\t\tif ( select_item[key] === item[key] ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t};\n\n\t\tthis.getNextSelectItemId = function() {\n\t\t\tvar retval = null;\n\t\t\t// This function is commonly used by edit views to get the id of the next record from the navigation box, such as during Delete&Next\n\t\t\tvar next_select_item = this.getSelectIndex() + 1;\n\t\t\tvar source_data = this.getSourceData();\n\t\t\tif ( source_data && next_select_item < source_data.length ) {\n\t\t\t\tretval = this.getItemByIndex( next_select_item );\n\t\t\t} else {\n\t\t\t\tretval = null;\n\t\t\t}\n\n\t\t\treturn retval;\n\t\t};\n\n\t\tthis.setErrorStyle = function( errStr, show, isWarning ) {\n\t\t\tif ( isWarning ) {\n\t\t\t\t$( this ).addClass( 'a-warning-tip' );\n\t\t\t} else {\n\t\t\t\t$( this ).addClass( 'a-error-tip' );\n\t\t\t}\n\t\t\terror_string = errStr;\n\n\t\t\tif ( show ) {\n\t\t\t\tthis.showErrorTip();\n\t\t\t}\n\t\t};\n\n\t\tthis.showErrorTip = function( sec ) {\n\n\t\t\tif ( !Global.isSet( sec ) ) {\n\t\t\t\tsec = 2;\n\t\t\t}\n\n\t\t\tif ( !error_tip_box ) {\n\t\t\t\terror_tip_box = Global.loadWidgetByName( WidgetNamesDic.ERROR_TOOLTIP );\n\t\t\t\terror_tip_box = error_tip_box.ErrorTipBox();\n\t\t\t}\n\t\t\tif ( $( this ).hasClass( 'a-warning-tip' ) ) {\n\t\t\t\terror_tip_box.show( this, error_string, sec, true );\n\t\t\t} else {\n\t\t\t\terror_tip_box.show( this, error_string, sec );\n\t\t\t}\n\t\t};\n\n\t\tthis.hideErrorTip = function() {\n\n\t\t\tif ( Global.isSet( error_tip_box ) ) {\n\t\t\t\terror_tip_box.remove();\n\t\t\t}\n\n\t\t};\n\n\t\tthis.clearErrorStyle = function() {\n\t\t\t$( this ).removeClass( 'a-error-tip' );\n\t\t\t$( this ).removeClass( 'a-warning-tip' );\n\t\t\terror_string = '';\n\t\t\tthis.hideErrorTip();\n\t\t};\n\n\t\tthis.setField = function( val ) {\n\t\t\tfield = val;\n\t\t};\n\n\t\tthis.getField = function() {\n\t\t\treturn field;\n\t\t};\n\n\t\tthis.getValidationField = function() {\n\t\t\treturn validation_field;\n\t\t};\n\n\t\tthis.getValue = function( return_full_value ) {\n\t\t\tvar return_value = null;\n\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\tif ( return_full_value ) {\n\t\t\t\t\treturn_value = select_items;\n\t\t\t\t} else {\n\t\t\t\t\treturn_value = [];\n\t\t\t\t\tif ( Global.isArray( select_items ) ) {\n\t\t\t\t\t\t$.each( select_items, function( index, content ) {\n\t\t\t\t\t\t\t// In 1891, one value in select items is null\n\t\t\t\t\t\t\tif ( content ) {\n\t\t\t\t\t\t\t\tif ( Global.isString( content ) || $.type( content ) === 'number' ) {\n\t\t\t\t\t\t\t\t\treturn_value.push( content );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\treturn_value.push( content[key] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tif ( select_items.length === 0 ) {\n\t\t\t\t\t\t\tif ( set_any ) {\n\t\t\t\t\t\t\t\treturn_value.push( TTUUID.not_exist_id ); // In fact, if the columns can be multiple selected. and no have any options selected, it's should be return an array.\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( set_any ) {\n\t\t\t\t\t\t\treturn_value.push( TTUUID.not_exist_id ); // In fact, if the columns can be multiple selected. and no have any options selected, it's should be return an array.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Return false when no selected value\n\t\t\t\t\tif ( return_value.length === 0 ) {\n\t\t\t\t\t\tif ( set_any ) {\n\t\t\t\t\t\t\treturn_value = TTUUID.not_exist_id;\n\t\t\t\t\t\t} else if ( set_empty ) {\n\t\t\t\t\t\t\treturn_value = TTUUID.zero_id;\n\t\t\t\t\t\t} else if ( set_special_empty ) {\n\t\t\t\t\t\t\treturn_value = TTUUID.not_exist_id;\n\t\t\t\t\t\t} else if ( set_open ) {\n\t\t\t\t\t\t\treturn_value = TTUUID.zero_id;\n\t\t\t\t\t\t} else if ( set_default ) {\n\t\t\t\t\t\t\treturn_value = TTUUID.zero_id;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( return_full_value ) {\n\t\t\t\t\treturn_value = select_item;\n\t\t\t\t} else {\n\t\t\t\t\tif ( select_item ) {\n\n\t\t\t\t\t\tif ( Global.isSet( select_item[key] ) ) {\n\t\t\t\t\t\t\treturn_value = select_item[key];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn_value = select_item;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( set_any ) {\n\t\t\t\t\t\t\treturn TTUUID.not_exist_id;\n\t\t\t\t\t\t} else if ( set_empty ) {\n\t\t\t\t\t\t\treturn TTUUID.zero_id;\n\t\t\t\t\t\t} else if ( set_special_empty ) {\n\t\t\t\t\t\t\treturn TTUUID.not_exist_id;\n\t\t\t\t\t\t} else if ( set_open ) {\n\t\t\t\t\t\t\treturn TTUUID.zero_id;\n\t\t\t\t\t\t} else if ( set_default ) {\n\t\t\t\t\t\t\treturn TTUUID.zero_id;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn return_value;\n\t\t};\n\n\t\tthis.setSourceData = function( val ) {\n\t\t\tsource_data = val;\n\n\t\t\tif ( !allow_multiple_selection ) {\n\t\t\t\tif ( val && val.length > 0 ) {\n\t\t\t\t\tif ( set_empty || set_any || set_default || set_open || set_all || set_special_empty ) {\n\t\t\t\t\t\t$this.createFirstItem();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( !select_item ) {\n\t\t\t\t\t\t\t//Related to 1825, directly use item not item id, since use item id willl\n\t\t\t\t\t\t\t// trigger getReal data which case problems and not necessary.\n\t\t\t\t\t\t\tthis.setValue( val[0] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( val && val.length > 0 ) {\n\t\t\t\t\tif ( set_all ) {\n\t\t\t\t\t\t$this.createFirstItem();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( set_select_items_when_set_data_provider && source_data ) {\n\n\t\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\t\tthis.setValue( select_items );\n\t\t\t\t} else {\n\t\t\t\t\tthis.setValue( select_item );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tthis.getSourceData = function() {\n\n\t\t\tif ( navigation_mode && navigation_mode_source_data_before_open ) {\n\t\t\t\treturn navigation_mode_source_data_before_open;\n\t\t\t}\n\n\t\t\t//if done search, return the result o\n\t\t\tif ( unselect_grid_search_result ) {\n\t\t\t\treturn unselect_grid_search_result;\n\t\t\t}\n\n\t\t\treturn source_data;\n\t\t};\n\n\t\t//Always return source data only\n\t\tthis.getStaticSourceData = function() {\n\t\t\treturn source_data;\n\t\t};\n\n\t\tthis.getRowPerPage = function() {\n\t\t\treturn row_per_page;\n\t\t};\n\n\t\tthis.setAllColumns = function( value ) {\n\t\t\tall_columns = value;\n\t\t};\n\n\t\tthis.setDisplayColumnsForEditor = function( value ) {\n\t\t\tdisplay_columns_in_columnEditor = value;\n\t\t};\n\n\t\tthis.getAllColumns = function() {\n\n\t\t\tif ( possible_display_columns ) {\n\t\t\t\treturn possible_display_columns;\n\t\t\t}\n\t\t\treturn all_columns;\n\t\t};\n\n\t\tthis.getDisplayColumnsForEditor = function() {\n\t\t\treturn display_columns_in_columnEditor;\n\t\t};\n\n\t\tthis.setEmptyValueAndShowLoading = function() {\n\t\t\tvar current_width = $this.find( '.a-combobox-label' ).width();\n\t\t\tthis.setValue( null );\n\t\t\tlabel_span.text( Global.loading_label );\n\t\t\t$this.find( '.a-combobox-label' ).width( current_width + 'px' );\n\t\t};\n\n\t\tthis.setValue = function( val ) {\n\t\t\t// Related to 1891, one case is value is [null] in vacatuon_psea_ids in ROE edit view\n\t\t\tif ( _.isArray( val ) && val.length === 1 && val[0] === null ) {\n\t\t\t\tval = null;\n\t\t\t}\n\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\tif ( !val || $.type( val ) === 'array' ) {\n\t\t\t\t\tthis.setSelectItems( val );\n\t\t\t\t} else if ( $.type( val ) === 'string' || $.type( val ) === 'number' ) {\n\t\t\t\t\tthis.setSelectItems( [val] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( $.type( val ) === 'array' && val.length > 0 ) {\n\t\t\t\t\tval = val[0];\n\t\t\t\t}\n\t\t\t\t//If no default value set first item as default select item\n\t\t\t\t//#1187 - this fix might cause problems but is needed to allow proper selection of default value when zero_uuid is selected.\n\t\t\t\tif ( !val || val == TTUUID.zero_id ) {\n\t\t\t\t\t// if ( !val ) {\n\t\t\t\t\tif ( !set_empty && !set_any && !set_default && !set_open && !set_all && !set_special_empty && source_data && source_data.length > 0 ) {\n\t\t\t\t\t\tthis.setValue( source_data[0] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setSelectItem( null );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.setSelectItem( val );\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getAllowMultipleSelection = function() {\n\t\t\treturn allow_multiple_selection;\n\t\t};\n\n\t\t//Get full data from api, if get a id\n\t\tthis.getRealData = function( val ) {\n\n\t\t\tif ( Global.isSet( api_class ) ) {\n\n\t\t\t\t//Try api awesomebox first\n\t\t\t\tif ( ( !TTUUID.isUUID( val ) && parseInt( val ) <= 0 ) || val == TTUUID.zero_id || val == TTUUID.not_exist_id ) {\n\n\t\t\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\t\t\t$this.setValue( [this.getLocalSelectItem( val )] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$this.setValue( this.getLocalSelectItem( val ) );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar filter = {};\n\t\t\t\t//id is a public member of this class which contains the field id, so we wrapped 'id' in quotes here to show it's not the public member from above.\n\t\t\t\tfilter.filter_data = { 'id': val };\n\n\t\t\t\t//#2289 - If you have an employee who can view subordinate punches but not view subordinate employee, you will see permission denied without sending the permission section.\n\t\t\t\tif ( default_args && Global.isSet( default_args.permission_section ) ) {\n\t\t\t\t\tfilter.permission_section = default_args.permission_section;\n\t\t\t\t}\n\n\t\t\t\tif ( this.customSearchFilter ) {\n\t\t\t\t\tfilter = this.customSearchFilter( filter );\n\t\t\t\t}\n\n\t\t\t\tlabel_span.text( Global.loading_label );\n\n\t\t\t\tapi['get' + custom_key_name]( filter, {\n\t\t\t\t\tonResult: function( result ) {\n\t\t\t\t\t\tvar result_data = result.getResult();\n\n\t\t\t\t\t\tif ( result_data && result_data.length > 0 ) {\n\n\t\t\t\t\t\t\tvar value;\n\t\t\t\t\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\t\t\t\t\tvalue = result_data;\n\t\t\t\t\t\t\t\t$this.setValue( result_data );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tvalue = result_data[0];\n\t\t\t\t\t\t\t\t$this.setValue( result_data[0] );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( setRealValueCallBack ) {\n\t\t\t\t\t\t\tsetRealValueCallBack( value );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tif ( source_data && source_data.length > 0 ) {\n\t\t\t\t\t$.each( source_data, function( index, content ) {\n\n\t\t\t\t\t\t//Make the id match when val is string or number. use == instead ===.\n\t\t\t\t\t\tif ( content[key] == val ) {\n\n\t\t\t\t\t\t\t$this.setValue( content );\n\t\t\t\t\t\t\treturn false; //This is a boolean false, not an integer or UUID.\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t} else {\n\t\t\t\t\tset_select_items_when_set_data_provider = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getColumnFilter = function() {\n\n\t\t\tif ( always_search_full_columns ) {\n\t\t\t\treturn {};\n\t\t\t}\n\n\t\t\tvar column_filter = {};\n\t\t\tcolumn_filter.is_owner = true;\n\t\t\tcolumn_filter.id = true;\n\t\t\tcolumn_filter.is_child = true;\n\t\t\tcolumn_filter.user_id = true;\n\t\t\tcolumn_filter.first_name = true; //always contains this if it exists\n\t\t\tcolumn_filter.last_name = true; //always contains this if it exists\n\t\t\tcolumn_filter.object_type_id = true;\n\t\t\tcolumn_filter.manual_id = true;\n\t\t\tcolumn_filter.default_item_id = true;\n\t\t\tcolumn_filter.accrual_policy_id = true;\n\t\t\tcolumn_filter.pay_code_id = true;\n\t\t\tcolumn_filter.start_date = true;\n\t\t\tcolumn_filter.end_date = true;\n\t\t\tcolumn_filter.pay_period_id = true;\n\n\t\t\tif ( api && api.className === 'APIUser' ) {\n\t\t\t\tcolumn_filter.pay_period_schedule_id = true;\n\t\t\t\tcolumn_filter.policy_group_id = true;\n\t\t\t\tcolumn_filter.hire_date = true;\n\t\t\t\tcolumn_filter.termination_date = true;\n\t\t\t}\n\n\t\t\t$.each( display_columns, function( key, item ) {\n\t\t\t\tcolumn_filter[item.name] = true;\n\t\t\t} );\n\n\t\t\tif ( always_include_columns && always_include_columns.length > 0 ) {\n\t\t\t\t$.each( always_include_columns, function( key, item ) {\n\t\t\t\t\tcolumn_filter[item] = true;\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn column_filter;\n\t\t};\n\n\t\tthis.cleanDropDownValues = function() {\n\t\t\tif ( a_dropdown ) {\n\t\t\t\ta_dropdown.setSelectGridData( [] );\n\t\t\t}\n\t\t};\n\n\t\tthis.setSelectItem = function( val ) {\n\t\t\t//When setting select_item, clear out the select_items (plural) variable so it doesn't contain old data if the dropdown box happens to get switched back to it.\n\t\t\tselect_items = null;\n\n\t\t\tselect_item = val;\n\n\t\t\tif ( val === false || val === '' ) {\n\t\t\t\tthis.setLabel( val );\n\t\t\t\tif ( setRealValueCallBack ) {\n\t\t\t\t\tsetRealValueCallBack( false );\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( $.type( val ) === 'string' || $.type( val ) === 'number' ) {\n\t\t\t\tthis.getRealData( val );\n\t\t\t} else {\n\t\t\t\tthis.setLabel();\n\t\t\t}\n\t\t};\n\n\t\tthis.setSelectItems = function( val ) {\n\t\t\t//When setting select_items (plural), clear out the select_item variable so it doesn't contain old data if the dropdown box happens to get switched back to it.\n\t\t\tselect_item = null;\n\n\t\t\tif ( !val || val.length < 1 ) {\n\t\t\t\tthis.setEmptyLabel();\n\t\t\t\tselect_items = null;\n\t\t\t\tif ( setRealValueCallBack ) {\n\t\t\t\t\tsetRealValueCallBack( false );\n\t\t\t\t}\n\n\t\t\t\tthis.cleanDropDownValues();\n\n\t\t\t\treturn;\n\t\t\t} else if ( val == TTUUID.not_exist_id && set_any ) {\n\t\t\t\tselect_items = val;\n\t\t\t\tthis.setEmptyLabel();\n\t\t\t\tif ( setRealValueCallBack ) {\n\t\t\t\t\tsetRealValueCallBack( false );\n\t\t\t\t}\n\t\t\t\tthis.cleanDropDownValues();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tselect_items = val;\n\n\t\t\tvar len = val.length;\n\n\t\t\tif ( len > 1 ) {\n\t\t\t\tvar item = val[0];\n\t\t\t\tif ( $.type( item ) === 'string' || $.type( item ) === 'number' ) {\n\t\t\t\t\tif ( !do_not_get_real_data ) {\n\t\t\t\t\t\tget_real_data_when_open = true;\n\t\t\t\t\t}\n\t\t\t\t\tif ( get_real_data_on_multi && setRealValueCallBack ) {\n\t\t\t\t\t\t//Required to get values for Multi-select field callbacks. Currently, used to retrieve punch tag manual ids.\n\t\t\t\t\t\t//If this is not done, manual ids will only be retrieved in the scenario there is only one item selected in which case this.getRealData() is called.\n\t\t\t\t\t\t//However, adding this.getRealData() here causes other issues.\n\t\t\t\t\t\tsetRealValueCallBack( val, true );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.setLabel();\n\t\t\t} else {\n\t\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\t\titem = val[i];\n\t\t\t\t\tif ( $.type( item ) === 'string' ||\n\t\t\t\t\t\t$.type( item ) === 'number' ) {\n\t\t\t\t\t\tif ( !do_not_get_real_data ) {\n\t\t\t\t\t\t\tthis.getRealData( item );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif ( !source_data ) {\n\t\t\t\t\t\t\t\tset_select_items_when_set_data_provider = true;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t//set select items\twhich only contains value to select items have label and value\n\t\t\t\t\t\t\tthis.setSelectItems( this.getRealSelectItemsFromSourceData() );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor ( var key in item ) {\n\t\t\t\t\t\t\t//speical handle for sort field\n\t\t\t\t\t\t\tif ( item[key] === 'asc' || item[key] === 'desc' ) {\n\t\t\t\t\t\t\t\tif ( !source_data ) {\n\t\t\t\t\t\t\t\t\tset_select_items_when_set_data_provider = true;\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis.setLabel();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getSelectItems = function() {\n\t\t\treturn a_dropdown.getSelectItems();\n\t\t}\n\n\t\tthis.getRealSelectItemsFromSourceData = function() {\n\t\t\tvar len = source_data.length;\n\t\t\tvar select_items_len = select_items ? select_items.length : 0; // Fix for JS Exception if select_items is null.\n\t\t\tvar res = [];\n\n\t\t\tfor ( var i = 0; i < select_items_len; i++ ) {\n\t\t\t\tvar select_value = select_items[i];\n\t\t\t\tfor ( var j = 0; j < len; j++ ) {\n\t\t\t\t\tvar source_item = source_data[j];\n\n\t\t\t\t\t//Could be string or number, use ==\n\t\t\t\t\tif ( select_value == source_item[key] ) {\n\t\t\t\t\t\tres.push( source_item );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn res;\n\t\t};\n\n\t\tthis.setLabel = function() {\n\t\t\tvar label_arr = Array();\n\n\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\tif ( !select_items ) {\n\t\t\t\t\tthis.setEmptyLabel();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar len = select_items.length;\n\t\t\t\tif ( len === 1 ) {\n\n\t\t\t\t\tvar display_column_len = display_columns.length;\n\t\t\t\t\tfor ( y = 0; y < display_column_len; y++ ) {\n\n\t\t\t\t\t\tif ( display_columns[y].hidden === true ) { //Hidden field for jGgrid, usually is id\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( layout_name === 'global_sort_columns' && select_items[0][display_columns[y].name] === undefined ) {\n\t\t\t\t\t\t\tvar item = select_items[0];\n\n\t\t\t\t\t\t\tfor ( var key in item ) {\n\t\t\t\t\t\t\t\tvar c_value = key + ' | ' + item[key];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t//When sort field has source data, use proper label shown on the dropdown.\n\t\t\t\t\t\t\tif ( source_data ) {\n\t\t\t\t\t\t\t\tfor ( var i = 0; i < source_data.length; i++ ) {\n\t\t\t\t\t\t\t\t\tvar column = source_data[i];\n\n\t\t\t\t\t\t\t\t\tif ( column.value === key ) {\n\t\t\t\t\t\t\t\t\t\tvar c_value = column.label + ' | ' + item[key];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( c_value !== 0 && c_value == '' ) {\n\t\t\t\t\t\t\t\tc_value = '--';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlabel_arr.push( c_value );\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar c_value = select_items[0][display_columns[y].name];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( c_value !== 0 && c_value == '' ) {\n\t\t\t\t\t\t\tc_value = '--';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( c_value === 0 || c_value ) {\n\t\t\t\t\t\t\tlabel_arr.push( c_value );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( label_arr.length > 0 ) {\n\t\t\t\t\t\tlabel_span.text( label_arr.join( ' | ' ) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setEmptyLabel();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlabel_span.text( len + ' ' + $.i18n._( 'items selected' ) );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Error: Uncaught TypeError: Cannot read property 'length' of null in interface/html5/global/widgets/awesomebox/AComboBox.js?v=9.0.6-20151231-140748 line 902\n\t\t\t\tif ( !select_item || !display_columns ) {\n\t\t\t\t\tthis.setEmptyLabel();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tdisplay_column_len = display_columns.length;\n\t\t\t\tfor ( var y = 0; y < display_column_len; y++ ) {\n\t\t\t\t\tif ( display_columns[y].hidden === true ) { //Hidden field for jGgrid, usually is id\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tc_value = select_item[display_columns[y].name];\n\n\t\t\t\t\tif ( c_value !== 0 && c_value == '' ) {\n\t\t\t\t\t\tc_value = '--';\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( c_value === 0 || c_value ) {\n\t\t\t\t\t\tlabel_arr.push( c_value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( label_arr.length > 0 ) {\n\t\t\t\t\tlabel_span.text( label_arr.join( ' | ' ) );\n\t\t\t\t} else {\n\t\t\t\t\tthis.setEmptyLabel();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$this.find( '.a-combobox-label' ).width( 'auto' );\n\t\t};\n\n\t\tthis.setEmptyLabel = function() {\n\t\t\tif ( set_any ) {\n\t\t\t\tlabel_span.text( Global.any_item );\n\t\t\t} else if ( set_empty || set_special_empty ) {\n\t\t\t\tif ( layout_name === 'global_tree_column' ) {\n\t\t\t\t\tlabel_span.text( Global.root_item );\n\t\t\t\t} else {\n\t\t\t\t\tlabel_span.text( Global.empty_item );\n\t\t\t\t}\n\t\t\t} else if ( set_default ) {\n\t\t\t\tlabel_span.text( Global.default_item );\n\t\t\t} else if ( set_open ) {\n\t\t\t\tlabel_span.text( Global.open_item );\n\t\t\t} else {\n\t\t\t\tif ( source_data && source_data.length > 0 ) {\n\t\t\t\t\tvar first_item = source_data[0];\n\n\t\t\t\t\tif ( first_item.hasOwnProperty( 'label' ) ) {\n\t\t\t\t\t\tlabel_span.text( first_item.label );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( custom_first_label ) {\n\t\t\t\tlabel_span.text( custom_first_label );\n\t\t\t}\n\n\t\t};\n\n\t\tthis.onColumnSettingSaveFromLayout = function( layout ) {\n\t\t\tvar filter = {};\n\t\t\tfilter.script = 'global_awesomebox_columns';\n\t\t\tfilter.name = layout_name;\n\t\t\tfilter.is_default = 'false';\n\n\t\t\tfilter.data = layout.data;\n\t\t\tfilter.data.type = 10;\n\t\t\tfilter.data.layout_id = layout.id;\n\n\t\t\tif ( ALayoutCache.layout_dic[layout_name] ) {\n\t\t\t\tfilter.id = ALayoutCache.layout_dic[layout_name].id;\n\t\t\t}\n\n\t\t\tuser_generic_api.setUserGenericData( filter, {\n\t\t\t\tonResult: function( res ) {\n\t\t\t\t\tALayoutCache.layout_dic[layout_name] = null;\n\t\t\t\t\t$this.initColumns();\n\t\t\t\t\tsource_data = null; //Reload source data if column changed\n\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\n\t\tthis.onColumnSettingSave = function( seletedColumns, rowsPerPageNumber, layout_id, filter_data ) {\n\n\t\t\tvar filter = {};\n\t\t\tfilter.script = 'global_awesomebox_columns';\n\t\t\tfilter.name = layout_name;\n\t\t\tfilter.is_default = 'false';\n\t\t\tfilter.type = 1; //ALayoutType.customize\n\n\t\t\tif ( ALayoutCache.layout_dic[layout_name] ) {\n\t\t\t\tfilter.id = ALayoutCache.layout_dic[layout_name].id;\n\t\t\t}\n\n\t\t\tvar select_columns_in_JSON = [];\n\t\t\tvar len = seletedColumns.length;\n\n\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\tvar column_in_JSON = {\n\t\t\t\t\tlabel: seletedColumns[i].label,\n\t\t\t\t\tvalue: seletedColumns[i].value,\n\t\t\t\t\torderValue: seletedColumns[i].orderValue\n\t\t\t\t};\n\t\t\t\tselect_columns_in_JSON.push( column_in_JSON );\n\t\t\t}\n\n\t\t\tfilter.data = {\n\t\t\t\tdisplay_columns: select_columns_in_JSON,\n\t\t\t\trow_per_page: rowsPerPageNumber,\n\t\t\t\tlayout_id: layout_id,\n\t\t\t\tfilter_data: filter_data\n\t\t\t};\n\n\t\t\t//Error: TypeError: user_generic_api is null in /interface/html5/global/widgets/awesomebox/AComboBox.js?v=9.0.0-20150822-090205 line 987\n\t\t\tif ( !user_generic_api ) {\n\t\t\t\tuser_generic_api = TTAPI.APIUserGenericData;\n\t\t\t}\n\t\t\tuser_generic_api.setUserGenericData( filter, {\n\t\t\t\tonResult: function( res ) {\n\t\t\t\t\tALayoutCache.layout_dic[layout_name] = null;\n\n\t\t\t\t\t$this.initColumns();\n\n\t\t\t\t\tsource_data = null; //Reload source data if column changed\n\n\t\t\t\t\t//Reload real data if columns have changed, so they display data for any new columns\n\t\t\t\t\t// We can't just pass in the selected_items verbatim here, we need to parse off the 'id' fields and pass that in as an array instead.\n\t\t\t\t\tif ( $.type( select_items ) === 'array' ) {\n\t\t\t\t\t\tselect_items = select_items.map( function( obj ) {\n\t\t\t\t\t\t\tif ( obj.hasOwnProperty( 'id' ) ) {\n\t\t\t\t\t\t\t\treturn obj['id'];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\t//Don't try to load data from the API if there is no filter criteria, as everything is likely be returned and therefore will be selected.\n\t\t\t\t\t// This would manifest itself by expanding a dropdown without anything selected in it, then changing the columns.\n\t\t\t\t\tif ( select_items ) {\n\t\t\t\t\t\t$this.getRealData( select_items );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t};\n\n\t\t//Set columns, display columns will be used when open AwesomeBox. If no layout saved. Display columns are the default ones set in this.each\n\t\tthis.initColumns = function() {\n\n\t\t\tuser_generic_api = TTAPI.APIUserGenericData;\n\n\t\t\t//Error: TypeError: 'undefined' is not a function (evaluating 'user_generic_api.getUserGenericData') in /interface/html5/global/widgets/awesomebox/AComboBox.js?v=8.0.0-20141117-095711 line 1044\n\t\t\tif ( !user_generic_api || !user_generic_api.getUserGenericData || typeof ( user_generic_api.getUserGenericData ) !== 'function' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( Global.isSet( ALayoutCache.layout_dic[layout_name] ) ) {\n\t\t\t\tif ( ALayoutCache.layout_dic[layout_name].pending ) {\n\t\t\t\t\tTTPromise.add( 'AComboBox', layout_name );\n\t\t\t\t\tTTPromise.wait( 'AComboBox', layout_name, function() {\n\t\t\t\t\t\tinitColumnsFromCache( layout_name );\n\t\t\t\t\t} );\n\t\t\t\t} else {\n\t\t\t\t\tinitColumnsFromCache( layout_name );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t//Set cache to pending to stop multiple calls to the API for the same layout_name.\n\t\t\t\tALayoutCache.layout_dic[layout_name] = { pending: true };\n\t\t\t\tvar filter = {};\n\t\t\t\tfilter.filter_data = { script: 'global_awesomebox_columns', name: layout_name };\n\t\t\t\tuser_generic_api.getUserGenericData( filter, {\n\t\t\t\t\tonResult: function( res ) {\n\n\t\t\t\t\t\tvar resData = res.getResult();\n\t\t\t\t\t\t//Set this here so Column setting dialog can get correct display columns before open Awesomebox\n\t\t\t\t\t\tif ( resData && resData.length > 0 ) {\n\n\t\t\t\t\t\t\tvar data = resData[0].data;\n\n\t\t\t\t\t\t\t//if saved layout is saved view layout. get it\n\t\t\t\t\t\t\tif ( data.type === 10 ) {\n\n\t\t\t\t\t\t\t\tvar columns_result_data = api.getOptions( column_option_key, { async: false } ).getResult();\n\t\t\t\t\t\t\t\tall_columns = Global.buildColumnArray( columns_result_data );\n\n\t\t\t\t\t\t\t\tvar saved_layout_result = user_generic_api.getUserGenericData( {\n\t\t\t\t\t\t\t\t\tfilter_data: {\n\t\t\t\t\t\t\t\t\t\tid: data.layout_id,\n\t\t\t\t\t\t\t\t\t\tdeleted: false\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}, { async: false } ).getResult();\n\n\t\t\t\t\t\t\t\tif ( saved_layout_result && saved_layout_result.length > 0 ) {\n\t\t\t\t\t\t\t\t\tvar saved_layout = saved_layout_result.slice()[0];\n\t\t\t\t\t\t\t\t\tvar new_data = saved_layout.data;\n\t\t\t\t\t\t\t\t\tnew_data.display_columns = $this.buildDisplayColumns( new_data.display_columns );\n\t\t\t\t\t\t\t\t\tnew_data.filter_data = Global.convertLayoutFilterToAPIFilter( saved_layout );\n\t\t\t\t\t\t\t\t\tresData[0].data.display_columns = new_data.display_columns;\n\t\t\t\t\t\t\t\t\tresData[0].data.filter_data = new_data.filter_data;\n\n\t\t\t\t\t\t\t\t\tdata = resData[0].data;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tdata.filter_data = []; // if saved layou is deleted.\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tALayoutCache.layout_dic[layout_name] = resData[0];\n\n\t\t\t\t\t\t\tALayoutCache.layout_dic[$this.getScriptName()] = layout_name; // bind current view name to layout name;\n\n\t\t\t\t\t\t\tif ( Global.isSet( data.type ) && data.type === 10 ) {\n\n\t\t\t\t\t\t\t\tdisplay_columns = data.display_columns;\n\t\t\t\t\t\t\t\tif ( display_columns.length > 0 ) {\n\t\t\t\t\t\t\t\t\tif ( possible_display_columns ) {\n\t\t\t\t\t\t\t\t\t\tdisplay_columns = filterBaseOnPossibleColumns( display_columns );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( display_columns, layout_name, function( width ) {\n\t\t\t\t\t\t\t\t\t\ttotal_header_width = width;\n\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t} else if ( list_view_default_columns ) {\n\t\t\t\t\t\t\t\t\tdisplay_columns = list_view_default_columns;\n\t\t\t\t\t\t\t\t\tdisplay_columns = filterBaseOnPossibleColumns( display_columns );\n\t\t\t\t\t\t\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( display_columns, layout_name, function( width ) {\n\t\t\t\t\t\t\t\t\t\ttotal_header_width = width;\n\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\targs_from_saved_layout = {};\n\t\t\t\t\t\t\t\targs_from_saved_layout.filter_data = data.filter_data;\n\t\t\t\t\t\t\t\targs_from_saved_layout.filter_sort = data.filter_sort;\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tdisplay_columns = data.display_columns;\n\n\t\t\t\t\t\t\t\t//Happen when save no columns in column setting for navigation mode\n\t\t\t\t\t\t\t\tif ( display_columns.length > 0 ) {\n\t\t\t\t\t\t\t\t\tif ( possible_display_columns ) {\n\t\t\t\t\t\t\t\t\t\tdisplay_columns = filterBaseOnPossibleColumns( display_columns );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( display_columns, layout_name, function( width ) {\n\t\t\t\t\t\t\t\t\t\ttotal_header_width = width;\n\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t} else if ( list_view_default_columns ) {\n\t\t\t\t\t\t\t\t\tdisplay_columns = list_view_default_columns;\n\t\t\t\t\t\t\t\t\tdisplay_columns = filterBaseOnPossibleColumns( display_columns );\n\t\t\t\t\t\t\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( display_columns, layout_name, function( width ) {\n\t\t\t\t\t\t\t\t\t\ttotal_header_width = width;\n\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\trow_per_page = data.row_per_page;\n\t\t\t\t\t\t\t\targs_from_saved_layout = null;\n//\t\t\t\t\t\t\tif ( !navigation_mode && !set_default_args_manually ) {\n//\t\t\t\t\t\t\t\tdefault_args = null;\n//\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t//If set possible columns, use it\n\t\t\t\t\t\t\tif ( list_view_default_columns ) {\n\t\t\t\t\t\t\t\tdisplay_columns = list_view_default_columns;\n\t\t\t\t\t\t\t\tdisplay_columns = filterBaseOnPossibleColumns( display_columns );\n\t\t\t\t\t\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( display_columns, layout_name, function( width ) {\n\t\t\t\t\t\t\t\t\ttotal_header_width = width;\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tALayoutCache.layout_dic[layout_name] = false;\n\t\t\t\t\t\t\trow_per_page = 0;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( init_data_immediately ) {\n\t\t\t\t\t\t\t$this.initSourceData();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tTTPromise.resolve( 'AComboBox', layout_name );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t};\n\n\t\tvar initColumnsFromCache = function( layout_name ) {\n\t\t\t//Set this here so Column setting dialog can get correct display columns before open Awesomebox\n\t\t\tif ( Global.isSet( ALayoutCache.layout_dic[layout_name].data ) ) {\n\n\t\t\t\tvar data = ALayoutCache.layout_dic[layout_name].data;\n\n\t\t\t\tif ( Global.isSet( data.type ) && data.type === 10 ) {\n\t\t\t\t\tdisplay_columns = data.display_columns;\n\n\t\t\t\t\tif ( display_columns.length > 0 ) {\n\t\t\t\t\t\tif ( possible_display_columns ) {\n\t\t\t\t\t\t\tdisplay_columns = filterBaseOnPossibleColumns( display_columns );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( display_columns, layout_name, function( width ) {\n\t\t\t\t\t\t\ttotal_header_width = width;\n\t\t\t\t\t\t} );\n\t\t\t\t\t} else if ( list_view_default_columns ) {\n\t\t\t\t\t\tdisplay_columns = list_view_default_columns;\n\t\t\t\t\t\tdisplay_columns = filterBaseOnPossibleColumns( display_columns );\n\t\t\t\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( display_columns, layout_name, function( width ) {\n\t\t\t\t\t\t\ttotal_header_width = width;\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\targs_from_saved_layout = {};\n\t\t\t\t\targs_from_saved_layout.filter_data = data.filter_data;\n\t\t\t\t\targs_from_saved_layout.filter_sort = data.filter_sort;\n\n\t\t\t\t} else {\n\t\t\t\t\tdisplay_columns = data.display_columns;\n\n\t\t\t\t\tif ( display_columns.length > 0 ) {\n\t\t\t\t\t\tif ( possible_display_columns ) {\n\t\t\t\t\t\t\tdisplay_columns = filterBaseOnPossibleColumns( display_columns );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( display_columns, layout_name, function( width ) {\n\t\t\t\t\t\t\ttotal_header_width = width;\n\t\t\t\t\t\t} );\n\t\t\t\t\t} else if ( possible_display_columns ) {\n\t\t\t\t\t\tdisplay_columns = possible_display_columns;\n\t\t\t\t\t}\n\t\t\t\t\trow_per_page = data.row_per_page;\n\t\t\t\t\tif ( !navigation_mode && !set_default_args_manually ) {\n\t\t\t\t\t\tdefault_args = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tif ( list_view_default_columns ) {\n\t\t\t\t\tdisplay_columns = list_view_default_columns;\n\t\t\t\t\tdisplay_columns = filterBaseOnPossibleColumns( display_columns );\n\t\t\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( display_columns, layout_name, function( width ) {\n\t\t\t\t\t\ttotal_header_width = width;\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\trow_per_page = 0;\n\t\t\t}\n\t\t\tif ( init_data_immediately ) {\n\t\t\t\t$this.initSourceData();\n\t\t\t}\n\t\t}\n\n\t\tvar filterBaseOnPossibleColumns = function( display_columns ) {\n\n\t\t\t//Error: Unable to get property 'length' of undefined or null reference in /interface/html5/global/widgets/awesomebox/AComboBox.js?v=8.0.0-20141230-125406 line 1169\n\t\t\tif ( !possible_display_columns ) {\n\t\t\t\treturn display_columns;\n\t\t\t}\n\n\t\t\tvar len = possible_display_columns.length;\n\n\t\t\tvar result = [];\n\t\t\tfor ( var j = 0; j < display_columns.length; j++ ) {\n\t\t\t\tvar dis_column = display_columns[j];\n\t\t\t\tvar found = false;\n\t\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\t\tvar column = possible_display_columns[i];\n\t\t\t\t\tif ( column.value === dis_column.value ) {\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( found ) {\n\t\t\t\t\tresult.push( dis_column );\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( result.length === 0 ) {\n\t\t\t\tresult = possible_display_columns;\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t};\n\n\t\tthis.getId = function() {\n\t\t\treturn id;\n\t\t};\n\n\t\t//update source data to new saved item, happens in timesheet view, edit employee\n\t\tthis.updateSelectItem = function( new_item ) {\n\t\t\tselect_item = new_item;\n\t\t\tif ( source_data ) {\n\n\t\t\t\tfor ( var i = 0; i < source_data.length; i++ ) {\n\t\t\t\t\tvar content = source_data[i];\n\t\t\t\t\tif ( content.id === new_item.id ) {\n\t\t\t\t\t\tsource_data[i] = new_item;\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getADropDown = function() {\n\t\t\treturn a_dropdown_div;\n\t\t};\n\n\t\tthis.onClose = function( e, target ) {\n\t\t\tif ( a_dropdown == undefined ) {\n\t\t\t\tDebug.Text( 'ERROR: Unable to close AComboBox check to make sure it wasn\\'t instantiated twice.', 'ACombobox.js', 'ACombobox', 'onClose', 10 );\n\t\t\t}\n\n\t\t\t//In the case where a user double clicks a drop-down box to expand it, that can cause it to open the close again immediately, and show a \"-- NONE --\" even though something was previously selected.\n\t\t\t// Therefore if the 'init' promise is still pending because the data is still loading, simply don't close it yet.\n\t\t\tvar pending_promise = TTPromise.isPendingPromises( 'AComboBox', 'init' );\n\t\t\tif ( pending_promise == false ) {\n\t\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\t\t//Re load source_data if select items\n\t\t\t\t\tvar select_items = a_dropdown.getSelectItems();\n\t\t\t\t\t$this.setValue( select_items );\n\t\t\t\t} else {\n\t\t\t\t\tvar select_item = a_dropdown.getSelectItem();\n\t\t\t\t\tif ( select_item ) { // #2593 - null is not an object (evaluating 'select_item._id_')\n\t\t\t\t\t\tif ( !tree_mode ) {\n\t\t\t\t\t\t\t$this.setValue( select_item );\n\t\t\t\t\t\t} else if ( select_item._id_ ) {\n\t\t\t\t\t\t\t$this.setValue( select_item._id_ );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDebug.Text( 'WARNING: AComboBox::Init promise still pending, cant call setValue()...', 'ACombobox.js', 'ACombobox', 'onClose', 10 );\n\t\t\t}\n\n\t\t\ta_dropdown_div.remove();\n\t\t\tis_mouse_over = false; //When close from esc, this maybe true\n\t\t\tLocalCacheData.openAwesomeBox = null;\n\t\t\tif ( a_dropdown.isChanged() || layout_name === 'global_sort_columns' ) {\n\t\t\t\tif ( check_box ) {\n\t\t\t\t\t$this.setCheckBox( true );\n\t\t\t\t}\n\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t}\n\t\t\t$this.trigger( 'onClose', [$this] );\n\t\t\tdontOpen = true;\n\t\t\tdontOpenTimer = setTimeout( function() {\n\t\t\t\tdontOpen = false;\n\t\t\t}, 200 );\n\t\t\t$this.find( '.focus-input' ).focus();\n\t\t};\n\n\t\t//set next or last item when key down, call from main.js\n\t\tthis.selectNextItem = function( e ) {\n\n\t\t\tvar select_index = this.getSelectIndex();\n\t\t\tvar next_index;\n\t\t\tvar target_grid;\n\t\t\tif ( e.keyCode === 40 ) { //Down\n\t\t\t\te.preventDefault();\n\t\t\t\tif ( !allow_multiple_selection ) {\n\t\t\t\t\tif ( select_index === 0 ) {\n\t\t\t\t\t\tnext_index = 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnext_index = select_index + 1;\n\t\t\t\t\t}\n\t\t\t\t\tvar next_select_item = this.getItemByIndex( next_index );\n\n\t\t\t\t\tif ( !next_select_item ) {\n\t\t\t\t\t\tnext_index = next_index - 1;\n\t\t\t\t\t\tnext_select_item = this.getItemByIndex( next_index );\n\t\t\t\t\t}\n\t\t\t\t\tselect_item = next_select_item;\n\t\t\t\t\ta_dropdown.setSelectItem( next_select_item );\n\t\t\t\t\ta_dropdown.setIsChanged( true );\n\t\t\t\t}\n\t\t\t} else if ( e.keyCode === 38 ) { //Up\n\t\t\t\te.preventDefault();\n\t\t\t\tif ( !allow_multiple_selection ) {\n\t\t\t\t\tif ( select_index === 0 ) {\n\t\t\t\t\t\tnext_index = 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnext_index = select_index - 1;\n\t\t\t\t\t}\n\n\t\t\t\t\tnext_select_item = this.getItemByIndex( next_index );\n\t\t\t\t\tselect_item = next_select_item;\n\t\t\t\t\ta_dropdown.setSelectItem( next_select_item );\n\t\t\t\t\ta_dropdown.setIsChanged( true );\n\t\t\t\t}\n\t\t\t} else if ( e.keyCode === 39 ) { //right\n\t\t\t\tif ( allow_multiple_selection && !$( e.target ).hasClass( 'search-input' ) ) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\ta_dropdown.onUnSelectGridDoubleClick();\n\t\t\t\t\ta_dropdown.setIsChanged( true );\n\t\t\t\t}\n\t\t\t} else if ( e.keyCode === 37 ) { //left\n\t\t\t\tif ( allow_multiple_selection && !$( e.target ).hasClass( 'search-input' ) ) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\ta_dropdown.onSelectGridDoubleClick();\n\t\t\t\t\ta_dropdown.setIsChanged( true );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( quick_search_timer ) {\n\t\t\t\t\tclearTimeout( quick_search_timer );\n\t\t\t\t}\n\t\t\t\tvar focus_target = $( ':focus' );\n\t\t\t\tif ( focus_target.length > 0 && $( focus_target[0] ).hasClass( 'search-input' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tquick_search_timer = setTimeout( function() {\n\t\t\t\t\tquick_search_typed_keys = '';\n\t\t\t\t}, 750 );\n\t\t\t\te.preventDefault();\n\n\t\t\t\tquick_search_typed_keys = quick_search_typed_keys + String.fromCharCode( e.which ).toLowerCase();\n\t\t\t\tDebug.Text( 'Quick search typed keys: ' + quick_search_typed_keys, 'AComboBox.js', 'AComboBox', 'selectNextItem', 10 );\n\t\t\t\tvar trimmed_quick_search_typed_keys = quick_search_typed_keys.trim();\n\n\t\t\t\tif ( allow_multiple_selection || tree_mode ) {\n\t\t\t\t\tif ( trimmed_quick_search_typed_keys ) {\n\t\t\t\t\t\ttarget_grid = a_dropdown.getFocusInSeletGrid() ? a_dropdown.getSelectGrid() : a_dropdown.getUnSelectGrid();\n\n\t\t\t\t\t\tvar search_index = quick_search_dic[trimmed_quick_search_typed_keys] ? quick_search_dic[trimmed_quick_search_typed_keys] : 0;\n\t\t\t\t\t\tvar tds = $( target_grid.grid.find( 'tr' ).find( 'td:eq(1)' ).filter( function() {\n\t\t\t\t\t\t\treturn $.text( [this] ).toLowerCase().indexOf( trimmed_quick_search_typed_keys ) == 0;\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t\tvar td;\n\t\t\t\t\t\tif ( search_index > 0 && search_index < tds.length ) {\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsearch_index = 0;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttd = $( tds[search_index] );\n\t\t\t\t\t\ta_dropdown.unSelectAll( target_grid.grid, true );\n\t\t\t\t\t\t//next_index = td.parent().index() - 1;\n\n\t\t\t\t\t\tvar next_select_item = false;\n\t\t\t\t\t\tvar grid_data = target_grid.getData();\n\t\t\t\t\t\tfor ( var z = 0; z < grid_data.length; z++ ) {\n\t\t\t\t\t\t\tif ( grid_data[z].id == td.parents( 'tr' ).attr( 'id' ) ) {\n\t\t\t\t\t\t\t\tnext_select_item = grid_data[z];\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tselect_item = next_select_item;\n\n\t\t\t\t\t\ta_dropdown.setSelectItem( next_select_item, target_grid );\n\t\t\t\t\t\ta_dropdown.setIsChanged( true );\n\t\t\t\t\t\tquick_search_dic = {};\n\t\t\t\t\t\tquick_search_dic[trimmed_quick_search_typed_keys] = search_index + 1;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( trimmed_quick_search_typed_keys ) {\n\t\t\t\t\t\tsearch_index = quick_search_dic[trimmed_quick_search_typed_keys] ? quick_search_dic[trimmed_quick_search_typed_keys] : 0;\n\t\t\t\t\t\ttds = $( a_dropdown.getUnSelectGrid().grid.find( 'tr' ).find( 'td:first' ).filter( function() {\n\t\t\t\t\t\t\treturn $.text( [this] ).toLowerCase().indexOf( trimmed_quick_search_typed_keys ) == 0;\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t\tif ( search_index > 0 && search_index < tds.length ) {\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsearch_index = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttd = $( tds[search_index] );\n\t\t\t\t\t\tnext_index = td.parent().index() - 1;\n\t\t\t\t\t\tnext_select_item = this.getItemByIndex( next_index );\n\t\t\t\t\t\tselect_item = next_select_item;\n\t\t\t\t\t\ta_dropdown.setSelectItem( next_select_item );\n\t\t\t\t\t\tquick_search_dic = {};\n\t\t\t\t\t\tquick_search_dic[trimmed_quick_search_typed_keys] = search_index + 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.gridScrollTop = function() {\n\n\t\t\tif ( !a_dropdown ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ta_dropdown.gridScrollTop();\n\t\t};\n\n\t\tthis.gridScrollDown = function() {\n\n\t\t\tif ( !a_dropdown ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ta_dropdown.gridScrollDown();\n\t\t};\n\n\t\tthis.selectAll = function() {\n\t\t\tif ( !a_dropdown || tree_mode || !allow_multiple_selection ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ta_dropdown.selectAll();\n\n\t\t};\n\n\t\tthis.getIsMouseOver = function() {\n\t\t\treturn is_mouse_over;\n\t\t};\n\n\t\tthis.onShowAll = function( isShowAll ) {\n\t\t\tshow_all = isShowAll;\n\n\t\t\tvar args = this.buildUnSelectGridFilter();\n\t\t\targs = this.addExcludeIDsToFilter( args, a_dropdown.getSelectItems() );\n\n\t\t\tapi['get' + custom_key_name]( args, {\n\t\t\t\tonResult: function( result ) {\n\n\t\t\t\t\tvar result_data = result.getResult();\n\n\t\t\t\t\tif ( !result_data ) {\n\t\t\t\t\t\tresult_data = [];\n\t\t\t\t\t}\n\n\t\t\t\t\tpager_data = result.getPagerData();\n\t\t\t\t\tsource_data = result_data;\n\n\t\t\t\t\tif ( Global.isSet( api ) ) {\n\t\t\t\t\t\tsource_data = Global.formatGridData( source_data, api.key_name );\n\t\t\t\t\t}\n\n\t\t\t\t\ta_dropdown.setUnselectedGridData( source_data );\n\t\t\t\t\t//a_dropdown.setSelectGridData( a_dropdown.getSelectItems() );\n\t\t\t\t\ta_dropdown.setPagerData( pager_data );\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\n\t\tthis.buildUnSelectGridFilter = function( exclude_ids = null ) {\n\t\t\tvar args = {};\n\t\t\targs.filter_data = {};\n\t\t\targs.filter_columns = $this.getColumnFilter();\n\t\t\targs.filter_items_per_page = row_per_page;\n\n\t\t\tif ( a_dropdown ) {\n\t\t\t\t//use clone so the view search condition not be set when set default args\n\t\t\t\targs.filter_data = Global.clone( a_dropdown.getUnSelectGridMap() );\n\t\t\t\targs.filter_sort = Global.clone( a_dropdown.getUnSelectGridSortMap() );\n\t\t\t}\n\n\t\t\tif ( args_from_saved_layout ) {\n\t\t\t\tif ( Global.isSet( args_from_saved_layout.filter_data ) ) {\n\t\t\t\t\tfor ( var key in args_from_saved_layout.filter_data ) {\n\t\t\t\t\t\tif ( !args.filter_data.hasOwnProperty( key ) ) {\n\t\t\t\t\t\t\targs.filter_data[key] = args_from_saved_layout.filter_data[key];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( args_from_saved_layout && Global.isSet( args_from_saved_layout.permission_section ) ) {\n\t\t\t\t\targs.permission_section = args_from_saved_layout.permission_section;\n\t\t\t\t}\n\n\t\t\t\t//Do not override sort condition\n\t\t\t\tif ( Global.isSet( args_from_saved_layout.filter_sort ) && !args.filter_sort ) {\n\n\t\t\t\t\targs.filter_sort = args_from_saved_layout.filter_sort;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//default_args is set when navigation mode usually. To keep search filter same as list view grid\n\t\t\t//. In BaseController, setEditViewData function\n\t\t\tif ( default_args ) {\n\n\t\t\t\tif ( Global.isSet( default_args.filter_data ) ) {\n\t\t\t\t\tfor ( var key in default_args.filter_data ) {\n\t\t\t\t\t\tif ( !args.filter_data.hasOwnProperty( key ) ) {\n\t\t\t\t\t\t\targs.filter_data[key] = default_args.filter_data[key];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( default_args && Global.isSet( default_args.permission_section ) ) {\n\t\t\t\t\targs.permission_section = default_args.permission_section;\n\t\t\t\t}\n\n\t\t\t\t//Do not override sort condition\n\t\t\t\tif ( Global.isSet( default_args.filter_sort ) && !args.filter_sort ) {\n\n\t\t\t\t\targs.filter_sort = default_args.filter_sort;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t//If it has additional search condition from outside viewcontroller\n\t\t\tif ( this.customSearchFilter ) {\n\t\t\t\targs = this.customSearchFilter( args );\n\t\t\t}\n\n\t\t\tif ( show_all ) {\n\t\t\t\targs.second_parameter = true;\n\t\t\t}\n\n\t\t\t// When using ACombo, at this point a_dropdown.getSelectItems() might be empty, but $this.getValue()/select_items has the selected IDs instead. They are in a different format though.\n\t\t\t// This is also required in cases where an employee has 50 items, 48 are already selected, and pagination is set to 5 items per row.\n\t\t\t// Then on the unselected side click to sort by \"Last Name\" a couple times. These exclude_ids must be passed to the API so no matter what all the unselected rows are always returned, just in the proper sort order.\n\t\t\tif ( exclude_ids ) {\n\t\t\t\targs = this.addExcludeIDsToFilter( args, exclude_ids );\n\t\t\t}\n\n\t\t\treturn args;\n\t\t};\n\n\t\tthis.addExcludeIDsToFilter = function( args, exclude_ids ) {\n\t\t\tif ( a_dropdown && args && exclude_ids ) { //#2353 - js exception when a_dropdown is not defined yet\n\t\t\t\tvar selected_ids = exclude_ids;\n\t\t\t\tif ( selected_ids && Global.isArray( selected_ids ) && selected_ids.length > 0 && selected_ids[0] != TTUUID.zero_id ) {\n\t\t\t\t\targs.filter_data.exclude_id = [];\n\t\t\t\t\tfor ( var x in selected_ids ) {\n\t\t\t\t\t\t// Issue #2899 - Selected items can either be an array of IDs or an object. Need to account for either situation.\n\t\t\t\t\t\tif ( selected_ids[x].id ) {\n\t\t\t\t\t\t\targs.filter_data.exclude_id.push( selected_ids[x].id );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\targs.filter_data.exclude_id.push( selected_ids[x] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn args;\n\t\t}\n\n\t\tthis.buildSelectGridFilter = function() {\n\t\t\tvar args = {};\n\t\t\targs.filter_columns = $this.getColumnFilter();\n\t\t\targs.filter_items_per_page = row_per_page;\n\t\t\targs.filter_data = a_dropdown.getSelectGridMap();\n\t\t\targs.filter_sort = a_dropdown.getSelectGridSortMap();\n\t\t\targs.second_parameter = true; //Always set true because we want alwasy set all data out in select grid\n\n\t\t\treturn args;\n\t\t};\n\n\t\tthis.searchIsEmpty = function( a_dropdown ) {\n\t\t\tvar inputs = a_dropdown.find( 'input.search-input' );\n\t\t\tfor ( var i = 0; i < inputs.length; i++ ) {\n\t\t\t\tif ( $( inputs[i] ).val() != $.i18n._( 'click to search' ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tthis.onADropDownSearch = function( targetName, page_action, default_select_item, callBack, trigger_form_item_change = true ) {\n\t\t\tvar this_val = this.getValue();\n\t\t\tif ( targetName == 'select_grid' && this_val.length == 0 || ( targetName == 'select_grid' && this_val.length == 1 && this_val[0] == TTUUID.not_exist_id ) ) {\n\t\t\t\t//#2353 - prevent bug where sorted empty select grid selects everything\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar args = {};\n\t\t\targs.filter_columns = $this.getColumnFilter();\n\t\t\targs.filter_items_per_page = row_per_page;\n\t\t\tif ( targetName === 'unselect_grid' ) {\n\t\t\t\t//When using pagination and first opening the dropdown box, we need to exclude the selected items from the API call\n\t\t\t\t// so the first page will always be populated with a full page of records.\n\t\t\t\targs = $this.buildUnSelectGridFilter( ( ( a_dropdown ) ? a_dropdown.getSelectItems() : null ) ); //Handle JS exception: Error: Cannot read property 'getSelectItems' of null\n\n\t\t\t\t//Error: Unable to get property 'current_page' of undefined or null reference in /interface/html5/global/widgets/awesomebox/AComboBox.js?v=7.4.6-20141027-070003 line 1489\n\t\t\t\tif ( a_dropdown && a_dropdown.getPagerData() ) {\n\t\t\t\t\tif ( LocalCacheData.paging_type === 0 ) {\n\t\t\t\t\t\tif ( page_action === 'next' ) {\n\t\t\t\t\t\t\targs.filter_page = a_dropdown.getPagerData().next_page;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\targs.filter_page = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tswitch ( page_action ) {\n\t\t\t\t\t\t\tcase 'next':\n\t\t\t\t\t\t\t\targs.filter_page = a_dropdown.getPagerData().next_page;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'last':\n\t\t\t\t\t\t\t\targs.filter_page = a_dropdown.getPagerData().previous_page;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'start':\n\t\t\t\t\t\t\t\targs.filter_page = 1;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'end':\n\t\t\t\t\t\t\t\targs.filter_page = a_dropdown.getPagerData().last_page_number;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\targs.filter_page = a_dropdown.getPagerData().current_page;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( parseInt( page_action ) >= 1 ) {\n\t\t\t\t\targs.filter_page = page_action;\n\t\t\t\t}\n\n\t\t\t\tapi['get' + custom_key_name]( args, {\n\t\t\t\t\tonResult: function( result ) {\n\n\t\t\t\t\t\tvar focused_element = $( ':focus' );\n\n\t\t\t\t\t\tvar result_data = result.getResult();\n\n\t\t\t\t\t\tif ( !Global.isArray( result_data ) ) {\n\t\t\t\t\t\t\tresult_data = [];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//set this outside, to add more data to source_data\n\t\t\t\t\t\tif ( addition_source_function ) {\n\t\t\t\t\t\t\tresult_data = addition_source_function( $this, result_data );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( LocalCacheData.paging_type === 0 && page_action === 'next' ) {\n\t\t\t\t\t\t\tvar current_data = a_dropdown.getUnSelectGridData();\n\t\t\t\t\t\t\tresult_data = current_data.concat( result_data );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( navigation_mode ) {\n\t\t\t\t\t\t\tsource_data = result_data;\n\t\t\t\t\t\t\tpager_data = result.getPagerData();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tunselect_grid_search_result = result_data;\n\t\t\t\t\t\t\tcurrent_open_page = result.getPagerData().current_page;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( $.type( result_data ) != 'array' ) {\n\t\t\t\t\t\t\tresult_data = [];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( !allow_multiple_selection ) {\n\t\t\t\t\t\t\t$this.createFirstItem( result_data );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresult_data = Global.formatGridData( result_data, api.key_name );\n\n\t\t\t\t\t\tif ( extendDataProcessWhenSearch ) {\n\t\t\t\t\t\t\tresult_data = extendDataProcessWhenSearch( result_data );\n\t\t\t\t\t\t}\n\t\t\t\t\t\ta_dropdown && a_dropdown.setUnselectedGridData( result_data );\n\n\t\t\t\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\t\t\t\ta_dropdown && a_dropdown.setSelectGridData( a_dropdown.getSelectItems(), true );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ta_dropdown && a_dropdown.setSelectItem( a_dropdown.getSelectItem() );\n\t\t\t\t\t\t\tif ( default_select_item == 'first' ) {\n\t\t\t\t\t\t\t\t$this.setValue( result_data[0] );\n\t\t\t\t\t\t\t\tif ( trigger_form_item_change == true ) {\n\t\t\t\t\t\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( callBack ) {\n\t\t\t\t\t\t\t\t\tcallBack( result_data[0] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( default_select_item == 'last' ) {\n\t\t\t\t\t\t\t\t$this.setValue( result_data[result_data.length - 1] );\n\t\t\t\t\t\t\t\tif ( trigger_form_item_change == true ) {\n\t\t\t\t\t\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( callBack ) {\n\t\t\t\t\t\t\t\t\tcallBack( result_data[result_data.length - 1] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( callBack ) {\n\t\t\t\t\t\t\t\tcallBack();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ta_dropdown && a_dropdown.setPagerData( result.getPagerData() );\n\n\t\t\t\t\t\tif ( result_data.length < 1 && a_dropdown.getSelectItems().length < 1 ) {\n\t\t\t\t\t\t\ta_dropdown && a_dropdown.showNoResultCover( 'unselect_grid' );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ta_dropdown && a_dropdown.removeNoResultCover( 'unselect_grid' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ta_dropdown && a_dropdown.getUnSelectGrid().grid.show();\n\n\t\t\t\t\t\tif ( focused_element.length ) {\n\t\t\t\t\t\t\tfocused_element.focus();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t} else {\n\t\t\t\targs = this.buildSelectGridFilter();\n\t\t\t\tif ( args.filter_data.id && args.filter_data.id !== false ) { //prevent returning all available rows when nothing is selected\n\t\t\t\t\tapi['get' + custom_key_name]( args, {\n\t\t\t\t\t\tonResult: function( result ) {\n\t\t\t\t\t\t\tvar result_data = result.getResult();\n\t\t\t\t\t\t\tvar focused_element = $( ':focus' );\n\n\t\t\t\t\t\t\tif ( $.type( result_data ) != 'array' ) {\n\t\t\t\t\t\t\t\tresult_data = [];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tresult_data = Global.formatGridData( result_data, api.key_name );\n\n\t\t\t\t\t\t\ta_dropdown.setSelectGridSearchResult( result_data ); //set as search result\n\n\t\t\t\t\t\t\tif ( result_data.length < 1 ) {\n\t\t\t\t\t\t\t\ta_dropdown.getSelectGrid().grid.clearGridData();\n\t\t\t\t\t\t\t\ta_dropdown.showNoResultCover( 'select_grid' );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ta_dropdown.removeNoResultCover( 'select_grid' );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\ta_dropdown.setSelectGridDragAble();\n\n\t\t\t\t\t\t\ta_dropdown.getSelectGrid().grid.show();\n\n\t\t\t\t\t\t\tif ( focused_element.length > 0 ) {\n\t\t\t\t\t\t\t\tfocused_element.focus();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.buildDisplayColumns = function( api_display_columns ) {\n\t\t\tvar len = all_columns.length;\n\t\t\tvar len1 = api_display_columns.length;\n\t\t\tvar display_columns = [];\n\n\t\t\tfor ( var j = 0; j < len1; j++ ) {\n\t\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( api_display_columns[j] === all_columns[i].value ) {\n\t\t\t\t\t\tdisplay_columns.push( all_columns[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn display_columns;\n\t\t};\n\n\t\tthis.buildDisplayColumnsForEditor = function() {\n\t\t\tvar len = all_columns.length;\n\t\t\tvar len1 = display_columns.length;\n\t\t\tvar result_display_columns = [];\n\t\t\tfor ( var j = 0; j < len1; j++ ) {\n\t\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( !display_columns[j] ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif ( Global.isSet( display_columns[j].name ) ) { //jQgrid column format\n\t\t\t\t\t\tvar name = display_columns[j].name;\n\t\t\t\t\t} else if ( Global.isSet( display_columns[j].value ) ) { //ViewColumn format,\tlabel and value\n\t\t\t\t\t\tname = display_columns[j].value;\n\t\t\t\t\t}\n\t\t\t\t\tif ( name === all_columns[i].value ) {\n\t\t\t\t\t\tresult_display_columns.push( all_columns[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn result_display_columns;\n\n\t\t};\n\n\t\tthis.getLocalSelectItem = function( val ) {\n\n\t\t\tif ( added_items ) {\n\t\t\t\tfor ( var i = 0; i < added_items.length; i++ ) {\n\t\t\t\t\tif ( val == added_items[i].value ) { //sometime the value is not number\n\t\t\t\t\t\tvar item = {};\n\n\t\t\t\t\t\titem[key] = val;\n\n\t\t\t\t\t\t$.each( display_columns, function( index, content ) {\n\n\t\t\t\t\t\t\titem[content.name] = added_items[i].label;\n\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\treturn item;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn this.getFirstItem();\n\t\t\t} else {\n\t\t\t\treturn this.getFirstItem();\n\t\t\t}\n\t\t};\n\n\t\tthis.getFirstItem = function() {\n\t\t\tvar first_item = {};\n\n\t\t\tfirst_item[key] = TTUUID.zero_id;\n\n\t\t\tif ( set_any || set_all ) {\n\t\t\t\tfirst_item[key] = TTUUID.not_exist_id;\n\t\t\t} else {\n\t\t\t\tfirst_item[key] = TTUUID.zero_id;\n\t\t\t}\n\n\t\t\t$.each( display_columns, function( index, content ) {\n\n\t\t\t\tif ( key !== 'id' ) {\n\t\t\t\t\t//first_item.id = 999; //records id start from 10000\n\t\t\t\t\tfirst_item.id = TTUUID.not_exist_id;\n\t\t\t\t}\n\t\t\t\tif ( set_all ) {\n\t\t\t\t\tfirst_item[content.name] = Global.all_item;\n\t\t\t\t} else if ( set_any ) {\n\t\t\t\t\tfirst_item[content.name] = Global.any_item;\n\t\t\t\t} else if ( set_empty || set_special_empty ) {\n\n\t\t\t\t\tfirst_item[content.name] = Global.empty_item;\n\n\t\t\t\t} else if ( set_open ) {\n\t\t\t\t\tfirst_item[content.name] = Global.open_item;\n\t\t\t\t} else if ( set_default ) {\n\t\t\t\t\tfirst_item[content.name] = Global.default_item;\n\t\t\t\t}\n\n\t\t\t\tif ( custom_first_label ) {\n\t\t\t\t\tfirst_item[content.name] = custom_first_label;\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t} );\n\n\t\t\treturn first_item;\n\t\t};\n\n\t\tthis.createFirstItem = function( target_data ) {\n\n\t\t\tvar no_first_item = false;\n\t\t\tif ( !target_data ) {\n\t\t\t\ttarget_data = source_data;\n\t\t\t}\n\n\t\t\tif ( target_data.hasOwnProperty( 0 ) ) {\n\t\t\t\tif ( set_any || set_all ) {\n\t\t\t\t\tif ( target_data[0][key] === TTUUID.not_exist_id ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\tif ( target_data[0][key] === TTUUID.zero_id ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tvar first_item = {};\n\n\t\t\tfirst_item[key] = TTUUID.zero_id;\n\n\t\t\tif ( set_any || set_all || set_special_empty ) {\n\t\t\t\tfirst_item[key] = TTUUID.not_exist_id;\n\t\t\t} else {\n\t\t\t\tfirst_item[key] = TTUUID.zero_id;\n\t\t\t}\n\n\t\t\t$.each( display_columns, function( index, content ) {\n\n\t\t\t\tif ( key !== 'id' ) {\n\t\t\t\t\t//first_item.id = 999; //records id start from 10000\n\t\t\t\t\tfirst_item.id = TTUUID.not_exist_id; //records id start from 10000\n\t\t\t\t}\n\t\t\t\tif ( set_all ) {\n\t\t\t\t\tfirst_item[content.name] = Global.all_item;\n\t\t\t\t} else if ( set_any ) {\n\t\t\t\t\tfirst_item[content.name] = Global.any_item;\n\t\t\t\t} else if ( set_empty || set_special_empty ) {\n\t\t\t\t\tfirst_item[content.name] = Global.empty_item;\n\t\t\t\t} else if ( set_open ) {\n\t\t\t\t\tfirst_item[content.name] = Global.open_item;\n\t\t\t\t} else if ( set_default ) {\n\t\t\t\t\tfirst_item[content.name] = Global.default_item;\n\t\t\t\t} else {\n\t\t\t\t\tno_first_item = true;\n\t\t\t\t}\n\n\t\t\t\tif ( custom_first_label ) {\n\t\t\t\t\tfirst_item[content.name] = custom_first_label;\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t} );\n\n\t\t\tif ( !no_first_item ) {\n\t\t\t\ttarget_data.unshift( first_item );\n\t\t\t}\n\n\t\t};\n\n\t\tthis.checkIfLayoutChanged = function( newDisplayColumns ) {\n\n\t\t\tif ( !display_columns ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif ( !newDisplayColumns ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif ( display_columns.length !== newDisplayColumns.length ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tvar len = display_columns.length;\n\n\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\tvar display_column = display_columns[i];\n\t\t\t\tvar found = false;\n\t\t\t\tfor ( var j = 0; j < len; j++ ) {\n\t\t\t\t\tvar new_display_column = newDisplayColumns[j];\n\t\t\t\t\tif ( new_display_column.name === display_column.name ) {\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( !found ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t};\n\n\t\tthis.setDefaultArgs = function( val ) {\n\t\t\t$this.default_args = val;\n\t\t\tset_default_args_manually = true;\n\t\t\tdefault_args = val;\n\n\t\t};\n\n\t\tthis.setDisPlayColumns = function( val ) {\n\n\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( val, layout_name );\n\t\t};\n\n\t\t//Only these columns can be shown no matter\n\t\tthis.setPossibleDisplayColumns = function( val, default_columns ) {\n\t\t\tpossible_display_columns = val;\n\n\t\t\tif ( default_columns ) {\n\t\t\t\tlist_view_default_columns = default_columns;\n\t\t\t} else {\n\t\t\t\tlist_view_default_columns = val;\n\t\t\t}\n\n\t\t\tif ( layout_name !== 'global_option_column' && //Simple options\n\t\t\t\tlayout_name !== 'global_tree_column' && //Tree Mode\n\t\t\t\tlayout_name !== 'global_sort_columns' &&\n\t\t\t\tlayout_name !== 'global_timesheet' &&\n\t\t\t\tlayout_name !== 'global_absence' ) {\n\t\t\t\tthis.initColumns();\n\t\t\t}\n\n\t\t};\n\n\t\tthis.setRowPerPage = function( val ) {\n\t\t\trow_per_page = val;\n\t\t};\n\n\t\tthis.setPagerData = function( val ) {\n\t\t\tpager_data = val;\n\t\t};\n\n\t\tthis.shouldInitColumns = function() {\n\t\t\tif ( layout_name === 'global_option_column' || //Simple options\n\t\t\t\tlayout_name === 'global_tree_column' || //Tree Mode\n\t\t\t\tlayout_name === 'global_sort_columns' ||\n\t\t\t\tlayout_name === 'global_timesheet' ||\n\t\t\t\tlayout_name === 'global_absence' ||\n\t\t\t\tlayout_name === 'global_simple_name' ||\n\t\t\t\tlayout_name === 'global_simple_name' + '_navigation' ) {\n\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t};\n\n\t\tthis.createItem = function( val, label ) {\n\t\t\tvar item = {};\n\n\t\t\titem[key] = val;\n\t\t\t$.each( display_columns, function( index, content ) {\n\n\t\t\t\tif ( key !== 'id' ) {\n\t\t\t\t\titem.id = 20000; //records id start from 10000\n\t\t\t\t}\n\t\t\t\titem[content.name] = label;\n\t\t\t\treturn false;\n\n\t\t\t} );\n\n\t\t\treturn item;\n\n\t\t};\n\n\t\tthis.initSourceData = function() {\n\t\t\tvar args = $this.buildUnSelectGridFilter();\n\t\t\tapi['get' + custom_key_name]( args, {\n\t\t\t\tonResult: function( result ) {\n\t\t\t\t\tvar result_data = result.getResult();\n\t\t\t\t\tif ( !Global.isArray( result_data ) ) {\n\t\t\t\t\t\tresult_data = [];\n\t\t\t\t\t}\n\t\t\t\t\tsource_data = result_data;\n\t\t\t\t\tpager_data = result.getPagerData();\n\n\t\t\t\t\t$this.trigger( 'initSourceComplete', [$this] );\n\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t//only do this once\n\t\t\tinit_data_immediately = false;\n\t\t};\n\n\t\tthis.addHideIdColumn = function( display_columns ) {\n\t\t\tvar id_column = { name: 'id', index: 'id', label: '', width: 0, hidden: true };\n\n\t\t\tdisplay_columns.push( id_column );\n\n\t\t\treturn display_columns;\n\t\t};\n\n\t\tvar buildSortBySelectColumns = function( array ) {\n\t\t\tvar sort_by_array = array;\n\t\t\tvar sort_by_select_columns = [];\n\t\t\tvar sort_by_unselect_columns = source_data;\n\n\t\t\tif ( sort_by_array ) {\n\t\t\t\t$.each( sort_by_array, function( index, content ) {\n\t\t\t\t\tfor ( var key in content ) {\n\t\t\t\t\t\tif ( key === 'label' || key === 'value' || key === 'fullValue' ) {\n\t\t\t\t\t\t\tsort_by_select_columns = sort_by_array;\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$.each( sort_by_unselect_columns, function( index1, content1 ) {\n\t\t\t\t\t\t\tif ( content1.value === key ) {\n\t\t\t\t\t\t\t\tcontent1.sort = content[key];\n\t\t\t\t\t\t\t\tsort_by_select_columns.push( content1 );\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn sort_by_select_columns;\n\n\t\t};\n\n\t\t//For multiple items like .xxx could contains a few widgets.\n\t\tthis.each( function() {\n\t\t\tvar o = $.meta ? $.extend( {}, opts, $( this ).data() ) : opts;\n\t\t\tlabel_span = $( this ).find( '.a-combobox-label' );\n\t\t\tvar focus_input = $( this ).find( '.focus-input' );\n\n\t\t\tif ( o.always_include_columns ) {\n\t\t\t\talways_include_columns = o.always_include_columns;\n\t\t\t}\n\n\t\t\tif ( o.extendDataProcessWhenSearch ) {\n\t\t\t\textendDataProcessWhenSearch = o.extendDataProcessWhenSearch;\n\t\t\t}\n\n\t\t\tif ( o.always_search_full_columns ) {\n\t\t\t\talways_search_full_columns = o.always_search_full_columns;\n\t\t\t}\n\n\t\t\t//source_data id that add from outsite, used to set value before open awesomebox\n\t\t\tif ( o.added_items ) {\n\t\t\t\tadded_items = o.added_items;\n\t\t\t}\n\n\t\t\tif ( o.init_data_immediately ) {\n\t\t\t\tinit_data_immediately = o.init_data_immediately;\n\t\t\t}\n\n\t\t\t//first item label , like -- No Meal -- in Policy -> Schedule Policies\n\t\t\tif ( o.custom_first_label ) {\n\t\t\t\tcustom_first_label = o.custom_first_label;\n\t\t\t}\n\n\t\t\tif ( o.script_name ) {\n\t\t\t\tscript_name = o.script_name;\n\t\t\t}\n\n\t\t\tif ( o.get_real_data_on_multi ) {\n\t\t\t\tget_real_data_on_multi = o.get_real_data_on_multi;\n\t\t\t}\n\n\t\t\tif ( o.setRealValueCallBack ) {\n\t\t\t\tsetRealValueCallBack = o.setRealValueCallBack;\n\t\t\t}\n\n\t\t\tif ( o.navigation_mode ) {\n\t\t\t\tnavigation_mode = o.navigation_mode;\n\t\t\t\t$( this ).children().eq( 1 ).css( 'max-width', 132 );\n\t\t\t\t$( this ).children().eq( 1 ).css( 'min-width', 132 );\n\t\t\t}\n\n\t\t\tif ( o.search_panel_model ) {\n\t\t\t\t$( this ).children().eq( 1 ).css( 'max-width', 132 );\n\t\t\t\t$( this ).children().eq( 1 ).css( 'min-width', 132 );\n\t\t\t}\n\n\t\t\tif ( o.width ) {\n\t\t\t\t$( this ).children().eq( 1 ).css( 'max-width', o.width );\n\t\t\t\tif ( o.is_static_width ) {\n\t\t\t\t\t$( this ).children().eq( 1 ).css( 'min-width', o.width );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$( this ).children().eq( 1 ).css( 'min-width', 132 );\n\t\t\t}\n\n\t\t\tif ( o.api_class ) {\n\t\t\t\tapi_class = o.api_class;\n\t\t\t\tapi = o.api_class;\n\t\t\t}\n\n\t\t\tif ( o.custom_key_name ) {\n\t\t\t\tcustom_key_name = o.custom_key_name;\n\t\t\t} else {\n\n\t\t\t\tif ( api ) {\n\t\t\t\t\tcustom_key_name = api.key_name;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( o.allow_multiple_selection ) {\n\t\t\t\tallow_multiple_selection = o.allow_multiple_selection;\n\t\t\t}\n\n\t\t\tif ( o.set_any ) {\n\t\t\t\tset_any = o.set_any;\n\t\t\t}\n\n\t\t\tif ( o.set_empty ) {\n\t\t\t\tset_empty = o.set_empty;\n\t\t\t}\n\n\t\t\tif ( o.set_special_empty ) {\n\t\t\t\tset_special_empty = o.set_special_empty;\n\t\t\t}\n\n\t\t\tif ( o.set_open ) {\n\t\t\t\tset_open = o.set_open;\n\t\t\t}\n\n\t\t\tif ( o.set_default ) {\n\t\t\t\tset_default = o.set_default;\n\t\t\t}\n\n\t\t\tif ( o.set_all ) {\n\t\t\t\tset_all = o.set_all;\n\t\t\t}\n\n\t\t\tif ( o.addition_source_function ) {\n\t\t\t\taddition_source_function = o.addition_source_function;\n\t\t\t}\n\n\t\t\tif ( o.column_option_key ) {\n\t\t\t\tcolumn_option_key = o.column_option_key;\n\t\t\t}\n\n\t\t\tfield = o.field;\n\n\t\t\tif ( o.validation_field ) {\n\t\t\t\tvalidation_field = o.validation_field;\n\t\t\t}\n\n\t\t\tif ( o.layout_name ) {\n\t\t\t\tif ( navigation_mode ) {\n\t\t\t\t\tlayout_name = o.layout_name + '_navigation';\n\t\t\t\t} else {\n\t\t\t\t\tlayout_name = o.layout_name;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( o.hasOwnProperty( 'show_search_inputs' ) ) {\n\t\t\t\tshow_search_inputs = o.show_search_inputs;\n\t\t\t}\n\n\t\t\tif ( o.tree_mode ) {\n\t\t\t\ttree_mode = o.tree_mode;\n\t\t\t}\n\n\t\t\tif ( o.on_tree_grid_row_select ) {\n\t\t\t\ton_tree_grid_row_select = o.on_tree_grid_row_select;\n\t\t\t}\n\n\t\t\t//Always set this true;\n\t\t\tallow_drag_to_order = true;\n\n\t\t\tif ( o.key ) {\n\t\t\t\tkey = o.key;\n\t\t\t}\n\n\t\t\tif ( o.args ) {\n\t\t\t\t$this.args = o.args;\n\t\t\t}\n\n\t\t\tif ( o.customSearchFilter ) {\n\t\t\t\t$this.customSearchFilter = o.customSearchFilter;\n\t\t\t}\n\n\t\t\t//Set default args use when init source;\n\t\t\tif ( o.default_args ) {\n\t\t\t\t$this.setDefaultArgs( o.default_args );\n\t\t\t}\n\n\t\t\tvar $$this = this;\n\t\t\tfocus_input.unbind( 'keydown' ).bind( 'keydown', function( e ) {\n\t\t\t\t//Stop click event to top, prevent the body click event\n\t\t\t\tif ( e.keyCode === 13 || e.keyCode === 32 ) {\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\te.preventDefault();\n\n\t\t\t\t\tTTPromise.add( 'AComboBox', 'init' );\n\t\t\t\t\topenADropDown();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tfocus_input.bind( 'focusin', function() {\n\t\t\t\t$( $$this ).addClass( 'focus' );\n\t\t\t} );\n\n\t\t\tfocus_input.bind( 'focusout', function() {\n\t\t\t\t$( $$this ).removeClass( 'focus' );\n\t\t\t} );\n\n\t\t\t$( this ).click( function( e ) {\n\t\t\t\te.stopPropagation();\n\t\t\t\tif ( !enabled ) {\n\t\t\t\t\tif ( LocalCacheData.current_open_sub_controller &&\n\t\t\t\t\t\tLocalCacheData.current_open_sub_controller.edit_view &&\n\t\t\t\t\t\tLocalCacheData.current_open_sub_controller.is_viewing ) {\n\t\t\t\t\t\terror_string = LocalCacheData.current_open_sub_controller.getViewModeErrorMessage();\n\t\t\t\t\t\t$this.showErrorTip( 10 );\n\t\t\t\t\t} else if ( LocalCacheData.current_open_primary_controller &&\n\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.edit_view &&\n\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.is_viewing ) {\n\t\t\t\t\t\terror_string = LocalCacheData.current_open_primary_controller.getViewModeErrorMessage();\n\t\t\t\t\t\t$this.showErrorTip( 10 );\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\tif ( dontOpen === true ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tTTPromise.add( 'AComboBox', 'init' );\n\t\t\t\t\topenADropDown();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t$( this ).mouseover( function() {\n\t\t\t\tif ( enabled ) {\n\t\t\t\t\tif ( error_string && error_string.length > 0 ) {\n\t\t\t\t\t\t$this.showErrorTip( 1000 );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t$( this ).mouseout( function() {\n\t\t\t\t$this.hideErrorTip();\n\t\t\t} );\n\n\t\t\tif ( !o.width ) {\n\t\t\t\t$( this ).css( 'min-width', '169px' );\n\t\t\t} else {\n\t\t\t\t$( this ).css( 'min-width', ( o.width + 33 ) + 'px' );\n\t\t\t}\n\n\t\t\tif ( !$this.shouldInitColumns() ) { //Sort Selector in search panel\n\t\t\t\tdo_not_get_real_data = true; // For Simple OPTIONS mode\n\n\t\t\t}\n\n\t\t\tdisplay_columns = ALayoutCache.getDefaultColumn( layout_name ); //Get Default columns base on different layout name\n\t\t\tdisplay_columns = Global.convertColumnsTojGridFormat( display_columns, layout_name ); //Convert to jQgrid format\n\n\t\t\tif ( $this.shouldInitColumns() && !navigation_mode ) { //Sort Selector in search panel\n\n\t\t\t\t//init columnd when set possible columns for navigation mode\n\t\t\t\t$this.initColumns();\n\t\t\t}\n\n\t\t\tif ( o.id ) {\n\t\t\t\t$( this ).attr( 'id', o.id + '_AComboBox' );\n\t\t\t\tid = o.id;\n\t\t\t} else {\n\t\t\t\t$( this ).attr( 'id', field + '_AComboBox' );\n\t\t\t\tid = o.field;\n\t\t\t}\n\n\t\t\t$this.setEmptyLabel();\n\n\t\t\t//Open ADropDown\n\t\t\tfunction setADropDownSelectValues( select_items ) {\n\t\t\t\tif ( !( set_any && select_items == TTUUID.not_exist_id ) ) {\n\t\t\t\t\ta_dropdown.setSelectGridData( select_items );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction openADropDown() {\n\t\t\t\tif ( !enabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif ( LocalCacheData.openAwesomeBox ) {\n\t\t\t\t\tif ( LocalCacheData.openAwesomeBox.getId() === id ) {\n\t\t\t\t\t\tLocalCacheData.openAwesomeBox.onClose();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tLocalCacheData.openAwesomeBox.onClose();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tLocalCacheData.openAwesomeBox = $this;\n\n\t\t\t\t//Create and open ADropDown\n\t\t\t\ta_dropdown = Global.loadWidgetByName( FormItemType.AWESOME_DROPDOWN );\n\n\t\t\t\tvar display_show_all = false;\n\t\t\t\tif ( $this.shouldInitColumns() && !navigation_mode ) {\n\t\t\t\t\tdisplay_show_all = true;\n\t\t\t\t}\n\n\t\t\t\tif ( navigation_mode && default_args && default_args.filter_sort && !cached_sort_filter ) {\n\t\t\t\t\tcached_sort_filter = default_args.filter_sort;\n\t\t\t\t}\n\n\t\t\t\t//Create ADropDown\n\t\t\t\ta_dropdown = a_dropdown.ADropDown( {\n\t\t\t\t\tdisplay_show_all: display_show_all,\n\t\t\t\t\tallow_drag_to_order: allow_drag_to_order,\n\t\t\t\t\tallow_multiple_selection: allow_multiple_selection,\n\t\t\t\t\tshow_all: show_all,\n\t\t\t\t\tkey: key,\n\t\t\t\t\tid: id,\n\t\t\t\t\tcomboBox: $this,\n\t\t\t\t\tshow_search_inputs: show_search_inputs,\n\t\t\t\t\tsearch_input_filter: cached_search_inputs_filter,\n\t\t\t\t\tselect_grid_search_input_filter: cached_select_grid_search_inputs_filter,\n\t\t\t\t\tdefault_sort_filter: cached_sort_filter,\n\t\t\t\t\tdefault_select_grid_sort_filter: cached_selected_grid_sort_filter,\n\t\t\t\t\ttree_mode: tree_mode,\n\t\t\t\t\tcolumn_option_key: column_option_key,\n\t\t\t\t\tapi: api,\n\t\t\t\t\tdisplay_column_settings: $this.shouldInitColumns(),\n\n\t\t\t\t\ton_tree_grid_row_select: on_tree_grid_row_select\n\t\t\t\t} );\n\n\t\t\t\ta_dropdown_div = $( '<div id=\\'' + id + 'a_dropdown_div\\' class=\\'a-dropdown-div\\'></div>' );\n\n\t\t\t\ta_dropdown_div.append( a_dropdown );\n\n\t\t\t\ta_dropdown_div.mouseenter( function() {\n\t\t\t\t\tis_mouse_over = true;\n\t\t\t\t} );\n\n\t\t\t\ta_dropdown_div.mouseleave( function() {\n\t\t\t\t\tis_mouse_over = false;\n\t\t\t\t} );\n\n\t\t\t\t$( 'body' ).append( a_dropdown_div );\n\n\t\t\t\tTTPromise.wait( 'AComboBox', 'init', function() {\n\t\t\t\t\ta_dropdown.setGridColumnsWidths();\n\n\t\t\t\t\t//Make sure we don't run this API call if the only selected value is a zero/not exists UUID,\n\t\t\t\t\t// otherwise it causes companies with thousands of employees to return *all* employees.\n\t\t\t\t\tif ( allow_multiple_selection == true && ( $this.getValue().length > 1 || ( $this.getValue().length == 1 && $this.getValue()[0] && ( $this.getValue()[0] != TTUUID.zero_id && $this.getValue()[0] != TTUUID.not_exist_id ) ) ) && api ) {\n\t\t\t\t\t\tvar args = {};\n\t\t\t\t\t\targs.filter_data = { id: $this.getValue() };\n\t\t\t\t\t\targs.filter_columns = $this.getColumnFilter();\n\t\t\t\t\t\targs.filter_items_per_page = 10000;\n\n\t\t\t\t\t\tapi['get' + custom_key_name]( args, {\n\t\t\t\t\t\t\tonResult: function( result ) {\n\t\t\t\t\t\t\t\tdoNext( result );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdoNext();\n\t\t\t\t\t}\n\n\t\t\t\t\tfunction doNext( result ) {\n\t\t\t\t\t\tif ( result ) {\n\t\t\t\t\t\t\ta_dropdown.setRealSelectItems( result.getResult(), $this.getValue() );\n\t\t\t\t\t\t}\n\t\t\t\t\t\ta_dropdown_div.css( 'opacity', '1' );\n\n\t\t\t\t\t\t//#2353 - remove the right side border from jqgrid.\n\t\t\t\t\t\tvar tables = $this.find( '.ui-jqgrid' ).find( 'table' );\n\t\t\t\t\t\tif ( tables.length > 0 ) {\n\t\t\t\t\t\t\tfor ( var i = 0; i < tables.length; i++ ) {\n\t\t\t\t\t\t\t\t//resize awesomebox grid tables to remove right-size gap.\n\t\t\t\t\t\t\t\tvar width = $( tables[0] ).parents( '.ui-jqgrid' ).find( '.ui-jqgrid-bdiv' ).width() - 11;\n\t\t\t\t\t\t\t\t$( tables[0] ).parents( '.ui-jqgrid' ).find( '.ui-jqgrid-view' ).width( width );\n\t\t\t\t\t\t\t\t$( tables[i] ).width( width );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ta_dropdown.setUnSelectGridDragAble();\n\t\t\t\t\t\ta_dropdown.setSelectGridDragAble();\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t\ta_dropdown.bind( 'close', $this.onClose );\n\n\t\t\t\tvar layout = ALayoutCache.layout_dic[layout_name];\n\n\t\t\t\t//Always use columns from global cache if columns is not default\n\t\t\t\tif ( layout_name && layout && Global.isSet( layout.data ) ) {\n\n\t\t\t\t\tvar current_display_columns = layout.data.display_columns;\n\n\t\t\t\t\t//Happen when save no columns in column setting for navigation mode\n\t\t\t\t\tif ( current_display_columns.length > 0 ) {\n\t\t\t\t\t\t//Only check possible columns if any\n\t\t\t\t\t\tif ( possible_display_columns ) {\n\t\t\t\t\t\t\tcurrent_display_columns = filterBaseOnPossibleColumns( current_display_columns );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( list_view_default_columns ) {\n\t\t\t\t\t\t\tcurrent_display_columns = list_view_default_columns;\n\t\t\t\t\t\t\tcurrent_display_columns = filterBaseOnPossibleColumns( current_display_columns );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrent_display_columns = Global.convertColumnsTojGridFormat( current_display_columns, layout_name );\n\n\t\t\t\t\tvar current_row_per_page = layout.data.row_per_page;\n\n\t\t\t\t\t//If current columns or row_per_page not same as saved layout. Reload data base on current setting\n\t\t\t\t\tif ( $this.checkIfLayoutChanged( current_display_columns ) || ( row_per_page !== current_row_per_page && !navigation_mode ) ) {\n\n\t\t\t\t\t\tdisplay_columns = current_display_columns;\n\t\t\t\t\t\tsource_data = null;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !navigation_mode ) {\n\t\t\t\t\t\trow_per_page = current_row_per_page;\n\n\t\t\t\t\t\tif ( !set_default_args_manually ) {\n\t\t\t\t\t\t\tif ( Global.isSet( layout.data.type ) && layout.data.type === 10 ) {\n\t\t\t\t\t\t\t\tvar default_args = {};\n\t\t\t\t\t\t\t\tdefault_args.filter_data = layout.data.filter_data;\n\t\t\t\t\t\t\t\tdefault_args.filter_sort = layout.data.filter_sort;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdefault_args = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t//Set columns first\n\t\t\t\ta_dropdown.setColumns( display_columns );\n\n\t\t\t\t//Set DropDown position\n\t\t\t\t//use default with since .width() not return correct width when first open\n\n\t\t\t\tvar dropdown_width = a_dropdown.getBoxWidth();\n\n\t\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\t\tdropdown_width = dropdown_width * 2 + 30 + 15;\n\t\t\t\t}\n\n\t\t\t\tif ( ( dropdown_width + $( $this ).offset().left + 50 ) > Global.bodyWidth() ) {\n\t\t\t\t\ta_dropdown_div.css( 'left', ( Global.bodyWidth() - dropdown_width - 50 ) );\n\t\t\t\t} else {\n\t\t\t\t\ta_dropdown_div.css( 'left', $( $this ).offset().left );\n\t\t\t\t}\n\n\t\t\t\t// makes sure it shown on the screen, will calculte position after source setting\n\t\t\t\tif ( ( $( $this ).offset().top + 25 + 275 ) < Global.bodyHeight() ) {\n\t\t\t\t\ta_dropdown_div.css( 'top', ( $( $this ).offset().top + 25 ) );\n\t\t\t\t} else {\n\t\t\t\t\ta_dropdown_div.css( 'top', ( $( $this ).offset().top - 275 ) );\n\t\t\t\t}\n\n\t\t\t\t// This will never change when search in search input. Set it back to dropdown every time when open\n\t\t\t\tif ( !source_data ) {\n\t\t\t\t\t//When using pagination and first opening the dropdown box, we need to exclude the selected items from the API call\n\t\t\t\t\t// so the first page will always be populated with a full page of records.\n\t\t\t\t\t// Lower down we make a separate API call to get the records for the selected items, and source_data.concat() them there.\n\t\t\t\t\tvar args = $this.buildUnSelectGridFilter( $this.getValue() );\n\n\t\t\t\t\t//Error: TypeError: api is null in /interface/html5/global/widgets/awesomebox/AComboBox.js?v=8.0.0-20141117-112033 line 2364\n\t\t\t\t\tif ( !api ) {\n\t\t\t\t\t\tif ( addition_source_function ) { //Required to add data to search UI for custom fields\n\t\t\t\t\t\t\tsource_data = addition_source_function( $this, source_data );\n\t\t\t\t\t\t\ta_dropdown.setUnselectedGridData( source_data );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tTTPromise.resolve( 'AComboBox', 'init' );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tapi['get' + custom_key_name]( args, {\n\t\t\t\t\t\tonResult: function( result ) {\n\t\t\t\t\t\t\tvar result_data = result.getResult();\n\n\t\t\t\t\t\t\tif ( !Global.isArray( result_data ) ) {\n\t\t\t\t\t\t\t\tresult_data = [];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tsource_data = result_data;\n\n\t\t\t\t\t\t\t//set this outside, to add more data to source_data\n\t\t\t\t\t\t\tif ( addition_source_function ) {\n\t\t\t\t\t\t\t\tsource_data = addition_source_function( $this, source_data );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tnavigation_mode_source_data_before_open = null;\n\n\t\t\t\t\t\t\tif ( Global.isSet( api ) ) {\n\t\t\t\t\t\t\t\tsource_data = Global.formatGridData( source_data, api.key_name );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\t\t\t\t\tif ( set_all ) {\n\t\t\t\t\t\t\t\t\t$this.createFirstItem();\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// For select items which only contains ids, like all awesomeboxes in edit view\n\t\t\t\t\t\t\t\t// Similar code is also below in the } else { clause of this IF statement.\n\t\t\t\t\t\t\t\tif ( get_real_data_when_open ) {\n\t\t\t\t\t\t\t\t\tget_real_data_when_open = false;\n\n\t\t\t\t\t\t\t\t\ta_dropdown.setUnselectedGridData( source_data );\n\n\t\t\t\t\t\t\t\t\tif ( !select_items || ( select_items && select_items.length == 1 && ( select_items[0] == TTUUID.zero_id || select_items[0] == TTUUID.not_exist_id ) ) ) {\n\t\t\t\t\t\t\t\t\t\tTTPromise.resolve( 'AComboBox', 'init' );\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tvar args = {};\n\t\t\t\t\t\t\t\t\t\targs.filter_data = { id: select_items };\n\t\t\t\t\t\t\t\t\t\targs.filter_columns = $this.getColumnFilter();\n\t\t\t\t\t\t\t\t\t\targs.filter_items_per_page = 10000;\n\n\t\t\t\t\t\t\t\t\t\t//Error: TypeError: null is not an object (evaluating 'select_items.length') in /interface/html5/global/widgets/awesomebox/AComboBox.js?v=8.0.0-20141230-113526 line 2441\n\t\t\t\t\t\t\t\t\t\t//if select items contains data like 0, for example Employee in Recurring Schedule edit view\n\t\t\t\t\t\t\t\t\t\tvar local_data = false;\n\t\t\t\t\t\t\t\t\t\tif ( select_items && select_items.length > 0 && ( select_items[0] == TTUUID.zero_id || select_items[0] == TTUUID.not_exist_id ) ) {\n\t\t\t\t\t\t\t\t\t\t\tlocal_data = $this.getLocalSelectItem( select_items[0] );\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tapi['get' + custom_key_name]( args, {\n\t\t\t\t\t\t\t\t\t\t\tonResult: function( result ) {\n\t\t\t\t\t\t\t\t\t\t\t\tselect_items = result.getResult();\n\n\t\t\t\t\t\t\t\t\t\t\t\t//Since the initial API call above excluded the selected items, we need to concat() them back onto the source_data array\n\t\t\t\t\t\t\t\t\t\t\t\tsource_data = source_data.concat( select_items ); //Do above the unshift( local_data ) below.\n\n\t\t\t\t\t\t\t\t\t\t\t\tif ( local_data ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tselect_items.unshift( local_data );\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\t//a_dropdown.setSelectGridData( select_items ); //set Selected Data after set sourceData\n\t\t\t\t\t\t\t\t\t\t\t\tsetADropDownSelectValues( select_items );\n\t\t\t\t\t\t\t\t\t\t\t\tTTPromise.resolve( 'AComboBox', 'init' );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\ta_dropdown.setUnselectedGridData( source_data );\n\t\t\t\t\t\t\t\t\t//Issue #3220 - When an AwesomeBox has only 1 item selected on initial load, that item will disappear on reopen\n\t\t\t\t\t\t\t\t\t//if it is unselected by the user as it is not in the source_data for the AwesomeBox.\n\t\t\t\t\t\t\t\t\t//Since the initial API call above excluded the selected items, we need to concat() them back onto the source_data array\n\t\t\t\t\t\t\t\t\tif ( Array.isArray( select_items ) && select_items.length > 0 && select_items[0].id ) {\n\t\t\t\t\t\t\t\t\t\tsource_data = source_data.concat( select_items );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tsetADropDownSelectValues( select_items );\n\t\t\t\t\t\t\t\t\tTTPromise.resolve( 'AComboBox', 'init' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif ( set_empty || set_any || set_default || set_open || set_special_empty ) {\n\t\t\t\t\t\t\t\t\t$this.createFirstItem();\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\ta_dropdown.setUnselectedGridData( source_data );\n\t\t\t\t\t\t\t\ta_dropdown.setSelectItem( select_item );\n\t\t\t\t\t\t\t\tTTPromise.resolve( 'AComboBox', 'init' );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tpager_data = result.getPagerData();\n\t\t\t\t\t\t\ta_dropdown.setPagerData( pager_data );\n\n\t\t\t\t\t\t\tif ( !Global.isEmpty( cached_search_inputs_filter ) || !Global.isEmpty( cached_sort_filter ) ) {\n\t\t\t\t\t\t\t\ta_dropdown.getUnSelectGrid().grid.hide();\n\t\t\t\t\t\t\t\t$this.onADropDownSearch( 'unselect_grid' );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( !Global.isEmpty( cached_select_grid_search_inputs_filter ) || !Global.isEmpty( cached_selected_grid_sort_filter ) ) {\n\t\t\t\t\t\t\t\ta_dropdown.getSelectGrid().grid.hide();\n\t\t\t\t\t\t\t\t$this.onADropDownSearch( 'select_grid' );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t} else { //Use cache if already loaded data before\n\n\t\t\t\t\tif ( Global.isSet( api ) ) {\n\t\t\t\t\t\tsource_data = Global.formatGridData( source_data, api.key_name );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( allow_multiple_selection ) {\n\t\t\t\t\t\tif ( layout_name === 'global_sort_columns' ) {\n\t\t\t\t\t\t\tselect_items = buildSortBySelectColumns( select_items );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Similar code is also below in the above TRUE IF statement clause.\n\t\t\t\t\t\tif ( get_real_data_when_open ) {\n\t\t\t\t\t\t\tget_real_data_when_open = false;\n\n\t\t\t\t\t\t\ta_dropdown.setUnselectedGridData( source_data );\n\n\t\t\t\t\t\t\tif ( !select_items || ( select_items && select_items.length == 1 && ( select_items[0] == TTUUID.zero_id || select_items[0] == TTUUID.not_exist_id ) ) ) {\n\t\t\t\t\t\t\t\tTTPromise.resolve( 'AComboBox', 'init' );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tvar args = {};\n\t\t\t\t\t\t\t\targs.filter_data = { id: select_items };\n\t\t\t\t\t\t\t\targs.filter_columns = $this.getColumnFilter();\n\t\t\t\t\t\t\t\targs.filter_items_per_page = 10000;\n\n\t\t\t\t\t\t\t\t//Error: TypeError: null is not an object (evaluating 'select_items.length') in /interface/html5/global/widgets/awesomebox/AComboBox.js?v=8.0.0-20141230-113526 line 2441\n\t\t\t\t\t\t\t\t//if select items contains data like 0, for example Employee in Recurring Schedule edit view\n\t\t\t\t\t\t\t\tvar local_data = false;\n\t\t\t\t\t\t\t\tif ( select_items && select_items.length > 0 && ( select_items[0] == TTUUID.zero_id || select_items[0] == TTUUID.not_exist_id ) ) {\n\t\t\t\t\t\t\t\t\tlocal_data = $this.getLocalSelectItem( select_items[0] );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tapi['get' + custom_key_name]( args, {\n\t\t\t\t\t\t\t\t\tonResult: function( result ) {\n\t\t\t\t\t\t\t\t\t\tselect_items = result.getResult();\n\n\t\t\t\t\t\t\t\t\t\tif ( local_data ) {\n\t\t\t\t\t\t\t\t\t\t\tselect_items.unshift( local_data );\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\ta_dropdown.setUnselectedGridData( source_data );\n\t\t\t\t\t\t\t\t\t\t//a_dropdown.setSelectGridData( select_items ); //set Selected Data after set sourceData\n\t\t\t\t\t\t\t\t\t\tsetADropDownSelectValues( select_items );\n\t\t\t\t\t\t\t\t\t\tTTPromise.resolve( 'AComboBox', 'init' );\n\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ta_dropdown.setUnselectedGridData( source_data );\n\t\t\t\t\t\t\t//a_dropdown.setSelectGridData( select_items );\n\t\t\t\t\t\t\tsetADropDownSelectValues( select_items );\n\t\t\t\t\t\t\tTTPromise.resolve( 'AComboBox', 'init' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\ta_dropdown.setUnselectedGridData( source_data );\n\t\t\t\t\t\ta_dropdown.setSelectItem( select_item );\n\t\t\t\t\t\tTTPromise.resolve( 'AComboBox', 'init' );\n\t\t\t\t\t}\n\n\t\t\t\t\ta_dropdown.setPagerData( pager_data );\n\n\t\t\t\t\tif ( !Global.isEmpty( cached_search_inputs_filter ) || !Global.isEmpty( cached_sort_filter ) ) {\n\t\t\t\t\t\ta_dropdown.getUnSelectGrid().grid.hide();\n\t\t\t\t\t\t$this.onADropDownSearch( 'unselect_grid' );\n\t\t\t\t\t\tcurrent_open_page = 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( current_open_page > 1 && current_open_page <= pager_data.last_page_number ) {\n\t\t\t\t\t\t\ta_dropdown.getUnSelectGrid().grid.hide();\n\t\t\t\t\t\t\t$this.onADropDownSearch( 'unselect_grid', current_open_page );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !Global.isEmpty( cached_select_grid_search_inputs_filter ) || !Global.isEmpty( cached_selected_grid_sort_filter ) ) {\n\t\t\t\t\t\t//a_dropdown.getSelectGrid().grid.hide(); //#2721 - This helps fixes a bug where if you expand a awesomebox (ie: Edit Policy Group, Absence Policys), on right-hand side click clear search. Click Move All on right-hand side. Collapse, expand, click move All left-hand side. Both sides are now blank because the right grid had a display: none attached to it.\n\t\t\t\t\t\t$this.onADropDownSearch( 'select_grid' );\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t} );\n\n\t\treturn this;\n\n\t};\n\n\t$.fn.AComboBox.defaults = {};\n\t$.fn.AComboBox.html_template = `\n\t<div class=\"a-combobox\">\n\t\t<div class=\"a-combobox-left-bg\"></div>\n\t\t<span class=\"a-combobox-label openADropDown a-combobox-mid-bg\"></span>\n\t\t<input class=\"focus-input\">\n\t\t<div class=\"clickable-space openADropDown\"></div>\n\t</div>\n\t`;\n\n} )( jQuery );//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjg5Ny5qcyIsIm1hcHBpbmdzIjoiOztBQUFBOztBQUVBO0FBQ0EseUJBQXlCOztBQUV6Qjs7QUFFQTs7QUFFQTs7QUFFQSx5QkFBeUI7O0FBRXpCOztBQUVBLGtCQUFrQjs7QUFFbEIsK0JBQStCOztBQUUvQjs7QUFFQSxvQ0FBb0M7O0FBRXBDLHNDQUFzQzs7QUFFdEM7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUEsOEJBQThCOztBQUU5Qix1Q0FBdUM7O0FBRXZDLHdDQUF3Qzs7QUFFeEMsOENBQThDOztBQUU5QywwQkFBMEI7O0FBRTFCOztBQUVBLDBCQUEwQjs7QUFFMUI7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsaUNBQWlDOztBQUVqQywrQ0FBK0M7O0FBRS9DOztBQUVBOztBQUVBLHlDQUF5Qzs7QUFFekM7O0FBRUE7O0FBRUEsbUNBQW1DOztBQUVuQzs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTs7QUFFTixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnREFBZ0Q7QUFDaEQ7QUFDQTs7QUFFQTtBQUNBLG9CQUFvQixTQUFTO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQSxrREFBa0Q7QUFDbEQ7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLGlEQUFpRDtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7O0FBRUEsT0FBTztBQUNQO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUSxDQUFDO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsTUFBTTs7QUFFTjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMkJBQTJCOztBQUUzQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxNQUFNO0FBQ04sS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLE9BQU87O0FBRVAsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQyxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrRUFBa0U7QUFDbEU7O0FBRUEsb0JBQW9CLHNCQUFzQjtBQUMxQztBQUNBLHFCQUFxQixTQUFTO0FBQzlCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0Esa0JBQWtCLHdCQUF3Qjs7QUFFMUMsa0RBQWtEO0FBQ2xEO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHlCQUF5Qix3QkFBd0I7QUFDakQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFFBQVE7QUFDUjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCLHdCQUF3QjtBQUM3QyxpREFBaUQ7QUFDakQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7O0FBRXpCO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9COztBQUVwQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxvQkFBb0IsU0FBUztBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEseUJBQXlCOztBQUV6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxNQUFNO0FBQ047QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLDZDQUE2QztBQUM3QztBQUNBLDJCQUEyQjtBQUMzQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBLHVFQUF1RSxlQUFlO0FBQ3RGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLElBQUksZUFBZTs7QUFFNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxVQUFVO0FBQ1YsZ0NBQWdDO0FBQ2hDOztBQUVBOztBQUVBOztBQUVBLHFFQUFxRTs7QUFFckU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7O0FBRVI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTs7QUFFTjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsTUFBTTtBQUNOOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1IsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0Esb0JBQW9CLDRCQUE0QjtBQUNoRDtBQUNBO0FBQ0EscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBcUIsd0JBQXdCO0FBQzdDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUssK0JBQStCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUssK0JBQStCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLLCtCQUErQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBOztBQUVBLFFBQVE7QUFDUjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCLHNCQUFzQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7O0FBRUEsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSw4Q0FBOEM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQzs7QUFFakM7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLG1CQUFtQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFHQUFxRzs7QUFFckc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsTUFBTTs7QUFFTixLQUFLO0FBQ0w7QUFDQSxrRUFBa0U7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLDREQUE0RDs7QUFFNUQ7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLFVBQVU7QUFDOUIscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsVUFBVTtBQUM5QixxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQSxzREFBc0Q7QUFDdEQ7QUFDQSxPQUFPLHdEQUF3RDtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBLHFCQUFxQix3QkFBd0I7QUFDN0MsMENBQTBDO0FBQzFDOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0EsUUFBUTs7QUFFUjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTs7QUFFTjs7QUFFQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0EsNEJBQTRCO0FBQzVCLDBDQUEwQztBQUMxQztBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxvQkFBb0IsU0FBUztBQUM3QjtBQUNBO0FBQ0EscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7O0FBRUEsS0FBSzs7QUFFTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCOztBQUVyQjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsTUFBTTtBQUNOOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBLHVDQUF1QztBQUN2QyxpQ0FBaUM7O0FBRWpDOztBQUVBLG1FQUFtRTtBQUNuRSx5RkFBeUY7O0FBRXpGLDBEQUEwRDs7QUFFMUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNOztBQUVOOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxNQUFNOztBQUVOO0FBQ0E7QUFDQSxNQUFNOztBQUVOOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUixPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixtQkFBbUI7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxNQUFNOztBQUVOOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3Q0FBd0M7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsK0NBQStDLE9BQU87QUFDdEQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDhEQUE4RDs7QUFFOUQ7QUFDQTtBQUNBOztBQUVBLDREQUE0RDtBQUM1RDtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxPQUFPO0FBQ1AsTUFBTSxPQUFPOztBQUViO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMERBQTBEO0FBQzFEO0FBQ0E7O0FBRUE7QUFDQSxVQUFVO0FBQ1Y7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBOztBQUVBOztBQUVBOztBQUVBLElBQUk7O0FBRUo7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEVBQUUsR0FBRyxNQUFNIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC93aWRnZXRzL2F3ZXNvbWVib3gvQUNvbWJvQm94LmpzPzE0OTIiXSwic291cmNlc0NvbnRlbnQiOlsiKCBmdW5jdGlvbiggJCApIHtcblxuXHQkLmZuLkFDb21ib0JveCA9IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXHRcdHZhciBvcHRzID0gJC5leHRlbmQoIHt9LCAkLmZuLkFDb21ib0JveC5kZWZhdWx0cywgb3B0aW9ucyApO1xuXG5cdFx0dmFyIGxhYmVsX3NwYW4gPSBudWxsO1xuXG5cdFx0dmFyIGFfZHJvcGRvd24gPSBudWxsO1xuXG5cdFx0dmFyIGxheW91dF9uYW1lID0gJyc7XG5cblx0XHR2YXIgcGFnZXJfZGF0YSA9IG51bGw7IC8vdXNlIHRvIHJlc2V0IHBhZ2VyIGRhdGEgd2hlbiBvcGVuIGRyb3Bkb3duXG5cblx0XHR2YXIgYXBpX2NsYXNzID0gbnVsbDtcblxuXHRcdHZhciBhcGkgPSBudWxsOyAvL1JlbGF0ZWQgVFRBUEkuQVBJIGluc3RhbmNlLCB1c2UgdG8gZ2V0IGRhdGFcblxuXHRcdHZhciBkZWZhdWx0X2NvbHVtbnMgPSBudWxsO1x0IC8vRGVmYXVsdCBjb2x1bnMgd2hlbiBubyBsYXlvdXQgc2F2ZWRcblxuXHRcdHZhciBhbGxvd19tdWx0aXBsZV9zZWxlY3Rpb24gPSBmYWxzZTtcblxuXHRcdHZhciBkb19ub3RfZ2V0X3JlYWxfZGF0YSA9IGZhbHNlOyAvL0dldCBmdWxsIGRhdGEgd2hlbiBvbmx5IHBhc3MgaWQgdG8gc2VsZWN0IFZhbHVlLlxuXG5cdFx0dmFyIGdldF9yZWFsX2RhdGFfb25fbXVsdGkgPSBmYWxzZTsgLy9Vc3VhbGx5IG9ubHkgZ2V0IHJlYWwgZGF0YSB3aGVuIHNlbGVjdCBoYXMgYSBzaW5nbGUgdmFsdWUuIEJ1dCBwdW5jaCB0YWdzIHJlcXVpcmUgbWFudWFsX2lkIG9mIGFsbCByZWNvcmRzLlxuXG5cdFx0dmFyIHNldF9hbnkgPSBmYWxzZTtcblxuXHRcdHZhciBzZXRfZW1wdHkgPSBmYWxzZTtcblxuXHRcdHZhciBzZXRfc3BlY2lhbF9lbXB0eSA9IGZhbHNlO1xuXG5cdFx0dmFyIHNldF9vcGVuID0gZmFsc2U7XG5cblx0XHR2YXIgc2V0X2RlZmF1bHQgPSBmYWxzZTtcblxuXHRcdHZhciBzZXRfYWxsID0gZmFsc2U7XG5cblx0XHR2YXIgc2VsZWN0X2l0ZW0gPSBudWxsO1xuXG5cdFx0dmFyIHNlbGVjdF9pdGVtcyA9IG51bGw7XG5cblx0XHR2YXIgZmllbGQgPSAnJztcblxuXHRcdHZhciB2YWxpZGF0aW9uX2ZpZWxkO1xuXG5cdFx0dmFyIHVzZXJfZ2VuZXJpY19hcGkgPSBudWxsO1xuXG5cdFx0dmFyIGRpc3BsYXlfY29sdW1ucyA9IG51bGw7IC8vRGlzcGxheSBjb2x1bW5zIGluIEFEcm9wRG93biBpbiBqR3JpZCBtb2RlbCBmb3JtYXRcblxuXHRcdHZhciBwb3NzaWJsZV9kaXNwbGF5X2NvbHVtbnMgPSBudWxsOyAvL09ubHkgdGhlc2UgY29sdW1ucyBjYW4gYmUgc2hvd24gd2hlbiBpbml0IGRpc3BhbHkgY29sdW1ucy5cblxuXHRcdHZhciBsaXN0X3ZpZXdfZGVmYXVsdF9jb2x1bW5zID0gbnVsbDsgLy9Pbmx5IHRoZXNlIGNvbHVtbnMgY2FuIGJlIHNob3duIHdoZW4gaW5pdCBkaXNwYWx5IGNvbHVtbnMuXG5cblx0XHR2YXIgZGlzcGxheV9jb2x1bW5zX2luX2NvbHVtbkVkaXRvciA9IG51bGw7IC8vRGlzcGxheSBjb2x1bW5zIGluIGVkaXQgY29sdW1uc1xuXG5cdFx0dmFyIGFsbF9jb2x1bW5zID0gbnVsbDsgLy8gQWxsIGNvbHVtbnMgd2hlbiBlZGl0IGNvbHVtbnNcblxuXHRcdHZhciBjb2x1bW5fZWRpdG9yID0gbnVsbDtcblxuXHRcdHZhciBzb3VyY2VfZGF0YSA9IG51bGw7IC8vIFRoaXMgd2lsbCBuZXZlciBjaGFuZ2Ugd2hlbiBzZWFyY2ggaW4gc2VhcmNoIGlucHV0LiBTZXQgaXQgYmFjayB0byBkcm9wZG93biBldmVyeSB0aW1lIHdoZW4gb3BlblxuXG5cdFx0dmFyIGlkID0gJyc7XG5cblx0XHR2YXIgZ2V0X3JlYWxfZGF0YV93aGVuX29wZW4gPSBmYWxzZTtcblxuXHRcdHZhciBzZXRfc2VsZWN0X2l0ZW1zX3doZW5fc2V0X2RhdGFfcHJvdmlkZXIgPSBmYWxzZTtcblxuXHRcdHZhciAkdGhpcyA9IG51bGw7XG5cblx0XHR2YXIgYV9kcm9wZG93bl9kaXYgPSBudWxsO1xuXG5cdFx0dmFyIGlzX21vdXNlX292ZXIgPSBmYWxzZTtcblxuXHRcdHZhciByb3dfcGVyX3BhZ2UgPSAwO1xuXG5cdFx0dmFyIHNob3dfYWxsID0gZmFsc2U7XG5cblx0XHR2YXIgYXJncyA9IG51bGw7XG5cblx0XHRHbG9iYWwuYWRkQ3NzKCAnZ2xvYmFsL3dpZGdldHMvYXdlc29tZWJveC9BQ29tYm9Cb3guY3NzJyApO1xuXG5cdFx0dmFyIHNob3dfc2VhcmNoX2lucHV0cyA9IHRydWU7XG5cblx0XHR2YXIgdHJlZV9tb2RlID0gZmFsc2U7XG5cblx0XHR2YXIgb25fdHJlZV9ncmlkX3Jvd19zZWxlY3QgPSBmYWxzZTtcblxuXHRcdHZhciBrZXkgPSAnaWQnO1xuXG5cdFx0dmFyIGVycm9yX3N0cmluZyA9ICcnO1xuXG5cdFx0dmFyIGVycm9yX3RpcF9ib3g7XG5cblx0XHQkdGhpcyA9IHRoaXM7XG5cblx0XHR2YXIgbWFzc19lZGl0X21vZGUgPSBmYWxzZTtcblxuXHRcdHZhciBjaGVja19ib3ggPSBudWxsO1xuXG5cdFx0dmFyIGVuYWJsZWQgPSB0cnVlO1xuXG5cdFx0dmFyIGFsbG93X2RyYWdfdG9fb3JkZXIgPSBmYWxzZTtcblxuXHRcdHZhciBuYXZpZ2F0aW9uX21vZGUgPSBmYWxzZTtcblxuXHRcdHZhciBhcmdzX2Zyb21fc2F2ZWRfbGF5b3V0ID0gbnVsbDtcblxuXHRcdHZhciBkZWZhdWx0X2FyZ3MgPSBudWxsO1xuXHRcdC8vVXNlIHRoaXMgaW4gTmF2aWdhdGlvbiBNb2RlLCBLZWVwIHNlYXJjaCBmaWx0ZXIgd2hlbiBvcGVuLiBEb24ndCBjbGVhbiBpdCBpbiBvbkNsb3NlIGlmIG5hdmlnYXRpb25fbW9kZVxuXHRcdC8vIE5vdyB3ZSBkaSB0aGlzIGluIGJvdGggbmF2aWdhdGlvbiBhbmQgbm9ybWFsICgyMDE0LzYvNylcblx0XHR2YXIgY2FjaGVkX3NlYXJjaF9pbnB1dHNfZmlsdGVyID0gbnVsbDtcblxuXHRcdHZhciBjYWNoZWRfc2VsZWN0X2dyaWRfc2VhcmNoX2lucHV0c19maWx0ZXIgPSBudWxsO1xuXG5cdFx0dmFyIGNhY2hlZF9zb3J0X2ZpbHRlciA9IG51bGw7IC8vU2FtZSBhcyBhYm92ZVxuXG5cdFx0dmFyIGNhY2hlZF9zZWxlY3RlZF9ncmlkX3NvcnRfZmlsdGVyID0gbnVsbDsgLy9TYW1lIGFzIGFib3ZlXG5cblx0XHR2YXIgc2NyaXB0X25hbWUgPSAnJztcblxuXHRcdHZhciBuYXZpZ2F0aW9uX21vZGVfc291cmNlX2RhdGFfYmVmb3JlX29wZW4gPSBudWxsO1xuXG5cdFx0dmFyIHNldF9kZWZhdWx0X2FyZ3NfbWFudWFsbHkgPSBmYWxzZTsgLy9JZiBzZXQgZGVmYXVsdCBhcmdzIG91dHNpZGVcblxuXHRcdHZhciBhZGRpdGlvbl9zb3VyY2VfZnVuY3Rpb24gPSBudWxsO1xuXG5cdFx0dmFyIGN1c3RvbV9rZXlfbmFtZSA9IG51bGw7XG5cblx0XHR2YXIgc2V0UmVhbFZhbHVlQ2FsbEJhY2sgPSBudWxsOyAvL1NldCByZWFsIGRhdGEgY2FsbCBiYWNrIGZ1bmN0aW9uXG5cblx0XHR2YXIgY3VzdG9tX2ZpcnN0X2xhYmVsID0gbnVsbDtcblxuXHRcdHZhciBhZGRlZF9pdGVtcyA9IG51bGw7XG5cblx0XHR2YXIgY29sdW1uX29wdGlvbl9rZXkgPSAnY29sdW1ucyc7XG5cblx0XHQvLyBzZXQgdGhpcyB3aGVuIGNsb3NlLCBkb24ndCBhbGxvdyBhd2Vzb21lYm94IG9wZW4gdW50aWwgMC4zIHNlYywgdGhpcyBwcmV2ZW50IGF3ZXNvbWVib3ggY2xvc2UgaW4gbW91c2Vkb3duLCBhbmQgb3BlbiBpbiBjbGljay5cblx0XHR2YXIgZG9udE9wZW5UaW1lciA9IG51bGw7XG5cblx0XHR2YXIgZG9udE9wZW4gPSBmYWxzZTtcblxuXHRcdHZhciB0b3RhbF9oZWFkZXJfd2lkdGg7XG5cblx0XHQvL2lmIGluaXQgc291cmNlIGRhdGEgcmlnaHQgYWZ0ZXIgaW5pdGNvbHVtbnMgY29tcGxldGVcblx0XHR2YXIgaW5pdF9kYXRhX2ltbWVkaWF0ZWx5ID0gZmFsc2U7XG5cblx0XHR2YXIgdW5zZWxlY3RfZ3JpZF9zZWFyY2hfcmVzdWx0O1xuXG5cdFx0Ly8gZG9uJ3QgZG8gY29sdW1uIGZpbHRlciBiYXNlIG9uIGRpc3BsYXkgY29sdW1ucywgdXNlIGFsbCBpbnN0ZWFkXG5cdFx0Ly9Vc2UgaW4gcmVwb3J0IGVkaXQgdmlldy4gbG9hZCBzYXZlZCByZXBvcnQgbmF2aWdhdGlvblxuXHRcdHZhciBhbHdheXNfc2VhcmNoX2Z1bGxfY29sdW1ucyA9IGZhbHNlO1xuXG5cdFx0Ly9TYXZlIHdoYXQgbGV0dGVyIHVzZXIgY3VycmVudCB1c2UgdG8gZG8gdGhlIHNlYXJjaFxuXHRcdHZhciBxdWlja19zZWFyY2hfZGljID0ge307XG5cblx0XHQvL1NhdmUgbXVsdGkga2V5IHR5cGVkIHdoZW4gcXVpY2sgc2VhcmNoXG5cdFx0dmFyIHF1aWNrX3NlYXJjaF90eXBlZF9rZXlzID0gJyc7XG5cblx0XHR2YXIgc2VsZWN0X2dyaWRfc2VhcmNoX3Jlc3VsdDtcblxuXHRcdC8vdXNlIHRvIGp1ZWRnZSBpZiBuZWVkIHRvIGNsZWFyIHF1aWNrX3NlYXJjaF90eXBlZF9rZXlzXG5cdFx0dmFyIHF1aWNrX3NlYXJjaF90aW1lcjtcblxuXHRcdHZhciBjdXJyZW50X29wZW5fcGFnZSA9IDE7XG5cblx0XHQvL2RlYWwgd2l0aCByZXN1bHQgd2hlbiBkb2luZyBkcm9wZG93biBzZWFyY2gsIFRpbWVzaGVldEF1dGhvcml6YXRpb25WaWV3Q29udHJvbCBuZWVkIHRoaXMuXG5cdFx0dmFyIGV4dGVuZERhdGFQcm9jZXNzV2hlblNlYXJjaDtcblxuXHRcdHZhciBhbHdheXNfaW5jbHVkZV9jb2x1bW5zID0gZmFsc2U7XG4vL1xuLy9cdFx0Ly9Vc2VkIGZvciBtb2RpZnkgc2VhcmNoIHJlc3VsdCB3aGVuIGRvaW5nIFBhZ2luZyBvciBTZWFyY2hpbmcsIEZvciBleGFtcGxlLCB1c2VkIGluIEFjY3J1YWxCYWxhbmNlVmlld0NvbnRyb2xsZXIgdG8gc2V0IGNvcnJlY3QgaWRzXG4vL1x0XHR0aGlzLmN1c3RvbVNlYXJjaFJlc3VsdEhhbmRsZXIgPSBudWxsO1xuXG5cdFx0Ly9Vc2VkIGZvciBtb2RpZnkgc2VhcmNoIGZpbHRlciB3aGVuIG9wZW4gYXdlc29tZWJveCBvciBkbyBzZWFyY2gvc29ydGluZyBhbmQgcGFnaW5nLiBGaXJzdCB1c2VkIGluIFRpbWVoc2hlZXQgYWJzZW5jeV9wb2xpY3kgYXdlc29tZWJveFxuXHRcdHRoaXMuY3VzdG9tU2VhcmNoRmlsdGVyID0gbnVsbDtcblxuXHRcdHRoaXMuZ2V0Q3VycmVudE9wZW5QYWdlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gY3VycmVudF9vcGVuX3BhZ2U7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0UGFnZXJEYXRhID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gcGFnZXJfZGF0YTtcblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRIZWFkZXJXaWR0aCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHRvdGFsX2hlYWRlcl93aWR0aDtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRLZXkgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0a2V5ID0gdmFsO1xuXHRcdH07XG5cblx0XHR0aGlzLmdldERpc3BsYXlDb2x1bW5zID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gZGlzcGxheV9jb2x1bW5zO1xuXHRcdH07XG5cblx0XHR0aGlzLmdldExheW91dCA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRyZXR1cm4gQUxheW91dENhY2hlLmxheW91dF9kaWNbbGF5b3V0X25hbWVdO1xuXHRcdH07XG5cblx0XHR0aGlzLmdldEFQSSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGFwaTtcblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRTY3JpcHROYW1lID0gZnVuY3Rpb24oKSB7XG5cblx0XHRcdHNjcmlwdF9uYW1lID0gR2xvYmFsLmdldFNjcmlwdE5hbWVCeUFQSSggYXBpX2NsYXNzICk7XG5cblx0XHRcdHJldHVybiBzY3JpcHRfbmFtZTtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRDYWNoZWRTb3J0RmlsdGVyID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdGNhY2hlZF9zb3J0X2ZpbHRlciA9IHZhbDtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRDYWNoZWRTZWxlY3RlZEdyaWRTb3J0RmlsdGVyID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdGNhY2hlZF9zZWxlY3RlZF9ncmlkX3NvcnRfZmlsdGVyID0gdmFsO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldENhY2hlZFNlYXJjaElucHV0c0ZpbHRlciA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRjYWNoZWRfc2VhcmNoX2lucHV0c19maWx0ZXIgPSB2YWw7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0Q2FjaGVkU2VsZWN0R3JpZFNlYXJjaElucHV0c0ZpbHRlciA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRjYWNoZWRfc2VsZWN0X2dyaWRfc2VhcmNoX2lucHV0c19maWx0ZXIgPSB2YWw7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0QWxsb3dNdWx0aXBsZVNlbGVjdGlvbiA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRhbGxvd19tdWx0aXBsZV9zZWxlY3Rpb24gPSB2YWw7XG5cblx0XHRcdGlmICggdmFsID09IHRydWUgKSB7XG5cdFx0XHRcdGlmICggc2VsZWN0X2l0ZW0gKSB7XG5cdFx0XHRcdFx0c2VsZWN0X2l0ZW1zID0gW3NlbGVjdF9pdGVtXTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCBzZWxlY3RfaXRlbXMgJiYgc2VsZWN0X2l0ZW1zLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRcdFx0c2VsZWN0X2l0ZW0gPSBzZWxlY3RfaXRlbXNbMF07XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLmdldEVuYWJsZWQgPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBlbmFibGVkO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldEVuYWJsZWQgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0ZW5hYmxlZCA9IHZhbDtcblx0XHRcdGlmICggdmFsID09PSBmYWxzZSB8fCB2YWwgPT09ICcnICkge1xuXHRcdFx0XHQkdGhpcy5hZGRDbGFzcyggJ2EtY29tYm9ib3gtcmVhZG9ubHknICk7XG5cdFx0XHRcdGlmICggY2hlY2tfYm94ICkge1xuXHRcdFx0XHRcdGNoZWNrX2JveC5oaWRlKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCAhdGhpcy5jaGlsZHJlbigpLmVxKCAxICkudGV4dCgpICkge1xuXHRcdFx0XHRcdHRoaXMuY2hpbGRyZW4oKS5lcSggMSApLnRleHQoICQuaTE4bi5fKCAnTi9BJyApICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdCR0aGlzLnJlbW92ZUNsYXNzKCAnYS1jb21ib2JveC1yZWFkb25seScgKTtcblxuXHRcdFx0XHRpZiAoIGNoZWNrX2JveCApIHtcblx0XHRcdFx0XHRjaGVja19ib3guc2hvdygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICggIXRoaXMuY2hpbGRyZW4oKS5lcSggMSApLnRleHQoKSA9PT0gJC5pMThuLl8oICdOL0EnICkgKSB7XG5cdFx0XHRcdFx0dGhpcy5jaGlsZHJlbigpLmVxKCAxICkudGV4dCggJycgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0Q2hlY2tCb3ggPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0aWYgKCBjaGVja19ib3ggKSB7XG5cdFx0XHRcdGNoZWNrX2JveC5jaGlsZHJlbigpLmVxKCAwIClbMF0uY2hlY2tlZCA9IHZhbDtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhpcy5pc0NoZWNrZWQgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggY2hlY2tfYm94ICkge1xuXHRcdFx0XHRpZiAoIGNoZWNrX2JveC5jaGlsZHJlbigpLmVxKCAwIClbMF0uY2hlY2tlZCA9PT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0TWFzc0VkaXRNb2RlID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdG1hc3NfZWRpdF9tb2RlID0gdmFsO1xuXG5cdFx0XHRpZiAoIG1hc3NfZWRpdF9tb2RlICkge1xuXHRcdFx0XHRjaGVja19ib3ggPSAkKCAnIDxkaXYgY2xhc3M9XCJtYXNzLWVkaXQtY2hlY2tib3gtd3JhcHBlclwiPjxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cIm1hc3MtZWRpdC1jaGVja2JveFwiPjwvaW5wdXQ+JyArXG5cdFx0XHRcdFx0JzxsYWJlbCBmb3I9XCJjaGVja2JveC1pbnB1dC0xXCIgY2xhc3M9XCJpbnB1dC1oZWxwZXIgaW5wdXQtaGVscGVyLS1jaGVja2JveFwiPjwvbGFiZWw+PC9kaXY+JyApO1xuXHRcdFx0XHRjaGVja19ib3guaW5zZXJ0QmVmb3JlKCAkKCB0aGlzICkgKTtcblxuXHRcdFx0XHRjaGVja19ib3guY2hhbmdlKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHQkdGhpcy50cmlnZ2VyKCAnZm9ybUl0ZW1DaGFuZ2UnLCBbJHRoaXNdICk7XG5cdFx0XHRcdH0gKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCBjaGVja19ib3ggKSB7XG5cdFx0XHRcdFx0Y2hlY2tfYm94LnJlbW92ZSgpO1xuXHRcdFx0XHRcdGNoZWNrX2JveCA9IG51bGw7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLmdldEl0ZW1CeUluZGV4ID0gZnVuY3Rpb24oIGluZGV4ICkge1xuXHRcdFx0dmFyIHRhcmdldF9zb3VyY2VfZGF0YTtcblxuXHRcdFx0aWYgKCBuYXZpZ2F0aW9uX21vZGUgJiYgIXNvdXJjZV9kYXRhICkge1xuXHRcdFx0XHR0YXJnZXRfc291cmNlX2RhdGEgPSBuYXZpZ2F0aW9uX21vZGVfc291cmNlX2RhdGFfYmVmb3JlX29wZW47XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0YXJnZXRfc291cmNlX2RhdGEgPSBzb3VyY2VfZGF0YTtcblxuXHRcdFx0XHQvL09ubHkgZm9yIHNpbmdsZSBtb2RlXG5cdFx0XHRcdGlmICggdW5zZWxlY3RfZ3JpZF9zZWFyY2hfcmVzdWx0ICYmIHVuc2VsZWN0X2dyaWRfc2VhcmNoX3Jlc3VsdC5sZW5ndGggPiAwICkge1xuXHRcdFx0XHRcdHRhcmdldF9zb3VyY2VfZGF0YSA9IHVuc2VsZWN0X2dyaWRfc2VhcmNoX3Jlc3VsdDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoICF0YXJnZXRfc291cmNlX2RhdGEgKSB7XG5cdFx0XHRcdHJldHVybiBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgcmVzdWx0ID0gbnVsbDtcblx0XHRcdHJlc3VsdCA9IHRhcmdldF9zb3VyY2VfZGF0YVtpbmRleF07XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0U2VsZWN0SW5kZXggPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0dmFyIHRhcmdldF9zb3VyY2VfZGF0YTtcblxuXHRcdFx0aWYgKCBuYXZpZ2F0aW9uX21vZGUgJiYgIXNvdXJjZV9kYXRhICkge1xuXHRcdFx0XHR0YXJnZXRfc291cmNlX2RhdGEgPSBuYXZpZ2F0aW9uX21vZGVfc291cmNlX2RhdGFfYmVmb3JlX29wZW47XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0YXJnZXRfc291cmNlX2RhdGEgPSBzb3VyY2VfZGF0YTtcblxuXHRcdFx0XHQvL09ubHkgZm9yIHNpbmdsZSBtb2RlXG5cdFx0XHRcdGlmICggdW5zZWxlY3RfZ3JpZF9zZWFyY2hfcmVzdWx0ICYmIHVuc2VsZWN0X2dyaWRfc2VhcmNoX3Jlc3VsdC5sZW5ndGggPiAwICkge1xuXHRcdFx0XHRcdHRhcmdldF9zb3VyY2VfZGF0YSA9IHVuc2VsZWN0X2dyaWRfc2VhcmNoX3Jlc3VsdDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoICFzZWxlY3RfaXRlbSB8fCAhdGFyZ2V0X3NvdXJjZV9kYXRhICkgeyAvLyBjYW4ndCBnZXQgY29ycmVjdCBpbmRleCBpZiBzb3VyY2VfZGF0YSBpcyBudWxsXG5cdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgbGVuID0gdGFyZ2V0X3NvdXJjZV9kYXRhLmxlbmd0aDtcblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHR2YXIgaXRlbSA9IHRhcmdldF9zb3VyY2VfZGF0YVtpXTtcblx0XHRcdFx0aWYgKCBzZWxlY3RfaXRlbVtrZXldID09PSBpdGVtW2tleV0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0TmV4dFNlbGVjdEl0ZW1JZCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHJldHZhbCA9IG51bGw7XG5cdFx0XHQvLyBUaGlzIGZ1bmN0aW9uIGlzIGNvbW1vbmx5IHVzZWQgYnkgZWRpdCB2aWV3cyB0byBnZXQgdGhlIGlkIG9mIHRoZSBuZXh0IHJlY29yZCBmcm9tIHRoZSBuYXZpZ2F0aW9uIGJveCwgc3VjaCBhcyBkdXJpbmcgRGVsZXRlJk5leHRcblx0XHRcdHZhciBuZXh0X3NlbGVjdF9pdGVtID0gdGhpcy5nZXRTZWxlY3RJbmRleCgpICsgMTtcblx0XHRcdHZhciBzb3VyY2VfZGF0YSA9IHRoaXMuZ2V0U291cmNlRGF0YSgpO1xuXHRcdFx0aWYgKCBzb3VyY2VfZGF0YSAmJiBuZXh0X3NlbGVjdF9pdGVtIDwgc291cmNlX2RhdGEubGVuZ3RoICkge1xuXHRcdFx0XHRyZXR2YWwgPSB0aGlzLmdldEl0ZW1CeUluZGV4KCBuZXh0X3NlbGVjdF9pdGVtICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR2YWwgPSBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmV0dmFsO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldEVycm9yU3R5bGUgPSBmdW5jdGlvbiggZXJyU3RyLCBzaG93LCBpc1dhcm5pbmcgKSB7XG5cdFx0XHRpZiAoIGlzV2FybmluZyApIHtcblx0XHRcdFx0JCggdGhpcyApLmFkZENsYXNzKCAnYS13YXJuaW5nLXRpcCcgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdCQoIHRoaXMgKS5hZGRDbGFzcyggJ2EtZXJyb3ItdGlwJyApO1xuXHRcdFx0fVxuXHRcdFx0ZXJyb3Jfc3RyaW5nID0gZXJyU3RyO1xuXG5cdFx0XHRpZiAoIHNob3cgKSB7XG5cdFx0XHRcdHRoaXMuc2hvd0Vycm9yVGlwKCk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoaXMuc2hvd0Vycm9yVGlwID0gZnVuY3Rpb24oIHNlYyApIHtcblxuXHRcdFx0aWYgKCAhR2xvYmFsLmlzU2V0KCBzZWMgKSApIHtcblx0XHRcdFx0c2VjID0gMjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCAhZXJyb3JfdGlwX2JveCApIHtcblx0XHRcdFx0ZXJyb3JfdGlwX2JveCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBXaWRnZXROYW1lc0RpYy5FUlJPUl9UT09MVElQICk7XG5cdFx0XHRcdGVycm9yX3RpcF9ib3ggPSBlcnJvcl90aXBfYm94LkVycm9yVGlwQm94KCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoICQoIHRoaXMgKS5oYXNDbGFzcyggJ2Etd2FybmluZy10aXAnICkgKSB7XG5cdFx0XHRcdGVycm9yX3RpcF9ib3guc2hvdyggdGhpcywgZXJyb3Jfc3RyaW5nLCBzZWMsIHRydWUgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVycm9yX3RpcF9ib3guc2hvdyggdGhpcywgZXJyb3Jfc3RyaW5nLCBzZWMgKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhpcy5oaWRlRXJyb3JUaXAgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGVycm9yX3RpcF9ib3ggKSApIHtcblx0XHRcdFx0ZXJyb3JfdGlwX2JveC5yZW1vdmUoKTtcblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLmNsZWFyRXJyb3JTdHlsZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0JCggdGhpcyApLnJlbW92ZUNsYXNzKCAnYS1lcnJvci10aXAnICk7XG5cdFx0XHQkKCB0aGlzICkucmVtb3ZlQ2xhc3MoICdhLXdhcm5pbmctdGlwJyApO1xuXHRcdFx0ZXJyb3Jfc3RyaW5nID0gJyc7XG5cdFx0XHR0aGlzLmhpZGVFcnJvclRpcCgpO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldEZpZWxkID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdGZpZWxkID0gdmFsO1xuXHRcdH07XG5cblx0XHR0aGlzLmdldEZpZWxkID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gZmllbGQ7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0VmFsaWRhdGlvbkZpZWxkID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gdmFsaWRhdGlvbl9maWVsZDtcblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRWYWx1ZSA9IGZ1bmN0aW9uKCByZXR1cm5fZnVsbF92YWx1ZSApIHtcblx0XHRcdHZhciByZXR1cm5fdmFsdWUgPSBudWxsO1xuXHRcdFx0aWYgKCBhbGxvd19tdWx0aXBsZV9zZWxlY3Rpb24gKSB7XG5cdFx0XHRcdGlmICggcmV0dXJuX2Z1bGxfdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuX3ZhbHVlID0gc2VsZWN0X2l0ZW1zO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJldHVybl92YWx1ZSA9IFtdO1xuXHRcdFx0XHRcdGlmICggR2xvYmFsLmlzQXJyYXkoIHNlbGVjdF9pdGVtcyApICkge1xuXHRcdFx0XHRcdFx0JC5lYWNoKCBzZWxlY3RfaXRlbXMsIGZ1bmN0aW9uKCBpbmRleCwgY29udGVudCApIHtcblx0XHRcdFx0XHRcdFx0Ly8gSW4gMTg5MSwgb25lIHZhbHVlIGluIHNlbGVjdCBpdGVtcyBpcyBudWxsXG5cdFx0XHRcdFx0XHRcdGlmICggY29udGVudCApIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIEdsb2JhbC5pc1N0cmluZyggY29udGVudCApIHx8ICQudHlwZSggY29udGVudCApID09PSAnbnVtYmVyJyApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybl92YWx1ZS5wdXNoKCBjb250ZW50ICk7XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybl92YWx1ZS5wdXNoKCBjb250ZW50W2tleV0gKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHRcdGlmICggc2VsZWN0X2l0ZW1zLmxlbmd0aCA9PT0gMCApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBzZXRfYW55ICkge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybl92YWx1ZS5wdXNoKCBUVFVVSUQubm90X2V4aXN0X2lkICk7IC8vIEluIGZhY3QsIGlmIHRoZSBjb2x1bW5zIGNhbiBiZSBtdWx0aXBsZSBzZWxlY3RlZC4gYW5kIG5vIGhhdmUgYW55IG9wdGlvbnMgc2VsZWN0ZWQsIGl0J3Mgc2hvdWxkIGJlIHJldHVybiBhbiBhcnJheS5cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRpZiAoIHNldF9hbnkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybl92YWx1ZS5wdXNoKCBUVFVVSUQubm90X2V4aXN0X2lkICk7IC8vIEluIGZhY3QsIGlmIHRoZSBjb2x1bW5zIGNhbiBiZSBtdWx0aXBsZSBzZWxlY3RlZC4gYW5kIG5vIGhhdmUgYW55IG9wdGlvbnMgc2VsZWN0ZWQsIGl0J3Mgc2hvdWxkIGJlIHJldHVybiBhbiBhcnJheS5cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gUmV0dXJuIGZhbHNlIHdoZW4gbm8gc2VsZWN0ZWQgdmFsdWVcblx0XHRcdFx0XHRpZiAoIHJldHVybl92YWx1ZS5sZW5ndGggPT09IDAgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIHNldF9hbnkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybl92YWx1ZSA9IFRUVVVJRC5ub3RfZXhpc3RfaWQ7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBzZXRfZW1wdHkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybl92YWx1ZSA9IFRUVVVJRC56ZXJvX2lkO1xuXHRcdFx0XHRcdFx0fSBlbHNlIGlmICggc2V0X3NwZWNpYWxfZW1wdHkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybl92YWx1ZSA9IFRUVVVJRC5ub3RfZXhpc3RfaWQ7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBzZXRfb3BlbiApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuX3ZhbHVlID0gVFRVVUlELnplcm9faWQ7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBzZXRfZGVmYXVsdCApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuX3ZhbHVlID0gVFRVVUlELnplcm9faWQ7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAoIHJldHVybl9mdWxsX3ZhbHVlICkge1xuXHRcdFx0XHRcdHJldHVybl92YWx1ZSA9IHNlbGVjdF9pdGVtO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGlmICggc2VsZWN0X2l0ZW0gKSB7XG5cblx0XHRcdFx0XHRcdGlmICggR2xvYmFsLmlzU2V0KCBzZWxlY3RfaXRlbVtrZXldICkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybl92YWx1ZSA9IHNlbGVjdF9pdGVtW2tleV07XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm5fdmFsdWUgPSBzZWxlY3RfaXRlbTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRpZiAoIHNldF9hbnkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBUVFVVSUQubm90X2V4aXN0X2lkO1xuXHRcdFx0XHRcdFx0fSBlbHNlIGlmICggc2V0X2VtcHR5ICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gVFRVVUlELnplcm9faWQ7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBzZXRfc3BlY2lhbF9lbXB0eSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIFRUVVVJRC5ub3RfZXhpc3RfaWQ7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBzZXRfb3BlbiApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIFRUVVVJRC56ZXJvX2lkO1xuXHRcdFx0XHRcdFx0fSBlbHNlIGlmICggc2V0X2RlZmF1bHQgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBUVFVVSUQuemVyb19pZDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmV0dXJuX3ZhbHVlO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldFNvdXJjZURhdGEgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0c291cmNlX2RhdGEgPSB2YWw7XG5cblx0XHRcdGlmICggIWFsbG93X211bHRpcGxlX3NlbGVjdGlvbiApIHtcblx0XHRcdFx0aWYgKCB2YWwgJiYgdmFsLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRcdFx0aWYgKCBzZXRfZW1wdHkgfHwgc2V0X2FueSB8fCBzZXRfZGVmYXVsdCB8fCBzZXRfb3BlbiB8fCBzZXRfYWxsIHx8IHNldF9zcGVjaWFsX2VtcHR5ICkge1xuXHRcdFx0XHRcdFx0JHRoaXMuY3JlYXRlRmlyc3RJdGVtKCk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGlmICggIXNlbGVjdF9pdGVtICkge1xuXHRcdFx0XHRcdFx0XHQvL1JlbGF0ZWQgdG8gMTgyNSwgZGlyZWN0bHkgdXNlIGl0ZW0gbm90IGl0ZW0gaWQsIHNpbmNlIHVzZSBpdGVtIGlkIHdpbGxsXG5cdFx0XHRcdFx0XHRcdC8vIHRyaWdnZXIgZ2V0UmVhbCBkYXRhIHdoaWNoIGNhc2UgcHJvYmxlbXMgYW5kIG5vdCBuZWNlc3NhcnkuXG5cdFx0XHRcdFx0XHRcdHRoaXMuc2V0VmFsdWUoIHZhbFswXSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCB2YWwgJiYgdmFsLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRcdFx0aWYgKCBzZXRfYWxsICkge1xuXHRcdFx0XHRcdFx0JHRoaXMuY3JlYXRlRmlyc3RJdGVtKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICggc2V0X3NlbGVjdF9pdGVtc193aGVuX3NldF9kYXRhX3Byb3ZpZGVyICYmIHNvdXJjZV9kYXRhICkge1xuXG5cdFx0XHRcdGlmICggYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uICkge1xuXHRcdFx0XHRcdHRoaXMuc2V0VmFsdWUoIHNlbGVjdF9pdGVtcyApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMuc2V0VmFsdWUoIHNlbGVjdF9pdGVtICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRTb3VyY2VEYXRhID0gZnVuY3Rpb24oKSB7XG5cblx0XHRcdGlmICggbmF2aWdhdGlvbl9tb2RlICYmIG5hdmlnYXRpb25fbW9kZV9zb3VyY2VfZGF0YV9iZWZvcmVfb3BlbiApIHtcblx0XHRcdFx0cmV0dXJuIG5hdmlnYXRpb25fbW9kZV9zb3VyY2VfZGF0YV9iZWZvcmVfb3Blbjtcblx0XHRcdH1cblxuXHRcdFx0Ly9pZiBkb25lIHNlYXJjaCwgcmV0dXJuIHRoZSByZXN1bHQgb1xuXHRcdFx0aWYgKCB1bnNlbGVjdF9ncmlkX3NlYXJjaF9yZXN1bHQgKSB7XG5cdFx0XHRcdHJldHVybiB1bnNlbGVjdF9ncmlkX3NlYXJjaF9yZXN1bHQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBzb3VyY2VfZGF0YTtcblx0XHR9O1xuXG5cdFx0Ly9BbHdheXMgcmV0dXJuIHNvdXJjZSBkYXRhIG9ubHlcblx0XHR0aGlzLmdldFN0YXRpY1NvdXJjZURhdGEgPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBzb3VyY2VfZGF0YTtcblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRSb3dQZXJQYWdlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gcm93X3Blcl9wYWdlO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldEFsbENvbHVtbnMgPSBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRhbGxfY29sdW1ucyA9IHZhbHVlO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldERpc3BsYXlDb2x1bW5zRm9yRWRpdG9yID0gZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0ZGlzcGxheV9jb2x1bW5zX2luX2NvbHVtbkVkaXRvciA9IHZhbHVlO1xuXHRcdH07XG5cblx0XHR0aGlzLmdldEFsbENvbHVtbnMgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0aWYgKCBwb3NzaWJsZV9kaXNwbGF5X2NvbHVtbnMgKSB7XG5cdFx0XHRcdHJldHVybiBwb3NzaWJsZV9kaXNwbGF5X2NvbHVtbnM7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gYWxsX2NvbHVtbnM7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0RGlzcGxheUNvbHVtbnNGb3JFZGl0b3IgPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBkaXNwbGF5X2NvbHVtbnNfaW5fY29sdW1uRWRpdG9yO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldEVtcHR5VmFsdWVBbmRTaG93TG9hZGluZyA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGN1cnJlbnRfd2lkdGggPSAkdGhpcy5maW5kKCAnLmEtY29tYm9ib3gtbGFiZWwnICkud2lkdGgoKTtcblx0XHRcdHRoaXMuc2V0VmFsdWUoIG51bGwgKTtcblx0XHRcdGxhYmVsX3NwYW4udGV4dCggR2xvYmFsLmxvYWRpbmdfbGFiZWwgKTtcblx0XHRcdCR0aGlzLmZpbmQoICcuYS1jb21ib2JveC1sYWJlbCcgKS53aWR0aCggY3VycmVudF93aWR0aCArICdweCcgKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRWYWx1ZSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHQvLyBSZWxhdGVkIHRvIDE4OTEsIG9uZSBjYXNlIGlzIHZhbHVlIGlzIFtudWxsXSBpbiB2YWNhdHVvbl9wc2VhX2lkcyBpbiBST0UgZWRpdCB2aWV3XG5cdFx0XHRpZiAoIF8uaXNBcnJheSggdmFsICkgJiYgdmFsLmxlbmd0aCA9PT0gMSAmJiB2YWxbMF0gPT09IG51bGwgKSB7XG5cdFx0XHRcdHZhbCA9IG51bGw7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGFsbG93X211bHRpcGxlX3NlbGVjdGlvbiApIHtcblx0XHRcdFx0aWYgKCAhdmFsIHx8ICQudHlwZSggdmFsICkgPT09ICdhcnJheScgKSB7XG5cdFx0XHRcdFx0dGhpcy5zZXRTZWxlY3RJdGVtcyggdmFsICk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoICQudHlwZSggdmFsICkgPT09ICdzdHJpbmcnIHx8ICQudHlwZSggdmFsICkgPT09ICdudW1iZXInICkge1xuXHRcdFx0XHRcdHRoaXMuc2V0U2VsZWN0SXRlbXMoIFt2YWxdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGlmICggJC50eXBlKCB2YWwgKSA9PT0gJ2FycmF5JyAmJiB2YWwubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHR2YWwgPSB2YWxbMF07XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly9JZiBubyBkZWZhdWx0IHZhbHVlIHNldCBmaXJzdCBpdGVtIGFzIGRlZmF1bHQgc2VsZWN0IGl0ZW1cblx0XHRcdFx0Ly8jMTE4NyAtIHRoaXMgZml4IG1pZ2h0IGNhdXNlIHByb2JsZW1zIGJ1dCBpcyBuZWVkZWQgdG8gYWxsb3cgcHJvcGVyIHNlbGVjdGlvbiBvZiBkZWZhdWx0IHZhbHVlIHdoZW4gemVyb191dWlkIGlzIHNlbGVjdGVkLlxuXHRcdFx0XHRpZiAoICF2YWwgfHwgdmFsID09IFRUVVVJRC56ZXJvX2lkICkge1xuXHRcdFx0XHRcdC8vIGlmICggIXZhbCApIHtcblx0XHRcdFx0XHRpZiAoICFzZXRfZW1wdHkgJiYgIXNldF9hbnkgJiYgIXNldF9kZWZhdWx0ICYmICFzZXRfb3BlbiAmJiAhc2V0X2FsbCAmJiAhc2V0X3NwZWNpYWxfZW1wdHkgJiYgc291cmNlX2RhdGEgJiYgc291cmNlX2RhdGEubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHRcdHRoaXMuc2V0VmFsdWUoIHNvdXJjZV9kYXRhWzBdICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRoaXMuc2V0U2VsZWN0SXRlbSggbnVsbCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdHRoaXMuc2V0U2VsZWN0SXRlbSggdmFsICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLmdldEFsbG93TXVsdGlwbGVTZWxlY3Rpb24gPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBhbGxvd19tdWx0aXBsZV9zZWxlY3Rpb247XG5cdFx0fTtcblxuXHRcdC8vR2V0IGZ1bGwgZGF0YSBmcm9tIGFwaSwgaWYgZ2V0IGEgaWRcblx0XHR0aGlzLmdldFJlYWxEYXRhID0gZnVuY3Rpb24oIHZhbCApIHtcblxuXHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGFwaV9jbGFzcyApICkge1xuXG5cdFx0XHRcdC8vVHJ5IGFwaSBhd2Vzb21lYm94IGZpcnN0XG5cdFx0XHRcdGlmICggKCAhVFRVVUlELmlzVVVJRCggdmFsICkgJiYgcGFyc2VJbnQoIHZhbCApIDw9IDAgKSB8fCB2YWwgPT0gVFRVVUlELnplcm9faWQgfHwgdmFsID09IFRUVVVJRC5ub3RfZXhpc3RfaWQgKSB7XG5cblx0XHRcdFx0XHRpZiAoIGFsbG93X211bHRpcGxlX3NlbGVjdGlvbiApIHtcblx0XHRcdFx0XHRcdCR0aGlzLnNldFZhbHVlKCBbdGhpcy5nZXRMb2NhbFNlbGVjdEl0ZW0oIHZhbCApXSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQkdGhpcy5zZXRWYWx1ZSggdGhpcy5nZXRMb2NhbFNlbGVjdEl0ZW0oIHZhbCApICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dmFyIGZpbHRlciA9IHt9O1xuXHRcdFx0XHQvL2lkIGlzIGEgcHVibGljIG1lbWJlciBvZiB0aGlzIGNsYXNzIHdoaWNoIGNvbnRhaW5zIHRoZSBmaWVsZCBpZCwgc28gd2Ugd3JhcHBlZCAnaWQnIGluIHF1b3RlcyBoZXJlIHRvIHNob3cgaXQncyBub3QgdGhlIHB1YmxpYyBtZW1iZXIgZnJvbSBhYm92ZS5cblx0XHRcdFx0ZmlsdGVyLmZpbHRlcl9kYXRhID0geyAnaWQnOiB2YWwgfTtcblxuXHRcdFx0XHQvLyMyMjg5IC0gSWYgeW91IGhhdmUgYW4gZW1wbG95ZWUgd2hvIGNhbiB2aWV3IHN1Ym9yZGluYXRlIHB1bmNoZXMgYnV0IG5vdCB2aWV3IHN1Ym9yZGluYXRlIGVtcGxveWVlLCB5b3Ugd2lsbCBzZWUgcGVybWlzc2lvbiBkZW5pZWQgd2l0aG91dCBzZW5kaW5nIHRoZSBwZXJtaXNzaW9uIHNlY3Rpb24uXG5cdFx0XHRcdGlmICggZGVmYXVsdF9hcmdzICYmIEdsb2JhbC5pc1NldCggZGVmYXVsdF9hcmdzLnBlcm1pc3Npb25fc2VjdGlvbiApICkge1xuXHRcdFx0XHRcdGZpbHRlci5wZXJtaXNzaW9uX3NlY3Rpb24gPSBkZWZhdWx0X2FyZ3MucGVybWlzc2lvbl9zZWN0aW9uO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCB0aGlzLmN1c3RvbVNlYXJjaEZpbHRlciApIHtcblx0XHRcdFx0XHRmaWx0ZXIgPSB0aGlzLmN1c3RvbVNlYXJjaEZpbHRlciggZmlsdGVyICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRsYWJlbF9zcGFuLnRleHQoIEdsb2JhbC5sb2FkaW5nX2xhYmVsICk7XG5cblx0XHRcdFx0YXBpWydnZXQnICsgY3VzdG9tX2tleV9uYW1lXSggZmlsdGVyLCB7XG5cdFx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXN1bHQgKSB7XG5cdFx0XHRcdFx0XHR2YXIgcmVzdWx0X2RhdGEgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cblx0XHRcdFx0XHRcdGlmICggcmVzdWx0X2RhdGEgJiYgcmVzdWx0X2RhdGEubGVuZ3RoID4gMCApIHtcblxuXHRcdFx0XHRcdFx0XHR2YXIgdmFsdWU7XG5cdFx0XHRcdFx0XHRcdGlmICggYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uICkge1xuXHRcdFx0XHRcdFx0XHRcdHZhbHVlID0gcmVzdWx0X2RhdGE7XG5cdFx0XHRcdFx0XHRcdFx0JHRoaXMuc2V0VmFsdWUoIHJlc3VsdF9kYXRhICk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0dmFsdWUgPSByZXN1bHRfZGF0YVswXTtcblx0XHRcdFx0XHRcdFx0XHQkdGhpcy5zZXRWYWx1ZSggcmVzdWx0X2RhdGFbMF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGlmICggc2V0UmVhbFZhbHVlQ2FsbEJhY2sgKSB7XG5cdFx0XHRcdFx0XHRcdHNldFJlYWxWYWx1ZUNhbGxCYWNrKCB2YWx1ZSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAoIHNvdXJjZV9kYXRhICYmIHNvdXJjZV9kYXRhLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRcdFx0JC5lYWNoKCBzb3VyY2VfZGF0YSwgZnVuY3Rpb24oIGluZGV4LCBjb250ZW50ICkge1xuXG5cdFx0XHRcdFx0XHQvL01ha2UgdGhlIGlkIG1hdGNoIHdoZW4gdmFsIGlzIHN0cmluZyBvciBudW1iZXIuIHVzZSA9PSBpbnN0ZWFkID09PS5cblx0XHRcdFx0XHRcdGlmICggY29udGVudFtrZXldID09IHZhbCApIHtcblxuXHRcdFx0XHRcdFx0XHQkdGhpcy5zZXRWYWx1ZSggY29udGVudCApO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7IC8vVGhpcyBpcyBhIGJvb2xlYW4gZmFsc2UsIG5vdCBhbiBpbnRlZ2VyIG9yIFVVSUQuXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c2V0X3NlbGVjdF9pdGVtc193aGVuX3NldF9kYXRhX3Byb3ZpZGVyID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0Q29sdW1uRmlsdGVyID0gZnVuY3Rpb24oKSB7XG5cblx0XHRcdGlmICggYWx3YXlzX3NlYXJjaF9mdWxsX2NvbHVtbnMgKSB7XG5cdFx0XHRcdHJldHVybiB7fTtcblx0XHRcdH1cblxuXHRcdFx0dmFyIGNvbHVtbl9maWx0ZXIgPSB7fTtcblx0XHRcdGNvbHVtbl9maWx0ZXIuaXNfb3duZXIgPSB0cnVlO1xuXHRcdFx0Y29sdW1uX2ZpbHRlci5pZCA9IHRydWU7XG5cdFx0XHRjb2x1bW5fZmlsdGVyLmlzX2NoaWxkID0gdHJ1ZTtcblx0XHRcdGNvbHVtbl9maWx0ZXIudXNlcl9pZCA9IHRydWU7XG5cdFx0XHRjb2x1bW5fZmlsdGVyLmZpcnN0X25hbWUgPSB0cnVlOyAvL2Fsd2F5cyBjb250YWlucyB0aGlzIGlmIGl0IGV4aXN0c1xuXHRcdFx0Y29sdW1uX2ZpbHRlci5sYXN0X25hbWUgPSB0cnVlOyAvL2Fsd2F5cyBjb250YWlucyB0aGlzIGlmIGl0IGV4aXN0c1xuXHRcdFx0Y29sdW1uX2ZpbHRlci5vYmplY3RfdHlwZV9pZCA9IHRydWU7XG5cdFx0XHRjb2x1bW5fZmlsdGVyLm1hbnVhbF9pZCA9IHRydWU7XG5cdFx0XHRjb2x1bW5fZmlsdGVyLmRlZmF1bHRfaXRlbV9pZCA9IHRydWU7XG5cdFx0XHRjb2x1bW5fZmlsdGVyLmFjY3J1YWxfcG9saWN5X2lkID0gdHJ1ZTtcblx0XHRcdGNvbHVtbl9maWx0ZXIucGF5X2NvZGVfaWQgPSB0cnVlO1xuXHRcdFx0Y29sdW1uX2ZpbHRlci5zdGFydF9kYXRlID0gdHJ1ZTtcblx0XHRcdGNvbHVtbl9maWx0ZXIuZW5kX2RhdGUgPSB0cnVlO1xuXHRcdFx0Y29sdW1uX2ZpbHRlci5wYXlfcGVyaW9kX2lkID0gdHJ1ZTtcblxuXHRcdFx0aWYgKCBhcGkgJiYgYXBpLmNsYXNzTmFtZSA9PT0gJ0FQSVVzZXInICkge1xuXHRcdFx0XHRjb2x1bW5fZmlsdGVyLnBheV9wZXJpb2Rfc2NoZWR1bGVfaWQgPSB0cnVlO1xuXHRcdFx0XHRjb2x1bW5fZmlsdGVyLnBvbGljeV9ncm91cF9pZCA9IHRydWU7XG5cdFx0XHRcdGNvbHVtbl9maWx0ZXIuaGlyZV9kYXRlID0gdHJ1ZTtcblx0XHRcdFx0Y29sdW1uX2ZpbHRlci50ZXJtaW5hdGlvbl9kYXRlID0gdHJ1ZTtcblx0XHRcdH1cblxuXHRcdFx0JC5lYWNoKCBkaXNwbGF5X2NvbHVtbnMsIGZ1bmN0aW9uKCBrZXksIGl0ZW0gKSB7XG5cdFx0XHRcdGNvbHVtbl9maWx0ZXJbaXRlbS5uYW1lXSA9IHRydWU7XG5cdFx0XHR9ICk7XG5cblx0XHRcdGlmICggYWx3YXlzX2luY2x1ZGVfY29sdW1ucyAmJiBhbHdheXNfaW5jbHVkZV9jb2x1bW5zLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRcdCQuZWFjaCggYWx3YXlzX2luY2x1ZGVfY29sdW1ucywgZnVuY3Rpb24oIGtleSwgaXRlbSApIHtcblx0XHRcdFx0XHRjb2x1bW5fZmlsdGVyW2l0ZW1dID0gdHJ1ZTtcblx0XHRcdFx0fSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gY29sdW1uX2ZpbHRlcjtcblx0XHR9O1xuXG5cdFx0dGhpcy5jbGVhbkRyb3BEb3duVmFsdWVzID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGFfZHJvcGRvd24gKSB7XG5cdFx0XHRcdGFfZHJvcGRvd24uc2V0U2VsZWN0R3JpZERhdGEoIFtdICk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0U2VsZWN0SXRlbSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHQvL1doZW4gc2V0dGluZyBzZWxlY3RfaXRlbSwgY2xlYXIgb3V0IHRoZSBzZWxlY3RfaXRlbXMgKHBsdXJhbCkgdmFyaWFibGUgc28gaXQgZG9lc24ndCBjb250YWluIG9sZCBkYXRhIGlmIHRoZSBkcm9wZG93biBib3ggaGFwcGVucyB0byBnZXQgc3dpdGNoZWQgYmFjayB0byBpdC5cblx0XHRcdHNlbGVjdF9pdGVtcyA9IG51bGw7XG5cblx0XHRcdHNlbGVjdF9pdGVtID0gdmFsO1xuXG5cdFx0XHRpZiAoIHZhbCA9PT0gZmFsc2UgfHwgdmFsID09PSAnJyApIHtcblx0XHRcdFx0dGhpcy5zZXRMYWJlbCggdmFsICk7XG5cdFx0XHRcdGlmICggc2V0UmVhbFZhbHVlQ2FsbEJhY2sgKSB7XG5cdFx0XHRcdFx0c2V0UmVhbFZhbHVlQ2FsbEJhY2soIGZhbHNlICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoICQudHlwZSggdmFsICkgPT09ICdzdHJpbmcnIHx8ICQudHlwZSggdmFsICkgPT09ICdudW1iZXInICkge1xuXHRcdFx0XHR0aGlzLmdldFJlYWxEYXRhKCB2YWwgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuc2V0TGFiZWwoKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRTZWxlY3RJdGVtcyA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHQvL1doZW4gc2V0dGluZyBzZWxlY3RfaXRlbXMgKHBsdXJhbCksIGNsZWFyIG91dCB0aGUgc2VsZWN0X2l0ZW0gdmFyaWFibGUgc28gaXQgZG9lc24ndCBjb250YWluIG9sZCBkYXRhIGlmIHRoZSBkcm9wZG93biBib3ggaGFwcGVucyB0byBnZXQgc3dpdGNoZWQgYmFjayB0byBpdC5cblx0XHRcdHNlbGVjdF9pdGVtID0gbnVsbDtcblxuXHRcdFx0aWYgKCAhdmFsIHx8IHZhbC5sZW5ndGggPCAxICkge1xuXHRcdFx0XHR0aGlzLnNldEVtcHR5TGFiZWwoKTtcblx0XHRcdFx0c2VsZWN0X2l0ZW1zID0gbnVsbDtcblx0XHRcdFx0aWYgKCBzZXRSZWFsVmFsdWVDYWxsQmFjayApIHtcblx0XHRcdFx0XHRzZXRSZWFsVmFsdWVDYWxsQmFjayggZmFsc2UgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoaXMuY2xlYW5Ecm9wRG93blZhbHVlcygpO1xuXG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH0gZWxzZSBpZiAoIHZhbCA9PSBUVFVVSUQubm90X2V4aXN0X2lkICYmIHNldF9hbnkgKSB7XG5cdFx0XHRcdHNlbGVjdF9pdGVtcyA9IHZhbDtcblx0XHRcdFx0dGhpcy5zZXRFbXB0eUxhYmVsKCk7XG5cdFx0XHRcdGlmICggc2V0UmVhbFZhbHVlQ2FsbEJhY2sgKSB7XG5cdFx0XHRcdFx0c2V0UmVhbFZhbHVlQ2FsbEJhY2soIGZhbHNlICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5jbGVhbkRyb3BEb3duVmFsdWVzKCk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0c2VsZWN0X2l0ZW1zID0gdmFsO1xuXG5cdFx0XHR2YXIgbGVuID0gdmFsLmxlbmd0aDtcblxuXHRcdFx0aWYgKCBsZW4gPiAxICkge1xuXHRcdFx0XHR2YXIgaXRlbSA9IHZhbFswXTtcblx0XHRcdFx0aWYgKCAkLnR5cGUoIGl0ZW0gKSA9PT0gJ3N0cmluZycgfHwgJC50eXBlKCBpdGVtICkgPT09ICdudW1iZXInICkge1xuXHRcdFx0XHRcdGlmICggIWRvX25vdF9nZXRfcmVhbF9kYXRhICkge1xuXHRcdFx0XHRcdFx0Z2V0X3JlYWxfZGF0YV93aGVuX29wZW4gPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIGdldF9yZWFsX2RhdGFfb25fbXVsdGkgJiYgc2V0UmVhbFZhbHVlQ2FsbEJhY2sgKSB7XG5cdFx0XHRcdFx0XHQvL1JlcXVpcmVkIHRvIGdldCB2YWx1ZXMgZm9yIE11bHRpLXNlbGVjdCBmaWVsZCBjYWxsYmFja3MuIEN1cnJlbnRseSwgdXNlZCB0byByZXRyaWV2ZSBwdW5jaCB0YWcgbWFudWFsIGlkcy5cblx0XHRcdFx0XHRcdC8vSWYgdGhpcyBpcyBub3QgZG9uZSwgbWFudWFsIGlkcyB3aWxsIG9ubHkgYmUgcmV0cmlldmVkIGluIHRoZSBzY2VuYXJpbyB0aGVyZSBpcyBvbmx5IG9uZSBpdGVtIHNlbGVjdGVkIGluIHdoaWNoIGNhc2UgdGhpcy5nZXRSZWFsRGF0YSgpIGlzIGNhbGxlZC5cblx0XHRcdFx0XHRcdC8vSG93ZXZlciwgYWRkaW5nIHRoaXMuZ2V0UmVhbERhdGEoKSBoZXJlIGNhdXNlcyBvdGhlciBpc3N1ZXMuXG5cdFx0XHRcdFx0XHRzZXRSZWFsVmFsdWVDYWxsQmFjayggdmFsLCB0cnVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMuc2V0TGFiZWwoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRcdGl0ZW0gPSB2YWxbaV07XG5cdFx0XHRcdFx0aWYgKCAkLnR5cGUoIGl0ZW0gKSA9PT0gJ3N0cmluZycgfHxcblx0XHRcdFx0XHRcdCQudHlwZSggaXRlbSApID09PSAnbnVtYmVyJyApIHtcblx0XHRcdFx0XHRcdGlmICggIWRvX25vdF9nZXRfcmVhbF9kYXRhICkge1xuXHRcdFx0XHRcdFx0XHR0aGlzLmdldFJlYWxEYXRhKCBpdGVtICk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRpZiAoICFzb3VyY2VfZGF0YSApIHtcblx0XHRcdFx0XHRcdFx0XHRzZXRfc2VsZWN0X2l0ZW1zX3doZW5fc2V0X2RhdGFfcHJvdmlkZXIgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHQvL3NldCBzZWxlY3QgaXRlbXNcdHdoaWNoIG9ubHkgY29udGFpbnMgdmFsdWUgdG8gc2VsZWN0IGl0ZW1zIGhhdmUgbGFiZWwgYW5kIHZhbHVlXG5cdFx0XHRcdFx0XHRcdHRoaXMuc2V0U2VsZWN0SXRlbXMoIHRoaXMuZ2V0UmVhbFNlbGVjdEl0ZW1zRnJvbVNvdXJjZURhdGEoKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRmb3IgKCB2YXIga2V5IGluIGl0ZW0gKSB7XG5cdFx0XHRcdFx0XHRcdC8vc3BlaWNhbCBoYW5kbGUgZm9yIHNvcnQgZmllbGRcblx0XHRcdFx0XHRcdFx0aWYgKCBpdGVtW2tleV0gPT09ICdhc2MnIHx8IGl0ZW1ba2V5XSA9PT0gJ2Rlc2MnICkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggIXNvdXJjZV9kYXRhICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0c2V0X3NlbGVjdF9pdGVtc193aGVuX3NldF9kYXRhX3Byb3ZpZGVyID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHRoaXMuc2V0TGFiZWwoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLmdldFNlbGVjdEl0ZW1zID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gYV9kcm9wZG93bi5nZXRTZWxlY3RJdGVtcygpO1xuXHRcdH1cblxuXHRcdHRoaXMuZ2V0UmVhbFNlbGVjdEl0ZW1zRnJvbVNvdXJjZURhdGEgPSBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBsZW4gPSBzb3VyY2VfZGF0YS5sZW5ndGg7XG5cdFx0XHR2YXIgc2VsZWN0X2l0ZW1zX2xlbiA9IHNlbGVjdF9pdGVtcyA/IHNlbGVjdF9pdGVtcy5sZW5ndGggOiAwOyAvLyBGaXggZm9yIEpTIEV4Y2VwdGlvbiBpZiBzZWxlY3RfaXRlbXMgaXMgbnVsbC5cblx0XHRcdHZhciByZXMgPSBbXTtcblxuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgc2VsZWN0X2l0ZW1zX2xlbjsgaSsrICkge1xuXHRcdFx0XHR2YXIgc2VsZWN0X3ZhbHVlID0gc2VsZWN0X2l0ZW1zW2ldO1xuXHRcdFx0XHRmb3IgKCB2YXIgaiA9IDA7IGogPCBsZW47IGorKyApIHtcblx0XHRcdFx0XHR2YXIgc291cmNlX2l0ZW0gPSBzb3VyY2VfZGF0YVtqXTtcblxuXHRcdFx0XHRcdC8vQ291bGQgYmUgc3RyaW5nIG9yIG51bWJlciwgdXNlID09XG5cdFx0XHRcdFx0aWYgKCBzZWxlY3RfdmFsdWUgPT0gc291cmNlX2l0ZW1ba2V5XSApIHtcblx0XHRcdFx0XHRcdHJlcy5wdXNoKCBzb3VyY2VfaXRlbSApO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHJlcztcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRMYWJlbCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGxhYmVsX2FyciA9IEFycmF5KCk7XG5cblx0XHRcdGlmICggYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uICkge1xuXHRcdFx0XHRpZiAoICFzZWxlY3RfaXRlbXMgKSB7XG5cdFx0XHRcdFx0dGhpcy5zZXRFbXB0eUxhYmVsKCk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dmFyIGxlbiA9IHNlbGVjdF9pdGVtcy5sZW5ndGg7XG5cdFx0XHRcdGlmICggbGVuID09PSAxICkge1xuXG5cdFx0XHRcdFx0dmFyIGRpc3BsYXlfY29sdW1uX2xlbiA9IGRpc3BsYXlfY29sdW1ucy5sZW5ndGg7XG5cdFx0XHRcdFx0Zm9yICggeSA9IDA7IHkgPCBkaXNwbGF5X2NvbHVtbl9sZW47IHkrKyApIHtcblxuXHRcdFx0XHRcdFx0aWYgKCBkaXNwbGF5X2NvbHVtbnNbeV0uaGlkZGVuID09PSB0cnVlICkgeyAvL0hpZGRlbiBmaWVsZCBmb3IgakdncmlkLCB1c3VhbGx5IGlzIGlkXG5cdFx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRpZiAoIGxheW91dF9uYW1lID09PSAnZ2xvYmFsX3NvcnRfY29sdW1ucycgJiYgc2VsZWN0X2l0ZW1zWzBdW2Rpc3BsYXlfY29sdW1uc1t5XS5uYW1lXSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdFx0XHR2YXIgaXRlbSA9IHNlbGVjdF9pdGVtc1swXTtcblxuXHRcdFx0XHRcdFx0XHRmb3IgKCB2YXIga2V5IGluIGl0ZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0dmFyIGNfdmFsdWUgPSBrZXkgKyAnIHwgJyArIGl0ZW1ba2V5XTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdC8vV2hlbiBzb3J0IGZpZWxkIGhhcyBzb3VyY2UgZGF0YSwgdXNlIHByb3BlciBsYWJlbCBzaG93biBvbiB0aGUgZHJvcGRvd24uXG5cdFx0XHRcdFx0XHRcdGlmICggc291cmNlX2RhdGEgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgc291cmNlX2RhdGEubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR2YXIgY29sdW1uID0gc291cmNlX2RhdGFbaV07XG5cblx0XHRcdFx0XHRcdFx0XHRcdGlmICggY29sdW1uLnZhbHVlID09PSBrZXkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHZhciBjX3ZhbHVlID0gY29sdW1uLmxhYmVsICsgJyB8ICcgKyBpdGVtW2tleV07XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0aWYgKCBjX3ZhbHVlICE9PSAwICYmIGNfdmFsdWUgPT0gJycgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y192YWx1ZSA9ICctLSc7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0bGFiZWxfYXJyLnB1c2goIGNfdmFsdWUgKTtcblxuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHZhciBjX3ZhbHVlID0gc2VsZWN0X2l0ZW1zWzBdW2Rpc3BsYXlfY29sdW1uc1t5XS5uYW1lXTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKCBjX3ZhbHVlICE9PSAwICYmIGNfdmFsdWUgPT0gJycgKSB7XG5cdFx0XHRcdFx0XHRcdGNfdmFsdWUgPSAnLS0nO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRpZiAoIGNfdmFsdWUgPT09IDAgfHwgY192YWx1ZSApIHtcblx0XHRcdFx0XHRcdFx0bGFiZWxfYXJyLnB1c2goIGNfdmFsdWUgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIGxhYmVsX2Fyci5sZW5ndGggPiAwICkge1xuXHRcdFx0XHRcdFx0bGFiZWxfc3Bhbi50ZXh0KCBsYWJlbF9hcnIuam9pbiggJyB8ICcgKSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR0aGlzLnNldEVtcHR5TGFiZWwoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bGFiZWxfc3Bhbi50ZXh0KCBsZW4gKyAnICcgKyAkLmkxOG4uXyggJ2l0ZW1zIHNlbGVjdGVkJyApICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIEVycm9yOiBVbmNhdWdodCBUeXBlRXJyb3I6IENhbm5vdCByZWFkIHByb3BlcnR5ICdsZW5ndGgnIG9mIG51bGwgaW4gaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC93aWRnZXRzL2F3ZXNvbWVib3gvQUNvbWJvQm94LmpzP3Y9OS4wLjYtMjAxNTEyMzEtMTQwNzQ4IGxpbmUgOTAyXG5cdFx0XHRcdGlmICggIXNlbGVjdF9pdGVtIHx8ICFkaXNwbGF5X2NvbHVtbnMgKSB7XG5cdFx0XHRcdFx0dGhpcy5zZXRFbXB0eUxhYmVsKCk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZGlzcGxheV9jb2x1bW5fbGVuID0gZGlzcGxheV9jb2x1bW5zLmxlbmd0aDtcblx0XHRcdFx0Zm9yICggdmFyIHkgPSAwOyB5IDwgZGlzcGxheV9jb2x1bW5fbGVuOyB5KysgKSB7XG5cdFx0XHRcdFx0aWYgKCBkaXNwbGF5X2NvbHVtbnNbeV0uaGlkZGVuID09PSB0cnVlICkgeyAvL0hpZGRlbiBmaWVsZCBmb3IgakdncmlkLCB1c3VhbGx5IGlzIGlkXG5cdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRjX3ZhbHVlID0gc2VsZWN0X2l0ZW1bZGlzcGxheV9jb2x1bW5zW3ldLm5hbWVdO1xuXG5cdFx0XHRcdFx0aWYgKCBjX3ZhbHVlICE9PSAwICYmIGNfdmFsdWUgPT0gJycgKSB7XG5cdFx0XHRcdFx0XHRjX3ZhbHVlID0gJy0tJztcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIGNfdmFsdWUgPT09IDAgfHwgY192YWx1ZSApIHtcblx0XHRcdFx0XHRcdGxhYmVsX2Fyci5wdXNoKCBjX3ZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBsYWJlbF9hcnIubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHRsYWJlbF9zcGFuLnRleHQoIGxhYmVsX2Fyci5qb2luKCAnIHwgJyApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5zZXRFbXB0eUxhYmVsKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0JHRoaXMuZmluZCggJy5hLWNvbWJvYm94LWxhYmVsJyApLndpZHRoKCAnYXV0bycgKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRFbXB0eUxhYmVsID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIHNldF9hbnkgKSB7XG5cdFx0XHRcdGxhYmVsX3NwYW4udGV4dCggR2xvYmFsLmFueV9pdGVtICk7XG5cdFx0XHR9IGVsc2UgaWYgKCBzZXRfZW1wdHkgfHwgc2V0X3NwZWNpYWxfZW1wdHkgKSB7XG5cdFx0XHRcdGlmICggbGF5b3V0X25hbWUgPT09ICdnbG9iYWxfdHJlZV9jb2x1bW4nICkge1xuXHRcdFx0XHRcdGxhYmVsX3NwYW4udGV4dCggR2xvYmFsLnJvb3RfaXRlbSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGxhYmVsX3NwYW4udGV4dCggR2xvYmFsLmVtcHR5X2l0ZW0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIGlmICggc2V0X2RlZmF1bHQgKSB7XG5cdFx0XHRcdGxhYmVsX3NwYW4udGV4dCggR2xvYmFsLmRlZmF1bHRfaXRlbSApO1xuXHRcdFx0fSBlbHNlIGlmICggc2V0X29wZW4gKSB7XG5cdFx0XHRcdGxhYmVsX3NwYW4udGV4dCggR2xvYmFsLm9wZW5faXRlbSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCBzb3VyY2VfZGF0YSAmJiBzb3VyY2VfZGF0YS5sZW5ndGggPiAwICkge1xuXHRcdFx0XHRcdHZhciBmaXJzdF9pdGVtID0gc291cmNlX2RhdGFbMF07XG5cblx0XHRcdFx0XHRpZiAoIGZpcnN0X2l0ZW0uaGFzT3duUHJvcGVydHkoICdsYWJlbCcgKSApIHtcblx0XHRcdFx0XHRcdGxhYmVsX3NwYW4udGV4dCggZmlyc3RfaXRlbS5sYWJlbCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKCBjdXN0b21fZmlyc3RfbGFiZWwgKSB7XG5cdFx0XHRcdGxhYmVsX3NwYW4udGV4dCggY3VzdG9tX2ZpcnN0X2xhYmVsICk7XG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5vbkNvbHVtblNldHRpbmdTYXZlRnJvbUxheW91dCA9IGZ1bmN0aW9uKCBsYXlvdXQgKSB7XG5cdFx0XHR2YXIgZmlsdGVyID0ge307XG5cdFx0XHRmaWx0ZXIuc2NyaXB0ID0gJ2dsb2JhbF9hd2Vzb21lYm94X2NvbHVtbnMnO1xuXHRcdFx0ZmlsdGVyLm5hbWUgPSBsYXlvdXRfbmFtZTtcblx0XHRcdGZpbHRlci5pc19kZWZhdWx0ID0gJ2ZhbHNlJztcblxuXHRcdFx0ZmlsdGVyLmRhdGEgPSBsYXlvdXQuZGF0YTtcblx0XHRcdGZpbHRlci5kYXRhLnR5cGUgPSAxMDtcblx0XHRcdGZpbHRlci5kYXRhLmxheW91dF9pZCA9IGxheW91dC5pZDtcblxuXHRcdFx0aWYgKCBBTGF5b3V0Q2FjaGUubGF5b3V0X2RpY1tsYXlvdXRfbmFtZV0gKSB7XG5cdFx0XHRcdGZpbHRlci5pZCA9IEFMYXlvdXRDYWNoZS5sYXlvdXRfZGljW2xheW91dF9uYW1lXS5pZDtcblx0XHRcdH1cblxuXHRcdFx0dXNlcl9nZW5lcmljX2FwaS5zZXRVc2VyR2VuZXJpY0RhdGEoIGZpbHRlciwge1xuXHRcdFx0XHRvblJlc3VsdDogZnVuY3Rpb24oIHJlcyApIHtcblx0XHRcdFx0XHRBTGF5b3V0Q2FjaGUubGF5b3V0X2RpY1tsYXlvdXRfbmFtZV0gPSBudWxsO1xuXHRcdFx0XHRcdCR0aGlzLmluaXRDb2x1bW5zKCk7XG5cdFx0XHRcdFx0c291cmNlX2RhdGEgPSBudWxsOyAvL1JlbG9hZCBzb3VyY2UgZGF0YSBpZiBjb2x1bW4gY2hhbmdlZFxuXG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5vbkNvbHVtblNldHRpbmdTYXZlID0gZnVuY3Rpb24oIHNlbGV0ZWRDb2x1bW5zLCByb3dzUGVyUGFnZU51bWJlciwgbGF5b3V0X2lkLCBmaWx0ZXJfZGF0YSApIHtcblxuXHRcdFx0dmFyIGZpbHRlciA9IHt9O1xuXHRcdFx0ZmlsdGVyLnNjcmlwdCA9ICdnbG9iYWxfYXdlc29tZWJveF9jb2x1bW5zJztcblx0XHRcdGZpbHRlci5uYW1lID0gbGF5b3V0X25hbWU7XG5cdFx0XHRmaWx0ZXIuaXNfZGVmYXVsdCA9ICdmYWxzZSc7XG5cdFx0XHRmaWx0ZXIudHlwZSA9IDE7IC8vQUxheW91dFR5cGUuY3VzdG9taXplXG5cblx0XHRcdGlmICggQUxheW91dENhY2hlLmxheW91dF9kaWNbbGF5b3V0X25hbWVdICkge1xuXHRcdFx0XHRmaWx0ZXIuaWQgPSBBTGF5b3V0Q2FjaGUubGF5b3V0X2RpY1tsYXlvdXRfbmFtZV0uaWQ7XG5cdFx0XHR9XG5cblx0XHRcdHZhciBzZWxlY3RfY29sdW1uc19pbl9KU09OID0gW107XG5cdFx0XHR2YXIgbGVuID0gc2VsZXRlZENvbHVtbnMubGVuZ3RoO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0dmFyIGNvbHVtbl9pbl9KU09OID0ge1xuXHRcdFx0XHRcdGxhYmVsOiBzZWxldGVkQ29sdW1uc1tpXS5sYWJlbCxcblx0XHRcdFx0XHR2YWx1ZTogc2VsZXRlZENvbHVtbnNbaV0udmFsdWUsXG5cdFx0XHRcdFx0b3JkZXJWYWx1ZTogc2VsZXRlZENvbHVtbnNbaV0ub3JkZXJWYWx1ZVxuXHRcdFx0XHR9O1xuXHRcdFx0XHRzZWxlY3RfY29sdW1uc19pbl9KU09OLnB1c2goIGNvbHVtbl9pbl9KU09OICk7XG5cdFx0XHR9XG5cblx0XHRcdGZpbHRlci5kYXRhID0ge1xuXHRcdFx0XHRkaXNwbGF5X2NvbHVtbnM6IHNlbGVjdF9jb2x1bW5zX2luX0pTT04sXG5cdFx0XHRcdHJvd19wZXJfcGFnZTogcm93c1BlclBhZ2VOdW1iZXIsXG5cdFx0XHRcdGxheW91dF9pZDogbGF5b3V0X2lkLFxuXHRcdFx0XHRmaWx0ZXJfZGF0YTogZmlsdGVyX2RhdGFcblx0XHRcdH07XG5cblx0XHRcdC8vRXJyb3I6IFR5cGVFcnJvcjogdXNlcl9nZW5lcmljX2FwaSBpcyBudWxsIGluIC9pbnRlcmZhY2UvaHRtbDUvZ2xvYmFsL3dpZGdldHMvYXdlc29tZWJveC9BQ29tYm9Cb3guanM/dj05LjAuMC0yMDE1MDgyMi0wOTAyMDUgbGluZSA5ODdcblx0XHRcdGlmICggIXVzZXJfZ2VuZXJpY19hcGkgKSB7XG5cdFx0XHRcdHVzZXJfZ2VuZXJpY19hcGkgPSBUVEFQSS5BUElVc2VyR2VuZXJpY0RhdGE7XG5cdFx0XHR9XG5cdFx0XHR1c2VyX2dlbmVyaWNfYXBpLnNldFVzZXJHZW5lcmljRGF0YSggZmlsdGVyLCB7XG5cdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzICkge1xuXHRcdFx0XHRcdEFMYXlvdXRDYWNoZS5sYXlvdXRfZGljW2xheW91dF9uYW1lXSA9IG51bGw7XG5cblx0XHRcdFx0XHQkdGhpcy5pbml0Q29sdW1ucygpO1xuXG5cdFx0XHRcdFx0c291cmNlX2RhdGEgPSBudWxsOyAvL1JlbG9hZCBzb3VyY2UgZGF0YSBpZiBjb2x1bW4gY2hhbmdlZFxuXG5cdFx0XHRcdFx0Ly9SZWxvYWQgcmVhbCBkYXRhIGlmIGNvbHVtbnMgaGF2ZSBjaGFuZ2VkLCBzbyB0aGV5IGRpc3BsYXkgZGF0YSBmb3IgYW55IG5ldyBjb2x1bW5zXG5cdFx0XHRcdFx0Ly8gV2UgY2FuJ3QganVzdCBwYXNzIGluIHRoZSBzZWxlY3RlZF9pdGVtcyB2ZXJiYXRpbSBoZXJlLCB3ZSBuZWVkIHRvIHBhcnNlIG9mZiB0aGUgJ2lkJyBmaWVsZHMgYW5kIHBhc3MgdGhhdCBpbiBhcyBhbiBhcnJheSBpbnN0ZWFkLlxuXHRcdFx0XHRcdGlmICggJC50eXBlKCBzZWxlY3RfaXRlbXMgKSA9PT0gJ2FycmF5JyApIHtcblx0XHRcdFx0XHRcdHNlbGVjdF9pdGVtcyA9IHNlbGVjdF9pdGVtcy5tYXAoIGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggb2JqLmhhc093blByb3BlcnR5KCAnaWQnICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG9ialsnaWQnXTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vRG9uJ3QgdHJ5IHRvIGxvYWQgZGF0YSBmcm9tIHRoZSBBUEkgaWYgdGhlcmUgaXMgbm8gZmlsdGVyIGNyaXRlcmlhLCBhcyBldmVyeXRoaW5nIGlzIGxpa2VseSBiZSByZXR1cm5lZCBhbmQgdGhlcmVmb3JlIHdpbGwgYmUgc2VsZWN0ZWQuXG5cdFx0XHRcdFx0Ly8gVGhpcyB3b3VsZCBtYW5pZmVzdCBpdHNlbGYgYnkgZXhwYW5kaW5nIGEgZHJvcGRvd24gd2l0aG91dCBhbnl0aGluZyBzZWxlY3RlZCBpbiBpdCwgdGhlbiBjaGFuZ2luZyB0aGUgY29sdW1ucy5cblx0XHRcdFx0XHRpZiAoIHNlbGVjdF9pdGVtcyApIHtcblx0XHRcdFx0XHRcdCR0aGlzLmdldFJlYWxEYXRhKCBzZWxlY3RfaXRlbXMgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblxuXHRcdH07XG5cblx0XHQvL1NldCBjb2x1bW5zLCBkaXNwbGF5IGNvbHVtbnMgd2lsbCBiZSB1c2VkIHdoZW4gb3BlbiBBd2Vzb21lQm94LiBJZiBubyBsYXlvdXQgc2F2ZWQuIERpc3BsYXkgY29sdW1ucyBhcmUgdGhlIGRlZmF1bHQgb25lcyBzZXQgaW4gdGhpcy5lYWNoXG5cdFx0dGhpcy5pbml0Q29sdW1ucyA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHR1c2VyX2dlbmVyaWNfYXBpID0gVFRBUEkuQVBJVXNlckdlbmVyaWNEYXRhO1xuXG5cdFx0XHQvL0Vycm9yOiBUeXBlRXJyb3I6ICd1bmRlZmluZWQnIGlzIG5vdCBhIGZ1bmN0aW9uIChldmFsdWF0aW5nICd1c2VyX2dlbmVyaWNfYXBpLmdldFVzZXJHZW5lcmljRGF0YScpIGluIC9pbnRlcmZhY2UvaHRtbDUvZ2xvYmFsL3dpZGdldHMvYXdlc29tZWJveC9BQ29tYm9Cb3guanM/dj04LjAuMC0yMDE0MTExNy0wOTU3MTEgbGluZSAxMDQ0XG5cdFx0XHRpZiAoICF1c2VyX2dlbmVyaWNfYXBpIHx8ICF1c2VyX2dlbmVyaWNfYXBpLmdldFVzZXJHZW5lcmljRGF0YSB8fCB0eXBlb2YgKCB1c2VyX2dlbmVyaWNfYXBpLmdldFVzZXJHZW5lcmljRGF0YSApICE9PSAnZnVuY3Rpb24nICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICggR2xvYmFsLmlzU2V0KCBBTGF5b3V0Q2FjaGUubGF5b3V0X2RpY1tsYXlvdXRfbmFtZV0gKSApIHtcblx0XHRcdFx0aWYgKCBBTGF5b3V0Q2FjaGUubGF5b3V0X2RpY1tsYXlvdXRfbmFtZV0ucGVuZGluZyApIHtcblx0XHRcdFx0XHRUVFByb21pc2UuYWRkKCAnQUNvbWJvQm94JywgbGF5b3V0X25hbWUgKTtcblx0XHRcdFx0XHRUVFByb21pc2Uud2FpdCggJ0FDb21ib0JveCcsIGxheW91dF9uYW1lLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdGluaXRDb2x1bW5zRnJvbUNhY2hlKCBsYXlvdXRfbmFtZSApO1xuXHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpbml0Q29sdW1uc0Zyb21DYWNoZSggbGF5b3V0X25hbWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly9TZXQgY2FjaGUgdG8gcGVuZGluZyB0byBzdG9wIG11bHRpcGxlIGNhbGxzIHRvIHRoZSBBUEkgZm9yIHRoZSBzYW1lIGxheW91dF9uYW1lLlxuXHRcdFx0XHRBTGF5b3V0Q2FjaGUubGF5b3V0X2RpY1tsYXlvdXRfbmFtZV0gPSB7IHBlbmRpbmc6IHRydWUgfTtcblx0XHRcdFx0dmFyIGZpbHRlciA9IHt9O1xuXHRcdFx0XHRmaWx0ZXIuZmlsdGVyX2RhdGEgPSB7IHNjcmlwdDogJ2dsb2JhbF9hd2Vzb21lYm94X2NvbHVtbnMnLCBuYW1lOiBsYXlvdXRfbmFtZSB9O1xuXHRcdFx0XHR1c2VyX2dlbmVyaWNfYXBpLmdldFVzZXJHZW5lcmljRGF0YSggZmlsdGVyLCB7XG5cdFx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXMgKSB7XG5cblx0XHRcdFx0XHRcdHZhciByZXNEYXRhID0gcmVzLmdldFJlc3VsdCgpO1xuXHRcdFx0XHRcdFx0Ly9TZXQgdGhpcyBoZXJlIHNvIENvbHVtbiBzZXR0aW5nIGRpYWxvZyBjYW4gZ2V0IGNvcnJlY3QgZGlzcGxheSBjb2x1bW5zIGJlZm9yZSBvcGVuIEF3ZXNvbWVib3hcblx0XHRcdFx0XHRcdGlmICggcmVzRGF0YSAmJiByZXNEYXRhLmxlbmd0aCA+IDAgKSB7XG5cblx0XHRcdFx0XHRcdFx0dmFyIGRhdGEgPSByZXNEYXRhWzBdLmRhdGE7XG5cblx0XHRcdFx0XHRcdFx0Ly9pZiBzYXZlZCBsYXlvdXQgaXMgc2F2ZWQgdmlldyBsYXlvdXQuIGdldCBpdFxuXHRcdFx0XHRcdFx0XHRpZiAoIGRhdGEudHlwZSA9PT0gMTAgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHR2YXIgY29sdW1uc19yZXN1bHRfZGF0YSA9IGFwaS5nZXRPcHRpb25zKCBjb2x1bW5fb3B0aW9uX2tleSwgeyBhc3luYzogZmFsc2UgfSApLmdldFJlc3VsdCgpO1xuXHRcdFx0XHRcdFx0XHRcdGFsbF9jb2x1bW5zID0gR2xvYmFsLmJ1aWxkQ29sdW1uQXJyYXkoIGNvbHVtbnNfcmVzdWx0X2RhdGEgKTtcblxuXHRcdFx0XHRcdFx0XHRcdHZhciBzYXZlZF9sYXlvdXRfcmVzdWx0ID0gdXNlcl9nZW5lcmljX2FwaS5nZXRVc2VyR2VuZXJpY0RhdGEoIHtcblx0XHRcdFx0XHRcdFx0XHRcdGZpbHRlcl9kYXRhOiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlkOiBkYXRhLmxheW91dF9pZCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZGVsZXRlZDogZmFsc2Vcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9LCB7IGFzeW5jOiBmYWxzZSB9ICkuZ2V0UmVzdWx0KCk7XG5cblx0XHRcdFx0XHRcdFx0XHRpZiAoIHNhdmVkX2xheW91dF9yZXN1bHQgJiYgc2F2ZWRfbGF5b3V0X3Jlc3VsdC5sZW5ndGggPiAwICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dmFyIHNhdmVkX2xheW91dCA9IHNhdmVkX2xheW91dF9yZXN1bHQuc2xpY2UoKVswXTtcblx0XHRcdFx0XHRcdFx0XHRcdHZhciBuZXdfZGF0YSA9IHNhdmVkX2xheW91dC5kYXRhO1xuXHRcdFx0XHRcdFx0XHRcdFx0bmV3X2RhdGEuZGlzcGxheV9jb2x1bW5zID0gJHRoaXMuYnVpbGREaXNwbGF5Q29sdW1ucyggbmV3X2RhdGEuZGlzcGxheV9jb2x1bW5zICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRuZXdfZGF0YS5maWx0ZXJfZGF0YSA9IEdsb2JhbC5jb252ZXJ0TGF5b3V0RmlsdGVyVG9BUElGaWx0ZXIoIHNhdmVkX2xheW91dCApO1xuXHRcdFx0XHRcdFx0XHRcdFx0cmVzRGF0YVswXS5kYXRhLmRpc3BsYXlfY29sdW1ucyA9IG5ld19kYXRhLmRpc3BsYXlfY29sdW1ucztcblx0XHRcdFx0XHRcdFx0XHRcdHJlc0RhdGFbMF0uZGF0YS5maWx0ZXJfZGF0YSA9IG5ld19kYXRhLmZpbHRlcl9kYXRhO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRkYXRhID0gcmVzRGF0YVswXS5kYXRhO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRkYXRhLmZpbHRlcl9kYXRhID0gW107IC8vIGlmIHNhdmVkIGxheW91IGlzIGRlbGV0ZWQuXG5cdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRBTGF5b3V0Q2FjaGUubGF5b3V0X2RpY1tsYXlvdXRfbmFtZV0gPSByZXNEYXRhWzBdO1xuXG5cdFx0XHRcdFx0XHRcdEFMYXlvdXRDYWNoZS5sYXlvdXRfZGljWyR0aGlzLmdldFNjcmlwdE5hbWUoKV0gPSBsYXlvdXRfbmFtZTsgLy8gYmluZCBjdXJyZW50IHZpZXcgbmFtZSB0byBsYXlvdXQgbmFtZTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIEdsb2JhbC5pc1NldCggZGF0YS50eXBlICkgJiYgZGF0YS50eXBlID09PSAxMCApIHtcblxuXHRcdFx0XHRcdFx0XHRcdGRpc3BsYXlfY29sdW1ucyA9IGRhdGEuZGlzcGxheV9jb2x1bW5zO1xuXHRcdFx0XHRcdFx0XHRcdGlmICggZGlzcGxheV9jb2x1bW5zLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIHBvc3NpYmxlX2Rpc3BsYXlfY29sdW1ucyApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gZmlsdGVyQmFzZU9uUG9zc2libGVDb2x1bW5zKCBkaXNwbGF5X2NvbHVtbnMgKTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gR2xvYmFsLmNvbnZlcnRDb2x1bW5zVG9qR3JpZEZvcm1hdCggZGlzcGxheV9jb2x1bW5zLCBsYXlvdXRfbmFtZSwgZnVuY3Rpb24oIHdpZHRoICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0b3RhbF9oZWFkZXJfd2lkdGggPSB3aWR0aDtcblx0XHRcdFx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBsaXN0X3ZpZXdfZGVmYXVsdF9jb2x1bW5zICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gbGlzdF92aWV3X2RlZmF1bHRfY29sdW1ucztcblx0XHRcdFx0XHRcdFx0XHRcdGRpc3BsYXlfY29sdW1ucyA9IGZpbHRlckJhc2VPblBvc3NpYmxlQ29sdW1ucyggZGlzcGxheV9jb2x1bW5zICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBHbG9iYWwuY29udmVydENvbHVtbnNUb2pHcmlkRm9ybWF0KCBkaXNwbGF5X2NvbHVtbnMsIGxheW91dF9uYW1lLCBmdW5jdGlvbiggd2lkdGggKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRvdGFsX2hlYWRlcl93aWR0aCA9IHdpZHRoO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdGFyZ3NfZnJvbV9zYXZlZF9sYXlvdXQgPSB7fTtcblx0XHRcdFx0XHRcdFx0XHRhcmdzX2Zyb21fc2F2ZWRfbGF5b3V0LmZpbHRlcl9kYXRhID0gZGF0YS5maWx0ZXJfZGF0YTtcblx0XHRcdFx0XHRcdFx0XHRhcmdzX2Zyb21fc2F2ZWRfbGF5b3V0LmZpbHRlcl9zb3J0ID0gZGF0YS5maWx0ZXJfc29ydDtcblxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gZGF0YS5kaXNwbGF5X2NvbHVtbnM7XG5cblx0XHRcdFx0XHRcdFx0XHQvL0hhcHBlbiB3aGVuIHNhdmUgbm8gY29sdW1ucyBpbiBjb2x1bW4gc2V0dGluZyBmb3IgbmF2aWdhdGlvbiBtb2RlXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBkaXNwbGF5X2NvbHVtbnMubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggcG9zc2libGVfZGlzcGxheV9jb2x1bW5zICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBmaWx0ZXJCYXNlT25Qb3NzaWJsZUNvbHVtbnMoIGRpc3BsYXlfY29sdW1ucyApO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBHbG9iYWwuY29udmVydENvbHVtbnNUb2pHcmlkRm9ybWF0KCBkaXNwbGF5X2NvbHVtbnMsIGxheW91dF9uYW1lLCBmdW5jdGlvbiggd2lkdGggKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRvdGFsX2hlYWRlcl93aWR0aCA9IHdpZHRoO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGxpc3Rfdmlld19kZWZhdWx0X2NvbHVtbnMgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBsaXN0X3ZpZXdfZGVmYXVsdF9jb2x1bW5zO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gZmlsdGVyQmFzZU9uUG9zc2libGVDb2x1bW5zKCBkaXNwbGF5X2NvbHVtbnMgKTtcblx0XHRcdFx0XHRcdFx0XHRcdGRpc3BsYXlfY29sdW1ucyA9IEdsb2JhbC5jb252ZXJ0Q29sdW1uc1RvakdyaWRGb3JtYXQoIGRpc3BsYXlfY29sdW1ucywgbGF5b3V0X25hbWUsIGZ1bmN0aW9uKCB3aWR0aCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dG90YWxfaGVhZGVyX3dpZHRoID0gd2lkdGg7XG5cdFx0XHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0cm93X3Blcl9wYWdlID0gZGF0YS5yb3dfcGVyX3BhZ2U7XG5cdFx0XHRcdFx0XHRcdFx0YXJnc19mcm9tX3NhdmVkX2xheW91dCA9IG51bGw7XG4vL1x0XHRcdFx0XHRcdFx0aWYgKCAhbmF2aWdhdGlvbl9tb2RlICYmICFzZXRfZGVmYXVsdF9hcmdzX21hbnVhbGx5ICkge1xuLy9cdFx0XHRcdFx0XHRcdFx0ZGVmYXVsdF9hcmdzID0gbnVsbDtcbi8vXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0Ly9JZiBzZXQgcG9zc2libGUgY29sdW1ucywgdXNlIGl0XG5cdFx0XHRcdFx0XHRcdGlmICggbGlzdF92aWV3X2RlZmF1bHRfY29sdW1ucyApIHtcblx0XHRcdFx0XHRcdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBsaXN0X3ZpZXdfZGVmYXVsdF9jb2x1bW5zO1xuXHRcdFx0XHRcdFx0XHRcdGRpc3BsYXlfY29sdW1ucyA9IGZpbHRlckJhc2VPblBvc3NpYmxlQ29sdW1ucyggZGlzcGxheV9jb2x1bW5zICk7XG5cdFx0XHRcdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gR2xvYmFsLmNvbnZlcnRDb2x1bW5zVG9qR3JpZEZvcm1hdCggZGlzcGxheV9jb2x1bW5zLCBsYXlvdXRfbmFtZSwgZnVuY3Rpb24oIHdpZHRoICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dG90YWxfaGVhZGVyX3dpZHRoID0gd2lkdGg7XG5cdFx0XHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdEFMYXlvdXRDYWNoZS5sYXlvdXRfZGljW2xheW91dF9uYW1lXSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRyb3dfcGVyX3BhZ2UgPSAwO1xuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGlmICggaW5pdF9kYXRhX2ltbWVkaWF0ZWx5ICkge1xuXHRcdFx0XHRcdFx0XHQkdGhpcy5pbml0U291cmNlRGF0YSgpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0VFRQcm9taXNlLnJlc29sdmUoICdBQ29tYm9Cb3gnLCBsYXlvdXRfbmFtZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSApO1xuXG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dmFyIGluaXRDb2x1bW5zRnJvbUNhY2hlID0gZnVuY3Rpb24oIGxheW91dF9uYW1lICkge1xuXHRcdFx0Ly9TZXQgdGhpcyBoZXJlIHNvIENvbHVtbiBzZXR0aW5nIGRpYWxvZyBjYW4gZ2V0IGNvcnJlY3QgZGlzcGxheSBjb2x1bW5zIGJlZm9yZSBvcGVuIEF3ZXNvbWVib3hcblx0XHRcdGlmICggR2xvYmFsLmlzU2V0KCBBTGF5b3V0Q2FjaGUubGF5b3V0X2RpY1tsYXlvdXRfbmFtZV0uZGF0YSApICkge1xuXG5cdFx0XHRcdHZhciBkYXRhID0gQUxheW91dENhY2hlLmxheW91dF9kaWNbbGF5b3V0X25hbWVdLmRhdGE7XG5cblx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGRhdGEudHlwZSApICYmIGRhdGEudHlwZSA9PT0gMTAgKSB7XG5cdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gZGF0YS5kaXNwbGF5X2NvbHVtbnM7XG5cblx0XHRcdFx0XHRpZiAoIGRpc3BsYXlfY29sdW1ucy5sZW5ndGggPiAwICkge1xuXHRcdFx0XHRcdFx0aWYgKCBwb3NzaWJsZV9kaXNwbGF5X2NvbHVtbnMgKSB7XG5cdFx0XHRcdFx0XHRcdGRpc3BsYXlfY29sdW1ucyA9IGZpbHRlckJhc2VPblBvc3NpYmxlQ29sdW1ucyggZGlzcGxheV9jb2x1bW5zICk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGRpc3BsYXlfY29sdW1ucyA9IEdsb2JhbC5jb252ZXJ0Q29sdW1uc1RvakdyaWRGb3JtYXQoIGRpc3BsYXlfY29sdW1ucywgbGF5b3V0X25hbWUsIGZ1bmN0aW9uKCB3aWR0aCApIHtcblx0XHRcdFx0XHRcdFx0dG90YWxfaGVhZGVyX3dpZHRoID0gd2lkdGg7XG5cdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmICggbGlzdF92aWV3X2RlZmF1bHRfY29sdW1ucyApIHtcblx0XHRcdFx0XHRcdGRpc3BsYXlfY29sdW1ucyA9IGxpc3Rfdmlld19kZWZhdWx0X2NvbHVtbnM7XG5cdFx0XHRcdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBmaWx0ZXJCYXNlT25Qb3NzaWJsZUNvbHVtbnMoIGRpc3BsYXlfY29sdW1ucyApO1xuXHRcdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gR2xvYmFsLmNvbnZlcnRDb2x1bW5zVG9qR3JpZEZvcm1hdCggZGlzcGxheV9jb2x1bW5zLCBsYXlvdXRfbmFtZSwgZnVuY3Rpb24oIHdpZHRoICkge1xuXHRcdFx0XHRcdFx0XHR0b3RhbF9oZWFkZXJfd2lkdGggPSB3aWR0aDtcblx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRhcmdzX2Zyb21fc2F2ZWRfbGF5b3V0ID0ge307XG5cdFx0XHRcdFx0YXJnc19mcm9tX3NhdmVkX2xheW91dC5maWx0ZXJfZGF0YSA9IGRhdGEuZmlsdGVyX2RhdGE7XG5cdFx0XHRcdFx0YXJnc19mcm9tX3NhdmVkX2xheW91dC5maWx0ZXJfc29ydCA9IGRhdGEuZmlsdGVyX3NvcnQ7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBkYXRhLmRpc3BsYXlfY29sdW1ucztcblxuXHRcdFx0XHRcdGlmICggZGlzcGxheV9jb2x1bW5zLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIHBvc3NpYmxlX2Rpc3BsYXlfY29sdW1ucyApIHtcblx0XHRcdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gZmlsdGVyQmFzZU9uUG9zc2libGVDb2x1bW5zKCBkaXNwbGF5X2NvbHVtbnMgKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gR2xvYmFsLmNvbnZlcnRDb2x1bW5zVG9qR3JpZEZvcm1hdCggZGlzcGxheV9jb2x1bW5zLCBsYXlvdXRfbmFtZSwgZnVuY3Rpb24oIHdpZHRoICkge1xuXHRcdFx0XHRcdFx0XHR0b3RhbF9oZWFkZXJfd2lkdGggPSB3aWR0aDtcblx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBwb3NzaWJsZV9kaXNwbGF5X2NvbHVtbnMgKSB7XG5cdFx0XHRcdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBwb3NzaWJsZV9kaXNwbGF5X2NvbHVtbnM7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJvd19wZXJfcGFnZSA9IGRhdGEucm93X3Blcl9wYWdlO1xuXHRcdFx0XHRcdGlmICggIW5hdmlnYXRpb25fbW9kZSAmJiAhc2V0X2RlZmF1bHRfYXJnc19tYW51YWxseSApIHtcblx0XHRcdFx0XHRcdGRlZmF1bHRfYXJncyA9IG51bGw7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGlmICggbGlzdF92aWV3X2RlZmF1bHRfY29sdW1ucyApIHtcblx0XHRcdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBsaXN0X3ZpZXdfZGVmYXVsdF9jb2x1bW5zO1xuXHRcdFx0XHRcdGRpc3BsYXlfY29sdW1ucyA9IGZpbHRlckJhc2VPblBvc3NpYmxlQ29sdW1ucyggZGlzcGxheV9jb2x1bW5zICk7XG5cdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gR2xvYmFsLmNvbnZlcnRDb2x1bW5zVG9qR3JpZEZvcm1hdCggZGlzcGxheV9jb2x1bW5zLCBsYXlvdXRfbmFtZSwgZnVuY3Rpb24oIHdpZHRoICkge1xuXHRcdFx0XHRcdFx0dG90YWxfaGVhZGVyX3dpZHRoID0gd2lkdGg7XG5cdFx0XHRcdFx0fSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJvd19wZXJfcGFnZSA9IDA7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGluaXRfZGF0YV9pbW1lZGlhdGVseSApIHtcblx0XHRcdFx0JHRoaXMuaW5pdFNvdXJjZURhdGEoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgZmlsdGVyQmFzZU9uUG9zc2libGVDb2x1bW5zID0gZnVuY3Rpb24oIGRpc3BsYXlfY29sdW1ucyApIHtcblxuXHRcdFx0Ly9FcnJvcjogVW5hYmxlIHRvIGdldCBwcm9wZXJ0eSAnbGVuZ3RoJyBvZiB1bmRlZmluZWQgb3IgbnVsbCByZWZlcmVuY2UgaW4gL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvd2lkZ2V0cy9hd2Vzb21lYm94L0FDb21ib0JveC5qcz92PTguMC4wLTIwMTQxMjMwLTEyNTQwNiBsaW5lIDExNjlcblx0XHRcdGlmICggIXBvc3NpYmxlX2Rpc3BsYXlfY29sdW1ucyApIHtcblx0XHRcdFx0cmV0dXJuIGRpc3BsYXlfY29sdW1ucztcblx0XHRcdH1cblxuXHRcdFx0dmFyIGxlbiA9IHBvc3NpYmxlX2Rpc3BsYXlfY29sdW1ucy5sZW5ndGg7XG5cblx0XHRcdHZhciByZXN1bHQgPSBbXTtcblx0XHRcdGZvciAoIHZhciBqID0gMDsgaiA8IGRpc3BsYXlfY29sdW1ucy5sZW5ndGg7IGorKyApIHtcblx0XHRcdFx0dmFyIGRpc19jb2x1bW4gPSBkaXNwbGF5X2NvbHVtbnNbal07XG5cdFx0XHRcdHZhciBmb3VuZCA9IGZhbHNlO1xuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHR2YXIgY29sdW1uID0gcG9zc2libGVfZGlzcGxheV9jb2x1bW5zW2ldO1xuXHRcdFx0XHRcdGlmICggY29sdW1uLnZhbHVlID09PSBkaXNfY29sdW1uLnZhbHVlICkge1xuXHRcdFx0XHRcdFx0Zm91bmQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIGZvdW5kICkge1xuXHRcdFx0XHRcdHJlc3VsdC5wdXNoKCBkaXNfY29sdW1uICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHJlc3VsdC5sZW5ndGggPT09IDAgKSB7XG5cdFx0XHRcdHJlc3VsdCA9IHBvc3NpYmxlX2Rpc3BsYXlfY29sdW1ucztcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblxuXHRcdH07XG5cblx0XHR0aGlzLmdldElkID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gaWQ7XG5cdFx0fTtcblxuXHRcdC8vdXBkYXRlIHNvdXJjZSBkYXRhIHRvIG5ldyBzYXZlZCBpdGVtLCBoYXBwZW5zIGluIHRpbWVzaGVldCB2aWV3LCBlZGl0IGVtcGxveWVlXG5cdFx0dGhpcy51cGRhdGVTZWxlY3RJdGVtID0gZnVuY3Rpb24oIG5ld19pdGVtICkge1xuXHRcdFx0c2VsZWN0X2l0ZW0gPSBuZXdfaXRlbTtcblx0XHRcdGlmICggc291cmNlX2RhdGEgKSB7XG5cblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgc291cmNlX2RhdGEubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0dmFyIGNvbnRlbnQgPSBzb3VyY2VfZGF0YVtpXTtcblx0XHRcdFx0XHRpZiAoIGNvbnRlbnQuaWQgPT09IG5ld19pdGVtLmlkICkge1xuXHRcdFx0XHRcdFx0c291cmNlX2RhdGFbaV0gPSBuZXdfaXRlbTtcblxuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRBRHJvcERvd24gPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBhX2Ryb3Bkb3duX2Rpdjtcblx0XHR9O1xuXG5cdFx0dGhpcy5vbkNsb3NlID0gZnVuY3Rpb24oIGUsIHRhcmdldCApIHtcblx0XHRcdGlmICggYV9kcm9wZG93biA9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdERlYnVnLlRleHQoICdFUlJPUjogVW5hYmxlIHRvIGNsb3NlIEFDb21ib0JveCBjaGVjayB0byBtYWtlIHN1cmUgaXQgd2FzblxcJ3QgaW5zdGFudGlhdGVkIHR3aWNlLicsICdBQ29tYm9ib3guanMnLCAnQUNvbWJvYm94JywgJ29uQ2xvc2UnLCAxMCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvL0luIHRoZSBjYXNlIHdoZXJlIGEgdXNlciBkb3VibGUgY2xpY2tzIGEgZHJvcC1kb3duIGJveCB0byBleHBhbmQgaXQsIHRoYXQgY2FuIGNhdXNlIGl0IHRvIG9wZW4gdGhlIGNsb3NlIGFnYWluIGltbWVkaWF0ZWx5LCBhbmQgc2hvdyBhIFwiLS0gTk9ORSAtLVwiIGV2ZW4gdGhvdWdoIHNvbWV0aGluZyB3YXMgcHJldmlvdXNseSBzZWxlY3RlZC5cblx0XHRcdC8vICBUaGVyZWZvcmUgaWYgdGhlICdpbml0JyBwcm9taXNlIGlzIHN0aWxsIHBlbmRpbmcgYmVjYXVzZSB0aGUgZGF0YSBpcyBzdGlsbCBsb2FkaW5nLCBzaW1wbHkgZG9uJ3QgY2xvc2UgaXQgeWV0LlxuXHRcdFx0dmFyIHBlbmRpbmdfcHJvbWlzZSA9IFRUUHJvbWlzZS5pc1BlbmRpbmdQcm9taXNlcyggJ0FDb21ib0JveCcsICdpbml0JyApO1xuXHRcdFx0aWYgKCBwZW5kaW5nX3Byb21pc2UgPT0gZmFsc2UgKSB7XG5cdFx0XHRcdGlmICggYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uICkge1xuXHRcdFx0XHRcdC8vUmUgbG9hZCBzb3VyY2VfZGF0YSBpZiBzZWxlY3QgaXRlbXNcblx0XHRcdFx0XHR2YXIgc2VsZWN0X2l0ZW1zID0gYV9kcm9wZG93bi5nZXRTZWxlY3RJdGVtcygpO1xuXHRcdFx0XHRcdCR0aGlzLnNldFZhbHVlKCBzZWxlY3RfaXRlbXMgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR2YXIgc2VsZWN0X2l0ZW0gPSBhX2Ryb3Bkb3duLmdldFNlbGVjdEl0ZW0oKTtcblx0XHRcdFx0XHRpZiAoIHNlbGVjdF9pdGVtICkgeyAvLyAjMjU5MyAtIG51bGwgaXMgbm90IGFuIG9iamVjdCAoZXZhbHVhdGluZyAnc2VsZWN0X2l0ZW0uX2lkXycpXG5cdFx0XHRcdFx0XHRpZiAoICF0cmVlX21vZGUgKSB7XG5cdFx0XHRcdFx0XHRcdCR0aGlzLnNldFZhbHVlKCBzZWxlY3RfaXRlbSApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIGlmICggc2VsZWN0X2l0ZW0uX2lkXyApIHtcblx0XHRcdFx0XHRcdFx0JHRoaXMuc2V0VmFsdWUoIHNlbGVjdF9pdGVtLl9pZF8gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdERlYnVnLlRleHQoICdXQVJOSU5HOiBBQ29tYm9Cb3g6OkluaXQgcHJvbWlzZSBzdGlsbCBwZW5kaW5nLCBjYW50IGNhbGwgc2V0VmFsdWUoKS4uLicsICdBQ29tYm9ib3guanMnLCAnQUNvbWJvYm94JywgJ29uQ2xvc2UnLCAxMCApO1xuXHRcdFx0fVxuXG5cdFx0XHRhX2Ryb3Bkb3duX2Rpdi5yZW1vdmUoKTtcblx0XHRcdGlzX21vdXNlX292ZXIgPSBmYWxzZTsgLy9XaGVuIGNsb3NlIGZyb20gZXNjLCB0aGlzIG1heWJlIHRydWVcblx0XHRcdExvY2FsQ2FjaGVEYXRhLm9wZW5Bd2Vzb21lQm94ID0gbnVsbDtcblx0XHRcdGlmICggYV9kcm9wZG93bi5pc0NoYW5nZWQoKSB8fCBsYXlvdXRfbmFtZSA9PT0gJ2dsb2JhbF9zb3J0X2NvbHVtbnMnICkge1xuXHRcdFx0XHRpZiAoIGNoZWNrX2JveCApIHtcblx0XHRcdFx0XHQkdGhpcy5zZXRDaGVja0JveCggdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdCR0aGlzLnRyaWdnZXIoICdmb3JtSXRlbUNoYW5nZScsIFskdGhpc10gKTtcblx0XHRcdH1cblx0XHRcdCR0aGlzLnRyaWdnZXIoICdvbkNsb3NlJywgWyR0aGlzXSApO1xuXHRcdFx0ZG9udE9wZW4gPSB0cnVlO1xuXHRcdFx0ZG9udE9wZW5UaW1lciA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkb250T3BlbiA9IGZhbHNlO1xuXHRcdFx0fSwgMjAwICk7XG5cdFx0XHQkdGhpcy5maW5kKCAnLmZvY3VzLWlucHV0JyApLmZvY3VzKCk7XG5cdFx0fTtcblxuXHRcdC8vc2V0IG5leHQgb3IgbGFzdCBpdGVtIHdoZW4ga2V5IGRvd24sIGNhbGwgZnJvbSBtYWluLmpzXG5cdFx0dGhpcy5zZWxlY3ROZXh0SXRlbSA9IGZ1bmN0aW9uKCBlICkge1xuXG5cdFx0XHR2YXIgc2VsZWN0X2luZGV4ID0gdGhpcy5nZXRTZWxlY3RJbmRleCgpO1xuXHRcdFx0dmFyIG5leHRfaW5kZXg7XG5cdFx0XHR2YXIgdGFyZ2V0X2dyaWQ7XG5cdFx0XHRpZiAoIGUua2V5Q29kZSA9PT0gNDAgKSB7IC8vRG93blxuXHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdGlmICggIWFsbG93X211bHRpcGxlX3NlbGVjdGlvbiApIHtcblx0XHRcdFx0XHRpZiAoIHNlbGVjdF9pbmRleCA9PT0gMCApIHtcblx0XHRcdFx0XHRcdG5leHRfaW5kZXggPSAxO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRuZXh0X2luZGV4ID0gc2VsZWN0X2luZGV4ICsgMTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dmFyIG5leHRfc2VsZWN0X2l0ZW0gPSB0aGlzLmdldEl0ZW1CeUluZGV4KCBuZXh0X2luZGV4ICk7XG5cblx0XHRcdFx0XHRpZiAoICFuZXh0X3NlbGVjdF9pdGVtICkge1xuXHRcdFx0XHRcdFx0bmV4dF9pbmRleCA9IG5leHRfaW5kZXggLSAxO1xuXHRcdFx0XHRcdFx0bmV4dF9zZWxlY3RfaXRlbSA9IHRoaXMuZ2V0SXRlbUJ5SW5kZXgoIG5leHRfaW5kZXggKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c2VsZWN0X2l0ZW0gPSBuZXh0X3NlbGVjdF9pdGVtO1xuXHRcdFx0XHRcdGFfZHJvcGRvd24uc2V0U2VsZWN0SXRlbSggbmV4dF9zZWxlY3RfaXRlbSApO1xuXHRcdFx0XHRcdGFfZHJvcGRvd24uc2V0SXNDaGFuZ2VkKCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoIGUua2V5Q29kZSA9PT0gMzggKSB7IC8vVXBcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRpZiAoICFhbGxvd19tdWx0aXBsZV9zZWxlY3Rpb24gKSB7XG5cdFx0XHRcdFx0aWYgKCBzZWxlY3RfaW5kZXggPT09IDAgKSB7XG5cdFx0XHRcdFx0XHRuZXh0X2luZGV4ID0gMDtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0bmV4dF9pbmRleCA9IHNlbGVjdF9pbmRleCAtIDE7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0bmV4dF9zZWxlY3RfaXRlbSA9IHRoaXMuZ2V0SXRlbUJ5SW5kZXgoIG5leHRfaW5kZXggKTtcblx0XHRcdFx0XHRzZWxlY3RfaXRlbSA9IG5leHRfc2VsZWN0X2l0ZW07XG5cdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRTZWxlY3RJdGVtKCBuZXh0X3NlbGVjdF9pdGVtICk7XG5cdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRJc0NoYW5nZWQoIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIGlmICggZS5rZXlDb2RlID09PSAzOSApIHsgLy9yaWdodFxuXHRcdFx0XHRpZiAoIGFsbG93X211bHRpcGxlX3NlbGVjdGlvbiAmJiAhJCggZS50YXJnZXQgKS5oYXNDbGFzcyggJ3NlYXJjaC1pbnB1dCcgKSApIHtcblx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0YV9kcm9wZG93bi5vblVuU2VsZWN0R3JpZERvdWJsZUNsaWNrKCk7XG5cdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRJc0NoYW5nZWQoIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIGlmICggZS5rZXlDb2RlID09PSAzNyApIHsgLy9sZWZ0XG5cdFx0XHRcdGlmICggYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uICYmICEkKCBlLnRhcmdldCApLmhhc0NsYXNzKCAnc2VhcmNoLWlucHV0JyApICkge1xuXHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRhX2Ryb3Bkb3duLm9uU2VsZWN0R3JpZERvdWJsZUNsaWNrKCk7XG5cdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRJc0NoYW5nZWQoIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCBxdWlja19zZWFyY2hfdGltZXIgKSB7XG5cdFx0XHRcdFx0Y2xlYXJUaW1lb3V0KCBxdWlja19zZWFyY2hfdGltZXIgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR2YXIgZm9jdXNfdGFyZ2V0ID0gJCggJzpmb2N1cycgKTtcblx0XHRcdFx0aWYgKCBmb2N1c190YXJnZXQubGVuZ3RoID4gMCAmJiAkKCBmb2N1c190YXJnZXRbMF0gKS5oYXNDbGFzcyggJ3NlYXJjaC1pbnB1dCcgKSApIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0cXVpY2tfc2VhcmNoX3RpbWVyID0gc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cXVpY2tfc2VhcmNoX3R5cGVkX2tleXMgPSAnJztcblx0XHRcdFx0fSwgNzUwICk7XG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblxuXHRcdFx0XHRxdWlja19zZWFyY2hfdHlwZWRfa2V5cyA9IHF1aWNrX3NlYXJjaF90eXBlZF9rZXlzICsgU3RyaW5nLmZyb21DaGFyQ29kZSggZS53aGljaCApLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdERlYnVnLlRleHQoICdRdWljayBzZWFyY2ggdHlwZWQga2V5czogJyArIHF1aWNrX3NlYXJjaF90eXBlZF9rZXlzLCAnQUNvbWJvQm94LmpzJywgJ0FDb21ib0JveCcsICdzZWxlY3ROZXh0SXRlbScsIDEwICk7XG5cdFx0XHRcdHZhciB0cmltbWVkX3F1aWNrX3NlYXJjaF90eXBlZF9rZXlzID0gcXVpY2tfc2VhcmNoX3R5cGVkX2tleXMudHJpbSgpO1xuXG5cdFx0XHRcdGlmICggYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uIHx8IHRyZWVfbW9kZSApIHtcblx0XHRcdFx0XHRpZiAoIHRyaW1tZWRfcXVpY2tfc2VhcmNoX3R5cGVkX2tleXMgKSB7XG5cdFx0XHRcdFx0XHR0YXJnZXRfZ3JpZCA9IGFfZHJvcGRvd24uZ2V0Rm9jdXNJblNlbGV0R3JpZCgpID8gYV9kcm9wZG93bi5nZXRTZWxlY3RHcmlkKCkgOiBhX2Ryb3Bkb3duLmdldFVuU2VsZWN0R3JpZCgpO1xuXG5cdFx0XHRcdFx0XHR2YXIgc2VhcmNoX2luZGV4ID0gcXVpY2tfc2VhcmNoX2RpY1t0cmltbWVkX3F1aWNrX3NlYXJjaF90eXBlZF9rZXlzXSA/IHF1aWNrX3NlYXJjaF9kaWNbdHJpbW1lZF9xdWlja19zZWFyY2hfdHlwZWRfa2V5c10gOiAwO1xuXHRcdFx0XHRcdFx0dmFyIHRkcyA9ICQoIHRhcmdldF9ncmlkLmdyaWQuZmluZCggJ3RyJyApLmZpbmQoICd0ZDplcSgxKScgKS5maWx0ZXIoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gJC50ZXh0KCBbdGhpc10gKS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoIHRyaW1tZWRfcXVpY2tfc2VhcmNoX3R5cGVkX2tleXMgKSA9PSAwO1xuXHRcdFx0XHRcdFx0fSApICk7XG5cdFx0XHRcdFx0XHR2YXIgdGQ7XG5cdFx0XHRcdFx0XHRpZiAoIHNlYXJjaF9pbmRleCA+IDAgJiYgc2VhcmNoX2luZGV4IDwgdGRzLmxlbmd0aCApIHtcblxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0c2VhcmNoX2luZGV4ID0gMDtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0dGQgPSAkKCB0ZHNbc2VhcmNoX2luZGV4XSApO1xuXHRcdFx0XHRcdFx0YV9kcm9wZG93bi51blNlbGVjdEFsbCggdGFyZ2V0X2dyaWQuZ3JpZCwgdHJ1ZSApO1xuXHRcdFx0XHRcdFx0Ly9uZXh0X2luZGV4ID0gdGQucGFyZW50KCkuaW5kZXgoKSAtIDE7XG5cblx0XHRcdFx0XHRcdHZhciBuZXh0X3NlbGVjdF9pdGVtID0gZmFsc2U7XG5cdFx0XHRcdFx0XHR2YXIgZ3JpZF9kYXRhID0gdGFyZ2V0X2dyaWQuZ2V0RGF0YSgpO1xuXHRcdFx0XHRcdFx0Zm9yICggdmFyIHogPSAwOyB6IDwgZ3JpZF9kYXRhLmxlbmd0aDsgeisrICkge1xuXHRcdFx0XHRcdFx0XHRpZiAoIGdyaWRfZGF0YVt6XS5pZCA9PSB0ZC5wYXJlbnRzKCAndHInICkuYXR0ciggJ2lkJyApICkge1xuXHRcdFx0XHRcdFx0XHRcdG5leHRfc2VsZWN0X2l0ZW0gPSBncmlkX2RhdGFbel07XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0c2VsZWN0X2l0ZW0gPSBuZXh0X3NlbGVjdF9pdGVtO1xuXG5cdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLnNldFNlbGVjdEl0ZW0oIG5leHRfc2VsZWN0X2l0ZW0sIHRhcmdldF9ncmlkICk7XG5cdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLnNldElzQ2hhbmdlZCggdHJ1ZSApO1xuXHRcdFx0XHRcdFx0cXVpY2tfc2VhcmNoX2RpYyA9IHt9O1xuXHRcdFx0XHRcdFx0cXVpY2tfc2VhcmNoX2RpY1t0cmltbWVkX3F1aWNrX3NlYXJjaF90eXBlZF9rZXlzXSA9IHNlYXJjaF9pbmRleCArIDE7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGlmICggdHJpbW1lZF9xdWlja19zZWFyY2hfdHlwZWRfa2V5cyApIHtcblx0XHRcdFx0XHRcdHNlYXJjaF9pbmRleCA9IHF1aWNrX3NlYXJjaF9kaWNbdHJpbW1lZF9xdWlja19zZWFyY2hfdHlwZWRfa2V5c10gPyBxdWlja19zZWFyY2hfZGljW3RyaW1tZWRfcXVpY2tfc2VhcmNoX3R5cGVkX2tleXNdIDogMDtcblx0XHRcdFx0XHRcdHRkcyA9ICQoIGFfZHJvcGRvd24uZ2V0VW5TZWxlY3RHcmlkKCkuZ3JpZC5maW5kKCAndHInICkuZmluZCggJ3RkOmZpcnN0JyApLmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiAkLnRleHQoIFt0aGlzXSApLnRvTG93ZXJDYXNlKCkuaW5kZXhPZiggdHJpbW1lZF9xdWlja19zZWFyY2hfdHlwZWRfa2V5cyApID09IDA7XG5cdFx0XHRcdFx0XHR9ICkgKTtcblx0XHRcdFx0XHRcdGlmICggc2VhcmNoX2luZGV4ID4gMCAmJiBzZWFyY2hfaW5kZXggPCB0ZHMubGVuZ3RoICkge1xuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRzZWFyY2hfaW5kZXggPSAwO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0dGQgPSAkKCB0ZHNbc2VhcmNoX2luZGV4XSApO1xuXHRcdFx0XHRcdFx0bmV4dF9pbmRleCA9IHRkLnBhcmVudCgpLmluZGV4KCkgLSAxO1xuXHRcdFx0XHRcdFx0bmV4dF9zZWxlY3RfaXRlbSA9IHRoaXMuZ2V0SXRlbUJ5SW5kZXgoIG5leHRfaW5kZXggKTtcblx0XHRcdFx0XHRcdHNlbGVjdF9pdGVtID0gbmV4dF9zZWxlY3RfaXRlbTtcblx0XHRcdFx0XHRcdGFfZHJvcGRvd24uc2V0U2VsZWN0SXRlbSggbmV4dF9zZWxlY3RfaXRlbSApO1xuXHRcdFx0XHRcdFx0cXVpY2tfc2VhcmNoX2RpYyA9IHt9O1xuXHRcdFx0XHRcdFx0cXVpY2tfc2VhcmNoX2RpY1t0cmltbWVkX3F1aWNrX3NlYXJjaF90eXBlZF9rZXlzXSA9IHNlYXJjaF9pbmRleCArIDE7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLmdyaWRTY3JvbGxUb3AgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0aWYgKCAhYV9kcm9wZG93biApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRhX2Ryb3Bkb3duLmdyaWRTY3JvbGxUb3AoKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5ncmlkU2Nyb2xsRG93biA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRpZiAoICFhX2Ryb3Bkb3duICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGFfZHJvcGRvd24uZ3JpZFNjcm9sbERvd24oKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZWxlY3RBbGwgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggIWFfZHJvcGRvd24gfHwgdHJlZV9tb2RlIHx8ICFhbGxvd19tdWx0aXBsZV9zZWxlY3Rpb24gKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0YV9kcm9wZG93bi5zZWxlY3RBbGwoKTtcblxuXHRcdH07XG5cblx0XHR0aGlzLmdldElzTW91c2VPdmVyID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gaXNfbW91c2Vfb3Zlcjtcblx0XHR9O1xuXG5cdFx0dGhpcy5vblNob3dBbGwgPSBmdW5jdGlvbiggaXNTaG93QWxsICkge1xuXHRcdFx0c2hvd19hbGwgPSBpc1Nob3dBbGw7XG5cblx0XHRcdHZhciBhcmdzID0gdGhpcy5idWlsZFVuU2VsZWN0R3JpZEZpbHRlcigpO1xuXHRcdFx0YXJncyA9IHRoaXMuYWRkRXhjbHVkZUlEc1RvRmlsdGVyKCBhcmdzLCBhX2Ryb3Bkb3duLmdldFNlbGVjdEl0ZW1zKCkgKTtcblxuXHRcdFx0YXBpWydnZXQnICsgY3VzdG9tX2tleV9uYW1lXSggYXJncywge1xuXHRcdFx0XHRvblJlc3VsdDogZnVuY3Rpb24oIHJlc3VsdCApIHtcblxuXHRcdFx0XHRcdHZhciByZXN1bHRfZGF0YSA9IHJlc3VsdC5nZXRSZXN1bHQoKTtcblxuXHRcdFx0XHRcdGlmICggIXJlc3VsdF9kYXRhICkge1xuXHRcdFx0XHRcdFx0cmVzdWx0X2RhdGEgPSBbXTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRwYWdlcl9kYXRhID0gcmVzdWx0LmdldFBhZ2VyRGF0YSgpO1xuXHRcdFx0XHRcdHNvdXJjZV9kYXRhID0gcmVzdWx0X2RhdGE7XG5cblx0XHRcdFx0XHRpZiAoIEdsb2JhbC5pc1NldCggYXBpICkgKSB7XG5cdFx0XHRcdFx0XHRzb3VyY2VfZGF0YSA9IEdsb2JhbC5mb3JtYXRHcmlkRGF0YSggc291cmNlX2RhdGEsIGFwaS5rZXlfbmFtZSApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGFfZHJvcGRvd24uc2V0VW5zZWxlY3RlZEdyaWREYXRhKCBzb3VyY2VfZGF0YSApO1xuXHRcdFx0XHRcdC8vYV9kcm9wZG93bi5zZXRTZWxlY3RHcmlkRGF0YSggYV9kcm9wZG93bi5nZXRTZWxlY3RJdGVtcygpICk7XG5cdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRQYWdlckRhdGEoIHBhZ2VyX2RhdGEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH07XG5cblx0XHR0aGlzLmJ1aWxkVW5TZWxlY3RHcmlkRmlsdGVyID0gZnVuY3Rpb24oIGV4Y2x1ZGVfaWRzID0gbnVsbCApIHtcblx0XHRcdHZhciBhcmdzID0ge307XG5cdFx0XHRhcmdzLmZpbHRlcl9kYXRhID0ge307XG5cdFx0XHRhcmdzLmZpbHRlcl9jb2x1bW5zID0gJHRoaXMuZ2V0Q29sdW1uRmlsdGVyKCk7XG5cdFx0XHRhcmdzLmZpbHRlcl9pdGVtc19wZXJfcGFnZSA9IHJvd19wZXJfcGFnZTtcblxuXHRcdFx0aWYgKCBhX2Ryb3Bkb3duICkge1xuXHRcdFx0XHQvL3VzZSBjbG9uZSBzbyB0aGUgdmlldyBzZWFyY2ggY29uZGl0aW9uIG5vdCBiZSBzZXQgd2hlbiBzZXQgZGVmYXVsdCBhcmdzXG5cdFx0XHRcdGFyZ3MuZmlsdGVyX2RhdGEgPSBHbG9iYWwuY2xvbmUoIGFfZHJvcGRvd24uZ2V0VW5TZWxlY3RHcmlkTWFwKCkgKTtcblx0XHRcdFx0YXJncy5maWx0ZXJfc29ydCA9IEdsb2JhbC5jbG9uZSggYV9kcm9wZG93bi5nZXRVblNlbGVjdEdyaWRTb3J0TWFwKCkgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBhcmdzX2Zyb21fc2F2ZWRfbGF5b3V0ICkge1xuXHRcdFx0XHRpZiAoIEdsb2JhbC5pc1NldCggYXJnc19mcm9tX3NhdmVkX2xheW91dC5maWx0ZXJfZGF0YSApICkge1xuXHRcdFx0XHRcdGZvciAoIHZhciBrZXkgaW4gYXJnc19mcm9tX3NhdmVkX2xheW91dC5maWx0ZXJfZGF0YSApIHtcblx0XHRcdFx0XHRcdGlmICggIWFyZ3MuZmlsdGVyX2RhdGEuaGFzT3duUHJvcGVydHkoIGtleSApICkge1xuXHRcdFx0XHRcdFx0XHRhcmdzLmZpbHRlcl9kYXRhW2tleV0gPSBhcmdzX2Zyb21fc2F2ZWRfbGF5b3V0LmZpbHRlcl9kYXRhW2tleV07XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIGFyZ3NfZnJvbV9zYXZlZF9sYXlvdXQgJiYgR2xvYmFsLmlzU2V0KCBhcmdzX2Zyb21fc2F2ZWRfbGF5b3V0LnBlcm1pc3Npb25fc2VjdGlvbiApICkge1xuXHRcdFx0XHRcdGFyZ3MucGVybWlzc2lvbl9zZWN0aW9uID0gYXJnc19mcm9tX3NhdmVkX2xheW91dC5wZXJtaXNzaW9uX3NlY3Rpb247XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvL0RvIG5vdCBvdmVycmlkZSBzb3J0IGNvbmRpdGlvblxuXHRcdFx0XHRpZiAoIEdsb2JhbC5pc1NldCggYXJnc19mcm9tX3NhdmVkX2xheW91dC5maWx0ZXJfc29ydCApICYmICFhcmdzLmZpbHRlcl9zb3J0ICkge1xuXG5cdFx0XHRcdFx0YXJncy5maWx0ZXJfc29ydCA9IGFyZ3NfZnJvbV9zYXZlZF9sYXlvdXQuZmlsdGVyX3NvcnQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly9kZWZhdWx0X2FyZ3MgaXMgc2V0IHdoZW4gbmF2aWdhdGlvbiBtb2RlIHVzdWFsbHkuIFRvIGtlZXAgc2VhcmNoIGZpbHRlciBzYW1lIGFzIGxpc3QgdmlldyBncmlkXG5cdFx0XHQvLy4gSW4gQmFzZUNvbnRyb2xsZXIsIHNldEVkaXRWaWV3RGF0YSBmdW5jdGlvblxuXHRcdFx0aWYgKCBkZWZhdWx0X2FyZ3MgKSB7XG5cblx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGRlZmF1bHRfYXJncy5maWx0ZXJfZGF0YSApICkge1xuXHRcdFx0XHRcdGZvciAoIHZhciBrZXkgaW4gZGVmYXVsdF9hcmdzLmZpbHRlcl9kYXRhICkge1xuXHRcdFx0XHRcdFx0aWYgKCAhYXJncy5maWx0ZXJfZGF0YS5oYXNPd25Qcm9wZXJ0eSgga2V5ICkgKSB7XG5cdFx0XHRcdFx0XHRcdGFyZ3MuZmlsdGVyX2RhdGFba2V5XSA9IGRlZmF1bHRfYXJncy5maWx0ZXJfZGF0YVtrZXldO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBkZWZhdWx0X2FyZ3MgJiYgR2xvYmFsLmlzU2V0KCBkZWZhdWx0X2FyZ3MucGVybWlzc2lvbl9zZWN0aW9uICkgKSB7XG5cdFx0XHRcdFx0YXJncy5wZXJtaXNzaW9uX3NlY3Rpb24gPSBkZWZhdWx0X2FyZ3MucGVybWlzc2lvbl9zZWN0aW9uO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly9EbyBub3Qgb3ZlcnJpZGUgc29ydCBjb25kaXRpb25cblx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGRlZmF1bHRfYXJncy5maWx0ZXJfc29ydCApICYmICFhcmdzLmZpbHRlcl9zb3J0ICkge1xuXG5cdFx0XHRcdFx0YXJncy5maWx0ZXJfc29ydCA9IGRlZmF1bHRfYXJncy5maWx0ZXJfc29ydDtcblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdC8vSWYgaXQgaGFzIGFkZGl0aW9uYWwgc2VhcmNoIGNvbmRpdGlvbiBmcm9tIG91dHNpZGUgdmlld2NvbnRyb2xsZXJcblx0XHRcdGlmICggdGhpcy5jdXN0b21TZWFyY2hGaWx0ZXIgKSB7XG5cdFx0XHRcdGFyZ3MgPSB0aGlzLmN1c3RvbVNlYXJjaEZpbHRlciggYXJncyApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHNob3dfYWxsICkge1xuXHRcdFx0XHRhcmdzLnNlY29uZF9wYXJhbWV0ZXIgPSB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBXaGVuIHVzaW5nIEFDb21ibywgYXQgdGhpcyBwb2ludCBhX2Ryb3Bkb3duLmdldFNlbGVjdEl0ZW1zKCkgbWlnaHQgYmUgZW1wdHksIGJ1dCAkdGhpcy5nZXRWYWx1ZSgpL3NlbGVjdF9pdGVtcyBoYXMgdGhlIHNlbGVjdGVkIElEcyBpbnN0ZWFkLiBUaGV5IGFyZSBpbiBhIGRpZmZlcmVudCBmb3JtYXQgdGhvdWdoLlxuXHRcdFx0Ly8gICBUaGlzIGlzIGFsc28gcmVxdWlyZWQgaW4gY2FzZXMgd2hlcmUgYW4gZW1wbG95ZWUgaGFzIDUwIGl0ZW1zLCA0OCBhcmUgYWxyZWFkeSBzZWxlY3RlZCwgYW5kIHBhZ2luYXRpb24gaXMgc2V0IHRvIDUgaXRlbXMgcGVyIHJvdy5cblx0XHRcdC8vICAgICBUaGVuIG9uIHRoZSB1bnNlbGVjdGVkIHNpZGUgY2xpY2sgdG8gc29ydCBieSBcIkxhc3QgTmFtZVwiIGEgY291cGxlIHRpbWVzLiBUaGVzZSBleGNsdWRlX2lkcyBtdXN0IGJlIHBhc3NlZCB0byB0aGUgQVBJIHNvIG5vIG1hdHRlciB3aGF0IGFsbCB0aGUgdW5zZWxlY3RlZCByb3dzIGFyZSBhbHdheXMgcmV0dXJuZWQsIGp1c3QgaW4gdGhlIHByb3BlciBzb3J0IG9yZGVyLlxuXHRcdFx0aWYgKCBleGNsdWRlX2lkcyApIHtcblx0XHRcdFx0YXJncyA9IHRoaXMuYWRkRXhjbHVkZUlEc1RvRmlsdGVyKCBhcmdzLCBleGNsdWRlX2lkcyApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gYXJncztcblx0XHR9O1xuXG5cdFx0dGhpcy5hZGRFeGNsdWRlSURzVG9GaWx0ZXIgPSBmdW5jdGlvbiggYXJncywgZXhjbHVkZV9pZHMgKSB7XG5cdFx0XHRpZiAoIGFfZHJvcGRvd24gJiYgYXJncyAmJiBleGNsdWRlX2lkcyApIHsgLy8jMjM1MyAtIGpzIGV4Y2VwdGlvbiB3aGVuIGFfZHJvcGRvd24gaXMgbm90IGRlZmluZWQgeWV0XG5cdFx0XHRcdHZhciBzZWxlY3RlZF9pZHMgPSBleGNsdWRlX2lkcztcblx0XHRcdFx0aWYgKCBzZWxlY3RlZF9pZHMgJiYgR2xvYmFsLmlzQXJyYXkoIHNlbGVjdGVkX2lkcyApICYmIHNlbGVjdGVkX2lkcy5sZW5ndGggPiAwICYmIHNlbGVjdGVkX2lkc1swXSAhPSBUVFVVSUQuemVyb19pZCApIHtcblx0XHRcdFx0XHRhcmdzLmZpbHRlcl9kYXRhLmV4Y2x1ZGVfaWQgPSBbXTtcblx0XHRcdFx0XHRmb3IgKCB2YXIgeCBpbiBzZWxlY3RlZF9pZHMgKSB7XG5cdFx0XHRcdFx0XHQvLyBJc3N1ZSAjMjg5OSAtIFNlbGVjdGVkIGl0ZW1zIGNhbiBlaXRoZXIgYmUgYW4gYXJyYXkgb2YgSURzIG9yIGFuIG9iamVjdC4gTmVlZCB0byBhY2NvdW50IGZvciBlaXRoZXIgc2l0dWF0aW9uLlxuXHRcdFx0XHRcdFx0aWYgKCBzZWxlY3RlZF9pZHNbeF0uaWQgKSB7XG5cdFx0XHRcdFx0XHRcdGFyZ3MuZmlsdGVyX2RhdGEuZXhjbHVkZV9pZC5wdXNoKCBzZWxlY3RlZF9pZHNbeF0uaWQgKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGFyZ3MuZmlsdGVyX2RhdGEuZXhjbHVkZV9pZC5wdXNoKCBzZWxlY3RlZF9pZHNbeF0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGFyZ3M7XG5cdFx0fVxuXG5cdFx0dGhpcy5idWlsZFNlbGVjdEdyaWRGaWx0ZXIgPSBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBhcmdzID0ge307XG5cdFx0XHRhcmdzLmZpbHRlcl9jb2x1bW5zID0gJHRoaXMuZ2V0Q29sdW1uRmlsdGVyKCk7XG5cdFx0XHRhcmdzLmZpbHRlcl9pdGVtc19wZXJfcGFnZSA9IHJvd19wZXJfcGFnZTtcblx0XHRcdGFyZ3MuZmlsdGVyX2RhdGEgPSBhX2Ryb3Bkb3duLmdldFNlbGVjdEdyaWRNYXAoKTtcblx0XHRcdGFyZ3MuZmlsdGVyX3NvcnQgPSBhX2Ryb3Bkb3duLmdldFNlbGVjdEdyaWRTb3J0TWFwKCk7XG5cdFx0XHRhcmdzLnNlY29uZF9wYXJhbWV0ZXIgPSB0cnVlOyAvL0Fsd2F5cyBzZXQgdHJ1ZSBiZWNhdXNlIHdlIHdhbnQgYWx3YXN5IHNldCBhbGwgZGF0YSBvdXQgaW4gc2VsZWN0IGdyaWRcblxuXHRcdFx0cmV0dXJuIGFyZ3M7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2VhcmNoSXNFbXB0eSA9IGZ1bmN0aW9uKCBhX2Ryb3Bkb3duICkge1xuXHRcdFx0dmFyIGlucHV0cyA9IGFfZHJvcGRvd24uZmluZCggJ2lucHV0LnNlYXJjaC1pbnB1dCcgKTtcblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0aWYgKCAkKCBpbnB1dHNbaV0gKS52YWwoKSAhPSAkLmkxOG4uXyggJ2NsaWNrIHRvIHNlYXJjaCcgKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH07XG5cblx0XHR0aGlzLm9uQURyb3BEb3duU2VhcmNoID0gZnVuY3Rpb24oIHRhcmdldE5hbWUsIHBhZ2VfYWN0aW9uLCBkZWZhdWx0X3NlbGVjdF9pdGVtLCBjYWxsQmFjaywgdHJpZ2dlcl9mb3JtX2l0ZW1fY2hhbmdlID0gdHJ1ZSApIHtcblx0XHRcdHZhciB0aGlzX3ZhbCA9IHRoaXMuZ2V0VmFsdWUoKTtcblx0XHRcdGlmICggdGFyZ2V0TmFtZSA9PSAnc2VsZWN0X2dyaWQnICYmIHRoaXNfdmFsLmxlbmd0aCA9PSAwIHx8ICggdGFyZ2V0TmFtZSA9PSAnc2VsZWN0X2dyaWQnICYmIHRoaXNfdmFsLmxlbmd0aCA9PSAxICYmIHRoaXNfdmFsWzBdID09IFRUVVVJRC5ub3RfZXhpc3RfaWQgKSApIHtcblx0XHRcdFx0Ly8jMjM1MyAtIHByZXZlbnQgYnVnIHdoZXJlIHNvcnRlZCBlbXB0eSBzZWxlY3QgZ3JpZCBzZWxlY3RzIGV2ZXJ5dGhpbmdcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgYXJncyA9IHt9O1xuXHRcdFx0YXJncy5maWx0ZXJfY29sdW1ucyA9ICR0aGlzLmdldENvbHVtbkZpbHRlcigpO1xuXHRcdFx0YXJncy5maWx0ZXJfaXRlbXNfcGVyX3BhZ2UgPSByb3dfcGVyX3BhZ2U7XG5cdFx0XHRpZiAoIHRhcmdldE5hbWUgPT09ICd1bnNlbGVjdF9ncmlkJyApIHtcblx0XHRcdFx0Ly9XaGVuIHVzaW5nIHBhZ2luYXRpb24gYW5kIGZpcnN0IG9wZW5pbmcgdGhlIGRyb3Bkb3duIGJveCwgd2UgbmVlZCB0byBleGNsdWRlIHRoZSBzZWxlY3RlZCBpdGVtcyBmcm9tIHRoZSBBUEkgY2FsbFxuXHRcdFx0XHQvLyBzbyB0aGUgZmlyc3QgcGFnZSB3aWxsIGFsd2F5cyBiZSBwb3B1bGF0ZWQgd2l0aCBhIGZ1bGwgcGFnZSBvZiByZWNvcmRzLlxuXHRcdFx0XHRhcmdzID0gJHRoaXMuYnVpbGRVblNlbGVjdEdyaWRGaWx0ZXIoICggKCBhX2Ryb3Bkb3duICkgPyBhX2Ryb3Bkb3duLmdldFNlbGVjdEl0ZW1zKCkgOiBudWxsICkgKTsgLy9IYW5kbGUgSlMgZXhjZXB0aW9uOiBFcnJvcjogQ2Fubm90IHJlYWQgcHJvcGVydHkgJ2dldFNlbGVjdEl0ZW1zJyBvZiBudWxsXG5cblx0XHRcdFx0Ly9FcnJvcjogVW5hYmxlIHRvIGdldCBwcm9wZXJ0eSAnY3VycmVudF9wYWdlJyBvZiB1bmRlZmluZWQgb3IgbnVsbCByZWZlcmVuY2UgaW4gL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvd2lkZ2V0cy9hd2Vzb21lYm94L0FDb21ib0JveC5qcz92PTcuNC42LTIwMTQxMDI3LTA3MDAwMyBsaW5lIDE0ODlcblx0XHRcdFx0aWYgKCBhX2Ryb3Bkb3duICYmIGFfZHJvcGRvd24uZ2V0UGFnZXJEYXRhKCkgKSB7XG5cdFx0XHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5wYWdpbmdfdHlwZSA9PT0gMCApIHtcblx0XHRcdFx0XHRcdGlmICggcGFnZV9hY3Rpb24gPT09ICduZXh0JyApIHtcblx0XHRcdFx0XHRcdFx0YXJncy5maWx0ZXJfcGFnZSA9IGFfZHJvcGRvd24uZ2V0UGFnZXJEYXRhKCkubmV4dF9wYWdlO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0YXJncy5maWx0ZXJfcGFnZSA9IDE7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHN3aXRjaCAoIHBhZ2VfYWN0aW9uICkge1xuXHRcdFx0XHRcdFx0XHRjYXNlICduZXh0Jzpcblx0XHRcdFx0XHRcdFx0XHRhcmdzLmZpbHRlcl9wYWdlID0gYV9kcm9wZG93bi5nZXRQYWdlckRhdGEoKS5uZXh0X3BhZ2U7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdGNhc2UgJ2xhc3QnOlxuXHRcdFx0XHRcdFx0XHRcdGFyZ3MuZmlsdGVyX3BhZ2UgPSBhX2Ryb3Bkb3duLmdldFBhZ2VyRGF0YSgpLnByZXZpb3VzX3BhZ2U7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdGNhc2UgJ3N0YXJ0Jzpcblx0XHRcdFx0XHRcdFx0XHRhcmdzLmZpbHRlcl9wYWdlID0gMTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0Y2FzZSAnZW5kJzpcblx0XHRcdFx0XHRcdFx0XHRhcmdzLmZpbHRlcl9wYWdlID0gYV9kcm9wZG93bi5nZXRQYWdlckRhdGEoKS5sYXN0X3BhZ2VfbnVtYmVyO1xuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0XHRcdGFyZ3MuZmlsdGVyX3BhZ2UgPSBhX2Ryb3Bkb3duLmdldFBhZ2VyRGF0YSgpLmN1cnJlbnRfcGFnZTtcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIHBhcnNlSW50KCBwYWdlX2FjdGlvbiApID49IDEgKSB7XG5cdFx0XHRcdFx0YXJncy5maWx0ZXJfcGFnZSA9IHBhZ2VfYWN0aW9uO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0YXBpWydnZXQnICsgY3VzdG9tX2tleV9uYW1lXSggYXJncywge1xuXHRcdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXG5cdFx0XHRcdFx0XHR2YXIgZm9jdXNlZF9lbGVtZW50ID0gJCggJzpmb2N1cycgKTtcblxuXHRcdFx0XHRcdFx0dmFyIHJlc3VsdF9kYXRhID0gcmVzdWx0LmdldFJlc3VsdCgpO1xuXG5cdFx0XHRcdFx0XHRpZiAoICFHbG9iYWwuaXNBcnJheSggcmVzdWx0X2RhdGEgKSApIHtcblx0XHRcdFx0XHRcdFx0cmVzdWx0X2RhdGEgPSBbXTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly9zZXQgdGhpcyBvdXRzaWRlLCB0byBhZGQgbW9yZSBkYXRhIHRvIHNvdXJjZV9kYXRhXG5cdFx0XHRcdFx0XHRpZiAoIGFkZGl0aW9uX3NvdXJjZV9mdW5jdGlvbiApIHtcblx0XHRcdFx0XHRcdFx0cmVzdWx0X2RhdGEgPSBhZGRpdGlvbl9zb3VyY2VfZnVuY3Rpb24oICR0aGlzLCByZXN1bHRfZGF0YSApO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLnBhZ2luZ190eXBlID09PSAwICYmIHBhZ2VfYWN0aW9uID09PSAnbmV4dCcgKSB7XG5cdFx0XHRcdFx0XHRcdHZhciBjdXJyZW50X2RhdGEgPSBhX2Ryb3Bkb3duLmdldFVuU2VsZWN0R3JpZERhdGEoKTtcblx0XHRcdFx0XHRcdFx0cmVzdWx0X2RhdGEgPSBjdXJyZW50X2RhdGEuY29uY2F0KCByZXN1bHRfZGF0YSApO1xuXG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGlmICggbmF2aWdhdGlvbl9tb2RlICkge1xuXHRcdFx0XHRcdFx0XHRzb3VyY2VfZGF0YSA9IHJlc3VsdF9kYXRhO1xuXHRcdFx0XHRcdFx0XHRwYWdlcl9kYXRhID0gcmVzdWx0LmdldFBhZ2VyRGF0YSgpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0dW5zZWxlY3RfZ3JpZF9zZWFyY2hfcmVzdWx0ID0gcmVzdWx0X2RhdGE7XG5cdFx0XHRcdFx0XHRcdGN1cnJlbnRfb3Blbl9wYWdlID0gcmVzdWx0LmdldFBhZ2VyRGF0YSgpLmN1cnJlbnRfcGFnZTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKCAkLnR5cGUoIHJlc3VsdF9kYXRhICkgIT0gJ2FycmF5JyApIHtcblx0XHRcdFx0XHRcdFx0cmVzdWx0X2RhdGEgPSBbXTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKCAhYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uICkge1xuXHRcdFx0XHRcdFx0XHQkdGhpcy5jcmVhdGVGaXJzdEl0ZW0oIHJlc3VsdF9kYXRhICk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHJlc3VsdF9kYXRhID0gR2xvYmFsLmZvcm1hdEdyaWREYXRhKCByZXN1bHRfZGF0YSwgYXBpLmtleV9uYW1lICk7XG5cblx0XHRcdFx0XHRcdGlmICggZXh0ZW5kRGF0YVByb2Nlc3NXaGVuU2VhcmNoICkge1xuXHRcdFx0XHRcdFx0XHRyZXN1bHRfZGF0YSA9IGV4dGVuZERhdGFQcm9jZXNzV2hlblNlYXJjaCggcmVzdWx0X2RhdGEgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGFfZHJvcGRvd24gJiYgYV9kcm9wZG93bi5zZXRVbnNlbGVjdGVkR3JpZERhdGEoIHJlc3VsdF9kYXRhICk7XG5cblx0XHRcdFx0XHRcdGlmICggYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uICkge1xuXHRcdFx0XHRcdFx0XHRhX2Ryb3Bkb3duICYmIGFfZHJvcGRvd24uc2V0U2VsZWN0R3JpZERhdGEoIGFfZHJvcGRvd24uZ2V0U2VsZWN0SXRlbXMoKSwgdHJ1ZSApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0YV9kcm9wZG93biAmJiBhX2Ryb3Bkb3duLnNldFNlbGVjdEl0ZW0oIGFfZHJvcGRvd24uZ2V0U2VsZWN0SXRlbSgpICk7XG5cdFx0XHRcdFx0XHRcdGlmICggZGVmYXVsdF9zZWxlY3RfaXRlbSA9PSAnZmlyc3QnICkge1xuXHRcdFx0XHRcdFx0XHRcdCR0aGlzLnNldFZhbHVlKCByZXN1bHRfZGF0YVswXSApO1xuXHRcdFx0XHRcdFx0XHRcdGlmICggdHJpZ2dlcl9mb3JtX2l0ZW1fY2hhbmdlID09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQkdGhpcy50cmlnZ2VyKCAnZm9ybUl0ZW1DaGFuZ2UnLCBbJHRoaXNdICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGlmICggY2FsbEJhY2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjYWxsQmFjayggcmVzdWx0X2RhdGFbMF0gKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGRlZmF1bHRfc2VsZWN0X2l0ZW0gPT0gJ2xhc3QnICkge1xuXHRcdFx0XHRcdFx0XHRcdCR0aGlzLnNldFZhbHVlKCByZXN1bHRfZGF0YVtyZXN1bHRfZGF0YS5sZW5ndGggLSAxXSApO1xuXHRcdFx0XHRcdFx0XHRcdGlmICggdHJpZ2dlcl9mb3JtX2l0ZW1fY2hhbmdlID09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQkdGhpcy50cmlnZ2VyKCAnZm9ybUl0ZW1DaGFuZ2UnLCBbJHRoaXNdICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGlmICggY2FsbEJhY2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjYWxsQmFjayggcmVzdWx0X2RhdGFbcmVzdWx0X2RhdGEubGVuZ3RoIC0gMV0gKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGNhbGxCYWNrICkge1xuXHRcdFx0XHRcdFx0XHRcdGNhbGxCYWNrKCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0YV9kcm9wZG93biAmJiBhX2Ryb3Bkb3duLnNldFBhZ2VyRGF0YSggcmVzdWx0LmdldFBhZ2VyRGF0YSgpICk7XG5cblx0XHRcdFx0XHRcdGlmICggcmVzdWx0X2RhdGEubGVuZ3RoIDwgMSAmJiBhX2Ryb3Bkb3duLmdldFNlbGVjdEl0ZW1zKCkubGVuZ3RoIDwgMSApIHtcblx0XHRcdFx0XHRcdFx0YV9kcm9wZG93biAmJiBhX2Ryb3Bkb3duLnNob3dOb1Jlc3VsdENvdmVyKCAndW5zZWxlY3RfZ3JpZCcgKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGFfZHJvcGRvd24gJiYgYV9kcm9wZG93bi5yZW1vdmVOb1Jlc3VsdENvdmVyKCAndW5zZWxlY3RfZ3JpZCcgKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0YV9kcm9wZG93biAmJiBhX2Ryb3Bkb3duLmdldFVuU2VsZWN0R3JpZCgpLmdyaWQuc2hvdygpO1xuXG5cdFx0XHRcdFx0XHRpZiAoIGZvY3VzZWRfZWxlbWVudC5sZW5ndGggKSB7XG5cdFx0XHRcdFx0XHRcdGZvY3VzZWRfZWxlbWVudC5mb2N1cygpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGFyZ3MgPSB0aGlzLmJ1aWxkU2VsZWN0R3JpZEZpbHRlcigpO1xuXHRcdFx0XHRpZiAoIGFyZ3MuZmlsdGVyX2RhdGEuaWQgJiYgYXJncy5maWx0ZXJfZGF0YS5pZCAhPT0gZmFsc2UgKSB7IC8vcHJldmVudCByZXR1cm5pbmcgYWxsIGF2YWlsYWJsZSByb3dzIHdoZW4gbm90aGluZyBpcyBzZWxlY3RlZFxuXHRcdFx0XHRcdGFwaVsnZ2V0JyArIGN1c3RvbV9rZXlfbmFtZV0oIGFyZ3MsIHtcblx0XHRcdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdFx0XHRcdFx0XHR2YXIgcmVzdWx0X2RhdGEgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cdFx0XHRcdFx0XHRcdHZhciBmb2N1c2VkX2VsZW1lbnQgPSAkKCAnOmZvY3VzJyApO1xuXG5cdFx0XHRcdFx0XHRcdGlmICggJC50eXBlKCByZXN1bHRfZGF0YSApICE9ICdhcnJheScgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzdWx0X2RhdGEgPSBbXTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdHJlc3VsdF9kYXRhID0gR2xvYmFsLmZvcm1hdEdyaWREYXRhKCByZXN1bHRfZGF0YSwgYXBpLmtleV9uYW1lICk7XG5cblx0XHRcdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRTZWxlY3RHcmlkU2VhcmNoUmVzdWx0KCByZXN1bHRfZGF0YSApOyAvL3NldCBhcyBzZWFyY2ggcmVzdWx0XG5cblx0XHRcdFx0XHRcdFx0aWYgKCByZXN1bHRfZGF0YS5sZW5ndGggPCAxICkge1xuXHRcdFx0XHRcdFx0XHRcdGFfZHJvcGRvd24uZ2V0U2VsZWN0R3JpZCgpLmdyaWQuY2xlYXJHcmlkRGF0YSgpO1xuXHRcdFx0XHRcdFx0XHRcdGFfZHJvcGRvd24uc2hvd05vUmVzdWx0Q292ZXIoICdzZWxlY3RfZ3JpZCcgKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLnJlbW92ZU5vUmVzdWx0Q292ZXIoICdzZWxlY3RfZ3JpZCcgKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGFfZHJvcGRvd24uc2V0U2VsZWN0R3JpZERyYWdBYmxlKCk7XG5cblx0XHRcdFx0XHRcdFx0YV9kcm9wZG93bi5nZXRTZWxlY3RHcmlkKCkuZ3JpZC5zaG93KCk7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCBmb2N1c2VkX2VsZW1lbnQubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHRcdFx0XHRmb2N1c2VkX2VsZW1lbnQuZm9jdXMoKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5idWlsZERpc3BsYXlDb2x1bW5zID0gZnVuY3Rpb24oIGFwaV9kaXNwbGF5X2NvbHVtbnMgKSB7XG5cdFx0XHR2YXIgbGVuID0gYWxsX2NvbHVtbnMubGVuZ3RoO1xuXHRcdFx0dmFyIGxlbjEgPSBhcGlfZGlzcGxheV9jb2x1bW5zLmxlbmd0aDtcblx0XHRcdHZhciBkaXNwbGF5X2NvbHVtbnMgPSBbXTtcblxuXHRcdFx0Zm9yICggdmFyIGogPSAwOyBqIDwgbGVuMTsgaisrICkge1xuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRpZiAoIGFwaV9kaXNwbGF5X2NvbHVtbnNbal0gPT09IGFsbF9jb2x1bW5zW2ldLnZhbHVlICkge1xuXHRcdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5zLnB1c2goIGFsbF9jb2x1bW5zW2ldICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZGlzcGxheV9jb2x1bW5zO1xuXHRcdH07XG5cblx0XHR0aGlzLmJ1aWxkRGlzcGxheUNvbHVtbnNGb3JFZGl0b3IgPSBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBsZW4gPSBhbGxfY29sdW1ucy5sZW5ndGg7XG5cdFx0XHR2YXIgbGVuMSA9IGRpc3BsYXlfY29sdW1ucy5sZW5ndGg7XG5cdFx0XHR2YXIgcmVzdWx0X2Rpc3BsYXlfY29sdW1ucyA9IFtdO1xuXHRcdFx0Zm9yICggdmFyIGogPSAwOyBqIDwgbGVuMTsgaisrICkge1xuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRpZiAoICFkaXNwbGF5X2NvbHVtbnNbal0gKSB7XG5cdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGRpc3BsYXlfY29sdW1uc1tqXS5uYW1lICkgKSB7IC8valFncmlkIGNvbHVtbiBmb3JtYXRcblx0XHRcdFx0XHRcdHZhciBuYW1lID0gZGlzcGxheV9jb2x1bW5zW2pdLm5hbWU7XG5cdFx0XHRcdFx0fSBlbHNlIGlmICggR2xvYmFsLmlzU2V0KCBkaXNwbGF5X2NvbHVtbnNbal0udmFsdWUgKSApIHsgIC8vVmlld0NvbHVtbiBmb3JtYXQsXHRsYWJlbCBhbmQgdmFsdWVcblx0XHRcdFx0XHRcdG5hbWUgPSBkaXNwbGF5X2NvbHVtbnNbal0udmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggbmFtZSA9PT0gYWxsX2NvbHVtbnNbaV0udmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRyZXN1bHRfZGlzcGxheV9jb2x1bW5zLnB1c2goIGFsbF9jb2x1bW5zW2ldICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiByZXN1bHRfZGlzcGxheV9jb2x1bW5zO1xuXG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0TG9jYWxTZWxlY3RJdGVtID0gZnVuY3Rpb24oIHZhbCApIHtcblxuXHRcdFx0aWYgKCBhZGRlZF9pdGVtcyApIHtcblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgYWRkZWRfaXRlbXMubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0aWYgKCB2YWwgPT0gYWRkZWRfaXRlbXNbaV0udmFsdWUgKSB7IC8vc29tZXRpbWUgdGhlIHZhbHVlIGlzIG5vdCBudW1iZXJcblx0XHRcdFx0XHRcdHZhciBpdGVtID0ge307XG5cblx0XHRcdFx0XHRcdGl0ZW1ba2V5XSA9IHZhbDtcblxuXHRcdFx0XHRcdFx0JC5lYWNoKCBkaXNwbGF5X2NvbHVtbnMsIGZ1bmN0aW9uKCBpbmRleCwgY29udGVudCApIHtcblxuXHRcdFx0XHRcdFx0XHRpdGVtW2NvbnRlbnQubmFtZV0gPSBhZGRlZF9pdGVtc1tpXS5sYWJlbDtcblxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0XHR9ICk7XG5cblx0XHRcdFx0XHRcdHJldHVybiBpdGVtO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB0aGlzLmdldEZpcnN0SXRlbSgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMuZ2V0Rmlyc3RJdGVtKCk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0Rmlyc3RJdGVtID0gZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgZmlyc3RfaXRlbSA9IHt9O1xuXG5cdFx0XHRmaXJzdF9pdGVtW2tleV0gPSBUVFVVSUQuemVyb19pZDtcblxuXHRcdFx0aWYgKCBzZXRfYW55IHx8IHNldF9hbGwgKSB7XG5cdFx0XHRcdGZpcnN0X2l0ZW1ba2V5XSA9IFRUVVVJRC5ub3RfZXhpc3RfaWQ7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmaXJzdF9pdGVtW2tleV0gPSBUVFVVSUQuemVyb19pZDtcblx0XHRcdH1cblxuXHRcdFx0JC5lYWNoKCBkaXNwbGF5X2NvbHVtbnMsIGZ1bmN0aW9uKCBpbmRleCwgY29udGVudCApIHtcblxuXHRcdFx0XHRpZiAoIGtleSAhPT0gJ2lkJyApIHtcblx0XHRcdFx0XHQvL2ZpcnN0X2l0ZW0uaWQgPSA5OTk7IC8vcmVjb3JkcyBpZCBzdGFydCBmcm9tIDEwMDAwXG5cdFx0XHRcdFx0Zmlyc3RfaXRlbS5pZCA9IFRUVVVJRC5ub3RfZXhpc3RfaWQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBzZXRfYWxsICkge1xuXHRcdFx0XHRcdGZpcnN0X2l0ZW1bY29udGVudC5uYW1lXSA9IEdsb2JhbC5hbGxfaXRlbTtcblx0XHRcdFx0fSBlbHNlIGlmICggc2V0X2FueSApIHtcblx0XHRcdFx0XHRmaXJzdF9pdGVtW2NvbnRlbnQubmFtZV0gPSBHbG9iYWwuYW55X2l0ZW07XG5cdFx0XHRcdH0gZWxzZSBpZiAoIHNldF9lbXB0eSB8fCBzZXRfc3BlY2lhbF9lbXB0eSApIHtcblxuXHRcdFx0XHRcdGZpcnN0X2l0ZW1bY29udGVudC5uYW1lXSA9IEdsb2JhbC5lbXB0eV9pdGVtO1xuXG5cdFx0XHRcdH0gZWxzZSBpZiAoIHNldF9vcGVuICkge1xuXHRcdFx0XHRcdGZpcnN0X2l0ZW1bY29udGVudC5uYW1lXSA9IEdsb2JhbC5vcGVuX2l0ZW07XG5cdFx0XHRcdH0gZWxzZSBpZiAoIHNldF9kZWZhdWx0ICkge1xuXHRcdFx0XHRcdGZpcnN0X2l0ZW1bY29udGVudC5uYW1lXSA9IEdsb2JhbC5kZWZhdWx0X2l0ZW07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIGN1c3RvbV9maXJzdF9sYWJlbCApIHtcblx0XHRcdFx0XHRmaXJzdF9pdGVtW2NvbnRlbnQubmFtZV0gPSBjdXN0b21fZmlyc3RfbGFiZWw7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9ICk7XG5cblx0XHRcdHJldHVybiBmaXJzdF9pdGVtO1xuXHRcdH07XG5cblx0XHR0aGlzLmNyZWF0ZUZpcnN0SXRlbSA9IGZ1bmN0aW9uKCB0YXJnZXRfZGF0YSApIHtcblxuXHRcdFx0dmFyIG5vX2ZpcnN0X2l0ZW0gPSBmYWxzZTtcblx0XHRcdGlmICggIXRhcmdldF9kYXRhICkge1xuXHRcdFx0XHR0YXJnZXRfZGF0YSA9IHNvdXJjZV9kYXRhO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHRhcmdldF9kYXRhLmhhc093blByb3BlcnR5KCAwICkgKSB7XG5cdFx0XHRcdGlmICggc2V0X2FueSB8fCBzZXRfYWxsICkge1xuXHRcdFx0XHRcdGlmICggdGFyZ2V0X2RhdGFbMF1ba2V5XSA9PT0gVFRVVUlELm5vdF9leGlzdF9pZCApIHtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpZiAoIHRhcmdldF9kYXRhWzBdW2tleV0gPT09IFRUVVVJRC56ZXJvX2lkICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdHZhciBmaXJzdF9pdGVtID0ge307XG5cblx0XHRcdGZpcnN0X2l0ZW1ba2V5XSA9IFRUVVVJRC56ZXJvX2lkO1xuXG5cdFx0XHRpZiAoIHNldF9hbnkgfHwgc2V0X2FsbCB8fCBzZXRfc3BlY2lhbF9lbXB0eSApIHtcblx0XHRcdFx0Zmlyc3RfaXRlbVtrZXldID0gVFRVVUlELm5vdF9leGlzdF9pZDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZpcnN0X2l0ZW1ba2V5XSA9IFRUVVVJRC56ZXJvX2lkO1xuXHRcdFx0fVxuXG5cdFx0XHQkLmVhY2goIGRpc3BsYXlfY29sdW1ucywgZnVuY3Rpb24oIGluZGV4LCBjb250ZW50ICkge1xuXG5cdFx0XHRcdGlmICgga2V5ICE9PSAnaWQnICkge1xuXHRcdFx0XHRcdC8vZmlyc3RfaXRlbS5pZCA9IDk5OTsgLy9yZWNvcmRzIGlkIHN0YXJ0IGZyb20gMTAwMDBcblx0XHRcdFx0XHRmaXJzdF9pdGVtLmlkID0gVFRVVUlELm5vdF9leGlzdF9pZDsgLy9yZWNvcmRzIGlkIHN0YXJ0IGZyb20gMTAwMDBcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIHNldF9hbGwgKSB7XG5cdFx0XHRcdFx0Zmlyc3RfaXRlbVtjb250ZW50Lm5hbWVdID0gR2xvYmFsLmFsbF9pdGVtO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBzZXRfYW55ICkge1xuXHRcdFx0XHRcdGZpcnN0X2l0ZW1bY29udGVudC5uYW1lXSA9IEdsb2JhbC5hbnlfaXRlbTtcblx0XHRcdFx0fSBlbHNlIGlmICggc2V0X2VtcHR5IHx8IHNldF9zcGVjaWFsX2VtcHR5ICkge1xuXHRcdFx0XHRcdGZpcnN0X2l0ZW1bY29udGVudC5uYW1lXSA9IEdsb2JhbC5lbXB0eV9pdGVtO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBzZXRfb3BlbiApIHtcblx0XHRcdFx0XHRmaXJzdF9pdGVtW2NvbnRlbnQubmFtZV0gPSBHbG9iYWwub3Blbl9pdGVtO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBzZXRfZGVmYXVsdCApIHtcblx0XHRcdFx0XHRmaXJzdF9pdGVtW2NvbnRlbnQubmFtZV0gPSBHbG9iYWwuZGVmYXVsdF9pdGVtO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdG5vX2ZpcnN0X2l0ZW0gPSB0cnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBjdXN0b21fZmlyc3RfbGFiZWwgKSB7XG5cdFx0XHRcdFx0Zmlyc3RfaXRlbVtjb250ZW50Lm5hbWVdID0gY3VzdG9tX2ZpcnN0X2xhYmVsO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSApO1xuXG5cdFx0XHRpZiAoICFub19maXJzdF9pdGVtICkge1xuXHRcdFx0XHR0YXJnZXRfZGF0YS51bnNoaWZ0KCBmaXJzdF9pdGVtICk7XG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5jaGVja0lmTGF5b3V0Q2hhbmdlZCA9IGZ1bmN0aW9uKCBuZXdEaXNwbGF5Q29sdW1ucyApIHtcblxuXHRcdFx0aWYgKCAhZGlzcGxheV9jb2x1bW5zICkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCAhbmV3RGlzcGxheUNvbHVtbnMgKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGRpc3BsYXlfY29sdW1ucy5sZW5ndGggIT09IG5ld0Rpc3BsYXlDb2x1bW5zLmxlbmd0aCApIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdHZhciBsZW4gPSBkaXNwbGF5X2NvbHVtbnMubGVuZ3RoO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0dmFyIGRpc3BsYXlfY29sdW1uID0gZGlzcGxheV9jb2x1bW5zW2ldO1xuXHRcdFx0XHR2YXIgZm91bmQgPSBmYWxzZTtcblx0XHRcdFx0Zm9yICggdmFyIGogPSAwOyBqIDwgbGVuOyBqKysgKSB7XG5cdFx0XHRcdFx0dmFyIG5ld19kaXNwbGF5X2NvbHVtbiA9IG5ld0Rpc3BsYXlDb2x1bW5zW2pdO1xuXHRcdFx0XHRcdGlmICggbmV3X2Rpc3BsYXlfY29sdW1uLm5hbWUgPT09IGRpc3BsYXlfY29sdW1uLm5hbWUgKSB7XG5cdFx0XHRcdFx0XHRmb3VuZCA9IHRydWU7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoICFmb3VuZCApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5zZXREZWZhdWx0QXJncyA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHQkdGhpcy5kZWZhdWx0X2FyZ3MgPSB2YWw7XG5cdFx0XHRzZXRfZGVmYXVsdF9hcmdzX21hbnVhbGx5ID0gdHJ1ZTtcblx0XHRcdGRlZmF1bHRfYXJncyA9IHZhbDtcblxuXHRcdH07XG5cblx0XHR0aGlzLnNldERpc1BsYXlDb2x1bW5zID0gZnVuY3Rpb24oIHZhbCApIHtcblxuXHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gR2xvYmFsLmNvbnZlcnRDb2x1bW5zVG9qR3JpZEZvcm1hdCggdmFsLCBsYXlvdXRfbmFtZSApO1xuXHRcdH07XG5cblx0XHQvL09ubHkgdGhlc2UgY29sdW1ucyBjYW4gYmUgc2hvd24gbm8gbWF0dGVyXG5cdFx0dGhpcy5zZXRQb3NzaWJsZURpc3BsYXlDb2x1bW5zID0gZnVuY3Rpb24oIHZhbCwgZGVmYXVsdF9jb2x1bW5zICkge1xuXHRcdFx0cG9zc2libGVfZGlzcGxheV9jb2x1bW5zID0gdmFsO1xuXG5cdFx0XHRpZiAoIGRlZmF1bHRfY29sdW1ucyApIHtcblx0XHRcdFx0bGlzdF92aWV3X2RlZmF1bHRfY29sdW1ucyA9IGRlZmF1bHRfY29sdW1ucztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGxpc3Rfdmlld19kZWZhdWx0X2NvbHVtbnMgPSB2YWw7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggbGF5b3V0X25hbWUgIT09ICdnbG9iYWxfb3B0aW9uX2NvbHVtbicgJiYgLy9TaW1wbGUgb3B0aW9uc1xuXHRcdFx0XHRsYXlvdXRfbmFtZSAhPT0gJ2dsb2JhbF90cmVlX2NvbHVtbicgJiYgLy9UcmVlIE1vZGVcblx0XHRcdFx0bGF5b3V0X25hbWUgIT09ICdnbG9iYWxfc29ydF9jb2x1bW5zJyAmJlxuXHRcdFx0XHRsYXlvdXRfbmFtZSAhPT0gJ2dsb2JhbF90aW1lc2hlZXQnICYmXG5cdFx0XHRcdGxheW91dF9uYW1lICE9PSAnZ2xvYmFsX2Fic2VuY2UnICkge1xuXHRcdFx0XHR0aGlzLmluaXRDb2x1bW5zKCk7XG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRSb3dQZXJQYWdlID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdHJvd19wZXJfcGFnZSA9IHZhbDtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRQYWdlckRhdGEgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0cGFnZXJfZGF0YSA9IHZhbDtcblx0XHR9O1xuXG5cdFx0dGhpcy5zaG91bGRJbml0Q29sdW1ucyA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBsYXlvdXRfbmFtZSA9PT0gJ2dsb2JhbF9vcHRpb25fY29sdW1uJyB8fCAvL1NpbXBsZSBvcHRpb25zXG5cdFx0XHRcdGxheW91dF9uYW1lID09PSAnZ2xvYmFsX3RyZWVfY29sdW1uJyB8fCAvL1RyZWUgTW9kZVxuXHRcdFx0XHRsYXlvdXRfbmFtZSA9PT0gJ2dsb2JhbF9zb3J0X2NvbHVtbnMnIHx8XG5cdFx0XHRcdGxheW91dF9uYW1lID09PSAnZ2xvYmFsX3RpbWVzaGVldCcgfHxcblx0XHRcdFx0bGF5b3V0X25hbWUgPT09ICdnbG9iYWxfYWJzZW5jZScgfHxcblx0XHRcdFx0bGF5b3V0X25hbWUgPT09ICdnbG9iYWxfc2ltcGxlX25hbWUnIHx8XG5cdFx0XHRcdGxheW91dF9uYW1lID09PSAnZ2xvYmFsX3NpbXBsZV9uYW1lJyArICdfbmF2aWdhdGlvbicgKSB7XG5cblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9O1xuXG5cdFx0dGhpcy5jcmVhdGVJdGVtID0gZnVuY3Rpb24oIHZhbCwgbGFiZWwgKSB7XG5cdFx0XHR2YXIgaXRlbSA9IHt9O1xuXG5cdFx0XHRpdGVtW2tleV0gPSB2YWw7XG5cdFx0XHQkLmVhY2goIGRpc3BsYXlfY29sdW1ucywgZnVuY3Rpb24oIGluZGV4LCBjb250ZW50ICkge1xuXG5cdFx0XHRcdGlmICgga2V5ICE9PSAnaWQnICkge1xuXHRcdFx0XHRcdGl0ZW0uaWQgPSAyMDAwMDsgLy9yZWNvcmRzIGlkIHN0YXJ0IGZyb20gMTAwMDBcblx0XHRcdFx0fVxuXHRcdFx0XHRpdGVtW2NvbnRlbnQubmFtZV0gPSBsYWJlbDtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXG5cdFx0XHR9ICk7XG5cblx0XHRcdHJldHVybiBpdGVtO1xuXG5cdFx0fTtcblxuXHRcdHRoaXMuaW5pdFNvdXJjZURhdGEgPSBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBhcmdzID0gJHRoaXMuYnVpbGRVblNlbGVjdEdyaWRGaWx0ZXIoKTtcblx0XHRcdGFwaVsnZ2V0JyArIGN1c3RvbV9rZXlfbmFtZV0oIGFyZ3MsIHtcblx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXN1bHQgKSB7XG5cdFx0XHRcdFx0dmFyIHJlc3VsdF9kYXRhID0gcmVzdWx0LmdldFJlc3VsdCgpO1xuXHRcdFx0XHRcdGlmICggIUdsb2JhbC5pc0FycmF5KCByZXN1bHRfZGF0YSApICkge1xuXHRcdFx0XHRcdFx0cmVzdWx0X2RhdGEgPSBbXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c291cmNlX2RhdGEgPSByZXN1bHRfZGF0YTtcblx0XHRcdFx0XHRwYWdlcl9kYXRhID0gcmVzdWx0LmdldFBhZ2VyRGF0YSgpO1xuXG5cdFx0XHRcdFx0JHRoaXMudHJpZ2dlciggJ2luaXRTb3VyY2VDb21wbGV0ZScsIFskdGhpc10gKTtcblxuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cblx0XHRcdC8vb25seSBkbyB0aGlzIG9uY2Vcblx0XHRcdGluaXRfZGF0YV9pbW1lZGlhdGVseSA9IGZhbHNlO1xuXHRcdH07XG5cblx0XHR0aGlzLmFkZEhpZGVJZENvbHVtbiA9IGZ1bmN0aW9uKCBkaXNwbGF5X2NvbHVtbnMgKSB7XG5cdFx0XHR2YXIgaWRfY29sdW1uID0geyBuYW1lOiAnaWQnLCBpbmRleDogJ2lkJywgbGFiZWw6ICcnLCB3aWR0aDogMCwgaGlkZGVuOiB0cnVlIH07XG5cblx0XHRcdGRpc3BsYXlfY29sdW1ucy5wdXNoKCBpZF9jb2x1bW4gKTtcblxuXHRcdFx0cmV0dXJuIGRpc3BsYXlfY29sdW1ucztcblx0XHR9O1xuXG5cdFx0dmFyIGJ1aWxkU29ydEJ5U2VsZWN0Q29sdW1ucyA9IGZ1bmN0aW9uKCBhcnJheSApIHtcblx0XHRcdHZhciBzb3J0X2J5X2FycmF5ID0gYXJyYXk7XG5cdFx0XHR2YXIgc29ydF9ieV9zZWxlY3RfY29sdW1ucyA9IFtdO1xuXHRcdFx0dmFyIHNvcnRfYnlfdW5zZWxlY3RfY29sdW1ucyA9IHNvdXJjZV9kYXRhO1xuXG5cdFx0XHRpZiAoIHNvcnRfYnlfYXJyYXkgKSB7XG5cdFx0XHRcdCQuZWFjaCggc29ydF9ieV9hcnJheSwgZnVuY3Rpb24oIGluZGV4LCBjb250ZW50ICkge1xuXHRcdFx0XHRcdGZvciAoIHZhciBrZXkgaW4gY29udGVudCApIHtcblx0XHRcdFx0XHRcdGlmICgga2V5ID09PSAnbGFiZWwnIHx8IGtleSA9PT0gJ3ZhbHVlJyB8fCBrZXkgPT09ICdmdWxsVmFsdWUnICkge1xuXHRcdFx0XHRcdFx0XHRzb3J0X2J5X3NlbGVjdF9jb2x1bW5zID0gc29ydF9ieV9hcnJheTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0JC5lYWNoKCBzb3J0X2J5X3Vuc2VsZWN0X2NvbHVtbnMsIGZ1bmN0aW9uKCBpbmRleDEsIGNvbnRlbnQxICkge1xuXHRcdFx0XHRcdFx0XHRpZiAoIGNvbnRlbnQxLnZhbHVlID09PSBrZXkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29udGVudDEuc29ydCA9IGNvbnRlbnRba2V5XTtcblx0XHRcdFx0XHRcdFx0XHRzb3J0X2J5X3NlbGVjdF9jb2x1bW5zLnB1c2goIGNvbnRlbnQxICk7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBzb3J0X2J5X3NlbGVjdF9jb2x1bW5zO1xuXG5cdFx0fTtcblxuXHRcdC8vRm9yIG11bHRpcGxlIGl0ZW1zIGxpa2UgLnh4eCBjb3VsZCBjb250YWlucyBhIGZldyB3aWRnZXRzLlxuXHRcdHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbyA9ICQubWV0YSA/ICQuZXh0ZW5kKCB7fSwgb3B0cywgJCggdGhpcyApLmRhdGEoKSApIDogb3B0cztcblx0XHRcdGxhYmVsX3NwYW4gPSAkKCB0aGlzICkuZmluZCggJy5hLWNvbWJvYm94LWxhYmVsJyApO1xuXHRcdFx0dmFyIGZvY3VzX2lucHV0ID0gJCggdGhpcyApLmZpbmQoICcuZm9jdXMtaW5wdXQnICk7XG5cblx0XHRcdGlmICggby5hbHdheXNfaW5jbHVkZV9jb2x1bW5zICkge1xuXHRcdFx0XHRhbHdheXNfaW5jbHVkZV9jb2x1bW5zID0gby5hbHdheXNfaW5jbHVkZV9jb2x1bW5zO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8uZXh0ZW5kRGF0YVByb2Nlc3NXaGVuU2VhcmNoICkge1xuXHRcdFx0XHRleHRlbmREYXRhUHJvY2Vzc1doZW5TZWFyY2ggPSBvLmV4dGVuZERhdGFQcm9jZXNzV2hlblNlYXJjaDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLmFsd2F5c19zZWFyY2hfZnVsbF9jb2x1bW5zICkge1xuXHRcdFx0XHRhbHdheXNfc2VhcmNoX2Z1bGxfY29sdW1ucyA9IG8uYWx3YXlzX3NlYXJjaF9mdWxsX2NvbHVtbnM7XG5cdFx0XHR9XG5cblx0XHRcdC8vc291cmNlX2RhdGEgaWQgdGhhdCBhZGQgZnJvbSBvdXRzaXRlLCB1c2VkIHRvIHNldCB2YWx1ZSBiZWZvcmUgb3BlbiBhd2Vzb21lYm94XG5cdFx0XHRpZiAoIG8uYWRkZWRfaXRlbXMgKSB7XG5cdFx0XHRcdGFkZGVkX2l0ZW1zID0gby5hZGRlZF9pdGVtcztcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLmluaXRfZGF0YV9pbW1lZGlhdGVseSApIHtcblx0XHRcdFx0aW5pdF9kYXRhX2ltbWVkaWF0ZWx5ID0gby5pbml0X2RhdGFfaW1tZWRpYXRlbHk7XG5cdFx0XHR9XG5cblx0XHRcdC8vZmlyc3QgaXRlbSBsYWJlbCAsIGxpa2UgLS0gTm8gTWVhbCAtLSBpbiBQb2xpY3kgLT4gU2NoZWR1bGUgUG9saWNpZXNcblx0XHRcdGlmICggby5jdXN0b21fZmlyc3RfbGFiZWwgKSB7XG5cdFx0XHRcdGN1c3RvbV9maXJzdF9sYWJlbCA9IG8uY3VzdG9tX2ZpcnN0X2xhYmVsO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8uc2NyaXB0X25hbWUgKSB7XG5cdFx0XHRcdHNjcmlwdF9uYW1lID0gby5zY3JpcHRfbmFtZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLmdldF9yZWFsX2RhdGFfb25fbXVsdGkgKSB7XG5cdFx0XHRcdGdldF9yZWFsX2RhdGFfb25fbXVsdGkgPSBvLmdldF9yZWFsX2RhdGFfb25fbXVsdGk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggby5zZXRSZWFsVmFsdWVDYWxsQmFjayApIHtcblx0XHRcdFx0c2V0UmVhbFZhbHVlQ2FsbEJhY2sgPSBvLnNldFJlYWxWYWx1ZUNhbGxCYWNrO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8ubmF2aWdhdGlvbl9tb2RlICkge1xuXHRcdFx0XHRuYXZpZ2F0aW9uX21vZGUgPSBvLm5hdmlnYXRpb25fbW9kZTtcblx0XHRcdFx0JCggdGhpcyApLmNoaWxkcmVuKCkuZXEoIDEgKS5jc3MoICdtYXgtd2lkdGgnLCAxMzIgKTtcblx0XHRcdFx0JCggdGhpcyApLmNoaWxkcmVuKCkuZXEoIDEgKS5jc3MoICdtaW4td2lkdGgnLCAxMzIgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLnNlYXJjaF9wYW5lbF9tb2RlbCApIHtcblx0XHRcdFx0JCggdGhpcyApLmNoaWxkcmVuKCkuZXEoIDEgKS5jc3MoICdtYXgtd2lkdGgnLCAxMzIgKTtcblx0XHRcdFx0JCggdGhpcyApLmNoaWxkcmVuKCkuZXEoIDEgKS5jc3MoICdtaW4td2lkdGgnLCAxMzIgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLndpZHRoICkge1xuXHRcdFx0XHQkKCB0aGlzICkuY2hpbGRyZW4oKS5lcSggMSApLmNzcyggJ21heC13aWR0aCcsIG8ud2lkdGggKTtcblx0XHRcdFx0aWYgKCBvLmlzX3N0YXRpY193aWR0aCApIHtcblx0XHRcdFx0XHQkKCB0aGlzICkuY2hpbGRyZW4oKS5lcSggMSApLmNzcyggJ21pbi13aWR0aCcsIG8ud2lkdGggKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0JCggdGhpcyApLmNoaWxkcmVuKCkuZXEoIDEgKS5jc3MoICdtaW4td2lkdGgnLCAxMzIgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLmFwaV9jbGFzcyApIHtcblx0XHRcdFx0YXBpX2NsYXNzID0gby5hcGlfY2xhc3M7XG5cdFx0XHRcdGFwaSA9IG8uYXBpX2NsYXNzO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8uY3VzdG9tX2tleV9uYW1lICkge1xuXHRcdFx0XHRjdXN0b21fa2V5X25hbWUgPSBvLmN1c3RvbV9rZXlfbmFtZTtcblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0aWYgKCBhcGkgKSB7XG5cdFx0XHRcdFx0Y3VzdG9tX2tleV9uYW1lID0gYXBpLmtleV9uYW1lO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICggby5hbGxvd19tdWx0aXBsZV9zZWxlY3Rpb24gKSB7XG5cdFx0XHRcdGFsbG93X211bHRpcGxlX3NlbGVjdGlvbiA9IG8uYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8uc2V0X2FueSApIHtcblx0XHRcdFx0c2V0X2FueSA9IG8uc2V0X2FueTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLnNldF9lbXB0eSApIHtcblx0XHRcdFx0c2V0X2VtcHR5ID0gby5zZXRfZW1wdHk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggby5zZXRfc3BlY2lhbF9lbXB0eSApIHtcblx0XHRcdFx0c2V0X3NwZWNpYWxfZW1wdHkgPSBvLnNldF9zcGVjaWFsX2VtcHR5O1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8uc2V0X29wZW4gKSB7XG5cdFx0XHRcdHNldF9vcGVuID0gby5zZXRfb3Blbjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLnNldF9kZWZhdWx0ICkge1xuXHRcdFx0XHRzZXRfZGVmYXVsdCA9IG8uc2V0X2RlZmF1bHQ7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggby5zZXRfYWxsICkge1xuXHRcdFx0XHRzZXRfYWxsID0gby5zZXRfYWxsO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8uYWRkaXRpb25fc291cmNlX2Z1bmN0aW9uICkge1xuXHRcdFx0XHRhZGRpdGlvbl9zb3VyY2VfZnVuY3Rpb24gPSBvLmFkZGl0aW9uX3NvdXJjZV9mdW5jdGlvbjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLmNvbHVtbl9vcHRpb25fa2V5ICkge1xuXHRcdFx0XHRjb2x1bW5fb3B0aW9uX2tleSA9IG8uY29sdW1uX29wdGlvbl9rZXk7XG5cdFx0XHR9XG5cblx0XHRcdGZpZWxkID0gby5maWVsZDtcblxuXHRcdFx0aWYgKCBvLnZhbGlkYXRpb25fZmllbGQgKSB7XG5cdFx0XHRcdHZhbGlkYXRpb25fZmllbGQgPSBvLnZhbGlkYXRpb25fZmllbGQ7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggby5sYXlvdXRfbmFtZSApIHtcblx0XHRcdFx0aWYgKCBuYXZpZ2F0aW9uX21vZGUgKSB7XG5cdFx0XHRcdFx0bGF5b3V0X25hbWUgPSBvLmxheW91dF9uYW1lICsgJ19uYXZpZ2F0aW9uJztcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRsYXlvdXRfbmFtZSA9IG8ubGF5b3V0X25hbWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8uaGFzT3duUHJvcGVydHkoICdzaG93X3NlYXJjaF9pbnB1dHMnICkgKSB7XG5cdFx0XHRcdHNob3dfc2VhcmNoX2lucHV0cyA9IG8uc2hvd19zZWFyY2hfaW5wdXRzO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8udHJlZV9tb2RlICkge1xuXHRcdFx0XHR0cmVlX21vZGUgPSBvLnRyZWVfbW9kZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLm9uX3RyZWVfZ3JpZF9yb3dfc2VsZWN0ICkge1xuXHRcdFx0XHRvbl90cmVlX2dyaWRfcm93X3NlbGVjdCA9IG8ub25fdHJlZV9ncmlkX3Jvd19zZWxlY3Q7XG5cdFx0XHR9XG5cblx0XHRcdC8vQWx3YXlzIHNldCB0aGlzIHRydWU7XG5cdFx0XHRhbGxvd19kcmFnX3RvX29yZGVyID0gdHJ1ZTtcblxuXHRcdFx0aWYgKCBvLmtleSApIHtcblx0XHRcdFx0a2V5ID0gby5rZXk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggby5hcmdzICkge1xuXHRcdFx0XHQkdGhpcy5hcmdzID0gby5hcmdzO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8uY3VzdG9tU2VhcmNoRmlsdGVyICkge1xuXHRcdFx0XHQkdGhpcy5jdXN0b21TZWFyY2hGaWx0ZXIgPSBvLmN1c3RvbVNlYXJjaEZpbHRlcjtcblx0XHRcdH1cblxuXHRcdFx0Ly9TZXQgZGVmYXVsdCBhcmdzIHVzZSB3aGVuIGluaXQgc291cmNlO1xuXHRcdFx0aWYgKCBvLmRlZmF1bHRfYXJncyApIHtcblx0XHRcdFx0JHRoaXMuc2V0RGVmYXVsdEFyZ3MoIG8uZGVmYXVsdF9hcmdzICk7XG5cdFx0XHR9XG5cblx0XHRcdHZhciAkJHRoaXMgPSB0aGlzO1xuXHRcdFx0Zm9jdXNfaW5wdXQudW5iaW5kKCAna2V5ZG93bicgKS5iaW5kKCAna2V5ZG93bicsIGZ1bmN0aW9uKCBlICkge1xuXHRcdFx0XHQvL1N0b3AgY2xpY2sgZXZlbnQgdG8gdG9wLCBwcmV2ZW50IHRoZSBib2R5IGNsaWNrIGV2ZW50XG5cdFx0XHRcdGlmICggZS5rZXlDb2RlID09PSAxMyB8fCBlLmtleUNvZGUgPT09IDMyICkge1xuXHRcdFx0XHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG5cdFx0XHRcdFx0VFRQcm9taXNlLmFkZCggJ0FDb21ib0JveCcsICdpbml0JyApO1xuXHRcdFx0XHRcdG9wZW5BRHJvcERvd24oKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXG5cdFx0XHRmb2N1c19pbnB1dC5iaW5kKCAnZm9jdXNpbicsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQkKCAkJHRoaXMgKS5hZGRDbGFzcyggJ2ZvY3VzJyApO1xuXHRcdFx0fSApO1xuXG5cdFx0XHRmb2N1c19pbnB1dC5iaW5kKCAnZm9jdXNvdXQnLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0JCggJCR0aGlzICkucmVtb3ZlQ2xhc3MoICdmb2N1cycgKTtcblx0XHRcdH0gKTtcblxuXHRcdFx0JCggdGhpcyApLmNsaWNrKCBmdW5jdGlvbiggZSApIHtcblx0XHRcdFx0ZS5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0aWYgKCAhZW5hYmxlZCApIHtcblx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9zdWJfY29udHJvbGxlciAmJlxuXHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyLmVkaXRfdmlldyAmJlxuXHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyLmlzX3ZpZXdpbmcgKSB7XG5cdFx0XHRcdFx0XHRlcnJvcl9zdHJpbmcgPSBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fc3ViX2NvbnRyb2xsZXIuZ2V0Vmlld01vZGVFcnJvck1lc3NhZ2UoKTtcblx0XHRcdFx0XHRcdCR0aGlzLnNob3dFcnJvclRpcCggMTAgKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICYmXG5cdFx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmVkaXRfdmlldyAmJlxuXHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5pc192aWV3aW5nICkge1xuXHRcdFx0XHRcdFx0ZXJyb3Jfc3RyaW5nID0gTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5nZXRWaWV3TW9kZUVycm9yTWVzc2FnZSgpO1xuXHRcdFx0XHRcdFx0JHRoaXMuc2hvd0Vycm9yVGlwKCAxMCApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGlmICggZG9udE9wZW4gPT09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFRUUHJvbWlzZS5hZGQoICdBQ29tYm9Cb3gnLCAnaW5pdCcgKTtcblx0XHRcdFx0XHRvcGVuQURyb3BEb3duKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblxuXHRcdFx0JCggdGhpcyApLm1vdXNlb3ZlciggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggZW5hYmxlZCApIHtcblx0XHRcdFx0XHRpZiAoIGVycm9yX3N0cmluZyAmJiBlcnJvcl9zdHJpbmcubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHRcdCR0aGlzLnNob3dFcnJvclRpcCggMTAwMCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXG5cdFx0XHQkKCB0aGlzICkubW91c2VvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQkdGhpcy5oaWRlRXJyb3JUaXAoKTtcblx0XHRcdH0gKTtcblxuXHRcdFx0aWYgKCAhby53aWR0aCApIHtcblx0XHRcdFx0JCggdGhpcyApLmNzcyggJ21pbi13aWR0aCcsICcxNjlweCcgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdCQoIHRoaXMgKS5jc3MoICdtaW4td2lkdGgnLCAoIG8ud2lkdGggKyAzMyApICsgJ3B4JyApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoICEkdGhpcy5zaG91bGRJbml0Q29sdW1ucygpICkgeyAvL1NvcnQgU2VsZWN0b3IgaW4gc2VhcmNoIHBhbmVsXG5cdFx0XHRcdGRvX25vdF9nZXRfcmVhbF9kYXRhID0gdHJ1ZTsgLy8gRm9yIFNpbXBsZSBPUFRJT05TIG1vZGVcblxuXHRcdFx0fVxuXG5cdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBBTGF5b3V0Q2FjaGUuZ2V0RGVmYXVsdENvbHVtbiggbGF5b3V0X25hbWUgKTsgLy9HZXQgRGVmYXVsdCBjb2x1bW5zIGJhc2Ugb24gZGlmZmVyZW50IGxheW91dCBuYW1lXG5cdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBHbG9iYWwuY29udmVydENvbHVtbnNUb2pHcmlkRm9ybWF0KCBkaXNwbGF5X2NvbHVtbnMsIGxheW91dF9uYW1lICk7IC8vQ29udmVydCB0byBqUWdyaWQgZm9ybWF0XG5cblx0XHRcdGlmICggJHRoaXMuc2hvdWxkSW5pdENvbHVtbnMoKSAmJiAhbmF2aWdhdGlvbl9tb2RlICkgeyAvL1NvcnQgU2VsZWN0b3IgaW4gc2VhcmNoIHBhbmVsXG5cblx0XHRcdFx0Ly9pbml0IGNvbHVtbmQgd2hlbiBzZXQgcG9zc2libGUgY29sdW1ucyBmb3IgbmF2aWdhdGlvbiBtb2RlXG5cdFx0XHRcdCR0aGlzLmluaXRDb2x1bW5zKCk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggby5pZCApIHtcblx0XHRcdFx0JCggdGhpcyApLmF0dHIoICdpZCcsIG8uaWQgKyAnX0FDb21ib0JveCcgKTtcblx0XHRcdFx0aWQgPSBvLmlkO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0JCggdGhpcyApLmF0dHIoICdpZCcsIGZpZWxkICsgJ19BQ29tYm9Cb3gnICk7XG5cdFx0XHRcdGlkID0gby5maWVsZDtcblx0XHRcdH1cblxuXHRcdFx0JHRoaXMuc2V0RW1wdHlMYWJlbCgpO1xuXG5cdFx0XHQvL09wZW4gQURyb3BEb3duXG5cdFx0XHRmdW5jdGlvbiBzZXRBRHJvcERvd25TZWxlY3RWYWx1ZXMoIHNlbGVjdF9pdGVtcyApIHtcblx0XHRcdFx0aWYgKCAhKCBzZXRfYW55ICYmIHNlbGVjdF9pdGVtcyA9PSBUVFVVSUQubm90X2V4aXN0X2lkICkgKSB7XG5cdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRTZWxlY3RHcmlkRGF0YSggc2VsZWN0X2l0ZW1zICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0ZnVuY3Rpb24gb3BlbkFEcm9wRG93bigpIHtcblx0XHRcdFx0aWYgKCAhZW5hYmxlZCApIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLm9wZW5Bd2Vzb21lQm94ICkge1xuXHRcdFx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEub3BlbkF3ZXNvbWVCb3guZ2V0SWQoKSA9PT0gaWQgKSB7XG5cdFx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5vcGVuQXdlc29tZUJveC5vbkNsb3NlKCk7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLm9wZW5Bd2Vzb21lQm94Lm9uQ2xvc2UoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRMb2NhbENhY2hlRGF0YS5vcGVuQXdlc29tZUJveCA9ICR0aGlzO1xuXG5cdFx0XHRcdC8vQ3JlYXRlIGFuZCBvcGVuIEFEcm9wRG93blxuXHRcdFx0XHRhX2Ryb3Bkb3duID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5BV0VTT01FX0RST1BET1dOICk7XG5cblx0XHRcdFx0dmFyIGRpc3BsYXlfc2hvd19hbGwgPSBmYWxzZTtcblx0XHRcdFx0aWYgKCAkdGhpcy5zaG91bGRJbml0Q29sdW1ucygpICYmICFuYXZpZ2F0aW9uX21vZGUgKSB7XG5cdFx0XHRcdFx0ZGlzcGxheV9zaG93X2FsbCA9IHRydWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIG5hdmlnYXRpb25fbW9kZSAmJiBkZWZhdWx0X2FyZ3MgJiYgZGVmYXVsdF9hcmdzLmZpbHRlcl9zb3J0ICYmICFjYWNoZWRfc29ydF9maWx0ZXIgKSB7XG5cdFx0XHRcdFx0Y2FjaGVkX3NvcnRfZmlsdGVyID0gZGVmYXVsdF9hcmdzLmZpbHRlcl9zb3J0O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly9DcmVhdGUgQURyb3BEb3duXG5cdFx0XHRcdGFfZHJvcGRvd24gPSBhX2Ryb3Bkb3duLkFEcm9wRG93bigge1xuXHRcdFx0XHRcdGRpc3BsYXlfc2hvd19hbGw6IGRpc3BsYXlfc2hvd19hbGwsXG5cdFx0XHRcdFx0YWxsb3dfZHJhZ190b19vcmRlcjogYWxsb3dfZHJhZ190b19vcmRlcixcblx0XHRcdFx0XHRhbGxvd19tdWx0aXBsZV9zZWxlY3Rpb246IGFsbG93X211bHRpcGxlX3NlbGVjdGlvbixcblx0XHRcdFx0XHRzaG93X2FsbDogc2hvd19hbGwsXG5cdFx0XHRcdFx0a2V5OiBrZXksXG5cdFx0XHRcdFx0aWQ6IGlkLFxuXHRcdFx0XHRcdGNvbWJvQm94OiAkdGhpcyxcblx0XHRcdFx0XHRzaG93X3NlYXJjaF9pbnB1dHM6IHNob3dfc2VhcmNoX2lucHV0cyxcblx0XHRcdFx0XHRzZWFyY2hfaW5wdXRfZmlsdGVyOiBjYWNoZWRfc2VhcmNoX2lucHV0c19maWx0ZXIsXG5cdFx0XHRcdFx0c2VsZWN0X2dyaWRfc2VhcmNoX2lucHV0X2ZpbHRlcjogY2FjaGVkX3NlbGVjdF9ncmlkX3NlYXJjaF9pbnB1dHNfZmlsdGVyLFxuXHRcdFx0XHRcdGRlZmF1bHRfc29ydF9maWx0ZXI6IGNhY2hlZF9zb3J0X2ZpbHRlcixcblx0XHRcdFx0XHRkZWZhdWx0X3NlbGVjdF9ncmlkX3NvcnRfZmlsdGVyOiBjYWNoZWRfc2VsZWN0ZWRfZ3JpZF9zb3J0X2ZpbHRlcixcblx0XHRcdFx0XHR0cmVlX21vZGU6IHRyZWVfbW9kZSxcblx0XHRcdFx0XHRjb2x1bW5fb3B0aW9uX2tleTogY29sdW1uX29wdGlvbl9rZXksXG5cdFx0XHRcdFx0YXBpOiBhcGksXG5cdFx0XHRcdFx0ZGlzcGxheV9jb2x1bW5fc2V0dGluZ3M6ICR0aGlzLnNob3VsZEluaXRDb2x1bW5zKCksXG5cblx0XHRcdFx0XHRvbl90cmVlX2dyaWRfcm93X3NlbGVjdDogb25fdHJlZV9ncmlkX3Jvd19zZWxlY3Rcblx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdGFfZHJvcGRvd25fZGl2ID0gJCggJzxkaXYgaWQ9XFwnJyArIGlkICsgJ2FfZHJvcGRvd25fZGl2XFwnIGNsYXNzPVxcJ2EtZHJvcGRvd24tZGl2XFwnPjwvZGl2PicgKTtcblxuXHRcdFx0XHRhX2Ryb3Bkb3duX2Rpdi5hcHBlbmQoIGFfZHJvcGRvd24gKTtcblxuXHRcdFx0XHRhX2Ryb3Bkb3duX2Rpdi5tb3VzZWVudGVyKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRpc19tb3VzZV9vdmVyID0gdHJ1ZTtcblx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdGFfZHJvcGRvd25fZGl2Lm1vdXNlbGVhdmUoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGlzX21vdXNlX292ZXIgPSBmYWxzZTtcblx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdCQoICdib2R5JyApLmFwcGVuZCggYV9kcm9wZG93bl9kaXYgKTtcblxuXHRcdFx0XHRUVFByb21pc2Uud2FpdCggJ0FDb21ib0JveCcsICdpbml0JywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRHcmlkQ29sdW1uc1dpZHRocygpO1xuXG5cdFx0XHRcdFx0Ly9NYWtlIHN1cmUgd2UgZG9uJ3QgcnVuIHRoaXMgQVBJIGNhbGwgaWYgdGhlIG9ubHkgc2VsZWN0ZWQgdmFsdWUgaXMgYSB6ZXJvL25vdCBleGlzdHMgVVVJRCxcblx0XHRcdFx0XHQvLyBvdGhlcndpc2UgaXQgY2F1c2VzIGNvbXBhbmllcyB3aXRoIHRob3VzYW5kcyBvZiBlbXBsb3llZXMgdG8gcmV0dXJuICphbGwqIGVtcGxveWVlcy5cblx0XHRcdFx0XHRpZiAoIGFsbG93X211bHRpcGxlX3NlbGVjdGlvbiA9PSB0cnVlICYmICggJHRoaXMuZ2V0VmFsdWUoKS5sZW5ndGggPiAxIHx8ICggJHRoaXMuZ2V0VmFsdWUoKS5sZW5ndGggPT0gMSAmJiAkdGhpcy5nZXRWYWx1ZSgpWzBdICYmICggJHRoaXMuZ2V0VmFsdWUoKVswXSAhPSBUVFVVSUQuemVyb19pZCAmJiAkdGhpcy5nZXRWYWx1ZSgpWzBdICE9IFRUVVVJRC5ub3RfZXhpc3RfaWQgKSApICkgJiYgYXBpICkge1xuXHRcdFx0XHRcdFx0dmFyIGFyZ3MgPSB7fTtcblx0XHRcdFx0XHRcdGFyZ3MuZmlsdGVyX2RhdGEgPSB7IGlkOiAkdGhpcy5nZXRWYWx1ZSgpIH07XG5cdFx0XHRcdFx0XHRhcmdzLmZpbHRlcl9jb2x1bW5zID0gJHRoaXMuZ2V0Q29sdW1uRmlsdGVyKCk7XG5cdFx0XHRcdFx0XHRhcmdzLmZpbHRlcl9pdGVtc19wZXJfcGFnZSA9IDEwMDAwO1xuXG5cdFx0XHRcdFx0XHRhcGlbJ2dldCcgKyBjdXN0b21fa2V5X25hbWVdKCBhcmdzLCB7XG5cdFx0XHRcdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdFx0XHRcdFx0XHRcdGRvTmV4dCggcmVzdWx0ICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0ZG9OZXh0KCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0ZnVuY3Rpb24gZG9OZXh0KCByZXN1bHQgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIHJlc3VsdCApIHtcblx0XHRcdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRSZWFsU2VsZWN0SXRlbXMoIHJlc3VsdC5nZXRSZXN1bHQoKSwgJHRoaXMuZ2V0VmFsdWUoKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0YV9kcm9wZG93bl9kaXYuY3NzKCAnb3BhY2l0eScsICcxJyApO1xuXG5cdFx0XHRcdFx0XHQvLyMyMzUzIC0gcmVtb3ZlIHRoZSByaWdodCBzaWRlIGJvcmRlciBmcm9tIGpxZ3JpZC5cblx0XHRcdFx0XHRcdHZhciB0YWJsZXMgPSAkdGhpcy5maW5kKCAnLnVpLWpxZ3JpZCcgKS5maW5kKCAndGFibGUnICk7XG5cdFx0XHRcdFx0XHRpZiAoIHRhYmxlcy5sZW5ndGggPiAwICkge1xuXHRcdFx0XHRcdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCB0YWJsZXMubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly9yZXNpemUgYXdlc29tZWJveCBncmlkIHRhYmxlcyB0byByZW1vdmUgcmlnaHQtc2l6ZSBnYXAuXG5cdFx0XHRcdFx0XHRcdFx0dmFyIHdpZHRoID0gJCggdGFibGVzWzBdICkucGFyZW50cyggJy51aS1qcWdyaWQnICkuZmluZCggJy51aS1qcWdyaWQtYmRpdicgKS53aWR0aCgpIC0gMTE7XG5cdFx0XHRcdFx0XHRcdFx0JCggdGFibGVzWzBdICkucGFyZW50cyggJy51aS1qcWdyaWQnICkuZmluZCggJy51aS1qcWdyaWQtdmlldycgKS53aWR0aCggd2lkdGggKTtcblx0XHRcdFx0XHRcdFx0XHQkKCB0YWJsZXNbaV0gKS53aWR0aCggd2lkdGggKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLnNldFVuU2VsZWN0R3JpZERyYWdBYmxlKCk7XG5cdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLnNldFNlbGVjdEdyaWREcmFnQWJsZSgpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9ICk7XG5cblx0XHRcdFx0YV9kcm9wZG93bi5iaW5kKCAnY2xvc2UnLCAkdGhpcy5vbkNsb3NlICk7XG5cblx0XHRcdFx0dmFyIGxheW91dCA9IEFMYXlvdXRDYWNoZS5sYXlvdXRfZGljW2xheW91dF9uYW1lXTtcblxuXHRcdFx0XHQvL0Fsd2F5cyB1c2UgY29sdW1ucyBmcm9tIGdsb2JhbCBjYWNoZSBpZiBjb2x1bW5zIGlzIG5vdCBkZWZhdWx0XG5cdFx0XHRcdGlmICggbGF5b3V0X25hbWUgJiYgbGF5b3V0ICYmIEdsb2JhbC5pc1NldCggbGF5b3V0LmRhdGEgKSApIHtcblxuXHRcdFx0XHRcdHZhciBjdXJyZW50X2Rpc3BsYXlfY29sdW1ucyA9IGxheW91dC5kYXRhLmRpc3BsYXlfY29sdW1ucztcblxuXHRcdFx0XHRcdC8vSGFwcGVuIHdoZW4gc2F2ZSBubyBjb2x1bW5zIGluIGNvbHVtbiBzZXR0aW5nIGZvciBuYXZpZ2F0aW9uIG1vZGVcblx0XHRcdFx0XHRpZiAoIGN1cnJlbnRfZGlzcGxheV9jb2x1bW5zLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRcdFx0XHQvL09ubHkgY2hlY2sgcG9zc2libGUgY29sdW1ucyBpZiBhbnlcblx0XHRcdFx0XHRcdGlmICggcG9zc2libGVfZGlzcGxheV9jb2x1bW5zICkge1xuXHRcdFx0XHRcdFx0XHRjdXJyZW50X2Rpc3BsYXlfY29sdW1ucyA9IGZpbHRlckJhc2VPblBvc3NpYmxlQ29sdW1ucyggY3VycmVudF9kaXNwbGF5X2NvbHVtbnMgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRpZiAoIGxpc3Rfdmlld19kZWZhdWx0X2NvbHVtbnMgKSB7XG5cdFx0XHRcdFx0XHRcdGN1cnJlbnRfZGlzcGxheV9jb2x1bW5zID0gbGlzdF92aWV3X2RlZmF1bHRfY29sdW1ucztcblx0XHRcdFx0XHRcdFx0Y3VycmVudF9kaXNwbGF5X2NvbHVtbnMgPSBmaWx0ZXJCYXNlT25Qb3NzaWJsZUNvbHVtbnMoIGN1cnJlbnRfZGlzcGxheV9jb2x1bW5zICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Y3VycmVudF9kaXNwbGF5X2NvbHVtbnMgPSBHbG9iYWwuY29udmVydENvbHVtbnNUb2pHcmlkRm9ybWF0KCBjdXJyZW50X2Rpc3BsYXlfY29sdW1ucywgbGF5b3V0X25hbWUgKTtcblxuXHRcdFx0XHRcdHZhciBjdXJyZW50X3Jvd19wZXJfcGFnZSA9IGxheW91dC5kYXRhLnJvd19wZXJfcGFnZTtcblxuXHRcdFx0XHRcdC8vSWYgY3VycmVudCBjb2x1bW5zIG9yIHJvd19wZXJfcGFnZSBub3Qgc2FtZSBhcyBzYXZlZCBsYXlvdXQuIFJlbG9hZCBkYXRhIGJhc2Ugb24gY3VycmVudCBzZXR0aW5nXG5cdFx0XHRcdFx0aWYgKCAkdGhpcy5jaGVja0lmTGF5b3V0Q2hhbmdlZCggY3VycmVudF9kaXNwbGF5X2NvbHVtbnMgKSB8fCAoIHJvd19wZXJfcGFnZSAhPT0gY3VycmVudF9yb3dfcGVyX3BhZ2UgJiYgIW5hdmlnYXRpb25fbW9kZSApICkge1xuXG5cdFx0XHRcdFx0XHRkaXNwbGF5X2NvbHVtbnMgPSBjdXJyZW50X2Rpc3BsYXlfY29sdW1ucztcblx0XHRcdFx0XHRcdHNvdXJjZV9kYXRhID0gbnVsbDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoICFuYXZpZ2F0aW9uX21vZGUgKSB7XG5cdFx0XHRcdFx0XHRyb3dfcGVyX3BhZ2UgPSBjdXJyZW50X3Jvd19wZXJfcGFnZTtcblxuXHRcdFx0XHRcdFx0aWYgKCAhc2V0X2RlZmF1bHRfYXJnc19tYW51YWxseSApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGxheW91dC5kYXRhLnR5cGUgKSAmJiBsYXlvdXQuZGF0YS50eXBlID09PSAxMCApIHtcblx0XHRcdFx0XHRcdFx0XHR2YXIgZGVmYXVsdF9hcmdzID0ge307XG5cdFx0XHRcdFx0XHRcdFx0ZGVmYXVsdF9hcmdzLmZpbHRlcl9kYXRhID0gbGF5b3V0LmRhdGEuZmlsdGVyX2RhdGE7XG5cdFx0XHRcdFx0XHRcdFx0ZGVmYXVsdF9hcmdzLmZpbHRlcl9zb3J0ID0gbGF5b3V0LmRhdGEuZmlsdGVyX3NvcnQ7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0ZGVmYXVsdF9hcmdzID0gbnVsbDtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvL1NldCBjb2x1bW5zIGZpcnN0XG5cdFx0XHRcdGFfZHJvcGRvd24uc2V0Q29sdW1ucyggZGlzcGxheV9jb2x1bW5zICk7XG5cblx0XHRcdFx0Ly9TZXQgRHJvcERvd24gcG9zaXRpb25cblx0XHRcdFx0Ly91c2UgZGVmYXVsdCB3aXRoIHNpbmNlIC53aWR0aCgpICBub3QgcmV0dXJuIGNvcnJlY3Qgd2lkdGggd2hlbiBmaXJzdCBvcGVuXG5cblx0XHRcdFx0dmFyIGRyb3Bkb3duX3dpZHRoID0gYV9kcm9wZG93bi5nZXRCb3hXaWR0aCgpO1xuXG5cdFx0XHRcdGlmICggYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uICkge1xuXHRcdFx0XHRcdGRyb3Bkb3duX3dpZHRoID0gZHJvcGRvd25fd2lkdGggKiAyICsgMzAgKyAxNTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggKCBkcm9wZG93bl93aWR0aCArICQoICR0aGlzICkub2Zmc2V0KCkubGVmdCArIDUwICkgPiBHbG9iYWwuYm9keVdpZHRoKCkgKSB7XG5cdFx0XHRcdFx0YV9kcm9wZG93bl9kaXYuY3NzKCAnbGVmdCcsICggR2xvYmFsLmJvZHlXaWR0aCgpIC0gZHJvcGRvd25fd2lkdGggLSA1MCApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0YV9kcm9wZG93bl9kaXYuY3NzKCAnbGVmdCcsICQoICR0aGlzICkub2Zmc2V0KCkubGVmdCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gbWFrZXMgc3VyZSBpdCBzaG93biBvbiB0aGUgc2NyZWVuLCB3aWxsIGNhbGN1bHRlIHBvc2l0aW9uIGFmdGVyIHNvdXJjZSBzZXR0aW5nXG5cdFx0XHRcdGlmICggKCAkKCAkdGhpcyApLm9mZnNldCgpLnRvcCArIDI1ICsgMjc1ICkgPCBHbG9iYWwuYm9keUhlaWdodCgpICkge1xuXHRcdFx0XHRcdGFfZHJvcGRvd25fZGl2LmNzcyggJ3RvcCcsICggJCggJHRoaXMgKS5vZmZzZXQoKS50b3AgKyAyNSApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0YV9kcm9wZG93bl9kaXYuY3NzKCAndG9wJywgKCAkKCAkdGhpcyApLm9mZnNldCgpLnRvcCAtIDI3NSApICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBUaGlzIHdpbGwgbmV2ZXIgY2hhbmdlIHdoZW4gc2VhcmNoIGluIHNlYXJjaCBpbnB1dC4gU2V0IGl0IGJhY2sgdG8gZHJvcGRvd24gZXZlcnkgdGltZSB3aGVuIG9wZW5cblx0XHRcdFx0aWYgKCAhc291cmNlX2RhdGEgKSB7XG5cdFx0XHRcdFx0Ly9XaGVuIHVzaW5nIHBhZ2luYXRpb24gYW5kIGZpcnN0IG9wZW5pbmcgdGhlIGRyb3Bkb3duIGJveCwgd2UgbmVlZCB0byBleGNsdWRlIHRoZSBzZWxlY3RlZCBpdGVtcyBmcm9tIHRoZSBBUEkgY2FsbFxuXHRcdFx0XHRcdC8vIHNvIHRoZSBmaXJzdCBwYWdlIHdpbGwgYWx3YXlzIGJlIHBvcHVsYXRlZCB3aXRoIGEgZnVsbCBwYWdlIG9mIHJlY29yZHMuXG5cdFx0XHRcdFx0Ly8gTG93ZXIgZG93biB3ZSBtYWtlIGEgc2VwYXJhdGUgQVBJIGNhbGwgdG8gZ2V0IHRoZSByZWNvcmRzIGZvciB0aGUgc2VsZWN0ZWQgaXRlbXMsIGFuZCBzb3VyY2VfZGF0YS5jb25jYXQoKSB0aGVtIHRoZXJlLlxuXHRcdFx0XHRcdHZhciBhcmdzID0gJHRoaXMuYnVpbGRVblNlbGVjdEdyaWRGaWx0ZXIoICR0aGlzLmdldFZhbHVlKCkgKTtcblxuXHRcdFx0XHRcdC8vRXJyb3I6IFR5cGVFcnJvcjogYXBpIGlzIG51bGwgaW4gL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvd2lkZ2V0cy9hd2Vzb21lYm94L0FDb21ib0JveC5qcz92PTguMC4wLTIwMTQxMTE3LTExMjAzMyBsaW5lIDIzNjRcblx0XHRcdFx0XHRpZiAoICFhcGkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGFkZGl0aW9uX3NvdXJjZV9mdW5jdGlvbiApIHsgLy9SZXF1aXJlZCB0byBhZGQgZGF0YSB0byBzZWFyY2ggVUkgZm9yIGN1c3RvbSBmaWVsZHNcblx0XHRcdFx0XHRcdFx0c291cmNlX2RhdGEgPSBhZGRpdGlvbl9zb3VyY2VfZnVuY3Rpb24oICR0aGlzLCBzb3VyY2VfZGF0YSApO1xuXHRcdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLnNldFVuc2VsZWN0ZWRHcmlkRGF0YSggc291cmNlX2RhdGEgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFRUUHJvbWlzZS5yZXNvbHZlKCAnQUNvbWJvQm94JywgJ2luaXQnICk7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YXBpWydnZXQnICsgY3VzdG9tX2tleV9uYW1lXSggYXJncywge1xuXHRcdFx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXN1bHQgKSB7XG5cdFx0XHRcdFx0XHRcdHZhciByZXN1bHRfZGF0YSA9IHJlc3VsdC5nZXRSZXN1bHQoKTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoICFHbG9iYWwuaXNBcnJheSggcmVzdWx0X2RhdGEgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXN1bHRfZGF0YSA9IFtdO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0c291cmNlX2RhdGEgPSByZXN1bHRfZGF0YTtcblxuXHRcdFx0XHRcdFx0XHQvL3NldCB0aGlzIG91dHNpZGUsIHRvIGFkZCBtb3JlIGRhdGEgdG8gc291cmNlX2RhdGFcblx0XHRcdFx0XHRcdFx0aWYgKCBhZGRpdGlvbl9zb3VyY2VfZnVuY3Rpb24gKSB7XG5cdFx0XHRcdFx0XHRcdFx0c291cmNlX2RhdGEgPSBhZGRpdGlvbl9zb3VyY2VfZnVuY3Rpb24oICR0aGlzLCBzb3VyY2VfZGF0YSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0bmF2aWdhdGlvbl9tb2RlX3NvdXJjZV9kYXRhX2JlZm9yZV9vcGVuID0gbnVsbDtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIEdsb2JhbC5pc1NldCggYXBpICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c291cmNlX2RhdGEgPSBHbG9iYWwuZm9ybWF0R3JpZERhdGEoIHNvdXJjZV9kYXRhLCBhcGkua2V5X25hbWUgKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGlmICggYWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uICkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggc2V0X2FsbCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdCR0aGlzLmNyZWF0ZUZpcnN0SXRlbSgpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdC8vIEZvciBzZWxlY3QgaXRlbXMgd2hpY2ggb25seSBjb250YWlucyBpZHMsIGxpa2UgYWxsIGF3ZXNvbWVib3hlcyBpbiBlZGl0IHZpZXdcblx0XHRcdFx0XHRcdFx0XHQvLyBTaW1pbGFyIGNvZGUgaXMgYWxzbyBiZWxvdyBpbiB0aGUgfSBlbHNlIHsgY2xhdXNlIG9mIHRoaXMgSUYgc3RhdGVtZW50LlxuXHRcdFx0XHRcdFx0XHRcdGlmICggZ2V0X3JlYWxfZGF0YV93aGVuX29wZW4gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRnZXRfcmVhbF9kYXRhX3doZW5fb3BlbiA9IGZhbHNlO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLnNldFVuc2VsZWN0ZWRHcmlkRGF0YSggc291cmNlX2RhdGEgKTtcblxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCAhc2VsZWN0X2l0ZW1zIHx8ICggc2VsZWN0X2l0ZW1zICYmIHNlbGVjdF9pdGVtcy5sZW5ndGggPT0gMSAmJiAoIHNlbGVjdF9pdGVtc1swXSA9PSBUVFVVSUQuemVyb19pZCB8fCBzZWxlY3RfaXRlbXNbMF0gPT0gVFRVVUlELm5vdF9leGlzdF9pZCApICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFRUUHJvbWlzZS5yZXNvbHZlKCAnQUNvbWJvQm94JywgJ2luaXQnICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR2YXIgYXJncyA9IHt9O1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRhcmdzLmZpbHRlcl9kYXRhID0geyBpZDogc2VsZWN0X2l0ZW1zIH07XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGFyZ3MuZmlsdGVyX2NvbHVtbnMgPSAkdGhpcy5nZXRDb2x1bW5GaWx0ZXIoKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0YXJncy5maWx0ZXJfaXRlbXNfcGVyX3BhZ2UgPSAxMDAwMDtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvL0Vycm9yOiBUeXBlRXJyb3I6IG51bGwgaXMgbm90IGFuIG9iamVjdCAoZXZhbHVhdGluZyAnc2VsZWN0X2l0ZW1zLmxlbmd0aCcpIGluIC9pbnRlcmZhY2UvaHRtbDUvZ2xvYmFsL3dpZGdldHMvYXdlc29tZWJveC9BQ29tYm9Cb3guanM/dj04LjAuMC0yMDE0MTIzMC0xMTM1MjYgbGluZSAyNDQxXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vaWYgc2VsZWN0IGl0ZW1zIGNvbnRhaW5zIGRhdGEgbGlrZSAwLCBmb3IgZXhhbXBsZSBFbXBsb3llZSBpbiBSZWN1cnJpbmcgU2NoZWR1bGUgZWRpdCB2aWV3XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHZhciBsb2NhbF9kYXRhID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggc2VsZWN0X2l0ZW1zICYmIHNlbGVjdF9pdGVtcy5sZW5ndGggPiAwICYmICggc2VsZWN0X2l0ZW1zWzBdID09IFRUVVVJRC56ZXJvX2lkIHx8IHNlbGVjdF9pdGVtc1swXSA9PSBUVFVVSUQubm90X2V4aXN0X2lkICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bG9jYWxfZGF0YSA9ICR0aGlzLmdldExvY2FsU2VsZWN0SXRlbSggc2VsZWN0X2l0ZW1zWzBdICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRhcGlbJ2dldCcgKyBjdXN0b21fa2V5X25hbWVdKCBhcmdzLCB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXN1bHQgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRzZWxlY3RfaXRlbXMgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vU2luY2UgdGhlIGluaXRpYWwgQVBJIGNhbGwgYWJvdmUgZXhjbHVkZWQgdGhlIHNlbGVjdGVkIGl0ZW1zLCB3ZSBuZWVkIHRvIGNvbmNhdCgpIHRoZW0gYmFjayBvbnRvIHRoZSBzb3VyY2VfZGF0YSBhcnJheVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0c291cmNlX2RhdGEgPSBzb3VyY2VfZGF0YS5jb25jYXQoIHNlbGVjdF9pdGVtcyApOyAvL0RvIGFib3ZlIHRoZSB1bnNoaWZ0KCBsb2NhbF9kYXRhICkgYmVsb3cuXG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggbG9jYWxfZGF0YSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0c2VsZWN0X2l0ZW1zLnVuc2hpZnQoIGxvY2FsX2RhdGEgKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly9hX2Ryb3Bkb3duLnNldFNlbGVjdEdyaWREYXRhKCBzZWxlY3RfaXRlbXMgKTsgLy9zZXQgU2VsZWN0ZWQgRGF0YSBhZnRlciBzZXQgc291cmNlRGF0YVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0c2V0QURyb3BEb3duU2VsZWN0VmFsdWVzKCBzZWxlY3RfaXRlbXMgKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFRUUHJvbWlzZS5yZXNvbHZlKCAnQUNvbWJvQm94JywgJ2luaXQnICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdGFfZHJvcGRvd24uc2V0VW5zZWxlY3RlZEdyaWREYXRhKCBzb3VyY2VfZGF0YSApO1xuXHRcdFx0XHRcdFx0XHRcdFx0Ly9Jc3N1ZSAjMzIyMCAtIFdoZW4gYW4gQXdlc29tZUJveCBoYXMgb25seSAxIGl0ZW0gc2VsZWN0ZWQgb24gaW5pdGlhbCBsb2FkLCB0aGF0IGl0ZW0gd2lsbCBkaXNhcHBlYXIgb24gcmVvcGVuXG5cdFx0XHRcdFx0XHRcdFx0XHQvL2lmIGl0IGlzIHVuc2VsZWN0ZWQgYnkgdGhlIHVzZXIgYXMgaXQgaXMgbm90IGluIHRoZSBzb3VyY2VfZGF0YSBmb3IgdGhlIEF3ZXNvbWVCb3guXG5cdFx0XHRcdFx0XHRcdFx0XHQvL1NpbmNlIHRoZSBpbml0aWFsIEFQSSBjYWxsIGFib3ZlIGV4Y2x1ZGVkIHRoZSBzZWxlY3RlZCBpdGVtcywgd2UgbmVlZCB0byBjb25jYXQoKSB0aGVtIGJhY2sgb250byB0aGUgc291cmNlX2RhdGEgYXJyYXlcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggQXJyYXkuaXNBcnJheSggc2VsZWN0X2l0ZW1zICkgJiYgc2VsZWN0X2l0ZW1zLmxlbmd0aCA+IDAgJiYgc2VsZWN0X2l0ZW1zWzBdLmlkICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRzb3VyY2VfZGF0YSA9IHNvdXJjZV9kYXRhLmNvbmNhdCggc2VsZWN0X2l0ZW1zICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRzZXRBRHJvcERvd25TZWxlY3RWYWx1ZXMoIHNlbGVjdF9pdGVtcyApO1xuXHRcdFx0XHRcdFx0XHRcdFx0VFRQcm9taXNlLnJlc29sdmUoICdBQ29tYm9Cb3gnLCAnaW5pdCcgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBzZXRfZW1wdHkgfHwgc2V0X2FueSB8fCBzZXRfZGVmYXVsdCB8fCBzZXRfb3BlbiB8fCBzZXRfc3BlY2lhbF9lbXB0eSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdCR0aGlzLmNyZWF0ZUZpcnN0SXRlbSgpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdGFfZHJvcGRvd24uc2V0VW5zZWxlY3RlZEdyaWREYXRhKCBzb3VyY2VfZGF0YSApO1xuXHRcdFx0XHRcdFx0XHRcdGFfZHJvcGRvd24uc2V0U2VsZWN0SXRlbSggc2VsZWN0X2l0ZW0gKTtcblx0XHRcdFx0XHRcdFx0XHRUVFByb21pc2UucmVzb2x2ZSggJ0FDb21ib0JveCcsICdpbml0JyApO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0cGFnZXJfZGF0YSA9IHJlc3VsdC5nZXRQYWdlckRhdGEoKTtcblx0XHRcdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRQYWdlckRhdGEoIHBhZ2VyX2RhdGEgKTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoICFHbG9iYWwuaXNFbXB0eSggY2FjaGVkX3NlYXJjaF9pbnB1dHNfZmlsdGVyICkgfHwgIUdsb2JhbC5pc0VtcHR5KCBjYWNoZWRfc29ydF9maWx0ZXIgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLmdldFVuU2VsZWN0R3JpZCgpLmdyaWQuaGlkZSgpO1xuXHRcdFx0XHRcdFx0XHRcdCR0aGlzLm9uQURyb3BEb3duU2VhcmNoKCAndW5zZWxlY3RfZ3JpZCcgKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGlmICggIUdsb2JhbC5pc0VtcHR5KCBjYWNoZWRfc2VsZWN0X2dyaWRfc2VhcmNoX2lucHV0c19maWx0ZXIgKSB8fCAhR2xvYmFsLmlzRW1wdHkoIGNhY2hlZF9zZWxlY3RlZF9ncmlkX3NvcnRfZmlsdGVyICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0YV9kcm9wZG93bi5nZXRTZWxlY3RHcmlkKCkuZ3JpZC5oaWRlKCk7XG5cdFx0XHRcdFx0XHRcdFx0JHRoaXMub25BRHJvcERvd25TZWFyY2goICdzZWxlY3RfZ3JpZCcgKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSApO1xuXHRcdFx0XHR9IGVsc2UgeyAvL1VzZSBjYWNoZSBpZiBhbHJlYWR5IGxvYWRlZCBkYXRhIGJlZm9yZVxuXG5cdFx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGFwaSApICkge1xuXHRcdFx0XHRcdFx0c291cmNlX2RhdGEgPSBHbG9iYWwuZm9ybWF0R3JpZERhdGEoIHNvdXJjZV9kYXRhLCBhcGkua2V5X25hbWUgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIGFsbG93X211bHRpcGxlX3NlbGVjdGlvbiApIHtcblx0XHRcdFx0XHRcdGlmICggbGF5b3V0X25hbWUgPT09ICdnbG9iYWxfc29ydF9jb2x1bW5zJyApIHtcblx0XHRcdFx0XHRcdFx0c2VsZWN0X2l0ZW1zID0gYnVpbGRTb3J0QnlTZWxlY3RDb2x1bW5zKCBzZWxlY3RfaXRlbXMgKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gU2ltaWxhciBjb2RlIGlzIGFsc28gYmVsb3cgaW4gdGhlIGFib3ZlIFRSVUUgSUYgc3RhdGVtZW50IGNsYXVzZS5cblx0XHRcdFx0XHRcdGlmICggZ2V0X3JlYWxfZGF0YV93aGVuX29wZW4gKSB7XG5cdFx0XHRcdFx0XHRcdGdldF9yZWFsX2RhdGFfd2hlbl9vcGVuID0gZmFsc2U7XG5cblx0XHRcdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRVbnNlbGVjdGVkR3JpZERhdGEoIHNvdXJjZV9kYXRhICk7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCAhc2VsZWN0X2l0ZW1zIHx8ICggc2VsZWN0X2l0ZW1zICYmIHNlbGVjdF9pdGVtcy5sZW5ndGggPT0gMSAmJiAoIHNlbGVjdF9pdGVtc1swXSA9PSBUVFVVSUQuemVyb19pZCB8fCBzZWxlY3RfaXRlbXNbMF0gPT0gVFRVVUlELm5vdF9leGlzdF9pZCApICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0VFRQcm9taXNlLnJlc29sdmUoICdBQ29tYm9Cb3gnLCAnaW5pdCcgKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHR2YXIgYXJncyA9IHt9O1xuXHRcdFx0XHRcdFx0XHRcdGFyZ3MuZmlsdGVyX2RhdGEgPSB7IGlkOiBzZWxlY3RfaXRlbXMgfTtcblx0XHRcdFx0XHRcdFx0XHRhcmdzLmZpbHRlcl9jb2x1bW5zID0gJHRoaXMuZ2V0Q29sdW1uRmlsdGVyKCk7XG5cdFx0XHRcdFx0XHRcdFx0YXJncy5maWx0ZXJfaXRlbXNfcGVyX3BhZ2UgPSAxMDAwMDtcblxuXHRcdFx0XHRcdFx0XHRcdC8vRXJyb3I6IFR5cGVFcnJvcjogbnVsbCBpcyBub3QgYW4gb2JqZWN0IChldmFsdWF0aW5nICdzZWxlY3RfaXRlbXMubGVuZ3RoJykgaW4gL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvd2lkZ2V0cy9hd2Vzb21lYm94L0FDb21ib0JveC5qcz92PTguMC4wLTIwMTQxMjMwLTExMzUyNiBsaW5lIDI0NDFcblx0XHRcdFx0XHRcdFx0XHQvL2lmIHNlbGVjdCBpdGVtcyBjb250YWlucyBkYXRhIGxpa2UgMCwgZm9yIGV4YW1wbGUgRW1wbG95ZWUgaW4gUmVjdXJyaW5nIFNjaGVkdWxlIGVkaXQgdmlld1xuXHRcdFx0XHRcdFx0XHRcdHZhciBsb2NhbF9kYXRhID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBzZWxlY3RfaXRlbXMgJiYgc2VsZWN0X2l0ZW1zLmxlbmd0aCA+IDAgJiYgKCBzZWxlY3RfaXRlbXNbMF0gPT0gVFRVVUlELnplcm9faWQgfHwgc2VsZWN0X2l0ZW1zWzBdID09IFRUVVVJRC5ub3RfZXhpc3RfaWQgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGxvY2FsX2RhdGEgPSAkdGhpcy5nZXRMb2NhbFNlbGVjdEl0ZW0oIHNlbGVjdF9pdGVtc1swXSApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdGFwaVsnZ2V0JyArIGN1c3RvbV9rZXlfbmFtZV0oIGFyZ3MsIHtcblx0XHRcdFx0XHRcdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRzZWxlY3RfaXRlbXMgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBsb2NhbF9kYXRhICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHNlbGVjdF9pdGVtcy51bnNoaWZ0KCBsb2NhbF9kYXRhICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLnNldFVuc2VsZWN0ZWRHcmlkRGF0YSggc291cmNlX2RhdGEgKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly9hX2Ryb3Bkb3duLnNldFNlbGVjdEdyaWREYXRhKCBzZWxlY3RfaXRlbXMgKTsgLy9zZXQgU2VsZWN0ZWQgRGF0YSBhZnRlciBzZXQgc291cmNlRGF0YVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRzZXRBRHJvcERvd25TZWxlY3RWYWx1ZXMoIHNlbGVjdF9pdGVtcyApO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRUVFByb21pc2UucmVzb2x2ZSggJ0FDb21ib0JveCcsICdpbml0JyApO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLnNldFVuc2VsZWN0ZWRHcmlkRGF0YSggc291cmNlX2RhdGEgKTtcblx0XHRcdFx0XHRcdFx0Ly9hX2Ryb3Bkb3duLnNldFNlbGVjdEdyaWREYXRhKCBzZWxlY3RfaXRlbXMgKTtcblx0XHRcdFx0XHRcdFx0c2V0QURyb3BEb3duU2VsZWN0VmFsdWVzKCBzZWxlY3RfaXRlbXMgKTtcblx0XHRcdFx0XHRcdFx0VFRQcm9taXNlLnJlc29sdmUoICdBQ29tYm9Cb3gnLCAnaW5pdCcgKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLnNldFVuc2VsZWN0ZWRHcmlkRGF0YSggc291cmNlX2RhdGEgKTtcblx0XHRcdFx0XHRcdGFfZHJvcGRvd24uc2V0U2VsZWN0SXRlbSggc2VsZWN0X2l0ZW0gKTtcblx0XHRcdFx0XHRcdFRUUHJvbWlzZS5yZXNvbHZlKCAnQUNvbWJvQm94JywgJ2luaXQnICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YV9kcm9wZG93bi5zZXRQYWdlckRhdGEoIHBhZ2VyX2RhdGEgKTtcblxuXHRcdFx0XHRcdGlmICggIUdsb2JhbC5pc0VtcHR5KCBjYWNoZWRfc2VhcmNoX2lucHV0c19maWx0ZXIgKSB8fCAhR2xvYmFsLmlzRW1wdHkoIGNhY2hlZF9zb3J0X2ZpbHRlciApICkge1xuXHRcdFx0XHRcdFx0YV9kcm9wZG93bi5nZXRVblNlbGVjdEdyaWQoKS5ncmlkLmhpZGUoKTtcblx0XHRcdFx0XHRcdCR0aGlzLm9uQURyb3BEb3duU2VhcmNoKCAndW5zZWxlY3RfZ3JpZCcgKTtcblx0XHRcdFx0XHRcdGN1cnJlbnRfb3Blbl9wYWdlID0gMTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0aWYgKCBjdXJyZW50X29wZW5fcGFnZSA+IDEgJiYgY3VycmVudF9vcGVuX3BhZ2UgPD0gcGFnZXJfZGF0YS5sYXN0X3BhZ2VfbnVtYmVyICkge1xuXHRcdFx0XHRcdFx0XHRhX2Ryb3Bkb3duLmdldFVuU2VsZWN0R3JpZCgpLmdyaWQuaGlkZSgpO1xuXHRcdFx0XHRcdFx0XHQkdGhpcy5vbkFEcm9wRG93blNlYXJjaCggJ3Vuc2VsZWN0X2dyaWQnLCBjdXJyZW50X29wZW5fcGFnZSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICggIUdsb2JhbC5pc0VtcHR5KCBjYWNoZWRfc2VsZWN0X2dyaWRfc2VhcmNoX2lucHV0c19maWx0ZXIgKSB8fCAhR2xvYmFsLmlzRW1wdHkoIGNhY2hlZF9zZWxlY3RlZF9ncmlkX3NvcnRfZmlsdGVyICkgKSB7XG5cdFx0XHRcdFx0XHQvL2FfZHJvcGRvd24uZ2V0U2VsZWN0R3JpZCgpLmdyaWQuaGlkZSgpOyAvLyMyNzIxIC0gVGhpcyBoZWxwcyBmaXhlcyBhIGJ1ZyB3aGVyZSBpZiB5b3UgZXhwYW5kIGEgYXdlc29tZWJveCAoaWU6IEVkaXQgUG9saWN5IEdyb3VwLCBBYnNlbmNlIFBvbGljeXMpLCBvbiByaWdodC1oYW5kIHNpZGUgY2xpY2sgY2xlYXIgc2VhcmNoLiBDbGljayBNb3ZlIEFsbCBvbiByaWdodC1oYW5kIHNpZGUuIENvbGxhcHNlLCBleHBhbmQsIGNsaWNrIG1vdmUgQWxsIGxlZnQtaGFuZCBzaWRlLiBCb3RoIHNpZGVzIGFyZSBub3cgYmxhbmsgYmVjYXVzZSB0aGUgcmlnaHQgZ3JpZCBoYWQgYSBkaXNwbGF5OiBub25lIGF0dGFjaGVkIHRvIGl0LlxuXHRcdFx0XHRcdFx0JHRoaXMub25BRHJvcERvd25TZWFyY2goICdzZWxlY3RfZ3JpZCcgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHR9ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9O1xuXG5cdCQuZm4uQUNvbWJvQm94LmRlZmF1bHRzID0ge307XG5cdCQuZm4uQUNvbWJvQm94Lmh0bWxfdGVtcGxhdGUgPSBgXG5cdDxkaXYgY2xhc3M9XCJhLWNvbWJvYm94XCI+XG5cdFx0PGRpdiBjbGFzcz1cImEtY29tYm9ib3gtbGVmdC1iZ1wiPjwvZGl2PlxuXHRcdDxzcGFuIGNsYXNzPVwiYS1jb21ib2JveC1sYWJlbCBvcGVuQURyb3BEb3duIGEtY29tYm9ib3gtbWlkLWJnXCI+PC9zcGFuPlxuXHRcdDxpbnB1dCBjbGFzcz1cImZvY3VzLWlucHV0XCI+XG5cdFx0PGRpdiBjbGFzcz1cImNsaWNrYWJsZS1zcGFjZSBvcGVuQURyb3BEb3duXCI+PC9kaXY+XG5cdDwvZGl2PlxuXHRgO1xuXG59ICkoIGpRdWVyeSApOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2897\n")}}]);