TimeTrex/interface/html5/dist/my_account-message_control-MessageControlViewController.bundle.js

1 line
131 KiB
JavaScript

"use strict";(self.webpackChunktimetrex=self.webpackChunktimetrex||[]).push([["my_account-message_control-MessageControlViewController"],{4468:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"MessageControlViewController\": () => (/* binding */ MessageControlViewController)\n/* harmony export */ });\n/* harmony import */ var linkifyjs_string__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5853);\n/* harmony import */ var linkifyjs_string__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(linkifyjs_string__WEBPACK_IMPORTED_MODULE_0__);\n/* provided dependency */ var _ = __webpack_require__(9050);\n/* provided dependency */ var $ = __webpack_require__(9755);\n\n\nclass MessageControlViewController extends BaseViewController {\n\tconstructor( options = {} ) {\n\t\t_.defaults( options, {\n\t\t\tel: '#message_control_view_container',\n\n\t\t\tobject_type_array: null,\n\n\t\t\tis_request: false,\n\t\t\tis_message: false,\n\n\t\t\tmessages: null,\n\t\t\trequest_api: null,\n\n\t\t\tfolder_id: null,\n\n\t\t\tnavigation_source_data: null,\n\n\t\t\tisReloadViewUI: false,\n\n\t\t\tcurrent_select_message_control_data: null, //current select message control data, set in onViewClick\n\n\t\t} );\n\n\t\tsuper( options );\n\t}\n\n\tinit( options ) {\n\t\t//this._super('initialize', options );\n\t\tthis.edit_view_tpl = 'MessageControlEditView.html';\n\t\tthis.permission_id = 'message';\n\t\tthis.viewId = 'MessageControl';\n\t\tthis.script_name = 'MessageControlView';\n\t\tthis.table_name_key = 'message_control';\n\t\tthis.context_menu_name = $.i18n._( 'Message' );\n\t\tthis.api = TTAPI.APIMessageControl;\n\t\tthis.request_api = TTAPI.APIRequest;\n\t\tthis.folder_id = 10;\n\t\tthis.event_bus = new TTEventBus({ view_id: this.viewId });\n\n\t\tthis.render();\n\t\tthis.buildContextMenu();\n\n\t\tthis.initData();\n\t}\n\n\tinitOptions() {\n\t\tvar $this = this;\n\n\t\tthis.initDropDownOption( 'object_type' );\n\t}\n\n\tbuildSearchFields() {\n\n\t\tsuper.buildSearchFields();\n\n\t\tvar default_args = {};\n\t\tdefault_args.permission_section = 'message';\n\t\tthis.search_fields = [\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Employee' ),\n\t\t\t\tin_column: 1,\n\t\t\t\tfield: 'user_id',\n\t\t\t\tdefault_args: default_args,\n\t\t\t\tlayout_name: 'global_user',\n\t\t\t\tapi_class: TTAPI.APIUser,\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: false,\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Type' ),\n\t\t\t\tin_column: 1,\n\t\t\t\tmultiple: true,\n\t\t\t\tfield: 'object_type_id',\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: false,\n\t\t\t\tlayout_name: 'global_option_column',\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Subject' ),\n\t\t\t\tin_column: 1,\n\t\t\t\tfield: 'subject',\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: false,\n\t\t\t\tform_item_type: FormItemType.TEXT_INPUT\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Created By' ),\n\t\t\t\tin_column: 2,\n\t\t\t\tfield: 'created_by',\n\t\t\t\tlayout_name: 'global_user',\n\t\t\t\tapi_class: TTAPI.APIUser,\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: false,\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Updated By' ),\n\t\t\t\tin_column: 2,\n\t\t\t\tfield: 'updated_by',\n\t\t\t\tlayout_name: 'global_user',\n\t\t\t\tapi_class: TTAPI.APIUser,\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: false,\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} )\n\t\t];\n\t}\n\n\tgetSubViewFilter( filter ) {\n\n\t\tif ( filter.length === 0 ) {\n\t\t\tfilter = {};\n\t\t}\n\n\t\tfilter['folder_id'] = this.folder_id;\n\n\t\treturn filter;\n\t}\n\n\tgetCustomContextMenuModel() {\n\t\tvar context_menu_model = {\n\t\t\texclude: ['default'],\n\t\t\tinclude: [\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'New' ),\n\t\t\t\t\tid: 'add',\n\t\t\t\t\tvue_icon: 'tticon tticon-add_black_24dp'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'View' ),\n\t\t\t\t\tid: 'view',\n\t\t\t\t\tvue_icon: 'tticon tticon-visibility_black_24dp',\n\t\t\t\t\tshow_on_right_click: true,\n\t\t\t\t\tsort_order: 1010\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'Reply' ),\n\t\t\t\t\tid: 'edit',\n\t\t\t\t\tvue_icon: 'tticon tticon-reply_black_24dp'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'Delete' ),\n\t\t\t\t\tid: 'delete_icon',\n\t\t\t\t\taction_group: 'delete',\n\t\t\t\t\tvue_icon: 'tticon tticon-delete_black_24dp'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'Delete & Next' ),\n\t\t\t\t\tid: 'delete_and_next',\n\t\t\t\t\taction_group: 'delete',\n\t\t\t\t\tvue_icon: 'tticon tticon-delete_black_24dp'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'Send' ),\n\t\t\t\t\tid: 'send',\n\t\t\t\t\tvue_icon: 'tticon tticon-send_black_24dp'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'Cancel' ),\n\t\t\t\t\tid: 'cancel',\n\t\t\t\t\tpermission_result: true,\n\t\t\t\t\tpermission: null,\n\t\t\t\t\tsort_order: 1990\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'Folder: Inbox' ),\n\t\t\t\t\tid: 'inbox',\n\t\t\t\t\taction_group: 'message_type',\n\t\t\t\t\tmulti_select_group: 1,\n\t\t\t\t\tselected: true,\n\t\t\t\t\tpermission_result: true,\n\t\t\t\t\tpermission: null\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'Folder: Sent' ),\n\t\t\t\t\tid: 'sent',\n\t\t\t\t\taction_group: 'message_type',\n\t\t\t\t\tmulti_select_group: 1,\n\t\t\t\t\tselected: false,\n\t\t\t\t\tpermission_result: true,\n\t\t\t\t\tpermission: null\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'Export' ),\n\t\t\t\t\tid: 'export_excel',\n\t\t\t\t\tvue_icon: 'tticon tticon-file_upload_black_24dp',\n\t\t\t\t\tmenu_align: 'right',\n\t\t\t\t\tpermission_result: true,\n\t\t\t\t\tpermission: null,\n\t\t\t\t\tsort_order: 9000\n\t\t\t\t}\n\t\t\t]\n\t\t};\n\n\t\treturn context_menu_model;\n\t}\n\n\tsetCustomDefaultMenuIcon( id, context_btn, grid_selected_length ) {\n\t\tswitch ( id ) {\n\t\t\tcase 'close_misc':\n\t\t\t\tthis.setDefaultMenuCloseMiscIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t\tcase 'send':\n\t\t\t\tthis.setDefaultMenuSendIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t\tcase 'cancel':\n\t\t\t\tthis.setDefaultMenuCancelIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t\tcase 'inbox':\n\t\t\t\tif ( this.folder_id === 10 ) {\n\t\t\t\t\tthis.setCurrentSelectedIcon( context_btn );\n\t\t\t\t}\n\t\t\t\tthis.setDefaultMenuInboxIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t\tcase 'sent':\n\t\t\t\tif ( this.folder_id === 20 ) {\n\t\t\t\t\tthis.setCurrentSelectedIcon( context_btn );\n\t\t\t\t}\n\t\t\t\tthis.setDefaultMenuSentIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tonGridDblClickRow() {\n\n\t\tvar context_menu_array = ContextMenuManager.getMenuModelByMenuId( this.determineContextMenuMountAttributes().id );\n\t\tvar len = context_menu_array.length;\n\n\t\tvar need_break = false;\n\n\t\tfor ( var i = 0; i < len; i++ ) {\n\n\t\t\tif ( need_break ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tlet context_btn = context_menu_array[i];\n\t\t\tlet id = context_menu_array[i].id;\n\n\t\t\tswitch ( id ) {\n\t\t\t\tcase 'view':\n\t\t\t\t\tneed_break = true;\n\t\t\t\t\tif ( context_btn.visible && !context_btn.disabled ) {\n\t\t\t\t\t\tProgressBar.showOverlay();\n\t\t\t\t\t\tthis.onViewClick();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tonCustomContextClick( id, context_btn ) {\n\t\t// Vue notes: Normally when Vue calls this menu, it does not need context_btn, as most places that use this function have the Global.isSet( menu_name ) check to just use menu_name as the id. However, MessageControlVC does use it, via setCurrentSelectedIcon\n\t\tif ( !context_btn ) {\n\t\t\tcontext_btn = ContextMenuManager.getMenuModelByMenuId( this.determineContextMenuMountAttributes().id ).find( icon => icon.id == id );\n\t\t}\n\n\t\tswitch ( id ) {\n\t\t\tcase 'send':\n\t\t\t\tthis.onSaveClick();\n\t\t\t\tbreak;\n\t\t\tcase 'close_misc':\n\t\t\tcase 'cancel':\n\t\t\t\tthis.onCancelClick( id );\n\t\t\t\tbreak;\n\t\t\tcase 'inbox':\n\t\t\t\tthis.setCurrentSelectedIcon( context_btn );\n\t\t\t\tthis.onInboxClick();\n\t\t\t\tbreak;\n\t\t\tcase 'sent':\n\t\t\t\tthis.setCurrentSelectedIcon( context_btn );\n\t\t\t\tthis.onSentClick();\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tonCancelClick( iconName ) {\n\t\tvar $this = this;\n\t\tLocalCacheData.current_doing_context_action = 'cancel';\n\n\t\tif ( this.is_changed ) {\n\t\t\tTAlertManager.showConfirmAlert( Global.modify_alert_message, null, function( flag ) {\n\n\t\t\t\tif ( flag === true ) {\n\t\t\t\t\tdoNext();\n\t\t\t\t}\n\n\t\t\t} );\n\t\t} else {\n\t\t\tdoNext();\n\t\t}\n\n\t\tfunction doNext() {\n\n\t\t\tif ( iconName === 'cancel' && $this.isReloadViewUI ) {\n\t\t\t\t$this.isReloadViewUI = false;\n//\t\t\t\t //set to fix that IndexViewConroler force ui back to view when open view again\n\t\t\t\tContextMenuManager.unmountContextMenu( $this.determineContextMenuMountAttributes().id );\n\t\t\t\t$this.onViewClick( $this.current_select_message_control_data );\n\t\t\t} else {\n\t\t\t\t$this.removeEditView();\n\t\t\t\t$this.isReloadViewUI = false;\n\t\t\t}\n\n\t\t\tGlobal.setUIInitComplete();\n\t\t\tProgressBar.closeOverlay();\n\n\t\t\tTTPromise.resolve( 'base', 'onCancelClick' );\n\n\t\t}\n\t}\n\n\tonSaveResult( result ) {\n\t\tvar $this = this;\n\t\tif ( result.isValid() ) {\n\t\t\tvar result_data = result.getResult();\n\t\t\tif ( !this.edit_only_mode ) {\n\t\t\t\tif ( result_data === true ) {\n\t\t\t\t\t$this.refresh_id = $this.current_edit_record.id;\n\t\t\t\t} else if ( TTUUID.isUUID( result_data ) && result_data != TTUUID.zero_id && result_data != TTUUID.not_exist_id ) {\n\t\t\t\t\t$this.refresh_id = result_data;\n\t\t\t\t}\n\n\t\t\t\t$this.search( false );\n\t\t\t}\n\n\t\t\t$this.onSaveDone( result );\n\n\t\t\tif ( $this.isReloadViewUI ) {\n\t\t\t\t$this.isReloadViewUI = false;\n\t\t\t\t$this.removeEditView();\n\t\t\t\t$this.onViewClick( $this.current_select_message_control_data );\n\n\t\t\t} else {\n\t\t\t\t$this.removeEditView();\n\t\t\t}\n\n\t\t\t$().TFeedback( {\n\t\t\t\tsource: 'Save'\n\t\t\t} );\n\n\t\t} else {\n\t\t\t$this.setErrorMenu();\n\t\t\t$this.setErrorTips( result );\n\n\t\t}\n\t}\n\n\tonInboxClick() {\n\t\tthis.folder_id = 10;\n\t\tthis.search();\n\t}\n\n\tonSentClick() {\n\t\tthis.folder_id = 20;\n\t\tthis.search();\n\t}\n\n\tsetCustomEditMenuIcon( id, context_btn ) {\n\t\tswitch ( id ) {\n\t\t\tcase 'close_misc':\n\t\t\t\tthis.setEditMenuCloseMiscIcon( context_btn );\n\t\t\t\tbreak;\n\t\t\tcase 'send':\n\t\t\t\tthis.setEditMenuSendIcon( context_btn );\n\t\t\t\tbreak;\n\t\t\tcase 'inbox':\n\t\t\t\tthis.setEditMenuInboxIcon( context_btn );\n\t\t\t\tbreak;\n\t\t\tcase 'sent':\n\t\t\t\tthis.setEditMenuSentIcon( context_btn );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tgetIsPunchOrRequest() {\n\t\tlet p_id = null;\n\t\tif ( this.is_message ) {\n\t\t\tp_id = 'message';\n\t\t} else if ( this.is_request ) {\n\t\t\tp_id = 'request';\n\t\t}\n\n\t\treturn p_id;\n\t}\n\n\tsetCurrentSelectedIcon( icon ) {\n\n\t\tvar context_menu_array = ContextMenuManager.getMenuModelByMenuId( this.determineContextMenuMountAttributes().id );\n\t\t//Error: Uncaught TypeError: Cannot read property 'find' of null in /interface/html5/#!m=MessageControl line 543\n\t\tif ( !icon ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar len = context_menu_array.length;\n\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\tlet context_btn = context_menu_array[i];\n\t\t\tlet id = context_menu_array[i].id;\n\n\t\t\tif( context_btn.active ) {\n\t\t\t\t// Make sure to only set the relevant group icons inactive, otherwise the other context menu icons get active/inactive toggle icons set on them too.\n\t\t\t\tContextMenuManager.activateMenuItem( this.determineContextMenuMountAttributes().id, context_btn\t.id, true );\n\t\t\t}\n\t\t}\n\t\tContextMenuManager.activateMenuItem( this.determineContextMenuMountAttributes().id, icon.id, false );\n\t}\n\n\tsetDefaultMenuDeleteAndNextIcon( context_btn, grid_selected_length ) {\n\n\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t}\n\n\tsetDefaultMenuDeleteIcon( context_btn, grid_selected_length ) {\n\n\t\tif ( grid_selected_length >= 1 ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t\t} else {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetDefaultMenuEditIcon( context_btn, grid_selected_length ) {\n\n\t\tif ( this.is_edit || this.is_viewing ) {\n\t\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t\t} else {\n\t\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\n\t\tif ( grid_selected_length === 1 ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t\t} else {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetDefaultMenuViewIcon( context_btn, grid_selected_length ) {\n\n\t\tif ( grid_selected_length === 1 ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t\t} else {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetDefaultMenuAddIcon( context_btn, grid_selected_length ) {\n\t}\n\n\tsetEditMenuCloseMiscIcon( context_btn ) {\n\t}\n\n\tsetEditMenuSendIcon( context_btn ) {\n\n\t\tif ( this.is_edit || this.is_add ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t\t} else {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetEditMenuInboxIcon( context_btn ) {\n\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t}\n\n\tsetEditMenuSentIcon( context_btn ) {\n\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t}\n\n\tsetDefaultMenuCloseMiscIcon( context_btn, grid_selected_length ) {\n\n\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t}\n\n\tsetDefaultMenuSendIcon( context_btn, grid_selected_length ) {\n\t\tif ( this.is_edit || this.is_viewing ) {\n\t\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t\t} else {\n\t\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\n\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t}\n\n\tsetDefaultMenuInboxIcon( context_btn, grid_selected_length ) {\n\t}\n\n\tsetDefaultMenuSentIcon( context_btn, grid_selected_length ) {\n\t}\n\n\tsetGridCellBackGround() {\n\t\tvar data = this.grid.getGridParam( 'data' );\n\n\t\t//Error: TypeError: data is undefined in /interface/html5/framework/jquery.min.js?v=7.4.6-20141027-074127 line 2 > eval line 70\n\t\tif ( !data ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar len = data.length;\n\n\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\tvar item = data[i];\n\n\t\t\tif ( item.status_id == 10 ) {\n\t\t\t\t$( 'tr[id=\\'' + item.id + '\\'] td' ).css( 'font-weight', 'bold' );\n\t\t\t}\n\t\t}\n\t}\n\n\tgetFilterColumnsFromDisplayColumns() {\n\t\tvar column_filter = {};\n\n\t\tcolumn_filter.id = true;\n\t\tcolumn_filter.is_child = true;\n\t\tcolumn_filter.is_owner = true;\n\t\tcolumn_filter.object_type_id = true;\n\t\tcolumn_filter.object_id = true;\n\t\tcolumn_filter.status_id = true;\n\t\tcolumn_filter.from_user_id = true;\n\t\tcolumn_filter.to_user_id = true;\n\n\t\t// Error: Unable to get property 'getGridParam' of undefined or null reference\n\t\tvar display_columns = [];\n\t\tif ( this.grid ) {\n\t\t\tdisplay_columns = this.grid.getGridParam( 'colModel' );\n\t\t}\n\n\t\tif ( display_columns ) {\n\t\t\tvar len = display_columns.length;\n\n\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\tvar column_info = display_columns[i];\n\t\t\t\tcolumn_filter[column_info.name] = true;\n\t\t\t}\n\t\t}\n\n\t\treturn column_filter;\n\t}\n\n\tinitEditViewUI( view_id, edit_view_file_name ) {\n\n\t\tvar $this = this;\n\n\t\tif ( this.edit_view ) {\n\t\t\tthis.edit_view.remove();\n\t\t}\n\t\tthis.edit_view = $( Global.loadViewSource( view_id, edit_view_file_name, null, true ) );\n\t\tthis.edit_view_tab = $( this.edit_view.find( '.edit-view-tab-bar' ) );\n\t\t//Give edt view tab a id, so we can load it when put right click menu on it\n\t\tthis.edit_view_tab.attr( 'id', this.ui_id + '_edit_view_tab' );\n\t\t// Moved into generic BaseView.initEditViewTabs\n\t\t// this.setTabOVisibility( false );\n\t\t// this.edit_view_tab = this.edit_view_tab.tabs( {\n\t\t// \tactivate: function( e, ui ) {\n\t\t// \t\t$this.onTabShow( e, ui );\n\t\t// \t}\n\t\t// } );\n\n\t\t// this.edit_view_tab.bind( 'tabsselect', function( e, ui ) {\n\t\t// \t$this.onTabIndexChange( e, ui );\n\t\t// } );\n\n\t\tif ( this.folder_id == 10 ) {\n\t\t\tthis.navigation_label = $.i18n._( 'From' );\n\t\t} else if ( this.folder_id == 20 ) {\n\t\t\tthis.navigation_label = $.i18n._( 'To' );\n\t\t}\n\n\t\tContextMenuManager.unmountContextMenu( this.determineContextMenuMountAttributes().id );\n\n\t\tGlobal.contentContainer().append( this.edit_view );\n\n\t\tthis.initRightClickMenu( RightClickMenuType.EDITVIEW );\n\n\t\tthis.buildEditViewUI();\n\t\tthis.setEditViewTabHeight();\n\t}\n\n\tinitEditViewTabs() {\n\t\tvar $this = this;\n\t\tvar tab_options = {\n\t\t\tactivate: function( e, ui ) {\n\t\t\t\t$this.onTabShow( e, ui );\n\t\t\t}\n\t\t};\n\n\t\tsuper.initEditViewTabs( tab_options );\n\t}\n\n\tgetViewSelectedRecordId( record ) {\n\t\t// overriden from BaseVC due to the this.getRecordFromGridById call\n\t\tvar selected_item;\n\t\tvar selected_id;\n\t\tvar grid_selected_id_array = this.getGridSelectIdArray();\n\t\tvar grid_selected_length = grid_selected_id_array.length;\n\n\t\tif ( Global.isSet( record ) ) {\n\t\t\tselected_item = record; // If the next_selected_item is defined, first to use this variable.\n\n\t\t} else if ( grid_selected_length > 0 ) {\n\t\t\tselected_item = this.getRecordFromGridById( grid_selected_id_array[0] );\n\t\t} else {\n\t\t\tTTPromise.reject( 'MessageControllViewController', 'onViewClick' );\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( selected_item.object_type_id == 50 ) {\n\t\t\tselected_id = selected_item.object_id;\n\t\t\tthis.is_request = true;\n\t\t\tthis.is_message = false;\n\t\t} else {\n\t\t\tselected_id = selected_item.id;\n\t\t\tthis.is_request = false;\n\t\t\tthis.is_message = true;\n\t\t}\n\n\t\treturn selected_item;\n\t}\n\n\tgetCurrentSelectedRecord( return_object ) {\n\t\tvar selected_item = this.current_selected_record;\n\t\tif ( !selected_item ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar selected_id;\n\t\tif ( selected_item.object_type_id && selected_item.object_type_id == 50 ) {\n\t\t\tselected_id = selected_item.object_id;\n\t\t} else {\n\t\t\tselected_id = selected_item.id;\n\t\t}\n\n\t\t// current_selected_record normally handles ID's, but for MessageControlVC we will be using the record object as this is needed in various places.\n\t\tif ( return_object === true ) {\n\t\t\treturn selected_item;\n\t\t} else {\n\t\t\treturn selected_id;\n\t\t}\n\t}\n\n\thandleViewAPICallbackResult( result ) {\n\t\tvar result_data;\n\t\tif ( result && result.getResult ) {\n\t\t\tresult_data = result.getResult();\n\t\t\tif ( this.is_request ) {\n\t\t\t\tresult_data = result_data[0];\n\t\t\t} else {\n\t\t\t\t// Note that we dont want to take just the first record if its not a request. Requests (and most other onView pages, only have one record. But messages can have multiple records in the results data.\n\t\t\t\tresult_data = result_data.length > 1 ? result_data.reverse() : result_data[0];\n\t\t\t}\n\t\t} else {\n\t\t\tresult_data = result;\n\t\t}\n\n\t\treturn super.handleViewAPICallbackResult( result_data );\n\t}\n\n\tdoViewAPICall( filter ) {\n\t\tvar callback = { onResult: this.handleViewAPICallbackResult.bind( this ) };\n\n\t\tif ( this.is_request ) {\n\t\t\treturn this.request_api.getRequest( filter, callback );\n\t\t} else {\n\t\t\treturn this.api.getMessage( filter, callback );\n\t\t}\n\t}\n\n\tdoViewClickResult( result_data ) {\n\t\t// save current select grid data. Not this not work when access from url action. See autoOpenEditView function for why\n\t\tthis.current_select_message_control_data = this.getCurrentSelectedRecord( true );\n\n\t\t//if access from url, current_select_message_control_data need be get again\n\t\tif ( !this.current_select_message_control_data.hasOwnProperty( 'to_user_id' ) ) {\n\t\t\tvar filter = { filter_data: { id: this.current_select_message_control_data.id } };\n\t\t\tvar message_control_data = this.api.getMessageControl( filter, { async: false } ).getResult()[0];\n\n\t\t\tif ( message_control_data ) {\n\t\t\t\tthis.current_select_message_control_data = message_control_data;\n\t\t\t}\n\n\t\t}\n\t\tvar retval = super.doViewClickResult( result_data );\n\t\tTTPromise.resolve( 'MessageControllViewController', 'onViewClick' );\n\t\t// The promise must be resolved last, after everthing else, hence the specific order here with retval and the super.\n\t\treturn retval;\n\t}\n\n\tgetAPIFilters() {\n\t\tvar record_id = this.getCurrentSelectedRecord();\n\t\tvar filter = {};\n\n\t\tfilter.filter_data = {};\n\t\tfilter.filter_data.id = record_id;\n\n\t\treturn filter;\n\t}\n\n\tonViewClick( next_selected_item, noRefreshUI ) {\n\t\tTTPromise.add( 'MessageControllViewController', 'onViewClick' );\n\t\tTTPromise.wait();\n\t\tvar $this = this;\n\n\t\tthis.setCurrentEditViewState( 'view' );\n\n\t\t$this.isReloadViewUI = true;\n\n\t\tvar selected_item = this.getViewSelectedRecordId( next_selected_item );\n\t\tif ( Global.isFalseOrNull( selected_item ) ) {\n\t\t\treturn;\n\t\t}\n\t\tthis.setCurrentSelectedRecord( selected_item );\n\n\t\tvar filter = this.getAPIFilters();\n\t\tthis.openEditView();\n\n\t\treturn this.doViewAPICall( filter );\n\t}\n\n\t/* jshint ignore:start */\n\tsetURL() {\n\n\t\tif ( LocalCacheData.current_doing_context_action === 'edit' ) {\n\t\t\tLocalCacheData.current_doing_context_action = '';\n\t\t\treturn;\n\t\t}\n\n\t\tvar a = '';\n\t\tswitch ( LocalCacheData.current_doing_context_action ) {\n\t\t\tcase 'new':\n\t\t\tcase 'edit':\n\t\t\tcase 'view':\n\t\t\t\ta = LocalCacheData.current_doing_context_action;\n\t\t\t\tbreak;\n\t\t\tcase 'copy_as_new':\n\t\t\t\ta = 'new';\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( this.canSetURL() ) {\n\t\t\tvar tab_name = this.edit_view_tab ? this.edit_view_tab.find( '.edit-view-tab-bar-label' ).children().eq( this.getEditViewTabIndex() ).text() : '';\n\t\t\ttab_name = tab_name.replace( /\\/|\\s+/g, '' );\n\t\t\tif ( this.current_select_message_control_data && this.current_select_message_control_data.id ) {\n\t\t\t\tif ( a ) {\n\n\t\t\t\t\tif ( this.is_request ) {\n\t\t\t\t\t\tGlobal.setURLToBrowser( Global.getBaseURL() + '#!m=' + this.viewId +\n\t\t\t\t\t\t\t'&a=' + a + '&id=' + this.current_select_message_control_data.id +\n\t\t\t\t\t\t\t'&t=request&object_id=' + this.current_select_message_control_data.object_id +\n\t\t\t\t\t\t\t'&tab=' + tab_name );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tGlobal.setURLToBrowser( Global.getBaseURL() +\n\t\t\t\t\t\t\t'#!m=' + this.viewId + '&a=' +\n\t\t\t\t\t\t\ta + '&id=' + this.current_select_message_control_data.id + '&t=message' +\n\t\t\t\t\t\t\t'&tab=' + tab_name );\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tGlobal.trackView();\n\n\t\t\t} else {\n\t\t\t\tif ( a ) {\n\t\t\t\t\t//Edit a record which don't have id, schedule view Recurring Scedule\n\t\t\t\t\tif ( a === 'edit' ) {\n\t\t\t\t\t\tGlobal.setURLToBrowser( Global.getBaseURL() + '#!m=' + this.viewId + '&a=new&t=' + ( this.is_request ? 'request' : 'message' ) +\n\t\t\t\t\t\t\t'&tab=' + tab_name );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tGlobal.setURLToBrowser( Global.getBaseURL() + '#!m=' + this.viewId + '&a=' + a + '&t=' + ( this.is_request ? 'request' : 'message' ) +\n\t\t\t\t\t\t\t'&tab=' + tab_name );\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\tGlobal.setURLToBrowser( Global.getBaseURL() + '#!m=' + this.viewId );\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\t/* jshint ignore:end */\n\tinitEditViewData() {\n\t\tvar $this = this;\n\t\tif ( !this.edit_only_mode && this.navigation ) {\n\n\t\t\tvar grid_current_page_items = this.grid.getGridParam( 'data' );\n\n\t\t\tvar navigation_div = this.edit_view.find( '.navigation-div' );\n\t\t\tvar navigation_source_data;\n\n\t\t\t//because I will always get this in onViewClick, so else branch should never be in\n\t\t\tif ( this.current_select_message_control_data && this.current_select_message_control_data.hasOwnProperty( 'id' ) &&\n\t\t\t\tthis.current_select_message_control_data.hasOwnProperty( 'subject' ) ) {\n\t\t\t\tnavigation_source_data = this.current_select_message_control_data;\n\t\t\t} else {\n\t\t\t\tnavigation_source_data = Global.isArray( this.current_edit_record ) ? this.current_edit_record[0] : this.current_edit_record;\n\t\t\t}\n\n\t\t\tthis.navigation_source_data = navigation_source_data;\n\n\t\t\tif ( this.is_viewing && Global.isSet( navigation_source_data.id ) && navigation_source_data.id ) {\n\t\t\t\tnavigation_div.css( 'display', 'block' );\n\t\t\t\t//Set Navigation Awesomebox\n\n\t\t\t\t//init navigation only when open edit view\n\t\t\t\tif ( !this.navigation.getSourceData() ) {\n\t\t\t\t\tthis.navigation.setSourceData( grid_current_page_items );\n\t\t\t\t\tthis.navigation.setRowPerPage( LocalCacheData.getLoginUserPreference().items_per_page );\n\t\t\t\t\tthis.navigation.setPagerData( this.pager_data );\n\n//\t\t\t\t\tthis.navigation.setDisPlayColumns( this.buildDisplayColumnsByColumnModel( this.grid.getGridParam( 'colModel' ) ) );\n\n\t\t\t\t\tvar default_args = {};\n\t\t\t\t\tdefault_args.filter_data = Global.convertLayoutFilterToAPIFilter( this.select_layout );\n\t\t\t\t\tdefault_args.filter_sort = this.select_layout.data.filter_sort;\n\t\t\t\t\tthis.navigation.setDefaultArgs( default_args );\n\t\t\t\t}\n\n\t\t\t\tthis.navigation.setValue( navigation_source_data );\n\n\t\t\t} else {\n\t\t\t\tnavigation_div.css( 'display', 'none' );\n\t\t\t}\n\t\t}\n\n\t\tthis.setUIWidgetFieldsToCurrentEditRecord();\n\n\t\tthis.setNavigationArrowsEnabled();\n\n\t\t// Create this function alone because of the column value of view is different from each other, some columns need to be handle specially. and easily to rewrite this function in sub-class.\n\n\t\tthis.setCurrentEditRecordData();\n\n\t\t//Init *Please save this record before modifying any related data* box\n\t\tthis.edit_view.find( '.save-and-continue-div' ).SaveAndContinueBox( { related_view_controller: this } );\n\t\tthis.edit_view.find( '.save-and-continue-div' ).css( 'display', 'none' );\n\t}\n\n\tsetNavigation() {\n\n\t\tvar $this = this;\n\n\t\tthis.navigation.setPossibleDisplayColumns( this.buildDisplayColumnsByColumnModel( this.grid.getGridParam( 'colModel' ) ),\n\t\t\tthis.buildDisplayColumns( this.default_display_columns ) );\n\n\t\tthis.navigation.unbind( 'formItemChange' ).bind( 'formItemChange', function( e, target ) {\n\n\t\t\tvar key = target.getField();\n\t\t\tvar next_select_item = target.getValue( true );\n\n\t\t\tif ( !next_select_item ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( next_select_item.id !== $this.navigation_source_data.id ) {\n\t\t\t\tProgressBar.showOverlay();\n\n\t\t\t\tif ( $this.is_viewing ) {\n\t\t\t\t\t$this.onViewClick( next_select_item ); //Dont refresh UI\n\t\t\t\t} else {\n\t\t\t\t\t$this.onEditClick( next_select_item ); //Dont refresh UI\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t$this.setNavigationArrowsEnabled();\n\n\t\t} );\n\t}\n\n\tonEditClick( editId, noRefreshUI ) {\n\t\t// edit click is clicking on Reply\n\t\tthis.setCurrentEditViewState( 'edit' );\n\t\tthis.is_request = false;\n\t\tthis.is_message = false;\n\n\t\tvar grid_selected_id_array = this.getGridSelectIdArray();\n\t\tvar selected_item = {};\n\n\t\tif ( this.edit_view ) {\n\t\t\tselected_item = this.current_select_message_control_data;\n\t\t} else { // click Reply on list view.\n\t\t\tselected_item = this.getRecordFromGridById( grid_selected_id_array[0] );\n\t\t}\n\n\t\tthis.current_edit_record = selected_item;\n\t\tthis.initEditViewUI( this.viewId, this.edit_view_tpl );\n\t\tthis.initEditView();\n\t}\n\n\tbuildEditViewUI() {\n\t\t// Builds the fields for Add and Edit, and partially for Requests. But fields for Messages and some of requests are done dynamically in setMessages (Both) and initEmbeddedMessageData (Request only)\n\n\t\tvar pager_data = this.navigation && this.navigation.getPagerData && this.navigation.getPagerData();\n\t\tvar source_data = this.navigation && this.navigation.getSourceData && this.navigation.getSourceData();\n\t\tsuper.buildEditViewUI();\n\t\tvar $this = this;\n\n\t\t// This is actually updated in switchMessageOrRequestWidgets depending on view type\n\t\tvar tab_model = {\n\t\t\t'tab_message': { \n\t\t\t\t'label': $.i18n._( 'Message' )\n\t\t\t}\n\t\t};\n\t\tthis.setTabModel( tab_model );\n\n\t\tif ( !this.edit_only_mode ) {\n\t\t\tthis.navigation.AComboBox( {\n\t\t\t\tapi_class: TTAPI.APIMessageControl,\n\t\t\t\tid: this.script_name + '_navigation',\n\t\t\t\tallow_multiple_selection: false,\n\t\t\t\tlayout_name: 'global_message_user',\n\t\t\t\tnavigation_mode: true,\n\t\t\t\tshow_search_inputs: true\n\t\t\t} );\n\t\t\tthis.setNavigation();\n\t\t}\n\n\t\tif ( pager_data && source_data ) {\n\t\t\tthis.navigation.setSourceData( source_data );\n\t\t\tthis.navigation.setPagerData( pager_data );\n\t\t}\n\n\t\t//Tab 0 start\n\n\t\tvar form_item_input;\n\n\t\tvar tab_message = this.edit_view_tab.find( '#tab_message' );\n\n\t\tvar tab_message_column1 = tab_message.find( '.first-column' );\n\n\t\tvar tab_message_column2 = tab_message.find( '.second-column' );\n\n\t\tthis.edit_view_tabs[0] = [];\n\n\t\tthis.edit_view_tabs[0].push( tab_message_column1 );\n\t\tthis.edit_view_tabs[0].push( tab_message_column2 );\n\t\ttab_message_column2.css( 'display', 'none' );\n\n\t\t// Now set the fields up\n\n\t\t// 'Message' fields\n\t\t// #2775 'Message' message threads fields now dynamically built on the fly in setMessages()\n\n\t\t// 'Request' fields\n\n\t\t// Employee\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT );\n\t\tform_item_input.TText( { field: 'full_name', selected_able: true } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Employee' ), form_item_input, tab_message_column1, '', null, true );\n\n\t\t// Date\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT );\n\t\tform_item_input.TText( { field: 'date_stamp', selected_able: true } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Date' ), form_item_input, tab_message_column1, '', null, true );\n\n\t\t// Type\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT );\n\t\tform_item_input.TText( { field: 'type', selected_able: true } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Type' ), form_item_input, tab_message_column1, '', null, true );\n\n\t\t// tab_message first column end\n\n\t\t// 'Request' Separated Box for 'Messages' Header\n\n\t\tvar separated_box = tab_message.find( '.separate' );\n\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.SEPARATED_BOX );\n\t\tform_item_input.SeparatedBox( { label: $.i18n._( 'Messages' ) } );\n\t\tthis.addEditFieldToColumn( null, form_item_input, separated_box, '', null, true, null, 'separated_box' );\n\n\t\t// #2775 Request message thread fields now generated by initEmbeddedMessageData() and setMessages()\n\n\t\t// Tab 0 second column end\n\n\t\t// 'New (add)' and 'Reply (edit)' fields\n\n\t\t// Employee - 'New' view\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );\n\t\tform_item_input.AComboBox( {\n\t\t\tapi_class: TTAPI.APIMessageControl,\n\t\t\tcolumn_option_key: 'user_columns',\n\t\t\tallow_multiple_selection: true,\n\t\t\tlayout_name: 'global_message_user',\n\t\t\tshow_search_inputs: true,\n\t\t\tset_empty: true,\n\t\t\tcustom_key_name: 'User',\n\t\t\tfield: 'to_user_id'\n\t\t} );\n\t\tvar default_args = {};\n\t\tdefault_args.permission_section = 'message';\n\t\tform_item_input.setDefaultArgs( default_args );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Employee(s)' ), form_item_input, tab_message_column1, '', null, true );\n\n\t\t// Employee(s) - 'Reply' view\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT );\n\t\tform_item_input.TText( { field: 'from_full_name' } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Employee(s)' ), form_item_input, tab_message_column1, '', null, true );\n\n\t\t// Subject - shared with the new/add & reply/edit view\n\t\t// Dev Note, in old reply view code, the width was passed as 359. Should that be incorporated here?\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\tform_item_input.TTextInput( { field: 'subject' } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Subject' ), form_item_input, tab_message_column1, '', null, true );\n\n\t\t// Body - shared with the new/add & reply/edit view\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_AREA );\n\t\tform_item_input.TTextArea( { field: 'body', width: 600, height: 400 } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Body' ), form_item_input, tab_message_column1, '', null, true, true );\n\t}\n\n\tsetEditViewWidgetsMode() {\n\t\tthis.switchMessageOrRequestWidgets();\n\t\tsuper.setEditViewWidgetsMode();\n\t}\n\n\tswitchMessageOrRequestWidgets() {\n\t\t// UI field building is done from buildEditViewUI(), and setMessages() for Messages and Requests (Also initEmbeddedMessageData).\n\t\t// This function shows/hides various fields depending on whether the view is displaying a message or request, to reduce re-building the form elements, instead simply hiding and showing the right ones.\n\t\tvar tab_label;\n\n\t\t// Detach all fields, further down we just attach the ones we need for the view\n\t\tfor ( var key in this.edit_view_ui_dic ) {\n\t\t\tif ( !this.edit_view_ui_dic.hasOwnProperty( key ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.detachElement( key );\n\t\t}\n\n\t\t// Detach the Request Messages header label box and hide parent container\n\t\tthis.detachElement( 'separated_box' );\n\n\t\t// Remove message list for both Message type and Request type - Message UI fields do not detach, we just remove them, as they are dynamically built on the fly.\n\t\tthis.edit_view_tab.find( '#tab_message' ).find( '.edit-view-tab .second-column.message-container' ).remove();\n\n\t\tif ( this.is_request ) {\n\t\t\ttab_label = 'Request';\n\t\t\tthis.attachElement( 'full_name' );\n\t\t\tthis.attachElement( 'date_stamp' );\n\t\t\tthis.attachElement( 'type' );\n\t\t\tthis.attachElement( 'separated_box' );\n\n\t\t\t// In show the main container which holds the fields.\n\t\t\tthis.edit_view_tab.find( '#tab_message' ).find( '.edit-view-tab .first-column' ).show();\n\n\t\t} else if ( this.is_message ) {\n\t\t\ttab_label = 'Message';\n\t\t\t// #2775 No longer attaching elements here, as the Messages fields are dynamically built in setMessages\n\n\t\t\t// Hide the first-column field, as this is not used by messages, but causes a border to be shown at the top. Hiding only here rather than at the top, to reduce flashing (if any)\n\t\t\tthis.edit_view_tab.find( '#tab_message' ).find( '.edit-view-tab .first-column' ).hide();\n\n\t\t} else if ( this.is_add ) {\n\t\t\ttab_label = 'New Message';\n\t\t\tthis.attachElement( 'to_user_id' );\n\t\t\tthis.attachElement( 'subject' );\n\t\t\tthis.attachElement( 'body' );\n\n\t\t\t// Show the main container which holds the fields.\n\t\t\tthis.edit_view_tab.find( '#tab_message' ).find( '.edit-view-tab .first-column' ).show();\n\n\t\t} else if ( this.is_edit ) {\n\t\t\ttab_label = 'Reply';\n\t\t\tthis.attachElement( 'from_full_name' );\n\t\t\tthis.attachElement( 'subject' );\n\t\t\tthis.attachElement( 'body' );\n\n\t\t\t// Show the main container which holds the fields.\n\t\t\tthis.edit_view_tab.find( '#tab_message' ).find( '.edit-view-tab .first-column' ).show();\n\t\t}\n\n\t\tvar tab_model = {\n\t\t\t'tab_message': { 'label': $.i18n._( tab_label ), 'is_multi_column': true }\n\t\t};\n\t\tthis.setTabModel( tab_model );\n\t}\n\n\trefreshCurrentRecord() {\n\t\tvar next_select_item = this.navigation.getItemByIndex( this.navigation.getSelectIndex() );\n\t\tProgressBar.showOverlay();\n\t\tthis.onViewClick( next_select_item ); //Dont refresh UI\n\t\tthis.setNavigationArrowsEnabled();\n\t}\n\n\tonRightOrLeftArrowClickCallBack( next_select_item ) {\n\t\tProgressBar.showOverlay();\n\t\tthis.onViewClick( next_select_item ); //Dont refresh UI\n\t\tthis.setNavigationArrowsEnabled();\n\t}\n\n\tonAddClick() {\n\n\t\tTTPromise.add( 'Message', 'add' );\n\t\tTTPromise.wait();\n\t\tvar $this = this;\n\t\tthis.is_viewing = false;\n\t\tthis.is_edit = false;\n\t\tthis.is_add = true;\n\t\tthis.isReloadViewUI = false;\n\t\tLocalCacheData.current_doing_context_action = 'new';\n\t\tthis.is_request = false;\n\t\tthis.is_message = false;\n\t\t$this.openEditView();\n\n\t\tvar result_data = {};\n\t\tif ( LocalCacheData.default_filter_for_next_open_view ) {\n\t\t\tresult_data.to_user_id = LocalCacheData.default_filter_for_next_open_view.to_user_id;\n\t\t\tLocalCacheData.default_filter_for_next_open_view = null;\n\t\t}\n\t\t$this.current_edit_record = result_data;\n\t\t$this.initEditView();\n\t}\n\n\tinitEditView() {\n\t\tsuper.initEditView();\n\t\tTTPromise.resolve( 'Message', 'add' );\n\t}\n\n\tsetEditMenuAddIcon( context_btn ) {\n\t\tif ( this.edit_only_mode ) {\n\t\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t\tif ( this.is_add || this.is_changed ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t} else {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t\t}\n\t}\n\n\tsetEditMenuEditIcon( context_btn ) {\n\t\tif ( this.edit_only_mode ) {\n\t\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t\tif ( !this.is_viewing ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetEditMenuDeleteIcon( context_btn ) {\n\t\tif ( this.edit_only_mode ) {\n\t\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t\tif ( !this.current_select_message_control_data ||\n\t\t\tthis.is_edit ||\n\t\t\tthis.is_add ) {\n\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetEditMenuDeleteAndNextIcon( context_btn ) {\n\t\tif ( this.edit_only_mode ) {\n\t\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t\tif ( !this.current_select_message_control_data ||\n\t\t\tthis.is_edit ||\n\t\t\tthis.is_add ) {\n\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tvalidate() {\n\n\t\tvar $this = this;\n\n\t\tvar record = this.current_edit_record;\n\n\t\tif ( Global.isSet( this.edit_view_ui_dic['subject'] ) ) {\n\t\t\trecord.subject = this.edit_view_ui_dic['subject'].getValue();\n\t\t} else if ( Global.isSet( this.edit_view_ui_dic['message_subject'] ) ) {\n\t\t\trecord.subject = this.edit_view_ui_dic['message_subject'].getValue();\n\t\t} else if ( Global.isSet( this.edit_view_ui_dic['request_subject'] ) ) {\n\t\t\trecord.subject = this.edit_view_ui_dic['request_subject'].getValue();\n\t\t}\n\t\trecord = this.uniformVariable( record );\n\n\t\tthis.api['validate' + this.api.key_name]( record, {\n\t\t\tonResult: function( result ) {\n\t\t\t\t$this.validateResult( result );\n\n\t\t\t}\n\t\t} );\n\t}\n\n\tonSaveClick( ignoreWarning ) {\n\t\tLocalCacheData.current_doing_context_action = 'save';\n\t\tthis.collectUIDataToCurrentEditRecord();\n\t\tvar record = this.current_edit_record;\n\t\tif ( !Global.isSet( ignoreWarning ) ) {\n\t\t\tignoreWarning = false;\n\t\t}\n\t\tif ( Global.isSet( this.edit_view_ui_dic['subject'] ) ) {\n\t\t\trecord.subject = this.edit_view_ui_dic['subject'].getValue();\n\t\t} else if ( Global.isSet( this.edit_view_ui_dic['message_subject'] ) ) {\n\t\t\trecord.subject = this.edit_view_ui_dic['message_subject'].getValue();\n\t\t} else if ( Global.isSet( this.edit_view_ui_dic['request_subject'] ) ) {\n\t\t\trecord.subject = this.edit_view_ui_dic['request_subject'].getValue();\n\t\t}\n\t\trecord = this.uniformVariable( record );\n\n\t\tthis.doSaveAPICall( record, ignoreWarning );\n\t}\n\n\tuniformVariable( records ) {\n\t\tvar reply_data = {};\n\n\t\tif ( this.is_edit ) {\n\n\t\t\treply_data.subject = records.subject;\n\t\t\treply_data.body = records.body;\n\n\t\t\t// message\n\t\t\tif ( records.object_type_id != 50 ) {\n\t\t\t\treply_data.to_user_id = records.from_user_id;\n\t\t\t\treply_data.object_type_id = 5;\n\t\t\t\treply_data.object_id = LocalCacheData.loginUser.id;\n\t\t\t\treply_data.parent_id = records.id;\n\n\t\t\t} else {\n\t\t\t\t// request\n\n\t\t\t\treply_data.object_id = records.object_id;\n\n\t\t\t\treply_data.to_user_id = LocalCacheData.loginUser.id;\n\t\t\t\treply_data.object_type_id = 50;\n\n\t\t\t\treply_data.parent_id = 1;\n\t\t\t}\n\n\t\t\treturn reply_data;\n\n\t\t}\n\n\t\tif ( this.is_add ) {\n\t\t\trecords.object_type_id = 5;\n\t\t\trecords.object_id = LocalCacheData.loginUser.id;\n\t\t\trecords.parent_id = 0;\n\t\t}\n\n\t\treturn records;\n\t}\n\n\tsearch( set_default_menu, page_action, page_number, callBack ) {\n\t\tthis.event_bus.emit( 'tt_topbar', 'profile_pending_counts', { //Update all \"My Profile\" badge.\n\t\t\tobject_types: [ 'notification', 'message' ]\n\t\t} );\n\t\tsuper.search( set_default_menu, page_action, page_number, callBack );\n\t}\n\n\t/* jshint ignore:start */\n\tsetCurrentEditRecordData() {\n\t\tvar $this = this;\n\t\t// If the current_edit_record is an array, then handle them in setEditViewDataDone function.\n\t\t// if ( Global.isArray( this.current_edit_record ) ) { // Commenting out to trial whether single messages can go through this too.\n\t\tif ( this.is_message ) {\n\t\t\tthis.setMessages();\n\t\t} else {\n\t\t\t// TODO: Figure out where to trigger the uniformVariable work on splitting out the subject and body for msg/req stuff. Here or in above section, as multiple messages go elsewhere???\n\n\t\t\t//Set current edit record data to all widgets\n\t\t\tfor ( var key in this.current_edit_record ) {\n\t\t\t\tif ( !this.current_edit_record.hasOwnProperty( key ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tvar widget = this.edit_view_ui_dic[key];\n\t\t\t\tif ( Global.isSet( widget ) ) {\n\t\t\t\t\t// Now that all messages go through setMessages() and no longer through the below, we can remove some of the fields below. Not done yet as theres Add/Edit to consider and test first.\n\t\t\t\t\tswitch ( key ) {\n\t\t\t\t\t\tcase 'from_full_name':\n\t\t\t\t\t\t\twidget.setValue( this.current_edit_record['from_first_name'] + ' ' + this.current_edit_record['from_last_name'] );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'to_full_name':\n\t\t\t\t\t\t\twidget.setValue( this.current_edit_record['to_first_name'] + ' ' + this.current_edit_record['to_last_name'] );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'full_name':\n\t\t\t\t\t\t\twidget.setValue( this.current_edit_record['first_name'] + ' ' + this.current_edit_record['last_name'] );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'subject':\n\t\t\t\t\t\t\tif ( this.is_edit ) {\n\t\t\t\t\t\t\t\tif ( Global.isArray( this.messages ) ) {\n\t\t\t\t\t\t\t\t\twidget.setValue( 'Re: ' + this.messages[0].subject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\twidget.setValue( 'Re: ' + this.current_edit_record[key] );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else if ( this.is_viewing ) {\n\t\t\t\t\t\t\t\twidget.setValue( this.current_edit_record[key] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'message_body':\n\t\t\t\t\t\tcase 'request_body':\n\t\t\t\t\t\t\twidget.setValue( this.current_edit_record[key] );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\twidget.setValue( this.current_edit_record[key] );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t//request will do this when initEmbeddedMessage\n\t\t\tif ( this.is_message && this.current_edit_record && this.current_edit_record.status_id == 10 ) {\n\t\t\t\tthis.api['markRecipientMessageAsRead']( [this.current_edit_record.id], {\n\t\t\t\t\tonResult: function( res ) {\n\t\t\t\t\t\t$this.search( false );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\tthis.collectUIDataToCurrentEditRecord(); // #2775 If Messages then, we do not want to store any ui fields to current_edit_record. Its view only, and we dont have references to each generated message anyway, as they generate on the fly.\n\t\t}\n\t\tthis.setEditViewDataDone(); // 2775 notes: also trigger more data/widget handling for request (SINGLE+MULTIPLE)\n\t}\n\n\t/* jshint ignore:end */\n\tautoOpenEditViewIfNecessary() {\n\t\t//Auto open edit view. Should set in IndexController\n\n\t\tswitch ( LocalCacheData.current_doing_context_action ) {\n\t\t\tcase 'view':\n\t\t\t\tif ( LocalCacheData.edit_id_for_next_open_view ) {\n\t\t\t\t\tvar item = {};\n\t\t\t\t\titem.id = LocalCacheData.edit_id_for_next_open_view;\n\t\t\t\t\tif ( LocalCacheData.getAllURLArgs().t === 'request' ) {\n\t\t\t\t\t\titem.object_id = LocalCacheData.getAllURLArgs().object_id;\n\t\t\t\t\t\titem.object_type_id = 50;\n\t\t\t\t\t}\n\t\t\t\t\tthis.onViewClick( item );\n\t\t\t\t\tLocalCacheData.edit_id_for_next_open_view = null;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'new':\n\t\t\t\tthis.onAddClick();\n\t\t\t\tbreak;\n\t\t}\n\n\t\tthis.autoOpenEditOnlyViewIfNecessary();\n\t}\n\n\tgetDeleteSelectedRecordId() {\n\t\tvar retval = [];\n\t\tif ( this.edit_view ) {\n\t\t\tif ( !this.current_select_message_control_data ) {\n\t\t\t\tTAlertManager.showAlert( $.i18n._( 'Invalid Message id' ) );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tretval.push( this.current_select_message_control_data.id );\n\t\t} else {\n\t\t\tretval = super.getDeleteSelectedRecordId();\n\t\t}\n\t\treturn retval;\n\t}\n\n\tdoDeleteAPICall( remove_ids, _callback ) {\n\t\tvar callback = _callback || {\n\t\t\tonResult: function( result ) {\n\t\t\t\tthis.isReloadViewUI = false;\n\t\t\t\tthis.onDeleteResult( result, remove_ids );\n\t\t\t}.bind( this )\n\t\t};\n\t\treturn this.api['delete' + this.api.key_name]( remove_ids, this.folder_id, callback );\n\t}\n\n\tsetEditViewDataDone() {\n\t\t// TODO: Refactor this to move into setCurrentEditRecordData, as this is not code that is classed as Data Load Done, its still data loading.\n\t\tvar $this = this;\n\t\tsuper.setEditViewDataDone();\n\n\t\tif ( this.is_viewing ) {\n\n\t\t\tif ( this.is_request ) {\n\t\t\t\tthis.initEmbeddedMessageData();\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tif ( Global.isSet( $this.messages ) ) {\n\t\t\t\t$this.messages = null;\n\t\t\t}\n\t\t}\n\t}\n\n\tsetMessages( message_data ) {\n\t\t// This function handles message thread generation for both the message and request types.\n\t\tvar read_ids = [];\n\n\t\tif ( message_data ) {\n\t\t\tthis.messages = message_data;\n\t\t} else {\n\t\t\tthis.messages = this.current_edit_record;\n\t\t}\n\n\t\tif ( !Global.isArray( this.messages ) ) {\n\t\t\t// This function works on an array of messages. If there is only one message, then provide an array of one message and process the same way.\n\t\t\tthis.messages = [this.messages];\n\t\t}\n\n\t\t// Remove all old messages first.\n\t\tthis.edit_view_tab.find( '#tab_message' ).find( '.edit-view-tab .second-column.message-container' ).remove();\n\n\t\t/*\n\t\t * Loop through and create the message fields\n\t\t */\n\n\t\t// Collection container for the messages to be held in, until they are added in one go to the page.\n\t\tvar container = $( '<div></div>' );\n\n\t\tfor ( var key = 0; key < this.messages.length; key++ ) {\n\n\t\t\tvar current_item = this.messages[key];\n\t\t\tif ( !current_item.hasOwnProperty( 'id' ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( current_item.status_id == 10 ) {\n\t\t\t\tread_ids.push( current_item.id );\n\t\t\t}\n\n\t\t\tvar message_container = $( '<div></div>', { class: \"second-column full-width-column message-container\" } );\n\n\t\t\tif ( this.is_message ) {\n\t\t\t\tthis.addMessageRow( message_container, 'From', 'msg_from_full_name', current_item['from_first_name'] + ' ' + current_item['from_last_name'] );\n\t\t\t\tthis.addMessageRow( message_container, 'To', 'msg_to_full_name', current_item['to_first_name'] + ' ' + current_item['to_last_name'] );\n\t\t\t\tthis.addMessageRow( message_container, 'Date', 'msg_updated_date', current_item['updated_date'] );\n\t\t\t\tthis.addMessageRow( message_container, 'Subject', 'msg_subject', current_item['subject'] );\n\t\t\t\tthis.addMessageRow( message_container, 'Body', 'msg_body', current_item['body'], true, true );\n\n\t\t\t} else if ( this.is_request ) {\n\t\t\t\tthis.addMessageRow( message_container, 'From', 'req_from_full_name', current_item['from_first_name'] + ' ' + current_item['from_last_name'] + '@' + current_item['updated_date'] );\n\t\t\t\tthis.addMessageRow( message_container, 'Subject', 'req_subject', current_item['subject'] );\n\t\t\t\tthis.addMessageRow( message_container, 'Body', 'req_body', current_item['body'], true, true );\n\n\t\t\t} else {\n\t\t\t\t// Error: Message type not supported. Exit. Currently only messages and request types supported.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcontainer.append( message_container );\n\t\t}\n\n\t\t// Add the new message to the page\n\t\tthis.edit_view_tab.find( '#tab_message' ).find( '.edit-view-tab' ).append( container.html() );\n\n\t\tif ( read_ids.length > 0 ) {\n\t\t\tvar $this = this;\n\t\t\tthis.api['markRecipientMessageAsRead']( read_ids, {\n\t\t\t\tonResult: function( res ) {\n\t\t\t\t\t$this.search( false );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\taddMessageRow( message_container, label, field, value, set_resize_event, parse_link ) {\n\t\t// Note: Take extra care with this function, as we are building widgets outside of the normal init flow, so compare to the standard flow of buildEditViewUI if anything odd happens.\n\n\t\tvar form_item_input = Global.loadWidgetByName( FormItemType.TEXT );\n\t\tform_item_input.TText( { field: field, selected_able: true } );\n\t\tthis.addEditFieldToColumn( $.i18n._( label ), form_item_input, message_container, '', null, null, set_resize_event );\n\n\t\t// #2775 You must set the value after its added to column, not before, otherwise the field label will not resize after a large value is set.\n\n\t\tif ( parse_link ) {\n\t\t\tform_item_input.html( value.linkify( { nl2br: true, className: 'linkified' } ) );\n\t\t\tform_item_input.setResizeEvent();\n\t\t} else {\n\t\t\tform_item_input.setValue( value );\n\t\t}\n\n\t\t// #2775 You must set the opacity to 1 after adding to column, as the addEditFieldToColumn sets opacity to 0 during loading, and normally set back to 1 at the bottom of BaseVC.initEditViewData but here we are building widgets outside of the normal init flow.\n\t\tform_item_input.css( 'opacity', '1' );\n\n\t\t// remove the field reference from this.edit_view_ui_dic as we wont track the on-the-fly built fields.\n\t\tdelete this.edit_view_ui_dic[field];\n\t}\n\n\tinitEmbeddedMessageData() {\n\t\t// Used to generate the message threads for a Request type\n\t\tvar $this = this;\n\t\tvar args = {};\n\t\targs.filter_data = {};\n\t\targs.filter_data.object_type_id = 50;\n\t\targs.filter_data.object_id = this.current_edit_record.id;\n\n\t\t$this.api['getEmbeddedMessage']( args, {\n\t\t\tonResult: function( res ) {\n\n\t\t\t\tif ( !$this.edit_view ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar data = res.getResult();\n\t\t\t\t$this.setMessages( data );\n\t\t\t}\n\t\t} );\n\t}\n\n\t// #2775 Commenting out to fix an issue where Delete&Next does not go to the next record. Not 100% certain why this is here, but annotations show something to do with flashing, which does not seem an issue atm.\n\t// /* jshint ignore:start */\n\t// search: function( set_default_menu, page_action, page_number, callBack ) {\n\t// \tthis.refresh_id = null;\n\t// \tsuper.search( set_default_menu, page_action, page_number, callBack );\n\t// }\n\t//\n\t// /* jshint ignore:end */\n\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDQ2OC5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUEwQzs7QUFFbkM7QUFDUCwyQkFBMkI7QUFDM0IsRUFBRSxDQUFDO0FBQ0g7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBLElBQUk7O0FBRUo7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixDQUFDO0FBQzVCO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxzQkFBc0I7O0FBRTFEO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsV0FBVyxDQUFDO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLFdBQVcsQ0FBQztBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLFdBQVcsQ0FBQztBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQSxXQUFXLENBQUM7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLFdBQVcsQ0FBQztBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxDQUFDO0FBQ2I7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLFlBQVksQ0FBQztBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsWUFBWSxDQUFDO0FBQ2I7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLFlBQVksQ0FBQztBQUNiO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLFlBQVksQ0FBQztBQUNiO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLFlBQVksQ0FBQztBQUNiO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxZQUFZLENBQUM7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLFlBQVksQ0FBQztBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLFlBQVksQ0FBQztBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLFlBQVksQ0FBQztBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsbUJBQW1CLFNBQVM7O0FBRTVCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTCxJQUFJO0FBQ0o7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBOztBQUVBLEdBQUcsQ0FBQztBQUNKO0FBQ0EsS0FBSzs7QUFFTCxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLG1CQUFtQixTQUFTO0FBQzVCOztBQUVBO0FBQ0EsSUFBSSxDQUFDO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsb0JBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsQ0FBQztBQUNwQix1QkFBdUIsQ0FBQztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBLDJCQUEyQixDQUFDO0FBQzVCLElBQUk7QUFDSiwyQkFBMkIsQ0FBQztBQUM1Qjs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkI7O0FBRTNCLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxtQkFBbUI7O0FBRW5CO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0JBQWtCLGVBQWU7QUFDakMsb0VBQW9FLGVBQWU7O0FBRW5GO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0Esd0VBQXdFLGdDQUFnQztBQUN4RztBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDRDQUE0QztBQUM1QyxNQUFNO0FBQ04sNENBQTRDO0FBQzVDOztBQUVBOztBQUVBOztBQUVBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUksT0FBTztBQUNYO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLENBQUM7QUFDZDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSwyQkFBMkIsMENBQTBDO0FBQ3JFLDZCQUE2QixDQUFDOztBQUU5QjtBQUNBO0FBQ0EsMkJBQTJCLDJDQUEyQztBQUN0RSw2QkFBNkIsQ0FBQzs7QUFFOUI7QUFDQTtBQUNBLDJCQUEyQixxQ0FBcUM7QUFDaEUsNkJBQTZCLENBQUM7O0FBRTlCOztBQUVBOztBQUVBOztBQUVBO0FBQ0Esa0NBQWtDLE9BQU8sQ0FBQyx3QkFBd0I7QUFDbEU7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsQ0FBQzs7QUFFOUI7QUFDQTtBQUNBLDJCQUEyQiwwQkFBMEI7QUFDckQsNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxtQkFBbUI7QUFDbkQsNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7QUFDQSwrQkFBK0IseUNBQXlDO0FBQ3hFLDZCQUE2QixDQUFDO0FBQzlCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvQkFBb0IsU0FBUyxDQUFDO0FBQzlCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0M7QUFDeEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0NBQXdDO0FBQ3hDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGdFQUFnRTtBQUNoRTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUEsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBLDRDQUE0QztBQUM1QztBQUNBLDhCQUE4QjtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLENBQUM7QUFDOUI7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixDQUFDOztBQUVuQixxQkFBcUIsNEJBQTRCOztBQUVqRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsMkJBQTJCLENBQUMsbUJBQW1CLDZEQUE2RDs7QUFFNUc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQixvQ0FBb0M7QUFDL0QsNkJBQTZCLENBQUM7O0FBRTlCOztBQUVBO0FBQ0EsMENBQTBDLHNDQUFzQztBQUNoRjtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L3ZpZXdzL215X2FjY291bnQvbWVzc2FnZV9jb250cm9sL01lc3NhZ2VDb250cm9sVmlld0NvbnRyb2xsZXIuanM/NDU0MyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbGlua2lmeVN0ciBmcm9tICdsaW5raWZ5anMvc3RyaW5nJztcblxuZXhwb3J0IGNsYXNzIE1lc3NhZ2VDb250cm9sVmlld0NvbnRyb2xsZXIgZXh0ZW5kcyBCYXNlVmlld0NvbnRyb2xsZXIge1xuXHRjb25zdHJ1Y3Rvciggb3B0aW9ucyA9IHt9ICkge1xuXHRcdF8uZGVmYXVsdHMoIG9wdGlvbnMsIHtcblx0XHRcdGVsOiAnI21lc3NhZ2VfY29udHJvbF92aWV3X2NvbnRhaW5lcicsXG5cblx0XHRcdG9iamVjdF90eXBlX2FycmF5OiBudWxsLFxuXG5cdFx0XHRpc19yZXF1ZXN0OiBmYWxzZSxcblx0XHRcdGlzX21lc3NhZ2U6IGZhbHNlLFxuXG5cdFx0XHRtZXNzYWdlczogbnVsbCxcblx0XHRcdHJlcXVlc3RfYXBpOiBudWxsLFxuXG5cdFx0XHRmb2xkZXJfaWQ6IG51bGwsXG5cblx0XHRcdG5hdmlnYXRpb25fc291cmNlX2RhdGE6IG51bGwsXG5cblx0XHRcdGlzUmVsb2FkVmlld1VJOiBmYWxzZSxcblxuXHRcdFx0Y3VycmVudF9zZWxlY3RfbWVzc2FnZV9jb250cm9sX2RhdGE6IG51bGwsIC8vY3VycmVudCBzZWxlY3QgbWVzc2FnZSBjb250cm9sIGRhdGEsIHNldCBpbiBvblZpZXdDbGlja1xuXG5cdFx0fSApO1xuXG5cdFx0c3VwZXIoIG9wdGlvbnMgKTtcblx0fVxuXG5cdGluaXQoIG9wdGlvbnMgKSB7XG5cdFx0Ly90aGlzLl9zdXBlcignaW5pdGlhbGl6ZScsIG9wdGlvbnMgKTtcblx0XHR0aGlzLmVkaXRfdmlld190cGwgPSAnTWVzc2FnZUNvbnRyb2xFZGl0Vmlldy5odG1sJztcblx0XHR0aGlzLnBlcm1pc3Npb25faWQgPSAnbWVzc2FnZSc7XG5cdFx0dGhpcy52aWV3SWQgPSAnTWVzc2FnZUNvbnRyb2wnO1xuXHRcdHRoaXMuc2NyaXB0X25hbWUgPSAnTWVzc2FnZUNvbnRyb2xWaWV3Jztcblx0XHR0aGlzLnRhYmxlX25hbWVfa2V5ID0gJ21lc3NhZ2VfY29udHJvbCc7XG5cdFx0dGhpcy5jb250ZXh0X21lbnVfbmFtZSA9ICQuaTE4bi5fKCAnTWVzc2FnZScgKTtcblx0XHR0aGlzLmFwaSA9IFRUQVBJLkFQSU1lc3NhZ2VDb250cm9sO1xuXHRcdHRoaXMucmVxdWVzdF9hcGkgPSBUVEFQSS5BUElSZXF1ZXN0O1xuXHRcdHRoaXMuZm9sZGVyX2lkID0gMTA7XG5cdFx0dGhpcy5ldmVudF9idXMgPSBuZXcgVFRFdmVudEJ1cyh7IHZpZXdfaWQ6IHRoaXMudmlld0lkIH0pO1xuXG5cdFx0dGhpcy5yZW5kZXIoKTtcblx0XHR0aGlzLmJ1aWxkQ29udGV4dE1lbnUoKTtcblxuXHRcdHRoaXMuaW5pdERhdGEoKTtcblx0fVxuXG5cdGluaXRPcHRpb25zKCkge1xuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cblx0XHR0aGlzLmluaXREcm9wRG93bk9wdGlvbiggJ29iamVjdF90eXBlJyApO1xuXHR9XG5cblx0YnVpbGRTZWFyY2hGaWVsZHMoKSB7XG5cblx0XHRzdXBlci5idWlsZFNlYXJjaEZpZWxkcygpO1xuXG5cdFx0dmFyIGRlZmF1bHRfYXJncyA9IHt9O1xuXHRcdGRlZmF1bHRfYXJncy5wZXJtaXNzaW9uX3NlY3Rpb24gPSAnbWVzc2FnZSc7XG5cdFx0dGhpcy5zZWFyY2hfZmllbGRzID0gW1xuXG5cdFx0XHRuZXcgU2VhcmNoRmllbGQoIHtcblx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnRW1wbG95ZWUnICksXG5cdFx0XHRcdGluX2NvbHVtbjogMSxcblx0XHRcdFx0ZmllbGQ6ICd1c2VyX2lkJyxcblx0XHRcdFx0ZGVmYXVsdF9hcmdzOiBkZWZhdWx0X2FyZ3MsXG5cdFx0XHRcdGxheW91dF9uYW1lOiAnZ2xvYmFsX3VzZXInLFxuXHRcdFx0XHRhcGlfY2xhc3M6IFRUQVBJLkFQSVVzZXIsXG5cdFx0XHRcdG11bHRpcGxlOiB0cnVlLFxuXHRcdFx0XHRiYXNpY19zZWFyY2g6IHRydWUsXG5cdFx0XHRcdGFkdl9zZWFyY2g6IGZhbHNlLFxuXHRcdFx0XHRmb3JtX2l0ZW1fdHlwZTogRm9ybUl0ZW1UeXBlLkFXRVNPTUVfQk9YXG5cdFx0XHR9ICksXG5cblx0XHRcdG5ldyBTZWFyY2hGaWVsZCgge1xuXHRcdFx0XHRsYWJlbDogJC5pMThuLl8oICdUeXBlJyApLFxuXHRcdFx0XHRpbl9jb2x1bW46IDEsXG5cdFx0XHRcdG11bHRpcGxlOiB0cnVlLFxuXHRcdFx0XHRmaWVsZDogJ29iamVjdF90eXBlX2lkJyxcblx0XHRcdFx0YmFzaWNfc2VhcmNoOiB0cnVlLFxuXHRcdFx0XHRhZHZfc2VhcmNoOiBmYWxzZSxcblx0XHRcdFx0bGF5b3V0X25hbWU6ICdnbG9iYWxfb3B0aW9uX2NvbHVtbicsXG5cdFx0XHRcdGZvcm1faXRlbV90eXBlOiBGb3JtSXRlbVR5cGUuQVdFU09NRV9CT1hcblx0XHRcdH0gKSxcblxuXHRcdFx0bmV3IFNlYXJjaEZpZWxkKCB7XG5cdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ1N1YmplY3QnICksXG5cdFx0XHRcdGluX2NvbHVtbjogMSxcblx0XHRcdFx0ZmllbGQ6ICdzdWJqZWN0Jyxcblx0XHRcdFx0bXVsdGlwbGU6IHRydWUsXG5cdFx0XHRcdGJhc2ljX3NlYXJjaDogdHJ1ZSxcblx0XHRcdFx0YWR2X3NlYXJjaDogZmFsc2UsXG5cdFx0XHRcdGZvcm1faXRlbV90eXBlOiBGb3JtSXRlbVR5cGUuVEVYVF9JTlBVVFxuXHRcdFx0fSApLFxuXG5cdFx0XHRuZXcgU2VhcmNoRmllbGQoIHtcblx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnQ3JlYXRlZCBCeScgKSxcblx0XHRcdFx0aW5fY29sdW1uOiAyLFxuXHRcdFx0XHRmaWVsZDogJ2NyZWF0ZWRfYnknLFxuXHRcdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF91c2VyJyxcblx0XHRcdFx0YXBpX2NsYXNzOiBUVEFQSS5BUElVc2VyLFxuXHRcdFx0XHRtdWx0aXBsZTogdHJ1ZSxcblx0XHRcdFx0YmFzaWNfc2VhcmNoOiB0cnVlLFxuXHRcdFx0XHRhZHZfc2VhcmNoOiBmYWxzZSxcblx0XHRcdFx0Zm9ybV9pdGVtX3R5cGU6IEZvcm1JdGVtVHlwZS5BV0VTT01FX0JPWFxuXHRcdFx0fSApLFxuXG5cdFx0XHRuZXcgU2VhcmNoRmllbGQoIHtcblx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnVXBkYXRlZCBCeScgKSxcblx0XHRcdFx0aW5fY29sdW1uOiAyLFxuXHRcdFx0XHRmaWVsZDogJ3VwZGF0ZWRfYnknLFxuXHRcdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF91c2VyJyxcblx0XHRcdFx0YXBpX2NsYXNzOiBUVEFQSS5BUElVc2VyLFxuXHRcdFx0XHRtdWx0aXBsZTogdHJ1ZSxcblx0XHRcdFx0YmFzaWNfc2VhcmNoOiB0cnVlLFxuXHRcdFx0XHRhZHZfc2VhcmNoOiBmYWxzZSxcblx0XHRcdFx0Zm9ybV9pdGVtX3R5cGU6IEZvcm1JdGVtVHlwZS5BV0VTT01FX0JPWFxuXHRcdFx0fSApXG5cdFx0XTtcblx0fVxuXG5cdGdldFN1YlZpZXdGaWx0ZXIoIGZpbHRlciApIHtcblxuXHRcdGlmICggZmlsdGVyLmxlbmd0aCA9PT0gMCApIHtcblx0XHRcdGZpbHRlciA9IHt9O1xuXHRcdH1cblxuXHRcdGZpbHRlclsnZm9sZGVyX2lkJ10gPSB0aGlzLmZvbGRlcl9pZDtcblxuXHRcdHJldHVybiBmaWx0ZXI7XG5cdH1cblxuXHRnZXRDdXN0b21Db250ZXh0TWVudU1vZGVsKCkge1xuXHRcdHZhciBjb250ZXh0X21lbnVfbW9kZWwgPSB7XG5cdFx0XHRleGNsdWRlOiBbJ2RlZmF1bHQnXSxcblx0XHRcdGluY2x1ZGU6IFtcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ05ldycgKSxcblx0XHRcdFx0XHRpZDogJ2FkZCcsXG5cdFx0XHRcdFx0dnVlX2ljb246ICd0dGljb24gdHRpY29uLWFkZF9ibGFja18yNGRwJ1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnVmlldycgKSxcblx0XHRcdFx0XHRpZDogJ3ZpZXcnLFxuXHRcdFx0XHRcdHZ1ZV9pY29uOiAndHRpY29uIHR0aWNvbi12aXNpYmlsaXR5X2JsYWNrXzI0ZHAnLFxuXHRcdFx0XHRcdHNob3dfb25fcmlnaHRfY2xpY2s6IHRydWUsXG5cdFx0XHRcdFx0c29ydF9vcmRlcjogMTAxMFxuXHRcdFx0XHR9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnUmVwbHknICksXG5cdFx0XHRcdFx0aWQ6ICdlZGl0Jyxcblx0XHRcdFx0XHR2dWVfaWNvbjogJ3R0aWNvbiB0dGljb24tcmVwbHlfYmxhY2tfMjRkcCdcblx0XHRcdFx0fSxcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ0RlbGV0ZScgKSxcblx0XHRcdFx0XHRpZDogJ2RlbGV0ZV9pY29uJyxcblx0XHRcdFx0XHRhY3Rpb25fZ3JvdXA6ICdkZWxldGUnLFxuXHRcdFx0XHRcdHZ1ZV9pY29uOiAndHRpY29uIHR0aWNvbi1kZWxldGVfYmxhY2tfMjRkcCdcblx0XHRcdFx0fSxcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ0RlbGV0ZSAmIE5leHQnICksXG5cdFx0XHRcdFx0aWQ6ICdkZWxldGVfYW5kX25leHQnLFxuXHRcdFx0XHRcdGFjdGlvbl9ncm91cDogJ2RlbGV0ZScsXG5cdFx0XHRcdFx0dnVlX2ljb246ICd0dGljb24gdHRpY29uLWRlbGV0ZV9ibGFja18yNGRwJ1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnU2VuZCcgKSxcblx0XHRcdFx0XHRpZDogJ3NlbmQnLFxuXHRcdFx0XHRcdHZ1ZV9pY29uOiAndHRpY29uIHR0aWNvbi1zZW5kX2JsYWNrXzI0ZHAnXG5cdFx0XHRcdH0sXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRsYWJlbDogJC5pMThuLl8oICdDYW5jZWwnICksXG5cdFx0XHRcdFx0aWQ6ICdjYW5jZWwnLFxuXHRcdFx0XHRcdHBlcm1pc3Npb25fcmVzdWx0OiB0cnVlLFxuXHRcdFx0XHRcdHBlcm1pc3Npb246IG51bGwsXG5cdFx0XHRcdFx0c29ydF9vcmRlcjogMTk5MFxuXHRcdFx0XHR9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnRm9sZGVyOiBJbmJveCcgKSxcblx0XHRcdFx0XHRpZDogJ2luYm94Jyxcblx0XHRcdFx0XHRhY3Rpb25fZ3JvdXA6ICdtZXNzYWdlX3R5cGUnLFxuXHRcdFx0XHRcdG11bHRpX3NlbGVjdF9ncm91cDogMSxcblx0XHRcdFx0XHRzZWxlY3RlZDogdHJ1ZSxcblx0XHRcdFx0XHRwZXJtaXNzaW9uX3Jlc3VsdDogdHJ1ZSxcblx0XHRcdFx0XHRwZXJtaXNzaW9uOiBudWxsXG5cdFx0XHRcdH0sXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRsYWJlbDogJC5pMThuLl8oICdGb2xkZXI6IFNlbnQnICksXG5cdFx0XHRcdFx0aWQ6ICdzZW50Jyxcblx0XHRcdFx0XHRhY3Rpb25fZ3JvdXA6ICdtZXNzYWdlX3R5cGUnLFxuXHRcdFx0XHRcdG11bHRpX3NlbGVjdF9ncm91cDogMSxcblx0XHRcdFx0XHRzZWxlY3RlZDogZmFsc2UsXG5cdFx0XHRcdFx0cGVybWlzc2lvbl9yZXN1bHQ6IHRydWUsXG5cdFx0XHRcdFx0cGVybWlzc2lvbjogbnVsbFxuXHRcdFx0XHR9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnRXhwb3J0JyApLFxuXHRcdFx0XHRcdGlkOiAnZXhwb3J0X2V4Y2VsJyxcblx0XHRcdFx0XHR2dWVfaWNvbjogJ3R0aWNvbiB0dGljb24tZmlsZV91cGxvYWRfYmxhY2tfMjRkcCcsXG5cdFx0XHRcdFx0bWVudV9hbGlnbjogJ3JpZ2h0Jyxcblx0XHRcdFx0XHRwZXJtaXNzaW9uX3Jlc3VsdDogdHJ1ZSxcblx0XHRcdFx0XHRwZXJtaXNzaW9uOiBudWxsLFxuXHRcdFx0XHRcdHNvcnRfb3JkZXI6IDkwMDBcblx0XHRcdFx0fVxuXHRcdFx0XVxuXHRcdH07XG5cblx0XHRyZXR1cm4gY29udGV4dF9tZW51X21vZGVsO1xuXHR9XG5cblx0c2V0Q3VzdG9tRGVmYXVsdE1lbnVJY29uKCBpZCwgY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICkge1xuXHRcdHN3aXRjaCAoIGlkICkge1xuXHRcdFx0Y2FzZSAnY2xvc2VfbWlzYyc6XG5cdFx0XHRcdHRoaXMuc2V0RGVmYXVsdE1lbnVDbG9zZU1pc2NJY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGggKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdzZW5kJzpcblx0XHRcdFx0dGhpcy5zZXREZWZhdWx0TWVudVNlbmRJY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGggKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdjYW5jZWwnOlxuXHRcdFx0XHR0aGlzLnNldERlZmF1bHRNZW51Q2FuY2VsSWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnaW5ib3gnOlxuXHRcdFx0XHRpZiAoIHRoaXMuZm9sZGVyX2lkID09PSAxMCAgKSB7XG5cdFx0XHRcdFx0dGhpcy5zZXRDdXJyZW50U2VsZWN0ZWRJY29uKCBjb250ZXh0X2J0biApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMuc2V0RGVmYXVsdE1lbnVJbmJveEljb24oIGNvbnRleHRfYnRuLCBncmlkX3NlbGVjdGVkX2xlbmd0aCApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ3NlbnQnOlxuXHRcdFx0XHRpZiAoIHRoaXMuZm9sZGVyX2lkID09PSAyMCAgKSB7XG5cdFx0XHRcdFx0dGhpcy5zZXRDdXJyZW50U2VsZWN0ZWRJY29uKCBjb250ZXh0X2J0biApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMuc2V0RGVmYXVsdE1lbnVTZW50SWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXG5cdG9uR3JpZERibENsaWNrUm93KCkge1xuXG5cdFx0dmFyIGNvbnRleHRfbWVudV9hcnJheSA9IENvbnRleHRNZW51TWFuYWdlci5nZXRNZW51TW9kZWxCeU1lbnVJZCggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkICk7XG5cdFx0dmFyIGxlbiA9IGNvbnRleHRfbWVudV9hcnJheS5sZW5ndGg7XG5cblx0XHR2YXIgbmVlZF9icmVhayA9IGZhbHNlO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XG5cblx0XHRcdGlmICggbmVlZF9icmVhayApIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cblx0XHRcdGxldCBjb250ZXh0X2J0biA9IGNvbnRleHRfbWVudV9hcnJheVtpXTtcblx0XHRcdGxldCBpZCA9IGNvbnRleHRfbWVudV9hcnJheVtpXS5pZDtcblxuXHRcdFx0c3dpdGNoICggaWQgKSB7XG5cdFx0XHRcdGNhc2UgJ3ZpZXcnOlxuXHRcdFx0XHRcdG5lZWRfYnJlYWsgPSB0cnVlO1xuXHRcdFx0XHRcdGlmICggY29udGV4dF9idG4udmlzaWJsZSAmJiAhY29udGV4dF9idG4uZGlzYWJsZWQgKSB7XG5cdFx0XHRcdFx0XHRQcm9ncmVzc0Jhci5zaG93T3ZlcmxheSgpO1xuXHRcdFx0XHRcdFx0dGhpcy5vblZpZXdDbGljaygpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRvbkN1c3RvbUNvbnRleHRDbGljayggaWQsIGNvbnRleHRfYnRuICkge1xuXHRcdC8vIFZ1ZSBub3RlczogTm9ybWFsbHkgd2hlbiBWdWUgY2FsbHMgdGhpcyBtZW51LCBpdCBkb2VzIG5vdCBuZWVkIGNvbnRleHRfYnRuLCBhcyBtb3N0IHBsYWNlcyB0aGF0IHVzZSB0aGlzIGZ1bmN0aW9uIGhhdmUgdGhlIEdsb2JhbC5pc1NldCggbWVudV9uYW1lICkgY2hlY2sgdG8ganVzdCB1c2UgbWVudV9uYW1lIGFzIHRoZSBpZC4gSG93ZXZlciwgTWVzc2FnZUNvbnRyb2xWQyBkb2VzIHVzZSBpdCwgdmlhIHNldEN1cnJlbnRTZWxlY3RlZEljb25cblx0XHRpZiAoICFjb250ZXh0X2J0biApIHtcblx0XHRcdGNvbnRleHRfYnRuID0gQ29udGV4dE1lbnVNYW5hZ2VyLmdldE1lbnVNb2RlbEJ5TWVudUlkKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQgKS5maW5kKCBpY29uID0+IGljb24uaWQgPT0gaWQgKTtcblx0XHR9XG5cblx0XHRzd2l0Y2ggKCBpZCApIHtcblx0XHRcdGNhc2UgJ3NlbmQnOlxuXHRcdFx0XHR0aGlzLm9uU2F2ZUNsaWNrKCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnY2xvc2VfbWlzYyc6XG5cdFx0XHRjYXNlICdjYW5jZWwnOlxuXHRcdFx0XHR0aGlzLm9uQ2FuY2VsQ2xpY2soIGlkICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnaW5ib3gnOlxuXHRcdFx0XHR0aGlzLnNldEN1cnJlbnRTZWxlY3RlZEljb24oIGNvbnRleHRfYnRuICk7XG5cdFx0XHRcdHRoaXMub25JbmJveENsaWNrKCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnc2VudCc6XG5cdFx0XHRcdHRoaXMuc2V0Q3VycmVudFNlbGVjdGVkSWNvbiggY29udGV4dF9idG4gKTtcblx0XHRcdFx0dGhpcy5vblNlbnRDbGljaygpO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHRvbkNhbmNlbENsaWNrKCBpY29uTmFtZSApIHtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb24gPSAnY2FuY2VsJztcblxuXHRcdGlmICggdGhpcy5pc19jaGFuZ2VkICkge1xuXHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93Q29uZmlybUFsZXJ0KCBHbG9iYWwubW9kaWZ5X2FsZXJ0X21lc3NhZ2UsIG51bGwsIGZ1bmN0aW9uKCBmbGFnICkge1xuXG5cdFx0XHRcdGlmICggZmxhZyA9PT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRkb05leHQoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9ICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRvTmV4dCgpO1xuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGRvTmV4dCgpIHtcblxuXHRcdFx0aWYgKCBpY29uTmFtZSA9PT0gJ2NhbmNlbCcgJiYgJHRoaXMuaXNSZWxvYWRWaWV3VUkgKSB7XG5cdFx0XHRcdCR0aGlzLmlzUmVsb2FkVmlld1VJID0gZmFsc2U7XG4vL1x0XHRcdFx0IC8vc2V0IHRvIGZpeCB0aGF0IEluZGV4Vmlld0NvbnJvbGVyIGZvcmNlIHVpIGJhY2sgdG8gdmlldyB3aGVuIG9wZW4gdmlldyBhZ2FpblxuXHRcdFx0XHRDb250ZXh0TWVudU1hbmFnZXIudW5tb3VudENvbnRleHRNZW51KCAkdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkICk7XG5cdFx0XHRcdCR0aGlzLm9uVmlld0NsaWNrKCAkdGhpcy5jdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0JHRoaXMucmVtb3ZlRWRpdFZpZXcoKTtcblx0XHRcdFx0JHRoaXMuaXNSZWxvYWRWaWV3VUkgPSBmYWxzZTtcblx0XHRcdH1cblxuXHRcdFx0R2xvYmFsLnNldFVJSW5pdENvbXBsZXRlKCk7XG5cdFx0XHRQcm9ncmVzc0Jhci5jbG9zZU92ZXJsYXkoKTtcblxuXHRcdFx0VFRQcm9taXNlLnJlc29sdmUoICdiYXNlJywgJ29uQ2FuY2VsQ2xpY2snICk7XG5cblx0XHR9XG5cdH1cblxuXHRvblNhdmVSZXN1bHQoIHJlc3VsdCApIHtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXHRcdGlmICggcmVzdWx0LmlzVmFsaWQoKSApIHtcblx0XHRcdHZhciByZXN1bHRfZGF0YSA9IHJlc3VsdC5nZXRSZXN1bHQoKTtcblx0XHRcdGlmICggIXRoaXMuZWRpdF9vbmx5X21vZGUgKSB7XG5cdFx0XHRcdGlmICggcmVzdWx0X2RhdGEgPT09IHRydWUgKSB7XG5cdFx0XHRcdFx0JHRoaXMucmVmcmVzaF9pZCA9ICR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQuaWQ7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFRUVVVJRC5pc1VVSUQoIHJlc3VsdF9kYXRhICkgJiYgcmVzdWx0X2RhdGEgIT0gVFRVVUlELnplcm9faWQgJiYgcmVzdWx0X2RhdGEgIT0gVFRVVUlELm5vdF9leGlzdF9pZCApIHtcblx0XHRcdFx0XHQkdGhpcy5yZWZyZXNoX2lkID0gcmVzdWx0X2RhdGE7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQkdGhpcy5zZWFyY2goIGZhbHNlICk7XG5cdFx0XHR9XG5cblx0XHRcdCR0aGlzLm9uU2F2ZURvbmUoIHJlc3VsdCApO1xuXG5cdFx0XHRpZiAoICR0aGlzLmlzUmVsb2FkVmlld1VJICkge1xuXHRcdFx0XHQkdGhpcy5pc1JlbG9hZFZpZXdVSSA9IGZhbHNlO1xuXHRcdFx0XHQkdGhpcy5yZW1vdmVFZGl0VmlldygpO1xuXHRcdFx0XHQkdGhpcy5vblZpZXdDbGljayggJHRoaXMuY3VycmVudF9zZWxlY3RfbWVzc2FnZV9jb250cm9sX2RhdGEgKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0JHRoaXMucmVtb3ZlRWRpdFZpZXcoKTtcblx0XHRcdH1cblxuXHRcdFx0JCgpLlRGZWVkYmFjaygge1xuXHRcdFx0XHRzb3VyY2U6ICdTYXZlJ1xuXHRcdFx0fSApO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdCR0aGlzLnNldEVycm9yTWVudSgpO1xuXHRcdFx0JHRoaXMuc2V0RXJyb3JUaXBzKCByZXN1bHQgKTtcblxuXHRcdH1cblx0fVxuXG5cdG9uSW5ib3hDbGljaygpIHtcblx0XHR0aGlzLmZvbGRlcl9pZCA9IDEwO1xuXHRcdHRoaXMuc2VhcmNoKCk7XG5cdH1cblxuXHRvblNlbnRDbGljaygpIHtcblx0XHR0aGlzLmZvbGRlcl9pZCA9IDIwO1xuXHRcdHRoaXMuc2VhcmNoKCk7XG5cdH1cblxuXHRzZXRDdXN0b21FZGl0TWVudUljb24oIGlkLCBjb250ZXh0X2J0biApIHtcblx0XHRzd2l0Y2ggKCBpZCApIHtcblx0XHRcdGNhc2UgJ2Nsb3NlX21pc2MnOlxuXHRcdFx0XHR0aGlzLnNldEVkaXRNZW51Q2xvc2VNaXNjSWNvbiggY29udGV4dF9idG4gKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdzZW5kJzpcblx0XHRcdFx0dGhpcy5zZXRFZGl0TWVudVNlbmRJY29uKCBjb250ZXh0X2J0biApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ2luYm94Jzpcblx0XHRcdFx0dGhpcy5zZXRFZGl0TWVudUluYm94SWNvbiggY29udGV4dF9idG4gKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdzZW50Jzpcblx0XHRcdFx0dGhpcy5zZXRFZGl0TWVudVNlbnRJY29uKCBjb250ZXh0X2J0biApO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHRnZXRJc1B1bmNoT3JSZXF1ZXN0KCkge1xuXHRcdGxldCBwX2lkID0gbnVsbDtcblx0XHRpZiAoIHRoaXMuaXNfbWVzc2FnZSApIHtcblx0XHRcdHBfaWQgPSAnbWVzc2FnZSc7XG5cdFx0fSBlbHNlIGlmICggdGhpcy5pc19yZXF1ZXN0ICkge1xuXHRcdFx0cF9pZCA9ICdyZXF1ZXN0Jztcblx0XHR9XG5cblx0XHRyZXR1cm4gcF9pZDtcblx0fVxuXG5cdHNldEN1cnJlbnRTZWxlY3RlZEljb24oIGljb24gKSB7XG5cblx0XHR2YXIgY29udGV4dF9tZW51X2FycmF5ID0gQ29udGV4dE1lbnVNYW5hZ2VyLmdldE1lbnVNb2RlbEJ5TWVudUlkKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQgKTtcblx0XHQvL0Vycm9yOiBVbmNhdWdodCBUeXBlRXJyb3I6IENhbm5vdCByZWFkIHByb3BlcnR5ICdmaW5kJyBvZiBudWxsIGluIC9pbnRlcmZhY2UvaHRtbDUvIyFtPU1lc3NhZ2VDb250cm9sIGxpbmUgNTQzXG5cdFx0aWYgKCAhaWNvbiApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgbGVuID0gY29udGV4dF9tZW51X2FycmF5Lmxlbmd0aDtcblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdGxldCBjb250ZXh0X2J0biA9IGNvbnRleHRfbWVudV9hcnJheVtpXTtcblx0XHRcdGxldCBpZCA9IGNvbnRleHRfbWVudV9hcnJheVtpXS5pZDtcblxuXHRcdFx0aWYoIGNvbnRleHRfYnRuLmFjdGl2ZSApIHtcblx0XHRcdFx0Ly8gTWFrZSBzdXJlIHRvIG9ubHkgc2V0IHRoZSByZWxldmFudCBncm91cCBpY29ucyBpbmFjdGl2ZSwgb3RoZXJ3aXNlIHRoZSBvdGhlciBjb250ZXh0IG1lbnUgaWNvbnMgZ2V0IGFjdGl2ZS9pbmFjdGl2ZSB0b2dnbGUgaWNvbnMgc2V0IG9uIHRoZW0gdG9vLlxuXHRcdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuYWN0aXZhdGVNZW51SXRlbSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkLCBjb250ZXh0X2J0blx0LmlkLCB0cnVlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdENvbnRleHRNZW51TWFuYWdlci5hY3RpdmF0ZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGljb24uaWQsIGZhbHNlICk7XG5cdH1cblxuXHRzZXREZWZhdWx0TWVudURlbGV0ZUFuZE5leHRJY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGggKSB7XG5cblx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHR9XG5cblx0c2V0RGVmYXVsdE1lbnVEZWxldGVJY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGggKSB7XG5cblx0XHRpZiAoIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoID49IDEgKSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCB0cnVlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIGZhbHNlICk7XG5cdFx0fVxuXHR9XG5cblx0c2V0RGVmYXVsdE1lbnVFZGl0SWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICkge1xuXG5cdFx0aWYgKCB0aGlzLmlzX2VkaXQgfHwgdGhpcy5pc192aWV3aW5nICkge1xuXHRcdFx0Q29udGV4dE1lbnVNYW5hZ2VyLmhpZGVNZW51SXRlbSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkLCBjb250ZXh0X2J0bi5pZCwgdHJ1ZSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuaGlkZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdH1cblxuXHRcdGlmICggZ3JpZF9zZWxlY3RlZF9sZW5ndGggPT09IDEgKSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCB0cnVlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIGZhbHNlICk7XG5cdFx0fVxuXHR9XG5cblx0c2V0RGVmYXVsdE1lbnVWaWV3SWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICkge1xuXG5cdFx0aWYgKCBncmlkX3NlbGVjdGVkX2xlbmd0aCA9PT0gMSApIHtcblx0XHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIHRydWUgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Q29udGV4dE1lbnVNYW5hZ2VyLmRpc2FibGVNZW51SXRlbSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkLCBjb250ZXh0X2J0bi5pZCwgZmFsc2UgKTtcblx0XHR9XG5cdH1cblxuXHRzZXREZWZhdWx0TWVudUFkZEljb24oIGNvbnRleHRfYnRuLCBncmlkX3NlbGVjdGVkX2xlbmd0aCApIHtcblx0fVxuXG5cdHNldEVkaXRNZW51Q2xvc2VNaXNjSWNvbiggY29udGV4dF9idG4gKSB7XG5cdH1cblxuXHRzZXRFZGl0TWVudVNlbmRJY29uKCBjb250ZXh0X2J0biApIHtcblxuXHRcdGlmICggdGhpcy5pc19lZGl0IHx8IHRoaXMuaXNfYWRkICkge1xuXHRcdFx0Q29udGV4dE1lbnVNYW5hZ2VyLmRpc2FibGVNZW51SXRlbSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkLCBjb250ZXh0X2J0bi5pZCwgdHJ1ZSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdH1cblx0fVxuXG5cdHNldEVkaXRNZW51SW5ib3hJY29uKCBjb250ZXh0X2J0biApIHtcblx0XHRDb250ZXh0TWVudU1hbmFnZXIuaGlkZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIGZhbHNlICk7XG5cdH1cblxuXHRzZXRFZGl0TWVudVNlbnRJY29uKCBjb250ZXh0X2J0biApIHtcblx0XHRDb250ZXh0TWVudU1hbmFnZXIuaGlkZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIGZhbHNlICk7XG5cdH1cblxuXHRzZXREZWZhdWx0TWVudUNsb3NlTWlzY0ljb24oIGNvbnRleHRfYnRuLCBncmlkX3NlbGVjdGVkX2xlbmd0aCApIHtcblxuXHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIGZhbHNlICk7XG5cdH1cblxuXHRzZXREZWZhdWx0TWVudVNlbmRJY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGggKSB7XG5cdFx0aWYgKCB0aGlzLmlzX2VkaXQgfHwgdGhpcy5pc192aWV3aW5nICkge1xuXHRcdFx0Q29udGV4dE1lbnVNYW5hZ2VyLmhpZGVNZW51SXRlbSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkLCBjb250ZXh0X2J0bi5pZCwgdHJ1ZSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuaGlkZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdH1cblxuXHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIGZhbHNlICk7XG5cdH1cblxuXHRzZXREZWZhdWx0TWVudUluYm94SWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICkge1xuXHR9XG5cblx0c2V0RGVmYXVsdE1lbnVTZW50SWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICkge1xuXHR9XG5cblx0c2V0R3JpZENlbGxCYWNrR3JvdW5kKCkge1xuXHRcdHZhciBkYXRhID0gdGhpcy5ncmlkLmdldEdyaWRQYXJhbSggJ2RhdGEnICk7XG5cblx0XHQvL0Vycm9yOiBUeXBlRXJyb3I6IGRhdGEgaXMgdW5kZWZpbmVkIGluIC9pbnRlcmZhY2UvaHRtbDUvZnJhbWV3b3JrL2pxdWVyeS5taW4uanM/dj03LjQuNi0yMDE0MTAyNy0wNzQxMjcgbGluZSAyID4gZXZhbCBsaW5lIDcwXG5cdFx0aWYgKCAhZGF0YSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgbGVuID0gZGF0YS5sZW5ndGg7XG5cblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdHZhciBpdGVtID0gZGF0YVtpXTtcblxuXHRcdFx0aWYgKCBpdGVtLnN0YXR1c19pZCA9PSAxMCApIHtcblx0XHRcdFx0JCggJ3RyW2lkPVxcJycgKyBpdGVtLmlkICsgJ1xcJ10gdGQnICkuY3NzKCAnZm9udC13ZWlnaHQnLCAnYm9sZCcgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRnZXRGaWx0ZXJDb2x1bW5zRnJvbURpc3BsYXlDb2x1bW5zKCkge1xuXHRcdHZhciBjb2x1bW5fZmlsdGVyID0ge307XG5cblx0XHRjb2x1bW5fZmlsdGVyLmlkID0gdHJ1ZTtcblx0XHRjb2x1bW5fZmlsdGVyLmlzX2NoaWxkID0gdHJ1ZTtcblx0XHRjb2x1bW5fZmlsdGVyLmlzX293bmVyID0gdHJ1ZTtcblx0XHRjb2x1bW5fZmlsdGVyLm9iamVjdF90eXBlX2lkID0gdHJ1ZTtcblx0XHRjb2x1bW5fZmlsdGVyLm9iamVjdF9pZCA9IHRydWU7XG5cdFx0Y29sdW1uX2ZpbHRlci5zdGF0dXNfaWQgPSB0cnVlO1xuXHRcdGNvbHVtbl9maWx0ZXIuZnJvbV91c2VyX2lkID0gdHJ1ZTtcblx0XHRjb2x1bW5fZmlsdGVyLnRvX3VzZXJfaWQgPSB0cnVlO1xuXG5cdFx0Ly8gRXJyb3I6IFVuYWJsZSB0byBnZXQgcHJvcGVydHkgJ2dldEdyaWRQYXJhbScgb2YgdW5kZWZpbmVkIG9yIG51bGwgcmVmZXJlbmNlXG5cdFx0dmFyIGRpc3BsYXlfY29sdW1ucyA9IFtdO1xuXHRcdGlmICggdGhpcy5ncmlkICkge1xuXHRcdFx0ZGlzcGxheV9jb2x1bW5zID0gdGhpcy5ncmlkLmdldEdyaWRQYXJhbSggJ2NvbE1vZGVsJyApO1xuXHRcdH1cblxuXHRcdGlmICggZGlzcGxheV9jb2x1bW5zICkge1xuXHRcdFx0dmFyIGxlbiA9IGRpc3BsYXlfY29sdW1ucy5sZW5ndGg7XG5cblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHR2YXIgY29sdW1uX2luZm8gPSBkaXNwbGF5X2NvbHVtbnNbaV07XG5cdFx0XHRcdGNvbHVtbl9maWx0ZXJbY29sdW1uX2luZm8ubmFtZV0gPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBjb2x1bW5fZmlsdGVyO1xuXHR9XG5cblx0aW5pdEVkaXRWaWV3VUkoIHZpZXdfaWQsIGVkaXRfdmlld19maWxlX25hbWUgKSB7XG5cblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXG5cdFx0aWYgKCB0aGlzLmVkaXRfdmlldyApIHtcblx0XHRcdHRoaXMuZWRpdF92aWV3LnJlbW92ZSgpO1xuXHRcdH1cblx0XHR0aGlzLmVkaXRfdmlldyA9ICQoIEdsb2JhbC5sb2FkVmlld1NvdXJjZSggdmlld19pZCwgZWRpdF92aWV3X2ZpbGVfbmFtZSwgbnVsbCwgdHJ1ZSApICk7XG5cdFx0dGhpcy5lZGl0X3ZpZXdfdGFiID0gJCggdGhpcy5lZGl0X3ZpZXcuZmluZCggJy5lZGl0LXZpZXctdGFiLWJhcicgKSApO1xuXHRcdC8vR2l2ZSBlZHQgdmlldyB0YWIgYSBpZCwgc28gd2UgY2FuIGxvYWQgaXQgd2hlbiBwdXQgcmlnaHQgY2xpY2sgbWVudSBvbiBpdFxuXHRcdHRoaXMuZWRpdF92aWV3X3RhYi5hdHRyKCAnaWQnLCB0aGlzLnVpX2lkICsgJ19lZGl0X3ZpZXdfdGFiJyApO1xuXHRcdC8vIE1vdmVkIGludG8gZ2VuZXJpYyBCYXNlVmlldy5pbml0RWRpdFZpZXdUYWJzXG5cdFx0Ly8gdGhpcy5zZXRUYWJPVmlzaWJpbGl0eSggZmFsc2UgKTtcblx0XHQvLyB0aGlzLmVkaXRfdmlld190YWIgPSB0aGlzLmVkaXRfdmlld190YWIudGFicygge1xuXHRcdC8vIFx0YWN0aXZhdGU6IGZ1bmN0aW9uKCBlLCB1aSApIHtcblx0XHQvLyBcdFx0JHRoaXMub25UYWJTaG93KCBlLCB1aSApO1xuXHRcdC8vIFx0fVxuXHRcdC8vIH0gKTtcblxuXHRcdC8vIHRoaXMuZWRpdF92aWV3X3RhYi5iaW5kKCAndGFic3NlbGVjdCcsIGZ1bmN0aW9uKCBlLCB1aSApIHtcblx0XHQvLyBcdCR0aGlzLm9uVGFiSW5kZXhDaGFuZ2UoIGUsIHVpICk7XG5cdFx0Ly8gfSApO1xuXG5cdFx0aWYgKCB0aGlzLmZvbGRlcl9pZCA9PSAxMCApIHtcblx0XHRcdHRoaXMubmF2aWdhdGlvbl9sYWJlbCA9ICQuaTE4bi5fKCAnRnJvbScgKTtcblx0XHR9IGVsc2UgaWYgKCB0aGlzLmZvbGRlcl9pZCA9PSAyMCApIHtcblx0XHRcdHRoaXMubmF2aWdhdGlvbl9sYWJlbCA9ICQuaTE4bi5fKCAnVG8nICk7XG5cdFx0fVxuXG5cdFx0Q29udGV4dE1lbnVNYW5hZ2VyLnVubW91bnRDb250ZXh0TWVudSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkICk7XG5cblx0XHRHbG9iYWwuY29udGVudENvbnRhaW5lcigpLmFwcGVuZCggdGhpcy5lZGl0X3ZpZXcgKTtcblxuXHRcdHRoaXMuaW5pdFJpZ2h0Q2xpY2tNZW51KCBSaWdodENsaWNrTWVudVR5cGUuRURJVFZJRVcgKTtcblxuXHRcdHRoaXMuYnVpbGRFZGl0Vmlld1VJKCk7XG5cdFx0dGhpcy5zZXRFZGl0Vmlld1RhYkhlaWdodCgpO1xuXHR9XG5cblx0aW5pdEVkaXRWaWV3VGFicygpIHtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXHRcdHZhciB0YWJfb3B0aW9ucyA9IHtcblx0XHRcdGFjdGl2YXRlOiBmdW5jdGlvbiggZSwgdWkgKSB7XG5cdFx0XHRcdCR0aGlzLm9uVGFiU2hvdyggZSwgdWkgKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0c3VwZXIuaW5pdEVkaXRWaWV3VGFicyggdGFiX29wdGlvbnMgKTtcblx0fVxuXG5cdGdldFZpZXdTZWxlY3RlZFJlY29yZElkKCByZWNvcmQgKSB7XG5cdFx0Ly8gb3ZlcnJpZGVuIGZyb20gQmFzZVZDIGR1ZSB0byB0aGUgdGhpcy5nZXRSZWNvcmRGcm9tR3JpZEJ5SWQgY2FsbFxuXHRcdHZhciBzZWxlY3RlZF9pdGVtO1xuXHRcdHZhciBzZWxlY3RlZF9pZDtcblx0XHR2YXIgZ3JpZF9zZWxlY3RlZF9pZF9hcnJheSA9IHRoaXMuZ2V0R3JpZFNlbGVjdElkQXJyYXkoKTtcblx0XHR2YXIgZ3JpZF9zZWxlY3RlZF9sZW5ndGggPSBncmlkX3NlbGVjdGVkX2lkX2FycmF5Lmxlbmd0aDtcblxuXHRcdGlmICggR2xvYmFsLmlzU2V0KCByZWNvcmQgKSApIHtcblx0XHRcdHNlbGVjdGVkX2l0ZW0gPSByZWNvcmQ7IC8vIElmIHRoZSBuZXh0X3NlbGVjdGVkX2l0ZW0gaXMgZGVmaW5lZCwgZmlyc3QgdG8gdXNlIHRoaXMgdmFyaWFibGUuXG5cblx0XHR9IGVsc2UgaWYgKCBncmlkX3NlbGVjdGVkX2xlbmd0aCA+IDAgKSB7XG5cdFx0XHRzZWxlY3RlZF9pdGVtID0gdGhpcy5nZXRSZWNvcmRGcm9tR3JpZEJ5SWQoIGdyaWRfc2VsZWN0ZWRfaWRfYXJyYXlbMF0gKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0VFRQcm9taXNlLnJlamVjdCggJ01lc3NhZ2VDb250cm9sbFZpZXdDb250cm9sbGVyJywgJ29uVmlld0NsaWNrJyApO1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWxlY3RlZF9pdGVtLm9iamVjdF90eXBlX2lkID09IDUwICkge1xuXHRcdFx0c2VsZWN0ZWRfaWQgPSBzZWxlY3RlZF9pdGVtLm9iamVjdF9pZDtcblx0XHRcdHRoaXMuaXNfcmVxdWVzdCA9IHRydWU7XG5cdFx0XHR0aGlzLmlzX21lc3NhZ2UgPSBmYWxzZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0c2VsZWN0ZWRfaWQgPSBzZWxlY3RlZF9pdGVtLmlkO1xuXHRcdFx0dGhpcy5pc19yZXF1ZXN0ID0gZmFsc2U7XG5cdFx0XHR0aGlzLmlzX21lc3NhZ2UgPSB0cnVlO1xuXHRcdH1cblxuXHRcdHJldHVybiBzZWxlY3RlZF9pdGVtO1xuXHR9XG5cblx0Z2V0Q3VycmVudFNlbGVjdGVkUmVjb3JkKCByZXR1cm5fb2JqZWN0ICkge1xuXHRcdHZhciBzZWxlY3RlZF9pdGVtID0gdGhpcy5jdXJyZW50X3NlbGVjdGVkX3JlY29yZDtcblx0XHRpZiAoICFzZWxlY3RlZF9pdGVtICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHZhciBzZWxlY3RlZF9pZDtcblx0XHRpZiAoIHNlbGVjdGVkX2l0ZW0ub2JqZWN0X3R5cGVfaWQgJiYgc2VsZWN0ZWRfaXRlbS5vYmplY3RfdHlwZV9pZCA9PSA1MCApIHtcblx0XHRcdHNlbGVjdGVkX2lkID0gc2VsZWN0ZWRfaXRlbS5vYmplY3RfaWQ7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNlbGVjdGVkX2lkID0gc2VsZWN0ZWRfaXRlbS5pZDtcblx0XHR9XG5cblx0XHQvLyBjdXJyZW50X3NlbGVjdGVkX3JlY29yZCBub3JtYWxseSBoYW5kbGVzIElEJ3MsIGJ1dCBmb3IgTWVzc2FnZUNvbnRyb2xWQyB3ZSB3aWxsIGJlIHVzaW5nIHRoZSByZWNvcmQgb2JqZWN0IGFzIHRoaXMgaXMgbmVlZGVkIGluIHZhcmlvdXMgcGxhY2VzLlxuXHRcdGlmICggcmV0dXJuX29iamVjdCA9PT0gdHJ1ZSApIHtcblx0XHRcdHJldHVybiBzZWxlY3RlZF9pdGVtO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gc2VsZWN0ZWRfaWQ7XG5cdFx0fVxuXHR9XG5cblx0aGFuZGxlVmlld0FQSUNhbGxiYWNrUmVzdWx0KCByZXN1bHQgKSB7XG5cdFx0dmFyIHJlc3VsdF9kYXRhO1xuXHRcdGlmICggcmVzdWx0ICYmIHJlc3VsdC5nZXRSZXN1bHQgKSB7XG5cdFx0XHRyZXN1bHRfZGF0YSA9IHJlc3VsdC5nZXRSZXN1bHQoKTtcblx0XHRcdGlmICggdGhpcy5pc19yZXF1ZXN0ICkge1xuXHRcdFx0XHRyZXN1bHRfZGF0YSA9IHJlc3VsdF9kYXRhWzBdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gTm90ZSB0aGF0IHdlIGRvbnQgd2FudCB0byB0YWtlIGp1c3QgdGhlIGZpcnN0IHJlY29yZCBpZiBpdHMgbm90IGEgcmVxdWVzdC4gUmVxdWVzdHMgKGFuZCBtb3N0IG90aGVyIG9uVmlldyBwYWdlcywgb25seSBoYXZlIG9uZSByZWNvcmQuIEJ1dCBtZXNzYWdlcyBjYW4gaGF2ZSBtdWx0aXBsZSByZWNvcmRzIGluIHRoZSByZXN1bHRzIGRhdGEuXG5cdFx0XHRcdHJlc3VsdF9kYXRhID0gcmVzdWx0X2RhdGEubGVuZ3RoID4gMSA/IHJlc3VsdF9kYXRhLnJldmVyc2UoKSA6IHJlc3VsdF9kYXRhWzBdO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXN1bHRfZGF0YSA9IHJlc3VsdDtcblx0XHR9XG5cblx0XHRyZXR1cm4gc3VwZXIuaGFuZGxlVmlld0FQSUNhbGxiYWNrUmVzdWx0KCByZXN1bHRfZGF0YSApO1xuXHR9XG5cblx0ZG9WaWV3QVBJQ2FsbCggZmlsdGVyICkge1xuXHRcdHZhciBjYWxsYmFjayA9IHsgb25SZXN1bHQ6IHRoaXMuaGFuZGxlVmlld0FQSUNhbGxiYWNrUmVzdWx0LmJpbmQoIHRoaXMgKSB9O1xuXG5cdFx0aWYgKCB0aGlzLmlzX3JlcXVlc3QgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5yZXF1ZXN0X2FwaS5nZXRSZXF1ZXN0KCBmaWx0ZXIsIGNhbGxiYWNrICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiB0aGlzLmFwaS5nZXRNZXNzYWdlKCBmaWx0ZXIsIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9XG5cblx0ZG9WaWV3Q2xpY2tSZXN1bHQoIHJlc3VsdF9kYXRhICkge1xuXHRcdC8vIHNhdmUgY3VycmVudCBzZWxlY3QgZ3JpZCBkYXRhLiBOb3QgdGhpcyBub3Qgd29yayB3aGVuIGFjY2VzcyBmcm9tIHVybCBhY3Rpb24uIFNlZSBhdXRvT3BlbkVkaXRWaWV3IGZ1bmN0aW9uIGZvciB3aHlcblx0XHR0aGlzLmN1cnJlbnRfc2VsZWN0X21lc3NhZ2VfY29udHJvbF9kYXRhID0gdGhpcy5nZXRDdXJyZW50U2VsZWN0ZWRSZWNvcmQoIHRydWUgKTtcblxuXHRcdC8vaWYgYWNjZXNzIGZyb20gdXJsLCBjdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YSBuZWVkIGJlIGdldCBhZ2FpblxuXHRcdGlmICggIXRoaXMuY3VycmVudF9zZWxlY3RfbWVzc2FnZV9jb250cm9sX2RhdGEuaGFzT3duUHJvcGVydHkoICd0b191c2VyX2lkJyApICkge1xuXHRcdFx0dmFyIGZpbHRlciA9IHsgZmlsdGVyX2RhdGE6IHsgaWQ6IHRoaXMuY3VycmVudF9zZWxlY3RfbWVzc2FnZV9jb250cm9sX2RhdGEuaWQgfSB9O1xuXHRcdFx0dmFyIG1lc3NhZ2VfY29udHJvbF9kYXRhID0gdGhpcy5hcGkuZ2V0TWVzc2FnZUNvbnRyb2woIGZpbHRlciwgeyBhc3luYzogZmFsc2UgfSApLmdldFJlc3VsdCgpWzBdO1xuXG5cdFx0XHRpZiAoIG1lc3NhZ2VfY29udHJvbF9kYXRhICkge1xuXHRcdFx0XHR0aGlzLmN1cnJlbnRfc2VsZWN0X21lc3NhZ2VfY29udHJvbF9kYXRhID0gbWVzc2FnZV9jb250cm9sX2RhdGE7XG5cdFx0XHR9XG5cblx0XHR9XG5cdFx0dmFyIHJldHZhbCA9IHN1cGVyLmRvVmlld0NsaWNrUmVzdWx0KCByZXN1bHRfZGF0YSApO1xuXHRcdFRUUHJvbWlzZS5yZXNvbHZlKCAnTWVzc2FnZUNvbnRyb2xsVmlld0NvbnRyb2xsZXInLCAnb25WaWV3Q2xpY2snICk7XG5cdFx0Ly8gVGhlIHByb21pc2UgbXVzdCBiZSByZXNvbHZlZCBsYXN0LCBhZnRlciBldmVydGhpbmcgZWxzZSwgaGVuY2UgdGhlIHNwZWNpZmljIG9yZGVyIGhlcmUgd2l0aCByZXR2YWwgYW5kIHRoZSBzdXBlci5cblx0XHRyZXR1cm4gcmV0dmFsO1xuXHR9XG5cblx0Z2V0QVBJRmlsdGVycygpIHtcblx0XHR2YXIgcmVjb3JkX2lkID0gdGhpcy5nZXRDdXJyZW50U2VsZWN0ZWRSZWNvcmQoKTtcblx0XHR2YXIgZmlsdGVyID0ge307XG5cblx0XHRmaWx0ZXIuZmlsdGVyX2RhdGEgPSB7fTtcblx0XHRmaWx0ZXIuZmlsdGVyX2RhdGEuaWQgPSByZWNvcmRfaWQ7XG5cblx0XHRyZXR1cm4gZmlsdGVyO1xuXHR9XG5cblx0b25WaWV3Q2xpY2soIG5leHRfc2VsZWN0ZWRfaXRlbSwgbm9SZWZyZXNoVUkgKSB7XG5cdFx0VFRQcm9taXNlLmFkZCggJ01lc3NhZ2VDb250cm9sbFZpZXdDb250cm9sbGVyJywgJ29uVmlld0NsaWNrJyApO1xuXHRcdFRUUHJvbWlzZS53YWl0KCk7XG5cdFx0dmFyICR0aGlzID0gdGhpcztcblxuXHRcdHRoaXMuc2V0Q3VycmVudEVkaXRWaWV3U3RhdGUoICd2aWV3JyApO1xuXG5cdFx0JHRoaXMuaXNSZWxvYWRWaWV3VUkgPSB0cnVlO1xuXG5cdFx0dmFyIHNlbGVjdGVkX2l0ZW0gPSB0aGlzLmdldFZpZXdTZWxlY3RlZFJlY29yZElkKCBuZXh0X3NlbGVjdGVkX2l0ZW0gKTtcblx0XHRpZiAoIEdsb2JhbC5pc0ZhbHNlT3JOdWxsKCBzZWxlY3RlZF9pdGVtICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuc2V0Q3VycmVudFNlbGVjdGVkUmVjb3JkKCBzZWxlY3RlZF9pdGVtICk7XG5cblx0XHR2YXIgZmlsdGVyID0gdGhpcy5nZXRBUElGaWx0ZXJzKCk7XG5cdFx0dGhpcy5vcGVuRWRpdFZpZXcoKTtcblxuXHRcdHJldHVybiB0aGlzLmRvVmlld0FQSUNhbGwoIGZpbHRlciApO1xuXHR9XG5cblx0LyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuXHRzZXRVUkwoKSB7XG5cblx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb24gPT09ICdlZGl0JyApIHtcblx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb24gPSAnJztcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgYSA9ICcnO1xuXHRcdHN3aXRjaCAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb24gKSB7XG5cdFx0XHRjYXNlICduZXcnOlxuXHRcdFx0Y2FzZSAnZWRpdCc6XG5cdFx0XHRjYXNlICd2aWV3Jzpcblx0XHRcdFx0YSA9IExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb247XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnY29weV9hc19uZXcnOlxuXHRcdFx0XHRhID0gJ25ldyc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy5jYW5TZXRVUkwoKSApIHtcblx0XHRcdHZhciB0YWJfbmFtZSA9IHRoaXMuZWRpdF92aWV3X3RhYiA/IHRoaXMuZWRpdF92aWV3X3RhYi5maW5kKCAnLmVkaXQtdmlldy10YWItYmFyLWxhYmVsJyApLmNoaWxkcmVuKCkuZXEoIHRoaXMuZ2V0RWRpdFZpZXdUYWJJbmRleCgpICkudGV4dCgpIDogJyc7XG5cdFx0XHR0YWJfbmFtZSA9IHRhYl9uYW1lLnJlcGxhY2UoIC9cXC98XFxzKy9nLCAnJyApO1xuXHRcdFx0aWYgKCB0aGlzLmN1cnJlbnRfc2VsZWN0X21lc3NhZ2VfY29udHJvbF9kYXRhICYmIHRoaXMuY3VycmVudF9zZWxlY3RfbWVzc2FnZV9jb250cm9sX2RhdGEuaWQgKSB7XG5cdFx0XHRcdGlmICggYSApIHtcblxuXHRcdFx0XHRcdGlmICggdGhpcy5pc19yZXF1ZXN0ICkge1xuXHRcdFx0XHRcdFx0R2xvYmFsLnNldFVSTFRvQnJvd3NlciggR2xvYmFsLmdldEJhc2VVUkwoKSArICcjIW09JyArIHRoaXMudmlld0lkICtcblx0XHRcdFx0XHRcdFx0JyZhPScgKyBhICsgJyZpZD0nICsgdGhpcy5jdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YS5pZCArXG5cdFx0XHRcdFx0XHRcdCcmdD1yZXF1ZXN0Jm9iamVjdF9pZD0nICsgdGhpcy5jdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YS5vYmplY3RfaWQgK1xuXHRcdFx0XHRcdFx0XHQnJnRhYj0nICsgdGFiX25hbWUgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0R2xvYmFsLnNldFVSTFRvQnJvd3NlciggR2xvYmFsLmdldEJhc2VVUkwoKSArXG5cdFx0XHRcdFx0XHRcdCcjIW09JyArIHRoaXMudmlld0lkICsgJyZhPScgK1xuXHRcdFx0XHRcdFx0XHRhICsgJyZpZD0nICsgdGhpcy5jdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YS5pZCArICcmdD1tZXNzYWdlJyArXG5cdFx0XHRcdFx0XHRcdCcmdGFiPScgKyB0YWJfbmFtZSApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0R2xvYmFsLnRyYWNrVmlldygpO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAoIGEgKSB7XG5cdFx0XHRcdFx0Ly9FZGl0IGEgcmVjb3JkIHdoaWNoIGRvbid0IGhhdmUgaWQsIHNjaGVkdWxlIHZpZXcgUmVjdXJyaW5nIFNjZWR1bGVcblx0XHRcdFx0XHRpZiAoIGEgPT09ICdlZGl0JyApIHtcblx0XHRcdFx0XHRcdEdsb2JhbC5zZXRVUkxUb0Jyb3dzZXIoIEdsb2JhbC5nZXRCYXNlVVJMKCkgKyAnIyFtPScgKyB0aGlzLnZpZXdJZCArICcmYT1uZXcmdD0nICsgKCB0aGlzLmlzX3JlcXVlc3QgPyAncmVxdWVzdCcgOiAnbWVzc2FnZScgKSArXG5cdFx0XHRcdFx0XHRcdCcmdGFiPScgKyB0YWJfbmFtZSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCBHbG9iYWwuZ2V0QmFzZVVSTCgpICsgJyMhbT0nICsgdGhpcy52aWV3SWQgKyAnJmE9JyArIGEgKyAnJnQ9JyArICggdGhpcy5pc19yZXF1ZXN0ID8gJ3JlcXVlc3QnIDogJ21lc3NhZ2UnICkgK1xuXHRcdFx0XHRcdFx0XHQnJnRhYj0nICsgdGFiX25hbWUgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCBHbG9iYWwuZ2V0QmFzZVVSTCgpICsgJyMhbT0nICsgdGhpcy52aWV3SWQgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0fVxuXHR9XG5cblx0LyoganNoaW50IGlnbm9yZTplbmQgKi9cblx0aW5pdEVkaXRWaWV3RGF0YSgpIHtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXHRcdGlmICggIXRoaXMuZWRpdF9vbmx5X21vZGUgJiYgdGhpcy5uYXZpZ2F0aW9uICkge1xuXG5cdFx0XHR2YXIgZ3JpZF9jdXJyZW50X3BhZ2VfaXRlbXMgPSB0aGlzLmdyaWQuZ2V0R3JpZFBhcmFtKCAnZGF0YScgKTtcblxuXHRcdFx0dmFyIG5hdmlnYXRpb25fZGl2ID0gdGhpcy5lZGl0X3ZpZXcuZmluZCggJy5uYXZpZ2F0aW9uLWRpdicgKTtcblx0XHRcdHZhciBuYXZpZ2F0aW9uX3NvdXJjZV9kYXRhO1xuXG5cdFx0XHQvL2JlY2F1c2UgSSB3aWxsIGFsd2F5cyBnZXQgdGhpcyBpbiBvblZpZXdDbGljaywgc28gZWxzZSBicmFuY2ggc2hvdWxkIG5ldmVyIGJlIGluXG5cdFx0XHRpZiAoIHRoaXMuY3VycmVudF9zZWxlY3RfbWVzc2FnZV9jb250cm9sX2RhdGEgJiYgdGhpcy5jdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YS5oYXNPd25Qcm9wZXJ0eSggJ2lkJyApICYmXG5cdFx0XHRcdHRoaXMuY3VycmVudF9zZWxlY3RfbWVzc2FnZV9jb250cm9sX2RhdGEuaGFzT3duUHJvcGVydHkoICdzdWJqZWN0JyApICkge1xuXHRcdFx0XHRuYXZpZ2F0aW9uX3NvdXJjZV9kYXRhID0gdGhpcy5jdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG5hdmlnYXRpb25fc291cmNlX2RhdGEgPSBHbG9iYWwuaXNBcnJheSggdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkICkgPyB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmRbMF0gOiB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQ7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMubmF2aWdhdGlvbl9zb3VyY2VfZGF0YSA9IG5hdmlnYXRpb25fc291cmNlX2RhdGE7XG5cblx0XHRcdGlmICggdGhpcy5pc192aWV3aW5nICYmIEdsb2JhbC5pc1NldCggbmF2aWdhdGlvbl9zb3VyY2VfZGF0YS5pZCApICYmIG5hdmlnYXRpb25fc291cmNlX2RhdGEuaWQgKSB7XG5cdFx0XHRcdG5hdmlnYXRpb25fZGl2LmNzcyggJ2Rpc3BsYXknLCAnYmxvY2snICk7XG5cdFx0XHRcdC8vU2V0IE5hdmlnYXRpb24gQXdlc29tZWJveFxuXG5cdFx0XHRcdC8vaW5pdCBuYXZpZ2F0aW9uIG9ubHkgd2hlbiBvcGVuIGVkaXQgdmlld1xuXHRcdFx0XHRpZiAoICF0aGlzLm5hdmlnYXRpb24uZ2V0U291cmNlRGF0YSgpICkge1xuXHRcdFx0XHRcdHRoaXMubmF2aWdhdGlvbi5zZXRTb3VyY2VEYXRhKCBncmlkX2N1cnJlbnRfcGFnZV9pdGVtcyApO1xuXHRcdFx0XHRcdHRoaXMubmF2aWdhdGlvbi5zZXRSb3dQZXJQYWdlKCBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkuaXRlbXNfcGVyX3BhZ2UgKTtcblx0XHRcdFx0XHR0aGlzLm5hdmlnYXRpb24uc2V0UGFnZXJEYXRhKCB0aGlzLnBhZ2VyX2RhdGEgKTtcblxuLy9cdFx0XHRcdFx0dGhpcy5uYXZpZ2F0aW9uLnNldERpc1BsYXlDb2x1bW5zKCB0aGlzLmJ1aWxkRGlzcGxheUNvbHVtbnNCeUNvbHVtbk1vZGVsKCB0aGlzLmdyaWQuZ2V0R3JpZFBhcmFtKCAnY29sTW9kZWwnICkgKSApO1xuXG5cdFx0XHRcdFx0dmFyIGRlZmF1bHRfYXJncyA9IHt9O1xuXHRcdFx0XHRcdGRlZmF1bHRfYXJncy5maWx0ZXJfZGF0YSA9IEdsb2JhbC5jb252ZXJ0TGF5b3V0RmlsdGVyVG9BUElGaWx0ZXIoIHRoaXMuc2VsZWN0X2xheW91dCApO1xuXHRcdFx0XHRcdGRlZmF1bHRfYXJncy5maWx0ZXJfc29ydCA9IHRoaXMuc2VsZWN0X2xheW91dC5kYXRhLmZpbHRlcl9zb3J0O1xuXHRcdFx0XHRcdHRoaXMubmF2aWdhdGlvbi5zZXREZWZhdWx0QXJncyggZGVmYXVsdF9hcmdzICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLm5hdmlnYXRpb24uc2V0VmFsdWUoIG5hdmlnYXRpb25fc291cmNlX2RhdGEgKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bmF2aWdhdGlvbl9kaXYuY3NzKCAnZGlzcGxheScsICdub25lJyApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuc2V0VUlXaWRnZXRGaWVsZHNUb0N1cnJlbnRFZGl0UmVjb3JkKCk7XG5cblx0XHR0aGlzLnNldE5hdmlnYXRpb25BcnJvd3NFbmFibGVkKCk7XG5cblx0XHQvLyBDcmVhdGUgdGhpcyBmdW5jdGlvbiBhbG9uZSBiZWNhdXNlIG9mIHRoZSBjb2x1bW4gdmFsdWUgb2YgdmlldyBpcyBkaWZmZXJlbnQgZnJvbSBlYWNoIG90aGVyLCBzb21lIGNvbHVtbnMgbmVlZCB0byBiZSBoYW5kbGUgc3BlY2lhbGx5LiBhbmQgZWFzaWx5IHRvIHJld3JpdGUgdGhpcyBmdW5jdGlvbiBpbiBzdWItY2xhc3MuXG5cblx0XHR0aGlzLnNldEN1cnJlbnRFZGl0UmVjb3JkRGF0YSgpO1xuXG5cdFx0Ly9Jbml0ICpQbGVhc2Ugc2F2ZSB0aGlzIHJlY29yZCBiZWZvcmUgbW9kaWZ5aW5nIGFueSByZWxhdGVkIGRhdGEqIGJveFxuXHRcdHRoaXMuZWRpdF92aWV3LmZpbmQoICcuc2F2ZS1hbmQtY29udGludWUtZGl2JyApLlNhdmVBbmRDb250aW51ZUJveCggeyByZWxhdGVkX3ZpZXdfY29udHJvbGxlcjogdGhpcyB9ICk7XG5cdFx0dGhpcy5lZGl0X3ZpZXcuZmluZCggJy5zYXZlLWFuZC1jb250aW51ZS1kaXYnICkuY3NzKCAnZGlzcGxheScsICdub25lJyApO1xuXHR9XG5cblx0c2V0TmF2aWdhdGlvbigpIHtcblxuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cblx0XHR0aGlzLm5hdmlnYXRpb24uc2V0UG9zc2libGVEaXNwbGF5Q29sdW1ucyggdGhpcy5idWlsZERpc3BsYXlDb2x1bW5zQnlDb2x1bW5Nb2RlbCggdGhpcy5ncmlkLmdldEdyaWRQYXJhbSggJ2NvbE1vZGVsJyApICksXG5cdFx0XHR0aGlzLmJ1aWxkRGlzcGxheUNvbHVtbnMoIHRoaXMuZGVmYXVsdF9kaXNwbGF5X2NvbHVtbnMgKSApO1xuXG5cdFx0dGhpcy5uYXZpZ2F0aW9uLnVuYmluZCggJ2Zvcm1JdGVtQ2hhbmdlJyApLmJpbmQoICdmb3JtSXRlbUNoYW5nZScsIGZ1bmN0aW9uKCBlLCB0YXJnZXQgKSB7XG5cblx0XHRcdHZhciBrZXkgPSB0YXJnZXQuZ2V0RmllbGQoKTtcblx0XHRcdHZhciBuZXh0X3NlbGVjdF9pdGVtID0gdGFyZ2V0LmdldFZhbHVlKCB0cnVlICk7XG5cblx0XHRcdGlmICggIW5leHRfc2VsZWN0X2l0ZW0gKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBuZXh0X3NlbGVjdF9pdGVtLmlkICE9PSAkdGhpcy5uYXZpZ2F0aW9uX3NvdXJjZV9kYXRhLmlkICkge1xuXHRcdFx0XHRQcm9ncmVzc0Jhci5zaG93T3ZlcmxheSgpO1xuXG5cdFx0XHRcdGlmICggJHRoaXMuaXNfdmlld2luZyApIHtcblx0XHRcdFx0XHQkdGhpcy5vblZpZXdDbGljayggbmV4dF9zZWxlY3RfaXRlbSApOyAvL0RvbnQgcmVmcmVzaCBVSVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdCR0aGlzLm9uRWRpdENsaWNrKCBuZXh0X3NlbGVjdF9pdGVtICk7IC8vRG9udCByZWZyZXNoIFVJXG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHQkdGhpcy5zZXROYXZpZ2F0aW9uQXJyb3dzRW5hYmxlZCgpO1xuXG5cdFx0fSApO1xuXHR9XG5cblx0b25FZGl0Q2xpY2soIGVkaXRJZCwgbm9SZWZyZXNoVUkgKSB7XG5cdFx0Ly8gZWRpdCBjbGljayBpcyBjbGlja2luZyBvbiBSZXBseVxuXHRcdHRoaXMuc2V0Q3VycmVudEVkaXRWaWV3U3RhdGUoICdlZGl0JyApO1xuXHRcdHRoaXMuaXNfcmVxdWVzdCA9IGZhbHNlO1xuXHRcdHRoaXMuaXNfbWVzc2FnZSA9IGZhbHNlO1xuXG5cdFx0dmFyIGdyaWRfc2VsZWN0ZWRfaWRfYXJyYXkgPSB0aGlzLmdldEdyaWRTZWxlY3RJZEFycmF5KCk7XG5cdFx0dmFyIHNlbGVjdGVkX2l0ZW0gPSB7fTtcblxuXHRcdGlmICggdGhpcy5lZGl0X3ZpZXcgKSB7XG5cdFx0XHRzZWxlY3RlZF9pdGVtID0gdGhpcy5jdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YTtcblx0XHR9IGVsc2UgeyAvLyBjbGljayBSZXBseSBvbiBsaXN0IHZpZXcuXG5cdFx0XHRzZWxlY3RlZF9pdGVtID0gdGhpcy5nZXRSZWNvcmRGcm9tR3JpZEJ5SWQoIGdyaWRfc2VsZWN0ZWRfaWRfYXJyYXlbMF0gKTtcblx0XHR9XG5cblx0XHR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQgPSBzZWxlY3RlZF9pdGVtO1xuXHRcdHRoaXMuaW5pdEVkaXRWaWV3VUkoIHRoaXMudmlld0lkLCB0aGlzLmVkaXRfdmlld190cGwgKTtcblx0XHR0aGlzLmluaXRFZGl0VmlldygpO1xuXHR9XG5cblx0YnVpbGRFZGl0Vmlld1VJKCkge1xuXHRcdC8vIEJ1aWxkcyB0aGUgZmllbGRzIGZvciBBZGQgYW5kIEVkaXQsIGFuZCBwYXJ0aWFsbHkgZm9yIFJlcXVlc3RzLiBCdXQgZmllbGRzIGZvciBNZXNzYWdlcyBhbmQgc29tZSBvZiByZXF1ZXN0cyBhcmUgZG9uZSBkeW5hbWljYWxseSBpbiBzZXRNZXNzYWdlcyAoQm90aCkgYW5kIGluaXRFbWJlZGRlZE1lc3NhZ2VEYXRhIChSZXF1ZXN0IG9ubHkpXG5cblx0XHR2YXIgcGFnZXJfZGF0YSA9IHRoaXMubmF2aWdhdGlvbiAmJiB0aGlzLm5hdmlnYXRpb24uZ2V0UGFnZXJEYXRhICYmIHRoaXMubmF2aWdhdGlvbi5nZXRQYWdlckRhdGEoKTtcblx0XHR2YXIgc291cmNlX2RhdGEgPSB0aGlzLm5hdmlnYXRpb24gJiYgdGhpcy5uYXZpZ2F0aW9uLmdldFNvdXJjZURhdGEgJiYgdGhpcy5uYXZpZ2F0aW9uLmdldFNvdXJjZURhdGEoKTtcblx0XHRzdXBlci5idWlsZEVkaXRWaWV3VUkoKTtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXG5cdFx0Ly8gVGhpcyBpcyBhY3R1YWxseSB1cGRhdGVkIGluIHN3aXRjaE1lc3NhZ2VPclJlcXVlc3RXaWRnZXRzIGRlcGVuZGluZyBvbiB2aWV3IHR5cGVcblx0XHR2YXIgdGFiX21vZGVsID0ge1xuXHRcdFx0J3RhYl9tZXNzYWdlJzogeyBcblx0XHRcdFx0J2xhYmVsJzogJC5pMThuLl8oICdNZXNzYWdlJyApXG5cdFx0XHR9XG5cdFx0fTtcblx0XHR0aGlzLnNldFRhYk1vZGVsKCB0YWJfbW9kZWwgKTtcblxuXHRcdGlmICggIXRoaXMuZWRpdF9vbmx5X21vZGUgKSB7XG5cdFx0XHR0aGlzLm5hdmlnYXRpb24uQUNvbWJvQm94KCB7XG5cdFx0XHRcdGFwaV9jbGFzczogVFRBUEkuQVBJTWVzc2FnZUNvbnRyb2wsXG5cdFx0XHRcdGlkOiB0aGlzLnNjcmlwdF9uYW1lICsgJ19uYXZpZ2F0aW9uJyxcblx0XHRcdFx0YWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uOiBmYWxzZSxcblx0XHRcdFx0bGF5b3V0X25hbWU6ICdnbG9iYWxfbWVzc2FnZV91c2VyJyxcblx0XHRcdFx0bmF2aWdhdGlvbl9tb2RlOiB0cnVlLFxuXHRcdFx0XHRzaG93X3NlYXJjaF9pbnB1dHM6IHRydWVcblx0XHRcdH0gKTtcblx0XHRcdHRoaXMuc2V0TmF2aWdhdGlvbigpO1xuXHRcdH1cblxuXHRcdGlmICggcGFnZXJfZGF0YSAmJiBzb3VyY2VfZGF0YSApIHtcblx0XHRcdHRoaXMubmF2aWdhdGlvbi5zZXRTb3VyY2VEYXRhKCBzb3VyY2VfZGF0YSApO1xuXHRcdFx0dGhpcy5uYXZpZ2F0aW9uLnNldFBhZ2VyRGF0YSggcGFnZXJfZGF0YSApO1xuXHRcdH1cblxuXHRcdC8vVGFiIDAgc3RhcnRcblxuXHRcdHZhciBmb3JtX2l0ZW1faW5wdXQ7XG5cblx0XHR2YXIgdGFiX21lc3NhZ2UgPSB0aGlzLmVkaXRfdmlld190YWIuZmluZCggJyN0YWJfbWVzc2FnZScgKTtcblxuXHRcdHZhciB0YWJfbWVzc2FnZV9jb2x1bW4xID0gdGFiX21lc3NhZ2UuZmluZCggJy5maXJzdC1jb2x1bW4nICk7XG5cblx0XHR2YXIgdGFiX21lc3NhZ2VfY29sdW1uMiA9IHRhYl9tZXNzYWdlLmZpbmQoICcuc2Vjb25kLWNvbHVtbicgKTtcblxuXHRcdHRoaXMuZWRpdF92aWV3X3RhYnNbMF0gPSBbXTtcblxuXHRcdHRoaXMuZWRpdF92aWV3X3RhYnNbMF0ucHVzaCggdGFiX21lc3NhZ2VfY29sdW1uMSApO1xuXHRcdHRoaXMuZWRpdF92aWV3X3RhYnNbMF0ucHVzaCggdGFiX21lc3NhZ2VfY29sdW1uMiApO1xuXHRcdHRhYl9tZXNzYWdlX2NvbHVtbjIuY3NzKCAnZGlzcGxheScsICdub25lJyApO1xuXG5cdFx0Ly8gTm93IHNldCB0aGUgZmllbGRzIHVwXG5cblx0XHQvLyAnTWVzc2FnZScgZmllbGRzXG5cdFx0Ly8gIzI3NzUgJ01lc3NhZ2UnIG1lc3NhZ2UgdGhyZWFkcyBmaWVsZHMgbm93IGR5bmFtaWNhbGx5IGJ1aWx0IG9uIHRoZSBmbHkgaW4gc2V0TWVzc2FnZXMoKVxuXG5cdFx0Ly8gJ1JlcXVlc3QnIGZpZWxkc1xuXG5cdFx0Ly8gRW1wbG95ZWVcblx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLlRFWFQgKTtcblx0XHRmb3JtX2l0ZW1faW5wdXQuVFRleHQoIHsgZmllbGQ6ICdmdWxsX25hbWUnLCBzZWxlY3RlZF9hYmxlOiB0cnVlIH0gKTtcblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggJ0VtcGxveWVlJyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9tZXNzYWdlX2NvbHVtbjEsICcnLCBudWxsLCB0cnVlICk7XG5cblx0XHQvLyBEYXRlXG5cdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5URVhUICk7XG5cdFx0Zm9ybV9pdGVtX2lucHV0LlRUZXh0KCB7IGZpZWxkOiAnZGF0ZV9zdGFtcCcsIHNlbGVjdGVkX2FibGU6IHRydWUgfSApO1xuXHRcdHRoaXMuYWRkRWRpdEZpZWxkVG9Db2x1bW4oICQuaTE4bi5fKCAnRGF0ZScgKSwgZm9ybV9pdGVtX2lucHV0LCB0YWJfbWVzc2FnZV9jb2x1bW4xLCAnJywgbnVsbCwgdHJ1ZSApO1xuXG5cdFx0Ly8gVHlwZVxuXHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuVEVYVCApO1xuXHRcdGZvcm1faXRlbV9pbnB1dC5UVGV4dCggeyBmaWVsZDogJ3R5cGUnLCBzZWxlY3RlZF9hYmxlOiB0cnVlIH0gKTtcblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggJ1R5cGUnICksIGZvcm1faXRlbV9pbnB1dCwgdGFiX21lc3NhZ2VfY29sdW1uMSwgJycsIG51bGwsIHRydWUgKTtcblxuXHRcdC8vIHRhYl9tZXNzYWdlIGZpcnN0IGNvbHVtbiBlbmRcblxuXHRcdC8vICdSZXF1ZXN0JyBTZXBhcmF0ZWQgQm94IGZvciAnTWVzc2FnZXMnIEhlYWRlclxuXG5cdFx0dmFyIHNlcGFyYXRlZF9ib3ggPSB0YWJfbWVzc2FnZS5maW5kKCAnLnNlcGFyYXRlJyApO1xuXG5cdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5TRVBBUkFURURfQk9YICk7XG5cdFx0Zm9ybV9pdGVtX2lucHV0LlNlcGFyYXRlZEJveCggeyBsYWJlbDogJC5pMThuLl8oICdNZXNzYWdlcycgKSB9ICk7XG5cdFx0dGhpcy5hZGRFZGl0RmllbGRUb0NvbHVtbiggbnVsbCwgZm9ybV9pdGVtX2lucHV0LCBzZXBhcmF0ZWRfYm94LCAnJywgbnVsbCwgdHJ1ZSwgbnVsbCwgJ3NlcGFyYXRlZF9ib3gnICk7XG5cblx0XHQvLyAjMjc3NSBSZXF1ZXN0IG1lc3NhZ2UgdGhyZWFkIGZpZWxkcyBub3cgZ2VuZXJhdGVkIGJ5IGluaXRFbWJlZGRlZE1lc3NhZ2VEYXRhKCkgYW5kIHNldE1lc3NhZ2VzKClcblxuXHRcdC8vIFRhYiAwIHNlY29uZCBjb2x1bW4gZW5kXG5cblx0XHQvLyAnTmV3IChhZGQpJyBhbmQgJ1JlcGx5IChlZGl0KScgZmllbGRzXG5cblx0XHQvLyBFbXBsb3llZSAtICdOZXcnIHZpZXdcblx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLkFXRVNPTUVfQk9YICk7XG5cdFx0Zm9ybV9pdGVtX2lucHV0LkFDb21ib0JveCgge1xuXHRcdFx0YXBpX2NsYXNzOiBUVEFQSS5BUElNZXNzYWdlQ29udHJvbCxcblx0XHRcdGNvbHVtbl9vcHRpb25fa2V5OiAndXNlcl9jb2x1bW5zJyxcblx0XHRcdGFsbG93X211bHRpcGxlX3NlbGVjdGlvbjogdHJ1ZSxcblx0XHRcdGxheW91dF9uYW1lOiAnZ2xvYmFsX21lc3NhZ2VfdXNlcicsXG5cdFx0XHRzaG93X3NlYXJjaF9pbnB1dHM6IHRydWUsXG5cdFx0XHRzZXRfZW1wdHk6IHRydWUsXG5cdFx0XHRjdXN0b21fa2V5X25hbWU6ICdVc2VyJyxcblx0XHRcdGZpZWxkOiAndG9fdXNlcl9pZCdcblx0XHR9ICk7XG5cdFx0dmFyIGRlZmF1bHRfYXJncyA9IHt9O1xuXHRcdGRlZmF1bHRfYXJncy5wZXJtaXNzaW9uX3NlY3Rpb24gPSAnbWVzc2FnZSc7XG5cdFx0Zm9ybV9pdGVtX2lucHV0LnNldERlZmF1bHRBcmdzKCBkZWZhdWx0X2FyZ3MgKTtcblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggJ0VtcGxveWVlKHMpJyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9tZXNzYWdlX2NvbHVtbjEsICcnLCBudWxsLCB0cnVlICk7XG5cblx0XHQvLyBFbXBsb3llZShzKSAtICdSZXBseScgdmlld1xuXHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuVEVYVCApO1xuXHRcdGZvcm1faXRlbV9pbnB1dC5UVGV4dCggeyBmaWVsZDogJ2Zyb21fZnVsbF9uYW1lJyB9ICk7XG5cdFx0dGhpcy5hZGRFZGl0RmllbGRUb0NvbHVtbiggJC5pMThuLl8oICdFbXBsb3llZShzKScgKSwgZm9ybV9pdGVtX2lucHV0LCB0YWJfbWVzc2FnZV9jb2x1bW4xLCAnJywgbnVsbCwgdHJ1ZSApO1xuXG5cdFx0Ly8gU3ViamVjdCAtIHNoYXJlZCB3aXRoIHRoZSBuZXcvYWRkICYgcmVwbHkvZWRpdCB2aWV3XG5cdFx0Ly8gRGV2IE5vdGUsIGluIG9sZCByZXBseSB2aWV3IGNvZGUsIHRoZSB3aWR0aCB3YXMgcGFzc2VkIGFzIDM1OS4gU2hvdWxkIHRoYXQgYmUgaW5jb3Jwb3JhdGVkIGhlcmU/XG5cdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5URVhUX0lOUFVUICk7XG5cdFx0Zm9ybV9pdGVtX2lucHV0LlRUZXh0SW5wdXQoIHsgZmllbGQ6ICdzdWJqZWN0JyB9ICk7XG5cdFx0dGhpcy5hZGRFZGl0RmllbGRUb0NvbHVtbiggJC5pMThuLl8oICdTdWJqZWN0JyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9tZXNzYWdlX2NvbHVtbjEsICcnLCBudWxsLCB0cnVlICk7XG5cblx0XHQvLyBCb2R5ICAtIHNoYXJlZCB3aXRoIHRoZSBuZXcvYWRkICYgcmVwbHkvZWRpdCB2aWV3XG5cdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5URVhUX0FSRUEgKTtcblx0XHRmb3JtX2l0ZW1faW5wdXQuVFRleHRBcmVhKCB7IGZpZWxkOiAnYm9keScsIHdpZHRoOiA2MDAsIGhlaWdodDogNDAwIH0gKTtcblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggJ0JvZHknICksIGZvcm1faXRlbV9pbnB1dCwgdGFiX21lc3NhZ2VfY29sdW1uMSwgJycsIG51bGwsIHRydWUsIHRydWUgKTtcblx0fVxuXG5cdHNldEVkaXRWaWV3V2lkZ2V0c01vZGUoKSB7XG5cdFx0dGhpcy5zd2l0Y2hNZXNzYWdlT3JSZXF1ZXN0V2lkZ2V0cygpO1xuXHRcdHN1cGVyLnNldEVkaXRWaWV3V2lkZ2V0c01vZGUoKTtcblx0fVxuXG5cdHN3aXRjaE1lc3NhZ2VPclJlcXVlc3RXaWRnZXRzKCkge1xuXHRcdC8vIFVJIGZpZWxkIGJ1aWxkaW5nIGlzIGRvbmUgZnJvbSBidWlsZEVkaXRWaWV3VUkoKSwgYW5kIHNldE1lc3NhZ2VzKCkgZm9yIE1lc3NhZ2VzIGFuZCBSZXF1ZXN0cyAoQWxzbyBpbml0RW1iZWRkZWRNZXNzYWdlRGF0YSkuXG5cdFx0Ly8gVGhpcyBmdW5jdGlvbiBzaG93cy9oaWRlcyB2YXJpb3VzIGZpZWxkcyBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgdmlldyBpcyBkaXNwbGF5aW5nIGEgbWVzc2FnZSBvciByZXF1ZXN0LCB0byByZWR1Y2UgcmUtYnVpbGRpbmcgdGhlIGZvcm0gZWxlbWVudHMsIGluc3RlYWQgc2ltcGx5IGhpZGluZyBhbmQgc2hvd2luZyB0aGUgcmlnaHQgb25lcy5cblx0XHR2YXIgdGFiX2xhYmVsO1xuXG5cdFx0Ly8gRGV0YWNoIGFsbCBmaWVsZHMsIGZ1cnRoZXIgZG93biB3ZSBqdXN0IGF0dGFjaCB0aGUgb25lcyB3ZSBuZWVkIGZvciB0aGUgdmlld1xuXHRcdGZvciAoIHZhciBrZXkgaW4gdGhpcy5lZGl0X3ZpZXdfdWlfZGljICkge1xuXHRcdFx0aWYgKCAhdGhpcy5lZGl0X3ZpZXdfdWlfZGljLmhhc093blByb3BlcnR5KCBrZXkgKSApIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmRldGFjaEVsZW1lbnQoIGtleSApO1xuXHRcdH1cblxuXHRcdC8vIERldGFjaCB0aGUgUmVxdWVzdCBNZXNzYWdlcyBoZWFkZXIgbGFiZWwgYm94IGFuZCBoaWRlIHBhcmVudCBjb250YWluZXJcblx0XHR0aGlzLmRldGFjaEVsZW1lbnQoICdzZXBhcmF0ZWRfYm94JyApO1xuXG5cdFx0Ly8gUmVtb3ZlIG1lc3NhZ2UgbGlzdCBmb3IgYm90aCBNZXNzYWdlIHR5cGUgYW5kIFJlcXVlc3QgdHlwZSAtIE1lc3NhZ2UgVUkgZmllbGRzIGRvIG5vdCBkZXRhY2gsIHdlIGp1c3QgcmVtb3ZlIHRoZW0sIGFzIHRoZXkgYXJlIGR5bmFtaWNhbGx5IGJ1aWx0IG9uIHRoZSBmbHkuXG5cdFx0dGhpcy5lZGl0X3ZpZXdfdGFiLmZpbmQoICcjdGFiX21lc3NhZ2UnICkuZmluZCggJy5lZGl0LXZpZXctdGFiIC5zZWNvbmQtY29sdW1uLm1lc3NhZ2UtY29udGFpbmVyJyApLnJlbW92ZSgpO1xuXG5cdFx0aWYgKCB0aGlzLmlzX3JlcXVlc3QgKSB7XG5cdFx0XHR0YWJfbGFiZWwgPSAnUmVxdWVzdCc7XG5cdFx0XHR0aGlzLmF0dGFjaEVsZW1lbnQoICdmdWxsX25hbWUnICk7XG5cdFx0XHR0aGlzLmF0dGFjaEVsZW1lbnQoICdkYXRlX3N0YW1wJyApO1xuXHRcdFx0dGhpcy5hdHRhY2hFbGVtZW50KCAndHlwZScgKTtcblx0XHRcdHRoaXMuYXR0YWNoRWxlbWVudCggJ3NlcGFyYXRlZF9ib3gnICk7XG5cblx0XHRcdC8vIEluIHNob3cgdGhlIG1haW4gY29udGFpbmVyIHdoaWNoIGhvbGRzIHRoZSBmaWVsZHMuXG5cdFx0XHR0aGlzLmVkaXRfdmlld190YWIuZmluZCggJyN0YWJfbWVzc2FnZScgKS5maW5kKCAnLmVkaXQtdmlldy10YWIgLmZpcnN0LWNvbHVtbicgKS5zaG93KCk7XG5cblx0XHR9IGVsc2UgaWYgKCB0aGlzLmlzX21lc3NhZ2UgKSB7XG5cdFx0XHR0YWJfbGFiZWwgPSAnTWVzc2FnZSc7XG5cdFx0XHQvLyAjMjc3NSBObyBsb25nZXIgYXR0YWNoaW5nIGVsZW1lbnRzIGhlcmUsIGFzIHRoZSBNZXNzYWdlcyBmaWVsZHMgYXJlIGR5bmFtaWNhbGx5IGJ1aWx0IGluIHNldE1lc3NhZ2VzXG5cblx0XHRcdC8vIEhpZGUgdGhlIGZpcnN0LWNvbHVtbiBmaWVsZCwgYXMgdGhpcyBpcyBub3QgdXNlZCBieSBtZXNzYWdlcywgYnV0IGNhdXNlcyBhIGJvcmRlciB0byBiZSBzaG93biBhdCB0aGUgdG9wLiBIaWRpbmcgb25seSBoZXJlIHJhdGhlciB0aGFuIGF0IHRoZSB0b3AsIHRvIHJlZHVjZSBmbGFzaGluZyAoaWYgYW55KVxuXHRcdFx0dGhpcy5lZGl0X3ZpZXdfdGFiLmZpbmQoICcjdGFiX21lc3NhZ2UnICkuZmluZCggJy5lZGl0LXZpZXctdGFiIC5maXJzdC1jb2x1bW4nICkuaGlkZSgpO1xuXG5cdFx0fSBlbHNlIGlmICggdGhpcy5pc19hZGQgKSB7XG5cdFx0XHR0YWJfbGFiZWwgPSAnTmV3IE1lc3NhZ2UnO1xuXHRcdFx0dGhpcy5hdHRhY2hFbGVtZW50KCAndG9fdXNlcl9pZCcgKTtcblx0XHRcdHRoaXMuYXR0YWNoRWxlbWVudCggJ3N1YmplY3QnICk7XG5cdFx0XHR0aGlzLmF0dGFjaEVsZW1lbnQoICdib2R5JyApO1xuXG5cdFx0XHQvLyBTaG93IHRoZSBtYWluIGNvbnRhaW5lciB3aGljaCBob2xkcyB0aGUgZmllbGRzLlxuXHRcdFx0dGhpcy5lZGl0X3ZpZXdfdGFiLmZpbmQoICcjdGFiX21lc3NhZ2UnICkuZmluZCggJy5lZGl0LXZpZXctdGFiIC5maXJzdC1jb2x1bW4nICkuc2hvdygpO1xuXG5cdFx0fSBlbHNlIGlmICggdGhpcy5pc19lZGl0ICkge1xuXHRcdFx0dGFiX2xhYmVsID0gJ1JlcGx5Jztcblx0XHRcdHRoaXMuYXR0YWNoRWxlbWVudCggJ2Zyb21fZnVsbF9uYW1lJyApO1xuXHRcdFx0dGhpcy5hdHRhY2hFbGVtZW50KCAnc3ViamVjdCcgKTtcblx0XHRcdHRoaXMuYXR0YWNoRWxlbWVudCggJ2JvZHknICk7XG5cblx0XHRcdC8vIFNob3cgdGhlIG1haW4gY29udGFpbmVyIHdoaWNoIGhvbGRzIHRoZSBmaWVsZHMuXG5cdFx0XHR0aGlzLmVkaXRfdmlld190YWIuZmluZCggJyN0YWJfbWVzc2FnZScgKS5maW5kKCAnLmVkaXQtdmlldy10YWIgLmZpcnN0LWNvbHVtbicgKS5zaG93KCk7XG5cdFx0fVxuXG5cdFx0dmFyIHRhYl9tb2RlbCA9IHtcblx0XHRcdCd0YWJfbWVzc2FnZSc6IHsgJ2xhYmVsJzogJC5pMThuLl8oIHRhYl9sYWJlbCApLCAnaXNfbXVsdGlfY29sdW1uJzogdHJ1ZSB9XG5cdFx0fTtcblx0XHR0aGlzLnNldFRhYk1vZGVsKCB0YWJfbW9kZWwgKTtcblx0fVxuXG5cdHJlZnJlc2hDdXJyZW50UmVjb3JkKCkge1xuXHRcdHZhciBuZXh0X3NlbGVjdF9pdGVtID0gdGhpcy5uYXZpZ2F0aW9uLmdldEl0ZW1CeUluZGV4KCB0aGlzLm5hdmlnYXRpb24uZ2V0U2VsZWN0SW5kZXgoKSApO1xuXHRcdFByb2dyZXNzQmFyLnNob3dPdmVybGF5KCk7XG5cdFx0dGhpcy5vblZpZXdDbGljayggbmV4dF9zZWxlY3RfaXRlbSApOyAvL0RvbnQgcmVmcmVzaCBVSVxuXHRcdHRoaXMuc2V0TmF2aWdhdGlvbkFycm93c0VuYWJsZWQoKTtcblx0fVxuXG5cdG9uUmlnaHRPckxlZnRBcnJvd0NsaWNrQ2FsbEJhY2soIG5leHRfc2VsZWN0X2l0ZW0gKSB7XG5cdFx0UHJvZ3Jlc3NCYXIuc2hvd092ZXJsYXkoKTtcblx0XHR0aGlzLm9uVmlld0NsaWNrKCBuZXh0X3NlbGVjdF9pdGVtICk7IC8vRG9udCByZWZyZXNoIFVJXG5cdFx0dGhpcy5zZXROYXZpZ2F0aW9uQXJyb3dzRW5hYmxlZCgpO1xuXHR9XG5cblx0b25BZGRDbGljaygpIHtcblxuXHRcdFRUUHJvbWlzZS5hZGQoICdNZXNzYWdlJywgJ2FkZCcgKTtcblx0XHRUVFByb21pc2Uud2FpdCgpO1xuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cdFx0dGhpcy5pc192aWV3aW5nID0gZmFsc2U7XG5cdFx0dGhpcy5pc19lZGl0ID0gZmFsc2U7XG5cdFx0dGhpcy5pc19hZGQgPSB0cnVlO1xuXHRcdHRoaXMuaXNSZWxvYWRWaWV3VUkgPSBmYWxzZTtcblx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X2RvaW5nX2NvbnRleHRfYWN0aW9uID0gJ25ldyc7XG5cdFx0dGhpcy5pc19yZXF1ZXN0ID0gZmFsc2U7XG5cdFx0dGhpcy5pc19tZXNzYWdlID0gZmFsc2U7XG5cdFx0JHRoaXMub3BlbkVkaXRWaWV3KCk7XG5cblx0XHR2YXIgcmVzdWx0X2RhdGEgPSB7fTtcblx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmRlZmF1bHRfZmlsdGVyX2Zvcl9uZXh0X29wZW5fdmlldyApIHtcblx0XHRcdHJlc3VsdF9kYXRhLnRvX3VzZXJfaWQgPSBMb2NhbENhY2hlRGF0YS5kZWZhdWx0X2ZpbHRlcl9mb3JfbmV4dF9vcGVuX3ZpZXcudG9fdXNlcl9pZDtcblx0XHRcdExvY2FsQ2FjaGVEYXRhLmRlZmF1bHRfZmlsdGVyX2Zvcl9uZXh0X29wZW5fdmlldyA9IG51bGw7XG5cdFx0fVxuXHRcdCR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQgPSByZXN1bHRfZGF0YTtcblx0XHQkdGhpcy5pbml0RWRpdFZpZXcoKTtcblx0fVxuXG5cdGluaXRFZGl0VmlldygpIHtcblx0XHRzdXBlci5pbml0RWRpdFZpZXcoKTtcblx0XHRUVFByb21pc2UucmVzb2x2ZSggJ01lc3NhZ2UnLCAnYWRkJyApO1xuXHR9XG5cblx0c2V0RWRpdE1lbnVBZGRJY29uKCBjb250ZXh0X2J0biApIHtcblx0XHRpZiAoIHRoaXMuZWRpdF9vbmx5X21vZGUgKSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuaGlkZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdH1cblx0XHRpZiAoIHRoaXMuaXNfYWRkIHx8IHRoaXMuaXNfY2hhbmdlZCApIHtcblx0XHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIGZhbHNlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIHRydWUgKTtcblx0XHR9XG5cdH1cblxuXHRzZXRFZGl0TWVudUVkaXRJY29uKCBjb250ZXh0X2J0biApIHtcblx0XHRpZiAoIHRoaXMuZWRpdF9vbmx5X21vZGUgKSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuaGlkZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdH1cblx0XHRpZiAoICF0aGlzLmlzX3ZpZXdpbmcgKSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdH1cblx0fVxuXG5cdHNldEVkaXRNZW51RGVsZXRlSWNvbiggY29udGV4dF9idG4gKSB7XG5cdFx0aWYgKCB0aGlzLmVkaXRfb25seV9tb2RlICkge1xuXHRcdFx0Q29udGV4dE1lbnVNYW5hZ2VyLmhpZGVNZW51SXRlbSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkLCBjb250ZXh0X2J0bi5pZCwgZmFsc2UgKTtcblx0XHR9XG5cdFx0aWYgKCAhdGhpcy5jdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YSB8fFxuXHRcdFx0dGhpcy5pc19lZGl0IHx8XG5cdFx0XHR0aGlzLmlzX2FkZCApIHtcblxuXHRcdFx0Q29udGV4dE1lbnVNYW5hZ2VyLmRpc2FibGVNZW51SXRlbSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkLCBjb250ZXh0X2J0bi5pZCwgZmFsc2UgKTtcblx0XHR9XG5cdH1cblxuXHRzZXRFZGl0TWVudURlbGV0ZUFuZE5leHRJY29uKCBjb250ZXh0X2J0biApIHtcblx0XHRpZiAoIHRoaXMuZWRpdF9vbmx5X21vZGUgKSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuaGlkZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdH1cblx0XHRpZiAoICF0aGlzLmN1cnJlbnRfc2VsZWN0X21lc3NhZ2VfY29udHJvbF9kYXRhIHx8XG5cdFx0XHR0aGlzLmlzX2VkaXQgfHxcblx0XHRcdHRoaXMuaXNfYWRkICkge1xuXG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdH1cblx0fVxuXG5cdHZhbGlkYXRlKCkge1xuXG5cdFx0dmFyICR0aGlzID0gdGhpcztcblxuXHRcdHZhciByZWNvcmQgPSB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQ7XG5cblx0XHRpZiAoIEdsb2JhbC5pc1NldCggdGhpcy5lZGl0X3ZpZXdfdWlfZGljWydzdWJqZWN0J10gKSApIHtcblx0XHRcdHJlY29yZC5zdWJqZWN0ID0gdGhpcy5lZGl0X3ZpZXdfdWlfZGljWydzdWJqZWN0J10uZ2V0VmFsdWUoKTtcblx0XHR9IGVsc2UgaWYgKCBHbG9iYWwuaXNTZXQoIHRoaXMuZWRpdF92aWV3X3VpX2RpY1snbWVzc2FnZV9zdWJqZWN0J10gKSApIHtcblx0XHRcdHJlY29yZC5zdWJqZWN0ID0gdGhpcy5lZGl0X3ZpZXdfdWlfZGljWydtZXNzYWdlX3N1YmplY3QnXS5nZXRWYWx1ZSgpO1xuXHRcdH0gZWxzZSBpZiAoIEdsb2JhbC5pc1NldCggdGhpcy5lZGl0X3ZpZXdfdWlfZGljWydyZXF1ZXN0X3N1YmplY3QnXSApICkge1xuXHRcdFx0cmVjb3JkLnN1YmplY3QgPSB0aGlzLmVkaXRfdmlld191aV9kaWNbJ3JlcXVlc3Rfc3ViamVjdCddLmdldFZhbHVlKCk7XG5cdFx0fVxuXHRcdHJlY29yZCA9IHRoaXMudW5pZm9ybVZhcmlhYmxlKCByZWNvcmQgKTtcblxuXHRcdHRoaXMuYXBpWyd2YWxpZGF0ZScgKyB0aGlzLmFwaS5rZXlfbmFtZV0oIHJlY29yZCwge1xuXHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXN1bHQgKSB7XG5cdFx0XHRcdCR0aGlzLnZhbGlkYXRlUmVzdWx0KCByZXN1bHQgKTtcblxuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxuXG5cdG9uU2F2ZUNsaWNrKCBpZ25vcmVXYXJuaW5nICkge1xuXHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb24gPSAnc2F2ZSc7XG5cdFx0dGhpcy5jb2xsZWN0VUlEYXRhVG9DdXJyZW50RWRpdFJlY29yZCgpO1xuXHRcdHZhciByZWNvcmQgPSB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQ7XG5cdFx0aWYgKCAhR2xvYmFsLmlzU2V0KCBpZ25vcmVXYXJuaW5nICkgKSB7XG5cdFx0XHRpZ25vcmVXYXJuaW5nID0gZmFsc2U7XG5cdFx0fVxuXHRcdGlmICggR2xvYmFsLmlzU2V0KCB0aGlzLmVkaXRfdmlld191aV9kaWNbJ3N1YmplY3QnXSApICkge1xuXHRcdFx0cmVjb3JkLnN1YmplY3QgPSB0aGlzLmVkaXRfdmlld191aV9kaWNbJ3N1YmplY3QnXS5nZXRWYWx1ZSgpO1xuXHRcdH0gZWxzZSBpZiAoIEdsb2JhbC5pc1NldCggdGhpcy5lZGl0X3ZpZXdfdWlfZGljWydtZXNzYWdlX3N1YmplY3QnXSApICkge1xuXHRcdFx0cmVjb3JkLnN1YmplY3QgPSB0aGlzLmVkaXRfdmlld191aV9kaWNbJ21lc3NhZ2Vfc3ViamVjdCddLmdldFZhbHVlKCk7XG5cdFx0fSBlbHNlIGlmICggR2xvYmFsLmlzU2V0KCB0aGlzLmVkaXRfdmlld191aV9kaWNbJ3JlcXVlc3Rfc3ViamVjdCddICkgKSB7XG5cdFx0XHRyZWNvcmQuc3ViamVjdCA9IHRoaXMuZWRpdF92aWV3X3VpX2RpY1sncmVxdWVzdF9zdWJqZWN0J10uZ2V0VmFsdWUoKTtcblx0XHR9XG5cdFx0cmVjb3JkID0gdGhpcy51bmlmb3JtVmFyaWFibGUoIHJlY29yZCApO1xuXG5cdFx0dGhpcy5kb1NhdmVBUElDYWxsKCByZWNvcmQsIGlnbm9yZVdhcm5pbmcgKTtcblx0fVxuXG5cdHVuaWZvcm1WYXJpYWJsZSggcmVjb3JkcyApIHtcblx0XHR2YXIgcmVwbHlfZGF0YSA9IHt9O1xuXG5cdFx0aWYgKCB0aGlzLmlzX2VkaXQgKSB7XG5cblx0XHRcdHJlcGx5X2RhdGEuc3ViamVjdCA9IHJlY29yZHMuc3ViamVjdDtcblx0XHRcdHJlcGx5X2RhdGEuYm9keSA9IHJlY29yZHMuYm9keTtcblxuXHRcdFx0Ly8gbWVzc2FnZVxuXHRcdFx0aWYgKCByZWNvcmRzLm9iamVjdF90eXBlX2lkICE9IDUwICkge1xuXHRcdFx0XHRyZXBseV9kYXRhLnRvX3VzZXJfaWQgPSByZWNvcmRzLmZyb21fdXNlcl9pZDtcblx0XHRcdFx0cmVwbHlfZGF0YS5vYmplY3RfdHlwZV9pZCA9IDU7XG5cdFx0XHRcdHJlcGx5X2RhdGEub2JqZWN0X2lkID0gTG9jYWxDYWNoZURhdGEubG9naW5Vc2VyLmlkO1xuXHRcdFx0XHRyZXBseV9kYXRhLnBhcmVudF9pZCA9IHJlY29yZHMuaWQ7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIHJlcXVlc3RcblxuXHRcdFx0XHRyZXBseV9kYXRhLm9iamVjdF9pZCA9IHJlY29yZHMub2JqZWN0X2lkO1xuXG5cdFx0XHRcdHJlcGx5X2RhdGEudG9fdXNlcl9pZCA9IExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlci5pZDtcblx0XHRcdFx0cmVwbHlfZGF0YS5vYmplY3RfdHlwZV9pZCA9IDUwO1xuXG5cdFx0XHRcdHJlcGx5X2RhdGEucGFyZW50X2lkID0gMTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHJlcGx5X2RhdGE7XG5cblx0XHR9XG5cblx0XHRpZiAoIHRoaXMuaXNfYWRkICkge1xuXHRcdFx0cmVjb3Jkcy5vYmplY3RfdHlwZV9pZCA9IDU7XG5cdFx0XHRyZWNvcmRzLm9iamVjdF9pZCA9IExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlci5pZDtcblx0XHRcdHJlY29yZHMucGFyZW50X2lkID0gMDtcblx0XHR9XG5cblx0XHRyZXR1cm4gcmVjb3Jkcztcblx0fVxuXG5cdHNlYXJjaCggc2V0X2RlZmF1bHRfbWVudSwgcGFnZV9hY3Rpb24sIHBhZ2VfbnVtYmVyLCBjYWxsQmFjayApIHtcblx0XHR0aGlzLmV2ZW50X2J1cy5lbWl0KCAndHRfdG9wYmFyJywgJ3Byb2ZpbGVfcGVuZGluZ19jb3VudHMnLCB7IC8vVXBkYXRlIGFsbCBcIk15IFByb2ZpbGVcIiBiYWRnZS5cblx0XHRcdG9iamVjdF90eXBlczogWyAnbm90aWZpY2F0aW9uJywgJ21lc3NhZ2UnIF1cblx0XHR9ICk7XG5cdFx0c3VwZXIuc2VhcmNoKCBzZXRfZGVmYXVsdF9tZW51LCBwYWdlX2FjdGlvbiwgcGFnZV9udW1iZXIsIGNhbGxCYWNrICk7XG5cdH1cblxuXHQvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG5cdHNldEN1cnJlbnRFZGl0UmVjb3JkRGF0YSgpIHtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXHRcdC8vIElmIHRoZSBjdXJyZW50X2VkaXRfcmVjb3JkIGlzIGFuIGFycmF5LCB0aGVuIGhhbmRsZSB0aGVtIGluIHNldEVkaXRWaWV3RGF0YURvbmUgZnVuY3Rpb24uXG5cdFx0Ly8gaWYgKCBHbG9iYWwuaXNBcnJheSggdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkICkgKSB7IC8vIENvbW1lbnRpbmcgb3V0IHRvIHRyaWFsIHdoZXRoZXIgc2luZ2xlIG1lc3NhZ2VzIGNhbiBnbyB0aHJvdWdoIHRoaXMgdG9vLlxuXHRcdGlmICggdGhpcy5pc19tZXNzYWdlICkge1xuXHRcdFx0dGhpcy5zZXRNZXNzYWdlcygpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBUT0RPOiBGaWd1cmUgb3V0IHdoZXJlIHRvIHRyaWdnZXIgdGhlIHVuaWZvcm1WYXJpYWJsZSB3b3JrIG9uIHNwbGl0dGluZyBvdXQgdGhlIHN1YmplY3QgYW5kIGJvZHkgZm9yIG1zZy9yZXEgc3R1ZmYuIEhlcmUgb3IgaW4gYWJvdmUgc2VjdGlvbiwgYXMgbXVsdGlwbGUgbWVzc2FnZXMgZ28gZWxzZXdoZXJlPz8/XG5cblx0XHRcdC8vU2V0IGN1cnJlbnQgZWRpdCByZWNvcmQgZGF0YSB0byBhbGwgd2lkZ2V0c1xuXHRcdFx0Zm9yICggdmFyIGtleSBpbiB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQgKSB7XG5cdFx0XHRcdGlmICggIXRoaXMuY3VycmVudF9lZGl0X3JlY29yZC5oYXNPd25Qcm9wZXJ0eSgga2V5ICkgKSB7XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR2YXIgd2lkZ2V0ID0gdGhpcy5lZGl0X3ZpZXdfdWlfZGljW2tleV07XG5cdFx0XHRcdGlmICggR2xvYmFsLmlzU2V0KCB3aWRnZXQgKSApIHtcblx0XHRcdFx0XHQvLyBOb3cgdGhhdCBhbGwgbWVzc2FnZXMgZ28gdGhyb3VnaCBzZXRNZXNzYWdlcygpIGFuZCBubyBsb25nZXIgdGhyb3VnaCB0aGUgYmVsb3csIHdlIGNhbiByZW1vdmUgc29tZSBvZiB0aGUgZmllbGRzIGJlbG93LiBOb3QgZG9uZSB5ZXQgYXMgdGhlcmVzIEFkZC9FZGl0IHRvIGNvbnNpZGVyIGFuZCB0ZXN0IGZpcnN0LlxuXHRcdFx0XHRcdHN3aXRjaCAoIGtleSApIHtcblx0XHRcdFx0XHRcdGNhc2UgJ2Zyb21fZnVsbF9uYW1lJzpcblx0XHRcdFx0XHRcdFx0d2lkZ2V0LnNldFZhbHVlKCB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmRbJ2Zyb21fZmlyc3RfbmFtZSddICsgJyAnICsgdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkWydmcm9tX2xhc3RfbmFtZSddICk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSAndG9fZnVsbF9uYW1lJzpcblx0XHRcdFx0XHRcdFx0d2lkZ2V0LnNldFZhbHVlKCB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmRbJ3RvX2ZpcnN0X25hbWUnXSArICcgJyArIHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFsndG9fbGFzdF9uYW1lJ10gKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlICdmdWxsX25hbWUnOlxuXHRcdFx0XHRcdFx0XHR3aWRnZXQuc2V0VmFsdWUoIHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFsnZmlyc3RfbmFtZSddICsgJyAnICsgdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkWydsYXN0X25hbWUnXSApO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgJ3N1YmplY3QnOlxuXHRcdFx0XHRcdFx0XHRpZiAoIHRoaXMuaXNfZWRpdCApIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIEdsb2JhbC5pc0FycmF5KCB0aGlzLm1lc3NhZ2VzICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR3aWRnZXQuc2V0VmFsdWUoICdSZTogJyArIHRoaXMubWVzc2FnZXNbMF0uc3ViamVjdCApO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR3aWRnZXQuc2V0VmFsdWUoICdSZTogJyArIHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFtrZXldICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIHRoaXMuaXNfdmlld2luZyApIHtcblx0XHRcdFx0XHRcdFx0XHR3aWRnZXQuc2V0VmFsdWUoIHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFtrZXldICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlICdtZXNzYWdlX2JvZHknOlxuXHRcdFx0XHRcdFx0Y2FzZSAncmVxdWVzdF9ib2R5Jzpcblx0XHRcdFx0XHRcdFx0d2lkZ2V0LnNldFZhbHVlKCB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmRba2V5XSApO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRcdHdpZGdldC5zZXRWYWx1ZSggdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkW2tleV0gKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvL3JlcXVlc3Qgd2lsbCBkbyB0aGlzIHdoZW4gaW5pdEVtYmVkZGVkTWVzc2FnZVxuXHRcdFx0aWYgKCB0aGlzLmlzX21lc3NhZ2UgJiYgdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkICYmIHRoaXMuY3VycmVudF9lZGl0X3JlY29yZC5zdGF0dXNfaWQgPT0gMTAgKSB7XG5cdFx0XHRcdHRoaXMuYXBpWydtYXJrUmVjaXBpZW50TWVzc2FnZUFzUmVhZCddKCBbdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmlkXSwge1xuXHRcdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzICkge1xuXHRcdFx0XHRcdFx0JHRoaXMuc2VhcmNoKCBmYWxzZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSApO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLmNvbGxlY3RVSURhdGFUb0N1cnJlbnRFZGl0UmVjb3JkKCk7IC8vICMyNzc1IElmIE1lc3NhZ2VzIHRoZW4sIHdlIGRvIG5vdCB3YW50IHRvIHN0b3JlIGFueSB1aSBmaWVsZHMgdG8gY3VycmVudF9lZGl0X3JlY29yZC4gSXRzIHZpZXcgb25seSwgYW5kIHdlIGRvbnQgaGF2ZSByZWZlcmVuY2VzIHRvIGVhY2ggZ2VuZXJhdGVkIG1lc3NhZ2UgYW55d2F5LCBhcyB0aGV5IGdlbmVyYXRlIG9uIHRoZSBmbHkuXG5cdFx0fVxuXHRcdHRoaXMuc2V0RWRpdFZpZXdEYXRhRG9uZSgpOyAvLyAyNzc1IG5vdGVzOiBhbHNvIHRyaWdnZXIgbW9yZSBkYXRhL3dpZGdldCBoYW5kbGluZyBmb3IgcmVxdWVzdCAoU0lOR0xFK01VTFRJUExFKVxuXHR9XG5cblx0LyoganNoaW50IGlnbm9yZTplbmQgKi9cblx0YXV0b09wZW5FZGl0Vmlld0lmTmVjZXNzYXJ5KCkge1xuXHRcdC8vQXV0byBvcGVuIGVkaXQgdmlldy4gU2hvdWxkIHNldCBpbiBJbmRleENvbnRyb2xsZXJcblxuXHRcdHN3aXRjaCAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb24gKSB7XG5cdFx0XHRjYXNlICd2aWV3Jzpcblx0XHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5lZGl0X2lkX2Zvcl9uZXh0X29wZW5fdmlldyApIHtcblx0XHRcdFx0XHR2YXIgaXRlbSA9IHt9O1xuXHRcdFx0XHRcdGl0ZW0uaWQgPSBMb2NhbENhY2hlRGF0YS5lZGl0X2lkX2Zvcl9uZXh0X29wZW5fdmlldztcblx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmdldEFsbFVSTEFyZ3MoKS50ID09PSAncmVxdWVzdCcgKSB7XG5cdFx0XHRcdFx0XHRpdGVtLm9iamVjdF9pZCA9IExvY2FsQ2FjaGVEYXRhLmdldEFsbFVSTEFyZ3MoKS5vYmplY3RfaWQ7XG5cdFx0XHRcdFx0XHRpdGVtLm9iamVjdF90eXBlX2lkID0gNTA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMub25WaWV3Q2xpY2soIGl0ZW0gKTtcblx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5lZGl0X2lkX2Zvcl9uZXh0X29wZW5fdmlldyA9IG51bGw7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICduZXcnOlxuXHRcdFx0XHR0aGlzLm9uQWRkQ2xpY2soKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXG5cdFx0dGhpcy5hdXRvT3BlbkVkaXRPbmx5Vmlld0lmTmVjZXNzYXJ5KCk7XG5cdH1cblxuXHRnZXREZWxldGVTZWxlY3RlZFJlY29yZElkKCkge1xuXHRcdHZhciByZXR2YWwgPSBbXTtcblx0XHRpZiAoIHRoaXMuZWRpdF92aWV3ICkge1xuXHRcdFx0aWYgKCAhdGhpcy5jdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YSApIHtcblx0XHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93QWxlcnQoICQuaTE4bi5fKCAnSW52YWxpZCBNZXNzYWdlIGlkJyApICk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdHJldHZhbC5wdXNoKCB0aGlzLmN1cnJlbnRfc2VsZWN0X21lc3NhZ2VfY29udHJvbF9kYXRhLmlkICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHZhbCA9IHN1cGVyLmdldERlbGV0ZVNlbGVjdGVkUmVjb3JkSWQoKTtcblx0XHR9XG5cdFx0cmV0dXJuIHJldHZhbDtcblx0fVxuXG5cdGRvRGVsZXRlQVBJQ2FsbCggcmVtb3ZlX2lkcywgX2NhbGxiYWNrICkge1xuXHRcdHZhciBjYWxsYmFjayA9IF9jYWxsYmFjayB8fCB7XG5cdFx0XHRvblJlc3VsdDogZnVuY3Rpb24oIHJlc3VsdCApIHtcblx0XHRcdFx0dGhpcy5pc1JlbG9hZFZpZXdVSSA9IGZhbHNlO1xuXHRcdFx0XHR0aGlzLm9uRGVsZXRlUmVzdWx0KCByZXN1bHQsIHJlbW92ZV9pZHMgKTtcblx0XHRcdH0uYmluZCggdGhpcyApXG5cdFx0fTtcblx0XHRyZXR1cm4gdGhpcy5hcGlbJ2RlbGV0ZScgKyB0aGlzLmFwaS5rZXlfbmFtZV0oIHJlbW92ZV9pZHMsIHRoaXMuZm9sZGVyX2lkLCBjYWxsYmFjayApO1xuXHR9XG5cblx0c2V0RWRpdFZpZXdEYXRhRG9uZSgpIHtcblx0XHQvLyBUT0RPOiBSZWZhY3RvciB0aGlzIHRvIG1vdmUgaW50byBzZXRDdXJyZW50RWRpdFJlY29yZERhdGEsIGFzIHRoaXMgaXMgbm90IGNvZGUgdGhhdCBpcyBjbGFzc2VkIGFzIERhdGEgTG9hZCBEb25lLCBpdHMgc3RpbGwgZGF0YSBsb2FkaW5nLlxuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cdFx0c3VwZXIuc2V0RWRpdFZpZXdEYXRhRG9uZSgpO1xuXG5cdFx0aWYgKCB0aGlzLmlzX3ZpZXdpbmcgKSB7XG5cblx0XHRcdGlmICggdGhpcy5pc19yZXF1ZXN0ICkge1xuXHRcdFx0XHR0aGlzLmluaXRFbWJlZGRlZE1lc3NhZ2VEYXRhKCk7XG5cdFx0XHR9XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRpZiAoIEdsb2JhbC5pc1NldCggJHRoaXMubWVzc2FnZXMgKSApIHtcblx0XHRcdFx0JHRoaXMubWVzc2FnZXMgPSBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHNldE1lc3NhZ2VzKCBtZXNzYWdlX2RhdGEgKSB7XG5cdFx0Ly8gVGhpcyBmdW5jdGlvbiBoYW5kbGVzIG1lc3NhZ2UgdGhyZWFkIGdlbmVyYXRpb24gZm9yIGJvdGggdGhlIG1lc3NhZ2UgYW5kIHJlcXVlc3QgdHlwZXMuXG5cdFx0dmFyIHJlYWRfaWRzID0gW107XG5cblx0XHRpZiAoIG1lc3NhZ2VfZGF0YSApIHtcblx0XHRcdHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlX2RhdGE7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMubWVzc2FnZXMgPSB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQ7XG5cdFx0fVxuXG5cdFx0aWYgKCAhR2xvYmFsLmlzQXJyYXkoIHRoaXMubWVzc2FnZXMgKSApIHtcblx0XHRcdC8vIFRoaXMgZnVuY3Rpb24gd29ya3Mgb24gYW4gYXJyYXkgb2YgbWVzc2FnZXMuIElmIHRoZXJlIGlzIG9ubHkgb25lIG1lc3NhZ2UsIHRoZW4gcHJvdmlkZSBhbiBhcnJheSBvZiBvbmUgbWVzc2FnZSBhbmQgcHJvY2VzcyB0aGUgc2FtZSB3YXkuXG5cdFx0XHR0aGlzLm1lc3NhZ2VzID0gW3RoaXMubWVzc2FnZXNdO1xuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSBhbGwgb2xkIG1lc3NhZ2VzIGZpcnN0LlxuXHRcdHRoaXMuZWRpdF92aWV3X3RhYi5maW5kKCAnI3RhYl9tZXNzYWdlJyApLmZpbmQoICcuZWRpdC12aWV3LXRhYiAuc2Vjb25kLWNvbHVtbi5tZXNzYWdlLWNvbnRhaW5lcicgKS5yZW1vdmUoKTtcblxuXHRcdC8qXG5cdFx0ICogTG9vcCB0aHJvdWdoIGFuZCBjcmVhdGUgdGhlIG1lc3NhZ2UgZmllbGRzXG5cdFx0ICovXG5cblx0XHQvLyBDb2xsZWN0aW9uIGNvbnRhaW5lciBmb3IgdGhlIG1lc3NhZ2VzIHRvIGJlIGhlbGQgaW4sIHVudGlsIHRoZXkgYXJlIGFkZGVkIGluIG9uZSBnbyB0byB0aGUgcGFnZS5cblx0XHR2YXIgY29udGFpbmVyID0gJCggJzxkaXY+PC9kaXY+JyApO1xuXG5cdFx0Zm9yICggdmFyIGtleSA9IDA7IGtleSA8IHRoaXMubWVzc2FnZXMubGVuZ3RoOyBrZXkrKyApIHtcblxuXHRcdFx0dmFyIGN1cnJlbnRfaXRlbSA9IHRoaXMubWVzc2FnZXNba2V5XTtcblx0XHRcdGlmICggIWN1cnJlbnRfaXRlbS5oYXNPd25Qcm9wZXJ0eSggJ2lkJyApICkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBjdXJyZW50X2l0ZW0uc3RhdHVzX2lkID09IDEwICkge1xuXHRcdFx0XHRyZWFkX2lkcy5wdXNoKCBjdXJyZW50X2l0ZW0uaWQgKTtcblx0XHRcdH1cblxuXHRcdFx0dmFyIG1lc3NhZ2VfY29udGFpbmVyID0gJCggJzxkaXY+PC9kaXY+JywgeyBjbGFzczogXCJzZWNvbmQtY29sdW1uIGZ1bGwtd2lkdGgtY29sdW1uIG1lc3NhZ2UtY29udGFpbmVyXCIgfSApO1xuXG5cdFx0XHRpZiAoIHRoaXMuaXNfbWVzc2FnZSApIHtcblx0XHRcdFx0dGhpcy5hZGRNZXNzYWdlUm93KCBtZXNzYWdlX2NvbnRhaW5lciwgJ0Zyb20nLCAnbXNnX2Zyb21fZnVsbF9uYW1lJywgY3VycmVudF9pdGVtWydmcm9tX2ZpcnN0X25hbWUnXSArICcgJyArIGN1cnJlbnRfaXRlbVsnZnJvbV9sYXN0X25hbWUnXSApO1xuXHRcdFx0XHR0aGlzLmFkZE1lc3NhZ2VSb3coIG1lc3NhZ2VfY29udGFpbmVyLCAnVG8nLCAnbXNnX3RvX2Z1bGxfbmFtZScsIGN1cnJlbnRfaXRlbVsndG9fZmlyc3RfbmFtZSddICsgJyAnICsgY3VycmVudF9pdGVtWyd0b19sYXN0X25hbWUnXSApO1xuXHRcdFx0XHR0aGlzLmFkZE1lc3NhZ2VSb3coIG1lc3NhZ2VfY29udGFpbmVyLCAnRGF0ZScsICdtc2dfdXBkYXRlZF9kYXRlJywgY3VycmVudF9pdGVtWyd1cGRhdGVkX2RhdGUnXSApO1xuXHRcdFx0XHR0aGlzLmFkZE1lc3NhZ2VSb3coIG1lc3NhZ2VfY29udGFpbmVyLCAnU3ViamVjdCcsICdtc2dfc3ViamVjdCcsIGN1cnJlbnRfaXRlbVsnc3ViamVjdCddICk7XG5cdFx0XHRcdHRoaXMuYWRkTWVzc2FnZVJvdyggbWVzc2FnZV9jb250YWluZXIsICdCb2R5JywgJ21zZ19ib2R5JywgY3VycmVudF9pdGVtWydib2R5J10sIHRydWUsIHRydWUgKTtcblxuXHRcdFx0fSBlbHNlIGlmICggdGhpcy5pc19yZXF1ZXN0ICkge1xuXHRcdFx0XHR0aGlzLmFkZE1lc3NhZ2VSb3coIG1lc3NhZ2VfY29udGFpbmVyLCAnRnJvbScsICdyZXFfZnJvbV9mdWxsX25hbWUnLCBjdXJyZW50X2l0ZW1bJ2Zyb21fZmlyc3RfbmFtZSddICsgJyAnICsgY3VycmVudF9pdGVtWydmcm9tX2xhc3RfbmFtZSddICsgJ0AnICsgY3VycmVudF9pdGVtWyd1cGRhdGVkX2RhdGUnXSApO1xuXHRcdFx0XHR0aGlzLmFkZE1lc3NhZ2VSb3coIG1lc3NhZ2VfY29udGFpbmVyLCAnU3ViamVjdCcsICdyZXFfc3ViamVjdCcsIGN1cnJlbnRfaXRlbVsnc3ViamVjdCddICk7XG5cdFx0XHRcdHRoaXMuYWRkTWVzc2FnZVJvdyggbWVzc2FnZV9jb250YWluZXIsICdCb2R5JywgJ3JlcV9ib2R5JywgY3VycmVudF9pdGVtWydib2R5J10sIHRydWUsIHRydWUgKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gRXJyb3I6IE1lc3NhZ2UgdHlwZSBub3Qgc3VwcG9ydGVkLiBFeGl0LiBDdXJyZW50bHkgb25seSBtZXNzYWdlcyBhbmQgcmVxdWVzdCB0eXBlcyBzdXBwb3J0ZWQuXG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Y29udGFpbmVyLmFwcGVuZCggbWVzc2FnZV9jb250YWluZXIgKTtcblx0XHR9XG5cblx0XHQvLyBBZGQgdGhlIG5ldyBtZXNzYWdlIHRvIHRoZSBwYWdlXG5cdFx0dGhpcy5lZGl0X3ZpZXdfdGFiLmZpbmQoICcjdGFiX21lc3NhZ2UnICkuZmluZCggJy5lZGl0LXZpZXctdGFiJyApLmFwcGVuZCggY29udGFpbmVyLmh0bWwoKSApO1xuXG5cdFx0aWYgKCByZWFkX2lkcy5sZW5ndGggPiAwICkge1xuXHRcdFx0dmFyICR0aGlzID0gdGhpcztcblx0XHRcdHRoaXMuYXBpWydtYXJrUmVjaXBpZW50TWVzc2FnZUFzUmVhZCddKCByZWFkX2lkcywge1xuXHRcdFx0XHRvblJlc3VsdDogZnVuY3Rpb24oIHJlcyApIHtcblx0XHRcdFx0XHQkdGhpcy5zZWFyY2goIGZhbHNlICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHR9XG5cdH1cblxuXHRhZGRNZXNzYWdlUm93KCBtZXNzYWdlX2NvbnRhaW5lciwgbGFiZWwsIGZpZWxkLCB2YWx1ZSwgc2V0X3Jlc2l6ZV9ldmVudCwgcGFyc2VfbGluayApIHtcblx0XHQvLyBOb3RlOiBUYWtlIGV4dHJhIGNhcmUgd2l0aCB0aGlzIGZ1bmN0aW9uLCBhcyB3ZSBhcmUgYnVpbGRpbmcgd2lkZ2V0cyBvdXRzaWRlIG9mIHRoZSBub3JtYWwgaW5pdCBmbG93LCBzbyBjb21wYXJlIHRvIHRoZSBzdGFuZGFyZCBmbG93IG9mIGJ1aWxkRWRpdFZpZXdVSSBpZiBhbnl0aGluZyBvZGQgaGFwcGVucy5cblxuXHRcdHZhciBmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLlRFWFQgKTtcblx0XHRmb3JtX2l0ZW1faW5wdXQuVFRleHQoIHsgZmllbGQ6IGZpZWxkLCBzZWxlY3RlZF9hYmxlOiB0cnVlIH0gKTtcblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggbGFiZWwgKSwgZm9ybV9pdGVtX2lucHV0LCBtZXNzYWdlX2NvbnRhaW5lciwgJycsIG51bGwsIG51bGwsIHNldF9yZXNpemVfZXZlbnQgKTtcblxuXHRcdC8vICMyNzc1IFlvdSBtdXN0IHNldCB0aGUgdmFsdWUgYWZ0ZXIgaXRzIGFkZGVkIHRvIGNvbHVtbiwgbm90IGJlZm9yZSwgb3RoZXJ3aXNlIHRoZSBmaWVsZCBsYWJlbCB3aWxsIG5vdCByZXNpemUgYWZ0ZXIgYSBsYXJnZSB2YWx1ZSBpcyBzZXQuXG5cblx0XHRpZiAoIHBhcnNlX2xpbmsgKSB7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuaHRtbCggdmFsdWUubGlua2lmeSggeyBubDJicjogdHJ1ZSwgY2xhc3NOYW1lOiAnbGlua2lmaWVkJyB9ICkgKTtcblx0XHRcdGZvcm1faXRlbV9pbnB1dC5zZXRSZXNpemVFdmVudCgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuc2V0VmFsdWUoIHZhbHVlICk7XG5cdFx0fVxuXG5cdFx0Ly8gIzI3NzUgWW91IG11c3Qgc2V0IHRoZSBvcGFjaXR5IHRvIDEgYWZ0ZXIgYWRkaW5nIHRvIGNvbHVtbiwgYXMgdGhlIGFkZEVkaXRGaWVsZFRvQ29sdW1uIHNldHMgb3BhY2l0eSB0byAwIGR1cmluZyBsb2FkaW5nLCBhbmQgbm9ybWFsbHkgc2V0IGJhY2sgdG8gMSBhdCB0aGUgYm90dG9tIG9mIEJhc2VWQy5pbml0RWRpdFZpZXdEYXRhIGJ1dCBoZXJlIHdlIGFyZSBidWlsZGluZyB3aWRnZXRzIG91dHNpZGUgb2YgdGhlIG5vcm1hbCBpbml0IGZsb3cuXG5cdFx0Zm9ybV9pdGVtX2lucHV0LmNzcyggJ29wYWNpdHknLCAnMScgKTtcblxuXHRcdC8vIHJlbW92ZSB0aGUgZmllbGQgcmVmZXJlbmNlIGZyb20gdGhpcy5lZGl0X3ZpZXdfdWlfZGljIGFzIHdlIHdvbnQgdHJhY2sgdGhlIG9uLXRoZS1mbHkgYnVpbHQgZmllbGRzLlxuXHRcdGRlbGV0ZSB0aGlzLmVkaXRfdmlld191aV9kaWNbZmllbGRdO1xuXHR9XG5cblx0aW5pdEVtYmVkZGVkTWVzc2FnZURhdGEoKSB7XG5cdFx0Ly8gVXNlZCB0byBnZW5lcmF0ZSB0aGUgbWVzc2FnZSB0aHJlYWRzIGZvciBhIFJlcXVlc3QgdHlwZVxuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cdFx0dmFyIGFyZ3MgPSB7fTtcblx0XHRhcmdzLmZpbHRlcl9kYXRhID0ge307XG5cdFx0YXJncy5maWx0ZXJfZGF0YS5vYmplY3RfdHlwZV9pZCA9IDUwO1xuXHRcdGFyZ3MuZmlsdGVyX2RhdGEub2JqZWN0X2lkID0gdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmlkO1xuXG5cdFx0JHRoaXMuYXBpWydnZXRFbWJlZGRlZE1lc3NhZ2UnXSggYXJncywge1xuXHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXMgKSB7XG5cblx0XHRcdFx0aWYgKCAhJHRoaXMuZWRpdF92aWV3ICkge1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHZhciBkYXRhID0gcmVzLmdldFJlc3VsdCgpO1xuXHRcdFx0XHQkdGhpcy5zZXRNZXNzYWdlcyggZGF0YSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxuXG5cdC8vICMyNzc1IENvbW1lbnRpbmcgb3V0IHRvIGZpeCBhbiBpc3N1ZSB3aGVyZSBEZWxldGUmTmV4dCBkb2VzIG5vdCBnbyB0byB0aGUgbmV4dCByZWNvcmQuIE5vdCAxMDAlIGNlcnRhaW4gd2h5IHRoaXMgaXMgaGVyZSwgYnV0IGFubm90YXRpb25zIHNob3cgc29tZXRoaW5nIHRvIGRvIHdpdGggZmxhc2hpbmcsIHdoaWNoIGRvZXMgbm90IHNlZW0gYW4gaXNzdWUgYXRtLlxuXHQvLyAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG5cdC8vIHNlYXJjaDogZnVuY3Rpb24oIHNldF9kZWZhdWx0X21lbnUsIHBhZ2VfYWN0aW9uLCBwYWdlX251bWJlciwgY2FsbEJhY2sgKSB7XG5cdC8vIFx0dGhpcy5yZWZyZXNoX2lkID0gbnVsbDtcblx0Ly8gXHRzdXBlci5zZWFyY2goIHNldF9kZWZhdWx0X21lbnUsIHBhZ2VfYWN0aW9uLCBwYWdlX251bWJlciwgY2FsbEJhY2sgKTtcblx0Ly8gfVxuXHQvL1xuXHQvLyAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4468\n")}}]);