(self.webpackChunktimetrex=self.webpackChunktimetrex||[]).push([["main_ui","BaseViewController","BaseWindowController","wizard-BaseWizardController","combobox-TComboBox","paging-Paging2","text_input-TPasswordInput","text_input-TTextInput","dynamic-editview-primevue-button","interface_html5_components_context_menu_TTContextButton_vue"],{8678:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"g\": () => (/* binding */ IndexViewController)\n/* harmony export */ });\n/* harmony import */ var _views_TTBackboneView__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6739);\n/* harmony import */ var _services_TTEventBus__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7967);\n/* provided dependency */ var _ = __webpack_require__(9050);\n/* provided dependency */ var $ = __webpack_require__(9755);\n\n\n\nclass ApplicationRouter extends Backbone.Router {\n\tconstructor( options = {} ) {\n\t\t_.defaults( options, {\n\t\t\tcontroller: null,\n\n\t\t\troutes: {\n\t\t\t\t'': 'onViewChange',\n\t\t\t\t'!:viewName': 'onViewChange',\n\t\t\t\t'*notFound': 'notFound'\n\t\t\t}\n\t\t} );\n\n\t\tsuper( options );\n\t\tthis.event_bus = new _services_TTEventBus__WEBPACK_IMPORTED_MODULE_1__/* [\"default\"] */ .Z({ view_id: 'index_controller' });\n\t}\n\n\treloadView( view_id ) {\n\t\t//error: Uncaught ReferenceError: XXXXViewController is not defined ininterface/html5/#!m=TimeSheet line 3\n\t\t// Happens when quickly click on context menu and network is slow.\n\t\tif ( eval( 'typeof '+ view_id + 'ViewController' ) === 'function' && //Was ES5: window[view_id + 'ViewController'] &&\n\t\t\tLocalCacheData.current_open_primary_controller &&\n\t\t\tLocalCacheData.current_open_primary_controller.viewId === view_id ) {\n\t\t\tLocalCacheData.current_open_primary_controller.setSelectLayout();\n\t\t\tLocalCacheData.current_open_primary_controller.search();\n\t\t}\n\t}\n\n\tnotFound( url ) {\n\n\t\tvar new_url = Global.getBaseURL();\n\n\t\tGlobal.setURLToBrowser( new_url + '#!m=Login' );\n\t}\n\n\t/* jshint ignore:start */\n\tonViewChange( viewName ) {\n\t\tvar $this = this;\n\t\tvar args = {};\n\t\tvar view_id;\n\t\tvar edit_id;\n\t\tvar action;\n\t\tvar auto_login_timer;\n\n\t\tif ( Global.needReloadBrowser ) {\n\t\t\tGlobal.needReloadBrowser = false;\n\t\t\twindow.location.reload();\n\t\t\treturn;\n\t\t}\n\n\t\tif ( viewName ) {\n\t\t\targs = Global.buildArgDic( viewName.split( '&' ) );\n\t\t}\n\t\tif ( viewName && viewName.indexOf( 'm=' ) >= 0 ) {\n\t\t\tview_id = Global.sanitizeViewId( args.m );\n\t\t} else {\n\t\t\tview_id = 'Login';\n\t\t}\n\n\t\t// #VueContextMenu# Trigger Vue Router changes\n\t\t// Add interface functions for this once POC works.\n\t\t// console.log('aaaa onViewChange', view_id); // comparing triggers against BaseVC.\n\t\t// VueRouter.push('/view/'+view_id);\n\t\t// End Vue router\n\n\t\tLocalCacheData.fullUrlParameterStr = viewName;\n\t\tLocalCacheData.setAllURLArgs( args );\n\n\t\tif ( view_id == 'Install' ) {\n\t\t\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\t\t\tIndexViewController.openWizard( 'InstallWizard', null, function() {\n\t\t\t\t\t// need to link to the login interface.\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tauto_login_timer = setInterval( function() {\n\t\t\t\t\tif ( timeout_count == 100 ) {\n\t\t\t\t\t\tclearInterval( auto_login_timer );\n\t\t\t\t\t}\n\t\t\t\t\ttimeout_count = timeout_count + 1;\n\t\t\t\t\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\t\t\t\t\tIndexViewController.openWizard( 'InstallWizard', null, function() {\n\t\t\t\t\t\t\t// need to link to the login interface.\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tclearInterval( auto_login_timer );\n\t\t\t\t\t}\n\t\t\t\t}, 600 );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif ( LocalCacheData.getAllURLArgs().sm === 'ResetPassword' && LocalCacheData.getAllURLArgs().key ) {\n\t\t\tIndexViewController.openWizard( 'ResetForgotPasswordWizard', null, function() {\n\t\t\t\tLocalCacheData.setAllURLArgs( _.omit( LocalCacheData.getAllURLArgs(), 'sm' ) );\n\t\t\t\tLocalCacheData.setAllURLArgs( _.omit( LocalCacheData.getAllURLArgs(), 'key' ) );\n\t\t\t\tTAlertManager.showAlert( $.i18n._( 'Password has been changed successfully, you may now login.' ) );\n\t\t\t\tvar new_url = Global.getBaseURL();\n\t\t\t\tGlobal.setURLToBrowser( new_url + '#!m=Login' );\n\t\t\t\treturn;\n\t\t\t} );\n\t\t\treturn;\n\t\t}\n\n\t\tedit_id = args.id; //Accrual id is combined. x_x -- Also need to support UUID.\n\t\taction = args.a;\n\n\t\tif ( LocalCacheData.current_open_view_id === view_id ) {\n\n\t\t\tif ( LocalCacheData.current_open_primary_controller ) {\n\n\t\t\t\tif ( action ) {\n\t\t\t\t\tswitch ( action ) {\n\t\t\t\t\t\tcase 'edit':\n\t\t\t\t\t\t\t//Error: Unable to get property 'id' of undefined or null reference in /interface/html5/IndexController.js?v=8.0.0-20141230-125406 line 87\n\t\t\t\t\t\t\tif ( typeof LocalCacheData.current_open_primary_controller != 'undefined' && ( !LocalCacheData.current_open_primary_controller.edit_view || ( LocalCacheData.current_open_primary_controller.current_edit_record && LocalCacheData.current_open_primary_controller.current_edit_record.id && LocalCacheData.current_open_primary_controller.current_edit_record.id != edit_id ) ) ) {\n\t\t\t\t\t\t\t\t//Makes ure when doing copy_as_new, don't open this\n\t\t\t\t\t\t\t\tif ( LocalCacheData.current_doing_context_action === 'edit' ) {\n\t\t\t\t\t\t\t\t\topenEditView( edit_id );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'new':\n\t\t\t\t\t\t\tif ( !LocalCacheData.current_open_primary_controller.edit_view ) {\n\t\t\t\t\t\t\t\topenEditView();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'view':\n\t\t\t\t\t\t\tswitch ( view_id ) {\n\t\t\t\t\t\t\t\tcase 'MessageControl':\n\t\t\t\t\t\t\t\t\tif ( args.t === 'message' ) {\n\t\t\t\t\t\t\t\t\t\tif ( !LocalCacheData.current_open_primary_controller.edit_view ||\n\t\t\t\t\t\t\t\t\t\t\t( !checkIds() ) ) {\n\t\t\t\t\t\t\t\t\t\t\topenEditView( edit_id, true );\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} else if ( args.t === 'request' ) {\n\t\t\t\t\t\t\t\t\t\tif ( !LocalCacheData.current_open_primary_controller.edit_view ||\n\t\t\t\t\t\t\t\t\t\t\t( LocalCacheData.current_open_primary_controller.current_select_message_control_data.id != edit_id ) ) {\n\t\t\t\t\t\t\t\t\t\t\topenEditView( edit_id, true );\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t// Error: Unable to get property 'id' of undefined or null reference\n\t\t\t\t\t\t\t\t\tif ( typeof LocalCacheData.current_open_primary_controller != 'undefined' && ( !LocalCacheData.current_open_primary_controller.edit_view || ( LocalCacheData.current_open_primary_controller.current_edit_record && LocalCacheData.current_open_primary_controller.current_edit_record.id && LocalCacheData.current_open_primary_controller.current_edit_record.id != edit_id ) ) ) {\n\t\t\t\t\t\t\t\t\t\topenEditView( edit_id, true );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tif ( view_id === 'Login' ) {\n\t\t\t\t\t\t$this.event_bus.emit( 'tt_login', 'step_changed' ); //Notify login view to change step when browser back button is clicked.\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( LocalCacheData.current_open_primary_controller.edit_view &&\n\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.current_edit_record ) {\n\n\t\t\t\t\t\tif ( LocalCacheData.current_open_primary_controller.is_mass_editing ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.buildContextMenu( true );\n\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.removeEditView();\n\t\t\t\t\t\tthis.cleanAnySubViewUI();\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t\treturn;\n\n\t\t} else {\n\t\t\tLocalCacheData.edit_id_for_next_open_view = edit_id;\n\n\t\t\tif ( action ) {\n\t\t\t\tLocalCacheData.current_doing_context_action = action;\n\t\t\t}\n\t\t}\n\n\t\tGlobal.setDeepLink();\n\t\tvar timeout_count;\n\t\tif ( view_id !== 'Login' && !LocalCacheData.getLoginUser() ) {\n\t\t\tGlobal.setURLToBrowser( Global.getBaseURL() + '#!m=Login' );\n\t\t\treturn;\n\t\t} else {\n\t\t\ttimeout_count = 0;\n\t\t\tif ( view_id !== 'Login' && Global.isSet( view_id ) ) {\n\t\t\t\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\t\t\t\tinitRibbonMenuAndCopyRight();\n\t\t\t\t} else {\n\t\t\t\t\tauto_login_timer = setInterval( function() {\n\t\t\t\t\t\tif ( timeout_count == 100 ) {\n\t\t\t\t\t\t\tclearInterval( auto_login_timer );\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttimeout_count = timeout_count + 1;\n\t\t\t\t\t\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\t\t\t\t\t\tinitRibbonMenuAndCopyRight();\n\t\t\t\t\t\t\tclearInterval( auto_login_timer );\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 600 );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tshowRibbonMenuAndLoadView();\n\t\t\t}\n\n\t\t}\n\n\t\tfunction showRibbonMenuAndLoadView() {\n\n\t\t\tif ( view_id && view_id !== 'Login' ) {\n\t\t\t\t$this.event_bus.emit( 'tt_topbar', 'refresh_login_data' ); // Update the topbar company and logged in user.\n\t\t\t\t$this.setContentDivHeight();\n\t\t\t}\n\n\t\t\t if ( view_id && view_id !== 'Login' ) {\n\t\t\t\t$( 'body' ).removeClass( 'login-bg' );\n\t\t\t\t$( 'body' ).addClass( 'application-bg' );\n\t\t\t}\n\n\t\t\tswitch ( view_id ) {\n\t\t\t\tcase 'JobApplication':\n\t\t\t\t\t// require( ['autolinker/Autolinker.min', 'pdfjs-dist/build/pdf', 'pdfjs/compatibility', 'pdfjs/ui_utils', 'pdfjs/text_layer_builder'], function( autolinker ) {\n\t\t\t\t\t// \twindow.Autolinker = autolinker;\n\t\t\t\t\t\tGlobal.loadViewSource( view_id, view_id + 'ViewController.js', function() {\n\t\t\t\t\t\t\tvar permission_id = view_id;\n\t\t\t\t\t\t\tif ( PermissionManager.checkTopLevelPermission( permission_id ) ) {\n\t\t\t\t\t\t\t\tBaseViewController.loadView( view_id );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tTAlertManager.showAlert( 'Permission denied', 'ERROR', function() {\n\t\t\t\t\t\t\t\t\tif ( LocalCacheData.getLoginUserPreference() && LocalCacheData.getLoginUserPreference().default_login_screen ) {\n\t\t\t\t\t\t\t\t\t\tMenuManager.goToView( LocalCacheData.getLoginUserPreference().default_login_screen );\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tMenuManager.goToView( 'Home' );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\tDebug.Text( 'Navigation permission denied. Permission: ' + permission_id, 'IndexController.js', 'IndexController', 'showRibbonMenuAndLoadView', 10 );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t// } );\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tGlobal.loadViewSource( view_id, view_id + 'ViewController.js', function() {\n\t\t\t\t\t\tvar permission_id = view_id;\n\n\t\t\t\t\t\tswitch ( view_id ) {\n\t\t\t\t\t\t\tcase 'ClientGroup':\n\t\t\t\t\t\t\t\tpermission_id = 'Client';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'ProductGroup':\n\t\t\t\t\t\t\t\tpermission_id = 'Product';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'PayStubTransactionSummaryReport':\n\t\t\t\t\t\t\tcase 'PayStubTransaction':\n\t\t\t\t\t\t\t\tpermission_id = 'PayStub';\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( view_id === 'Login' || view_id === 'Home' || PermissionManager.checkTopLevelPermission( permission_id ) ) {\n\t\t\t\t\t\t\tBaseViewController.loadView( view_id );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.viewId && LocalCacheData.current_open_primary_controller.viewId == 'LoginView' ) {\n\t\t\t\t\t\t\t\tif ( LocalCacheData.getLoginUserPreference() && LocalCacheData.getLoginUserPreference().default_login_screen ) {\n\t\t\t\t\t\t\t\t\tMenuManager.goToView( LocalCacheData.getLoginUserPreference().default_login_screen );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tMenuManager.goToView( 'Home' );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tTAlertManager.showAlert( 'Permission denied', 'ERROR', function() {\n\t\t\t\t\t\t\t\t\tif ( LocalCacheData.getLoginUserPreference() && LocalCacheData.getLoginUserPreference().default_login_screen ) {\n\t\t\t\t\t\t\t\t\t\tMenuManager.goToView( LocalCacheData.getLoginUserPreference().default_login_screen );\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tMenuManager.goToView( 'Home' );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tDebug.Text( 'Navigation permission denied. Permission: ' + permission_id, 'IndexController.js', 'IndexController', 'showRibbonMenuAndLoadView', 10 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t}\n\n\t\tfunction initRibbonMenuAndCopyRight() {\n\n\t\t\t// Trigger Vue TopMenu to load, now that all pre-requisitives like login info have been run.\n\t\t\t$this.event_bus.emit( 'tt_top_container', 'ready_to_load_top_bar' );\n\n\t\t\t//Add copy right\n\t\t\tGlobal.bottomContainer().css( 'display', 'block' );\n\n\t\t\t//Start check signal\n\t\t\tGlobal.setSignalStrength();\n\n\t\t\t//Add feedback event\n\t\t\tGlobal.bottomFeedbackLinkContainer().css( 'display', 'block' );\n\t\t\t$( '#feedback-link' ).off( 'click.feedback' ).on( 'click.feedback', function() {\n\t\t\t\t$().TFeedback( {\n\t\t\t\t\tsource: 'ManualTrigger',\n\t\t\t\t\tmanual_trigger: true,\n\t\t\t\t\tprompt_for_feedback: true // regardless of server feedback state input, click should always allow feedback\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\t$( '#copy_right_info_1' ).css( 'display', 'inline' );\n\t\t\t$( '#copy_right_logo_link' ).attr( 'href', 'https://' + LocalCacheData.getLoginData().organization_url );\n\t\t\tif ( !$( '#copy_right_logo' ).attr( 'src' ) ) {\n\t\t\t\t$( '#copy_right_logo' ).attr( 'src', ServiceCaller.getURLByObjectType( 'copyright' ) ); // Use the same logo as the one on the login screen. (Changed from smcopyright)\n\t\t\t}\n\t\t\tshowRibbonMenuAndLoadView();\n\t\t}\n\n\t\tfunction checkIds() {\n\n\t\t\tif ( Global.isArray( LocalCacheData.current_open_primary_controller.current_edit_record ) ) {\n\t\t\t\tfor ( var i = 0; i < LocalCacheData.current_open_primary_controller.current_edit_record.length; i++ ) {\n\t\t\t\t\tvar item = LocalCacheData.current_open_primary_controller.current_edit_record[i];\n\n\t\t\t\t\tif ( item.id && item.id === edit_id ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\titem = LocalCacheData.current_open_primary_controller.current_edit_record;\n\t\t\t\tif ( item.id && item.id === edit_id ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tfunction openEditView( edit_id, view_mode ) {\n\t\t\tvar type;\n\t\t\tswitch ( view_id ) {\n\t\t\t\tcase 'MessageControl':\n\t\t\t\t\ttype = args.t;\n\t\t\t\t\tvar item = {};\n\t\t\t\t\tif ( type === 'message' ) {\n\t\t\t\t\t\titem.id = edit_id;\n\t\t\t\t\t} else {\n\t\t\t\t\t\titem.object_id = edit_id;\n\t\t\t\t\t\titem.object_type_id = 50;\n\t\t\t\t\t}\n\t\t\t\t\tLocalCacheData.current_open_primary_controller.onViewClick( item );\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'TimeSheet':\n\t\t\t\t\ttype = args.t;\n\n\t\t\t\t\tif ( !view_mode ) {\n\t\t\t\t\t\tif ( edit_id ) {\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.onEditClick( edit_id, type );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.onAddClick();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( edit_id ) {\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.onViewClick( edit_id, type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\n\t\t\t\t\tif ( !view_mode ) {\n\t\t\t\t\t\tif ( edit_id ) {\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.onEditClick( edit_id );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.onAddClick();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( edit_id ) {\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.onViewClick( edit_id );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/* jshint ignore:end */\n\n\tcleanAnySubViewUI() {\n\t\tvar children = Global.contentContainer().children();\n\n\t\tif ( children.length > 1 ) {\n\t\t\tfor ( var i = 1; i < children.length; i++ ) {\n\t\t\t\t// Object doesn't support property or method 'remove', Not sure why, add try catch to ingore this error since this should no harm\n\t\t\t\ttry {\n\n\t\t\t\t\tif ( $( children[i] ).attr( 'id' ) === LocalCacheData.current_open_primary_controller.ui_id ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchildren[i].remove();\n\t\t\t\t\t}\n\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\t//Do nothing\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n\n\tsetContentDivHeight() {\n\t\t// Now done by CSS calculation\n\t\t// Global.contentContainer().css( 'height', ( Global.bodyHeight() - Global.topContainer().height() - $('.topbar').height() ) ); // TODO: do away with these hardcoded calculated heights in future refactor.\n\t\t// $( window ).resize( function() {\n\t\t// \tGlobal.contentContainer().css( 'height', ( Global.bodyHeight() - Global.topContainer().height() - $('.topbar').height()) ); // TODO: do away with these hardcoded calculated heights in future refactor.\n\t\t// } );\n\n\t\tGlobal.contentContainer().removeClass( 'content-container' );\n\t\tGlobal.contentContainer().addClass( 'content-container-after-login' );\n\t}\n\n\tremoveCurrentView( callBack ) {\n\n\t\tif ( LocalCacheData.current_open_edit_only_controller ) {\n\t\t\tclean( LocalCacheData.current_open_edit_only_controller );\n\t\t\tLocalCacheData.current_open_edit_only_controller = null;\n\t\t}\n\n\t\tif ( LocalCacheData.current_open_primary_controller ) {\n\t\t\tif ( LocalCacheData.current_open_primary_controller.edit_view ) {\n\t\t\t\tclean( LocalCacheData.current_open_primary_controller );\n\t\t\t}\n\t\t\tLocalCacheData.current_open_primary_controller.unmountContextMenu();\n\t\t\tGlobal.contentContainer().children().detach().remove(); // This is about 3x faster than Global.contentContainer().empty()\n\t\t\tLocalCacheData.current_open_primary_controller.cleanWhenUnloadView( callBack );\n\t\t} else {\n\n\t\t\tif ( Global.isSet( callBack ) ) {\n\t\t\t\tcallBack();\n\t\t\t}\n\t\t}\n\n\t\tfunction clean( viewController ) {\n\t\t\tviewController.clearErrorTips();\n\t\t\t// Cannot read property 'remove' of null in interface/html5/IndexController.js?v=9.0.0-20151016-153057 line 439\n\t\t\tif ( viewController.edit_view ) {\n\t\t\t\t// #question: Not sure when this would be trigged, but this should surely run through viewController.removeEditView()?\n\t\t\t\tviewController.unmountContextMenu(); // Not sure when this clean would be trigged, but lets have this here just in case.\n\t\t\t\tviewController.edit_view.remove();\n\t\t\t}\n\t\t\tviewController.sub_log_view_controller = null;\n\t\t\tviewController.edit_view_ui_dic = {};\n\t\t\tviewController.edit_view_ui_validation_field_dic = {};\n\t\t\tviewController.edit_view_form_item_dic = {};\n\t\t\tviewController.edit_view_error_ui_dic = {};\n\t\t\tLocalCacheData.current_doing_context_action = '';\n\t\t}\n\t}\n\n}\n\nclass IndexViewController extends _views_TTBackboneView__WEBPACK_IMPORTED_MODULE_0__.TTBackboneView {\n\n\tconstructor( options = {} ) {\n\t\t_.defaults( options, {\n\t\t\tel: 'body', //So we can add event listener for all elements\n\t\t\trouter: null,\n\t\t} );\n\n\t\tsuper( options );\n\t}\n\n\tinitialize( options ) {\n\n\t\tsuper.initialize( options );\n\t\tthis.router = new ApplicationRouter();\n\n\t\t//Set title in index.php instead.\n\t\t//$( 'title' ).html( '' );\n\n\t\tthis.router.controller = this;\n\t\t//Error: Backbone.history has already been started in interface/html5/framework/backbone/backbone-min.js?v=9.0.1-20151022-162110 line 28\n\t\tif ( !Backbone.History.started ) {\n\t\t\tBackbone.history.start();\n\t\t}\n\n\t\tIndexViewController.instance = this;\n\n\t}\n\n\tstatic goToView( view_name, filter ) {\n\t\tGlobal.closeEditViews( function() {\n\t\t\tLocalCacheData.default_filter_for_next_open_view = filter;\n\t\t\tMenuManager.goToView( view_name, true );\n\t\t} );\n\n\t}\n\n\tstatic goToViewByViewLabel( view_label ) {\n\t\tvar view_name;\n\t\tswitch ( view_label ) {\n\t\t\tcase 'Exceptions':\n\t\t\t\tview_name = 'Exception';\n\t\t\t\tbreak;\n\t\t\tcase 'Messages':\n\t\t\t\tview_name = 'MessageControl';\n\t\t\t\tbreak;\n\t\t\tcase 'Requests':\n\t\t\t\tview_name = 'Request';\n\t\t\t\tbreak;\n\t\t\tcase 'Contact Information':\n\t\t\t\tIndexViewController.openEditView( LocalCacheData.current_open_primary_controller, 'LoginUserContact' );\n\t\t\t\treturn;\n\t\t\tcase 'InOut':\n\t\t\t\tIndexViewController.openEditView( LocalCacheData.current_open_primary_controller, 'InOut' );\n\t\t\t\treturn;\n\t\t\tdefault:\n\t\t\t\tvar reg = /\\s/g;\n\t\t\t\tview_name = view_label.replace( reg, '' );\n\t\t\t\tbreak;\n\t\t}\n\n\t\tMenuManager.goToView( view_name, true );\n\n\t}\n\n\t//DEPRECATED: all new wizards should go through openWizardController()\n\tstatic openWizard( wizardName, defaultData, callBack ) {\n\t\tGlobal.setUINotready();\n\n\t\tBaseWizardController.default_data = defaultData;\n\t\tBaseWizardController.call_back = callBack;\n\n\t\tswitch ( wizardName ) {\n\t\t\tdefault:\n\t\t\t\t// track edit view only view\n\t\t\t\tGlobal.trackView( wizardName );\n\t\t\t\tGlobal.loadViewSource( wizardName, wizardName + 'Controller.js', function() {\n\t\t\t\t\tBaseWizardController.openWizard( wizardName, wizardName + '.html' );\n\t\t\t\t} );\n\t\t\t\tbreak;\n\t\t}\n\n\t}\n\n\t//ATTN: New wizards should go through this\n\tstatic openWizardController( wizard_id, filter_data, source_view ) {\n\t\tGlobal.setUINotready();\n\t\t// BaseWizardController.default_data = defaultData;\n\t\t// BaseWizardController.call_back = callBack;\n\t\tswitch ( wizard_id ) {\n\t\t\tdefault:\n\t\t\t\t// track edit view only view\n\t\t\t\tGlobal.trackView( wizard_id );\n\t\t\t\tGlobal.loadViewSource( wizard_id, wizard_id + '.js', function() {\n\n\t\t\t\t\tif ( LocalCacheData.current_open_wizard_controllers.some( wizard => wizard.wizard_id === wizard_id ) ) {\n\t\t\t\t\t\tswitch ( wizard_id ) {\n\t\t\t\t\t\t\tcase 'ReportViewWizard':\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'PayrollRemittanceAgencyEventWizardController':\n\t\t\t\t\t\t\t\t//if the current wizard is a PayrollRemittanceAgencyEventWizard, we need to remember the cards that were clicked because it's just minimized.\n\t\t\t\t\t\t\t\tvar wizard = LocalCacheData.current_open_wizard_controllers.find( wizard => wizard.wizard_id === wizard_id );\n\t\t\t\t\t\t\t\twizard.remove(); // #2768 Removes the existing wizard DOM element if it exists, to avoid duplicate wizards. Causes issue when user double clicks on Wizard icon (without overlay) or Tax Wizard opened when already open. TODO: Add overlay to prevent background clicks.\n\t\t\t\t\t\t\t\twizard.getStepObject().initialize( wizard );\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tvar wizard = LocalCacheData.current_open_wizard_controllers.find( wizard => wizard.wizard_id === wizard_id );\n\t\t\t\t\t\t\t\twizard.onCloseClick();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tGlobal.loadViewSource( wizard_id, wizard_id + '.html', function( result ) {\n\t\t\t\t\t\tvar args = {};\n\t\t\t\t\t\tvar template = _.template( result );\n\t\t\t\t\t\t$( 'body' ).append( template( args ) );\n\n\t\t\t\t\t\t//#2422 - pass the data on to the process transactions wizard\n\t\t\t\t\t\t// This must be here because we don't instantiate the WizardController ( the host view ) in the html file like we do with other views so that we can pass it constructor arguments\n\t\t\t\t\t\tswitch ( wizard_id ) {\n\t\t\t\t\t\t\tcase 'ProcessTransactionsWizardController':\n\t\t\t\t\t\t\t\tnew ProcessTransactionsWizardController( filter_data );\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tGlobal.setUIInitComplete();\n\t\t\t\t\t} );\n\t\t\t\t} );\n\t\t\t\tbreak;\n\t\t}\n\n\t}\n\n\tstatic openReport( parent_view_controller, view_name, id, tab_name ) {\n\t\t// Note: This behaviour/router call is also in BaseViewController.loadView()\n\t\t// VueRouter.push({\n\t\t// \tname: 'report',\n\t\t// \tparams: {\n\t\t// \t\tviewId: view_name\n\t\t// \t}\n\t\t// }).then(function() {\n\t\t// \tdoNextAfterReportRouteChange();\n\t\t// });\n\t\tdoNextAfterReportRouteChange(); // Now using one global context menu, so no need for router calls. Just using the one single LegacyView for now.\n\n\t\tfunction doNextAfterReportRouteChange() {\n\t\t\tGlobal.closeEditViews( function() {\n\t\t\t\tif ( LocalCacheData.current_open_report_controller ) {\n\t\t\t\t\tLocalCacheData.current_open_report_controller.removeEditView();\n\t\t\t\t}\n\n\t\t\t\tProgressBar.showOverlay();\n\n\t\t\t\tswitch ( view_name ) {\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tvar path = Global.getViewPathByViewId( view_name );\n\t\t\t\t\t\tif ( path ) {\n\t\t\t\t\t\t\tGlobal.loadScript( path + view_name + 'ViewController', function() {\n\t\t\t\t\t\t\t\tDebug.Text( 'R-LOADING: ' + view_name, 'IndexViewController.js', 'IndexViewController', 'openReport', 10 );\n\t\t\t\t\t\t\t\t/* jshint ignore:start */\n\t\t\t\t\t\t\t\tTTPromise.add( 'Reports', 'openReport' );\n\t\t\t\t\t\t\t\tvar $view_controller = eval( 'new ' + view_name + 'ViewController( {edit_only_mode: true} ); ' );\n\t\t\t\t\t\t\t\t/* jshint ignore:end */\n\n\t\t\t\t\t\t\t\tTTPromise.wait( 'Reports', 'openReport', function() {\n\t\t\t\t\t\t\t\t\tdoNext( view_name, tab_name );\n\t\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t\tfunction doNext( view_name, tab_name ) {\n\t\t\t\t\t\t\t\t\t$view_controller.parent_view_controller = parent_view_controller;\n\t\t\t\t\t\t\t\t\t$view_controller.openEditView();\n\n\t\t\t\t\t\t\t\t\tvar current_url = window.location.href;\n\t\t\t\t\t\t\t\t\tif ( current_url.indexOf( '&sm' ) > 0 ) {\n\t\t\t\t\t\t\t\t\t\tcurrent_url = current_url.substring( 0, current_url.indexOf( '&sm' ) );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcurrent_url = current_url + '&sm=' + view_name;\n\n\t\t\t\t\t\t\t\t\tif ( LocalCacheData.default_edit_id_for_next_open_edit_view ) {\n\t\t\t\t\t\t\t\t\t\tcurrent_url = current_url + '&sid=' + LocalCacheData.default_edit_id_for_next_open_edit_view;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( typeof tab_name != 'undefined' ) {\n\t\t\t\t\t\t\t\t\t\tLocalCacheData.current_open_report_controller.selected_tab = tab_name;\n\t\t\t\t\t\t\t\t\t\tcurrent_url += '&tab=' + tab_name;\n\t\t\t\t\t\t\t\t\t} else if ( window.location.href.indexOf( '&tab=' ) > -1 ) {\n\t\t\t\t\t\t\t\t\t\tvar tab_name = window.location.href;\n\t\t\t\t\t\t\t\t\t\ttab_name = tab_name.substr( ( window.location.href.indexOf( '&tab=' ) + 5 ) ); //get the selected tab name\n\t\t\t\t\t\t\t\t\t\ttab_name = tab_name.substr( 0, window.location.href.indexOf( '&' ) ); // incase there are subsequent arguments after the tab argument\n\t\t\t\t\t\t\t\t\t\tcurrent_url += '&tab=' + tab_name;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tGlobal.setURLToBrowser( current_url );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.debug( 'Report View does not exist! View Name: ' + view_name );\n\t\t\t\t\t\t\tif ( ServiceCaller.root_url && APIGlobal.pre_login_data.base_url ) {\n\t\t\t\t\t\t\t\tGlobal.setURLToBrowser( ServiceCaller.root_url + APIGlobal.pre_login_data.base_url );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\t//Open edit view\n\tstatic openEditView( parent_view_controller, view_name, id, action_function ) {\n\t\tif ( LocalCacheData.current_open_report_controller ) { //don't allow editviews over report views.\n\t\t\tLocalCacheData.current_open_report_controller.onCancelClick( null, null, function() {\n\t\t\t\tGlobal.closeEditViews( function() {\n\t\t\t\t\tIndexViewController.openEditView( parent_view_controller, view_name, id, action_function );\n\t\t\t\t} );\n\t\t\t} );\n\t\t\treturn;\n\t\t} else if ( LocalCacheData.current_open_edit_only_controller && LocalCacheData.current_open_edit_only_controller.viewId && LocalCacheData.current_open_edit_only_controller.viewId == view_name ) { //Stop edit only views from overlaying themselves with the same view and disconnecting others from the menu\n\t\t\tLocalCacheData.current_open_edit_only_controller.setEditMenu(); //display the right edit menu\n\t\t\t$( '#ribbon_view_container .context-menu:visible a' ).click();\n\t\t} else {\n\t\t\tdoNext();\n\t\t}\n\n\t\tfunction doNext() {\n\t\t\tvar view_controller = null;\n\n\t\t\tif ( !PermissionManager.checkTopLevelPermission( view_name ) && view_name !== 'Map' ) {\n\t\t\t\tif ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.viewId && LocalCacheData.current_open_primary_controller.viewId == 'LoginView' ) {\n\t\t\t\t\tif ( LocalCacheData.getLoginUserPreference() && LocalCacheData.getLoginUserPreference().default_login_screen ) {\n\t\t\t\t\t\tMenuManager.goToView( LocalCacheData.getLoginUserPreference().default_login_screen );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMenuManager.goToView( 'Home' );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tTAlertManager.showAlert( 'Permission denied', 'ERROR', function() {\n\t\t\t\t\t\tif ( LocalCacheData.getLoginUserPreference() && LocalCacheData.getLoginUserPreference().default_login_screen ) {\n\t\t\t\t\t\t\tMenuManager.goToView( LocalCacheData.getLoginUserPreference().default_login_screen );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tMenuManager.goToView( 'Home' );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\tDebug.Text( 'Navigation permission denied. View: ' + view_name, 'IndexController.js', 'IndexController', 'openEditView', 10 );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( view_name == 'Request' ) {\n\t\t\t\taction_function = 'openAddView';\n\t\t\t}\n\n\t\t\tif ( !action_function ) {\n\t\t\t\taction_function = 'openEditView';\n\t\t\t}\n\n\t\t\t// Added originally in 83a1df72 for issue #1805 but caused a bug mentioned in issue #2091 the steps to reproduce the bug are as follows:\n\t\t\t// 1. Go to invoice > client contacts and highlite a Client Contact 2. Click the \"Edit Client\" button on the ribbon menu\n\t\t\t// 3. Click the Invoices tab 4. Edit an invoice 5. Click Payment on the ribbon menu 6. Click Cancel to bring you back to the invoice edit scren, then Cancel again to go back to the Invoices tab on the client screen.\n\t\t\t// 7. You won't be back there. The Client screen will be missing.\n\t\t\t//if ( LocalCacheData.current_open_edit_only_controller ) {\n\t\t\t//LocalCacheData.current_open_edit_only_controller.onCancelClick();\n\t\t\t//}\n\n\t\t\t// track edit view only view\n\t\t\tGlobal.trackView( view_name );\n\n\t\t\tGlobal.loadViewSource( view_name, view_name + 'ViewController.js', function() {\n\t\t\t\t/* jshint ignore:start */\n\t\t\t\tview_controller = eval( 'new ' + view_name + 'ViewController( {edit_only_mode: true} ); ' );\n\t\t\t\t/* jshint ignore:end */\n\n\t\t\t\tTTPromise.wait( 'BaseViewController', 'initialize', function() {\n\t\t\t\t\tview_controller.parent_view_controller = parent_view_controller;\n\n\t\t\t\t\tview_controller[action_function]( id );\n\t\t\t\t\tif ( TTUUID.isUUID( id ) ) {\n\t\t\t\t\t\tvar current_url = window.location.href;\n\t\t\t\t\t\tif ( current_url.indexOf( '&sm' ) > 0 ) {\n\t\t\t\t\t\t\tcurrent_url = current_url.substring( 0, current_url.indexOf( '&sm' ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( id && _.isString( id ) ) {\n\t\t\t\t\t\t\tcurrent_url = current_url + '&sm=' + view_name + '&sid=' + id;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcurrent_url = current_url + '&sm=' + view_name;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tGlobal.setURLToBrowser( current_url );\n\t\t\t\t\t}\n\n\t\t\t\t\tLocalCacheData.current_open_edit_only_controller = view_controller;\n\t\t\t\t} );\n\t\t\t} );\n\t\t}\n\t}\n\n\tstatic initializeNotifications( target ) {\n\t\tNotificationConsumer.setupUser( true, false );\n\t\tNotificationConsumer.getSystemNotifications( target );\n\t}\n\n\tstatic testInternetConnection() {\n\t\tif ( !navigator.onLine ) {\n\t\t\twindow.internet_connection_available = false;\n\t\t\twindow.is_testing_internet_connection = false;\n\t\t}\n\n\t\tvar img = new Image();\n\t\twindow.is_testing_internet_connection = true;\n\t\timg.onload = function() {\n\t\t\twindow.internet_connection_available = true;\n\t\t\twindow.is_testing_internet_connection = false;\n\t\t};\n\t\timg.onerror = function( e ) {\n\t\t\twindow.internet_connection_available = false;\n\t\t\twindow.is_testing_internet_connection = false;\n\t\t};\n\t\timg.src = 'https://www.timetrex.com/images/ping.gif';\n\t}\n}\nIndexViewController.instance = null;\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODY3OC5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQXdEO0FBQ1Q7O0FBRS9DO0FBQ0EsMkJBQTJCO0FBQzNCLEVBQUUsQ0FBQztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0EsdUJBQXVCLHFFQUFVLEdBQUcsNkJBQTZCO0FBQ2pFOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZ0RBQWdEO0FBQ2hEO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDLENBQUM7QUFDbkMsa0NBQWtDLENBQUM7QUFDbkMsNkJBQTZCLENBQUM7QUFDOUI7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEscUJBQXFCO0FBQ3JCOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsMERBQTBEO0FBQzFEOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQSwrREFBK0Q7QUFDL0Q7QUFDQTs7QUFFQTtBQUNBLElBQUksQ0FBQztBQUNMLElBQUksQ0FBQztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFFBQVE7QUFDUixVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRyxDQUFDO0FBQ0osSUFBSSxDQUFDO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOLEtBQUs7O0FBRUwsR0FBRyxDQUFDO0FBQ0osR0FBRyxDQUFDO0FBQ0osU0FBUyxDQUFDO0FBQ1YsSUFBSSxDQUFDLHVGQUF1RjtBQUM1RjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxxQkFBcUIsK0VBQStFO0FBQ3BHOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0Esb0JBQW9CLHFCQUFxQjtBQUN6QztBQUNBOztBQUVBLFVBQVUsQ0FBQztBQUNYO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUEsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrSUFBa0k7QUFDbEk7QUFDQSxrSUFBa0k7QUFDbEksT0FBTzs7QUFFUDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFTyxrQ0FBa0MsaUVBQWM7O0FBRXZELDJCQUEyQjtBQUMzQixFQUFFLENBQUM7QUFDSDtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFCQUFxQixDQUFDO0FBQ3RCLE1BQU0sQ0FBQzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE9BQU87QUFDUCxNQUFNO0FBQ047QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTixrQ0FBa0M7O0FBRWxDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRFQUE0RSxzQkFBc0IsR0FBRztBQUNyRzs7QUFFQTtBQUNBO0FBQ0EsVUFBVTs7QUFFVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0EseUZBQXlGO0FBQ3pGLGdGQUFnRjtBQUNoRjtBQUNBOztBQUVBOztBQUVBOztBQUVBLFNBQVM7QUFDVDtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTixLQUFLO0FBQ0w7QUFDQSxJQUFJLGtNQUFrTTtBQUN0TSxtRUFBbUU7QUFDbkUsR0FBRyxDQUFDO0FBQ0osSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUVBQW1FLHNCQUFzQixHQUFHO0FBQzVGOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLENBQUM7QUFDbEI7QUFDQSxRQUFRO0FBQ1I7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsTUFBTTtBQUNOLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9JbmRleENvbnRyb2xsZXIuanM/MWJjNSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUVEJhY2tib25lVmlldyB9IGZyb20gJ0Avdmlld3MvVFRCYWNrYm9uZVZpZXcnO1xuaW1wb3J0IFRURXZlbnRCdXMgZnJvbSAnQC9zZXJ2aWNlcy9UVEV2ZW50QnVzJztcblxuY2xhc3MgQXBwbGljYXRpb25Sb3V0ZXIgZXh0ZW5kcyBCYWNrYm9uZS5Sb3V0ZXIge1xuXHRjb25zdHJ1Y3Rvciggb3B0aW9ucyA9IHt9ICkge1xuXHRcdF8uZGVmYXVsdHMoIG9wdGlvbnMsIHtcblx0XHRcdGNvbnRyb2xsZXI6IG51bGwsXG5cblx0XHRcdHJvdXRlczoge1xuXHRcdFx0XHQnJzogJ29uVmlld0NoYW5nZScsXG5cdFx0XHRcdCchOnZpZXdOYW1lJzogJ29uVmlld0NoYW5nZScsXG5cdFx0XHRcdCcqbm90Rm91bmQnOiAnbm90Rm91bmQnXG5cdFx0XHR9XG5cdFx0fSApO1xuXG5cdFx0c3VwZXIoIG9wdGlvbnMgKTtcblx0XHR0aGlzLmV2ZW50X2J1cyA9IG5ldyBUVEV2ZW50QnVzKHsgdmlld19pZDogJ2luZGV4X2NvbnRyb2xsZXInIH0pO1xuXHR9XG5cblx0cmVsb2FkVmlldyggdmlld19pZCApIHtcblx0XHQvL2Vycm9yOiBVbmNhdWdodCBSZWZlcmVuY2VFcnJvcjogWFhYWFZpZXdDb250cm9sbGVyIGlzIG5vdCBkZWZpbmVkIGluaW50ZXJmYWNlL2h0bWw1LyMhbT1UaW1lU2hlZXQgbGluZSAzXG5cdFx0Ly8gSGFwcGVucyB3aGVuIHF1aWNrbHkgY2xpY2sgb24gY29udGV4dCBtZW51IGFuZCBuZXR3b3JrIGlzIHNsb3cuXG5cdFx0aWYgKCBldmFsKCAndHlwZW9mICcrIHZpZXdfaWQgKyAnVmlld0NvbnRyb2xsZXInICkgPT09ICdmdW5jdGlvbicgJiYgLy9XYXMgRVM1OiB3aW5kb3dbdmlld19pZCArICdWaWV3Q29udHJvbGxlciddICYmXG5cdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICYmXG5cdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnZpZXdJZCA9PT0gdmlld19pZCApIHtcblx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuc2V0U2VsZWN0TGF5b3V0KCk7XG5cdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnNlYXJjaCgpO1xuXHRcdH1cblx0fVxuXG5cdG5vdEZvdW5kKCB1cmwgKSB7XG5cblx0XHR2YXIgbmV3X3VybCA9IEdsb2JhbC5nZXRCYXNlVVJMKCk7XG5cblx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCBuZXdfdXJsICsgJyMhbT1Mb2dpbicgKTtcblx0fVxuXG5cdC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cblx0b25WaWV3Q2hhbmdlKCB2aWV3TmFtZSApIHtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXHRcdHZhciBhcmdzID0ge307XG5cdFx0dmFyIHZpZXdfaWQ7XG5cdFx0dmFyIGVkaXRfaWQ7XG5cdFx0dmFyIGFjdGlvbjtcblx0XHR2YXIgYXV0b19sb2dpbl90aW1lcjtcblxuXHRcdGlmICggR2xvYmFsLm5lZWRSZWxvYWRCcm93c2VyICkge1xuXHRcdFx0R2xvYmFsLm5lZWRSZWxvYWRCcm93c2VyID0gZmFsc2U7XG5cdFx0XHR3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCB2aWV3TmFtZSApIHtcblx0XHRcdGFyZ3MgPSBHbG9iYWwuYnVpbGRBcmdEaWMoIHZpZXdOYW1lLnNwbGl0KCAnJicgKSApO1xuXHRcdH1cblx0XHRpZiAoIHZpZXdOYW1lICYmIHZpZXdOYW1lLmluZGV4T2YoICdtPScgKSA+PSAwICkge1xuXHRcdFx0dmlld19pZCA9IEdsb2JhbC5zYW5pdGl6ZVZpZXdJZCggYXJncy5tICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHZpZXdfaWQgPSAnTG9naW4nO1xuXHRcdH1cblxuXHRcdC8vICNWdWVDb250ZXh0TWVudSMgVHJpZ2dlciBWdWUgUm91dGVyIGNoYW5nZXNcblx0XHQvLyBBZGQgaW50ZXJmYWNlIGZ1bmN0aW9ucyBmb3IgdGhpcyBvbmNlIFBPQyB3b3Jrcy5cblx0XHQvLyBjb25zb2xlLmxvZygnYWFhYSBvblZpZXdDaGFuZ2UnLCB2aWV3X2lkKTsgLy8gY29tcGFyaW5nIHRyaWdnZXJzIGFnYWluc3QgQmFzZVZDLlxuXHRcdC8vIFZ1ZVJvdXRlci5wdXNoKCcvdmlldy8nK3ZpZXdfaWQpO1xuXHRcdC8vIEVuZCBWdWUgcm91dGVyXG5cblx0XHRMb2NhbENhY2hlRGF0YS5mdWxsVXJsUGFyYW1ldGVyU3RyID0gdmlld05hbWU7XG5cdFx0TG9jYWxDYWNoZURhdGEuc2V0QWxsVVJMQXJncyggYXJncyApO1xuXG5cdFx0aWYgKCB2aWV3X2lkID09ICdJbnN0YWxsJyApIHtcblx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEubG9hZFZpZXdSZXF1aXJlZEpTUmVhZHkgKSB7XG5cdFx0XHRcdEluZGV4Vmlld0NvbnRyb2xsZXIub3BlbldpemFyZCggJ0luc3RhbGxXaXphcmQnLCBudWxsLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHQvLyBuZWVkIHRvIGxpbmsgdG8gdGhlIGxvZ2luIGludGVyZmFjZS5cblx0XHRcdFx0fSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0YXV0b19sb2dpbl90aW1lciA9IHNldEludGVydmFsKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRpZiAoIHRpbWVvdXRfY291bnQgPT0gMTAwICkge1xuXHRcdFx0XHRcdFx0Y2xlYXJJbnRlcnZhbCggYXV0b19sb2dpbl90aW1lciApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aW1lb3V0X2NvdW50ID0gdGltZW91dF9jb3VudCArIDE7XG5cdFx0XHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5sb2FkVmlld1JlcXVpcmVkSlNSZWFkeSApIHtcblx0XHRcdFx0XHRcdEluZGV4Vmlld0NvbnRyb2xsZXIub3BlbldpemFyZCggJ0luc3RhbGxXaXphcmQnLCBudWxsLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0Ly8gbmVlZCB0byBsaW5rIHRvIHRoZSBsb2dpbiBpbnRlcmZhY2UuXG5cdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHRjbGVhckludGVydmFsKCBhdXRvX2xvZ2luX3RpbWVyICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LCA2MDAgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmdldEFsbFVSTEFyZ3MoKS5zbSA9PT0gJ1Jlc2V0UGFzc3dvcmQnICYmIExvY2FsQ2FjaGVEYXRhLmdldEFsbFVSTEFyZ3MoKS5rZXkgKSB7XG5cdFx0XHRJbmRleFZpZXdDb250cm9sbGVyLm9wZW5XaXphcmQoICdSZXNldEZvcmdvdFBhc3N3b3JkV2l6YXJkJywgbnVsbCwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdExvY2FsQ2FjaGVEYXRhLnNldEFsbFVSTEFyZ3MoIF8ub21pdCggTG9jYWxDYWNoZURhdGEuZ2V0QWxsVVJMQXJncygpLCAnc20nICkgKTtcblx0XHRcdFx0TG9jYWxDYWNoZURhdGEuc2V0QWxsVVJMQXJncyggXy5vbWl0KCBMb2NhbENhY2hlRGF0YS5nZXRBbGxVUkxBcmdzKCksICdrZXknICkgKTtcblx0XHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93QWxlcnQoICQuaTE4bi5fKCAnUGFzc3dvcmQgaGFzIGJlZW4gY2hhbmdlZCBzdWNjZXNzZnVsbHksIHlvdSBtYXkgbm93IGxvZ2luLicgKSApO1xuXHRcdFx0XHR2YXIgbmV3X3VybCA9IEdsb2JhbC5nZXRCYXNlVVJMKCk7XG5cdFx0XHRcdEdsb2JhbC5zZXRVUkxUb0Jyb3dzZXIoIG5ld191cmwgKyAnIyFtPUxvZ2luJyApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9ICk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0ZWRpdF9pZCA9IGFyZ3MuaWQ7IC8vQWNjcnVhbCBpZCBpcyBjb21iaW5lZC4geF94IC0tIEFsc28gbmVlZCB0byBzdXBwb3J0IFVVSUQuXG5cdFx0YWN0aW9uID0gYXJncy5hO1xuXG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fdmlld19pZCA9PT0gdmlld19pZCApIHtcblxuXHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICkge1xuXG5cdFx0XHRcdGlmICggYWN0aW9uICkge1xuXHRcdFx0XHRcdHN3aXRjaCAoIGFjdGlvbiApIHtcblx0XHRcdFx0XHRcdGNhc2UgJ2VkaXQnOlxuXHRcdFx0XHRcdFx0XHQvL0Vycm9yOiBVbmFibGUgdG8gZ2V0IHByb3BlcnR5ICdpZCcgb2YgdW5kZWZpbmVkIG9yIG51bGwgcmVmZXJlbmNlIGluIC9pbnRlcmZhY2UvaHRtbDUvSW5kZXhDb250cm9sbGVyLmpzP3Y9OC4wLjAtMjAxNDEyMzAtMTI1NDA2IGxpbmUgODdcblx0XHRcdFx0XHRcdFx0aWYgKCB0eXBlb2YgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlciAhPSAndW5kZWZpbmVkJyAmJiAoICFMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmVkaXRfdmlldyB8fCAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuY3VycmVudF9lZGl0X3JlY29yZCAmJiBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmN1cnJlbnRfZWRpdF9yZWNvcmQuaWQgJiYgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5jdXJyZW50X2VkaXRfcmVjb3JkLmlkICE9IGVkaXRfaWQgKSApICkge1xuXHRcdFx0XHRcdFx0XHRcdC8vTWFrZXMgdXJlIHdoZW4gZG9pbmcgY29weV9hc19uZXcsIGRvbid0IG9wZW4gdGhpc1xuXHRcdFx0XHRcdFx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9kb2luZ19jb250ZXh0X2FjdGlvbiA9PT0gJ2VkaXQnICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0b3BlbkVkaXRWaWV3KCBlZGl0X2lkICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlICduZXcnOlxuXHRcdFx0XHRcdFx0XHRpZiAoICFMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmVkaXRfdmlldyApIHtcblx0XHRcdFx0XHRcdFx0XHRvcGVuRWRpdFZpZXcoKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSAndmlldyc6XG5cdFx0XHRcdFx0XHRcdHN3aXRjaCAoIHZpZXdfaWQgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y2FzZSAnTWVzc2FnZUNvbnRyb2wnOlxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBhcmdzLnQgPT09ICdtZXNzYWdlJyApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCAhTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5lZGl0X3ZpZXcgfHxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQoICFjaGVja0lkcygpICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b3BlbkVkaXRWaWV3KCBlZGl0X2lkLCB0cnVlICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGFyZ3MudCA9PT0gJ3JlcXVlc3QnICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoICFMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmVkaXRfdmlldyB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5jdXJyZW50X3NlbGVjdF9tZXNzYWdlX2NvbnRyb2xfZGF0YS5pZCAhPSBlZGl0X2lkICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0b3BlbkVkaXRWaWV3KCBlZGl0X2lkLCB0cnVlICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBFcnJvcjogVW5hYmxlIHRvIGdldCBwcm9wZXJ0eSAnaWQnIG9mIHVuZGVmaW5lZCBvciBudWxsIHJlZmVyZW5jZVxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCB0eXBlb2YgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlciAhPSAndW5kZWZpbmVkJyAmJiAoICFMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmVkaXRfdmlldyB8fCAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuY3VycmVudF9lZGl0X3JlY29yZCAmJiBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmN1cnJlbnRfZWRpdF9yZWNvcmQuaWQgJiYgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5jdXJyZW50X2VkaXRfcmVjb3JkLmlkICE9IGVkaXRfaWQgKSApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRvcGVuRWRpdFZpZXcoIGVkaXRfaWQsIHRydWUgKTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aWYgKCB2aWV3X2lkID09PSAnTG9naW4nICkge1xuXHRcdFx0XHRcdFx0JHRoaXMuZXZlbnRfYnVzLmVtaXQoICd0dF9sb2dpbicsICdzdGVwX2NoYW5nZWQnICk7IC8vTm90aWZ5IGxvZ2luIHZpZXcgdG8gY2hhbmdlIHN0ZXAgd2hlbiBicm93c2VyIGJhY2sgYnV0dG9uIGlzIGNsaWNrZWQuXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmVkaXRfdmlldyAmJlxuXHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5jdXJyZW50X2VkaXRfcmVjb3JkICkge1xuXG5cdFx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuaXNfbWFzc19lZGl0aW5nICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuYnVpbGRDb250ZXh0TWVudSggdHJ1ZSApO1xuXHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5yZW1vdmVFZGl0VmlldygpO1xuXHRcdFx0XHRcdFx0dGhpcy5jbGVhbkFueVN1YlZpZXdVSSgpO1xuXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdH1cblx0XHRcdHJldHVybjtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRMb2NhbENhY2hlRGF0YS5lZGl0X2lkX2Zvcl9uZXh0X29wZW5fdmlldyA9IGVkaXRfaWQ7XG5cblx0XHRcdGlmICggYWN0aW9uICkge1xuXHRcdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X2RvaW5nX2NvbnRleHRfYWN0aW9uID0gYWN0aW9uO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdEdsb2JhbC5zZXREZWVwTGluaygpO1xuXHRcdHZhciB0aW1lb3V0X2NvdW50O1xuXHRcdGlmICggdmlld19pZCAhPT0gJ0xvZ2luJyAmJiAhTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyKCkgKSB7XG5cdFx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCBHbG9iYWwuZ2V0QmFzZVVSTCgpICsgJyMhbT1Mb2dpbicgKTtcblx0XHRcdHJldHVybjtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGltZW91dF9jb3VudCA9IDA7XG5cdFx0XHRpZiAoIHZpZXdfaWQgIT09ICdMb2dpbicgJiYgR2xvYmFsLmlzU2V0KCB2aWV3X2lkICkgKSB7XG5cdFx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEubG9hZFZpZXdSZXF1aXJlZEpTUmVhZHkgKSB7XG5cdFx0XHRcdFx0aW5pdFJpYmJvbk1lbnVBbmRDb3B5UmlnaHQoKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRhdXRvX2xvZ2luX3RpbWVyID0gc2V0SW50ZXJ2YWwoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0aWYgKCB0aW1lb3V0X2NvdW50ID09IDEwMCApIHtcblx0XHRcdFx0XHRcdFx0Y2xlYXJJbnRlcnZhbCggYXV0b19sb2dpbl90aW1lciApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0dGltZW91dF9jb3VudCA9IHRpbWVvdXRfY291bnQgKyAxO1xuXHRcdFx0XHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5sb2FkVmlld1JlcXVpcmVkSlNSZWFkeSApIHtcblx0XHRcdFx0XHRcdFx0aW5pdFJpYmJvbk1lbnVBbmRDb3B5UmlnaHQoKTtcblx0XHRcdFx0XHRcdFx0Y2xlYXJJbnRlcnZhbCggYXV0b19sb2dpbl90aW1lciApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0sIDYwMCApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzaG93UmliYm9uTWVudUFuZExvYWRWaWV3KCk7XG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRmdW5jdGlvbiBzaG93UmliYm9uTWVudUFuZExvYWRWaWV3KCkge1xuXG5cdFx0XHRpZiAoIHZpZXdfaWQgJiYgdmlld19pZCAhPT0gJ0xvZ2luJyApIHtcblx0XHRcdFx0JHRoaXMuZXZlbnRfYnVzLmVtaXQoICd0dF90b3BiYXInLCAncmVmcmVzaF9sb2dpbl9kYXRhJyApOyAvLyBVcGRhdGUgdGhlIHRvcGJhciBjb21wYW55IGFuZCBsb2dnZWQgaW4gdXNlci5cblx0XHRcdFx0JHRoaXMuc2V0Q29udGVudERpdkhlaWdodCgpO1xuXHRcdFx0fVxuXG5cdFx0XHQgaWYgKCB2aWV3X2lkICYmIHZpZXdfaWQgIT09ICdMb2dpbicgKSB7XG5cdFx0XHRcdCQoICdib2R5JyApLnJlbW92ZUNsYXNzKCAnbG9naW4tYmcnICk7XG5cdFx0XHRcdCQoICdib2R5JyApLmFkZENsYXNzKCAnYXBwbGljYXRpb24tYmcnICk7XG5cdFx0XHR9XG5cblx0XHRcdHN3aXRjaCAoIHZpZXdfaWQgKSB7XG5cdFx0XHRcdGNhc2UgJ0pvYkFwcGxpY2F0aW9uJzpcblx0XHRcdFx0XHQvLyByZXF1aXJlKCBbJ2F1dG9saW5rZXIvQXV0b2xpbmtlci5taW4nLCAncGRmanMtZGlzdC9idWlsZC9wZGYnLCAncGRmanMvY29tcGF0aWJpbGl0eScsICdwZGZqcy91aV91dGlscycsICdwZGZqcy90ZXh0X2xheWVyX2J1aWxkZXInXSwgZnVuY3Rpb24oIGF1dG9saW5rZXIgKSB7XG5cdFx0XHRcdFx0Ly8gXHR3aW5kb3cuQXV0b2xpbmtlciA9IGF1dG9saW5rZXI7XG5cdFx0XHRcdFx0XHRHbG9iYWwubG9hZFZpZXdTb3VyY2UoIHZpZXdfaWQsIHZpZXdfaWQgKyAnVmlld0NvbnRyb2xsZXIuanMnLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0dmFyIHBlcm1pc3Npb25faWQgPSB2aWV3X2lkO1xuXHRcdFx0XHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLmNoZWNrVG9wTGV2ZWxQZXJtaXNzaW9uKCBwZXJtaXNzaW9uX2lkICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0QmFzZVZpZXdDb250cm9sbGVyLmxvYWRWaWV3KCB2aWV3X2lkICk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93QWxlcnQoICdQZXJtaXNzaW9uIGRlbmllZCcsICdFUlJPUicsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkgJiYgTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLmRlZmF1bHRfbG9naW5fc2NyZWVuICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRNZW51TWFuYWdlci5nb1RvVmlldyggTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLmRlZmF1bHRfbG9naW5fc2NyZWVuICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRNZW51TWFuYWdlci5nb1RvVmlldyggJ0hvbWUnICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0XHRcdERlYnVnLlRleHQoICdOYXZpZ2F0aW9uIHBlcm1pc3Npb24gZGVuaWVkLiBQZXJtaXNzaW9uOiAnICsgcGVybWlzc2lvbl9pZCwgJ0luZGV4Q29udHJvbGxlci5qcycsICdJbmRleENvbnRyb2xsZXInLCAnc2hvd1JpYmJvbk1lbnVBbmRMb2FkVmlldycsIDEwICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHQvLyB9ICk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0R2xvYmFsLmxvYWRWaWV3U291cmNlKCB2aWV3X2lkLCB2aWV3X2lkICsgJ1ZpZXdDb250cm9sbGVyLmpzJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHR2YXIgcGVybWlzc2lvbl9pZCA9IHZpZXdfaWQ7XG5cblx0XHRcdFx0XHRcdHN3aXRjaCAoIHZpZXdfaWQgKSB7XG5cdFx0XHRcdFx0XHRcdGNhc2UgJ0NsaWVudEdyb3VwJzpcblx0XHRcdFx0XHRcdFx0XHRwZXJtaXNzaW9uX2lkID0gJ0NsaWVudCc7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdGNhc2UgJ1Byb2R1Y3RHcm91cCc6XG5cdFx0XHRcdFx0XHRcdFx0cGVybWlzc2lvbl9pZCA9ICdQcm9kdWN0Jztcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0Y2FzZSAnUGF5U3R1YlRyYW5zYWN0aW9uU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRcdFx0XHRcdGNhc2UgJ1BheVN0dWJUcmFuc2FjdGlvbic6XG5cdFx0XHRcdFx0XHRcdFx0cGVybWlzc2lvbl9pZCA9ICdQYXlTdHViJztcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRpZiAoIHZpZXdfaWQgPT09ICdMb2dpbicgfHwgdmlld19pZCA9PT0gJ0hvbWUnIHx8IFBlcm1pc3Npb25NYW5hZ2VyLmNoZWNrVG9wTGV2ZWxQZXJtaXNzaW9uKCBwZXJtaXNzaW9uX2lkICkgKSB7XG5cdFx0XHRcdFx0XHRcdEJhc2VWaWV3Q29udHJvbGxlci5sb2FkVmlldyggdmlld19pZCApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIudmlld0lkICYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIudmlld0lkID09ICdMb2dpblZpZXcnICkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpICYmIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKS5kZWZhdWx0X2xvZ2luX3NjcmVlbiApIHtcblx0XHRcdFx0XHRcdFx0XHRcdE1lbnVNYW5hZ2VyLmdvVG9WaWV3KCBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkuZGVmYXVsdF9sb2dpbl9zY3JlZW4gKTtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0TWVudU1hbmFnZXIuZ29Ub1ZpZXcoICdIb21lJyApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dBbGVydCggJ1Blcm1pc3Npb24gZGVuaWVkJywgJ0VSUk9SJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKSAmJiBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkuZGVmYXVsdF9sb2dpbl9zY3JlZW4gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdE1lbnVNYW5hZ2VyLmdvVG9WaWV3KCBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkuZGVmYXVsdF9sb2dpbl9zY3JlZW4gKTtcblx0XHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdE1lbnVNYW5hZ2VyLmdvVG9WaWV3KCAnSG9tZScgKTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0RGVidWcuVGV4dCggJ05hdmlnYXRpb24gcGVybWlzc2lvbiBkZW5pZWQuIFBlcm1pc3Npb246ICcgKyBwZXJtaXNzaW9uX2lkLCAnSW5kZXhDb250cm9sbGVyLmpzJywgJ0luZGV4Q29udHJvbGxlcicsICdzaG93UmliYm9uTWVudUFuZExvYWRWaWV3JywgMTAgKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGluaXRSaWJib25NZW51QW5kQ29weVJpZ2h0KCkge1xuXG5cdFx0XHQvLyBUcmlnZ2VyIFZ1ZSBUb3BNZW51IHRvIGxvYWQsIG5vdyB0aGF0IGFsbCBwcmUtcmVxdWlzaXRpdmVzIGxpa2UgbG9naW4gaW5mbyBoYXZlIGJlZW4gcnVuLlxuXHRcdFx0JHRoaXMuZXZlbnRfYnVzLmVtaXQoICd0dF90b3BfY29udGFpbmVyJywgJ3JlYWR5X3RvX2xvYWRfdG9wX2JhcicgKTtcblxuXHRcdFx0Ly9BZGQgY29weSByaWdodFxuXHRcdFx0R2xvYmFsLmJvdHRvbUNvbnRhaW5lcigpLmNzcyggJ2Rpc3BsYXknLCAnYmxvY2snICk7XG5cblx0XHRcdC8vU3RhcnQgY2hlY2sgc2lnbmFsXG5cdFx0XHRHbG9iYWwuc2V0U2lnbmFsU3RyZW5ndGgoKTtcblxuXHRcdFx0Ly9BZGQgZmVlZGJhY2sgZXZlbnRcblx0XHRcdEdsb2JhbC5ib3R0b21GZWVkYmFja0xpbmtDb250YWluZXIoKS5jc3MoICdkaXNwbGF5JywgJ2Jsb2NrJyApO1xuXHRcdFx0JCggJyNmZWVkYmFjay1saW5rJyApLm9mZiggJ2NsaWNrLmZlZWRiYWNrJyApLm9uKCAnY2xpY2suZmVlZGJhY2snLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0JCgpLlRGZWVkYmFjaygge1xuXHRcdFx0XHRcdHNvdXJjZTogJ01hbnVhbFRyaWdnZXInLFxuXHRcdFx0XHRcdG1hbnVhbF90cmlnZ2VyOiB0cnVlLFxuXHRcdFx0XHRcdHByb21wdF9mb3JfZmVlZGJhY2s6IHRydWUgLy8gcmVnYXJkbGVzcyBvZiBzZXJ2ZXIgZmVlZGJhY2sgc3RhdGUgaW5wdXQsIGNsaWNrIHNob3VsZCBhbHdheXMgYWxsb3cgZmVlZGJhY2tcblx0XHRcdFx0fSApO1xuXHRcdFx0fSApO1xuXG5cdFx0XHQkKCAnI2NvcHlfcmlnaHRfaW5mb18xJyApLmNzcyggJ2Rpc3BsYXknLCAnaW5saW5lJyApO1xuXHRcdFx0JCggJyNjb3B5X3JpZ2h0X2xvZ29fbGluaycgKS5hdHRyKCAnaHJlZicsICdodHRwczovLycgKyBMb2NhbENhY2hlRGF0YS5nZXRMb2dpbkRhdGEoKS5vcmdhbml6YXRpb25fdXJsICk7XG5cdFx0XHRpZiAoICEkKCAnI2NvcHlfcmlnaHRfbG9nbycgKS5hdHRyKCAnc3JjJyApICkge1xuXHRcdFx0XHQkKCAnI2NvcHlfcmlnaHRfbG9nbycgKS5hdHRyKCAnc3JjJywgU2VydmljZUNhbGxlci5nZXRVUkxCeU9iamVjdFR5cGUoICdjb3B5cmlnaHQnICkgKTsgLy8gVXNlIHRoZSBzYW1lIGxvZ28gYXMgdGhlIG9uZSBvbiB0aGUgbG9naW4gc2NyZWVuLiAoQ2hhbmdlZCBmcm9tIHNtY29weXJpZ2h0KVxuXHRcdFx0fVxuXHRcdFx0c2hvd1JpYmJvbk1lbnVBbmRMb2FkVmlldygpO1xuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGNoZWNrSWRzKCkge1xuXG5cdFx0XHRpZiAoIEdsb2JhbC5pc0FycmF5KCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmN1cnJlbnRfZWRpdF9yZWNvcmQgKSApIHtcblx0XHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5jdXJyZW50X2VkaXRfcmVjb3JkLmxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRcdHZhciBpdGVtID0gTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5jdXJyZW50X2VkaXRfcmVjb3JkW2ldO1xuXG5cdFx0XHRcdFx0aWYgKCBpdGVtLmlkICYmIGl0ZW0uaWQgPT09IGVkaXRfaWQgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGl0ZW0gPSBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmN1cnJlbnRfZWRpdF9yZWNvcmQ7XG5cdFx0XHRcdGlmICggaXRlbS5pZCAmJiBpdGVtLmlkID09PSBlZGl0X2lkICkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBvcGVuRWRpdFZpZXcoIGVkaXRfaWQsIHZpZXdfbW9kZSApIHtcblx0XHRcdHZhciB0eXBlO1xuXHRcdFx0c3dpdGNoICggdmlld19pZCApIHtcblx0XHRcdFx0Y2FzZSAnTWVzc2FnZUNvbnRyb2wnOlxuXHRcdFx0XHRcdHR5cGUgPSBhcmdzLnQ7XG5cdFx0XHRcdFx0dmFyIGl0ZW0gPSB7fTtcblx0XHRcdFx0XHRpZiAoIHR5cGUgPT09ICdtZXNzYWdlJyApIHtcblx0XHRcdFx0XHRcdGl0ZW0uaWQgPSBlZGl0X2lkO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRpdGVtLm9iamVjdF9pZCA9IGVkaXRfaWQ7XG5cdFx0XHRcdFx0XHRpdGVtLm9iamVjdF90eXBlX2lkID0gNTA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIub25WaWV3Q2xpY2soIGl0ZW0gKTtcblx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRjYXNlICdUaW1lU2hlZXQnOlxuXHRcdFx0XHRcdHR5cGUgPSBhcmdzLnQ7XG5cblx0XHRcdFx0XHRpZiAoICF2aWV3X21vZGUgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGVkaXRfaWQgKSB7XG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIub25FZGl0Q2xpY2soIGVkaXRfaWQsIHR5cGUgKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIub25BZGRDbGljaygpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRpZiAoIGVkaXRfaWQgKSB7XG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIub25WaWV3Q2xpY2soIGVkaXRfaWQsIHR5cGUgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0ZGVmYXVsdDpcblxuXHRcdFx0XHRcdGlmICggIXZpZXdfbW9kZSApIHtcblx0XHRcdFx0XHRcdGlmICggZWRpdF9pZCApIHtcblx0XHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5vbkVkaXRDbGljayggZWRpdF9pZCApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5vbkFkZENsaWNrKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGlmICggZWRpdF9pZCApIHtcblx0XHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5vblZpZXdDbGljayggZWRpdF9pZCApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblxuXHR9XG5cblx0LyoganNoaW50IGlnbm9yZTplbmQgKi9cblxuXHRjbGVhbkFueVN1YlZpZXdVSSgpIHtcblx0XHR2YXIgY2hpbGRyZW4gPSBHbG9iYWwuY29udGVudENvbnRhaW5lcigpLmNoaWxkcmVuKCk7XG5cblx0XHRpZiAoIGNoaWxkcmVuLmxlbmd0aCA+IDEgKSB7XG5cdFx0XHRmb3IgKCB2YXIgaSA9IDE7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0Ly8gT2JqZWN0IGRvZXNuJ3Qgc3VwcG9ydCBwcm9wZXJ0eSBvciBtZXRob2QgJ3JlbW92ZScsIE5vdCBzdXJlIHdoeSwgYWRkIHRyeSBjYXRjaCB0byBpbmdvcmUgdGhpcyBlcnJvciBzaW5jZSB0aGlzIHNob3VsZCBubyBoYXJtXG5cdFx0XHRcdHRyeSB7XG5cblx0XHRcdFx0XHRpZiAoICQoIGNoaWxkcmVuW2ldICkuYXR0ciggJ2lkJyApID09PSBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnVpX2lkICkge1xuXHRcdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGNoaWxkcmVuW2ldLnJlbW92ZSgpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0XHQvL0RvIG5vdGhpbmdcblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0c2V0Q29udGVudERpdkhlaWdodCgpIHtcblx0XHQvLyBOb3cgZG9uZSBieSBDU1MgY2FsY3VsYXRpb25cblx0XHQvLyBHbG9iYWwuY29udGVudENvbnRhaW5lcigpLmNzcyggJ2hlaWdodCcsICggR2xvYmFsLmJvZHlIZWlnaHQoKSAtIEdsb2JhbC50b3BDb250YWluZXIoKS5oZWlnaHQoKSAtICQoJy50b3BiYXInKS5oZWlnaHQoKSApICk7IC8vIFRPRE86IGRvIGF3YXkgd2l0aCB0aGVzZSBoYXJkY29kZWQgY2FsY3VsYXRlZCBoZWlnaHRzIGluIGZ1dHVyZSByZWZhY3Rvci5cblx0XHQvLyAkKCB3aW5kb3cgKS5yZXNpemUoIGZ1bmN0aW9uKCkge1xuXHRcdC8vIFx0R2xvYmFsLmNvbnRlbnRDb250YWluZXIoKS5jc3MoICdoZWlnaHQnLCAoIEdsb2JhbC5ib2R5SGVpZ2h0KCkgLSBHbG9iYWwudG9wQ29udGFpbmVyKCkuaGVpZ2h0KCkgLSAkKCcudG9wYmFyJykuaGVpZ2h0KCkpICk7IC8vIFRPRE86IGRvIGF3YXkgd2l0aCB0aGVzZSBoYXJkY29kZWQgY2FsY3VsYXRlZCBoZWlnaHRzIGluIGZ1dHVyZSByZWZhY3Rvci5cblx0XHQvLyB9ICk7XG5cblx0XHRHbG9iYWwuY29udGVudENvbnRhaW5lcigpLnJlbW92ZUNsYXNzKCAnY29udGVudC1jb250YWluZXInICk7XG5cdFx0R2xvYmFsLmNvbnRlbnRDb250YWluZXIoKS5hZGRDbGFzcyggJ2NvbnRlbnQtY29udGFpbmVyLWFmdGVyLWxvZ2luJyApO1xuXHR9XG5cblx0cmVtb3ZlQ3VycmVudFZpZXcoIGNhbGxCYWNrICkge1xuXG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fZWRpdF9vbmx5X2NvbnRyb2xsZXIgKSB7XG5cdFx0XHRjbGVhbiggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX2VkaXRfb25seV9jb250cm9sbGVyICk7XG5cdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fZWRpdF9vbmx5X2NvbnRyb2xsZXIgPSBudWxsO1xuXHRcdH1cblxuXHRcdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlciApIHtcblx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5lZGl0X3ZpZXcgKSB7XG5cdFx0XHRcdGNsZWFuKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICk7XG5cdFx0XHR9XG5cdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnVubW91bnRDb250ZXh0TWVudSgpO1xuXHRcdFx0R2xvYmFsLmNvbnRlbnRDb250YWluZXIoKS5jaGlsZHJlbigpLmRldGFjaCgpLnJlbW92ZSgpOyAvLyBUaGlzIGlzIGFib3V0IDN4IGZhc3RlciB0aGFuIEdsb2JhbC5jb250ZW50Q29udGFpbmVyKCkuZW1wdHkoKVxuXHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5jbGVhbldoZW5VbmxvYWRWaWV3KCBjYWxsQmFjayApO1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGlmICggR2xvYmFsLmlzU2V0KCBjYWxsQmFjayApICkge1xuXHRcdFx0XHRjYWxsQmFjaygpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGNsZWFuKCB2aWV3Q29udHJvbGxlciApIHtcblx0XHRcdHZpZXdDb250cm9sbGVyLmNsZWFyRXJyb3JUaXBzKCk7XG5cdFx0XHQvLyBDYW5ub3QgcmVhZCBwcm9wZXJ0eSAncmVtb3ZlJyBvZiBudWxsIGluIGludGVyZmFjZS9odG1sNS9JbmRleENvbnRyb2xsZXIuanM/dj05LjAuMC0yMDE1MTAxNi0xNTMwNTcgbGluZSA0Mzlcblx0XHRcdGlmICggdmlld0NvbnRyb2xsZXIuZWRpdF92aWV3ICkge1xuXHRcdFx0XHQvLyAjcXVlc3Rpb246IE5vdCBzdXJlIHdoZW4gdGhpcyB3b3VsZCBiZSB0cmlnZ2VkLCBidXQgdGhpcyBzaG91bGQgc3VyZWx5IHJ1biB0aHJvdWdoIHZpZXdDb250cm9sbGVyLnJlbW92ZUVkaXRWaWV3KCk/XG5cdFx0XHRcdHZpZXdDb250cm9sbGVyLnVubW91bnRDb250ZXh0TWVudSgpOyAvLyBOb3Qgc3VyZSB3aGVuIHRoaXMgY2xlYW4gd291bGQgYmUgdHJpZ2dlZCwgYnV0IGxldHMgaGF2ZSB0aGlzIGhlcmUganVzdCBpbiBjYXNlLlxuXHRcdFx0XHR2aWV3Q29udHJvbGxlci5lZGl0X3ZpZXcucmVtb3ZlKCk7XG5cdFx0XHR9XG5cdFx0XHR2aWV3Q29udHJvbGxlci5zdWJfbG9nX3ZpZXdfY29udHJvbGxlciA9IG51bGw7XG5cdFx0XHR2aWV3Q29udHJvbGxlci5lZGl0X3ZpZXdfdWlfZGljID0ge307XG5cdFx0XHR2aWV3Q29udHJvbGxlci5lZGl0X3ZpZXdfdWlfdmFsaWRhdGlvbl9maWVsZF9kaWMgPSB7fTtcblx0XHRcdHZpZXdDb250cm9sbGVyLmVkaXRfdmlld19mb3JtX2l0ZW1fZGljID0ge307XG5cdFx0XHR2aWV3Q29udHJvbGxlci5lZGl0X3ZpZXdfZXJyb3JfdWlfZGljID0ge307XG5cdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X2RvaW5nX2NvbnRleHRfYWN0aW9uID0gJyc7XG5cdFx0fVxuXHR9XG5cbn1cblxuZXhwb3J0IGNsYXNzIEluZGV4Vmlld0NvbnRyb2xsZXIgZXh0ZW5kcyBUVEJhY2tib25lVmlldyB7XG5cblx0Y29uc3RydWN0b3IoIG9wdGlvbnMgPSB7fSApIHtcblx0XHRfLmRlZmF1bHRzKCBvcHRpb25zLCB7XG5cdFx0XHRlbDogJ2JvZHknLCAvL1NvIHdlIGNhbiBhZGQgZXZlbnQgbGlzdGVuZXIgZm9yIGFsbCBlbGVtZW50c1xuXHRcdFx0cm91dGVyOiBudWxsLFxuXHRcdH0gKTtcblxuXHRcdHN1cGVyKCBvcHRpb25zICk7XG5cdH1cblxuXHRpbml0aWFsaXplKCBvcHRpb25zICkge1xuXG5cdFx0c3VwZXIuaW5pdGlhbGl6ZSggb3B0aW9ucyApO1xuXHRcdHRoaXMucm91dGVyID0gbmV3IEFwcGxpY2F0aW9uUm91dGVyKCk7XG5cblx0XHQvL1NldCB0aXRsZSBpbiBpbmRleC5waHAgaW5zdGVhZC5cblx0XHQvLyQoICd0aXRsZScgKS5odG1sKCAnJyApO1xuXG5cdFx0dGhpcy5yb3V0ZXIuY29udHJvbGxlciA9IHRoaXM7XG5cdFx0Ly9FcnJvcjogQmFja2JvbmUuaGlzdG9yeSBoYXMgYWxyZWFkeSBiZWVuIHN0YXJ0ZWQgaW4gaW50ZXJmYWNlL2h0bWw1L2ZyYW1ld29yay9iYWNrYm9uZS9iYWNrYm9uZS1taW4uanM/dj05LjAuMS0yMDE1MTAyMi0xNjIxMTAgbGluZSAyOFxuXHRcdGlmICggIUJhY2tib25lLkhpc3Rvcnkuc3RhcnRlZCApIHtcblx0XHRcdEJhY2tib25lLmhpc3Rvcnkuc3RhcnQoKTtcblx0XHR9XG5cblx0XHRJbmRleFZpZXdDb250cm9sbGVyLmluc3RhbmNlID0gdGhpcztcblxuXHR9XG5cblx0c3RhdGljIGdvVG9WaWV3KCB2aWV3X25hbWUsIGZpbHRlciApIHtcblx0XHRHbG9iYWwuY2xvc2VFZGl0Vmlld3MoIGZ1bmN0aW9uKCkge1xuXHRcdFx0TG9jYWxDYWNoZURhdGEuZGVmYXVsdF9maWx0ZXJfZm9yX25leHRfb3Blbl92aWV3ID0gZmlsdGVyO1xuXHRcdFx0TWVudU1hbmFnZXIuZ29Ub1ZpZXcoIHZpZXdfbmFtZSwgdHJ1ZSApO1xuXHRcdH0gKTtcblxuXHR9XG5cblx0c3RhdGljIGdvVG9WaWV3QnlWaWV3TGFiZWwoIHZpZXdfbGFiZWwgKSB7XG5cdFx0dmFyIHZpZXdfbmFtZTtcblx0XHRzd2l0Y2ggKCB2aWV3X2xhYmVsICkge1xuXHRcdFx0Y2FzZSAnRXhjZXB0aW9ucyc6XG5cdFx0XHRcdHZpZXdfbmFtZSA9ICdFeGNlcHRpb24nO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ01lc3NhZ2VzJzpcblx0XHRcdFx0dmlld19uYW1lID0gJ01lc3NhZ2VDb250cm9sJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdSZXF1ZXN0cyc6XG5cdFx0XHRcdHZpZXdfbmFtZSA9ICdSZXF1ZXN0Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdDb250YWN0IEluZm9ybWF0aW9uJzpcblx0XHRcdFx0SW5kZXhWaWV3Q29udHJvbGxlci5vcGVuRWRpdFZpZXcoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIsICdMb2dpblVzZXJDb250YWN0JyApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHRjYXNlICdJbk91dCc6XG5cdFx0XHRcdEluZGV4Vmlld0NvbnRyb2xsZXIub3BlbkVkaXRWaWV3KCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLCAnSW5PdXQnICk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdHZhciByZWcgPSAvXFxzL2c7XG5cdFx0XHRcdHZpZXdfbmFtZSA9IHZpZXdfbGFiZWwucmVwbGFjZSggcmVnLCAnJyApO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHRNZW51TWFuYWdlci5nb1RvVmlldyggdmlld19uYW1lLCB0cnVlICk7XG5cblx0fVxuXG5cdC8vREVQUkVDQVRFRDogYWxsIG5ldyB3aXphcmRzIHNob3VsZCBnbyB0aHJvdWdoIG9wZW5XaXphcmRDb250cm9sbGVyKClcblx0c3RhdGljIG9wZW5XaXphcmQoIHdpemFyZE5hbWUsIGRlZmF1bHREYXRhLCBjYWxsQmFjayApIHtcblx0XHRHbG9iYWwuc2V0VUlOb3RyZWFkeSgpO1xuXG5cdFx0QmFzZVdpemFyZENvbnRyb2xsZXIuZGVmYXVsdF9kYXRhID0gZGVmYXVsdERhdGE7XG5cdFx0QmFzZVdpemFyZENvbnRyb2xsZXIuY2FsbF9iYWNrID0gY2FsbEJhY2s7XG5cblx0XHRzd2l0Y2ggKCB3aXphcmROYW1lICkge1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0Ly8gdHJhY2sgZWRpdCB2aWV3IG9ubHkgdmlld1xuXHRcdFx0XHRHbG9iYWwudHJhY2tWaWV3KCB3aXphcmROYW1lICk7XG5cdFx0XHRcdEdsb2JhbC5sb2FkVmlld1NvdXJjZSggd2l6YXJkTmFtZSwgd2l6YXJkTmFtZSArICdDb250cm9sbGVyLmpzJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0QmFzZVdpemFyZENvbnRyb2xsZXIub3BlbldpemFyZCggd2l6YXJkTmFtZSwgd2l6YXJkTmFtZSArICcuaHRtbCcgKTtcblx0XHRcdFx0fSApO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0fVxuXG5cdC8vQVRUTjogTmV3IHdpemFyZHMgc2hvdWxkIGdvIHRocm91Z2ggdGhpc1xuXHRzdGF0aWMgb3BlbldpemFyZENvbnRyb2xsZXIoIHdpemFyZF9pZCwgZmlsdGVyX2RhdGEsIHNvdXJjZV92aWV3ICkge1xuXHRcdEdsb2JhbC5zZXRVSU5vdHJlYWR5KCk7XG5cdFx0Ly8gQmFzZVdpemFyZENvbnRyb2xsZXIuZGVmYXVsdF9kYXRhID0gZGVmYXVsdERhdGE7XG5cdFx0Ly8gQmFzZVdpemFyZENvbnRyb2xsZXIuY2FsbF9iYWNrID0gY2FsbEJhY2s7XG5cdFx0c3dpdGNoICggd2l6YXJkX2lkICkge1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0Ly8gdHJhY2sgZWRpdCB2aWV3IG9ubHkgdmlld1xuXHRcdFx0XHRHbG9iYWwudHJhY2tWaWV3KCB3aXphcmRfaWQgKTtcblx0XHRcdFx0R2xvYmFsLmxvYWRWaWV3U291cmNlKCB3aXphcmRfaWQsIHdpemFyZF9pZCArICcuanMnLCBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3dpemFyZF9jb250cm9sbGVycy5zb21lKCB3aXphcmQgPT4gd2l6YXJkLndpemFyZF9pZCA9PT0gd2l6YXJkX2lkICkgKSB7XG5cdFx0XHRcdFx0XHRzd2l0Y2ggKCB3aXphcmRfaWQgKSB7XG5cdFx0XHRcdFx0XHRcdGNhc2UgJ1JlcG9ydFZpZXdXaXphcmQnOlxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRjYXNlICdQYXlyb2xsUmVtaXR0YW5jZUFnZW5jeUV2ZW50V2l6YXJkQ29udHJvbGxlcic6XG5cdFx0XHRcdFx0XHRcdFx0Ly9pZiB0aGUgY3VycmVudCB3aXphcmQgaXMgYSBQYXlyb2xsUmVtaXR0YW5jZUFnZW5jeUV2ZW50V2l6YXJkLCB3ZSBuZWVkIHRvIHJlbWVtYmVyIHRoZSBjYXJkcyB0aGF0IHdlcmUgY2xpY2tlZCBiZWNhdXNlIGl0J3MganVzdCBtaW5pbWl6ZWQuXG5cdFx0XHRcdFx0XHRcdFx0dmFyIHdpemFyZCA9IExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl93aXphcmRfY29udHJvbGxlcnMuZmluZCggd2l6YXJkID0+IHdpemFyZC53aXphcmRfaWQgPT09IHdpemFyZF9pZCApO1xuXHRcdFx0XHRcdFx0XHRcdHdpemFyZC5yZW1vdmUoKTsgLy8gIzI3NjggUmVtb3ZlcyB0aGUgZXhpc3Rpbmcgd2l6YXJkIERPTSBlbGVtZW50IGlmIGl0IGV4aXN0cywgdG8gYXZvaWQgZHVwbGljYXRlIHdpemFyZHMuIENhdXNlcyBpc3N1ZSB3aGVuIHVzZXIgZG91YmxlIGNsaWNrcyBvbiBXaXphcmQgaWNvbiAod2l0aG91dCBvdmVybGF5KSBvciBUYXggV2l6YXJkIG9wZW5lZCB3aGVuIGFscmVhZHkgb3Blbi4gVE9ETzogQWRkIG92ZXJsYXkgdG8gcHJldmVudCBiYWNrZ3JvdW5kIGNsaWNrcy5cblx0XHRcdFx0XHRcdFx0XHR3aXphcmQuZ2V0U3RlcE9iamVjdCgpLmluaXRpYWxpemUoIHdpemFyZCApO1xuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0XHRcdHZhciB3aXphcmQgPSBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fd2l6YXJkX2NvbnRyb2xsZXJzLmZpbmQoIHdpemFyZCA9PiB3aXphcmQud2l6YXJkX2lkID09PSB3aXphcmRfaWQgKTtcblx0XHRcdFx0XHRcdFx0XHR3aXphcmQub25DbG9zZUNsaWNrKCk7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0R2xvYmFsLmxvYWRWaWV3U291cmNlKCB3aXphcmRfaWQsIHdpemFyZF9pZCArICcuaHRtbCcsIGZ1bmN0aW9uKCByZXN1bHQgKSB7XG5cdFx0XHRcdFx0XHR2YXIgYXJncyA9IHt9O1xuXHRcdFx0XHRcdFx0dmFyIHRlbXBsYXRlID0gXy50ZW1wbGF0ZSggcmVzdWx0ICk7XG5cdFx0XHRcdFx0XHQkKCAnYm9keScgKS5hcHBlbmQoIHRlbXBsYXRlKCBhcmdzICkgKTtcblxuXHRcdFx0XHRcdFx0Ly8jMjQyMiAtIHBhc3MgdGhlIGRhdGEgb24gdG8gdGhlIHByb2Nlc3MgdHJhbnNhY3Rpb25zIHdpemFyZFxuXHRcdFx0XHRcdFx0Ly8gVGhpcyBtdXN0IGJlIGhlcmUgYmVjYXVzZSB3ZSBkb24ndCBpbnN0YW50aWF0ZSB0aGUgV2l6YXJkQ29udHJvbGxlciAoIHRoZSBob3N0IHZpZXcgKSBpbiB0aGUgaHRtbCBmaWxlIGxpa2Ugd2UgZG8gd2l0aCBvdGhlciB2aWV3cyBzbyB0aGF0IHdlIGNhbiBwYXNzIGl0IGNvbnN0cnVjdG9yIGFyZ3VtZW50c1xuXHRcdFx0XHRcdFx0c3dpdGNoICggd2l6YXJkX2lkICkge1xuXHRcdFx0XHRcdFx0XHRjYXNlICdQcm9jZXNzVHJhbnNhY3Rpb25zV2l6YXJkQ29udHJvbGxlcic6XG5cdFx0XHRcdFx0XHRcdFx0bmV3IFByb2Nlc3NUcmFuc2FjdGlvbnNXaXphcmRDb250cm9sbGVyKCBmaWx0ZXJfZGF0YSApO1xuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRHbG9iYWwuc2V0VUlJbml0Q29tcGxldGUoKTtcblx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdH0gKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXG5cdH1cblxuXHRzdGF0aWMgb3BlblJlcG9ydCggcGFyZW50X3ZpZXdfY29udHJvbGxlciwgdmlld19uYW1lLCBpZCwgdGFiX25hbWUgKSB7XG5cdFx0Ly8gTm90ZTogVGhpcyBiZWhhdmlvdXIvcm91dGVyIGNhbGwgaXMgYWxzbyBpbiBCYXNlVmlld0NvbnRyb2xsZXIubG9hZFZpZXcoKVxuXHRcdC8vIFZ1ZVJvdXRlci5wdXNoKHtcblx0XHQvLyBcdG5hbWU6ICdyZXBvcnQnLFxuXHRcdC8vIFx0cGFyYW1zOiB7XG5cdFx0Ly8gXHRcdHZpZXdJZDogdmlld19uYW1lXG5cdFx0Ly8gXHR9XG5cdFx0Ly8gfSkudGhlbihmdW5jdGlvbigpIHtcblx0XHQvLyBcdGRvTmV4dEFmdGVyUmVwb3J0Um91dGVDaGFuZ2UoKTtcblx0XHQvLyB9KTtcblx0XHRkb05leHRBZnRlclJlcG9ydFJvdXRlQ2hhbmdlKCk7IC8vIE5vdyB1c2luZyBvbmUgZ2xvYmFsIGNvbnRleHQgbWVudSwgc28gbm8gbmVlZCBmb3Igcm91dGVyIGNhbGxzLiBKdXN0IHVzaW5nIHRoZSBvbmUgc2luZ2xlIExlZ2FjeVZpZXcgZm9yIG5vdy5cblxuXHRcdGZ1bmN0aW9uIGRvTmV4dEFmdGVyUmVwb3J0Um91dGVDaGFuZ2UoKSB7XG5cdFx0XHRHbG9iYWwuY2xvc2VFZGl0Vmlld3MoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9yZXBvcnRfY29udHJvbGxlciApIHtcblx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcmVwb3J0X2NvbnRyb2xsZXIucmVtb3ZlRWRpdFZpZXcoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdFByb2dyZXNzQmFyLnNob3dPdmVybGF5KCk7XG5cblx0XHRcdFx0c3dpdGNoICggdmlld19uYW1lICkge1xuXHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHR2YXIgcGF0aCA9IEdsb2JhbC5nZXRWaWV3UGF0aEJ5Vmlld0lkKCB2aWV3X25hbWUgKTtcblx0XHRcdFx0XHRcdGlmICggcGF0aCApIHtcblx0XHRcdFx0XHRcdFx0R2xvYmFsLmxvYWRTY3JpcHQoIHBhdGggKyB2aWV3X25hbWUgKyAnVmlld0NvbnRyb2xsZXInLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnUi1MT0FESU5HOiAnICsgdmlld19uYW1lLCAnSW5kZXhWaWV3Q29udHJvbGxlci5qcycsICdJbmRleFZpZXdDb250cm9sbGVyJywgJ29wZW5SZXBvcnQnLCAxMCApO1xuXHRcdFx0XHRcdFx0XHRcdC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cblx0XHRcdFx0XHRcdFx0XHRUVFByb21pc2UuYWRkKCAnUmVwb3J0cycsICdvcGVuUmVwb3J0JyApO1xuXHRcdFx0XHRcdFx0XHRcdHZhciAkdmlld19jb250cm9sbGVyID0gZXZhbCggJ25ldyAnICsgdmlld19uYW1lICsgJ1ZpZXdDb250cm9sbGVyKCB7ZWRpdF9vbmx5X21vZGU6IHRydWV9ICk7ICcgKTtcblx0XHRcdFx0XHRcdFx0XHQvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5cdFx0XHRcdFx0XHRcdFx0VFRQcm9taXNlLndhaXQoICdSZXBvcnRzJywgJ29wZW5SZXBvcnQnLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGRvTmV4dCggdmlld19uYW1lLCB0YWJfbmFtZSApO1xuXHRcdFx0XHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHRcdFx0XHRcdGZ1bmN0aW9uIGRvTmV4dCggdmlld19uYW1lLCB0YWJfbmFtZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdCR2aWV3X2NvbnRyb2xsZXIucGFyZW50X3ZpZXdfY29udHJvbGxlciA9IHBhcmVudF92aWV3X2NvbnRyb2xsZXI7XG5cdFx0XHRcdFx0XHRcdFx0XHQkdmlld19jb250cm9sbGVyLm9wZW5FZGl0VmlldygpO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHR2YXIgY3VycmVudF91cmwgPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggY3VycmVudF91cmwuaW5kZXhPZiggJyZzbScgKSA+IDAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGN1cnJlbnRfdXJsID0gY3VycmVudF91cmwuc3Vic3RyaW5nKCAwLCBjdXJyZW50X3VybC5pbmRleE9mKCAnJnNtJyApICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRjdXJyZW50X3VybCA9IGN1cnJlbnRfdXJsICsgJyZzbT0nICsgdmlld19uYW1lO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmRlZmF1bHRfZWRpdF9pZF9mb3JfbmV4dF9vcGVuX2VkaXRfdmlldyApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y3VycmVudF91cmwgPSBjdXJyZW50X3VybCArICcmc2lkPScgKyBMb2NhbENhY2hlRGF0YS5kZWZhdWx0X2VkaXRfaWRfZm9yX25leHRfb3Blbl9lZGl0X3ZpZXc7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdGlmICggdHlwZW9mIHRhYl9uYW1lICE9ICd1bmRlZmluZWQnICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcmVwb3J0X2NvbnRyb2xsZXIuc2VsZWN0ZWRfdGFiID0gdGFiX25hbWU7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGN1cnJlbnRfdXJsICs9ICcmdGFiPScgKyB0YWJfbmFtZTtcblx0XHRcdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIHdpbmRvdy5sb2NhdGlvbi5ocmVmLmluZGV4T2YoICcmdGFiPScgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR2YXIgdGFiX25hbWUgPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGFiX25hbWUgPSB0YWJfbmFtZS5zdWJzdHIoICggd2luZG93LmxvY2F0aW9uLmhyZWYuaW5kZXhPZiggJyZ0YWI9JyApICsgNSApICk7IC8vZ2V0IHRoZSBzZWxlY3RlZCB0YWIgbmFtZVxuXHRcdFx0XHRcdFx0XHRcdFx0XHR0YWJfbmFtZSA9IHRhYl9uYW1lLnN1YnN0ciggMCwgd2luZG93LmxvY2F0aW9uLmhyZWYuaW5kZXhPZiggJyYnICkgKTsgLy8gaW5jYXNlIHRoZXJlIGFyZSBzdWJzZXF1ZW50IGFyZ3VtZW50cyBhZnRlciB0aGUgdGFiIGFyZ3VtZW50XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGN1cnJlbnRfdXJsICs9ICcmdGFiPScgKyB0YWJfbmFtZTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0R2xvYmFsLnNldFVSTFRvQnJvd3NlciggY3VycmVudF91cmwgKTtcblxuXHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Y29uc29sZS5kZWJ1ZyggJ1JlcG9ydCBWaWV3IGRvZXMgbm90IGV4aXN0ISBWaWV3IE5hbWU6ICcgKyB2aWV3X25hbWUgKTtcblx0XHRcdFx0XHRcdFx0aWYgKCBTZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsICYmIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5iYXNlX3VybCApIHtcblx0XHRcdFx0XHRcdFx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCBTZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmJhc2VfdXJsICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH1cblx0fVxuXG5cdC8vT3BlbiBlZGl0IHZpZXdcblx0c3RhdGljIG9wZW5FZGl0VmlldyggcGFyZW50X3ZpZXdfY29udHJvbGxlciwgdmlld19uYW1lLCBpZCwgYWN0aW9uX2Z1bmN0aW9uICkge1xuXHRcdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3JlcG9ydF9jb250cm9sbGVyICkgeyAvL2Rvbid0IGFsbG93IGVkaXR2aWV3cyBvdmVyIHJlcG9ydCB2aWV3cy5cblx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9yZXBvcnRfY29udHJvbGxlci5vbkNhbmNlbENsaWNrKCBudWxsLCBudWxsLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0R2xvYmFsLmNsb3NlRWRpdFZpZXdzKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRJbmRleFZpZXdDb250cm9sbGVyLm9wZW5FZGl0VmlldyggcGFyZW50X3ZpZXdfY29udHJvbGxlciwgdmlld19uYW1lLCBpZCwgYWN0aW9uX2Z1bmN0aW9uICk7XG5cdFx0XHRcdH0gKTtcblx0XHRcdH0gKTtcblx0XHRcdHJldHVybjtcblx0XHR9IGVsc2UgaWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fZWRpdF9vbmx5X2NvbnRyb2xsZXIgJiYgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX2VkaXRfb25seV9jb250cm9sbGVyLnZpZXdJZCAmJiBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fZWRpdF9vbmx5X2NvbnRyb2xsZXIudmlld0lkID09IHZpZXdfbmFtZSApIHsgLy9TdG9wIGVkaXQgb25seSB2aWV3cyBmcm9tIG92ZXJsYXlpbmcgdGhlbXNlbHZlcyB3aXRoIHRoZSBzYW1lIHZpZXcgYW5kIGRpc2Nvbm5lY3Rpbmcgb3RoZXJzIGZyb20gdGhlIG1lbnVcblx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlci5zZXRFZGl0TWVudSgpOyAvL2Rpc3BsYXkgdGhlIHJpZ2h0IGVkaXQgbWVudVxuXHRcdFx0JCggJyNyaWJib25fdmlld19jb250YWluZXIgLmNvbnRleHQtbWVudTp2aXNpYmxlIGEnICkuY2xpY2soKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZG9OZXh0KCk7XG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gZG9OZXh0KCkge1xuXHRcdFx0dmFyIHZpZXdfY29udHJvbGxlciA9IG51bGw7XG5cblx0XHRcdGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLmNoZWNrVG9wTGV2ZWxQZXJtaXNzaW9uKCB2aWV3X25hbWUgKSAmJiB2aWV3X25hbWUgIT09ICdNYXAnICkge1xuXHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIgJiYgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci52aWV3SWQgJiYgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci52aWV3SWQgPT0gJ0xvZ2luVmlldycgKSB7XG5cdFx0XHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkgJiYgTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLmRlZmF1bHRfbG9naW5fc2NyZWVuICkge1xuXHRcdFx0XHRcdFx0TWVudU1hbmFnZXIuZ29Ub1ZpZXcoIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKS5kZWZhdWx0X2xvZ2luX3NjcmVlbiApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRNZW51TWFuYWdlci5nb1RvVmlldyggJ0hvbWUnICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFRBbGVydE1hbmFnZXIuc2hvd0FsZXJ0KCAnUGVybWlzc2lvbiBkZW5pZWQnLCAnRVJST1InLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpICYmIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKS5kZWZhdWx0X2xvZ2luX3NjcmVlbiApIHtcblx0XHRcdFx0XHRcdFx0TWVudU1hbmFnZXIuZ29Ub1ZpZXcoIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKS5kZWZhdWx0X2xvZ2luX3NjcmVlbiApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0TWVudU1hbmFnZXIuZ29Ub1ZpZXcoICdIb21lJyApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHREZWJ1Zy5UZXh0KCAnTmF2aWdhdGlvbiBwZXJtaXNzaW9uIGRlbmllZC4gVmlldzogJyArIHZpZXdfbmFtZSwgJ0luZGV4Q29udHJvbGxlci5qcycsICdJbmRleENvbnRyb2xsZXInLCAnb3BlbkVkaXRWaWV3JywgMTAgKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHZpZXdfbmFtZSA9PSAnUmVxdWVzdCcgKSB7XG5cdFx0XHRcdGFjdGlvbl9mdW5jdGlvbiA9ICdvcGVuQWRkVmlldyc7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggIWFjdGlvbl9mdW5jdGlvbiApIHtcblx0XHRcdFx0YWN0aW9uX2Z1bmN0aW9uID0gJ29wZW5FZGl0Vmlldyc7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZGVkIG9yaWdpbmFsbHkgaW4gODNhMWRmNzIgZm9yIGlzc3VlICMxODA1IGJ1dCBjYXVzZWQgYSBidWcgbWVudGlvbmVkIGluIGlzc3VlICMyMDkxIHRoZSBzdGVwcyB0byByZXByb2R1Y2UgdGhlIGJ1ZyBhcmUgYXMgZm9sbG93czpcblx0XHRcdC8vIDEuIEdvIHRvIGludm9pY2UgPiBjbGllbnQgY29udGFjdHMgYW5kIGhpZ2hsaXRlIGEgQ2xpZW50IENvbnRhY3QgMi4gQ2xpY2sgdGhlIFwiRWRpdCBDbGllbnRcIiBidXR0b24gb24gdGhlIHJpYmJvbiBtZW51XG5cdFx0XHQvLyAzLiBDbGljayB0aGUgSW52b2ljZXMgdGFiIDQuIEVkaXQgYW4gaW52b2ljZSA1LiBDbGljayBQYXltZW50IG9uIHRoZSByaWJib24gbWVudSA2LiBDbGljayBDYW5jZWwgdG8gYnJpbmcgeW91IGJhY2sgdG8gdGhlIGludm9pY2UgZWRpdCBzY3JlbiwgdGhlbiBDYW5jZWwgYWdhaW4gdG8gZ28gYmFjayB0byB0aGUgSW52b2ljZXMgdGFiIG9uIHRoZSBjbGllbnQgc2NyZWVuLlxuXHRcdFx0Ly8gNy4gWW91IHdvbid0IGJlIGJhY2sgdGhlcmUuIFRoZSBDbGllbnQgc2NyZWVuIHdpbGwgYmUgbWlzc2luZy5cblx0XHRcdC8vaWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fZWRpdF9vbmx5X2NvbnRyb2xsZXIgKSB7XG5cdFx0XHQvL0xvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlci5vbkNhbmNlbENsaWNrKCk7XG5cdFx0XHQvL31cblxuXHRcdFx0Ly8gdHJhY2sgZWRpdCB2aWV3IG9ubHkgdmlld1xuXHRcdFx0R2xvYmFsLnRyYWNrVmlldyggdmlld19uYW1lICk7XG5cblx0XHRcdEdsb2JhbC5sb2FkVmlld1NvdXJjZSggdmlld19uYW1lLCB2aWV3X25hbWUgKyAnVmlld0NvbnRyb2xsZXIuanMnLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0LyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuXHRcdFx0XHR2aWV3X2NvbnRyb2xsZXIgPSBldmFsKCAnbmV3ICcgKyB2aWV3X25hbWUgKyAnVmlld0NvbnRyb2xsZXIoIHtlZGl0X29ubHlfbW9kZTogdHJ1ZX0gKTsgJyApO1xuXHRcdFx0XHQvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5cdFx0XHRcdFRUUHJvbWlzZS53YWl0KCAnQmFzZVZpZXdDb250cm9sbGVyJywgJ2luaXRpYWxpemUnLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHR2aWV3X2NvbnRyb2xsZXIucGFyZW50X3ZpZXdfY29udHJvbGxlciA9IHBhcmVudF92aWV3X2NvbnRyb2xsZXI7XG5cblx0XHRcdFx0XHR2aWV3X2NvbnRyb2xsZXJbYWN0aW9uX2Z1bmN0aW9uXSggaWQgKTtcblx0XHRcdFx0XHRpZiAoIFRUVVVJRC5pc1VVSUQoIGlkICkgKSB7XG5cdFx0XHRcdFx0XHR2YXIgY3VycmVudF91cmwgPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcblx0XHRcdFx0XHRcdGlmICggY3VycmVudF91cmwuaW5kZXhPZiggJyZzbScgKSA+IDAgKSB7XG5cdFx0XHRcdFx0XHRcdGN1cnJlbnRfdXJsID0gY3VycmVudF91cmwuc3Vic3RyaW5nKCAwLCBjdXJyZW50X3VybC5pbmRleE9mKCAnJnNtJyApICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZiAoIGlkICYmIF8uaXNTdHJpbmcoIGlkICkgKSB7XG5cdFx0XHRcdFx0XHRcdGN1cnJlbnRfdXJsID0gY3VycmVudF91cmwgKyAnJnNtPScgKyB2aWV3X25hbWUgKyAnJnNpZD0nICsgaWQ7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRjdXJyZW50X3VybCA9IGN1cnJlbnRfdXJsICsgJyZzbT0nICsgdmlld19uYW1lO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCBjdXJyZW50X3VybCApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlciA9IHZpZXdfY29udHJvbGxlcjtcblx0XHRcdFx0fSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblx0fVxuXG5cdHN0YXRpYyBpbml0aWFsaXplTm90aWZpY2F0aW9ucyggdGFyZ2V0ICkge1xuXHRcdE5vdGlmaWNhdGlvbkNvbnN1bWVyLnNldHVwVXNlciggdHJ1ZSwgZmFsc2UgKTtcblx0XHROb3RpZmljYXRpb25Db25zdW1lci5nZXRTeXN0ZW1Ob3RpZmljYXRpb25zKCB0YXJnZXQgKTtcblx0fVxuXG5cdHN0YXRpYyB0ZXN0SW50ZXJuZXRDb25uZWN0aW9uKCkge1xuXHRcdGlmICggIW5hdmlnYXRvci5vbkxpbmUgKSB7XG5cdFx0XHR3aW5kb3cuaW50ZXJuZXRfY29ubmVjdGlvbl9hdmFpbGFibGUgPSBmYWxzZTtcblx0XHRcdHdpbmRvdy5pc190ZXN0aW5nX2ludGVybmV0X2Nvbm5lY3Rpb24gPSBmYWxzZTtcblx0XHR9XG5cblx0XHR2YXIgaW1nID0gbmV3IEltYWdlKCk7XG5cdFx0d2luZG93LmlzX3Rlc3RpbmdfaW50ZXJuZXRfY29ubmVjdGlvbiA9IHRydWU7XG5cdFx0aW1nLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0d2luZG93LmludGVybmV0X2Nvbm5lY3Rpb25fYXZhaWxhYmxlID0gdHJ1ZTtcblx0XHRcdHdpbmRvdy5pc190ZXN0aW5nX2ludGVybmV0X2Nvbm5lY3Rpb24gPSBmYWxzZTtcblx0XHR9O1xuXHRcdGltZy5vbmVycm9yID0gZnVuY3Rpb24oIGUgKSB7XG5cdFx0XHR3aW5kb3cuaW50ZXJuZXRfY29ubmVjdGlvbl9hdmFpbGFibGUgPSBmYWxzZTtcblx0XHRcdHdpbmRvdy5pc190ZXN0aW5nX2ludGVybmV0X2Nvbm5lY3Rpb24gPSBmYWxzZTtcblx0XHR9O1xuXHRcdGltZy5zcmMgPSAnaHR0cHM6Ly93d3cudGltZXRyZXguY29tL2ltYWdlcy9waW5nLmdpZic7XG5cdH1cbn1cbkluZGV4Vmlld0NvbnRyb2xsZXIuaW5zdGFuY2UgPSBudWxsO1xuXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8678\n")},2237:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"Z\": () => (/* binding */ components_main_ui_router)\n});\n\n// EXTERNAL MODULE: ./node_modules/vue/dist/vue.esm-bundler.js + 6 modules\nvar vue_esm_bundler = __webpack_require__(5166);\n;// CONCATENATED MODULE: ./node_modules/vue-router/dist/vue-router.esm-bundler.js\n/*!\n * vue-router v4.0.12\n * (c) 2021 Eduardo San Martin Morote\n * @license MIT\n */\n\n\n\nconst hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';\r\nconst PolySymbol = (name) => \r\n// vr = vue router\r\nhasSymbol\r\n ? Symbol(( false) ? 0 : name)\r\n : (( false) ? 0 : '_vr_') + name;\r\n// rvlm = Router View Location Matched\r\n/**\r\n * RouteRecord being rendered by the closest ancestor Router View. Used for\r\n * `onBeforeRouteUpdate` and `onBeforeRouteLeave`. rvlm stands for Router View\r\n * Location Matched\r\n *\r\n * @internal\r\n */\r\nconst matchedRouteKey = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'rvlm');\r\n/**\r\n * Allows overriding the router view depth to control which component in\r\n * `matched` is rendered. rvd stands for Router View Depth\r\n *\r\n * @internal\r\n */\r\nconst viewDepthKey = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'rvd');\r\n/**\r\n * Allows overriding the router instance returned by `useRouter` in tests. r\r\n * stands for router\r\n *\r\n * @internal\r\n */\r\nconst routerKey = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'r');\r\n/**\r\n * Allows overriding the current route returned by `useRoute` in tests. rl\r\n * stands for route location\r\n *\r\n * @internal\r\n */\r\nconst routeLocationKey = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'rl');\r\n/**\r\n * Allows overriding the current route used by router-view. Internally this is\r\n * used when the `route` prop is passed.\r\n *\r\n * @internal\r\n */\r\nconst routerViewLocationKey = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'rvl');\n\nconst isBrowser = typeof window !== 'undefined';\n\nfunction isESModule(obj) {\r\n return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module');\r\n}\r\nconst vue_router_esm_bundler_assign = Object.assign;\r\nfunction applyToParams(fn, params) {\r\n const newParams = {};\r\n for (const key in params) {\r\n const value = params[key];\r\n newParams[key] = Array.isArray(value) ? value.map(fn) : fn(value);\r\n }\r\n return newParams;\r\n}\r\nconst noop = () => { };\n\nfunction warn(msg) {\r\n // avoid using ...args as it breaks in older Edge builds\r\n const args = Array.from(arguments).slice(1);\r\n console.warn.apply(console, ['[Vue Router warn]: ' + msg].concat(args));\r\n}\n\nconst TRAILING_SLASH_RE = /\\/$/;\r\nconst removeTrailingSlash = (path) => path.replace(TRAILING_SLASH_RE, '');\r\n/**\r\n * Transforms an URI into a normalized history location\r\n *\r\n * @param parseQuery\r\n * @param location - URI to normalize\r\n * @param currentLocation - current absolute location. Allows resolving relative\r\n * paths. Must start with `/`. Defaults to `/`\r\n * @returns a normalized history location\r\n */\r\nfunction parseURL(parseQuery, location, currentLocation = '/') {\r\n let path, query = {}, searchString = '', hash = '';\r\n // Could use URL and URLSearchParams but IE 11 doesn't support it\r\n const searchPos = location.indexOf('?');\r\n const hashPos = location.indexOf('#', searchPos > -1 ? searchPos : 0);\r\n if (searchPos > -1) {\r\n path = location.slice(0, searchPos);\r\n searchString = location.slice(searchPos + 1, hashPos > -1 ? hashPos : location.length);\r\n query = parseQuery(searchString);\r\n }\r\n if (hashPos > -1) {\r\n path = path || location.slice(0, hashPos);\r\n // keep the # character\r\n hash = location.slice(hashPos, location.length);\r\n }\r\n // no search and no query\r\n path = resolveRelativePath(path != null ? path : location, currentLocation);\r\n // empty path means a relative query or hash `?foo=f`, `#thing`\r\n return {\r\n fullPath: path + (searchString && '?') + searchString + hash,\r\n path,\r\n query,\r\n hash,\r\n };\r\n}\r\n/**\r\n * Stringifies a URL object\r\n *\r\n * @param stringifyQuery\r\n * @param location\r\n */\r\nfunction stringifyURL(stringifyQuery, location) {\r\n const query = location.query ? stringifyQuery(location.query) : '';\r\n return location.path + (query && '?') + query + (location.hash || '');\r\n}\r\n/**\r\n * Strips off the base from the beginning of a location.pathname in a non\r\n * case-sensitive way.\r\n *\r\n * @param pathname - location.pathname\r\n * @param base - base to strip off\r\n */\r\nfunction stripBase(pathname, base) {\r\n // no base or base is not found at the beginning\r\n if (!base || !pathname.toLowerCase().startsWith(base.toLowerCase()))\r\n return pathname;\r\n return pathname.slice(base.length) || '/';\r\n}\r\n/**\r\n * Checks if two RouteLocation are equal. This means that both locations are\r\n * pointing towards the same {@link RouteRecord} and that all `params`, `query`\r\n * parameters and `hash` are the same\r\n *\r\n * @param a - first {@link RouteLocation}\r\n * @param b - second {@link RouteLocation}\r\n */\r\nfunction isSameRouteLocation(stringifyQuery, a, b) {\r\n const aLastIndex = a.matched.length - 1;\r\n const bLastIndex = b.matched.length - 1;\r\n return (aLastIndex > -1 &&\r\n aLastIndex === bLastIndex &&\r\n isSameRouteRecord(a.matched[aLastIndex], b.matched[bLastIndex]) &&\r\n isSameRouteLocationParams(a.params, b.params) &&\r\n stringifyQuery(a.query) === stringifyQuery(b.query) &&\r\n a.hash === b.hash);\r\n}\r\n/**\r\n * Check if two `RouteRecords` are equal. Takes into account aliases: they are\r\n * considered equal to the `RouteRecord` they are aliasing.\r\n *\r\n * @param a - first {@link RouteRecord}\r\n * @param b - second {@link RouteRecord}\r\n */\r\nfunction isSameRouteRecord(a, b) {\r\n // since the original record has an undefined value for aliasOf\r\n // but all aliases point to the original record, this will always compare\r\n // the original record\r\n return (a.aliasOf || a) === (b.aliasOf || b);\r\n}\r\nfunction isSameRouteLocationParams(a, b) {\r\n if (Object.keys(a).length !== Object.keys(b).length)\r\n return false;\r\n for (const key in a) {\r\n if (!isSameRouteLocationParamsValue(a[key], b[key]))\r\n return false;\r\n }\r\n return true;\r\n}\r\nfunction isSameRouteLocationParamsValue(a, b) {\r\n return Array.isArray(a)\r\n ? isEquivalentArray(a, b)\r\n : Array.isArray(b)\r\n ? isEquivalentArray(b, a)\r\n : a === b;\r\n}\r\n/**\r\n * Check if two arrays are the same or if an array with one single entry is the\r\n * same as another primitive value. Used to check query and parameters\r\n *\r\n * @param a - array of values\r\n * @param b - array of values or a single value\r\n */\r\nfunction isEquivalentArray(a, b) {\r\n return Array.isArray(b)\r\n ? a.length === b.length && a.every((value, i) => value === b[i])\r\n : a.length === 1 && a[0] === b;\r\n}\r\n/**\r\n * Resolves a relative path that starts with `.`.\r\n *\r\n * @param to - path location we are resolving\r\n * @param from - currentLocation.path, should start with `/`\r\n */\r\nfunction resolveRelativePath(to, from) {\r\n if (to.startsWith('/'))\r\n return to;\r\n if (false) {}\r\n if (!to)\r\n return from;\r\n const fromSegments = from.split('/');\r\n const toSegments = to.split('/');\r\n let position = fromSegments.length - 1;\r\n let toPosition;\r\n let segment;\r\n for (toPosition = 0; toPosition < toSegments.length; toPosition++) {\r\n segment = toSegments[toPosition];\r\n // can't go below zero\r\n if (position === 1 || segment === '.')\r\n continue;\r\n if (segment === '..')\r\n position--;\r\n // found something that is not relative path\r\n else\r\n break;\r\n }\r\n return (fromSegments.slice(0, position).join('/') +\r\n '/' +\r\n toSegments\r\n .slice(toPosition - (toPosition === toSegments.length ? 1 : 0))\r\n .join('/'));\r\n}\n\nvar NavigationType;\r\n(function (NavigationType) {\r\n NavigationType[\"pop\"] = \"pop\";\r\n NavigationType[\"push\"] = \"push\";\r\n})(NavigationType || (NavigationType = {}));\r\nvar NavigationDirection;\r\n(function (NavigationDirection) {\r\n NavigationDirection[\"back\"] = \"back\";\r\n NavigationDirection[\"forward\"] = \"forward\";\r\n NavigationDirection[\"unknown\"] = \"\";\r\n})(NavigationDirection || (NavigationDirection = {}));\r\n/**\r\n * Starting location for Histories\r\n */\r\nconst START = '';\r\n// Generic utils\r\n/**\r\n * Normalizes a base by removing any trailing slash and reading the base tag if\r\n * present.\r\n *\r\n * @param base - base to normalize\r\n */\r\nfunction normalizeBase(base) {\r\n if (!base) {\r\n if (isBrowser) {\r\n // respect tag\r\n const baseEl = document.querySelector('base');\r\n base = (baseEl && baseEl.getAttribute('href')) || '/';\r\n // strip full URL origin\r\n base = base.replace(/^\\w+:\\/\\/[^\\/]+/, '');\r\n }\r\n else {\r\n base = '/';\r\n }\r\n }\r\n // ensure leading slash when it was removed by the regex above avoid leading\r\n // slash with hash because the file could be read from the disk like file://\r\n // and the leading slash would cause problems\r\n if (base[0] !== '/' && base[0] !== '#')\r\n base = '/' + base;\r\n // remove the trailing slash so all other method can just do `base + fullPath`\r\n // to build an href\r\n return removeTrailingSlash(base);\r\n}\r\n// remove any character before the hash\r\nconst BEFORE_HASH_RE = /^[^#]+#/;\r\nfunction createHref(base, location) {\r\n return base.replace(BEFORE_HASH_RE, '#') + location;\r\n}\n\nfunction getElementPosition(el, offset) {\r\n const docRect = document.documentElement.getBoundingClientRect();\r\n const elRect = el.getBoundingClientRect();\r\n return {\r\n behavior: offset.behavior,\r\n left: elRect.left - docRect.left - (offset.left || 0),\r\n top: elRect.top - docRect.top - (offset.top || 0),\r\n };\r\n}\r\nconst computeScrollPosition = () => ({\r\n left: window.pageXOffset,\r\n top: window.pageYOffset,\r\n});\r\nfunction scrollToPosition(position) {\r\n let scrollToOptions;\r\n if ('el' in position) {\r\n const positionEl = position.el;\r\n const isIdSelector = typeof positionEl === 'string' && positionEl.startsWith('#');\r\n /**\r\n * `id`s can accept pretty much any characters, including CSS combinators\r\n * like `>` or `~`. It's still possible to retrieve elements using\r\n * `document.getElementById('~')` but it needs to be escaped when using\r\n * `document.querySelector('#\\\\~')` for it to be valid. The only\r\n * requirements for `id`s are them to be unique on the page and to not be\r\n * empty (`id=\"\"`). Because of that, when passing an id selector, it should\r\n * be properly escaped for it to work with `querySelector`. We could check\r\n * for the id selector to be simple (no CSS combinators `+ >~`) but that\r\n * would make things inconsistent since they are valid characters for an\r\n * `id` but would need to be escaped when using `querySelector`, breaking\r\n * their usage and ending up in no selector returned. Selectors need to be\r\n * escaped:\r\n *\r\n * - `#1-thing` becomes `#\\31 -thing`\r\n * - `#with~symbols` becomes `#with\\\\~symbols`\r\n *\r\n * - More information about the topic can be found at\r\n * https://mathiasbynens.be/notes/html5-id-class.\r\n * - Practical example: https://mathiasbynens.be/demo/html5-id\r\n */\r\n if (false) {}\r\n const el = typeof positionEl === 'string'\r\n ? isIdSelector\r\n ? document.getElementById(positionEl.slice(1))\r\n : document.querySelector(positionEl)\r\n : positionEl;\r\n if (!el) {\r\n ( false) &&\r\n 0;\r\n return;\r\n }\r\n scrollToOptions = getElementPosition(el, position);\r\n }\r\n else {\r\n scrollToOptions = position;\r\n }\r\n if ('scrollBehavior' in document.documentElement.style)\r\n window.scrollTo(scrollToOptions);\r\n else {\r\n window.scrollTo(scrollToOptions.left != null ? scrollToOptions.left : window.pageXOffset, scrollToOptions.top != null ? scrollToOptions.top : window.pageYOffset);\r\n }\r\n}\r\nfunction getScrollKey(path, delta) {\r\n const position = history.state ? history.state.position - delta : -1;\r\n return position + path;\r\n}\r\nconst scrollPositions = new Map();\r\nfunction saveScrollPosition(key, scrollPosition) {\r\n scrollPositions.set(key, scrollPosition);\r\n}\r\nfunction getSavedScrollPosition(key) {\r\n const scroll = scrollPositions.get(key);\r\n // consume it so it's not used again\r\n scrollPositions.delete(key);\r\n return scroll;\r\n}\r\n// TODO: RFC about how to save scroll position\r\n/**\r\n * ScrollBehavior instance used by the router to compute and restore the scroll\r\n * position when navigating.\r\n */\r\n// export interface ScrollHandler {\r\n// // returns a scroll position that can be saved in history\r\n// compute(): ScrollPositionEntry\r\n// // can take an extended ScrollPositionEntry\r\n// scroll(position: ScrollPosition): void\r\n// }\r\n// export const scrollHandler: ScrollHandler = {\r\n// compute: computeScroll,\r\n// scroll: scrollToPosition,\r\n// }\n\nlet createBaseLocation = () => location.protocol + '//' + location.host;\r\n/**\r\n * Creates a normalized history location from a window.location object\r\n * @param location -\r\n */\r\nfunction createCurrentLocation(base, location) {\r\n const { pathname, search, hash } = location;\r\n // allows hash bases like #, /#, #/, #!, #!/, /#!/, or even /folder#end\r\n const hashPos = base.indexOf('#');\r\n if (hashPos > -1) {\r\n let slicePos = hash.includes(base.slice(hashPos))\r\n ? base.slice(hashPos).length\r\n : 1;\r\n let pathFromHash = hash.slice(slicePos);\r\n // prepend the starting slash to hash so the url starts with /#\r\n if (pathFromHash[0] !== '/')\r\n pathFromHash = '/' + pathFromHash;\r\n return stripBase(pathFromHash, '');\r\n }\r\n const path = stripBase(pathname, base);\r\n return path + search + hash;\r\n}\r\nfunction useHistoryListeners(base, historyState, currentLocation, replace) {\r\n let listeners = [];\r\n let teardowns = [];\r\n // TODO: should it be a stack? a Dict. Check if the popstate listener\r\n // can trigger twice\r\n let pauseState = null;\r\n const popStateHandler = ({ state, }) => {\r\n const to = createCurrentLocation(base, location);\r\n const from = currentLocation.value;\r\n const fromState = historyState.value;\r\n let delta = 0;\r\n if (state) {\r\n currentLocation.value = to;\r\n historyState.value = state;\r\n // ignore the popstate and reset the pauseState\r\n if (pauseState && pauseState === from) {\r\n pauseState = null;\r\n return;\r\n }\r\n delta = fromState ? state.position - fromState.position : 0;\r\n }\r\n else {\r\n replace(to);\r\n }\r\n // console.log({ deltaFromCurrent })\r\n // Here we could also revert the navigation by calling history.go(-delta)\r\n // this listener will have to be adapted to not trigger again and to wait for the url\r\n // to be updated before triggering the listeners. Some kind of validation function would also\r\n // need to be passed to the listeners so the navigation can be accepted\r\n // call all listeners\r\n listeners.forEach(listener => {\r\n listener(currentLocation.value, from, {\r\n delta,\r\n type: NavigationType.pop,\r\n direction: delta\r\n ? delta > 0\r\n ? NavigationDirection.forward\r\n : NavigationDirection.back\r\n : NavigationDirection.unknown,\r\n });\r\n });\r\n };\r\n function pauseListeners() {\r\n pauseState = currentLocation.value;\r\n }\r\n function listen(callback) {\r\n // setup the listener and prepare teardown callbacks\r\n listeners.push(callback);\r\n const teardown = () => {\r\n const index = listeners.indexOf(callback);\r\n if (index > -1)\r\n listeners.splice(index, 1);\r\n };\r\n teardowns.push(teardown);\r\n return teardown;\r\n }\r\n function beforeUnloadListener() {\r\n const { history } = window;\r\n if (!history.state)\r\n return;\r\n history.replaceState(vue_router_esm_bundler_assign({}, history.state, { scroll: computeScrollPosition() }), '');\r\n }\r\n function destroy() {\r\n for (const teardown of teardowns)\r\n teardown();\r\n teardowns = [];\r\n window.removeEventListener('popstate', popStateHandler);\r\n window.removeEventListener('beforeunload', beforeUnloadListener);\r\n }\r\n // setup the listeners and prepare teardown callbacks\r\n window.addEventListener('popstate', popStateHandler);\r\n window.addEventListener('beforeunload', beforeUnloadListener);\r\n return {\r\n pauseListeners,\r\n listen,\r\n destroy,\r\n };\r\n}\r\n/**\r\n * Creates a state object\r\n */\r\nfunction buildState(back, current, forward, replaced = false, computeScroll = false) {\r\n return {\r\n back,\r\n current,\r\n forward,\r\n replaced,\r\n position: window.history.length,\r\n scroll: computeScroll ? computeScrollPosition() : null,\r\n };\r\n}\r\nfunction useHistoryStateNavigation(base) {\r\n const { history, location } = window;\r\n // private variables\r\n const currentLocation = {\r\n value: createCurrentLocation(base, location),\r\n };\r\n const historyState = { value: history.state };\r\n // build current history entry as this is a fresh navigation\r\n if (!historyState.value) {\r\n changeLocation(currentLocation.value, {\r\n back: null,\r\n current: currentLocation.value,\r\n forward: null,\r\n // the length is off by one, we need to decrease it\r\n position: history.length - 1,\r\n replaced: true,\r\n // don't add a scroll as the user may have an anchor and we want\r\n // scrollBehavior to be triggered without a saved position\r\n scroll: null,\r\n }, true);\r\n }\r\n function changeLocation(to, state, replace) {\r\n /**\r\n * if a base tag is provided and we are on a normal domain, we have to\r\n * respect the provided `base` attribute because pushState() will use it and\r\n * potentially erase anything before the `#` like at\r\n * https://github.com/vuejs/vue-router-next/issues/685 where a base of\r\n * `/folder/#` but a base of `/` would erase the `/folder/` section. If\r\n * there is no host, the `` tag makes no sense and if there isn't a\r\n * base tag we can just use everything after the `#`.\r\n */\r\n const hashIndex = base.indexOf('#');\r\n const url = hashIndex > -1\r\n ? (location.host && document.querySelector('base')\r\n ? base\r\n : base.slice(hashIndex)) + to\r\n : createBaseLocation() + base + to;\r\n try {\r\n // BROWSER QUIRK\r\n // NOTE: Safari throws a SecurityError when calling this function 100 times in 30 seconds\r\n history[replace ? 'replaceState' : 'pushState'](state, '', url);\r\n historyState.value = state;\r\n }\r\n catch (err) {\r\n if ((false)) {}\r\n else {\r\n console.error(err);\r\n }\r\n // Force the navigation, this also resets the call count\r\n location[replace ? 'replace' : 'assign'](url);\r\n }\r\n }\r\n function replace(to, data) {\r\n const state = vue_router_esm_bundler_assign({}, history.state, buildState(historyState.value.back, \r\n // keep back and forward entries but override current position\r\n to, historyState.value.forward, true), data, { position: historyState.value.position });\r\n changeLocation(to, state, true);\r\n currentLocation.value = to;\r\n }\r\n function push(to, data) {\r\n // Add to current entry the information of where we are going\r\n // as well as saving the current position\r\n const currentState = vue_router_esm_bundler_assign({}, \r\n // use current history state to gracefully handle a wrong call to\r\n // history.replaceState\r\n // https://github.com/vuejs/vue-router-next/issues/366\r\n historyState.value, history.state, {\r\n forward: to,\r\n scroll: computeScrollPosition(),\r\n });\r\n if (false) {}\r\n changeLocation(currentState.current, currentState, true);\r\n const state = vue_router_esm_bundler_assign({}, buildState(currentLocation.value, to, null), { position: currentState.position + 1 }, data);\r\n changeLocation(to, state, false);\r\n currentLocation.value = to;\r\n }\r\n return {\r\n location: currentLocation,\r\n state: historyState,\r\n push,\r\n replace,\r\n };\r\n}\r\n/**\r\n * Creates an HTML5 history. Most common history for single page applications.\r\n *\r\n * @param base -\r\n */\r\nfunction createWebHistory(base) {\r\n base = normalizeBase(base);\r\n const historyNavigation = useHistoryStateNavigation(base);\r\n const historyListeners = useHistoryListeners(base, historyNavigation.state, historyNavigation.location, historyNavigation.replace);\r\n function go(delta, triggerListeners = true) {\r\n if (!triggerListeners)\r\n historyListeners.pauseListeners();\r\n history.go(delta);\r\n }\r\n const routerHistory = vue_router_esm_bundler_assign({\r\n // it's overridden right after\r\n location: '',\r\n base,\r\n go,\r\n createHref: createHref.bind(null, base),\r\n }, historyNavigation, historyListeners);\r\n Object.defineProperty(routerHistory, 'location', {\r\n enumerable: true,\r\n get: () => historyNavigation.location.value,\r\n });\r\n Object.defineProperty(routerHistory, 'state', {\r\n enumerable: true,\r\n get: () => historyNavigation.state.value,\r\n });\r\n return routerHistory;\r\n}\n\n/**\r\n * Creates a in-memory based history. The main purpose of this history is to handle SSR. It starts in a special location that is nowhere.\r\n * It's up to the user to replace that location with the starter location by either calling `router.push` or `router.replace`.\r\n *\r\n * @param base - Base applied to all urls, defaults to '/'\r\n * @returns a history object that can be passed to the router constructor\r\n */\r\nfunction createMemoryHistory(base = '') {\r\n let listeners = [];\r\n let queue = [START];\r\n let position = 0;\r\n base = normalizeBase(base);\r\n function setLocation(location) {\r\n position++;\r\n if (position === queue.length) {\r\n // we are at the end, we can simply append a new entry\r\n queue.push(location);\r\n }\r\n else {\r\n // we are in the middle, we remove everything from here in the queue\r\n queue.splice(position);\r\n queue.push(location);\r\n }\r\n }\r\n function triggerListeners(to, from, { direction, delta }) {\r\n const info = {\r\n direction,\r\n delta,\r\n type: NavigationType.pop,\r\n };\r\n for (const callback of listeners) {\r\n callback(to, from, info);\r\n }\r\n }\r\n const routerHistory = {\r\n // rewritten by Object.defineProperty\r\n location: START,\r\n // TODO: should be kept in queue\r\n state: {},\r\n base,\r\n createHref: createHref.bind(null, base),\r\n replace(to) {\r\n // remove current entry and decrement position\r\n queue.splice(position--, 1);\r\n setLocation(to);\r\n },\r\n push(to, data) {\r\n setLocation(to);\r\n },\r\n listen(callback) {\r\n listeners.push(callback);\r\n return () => {\r\n const index = listeners.indexOf(callback);\r\n if (index > -1)\r\n listeners.splice(index, 1);\r\n };\r\n },\r\n destroy() {\r\n listeners = [];\r\n queue = [START];\r\n position = 0;\r\n },\r\n go(delta, shouldTrigger = true) {\r\n const from = this.location;\r\n const direction = \r\n // we are considering delta === 0 going forward, but in abstract mode\r\n // using 0 for the delta doesn't make sense like it does in html5 where\r\n // it reloads the page\r\n delta < 0 ? NavigationDirection.back : NavigationDirection.forward;\r\n position = Math.max(0, Math.min(position + delta, queue.length - 1));\r\n if (shouldTrigger) {\r\n triggerListeners(this.location, from, {\r\n direction,\r\n delta,\r\n });\r\n }\r\n },\r\n };\r\n Object.defineProperty(routerHistory, 'location', {\r\n enumerable: true,\r\n get: () => queue[position],\r\n });\r\n return routerHistory;\r\n}\n\n/**\r\n * Creates a hash history. Useful for web applications with no host (e.g.\r\n * `file://`) or when configuring a server to handle any URL is not possible.\r\n *\r\n * @param base - optional base to provide. Defaults to `location.pathname +\r\n * location.search` If there is a `` tag in the `head`, its value will be\r\n * ignored in favor of this parameter **but note it affects all the\r\n * history.pushState() calls**, meaning that if you use a `` tag, it's\r\n * `href` value **has to match this parameter** (ignoring anything after the\r\n * `#`).\r\n *\r\n * @example\r\n * ```js\r\n * // at https://example.com/folder\r\n * createWebHashHistory() // gives a url of `https://example.com/folder#`\r\n * createWebHashHistory('/folder/') // gives a url of `https://example.com/folder/#`\r\n * // if the `#` is provided in the base, it won't be added by `createWebHashHistory`\r\n * createWebHashHistory('/folder/#/app/') // gives a url of `https://example.com/folder/#/app/`\r\n * // you should avoid doing this because it changes the original url and breaks copying urls\r\n * createWebHashHistory('/other-folder/') // gives a url of `https://example.com/other-folder/#`\r\n *\r\n * // at file:///usr/etc/folder/index.html\r\n * // for locations with no `host`, the base is ignored\r\n * createWebHashHistory('/iAmIgnored') // gives a url of `file:///usr/etc/folder/index.html#`\r\n * ```\r\n */\r\nfunction createWebHashHistory(base) {\r\n // Make sure this implementation is fine in terms of encoding, specially for IE11\r\n // for `file://`, directly use the pathname and ignore the base\r\n // location.pathname contains an initial `/` even at the root: `https://example.com`\r\n base = location.host ? base || location.pathname + location.search : '';\r\n // allow the user to provide a `#` in the middle: `/base/#/app`\r\n if (!base.includes('#'))\r\n base += '#';\r\n if (false) {}\r\n return createWebHistory(base);\r\n}\n\nfunction isRouteLocation(route) {\r\n return typeof route === 'string' || (route && typeof route === 'object');\r\n}\r\nfunction isRouteName(name) {\r\n return typeof name === 'string' || typeof name === 'symbol';\r\n}\n\n/**\r\n * Initial route location where the router is. Can be used in navigation guards\r\n * to differentiate the initial navigation.\r\n *\r\n * @example\r\n * ```js\r\n * import { START_LOCATION } from 'vue-router'\r\n *\r\n * router.beforeEach((to, from) => {\r\n * if (from === START_LOCATION) {\r\n * // initial navigation\r\n * }\r\n * })\r\n * ```\r\n */\r\nconst START_LOCATION_NORMALIZED = {\r\n path: '/',\r\n name: undefined,\r\n params: {},\r\n query: {},\r\n hash: '',\r\n fullPath: '/',\r\n matched: [],\r\n meta: {},\r\n redirectedFrom: undefined,\r\n};\n\nconst NavigationFailureSymbol = /*#__PURE__*/ PolySymbol(( false) ? 0 : 'nf');\r\n/**\r\n * Enumeration with all possible types for navigation failures. Can be passed to\r\n * {@link isNavigationFailure} to check for specific failures.\r\n */\r\nvar NavigationFailureType;\r\n(function (NavigationFailureType) {\r\n /**\r\n * An aborted navigation is a navigation that failed because a navigation\r\n * guard returned `false` or called `next(false)`\r\n */\r\n NavigationFailureType[NavigationFailureType[\"aborted\"] = 4] = \"aborted\";\r\n /**\r\n * A cancelled navigation is a navigation that failed because a more recent\r\n * navigation finished started (not necessarily finished).\r\n */\r\n NavigationFailureType[NavigationFailureType[\"cancelled\"] = 8] = \"cancelled\";\r\n /**\r\n * A duplicated navigation is a navigation that failed because it was\r\n * initiated while already being at the exact same location.\r\n */\r\n NavigationFailureType[NavigationFailureType[\"duplicated\"] = 16] = \"duplicated\";\r\n})(NavigationFailureType || (NavigationFailureType = {}));\r\n// DEV only debug messages\r\nconst ErrorTypeMessages = {\r\n [1 /* MATCHER_NOT_FOUND */]({ location, currentLocation }) {\r\n return `No match for\\n ${JSON.stringify(location)}${currentLocation\r\n ? '\\nwhile being at\\n' + JSON.stringify(currentLocation)\r\n : ''}`;\r\n },\r\n [2 /* NAVIGATION_GUARD_REDIRECT */]({ from, to, }) {\r\n return `Redirected from \"${from.fullPath}\" to \"${stringifyRoute(to)}\" via a navigation guard.`;\r\n },\r\n [4 /* NAVIGATION_ABORTED */]({ from, to }) {\r\n return `Navigation aborted from \"${from.fullPath}\" to \"${to.fullPath}\" via a navigation guard.`;\r\n },\r\n [8 /* NAVIGATION_CANCELLED */]({ from, to }) {\r\n return `Navigation cancelled from \"${from.fullPath}\" to \"${to.fullPath}\" with a new navigation.`;\r\n },\r\n [16 /* NAVIGATION_DUPLICATED */]({ from, to }) {\r\n return `Avoided redundant navigation to current location: \"${from.fullPath}\".`;\r\n },\r\n};\r\nfunction createRouterError(type, params) {\r\n // keep full error messages in cjs versions\r\n if (false) {}\r\n else {\r\n return vue_router_esm_bundler_assign(new Error(), {\r\n type,\r\n [NavigationFailureSymbol]: true,\r\n }, params);\r\n }\r\n}\r\nfunction isNavigationFailure(error, type) {\r\n return (error instanceof Error &&\r\n NavigationFailureSymbol in error &&\r\n (type == null || !!(error.type & type)));\r\n}\r\nconst propertiesToLog = ['params', 'query', 'hash'];\r\nfunction stringifyRoute(to) {\r\n if (typeof to === 'string')\r\n return to;\r\n if ('path' in to)\r\n return to.path;\r\n const location = {};\r\n for (const key of propertiesToLog) {\r\n if (key in to)\r\n location[key] = to[key];\r\n }\r\n return JSON.stringify(location, null, 2);\r\n}\n\n// default pattern for a param: non greedy everything but /\r\nconst BASE_PARAM_PATTERN = '[^/]+?';\r\nconst BASE_PATH_PARSER_OPTIONS = {\r\n sensitive: false,\r\n strict: false,\r\n start: true,\r\n end: true,\r\n};\r\n// Special Regex characters that must be escaped in static tokens\r\nconst REGEX_CHARS_RE = /[.+*?^${}()[\\]/\\\\]/g;\r\n/**\r\n * Creates a path parser from an array of Segments (a segment is an array of Tokens)\r\n *\r\n * @param segments - array of segments returned by tokenizePath\r\n * @param extraOptions - optional options for the regexp\r\n * @returns a PathParser\r\n */\r\nfunction tokensToParser(segments, extraOptions) {\r\n const options = vue_router_esm_bundler_assign({}, BASE_PATH_PARSER_OPTIONS, extraOptions);\r\n // the amount of scores is the same as the length of segments except for the root segment \"/\"\r\n const score = [];\r\n // the regexp as a string\r\n let pattern = options.start ? '^' : '';\r\n // extracted keys\r\n const keys = [];\r\n for (const segment of segments) {\r\n // the root segment needs special treatment\r\n const segmentScores = segment.length ? [] : [90 /* Root */];\r\n // allow trailing slash\r\n if (options.strict && !segment.length)\r\n pattern += '/';\r\n for (let tokenIndex = 0; tokenIndex < segment.length; tokenIndex++) {\r\n const token = segment[tokenIndex];\r\n // resets the score if we are inside a sub segment /:a-other-:b\r\n let subSegmentScore = 40 /* Segment */ +\r\n (options.sensitive ? 0.25 /* BonusCaseSensitive */ : 0);\r\n if (token.type === 0 /* Static */) {\r\n // prepend the slash if we are starting a new segment\r\n if (!tokenIndex)\r\n pattern += '/';\r\n pattern += token.value.replace(REGEX_CHARS_RE, '\\\\$&');\r\n subSegmentScore += 40 /* Static */;\r\n }\r\n else if (token.type === 1 /* Param */) {\r\n const { value, repeatable, optional, regexp } = token;\r\n keys.push({\r\n name: value,\r\n repeatable,\r\n optional,\r\n });\r\n const re = regexp ? regexp : BASE_PARAM_PATTERN;\r\n // the user provided a custom regexp /:id(\\\\d+)\r\n if (re !== BASE_PARAM_PATTERN) {\r\n subSegmentScore += 10 /* BonusCustomRegExp */;\r\n // make sure the regexp is valid before using it\r\n try {\r\n new RegExp(`(${re})`);\r\n }\r\n catch (err) {\r\n throw new Error(`Invalid custom RegExp for param \"${value}\" (${re}): ` +\r\n err.message);\r\n }\r\n }\r\n // when we repeat we must take care of the repeating leading slash\r\n let subPattern = repeatable ? `((?:${re})(?:/(?:${re}))*)` : `(${re})`;\r\n // prepend the slash if we are starting a new segment\r\n if (!tokenIndex)\r\n subPattern =\r\n // avoid an optional / if there are more segments e.g. /:p?-static\r\n // or /:p?-:p2\r\n optional && segment.length < 2\r\n ? `(?:/${subPattern})`\r\n : '/' + subPattern;\r\n if (optional)\r\n subPattern += '?';\r\n pattern += subPattern;\r\n subSegmentScore += 20 /* Dynamic */;\r\n if (optional)\r\n subSegmentScore += -8 /* BonusOptional */;\r\n if (repeatable)\r\n subSegmentScore += -20 /* BonusRepeatable */;\r\n if (re === '.*')\r\n subSegmentScore += -50 /* BonusWildcard */;\r\n }\r\n segmentScores.push(subSegmentScore);\r\n }\r\n // an empty array like /home/ -> [[{home}], []]\r\n // if (!segment.length) pattern += '/'\r\n score.push(segmentScores);\r\n }\r\n // only apply the strict bonus to the last score\r\n if (options.strict && options.end) {\r\n const i = score.length - 1;\r\n score[i][score[i].length - 1] += 0.7000000000000001 /* BonusStrict */;\r\n }\r\n // TODO: dev only warn double trailing slash\r\n if (!options.strict)\r\n pattern += '/?';\r\n if (options.end)\r\n pattern += '$';\r\n // allow paths like /dynamic to only match dynamic or dynamic/... but not dynamic_something_else\r\n else if (options.strict)\r\n pattern += '(?:/|$)';\r\n const re = new RegExp(pattern, options.sensitive ? '' : 'i');\r\n function parse(path) {\r\n const match = path.match(re);\r\n const params = {};\r\n if (!match)\r\n return null;\r\n for (let i = 1; i < match.length; i++) {\r\n const value = match[i] || '';\r\n const key = keys[i - 1];\r\n params[key.name] = value && key.repeatable ? value.split('/') : value;\r\n }\r\n return params;\r\n }\r\n function stringify(params) {\r\n let path = '';\r\n // for optional parameters to allow to be empty\r\n let avoidDuplicatedSlash = false;\r\n for (const segment of segments) {\r\n if (!avoidDuplicatedSlash || !path.endsWith('/'))\r\n path += '/';\r\n avoidDuplicatedSlash = false;\r\n for (const token of segment) {\r\n if (token.type === 0 /* Static */) {\r\n path += token.value;\r\n }\r\n else if (token.type === 1 /* Param */) {\r\n const { value, repeatable, optional } = token;\r\n const param = value in params ? params[value] : '';\r\n if (Array.isArray(param) && !repeatable)\r\n throw new Error(`Provided param \"${value}\" is an array but it is not repeatable (* or + modifiers)`);\r\n const text = Array.isArray(param) ? param.join('/') : param;\r\n if (!text) {\r\n if (optional) {\r\n // if we have more than one optional param like /:a?-static we\r\n // don't need to care about the optional param\r\n if (segment.length < 2) {\r\n // remove the last slash as we could be at the end\r\n if (path.endsWith('/'))\r\n path = path.slice(0, -1);\r\n // do not append a slash on the next iteration\r\n else\r\n avoidDuplicatedSlash = true;\r\n }\r\n }\r\n else\r\n throw new Error(`Missing required param \"${value}\"`);\r\n }\r\n path += text;\r\n }\r\n }\r\n }\r\n return path;\r\n }\r\n return {\r\n re,\r\n score,\r\n keys,\r\n parse,\r\n stringify,\r\n };\r\n}\r\n/**\r\n * Compares an array of numbers as used in PathParser.score and returns a\r\n * number. This function can be used to `sort` an array\r\n *\r\n * @param a - first array of numbers\r\n * @param b - second array of numbers\r\n * @returns 0 if both are equal, < 0 if a should be sorted first, > 0 if b\r\n * should be sorted first\r\n */\r\nfunction compareScoreArray(a, b) {\r\n let i = 0;\r\n while (i < a.length && i < b.length) {\r\n const diff = b[i] - a[i];\r\n // only keep going if diff === 0\r\n if (diff)\r\n return diff;\r\n i++;\r\n }\r\n // if the last subsegment was Static, the shorter segments should be sorted first\r\n // otherwise sort the longest segment first\r\n if (a.length < b.length) {\r\n return a.length === 1 && a[0] === 40 /* Static */ + 40 /* Segment */\r\n ? -1\r\n : 1;\r\n }\r\n else if (a.length > b.length) {\r\n return b.length === 1 && b[0] === 40 /* Static */ + 40 /* Segment */\r\n ? 1\r\n : -1;\r\n }\r\n return 0;\r\n}\r\n/**\r\n * Compare function that can be used with `sort` to sort an array of PathParser\r\n *\r\n * @param a - first PathParser\r\n * @param b - second PathParser\r\n * @returns 0 if both are equal, < 0 if a should be sorted first, > 0 if b\r\n */\r\nfunction comparePathParserScore(a, b) {\r\n let i = 0;\r\n const aScore = a.score;\r\n const bScore = b.score;\r\n while (i < aScore.length && i < bScore.length) {\r\n const comp = compareScoreArray(aScore[i], bScore[i]);\r\n // do not return if both are equal\r\n if (comp)\r\n return comp;\r\n i++;\r\n }\r\n // if a and b share the same score entries but b has more, sort b first\r\n return bScore.length - aScore.length;\r\n // this is the ternary version\r\n // return aScore.length < bScore.length\r\n // ? 1\r\n // : aScore.length > bScore.length\r\n // ? -1\r\n // : 0\r\n}\n\nconst ROOT_TOKEN = {\r\n type: 0 /* Static */,\r\n value: '',\r\n};\r\nconst VALID_PARAM_RE = /[a-zA-Z0-9_]/;\r\n// After some profiling, the cache seems to be unnecessary because tokenizePath\r\n// (the slowest part of adding a route) is very fast\r\n// const tokenCache = new Map()\r\nfunction tokenizePath(path) {\r\n if (!path)\r\n return [[]];\r\n if (path === '/')\r\n return [[ROOT_TOKEN]];\r\n if (!path.startsWith('/')) {\r\n throw new Error(( false)\r\n ? 0\r\n : `Invalid path \"${path}\"`);\r\n }\r\n // if (tokenCache.has(path)) return tokenCache.get(path)!\r\n function crash(message) {\r\n throw new Error(`ERR (${state})/\"${buffer}\": ${message}`);\r\n }\r\n let state = 0 /* Static */;\r\n let previousState = state;\r\n const tokens = [];\r\n // the segment will always be valid because we get into the initial state\r\n // with the leading /\r\n let segment;\r\n function finalizeSegment() {\r\n if (segment)\r\n tokens.push(segment);\r\n segment = [];\r\n }\r\n // index on the path\r\n let i = 0;\r\n // char at index\r\n let char;\r\n // buffer of the value read\r\n let buffer = '';\r\n // custom regexp for a param\r\n let customRe = '';\r\n function consumeBuffer() {\r\n if (!buffer)\r\n return;\r\n if (state === 0 /* Static */) {\r\n segment.push({\r\n type: 0 /* Static */,\r\n value: buffer,\r\n });\r\n }\r\n else if (state === 1 /* Param */ ||\r\n state === 2 /* ParamRegExp */ ||\r\n state === 3 /* ParamRegExpEnd */) {\r\n if (segment.length > 1 && (char === '*' || char === '+'))\r\n crash(`A repeatable param (${buffer}) must be alone in its segment. eg: '/:ids+.`);\r\n segment.push({\r\n type: 1 /* Param */,\r\n value: buffer,\r\n regexp: customRe,\r\n repeatable: char === '*' || char === '+',\r\n optional: char === '*' || char === '?',\r\n });\r\n }\r\n else {\r\n crash('Invalid state to consume buffer');\r\n }\r\n buffer = '';\r\n }\r\n function addCharToBuffer() {\r\n buffer += char;\r\n }\r\n while (i < path.length) {\r\n char = path[i++];\r\n if (char === '\\\\' && state !== 2 /* ParamRegExp */) {\r\n previousState = state;\r\n state = 4 /* EscapeNext */;\r\n continue;\r\n }\r\n switch (state) {\r\n case 0 /* Static */:\r\n if (char === '/') {\r\n if (buffer) {\r\n consumeBuffer();\r\n }\r\n finalizeSegment();\r\n }\r\n else if (char === ':') {\r\n consumeBuffer();\r\n state = 1 /* Param */;\r\n }\r\n else {\r\n addCharToBuffer();\r\n }\r\n break;\r\n case 4 /* EscapeNext */:\r\n addCharToBuffer();\r\n state = previousState;\r\n break;\r\n case 1 /* Param */:\r\n if (char === '(') {\r\n state = 2 /* ParamRegExp */;\r\n }\r\n else if (VALID_PARAM_RE.test(char)) {\r\n addCharToBuffer();\r\n }\r\n else {\r\n consumeBuffer();\r\n state = 0 /* Static */;\r\n // go back one character if we were not modifying\r\n if (char !== '*' && char !== '?' && char !== '+')\r\n i--;\r\n }\r\n break;\r\n case 2 /* ParamRegExp */:\r\n // TODO: is it worth handling nested regexp? like :p(?:prefix_([^/]+)_suffix)\r\n // it already works by escaping the closing )\r\n // https://paths.esm.dev/?p=AAMeJbiAwQEcDKbAoAAkP60PG2R6QAvgNaA6AFACM2ABuQBB#\r\n // is this really something people need since you can also write\r\n // /prefix_:p()_suffix\r\n if (char === ')') {\r\n // handle the escaped )\r\n if (customRe[customRe.length - 1] == '\\\\')\r\n customRe = customRe.slice(0, -1) + char;\r\n else\r\n state = 3 /* ParamRegExpEnd */;\r\n }\r\n else {\r\n customRe += char;\r\n }\r\n break;\r\n case 3 /* ParamRegExpEnd */:\r\n // same as finalizing a param\r\n consumeBuffer();\r\n state = 0 /* Static */;\r\n // go back one character if we were not modifying\r\n if (char !== '*' && char !== '?' && char !== '+')\r\n i--;\r\n customRe = '';\r\n break;\r\n default:\r\n crash('Unknown state');\r\n break;\r\n }\r\n }\r\n if (state === 2 /* ParamRegExp */)\r\n crash(`Unfinished custom RegExp for param \"${buffer}\"`);\r\n consumeBuffer();\r\n finalizeSegment();\r\n // tokenCache.set(path, tokens)\r\n return tokens;\r\n}\n\nfunction createRouteRecordMatcher(record, parent, options) {\r\n const parser = tokensToParser(tokenizePath(record.path), options);\r\n // warn against params with the same name\r\n if ((false)) {}\r\n const matcher = vue_router_esm_bundler_assign(parser, {\r\n record,\r\n parent,\r\n // these needs to be populated by the parent\r\n children: [],\r\n alias: [],\r\n });\r\n if (parent) {\r\n // both are aliases or both are not aliases\r\n // we don't want to mix them because the order is used when\r\n // passing originalRecord in Matcher.addRoute\r\n if (!matcher.record.aliasOf === !parent.record.aliasOf)\r\n parent.children.push(matcher);\r\n }\r\n return matcher;\r\n}\n\n/**\r\n * Creates a Router Matcher.\r\n *\r\n * @internal\r\n * @param routes - array of initial routes\r\n * @param globalOptions - global route options\r\n */\r\nfunction createRouterMatcher(routes, globalOptions) {\r\n // normalized ordered array of matchers\r\n const matchers = [];\r\n const matcherMap = new Map();\r\n globalOptions = mergeOptions({ strict: false, end: true, sensitive: false }, globalOptions);\r\n function getRecordMatcher(name) {\r\n return matcherMap.get(name);\r\n }\r\n function addRoute(record, parent, originalRecord) {\r\n // used later on to remove by name\r\n const isRootAdd = !originalRecord;\r\n const mainNormalizedRecord = normalizeRouteRecord(record);\r\n // we might be the child of an alias\r\n mainNormalizedRecord.aliasOf = originalRecord && originalRecord.record;\r\n const options = mergeOptions(globalOptions, record);\r\n // generate an array of records to correctly handle aliases\r\n const normalizedRecords = [\r\n mainNormalizedRecord,\r\n ];\r\n if ('alias' in record) {\r\n const aliases = typeof record.alias === 'string' ? [record.alias] : record.alias;\r\n for (const alias of aliases) {\r\n normalizedRecords.push(vue_router_esm_bundler_assign({}, mainNormalizedRecord, {\r\n // this allows us to hold a copy of the `components` option\r\n // so that async components cache is hold on the original record\r\n components: originalRecord\r\n ? originalRecord.record.components\r\n : mainNormalizedRecord.components,\r\n path: alias,\r\n // we might be the child of an alias\r\n aliasOf: originalRecord\r\n ? originalRecord.record\r\n : mainNormalizedRecord,\r\n // the aliases are always of the same kind as the original since they\r\n // are defined on the same record\r\n }));\r\n }\r\n }\r\n let matcher;\r\n let originalMatcher;\r\n for (const normalizedRecord of normalizedRecords) {\r\n const { path } = normalizedRecord;\r\n // Build up the path for nested routes if the child isn't an absolute\r\n // route. Only add the / delimiter if the child path isn't empty and if the\r\n // parent path doesn't have a trailing slash\r\n if (parent && path[0] !== '/') {\r\n const parentPath = parent.record.path;\r\n const connectingSlash = parentPath[parentPath.length - 1] === '/' ? '' : '/';\r\n normalizedRecord.path =\r\n parent.record.path + (path && connectingSlash + path);\r\n }\r\n if (false) {}\r\n // create the object before hand so it can be passed to children\r\n matcher = createRouteRecordMatcher(normalizedRecord, parent, options);\r\n if (false)\r\n {}\r\n // if we are an alias we must tell the original record that we exist\r\n // so we can be removed\r\n if (originalRecord) {\r\n originalRecord.alias.push(matcher);\r\n if ((false)) {}\r\n }\r\n else {\r\n // otherwise, the first record is the original and others are aliases\r\n originalMatcher = originalMatcher || matcher;\r\n if (originalMatcher !== matcher)\r\n originalMatcher.alias.push(matcher);\r\n // remove the route if named and only for the top record (avoid in nested calls)\r\n // this works because the original record is the first one\r\n if (isRootAdd && record.name && !isAliasRecord(matcher))\r\n removeRoute(record.name);\r\n }\r\n if ('children' in mainNormalizedRecord) {\r\n const children = mainNormalizedRecord.children;\r\n for (let i = 0; i < children.length; i++) {\r\n addRoute(children[i], matcher, originalRecord && originalRecord.children[i]);\r\n }\r\n }\r\n // if there was no original record, then the first one was not an alias and all\r\n // other alias (if any) need to reference this record when adding children\r\n originalRecord = originalRecord || matcher;\r\n // TODO: add normalized records for more flexibility\r\n // if (parent && isAliasRecord(originalRecord)) {\r\n // parent.children.push(originalRecord)\r\n // }\r\n insertMatcher(matcher);\r\n }\r\n return originalMatcher\r\n ? () => {\r\n // since other matchers are aliases, they should be removed by the original matcher\r\n removeRoute(originalMatcher);\r\n }\r\n : noop;\r\n }\r\n function removeRoute(matcherRef) {\r\n if (isRouteName(matcherRef)) {\r\n const matcher = matcherMap.get(matcherRef);\r\n if (matcher) {\r\n matcherMap.delete(matcherRef);\r\n matchers.splice(matchers.indexOf(matcher), 1);\r\n matcher.children.forEach(removeRoute);\r\n matcher.alias.forEach(removeRoute);\r\n }\r\n }\r\n else {\r\n const index = matchers.indexOf(matcherRef);\r\n if (index > -1) {\r\n matchers.splice(index, 1);\r\n if (matcherRef.record.name)\r\n matcherMap.delete(matcherRef.record.name);\r\n matcherRef.children.forEach(removeRoute);\r\n matcherRef.alias.forEach(removeRoute);\r\n }\r\n }\r\n }\r\n function getRoutes() {\r\n return matchers;\r\n }\r\n function insertMatcher(matcher) {\r\n let i = 0;\r\n // console.log('i is', { i })\r\n while (i < matchers.length &&\r\n comparePathParserScore(matcher, matchers[i]) >= 0)\r\n i++;\r\n // console.log('END i is', { i })\r\n // while (i < matchers.length && matcher.score <= matchers[i].score) i++\r\n matchers.splice(i, 0, matcher);\r\n // only add the original record to the name map\r\n if (matcher.record.name && !isAliasRecord(matcher))\r\n matcherMap.set(matcher.record.name, matcher);\r\n }\r\n function resolve(location, currentLocation) {\r\n let matcher;\r\n let params = {};\r\n let path;\r\n let name;\r\n if ('name' in location && location.name) {\r\n matcher = matcherMap.get(location.name);\r\n if (!matcher)\r\n throw createRouterError(1 /* MATCHER_NOT_FOUND */, {\r\n location,\r\n });\r\n name = matcher.record.name;\r\n params = vue_router_esm_bundler_assign(\r\n // paramsFromLocation is a new object\r\n paramsFromLocation(currentLocation.params, \r\n // only keep params that exist in the resolved location\r\n // TODO: only keep optional params coming from a parent record\r\n matcher.keys.filter(k => !k.optional).map(k => k.name)), location.params);\r\n // throws if cannot be stringified\r\n path = matcher.stringify(params);\r\n }\r\n else if ('path' in location) {\r\n // no need to resolve the path with the matcher as it was provided\r\n // this also allows the user to control the encoding\r\n path = location.path;\r\n if (false) {}\r\n matcher = matchers.find(m => m.re.test(path));\r\n // matcher should have a value after the loop\r\n if (matcher) {\r\n // TODO: dev warning of unused params if provided\r\n // we know the matcher works because we tested the regexp\r\n params = matcher.parse(path);\r\n name = matcher.record.name;\r\n }\r\n // location is a relative path\r\n }\r\n else {\r\n // match by name or path of current route\r\n matcher = currentLocation.name\r\n ? matcherMap.get(currentLocation.name)\r\n : matchers.find(m => m.re.test(currentLocation.path));\r\n if (!matcher)\r\n throw createRouterError(1 /* MATCHER_NOT_FOUND */, {\r\n location,\r\n currentLocation,\r\n });\r\n name = matcher.record.name;\r\n // since we are navigating to the same location, we don't need to pick the\r\n // params like when `name` is provided\r\n params = vue_router_esm_bundler_assign({}, currentLocation.params, location.params);\r\n path = matcher.stringify(params);\r\n }\r\n const matched = [];\r\n let parentMatcher = matcher;\r\n while (parentMatcher) {\r\n // reversed order so parents are at the beginning\r\n matched.unshift(parentMatcher.record);\r\n parentMatcher = parentMatcher.parent;\r\n }\r\n return {\r\n name,\r\n path,\r\n params,\r\n matched,\r\n meta: mergeMetaFields(matched),\r\n };\r\n }\r\n // add initial routes\r\n routes.forEach(route => addRoute(route));\r\n return { addRoute, resolve, removeRoute, getRoutes, getRecordMatcher };\r\n}\r\nfunction paramsFromLocation(params, keys) {\r\n const newParams = {};\r\n for (const key of keys) {\r\n if (key in params)\r\n newParams[key] = params[key];\r\n }\r\n return newParams;\r\n}\r\n/**\r\n * Normalizes a RouteRecordRaw. Creates a copy\r\n *\r\n * @param record\r\n * @returns the normalized version\r\n */\r\nfunction normalizeRouteRecord(record) {\r\n return {\r\n path: record.path,\r\n redirect: record.redirect,\r\n name: record.name,\r\n meta: record.meta || {},\r\n aliasOf: undefined,\r\n beforeEnter: record.beforeEnter,\r\n props: normalizeRecordProps(record),\r\n children: record.children || [],\r\n instances: {},\r\n leaveGuards: new Set(),\r\n updateGuards: new Set(),\r\n enterCallbacks: {},\r\n components: 'components' in record\r\n ? record.components || {}\r\n : { default: record.component },\r\n };\r\n}\r\n/**\r\n * Normalize the optional `props` in a record to always be an object similar to\r\n * components. Also accept a boolean for components.\r\n * @param record\r\n */\r\nfunction normalizeRecordProps(record) {\r\n const propsObject = {};\r\n // props does not exist on redirect records but we can set false directly\r\n const props = record.props || false;\r\n if ('component' in record) {\r\n propsObject.default = props;\r\n }\r\n else {\r\n // NOTE: we could also allow a function to be applied to every component.\r\n // Would need user feedback for use cases\r\n for (const name in record.components)\r\n propsObject[name] = typeof props === 'boolean' ? props : props[name];\r\n }\r\n return propsObject;\r\n}\r\n/**\r\n * Checks if a record or any of its parent is an alias\r\n * @param record\r\n */\r\nfunction isAliasRecord(record) {\r\n while (record) {\r\n if (record.record.aliasOf)\r\n return true;\r\n record = record.parent;\r\n }\r\n return false;\r\n}\r\n/**\r\n * Merge meta fields of an array of records\r\n *\r\n * @param matched - array of matched records\r\n */\r\nfunction mergeMetaFields(matched) {\r\n return matched.reduce((meta, record) => vue_router_esm_bundler_assign(meta, record.meta), {});\r\n}\r\nfunction mergeOptions(defaults, partialOptions) {\r\n const options = {};\r\n for (const key in defaults) {\r\n options[key] = key in partialOptions ? partialOptions[key] : defaults[key];\r\n }\r\n return options;\r\n}\r\nfunction isSameParam(a, b) {\r\n return (a.name === b.name &&\r\n a.optional === b.optional &&\r\n a.repeatable === b.repeatable);\r\n}\r\n/**\r\n * Check if a path and its alias have the same required params\r\n *\r\n * @param a - original record\r\n * @param b - alias record\r\n */\r\nfunction checkSameParams(a, b) {\r\n for (const key of a.keys) {\r\n if (!key.optional && !b.keys.find(isSameParam.bind(null, key)))\r\n return warn(`Alias \"${b.record.path}\" and the original record: \"${a.record.path}\" should have the exact same param named \"${key.name}\"`);\r\n }\r\n for (const key of b.keys) {\r\n if (!key.optional && !a.keys.find(isSameParam.bind(null, key)))\r\n return warn(`Alias \"${b.record.path}\" and the original record: \"${a.record.path}\" should have the exact same param named \"${key.name}\"`);\r\n }\r\n}\r\nfunction checkMissingParamsInAbsolutePath(record, parent) {\r\n for (const key of parent.keys) {\r\n if (!record.keys.find(isSameParam.bind(null, key)))\r\n return warn(`Absolute path \"${record.record.path}\" should have the exact same param named \"${key.name}\" as its parent \"${parent.record.path}\".`);\r\n }\r\n}\n\n/**\r\n * Encoding Rules ␣ = Space Path: ␣ \" < > # ? { } Query: ␣ \" < > # & = Hash: ␣ \"\r\n * < > `\r\n *\r\n * On top of that, the RFC3986 (https://tools.ietf.org/html/rfc3986#section-2.2)\r\n * defines some extra characters to be encoded. Most browsers do not encode them\r\n * in encodeURI https://github.com/whatwg/url/issues/369, so it may be safer to\r\n * also encode `!'()*`. Leaving unencoded only ASCII alphanumeric(`a-zA-Z0-9`)\r\n * plus `-._~`. This extra safety should be applied to query by patching the\r\n * string returned by encodeURIComponent encodeURI also encodes `[\\]^`. `\\`\r\n * should be encoded to avoid ambiguity. Browsers (IE, FF, C) transform a `\\`\r\n * into a `/` if directly typed in. The _backtick_ (`````) should also be\r\n * encoded everywhere because some browsers like FF encode it when directly\r\n * written while others don't. Safari and IE don't encode ``\"<>{}``` in hash.\r\n */\r\n// const EXTRA_RESERVED_RE = /[!'()*]/g\r\n// const encodeReservedReplacer = (c: string) => '%' + c.charCodeAt(0).toString(16)\r\nconst HASH_RE = /#/g; // %23\r\nconst AMPERSAND_RE = /&/g; // %26\r\nconst SLASH_RE = /\\//g; // %2F\r\nconst EQUAL_RE = /=/g; // %3D\r\nconst IM_RE = /\\?/g; // %3F\r\nconst PLUS_RE = /\\+/g; // %2B\r\n/**\r\n * NOTE: It's not clear to me if we should encode the + symbol in queries, it\r\n * seems to be less flexible than not doing so and I can't find out the legacy\r\n * systems requiring this for regular requests like text/html. In the standard,\r\n * the encoding of the plus character is only mentioned for\r\n * application/x-www-form-urlencoded\r\n * (https://url.spec.whatwg.org/#urlencoded-parsing) and most browsers seems lo\r\n * leave the plus character as is in queries. To be more flexible, we allow the\r\n * plus character on the query but it can also be manually encoded by the user.\r\n *\r\n * Resources:\r\n * - https://url.spec.whatwg.org/#urlencoded-parsing\r\n * - https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20\r\n */\r\nconst ENC_BRACKET_OPEN_RE = /%5B/g; // [\r\nconst ENC_BRACKET_CLOSE_RE = /%5D/g; // ]\r\nconst ENC_CARET_RE = /%5E/g; // ^\r\nconst ENC_BACKTICK_RE = /%60/g; // `\r\nconst ENC_CURLY_OPEN_RE = /%7B/g; // {\r\nconst ENC_PIPE_RE = /%7C/g; // |\r\nconst ENC_CURLY_CLOSE_RE = /%7D/g; // }\r\nconst ENC_SPACE_RE = /%20/g; // }\r\n/**\r\n * Encode characters that need to be encoded on the path, search and hash\r\n * sections of the URL.\r\n *\r\n * @internal\r\n * @param text - string to encode\r\n * @returns encoded string\r\n */\r\nfunction commonEncode(text) {\r\n return encodeURI('' + text)\r\n .replace(ENC_PIPE_RE, '|')\r\n .replace(ENC_BRACKET_OPEN_RE, '[')\r\n .replace(ENC_BRACKET_CLOSE_RE, ']');\r\n}\r\n/**\r\n * Encode characters that need to be encoded on the hash section of the URL.\r\n *\r\n * @param text - string to encode\r\n * @returns encoded string\r\n */\r\nfunction encodeHash(text) {\r\n return commonEncode(text)\r\n .replace(ENC_CURLY_OPEN_RE, '{')\r\n .replace(ENC_CURLY_CLOSE_RE, '}')\r\n .replace(ENC_CARET_RE, '^');\r\n}\r\n/**\r\n * Encode characters that need to be encoded query values on the query\r\n * section of the URL.\r\n *\r\n * @param text - string to encode\r\n * @returns encoded string\r\n */\r\nfunction encodeQueryValue(text) {\r\n return (commonEncode(text)\r\n // Encode the space as +, encode the + to differentiate it from the space\r\n .replace(PLUS_RE, '%2B')\r\n .replace(ENC_SPACE_RE, '+')\r\n .replace(HASH_RE, '%23')\r\n .replace(AMPERSAND_RE, '%26')\r\n .replace(ENC_BACKTICK_RE, '`')\r\n .replace(ENC_CURLY_OPEN_RE, '{')\r\n .replace(ENC_CURLY_CLOSE_RE, '}')\r\n .replace(ENC_CARET_RE, '^'));\r\n}\r\n/**\r\n * Like `encodeQueryValue` but also encodes the `=` character.\r\n *\r\n * @param text - string to encode\r\n */\r\nfunction encodeQueryKey(text) {\r\n return encodeQueryValue(text).replace(EQUAL_RE, '%3D');\r\n}\r\n/**\r\n * Encode characters that need to be encoded on the path section of the URL.\r\n *\r\n * @param text - string to encode\r\n * @returns encoded string\r\n */\r\nfunction encodePath(text) {\r\n return commonEncode(text).replace(HASH_RE, '%23').replace(IM_RE, '%3F');\r\n}\r\n/**\r\n * Encode characters that need to be encoded on the path section of the URL as a\r\n * param. This function encodes everything {@link encodePath} does plus the\r\n * slash (`/`) character. If `text` is `null` or `undefined`, returns an empty\r\n * string instead.\r\n *\r\n * @param text - string to encode\r\n * @returns encoded string\r\n */\r\nfunction encodeParam(text) {\r\n return text == null ? '' : encodePath(text).replace(SLASH_RE, '%2F');\r\n}\r\n/**\r\n * Decode text using `decodeURIComponent`. Returns the original text if it\r\n * fails.\r\n *\r\n * @param text - string to decode\r\n * @returns decoded string\r\n */\r\nfunction decode(text) {\r\n try {\r\n return decodeURIComponent('' + text);\r\n }\r\n catch (err) {\r\n ( false) && 0;\r\n }\r\n return '' + text;\r\n}\n\n/**\r\n * Transforms a queryString into a {@link LocationQuery} object. Accept both, a\r\n * version with the leading `?` and without Should work as URLSearchParams\r\n\n * @internal\r\n *\r\n * @param search - search string to parse\r\n * @returns a query object\r\n */\r\nfunction parseQuery(search) {\r\n const query = {};\r\n // avoid creating an object with an empty key and empty value\r\n // because of split('&')\r\n if (search === '' || search === '?')\r\n return query;\r\n const hasLeadingIM = search[0] === '?';\r\n const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&');\r\n for (let i = 0; i < searchParams.length; ++i) {\r\n // pre decode the + into space\r\n const searchParam = searchParams[i].replace(PLUS_RE, ' ');\r\n // allow the = character\r\n const eqPos = searchParam.indexOf('=');\r\n const key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos));\r\n const value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1));\r\n if (key in query) {\r\n // an extra variable for ts types\r\n let currentValue = query[key];\r\n if (!Array.isArray(currentValue)) {\r\n currentValue = query[key] = [currentValue];\r\n }\r\n currentValue.push(value);\r\n }\r\n else {\r\n query[key] = value;\r\n }\r\n }\r\n return query;\r\n}\r\n/**\r\n * Stringifies a {@link LocationQueryRaw} object. Like `URLSearchParams`, it\r\n * doesn't prepend a `?`\r\n *\r\n * @internal\r\n *\r\n * @param query - query object to stringify\r\n * @returns string version of the query without the leading `?`\r\n */\r\nfunction stringifyQuery(query) {\r\n let search = '';\r\n for (let key in query) {\r\n const value = query[key];\r\n key = encodeQueryKey(key);\r\n if (value == null) {\r\n // only null adds the value\r\n if (value !== undefined) {\r\n search += (search.length ? '&' : '') + key;\r\n }\r\n continue;\r\n }\r\n // keep null values\r\n const values = Array.isArray(value)\r\n ? value.map(v => v && encodeQueryValue(v))\r\n : [value && encodeQueryValue(value)];\r\n values.forEach(value => {\r\n // skip undefined values in arrays as if they were not present\r\n // smaller code than using filter\r\n if (value !== undefined) {\r\n // only append & with non-empty search\r\n search += (search.length ? '&' : '') + key;\r\n if (value != null)\r\n search += '=' + value;\r\n }\r\n });\r\n }\r\n return search;\r\n}\r\n/**\r\n * Transforms a {@link LocationQueryRaw} into a {@link LocationQuery} by casting\r\n * numbers into strings, removing keys with an undefined value and replacing\r\n * undefined with null in arrays\r\n *\r\n * @param query - query object to normalize\r\n * @returns a normalized query object\r\n */\r\nfunction normalizeQuery(query) {\r\n const normalizedQuery = {};\r\n for (const key in query) {\r\n const value = query[key];\r\n if (value !== undefined) {\r\n normalizedQuery[key] = Array.isArray(value)\r\n ? value.map(v => (v == null ? null : '' + v))\r\n : value == null\r\n ? value\r\n : '' + value;\r\n }\r\n }\r\n return normalizedQuery;\r\n}\n\n/**\r\n * Create a list of callbacks that can be reset. Used to create before and after navigation guards list\r\n */\r\nfunction useCallbacks() {\r\n let handlers = [];\r\n function add(handler) {\r\n handlers.push(handler);\r\n return () => {\r\n const i = handlers.indexOf(handler);\r\n if (i > -1)\r\n handlers.splice(i, 1);\r\n };\r\n }\r\n function reset() {\r\n handlers = [];\r\n }\r\n return {\r\n add,\r\n list: () => handlers,\r\n reset,\r\n };\r\n}\n\nfunction registerGuard(record, name, guard) {\r\n const removeFromList = () => {\r\n record[name].delete(guard);\r\n };\r\n onUnmounted(removeFromList);\r\n onDeactivated(removeFromList);\r\n onActivated(() => {\r\n record[name].add(guard);\r\n });\r\n record[name].add(guard);\r\n}\r\n/**\r\n * Add a navigation guard that triggers whenever the component for the current\r\n * location is about to be left. Similar to {@link beforeRouteLeave} but can be\r\n * used in any component. The guard is removed when the component is unmounted.\r\n *\r\n * @param leaveGuard - {@link NavigationGuard}\r\n */\r\nfunction onBeforeRouteLeave(leaveGuard) {\r\n if (false) {}\r\n const activeRecord = inject(matchedRouteKey, \r\n // to avoid warning\r\n {}).value;\r\n if (!activeRecord) {\r\n ( false) &&\r\n 0;\r\n return;\r\n }\r\n registerGuard(activeRecord, 'leaveGuards', leaveGuard);\r\n}\r\n/**\r\n * Add a navigation guard that triggers whenever the current location is about\r\n * to be updated. Similar to {@link beforeRouteUpdate} but can be used in any\r\n * component. The guard is removed when the component is unmounted.\r\n *\r\n * @param updateGuard - {@link NavigationGuard}\r\n */\r\nfunction onBeforeRouteUpdate(updateGuard) {\r\n if (false) {}\r\n const activeRecord = inject(matchedRouteKey, \r\n // to avoid warning\r\n {}).value;\r\n if (!activeRecord) {\r\n ( false) &&\r\n 0;\r\n return;\r\n }\r\n registerGuard(activeRecord, 'updateGuards', updateGuard);\r\n}\r\nfunction guardToPromiseFn(guard, to, from, record, name) {\r\n // keep a reference to the enterCallbackArray to prevent pushing callbacks if a new navigation took place\r\n const enterCallbackArray = record &&\r\n // name is defined if record is because of the function overload\r\n (record.enterCallbacks[name] = record.enterCallbacks[name] || []);\r\n return () => new Promise((resolve, reject) => {\r\n const next = (valid) => {\r\n if (valid === false)\r\n reject(createRouterError(4 /* NAVIGATION_ABORTED */, {\r\n from,\r\n to,\r\n }));\r\n else if (valid instanceof Error) {\r\n reject(valid);\r\n }\r\n else if (isRouteLocation(valid)) {\r\n reject(createRouterError(2 /* NAVIGATION_GUARD_REDIRECT */, {\r\n from: to,\r\n to: valid,\r\n }));\r\n }\r\n else {\r\n if (enterCallbackArray &&\r\n // since enterCallbackArray is truthy, both record and name also are\r\n record.enterCallbacks[name] === enterCallbackArray &&\r\n typeof valid === 'function')\r\n enterCallbackArray.push(valid);\r\n resolve();\r\n }\r\n };\r\n // wrapping with Promise.resolve allows it to work with both async and sync guards\r\n const guardReturn = guard.call(record && record.instances[name], to, from, ( false) ? 0 : next);\r\n let guardCall = Promise.resolve(guardReturn);\r\n if (guard.length < 3)\r\n guardCall = guardCall.then(next);\r\n if (false) {}\r\n guardCall.catch(err => reject(err));\r\n });\r\n}\r\nfunction canOnlyBeCalledOnce(next, to, from) {\r\n let called = 0;\r\n return function () {\r\n if (called++ === 1)\r\n warn(`The \"next\" callback was called more than once in one navigation guard when going from \"${from.fullPath}\" to \"${to.fullPath}\". It should be called exactly one time in each navigation guard. This will fail in production.`);\r\n // @ts-expect-error: we put it in the original one because it's easier to check\r\n next._called = true;\r\n if (called === 1)\r\n next.apply(null, arguments);\r\n };\r\n}\r\nfunction extractComponentsGuards(matched, guardType, to, from) {\r\n const guards = [];\r\n for (const record of matched) {\r\n for (const name in record.components) {\r\n let rawComponent = record.components[name];\r\n if ((false)) {}\r\n // skip update and leave guards if the route component is not mounted\r\n if (guardType !== 'beforeRouteEnter' && !record.instances[name])\r\n continue;\r\n if (isRouteComponent(rawComponent)) {\r\n // __vccOpts is added by vue-class-component and contain the regular options\r\n const options = rawComponent.__vccOpts || rawComponent;\r\n const guard = options[guardType];\r\n guard && guards.push(guardToPromiseFn(guard, to, from, record, name));\r\n }\r\n else {\r\n // start requesting the chunk already\r\n let componentPromise = rawComponent();\r\n if (false) {}\r\n guards.push(() => componentPromise.then(resolved => {\r\n if (!resolved)\r\n return Promise.reject(new Error(`Couldn't resolve component \"${name}\" at \"${record.path}\"`));\r\n const resolvedComponent = isESModule(resolved)\r\n ? resolved.default\r\n : resolved;\r\n // replace the function with the resolved component\r\n record.components[name] = resolvedComponent;\r\n // __vccOpts is added by vue-class-component and contain the regular options\r\n const options = resolvedComponent.__vccOpts || resolvedComponent;\r\n const guard = options[guardType];\r\n return guard && guardToPromiseFn(guard, to, from, record, name)();\r\n }));\r\n }\r\n }\r\n }\r\n return guards;\r\n}\r\n/**\r\n * Allows differentiating lazy components from functional components and vue-class-component\r\n *\r\n * @param component\r\n */\r\nfunction isRouteComponent(component) {\r\n return (typeof component === 'object' ||\r\n 'displayName' in component ||\r\n 'props' in component ||\r\n '__vccOpts' in component);\r\n}\n\n// TODO: we could allow currentRoute as a prop to expose `isActive` and\r\n// `isExactActive` behavior should go through an RFC\r\nfunction useLink(props) {\r\n const router = (0,vue_esm_bundler/* inject */.f3)(routerKey);\r\n const currentRoute = (0,vue_esm_bundler/* inject */.f3)(routeLocationKey);\r\n const route = (0,vue_esm_bundler/* computed */.Fl)(() => router.resolve((0,vue_esm_bundler/* unref */.SU)(props.to)));\r\n const activeRecordIndex = (0,vue_esm_bundler/* computed */.Fl)(() => {\r\n const { matched } = route.value;\r\n const { length } = matched;\r\n const routeMatched = matched[length - 1];\r\n const currentMatched = currentRoute.matched;\r\n if (!routeMatched || !currentMatched.length)\r\n return -1;\r\n const index = currentMatched.findIndex(isSameRouteRecord.bind(null, routeMatched));\r\n if (index > -1)\r\n return index;\r\n // possible parent record\r\n const parentRecordPath = getOriginalPath(matched[length - 2]);\r\n return (\r\n // we are dealing with nested routes\r\n length > 1 &&\r\n // if the parent and matched route have the same path, this link is\r\n // referring to the empty child. Or we currently are on a different\r\n // child of the same parent\r\n getOriginalPath(routeMatched) === parentRecordPath &&\r\n // avoid comparing the child with its parent\r\n currentMatched[currentMatched.length - 1].path !== parentRecordPath\r\n ? currentMatched.findIndex(isSameRouteRecord.bind(null, matched[length - 2]))\r\n : index);\r\n });\r\n const isActive = (0,vue_esm_bundler/* computed */.Fl)(() => activeRecordIndex.value > -1 &&\r\n includesParams(currentRoute.params, route.value.params));\r\n const isExactActive = (0,vue_esm_bundler/* computed */.Fl)(() => activeRecordIndex.value > -1 &&\r\n activeRecordIndex.value === currentRoute.matched.length - 1 &&\r\n isSameRouteLocationParams(currentRoute.params, route.value.params));\r\n function navigate(e = {}) {\r\n if (guardEvent(e)) {\r\n return router[(0,vue_esm_bundler/* unref */.SU)(props.replace) ? 'replace' : 'push']((0,vue_esm_bundler/* unref */.SU)(props.to)\r\n // avoid uncaught errors are they are logged anyway\r\n ).catch(noop);\r\n }\r\n return Promise.resolve();\r\n }\r\n // devtools only\r\n if (false) {}\r\n return {\r\n route,\r\n href: (0,vue_esm_bundler/* computed */.Fl)(() => route.value.href),\r\n isActive,\r\n isExactActive,\r\n navigate,\r\n };\r\n}\r\nconst RouterLinkImpl = /*#__PURE__*/ (0,vue_esm_bundler/* defineComponent */.aZ)({\r\n name: 'RouterLink',\r\n props: {\r\n to: {\r\n type: [String, Object],\r\n required: true,\r\n },\r\n replace: Boolean,\r\n activeClass: String,\r\n // inactiveClass: String,\r\n exactActiveClass: String,\r\n custom: Boolean,\r\n ariaCurrentValue: {\r\n type: String,\r\n default: 'page',\r\n },\r\n },\r\n useLink,\r\n setup(props, { slots }) {\r\n const link = (0,vue_esm_bundler/* reactive */.qj)(useLink(props));\r\n const { options } = (0,vue_esm_bundler/* inject */.f3)(routerKey);\r\n const elClass = (0,vue_esm_bundler/* computed */.Fl)(() => ({\r\n [getLinkClass(props.activeClass, options.linkActiveClass, 'router-link-active')]: link.isActive,\r\n // [getLinkClass(\r\n // props.inactiveClass,\r\n // options.linkInactiveClass,\r\n // 'router-link-inactive'\r\n // )]: !link.isExactActive,\r\n [getLinkClass(props.exactActiveClass, options.linkExactActiveClass, 'router-link-exact-active')]: link.isExactActive,\r\n }));\r\n return () => {\r\n const children = slots.default && slots.default(link);\r\n return props.custom\r\n ? children\r\n : (0,vue_esm_bundler.h)('a', {\r\n 'aria-current': link.isExactActive\r\n ? props.ariaCurrentValue\r\n : null,\r\n href: link.href,\r\n // this would override user added attrs but Vue will still add\r\n // the listener so we end up triggering both\r\n onClick: link.navigate,\r\n class: elClass.value,\r\n }, children);\r\n };\r\n },\r\n});\r\n// export the public type for h/tsx inference\r\n// also to avoid inline import() in generated d.ts files\r\n/**\r\n * Component to render a link that triggers a navigation on click.\r\n */\r\nconst RouterLink = RouterLinkImpl;\r\nfunction guardEvent(e) {\r\n // don't redirect with control keys\r\n if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\r\n return;\r\n // don't redirect when preventDefault called\r\n if (e.defaultPrevented)\r\n return;\r\n // don't redirect on right click\r\n if (e.button !== undefined && e.button !== 0)\r\n return;\r\n // don't redirect if `target=\"_blank\"`\r\n // @ts-expect-error getAttribute does exist\r\n if (e.currentTarget && e.currentTarget.getAttribute) {\r\n // @ts-expect-error getAttribute exists\r\n const target = e.currentTarget.getAttribute('target');\r\n if (/\\b_blank\\b/i.test(target))\r\n return;\r\n }\r\n // this may be a Weex event which doesn't have this method\r\n if (e.preventDefault)\r\n e.preventDefault();\r\n return true;\r\n}\r\nfunction includesParams(outer, inner) {\r\n for (const key in inner) {\r\n const innerValue = inner[key];\r\n const outerValue = outer[key];\r\n if (typeof innerValue === 'string') {\r\n if (innerValue !== outerValue)\r\n return false;\r\n }\r\n else {\r\n if (!Array.isArray(outerValue) ||\r\n outerValue.length !== innerValue.length ||\r\n innerValue.some((value, i) => value !== outerValue[i]))\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n/**\r\n * Get the original path value of a record by following its aliasOf\r\n * @param record\r\n */\r\nfunction getOriginalPath(record) {\r\n return record ? (record.aliasOf ? record.aliasOf.path : record.path) : '';\r\n}\r\n/**\r\n * Utility class to get the active class based on defaults.\r\n * @param propClass\r\n * @param globalClass\r\n * @param defaultClass\r\n */\r\nconst getLinkClass = (propClass, globalClass, defaultClass) => propClass != null\r\n ? propClass\r\n : globalClass != null\r\n ? globalClass\r\n : defaultClass;\n\nconst RouterViewImpl = /*#__PURE__*/ (0,vue_esm_bundler/* defineComponent */.aZ)({\r\n name: 'RouterView',\r\n // #674 we manually inherit them\r\n inheritAttrs: false,\r\n props: {\r\n name: {\r\n type: String,\r\n default: 'default',\r\n },\r\n route: Object,\r\n },\r\n setup(props, { attrs, slots }) {\r\n ( false) && 0;\r\n const injectedRoute = (0,vue_esm_bundler/* inject */.f3)(routerViewLocationKey);\r\n const routeToDisplay = (0,vue_esm_bundler/* computed */.Fl)(() => props.route || injectedRoute.value);\r\n const depth = (0,vue_esm_bundler/* inject */.f3)(viewDepthKey, 0);\r\n const matchedRouteRef = (0,vue_esm_bundler/* computed */.Fl)(() => routeToDisplay.value.matched[depth]);\r\n (0,vue_esm_bundler/* provide */.JJ)(viewDepthKey, depth + 1);\r\n (0,vue_esm_bundler/* provide */.JJ)(matchedRouteKey, matchedRouteRef);\r\n (0,vue_esm_bundler/* provide */.JJ)(routerViewLocationKey, routeToDisplay);\r\n const viewRef = (0,vue_esm_bundler/* ref */.iH)();\r\n // watch at the same time the component instance, the route record we are\r\n // rendering, and the name\r\n (0,vue_esm_bundler/* watch */.YP)(() => [viewRef.value, matchedRouteRef.value, props.name], ([instance, to, name], [oldInstance, from, oldName]) => {\r\n // copy reused instances\r\n if (to) {\r\n // this will update the instance for new instances as well as reused\r\n // instances when navigating to a new route\r\n to.instances[name] = instance;\r\n // the component instance is reused for a different route or name so\r\n // we copy any saved update or leave guards. With async setup, the\r\n // mounting component will mount before the matchedRoute changes,\r\n // making instance === oldInstance, so we check if guards have been\r\n // added before. This works because we remove guards when\r\n // unmounting/deactivating components\r\n if (from && from !== to && instance && instance === oldInstance) {\r\n if (!to.leaveGuards.size) {\r\n to.leaveGuards = from.leaveGuards;\r\n }\r\n if (!to.updateGuards.size) {\r\n to.updateGuards = from.updateGuards;\r\n }\r\n }\r\n }\r\n // trigger beforeRouteEnter next callbacks\r\n if (instance &&\r\n to &&\r\n // if there is no instance but to and from are the same this might be\r\n // the first visit\r\n (!from || !isSameRouteRecord(to, from) || !oldInstance)) {\r\n (to.enterCallbacks[name] || []).forEach(callback => callback(instance));\r\n }\r\n }, { flush: 'post' });\r\n return () => {\r\n const route = routeToDisplay.value;\r\n const matchedRoute = matchedRouteRef.value;\r\n const ViewComponent = matchedRoute && matchedRoute.components[props.name];\r\n // we need the value at the time we render because when we unmount, we\r\n // navigated to a different location so the value is different\r\n const currentName = props.name;\r\n if (!ViewComponent) {\r\n return normalizeSlot(slots.default, { Component: ViewComponent, route });\r\n }\r\n // props from route configuration\r\n const routePropsOption = matchedRoute.props[props.name];\r\n const routeProps = routePropsOption\r\n ? routePropsOption === true\r\n ? route.params\r\n : typeof routePropsOption === 'function'\r\n ? routePropsOption(route)\r\n : routePropsOption\r\n : null;\r\n const onVnodeUnmounted = vnode => {\r\n // remove the instance reference to prevent leak\r\n if (vnode.component.isUnmounted) {\r\n matchedRoute.instances[currentName] = null;\r\n }\r\n };\r\n const component = (0,vue_esm_bundler.h)(ViewComponent, vue_router_esm_bundler_assign({}, routeProps, attrs, {\r\n onVnodeUnmounted,\r\n ref: viewRef,\r\n }));\r\n if (false) {}\r\n return (\r\n // pass the vnode to the slot as a prop.\r\n // h and both accept vnodes\r\n normalizeSlot(slots.default, { Component: component, route }) ||\r\n component);\r\n };\r\n },\r\n});\r\nfunction normalizeSlot(slot, data) {\r\n if (!slot)\r\n return null;\r\n const slotContent = slot(data);\r\n return slotContent.length === 1 ? slotContent[0] : slotContent;\r\n}\r\n// export the public type for h/tsx inference\r\n// also to avoid inline import() in generated d.ts files\r\n/**\r\n * Component to display the current route the user is at.\r\n */\r\nconst RouterView = RouterViewImpl;\r\n// warn against deprecated usage with & \r\n// due to functional component being no longer eager in Vue 3\r\nfunction warnDeprecatedUsage() {\r\n const instance = getCurrentInstance();\r\n const parentName = instance.parent && instance.parent.type.name;\r\n if (parentName &&\r\n (parentName === 'KeepAlive' || parentName.includes('Transition'))) {\r\n const comp = parentName === 'KeepAlive' ? 'keep-alive' : 'transition';\r\n warn(` can no longer be used directly inside or .\\n` +\r\n `Use slot props instead:\\n\\n` +\r\n `\\n` +\r\n ` <${comp}>\\n` +\r\n ` \\n` +\r\n ` \\n` +\r\n ``);\r\n }\r\n}\n\nfunction formatRouteLocation(routeLocation, tooltip) {\r\n const copy = vue_router_esm_bundler_assign({}, routeLocation, {\r\n // remove variables that can contain vue instances\r\n matched: routeLocation.matched.map(matched => omit(matched, ['instances', 'children', 'aliasOf'])),\r\n });\r\n return {\r\n _custom: {\r\n type: null,\r\n readOnly: true,\r\n display: routeLocation.fullPath,\r\n tooltip,\r\n value: copy,\r\n },\r\n };\r\n}\r\nfunction formatDisplay(display) {\r\n return {\r\n _custom: {\r\n display,\r\n },\r\n };\r\n}\r\n// to support multiple router instances\r\nlet routerId = 0;\r\nfunction addDevtools(app, router, matcher) {\r\n // Take over router.beforeEach and afterEach\r\n // make sure we are not registering the devtool twice\r\n if (router.__hasDevtools)\r\n return;\r\n router.__hasDevtools = true;\r\n // increment to support multiple router instances\r\n const id = routerId++;\r\n setupDevtoolsPlugin({\r\n id: 'org.vuejs.router' + (id ? '.' + id : ''),\r\n label: 'Vue Router',\r\n packageName: 'vue-router',\r\n homepage: 'https://next.router.vuejs.org/',\r\n logo: 'https://vuejs.org/images/icons/favicon-96x96.png',\r\n componentStateTypes: ['Routing'],\r\n app,\r\n }, api => {\r\n // display state added by the router\r\n api.on.inspectComponent((payload, ctx) => {\r\n if (payload.instanceData) {\r\n payload.instanceData.state.push({\r\n type: 'Routing',\r\n key: '$route',\r\n editable: false,\r\n value: formatRouteLocation(router.currentRoute.value, 'Current Route'),\r\n });\r\n }\r\n });\r\n // mark router-link as active and display tags on router views\r\n api.on.visitComponentTree(({ treeNode: node, componentInstance }) => {\r\n if (componentInstance.__vrv_devtools) {\r\n const info = componentInstance.__vrv_devtools;\r\n node.tags.push({\r\n label: (info.name ? `${info.name.toString()}: ` : '') + info.path,\r\n textColor: 0,\r\n tooltip: 'This component is rendered by <router-view>',\r\n backgroundColor: PINK_500,\r\n });\r\n }\r\n // if multiple useLink are used\r\n if (Array.isArray(componentInstance.__vrl_devtools)) {\r\n componentInstance.__devtoolsApi = api;\r\n componentInstance.__vrl_devtools.forEach(devtoolsData => {\r\n let backgroundColor = ORANGE_400;\r\n let tooltip = '';\r\n if (devtoolsData.isExactActive) {\r\n backgroundColor = LIME_500;\r\n tooltip = 'This is exactly active';\r\n }\r\n else if (devtoolsData.isActive) {\r\n backgroundColor = BLUE_600;\r\n tooltip = 'This link is active';\r\n }\r\n node.tags.push({\r\n label: devtoolsData.route.path,\r\n textColor: 0,\r\n tooltip,\r\n backgroundColor,\r\n });\r\n });\r\n }\r\n });\r\n watch(router.currentRoute, () => {\r\n // refresh active state\r\n refreshRoutesView();\r\n api.notifyComponentUpdate();\r\n api.sendInspectorTree(routerInspectorId);\r\n api.sendInspectorState(routerInspectorId);\r\n });\r\n const navigationsLayerId = 'router:navigations:' + id;\r\n api.addTimelineLayer({\r\n id: navigationsLayerId,\r\n label: `Router${id ? ' ' + id : ''} Navigations`,\r\n color: 0x40a8c4,\r\n });\r\n // const errorsLayerId = 'router:errors'\r\n // api.addTimelineLayer({\r\n // id: errorsLayerId,\r\n // label: 'Router Errors',\r\n // color: 0xea5455,\r\n // })\r\n router.onError((error, to) => {\r\n api.addTimelineEvent({\r\n layerId: navigationsLayerId,\r\n event: {\r\n title: 'Error during Navigation',\r\n subtitle: to.fullPath,\r\n logType: 'error',\r\n time: Date.now(),\r\n data: { error },\r\n groupId: to.meta.__navigationId,\r\n },\r\n });\r\n });\r\n // attached to `meta` and used to group events\r\n let navigationId = 0;\r\n router.beforeEach((to, from) => {\r\n const data = {\r\n guard: formatDisplay('beforeEach'),\r\n from: formatRouteLocation(from, 'Current Location during this navigation'),\r\n to: formatRouteLocation(to, 'Target location'),\r\n };\r\n // Used to group navigations together, hide from devtools\r\n Object.defineProperty(to.meta, '__navigationId', {\r\n value: navigationId++,\r\n });\r\n api.addTimelineEvent({\r\n layerId: navigationsLayerId,\r\n event: {\r\n time: Date.now(),\r\n title: 'Start of navigation',\r\n subtitle: to.fullPath,\r\n data,\r\n groupId: to.meta.__navigationId,\r\n },\r\n });\r\n });\r\n router.afterEach((to, from, failure) => {\r\n const data = {\r\n guard: formatDisplay('afterEach'),\r\n };\r\n if (failure) {\r\n data.failure = {\r\n _custom: {\r\n type: Error,\r\n readOnly: true,\r\n display: failure ? failure.message : '',\r\n tooltip: 'Navigation Failure',\r\n value: failure,\r\n },\r\n };\r\n data.status = formatDisplay('❌');\r\n }\r\n else {\r\n data.status = formatDisplay('✅');\r\n }\r\n // we set here to have the right order\r\n data.from = formatRouteLocation(from, 'Current Location during this navigation');\r\n data.to = formatRouteLocation(to, 'Target location');\r\n api.addTimelineEvent({\r\n layerId: navigationsLayerId,\r\n event: {\r\n title: 'End of navigation',\r\n subtitle: to.fullPath,\r\n time: Date.now(),\r\n data,\r\n logType: failure ? 'warning' : 'default',\r\n groupId: to.meta.__navigationId,\r\n },\r\n });\r\n });\r\n /**\r\n * Inspector of Existing routes\r\n */\r\n const routerInspectorId = 'router-inspector:' + id;\r\n api.addInspector({\r\n id: routerInspectorId,\r\n label: 'Routes' + (id ? ' ' + id : ''),\r\n icon: 'book',\r\n treeFilterPlaceholder: 'Search routes',\r\n });\r\n function refreshRoutesView() {\r\n // the routes view isn't active\r\n if (!activeRoutesPayload)\r\n return;\r\n const payload = activeRoutesPayload;\r\n // children routes will appear as nested\r\n let routes = matcher.getRoutes().filter(route => !route.parent);\r\n // reset match state to false\r\n routes.forEach(resetMatchStateOnRouteRecord);\r\n // apply a match state if there is a payload\r\n if (payload.filter) {\r\n routes = routes.filter(route => \r\n // save matches state based on the payload\r\n isRouteMatching(route, payload.filter.toLowerCase()));\r\n }\r\n // mark active routes\r\n routes.forEach(route => markRouteRecordActive(route, router.currentRoute.value));\r\n payload.rootNodes = routes.map(formatRouteRecordForInspector);\r\n }\r\n let activeRoutesPayload;\r\n api.on.getInspectorTree(payload => {\r\n activeRoutesPayload = payload;\r\n if (payload.app === app && payload.inspectorId === routerInspectorId) {\r\n refreshRoutesView();\r\n }\r\n });\r\n /**\r\n * Display information about the currently selected route record\r\n */\r\n api.on.getInspectorState(payload => {\r\n if (payload.app === app && payload.inspectorId === routerInspectorId) {\r\n const routes = matcher.getRoutes();\r\n const route = routes.find(route => route.record.__vd_id === payload.nodeId);\r\n if (route) {\r\n payload.state = {\r\n options: formatRouteRecordMatcherForStateInspector(route),\r\n };\r\n }\r\n }\r\n });\r\n api.sendInspectorTree(routerInspectorId);\r\n api.sendInspectorState(routerInspectorId);\r\n });\r\n}\r\nfunction modifierForKey(key) {\r\n if (key.optional) {\r\n return key.repeatable ? '*' : '?';\r\n }\r\n else {\r\n return key.repeatable ? '+' : '';\r\n }\r\n}\r\nfunction formatRouteRecordMatcherForStateInspector(route) {\r\n const { record } = route;\r\n const fields = [\r\n { editable: false, key: 'path', value: record.path },\r\n ];\r\n if (record.name != null) {\r\n fields.push({\r\n editable: false,\r\n key: 'name',\r\n value: record.name,\r\n });\r\n }\r\n fields.push({ editable: false, key: 'regexp', value: route.re });\r\n if (route.keys.length) {\r\n fields.push({\r\n editable: false,\r\n key: 'keys',\r\n value: {\r\n _custom: {\r\n type: null,\r\n readOnly: true,\r\n display: route.keys\r\n .map(key => `${key.name}${modifierForKey(key)}`)\r\n .join(' '),\r\n tooltip: 'Param keys',\r\n value: route.keys,\r\n },\r\n },\r\n });\r\n }\r\n if (record.redirect != null) {\r\n fields.push({\r\n editable: false,\r\n key: 'redirect',\r\n value: record.redirect,\r\n });\r\n }\r\n if (route.alias.length) {\r\n fields.push({\r\n editable: false,\r\n key: 'aliases',\r\n value: route.alias.map(alias => alias.record.path),\r\n });\r\n }\r\n fields.push({\r\n key: 'score',\r\n editable: false,\r\n value: {\r\n _custom: {\r\n type: null,\r\n readOnly: true,\r\n display: route.score.map(score => score.join(', ')).join(' | '),\r\n tooltip: 'Score used to sort routes',\r\n value: route.score,\r\n },\r\n },\r\n });\r\n return fields;\r\n}\r\n/**\r\n * Extracted from tailwind palette\r\n */\r\nconst PINK_500 = 0xec4899;\r\nconst BLUE_600 = 0x2563eb;\r\nconst LIME_500 = 0x84cc16;\r\nconst CYAN_400 = 0x22d3ee;\r\nconst ORANGE_400 = 0xfb923c;\r\n// const GRAY_100 = 0xf4f4f5\r\nconst DARK = 0x666666;\r\nfunction formatRouteRecordForInspector(route) {\r\n const tags = [];\r\n const { record } = route;\r\n if (record.name != null) {\r\n tags.push({\r\n label: String(record.name),\r\n textColor: 0,\r\n backgroundColor: CYAN_400,\r\n });\r\n }\r\n if (record.aliasOf) {\r\n tags.push({\r\n label: 'alias',\r\n textColor: 0,\r\n backgroundColor: ORANGE_400,\r\n });\r\n }\r\n if (route.__vd_match) {\r\n tags.push({\r\n label: 'matches',\r\n textColor: 0,\r\n backgroundColor: PINK_500,\r\n });\r\n }\r\n if (route.__vd_exactActive) {\r\n tags.push({\r\n label: 'exact',\r\n textColor: 0,\r\n backgroundColor: LIME_500,\r\n });\r\n }\r\n if (route.__vd_active) {\r\n tags.push({\r\n label: 'active',\r\n textColor: 0,\r\n backgroundColor: BLUE_600,\r\n });\r\n }\r\n if (record.redirect) {\r\n tags.push({\r\n label: 'redirect: ' +\r\n (typeof record.redirect === 'string' ? record.redirect : 'Object'),\r\n textColor: 0xffffff,\r\n backgroundColor: DARK,\r\n });\r\n }\r\n // add an id to be able to select it. Using the `path` is not possible because\r\n // empty path children would collide with their parents\r\n let id = record.__vd_id;\r\n if (id == null) {\r\n id = String(routeRecordId++);\r\n record.__vd_id = id;\r\n }\r\n return {\r\n id,\r\n label: record.path,\r\n tags,\r\n children: route.children.map(formatRouteRecordForInspector),\r\n };\r\n}\r\n// incremental id for route records and inspector state\r\nlet routeRecordId = 0;\r\nconst EXTRACT_REGEXP_RE = /^\\/(.*)\\/([a-z]*)$/;\r\nfunction markRouteRecordActive(route, currentRoute) {\r\n // no route will be active if matched is empty\r\n // reset the matching state\r\n const isExactActive = currentRoute.matched.length &&\r\n isSameRouteRecord(currentRoute.matched[currentRoute.matched.length - 1], route.record);\r\n route.__vd_exactActive = route.__vd_active = isExactActive;\r\n if (!isExactActive) {\r\n route.__vd_active = currentRoute.matched.some(match => isSameRouteRecord(match, route.record));\r\n }\r\n route.children.forEach(childRoute => markRouteRecordActive(childRoute, currentRoute));\r\n}\r\nfunction resetMatchStateOnRouteRecord(route) {\r\n route.__vd_match = false;\r\n route.children.forEach(resetMatchStateOnRouteRecord);\r\n}\r\nfunction isRouteMatching(route, filter) {\r\n const found = String(route.re).match(EXTRACT_REGEXP_RE);\r\n route.__vd_match = false;\r\n if (!found || found.length < 3) {\r\n return false;\r\n }\r\n // use a regexp without $ at the end to match nested routes better\r\n const nonEndingRE = new RegExp(found[1].replace(/\\$$/, ''), found[2]);\r\n if (nonEndingRE.test(filter)) {\r\n // mark children as matches\r\n route.children.forEach(child => isRouteMatching(child, filter));\r\n // exception case: `/`\r\n if (route.record.path !== '/' || filter === '/') {\r\n route.__vd_match = route.re.test(filter);\r\n return true;\r\n }\r\n // hide the / route\r\n return false;\r\n }\r\n const path = route.record.path.toLowerCase();\r\n const decodedPath = decode(path);\r\n // also allow partial matching on the path\r\n if (!filter.startsWith('/') &&\r\n (decodedPath.includes(filter) || path.includes(filter)))\r\n return true;\r\n if (decodedPath.startsWith(filter) || path.startsWith(filter))\r\n return true;\r\n if (route.record.name && String(route.record.name).includes(filter))\r\n return true;\r\n return route.children.some(child => isRouteMatching(child, filter));\r\n}\r\nfunction omit(obj, keys) {\r\n const ret = {};\r\n for (const key in obj) {\r\n if (!keys.includes(key)) {\r\n // @ts-expect-error\r\n ret[key] = obj[key];\r\n }\r\n }\r\n return ret;\r\n}\n\n/**\r\n * Creates a Router instance that can be used by a Vue app.\r\n *\r\n * @param options - {@link RouterOptions}\r\n */\r\nfunction createRouter(options) {\r\n const matcher = createRouterMatcher(options.routes, options);\r\n const parseQuery$1 = options.parseQuery || parseQuery;\r\n const stringifyQuery$1 = options.stringifyQuery || stringifyQuery;\r\n const routerHistory = options.history;\r\n if (false)\r\n {}\r\n const beforeGuards = useCallbacks();\r\n const beforeResolveGuards = useCallbacks();\r\n const afterGuards = useCallbacks();\r\n const currentRoute = (0,vue_esm_bundler/* shallowRef */.XI)(START_LOCATION_NORMALIZED);\r\n let pendingLocation = START_LOCATION_NORMALIZED;\r\n // leave the scrollRestoration if no scrollBehavior is provided\r\n if (isBrowser && options.scrollBehavior && 'scrollRestoration' in history) {\r\n history.scrollRestoration = 'manual';\r\n }\r\n const normalizeParams = applyToParams.bind(null, paramValue => '' + paramValue);\r\n const encodeParams = applyToParams.bind(null, encodeParam);\r\n const decodeParams = \r\n // @ts-expect-error: intentionally avoid the type check\r\n applyToParams.bind(null, decode);\r\n function addRoute(parentOrRoute, route) {\r\n let parent;\r\n let record;\r\n if (isRouteName(parentOrRoute)) {\r\n parent = matcher.getRecordMatcher(parentOrRoute);\r\n record = route;\r\n }\r\n else {\r\n record = parentOrRoute;\r\n }\r\n return matcher.addRoute(record, parent);\r\n }\r\n function removeRoute(name) {\r\n const recordMatcher = matcher.getRecordMatcher(name);\r\n if (recordMatcher) {\r\n matcher.removeRoute(recordMatcher);\r\n }\r\n else if ((false)) {}\r\n }\r\n function getRoutes() {\r\n return matcher.getRoutes().map(routeMatcher => routeMatcher.record);\r\n }\r\n function hasRoute(name) {\r\n return !!matcher.getRecordMatcher(name);\r\n }\r\n function resolve(rawLocation, currentLocation) {\r\n // const objectLocation = routerLocationAsObject(rawLocation)\r\n // we create a copy to modify it later\r\n currentLocation = vue_router_esm_bundler_assign({}, currentLocation || currentRoute.value);\r\n if (typeof rawLocation === 'string') {\r\n const locationNormalized = parseURL(parseQuery$1, rawLocation, currentLocation.path);\r\n const matchedRoute = matcher.resolve({ path: locationNormalized.path }, currentLocation);\r\n const href = routerHistory.createHref(locationNormalized.fullPath);\r\n if ((false)) {}\r\n // locationNormalized is always a new object\r\n return vue_router_esm_bundler_assign(locationNormalized, matchedRoute, {\r\n params: decodeParams(matchedRoute.params),\r\n hash: decode(locationNormalized.hash),\r\n redirectedFrom: undefined,\r\n href,\r\n });\r\n }\r\n let matcherLocation;\r\n // path could be relative in object as well\r\n if ('path' in rawLocation) {\r\n if (false) {}\r\n matcherLocation = vue_router_esm_bundler_assign({}, rawLocation, {\r\n path: parseURL(parseQuery$1, rawLocation.path, currentLocation.path).path,\r\n });\r\n }\r\n else {\r\n // remove any nullish param\r\n const targetParams = vue_router_esm_bundler_assign({}, rawLocation.params);\r\n for (const key in targetParams) {\r\n if (targetParams[key] == null) {\r\n delete targetParams[key];\r\n }\r\n }\r\n // pass encoded values to the matcher so it can produce encoded path and fullPath\r\n matcherLocation = vue_router_esm_bundler_assign({}, rawLocation, {\r\n params: encodeParams(rawLocation.params),\r\n });\r\n // current location params are decoded, we need to encode them in case the\r\n // matcher merges the params\r\n currentLocation.params = encodeParams(currentLocation.params);\r\n }\r\n const matchedRoute = matcher.resolve(matcherLocation, currentLocation);\r\n const hash = rawLocation.hash || '';\r\n if (false) {}\r\n // decoding them) the matcher might have merged current location params so\r\n // we need to run the decoding again\r\n matchedRoute.params = normalizeParams(decodeParams(matchedRoute.params));\r\n const fullPath = stringifyURL(stringifyQuery$1, vue_router_esm_bundler_assign({}, rawLocation, {\r\n hash: encodeHash(hash),\r\n path: matchedRoute.path,\r\n }));\r\n const href = routerHistory.createHref(fullPath);\r\n if ((false)) {}\r\n return vue_router_esm_bundler_assign({\r\n fullPath,\r\n // keep the hash encoded so fullPath is effectively path + encodedQuery +\r\n // hash\r\n hash,\r\n query: \r\n // if the user is using a custom query lib like qs, we might have\r\n // nested objects, so we keep the query as is, meaning it can contain\r\n // numbers at `$route.query`, but at the point, the user will have to\r\n // use their own type anyway.\r\n // https://github.com/vuejs/vue-router-next/issues/328#issuecomment-649481567\r\n stringifyQuery$1 === stringifyQuery\r\n ? normalizeQuery(rawLocation.query)\r\n : (rawLocation.query || {}),\r\n }, matchedRoute, {\r\n redirectedFrom: undefined,\r\n href,\r\n });\r\n }\r\n function locationAsObject(to) {\r\n return typeof to === 'string'\r\n ? parseURL(parseQuery$1, to, currentRoute.value.path)\r\n : vue_router_esm_bundler_assign({}, to);\r\n }\r\n function checkCanceledNavigation(to, from) {\r\n if (pendingLocation !== to) {\r\n return createRouterError(8 /* NAVIGATION_CANCELLED */, {\r\n from,\r\n to,\r\n });\r\n }\r\n }\r\n function push(to) {\r\n return pushWithRedirect(to);\r\n }\r\n function replace(to) {\r\n return push(vue_router_esm_bundler_assign(locationAsObject(to), { replace: true }));\r\n }\r\n function handleRedirectRecord(to) {\r\n const lastMatched = to.matched[to.matched.length - 1];\r\n if (lastMatched && lastMatched.redirect) {\r\n const { redirect } = lastMatched;\r\n let newTargetLocation = typeof redirect === 'function' ? redirect(to) : redirect;\r\n if (typeof newTargetLocation === 'string') {\r\n newTargetLocation =\r\n newTargetLocation.includes('?') || newTargetLocation.includes('#')\r\n ? (newTargetLocation = locationAsObject(newTargetLocation))\r\n : // force empty params\r\n { path: newTargetLocation };\r\n // @ts-expect-error: force empty params when a string is passed to let\r\n // the router parse them again\r\n newTargetLocation.params = {};\r\n }\r\n if (false) {}\r\n return vue_router_esm_bundler_assign({\r\n query: to.query,\r\n hash: to.hash,\r\n params: to.params,\r\n }, newTargetLocation);\r\n }\r\n }\r\n function pushWithRedirect(to, redirectedFrom) {\r\n const targetLocation = (pendingLocation = resolve(to));\r\n const from = currentRoute.value;\r\n const data = to.state;\r\n const force = to.force;\r\n // to could be a string where `replace` is a function\r\n const replace = to.replace === true;\r\n const shouldRedirect = handleRedirectRecord(targetLocation);\r\n if (shouldRedirect)\r\n return pushWithRedirect(vue_router_esm_bundler_assign(locationAsObject(shouldRedirect), {\r\n state: data,\r\n force,\r\n replace,\r\n }), \r\n // keep original redirectedFrom if it exists\r\n redirectedFrom || targetLocation);\r\n // if it was a redirect we already called `pushWithRedirect` above\r\n const toLocation = targetLocation;\r\n toLocation.redirectedFrom = redirectedFrom;\r\n let failure;\r\n if (!force && isSameRouteLocation(stringifyQuery$1, from, targetLocation)) {\r\n failure = createRouterError(16 /* NAVIGATION_DUPLICATED */, { to: toLocation, from });\r\n // trigger scroll to allow scrolling to the same anchor\r\n handleScroll(from, from, \r\n // this is a push, the only way for it to be triggered from a\r\n // history.listen is with a redirect, which makes it become a push\r\n true, \r\n // This cannot be the first navigation because the initial location\r\n // cannot be manually navigated to\r\n false);\r\n }\r\n return (failure ? Promise.resolve(failure) : navigate(toLocation, from))\r\n .catch((error) => isNavigationFailure(error)\r\n ? error\r\n : // reject any unknown error\r\n triggerError(error, toLocation, from))\r\n .then((failure) => {\r\n if (failure) {\r\n if (isNavigationFailure(failure, 2 /* NAVIGATION_GUARD_REDIRECT */)) {\r\n if (false) {}\r\n return pushWithRedirect(\r\n // keep options\r\n vue_router_esm_bundler_assign(locationAsObject(failure.to), {\r\n state: data,\r\n force,\r\n replace,\r\n }), \r\n // preserve the original redirectedFrom if any\r\n redirectedFrom || toLocation);\r\n }\r\n }\r\n else {\r\n // if we fail we don't finalize the navigation\r\n failure = finalizeNavigation(toLocation, from, true, replace, data);\r\n }\r\n triggerAfterEach(toLocation, from, failure);\r\n return failure;\r\n });\r\n }\r\n /**\r\n * Helper to reject and skip all navigation guards if a new navigation happened\r\n * @param to\r\n * @param from\r\n */\r\n function checkCanceledNavigationAndReject(to, from) {\r\n const error = checkCanceledNavigation(to, from);\r\n return error ? Promise.reject(error) : Promise.resolve();\r\n }\r\n // TODO: refactor the whole before guards by internally using router.beforeEach\r\n function navigate(to, from) {\r\n let guards;\r\n const [leavingRecords, updatingRecords, enteringRecords] = extractChangingRecords(to, from);\r\n // all components here have been resolved once because we are leaving\r\n guards = extractComponentsGuards(leavingRecords.reverse(), 'beforeRouteLeave', to, from);\r\n // leavingRecords is already reversed\r\n for (const record of leavingRecords) {\r\n record.leaveGuards.forEach(guard => {\r\n guards.push(guardToPromiseFn(guard, to, from));\r\n });\r\n }\r\n const canceledNavigationCheck = checkCanceledNavigationAndReject.bind(null, to, from);\r\n guards.push(canceledNavigationCheck);\r\n // run the queue of per route beforeRouteLeave guards\r\n return (runGuardQueue(guards)\r\n .then(() => {\r\n // check global guards beforeEach\r\n guards = [];\r\n for (const guard of beforeGuards.list()) {\r\n guards.push(guardToPromiseFn(guard, to, from));\r\n }\r\n guards.push(canceledNavigationCheck);\r\n return runGuardQueue(guards);\r\n })\r\n .then(() => {\r\n // check in components beforeRouteUpdate\r\n guards = extractComponentsGuards(updatingRecords, 'beforeRouteUpdate', to, from);\r\n for (const record of updatingRecords) {\r\n record.updateGuards.forEach(guard => {\r\n guards.push(guardToPromiseFn(guard, to, from));\r\n });\r\n }\r\n guards.push(canceledNavigationCheck);\r\n // run the queue of per route beforeEnter guards\r\n return runGuardQueue(guards);\r\n })\r\n .then(() => {\r\n // check the route beforeEnter\r\n guards = [];\r\n for (const record of to.matched) {\r\n // do not trigger beforeEnter on reused views\r\n if (record.beforeEnter && !from.matched.includes(record)) {\r\n if (Array.isArray(record.beforeEnter)) {\r\n for (const beforeEnter of record.beforeEnter)\r\n guards.push(guardToPromiseFn(beforeEnter, to, from));\r\n }\r\n else {\r\n guards.push(guardToPromiseFn(record.beforeEnter, to, from));\r\n }\r\n }\r\n }\r\n guards.push(canceledNavigationCheck);\r\n // run the queue of per route beforeEnter guards\r\n return runGuardQueue(guards);\r\n })\r\n .then(() => {\r\n // NOTE: at this point to.matched is normalized and does not contain any () => Promise\r\n // clear existing enterCallbacks, these are added by extractComponentsGuards\r\n to.matched.forEach(record => (record.enterCallbacks = {}));\r\n // check in-component beforeRouteEnter\r\n guards = extractComponentsGuards(enteringRecords, 'beforeRouteEnter', to, from);\r\n guards.push(canceledNavigationCheck);\r\n // run the queue of per route beforeEnter guards\r\n return runGuardQueue(guards);\r\n })\r\n .then(() => {\r\n // check global guards beforeResolve\r\n guards = [];\r\n for (const guard of beforeResolveGuards.list()) {\r\n guards.push(guardToPromiseFn(guard, to, from));\r\n }\r\n guards.push(canceledNavigationCheck);\r\n return runGuardQueue(guards);\r\n })\r\n // catch any navigation canceled\r\n .catch(err => isNavigationFailure(err, 8 /* NAVIGATION_CANCELLED */)\r\n ? err\r\n : Promise.reject(err)));\r\n }\r\n function triggerAfterEach(to, from, failure) {\r\n // navigation is confirmed, call afterGuards\r\n // TODO: wrap with error handlers\r\n for (const guard of afterGuards.list())\r\n guard(to, from, failure);\r\n }\r\n /**\r\n * - Cleans up any navigation guards\r\n * - Changes the url if necessary\r\n * - Calls the scrollBehavior\r\n */\r\n function finalizeNavigation(toLocation, from, isPush, replace, data) {\r\n // a more recent navigation took place\r\n const error = checkCanceledNavigation(toLocation, from);\r\n if (error)\r\n return error;\r\n // only consider as push if it's not the first navigation\r\n const isFirstNavigation = from === START_LOCATION_NORMALIZED;\r\n const state = !isBrowser ? {} : history.state;\r\n // change URL only if the user did a push/replace and if it's not the initial navigation because\r\n // it's just reflecting the url\r\n if (isPush) {\r\n // on the initial navigation, we want to reuse the scroll position from\r\n // history state if it exists\r\n if (replace || isFirstNavigation)\r\n routerHistory.replace(toLocation.fullPath, vue_router_esm_bundler_assign({\r\n scroll: isFirstNavigation && state && state.scroll,\r\n }, data));\r\n else\r\n routerHistory.push(toLocation.fullPath, data);\r\n }\r\n // accept current navigation\r\n currentRoute.value = toLocation;\r\n handleScroll(toLocation, from, isPush, isFirstNavigation);\r\n markAsReady();\r\n }\r\n let removeHistoryListener;\r\n // attach listener to history to trigger navigations\r\n function setupListeners() {\r\n removeHistoryListener = routerHistory.listen((to, _from, info) => {\r\n // cannot be a redirect route because it was in history\r\n const toLocation = resolve(to);\r\n // due to dynamic routing, and to hash history with manual navigation\r\n // (manually changing the url or calling history.hash = '#/somewhere'),\r\n // there could be a redirect record in history\r\n const shouldRedirect = handleRedirectRecord(toLocation);\r\n if (shouldRedirect) {\r\n pushWithRedirect(vue_router_esm_bundler_assign(shouldRedirect, { replace: true }), toLocation).catch(noop);\r\n return;\r\n }\r\n pendingLocation = toLocation;\r\n const from = currentRoute.value;\r\n // TODO: should be moved to web history?\r\n if (isBrowser) {\r\n saveScrollPosition(getScrollKey(from.fullPath, info.delta), computeScrollPosition());\r\n }\r\n navigate(toLocation, from)\r\n .catch((error) => {\r\n if (isNavigationFailure(error, 4 /* NAVIGATION_ABORTED */ | 8 /* NAVIGATION_CANCELLED */)) {\r\n return error;\r\n }\r\n if (isNavigationFailure(error, 2 /* NAVIGATION_GUARD_REDIRECT */)) {\r\n // Here we could call if (info.delta) routerHistory.go(-info.delta,\r\n // false) but this is bug prone as we have no way to wait the\r\n // navigation to be finished before calling pushWithRedirect. Using\r\n // a setTimeout of 16ms seems to work but there is not guarantee for\r\n // it to work on every browser. So Instead we do not restore the\r\n // history entry and trigger a new navigation as requested by the\r\n // navigation guard.\r\n // the error is already handled by router.push we just want to avoid\r\n // logging the error\r\n pushWithRedirect(error.to, toLocation\r\n // avoid an uncaught rejection, let push call triggerError\r\n )\r\n .then(failure => {\r\n // manual change in hash history #916 ending up in the URL not\r\n // changing but it was changed by the manual url change, so we\r\n // need to manually change it ourselves\r\n if (isNavigationFailure(failure, 4 /* NAVIGATION_ABORTED */ |\r\n 16 /* NAVIGATION_DUPLICATED */) &&\r\n !info.delta &&\r\n info.type === NavigationType.pop) {\r\n routerHistory.go(-1, false);\r\n }\r\n })\r\n .catch(noop);\r\n // avoid the then branch\r\n return Promise.reject();\r\n }\r\n // do not restore history on unknown direction\r\n if (info.delta)\r\n routerHistory.go(-info.delta, false);\r\n // unrecognized error, transfer to the global handler\r\n return triggerError(error, toLocation, from);\r\n })\r\n .then((failure) => {\r\n failure =\r\n failure ||\r\n finalizeNavigation(\r\n // after navigation, all matched components are resolved\r\n toLocation, from, false);\r\n // revert the navigation\r\n if (failure) {\r\n if (info.delta) {\r\n routerHistory.go(-info.delta, false);\r\n }\r\n else if (info.type === NavigationType.pop &&\r\n isNavigationFailure(failure, 4 /* NAVIGATION_ABORTED */ | 16 /* NAVIGATION_DUPLICATED */)) {\r\n // manual change in hash history #916\r\n // it's like a push but lacks the information of the direction\r\n routerHistory.go(-1, false);\r\n }\r\n }\r\n triggerAfterEach(toLocation, from, failure);\r\n })\r\n .catch(noop);\r\n });\r\n }\r\n // Initialization and Errors\r\n let readyHandlers = useCallbacks();\r\n let errorHandlers = useCallbacks();\r\n let ready;\r\n /**\r\n * Trigger errorHandlers added via onError and throws the error as well\r\n *\r\n * @param error - error to throw\r\n * @param to - location we were navigating to when the error happened\r\n * @param from - location we were navigating from when the error happened\r\n * @returns the error as a rejected promise\r\n */\r\n function triggerError(error, to, from) {\r\n markAsReady(error);\r\n const list = errorHandlers.list();\r\n if (list.length) {\r\n list.forEach(handler => handler(error, to, from));\r\n }\r\n else {\r\n if ((false)) {}\r\n console.error(error);\r\n }\r\n return Promise.reject(error);\r\n }\r\n function isReady() {\r\n if (ready && currentRoute.value !== START_LOCATION_NORMALIZED)\r\n return Promise.resolve();\r\n return new Promise((resolve, reject) => {\r\n readyHandlers.add([resolve, reject]);\r\n });\r\n }\r\n /**\r\n * Mark the router as ready, resolving the promised returned by isReady(). Can\r\n * only be called once, otherwise does nothing.\r\n * @param err - optional error\r\n */\r\n function markAsReady(err) {\r\n if (ready)\r\n return;\r\n ready = true;\r\n setupListeners();\r\n readyHandlers\r\n .list()\r\n .forEach(([resolve, reject]) => (err ? reject(err) : resolve()));\r\n readyHandlers.reset();\r\n }\r\n // Scroll behavior\r\n function handleScroll(to, from, isPush, isFirstNavigation) {\r\n const { scrollBehavior } = options;\r\n if (!isBrowser || !scrollBehavior)\r\n return Promise.resolve();\r\n const scrollPosition = (!isPush && getSavedScrollPosition(getScrollKey(to.fullPath, 0))) ||\r\n ((isFirstNavigation || !isPush) &&\r\n history.state &&\r\n history.state.scroll) ||\r\n null;\r\n return (0,vue_esm_bundler/* nextTick */.Y3)()\r\n .then(() => scrollBehavior(to, from, scrollPosition))\r\n .then(position => position && scrollToPosition(position))\r\n .catch(err => triggerError(err, to, from));\r\n }\r\n const go = (delta) => routerHistory.go(delta);\r\n let started;\r\n const installedApps = new Set();\r\n const router = {\r\n currentRoute,\r\n addRoute,\r\n removeRoute,\r\n hasRoute,\r\n getRoutes,\r\n resolve,\r\n options,\r\n push,\r\n replace,\r\n go,\r\n back: () => go(-1),\r\n forward: () => go(1),\r\n beforeEach: beforeGuards.add,\r\n beforeResolve: beforeResolveGuards.add,\r\n afterEach: afterGuards.add,\r\n onError: errorHandlers.add,\r\n isReady,\r\n install(app) {\r\n const router = this;\r\n app.component('RouterLink', RouterLink);\r\n app.component('RouterView', RouterView);\r\n app.config.globalProperties.$router = router;\r\n Object.defineProperty(app.config.globalProperties, '$route', {\r\n enumerable: true,\r\n get: () => (0,vue_esm_bundler/* unref */.SU)(currentRoute),\r\n });\r\n // this initial navigation is only necessary on client, on server it doesn't\r\n // make sense because it will create an extra unnecessary navigation and could\r\n // lead to problems\r\n if (isBrowser &&\r\n // used for the initial navigation client side to avoid pushing\r\n // multiple times when the router is used in multiple apps\r\n !started &&\r\n currentRoute.value === START_LOCATION_NORMALIZED) {\r\n // see above\r\n started = true;\r\n push(routerHistory.location).catch(err => {\r\n if ((false))\r\n {}\r\n });\r\n }\r\n const reactiveRoute = {};\r\n for (const key in START_LOCATION_NORMALIZED) {\r\n // @ts-expect-error: the key matches\r\n reactiveRoute[key] = (0,vue_esm_bundler/* computed */.Fl)(() => currentRoute.value[key]);\r\n }\r\n app.provide(routerKey, router);\r\n app.provide(routeLocationKey, (0,vue_esm_bundler/* reactive */.qj)(reactiveRoute));\r\n app.provide(routerViewLocationKey, currentRoute);\r\n const unmountApp = app.unmount;\r\n installedApps.add(app);\r\n app.unmount = function () {\r\n installedApps.delete(app);\r\n // the router is not attached to an app anymore\r\n if (installedApps.size < 1) {\r\n // invalidate the current navigation\r\n pendingLocation = START_LOCATION_NORMALIZED;\r\n removeHistoryListener && removeHistoryListener();\r\n currentRoute.value = START_LOCATION_NORMALIZED;\r\n started = false;\r\n ready = false;\r\n }\r\n unmountApp();\r\n };\r\n if (false) {}\r\n },\r\n };\r\n return router;\r\n}\r\nfunction runGuardQueue(guards) {\r\n return guards.reduce((promise, guard) => promise.then(() => guard()), Promise.resolve());\r\n}\r\nfunction extractChangingRecords(to, from) {\r\n const leavingRecords = [];\r\n const updatingRecords = [];\r\n const enteringRecords = [];\r\n const len = Math.max(from.matched.length, to.matched.length);\r\n for (let i = 0; i < len; i++) {\r\n const recordFrom = from.matched[i];\r\n if (recordFrom) {\r\n if (to.matched.find(record => isSameRouteRecord(record, recordFrom)))\r\n updatingRecords.push(recordFrom);\r\n else\r\n leavingRecords.push(recordFrom);\r\n }\r\n const recordTo = to.matched[i];\r\n if (recordTo) {\r\n // the type doesn't matter because we are comparing per reference\r\n if (!from.matched.find(record => isSameRouteRecord(record, recordTo))) {\r\n enteringRecords.push(recordTo);\r\n }\r\n }\r\n }\r\n return [leavingRecords, updatingRecords, enteringRecords];\r\n}\n\n/**\r\n * Returns the router instance. Equivalent to using `$router` inside\r\n * templates.\r\n */\r\nfunction useRouter() {\r\n return inject(routerKey);\r\n}\r\n/**\r\n * Returns the current route location. Equivalent to using `$route` inside\r\n * templates.\r\n */\r\nfunction useRoute() {\r\n return inject(routeLocationKey);\r\n}\n\n\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/LegacyView.vue?vue&type=template&id=374ba4a8\n\n\nconst _hoisted_1 = {\n id: \"contentContainer\",\n class: \"content-container\"\n}\nconst _hoisted_2 = /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\", { class: \"loading-view\" }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\", { class: \"progress-bar-div\" }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"progress\", {\n class: \"progress-bar\",\n max: \"100\",\n value: \"10\"\n }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"strong\", null, \"Progress: 100% Complete.\")\n ]),\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"span\", { class: \"progress-label\" }, \"Initializing...\")\n ])\n], -1 /* HOISTED */)\nconst _hoisted_3 = [\n _hoisted_2\n]\n\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", _hoisted_1, _hoisted_3))\n}\n;// CONCATENATED MODULE: ./interface/html5/components/LegacyView.vue?vue&type=template&id=374ba4a8\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/LegacyView.vue?vue&type=script&lang=js\n\n\n/* harmony default export */ const LegacyViewvue_type_script_lang_js = ({\n name: \"LegacyView\",\n components: {}\n});\n\n;// CONCATENATED MODULE: ./interface/html5/components/LegacyView.vue?vue&type=script&lang=js\n \n// EXTERNAL MODULE: ./node_modules/vue-loader/dist/exportHelper.js\nvar exportHelper = __webpack_require__(3744);\n;// CONCATENATED MODULE: ./interface/html5/components/LegacyView.vue\n\n\n\n\n;\nconst __exports__ = /*#__PURE__*/(0,exportHelper/* default */.Z)(LegacyViewvue_type_script_lang_js, [['render',render]])\n\n/* harmony default export */ const LegacyView = (__exports__);\n;// CONCATENATED MODULE: ./interface/html5/components/main_ui_router.js\n// import { createRouter, createWebHistory } from 'vue-router'\n\n\n\n// import ReportView from '@/components/ReportView';\n\nconst lazy_load_test = () => __webpack_require__.e(/* import() | dynamic-testview */ \"dynamic-testview\").then(__webpack_require__.bind(__webpack_require__, 1136)); // #VUETEST\n\n// Can also import this from another file.\nconst routes = [\n\t{ path: '/test', name: 'test', component: lazy_load_test, props:true }, // #VUETEST Lazy loaded, so not loaded normally. Only when used with `VueRouter.push('test')` or via dev tools.\n\t// { path: '/view/:viewId', name: 'view', component: LegacyView, props:true },\n\t// { path: '/report/:viewId', name: 'report', component: ReportView, props:true },\n\t// { path: '/report/:reportId', name: 'report', component: LegacyView },\n\t// { path: '/wizard/:wizardId', name: 'wizard', component: LegacyView },\n\t{ path: '/:pathMatch(.*)*', name: 'catch-all', component: LegacyView },\n\t// { path: '/#!m=Login', name: 'not-found', component: LegacyView },\n\t// { path: '/#!m=:viewId&*:restOf(.*)', name: 'not-found', component: LegacyView },\n\n];\n\nconst main_ui_router = createRouter({\n\t// history: createWebHistory(),\n\thistory: createMemoryHistory(),\n\troutes,\n});\n\n/* harmony default export */ const components_main_ui_router = (main_ui_router);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjIzNy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2lNO0FBQ3pJOztBQUV4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsTUFBcUMsSUFBSSxDQUF1QjtBQUM5RSxRQUFRLE1BQXFDLElBQUksQ0FBZ0I7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxNQUFxQyxJQUFJLENBQThCO0FBQ3pIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQyxNQUFxQyxJQUFJLENBQW1CO0FBQzNHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QyxNQUFxQyxJQUFJLENBQVE7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELE1BQXFDLElBQUksQ0FBZ0I7QUFDNUc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0RBQXdELE1BQXFDLElBQUksQ0FBc0I7O0FBRXZIOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU0sNkJBQU07QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLG1CQUFtQjtBQUNqRDtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLEtBQWdFLEVBQUUsRUFHckU7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixnQ0FBZ0M7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLHdDQUF3QztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxrREFBa0Q7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksS0FBMEUsRUFBRSxFQWdCL0U7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLE1BQXFDO0FBQ2xELGdCQUFnQixDQUF5RjtBQUN6RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSx5QkFBeUI7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLFFBQVE7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixrQkFBa0I7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsVUFBVTtBQUMxQjtBQUNBO0FBQ0EsNkJBQTZCLDZCQUFNLEdBQUcsbUJBQW1CLGlDQUFpQztBQUMxRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksb0JBQW9CO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsS0FBcUMsR0FBRyxFQUU1QztBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsNkJBQU0sR0FBRztBQUMvQjtBQUNBLHVEQUF1RCx1Q0FBdUM7QUFDOUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLDZCQUFNLEdBQUc7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULFlBQVksS0FBeUQsRUFBRSxFQUk5RDtBQUNUO0FBQ0Esc0JBQXNCLDZCQUFNLEdBQUcsaURBQWlELHFDQUFxQztBQUNySDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsNkJBQU07QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLGtCQUFrQjtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsS0FBc0YsRUFBRSxFQUUzRjtBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksaUJBQWlCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZCxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7O0FBRUEsMERBQTBELE1BQXFDLElBQUksQ0FBb0I7QUFDdkg7QUFDQTtBQUNBLElBQUksMkJBQTJCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsc0RBQXNEO0FBQ3ZEO0FBQ0E7QUFDQSxrQ0FBa0MsMkJBQTJCO0FBQzdELGlDQUFpQyx5QkFBeUIsRUFBRTtBQUM1RDtBQUNBLGlCQUFpQjtBQUNqQixLQUFLO0FBQ0wsMENBQTBDLFdBQVc7QUFDckQsbUNBQW1DLGNBQWMsUUFBUSxtQkFBbUI7QUFDNUUsS0FBSztBQUNMLG1DQUFtQyxVQUFVO0FBQzdDLDJDQUEyQyxjQUFjLFFBQVEsWUFBWTtBQUM3RSxLQUFLO0FBQ0wscUNBQXFDLFVBQVU7QUFDL0MsNkNBQTZDLGNBQWMsUUFBUSxZQUFZO0FBQy9FLEtBQUs7QUFDTCx1Q0FBdUMsVUFBVTtBQUNqRCxxRUFBcUUsY0FBYztBQUNuRixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsUUFBUSxLQUFnRCxFQUFFLEVBS3JEO0FBQ0w7QUFDQSxlQUFlLDZCQUFNO0FBQ3JCO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQiw2QkFBTSxHQUFHO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyw2QkFBNkI7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHNDQUFzQztBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsR0FBRztBQUMxQztBQUNBO0FBQ0EsNEVBQTRFLE1BQU0sS0FBSyxHQUFHO0FBQzFGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELEdBQUcsVUFBVSxHQUFHLFlBQVksR0FBRztBQUNwRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsV0FBVztBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNENBQTRDLEtBQUs7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0Isa0JBQWtCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLDhCQUE4QjtBQUMxRDtBQUNBO0FBQ0EsMkRBQTJELE1BQU07QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUVBQXVFLE1BQU07QUFDN0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLE1BQXFDO0FBQzlELGNBQWMsQ0FBc0U7QUFDcEYsK0JBQStCLEtBQUs7QUFDcEM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLE1BQU0sS0FBSyxPQUFPLEtBQUssUUFBUTtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QyxPQUFPO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELE9BQU87QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLEtBQXFDLEdBQUcsRUFPNUM7QUFDTCxvQkFBb0IsNkJBQU07QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyw0Q0FBNEM7QUFDL0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1Qyw2QkFBTSxHQUFHO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLE9BQU87QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLEtBQXdFLEVBQUUsRUFHN0U7QUFDYjtBQUNBO0FBQ0EsZ0JBQWdCLEtBQW9FO0FBQ3BGLGdCQUFnQixFQUFrRDtBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixLQUFxQyxHQUFHLEVBRTVDO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHFCQUFxQjtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsR0FBRztBQUNwQztBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsR0FBRztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLHFCQUFxQiw2QkFBTTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsS0FBZ0UsRUFBRSxFQUVyRTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQiw2QkFBTSxHQUFHO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0EsZ0JBQWdCLDJCQUEyQjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0Qyw2QkFBTSx1QkFBdUI7QUFDekU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsY0FBYyw4QkFBOEIsY0FBYyw0Q0FBNEMsU0FBUztBQUNqSjtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsY0FBYyw4QkFBOEIsY0FBYyw0Q0FBNEMsU0FBUztBQUNqSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLG1CQUFtQiw0Q0FBNEMsU0FBUyxtQkFBbUIsbUJBQW1CO0FBQ3hKO0FBQ0E7O0FBRUE7QUFDQSxrREFBa0Q7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRTtBQUNqRTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEIsMkJBQTJCO0FBQzNCLHdCQUF3QjtBQUN4Qix1QkFBdUI7QUFDdkIscUJBQXFCO0FBQ3JCLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DO0FBQ3BDLHFDQUFxQztBQUNyQyw2QkFBNkI7QUFDN0IsZ0NBQWdDO0FBQ2hDLGtDQUFrQztBQUNsQyw0QkFBNEI7QUFDNUIsbUNBQW1DO0FBQ25DLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQztBQUN0Qyx1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQztBQUN0Qyx1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNENBQTRDLGtCQUFrQjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLE1BQXFDLEtBQUssQ0FBc0Q7QUFDekc7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0NBQW9DLHFCQUFxQjtBQUN6RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQix5QkFBeUI7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLHdCQUF3QjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLHdCQUF3QixRQUFRLHFCQUFxQjtBQUN0RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsd0JBQXdCO0FBQ3JFO0FBQ0E7QUFDQSx3QkFBd0I7QUFDeEI7QUFDQTtBQUNBLFFBQVEsS0FBZ0UsRUFBRSxFQUdyRTtBQUNMO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxTQUFTLE1BQXFDO0FBQzlDLFlBQVksQ0FBbU07QUFDL007QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLHlCQUF5QjtBQUN2RDtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQSxRQUFRLEtBQWdFLEVBQUUsRUFHckU7QUFDTDtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsU0FBUyxNQUFxQztBQUM5QyxZQUFZLENBQW9NO0FBQ2hOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0ZBQW9GLE1BQXFDLElBQUksQ0FBbUM7QUFDaEs7QUFDQTtBQUNBO0FBQ0EsWUFBWSxLQUEyRCxFQUFFLEVBcUJoRTtBQUNUO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyR0FBMkcsY0FBYyxRQUFRLFlBQVk7QUFDN0k7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixLQUFxQyxHQUFHLEVBOEI1QztBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixLQUF5RSxFQUFFLEVBRzlFO0FBQ2pCO0FBQ0E7QUFDQSx1RkFBdUYsS0FBSyxRQUFRLFlBQVk7QUFDaEg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixrQ0FBTTtBQUN6Qix5QkFBeUIsa0NBQU07QUFDL0Isa0JBQWtCLG9DQUFRLHNCQUFzQixpQ0FBSztBQUNyRCw4QkFBOEIsb0NBQVE7QUFDdEMsZ0JBQWdCLFVBQVU7QUFDMUIsZ0JBQWdCLFNBQVM7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxxQkFBcUIsb0NBQVE7QUFDN0I7QUFDQSwwQkFBMEIsb0NBQVE7QUFDbEM7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBLDBCQUEwQixpQ0FBSyxzQ0FBc0MsaUNBQUs7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxLQUErRSxFQUFFLEVBa0JwRjtBQUNMO0FBQ0E7QUFDQSxjQUFjLG9DQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsMkNBQWU7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLG1CQUFtQixPQUFPO0FBQzFCLHFCQUFxQixvQ0FBUTtBQUM3QixnQkFBZ0IsVUFBVSxFQUFFLGtDQUFNO0FBQ2xDLHdCQUF3QixvQ0FBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixxQkFBQztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsS0FBSztBQUNMLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQ0FBcUMsMkNBQWU7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0wsbUJBQW1CLGNBQWM7QUFDakMsU0FBUyxNQUFxQyxLQUFLLENBQXFCO0FBQ3hFLDhCQUE4QixrQ0FBTTtBQUNwQywrQkFBK0Isb0NBQVE7QUFDdkMsc0JBQXNCLGtDQUFNO0FBQzVCLGdDQUFnQyxvQ0FBUTtBQUN4QyxRQUFRLG1DQUFPO0FBQ2YsUUFBUSxtQ0FBTztBQUNmLFFBQVEsbUNBQU87QUFDZix3QkFBd0IsK0JBQUc7QUFDM0I7QUFDQTtBQUNBLFFBQVEsaUNBQUs7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsSUFBSSxlQUFlO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0QsaUNBQWlDO0FBQ3ZGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLHFCQUFDLGdCQUFnQiw2QkFBTSxHQUFHO0FBQ3hEO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsZ0JBQWdCLEtBRWEsRUFBRSxFQWVsQjtBQUNiO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyw2QkFBNkI7QUFDeEU7QUFDQTtBQUNBLEtBQUs7QUFDTCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsV0FBVztBQUMvQyxrQkFBa0IsS0FBSztBQUN2QjtBQUNBLG1CQUFtQixLQUFLO0FBQ3hCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQiw2QkFBTSxHQUFHO0FBQzFCO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLFNBQVM7QUFDVDtBQUNBLHFDQUFxQyxtQ0FBbUM7QUFDeEU7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLHFCQUFxQjtBQUNoRTtBQUNBLGdFQUFnRSxlQUFlO0FBQy9FO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsaUJBQWlCO0FBQ2pCO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsb0JBQW9CO0FBQ2hEO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixPQUFPO0FBQ25DO0FBQ0EsaUJBQWlCO0FBQ2pCLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxTQUFTO0FBQ3JCO0FBQ0EsVUFBVSxrREFBa0Q7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0Esa0JBQWtCLGlEQUFpRDtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsU0FBUyxFQUFFLG9CQUFvQjtBQUN0RTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakIsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxTQUFTO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsS0FBeUQ7QUFDakUsUUFBUSxFQUNvRDtBQUM1RDtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsc0NBQVU7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLEtBQXFDLEdBQUcsRUFFakQ7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQiw2QkFBTSxHQUFHO0FBQ25DO0FBQ0E7QUFDQSxtREFBbUQsK0JBQStCO0FBQ2xGO0FBQ0EsaUJBQWlCLEtBQXFDLEdBQUcsRUFNNUM7QUFDYjtBQUNBLG1CQUFtQiw2QkFBTTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixLQUlzQyxFQUFFLEVBSTNDO0FBQ2IsOEJBQThCLDZCQUFNLEdBQUc7QUFDdkM7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLDZCQUFNLEdBQUc7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLDZCQUFNLEdBQUc7QUFDdkM7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxLQUF3RSxFQUFFLEVBRTdFO0FBQ1Q7QUFDQTtBQUNBO0FBQ0Esd0RBQXdELDZCQUFNLEdBQUc7QUFDakU7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLGFBQWEsS0FBcUMsR0FBRyxFQU81QztBQUNULGVBQWUsNkJBQU07QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDO0FBQzFDLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyw2QkFBTSxHQUFHO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsNkJBQU0seUJBQXlCLGVBQWU7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsV0FBVztBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsS0FFOEIsRUFBRSxFQUduQztBQUNiLG1CQUFtQiw2QkFBTTtBQUN6QjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyw2QkFBTTtBQUMxQztBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRUFBMEUsc0JBQXNCO0FBQ2hHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsS0FTYSxFQUFFLEVBR2xCO0FBQ3JCO0FBQ0E7QUFDQSxvQkFBb0IsNkJBQU07QUFDMUI7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxvRUFBb0U7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELDZCQUFNO0FBQ2pFO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLDZCQUFNLG1CQUFtQixlQUFlO0FBQ3pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixLQUFxQyxHQUFHLEVBRTVDO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixpQkFBaUI7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLG9DQUFRO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsaUNBQUs7QUFDaEMsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsS0FBcUM7QUFDOUQsd0JBQXdCLEVBQXdEO0FBQ2hGLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxvQ0FBUTtBQUM3QztBQUNBO0FBQ0EsMENBQTBDLG9DQUFRO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLEtBQStFLEVBQUUsRUFFcEY7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixTQUFTO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFaVo7Ozs7OztFQzMzR3hZLEVBQUUsRUFBQyxrQkFBa0I7RUFBQyxLQUFLLEVBQUMsbUJBQW1COztnQ0FDaEQsOENBT00sU0FQRCxLQUFLLEVBQUMsY0FBYztlQUNyQiw4Q0FLTSxTQUxELEtBQUssRUFBQyxrQkFBa0I7aUJBQ3pCLDhDQUVXO01BRkQsS0FBSyxFQUFDLGNBQWM7TUFBQyxHQUFHLEVBQUMsS0FBSztNQUFDLEtBQUssRUFBQyxJQUFJOzttQkFDL0MsOENBQXlDLGdCQUFqQywwQkFBd0I7O2lCQUVwQyw4Q0FBbUQsVUFBN0MsS0FBSyxFQUFDLGdCQUFnQixJQUFDLGlCQUFlOzs7O0VBTHBELFVBT007Ozs7bURBUlYsK0NBU00sT0FUTixVQVNNOzs7Ozs7O0FBS1Ysd0VBQWU7SUFDWCxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDakIsQ0FBQyxFQUFDOzs7QUVsQjhJLEM7Ozs7QUNBekU7QUFDVjtBQUNMOztBQUV4RCxDQUFxRztBQUNyRyxpQ0FBaUMsK0JBQWUsQ0FBQyxpQ0FBTSxhQUFhLE1BQU07O0FBRTFFLGlEQUFlOztBQ1BmLFlBQVksaUNBQWlDO0FBQ2lCOztBQUViO0FBQ2pEOztBQUVBLDZCQUE2QixxSUFBMkUsRUFBRTs7QUFFMUc7QUFDQTtBQUNBLEdBQUcsb0VBQW9FO0FBQ3ZFLE1BQU0sd0VBQXdFO0FBQzlFLE1BQU0sNEVBQTRFO0FBQ2xGLE1BQU0sa0VBQWtFO0FBQ3hFLE1BQU0sa0VBQWtFO0FBQ3hFLEdBQUcsd0RBQXdELFVBQVUsRUFBRTtBQUN2RSxNQUFNLDhEQUE4RDtBQUNwRSxNQUFNLDZFQUE2RTs7QUFFbkY7O0FBRUEsdUJBQXVCLFlBQVk7QUFDbkM7QUFDQSxVQUFVLG1CQUFtQjtBQUM3QjtBQUNBLENBQUM7O0FBRUQsZ0VBQWUsY0FBYyxFQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3Z1ZS1yb3V0ZXIvZGlzdC92dWUtcm91dGVyLmVzbS1idW5kbGVyLmpzPzZjMDIiLCJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2NvbXBvbmVudHMvTGVnYWN5Vmlldy52dWU/ZjNkOSIsIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvY29tcG9uZW50cy9MZWdhY3lWaWV3LnZ1ZT80M2M0Iiwid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9jb21wb25lbnRzL0xlZ2FjeVZpZXcudnVlPzg0NzciLCJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2NvbXBvbmVudHMvTGVnYWN5Vmlldy52dWU/MzgyNSIsIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvY29tcG9uZW50cy9tYWluX3VpX3JvdXRlci5qcz81MmU0Il0sInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICAqIHZ1ZS1yb3V0ZXIgdjQuMC4xMlxuICAqIChjKSAyMDIxIEVkdWFyZG8gU2FuIE1hcnRpbiBNb3JvdGVcbiAgKiBAbGljZW5zZSBNSVRcbiAgKi9cbmltcG9ydCB7IGdldEN1cnJlbnRJbnN0YW5jZSwgaW5qZWN0LCBvblVubW91bnRlZCwgb25EZWFjdGl2YXRlZCwgb25BY3RpdmF0ZWQsIGNvbXB1dGVkLCB1bnJlZiwgd2F0Y2hFZmZlY3QsIGRlZmluZUNvbXBvbmVudCwgcmVhY3RpdmUsIGgsIHByb3ZpZGUsIHJlZiwgd2F0Y2gsIHNoYWxsb3dSZWYsIG5leHRUaWNrIH0gZnJvbSAndnVlJztcbmltcG9ydCB7IHNldHVwRGV2dG9vbHNQbHVnaW4gfSBmcm9tICdAdnVlL2RldnRvb2xzLWFwaSc7XG5cbmNvbnN0IGhhc1N5bWJvbCA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCc7XHJcbmNvbnN0IFBvbHlTeW1ib2wgPSAobmFtZSkgPT4gXHJcbi8vIHZyID0gdnVlIHJvdXRlclxyXG5oYXNTeW1ib2xcclxuICAgID8gU3ltYm9sKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/ICdbdnVlLXJvdXRlcl06ICcgKyBuYW1lIDogbmFtZSlcclxuICAgIDogKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/ICdbdnVlLXJvdXRlcl06ICcgOiAnX3ZyXycpICsgbmFtZTtcclxuLy8gcnZsbSA9IFJvdXRlciBWaWV3IExvY2F0aW9uIE1hdGNoZWRcclxuLyoqXHJcbiAqIFJvdXRlUmVjb3JkIGJlaW5nIHJlbmRlcmVkIGJ5IHRoZSBjbG9zZXN0IGFuY2VzdG9yIFJvdXRlciBWaWV3LiBVc2VkIGZvclxyXG4gKiBgb25CZWZvcmVSb3V0ZVVwZGF0ZWAgYW5kIGBvbkJlZm9yZVJvdXRlTGVhdmVgLiBydmxtIHN0YW5kcyBmb3IgUm91dGVyIFZpZXdcclxuICogTG9jYXRpb24gTWF0Y2hlZFxyXG4gKlxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbmNvbnN0IG1hdGNoZWRSb3V0ZUtleSA9IC8qI19fUFVSRV9fKi8gUG9seVN5bWJvbCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyAncm91dGVyIHZpZXcgbG9jYXRpb24gbWF0Y2hlZCcgOiAncnZsbScpO1xyXG4vKipcclxuICogQWxsb3dzIG92ZXJyaWRpbmcgdGhlIHJvdXRlciB2aWV3IGRlcHRoIHRvIGNvbnRyb2wgd2hpY2ggY29tcG9uZW50IGluXHJcbiAqIGBtYXRjaGVkYCBpcyByZW5kZXJlZC4gcnZkIHN0YW5kcyBmb3IgUm91dGVyIFZpZXcgRGVwdGhcclxuICpcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5jb25zdCB2aWV3RGVwdGhLZXkgPSAvKiNfX1BVUkVfXyovIFBvbHlTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ3JvdXRlciB2aWV3IGRlcHRoJyA6ICdydmQnKTtcclxuLyoqXHJcbiAqIEFsbG93cyBvdmVycmlkaW5nIHRoZSByb3V0ZXIgaW5zdGFuY2UgcmV0dXJuZWQgYnkgYHVzZVJvdXRlcmAgaW4gdGVzdHMuIHJcclxuICogc3RhbmRzIGZvciByb3V0ZXJcclxuICpcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5jb25zdCByb3V0ZXJLZXkgPSAvKiNfX1BVUkVfXyovIFBvbHlTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ3JvdXRlcicgOiAncicpO1xyXG4vKipcclxuICogQWxsb3dzIG92ZXJyaWRpbmcgdGhlIGN1cnJlbnQgcm91dGUgcmV0dXJuZWQgYnkgYHVzZVJvdXRlYCBpbiB0ZXN0cy4gcmxcclxuICogc3RhbmRzIGZvciByb3V0ZSBsb2NhdGlvblxyXG4gKlxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbmNvbnN0IHJvdXRlTG9jYXRpb25LZXkgPSAvKiNfX1BVUkVfXyovIFBvbHlTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ3JvdXRlIGxvY2F0aW9uJyA6ICdybCcpO1xyXG4vKipcclxuICogQWxsb3dzIG92ZXJyaWRpbmcgdGhlIGN1cnJlbnQgcm91dGUgdXNlZCBieSByb3V0ZXItdmlldy4gSW50ZXJuYWxseSB0aGlzIGlzXHJcbiAqIHVzZWQgd2hlbiB0aGUgYHJvdXRlYCBwcm9wIGlzIHBhc3NlZC5cclxuICpcclxuICogQGludGVybmFsXHJcbiAqL1xyXG5jb25zdCByb3V0ZXJWaWV3TG9jYXRpb25LZXkgPSAvKiNfX1BVUkVfXyovIFBvbHlTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ3JvdXRlciB2aWV3IGxvY2F0aW9uJyA6ICdydmwnKTtcblxuY29uc3QgaXNCcm93c2VyID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCc7XG5cbmZ1bmN0aW9uIGlzRVNNb2R1bGUob2JqKSB7XHJcbiAgICByZXR1cm4gb2JqLl9fZXNNb2R1bGUgfHwgKGhhc1N5bWJvbCAmJiBvYmpbU3ltYm9sLnRvU3RyaW5nVGFnXSA9PT0gJ01vZHVsZScpO1xyXG59XHJcbmNvbnN0IGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XHJcbmZ1bmN0aW9uIGFwcGx5VG9QYXJhbXMoZm4sIHBhcmFtcykge1xyXG4gICAgY29uc3QgbmV3UGFyYW1zID0ge307XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBwYXJhbXMpIHtcclxuICAgICAgICBjb25zdCB2YWx1ZSA9IHBhcmFtc1trZXldO1xyXG4gICAgICAgIG5ld1BhcmFtc1trZXldID0gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZS5tYXAoZm4pIDogZm4odmFsdWUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5ld1BhcmFtcztcclxufVxyXG5jb25zdCBub29wID0gKCkgPT4geyB9O1xuXG5mdW5jdGlvbiB3YXJuKG1zZykge1xyXG4gICAgLy8gYXZvaWQgdXNpbmcgLi4uYXJncyBhcyBpdCBicmVha3MgaW4gb2xkZXIgRWRnZSBidWlsZHNcclxuICAgIGNvbnN0IGFyZ3MgPSBBcnJheS5mcm9tKGFyZ3VtZW50cykuc2xpY2UoMSk7XHJcbiAgICBjb25zb2xlLndhcm4uYXBwbHkoY29uc29sZSwgWydbVnVlIFJvdXRlciB3YXJuXTogJyArIG1zZ10uY29uY2F0KGFyZ3MpKTtcclxufVxuXG5jb25zdCBUUkFJTElOR19TTEFTSF9SRSA9IC9cXC8kLztcclxuY29uc3QgcmVtb3ZlVHJhaWxpbmdTbGFzaCA9IChwYXRoKSA9PiBwYXRoLnJlcGxhY2UoVFJBSUxJTkdfU0xBU0hfUkUsICcnKTtcclxuLyoqXHJcbiAqIFRyYW5zZm9ybXMgYW4gVVJJIGludG8gYSBub3JtYWxpemVkIGhpc3RvcnkgbG9jYXRpb25cclxuICpcclxuICogQHBhcmFtIHBhcnNlUXVlcnlcclxuICogQHBhcmFtIGxvY2F0aW9uIC0gVVJJIHRvIG5vcm1hbGl6ZVxyXG4gKiBAcGFyYW0gY3VycmVudExvY2F0aW9uIC0gY3VycmVudCBhYnNvbHV0ZSBsb2NhdGlvbi4gQWxsb3dzIHJlc29sdmluZyByZWxhdGl2ZVxyXG4gKiBwYXRocy4gTXVzdCBzdGFydCB3aXRoIGAvYC4gRGVmYXVsdHMgdG8gYC9gXHJcbiAqIEByZXR1cm5zIGEgbm9ybWFsaXplZCBoaXN0b3J5IGxvY2F0aW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBwYXJzZVVSTChwYXJzZVF1ZXJ5LCBsb2NhdGlvbiwgY3VycmVudExvY2F0aW9uID0gJy8nKSB7XHJcbiAgICBsZXQgcGF0aCwgcXVlcnkgPSB7fSwgc2VhcmNoU3RyaW5nID0gJycsIGhhc2ggPSAnJztcclxuICAgIC8vIENvdWxkIHVzZSBVUkwgYW5kIFVSTFNlYXJjaFBhcmFtcyBidXQgSUUgMTEgZG9lc24ndCBzdXBwb3J0IGl0XHJcbiAgICBjb25zdCBzZWFyY2hQb3MgPSBsb2NhdGlvbi5pbmRleE9mKCc/Jyk7XHJcbiAgICBjb25zdCBoYXNoUG9zID0gbG9jYXRpb24uaW5kZXhPZignIycsIHNlYXJjaFBvcyA+IC0xID8gc2VhcmNoUG9zIDogMCk7XHJcbiAgICBpZiAoc2VhcmNoUG9zID4gLTEpIHtcclxuICAgICAgICBwYXRoID0gbG9jYXRpb24uc2xpY2UoMCwgc2VhcmNoUG9zKTtcclxuICAgICAgICBzZWFyY2hTdHJpbmcgPSBsb2NhdGlvbi5zbGljZShzZWFyY2hQb3MgKyAxLCBoYXNoUG9zID4gLTEgPyBoYXNoUG9zIDogbG9jYXRpb24ubGVuZ3RoKTtcclxuICAgICAgICBxdWVyeSA9IHBhcnNlUXVlcnkoc2VhcmNoU3RyaW5nKTtcclxuICAgIH1cclxuICAgIGlmIChoYXNoUG9zID4gLTEpIHtcclxuICAgICAgICBwYXRoID0gcGF0aCB8fCBsb2NhdGlvbi5zbGljZSgwLCBoYXNoUG9zKTtcclxuICAgICAgICAvLyBrZWVwIHRoZSAjIGNoYXJhY3RlclxyXG4gICAgICAgIGhhc2ggPSBsb2NhdGlvbi5zbGljZShoYXNoUG9zLCBsb2NhdGlvbi5sZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgLy8gbm8gc2VhcmNoIGFuZCBubyBxdWVyeVxyXG4gICAgcGF0aCA9IHJlc29sdmVSZWxhdGl2ZVBhdGgocGF0aCAhPSBudWxsID8gcGF0aCA6IGxvY2F0aW9uLCBjdXJyZW50TG9jYXRpb24pO1xyXG4gICAgLy8gZW1wdHkgcGF0aCBtZWFucyBhIHJlbGF0aXZlIHF1ZXJ5IG9yIGhhc2ggYD9mb289ZmAsIGAjdGhpbmdgXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGZ1bGxQYXRoOiBwYXRoICsgKHNlYXJjaFN0cmluZyAmJiAnPycpICsgc2VhcmNoU3RyaW5nICsgaGFzaCxcclxuICAgICAgICBwYXRoLFxyXG4gICAgICAgIHF1ZXJ5LFxyXG4gICAgICAgIGhhc2gsXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBTdHJpbmdpZmllcyBhIFVSTCBvYmplY3RcclxuICpcclxuICogQHBhcmFtIHN0cmluZ2lmeVF1ZXJ5XHJcbiAqIEBwYXJhbSBsb2NhdGlvblxyXG4gKi9cclxuZnVuY3Rpb24gc3RyaW5naWZ5VVJMKHN0cmluZ2lmeVF1ZXJ5LCBsb2NhdGlvbikge1xyXG4gICAgY29uc3QgcXVlcnkgPSBsb2NhdGlvbi5xdWVyeSA/IHN0cmluZ2lmeVF1ZXJ5KGxvY2F0aW9uLnF1ZXJ5KSA6ICcnO1xyXG4gICAgcmV0dXJuIGxvY2F0aW9uLnBhdGggKyAocXVlcnkgJiYgJz8nKSArIHF1ZXJ5ICsgKGxvY2F0aW9uLmhhc2ggfHwgJycpO1xyXG59XHJcbi8qKlxyXG4gKiBTdHJpcHMgb2ZmIHRoZSBiYXNlIGZyb20gdGhlIGJlZ2lubmluZyBvZiBhIGxvY2F0aW9uLnBhdGhuYW1lIGluIGEgbm9uXHJcbiAqIGNhc2Utc2Vuc2l0aXZlIHdheS5cclxuICpcclxuICogQHBhcmFtIHBhdGhuYW1lIC0gbG9jYXRpb24ucGF0aG5hbWVcclxuICogQHBhcmFtIGJhc2UgLSBiYXNlIHRvIHN0cmlwIG9mZlxyXG4gKi9cclxuZnVuY3Rpb24gc3RyaXBCYXNlKHBhdGhuYW1lLCBiYXNlKSB7XHJcbiAgICAvLyBubyBiYXNlIG9yIGJhc2UgaXMgbm90IGZvdW5kIGF0IHRoZSBiZWdpbm5pbmdcclxuICAgIGlmICghYmFzZSB8fCAhcGF0aG5hbWUudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKGJhc2UudG9Mb3dlckNhc2UoKSkpXHJcbiAgICAgICAgcmV0dXJuIHBhdGhuYW1lO1xyXG4gICAgcmV0dXJuIHBhdGhuYW1lLnNsaWNlKGJhc2UubGVuZ3RoKSB8fCAnLyc7XHJcbn1cclxuLyoqXHJcbiAqIENoZWNrcyBpZiB0d28gUm91dGVMb2NhdGlvbiBhcmUgZXF1YWwuIFRoaXMgbWVhbnMgdGhhdCBib3RoIGxvY2F0aW9ucyBhcmVcclxuICogcG9pbnRpbmcgdG93YXJkcyB0aGUgc2FtZSB7QGxpbmsgUm91dGVSZWNvcmR9IGFuZCB0aGF0IGFsbCBgcGFyYW1zYCwgYHF1ZXJ5YFxyXG4gKiBwYXJhbWV0ZXJzIGFuZCBgaGFzaGAgYXJlIHRoZSBzYW1lXHJcbiAqXHJcbiAqIEBwYXJhbSBhIC0gZmlyc3Qge0BsaW5rIFJvdXRlTG9jYXRpb259XHJcbiAqIEBwYXJhbSBiIC0gc2Vjb25kIHtAbGluayBSb3V0ZUxvY2F0aW9ufVxyXG4gKi9cclxuZnVuY3Rpb24gaXNTYW1lUm91dGVMb2NhdGlvbihzdHJpbmdpZnlRdWVyeSwgYSwgYikge1xyXG4gICAgY29uc3QgYUxhc3RJbmRleCA9IGEubWF0Y2hlZC5sZW5ndGggLSAxO1xyXG4gICAgY29uc3QgYkxhc3RJbmRleCA9IGIubWF0Y2hlZC5sZW5ndGggLSAxO1xyXG4gICAgcmV0dXJuIChhTGFzdEluZGV4ID4gLTEgJiZcclxuICAgICAgICBhTGFzdEluZGV4ID09PSBiTGFzdEluZGV4ICYmXHJcbiAgICAgICAgaXNTYW1lUm91dGVSZWNvcmQoYS5tYXRjaGVkW2FMYXN0SW5kZXhdLCBiLm1hdGNoZWRbYkxhc3RJbmRleF0pICYmXHJcbiAgICAgICAgaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtcyhhLnBhcmFtcywgYi5wYXJhbXMpICYmXHJcbiAgICAgICAgc3RyaW5naWZ5UXVlcnkoYS5xdWVyeSkgPT09IHN0cmluZ2lmeVF1ZXJ5KGIucXVlcnkpICYmXHJcbiAgICAgICAgYS5oYXNoID09PSBiLmhhc2gpO1xyXG59XHJcbi8qKlxyXG4gKiBDaGVjayBpZiB0d28gYFJvdXRlUmVjb3Jkc2AgYXJlIGVxdWFsLiBUYWtlcyBpbnRvIGFjY291bnQgYWxpYXNlczogdGhleSBhcmVcclxuICogY29uc2lkZXJlZCBlcXVhbCB0byB0aGUgYFJvdXRlUmVjb3JkYCB0aGV5IGFyZSBhbGlhc2luZy5cclxuICpcclxuICogQHBhcmFtIGEgLSBmaXJzdCB7QGxpbmsgUm91dGVSZWNvcmR9XHJcbiAqIEBwYXJhbSBiIC0gc2Vjb25kIHtAbGluayBSb3V0ZVJlY29yZH1cclxuICovXHJcbmZ1bmN0aW9uIGlzU2FtZVJvdXRlUmVjb3JkKGEsIGIpIHtcclxuICAgIC8vIHNpbmNlIHRoZSBvcmlnaW5hbCByZWNvcmQgaGFzIGFuIHVuZGVmaW5lZCB2YWx1ZSBmb3IgYWxpYXNPZlxyXG4gICAgLy8gYnV0IGFsbCBhbGlhc2VzIHBvaW50IHRvIHRoZSBvcmlnaW5hbCByZWNvcmQsIHRoaXMgd2lsbCBhbHdheXMgY29tcGFyZVxyXG4gICAgLy8gdGhlIG9yaWdpbmFsIHJlY29yZFxyXG4gICAgcmV0dXJuIChhLmFsaWFzT2YgfHwgYSkgPT09IChiLmFsaWFzT2YgfHwgYik7XHJcbn1cclxuZnVuY3Rpb24gaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtcyhhLCBiKSB7XHJcbiAgICBpZiAoT2JqZWN0LmtleXMoYSkubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhiKS5sZW5ndGgpXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gYSkge1xyXG4gICAgICAgIGlmICghaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtc1ZhbHVlKGFba2V5XSwgYltrZXldKSlcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbn1cclxuZnVuY3Rpb24gaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtc1ZhbHVlKGEsIGIpIHtcclxuICAgIHJldHVybiBBcnJheS5pc0FycmF5KGEpXHJcbiAgICAgICAgPyBpc0VxdWl2YWxlbnRBcnJheShhLCBiKVxyXG4gICAgICAgIDogQXJyYXkuaXNBcnJheShiKVxyXG4gICAgICAgICAgICA/IGlzRXF1aXZhbGVudEFycmF5KGIsIGEpXHJcbiAgICAgICAgICAgIDogYSA9PT0gYjtcclxufVxyXG4vKipcclxuICogQ2hlY2sgaWYgdHdvIGFycmF5cyBhcmUgdGhlIHNhbWUgb3IgaWYgYW4gYXJyYXkgd2l0aCBvbmUgc2luZ2xlIGVudHJ5IGlzIHRoZVxyXG4gKiBzYW1lIGFzIGFub3RoZXIgcHJpbWl0aXZlIHZhbHVlLiBVc2VkIHRvIGNoZWNrIHF1ZXJ5IGFuZCBwYXJhbWV0ZXJzXHJcbiAqXHJcbiAqIEBwYXJhbSBhIC0gYXJyYXkgb2YgdmFsdWVzXHJcbiAqIEBwYXJhbSBiIC0gYXJyYXkgb2YgdmFsdWVzIG9yIGEgc2luZ2xlIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBpc0VxdWl2YWxlbnRBcnJheShhLCBiKSB7XHJcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShiKVxyXG4gICAgICAgID8gYS5sZW5ndGggPT09IGIubGVuZ3RoICYmIGEuZXZlcnkoKHZhbHVlLCBpKSA9PiB2YWx1ZSA9PT0gYltpXSlcclxuICAgICAgICA6IGEubGVuZ3RoID09PSAxICYmIGFbMF0gPT09IGI7XHJcbn1cclxuLyoqXHJcbiAqIFJlc29sdmVzIGEgcmVsYXRpdmUgcGF0aCB0aGF0IHN0YXJ0cyB3aXRoIGAuYC5cclxuICpcclxuICogQHBhcmFtIHRvIC0gcGF0aCBsb2NhdGlvbiB3ZSBhcmUgcmVzb2x2aW5nXHJcbiAqIEBwYXJhbSBmcm9tIC0gY3VycmVudExvY2F0aW9uLnBhdGgsIHNob3VsZCBzdGFydCB3aXRoIGAvYFxyXG4gKi9cclxuZnVuY3Rpb24gcmVzb2x2ZVJlbGF0aXZlUGF0aCh0bywgZnJvbSkge1xyXG4gICAgaWYgKHRvLnN0YXJ0c1dpdGgoJy8nKSlcclxuICAgICAgICByZXR1cm4gdG87XHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFmcm9tLnN0YXJ0c1dpdGgoJy8nKSkge1xyXG4gICAgICAgIHdhcm4oYENhbm5vdCByZXNvbHZlIGEgcmVsYXRpdmUgbG9jYXRpb24gd2l0aG91dCBhbiBhYnNvbHV0ZSBwYXRoLiBUcnlpbmcgdG8gcmVzb2x2ZSBcIiR7dG99XCIgZnJvbSBcIiR7ZnJvbX1cIi4gSXQgc2hvdWxkIGxvb2sgbGlrZSBcIi8ke2Zyb219XCIuYCk7XHJcbiAgICAgICAgcmV0dXJuIHRvO1xyXG4gICAgfVxyXG4gICAgaWYgKCF0bylcclxuICAgICAgICByZXR1cm4gZnJvbTtcclxuICAgIGNvbnN0IGZyb21TZWdtZW50cyA9IGZyb20uc3BsaXQoJy8nKTtcclxuICAgIGNvbnN0IHRvU2VnbWVudHMgPSB0by5zcGxpdCgnLycpO1xyXG4gICAgbGV0IHBvc2l0aW9uID0gZnJvbVNlZ21lbnRzLmxlbmd0aCAtIDE7XHJcbiAgICBsZXQgdG9Qb3NpdGlvbjtcclxuICAgIGxldCBzZWdtZW50O1xyXG4gICAgZm9yICh0b1Bvc2l0aW9uID0gMDsgdG9Qb3NpdGlvbiA8IHRvU2VnbWVudHMubGVuZ3RoOyB0b1Bvc2l0aW9uKyspIHtcclxuICAgICAgICBzZWdtZW50ID0gdG9TZWdtZW50c1t0b1Bvc2l0aW9uXTtcclxuICAgICAgICAvLyBjYW4ndCBnbyBiZWxvdyB6ZXJvXHJcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAxIHx8IHNlZ21lbnQgPT09ICcuJylcclxuICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgaWYgKHNlZ21lbnQgPT09ICcuLicpXHJcbiAgICAgICAgICAgIHBvc2l0aW9uLS07XHJcbiAgICAgICAgLy8gZm91bmQgc29tZXRoaW5nIHRoYXQgaXMgbm90IHJlbGF0aXZlIHBhdGhcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIChmcm9tU2VnbWVudHMuc2xpY2UoMCwgcG9zaXRpb24pLmpvaW4oJy8nKSArXHJcbiAgICAgICAgJy8nICtcclxuICAgICAgICB0b1NlZ21lbnRzXHJcbiAgICAgICAgICAgIC5zbGljZSh0b1Bvc2l0aW9uIC0gKHRvUG9zaXRpb24gPT09IHRvU2VnbWVudHMubGVuZ3RoID8gMSA6IDApKVxyXG4gICAgICAgICAgICAuam9pbignLycpKTtcclxufVxuXG52YXIgTmF2aWdhdGlvblR5cGU7XHJcbihmdW5jdGlvbiAoTmF2aWdhdGlvblR5cGUpIHtcclxuICAgIE5hdmlnYXRpb25UeXBlW1wicG9wXCJdID0gXCJwb3BcIjtcclxuICAgIE5hdmlnYXRpb25UeXBlW1wicHVzaFwiXSA9IFwicHVzaFwiO1xyXG59KShOYXZpZ2F0aW9uVHlwZSB8fCAoTmF2aWdhdGlvblR5cGUgPSB7fSkpO1xyXG52YXIgTmF2aWdhdGlvbkRpcmVjdGlvbjtcclxuKGZ1bmN0aW9uIChOYXZpZ2F0aW9uRGlyZWN0aW9uKSB7XHJcbiAgICBOYXZpZ2F0aW9uRGlyZWN0aW9uW1wiYmFja1wiXSA9IFwiYmFja1wiO1xyXG4gICAgTmF2aWdhdGlvbkRpcmVjdGlvbltcImZvcndhcmRcIl0gPSBcImZvcndhcmRcIjtcclxuICAgIE5hdmlnYXRpb25EaXJlY3Rpb25bXCJ1bmtub3duXCJdID0gXCJcIjtcclxufSkoTmF2aWdhdGlvbkRpcmVjdGlvbiB8fCAoTmF2aWdhdGlvbkRpcmVjdGlvbiA9IHt9KSk7XHJcbi8qKlxyXG4gKiBTdGFydGluZyBsb2NhdGlvbiBmb3IgSGlzdG9yaWVzXHJcbiAqL1xyXG5jb25zdCBTVEFSVCA9ICcnO1xyXG4vLyBHZW5lcmljIHV0aWxzXHJcbi8qKlxyXG4gKiBOb3JtYWxpemVzIGEgYmFzZSBieSByZW1vdmluZyBhbnkgdHJhaWxpbmcgc2xhc2ggYW5kIHJlYWRpbmcgdGhlIGJhc2UgdGFnIGlmXHJcbiAqIHByZXNlbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSBiYXNlIC0gYmFzZSB0byBub3JtYWxpemVcclxuICovXHJcbmZ1bmN0aW9uIG5vcm1hbGl6ZUJhc2UoYmFzZSkge1xyXG4gICAgaWYgKCFiYXNlKSB7XHJcbiAgICAgICAgaWYgKGlzQnJvd3Nlcikge1xyXG4gICAgICAgICAgICAvLyByZXNwZWN0IDxiYXNlPiB0YWdcclxuICAgICAgICAgICAgY29uc3QgYmFzZUVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYmFzZScpO1xyXG4gICAgICAgICAgICBiYXNlID0gKGJhc2VFbCAmJiBiYXNlRWwuZ2V0QXR0cmlidXRlKCdocmVmJykpIHx8ICcvJztcclxuICAgICAgICAgICAgLy8gc3RyaXAgZnVsbCBVUkwgb3JpZ2luXHJcbiAgICAgICAgICAgIGJhc2UgPSBiYXNlLnJlcGxhY2UoL15cXHcrOlxcL1xcL1teXFwvXSsvLCAnJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBiYXNlID0gJy8nO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGVuc3VyZSBsZWFkaW5nIHNsYXNoIHdoZW4gaXQgd2FzIHJlbW92ZWQgYnkgdGhlIHJlZ2V4IGFib3ZlIGF2b2lkIGxlYWRpbmdcclxuICAgIC8vIHNsYXNoIHdpdGggaGFzaCBiZWNhdXNlIHRoZSBmaWxlIGNvdWxkIGJlIHJlYWQgZnJvbSB0aGUgZGlzayBsaWtlIGZpbGU6Ly9cclxuICAgIC8vIGFuZCB0aGUgbGVhZGluZyBzbGFzaCB3b3VsZCBjYXVzZSBwcm9ibGVtc1xyXG4gICAgaWYgKGJhc2VbMF0gIT09ICcvJyAmJiBiYXNlWzBdICE9PSAnIycpXHJcbiAgICAgICAgYmFzZSA9ICcvJyArIGJhc2U7XHJcbiAgICAvLyByZW1vdmUgdGhlIHRyYWlsaW5nIHNsYXNoIHNvIGFsbCBvdGhlciBtZXRob2QgY2FuIGp1c3QgZG8gYGJhc2UgKyBmdWxsUGF0aGBcclxuICAgIC8vIHRvIGJ1aWxkIGFuIGhyZWZcclxuICAgIHJldHVybiByZW1vdmVUcmFpbGluZ1NsYXNoKGJhc2UpO1xyXG59XHJcbi8vIHJlbW92ZSBhbnkgY2hhcmFjdGVyIGJlZm9yZSB0aGUgaGFzaFxyXG5jb25zdCBCRUZPUkVfSEFTSF9SRSA9IC9eW14jXSsjLztcclxuZnVuY3Rpb24gY3JlYXRlSHJlZihiYXNlLCBsb2NhdGlvbikge1xyXG4gICAgcmV0dXJuIGJhc2UucmVwbGFjZShCRUZPUkVfSEFTSF9SRSwgJyMnKSArIGxvY2F0aW9uO1xyXG59XG5cbmZ1bmN0aW9uIGdldEVsZW1lbnRQb3NpdGlvbihlbCwgb2Zmc2V0KSB7XHJcbiAgICBjb25zdCBkb2NSZWN0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3QgZWxSZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGJlaGF2aW9yOiBvZmZzZXQuYmVoYXZpb3IsXHJcbiAgICAgICAgbGVmdDogZWxSZWN0LmxlZnQgLSBkb2NSZWN0LmxlZnQgLSAob2Zmc2V0LmxlZnQgfHwgMCksXHJcbiAgICAgICAgdG9wOiBlbFJlY3QudG9wIC0gZG9jUmVjdC50b3AgLSAob2Zmc2V0LnRvcCB8fCAwKSxcclxuICAgIH07XHJcbn1cclxuY29uc3QgY29tcHV0ZVNjcm9sbFBvc2l0aW9uID0gKCkgPT4gKHtcclxuICAgIGxlZnQ6IHdpbmRvdy5wYWdlWE9mZnNldCxcclxuICAgIHRvcDogd2luZG93LnBhZ2VZT2Zmc2V0LFxyXG59KTtcclxuZnVuY3Rpb24gc2Nyb2xsVG9Qb3NpdGlvbihwb3NpdGlvbikge1xyXG4gICAgbGV0IHNjcm9sbFRvT3B0aW9ucztcclxuICAgIGlmICgnZWwnIGluIHBvc2l0aW9uKSB7XHJcbiAgICAgICAgY29uc3QgcG9zaXRpb25FbCA9IHBvc2l0aW9uLmVsO1xyXG4gICAgICAgIGNvbnN0IGlzSWRTZWxlY3RvciA9IHR5cGVvZiBwb3NpdGlvbkVsID09PSAnc3RyaW5nJyAmJiBwb3NpdGlvbkVsLnN0YXJ0c1dpdGgoJyMnKTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBgaWRgcyBjYW4gYWNjZXB0IHByZXR0eSBtdWNoIGFueSBjaGFyYWN0ZXJzLCBpbmNsdWRpbmcgQ1NTIGNvbWJpbmF0b3JzXHJcbiAgICAgICAgICogbGlrZSBgPmAgb3IgYH5gLiBJdCdzIHN0aWxsIHBvc3NpYmxlIHRvIHJldHJpZXZlIGVsZW1lbnRzIHVzaW5nXHJcbiAgICAgICAgICogYGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd+JylgIGJ1dCBpdCBuZWVkcyB0byBiZSBlc2NhcGVkIHdoZW4gdXNpbmdcclxuICAgICAgICAgKiBgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI1xcXFx+JylgIGZvciBpdCB0byBiZSB2YWxpZC4gVGhlIG9ubHlcclxuICAgICAgICAgKiByZXF1aXJlbWVudHMgZm9yIGBpZGBzIGFyZSB0aGVtIHRvIGJlIHVuaXF1ZSBvbiB0aGUgcGFnZSBhbmQgdG8gbm90IGJlXHJcbiAgICAgICAgICogZW1wdHkgKGBpZD1cIlwiYCkuIEJlY2F1c2Ugb2YgdGhhdCwgd2hlbiBwYXNzaW5nIGFuIGlkIHNlbGVjdG9yLCBpdCBzaG91bGRcclxuICAgICAgICAgKiBiZSBwcm9wZXJseSBlc2NhcGVkIGZvciBpdCB0byB3b3JrIHdpdGggYHF1ZXJ5U2VsZWN0b3JgLiBXZSBjb3VsZCBjaGVja1xyXG4gICAgICAgICAqIGZvciB0aGUgaWQgc2VsZWN0b3IgdG8gYmUgc2ltcGxlIChubyBDU1MgY29tYmluYXRvcnMgYCsgPn5gKSBidXQgdGhhdFxyXG4gICAgICAgICAqIHdvdWxkIG1ha2UgdGhpbmdzIGluY29uc2lzdGVudCBzaW5jZSB0aGV5IGFyZSB2YWxpZCBjaGFyYWN0ZXJzIGZvciBhblxyXG4gICAgICAgICAqIGBpZGAgYnV0IHdvdWxkIG5lZWQgdG8gYmUgZXNjYXBlZCB3aGVuIHVzaW5nIGBxdWVyeVNlbGVjdG9yYCwgYnJlYWtpbmdcclxuICAgICAgICAgKiB0aGVpciB1c2FnZSBhbmQgZW5kaW5nIHVwIGluIG5vIHNlbGVjdG9yIHJldHVybmVkLiBTZWxlY3RvcnMgbmVlZCB0byBiZVxyXG4gICAgICAgICAqIGVzY2FwZWQ6XHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiAtIGAjMS10aGluZ2AgYmVjb21lcyBgI1xcMzEgLXRoaW5nYFxyXG4gICAgICAgICAqIC0gYCN3aXRofnN5bWJvbHNgIGJlY29tZXMgYCN3aXRoXFxcXH5zeW1ib2xzYFxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogLSBNb3JlIGluZm9ybWF0aW9uIGFib3V0ICB0aGUgdG9waWMgY2FuIGJlIGZvdW5kIGF0XHJcbiAgICAgICAgICogICBodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvaHRtbDUtaWQtY2xhc3MuXHJcbiAgICAgICAgICogLSBQcmFjdGljYWwgZXhhbXBsZTogaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL2RlbW8vaHRtbDUtaWRcclxuICAgICAgICAgKi9cclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIHR5cGVvZiBwb3NpdGlvbi5lbCA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgaWYgKCFpc0lkU2VsZWN0b3IgfHwgIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBvc2l0aW9uLmVsLnNsaWNlKDEpKSkge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3VuZEVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihwb3NpdGlvbi5lbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzSWRTZWxlY3RvciAmJiBmb3VuZEVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm4oYFRoZSBzZWxlY3RvciBcIiR7cG9zaXRpb24uZWx9XCIgc2hvdWxkIGJlIHBhc3NlZCBhcyBcImVsOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcke3Bvc2l0aW9uLmVsfScpXCIgYmVjYXVzZSBpdCBzdGFydHMgd2l0aCBcIiNcIi5gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJuIHRvIGF2b2lkIG90aGVyIHdhcm5pbmdzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybihgVGhlIHNlbGVjdG9yIFwiJHtwb3NpdGlvbi5lbH1cIiBpcyBpbnZhbGlkLiBJZiB5b3UgYXJlIHVzaW5nIGFuIGlkIHNlbGVjdG9yLCBtYWtlIHN1cmUgdG8gZXNjYXBlIGl0LiBZb3UgY2FuIGZpbmQgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBlc2NhcGluZyBjaGFyYWN0ZXJzIGluIHNlbGVjdG9ycyBhdCBodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvY3NzLWVzY2FwZXMgb3IgdXNlIENTUy5lc2NhcGUgKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DU1MvZXNjYXBlKS5gKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyByZXR1cm4gdG8gYXZvaWQgb3RoZXIgd2FybmluZ3NcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgZWwgPSB0eXBlb2YgcG9zaXRpb25FbCA9PT0gJ3N0cmluZydcclxuICAgICAgICAgICAgPyBpc0lkU2VsZWN0b3JcclxuICAgICAgICAgICAgICAgID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocG9zaXRpb25FbC5zbGljZSgxKSlcclxuICAgICAgICAgICAgICAgIDogZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihwb3NpdGlvbkVsKVxyXG4gICAgICAgICAgICA6IHBvc2l0aW9uRWw7XHJcbiAgICAgICAgaWYgKCFlbCkge1xyXG4gICAgICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiZcclxuICAgICAgICAgICAgICAgIHdhcm4oYENvdWxkbid0IGZpbmQgZWxlbWVudCB1c2luZyBzZWxlY3RvciBcIiR7cG9zaXRpb24uZWx9XCIgcmV0dXJuZWQgYnkgc2Nyb2xsQmVoYXZpb3IuYCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgc2Nyb2xsVG9PcHRpb25zID0gZ2V0RWxlbWVudFBvc2l0aW9uKGVsLCBwb3NpdGlvbik7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBzY3JvbGxUb09wdGlvbnMgPSBwb3NpdGlvbjtcclxuICAgIH1cclxuICAgIGlmICgnc2Nyb2xsQmVoYXZpb3InIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZSlcclxuICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oc2Nyb2xsVG9PcHRpb25zKTtcclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHdpbmRvdy5zY3JvbGxUbyhzY3JvbGxUb09wdGlvbnMubGVmdCAhPSBudWxsID8gc2Nyb2xsVG9PcHRpb25zLmxlZnQgOiB3aW5kb3cucGFnZVhPZmZzZXQsIHNjcm9sbFRvT3B0aW9ucy50b3AgIT0gbnVsbCA/IHNjcm9sbFRvT3B0aW9ucy50b3AgOiB3aW5kb3cucGFnZVlPZmZzZXQpO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGdldFNjcm9sbEtleShwYXRoLCBkZWx0YSkge1xyXG4gICAgY29uc3QgcG9zaXRpb24gPSBoaXN0b3J5LnN0YXRlID8gaGlzdG9yeS5zdGF0ZS5wb3NpdGlvbiAtIGRlbHRhIDogLTE7XHJcbiAgICByZXR1cm4gcG9zaXRpb24gKyBwYXRoO1xyXG59XHJcbmNvbnN0IHNjcm9sbFBvc2l0aW9ucyA9IG5ldyBNYXAoKTtcclxuZnVuY3Rpb24gc2F2ZVNjcm9sbFBvc2l0aW9uKGtleSwgc2Nyb2xsUG9zaXRpb24pIHtcclxuICAgIHNjcm9sbFBvc2l0aW9ucy5zZXQoa2V5LCBzY3JvbGxQb3NpdGlvbik7XHJcbn1cclxuZnVuY3Rpb24gZ2V0U2F2ZWRTY3JvbGxQb3NpdGlvbihrZXkpIHtcclxuICAgIGNvbnN0IHNjcm9sbCA9IHNjcm9sbFBvc2l0aW9ucy5nZXQoa2V5KTtcclxuICAgIC8vIGNvbnN1bWUgaXQgc28gaXQncyBub3QgdXNlZCBhZ2FpblxyXG4gICAgc2Nyb2xsUG9zaXRpb25zLmRlbGV0ZShrZXkpO1xyXG4gICAgcmV0dXJuIHNjcm9sbDtcclxufVxyXG4vLyBUT0RPOiBSRkMgYWJvdXQgaG93IHRvIHNhdmUgc2Nyb2xsIHBvc2l0aW9uXHJcbi8qKlxyXG4gKiBTY3JvbGxCZWhhdmlvciBpbnN0YW5jZSB1c2VkIGJ5IHRoZSByb3V0ZXIgdG8gY29tcHV0ZSBhbmQgcmVzdG9yZSB0aGUgc2Nyb2xsXHJcbiAqIHBvc2l0aW9uIHdoZW4gbmF2aWdhdGluZy5cclxuICovXHJcbi8vIGV4cG9ydCBpbnRlcmZhY2UgU2Nyb2xsSGFuZGxlcjxTY3JvbGxQb3NpdGlvbkVudHJ5IGV4dGVuZHMgSGlzdG9yeVN0YXRlVmFsdWUsIFNjcm9sbFBvc2l0aW9uIGV4dGVuZHMgU2Nyb2xsUG9zaXRpb25FbnRyeT4ge1xyXG4vLyAgIC8vIHJldHVybnMgYSBzY3JvbGwgcG9zaXRpb24gdGhhdCBjYW4gYmUgc2F2ZWQgaW4gaGlzdG9yeVxyXG4vLyAgIGNvbXB1dGUoKTogU2Nyb2xsUG9zaXRpb25FbnRyeVxyXG4vLyAgIC8vIGNhbiB0YWtlIGFuIGV4dGVuZGVkIFNjcm9sbFBvc2l0aW9uRW50cnlcclxuLy8gICBzY3JvbGwocG9zaXRpb246IFNjcm9sbFBvc2l0aW9uKTogdm9pZFxyXG4vLyB9XHJcbi8vIGV4cG9ydCBjb25zdCBzY3JvbGxIYW5kbGVyOiBTY3JvbGxIYW5kbGVyPFNjcm9sbFBvc2l0aW9uPiA9IHtcclxuLy8gICBjb21wdXRlOiBjb21wdXRlU2Nyb2xsLFxyXG4vLyAgIHNjcm9sbDogc2Nyb2xsVG9Qb3NpdGlvbixcclxuLy8gfVxuXG5sZXQgY3JlYXRlQmFzZUxvY2F0aW9uID0gKCkgPT4gbG9jYXRpb24ucHJvdG9jb2wgKyAnLy8nICsgbG9jYXRpb24uaG9zdDtcclxuLyoqXHJcbiAqIENyZWF0ZXMgYSBub3JtYWxpemVkIGhpc3RvcnkgbG9jYXRpb24gZnJvbSBhIHdpbmRvdy5sb2NhdGlvbiBvYmplY3RcclxuICogQHBhcmFtIGxvY2F0aW9uIC1cclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZUN1cnJlbnRMb2NhdGlvbihiYXNlLCBsb2NhdGlvbikge1xyXG4gICAgY29uc3QgeyBwYXRobmFtZSwgc2VhcmNoLCBoYXNoIH0gPSBsb2NhdGlvbjtcclxuICAgIC8vIGFsbG93cyBoYXNoIGJhc2VzIGxpa2UgIywgLyMsICMvLCAjISwgIyEvLCAvIyEvLCBvciBldmVuIC9mb2xkZXIjZW5kXHJcbiAgICBjb25zdCBoYXNoUG9zID0gYmFzZS5pbmRleE9mKCcjJyk7XHJcbiAgICBpZiAoaGFzaFBvcyA+IC0xKSB7XHJcbiAgICAgICAgbGV0IHNsaWNlUG9zID0gaGFzaC5pbmNsdWRlcyhiYXNlLnNsaWNlKGhhc2hQb3MpKVxyXG4gICAgICAgICAgICA/IGJhc2Uuc2xpY2UoaGFzaFBvcykubGVuZ3RoXHJcbiAgICAgICAgICAgIDogMTtcclxuICAgICAgICBsZXQgcGF0aEZyb21IYXNoID0gaGFzaC5zbGljZShzbGljZVBvcyk7XHJcbiAgICAgICAgLy8gcHJlcGVuZCB0aGUgc3RhcnRpbmcgc2xhc2ggdG8gaGFzaCBzbyB0aGUgdXJsIHN0YXJ0cyB3aXRoIC8jXHJcbiAgICAgICAgaWYgKHBhdGhGcm9tSGFzaFswXSAhPT0gJy8nKVxyXG4gICAgICAgICAgICBwYXRoRnJvbUhhc2ggPSAnLycgKyBwYXRoRnJvbUhhc2g7XHJcbiAgICAgICAgcmV0dXJuIHN0cmlwQmFzZShwYXRoRnJvbUhhc2gsICcnKTtcclxuICAgIH1cclxuICAgIGNvbnN0IHBhdGggPSBzdHJpcEJhc2UocGF0aG5hbWUsIGJhc2UpO1xyXG4gICAgcmV0dXJuIHBhdGggKyBzZWFyY2ggKyBoYXNoO1xyXG59XHJcbmZ1bmN0aW9uIHVzZUhpc3RvcnlMaXN0ZW5lcnMoYmFzZSwgaGlzdG9yeVN0YXRlLCBjdXJyZW50TG9jYXRpb24sIHJlcGxhY2UpIHtcclxuICAgIGxldCBsaXN0ZW5lcnMgPSBbXTtcclxuICAgIGxldCB0ZWFyZG93bnMgPSBbXTtcclxuICAgIC8vIFRPRE86IHNob3VsZCBpdCBiZSBhIHN0YWNrPyBhIERpY3QuIENoZWNrIGlmIHRoZSBwb3BzdGF0ZSBsaXN0ZW5lclxyXG4gICAgLy8gY2FuIHRyaWdnZXIgdHdpY2VcclxuICAgIGxldCBwYXVzZVN0YXRlID0gbnVsbDtcclxuICAgIGNvbnN0IHBvcFN0YXRlSGFuZGxlciA9ICh7IHN0YXRlLCB9KSA9PiB7XHJcbiAgICAgICAgY29uc3QgdG8gPSBjcmVhdGVDdXJyZW50TG9jYXRpb24oYmFzZSwgbG9jYXRpb24pO1xyXG4gICAgICAgIGNvbnN0IGZyb20gPSBjdXJyZW50TG9jYXRpb24udmFsdWU7XHJcbiAgICAgICAgY29uc3QgZnJvbVN0YXRlID0gaGlzdG9yeVN0YXRlLnZhbHVlO1xyXG4gICAgICAgIGxldCBkZWx0YSA9IDA7XHJcbiAgICAgICAgaWYgKHN0YXRlKSB7XHJcbiAgICAgICAgICAgIGN1cnJlbnRMb2NhdGlvbi52YWx1ZSA9IHRvO1xyXG4gICAgICAgICAgICBoaXN0b3J5U3RhdGUudmFsdWUgPSBzdGF0ZTtcclxuICAgICAgICAgICAgLy8gaWdub3JlIHRoZSBwb3BzdGF0ZSBhbmQgcmVzZXQgdGhlIHBhdXNlU3RhdGVcclxuICAgICAgICAgICAgaWYgKHBhdXNlU3RhdGUgJiYgcGF1c2VTdGF0ZSA9PT0gZnJvbSkge1xyXG4gICAgICAgICAgICAgICAgcGF1c2VTdGF0ZSA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVsdGEgPSBmcm9tU3RhdGUgPyBzdGF0ZS5wb3NpdGlvbiAtIGZyb21TdGF0ZS5wb3NpdGlvbiA6IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXBsYWNlKHRvKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coeyBkZWx0YUZyb21DdXJyZW50IH0pXHJcbiAgICAgICAgLy8gSGVyZSB3ZSBjb3VsZCBhbHNvIHJldmVydCB0aGUgbmF2aWdhdGlvbiBieSBjYWxsaW5nIGhpc3RvcnkuZ28oLWRlbHRhKVxyXG4gICAgICAgIC8vIHRoaXMgbGlzdGVuZXIgd2lsbCBoYXZlIHRvIGJlIGFkYXB0ZWQgdG8gbm90IHRyaWdnZXIgYWdhaW4gYW5kIHRvIHdhaXQgZm9yIHRoZSB1cmxcclxuICAgICAgICAvLyB0byBiZSB1cGRhdGVkIGJlZm9yZSB0cmlnZ2VyaW5nIHRoZSBsaXN0ZW5lcnMuIFNvbWUga2luZCBvZiB2YWxpZGF0aW9uIGZ1bmN0aW9uIHdvdWxkIGFsc29cclxuICAgICAgICAvLyBuZWVkIHRvIGJlIHBhc3NlZCB0byB0aGUgbGlzdGVuZXJzIHNvIHRoZSBuYXZpZ2F0aW9uIGNhbiBiZSBhY2NlcHRlZFxyXG4gICAgICAgIC8vIGNhbGwgYWxsIGxpc3RlbmVyc1xyXG4gICAgICAgIGxpc3RlbmVycy5mb3JFYWNoKGxpc3RlbmVyID0+IHtcclxuICAgICAgICAgICAgbGlzdGVuZXIoY3VycmVudExvY2F0aW9uLnZhbHVlLCBmcm9tLCB7XHJcbiAgICAgICAgICAgICAgICBkZWx0YSxcclxuICAgICAgICAgICAgICAgIHR5cGU6IE5hdmlnYXRpb25UeXBlLnBvcCxcclxuICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogZGVsdGFcclxuICAgICAgICAgICAgICAgICAgICA/IGRlbHRhID4gMFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IE5hdmlnYXRpb25EaXJlY3Rpb24uZm9yd2FyZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IE5hdmlnYXRpb25EaXJlY3Rpb24uYmFja1xyXG4gICAgICAgICAgICAgICAgICAgIDogTmF2aWdhdGlvbkRpcmVjdGlvbi51bmtub3duLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBmdW5jdGlvbiBwYXVzZUxpc3RlbmVycygpIHtcclxuICAgICAgICBwYXVzZVN0YXRlID0gY3VycmVudExvY2F0aW9uLnZhbHVlO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gbGlzdGVuKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgLy8gc2V0dXAgdGhlIGxpc3RlbmVyIGFuZCBwcmVwYXJlIHRlYXJkb3duIGNhbGxiYWNrc1xyXG4gICAgICAgIGxpc3RlbmVycy5wdXNoKGNhbGxiYWNrKTtcclxuICAgICAgICBjb25zdCB0ZWFyZG93biA9ICgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBsaXN0ZW5lcnMuaW5kZXhPZihjYWxsYmFjayk7XHJcbiAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0ZWFyZG93bnMucHVzaCh0ZWFyZG93bik7XHJcbiAgICAgICAgcmV0dXJuIHRlYXJkb3duO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gYmVmb3JlVW5sb2FkTGlzdGVuZXIoKSB7XHJcbiAgICAgICAgY29uc3QgeyBoaXN0b3J5IH0gPSB3aW5kb3c7XHJcbiAgICAgICAgaWYgKCFoaXN0b3J5LnN0YXRlKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgaGlzdG9yeS5yZXBsYWNlU3RhdGUoYXNzaWduKHt9LCBoaXN0b3J5LnN0YXRlLCB7IHNjcm9sbDogY29tcHV0ZVNjcm9sbFBvc2l0aW9uKCkgfSksICcnKTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGRlc3Ryb3koKSB7XHJcbiAgICAgICAgZm9yIChjb25zdCB0ZWFyZG93biBvZiB0ZWFyZG93bnMpXHJcbiAgICAgICAgICAgIHRlYXJkb3duKCk7XHJcbiAgICAgICAgdGVhcmRvd25zID0gW107XHJcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvcHN0YXRlJywgcG9wU3RhdGVIYW5kbGVyKTtcclxuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgYmVmb3JlVW5sb2FkTGlzdGVuZXIpO1xyXG4gICAgfVxyXG4gICAgLy8gc2V0dXAgdGhlIGxpc3RlbmVycyBhbmQgcHJlcGFyZSB0ZWFyZG93biBjYWxsYmFja3NcclxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdwb3BzdGF0ZScsIHBvcFN0YXRlSGFuZGxlcik7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgYmVmb3JlVW5sb2FkTGlzdGVuZXIpO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBwYXVzZUxpc3RlbmVycyxcclxuICAgICAgICBsaXN0ZW4sXHJcbiAgICAgICAgZGVzdHJveSxcclxuICAgIH07XHJcbn1cclxuLyoqXHJcbiAqIENyZWF0ZXMgYSBzdGF0ZSBvYmplY3RcclxuICovXHJcbmZ1bmN0aW9uIGJ1aWxkU3RhdGUoYmFjaywgY3VycmVudCwgZm9yd2FyZCwgcmVwbGFjZWQgPSBmYWxzZSwgY29tcHV0ZVNjcm9sbCA9IGZhbHNlKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGJhY2ssXHJcbiAgICAgICAgY3VycmVudCxcclxuICAgICAgICBmb3J3YXJkLFxyXG4gICAgICAgIHJlcGxhY2VkLFxyXG4gICAgICAgIHBvc2l0aW9uOiB3aW5kb3cuaGlzdG9yeS5sZW5ndGgsXHJcbiAgICAgICAgc2Nyb2xsOiBjb21wdXRlU2Nyb2xsID8gY29tcHV0ZVNjcm9sbFBvc2l0aW9uKCkgOiBudWxsLFxyXG4gICAgfTtcclxufVxyXG5mdW5jdGlvbiB1c2VIaXN0b3J5U3RhdGVOYXZpZ2F0aW9uKGJhc2UpIHtcclxuICAgIGNvbnN0IHsgaGlzdG9yeSwgbG9jYXRpb24gfSA9IHdpbmRvdztcclxuICAgIC8vIHByaXZhdGUgdmFyaWFibGVzXHJcbiAgICBjb25zdCBjdXJyZW50TG9jYXRpb24gPSB7XHJcbiAgICAgICAgdmFsdWU6IGNyZWF0ZUN1cnJlbnRMb2NhdGlvbihiYXNlLCBsb2NhdGlvbiksXHJcbiAgICB9O1xyXG4gICAgY29uc3QgaGlzdG9yeVN0YXRlID0geyB2YWx1ZTogaGlzdG9yeS5zdGF0ZSB9O1xyXG4gICAgLy8gYnVpbGQgY3VycmVudCBoaXN0b3J5IGVudHJ5IGFzIHRoaXMgaXMgYSBmcmVzaCBuYXZpZ2F0aW9uXHJcbiAgICBpZiAoIWhpc3RvcnlTdGF0ZS52YWx1ZSkge1xyXG4gICAgICAgIGNoYW5nZUxvY2F0aW9uKGN1cnJlbnRMb2NhdGlvbi52YWx1ZSwge1xyXG4gICAgICAgICAgICBiYWNrOiBudWxsLFxyXG4gICAgICAgICAgICBjdXJyZW50OiBjdXJyZW50TG9jYXRpb24udmFsdWUsXHJcbiAgICAgICAgICAgIGZvcndhcmQ6IG51bGwsXHJcbiAgICAgICAgICAgIC8vIHRoZSBsZW5ndGggaXMgb2ZmIGJ5IG9uZSwgd2UgbmVlZCB0byBkZWNyZWFzZSBpdFxyXG4gICAgICAgICAgICBwb3NpdGlvbjogaGlzdG9yeS5sZW5ndGggLSAxLFxyXG4gICAgICAgICAgICByZXBsYWNlZDogdHJ1ZSxcclxuICAgICAgICAgICAgLy8gZG9uJ3QgYWRkIGEgc2Nyb2xsIGFzIHRoZSB1c2VyIG1heSBoYXZlIGFuIGFuY2hvciBhbmQgd2Ugd2FudFxyXG4gICAgICAgICAgICAvLyBzY3JvbGxCZWhhdmlvciB0byBiZSB0cmlnZ2VyZWQgd2l0aG91dCBhIHNhdmVkIHBvc2l0aW9uXHJcbiAgICAgICAgICAgIHNjcm9sbDogbnVsbCxcclxuICAgICAgICB9LCB0cnVlKTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGNoYW5nZUxvY2F0aW9uKHRvLCBzdGF0ZSwgcmVwbGFjZSkge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIGlmIGEgYmFzZSB0YWcgaXMgcHJvdmlkZWQgYW5kIHdlIGFyZSBvbiBhIG5vcm1hbCBkb21haW4sIHdlIGhhdmUgdG9cclxuICAgICAgICAgKiByZXNwZWN0IHRoZSBwcm92aWRlZCBgYmFzZWAgYXR0cmlidXRlIGJlY2F1c2UgcHVzaFN0YXRlKCkgd2lsbCB1c2UgaXQgYW5kXHJcbiAgICAgICAgICogcG90ZW50aWFsbHkgZXJhc2UgYW55dGhpbmcgYmVmb3JlIHRoZSBgI2AgbGlrZSBhdFxyXG4gICAgICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS92dWVqcy92dWUtcm91dGVyLW5leHQvaXNzdWVzLzY4NSB3aGVyZSBhIGJhc2Ugb2ZcclxuICAgICAgICAgKiBgL2ZvbGRlci8jYCBidXQgYSBiYXNlIG9mIGAvYCB3b3VsZCBlcmFzZSB0aGUgYC9mb2xkZXIvYCBzZWN0aW9uLiBJZlxyXG4gICAgICAgICAqIHRoZXJlIGlzIG5vIGhvc3QsIHRoZSBgPGJhc2U+YCB0YWcgbWFrZXMgbm8gc2Vuc2UgYW5kIGlmIHRoZXJlIGlzbid0IGFcclxuICAgICAgICAgKiBiYXNlIHRhZyB3ZSBjYW4ganVzdCB1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgYCNgLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbnN0IGhhc2hJbmRleCA9IGJhc2UuaW5kZXhPZignIycpO1xyXG4gICAgICAgIGNvbnN0IHVybCA9IGhhc2hJbmRleCA+IC0xXHJcbiAgICAgICAgICAgID8gKGxvY2F0aW9uLmhvc3QgJiYgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYmFzZScpXHJcbiAgICAgICAgICAgICAgICA/IGJhc2VcclxuICAgICAgICAgICAgICAgIDogYmFzZS5zbGljZShoYXNoSW5kZXgpKSArIHRvXHJcbiAgICAgICAgICAgIDogY3JlYXRlQmFzZUxvY2F0aW9uKCkgKyBiYXNlICsgdG87XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgLy8gQlJPV1NFUiBRVUlSS1xyXG4gICAgICAgICAgICAvLyBOT1RFOiBTYWZhcmkgdGhyb3dzIGEgU2VjdXJpdHlFcnJvciB3aGVuIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiAxMDAgdGltZXMgaW4gMzAgc2Vjb25kc1xyXG4gICAgICAgICAgICBoaXN0b3J5W3JlcGxhY2UgPyAncmVwbGFjZVN0YXRlJyA6ICdwdXNoU3RhdGUnXShzdGF0ZSwgJycsIHVybCk7XHJcbiAgICAgICAgICAgIGhpc3RvcnlTdGF0ZS52YWx1ZSA9IHN0YXRlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oJ0Vycm9yIHdpdGggcHVzaC9yZXBsYWNlIFN0YXRlJywgZXJyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBGb3JjZSB0aGUgbmF2aWdhdGlvbiwgdGhpcyBhbHNvIHJlc2V0cyB0aGUgY2FsbCBjb3VudFxyXG4gICAgICAgICAgICBsb2NhdGlvbltyZXBsYWNlID8gJ3JlcGxhY2UnIDogJ2Fzc2lnbiddKHVybCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gcmVwbGFjZSh0bywgZGF0YSkge1xyXG4gICAgICAgIGNvbnN0IHN0YXRlID0gYXNzaWduKHt9LCBoaXN0b3J5LnN0YXRlLCBidWlsZFN0YXRlKGhpc3RvcnlTdGF0ZS52YWx1ZS5iYWNrLCBcclxuICAgICAgICAvLyBrZWVwIGJhY2sgYW5kIGZvcndhcmQgZW50cmllcyBidXQgb3ZlcnJpZGUgY3VycmVudCBwb3NpdGlvblxyXG4gICAgICAgIHRvLCBoaXN0b3J5U3RhdGUudmFsdWUuZm9yd2FyZCwgdHJ1ZSksIGRhdGEsIHsgcG9zaXRpb246IGhpc3RvcnlTdGF0ZS52YWx1ZS5wb3NpdGlvbiB9KTtcclxuICAgICAgICBjaGFuZ2VMb2NhdGlvbih0bywgc3RhdGUsIHRydWUpO1xyXG4gICAgICAgIGN1cnJlbnRMb2NhdGlvbi52YWx1ZSA9IHRvO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gcHVzaCh0bywgZGF0YSkge1xyXG4gICAgICAgIC8vIEFkZCB0byBjdXJyZW50IGVudHJ5IHRoZSBpbmZvcm1hdGlvbiBvZiB3aGVyZSB3ZSBhcmUgZ29pbmdcclxuICAgICAgICAvLyBhcyB3ZWxsIGFzIHNhdmluZyB0aGUgY3VycmVudCBwb3NpdGlvblxyXG4gICAgICAgIGNvbnN0IGN1cnJlbnRTdGF0ZSA9IGFzc2lnbih7fSwgXHJcbiAgICAgICAgLy8gdXNlIGN1cnJlbnQgaGlzdG9yeSBzdGF0ZSB0byBncmFjZWZ1bGx5IGhhbmRsZSBhIHdyb25nIGNhbGwgdG9cclxuICAgICAgICAvLyBoaXN0b3J5LnJlcGxhY2VTdGF0ZVxyXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS92dWVqcy92dWUtcm91dGVyLW5leHQvaXNzdWVzLzM2NlxyXG4gICAgICAgIGhpc3RvcnlTdGF0ZS52YWx1ZSwgaGlzdG9yeS5zdGF0ZSwge1xyXG4gICAgICAgICAgICBmb3J3YXJkOiB0byxcclxuICAgICAgICAgICAgc2Nyb2xsOiBjb21wdXRlU2Nyb2xsUG9zaXRpb24oKSxcclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFoaXN0b3J5LnN0YXRlKSB7XHJcbiAgICAgICAgICAgIHdhcm4oYGhpc3Rvcnkuc3RhdGUgc2VlbXMgdG8gaGF2ZSBiZWVuIG1hbnVhbGx5IHJlcGxhY2VkIHdpdGhvdXQgcHJlc2VydmluZyB0aGUgbmVjZXNzYXJ5IHZhbHVlcy4gTWFrZSBzdXJlIHRvIHByZXNlcnZlIGV4aXN0aW5nIGhpc3Rvcnkgc3RhdGUgaWYgeW91IGFyZSBtYW51YWxseSBjYWxsaW5nIGhpc3RvcnkucmVwbGFjZVN0YXRlOlxcblxcbmAgK1xyXG4gICAgICAgICAgICAgICAgYGhpc3RvcnkucmVwbGFjZVN0YXRlKGhpc3Rvcnkuc3RhdGUsICcnLCB1cmwpXFxuXFxuYCArXHJcbiAgICAgICAgICAgICAgICBgWW91IGNhbiBmaW5kIG1vcmUgaW5mb3JtYXRpb24gYXQgaHR0cHM6Ly9uZXh0LnJvdXRlci52dWVqcy5vcmcvZ3VpZGUvbWlncmF0aW9uLyN1c2FnZS1vZi1oaXN0b3J5LXN0YXRlLmApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjaGFuZ2VMb2NhdGlvbihjdXJyZW50U3RhdGUuY3VycmVudCwgY3VycmVudFN0YXRlLCB0cnVlKTtcclxuICAgICAgICBjb25zdCBzdGF0ZSA9IGFzc2lnbih7fSwgYnVpbGRTdGF0ZShjdXJyZW50TG9jYXRpb24udmFsdWUsIHRvLCBudWxsKSwgeyBwb3NpdGlvbjogY3VycmVudFN0YXRlLnBvc2l0aW9uICsgMSB9LCBkYXRhKTtcclxuICAgICAgICBjaGFuZ2VMb2NhdGlvbih0bywgc3RhdGUsIGZhbHNlKTtcclxuICAgICAgICBjdXJyZW50TG9jYXRpb24udmFsdWUgPSB0bztcclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgbG9jYXRpb246IGN1cnJlbnRMb2NhdGlvbixcclxuICAgICAgICBzdGF0ZTogaGlzdG9yeVN0YXRlLFxyXG4gICAgICAgIHB1c2gsXHJcbiAgICAgICAgcmVwbGFjZSxcclxuICAgIH07XHJcbn1cclxuLyoqXHJcbiAqIENyZWF0ZXMgYW4gSFRNTDUgaGlzdG9yeS4gTW9zdCBjb21tb24gaGlzdG9yeSBmb3Igc2luZ2xlIHBhZ2UgYXBwbGljYXRpb25zLlxyXG4gKlxyXG4gKiBAcGFyYW0gYmFzZSAtXHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVXZWJIaXN0b3J5KGJhc2UpIHtcclxuICAgIGJhc2UgPSBub3JtYWxpemVCYXNlKGJhc2UpO1xyXG4gICAgY29uc3QgaGlzdG9yeU5hdmlnYXRpb24gPSB1c2VIaXN0b3J5U3RhdGVOYXZpZ2F0aW9uKGJhc2UpO1xyXG4gICAgY29uc3QgaGlzdG9yeUxpc3RlbmVycyA9IHVzZUhpc3RvcnlMaXN0ZW5lcnMoYmFzZSwgaGlzdG9yeU5hdmlnYXRpb24uc3RhdGUsIGhpc3RvcnlOYXZpZ2F0aW9uLmxvY2F0aW9uLCBoaXN0b3J5TmF2aWdhdGlvbi5yZXBsYWNlKTtcclxuICAgIGZ1bmN0aW9uIGdvKGRlbHRhLCB0cmlnZ2VyTGlzdGVuZXJzID0gdHJ1ZSkge1xyXG4gICAgICAgIGlmICghdHJpZ2dlckxpc3RlbmVycylcclxuICAgICAgICAgICAgaGlzdG9yeUxpc3RlbmVycy5wYXVzZUxpc3RlbmVycygpO1xyXG4gICAgICAgIGhpc3RvcnkuZ28oZGVsdGEpO1xyXG4gICAgfVxyXG4gICAgY29uc3Qgcm91dGVySGlzdG9yeSA9IGFzc2lnbih7XHJcbiAgICAgICAgLy8gaXQncyBvdmVycmlkZGVuIHJpZ2h0IGFmdGVyXHJcbiAgICAgICAgbG9jYXRpb246ICcnLFxyXG4gICAgICAgIGJhc2UsXHJcbiAgICAgICAgZ28sXHJcbiAgICAgICAgY3JlYXRlSHJlZjogY3JlYXRlSHJlZi5iaW5kKG51bGwsIGJhc2UpLFxyXG4gICAgfSwgaGlzdG9yeU5hdmlnYXRpb24sIGhpc3RvcnlMaXN0ZW5lcnMpO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJvdXRlckhpc3RvcnksICdsb2NhdGlvbicsIHtcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGdldDogKCkgPT4gaGlzdG9yeU5hdmlnYXRpb24ubG9jYXRpb24udmFsdWUsXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyb3V0ZXJIaXN0b3J5LCAnc3RhdGUnLCB7XHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBnZXQ6ICgpID0+IGhpc3RvcnlOYXZpZ2F0aW9uLnN0YXRlLnZhbHVlLFxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gcm91dGVySGlzdG9yeTtcclxufVxuXG4vKipcclxuICogQ3JlYXRlcyBhIGluLW1lbW9yeSBiYXNlZCBoaXN0b3J5LiBUaGUgbWFpbiBwdXJwb3NlIG9mIHRoaXMgaGlzdG9yeSBpcyB0byBoYW5kbGUgU1NSLiBJdCBzdGFydHMgaW4gYSBzcGVjaWFsIGxvY2F0aW9uIHRoYXQgaXMgbm93aGVyZS5cclxuICogSXQncyB1cCB0byB0aGUgdXNlciB0byByZXBsYWNlIHRoYXQgbG9jYXRpb24gd2l0aCB0aGUgc3RhcnRlciBsb2NhdGlvbiBieSBlaXRoZXIgY2FsbGluZyBgcm91dGVyLnB1c2hgIG9yIGByb3V0ZXIucmVwbGFjZWAuXHJcbiAqXHJcbiAqIEBwYXJhbSBiYXNlIC0gQmFzZSBhcHBsaWVkIHRvIGFsbCB1cmxzLCBkZWZhdWx0cyB0byAnLydcclxuICogQHJldHVybnMgYSBoaXN0b3J5IG9iamVjdCB0aGF0IGNhbiBiZSBwYXNzZWQgdG8gdGhlIHJvdXRlciBjb25zdHJ1Y3RvclxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlTWVtb3J5SGlzdG9yeShiYXNlID0gJycpIHtcclxuICAgIGxldCBsaXN0ZW5lcnMgPSBbXTtcclxuICAgIGxldCBxdWV1ZSA9IFtTVEFSVF07XHJcbiAgICBsZXQgcG9zaXRpb24gPSAwO1xyXG4gICAgYmFzZSA9IG5vcm1hbGl6ZUJhc2UoYmFzZSk7XHJcbiAgICBmdW5jdGlvbiBzZXRMb2NhdGlvbihsb2NhdGlvbikge1xyXG4gICAgICAgIHBvc2l0aW9uKys7XHJcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSBxdWV1ZS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgLy8gd2UgYXJlIGF0IHRoZSBlbmQsIHdlIGNhbiBzaW1wbHkgYXBwZW5kIGEgbmV3IGVudHJ5XHJcbiAgICAgICAgICAgIHF1ZXVlLnB1c2gobG9jYXRpb24pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gd2UgYXJlIGluIHRoZSBtaWRkbGUsIHdlIHJlbW92ZSBldmVyeXRoaW5nIGZyb20gaGVyZSBpbiB0aGUgcXVldWVcclxuICAgICAgICAgICAgcXVldWUuc3BsaWNlKHBvc2l0aW9uKTtcclxuICAgICAgICAgICAgcXVldWUucHVzaChsb2NhdGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gdHJpZ2dlckxpc3RlbmVycyh0bywgZnJvbSwgeyBkaXJlY3Rpb24sIGRlbHRhIH0pIHtcclxuICAgICAgICBjb25zdCBpbmZvID0ge1xyXG4gICAgICAgICAgICBkaXJlY3Rpb24sXHJcbiAgICAgICAgICAgIGRlbHRhLFxyXG4gICAgICAgICAgICB0eXBlOiBOYXZpZ2F0aW9uVHlwZS5wb3AsXHJcbiAgICAgICAgfTtcclxuICAgICAgICBmb3IgKGNvbnN0IGNhbGxiYWNrIG9mIGxpc3RlbmVycykge1xyXG4gICAgICAgICAgICBjYWxsYmFjayh0bywgZnJvbSwgaW5mbyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3Qgcm91dGVySGlzdG9yeSA9IHtcclxuICAgICAgICAvLyByZXdyaXR0ZW4gYnkgT2JqZWN0LmRlZmluZVByb3BlcnR5XHJcbiAgICAgICAgbG9jYXRpb246IFNUQVJULFxyXG4gICAgICAgIC8vIFRPRE86IHNob3VsZCBiZSBrZXB0IGluIHF1ZXVlXHJcbiAgICAgICAgc3RhdGU6IHt9LFxyXG4gICAgICAgIGJhc2UsXHJcbiAgICAgICAgY3JlYXRlSHJlZjogY3JlYXRlSHJlZi5iaW5kKG51bGwsIGJhc2UpLFxyXG4gICAgICAgIHJlcGxhY2UodG8pIHtcclxuICAgICAgICAgICAgLy8gcmVtb3ZlIGN1cnJlbnQgZW50cnkgYW5kIGRlY3JlbWVudCBwb3NpdGlvblxyXG4gICAgICAgICAgICBxdWV1ZS5zcGxpY2UocG9zaXRpb24tLSwgMSk7XHJcbiAgICAgICAgICAgIHNldExvY2F0aW9uKHRvKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHB1c2godG8sIGRhdGEpIHtcclxuICAgICAgICAgICAgc2V0TG9jYXRpb24odG8pO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgbGlzdGVuKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIGxpc3RlbmVycy5wdXNoKGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gbGlzdGVuZXJzLmluZGV4T2YoY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpXHJcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSxcclxuICAgICAgICBkZXN0cm95KCkge1xyXG4gICAgICAgICAgICBsaXN0ZW5lcnMgPSBbXTtcclxuICAgICAgICAgICAgcXVldWUgPSBbU1RBUlRdO1xyXG4gICAgICAgICAgICBwb3NpdGlvbiA9IDA7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBnbyhkZWx0YSwgc2hvdWxkVHJpZ2dlciA9IHRydWUpIHtcclxuICAgICAgICAgICAgY29uc3QgZnJvbSA9IHRoaXMubG9jYXRpb247XHJcbiAgICAgICAgICAgIGNvbnN0IGRpcmVjdGlvbiA9IFxyXG4gICAgICAgICAgICAvLyB3ZSBhcmUgY29uc2lkZXJpbmcgZGVsdGEgPT09IDAgZ29pbmcgZm9yd2FyZCwgYnV0IGluIGFic3RyYWN0IG1vZGVcclxuICAgICAgICAgICAgLy8gdXNpbmcgMCBmb3IgdGhlIGRlbHRhIGRvZXNuJ3QgbWFrZSBzZW5zZSBsaWtlIGl0IGRvZXMgaW4gaHRtbDUgd2hlcmVcclxuICAgICAgICAgICAgLy8gaXQgcmVsb2FkcyB0aGUgcGFnZVxyXG4gICAgICAgICAgICBkZWx0YSA8IDAgPyBOYXZpZ2F0aW9uRGlyZWN0aW9uLmJhY2sgOiBOYXZpZ2F0aW9uRGlyZWN0aW9uLmZvcndhcmQ7XHJcbiAgICAgICAgICAgIHBvc2l0aW9uID0gTWF0aC5tYXgoMCwgTWF0aC5taW4ocG9zaXRpb24gKyBkZWx0YSwgcXVldWUubGVuZ3RoIC0gMSkpO1xyXG4gICAgICAgICAgICBpZiAoc2hvdWxkVHJpZ2dlcikge1xyXG4gICAgICAgICAgICAgICAgdHJpZ2dlckxpc3RlbmVycyh0aGlzLmxvY2F0aW9uLCBmcm9tLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgIGRlbHRhLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgfTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyb3V0ZXJIaXN0b3J5LCAnbG9jYXRpb24nLCB7XHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBnZXQ6ICgpID0+IHF1ZXVlW3Bvc2l0aW9uXSxcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHJvdXRlckhpc3Rvcnk7XHJcbn1cblxuLyoqXHJcbiAqIENyZWF0ZXMgYSBoYXNoIGhpc3RvcnkuIFVzZWZ1bCBmb3Igd2ViIGFwcGxpY2F0aW9ucyB3aXRoIG5vIGhvc3QgKGUuZy5cclxuICogYGZpbGU6Ly9gKSBvciB3aGVuIGNvbmZpZ3VyaW5nIGEgc2VydmVyIHRvIGhhbmRsZSBhbnkgVVJMIGlzIG5vdCBwb3NzaWJsZS5cclxuICpcclxuICogQHBhcmFtIGJhc2UgLSBvcHRpb25hbCBiYXNlIHRvIHByb3ZpZGUuIERlZmF1bHRzIHRvIGBsb2NhdGlvbi5wYXRobmFtZSArXHJcbiAqIGxvY2F0aW9uLnNlYXJjaGAgSWYgdGhlcmUgaXMgYSBgPGJhc2U+YCB0YWcgaW4gdGhlIGBoZWFkYCwgaXRzIHZhbHVlIHdpbGwgYmVcclxuICogaWdub3JlZCBpbiBmYXZvciBvZiB0aGlzIHBhcmFtZXRlciAqKmJ1dCBub3RlIGl0IGFmZmVjdHMgYWxsIHRoZVxyXG4gKiBoaXN0b3J5LnB1c2hTdGF0ZSgpIGNhbGxzKiosIG1lYW5pbmcgdGhhdCBpZiB5b3UgdXNlIGEgYDxiYXNlPmAgdGFnLCBpdCdzXHJcbiAqIGBocmVmYCB2YWx1ZSAqKmhhcyB0byBtYXRjaCB0aGlzIHBhcmFtZXRlcioqIChpZ25vcmluZyBhbnl0aGluZyBhZnRlciB0aGVcclxuICogYCNgKS5cclxuICpcclxuICogQGV4YW1wbGVcclxuICogYGBganNcclxuICogLy8gYXQgaHR0cHM6Ly9leGFtcGxlLmNvbS9mb2xkZXJcclxuICogY3JlYXRlV2ViSGFzaEhpc3RvcnkoKSAvLyBnaXZlcyBhIHVybCBvZiBgaHR0cHM6Ly9leGFtcGxlLmNvbS9mb2xkZXIjYFxyXG4gKiBjcmVhdGVXZWJIYXNoSGlzdG9yeSgnL2ZvbGRlci8nKSAvLyBnaXZlcyBhIHVybCBvZiBgaHR0cHM6Ly9leGFtcGxlLmNvbS9mb2xkZXIvI2BcclxuICogLy8gaWYgdGhlIGAjYCBpcyBwcm92aWRlZCBpbiB0aGUgYmFzZSwgaXQgd29uJ3QgYmUgYWRkZWQgYnkgYGNyZWF0ZVdlYkhhc2hIaXN0b3J5YFxyXG4gKiBjcmVhdGVXZWJIYXNoSGlzdG9yeSgnL2ZvbGRlci8jL2FwcC8nKSAvLyBnaXZlcyBhIHVybCBvZiBgaHR0cHM6Ly9leGFtcGxlLmNvbS9mb2xkZXIvIy9hcHAvYFxyXG4gKiAvLyB5b3Ugc2hvdWxkIGF2b2lkIGRvaW5nIHRoaXMgYmVjYXVzZSBpdCBjaGFuZ2VzIHRoZSBvcmlnaW5hbCB1cmwgYW5kIGJyZWFrcyBjb3B5aW5nIHVybHNcclxuICogY3JlYXRlV2ViSGFzaEhpc3RvcnkoJy9vdGhlci1mb2xkZXIvJykgLy8gZ2l2ZXMgYSB1cmwgb2YgYGh0dHBzOi8vZXhhbXBsZS5jb20vb3RoZXItZm9sZGVyLyNgXHJcbiAqXHJcbiAqIC8vIGF0IGZpbGU6Ly8vdXNyL2V0Yy9mb2xkZXIvaW5kZXguaHRtbFxyXG4gKiAvLyBmb3IgbG9jYXRpb25zIHdpdGggbm8gYGhvc3RgLCB0aGUgYmFzZSBpcyBpZ25vcmVkXHJcbiAqIGNyZWF0ZVdlYkhhc2hIaXN0b3J5KCcvaUFtSWdub3JlZCcpIC8vIGdpdmVzIGEgdXJsIG9mIGBmaWxlOi8vL3Vzci9ldGMvZm9sZGVyL2luZGV4Lmh0bWwjYFxyXG4gKiBgYGBcclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZVdlYkhhc2hIaXN0b3J5KGJhc2UpIHtcclxuICAgIC8vIE1ha2Ugc3VyZSB0aGlzIGltcGxlbWVudGF0aW9uIGlzIGZpbmUgaW4gdGVybXMgb2YgZW5jb2RpbmcsIHNwZWNpYWxseSBmb3IgSUUxMVxyXG4gICAgLy8gZm9yIGBmaWxlOi8vYCwgZGlyZWN0bHkgdXNlIHRoZSBwYXRobmFtZSBhbmQgaWdub3JlIHRoZSBiYXNlXHJcbiAgICAvLyBsb2NhdGlvbi5wYXRobmFtZSBjb250YWlucyBhbiBpbml0aWFsIGAvYCBldmVuIGF0IHRoZSByb290OiBgaHR0cHM6Ly9leGFtcGxlLmNvbWBcclxuICAgIGJhc2UgPSBsb2NhdGlvbi5ob3N0ID8gYmFzZSB8fCBsb2NhdGlvbi5wYXRobmFtZSArIGxvY2F0aW9uLnNlYXJjaCA6ICcnO1xyXG4gICAgLy8gYWxsb3cgdGhlIHVzZXIgdG8gcHJvdmlkZSBhIGAjYCBpbiB0aGUgbWlkZGxlOiBgL2Jhc2UvIy9hcHBgXHJcbiAgICBpZiAoIWJhc2UuaW5jbHVkZXMoJyMnKSlcclxuICAgICAgICBiYXNlICs9ICcjJztcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIWJhc2UuZW5kc1dpdGgoJyMvJykgJiYgIWJhc2UuZW5kc1dpdGgoJyMnKSkge1xyXG4gICAgICAgIHdhcm4oYEEgaGFzaCBiYXNlIG11c3QgZW5kIHdpdGggYSBcIiNcIjpcXG5cIiR7YmFzZX1cIiBzaG91bGQgYmUgXCIke2Jhc2UucmVwbGFjZSgvIy4qJC8sICcjJyl9XCIuYCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY3JlYXRlV2ViSGlzdG9yeShiYXNlKTtcclxufVxuXG5mdW5jdGlvbiBpc1JvdXRlTG9jYXRpb24ocm91dGUpIHtcclxuICAgIHJldHVybiB0eXBlb2Ygcm91dGUgPT09ICdzdHJpbmcnIHx8IChyb3V0ZSAmJiB0eXBlb2Ygcm91dGUgPT09ICdvYmplY3QnKTtcclxufVxyXG5mdW5jdGlvbiBpc1JvdXRlTmFtZShuYW1lKSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBuYW1lID09PSAnc3ltYm9sJztcclxufVxuXG4vKipcclxuICogSW5pdGlhbCByb3V0ZSBsb2NhdGlvbiB3aGVyZSB0aGUgcm91dGVyIGlzLiBDYW4gYmUgdXNlZCBpbiBuYXZpZ2F0aW9uIGd1YXJkc1xyXG4gKiB0byBkaWZmZXJlbnRpYXRlIHRoZSBpbml0aWFsIG5hdmlnYXRpb24uXHJcbiAqXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYGpzXHJcbiAqIGltcG9ydCB7IFNUQVJUX0xPQ0FUSU9OIH0gZnJvbSAndnVlLXJvdXRlcidcclxuICpcclxuICogcm91dGVyLmJlZm9yZUVhY2goKHRvLCBmcm9tKSA9PiB7XHJcbiAqICAgaWYgKGZyb20gPT09IFNUQVJUX0xPQ0FUSU9OKSB7XHJcbiAqICAgICAvLyBpbml0aWFsIG5hdmlnYXRpb25cclxuICogICB9XHJcbiAqIH0pXHJcbiAqIGBgYFxyXG4gKi9cclxuY29uc3QgU1RBUlRfTE9DQVRJT05fTk9STUFMSVpFRCA9IHtcclxuICAgIHBhdGg6ICcvJyxcclxuICAgIG5hbWU6IHVuZGVmaW5lZCxcclxuICAgIHBhcmFtczoge30sXHJcbiAgICBxdWVyeToge30sXHJcbiAgICBoYXNoOiAnJyxcclxuICAgIGZ1bGxQYXRoOiAnLycsXHJcbiAgICBtYXRjaGVkOiBbXSxcclxuICAgIG1ldGE6IHt9LFxyXG4gICAgcmVkaXJlY3RlZEZyb206IHVuZGVmaW5lZCxcclxufTtcblxuY29uc3QgTmF2aWdhdGlvbkZhaWx1cmVTeW1ib2wgPSAvKiNfX1BVUkVfXyovIFBvbHlTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ25hdmlnYXRpb24gZmFpbHVyZScgOiAnbmYnKTtcclxuLyoqXHJcbiAqIEVudW1lcmF0aW9uIHdpdGggYWxsIHBvc3NpYmxlIHR5cGVzIGZvciBuYXZpZ2F0aW9uIGZhaWx1cmVzLiBDYW4gYmUgcGFzc2VkIHRvXHJcbiAqIHtAbGluayBpc05hdmlnYXRpb25GYWlsdXJlfSB0byBjaGVjayBmb3Igc3BlY2lmaWMgZmFpbHVyZXMuXHJcbiAqL1xyXG52YXIgTmF2aWdhdGlvbkZhaWx1cmVUeXBlO1xyXG4oZnVuY3Rpb24gKE5hdmlnYXRpb25GYWlsdXJlVHlwZSkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBBbiBhYm9ydGVkIG5hdmlnYXRpb24gaXMgYSBuYXZpZ2F0aW9uIHRoYXQgZmFpbGVkIGJlY2F1c2UgYSBuYXZpZ2F0aW9uXHJcbiAgICAgKiBndWFyZCByZXR1cm5lZCBgZmFsc2VgIG9yIGNhbGxlZCBgbmV4dChmYWxzZSlgXHJcbiAgICAgKi9cclxuICAgIE5hdmlnYXRpb25GYWlsdXJlVHlwZVtOYXZpZ2F0aW9uRmFpbHVyZVR5cGVbXCJhYm9ydGVkXCJdID0gNF0gPSBcImFib3J0ZWRcIjtcclxuICAgIC8qKlxyXG4gICAgICogQSBjYW5jZWxsZWQgbmF2aWdhdGlvbiBpcyBhIG5hdmlnYXRpb24gdGhhdCBmYWlsZWQgYmVjYXVzZSBhIG1vcmUgcmVjZW50XHJcbiAgICAgKiBuYXZpZ2F0aW9uIGZpbmlzaGVkIHN0YXJ0ZWQgKG5vdCBuZWNlc3NhcmlseSBmaW5pc2hlZCkuXHJcbiAgICAgKi9cclxuICAgIE5hdmlnYXRpb25GYWlsdXJlVHlwZVtOYXZpZ2F0aW9uRmFpbHVyZVR5cGVbXCJjYW5jZWxsZWRcIl0gPSA4XSA9IFwiY2FuY2VsbGVkXCI7XHJcbiAgICAvKipcclxuICAgICAqIEEgZHVwbGljYXRlZCBuYXZpZ2F0aW9uIGlzIGEgbmF2aWdhdGlvbiB0aGF0IGZhaWxlZCBiZWNhdXNlIGl0IHdhc1xyXG4gICAgICogaW5pdGlhdGVkIHdoaWxlIGFscmVhZHkgYmVpbmcgYXQgdGhlIGV4YWN0IHNhbWUgbG9jYXRpb24uXHJcbiAgICAgKi9cclxuICAgIE5hdmlnYXRpb25GYWlsdXJlVHlwZVtOYXZpZ2F0aW9uRmFpbHVyZVR5cGVbXCJkdXBsaWNhdGVkXCJdID0gMTZdID0gXCJkdXBsaWNhdGVkXCI7XHJcbn0pKE5hdmlnYXRpb25GYWlsdXJlVHlwZSB8fCAoTmF2aWdhdGlvbkZhaWx1cmVUeXBlID0ge30pKTtcclxuLy8gREVWIG9ubHkgZGVidWcgbWVzc2FnZXNcclxuY29uc3QgRXJyb3JUeXBlTWVzc2FnZXMgPSB7XHJcbiAgICBbMSAvKiBNQVRDSEVSX05PVF9GT1VORCAqL10oeyBsb2NhdGlvbiwgY3VycmVudExvY2F0aW9uIH0pIHtcclxuICAgICAgICByZXR1cm4gYE5vIG1hdGNoIGZvclxcbiAke0pTT04uc3RyaW5naWZ5KGxvY2F0aW9uKX0ke2N1cnJlbnRMb2NhdGlvblxyXG4gICAgICAgICAgICA/ICdcXG53aGlsZSBiZWluZyBhdFxcbicgKyBKU09OLnN0cmluZ2lmeShjdXJyZW50TG9jYXRpb24pXHJcbiAgICAgICAgICAgIDogJyd9YDtcclxuICAgIH0sXHJcbiAgICBbMiAvKiBOQVZJR0FUSU9OX0dVQVJEX1JFRElSRUNUICovXSh7IGZyb20sIHRvLCB9KSB7XHJcbiAgICAgICAgcmV0dXJuIGBSZWRpcmVjdGVkIGZyb20gXCIke2Zyb20uZnVsbFBhdGh9XCIgdG8gXCIke3N0cmluZ2lmeVJvdXRlKHRvKX1cIiB2aWEgYSBuYXZpZ2F0aW9uIGd1YXJkLmA7XHJcbiAgICB9LFxyXG4gICAgWzQgLyogTkFWSUdBVElPTl9BQk9SVEVEICovXSh7IGZyb20sIHRvIH0pIHtcclxuICAgICAgICByZXR1cm4gYE5hdmlnYXRpb24gYWJvcnRlZCBmcm9tIFwiJHtmcm9tLmZ1bGxQYXRofVwiIHRvIFwiJHt0by5mdWxsUGF0aH1cIiB2aWEgYSBuYXZpZ2F0aW9uIGd1YXJkLmA7XHJcbiAgICB9LFxyXG4gICAgWzggLyogTkFWSUdBVElPTl9DQU5DRUxMRUQgKi9dKHsgZnJvbSwgdG8gfSkge1xyXG4gICAgICAgIHJldHVybiBgTmF2aWdhdGlvbiBjYW5jZWxsZWQgZnJvbSBcIiR7ZnJvbS5mdWxsUGF0aH1cIiB0byBcIiR7dG8uZnVsbFBhdGh9XCIgd2l0aCBhIG5ldyBuYXZpZ2F0aW9uLmA7XHJcbiAgICB9LFxyXG4gICAgWzE2IC8qIE5BVklHQVRJT05fRFVQTElDQVRFRCAqL10oeyBmcm9tLCB0byB9KSB7XHJcbiAgICAgICAgcmV0dXJuIGBBdm9pZGVkIHJlZHVuZGFudCBuYXZpZ2F0aW9uIHRvIGN1cnJlbnQgbG9jYXRpb246IFwiJHtmcm9tLmZ1bGxQYXRofVwiLmA7XHJcbiAgICB9LFxyXG59O1xyXG5mdW5jdGlvbiBjcmVhdGVSb3V0ZXJFcnJvcih0eXBlLCBwYXJhbXMpIHtcclxuICAgIC8vIGtlZXAgZnVsbCBlcnJvciBtZXNzYWdlcyBpbiBjanMgdmVyc2lvbnNcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgIXRydWUpIHtcclxuICAgICAgICByZXR1cm4gYXNzaWduKG5ldyBFcnJvcihFcnJvclR5cGVNZXNzYWdlc1t0eXBlXShwYXJhbXMpKSwge1xyXG4gICAgICAgICAgICB0eXBlLFxyXG4gICAgICAgICAgICBbTmF2aWdhdGlvbkZhaWx1cmVTeW1ib2xdOiB0cnVlLFxyXG4gICAgICAgIH0sIHBhcmFtcyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gYXNzaWduKG5ldyBFcnJvcigpLCB7XHJcbiAgICAgICAgICAgIHR5cGUsXHJcbiAgICAgICAgICAgIFtOYXZpZ2F0aW9uRmFpbHVyZVN5bWJvbF06IHRydWUsXHJcbiAgICAgICAgfSwgcGFyYW1zKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBpc05hdmlnYXRpb25GYWlsdXJlKGVycm9yLCB0eXBlKSB7XHJcbiAgICByZXR1cm4gKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiZcclxuICAgICAgICBOYXZpZ2F0aW9uRmFpbHVyZVN5bWJvbCBpbiBlcnJvciAmJlxyXG4gICAgICAgICh0eXBlID09IG51bGwgfHwgISEoZXJyb3IudHlwZSAmIHR5cGUpKSk7XHJcbn1cclxuY29uc3QgcHJvcGVydGllc1RvTG9nID0gWydwYXJhbXMnLCAncXVlcnknLCAnaGFzaCddO1xyXG5mdW5jdGlvbiBzdHJpbmdpZnlSb3V0ZSh0bykge1xyXG4gICAgaWYgKHR5cGVvZiB0byA9PT0gJ3N0cmluZycpXHJcbiAgICAgICAgcmV0dXJuIHRvO1xyXG4gICAgaWYgKCdwYXRoJyBpbiB0bylcclxuICAgICAgICByZXR1cm4gdG8ucGF0aDtcclxuICAgIGNvbnN0IGxvY2F0aW9uID0ge307XHJcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBwcm9wZXJ0aWVzVG9Mb2cpIHtcclxuICAgICAgICBpZiAoa2V5IGluIHRvKVxyXG4gICAgICAgICAgICBsb2NhdGlvbltrZXldID0gdG9ba2V5XTtcclxuICAgIH1cclxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShsb2NhdGlvbiwgbnVsbCwgMik7XHJcbn1cblxuLy8gZGVmYXVsdCBwYXR0ZXJuIGZvciBhIHBhcmFtOiBub24gZ3JlZWR5IGV2ZXJ5dGhpbmcgYnV0IC9cclxuY29uc3QgQkFTRV9QQVJBTV9QQVRURVJOID0gJ1teL10rPyc7XHJcbmNvbnN0IEJBU0VfUEFUSF9QQVJTRVJfT1BUSU9OUyA9IHtcclxuICAgIHNlbnNpdGl2ZTogZmFsc2UsXHJcbiAgICBzdHJpY3Q6IGZhbHNlLFxyXG4gICAgc3RhcnQ6IHRydWUsXHJcbiAgICBlbmQ6IHRydWUsXHJcbn07XHJcbi8vIFNwZWNpYWwgUmVnZXggY2hhcmFjdGVycyB0aGF0IG11c3QgYmUgZXNjYXBlZCBpbiBzdGF0aWMgdG9rZW5zXHJcbmNvbnN0IFJFR0VYX0NIQVJTX1JFID0gL1suKyo/XiR7fSgpW1xcXS9cXFxcXS9nO1xyXG4vKipcclxuICogQ3JlYXRlcyBhIHBhdGggcGFyc2VyIGZyb20gYW4gYXJyYXkgb2YgU2VnbWVudHMgKGEgc2VnbWVudCBpcyBhbiBhcnJheSBvZiBUb2tlbnMpXHJcbiAqXHJcbiAqIEBwYXJhbSBzZWdtZW50cyAtIGFycmF5IG9mIHNlZ21lbnRzIHJldHVybmVkIGJ5IHRva2VuaXplUGF0aFxyXG4gKiBAcGFyYW0gZXh0cmFPcHRpb25zIC0gb3B0aW9uYWwgb3B0aW9ucyBmb3IgdGhlIHJlZ2V4cFxyXG4gKiBAcmV0dXJucyBhIFBhdGhQYXJzZXJcclxuICovXHJcbmZ1bmN0aW9uIHRva2Vuc1RvUGFyc2VyKHNlZ21lbnRzLCBleHRyYU9wdGlvbnMpIHtcclxuICAgIGNvbnN0IG9wdGlvbnMgPSBhc3NpZ24oe30sIEJBU0VfUEFUSF9QQVJTRVJfT1BUSU9OUywgZXh0cmFPcHRpb25zKTtcclxuICAgIC8vIHRoZSBhbW91bnQgb2Ygc2NvcmVzIGlzIHRoZSBzYW1lIGFzIHRoZSBsZW5ndGggb2Ygc2VnbWVudHMgZXhjZXB0IGZvciB0aGUgcm9vdCBzZWdtZW50IFwiL1wiXHJcbiAgICBjb25zdCBzY29yZSA9IFtdO1xyXG4gICAgLy8gdGhlIHJlZ2V4cCBhcyBhIHN0cmluZ1xyXG4gICAgbGV0IHBhdHRlcm4gPSBvcHRpb25zLnN0YXJ0ID8gJ14nIDogJyc7XHJcbiAgICAvLyBleHRyYWN0ZWQga2V5c1xyXG4gICAgY29uc3Qga2V5cyA9IFtdO1xyXG4gICAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XHJcbiAgICAgICAgLy8gdGhlIHJvb3Qgc2VnbWVudCBuZWVkcyBzcGVjaWFsIHRyZWF0bWVudFxyXG4gICAgICAgIGNvbnN0IHNlZ21lbnRTY29yZXMgPSBzZWdtZW50Lmxlbmd0aCA/IFtdIDogWzkwIC8qIFJvb3QgKi9dO1xyXG4gICAgICAgIC8vIGFsbG93IHRyYWlsaW5nIHNsYXNoXHJcbiAgICAgICAgaWYgKG9wdGlvbnMuc3RyaWN0ICYmICFzZWdtZW50Lmxlbmd0aClcclxuICAgICAgICAgICAgcGF0dGVybiArPSAnLyc7XHJcbiAgICAgICAgZm9yIChsZXQgdG9rZW5JbmRleCA9IDA7IHRva2VuSW5kZXggPCBzZWdtZW50Lmxlbmd0aDsgdG9rZW5JbmRleCsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRva2VuID0gc2VnbWVudFt0b2tlbkluZGV4XTtcclxuICAgICAgICAgICAgLy8gcmVzZXRzIHRoZSBzY29yZSBpZiB3ZSBhcmUgaW5zaWRlIGEgc3ViIHNlZ21lbnQgLzphLW90aGVyLTpiXHJcbiAgICAgICAgICAgIGxldCBzdWJTZWdtZW50U2NvcmUgPSA0MCAvKiBTZWdtZW50ICovICtcclxuICAgICAgICAgICAgICAgIChvcHRpb25zLnNlbnNpdGl2ZSA/IDAuMjUgLyogQm9udXNDYXNlU2Vuc2l0aXZlICovIDogMCk7XHJcbiAgICAgICAgICAgIGlmICh0b2tlbi50eXBlID09PSAwIC8qIFN0YXRpYyAqLykge1xyXG4gICAgICAgICAgICAgICAgLy8gcHJlcGVuZCB0aGUgc2xhc2ggaWYgd2UgYXJlIHN0YXJ0aW5nIGEgbmV3IHNlZ21lbnRcclxuICAgICAgICAgICAgICAgIGlmICghdG9rZW5JbmRleClcclxuICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuICs9ICcvJztcclxuICAgICAgICAgICAgICAgIHBhdHRlcm4gKz0gdG9rZW4udmFsdWUucmVwbGFjZShSRUdFWF9DSEFSU19SRSwgJ1xcXFwkJicpO1xyXG4gICAgICAgICAgICAgICAgc3ViU2VnbWVudFNjb3JlICs9IDQwIC8qIFN0YXRpYyAqLztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICh0b2tlbi50eXBlID09PSAxIC8qIFBhcmFtICovKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB7IHZhbHVlLCByZXBlYXRhYmxlLCBvcHRpb25hbCwgcmVnZXhwIH0gPSB0b2tlbjtcclxuICAgICAgICAgICAgICAgIGtleXMucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogdmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgcmVwZWF0YWJsZSxcclxuICAgICAgICAgICAgICAgICAgICBvcHRpb25hbCxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmUgPSByZWdleHAgPyByZWdleHAgOiBCQVNFX1BBUkFNX1BBVFRFUk47XHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgdXNlciBwcm92aWRlZCBhIGN1c3RvbSByZWdleHAgLzppZChcXFxcZCspXHJcbiAgICAgICAgICAgICAgICBpZiAocmUgIT09IEJBU0VfUEFSQU1fUEFUVEVSTikge1xyXG4gICAgICAgICAgICAgICAgICAgIHN1YlNlZ21lbnRTY29yZSArPSAxMCAvKiBCb251c0N1c3RvbVJlZ0V4cCAqLztcclxuICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIHJlZ2V4cCBpcyB2YWxpZCBiZWZvcmUgdXNpbmcgaXRcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgUmVnRXhwKGAoJHtyZX0pYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGN1c3RvbSBSZWdFeHAgZm9yIHBhcmFtIFwiJHt2YWx1ZX1cIiAoJHtyZX0pOiBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyB3aGVuIHdlIHJlcGVhdCB3ZSBtdXN0IHRha2UgY2FyZSBvZiB0aGUgcmVwZWF0aW5nIGxlYWRpbmcgc2xhc2hcclxuICAgICAgICAgICAgICAgIGxldCBzdWJQYXR0ZXJuID0gcmVwZWF0YWJsZSA/IGAoKD86JHtyZX0pKD86Lyg/OiR7cmV9KSkqKWAgOiBgKCR7cmV9KWA7XHJcbiAgICAgICAgICAgICAgICAvLyBwcmVwZW5kIHRoZSBzbGFzaCBpZiB3ZSBhcmUgc3RhcnRpbmcgYSBuZXcgc2VnbWVudFxyXG4gICAgICAgICAgICAgICAgaWYgKCF0b2tlbkluZGV4KVxyXG4gICAgICAgICAgICAgICAgICAgIHN1YlBhdHRlcm4gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhdm9pZCBhbiBvcHRpb25hbCAvIGlmIHRoZXJlIGFyZSBtb3JlIHNlZ21lbnRzIGUuZy4gLzpwPy1zdGF0aWNcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3IgLzpwPy06cDJcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWwgJiYgc2VnbWVudC5sZW5ndGggPCAyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGAoPzovJHtzdWJQYXR0ZXJufSlgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICcvJyArIHN1YlBhdHRlcm47XHJcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9uYWwpXHJcbiAgICAgICAgICAgICAgICAgICAgc3ViUGF0dGVybiArPSAnPyc7XHJcbiAgICAgICAgICAgICAgICBwYXR0ZXJuICs9IHN1YlBhdHRlcm47XHJcbiAgICAgICAgICAgICAgICBzdWJTZWdtZW50U2NvcmUgKz0gMjAgLyogRHluYW1pYyAqLztcclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25hbClcclxuICAgICAgICAgICAgICAgICAgICBzdWJTZWdtZW50U2NvcmUgKz0gLTggLyogQm9udXNPcHRpb25hbCAqLztcclxuICAgICAgICAgICAgICAgIGlmIChyZXBlYXRhYmxlKVxyXG4gICAgICAgICAgICAgICAgICAgIHN1YlNlZ21lbnRTY29yZSArPSAtMjAgLyogQm9udXNSZXBlYXRhYmxlICovO1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlID09PSAnLionKVxyXG4gICAgICAgICAgICAgICAgICAgIHN1YlNlZ21lbnRTY29yZSArPSAtNTAgLyogQm9udXNXaWxkY2FyZCAqLztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzZWdtZW50U2NvcmVzLnB1c2goc3ViU2VnbWVudFNjb3JlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gYW4gZW1wdHkgYXJyYXkgbGlrZSAvaG9tZS8gLT4gW1t7aG9tZX1dLCBbXV1cclxuICAgICAgICAvLyBpZiAoIXNlZ21lbnQubGVuZ3RoKSBwYXR0ZXJuICs9ICcvJ1xyXG4gICAgICAgIHNjb3JlLnB1c2goc2VnbWVudFNjb3Jlcyk7XHJcbiAgICB9XHJcbiAgICAvLyBvbmx5IGFwcGx5IHRoZSBzdHJpY3QgYm9udXMgdG8gdGhlIGxhc3Qgc2NvcmVcclxuICAgIGlmIChvcHRpb25zLnN0cmljdCAmJiBvcHRpb25zLmVuZCkge1xyXG4gICAgICAgIGNvbnN0IGkgPSBzY29yZS5sZW5ndGggLSAxO1xyXG4gICAgICAgIHNjb3JlW2ldW3Njb3JlW2ldLmxlbmd0aCAtIDFdICs9IDAuNzAwMDAwMDAwMDAwMDAwMSAvKiBCb251c1N0cmljdCAqLztcclxuICAgIH1cclxuICAgIC8vIFRPRE86IGRldiBvbmx5IHdhcm4gZG91YmxlIHRyYWlsaW5nIHNsYXNoXHJcbiAgICBpZiAoIW9wdGlvbnMuc3RyaWN0KVxyXG4gICAgICAgIHBhdHRlcm4gKz0gJy8/JztcclxuICAgIGlmIChvcHRpb25zLmVuZClcclxuICAgICAgICBwYXR0ZXJuICs9ICckJztcclxuICAgIC8vIGFsbG93IHBhdGhzIGxpa2UgL2R5bmFtaWMgdG8gb25seSBtYXRjaCBkeW5hbWljIG9yIGR5bmFtaWMvLi4uIGJ1dCBub3QgZHluYW1pY19zb21ldGhpbmdfZWxzZVxyXG4gICAgZWxzZSBpZiAob3B0aW9ucy5zdHJpY3QpXHJcbiAgICAgICAgcGF0dGVybiArPSAnKD86L3wkKSc7XHJcbiAgICBjb25zdCByZSA9IG5ldyBSZWdFeHAocGF0dGVybiwgb3B0aW9ucy5zZW5zaXRpdmUgPyAnJyA6ICdpJyk7XHJcbiAgICBmdW5jdGlvbiBwYXJzZShwYXRoKSB7XHJcbiAgICAgICAgY29uc3QgbWF0Y2ggPSBwYXRoLm1hdGNoKHJlKTtcclxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7fTtcclxuICAgICAgICBpZiAoIW1hdGNoKVxyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG1hdGNoLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gbWF0Y2hbaV0gfHwgJyc7XHJcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IGtleXNbaSAtIDFdO1xyXG4gICAgICAgICAgICBwYXJhbXNba2V5Lm5hbWVdID0gdmFsdWUgJiYga2V5LnJlcGVhdGFibGUgPyB2YWx1ZS5zcGxpdCgnLycpIDogdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwYXJhbXM7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBzdHJpbmdpZnkocGFyYW1zKSB7XHJcbiAgICAgICAgbGV0IHBhdGggPSAnJztcclxuICAgICAgICAvLyBmb3Igb3B0aW9uYWwgcGFyYW1ldGVycyB0byBhbGxvdyB0byBiZSBlbXB0eVxyXG4gICAgICAgIGxldCBhdm9pZER1cGxpY2F0ZWRTbGFzaCA9IGZhbHNlO1xyXG4gICAgICAgIGZvciAoY29uc3Qgc2VnbWVudCBvZiBzZWdtZW50cykge1xyXG4gICAgICAgICAgICBpZiAoIWF2b2lkRHVwbGljYXRlZFNsYXNoIHx8ICFwYXRoLmVuZHNXaXRoKCcvJykpXHJcbiAgICAgICAgICAgICAgICBwYXRoICs9ICcvJztcclxuICAgICAgICAgICAgYXZvaWREdXBsaWNhdGVkU2xhc2ggPSBmYWxzZTtcclxuICAgICAgICAgICAgZm9yIChjb25zdCB0b2tlbiBvZiBzZWdtZW50KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodG9rZW4udHlwZSA9PT0gMCAvKiBTdGF0aWMgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICBwYXRoICs9IHRva2VuLnZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodG9rZW4udHlwZSA9PT0gMSAvKiBQYXJhbSAqLykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgdmFsdWUsIHJlcGVhdGFibGUsIG9wdGlvbmFsIH0gPSB0b2tlbjtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJhbSA9IHZhbHVlIGluIHBhcmFtcyA/IHBhcmFtc1t2YWx1ZV0gOiAnJztcclxuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwYXJhbSkgJiYgIXJlcGVhdGFibGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJvdmlkZWQgcGFyYW0gXCIke3ZhbHVlfVwiIGlzIGFuIGFycmF5IGJ1dCBpdCBpcyBub3QgcmVwZWF0YWJsZSAoKiBvciArIG1vZGlmaWVycylgKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gQXJyYXkuaXNBcnJheShwYXJhbSkgPyBwYXJhbS5qb2luKCcvJykgOiBwYXJhbTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRleHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB3ZSBoYXZlIG1vcmUgdGhhbiBvbmUgb3B0aW9uYWwgcGFyYW0gbGlrZSAvOmE/LXN0YXRpYyB3ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG9uJ3QgbmVlZCB0byBjYXJlIGFib3V0IHRoZSBvcHRpb25hbCBwYXJhbVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoIDwgMikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgbGFzdCBzbGFzaCBhcyB3ZSBjb3VsZCBiZSBhdCB0aGUgZW5kXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGguZW5kc1dpdGgoJy8nKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IHBhdGguc2xpY2UoMCwgLTEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBhcHBlbmQgYSBzbGFzaCBvbiB0aGUgbmV4dCBpdGVyYXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2b2lkRHVwbGljYXRlZFNsYXNoID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgcmVxdWlyZWQgcGFyYW0gXCIke3ZhbHVlfVwiYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHBhdGggKz0gdGV4dDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcGF0aDtcclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgcmUsXHJcbiAgICAgICAgc2NvcmUsXHJcbiAgICAgICAga2V5cyxcclxuICAgICAgICBwYXJzZSxcclxuICAgICAgICBzdHJpbmdpZnksXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBDb21wYXJlcyBhbiBhcnJheSBvZiBudW1iZXJzIGFzIHVzZWQgaW4gUGF0aFBhcnNlci5zY29yZSBhbmQgcmV0dXJucyBhXHJcbiAqIG51bWJlci4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBgc29ydGAgYW4gYXJyYXlcclxuICpcclxuICogQHBhcmFtIGEgLSBmaXJzdCBhcnJheSBvZiBudW1iZXJzXHJcbiAqIEBwYXJhbSBiIC0gc2Vjb25kIGFycmF5IG9mIG51bWJlcnNcclxuICogQHJldHVybnMgMCBpZiBib3RoIGFyZSBlcXVhbCwgPCAwIGlmIGEgc2hvdWxkIGJlIHNvcnRlZCBmaXJzdCwgPiAwIGlmIGJcclxuICogc2hvdWxkIGJlIHNvcnRlZCBmaXJzdFxyXG4gKi9cclxuZnVuY3Rpb24gY29tcGFyZVNjb3JlQXJyYXkoYSwgYikge1xyXG4gICAgbGV0IGkgPSAwO1xyXG4gICAgd2hpbGUgKGkgPCBhLmxlbmd0aCAmJiBpIDwgYi5sZW5ndGgpIHtcclxuICAgICAgICBjb25zdCBkaWZmID0gYltpXSAtIGFbaV07XHJcbiAgICAgICAgLy8gb25seSBrZWVwIGdvaW5nIGlmIGRpZmYgPT09IDBcclxuICAgICAgICBpZiAoZGlmZilcclxuICAgICAgICAgICAgcmV0dXJuIGRpZmY7XHJcbiAgICAgICAgaSsrO1xyXG4gICAgfVxyXG4gICAgLy8gaWYgdGhlIGxhc3Qgc3Vic2VnbWVudCB3YXMgU3RhdGljLCB0aGUgc2hvcnRlciBzZWdtZW50cyBzaG91bGQgYmUgc29ydGVkIGZpcnN0XHJcbiAgICAvLyBvdGhlcndpc2Ugc29ydCB0aGUgbG9uZ2VzdCBzZWdtZW50IGZpcnN0XHJcbiAgICBpZiAoYS5sZW5ndGggPCBiLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBhLmxlbmd0aCA9PT0gMSAmJiBhWzBdID09PSA0MCAvKiBTdGF0aWMgKi8gKyA0MCAvKiBTZWdtZW50ICovXHJcbiAgICAgICAgICAgID8gLTFcclxuICAgICAgICAgICAgOiAxO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoYS5sZW5ndGggPiBiLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBiLmxlbmd0aCA9PT0gMSAmJiBiWzBdID09PSA0MCAvKiBTdGF0aWMgKi8gKyA0MCAvKiBTZWdtZW50ICovXHJcbiAgICAgICAgICAgID8gMVxyXG4gICAgICAgICAgICA6IC0xO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIDA7XHJcbn1cclxuLyoqXHJcbiAqIENvbXBhcmUgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB3aXRoIGBzb3J0YCB0byBzb3J0IGFuIGFycmF5IG9mIFBhdGhQYXJzZXJcclxuICpcclxuICogQHBhcmFtIGEgLSBmaXJzdCBQYXRoUGFyc2VyXHJcbiAqIEBwYXJhbSBiIC0gc2Vjb25kIFBhdGhQYXJzZXJcclxuICogQHJldHVybnMgMCBpZiBib3RoIGFyZSBlcXVhbCwgPCAwIGlmIGEgc2hvdWxkIGJlIHNvcnRlZCBmaXJzdCwgPiAwIGlmIGJcclxuICovXHJcbmZ1bmN0aW9uIGNvbXBhcmVQYXRoUGFyc2VyU2NvcmUoYSwgYikge1xyXG4gICAgbGV0IGkgPSAwO1xyXG4gICAgY29uc3QgYVNjb3JlID0gYS5zY29yZTtcclxuICAgIGNvbnN0IGJTY29yZSA9IGIuc2NvcmU7XHJcbiAgICB3aGlsZSAoaSA8IGFTY29yZS5sZW5ndGggJiYgaSA8IGJTY29yZS5sZW5ndGgpIHtcclxuICAgICAgICBjb25zdCBjb21wID0gY29tcGFyZVNjb3JlQXJyYXkoYVNjb3JlW2ldLCBiU2NvcmVbaV0pO1xyXG4gICAgICAgIC8vIGRvIG5vdCByZXR1cm4gaWYgYm90aCBhcmUgZXF1YWxcclxuICAgICAgICBpZiAoY29tcClcclxuICAgICAgICAgICAgcmV0dXJuIGNvbXA7XHJcbiAgICAgICAgaSsrO1xyXG4gICAgfVxyXG4gICAgLy8gaWYgYSBhbmQgYiBzaGFyZSB0aGUgc2FtZSBzY29yZSBlbnRyaWVzIGJ1dCBiIGhhcyBtb3JlLCBzb3J0IGIgZmlyc3RcclxuICAgIHJldHVybiBiU2NvcmUubGVuZ3RoIC0gYVNjb3JlLmxlbmd0aDtcclxuICAgIC8vIHRoaXMgaXMgdGhlIHRlcm5hcnkgdmVyc2lvblxyXG4gICAgLy8gcmV0dXJuIGFTY29yZS5sZW5ndGggPCBiU2NvcmUubGVuZ3RoXHJcbiAgICAvLyAgID8gMVxyXG4gICAgLy8gICA6IGFTY29yZS5sZW5ndGggPiBiU2NvcmUubGVuZ3RoXHJcbiAgICAvLyAgID8gLTFcclxuICAgIC8vICAgOiAwXHJcbn1cblxuY29uc3QgUk9PVF9UT0tFTiA9IHtcclxuICAgIHR5cGU6IDAgLyogU3RhdGljICovLFxyXG4gICAgdmFsdWU6ICcnLFxyXG59O1xyXG5jb25zdCBWQUxJRF9QQVJBTV9SRSA9IC9bYS16QS1aMC05X10vO1xyXG4vLyBBZnRlciBzb21lIHByb2ZpbGluZywgdGhlIGNhY2hlIHNlZW1zIHRvIGJlIHVubmVjZXNzYXJ5IGJlY2F1c2UgdG9rZW5pemVQYXRoXHJcbi8vICh0aGUgc2xvd2VzdCBwYXJ0IG9mIGFkZGluZyBhIHJvdXRlKSBpcyB2ZXJ5IGZhc3RcclxuLy8gY29uc3QgdG9rZW5DYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBUb2tlbltdW10+KClcclxuZnVuY3Rpb24gdG9rZW5pemVQYXRoKHBhdGgpIHtcclxuICAgIGlmICghcGF0aClcclxuICAgICAgICByZXR1cm4gW1tdXTtcclxuICAgIGlmIChwYXRoID09PSAnLycpXHJcbiAgICAgICAgcmV0dXJuIFtbUk9PVF9UT0tFTl1dO1xyXG4gICAgaWYgKCFwYXRoLnN0YXJ0c1dpdGgoJy8nKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJylcclxuICAgICAgICAgICAgPyBgUm91dGUgcGF0aHMgc2hvdWxkIHN0YXJ0IHdpdGggYSBcIi9cIjogXCIke3BhdGh9XCIgc2hvdWxkIGJlIFwiLyR7cGF0aH1cIi5gXHJcbiAgICAgICAgICAgIDogYEludmFsaWQgcGF0aCBcIiR7cGF0aH1cImApO1xyXG4gICAgfVxyXG4gICAgLy8gaWYgKHRva2VuQ2FjaGUuaGFzKHBhdGgpKSByZXR1cm4gdG9rZW5DYWNoZS5nZXQocGF0aCkhXHJcbiAgICBmdW5jdGlvbiBjcmFzaChtZXNzYWdlKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFUlIgKCR7c3RhdGV9KS9cIiR7YnVmZmVyfVwiOiAke21lc3NhZ2V9YCk7XHJcbiAgICB9XHJcbiAgICBsZXQgc3RhdGUgPSAwIC8qIFN0YXRpYyAqLztcclxuICAgIGxldCBwcmV2aW91c1N0YXRlID0gc3RhdGU7XHJcbiAgICBjb25zdCB0b2tlbnMgPSBbXTtcclxuICAgIC8vIHRoZSBzZWdtZW50IHdpbGwgYWx3YXlzIGJlIHZhbGlkIGJlY2F1c2Ugd2UgZ2V0IGludG8gdGhlIGluaXRpYWwgc3RhdGVcclxuICAgIC8vIHdpdGggdGhlIGxlYWRpbmcgL1xyXG4gICAgbGV0IHNlZ21lbnQ7XHJcbiAgICBmdW5jdGlvbiBmaW5hbGl6ZVNlZ21lbnQoKSB7XHJcbiAgICAgICAgaWYgKHNlZ21lbnQpXHJcbiAgICAgICAgICAgIHRva2Vucy5wdXNoKHNlZ21lbnQpO1xyXG4gICAgICAgIHNlZ21lbnQgPSBbXTtcclxuICAgIH1cclxuICAgIC8vIGluZGV4IG9uIHRoZSBwYXRoXHJcbiAgICBsZXQgaSA9IDA7XHJcbiAgICAvLyBjaGFyIGF0IGluZGV4XHJcbiAgICBsZXQgY2hhcjtcclxuICAgIC8vIGJ1ZmZlciBvZiB0aGUgdmFsdWUgcmVhZFxyXG4gICAgbGV0IGJ1ZmZlciA9ICcnO1xyXG4gICAgLy8gY3VzdG9tIHJlZ2V4cCBmb3IgYSBwYXJhbVxyXG4gICAgbGV0IGN1c3RvbVJlID0gJyc7XHJcbiAgICBmdW5jdGlvbiBjb25zdW1lQnVmZmVyKCkge1xyXG4gICAgICAgIGlmICghYnVmZmVyKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgaWYgKHN0YXRlID09PSAwIC8qIFN0YXRpYyAqLykge1xyXG4gICAgICAgICAgICBzZWdtZW50LnB1c2goe1xyXG4gICAgICAgICAgICAgICAgdHlwZTogMCAvKiBTdGF0aWMgKi8sXHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogYnVmZmVyLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoc3RhdGUgPT09IDEgLyogUGFyYW0gKi8gfHxcclxuICAgICAgICAgICAgc3RhdGUgPT09IDIgLyogUGFyYW1SZWdFeHAgKi8gfHxcclxuICAgICAgICAgICAgc3RhdGUgPT09IDMgLyogUGFyYW1SZWdFeHBFbmQgKi8pIHtcclxuICAgICAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID4gMSAmJiAoY2hhciA9PT0gJyonIHx8IGNoYXIgPT09ICcrJykpXHJcbiAgICAgICAgICAgICAgICBjcmFzaChgQSByZXBlYXRhYmxlIHBhcmFtICgke2J1ZmZlcn0pIG11c3QgYmUgYWxvbmUgaW4gaXRzIHNlZ21lbnQuIGVnOiAnLzppZHMrLmApO1xyXG4gICAgICAgICAgICBzZWdtZW50LnB1c2goe1xyXG4gICAgICAgICAgICAgICAgdHlwZTogMSAvKiBQYXJhbSAqLyxcclxuICAgICAgICAgICAgICAgIHZhbHVlOiBidWZmZXIsXHJcbiAgICAgICAgICAgICAgICByZWdleHA6IGN1c3RvbVJlLFxyXG4gICAgICAgICAgICAgICAgcmVwZWF0YWJsZTogY2hhciA9PT0gJyonIHx8IGNoYXIgPT09ICcrJyxcclxuICAgICAgICAgICAgICAgIG9wdGlvbmFsOiBjaGFyID09PSAnKicgfHwgY2hhciA9PT0gJz8nLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGNyYXNoKCdJbnZhbGlkIHN0YXRlIHRvIGNvbnN1bWUgYnVmZmVyJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJ1ZmZlciA9ICcnO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gYWRkQ2hhclRvQnVmZmVyKCkge1xyXG4gICAgICAgIGJ1ZmZlciArPSBjaGFyO1xyXG4gICAgfVxyXG4gICAgd2hpbGUgKGkgPCBwYXRoLmxlbmd0aCkge1xyXG4gICAgICAgIGNoYXIgPSBwYXRoW2krK107XHJcbiAgICAgICAgaWYgKGNoYXIgPT09ICdcXFxcJyAmJiBzdGF0ZSAhPT0gMiAvKiBQYXJhbVJlZ0V4cCAqLykge1xyXG4gICAgICAgICAgICBwcmV2aW91c1N0YXRlID0gc3RhdGU7XHJcbiAgICAgICAgICAgIHN0YXRlID0gNCAvKiBFc2NhcGVOZXh0ICovO1xyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc3dpdGNoIChzdGF0ZSkge1xyXG4gICAgICAgICAgICBjYXNlIDAgLyogU3RhdGljICovOlxyXG4gICAgICAgICAgICAgICAgaWYgKGNoYXIgPT09ICcvJykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChidWZmZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3VtZUJ1ZmZlcigpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmaW5hbGl6ZVNlZ21lbnQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoYXIgPT09ICc6Jykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN1bWVCdWZmZXIoKTtcclxuICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IDEgLyogUGFyYW0gKi87XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBhZGRDaGFyVG9CdWZmZXIoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDQgLyogRXNjYXBlTmV4dCAqLzpcclxuICAgICAgICAgICAgICAgIGFkZENoYXJUb0J1ZmZlcigpO1xyXG4gICAgICAgICAgICAgICAgc3RhdGUgPSBwcmV2aW91c1N0YXRlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMSAvKiBQYXJhbSAqLzpcclxuICAgICAgICAgICAgICAgIGlmIChjaGFyID09PSAnKCcpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IDIgLyogUGFyYW1SZWdFeHAgKi87XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChWQUxJRF9QQVJBTV9SRS50ZXN0KGNoYXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYWRkQ2hhclRvQnVmZmVyKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdW1lQnVmZmVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSAwIC8qIFN0YXRpYyAqLztcclxuICAgICAgICAgICAgICAgICAgICAvLyBnbyBiYWNrIG9uZSBjaGFyYWN0ZXIgaWYgd2Ugd2VyZSBub3QgbW9kaWZ5aW5nXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXIgIT09ICcqJyAmJiBjaGFyICE9PSAnPycgJiYgY2hhciAhPT0gJysnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpLS07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAyIC8qIFBhcmFtUmVnRXhwICovOlxyXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogaXMgaXQgd29ydGggaGFuZGxpbmcgbmVzdGVkIHJlZ2V4cD8gbGlrZSA6cCg/OnByZWZpeF8oW14vXSspX3N1ZmZpeClcclxuICAgICAgICAgICAgICAgIC8vIGl0IGFscmVhZHkgd29ya3MgYnkgZXNjYXBpbmcgdGhlIGNsb3NpbmcgKVxyXG4gICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9wYXRocy5lc20uZGV2Lz9wPUFBTWVKYmlBd1FFY0RLYkFvQUFrUDYwUEcyUjZRQXZnTmFBNkFGQUNNMkFCdVFCQiNcclxuICAgICAgICAgICAgICAgIC8vIGlzIHRoaXMgcmVhbGx5IHNvbWV0aGluZyBwZW9wbGUgbmVlZCBzaW5jZSB5b3UgY2FuIGFsc28gd3JpdGVcclxuICAgICAgICAgICAgICAgIC8vIC9wcmVmaXhfOnAoKV9zdWZmaXhcclxuICAgICAgICAgICAgICAgIGlmIChjaGFyID09PSAnKScpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgdGhlIGVzY2FwZWQgKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjdXN0b21SZVtjdXN0b21SZS5sZW5ndGggLSAxXSA9PSAnXFxcXCcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1c3RvbVJlID0gY3VzdG9tUmUuc2xpY2UoMCwgLTEpICsgY2hhcjtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gMyAvKiBQYXJhbVJlZ0V4cEVuZCAqLztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbVJlICs9IGNoYXI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAzIC8qIFBhcmFtUmVnRXhwRW5kICovOlxyXG4gICAgICAgICAgICAgICAgLy8gc2FtZSBhcyBmaW5hbGl6aW5nIGEgcGFyYW1cclxuICAgICAgICAgICAgICAgIGNvbnN1bWVCdWZmZXIoKTtcclxuICAgICAgICAgICAgICAgIHN0YXRlID0gMCAvKiBTdGF0aWMgKi87XHJcbiAgICAgICAgICAgICAgICAvLyBnbyBiYWNrIG9uZSBjaGFyYWN0ZXIgaWYgd2Ugd2VyZSBub3QgbW9kaWZ5aW5nXHJcbiAgICAgICAgICAgICAgICBpZiAoY2hhciAhPT0gJyonICYmIGNoYXIgIT09ICc/JyAmJiBjaGFyICE9PSAnKycpXHJcbiAgICAgICAgICAgICAgICAgICAgaS0tO1xyXG4gICAgICAgICAgICAgICAgY3VzdG9tUmUgPSAnJztcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgY3Jhc2goJ1Vua25vd24gc3RhdGUnKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChzdGF0ZSA9PT0gMiAvKiBQYXJhbVJlZ0V4cCAqLylcclxuICAgICAgICBjcmFzaChgVW5maW5pc2hlZCBjdXN0b20gUmVnRXhwIGZvciBwYXJhbSBcIiR7YnVmZmVyfVwiYCk7XHJcbiAgICBjb25zdW1lQnVmZmVyKCk7XHJcbiAgICBmaW5hbGl6ZVNlZ21lbnQoKTtcclxuICAgIC8vIHRva2VuQ2FjaGUuc2V0KHBhdGgsIHRva2VucylcclxuICAgIHJldHVybiB0b2tlbnM7XHJcbn1cblxuZnVuY3Rpb24gY3JlYXRlUm91dGVSZWNvcmRNYXRjaGVyKHJlY29yZCwgcGFyZW50LCBvcHRpb25zKSB7XHJcbiAgICBjb25zdCBwYXJzZXIgPSB0b2tlbnNUb1BhcnNlcih0b2tlbml6ZVBhdGgocmVjb3JkLnBhdGgpLCBvcHRpb25zKTtcclxuICAgIC8vIHdhcm4gYWdhaW5zdCBwYXJhbXMgd2l0aCB0aGUgc2FtZSBuYW1lXHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgY29uc3QgZXhpc3RpbmdLZXlzID0gbmV3IFNldCgpO1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHBhcnNlci5rZXlzKSB7XHJcbiAgICAgICAgICAgIGlmIChleGlzdGluZ0tleXMuaGFzKGtleS5uYW1lKSlcclxuICAgICAgICAgICAgICAgIHdhcm4oYEZvdW5kIGR1cGxpY2F0ZWQgcGFyYW1zIHdpdGggbmFtZSBcIiR7a2V5Lm5hbWV9XCIgZm9yIHBhdGggXCIke3JlY29yZC5wYXRofVwiLiBPbmx5IHRoZSBsYXN0IG9uZSB3aWxsIGJlIGF2YWlsYWJsZSBvbiBcIiRyb3V0ZS5wYXJhbXNcIi5gKTtcclxuICAgICAgICAgICAgZXhpc3RpbmdLZXlzLmFkZChrZXkubmFtZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3QgbWF0Y2hlciA9IGFzc2lnbihwYXJzZXIsIHtcclxuICAgICAgICByZWNvcmQsXHJcbiAgICAgICAgcGFyZW50LFxyXG4gICAgICAgIC8vIHRoZXNlIG5lZWRzIHRvIGJlIHBvcHVsYXRlZCBieSB0aGUgcGFyZW50XHJcbiAgICAgICAgY2hpbGRyZW46IFtdLFxyXG4gICAgICAgIGFsaWFzOiBbXSxcclxuICAgIH0pO1xyXG4gICAgaWYgKHBhcmVudCkge1xyXG4gICAgICAgIC8vIGJvdGggYXJlIGFsaWFzZXMgb3IgYm90aCBhcmUgbm90IGFsaWFzZXNcclxuICAgICAgICAvLyB3ZSBkb24ndCB3YW50IHRvIG1peCB0aGVtIGJlY2F1c2UgdGhlIG9yZGVyIGlzIHVzZWQgd2hlblxyXG4gICAgICAgIC8vIHBhc3Npbmcgb3JpZ2luYWxSZWNvcmQgaW4gTWF0Y2hlci5hZGRSb3V0ZVxyXG4gICAgICAgIGlmICghbWF0Y2hlci5yZWNvcmQuYWxpYXNPZiA9PT0gIXBhcmVudC5yZWNvcmQuYWxpYXNPZilcclxuICAgICAgICAgICAgcGFyZW50LmNoaWxkcmVuLnB1c2gobWF0Y2hlcik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbWF0Y2hlcjtcclxufVxuXG4vKipcclxuICogQ3JlYXRlcyBhIFJvdXRlciBNYXRjaGVyLlxyXG4gKlxyXG4gKiBAaW50ZXJuYWxcclxuICogQHBhcmFtIHJvdXRlcyAtIGFycmF5IG9mIGluaXRpYWwgcm91dGVzXHJcbiAqIEBwYXJhbSBnbG9iYWxPcHRpb25zIC0gZ2xvYmFsIHJvdXRlIG9wdGlvbnNcclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZVJvdXRlck1hdGNoZXIocm91dGVzLCBnbG9iYWxPcHRpb25zKSB7XHJcbiAgICAvLyBub3JtYWxpemVkIG9yZGVyZWQgYXJyYXkgb2YgbWF0Y2hlcnNcclxuICAgIGNvbnN0IG1hdGNoZXJzID0gW107XHJcbiAgICBjb25zdCBtYXRjaGVyTWFwID0gbmV3IE1hcCgpO1xyXG4gICAgZ2xvYmFsT3B0aW9ucyA9IG1lcmdlT3B0aW9ucyh7IHN0cmljdDogZmFsc2UsIGVuZDogdHJ1ZSwgc2Vuc2l0aXZlOiBmYWxzZSB9LCBnbG9iYWxPcHRpb25zKTtcclxuICAgIGZ1bmN0aW9uIGdldFJlY29yZE1hdGNoZXIobmFtZSkge1xyXG4gICAgICAgIHJldHVybiBtYXRjaGVyTWFwLmdldChuYW1lKTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGFkZFJvdXRlKHJlY29yZCwgcGFyZW50LCBvcmlnaW5hbFJlY29yZCkge1xyXG4gICAgICAgIC8vIHVzZWQgbGF0ZXIgb24gdG8gcmVtb3ZlIGJ5IG5hbWVcclxuICAgICAgICBjb25zdCBpc1Jvb3RBZGQgPSAhb3JpZ2luYWxSZWNvcmQ7XHJcbiAgICAgICAgY29uc3QgbWFpbk5vcm1hbGl6ZWRSZWNvcmQgPSBub3JtYWxpemVSb3V0ZVJlY29yZChyZWNvcmQpO1xyXG4gICAgICAgIC8vIHdlIG1pZ2h0IGJlIHRoZSBjaGlsZCBvZiBhbiBhbGlhc1xyXG4gICAgICAgIG1haW5Ob3JtYWxpemVkUmVjb3JkLmFsaWFzT2YgPSBvcmlnaW5hbFJlY29yZCAmJiBvcmlnaW5hbFJlY29yZC5yZWNvcmQ7XHJcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG1lcmdlT3B0aW9ucyhnbG9iYWxPcHRpb25zLCByZWNvcmQpO1xyXG4gICAgICAgIC8vIGdlbmVyYXRlIGFuIGFycmF5IG9mIHJlY29yZHMgdG8gY29ycmVjdGx5IGhhbmRsZSBhbGlhc2VzXHJcbiAgICAgICAgY29uc3Qgbm9ybWFsaXplZFJlY29yZHMgPSBbXHJcbiAgICAgICAgICAgIG1haW5Ob3JtYWxpemVkUmVjb3JkLFxyXG4gICAgICAgIF07XHJcbiAgICAgICAgaWYgKCdhbGlhcycgaW4gcmVjb3JkKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGFsaWFzZXMgPSB0eXBlb2YgcmVjb3JkLmFsaWFzID09PSAnc3RyaW5nJyA/IFtyZWNvcmQuYWxpYXNdIDogcmVjb3JkLmFsaWFzO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGFsaWFzIG9mIGFsaWFzZXMpIHtcclxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRSZWNvcmRzLnB1c2goYXNzaWduKHt9LCBtYWluTm9ybWFsaXplZFJlY29yZCwge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgYWxsb3dzIHVzIHRvIGhvbGQgYSBjb3B5IG9mIHRoZSBgY29tcG9uZW50c2Agb3B0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc28gdGhhdCBhc3luYyBjb21wb25lbnRzIGNhY2hlIGlzIGhvbGQgb24gdGhlIG9yaWdpbmFsIHJlY29yZFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHM6IG9yaWdpbmFsUmVjb3JkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gb3JpZ2luYWxSZWNvcmQucmVjb3JkLmNvbXBvbmVudHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiBtYWluTm9ybWFsaXplZFJlY29yZC5jb21wb25lbnRzLFxyXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IGFsaWFzLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHdlIG1pZ2h0IGJlIHRoZSBjaGlsZCBvZiBhbiBhbGlhc1xyXG4gICAgICAgICAgICAgICAgICAgIGFsaWFzT2Y6IG9yaWdpbmFsUmVjb3JkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gb3JpZ2luYWxSZWNvcmQucmVjb3JkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbWFpbk5vcm1hbGl6ZWRSZWNvcmQsXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGFsaWFzZXMgYXJlIGFsd2F5cyBvZiB0aGUgc2FtZSBraW5kIGFzIHRoZSBvcmlnaW5hbCBzaW5jZSB0aGV5XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gYXJlIGRlZmluZWQgb24gdGhlIHNhbWUgcmVjb3JkXHJcbiAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IG1hdGNoZXI7XHJcbiAgICAgICAgbGV0IG9yaWdpbmFsTWF0Y2hlcjtcclxuICAgICAgICBmb3IgKGNvbnN0IG5vcm1hbGl6ZWRSZWNvcmQgb2Ygbm9ybWFsaXplZFJlY29yZHMpIHtcclxuICAgICAgICAgICAgY29uc3QgeyBwYXRoIH0gPSBub3JtYWxpemVkUmVjb3JkO1xyXG4gICAgICAgICAgICAvLyBCdWlsZCB1cCB0aGUgcGF0aCBmb3IgbmVzdGVkIHJvdXRlcyBpZiB0aGUgY2hpbGQgaXNuJ3QgYW4gYWJzb2x1dGVcclxuICAgICAgICAgICAgLy8gcm91dGUuIE9ubHkgYWRkIHRoZSAvIGRlbGltaXRlciBpZiB0aGUgY2hpbGQgcGF0aCBpc24ndCBlbXB0eSBhbmQgaWYgdGhlXHJcbiAgICAgICAgICAgIC8vIHBhcmVudCBwYXRoIGRvZXNuJ3QgaGF2ZSBhIHRyYWlsaW5nIHNsYXNoXHJcbiAgICAgICAgICAgIGlmIChwYXJlbnQgJiYgcGF0aFswXSAhPT0gJy8nKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRQYXRoID0gcGFyZW50LnJlY29yZC5wYXRoO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGluZ1NsYXNoID0gcGFyZW50UGF0aFtwYXJlbnRQYXRoLmxlbmd0aCAtIDFdID09PSAnLycgPyAnJyA6ICcvJztcclxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRSZWNvcmQucGF0aCA9XHJcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50LnJlY29yZC5wYXRoICsgKHBhdGggJiYgY29ubmVjdGluZ1NsYXNoICsgcGF0aCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBub3JtYWxpemVkUmVjb3JkLnBhdGggPT09ICcqJykge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYXRjaCBhbGwgcm91dGVzIChcIipcIikgbXVzdCBub3cgYmUgZGVmaW5lZCB1c2luZyBhIHBhcmFtIHdpdGggYSBjdXN0b20gcmVnZXhwLlxcbicgK1xyXG4gICAgICAgICAgICAgICAgICAgICdTZWUgbW9yZSBhdCBodHRwczovL25leHQucm91dGVyLnZ1ZWpzLm9yZy9ndWlkZS9taWdyYXRpb24vI3JlbW92ZWQtc3Rhci1vci1jYXRjaC1hbGwtcm91dGVzLicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgb2JqZWN0IGJlZm9yZSBoYW5kIHNvIGl0IGNhbiBiZSBwYXNzZWQgdG8gY2hpbGRyZW5cclxuICAgICAgICAgICAgbWF0Y2hlciA9IGNyZWF0ZVJvdXRlUmVjb3JkTWF0Y2hlcihub3JtYWxpemVkUmVjb3JkLCBwYXJlbnQsIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIHBhcmVudCAmJiBwYXRoWzBdID09PSAnLycpXHJcbiAgICAgICAgICAgICAgICBjaGVja01pc3NpbmdQYXJhbXNJbkFic29sdXRlUGF0aChtYXRjaGVyLCBwYXJlbnQpO1xyXG4gICAgICAgICAgICAvLyBpZiB3ZSBhcmUgYW4gYWxpYXMgd2UgbXVzdCB0ZWxsIHRoZSBvcmlnaW5hbCByZWNvcmQgdGhhdCB3ZSBleGlzdFxyXG4gICAgICAgICAgICAvLyBzbyB3ZSBjYW4gYmUgcmVtb3ZlZFxyXG4gICAgICAgICAgICBpZiAob3JpZ2luYWxSZWNvcmQpIHtcclxuICAgICAgICAgICAgICAgIG9yaWdpbmFsUmVjb3JkLmFsaWFzLnB1c2gobWF0Y2hlcik7XHJcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2hlY2tTYW1lUGFyYW1zKG9yaWdpbmFsUmVjb3JkLCBtYXRjaGVyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSwgdGhlIGZpcnN0IHJlY29yZCBpcyB0aGUgb3JpZ2luYWwgYW5kIG90aGVycyBhcmUgYWxpYXNlc1xyXG4gICAgICAgICAgICAgICAgb3JpZ2luYWxNYXRjaGVyID0gb3JpZ2luYWxNYXRjaGVyIHx8IG1hdGNoZXI7XHJcbiAgICAgICAgICAgICAgICBpZiAob3JpZ2luYWxNYXRjaGVyICE9PSBtYXRjaGVyKVxyXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsTWF0Y2hlci5hbGlhcy5wdXNoKG1hdGNoZXIpO1xyXG4gICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSByb3V0ZSBpZiBuYW1lZCBhbmQgb25seSBmb3IgdGhlIHRvcCByZWNvcmQgKGF2b2lkIGluIG5lc3RlZCBjYWxscylcclxuICAgICAgICAgICAgICAgIC8vIHRoaXMgd29ya3MgYmVjYXVzZSB0aGUgb3JpZ2luYWwgcmVjb3JkIGlzIHRoZSBmaXJzdCBvbmVcclxuICAgICAgICAgICAgICAgIGlmIChpc1Jvb3RBZGQgJiYgcmVjb3JkLm5hbWUgJiYgIWlzQWxpYXNSZWNvcmQobWF0Y2hlcikpXHJcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlUm91dGUocmVjb3JkLm5hbWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICgnY2hpbGRyZW4nIGluIG1haW5Ob3JtYWxpemVkUmVjb3JkKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IG1haW5Ob3JtYWxpemVkUmVjb3JkLmNoaWxkcmVuO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGFkZFJvdXRlKGNoaWxkcmVuW2ldLCBtYXRjaGVyLCBvcmlnaW5hbFJlY29yZCAmJiBvcmlnaW5hbFJlY29yZC5jaGlsZHJlbltpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gaWYgdGhlcmUgd2FzIG5vIG9yaWdpbmFsIHJlY29yZCwgdGhlbiB0aGUgZmlyc3Qgb25lIHdhcyBub3QgYW4gYWxpYXMgYW5kIGFsbFxyXG4gICAgICAgICAgICAvLyBvdGhlciBhbGlhcyAoaWYgYW55KSBuZWVkIHRvIHJlZmVyZW5jZSB0aGlzIHJlY29yZCB3aGVuIGFkZGluZyBjaGlsZHJlblxyXG4gICAgICAgICAgICBvcmlnaW5hbFJlY29yZCA9IG9yaWdpbmFsUmVjb3JkIHx8IG1hdGNoZXI7XHJcbiAgICAgICAgICAgIC8vIFRPRE86IGFkZCBub3JtYWxpemVkIHJlY29yZHMgZm9yIG1vcmUgZmxleGliaWxpdHlcclxuICAgICAgICAgICAgLy8gaWYgKHBhcmVudCAmJiBpc0FsaWFzUmVjb3JkKG9yaWdpbmFsUmVjb3JkKSkge1xyXG4gICAgICAgICAgICAvLyAgIHBhcmVudC5jaGlsZHJlbi5wdXNoKG9yaWdpbmFsUmVjb3JkKVxyXG4gICAgICAgICAgICAvLyB9XHJcbiAgICAgICAgICAgIGluc2VydE1hdGNoZXIobWF0Y2hlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvcmlnaW5hbE1hdGNoZXJcclxuICAgICAgICAgICAgPyAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBzaW5jZSBvdGhlciBtYXRjaGVycyBhcmUgYWxpYXNlcywgdGhleSBzaG91bGQgYmUgcmVtb3ZlZCBieSB0aGUgb3JpZ2luYWwgbWF0Y2hlclxyXG4gICAgICAgICAgICAgICAgcmVtb3ZlUm91dGUob3JpZ2luYWxNYXRjaGVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICA6IG5vb3A7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiByZW1vdmVSb3V0ZShtYXRjaGVyUmVmKSB7XHJcbiAgICAgICAgaWYgKGlzUm91dGVOYW1lKG1hdGNoZXJSZWYpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoZXIgPSBtYXRjaGVyTWFwLmdldChtYXRjaGVyUmVmKTtcclxuICAgICAgICAgICAgaWYgKG1hdGNoZXIpIHtcclxuICAgICAgICAgICAgICAgIG1hdGNoZXJNYXAuZGVsZXRlKG1hdGNoZXJSZWYpO1xyXG4gICAgICAgICAgICAgICAgbWF0Y2hlcnMuc3BsaWNlKG1hdGNoZXJzLmluZGV4T2YobWF0Y2hlciksIDEpO1xyXG4gICAgICAgICAgICAgICAgbWF0Y2hlci5jaGlsZHJlbi5mb3JFYWNoKHJlbW92ZVJvdXRlKTtcclxuICAgICAgICAgICAgICAgIG1hdGNoZXIuYWxpYXMuZm9yRWFjaChyZW1vdmVSb3V0ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gbWF0Y2hlcnMuaW5kZXhPZihtYXRjaGVyUmVmKTtcclxuICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgIG1hdGNoZXJzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2hlclJlZi5yZWNvcmQubmFtZSlcclxuICAgICAgICAgICAgICAgICAgICBtYXRjaGVyTWFwLmRlbGV0ZShtYXRjaGVyUmVmLnJlY29yZC5uYW1lKTtcclxuICAgICAgICAgICAgICAgIG1hdGNoZXJSZWYuY2hpbGRyZW4uZm9yRWFjaChyZW1vdmVSb3V0ZSk7XHJcbiAgICAgICAgICAgICAgICBtYXRjaGVyUmVmLmFsaWFzLmZvckVhY2gocmVtb3ZlUm91dGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gZ2V0Um91dGVzKCkge1xyXG4gICAgICAgIHJldHVybiBtYXRjaGVycztcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGluc2VydE1hdGNoZXIobWF0Y2hlcikge1xyXG4gICAgICAgIGxldCBpID0gMDtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZygnaSBpcycsIHsgaSB9KVxyXG4gICAgICAgIHdoaWxlIChpIDwgbWF0Y2hlcnMubGVuZ3RoICYmXHJcbiAgICAgICAgICAgIGNvbXBhcmVQYXRoUGFyc2VyU2NvcmUobWF0Y2hlciwgbWF0Y2hlcnNbaV0pID49IDApXHJcbiAgICAgICAgICAgIGkrKztcclxuICAgICAgICAvLyBjb25zb2xlLmxvZygnRU5EIGkgaXMnLCB7IGkgfSlcclxuICAgICAgICAvLyB3aGlsZSAoaSA8IG1hdGNoZXJzLmxlbmd0aCAmJiBtYXRjaGVyLnNjb3JlIDw9IG1hdGNoZXJzW2ldLnNjb3JlKSBpKytcclxuICAgICAgICBtYXRjaGVycy5zcGxpY2UoaSwgMCwgbWF0Y2hlcik7XHJcbiAgICAgICAgLy8gb25seSBhZGQgdGhlIG9yaWdpbmFsIHJlY29yZCB0byB0aGUgbmFtZSBtYXBcclxuICAgICAgICBpZiAobWF0Y2hlci5yZWNvcmQubmFtZSAmJiAhaXNBbGlhc1JlY29yZChtYXRjaGVyKSlcclxuICAgICAgICAgICAgbWF0Y2hlck1hcC5zZXQobWF0Y2hlci5yZWNvcmQubmFtZSwgbWF0Y2hlcik7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiByZXNvbHZlKGxvY2F0aW9uLCBjdXJyZW50TG9jYXRpb24pIHtcclxuICAgICAgICBsZXQgbWF0Y2hlcjtcclxuICAgICAgICBsZXQgcGFyYW1zID0ge307XHJcbiAgICAgICAgbGV0IHBhdGg7XHJcbiAgICAgICAgbGV0IG5hbWU7XHJcbiAgICAgICAgaWYgKCduYW1lJyBpbiBsb2NhdGlvbiAmJiBsb2NhdGlvbi5uYW1lKSB7XHJcbiAgICAgICAgICAgIG1hdGNoZXIgPSBtYXRjaGVyTWFwLmdldChsb2NhdGlvbi5uYW1lKTtcclxuICAgICAgICAgICAgaWYgKCFtYXRjaGVyKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlUm91dGVyRXJyb3IoMSAvKiBNQVRDSEVSX05PVF9GT1VORCAqLywge1xyXG4gICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIG5hbWUgPSBtYXRjaGVyLnJlY29yZC5uYW1lO1xyXG4gICAgICAgICAgICBwYXJhbXMgPSBhc3NpZ24oXHJcbiAgICAgICAgICAgIC8vIHBhcmFtc0Zyb21Mb2NhdGlvbiBpcyBhIG5ldyBvYmplY3RcclxuICAgICAgICAgICAgcGFyYW1zRnJvbUxvY2F0aW9uKGN1cnJlbnRMb2NhdGlvbi5wYXJhbXMsIFxyXG4gICAgICAgICAgICAvLyBvbmx5IGtlZXAgcGFyYW1zIHRoYXQgZXhpc3QgaW4gdGhlIHJlc29sdmVkIGxvY2F0aW9uXHJcbiAgICAgICAgICAgIC8vIFRPRE86IG9ubHkga2VlcCBvcHRpb25hbCBwYXJhbXMgY29taW5nIGZyb20gYSBwYXJlbnQgcmVjb3JkXHJcbiAgICAgICAgICAgIG1hdGNoZXIua2V5cy5maWx0ZXIoayA9PiAhay5vcHRpb25hbCkubWFwKGsgPT4gay5uYW1lKSksIGxvY2F0aW9uLnBhcmFtcyk7XHJcbiAgICAgICAgICAgIC8vIHRocm93cyBpZiBjYW5ub3QgYmUgc3RyaW5naWZpZWRcclxuICAgICAgICAgICAgcGF0aCA9IG1hdGNoZXIuc3RyaW5naWZ5KHBhcmFtcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKCdwYXRoJyBpbiBsb2NhdGlvbikge1xyXG4gICAgICAgICAgICAvLyBubyBuZWVkIHRvIHJlc29sdmUgdGhlIHBhdGggd2l0aCB0aGUgbWF0Y2hlciBhcyBpdCB3YXMgcHJvdmlkZWRcclxuICAgICAgICAgICAgLy8gdGhpcyBhbHNvIGFsbG93cyB0aGUgdXNlciB0byBjb250cm9sIHRoZSBlbmNvZGluZ1xyXG4gICAgICAgICAgICBwYXRoID0gbG9jYXRpb24ucGF0aDtcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhcGF0aC5zdGFydHNXaXRoKCcvJykpIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oYFRoZSBNYXRjaGVyIGNhbm5vdCByZXNvbHZlIHJlbGF0aXZlIHBhdGhzIGJ1dCByZWNlaXZlZCBcIiR7cGF0aH1cIi4gVW5sZXNzIHlvdSBkaXJlY3RseSBjYWxsZWQgXFxgbWF0Y2hlci5yZXNvbHZlKFwiJHtwYXRofVwiKVxcYCwgdGhpcyBpcyBwcm9iYWJseSBhIGJ1ZyBpbiB2dWUtcm91dGVyLiBQbGVhc2Ugb3BlbiBhbiBpc3N1ZSBhdCBodHRwczovL25ldy1pc3N1ZS52dWVqcy5vcmcvP3JlcG89dnVlanMvdnVlLXJvdXRlci1uZXh0LmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG1hdGNoZXIgPSBtYXRjaGVycy5maW5kKG0gPT4gbS5yZS50ZXN0KHBhdGgpKTtcclxuICAgICAgICAgICAgLy8gbWF0Y2hlciBzaG91bGQgaGF2ZSBhIHZhbHVlIGFmdGVyIHRoZSBsb29wXHJcbiAgICAgICAgICAgIGlmIChtYXRjaGVyKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBkZXYgd2FybmluZyBvZiB1bnVzZWQgcGFyYW1zIGlmIHByb3ZpZGVkXHJcbiAgICAgICAgICAgICAgICAvLyB3ZSBrbm93IHRoZSBtYXRjaGVyIHdvcmtzIGJlY2F1c2Ugd2UgdGVzdGVkIHRoZSByZWdleHBcclxuICAgICAgICAgICAgICAgIHBhcmFtcyA9IG1hdGNoZXIucGFyc2UocGF0aCk7XHJcbiAgICAgICAgICAgICAgICBuYW1lID0gbWF0Y2hlci5yZWNvcmQubmFtZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBsb2NhdGlvbiBpcyBhIHJlbGF0aXZlIHBhdGhcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIG1hdGNoIGJ5IG5hbWUgb3IgcGF0aCBvZiBjdXJyZW50IHJvdXRlXHJcbiAgICAgICAgICAgIG1hdGNoZXIgPSBjdXJyZW50TG9jYXRpb24ubmFtZVxyXG4gICAgICAgICAgICAgICAgPyBtYXRjaGVyTWFwLmdldChjdXJyZW50TG9jYXRpb24ubmFtZSlcclxuICAgICAgICAgICAgICAgIDogbWF0Y2hlcnMuZmluZChtID0+IG0ucmUudGVzdChjdXJyZW50TG9jYXRpb24ucGF0aCkpO1xyXG4gICAgICAgICAgICBpZiAoIW1hdGNoZXIpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVSb3V0ZXJFcnJvcigxIC8qIE1BVENIRVJfTk9UX0ZPVU5EICovLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudExvY2F0aW9uLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIG5hbWUgPSBtYXRjaGVyLnJlY29yZC5uYW1lO1xyXG4gICAgICAgICAgICAvLyBzaW5jZSB3ZSBhcmUgbmF2aWdhdGluZyB0byB0aGUgc2FtZSBsb2NhdGlvbiwgd2UgZG9uJ3QgbmVlZCB0byBwaWNrIHRoZVxyXG4gICAgICAgICAgICAvLyBwYXJhbXMgbGlrZSB3aGVuIGBuYW1lYCBpcyBwcm92aWRlZFxyXG4gICAgICAgICAgICBwYXJhbXMgPSBhc3NpZ24oe30sIGN1cnJlbnRMb2NhdGlvbi5wYXJhbXMsIGxvY2F0aW9uLnBhcmFtcyk7XHJcbiAgICAgICAgICAgIHBhdGggPSBtYXRjaGVyLnN0cmluZ2lmeShwYXJhbXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtYXRjaGVkID0gW107XHJcbiAgICAgICAgbGV0IHBhcmVudE1hdGNoZXIgPSBtYXRjaGVyO1xyXG4gICAgICAgIHdoaWxlIChwYXJlbnRNYXRjaGVyKSB7XHJcbiAgICAgICAgICAgIC8vIHJldmVyc2VkIG9yZGVyIHNvIHBhcmVudHMgYXJlIGF0IHRoZSBiZWdpbm5pbmdcclxuICAgICAgICAgICAgbWF0Y2hlZC51bnNoaWZ0KHBhcmVudE1hdGNoZXIucmVjb3JkKTtcclxuICAgICAgICAgICAgcGFyZW50TWF0Y2hlciA9IHBhcmVudE1hdGNoZXIucGFyZW50O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBuYW1lLFxyXG4gICAgICAgICAgICBwYXRoLFxyXG4gICAgICAgICAgICBwYXJhbXMsXHJcbiAgICAgICAgICAgIG1hdGNoZWQsXHJcbiAgICAgICAgICAgIG1ldGE6IG1lcmdlTWV0YUZpZWxkcyhtYXRjaGVkKSxcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgLy8gYWRkIGluaXRpYWwgcm91dGVzXHJcbiAgICByb3V0ZXMuZm9yRWFjaChyb3V0ZSA9PiBhZGRSb3V0ZShyb3V0ZSkpO1xyXG4gICAgcmV0dXJuIHsgYWRkUm91dGUsIHJlc29sdmUsIHJlbW92ZVJvdXRlLCBnZXRSb3V0ZXMsIGdldFJlY29yZE1hdGNoZXIgfTtcclxufVxyXG5mdW5jdGlvbiBwYXJhbXNGcm9tTG9jYXRpb24ocGFyYW1zLCBrZXlzKSB7XHJcbiAgICBjb25zdCBuZXdQYXJhbXMgPSB7fTtcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcclxuICAgICAgICBpZiAoa2V5IGluIHBhcmFtcylcclxuICAgICAgICAgICAgbmV3UGFyYW1zW2tleV0gPSBwYXJhbXNba2V5XTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXdQYXJhbXM7XHJcbn1cclxuLyoqXHJcbiAqIE5vcm1hbGl6ZXMgYSBSb3V0ZVJlY29yZFJhdy4gQ3JlYXRlcyBhIGNvcHlcclxuICpcclxuICogQHBhcmFtIHJlY29yZFxyXG4gKiBAcmV0dXJucyB0aGUgbm9ybWFsaXplZCB2ZXJzaW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBub3JtYWxpemVSb3V0ZVJlY29yZChyZWNvcmQpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgcGF0aDogcmVjb3JkLnBhdGgsXHJcbiAgICAgICAgcmVkaXJlY3Q6IHJlY29yZC5yZWRpcmVjdCxcclxuICAgICAgICBuYW1lOiByZWNvcmQubmFtZSxcclxuICAgICAgICBtZXRhOiByZWNvcmQubWV0YSB8fCB7fSxcclxuICAgICAgICBhbGlhc09mOiB1bmRlZmluZWQsXHJcbiAgICAgICAgYmVmb3JlRW50ZXI6IHJlY29yZC5iZWZvcmVFbnRlcixcclxuICAgICAgICBwcm9wczogbm9ybWFsaXplUmVjb3JkUHJvcHMocmVjb3JkKSxcclxuICAgICAgICBjaGlsZHJlbjogcmVjb3JkLmNoaWxkcmVuIHx8IFtdLFxyXG4gICAgICAgIGluc3RhbmNlczoge30sXHJcbiAgICAgICAgbGVhdmVHdWFyZHM6IG5ldyBTZXQoKSxcclxuICAgICAgICB1cGRhdGVHdWFyZHM6IG5ldyBTZXQoKSxcclxuICAgICAgICBlbnRlckNhbGxiYWNrczoge30sXHJcbiAgICAgICAgY29tcG9uZW50czogJ2NvbXBvbmVudHMnIGluIHJlY29yZFxyXG4gICAgICAgICAgICA/IHJlY29yZC5jb21wb25lbnRzIHx8IHt9XHJcbiAgICAgICAgICAgIDogeyBkZWZhdWx0OiByZWNvcmQuY29tcG9uZW50IH0sXHJcbiAgICB9O1xyXG59XHJcbi8qKlxyXG4gKiBOb3JtYWxpemUgdGhlIG9wdGlvbmFsIGBwcm9wc2AgaW4gYSByZWNvcmQgdG8gYWx3YXlzIGJlIGFuIG9iamVjdCBzaW1pbGFyIHRvXHJcbiAqIGNvbXBvbmVudHMuIEFsc28gYWNjZXB0IGEgYm9vbGVhbiBmb3IgY29tcG9uZW50cy5cclxuICogQHBhcmFtIHJlY29yZFxyXG4gKi9cclxuZnVuY3Rpb24gbm9ybWFsaXplUmVjb3JkUHJvcHMocmVjb3JkKSB7XHJcbiAgICBjb25zdCBwcm9wc09iamVjdCA9IHt9O1xyXG4gICAgLy8gcHJvcHMgZG9lcyBub3QgZXhpc3Qgb24gcmVkaXJlY3QgcmVjb3JkcyBidXQgd2UgY2FuIHNldCBmYWxzZSBkaXJlY3RseVxyXG4gICAgY29uc3QgcHJvcHMgPSByZWNvcmQucHJvcHMgfHwgZmFsc2U7XHJcbiAgICBpZiAoJ2NvbXBvbmVudCcgaW4gcmVjb3JkKSB7XHJcbiAgICAgICAgcHJvcHNPYmplY3QuZGVmYXVsdCA9IHByb3BzO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgLy8gTk9URTogd2UgY291bGQgYWxzbyBhbGxvdyBhIGZ1bmN0aW9uIHRvIGJlIGFwcGxpZWQgdG8gZXZlcnkgY29tcG9uZW50LlxyXG4gICAgICAgIC8vIFdvdWxkIG5lZWQgdXNlciBmZWVkYmFjayBmb3IgdXNlIGNhc2VzXHJcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIHJlY29yZC5jb21wb25lbnRzKVxyXG4gICAgICAgICAgICBwcm9wc09iamVjdFtuYW1lXSA9IHR5cGVvZiBwcm9wcyA9PT0gJ2Jvb2xlYW4nID8gcHJvcHMgOiBwcm9wc1tuYW1lXTtcclxuICAgIH1cclxuICAgIHJldHVybiBwcm9wc09iamVjdDtcclxufVxyXG4vKipcclxuICogQ2hlY2tzIGlmIGEgcmVjb3JkIG9yIGFueSBvZiBpdHMgcGFyZW50IGlzIGFuIGFsaWFzXHJcbiAqIEBwYXJhbSByZWNvcmRcclxuICovXHJcbmZ1bmN0aW9uIGlzQWxpYXNSZWNvcmQocmVjb3JkKSB7XHJcbiAgICB3aGlsZSAocmVjb3JkKSB7XHJcbiAgICAgICAgaWYgKHJlY29yZC5yZWNvcmQuYWxpYXNPZilcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgcmVjb3JkID0gcmVjb3JkLnBhcmVudDtcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG4vKipcclxuICogTWVyZ2UgbWV0YSBmaWVsZHMgb2YgYW4gYXJyYXkgb2YgcmVjb3Jkc1xyXG4gKlxyXG4gKiBAcGFyYW0gbWF0Y2hlZCAtIGFycmF5IG9mIG1hdGNoZWQgcmVjb3Jkc1xyXG4gKi9cclxuZnVuY3Rpb24gbWVyZ2VNZXRhRmllbGRzKG1hdGNoZWQpIHtcclxuICAgIHJldHVybiBtYXRjaGVkLnJlZHVjZSgobWV0YSwgcmVjb3JkKSA9PiBhc3NpZ24obWV0YSwgcmVjb3JkLm1ldGEpLCB7fSk7XHJcbn1cclxuZnVuY3Rpb24gbWVyZ2VPcHRpb25zKGRlZmF1bHRzLCBwYXJ0aWFsT3B0aW9ucykge1xyXG4gICAgY29uc3Qgb3B0aW9ucyA9IHt9O1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gZGVmYXVsdHMpIHtcclxuICAgICAgICBvcHRpb25zW2tleV0gPSBrZXkgaW4gcGFydGlhbE9wdGlvbnMgPyBwYXJ0aWFsT3B0aW9uc1trZXldIDogZGVmYXVsdHNba2V5XTtcclxuICAgIH1cclxuICAgIHJldHVybiBvcHRpb25zO1xyXG59XHJcbmZ1bmN0aW9uIGlzU2FtZVBhcmFtKGEsIGIpIHtcclxuICAgIHJldHVybiAoYS5uYW1lID09PSBiLm5hbWUgJiZcclxuICAgICAgICBhLm9wdGlvbmFsID09PSBiLm9wdGlvbmFsICYmXHJcbiAgICAgICAgYS5yZXBlYXRhYmxlID09PSBiLnJlcGVhdGFibGUpO1xyXG59XHJcbi8qKlxyXG4gKiBDaGVjayBpZiBhIHBhdGggYW5kIGl0cyBhbGlhcyBoYXZlIHRoZSBzYW1lIHJlcXVpcmVkIHBhcmFtc1xyXG4gKlxyXG4gKiBAcGFyYW0gYSAtIG9yaWdpbmFsIHJlY29yZFxyXG4gKiBAcGFyYW0gYiAtIGFsaWFzIHJlY29yZFxyXG4gKi9cclxuZnVuY3Rpb24gY2hlY2tTYW1lUGFyYW1zKGEsIGIpIHtcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIGEua2V5cykge1xyXG4gICAgICAgIGlmICgha2V5Lm9wdGlvbmFsICYmICFiLmtleXMuZmluZChpc1NhbWVQYXJhbS5iaW5kKG51bGwsIGtleSkpKVxyXG4gICAgICAgICAgICByZXR1cm4gd2FybihgQWxpYXMgXCIke2IucmVjb3JkLnBhdGh9XCIgYW5kIHRoZSBvcmlnaW5hbCByZWNvcmQ6IFwiJHthLnJlY29yZC5wYXRofVwiIHNob3VsZCBoYXZlIHRoZSBleGFjdCBzYW1lIHBhcmFtIG5hbWVkIFwiJHtrZXkubmFtZX1cImApO1xyXG4gICAgfVxyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgYi5rZXlzKSB7XHJcbiAgICAgICAgaWYgKCFrZXkub3B0aW9uYWwgJiYgIWEua2V5cy5maW5kKGlzU2FtZVBhcmFtLmJpbmQobnVsbCwga2V5KSkpXHJcbiAgICAgICAgICAgIHJldHVybiB3YXJuKGBBbGlhcyBcIiR7Yi5yZWNvcmQucGF0aH1cIiBhbmQgdGhlIG9yaWdpbmFsIHJlY29yZDogXCIke2EucmVjb3JkLnBhdGh9XCIgc2hvdWxkIGhhdmUgdGhlIGV4YWN0IHNhbWUgcGFyYW0gbmFtZWQgXCIke2tleS5uYW1lfVwiYCk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gY2hlY2tNaXNzaW5nUGFyYW1zSW5BYnNvbHV0ZVBhdGgocmVjb3JkLCBwYXJlbnQpIHtcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIHBhcmVudC5rZXlzKSB7XHJcbiAgICAgICAgaWYgKCFyZWNvcmQua2V5cy5maW5kKGlzU2FtZVBhcmFtLmJpbmQobnVsbCwga2V5KSkpXHJcbiAgICAgICAgICAgIHJldHVybiB3YXJuKGBBYnNvbHV0ZSBwYXRoIFwiJHtyZWNvcmQucmVjb3JkLnBhdGh9XCIgc2hvdWxkIGhhdmUgdGhlIGV4YWN0IHNhbWUgcGFyYW0gbmFtZWQgXCIke2tleS5uYW1lfVwiIGFzIGl0cyBwYXJlbnQgXCIke3BhcmVudC5yZWNvcmQucGF0aH1cIi5gKTtcclxuICAgIH1cclxufVxuXG4vKipcclxuICogRW5jb2RpbmcgUnVsZXMg4pCjID0gU3BhY2UgUGF0aDog4pCjIFwiIDwgPiAjID8geyB9IFF1ZXJ5OiDikKMgXCIgPCA+ICMgJiA9IEhhc2g6IOKQoyBcIlxyXG4gKiA8ID4gYFxyXG4gKlxyXG4gKiBPbiB0b3Agb2YgdGhhdCwgdGhlIFJGQzM5ODYgKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzOTg2I3NlY3Rpb24tMi4yKVxyXG4gKiBkZWZpbmVzIHNvbWUgZXh0cmEgY2hhcmFjdGVycyB0byBiZSBlbmNvZGVkLiBNb3N0IGJyb3dzZXJzIGRvIG5vdCBlbmNvZGUgdGhlbVxyXG4gKiBpbiBlbmNvZGVVUkkgaHR0cHM6Ly9naXRodWIuY29tL3doYXR3Zy91cmwvaXNzdWVzLzM2OSwgc28gaXQgbWF5IGJlIHNhZmVyIHRvXHJcbiAqIGFsc28gZW5jb2RlIGAhJygpKmAuIExlYXZpbmcgdW5lbmNvZGVkIG9ubHkgQVNDSUkgYWxwaGFudW1lcmljKGBhLXpBLVowLTlgKVxyXG4gKiBwbHVzIGAtLl9+YC4gVGhpcyBleHRyYSBzYWZldHkgc2hvdWxkIGJlIGFwcGxpZWQgdG8gcXVlcnkgYnkgcGF0Y2hpbmcgdGhlXHJcbiAqIHN0cmluZyByZXR1cm5lZCBieSBlbmNvZGVVUklDb21wb25lbnQgZW5jb2RlVVJJIGFsc28gZW5jb2RlcyBgW1xcXV5gLiBgXFxgXHJcbiAqIHNob3VsZCBiZSBlbmNvZGVkIHRvIGF2b2lkIGFtYmlndWl0eS4gQnJvd3NlcnMgKElFLCBGRiwgQykgdHJhbnNmb3JtIGEgYFxcYFxyXG4gKiBpbnRvIGEgYC9gIGlmIGRpcmVjdGx5IHR5cGVkIGluLiBUaGUgX2JhY2t0aWNrXyAoYGBgYGApIHNob3VsZCBhbHNvIGJlXHJcbiAqIGVuY29kZWQgZXZlcnl3aGVyZSBiZWNhdXNlIHNvbWUgYnJvd3NlcnMgbGlrZSBGRiBlbmNvZGUgaXQgd2hlbiBkaXJlY3RseVxyXG4gKiB3cml0dGVuIHdoaWxlIG90aGVycyBkb24ndC4gU2FmYXJpIGFuZCBJRSBkb24ndCBlbmNvZGUgYGBcIjw+e31gYGAgaW4gaGFzaC5cclxuICovXHJcbi8vIGNvbnN0IEVYVFJBX1JFU0VSVkVEX1JFID0gL1shJygpKl0vZ1xyXG4vLyBjb25zdCBlbmNvZGVSZXNlcnZlZFJlcGxhY2VyID0gKGM6IHN0cmluZykgPT4gJyUnICsgYy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KVxyXG5jb25zdCBIQVNIX1JFID0gLyMvZzsgLy8gJTIzXHJcbmNvbnN0IEFNUEVSU0FORF9SRSA9IC8mL2c7IC8vICUyNlxyXG5jb25zdCBTTEFTSF9SRSA9IC9cXC8vZzsgLy8gJTJGXHJcbmNvbnN0IEVRVUFMX1JFID0gLz0vZzsgLy8gJTNEXHJcbmNvbnN0IElNX1JFID0gL1xcPy9nOyAvLyAlM0ZcclxuY29uc3QgUExVU19SRSA9IC9cXCsvZzsgLy8gJTJCXHJcbi8qKlxyXG4gKiBOT1RFOiBJdCdzIG5vdCBjbGVhciB0byBtZSBpZiB3ZSBzaG91bGQgZW5jb2RlIHRoZSArIHN5bWJvbCBpbiBxdWVyaWVzLCBpdFxyXG4gKiBzZWVtcyB0byBiZSBsZXNzIGZsZXhpYmxlIHRoYW4gbm90IGRvaW5nIHNvIGFuZCBJIGNhbid0IGZpbmQgb3V0IHRoZSBsZWdhY3lcclxuICogc3lzdGVtcyByZXF1aXJpbmcgdGhpcyBmb3IgcmVndWxhciByZXF1ZXN0cyBsaWtlIHRleHQvaHRtbC4gSW4gdGhlIHN0YW5kYXJkLFxyXG4gKiB0aGUgZW5jb2Rpbmcgb2YgdGhlIHBsdXMgY2hhcmFjdGVyIGlzIG9ubHkgbWVudGlvbmVkIGZvclxyXG4gKiBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcclxuICogKGh0dHBzOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsZW5jb2RlZC1wYXJzaW5nKSBhbmQgbW9zdCBicm93c2VycyBzZWVtcyBsb1xyXG4gKiBsZWF2ZSB0aGUgcGx1cyBjaGFyYWN0ZXIgYXMgaXMgaW4gcXVlcmllcy4gVG8gYmUgbW9yZSBmbGV4aWJsZSwgd2UgYWxsb3cgdGhlXHJcbiAqIHBsdXMgY2hhcmFjdGVyIG9uIHRoZSBxdWVyeSBidXQgaXQgY2FuIGFsc28gYmUgbWFudWFsbHkgZW5jb2RlZCBieSB0aGUgdXNlci5cclxuICpcclxuICogUmVzb3VyY2VzOlxyXG4gKiAtIGh0dHBzOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsZW5jb2RlZC1wYXJzaW5nXHJcbiAqIC0gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTYzNDI3MS91cmwtZW5jb2RpbmctdGhlLXNwYWNlLWNoYXJhY3Rlci1vci0yMFxyXG4gKi9cclxuY29uc3QgRU5DX0JSQUNLRVRfT1BFTl9SRSA9IC8lNUIvZzsgLy8gW1xyXG5jb25zdCBFTkNfQlJBQ0tFVF9DTE9TRV9SRSA9IC8lNUQvZzsgLy8gXVxyXG5jb25zdCBFTkNfQ0FSRVRfUkUgPSAvJTVFL2c7IC8vIF5cclxuY29uc3QgRU5DX0JBQ0tUSUNLX1JFID0gLyU2MC9nOyAvLyBgXHJcbmNvbnN0IEVOQ19DVVJMWV9PUEVOX1JFID0gLyU3Qi9nOyAvLyB7XHJcbmNvbnN0IEVOQ19QSVBFX1JFID0gLyU3Qy9nOyAvLyB8XHJcbmNvbnN0IEVOQ19DVVJMWV9DTE9TRV9SRSA9IC8lN0QvZzsgLy8gfVxyXG5jb25zdCBFTkNfU1BBQ0VfUkUgPSAvJTIwL2c7IC8vIH1cclxuLyoqXHJcbiAqIEVuY29kZSBjaGFyYWN0ZXJzIHRoYXQgbmVlZCB0byBiZSBlbmNvZGVkIG9uIHRoZSBwYXRoLCBzZWFyY2ggYW5kIGhhc2hcclxuICogc2VjdGlvbnMgb2YgdGhlIFVSTC5cclxuICpcclxuICogQGludGVybmFsXHJcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxyXG4gKiBAcmV0dXJucyBlbmNvZGVkIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gY29tbW9uRW5jb2RlKHRleHQpIHtcclxuICAgIHJldHVybiBlbmNvZGVVUkkoJycgKyB0ZXh0KVxyXG4gICAgICAgIC5yZXBsYWNlKEVOQ19QSVBFX1JFLCAnfCcpXHJcbiAgICAgICAgLnJlcGxhY2UoRU5DX0JSQUNLRVRfT1BFTl9SRSwgJ1snKVxyXG4gICAgICAgIC5yZXBsYWNlKEVOQ19CUkFDS0VUX0NMT1NFX1JFLCAnXScpO1xyXG59XHJcbi8qKlxyXG4gKiBFbmNvZGUgY2hhcmFjdGVycyB0aGF0IG5lZWQgdG8gYmUgZW5jb2RlZCBvbiB0aGUgaGFzaCBzZWN0aW9uIG9mIHRoZSBVUkwuXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxyXG4gKiBAcmV0dXJucyBlbmNvZGVkIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZW5jb2RlSGFzaCh0ZXh0KSB7XHJcbiAgICByZXR1cm4gY29tbW9uRW5jb2RlKHRleHQpXHJcbiAgICAgICAgLnJlcGxhY2UoRU5DX0NVUkxZX09QRU5fUkUsICd7JylcclxuICAgICAgICAucmVwbGFjZShFTkNfQ1VSTFlfQ0xPU0VfUkUsICd9JylcclxuICAgICAgICAucmVwbGFjZShFTkNfQ0FSRVRfUkUsICdeJyk7XHJcbn1cclxuLyoqXHJcbiAqIEVuY29kZSBjaGFyYWN0ZXJzIHRoYXQgbmVlZCB0byBiZSBlbmNvZGVkIHF1ZXJ5IHZhbHVlcyBvbiB0aGUgcXVlcnlcclxuICogc2VjdGlvbiBvZiB0aGUgVVJMLlxyXG4gKlxyXG4gKiBAcGFyYW0gdGV4dCAtIHN0cmluZyB0byBlbmNvZGVcclxuICogQHJldHVybnMgZW5jb2RlZCBzdHJpbmdcclxuICovXHJcbmZ1bmN0aW9uIGVuY29kZVF1ZXJ5VmFsdWUodGV4dCkge1xyXG4gICAgcmV0dXJuIChjb21tb25FbmNvZGUodGV4dClcclxuICAgICAgICAvLyBFbmNvZGUgdGhlIHNwYWNlIGFzICssIGVuY29kZSB0aGUgKyB0byBkaWZmZXJlbnRpYXRlIGl0IGZyb20gdGhlIHNwYWNlXHJcbiAgICAgICAgLnJlcGxhY2UoUExVU19SRSwgJyUyQicpXHJcbiAgICAgICAgLnJlcGxhY2UoRU5DX1NQQUNFX1JFLCAnKycpXHJcbiAgICAgICAgLnJlcGxhY2UoSEFTSF9SRSwgJyUyMycpXHJcbiAgICAgICAgLnJlcGxhY2UoQU1QRVJTQU5EX1JFLCAnJTI2JylcclxuICAgICAgICAucmVwbGFjZShFTkNfQkFDS1RJQ0tfUkUsICdgJylcclxuICAgICAgICAucmVwbGFjZShFTkNfQ1VSTFlfT1BFTl9SRSwgJ3snKVxyXG4gICAgICAgIC5yZXBsYWNlKEVOQ19DVVJMWV9DTE9TRV9SRSwgJ30nKVxyXG4gICAgICAgIC5yZXBsYWNlKEVOQ19DQVJFVF9SRSwgJ14nKSk7XHJcbn1cclxuLyoqXHJcbiAqIExpa2UgYGVuY29kZVF1ZXJ5VmFsdWVgIGJ1dCBhbHNvIGVuY29kZXMgdGhlIGA9YCBjaGFyYWN0ZXIuXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxyXG4gKi9cclxuZnVuY3Rpb24gZW5jb2RlUXVlcnlLZXkodGV4dCkge1xyXG4gICAgcmV0dXJuIGVuY29kZVF1ZXJ5VmFsdWUodGV4dCkucmVwbGFjZShFUVVBTF9SRSwgJyUzRCcpO1xyXG59XHJcbi8qKlxyXG4gKiBFbmNvZGUgY2hhcmFjdGVycyB0aGF0IG5lZWQgdG8gYmUgZW5jb2RlZCBvbiB0aGUgcGF0aCBzZWN0aW9uIG9mIHRoZSBVUkwuXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGVuY29kZVxyXG4gKiBAcmV0dXJucyBlbmNvZGVkIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZW5jb2RlUGF0aCh0ZXh0KSB7XHJcbiAgICByZXR1cm4gY29tbW9uRW5jb2RlKHRleHQpLnJlcGxhY2UoSEFTSF9SRSwgJyUyMycpLnJlcGxhY2UoSU1fUkUsICclM0YnKTtcclxufVxyXG4vKipcclxuICogRW5jb2RlIGNoYXJhY3RlcnMgdGhhdCBuZWVkIHRvIGJlIGVuY29kZWQgb24gdGhlIHBhdGggc2VjdGlvbiBvZiB0aGUgVVJMIGFzIGFcclxuICogcGFyYW0uIFRoaXMgZnVuY3Rpb24gZW5jb2RlcyBldmVyeXRoaW5nIHtAbGluayBlbmNvZGVQYXRofSBkb2VzIHBsdXMgdGhlXHJcbiAqIHNsYXNoIChgL2ApIGNoYXJhY3Rlci4gSWYgYHRleHRgIGlzIGBudWxsYCBvciBgdW5kZWZpbmVkYCwgcmV0dXJucyBhbiBlbXB0eVxyXG4gKiBzdHJpbmcgaW5zdGVhZC5cclxuICpcclxuICogQHBhcmFtIHRleHQgLSBzdHJpbmcgdG8gZW5jb2RlXHJcbiAqIEByZXR1cm5zIGVuY29kZWQgc3RyaW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBlbmNvZGVQYXJhbSh0ZXh0KSB7XHJcbiAgICByZXR1cm4gdGV4dCA9PSBudWxsID8gJycgOiBlbmNvZGVQYXRoKHRleHQpLnJlcGxhY2UoU0xBU0hfUkUsICclMkYnKTtcclxufVxyXG4vKipcclxuICogRGVjb2RlIHRleHQgdXNpbmcgYGRlY29kZVVSSUNvbXBvbmVudGAuIFJldHVybnMgdGhlIG9yaWdpbmFsIHRleHQgaWYgaXRcclxuICogZmFpbHMuXHJcbiAqXHJcbiAqIEBwYXJhbSB0ZXh0IC0gc3RyaW5nIHRvIGRlY29kZVxyXG4gKiBAcmV0dXJucyBkZWNvZGVkIHN0cmluZ1xyXG4gKi9cclxuZnVuY3Rpb24gZGVjb2RlKHRleHQpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCgnJyArIHRleHQpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycikge1xyXG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB3YXJuKGBFcnJvciBkZWNvZGluZyBcIiR7dGV4dH1cIi4gVXNpbmcgb3JpZ2luYWwgdmFsdWVgKTtcclxuICAgIH1cclxuICAgIHJldHVybiAnJyArIHRleHQ7XHJcbn1cblxuLyoqXHJcbiAqIFRyYW5zZm9ybXMgYSBxdWVyeVN0cmluZyBpbnRvIGEge0BsaW5rIExvY2F0aW9uUXVlcnl9IG9iamVjdC4gQWNjZXB0IGJvdGgsIGFcclxuICogdmVyc2lvbiB3aXRoIHRoZSBsZWFkaW5nIGA/YCBhbmQgd2l0aG91dCBTaG91bGQgd29yayBhcyBVUkxTZWFyY2hQYXJhbXNcclxuXG4gKiBAaW50ZXJuYWxcclxuICpcclxuICogQHBhcmFtIHNlYXJjaCAtIHNlYXJjaCBzdHJpbmcgdG8gcGFyc2VcclxuICogQHJldHVybnMgYSBxdWVyeSBvYmplY3RcclxuICovXHJcbmZ1bmN0aW9uIHBhcnNlUXVlcnkoc2VhcmNoKSB7XHJcbiAgICBjb25zdCBxdWVyeSA9IHt9O1xyXG4gICAgLy8gYXZvaWQgY3JlYXRpbmcgYW4gb2JqZWN0IHdpdGggYW4gZW1wdHkga2V5IGFuZCBlbXB0eSB2YWx1ZVxyXG4gICAgLy8gYmVjYXVzZSBvZiBzcGxpdCgnJicpXHJcbiAgICBpZiAoc2VhcmNoID09PSAnJyB8fCBzZWFyY2ggPT09ICc/JylcclxuICAgICAgICByZXR1cm4gcXVlcnk7XHJcbiAgICBjb25zdCBoYXNMZWFkaW5nSU0gPSBzZWFyY2hbMF0gPT09ICc/JztcclxuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IChoYXNMZWFkaW5nSU0gPyBzZWFyY2guc2xpY2UoMSkgOiBzZWFyY2gpLnNwbGl0KCcmJyk7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlYXJjaFBhcmFtcy5sZW5ndGg7ICsraSkge1xyXG4gICAgICAgIC8vIHByZSBkZWNvZGUgdGhlICsgaW50byBzcGFjZVxyXG4gICAgICAgIGNvbnN0IHNlYXJjaFBhcmFtID0gc2VhcmNoUGFyYW1zW2ldLnJlcGxhY2UoUExVU19SRSwgJyAnKTtcclxuICAgICAgICAvLyBhbGxvdyB0aGUgPSBjaGFyYWN0ZXJcclxuICAgICAgICBjb25zdCBlcVBvcyA9IHNlYXJjaFBhcmFtLmluZGV4T2YoJz0nKTtcclxuICAgICAgICBjb25zdCBrZXkgPSBkZWNvZGUoZXFQb3MgPCAwID8gc2VhcmNoUGFyYW0gOiBzZWFyY2hQYXJhbS5zbGljZSgwLCBlcVBvcykpO1xyXG4gICAgICAgIGNvbnN0IHZhbHVlID0gZXFQb3MgPCAwID8gbnVsbCA6IGRlY29kZShzZWFyY2hQYXJhbS5zbGljZShlcVBvcyArIDEpKTtcclxuICAgICAgICBpZiAoa2V5IGluIHF1ZXJ5KSB7XHJcbiAgICAgICAgICAgIC8vIGFuIGV4dHJhIHZhcmlhYmxlIGZvciB0cyB0eXBlc1xyXG4gICAgICAgICAgICBsZXQgY3VycmVudFZhbHVlID0gcXVlcnlba2V5XTtcclxuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGN1cnJlbnRWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRWYWx1ZSA9IHF1ZXJ5W2tleV0gPSBbY3VycmVudFZhbHVlXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjdXJyZW50VmFsdWUucHVzaCh2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBxdWVyeVtrZXldID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHF1ZXJ5O1xyXG59XHJcbi8qKlxyXG4gKiBTdHJpbmdpZmllcyBhIHtAbGluayBMb2NhdGlvblF1ZXJ5UmF3fSBvYmplY3QuIExpa2UgYFVSTFNlYXJjaFBhcmFtc2AsIGl0XHJcbiAqIGRvZXNuJ3QgcHJlcGVuZCBhIGA/YFxyXG4gKlxyXG4gKiBAaW50ZXJuYWxcclxuICpcclxuICogQHBhcmFtIHF1ZXJ5IC0gcXVlcnkgb2JqZWN0IHRvIHN0cmluZ2lmeVxyXG4gKiBAcmV0dXJucyBzdHJpbmcgdmVyc2lvbiBvZiB0aGUgcXVlcnkgd2l0aG91dCB0aGUgbGVhZGluZyBgP2BcclxuICovXHJcbmZ1bmN0aW9uIHN0cmluZ2lmeVF1ZXJ5KHF1ZXJ5KSB7XHJcbiAgICBsZXQgc2VhcmNoID0gJyc7XHJcbiAgICBmb3IgKGxldCBrZXkgaW4gcXVlcnkpIHtcclxuICAgICAgICBjb25zdCB2YWx1ZSA9IHF1ZXJ5W2tleV07XHJcbiAgICAgICAga2V5ID0gZW5jb2RlUXVlcnlLZXkoa2V5KTtcclxuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAvLyBvbmx5IG51bGwgYWRkcyB0aGUgdmFsdWVcclxuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIHNlYXJjaCArPSAoc2VhcmNoLmxlbmd0aCA/ICcmJyA6ICcnKSArIGtleTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8ga2VlcCBudWxsIHZhbHVlc1xyXG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IEFycmF5LmlzQXJyYXkodmFsdWUpXHJcbiAgICAgICAgICAgID8gdmFsdWUubWFwKHYgPT4gdiAmJiBlbmNvZGVRdWVyeVZhbHVlKHYpKVxyXG4gICAgICAgICAgICA6IFt2YWx1ZSAmJiBlbmNvZGVRdWVyeVZhbHVlKHZhbHVlKV07XHJcbiAgICAgICAgdmFsdWVzLmZvckVhY2godmFsdWUgPT4ge1xyXG4gICAgICAgICAgICAvLyBza2lwIHVuZGVmaW5lZCB2YWx1ZXMgaW4gYXJyYXlzIGFzIGlmIHRoZXkgd2VyZSBub3QgcHJlc2VudFxyXG4gICAgICAgICAgICAvLyBzbWFsbGVyIGNvZGUgdGhhbiB1c2luZyBmaWx0ZXJcclxuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIC8vIG9ubHkgYXBwZW5kICYgd2l0aCBub24tZW1wdHkgc2VhcmNoXHJcbiAgICAgICAgICAgICAgICBzZWFyY2ggKz0gKHNlYXJjaC5sZW5ndGggPyAnJicgOiAnJykgKyBrZXk7XHJcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbClcclxuICAgICAgICAgICAgICAgICAgICBzZWFyY2ggKz0gJz0nICsgdmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBzZWFyY2g7XHJcbn1cclxuLyoqXHJcbiAqIFRyYW5zZm9ybXMgYSB7QGxpbmsgTG9jYXRpb25RdWVyeVJhd30gaW50byBhIHtAbGluayBMb2NhdGlvblF1ZXJ5fSBieSBjYXN0aW5nXHJcbiAqIG51bWJlcnMgaW50byBzdHJpbmdzLCByZW1vdmluZyBrZXlzIHdpdGggYW4gdW5kZWZpbmVkIHZhbHVlIGFuZCByZXBsYWNpbmdcclxuICogdW5kZWZpbmVkIHdpdGggbnVsbCBpbiBhcnJheXNcclxuICpcclxuICogQHBhcmFtIHF1ZXJ5IC0gcXVlcnkgb2JqZWN0IHRvIG5vcm1hbGl6ZVxyXG4gKiBAcmV0dXJucyBhIG5vcm1hbGl6ZWQgcXVlcnkgb2JqZWN0XHJcbiAqL1xyXG5mdW5jdGlvbiBub3JtYWxpemVRdWVyeShxdWVyeSkge1xyXG4gICAgY29uc3Qgbm9ybWFsaXplZFF1ZXJ5ID0ge307XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBxdWVyeSkge1xyXG4gICAgICAgIGNvbnN0IHZhbHVlID0gcXVlcnlba2V5XTtcclxuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBub3JtYWxpemVkUXVlcnlba2V5XSA9IEFycmF5LmlzQXJyYXkodmFsdWUpXHJcbiAgICAgICAgICAgICAgICA/IHZhbHVlLm1hcCh2ID0+ICh2ID09IG51bGwgPyBudWxsIDogJycgKyB2KSlcclxuICAgICAgICAgICAgICAgIDogdmFsdWUgPT0gbnVsbFxyXG4gICAgICAgICAgICAgICAgICAgID8gdmFsdWVcclxuICAgICAgICAgICAgICAgICAgICA6ICcnICsgdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5vcm1hbGl6ZWRRdWVyeTtcclxufVxuXG4vKipcclxuICogQ3JlYXRlIGEgbGlzdCBvZiBjYWxsYmFja3MgdGhhdCBjYW4gYmUgcmVzZXQuIFVzZWQgdG8gY3JlYXRlIGJlZm9yZSBhbmQgYWZ0ZXIgbmF2aWdhdGlvbiBndWFyZHMgbGlzdFxyXG4gKi9cclxuZnVuY3Rpb24gdXNlQ2FsbGJhY2tzKCkge1xyXG4gICAgbGV0IGhhbmRsZXJzID0gW107XHJcbiAgICBmdW5jdGlvbiBhZGQoaGFuZGxlcikge1xyXG4gICAgICAgIGhhbmRsZXJzLnB1c2goaGFuZGxlcik7XHJcbiAgICAgICAgcmV0dXJuICgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgaSA9IGhhbmRsZXJzLmluZGV4T2YoaGFuZGxlcik7XHJcbiAgICAgICAgICAgIGlmIChpID4gLTEpXHJcbiAgICAgICAgICAgICAgICBoYW5kbGVycy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIHJlc2V0KCkge1xyXG4gICAgICAgIGhhbmRsZXJzID0gW107XHJcbiAgICB9XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGFkZCxcclxuICAgICAgICBsaXN0OiAoKSA9PiBoYW5kbGVycyxcclxuICAgICAgICByZXNldCxcclxuICAgIH07XHJcbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJHdWFyZChyZWNvcmQsIG5hbWUsIGd1YXJkKSB7XHJcbiAgICBjb25zdCByZW1vdmVGcm9tTGlzdCA9ICgpID0+IHtcclxuICAgICAgICByZWNvcmRbbmFtZV0uZGVsZXRlKGd1YXJkKTtcclxuICAgIH07XHJcbiAgICBvblVubW91bnRlZChyZW1vdmVGcm9tTGlzdCk7XHJcbiAgICBvbkRlYWN0aXZhdGVkKHJlbW92ZUZyb21MaXN0KTtcclxuICAgIG9uQWN0aXZhdGVkKCgpID0+IHtcclxuICAgICAgICByZWNvcmRbbmFtZV0uYWRkKGd1YXJkKTtcclxuICAgIH0pO1xyXG4gICAgcmVjb3JkW25hbWVdLmFkZChndWFyZCk7XHJcbn1cclxuLyoqXHJcbiAqIEFkZCBhIG5hdmlnYXRpb24gZ3VhcmQgdGhhdCB0cmlnZ2VycyB3aGVuZXZlciB0aGUgY29tcG9uZW50IGZvciB0aGUgY3VycmVudFxyXG4gKiBsb2NhdGlvbiBpcyBhYm91dCB0byBiZSBsZWZ0LiBTaW1pbGFyIHRvIHtAbGluayBiZWZvcmVSb3V0ZUxlYXZlfSBidXQgY2FuIGJlXHJcbiAqIHVzZWQgaW4gYW55IGNvbXBvbmVudC4gVGhlIGd1YXJkIGlzIHJlbW92ZWQgd2hlbiB0aGUgY29tcG9uZW50IGlzIHVubW91bnRlZC5cclxuICpcclxuICogQHBhcmFtIGxlYXZlR3VhcmQgLSB7QGxpbmsgTmF2aWdhdGlvbkd1YXJkfVxyXG4gKi9cclxuZnVuY3Rpb24gb25CZWZvcmVSb3V0ZUxlYXZlKGxlYXZlR3VhcmQpIHtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIWdldEN1cnJlbnRJbnN0YW5jZSgpKSB7XHJcbiAgICAgICAgd2FybignZ2V0Q3VycmVudEluc3RhbmNlKCkgcmV0dXJuZWQgbnVsbC4gb25CZWZvcmVSb3V0ZUxlYXZlKCkgbXVzdCBiZSBjYWxsZWQgYXQgdGhlIHRvcCBvZiBhIHNldHVwIGZ1bmN0aW9uJyk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgY29uc3QgYWN0aXZlUmVjb3JkID0gaW5qZWN0KG1hdGNoZWRSb3V0ZUtleSwgXHJcbiAgICAvLyB0byBhdm9pZCB3YXJuaW5nXHJcbiAgICB7fSkudmFsdWU7XHJcbiAgICBpZiAoIWFjdGl2ZVJlY29yZCkge1xyXG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJlxyXG4gICAgICAgICAgICB3YXJuKCdObyBhY3RpdmUgcm91dGUgcmVjb3JkIHdhcyBmb3VuZCB3aGVuIGNhbGxpbmcgYG9uQmVmb3JlUm91dGVMZWF2ZSgpYC4gTWFrZSBzdXJlIHlvdSBjYWxsIHRoaXMgZnVuY3Rpb24gaW5zaWRlIG9mIGEgY29tcG9uZW50IGNoaWxkIG9mIDxyb3V0ZXItdmlldz4uIE1heWJlIHlvdSBjYWxsZWQgaXQgaW5zaWRlIG9mIEFwcC52dWU/Jyk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgcmVnaXN0ZXJHdWFyZChhY3RpdmVSZWNvcmQsICdsZWF2ZUd1YXJkcycsIGxlYXZlR3VhcmQpO1xyXG59XHJcbi8qKlxyXG4gKiBBZGQgYSBuYXZpZ2F0aW9uIGd1YXJkIHRoYXQgdHJpZ2dlcnMgd2hlbmV2ZXIgdGhlIGN1cnJlbnQgbG9jYXRpb24gaXMgYWJvdXRcclxuICogdG8gYmUgdXBkYXRlZC4gU2ltaWxhciB0byB7QGxpbmsgYmVmb3JlUm91dGVVcGRhdGV9IGJ1dCBjYW4gYmUgdXNlZCBpbiBhbnlcclxuICogY29tcG9uZW50LiBUaGUgZ3VhcmQgaXMgcmVtb3ZlZCB3aGVuIHRoZSBjb21wb25lbnQgaXMgdW5tb3VudGVkLlxyXG4gKlxyXG4gKiBAcGFyYW0gdXBkYXRlR3VhcmQgLSB7QGxpbmsgTmF2aWdhdGlvbkd1YXJkfVxyXG4gKi9cclxuZnVuY3Rpb24gb25CZWZvcmVSb3V0ZVVwZGF0ZSh1cGRhdGVHdWFyZCkge1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhZ2V0Q3VycmVudEluc3RhbmNlKCkpIHtcclxuICAgICAgICB3YXJuKCdnZXRDdXJyZW50SW5zdGFuY2UoKSByZXR1cm5lZCBudWxsLiBvbkJlZm9yZVJvdXRlVXBkYXRlKCkgbXVzdCBiZSBjYWxsZWQgYXQgdGhlIHRvcCBvZiBhIHNldHVwIGZ1bmN0aW9uJyk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgY29uc3QgYWN0aXZlUmVjb3JkID0gaW5qZWN0KG1hdGNoZWRSb3V0ZUtleSwgXHJcbiAgICAvLyB0byBhdm9pZCB3YXJuaW5nXHJcbiAgICB7fSkudmFsdWU7XHJcbiAgICBpZiAoIWFjdGl2ZVJlY29yZCkge1xyXG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJlxyXG4gICAgICAgICAgICB3YXJuKCdObyBhY3RpdmUgcm91dGUgcmVjb3JkIHdhcyBmb3VuZCB3aGVuIGNhbGxpbmcgYG9uQmVmb3JlUm91dGVVcGRhdGUoKWAuIE1ha2Ugc3VyZSB5b3UgY2FsbCB0aGlzIGZ1bmN0aW9uIGluc2lkZSBvZiBhIGNvbXBvbmVudCBjaGlsZCBvZiA8cm91dGVyLXZpZXc+LiBNYXliZSB5b3UgY2FsbGVkIGl0IGluc2lkZSBvZiBBcHAudnVlPycpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHJlZ2lzdGVyR3VhcmQoYWN0aXZlUmVjb3JkLCAndXBkYXRlR3VhcmRzJywgdXBkYXRlR3VhcmQpO1xyXG59XHJcbmZ1bmN0aW9uIGd1YXJkVG9Qcm9taXNlRm4oZ3VhcmQsIHRvLCBmcm9tLCByZWNvcmQsIG5hbWUpIHtcclxuICAgIC8vIGtlZXAgYSByZWZlcmVuY2UgdG8gdGhlIGVudGVyQ2FsbGJhY2tBcnJheSB0byBwcmV2ZW50IHB1c2hpbmcgY2FsbGJhY2tzIGlmIGEgbmV3IG5hdmlnYXRpb24gdG9vayBwbGFjZVxyXG4gICAgY29uc3QgZW50ZXJDYWxsYmFja0FycmF5ID0gcmVjb3JkICYmXHJcbiAgICAgICAgLy8gbmFtZSBpcyBkZWZpbmVkIGlmIHJlY29yZCBpcyBiZWNhdXNlIG9mIHRoZSBmdW5jdGlvbiBvdmVybG9hZFxyXG4gICAgICAgIChyZWNvcmQuZW50ZXJDYWxsYmFja3NbbmFtZV0gPSByZWNvcmQuZW50ZXJDYWxsYmFja3NbbmFtZV0gfHwgW10pO1xyXG4gICAgcmV0dXJuICgpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBjb25zdCBuZXh0ID0gKHZhbGlkKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICh2YWxpZCA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICByZWplY3QoY3JlYXRlUm91dGVyRXJyb3IoNCAvKiBOQVZJR0FUSU9OX0FCT1JURUQgKi8sIHtcclxuICAgICAgICAgICAgICAgICAgICBmcm9tLFxyXG4gICAgICAgICAgICAgICAgICAgIHRvLFxyXG4gICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICBlbHNlIGlmICh2YWxpZCBpbnN0YW5jZW9mIEVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICByZWplY3QodmFsaWQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzUm91dGVMb2NhdGlvbih2YWxpZCkpIHtcclxuICAgICAgICAgICAgICAgIHJlamVjdChjcmVhdGVSb3V0ZXJFcnJvcigyIC8qIE5BVklHQVRJT05fR1VBUkRfUkVESVJFQ1QgKi8sIHtcclxuICAgICAgICAgICAgICAgICAgICBmcm9tOiB0byxcclxuICAgICAgICAgICAgICAgICAgICB0bzogdmFsaWQsXHJcbiAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZW50ZXJDYWxsYmFja0FycmF5ICYmXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc2luY2UgZW50ZXJDYWxsYmFja0FycmF5IGlzIHRydXRoeSwgYm90aCByZWNvcmQgYW5kIG5hbWUgYWxzbyBhcmVcclxuICAgICAgICAgICAgICAgICAgICByZWNvcmQuZW50ZXJDYWxsYmFja3NbbmFtZV0gPT09IGVudGVyQ2FsbGJhY2tBcnJheSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiB2YWxpZCA9PT0gJ2Z1bmN0aW9uJylcclxuICAgICAgICAgICAgICAgICAgICBlbnRlckNhbGxiYWNrQXJyYXkucHVzaCh2YWxpZCk7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIHdyYXBwaW5nIHdpdGggUHJvbWlzZS5yZXNvbHZlIGFsbG93cyBpdCB0byB3b3JrIHdpdGggYm90aCBhc3luYyBhbmQgc3luYyBndWFyZHNcclxuICAgICAgICBjb25zdCBndWFyZFJldHVybiA9IGd1YXJkLmNhbGwocmVjb3JkICYmIHJlY29yZC5pbnN0YW5jZXNbbmFtZV0sIHRvLCBmcm9tLCAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyBjYW5Pbmx5QmVDYWxsZWRPbmNlKG5leHQsIHRvLCBmcm9tKSA6IG5leHQpO1xyXG4gICAgICAgIGxldCBndWFyZENhbGwgPSBQcm9taXNlLnJlc29sdmUoZ3VhcmRSZXR1cm4pO1xyXG4gICAgICAgIGlmIChndWFyZC5sZW5ndGggPCAzKVxyXG4gICAgICAgICAgICBndWFyZENhbGwgPSBndWFyZENhbGwudGhlbihuZXh0KTtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIGd1YXJkLmxlbmd0aCA+IDIpIHtcclxuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGBUaGUgXCJuZXh0XCIgY2FsbGJhY2sgd2FzIG5ldmVyIGNhbGxlZCBpbnNpZGUgb2YgJHtndWFyZC5uYW1lID8gJ1wiJyArIGd1YXJkLm5hbWUgKyAnXCInIDogJyd9OlxcbiR7Z3VhcmQudG9TdHJpbmcoKX1cXG4uIElmIHlvdSBhcmUgcmV0dXJuaW5nIGEgdmFsdWUgaW5zdGVhZCBvZiBjYWxsaW5nIFwibmV4dFwiLCBtYWtlIHN1cmUgdG8gcmVtb3ZlIHRoZSBcIm5leHRcIiBwYXJhbWV0ZXIgZnJvbSB5b3VyIGZ1bmN0aW9uLmA7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZ3VhcmRSZXR1cm4gPT09ICdvYmplY3QnICYmICd0aGVuJyBpbiBndWFyZFJldHVybikge1xyXG4gICAgICAgICAgICAgICAgZ3VhcmRDYWxsID0gZ3VhcmRDYWxsLnRoZW4ocmVzb2x2ZWRWYWx1ZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogX2NhbGxlZCBpcyBhZGRlZCBhdCBjYW5Pbmx5QmVDYWxsZWRPbmNlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuZXh0Ll9jYWxsZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2FybihtZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignSW52YWxpZCBuYXZpZ2F0aW9uIGd1YXJkJykpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRWYWx1ZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogdGVzdCBtZSFcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChndWFyZFJldHVybiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiBfY2FsbGVkIGlzIGFkZGVkIGF0IGNhbk9ubHlCZUNhbGxlZE9uY2VcclxuICAgICAgICAgICAgICAgIGlmICghbmV4dC5fY2FsbGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybihtZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKCdJbnZhbGlkIG5hdmlnYXRpb24gZ3VhcmQnKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGd1YXJkQ2FsbC5jYXRjaChlcnIgPT4gcmVqZWN0KGVycikpO1xyXG4gICAgfSk7XHJcbn1cclxuZnVuY3Rpb24gY2FuT25seUJlQ2FsbGVkT25jZShuZXh0LCB0bywgZnJvbSkge1xyXG4gICAgbGV0IGNhbGxlZCA9IDA7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmIChjYWxsZWQrKyA9PT0gMSlcclxuICAgICAgICAgICAgd2FybihgVGhlIFwibmV4dFwiIGNhbGxiYWNrIHdhcyBjYWxsZWQgbW9yZSB0aGFuIG9uY2UgaW4gb25lIG5hdmlnYXRpb24gZ3VhcmQgd2hlbiBnb2luZyBmcm9tIFwiJHtmcm9tLmZ1bGxQYXRofVwiIHRvIFwiJHt0by5mdWxsUGF0aH1cIi4gSXQgc2hvdWxkIGJlIGNhbGxlZCBleGFjdGx5IG9uZSB0aW1lIGluIGVhY2ggbmF2aWdhdGlvbiBndWFyZC4gVGhpcyB3aWxsIGZhaWwgaW4gcHJvZHVjdGlvbi5gKTtcclxuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiB3ZSBwdXQgaXQgaW4gdGhlIG9yaWdpbmFsIG9uZSBiZWNhdXNlIGl0J3MgZWFzaWVyIHRvIGNoZWNrXHJcbiAgICAgICAgbmV4dC5fY2FsbGVkID0gdHJ1ZTtcclxuICAgICAgICBpZiAoY2FsbGVkID09PSAxKVxyXG4gICAgICAgICAgICBuZXh0LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XHJcbiAgICB9O1xyXG59XHJcbmZ1bmN0aW9uIGV4dHJhY3RDb21wb25lbnRzR3VhcmRzKG1hdGNoZWQsIGd1YXJkVHlwZSwgdG8sIGZyb20pIHtcclxuICAgIGNvbnN0IGd1YXJkcyA9IFtdO1xyXG4gICAgZm9yIChjb25zdCByZWNvcmQgb2YgbWF0Y2hlZCkge1xyXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiByZWNvcmQuY29tcG9uZW50cykge1xyXG4gICAgICAgICAgICBsZXQgcmF3Q29tcG9uZW50ID0gcmVjb3JkLmNvbXBvbmVudHNbbmFtZV07XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgIGlmICghcmF3Q29tcG9uZW50IHx8XHJcbiAgICAgICAgICAgICAgICAgICAgKHR5cGVvZiByYXdDb21wb25lbnQgIT09ICdvYmplY3QnICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiByYXdDb21wb25lbnQgIT09ICdmdW5jdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybihgQ29tcG9uZW50IFwiJHtuYW1lfVwiIGluIHJlY29yZCB3aXRoIHBhdGggXCIke3JlY29yZC5wYXRofVwiIGlzIG5vdGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBgIGEgdmFsaWQgY29tcG9uZW50LiBSZWNlaXZlZCBcIiR7U3RyaW5nKHJhd0NvbXBvbmVudCl9XCIuYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhyb3cgdG8gZW5zdXJlIHdlIHN0b3AgaGVyZSBidXQgd2FybiB0byBlbnN1cmUgdGhlIG1lc3NhZ2UgaXNuJ3RcclxuICAgICAgICAgICAgICAgICAgICAvLyBtaXNzZWQgYnkgdGhlIHVzZXJcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcm91dGUgY29tcG9uZW50Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICgndGhlbicgaW4gcmF3Q29tcG9uZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gd2FybiBpZiB1c2VyIHdyb3RlIGltcG9ydCgnL2NvbXBvbmVudC52dWUnKSBpbnN0ZWFkIG9mICgpID0+XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaW1wb3J0KCcuL2NvbXBvbmVudC52dWUnKVxyXG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYENvbXBvbmVudCBcIiR7bmFtZX1cIiBpbiByZWNvcmQgd2l0aCBwYXRoIFwiJHtyZWNvcmQucGF0aH1cIiBpcyBhIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBgUHJvbWlzZSBpbnN0ZWFkIG9mIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgUHJvbWlzZS4gRGlkIHlvdSBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYHdyaXRlIFwiaW1wb3J0KCcuL015UGFnZS52dWUnKVwiIGluc3RlYWQgb2YgYCArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGBcIigpID0+IGltcG9ydCgnLi9NeVBhZ2UudnVlJylcIiA/IFRoaXMgd2lsbCBicmVhayBpbiBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYHByb2R1Y3Rpb24gaWYgbm90IGZpeGVkLmApO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSByYXdDb21wb25lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmF3Q29tcG9uZW50ID0gKCkgPT4gcHJvbWlzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJhd0NvbXBvbmVudC5fX2FzeW5jTG9hZGVyICYmXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gd2FybiBvbmx5IG9uY2UgcGVyIGNvbXBvbmVudFxyXG4gICAgICAgICAgICAgICAgICAgICFyYXdDb21wb25lbnQuX193YXJuZWREZWZpbmVBc3luYykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJhd0NvbXBvbmVudC5fX3dhcm5lZERlZmluZUFzeW5jID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBDb21wb25lbnQgXCIke25hbWV9XCIgaW4gcmVjb3JkIHdpdGggcGF0aCBcIiR7cmVjb3JkLnBhdGh9XCIgaXMgZGVmaW5lZCBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYHVzaW5nIFwiZGVmaW5lQXN5bmNDb21wb25lbnQoKVwiLiBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYFdyaXRlIFwiKCkgPT4gaW1wb3J0KCcuL015UGFnZS52dWUnKVwiIGluc3RlYWQgb2YgYCArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGBcImRlZmluZUFzeW5jQ29tcG9uZW50KCgpID0+IGltcG9ydCgnLi9NeVBhZ2UudnVlJykpXCIuYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gc2tpcCB1cGRhdGUgYW5kIGxlYXZlIGd1YXJkcyBpZiB0aGUgcm91dGUgY29tcG9uZW50IGlzIG5vdCBtb3VudGVkXHJcbiAgICAgICAgICAgIGlmIChndWFyZFR5cGUgIT09ICdiZWZvcmVSb3V0ZUVudGVyJyAmJiAhcmVjb3JkLmluc3RhbmNlc1tuYW1lXSlcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICBpZiAoaXNSb3V0ZUNvbXBvbmVudChyYXdDb21wb25lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBfX3ZjY09wdHMgaXMgYWRkZWQgYnkgdnVlLWNsYXNzLWNvbXBvbmVudCBhbmQgY29udGFpbiB0aGUgcmVndWxhciBvcHRpb25zXHJcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0gcmF3Q29tcG9uZW50Ll9fdmNjT3B0cyB8fCByYXdDb21wb25lbnQ7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBndWFyZCA9IG9wdGlvbnNbZ3VhcmRUeXBlXTtcclxuICAgICAgICAgICAgICAgIGd1YXJkICYmIGd1YXJkcy5wdXNoKGd1YXJkVG9Qcm9taXNlRm4oZ3VhcmQsIHRvLCBmcm9tLCByZWNvcmQsIG5hbWUpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIHN0YXJ0IHJlcXVlc3RpbmcgdGhlIGNodW5rIGFscmVhZHlcclxuICAgICAgICAgICAgICAgIGxldCBjb21wb25lbnRQcm9taXNlID0gcmF3Q29tcG9uZW50KCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICEoJ2NhdGNoJyBpbiBjb21wb25lbnRQcm9taXNlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYENvbXBvbmVudCBcIiR7bmFtZX1cIiBpbiByZWNvcmQgd2l0aCBwYXRoIFwiJHtyZWNvcmQucGF0aH1cIiBpcyBhIGZ1bmN0aW9uIHRoYXQgZG9lcyBub3QgcmV0dXJuIGEgUHJvbWlzZS4gSWYgeW91IHdlcmUgcGFzc2luZyBhIGZ1bmN0aW9uYWwgY29tcG9uZW50LCBtYWtlIHN1cmUgdG8gYWRkIGEgXCJkaXNwbGF5TmFtZVwiIHRvIHRoZSBjb21wb25lbnQuIFRoaXMgd2lsbCBicmVhayBpbiBwcm9kdWN0aW9uIGlmIG5vdCBmaXhlZC5gKTtcclxuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGNvbXBvbmVudFByb21pc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goKCkgPT4gY29tcG9uZW50UHJvbWlzZS50aGVuKHJlc29sdmVkID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc29sdmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKGBDb3VsZG4ndCByZXNvbHZlIGNvbXBvbmVudCBcIiR7bmFtZX1cIiBhdCBcIiR7cmVjb3JkLnBhdGh9XCJgKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZWRDb21wb25lbnQgPSBpc0VTTW9kdWxlKHJlc29sdmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHJlc29sdmVkLmRlZmF1bHRcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiByZXNvbHZlZDtcclxuICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNlIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSByZXNvbHZlZCBjb21wb25lbnRcclxuICAgICAgICAgICAgICAgICAgICByZWNvcmQuY29tcG9uZW50c1tuYW1lXSA9IHJlc29sdmVkQ29tcG9uZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIF9fdmNjT3B0cyBpcyBhZGRlZCBieSB2dWUtY2xhc3MtY29tcG9uZW50IGFuZCBjb250YWluIHRoZSByZWd1bGFyIG9wdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0gcmVzb2x2ZWRDb21wb25lbnQuX192Y2NPcHRzIHx8IHJlc29sdmVkQ29tcG9uZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGd1YXJkID0gb3B0aW9uc1tndWFyZFR5cGVdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBndWFyZCAmJiBndWFyZFRvUHJvbWlzZUZuKGd1YXJkLCB0bywgZnJvbSwgcmVjb3JkLCBuYW1lKSgpO1xyXG4gICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGd1YXJkcztcclxufVxyXG4vKipcclxuICogQWxsb3dzIGRpZmZlcmVudGlhdGluZyBsYXp5IGNvbXBvbmVudHMgZnJvbSBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYW5kIHZ1ZS1jbGFzcy1jb21wb25lbnRcclxuICpcclxuICogQHBhcmFtIGNvbXBvbmVudFxyXG4gKi9cclxuZnVuY3Rpb24gaXNSb3V0ZUNvbXBvbmVudChjb21wb25lbnQpIHtcclxuICAgIHJldHVybiAodHlwZW9mIGNvbXBvbmVudCA9PT0gJ29iamVjdCcgfHxcclxuICAgICAgICAnZGlzcGxheU5hbWUnIGluIGNvbXBvbmVudCB8fFxyXG4gICAgICAgICdwcm9wcycgaW4gY29tcG9uZW50IHx8XHJcbiAgICAgICAgJ19fdmNjT3B0cycgaW4gY29tcG9uZW50KTtcclxufVxuXG4vLyBUT0RPOiB3ZSBjb3VsZCBhbGxvdyBjdXJyZW50Um91dGUgYXMgYSBwcm9wIHRvIGV4cG9zZSBgaXNBY3RpdmVgIGFuZFxyXG4vLyBgaXNFeGFjdEFjdGl2ZWAgYmVoYXZpb3Igc2hvdWxkIGdvIHRocm91Z2ggYW4gUkZDXHJcbmZ1bmN0aW9uIHVzZUxpbmsocHJvcHMpIHtcclxuICAgIGNvbnN0IHJvdXRlciA9IGluamVjdChyb3V0ZXJLZXkpO1xyXG4gICAgY29uc3QgY3VycmVudFJvdXRlID0gaW5qZWN0KHJvdXRlTG9jYXRpb25LZXkpO1xyXG4gICAgY29uc3Qgcm91dGUgPSBjb21wdXRlZCgoKSA9PiByb3V0ZXIucmVzb2x2ZSh1bnJlZihwcm9wcy50bykpKTtcclxuICAgIGNvbnN0IGFjdGl2ZVJlY29yZEluZGV4ID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHsgbWF0Y2hlZCB9ID0gcm91dGUudmFsdWU7XHJcbiAgICAgICAgY29uc3QgeyBsZW5ndGggfSA9IG1hdGNoZWQ7XHJcbiAgICAgICAgY29uc3Qgcm91dGVNYXRjaGVkID0gbWF0Y2hlZFtsZW5ndGggLSAxXTtcclxuICAgICAgICBjb25zdCBjdXJyZW50TWF0Y2hlZCA9IGN1cnJlbnRSb3V0ZS5tYXRjaGVkO1xyXG4gICAgICAgIGlmICghcm91dGVNYXRjaGVkIHx8ICFjdXJyZW50TWF0Y2hlZC5sZW5ndGgpXHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICBjb25zdCBpbmRleCA9IGN1cnJlbnRNYXRjaGVkLmZpbmRJbmRleChpc1NhbWVSb3V0ZVJlY29yZC5iaW5kKG51bGwsIHJvdXRlTWF0Y2hlZCkpO1xyXG4gICAgICAgIGlmIChpbmRleCA+IC0xKVxyXG4gICAgICAgICAgICByZXR1cm4gaW5kZXg7XHJcbiAgICAgICAgLy8gcG9zc2libGUgcGFyZW50IHJlY29yZFxyXG4gICAgICAgIGNvbnN0IHBhcmVudFJlY29yZFBhdGggPSBnZXRPcmlnaW5hbFBhdGgobWF0Y2hlZFtsZW5ndGggLSAyXSk7XHJcbiAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAvLyB3ZSBhcmUgZGVhbGluZyB3aXRoIG5lc3RlZCByb3V0ZXNcclxuICAgICAgICBsZW5ndGggPiAxICYmXHJcbiAgICAgICAgICAgIC8vIGlmIHRoZSBwYXJlbnQgYW5kIG1hdGNoZWQgcm91dGUgaGF2ZSB0aGUgc2FtZSBwYXRoLCB0aGlzIGxpbmsgaXNcclxuICAgICAgICAgICAgLy8gcmVmZXJyaW5nIHRvIHRoZSBlbXB0eSBjaGlsZC4gT3Igd2UgY3VycmVudGx5IGFyZSBvbiBhIGRpZmZlcmVudFxyXG4gICAgICAgICAgICAvLyBjaGlsZCBvZiB0aGUgc2FtZSBwYXJlbnRcclxuICAgICAgICAgICAgZ2V0T3JpZ2luYWxQYXRoKHJvdXRlTWF0Y2hlZCkgPT09IHBhcmVudFJlY29yZFBhdGggJiZcclxuICAgICAgICAgICAgLy8gYXZvaWQgY29tcGFyaW5nIHRoZSBjaGlsZCB3aXRoIGl0cyBwYXJlbnRcclxuICAgICAgICAgICAgY3VycmVudE1hdGNoZWRbY3VycmVudE1hdGNoZWQubGVuZ3RoIC0gMV0ucGF0aCAhPT0gcGFyZW50UmVjb3JkUGF0aFxyXG4gICAgICAgICAgICA/IGN1cnJlbnRNYXRjaGVkLmZpbmRJbmRleChpc1NhbWVSb3V0ZVJlY29yZC5iaW5kKG51bGwsIG1hdGNoZWRbbGVuZ3RoIC0gMl0pKVxyXG4gICAgICAgICAgICA6IGluZGV4KTtcclxuICAgIH0pO1xyXG4gICAgY29uc3QgaXNBY3RpdmUgPSBjb21wdXRlZCgoKSA9PiBhY3RpdmVSZWNvcmRJbmRleC52YWx1ZSA+IC0xICYmXHJcbiAgICAgICAgaW5jbHVkZXNQYXJhbXMoY3VycmVudFJvdXRlLnBhcmFtcywgcm91dGUudmFsdWUucGFyYW1zKSk7XHJcbiAgICBjb25zdCBpc0V4YWN0QWN0aXZlID0gY29tcHV0ZWQoKCkgPT4gYWN0aXZlUmVjb3JkSW5kZXgudmFsdWUgPiAtMSAmJlxyXG4gICAgICAgIGFjdGl2ZVJlY29yZEluZGV4LnZhbHVlID09PSBjdXJyZW50Um91dGUubWF0Y2hlZC5sZW5ndGggLSAxICYmXHJcbiAgICAgICAgaXNTYW1lUm91dGVMb2NhdGlvblBhcmFtcyhjdXJyZW50Um91dGUucGFyYW1zLCByb3V0ZS52YWx1ZS5wYXJhbXMpKTtcclxuICAgIGZ1bmN0aW9uIG5hdmlnYXRlKGUgPSB7fSkge1xyXG4gICAgICAgIGlmIChndWFyZEV2ZW50KGUpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiByb3V0ZXJbdW5yZWYocHJvcHMucmVwbGFjZSkgPyAncmVwbGFjZScgOiAncHVzaCddKHVucmVmKHByb3BzLnRvKVxyXG4gICAgICAgICAgICAvLyBhdm9pZCB1bmNhdWdodCBlcnJvcnMgYXJlIHRoZXkgYXJlIGxvZ2dlZCBhbnl3YXlcclxuICAgICAgICAgICAgKS5jYXRjaChub29wKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgfVxyXG4gICAgLy8gZGV2dG9vbHMgb25seVxyXG4gICAgaWYgKCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSAmJiBpc0Jyb3dzZXIpIHtcclxuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpO1xyXG4gICAgICAgIGlmIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICBjb25zdCBsaW5rQ29udGV4dERldnRvb2xzID0ge1xyXG4gICAgICAgICAgICAgICAgcm91dGU6IHJvdXRlLnZhbHVlLFxyXG4gICAgICAgICAgICAgICAgaXNBY3RpdmU6IGlzQWN0aXZlLnZhbHVlLFxyXG4gICAgICAgICAgICAgICAgaXNFeGFjdEFjdGl2ZTogaXNFeGFjdEFjdGl2ZS52YWx1ZSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogdGhpcyBpcyBpbnRlcm5hbFxyXG4gICAgICAgICAgICBpbnN0YW5jZS5fX3ZybF9kZXZ0b29scyA9IGluc3RhbmNlLl9fdnJsX2RldnRvb2xzIHx8IFtdO1xyXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiB0aGlzIGlzIGludGVybmFsXHJcbiAgICAgICAgICAgIGluc3RhbmNlLl9fdnJsX2RldnRvb2xzLnB1c2gobGlua0NvbnRleHREZXZ0b29scyk7XHJcbiAgICAgICAgICAgIHdhdGNoRWZmZWN0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGxpbmtDb250ZXh0RGV2dG9vbHMucm91dGUgPSByb3V0ZS52YWx1ZTtcclxuICAgICAgICAgICAgICAgIGxpbmtDb250ZXh0RGV2dG9vbHMuaXNBY3RpdmUgPSBpc0FjdGl2ZS52YWx1ZTtcclxuICAgICAgICAgICAgICAgIGxpbmtDb250ZXh0RGV2dG9vbHMuaXNFeGFjdEFjdGl2ZSA9IGlzRXhhY3RBY3RpdmUudmFsdWU7XHJcbiAgICAgICAgICAgIH0sIHsgZmx1c2g6ICdwb3N0JyB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHJvdXRlLFxyXG4gICAgICAgIGhyZWY6IGNvbXB1dGVkKCgpID0+IHJvdXRlLnZhbHVlLmhyZWYpLFxyXG4gICAgICAgIGlzQWN0aXZlLFxyXG4gICAgICAgIGlzRXhhY3RBY3RpdmUsXHJcbiAgICAgICAgbmF2aWdhdGUsXHJcbiAgICB9O1xyXG59XHJcbmNvbnN0IFJvdXRlckxpbmtJbXBsID0gLyojX19QVVJFX18qLyBkZWZpbmVDb21wb25lbnQoe1xyXG4gICAgbmFtZTogJ1JvdXRlckxpbmsnLFxyXG4gICAgcHJvcHM6IHtcclxuICAgICAgICB0bzoge1xyXG4gICAgICAgICAgICB0eXBlOiBbU3RyaW5nLCBPYmplY3RdLFxyXG4gICAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHJlcGxhY2U6IEJvb2xlYW4sXHJcbiAgICAgICAgYWN0aXZlQ2xhc3M6IFN0cmluZyxcclxuICAgICAgICAvLyBpbmFjdGl2ZUNsYXNzOiBTdHJpbmcsXHJcbiAgICAgICAgZXhhY3RBY3RpdmVDbGFzczogU3RyaW5nLFxyXG4gICAgICAgIGN1c3RvbTogQm9vbGVhbixcclxuICAgICAgICBhcmlhQ3VycmVudFZhbHVlOiB7XHJcbiAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcclxuICAgICAgICAgICAgZGVmYXVsdDogJ3BhZ2UnLFxyXG4gICAgICAgIH0sXHJcbiAgICB9LFxyXG4gICAgdXNlTGluayxcclxuICAgIHNldHVwKHByb3BzLCB7IHNsb3RzIH0pIHtcclxuICAgICAgICBjb25zdCBsaW5rID0gcmVhY3RpdmUodXNlTGluayhwcm9wcykpO1xyXG4gICAgICAgIGNvbnN0IHsgb3B0aW9ucyB9ID0gaW5qZWN0KHJvdXRlcktleSk7XHJcbiAgICAgICAgY29uc3QgZWxDbGFzcyA9IGNvbXB1dGVkKCgpID0+ICh7XHJcbiAgICAgICAgICAgIFtnZXRMaW5rQ2xhc3MocHJvcHMuYWN0aXZlQ2xhc3MsIG9wdGlvbnMubGlua0FjdGl2ZUNsYXNzLCAncm91dGVyLWxpbmstYWN0aXZlJyldOiBsaW5rLmlzQWN0aXZlLFxyXG4gICAgICAgICAgICAvLyBbZ2V0TGlua0NsYXNzKFxyXG4gICAgICAgICAgICAvLyAgIHByb3BzLmluYWN0aXZlQ2xhc3MsXHJcbiAgICAgICAgICAgIC8vICAgb3B0aW9ucy5saW5rSW5hY3RpdmVDbGFzcyxcclxuICAgICAgICAgICAgLy8gICAncm91dGVyLWxpbmstaW5hY3RpdmUnXHJcbiAgICAgICAgICAgIC8vICldOiAhbGluay5pc0V4YWN0QWN0aXZlLFxyXG4gICAgICAgICAgICBbZ2V0TGlua0NsYXNzKHByb3BzLmV4YWN0QWN0aXZlQ2xhc3MsIG9wdGlvbnMubGlua0V4YWN0QWN0aXZlQ2xhc3MsICdyb3V0ZXItbGluay1leGFjdC1hY3RpdmUnKV06IGxpbmsuaXNFeGFjdEFjdGl2ZSxcclxuICAgICAgICB9KSk7XHJcbiAgICAgICAgcmV0dXJuICgpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBzbG90cy5kZWZhdWx0ICYmIHNsb3RzLmRlZmF1bHQobGluayk7XHJcbiAgICAgICAgICAgIHJldHVybiBwcm9wcy5jdXN0b21cclxuICAgICAgICAgICAgICAgID8gY2hpbGRyZW5cclxuICAgICAgICAgICAgICAgIDogaCgnYScsIHtcclxuICAgICAgICAgICAgICAgICAgICAnYXJpYS1jdXJyZW50JzogbGluay5pc0V4YWN0QWN0aXZlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gcHJvcHMuYXJpYUN1cnJlbnRWYWx1ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAgICAgaHJlZjogbGluay5ocmVmLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgd291bGQgb3ZlcnJpZGUgdXNlciBhZGRlZCBhdHRycyBidXQgVnVlIHdpbGwgc3RpbGwgYWRkXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGxpc3RlbmVyIHNvIHdlIGVuZCB1cCB0cmlnZ2VyaW5nIGJvdGhcclxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiBsaW5rLm5hdmlnYXRlLFxyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzOiBlbENsYXNzLnZhbHVlLFxyXG4gICAgICAgICAgICAgICAgfSwgY2hpbGRyZW4pO1xyXG4gICAgICAgIH07XHJcbiAgICB9LFxyXG59KTtcclxuLy8gZXhwb3J0IHRoZSBwdWJsaWMgdHlwZSBmb3IgaC90c3ggaW5mZXJlbmNlXHJcbi8vIGFsc28gdG8gYXZvaWQgaW5saW5lIGltcG9ydCgpIGluIGdlbmVyYXRlZCBkLnRzIGZpbGVzXHJcbi8qKlxyXG4gKiBDb21wb25lbnQgdG8gcmVuZGVyIGEgbGluayB0aGF0IHRyaWdnZXJzIGEgbmF2aWdhdGlvbiBvbiBjbGljay5cclxuICovXHJcbmNvbnN0IFJvdXRlckxpbmsgPSBSb3V0ZXJMaW5rSW1wbDtcclxuZnVuY3Rpb24gZ3VhcmRFdmVudChlKSB7XHJcbiAgICAvLyBkb24ndCByZWRpcmVjdCB3aXRoIGNvbnRyb2wga2V5c1xyXG4gICAgaWYgKGUubWV0YUtleSB8fCBlLmFsdEtleSB8fCBlLmN0cmxLZXkgfHwgZS5zaGlmdEtleSlcclxuICAgICAgICByZXR1cm47XHJcbiAgICAvLyBkb24ndCByZWRpcmVjdCB3aGVuIHByZXZlbnREZWZhdWx0IGNhbGxlZFxyXG4gICAgaWYgKGUuZGVmYXVsdFByZXZlbnRlZClcclxuICAgICAgICByZXR1cm47XHJcbiAgICAvLyBkb24ndCByZWRpcmVjdCBvbiByaWdodCBjbGlja1xyXG4gICAgaWYgKGUuYnV0dG9uICE9PSB1bmRlZmluZWQgJiYgZS5idXR0b24gIT09IDApXHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgLy8gZG9uJ3QgcmVkaXJlY3QgaWYgYHRhcmdldD1cIl9ibGFua1wiYFxyXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBnZXRBdHRyaWJ1dGUgZG9lcyBleGlzdFxyXG4gICAgaWYgKGUuY3VycmVudFRhcmdldCAmJiBlLmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKSB7XHJcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBnZXRBdHRyaWJ1dGUgZXhpc3RzXHJcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZS5jdXJyZW50VGFyZ2V0LmdldEF0dHJpYnV0ZSgndGFyZ2V0Jyk7XHJcbiAgICAgICAgaWYgKC9cXGJfYmxhbmtcXGIvaS50ZXN0KHRhcmdldCkpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIC8vIHRoaXMgbWF5IGJlIGEgV2VleCBldmVudCB3aGljaCBkb2Vzbid0IGhhdmUgdGhpcyBtZXRob2RcclxuICAgIGlmIChlLnByZXZlbnREZWZhdWx0KVxyXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgIHJldHVybiB0cnVlO1xyXG59XHJcbmZ1bmN0aW9uIGluY2x1ZGVzUGFyYW1zKG91dGVyLCBpbm5lcikge1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gaW5uZXIpIHtcclxuICAgICAgICBjb25zdCBpbm5lclZhbHVlID0gaW5uZXJba2V5XTtcclxuICAgICAgICBjb25zdCBvdXRlclZhbHVlID0gb3V0ZXJba2V5XTtcclxuICAgICAgICBpZiAodHlwZW9mIGlubmVyVmFsdWUgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIGlmIChpbm5lclZhbHVlICE9PSBvdXRlclZhbHVlKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG91dGVyVmFsdWUpIHx8XHJcbiAgICAgICAgICAgICAgICBvdXRlclZhbHVlLmxlbmd0aCAhPT0gaW5uZXJWYWx1ZS5sZW5ndGggfHxcclxuICAgICAgICAgICAgICAgIGlubmVyVmFsdWUuc29tZSgodmFsdWUsIGkpID0+IHZhbHVlICE9PSBvdXRlclZhbHVlW2ldKSlcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufVxyXG4vKipcclxuICogR2V0IHRoZSBvcmlnaW5hbCBwYXRoIHZhbHVlIG9mIGEgcmVjb3JkIGJ5IGZvbGxvd2luZyBpdHMgYWxpYXNPZlxyXG4gKiBAcGFyYW0gcmVjb3JkXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRPcmlnaW5hbFBhdGgocmVjb3JkKSB7XHJcbiAgICByZXR1cm4gcmVjb3JkID8gKHJlY29yZC5hbGlhc09mID8gcmVjb3JkLmFsaWFzT2YucGF0aCA6IHJlY29yZC5wYXRoKSA6ICcnO1xyXG59XHJcbi8qKlxyXG4gKiBVdGlsaXR5IGNsYXNzIHRvIGdldCB0aGUgYWN0aXZlIGNsYXNzIGJhc2VkIG9uIGRlZmF1bHRzLlxyXG4gKiBAcGFyYW0gcHJvcENsYXNzXHJcbiAqIEBwYXJhbSBnbG9iYWxDbGFzc1xyXG4gKiBAcGFyYW0gZGVmYXVsdENsYXNzXHJcbiAqL1xyXG5jb25zdCBnZXRMaW5rQ2xhc3MgPSAocHJvcENsYXNzLCBnbG9iYWxDbGFzcywgZGVmYXVsdENsYXNzKSA9PiBwcm9wQ2xhc3MgIT0gbnVsbFxyXG4gICAgPyBwcm9wQ2xhc3NcclxuICAgIDogZ2xvYmFsQ2xhc3MgIT0gbnVsbFxyXG4gICAgICAgID8gZ2xvYmFsQ2xhc3NcclxuICAgICAgICA6IGRlZmF1bHRDbGFzcztcblxuY29uc3QgUm91dGVyVmlld0ltcGwgPSAvKiNfX1BVUkVfXyovIGRlZmluZUNvbXBvbmVudCh7XHJcbiAgICBuYW1lOiAnUm91dGVyVmlldycsXHJcbiAgICAvLyAjNjc0IHdlIG1hbnVhbGx5IGluaGVyaXQgdGhlbVxyXG4gICAgaW5oZXJpdEF0dHJzOiBmYWxzZSxcclxuICAgIHByb3BzOiB7XHJcbiAgICAgICAgbmFtZToge1xyXG4gICAgICAgICAgICB0eXBlOiBTdHJpbmcsXHJcbiAgICAgICAgICAgIGRlZmF1bHQ6ICdkZWZhdWx0JyxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHJvdXRlOiBPYmplY3QsXHJcbiAgICB9LFxyXG4gICAgc2V0dXAocHJvcHMsIHsgYXR0cnMsIHNsb3RzIH0pIHtcclxuICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgd2FybkRlcHJlY2F0ZWRVc2FnZSgpO1xyXG4gICAgICAgIGNvbnN0IGluamVjdGVkUm91dGUgPSBpbmplY3Qocm91dGVyVmlld0xvY2F0aW9uS2V5KTtcclxuICAgICAgICBjb25zdCByb3V0ZVRvRGlzcGxheSA9IGNvbXB1dGVkKCgpID0+IHByb3BzLnJvdXRlIHx8IGluamVjdGVkUm91dGUudmFsdWUpO1xyXG4gICAgICAgIGNvbnN0IGRlcHRoID0gaW5qZWN0KHZpZXdEZXB0aEtleSwgMCk7XHJcbiAgICAgICAgY29uc3QgbWF0Y2hlZFJvdXRlUmVmID0gY29tcHV0ZWQoKCkgPT4gcm91dGVUb0Rpc3BsYXkudmFsdWUubWF0Y2hlZFtkZXB0aF0pO1xyXG4gICAgICAgIHByb3ZpZGUodmlld0RlcHRoS2V5LCBkZXB0aCArIDEpO1xyXG4gICAgICAgIHByb3ZpZGUobWF0Y2hlZFJvdXRlS2V5LCBtYXRjaGVkUm91dGVSZWYpO1xyXG4gICAgICAgIHByb3ZpZGUocm91dGVyVmlld0xvY2F0aW9uS2V5LCByb3V0ZVRvRGlzcGxheSk7XHJcbiAgICAgICAgY29uc3Qgdmlld1JlZiA9IHJlZigpO1xyXG4gICAgICAgIC8vIHdhdGNoIGF0IHRoZSBzYW1lIHRpbWUgdGhlIGNvbXBvbmVudCBpbnN0YW5jZSwgdGhlIHJvdXRlIHJlY29yZCB3ZSBhcmVcclxuICAgICAgICAvLyByZW5kZXJpbmcsIGFuZCB0aGUgbmFtZVxyXG4gICAgICAgIHdhdGNoKCgpID0+IFt2aWV3UmVmLnZhbHVlLCBtYXRjaGVkUm91dGVSZWYudmFsdWUsIHByb3BzLm5hbWVdLCAoW2luc3RhbmNlLCB0bywgbmFtZV0sIFtvbGRJbnN0YW5jZSwgZnJvbSwgb2xkTmFtZV0pID0+IHtcclxuICAgICAgICAgICAgLy8gY29weSByZXVzZWQgaW5zdGFuY2VzXHJcbiAgICAgICAgICAgIGlmICh0bykge1xyXG4gICAgICAgICAgICAgICAgLy8gdGhpcyB3aWxsIHVwZGF0ZSB0aGUgaW5zdGFuY2UgZm9yIG5ldyBpbnN0YW5jZXMgYXMgd2VsbCBhcyByZXVzZWRcclxuICAgICAgICAgICAgICAgIC8vIGluc3RhbmNlcyB3aGVuIG5hdmlnYXRpbmcgdG8gYSBuZXcgcm91dGVcclxuICAgICAgICAgICAgICAgIHRvLmluc3RhbmNlc1tuYW1lXSA9IGluc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgLy8gdGhlIGNvbXBvbmVudCBpbnN0YW5jZSBpcyByZXVzZWQgZm9yIGEgZGlmZmVyZW50IHJvdXRlIG9yIG5hbWUgc29cclxuICAgICAgICAgICAgICAgIC8vIHdlIGNvcHkgYW55IHNhdmVkIHVwZGF0ZSBvciBsZWF2ZSBndWFyZHMuIFdpdGggYXN5bmMgc2V0dXAsIHRoZVxyXG4gICAgICAgICAgICAgICAgLy8gbW91bnRpbmcgY29tcG9uZW50IHdpbGwgbW91bnQgYmVmb3JlIHRoZSBtYXRjaGVkUm91dGUgY2hhbmdlcyxcclxuICAgICAgICAgICAgICAgIC8vIG1ha2luZyBpbnN0YW5jZSA9PT0gb2xkSW5zdGFuY2UsIHNvIHdlIGNoZWNrIGlmIGd1YXJkcyBoYXZlIGJlZW5cclxuICAgICAgICAgICAgICAgIC8vIGFkZGVkIGJlZm9yZS4gVGhpcyB3b3JrcyBiZWNhdXNlIHdlIHJlbW92ZSBndWFyZHMgd2hlblxyXG4gICAgICAgICAgICAgICAgLy8gdW5tb3VudGluZy9kZWFjdGl2YXRpbmcgY29tcG9uZW50c1xyXG4gICAgICAgICAgICAgICAgaWYgKGZyb20gJiYgZnJvbSAhPT0gdG8gJiYgaW5zdGFuY2UgJiYgaW5zdGFuY2UgPT09IG9sZEluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0by5sZWF2ZUd1YXJkcy5zaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvLmxlYXZlR3VhcmRzID0gZnJvbS5sZWF2ZUd1YXJkcztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0by51cGRhdGVHdWFyZHMuc2l6ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0by51cGRhdGVHdWFyZHMgPSBmcm9tLnVwZGF0ZUd1YXJkcztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gdHJpZ2dlciBiZWZvcmVSb3V0ZUVudGVyIG5leHQgY2FsbGJhY2tzXHJcbiAgICAgICAgICAgIGlmIChpbnN0YW5jZSAmJlxyXG4gICAgICAgICAgICAgICAgdG8gJiZcclxuICAgICAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIGluc3RhbmNlIGJ1dCB0byBhbmQgZnJvbSBhcmUgdGhlIHNhbWUgdGhpcyBtaWdodCBiZVxyXG4gICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IHZpc2l0XHJcbiAgICAgICAgICAgICAgICAoIWZyb20gfHwgIWlzU2FtZVJvdXRlUmVjb3JkKHRvLCBmcm9tKSB8fCAhb2xkSW5zdGFuY2UpKSB7XHJcbiAgICAgICAgICAgICAgICAodG8uZW50ZXJDYWxsYmFja3NbbmFtZV0gfHwgW10pLmZvckVhY2goY2FsbGJhY2sgPT4gY2FsbGJhY2soaW5zdGFuY2UpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sIHsgZmx1c2g6ICdwb3N0JyB9KTtcclxuICAgICAgICByZXR1cm4gKCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCByb3V0ZSA9IHJvdXRlVG9EaXNwbGF5LnZhbHVlO1xyXG4gICAgICAgICAgICBjb25zdCBtYXRjaGVkUm91dGUgPSBtYXRjaGVkUm91dGVSZWYudmFsdWU7XHJcbiAgICAgICAgICAgIGNvbnN0IFZpZXdDb21wb25lbnQgPSBtYXRjaGVkUm91dGUgJiYgbWF0Y2hlZFJvdXRlLmNvbXBvbmVudHNbcHJvcHMubmFtZV07XHJcbiAgICAgICAgICAgIC8vIHdlIG5lZWQgdGhlIHZhbHVlIGF0IHRoZSB0aW1lIHdlIHJlbmRlciBiZWNhdXNlIHdoZW4gd2UgdW5tb3VudCwgd2VcclxuICAgICAgICAgICAgLy8gbmF2aWdhdGVkIHRvIGEgZGlmZmVyZW50IGxvY2F0aW9uIHNvIHRoZSB2YWx1ZSBpcyBkaWZmZXJlbnRcclxuICAgICAgICAgICAgY29uc3QgY3VycmVudE5hbWUgPSBwcm9wcy5uYW1lO1xyXG4gICAgICAgICAgICBpZiAoIVZpZXdDb21wb25lbnQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBub3JtYWxpemVTbG90KHNsb3RzLmRlZmF1bHQsIHsgQ29tcG9uZW50OiBWaWV3Q29tcG9uZW50LCByb3V0ZSB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBwcm9wcyBmcm9tIHJvdXRlIGNvbmZpZ3VyYXRpb25cclxuICAgICAgICAgICAgY29uc3Qgcm91dGVQcm9wc09wdGlvbiA9IG1hdGNoZWRSb3V0ZS5wcm9wc1twcm9wcy5uYW1lXTtcclxuICAgICAgICAgICAgY29uc3Qgcm91dGVQcm9wcyA9IHJvdXRlUHJvcHNPcHRpb25cclxuICAgICAgICAgICAgICAgID8gcm91dGVQcm9wc09wdGlvbiA9PT0gdHJ1ZVxyXG4gICAgICAgICAgICAgICAgICAgID8gcm91dGUucGFyYW1zXHJcbiAgICAgICAgICAgICAgICAgICAgOiB0eXBlb2Ygcm91dGVQcm9wc09wdGlvbiA9PT0gJ2Z1bmN0aW9uJ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHJvdXRlUHJvcHNPcHRpb24ocm91dGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogcm91dGVQcm9wc09wdGlvblxyXG4gICAgICAgICAgICAgICAgOiBudWxsO1xyXG4gICAgICAgICAgICBjb25zdCBvblZub2RlVW5tb3VudGVkID0gdm5vZGUgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBpbnN0YW5jZSByZWZlcmVuY2UgdG8gcHJldmVudCBsZWFrXHJcbiAgICAgICAgICAgICAgICBpZiAodm5vZGUuY29tcG9uZW50LmlzVW5tb3VudGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZFJvdXRlLmluc3RhbmNlc1tjdXJyZW50TmFtZV0gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBjb25zdCBjb21wb25lbnQgPSBoKFZpZXdDb21wb25lbnQsIGFzc2lnbih7fSwgcm91dGVQcm9wcywgYXR0cnMsIHtcclxuICAgICAgICAgICAgICAgIG9uVm5vZGVVbm1vdW50ZWQsXHJcbiAgICAgICAgICAgICAgICByZWY6IHZpZXdSZWYsXHJcbiAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgaWYgKCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSAmJlxyXG4gICAgICAgICAgICAgICAgaXNCcm93c2VyICYmXHJcbiAgICAgICAgICAgICAgICBjb21wb25lbnQucmVmKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBjYW4gZGlzcGxheSBpZiBpdCdzIGFuIGFsaWFzLCBpdHMgcHJvcHNcclxuICAgICAgICAgICAgICAgIGNvbnN0IGluZm8gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVwdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogbWF0Y2hlZFJvdXRlLm5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogbWF0Y2hlZFJvdXRlLnBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgbWV0YTogbWF0Y2hlZFJvdXRlLm1ldGEsXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW50ZXJuYWxJbnN0YW5jZXMgPSBBcnJheS5pc0FycmF5KGNvbXBvbmVudC5yZWYpXHJcbiAgICAgICAgICAgICAgICAgICAgPyBjb21wb25lbnQucmVmLm1hcChyID0+IHIuaSlcclxuICAgICAgICAgICAgICAgICAgICA6IFtjb21wb25lbnQucmVmLmldO1xyXG4gICAgICAgICAgICAgICAgaW50ZXJuYWxJbnN0YW5jZXMuZm9yRWFjaChpbnN0YW5jZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxyXG4gICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLl9fdnJ2X2RldnRvb2xzID0gaW5mbztcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICAgIC8vIHBhc3MgdGhlIHZub2RlIHRvIHRoZSBzbG90IGFzIGEgcHJvcC5cclxuICAgICAgICAgICAgLy8gaCBhbmQgPGNvbXBvbmVudCA6aXM9XCIuLi5cIj4gYm90aCBhY2NlcHQgdm5vZGVzXHJcbiAgICAgICAgICAgIG5vcm1hbGl6ZVNsb3Qoc2xvdHMuZGVmYXVsdCwgeyBDb21wb25lbnQ6IGNvbXBvbmVudCwgcm91dGUgfSkgfHxcclxuICAgICAgICAgICAgICAgIGNvbXBvbmVudCk7XHJcbiAgICAgICAgfTtcclxuICAgIH0sXHJcbn0pO1xyXG5mdW5jdGlvbiBub3JtYWxpemVTbG90KHNsb3QsIGRhdGEpIHtcclxuICAgIGlmICghc2xvdClcclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIGNvbnN0IHNsb3RDb250ZW50ID0gc2xvdChkYXRhKTtcclxuICAgIHJldHVybiBzbG90Q29udGVudC5sZW5ndGggPT09IDEgPyBzbG90Q29udGVudFswXSA6IHNsb3RDb250ZW50O1xyXG59XHJcbi8vIGV4cG9ydCB0aGUgcHVibGljIHR5cGUgZm9yIGgvdHN4IGluZmVyZW5jZVxyXG4vLyBhbHNvIHRvIGF2b2lkIGlubGluZSBpbXBvcnQoKSBpbiBnZW5lcmF0ZWQgZC50cyBmaWxlc1xyXG4vKipcclxuICogQ29tcG9uZW50IHRvIGRpc3BsYXkgdGhlIGN1cnJlbnQgcm91dGUgdGhlIHVzZXIgaXMgYXQuXHJcbiAqL1xyXG5jb25zdCBSb3V0ZXJWaWV3ID0gUm91dGVyVmlld0ltcGw7XHJcbi8vIHdhcm4gYWdhaW5zdCBkZXByZWNhdGVkIHVzYWdlIHdpdGggPHRyYW5zaXRpb24+ICYgPGtlZXAtYWxpdmU+XHJcbi8vIGR1ZSB0byBmdW5jdGlvbmFsIGNvbXBvbmVudCBiZWluZyBubyBsb25nZXIgZWFnZXIgaW4gVnVlIDNcclxuZnVuY3Rpb24gd2FybkRlcHJlY2F0ZWRVc2FnZSgpIHtcclxuICAgIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7XHJcbiAgICBjb25zdCBwYXJlbnROYW1lID0gaW5zdGFuY2UucGFyZW50ICYmIGluc3RhbmNlLnBhcmVudC50eXBlLm5hbWU7XHJcbiAgICBpZiAocGFyZW50TmFtZSAmJlxyXG4gICAgICAgIChwYXJlbnROYW1lID09PSAnS2VlcEFsaXZlJyB8fCBwYXJlbnROYW1lLmluY2x1ZGVzKCdUcmFuc2l0aW9uJykpKSB7XHJcbiAgICAgICAgY29uc3QgY29tcCA9IHBhcmVudE5hbWUgPT09ICdLZWVwQWxpdmUnID8gJ2tlZXAtYWxpdmUnIDogJ3RyYW5zaXRpb24nO1xyXG4gICAgICAgIHdhcm4oYDxyb3V0ZXItdmlldz4gY2FuIG5vIGxvbmdlciBiZSB1c2VkIGRpcmVjdGx5IGluc2lkZSA8dHJhbnNpdGlvbj4gb3IgPGtlZXAtYWxpdmU+LlxcbmAgK1xyXG4gICAgICAgICAgICBgVXNlIHNsb3QgcHJvcHMgaW5zdGVhZDpcXG5cXG5gICtcclxuICAgICAgICAgICAgYDxyb3V0ZXItdmlldyB2LXNsb3Q9XCJ7IENvbXBvbmVudCB9XCI+XFxuYCArXHJcbiAgICAgICAgICAgIGAgIDwke2NvbXB9PlxcbmAgK1xyXG4gICAgICAgICAgICBgICAgIDxjb21wb25lbnQgOmlzPVwiQ29tcG9uZW50XCIgLz5cXG5gICtcclxuICAgICAgICAgICAgYCAgPC8ke2NvbXB9PlxcbmAgK1xyXG4gICAgICAgICAgICBgPC9yb3V0ZXItdmlldz5gKTtcclxuICAgIH1cclxufVxuXG5mdW5jdGlvbiBmb3JtYXRSb3V0ZUxvY2F0aW9uKHJvdXRlTG9jYXRpb24sIHRvb2x0aXApIHtcclxuICAgIGNvbnN0IGNvcHkgPSBhc3NpZ24oe30sIHJvdXRlTG9jYXRpb24sIHtcclxuICAgICAgICAvLyByZW1vdmUgdmFyaWFibGVzIHRoYXQgY2FuIGNvbnRhaW4gdnVlIGluc3RhbmNlc1xyXG4gICAgICAgIG1hdGNoZWQ6IHJvdXRlTG9jYXRpb24ubWF0Y2hlZC5tYXAobWF0Y2hlZCA9PiBvbWl0KG1hdGNoZWQsIFsnaW5zdGFuY2VzJywgJ2NoaWxkcmVuJywgJ2FsaWFzT2YnXSkpLFxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIF9jdXN0b206IHtcclxuICAgICAgICAgICAgdHlwZTogbnVsbCxcclxuICAgICAgICAgICAgcmVhZE9ubHk6IHRydWUsXHJcbiAgICAgICAgICAgIGRpc3BsYXk6IHJvdXRlTG9jYXRpb24uZnVsbFBhdGgsXHJcbiAgICAgICAgICAgIHRvb2x0aXAsXHJcbiAgICAgICAgICAgIHZhbHVlOiBjb3B5LFxyXG4gICAgICAgIH0sXHJcbiAgICB9O1xyXG59XHJcbmZ1bmN0aW9uIGZvcm1hdERpc3BsYXkoZGlzcGxheSkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBfY3VzdG9tOiB7XHJcbiAgICAgICAgICAgIGRpc3BsYXksXHJcbiAgICAgICAgfSxcclxuICAgIH07XHJcbn1cclxuLy8gdG8gc3VwcG9ydCBtdWx0aXBsZSByb3V0ZXIgaW5zdGFuY2VzXHJcbmxldCByb3V0ZXJJZCA9IDA7XHJcbmZ1bmN0aW9uIGFkZERldnRvb2xzKGFwcCwgcm91dGVyLCBtYXRjaGVyKSB7XHJcbiAgICAvLyBUYWtlIG92ZXIgcm91dGVyLmJlZm9yZUVhY2ggYW5kIGFmdGVyRWFjaFxyXG4gICAgLy8gbWFrZSBzdXJlIHdlIGFyZSBub3QgcmVnaXN0ZXJpbmcgdGhlIGRldnRvb2wgdHdpY2VcclxuICAgIGlmIChyb3V0ZXIuX19oYXNEZXZ0b29scylcclxuICAgICAgICByZXR1cm47XHJcbiAgICByb3V0ZXIuX19oYXNEZXZ0b29scyA9IHRydWU7XHJcbiAgICAvLyBpbmNyZW1lbnQgdG8gc3VwcG9ydCBtdWx0aXBsZSByb3V0ZXIgaW5zdGFuY2VzXHJcbiAgICBjb25zdCBpZCA9IHJvdXRlcklkKys7XHJcbiAgICBzZXR1cERldnRvb2xzUGx1Z2luKHtcclxuICAgICAgICBpZDogJ29yZy52dWVqcy5yb3V0ZXInICsgKGlkID8gJy4nICsgaWQgOiAnJyksXHJcbiAgICAgICAgbGFiZWw6ICdWdWUgUm91dGVyJyxcclxuICAgICAgICBwYWNrYWdlTmFtZTogJ3Z1ZS1yb3V0ZXInLFxyXG4gICAgICAgIGhvbWVwYWdlOiAnaHR0cHM6Ly9uZXh0LnJvdXRlci52dWVqcy5vcmcvJyxcclxuICAgICAgICBsb2dvOiAnaHR0cHM6Ly92dWVqcy5vcmcvaW1hZ2VzL2ljb25zL2Zhdmljb24tOTZ4OTYucG5nJyxcclxuICAgICAgICBjb21wb25lbnRTdGF0ZVR5cGVzOiBbJ1JvdXRpbmcnXSxcclxuICAgICAgICBhcHAsXHJcbiAgICB9LCBhcGkgPT4ge1xyXG4gICAgICAgIC8vIGRpc3BsYXkgc3RhdGUgYWRkZWQgYnkgdGhlIHJvdXRlclxyXG4gICAgICAgIGFwaS5vbi5pbnNwZWN0Q29tcG9uZW50KChwYXlsb2FkLCBjdHgpID0+IHtcclxuICAgICAgICAgICAgaWYgKHBheWxvYWQuaW5zdGFuY2VEYXRhKSB7XHJcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmluc3RhbmNlRGF0YS5zdGF0ZS5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnUm91dGluZycsXHJcbiAgICAgICAgICAgICAgICAgICAga2V5OiAnJHJvdXRlJyxcclxuICAgICAgICAgICAgICAgICAgICBlZGl0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZvcm1hdFJvdXRlTG9jYXRpb24ocm91dGVyLmN1cnJlbnRSb3V0ZS52YWx1ZSwgJ0N1cnJlbnQgUm91dGUnKSxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gbWFyayByb3V0ZXItbGluayBhcyBhY3RpdmUgYW5kIGRpc3BsYXkgdGFncyBvbiByb3V0ZXIgdmlld3NcclxuICAgICAgICBhcGkub24udmlzaXRDb21wb25lbnRUcmVlKCh7IHRyZWVOb2RlOiBub2RlLCBjb21wb25lbnRJbnN0YW5jZSB9KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChjb21wb25lbnRJbnN0YW5jZS5fX3Zydl9kZXZ0b29scykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW5mbyA9IGNvbXBvbmVudEluc3RhbmNlLl9fdnJ2X2RldnRvb2xzO1xyXG4gICAgICAgICAgICAgICAgbm9kZS50YWdzLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiAoaW5mby5uYW1lID8gYCR7aW5mby5uYW1lLnRvU3RyaW5nKCl9OiBgIDogJycpICsgaW5mby5wYXRoLFxyXG4gICAgICAgICAgICAgICAgICAgIHRleHRDb2xvcjogMCxcclxuICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiAnVGhpcyBjb21wb25lbnQgaXMgcmVuZGVyZWQgYnkgJmx0O3JvdXRlci12aWV3Jmd0OycsXHJcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBQSU5LXzUwMCxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGlmIG11bHRpcGxlIHVzZUxpbmsgYXJlIHVzZWRcclxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29tcG9uZW50SW5zdGFuY2UuX192cmxfZGV2dG9vbHMpKSB7XHJcbiAgICAgICAgICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5fX2RldnRvb2xzQXBpID0gYXBpO1xyXG4gICAgICAgICAgICAgICAgY29tcG9uZW50SW5zdGFuY2UuX192cmxfZGV2dG9vbHMuZm9yRWFjaChkZXZ0b29sc0RhdGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBiYWNrZ3JvdW5kQ29sb3IgPSBPUkFOR0VfNDAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB0b29sdGlwID0gJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRldnRvb2xzRGF0YS5pc0V4YWN0QWN0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvciA9IExJTUVfNTAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwID0gJ1RoaXMgaXMgZXhhY3RseSBhY3RpdmUnO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChkZXZ0b29sc0RhdGEuaXNBY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yID0gQkxVRV82MDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXAgPSAnVGhpcyBsaW5rIGlzIGFjdGl2ZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIG5vZGUudGFncy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldnRvb2xzRGF0YS5yb3V0ZS5wYXRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0Q29sb3I6IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcixcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgd2F0Y2gocm91dGVyLmN1cnJlbnRSb3V0ZSwgKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyByZWZyZXNoIGFjdGl2ZSBzdGF0ZVxyXG4gICAgICAgICAgICByZWZyZXNoUm91dGVzVmlldygpO1xyXG4gICAgICAgICAgICBhcGkubm90aWZ5Q29tcG9uZW50VXBkYXRlKCk7XHJcbiAgICAgICAgICAgIGFwaS5zZW5kSW5zcGVjdG9yVHJlZShyb3V0ZXJJbnNwZWN0b3JJZCk7XHJcbiAgICAgICAgICAgIGFwaS5zZW5kSW5zcGVjdG9yU3RhdGUocm91dGVySW5zcGVjdG9ySWQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGNvbnN0IG5hdmlnYXRpb25zTGF5ZXJJZCA9ICdyb3V0ZXI6bmF2aWdhdGlvbnM6JyArIGlkO1xyXG4gICAgICAgIGFwaS5hZGRUaW1lbGluZUxheWVyKHtcclxuICAgICAgICAgICAgaWQ6IG5hdmlnYXRpb25zTGF5ZXJJZCxcclxuICAgICAgICAgICAgbGFiZWw6IGBSb3V0ZXIke2lkID8gJyAnICsgaWQgOiAnJ30gTmF2aWdhdGlvbnNgLFxyXG4gICAgICAgICAgICBjb2xvcjogMHg0MGE4YzQsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gY29uc3QgZXJyb3JzTGF5ZXJJZCA9ICdyb3V0ZXI6ZXJyb3JzJ1xyXG4gICAgICAgIC8vIGFwaS5hZGRUaW1lbGluZUxheWVyKHtcclxuICAgICAgICAvLyAgIGlkOiBlcnJvcnNMYXllcklkLFxyXG4gICAgICAgIC8vICAgbGFiZWw6ICdSb3V0ZXIgRXJyb3JzJyxcclxuICAgICAgICAvLyAgIGNvbG9yOiAweGVhNTQ1NSxcclxuICAgICAgICAvLyB9KVxyXG4gICAgICAgIHJvdXRlci5vbkVycm9yKChlcnJvciwgdG8pID0+IHtcclxuICAgICAgICAgICAgYXBpLmFkZFRpbWVsaW5lRXZlbnQoe1xyXG4gICAgICAgICAgICAgICAgbGF5ZXJJZDogbmF2aWdhdGlvbnNMYXllcklkLFxyXG4gICAgICAgICAgICAgICAgZXZlbnQ6IHtcclxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ0Vycm9yIGR1cmluZyBOYXZpZ2F0aW9uJyxcclxuICAgICAgICAgICAgICAgICAgICBzdWJ0aXRsZTogdG8uZnVsbFBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgbG9nVHlwZTogJ2Vycm9yJyxcclxuICAgICAgICAgICAgICAgICAgICB0aW1lOiBEYXRlLm5vdygpLFxyXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHsgZXJyb3IgfSxcclxuICAgICAgICAgICAgICAgICAgICBncm91cElkOiB0by5tZXRhLl9fbmF2aWdhdGlvbklkLFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gYXR0YWNoZWQgdG8gYG1ldGFgIGFuZCB1c2VkIHRvIGdyb3VwIGV2ZW50c1xyXG4gICAgICAgIGxldCBuYXZpZ2F0aW9uSWQgPSAwO1xyXG4gICAgICAgIHJvdXRlci5iZWZvcmVFYWNoKCh0bywgZnJvbSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBkYXRhID0ge1xyXG4gICAgICAgICAgICAgICAgZ3VhcmQ6IGZvcm1hdERpc3BsYXkoJ2JlZm9yZUVhY2gnKSxcclxuICAgICAgICAgICAgICAgIGZyb206IGZvcm1hdFJvdXRlTG9jYXRpb24oZnJvbSwgJ0N1cnJlbnQgTG9jYXRpb24gZHVyaW5nIHRoaXMgbmF2aWdhdGlvbicpLFxyXG4gICAgICAgICAgICAgICAgdG86IGZvcm1hdFJvdXRlTG9jYXRpb24odG8sICdUYXJnZXQgbG9jYXRpb24nKSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLy8gVXNlZCB0byBncm91cCBuYXZpZ2F0aW9ucyB0b2dldGhlciwgaGlkZSBmcm9tIGRldnRvb2xzXHJcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0by5tZXRhLCAnX19uYXZpZ2F0aW9uSWQnLCB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogbmF2aWdhdGlvbklkKyssXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBhcGkuYWRkVGltZWxpbmVFdmVudCh7XHJcbiAgICAgICAgICAgICAgICBsYXllcklkOiBuYXZpZ2F0aW9uc0xheWVySWQsXHJcbiAgICAgICAgICAgICAgICBldmVudDoge1xyXG4gICAgICAgICAgICAgICAgICAgIHRpbWU6IERhdGUubm93KCksXHJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdTdGFydCBvZiBuYXZpZ2F0aW9uJyxcclxuICAgICAgICAgICAgICAgICAgICBzdWJ0aXRsZTogdG8uZnVsbFBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YSxcclxuICAgICAgICAgICAgICAgICAgICBncm91cElkOiB0by5tZXRhLl9fbmF2aWdhdGlvbklkLFxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcm91dGVyLmFmdGVyRWFjaCgodG8sIGZyb20sIGZhaWx1cmUpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHtcclxuICAgICAgICAgICAgICAgIGd1YXJkOiBmb3JtYXREaXNwbGF5KCdhZnRlckVhY2gnKSxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgaWYgKGZhaWx1cmUpIHtcclxuICAgICAgICAgICAgICAgIGRhdGEuZmFpbHVyZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICBfY3VzdG9tOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IEVycm9yLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkT25seTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogZmFpbHVyZSA/IGZhaWx1cmUubWVzc2FnZSA6ICcnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiAnTmF2aWdhdGlvbiBGYWlsdXJlJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZhaWx1cmUsXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICBkYXRhLnN0YXR1cyA9IGZvcm1hdERpc3BsYXkoJ+KdjCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZGF0YS5zdGF0dXMgPSBmb3JtYXREaXNwbGF5KCfinIUnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyB3ZSBzZXQgaGVyZSB0byBoYXZlIHRoZSByaWdodCBvcmRlclxyXG4gICAgICAgICAgICBkYXRhLmZyb20gPSBmb3JtYXRSb3V0ZUxvY2F0aW9uKGZyb20sICdDdXJyZW50IExvY2F0aW9uIGR1cmluZyB0aGlzIG5hdmlnYXRpb24nKTtcclxuICAgICAgICAgICAgZGF0YS50byA9IGZvcm1hdFJvdXRlTG9jYXRpb24odG8sICdUYXJnZXQgbG9jYXRpb24nKTtcclxuICAgICAgICAgICAgYXBpLmFkZFRpbWVsaW5lRXZlbnQoe1xyXG4gICAgICAgICAgICAgICAgbGF5ZXJJZDogbmF2aWdhdGlvbnNMYXllcklkLFxyXG4gICAgICAgICAgICAgICAgZXZlbnQ6IHtcclxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ0VuZCBvZiBuYXZpZ2F0aW9uJyxcclxuICAgICAgICAgICAgICAgICAgICBzdWJ0aXRsZTogdG8uZnVsbFBhdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgdGltZTogRGF0ZS5ub3coKSxcclxuICAgICAgICAgICAgICAgICAgICBkYXRhLFxyXG4gICAgICAgICAgICAgICAgICAgIGxvZ1R5cGU6IGZhaWx1cmUgPyAnd2FybmluZycgOiAnZGVmYXVsdCcsXHJcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBJZDogdG8ubWV0YS5fX25hdmlnYXRpb25JZCxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEluc3BlY3RvciBvZiBFeGlzdGluZyByb3V0ZXNcclxuICAgICAgICAgKi9cclxuICAgICAgICBjb25zdCByb3V0ZXJJbnNwZWN0b3JJZCA9ICdyb3V0ZXItaW5zcGVjdG9yOicgKyBpZDtcclxuICAgICAgICBhcGkuYWRkSW5zcGVjdG9yKHtcclxuICAgICAgICAgICAgaWQ6IHJvdXRlckluc3BlY3RvcklkLFxyXG4gICAgICAgICAgICBsYWJlbDogJ1JvdXRlcycgKyAoaWQgPyAnICcgKyBpZCA6ICcnKSxcclxuICAgICAgICAgICAgaWNvbjogJ2Jvb2snLFxyXG4gICAgICAgICAgICB0cmVlRmlsdGVyUGxhY2Vob2xkZXI6ICdTZWFyY2ggcm91dGVzJyxcclxuICAgICAgICB9KTtcclxuICAgICAgICBmdW5jdGlvbiByZWZyZXNoUm91dGVzVmlldygpIHtcclxuICAgICAgICAgICAgLy8gdGhlIHJvdXRlcyB2aWV3IGlzbid0IGFjdGl2ZVxyXG4gICAgICAgICAgICBpZiAoIWFjdGl2ZVJvdXRlc1BheWxvYWQpXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBhY3RpdmVSb3V0ZXNQYXlsb2FkO1xyXG4gICAgICAgICAgICAvLyBjaGlsZHJlbiByb3V0ZXMgd2lsbCBhcHBlYXIgYXMgbmVzdGVkXHJcbiAgICAgICAgICAgIGxldCByb3V0ZXMgPSBtYXRjaGVyLmdldFJvdXRlcygpLmZpbHRlcihyb3V0ZSA9PiAhcm91dGUucGFyZW50KTtcclxuICAgICAgICAgICAgLy8gcmVzZXQgbWF0Y2ggc3RhdGUgdG8gZmFsc2VcclxuICAgICAgICAgICAgcm91dGVzLmZvckVhY2gocmVzZXRNYXRjaFN0YXRlT25Sb3V0ZVJlY29yZCk7XHJcbiAgICAgICAgICAgIC8vIGFwcGx5IGEgbWF0Y2ggc3RhdGUgaWYgdGhlcmUgaXMgYSBwYXlsb2FkXHJcbiAgICAgICAgICAgIGlmIChwYXlsb2FkLmZpbHRlcikge1xyXG4gICAgICAgICAgICAgICAgcm91dGVzID0gcm91dGVzLmZpbHRlcihyb3V0ZSA9PiBcclxuICAgICAgICAgICAgICAgIC8vIHNhdmUgbWF0Y2hlcyBzdGF0ZSBiYXNlZCBvbiB0aGUgcGF5bG9hZFxyXG4gICAgICAgICAgICAgICAgaXNSb3V0ZU1hdGNoaW5nKHJvdXRlLCBwYXlsb2FkLmZpbHRlci50b0xvd2VyQ2FzZSgpKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gbWFyayBhY3RpdmUgcm91dGVzXHJcbiAgICAgICAgICAgIHJvdXRlcy5mb3JFYWNoKHJvdXRlID0+IG1hcmtSb3V0ZVJlY29yZEFjdGl2ZShyb3V0ZSwgcm91dGVyLmN1cnJlbnRSb3V0ZS52YWx1ZSkpO1xyXG4gICAgICAgICAgICBwYXlsb2FkLnJvb3ROb2RlcyA9IHJvdXRlcy5tYXAoZm9ybWF0Um91dGVSZWNvcmRGb3JJbnNwZWN0b3IpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgYWN0aXZlUm91dGVzUGF5bG9hZDtcclxuICAgICAgICBhcGkub24uZ2V0SW5zcGVjdG9yVHJlZShwYXlsb2FkID0+IHtcclxuICAgICAgICAgICAgYWN0aXZlUm91dGVzUGF5bG9hZCA9IHBheWxvYWQ7XHJcbiAgICAgICAgICAgIGlmIChwYXlsb2FkLmFwcCA9PT0gYXBwICYmIHBheWxvYWQuaW5zcGVjdG9ySWQgPT09IHJvdXRlckluc3BlY3RvcklkKSB7XHJcbiAgICAgICAgICAgICAgICByZWZyZXNoUm91dGVzVmlldygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGlzcGxheSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHJvdXRlIHJlY29yZFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGFwaS5vbi5nZXRJbnNwZWN0b3JTdGF0ZShwYXlsb2FkID0+IHtcclxuICAgICAgICAgICAgaWYgKHBheWxvYWQuYXBwID09PSBhcHAgJiYgcGF5bG9hZC5pbnNwZWN0b3JJZCA9PT0gcm91dGVySW5zcGVjdG9ySWQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJvdXRlcyA9IG1hdGNoZXIuZ2V0Um91dGVzKCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByb3V0ZSA9IHJvdXRlcy5maW5kKHJvdXRlID0+IHJvdXRlLnJlY29yZC5fX3ZkX2lkID09PSBwYXlsb2FkLm5vZGVJZCk7XHJcbiAgICAgICAgICAgICAgICBpZiAocm91dGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBwYXlsb2FkLnN0YXRlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zOiBmb3JtYXRSb3V0ZVJlY29yZE1hdGNoZXJGb3JTdGF0ZUluc3BlY3Rvcihyb3V0ZSksXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGFwaS5zZW5kSW5zcGVjdG9yVHJlZShyb3V0ZXJJbnNwZWN0b3JJZCk7XHJcbiAgICAgICAgYXBpLnNlbmRJbnNwZWN0b3JTdGF0ZShyb3V0ZXJJbnNwZWN0b3JJZCk7XHJcbiAgICB9KTtcclxufVxyXG5mdW5jdGlvbiBtb2RpZmllckZvcktleShrZXkpIHtcclxuICAgIGlmIChrZXkub3B0aW9uYWwpIHtcclxuICAgICAgICByZXR1cm4ga2V5LnJlcGVhdGFibGUgPyAnKicgOiAnPyc7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4ga2V5LnJlcGVhdGFibGUgPyAnKycgOiAnJztcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBmb3JtYXRSb3V0ZVJlY29yZE1hdGNoZXJGb3JTdGF0ZUluc3BlY3Rvcihyb3V0ZSkge1xyXG4gICAgY29uc3QgeyByZWNvcmQgfSA9IHJvdXRlO1xyXG4gICAgY29uc3QgZmllbGRzID0gW1xyXG4gICAgICAgIHsgZWRpdGFibGU6IGZhbHNlLCBrZXk6ICdwYXRoJywgdmFsdWU6IHJlY29yZC5wYXRoIH0sXHJcbiAgICBdO1xyXG4gICAgaWYgKHJlY29yZC5uYW1lICE9IG51bGwpIHtcclxuICAgICAgICBmaWVsZHMucHVzaCh7XHJcbiAgICAgICAgICAgIGVkaXRhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAga2V5OiAnbmFtZScsXHJcbiAgICAgICAgICAgIHZhbHVlOiByZWNvcmQubmFtZSxcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIGZpZWxkcy5wdXNoKHsgZWRpdGFibGU6IGZhbHNlLCBrZXk6ICdyZWdleHAnLCB2YWx1ZTogcm91dGUucmUgfSk7XHJcbiAgICBpZiAocm91dGUua2V5cy5sZW5ndGgpIHtcclxuICAgICAgICBmaWVsZHMucHVzaCh7XHJcbiAgICAgICAgICAgIGVkaXRhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAga2V5OiAna2V5cycsXHJcbiAgICAgICAgICAgIHZhbHVlOiB7XHJcbiAgICAgICAgICAgICAgICBfY3VzdG9tOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICByZWFkT25seTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5OiByb3V0ZS5rZXlzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoa2V5ID0+IGAke2tleS5uYW1lfSR7bW9kaWZpZXJGb3JLZXkoa2V5KX1gKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuam9pbignICcpLFxyXG4gICAgICAgICAgICAgICAgICAgIHRvb2x0aXA6ICdQYXJhbSBrZXlzJyxcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogcm91dGUua2V5cyxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBpZiAocmVjb3JkLnJlZGlyZWN0ICE9IG51bGwpIHtcclxuICAgICAgICBmaWVsZHMucHVzaCh7XHJcbiAgICAgICAgICAgIGVkaXRhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAga2V5OiAncmVkaXJlY3QnLFxyXG4gICAgICAgICAgICB2YWx1ZTogcmVjb3JkLnJlZGlyZWN0LFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKHJvdXRlLmFsaWFzLmxlbmd0aCkge1xyXG4gICAgICAgIGZpZWxkcy5wdXNoKHtcclxuICAgICAgICAgICAgZWRpdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICBrZXk6ICdhbGlhc2VzJyxcclxuICAgICAgICAgICAgdmFsdWU6IHJvdXRlLmFsaWFzLm1hcChhbGlhcyA9PiBhbGlhcy5yZWNvcmQucGF0aCksXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBmaWVsZHMucHVzaCh7XHJcbiAgICAgICAga2V5OiAnc2NvcmUnLFxyXG4gICAgICAgIGVkaXRhYmxlOiBmYWxzZSxcclxuICAgICAgICB2YWx1ZToge1xyXG4gICAgICAgICAgICBfY3VzdG9tOiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcmVhZE9ubHk6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiByb3V0ZS5zY29yZS5tYXAoc2NvcmUgPT4gc2NvcmUuam9pbignLCAnKSkuam9pbignIHwgJyksXHJcbiAgICAgICAgICAgICAgICB0b29sdGlwOiAnU2NvcmUgdXNlZCB0byBzb3J0IHJvdXRlcycsXHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogcm91dGUuc2NvcmUsXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfSxcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIGZpZWxkcztcclxufVxyXG4vKipcclxuICogRXh0cmFjdGVkIGZyb20gdGFpbHdpbmQgcGFsZXR0ZVxyXG4gKi9cclxuY29uc3QgUElOS181MDAgPSAweGVjNDg5OTtcclxuY29uc3QgQkxVRV82MDAgPSAweDI1NjNlYjtcclxuY29uc3QgTElNRV81MDAgPSAweDg0Y2MxNjtcclxuY29uc3QgQ1lBTl80MDAgPSAweDIyZDNlZTtcclxuY29uc3QgT1JBTkdFXzQwMCA9IDB4ZmI5MjNjO1xyXG4vLyBjb25zdCBHUkFZXzEwMCA9IDB4ZjRmNGY1XHJcbmNvbnN0IERBUksgPSAweDY2NjY2NjtcclxuZnVuY3Rpb24gZm9ybWF0Um91dGVSZWNvcmRGb3JJbnNwZWN0b3Iocm91dGUpIHtcclxuICAgIGNvbnN0IHRhZ3MgPSBbXTtcclxuICAgIGNvbnN0IHsgcmVjb3JkIH0gPSByb3V0ZTtcclxuICAgIGlmIChyZWNvcmQubmFtZSAhPSBudWxsKSB7XHJcbiAgICAgICAgdGFncy5wdXNoKHtcclxuICAgICAgICAgICAgbGFiZWw6IFN0cmluZyhyZWNvcmQubmFtZSksXHJcbiAgICAgICAgICAgIHRleHRDb2xvcjogMCxcclxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBDWUFOXzQwMCxcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIGlmIChyZWNvcmQuYWxpYXNPZikge1xyXG4gICAgICAgIHRhZ3MucHVzaCh7XHJcbiAgICAgICAgICAgIGxhYmVsOiAnYWxpYXMnLFxyXG4gICAgICAgICAgICB0ZXh0Q29sb3I6IDAsXHJcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogT1JBTkdFXzQwMCxcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIGlmIChyb3V0ZS5fX3ZkX21hdGNoKSB7XHJcbiAgICAgICAgdGFncy5wdXNoKHtcclxuICAgICAgICAgICAgbGFiZWw6ICdtYXRjaGVzJyxcclxuICAgICAgICAgICAgdGV4dENvbG9yOiAwLFxyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IFBJTktfNTAwLFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKHJvdXRlLl9fdmRfZXhhY3RBY3RpdmUpIHtcclxuICAgICAgICB0YWdzLnB1c2goe1xyXG4gICAgICAgICAgICBsYWJlbDogJ2V4YWN0JyxcclxuICAgICAgICAgICAgdGV4dENvbG9yOiAwLFxyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IExJTUVfNTAwLFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgaWYgKHJvdXRlLl9fdmRfYWN0aXZlKSB7XHJcbiAgICAgICAgdGFncy5wdXNoKHtcclxuICAgICAgICAgICAgbGFiZWw6ICdhY3RpdmUnLFxyXG4gICAgICAgICAgICB0ZXh0Q29sb3I6IDAsXHJcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogQkxVRV82MDAsXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBpZiAocmVjb3JkLnJlZGlyZWN0KSB7XHJcbiAgICAgICAgdGFncy5wdXNoKHtcclxuICAgICAgICAgICAgbGFiZWw6ICdyZWRpcmVjdDogJyArXHJcbiAgICAgICAgICAgICAgICAodHlwZW9mIHJlY29yZC5yZWRpcmVjdCA9PT0gJ3N0cmluZycgPyByZWNvcmQucmVkaXJlY3QgOiAnT2JqZWN0JyksXHJcbiAgICAgICAgICAgIHRleHRDb2xvcjogMHhmZmZmZmYsXHJcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogREFSSyxcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIC8vIGFkZCBhbiBpZCB0byBiZSBhYmxlIHRvIHNlbGVjdCBpdC4gVXNpbmcgdGhlIGBwYXRoYCBpcyBub3QgcG9zc2libGUgYmVjYXVzZVxyXG4gICAgLy8gZW1wdHkgcGF0aCBjaGlsZHJlbiB3b3VsZCBjb2xsaWRlIHdpdGggdGhlaXIgcGFyZW50c1xyXG4gICAgbGV0IGlkID0gcmVjb3JkLl9fdmRfaWQ7XHJcbiAgICBpZiAoaWQgPT0gbnVsbCkge1xyXG4gICAgICAgIGlkID0gU3RyaW5nKHJvdXRlUmVjb3JkSWQrKyk7XHJcbiAgICAgICAgcmVjb3JkLl9fdmRfaWQgPSBpZDtcclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgaWQsXHJcbiAgICAgICAgbGFiZWw6IHJlY29yZC5wYXRoLFxyXG4gICAgICAgIHRhZ3MsXHJcbiAgICAgICAgY2hpbGRyZW46IHJvdXRlLmNoaWxkcmVuLm1hcChmb3JtYXRSb3V0ZVJlY29yZEZvckluc3BlY3RvciksXHJcbiAgICB9O1xyXG59XHJcbi8vICBpbmNyZW1lbnRhbCBpZCBmb3Igcm91dGUgcmVjb3JkcyBhbmQgaW5zcGVjdG9yIHN0YXRlXHJcbmxldCByb3V0ZVJlY29yZElkID0gMDtcclxuY29uc3QgRVhUUkFDVF9SRUdFWFBfUkUgPSAvXlxcLyguKilcXC8oW2Etel0qKSQvO1xyXG5mdW5jdGlvbiBtYXJrUm91dGVSZWNvcmRBY3RpdmUocm91dGUsIGN1cnJlbnRSb3V0ZSkge1xyXG4gICAgLy8gbm8gcm91dGUgd2lsbCBiZSBhY3RpdmUgaWYgbWF0Y2hlZCBpcyBlbXB0eVxyXG4gICAgLy8gcmVzZXQgdGhlIG1hdGNoaW5nIHN0YXRlXHJcbiAgICBjb25zdCBpc0V4YWN0QWN0aXZlID0gY3VycmVudFJvdXRlLm1hdGNoZWQubGVuZ3RoICYmXHJcbiAgICAgICAgaXNTYW1lUm91dGVSZWNvcmQoY3VycmVudFJvdXRlLm1hdGNoZWRbY3VycmVudFJvdXRlLm1hdGNoZWQubGVuZ3RoIC0gMV0sIHJvdXRlLnJlY29yZCk7XHJcbiAgICByb3V0ZS5fX3ZkX2V4YWN0QWN0aXZlID0gcm91dGUuX192ZF9hY3RpdmUgPSBpc0V4YWN0QWN0aXZlO1xyXG4gICAgaWYgKCFpc0V4YWN0QWN0aXZlKSB7XHJcbiAgICAgICAgcm91dGUuX192ZF9hY3RpdmUgPSBjdXJyZW50Um91dGUubWF0Y2hlZC5zb21lKG1hdGNoID0+IGlzU2FtZVJvdXRlUmVjb3JkKG1hdGNoLCByb3V0ZS5yZWNvcmQpKTtcclxuICAgIH1cclxuICAgIHJvdXRlLmNoaWxkcmVuLmZvckVhY2goY2hpbGRSb3V0ZSA9PiBtYXJrUm91dGVSZWNvcmRBY3RpdmUoY2hpbGRSb3V0ZSwgY3VycmVudFJvdXRlKSk7XHJcbn1cclxuZnVuY3Rpb24gcmVzZXRNYXRjaFN0YXRlT25Sb3V0ZVJlY29yZChyb3V0ZSkge1xyXG4gICAgcm91dGUuX192ZF9tYXRjaCA9IGZhbHNlO1xyXG4gICAgcm91dGUuY2hpbGRyZW4uZm9yRWFjaChyZXNldE1hdGNoU3RhdGVPblJvdXRlUmVjb3JkKTtcclxufVxyXG5mdW5jdGlvbiBpc1JvdXRlTWF0Y2hpbmcocm91dGUsIGZpbHRlcikge1xyXG4gICAgY29uc3QgZm91bmQgPSBTdHJpbmcocm91dGUucmUpLm1hdGNoKEVYVFJBQ1RfUkVHRVhQX1JFKTtcclxuICAgIHJvdXRlLl9fdmRfbWF0Y2ggPSBmYWxzZTtcclxuICAgIGlmICghZm91bmQgfHwgZm91bmQubGVuZ3RoIDwgMykge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIC8vIHVzZSBhIHJlZ2V4cCB3aXRob3V0ICQgYXQgdGhlIGVuZCB0byBtYXRjaCBuZXN0ZWQgcm91dGVzIGJldHRlclxyXG4gICAgY29uc3Qgbm9uRW5kaW5nUkUgPSBuZXcgUmVnRXhwKGZvdW5kWzFdLnJlcGxhY2UoL1xcJCQvLCAnJyksIGZvdW5kWzJdKTtcclxuICAgIGlmIChub25FbmRpbmdSRS50ZXN0KGZpbHRlcikpIHtcclxuICAgICAgICAvLyBtYXJrIGNoaWxkcmVuIGFzIG1hdGNoZXNcclxuICAgICAgICByb3V0ZS5jaGlsZHJlbi5mb3JFYWNoKGNoaWxkID0+IGlzUm91dGVNYXRjaGluZyhjaGlsZCwgZmlsdGVyKSk7XHJcbiAgICAgICAgLy8gZXhjZXB0aW9uIGNhc2U6IGAvYFxyXG4gICAgICAgIGlmIChyb3V0ZS5yZWNvcmQucGF0aCAhPT0gJy8nIHx8IGZpbHRlciA9PT0gJy8nKSB7XHJcbiAgICAgICAgICAgIHJvdXRlLl9fdmRfbWF0Y2ggPSByb3V0ZS5yZS50ZXN0KGZpbHRlcik7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBoaWRlIHRoZSAvIHJvdXRlXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcGF0aCA9IHJvdXRlLnJlY29yZC5wYXRoLnRvTG93ZXJDYXNlKCk7XHJcbiAgICBjb25zdCBkZWNvZGVkUGF0aCA9IGRlY29kZShwYXRoKTtcclxuICAgIC8vIGFsc28gYWxsb3cgcGFydGlhbCBtYXRjaGluZyBvbiB0aGUgcGF0aFxyXG4gICAgaWYgKCFmaWx0ZXIuc3RhcnRzV2l0aCgnLycpICYmXHJcbiAgICAgICAgKGRlY29kZWRQYXRoLmluY2x1ZGVzKGZpbHRlcikgfHwgcGF0aC5pbmNsdWRlcyhmaWx0ZXIpKSlcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIGlmIChkZWNvZGVkUGF0aC5zdGFydHNXaXRoKGZpbHRlcikgfHwgcGF0aC5zdGFydHNXaXRoKGZpbHRlcikpXHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICBpZiAocm91dGUucmVjb3JkLm5hbWUgJiYgU3RyaW5nKHJvdXRlLnJlY29yZC5uYW1lKS5pbmNsdWRlcyhmaWx0ZXIpKVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgcmV0dXJuIHJvdXRlLmNoaWxkcmVuLnNvbWUoY2hpbGQgPT4gaXNSb3V0ZU1hdGNoaW5nKGNoaWxkLCBmaWx0ZXIpKTtcclxufVxyXG5mdW5jdGlvbiBvbWl0KG9iaiwga2V5cykge1xyXG4gICAgY29uc3QgcmV0ID0ge307XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcclxuICAgICAgICBpZiAoIWtleXMuaW5jbHVkZXMoa2V5KSkge1xyXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXHJcbiAgICAgICAgICAgIHJldFtrZXldID0gb2JqW2tleV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJldDtcclxufVxuXG4vKipcclxuICogQ3JlYXRlcyBhIFJvdXRlciBpbnN0YW5jZSB0aGF0IGNhbiBiZSB1c2VkIGJ5IGEgVnVlIGFwcC5cclxuICpcclxuICogQHBhcmFtIG9wdGlvbnMgLSB7QGxpbmsgUm91dGVyT3B0aW9uc31cclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZVJvdXRlcihvcHRpb25zKSB7XHJcbiAgICBjb25zdCBtYXRjaGVyID0gY3JlYXRlUm91dGVyTWF0Y2hlcihvcHRpb25zLnJvdXRlcywgb3B0aW9ucyk7XHJcbiAgICBjb25zdCBwYXJzZVF1ZXJ5JDEgPSBvcHRpb25zLnBhcnNlUXVlcnkgfHwgcGFyc2VRdWVyeTtcclxuICAgIGNvbnN0IHN0cmluZ2lmeVF1ZXJ5JDEgPSBvcHRpb25zLnN0cmluZ2lmeVF1ZXJ5IHx8IHN0cmluZ2lmeVF1ZXJ5O1xyXG4gICAgY29uc3Qgcm91dGVySGlzdG9yeSA9IG9wdGlvbnMuaGlzdG9yeTtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIXJvdXRlckhpc3RvcnkpXHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm92aWRlIHRoZSBcImhpc3RvcnlcIiBvcHRpb24gd2hlbiBjYWxsaW5nIFwiY3JlYXRlUm91dGVyKClcIjonICtcclxuICAgICAgICAgICAgJyBodHRwczovL25leHQucm91dGVyLnZ1ZWpzLm9yZy9hcGkvI2hpc3RvcnkuJyk7XHJcbiAgICBjb25zdCBiZWZvcmVHdWFyZHMgPSB1c2VDYWxsYmFja3MoKTtcclxuICAgIGNvbnN0IGJlZm9yZVJlc29sdmVHdWFyZHMgPSB1c2VDYWxsYmFja3MoKTtcclxuICAgIGNvbnN0IGFmdGVyR3VhcmRzID0gdXNlQ2FsbGJhY2tzKCk7XHJcbiAgICBjb25zdCBjdXJyZW50Um91dGUgPSBzaGFsbG93UmVmKFNUQVJUX0xPQ0FUSU9OX05PUk1BTElaRUQpO1xyXG4gICAgbGV0IHBlbmRpbmdMb2NhdGlvbiA9IFNUQVJUX0xPQ0FUSU9OX05PUk1BTElaRUQ7XHJcbiAgICAvLyBsZWF2ZSB0aGUgc2Nyb2xsUmVzdG9yYXRpb24gaWYgbm8gc2Nyb2xsQmVoYXZpb3IgaXMgcHJvdmlkZWRcclxuICAgIGlmIChpc0Jyb3dzZXIgJiYgb3B0aW9ucy5zY3JvbGxCZWhhdmlvciAmJiAnc2Nyb2xsUmVzdG9yYXRpb24nIGluIGhpc3RvcnkpIHtcclxuICAgICAgICBoaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uID0gJ21hbnVhbCc7XHJcbiAgICB9XHJcbiAgICBjb25zdCBub3JtYWxpemVQYXJhbXMgPSBhcHBseVRvUGFyYW1zLmJpbmQobnVsbCwgcGFyYW1WYWx1ZSA9PiAnJyArIHBhcmFtVmFsdWUpO1xyXG4gICAgY29uc3QgZW5jb2RlUGFyYW1zID0gYXBwbHlUb1BhcmFtcy5iaW5kKG51bGwsIGVuY29kZVBhcmFtKTtcclxuICAgIGNvbnN0IGRlY29kZVBhcmFtcyA9IFxyXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogaW50ZW50aW9uYWxseSBhdm9pZCB0aGUgdHlwZSBjaGVja1xyXG4gICAgYXBwbHlUb1BhcmFtcy5iaW5kKG51bGwsIGRlY29kZSk7XHJcbiAgICBmdW5jdGlvbiBhZGRSb3V0ZShwYXJlbnRPclJvdXRlLCByb3V0ZSkge1xyXG4gICAgICAgIGxldCBwYXJlbnQ7XHJcbiAgICAgICAgbGV0IHJlY29yZDtcclxuICAgICAgICBpZiAoaXNSb3V0ZU5hbWUocGFyZW50T3JSb3V0ZSkpIHtcclxuICAgICAgICAgICAgcGFyZW50ID0gbWF0Y2hlci5nZXRSZWNvcmRNYXRjaGVyKHBhcmVudE9yUm91dGUpO1xyXG4gICAgICAgICAgICByZWNvcmQgPSByb3V0ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJlY29yZCA9IHBhcmVudE9yUm91dGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBtYXRjaGVyLmFkZFJvdXRlKHJlY29yZCwgcGFyZW50KTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIHJlbW92ZVJvdXRlKG5hbWUpIHtcclxuICAgICAgICBjb25zdCByZWNvcmRNYXRjaGVyID0gbWF0Y2hlci5nZXRSZWNvcmRNYXRjaGVyKG5hbWUpO1xyXG4gICAgICAgIGlmIChyZWNvcmRNYXRjaGVyKSB7XHJcbiAgICAgICAgICAgIG1hdGNoZXIucmVtb3ZlUm91dGUocmVjb3JkTWF0Y2hlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICB3YXJuKGBDYW5ub3QgcmVtb3ZlIG5vbi1leGlzdGVudCByb3V0ZSBcIiR7U3RyaW5nKG5hbWUpfVwiYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gZ2V0Um91dGVzKCkge1xyXG4gICAgICAgIHJldHVybiBtYXRjaGVyLmdldFJvdXRlcygpLm1hcChyb3V0ZU1hdGNoZXIgPT4gcm91dGVNYXRjaGVyLnJlY29yZCk7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBoYXNSb3V0ZShuYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuICEhbWF0Y2hlci5nZXRSZWNvcmRNYXRjaGVyKG5hbWUpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gcmVzb2x2ZShyYXdMb2NhdGlvbiwgY3VycmVudExvY2F0aW9uKSB7XHJcbiAgICAgICAgLy8gY29uc3Qgb2JqZWN0TG9jYXRpb24gPSByb3V0ZXJMb2NhdGlvbkFzT2JqZWN0KHJhd0xvY2F0aW9uKVxyXG4gICAgICAgIC8vIHdlIGNyZWF0ZSBhIGNvcHkgdG8gbW9kaWZ5IGl0IGxhdGVyXHJcbiAgICAgICAgY3VycmVudExvY2F0aW9uID0gYXNzaWduKHt9LCBjdXJyZW50TG9jYXRpb24gfHwgY3VycmVudFJvdXRlLnZhbHVlKTtcclxuICAgICAgICBpZiAodHlwZW9mIHJhd0xvY2F0aW9uID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBjb25zdCBsb2NhdGlvbk5vcm1hbGl6ZWQgPSBwYXJzZVVSTChwYXJzZVF1ZXJ5JDEsIHJhd0xvY2F0aW9uLCBjdXJyZW50TG9jYXRpb24ucGF0aCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoZWRSb3V0ZSA9IG1hdGNoZXIucmVzb2x2ZSh7IHBhdGg6IGxvY2F0aW9uTm9ybWFsaXplZC5wYXRoIH0sIGN1cnJlbnRMb2NhdGlvbik7XHJcbiAgICAgICAgICAgIGNvbnN0IGhyZWYgPSByb3V0ZXJIaXN0b3J5LmNyZWF0ZUhyZWYobG9jYXRpb25Ob3JtYWxpemVkLmZ1bGxQYXRoKTtcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGhyZWYuc3RhcnRzV2l0aCgnLy8nKSlcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBMb2NhdGlvbiBcIiR7cmF3TG9jYXRpb259XCIgcmVzb2x2ZWQgdG8gXCIke2hyZWZ9XCIuIEEgcmVzb2x2ZWQgbG9jYXRpb24gY2Fubm90IHN0YXJ0IHdpdGggbXVsdGlwbGUgc2xhc2hlcy5gKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFtYXRjaGVkUm91dGUubWF0Y2hlZC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBObyBtYXRjaCBmb3VuZCBmb3IgbG9jYXRpb24gd2l0aCBwYXRoIFwiJHtyYXdMb2NhdGlvbn1cImApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGxvY2F0aW9uTm9ybWFsaXplZCBpcyBhbHdheXMgYSBuZXcgb2JqZWN0XHJcbiAgICAgICAgICAgIHJldHVybiBhc3NpZ24obG9jYXRpb25Ob3JtYWxpemVkLCBtYXRjaGVkUm91dGUsIHtcclxuICAgICAgICAgICAgICAgIHBhcmFtczogZGVjb2RlUGFyYW1zKG1hdGNoZWRSb3V0ZS5wYXJhbXMpLFxyXG4gICAgICAgICAgICAgICAgaGFzaDogZGVjb2RlKGxvY2F0aW9uTm9ybWFsaXplZC5oYXNoKSxcclxuICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICBocmVmLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IG1hdGNoZXJMb2NhdGlvbjtcclxuICAgICAgICAvLyBwYXRoIGNvdWxkIGJlIHJlbGF0aXZlIGluIG9iamVjdCBhcyB3ZWxsXHJcbiAgICAgICAgaWYgKCdwYXRoJyBpbiByYXdMb2NhdGlvbikge1xyXG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgICAgICAncGFyYW1zJyBpbiByYXdMb2NhdGlvbiAmJlxyXG4gICAgICAgICAgICAgICAgISgnbmFtZScgaW4gcmF3TG9jYXRpb24pICYmXHJcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yOiB0aGUgdHlwZSBpcyBuZXZlclxyXG4gICAgICAgICAgICAgICAgT2JqZWN0LmtleXMocmF3TG9jYXRpb24ucGFyYW1zKS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oYFBhdGggXCIke1xyXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogdGhlIHR5cGUgaXMgbmV2ZXJcclxuICAgICAgICAgICAgICAgIHJhd0xvY2F0aW9uLnBhdGh9XCIgd2FzIHBhc3NlZCB3aXRoIHBhcmFtcyBidXQgdGhleSB3aWxsIGJlIGlnbm9yZWQuIFVzZSBhIG5hbWVkIHJvdXRlIGFsb25nc2lkZSBwYXJhbXMgaW5zdGVhZC5gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBtYXRjaGVyTG9jYXRpb24gPSBhc3NpZ24oe30sIHJhd0xvY2F0aW9uLCB7XHJcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXJzZVVSTChwYXJzZVF1ZXJ5JDEsIHJhd0xvY2F0aW9uLnBhdGgsIGN1cnJlbnRMb2NhdGlvbi5wYXRoKS5wYXRoLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIHJlbW92ZSBhbnkgbnVsbGlzaCBwYXJhbVxyXG4gICAgICAgICAgICBjb25zdCB0YXJnZXRQYXJhbXMgPSBhc3NpZ24oe30sIHJhd0xvY2F0aW9uLnBhcmFtcyk7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRhcmdldFBhcmFtcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRhcmdldFBhcmFtc1trZXldID09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGFyZ2V0UGFyYW1zW2tleV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gcGFzcyBlbmNvZGVkIHZhbHVlcyB0byB0aGUgbWF0Y2hlciBzbyBpdCBjYW4gcHJvZHVjZSBlbmNvZGVkIHBhdGggYW5kIGZ1bGxQYXRoXHJcbiAgICAgICAgICAgIG1hdGNoZXJMb2NhdGlvbiA9IGFzc2lnbih7fSwgcmF3TG9jYXRpb24sIHtcclxuICAgICAgICAgICAgICAgIHBhcmFtczogZW5jb2RlUGFyYW1zKHJhd0xvY2F0aW9uLnBhcmFtcyksXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAvLyBjdXJyZW50IGxvY2F0aW9uIHBhcmFtcyBhcmUgZGVjb2RlZCwgd2UgbmVlZCB0byBlbmNvZGUgdGhlbSBpbiBjYXNlIHRoZVxyXG4gICAgICAgICAgICAvLyBtYXRjaGVyIG1lcmdlcyB0aGUgcGFyYW1zXHJcbiAgICAgICAgICAgIGN1cnJlbnRMb2NhdGlvbi5wYXJhbXMgPSBlbmNvZGVQYXJhbXMoY3VycmVudExvY2F0aW9uLnBhcmFtcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG1hdGNoZWRSb3V0ZSA9IG1hdGNoZXIucmVzb2x2ZShtYXRjaGVyTG9jYXRpb24sIGN1cnJlbnRMb2NhdGlvbik7XHJcbiAgICAgICAgY29uc3QgaGFzaCA9IHJhd0xvY2F0aW9uLmhhc2ggfHwgJyc7XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBoYXNoICYmICFoYXNoLnN0YXJ0c1dpdGgoJyMnKSkge1xyXG4gICAgICAgICAgICB3YXJuKGBBIFxcYGhhc2hcXGAgc2hvdWxkIGFsd2F5cyBzdGFydCB3aXRoIHRoZSBjaGFyYWN0ZXIgXCIjXCIuIFJlcGxhY2UgXCIke2hhc2h9XCIgd2l0aCBcIiMke2hhc2h9XCIuYCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGRlY29kaW5nIHRoZW0pIHRoZSBtYXRjaGVyIG1pZ2h0IGhhdmUgbWVyZ2VkIGN1cnJlbnQgbG9jYXRpb24gcGFyYW1zIHNvXHJcbiAgICAgICAgLy8gd2UgbmVlZCB0byBydW4gdGhlIGRlY29kaW5nIGFnYWluXHJcbiAgICAgICAgbWF0Y2hlZFJvdXRlLnBhcmFtcyA9IG5vcm1hbGl6ZVBhcmFtcyhkZWNvZGVQYXJhbXMobWF0Y2hlZFJvdXRlLnBhcmFtcykpO1xyXG4gICAgICAgIGNvbnN0IGZ1bGxQYXRoID0gc3RyaW5naWZ5VVJMKHN0cmluZ2lmeVF1ZXJ5JDEsIGFzc2lnbih7fSwgcmF3TG9jYXRpb24sIHtcclxuICAgICAgICAgICAgaGFzaDogZW5jb2RlSGFzaChoYXNoKSxcclxuICAgICAgICAgICAgcGF0aDogbWF0Y2hlZFJvdXRlLnBhdGgsXHJcbiAgICAgICAgfSkpO1xyXG4gICAgICAgIGNvbnN0IGhyZWYgPSByb3V0ZXJIaXN0b3J5LmNyZWF0ZUhyZWYoZnVsbFBhdGgpO1xyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgaWYgKGhyZWYuc3RhcnRzV2l0aCgnLy8nKSkge1xyXG4gICAgICAgICAgICAgICAgd2FybihgTG9jYXRpb24gXCIke3Jhd0xvY2F0aW9ufVwiIHJlc29sdmVkIHRvIFwiJHtocmVmfVwiLiBBIHJlc29sdmVkIGxvY2F0aW9uIGNhbm5vdCBzdGFydCB3aXRoIG11bHRpcGxlIHNsYXNoZXMuYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoIW1hdGNoZWRSb3V0ZS5tYXRjaGVkLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgd2FybihgTm8gbWF0Y2ggZm91bmQgZm9yIGxvY2F0aW9uIHdpdGggcGF0aCBcIiR7J3BhdGgnIGluIHJhd0xvY2F0aW9uID8gcmF3TG9jYXRpb24ucGF0aCA6IHJhd0xvY2F0aW9ufVwiYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGFzc2lnbih7XHJcbiAgICAgICAgICAgIGZ1bGxQYXRoLFxyXG4gICAgICAgICAgICAvLyBrZWVwIHRoZSBoYXNoIGVuY29kZWQgc28gZnVsbFBhdGggaXMgZWZmZWN0aXZlbHkgcGF0aCArIGVuY29kZWRRdWVyeSArXHJcbiAgICAgICAgICAgIC8vIGhhc2hcclxuICAgICAgICAgICAgaGFzaCxcclxuICAgICAgICAgICAgcXVlcnk6IFxyXG4gICAgICAgICAgICAvLyBpZiB0aGUgdXNlciBpcyB1c2luZyBhIGN1c3RvbSBxdWVyeSBsaWIgbGlrZSBxcywgd2UgbWlnaHQgaGF2ZVxyXG4gICAgICAgICAgICAvLyBuZXN0ZWQgb2JqZWN0cywgc28gd2Uga2VlcCB0aGUgcXVlcnkgYXMgaXMsIG1lYW5pbmcgaXQgY2FuIGNvbnRhaW5cclxuICAgICAgICAgICAgLy8gbnVtYmVycyBhdCBgJHJvdXRlLnF1ZXJ5YCwgYnV0IGF0IHRoZSBwb2ludCwgdGhlIHVzZXIgd2lsbCBoYXZlIHRvXHJcbiAgICAgICAgICAgIC8vIHVzZSB0aGVpciBvd24gdHlwZSBhbnl3YXkuXHJcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS92dWVqcy92dWUtcm91dGVyLW5leHQvaXNzdWVzLzMyOCNpc3N1ZWNvbW1lbnQtNjQ5NDgxNTY3XHJcbiAgICAgICAgICAgIHN0cmluZ2lmeVF1ZXJ5JDEgPT09IHN0cmluZ2lmeVF1ZXJ5XHJcbiAgICAgICAgICAgICAgICA/IG5vcm1hbGl6ZVF1ZXJ5KHJhd0xvY2F0aW9uLnF1ZXJ5KVxyXG4gICAgICAgICAgICAgICAgOiAocmF3TG9jYXRpb24ucXVlcnkgfHwge30pLFxyXG4gICAgICAgIH0sIG1hdGNoZWRSb3V0ZSwge1xyXG4gICAgICAgICAgICByZWRpcmVjdGVkRnJvbTogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBocmVmLFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gbG9jYXRpb25Bc09iamVjdCh0bykge1xyXG4gICAgICAgIHJldHVybiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnXHJcbiAgICAgICAgICAgID8gcGFyc2VVUkwocGFyc2VRdWVyeSQxLCB0bywgY3VycmVudFJvdXRlLnZhbHVlLnBhdGgpXHJcbiAgICAgICAgICAgIDogYXNzaWduKHt9LCB0byk7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBjaGVja0NhbmNlbGVkTmF2aWdhdGlvbih0bywgZnJvbSkge1xyXG4gICAgICAgIGlmIChwZW5kaW5nTG9jYXRpb24gIT09IHRvKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVSb3V0ZXJFcnJvcig4IC8qIE5BVklHQVRJT05fQ0FOQ0VMTEVEICovLCB7XHJcbiAgICAgICAgICAgICAgICBmcm9tLFxyXG4gICAgICAgICAgICAgICAgdG8sXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIHB1c2godG8pIHtcclxuICAgICAgICByZXR1cm4gcHVzaFdpdGhSZWRpcmVjdCh0byk7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiByZXBsYWNlKHRvKSB7XHJcbiAgICAgICAgcmV0dXJuIHB1c2goYXNzaWduKGxvY2F0aW9uQXNPYmplY3QodG8pLCB7IHJlcGxhY2U6IHRydWUgfSkpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gaGFuZGxlUmVkaXJlY3RSZWNvcmQodG8pIHtcclxuICAgICAgICBjb25zdCBsYXN0TWF0Y2hlZCA9IHRvLm1hdGNoZWRbdG8ubWF0Y2hlZC5sZW5ndGggLSAxXTtcclxuICAgICAgICBpZiAobGFzdE1hdGNoZWQgJiYgbGFzdE1hdGNoZWQucmVkaXJlY3QpIHtcclxuICAgICAgICAgICAgY29uc3QgeyByZWRpcmVjdCB9ID0gbGFzdE1hdGNoZWQ7XHJcbiAgICAgICAgICAgIGxldCBuZXdUYXJnZXRMb2NhdGlvbiA9IHR5cGVvZiByZWRpcmVjdCA9PT0gJ2Z1bmN0aW9uJyA/IHJlZGlyZWN0KHRvKSA6IHJlZGlyZWN0O1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG5ld1RhcmdldExvY2F0aW9uID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgbmV3VGFyZ2V0TG9jYXRpb24gPVxyXG4gICAgICAgICAgICAgICAgICAgIG5ld1RhcmdldExvY2F0aW9uLmluY2x1ZGVzKCc/JykgfHwgbmV3VGFyZ2V0TG9jYXRpb24uaW5jbHVkZXMoJyMnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IChuZXdUYXJnZXRMb2NhdGlvbiA9IGxvY2F0aW9uQXNPYmplY3QobmV3VGFyZ2V0TG9jYXRpb24pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IC8vIGZvcmNlIGVtcHR5IHBhcmFtc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBwYXRoOiBuZXdUYXJnZXRMb2NhdGlvbiB9O1xyXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogZm9yY2UgZW1wdHkgcGFyYW1zIHdoZW4gYSBzdHJpbmcgaXMgcGFzc2VkIHRvIGxldFxyXG4gICAgICAgICAgICAgICAgLy8gdGhlIHJvdXRlciBwYXJzZSB0aGVtIGFnYWluXHJcbiAgICAgICAgICAgICAgICBuZXdUYXJnZXRMb2NhdGlvbi5wYXJhbXMgPSB7fTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgICAgICAhKCdwYXRoJyBpbiBuZXdUYXJnZXRMb2NhdGlvbikgJiZcclxuICAgICAgICAgICAgICAgICEoJ25hbWUnIGluIG5ld1RhcmdldExvY2F0aW9uKSkge1xyXG4gICAgICAgICAgICAgICAgd2FybihgSW52YWxpZCByZWRpcmVjdCBmb3VuZDpcXG4ke0pTT04uc3RyaW5naWZ5KG5ld1RhcmdldExvY2F0aW9uLCBudWxsLCAyKX1cXG4gd2hlbiBuYXZpZ2F0aW5nIHRvIFwiJHt0by5mdWxsUGF0aH1cIi4gQSByZWRpcmVjdCBtdXN0IGNvbnRhaW4gYSBuYW1lIG9yIHBhdGguIFRoaXMgd2lsbCBicmVhayBpbiBwcm9kdWN0aW9uLmApO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHJlZGlyZWN0Jyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGFzc2lnbih7XHJcbiAgICAgICAgICAgICAgICBxdWVyeTogdG8ucXVlcnksXHJcbiAgICAgICAgICAgICAgICBoYXNoOiB0by5oYXNoLFxyXG4gICAgICAgICAgICAgICAgcGFyYW1zOiB0by5wYXJhbXMsXHJcbiAgICAgICAgICAgIH0sIG5ld1RhcmdldExvY2F0aW9uKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBwdXNoV2l0aFJlZGlyZWN0KHRvLCByZWRpcmVjdGVkRnJvbSkge1xyXG4gICAgICAgIGNvbnN0IHRhcmdldExvY2F0aW9uID0gKHBlbmRpbmdMb2NhdGlvbiA9IHJlc29sdmUodG8pKTtcclxuICAgICAgICBjb25zdCBmcm9tID0gY3VycmVudFJvdXRlLnZhbHVlO1xyXG4gICAgICAgIGNvbnN0IGRhdGEgPSB0by5zdGF0ZTtcclxuICAgICAgICBjb25zdCBmb3JjZSA9IHRvLmZvcmNlO1xyXG4gICAgICAgIC8vIHRvIGNvdWxkIGJlIGEgc3RyaW5nIHdoZXJlIGByZXBsYWNlYCBpcyBhIGZ1bmN0aW9uXHJcbiAgICAgICAgY29uc3QgcmVwbGFjZSA9IHRvLnJlcGxhY2UgPT09IHRydWU7XHJcbiAgICAgICAgY29uc3Qgc2hvdWxkUmVkaXJlY3QgPSBoYW5kbGVSZWRpcmVjdFJlY29yZCh0YXJnZXRMb2NhdGlvbik7XHJcbiAgICAgICAgaWYgKHNob3VsZFJlZGlyZWN0KVxyXG4gICAgICAgICAgICByZXR1cm4gcHVzaFdpdGhSZWRpcmVjdChhc3NpZ24obG9jYXRpb25Bc09iamVjdChzaG91bGRSZWRpcmVjdCksIHtcclxuICAgICAgICAgICAgICAgIHN0YXRlOiBkYXRhLFxyXG4gICAgICAgICAgICAgICAgZm9yY2UsXHJcbiAgICAgICAgICAgICAgICByZXBsYWNlLFxyXG4gICAgICAgICAgICB9KSwgXHJcbiAgICAgICAgICAgIC8vIGtlZXAgb3JpZ2luYWwgcmVkaXJlY3RlZEZyb20gaWYgaXQgZXhpc3RzXHJcbiAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tIHx8IHRhcmdldExvY2F0aW9uKTtcclxuICAgICAgICAvLyBpZiBpdCB3YXMgYSByZWRpcmVjdCB3ZSBhbHJlYWR5IGNhbGxlZCBgcHVzaFdpdGhSZWRpcmVjdGAgYWJvdmVcclxuICAgICAgICBjb25zdCB0b0xvY2F0aW9uID0gdGFyZ2V0TG9jYXRpb247XHJcbiAgICAgICAgdG9Mb2NhdGlvbi5yZWRpcmVjdGVkRnJvbSA9IHJlZGlyZWN0ZWRGcm9tO1xyXG4gICAgICAgIGxldCBmYWlsdXJlO1xyXG4gICAgICAgIGlmICghZm9yY2UgJiYgaXNTYW1lUm91dGVMb2NhdGlvbihzdHJpbmdpZnlRdWVyeSQxLCBmcm9tLCB0YXJnZXRMb2NhdGlvbikpIHtcclxuICAgICAgICAgICAgZmFpbHVyZSA9IGNyZWF0ZVJvdXRlckVycm9yKDE2IC8qIE5BVklHQVRJT05fRFVQTElDQVRFRCAqLywgeyB0bzogdG9Mb2NhdGlvbiwgZnJvbSB9KTtcclxuICAgICAgICAgICAgLy8gdHJpZ2dlciBzY3JvbGwgdG8gYWxsb3cgc2Nyb2xsaW5nIHRvIHRoZSBzYW1lIGFuY2hvclxyXG4gICAgICAgICAgICBoYW5kbGVTY3JvbGwoZnJvbSwgZnJvbSwgXHJcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgYSBwdXNoLCB0aGUgb25seSB3YXkgZm9yIGl0IHRvIGJlIHRyaWdnZXJlZCBmcm9tIGFcclxuICAgICAgICAgICAgLy8gaGlzdG9yeS5saXN0ZW4gaXMgd2l0aCBhIHJlZGlyZWN0LCB3aGljaCBtYWtlcyBpdCBiZWNvbWUgYSBwdXNoXHJcbiAgICAgICAgICAgIHRydWUsIFxyXG4gICAgICAgICAgICAvLyBUaGlzIGNhbm5vdCBiZSB0aGUgZmlyc3QgbmF2aWdhdGlvbiBiZWNhdXNlIHRoZSBpbml0aWFsIGxvY2F0aW9uXHJcbiAgICAgICAgICAgIC8vIGNhbm5vdCBiZSBtYW51YWxseSBuYXZpZ2F0ZWQgdG9cclxuICAgICAgICAgICAgZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gKGZhaWx1cmUgPyBQcm9taXNlLnJlc29sdmUoZmFpbHVyZSkgOiBuYXZpZ2F0ZSh0b0xvY2F0aW9uLCBmcm9tKSlcclxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gaXNOYXZpZ2F0aW9uRmFpbHVyZShlcnJvcilcclxuICAgICAgICAgICAgPyBlcnJvclxyXG4gICAgICAgICAgICA6IC8vIHJlamVjdCBhbnkgdW5rbm93biBlcnJvclxyXG4gICAgICAgICAgICAgICAgdHJpZ2dlckVycm9yKGVycm9yLCB0b0xvY2F0aW9uLCBmcm9tKSlcclxuICAgICAgICAgICAgLnRoZW4oKGZhaWx1cmUpID0+IHtcclxuICAgICAgICAgICAgaWYgKGZhaWx1cmUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpc05hdmlnYXRpb25GYWlsdXJlKGZhaWx1cmUsIDIgLyogTkFWSUdBVElPTl9HVUFSRF9SRURJUkVDVCAqLykpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGFyZSByZWRpcmVjdGluZyB0byB0aGUgc2FtZSBsb2NhdGlvbiB3ZSB3ZXJlIGFscmVhZHkgYXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXNTYW1lUm91dGVMb2NhdGlvbihzdHJpbmdpZnlRdWVyeSQxLCByZXNvbHZlKGZhaWx1cmUudG8pLCB0b0xvY2F0aW9uKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbmQgd2UgaGF2ZSBkb25lIGl0IGEgY291cGxlIG9mIHRpbWVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3I6IGFkZGVkIG9ubHkgaW4gZGV2XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChyZWRpcmVjdGVkRnJvbS5fY291bnQgPSByZWRpcmVjdGVkRnJvbS5fY291bnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gLy8gQHRzLWV4cGVjdC1lcnJvclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tLl9jb3VudCArIDFcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogMSkgPiAxMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3YXJuKGBEZXRlY3RlZCBhbiBpbmZpbml0ZSByZWRpcmVjdGlvbiBpbiBhIG5hdmlnYXRpb24gZ3VhcmQgd2hlbiBnb2luZyBmcm9tIFwiJHtmcm9tLmZ1bGxQYXRofVwiIHRvIFwiJHt0b0xvY2F0aW9uLmZ1bGxQYXRofVwiLiBBYm9ydGluZyB0byBhdm9pZCBhIFN0YWNrIE92ZXJmbG93LiBUaGlzIHdpbGwgYnJlYWsgaW4gcHJvZHVjdGlvbiBpZiBub3QgZml4ZWQuYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ0luZmluaXRlIHJlZGlyZWN0IGluIG5hdmlnYXRpb24gZ3VhcmQnKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwdXNoV2l0aFJlZGlyZWN0KFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGtlZXAgb3B0aW9uc1xyXG4gICAgICAgICAgICAgICAgICAgIGFzc2lnbihsb2NhdGlvbkFzT2JqZWN0KGZhaWx1cmUudG8pLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlOiBkYXRhLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JjZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZSxcclxuICAgICAgICAgICAgICAgICAgICB9KSwgXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gcHJlc2VydmUgdGhlIG9yaWdpbmFsIHJlZGlyZWN0ZWRGcm9tIGlmIGFueVxyXG4gICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0ZWRGcm9tIHx8IHRvTG9jYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gaWYgd2UgZmFpbCB3ZSBkb24ndCBmaW5hbGl6ZSB0aGUgbmF2aWdhdGlvblxyXG4gICAgICAgICAgICAgICAgZmFpbHVyZSA9IGZpbmFsaXplTmF2aWdhdGlvbih0b0xvY2F0aW9uLCBmcm9tLCB0cnVlLCByZXBsYWNlLCBkYXRhKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0cmlnZ2VyQWZ0ZXJFYWNoKHRvTG9jYXRpb24sIGZyb20sIGZhaWx1cmUpO1xyXG4gICAgICAgICAgICByZXR1cm4gZmFpbHVyZTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIHRvIHJlamVjdCBhbmQgc2tpcCBhbGwgbmF2aWdhdGlvbiBndWFyZHMgaWYgYSBuZXcgbmF2aWdhdGlvbiBoYXBwZW5lZFxyXG4gICAgICogQHBhcmFtIHRvXHJcbiAgICAgKiBAcGFyYW0gZnJvbVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBjaGVja0NhbmNlbGVkTmF2aWdhdGlvbkFuZFJlamVjdCh0bywgZnJvbSkge1xyXG4gICAgICAgIGNvbnN0IGVycm9yID0gY2hlY2tDYW5jZWxlZE5hdmlnYXRpb24odG8sIGZyb20pO1xyXG4gICAgICAgIHJldHVybiBlcnJvciA/IFByb21pc2UucmVqZWN0KGVycm9yKSA6IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgfVxyXG4gICAgLy8gVE9ETzogcmVmYWN0b3IgdGhlIHdob2xlIGJlZm9yZSBndWFyZHMgYnkgaW50ZXJuYWxseSB1c2luZyByb3V0ZXIuYmVmb3JlRWFjaFxyXG4gICAgZnVuY3Rpb24gbmF2aWdhdGUodG8sIGZyb20pIHtcclxuICAgICAgICBsZXQgZ3VhcmRzO1xyXG4gICAgICAgIGNvbnN0IFtsZWF2aW5nUmVjb3JkcywgdXBkYXRpbmdSZWNvcmRzLCBlbnRlcmluZ1JlY29yZHNdID0gZXh0cmFjdENoYW5naW5nUmVjb3Jkcyh0bywgZnJvbSk7XHJcbiAgICAgICAgLy8gYWxsIGNvbXBvbmVudHMgaGVyZSBoYXZlIGJlZW4gcmVzb2x2ZWQgb25jZSBiZWNhdXNlIHdlIGFyZSBsZWF2aW5nXHJcbiAgICAgICAgZ3VhcmRzID0gZXh0cmFjdENvbXBvbmVudHNHdWFyZHMobGVhdmluZ1JlY29yZHMucmV2ZXJzZSgpLCAnYmVmb3JlUm91dGVMZWF2ZScsIHRvLCBmcm9tKTtcclxuICAgICAgICAvLyBsZWF2aW5nUmVjb3JkcyBpcyBhbHJlYWR5IHJldmVyc2VkXHJcbiAgICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgbGVhdmluZ1JlY29yZHMpIHtcclxuICAgICAgICAgICAgcmVjb3JkLmxlYXZlR3VhcmRzLmZvckVhY2goZ3VhcmQgPT4ge1xyXG4gICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goZ3VhcmRUb1Byb21pc2VGbihndWFyZCwgdG8sIGZyb20pKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGNhbmNlbGVkTmF2aWdhdGlvbkNoZWNrID0gY2hlY2tDYW5jZWxlZE5hdmlnYXRpb25BbmRSZWplY3QuYmluZChudWxsLCB0bywgZnJvbSk7XHJcbiAgICAgICAgZ3VhcmRzLnB1c2goY2FuY2VsZWROYXZpZ2F0aW9uQ2hlY2spO1xyXG4gICAgICAgIC8vIHJ1biB0aGUgcXVldWUgb2YgcGVyIHJvdXRlIGJlZm9yZVJvdXRlTGVhdmUgZ3VhcmRzXHJcbiAgICAgICAgcmV0dXJuIChydW5HdWFyZFF1ZXVlKGd1YXJkcylcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBjaGVjayBnbG9iYWwgZ3VhcmRzIGJlZm9yZUVhY2hcclxuICAgICAgICAgICAgZ3VhcmRzID0gW107XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgZ3VhcmQgb2YgYmVmb3JlR3VhcmRzLmxpc3QoKSkge1xyXG4gICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goZ3VhcmRUb1Byb21pc2VGbihndWFyZCwgdG8sIGZyb20pKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBndWFyZHMucHVzaChjYW5jZWxlZE5hdmlnYXRpb25DaGVjayk7XHJcbiAgICAgICAgICAgIHJldHVybiBydW5HdWFyZFF1ZXVlKGd1YXJkcyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBjaGVjayBpbiBjb21wb25lbnRzIGJlZm9yZVJvdXRlVXBkYXRlXHJcbiAgICAgICAgICAgIGd1YXJkcyA9IGV4dHJhY3RDb21wb25lbnRzR3VhcmRzKHVwZGF0aW5nUmVjb3JkcywgJ2JlZm9yZVJvdXRlVXBkYXRlJywgdG8sIGZyb20pO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiB1cGRhdGluZ1JlY29yZHMpIHtcclxuICAgICAgICAgICAgICAgIHJlY29yZC51cGRhdGVHdWFyZHMuZm9yRWFjaChndWFyZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goZ3VhcmRUb1Byb21pc2VGbihndWFyZCwgdG8sIGZyb20pKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGd1YXJkcy5wdXNoKGNhbmNlbGVkTmF2aWdhdGlvbkNoZWNrKTtcclxuICAgICAgICAgICAgLy8gcnVuIHRoZSBxdWV1ZSBvZiBwZXIgcm91dGUgYmVmb3JlRW50ZXIgZ3VhcmRzXHJcbiAgICAgICAgICAgIHJldHVybiBydW5HdWFyZFF1ZXVlKGd1YXJkcyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBjaGVjayB0aGUgcm91dGUgYmVmb3JlRW50ZXJcclxuICAgICAgICAgICAgZ3VhcmRzID0gW107XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIHRvLm1hdGNoZWQpIHtcclxuICAgICAgICAgICAgICAgIC8vIGRvIG5vdCB0cmlnZ2VyIGJlZm9yZUVudGVyIG9uIHJldXNlZCB2aWV3c1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlY29yZC5iZWZvcmVFbnRlciAmJiAhZnJvbS5tYXRjaGVkLmluY2x1ZGVzKHJlY29yZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyZWNvcmQuYmVmb3JlRW50ZXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmVmb3JlRW50ZXIgb2YgcmVjb3JkLmJlZm9yZUVudGVyKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3VhcmRzLnB1c2goZ3VhcmRUb1Byb21pc2VGbihiZWZvcmVFbnRlciwgdG8sIGZyb20pKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGd1YXJkcy5wdXNoKGd1YXJkVG9Qcm9taXNlRm4ocmVjb3JkLmJlZm9yZUVudGVyLCB0bywgZnJvbSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBndWFyZHMucHVzaChjYW5jZWxlZE5hdmlnYXRpb25DaGVjayk7XHJcbiAgICAgICAgICAgIC8vIHJ1biB0aGUgcXVldWUgb2YgcGVyIHJvdXRlIGJlZm9yZUVudGVyIGd1YXJkc1xyXG4gICAgICAgICAgICByZXR1cm4gcnVuR3VhcmRRdWV1ZShndWFyZHMpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgLy8gTk9URTogYXQgdGhpcyBwb2ludCB0by5tYXRjaGVkIGlzIG5vcm1hbGl6ZWQgYW5kIGRvZXMgbm90IGNvbnRhaW4gYW55ICgpID0+IFByb21pc2U8Q29tcG9uZW50PlxyXG4gICAgICAgICAgICAvLyBjbGVhciBleGlzdGluZyBlbnRlckNhbGxiYWNrcywgdGhlc2UgYXJlIGFkZGVkIGJ5IGV4dHJhY3RDb21wb25lbnRzR3VhcmRzXHJcbiAgICAgICAgICAgIHRvLm1hdGNoZWQuZm9yRWFjaChyZWNvcmQgPT4gKHJlY29yZC5lbnRlckNhbGxiYWNrcyA9IHt9KSk7XHJcbiAgICAgICAgICAgIC8vIGNoZWNrIGluLWNvbXBvbmVudCBiZWZvcmVSb3V0ZUVudGVyXHJcbiAgICAgICAgICAgIGd1YXJkcyA9IGV4dHJhY3RDb21wb25lbnRzR3VhcmRzKGVudGVyaW5nUmVjb3JkcywgJ2JlZm9yZVJvdXRlRW50ZXInLCB0bywgZnJvbSk7XHJcbiAgICAgICAgICAgIGd1YXJkcy5wdXNoKGNhbmNlbGVkTmF2aWdhdGlvbkNoZWNrKTtcclxuICAgICAgICAgICAgLy8gcnVuIHRoZSBxdWV1ZSBvZiBwZXIgcm91dGUgYmVmb3JlRW50ZXIgZ3VhcmRzXHJcbiAgICAgICAgICAgIHJldHVybiBydW5HdWFyZFF1ZXVlKGd1YXJkcyk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBjaGVjayBnbG9iYWwgZ3VhcmRzIGJlZm9yZVJlc29sdmVcclxuICAgICAgICAgICAgZ3VhcmRzID0gW107XHJcbiAgICAgICAgICAgIGZvciAoY29uc3QgZ3VhcmQgb2YgYmVmb3JlUmVzb2x2ZUd1YXJkcy5saXN0KCkpIHtcclxuICAgICAgICAgICAgICAgIGd1YXJkcy5wdXNoKGd1YXJkVG9Qcm9taXNlRm4oZ3VhcmQsIHRvLCBmcm9tKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZ3VhcmRzLnB1c2goY2FuY2VsZWROYXZpZ2F0aW9uQ2hlY2spO1xyXG4gICAgICAgICAgICByZXR1cm4gcnVuR3VhcmRRdWV1ZShndWFyZHMpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgICAgIC8vIGNhdGNoIGFueSBuYXZpZ2F0aW9uIGNhbmNlbGVkXHJcbiAgICAgICAgICAgIC5jYXRjaChlcnIgPT4gaXNOYXZpZ2F0aW9uRmFpbHVyZShlcnIsIDggLyogTkFWSUdBVElPTl9DQU5DRUxMRUQgKi8pXHJcbiAgICAgICAgICAgID8gZXJyXHJcbiAgICAgICAgICAgIDogUHJvbWlzZS5yZWplY3QoZXJyKSkpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gdHJpZ2dlckFmdGVyRWFjaCh0bywgZnJvbSwgZmFpbHVyZSkge1xyXG4gICAgICAgIC8vIG5hdmlnYXRpb24gaXMgY29uZmlybWVkLCBjYWxsIGFmdGVyR3VhcmRzXHJcbiAgICAgICAgLy8gVE9ETzogd3JhcCB3aXRoIGVycm9yIGhhbmRsZXJzXHJcbiAgICAgICAgZm9yIChjb25zdCBndWFyZCBvZiBhZnRlckd1YXJkcy5saXN0KCkpXHJcbiAgICAgICAgICAgIGd1YXJkKHRvLCBmcm9tLCBmYWlsdXJlKTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogLSBDbGVhbnMgdXAgYW55IG5hdmlnYXRpb24gZ3VhcmRzXHJcbiAgICAgKiAtIENoYW5nZXMgdGhlIHVybCBpZiBuZWNlc3NhcnlcclxuICAgICAqIC0gQ2FsbHMgdGhlIHNjcm9sbEJlaGF2aW9yXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGZpbmFsaXplTmF2aWdhdGlvbih0b0xvY2F0aW9uLCBmcm9tLCBpc1B1c2gsIHJlcGxhY2UsIGRhdGEpIHtcclxuICAgICAgICAvLyBhIG1vcmUgcmVjZW50IG5hdmlnYXRpb24gdG9vayBwbGFjZVxyXG4gICAgICAgIGNvbnN0IGVycm9yID0gY2hlY2tDYW5jZWxlZE5hdmlnYXRpb24odG9Mb2NhdGlvbiwgZnJvbSk7XHJcbiAgICAgICAgaWYgKGVycm9yKVxyXG4gICAgICAgICAgICByZXR1cm4gZXJyb3I7XHJcbiAgICAgICAgLy8gb25seSBjb25zaWRlciBhcyBwdXNoIGlmIGl0J3Mgbm90IHRoZSBmaXJzdCBuYXZpZ2F0aW9uXHJcbiAgICAgICAgY29uc3QgaXNGaXJzdE5hdmlnYXRpb24gPSBmcm9tID09PSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEO1xyXG4gICAgICAgIGNvbnN0IHN0YXRlID0gIWlzQnJvd3NlciA/IHt9IDogaGlzdG9yeS5zdGF0ZTtcclxuICAgICAgICAvLyBjaGFuZ2UgVVJMIG9ubHkgaWYgdGhlIHVzZXIgZGlkIGEgcHVzaC9yZXBsYWNlIGFuZCBpZiBpdCdzIG5vdCB0aGUgaW5pdGlhbCBuYXZpZ2F0aW9uIGJlY2F1c2VcclxuICAgICAgICAvLyBpdCdzIGp1c3QgcmVmbGVjdGluZyB0aGUgdXJsXHJcbiAgICAgICAgaWYgKGlzUHVzaCkge1xyXG4gICAgICAgICAgICAvLyBvbiB0aGUgaW5pdGlhbCBuYXZpZ2F0aW9uLCB3ZSB3YW50IHRvIHJldXNlIHRoZSBzY3JvbGwgcG9zaXRpb24gZnJvbVxyXG4gICAgICAgICAgICAvLyBoaXN0b3J5IHN0YXRlIGlmIGl0IGV4aXN0c1xyXG4gICAgICAgICAgICBpZiAocmVwbGFjZSB8fCBpc0ZpcnN0TmF2aWdhdGlvbilcclxuICAgICAgICAgICAgICAgIHJvdXRlckhpc3RvcnkucmVwbGFjZSh0b0xvY2F0aW9uLmZ1bGxQYXRoLCBhc3NpZ24oe1xyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbDogaXNGaXJzdE5hdmlnYXRpb24gJiYgc3RhdGUgJiYgc3RhdGUuc2Nyb2xsLFxyXG4gICAgICAgICAgICAgICAgfSwgZGF0YSkpO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICByb3V0ZXJIaXN0b3J5LnB1c2godG9Mb2NhdGlvbi5mdWxsUGF0aCwgZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGFjY2VwdCBjdXJyZW50IG5hdmlnYXRpb25cclxuICAgICAgICBjdXJyZW50Um91dGUudmFsdWUgPSB0b0xvY2F0aW9uO1xyXG4gICAgICAgIGhhbmRsZVNjcm9sbCh0b0xvY2F0aW9uLCBmcm9tLCBpc1B1c2gsIGlzRmlyc3ROYXZpZ2F0aW9uKTtcclxuICAgICAgICBtYXJrQXNSZWFkeSgpO1xyXG4gICAgfVxyXG4gICAgbGV0IHJlbW92ZUhpc3RvcnlMaXN0ZW5lcjtcclxuICAgIC8vIGF0dGFjaCBsaXN0ZW5lciB0byBoaXN0b3J5IHRvIHRyaWdnZXIgbmF2aWdhdGlvbnNcclxuICAgIGZ1bmN0aW9uIHNldHVwTGlzdGVuZXJzKCkge1xyXG4gICAgICAgIHJlbW92ZUhpc3RvcnlMaXN0ZW5lciA9IHJvdXRlckhpc3RvcnkubGlzdGVuKCh0bywgX2Zyb20sIGluZm8pID0+IHtcclxuICAgICAgICAgICAgLy8gY2Fubm90IGJlIGEgcmVkaXJlY3Qgcm91dGUgYmVjYXVzZSBpdCB3YXMgaW4gaGlzdG9yeVxyXG4gICAgICAgICAgICBjb25zdCB0b0xvY2F0aW9uID0gcmVzb2x2ZSh0byk7XHJcbiAgICAgICAgICAgIC8vIGR1ZSB0byBkeW5hbWljIHJvdXRpbmcsIGFuZCB0byBoYXNoIGhpc3Rvcnkgd2l0aCBtYW51YWwgbmF2aWdhdGlvblxyXG4gICAgICAgICAgICAvLyAobWFudWFsbHkgY2hhbmdpbmcgdGhlIHVybCBvciBjYWxsaW5nIGhpc3RvcnkuaGFzaCA9ICcjL3NvbWV3aGVyZScpLFxyXG4gICAgICAgICAgICAvLyB0aGVyZSBjb3VsZCBiZSBhIHJlZGlyZWN0IHJlY29yZCBpbiBoaXN0b3J5XHJcbiAgICAgICAgICAgIGNvbnN0IHNob3VsZFJlZGlyZWN0ID0gaGFuZGxlUmVkaXJlY3RSZWNvcmQodG9Mb2NhdGlvbik7XHJcbiAgICAgICAgICAgIGlmIChzaG91bGRSZWRpcmVjdCkge1xyXG4gICAgICAgICAgICAgICAgcHVzaFdpdGhSZWRpcmVjdChhc3NpZ24oc2hvdWxkUmVkaXJlY3QsIHsgcmVwbGFjZTogdHJ1ZSB9KSwgdG9Mb2NhdGlvbikuY2F0Y2gobm9vcCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcGVuZGluZ0xvY2F0aW9uID0gdG9Mb2NhdGlvbjtcclxuICAgICAgICAgICAgY29uc3QgZnJvbSA9IGN1cnJlbnRSb3V0ZS52YWx1ZTtcclxuICAgICAgICAgICAgLy8gVE9ETzogc2hvdWxkIGJlIG1vdmVkIHRvIHdlYiBoaXN0b3J5P1xyXG4gICAgICAgICAgICBpZiAoaXNCcm93c2VyKSB7XHJcbiAgICAgICAgICAgICAgICBzYXZlU2Nyb2xsUG9zaXRpb24oZ2V0U2Nyb2xsS2V5KGZyb20uZnVsbFBhdGgsIGluZm8uZGVsdGEpLCBjb21wdXRlU2Nyb2xsUG9zaXRpb24oKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbmF2aWdhdGUodG9Mb2NhdGlvbiwgZnJvbSlcclxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChpc05hdmlnYXRpb25GYWlsdXJlKGVycm9yLCA0IC8qIE5BVklHQVRJT05fQUJPUlRFRCAqLyB8IDggLyogTkFWSUdBVElPTl9DQU5DRUxMRUQgKi8pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGlzTmF2aWdhdGlvbkZhaWx1cmUoZXJyb3IsIDIgLyogTkFWSUdBVElPTl9HVUFSRF9SRURJUkVDVCAqLykpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBIZXJlIHdlIGNvdWxkIGNhbGwgaWYgKGluZm8uZGVsdGEpIHJvdXRlckhpc3RvcnkuZ28oLWluZm8uZGVsdGEsXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZmFsc2UpIGJ1dCB0aGlzIGlzIGJ1ZyBwcm9uZSBhcyB3ZSBoYXZlIG5vIHdheSB0byB3YWl0IHRoZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG5hdmlnYXRpb24gdG8gYmUgZmluaXNoZWQgYmVmb3JlIGNhbGxpbmcgcHVzaFdpdGhSZWRpcmVjdC4gVXNpbmdcclxuICAgICAgICAgICAgICAgICAgICAvLyBhIHNldFRpbWVvdXQgb2YgMTZtcyBzZWVtcyB0byB3b3JrIGJ1dCB0aGVyZSBpcyBub3QgZ3VhcmFudGVlIGZvclxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGl0IHRvIHdvcmsgb24gZXZlcnkgYnJvd3Nlci4gU28gSW5zdGVhZCB3ZSBkbyBub3QgcmVzdG9yZSB0aGVcclxuICAgICAgICAgICAgICAgICAgICAvLyBoaXN0b3J5IGVudHJ5IGFuZCB0cmlnZ2VyIGEgbmV3IG5hdmlnYXRpb24gYXMgcmVxdWVzdGVkIGJ5IHRoZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG5hdmlnYXRpb24gZ3VhcmQuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGVycm9yIGlzIGFscmVhZHkgaGFuZGxlZCBieSByb3V0ZXIucHVzaCB3ZSBqdXN0IHdhbnQgdG8gYXZvaWRcclxuICAgICAgICAgICAgICAgICAgICAvLyBsb2dnaW5nIHRoZSBlcnJvclxyXG4gICAgICAgICAgICAgICAgICAgIHB1c2hXaXRoUmVkaXJlY3QoZXJyb3IudG8sIHRvTG9jYXRpb25cclxuICAgICAgICAgICAgICAgICAgICAvLyBhdm9pZCBhbiB1bmNhdWdodCByZWplY3Rpb24sIGxldCBwdXNoIGNhbGwgdHJpZ2dlckVycm9yXHJcbiAgICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihmYWlsdXJlID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFudWFsIGNoYW5nZSBpbiBoYXNoIGhpc3RvcnkgIzkxNiBlbmRpbmcgdXAgaW4gdGhlIFVSTCBub3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hhbmdpbmcgYnV0IGl0IHdhcyBjaGFuZ2VkIGJ5IHRoZSBtYW51YWwgdXJsIGNoYW5nZSwgc28gd2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmVlZCB0byBtYW51YWxseSBjaGFuZ2UgaXQgb3Vyc2VsdmVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc05hdmlnYXRpb25GYWlsdXJlKGZhaWx1cmUsIDQgLyogTkFWSUdBVElPTl9BQk9SVEVEICovIHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDE2IC8qIE5BVklHQVRJT05fRFVQTElDQVRFRCAqLykgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICFpbmZvLmRlbHRhICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLnR5cGUgPT09IE5hdmlnYXRpb25UeXBlLnBvcCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVySGlzdG9yeS5nbygtMSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKG5vb3ApO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGF2b2lkIHRoZSB0aGVuIGJyYW5jaFxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gZG8gbm90IHJlc3RvcmUgaGlzdG9yeSBvbiB1bmtub3duIGRpcmVjdGlvblxyXG4gICAgICAgICAgICAgICAgaWYgKGluZm8uZGVsdGEpXHJcbiAgICAgICAgICAgICAgICAgICAgcm91dGVySGlzdG9yeS5nbygtaW5mby5kZWx0YSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgLy8gdW5yZWNvZ25pemVkIGVycm9yLCB0cmFuc2ZlciB0byB0aGUgZ2xvYmFsIGhhbmRsZXJcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cmlnZ2VyRXJyb3IoZXJyb3IsIHRvTG9jYXRpb24sIGZyb20pO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLnRoZW4oKGZhaWx1cmUpID0+IHtcclxuICAgICAgICAgICAgICAgIGZhaWx1cmUgPVxyXG4gICAgICAgICAgICAgICAgICAgIGZhaWx1cmUgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxpemVOYXZpZ2F0aW9uKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhZnRlciBuYXZpZ2F0aW9uLCBhbGwgbWF0Y2hlZCBjb21wb25lbnRzIGFyZSByZXNvbHZlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b0xvY2F0aW9uLCBmcm9tLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAvLyByZXZlcnQgdGhlIG5hdmlnYXRpb25cclxuICAgICAgICAgICAgICAgIGlmIChmYWlsdXJlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZm8uZGVsdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcm91dGVySGlzdG9yeS5nbygtaW5mby5kZWx0YSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChpbmZvLnR5cGUgPT09IE5hdmlnYXRpb25UeXBlLnBvcCAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc05hdmlnYXRpb25GYWlsdXJlKGZhaWx1cmUsIDQgLyogTkFWSUdBVElPTl9BQk9SVEVEICovIHwgMTYgLyogTkFWSUdBVElPTl9EVVBMSUNBVEVEICovKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBtYW51YWwgY2hhbmdlIGluIGhhc2ggaGlzdG9yeSAjOTE2XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0J3MgbGlrZSBhIHB1c2ggYnV0IGxhY2tzIHRoZSBpbmZvcm1hdGlvbiBvZiB0aGUgZGlyZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlckhpc3RvcnkuZ28oLTEsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0cmlnZ2VyQWZ0ZXJFYWNoKHRvTG9jYXRpb24sIGZyb20sIGZhaWx1cmUpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmNhdGNoKG5vb3ApO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgLy8gSW5pdGlhbGl6YXRpb24gYW5kIEVycm9yc1xyXG4gICAgbGV0IHJlYWR5SGFuZGxlcnMgPSB1c2VDYWxsYmFja3MoKTtcclxuICAgIGxldCBlcnJvckhhbmRsZXJzID0gdXNlQ2FsbGJhY2tzKCk7XHJcbiAgICBsZXQgcmVhZHk7XHJcbiAgICAvKipcclxuICAgICAqIFRyaWdnZXIgZXJyb3JIYW5kbGVycyBhZGRlZCB2aWEgb25FcnJvciBhbmQgdGhyb3dzIHRoZSBlcnJvciBhcyB3ZWxsXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGVycm9yIC0gZXJyb3IgdG8gdGhyb3dcclxuICAgICAqIEBwYXJhbSB0byAtIGxvY2F0aW9uIHdlIHdlcmUgbmF2aWdhdGluZyB0byB3aGVuIHRoZSBlcnJvciBoYXBwZW5lZFxyXG4gICAgICogQHBhcmFtIGZyb20gLSBsb2NhdGlvbiB3ZSB3ZXJlIG5hdmlnYXRpbmcgZnJvbSB3aGVuIHRoZSBlcnJvciBoYXBwZW5lZFxyXG4gICAgICogQHJldHVybnMgdGhlIGVycm9yIGFzIGEgcmVqZWN0ZWQgcHJvbWlzZVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiB0cmlnZ2VyRXJyb3IoZXJyb3IsIHRvLCBmcm9tKSB7XHJcbiAgICAgICAgbWFya0FzUmVhZHkoZXJyb3IpO1xyXG4gICAgICAgIGNvbnN0IGxpc3QgPSBlcnJvckhhbmRsZXJzLmxpc3QoKTtcclxuICAgICAgICBpZiAobGlzdC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgbGlzdC5mb3JFYWNoKGhhbmRsZXIgPT4gaGFuZGxlcihlcnJvciwgdG8sIGZyb20pKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oJ3VuY2F1Z2h0IGVycm9yIGR1cmluZyByb3V0ZSBuYXZpZ2F0aW9uOicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gaXNSZWFkeSgpIHtcclxuICAgICAgICBpZiAocmVhZHkgJiYgY3VycmVudFJvdXRlLnZhbHVlICE9PSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEKVxyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgcmVhZHlIYW5kbGVycy5hZGQoW3Jlc29sdmUsIHJlamVjdF0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBNYXJrIHRoZSByb3V0ZXIgYXMgcmVhZHksIHJlc29sdmluZyB0aGUgcHJvbWlzZWQgcmV0dXJuZWQgYnkgaXNSZWFkeSgpLiBDYW5cclxuICAgICAqIG9ubHkgYmUgY2FsbGVkIG9uY2UsIG90aGVyd2lzZSBkb2VzIG5vdGhpbmcuXHJcbiAgICAgKiBAcGFyYW0gZXJyIC0gb3B0aW9uYWwgZXJyb3JcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gbWFya0FzUmVhZHkoZXJyKSB7XHJcbiAgICAgICAgaWYgKHJlYWR5KVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgcmVhZHkgPSB0cnVlO1xyXG4gICAgICAgIHNldHVwTGlzdGVuZXJzKCk7XHJcbiAgICAgICAgcmVhZHlIYW5kbGVyc1xyXG4gICAgICAgICAgICAubGlzdCgpXHJcbiAgICAgICAgICAgIC5mb3JFYWNoKChbcmVzb2x2ZSwgcmVqZWN0XSkgPT4gKGVyciA/IHJlamVjdChlcnIpIDogcmVzb2x2ZSgpKSk7XHJcbiAgICAgICAgcmVhZHlIYW5kbGVycy5yZXNldCgpO1xyXG4gICAgfVxyXG4gICAgLy8gU2Nyb2xsIGJlaGF2aW9yXHJcbiAgICBmdW5jdGlvbiBoYW5kbGVTY3JvbGwodG8sIGZyb20sIGlzUHVzaCwgaXNGaXJzdE5hdmlnYXRpb24pIHtcclxuICAgICAgICBjb25zdCB7IHNjcm9sbEJlaGF2aW9yIH0gPSBvcHRpb25zO1xyXG4gICAgICAgIGlmICghaXNCcm93c2VyIHx8ICFzY3JvbGxCZWhhdmlvcilcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIGNvbnN0IHNjcm9sbFBvc2l0aW9uID0gKCFpc1B1c2ggJiYgZ2V0U2F2ZWRTY3JvbGxQb3NpdGlvbihnZXRTY3JvbGxLZXkodG8uZnVsbFBhdGgsIDApKSkgfHxcclxuICAgICAgICAgICAgKChpc0ZpcnN0TmF2aWdhdGlvbiB8fCAhaXNQdXNoKSAmJlxyXG4gICAgICAgICAgICAgICAgaGlzdG9yeS5zdGF0ZSAmJlxyXG4gICAgICAgICAgICAgICAgaGlzdG9yeS5zdGF0ZS5zY3JvbGwpIHx8XHJcbiAgICAgICAgICAgIG51bGw7XHJcbiAgICAgICAgcmV0dXJuIG5leHRUaWNrKClcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gc2Nyb2xsQmVoYXZpb3IodG8sIGZyb20sIHNjcm9sbFBvc2l0aW9uKSlcclxuICAgICAgICAgICAgLnRoZW4ocG9zaXRpb24gPT4gcG9zaXRpb24gJiYgc2Nyb2xsVG9Qb3NpdGlvbihwb3NpdGlvbikpXHJcbiAgICAgICAgICAgIC5jYXRjaChlcnIgPT4gdHJpZ2dlckVycm9yKGVyciwgdG8sIGZyb20pKTtcclxuICAgIH1cclxuICAgIGNvbnN0IGdvID0gKGRlbHRhKSA9PiByb3V0ZXJIaXN0b3J5LmdvKGRlbHRhKTtcclxuICAgIGxldCBzdGFydGVkO1xyXG4gICAgY29uc3QgaW5zdGFsbGVkQXBwcyA9IG5ldyBTZXQoKTtcclxuICAgIGNvbnN0IHJvdXRlciA9IHtcclxuICAgICAgICBjdXJyZW50Um91dGUsXHJcbiAgICAgICAgYWRkUm91dGUsXHJcbiAgICAgICAgcmVtb3ZlUm91dGUsXHJcbiAgICAgICAgaGFzUm91dGUsXHJcbiAgICAgICAgZ2V0Um91dGVzLFxyXG4gICAgICAgIHJlc29sdmUsXHJcbiAgICAgICAgb3B0aW9ucyxcclxuICAgICAgICBwdXNoLFxyXG4gICAgICAgIHJlcGxhY2UsXHJcbiAgICAgICAgZ28sXHJcbiAgICAgICAgYmFjazogKCkgPT4gZ28oLTEpLFxyXG4gICAgICAgIGZvcndhcmQ6ICgpID0+IGdvKDEpLFxyXG4gICAgICAgIGJlZm9yZUVhY2g6IGJlZm9yZUd1YXJkcy5hZGQsXHJcbiAgICAgICAgYmVmb3JlUmVzb2x2ZTogYmVmb3JlUmVzb2x2ZUd1YXJkcy5hZGQsXHJcbiAgICAgICAgYWZ0ZXJFYWNoOiBhZnRlckd1YXJkcy5hZGQsXHJcbiAgICAgICAgb25FcnJvcjogZXJyb3JIYW5kbGVycy5hZGQsXHJcbiAgICAgICAgaXNSZWFkeSxcclxuICAgICAgICBpbnN0YWxsKGFwcCkge1xyXG4gICAgICAgICAgICBjb25zdCByb3V0ZXIgPSB0aGlzO1xyXG4gICAgICAgICAgICBhcHAuY29tcG9uZW50KCdSb3V0ZXJMaW5rJywgUm91dGVyTGluayk7XHJcbiAgICAgICAgICAgIGFwcC5jb21wb25lbnQoJ1JvdXRlclZpZXcnLCBSb3V0ZXJWaWV3KTtcclxuICAgICAgICAgICAgYXBwLmNvbmZpZy5nbG9iYWxQcm9wZXJ0aWVzLiRyb3V0ZXIgPSByb3V0ZXI7XHJcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcHAuY29uZmlnLmdsb2JhbFByb3BlcnRpZXMsICckcm91dGUnLCB7XHJcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiB1bnJlZihjdXJyZW50Um91dGUpLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgLy8gdGhpcyBpbml0aWFsIG5hdmlnYXRpb24gaXMgb25seSBuZWNlc3Nhcnkgb24gY2xpZW50LCBvbiBzZXJ2ZXIgaXQgZG9lc24ndFxyXG4gICAgICAgICAgICAvLyBtYWtlIHNlbnNlIGJlY2F1c2UgaXQgd2lsbCBjcmVhdGUgYW4gZXh0cmEgdW5uZWNlc3NhcnkgbmF2aWdhdGlvbiBhbmQgY291bGRcclxuICAgICAgICAgICAgLy8gbGVhZCB0byBwcm9ibGVtc1xyXG4gICAgICAgICAgICBpZiAoaXNCcm93c2VyICYmXHJcbiAgICAgICAgICAgICAgICAvLyB1c2VkIGZvciB0aGUgaW5pdGlhbCBuYXZpZ2F0aW9uIGNsaWVudCBzaWRlIHRvIGF2b2lkIHB1c2hpbmdcclxuICAgICAgICAgICAgICAgIC8vIG11bHRpcGxlIHRpbWVzIHdoZW4gdGhlIHJvdXRlciBpcyB1c2VkIGluIG11bHRpcGxlIGFwcHNcclxuICAgICAgICAgICAgICAgICFzdGFydGVkICYmXHJcbiAgICAgICAgICAgICAgICBjdXJyZW50Um91dGUudmFsdWUgPT09IFNUQVJUX0xPQ0FUSU9OX05PUk1BTElaRUQpIHtcclxuICAgICAgICAgICAgICAgIC8vIHNlZSBhYm92ZVxyXG4gICAgICAgICAgICAgICAgc3RhcnRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBwdXNoKHJvdXRlckhpc3RvcnkubG9jYXRpb24pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2FybignVW5leHBlY3RlZCBlcnJvciB3aGVuIHN0YXJ0aW5nIHRoZSByb3V0ZXI6JywgZXJyKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IHJlYWN0aXZlUm91dGUgPSB7fTtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gU1RBUlRfTE9DQVRJT05fTk9STUFMSVpFRCkge1xyXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvcjogdGhlIGtleSBtYXRjaGVzXHJcbiAgICAgICAgICAgICAgICByZWFjdGl2ZVJvdXRlW2tleV0gPSBjb21wdXRlZCgoKSA9PiBjdXJyZW50Um91dGUudmFsdWVba2V5XSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYXBwLnByb3ZpZGUocm91dGVyS2V5LCByb3V0ZXIpO1xyXG4gICAgICAgICAgICBhcHAucHJvdmlkZShyb3V0ZUxvY2F0aW9uS2V5LCByZWFjdGl2ZShyZWFjdGl2ZVJvdXRlKSk7XHJcbiAgICAgICAgICAgIGFwcC5wcm92aWRlKHJvdXRlclZpZXdMb2NhdGlvbktleSwgY3VycmVudFJvdXRlKTtcclxuICAgICAgICAgICAgY29uc3QgdW5tb3VudEFwcCA9IGFwcC51bm1vdW50O1xyXG4gICAgICAgICAgICBpbnN0YWxsZWRBcHBzLmFkZChhcHApO1xyXG4gICAgICAgICAgICBhcHAudW5tb3VudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGluc3RhbGxlZEFwcHMuZGVsZXRlKGFwcCk7XHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgcm91dGVyIGlzIG5vdCBhdHRhY2hlZCB0byBhbiBhcHAgYW55bW9yZVxyXG4gICAgICAgICAgICAgICAgaWYgKGluc3RhbGxlZEFwcHMuc2l6ZSA8IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBpbnZhbGlkYXRlIHRoZSBjdXJyZW50IG5hdmlnYXRpb25cclxuICAgICAgICAgICAgICAgICAgICBwZW5kaW5nTG9jYXRpb24gPSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZUhpc3RvcnlMaXN0ZW5lciAmJiByZW1vdmVIaXN0b3J5TGlzdGVuZXIoKTtcclxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50Um91dGUudmFsdWUgPSBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEO1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICByZWFkeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdW5tb3VudEFwcCgpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBpZiAoKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB8fCBfX1ZVRV9QUk9EX0RFVlRPT0xTX18pICYmIGlzQnJvd3Nlcikge1xyXG4gICAgICAgICAgICAgICAgYWRkRGV2dG9vbHMoYXBwLCByb3V0ZXIsIG1hdGNoZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgIH07XHJcbiAgICByZXR1cm4gcm91dGVyO1xyXG59XHJcbmZ1bmN0aW9uIHJ1bkd1YXJkUXVldWUoZ3VhcmRzKSB7XHJcbiAgICByZXR1cm4gZ3VhcmRzLnJlZHVjZSgocHJvbWlzZSwgZ3VhcmQpID0+IHByb21pc2UudGhlbigoKSA9PiBndWFyZCgpKSwgUHJvbWlzZS5yZXNvbHZlKCkpO1xyXG59XHJcbmZ1bmN0aW9uIGV4dHJhY3RDaGFuZ2luZ1JlY29yZHModG8sIGZyb20pIHtcclxuICAgIGNvbnN0IGxlYXZpbmdSZWNvcmRzID0gW107XHJcbiAgICBjb25zdCB1cGRhdGluZ1JlY29yZHMgPSBbXTtcclxuICAgIGNvbnN0IGVudGVyaW5nUmVjb3JkcyA9IFtdO1xyXG4gICAgY29uc3QgbGVuID0gTWF0aC5tYXgoZnJvbS5tYXRjaGVkLmxlbmd0aCwgdG8ubWF0Y2hlZC5sZW5ndGgpO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgIGNvbnN0IHJlY29yZEZyb20gPSBmcm9tLm1hdGNoZWRbaV07XHJcbiAgICAgICAgaWYgKHJlY29yZEZyb20pIHtcclxuICAgICAgICAgICAgaWYgKHRvLm1hdGNoZWQuZmluZChyZWNvcmQgPT4gaXNTYW1lUm91dGVSZWNvcmQocmVjb3JkLCByZWNvcmRGcm9tKSkpXHJcbiAgICAgICAgICAgICAgICB1cGRhdGluZ1JlY29yZHMucHVzaChyZWNvcmRGcm9tKTtcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgbGVhdmluZ1JlY29yZHMucHVzaChyZWNvcmRGcm9tKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcmVjb3JkVG8gPSB0by5tYXRjaGVkW2ldO1xyXG4gICAgICAgIGlmIChyZWNvcmRUbykge1xyXG4gICAgICAgICAgICAvLyB0aGUgdHlwZSBkb2Vzbid0IG1hdHRlciBiZWNhdXNlIHdlIGFyZSBjb21wYXJpbmcgcGVyIHJlZmVyZW5jZVxyXG4gICAgICAgICAgICBpZiAoIWZyb20ubWF0Y2hlZC5maW5kKHJlY29yZCA9PiBpc1NhbWVSb3V0ZVJlY29yZChyZWNvcmQsIHJlY29yZFRvKSkpIHtcclxuICAgICAgICAgICAgICAgIGVudGVyaW5nUmVjb3Jkcy5wdXNoKHJlY29yZFRvKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBbbGVhdmluZ1JlY29yZHMsIHVwZGF0aW5nUmVjb3JkcywgZW50ZXJpbmdSZWNvcmRzXTtcclxufVxuXG4vKipcclxuICogUmV0dXJucyB0aGUgcm91dGVyIGluc3RhbmNlLiBFcXVpdmFsZW50IHRvIHVzaW5nIGAkcm91dGVyYCBpbnNpZGVcclxuICogdGVtcGxhdGVzLlxyXG4gKi9cclxuZnVuY3Rpb24gdXNlUm91dGVyKCkge1xyXG4gICAgcmV0dXJuIGluamVjdChyb3V0ZXJLZXkpO1xyXG59XHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBjdXJyZW50IHJvdXRlIGxvY2F0aW9uLiBFcXVpdmFsZW50IHRvIHVzaW5nIGAkcm91dGVgIGluc2lkZVxyXG4gKiB0ZW1wbGF0ZXMuXHJcbiAqL1xyXG5mdW5jdGlvbiB1c2VSb3V0ZSgpIHtcclxuICAgIHJldHVybiBpbmplY3Qocm91dGVMb2NhdGlvbktleSk7XHJcbn1cblxuZXhwb3J0IHsgTmF2aWdhdGlvbkZhaWx1cmVUeXBlLCBSb3V0ZXJMaW5rLCBSb3V0ZXJWaWV3LCBTVEFSVF9MT0NBVElPTl9OT1JNQUxJWkVEIGFzIFNUQVJUX0xPQ0FUSU9OLCBjcmVhdGVNZW1vcnlIaXN0b3J5LCBjcmVhdGVSb3V0ZXIsIGNyZWF0ZVJvdXRlck1hdGNoZXIsIGNyZWF0ZVdlYkhhc2hIaXN0b3J5LCBjcmVhdGVXZWJIaXN0b3J5LCBpc05hdmlnYXRpb25GYWlsdXJlLCBtYXRjaGVkUm91dGVLZXksIG9uQmVmb3JlUm91dGVMZWF2ZSwgb25CZWZvcmVSb3V0ZVVwZGF0ZSwgcGFyc2VRdWVyeSwgcm91dGVMb2NhdGlvbktleSwgcm91dGVyS2V5LCByb3V0ZXJWaWV3TG9jYXRpb25LZXksIHN0cmluZ2lmeVF1ZXJ5LCB1c2VMaW5rLCB1c2VSb3V0ZSwgdXNlUm91dGVyLCB2aWV3RGVwdGhLZXkgfTtcbiIsIjx0ZW1wbGF0ZT5cbiAgICA8ZGl2IGlkPVwiY29udGVudENvbnRhaW5lclwiIGNsYXNzPVwiY29udGVudC1jb250YWluZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImxvYWRpbmctdmlld1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInByb2dyZXNzLWJhci1kaXZcIj5cbiAgICAgICAgICAgICAgICA8cHJvZ3Jlc3MgY2xhc3M9XCJwcm9ncmVzcy1iYXJcIiBtYXg9XCIxMDBcIiB2YWx1ZT1cIjEwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzdHJvbmc+UHJvZ3Jlc3M6IDEwMCUgQ29tcGxldGUuPC9zdHJvbmc+XG4gICAgICAgICAgICAgICAgPC9wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInByb2dyZXNzLWxhYmVsXCI+SW5pdGlhbGl6aW5nLi4uPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIG5hbWU6IFwiTGVnYWN5Vmlld1wiLFxuICAgIGNvbXBvbmVudHM6IHt9XG59O1xuPC9zY3JpcHQ+XG5cbjxzdHlsZT5cbjwvc3R5bGU+IiwiZXhwb3J0ICogZnJvbSBcIi0hLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvZGlzdC90ZW1wbGF0ZUxvYWRlci5qcz8/cnVsZVNldFsxXS5ydWxlc1sxXSEuLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9kaXN0L2luZGV4LmpzPz9ydWxlU2V0WzFdLnJ1bGVzWzZdLnVzZVswXSEuL0xlZ2FjeVZpZXcudnVlP3Z1ZSZ0eXBlPXRlbXBsYXRlJmlkPTM3NGJhNGE4XCIiLCJleHBvcnQgeyBkZWZhdWx0IH0gZnJvbSBcIi0hLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvZGlzdC9pbmRleC5qcz8/cnVsZVNldFsxXS5ydWxlc1s2XS51c2VbMF0hLi9MZWdhY3lWaWV3LnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qc1wiOyBleHBvcnQgKiBmcm9tIFwiLSEuLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9kaXN0L2luZGV4LmpzPz9ydWxlU2V0WzFdLnJ1bGVzWzZdLnVzZVswXSEuL0xlZ2FjeVZpZXcudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzXCIiLCJpbXBvcnQgeyByZW5kZXIgfSBmcm9tIFwiLi9MZWdhY3lWaWV3LnZ1ZT92dWUmdHlwZT10ZW1wbGF0ZSZpZD0zNzRiYTRhOFwiXG5pbXBvcnQgc2NyaXB0IGZyb20gXCIuL0xlZ2FjeVZpZXcudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzXCJcbmV4cG9ydCAqIGZyb20gXCIuL0xlZ2FjeVZpZXcudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzXCJcblxuaW1wb3J0IGV4cG9ydENvbXBvbmVudCBmcm9tIFwiL2hvbWUvbWlrZWIvdGltZXRyZXgvdHJ1bmsvbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvZGlzdC9leHBvcnRIZWxwZXIuanNcIlxuY29uc3QgX19leHBvcnRzX18gPSAvKiNfX1BVUkVfXyovZXhwb3J0Q29tcG9uZW50KHNjcmlwdCwgW1sncmVuZGVyJyxyZW5kZXJdXSlcblxuZXhwb3J0IGRlZmF1bHQgX19leHBvcnRzX18iLCIvLyBpbXBvcnQgeyBjcmVhdGVSb3V0ZXIsIGNyZWF0ZVdlYkhpc3RvcnkgfSBmcm9tICd2dWUtcm91dGVyJ1xuaW1wb3J0IHsgY3JlYXRlUm91dGVyLCBjcmVhdGVNZW1vcnlIaXN0b3J5IH0gZnJvbSAndnVlLXJvdXRlcidcblxuaW1wb3J0IExlZ2FjeVZpZXcgZnJvbSAnQC9jb21wb25lbnRzL0xlZ2FjeVZpZXcnO1xuLy8gaW1wb3J0IFJlcG9ydFZpZXcgZnJvbSAnQC9jb21wb25lbnRzL1JlcG9ydFZpZXcnO1xuXG5jb25zdCBsYXp5X2xvYWRfdGVzdCA9ICgpID0+IGltcG9ydCgvKiB3ZWJwYWNrQ2h1bmtOYW1lOiBcImR5bmFtaWMtdGVzdHZpZXdcIiAqLydAL2NvbXBvbmVudHMvVFRUZXN0VmlldycpOyAvLyAjVlVFVEVTVFxuXG4vLyBDYW4gYWxzbyBpbXBvcnQgdGhpcyBmcm9tIGFub3RoZXIgZmlsZS5cbmNvbnN0IHJvdXRlcyA9IFtcblx0eyBwYXRoOiAnL3Rlc3QnLCBuYW1lOiAndGVzdCcsIGNvbXBvbmVudDogbGF6eV9sb2FkX3Rlc3QsIHByb3BzOnRydWUgfSwgLy8gI1ZVRVRFU1QgTGF6eSBsb2FkZWQsIHNvIG5vdCBsb2FkZWQgbm9ybWFsbHkuIE9ubHkgd2hlbiB1c2VkIHdpdGggYFZ1ZVJvdXRlci5wdXNoKCd0ZXN0JylgIG9yIHZpYSBkZXYgdG9vbHMuXG5cdC8vIHsgcGF0aDogJy92aWV3Lzp2aWV3SWQnLCBuYW1lOiAndmlldycsIGNvbXBvbmVudDogTGVnYWN5VmlldywgcHJvcHM6dHJ1ZSB9LFxuXHQvLyB7IHBhdGg6ICcvcmVwb3J0Lzp2aWV3SWQnLCBuYW1lOiAncmVwb3J0JywgY29tcG9uZW50OiBSZXBvcnRWaWV3LCBwcm9wczp0cnVlIH0sXG5cdC8vIHsgcGF0aDogJy9yZXBvcnQvOnJlcG9ydElkJywgbmFtZTogJ3JlcG9ydCcsIGNvbXBvbmVudDogTGVnYWN5VmlldyB9LFxuXHQvLyB7IHBhdGg6ICcvd2l6YXJkLzp3aXphcmRJZCcsIG5hbWU6ICd3aXphcmQnLCBjb21wb25lbnQ6IExlZ2FjeVZpZXcgfSxcblx0eyBwYXRoOiAnLzpwYXRoTWF0Y2goLiopKicsIG5hbWU6ICdjYXRjaC1hbGwnLCBjb21wb25lbnQ6IExlZ2FjeVZpZXcgfSxcblx0Ly8geyBwYXRoOiAnLyMhbT1Mb2dpbicsIG5hbWU6ICdub3QtZm91bmQnLCBjb21wb25lbnQ6IExlZ2FjeVZpZXcgfSxcblx0Ly8geyBwYXRoOiAnLyMhbT06dmlld0lkJio6cmVzdE9mKC4qKScsIG5hbWU6ICdub3QtZm91bmQnLCBjb21wb25lbnQ6IExlZ2FjeVZpZXcgfSxcblxuXTtcblxuY29uc3QgbWFpbl91aV9yb3V0ZXIgPSBjcmVhdGVSb3V0ZXIoe1xuXHQvLyBoaXN0b3J5OiBjcmVhdGVXZWJIaXN0b3J5KCksXG5cdGhpc3Rvcnk6IGNyZWF0ZU1lbW9yeUhpc3RvcnkoKSxcblx0cm91dGVzLFxufSk7XG5cbmV4cG9ydCBkZWZhdWx0IG1haW5fdWlfcm91dGVyO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2237\n")},6378:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/* provided dependency */ var jQuery = __webpack_require__(9755);\n/*!\n * jQuery i18n plugin\n * @requires jQuery v1.1 or later\n *\n * See https://github.com/recurser/jquery-i18n\n *\n * Licensed under the MIT license.\n *\n * Version: <%= pkg.version %> (<%= meta.date %>)\n */\n(function($) {\n\t/**\n\t * i18n provides a mechanism for translating strings using a jscript dictionary.\n\t *\n\t */\n\n\tvar __slice = Array.prototype.slice;\n\n\t/*\n\t * i18n property list\n\t */\n\tvar i18n = {\n\n\t\tdict: null,\n\t\tmissingPattern: null,\n\n\t\t/**\n\t\t * load()\n\t\t *\n\t\t * Load translations.\n\t\t *\n\t\t * @param property_list i18nDict : The dictionary to use for translation.\n\t\t */\n\t\tload: function(i18nDict, missingPattern) {\n\t\t\tif (this.dict !== null) {\n\t\t\t\t$.extend(this.dict, i18nDict);\n\t\t\t} else {\n\t\t\t\tthis.dict = i18nDict;\n\t\t\t}\n\n\t\t\tif (missingPattern) {\n\t\t\t\tthis.missingPattern = missingPattern;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * unload()\n\t\t *\n\t\t * Unloads translations and clears the dictionary.\n\t\t */\n\t\tunload: function() {\n\t\t\tthis.dict = null;\n\t\t\tthis.missingPattern = null;\n\t\t},\n\n\t\t/**\n\t\t * _()\n\t\t *\n\t\t * Looks the given string up in the dictionary and returns the translation if\n\t\t * one exists. If a translation is not found, returns the original word.\n\t\t *\n\t\t * @param string str : The string to translate.\n\t\t * @param property_list params.. : params for using printf() on the string.\n\t\t *\n\t\t * @return string : Translated word.\n\t\t */\n\t\t_: function (str) {\n\t\t\tdict = this.dict;\n\t\t\tif (dict && dict.hasOwnProperty(str)) {\n\t\t\t\tstr = dict[str];\n\t\t\t} else if (this.missingPattern !== null) {\n\t\t\t\treturn this.printf(this.missingPattern, str);\n\t\t\t}\n\t\t\tvar args = __slice.call(arguments);\n\t\t\targs[0] = str;\n\t\t\t// Substitute any params.\n\t\t\treturn this.printf.apply(this, args);\n\t\t},\n\n\t\t/*\n\t\t * printf()\n\t\t *\n\t\t * Substitutes %s with parameters given in list. %%s is used to escape %s.\n\t\t *\n\t\t * @param string str : String to perform printf on.\n\t\t * @param string args : Array of arguments for printf.\n\t\t *\n\t\t * @return string result : Substituted string\n\t\t */\n\t\tprintf: function(str, args) {\n\t\t\tif (arguments.length < 2) return str;\n\t\t\tvar args = $.isArray(args) ? args : __slice.call(arguments, 1);\n\t\t\treturn str.replace(/([^%]|^)%(?:(\\d+)\\$)?s/g, function(p0, p, position) {\n\t\t\t\tif (position) {\n\t\t\t\t\treturn p + args[parseInt(position)-1];\n\t\t\t\t}\n\t\t\t\treturn p + args.shift();\n\t\t\t}).replace(/%%s/g, '%s');\n\t\t}\n\n\t};\n\n\t/*\n\t * _t()\n\t *\n\t * Allows you to translate a jQuery selector.\n\t *\n\t * eg $('h1')._t('some text')\n\t *\n\t * @param string str : The string to translate .\n\t * @param property_list params : Params for using printf() on the string.\n\t *\n\t * @return element : Chained and translated element(s).\n\t*/\n\t$.fn._t = function(str, params) {\n\t\treturn $(this).html(i18n._.apply(i18n, arguments));\n\t};\n\n\t$.i18n = i18n;\n})(jQuery);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjM3OC5qcyIsIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDLEVBQUUsTUFBTSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9mcmFtZXdvcmsvanF1ZXJ5LmkxOG4uanM/OTAzNiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIGpRdWVyeSBpMThuIHBsdWdpblxuICogQHJlcXVpcmVzIGpRdWVyeSB2MS4xIG9yIGxhdGVyXG4gKlxuICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9yZWN1cnNlci9qcXVlcnktaTE4blxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbiAqXG4gKiBWZXJzaW9uOiA8JT0gcGtnLnZlcnNpb24gJT4gKDwlPSBtZXRhLmRhdGUgJT4pXG4gKi9cbihmdW5jdGlvbigkKSB7XG5cdC8qKlxuXHQgKiBpMThuIHByb3ZpZGVzIGEgbWVjaGFuaXNtIGZvciB0cmFuc2xhdGluZyBzdHJpbmdzIHVzaW5nIGEganNjcmlwdCBkaWN0aW9uYXJ5LlxuXHQgKlxuXHQgKi9cblxuXHR2YXIgX19zbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcblxuXHQvKlxuXHQgKiBpMThuIHByb3BlcnR5IGxpc3Rcblx0ICovXG5cdHZhciBpMThuID0ge1xuXG5cdFx0ZGljdDogbnVsbCxcblx0XHRtaXNzaW5nUGF0dGVybjogbnVsbCxcblxuXHRcdC8qKlxuXHRcdCAqIGxvYWQoKVxuXHRcdCAqXG5cdFx0ICogTG9hZCB0cmFuc2xhdGlvbnMuXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0gIHByb3BlcnR5X2xpc3QgaTE4bkRpY3QgOiBUaGUgZGljdGlvbmFyeSB0byB1c2UgZm9yIHRyYW5zbGF0aW9uLlxuXHRcdCAqL1xuXHRcdGxvYWQ6IGZ1bmN0aW9uKGkxOG5EaWN0LCBtaXNzaW5nUGF0dGVybikge1xuXHRcdFx0aWYgKHRoaXMuZGljdCAhPT0gbnVsbCkge1xuXHRcdFx0XHQkLmV4dGVuZCh0aGlzLmRpY3QsIGkxOG5EaWN0KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuZGljdCA9IGkxOG5EaWN0O1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAobWlzc2luZ1BhdHRlcm4pIHtcblx0XHRcdFx0dGhpcy5taXNzaW5nUGF0dGVybiA9IG1pc3NpbmdQYXR0ZXJuO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiB1bmxvYWQoKVxuXHRcdCAqXG5cdFx0ICogVW5sb2FkcyB0cmFuc2xhdGlvbnMgYW5kIGNsZWFycyB0aGUgZGljdGlvbmFyeS5cblx0XHQgKi9cblx0XHR1bmxvYWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dGhpcy5kaWN0ICAgICAgICAgICA9IG51bGw7XG5cdFx0XHR0aGlzLm1pc3NpbmdQYXR0ZXJuID0gbnVsbDtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogXygpXG5cdFx0ICpcblx0XHQgKiBMb29rcyB0aGUgZ2l2ZW4gc3RyaW5nIHVwIGluIHRoZSBkaWN0aW9uYXJ5IGFuZCByZXR1cm5zIHRoZSB0cmFuc2xhdGlvbiBpZlxuXHRcdCAqIG9uZSBleGlzdHMuIElmIGEgdHJhbnNsYXRpb24gaXMgbm90IGZvdW5kLCByZXR1cm5zIHRoZSBvcmlnaW5hbCB3b3JkLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtICBzdHJpbmcgc3RyICAgICAgICAgICA6IFRoZSBzdHJpbmcgdG8gdHJhbnNsYXRlLlxuXHRcdCAqIEBwYXJhbSAgcHJvcGVydHlfbGlzdCBwYXJhbXMuLiA6IHBhcmFtcyBmb3IgdXNpbmcgcHJpbnRmKCkgb24gdGhlIHN0cmluZy5cblx0XHQgKlxuXHRcdCAqIEByZXR1cm4gc3RyaW5nICAgICAgICAgICAgICAgOiBUcmFuc2xhdGVkIHdvcmQuXG5cdFx0ICovXG5cdFx0XzogZnVuY3Rpb24gKHN0cikge1xuXHRcdFx0ZGljdCA9IHRoaXMuZGljdDtcblx0XHRcdGlmIChkaWN0ICYmIGRpY3QuaGFzT3duUHJvcGVydHkoc3RyKSkge1xuXHRcdFx0XHRzdHIgPSBkaWN0W3N0cl07XG5cdFx0XHR9IGVsc2UgaWYgKHRoaXMubWlzc2luZ1BhdHRlcm4gIT09IG51bGwpIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMucHJpbnRmKHRoaXMubWlzc2luZ1BhdHRlcm4sIHN0cik7XG5cdFx0XHR9XG5cdFx0XHR2YXIgYXJncyA9IF9fc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXHRcdFx0YXJnc1swXSA9IHN0cjtcblx0XHRcdC8vIFN1YnN0aXR1dGUgYW55IHBhcmFtcy5cblx0XHRcdHJldHVybiB0aGlzLnByaW50Zi5hcHBseSh0aGlzLCBhcmdzKTtcblx0XHR9LFxuXG5cdFx0Lypcblx0XHQgKiBwcmludGYoKVxuXHRcdCAqXG5cdFx0ICogU3Vic3RpdHV0ZXMgJXMgd2l0aCBwYXJhbWV0ZXJzIGdpdmVuIGluIGxpc3QuICUlcyBpcyB1c2VkIHRvIGVzY2FwZSAlcy5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSAgc3RyaW5nIHN0ciAgICA6IFN0cmluZyB0byBwZXJmb3JtIHByaW50ZiBvbi5cblx0XHQgKiBAcGFyYW0gIHN0cmluZyBhcmdzICAgOiBBcnJheSBvZiBhcmd1bWVudHMgZm9yIHByaW50Zi5cblx0XHQgKlxuXHRcdCAqIEByZXR1cm4gc3RyaW5nIHJlc3VsdCA6IFN1YnN0aXR1dGVkIHN0cmluZ1xuXHRcdCAqL1xuXHRcdHByaW50ZjogZnVuY3Rpb24oc3RyLCBhcmdzKSB7XG5cdFx0XHRpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHJldHVybiBzdHI7XG5cdFx0XHR2YXIgYXJncyA9ICQuaXNBcnJheShhcmdzKSA/IGFyZ3MgOiBfX3NsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblx0XHRcdHJldHVybiBzdHIucmVwbGFjZSgvKFteJV18XiklKD86KFxcZCspXFwkKT9zL2csIGZ1bmN0aW9uKHAwLCBwLCBwb3NpdGlvbikge1xuXHRcdFx0XHRpZiAocG9zaXRpb24pIHtcblx0XHRcdFx0XHRyZXR1cm4gcCArIGFyZ3NbcGFyc2VJbnQocG9zaXRpb24pLTFdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBwICsgYXJncy5zaGlmdCgpO1xuXHRcdFx0fSkucmVwbGFjZSgvJSVzL2csICclcycpO1xuXHRcdH1cblxuXHR9O1xuXG5cdC8qXG5cdCAqIF90KClcblx0ICpcblx0ICogQWxsb3dzIHlvdSB0byB0cmFuc2xhdGUgYSBqUXVlcnkgc2VsZWN0b3IuXG5cdCAqXG5cdCAqIGVnICQoJ2gxJykuX3QoJ3NvbWUgdGV4dCcpXG5cdCAqXG5cdCAqIEBwYXJhbSAgc3RyaW5nIHN0ciAgICAgICAgICAgOiBUaGUgc3RyaW5nIHRvIHRyYW5zbGF0ZSAuXG5cdCAqIEBwYXJhbSAgcHJvcGVydHlfbGlzdCBwYXJhbXMgOiBQYXJhbXMgZm9yIHVzaW5nIHByaW50ZigpIG9uIHRoZSBzdHJpbmcuXG5cdCAqXG5cdCAqIEByZXR1cm4gZWxlbWVudCAgICAgICAgICAgICAgOiBDaGFpbmVkIGFuZCB0cmFuc2xhdGVkIGVsZW1lbnQocykuXG5cdCovXG5cdCQuZm4uX3QgPSBmdW5jdGlvbihzdHIsIHBhcmFtcykge1xuXHRcdHJldHVybiAkKHRoaXMpLmh0bWwoaTE4bi5fLmFwcGx5KGkxOG4sIGFyZ3VtZW50cykpO1xuXHR9O1xuXG5cdCQuaTE4biA9IGkxOG47XG59KShqUXVlcnkpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6378\n")},9490:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"x\": () => (/* binding */ Global)\n/* harmony export */ });\n/* harmony import */ var _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4936);\n/* harmony import */ var _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7526);\n/* harmony import */ var _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2548);\n/* harmony import */ var _global_RateLimit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7046);\n/* harmony import */ var _global_widgets_view_min_tab_ViewMinTabBar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8287);\n/* harmony import */ var _global_widgets_view_min_tab_ViewMinTabBar__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_global_widgets_view_min_tab_ViewMinTabBar__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(12);\n/* harmony import */ var _services_TTEventBus__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7967);\n/* harmony import */ var _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(4578);\n/* harmony import */ var _services_TTVueUtils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(4966);\n/* harmony import */ var _components_login_TTMultiFactorAuthentication__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(7024);\n/* provided dependency */ var $ = __webpack_require__(9755);\n/* provided dependency */ var _ = __webpack_require__(9050);\n/* provided dependency */ var jQuery = __webpack_require__(9755);\n// import { LocalCacheData } from 'exports-loader?exports=LocalCacheData!@/global/LocalCacheData';\n\n\n // TODO: duplicated in merged js files.\n\n\n\n\n\n\n\n// import { createApp } from 'vue'; // Currently only used by Global.initEditTest\n// import TTEditView from '@/components/TTEditView'; // Used by Global.initEditTest which is currently commented out as its for testing only.\n\n//Global variables and functions will be used everywhere\nvar Global = function() {\n};\nGlobal.event_bus = new _services_TTEventBus__WEBPACK_IMPORTED_MODULE_6__/* [\"default\"] */ .Z({ view_id: 'global' });\nGlobal.sortOrderRegex = /^-([0-9]{3,9})-/;\nGlobal.current_ping = -1;\n\nGlobal.UNIT_TEST_MODE = false;\n\nGlobal.app_min_width = 990;\n\nGlobal.theme = 'default';\n\n/**\n * UIReadyStatus:\n * 0 - Global.setUINotready() - the UI is not ready\n * 1 - Global.setUIReady() - the overlay is out of the way but ui is not done rendering\n * 2 - Global.setUIInitComplete() the overlay is done rendering\n */\nGlobal.UIReadyStatus = 0;\n\nGlobal.signal_timer = null;\n\nGlobal.isScrolledIntoView = function( elem ) {\n\tvar $elem = elem;\n\tvar $window = $( window );\n\tvar docViewTop = $window.scrollTop();\n\tvar docViewBottom = docViewTop + $window.height();\n\tif ( !$elem.offset() ) {\n\t\treturn true;\n\t}\n\tvar elemTop = $elem.offset().top;\n\t//var elemBottom = elemTop + $elem.height();\n\t//((elemBottom <= (docViewBottom + 200)) && (elemTop >= docViewTop));\n\treturn elemTop < docViewBottom;\n};\n\n//Check if the DOM (not jQuery) element requires a vertical scrollbar.\nGlobal.isVerticalScrollBarRequired = function( element ) {\n\treturn element && element.scrollHeight > element.clientHeight;\n};\n\n//Check if the DOM (not jQuery) element requires a horizontal scrollbar.\nGlobal.isHorizontalScrollBarRequired = function( element ) {\n\treturn element && element.scrollWidth > element.clientWidth;\n};\n\n//Gets the width of the browsers scrollbar. This value depends on the users OS/browser.\nGlobal.getScrollbarWidth = function() {\n\tif ( LocalCacheData.getScrollbarWidth() > 0 ) {\n return LocalCacheData.getScrollbarWidth();\n }\n\n\tlet scroll_div = document.createElement(\"div\");\n\tscroll_div.style.visibility = 'hidden';\n\tscroll_div.style.overflow = 'scroll';\n\tdocument.body.appendChild(scroll_div);\n\tlet scroll_bar_width = scroll_div.offsetWidth - scroll_div.clientWidth;\n\tdocument.body.removeChild(scroll_div);\n\n\t//If for some reason we cannot get the width, default the width to 17 which is most common value. (Windows\n\tif ( !scroll_bar_width ) {\n scroll_bar_width = 17;\n }\n\n\tLocalCacheData.setScrollBarWidth( scroll_bar_width );\n\n\treturn scroll_bar_width;\n}\n\n//Gets the height of the browsers scrollbar. This value depends on the users OS/browser.\nGlobal.getScrollbarHeight = function() {\n\tif ( LocalCacheData.getScrollbarHeight() > 0 ) {\n\t\treturn LocalCacheData.getScrollbarHeight();\n\t}\n\n\tlet scroll_div = document.createElement(\"div\");\n\tscroll_div.style.visibility = 'hidden';\n\tscroll_div.style.overflow = 'scroll';\n\tdocument.body.appendChild(scroll_div);\n\tlet scroll_bar_height = scroll_div.offsetHeight - scroll_div.clientHeight;\n\tdocument.body.removeChild(scroll_div);\n\n\t//If for some reason we cannot get the height, default the height to 17 which is most common value. (Windows\n\tif ( !scroll_bar_height ) {\n\t\tscroll_bar_height = 17;\n }\n\n\tLocalCacheData.setScrollBarHeight( scroll_bar_height );\n\n\treturn scroll_bar_height;\n}\n\nGlobal.KEYCODES = {\n\t'48': '0',\n\t'49': '1',\n\t'50': '2',\n\t'51': '3',\n\t'52': '4',\n\t'53': '5',\n\t'54': '6',\n\t'55': '7',\n\t'56': '8',\n\t'59': '9',\n\t'65': 'a',\n\t'66': 'b',\n\t'67': 'c',\n\t'68': 'd',\n\t'69': 'e',\n\t'70': 'f',\n\t'71': 'g',\n\t'72': 'h',\n\t'73': 'i',\n\t'74': 'j',\n\t'75': 'k',\n\t'76': 'l',\n\t'77': 'm',\n\t'78': 'n',\n\t'79': 'o',\n\t'80': 'p',\n\t'81': 'q',\n\t'82': 'r',\n\t'83': 's',\n\t'84': 't',\n\t'85': 'u',\n\t'86': 'v',\n\t'87': 'w',\n\t'88': 'x',\n\t'89': 'y',\n\t'90': 'z'\n};\n\nGlobal.needReloadBrowser = false; // Need reload browser after set new cookie. To make router work for new session.\n\n// this attribute use to block UI in speical case that we allow users to click part of them and block other parts.\n// For example, when open edit view to block context menu.\nGlobal.block_ui = false;\n\nGlobal.sendErrorReport = function() {\n\tvar error_string = arguments[0];\n\tvar from_file = arguments[1];\n\tvar line = arguments[2];\n\tvar col = arguments[3];\n\tvar error_obj = arguments[4]; //Error object.\n\n\t_global_RateLimit__WEBPACK_IMPORTED_MODULE_3__/* .RateLimit.setID */ .b.setID( 'sendErrorReport' );\n\t_global_RateLimit__WEBPACK_IMPORTED_MODULE_3__/* .RateLimit.setAllowedCalls */ .b.setAllowedCalls( 6 );\n\t_global_RateLimit__WEBPACK_IMPORTED_MODULE_3__/* .RateLimit.setTimeFrame */ .b.setTimeFrame( 7200 ); //2hrs\n\n\tif ( _global_RateLimit__WEBPACK_IMPORTED_MODULE_3__/* .RateLimit.check */ .b.check() ) {\n\t\tvar captureScreenShot = function( error_msg, error_obj ) {\n\t\t\tif ( Global.isCanvasSupported() && typeof Promise !== 'undefined' ) { //HTML2Canvas requires promises, which IE11 does not have.\n\t\t\t\thtml2canvas( document.body ).then( function( canvas ) {\n\t\t\t\t\tvar image_string = canvas.toDataURL().split( ',' )[1];\n\t\t\t\t\tsourceMapStackTrace( error_msg, error_obj, image_string );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tsourceMapStackTrace( error_msg, error_obj, null );\n\t\t\t}\n\t\t};\n\n\t\tvar sourceMapStackTrace = function( error_msg, error_obj, image_string ) {\n\t\t\tif ( error_obj ) {\n\t\t\t\tvar stacktrace_callback = function( stackframes, error_msg, error_obj, image_string ) {\n\t\t\t\t\tvar stringified_stack = stackframes.map( function( sf ) {\n\t\t\t\t\t\treturn ' ' + sf.toString(); //Indent stack trace.\n\t\t\t\t\t} ).join( '\\n' );\n\n\t\t\t\t\terror_msg = error_msg + '\\n\\n\\n' + 'Stack Trace (Mapped): \\n' + error_obj.name + ': ' + error_obj.message + '\\n' + stringified_stack;\n\t\t\t\t\terror_msg = error_msg + '\\n\\n\\n' + 'Stack Trace (Raw): \\n' + error_obj.stack;\n\n\t\t\t\t\tsendErrorReport( error_msg, error_obj, image_string );\n\t\t\t\t};\n\n\t\t\t\tvar stacktrace_errback = function( error_msg, error_obj, image_string ) {\n\t\t\t\t\tconsole.error( 'ERROR: Unable to source map stack trace!' );\n\t\t\t\t\tsendErrorReport( error_msg, error_obj, image_string );\n\t\t\t\t};\n\n\t\t\t\tStackTrace.fromError( error_obj ).then( stackframes => stacktrace_callback( stackframes, error_msg, error_obj, image_string ) ).catch( error => stacktrace_errback( error_msg, error_obj, image_string ) );\n\t\t\t} else {\n\t\t\t\tsendErrorReport( error_msg, error_obj, image_string );\n\t\t\t}\n\t\t};\n\n\t\tvar sendErrorReport = function( error_msg, error_obj, image_string ) {\n\t\t\tDebug.Text( 'ERROR: ' + error_msg, 'Global.js', '', 'sendErrorReport', 1 );\n\n\t\t\tvar api_authentication = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\t\t\tapi_authentication.sendErrorReport( error_msg, image_string, {\n\t\t\t\tonResult: function( result ) {\n\t\t\t\t\tif ( !Global.dont_check_browser_cache && APIGlobal.pre_login_data.production === true && result.getResult() !== APIGlobal.pre_login_data.application_build ) {\n\t\t\t\t\t\tresult = result.getResult();\n\t\t\t\t\t\tvar message = $.i18n._( 'Your web browser is caching incorrect data, please press the refresh button on your web browser or log out, clear your web browsers cache and try logging in again.' ) + '

' + $.i18n._( 'Local Version' ) + ': ' + result + '
' + $.i18n._( 'Remote Version' ) + ': ' + APIGlobal.pre_login_data.application_build;\n\t\t\t\t\t\tGlobal.dont_check_browser_cache = true;\n\t\t\t\t\t\tGlobal.sendErrorReport( 'Your web browser is caching incorrect data. Local Version' + ': ' + result + ' Remote Version' + ': ' + APIGlobal.pre_login_data.application_build, _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url, '', '', '' );\n\n\t\t\t\t\t\tvar timeout_handler = window.setTimeout( function() {\n\t\t\t\t\t\t\twindow.location.reload( true );\n\t\t\t\t\t\t}, 120000 );\n\n\t\t\t\t\t\tTAlertManager.showAlert( message, '', function() {\n\t\t\t\t\t\t\tLocalCacheData.loadedScriptNames = {};\n\t\t\t\t\t\t\tDebug.Text( 'Incorrect cache... Forcing reload after JS exception...', 'Global.js', 'Global', 'cachingIncorrectData', 10 );\n\t\t\t\t\t\t\twindow.clearTimeout( timeout_handler );\n\t\t\t\t\t\t\twindow.location.reload( true );\n\t\t\t\t\t\t} );\n\t\t\t\t\t} else if ( Global.dont_check_browser_cache ) {\n\t\t\t\t\t\tGlobal.dont_check_browser_cache = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\n\t\tvar login_user = LocalCacheData.getLoginUser();\n\n\t\t/*\n\t\t * JavaScript exception ignore list\n\t\t */\n\t\tif ( from_file && typeof from_file == 'string' && from_file.indexOf( 'extension://' ) >= 0 ) { //Error happened in some Chrome Extension, ignore.\n\t\t\tconsole.error( 'Ignoring javascript exception from browser extension outside of our control...' );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( error_string.indexOf( 'Script error' ) >= 0 || //Script error. in: line: 0 -- Likely browser extensions or errors from injected or outside javascript.\n\t\t\terror_string.indexOf( 'Unspecified error' ) >= 0 || //From IE: Unspecified error. in N/A line 1\n\t\t\terror_string.indexOf( 'TypeError: \\'null\\' is not an object' ) >= 0 ||\n\t\t\terror_string.indexOf( '_avast_submit' ) >= 0 || //Errors from anti-virus extension\n\t\t\terror_string.indexOf( 'ResizeObserver loop limit exceeded' ) >= 0 ||\n\t\t\terror_string.indexOf( 'googletag' ) >= 0 || //Errors from google tag extension -- Uncaught TypeError: Cannot redefine property: googletag\n\t\t\terror_string.indexOf( 'NS_ERROR_' ) >= 0 ||\n\t\t\terror_string.indexOf( 'NS_ERROR_OUT_OF_MEMORY' ) >= 0 ||\n\t\t\terror_string.indexOf( 'NPObject' ) >= 0 ) { //Error calling method on NPObject - likely caused by an extension or plugin in the browser\n\t\t\tconsole.error( 'Ignoring javascript exception outside of our control...' );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( Global.idle_time > 15 ) {\n\t\t\tDebug.Text( 'User inactive more than 15 mins, not sending error report.', 'Global.js', '', 'sendErrorReport', 1 );\n\t\t\tif ( typeof ( gtag ) !== 'undefined' && APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\t\t\tgtag( 'event', 'exception', {\n\t\t\t\t\t'exDescription': 'Session Idle: ' + error_string + ' File: ' + ( ( from_file ) ? from_file.replace( Global.getBaseURL(), '' ) : 'N/A' ) + ' Line: ' + line,\n\t\t\t\t\t'exFatal': false\n\t\t\t\t} )\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvar error;\n\n\t\t//BUG#2066 - allow this function to be called earlier.\n\t\tvar script_name = '~unknown~';\n\t\tif ( Global.isSet( LocalCacheData ) && Global.isSet( LocalCacheData.current_open_primary_controller ) && Global.isSet( LocalCacheData.current_open_primary_controller.script_name ) ) {\n\t\t\tscript_name = LocalCacheData.current_open_primary_controller.script_name;\n\t\t}\n\n\t\tvar pre_login_data;\n\t\tif ( APIGlobal.pre_login_data ) {\n\t\t\tpre_login_data = APIGlobal.pre_login_data;\n\t\t} else {\n\t\t\tpre_login_data = null;\n\t\t}\n\n\t\tvar current_company_obj;\n\t\tif ( Global.isSet( LocalCacheData ) && LocalCacheData['current_company'] ) { //getCurrentCompany() which in turn calls getRequiredLocalCache(), which can call sendErroReport causing a loop. So try to prevent that by checking LocalCacheData['current_company'] first.\n\t\t\tcurrent_company_obj = LocalCacheData.getCurrentCompany();\n\t\t} else {\n\t\t\tcurrent_company_obj = null;\n\t\t}\n\n\t\tif ( login_user && Debug.varDump ) {\n\t\t\terror = 'Client Version: ' + APIGlobal.pre_login_data.application_build + '\\n\\nUncaught Error From: ' + script_name + '\\n\\nError: ' + error_string + ' in: ' + from_file + ' line: ' + line + ':' + col + '\\n\\nUser: ' + login_user.user_name + '\\n\\nURL: ' + window.location.href + '\\n\\nUser-Agent: ' + navigator.userAgent + ' ' + '\\n\\nIE: ' + window.ie + '\\n\\nCurrent Ping: ' + Global.current_ping + '\\n\\nIdle Time: ' + Global.idle_time + '\\n\\nSession ID Key: ' + LocalCacheData.getSessionID() + '\\n\\nCurrent User Object: \\n' + Debug.varDump( login_user ) + '\\n\\nCurrent Company Object: \\n' + Debug.varDump( current_company_obj ) + '\\n\\nPreLogin: \\n' + Debug.varDump( pre_login_data ) + ' ';\n\t\t} else {\n\t\t\terror = 'Client Version: ' + APIGlobal.pre_login_data.application_build + '\\n\\nUncaught Error From: ' + script_name + '\\n\\nError: ' + error_string + ' in: ' + from_file + ' line: ' + line + ':' + col + '\\n\\nUser: N/A' + '\\n\\nURL: ' + window.location.href + ' ' + '\\n\\nUser-Agent: ' + navigator.userAgent + ' ' + '\\n\\nIE: ' + window.ie;\n\t\t}\n\n\t\tconsole.error( 'JAVASCRIPT EXCEPTION:\\n---------------------------------------------\\n' + error + '\\n---------------------------------------------' );\n\t\tdebugger;\n\n\t\t//When not in production mode, popup alert box anytime an exception appears so it can't be missed.\n\t\tif ( APIGlobal.pre_login_data.production !== true && APIGlobal.pre_login_data.demo_mode !== true && APIGlobal.pre_login_data.sandbox !== true ) {\n\t\t\talert( 'JAVASCRIPT EXCEPTION:\\n---------------------------------------------\\n' + error + '\\n---------------------------------------------' );\n\t\t}\n\n\t\tif ( typeof ( gtag ) !== 'undefined' && APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\t\t// Send an exception hit to Google Analytics. Must be 8192 bytes or smaller.\n\t\t\t// Strip the domain part off the URL on 'from_file' to better account for similar errors.\n\t\t\tgtag( 'event', 'exception', {\n\t\t\t\t'exDescription': error_string + ' File: ' + ( ( from_file ) ? from_file.replace( Global.getBaseURL(), '' ) : 'N/A' ) + ' Line: ' + line + ':' + col,\n\t\t\t\t'exFatal': false\n\t\t\t} )\n\t\t}\n\n\t\t//Don't send error report if exception not happens in our codes.\n\t\t//from_file should always contains the root url\n\t\t//If URL is not sent by IE, assume its our own code and report the error still.\n\t\t// Modern browsers won't send error reports from other domains due to security issues now, so I think this can be removed.\n\t\t// if ( from_file && from_file.indexOf( ServiceCaller.root_url ) < 0 ) {\n\t\t// \tDebug.Text( 'Exception caught from unauthorized source, not sending report. Source: \"' + ServiceCaller.root_url + '\" Script: ' + from_file, 'Global.js', '', 'sendErrorReport', 1 );\n\t\t// \treturn;\n\t\t// }\n\n\t\tif ( current_company_obj ) { //getCurrentCompany() which in turn calls getRequiredLocalCache(), which can call sendErroReport causing a loop. So try to prevent that by checking LocalCacheData['current_company'] first.\n\t\t\terror = error + '\\n\\n' + 'Product Edition: ' + current_company_obj.product_edition_id;\n\t\t}\n\n\t\terror = error + '\\n\\n\\n' + 'Clicked target stacks: ' + JSON.stringify( LocalCacheData.ui_click_stack, undefined, 2 );\n\t\terror = error + '\\n\\n\\n' + 'API stacks: ' + JSON.stringify( LocalCacheData.api_stack, undefined, 2 );\n\n\t\tcaptureScreenShot( error, error_obj );\n\t}\n};\n\nGlobal.initStaticStrings = function() {\n\tGlobal.network_lost_msg = $.i18n._( 'The network connection was lost. Please check your network connection then try again.' );\n\n\tGlobal.any_item = '-- ' + $.i18n._( 'Any' ) + ' --';\n\n\tGlobal.all_item = '-- ' + $.i18n._( 'All' ) + ' --';\n\n\tGlobal.root_item = $.i18n._( 'Root' );\n\n\tGlobal.loading_label = '...';\n\n\tGlobal.customize_item = '-- ' + $.i18n._( 'Customize' ) + ' --';\n\n\tGlobal.default_item = '-- ' + $.i18n._( 'Default' ) + ' --';\n\n\tGlobal.selected_item = '-- ' + $.i18n._( 'Selected' ) + ' --';\n\n\tGlobal.open_item = '-- ' + $.i18n._( 'Open' ) + ' --';\n\n\tGlobal.empty_item = '-- ' + $.i18n._( 'None' ) + ' --';\n\n\tGlobal.view_mode_message = $.i18n._( 'You are currently in \\'View\\' mode' );\n\n\tGlobal.view_mode_edit_message = $.i18n._( 'instead click the \\'Edit\\' icon to modify fields' ); //Does not start with a capital as it is appended text.\n\n\tGlobal.no_result_message = $.i18n._( 'No Results Found' );\n\n\tGlobal.save_and_continue_message = $.i18n._( 'Please save this record before modifying any related data' );\n\n\tGlobal.no_hierarchy_message = $.i18n._( 'No Hierarchies Defined' );\n\n\tGlobal.modify_alert_message = $.i18n._( 'You have modified data without saving, are you sure you want to continue and lose your changes' );\n\n\tGlobal.confirm_on_exit_message = $.i18n._( 'Are you sure you want to continue without saving?' );\n\n\tGlobal.delete_confirm_message = $.i18n._( 'You are about to delete data, once data is deleted it can not be recovered.
Are you sure you wish to continue?' );\n\n\tGlobal.delete_dashlet_confirm_message = $.i18n._( 'You are about to delete this dashlet, once a dashlet is deleted it can not be recovered.
Are you sure you wish to continue?' );\n\n\tGlobal.copy_multiple_confirm_message = $.i18n._( 'You are about to copy multiple records.
Are you sure you wish to continue?' );\n\n\tGlobal.auto_arrange_dashlet_confirm_message = $.i18n._( 'You are about to restore all dashlets to their default size/layout.
Are you sure you wish to continue?' );\n\n\tGlobal.rese_all_dashlet_confirm_message = $.i18n._( 'You are about to remove all your customized dashlets and restore them back to the defaults.
Are you sure you wish to continue?' );\n};\n\nGlobal.getUpgradeMessage = function() {\n\tvar message = $.i18n._( 'This functionality is only available in' ) +\n\t\t' ' + LocalCacheData.getLoginData().application_name + ' ';\n\n\tif ( Global.getProductEdition() < 15 ) {\n\t\t//Do not mention professional if user is on professional edition.\n\t\tmessage += $.i18n._( 'Professional, Corporate, or Enterprise Editions.' );\n\t} else if ( Global.getProductEdition() < 20 ) {\n\t\t//Do not mention corporate if user is on corporate edition.\n\t\tmessage += $.i18n._( 'Corporate or Enterprise Editions.' );\n\t} else {\n\t\tmessage += $.i18n._( 'Enterprise Editions.' );\n\t}\n\n\tmessage += ' ' + $.i18n._( 'For more information please visit' ) + ' www.timetrex.com';\n\n\tGlobal.trackView( 'CommunityUpgrade' );\n\treturn message;\n};\n\nGlobal.doPingIfNecessary = function() {\n\tif ( Global.idle_time < Math.min( 15, APIGlobal.pre_login_data.session_idle_timeout / 60 ) ) { //idle_time is minutes, session_idle_timeout is seconds.\n\t\tGlobal.idle_time = 0;\n\t\treturn;\n\t}\n\n\tDebug.Text( 'User is active again after idle for: ' + Global.idle_time + '... Resetting idle to 0', 'Global.js', '', 'doPingIfNecessary', 1 );\n\tGlobal.idle_time = 0;\n\n\tif ( LocalCacheData.current_open_primary_controller.viewId === 'LoginView' ) {\n\t\treturn;\n\t}\n\n\tvar api = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\tapi.isLoggedIn( false, {\n\t\tonResult: function( result ) {\n\t\t\tvar res_data = result.getResult();\n\n\t\t\tif ( res_data !== true ) {\n\t\t\t\t//Don't do Logout here, as we need to display a \"Session Expired\" message to the user, which is triggered from the ServiceCaller.\n\t\t\t\t// In order to trigger that though, we need to make an *Authenticated* API call to APIMisc.Ping(), rather than UnAuthenticated call to APIAuthentication.Ping()\n\t\t\t\tvar api = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIMisc */ .y.APIMisc;\n\t\t\t\tapi.ping( {\n\t\t\t\t\tonResult: function() {\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} );\n};\n\nGlobal.setupPing = function() {\n\tGlobal.idle_time = 0;\n\t$( 'body' ).mousemove( Global.debounce( function setupPingMouseMoveEvent( e ) {\n\t\tGlobal.doPingIfNecessary();\n\t}, 1000 ) );\n\t$( 'body' ).keypress( Global.debounce( function setupPingKeyPressEvent( e ) {\n\t\tGlobal.doPingIfNecessary();\n\t}, 1000 ) );\n\n\tsetInterval( timerIncrement, 60000 ); // 1 minute\n\tfunction timerIncrement() {\n\t\tGlobal.idle_time = Global.idle_time + 1;\n\t\tif ( Global.idle_time >= Math.min( 15, APIGlobal.pre_login_data.session_idle_timeout / 60 ) ) {\n\t\t\tDebug.Text( 'User is idle: ' + Global.idle_time, 'Global.js', '', 'setupPing', 1 );\n\t\t}\n\t}\n};\n\nGlobal.clearCache = function( function_name ) {\n\tfor ( var key in LocalCacheData.result_cache ) {\n\t\tif ( key.indexOf( function_name ) >= 0 ) {\n\t\t\tdelete LocalCacheData.result_cache[key];\n\t\t}\n\t}\n};\n\nGlobal.getHost = function( host ) {\n\tif ( !host ) {\n\t\thost = window.location.hostname;\n\t}\n\n\t//Make sure its not an IPv4 address, and if its a domain has more than 1 dot in it before parsing off the sub-domain part.\n\t// So both IPv4 addresses and domains like: localhost (no dot at all), mycompany.com should not be modified at all. Only: sub.mycompany.com, sub.sub2.mycompany.com\n\tvar is_sub_domain = host.match( /\\./g );\n\tif ( /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/.test( host ) == false && is_sub_domain && is_sub_domain.length > 1 ) {\n\t\thost = host.substring( ( host.indexOf( '.' ) + 1 ) );\n\t}\n\n\treturn host;\n};\n\nGlobal.setWidgetEnabled = function( widget, val ) {\n\tif ( widget ) {\n\t\tif ( !val ) {\n\t\t\twidget.attr( 'disabled', 'true' );\n\t\t\twidget.addClass( 'disable-filter' );\n\t\t} else {\n\t\t\twidget.removeAttr( 'disabled' );\n\t\t\twidget.removeClass( 'disable-filter' );\n\t\t}\n\t}\n};\n\nGlobal.createViewTabs = function() {\n\t//JS load Optimize\n\tif ( typeof _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic == 'undefined' ) {\n\t\treturn;\n\t}\n\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\tif ( !LocalCacheData.view_min_tab_bar ) {\n\t\t\tvar view_min_tab_bar = Global.loadWidgetByName( _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.VIEW_MIN_TAB_BAR );\n\t\t\tview_min_tab_bar = $( view_min_tab_bar ).ViewMinTabBar();\n\t\t\t$( '.layout-menu-container' ).append( view_min_tab_bar );\n\n\t\t\tLocalCacheData.view_min_tab_bar = view_min_tab_bar;\n\t\t}\n\n\t\tLocalCacheData.view_min_tab_bar.buildTabs( LocalCacheData.view_min_map );\n\t}\n};\n\nGlobal.addViewTab = function( view_id, view_name, url ) {\n\n\tLocalCacheData.view_min_map[view_id] = view_name;\n\n\tLocalCacheData.view_min_map[view_id + '_url'] = url;\n\n\tGlobal.createViewTabs();\n};\n\nGlobal.removeViewTab = function( view_id ) {\n\n\tdelete LocalCacheData.view_min_map[view_id];\n\t$( '#min_tab_' + view_id ).remove();\n};\n\nGlobal.cleanViewTab = function() {\n\n\tLocalCacheData.view_min_map = {};\n\tGlobal.createViewTabs();\n};\n\nGlobal.upCaseFirstLetter = function( str ) {\n\tif ( typeof str == 'string' ) { //in case null or false is passed, we should check the type.\n\t\tstr = str.charAt( 0 ).toUpperCase() + str.slice( 1 );\n\t}\n\treturn str;\n};\n\nGlobal.calculateTextWidth = function( text, options ) {\n\tif ( typeof options === \"undefined\" ) {\n\t\toptions = {};\n\t}\n\n\tif ( !options.fontSize ) {\n\t\toptions.fontSize = '12px';\n\t}\n\n\tvar element = document.createElement( 'div' );\n\tvar textNode = document.createTextNode( text );\n\n\telement.appendChild( textNode );\n\n\tif ( options.font ) {\n\t\telement.style.fontFamily = options.font;\n\t}\n\n\tif ( options.fontWeight ) {\n\t\telement.style.fontWeight = options.fontWeight;\n\t}\n\n\tif ( options.wordBreak ) {\n\t\telement.style.wordBreak = options.wordBreak;\n\t}\n\n\telement.style.fontSize = options.fontSize;\n\telement.style.position = 'absolute';\n\telement.style.visibility = 'hidden';\n\telement.style.left = '-999px';\n\telement.style.top = '-999px';\n\telement.style.height = 'auto';\n\n\tdocument.body.appendChild( element );\n\tvar content_width = element.offsetWidth;\n\telement.parentNode.removeChild( element );\n\n\tif ( options.min_width && options.min_width > 0 && content_width < options.min_width ) {\n\t\tcontent_width = options.min_width;\n\t}\n\tif ( options.padding && options.padding > 0 ) {\n\t\tcontent_width = content_width + options.padding;\n\t}\n\tif ( options.max_width > 0 && content_width > options.max_width ) {\n\t\tcontent_width = options.max_width;\n\t}\n\n\treturn content_width;\n};\n\nGlobal.strToDate = function( date_string, format ) {\n\n\t//better to use Date.parse, let's see\n\tif ( !Global.isSet( format ) && LocalCacheData.getLoginUserPreference() ) {\n\t\tformat = LocalCacheData.getLoginUserPreference().date_format;\n\t}\n\n\tif ( !format ) {\n\t\tformat = 'DD-MMM-YY';\n\t}\n\n\tvar date = moment( date_string, format );\n\tdate = date.toDate();\n\n\t//The moment will pass everything as a date. Judge if the year less 1000 than 1900 or beyond 1000 of 1900,\n\t//we think it's a invalid year\n\tif ( date.getYear() < -1000 || date.getYear() > 1000 ) {\n\t\treturn null;\n\t}\n\n\treturn date;\n};\n\nGlobal.strToDateTime = function( date_string ) {\n\t//Error: TypeError: Global.strToDateTime(...) is null in /interface/html5/framework/jquery.min.js?v=8.0.0-20141117-153515 line 4862\n\tif ( !date_string || !LocalCacheData.getLoginUserPreference() ) {\n\t\treturn null;\n\t}\n\n\tvar date_format = LocalCacheData.getLoginUserPreference().date_format;\n\tvar time_format = LocalCacheData.getLoginUserPreference().js_time_format[LocalCacheData.getLoginUserPreference().time_format];\n\tvar date = moment( date_string, date_format + ' ' + time_format ).toDate();\n\n\treturn date;\n\t//return Date.parse( date_string );\n};\n\n//Convert all kinds of date time to mm/dd/yyyy so Date.parse can parse it correct\nGlobal.getStandardDateTimeStr = function( date_str, time_str ) {\n\t//var result = Global.strToDate( date_str ).format( 'MM/DD/YYYY' ) + ' ' + time_str;\n\n\treturn date_str;\n};\n\nGlobal.convertTojQueryFormat = function( date_format ) {\n\t//For moment date parser\n\tvar jquery_date_format = {\n\t\t'd-M-y': 'dd-M-y',\n\t\t'd-M-Y': 'dd-M-yy',\n\t\t'dMY': 'ddMyy',\n\t\t'd/m/Y': 'dd/mm/yy',\n\t\t'd/m/y': 'dd/mm/y',\n\t\t'd-m-y': 'dd-mm-y',\n\t\t'd-m-Y': 'dd-mm-yy',\n\t\t'm/d/y': 'mm/dd/y',\n\t\t'm/d/Y': 'mm/dd/yy',\n\t\t'm-d-y': 'mm-dd-y',\n\t\t'm-d-Y': 'mm-dd-yy',\n\t\t'Y-m-d': 'yy-mm-dd',\n\t\t'M-d-y': 'M-dd-y',\n\t\t'M-d-Y': 'M-dd-yy',\n\t\t'l, F d Y': 'DD, MM dd yy',\n\t\t'D, F d Y': 'D, MM dd yy',\n\t\t'D, M d Y': 'D, M dd yy',\n\t\t'D, d-M-Y': 'D, dd-M-yy',\n\t\t'D, dMY': 'D, ddMyy',\n\n\t\t'g:i A': 'h:mm TT',\n\t\t'g:i a': 'h:mm tt',\n\t\t'G:i': 'H:mm',\n\t\t'g:i A T': 'h:mm TT',\n\t\t'G:i T': 'H:mm',\n\n\t\t'g:i:s A': 'h:mm:ss TT',\n\t\t'g:i:s a': 'h:mm:ss tt',\n\t\t'G:i:s': 'H:mm:ss',\n\t\t'g:i:s A T': 'h:mm:ss TT',\n\t\t'G:i:s T': 'H:mm:ss'\n\t};\n\n\treturn jquery_date_format[date_format];\n};\n\nGlobal.updateUserPreference = function( callBack, message ) {\n\tvar user_preference_api = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIUserPreference */ .y.APIUserPreference;\n\tvar current_user_aou = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\n\tif ( message ) {\n\t\tProgressBar.changeProgressBarMessage( message );\n\t}\n\n\tcurrent_user_aou.getCurrentUserPreference( {\n\t\tonResult: function( result ) {\n\t\t\tvar result_data = result.getResult();\n\t\t\tLocalCacheData.loginUserPreference = result_data;\n\n\t\t\tuser_preference_api.getOptions( 'moment_date_format', {\n\t\t\t\tonResult: function( jsDateFormatRes ) {\n\t\t\t\t\tvar jsDateFormatResultData = jsDateFormatRes.getResult();\n\n\t\t\t\t\t//For moment date parser\n\t\t\t\t\tLocalCacheData.loginUserPreference.js_date_format = jsDateFormatResultData;\n\n\t\t\t\t\tvar date_format = LocalCacheData.loginUserPreference.date_format;\n\t\t\t\t\tif ( !date_format ) {\n\t\t\t\t\t\tdate_format = 'DD-MMM-YY';\n\t\t\t\t\t}\n\n\t\t\t\t\tLocalCacheData.loginUserPreference.date_format = LocalCacheData.loginUserPreference.js_date_format[date_format];\n\n\t\t\t\t\tLocalCacheData.loginUserPreference.date_format_1 = Global.convertTojQueryFormat( date_format ); //TDatePicker, TRangePicker\n\t\t\t\t\tLocalCacheData.loginUserPreference.time_format_1 = Global.convertTojQueryFormat( LocalCacheData.loginUserPreference.time_format ); //TTimePicker\n\n\t\t\t\t\tuser_preference_api.getOptions( 'moment_time_format', {\n\t\t\t\t\t\tonResult: function( jsTimeFormatRes ) {\n\t\t\t\t\t\t\tvar jsTimeFormatResultData = jsTimeFormatRes.getResult();\n\n\t\t\t\t\t\t\tLocalCacheData.loginUserPreference.js_time_format = jsTimeFormatResultData;\n\n\t\t\t\t\t\t\tLocalCacheData.setLoginUserPreference( LocalCacheData.loginUserPreference );\n\n\t\t\t\t\t\t\tif ( callBack ) {\n\t\t\t\t\t\t\t\tcallBack();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t} );\n};\n\n/* jshint ignore:start */\nGlobal.roundTime = function( epoch, round_value, round_type ) {\n\tvar round_type = round_type || 20;\n\n\tswitch ( round_type ) {\n\t\tcase 10: //Down\n\t\t\tepoch = ( epoch - ( epoch % round_value ) );\n\t\t\tbreak;\n\t\tcase 20: //Average\n\t\tcase 25: //Average (round split seconds up)\n\t\tcase 27: //Average (round split seconds down)\n\t\t\tvar tmp_round_value;\n\t\t\tif ( round_type == 20 || round_value <= 60 ) {\n\t\t\t\ttmp_round_value = ( round_value / 2 );\n\t\t\t} else if ( round_type == 25 ) { //Average (Partial Min. Down)\n\t\t\t\ttmp_round_value = Global.roundTime( ( round_value / 2 ), 60, 10 ); //This is opposite rounding\n\t\t\t} else if ( round_type == 27 ) { //Average (Partial Min. Up)\n\t\t\t\ttmp_round_value = Global.roundTime( ( round_value / 2 ), 60, 30 );\n\t\t\t}\n\n\t\t\tif ( epoch > 0 ) {\n\t\t\t\t//When doing a 15min average rounding, US law states 7mins and 59 seconds can be rounded down in favor of the employer, and 8mins and 0 seconds must be rounded up.\n\t\t\t\t//So if the round interval is not an even number, round it up to the nearest minute before doing the calculations to avoid issues with seconds.\n\t\t\t\tepoch = ( Math.floor( ( epoch + tmp_round_value ) / round_value ) * round_value );\n\t\t\t} else {\n\t\t\t\tepoch = ( Math.ceil( ( epoch - tmp_round_value ) / round_value ) * round_value );\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 30: //Up\n\t\t\tepoch = ( ( ( epoch + ( round_value - 1 ) ) / round_value ) * round_value );\n\t\t\tbreak;\n\t}\n\n\treturn epoch;\n},\n\n\tGlobal.parseTimeUnit = function( time_unit, format ) {\n\t\tvar format, time_unit, time_units, seconds, negative_number;\n\n\t\tvar time_unit = time_unit.toString(); //Needs to be a string so we can use .charAt and .replace below.\n\n\t\tif ( !format ) {\n\t\t\tformat = LocalCacheData.getLoginUserPreference().time_unit_format;\n\t\t}\n\t\tformat = parseInt( format );\n\n\t\tvar enable_rounding = true;\n\t\tif ( time_unit.charAt( 0 ) == '\"' ) {\n\t\t\tenable_rounding = false;\n\t\t}\n\n\t\tvar thousands_separator = ',';\n\t\tvar decimal_separator = '.';\n\n\t\ttime_unit = time_unit.replace( new RegExp( thousands_separator, 'g' ), '' ).replace( new RegExp( ' ', 'g' ), '' ).replace( new RegExp( '\"', 'g' ), '' ); //Need to use regex to replace all instances.\n\n\t\tswitch ( format ) {\n\t\t\tcase 10: //hh:mm\n\t\t\tcase 12: //hh:mm:ss\n\t\t\t\tif ( time_unit.indexOf( decimal_separator ) !== -1 && time_unit.indexOf( ':' ) === -1 ) { //Hybrid mode, they passed a decimal format HH:MM, try to handle properly.\n\t\t\t\t\ttime_unit = Global.getTimeUnit( Global.parseTimeUnit( time_unit, 20 ), format );\n\t\t\t\t}\n\n\t\t\t\ttime_units = time_unit.split( ':' );\n\n\t\t\t\tif ( !time_units[0] ) {\n\t\t\t\t\ttime_units[0] = 0;\n\t\t\t\t}\n\n\t\t\t\tif ( !time_units[1] ) {\n\t\t\t\t\ttime_units[1] = 0;\n\t\t\t\t}\n\n\t\t\t\tif ( !time_units[2] ) {\n\t\t\t\t\ttime_units[2] = 0;\n\t\t\t\t} else {\n\t\t\t\t\tif ( time_units[2] != 0 ) {\n\t\t\t\t\t\tenable_rounding = false; //Since seconds were specified, don't round to nearest minute.\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tnegative_number = false;\n\t\t\t\tif ( time_units[0].toString().charAt( 0 ) == '-' || time_units[0] < 0 || time_units[1] < 0 || time_units[2] < 0 ) {\n\t\t\t\t\tnegative_number = true;\n\t\t\t\t}\n\n\t\t\t\tseconds = ( ( Math.abs( Math.floor( time_units[0] ) ) * 3600 ) + ( Math.abs( Math.floor( time_units[1] ) ) * 60 ) + Math.abs( Math.floor( time_units[2] ) ) );\n\n\t\t\t\tif ( negative_number == true ) {\n\t\t\t\t\tseconds = ( seconds * -1 );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tcase 20: //hours\n\t\t\tcase 22: //hours [Precise]\n\t\t\tcase 23: //hours [Super Precise]\n\t\t\t\tif ( time_unit.indexOf( ':' ) !== -1 ) { //Hybrid mode, they passed a decimal format HH:MM, try to handle properly.\n\t\t\t\t\ttime_unit = Global.getTimeUnit( Global.parseTimeUnit( time_unit, 10 ), format );\n\t\t\t\t}\n\n\t\t\t\tseconds = ( time_unit * 3600 );\n\t\t\t\tbreak;\n\t\t\tcase 30: //minutes\n\t\t\t\tseconds = ( time_unit * 60 );\n\t\t\t\tbreak;\n\t\t\tcase 40: //seconds\n\t\t\t\tseconds = time_unit;\n\t\t\t\tif ( enable_rounding == true ) {\n\t\t\t\t\tseconds = round( seconds ); //Round to nearest whole number by default.\n\t\t\t\t}\n\t\t\t\tenable_rounding = false; //Since seconds were specified, don't round to nearest minute. Also for accruals might need to allow decimal seconds.\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( enable_rounding == true ) {\n\t\t\tseconds = Global.roundTime( seconds, 60 );\n\t\t}\n\n\t\t//Debug.Text( 'Time Unit: '+ time_unit +' Retval: '+ seconds, 'Global.js', '', 'parseTimeUnit', 10 );\n\t\treturn seconds;\n\t},\n\n\tGlobal.convertSecondsToHMS = function( seconds, include_seconds, exclude_hours ) {\n\t\tvar negative_number = false;\n\n\t\tif ( seconds < 0 ) {\n\t\t\tnegative_number = true;\n\t\t}\n\n\t\tseconds = Math.round( Math.abs( seconds ) );\n\n\t\tvar tmp_hours = Math.floor( seconds / 3600 );\n\t\tvar tmp_minutes = Math.floor( ( seconds / 60 ) % 60 );\n\t\tvar tmp_seconds = Math.floor( seconds % 60 );\n\n\t\tif ( exclude_hours == true ) { //Convert hours to minutes before we pad it.\n\t\t\ttmp_minutes = ( ( tmp_hours * 60 ) + tmp_minutes );\n\t\t\ttmp_hours = 0;\n\t\t}\n\n\t\tif ( tmp_hours < 10 ) {\n\t\t\ttmp_hours = '0' + tmp_hours;\n\t\t}\n\n\t\tif ( tmp_minutes < 10 ) {\n\t\t\ttmp_minutes = '0' + tmp_minutes;\n\t\t}\n\n\t\tif ( tmp_seconds < 10 ) {\n\t\t\ttmp_seconds = '0' + tmp_seconds;\n\t\t}\n\n\t\tvar retval;\n\t\tif ( exclude_hours == true ) {\n\t\t\tretval = [tmp_minutes, tmp_seconds].join( ':' );\n\t\t} else {\n\t\t\tif ( include_seconds == true ) {\n\t\t\t\tretval = [tmp_hours, tmp_minutes, tmp_seconds].join( ':' );\n\t\t\t} else {\n\t\t\t\tretval = [tmp_hours, tmp_minutes].join( ':' );\n\t\t\t}\n\t\t}\n\n\t\tif ( negative_number == true ) {\n\t\t\tretval = '-' + retval;\n\t\t}\n\n\t\treturn retval;\n\t},\n\n//Was: Global.secondToHHMMSS\n\tGlobal.getTimeUnit = function( seconds, format ) {\n\t\tvar retval;\n\n\t\t//always return hh:ss. if we can't parse to float, then work with 0 tmp_seconds\n\t\tvar seconds = parseFloat( seconds );\n\t\tif ( isNaN( seconds ) ) {\n\t\t\tseconds = 0;\n\t\t}\n\n\t\t//FIXES BUG#2071 - don't check the local cache data for default value, or it will fail and cause errors when unauthenticated. For example in the installer.\n\t\tvar format;\n\t\tif ( !format ) {\n\t\t\tif ( LocalCacheData.getLoginUserPreference() ) {\n\t\t\t\tformat = LocalCacheData.getLoginUserPreference().time_unit_format;\n\t\t\t} else {\n\t\t\t\tformat = 10;\n\t\t\t}\n\t\t}\n\t\tformat = parseInt( format );\n\n\t\tswitch ( format ) {\n\t\t\tcase 10:\n\t\t\t\tretval = Global.convertSecondsToHMS( seconds );\n\t\t\t\tbreak;\n\t\t\tcase 12:\n\t\t\t\tretval = Global.convertSecondsToHMS( seconds, true );\n\t\t\t\tbreak;\n\t\t\tcase 99: //For local use only, in progress bar always show tmp_minutes and tmp_seconds\n\t\t\t\tretval = Global.convertSecondsToHMS( seconds, true, true );\n\t\t\t\tbreak;\n\t\t\tcase 20:\n\t\t\t\tretval = ( seconds / 3600 ).toFixed( 2 );\n\t\t\t\tbreak;\n\t\t\tcase 22:\n\t\t\t\tretval = ( seconds / 3600 ).toFixed( 3 );\n\t\t\t\tbreak;\n\t\t\tcase 23:\n\t\t\t\tretval = ( seconds / 3600 ).toFixed( 4 );\n\t\t\t\tbreak;\n\t\t\tcase 30:\n\t\t\t\tretval = ( seconds / 60 ).toFixed( 0 );\n\t\t\t\tbreak;\n\t\t\tcase 40:\n\t\t\t\tretval = seconds;\n\t\t\t\tbreak;\n\t\t}\n\n\t\t//Debug.Text( 'Seconds: '+ seconds +' Retval: '+ retval, 'Global.js', '', 'getTimeUnit', 10 );\n\t\treturn retval;\n\t};\n\nGlobal.removeTrailingZeros = function( value, minimum_decimals ) {\n\tif ( !minimum_decimals ) {\n\t\tminimum_decimals = 2;\n\t}\n\tif ( value ) {\n\t\tvalue = parseFloat( value ); // first to remove the zero after the point.\n\n\t\tvar trimmed_value = value.toString();\n\n\t\tif ( trimmed_value.indexOf( '.' ) > 0 ) {\n\t\t\t// If after removed has the point, then reverse it.\n\t\t\tvar tmp_minimum_decimals = parseInt( trimmed_value.split( '' ).reverse().join( '' ) ).toString().length;\n\t\t\tif ( tmp_minimum_decimals >= minimum_decimals && tmp_minimum_decimals <= 4 ) {\n\t\t\t\tminimum_decimals = tmp_minimum_decimals;\n\t\t\t}\n\n\t\t}\n\n\t\treturn value.toFixed( minimum_decimals );\n\t}\n\n\treturn value;\n};\n\n/* jshint ignore:end */\n\nGlobal.isCanvasSupported = function() {\n\tvar elem = document.createElement( 'canvas' );\n\treturn !!( elem.getContext && elem.getContext( '2d' ) );\n};\n\nGlobal.getRandomNum = function() {\n\n\tvar number = Math.floor( Math.random() * 999 );//0-23\n\n\treturn number;\n\n};\n\n/* jshint ignore:start */\n\nGlobal.getScriptNameByAPI = function( api_class ) {\n\n\tif ( !api_class || !api_class.className ) {\n\t\treturn null;\n\t}\n\n\tvar script_name = '';\n\tswitch ( api_class.className ) {\n\t\tcase 'APIUser':\n\t\t\tscript_name = 'EmployeeView';\n\t\t\tbreak;\n\t\tcase 'APIBranch':\n\t\t\tscript_name = 'BranchView';\n\t\t\tbreak;\n\t\tcase 'APIDepartment':\n\t\t\tscript_name = 'DepartmentView';\n\t\t\tbreak;\n\t\tcase 'APIUserWage':\n\t\t\tscript_name = 'WageView';\n\t\t\tbreak;\n\t\tcase 'APIUserContact':\n\t\t\tscript_name = 'UserContactView';\n\t\t\tbreak;\n\t\tcase 'APIUserTitle':\n\t\t\tscript_name = 'UserTitleView';\n\t\t\tbreak;\n\t\tcase 'APIWageGroup':\n\t\t\tscript_name = 'WageGroupView';\n\t\t\tbreak;\n\t\tcase 'APILog':\n\t\t\tscript_name = 'LogView';\n\t\t\tbreak;\n\t\tcase 'APIUserGroup':\n\t\t\tscript_name = 'UserGroupView';\n\t\t\tbreak;\n\t\tcase 'APIPayStubEntryAccount':\n\t\t\tscript_name = 'PayStubEntryAccountView';\n\t\t\tbreak;\n\t\tcase 'APIPayStubEntryAccountLink':\n\t\t\tscript_name = 'PayStubEntryAccountLinkView';\n\t\t\tbreak;\n\t\tcase 'APIPayPeriod':\n\t\tcase 'APIPayPeriodSchedule':\n\t\t\tscript_name = 'PayPeriodsView';\n\t\t\tbreak;\n\t\tcase 'APIAccrual':\n\t\t\tscript_name = 'APIAccrual';\n\t\t\tbreak;\n\t\tcase 'APIAccrualBalance':\n\t\t\tscript_name = 'AccrualBalanceView';\n\t\t\tbreak;\n\t\tcase 'APIException':\n\t\t\tscript_name = 'ExceptionView';\n\t\t\tbreak;\n\t\tcase 'APIJobGroup':\n\t\t\tscript_name = 'JobGroupView';\n\t\t\tbreak;\n\t\tcase 'APIJob':\n\t\t\tscript_name = 'JobView';\n\t\t\tbreak;\n\t\tcase 'APIJobItemGroup':\n\t\t\tscript_name = 'JobItemGroupView';\n\t\t\tbreak;\n\t\tcase 'APIJobItem':\n\t\t\tscript_name = 'JobItemView';\n\t\t\tbreak;\n\t\tcase 'APIJobItemAmendment':\n\t\t\tscript_name = 'JobItemAmendment';\n\t\t\tbreak;\n\t\tcase 'APIPunch':\n\t\t\tscript_name = 'PunchesView';\n\t\t\tbreak;\n\t\tcase 'APIPunchTag':\n\t\t\tscript_name = 'PunchTagView';\n\t\t\tbreak;\n\t\tcase 'APIPunchTagGroup':\n\t\t\tscript_name = 'PunchTagGroupView';\n\t\t\tbreak;\n\t\tcase 'APIRecurringScheduleControl':\n\t\t\tscript_name = 'RecurringScheduleControlView';\n\t\t\tbreak;\n\n\t\tcase 'APIRecurringScheduleTemplateControl':\n\t\t\tscript_name = 'RecurringScheduleTemplateControlView';\n\t\t\tbreak;\n\t\tcase 'APISchedule':\n\t\t\tscript_name = 'ScheduleShiftView';\n\t\t\tbreak;\n\t\tcase 'APIBankAccount':\n\t\t\tscript_name = 'BankAccountView';\n\t\t\tbreak;\n\t\tcase 'APICompany':\n\t\t\tscript_name = 'CompanyView';\n\t\t\tbreak;\n\t\tcase 'APICurrency':\n\t\t\tscript_name = 'CurrencyView';\n\t\t\tbreak;\n\t\tcase 'APICurrencyRate':\n\t\t\tscript_name = 'CurrencyRate';\n\t\t\tbreak;\n\t\tcase 'APIHierarchyControl':\n\t\t\tscript_name = 'HierarchyControlView';\n\t\t\tbreak;\n\t\tcase 'APIEthnicGroup':\n\t\t\tscript_name = 'EthnicGroupView';\n\t\t\tbreak;\n\t\tcase 'APICustomField':\n\t\t\tscript_name = 'CustomFieldView';\n\t\t\tbreak;\n\t\tcase 'APIPermissionControl':\n\t\t\tscript_name = 'PermissionControlView';\n\t\t\tbreak;\n\t\tcase 'APIStation':\n\t\t\tscript_name = 'StationView';\n\t\t\tbreak;\n\t\tcase 'APIDocumentRevision':\n\t\t\tscript_name = 'DocumentRevisionView';\n\t\t\tbreak;\n\t\tcase 'APIDocumentGroup':\n\t\t\tscript_name = 'DocumentGroupView';\n\t\t\tbreak;\n\t\tcase 'APIDocument':\n\t\t\tscript_name = 'DocumentView';\n\t\t\tbreak;\n\t\tcase 'APIROE':\n\t\t\tscript_name = 'ROEView';\n\t\t\tbreak;\n\t\tcase 'APIUserDefault':\n\t\t\tscript_name = 'UserDefaultView';\n\t\t\tbreak;\n\t\tcase 'APIUserPreference':\n\t\t\tscript_name = 'UserPreferenceView';\n\t\t\tbreak;\n\t\tcase 'APIKPI':\n\t\t\tscript_name = 'KPIView';\n\t\t\tbreak;\n\t\tcase 'APIUserReviewControl':\n\t\t\tscript_name = 'UserReviewControlView';\n\t\t\tbreak;\n\t\tcase 'APIQualification':\n\t\t\tscript_name = 'QualificationView';\n\t\t\tbreak;\n\t\tcase 'APIUserEducation':\n\t\t\tscript_name = 'UserTitleView';\n\t\t\tbreak;\n\t\tcase 'APIUserLanguage':\n\t\t\tscript_name = 'UserTitleView';\n\t\t\tbreak;\n\t\tcase 'APIUserLicense':\n\t\t\tscript_name = 'UserLicenseView';\n\t\t\tbreak;\n\t\tcase 'APIUserMembership':\n\t\t\tscript_name = 'UserMembershipView';\n\t\t\tbreak;\n\t\tcase 'APIUserSkill':\n\t\t\tscript_name = 'UserSkillView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantEducation':\n\t\t\tscript_name = 'JobApplicantEducationView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantEmployment':\n\t\t\tscript_name = 'JobApplicantEducationView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantLanguage':\n\t\t\tscript_name = 'JobApplicantLanguageView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantLicense':\n\t\t\tscript_name = 'JobApplicantLicenseView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantLocation':\n\t\t\tscript_name = 'JobApplicantLicenseView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantMembership':\n\t\t\tscript_name = 'JobApplicantMembershipView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantReference':\n\t\t\tscript_name = 'JobApplicantReferenceView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicantSkill':\n\t\t\tscript_name = 'JobApplicantSkillView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplicant':\n\t\t\tscript_name = 'JobApplicantSkillView';\n\t\t\tbreak;\n\t\tcase 'APIJobApplication':\n\t\t\tscript_name = 'JobApplicationView';\n\t\t\tbreak;\n\t\tcase 'APIJobVacancy':\n\t\t\tscript_name = 'JobVacancyView';\n\t\t\tbreak;\n\t\tcase 'APIAreaPolicy':\n\t\t\tscript_name = 'JobVacancyView';\n\t\t\tbreak;\n\t\tcase 'APIClient':\n\t\t\tscript_name = 'ClientView';\n\t\t\tbreak;\n\t\tcase 'APIClientContact':\n\t\t\tscript_name = 'ClientContactView';\n\t\t\tbreak;\n\t\tcase 'APIClientGroup':\n\t\t\tscript_name = 'ClientGroupView';\n\t\t\tbreak;\n\t\tcase 'APIClientPayment':\n\t\t\tscript_name = 'ClientPaymentView';\n\t\t\tbreak;\n\t\tcase 'APIInvoiceDistrict':\n\t\t\tscript_name = 'InvoiceDistrictView';\n\t\t\tbreak;\n\t\tcase 'APIInvoice':\n\t\t\tscript_name = 'InvoiceView';\n\t\t\tbreak;\n\t\tcase 'APITransaction':\n\t\t\tscript_name = 'InvoiceTransactionView';\n\t\t\tbreak;\n\t\tcase 'APIPaymentGateway':\n\t\t\tscript_name = 'PaymentGatewayView';\n\t\t\tbreak;\n\t\tcase 'APIProductGroup':\n\t\t\tscript_name = 'ProductGroupView';\n\t\t\tbreak;\n\t\tcase 'APIProduct':\n\t\t\tscript_name = 'ProductView';\n\t\t\tbreak;\n\t\tcase 'APIInvoiceConfig':\n\t\t\tscript_name = 'InvoiceConfigView';\n\t\t\tbreak;\n\t\tcase 'APIShippingPolicy':\n\t\t\tscript_name = 'ShippingPolicyView';\n\t\t\tbreak;\n\t\tcase 'APITaxPolicy':\n\t\t\tscript_name = 'TaxPolicyView';\n\t\t\tbreak;\n\t\tcase 'APICompanyDeduction':\n\t\t\tscript_name = 'CompanyTaxDeductionView';\n\t\t\tbreak;\n\t\tcase 'APIPayStub':\n\t\t\tscript_name = 'PayStubView';\n\t\t\tbreak;\n\t\tcase 'APIPayStubTransaction':\n\t\t\tscript_name = 'PayStubTransactionView';\n\t\t\tbreak;\n\t\tcase 'APIPayStubEntry':\n\t\t\tscript_name = 'PayStubEntryView';\n\t\t\tbreak;\n\t\tcase 'APIPayStubAmendment':\n\t\t\tscript_name = 'PayStubAmendmentView';\n\t\t\tbreak;\n\t\tcase 'APIRecurringPayStubAmendment':\n\t\t\tscript_name = 'RecurringPayStubAmendmentView';\n\t\t\tbreak;\n\t\tcase 'APIUserExpense':\n\t\t\tscript_name = 'UserExpenseView';\n\t\t\tbreak;\n\t\tcase 'APILegalEntity':\n\t\t\tscript_name = 'LegalEntityView';\n\t\t\tbreak;\n\t\tcase 'APIPayrollRemittanceAgency':\n\t\t\tscript_name = 'PayrollRemittanceAgencyView';\n\t\t\tbreak;\n\t\tcase 'APIPayrollRemittanceAgencyEvent':\n\t\t\tscript_name = 'PayrollRemittanceAgencyViewEvent';\n\t\t\tbreak;\n\t\tcase 'APIAbsencePolicy':\n\t\t\tscript_name = 'AbsencePolicyView';\n\t\t\tbreak;\n\t\tcase 'APIAccrualPolicyAccount':\n\t\t\tscript_name = 'AccrualPolicyAccountView';\n\t\t\tbreak;\n\t\tcase 'APIAccrualPolicy':\n\t\t\tscript_name = 'AccrualPolicyView';\n\t\t\tbreak;\n\t\tcase 'APIAccrualPolicyUserModifier':\n\t\t\tscript_name = 'AccrualPolicyUserModifierView';\n\t\t\tbreak;\n\t\tcase 'APIBreakPolicy':\n\t\t\tscript_name = 'BreakPolicyView';\n\t\t\tbreak;\n\t\tcase 'APIExceptionPolicyControl':\n\t\t\tscript_name = 'ExceptionPolicyControlView';\n\t\t\tbreak;\n\t\tcase 'APIExpensePolicy':\n\t\t\tscript_name = 'ExpensePolicyView';\n\t\t\tbreak;\n\t\tcase 'APIHoliday':\n\t\t\tscript_name = 'HolidayView';\n\t\t\tbreak;\n\t\tcase 'APIHolidayPolicy':\n\t\t\tscript_name = 'HolidayPolicyView';\n\t\t\tbreak;\n\t\tcase 'APIMealPolicy':\n\t\t\tscript_name = 'MealPolicyView';\n\t\t\tbreak;\n\t\tcase 'APIOvertimePolicy':\n\t\t\tscript_name = 'OvertimePolicyView';\n\t\t\tbreak;\n\t\tcase 'APIPolicyGroup':\n\t\t\tscript_name = 'PolicyGroupView';\n\t\t\tbreak;\n\t\tcase 'APIPremiumPolicy':\n\t\t\tscript_name = 'PremiumPolicyView';\n\t\t\tbreak;\n\t\tcase 'APIRecurringHoliday':\n\t\t\tscript_name = 'RecurringHolidayView';\n\t\t\tbreak;\n\t\tcase 'APIRoundIntervalPolicy':\n\t\t\tscript_name = 'RoundIntervalPolicyView';\n\t\t\tbreak;\n\t\tcase 'APISchedulePolicy':\n\t\t\tscript_name = 'SchedulePolicyView';\n\t\t\tbreak;\n\t\tcase 'APIUserReportData':\n\t\t\tscript_name = 'UserReportDataView';\n\t\t\tbreak;\n\t\tcase 'APIInstall':\n\t\t\tscript_name = 'InstallView';\n\t\t\tbreak;\n\t}\n\n\treturn script_name;\n};\n\n/* jshint ignore:end */\n\nGlobal.isObject = function( obj ) {\n\tif ( obj !== null && typeof obj === 'object' ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\nGlobal.isArray = function( obj ) {\n\n\tif ( Object.prototype.toString.call( obj ) !== '[object Array]' ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n\nGlobal.isString = function( obj ) {\n\n\tif ( Object.prototype.toString.call( obj ) !== '[object String]' ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n};\n\nGlobal.isValidDate = function( obj ) {\n\tif ( obj instanceof Date && !isNaN( obj ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\nGlobal.decodeCellValue = function( val ) {\n\tif ( !val || _.isObject( val ) ) {\n\t\treturn val;\n\t}\n\tval = val.toString();\n\tval = val.replace( /\\n|\\r|(\\r\\n)|(\\u0085)|(\\u2028)|(\\u2029)/g, '
' );\n\tval = val.replace( /\\n|\\r|(\\r\\n)|(\\u0085)|(\\u2028)|(\\u2029)/g, '
' );\n\tval = Global.htmlEncode( val );\n\tval = val.replace( /<br>/g, '
' );\n\n\treturn val;\n};\n\nGlobal.buildTreeRecord = function( array, parentId ) {\n\tvar finalArray = [];\n\n\t$.each( array, function( key, item ) {\n\t\titem.expanded = true;\n\t\titem.loaded = true;\n\n\t\tif ( Global.isSet( parentId ) ) {\n\t\t\titem.parent = parentId;\n\t\t}\n\n\t\tfinalArray.push( item );\n\n\t\tif ( Global.isSet( item.children ) ) {\n\t\t\tvar childrenArray = Global.buildTreeRecord( item.children, item.id );\n\t\t\tfinalArray = finalArray.concat( childrenArray );\n\t\t} else {\n\t\t\titem.isLeaf = true;\n\t\t}\n\n\t} );\n\n\treturn finalArray;\n};\n\nGlobal.getParentIdByTreeRecord = function( array, selectId ) {\n\n\tvar retval = [];\n\tfor ( var i = 0; i < array.length; i++ ) {\n\t\tvar item = array[i];\n\t\tif ( item.id.toString() === selectId.toString() ) {\n\t\t\tvar new_row = {};\n\t\t\tif ( typeof item.parent != 'undefined' ) {\n\t\t\t\tnew_row = { parent_id: item.parent.toString(), name: item.name };\n\t\t\t} else {\n\t\t\t\tnew_row = { name: item.name };\n\t\t\t}\n\n\t\t\t//Without created and updated info, audit tab shows N/A for both\n\t\t\tif ( typeof item.created_by != 'undefined' ) {\n\t\t\t\tnew_row.created_by = item.created_by;\n\t\t\t\tnew_row.created_date = item.created_date;\n\t\t\t\tnew_row.updated_by = item.updated_by;\n\t\t\t\tnew_row.updated_date = item.updated_date;\n\t\t\t}\n\n\t\t\tretval.push( new_row );\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn retval;\n\n};\n\nGlobal.addFirstItemToArray = function( array, firstItemType, customLabel ) {\n\t//Error: Unable to get property 'unshift' of undefined or null reference in /interface/html5/global/Global.js?v=8.0.0-20141230-153942 line 903\n\tvar label;\n\tif ( array ) {\n\t\tif ( firstItemType === 'any' ) {\n\t\t\tif ( customLabel ) {\n\t\t\t\tlabel = customLabel;\n\t\t\t} else {\n\t\t\t\tlabel = Global.any_item;\n\t\t\t}\n\t\t\t//#2301 - don't duplicate the --Any-- case when the array is recycled.\n\t\t\tif ( !array[0] || array[0].value != _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.not_exist_id */ .d.not_exist_id ) {\n\t\t\t\tarray.unshift( {\n\t\t\t\t\tlabel: label,\n\t\t\t\t\tvalue: _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.not_exist_id */ .d.not_exist_id,\n\t\t\t\t\tfullValue: _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.not_exist_id */ .d.not_exist_id,\n\t\t\t\t\torderValue: ''\n\t\t\t\t} );\n\t\t\t}\n\t\t} else if ( firstItemType === 'empty' ) {\n\t\t\tif ( customLabel ) {\n\t\t\t\tlabel = customLabel;\n\t\t\t} else {\n\t\t\t\tlabel = Global.empty_item;\n\t\t\t}\n\t\t\t//#2301 - don't duplicate the --None-- case when the array is recycled.\n\t\t\tif ( !array[0] || array[0].value != _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.zero_id */ .d.zero_id ) {\n\t\t\t\tarray.unshift( {\n\t\t\t\t\tlabel: label,\n\t\t\t\t\tvalue: _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.zero_id */ .d.zero_id,\n\t\t\t\t\tfullValue: _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.zero_id */ .d.zero_id,\n\t\t\t\t\torderValue: ''\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn array;\n};\n\n//Add item on to the end of the array, but make sure its not already there and therefore never duplicated.\nGlobal.addLastItemToArray = function( array, key, label ) {\n\tvar label;\n\tif ( array ) {\n\t\tvar last_array_element = array[( array.length - 1 )];\n\t\tif ( last_array_element.value != key ) {\n\t\t\tarray.push( {\n\t\t\t\tfullValue: key,\n\t\t\t\tvalue: key,\n\t\t\t\tlabel: label,\n\t\t\t\tid: 2000\n\t\t\t} );\n\t\t}\n\t}\n\n\treturn array;\n};\n\nGlobal.convertRecordArrayToOptions = function( array ) {\n\tvar len = array.length;\n\tvar options = {};\n\n\tfor ( var i = 0; i < len; i++ ) {\n\t\tvar item = array[i];\n\n\t\toptions[item.value] = item.label;\n\t}\n\n\treturn options;\n};\n\nGlobal.buildColumnArray = function( array ) {\n\tvar columns = [];\n\tvar id = 1000;\n\n\tfor ( var key in array ) {\n\t\tvar order_value = Global.getSortValue( key, true );\n\t\tvar column = {\n\t\t\tlabel: array[key],\n\t\t\tvalue: Global.removeSortPrefix( key ),\n\t\t\torderValue: order_value,\n\t\t\tid: id\n\t\t};\n\t\tcolumns.push( column );\n\t\tid = id + 1;\n\t}\n\treturn columns;\n};\n\nGlobal.removeSortPrefixFromArray = function( array ) {\n\tvar finalArray = {};\n\n\tif ( Global.isSet( array ) ) {\n\n\t\t$.each( array, function( key, item ) {\n\t\t\tfinalArray[Global.removeSortPrefix( key )] = item;\n\t\t} );\n\n\t\treturn finalArray;\n\t}\n\n\treturn array;\n};\n\nGlobal.removeSortPrefix = function( key ) {\n\tif ( typeof key == 'string' && key.match( Global.sortOrderRegex ) ) {\n\t\tkey = key.replace( Global.sortOrderRegex, '' );\n\t}\n\treturn key;\n};\n\nGlobal.getSortValue = function( key, return_key_on_null ) {\n\tvar order_value = 999;\n\tif ( typeof key == 'string' ) {\n\t\tvar regex_result = key.match( Global.sortOrderRegex );\n\t\tif ( regex_result == null ) {\n\t\t\tif ( return_key_on_null === true ) {\n\t\t\t\torder_value = key;\n\t\t\t}\n\t\t} else if ( regex_result[1] ) {\n\t\t\torder_value = regex_result[1];\n\t\t} else {\n\t\t\tDebug.Error( 'Error: Unable to parse order_value', 'Global', 'Global', 'buildColumnArray', 10 );\n\t\t}\n\t}\n\treturn order_value;\n};\n\nGlobal.convertToNumberIfPossible = function( val ) {\n\t//if value is number convert to number type\n\tvar reg = new RegExp( '^[0-9]*$' );\n\n\tif ( reg.test( val ) && val !== '00' ) {\n\t\tval = parseFloat( val );\n\t}\n\n\tif ( val === '-1' || val === -1 ) {\n\t\tval = -1;\n\t}\n\n\treturn val;\n};\n\nGlobal.buildRecordArray = function( array, first_item, orderType ) {\n\tvar finalArray = [];\n\n\tif ( first_item ) {\n\t\tfinalArray.push( first_item );\n\t}\n\n\tvar id = 1000;\n\n\tif ( Global.isSet( array ) ) {\n\n\t\tfor ( var key in array ) {\n\t\t\tvar item = array[key];\n\t\t\tvar value = Global.removeSortPrefix( key );\n\t\t\tvar order_value = Global.getSortValue( key );\n\n\t\t\t// 6/4 changed id to same as value to make flex show correct data when show search result saved in html5, flex use id if it existed.\n\t\t\tvar record = { label: item, value: value, fullValue: key, orderValue: order_value, id: value };\n\n\t\t\tid = id + 1;\n\n\t\t\tfinalArray.push( record );\n\n\t\t}\n\n\t}\n\n\treturn finalArray;\n\n};\n\nGlobal.topContainer = function() {\n\treturn $( '#topContainer' );\n};\n\nGlobal.overlay = function() {\n\treturn $( '#overlay' );\n};\n\nGlobal.bottomContainer = function() {\n\treturn $( '#bottomContainer' );\n};\n\nGlobal.bottomFeedbackLinkContainer = function() {\n\treturn $( '#feedbackLinkContainer' );\n};\n\nGlobal.showPoweredBy = function() {\n\tvar powered_by_img = $( '#powered_by' );\n\tpowered_by_img.show();\n\tpowered_by_img.attr( 'src', _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.getURLByObjectType */ .n.getURLByObjectType( 'copyright' ) );\n\tpowered_by_img.attr( 'alt', LocalCacheData.loginData.application_name + ' Workforce Management Software' );\n\tvar powered_by_link = $( '' );\n\tpowered_by_link.addClass( 'powered-by-img-seo' );\n\tpowered_by_img.wrap( powered_by_link );\n};\n\nGlobal.setSignalStrength = function() {\n\tif ( Global.signal_timer ) {\n\t\treturn;\n\t}\n\t$( '.signal-strength' ).css( 'display', 'block' );\n\tvar status = '......';\n\tvar average_time = 0;\n\tvar checking_array = [];\n\tvar single_strength = null;\n\tvar single_strength_tooltip = null;\n\n\tsetTooltip();\n\n\tsetTimeout( function() {\n\t\tdoPing();\n\t}, 10000 );\n\tGlobal.signal_timer = setInterval( function() {\n\t\tdoPing();\n\t}, 60000 );\n\n\tfunction doPing() {\n\t\tif ( ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.viewId === 'LoginView' ) || Global.idle_time >= Math.min( 15, APIGlobal.pre_login_data.session_idle_timeout / 60 ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tping( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.base_url */ .n.base_url + 'interface/ping.html?t=' + new Date().getTime(), function( time ) {\n\t\t\t$( '.signal-strength-empty' ).removeClass( 'signal-strength-empty' );\n\n\t\t\tif ( checking_array.length >= 3 ) {\n\t\t\t\tchecking_array.shift();\n\t\t\t}\n\t\t\tchecking_array.push( time );\n\t\t\tvar total_time = 0;\n\t\t\tfor ( var i = 0; i < checking_array.length; i++ ) {\n\t\t\t\ttotal_time = checking_array[i] + total_time;\n\t\t\t}\n\t\t\taverage_time = total_time / checking_array.length;\n\t\t\tDebug.Text( 'Current Ping: ' + time + 'ms Average: ' + average_time + 'ms Date: ' + ( new Date ).toISOString().replace( /z|t/gi, ' ' ), 'Global.js', '', 'doPing', 6 );\n\t\t\tGlobal.current_ping = average_time;\n\t\t\tstatus = $.i18n._( 'Good' );\n\t\t\t//do not allow signal strength variation in unit test mode\n\t\t\tif ( Global.UNIT_TEST_MODE == false ) {\n\t\t\t\tif ( average_time > 400 ) {\n\t\t\t\t\t$( '.signal-strength-pretty-strong' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\t$( '.signal-strength-strong' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\t$( '.signal-strength-weak' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\tstatus = $.i18n._( 'Poor' );\n\t\t\t\t} else if ( average_time > 250 ) {\n\t\t\t\t\t$( '.signal-strength-pretty-strong' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\t$( '.signal-strength-strong' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\tstatus = $.i18n._( 'Below Average' );\n\t\t\t\t} else if ( average_time > 150 ) {\n\t\t\t\t\t$( '.signal-strength-pretty-strong' ).addClass( 'signal-strength-empty' );\n\t\t\t\t\tstatus = $.i18n._( 'Average' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsetTooltip();\n\n\t\t} );\n\t}\n\n\tfunction setTooltip() {\n\t\tvar html = '
' + $.i18n._( 'Your Network Connection is' ) + ' ' + status + ' (' + $.i18n._( 'Latency' ) + ': ' + ( average_time > 0 ? average_time.toFixed( 0 ) + 'ms' : $.i18n._( 'Calculating...' ) ) + ')' + '
';\n\t\t$( '.signal-strength' ).qtip( {\n\t\t\tid: 'single_strength',\n\t\t\tcontent: {\n\t\t\t\ttext: html\n\t\t\t},\n\t\t\tposition: {\n\t\t\t\tmy: 'bottom left',\n\t\t\t\tat: 'top right'\n\t\t\t}\n\t\t} );\n\t}\n\n\tfunction ping( url, callback ) {\n\t\tvar inUse, start, img, timer;\n\t\tif ( !inUse ) {\n\t\t\tinUse = true;\n\t\t\timg = new Image();\n\t\t\timg.onload = function() {\n\t\t\t\tvar endTime = new Date().getTime();\n\t\t\t\tinUse = false;\n\t\t\t\tcallback( ( endTime - start ) );\n\n\t\t\t};\n\t\t\timg.onerror = function( e ) {\n\t\t\t\tif ( inUse ) {\n\t\t\t\t\tinUse = false;\n\t\t\t\t\tvar endTime = new Date().getTime();\n\t\t\t\t\tcallback( ( endTime - start ) );\n\t\t\t\t}\n\n\t\t\t};\n\t\t\tstart = new Date().getTime();\n\t\t\timg.src = url;\n\t\t\ttimer = setTimeout( function() {\n\t\t\t\tif ( inUse ) {\n\t\t\t\t\tvar endTime = new Date().getTime();\n\t\t\t\t\tinUse = false;\n\t\t\t\t\tcallback( ( endTime - start ) );\n\t\t\t\t}\n\t\t\t}, 5000 );\n\t\t}\n\t}\n};\n\nGlobal.contentContainer = function() {\n\treturn $( '#contentContainer' );\n};\n\nGlobal.bodyWidth = function() {\n\treturn $( window ).width();\n};\n\nGlobal.bodyHeight = function() {\n\treturn $( window ).height();\n};\n\nGlobal.hasRequireLoaded = function( script_path ) {\n\tvar split_script_path = script_path.split( '/' );\n\n\tvar id = split_script_path[split_script_path.length - 1];\n\tid = id.replace( '.js', '' );\n\n\t//Check alternative script names (ie: with/without the .js) when a full path is specified to see if it was loaded in different ways with requireJS and make sure its not loaded twice.\n\tif ( script_path.indexOf( '.js' ) == -1 ) {\n\t\tvar alternative_script_path = script_path + '.js';\n\t} else {\n\t\tvar alternative_script_path = script_path.replace( '.js', '' );\n\t}\n\n\t//Make sure the function is both specified and defined. This helps cases where the user is on a Slow 3G network and double clicks Attendance -> In/Out.\n\t// In this case the same InOutViewController.js file is in the process of being loaded, then is cancelled,\n\t// and another one tries to load and the success callback where the class is instantiated is called before it can be instantiated, causing a JS exception (ReferenceError: InOutViewController is not defined).\n\t// Better double-click prevention would also help.\n\t// if ( typeof require === 'function' && typeof require.specified === 'function' && ( require.specified( id ) || require.specified( script_path ) || require.specified( alternative_script_path ) ) ) {\n\t// if ( typeof require === 'function' && typeof require.defined === 'function' && ( require.defined( id ) || require.defined( script_path ) || require.defined( alternative_script_path ) ) ) {\n\t// \treturn true;\n\t// //}\n\n\treturn false;\n};\n\nGlobal.loadScript = function( scriptPath, onResult ) {\n\tif ( typeof scriptPath !== 'string' ) {\n\t\t// Not ideal fix but this is to handle the scriptPath.split is not a function error in #2696. if the path is not a string, split does not exist as a function.\n\t\t// Hard to find root-cause/reproduce, so this fix is to reduce the occurances of the JS exceptions related to it.\n\t\treturn false;\n\t}\n\n\tvar async = true;\n\tif ( typeof ( onResult ) === 'undefined' ) {\n\t\tasync = false;\n\t}\n\n\tif ( Global.hasRequireLoaded( scriptPath ) ) {\n\t\tif ( async ) {\n\t\t\tonResult();\n\t\t}\n\t\treturn true;\n\t}\n\n\t//Ensures that the js cached scripts are not loaded twice\n\tif ( async ) {\n\t\tif ( LocalCacheData.loadedScriptNames[scriptPath] ) {\n\t\t\tonResult();\n\t\t\treturn;\n\t\t}\n\t} else {\n\t\tif ( LocalCacheData.loadedScriptNames[scriptPath] ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tvar successflag = false;\n\n\tvar realPath = scriptPath;\n\n\t// Mainly used in the async code, but put here to also catch duplicate declared classes in both async and synchronous calls.\n\tvar split_script_path = realPath.split( '/' );\n\tvar import_file_name = split_script_path[split_script_path.length - 1].replace( '.js', '' );\n\t//var import_path = realPath.replace('views/', '');\n\n\tvar class_exists = eval(\"typeof \"+ import_file_name +\" === 'function'\");\n\tif ( class_exists ) {\n\t\t// This means class already exists on the window object, so it must have been already loaded.\n\t\t// DEV NOTE: This should NOT happen. If it happens, it means script is being loaded twice. Check manual loading calls like requirejs or Webpack MergeIntoSingleFilePlugin plugin\n\t\t// In all likelyhood, it is listed in the concatenation array for MergeIntoSingleFilePlugin. Best to try to remove it from there, as long as its correctly loaded on demand in all relevant places. See what else uses the class to be sure.\n\t\tGlobal.sendAnalyticsEvent( 'error:scriptload:duplicate_class', 'load', 'error:scriptload:duplicate:'+ scriptPath );\n\t\tDebug.Error( 'Duplicate class declaration: '+ import_file_name, 'Global.js', 'Global', 'loadScript', 1 );\n\t\treturn true;\n\t}\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.getBaseURL( Global.url_offset + realPath );\n\t}\n\n\tif ( async ) {\n\t\tDebug.Text( 'ASYNC-LOADING: ' + scriptPath, 'Global.js', 'Global', 'loadScript', 10 );\n\n\t\tvar import_path;\n\t\tif ( scriptPath.indexOf('views') !== -1 ){\n\t\t\timport_path = scriptPath.replace('views/', ''); // This is to ensure the variable in the dynamic webpack import() is a single variable rather than a full path.\n\t\t\t__webpack_require__(1430)(`./${import_path}`).then((module) => {\n\t\t\t\tif ( module && module[import_file_name] ) {\n\t\t\t\t\twindow[import_file_name] = module[import_file_name]; // After html2js this may not be needed anymore. But leave for now as this allows the legacy html files to trigger the 'new MyViewController()' code in their html files.\n\n\t\t\t\t\tLocalCacheData.loadedScriptNames[scriptPath] = true;\n\t\t\t\t\tonResult();\n\t\t\t\t} else {\n\t\t\t\t\tif( import_file_name === 'debugPanelController') {\n\t\t\t\t\t\t// debugPanel is coded different, with no classes/constructor, so this is not a fail.\n\t\t\t\t\t\tLocalCacheData.loadedScriptNames[scriptPath] = true;\n\t\t\t\t\t\tonResult();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Loading class failed.\n\t\t\t\t\t\t// If there is not an attribute matching the class on the module result, then this suggests a missing export on the class. There will also be a default attribute with an empty object to show no default classes exported.\n\t\t\t\t\t\tDebug.Error( 'Loading view class failed. Potential missing export for: ' + import_file_name, 'Global.js', 'Global', 'loadScript', 1 );\n\n\t\t\t\t\t\tonResult(); // To allow callbacks to work for non-module scripts like debugPanelController.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ).catch( Global.importErrorHandler );\n\t\t} else if ( scriptPath.indexOf('global/widgets') !== -1 ) {\n\t\t\timport_path = scriptPath.replace('global/widgets/', ''); // This is to ensure the variable in the dynamic webpack import() is a single variable rather than a full path.\n\t\t\t__webpack_require__(9769)(`./${import_path}`).then((module) => {\n\t\t\t\tif( module && module[import_file_name] ) {\n\t\t\t\t\twindow[import_file_name] = module[import_file_name];\n\t\t\t\t\tLocalCacheData.loadedScriptNames[scriptPath] = true;\n\t\t\t\t\tonResult();\n\t\t\t\t} else {\n\t\t\t\t\t// Loading class failed.\n\t\t\t\t\t// If there is not an attribute matching the class on the module result, then this suggests a missing export on the class. There will also be a default attribute with an empty object to show no default classes exported.\n\t\t\t\t\t// This could also be a widget that is historically meant to load synchronously with the jQuery.ajax code further down. If this is the case, refactor the callback to load the widget syncronously instead.\n\t\t\t\t\tDebug.Error( 'Loading widget class failed. Potential missing export for: '+ import_file_name, 'Global.js', 'Global', 'loadScript', 1 );\n\t\t\t\t}\n\n\t\t\t} ).catch( Global.importErrorHandler );\n\t\t} else {\n\t\t\tDebug.Error( 'Loading class failed. Unhandled file type path request: '+ scriptPath, 'Global.js', 'Global', 'loadScript', 1 );\n\t\t}\n\n\t} else {\n\t\tvar calling_script = '';\n\t\tif ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.viewId ) {\n\t\t\tcalling_script = ' from ' + LocalCacheData.current_open_primary_controller.viewId + 'ViewController';\n\t\t}\n\t\tDebug.Text( 'SYNC-LOADING: ' + scriptPath + calling_script );\n\n\t\tvar id = scriptPath.split( '/' );\n\t\tvar id = id[id.length - 1];\n\t\tid = id.replace( '.js', '' );\n\t\tif ( !window.badScripts ) {\n\t\t\twindow.badScripts = [];\n\t\t}\n\t\twindow.badScripts.push( id ); //When the page is done loading punch \"badScripts into the console to see a nice array of all the scripts that were not loaded async.\n\n\t\t/**\n\t\t * this seems to work, but causes the script erro at line 0 problem.\n\t\t * try to refactor to not use jquery.ajax\n\t\t */\n\t\tjQuery.ajax( {\n\t\t\tasync: false,\n\t\t\ttype: 'GET',\n\t\t\turl: realPath + '?v=' + APIGlobal.pre_login_data.application_build,\n\t\t\tcrossOrigin: false,\n\t\t\tdata: null,\n\t\t\tcache: true,\n\t\t\tsuccess: function() {\n\t\t\t\tsuccessflag = true;\n\t\t\t\tif ( async ) {\n\t\t\t\t\tLocalCacheData.loadedScriptNames[scriptPath] = true;\n\t\t\t\t\tonResult();\n\t\t\t\t}\n\t\t\t},\n\t\t\terror: function( jqXHR, textStatus, errorThrown ) {\n\t\t\t\tTAlertManager.showNetworkErrorAlert( jqXHR, textStatus, errorThrown );\n\t\t\t},\n\t\t\tdataType: 'script'\n\t\t} );\n\t}\n\n\tif ( !async ) {\n\t\tLocalCacheData.loadedScriptNames[scriptPath] = true;\n\t\treturn ( successflag );\n\t}\n\n};\n\nGlobal.importErrorHandler = function( error ) {\n\tif ( error.name == 'ChunkLoadError' ) {\n\t\tif ( window.script_error_shown === undefined ) {\n\t\t\twindow.script_error_shown = 1;\n\t\t\t//There is no pretty errorbox at this time. You may only have basic javascript.\n\t\t\tif ( confirm( 'Unable to download required data. Your internet connection may have failed press Ok to reload.' ) ) {\n\t\t\t\t//For testing, so that there's time to turn internet back on after confirm is clicked.\n\t\t\t\t//window.setTimeout(function() {window.location.reload()},5000);\n\n\t\t\t\t//This can also happen if the user manually modifies the URL to be a bogus ViewId (ie: #!m=homeABC)\n\t\t\t\t//So try to redirect back to the home page first, otherwise try to do a browser reload.\n\t\t\t\tif ( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url && APIGlobal.pre_login_data.base_url ) {\n\t\t\t\t\tGlobal.setURLToBrowser( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url + APIGlobal.pre_login_data.base_url );\n\t\t\t\t} else {\n\t\t\t\t\twindow.location.reload();\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t\tconsole.debug( error.message );\n\t\t//Stop error from bubbling up.\n\t\t// delete e; // commented out from old code as webpack complains about deleting local variable in strict mode.\n\n\t} else {\n\t\tDebug.Error( 'Error loading script during import(): ' + error, 'Global.js', 'Global', 'importErrorHandler', 1 );\n\t\t// Throw general error?\n\t}\n};\n\nGlobal.getRealImagePath = function( path ) {\n\n\tvar realPath = 'theme/' + Global.theme + '/' + path;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\treturn realPath;\n};\n\nGlobal.getRibbonIconRealPath = function( icon ) {\n\tvar realPath = 'theme/' + Global.theme + '/css/global/widgets/ribbon/icons/' + icon;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\treturn realPath;\n};\n\nGlobal.loadLanguage = function( name ) {\n\tvar successflag = false;\n\tvar message_id = _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.generateUUID */ .d.generateUUID();\n\tProgressBar.showProgressBar( message_id );\n\tvar res_data = {};\n\n\tif ( LocalCacheData.getI18nDic() ) {\n\t\tProgressBar.removeProgressBar( message_id );\n\t\treturn LocalCacheData.getI18nDic();\n\t}\n\tvar realPath = '../locale/' + name + '/LC_MESSAGES/messages.json' + '?v=' + APIGlobal.pre_login_data.application_build;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\tjQuery.ajax( {\n\t\tasync: false,\n\t\ttype: 'GET',\n\t\turl: realPath,\n\t\tdata: null,\n\t\tcache: true,\n\t\tconverters: {\n\t\t\t//Because this is a dataType: script, and jquery will blindy try to eval() any result returned by the server, including a HTML 404 error message.\n\t\t\t// resulting in\" Uncaught SyntaxError: Unexpected token < in line 1\" being triggered.\n\t\t\t// Instead just return the raw result and eval() it in the success function ourselves instead.\n\t\t\t'text script': function( text ) {\n\t\t\t\treturn text;\n\t\t\t}\n\t\t},\n\t\tsuccess: function( result ) {\n\t\t\tsuccessflag = true;\n\t\t\tjQuery.globalEval( result );\n\t\t},\n\t\terror: function( jqXHR, textStatus, errorThrown ) {\n\t\t\t//Unable to load or parse i18n dictionary. Could be due to a 404 error?\n\t\t\tDebug.Text( 'Unable to load Locale: ' + errorThrown, 'Global.js', '', 'loadLanguage', 10 );\n\t\t\tsuccessflag = false;\n\t\t},\n\t\tdataType: 'script'\n\t} );\n\n\tProgressBar.removeProgressBar( message_id );\n\n\tif ( successflag ) {\n\t\tLocalCacheData.setI18nDic( i18n_dictionary );\n\t} else {\n\t\tLocalCacheData.setI18nDic( {} );\n\t}\n\n\treturn successflag;\n};\n\nGlobal.getProductEdition = function() {\n\tvar current_company_data = LocalCacheData.getCurrentCompany();\n\n\tif ( current_company_data && current_company_data.product_edition_id ) {\n\t\treturn current_company_data.product_edition_id;\n\t}\n\n\treturn 10; //Community\n};\n\nGlobal.setURLToBrowser = function( new_url ) {\n\tif ( new_url != window.location.href ) {\n\t\tDebug.Text( 'Changing URL to: ' + new_url, 'Global.js', 'Global', 'setURLToBrowser', 9 );\n\t\twindow.location = new_url;\n\t}\n};\n\nGlobal.clone = function( obj ) {\n\treturn jQuery.extend( true, {}, obj ); // true means deep clone, omit for shallow, false is not an option\n};\n\nGlobal.getFirstKeyFromObject = function( obj ) {\n\tfor ( var key in obj ) {\n\n\t\tif ( obj.hasOwnProperty( key ) ) {\n\t\t\treturn key;\n\t\t}\n\n\t}\n};\n\nGlobal.getFuncName = function( _callee ) {\n\tvar _text = _callee.toString();\n\tvar _scriptArr = document.scripts;\n\tfor ( var i = 0; i < _scriptArr.length; i++ ) {\n\t\tvar _start = _scriptArr[i].text.indexOf( _text );\n\t\tif ( _start !== -1 ) {\n\t\t\tif ( /^function\\s*\\(.*\\).*\\r\\n/.test( _text ) ) {\n\t\t\t\tvar _tempArr = _scriptArr[i].text.substr( 0, _start ).split( '\\r\\n' );\n\t\t\t\treturn _tempArr[( _tempArr.length - 1 )].replace( /(var)|(\\s*)/g, '' ).replace( /=/g, '' );\n\t\t\t} else {\n\t\t\t\treturn _text.match( /^function\\s*([^\\(]+).*\\r\\n/ )[1];\n\t\t\t}\n\t\t}\n\t}\n};\n\nGlobal.concatArraysUniqueWithSort = function( thisArray, otherArray ) {\n\tvar newArray = thisArray.concat( otherArray ).sort( function( a, b ) {\n\t\treturn a > b ? 1 : a < b ? -1 : 0;\n\t} );\n\n\treturn newArray.filter( function( item, index ) {\n\t\treturn newArray.indexOf( item ) === index;\n\t} );\n};\n\nGlobal.addCss = function( path, callback ) {\n\tif ( LocalCacheData.loadedScriptNames[path] ) {\n\t\tif ( callback ) {\n\t\t\tcallback();\n\t\t}\n\t\treturn true;\n\t}\n\tLocalCacheData.loadedScriptNames[path] = true;\n\tvar realPath = 'theme/' + Global.theme + '/css/' + path;\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\trealPath = realPath + '?v=' + APIGlobal.pre_login_data.application_build;\n\tGlobal.loadStyleSheet( realPath, callback );\n};\n\n//JS think 0 is false, so use this to get 0 correctly.\nGlobal.isFalseOrNull = function( object ) {\n\n\tif ( object === false || object === null || object === 0 || object === '0' || object == _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.zero_id */ .d.zero_id ) {\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n\n};\n\nGlobal.isSet = function( object ) {\n\n\tif ( _.isUndefined( object ) || _.isNull( object ) ) {\n\t\treturn false;\n\t} else {\n\t\treturn true;\n\t}\n\n};\n\nGlobal.getIconPathByContextName = function( id ) {\n\n\tswitch ( id ) {\n\t\tcase 'add':\n\t\t\treturn Global.getRealImagePath( 'css/global/widgets/ribbon/icons/copy-35x35.png' );\n\t}\n};\n\nGlobal.isEmpty = function( obj ) {\n\n\t// null and undefined are \"empty\"\n\tif ( obj === null ) {\n\t\treturn true;\n\t}\n\n\t// Assume if it has a length property with a non-zero value\n\t// that that property is correct.\n\tif ( obj.length > 0 ) {\n\t\treturn false;\n\t}\n\tif ( obj.length === 0 ) {\n\t\treturn true;\n\t}\n\n\t// Otherwise, does it have any properties of its own?\n\t// Note that this doesn't handle\n\t// toString and valueOf enumeration bugs in IE < 9\n\tfor ( var key in obj ) {\n\t\tif ( hasOwnProperty.call( obj, key ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n\n};\n\nGlobal.convertColumnsTojGridFormat = function( columns, layout_name, setWidthCallBack ) {\n\tvar column_info_array = [];\n\tvar len = columns.length;\n\n\tvar total_width = 0;\n\tfor ( var i = 0; i < len; i++ ) {\n\t\tvar view_column_data = columns[i];\n\t\tvar column_info;\n\n\t\tvar text_width = Global.calculateTextWidth( view_column_data.label );\n\n\t\ttotal_width = total_width + text_width;\n\n\t\tif ( view_column_data.label === '' ) {\n\t\t\tcolumn_info = {\n\t\t\t\tname: view_column_data.value,\n\t\t\t\tindex: view_column_data.value,\n\t\t\t\tlabel: view_column_data.label,\n\t\t\t\tkey: true,\n\t\t\t\twidth: 100,\n\t\t\t\tsortable: false,\n\t\t\t\thidden: true,\n\t\t\t\ttitle: false\n\t\t\t};\n\t\t} else if ( layout_name === 'global_sort_columns' ) {\n\n\t\t\tif ( view_column_data.value === 'sort' ) {\n\t\t\t\tcolumn_info = {\n\t\t\t\t\tname: view_column_data.value,\n\t\t\t\t\tindex: view_column_data.value,\n\t\t\t\t\tlabel: view_column_data.label,\n\t\t\t\t\twidth: 100,\n\t\t\t\t\tsortable: false,\n\t\t\t\t\tformatter: 'select',\n\t\t\t\t\teditable: true,\n\t\t\t\t\ttitle: false,\n\t\t\t\t\tedittype: 'select',\n\t\t\t\t\teditoptions: { value: 'asc:ASC;desc:DESC' }\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tcolumn_info = {\n\t\t\t\t\tname: view_column_data.value,\n\t\t\t\t\tindex: view_column_data.value,\n\t\t\t\t\tlabel: view_column_data.label,\n\t\t\t\t\twidth: 100,\n\t\t\t\t\tsortable: false,\n\t\t\t\t\ttitle: false\n\t\t\t\t};\n\t\t\t}\n\n\t\t} else {\n\t\t\tcolumn_info = {\n\t\t\t\tname: view_column_data.value,\n\t\t\t\tindex: view_column_data.value,\n\t\t\t\tlabel: view_column_data.label,\n\t\t\t\twidth: 100,\n\t\t\t\tsortable: false,\n\t\t\t\ttitle: false\n\t\t\t};\n\t\t}\n\n\t\tcolumn_info_array.push( column_info );\n\t}\n\n\tif ( setWidthCallBack ) {\n\t\tsetWidthCallBack( total_width );\n\t}\n\n\treturn column_info_array;\n};\n/* jshint ignore:start */\nGlobal.loadWidgetByName = function( widgetName, raw_text ) {\n\tvar input = false;\n\tvar widget_path = false;\n\tvar widget_constructor = false;\n\tvar raw_text = false;\n\tswitch ( widgetName ) {\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.COLOR_PICKER:\n\t\t\tinput = $.fn.TColorPicker.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.FORMULA_BUILDER:\n\t\t\tinput = $.fn.FormulaBuilder.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.AWESOME_BOX:\n\t\t\tinput = $.fn.AComboBox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.AWESOME_DROPDOWN:\n\t\t\tinput = $.fn.ADropDown.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TEXT_INPUT:\n\t\t\tinput = $.fn.TTextInput.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.PASSWORD_INPUT:\n\t\t\tinput = $.fn.TPasswordInput.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TEXT:\n\t\t\tinput = $.fn.TText.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.CHECKBOX:\n\t\t\tinput = $.fn.TCheckbox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.COMBO_BOX:\n\t\t\tinput = $.fn.TComboBox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.LIST: //Does not seem to be used anywhere.\n\t\t\tinput = $.fn.TList.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TAG_INPUT:\n\t\t\tinput = $.fn.TTagInput.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.DATE_PICKER:\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.RANGE_PICKER:\n\t\t\tinput = $.fn.TDatePicker.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TIME_PICKER:\n\t\t\tinput = $.fn.TTimePicker.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TEXT_AREA:\n\t\t\tinput = $.fn.TTextArea.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.TINYMCE_TEXT_AREA:\n\t\t\tinput = $.fn.TTextArea.tinymce_html_template;\n\t\t\traw_text = true;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.SEPARATED_BOX:\n\t\t\tinput = $.fn.SeparatedBox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.IMAGE_BROWSER:\n\t\t\tinput = $.fn.TImageBrowser.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.FILE_BROWSER: //There is no file browser JS file for this widget.\n\t\t\tinput = `
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
\n\t\t\t\t\t
`;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.IMAGE_AVD_BROWSER:\n\t\t\tinput = $.fn.TImageAdvBrowser.html_template;\n\t\t\twidget_constructor = 'TImageAdvBrowser';\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.CAMERA_BROWSER:\n\t\t\tinput = $.fn.CameraBrowser.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.IMAGE_CUT:\n\t\t\tinput = $.fn.TImageCutArea.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.IMAGE:\n\t\t\tinput = '';\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.INSIDE_EDITOR:\n\t\t\tinput = $.fn.InsideEditor.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.PAGING:\n\t\t\t// widget_path = 'global/widgets/paging/Paging.html'; // TODO: #3023: Delete this line once all widget html converted and no longer need this quick reference for the old format.\n\t\t\tinput = $.fn.Paging2.html.paging;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.PAGING_2:\n\t\t\t// widget_path = 'global/widgets/paging/Paging2.html'; // TODO: #3023: Delete this line once all widget html converted and no longer need this quick reference for the old format.\n\t\t\tinput = $.fn.Paging2.html.paging2;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.ERROR_TOOLTIP:\n\t\t\tinput = $.fn.ErrorTipBox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.FormItemType.FEEDBACK_BOX:\n\t\t\tinput = $.fn.TFeedback.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.EDIT_VIEW_FORM_ITEM: //There is no file browser JS file for this widget.\n\t\t\tinput = `\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t
`;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.EDIT_VIEW_SUB_FORM_ITEM: //There is no file browser JS file for this widget.\n\t\t\tinput = `\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t
`;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.NO_RESULT_BOX:\n\t\t\tinput = $.fn.NoResultBox.html_template;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.VIEW_MIN_TAB:\n\t\t\tinput = $.fn.ViewMinTabBar.html.tab;\n\t\t\tbreak;\n\t\tcase _global_widgets_search_panel_FormItemType__WEBPACK_IMPORTED_MODULE_2__.WidgetNamesDic.VIEW_MIN_TAB_BAR:\n\t\t\tinput = $.fn.ViewMinTabBar.html.tab_bar;\n\t\t\tbreak;\n\t}\n\n\tif ( widget_path != false ) {\n\t\tinput = Global.loadWidget( widget_path );\n\t}\n\n\tif ( input && raw_text == true ) {\n\t\treturn input;\n\t} else {\n\t\t//#2571 - Error: Unable to get property 'indexOf' of undefined or null reference\n\t\tif ( input && input.indexOf( '<' ) != -1 ) {\n\t\t\tif ( !raw_text ) {\n\t\t\t\tinput = $( input );\n\n\t\t\t\tif ( widget_constructor && !input[widget_constructor] ) {\n\t\t\t\t\tvar error_string = $.i18n._( 'Class could not be found for' ) + ': ' + widgetName + '. ' + $.i18n._( 'Check that class is properly required.' );\n\t\t\t\t\tthrow( new Error( error_string ) );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t//See comment in Global.loadWidget() regarding return null return values.\n\t\t\tvar error_string = $.i18n._( 'Network error, failed to load' ) + ': ' + widgetName + ' ' + $.i18n._( 'Result' ) + ': \"' + input + '\"';\n\t\t\tTAlertManager.showNetworkErrorAlert( { status: 999 }, error_string, null ); //Show the user an error popoup.\n\t\t\tthrow( new Error( error_string ) ); //Halt execution and ensure that the email has a good error message because of failure of web server to provide the requested file.\n\t\t}\n\n\t\treturn input;\n\t}\n};\n\n/* jshint ignore:end */\n\nGlobal.loadWidget = function( url ) {\n\tif ( LocalCacheData.loadedWidgetCache[url] ) {\n\t\treturn ( LocalCacheData.loadedWidgetCache[url] );\n\t}\n\n\tvar realPath = url + '?v=' + APIGlobal.pre_login_data.application_build;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\tvar message_id = _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.generateUUID */ .d.generateUUID();\n\tProgressBar.showProgressBar( message_id );\n\tvar successflag = false;\n\tvar responseData = $.ajax( {\n\t\tasync: false,\n\t\ttype: 'GET',\n\t\turl: realPath,\n\t\tdata: null,\n\t\tcache: true,\n\t\tsuccess: function() {\n\t\t\tsuccessflag = true;\n\t\t},\n\t\terror: function( jqXHR, textStatus, errorThrown ) {\n\t\t\tTAlertManager.showNetworkErrorAlert( jqXHR, textStatus, errorThrown );\n\t\t}\n\t} );\n\n\tProgressBar.removeProgressBar( message_id );\n\t//Error: Uncaught ReferenceError: responseText is not defined in interface/html5/global/Global.js?v=9.0.2-20151106-092147 line 1747\n\t// Upon further investigation (IRC discussions on #jQuery) it was suggested to stop using 'async: false' as that could be whats causing a null return value when we are expecting a jqXHR object.\n\t// Since the ultimate goal is to refactor things so .html is embedded in the .js files anyways, may as well just wait for that.\n\tif ( !responseData ) {\n\t\treturn null;\n\t} else {\n\t\tLocalCacheData.loadedWidgetCache[url] = responseData.responseText;\n\t\treturn ( responseData.responseText );\n\t}\n\n};\n\nGlobal.removeCss = function( path ) {\n\tvar realPath = 'theme/' + Global.theme + '/css/' + path;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\t$( 'link[href=\\'\\' + realPath + \\'?v=\\' + APIGlobal.pre_login_data.application_build + \\'\\']' ).remove();\n};\n\n/* jshint ignore:start */\n\nGlobal.getViewPathByViewId = function( viewId ) {\n\tvar path;\n\tswitch ( viewId ) {\n\t\t//Recruitment Portal\n\t\tcase 'GridTest':\n\t\tcase 'WidgetTest':\n\t\tcase 'AwesomeboxTest':\n\t\t\tpath = 'views/developer_tools/';\n\t\t\tbreak;\n\t\tcase 'MyProfile':\n\t\t\tpath = 'views/portal/hr/my_profile/';\n\t\t\tbreak;\n\t\tcase 'MyJobApplication':\n\t\t\tpath = 'views/portal/hr/my_jobapplication/';\n\t\t\tbreak;\n\t\tcase 'MyProfileEmployment':\n\t\t\tpath = 'views/portal/hr/my_profile/';\n\t\t\tbreak;\n\n\t\tcase 'Map':\n\t\t\tpath = 'views/attendance/map/';\n\t\t\tbreak;\n\t\tcase 'ManualTimeSheet':\n\t\t\tpath = 'views/attendance/manual_timesheet/';\n\t\t\tbreak;\n\t\tcase 'Home':\n\t\t\tpath = 'views/home/dashboard/';\n\t\t\tbreak;\n\t\tcase 'PortalJobVacancyDetail':\n\t\tcase 'PortalJobVacancy':\n\t\t\tpath = 'views/portal/hr/recruitment/';\n\t\t\tbreak;\n\t\tcase 'PortalLogin':\n\t\t\tpath = 'views/portal/login/';\n\t\t\tbreak;\n\t\tcase 'QuickPunchLogin':\n\t\t\tpath = 'views/quick_punch/login/';\n\t\t\tbreak;\n\t\tcase 'QuickPunch':\n\t\t\tpath = 'views/quick_punch/punch/';\n\t\t\tbreak;\n\t\tcase 'UserDateTotalParent':\n\t\tcase 'UserDateTotal':\n\t\t\tpath = 'views/attendance/timesheet/';\n\t\t\tbreak;\n\t\tcase 'Product':\n\t\t\tpath = 'views/invoice/products/';\n\t\t\tbreak;\n\t\tcase 'InvoiceDistrict':\n\t\t\tpath = 'views/invoice/district/';\n\t\t\tbreak;\n\t\tcase 'PaymentGateway':\n\t\t\tpath = 'views/invoice/payment_gateway/';\n\t\t\tbreak;\n\t\tcase 'InvoiceConfig':\n\t\t\tpath = 'views/invoice/settings/';\n\t\t\tbreak;\n\t\tcase 'ShippingPolicy':\n\t\t\tpath = 'views/invoice/shipping_policy/';\n\t\t\tbreak;\n\t\tcase 'AreaPolicy':\n\t\t\tpath = 'views/invoice/area_policy/';\n\t\t\tbreak;\n\t\tcase 'TaxPolicy':\n\t\t\tpath = 'views/invoice/tax_policy/';\n\t\t\tbreak;\n\t\tcase 'ClientGroup':\n\t\t\tpath = 'views/invoice/client_group/';\n\t\t\tbreak;\n\t\tcase 'ProductGroup':\n\t\t\tpath = 'views/invoice/product_group/';\n\t\t\tbreak;\n\t\tcase 'Exception':\n\t\t\tpath = 'views/attendance/exceptions/';\n\t\t\tbreak;\n\t\tcase 'Employee':\n\t\t\tpath = 'views/employees/employee/';\n\t\t\tbreak;\n\t\tcase 'RemittanceDestinationAccount':\n\t\t\tpath = 'views/employees/remittance_destination_account/';\n\t\t\tbreak;\n\t\tcase 'Wage':\n\t\t\tpath = 'views/company/wage/';\n\t\t\tbreak;\n\t\tcase 'Login':\n\t\t\tpath = 'views/login/';\n\t\t\tbreak;\n\t\tcase 'TimeSheet':\n\t\t\tpath = 'views/attendance/timesheet/';\n\t\t\tbreak;\n\t\tcase 'InOut':\n\t\t\tpath = 'views/attendance/in_out/';\n\t\t\tbreak;\n\t\tcase 'RecurringScheduleControl':\n\t\t\tpath = 'views/attendance/recurring_schedule_control/';\n\t\t\tbreak;\n\t\tcase 'RecurringScheduleTemplateControl':\n\t\t\tpath = 'views/attendance/recurring_schedule_template_control/';\n\t\t\tbreak;\n\t\tcase 'ScheduleShift':\n\t\tcase 'Schedule':\n\t\t\tpath = 'views/attendance/schedule/';\n\t\t\tbreak;\n\t\tcase 'Accrual':\n\t\t\tpath = 'views/attendance/accrual/';\n\t\t\tbreak;\n\t\tcase 'AccrualBalance':\n\t\t\tpath = 'views/attendance/accrual_balance/';\n\t\t\tbreak;\n\t\tcase 'Punches':\n\t\t\tpath = 'views/attendance/punches/';\n\t\t\tbreak;\n\t\tcase 'PunchTagGroup':\n\t\tcase 'PunchTag':\n\t\t\tpath = 'views/attendance/punch_tag/';\n\t\t\tbreak;\n\t\tcase 'JobGroup':\n\t\tcase 'Job':\n\t\t\tpath = 'views/attendance/job/';\n\t\t\tbreak;\n\t\tcase 'JobItemGroup':\n\t\tcase 'JobItem':\n\t\t\tpath = 'views/attendance/job_item/';\n\t\t\tbreak;\n\t\tcase 'JobItemAmendment':\n\t\t\tpath = 'views/attendance/job_item_amendment/';\n\t\t\tbreak;\n\t\tcase 'UserTitle':\n\t\t\tpath = 'views/employees/user_title/';\n\t\t\tbreak;\n\t\tcase 'UserContact':\n\t\t\tpath = 'views/employees/user_contact/';\n\t\t\tbreak;\n\t\tcase 'UserPreference':\n\t\t\tpath = 'views/employees/user_preference/';\n\t\t\tbreak;\n\t\tcase 'UserGroup':\n\t\t\tpath = 'views/employees/user_group/';\n\t\t\tbreak;\n\t\tcase 'Log':\n\t\t\tpath = 'views/core/log/';\n\t\t\tbreak;\n\t\tcase 'UserDefault':\n\t\t\tpath = 'views/employees/user_default/';\n\t\t\tbreak;\n\t\tcase 'ROE':\n\t\t\tpath = 'views/employees/roe/';\n\t\t\tbreak;\n\t\tcase 'Company':\n\t\t\tpath = 'views/company/company/';\n\t\t\tbreak;\n\t\tcase 'Companies':\n\t\t\tpath = 'views/company/companies/';\n\t\t\tbreak;\n\t\tcase 'PayPeriodSchedule':\n\t\t\tpath = 'views/payperiod/';\n\t\t\tbreak;\n\t\tcase 'PayPeriods':\n\t\t\tpath = 'views/payroll/pay_periods/';\n\t\t\tbreak;\n\t\tcase 'LegalEntity':\n\t\t\tpath = 'views/company/legal_entity/';\n\t\t\tbreak;\n\t\tcase 'PayrollRemittanceAgencyEvent':\n\t\tcase 'PayrollRemittanceAgency':\n\t\t\tpath = 'views/company/payroll_remittance_agency/';\n\t\t\tbreak;\n\t\tcase 'RemittanceSourceAccount':\n\t\t\tpath = 'views/company/remittance_source_account/';\n\t\t\tbreak;\n\t\tcase 'Branch':\n\t\t\tpath = 'views/company/branch/';\n\t\t\tbreak;\n\t\tcase 'GEOFence':\n\t\t\tpath = 'views/company/geo_fence/';\n\t\t\tbreak;\n\t\tcase 'Department':\n\t\t\tpath = 'views/company/department/';\n\t\t\tbreak;\n\t\tcase 'HierarchyControl':\n\t\t\tpath = 'views/company/hierarchy_control/';\n\t\t\tbreak;\n\t\tcase 'WageGroup':\n\t\t\tpath = 'views/company/wage_group/';\n\t\t\tbreak;\n\t\tcase 'EthnicGroup':\n\t\t\tpath = 'views/company/ethnic_group/';\n\t\t\tbreak;\n\t\tcase 'Currency':\n\t\tcase 'CurrencyRate':\n\t\t\tpath = 'views/company/currency/';\n\t\t\tbreak;\n\t\tcase 'PermissionControl':\n\t\t\tpath = 'views/company/permission_control/';\n\t\t\tbreak;\n\t\tcase 'CustomField':\n\t\t\tpath = 'views/company/custom_field/';\n\t\t\tbreak;\n\t\tcase 'Station':\n\t\t\tpath = 'views/company/station/';\n\t\t\tbreak;\n\t\tcase 'PayStub':\n\t\t\tpath = 'views/payroll/pay_stub/';\n\t\t\tbreak;\n\t\tcase 'PayStubTransaction':\n\t\t\tpath = 'views/payroll/pay_stub_transaction/';\n\t\t\tbreak;\n\t\tcase 'GovernmentDocument':\n\t\t\tpath = 'views/payroll/government_document/';\n\t\t\tbreak;\n\t\tcase 'Request':\n\t\t\tpath = 'views/my_account/request/';\n\t\t\tbreak;\n\t\tcase 'ChangePassword':\n\t\t\tpath = 'views/my_account/password/';\n\t\t\tbreak;\n\t\tcase 'RequestAuthorization':\n\t\t\tpath = 'views/my_account/request_authorization/';\n\t\t\tbreak;\n\t\tcase 'TimeSheetAuthorization':\n\t\t\tpath = 'views/my_account/timesheet_authorization/';\n\t\t\tbreak;\n\t\tcase 'MessageControl':\n\t\t\tpath = 'views/my_account/message_control/';\n\t\t\tbreak;\n\t\tcase 'Notification':\n\t\t\tpath = 'views/my_account/notification/';\n\t\t\tbreak;\n\t\tcase 'LoginUserContact':\n\t\t\tpath = 'views/my_account/user_contact/';\n\t\t\tbreak;\n\t\tcase 'LoginUserPreference':\n\t\t\tpath = 'views/my_account/user_preference/';\n\t\t\tbreak;\n\t\tcase 'LoginUserExpense':\n\t\tcase 'ExpenseAuthorization':\n\t\t\tpath = 'views/my_account/expense/';\n\t\t\tbreak;\n\t\tcase 'PayStubAmendment':\n\t\t\tpath = 'views/payroll/pay_stub_amendment/';\n\t\t\tbreak;\n\t\tcase 'RecurringPayStubAmendment':\n\t\t\tpath = 'views/payroll/recurring_pay_stub_amendment/';\n\t\t\tbreak;\n\t\tcase 'PayStubEntryAccount':\n\t\t\tpath = 'views/payroll/pay_stub_entry_account/';\n\t\t\tbreak;\n\t\tcase 'CompanyTaxDeduction':\n\t\t\tpath = 'views/payroll/company_tax_deduction/';\n\t\t\tbreak;\n\t\tcase 'UserExpense':\n\t\t\tpath = 'views/payroll/user_expense/';\n\t\t\tbreak;\n\t\tcase 'PolicyGroup':\n\t\t\tpath = 'views/policy/policy_group/';\n\t\t\tbreak;\n\t\tcase 'PayCode':\n\t\t\tpath = 'views/policy/pay_code/';\n\t\t\tbreak;\n\t\tcase 'PayFormulaPolicy':\n\t\t\tpath = 'views/policy/pay_formula_policy/';\n\t\t\tbreak;\n\t\tcase 'ContributingPayCodePolicy':\n\t\t\tpath = 'views/policy/contributing_pay_code_policy/';\n\t\t\tbreak;\n\t\tcase 'ContributingShiftPolicy':\n\t\t\tpath = 'views/policy/contributing_shift_policy/';\n\t\t\tbreak;\n\t\tcase 'RoundIntervalPolicy':\n\t\t\tpath = 'views/policy/round_interval_policy/';\n\t\t\tbreak;\n\t\tcase 'MealPolicy':\n\t\t\tpath = 'views/policy/meal_policy/';\n\t\t\tbreak;\n\t\tcase 'BreakPolicy':\n\t\t\tpath = 'views/policy/break_policy/';\n\t\t\tbreak;\n\t\tcase 'RegularTimePolicy':\n\t\t\tpath = 'views/policy/regular_time_policy/';\n\t\t\tbreak;\n\t\tcase 'ExpensePolicy':\n\t\t\tpath = 'views/policy/expense_policy/';\n\t\t\tbreak;\n\t\tcase 'OvertimePolicy':\n\t\t\tpath = 'views/policy/overtime_policy/';\n\t\t\tbreak;\n\t\tcase 'AbsencePolicy':\n\t\t\tpath = 'views/policy/absence_policy/';\n\t\t\tbreak;\n\t\tcase 'PremiumPolicy':\n\t\t\tpath = 'views/policy/premium_policy/';\n\t\t\tbreak;\n\t\tcase 'ExceptionPolicyControl':\n\t\t\tpath = 'views/policy/exception_policy/';\n\t\t\tbreak;\n\n\t\tcase 'RecurringHoliday':\n\t\t\tpath = 'views/policy/recurring_holiday/';\n\t\t\tbreak;\n\t\tcase 'HolidayPolicy':\n\t\t\tpath = 'views/policy/holiday_policy/';\n\t\t\tbreak;\n\t\tcase 'Holiday':\n\t\t\tpath = 'views/policy/holiday/';\n\t\t\tbreak;\n\t\tcase 'SchedulePolicy':\n\t\t\tpath = 'views/policy/schedule_policy/';\n\t\t\tbreak;\n\t\tcase 'AccrualPolicy':\n\t\tcase 'AccrualPolicyAccount':\n\t\tcase 'AccrualPolicyUserModifier':\n\t\t\tpath = 'views/policy/accrual_policy/';\n\t\t\tbreak;\n\t\tcase 'DocumentRevision':\n\t\tcase 'Document':\n\t\tcase 'DocumentGroup':\n\t\t\tpath = 'views/document/';\n\t\t\tbreak;\n\t\tcase 'About':\n\t\t\tpath = 'views/help/';\n\t\t\tbreak;\n\t\tcase 'ActiveShiftReport':\n\t\t\tpath = 'views/reports/whos_in_summary/';\n\t\t\tbreak;\n\t\tcase 'UserSummaryReport':\n\t\t\tpath = 'views/reports/employee_information/';\n\t\t\tbreak;\n\t\tcase 'SavedReport':\n\t\t\tpath = 'views/reports/saved_report/';\n\t\t\tbreak;\n\t\tcase 'ReportSchedule':\n\t\t\tpath = 'views/reports/report_schedule/';\n\t\t\tbreak;\n\t\tcase 'ScheduleSummaryReport':\n\t\t\tpath = 'views/reports/schedule_summary/';\n\t\t\tbreak;\n\t\tcase 'TimesheetSummaryReport':\n\t\t\tpath = 'views/reports/timesheet_summary/';\n\t\t\tbreak;\n\t\tcase 'TimesheetDetailReport':\n\t\t\tpath = 'views/reports/timesheet_detail/';\n\t\t\tbreak;\n\t\tcase 'PunchSummaryReport':\n\t\t\tpath = 'views/reports/punch_summary/';\n\t\t\tbreak;\n\t\tcase 'ExceptionSummaryReport':\n\t\t\tpath = 'views/reports/exception_summary/';\n\t\t\tbreak;\n\t\tcase 'PayStubTransactionSummaryReport':\n\t\t\tpath = 'views/reports/pay_stub_transaction_summary/';\n\t\t\tbreak;\n\t\tcase 'PayStubSummaryReport':\n\t\t\tpath = 'views/reports/pay_stub_summary/';\n\t\t\tbreak;\n\t\tcase 'KPI':\n\t\tcase 'KPIGroup':\n\t\tcase 'UserReviewControl':\n\t\t\tpath = 'views/hr/kpi/';\n\t\t\tbreak;\n\t\tcase 'QualificationGroup':\n\t\tcase 'Qualification':\n\t\tcase 'UserSkill':\n\t\tcase 'UserEducation':\n\t\tcase 'UserMembership':\n\t\tcase 'UserLicense':\n\t\tcase 'UserLanguage':\n\t\t\tpath = 'views/hr/qualification/';\n\t\t\tbreak;\n\t\tcase 'JobApplication':\n\t\tcase 'JobVacancy':\n\t\tcase 'JobApplicant':\n\t\tcase 'JobApplicantEmployment':\n\t\tcase 'JobApplicantReference':\n\t\tcase 'JobApplicantLocation':\n\t\tcase 'JobApplicantSkill':\n\t\tcase 'JobApplicantEducation':\n\t\tcase 'JobApplicantMembership':\n\t\tcase 'JobApplicantLicense':\n\t\tcase 'JobApplicantLanguage':\n\t\tcase 'RecruitmentPortalConfig':\n\t\t\tpath = 'views/hr/recruitment/';\n\t\t\tbreak;\n\t\tcase 'PayrollExportReport':\n\t\t\tpath = 'views/reports/payroll_export/';\n\t\t\tbreak;\n\t\tcase 'GeneralLedgerSummaryReport':\n\t\t\tpath = 'views/reports/general_ledger_summary/';\n\t\t\tbreak;\n\t\tcase 'ExpenseSummaryReport':\n\t\t\tpath = 'views/reports/expense_summary/';\n\t\t\tbreak;\n\t\tcase 'AccrualBalanceSummaryReport':\n\t\t\tpath = 'views/reports/accrual_balance_summary/';\n\t\t\tbreak;\n\t\tcase 'JobSummaryReport':\n\t\t\tpath = 'views/reports/job_summary/';\n\t\t\tbreak;\n\t\tcase 'JobAnalysisReport':\n\t\t\tpath = 'views/reports/job_analysis/';\n\t\t\tbreak;\n\t\tcase 'JobInformationReport':\n\t\t\tpath = 'views/reports/job_info/';\n\t\t\tbreak;\n\t\tcase 'JobItemInformationReport':\n\t\t\tpath = 'views/reports/job_item_info/';\n\t\t\tbreak;\n\t\tcase 'InvoiceTransactionSummaryReport':\n\t\t\tpath = 'views/reports/invoice_transaction_summary/';\n\t\t\tbreak;\n\t\tcase 'RemittanceSummaryReport':\n\t\t\tpath = 'views/reports/remittance_summary/';\n\t\t\tbreak;\n\t\tcase 'T4SummaryReport':\n\t\t\tpath = 'views/reports/t4_summary/';\n\t\t\tbreak;\n\t\tcase 'T4ASummaryReport':\n\t\t\tpath = 'views/reports/t4a_summary/';\n\t\t\tbreak;\n\t\tcase 'TaxSummaryReport':\n\t\t\tpath = 'views/reports/tax_summary/';\n\t\t\tbreak;\n\t\tcase 'Form940Report':\n\t\t\tpath = 'views/reports/form940/';\n\t\t\tbreak;\n\t\tcase 'Form941Report':\n\t\t\tpath = 'views/reports/form941/';\n\t\t\tbreak;\n\t\tcase 'Form1099NecReport':\n\t\t\tpath = 'views/reports/form1099/';\n\t\t\tbreak;\n\t\tcase 'FormW2Report':\n\t\t\tpath = 'views/reports/formw2/';\n\t\t\tbreak;\n\t\tcase 'USStateUnemploymentReport':\n\t\t\tpath = 'views/reports/us_state_unemployment/';\n\t\t\tbreak;\n\t\tcase 'AffordableCareReport':\n\t\t\tpath = 'views/reports/affordable_care/';\n\t\t\tbreak;\n\t\tcase 'UserQualificationReport':\n\t\t\tpath = 'views/reports/qualification_summary/';\n\t\t\tbreak;\n\t\tcase 'KPIReport':\n\t\t\tpath = 'views/reports/review_summary/';\n\t\t\tbreak;\n\t\tcase 'UserRecruitmentSummaryReport':\n\t\t\tpath = 'views/reports/recruitment_summary/';\n\t\t\tbreak;\n\t\tcase 'UserRecruitmentDetailReport':\n\t\t\tpath = 'views/reports/recruitment_detail/';\n\t\t\tbreak;\n\t\tcase 'Client':\n\t\t\tpath = 'views/invoice/client/';\n\t\t\tbreak;\n\t\tcase 'ClientContact':\n\t\t\tpath = 'views/invoice/client_contact/';\n\t\t\tbreak;\n\t\tcase 'ClientPayment':\n\t\t\tpath = 'views/invoice/client_payment/';\n\t\t\tbreak;\n\t\tcase 'InvoiceTransaction':\n\t\t\tpath = 'views/invoice/invoice_transaction/';\n\t\t\tbreak;\n\t\tcase 'Invoice':\n\t\t\tpath = 'views/invoice/invoice/';\n\t\t\tbreak;\n\t\tcase 'CustomColumn':\n\t\t\tpath = 'views/reports/custom_column/';\n\t\t\tbreak;\n\t\tcase 'AuditTrailReport':\n\t\t\tpath = 'views/reports/audittrail/';\n\t\t\tbreak;\n\t\tcase 'ReCalculateTimeSheetWizard':\n\t\t\tpath = 'views/wizard/re_calculate_timesheet/';\n\t\t\tbreak;\n\t\tcase 'GeneratePayStubWizard':\n\t\t\tpath = 'views/wizard/generate_pay_stub/';\n\t\t\tbreak;\n\t\tcase 'UserGenericStatus':\n\t\t\tpath = 'views/wizard/user_generic_data_status/';\n\t\t\tbreak;\n\t\tcase 'ProcessPayrollWizard':\n\t\t\tpath = 'views/wizard/process_payroll/';\n\t\t\tbreak;\n\t\tcase 'PayrollRemittanceAgencyEventWizardController':\n\t\t\tpath = 'views/payroll/remittance_wizard/';\n\t\t\tbreak;\n\t\tcase 'ProcessTransactionsWizardController':\n\t\t\tpath = 'views/payroll/process_transactions_wizard/';\n\t\t\tbreak;\n\t\tcase 'ImportCSVWizard':\n\t\t\tpath = 'views/wizard/import_csv/';\n\t\t\tbreak;\n\t\tcase 'JobInvoiceWizard':\n\t\t\tpath = 'views/wizard/job_invoice/';\n\t\t\tbreak;\n\t\tcase 'LoginUserWizard':\n\t\tcase 'LoginUser':\n\t\t\tpath = 'views/wizard/login_user/';\n\t\t\tbreak;\n\t\tcase 'QuickStartWizard':\n\t\t\tpath = 'views/wizard/quick_start/';\n\t\t\tbreak;\n\t\tcase 'UserPhotoWizard':\n\t\t\tpath = 'views/wizard/user_photo/';\n\t\t\tbreak;\n\t\tcase 'FindAvailableWizard':\n\t\tcase 'FindAvailable':\n\t\t\tpath = 'views/wizard/find_available/';\n\t\t\tbreak;\n\t\tcase 'PermissionWizard':\n\t\t\tpath = 'views/wizard/permission_wizard/';\n\t\t\tbreak;\n\t\tcase 'FormulaBuilderWizard':\n\t\t\tpath = 'views/wizard/formula_builder_wizard/';\n\t\t\tbreak;\n\t\tcase 'ReCalculateAccrualWizard':\n\t\t\tpath = 'views/wizard/re_calculate_accrual/';\n\t\t\tbreak;\n\t\tcase 'ResetPasswordWizard':\n\t\t\tpath = 'views/wizard/reset_password/';\n\t\t\tbreak;\n\t\tcase 'ShareReportWizard':\n\t\t\tpath = 'views/wizard/share_report/';\n\t\t\tbreak;\n\t\tcase 'PayCodeWizard':\n\t\t\tpath = 'views/wizard/pay_code/';\n\t\t\tbreak;\n\t\tcase 'InstallWizard':\n\t\t\tpath = 'views/wizard/install/';\n\t\t\tbreak;\n\t\tcase 'PayStubAccountWizard':\n\t\t\tpath = 'views/wizard/pay_stub_account/';\n\t\t\tbreak;\n\t\tcase 'DashletWizard':\n\t\t\tpath = 'views/wizard/dashlet/';\n\t\t\tbreak;\n\t\tcase 'ReportViewWizard':\n\t\t\tpath = 'views/wizard/report_view/';\n\t\t\tbreak;\n\t\tcase 'PortalApplyJobWizard':\n\t\t\tpath = 'views/wizard/portal_apply_job/';\n\t\t\tbreak;\n\t\tcase 'ForgotPasswordWizard':\n\t\t\tpath = 'views/wizard/forgot_password/';\n\t\t\tbreak;\n\t\tcase 'ResetForgotPasswordWizard':\n\t\t\tpath = 'views/wizard/reset_forgot_password/';\n\t\t\tbreak;\n\t\tcase 'DeveloperTools':\n\t\t\tpath = 'views/developer_tools/';\n\t\t\tbreak;\n\t\tcase 'UIKitSample':\n\t\tcase 'UIKitChildSample':\n\t\t\tpath = 'views/ui_kit_sample/';\n\t\t\tbreak;\n\t}\n\treturn path;\n};\n/* jshint ignore:end */\n\n//returns exact filepaths for class dependencies\nGlobal.getViewPreloadPathByViewId = function( viewId ) {\n\t// DEPRECATED: Moved the loading of these preloads to post-login-main_ui-dependancies.js\n\n\tvar preloads = [];\n\t// switch ( viewId ) {\n\t// \tcase 'Request':\n\t// \tcase 'RequestAuthorization':\n\t// \t\tpreloads = ['views/common/AuthorizationHistoryCommon.js', 'views/common/RequestViewCommonController.js', 'views/common/EmbeddedMessageCommon.js'];\n\t// \t\tbreak;\n\t// \tcase 'ExpenseAuthorization':\n\t// \tcase 'UserExpense':\n\t// \tcase 'LoginUserExpense':\n\t// \tcase 'TimeSheetAuthorization':\n\t// \t\tpreloads = ['views/common/AuthorizationHistoryCommon.js'];\n\t// \t\tbreak;\n\t// }\n\treturn preloads;\n};\n\nGlobal.removeViewCss = function( viewId, fileName ) {\n\tGlobal.removeCss( Global.getViewPathByViewId( viewId ) + fileName );\n};\n\nGlobal.sanitizeViewId = function( viewId ) {\n\tif ( typeof viewId === 'string' || viewId instanceof String ) {\n\t\treturn viewId.replace( '/', '' ).replace( '\\\\', '' );\n\t}\n\n\treturn viewId;\n};\n\nGlobal.loadViewSource = function( viewId, fileName, onResult, sync ) {\n\tvar viewId = Global.sanitizeViewId( viewId );\n\tvar path = Global.getViewPathByViewId( viewId );\n\n\tif ( fileName.indexOf( '.js' ) > 0 ) {\n\t\tvar preloads = Global.getViewPreloadPathByViewId( viewId );\n\t\tif ( preloads.length > 0 ) {\n\t\t\tfor ( var p in preloads ) {\n\t\t\t\tGlobal.loadScript( preloads[p] );\n\t\t\t}\n\t\t}\n\n\t\tif ( path ) {\n\t\t\tif ( sync ) {\n\t\t\t\treturn Global.loadScript( path + fileName );\n\t\t\t} else {\n\t\t\t\tGlobal.loadScript( path + fileName, onResult );\n\t\t\t}\n\t\t} else {\n\t\t\t//Invalid viewId, redirect to home page?\n\t\t\tconsole.debug( 'View does not exist! ViewId: ' + viewId + ' File Name: ' + fileName );\n\t\t\tif ( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url && APIGlobal.pre_login_data.base_url ) {\n\t\t\t\tGlobal.setURLToBrowser( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url + APIGlobal.pre_login_data.base_url );\n\t\t\t}\n\t\t}\n\n\t} else if ( fileName.indexOf( '.css' ) > 0 ) {\n\t\tGlobal.addCss( path + fileName );\n\t} else {\n\t\tif ( path ) {\n\t\t\t// HTML2JS\n\t\t\tvar template_type = _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .HtmlTemplatesGlobal.getTemplateTypeFromFilename */ .H.getTemplateTypeFromFilename( fileName );\n\t\t\tvar template_options = _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .HtmlTemplatesGlobal.getTemplateOptionsFromViewId */ .H.getTemplateOptionsFromViewId( viewId );\n\n\t\t\tif( template_type === _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .TemplateType.INLINE_HTML */ .W.INLINE_HTML ) {\n\t\t\t\ttemplate_options.filename = fileName; // Needed by HtmlTemplates.checkViewClassForInlineHtmlbyFilename() which uses filename, not view id.\n\t\t\t}\n\t\t\tif ( sync ) {\n\t\t\t\t// Note: for #HTML2JS This path is taken for things such as: CompanyInformation, CompanyEditView.html, and general edit views.\n\n\t\t\t\t// Check if we should use the new templating logic, or legacy html load.\n\t\t\t\tif( template_type !== _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .TemplateType.LEGACY_HTML */ .W.LEGACY_HTML ) {\n\t\t\t\t\t// Use new HTML2JS template class\n\t\t\t\t\treturn _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .HtmlTemplatesGlobal.getTemplate */ .H.getTemplate( template_type, template_options, null ); // no onResult, as its syncronous.\n\t\t\t\t} else {\n\t\t\t\t\t// Legacy html file load for syncronous files.\n\t\t\t\t\treturn Global.loadPageSync( path + fileName );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Check if we should use the new templating logic, or legacy html load.\n\t\t\t\tif( template_type !== _services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .TemplateType.LEGACY_HTML */ .W.LEGACY_HTML ) {\n\t\t\t\t\t// Use new HTML2JS template class\n\t\t\t\t\t_services_HtmlTemplates__WEBPACK_IMPORTED_MODULE_7__/* .HtmlTemplatesGlobal.getTemplate */ .H.getTemplate( template_type, template_options, onResult );\n\t\t\t\t} else {\n\t\t\t\t\t// Legacy html file load\n\t\t\t\t\tGlobal.loadPage( path + fileName, onResult );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t//Invalid viewId, redirect to home page?\n\t\t\tconsole.debug( 'View does not exist! ViewId: ' + viewId + ' File Name: ' + fileName );\n\t\t\tif ( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url && APIGlobal.pre_login_data.base_url ) {\n\t\t\t\tGlobal.setURLToBrowser( _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url + APIGlobal.pre_login_data.base_url );\n\t\t\t}\n\t\t}\n\t}\n};\n\nGlobal.loadPageSync = function( url ) {\n\n\tvar realPath = url + '?v=' + APIGlobal.pre_login_data.application_build;\n\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\tvar message_id = _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.generateUUID */ .d.generateUUID();\n\tProgressBar.showProgressBar( message_id );\n\tvar successflag = false;\n\tvar responseData = $.ajax( {\n\t\tasync: false,\n\t\ttype: 'GET',\n\t\turl: realPath,\n\t\tdata: null,\n\t\tcache: true,\n\t\tsuccess: function() {\n\t\t\tsuccessflag = true;\n\t\t},\n\n\t\terror: function( jqXHR, textStatus, errorThrown ) {\n\t\t\tTAlertManager.showNetworkErrorAlert( jqXHR, textStatus, errorThrown );\n\t\t}\n\t} );\n\n\tProgressBar.removeProgressBar( message_id );\n\n\treturn ( responseData.responseText );\n\n};\n\nGlobal.loadPage = function( url, onResult ) {\n\n\tvar realPath = url + '?v=' + APIGlobal.pre_login_data.application_build;\n\tvar message_id = _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.generateUUID */ .d.generateUUID();\n\tif ( Global.url_offset ) {\n\t\trealPath = Global.url_offset + realPath;\n\t}\n\n\tProgressBar.showProgressBar( message_id );\n\t$.ajax( {\n\t\tasync: true,\n\t\ttype: 'GET',\n\t\turl: realPath,\n\t\tdata: null,\n\t\tcache: true,\n\t\tsuccess: function( result ) {\n\t\t\tProgressBar.removeProgressBar( message_id );\n\t\t\tonResult( result );\n\t\t},\n\t\terror: function( jqXHR, textStatus, errorThrown ) {\n\t\t\tTAlertManager.showNetworkErrorAlert( jqXHR, textStatus, errorThrown );\n\t\t}\n\t} );\n\n};\n\nGlobal.getRootURL = function( url ) {\n\tif ( !url ) {\n\t\turl = location.href;\n\t}\n\n\t//Rather than parse the URL ourselves, lets use the URL API and build it back up from its components.\n\tvar url_obj = new URL( url );\n\tvar retval = url_obj.protocol + '//' + url_obj.host;\n\n\treturn retval;\n};\n\nGlobal.getBaseURL = function( url_relative_path, include_search = true ) {\n\t//Rather than parse the URL ourselves, lets use the URL API and build it back up from its components.\n\tvar url_obj = new URL( location.href );\n\tvar retval = url_obj.protocol + '//' + url_obj.host + url_obj.pathname;\n\n\t//Resolve any specified relative path here, so we can append the search component of the URL after.\n\t// This is needed for the recruitment portal to work if Facebook or some other 3rd party appends search components on the URL, ie: ?test=1#!m=PortalJobVacancyDetail&id=05a45d0b-b982-2a1f-2003-21ea65522bf3&company_id=ABC\n\tif ( url_relative_path ) {\n\t\tretval = new URL( url_relative_path, retval ).href;\n\t}\n\n\tif ( include_search == true ) {\n\t\tretval += url_obj.search; //Can't put the search component back on when getting BaseURL.\n\t}\n\n\treturn retval;\n};\n\nGlobal.isArrayAndHasItems = function( object ) {\n\n\tif ( $.type( object ) === 'array' && object.length > 0 ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n\n};\n\nGlobal.isValidInputCodes = function( keyCode ) {\n\tvar result = true;\n\tswitch ( keyCode ) {\n\t\tcase 9:\n\t\tcase 16:\n\t\tcase 17:\n\t\tcase 18:\n\t\tcase 19:\n\t\tcase 20:\n\t\tcase 33:\n\t\tcase 34:\n\t\t// case 37:\n\t\t// case 38:\n\t\t// case 39:\n\t\t// case 40:\n\t\tcase 45:\n\t\tcase 91:\n\t\tcase 92:\n\t\tcase 93:\n\t\t\tresult = false;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif ( keyCode >= 112 && keyCode <= 123 ) {\n\t\t\t\tresult = false;\n\t\t\t}\n\t}\n\treturn result;\n};\n\n/* jshint ignore:start */\nGlobal.convertLayoutFilterToAPIFilter = function( layout ) {\n\tvar convert_filter_data = {};\n\n\tif ( !layout ) {\n\t\treturn null;\n\t}\n\n\tvar filter_data = layout.data.filter_data;\n\n\tif ( !filter_data ) {\n\t\treturn null;\n\t}\n\n\t$.each( filter_data, function( key, content ) {\n\t\t// Cannot read property 'value' of undefined\n\t\tif ( !content ) {\n\t\t\treturn;//continue;\n\t\t}\n\t\tif ( ( content.value instanceof Array && content.value.length > 0 ) || ( content.value instanceof Object ) ) {\n\t\t\tvar values = [];\n\t\t\tvar obj = content.value;\n\t\t\tif ( content.value instanceof Array ) {\n\n\t\t\t\tvar len = content.value.length;\n\t\t\t\tfor ( var i = 0; i < len; i++ ) {\n\n\t\t\t\t\tif ( Global.isSet( content.value[i].value ) ) {\n\t\t\t\t\t\tvalues.push( content.value[i].value ); //Options,\n\t\t\t\t\t} else if ( content.value[i].id || content.value[i].id === 0 || content.value[i].id === '0' ) {\n\t\t\t\t\t\tvalues.push( content.value[i].id ); //Awesomebox\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalues.push( content.value[i] ); // default_filter_data_for_next_view\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconvert_filter_data[key] = values;\n\t\t\t\t//only add search filter which not equal to false, see if this cause any bugs\n\t\t\t} else if ( content.value instanceof Object ) {\n\t\t\t\tvar final_value = '';\n\t\t\t\tif ( Global.isSet( content.value.value ) ) {\n\t\t\t\t\tfinal_value = content.value.value; //Options,\n\t\t\t\t} else if ( content.value.id || content.value.id === 0 || content.value.id === '0' ) {\n\t\t\t\t\tfinal_value = content.value.id; //Awesomebox\n\t\t\t\t} else {\n\t\t\t\t\tfinal_value = content.value; // default_filter_data_for_next_view\n\t\t\t\t}\n\n\t\t\t\tconvert_filter_data[key] = final_value;\n\n\t\t\t} else if ( obj.value === false ) {\n\t\t\t\treturn;//continue;\n\t\t\t} else {\n\t\t\t\tif ( Global.isSet( obj.value ) ) {\n\n\t\t\t\t\tconvert_filter_data[key] = obj.value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else if ( filter_data[key].value === false ) {\n\t\t\treturn; //continue;\n\t\t} else if ( Global.isSet( filter_data[key].value ) ) {\n\t\t\tconvert_filter_data[key] = filter_data[key].value;\n\t\t} else {\n\t\t\tconvert_filter_data[key] = filter_data[key];\n\t\t}\n\t} );\n\n\tif ( LocalCacheData.extra_filter_for_next_open_view ) { //MUST removed this when close the view which used this attribute.\n\n\t\tfor ( var key in LocalCacheData.extra_filter_for_next_open_view.filter_data ) {\n\t\t\tconvert_filter_data[key] = LocalCacheData.extra_filter_for_next_open_view.filter_data[key];\n\t\t}\n\n\t}\n\n\treturn convert_filter_data;\n\n};\n/* jshint ignore:end */\n\n//ASC\nGlobal.compare = function( a, b, orderKey, order_type ) {\n\n\tif ( !Global.isSet( order_type ) ) {\n\t\torder_type = 'asc';\n\t}\n\n\tif ( order_type === 'asc' ) {\n\t\tif ( a[orderKey] < b[orderKey] ) {\n\t\t\treturn -1;\n\t\t}\n\t\tif ( a[orderKey] > b[orderKey] ) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\tif ( a[orderKey] < b[orderKey] ) {\n\t\t\treturn 1;\n\t\t}\n\t\tif ( a[orderKey] > b[orderKey] ) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t}\n\n};\n\nGlobal.buildFilter = function() {\n\tvar filterCondition = arguments[0];\n\tvar filter = [];\n\n\tif ( filterCondition ) {\n\n\t\tfor ( var key in filterCondition ) {\n\t\t\tfilter[key] = filterCondition[key];\n\t\t}\n\n\t}\n\n\treturn filter;\n\n};\n\nGlobal.getLoginUserDateFormat = function() {\n\tvar format = 'DD-MMM-YY';\n\n\tif ( LocalCacheData.getLoginUserPreference() ) {\n\t\tformat = LocalCacheData.getLoginUserPreference().date_format;\n\t}\n\n\treturn format;\n};\n/* jshint ignore:start */\nGlobal.formatGridData = function( grid_data, key_name ) {\n\n\tif ( $.type( grid_data ) !== 'array' ) {\n\t\treturn grid_data;\n\t}\n\n\tfor ( var i = 0; i < grid_data.length; i++ ) {\n\t\tfor ( var key in grid_data[i] ) {\n\n\t\t\tif ( !grid_data[i].hasOwnProperty( key ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t//Need to convert custom fields time_unit to string\n\t\t\tif ( key.indexOf( 'custom_field' ) === 0 && Array.isArray( LocalCacheData.current_open_primary_controller.custom_fields ) ) {\n\t\t\t\tlet custom_field = LocalCacheData.current_open_primary_controller.custom_fields.find( ( field ) => {\n\t\t\t\t\treturn field.id === key.replace( 'custom_field-', '' );\n\t\t\t\t} );\n\n\t\t\t\tif ( custom_field && custom_field.type_id == 1300 ) {\n\t\t\t\t\tif ( Global.isNumeric( grid_data[i][key] ) ) {\n\t\t\t\t\t\tgrid_data[i][key] = Global.getTimeUnit( grid_data[i][key] );\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The same format for all views.\n\t\t\tswitch ( key ) {\n\t\t\t\tcase 'maximum_shift_time':\n\t\t\t\tcase 'new_day_trigger_time':\n\t\t\t\tcase 'trigger_time':\n\t\t\t\tcase 'minimum_punch_time':\n\t\t\t\tcase 'maximum_punch_time':\n\t\t\t\tcase 'window_length':\n\t\t\t\tcase 'start_window':\n\t\t\t\tcase 'round_interval':\n\t\t\t\tcase 'grace':\n\t\t\t\tcase 'estimate_time':\n\t\t\t\tcase 'minimum_time':\n\t\t\t\tcase 'maximum_time':\n\t\t\t\tcase 'total_time':\n\t\t\t\tcase 'start_stop_window':\n\t\t\t\t\tif ( Global.isNumeric( grid_data[i][key] ) ) {\n\t\t\t\t\t\tgrid_data[i][key] = Global.getTimeUnit( grid_data[i][key] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgrid_data[i][key] = null; //Prevent string \"false\" from being returned when the column isn't defined on the server side.\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'include_break_punch_time':\n\t\t\t\tcase 'include_multiple_breaks':\n\t\t\t\tcase 'include_lunch_punch_time':\n\t\t\t\tcase 'is_default':\n\t\t\t\tcase 'is_base':\n\t\t\t\tcase 'auto_update':\n\t\t\t\tcase 'currently_employed':\n\t\t\t\tcase 'criminal_record':\n\t\t\t\tcase 'immediate_drug_test':\n\t\t\t\tcase 'is_current_employer':\n\t\t\t\tcase 'is_contact_available':\n\t\t\t\tcase 'enable_pay_stub_balance_display':\n\t\t\t\tcase 'enable_login':\n\t\t\t\tcase 'ytd_adjustment':\n\t\t\t\tcase 'authorized':\n\t\t\t\tcase 'is_reimbursable':\n\t\t\t\tcase 'reimbursable':\n\t\t\t\tcase 'tainted':\n\t\t\t\tcase 'auto_fill':\n\t\t\t\tcase 'private':\n\t\t\t\t\tif ( grid_data[i][key] === true ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'Yes' );\n\t\t\t\t\t} else if ( grid_data[i][key] === false ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'No' );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'override':\n\t\t\t\t\tif ( grid_data[i][key] === true ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'Yes' );\n\t\t\t\t\t\tgrid_data[i]['is_override'] = true;\n\t\t\t\t\t} else if ( grid_data[i][key] === false ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'No' );\n\t\t\t\t\t\tgrid_data[i]['is_override'] = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'is_scheduled':\n\t\t\t\t\tif ( grid_data[i][key] === '1' ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'Yes' );\n\t\t\t\t\t} else if ( grid_data[i][key] === '0' ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'No' );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'in_use':\n\t\t\t\t\tif ( grid_data[i][key] === '1' ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'Yes' );\n\t\t\t\t\t\tgrid_data[i]['is_in_use'] = true;\n\t\t\t\t\t} else if ( grid_data[i][key] === '0' ) {\n\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'No' );\n\t\t\t\t\t\tgrid_data[i]['is_in_use'] = false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif ( grid_data[i][key] === false ) {\n\t\t\t\t\t\tgrid_data[i][key] = '';\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Handle the specially format columns which are not different with others.\n\t\t\tswitch ( key_name ) {\n\t\t\t\tcase 'AccrualPolicyUserModifier':\n\t\t\t\t\tswitch ( key ) {\n\t\t\t\t\t\tcase 'annual_maximum_time_modifier':\n\t\t\t\t\t\t\tif ( grid_data[i]['type_id'] === 20 ) {\n\t\t\t\t\t\t\t\tgrid_data[i][key] = $.i18n._( 'N/A' );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'BreakPolicy':\n\t\t\t\tcase 'MealPolicy':\n\t\t\t\tcase 'Accrual':\n\t\t\t\t\tswitch ( key ) {\n\t\t\t\t\t\tcase 'amount':\n\t\t\t\t\t\t\tif ( Global.isNumeric( grid_data[i][key] ) ) {\n\t\t\t\t\t\t\t\tgrid_data[i][key] = Global.getTimeUnit( grid_data[i][key] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'accrual_balance_summary':\n\t\t\t\tcase 'AccrualBalance':\n\t\t\t\t\tswitch ( key ) {\n\t\t\t\t\t\tcase 'balance':\n\t\t\t\t\t\t\tif ( Global.isNumeric( grid_data[i][key] ) ) {\n\t\t\t\t\t\t\t\tgrid_data[i][key] = Global.getTimeUnit( grid_data[i][key] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'RecurringScheduleControl':\n\t\t\t\t\tswitch ( key ) {\n\t\t\t\t\t\tcase 'end_date':\n\t\t\t\t\t\t\tif ( grid_data[i][key] === '' ) {\n\t\t\t\t\t\t\t\tgrid_data[i][key] = 'Never';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t}\n\t}\n\n\treturn grid_data;\n\n};\n/* jshint ignore:end */\n\n// Commented out as we have now fully refactored the old _super and __super references in the new ES6 code.\n// //make backone support a simple super funciton\n// Backbone.Model.prototype._super = function( funcName ) {\n// \treturn this.constructor.__super__[funcName].apply( this, _.rest( arguments ) );\n// };\n//\n// //make backone support a simple super function\n// Backbone.View.prototype._super = function( funcName ) {\n// \t// Note: If 'Maximum call stack size exceeded' error encountered, and view is extending twice (BaseView->ReportBaseView->SomeRandomView), then make sure you define `this.real_this` at the 2nd level extend. See reportBaseViewController init for example.\n// \tif ( this.real_this && this.real_this.constructor.__super__[funcName] ) {\n// \t\treturn this.real_this.constructor.__super__[funcName].apply( this, _.rest( arguments ) );\n// \t} else {\n// \t\treturn this.constructor.__super__[funcName].apply( this, _.rest( arguments ) );\n// \t}\n//\n// };\n//\n// //make backone support a simple super funciton for second level class\n// Backbone.View.prototype.__super = function( funcName ) {\n// \tif ( !this.real_this ) {\n// \t\tthis.real_this = this.constructor.__super__;\n// \t}\n//\n// \treturn this.constructor.__super__[funcName].apply( this, _.rest( arguments ) );\n//\n// };\n\n/*\n * Date Format 1.2.3\n * (c) 2007-2009 Steven Levithan \n * MIT license\n *\n * Includes enhancements by Scott Trenda \n * and Kris Kowal \n *\n * Accepts a date, a mask, or a date and a mask.\n * Returns a formatted version of the given date.\n * The date defaults to the current date/time.\n * The mask defaults to dateFormat.masks.default.\n */\n\nvar dateFormat = function() {\n\tvar token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\\1?|[LloSZ]|'[^']*\"|'[^']*'/g,\n\t\ttimezone = /\\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\\d{4})?)\\b/g,\n\t\ttimezoneClip = /[^-+\\dA-Z]/g,\n\t\tpad = function( val, len ) {\n\t\t\tval = String( val );\n\t\t\tlen = len || 2;\n\t\t\twhile ( val.length < len ) {\n\t\t\t\tval = '0' + val;\n\t\t\t}\n\t\t\treturn val;\n\t\t};\n\n\t// Regexes and supporting functions are cached through closure\n\n\t/* jshint ignore:start */\n\treturn function( date, mask, utc ) {\n\t\tvar dF = dateFormat;\n\n\t\t// You can't provide utc if you skip other args (use the 'UTC:' mask prefix)\n\t\tif ( arguments.length === 1 && Object.prototype.toString.call( date ) === '[object String]' && !/\\d/.test( date ) ) {\n\t\t\tmask = date;\n\t\t\tdate = undefined;\n\t\t}\n\n\t\t// Passing date through Date applies Date.parse, if necessary\n\t\tdate = date ? new Date( date ) : new Date();\n\t\tif ( isNaN( date ) ) {\n\t\t\tthrow SyntaxError( 'invalid date' );\n\t\t}\n\n\t\tmask = String( dF.masks[mask] || mask || dF.masks['default'] );\n\n\t\t// Allow setting the utc argument via the mask\n\t\tif ( mask.slice( 0, 4 ) === 'UTC:' ) {\n\t\t\tmask = mask.slice( 4 );\n\t\t\tutc = true;\n\t\t}\n\n\t\tvar _ = utc ? 'getUTC' : 'get',\n\t\t\td = date[_ + 'Date'](),\n\t\t\tD = date[_ + 'Day'](),\n\t\t\tm = date[_ + 'Month'](),\n\t\t\ty = date[_ + 'FullYear'](),\n\t\t\tH = date[_ + 'Hours'](),\n\t\t\tM = date[_ + 'Minutes'](),\n\t\t\ts = date[_ + 'Seconds'](),\n\t\t\tL = date[_ + 'Milliseconds'](),\n\t\t\to = utc ? 0 : date.getTimezoneOffset(),\n\t\t\tflags = {\n\t\t\t\td: d,\n\t\t\t\tdd: pad( d ),\n\t\t\t\tddd: dF.i18n.dayNames[D],\n\t\t\t\tdddd: dF.i18n.dayNames[D + 7],\n\t\t\t\tm: m + 1,\n\t\t\t\tmm: pad( m + 1 ),\n\t\t\t\tmmm: dF.i18n.monthNames[m],\n\t\t\t\tmmmm: dF.i18n.monthNames[m + 12],\n\t\t\t\tyy: String( y ).slice( 2 ),\n\t\t\t\tyyyy: y,\n\t\t\t\th: H % 12 || 12,\n\t\t\t\thh: pad( H % 12 || 12 ),\n\t\t\t\tH: H,\n\t\t\t\tHH: pad( H ),\n\t\t\t\tM: M,\n\t\t\t\tMM: pad( M ),\n\t\t\t\ts: s,\n\t\t\t\tss: pad( s ),\n\t\t\t\tl: pad( L, 3 ),\n\t\t\t\tL: pad( L > 99 ? Math.round( L / 10 ) : L ),\n\t\t\t\tt: H < 12 ? 'a' : 'p',\n\t\t\t\ttt: H < 12 ? 'am' : 'pm',\n\t\t\t\tT: H < 12 ? 'A' : 'P',\n\t\t\t\tTT: H < 12 ? 'AM' : 'PM',\n\t\t\t\tZ: utc ? 'UTC' : ( String( date ).match( timezone ) || [''] ).pop().replace( timezoneClip, '' ),\n\t\t\t\to: ( o > 0 ? '-' : '+' ) + pad( Math.floor( Math.abs( o ) / 60 ) * 100 + Math.abs( o ) % 60, 4 ),\n\t\t\t\tS: ['th', 'st', 'nd', 'rd'][d % 10 > 3 ? 0 : ( d % 100 - d % 10 !== 10 ) * d % 10]\n\t\t\t};\n\n\t\treturn mask.replace( token, function( $0 ) {\n\t\t\treturn $0 in flags ? flags[$0] : $0.slice( 1, $0.length - 1 );\n\t\t} );\n\t};\n\t/* jshint ignore:end */\n}();\n\n// Some common format strings\ndateFormat.masks = {\n\t'default': 'ddd mmm dd yyyy HH:MM:ss',\n\tshortDate: 'm/d/yy',\n\tmediumDate: 'mmm d, yyyy',\n\tlongDate: 'mmmm d, yyyy',\n\tfullDate: 'dddd, mmmm d, yyyy',\n\tshortTime: 'h:MM TT',\n\tmediumTime: 'h:MM:ss TT',\n\tlongTime: 'h:MM:ss TT Z',\n\tisoDate: 'yyyy-mm-dd',\n\tisoTime: 'HH:MM:ss',\n\tisoDateTime: 'yyyy-mm-dd\\'T\\'HH:MM:ss',\n\tisoUtcDateTime: 'UTC:yyyy-mm-dd\\'T\\'HH:MM:ss\\'Z\\''\n};\n\n// Internationalization strings\ndateFormat.i18n = {\n\tdayNames: [\n\t\t'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat',\n\t\t'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'\n\t],\n\tmonthNames: [\n\t\t'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',\n\t\t'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'\n\t]\n};\n\n// For convenience...\nDate.prototype.format = function( mask, utc ) {\n\t//JS Exception: Uncaught TypeError: Cannot read properties of undefined (reading 'date_format')\n\tif ( !Global.isSet( mask ) && LocalCacheData.getLoginUserPreference() ) {\n\t\tmask = LocalCacheData.getLoginUserPreference().date_format;\n\t}\n\n\tif ( !mask ) {\n\t\tmask = 'DD-MMM-YY';\n\t}\n\n\tvar format_str = moment( this ).format( mask );\n\n\treturn format_str;\n};\n\nwindow.RightClickMenuType = function() {\n\n};\n\nRightClickMenuType.LISTVIEW = '1';\nRightClickMenuType.EDITVIEW = '2';\nRightClickMenuType.NORESULTBOX = '3';\nRightClickMenuType.ABSENCE_GRID = '4';\nRightClickMenuType.VIEW_ICON = '5';\n\n/**\n * Decoding encoded html enitities (ie: \">\")\n * to avoid XSS vulnerabilities do not eval anything that has gone through this function\n *\n * @param str\n * @returns {*|jQuery}\n */\nGlobal.htmlDecode = function( str ) {\n\treturn $( '' ).html( str ).text();\n};\n\nGlobal.htmlEncode = function( str ) {\n\tvar encodedStr = str;\n\n\tif ( encodedStr ) {\n\t\t// This replaces 'S' in 'MST' with the encoded value, which is invalid.\n\t\t// encodedStr = str.replace( /[\\u00A0-\\u9999<>\\'\"\\&]/gim, function( i ) {\n\t\t// \treturn '&#' + i.charCodeAt( 0 ) + ';';\n\t\t// } );\n\t\t// encodedStr = encodedStr.replace( /<br>/g, '
' );\n\t\t// return encodedStr;\n\n\t\tvar tmp = document.createElement( 'div' );\n\t\ttmp.textContent = encodedStr;\n\n\t\treturn tmp.innerHTML;\n\t} else {\n\t\treturn encodedStr;\n\t}\n};\n\n//Sort by module\n\nGlobal.m_sort_by = ( function() {\n\t// utility functions\n\n\tvar default_cmp = function( a, b ) {\n\n\t\t\tif ( a === b ) {\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\t//Speical handle OPEN option to make it always stay together\n\t\t\tif ( a === false || a === 'OPEN' ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tif ( b === false || b === 'OPEN' ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\treturn a < b ? -1 : 1;\n\t\t},\n\t\tgetCmpFunc = function( primer, reverse ) {\n\t\t\tvar cmp = default_cmp;\n\t\t\tif ( primer ) {\n\t\t\t\tcmp = function( a, b ) {\n\t\t\t\t\treturn default_cmp( primer( a ), primer( b ) );\n\t\t\t\t};\n\t\t\t}\n\t\t\tif ( reverse ) {\n\t\t\t\treturn function( a, b ) {\n\t\t\t\t\treturn -1 * cmp( a, b );\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn cmp;\n\t\t};\n\n\t// actual implementation\n\tvar sort_by = function( sort_by_array ) {\n\t\tvar fields = [],\n\t\t\tn_fields = sort_by_array.length,\n\t\t\tfield, name, reverse, cmp;\n\n\t\t// preprocess sorting options\n\t\tfor ( var i = 0; i < n_fields; i++ ) {\n\t\t\tfield = sort_by_array[i];\n\t\t\tif ( typeof field === 'string' ) {\n\t\t\t\tname = field;\n\t\t\t\tcmp = default_cmp;\n\t\t\t} else {\n\t\t\t\tname = field.name;\n\t\t\t\tcmp = getCmpFunc( field.primer, field.reverse );\n\t\t\t}\n\t\t\tfields.push( {\n\t\t\t\tname: name,\n\t\t\t\tcmp: cmp\n\t\t\t} );\n\t\t}\n\n\t\treturn function( A, B ) {\n\t\t\tvar a, b, name, cmp, result;\n\t\t\tfor ( var i = 0, l = n_fields; i < l; i++ ) {\n\t\t\t\tresult = 0;\n\t\t\t\tfield = fields[i];\n\t\t\t\tname = field.name;\n\t\t\t\tcmp = field.cmp;\n\n\t\t\t\tresult = cmp( A[name], B[name] );\n\t\t\t\tif ( result !== 0 ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t};\n\t};\n\n\treturn sort_by;\n\n}() );\n\n$.fn.invisible = function() {\n\treturn this.each( function() {\n\t\t$( this ).css( 'opacity', '0' );\n\t} );\n};\n$.fn.visible = function() {\n\treturn this.each( function() {\n\t\t$( this ).css( 'opacity', '1' );\n\t} );\n};\n\nGlobal.trackView = function( name, action ) {\n\tif ( APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\tvar track_address;\n\n\t\t//Hostname is already sent separately, so this should just be the view/action in format:\n\t\t// '#!m=' + name + '&a=' + action\n\t\tif ( name ) {\n\t\t\ttrack_address = '#!m=' + name;\n\n\t\t\tif ( action ) {\n\t\t\t\ttrack_address += '&a=' + action;\n\t\t\t}\n\t\t} else {\n\t\t\t//Default to only data after (and including) the #.\n\t\t\ttrack_address = window.location.hash.substring( 1 );\n\t\t}\n\n\t\t//Track address is sent in sendAnalytics as the 3rd parameter.\n\t\tGlobal.sendAnalyticsPageview( track_address );\n\t}\n};\n\nGlobal.setAnalyticDimensions = function( user_name, company_name ) {\n\tif ( APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\tif ( typeof ( gtag ) !== 'undefined' ) {\n\t\t\ttry {\n\t\t\t\t//All names must be mapped in main.js 'custom_map'\n\t\t\t\tvar user_properties = {\n\t\t\t\t\t'application_version': APIGlobal.pre_login_data.application_version,\n\t\t\t\t\t'http_host': APIGlobal.pre_login_data.http_host,\n\t\t\t\t\t'product_edition_name': APIGlobal.pre_login_data.product_edition_name,\n\t\t\t\t\t'registration_key': APIGlobal.pre_login_data.registration_key,\n\t\t\t\t\t'primary_company_name': APIGlobal.pre_login_data.primary_company_name,\n\t\t\t\t};\n\n\t\t\t\tif ( user_name !== 'undefined' && user_name !== null ) {\n\t\t\t\t\tif ( APIGlobal.pre_login_data.production !== true ) {\n\t\t\t\t\t\tDebug.Text( 'Analytics User: ' + user_name, 'Global.js', '', 'doPing', 1 );\n\t\t\t\t\t}\n\t\t\t\t\tuser_properties.user_name = user_name;\n\t\t\t\t}\n\n\t\t\t\tif ( company_name !== 'undefined' && company_name !== null ) {\n\t\t\t\t\tif ( APIGlobal.pre_login_data.production !== true ) {\n\t\t\t\t\t\tDebug.Text( 'Analytics Company: ' + company_name, 'Global.js', '', 'setAnalyticDimensions', 1 );\n\t\t\t\t\t}\n\t\t\t\t\tuser_properties.company_name = company_name;\n\t\t\t\t}\n\n\t\t\t\tgtag( 'set', 'user_properties', user_properties );\n\t\t\t} catch ( e ) {\n\t\t\t\tthrow e; //Attempt to catch any errors thrown by Google Analytics.\n\t\t\t}\n\t\t}\n\t}\n};\n\nGlobal.sendAnalyticsPageview = function( track_address ) {\n\tif ( APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\t// Call this delay so view load goes first\n\t\tif ( typeof ( gtag ) !== 'undefined' ) {\n\t\t\tsetTimeout( function() {\n\t\t\t\ttry {\n\t\t\t\t\tgtag( 'event', 'page_view', { page_path: track_address } )\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}, 500 );\n\t\t}\n\n\t}\n};\n\n/**\n * This function is used to actually submit the analytics request to google.\n * @param {string} event_category - Category relating to the event tracked, e.g. feedback or context_menu\n * @param {string} event_action - What triggered the event. E.g. click, cancel.\n * @param {string} event_label - This is often a combo of the actual value string combined with some of the above fields, for clarity. e.g. submit:feedback:sad\n */\nGlobal.sendAnalyticsEvent = function( event_category, event_action, event_label ) {\n\tif ( typeof ( gtag ) !== 'undefined' && APIGlobal.pre_login_data.analytics_enabled === true ) {\n\t\t//Debug.Arr( fieldsObject, 'Sending analytics event payload. Event: ' + event_category + ', Action: ' + event_action + ', Label: ' + event_label, 'Global.js', 'Global', 'sendAnalyticsEvent', 11 );\n\t\ttry {\n\t\t\tgtag( 'event', event_category, { action: event_action, label: event_label } )\n\t\t} catch ( e ) {\n\t\t\tthrow e;\n\t\t}\n\t}\n};\n\n/**\n *\n * @param context_btn - the jQuery element that triggered the click event on the context menu\n * @param {string} menu_name - the name of the icon if the click event was triggered by the right click context menu\n */\nGlobal.triggerAnalyticsContextMenuClick = function( context_btn, menu_name ) {\n\t// If more detail is needed above and beyond contextmenu name, then use 'LocalCacheData.current_open_view_id' in addition, but not instead of, as they are different.\n\tvar dom_context_menu = LocalCacheData.currentShownContextMenuName || 'error-with-context-menu'; // '||' is for graceful fail. identify correct context menu (vs DOM search, where there could be multiple inactive context menus)\n\tvar dom_context_menu_group;\n\tvar button_id;\n\tvar event_category;\n\tvar event_action;\n\tvar event_label;\n\n\tif ( context_btn ) {\n\t\tif ( context_btn.group && context_btn.group.label ) {\n\t\t\tdom_context_menu_group = context_btn.group.label;\n\t\t} else {\n\t\t\tdom_context_menu_group = context_btn.action_group;\n\t\t}\n\t\tevent_category = 'navigation:context_menu';\n\t\tbutton_id = context_btn.id || 'error-with-icon';\n\t} else {\n\t\t// If context_btn is null, then this is likely a right click context menu call.\n\t\tevent_category = 'navigation:right_click_menu';\n\t\tdom_context_menu_group = 'right_click';\n\t\tbutton_id = menu_name || 'error-with-rightclick-icon';\n\t}\n\n\t// Beautify output\n\tdom_context_menu = dom_context_menu.replace( 'ContextMenu', '' );\n\tbutton_id = button_id.replace( 'Icon', '' ); //Remove \"icon\" from button_id.\n\n\tevent_action = 'click';\n\tevent_label = dom_context_menu + ':' + dom_context_menu_group + '|' + button_id;\n\n\t// Debug.Text( 'Context Menu: Category: navigation_context_menu Action: ' + event_action + ' Label: ' + event_label, 'Global.js', 'Global', 'triggerAnalyticsContextMenuClick', 10 );\n\tGlobal.sendAnalyticsEvent( event_category, event_action, event_label );\n};\n\n/**\n *\n * @param {string} context - Explains what element triggered the event\n * @param {string} view_id - Name of the current view in which element was triggered\n */\nGlobal.triggerAnalyticsEditViewNavigation = function( context, view_id ) {\n\t// context in this case can be 'left-arrow', 'right-arrow', or 'awesomebox'\n\tvar event_action = 'click';\n\tvar event_label = view_id + ':' + context;\n\n\t// Debug.Text( 'Context Menu: Category: navigation_edit_view_navigation Action: ' + event_action + ' Label: ' + event_label, 'Global.js', 'Global', 'triggerAnalyticsContextMenuClick', 10 );\n\tGlobal.sendAnalyticsEvent( 'navigation:edit_view_navigation', event_action, event_label );\n};\n\n/**\n *\n * @param event - the event object from the jQuery UI tabs. Currently expecting it to be triggered by the activate event\n * @param ui - the ui object from jQuery UI tabs, contains prev and target tab info\n */\nGlobal.triggerAnalyticsTabs = function( event, ui ) {\n\t// activate event triggered, ensure all required values are set\n\tif ( event && event.type && ui && ui.newTab ) {\n\t\tvar tab_target = ui.newTab.find( '.ui-tabs-anchor' ).attr( 'ref' ) || 'tab-target-error'; // '||' is for gracful fail\n\t\tvar viewId = LocalCacheData.current_open_view_id || 'error-viewid'; // '||' is for graceful fail\n\n\t\t// Beautify output\n\t\ttab_target = tab_target.replace( 'tab_', '' );\n\n\t\tvar event_action = 'click';\n\t\tvar event_label = viewId + ':tabs:' + tab_target;\n\n\t\t// Debug.Text( 'Context Menu: Category: navigation_tabs Action: ' + event_action + ' Label: ' + event_label, 'Global.js', 'Global', 'triggerAnalyticsContextMenuClick', 10 );\n\t\tGlobal.sendAnalyticsEvent( 'navigation:tabs', event_action, event_label );\n\t} else {\n\t\tGlobal.sendAnalyticsEvent( 'error:navigation:tabs', 'error-tabs', 'error' ); // Should never be triggered. If this appears in analytics results, investigate.\n\t}\n};\n\n/**\n *\n * @param {string} context - the label of the object involved in the event. E.g. close button for click event\n * @param {string} action - the action type of the event. E.g. click.\n * @param {string} view_id - the viewId in which the event occurred. E.g. TimeSheet.\n */\nGlobal.triggerAnalyticsNavigationOther = function( context, action, view_id ) {\n\tvar event_action = action;\n\tvar event_label = view_id + ':' + context;\n\n\t// Debug.Text( 'Context Menu: Category: navigation_other Action: ' + event_action + ' Label: ' + event_label, 'Global.js', 'Global', 'triggerAnalyticsContextMenuClick', 10 );\n\tGlobal.sendAnalyticsEvent( 'navigation:other', event_action, event_label );\n};\n\nGlobal.getSessionIDKey = function() {\n\tif ( LocalCacheData.getAllURLArgs() ) {\n\t\tif ( LocalCacheData.getAllURLArgs().hasOwnProperty( 'company_id' ) ) {\n\t\t\treturn 'SessionID-JA';\n\t\t}\n\t}\n\treturn 'SessionID';\n};\n\nGlobal.loadStyleSheet = function( path, fn, scope ) {\n\tvar head = document.getElementsByTagName( 'head' )[0], // reference to document.head for appending/ removing link nodes\n\t\tlink = document.createElement( 'link' ); // create the link node\n\tlink.setAttribute( 'href', path );\n\tlink.setAttribute( 'rel', 'stylesheet' );\n\tlink.setAttribute( 'type', 'text/css' );\n\tvar sheet, cssRules;\n\t// get the correct properties to check for depending on the browser\n\tif ( 'sheet' in link ) {\n\t\tsheet = 'sheet';\n\t\tcssRules = 'cssRules';\n\t} else {\n\t\tsheet = 'styleSheet';\n\t\tcssRules = 'rules';\n\t}\n\tvar interval_id = setInterval( function() { // start checking whether the style sheet has successfully loaded\n\t\t\ttry {\n\t\t\t\tif ( link[sheet] && link[sheet][cssRules].length ) { // SUCCESS! our style sheet has loaded\n\t\t\t\t\tclearInterval( interval_id ); // clear the counters\n\t\t\t\t\tclearTimeout( timeout_id );\n\t\t\t\t\tif ( typeof fn == 'function' ) {\n\t\t\t\t\t\tfn.call( scope || window, true, link ); // fire the callback with success == true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch ( e ) {\n\t\t\t} finally {\n\t\t\t}\n\t\t}, 10 ), // how often to check if the stylesheet is loaded\n\t\ttimeout_id = setTimeout( function() { // start counting down till fail\n\t\t\tclearInterval( timeout_id ); // clear the counters\n\t\t\tclearTimeout( timeout_id );\n\t\t\thead.removeChild( link ); // since the style sheet didn't load, remove the link node from the DOM\n\t\t\tif ( typeof fn == 'function' ) {\n\t\t\t\tfn.call( scope || window, false, link ); // fire the callback with success == false\n\t\t\t}\n\t\t}, 15000 ); // how long to wait before failing\n\thead.appendChild( link ); // insert the link node into the DOM and start loading the style sheet\n\treturn link; // return the link node;\n};\n\nGlobal.getSessionIDKey = function() {\n\tif ( LocalCacheData.getAllURLArgs() ) {\n\t\tif ( LocalCacheData.getAllURLArgs().hasOwnProperty( 'company_id' ) ) {\n\t\t\treturn 'SessionID-JA';\n\t\t}\n\t\tif ( LocalCacheData.getAllURLArgs().hasOwnProperty( 'punch_user_id' ) ) {\n\t\t\treturn 'SessionID-QP';\n\t\t}\n\t}\n\treturn 'SessionID';\n};\n\n//don't let the user leave without clicking OK.\n//uses localcachedata so that it will work in the ribbon\nGlobal.checkBeforeExit = function( functionToExecute ) {\n\tvar alert_message = Global.modify_alert_message;\n\tif ( LocalCacheData.current_open_edit_only_controller && LocalCacheData.current_open_edit_only_controller.confirm_on_exit && LocalCacheData.current_open_edit_only_controller.is_changed === false ) {\n\t\talert_message = Global.confirm_on_exit_message;\n\t}\n\n\tTAlertManager.showConfirmAlert( alert_message, null, function( clicked_yes ) {\n\t\tif ( clicked_yes === true ) {\n\t\t\tfunctionToExecute( clicked_yes );\n\t\t}\n\t} );\n};\n\nGlobal.detectMobileBrowser = function() {\n\treturn /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test( navigator.userAgent );\n};\n\nGlobal.getBrowserVendor = function() {\n\treturn APIGlobal.pre_login_data.user_agent_data.browser;\n};\n/**\n * Allowing deep linking\n * @type {boolean}\n */\nGlobal.deeplink = false;\n\nGlobal.getDeepLink = function() {\n\treturn Global.deeplink;\n};\n\n/**\n * Retrieves the deeplink from the current url.\n */\nGlobal.setDeepLink = function() {\n\tvar newDeepLink = window.location.href.split( '#!m=' )[1];\n\n\t//Because we add step to browser during login now so that the browser back button works, we need to check for that or login can fail leaving the user stuck.\n\tif ( newDeepLink == 'Login' || ( newDeepLink && newDeepLink.startsWith( 'Login&' ) == true ) ) { //We are not just checking startsWith because potential other views start with \"Login\" in the future\n\t\tvar alternate_session_data = getCookie( 'AlternateSessionData' );\n\t\tif ( alternate_session_data ) {\n\t\t\ttry { //Prevent JS exception if we can't parse alternate_session_data for some reason.\n\t\t\t\talternate_session_data = JSON.parse( alternate_session_data );\n\t\t\t\tif ( alternate_session_data && alternate_session_data.previous_session_view ) {\n\t\t\t\t\tGlobal.deeplink = alternate_session_data.previous_session_view;\n\t\t\t\t}\n\t\t\t} catch ( e ) {\n\t\t\t\tDebug.Text( e.message, 'Global.js', 'Global', 'setDeepLink', 10 );\n\t\t\t}\n\t\t}\n\t} else if ( newDeepLink != undefined ) {\n\t\tGlobal.deeplink = newDeepLink;\n\t}\n};\n\n/**\n sorts items for the ribbon menu\n **/\nGlobal.compareMenuItems = function( a, b ) {\n\tif ( a.attributes.sort_order == undefined ) {\n\t\ta.attributes.sort_order = 1000;\n\t}\n\tif ( b.attributes.sort_order == undefined ) {\n\t\tb.attributes.sort_order = 1000;\n\t}\n\n\tif ( a.attributes.sort_order < b.attributes.sort_order ) {\n\t\treturn -1;\n\t}\n\n\tif ( a.attributes.sort_order > b.attributes.sort_order ) {\n\t\treturn 1;\n\t}\n\n\tif ( a.attributes.sort_order == b.attributes.sort_order ) {\n\t\tif ( a.attributes.add_order < b.attributes.add_order ) {\n\t\t\treturn -1;\n\t\t}\n\t\tif ( a.attributes.add_order > b.attributes.add_order ) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n};\n\nGlobal.getDaysInSpan = function( start_date, end_date, sun, mon, tue, wed, thu, fri, sat ) {\n\tvar start_date_obj = Global.strToDate( start_date );\n\tvar end_date_obj = Global.strToDate( end_date );\n\n\tif ( start_date_obj == null ) {\n\t\treturn 0;\n\t}\n\n\tif ( end_date_obj == null ) {\n\t\treturn 0;\n\t}\n\n\tvar days = Math.round( Math.abs( ( start_date_obj.getTime() - end_date_obj.getTime() ) / ( 86400 * 1000 ) ) ) + 1;\n\n\t//Need to loop over the whole range to ensure proper counting of effective days on ranges that span multiple weeks.\n\twhile ( start_date_obj <= end_date_obj ) {\n\t\tswitch ( start_date_obj.getDay() ) {\n\t\t\tcase 0:\n\t\t\t\tif ( !sun ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tif ( !mon ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tif ( !tue ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tif ( !wed ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\tif ( !thu ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 5:\n\t\t\t\tif ( !fri ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 6:\n\t\t\t\tif ( !sat ) {\n\t\t\t\t\tdays -= 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tstart_date_obj.setDate( start_date_obj.getDate() + 1 ); //Increment to next day and continue the loop.\n\t}\n\n\treturn days;\n};\n\n/**\n * Sets the language cookie to root cookie url\n * @param lang\n */\nGlobal.setLanguageCookie = function( lang ) {\n\tsetCookie( 'language', lang, 10000, APIGlobal.pre_login_data.cookie_base_url );\n};\n\n/**\n * Removes cookies from all paths. Put in specifically to move the language cookies to root.\n * @param name\n */\nGlobal.eraseCookieFromAllPaths = function( name ) {\n\tvar value = getCookie( name );\n\n\t// This function will attempt to remove a cookie from all paths\n\tvar path_bits = location.pathname.split( '/' );\n\tvar path_current = ' path=';\n\n\t// Do a simple pathless delete first\n\tdocument.cookie = name + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT;';\n\tfor ( var i = 0; i < path_bits.length; i++ ) {\n\t\tpath_current += ( ( path_current.substr( -1 ) != '/' ) ? '/' : '' ) + path_bits[i];\n\t\tDebug.Text( '---' + i + '. Deleting cookie: ' + name + ' with value: ' + value + ' and path: ' + path_current, 'Global.js', 'Global', 'eraseCookieFromAllPaths', 10 );\n\t\tdocument.cookie = name + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; ' + path_current + '/;';\n\t\tdocument.cookie = name + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; ' + path_current + ';';\n\t}\n\n\tDebug.Text( 'Deleting cookie: ' + name + ' with value:' + value + ' and path:' + path_current, 'Global.js', 'Global', 'eraseCookieFromAllPaths', 10 );\n\treturn value;\n};\n\n/**\n * Moves specific app cookies from all over to the root cookie path so that they will be accessible from everywhere\n */\nGlobal.moveCookiesToNewPath = function() {\n\tDebug.Arr( document.cookie, 'COOKIE BEFORE CONTENT: ', 'Global.js', 'Global', 'moveCookiesToNewPath', 10 );\n\tvar cookies = ['language', 'StationID', 'SessionID'];\n\tvar year = new Date().getFullYear();\n\tfor ( var i = 0; i < cookies.length; i++ ) {\n\t\tvar val = Global.eraseCookieFromAllPaths( cookies[i] );\n\t\tif ( val && val.length > 0 ) {\n\t\t\tDebug.Text( 'Setting cookie:' + cookies[i] + ' with value:' + val + ' and path:' + APIGlobal.pre_login_data.cookie_base_url, 'Global.js', 'Global', 'moveCookiesToNewPath', 10 );\n\t\t\tdocument.cookie = cookies[i] + '=' + val + '; expires=Thu, 01-Jan-' + ( year + 10 ) + ' 00:00:01 GMT; path=' + APIGlobal.pre_login_data.cookie_base_url + ';';\n\t\t} else {\n\t\t\tDebug.Text( 'NOT Setting cookie:' + cookies[i] + ' with value:' + val + ' and path:' + APIGlobal.pre_login_data.cookie_base_url, 'Global.js', 'Global', 'moveCookiesToNewPath', 10 );\n\t\t}\n\t}\n\tDebug.Arr( document.cookie, 'COOKIE AFTER CONTENT: ', 'Global.js', 'Global', 'moveCookiesToNewPath', 10 );\n};\n\nGlobal.clearSessionCookie = function() {\n\tGlobal.moveCookiesToNewPath();\n\tdeleteCookie( Global.getSessionIDKey() );\n};\nGlobal.array_unique = function( arr ) {\n\tif ( Global.isArray( arr ) == false ) {\n\t\treturn arr;\n\t}\n\tvar clean_arr = [];\n\tfor ( var n in arr ) {\n\t\tif ( clean_arr.indexOf( arr[n] ) == -1 ) {\n\t\t\tclean_arr.push( arr[n] );\n\t\t}\n\t}\n\treturn clean_arr;\n};\n\n//Returns property keys that have different values or that don't exist. Similar to PHP's array_diff_assoc() function.\nGlobal.ArrayDiffAssoc = function( arr1 ) {\n\tconst retarr = {};\n\tconst argl = arguments.length;\n\tlet k1 = '';\n\tlet i = 1;\n\tlet k = '';\n\tlet arr = {};\n\n\tarr1_keys: for ( k1 in arr1 ) {\n\t\tfor ( i = 1; i < argl; i++ ) {\n\t\t\tarr = arguments[i];\n\n\t\t\tfor ( k in arr ) {\n\t\t\t\tif ( arr[k] === arr1[k1] && k === k1 ) {\n\t\t\t\t\t// If it reaches here, it was found in at least one array, so try next value\n\t\t\t\t\tcontinue arr1_keys;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tretarr[k1] = arr1[k1];\n\t\t}\n\t}\n\n\treturn retarr;\n};\n\n//Special rounding function that handles values like 1.005 or 1.0049999999999999 properly, see: http://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places\nGlobal.MoneyRound = function( number, decimals ) {\n\tif ( isNaN( number ) ) {\n\t\tnumber = 0;\n\t}\n\n\tif ( !decimals ) {\n\t\tdecimals = 2;\n\t}\n\n\t//#2294 - We must round the absolute value or negative numbers will round toward zero.\n\tvar negative = false;\n\tif ( number < 0 ) {\n\t\tnegative = true;\n\t}\n\tnumber = Math.abs( number );\n\n\tvar retval = +( Math.round( number + 'e+' + decimals ) + 'e-' + decimals );\n\n\tif ( negative ) {\n\t\tretval = retval * -1;\n\t}\n\n\treturn retval.toFixed( decimals );\n};\n\nGlobal.getUIReadyStatus = function() {\n\treturn Global.UIReadyStatus;\n};\nGlobal.setUINotready = function() {\n\tGlobal.UIReadyStatus = 0;\n\tDebug.Text( 'Global ready status changed: 0', 'Global.js', 'Global', 'setUIReadyStatus', 10 );\n};\nGlobal.setUIReady = function() {\n\t//need to check the document isn't already complete and ready for a screenshot.'\n\tif ( Global.UIReadyStatus == 0 ) {\n\t\tGlobal.UIReadyStatus = 1;\n\t\tDebug.Text( 'Global ready status changed: 1', 'Global.js', 'Global', 'setUIReady', 10 );\n\t}\n};\nGlobal.setUIInitComplete = function() {\n\tGlobal.UIReadyStatus = 2;\n\tDebug.Text( 'Global ready status changed: 2', 'Global.js', 'Global', 'setUIReadyStatus', 10 );\n};\n\nGlobal.setUnitTestMode = function() {\n\tGlobal.UNIT_TEST_MODE = true;\n\t$( 'body' ).addClass( 'UNIT_TEST_MODE' );\n\tDebug.setEnable( true );\n\tDebug.setVerbosity( 11 );\n};\n\nGlobal.convertValidationErrorToString = function( object ) {\n\t//Debug.Arr(object,'Converting Error to String: ','Global.js', 'Global', 'convertValidationErrorToString', 10);\n\tvar retval = '';\n\n\t// #2288 - If you are deleting several records and records 2 and 4 contain errors, those are the object keys that will need to be referenced here.\n\t// To fix this we need to grab the first element independent of the index number.\n\tif ( Object.keys( object ).length > 0 ) {\n\t\tfor ( var first in object ) {\n\t\t\tobject = object[first];\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tvar error_strings = [];\n\tif ( typeof object == 'string' ) {\n\t\t//#2290 - error objects are not always uniform and can sometimes cause malformed error tips (see screenshot) if we do not check each level for string type\n\t\terror_strings.push( object );\n\t} else {\n\t\tfor ( var index in object ) {\n\t\t\tif ( typeof object[index] == 'string' ) {\n\t\t\t\terror_strings.push( object[index] );\n\t\t\t} else {\n\t\t\t\tfor ( var key in object[index] ) {\n\t\t\t\t\tif ( typeof ( object[index][key] ) == 'string' ) {\n\t\t\t\t\t\terror_strings.push( object[index][key] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor ( var i in object[index][key] ) {\n\t\t\t\t\t\t\terror_strings.push( object[index][key][i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( error_strings.length > 1 ) {\n\t\tvar error_count = 1;\n\t\tfor ( var index in error_strings ) {\n\t\t\tretval += error_count + '. ' + error_strings[index] + '.
';\n\t\t\terror_count++;\n\t\t}\n\t} else if ( typeof error_strings[0] == 'string' ) {\n\t\tretval = error_strings[0] + '.';\n\t}\n\n\treturn retval;\n};\n\nGlobal.APIFileDownload = function( class_name, method, post_data, url ) {\n\tif ( url == undefined ) {\n\t\turl = _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.getAPIURL */ .n.getAPIURL( 'Class=' + class_name + '&Method=' + method );\n\t}\n\n\tvar message_id = _global_TTUUID__WEBPACK_IMPORTED_MODULE_0__/* .TTUUID.generateUUID */ .d.generateUUID();\n\turl = url + '&MessageID=' + message_id;\n\n\tvar tempForm = $( '
' );\n\ttempForm.attr( 'id', 'temp_form' );\n\ttempForm.attr( 'method', 'POST' );\n\ttempForm.attr( 'action', url );\n\n\ttempForm.attr( 'target', is_browser_iOS ? '_blank' : 'hideReportIFrame' ); //hideReportIFrame\n\n\ttempForm.append( $( '' ) );\n\ttempForm.append( $( '' ) );\n\n\ttempForm.css( 'display', 'none' );\n\tif ( post_data ) {\n\t\tvar hideInput = $( '' );\n\t\thideInput.val( JSON.stringify( post_data ) );\n\t\ttempForm.append( hideInput );\n\t}\n\ttempForm.appendTo( 'body' );\n\ttempForm.css( 'display', 'none' );\n\ttempForm.submit();\n\ttempForm.remove();\n\n\tif ( !is_browser_iOS ) {\n\t\tProgressBar.showProgressBar( message_id, true );\n\t}\n};\n\nGlobal.JSFileDownload = function( file_name, content, mime_type ) {\n\tvar a = document.createElement( 'a' );\n\tmime_type = mime_type || 'application/octet-stream';\n\n\tif ( URL && 'download' in a ) { //html5 A[download]\n\t\ta.href = URL.createObjectURL( new Blob( [content], {\n\t\t\ttype: mime_type\n\t\t} ) );\n\t\ta.setAttribute( 'download', file_name );\n\t\tdocument.body.appendChild( a );\n\t\ta.click();\n\t\tdocument.body.removeChild( a );\n\t} else {\n\t\tlocation.href = 'data:application/octet-stream,' + encodeURIComponent( content ); // only this mime type is supported\n\t}\n};\n\n//Get a refreshed CSRF token cookie in case it expires prior to the user clicking the login button. This helps avoid showing an error message and triggering a full browser refresh.\nGlobal.refreshCSRFToken = function( callback ) {\n\tif ( getCookie( 'CSRF-Token' ) == '' ) {\n\t\tDebug.Text( 'CSRF Token cookie does not exist, refreshing...', 'Global.js', '', 'refreshCSRFToken', 10 );\n\t\tthis.authentication_api = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\t\tthis.authentication_api.sendCSRFTokenCookie( {\n\t\t\t\tonResult: function( e ) {\n\t\t\t\t\tDebug.Text( 'CSRF Refresh success!...', null, null, 'refreshCSRFToken', 10 );\n\t\t\t\t\tcallback();\n\t\t\t\t},\n\t\t\t\tonError: function( e ) {\n\t\t\t\t\tDebug.Text( 'CSRF Refresh Error...', null, null, 'refreshCSRFToken', 10 );\n\t\t\t\t\tcallback();\n\t\t\t\t},\n\t\t\t});\n\t} else {\n\t\tcallback();\n\t}\n\n\treturn true;\n};\n\nGlobal.refreshPermissions = function() {\n\tthis.authentication_api = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIPermission */ .y.APIPermission;\n\tthis.authentication_api.getPermissions( {\n\t\tonResult: function( response ) {\n\t\t\tlet result = response.getResult();\n\t\t\tif ( result !== false ) {\n\t\t\t\tLocalCacheData.setPermissionData( result );\n\t\t\t\tDebug.Text( 'Permissions Refreshed!', 'Global.js', null, 'refreshPermissions', 10 );\n\t\t\t}\n\t\t},\n\t});\n};\n\nGlobal.setStationID = function( val ) {\n\tsetCookie( 'StationID', val, 10000 );\n};\n\nGlobal.getStationID = function() {\n\tvar retval = getCookie( 'StationID' );\n\n\t//Check to see if there is a \"sticky\" user agent based Station ID defined.\n\tif ( navigator.userAgent.indexOf( 'StationID:' ) != -1 ) {\n\t\tvar regex = /StationID:\\s?([a-zA-Z0-9]{30,64})/i;\n\t\tvar matches = regex.exec( navigator.userAgent );\n\t\tif ( matches[1] ) {\n\t\t\tDebug.Text( 'Found StationID in user agent, forcing to that instead!', 'Global.js', '', 'getStationID', 11 );\n\t\t\tretval = matches[1];\n\t\t}\n\t}\n\n\treturn retval;\n};\n\n//#2342 - Close all open edit views from one place.\nGlobal.closeEditViews = function( callback ) {\n\t//Don't check the .is_changed flag, as that will prevent edit views from being closed if no data has been changed.\n\t// For example if you go to MyAccount -> Request Authorization, View any request, click the \"TimeSheet\" icon, then click the Request timesheet cell (just below the punches) to navigate back to the requests.\n\tif ( LocalCacheData.current_open_report_controller ) { //&& LocalCacheData.current_open_report_controller.is_changed == true ) {\n\t\tLocalCacheData.current_open_report_controller.onCancelClick( null, null, function() {\n\t\t\tGlobal.closeEditViews( callback );\n\t\t} );\n\t} else if ( LocalCacheData.current_open_edit_only_controller ) { //&& LocalCacheData.current_open_edit_only_controller.is_changed == true ) {\n\t\tLocalCacheData.current_open_edit_only_controller.onCancelClick( null, null, function() {\n\t\t\tGlobal.closeEditViews( callback );\n\t\t} );\n\t} else if ( LocalCacheData.current_open_sub_controller && LocalCacheData.current_open_sub_controller.edit_view ) { //&& LocalCacheData.current_open_sub_controller.is_changed == true ) {\n\t\tLocalCacheData.current_open_sub_controller.onCancelClick( null, null, function() {\n\t\t\tGlobal.closeEditViews( callback );\n\t\t} );\n\t} else if ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.edit_view ) { //&& LocalCacheData.current_open_primary_controller.is_changed == true ) {\n\t\tLocalCacheData.current_open_primary_controller.onCancelClick( null, null, function() {\n\t\t\tGlobal.closeEditViews( callback );\n\t\t} );\n\t} else if ( LocalCacheData.current_open_primary_controller &&\n\t\tLocalCacheData.current_open_primary_controller.viewId === 'TimeSheet' &&\n\t\tLocalCacheData.current_open_primary_controller.getPunchMode() === 'manual' ) {\n\t\tLocalCacheData.current_open_primary_controller.doNextIfNoValueChangeInManualGrid( function() {\n\t\t\t//#2567 Must conclude here. Recursion would be infinite\n\t\t\tif ( callback ) {\n\t\t\t\tcallback();\n\t\t\t}\n\t\t} );\n\t} else {\n\t\tif ( callback ) {\n\t\t\tcallback();\n\t\t}\n\t}\n};\n\n//#2351 - red border for sandbox mode\nGlobal.styleSandbox = function() {\n\tif ( APIGlobal.pre_login_data['sandbox'] && APIGlobal.pre_login_data['sandbox'] == true ) {\n\t\t$( 'body' ).addClass( 'sandbox_container' );\n\t}\n};\n\n//#2351 - Used for logging in as employee/client or switching to sandbox mode.\nGlobal.NewSession = function( user_id, client_id ) {\n\tvar api_auth = _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication */ .y.APIAuthentication;\n\tapi_auth.newSession( user_id, client_id, {\n\t\tonResult: function( result ) {\n\t\t\tif ( !result.isValid() ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar result_data = result.getResult();\n\t\t\tif ( result_data && result_data.url ) {\n\t\t\t\tvar url = result_data.url;\n\t\t\t\tif ( url.indexOf( 'http' ) === -1 ) {\n\t\t\t\t\turl = window.location.protocol + '//' + url;\n\t\t\t\t}\n\n\t\t\t\tvar alternate_session_data = {\n\t\t\t\t\tnew_session_id: result_data.session_id,\n\t\t\t\t\tprevious_session_id: getCookie( Global.getSessionIDKey() ),\n\t\t\t\t\tprevious_session_url: Global.getBaseURL(),\n\t\t\t\t\tprevious_session_view: window.location.href.split( '#!m=' )[1],\n\t\t\t\t\tprevious_cookie_path: LocalCacheData.cookie_path\n\t\t\t\t};\n\n\t\t\t\tsetCookie( 'AlternateSessionData', JSON.stringify( alternate_session_data ), 1, result_data.cookie_base_url, Global.getHost() );\n\n\t\t\t\tGlobal.setURLToBrowser( url + 'html5/#!m=Login' );\n\t\t\t\tGlobal.needReloadBrowser = true;\n\t\t\t} else {\n\t\t\t\tTAlertManager.showAlert( $.i18n._( 'ERROR: Unable to perform action, please contact your %s administrator immediately.', LocalCacheData.getApplicationName() ), $.i18n._( 'ERROR' ) );\n\t\t\t}\n\t\t}\n\t} );\n\n};\n\nGlobal.isNumeric = function( value ) {\n\tvar retval = false;\n\n\tvalue = parseFloat( value );\n\tif ( typeof value == 'number' && !isNaN( value ) ) {\n\t\tretval = true;\n\t}\n\n\treturn retval;\n};\n\n//Calculates a \"smart\" debounce time based on the network ping time.\n//Debounce on at least 1.5x the round-trip ping time. ( 333 * 1.5 = 500ms. )\n//Because a user on a really slow connection could click Save 1s apart and the packets could arrive close to each other and cause duplicate request errors still.\nGlobal.calcDebounceWaitTimeBasedOnNetwork = function( min_time = null, max_time = null ) {\n\tvar ping = Global.current_ping;\n\n\tif ( !min_time ) {\n\t\tvar min_time = 500; //Turns into 500ms after 1.5x\n\t}\n\n\tif ( !max_time ) {\n\t\tvar max_time = 10000; //Turns into 10s after 1.5x\n\t}\n\n\tvar retval = ( ping * 1.5 );\n\n\tif ( retval < min_time ) {\n\t\tretval = min_time;\n\t}\n\n\tif ( retval > max_time ) {\n\t\tretval = max_time;\n\t}\n\n\treturn retval;\n}\n\n// Returns a function, that, as long as it continues to be invoked, will not be triggered. The function will be called after it stops being called for N milliseconds.\n// If `immediate` is passed, trigger the function on the leading edge, instead of the trailing.\nGlobal.debounce = function( callback, wait, immediate ) {\n\tvar timeout;\n\n\treturn function() {\n\t\tvar context = this;\n\t\tvar args = arguments;\n\n\t\tvar callback_name = ( callback.name ) ? callback.name : 'N/A';\n\n\t\tvar later = function() {\n\t\t\ttimeout = null;\n\t\t\tif ( !immediate ) {\n\t\t\t\tDebug.Text( 'Calling after debounce wait: ' + callback_name + ' Wait Time: ' + wait, 'Global.js', 'Global', 'debounce', 10 );\n\t\t\t\tcallback.apply( context, args );\n\t\t\t} else {\n\t\t\t\tDebug.Text( 'Skipping due to debounce: ' + callback_name + ' Wait Time: ' + wait, 'Global.js', 'Global', 'debounce', 11 );\n\t\t\t}\n\t\t};\n\n\t\tvar call_now = immediate && !timeout;\n\n\t\tclearTimeout( timeout );\n\n\t\ttimeout = setTimeout( later, wait );\n\n\t\tif ( call_now ) {\n\t\t\tDebug.Text( 'Calling immediate debounce: ' + callback_name + ' Wait Time: ' + wait, 'Global.js', 'Global', 'debounce', 10 );\n\t\t\tcallback.apply( context, args );\n\t\t} else {\n\t\t\tDebug.Text( 'Skipping due to debounce: ' + callback_name + ' Wait Time: ' + wait, 'Global.js', 'Global', 'debounce', 11 );\n\t\t}\n\t};\n};\n\n/**\n * Filter output to prevent the user from seeing strings such as undefined, false or null.\n * @param {string} entry the string that needs to be sanitized.\n * @param {Array} [filters] optional array of filters. If none is supplied, defaults will be used.\n * @returns {string} returns the sanitized string result\n */\nGlobal.filterOutput = function( entry, filters ) {\n\t// default filters can be overridden by passing in a second param\n\n\tif ( !filters ) {\n\t\tfilters = [false, undefined, null, 'false', 'undefined', 'null'];\n\t}\n\n\t// if filter matches, replace contents with empty string\n\tif ( ( filters.indexOf( entry ) !== -1 ) ) {\n\t\treturn '';\n\t} else {\n\t\treturn entry;\n\t}\n};\n\n/**\n * groupArrayDataByKey - This function is used to group data by object key - used (so far) for the geofence filters\n * @param {Object[]} data - the array dataset\n * @param {boolean} [makeUnique] - true will only output one occurance per key. false or ommiting will return all occurances\n * @returns {*}\n */\nGlobal.groupArrayDataByKey = function( data, makeUnique ) {\n\n\treturn data.reduce( function( accumulator, currentValue ) {\n\t\t// get a list of all object keys for data object, then iterate through each\n\t\tObject.entries( currentValue ).forEach( function( key ) {\n\t\t\taccumulator[key[0]] = accumulator[key[0]] || [];\n\n\t\t\t// check if value exists or add anyway if makeUnique is false\n\t\t\tif ( accumulator[key[0]].indexOf( key[1] ) === -1 || !makeUnique ) {\n\t\t\t\taccumulator[key[0]].push( key[1] );\n\t\t\t}\n\t\t} );\n\t\treturn accumulator;\n\t}, {} );\n};\n\n/**\n * Used to modify the viewport meta tag in the index.php head section. This controls the 'virtual' device viewport on mobile devices.\n * More info: https://developers.google.com/web/updates/2015/01/What-the-Viewport\n * @param {string} setting - name of pre-defined viewport setting\n * @returns {string} returns the new content value for the viewport meta tag\n * @example A use case is Setting mobile view on login, then back to desktop (990px virtual) after login, to allow pan & zoom, as not whole app is mobile optimized.\n */\nGlobal.setVirtualDeviceViewport = function( setting ) {\n\tvar width;\n\tvar scale;\n\tvar meta_tag_viewport = $( 'meta[name=viewport]' );\n\n\tif ( !setting || !meta_tag_viewport || meta_tag_viewport.length !== 1 ) {\n\t\tDebug.Text( 'Error: Missing params in function call', 'Global.js', 'Global', 'setVirtualDeviceViewport', 1 );\n\t\treturn undefined;\n\t}\n\tif ( setting === 'mobile' ) {\n\t\twidth = 'device-width';\n\t\tscale = 1;\n\t} else if ( setting === 'desktop' ) {\n\t\twidth = 990; // Minium application width which was previously used elsewhere.\n\t\tscale = 0.5;\n\t} else {\n\t\tDebug.Text( 'Error: Invalid setting passed to function', 'Global.js', 'Global', 'setVirtualDeviceViewport', 1 );\n\t\treturn undefined;\n\t}\n\tif ( width && scale ) {\n\t\tmeta_tag_viewport.attr( 'content', 'width=' + width + ', initial-scale=' + scale );\n\t\treturn meta_tag_viewport.attr( 'content' );\n\t} else {\n\t\tDebug.Text( 'Error: Invalid device settings. Either width or scale is invalid', 'Global.js', 'Global', 'setVirtualDeviceViewport', 1 );\n\t\treturn undefined;\n\t}\n};\n\n//Clear all session and local cache data for logout.\nGlobal.Logout = function() {\n\t_services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.abortAll */ .n.abortAll(); //Abort any pending AJAX requests so their callbacks don't get triggered and cause all kind of weirdness.\n\tLocalCacheData.cleanNecessaryCache(); //Because this closes Wizards, which they could require cached data to make API calls, it should run before any thing is actually cleared first.\n\tGlobal.clearSessionCookie();\n\tLocalCacheData.setSessionID( '' );\n\tLocalCacheData.current_open_view_id = ''; //#1528 - Logout icon not working.\n\t//LocalCacheData.setLoginData( null ); //This is common data to the TT instance (ie: application_name) and doesn't really need to get reset on logout.\n\tLocalCacheData.setLoginUser( null );\n\tLocalCacheData.setLoginUserPreference( null );\n\tLocalCacheData.setPermissionData( null );\n\tLocalCacheData.setCurrentCompany( null );\n\tLocalCacheData.setLastPunchTime( null );\n\tLocalCacheData.setJobQueuePunchData( null );\n\tsessionStorage.clear();\n\n\tGlobal.event_bus.emit( 'global', 'reset_vue_data' ); // Reset vue data to default values. Otherwise user data from previous session will remain.\n\n\t//Don't reload or change views, allow that to be done by the caller.\n\n\treturn true;\n};\n\nGlobal.glowAnimation = {\n\tstart: function( element, color ) {\n\t\tif ( !element ) {\n\t\t\treturn false;\n\t\t}\n\t\tif ( !color ) {\n\t\t\t// Set default color to green. Remember this affects the text color of the element too. Might want to disable this default in future if we want to set color separately or use inherited/existing.\n\t\t\tcolor = '#00ff00';\n\t\t}\n\t\treturn element\n\t\t\t.css( 'color', color ) // sets the font color of the element. The glow then uses this value via 'currentColor'\n\t\t\t.addClass( 'animate-glow' );\n\t},\n\tstop: function( element ) {\n\t\tif ( !element ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn element.removeClass( 'animate-glow' );\n\t}\n};\n\nGlobal.buildArgDic = function( array ) {\n\tvar len = array.length;\n\tvar result = {};\n\tfor ( var i = 0; i < len; i++ ) {\n\t\tvar item = array[i];\n\t\titem = item.split( '=' );\n\t\tresult[item[0]] = item[1];\n\t}\n\n\treturn result;\n};\n\nGlobal.getFeatureFlag = function( flag, default_value ) {\n\tlet feature_flags = LocalCacheData.getFeatureFlagData();\n\n\t//Post login has updated feature flags and are specific to the current company.\n\tif ( feature_flags && feature_flags.hasOwnProperty( flag ) ) {\n\t\treturn feature_flags[flag];\n\t}\n\n\t//If we only have pre-login dqta, use the feature flags for the installed company.\n\tif ( APIGlobal.pre_login_data && APIGlobal.pre_login_data.feature_flags && APIGlobal.pre_login_data.feature_flags.hasOwnProperty( flag ) ) {\n\t\treturn APIGlobal.pre_login_data.feature_flags[flag];\n\t}\n\n\treturn default_value;\n};\n\nGlobal.showAuthenticationModal = function( view_id, session_type, mfa_data, is_reauthentication, authenticate_callback, error_string = '', mount_id = 'tt_authenticate_ui' ) {\n\t_services_TTVueUtils__WEBPACK_IMPORTED_MODULE_8__/* [\"default\"].mountComponent */ .Z.mountComponent( mount_id, _components_login_TTMultiFactorAuthentication__WEBPACK_IMPORTED_MODULE_9__/* [\"default\"] */ .Z, {\n\t\tview_id: view_id,\n\t\tsession_type: session_type,\n\t\tcomponent_id: mount_id,\n\t\tmfa_data: mfa_data,\n\t\tuser_name: LocalCacheData.getLoginUser() ? LocalCacheData.getLoginUser().user_name : '',\n\t\terror_string: LocalCacheData.login_error_string || error_string,\n\t\tauthenticate_callback: authenticate_callback || function( success ) {\n\t\t\tGlobal.hideAuthenticationModal();\n\t\t\treturn success;\n\t\t},\n\t\tis_reauthentication: is_reauthentication\n\t} );\n};\n\nGlobal.hideAuthenticationModal = function( mount_id = 'tt_authenticate_ui' ) {\n\t_services_TTVueUtils__WEBPACK_IMPORTED_MODULE_8__/* [\"default\"].unmountComponent */ .Z.unmountComponent( mount_id );\n};\n\nGlobal.getSessionTypeForLogin = function( user_name, callback ) {\n\t_services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication.getSessionTypeForLogin */ .y.APIAuthentication.getSessionTypeForLogin( user_name, {\n\t\tonResult: ( result ) => {\n\t\t\tif ( result.isValid() ) {\n\t\t\t\tcallback( result.getResult() );\n\t\t\t} else {\n\t\t\t\tcallback( false );\n\t\t\t}\n\t\t}\n\t} );\n};\n\nGlobal.login = function( user_name, user_password, session_type, is_reauthentication, callback ) {\n\t//Catch blank username/passwords as early as possible. This may catch some bots from attempting to login as well.\n\tif ( user_name == '' || user_password == '' ) {\n\t\tTAlertManager.showAlert( $.i18n._( 'Please enter a user name and password.' ) );\n\t\tcallback( false );\n\t\treturn;\n\t}\n\n\tif ( LocalCacheData.current_open_primary_controller.viewId == 'LoginView' ) {\n\t\tvar cr_text = $( \"\\x23\\x6C\\x6F\\x67\\x69\\x6E\\x5F\\x63\\x6F\\x70\\x79\\x5F\\x72\\x69\\x67\\x68\\x74\\x5F\\x69\\x6E\\x66\\x6F\" ).text();\n\t\tvar _0xee93 = [\"\\x6F\\x6E\\x6C\\x6F\\x61\\x64\", \"\\x74\\x6F\\x74\\x61\\x6C\", \"\\x43\\x6F\\x70\\x79\\x72\\x69\\x67\\x68\\x74\\x20\", \"\\x69\\x6E\\x64\\x65\\x78\\x4F\\x66\", \"\\x6F\\x72\\x67\\x61\\x6E\\x69\\x7A\\x61\\x74\\x69\\x6F\\x6E\\x5F\\x6E\\x61\\x6D\\x65\", \"\\x6C\\x6F\\x67\\x69\\x6E\\x44\\x61\\x74\\x61\", \"\\x41\\x6C\\x6C\\x20\\x52\\x69\\x67\\x68\\x74\\x73\\x20\\x52\\x65\\x73\\x65\\x72\\x76\\x65\\x64\", \"\\x45\\x52\\x52\\x4F\\x52\\x3A\\x20\\x54\\x68\\x69\\x73\\x20\\x69\\x6E\\x73\\x74\\x61\\x6C\\x6C\\x61\\x74\\x69\\x6F\\x6E\\x20\\x6F\\x66\\x20\", \"\\x61\\x70\\x70\\x6C\\x69\\x63\\x61\\x74\\x69\\x6F\\x6E\\x5F\\x6E\\x61\\x6D\\x65\", \"\\x20\\x69\\x73\\x20\\x69\\x6E\\x20\\x76\\x69\\x6F\\x6C\\x61\\x74\\x69\\x6F\\x6E\\x20\\x6F\\x66\\x20\\x74\\x68\\x65\\x20\\x6C\\x69\\x63\\x65\\x6E\\x73\\x65\\x20\\x61\\x67\\x72\\x65\\x65\\x6D\\x65\\x6E\\x74\\x21\", \"\\x73\\x68\\x6F\\x77\\x41\\x6C\\x65\\x72\\x74\", \"\\x67\\x65\\x74\\x52\\x65\\x73\\x70\\x6f\\x6e\\x73\\x65\\x48\\x65\\x61\\x64\\x65\\x72\", \"\\x43\\x6f\\x6e\\x74\\x65\\x6e\\x74\\x2d\\x4c\\x65\\x6e\\x67\\x74\\x68\", \"\\x54\\x69\\x6D\\x65\\x54\\x72\\x65\\x78\", \"\\x23\\x70\\x6F\\x77\\x65\\x72\\x65\\x64\\x5F\\x62\\x79\", \"\\x6E\\x61\\x74\\x75\\x72\\x61\\x6C\\x57\\x69\\x64\\x74\\x68\", \"\\x6E\\x61\\x74\\x75\\x72\\x61\\x6C\\x48\\x65\\x69\\x67\\x68\\x74\"];\n\t\tif ( ( !$( _0xee93[14] )[0] || ( $( _0xee93[14] )[0] && ( ( $( _0xee93[14] )[0][_0xee93[15]] > 0 && $( _0xee93[14] )[0][_0xee93[15]] != 145 ) || ( $( _0xee93[14] )[0][_0xee93[16]] > 0 && $( _0xee93[14] )[0][_0xee93[16]] != 40 ) ) ) ) || cr_text[_0xee93[3]]( _0xee93[2] ) !== 0 || LocalCacheData[_0xee93[5]][_0xee93[8]][_0xee93[3]]( _0xee93[13] ) !== 0 || cr_text[_0xee93[3]]( _0xee93[13] ) !== 17 ) {\n\t\t\tGlobal.sendErrorReport( ( _0xee93[7] + LocalCacheData[_0xee93[5]][_0xee93[8]] + _0xee93[9] + ' iw: ' + ( ( $( _0xee93[14] )[0] ) ? $( _0xee93[14] )[0][_0xee93[15]] : 0 ) + ' ih: ' + ( ( $( _0xee93[14] )[0] ) ? $( _0xee93[14] )[0][_0xee93[16]] : 0 ) + ' c: ' + cr_text[_0xee93[3]]( _0xee93[2] ) + ' ' + cr_text[_0xee93[3]]( LocalCacheData[_0xee93[5]][_0xee93[4]] ) ), _services_ServiceCaller__WEBPACK_IMPORTED_MODULE_5__/* .ServiceCaller.root_url */ .n.root_url, '', '', '' );\n\t\t}\n\t}\n\n\t//Check to make sure a CSRF token cookie exists, if not refresh it.\n\tGlobal.refreshCSRFToken( () => {\n\t\t_services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_1__/* .TTAPI.APIAuthentication.login */ .y.APIAuthentication.login( user_name, user_password, session_type, is_reauthentication, {\n\t\t\tonResult: ( result ) => {\n\t\t\t\tif ( result.isValid() ) {\n\t\t\t\t\tlet session_result = result.getResult();\n\t\t\t\t\tlet session_id = session_result.session_id;\n\t\t\t\t\tLocalCacheData.setSessionID( session_id );\n\t\t\t\t\tsetCookie( Global.getSessionIDKey(), session_id );\n\t\t\t\t\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\t\t\t\t\tDebug.Text( 'Login Success (first try)', null, null, 'onLoginBtnClick', 10 );\n\t\t\t\t\t\tif ( session_result.mfa && session_result.mfa.step != false && is_reauthentication == false ) {\n\t\t\t\t\t\t\tGlobal.showAuthenticationModal( this.viewId, session_result.session_type, session_result.mfa, false,( success ) => {\n\t\t\t\t\t\t\t\tcallback( result );\n\t\t\t\t\t\t\t}, );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcallback( result );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar timeout_count = 0;\n\t\t\t\t\t\tvar auto_login_timer = setInterval( () => {\n\t\t\t\t\t\t\tif ( timeout_count == 100 ) {\n\t\t\t\t\t\t\t\tclearInterval( auto_login_timer );\n\t\t\t\t\t\t\t\tTAlertManager.showAlert( $.i18n._( 'The network connection was lost. Please check your network connection then try again.' ) );\n\t\t\t\t\t\t\t\tDebug.Text( 'Login Failure', 'Global.js', '', 'login', 10 );\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttimeout_count = timeout_count + 1;\n\t\t\t\t\t\t\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\t\t\t\t\t\t\tif ( session_result.mfa && session_result.mfa.step != false && is_reauthentication == false ) {\n\t\t\t\t\t\t\t\t\tGlobal.showAuthenticationModal( this.viewId, session_result.session_type, session_result.mfa, false, ( success ) => {\n\t\t\t\t\t\t\t\t\t\tcallback( result );\n\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcallback( result );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tDebug.Text( 'Login Success after retry: ' + timeout_count, 'Global.js', '', 'login', 10 );\n\t\t\t\t\t\t\t\tclearInterval( auto_login_timer );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 600 );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( result.getDetails()[0] && result.getDetails()[0].hasOwnProperty( 'password' ) ) {\n\t\t\t\t\t\tGlobal.showCompromisedPasswordModal( user_name, result.getDetailsAsString() );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tTAlertManager.showErrorAlert( result );\n\t\t\t\t\t}\n\t\t\t\t\tcallback( result );\n\t\t\t\t}\n\t\t\t},\n\t\t\tonError: ( e ) => {\n\t\t\t\tDebug.Text( 'Login Error...', 'Global.js', '', 'login', 10 );\n\t\t\t\tcallback( false );\n\t\t\t},\n\t\t} );\n\t} );\n\n\tGlobal.showCompromisedPasswordModal = function( user_name, message, callback ) {\n\t\tGlobal.getSessionTypeForLogin( user_name, ( result ) => {\n\t\t\tif ( result.mfa_type_id > 0 ) {\n\t\t\t\t//MFA users must reset password before login, otherwise simply having the password would bypass MFA.\n\t\t\t\tIndexViewController.openWizard( 'ForgotPasswordWizard', { message: message }, function() {\n\t\t\t\t\tTAlertManager.showAlert( $.i18n._( 'An email has been sent to you with instructions on how to change your password.' ) );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\t//None MFA users can change password by supplying their username, current password and new password.\n\t\t\t\tIndexViewController.openWizard( 'ResetPasswordWizard', {\n\t\t\t\t\tuser_name: user_name,\n\t\t\t\t\tmessage: message\n\t\t\t\t}, function() {\n\t\t\t\t\tTAlertManager.showAlert( $.i18n._( 'Password has been changed successfully, you may now login.' ) );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t}\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTQ5MC5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLFlBQVksaUJBQWlCO0FBQ1k7QUFDWTtBQUNxQyxDQUFDO0FBQzVDO0FBQ007QUFDSTtBQUNWO0FBQzhCO0FBQzlCO0FBQzBDO0FBQ3pGLFlBQVksWUFBWSxZQUFZO0FBQ3BDLHFEQUFxRDs7QUFFckQ7QUFDTztBQUNQO0FBQ0EsdUJBQXVCLHFFQUFVLEdBQUcsbUJBQW1CO0FBQ3ZELGtDQUFrQyxJQUFJO0FBQ3RDOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxlQUFlLENBQUM7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0NBQWtDOztBQUVsQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjs7QUFFL0IsQ0FBQyw2RUFBZTtBQUNoQixDQUFDLGlHQUF5QjtBQUMxQixDQUFDLDJGQUFzQixVQUFVOztBQUVqQyxNQUFNLDZFQUFlO0FBQ3JCO0FBQ0EseUVBQXlFO0FBQ3pFO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTixLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLE9BQU87O0FBRVA7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLDRCQUE0QiwyR0FBdUI7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsQ0FBQyxnTUFBZ00sQ0FBQyx1REFBdUQsQ0FBQztBQUM5UTtBQUNBLG9MQUFvTCw2RkFBc0I7O0FBRTFNO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1IsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpR0FBaUc7QUFDakc7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQSwrRUFBK0U7QUFDL0U7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0I7QUFDL0I7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQixDQUFDOztBQUU1QiwyQkFBMkIsQ0FBQzs7QUFFNUIsMkJBQTJCLENBQUM7O0FBRTVCLG9CQUFvQixDQUFDOztBQUVyQjs7QUFFQSxpQ0FBaUMsQ0FBQzs7QUFFbEMsK0JBQStCLENBQUM7O0FBRWhDLGdDQUFnQyxDQUFDOztBQUVqQyw0QkFBNEIsQ0FBQzs7QUFFN0IsNkJBQTZCLENBQUM7O0FBRTlCLDRCQUE0QixDQUFDOztBQUU3QixpQ0FBaUMsQ0FBQywrREFBK0Q7O0FBRWpHLDRCQUE0QixDQUFDOztBQUU3QixvQ0FBb0MsQ0FBQzs7QUFFckMsK0JBQStCLENBQUM7O0FBRWhDLCtCQUErQixDQUFDOztBQUVoQyxrQ0FBa0MsQ0FBQzs7QUFFbkMsaUNBQWlDLENBQUM7O0FBRWxDLHlDQUF5QyxDQUFDOztBQUUxQyx3Q0FBd0MsQ0FBQzs7QUFFekMsK0NBQStDLENBQUM7O0FBRWhELDJDQUEyQyxDQUFDO0FBQzVDOztBQUVBO0FBQ0EsZUFBZSxDQUFDO0FBQ2hCOztBQUVBO0FBQ0E7QUFDQSxhQUFhLENBQUM7QUFDZCxHQUFHO0FBQ0g7QUFDQSxhQUFhLENBQUM7QUFDZCxHQUFHO0FBQ0gsYUFBYSxDQUFDO0FBQ2Q7O0FBRUEsa0JBQWtCLENBQUM7O0FBRW5CO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdHQUFnRztBQUNoRztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsV0FBVywyR0FBdUI7QUFDbEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsdUZBQWE7QUFDM0I7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBLENBQUMsQ0FBQztBQUNGO0FBQ0EsRUFBRTtBQUNGLENBQUMsQ0FBQztBQUNGO0FBQ0EsRUFBRTs7QUFFRix1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLEVBQUUseUJBQXlCLEVBQUUseUJBQXlCLEVBQUU7QUFDMUY7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxxRkFBYztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRCxzR0FBK0I7QUFDbEYsc0JBQXNCLENBQUM7QUFDdkIsR0FBRyxDQUFDOztBQUVKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxDQUFDLENBQUM7QUFDRjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkIsMkdBQXVCO0FBQ2xELHdCQUF3QiwyR0FBdUI7O0FBRS9DO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxxR0FBcUc7QUFDckcsd0lBQXdJOztBQUV4STtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLLCtCQUErQjtBQUNwQyx1RUFBdUU7QUFDdkUsS0FBSywrQkFBK0I7QUFDcEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUEsd0NBQXdDOztBQUV4QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLDJKQUEySjs7QUFFM0o7QUFDQTtBQUNBO0FBQ0EsOEZBQThGO0FBQzlGO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQztBQUNBLDZCQUE2QjtBQUM3QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7O0FBRS9COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsZ0RBQWdEOztBQUVoRDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsY0FBYyxDQUFDO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLE1BQU07O0FBRS9CO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxDQUFDLENBQUM7QUFDRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxrQkFBa0Isa0JBQWtCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLEtBQUs7QUFDTCxnQkFBZ0I7QUFDaEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLHFGQUFtQjtBQUMxRDtBQUNBO0FBQ0EsWUFBWSxxRkFBbUI7QUFDL0IsZ0JBQWdCLHFGQUFtQjtBQUNuQztBQUNBLE1BQU07QUFDTjtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QywyRUFBYztBQUNyRDtBQUNBO0FBQ0EsWUFBWSwyRUFBYztBQUMxQixnQkFBZ0IsMkVBQWM7QUFDOUI7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGtCQUFrQixTQUFTO0FBQzNCOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxFQUFFLENBQUM7QUFDSDtBQUNBLElBQUk7O0FBRUo7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQjs7QUFFbEI7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQSxRQUFRLENBQUM7QUFDVDs7QUFFQTtBQUNBLFFBQVEsQ0FBQztBQUNUOztBQUVBO0FBQ0EsUUFBUSxDQUFDO0FBQ1Q7O0FBRUE7QUFDQSxRQUFRLENBQUM7QUFDVDs7QUFFQTtBQUNBLHNCQUFzQixDQUFDO0FBQ3ZCO0FBQ0EsNkJBQTZCLGlIQUFnQztBQUM3RDtBQUNBLHVCQUF1QixDQUFDO0FBQ3hCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsQ0FBQztBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxRQUFRLDZGQUFzQjtBQUM5QixHQUFHLENBQUM7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQiwyQkFBMkI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksQ0FBQztBQUNiO0FBQ0E7QUFDQTtBQUNBLEtBQUssQ0FBQztBQUNOLEtBQUssQ0FBQztBQUNOLEtBQUssQ0FBQztBQUNOLGNBQWMsQ0FBQztBQUNmLE1BQU07QUFDTixLQUFLLENBQUM7QUFDTixLQUFLLENBQUM7QUFDTixjQUFjLENBQUM7QUFDZixNQUFNO0FBQ04sS0FBSyxDQUFDO0FBQ04sY0FBYyxDQUFDO0FBQ2Y7QUFDQTs7QUFFQTs7QUFFQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQSx1QkFBdUIsQ0FBQyxnRUFBZ0UsQ0FBQyxzRkFBc0YsQ0FBQztBQUNoTCxFQUFFLENBQUM7QUFDSDtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxRQUFRLENBQUM7QUFDVDs7QUFFQTtBQUNBLFFBQVEsQ0FBQztBQUNUOztBQUVBO0FBQ0EsUUFBUSxDQUFDO0FBQ1Q7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1EQUFtRDtBQUNuRCxHQUFHLDBCQUlDLEdBQVMsRUFBRSxZQUFZLENBQUMsQ0FDeEI7QUFDSjtBQUNBLDBEQUEwRDs7QUFFMUQ7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUEsa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsSUFBSTtBQUNKLDREQUE0RDtBQUM1RCxHQUFHLDBCQUdDLEdBQWtCLEVBQUUsWUFBWSxDQUFDLENBQ2pDO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0wsSUFBSTtBQUNKO0FBQ0E7O0FBRUEsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDOztBQUVoQztBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsTUFBTTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLHlCQUF5Qjs7QUFFN0Q7QUFDQTtBQUNBLFNBQVMsNkZBQXNCO0FBQy9CLDZCQUE2Qiw2RkFBc0I7QUFDbkQsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0IscUZBQW1CO0FBQ3JDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxNQUFNO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHLE1BQU07QUFDVCxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsZ0NBQWdDO0FBQ2hDOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsWUFBWTtBQUNaOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFFBQVEsTUFBTSxpQkFBaUIsU0FBUztBQUN4Qzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQix1QkFBdUI7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSx5RkFBeUYsMkVBQWM7QUFDdkc7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxNQUFNLENBQUMsMEJBQTBCLENBQUM7QUFDbEM7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrQkFBa0IsU0FBUztBQUMzQjtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsZ0JBQWdCO0FBQ3BDO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sZ0dBQXlCO0FBQ2hDLFdBQVcsQ0FBQztBQUNaO0FBQ0EsT0FBTyxtR0FBNEI7QUFDbkMsV0FBVyxDQUFDO0FBQ1o7QUFDQSxPQUFPLCtGQUF3QjtBQUMvQixXQUFXLENBQUM7QUFDWjtBQUNBLE9BQU8sb0dBQTZCO0FBQ3BDLFdBQVcsQ0FBQztBQUNaO0FBQ0EsT0FBTyw4RkFBdUI7QUFDOUIsV0FBVyxDQUFDO0FBQ1o7QUFDQSxPQUFPLGtHQUEyQjtBQUNsQyxXQUFXLENBQUM7QUFDWjtBQUNBLE9BQU8sd0ZBQWlCO0FBQ3hCLFdBQVcsQ0FBQztBQUNaO0FBQ0EsT0FBTyw0RkFBcUI7QUFDNUIsV0FBVyxDQUFDO0FBQ1o7QUFDQSxPQUFPLDZGQUFzQjtBQUM3QixXQUFXLENBQUM7QUFDWjtBQUNBLE9BQU8sd0ZBQWlCO0FBQ3hCLFdBQVcsQ0FBQztBQUNaO0FBQ0EsT0FBTyw2RkFBc0I7QUFDN0IsV0FBVyxDQUFDO0FBQ1o7QUFDQSxPQUFPLCtGQUF3QjtBQUMvQixPQUFPLGdHQUF5QjtBQUNoQyxXQUFXLENBQUM7QUFDWjtBQUNBLE9BQU8sK0ZBQXdCO0FBQy9CLFdBQVcsQ0FBQztBQUNaO0FBQ0EsT0FBTyw2RkFBc0I7QUFDN0IsV0FBVyxDQUFDO0FBQ1o7QUFDQSxPQUFPLHFHQUE4QjtBQUNyQyxXQUFXLENBQUM7QUFDWjtBQUNBO0FBQ0EsT0FBTyxpR0FBMEI7QUFDakMsV0FBVyxDQUFDO0FBQ1o7QUFDQSxPQUFPLGlHQUEwQjtBQUNqQyxXQUFXLENBQUM7QUFDWjtBQUNBLE9BQU8sZ0dBQXlCO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8scUdBQThCO0FBQ3JDLFdBQVcsQ0FBQztBQUNaO0FBQ0E7QUFDQSxPQUFPLGtHQUEyQjtBQUNsQyxXQUFXLENBQUM7QUFDWjtBQUNBLE9BQU8sNkZBQXNCO0FBQzdCLFdBQVcsQ0FBQztBQUNaO0FBQ0EsT0FBTyx5RkFBa0I7QUFDekI7QUFDQTtBQUNBLE9BQU8saUdBQTBCO0FBQ2pDLFdBQVcsQ0FBQztBQUNaO0FBQ0EsT0FBTyw0RkFBcUI7QUFDNUIseURBQXlEO0FBQ3pELFdBQVcsQ0FBQztBQUNaO0FBQ0EsT0FBTyw4RkFBdUI7QUFDOUIsMERBQTBEO0FBQzFELFdBQVcsQ0FBQztBQUNaO0FBQ0EsT0FBTyxtR0FBNEI7QUFDbkMsV0FBVyxDQUFDO0FBQ1o7QUFDQSxPQUFPLGdHQUF5QjtBQUNoQyxXQUFXLENBQUM7QUFDWjtBQUNBLE9BQU8seUdBQWtDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sNkdBQXNDO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sbUdBQTRCO0FBQ25DLFdBQVcsQ0FBQztBQUNaO0FBQ0EsT0FBTyxrR0FBMkI7QUFDbEMsV0FBVyxDQUFDO0FBQ1o7QUFDQSxPQUFPLHNHQUErQjtBQUN0QyxXQUFXLENBQUM7QUFDWjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLFlBQVksQ0FBQzs7QUFFYjtBQUNBLHdCQUF3QixDQUFDLHVFQUF1RSxDQUFDO0FBQ2pHO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLHNCQUFzQixDQUFDLHVFQUF1RSxDQUFDO0FBQy9GLDBDQUEwQyxhQUFhLHdCQUF3QjtBQUMvRSx1Q0FBdUM7QUFDdkM7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0IscUZBQW1CO0FBQ3JDO0FBQ0E7QUFDQSxvQkFBb0IsQ0FBQztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxDQUFDO0FBQ0Y7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLFFBQVEsNkZBQXNCO0FBQzlCLDRCQUE0Qiw2RkFBc0I7QUFDbEQ7QUFDQTs7QUFFQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLHVCQUF1Qix5SUFBK0M7QUFDdEUsMEJBQTBCLDJJQUFnRDs7QUFFMUUseUJBQXlCLGtHQUF3QjtBQUNqRCwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLGtHQUF3QjtBQUNsRDtBQUNBLFlBQVkseUdBQStCLDJDQUEyQztBQUN0RixNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsMEJBQTBCLGtHQUF3QjtBQUNsRDtBQUNBLEtBQUsseUdBQStCO0FBQ3BDLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsUUFBUSw2RkFBc0I7QUFDOUIsNEJBQTRCLDZGQUFzQjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IscUZBQW1CO0FBQ3JDO0FBQ0E7QUFDQSxvQkFBb0IsQ0FBQztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBLGtCQUFrQixxRkFBbUI7QUFDckM7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQyxDQUFDO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0QkFBNEI7QUFDNUI7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxNQUFNLENBQUM7QUFDUDtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBLENBQUMsQ0FBQztBQUNGO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQixTQUFTOztBQUU5QjtBQUNBLDZDQUE2QztBQUM3QyxPQUFPO0FBQ1AsMENBQTBDO0FBQzFDLE9BQU87QUFDUCx1Q0FBdUM7QUFDdkM7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0Esd0NBQXdDO0FBQ3hDLE1BQU07QUFDTixxQ0FBcUM7QUFDckMsTUFBTTtBQUNOLGtDQUFrQztBQUNsQzs7QUFFQTs7QUFFQSxLQUFLO0FBQ0wsV0FBVztBQUNYLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsSUFBSTtBQUNKLFdBQVc7QUFDWCxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLEdBQUc7O0FBRUgseURBQXlEOztBQUV6RDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxNQUFNLENBQUM7QUFDUDtBQUNBOztBQUVBLGtCQUFrQixzQkFBc0I7QUFDeEM7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTs7QUFFTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsQ0FBQztBQUMzQixPQUFPO0FBQ1AsMEJBQTBCLENBQUM7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsQ0FBQztBQUMzQjtBQUNBLE9BQU87QUFDUCwwQkFBMEIsQ0FBQztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLENBQUM7QUFDM0IsT0FBTztBQUNQLDBCQUEwQixDQUFDO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLENBQUM7QUFDM0I7QUFDQSxPQUFPO0FBQ1AsMEJBQTBCLENBQUM7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixDQUFDO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0JBQWdCLElBQUksR0FBRyxJQUFJO0FBQzNCLDBJQUEwSSxFQUFFO0FBQzVJO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxRQUFRLENBQUM7QUFDVDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQyxPQUFPO0FBQ1AsNENBQTRDLE9BQU87QUFDbkQ7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixjQUFjO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDLE9BQU87QUFDekM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDOztBQUVELENBQUM7QUFDRDtBQUNBLEVBQUUsQ0FBQztBQUNILEdBQUc7QUFDSDtBQUNBLENBQUM7QUFDRDtBQUNBLEVBQUUsQ0FBQztBQUNILEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTCxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLDJCQUEyQjtBQUM5RCxNQUFNO0FBQ047QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLDJDQUEyQztBQUMvRSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBLGlHQUFpRztBQUNqRztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4Q0FBOEM7O0FBRTlDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0RkFBNEY7QUFDNUYsc0VBQXNFOztBQUV0RTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSCwrRUFBK0U7QUFDL0U7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFEQUFxRDtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRTtBQUNqRTtBQUNBLHlEQUF5RDtBQUN6RCx3REFBd0Q7QUFDeEQ7QUFDQTtBQUNBLHdEQUF3RDtBQUN4RDtBQUNBO0FBQ0EsS0FBSztBQUNMLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSCw4Q0FBOEM7QUFDOUMsNENBQTRDO0FBQzVDO0FBQ0EsNENBQTRDO0FBQzVDO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0EsR0FBRywyQ0FBMkM7QUFDOUMsNEJBQTRCO0FBQzVCLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrR0FBa0c7QUFDbEc7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwwREFBMEQ7QUFDMUQ7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOEJBQThCLHNDQUFzQztBQUNwRSxrQkFBa0Isc0JBQXNCO0FBQ3hDO0FBQ0E7QUFDQSwrQkFBK0IsdUNBQXVDLHNCQUFzQjtBQUM1RiwrQkFBK0IsdUNBQXVDLHFCQUFxQjtBQUMzRjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0Isb0JBQW9CO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRCx3REFBd0Qsc0RBQXNEO0FBQy9KLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxlQUFlLFVBQVU7QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUMsQ0FBQztBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUSwrRkFBdUI7QUFDL0I7O0FBRUEsa0JBQWtCLHFGQUFtQjtBQUNyQzs7QUFFQSxnQkFBZ0IsQ0FBQztBQUNqQjtBQUNBO0FBQ0E7O0FBRUEsNEVBQTRFOztBQUU1RSxrQkFBa0IsQ0FBQztBQUNuQixrQkFBa0IsQ0FBQzs7QUFFbkI7QUFDQTtBQUNBLGtCQUFrQixDQUFDO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxvRkFBb0Y7QUFDcEY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QiwyR0FBdUI7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSixHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMkJBQTJCLG1HQUFtQjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHlDQUF5QyxNQUFNO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0RBQXdEO0FBQ3hEO0FBQ0E7QUFDQSxJQUFJO0FBQ0osR0FBRywrREFBK0Q7QUFDbEU7QUFDQTtBQUNBLElBQUk7QUFDSixHQUFHLGlIQUFpSDtBQUNwSDtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUcseUhBQXlIO0FBQzVIO0FBQ0E7QUFDQSxJQUFJO0FBQ0osR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsQ0FBQztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGdCQUFnQiwyR0FBdUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTCw2QkFBNkIsQ0FBQyxzSUFBc0ksQ0FBQztBQUNySztBQUNBO0FBQ0EsR0FBRzs7QUFFSDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHNCQUFzQjtBQUN0Qjs7QUFFQTtBQUNBLHdCQUF3QjtBQUN4Qjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsT0FBTztBQUNsQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFVBQVU7QUFDckIsV0FBVyxTQUFTO0FBQ3BCLGFBQWE7QUFDYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsRUFBRSxLQUFLO0FBQ1A7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLENBQUM7O0FBRTFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGVBQWU7QUFDZjtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUMsNkZBQXNCLElBQUk7QUFDM0IsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQSwyQ0FBMkM7QUFDM0MseUNBQXlDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNEQUFzRDs7QUFFdEQ7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLFNBQVM7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxDQUFDLG1HQUF5QixZQUFZLDhGQUEyQjtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQSxDQUFDLHVHQUEyQjtBQUM1Qjs7QUFFQTtBQUNBLENBQUMseUpBQThDO0FBQy9DO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLENBQUM7QUFDNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0JBQWdCLENBQUM7QUFDakI7QUFDQSxVQUFVLENBQUMsd0JBQXdCLENBQUMsMEJBQTBCLENBQUMsdUNBQXVDLENBQUMsOENBQThDLENBQUMsdUNBQXVDLENBQUM7QUFDOUwsOEdBQThHLENBQUMsdUJBQXVCLENBQUMsc0RBQXNELENBQUMsdUJBQXVCLENBQUMsNEpBQTRKLDZGQUFzQjtBQUN4WTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFLHVIQUE2QjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSLFFBQVE7QUFDUjtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLENBQUM7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixJQUFJO0FBQ0osR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhEQUE4RCxrQkFBa0I7QUFDaEYsOEJBQThCLENBQUM7QUFDL0IsTUFBTTtBQUNOLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCw4QkFBOEIsQ0FBQztBQUMvQixNQUFNO0FBQ047QUFDQSxJQUFJO0FBQ0o7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvR2xvYmFsLmpzP2M2NjAiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gaW1wb3J0IHsgTG9jYWxDYWNoZURhdGEgfSBmcm9tICdleHBvcnRzLWxvYWRlcj9leHBvcnRzPUxvY2FsQ2FjaGVEYXRhIUAvZ2xvYmFsL0xvY2FsQ2FjaGVEYXRhJztcbmltcG9ydCB7IFRUVVVJRCB9IGZyb20gJ0AvZ2xvYmFsL1RUVVVJRCc7XG5pbXBvcnQgeyBUVEFQSSB9IGZyb20gJ0Avc2VydmljZXMvVGltZVRyZXhDbGllbnRBUEknO1xuaW1wb3J0IHsgRm9ybUl0ZW1UeXBlLCBXaWRnZXROYW1lc0RpYyB9IGZyb20gJ0AvZ2xvYmFsL3dpZGdldHMvc2VhcmNoX3BhbmVsL0Zvcm1JdGVtVHlwZSc7IC8vIFRPRE86IGR1cGxpY2F0ZWQgaW4gbWVyZ2VkIGpzIGZpbGVzLlxuaW1wb3J0IHsgUmF0ZUxpbWl0IH0gZnJvbSAnQC9nbG9iYWwvUmF0ZUxpbWl0JztcbmltcG9ydCAnQC9nbG9iYWwvd2lkZ2V0cy92aWV3X21pbl90YWIvVmlld01pblRhYkJhcic7XG5pbXBvcnQgeyBTZXJ2aWNlQ2FsbGVyIH0gZnJvbSAnQC9zZXJ2aWNlcy9TZXJ2aWNlQ2FsbGVyJztcbmltcG9ydCBUVEV2ZW50QnVzIGZyb20gJ0Avc2VydmljZXMvVFRFdmVudEJ1cyc7XG5pbXBvcnQgeyBIdG1sVGVtcGxhdGVzR2xvYmFsLCBUZW1wbGF0ZVR5cGUgfSBmcm9tICdAL3NlcnZpY2VzL0h0bWxUZW1wbGF0ZXMnO1xuaW1wb3J0IFRUVnVlVXRpbHMgZnJvbSAnQC9zZXJ2aWNlcy9UVFZ1ZVV0aWxzJztcbmltcG9ydCBUVE11bHRpRmFjdG9yQXV0aGVudGljYXRpb24gZnJvbSAnQC9jb21wb25lbnRzL2xvZ2luL1RUTXVsdGlGYWN0b3JBdXRoZW50aWNhdGlvbic7XG4vLyBpbXBvcnQgeyBjcmVhdGVBcHAgfSBmcm9tICd2dWUnOyAvLyBDdXJyZW50bHkgb25seSB1c2VkIGJ5IEdsb2JhbC5pbml0RWRpdFRlc3Rcbi8vIGltcG9ydCBUVEVkaXRWaWV3IGZyb20gJ0AvY29tcG9uZW50cy9UVEVkaXRWaWV3JzsgLy8gVXNlZCBieSBHbG9iYWwuaW5pdEVkaXRUZXN0IHdoaWNoIGlzIGN1cnJlbnRseSBjb21tZW50ZWQgb3V0IGFzIGl0cyBmb3IgdGVzdGluZyBvbmx5LlxuXG4vL0dsb2JhbCB2YXJpYWJsZXMgYW5kIGZ1bmN0aW9ucyB3aWxsIGJlIHVzZWQgZXZlcnl3aGVyZVxuZXhwb3J0IHZhciBHbG9iYWwgPSBmdW5jdGlvbigpIHtcbn07XG5HbG9iYWwuZXZlbnRfYnVzID0gbmV3IFRURXZlbnRCdXMoeyB2aWV3X2lkOiAnZ2xvYmFsJyB9KTtcbkdsb2JhbC5zb3J0T3JkZXJSZWdleCA9IC9eLShbMC05XXszLDl9KS0vO1xuR2xvYmFsLmN1cnJlbnRfcGluZyA9IC0xO1xuXG5HbG9iYWwuVU5JVF9URVNUX01PREUgPSBmYWxzZTtcblxuR2xvYmFsLmFwcF9taW5fd2lkdGggPSA5OTA7XG5cbkdsb2JhbC50aGVtZSA9ICdkZWZhdWx0JztcblxuLyoqXG4gKiBVSVJlYWR5U3RhdHVzOlxuICogMCAtIEdsb2JhbC5zZXRVSU5vdHJlYWR5KCkgLSB0aGUgVUkgaXMgbm90IHJlYWR5XG4gKiAxIC0gR2xvYmFsLnNldFVJUmVhZHkoKSAtIHRoZSBvdmVybGF5IGlzIG91dCBvZiB0aGUgd2F5IGJ1dCB1aSBpcyBub3QgZG9uZSByZW5kZXJpbmdcbiAqIDIgLSBHbG9iYWwuc2V0VUlJbml0Q29tcGxldGUoKSB0aGUgb3ZlcmxheSBpcyBkb25lIHJlbmRlcmluZ1xuICovXG5HbG9iYWwuVUlSZWFkeVN0YXR1cyA9IDA7XG5cbkdsb2JhbC5zaWduYWxfdGltZXIgPSBudWxsO1xuXG5HbG9iYWwuaXNTY3JvbGxlZEludG9WaWV3ID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHZhciAkZWxlbSA9IGVsZW07XG5cdHZhciAkd2luZG93ID0gJCggd2luZG93ICk7XG5cdHZhciBkb2NWaWV3VG9wID0gJHdpbmRvdy5zY3JvbGxUb3AoKTtcblx0dmFyIGRvY1ZpZXdCb3R0b20gPSBkb2NWaWV3VG9wICsgJHdpbmRvdy5oZWlnaHQoKTtcblx0aWYgKCAhJGVsZW0ub2Zmc2V0KCkgKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblx0dmFyIGVsZW1Ub3AgPSAkZWxlbS5vZmZzZXQoKS50b3A7XG5cdC8vdmFyIGVsZW1Cb3R0b20gPSBlbGVtVG9wICsgJGVsZW0uaGVpZ2h0KCk7XG5cdC8vKChlbGVtQm90dG9tIDw9IChkb2NWaWV3Qm90dG9tICsgMjAwKSkgJiYgKGVsZW1Ub3AgPj0gZG9jVmlld1RvcCkpO1xuXHRyZXR1cm4gZWxlbVRvcCA8IGRvY1ZpZXdCb3R0b207XG59O1xuXG4vL0NoZWNrIGlmIHRoZSBET00gKG5vdCBqUXVlcnkpIGVsZW1lbnQgcmVxdWlyZXMgYSB2ZXJ0aWNhbCBzY3JvbGxiYXIuXG5HbG9iYWwuaXNWZXJ0aWNhbFNjcm9sbEJhclJlcXVpcmVkID0gZnVuY3Rpb24oIGVsZW1lbnQgKSB7XG5cdHJldHVybiBlbGVtZW50ICYmIGVsZW1lbnQuc2Nyb2xsSGVpZ2h0ID4gZWxlbWVudC5jbGllbnRIZWlnaHQ7XG59O1xuXG4vL0NoZWNrIGlmIHRoZSBET00gKG5vdCBqUXVlcnkpIGVsZW1lbnQgcmVxdWlyZXMgYSBob3Jpem9udGFsIHNjcm9sbGJhci5cbkdsb2JhbC5pc0hvcml6b250YWxTY3JvbGxCYXJSZXF1aXJlZCA9IGZ1bmN0aW9uKCBlbGVtZW50ICkge1xuXHRyZXR1cm4gZWxlbWVudCAmJiBlbGVtZW50LnNjcm9sbFdpZHRoID4gZWxlbWVudC5jbGllbnRXaWR0aDtcbn07XG5cbi8vR2V0cyB0aGUgd2lkdGggb2YgdGhlIGJyb3dzZXJzIHNjcm9sbGJhci4gVGhpcyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB1c2VycyBPUy9icm93c2VyLlxuR2xvYmFsLmdldFNjcm9sbGJhcldpZHRoID0gZnVuY3Rpb24oKSB7XG5cdGlmICggTG9jYWxDYWNoZURhdGEuZ2V0U2Nyb2xsYmFyV2lkdGgoKSA+IDAgKSB7XG4gICAgICAgIHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRTY3JvbGxiYXJXaWR0aCgpO1xuICAgIH1cblxuXHRsZXQgc2Nyb2xsX2RpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cdHNjcm9sbF9kaXYuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuXHRzY3JvbGxfZGl2LnN0eWxlLm92ZXJmbG93ID0gJ3Njcm9sbCc7XG5cdGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoc2Nyb2xsX2Rpdik7XG5cdGxldCBzY3JvbGxfYmFyX3dpZHRoID0gc2Nyb2xsX2Rpdi5vZmZzZXRXaWR0aCAtIHNjcm9sbF9kaXYuY2xpZW50V2lkdGg7XG5cdGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoc2Nyb2xsX2Rpdik7XG5cblx0Ly9JZiBmb3Igc29tZSByZWFzb24gd2UgY2Fubm90IGdldCB0aGUgd2lkdGgsIGRlZmF1bHQgdGhlIHdpZHRoIHRvIDE3IHdoaWNoIGlzIG1vc3QgY29tbW9uIHZhbHVlLiAoV2luZG93c1xuXHRpZiAoICFzY3JvbGxfYmFyX3dpZHRoICkge1xuICAgICAgICBzY3JvbGxfYmFyX3dpZHRoID0gMTc7XG4gICAgfVxuXG5cdExvY2FsQ2FjaGVEYXRhLnNldFNjcm9sbEJhcldpZHRoKCBzY3JvbGxfYmFyX3dpZHRoICk7XG5cblx0cmV0dXJuIHNjcm9sbF9iYXJfd2lkdGg7XG59XG5cbi8vR2V0cyB0aGUgaGVpZ2h0IG9mIHRoZSBicm93c2VycyBzY3JvbGxiYXIuIFRoaXMgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdXNlcnMgT1MvYnJvd3Nlci5cbkdsb2JhbC5nZXRTY3JvbGxiYXJIZWlnaHQgPSBmdW5jdGlvbigpIHtcblx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRTY3JvbGxiYXJIZWlnaHQoKSA+IDAgKSB7XG5cdFx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldFNjcm9sbGJhckhlaWdodCgpO1xuXHR9XG5cblx0bGV0IHNjcm9sbF9kaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXHRzY3JvbGxfZGl2LnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcblx0c2Nyb2xsX2Rpdi5zdHlsZS5vdmVyZmxvdyA9ICdzY3JvbGwnO1xuXHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHNjcm9sbF9kaXYpO1xuXHRsZXQgc2Nyb2xsX2Jhcl9oZWlnaHQgPSBzY3JvbGxfZGl2Lm9mZnNldEhlaWdodCAtIHNjcm9sbF9kaXYuY2xpZW50SGVpZ2h0O1xuXHRkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHNjcm9sbF9kaXYpO1xuXG5cdC8vSWYgZm9yIHNvbWUgcmVhc29uIHdlIGNhbm5vdCBnZXQgdGhlIGhlaWdodCwgZGVmYXVsdCB0aGUgaGVpZ2h0IHRvIDE3IHdoaWNoIGlzIG1vc3QgY29tbW9uIHZhbHVlLiAoV2luZG93c1xuXHRpZiAoICFzY3JvbGxfYmFyX2hlaWdodCApIHtcblx0XHRzY3JvbGxfYmFyX2hlaWdodCA9IDE3O1xuICAgIH1cblxuXHRMb2NhbENhY2hlRGF0YS5zZXRTY3JvbGxCYXJIZWlnaHQoIHNjcm9sbF9iYXJfaGVpZ2h0ICk7XG5cblx0cmV0dXJuIHNjcm9sbF9iYXJfaGVpZ2h0O1xufVxuXG5HbG9iYWwuS0VZQ09ERVMgPSB7XG5cdCc0OCc6ICcwJyxcblx0JzQ5JzogJzEnLFxuXHQnNTAnOiAnMicsXG5cdCc1MSc6ICczJyxcblx0JzUyJzogJzQnLFxuXHQnNTMnOiAnNScsXG5cdCc1NCc6ICc2Jyxcblx0JzU1JzogJzcnLFxuXHQnNTYnOiAnOCcsXG5cdCc1OSc6ICc5Jyxcblx0JzY1JzogJ2EnLFxuXHQnNjYnOiAnYicsXG5cdCc2Nyc6ICdjJyxcblx0JzY4JzogJ2QnLFxuXHQnNjknOiAnZScsXG5cdCc3MCc6ICdmJyxcblx0JzcxJzogJ2cnLFxuXHQnNzInOiAnaCcsXG5cdCc3Myc6ICdpJyxcblx0Jzc0JzogJ2onLFxuXHQnNzUnOiAnaycsXG5cdCc3Nic6ICdsJyxcblx0Jzc3JzogJ20nLFxuXHQnNzgnOiAnbicsXG5cdCc3OSc6ICdvJyxcblx0JzgwJzogJ3AnLFxuXHQnODEnOiAncScsXG5cdCc4Mic6ICdyJyxcblx0JzgzJzogJ3MnLFxuXHQnODQnOiAndCcsXG5cdCc4NSc6ICd1Jyxcblx0Jzg2JzogJ3YnLFxuXHQnODcnOiAndycsXG5cdCc4OCc6ICd4Jyxcblx0Jzg5JzogJ3knLFxuXHQnOTAnOiAneidcbn07XG5cbkdsb2JhbC5uZWVkUmVsb2FkQnJvd3NlciA9IGZhbHNlOyAvLyBOZWVkIHJlbG9hZCBicm93c2VyIGFmdGVyIHNldCBuZXcgY29va2llLiBUbyBtYWtlIHJvdXRlciB3b3JrIGZvciBuZXcgc2Vzc2lvbi5cblxuLy8gdGhpcyBhdHRyaWJ1dGUgdXNlIHRvIGJsb2NrIFVJIGluIHNwZWljYWwgY2FzZSB0aGF0IHdlIGFsbG93IHVzZXJzIHRvIGNsaWNrIHBhcnQgb2YgdGhlbSBhbmQgYmxvY2sgb3RoZXIgcGFydHMuXG4vLyBGb3IgZXhhbXBsZSwgd2hlbiBvcGVuIGVkaXQgdmlldyB0byBibG9jayBjb250ZXh0IG1lbnUuXG5HbG9iYWwuYmxvY2tfdWkgPSBmYWxzZTtcblxuR2xvYmFsLnNlbmRFcnJvclJlcG9ydCA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgZXJyb3Jfc3RyaW5nID0gYXJndW1lbnRzWzBdO1xuXHR2YXIgZnJvbV9maWxlID0gYXJndW1lbnRzWzFdO1xuXHR2YXIgbGluZSA9IGFyZ3VtZW50c1syXTtcblx0dmFyIGNvbCA9IGFyZ3VtZW50c1szXTtcblx0dmFyIGVycm9yX29iaiA9IGFyZ3VtZW50c1s0XTsgLy9FcnJvciBvYmplY3QuXG5cblx0UmF0ZUxpbWl0LnNldElEKCAnc2VuZEVycm9yUmVwb3J0JyApO1xuXHRSYXRlTGltaXQuc2V0QWxsb3dlZENhbGxzKCA2ICk7XG5cdFJhdGVMaW1pdC5zZXRUaW1lRnJhbWUoIDcyMDAgKTsgLy8yaHJzXG5cblx0aWYgKCBSYXRlTGltaXQuY2hlY2soKSApIHtcblx0XHR2YXIgY2FwdHVyZVNjcmVlblNob3QgPSBmdW5jdGlvbiggZXJyb3JfbXNnLCBlcnJvcl9vYmogKSB7XG5cdFx0XHRpZiAoIEdsb2JhbC5pc0NhbnZhc1N1cHBvcnRlZCgpICYmIHR5cGVvZiBQcm9taXNlICE9PSAndW5kZWZpbmVkJyApIHsgLy9IVE1MMkNhbnZhcyByZXF1aXJlcyBwcm9taXNlcywgd2hpY2ggSUUxMSBkb2VzIG5vdCBoYXZlLlxuXHRcdFx0XHRodG1sMmNhbnZhcyggZG9jdW1lbnQuYm9keSApLnRoZW4oIGZ1bmN0aW9uKCBjYW52YXMgKSB7XG5cdFx0XHRcdFx0dmFyIGltYWdlX3N0cmluZyA9IGNhbnZhcy50b0RhdGFVUkwoKS5zcGxpdCggJywnIClbMV07XG5cdFx0XHRcdFx0c291cmNlTWFwU3RhY2tUcmFjZSggZXJyb3JfbXNnLCBlcnJvcl9vYmosIGltYWdlX3N0cmluZyApO1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzb3VyY2VNYXBTdGFja1RyYWNlKCBlcnJvcl9tc2csIGVycm9yX29iaiwgbnVsbCApO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR2YXIgc291cmNlTWFwU3RhY2tUcmFjZSA9IGZ1bmN0aW9uKCBlcnJvcl9tc2csIGVycm9yX29iaiwgaW1hZ2Vfc3RyaW5nICkge1xuXHRcdFx0aWYgKCBlcnJvcl9vYmogKSB7XG5cdFx0XHRcdHZhciBzdGFja3RyYWNlX2NhbGxiYWNrID0gZnVuY3Rpb24oIHN0YWNrZnJhbWVzLCBlcnJvcl9tc2csIGVycm9yX29iaiwgaW1hZ2Vfc3RyaW5nICkge1xuXHRcdFx0XHRcdHZhciBzdHJpbmdpZmllZF9zdGFjayA9IHN0YWNrZnJhbWVzLm1hcCggZnVuY3Rpb24oIHNmICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuICcgICcgKyBzZi50b1N0cmluZygpOyAvL0luZGVudCBzdGFjayB0cmFjZS5cblx0XHRcdFx0XHR9ICkuam9pbiggJ1xcbicgKTtcblxuXHRcdFx0XHRcdGVycm9yX21zZyA9IGVycm9yX21zZyArICdcXG5cXG5cXG4nICsgJ1N0YWNrIFRyYWNlIChNYXBwZWQpOiBcXG4nICsgZXJyb3Jfb2JqLm5hbWUgKyAnOiAnICsgZXJyb3Jfb2JqLm1lc3NhZ2UgKyAnXFxuJyArIHN0cmluZ2lmaWVkX3N0YWNrO1xuXHRcdFx0XHRcdGVycm9yX21zZyA9IGVycm9yX21zZyArICdcXG5cXG5cXG4nICsgJ1N0YWNrIFRyYWNlIChSYXcpOiBcXG4nICsgZXJyb3Jfb2JqLnN0YWNrO1xuXG5cdFx0XHRcdFx0c2VuZEVycm9yUmVwb3J0KCBlcnJvcl9tc2csIGVycm9yX29iaiwgaW1hZ2Vfc3RyaW5nICk7XG5cdFx0XHRcdH07XG5cblx0XHRcdFx0dmFyIHN0YWNrdHJhY2VfZXJyYmFjayA9IGZ1bmN0aW9uKCBlcnJvcl9tc2csIGVycm9yX29iaiwgaW1hZ2Vfc3RyaW5nICkge1xuXHRcdFx0XHRcdGNvbnNvbGUuZXJyb3IoICdFUlJPUjogVW5hYmxlIHRvIHNvdXJjZSBtYXAgc3RhY2sgdHJhY2UhJyApO1xuXHRcdFx0XHRcdHNlbmRFcnJvclJlcG9ydCggZXJyb3JfbXNnLCBlcnJvcl9vYmosIGltYWdlX3N0cmluZyApO1xuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdFN0YWNrVHJhY2UuZnJvbUVycm9yKCBlcnJvcl9vYmogKS50aGVuKCBzdGFja2ZyYW1lcyA9PiBzdGFja3RyYWNlX2NhbGxiYWNrKCBzdGFja2ZyYW1lcywgZXJyb3JfbXNnLCBlcnJvcl9vYmosIGltYWdlX3N0cmluZyApICkuY2F0Y2goIGVycm9yID0+IHN0YWNrdHJhY2VfZXJyYmFjayggZXJyb3JfbXNnLCBlcnJvcl9vYmosIGltYWdlX3N0cmluZyApICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzZW5kRXJyb3JSZXBvcnQoIGVycm9yX21zZywgZXJyb3Jfb2JqLCBpbWFnZV9zdHJpbmcgKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dmFyIHNlbmRFcnJvclJlcG9ydCA9IGZ1bmN0aW9uKCBlcnJvcl9tc2csIGVycm9yX29iaiwgaW1hZ2Vfc3RyaW5nICkge1xuXHRcdFx0RGVidWcuVGV4dCggJ0VSUk9SOiAnICsgZXJyb3JfbXNnLCAnR2xvYmFsLmpzJywgJycsICdzZW5kRXJyb3JSZXBvcnQnLCAxICk7XG5cblx0XHRcdHZhciBhcGlfYXV0aGVudGljYXRpb24gPSBUVEFQSS5BUElBdXRoZW50aWNhdGlvbjtcblx0XHRcdGFwaV9hdXRoZW50aWNhdGlvbi5zZW5kRXJyb3JSZXBvcnQoIGVycm9yX21zZywgaW1hZ2Vfc3RyaW5nLCB7XG5cdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdFx0XHRcdGlmICggIUdsb2JhbC5kb250X2NoZWNrX2Jyb3dzZXJfY2FjaGUgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLnByb2R1Y3Rpb24gPT09IHRydWUgJiYgcmVzdWx0LmdldFJlc3VsdCgpICE9PSBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYXBwbGljYXRpb25fYnVpbGQgKSB7XG5cdFx0XHRcdFx0XHRyZXN1bHQgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cdFx0XHRcdFx0XHR2YXIgbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91ciB3ZWIgYnJvd3NlciBpcyBjYWNoaW5nIGluY29ycmVjdCBkYXRhLCBwbGVhc2UgcHJlc3MgdGhlIHJlZnJlc2ggYnV0dG9uIG9uIHlvdXIgd2ViIGJyb3dzZXIgb3IgbG9nIG91dCwgY2xlYXIgeW91ciB3ZWIgYnJvd3NlcnMgY2FjaGUgYW5kIHRyeSBsb2dnaW5nIGluIGFnYWluLicgKSArICc8YnI+PGJyPicgKyAkLmkxOG4uXyggJ0xvY2FsIFZlcnNpb24nICkgKyAnOiAgJyArIHJlc3VsdCArICc8YnI+JyArICQuaTE4bi5fKCAnUmVtb3RlIFZlcnNpb24nICkgKyAnOiAnICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkO1xuXHRcdFx0XHRcdFx0R2xvYmFsLmRvbnRfY2hlY2tfYnJvd3Nlcl9jYWNoZSA9IHRydWU7XG5cdFx0XHRcdFx0XHRHbG9iYWwuc2VuZEVycm9yUmVwb3J0KCAnWW91ciB3ZWIgYnJvd3NlciBpcyBjYWNoaW5nIGluY29ycmVjdCBkYXRhLiBMb2NhbCBWZXJzaW9uJyArICc6ICAnICsgcmVzdWx0ICsgJyBSZW1vdGUgVmVyc2lvbicgKyAnOiAnICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkLCBTZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsLCAnJywgJycsICcnICk7XG5cblx0XHRcdFx0XHRcdHZhciB0aW1lb3V0X2hhbmRsZXIgPSB3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoIHRydWUgKTtcblx0XHRcdFx0XHRcdH0sIDEyMDAwMCApO1xuXG5cdFx0XHRcdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dBbGVydCggbWVzc2FnZSwgJycsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5sb2FkZWRTY3JpcHROYW1lcyA9IHt9O1xuXHRcdFx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnSW5jb3JyZWN0IGNhY2hlLi4uIEZvcmNpbmcgcmVsb2FkIGFmdGVyIEpTIGV4Y2VwdGlvbi4uLicsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2NhY2hpbmdJbmNvcnJlY3REYXRhJywgMTAgKTtcblx0XHRcdFx0XHRcdFx0d2luZG93LmNsZWFyVGltZW91dCggdGltZW91dF9oYW5kbGVyICk7XG5cdFx0XHRcdFx0XHRcdHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoIHRydWUgKTtcblx0XHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBHbG9iYWwuZG9udF9jaGVja19icm93c2VyX2NhY2hlICkge1xuXHRcdFx0XHRcdFx0R2xvYmFsLmRvbnRfY2hlY2tfYnJvd3Nlcl9jYWNoZSA9IGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH07XG5cblx0XHR2YXIgbG9naW5fdXNlciA9IExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlcigpO1xuXG5cdFx0Lypcblx0XHQgKiBKYXZhU2NyaXB0IGV4Y2VwdGlvbiBpZ25vcmUgbGlzdFxuXHRcdCAqL1xuXHRcdGlmICggZnJvbV9maWxlICYmIHR5cGVvZiBmcm9tX2ZpbGUgPT0gJ3N0cmluZycgJiYgZnJvbV9maWxlLmluZGV4T2YoICdleHRlbnNpb246Ly8nICkgPj0gMCApIHsgLy9FcnJvciBoYXBwZW5lZCBpbiBzb21lIENocm9tZSBFeHRlbnNpb24sIGlnbm9yZS5cblx0XHRcdGNvbnNvbGUuZXJyb3IoICdJZ25vcmluZyBqYXZhc2NyaXB0IGV4Y2VwdGlvbiBmcm9tIGJyb3dzZXIgZXh0ZW5zaW9uIG91dHNpZGUgb2Ygb3VyIGNvbnRyb2wuLi4nICk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCBlcnJvcl9zdHJpbmcuaW5kZXhPZiggJ1NjcmlwdCBlcnJvcicgKSA+PSAwIHx8IC8vU2NyaXB0IGVycm9yLiBpbjogIGxpbmU6IDAgLS0gTGlrZWx5IGJyb3dzZXIgZXh0ZW5zaW9ucyBvciBlcnJvcnMgZnJvbSBpbmplY3RlZCBvciBvdXRzaWRlIGphdmFzY3JpcHQuXG5cdFx0XHRlcnJvcl9zdHJpbmcuaW5kZXhPZiggJ1Vuc3BlY2lmaWVkIGVycm9yJyApID49IDAgfHwgLy9Gcm9tIElFOiBVbnNwZWNpZmllZCBlcnJvci4gaW4gTi9BIGxpbmUgMVxuXHRcdFx0ZXJyb3Jfc3RyaW5nLmluZGV4T2YoICdUeXBlRXJyb3I6IFxcJ251bGxcXCcgaXMgbm90IGFuIG9iamVjdCcgKSA+PSAwIHx8XG5cdFx0XHRlcnJvcl9zdHJpbmcuaW5kZXhPZiggJ19hdmFzdF9zdWJtaXQnICkgPj0gMCB8fCAvL0Vycm9ycyBmcm9tIGFudGktdmlydXMgZXh0ZW5zaW9uXG5cdFx0XHRlcnJvcl9zdHJpbmcuaW5kZXhPZiggJ1Jlc2l6ZU9ic2VydmVyIGxvb3AgbGltaXQgZXhjZWVkZWQnICkgPj0gMCB8fFxuXHRcdFx0ZXJyb3Jfc3RyaW5nLmluZGV4T2YoICdnb29nbGV0YWcnICkgPj0gMCB8fCAvL0Vycm9ycyBmcm9tIGdvb2dsZSB0YWcgZXh0ZW5zaW9uIC0tIFVuY2F1Z2h0IFR5cGVFcnJvcjogQ2Fubm90IHJlZGVmaW5lIHByb3BlcnR5OiBnb29nbGV0YWdcblx0XHRcdGVycm9yX3N0cmluZy5pbmRleE9mKCAnTlNfRVJST1JfJyApID49IDAgfHxcblx0XHRcdGVycm9yX3N0cmluZy5pbmRleE9mKCAnTlNfRVJST1JfT1VUX09GX01FTU9SWScgKSA+PSAwIHx8XG5cdFx0XHRlcnJvcl9zdHJpbmcuaW5kZXhPZiggJ05QT2JqZWN0JyApID49IDAgKSB7IC8vRXJyb3IgY2FsbGluZyBtZXRob2Qgb24gTlBPYmplY3QgLSBsaWtlbHkgY2F1c2VkIGJ5IGFuIGV4dGVuc2lvbiBvciBwbHVnaW4gaW4gdGhlIGJyb3dzZXJcblx0XHRcdGNvbnNvbGUuZXJyb3IoICdJZ25vcmluZyBqYXZhc2NyaXB0IGV4Y2VwdGlvbiBvdXRzaWRlIG9mIG91ciBjb250cm9sLi4uJyApO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggR2xvYmFsLmlkbGVfdGltZSA+IDE1ICkge1xuXHRcdFx0RGVidWcuVGV4dCggJ1VzZXIgaW5hY3RpdmUgbW9yZSB0aGFuIDE1IG1pbnMsIG5vdCBzZW5kaW5nIGVycm9yIHJlcG9ydC4nLCAnR2xvYmFsLmpzJywgJycsICdzZW5kRXJyb3JSZXBvcnQnLCAxICk7XG5cdFx0XHRpZiAoIHR5cGVvZiAoIGd0YWcgKSAhPT0gJ3VuZGVmaW5lZCcgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFuYWx5dGljc19lbmFibGVkID09PSB0cnVlICkge1xuXHRcdFx0XHRndGFnKCAnZXZlbnQnLCAnZXhjZXB0aW9uJywge1xuXHRcdFx0XHRcdCdleERlc2NyaXB0aW9uJzogJ1Nlc3Npb24gSWRsZTogJyArIGVycm9yX3N0cmluZyArICcgRmlsZTogJyArICggKCBmcm9tX2ZpbGUgKSA/IGZyb21fZmlsZS5yZXBsYWNlKCBHbG9iYWwuZ2V0QmFzZVVSTCgpLCAnJyApIDogJ04vQScgKSArICcgTGluZTogJyArIGxpbmUsXG5cdFx0XHRcdFx0J2V4RmF0YWwnOiBmYWxzZVxuXHRcdFx0XHR9IClcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBlcnJvcjtcblxuXHRcdC8vQlVHIzIwNjYgLSBhbGxvdyB0aGlzIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBlYXJsaWVyLlxuXHRcdHZhciBzY3JpcHRfbmFtZSA9ICd+dW5rbm93bn4nO1xuXHRcdGlmICggR2xvYmFsLmlzU2V0KCBMb2NhbENhY2hlRGF0YSApICYmIEdsb2JhbC5pc1NldCggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlciApICYmIEdsb2JhbC5pc1NldCggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5zY3JpcHRfbmFtZSApICkge1xuXHRcdFx0c2NyaXB0X25hbWUgPSBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnNjcmlwdF9uYW1lO1xuXHRcdH1cblxuXHRcdHZhciBwcmVfbG9naW5fZGF0YTtcblx0XHRpZiAoIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YSApIHtcblx0XHRcdHByZV9sb2dpbl9kYXRhID0gQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcmVfbG9naW5fZGF0YSA9IG51bGw7XG5cdFx0fVxuXG5cdFx0dmFyIGN1cnJlbnRfY29tcGFueV9vYmo7XG5cdFx0aWYgKCBHbG9iYWwuaXNTZXQoIExvY2FsQ2FjaGVEYXRhICkgJiYgTG9jYWxDYWNoZURhdGFbJ2N1cnJlbnRfY29tcGFueSddICkgeyAvL2dldEN1cnJlbnRDb21wYW55KCkgd2hpY2ggaW4gdHVybiBjYWxscyBnZXRSZXF1aXJlZExvY2FsQ2FjaGUoKSwgd2hpY2ggY2FuIGNhbGwgc2VuZEVycm9SZXBvcnQgY2F1c2luZyBhIGxvb3AuIFNvIHRyeSB0byBwcmV2ZW50IHRoYXQgYnkgY2hlY2tpbmcgTG9jYWxDYWNoZURhdGFbJ2N1cnJlbnRfY29tcGFueSddIGZpcnN0LlxuXHRcdFx0Y3VycmVudF9jb21wYW55X29iaiA9IExvY2FsQ2FjaGVEYXRhLmdldEN1cnJlbnRDb21wYW55KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1cnJlbnRfY29tcGFueV9vYmogPSBudWxsO1xuXHRcdH1cblxuXHRcdGlmICggbG9naW5fdXNlciAmJiBEZWJ1Zy52YXJEdW1wICkge1xuXHRcdFx0ZXJyb3IgPSAnQ2xpZW50IFZlcnNpb246ICcgKyBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYXBwbGljYXRpb25fYnVpbGQgKyAnXFxuXFxuVW5jYXVnaHQgRXJyb3IgRnJvbTogJyArIHNjcmlwdF9uYW1lICsgJ1xcblxcbkVycm9yOiAnICsgZXJyb3Jfc3RyaW5nICsgJyBpbjogJyArIGZyb21fZmlsZSArICcgbGluZTogJyArIGxpbmUgKyAnOicgKyBjb2wgKyAnXFxuXFxuVXNlcjogJyArIGxvZ2luX3VzZXIudXNlcl9uYW1lICsgJ1xcblxcblVSTDogJyArIHdpbmRvdy5sb2NhdGlvbi5ocmVmICsgJ1xcblxcblVzZXItQWdlbnQ6ICcgKyBuYXZpZ2F0b3IudXNlckFnZW50ICsgJyAnICsgJ1xcblxcbklFOiAnICsgd2luZG93LmllICsgJ1xcblxcbkN1cnJlbnQgUGluZzogJyArIEdsb2JhbC5jdXJyZW50X3BpbmcgKyAnXFxuXFxuSWRsZSBUaW1lOiAnICsgR2xvYmFsLmlkbGVfdGltZSArICdcXG5cXG5TZXNzaW9uIElEIEtleTogJyArIExvY2FsQ2FjaGVEYXRhLmdldFNlc3Npb25JRCgpICsgJ1xcblxcbkN1cnJlbnQgVXNlciBPYmplY3Q6IFxcbicgKyBEZWJ1Zy52YXJEdW1wKCBsb2dpbl91c2VyICkgKyAnXFxuXFxuQ3VycmVudCBDb21wYW55IE9iamVjdDogXFxuJyArIERlYnVnLnZhckR1bXAoIGN1cnJlbnRfY29tcGFueV9vYmogKSArICdcXG5cXG5QcmVMb2dpbjogXFxuJyArIERlYnVnLnZhckR1bXAoIHByZV9sb2dpbl9kYXRhICkgKyAnICc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGVycm9yID0gJ0NsaWVudCBWZXJzaW9uOiAnICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkICsgJ1xcblxcblVuY2F1Z2h0IEVycm9yIEZyb206ICcgKyBzY3JpcHRfbmFtZSArICdcXG5cXG5FcnJvcjogJyArIGVycm9yX3N0cmluZyArICcgaW46ICcgKyBmcm9tX2ZpbGUgKyAnIGxpbmU6ICcgKyBsaW5lICsgJzonICsgY29sICsgJ1xcblxcblVzZXI6IE4vQScgKyAnXFxuXFxuVVJMOiAnICsgd2luZG93LmxvY2F0aW9uLmhyZWYgKyAnICcgKyAnXFxuXFxuVXNlci1BZ2VudDogJyArIG5hdmlnYXRvci51c2VyQWdlbnQgKyAnICcgKyAnXFxuXFxuSUU6ICcgKyB3aW5kb3cuaWU7XG5cdFx0fVxuXG5cdFx0Y29uc29sZS5lcnJvciggJ0pBVkFTQ1JJUFQgRVhDRVBUSU9OOlxcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxcbicgKyBlcnJvciArICdcXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nICk7XG5cdFx0ZGVidWdnZXI7XG5cblx0XHQvL1doZW4gbm90IGluIHByb2R1Y3Rpb24gbW9kZSwgcG9wdXAgYWxlcnQgYm94IGFueXRpbWUgYW4gZXhjZXB0aW9uIGFwcGVhcnMgc28gaXQgY2FuJ3QgYmUgbWlzc2VkLlxuXHRcdGlmICggQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLnByb2R1Y3Rpb24gIT09IHRydWUgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmRlbW9fbW9kZSAhPT0gdHJ1ZSAmJiBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuc2FuZGJveCAhPT0gdHJ1ZSApIHtcblx0XHRcdGFsZXJ0KCAnSkFWQVNDUklQVCBFWENFUFRJT046XFxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXFxuJyArIGVycm9yICsgJ1xcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScgKTtcblx0XHR9XG5cblx0XHRpZiAoIHR5cGVvZiAoIGd0YWcgKSAhPT0gJ3VuZGVmaW5lZCcgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFuYWx5dGljc19lbmFibGVkID09PSB0cnVlICkge1xuXHRcdFx0Ly8gU2VuZCBhbiBleGNlcHRpb24gaGl0IHRvIEdvb2dsZSBBbmFseXRpY3MuIE11c3QgYmUgODE5MiBieXRlcyBvciBzbWFsbGVyLlxuXHRcdFx0Ly8gU3RyaXAgdGhlIGRvbWFpbiBwYXJ0IG9mZiB0aGUgVVJMIG9uICdmcm9tX2ZpbGUnIHRvIGJldHRlciBhY2NvdW50IGZvciBzaW1pbGFyIGVycm9ycy5cblx0XHRcdGd0YWcoICdldmVudCcsICdleGNlcHRpb24nLCB7XG5cdFx0XHRcdCdleERlc2NyaXB0aW9uJzogZXJyb3Jfc3RyaW5nICsgJyBGaWxlOiAnICsgKCAoIGZyb21fZmlsZSApID8gZnJvbV9maWxlLnJlcGxhY2UoIEdsb2JhbC5nZXRCYXNlVVJMKCksICcnICkgOiAnTi9BJyApICsgJyBMaW5lOiAnICsgbGluZSArICc6JyArIGNvbCxcblx0XHRcdFx0J2V4RmF0YWwnOiBmYWxzZVxuXHRcdFx0fSApXG5cdFx0fVxuXG5cdFx0Ly9Eb24ndCBzZW5kIGVycm9yIHJlcG9ydCBpZiBleGNlcHRpb24gbm90IGhhcHBlbnMgaW4gb3VyIGNvZGVzLlxuXHRcdC8vZnJvbV9maWxlIHNob3VsZCBhbHdheXMgY29udGFpbnMgdGhlIHJvb3QgdXJsXG5cdFx0Ly9JZiBVUkwgaXMgbm90IHNlbnQgYnkgSUUsIGFzc3VtZSBpdHMgb3VyIG93biBjb2RlIGFuZCByZXBvcnQgdGhlIGVycm9yIHN0aWxsLlxuXHRcdC8vIE1vZGVybiBicm93c2VycyB3b24ndCBzZW5kIGVycm9yIHJlcG9ydHMgZnJvbSBvdGhlciBkb21haW5zIGR1ZSB0byBzZWN1cml0eSBpc3N1ZXMgbm93LCBzbyBJIHRoaW5rIHRoaXMgY2FuIGJlIHJlbW92ZWQuXG5cdFx0Ly8gaWYgKCBmcm9tX2ZpbGUgJiYgZnJvbV9maWxlLmluZGV4T2YoIFNlcnZpY2VDYWxsZXIucm9vdF91cmwgKSA8IDAgKSB7XG5cdFx0Ly8gXHREZWJ1Zy5UZXh0KCAnRXhjZXB0aW9uIGNhdWdodCBmcm9tIHVuYXV0aG9yaXplZCBzb3VyY2UsIG5vdCBzZW5kaW5nIHJlcG9ydC4gU291cmNlOiBcIicgKyBTZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsICsgJ1wiIFNjcmlwdDogJyArIGZyb21fZmlsZSwgJ0dsb2JhbC5qcycsICcnLCAnc2VuZEVycm9yUmVwb3J0JywgMSApO1xuXHRcdC8vIFx0cmV0dXJuO1xuXHRcdC8vIH1cblxuXHRcdGlmICggY3VycmVudF9jb21wYW55X29iaiApIHsgLy9nZXRDdXJyZW50Q29tcGFueSgpIHdoaWNoIGluIHR1cm4gY2FsbHMgZ2V0UmVxdWlyZWRMb2NhbENhY2hlKCksIHdoaWNoIGNhbiBjYWxsIHNlbmRFcnJvUmVwb3J0IGNhdXNpbmcgYSBsb29wLiBTbyB0cnkgdG8gcHJldmVudCB0aGF0IGJ5IGNoZWNraW5nIExvY2FsQ2FjaGVEYXRhWydjdXJyZW50X2NvbXBhbnknXSBmaXJzdC5cblx0XHRcdGVycm9yID0gZXJyb3IgKyAnXFxuXFxuJyArICdQcm9kdWN0IEVkaXRpb246ICcgKyBjdXJyZW50X2NvbXBhbnlfb2JqLnByb2R1Y3RfZWRpdGlvbl9pZDtcblx0XHR9XG5cblx0XHRlcnJvciA9IGVycm9yICsgJ1xcblxcblxcbicgKyAnQ2xpY2tlZCB0YXJnZXQgc3RhY2tzOiAnICsgSlNPTi5zdHJpbmdpZnkoIExvY2FsQ2FjaGVEYXRhLnVpX2NsaWNrX3N0YWNrLCB1bmRlZmluZWQsIDIgKTtcblx0XHRlcnJvciA9IGVycm9yICsgJ1xcblxcblxcbicgKyAnQVBJIHN0YWNrczogJyArIEpTT04uc3RyaW5naWZ5KCBMb2NhbENhY2hlRGF0YS5hcGlfc3RhY2ssIHVuZGVmaW5lZCwgMiApO1xuXG5cdFx0Y2FwdHVyZVNjcmVlblNob3QoIGVycm9yLCBlcnJvcl9vYmogKTtcblx0fVxufTtcblxuR2xvYmFsLmluaXRTdGF0aWNTdHJpbmdzID0gZnVuY3Rpb24oKSB7XG5cdEdsb2JhbC5uZXR3b3JrX2xvc3RfbXNnID0gJC5pMThuLl8oICdUaGUgbmV0d29yayBjb25uZWN0aW9uIHdhcyBsb3N0LiBQbGVhc2UgY2hlY2sgeW91ciBuZXR3b3JrIGNvbm5lY3Rpb24gdGhlbiB0cnkgYWdhaW4uJyApO1xuXG5cdEdsb2JhbC5hbnlfaXRlbSA9ICctLSAnICsgJC5pMThuLl8oICdBbnknICkgKyAnIC0tJztcblxuXHRHbG9iYWwuYWxsX2l0ZW0gPSAnLS0gJyArICQuaTE4bi5fKCAnQWxsJyApICsgJyAtLSc7XG5cblx0R2xvYmFsLnJvb3RfaXRlbSA9ICQuaTE4bi5fKCAnUm9vdCcgKTtcblxuXHRHbG9iYWwubG9hZGluZ19sYWJlbCA9ICcuLi4nO1xuXG5cdEdsb2JhbC5jdXN0b21pemVfaXRlbSA9ICctLSAnICsgJC5pMThuLl8oICdDdXN0b21pemUnICkgKyAnIC0tJztcblxuXHRHbG9iYWwuZGVmYXVsdF9pdGVtID0gJy0tICcgKyAkLmkxOG4uXyggJ0RlZmF1bHQnICkgKyAnIC0tJztcblxuXHRHbG9iYWwuc2VsZWN0ZWRfaXRlbSA9ICctLSAnICsgJC5pMThuLl8oICdTZWxlY3RlZCcgKSArICcgLS0nO1xuXG5cdEdsb2JhbC5vcGVuX2l0ZW0gPSAnLS0gJyArICQuaTE4bi5fKCAnT3BlbicgKSArICcgLS0nO1xuXG5cdEdsb2JhbC5lbXB0eV9pdGVtID0gJy0tICcgKyAkLmkxOG4uXyggJ05vbmUnICkgKyAnIC0tJztcblxuXHRHbG9iYWwudmlld19tb2RlX21lc3NhZ2UgPSAkLmkxOG4uXyggJ1lvdSBhcmUgY3VycmVudGx5IGluIFxcJ1ZpZXdcXCcgbW9kZScgKTtcblxuXHRHbG9iYWwudmlld19tb2RlX2VkaXRfbWVzc2FnZSA9ICQuaTE4bi5fKCAnaW5zdGVhZCBjbGljayB0aGUgXFwnRWRpdFxcJyBpY29uIHRvIG1vZGlmeSBmaWVsZHMnICk7IC8vRG9lcyBub3Qgc3RhcnQgd2l0aCBhIGNhcGl0YWwgYXMgaXQgaXMgYXBwZW5kZWQgdGV4dC5cblxuXHRHbG9iYWwubm9fcmVzdWx0X21lc3NhZ2UgPSAkLmkxOG4uXyggJ05vIFJlc3VsdHMgRm91bmQnICk7XG5cblx0R2xvYmFsLnNhdmVfYW5kX2NvbnRpbnVlX21lc3NhZ2UgPSAkLmkxOG4uXyggJ1BsZWFzZSBzYXZlIHRoaXMgcmVjb3JkIGJlZm9yZSBtb2RpZnlpbmcgYW55IHJlbGF0ZWQgZGF0YScgKTtcblxuXHRHbG9iYWwubm9faGllcmFyY2h5X21lc3NhZ2UgPSAkLmkxOG4uXyggJ05vIEhpZXJhcmNoaWVzIERlZmluZWQnICk7XG5cblx0R2xvYmFsLm1vZGlmeV9hbGVydF9tZXNzYWdlID0gJC5pMThuLl8oICdZb3UgaGF2ZSBtb2RpZmllZCBkYXRhIHdpdGhvdXQgc2F2aW5nLCBhcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gY29udGludWUgYW5kIGxvc2UgeW91ciBjaGFuZ2VzJyApO1xuXG5cdEdsb2JhbC5jb25maXJtX29uX2V4aXRfbWVzc2FnZSA9ICQuaTE4bi5fKCAnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGNvbnRpbnVlIHdpdGhvdXQgc2F2aW5nPycgKTtcblxuXHRHbG9iYWwuZGVsZXRlX2NvbmZpcm1fbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91IGFyZSBhYm91dCB0byBkZWxldGUgZGF0YSwgb25jZSBkYXRhIGlzIGRlbGV0ZWQgaXQgY2FuIG5vdCBiZSByZWNvdmVyZWQuPGJyPkFyZSB5b3Ugc3VyZSB5b3Ugd2lzaCB0byBjb250aW51ZT8nICk7XG5cblx0R2xvYmFsLmRlbGV0ZV9kYXNobGV0X2NvbmZpcm1fbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91IGFyZSBhYm91dCB0byBkZWxldGUgdGhpcyBkYXNobGV0LCBvbmNlIGEgZGFzaGxldCBpcyBkZWxldGVkIGl0IGNhbiBub3QgYmUgcmVjb3ZlcmVkLjxicj5BcmUgeW91IHN1cmUgeW91IHdpc2ggdG8gY29udGludWU/JyApO1xuXG5cdEdsb2JhbC5jb3B5X211bHRpcGxlX2NvbmZpcm1fbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91IGFyZSBhYm91dCB0byBjb3B5IG11bHRpcGxlIHJlY29yZHMuPGJyPkFyZSB5b3Ugc3VyZSB5b3Ugd2lzaCB0byBjb250aW51ZT8nICk7XG5cblx0R2xvYmFsLmF1dG9fYXJyYW5nZV9kYXNobGV0X2NvbmZpcm1fbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91IGFyZSBhYm91dCB0byByZXN0b3JlIGFsbCBkYXNobGV0cyB0byB0aGVpciBkZWZhdWx0IHNpemUvbGF5b3V0Ljxicj5BcmUgeW91IHN1cmUgeW91IHdpc2ggdG8gY29udGludWU/JyApO1xuXG5cdEdsb2JhbC5yZXNlX2FsbF9kYXNobGV0X2NvbmZpcm1fbWVzc2FnZSA9ICQuaTE4bi5fKCAnWW91IGFyZSBhYm91dCB0byByZW1vdmUgYWxsIHlvdXIgY3VzdG9taXplZCBkYXNobGV0cyBhbmQgcmVzdG9yZSB0aGVtIGJhY2sgdG8gdGhlIGRlZmF1bHRzLjxicj5BcmUgeW91IHN1cmUgeW91IHdpc2ggdG8gY29udGludWU/JyApO1xufTtcblxuR2xvYmFsLmdldFVwZ3JhZGVNZXNzYWdlID0gZnVuY3Rpb24oKSB7XG5cdHZhciBtZXNzYWdlID0gJC5pMThuLl8oICdUaGlzIGZ1bmN0aW9uYWxpdHkgaXMgb25seSBhdmFpbGFibGUgaW4nICkgK1xuXHRcdCcgJyArIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luRGF0YSgpLmFwcGxpY2F0aW9uX25hbWUgKyAnICc7XG5cblx0aWYgKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA8IDE1ICkge1xuXHRcdC8vRG8gbm90IG1lbnRpb24gcHJvZmVzc2lvbmFsIGlmIHVzZXIgaXMgb24gcHJvZmVzc2lvbmFsIGVkaXRpb24uXG5cdFx0bWVzc2FnZSArPSAkLmkxOG4uXyggJ1Byb2Zlc3Npb25hbCwgQ29ycG9yYXRlLCBvciBFbnRlcnByaXNlIEVkaXRpb25zLicgKTtcblx0fSBlbHNlIGlmICggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPCAyMCApIHtcblx0XHQvL0RvIG5vdCBtZW50aW9uIGNvcnBvcmF0ZSBpZiB1c2VyIGlzIG9uIGNvcnBvcmF0ZSBlZGl0aW9uLlxuXHRcdG1lc3NhZ2UgKz0gJC5pMThuLl8oICdDb3Jwb3JhdGUgb3IgRW50ZXJwcmlzZSBFZGl0aW9ucy4nICk7XG5cdH0gZWxzZSB7XG5cdFx0bWVzc2FnZSArPSAkLmkxOG4uXyggJ0VudGVycHJpc2UgRWRpdGlvbnMuJyApO1xuXHR9XG5cblx0bWVzc2FnZSArPSAnICcgKyAkLmkxOG4uXyggJ0ZvciBtb3JlIGluZm9ybWF0aW9uIHBsZWFzZSB2aXNpdCcgKSArICcgPGEgaHJlZj1cImh0dHBzOi8vd3d3LnRpbWV0cmV4LmNvbS9yP2lkPTgxMFwiIHRhcmdldD1cIl9ibGFua1wiPnd3dy50aW1ldHJleC5jb208L2E+JztcblxuXHRHbG9iYWwudHJhY2tWaWV3KCAnQ29tbXVuaXR5VXBncmFkZScgKTtcblx0cmV0dXJuIG1lc3NhZ2U7XG59O1xuXG5HbG9iYWwuZG9QaW5nSWZOZWNlc3NhcnkgPSBmdW5jdGlvbigpIHtcblx0aWYgKCBHbG9iYWwuaWRsZV90aW1lIDwgTWF0aC5taW4oIDE1LCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuc2Vzc2lvbl9pZGxlX3RpbWVvdXQgLyA2MCApICkgeyAvL2lkbGVfdGltZSBpcyBtaW51dGVzLCBzZXNzaW9uX2lkbGVfdGltZW91dCBpcyBzZWNvbmRzLlxuXHRcdEdsb2JhbC5pZGxlX3RpbWUgPSAwO1xuXHRcdHJldHVybjtcblx0fVxuXG5cdERlYnVnLlRleHQoICdVc2VyIGlzIGFjdGl2ZSBhZ2FpbiBhZnRlciBpZGxlIGZvcjogJyArIEdsb2JhbC5pZGxlX3RpbWUgKyAnLi4uIFJlc2V0dGluZyBpZGxlIHRvIDAnLCAnR2xvYmFsLmpzJywgJycsICdkb1BpbmdJZk5lY2Vzc2FyeScsIDEgKTtcblx0R2xvYmFsLmlkbGVfdGltZSA9IDA7XG5cblx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnZpZXdJZCA9PT0gJ0xvZ2luVmlldycgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0dmFyIGFwaSA9IFRUQVBJLkFQSUF1dGhlbnRpY2F0aW9uO1xuXHRhcGkuaXNMb2dnZWRJbiggZmFsc2UsIHtcblx0XHRvblJlc3VsdDogZnVuY3Rpb24oIHJlc3VsdCApIHtcblx0XHRcdHZhciByZXNfZGF0YSA9IHJlc3VsdC5nZXRSZXN1bHQoKTtcblxuXHRcdFx0aWYgKCByZXNfZGF0YSAhPT0gdHJ1ZSApIHtcblx0XHRcdFx0Ly9Eb24ndCBkbyBMb2dvdXQgaGVyZSwgYXMgd2UgbmVlZCB0byBkaXNwbGF5IGEgXCJTZXNzaW9uIEV4cGlyZWRcIiBtZXNzYWdlIHRvIHRoZSB1c2VyLCB3aGljaCBpcyB0cmlnZ2VyZWQgZnJvbSB0aGUgU2VydmljZUNhbGxlci5cblx0XHRcdFx0Ly8gIEluIG9yZGVyIHRvIHRyaWdnZXIgdGhhdCB0aG91Z2gsIHdlIG5lZWQgdG8gbWFrZSBhbiAqQXV0aGVudGljYXRlZCogQVBJIGNhbGwgdG8gQVBJTWlzYy5QaW5nKCksIHJhdGhlciB0aGFuIFVuQXV0aGVudGljYXRlZCBjYWxsIHRvIEFQSUF1dGhlbnRpY2F0aW9uLlBpbmcoKVxuXHRcdFx0XHR2YXIgYXBpID0gVFRBUEkuQVBJTWlzYztcblx0XHRcdFx0YXBpLnBpbmcoIHtcblx0XHRcdFx0XHRvblJlc3VsdDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59O1xuXG5HbG9iYWwuc2V0dXBQaW5nID0gZnVuY3Rpb24oKSB7XG5cdEdsb2JhbC5pZGxlX3RpbWUgPSAwO1xuXHQkKCAnYm9keScgKS5tb3VzZW1vdmUoIEdsb2JhbC5kZWJvdW5jZSggZnVuY3Rpb24gc2V0dXBQaW5nTW91c2VNb3ZlRXZlbnQoIGUgKSB7XG5cdFx0R2xvYmFsLmRvUGluZ0lmTmVjZXNzYXJ5KCk7XG5cdH0sIDEwMDAgKSApO1xuXHQkKCAnYm9keScgKS5rZXlwcmVzcyggR2xvYmFsLmRlYm91bmNlKCBmdW5jdGlvbiBzZXR1cFBpbmdLZXlQcmVzc0V2ZW50KCBlICkge1xuXHRcdEdsb2JhbC5kb1BpbmdJZk5lY2Vzc2FyeSgpO1xuXHR9LCAxMDAwICkgKTtcblxuXHRzZXRJbnRlcnZhbCggdGltZXJJbmNyZW1lbnQsIDYwMDAwICk7IC8vIDEgbWludXRlXG5cdGZ1bmN0aW9uIHRpbWVySW5jcmVtZW50KCkge1xuXHRcdEdsb2JhbC5pZGxlX3RpbWUgPSBHbG9iYWwuaWRsZV90aW1lICsgMTtcblx0XHRpZiAoIEdsb2JhbC5pZGxlX3RpbWUgPj0gTWF0aC5taW4oIDE1LCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuc2Vzc2lvbl9pZGxlX3RpbWVvdXQgLyA2MCApICkge1xuXHRcdFx0RGVidWcuVGV4dCggJ1VzZXIgaXMgaWRsZTogJyArIEdsb2JhbC5pZGxlX3RpbWUsICdHbG9iYWwuanMnLCAnJywgJ3NldHVwUGluZycsIDEgKTtcblx0XHR9XG5cdH1cbn07XG5cbkdsb2JhbC5jbGVhckNhY2hlID0gZnVuY3Rpb24oIGZ1bmN0aW9uX25hbWUgKSB7XG5cdGZvciAoIHZhciBrZXkgaW4gTG9jYWxDYWNoZURhdGEucmVzdWx0X2NhY2hlICkge1xuXHRcdGlmICgga2V5LmluZGV4T2YoIGZ1bmN0aW9uX25hbWUgKSA+PSAwICkge1xuXHRcdFx0ZGVsZXRlIExvY2FsQ2FjaGVEYXRhLnJlc3VsdF9jYWNoZVtrZXldO1xuXHRcdH1cblx0fVxufTtcblxuR2xvYmFsLmdldEhvc3QgPSBmdW5jdGlvbiggaG9zdCApIHtcblx0aWYgKCAhaG9zdCApIHtcblx0XHRob3N0ID0gd2luZG93LmxvY2F0aW9uLmhvc3RuYW1lO1xuXHR9XG5cblx0Ly9NYWtlIHN1cmUgaXRzIG5vdCBhbiBJUHY0IGFkZHJlc3MsIGFuZCBpZiBpdHMgYSBkb21haW4gaGFzIG1vcmUgdGhhbiAxIGRvdCBpbiBpdCBiZWZvcmUgcGFyc2luZyBvZmYgdGhlIHN1Yi1kb21haW4gcGFydC5cblx0Ly8gU28gYm90aCBJUHY0IGFkZHJlc3NlcyBhbmQgZG9tYWlucyBsaWtlOiBsb2NhbGhvc3QgKG5vIGRvdCBhdCBhbGwpLCBteWNvbXBhbnkuY29tIHNob3VsZCBub3QgYmUgbW9kaWZpZWQgYXQgYWxsLiBPbmx5OiBzdWIubXljb21wYW55LmNvbSwgc3ViLnN1YjIubXljb21wYW55LmNvbVxuXHR2YXIgaXNfc3ViX2RvbWFpbiA9IGhvc3QubWF0Y2goIC9cXC4vZyApO1xuXHRpZiAoIC9eKChbMC05XXxbMS05XVswLTldfDFbMC05XXsyfXwyWzAtNF1bMC05XXwyNVswLTVdKVxcLil7M30oWzAtOV18WzEtOV1bMC05XXwxWzAtOV17Mn18MlswLTRdWzAtOV18MjVbMC01XSkkLy50ZXN0KCBob3N0ICkgPT0gZmFsc2UgJiYgaXNfc3ViX2RvbWFpbiAmJiBpc19zdWJfZG9tYWluLmxlbmd0aCA+IDEgKSB7XG5cdFx0aG9zdCA9IGhvc3Quc3Vic3RyaW5nKCAoIGhvc3QuaW5kZXhPZiggJy4nICkgKyAxICkgKTtcblx0fVxuXG5cdHJldHVybiBob3N0O1xufTtcblxuR2xvYmFsLnNldFdpZGdldEVuYWJsZWQgPSBmdW5jdGlvbiggd2lkZ2V0LCB2YWwgKSB7XG5cdGlmICggd2lkZ2V0ICkge1xuXHRcdGlmICggIXZhbCApIHtcblx0XHRcdHdpZGdldC5hdHRyKCAnZGlzYWJsZWQnLCAndHJ1ZScgKTtcblx0XHRcdHdpZGdldC5hZGRDbGFzcyggJ2Rpc2FibGUtZmlsdGVyJyApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR3aWRnZXQucmVtb3ZlQXR0ciggJ2Rpc2FibGVkJyApO1xuXHRcdFx0d2lkZ2V0LnJlbW92ZUNsYXNzKCAnZGlzYWJsZS1maWx0ZXInICk7XG5cdFx0fVxuXHR9XG59O1xuXG5HbG9iYWwuY3JlYXRlVmlld1RhYnMgPSBmdW5jdGlvbigpIHtcblx0Ly9KUyBsb2FkIE9wdGltaXplXG5cdGlmICggdHlwZW9mIFdpZGdldE5hbWVzRGljID09ICd1bmRlZmluZWQnICkge1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoIExvY2FsQ2FjaGVEYXRhLmxvYWRWaWV3UmVxdWlyZWRKU1JlYWR5ICkge1xuXHRcdGlmICggIUxvY2FsQ2FjaGVEYXRhLnZpZXdfbWluX3RhYl9iYXIgKSB7XG5cdFx0XHR2YXIgdmlld19taW5fdGFiX2JhciA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBXaWRnZXROYW1lc0RpYy5WSUVXX01JTl9UQUJfQkFSICk7XG5cdFx0XHR2aWV3X21pbl90YWJfYmFyID0gJCggdmlld19taW5fdGFiX2JhciApLlZpZXdNaW5UYWJCYXIoKTtcblx0XHRcdCQoICcubGF5b3V0LW1lbnUtY29udGFpbmVyJyApLmFwcGVuZCggdmlld19taW5fdGFiX2JhciApO1xuXG5cdFx0XHRMb2NhbENhY2hlRGF0YS52aWV3X21pbl90YWJfYmFyID0gdmlld19taW5fdGFiX2Jhcjtcblx0XHR9XG5cblx0XHRMb2NhbENhY2hlRGF0YS52aWV3X21pbl90YWJfYmFyLmJ1aWxkVGFicyggTG9jYWxDYWNoZURhdGEudmlld19taW5fbWFwICk7XG5cdH1cbn07XG5cbkdsb2JhbC5hZGRWaWV3VGFiID0gZnVuY3Rpb24oIHZpZXdfaWQsIHZpZXdfbmFtZSwgdXJsICkge1xuXG5cdExvY2FsQ2FjaGVEYXRhLnZpZXdfbWluX21hcFt2aWV3X2lkXSA9IHZpZXdfbmFtZTtcblxuXHRMb2NhbENhY2hlRGF0YS52aWV3X21pbl9tYXBbdmlld19pZCArICdfdXJsJ10gPSB1cmw7XG5cblx0R2xvYmFsLmNyZWF0ZVZpZXdUYWJzKCk7XG59O1xuXG5HbG9iYWwucmVtb3ZlVmlld1RhYiA9IGZ1bmN0aW9uKCB2aWV3X2lkICkge1xuXG5cdGRlbGV0ZSBMb2NhbENhY2hlRGF0YS52aWV3X21pbl9tYXBbdmlld19pZF07XG5cdCQoICcjbWluX3RhYl8nICsgdmlld19pZCApLnJlbW92ZSgpO1xufTtcblxuR2xvYmFsLmNsZWFuVmlld1RhYiA9IGZ1bmN0aW9uKCkge1xuXG5cdExvY2FsQ2FjaGVEYXRhLnZpZXdfbWluX21hcCA9IHt9O1xuXHRHbG9iYWwuY3JlYXRlVmlld1RhYnMoKTtcbn07XG5cbkdsb2JhbC51cENhc2VGaXJzdExldHRlciA9IGZ1bmN0aW9uKCBzdHIgKSB7XG5cdGlmICggdHlwZW9mIHN0ciA9PSAnc3RyaW5nJyApIHsgLy9pbiBjYXNlIG51bGwgb3IgZmFsc2UgaXMgcGFzc2VkLCB3ZSBzaG91bGQgY2hlY2sgdGhlIHR5cGUuXG5cdFx0c3RyID0gc3RyLmNoYXJBdCggMCApLnRvVXBwZXJDYXNlKCkgKyBzdHIuc2xpY2UoIDEgKTtcblx0fVxuXHRyZXR1cm4gc3RyO1xufTtcblxuR2xvYmFsLmNhbGN1bGF0ZVRleHRXaWR0aCA9IGZ1bmN0aW9uKCB0ZXh0LCBvcHRpb25zICkge1xuXHRpZiAoIHR5cGVvZiBvcHRpb25zID09PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdG9wdGlvbnMgPSB7fTtcblx0fVxuXG5cdGlmICggIW9wdGlvbnMuZm9udFNpemUgKSB7XG5cdFx0b3B0aW9ucy5mb250U2l6ZSA9ICcxMnB4Jztcblx0fVxuXG5cdHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2RpdicgKTtcblx0dmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIHRleHQgKTtcblxuXHRlbGVtZW50LmFwcGVuZENoaWxkKCB0ZXh0Tm9kZSApO1xuXG5cdGlmICggb3B0aW9ucy5mb250ICkge1xuXHRcdGVsZW1lbnQuc3R5bGUuZm9udEZhbWlseSA9IG9wdGlvbnMuZm9udDtcblx0fVxuXG5cdGlmICggb3B0aW9ucy5mb250V2VpZ2h0ICkge1xuXHRcdGVsZW1lbnQuc3R5bGUuZm9udFdlaWdodCA9IG9wdGlvbnMuZm9udFdlaWdodDtcblx0fVxuXG5cdGlmICggb3B0aW9ucy53b3JkQnJlYWsgKSB7XG5cdFx0ZWxlbWVudC5zdHlsZS53b3JkQnJlYWsgPSBvcHRpb25zLndvcmRCcmVhaztcblx0fVxuXG5cdGVsZW1lbnQuc3R5bGUuZm9udFNpemUgPSBvcHRpb25zLmZvbnRTaXplO1xuXHRlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcblx0ZWxlbWVudC5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG5cdGVsZW1lbnQuc3R5bGUubGVmdCA9ICctOTk5cHgnO1xuXHRlbGVtZW50LnN0eWxlLnRvcCA9ICctOTk5cHgnO1xuXHRlbGVtZW50LnN0eWxlLmhlaWdodCA9ICdhdXRvJztcblxuXHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKCBlbGVtZW50ICk7XG5cdHZhciBjb250ZW50X3dpZHRoID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcblx0ZWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBlbGVtZW50ICk7XG5cblx0aWYgKCBvcHRpb25zLm1pbl93aWR0aCAmJiBvcHRpb25zLm1pbl93aWR0aCA+IDAgJiYgY29udGVudF93aWR0aCA8IG9wdGlvbnMubWluX3dpZHRoICkge1xuXHRcdGNvbnRlbnRfd2lkdGggPSBvcHRpb25zLm1pbl93aWR0aDtcblx0fVxuXHRpZiAoIG9wdGlvbnMucGFkZGluZyAmJiBvcHRpb25zLnBhZGRpbmcgPiAwICkge1xuXHRcdGNvbnRlbnRfd2lkdGggPSBjb250ZW50X3dpZHRoICsgb3B0aW9ucy5wYWRkaW5nO1xuXHR9XG5cdGlmICggb3B0aW9ucy5tYXhfd2lkdGggPiAwICYmIGNvbnRlbnRfd2lkdGggPiBvcHRpb25zLm1heF93aWR0aCApIHtcblx0XHRjb250ZW50X3dpZHRoID0gb3B0aW9ucy5tYXhfd2lkdGg7XG5cdH1cblxuXHRyZXR1cm4gY29udGVudF93aWR0aDtcbn07XG5cbkdsb2JhbC5zdHJUb0RhdGUgPSBmdW5jdGlvbiggZGF0ZV9zdHJpbmcsIGZvcm1hdCApIHtcblxuXHQvL2JldHRlciB0byB1c2UgRGF0ZS5wYXJzZSwgbGV0J3Mgc2VlXG5cdGlmICggIUdsb2JhbC5pc1NldCggZm9ybWF0ICkgJiYgTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpICkge1xuXHRcdGZvcm1hdCA9IExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKS5kYXRlX2Zvcm1hdDtcblx0fVxuXG5cdGlmICggIWZvcm1hdCApIHtcblx0XHRmb3JtYXQgPSAnREQtTU1NLVlZJztcblx0fVxuXG5cdHZhciBkYXRlID0gbW9tZW50KCBkYXRlX3N0cmluZywgZm9ybWF0ICk7XG5cdGRhdGUgPSBkYXRlLnRvRGF0ZSgpO1xuXG5cdC8vVGhlIG1vbWVudCB3aWxsIHBhc3MgZXZlcnl0aGluZyBhcyBhIGRhdGUuIEp1ZGdlIGlmIHRoZSB5ZWFyIGxlc3MgMTAwMCB0aGFuIDE5MDAgb3IgYmV5b25kIDEwMDAgb2YgMTkwMCxcblx0Ly93ZSB0aGluayBpdCdzIGEgaW52YWxpZCB5ZWFyXG5cdGlmICggZGF0ZS5nZXRZZWFyKCkgPCAtMTAwMCB8fCBkYXRlLmdldFllYXIoKSA+IDEwMDAgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHRyZXR1cm4gZGF0ZTtcbn07XG5cbkdsb2JhbC5zdHJUb0RhdGVUaW1lID0gZnVuY3Rpb24oIGRhdGVfc3RyaW5nICkge1xuXHQvL0Vycm9yOiBUeXBlRXJyb3I6IEdsb2JhbC5zdHJUb0RhdGVUaW1lKC4uLikgaXMgbnVsbCBpbiAvaW50ZXJmYWNlL2h0bWw1L2ZyYW1ld29yay9qcXVlcnkubWluLmpzP3Y9OC4wLjAtMjAxNDExMTctMTUzNTE1IGxpbmUgNDg2MlxuXHRpZiAoICFkYXRlX3N0cmluZyB8fCAhTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0dmFyIGRhdGVfZm9ybWF0ID0gTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLmRhdGVfZm9ybWF0O1xuXHR2YXIgdGltZV9mb3JtYXQgPSBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkuanNfdGltZV9mb3JtYXRbTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLnRpbWVfZm9ybWF0XTtcblx0dmFyIGRhdGUgPSBtb21lbnQoIGRhdGVfc3RyaW5nLCBkYXRlX2Zvcm1hdCArICcgJyArIHRpbWVfZm9ybWF0ICkudG9EYXRlKCk7XG5cblx0cmV0dXJuIGRhdGU7XG5cdC8vcmV0dXJuIERhdGUucGFyc2UoIGRhdGVfc3RyaW5nICk7XG59O1xuXG4vL0NvbnZlcnQgYWxsIGtpbmRzIG9mIGRhdGUgdGltZSB0byBtbS9kZC95eXl5IHNvIERhdGUucGFyc2UgY2FuIHBhcnNlIGl0IGNvcnJlY3Rcbkdsb2JhbC5nZXRTdGFuZGFyZERhdGVUaW1lU3RyID0gZnVuY3Rpb24oIGRhdGVfc3RyLCB0aW1lX3N0ciApIHtcblx0Ly92YXIgcmVzdWx0ID0gR2xvYmFsLnN0clRvRGF0ZSggZGF0ZV9zdHIgKS5mb3JtYXQoICdNTS9ERC9ZWVlZJyApICsgJyAnICsgdGltZV9zdHI7XG5cblx0cmV0dXJuIGRhdGVfc3RyO1xufTtcblxuR2xvYmFsLmNvbnZlcnRUb2pRdWVyeUZvcm1hdCA9IGZ1bmN0aW9uKCBkYXRlX2Zvcm1hdCApIHtcblx0Ly9Gb3IgbW9tZW50IGRhdGUgcGFyc2VyXG5cdHZhciBqcXVlcnlfZGF0ZV9mb3JtYXQgPSB7XG5cdFx0J2QtTS15JzogJ2RkLU0teScsXG5cdFx0J2QtTS1ZJzogJ2RkLU0teXknLFxuXHRcdCdkTVknOiAnZGRNeXknLFxuXHRcdCdkL20vWSc6ICdkZC9tbS95eScsXG5cdFx0J2QvbS95JzogJ2RkL21tL3knLFxuXHRcdCdkLW0teSc6ICdkZC1tbS15Jyxcblx0XHQnZC1tLVknOiAnZGQtbW0teXknLFxuXHRcdCdtL2QveSc6ICdtbS9kZC95Jyxcblx0XHQnbS9kL1knOiAnbW0vZGQveXknLFxuXHRcdCdtLWQteSc6ICdtbS1kZC15Jyxcblx0XHQnbS1kLVknOiAnbW0tZGQteXknLFxuXHRcdCdZLW0tZCc6ICd5eS1tbS1kZCcsXG5cdFx0J00tZC15JzogJ00tZGQteScsXG5cdFx0J00tZC1ZJzogJ00tZGQteXknLFxuXHRcdCdsLCBGIGQgWSc6ICdERCwgTU0gZGQgeXknLFxuXHRcdCdELCBGIGQgWSc6ICdELCBNTSBkZCB5eScsXG5cdFx0J0QsIE0gZCBZJzogJ0QsIE0gZGQgeXknLFxuXHRcdCdELCBkLU0tWSc6ICdELCBkZC1NLXl5Jyxcblx0XHQnRCwgZE1ZJzogJ0QsIGRkTXl5JyxcblxuXHRcdCdnOmkgQSc6ICdoOm1tIFRUJyxcblx0XHQnZzppIGEnOiAnaDptbSB0dCcsXG5cdFx0J0c6aSc6ICdIOm1tJyxcblx0XHQnZzppIEEgVCc6ICdoOm1tIFRUJyxcblx0XHQnRzppIFQnOiAnSDptbScsXG5cblx0XHQnZzppOnMgQSc6ICdoOm1tOnNzIFRUJyxcblx0XHQnZzppOnMgYSc6ICdoOm1tOnNzIHR0Jyxcblx0XHQnRzppOnMnOiAnSDptbTpzcycsXG5cdFx0J2c6aTpzIEEgVCc6ICdoOm1tOnNzIFRUJyxcblx0XHQnRzppOnMgVCc6ICdIOm1tOnNzJ1xuXHR9O1xuXG5cdHJldHVybiBqcXVlcnlfZGF0ZV9mb3JtYXRbZGF0ZV9mb3JtYXRdO1xufTtcblxuR2xvYmFsLnVwZGF0ZVVzZXJQcmVmZXJlbmNlID0gZnVuY3Rpb24oIGNhbGxCYWNrLCBtZXNzYWdlICkge1xuXHR2YXIgdXNlcl9wcmVmZXJlbmNlX2FwaSA9IFRUQVBJLkFQSVVzZXJQcmVmZXJlbmNlO1xuXHR2YXIgY3VycmVudF91c2VyX2FvdSA9IFRUQVBJLkFQSUF1dGhlbnRpY2F0aW9uO1xuXG5cdGlmICggbWVzc2FnZSApIHtcblx0XHRQcm9ncmVzc0Jhci5jaGFuZ2VQcm9ncmVzc0Jhck1lc3NhZ2UoIG1lc3NhZ2UgKTtcblx0fVxuXG5cdGN1cnJlbnRfdXNlcl9hb3UuZ2V0Q3VycmVudFVzZXJQcmVmZXJlbmNlKCB7XG5cdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXN1bHQgKSB7XG5cdFx0XHR2YXIgcmVzdWx0X2RhdGEgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cdFx0XHRMb2NhbENhY2hlRGF0YS5sb2dpblVzZXJQcmVmZXJlbmNlID0gcmVzdWx0X2RhdGE7XG5cblx0XHRcdHVzZXJfcHJlZmVyZW5jZV9hcGkuZ2V0T3B0aW9ucyggJ21vbWVudF9kYXRlX2Zvcm1hdCcsIHtcblx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCBqc0RhdGVGb3JtYXRSZXMgKSB7XG5cdFx0XHRcdFx0dmFyIGpzRGF0ZUZvcm1hdFJlc3VsdERhdGEgPSBqc0RhdGVGb3JtYXRSZXMuZ2V0UmVzdWx0KCk7XG5cblx0XHRcdFx0XHQvL0ZvciBtb21lbnQgZGF0ZSBwYXJzZXJcblx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5sb2dpblVzZXJQcmVmZXJlbmNlLmpzX2RhdGVfZm9ybWF0ID0ganNEYXRlRm9ybWF0UmVzdWx0RGF0YTtcblxuXHRcdFx0XHRcdHZhciBkYXRlX2Zvcm1hdCA9IExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UuZGF0ZV9mb3JtYXQ7XG5cdFx0XHRcdFx0aWYgKCAhZGF0ZV9mb3JtYXQgKSB7XG5cdFx0XHRcdFx0XHRkYXRlX2Zvcm1hdCA9ICdERC1NTU0tWVknO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UuZGF0ZV9mb3JtYXQgPSBMb2NhbENhY2hlRGF0YS5sb2dpblVzZXJQcmVmZXJlbmNlLmpzX2RhdGVfZm9ybWF0W2RhdGVfZm9ybWF0XTtcblxuXHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UuZGF0ZV9mb3JtYXRfMSA9IEdsb2JhbC5jb252ZXJ0VG9qUXVlcnlGb3JtYXQoIGRhdGVfZm9ybWF0ICk7IC8vVERhdGVQaWNrZXIsIFRSYW5nZVBpY2tlclxuXHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UudGltZV9mb3JtYXRfMSA9IEdsb2JhbC5jb252ZXJ0VG9qUXVlcnlGb3JtYXQoIExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UudGltZV9mb3JtYXQgKTsgLy9UVGltZVBpY2tlclxuXG5cdFx0XHRcdFx0dXNlcl9wcmVmZXJlbmNlX2FwaS5nZXRPcHRpb25zKCAnbW9tZW50X3RpbWVfZm9ybWF0Jywge1xuXHRcdFx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCBqc1RpbWVGb3JtYXRSZXMgKSB7XG5cdFx0XHRcdFx0XHRcdHZhciBqc1RpbWVGb3JtYXRSZXN1bHREYXRhID0ganNUaW1lRm9ybWF0UmVzLmdldFJlc3VsdCgpO1xuXG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UuanNfdGltZV9mb3JtYXQgPSBqc1RpbWVGb3JtYXRSZXN1bHREYXRhO1xuXG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLnNldExvZ2luVXNlclByZWZlcmVuY2UoIExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlclByZWZlcmVuY2UgKTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIGNhbGxCYWNrICkge1xuXHRcdFx0XHRcdFx0XHRcdGNhbGxCYWNrKCk7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdFx0fVxuXHR9ICk7XG59O1xuXG4vKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG5HbG9iYWwucm91bmRUaW1lID0gZnVuY3Rpb24oIGVwb2NoLCByb3VuZF92YWx1ZSwgcm91bmRfdHlwZSApIHtcblx0dmFyIHJvdW5kX3R5cGUgPSByb3VuZF90eXBlIHx8IDIwO1xuXG5cdHN3aXRjaCAoIHJvdW5kX3R5cGUgKSB7XG5cdFx0Y2FzZSAxMDogLy9Eb3duXG5cdFx0XHRlcG9jaCA9ICggZXBvY2ggLSAoIGVwb2NoICUgcm91bmRfdmFsdWUgKSApO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAyMDogLy9BdmVyYWdlXG5cdFx0Y2FzZSAyNTogLy9BdmVyYWdlIChyb3VuZCBzcGxpdCBzZWNvbmRzIHVwKVxuXHRcdGNhc2UgMjc6IC8vQXZlcmFnZSAocm91bmQgc3BsaXQgc2Vjb25kcyBkb3duKVxuXHRcdFx0dmFyIHRtcF9yb3VuZF92YWx1ZTtcblx0XHRcdGlmICggcm91bmRfdHlwZSA9PSAyMCB8fCByb3VuZF92YWx1ZSA8PSA2MCApIHtcblx0XHRcdFx0dG1wX3JvdW5kX3ZhbHVlID0gKCByb3VuZF92YWx1ZSAvIDIgKTtcblx0XHRcdH0gZWxzZSBpZiAoIHJvdW5kX3R5cGUgPT0gMjUgKSB7IC8vQXZlcmFnZSAoUGFydGlhbCBNaW4uIERvd24pXG5cdFx0XHRcdHRtcF9yb3VuZF92YWx1ZSA9IEdsb2JhbC5yb3VuZFRpbWUoICggcm91bmRfdmFsdWUgLyAyICksIDYwLCAxMCApOyAvL1RoaXMgaXMgb3Bwb3NpdGUgcm91bmRpbmdcblx0XHRcdH0gZWxzZSBpZiAoIHJvdW5kX3R5cGUgPT0gMjcgKSB7IC8vQXZlcmFnZSAoUGFydGlhbCBNaW4uIFVwKVxuXHRcdFx0XHR0bXBfcm91bmRfdmFsdWUgPSBHbG9iYWwucm91bmRUaW1lKCAoIHJvdW5kX3ZhbHVlIC8gMiApLCA2MCwgMzAgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBlcG9jaCA+IDAgKSB7XG5cdFx0XHRcdC8vV2hlbiBkb2luZyBhIDE1bWluIGF2ZXJhZ2Ugcm91bmRpbmcsIFVTIGxhdyBzdGF0ZXMgN21pbnMgYW5kIDU5IHNlY29uZHMgY2FuIGJlIHJvdW5kZWQgZG93biBpbiBmYXZvciBvZiB0aGUgZW1wbG95ZXIsIGFuZCA4bWlucyBhbmQgMCBzZWNvbmRzIG11c3QgYmUgcm91bmRlZCB1cC5cblx0XHRcdFx0Ly9TbyBpZiB0aGUgcm91bmQgaW50ZXJ2YWwgaXMgbm90IGFuIGV2ZW4gbnVtYmVyLCByb3VuZCBpdCB1cCB0byB0aGUgbmVhcmVzdCBtaW51dGUgYmVmb3JlIGRvaW5nIHRoZSBjYWxjdWxhdGlvbnMgdG8gYXZvaWQgaXNzdWVzIHdpdGggc2Vjb25kcy5cblx0XHRcdFx0ZXBvY2ggPSAoIE1hdGguZmxvb3IoICggZXBvY2ggKyB0bXBfcm91bmRfdmFsdWUgKSAvIHJvdW5kX3ZhbHVlICkgKiByb3VuZF92YWx1ZSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZXBvY2ggPSAoIE1hdGguY2VpbCggKCBlcG9jaCAtIHRtcF9yb3VuZF92YWx1ZSApIC8gcm91bmRfdmFsdWUgKSAqIHJvdW5kX3ZhbHVlICk7XG5cdFx0XHR9XG5cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgMzA6IC8vVXBcblx0XHRcdGVwb2NoID0gKCAoICggZXBvY2ggKyAoIHJvdW5kX3ZhbHVlIC0gMSApICkgLyByb3VuZF92YWx1ZSApICogcm91bmRfdmFsdWUgKTtcblx0XHRcdGJyZWFrO1xuXHR9XG5cblx0cmV0dXJuIGVwb2NoO1xufSxcblxuXHRHbG9iYWwucGFyc2VUaW1lVW5pdCA9IGZ1bmN0aW9uKCB0aW1lX3VuaXQsIGZvcm1hdCApIHtcblx0XHR2YXIgZm9ybWF0LCB0aW1lX3VuaXQsIHRpbWVfdW5pdHMsIHNlY29uZHMsIG5lZ2F0aXZlX251bWJlcjtcblxuXHRcdHZhciB0aW1lX3VuaXQgPSB0aW1lX3VuaXQudG9TdHJpbmcoKTsgLy9OZWVkcyB0byBiZSBhIHN0cmluZyBzbyB3ZSBjYW4gdXNlIC5jaGFyQXQgYW5kIC5yZXBsYWNlIGJlbG93LlxuXG5cdFx0aWYgKCAhZm9ybWF0ICkge1xuXHRcdFx0Zm9ybWF0ID0gTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLnRpbWVfdW5pdF9mb3JtYXQ7XG5cdFx0fVxuXHRcdGZvcm1hdCA9IHBhcnNlSW50KCBmb3JtYXQgKTtcblxuXHRcdHZhciBlbmFibGVfcm91bmRpbmcgPSB0cnVlO1xuXHRcdGlmICggdGltZV91bml0LmNoYXJBdCggMCApID09ICdcIicgKSB7XG5cdFx0XHRlbmFibGVfcm91bmRpbmcgPSBmYWxzZTtcblx0XHR9XG5cblx0XHR2YXIgdGhvdXNhbmRzX3NlcGFyYXRvciA9ICcsJztcblx0XHR2YXIgZGVjaW1hbF9zZXBhcmF0b3IgPSAnLic7XG5cblx0XHR0aW1lX3VuaXQgPSB0aW1lX3VuaXQucmVwbGFjZSggbmV3IFJlZ0V4cCggdGhvdXNhbmRzX3NlcGFyYXRvciwgJ2cnICksICcnICkucmVwbGFjZSggbmV3IFJlZ0V4cCggJyAnLCAnZycgKSwgJycgKS5yZXBsYWNlKCBuZXcgUmVnRXhwKCAnXCInLCAnZycgKSwgJycgKTsgLy9OZWVkIHRvIHVzZSByZWdleCB0byByZXBsYWNlIGFsbCBpbnN0YW5jZXMuXG5cblx0XHRzd2l0Y2ggKCBmb3JtYXQgKSB7XG5cdFx0XHRjYXNlIDEwOiAvL2hoOm1tXG5cdFx0XHRjYXNlIDEyOiAvL2hoOm1tOnNzXG5cdFx0XHRcdGlmICggdGltZV91bml0LmluZGV4T2YoIGRlY2ltYWxfc2VwYXJhdG9yICkgIT09IC0xICYmIHRpbWVfdW5pdC5pbmRleE9mKCAnOicgKSA9PT0gLTEgKSB7IC8vSHlicmlkIG1vZGUsIHRoZXkgcGFzc2VkIGEgZGVjaW1hbCBmb3JtYXQgSEg6TU0sIHRyeSB0byBoYW5kbGUgcHJvcGVybHkuXG5cdFx0XHRcdFx0dGltZV91bml0ID0gR2xvYmFsLmdldFRpbWVVbml0KCBHbG9iYWwucGFyc2VUaW1lVW5pdCggdGltZV91bml0LCAyMCApLCBmb3JtYXQgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRpbWVfdW5pdHMgPSB0aW1lX3VuaXQuc3BsaXQoICc6JyApO1xuXG5cdFx0XHRcdGlmICggIXRpbWVfdW5pdHNbMF0gKSB7XG5cdFx0XHRcdFx0dGltZV91bml0c1swXSA9IDA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoICF0aW1lX3VuaXRzWzFdICkge1xuXHRcdFx0XHRcdHRpbWVfdW5pdHNbMV0gPSAwO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCAhdGltZV91bml0c1syXSApIHtcblx0XHRcdFx0XHR0aW1lX3VuaXRzWzJdID0gMDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpZiAoIHRpbWVfdW5pdHNbMl0gIT0gMCApIHtcblx0XHRcdFx0XHRcdGVuYWJsZV9yb3VuZGluZyA9IGZhbHNlOyAvL1NpbmNlIHNlY29uZHMgd2VyZSBzcGVjaWZpZWQsIGRvbid0IHJvdW5kIHRvIG5lYXJlc3QgbWludXRlLlxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdG5lZ2F0aXZlX251bWJlciA9IGZhbHNlO1xuXHRcdFx0XHRpZiAoIHRpbWVfdW5pdHNbMF0udG9TdHJpbmcoKS5jaGFyQXQoIDAgKSA9PSAnLScgfHwgdGltZV91bml0c1swXSA8IDAgfHwgdGltZV91bml0c1sxXSA8IDAgfHwgdGltZV91bml0c1syXSA8IDAgKSB7XG5cdFx0XHRcdFx0bmVnYXRpdmVfbnVtYmVyID0gdHJ1ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHNlY29uZHMgPSAoICggTWF0aC5hYnMoIE1hdGguZmxvb3IoIHRpbWVfdW5pdHNbMF0gKSApICogMzYwMCApICsgKCBNYXRoLmFicyggTWF0aC5mbG9vciggdGltZV91bml0c1sxXSApICkgKiA2MCApICsgTWF0aC5hYnMoIE1hdGguZmxvb3IoIHRpbWVfdW5pdHNbMl0gKSApICk7XG5cblx0XHRcdFx0aWYgKCBuZWdhdGl2ZV9udW1iZXIgPT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRzZWNvbmRzID0gKCBzZWNvbmRzICogLTEgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAyMDogLy9ob3Vyc1xuXHRcdFx0Y2FzZSAyMjogLy9ob3VycyBbUHJlY2lzZV1cblx0XHRcdGNhc2UgMjM6IC8vaG91cnMgW1N1cGVyIFByZWNpc2VdXG5cdFx0XHRcdGlmICggdGltZV91bml0LmluZGV4T2YoICc6JyApICE9PSAtMSApIHsgLy9IeWJyaWQgbW9kZSwgdGhleSBwYXNzZWQgYSBkZWNpbWFsIGZvcm1hdCBISDpNTSwgdHJ5IHRvIGhhbmRsZSBwcm9wZXJseS5cblx0XHRcdFx0XHR0aW1lX3VuaXQgPSBHbG9iYWwuZ2V0VGltZVVuaXQoIEdsb2JhbC5wYXJzZVRpbWVVbml0KCB0aW1lX3VuaXQsIDEwICksIGZvcm1hdCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0c2Vjb25kcyA9ICggdGltZV91bml0ICogMzYwMCApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMzA6IC8vbWludXRlc1xuXHRcdFx0XHRzZWNvbmRzID0gKCB0aW1lX3VuaXQgKiA2MCApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgNDA6IC8vc2Vjb25kc1xuXHRcdFx0XHRzZWNvbmRzID0gdGltZV91bml0O1xuXHRcdFx0XHRpZiAoIGVuYWJsZV9yb3VuZGluZyA9PSB0cnVlICkge1xuXHRcdFx0XHRcdHNlY29uZHMgPSByb3VuZCggc2Vjb25kcyApOyAvL1JvdW5kIHRvIG5lYXJlc3Qgd2hvbGUgbnVtYmVyIGJ5IGRlZmF1bHQuXG5cdFx0XHRcdH1cblx0XHRcdFx0ZW5hYmxlX3JvdW5kaW5nID0gZmFsc2U7IC8vU2luY2Ugc2Vjb25kcyB3ZXJlIHNwZWNpZmllZCwgZG9uJ3Qgcm91bmQgdG8gbmVhcmVzdCBtaW51dGUuIEFsc28gZm9yIGFjY3J1YWxzIG1pZ2h0IG5lZWQgdG8gYWxsb3cgZGVjaW1hbCBzZWNvbmRzLlxuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHRpZiAoIGVuYWJsZV9yb3VuZGluZyA9PSB0cnVlICkge1xuXHRcdFx0c2Vjb25kcyA9IEdsb2JhbC5yb3VuZFRpbWUoIHNlY29uZHMsIDYwICk7XG5cdFx0fVxuXG5cdFx0Ly9EZWJ1Zy5UZXh0KCAnVGltZSBVbml0OiAnKyB0aW1lX3VuaXQgKycgUmV0dmFsOiAnKyBzZWNvbmRzLCAnR2xvYmFsLmpzJywgJycsICdwYXJzZVRpbWVVbml0JywgMTAgKTtcblx0XHRyZXR1cm4gc2Vjb25kcztcblx0fSxcblxuXHRHbG9iYWwuY29udmVydFNlY29uZHNUb0hNUyA9IGZ1bmN0aW9uKCBzZWNvbmRzLCBpbmNsdWRlX3NlY29uZHMsIGV4Y2x1ZGVfaG91cnMgKSB7XG5cdFx0dmFyIG5lZ2F0aXZlX251bWJlciA9IGZhbHNlO1xuXG5cdFx0aWYgKCBzZWNvbmRzIDwgMCApIHtcblx0XHRcdG5lZ2F0aXZlX251bWJlciA9IHRydWU7XG5cdFx0fVxuXG5cdFx0c2Vjb25kcyA9IE1hdGgucm91bmQoIE1hdGguYWJzKCBzZWNvbmRzICkgKTtcblxuXHRcdHZhciB0bXBfaG91cnMgPSBNYXRoLmZsb29yKCBzZWNvbmRzIC8gMzYwMCApO1xuXHRcdHZhciB0bXBfbWludXRlcyA9IE1hdGguZmxvb3IoICggc2Vjb25kcyAvIDYwICkgJSA2MCApO1xuXHRcdHZhciB0bXBfc2Vjb25kcyA9IE1hdGguZmxvb3IoIHNlY29uZHMgJSA2MCApO1xuXG5cdFx0aWYgKCBleGNsdWRlX2hvdXJzID09IHRydWUgKSB7IC8vQ29udmVydCBob3VycyB0byBtaW51dGVzIGJlZm9yZSB3ZSBwYWQgaXQuXG5cdFx0XHR0bXBfbWludXRlcyA9ICggKCB0bXBfaG91cnMgKiA2MCApICsgdG1wX21pbnV0ZXMgKTtcblx0XHRcdHRtcF9ob3VycyA9IDA7XG5cdFx0fVxuXG5cdFx0aWYgKCB0bXBfaG91cnMgPCAxMCApIHtcblx0XHRcdHRtcF9ob3VycyA9ICcwJyArIHRtcF9ob3Vycztcblx0XHR9XG5cblx0XHRpZiAoIHRtcF9taW51dGVzIDwgMTAgKSB7XG5cdFx0XHR0bXBfbWludXRlcyA9ICcwJyArIHRtcF9taW51dGVzO1xuXHRcdH1cblxuXHRcdGlmICggdG1wX3NlY29uZHMgPCAxMCApIHtcblx0XHRcdHRtcF9zZWNvbmRzID0gJzAnICsgdG1wX3NlY29uZHM7XG5cdFx0fVxuXG5cdFx0dmFyIHJldHZhbDtcblx0XHRpZiAoIGV4Y2x1ZGVfaG91cnMgPT0gdHJ1ZSApIHtcblx0XHRcdHJldHZhbCA9IFt0bXBfbWludXRlcywgdG1wX3NlY29uZHNdLmpvaW4oICc6JyApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIGluY2x1ZGVfc2Vjb25kcyA9PSB0cnVlICkge1xuXHRcdFx0XHRyZXR2YWwgPSBbdG1wX2hvdXJzLCB0bXBfbWludXRlcywgdG1wX3NlY29uZHNdLmpvaW4oICc6JyApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dmFsID0gW3RtcF9ob3VycywgdG1wX21pbnV0ZXNdLmpvaW4oICc6JyApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggbmVnYXRpdmVfbnVtYmVyID09IHRydWUgKSB7XG5cdFx0XHRyZXR2YWwgPSAnLScgKyByZXR2YWw7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldHZhbDtcblx0fSxcblxuLy9XYXM6IEdsb2JhbC5zZWNvbmRUb0hITU1TU1xuXHRHbG9iYWwuZ2V0VGltZVVuaXQgPSBmdW5jdGlvbiggc2Vjb25kcywgZm9ybWF0ICkge1xuXHRcdHZhciByZXR2YWw7XG5cblx0XHQvL2Fsd2F5cyByZXR1cm4gaGg6c3MuIGlmIHdlIGNhbid0IHBhcnNlIHRvIGZsb2F0LCB0aGVuIHdvcmsgd2l0aCAwIHRtcF9zZWNvbmRzXG5cdFx0dmFyIHNlY29uZHMgPSBwYXJzZUZsb2F0KCBzZWNvbmRzICk7XG5cdFx0aWYgKCBpc05hTiggc2Vjb25kcyApICkge1xuXHRcdFx0c2Vjb25kcyA9IDA7XG5cdFx0fVxuXG5cdFx0Ly9GSVhFUyBCVUcjMjA3MSAtIGRvbid0IGNoZWNrIHRoZSBsb2NhbCBjYWNoZSBkYXRhIGZvciBkZWZhdWx0IHZhbHVlLCBvciBpdCB3aWxsIGZhaWwgYW5kIGNhdXNlIGVycm9ycyB3aGVuIHVuYXV0aGVudGljYXRlZC4gRm9yIGV4YW1wbGUgaW4gdGhlIGluc3RhbGxlci5cblx0XHR2YXIgZm9ybWF0O1xuXHRcdGlmICggIWZvcm1hdCApIHtcblx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpICkge1xuXHRcdFx0XHRmb3JtYXQgPSBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkudGltZV91bml0X2Zvcm1hdDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvcm1hdCA9IDEwO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRmb3JtYXQgPSBwYXJzZUludCggZm9ybWF0ICk7XG5cblx0XHRzd2l0Y2ggKCBmb3JtYXQgKSB7XG5cdFx0XHRjYXNlIDEwOlxuXHRcdFx0XHRyZXR2YWwgPSBHbG9iYWwuY29udmVydFNlY29uZHNUb0hNUyggc2Vjb25kcyApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMTI6XG5cdFx0XHRcdHJldHZhbCA9IEdsb2JhbC5jb252ZXJ0U2Vjb25kc1RvSE1TKCBzZWNvbmRzLCB0cnVlICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSA5OTogLy9Gb3IgbG9jYWwgdXNlIG9ubHksIGluIHByb2dyZXNzIGJhciBhbHdheXMgc2hvdyB0bXBfbWludXRlcyBhbmQgdG1wX3NlY29uZHNcblx0XHRcdFx0cmV0dmFsID0gR2xvYmFsLmNvbnZlcnRTZWNvbmRzVG9ITVMoIHNlY29uZHMsIHRydWUsIHRydWUgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDIwOlxuXHRcdFx0XHRyZXR2YWwgPSAoIHNlY29uZHMgLyAzNjAwICkudG9GaXhlZCggMiApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMjI6XG5cdFx0XHRcdHJldHZhbCA9ICggc2Vjb25kcyAvIDM2MDAgKS50b0ZpeGVkKCAzICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAyMzpcblx0XHRcdFx0cmV0dmFsID0gKCBzZWNvbmRzIC8gMzYwMCApLnRvRml4ZWQoIDQgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDMwOlxuXHRcdFx0XHRyZXR2YWwgPSAoIHNlY29uZHMgLyA2MCApLnRvRml4ZWQoIDAgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDQwOlxuXHRcdFx0XHRyZXR2YWwgPSBzZWNvbmRzO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHQvL0RlYnVnLlRleHQoICdTZWNvbmRzOiAnKyBzZWNvbmRzICsnIFJldHZhbDogJysgcmV0dmFsLCAnR2xvYmFsLmpzJywgJycsICdnZXRUaW1lVW5pdCcsIDEwICk7XG5cdFx0cmV0dXJuIHJldHZhbDtcblx0fTtcblxuR2xvYmFsLnJlbW92ZVRyYWlsaW5nWmVyb3MgPSBmdW5jdGlvbiggdmFsdWUsIG1pbmltdW1fZGVjaW1hbHMgKSB7XG5cdGlmICggIW1pbmltdW1fZGVjaW1hbHMgKSB7XG5cdFx0bWluaW11bV9kZWNpbWFscyA9IDI7XG5cdH1cblx0aWYgKCB2YWx1ZSApIHtcblx0XHR2YWx1ZSA9IHBhcnNlRmxvYXQoIHZhbHVlICk7IC8vIGZpcnN0IHRvIHJlbW92ZSB0aGUgemVybyBhZnRlciB0aGUgcG9pbnQuXG5cblx0XHR2YXIgdHJpbW1lZF92YWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7XG5cblx0XHRpZiAoIHRyaW1tZWRfdmFsdWUuaW5kZXhPZiggJy4nICkgPiAwICkge1xuXHRcdFx0Ly8gSWYgYWZ0ZXIgcmVtb3ZlZCBoYXMgdGhlIHBvaW50LCB0aGVuIHJldmVyc2UgaXQuXG5cdFx0XHR2YXIgdG1wX21pbmltdW1fZGVjaW1hbHMgPSBwYXJzZUludCggdHJpbW1lZF92YWx1ZS5zcGxpdCggJycgKS5yZXZlcnNlKCkuam9pbiggJycgKSApLnRvU3RyaW5nKCkubGVuZ3RoO1xuXHRcdFx0aWYgKCB0bXBfbWluaW11bV9kZWNpbWFscyA+PSBtaW5pbXVtX2RlY2ltYWxzICYmIHRtcF9taW5pbXVtX2RlY2ltYWxzIDw9IDQgKSB7XG5cdFx0XHRcdG1pbmltdW1fZGVjaW1hbHMgPSB0bXBfbWluaW11bV9kZWNpbWFscztcblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHJldHVybiB2YWx1ZS50b0ZpeGVkKCBtaW5pbXVtX2RlY2ltYWxzICk7XG5cdH1cblxuXHRyZXR1cm4gdmFsdWU7XG59O1xuXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5HbG9iYWwuaXNDYW52YXNTdXBwb3J0ZWQgPSBmdW5jdGlvbigpIHtcblx0dmFyIGVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnY2FudmFzJyApO1xuXHRyZXR1cm4gISEoIGVsZW0uZ2V0Q29udGV4dCAmJiBlbGVtLmdldENvbnRleHQoICcyZCcgKSApO1xufTtcblxuR2xvYmFsLmdldFJhbmRvbU51bSA9IGZ1bmN0aW9uKCkge1xuXG5cdHZhciBudW1iZXIgPSBNYXRoLmZsb29yKCBNYXRoLnJhbmRvbSgpICogOTk5ICk7Ly8wLTIzXG5cblx0cmV0dXJuIG51bWJlcjtcblxufTtcblxuLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuXG5HbG9iYWwuZ2V0U2NyaXB0TmFtZUJ5QVBJID0gZnVuY3Rpb24oIGFwaV9jbGFzcyApIHtcblxuXHRpZiAoICFhcGlfY2xhc3MgfHwgIWFwaV9jbGFzcy5jbGFzc05hbWUgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHR2YXIgc2NyaXB0X25hbWUgPSAnJztcblx0c3dpdGNoICggYXBpX2NsYXNzLmNsYXNzTmFtZSApIHtcblx0XHRjYXNlICdBUElVc2VyJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0VtcGxveWVlVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElCcmFuY2gnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnQnJhbmNoVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElEZXBhcnRtZW50Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0RlcGFydG1lbnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJXYWdlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1dhZ2VWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJDb250YWN0Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1VzZXJDb250YWN0Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElVc2VyVGl0bGUnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnVXNlclRpdGxlVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElXYWdlR3JvdXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnV2FnZUdyb3VwVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElMb2cnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnTG9nVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElVc2VyR3JvdXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnVXNlckdyb3VwVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQYXlTdHViRW50cnlBY2NvdW50Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BheVN0dWJFbnRyeUFjY291bnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVBheVN0dWJFbnRyeUFjY291bnRMaW5rJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BheVN0dWJFbnRyeUFjY291bnRMaW5rVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQYXlQZXJpb2QnOlxuXHRcdGNhc2UgJ0FQSVBheVBlcmlvZFNjaGVkdWxlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BheVBlcmlvZHNWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUFjY3J1YWwnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnQVBJQWNjcnVhbCc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElBY2NydWFsQmFsYW5jZSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdBY2NydWFsQmFsYW5jZVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJRXhjZXB0aW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0V4Y2VwdGlvblZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iR3JvdXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iR3JvdXBWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYic6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkl0ZW1Hcm91cCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JJdGVtR3JvdXBWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkl0ZW0nOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iSXRlbVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iSXRlbUFtZW5kbWVudCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JJdGVtQW1lbmRtZW50Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVB1bmNoJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1B1bmNoZXNWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVB1bmNoVGFnJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1B1bmNoVGFnVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQdW5jaFRhZ0dyb3VwJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1B1bmNoVGFnR3JvdXBWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVJlY3VycmluZ1NjaGVkdWxlQ29udHJvbCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdSZWN1cnJpbmdTY2hlZHVsZUNvbnRyb2xWaWV3Jztcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAnQVBJUmVjdXJyaW5nU2NoZWR1bGVUZW1wbGF0ZUNvbnRyb2wnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUmVjdXJyaW5nU2NoZWR1bGVUZW1wbGF0ZUNvbnRyb2xWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVNjaGVkdWxlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1NjaGVkdWxlU2hpZnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUJhbmtBY2NvdW50Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0JhbmtBY2NvdW50Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDb21wYW55Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0NvbXBhbnlWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUN1cnJlbmN5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0N1cnJlbmN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDdXJyZW5jeVJhdGUnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnQ3VycmVuY3lSYXRlJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUhpZXJhcmNoeUNvbnRyb2wnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSGllcmFyY2h5Q29udHJvbFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJRXRobmljR3JvdXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnRXRobmljR3JvdXBWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUN1c3RvbUZpZWxkJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0N1c3RvbUZpZWxkVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQZXJtaXNzaW9uQ29udHJvbCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdQZXJtaXNzaW9uQ29udHJvbFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJU3RhdGlvbic6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdTdGF0aW9uVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElEb2N1bWVudFJldmlzaW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0RvY3VtZW50UmV2aXNpb25WaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSURvY3VtZW50R3JvdXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnRG9jdW1lbnRHcm91cFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJRG9jdW1lbnQnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnRG9jdW1lbnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVJPRSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdST0VWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJEZWZhdWx0Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1VzZXJEZWZhdWx0Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElVc2VyUHJlZmVyZW5jZSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdVc2VyUHJlZmVyZW5jZVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJS1BJJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0tQSVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJVXNlclJldmlld0NvbnRyb2wnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnVXNlclJldmlld0NvbnRyb2xWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVF1YWxpZmljYXRpb24nOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUXVhbGlmaWNhdGlvblZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJVXNlckVkdWNhdGlvbic6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdVc2VyVGl0bGVWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJMYW5ndWFnZSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdVc2VyVGl0bGVWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJMaWNlbnNlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1VzZXJMaWNlbnNlVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElVc2VyTWVtYmVyc2hpcCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdVc2VyTWVtYmVyc2hpcFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJVXNlclNraWxsJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1VzZXJTa2lsbFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iQXBwbGljYW50RWR1Y2F0aW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0pvYkFwcGxpY2FudEVkdWNhdGlvblZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iQXBwbGljYW50RW1wbG95bWVudCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JBcHBsaWNhbnRFZHVjYXRpb25WaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkFwcGxpY2FudExhbmd1YWdlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0pvYkFwcGxpY2FudExhbmd1YWdlVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElKb2JBcHBsaWNhbnRMaWNlbnNlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0pvYkFwcGxpY2FudExpY2Vuc2VWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkFwcGxpY2FudExvY2F0aW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0pvYkFwcGxpY2FudExpY2Vuc2VWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkFwcGxpY2FudE1lbWJlcnNoaXAnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iQXBwbGljYW50TWVtYmVyc2hpcFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iQXBwbGljYW50UmVmZXJlbmNlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0pvYkFwcGxpY2FudFJlZmVyZW5jZVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iQXBwbGljYW50U2tpbGwnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iQXBwbGljYW50U2tpbGxWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYkFwcGxpY2FudCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JBcHBsaWNhbnRTa2lsbFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSm9iQXBwbGljYXRpb24nOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iQXBwbGljYXRpb25WaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUpvYlZhY2FuY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSm9iVmFjYW5jeVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJQXJlYVBvbGljeSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdKb2JWYWNhbmN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDbGllbnQnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnQ2xpZW50Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDbGllbnRDb250YWN0Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0NsaWVudENvbnRhY3RWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUNsaWVudEdyb3VwJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0NsaWVudEdyb3VwVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDbGllbnRQYXltZW50Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0NsaWVudFBheW1lbnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUludm9pY2VEaXN0cmljdCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdJbnZvaWNlRGlzdHJpY3RWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUludm9pY2UnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSW52b2ljZVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJVHJhbnNhY3Rpb24nOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSW52b2ljZVRyYW5zYWN0aW9uVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQYXltZW50R2F0ZXdheSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdQYXltZW50R2F0ZXdheVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUHJvZHVjdEdyb3VwJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1Byb2R1Y3RHcm91cFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUHJvZHVjdCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdQcm9kdWN0Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElJbnZvaWNlQ29uZmlnJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0ludm9pY2VDb25maWdWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVNoaXBwaW5nUG9saWN5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1NoaXBwaW5nUG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElUYXhQb2xpY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnVGF4UG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElDb21wYW55RGVkdWN0aW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0NvbXBhbnlUYXhEZWR1Y3Rpb25WaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVBheVN0dWInOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUGF5U3R1YlZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUGF5U3R1YlRyYW5zYWN0aW9uJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BheVN0dWJUcmFuc2FjdGlvblZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUGF5U3R1YkVudHJ5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BheVN0dWJFbnRyeVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUGF5U3R1YkFtZW5kbWVudCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdQYXlTdHViQW1lbmRtZW50Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElSZWN1cnJpbmdQYXlTdHViQW1lbmRtZW50Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1JlY3VycmluZ1BheVN0dWJBbWVuZG1lbnRWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVVzZXJFeHBlbnNlJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1VzZXJFeHBlbnNlVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElMZWdhbEVudGl0eSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdMZWdhbEVudGl0eVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3lWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVBheXJvbGxSZW1pdHRhbmNlQWdlbmN5RXZlbnQnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3lWaWV3RXZlbnQnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJQWJzZW5jZVBvbGljeSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdBYnNlbmNlUG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElBY2NydWFsUG9saWN5QWNjb3VudCc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdBY2NydWFsUG9saWN5QWNjb3VudFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJQWNjcnVhbFBvbGljeSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdBY2NydWFsUG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElBY2NydWFsUG9saWN5VXNlck1vZGlmaWVyJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0FjY3J1YWxQb2xpY3lVc2VyTW9kaWZpZXJWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUJyZWFrUG9saWN5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0JyZWFrUG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElFeGNlcHRpb25Qb2xpY3lDb250cm9sJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0V4Y2VwdGlvblBvbGljeUNvbnRyb2xWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUV4cGVuc2VQb2xpY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnRXhwZW5zZVBvbGljeVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJSG9saWRheSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdIb2xpZGF5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElIb2xpZGF5UG9saWN5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ0hvbGlkYXlQb2xpY3lWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSU1lYWxQb2xpY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnTWVhbFBvbGljeVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJT3ZlcnRpbWVQb2xpY3knOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnT3ZlcnRpbWVQb2xpY3lWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVBvbGljeUdyb3VwJzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1BvbGljeUdyb3VwVmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElQcmVtaXVtUG9saWN5Jzpcblx0XHRcdHNjcmlwdF9uYW1lID0gJ1ByZW1pdW1Qb2xpY3lWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSVJlY3VycmluZ0hvbGlkYXknOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnUmVjdXJyaW5nSG9saWRheVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJUm91bmRJbnRlcnZhbFBvbGljeSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdSb3VuZEludGVydmFsUG9saWN5Vmlldyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBUElTY2hlZHVsZVBvbGljeSc6XG5cdFx0XHRzY3JpcHRfbmFtZSA9ICdTY2hlZHVsZVBvbGljeVZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQVBJVXNlclJlcG9ydERhdGEnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnVXNlclJlcG9ydERhdGFWaWV3Jztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FQSUluc3RhbGwnOlxuXHRcdFx0c2NyaXB0X25hbWUgPSAnSW5zdGFsbFZpZXcnO1xuXHRcdFx0YnJlYWs7XG5cdH1cblxuXHRyZXR1cm4gc2NyaXB0X25hbWU7XG59O1xuXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5HbG9iYWwuaXNPYmplY3QgPSBmdW5jdGlvbiggb2JqICkge1xuXHRpZiAoIG9iaiAhPT0gbnVsbCAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyApIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdHJldHVybiBmYWxzZTtcbn07XG5cbkdsb2JhbC5pc0FycmF5ID0gZnVuY3Rpb24oIG9iaiApIHtcblxuXHRpZiAoIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCggb2JqICkgIT09ICdbb2JqZWN0IEFycmF5XScgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0cmV0dXJuIHRydWU7XG59O1xuXG5HbG9iYWwuaXNTdHJpbmcgPSBmdW5jdGlvbiggb2JqICkge1xuXG5cdGlmICggT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKCBvYmogKSAhPT0gJ1tvYmplY3QgU3RyaW5nXScgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0cmV0dXJuIHRydWU7XG59O1xuXG5HbG9iYWwuaXNWYWxpZERhdGUgPSBmdW5jdGlvbiggb2JqICkge1xuXHRpZiAoIG9iaiBpbnN0YW5jZW9mIERhdGUgJiYgIWlzTmFOKCBvYmogKSApIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdHJldHVybiBmYWxzZTtcbn07XG5cbkdsb2JhbC5kZWNvZGVDZWxsVmFsdWUgPSBmdW5jdGlvbiggdmFsICkge1xuXHRpZiAoICF2YWwgfHwgXy5pc09iamVjdCggdmFsICkgKSB7XG5cdFx0cmV0dXJuIHZhbDtcblx0fVxuXHR2YWwgPSB2YWwudG9TdHJpbmcoKTtcblx0dmFsID0gdmFsLnJlcGxhY2UoIC9cXG58XFxyfChcXHJcXG4pfChcXHUwMDg1KXwoXFx1MjAyOCl8KFxcdTIwMjkpL2csICc8YnI+JyApO1xuXHR2YWwgPSB2YWwucmVwbGFjZSggL1xcbnxcXHJ8KFxcclxcbil8KFxcdTAwODUpfChcXHUyMDI4KXwoXFx1MjAyOSkvZywgJzxicj4nICk7XG5cdHZhbCA9IEdsb2JhbC5odG1sRW5jb2RlKCB2YWwgKTtcblx0dmFsID0gdmFsLnJlcGxhY2UoIC8mbHQ7YnImZ3Q7L2csICc8YnI+JyApO1xuXG5cdHJldHVybiB2YWw7XG59O1xuXG5HbG9iYWwuYnVpbGRUcmVlUmVjb3JkID0gZnVuY3Rpb24oIGFycmF5LCBwYXJlbnRJZCApIHtcblx0dmFyIGZpbmFsQXJyYXkgPSBbXTtcblxuXHQkLmVhY2goIGFycmF5LCBmdW5jdGlvbigga2V5LCBpdGVtICkge1xuXHRcdGl0ZW0uZXhwYW5kZWQgPSB0cnVlO1xuXHRcdGl0ZW0ubG9hZGVkID0gdHJ1ZTtcblxuXHRcdGlmICggR2xvYmFsLmlzU2V0KCBwYXJlbnRJZCApICkge1xuXHRcdFx0aXRlbS5wYXJlbnQgPSBwYXJlbnRJZDtcblx0XHR9XG5cblx0XHRmaW5hbEFycmF5LnB1c2goIGl0ZW0gKTtcblxuXHRcdGlmICggR2xvYmFsLmlzU2V0KCBpdGVtLmNoaWxkcmVuICkgKSB7XG5cdFx0XHR2YXIgY2hpbGRyZW5BcnJheSA9IEdsb2JhbC5idWlsZFRyZWVSZWNvcmQoIGl0ZW0uY2hpbGRyZW4sIGl0ZW0uaWQgKTtcblx0XHRcdGZpbmFsQXJyYXkgPSBmaW5hbEFycmF5LmNvbmNhdCggY2hpbGRyZW5BcnJheSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpdGVtLmlzTGVhZiA9IHRydWU7XG5cdFx0fVxuXG5cdH0gKTtcblxuXHRyZXR1cm4gZmluYWxBcnJheTtcbn07XG5cbkdsb2JhbC5nZXRQYXJlbnRJZEJ5VHJlZVJlY29yZCA9IGZ1bmN0aW9uKCBhcnJheSwgc2VsZWN0SWQgKSB7XG5cblx0dmFyIHJldHZhbCA9IFtdO1xuXHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKyApIHtcblx0XHR2YXIgaXRlbSA9IGFycmF5W2ldO1xuXHRcdGlmICggaXRlbS5pZC50b1N0cmluZygpID09PSBzZWxlY3RJZC50b1N0cmluZygpICkge1xuXHRcdFx0dmFyIG5ld19yb3cgPSB7fTtcblx0XHRcdGlmICggdHlwZW9mIGl0ZW0ucGFyZW50ICE9ICd1bmRlZmluZWQnICkge1xuXHRcdFx0XHRuZXdfcm93ID0geyBwYXJlbnRfaWQ6IGl0ZW0ucGFyZW50LnRvU3RyaW5nKCksIG5hbWU6IGl0ZW0ubmFtZSB9O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bmV3X3JvdyA9IHsgbmFtZTogaXRlbS5uYW1lIH07XG5cdFx0XHR9XG5cblx0XHRcdC8vV2l0aG91dCBjcmVhdGVkIGFuZCB1cGRhdGVkIGluZm8sIGF1ZGl0IHRhYiBzaG93cyBOL0EgZm9yIGJvdGhcblx0XHRcdGlmICggdHlwZW9mIGl0ZW0uY3JlYXRlZF9ieSAhPSAndW5kZWZpbmVkJyApIHtcblx0XHRcdFx0bmV3X3Jvdy5jcmVhdGVkX2J5ID0gaXRlbS5jcmVhdGVkX2J5O1xuXHRcdFx0XHRuZXdfcm93LmNyZWF0ZWRfZGF0ZSA9IGl0ZW0uY3JlYXRlZF9kYXRlO1xuXHRcdFx0XHRuZXdfcm93LnVwZGF0ZWRfYnkgPSBpdGVtLnVwZGF0ZWRfYnk7XG5cdFx0XHRcdG5ld19yb3cudXBkYXRlZF9kYXRlID0gaXRlbS51cGRhdGVkX2RhdGU7XG5cdFx0XHR9XG5cblx0XHRcdHJldHZhbC5wdXNoKCBuZXdfcm93ICk7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gcmV0dmFsO1xuXG59O1xuXG5HbG9iYWwuYWRkRmlyc3RJdGVtVG9BcnJheSA9IGZ1bmN0aW9uKCBhcnJheSwgZmlyc3RJdGVtVHlwZSwgY3VzdG9tTGFiZWwgKSB7XG5cdC8vRXJyb3I6IFVuYWJsZSB0byBnZXQgcHJvcGVydHkgJ3Vuc2hpZnQnIG9mIHVuZGVmaW5lZCBvciBudWxsIHJlZmVyZW5jZSBpbiAvaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC9HbG9iYWwuanM/dj04LjAuMC0yMDE0MTIzMC0xNTM5NDIgbGluZSA5MDNcblx0dmFyIGxhYmVsO1xuXHRpZiAoIGFycmF5ICkge1xuXHRcdGlmICggZmlyc3RJdGVtVHlwZSA9PT0gJ2FueScgKSB7XG5cdFx0XHRpZiAoIGN1c3RvbUxhYmVsICkge1xuXHRcdFx0XHRsYWJlbCA9IGN1c3RvbUxhYmVsO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGFiZWwgPSBHbG9iYWwuYW55X2l0ZW07XG5cdFx0XHR9XG5cdFx0XHQvLyMyMzAxIC0gZG9uJ3QgZHVwbGljYXRlIHRoZSAtLUFueS0tIGNhc2Ugd2hlbiB0aGUgYXJyYXkgaXMgcmVjeWNsZWQuXG5cdFx0XHRpZiAoICFhcnJheVswXSB8fCBhcnJheVswXS52YWx1ZSAhPSBUVFVVSUQubm90X2V4aXN0X2lkICkge1xuXHRcdFx0XHRhcnJheS51bnNoaWZ0KCB7XG5cdFx0XHRcdFx0bGFiZWw6IGxhYmVsLFxuXHRcdFx0XHRcdHZhbHVlOiBUVFVVSUQubm90X2V4aXN0X2lkLFxuXHRcdFx0XHRcdGZ1bGxWYWx1ZTogVFRVVUlELm5vdF9leGlzdF9pZCxcblx0XHRcdFx0XHRvcmRlclZhbHVlOiAnJ1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmICggZmlyc3RJdGVtVHlwZSA9PT0gJ2VtcHR5JyApIHtcblx0XHRcdGlmICggY3VzdG9tTGFiZWwgKSB7XG5cdFx0XHRcdGxhYmVsID0gY3VzdG9tTGFiZWw7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRsYWJlbCA9IEdsb2JhbC5lbXB0eV9pdGVtO1xuXHRcdFx0fVxuXHRcdFx0Ly8jMjMwMSAtIGRvbid0IGR1cGxpY2F0ZSB0aGUgLS1Ob25lLS0gY2FzZSB3aGVuIHRoZSBhcnJheSBpcyByZWN5Y2xlZC5cblx0XHRcdGlmICggIWFycmF5WzBdIHx8IGFycmF5WzBdLnZhbHVlICE9IFRUVVVJRC56ZXJvX2lkICkge1xuXHRcdFx0XHRhcnJheS51bnNoaWZ0KCB7XG5cdFx0XHRcdFx0bGFiZWw6IGxhYmVsLFxuXHRcdFx0XHRcdHZhbHVlOiBUVFVVSUQuemVyb19pZCxcblx0XHRcdFx0XHRmdWxsVmFsdWU6IFRUVVVJRC56ZXJvX2lkLFxuXHRcdFx0XHRcdG9yZGVyVmFsdWU6ICcnXG5cdFx0XHRcdH0gKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gYXJyYXk7XG59O1xuXG4vL0FkZCBpdGVtIG9uIHRvIHRoZSBlbmQgb2YgdGhlIGFycmF5LCBidXQgbWFrZSBzdXJlIGl0cyBub3QgYWxyZWFkeSB0aGVyZSBhbmQgdGhlcmVmb3JlIG5ldmVyIGR1cGxpY2F0ZWQuXG5HbG9iYWwuYWRkTGFzdEl0ZW1Ub0FycmF5ID0gZnVuY3Rpb24oIGFycmF5LCBrZXksIGxhYmVsICkge1xuXHR2YXIgbGFiZWw7XG5cdGlmICggYXJyYXkgKSB7XG5cdFx0dmFyIGxhc3RfYXJyYXlfZWxlbWVudCA9IGFycmF5WyggYXJyYXkubGVuZ3RoIC0gMSApXTtcblx0XHRpZiAoIGxhc3RfYXJyYXlfZWxlbWVudC52YWx1ZSAhPSBrZXkgKSB7XG5cdFx0XHRhcnJheS5wdXNoKCB7XG5cdFx0XHRcdGZ1bGxWYWx1ZToga2V5LFxuXHRcdFx0XHR2YWx1ZToga2V5LFxuXHRcdFx0XHRsYWJlbDogbGFiZWwsXG5cdFx0XHRcdGlkOiAyMDAwXG5cdFx0XHR9ICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGFycmF5O1xufTtcblxuR2xvYmFsLmNvbnZlcnRSZWNvcmRBcnJheVRvT3B0aW9ucyA9IGZ1bmN0aW9uKCBhcnJheSApIHtcblx0dmFyIGxlbiA9IGFycmF5Lmxlbmd0aDtcblx0dmFyIG9wdGlvbnMgPSB7fTtcblxuXHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHR2YXIgaXRlbSA9IGFycmF5W2ldO1xuXG5cdFx0b3B0aW9uc1tpdGVtLnZhbHVlXSA9IGl0ZW0ubGFiZWw7XG5cdH1cblxuXHRyZXR1cm4gb3B0aW9ucztcbn07XG5cbkdsb2JhbC5idWlsZENvbHVtbkFycmF5ID0gZnVuY3Rpb24oIGFycmF5ICkge1xuXHR2YXIgY29sdW1ucyA9IFtdO1xuXHR2YXIgaWQgPSAxMDAwO1xuXG5cdGZvciAoIHZhciBrZXkgaW4gYXJyYXkgKSB7XG5cdFx0dmFyIG9yZGVyX3ZhbHVlID0gR2xvYmFsLmdldFNvcnRWYWx1ZSgga2V5LCB0cnVlICk7XG5cdFx0dmFyIGNvbHVtbiA9IHtcblx0XHRcdGxhYmVsOiBhcnJheVtrZXldLFxuXHRcdFx0dmFsdWU6IEdsb2JhbC5yZW1vdmVTb3J0UHJlZml4KCBrZXkgKSxcblx0XHRcdG9yZGVyVmFsdWU6IG9yZGVyX3ZhbHVlLFxuXHRcdFx0aWQ6IGlkXG5cdFx0fTtcblx0XHRjb2x1bW5zLnB1c2goIGNvbHVtbiApO1xuXHRcdGlkID0gaWQgKyAxO1xuXHR9XG5cdHJldHVybiBjb2x1bW5zO1xufTtcblxuR2xvYmFsLnJlbW92ZVNvcnRQcmVmaXhGcm9tQXJyYXkgPSBmdW5jdGlvbiggYXJyYXkgKSB7XG5cdHZhciBmaW5hbEFycmF5ID0ge307XG5cblx0aWYgKCBHbG9iYWwuaXNTZXQoIGFycmF5ICkgKSB7XG5cblx0XHQkLmVhY2goIGFycmF5LCBmdW5jdGlvbigga2V5LCBpdGVtICkge1xuXHRcdFx0ZmluYWxBcnJheVtHbG9iYWwucmVtb3ZlU29ydFByZWZpeCgga2V5ICldID0gaXRlbTtcblx0XHR9ICk7XG5cblx0XHRyZXR1cm4gZmluYWxBcnJheTtcblx0fVxuXG5cdHJldHVybiBhcnJheTtcbn07XG5cbkdsb2JhbC5yZW1vdmVTb3J0UHJlZml4ID0gZnVuY3Rpb24oIGtleSApIHtcblx0aWYgKCB0eXBlb2Yga2V5ID09ICdzdHJpbmcnICYmIGtleS5tYXRjaCggR2xvYmFsLnNvcnRPcmRlclJlZ2V4ICkgKSB7XG5cdFx0a2V5ID0ga2V5LnJlcGxhY2UoIEdsb2JhbC5zb3J0T3JkZXJSZWdleCwgJycgKTtcblx0fVxuXHRyZXR1cm4ga2V5O1xufTtcblxuR2xvYmFsLmdldFNvcnRWYWx1ZSA9IGZ1bmN0aW9uKCBrZXksIHJldHVybl9rZXlfb25fbnVsbCApIHtcblx0dmFyIG9yZGVyX3ZhbHVlID0gOTk5O1xuXHRpZiAoIHR5cGVvZiBrZXkgPT0gJ3N0cmluZycgKSB7XG5cdFx0dmFyIHJlZ2V4X3Jlc3VsdCA9IGtleS5tYXRjaCggR2xvYmFsLnNvcnRPcmRlclJlZ2V4ICk7XG5cdFx0aWYgKCByZWdleF9yZXN1bHQgPT0gbnVsbCApIHtcblx0XHRcdGlmICggcmV0dXJuX2tleV9vbl9udWxsID09PSB0cnVlICkge1xuXHRcdFx0XHRvcmRlcl92YWx1ZSA9IGtleTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKCByZWdleF9yZXN1bHRbMV0gKSB7XG5cdFx0XHRvcmRlcl92YWx1ZSA9IHJlZ2V4X3Jlc3VsdFsxXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0RGVidWcuRXJyb3IoICdFcnJvcjogVW5hYmxlIHRvIHBhcnNlIG9yZGVyX3ZhbHVlJywgJ0dsb2JhbCcsICdHbG9iYWwnLCAnYnVpbGRDb2x1bW5BcnJheScsIDEwICk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBvcmRlcl92YWx1ZTtcbn07XG5cbkdsb2JhbC5jb252ZXJ0VG9OdW1iZXJJZlBvc3NpYmxlID0gZnVuY3Rpb24oIHZhbCApIHtcblx0Ly9pZiB2YWx1ZSBpcyBudW1iZXIgY29udmVydCB0byBudW1iZXIgdHlwZVxuXHR2YXIgcmVnID0gbmV3IFJlZ0V4cCggJ15bMC05XSokJyApO1xuXG5cdGlmICggcmVnLnRlc3QoIHZhbCApICYmIHZhbCAhPT0gJzAwJyApIHtcblx0XHR2YWwgPSBwYXJzZUZsb2F0KCB2YWwgKTtcblx0fVxuXG5cdGlmICggdmFsID09PSAnLTEnIHx8IHZhbCA9PT0gLTEgKSB7XG5cdFx0dmFsID0gLTE7XG5cdH1cblxuXHRyZXR1cm4gdmFsO1xufTtcblxuR2xvYmFsLmJ1aWxkUmVjb3JkQXJyYXkgPSBmdW5jdGlvbiggYXJyYXksIGZpcnN0X2l0ZW0sIG9yZGVyVHlwZSApIHtcblx0dmFyIGZpbmFsQXJyYXkgPSBbXTtcblxuXHRpZiAoIGZpcnN0X2l0ZW0gKSB7XG5cdFx0ZmluYWxBcnJheS5wdXNoKCBmaXJzdF9pdGVtICk7XG5cdH1cblxuXHR2YXIgaWQgPSAxMDAwO1xuXG5cdGlmICggR2xvYmFsLmlzU2V0KCBhcnJheSApICkge1xuXG5cdFx0Zm9yICggdmFyIGtleSBpbiBhcnJheSApIHtcblx0XHRcdHZhciBpdGVtID0gYXJyYXlba2V5XTtcblx0XHRcdHZhciB2YWx1ZSA9IEdsb2JhbC5yZW1vdmVTb3J0UHJlZml4KCBrZXkgKTtcblx0XHRcdHZhciBvcmRlcl92YWx1ZSA9IEdsb2JhbC5nZXRTb3J0VmFsdWUoIGtleSApO1xuXG5cdFx0XHQvLyA2LzQgY2hhbmdlZCBpZCB0byBzYW1lIGFzIHZhbHVlIHRvIG1ha2UgZmxleCBzaG93IGNvcnJlY3QgZGF0YSB3aGVuIHNob3cgc2VhcmNoIHJlc3VsdCBzYXZlZCBpbiBodG1sNSwgZmxleCB1c2UgaWQgaWYgaXQgZXhpc3RlZC5cblx0XHRcdHZhciByZWNvcmQgPSB7IGxhYmVsOiBpdGVtLCB2YWx1ZTogdmFsdWUsIGZ1bGxWYWx1ZToga2V5LCBvcmRlclZhbHVlOiBvcmRlcl92YWx1ZSwgaWQ6IHZhbHVlIH07XG5cblx0XHRcdGlkID0gaWQgKyAxO1xuXG5cdFx0XHRmaW5hbEFycmF5LnB1c2goIHJlY29yZCApO1xuXG5cdFx0fVxuXG5cdH1cblxuXHRyZXR1cm4gZmluYWxBcnJheTtcblxufTtcblxuR2xvYmFsLnRvcENvbnRhaW5lciA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gJCggJyN0b3BDb250YWluZXInICk7XG59O1xuXG5HbG9iYWwub3ZlcmxheSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gJCggJyNvdmVybGF5JyApO1xufTtcblxuR2xvYmFsLmJvdHRvbUNvbnRhaW5lciA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gJCggJyNib3R0b21Db250YWluZXInICk7XG59O1xuXG5HbG9iYWwuYm90dG9tRmVlZGJhY2tMaW5rQ29udGFpbmVyID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiAkKCAnI2ZlZWRiYWNrTGlua0NvbnRhaW5lcicgKTtcbn07XG5cbkdsb2JhbC5zaG93UG93ZXJlZEJ5ID0gZnVuY3Rpb24oKSB7XG5cdHZhciBwb3dlcmVkX2J5X2ltZyA9ICQoICcjcG93ZXJlZF9ieScgKTtcblx0cG93ZXJlZF9ieV9pbWcuc2hvdygpO1xuXHRwb3dlcmVkX2J5X2ltZy5hdHRyKCAnc3JjJywgU2VydmljZUNhbGxlci5nZXRVUkxCeU9iamVjdFR5cGUoICdjb3B5cmlnaHQnICkgKTtcblx0cG93ZXJlZF9ieV9pbWcuYXR0ciggJ2FsdCcsIExvY2FsQ2FjaGVEYXRhLmxvZ2luRGF0YS5hcHBsaWNhdGlvbl9uYW1lICsgJyBXb3JrZm9yY2UgTWFuYWdlbWVudCBTb2Z0d2FyZScgKTtcblx0dmFyIHBvd2VyZWRfYnlfbGluayA9ICQoICc8YSB0YXJnZXQ9XCJfYmxhbmtcIiBocmVmPVwiaHR0cHM6Ly8nICsgTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5EYXRhKCkub3JnYW5pemF0aW9uX3VybCArICdcIj48L2E+JyApO1xuXHRwb3dlcmVkX2J5X2xpbmsuYWRkQ2xhc3MoICdwb3dlcmVkLWJ5LWltZy1zZW8nICk7XG5cdHBvd2VyZWRfYnlfaW1nLndyYXAoIHBvd2VyZWRfYnlfbGluayApO1xufTtcblxuR2xvYmFsLnNldFNpZ25hbFN0cmVuZ3RoID0gZnVuY3Rpb24oKSB7XG5cdGlmICggR2xvYmFsLnNpZ25hbF90aW1lciApIHtcblx0XHRyZXR1cm47XG5cdH1cblx0JCggJy5zaWduYWwtc3RyZW5ndGgnICkuY3NzKCAnZGlzcGxheScsICdibG9jaycgKTtcblx0dmFyIHN0YXR1cyA9ICcuLi4uLi4nO1xuXHR2YXIgYXZlcmFnZV90aW1lID0gMDtcblx0dmFyIGNoZWNraW5nX2FycmF5ID0gW107XG5cdHZhciBzaW5nbGVfc3RyZW5ndGggPSBudWxsO1xuXHR2YXIgc2luZ2xlX3N0cmVuZ3RoX3Rvb2x0aXAgPSBudWxsO1xuXG5cdHNldFRvb2x0aXAoKTtcblxuXHRzZXRUaW1lb3V0KCBmdW5jdGlvbigpIHtcblx0XHRkb1BpbmcoKTtcblx0fSwgMTAwMDAgKTtcblx0R2xvYmFsLnNpZ25hbF90aW1lciA9IHNldEludGVydmFsKCBmdW5jdGlvbigpIHtcblx0XHRkb1BpbmcoKTtcblx0fSwgNjAwMDAgKTtcblxuXHRmdW5jdGlvbiBkb1BpbmcoKSB7XG5cdFx0aWYgKCAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIgJiYgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci52aWV3SWQgPT09ICdMb2dpblZpZXcnICkgfHwgR2xvYmFsLmlkbGVfdGltZSA+PSBNYXRoLm1pbiggMTUsIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5zZXNzaW9uX2lkbGVfdGltZW91dCAvIDYwICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0cGluZyggU2VydmljZUNhbGxlci5iYXNlX3VybCArICdpbnRlcmZhY2UvcGluZy5odG1sP3Q9JyArIG5ldyBEYXRlKCkuZ2V0VGltZSgpLCBmdW5jdGlvbiggdGltZSApIHtcblx0XHRcdCQoICcuc2lnbmFsLXN0cmVuZ3RoLWVtcHR5JyApLnJlbW92ZUNsYXNzKCAnc2lnbmFsLXN0cmVuZ3RoLWVtcHR5JyApO1xuXG5cdFx0XHRpZiAoIGNoZWNraW5nX2FycmF5Lmxlbmd0aCA+PSAzICkge1xuXHRcdFx0XHRjaGVja2luZ19hcnJheS5zaGlmdCgpO1xuXHRcdFx0fVxuXHRcdFx0Y2hlY2tpbmdfYXJyYXkucHVzaCggdGltZSApO1xuXHRcdFx0dmFyIHRvdGFsX3RpbWUgPSAwO1xuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgY2hlY2tpbmdfYXJyYXkubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdHRvdGFsX3RpbWUgPSBjaGVja2luZ19hcnJheVtpXSArIHRvdGFsX3RpbWU7XG5cdFx0XHR9XG5cdFx0XHRhdmVyYWdlX3RpbWUgPSB0b3RhbF90aW1lIC8gY2hlY2tpbmdfYXJyYXkubGVuZ3RoO1xuXHRcdFx0RGVidWcuVGV4dCggJ0N1cnJlbnQgUGluZzogJyArIHRpbWUgKyAnbXMgQXZlcmFnZTogJyArIGF2ZXJhZ2VfdGltZSArICdtcyBEYXRlOiAnICsgKCBuZXcgRGF0ZSApLnRvSVNPU3RyaW5nKCkucmVwbGFjZSggL3p8dC9naSwgJyAnICksICdHbG9iYWwuanMnLCAnJywgJ2RvUGluZycsIDYgKTtcblx0XHRcdEdsb2JhbC5jdXJyZW50X3BpbmcgPSBhdmVyYWdlX3RpbWU7XG5cdFx0XHRzdGF0dXMgPSAkLmkxOG4uXyggJ0dvb2QnICk7XG5cdFx0XHQvL2RvIG5vdCBhbGxvdyBzaWduYWwgc3RyZW5ndGggdmFyaWF0aW9uIGluIHVuaXQgdGVzdCBtb2RlXG5cdFx0XHRpZiAoIEdsb2JhbC5VTklUX1RFU1RfTU9ERSA9PSBmYWxzZSApIHtcblx0XHRcdFx0aWYgKCBhdmVyYWdlX3RpbWUgPiA0MDAgKSB7XG5cdFx0XHRcdFx0JCggJy5zaWduYWwtc3RyZW5ndGgtcHJldHR5LXN0cm9uZycgKS5hZGRDbGFzcyggJ3NpZ25hbC1zdHJlbmd0aC1lbXB0eScgKTtcblx0XHRcdFx0XHQkKCAnLnNpZ25hbC1zdHJlbmd0aC1zdHJvbmcnICkuYWRkQ2xhc3MoICdzaWduYWwtc3RyZW5ndGgtZW1wdHknICk7XG5cdFx0XHRcdFx0JCggJy5zaWduYWwtc3RyZW5ndGgtd2VhaycgKS5hZGRDbGFzcyggJ3NpZ25hbC1zdHJlbmd0aC1lbXB0eScgKTtcblx0XHRcdFx0XHRzdGF0dXMgPSAkLmkxOG4uXyggJ1Bvb3InICk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIGF2ZXJhZ2VfdGltZSA+IDI1MCApIHtcblx0XHRcdFx0XHQkKCAnLnNpZ25hbC1zdHJlbmd0aC1wcmV0dHktc3Ryb25nJyApLmFkZENsYXNzKCAnc2lnbmFsLXN0cmVuZ3RoLWVtcHR5JyApO1xuXHRcdFx0XHRcdCQoICcuc2lnbmFsLXN0cmVuZ3RoLXN0cm9uZycgKS5hZGRDbGFzcyggJ3NpZ25hbC1zdHJlbmd0aC1lbXB0eScgKTtcblx0XHRcdFx0XHRzdGF0dXMgPSAkLmkxOG4uXyggJ0JlbG93IEF2ZXJhZ2UnICk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIGF2ZXJhZ2VfdGltZSA+IDE1MCApIHtcblx0XHRcdFx0XHQkKCAnLnNpZ25hbC1zdHJlbmd0aC1wcmV0dHktc3Ryb25nJyApLmFkZENsYXNzKCAnc2lnbmFsLXN0cmVuZ3RoLWVtcHR5JyApO1xuXHRcdFx0XHRcdHN0YXR1cyA9ICQuaTE4bi5fKCAnQXZlcmFnZScgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRzZXRUb29sdGlwKCk7XG5cblx0XHR9ICk7XG5cdH1cblxuXHRmdW5jdGlvbiBzZXRUb29sdGlwKCkge1xuXHRcdHZhciBodG1sID0gJzxkaXY+JyArICQuaTE4bi5fKCAnWW91ciBOZXR3b3JrIENvbm5lY3Rpb24gaXMnICkgKyAnICcgKyBzdGF0dXMgKyAnICgnICsgJC5pMThuLl8oICdMYXRlbmN5JyApICsgJzogJyArICggYXZlcmFnZV90aW1lID4gMCA/IGF2ZXJhZ2VfdGltZS50b0ZpeGVkKCAwICkgKyAnbXMnIDogJC5pMThuLl8oICdDYWxjdWxhdGluZy4uLicgKSApICsgJyknICsgJzwvZGl2Pic7XG5cdFx0JCggJy5zaWduYWwtc3RyZW5ndGgnICkucXRpcCgge1xuXHRcdFx0aWQ6ICdzaW5nbGVfc3RyZW5ndGgnLFxuXHRcdFx0Y29udGVudDoge1xuXHRcdFx0XHR0ZXh0OiBodG1sXG5cdFx0XHR9LFxuXHRcdFx0cG9zaXRpb246IHtcblx0XHRcdFx0bXk6ICdib3R0b20gbGVmdCcsXG5cdFx0XHRcdGF0OiAndG9wIHJpZ2h0J1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxuXG5cdGZ1bmN0aW9uIHBpbmcoIHVybCwgY2FsbGJhY2sgKSB7XG5cdFx0dmFyIGluVXNlLCBzdGFydCwgaW1nLCB0aW1lcjtcblx0XHRpZiAoICFpblVzZSApIHtcblx0XHRcdGluVXNlID0gdHJ1ZTtcblx0XHRcdGltZyA9IG5ldyBJbWFnZSgpO1xuXHRcdFx0aW1nLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZW5kVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXHRcdFx0XHRpblVzZSA9IGZhbHNlO1xuXHRcdFx0XHRjYWxsYmFjayggKCBlbmRUaW1lIC0gc3RhcnQgKSApO1xuXG5cdFx0XHR9O1xuXHRcdFx0aW1nLm9uZXJyb3IgPSBmdW5jdGlvbiggZSApIHtcblx0XHRcdFx0aWYgKCBpblVzZSApIHtcblx0XHRcdFx0XHRpblVzZSA9IGZhbHNlO1xuXHRcdFx0XHRcdHZhciBlbmRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cdFx0XHRcdFx0Y2FsbGJhY2soICggZW5kVGltZSAtIHN0YXJ0ICkgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9O1xuXHRcdFx0c3RhcnQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblx0XHRcdGltZy5zcmMgPSB1cmw7XG5cdFx0XHR0aW1lciA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGluVXNlICkge1xuXHRcdFx0XHRcdHZhciBlbmRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cdFx0XHRcdFx0aW5Vc2UgPSBmYWxzZTtcblx0XHRcdFx0XHRjYWxsYmFjayggKCBlbmRUaW1lIC0gc3RhcnQgKSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9LCA1MDAwICk7XG5cdFx0fVxuXHR9XG59O1xuXG5HbG9iYWwuY29udGVudENvbnRhaW5lciA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gJCggJyNjb250ZW50Q29udGFpbmVyJyApO1xufTtcblxuR2xvYmFsLmJvZHlXaWR0aCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gJCggd2luZG93ICkud2lkdGgoKTtcbn07XG5cbkdsb2JhbC5ib2R5SGVpZ2h0ID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiAkKCB3aW5kb3cgKS5oZWlnaHQoKTtcbn07XG5cbkdsb2JhbC5oYXNSZXF1aXJlTG9hZGVkID0gZnVuY3Rpb24oIHNjcmlwdF9wYXRoICkge1xuXHR2YXIgc3BsaXRfc2NyaXB0X3BhdGggPSBzY3JpcHRfcGF0aC5zcGxpdCggJy8nICk7XG5cblx0dmFyIGlkID0gc3BsaXRfc2NyaXB0X3BhdGhbc3BsaXRfc2NyaXB0X3BhdGgubGVuZ3RoIC0gMV07XG5cdGlkID0gaWQucmVwbGFjZSggJy5qcycsICcnICk7XG5cblx0Ly9DaGVjayBhbHRlcm5hdGl2ZSBzY3JpcHQgbmFtZXMgKGllOiB3aXRoL3dpdGhvdXQgdGhlIC5qcykgd2hlbiBhIGZ1bGwgcGF0aCBpcyBzcGVjaWZpZWQgdG8gc2VlIGlmIGl0IHdhcyBsb2FkZWQgaW4gZGlmZmVyZW50IHdheXMgd2l0aCByZXF1aXJlSlMgYW5kIG1ha2Ugc3VyZSBpdHMgbm90IGxvYWRlZCB0d2ljZS5cblx0aWYgKCBzY3JpcHRfcGF0aC5pbmRleE9mKCAnLmpzJyApID09IC0xICkge1xuXHRcdHZhciBhbHRlcm5hdGl2ZV9zY3JpcHRfcGF0aCA9IHNjcmlwdF9wYXRoICsgJy5qcyc7XG5cdH0gZWxzZSB7XG5cdFx0dmFyIGFsdGVybmF0aXZlX3NjcmlwdF9wYXRoID0gc2NyaXB0X3BhdGgucmVwbGFjZSggJy5qcycsICcnICk7XG5cdH1cblxuXHQvL01ha2Ugc3VyZSB0aGUgZnVuY3Rpb24gaXMgYm90aCBzcGVjaWZpZWQgYW5kIGRlZmluZWQuIFRoaXMgaGVscHMgY2FzZXMgd2hlcmUgdGhlIHVzZXIgaXMgb24gYSBTbG93IDNHIG5ldHdvcmsgYW5kIGRvdWJsZSBjbGlja3MgQXR0ZW5kYW5jZSAtPiBJbi9PdXQuXG5cdC8vICBJbiB0aGlzIGNhc2UgdGhlIHNhbWUgSW5PdXRWaWV3Q29udHJvbGxlci5qcyBmaWxlIGlzIGluIHRoZSBwcm9jZXNzIG9mIGJlaW5nIGxvYWRlZCwgdGhlbiBpcyBjYW5jZWxsZWQsXG5cdC8vICBhbmQgYW5vdGhlciBvbmUgdHJpZXMgdG8gbG9hZCBhbmQgdGhlIHN1Y2Nlc3MgY2FsbGJhY2sgd2hlcmUgdGhlIGNsYXNzIGlzIGluc3RhbnRpYXRlZCBpcyBjYWxsZWQgYmVmb3JlIGl0IGNhbiBiZSBpbnN0YW50aWF0ZWQsIGNhdXNpbmcgYSBKUyBleGNlcHRpb24gKFJlZmVyZW5jZUVycm9yOiBJbk91dFZpZXdDb250cm9sbGVyIGlzIG5vdCBkZWZpbmVkKS5cblx0Ly8gIEJldHRlciBkb3VibGUtY2xpY2sgcHJldmVudGlvbiB3b3VsZCBhbHNvIGhlbHAuXG5cdC8vIGlmICggdHlwZW9mIHJlcXVpcmUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHJlcXVpcmUuc3BlY2lmaWVkID09PSAnZnVuY3Rpb24nICYmICggcmVxdWlyZS5zcGVjaWZpZWQoIGlkICkgfHwgcmVxdWlyZS5zcGVjaWZpZWQoIHNjcmlwdF9wYXRoICkgfHwgcmVxdWlyZS5zcGVjaWZpZWQoIGFsdGVybmF0aXZlX3NjcmlwdF9wYXRoICkgKSApIHtcblx0Ly8gaWYgKCB0eXBlb2YgcmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgcmVxdWlyZS5kZWZpbmVkID09PSAnZnVuY3Rpb24nICYmICggcmVxdWlyZS5kZWZpbmVkKCBpZCApIHx8IHJlcXVpcmUuZGVmaW5lZCggc2NyaXB0X3BhdGggKSB8fCByZXF1aXJlLmRlZmluZWQoIGFsdGVybmF0aXZlX3NjcmlwdF9wYXRoICkgKSApIHtcblx0Ly8gXHRyZXR1cm4gdHJ1ZTtcblx0Ly8gLy99XG5cblx0cmV0dXJuIGZhbHNlO1xufTtcblxuR2xvYmFsLmxvYWRTY3JpcHQgPSBmdW5jdGlvbiggc2NyaXB0UGF0aCwgb25SZXN1bHQgKSB7XG5cdGlmICggdHlwZW9mIHNjcmlwdFBhdGggIT09ICdzdHJpbmcnICkge1xuXHRcdC8vIE5vdCBpZGVhbCBmaXggYnV0IHRoaXMgaXMgdG8gaGFuZGxlIHRoZSBzY3JpcHRQYXRoLnNwbGl0IGlzIG5vdCBhIGZ1bmN0aW9uIGVycm9yIGluICMyNjk2LiBpZiB0aGUgcGF0aCBpcyBub3QgYSBzdHJpbmcsIHNwbGl0IGRvZXMgbm90IGV4aXN0IGFzIGEgZnVuY3Rpb24uXG5cdFx0Ly8gSGFyZCB0byBmaW5kIHJvb3QtY2F1c2UvcmVwcm9kdWNlLCBzbyB0aGlzIGZpeCBpcyB0byByZWR1Y2UgdGhlIG9jY3VyYW5jZXMgb2YgdGhlIEpTIGV4Y2VwdGlvbnMgcmVsYXRlZCB0byBpdC5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHR2YXIgYXN5bmMgPSB0cnVlO1xuXHRpZiAoIHR5cGVvZiAoIG9uUmVzdWx0ICkgPT09ICd1bmRlZmluZWQnICkge1xuXHRcdGFzeW5jID0gZmFsc2U7XG5cdH1cblxuXHRpZiAoIEdsb2JhbC5oYXNSZXF1aXJlTG9hZGVkKCBzY3JpcHRQYXRoICkgKSB7XG5cdFx0aWYgKCBhc3luYyApIHtcblx0XHRcdG9uUmVzdWx0KCk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0Ly9FbnN1cmVzIHRoYXQgdGhlIGpzIGNhY2hlZCBzY3JpcHRzIGFyZSBub3QgbG9hZGVkIHR3aWNlXG5cdGlmICggYXN5bmMgKSB7XG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5sb2FkZWRTY3JpcHROYW1lc1tzY3JpcHRQYXRoXSApIHtcblx0XHRcdG9uUmVzdWx0KCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdGlmICggTG9jYWxDYWNoZURhdGEubG9hZGVkU2NyaXB0TmFtZXNbc2NyaXB0UGF0aF0gKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdH1cblxuXHR2YXIgc3VjY2Vzc2ZsYWcgPSBmYWxzZTtcblxuXHR2YXIgcmVhbFBhdGggPSBzY3JpcHRQYXRoO1xuXG5cdC8vIE1haW5seSB1c2VkIGluIHRoZSBhc3luYyBjb2RlLCBidXQgcHV0IGhlcmUgdG8gYWxzbyBjYXRjaCBkdXBsaWNhdGUgZGVjbGFyZWQgY2xhc3NlcyBpbiBib3RoIGFzeW5jIGFuZCBzeW5jaHJvbm91cyBjYWxscy5cblx0dmFyIHNwbGl0X3NjcmlwdF9wYXRoID0gcmVhbFBhdGguc3BsaXQoICcvJyApO1xuXHR2YXIgaW1wb3J0X2ZpbGVfbmFtZSA9IHNwbGl0X3NjcmlwdF9wYXRoW3NwbGl0X3NjcmlwdF9wYXRoLmxlbmd0aCAtIDFdLnJlcGxhY2UoICcuanMnLCAnJyApO1xuXHQvL3ZhciBpbXBvcnRfcGF0aCA9IHJlYWxQYXRoLnJlcGxhY2UoJ3ZpZXdzLycsICcnKTtcblxuXHR2YXIgY2xhc3NfZXhpc3RzID0gZXZhbChcInR5cGVvZiBcIisgaW1wb3J0X2ZpbGVfbmFtZSArXCIgPT09ICdmdW5jdGlvbidcIik7XG5cdGlmICggY2xhc3NfZXhpc3RzICkge1xuXHRcdC8vIFRoaXMgbWVhbnMgY2xhc3MgYWxyZWFkeSBleGlzdHMgb24gdGhlIHdpbmRvdyBvYmplY3QsIHNvIGl0IG11c3QgaGF2ZSBiZWVuIGFscmVhZHkgbG9hZGVkLlxuXHRcdC8vIERFViBOT1RFOiBUaGlzIHNob3VsZCBOT1QgaGFwcGVuLiBJZiBpdCBoYXBwZW5zLCBpdCBtZWFucyBzY3JpcHQgaXMgYmVpbmcgbG9hZGVkIHR3aWNlLiBDaGVjayBtYW51YWwgbG9hZGluZyBjYWxscyBsaWtlIHJlcXVpcmVqcyBvciBXZWJwYWNrIE1lcmdlSW50b1NpbmdsZUZpbGVQbHVnaW4gcGx1Z2luXG5cdFx0Ly8gSW4gYWxsIGxpa2VseWhvb2QsIGl0IGlzIGxpc3RlZCBpbiB0aGUgY29uY2F0ZW5hdGlvbiBhcnJheSBmb3IgTWVyZ2VJbnRvU2luZ2xlRmlsZVBsdWdpbi4gQmVzdCB0byB0cnkgdG8gcmVtb3ZlIGl0IGZyb20gdGhlcmUsIGFzIGxvbmcgYXMgaXRzIGNvcnJlY3RseSBsb2FkZWQgb24gZGVtYW5kIGluIGFsbCByZWxldmFudCBwbGFjZXMuIFNlZSB3aGF0IGVsc2UgdXNlcyB0aGUgY2xhc3MgdG8gYmUgc3VyZS5cblx0XHRHbG9iYWwuc2VuZEFuYWx5dGljc0V2ZW50KCAnZXJyb3I6c2NyaXB0bG9hZDpkdXBsaWNhdGVfY2xhc3MnLCAnbG9hZCcsICdlcnJvcjpzY3JpcHRsb2FkOmR1cGxpY2F0ZTonKyBzY3JpcHRQYXRoICk7XG5cdFx0RGVidWcuRXJyb3IoICdEdXBsaWNhdGUgY2xhc3MgZGVjbGFyYXRpb246ICcrIGltcG9ydF9maWxlX25hbWUsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2xvYWRTY3JpcHQnLCAxICk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRpZiAoIEdsb2JhbC51cmxfb2Zmc2V0ICkge1xuXHRcdHJlYWxQYXRoID0gR2xvYmFsLmdldEJhc2VVUkwoIEdsb2JhbC51cmxfb2Zmc2V0ICsgcmVhbFBhdGggKTtcblx0fVxuXG5cdGlmICggYXN5bmMgKSB7XG5cdFx0RGVidWcuVGV4dCggJ0FTWU5DLUxPQURJTkc6ICcgKyBzY3JpcHRQYXRoLCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdsb2FkU2NyaXB0JywgMTAgKTtcblxuXHRcdHZhciBpbXBvcnRfcGF0aDtcblx0XHRpZiAoIHNjcmlwdFBhdGguaW5kZXhPZigndmlld3MnKSAhPT0gLTEgKXtcblx0XHRcdGltcG9ydF9wYXRoID0gc2NyaXB0UGF0aC5yZXBsYWNlKCd2aWV3cy8nLCAnJyk7IC8vIFRoaXMgaXMgdG8gZW5zdXJlIHRoZSB2YXJpYWJsZSBpbiB0aGUgZHluYW1pYyB3ZWJwYWNrIGltcG9ydCgpIGlzIGEgc2luZ2xlIHZhcmlhYmxlIHJhdGhlciB0aGFuIGEgZnVsbCBwYXRoLlxuXHRcdFx0aW1wb3J0KFxuXHRcdFx0XHQvKiB3ZWJwYWNrQ2h1bmtOYW1lOiBcIltyZXF1ZXN0XVwiICovXG5cdFx0XHRcdC8qIHdlYnBhY2tJbmNsdWRlOiAvXFwuanMkLyAqL1xuXHRcdFx0XHQvKiB3ZWJwYWNrRXhjbHVkZTogL3RyaWdnZXJQYXJzZXJFcnJvclxcLmpzJC8gKi9cblx0XHRcdFx0YEAvdmlld3MvJHtpbXBvcnRfcGF0aH1gXG5cdFx0XHQpLnRoZW4oKG1vZHVsZSkgPT4ge1xuXHRcdFx0XHRpZiAoIG1vZHVsZSAmJiBtb2R1bGVbaW1wb3J0X2ZpbGVfbmFtZV0gKSB7XG5cdFx0XHRcdFx0d2luZG93W2ltcG9ydF9maWxlX25hbWVdID0gbW9kdWxlW2ltcG9ydF9maWxlX25hbWVdOyAvLyBBZnRlciBodG1sMmpzIHRoaXMgbWF5IG5vdCBiZSBuZWVkZWQgYW55bW9yZS4gQnV0IGxlYXZlIGZvciBub3cgYXMgdGhpcyBhbGxvd3MgdGhlIGxlZ2FjeSBodG1sIGZpbGVzIHRvIHRyaWdnZXIgdGhlICduZXcgTXlWaWV3Q29udHJvbGxlcigpJyBjb2RlIGluIHRoZWlyIGh0bWwgZmlsZXMuXG5cblx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5sb2FkZWRTY3JpcHROYW1lc1tzY3JpcHRQYXRoXSA9IHRydWU7XG5cdFx0XHRcdFx0b25SZXN1bHQoKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpZiggaW1wb3J0X2ZpbGVfbmFtZSA9PT0gJ2RlYnVnUGFuZWxDb250cm9sbGVyJykge1xuXHRcdFx0XHRcdFx0Ly8gZGVidWdQYW5lbCBpcyBjb2RlZCBkaWZmZXJlbnQsIHdpdGggbm8gY2xhc3Nlcy9jb25zdHJ1Y3Rvciwgc28gdGhpcyBpcyBub3QgYSBmYWlsLlxuXHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEubG9hZGVkU2NyaXB0TmFtZXNbc2NyaXB0UGF0aF0gPSB0cnVlO1xuXHRcdFx0XHRcdFx0b25SZXN1bHQoKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Ly8gTG9hZGluZyBjbGFzcyBmYWlsZWQuXG5cdFx0XHRcdFx0XHQvLyBJZiB0aGVyZSBpcyBub3QgYW4gYXR0cmlidXRlIG1hdGNoaW5nIHRoZSBjbGFzcyBvbiB0aGUgbW9kdWxlIHJlc3VsdCwgdGhlbiB0aGlzIHN1Z2dlc3RzIGEgbWlzc2luZyBleHBvcnQgb24gdGhlIGNsYXNzLiBUaGVyZSB3aWxsIGFsc28gYmUgYSBkZWZhdWx0IGF0dHJpYnV0ZSB3aXRoIGFuIGVtcHR5IG9iamVjdCB0byBzaG93IG5vIGRlZmF1bHQgY2xhc3NlcyBleHBvcnRlZC5cblx0XHRcdFx0XHRcdERlYnVnLkVycm9yKCAnTG9hZGluZyB2aWV3IGNsYXNzIGZhaWxlZC4gUG90ZW50aWFsIG1pc3NpbmcgZXhwb3J0IGZvcjogJyArIGltcG9ydF9maWxlX25hbWUsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2xvYWRTY3JpcHQnLCAxICk7XG5cblx0XHRcdFx0XHRcdG9uUmVzdWx0KCk7IC8vIFRvIGFsbG93IGNhbGxiYWNrcyB0byB3b3JrIGZvciBub24tbW9kdWxlIHNjcmlwdHMgbGlrZSBkZWJ1Z1BhbmVsQ29udHJvbGxlci5cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gKS5jYXRjaCggR2xvYmFsLmltcG9ydEVycm9ySGFuZGxlciApO1xuXHRcdH0gZWxzZSBpZiAoIHNjcmlwdFBhdGguaW5kZXhPZignZ2xvYmFsL3dpZGdldHMnKSAhPT0gLTEgKSB7XG5cdFx0XHRpbXBvcnRfcGF0aCA9IHNjcmlwdFBhdGgucmVwbGFjZSgnZ2xvYmFsL3dpZGdldHMvJywgJycpOyAvLyBUaGlzIGlzIHRvIGVuc3VyZSB0aGUgdmFyaWFibGUgaW4gdGhlIGR5bmFtaWMgd2VicGFjayBpbXBvcnQoKSBpcyBhIHNpbmdsZSB2YXJpYWJsZSByYXRoZXIgdGhhbiBhIGZ1bGwgcGF0aC5cblx0XHRcdGltcG9ydChcblx0XHRcdFx0Lyogd2VicGFja0NodW5rTmFtZTogXCJbcmVxdWVzdF1cIiAqL1xuXHRcdFx0XHQvKiB3ZWJwYWNrSW5jbHVkZTogL1xcLmpzJC8gKi9cblx0XHRcdFx0YEAvZ2xvYmFsL3dpZGdldHMvJHtpbXBvcnRfcGF0aH1gXG5cdFx0XHQpLnRoZW4oKG1vZHVsZSkgPT4ge1xuXHRcdFx0XHRpZiggbW9kdWxlICYmIG1vZHVsZVtpbXBvcnRfZmlsZV9uYW1lXSApIHtcblx0XHRcdFx0XHR3aW5kb3dbaW1wb3J0X2ZpbGVfbmFtZV0gPSBtb2R1bGVbaW1wb3J0X2ZpbGVfbmFtZV07XG5cdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEubG9hZGVkU2NyaXB0TmFtZXNbc2NyaXB0UGF0aF0gPSB0cnVlO1xuXHRcdFx0XHRcdG9uUmVzdWx0KCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gTG9hZGluZyBjbGFzcyBmYWlsZWQuXG5cdFx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgbm90IGFuIGF0dHJpYnV0ZSBtYXRjaGluZyB0aGUgY2xhc3Mgb24gdGhlIG1vZHVsZSByZXN1bHQsIHRoZW4gdGhpcyBzdWdnZXN0cyBhIG1pc3NpbmcgZXhwb3J0IG9uIHRoZSBjbGFzcy4gVGhlcmUgd2lsbCBhbHNvIGJlIGEgZGVmYXVsdCBhdHRyaWJ1dGUgd2l0aCBhbiBlbXB0eSBvYmplY3QgdG8gc2hvdyBubyBkZWZhdWx0IGNsYXNzZXMgZXhwb3J0ZWQuXG5cdFx0XHRcdFx0Ly8gVGhpcyBjb3VsZCBhbHNvIGJlIGEgd2lkZ2V0IHRoYXQgaXMgaGlzdG9yaWNhbGx5IG1lYW50IHRvIGxvYWQgc3luY2hyb25vdXNseSB3aXRoIHRoZSBqUXVlcnkuYWpheCBjb2RlIGZ1cnRoZXIgZG93bi4gSWYgdGhpcyBpcyB0aGUgY2FzZSwgcmVmYWN0b3IgdGhlIGNhbGxiYWNrIHRvIGxvYWQgdGhlIHdpZGdldCBzeW5jcm9ub3VzbHkgaW5zdGVhZC5cblx0XHRcdFx0XHREZWJ1Zy5FcnJvciggJ0xvYWRpbmcgd2lkZ2V0IGNsYXNzIGZhaWxlZC4gUG90ZW50aWFsIG1pc3NpbmcgZXhwb3J0IGZvcjogJysgaW1wb3J0X2ZpbGVfbmFtZSwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnbG9hZFNjcmlwdCcsIDEgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9ICkuY2F0Y2goIEdsb2JhbC5pbXBvcnRFcnJvckhhbmRsZXIgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0RGVidWcuRXJyb3IoICdMb2FkaW5nIGNsYXNzIGZhaWxlZC4gVW5oYW5kbGVkIGZpbGUgdHlwZSBwYXRoIHJlcXVlc3Q6ICcrIHNjcmlwdFBhdGgsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2xvYWRTY3JpcHQnLCAxICk7XG5cdFx0fVxuXG5cdH0gZWxzZSB7XG5cdFx0dmFyIGNhbGxpbmdfc2NyaXB0ID0gJyc7XG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIudmlld0lkICkge1xuXHRcdFx0Y2FsbGluZ19zY3JpcHQgPSAnIGZyb20gJyArIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIudmlld0lkICsgJ1ZpZXdDb250cm9sbGVyJztcblx0XHR9XG5cdFx0RGVidWcuVGV4dCggJ1NZTkMtTE9BRElORzogJyArIHNjcmlwdFBhdGggKyBjYWxsaW5nX3NjcmlwdCApO1xuXG5cdFx0dmFyIGlkID0gc2NyaXB0UGF0aC5zcGxpdCggJy8nICk7XG5cdFx0dmFyIGlkID0gaWRbaWQubGVuZ3RoIC0gMV07XG5cdFx0aWQgPSBpZC5yZXBsYWNlKCAnLmpzJywgJycgKTtcblx0XHRpZiAoICF3aW5kb3cuYmFkU2NyaXB0cyApIHtcblx0XHRcdHdpbmRvdy5iYWRTY3JpcHRzID0gW107XG5cdFx0fVxuXHRcdHdpbmRvdy5iYWRTY3JpcHRzLnB1c2goIGlkICk7IC8vV2hlbiB0aGUgcGFnZSBpcyBkb25lIGxvYWRpbmcgcHVuY2ggXCJiYWRTY3JpcHRzIGludG8gdGhlIGNvbnNvbGUgdG8gc2VlIGEgbmljZSBhcnJheSBvZiBhbGwgdGhlIHNjcmlwdHMgdGhhdCB3ZXJlIG5vdCBsb2FkZWQgYXN5bmMuXG5cblx0XHQvKipcblx0XHQgKiB0aGlzIHNlZW1zIHRvIHdvcmssIGJ1dCBjYXVzZXMgdGhlIHNjcmlwdCBlcnJvIGF0IGxpbmUgMCBwcm9ibGVtLlxuXHRcdCAqIHRyeSB0byByZWZhY3RvciB0byBub3QgdXNlIGpxdWVyeS5hamF4XG5cdFx0ICovXG5cdFx0alF1ZXJ5LmFqYXgoIHtcblx0XHRcdGFzeW5jOiBmYWxzZSxcblx0XHRcdHR5cGU6ICdHRVQnLFxuXHRcdFx0dXJsOiByZWFsUGF0aCArICc/dj0nICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkLFxuXHRcdFx0Y3Jvc3NPcmlnaW46IGZhbHNlLFxuXHRcdFx0ZGF0YTogbnVsbCxcblx0XHRcdGNhY2hlOiB0cnVlLFxuXHRcdFx0c3VjY2VzczogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHN1Y2Nlc3NmbGFnID0gdHJ1ZTtcblx0XHRcdFx0aWYgKCBhc3luYyApIHtcblx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5sb2FkZWRTY3JpcHROYW1lc1tzY3JpcHRQYXRoXSA9IHRydWU7XG5cdFx0XHRcdFx0b25SZXN1bHQoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGVycm9yOiBmdW5jdGlvbigganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICkge1xuXHRcdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dOZXR3b3JrRXJyb3JBbGVydCgganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICk7XG5cdFx0XHR9LFxuXHRcdFx0ZGF0YVR5cGU6ICdzY3JpcHQnXG5cdFx0fSApO1xuXHR9XG5cblx0aWYgKCAhYXN5bmMgKSB7XG5cdFx0TG9jYWxDYWNoZURhdGEubG9hZGVkU2NyaXB0TmFtZXNbc2NyaXB0UGF0aF0gPSB0cnVlO1xuXHRcdHJldHVybiAoIHN1Y2Nlc3NmbGFnICk7XG5cdH1cblxufTtcblxuR2xvYmFsLmltcG9ydEVycm9ySGFuZGxlciA9IGZ1bmN0aW9uKCBlcnJvciApIHtcblx0aWYgKCBlcnJvci5uYW1lID09ICdDaHVua0xvYWRFcnJvcicgKSB7XG5cdFx0aWYgKCB3aW5kb3cuc2NyaXB0X2Vycm9yX3Nob3duID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR3aW5kb3cuc2NyaXB0X2Vycm9yX3Nob3duID0gMTtcblx0XHRcdC8vVGhlcmUgaXMgbm8gcHJldHR5IGVycm9yYm94IGF0IHRoaXMgdGltZS4gWW91IG1heSBvbmx5IGhhdmUgYmFzaWMgamF2YXNjcmlwdC5cblx0XHRcdGlmICggY29uZmlybSggJ1VuYWJsZSB0byBkb3dubG9hZCByZXF1aXJlZCBkYXRhLiBZb3VyIGludGVybmV0IGNvbm5lY3Rpb24gbWF5IGhhdmUgZmFpbGVkIHByZXNzIE9rIHRvIHJlbG9hZC4nICkgKSB7XG5cdFx0XHRcdC8vRm9yIHRlc3RpbmcsIHNvIHRoYXQgdGhlcmUncyB0aW1lIHRvIHR1cm4gaW50ZXJuZXQgYmFjayBvbiBhZnRlciBjb25maXJtIGlzIGNsaWNrZWQuXG5cdFx0XHRcdC8vd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7d2luZG93LmxvY2F0aW9uLnJlbG9hZCgpfSw1MDAwKTtcblxuXHRcdFx0XHQvL1RoaXMgY2FuIGFsc28gaGFwcGVuIGlmIHRoZSB1c2VyIG1hbnVhbGx5IG1vZGlmaWVzIHRoZSBVUkwgdG8gYmUgYSBib2d1cyBWaWV3SWQgKGllOiAjIW09aG9tZUFCQylcblx0XHRcdFx0Ly9TbyB0cnkgdG8gcmVkaXJlY3QgYmFjayB0byB0aGUgaG9tZSBwYWdlIGZpcnN0LCBvdGhlcndpc2UgdHJ5IHRvIGRvIGEgYnJvd3NlciByZWxvYWQuXG5cdFx0XHRcdGlmICggU2VydmljZUNhbGxlci5yb290X3VybCAmJiBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYmFzZV91cmwgKSB7XG5cdFx0XHRcdFx0R2xvYmFsLnNldFVSTFRvQnJvd3NlciggU2VydmljZUNhbGxlci5yb290X3VybCArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5iYXNlX3VybCApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cdFx0fVxuXHRcdGNvbnNvbGUuZGVidWcoIGVycm9yLm1lc3NhZ2UgKTtcblx0XHQvL1N0b3AgZXJyb3IgZnJvbSBidWJibGluZyB1cC5cblx0XHQvLyBkZWxldGUgZTsgLy8gY29tbWVudGVkIG91dCBmcm9tIG9sZCBjb2RlIGFzIHdlYnBhY2sgY29tcGxhaW5zIGFib3V0IGRlbGV0aW5nIGxvY2FsIHZhcmlhYmxlIGluIHN0cmljdCBtb2RlLlxuXG5cdH0gZWxzZSB7XG5cdFx0RGVidWcuRXJyb3IoICdFcnJvciBsb2FkaW5nIHNjcmlwdCBkdXJpbmcgaW1wb3J0KCk6ICcgKyBlcnJvciwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnaW1wb3J0RXJyb3JIYW5kbGVyJywgMSApO1xuXHRcdC8vIFRocm93IGdlbmVyYWwgZXJyb3I/XG5cdH1cbn07XG5cbkdsb2JhbC5nZXRSZWFsSW1hZ2VQYXRoID0gZnVuY3Rpb24oIHBhdGggKSB7XG5cblx0dmFyIHJlYWxQYXRoID0gJ3RoZW1lLycgKyBHbG9iYWwudGhlbWUgKyAnLycgKyBwYXRoO1xuXG5cdGlmICggR2xvYmFsLnVybF9vZmZzZXQgKSB7XG5cdFx0cmVhbFBhdGggPSBHbG9iYWwudXJsX29mZnNldCArIHJlYWxQYXRoO1xuXHR9XG5cblx0cmV0dXJuIHJlYWxQYXRoO1xufTtcblxuR2xvYmFsLmdldFJpYmJvbkljb25SZWFsUGF0aCA9IGZ1bmN0aW9uKCBpY29uICkge1xuXHR2YXIgcmVhbFBhdGggPSAndGhlbWUvJyArIEdsb2JhbC50aGVtZSArICcvY3NzL2dsb2JhbC93aWRnZXRzL3JpYmJvbi9pY29ucy8nICsgaWNvbjtcblxuXHRpZiAoIEdsb2JhbC51cmxfb2Zmc2V0ICkge1xuXHRcdHJlYWxQYXRoID0gR2xvYmFsLnVybF9vZmZzZXQgKyByZWFsUGF0aDtcblx0fVxuXG5cdHJldHVybiByZWFsUGF0aDtcbn07XG5cbkdsb2JhbC5sb2FkTGFuZ3VhZ2UgPSBmdW5jdGlvbiggbmFtZSApIHtcblx0dmFyIHN1Y2Nlc3NmbGFnID0gZmFsc2U7XG5cdHZhciBtZXNzYWdlX2lkID0gVFRVVUlELmdlbmVyYXRlVVVJRCgpO1xuXHRQcm9ncmVzc0Jhci5zaG93UHJvZ3Jlc3NCYXIoIG1lc3NhZ2VfaWQgKTtcblx0dmFyIHJlc19kYXRhID0ge307XG5cblx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRJMThuRGljKCkgKSB7XG5cdFx0UHJvZ3Jlc3NCYXIucmVtb3ZlUHJvZ3Jlc3NCYXIoIG1lc3NhZ2VfaWQgKTtcblx0XHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0STE4bkRpYygpO1xuXHR9XG5cdHZhciByZWFsUGF0aCA9ICcuLi9sb2NhbGUvJyArIG5hbWUgKyAnL0xDX01FU1NBR0VTL21lc3NhZ2VzLmpzb24nICsgJz92PScgKyBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYXBwbGljYXRpb25fYnVpbGQ7XG5cblx0aWYgKCBHbG9iYWwudXJsX29mZnNldCApIHtcblx0XHRyZWFsUGF0aCA9IEdsb2JhbC51cmxfb2Zmc2V0ICsgcmVhbFBhdGg7XG5cdH1cblxuXHRqUXVlcnkuYWpheCgge1xuXHRcdGFzeW5jOiBmYWxzZSxcblx0XHR0eXBlOiAnR0VUJyxcblx0XHR1cmw6IHJlYWxQYXRoLFxuXHRcdGRhdGE6IG51bGwsXG5cdFx0Y2FjaGU6IHRydWUsXG5cdFx0Y29udmVydGVyczoge1xuXHRcdFx0Ly9CZWNhdXNlIHRoaXMgaXMgYSBkYXRhVHlwZTogc2NyaXB0LCBhbmQganF1ZXJ5IHdpbGwgYmxpbmR5IHRyeSB0byBldmFsKCkgYW55IHJlc3VsdCByZXR1cm5lZCBieSB0aGUgc2VydmVyLCBpbmNsdWRpbmcgYSBIVE1MIDQwNCBlcnJvciBtZXNzYWdlLlxuXHRcdFx0Ly8gcmVzdWx0aW5nIGluXCIgVW5jYXVnaHQgU3ludGF4RXJyb3I6IFVuZXhwZWN0ZWQgdG9rZW4gPCBpbiAgbGluZSAxXCIgYmVpbmcgdHJpZ2dlcmVkLlxuXHRcdFx0Ly8gSW5zdGVhZCBqdXN0IHJldHVybiB0aGUgcmF3IHJlc3VsdCBhbmQgZXZhbCgpIGl0IGluIHRoZSBzdWNjZXNzIGZ1bmN0aW9uIG91cnNlbHZlcyBpbnN0ZWFkLlxuXHRcdFx0J3RleHQgc2NyaXB0JzogZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0XHRcdHJldHVybiB0ZXh0O1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0c3VjY2VzczogZnVuY3Rpb24oIHJlc3VsdCApIHtcblx0XHRcdHN1Y2Nlc3NmbGFnID0gdHJ1ZTtcblx0XHRcdGpRdWVyeS5nbG9iYWxFdmFsKCByZXN1bHQgKTtcblx0XHR9LFxuXHRcdGVycm9yOiBmdW5jdGlvbigganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICkge1xuXHRcdFx0Ly9VbmFibGUgdG8gbG9hZCBvciBwYXJzZSBpMThuIGRpY3Rpb25hcnkuIENvdWxkIGJlIGR1ZSB0byBhIDQwNCBlcnJvcj9cblx0XHRcdERlYnVnLlRleHQoICdVbmFibGUgdG8gbG9hZCBMb2NhbGU6ICcgKyBlcnJvclRocm93biwgJ0dsb2JhbC5qcycsICcnLCAnbG9hZExhbmd1YWdlJywgMTAgKTtcblx0XHRcdHN1Y2Nlc3NmbGFnID0gZmFsc2U7XG5cdFx0fSxcblx0XHRkYXRhVHlwZTogJ3NjcmlwdCdcblx0fSApO1xuXG5cdFByb2dyZXNzQmFyLnJlbW92ZVByb2dyZXNzQmFyKCBtZXNzYWdlX2lkICk7XG5cblx0aWYgKCBzdWNjZXNzZmxhZyApIHtcblx0XHRMb2NhbENhY2hlRGF0YS5zZXRJMThuRGljKCBpMThuX2RpY3Rpb25hcnkgKTtcblx0fSBlbHNlIHtcblx0XHRMb2NhbENhY2hlRGF0YS5zZXRJMThuRGljKCB7fSApO1xuXHR9XG5cblx0cmV0dXJuIHN1Y2Nlc3NmbGFnO1xufTtcblxuR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uID0gZnVuY3Rpb24oKSB7XG5cdHZhciBjdXJyZW50X2NvbXBhbnlfZGF0YSA9IExvY2FsQ2FjaGVEYXRhLmdldEN1cnJlbnRDb21wYW55KCk7XG5cblx0aWYgKCBjdXJyZW50X2NvbXBhbnlfZGF0YSAmJiBjdXJyZW50X2NvbXBhbnlfZGF0YS5wcm9kdWN0X2VkaXRpb25faWQgKSB7XG5cdFx0cmV0dXJuIGN1cnJlbnRfY29tcGFueV9kYXRhLnByb2R1Y3RfZWRpdGlvbl9pZDtcblx0fVxuXG5cdHJldHVybiAxMDsgLy9Db21tdW5pdHlcbn07XG5cbkdsb2JhbC5zZXRVUkxUb0Jyb3dzZXIgPSBmdW5jdGlvbiggbmV3X3VybCApIHtcblx0aWYgKCBuZXdfdXJsICE9IHdpbmRvdy5sb2NhdGlvbi5ocmVmICkge1xuXHRcdERlYnVnLlRleHQoICdDaGFuZ2luZyBVUkwgdG86ICcgKyBuZXdfdXJsLCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdzZXRVUkxUb0Jyb3dzZXInLCA5ICk7XG5cdFx0d2luZG93LmxvY2F0aW9uID0gbmV3X3VybDtcblx0fVxufTtcblxuR2xvYmFsLmNsb25lID0gZnVuY3Rpb24oIG9iaiApIHtcblx0cmV0dXJuIGpRdWVyeS5leHRlbmQoIHRydWUsIHt9LCBvYmogKTsgLy8gdHJ1ZSBtZWFucyBkZWVwIGNsb25lLCBvbWl0IGZvciBzaGFsbG93LCBmYWxzZSBpcyBub3QgYW4gb3B0aW9uXG59O1xuXG5HbG9iYWwuZ2V0Rmlyc3RLZXlGcm9tT2JqZWN0ID0gZnVuY3Rpb24oIG9iaiApIHtcblx0Zm9yICggdmFyIGtleSBpbiBvYmogKSB7XG5cblx0XHRpZiAoIG9iai5oYXNPd25Qcm9wZXJ0eSgga2V5ICkgKSB7XG5cdFx0XHRyZXR1cm4ga2V5O1xuXHRcdH1cblxuXHR9XG59O1xuXG5HbG9iYWwuZ2V0RnVuY05hbWUgPSBmdW5jdGlvbiggX2NhbGxlZSApIHtcblx0dmFyIF90ZXh0ID0gX2NhbGxlZS50b1N0cmluZygpO1xuXHR2YXIgX3NjcmlwdEFyciA9IGRvY3VtZW50LnNjcmlwdHM7XG5cdGZvciAoIHZhciBpID0gMDsgaSA8IF9zY3JpcHRBcnIubGVuZ3RoOyBpKysgKSB7XG5cdFx0dmFyIF9zdGFydCA9IF9zY3JpcHRBcnJbaV0udGV4dC5pbmRleE9mKCBfdGV4dCApO1xuXHRcdGlmICggX3N0YXJ0ICE9PSAtMSApIHtcblx0XHRcdGlmICggL15mdW5jdGlvblxccypcXCguKlxcKS4qXFxyXFxuLy50ZXN0KCBfdGV4dCApICkge1xuXHRcdFx0XHR2YXIgX3RlbXBBcnIgPSBfc2NyaXB0QXJyW2ldLnRleHQuc3Vic3RyKCAwLCBfc3RhcnQgKS5zcGxpdCggJ1xcclxcbicgKTtcblx0XHRcdFx0cmV0dXJuIF90ZW1wQXJyWyggX3RlbXBBcnIubGVuZ3RoIC0gMSApXS5yZXBsYWNlKCAvKHZhcil8KFxccyopL2csICcnICkucmVwbGFjZSggLz0vZywgJycgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiBfdGV4dC5tYXRjaCggL15mdW5jdGlvblxccyooW15cXChdKykuKlxcclxcbi8gKVsxXTtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbkdsb2JhbC5jb25jYXRBcnJheXNVbmlxdWVXaXRoU29ydCA9IGZ1bmN0aW9uKCB0aGlzQXJyYXksIG90aGVyQXJyYXkgKSB7XG5cdHZhciBuZXdBcnJheSA9IHRoaXNBcnJheS5jb25jYXQoIG90aGVyQXJyYXkgKS5zb3J0KCBmdW5jdGlvbiggYSwgYiApIHtcblx0XHRyZXR1cm4gYSA+IGIgPyAxIDogYSA8IGIgPyAtMSA6IDA7XG5cdH0gKTtcblxuXHRyZXR1cm4gbmV3QXJyYXkuZmlsdGVyKCBmdW5jdGlvbiggaXRlbSwgaW5kZXggKSB7XG5cdFx0cmV0dXJuIG5ld0FycmF5LmluZGV4T2YoIGl0ZW0gKSA9PT0gaW5kZXg7XG5cdH0gKTtcbn07XG5cbkdsb2JhbC5hZGRDc3MgPSBmdW5jdGlvbiggcGF0aCwgY2FsbGJhY2sgKSB7XG5cdGlmICggTG9jYWxDYWNoZURhdGEubG9hZGVkU2NyaXB0TmFtZXNbcGF0aF0gKSB7XG5cdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdExvY2FsQ2FjaGVEYXRhLmxvYWRlZFNjcmlwdE5hbWVzW3BhdGhdID0gdHJ1ZTtcblx0dmFyIHJlYWxQYXRoID0gJ3RoZW1lLycgKyBHbG9iYWwudGhlbWUgKyAnL2Nzcy8nICsgcGF0aDtcblx0aWYgKCBHbG9iYWwudXJsX29mZnNldCApIHtcblx0XHRyZWFsUGF0aCA9IEdsb2JhbC51cmxfb2Zmc2V0ICsgcmVhbFBhdGg7XG5cdH1cblx0cmVhbFBhdGggPSByZWFsUGF0aCArICc/dj0nICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkO1xuXHRHbG9iYWwubG9hZFN0eWxlU2hlZXQoIHJlYWxQYXRoLCBjYWxsYmFjayApO1xufTtcblxuLy9KUyB0aGluayAwIGlzIGZhbHNlLCBzbyB1c2UgdGhpcyB0byBnZXQgMCBjb3JyZWN0bHkuXG5HbG9iYWwuaXNGYWxzZU9yTnVsbCA9IGZ1bmN0aW9uKCBvYmplY3QgKSB7XG5cblx0aWYgKCBvYmplY3QgPT09IGZhbHNlIHx8IG9iamVjdCA9PT0gbnVsbCB8fCBvYmplY3QgPT09IDAgfHwgb2JqZWN0ID09PSAnMCcgfHwgb2JqZWN0ID09IFRUVVVJRC56ZXJvX2lkICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG59O1xuXG5HbG9iYWwuaXNTZXQgPSBmdW5jdGlvbiggb2JqZWN0ICkge1xuXG5cdGlmICggXy5pc1VuZGVmaW5lZCggb2JqZWN0ICkgfHwgXy5pc051bGwoIG9iamVjdCApICkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG59O1xuXG5HbG9iYWwuZ2V0SWNvblBhdGhCeUNvbnRleHROYW1lID0gZnVuY3Rpb24oIGlkICkge1xuXG5cdHN3aXRjaCAoIGlkICkge1xuXHRcdGNhc2UgJ2FkZCc6XG5cdFx0XHRyZXR1cm4gR2xvYmFsLmdldFJlYWxJbWFnZVBhdGgoICdjc3MvZ2xvYmFsL3dpZGdldHMvcmliYm9uL2ljb25zL2NvcHktMzV4MzUucG5nJyApO1xuXHR9XG59O1xuXG5HbG9iYWwuaXNFbXB0eSA9IGZ1bmN0aW9uKCBvYmogKSB7XG5cblx0Ly8gbnVsbCBhbmQgdW5kZWZpbmVkIGFyZSBcImVtcHR5XCJcblx0aWYgKCBvYmogPT09IG51bGwgKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvLyBBc3N1bWUgaWYgaXQgaGFzIGEgbGVuZ3RoIHByb3BlcnR5IHdpdGggYSBub24temVybyB2YWx1ZVxuXHQvLyB0aGF0IHRoYXQgcHJvcGVydHkgaXMgY29ycmVjdC5cblx0aWYgKCBvYmoubGVuZ3RoID4gMCApIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0aWYgKCBvYmoubGVuZ3RoID09PSAwICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0Ly8gT3RoZXJ3aXNlLCBkb2VzIGl0IGhhdmUgYW55IHByb3BlcnRpZXMgb2YgaXRzIG93bj9cblx0Ly8gTm90ZSB0aGF0IHRoaXMgZG9lc24ndCBoYW5kbGVcblx0Ly8gdG9TdHJpbmcgYW5kIHZhbHVlT2YgZW51bWVyYXRpb24gYnVncyBpbiBJRSA8IDlcblx0Zm9yICggdmFyIGtleSBpbiBvYmogKSB7XG5cdFx0aWYgKCBoYXNPd25Qcm9wZXJ0eS5jYWxsKCBvYmosIGtleSApICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xuXG59O1xuXG5HbG9iYWwuY29udmVydENvbHVtbnNUb2pHcmlkRm9ybWF0ID0gZnVuY3Rpb24oIGNvbHVtbnMsIGxheW91dF9uYW1lLCBzZXRXaWR0aENhbGxCYWNrICkge1xuXHR2YXIgY29sdW1uX2luZm9fYXJyYXkgPSBbXTtcblx0dmFyIGxlbiA9IGNvbHVtbnMubGVuZ3RoO1xuXG5cdHZhciB0b3RhbF93aWR0aCA9IDA7XG5cdGZvciAoIHZhciBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdHZhciB2aWV3X2NvbHVtbl9kYXRhID0gY29sdW1uc1tpXTtcblx0XHR2YXIgY29sdW1uX2luZm87XG5cblx0XHR2YXIgdGV4dF93aWR0aCA9IEdsb2JhbC5jYWxjdWxhdGVUZXh0V2lkdGgoIHZpZXdfY29sdW1uX2RhdGEubGFiZWwgKTtcblxuXHRcdHRvdGFsX3dpZHRoID0gdG90YWxfd2lkdGggKyB0ZXh0X3dpZHRoO1xuXG5cdFx0aWYgKCB2aWV3X2NvbHVtbl9kYXRhLmxhYmVsID09PSAnJyApIHtcblx0XHRcdGNvbHVtbl9pbmZvID0ge1xuXHRcdFx0XHRuYW1lOiB2aWV3X2NvbHVtbl9kYXRhLnZhbHVlLFxuXHRcdFx0XHRpbmRleDogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0bGFiZWw6IHZpZXdfY29sdW1uX2RhdGEubGFiZWwsXG5cdFx0XHRcdGtleTogdHJ1ZSxcblx0XHRcdFx0d2lkdGg6IDEwMCxcblx0XHRcdFx0c29ydGFibGU6IGZhbHNlLFxuXHRcdFx0XHRoaWRkZW46IHRydWUsXG5cdFx0XHRcdHRpdGxlOiBmYWxzZVxuXHRcdFx0fTtcblx0XHR9IGVsc2UgaWYgKCBsYXlvdXRfbmFtZSA9PT0gJ2dsb2JhbF9zb3J0X2NvbHVtbnMnICkge1xuXG5cdFx0XHRpZiAoIHZpZXdfY29sdW1uX2RhdGEudmFsdWUgPT09ICdzb3J0JyApIHtcblx0XHRcdFx0Y29sdW1uX2luZm8gPSB7XG5cdFx0XHRcdFx0bmFtZTogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0XHRpbmRleDogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0XHRsYWJlbDogdmlld19jb2x1bW5fZGF0YS5sYWJlbCxcblx0XHRcdFx0XHR3aWR0aDogMTAwLFxuXHRcdFx0XHRcdHNvcnRhYmxlOiBmYWxzZSxcblx0XHRcdFx0XHRmb3JtYXR0ZXI6ICdzZWxlY3QnLFxuXHRcdFx0XHRcdGVkaXRhYmxlOiB0cnVlLFxuXHRcdFx0XHRcdHRpdGxlOiBmYWxzZSxcblx0XHRcdFx0XHRlZGl0dHlwZTogJ3NlbGVjdCcsXG5cdFx0XHRcdFx0ZWRpdG9wdGlvbnM6IHsgdmFsdWU6ICdhc2M6QVNDO2Rlc2M6REVTQycgfVxuXHRcdFx0XHR9O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29sdW1uX2luZm8gPSB7XG5cdFx0XHRcdFx0bmFtZTogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0XHRpbmRleDogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0XHRsYWJlbDogdmlld19jb2x1bW5fZGF0YS5sYWJlbCxcblx0XHRcdFx0XHR3aWR0aDogMTAwLFxuXHRcdFx0XHRcdHNvcnRhYmxlOiBmYWxzZSxcblx0XHRcdFx0XHR0aXRsZTogZmFsc2Vcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb2x1bW5faW5mbyA9IHtcblx0XHRcdFx0bmFtZTogdmlld19jb2x1bW5fZGF0YS52YWx1ZSxcblx0XHRcdFx0aW5kZXg6IHZpZXdfY29sdW1uX2RhdGEudmFsdWUsXG5cdFx0XHRcdGxhYmVsOiB2aWV3X2NvbHVtbl9kYXRhLmxhYmVsLFxuXHRcdFx0XHR3aWR0aDogMTAwLFxuXHRcdFx0XHRzb3J0YWJsZTogZmFsc2UsXG5cdFx0XHRcdHRpdGxlOiBmYWxzZVxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRjb2x1bW5faW5mb19hcnJheS5wdXNoKCBjb2x1bW5faW5mbyApO1xuXHR9XG5cblx0aWYgKCBzZXRXaWR0aENhbGxCYWNrICkge1xuXHRcdHNldFdpZHRoQ2FsbEJhY2soIHRvdGFsX3dpZHRoICk7XG5cdH1cblxuXHRyZXR1cm4gY29sdW1uX2luZm9fYXJyYXk7XG59O1xuLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUgPSBmdW5jdGlvbiggd2lkZ2V0TmFtZSwgcmF3X3RleHQgKSB7XG5cdHZhciBpbnB1dCA9IGZhbHNlO1xuXHR2YXIgd2lkZ2V0X3BhdGggPSBmYWxzZTtcblx0dmFyIHdpZGdldF9jb25zdHJ1Y3RvciA9IGZhbHNlO1xuXHR2YXIgcmF3X3RleHQgPSBmYWxzZTtcblx0c3dpdGNoICggd2lkZ2V0TmFtZSApIHtcblx0XHRjYXNlIEZvcm1JdGVtVHlwZS5DT0xPUl9QSUNLRVI6XG5cdFx0XHRpbnB1dCA9ICQuZm4uVENvbG9yUGlja2VyLmh0bWxfdGVtcGxhdGU7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIEZvcm1JdGVtVHlwZS5GT1JNVUxBX0JVSUxERVI6XG5cdFx0XHRpbnB1dCA9ICQuZm4uRm9ybXVsYUJ1aWxkZXIuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLkFXRVNPTUVfQk9YOlxuXHRcdFx0aW5wdXQgPSAkLmZuLkFDb21ib0JveC5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuQVdFU09NRV9EUk9QRE9XTjpcblx0XHRcdGlucHV0ID0gJC5mbi5BRHJvcERvd24uaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlRFWFRfSU5QVVQ6XG5cdFx0XHRpbnB1dCA9ICQuZm4uVFRleHRJbnB1dC5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuUEFTU1dPUkRfSU5QVVQ6XG5cdFx0XHRpbnB1dCA9ICQuZm4uVFBhc3N3b3JkSW5wdXQuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlRFWFQ6XG5cdFx0XHRpbnB1dCA9ICQuZm4uVFRleHQuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLkNIRUNLQk9YOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlRDaGVja2JveC5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuQ09NQk9fQk9YOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlRDb21ib0JveC5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuTElTVDogLy9Eb2VzIG5vdCBzZWVtIHRvIGJlIHVzZWQgYW55d2hlcmUuXG5cdFx0XHRpbnB1dCA9ICQuZm4uVExpc3QuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlRBR19JTlBVVDpcblx0XHRcdGlucHV0ID0gJC5mbi5UVGFnSW5wdXQuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLkRBVEVfUElDS0VSOlxuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlJBTkdFX1BJQ0tFUjpcblx0XHRcdGlucHV0ID0gJC5mbi5URGF0ZVBpY2tlci5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuVElNRV9QSUNLRVI6XG5cdFx0XHRpbnB1dCA9ICQuZm4uVFRpbWVQaWNrZXIuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlRFWFRfQVJFQTpcblx0XHRcdGlucHV0ID0gJC5mbi5UVGV4dEFyZWEuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLlRJTllNQ0VfVEVYVF9BUkVBOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlRUZXh0QXJlYS50aW55bWNlX2h0bWxfdGVtcGxhdGU7XG5cdFx0XHRyYXdfdGV4dCA9IHRydWU7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIEZvcm1JdGVtVHlwZS5TRVBBUkFURURfQk9YOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlNlcGFyYXRlZEJveC5odG1sX3RlbXBsYXRlO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuSU1BR0VfQlJPV1NFUjpcblx0XHRcdGlucHV0ID0gJC5mbi5USW1hZ2VCcm93c2VyLmh0bWxfdGVtcGxhdGU7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIEZvcm1JdGVtVHlwZS5GSUxFX0JST1dTRVI6IC8vVGhlcmUgaXMgbm8gZmlsZSBicm93c2VyIEpTIGZpbGUgZm9yIHRoaXMgd2lkZ2V0LlxuXHRcdFx0aW5wdXQgPSBgPGRpdiBjbGFzcz1cImZpbGUtYnJvd3NlclwiPlxuXHRcdFx0XHRcdFx0PGZvcm0gZW5jdHlwZT1cIm11bHRpcGFydC9mb3JtLWRhdGFcIiBjbGFzcz1cImJyb3dzZXItZm9ybVwiPlxuXHRcdFx0XHRcdFx0XHQ8aW5wdXQgbmFtZT1cImZpbGVkYXRhXCIgY2xhc3M9XCJicm93c2VyXCIgdHlwZT1cImZpbGVcIi8+XG5cdFx0XHRcdFx0XHQ8L2Zvcm0+XG5cdFx0XHRcdFx0PC9kaXY+YDtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLklNQUdFX0FWRF9CUk9XU0VSOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlRJbWFnZUFkdkJyb3dzZXIuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdHdpZGdldF9jb25zdHJ1Y3RvciA9ICdUSW1hZ2VBZHZCcm93c2VyJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLkNBTUVSQV9CUk9XU0VSOlxuXHRcdFx0aW5wdXQgPSAkLmZuLkNhbWVyYUJyb3dzZXIuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLklNQUdFX0NVVDpcblx0XHRcdGlucHV0ID0gJC5mbi5USW1hZ2VDdXRBcmVhLmh0bWxfdGVtcGxhdGU7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIEZvcm1JdGVtVHlwZS5JTUFHRTpcblx0XHRcdGlucHV0ID0gJzxpbWcgY2xhc3M9XFwndC1pbWFnZVxcJz4nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBGb3JtSXRlbVR5cGUuSU5TSURFX0VESVRPUjpcblx0XHRcdGlucHV0ID0gJC5mbi5JbnNpZGVFZGl0b3IuaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgV2lkZ2V0TmFtZXNEaWMuUEFHSU5HOlxuXHRcdFx0Ly8gd2lkZ2V0X3BhdGggPSAnZ2xvYmFsL3dpZGdldHMvcGFnaW5nL1BhZ2luZy5odG1sJzsgLy8gVE9ETzogIzMwMjM6IERlbGV0ZSB0aGlzIGxpbmUgb25jZSBhbGwgd2lkZ2V0IGh0bWwgY29udmVydGVkIGFuZCBubyBsb25nZXIgbmVlZCB0aGlzIHF1aWNrIHJlZmVyZW5jZSBmb3IgdGhlIG9sZCBmb3JtYXQuXG5cdFx0XHRpbnB1dCA9ICQuZm4uUGFnaW5nMi5odG1sLnBhZ2luZztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgV2lkZ2V0TmFtZXNEaWMuUEFHSU5HXzI6XG5cdFx0XHQvLyB3aWRnZXRfcGF0aCA9ICdnbG9iYWwvd2lkZ2V0cy9wYWdpbmcvUGFnaW5nMi5odG1sJzsgLy8gVE9ETzogIzMwMjM6IERlbGV0ZSB0aGlzIGxpbmUgb25jZSBhbGwgd2lkZ2V0IGh0bWwgY29udmVydGVkIGFuZCBubyBsb25nZXIgbmVlZCB0aGlzIHF1aWNrIHJlZmVyZW5jZSBmb3IgdGhlIG9sZCBmb3JtYXQuXG5cdFx0XHRpbnB1dCA9ICQuZm4uUGFnaW5nMi5odG1sLnBhZ2luZzI7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFdpZGdldE5hbWVzRGljLkVSUk9SX1RPT0xUSVA6XG5cdFx0XHRpbnB1dCA9ICQuZm4uRXJyb3JUaXBCb3guaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgRm9ybUl0ZW1UeXBlLkZFRURCQUNLX0JPWDpcblx0XHRcdGlucHV0ID0gJC5mbi5URmVlZGJhY2suaHRtbF90ZW1wbGF0ZTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgV2lkZ2V0TmFtZXNEaWMuRURJVF9WSUVXX0ZPUk1fSVRFTTogLy9UaGVyZSBpcyBubyBmaWxlIGJyb3dzZXIgSlMgZmlsZSBmb3IgdGhpcyB3aWRnZXQuXG5cdFx0XHRpbnB1dCA9IGBcblx0XHRcdDxkaXYgY2xhc3M9XCJlZGl0LXZpZXctZm9ybS1pdGVtLWRpdlwiPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwiZWRpdC12aWV3LWZvcm0taXRlbS1sYWJlbC1kaXZcIj48c3BhbiBjbGFzcz1cImVkaXQtdmlldy1mb3JtLWl0ZW0tbGFiZWxcIj48L3NwYW4+PC9kaXY+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJlZGl0LXZpZXctZm9ybS1pdGVtLWlucHV0LWRpdlwiPjwvZGl2PlxuXHRcdFx0PC9kaXY+YDtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgV2lkZ2V0TmFtZXNEaWMuRURJVF9WSUVXX1NVQl9GT1JNX0lURU06IC8vVGhlcmUgaXMgbm8gZmlsZSBicm93c2VyIEpTIGZpbGUgZm9yIHRoaXMgd2lkZ2V0LlxuXHRcdFx0aW5wdXQgPSBgXG5cdFx0XHQ8ZGl2IGNsYXNzPVwiZWRpdC12aWV3LWZvcm0taXRlbS1kaXZcIj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cImVkaXQtdmlldy1mb3JtLWl0ZW0tc3ViLWxhYmVsLWRpdlwiPjxzcGFuIGNsYXNzPVwiZWRpdC12aWV3LWZvcm0taXRlbS1sYWJlbFwiPjwvc3Bhbj48L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cImVkaXQtdmlldy1mb3JtLWl0ZW0taW5wdXQtZGl2XCI+PC9kaXY+XG5cdFx0XHQ8L2Rpdj5gO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBXaWRnZXROYW1lc0RpYy5OT19SRVNVTFRfQk9YOlxuXHRcdFx0aW5wdXQgPSAkLmZuLk5vUmVzdWx0Qm94Lmh0bWxfdGVtcGxhdGU7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFdpZGdldE5hbWVzRGljLlZJRVdfTUlOX1RBQjpcblx0XHRcdGlucHV0ID0gJC5mbi5WaWV3TWluVGFiQmFyLmh0bWwudGFiO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBXaWRnZXROYW1lc0RpYy5WSUVXX01JTl9UQUJfQkFSOlxuXHRcdFx0aW5wdXQgPSAkLmZuLlZpZXdNaW5UYWJCYXIuaHRtbC50YWJfYmFyO1xuXHRcdFx0YnJlYWs7XG5cdH1cblxuXHRpZiAoIHdpZGdldF9wYXRoICE9IGZhbHNlICkge1xuXHRcdGlucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXQoIHdpZGdldF9wYXRoICk7XG5cdH1cblxuXHRpZiAoIGlucHV0ICYmIHJhd190ZXh0ID09IHRydWUgKSB7XG5cdFx0cmV0dXJuIGlucHV0O1xuXHR9IGVsc2Uge1xuXHRcdC8vIzI1NzEgLSBFcnJvcjogVW5hYmxlIHRvIGdldCBwcm9wZXJ0eSAnaW5kZXhPZicgb2YgdW5kZWZpbmVkIG9yIG51bGwgcmVmZXJlbmNlXG5cdFx0aWYgKCBpbnB1dCAmJiBpbnB1dC5pbmRleE9mKCAnPCcgKSAhPSAtMSApIHtcblx0XHRcdGlmICggIXJhd190ZXh0ICkge1xuXHRcdFx0XHRpbnB1dCA9ICQoIGlucHV0ICk7XG5cblx0XHRcdFx0aWYgKCB3aWRnZXRfY29uc3RydWN0b3IgJiYgIWlucHV0W3dpZGdldF9jb25zdHJ1Y3Rvcl0gKSB7XG5cdFx0XHRcdFx0dmFyIGVycm9yX3N0cmluZyA9ICQuaTE4bi5fKCAnQ2xhc3MgY291bGQgbm90IGJlIGZvdW5kIGZvcicgKSArICc6ICcgKyB3aWRnZXROYW1lICsgJy4gJyArICQuaTE4bi5fKCAnQ2hlY2sgdGhhdCBjbGFzcyBpcyBwcm9wZXJseSByZXF1aXJlZC4nICk7XG5cdFx0XHRcdFx0dGhyb3coIG5ldyBFcnJvciggZXJyb3Jfc3RyaW5nICkgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvL1NlZSBjb21tZW50IGluIEdsb2JhbC5sb2FkV2lkZ2V0KCkgcmVnYXJkaW5nIHJldHVybiBudWxsIHJldHVybiB2YWx1ZXMuXG5cdFx0XHR2YXIgZXJyb3Jfc3RyaW5nID0gJC5pMThuLl8oICdOZXR3b3JrIGVycm9yLCBmYWlsZWQgdG8gbG9hZCcgKSArICc6ICcgKyB3aWRnZXROYW1lICsgJyAnICsgJC5pMThuLl8oICdSZXN1bHQnICkgKyAnOiBcIicgKyBpbnB1dCArICdcIic7XG5cdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dOZXR3b3JrRXJyb3JBbGVydCggeyBzdGF0dXM6IDk5OSB9LCBlcnJvcl9zdHJpbmcsIG51bGwgKTsgLy9TaG93IHRoZSB1c2VyIGFuIGVycm9yIHBvcG91cC5cblx0XHRcdHRocm93KCBuZXcgRXJyb3IoIGVycm9yX3N0cmluZyApICk7IC8vSGFsdCBleGVjdXRpb24gYW5kIGVuc3VyZSB0aGF0IHRoZSBlbWFpbCBoYXMgYSBnb29kIGVycm9yIG1lc3NhZ2UgYmVjYXVzZSBvZiBmYWlsdXJlIG9mIHdlYiBzZXJ2ZXIgdG8gcHJvdmlkZSB0aGUgcmVxdWVzdGVkIGZpbGUuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGlucHV0O1xuXHR9XG59O1xuXG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5HbG9iYWwubG9hZFdpZGdldCA9IGZ1bmN0aW9uKCB1cmwgKSB7XG5cdGlmICggTG9jYWxDYWNoZURhdGEubG9hZGVkV2lkZ2V0Q2FjaGVbdXJsXSApIHtcblx0XHRyZXR1cm4gKCBMb2NhbENhY2hlRGF0YS5sb2FkZWRXaWRnZXRDYWNoZVt1cmxdICk7XG5cdH1cblxuXHR2YXIgcmVhbFBhdGggPSB1cmwgKyAnP3Y9JyArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5hcHBsaWNhdGlvbl9idWlsZDtcblxuXHRpZiAoIEdsb2JhbC51cmxfb2Zmc2V0ICkge1xuXHRcdHJlYWxQYXRoID0gR2xvYmFsLnVybF9vZmZzZXQgKyByZWFsUGF0aDtcblx0fVxuXG5cdHZhciBtZXNzYWdlX2lkID0gVFRVVUlELmdlbmVyYXRlVVVJRCgpO1xuXHRQcm9ncmVzc0Jhci5zaG93UHJvZ3Jlc3NCYXIoIG1lc3NhZ2VfaWQgKTtcblx0dmFyIHN1Y2Nlc3NmbGFnID0gZmFsc2U7XG5cdHZhciByZXNwb25zZURhdGEgPSAkLmFqYXgoIHtcblx0XHRhc3luYzogZmFsc2UsXG5cdFx0dHlwZTogJ0dFVCcsXG5cdFx0dXJsOiByZWFsUGF0aCxcblx0XHRkYXRhOiBudWxsLFxuXHRcdGNhY2hlOiB0cnVlLFxuXHRcdHN1Y2Nlc3M6IGZ1bmN0aW9uKCkge1xuXHRcdFx0c3VjY2Vzc2ZsYWcgPSB0cnVlO1xuXHRcdH0sXG5cdFx0ZXJyb3I6IGZ1bmN0aW9uKCBqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24gKSB7XG5cdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dOZXR3b3JrRXJyb3JBbGVydCgganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICk7XG5cdFx0fVxuXHR9ICk7XG5cblx0UHJvZ3Jlc3NCYXIucmVtb3ZlUHJvZ3Jlc3NCYXIoIG1lc3NhZ2VfaWQgKTtcblx0Ly9FcnJvcjogVW5jYXVnaHQgUmVmZXJlbmNlRXJyb3I6IHJlc3BvbnNlVGV4dCBpcyBub3QgZGVmaW5lZCBpbiBpbnRlcmZhY2UvaHRtbDUvZ2xvYmFsL0dsb2JhbC5qcz92PTkuMC4yLTIwMTUxMTA2LTA5MjE0NyBsaW5lIDE3NDdcblx0Ly8gIFVwb24gZnVydGhlciBpbnZlc3RpZ2F0aW9uIChJUkMgZGlzY3Vzc2lvbnMgb24gI2pRdWVyeSkgaXQgd2FzIHN1Z2dlc3RlZCB0byBzdG9wIHVzaW5nICdhc3luYzogZmFsc2UnIGFzIHRoYXQgY291bGQgYmUgd2hhdHMgY2F1c2luZyBhIG51bGwgcmV0dXJuIHZhbHVlIHdoZW4gd2UgYXJlIGV4cGVjdGluZyBhIGpxWEhSIG9iamVjdC5cblx0Ly8gIFNpbmNlIHRoZSB1bHRpbWF0ZSBnb2FsIGlzIHRvIHJlZmFjdG9yIHRoaW5ncyBzbyAuaHRtbCBpcyBlbWJlZGRlZCBpbiB0aGUgLmpzIGZpbGVzIGFueXdheXMsIG1heSBhcyB3ZWxsIGp1c3Qgd2FpdCBmb3IgdGhhdC5cblx0aWYgKCAhcmVzcG9uc2VEYXRhICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9IGVsc2Uge1xuXHRcdExvY2FsQ2FjaGVEYXRhLmxvYWRlZFdpZGdldENhY2hlW3VybF0gPSByZXNwb25zZURhdGEucmVzcG9uc2VUZXh0O1xuXHRcdHJldHVybiAoIHJlc3BvbnNlRGF0YS5yZXNwb25zZVRleHQgKTtcblx0fVxuXG59O1xuXG5HbG9iYWwucmVtb3ZlQ3NzID0gZnVuY3Rpb24oIHBhdGggKSB7XG5cdHZhciByZWFsUGF0aCA9ICd0aGVtZS8nICsgR2xvYmFsLnRoZW1lICsgJy9jc3MvJyArIHBhdGg7XG5cblx0aWYgKCBHbG9iYWwudXJsX29mZnNldCApIHtcblx0XHRyZWFsUGF0aCA9IEdsb2JhbC51cmxfb2Zmc2V0ICsgcmVhbFBhdGg7XG5cdH1cblxuXHQkKCAnbGlua1tocmVmPVxcJ1xcJyArIHJlYWxQYXRoICsgXFwnP3Y9XFwnICsgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFwcGxpY2F0aW9uX2J1aWxkICsgXFwnXFwnXScgKS5yZW1vdmUoKTtcbn07XG5cbi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cblxuR2xvYmFsLmdldFZpZXdQYXRoQnlWaWV3SWQgPSBmdW5jdGlvbiggdmlld0lkICkge1xuXHR2YXIgcGF0aDtcblx0c3dpdGNoICggdmlld0lkICkge1xuXHRcdC8vUmVjcnVpdG1lbnQgUG9ydGFsXG5cdFx0Y2FzZSAnR3JpZFRlc3QnOlxuXHRcdGNhc2UgJ1dpZGdldFRlc3QnOlxuXHRcdGNhc2UgJ0F3ZXNvbWVib3hUZXN0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvZGV2ZWxvcGVyX3Rvb2xzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdNeVByb2ZpbGUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb3J0YWwvaHIvbXlfcHJvZmlsZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnTXlKb2JBcHBsaWNhdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvcnRhbC9oci9teV9qb2JhcHBsaWNhdGlvbi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnTXlQcm9maWxlRW1wbG95bWVudCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvcnRhbC9oci9teV9wcm9maWxlLyc7XG5cdFx0XHRicmVhaztcblxuXHRcdGNhc2UgJ01hcCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2F0dGVuZGFuY2UvbWFwLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdNYW51YWxUaW1lU2hlZXQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL21hbnVhbF90aW1lc2hlZXQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0hvbWUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9ob21lL2Rhc2hib2FyZC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUG9ydGFsSm9iVmFjYW5jeURldGFpbCc6XG5cdFx0Y2FzZSAnUG9ydGFsSm9iVmFjYW5jeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvcnRhbC9oci9yZWNydWl0bWVudC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUG9ydGFsTG9naW4nOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb3J0YWwvbG9naW4vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1F1aWNrUHVuY2hMb2dpbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3F1aWNrX3B1bmNoL2xvZ2luLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdRdWlja1B1bmNoJzpcblx0XHRcdHBhdGggPSAndmlld3MvcXVpY2tfcHVuY2gvcHVuY2gvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1VzZXJEYXRlVG90YWxQYXJlbnQnOlxuXHRcdGNhc2UgJ1VzZXJEYXRlVG90YWwnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL3RpbWVzaGVldC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUHJvZHVjdCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2ludm9pY2UvcHJvZHVjdHMvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0ludm9pY2VEaXN0cmljdCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2ludm9pY2UvZGlzdHJpY3QvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BheW1lbnRHYXRld2F5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9wYXltZW50X2dhdGV3YXkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0ludm9pY2VDb25maWcnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9pbnZvaWNlL3NldHRpbmdzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdTaGlwcGluZ1BvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2ludm9pY2Uvc2hpcHBpbmdfcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBcmVhUG9saWN5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9hcmVhX3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVGF4UG9saWN5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS90YXhfcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDbGllbnRHcm91cCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2ludm9pY2UvY2xpZW50X2dyb3VwLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQcm9kdWN0R3JvdXAnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9pbnZvaWNlL3Byb2R1Y3RfZ3JvdXAvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0V4Y2VwdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2F0dGVuZGFuY2UvZXhjZXB0aW9ucy8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnRW1wbG95ZWUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvZW1wbG95ZWUvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1JlbWl0dGFuY2VEZXN0aW5hdGlvbkFjY291bnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvcmVtaXR0YW5jZV9kZXN0aW5hdGlvbl9hY2NvdW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdXYWdlJzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS93YWdlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdMb2dpbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2xvZ2luLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdUaW1lU2hlZXQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL3RpbWVzaGVldC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSW5PdXQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL2luX291dC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVjdXJyaW5nU2NoZWR1bGVDb250cm9sJzpcblx0XHRcdHBhdGggPSAndmlld3MvYXR0ZW5kYW5jZS9yZWN1cnJpbmdfc2NoZWR1bGVfY29udHJvbC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVjdXJyaW5nU2NoZWR1bGVUZW1wbGF0ZUNvbnRyb2wnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL3JlY3VycmluZ19zY2hlZHVsZV90ZW1wbGF0ZV9jb250cm9sLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdTY2hlZHVsZVNoaWZ0Jzpcblx0XHRjYXNlICdTY2hlZHVsZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2F0dGVuZGFuY2Uvc2NoZWR1bGUvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FjY3J1YWwnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL2FjY3J1YWwvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FjY3J1YWxCYWxhbmNlJzpcblx0XHRcdHBhdGggPSAndmlld3MvYXR0ZW5kYW5jZS9hY2NydWFsX2JhbGFuY2UvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1B1bmNoZXMnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL3B1bmNoZXMvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1B1bmNoVGFnR3JvdXAnOlxuXHRcdGNhc2UgJ1B1bmNoVGFnJzpcblx0XHRcdHBhdGggPSAndmlld3MvYXR0ZW5kYW5jZS9wdW5jaF90YWcvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0pvYkdyb3VwJzpcblx0XHRjYXNlICdKb2InOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9hdHRlbmRhbmNlL2pvYi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSm9iSXRlbUdyb3VwJzpcblx0XHRjYXNlICdKb2JJdGVtJzpcblx0XHRcdHBhdGggPSAndmlld3MvYXR0ZW5kYW5jZS9qb2JfaXRlbS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSm9iSXRlbUFtZW5kbWVudCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2F0dGVuZGFuY2Uvam9iX2l0ZW1fYW1lbmRtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVc2VyVGl0bGUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvdXNlcl90aXRsZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVXNlckNvbnRhY3QnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvdXNlcl9jb250YWN0Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVc2VyUHJlZmVyZW5jZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2VtcGxveWVlcy91c2VyX3ByZWZlcmVuY2UvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1VzZXJHcm91cCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2VtcGxveWVlcy91c2VyX2dyb3VwLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdMb2cnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9jb3JlL2xvZy8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVXNlckRlZmF1bHQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvdXNlcl9kZWZhdWx0Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdST0UnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9lbXBsb3llZXMvcm9lLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDb21wYW55Jzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS9jb21wYW55Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDb21wYW5pZXMnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9jb21wYW55L2NvbXBhbmllcy8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5UGVyaW9kU2NoZWR1bGUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wYXlwZXJpb2QvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BheVBlcmlvZHMnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wYXlyb2xsL3BheV9wZXJpb2RzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdMZWdhbEVudGl0eSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvbGVnYWxfZW50aXR5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlyb2xsUmVtaXR0YW5jZUFnZW5jeUV2ZW50Jzpcblx0XHRjYXNlICdQYXlyb2xsUmVtaXR0YW5jZUFnZW5jeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvcGF5cm9sbF9yZW1pdHRhbmNlX2FnZW5jeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVtaXR0YW5jZVNvdXJjZUFjY291bnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9jb21wYW55L3JlbWl0dGFuY2Vfc291cmNlX2FjY291bnQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0JyYW5jaCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvYnJhbmNoLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdHRU9GZW5jZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvZ2VvX2ZlbmNlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdEZXBhcnRtZW50Jzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS9kZXBhcnRtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdIaWVyYXJjaHlDb250cm9sJzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS9oaWVyYXJjaHlfY29udHJvbC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnV2FnZUdyb3VwJzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS93YWdlX2dyb3VwLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdFdGhuaWNHcm91cCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvZXRobmljX2dyb3VwLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDdXJyZW5jeSc6XG5cdFx0Y2FzZSAnQ3VycmVuY3lSYXRlJzpcblx0XHRcdHBhdGggPSAndmlld3MvY29tcGFueS9jdXJyZW5jeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGVybWlzc2lvbkNvbnRyb2wnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9jb21wYW55L3Blcm1pc3Npb25fY29udHJvbC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQ3VzdG9tRmllbGQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9jb21wYW55L2N1c3RvbV9maWVsZC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnU3RhdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2NvbXBhbnkvc3RhdGlvbi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5U3R1Yic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BheXJvbGwvcGF5X3N0dWIvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BheVN0dWJUcmFuc2FjdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BheXJvbGwvcGF5X3N0dWJfdHJhbnNhY3Rpb24vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0dvdmVybm1lbnREb2N1bWVudCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BheXJvbGwvZ292ZXJubWVudF9kb2N1bWVudC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVxdWVzdCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL215X2FjY291bnQvcmVxdWVzdC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQ2hhbmdlUGFzc3dvcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9teV9hY2NvdW50L3Bhc3N3b3JkLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdSZXF1ZXN0QXV0aG9yaXphdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL215X2FjY291bnQvcmVxdWVzdF9hdXRob3JpemF0aW9uLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdUaW1lU2hlZXRBdXRob3JpemF0aW9uJzpcblx0XHRcdHBhdGggPSAndmlld3MvbXlfYWNjb3VudC90aW1lc2hlZXRfYXV0aG9yaXphdGlvbi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnTWVzc2FnZUNvbnRyb2wnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9teV9hY2NvdW50L21lc3NhZ2VfY29udHJvbC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnTm90aWZpY2F0aW9uJzpcblx0XHRcdHBhdGggPSAndmlld3MvbXlfYWNjb3VudC9ub3RpZmljYXRpb24vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0xvZ2luVXNlckNvbnRhY3QnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9teV9hY2NvdW50L3VzZXJfY29udGFjdC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnTG9naW5Vc2VyUHJlZmVyZW5jZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL215X2FjY291bnQvdXNlcl9wcmVmZXJlbmNlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdMb2dpblVzZXJFeHBlbnNlJzpcblx0XHRjYXNlICdFeHBlbnNlQXV0aG9yaXphdGlvbic6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL215X2FjY291bnQvZXhwZW5zZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5U3R1YkFtZW5kbWVudCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BheXJvbGwvcGF5X3N0dWJfYW1lbmRtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdSZWN1cnJpbmdQYXlTdHViQW1lbmRtZW50Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcGF5cm9sbC9yZWN1cnJpbmdfcGF5X3N0dWJfYW1lbmRtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlTdHViRW50cnlBY2NvdW50Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcGF5cm9sbC9wYXlfc3R1Yl9lbnRyeV9hY2NvdW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDb21wYW55VGF4RGVkdWN0aW9uJzpcblx0XHRcdHBhdGggPSAndmlld3MvcGF5cm9sbC9jb21wYW55X3RheF9kZWR1Y3Rpb24vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1VzZXJFeHBlbnNlJzpcblx0XHRcdHBhdGggPSAndmlld3MvcGF5cm9sbC91c2VyX2V4cGVuc2UvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BvbGljeUdyb3VwJzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L3BvbGljeV9ncm91cC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5Q29kZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9wYXlfY29kZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5Rm9ybXVsYVBvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9wYXlfZm9ybXVsYV9wb2xpY3kvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0NvbnRyaWJ1dGluZ1BheUNvZGVQb2xpY3knOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb2xpY3kvY29udHJpYnV0aW5nX3BheV9jb2RlX3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQ29udHJpYnV0aW5nU2hpZnRQb2xpY3knOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb2xpY3kvY29udHJpYnV0aW5nX3NoaWZ0X3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUm91bmRJbnRlcnZhbFBvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9yb3VuZF9pbnRlcnZhbF9wb2xpY3kvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ01lYWxQb2xpY3knOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb2xpY3kvbWVhbF9wb2xpY3kvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0JyZWFrUG9saWN5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L2JyZWFrX3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVndWxhclRpbWVQb2xpY3knOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb2xpY3kvcmVndWxhcl90aW1lX3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnRXhwZW5zZVBvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9leHBlbnNlX3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnT3ZlcnRpbWVQb2xpY3knOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wb2xpY3kvb3ZlcnRpbWVfcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBYnNlbmNlUG9saWN5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L2Fic2VuY2VfcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQcmVtaXVtUG9saWN5Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L3ByZW1pdW1fcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdFeGNlcHRpb25Qb2xpY3lDb250cm9sJzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L2V4Y2VwdGlvbl9wb2xpY3kvJztcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAnUmVjdXJyaW5nSG9saWRheSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9yZWN1cnJpbmdfaG9saWRheS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSG9saWRheVBvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9ob2xpZGF5X3BvbGljeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSG9saWRheSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9ob2xpZGF5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdTY2hlZHVsZVBvbGljeSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3BvbGljeS9zY2hlZHVsZV9wb2xpY3kvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FjY3J1YWxQb2xpY3knOlxuXHRcdGNhc2UgJ0FjY3J1YWxQb2xpY3lBY2NvdW50Jzpcblx0XHRjYXNlICdBY2NydWFsUG9saWN5VXNlck1vZGlmaWVyJzpcblx0XHRcdHBhdGggPSAndmlld3MvcG9saWN5L2FjY3J1YWxfcG9saWN5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdEb2N1bWVudFJldmlzaW9uJzpcblx0XHRjYXNlICdEb2N1bWVudCc6XG5cdFx0Y2FzZSAnRG9jdW1lbnRHcm91cCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2RvY3VtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBYm91dCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2hlbHAvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FjdGl2ZVNoaWZ0UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy93aG9zX2luX3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1VzZXJTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9lbXBsb3llZV9pbmZvcm1hdGlvbi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnU2F2ZWRSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3NhdmVkX3JlcG9ydC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVwb3J0U2NoZWR1bGUnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3JlcG9ydF9zY2hlZHVsZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnU2NoZWR1bGVTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9zY2hlZHVsZV9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdUaW1lc2hlZXRTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy90aW1lc2hlZXRfc3VtbWFyeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVGltZXNoZWV0RGV0YWlsUmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy90aW1lc2hlZXRfZGV0YWlsLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQdW5jaFN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3B1bmNoX3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0V4Y2VwdGlvblN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2V4Y2VwdGlvbl9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlTdHViVHJhbnNhY3Rpb25TdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9wYXlfc3R1Yl90cmFuc2FjdGlvbl9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlTdHViU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvcGF5X3N0dWJfc3VtbWFyeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnS1BJJzpcblx0XHRjYXNlICdLUElHcm91cCc6XG5cdFx0Y2FzZSAnVXNlclJldmlld0NvbnRyb2wnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9oci9rcGkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1F1YWxpZmljYXRpb25Hcm91cCc6XG5cdFx0Y2FzZSAnUXVhbGlmaWNhdGlvbic6XG5cdFx0Y2FzZSAnVXNlclNraWxsJzpcblx0XHRjYXNlICdVc2VyRWR1Y2F0aW9uJzpcblx0XHRjYXNlICdVc2VyTWVtYmVyc2hpcCc6XG5cdFx0Y2FzZSAnVXNlckxpY2Vuc2UnOlxuXHRcdGNhc2UgJ1VzZXJMYW5ndWFnZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2hyL3F1YWxpZmljYXRpb24vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0pvYkFwcGxpY2F0aW9uJzpcblx0XHRjYXNlICdKb2JWYWNhbmN5Jzpcblx0XHRjYXNlICdKb2JBcHBsaWNhbnQnOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudEVtcGxveW1lbnQnOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudFJlZmVyZW5jZSc6XG5cdFx0Y2FzZSAnSm9iQXBwbGljYW50TG9jYXRpb24nOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudFNraWxsJzpcblx0XHRjYXNlICdKb2JBcHBsaWNhbnRFZHVjYXRpb24nOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudE1lbWJlcnNoaXAnOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudExpY2Vuc2UnOlxuXHRcdGNhc2UgJ0pvYkFwcGxpY2FudExhbmd1YWdlJzpcblx0XHRjYXNlICdSZWNydWl0bWVudFBvcnRhbENvbmZpZyc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL2hyL3JlY3J1aXRtZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlyb2xsRXhwb3J0UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9wYXlyb2xsX2V4cG9ydC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnR2VuZXJhbExlZGdlclN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2dlbmVyYWxfbGVkZ2VyX3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0V4cGVuc2VTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9leHBlbnNlX3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0FjY3J1YWxCYWxhbmNlU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvYWNjcnVhbF9iYWxhbmNlX3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0pvYlN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2pvYl9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdKb2JBbmFseXNpc1JlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvam9iX2FuYWx5c2lzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdKb2JJbmZvcm1hdGlvblJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvam9iX2luZm8vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0pvYkl0ZW1JbmZvcm1hdGlvblJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvam9iX2l0ZW1faW5mby8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSW52b2ljZVRyYW5zYWN0aW9uU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvaW52b2ljZV90cmFuc2FjdGlvbl9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdSZW1pdHRhbmNlU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvcmVtaXR0YW5jZV9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdUNFN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3Q0X3N1bW1hcnkvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1Q0QVN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3Q0YV9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdUYXhTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy90YXhfc3VtbWFyeS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnRm9ybTk0MFJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvZm9ybTk0MC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnRm9ybTk0MVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvZm9ybTk0MS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnRm9ybTEwOTlOZWNSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2Zvcm0xMDk5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdGb3JtVzJSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2Zvcm13Mi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVVNTdGF0ZVVuZW1wbG95bWVudFJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvdXNfc3RhdGVfdW5lbXBsb3ltZW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdBZmZvcmRhYmxlQ2FyZVJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvYWZmb3JkYWJsZV9jYXJlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVc2VyUXVhbGlmaWNhdGlvblJlcG9ydCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3JlcG9ydHMvcXVhbGlmaWNhdGlvbl9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdLUElSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3Jldmlld19zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVc2VyUmVjcnVpdG1lbnRTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdHBhdGggPSAndmlld3MvcmVwb3J0cy9yZWNydWl0bWVudF9zdW1tYXJ5Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVc2VyUmVjcnVpdG1lbnREZXRhaWxSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL3JlY3J1aXRtZW50X2RldGFpbC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnQ2xpZW50Jzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9jbGllbnQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0NsaWVudENvbnRhY3QnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9pbnZvaWNlL2NsaWVudF9jb250YWN0Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDbGllbnRQYXltZW50Jzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9jbGllbnRfcGF5bWVudC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSW52b2ljZVRyYW5zYWN0aW9uJzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9pbnZvaWNlX3RyYW5zYWN0aW9uLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdJbnZvaWNlJzpcblx0XHRcdHBhdGggPSAndmlld3MvaW52b2ljZS9pbnZvaWNlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdDdXN0b21Db2x1bW4nOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2N1c3RvbV9jb2x1bW4vJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0F1ZGl0VHJhaWxSZXBvcnQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9yZXBvcnRzL2F1ZGl0dHJhaWwvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1JlQ2FsY3VsYXRlVGltZVNoZWV0V2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL3JlX2NhbGN1bGF0ZV90aW1lc2hlZXQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0dlbmVyYXRlUGF5U3R1YldpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9nZW5lcmF0ZV9wYXlfc3R1Yi8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnVXNlckdlbmVyaWNTdGF0dXMnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvdXNlcl9nZW5lcmljX2RhdGFfc3RhdHVzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQcm9jZXNzUGF5cm9sbFdpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9wcm9jZXNzX3BheXJvbGwvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BheXJvbGxSZW1pdHRhbmNlQWdlbmN5RXZlbnRXaXphcmRDb250cm9sbGVyJzpcblx0XHRcdHBhdGggPSAndmlld3MvcGF5cm9sbC9yZW1pdHRhbmNlX3dpemFyZC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUHJvY2Vzc1RyYW5zYWN0aW9uc1dpemFyZENvbnRyb2xsZXInOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy9wYXlyb2xsL3Byb2Nlc3NfdHJhbnNhY3Rpb25zX3dpemFyZC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSW1wb3J0Q1NWV2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL2ltcG9ydF9jc3YvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0pvYkludm9pY2VXaXphcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvam9iX2ludm9pY2UvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0xvZ2luVXNlcldpemFyZCc6XG5cdFx0Y2FzZSAnTG9naW5Vc2VyJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL2xvZ2luX3VzZXIvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1F1aWNrU3RhcnRXaXphcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvcXVpY2tfc3RhcnQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1VzZXJQaG90b1dpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC91c2VyX3Bob3RvLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdGaW5kQXZhaWxhYmxlV2l6YXJkJzpcblx0XHRjYXNlICdGaW5kQXZhaWxhYmxlJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL2ZpbmRfYXZhaWxhYmxlLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQZXJtaXNzaW9uV2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL3Blcm1pc3Npb25fd2l6YXJkLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdGb3JtdWxhQnVpbGRlcldpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9mb3JtdWxhX2J1aWxkZXJfd2l6YXJkLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdSZUNhbGN1bGF0ZUFjY3J1YWxXaXphcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvcmVfY2FsY3VsYXRlX2FjY3J1YWwvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1Jlc2V0UGFzc3dvcmRXaXphcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvcmVzZXRfcGFzc3dvcmQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1NoYXJlUmVwb3J0V2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL3NoYXJlX3JlcG9ydC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUGF5Q29kZVdpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9wYXlfY29kZS8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnSW5zdGFsbFdpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9pbnN0YWxsLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdQYXlTdHViQWNjb3VudFdpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9wYXlfc3R1Yl9hY2NvdW50Lyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdEYXNobGV0V2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL2Rhc2hsZXQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1JlcG9ydFZpZXdXaXphcmQnOlxuXHRcdFx0cGF0aCA9ICd2aWV3cy93aXphcmQvcmVwb3J0X3ZpZXcvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ1BvcnRhbEFwcGx5Sm9iV2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL3BvcnRhbF9hcHBseV9qb2IvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0ZvcmdvdFBhc3N3b3JkV2l6YXJkJzpcblx0XHRcdHBhdGggPSAndmlld3Mvd2l6YXJkL2ZvcmdvdF9wYXNzd29yZC8nO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAnUmVzZXRGb3Jnb3RQYXNzd29yZFdpemFyZCc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3dpemFyZC9yZXNldF9mb3Jnb3RfcGFzc3dvcmQvJztcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ0RldmVsb3BlclRvb2xzJzpcblx0XHRcdHBhdGggPSAndmlld3MvZGV2ZWxvcGVyX3Rvb2xzLyc7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdVSUtpdFNhbXBsZSc6XG5cdFx0Y2FzZSAnVUlLaXRDaGlsZFNhbXBsZSc6XG5cdFx0XHRwYXRoID0gJ3ZpZXdzL3VpX2tpdF9zYW1wbGUvJztcblx0XHRcdGJyZWFrO1xuXHR9XG5cdHJldHVybiBwYXRoO1xufTtcbi8qIGpzaGludCBpZ25vcmU6ZW5kICovXG5cbi8vcmV0dXJucyBleGFjdCBmaWxlcGF0aHMgZm9yIGNsYXNzIGRlcGVuZGVuY2llc1xuR2xvYmFsLmdldFZpZXdQcmVsb2FkUGF0aEJ5Vmlld0lkID0gZnVuY3Rpb24oIHZpZXdJZCApIHtcblx0Ly8gREVQUkVDQVRFRDogTW92ZWQgdGhlIGxvYWRpbmcgb2YgdGhlc2UgcHJlbG9hZHMgdG8gcG9zdC1sb2dpbi1tYWluX3VpLWRlcGVuZGFuY2llcy5qc1xuXG5cdHZhciBwcmVsb2FkcyA9IFtdO1xuXHQvLyBzd2l0Y2ggKCB2aWV3SWQgKSB7XG5cdC8vIFx0Y2FzZSAnUmVxdWVzdCc6XG5cdC8vIFx0Y2FzZSAnUmVxdWVzdEF1dGhvcml6YXRpb24nOlxuXHQvLyBcdFx0cHJlbG9hZHMgPSBbJ3ZpZXdzL2NvbW1vbi9BdXRob3JpemF0aW9uSGlzdG9yeUNvbW1vbi5qcycsICd2aWV3cy9jb21tb24vUmVxdWVzdFZpZXdDb21tb25Db250cm9sbGVyLmpzJywgJ3ZpZXdzL2NvbW1vbi9FbWJlZGRlZE1lc3NhZ2VDb21tb24uanMnXTtcblx0Ly8gXHRcdGJyZWFrO1xuXHQvLyBcdGNhc2UgJ0V4cGVuc2VBdXRob3JpemF0aW9uJzpcblx0Ly8gXHRjYXNlICdVc2VyRXhwZW5zZSc6XG5cdC8vIFx0Y2FzZSAnTG9naW5Vc2VyRXhwZW5zZSc6XG5cdC8vIFx0Y2FzZSAnVGltZVNoZWV0QXV0aG9yaXphdGlvbic6XG5cdC8vIFx0XHRwcmVsb2FkcyA9IFsndmlld3MvY29tbW9uL0F1dGhvcml6YXRpb25IaXN0b3J5Q29tbW9uLmpzJ107XG5cdC8vIFx0XHRicmVhaztcblx0Ly8gfVxuXHRyZXR1cm4gcHJlbG9hZHM7XG59O1xuXG5HbG9iYWwucmVtb3ZlVmlld0NzcyA9IGZ1bmN0aW9uKCB2aWV3SWQsIGZpbGVOYW1lICkge1xuXHRHbG9iYWwucmVtb3ZlQ3NzKCBHbG9iYWwuZ2V0Vmlld1BhdGhCeVZpZXdJZCggdmlld0lkICkgKyBmaWxlTmFtZSApO1xufTtcblxuR2xvYmFsLnNhbml0aXplVmlld0lkID0gZnVuY3Rpb24oIHZpZXdJZCApIHtcblx0aWYgKCB0eXBlb2Ygdmlld0lkID09PSAnc3RyaW5nJyB8fCB2aWV3SWQgaW5zdGFuY2VvZiBTdHJpbmcgKSB7XG5cdFx0cmV0dXJuIHZpZXdJZC5yZXBsYWNlKCAnLycsICcnICkucmVwbGFjZSggJ1xcXFwnLCAnJyApO1xuXHR9XG5cblx0cmV0dXJuIHZpZXdJZDtcbn07XG5cbkdsb2JhbC5sb2FkVmlld1NvdXJjZSA9IGZ1bmN0aW9uKCB2aWV3SWQsIGZpbGVOYW1lLCBvblJlc3VsdCwgc3luYyApIHtcblx0dmFyIHZpZXdJZCA9IEdsb2JhbC5zYW5pdGl6ZVZpZXdJZCggdmlld0lkICk7XG5cdHZhciBwYXRoID0gR2xvYmFsLmdldFZpZXdQYXRoQnlWaWV3SWQoIHZpZXdJZCApO1xuXG5cdGlmICggZmlsZU5hbWUuaW5kZXhPZiggJy5qcycgKSA+IDAgKSB7XG5cdFx0dmFyIHByZWxvYWRzID0gR2xvYmFsLmdldFZpZXdQcmVsb2FkUGF0aEJ5Vmlld0lkKCB2aWV3SWQgKTtcblx0XHRpZiAoIHByZWxvYWRzLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRmb3IgKCB2YXIgcCBpbiBwcmVsb2FkcyApIHtcblx0XHRcdFx0R2xvYmFsLmxvYWRTY3JpcHQoIHByZWxvYWRzW3BdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBwYXRoICkge1xuXHRcdFx0aWYgKCBzeW5jICkge1xuXHRcdFx0XHRyZXR1cm4gR2xvYmFsLmxvYWRTY3JpcHQoIHBhdGggKyBmaWxlTmFtZSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0R2xvYmFsLmxvYWRTY3JpcHQoIHBhdGggKyBmaWxlTmFtZSwgb25SZXN1bHQgKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly9JbnZhbGlkIHZpZXdJZCwgcmVkaXJlY3QgdG8gaG9tZSBwYWdlP1xuXHRcdFx0Y29uc29sZS5kZWJ1ZyggJ1ZpZXcgZG9lcyBub3QgZXhpc3QhIFZpZXdJZDogJyArIHZpZXdJZCArICcgRmlsZSBOYW1lOiAnICsgZmlsZU5hbWUgKTtcblx0XHRcdGlmICggU2VydmljZUNhbGxlci5yb290X3VybCAmJiBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYmFzZV91cmwgKSB7XG5cdFx0XHRcdEdsb2JhbC5zZXRVUkxUb0Jyb3dzZXIoIFNlcnZpY2VDYWxsZXIucm9vdF91cmwgKyBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYmFzZV91cmwgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0fSBlbHNlIGlmICggZmlsZU5hbWUuaW5kZXhPZiggJy5jc3MnICkgPiAwICkge1xuXHRcdEdsb2JhbC5hZGRDc3MoIHBhdGggKyBmaWxlTmFtZSApO1xuXHR9IGVsc2Uge1xuXHRcdGlmICggcGF0aCApIHtcblx0XHRcdC8vIEhUTUwySlNcblx0XHRcdHZhciB0ZW1wbGF0ZV90eXBlID0gSHRtbFRlbXBsYXRlc0dsb2JhbC5nZXRUZW1wbGF0ZVR5cGVGcm9tRmlsZW5hbWUoIGZpbGVOYW1lICk7XG5cdFx0XHR2YXIgdGVtcGxhdGVfb3B0aW9ucyA9IEh0bWxUZW1wbGF0ZXNHbG9iYWwuZ2V0VGVtcGxhdGVPcHRpb25zRnJvbVZpZXdJZCggdmlld0lkICk7XG5cblx0XHRcdGlmKCB0ZW1wbGF0ZV90eXBlID09PSBUZW1wbGF0ZVR5cGUuSU5MSU5FX0hUTUwgKSB7XG5cdFx0XHRcdHRlbXBsYXRlX29wdGlvbnMuZmlsZW5hbWUgPSBmaWxlTmFtZTsgLy8gTmVlZGVkIGJ5IEh0bWxUZW1wbGF0ZXMuY2hlY2tWaWV3Q2xhc3NGb3JJbmxpbmVIdG1sYnlGaWxlbmFtZSgpIHdoaWNoIHVzZXMgZmlsZW5hbWUsIG5vdCB2aWV3IGlkLlxuXHRcdFx0fVxuXHRcdFx0aWYgKCBzeW5jICkge1xuXHRcdFx0XHQvLyBOb3RlOiBmb3IgI0hUTUwySlMgVGhpcyBwYXRoIGlzIHRha2VuIGZvciB0aGluZ3Mgc3VjaCBhczogQ29tcGFueUluZm9ybWF0aW9uLCBDb21wYW55RWRpdFZpZXcuaHRtbCwgYW5kIGdlbmVyYWwgZWRpdCB2aWV3cy5cblxuXHRcdFx0XHQvLyBDaGVjayBpZiB3ZSBzaG91bGQgdXNlIHRoZSBuZXcgdGVtcGxhdGluZyBsb2dpYywgb3IgbGVnYWN5IGh0bWwgbG9hZC5cblx0XHRcdFx0aWYoIHRlbXBsYXRlX3R5cGUgIT09IFRlbXBsYXRlVHlwZS5MRUdBQ1lfSFRNTCApIHtcblx0XHRcdFx0XHQvLyBVc2UgbmV3IEhUTUwySlMgdGVtcGxhdGUgY2xhc3Ncblx0XHRcdFx0XHRyZXR1cm4gSHRtbFRlbXBsYXRlc0dsb2JhbC5nZXRUZW1wbGF0ZSggdGVtcGxhdGVfdHlwZSwgdGVtcGxhdGVfb3B0aW9ucywgbnVsbCApOyAvLyBubyBvblJlc3VsdCwgYXMgaXRzIHN5bmNyb25vdXMuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gTGVnYWN5IGh0bWwgZmlsZSBsb2FkIGZvciBzeW5jcm9ub3VzIGZpbGVzLlxuXHRcdFx0XHRcdHJldHVybiBHbG9iYWwubG9hZFBhZ2VTeW5jKCBwYXRoICsgZmlsZU5hbWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gQ2hlY2sgaWYgd2Ugc2hvdWxkIHVzZSB0aGUgbmV3IHRlbXBsYXRpbmcgbG9naWMsIG9yIGxlZ2FjeSBodG1sIGxvYWQuXG5cdFx0XHRcdGlmKCB0ZW1wbGF0ZV90eXBlICE9PSBUZW1wbGF0ZVR5cGUuTEVHQUNZX0hUTUwgKSB7XG5cdFx0XHRcdFx0Ly8gVXNlIG5ldyBIVE1MMkpTIHRlbXBsYXRlIGNsYXNzXG5cdFx0XHRcdFx0SHRtbFRlbXBsYXRlc0dsb2JhbC5nZXRUZW1wbGF0ZSggdGVtcGxhdGVfdHlwZSwgdGVtcGxhdGVfb3B0aW9ucywgb25SZXN1bHQgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyBMZWdhY3kgaHRtbCBmaWxlIGxvYWRcblx0XHRcdFx0XHRHbG9iYWwubG9hZFBhZ2UoIHBhdGggKyBmaWxlTmFtZSwgb25SZXN1bHQgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvL0ludmFsaWQgdmlld0lkLCByZWRpcmVjdCB0byBob21lIHBhZ2U/XG5cdFx0XHRjb25zb2xlLmRlYnVnKCAnVmlldyBkb2VzIG5vdCBleGlzdCEgVmlld0lkOiAnICsgdmlld0lkICsgJyBGaWxlIE5hbWU6ICcgKyBmaWxlTmFtZSApO1xuXHRcdFx0aWYgKCBTZXJ2aWNlQ2FsbGVyLnJvb3RfdXJsICYmIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5iYXNlX3VybCApIHtcblx0XHRcdFx0R2xvYmFsLnNldFVSTFRvQnJvd3NlciggU2VydmljZUNhbGxlci5yb290X3VybCArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5iYXNlX3VybCApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcblxuR2xvYmFsLmxvYWRQYWdlU3luYyA9IGZ1bmN0aW9uKCB1cmwgKSB7XG5cblx0dmFyIHJlYWxQYXRoID0gdXJsICsgJz92PScgKyBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYXBwbGljYXRpb25fYnVpbGQ7XG5cblx0aWYgKCBHbG9iYWwudXJsX29mZnNldCApIHtcblx0XHRyZWFsUGF0aCA9IEdsb2JhbC51cmxfb2Zmc2V0ICsgcmVhbFBhdGg7XG5cdH1cblx0dmFyIG1lc3NhZ2VfaWQgPSBUVFVVSUQuZ2VuZXJhdGVVVUlEKCk7XG5cdFByb2dyZXNzQmFyLnNob3dQcm9ncmVzc0JhciggbWVzc2FnZV9pZCApO1xuXHR2YXIgc3VjY2Vzc2ZsYWcgPSBmYWxzZTtcblx0dmFyIHJlc3BvbnNlRGF0YSA9ICQuYWpheCgge1xuXHRcdGFzeW5jOiBmYWxzZSxcblx0XHR0eXBlOiAnR0VUJyxcblx0XHR1cmw6IHJlYWxQYXRoLFxuXHRcdGRhdGE6IG51bGwsXG5cdFx0Y2FjaGU6IHRydWUsXG5cdFx0c3VjY2VzczogZnVuY3Rpb24oKSB7XG5cdFx0XHRzdWNjZXNzZmxhZyA9IHRydWU7XG5cdFx0fSxcblxuXHRcdGVycm9yOiBmdW5jdGlvbigganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICkge1xuXHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93TmV0d29ya0Vycm9yQWxlcnQoIGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93biApO1xuXHRcdH1cblx0fSApO1xuXG5cdFByb2dyZXNzQmFyLnJlbW92ZVByb2dyZXNzQmFyKCBtZXNzYWdlX2lkICk7XG5cblx0cmV0dXJuICggcmVzcG9uc2VEYXRhLnJlc3BvbnNlVGV4dCApO1xuXG59O1xuXG5HbG9iYWwubG9hZFBhZ2UgPSBmdW5jdGlvbiggdXJsLCBvblJlc3VsdCApIHtcblxuXHR2YXIgcmVhbFBhdGggPSB1cmwgKyAnP3Y9JyArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5hcHBsaWNhdGlvbl9idWlsZDtcblx0dmFyIG1lc3NhZ2VfaWQgPSBUVFVVSUQuZ2VuZXJhdGVVVUlEKCk7XG5cdGlmICggR2xvYmFsLnVybF9vZmZzZXQgKSB7XG5cdFx0cmVhbFBhdGggPSBHbG9iYWwudXJsX29mZnNldCArIHJlYWxQYXRoO1xuXHR9XG5cblx0UHJvZ3Jlc3NCYXIuc2hvd1Byb2dyZXNzQmFyKCBtZXNzYWdlX2lkICk7XG5cdCQuYWpheCgge1xuXHRcdGFzeW5jOiB0cnVlLFxuXHRcdHR5cGU6ICdHRVQnLFxuXHRcdHVybDogcmVhbFBhdGgsXG5cdFx0ZGF0YTogbnVsbCxcblx0XHRjYWNoZTogdHJ1ZSxcblx0XHRzdWNjZXNzOiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdFx0UHJvZ3Jlc3NCYXIucmVtb3ZlUHJvZ3Jlc3NCYXIoIG1lc3NhZ2VfaWQgKTtcblx0XHRcdG9uUmVzdWx0KCByZXN1bHQgKTtcblx0XHR9LFxuXHRcdGVycm9yOiBmdW5jdGlvbigganFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duICkge1xuXHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93TmV0d29ya0Vycm9yQWxlcnQoIGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93biApO1xuXHRcdH1cblx0fSApO1xuXG59O1xuXG5HbG9iYWwuZ2V0Um9vdFVSTCA9IGZ1bmN0aW9uKCB1cmwgKSB7XG5cdGlmICggIXVybCApIHtcblx0XHR1cmwgPSBsb2NhdGlvbi5ocmVmO1xuXHR9XG5cblx0Ly9SYXRoZXIgdGhhbiBwYXJzZSB0aGUgVVJMIG91cnNlbHZlcywgbGV0cyB1c2UgdGhlIFVSTCBBUEkgYW5kIGJ1aWxkIGl0IGJhY2sgdXAgZnJvbSBpdHMgY29tcG9uZW50cy5cblx0dmFyIHVybF9vYmogPSBuZXcgVVJMKCB1cmwgKTtcblx0dmFyIHJldHZhbCA9IHVybF9vYmoucHJvdG9jb2wgKyAnLy8nICsgdXJsX29iai5ob3N0O1xuXG5cdHJldHVybiByZXR2YWw7XG59O1xuXG5HbG9iYWwuZ2V0QmFzZVVSTCA9IGZ1bmN0aW9uKCB1cmxfcmVsYXRpdmVfcGF0aCwgaW5jbHVkZV9zZWFyY2ggPSB0cnVlICkge1xuXHQvL1JhdGhlciB0aGFuIHBhcnNlIHRoZSBVUkwgb3Vyc2VsdmVzLCBsZXRzIHVzZSB0aGUgVVJMIEFQSSBhbmQgYnVpbGQgaXQgYmFjayB1cCBmcm9tIGl0cyBjb21wb25lbnRzLlxuXHR2YXIgdXJsX29iaiA9IG5ldyBVUkwoIGxvY2F0aW9uLmhyZWYgKTtcblx0dmFyIHJldHZhbCA9IHVybF9vYmoucHJvdG9jb2wgKyAnLy8nICsgdXJsX29iai5ob3N0ICsgdXJsX29iai5wYXRobmFtZTtcblxuXHQvL1Jlc29sdmUgYW55IHNwZWNpZmllZCByZWxhdGl2ZSBwYXRoIGhlcmUsIHNvIHdlIGNhbiBhcHBlbmQgdGhlIHNlYXJjaCBjb21wb25lbnQgb2YgdGhlIFVSTCBhZnRlci5cblx0Ly8gIFRoaXMgaXMgbmVlZGVkIGZvciB0aGUgcmVjcnVpdG1lbnQgcG9ydGFsIHRvIHdvcmsgaWYgRmFjZWJvb2sgb3Igc29tZSBvdGhlciAzcmQgcGFydHkgYXBwZW5kcyBzZWFyY2ggY29tcG9uZW50cyBvbiB0aGUgVVJMLCBpZTogP3Rlc3Q9MSMhbT1Qb3J0YWxKb2JWYWNhbmN5RGV0YWlsJmlkPTA1YTQ1ZDBiLWI5ODItMmExZi0yMDAzLTIxZWE2NTUyMmJmMyZjb21wYW55X2lkPUFCQ1xuXHRpZiAoIHVybF9yZWxhdGl2ZV9wYXRoICkge1xuXHRcdHJldHZhbCA9IG5ldyBVUkwoIHVybF9yZWxhdGl2ZV9wYXRoLCByZXR2YWwgKS5ocmVmO1xuXHR9XG5cblx0aWYgKCBpbmNsdWRlX3NlYXJjaCA9PSB0cnVlICkge1xuXHRcdHJldHZhbCArPSB1cmxfb2JqLnNlYXJjaDsgLy9DYW4ndCBwdXQgdGhlIHNlYXJjaCBjb21wb25lbnQgYmFjayBvbiB3aGVuIGdldHRpbmcgQmFzZVVSTC5cblx0fVxuXG5cdHJldHVybiByZXR2YWw7XG59O1xuXG5HbG9iYWwuaXNBcnJheUFuZEhhc0l0ZW1zID0gZnVuY3Rpb24oIG9iamVjdCApIHtcblxuXHRpZiAoICQudHlwZSggb2JqZWN0ICkgPT09ICdhcnJheScgJiYgb2JqZWN0Lmxlbmd0aCA+IDAgKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRyZXR1cm4gZmFsc2U7XG5cbn07XG5cbkdsb2JhbC5pc1ZhbGlkSW5wdXRDb2RlcyA9IGZ1bmN0aW9uKCBrZXlDb2RlICkge1xuXHR2YXIgcmVzdWx0ID0gdHJ1ZTtcblx0c3dpdGNoICgga2V5Q29kZSApIHtcblx0XHRjYXNlIDk6XG5cdFx0Y2FzZSAxNjpcblx0XHRjYXNlIDE3OlxuXHRcdGNhc2UgMTg6XG5cdFx0Y2FzZSAxOTpcblx0XHRjYXNlIDIwOlxuXHRcdGNhc2UgMzM6XG5cdFx0Y2FzZSAzNDpcblx0XHQvLyBjYXNlIDM3OlxuXHRcdC8vIGNhc2UgMzg6XG5cdFx0Ly8gY2FzZSAzOTpcblx0XHQvLyBjYXNlIDQwOlxuXHRcdGNhc2UgNDU6XG5cdFx0Y2FzZSA5MTpcblx0XHRjYXNlIDkyOlxuXHRcdGNhc2UgOTM6XG5cdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdGJyZWFrO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHRpZiAoIGtleUNvZGUgPj0gMTEyICYmIGtleUNvZGUgPD0gMTIzICkge1xuXHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdH1cblx0fVxuXHRyZXR1cm4gcmVzdWx0O1xufTtcblxuLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuR2xvYmFsLmNvbnZlcnRMYXlvdXRGaWx0ZXJUb0FQSUZpbHRlciA9IGZ1bmN0aW9uKCBsYXlvdXQgKSB7XG5cdHZhciBjb252ZXJ0X2ZpbHRlcl9kYXRhID0ge307XG5cblx0aWYgKCAhbGF5b3V0ICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0dmFyIGZpbHRlcl9kYXRhID0gbGF5b3V0LmRhdGEuZmlsdGVyX2RhdGE7XG5cblx0aWYgKCAhZmlsdGVyX2RhdGEgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQkLmVhY2goIGZpbHRlcl9kYXRhLCBmdW5jdGlvbigga2V5LCBjb250ZW50ICkge1xuXHRcdC8vIENhbm5vdCByZWFkIHByb3BlcnR5ICd2YWx1ZScgb2YgdW5kZWZpbmVkXG5cdFx0aWYgKCAhY29udGVudCApIHtcblx0XHRcdHJldHVybjsvL2NvbnRpbnVlO1xuXHRcdH1cblx0XHRpZiAoICggY29udGVudC52YWx1ZSBpbnN0YW5jZW9mIEFycmF5ICYmIGNvbnRlbnQudmFsdWUubGVuZ3RoID4gMCApIHx8ICggY29udGVudC52YWx1ZSBpbnN0YW5jZW9mIE9iamVjdCApICkge1xuXHRcdFx0dmFyIHZhbHVlcyA9IFtdO1xuXHRcdFx0dmFyIG9iaiA9IGNvbnRlbnQudmFsdWU7XG5cdFx0XHRpZiAoIGNvbnRlbnQudmFsdWUgaW5zdGFuY2VvZiBBcnJheSApIHtcblxuXHRcdFx0XHR2YXIgbGVuID0gY29udGVudC52YWx1ZS5sZW5ndGg7XG5cdFx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXG5cdFx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGNvbnRlbnQudmFsdWVbaV0udmFsdWUgKSApIHtcblx0XHRcdFx0XHRcdHZhbHVlcy5wdXNoKCBjb250ZW50LnZhbHVlW2ldLnZhbHVlICk7IC8vT3B0aW9ucyxcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBjb250ZW50LnZhbHVlW2ldLmlkIHx8IGNvbnRlbnQudmFsdWVbaV0uaWQgPT09IDAgfHwgY29udGVudC52YWx1ZVtpXS5pZCA9PT0gJzAnICkge1xuXHRcdFx0XHRcdFx0dmFsdWVzLnB1c2goIGNvbnRlbnQudmFsdWVbaV0uaWQgKTsgLy9Bd2Vzb21lYm94XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHZhbHVlcy5wdXNoKCBjb250ZW50LnZhbHVlW2ldICk7IC8vIGRlZmF1bHRfZmlsdGVyX2RhdGFfZm9yX25leHRfdmlld1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29udmVydF9maWx0ZXJfZGF0YVtrZXldID0gdmFsdWVzO1xuXHRcdFx0XHQvL29ubHkgYWRkIHNlYXJjaCBmaWx0ZXIgd2hpY2ggbm90IGVxdWFsIHRvIGZhbHNlLCBzZWUgaWYgdGhpcyBjYXVzZSBhbnkgYnVnc1xuXHRcdFx0fSBlbHNlIGlmICggY29udGVudC52YWx1ZSBpbnN0YW5jZW9mIE9iamVjdCApIHtcblx0XHRcdFx0dmFyIGZpbmFsX3ZhbHVlID0gJyc7XG5cdFx0XHRcdGlmICggR2xvYmFsLmlzU2V0KCBjb250ZW50LnZhbHVlLnZhbHVlICkgKSB7XG5cdFx0XHRcdFx0ZmluYWxfdmFsdWUgPSBjb250ZW50LnZhbHVlLnZhbHVlOyAvL09wdGlvbnMsXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGNvbnRlbnQudmFsdWUuaWQgfHwgY29udGVudC52YWx1ZS5pZCA9PT0gMCB8fCBjb250ZW50LnZhbHVlLmlkID09PSAnMCcgKSB7XG5cdFx0XHRcdFx0ZmluYWxfdmFsdWUgPSBjb250ZW50LnZhbHVlLmlkOyAvL0F3ZXNvbWVib3hcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRmaW5hbF92YWx1ZSA9IGNvbnRlbnQudmFsdWU7IC8vIGRlZmF1bHRfZmlsdGVyX2RhdGFfZm9yX25leHRfdmlld1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29udmVydF9maWx0ZXJfZGF0YVtrZXldID0gZmluYWxfdmFsdWU7XG5cblx0XHRcdH0gZWxzZSBpZiAoIG9iai52YWx1ZSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdHJldHVybjsvL2NvbnRpbnVlO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIG9iai52YWx1ZSApICkge1xuXG5cdFx0XHRcdFx0Y29udmVydF9maWx0ZXJfZGF0YVtrZXldID0gb2JqLnZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgaWYgKCBmaWx0ZXJfZGF0YVtrZXldLnZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjsgLy9jb250aW51ZTtcblx0XHR9IGVsc2UgaWYgKCBHbG9iYWwuaXNTZXQoIGZpbHRlcl9kYXRhW2tleV0udmFsdWUgKSApIHtcblx0XHRcdGNvbnZlcnRfZmlsdGVyX2RhdGFba2V5XSA9IGZpbHRlcl9kYXRhW2tleV0udmFsdWU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnZlcnRfZmlsdGVyX2RhdGFba2V5XSA9IGZpbHRlcl9kYXRhW2tleV07XG5cdFx0fVxuXHR9ICk7XG5cblx0aWYgKCBMb2NhbENhY2hlRGF0YS5leHRyYV9maWx0ZXJfZm9yX25leHRfb3Blbl92aWV3ICkgeyAvL01VU1QgcmVtb3ZlZCB0aGlzIHdoZW4gY2xvc2UgdGhlIHZpZXcgd2hpY2ggdXNlZCB0aGlzIGF0dHJpYnV0ZS5cblxuXHRcdGZvciAoIHZhciBrZXkgaW4gTG9jYWxDYWNoZURhdGEuZXh0cmFfZmlsdGVyX2Zvcl9uZXh0X29wZW5fdmlldy5maWx0ZXJfZGF0YSApIHtcblx0XHRcdGNvbnZlcnRfZmlsdGVyX2RhdGFba2V5XSA9IExvY2FsQ2FjaGVEYXRhLmV4dHJhX2ZpbHRlcl9mb3JfbmV4dF9vcGVuX3ZpZXcuZmlsdGVyX2RhdGFba2V5XTtcblx0XHR9XG5cblx0fVxuXG5cdHJldHVybiBjb252ZXJ0X2ZpbHRlcl9kYXRhO1xuXG59O1xuLyoganNoaW50IGlnbm9yZTplbmQgKi9cblxuLy9BU0Ncbkdsb2JhbC5jb21wYXJlID0gZnVuY3Rpb24oIGEsIGIsIG9yZGVyS2V5LCBvcmRlcl90eXBlICkge1xuXG5cdGlmICggIUdsb2JhbC5pc1NldCggb3JkZXJfdHlwZSApICkge1xuXHRcdG9yZGVyX3R5cGUgPSAnYXNjJztcblx0fVxuXG5cdGlmICggb3JkZXJfdHlwZSA9PT0gJ2FzYycgKSB7XG5cdFx0aWYgKCBhW29yZGVyS2V5XSA8IGJbb3JkZXJLZXldICkge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpZiAoIGFbb3JkZXJLZXldID4gYltvcmRlcktleV0gKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH0gZWxzZSB7XG5cdFx0aWYgKCBhW29yZGVyS2V5XSA8IGJbb3JkZXJLZXldICkge1xuXHRcdFx0cmV0dXJuIDE7XG5cdFx0fVxuXHRcdGlmICggYVtvcmRlcktleV0gPiBiW29yZGVyS2V5XSApIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxufTtcblxuR2xvYmFsLmJ1aWxkRmlsdGVyID0gZnVuY3Rpb24oKSB7XG5cdHZhciBmaWx0ZXJDb25kaXRpb24gPSBhcmd1bWVudHNbMF07XG5cdHZhciBmaWx0ZXIgPSBbXTtcblxuXHRpZiAoIGZpbHRlckNvbmRpdGlvbiApIHtcblxuXHRcdGZvciAoIHZhciBrZXkgaW4gZmlsdGVyQ29uZGl0aW9uICkge1xuXHRcdFx0ZmlsdGVyW2tleV0gPSBmaWx0ZXJDb25kaXRpb25ba2V5XTtcblx0XHR9XG5cblx0fVxuXG5cdHJldHVybiBmaWx0ZXI7XG5cbn07XG5cbkdsb2JhbC5nZXRMb2dpblVzZXJEYXRlRm9ybWF0ID0gZnVuY3Rpb24oKSB7XG5cdHZhciBmb3JtYXQgPSAnREQtTU1NLVlZJztcblxuXHRpZiAoIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKSApIHtcblx0XHRmb3JtYXQgPSBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkuZGF0ZV9mb3JtYXQ7XG5cdH1cblxuXHRyZXR1cm4gZm9ybWF0O1xufTtcbi8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbkdsb2JhbC5mb3JtYXRHcmlkRGF0YSA9IGZ1bmN0aW9uKCBncmlkX2RhdGEsIGtleV9uYW1lICkge1xuXG5cdGlmICggJC50eXBlKCBncmlkX2RhdGEgKSAhPT0gJ2FycmF5JyApIHtcblx0XHRyZXR1cm4gZ3JpZF9kYXRhO1xuXHR9XG5cblx0Zm9yICggdmFyIGkgPSAwOyBpIDwgZ3JpZF9kYXRhLmxlbmd0aDsgaSsrICkge1xuXHRcdGZvciAoIHZhciBrZXkgaW4gZ3JpZF9kYXRhW2ldICkge1xuXG5cdFx0XHRpZiAoICFncmlkX2RhdGFbaV0uaGFzT3duUHJvcGVydHkoIGtleSApICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vTmVlZCB0byBjb252ZXJ0IGN1c3RvbSBmaWVsZHMgdGltZV91bml0IHRvIHN0cmluZ1xuXHRcdFx0aWYgKCBrZXkuaW5kZXhPZiggJ2N1c3RvbV9maWVsZCcgKSA9PT0gMCAmJiBBcnJheS5pc0FycmF5KCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmN1c3RvbV9maWVsZHMgKSApIHtcblx0XHRcdFx0bGV0IGN1c3RvbV9maWVsZCA9IExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuY3VzdG9tX2ZpZWxkcy5maW5kKCAoIGZpZWxkICkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiBmaWVsZC5pZCA9PT0ga2V5LnJlcGxhY2UoICdjdXN0b21fZmllbGQtJywgJycgKTtcblx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdGlmICggY3VzdG9tX2ZpZWxkICYmIGN1c3RvbV9maWVsZC50eXBlX2lkID09IDEzMDAgKSB7XG5cdFx0XHRcdFx0aWYgKCBHbG9iYWwuaXNOdW1lcmljKCBncmlkX2RhdGFbaV1ba2V5XSApICkge1xuXHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldW2tleV0gPSBHbG9iYWwuZ2V0VGltZVVuaXQoIGdyaWRfZGF0YVtpXVtrZXldICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRoZSBzYW1lIGZvcm1hdCBmb3IgYWxsIHZpZXdzLlxuXHRcdFx0c3dpdGNoICgga2V5ICkge1xuXHRcdFx0XHRjYXNlICdtYXhpbXVtX3NoaWZ0X3RpbWUnOlxuXHRcdFx0XHRjYXNlICduZXdfZGF5X3RyaWdnZXJfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ3RyaWdnZXJfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ21pbmltdW1fcHVuY2hfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ21heGltdW1fcHVuY2hfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ3dpbmRvd19sZW5ndGgnOlxuXHRcdFx0XHRjYXNlICdzdGFydF93aW5kb3cnOlxuXHRcdFx0XHRjYXNlICdyb3VuZF9pbnRlcnZhbCc6XG5cdFx0XHRcdGNhc2UgJ2dyYWNlJzpcblx0XHRcdFx0Y2FzZSAnZXN0aW1hdGVfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ21pbmltdW1fdGltZSc6XG5cdFx0XHRcdGNhc2UgJ21heGltdW1fdGltZSc6XG5cdFx0XHRcdGNhc2UgJ3RvdGFsX3RpbWUnOlxuXHRcdFx0XHRjYXNlICdzdGFydF9zdG9wX3dpbmRvdyc6XG5cdFx0XHRcdFx0aWYgKCBHbG9iYWwuaXNOdW1lcmljKCBncmlkX2RhdGFbaV1ba2V5XSApICkge1xuXHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldW2tleV0gPSBHbG9iYWwuZ2V0VGltZVVuaXQoIGdyaWRfZGF0YVtpXVtrZXldICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gbnVsbDsgLy9QcmV2ZW50IHN0cmluZyBcImZhbHNlXCIgZnJvbSBiZWluZyByZXR1cm5lZCB3aGVuIHRoZSBjb2x1bW4gaXNuJ3QgZGVmaW5lZCBvbiB0aGUgc2VydmVyIHNpZGUuXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICdpbmNsdWRlX2JyZWFrX3B1bmNoX3RpbWUnOlxuXHRcdFx0XHRjYXNlICdpbmNsdWRlX211bHRpcGxlX2JyZWFrcyc6XG5cdFx0XHRcdGNhc2UgJ2luY2x1ZGVfbHVuY2hfcHVuY2hfdGltZSc6XG5cdFx0XHRcdGNhc2UgJ2lzX2RlZmF1bHQnOlxuXHRcdFx0XHRjYXNlICdpc19iYXNlJzpcblx0XHRcdFx0Y2FzZSAnYXV0b191cGRhdGUnOlxuXHRcdFx0XHRjYXNlICdjdXJyZW50bHlfZW1wbG95ZWQnOlxuXHRcdFx0XHRjYXNlICdjcmltaW5hbF9yZWNvcmQnOlxuXHRcdFx0XHRjYXNlICdpbW1lZGlhdGVfZHJ1Z190ZXN0Jzpcblx0XHRcdFx0Y2FzZSAnaXNfY3VycmVudF9lbXBsb3llcic6XG5cdFx0XHRcdGNhc2UgJ2lzX2NvbnRhY3RfYXZhaWxhYmxlJzpcblx0XHRcdFx0Y2FzZSAnZW5hYmxlX3BheV9zdHViX2JhbGFuY2VfZGlzcGxheSc6XG5cdFx0XHRcdGNhc2UgJ2VuYWJsZV9sb2dpbic6XG5cdFx0XHRcdGNhc2UgJ3l0ZF9hZGp1c3RtZW50Jzpcblx0XHRcdFx0Y2FzZSAnYXV0aG9yaXplZCc6XG5cdFx0XHRcdGNhc2UgJ2lzX3JlaW1idXJzYWJsZSc6XG5cdFx0XHRcdGNhc2UgJ3JlaW1idXJzYWJsZSc6XG5cdFx0XHRcdGNhc2UgJ3RhaW50ZWQnOlxuXHRcdFx0XHRjYXNlICdhdXRvX2ZpbGwnOlxuXHRcdFx0XHRjYXNlICdwcml2YXRlJzpcblx0XHRcdFx0XHRpZiAoIGdyaWRfZGF0YVtpXVtrZXldID09PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldW2tleV0gPSAkLmkxOG4uXyggJ1llcycgKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBncmlkX2RhdGFbaV1ba2V5XSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1ba2V5XSA9ICQuaTE4bi5fKCAnTm8nICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICdvdmVycmlkZSc6XG5cdFx0XHRcdFx0aWYgKCBncmlkX2RhdGFbaV1ba2V5XSA9PT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gJC5pMThuLl8oICdZZXMnICk7XG5cdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1bJ2lzX292ZXJyaWRlJ10gPSB0cnVlO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoIGdyaWRfZGF0YVtpXVtrZXldID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gJC5pMThuLl8oICdObycgKTtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVsnaXNfb3ZlcnJpZGUnXSA9IGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnaXNfc2NoZWR1bGVkJzpcblx0XHRcdFx0XHRpZiAoIGdyaWRfZGF0YVtpXVtrZXldID09PSAnMScgKSB7XG5cdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1ba2V5XSA9ICQuaTE4bi5fKCAnWWVzJyApO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoIGdyaWRfZGF0YVtpXVtrZXldID09PSAnMCcgKSB7XG5cdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1ba2V5XSA9ICQuaTE4bi5fKCAnTm8nICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICdpbl91c2UnOlxuXHRcdFx0XHRcdGlmICggZ3JpZF9kYXRhW2ldW2tleV0gPT09ICcxJyApIHtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gJC5pMThuLl8oICdZZXMnICk7XG5cdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1bJ2lzX2luX3VzZSddID0gdHJ1ZTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBncmlkX2RhdGFbaV1ba2V5XSA9PT0gJzAnICkge1xuXHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldW2tleV0gPSAkLmkxOG4uXyggJ05vJyApO1xuXHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldWydpc19pbl91c2UnXSA9IGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRpZiAoIGdyaWRfZGF0YVtpXVtrZXldID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gJyc7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBIYW5kbGUgdGhlIHNwZWNpYWxseSBmb3JtYXQgY29sdW1ucyB3aGljaCBhcmUgbm90IGRpZmZlcmVudCB3aXRoIG90aGVycy5cblx0XHRcdHN3aXRjaCAoIGtleV9uYW1lICkge1xuXHRcdFx0XHRjYXNlICdBY2NydWFsUG9saWN5VXNlck1vZGlmaWVyJzpcblx0XHRcdFx0XHRzd2l0Y2ggKCBrZXkgKSB7XG5cdFx0XHRcdFx0XHRjYXNlICdhbm51YWxfbWF4aW11bV90aW1lX21vZGlmaWVyJzpcblx0XHRcdFx0XHRcdFx0aWYgKCBncmlkX2RhdGFbaV1bJ3R5cGVfaWQnXSA9PT0gMjAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Z3JpZF9kYXRhW2ldW2tleV0gPSAkLmkxOG4uXyggJ04vQScgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgJ0JyZWFrUG9saWN5Jzpcblx0XHRcdFx0Y2FzZSAnTWVhbFBvbGljeSc6XG5cdFx0XHRcdGNhc2UgJ0FjY3J1YWwnOlxuXHRcdFx0XHRcdHN3aXRjaCAoIGtleSApIHtcblx0XHRcdFx0XHRcdGNhc2UgJ2Ftb3VudCc6XG5cdFx0XHRcdFx0XHRcdGlmICggR2xvYmFsLmlzTnVtZXJpYyggZ3JpZF9kYXRhW2ldW2tleV0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1ba2V5XSA9IEdsb2JhbC5nZXRUaW1lVW5pdCggZ3JpZF9kYXRhW2ldW2tleV0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnYWNjcnVhbF9iYWxhbmNlX3N1bW1hcnknOlxuXHRcdFx0XHRjYXNlICdBY2NydWFsQmFsYW5jZSc6XG5cdFx0XHRcdFx0c3dpdGNoICgga2V5ICkge1xuXHRcdFx0XHRcdFx0Y2FzZSAnYmFsYW5jZSc6XG5cdFx0XHRcdFx0XHRcdGlmICggR2xvYmFsLmlzTnVtZXJpYyggZ3JpZF9kYXRhW2ldW2tleV0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHRncmlkX2RhdGFbaV1ba2V5XSA9IEdsb2JhbC5nZXRUaW1lVW5pdCggZ3JpZF9kYXRhW2ldW2tleV0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnUmVjdXJyaW5nU2NoZWR1bGVDb250cm9sJzpcblx0XHRcdFx0XHRzd2l0Y2ggKCBrZXkgKSB7XG5cdFx0XHRcdFx0XHRjYXNlICdlbmRfZGF0ZSc6XG5cdFx0XHRcdFx0XHRcdGlmICggZ3JpZF9kYXRhW2ldW2tleV0gPT09ICcnICkge1xuXHRcdFx0XHRcdFx0XHRcdGdyaWRfZGF0YVtpXVtrZXldID0gJ05ldmVyJztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZ3JpZF9kYXRhO1xuXG59O1xuLyoganNoaW50IGlnbm9yZTplbmQgKi9cblxuLy8gQ29tbWVudGVkIG91dCBhcyB3ZSBoYXZlIG5vdyBmdWxseSByZWZhY3RvcmVkIHRoZSBvbGQgX3N1cGVyIGFuZCBfX3N1cGVyIHJlZmVyZW5jZXMgaW4gdGhlIG5ldyBFUzYgY29kZS5cbi8vIC8vbWFrZSBiYWNrb25lIHN1cHBvcnQgYSBzaW1wbGUgc3VwZXIgZnVuY2l0b25cbi8vIEJhY2tib25lLk1vZGVsLnByb3RvdHlwZS5fc3VwZXIgPSBmdW5jdGlvbiggZnVuY05hbWUgKSB7XG4vLyBcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLl9fc3VwZXJfX1tmdW5jTmFtZV0uYXBwbHkoIHRoaXMsIF8ucmVzdCggYXJndW1lbnRzICkgKTtcbi8vIH07XG4vL1xuLy8gLy9tYWtlIGJhY2tvbmUgc3VwcG9ydCBhIHNpbXBsZSBzdXBlciBmdW5jdGlvblxuLy8gQmFja2JvbmUuVmlldy5wcm90b3R5cGUuX3N1cGVyID0gZnVuY3Rpb24oIGZ1bmNOYW1lICkge1xuLy8gXHQvLyBOb3RlOiBJZiAnTWF4aW11bSBjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWQnIGVycm9yIGVuY291bnRlcmVkLCBhbmQgdmlldyBpcyBleHRlbmRpbmcgdHdpY2UgKEJhc2VWaWV3LT5SZXBvcnRCYXNlVmlldy0+U29tZVJhbmRvbVZpZXcpLCB0aGVuIG1ha2Ugc3VyZSB5b3UgZGVmaW5lIGB0aGlzLnJlYWxfdGhpc2AgYXQgdGhlIDJuZCBsZXZlbCBleHRlbmQuIFNlZSByZXBvcnRCYXNlVmlld0NvbnRyb2xsZXIgaW5pdCBmb3IgZXhhbXBsZS5cbi8vIFx0aWYgKCB0aGlzLnJlYWxfdGhpcyAmJiB0aGlzLnJlYWxfdGhpcy5jb25zdHJ1Y3Rvci5fX3N1cGVyX19bZnVuY05hbWVdICkge1xuLy8gXHRcdHJldHVybiB0aGlzLnJlYWxfdGhpcy5jb25zdHJ1Y3Rvci5fX3N1cGVyX19bZnVuY05hbWVdLmFwcGx5KCB0aGlzLCBfLnJlc3QoIGFyZ3VtZW50cyApICk7XG4vLyBcdH0gZWxzZSB7XG4vLyBcdFx0cmV0dXJuIHRoaXMuY29uc3RydWN0b3IuX19zdXBlcl9fW2Z1bmNOYW1lXS5hcHBseSggdGhpcywgXy5yZXN0KCBhcmd1bWVudHMgKSApO1xuLy8gXHR9XG4vL1xuLy8gfTtcbi8vXG4vLyAvL21ha2UgYmFja29uZSBzdXBwb3J0IGEgc2ltcGxlIHN1cGVyIGZ1bmNpdG9uIGZvciBzZWNvbmQgbGV2ZWwgY2xhc3Ncbi8vIEJhY2tib25lLlZpZXcucHJvdG90eXBlLl9fc3VwZXIgPSBmdW5jdGlvbiggZnVuY05hbWUgKSB7XG4vLyBcdGlmICggIXRoaXMucmVhbF90aGlzICkge1xuLy8gXHRcdHRoaXMucmVhbF90aGlzID0gdGhpcy5jb25zdHJ1Y3Rvci5fX3N1cGVyX187XG4vLyBcdH1cbi8vXG4vLyBcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLl9fc3VwZXJfX1tmdW5jTmFtZV0uYXBwbHkoIHRoaXMsIF8ucmVzdCggYXJndW1lbnRzICkgKTtcbi8vXG4vLyB9O1xuXG4vKlxuICogRGF0ZSBGb3JtYXQgMS4yLjNcbiAqIChjKSAyMDA3LTIwMDkgU3RldmVuIExldml0aGFuIDxzdGV2ZW5sZXZpdGhhbi5jb20+XG4gKiBNSVQgbGljZW5zZVxuICpcbiAqIEluY2x1ZGVzIGVuaGFuY2VtZW50cyBieSBTY290dCBUcmVuZGEgPHNjb3R0LnRyZW5kYS5uZXQ+XG4gKiBhbmQgS3JpcyBLb3dhbCA8Y2l4YXIuY29tL35rcmlzLmtvd2FsPlxuICpcbiAqIEFjY2VwdHMgYSBkYXRlLCBhIG1hc2ssIG9yIGEgZGF0ZSBhbmQgYSBtYXNrLlxuICogUmV0dXJucyBhIGZvcm1hdHRlZCB2ZXJzaW9uIG9mIHRoZSBnaXZlbiBkYXRlLlxuICogVGhlIGRhdGUgZGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgZGF0ZS90aW1lLlxuICogVGhlIG1hc2sgZGVmYXVsdHMgdG8gZGF0ZUZvcm1hdC5tYXNrcy5kZWZhdWx0LlxuICovXG5cbnZhciBkYXRlRm9ybWF0ID0gZnVuY3Rpb24oKSB7XG5cdHZhciB0b2tlbiA9IC9kezEsNH18bXsxLDR9fHl5KD86eXkpP3woW0hoTXNUdF0pXFwxP3xbTGxvU1pdfCdbXiddKlwifCdbXiddKicvZyxcblx0XHR0aW1lem9uZSA9IC9cXGIoPzpbUE1DRUFdW1NEUF1UfCg/OlBhY2lmaWN8TW91bnRhaW58Q2VudHJhbHxFYXN0ZXJufEF0bGFudGljKSAoPzpTdGFuZGFyZHxEYXlsaWdodHxQcmV2YWlsaW5nKSBUaW1lfCg/OkdNVHxVVEMpKD86Wy0rXVxcZHs0fSk/KVxcYi9nLFxuXHRcdHRpbWV6b25lQ2xpcCA9IC9bXi0rXFxkQS1aXS9nLFxuXHRcdHBhZCA9IGZ1bmN0aW9uKCB2YWwsIGxlbiApIHtcblx0XHRcdHZhbCA9IFN0cmluZyggdmFsICk7XG5cdFx0XHRsZW4gPSBsZW4gfHwgMjtcblx0XHRcdHdoaWxlICggdmFsLmxlbmd0aCA8IGxlbiApIHtcblx0XHRcdFx0dmFsID0gJzAnICsgdmFsO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHZhbDtcblx0XHR9O1xuXG5cdC8vIFJlZ2V4ZXMgYW5kIHN1cHBvcnRpbmcgZnVuY3Rpb25zIGFyZSBjYWNoZWQgdGhyb3VnaCBjbG9zdXJlXG5cblx0LyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuXHRyZXR1cm4gZnVuY3Rpb24oIGRhdGUsIG1hc2ssIHV0YyApIHtcblx0XHR2YXIgZEYgPSBkYXRlRm9ybWF0O1xuXG5cdFx0Ly8gWW91IGNhbid0IHByb3ZpZGUgdXRjIGlmIHlvdSBza2lwIG90aGVyIGFyZ3MgKHVzZSB0aGUgJ1VUQzonIG1hc2sgcHJlZml4KVxuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoIGRhdGUgKSA9PT0gJ1tvYmplY3QgU3RyaW5nXScgJiYgIS9cXGQvLnRlc3QoIGRhdGUgKSApIHtcblx0XHRcdG1hc2sgPSBkYXRlO1xuXHRcdFx0ZGF0ZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBQYXNzaW5nIGRhdGUgdGhyb3VnaCBEYXRlIGFwcGxpZXMgRGF0ZS5wYXJzZSwgaWYgbmVjZXNzYXJ5XG5cdFx0ZGF0ZSA9IGRhdGUgPyBuZXcgRGF0ZSggZGF0ZSApIDogbmV3IERhdGUoKTtcblx0XHRpZiAoIGlzTmFOKCBkYXRlICkgKSB7XG5cdFx0XHR0aHJvdyBTeW50YXhFcnJvciggJ2ludmFsaWQgZGF0ZScgKTtcblx0XHR9XG5cblx0XHRtYXNrID0gU3RyaW5nKCBkRi5tYXNrc1ttYXNrXSB8fCBtYXNrIHx8IGRGLm1hc2tzWydkZWZhdWx0J10gKTtcblxuXHRcdC8vIEFsbG93IHNldHRpbmcgdGhlIHV0YyBhcmd1bWVudCB2aWEgdGhlIG1hc2tcblx0XHRpZiAoIG1hc2suc2xpY2UoIDAsIDQgKSA9PT0gJ1VUQzonICkge1xuXHRcdFx0bWFzayA9IG1hc2suc2xpY2UoIDQgKTtcblx0XHRcdHV0YyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0dmFyIF8gPSB1dGMgPyAnZ2V0VVRDJyA6ICdnZXQnLFxuXHRcdFx0ZCA9IGRhdGVbXyArICdEYXRlJ10oKSxcblx0XHRcdEQgPSBkYXRlW18gKyAnRGF5J10oKSxcblx0XHRcdG0gPSBkYXRlW18gKyAnTW9udGgnXSgpLFxuXHRcdFx0eSA9IGRhdGVbXyArICdGdWxsWWVhciddKCksXG5cdFx0XHRIID0gZGF0ZVtfICsgJ0hvdXJzJ10oKSxcblx0XHRcdE0gPSBkYXRlW18gKyAnTWludXRlcyddKCksXG5cdFx0XHRzID0gZGF0ZVtfICsgJ1NlY29uZHMnXSgpLFxuXHRcdFx0TCA9IGRhdGVbXyArICdNaWxsaXNlY29uZHMnXSgpLFxuXHRcdFx0byA9IHV0YyA/IDAgOiBkYXRlLmdldFRpbWV6b25lT2Zmc2V0KCksXG5cdFx0XHRmbGFncyA9IHtcblx0XHRcdFx0ZDogZCxcblx0XHRcdFx0ZGQ6IHBhZCggZCApLFxuXHRcdFx0XHRkZGQ6IGRGLmkxOG4uZGF5TmFtZXNbRF0sXG5cdFx0XHRcdGRkZGQ6IGRGLmkxOG4uZGF5TmFtZXNbRCArIDddLFxuXHRcdFx0XHRtOiBtICsgMSxcblx0XHRcdFx0bW06IHBhZCggbSArIDEgKSxcblx0XHRcdFx0bW1tOiBkRi5pMThuLm1vbnRoTmFtZXNbbV0sXG5cdFx0XHRcdG1tbW06IGRGLmkxOG4ubW9udGhOYW1lc1ttICsgMTJdLFxuXHRcdFx0XHR5eTogU3RyaW5nKCB5ICkuc2xpY2UoIDIgKSxcblx0XHRcdFx0eXl5eTogeSxcblx0XHRcdFx0aDogSCAlIDEyIHx8IDEyLFxuXHRcdFx0XHRoaDogcGFkKCBIICUgMTIgfHwgMTIgKSxcblx0XHRcdFx0SDogSCxcblx0XHRcdFx0SEg6IHBhZCggSCApLFxuXHRcdFx0XHRNOiBNLFxuXHRcdFx0XHRNTTogcGFkKCBNICksXG5cdFx0XHRcdHM6IHMsXG5cdFx0XHRcdHNzOiBwYWQoIHMgKSxcblx0XHRcdFx0bDogcGFkKCBMLCAzICksXG5cdFx0XHRcdEw6IHBhZCggTCA+IDk5ID8gTWF0aC5yb3VuZCggTCAvIDEwICkgOiBMICksXG5cdFx0XHRcdHQ6IEggPCAxMiA/ICdhJyA6ICdwJyxcblx0XHRcdFx0dHQ6IEggPCAxMiA/ICdhbScgOiAncG0nLFxuXHRcdFx0XHRUOiBIIDwgMTIgPyAnQScgOiAnUCcsXG5cdFx0XHRcdFRUOiBIIDwgMTIgPyAnQU0nIDogJ1BNJyxcblx0XHRcdFx0WjogdXRjID8gJ1VUQycgOiAoIFN0cmluZyggZGF0ZSApLm1hdGNoKCB0aW1lem9uZSApIHx8IFsnJ10gKS5wb3AoKS5yZXBsYWNlKCB0aW1lem9uZUNsaXAsICcnICksXG5cdFx0XHRcdG86ICggbyA+IDAgPyAnLScgOiAnKycgKSArIHBhZCggTWF0aC5mbG9vciggTWF0aC5hYnMoIG8gKSAvIDYwICkgKiAxMDAgKyBNYXRoLmFicyggbyApICUgNjAsIDQgKSxcblx0XHRcdFx0UzogWyd0aCcsICdzdCcsICduZCcsICdyZCddW2QgJSAxMCA+IDMgPyAwIDogKCBkICUgMTAwIC0gZCAlIDEwICE9PSAxMCApICogZCAlIDEwXVxuXHRcdFx0fTtcblxuXHRcdHJldHVybiBtYXNrLnJlcGxhY2UoIHRva2VuLCBmdW5jdGlvbiggJDAgKSB7XG5cdFx0XHRyZXR1cm4gJDAgaW4gZmxhZ3MgPyBmbGFnc1skMF0gOiAkMC5zbGljZSggMSwgJDAubGVuZ3RoIC0gMSApO1xuXHRcdH0gKTtcblx0fTtcblx0LyoganNoaW50IGlnbm9yZTplbmQgKi9cbn0oKTtcblxuLy8gU29tZSBjb21tb24gZm9ybWF0IHN0cmluZ3NcbmRhdGVGb3JtYXQubWFza3MgPSB7XG5cdCdkZWZhdWx0JzogJ2RkZCBtbW0gZGQgeXl5eSBISDpNTTpzcycsXG5cdHNob3J0RGF0ZTogJ20vZC95eScsXG5cdG1lZGl1bURhdGU6ICdtbW0gZCwgeXl5eScsXG5cdGxvbmdEYXRlOiAnbW1tbSBkLCB5eXl5Jyxcblx0ZnVsbERhdGU6ICdkZGRkLCBtbW1tIGQsIHl5eXknLFxuXHRzaG9ydFRpbWU6ICdoOk1NIFRUJyxcblx0bWVkaXVtVGltZTogJ2g6TU06c3MgVFQnLFxuXHRsb25nVGltZTogJ2g6TU06c3MgVFQgWicsXG5cdGlzb0RhdGU6ICd5eXl5LW1tLWRkJyxcblx0aXNvVGltZTogJ0hIOk1NOnNzJyxcblx0aXNvRGF0ZVRpbWU6ICd5eXl5LW1tLWRkXFwnVFxcJ0hIOk1NOnNzJyxcblx0aXNvVXRjRGF0ZVRpbWU6ICdVVEM6eXl5eS1tbS1kZFxcJ1RcXCdISDpNTTpzc1xcJ1pcXCcnXG59O1xuXG4vLyBJbnRlcm5hdGlvbmFsaXphdGlvbiBzdHJpbmdzXG5kYXRlRm9ybWF0LmkxOG4gPSB7XG5cdGRheU5hbWVzOiBbXG5cdFx0J1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCcsXG5cdFx0J1N1bmRheScsICdNb25kYXknLCAnVHVlc2RheScsICdXZWRuZXNkYXknLCAnVGh1cnNkYXknLCAnRnJpZGF5JywgJ1NhdHVyZGF5J1xuXHRdLFxuXHRtb250aE5hbWVzOiBbXG5cdFx0J0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJywgJ09jdCcsICdOb3YnLCAnRGVjJyxcblx0XHQnSmFudWFyeScsICdGZWJydWFyeScsICdNYXJjaCcsICdBcHJpbCcsICdNYXknLCAnSnVuZScsICdKdWx5JywgJ0F1Z3VzdCcsICdTZXB0ZW1iZXInLCAnT2N0b2JlcicsICdOb3ZlbWJlcicsICdEZWNlbWJlcidcblx0XVxufTtcblxuLy8gRm9yIGNvbnZlbmllbmNlLi4uXG5EYXRlLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbiggbWFzaywgdXRjICkge1xuXHQvL0pTIEV4Y2VwdGlvbjogVW5jYXVnaHQgVHlwZUVycm9yOiBDYW5ub3QgcmVhZCBwcm9wZXJ0aWVzIG9mIHVuZGVmaW5lZCAocmVhZGluZyAnZGF0ZV9mb3JtYXQnKVxuXHRpZiAoICFHbG9iYWwuaXNTZXQoIG1hc2sgKSAmJiBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXJQcmVmZXJlbmNlKCkgKSB7XG5cdFx0bWFzayA9IExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlclByZWZlcmVuY2UoKS5kYXRlX2Zvcm1hdDtcblx0fVxuXG5cdGlmICggIW1hc2sgKSB7XG5cdFx0bWFzayA9ICdERC1NTU0tWVknO1xuXHR9XG5cblx0dmFyIGZvcm1hdF9zdHIgPSBtb21lbnQoIHRoaXMgKS5mb3JtYXQoIG1hc2sgKTtcblxuXHRyZXR1cm4gZm9ybWF0X3N0cjtcbn07XG5cbndpbmRvdy5SaWdodENsaWNrTWVudVR5cGUgPSBmdW5jdGlvbigpIHtcblxufTtcblxuUmlnaHRDbGlja01lbnVUeXBlLkxJU1RWSUVXID0gJzEnO1xuUmlnaHRDbGlja01lbnVUeXBlLkVESVRWSUVXID0gJzInO1xuUmlnaHRDbGlja01lbnVUeXBlLk5PUkVTVUxUQk9YID0gJzMnO1xuUmlnaHRDbGlja01lbnVUeXBlLkFCU0VOQ0VfR1JJRCA9ICc0JztcblJpZ2h0Q2xpY2tNZW51VHlwZS5WSUVXX0lDT04gPSAnNSc7XG5cbi8qKlxuICogRGVjb2RpbmcgZW5jb2RlZCBodG1sIGVuaXRpdGllcyAoaWU6IFwiJmd0O1wiKVxuICogdG8gYXZvaWQgWFNTIHZ1bG5lcmFiaWxpdGllcyBkbyBub3QgZXZhbCBhbnl0aGluZyB0aGF0IGhhcyBnb25lIHRocm91Z2ggdGhpcyBmdW5jdGlvblxuICpcbiAqIEBwYXJhbSBzdHJcbiAqIEByZXR1cm5zIHsqfGpRdWVyeX1cbiAqL1xuR2xvYmFsLmh0bWxEZWNvZGUgPSBmdW5jdGlvbiggc3RyICkge1xuXHRyZXR1cm4gJCggJzx0ZXh0YXJlYT48L3RleHRhcmVhPicgKS5odG1sKCBzdHIgKS50ZXh0KCk7XG59O1xuXG5HbG9iYWwuaHRtbEVuY29kZSA9IGZ1bmN0aW9uKCBzdHIgKSB7XG5cdHZhciBlbmNvZGVkU3RyID0gc3RyO1xuXG5cdGlmICggZW5jb2RlZFN0ciApIHtcblx0XHQvLyBUaGlzIHJlcGxhY2VzICdTJyBpbiAnTVNUJyB3aXRoIHRoZSBlbmNvZGVkIHZhbHVlLCB3aGljaCBpcyBpbnZhbGlkLlxuXHRcdC8vIGVuY29kZWRTdHIgPSBzdHIucmVwbGFjZSggL1tcXHUwMEEwLVxcdTk5OTk8PlxcJ1wiXFwmXS9naW0sIGZ1bmN0aW9uKCBpICkge1xuXHRcdC8vIFx0cmV0dXJuICcmIycgKyBpLmNoYXJDb2RlQXQoIDAgKSArICc7Jztcblx0XHQvLyB9ICk7XG5cdFx0Ly8gZW5jb2RlZFN0ciA9IGVuY29kZWRTdHIucmVwbGFjZSggLyYjNjA7YnImIzYyOy9nLCAnPGJyPicgKTtcblx0XHQvLyByZXR1cm4gZW5jb2RlZFN0cjtcblxuXHRcdHZhciB0bXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnZGl2JyApO1xuXHRcdHRtcC50ZXh0Q29udGVudCA9IGVuY29kZWRTdHI7XG5cblx0XHRyZXR1cm4gdG1wLmlubmVySFRNTDtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gZW5jb2RlZFN0cjtcblx0fVxufTtcblxuLy9Tb3J0IGJ5IG1vZHVsZVxuXG5HbG9iYWwubV9zb3J0X2J5ID0gKCBmdW5jdGlvbigpIHtcblx0Ly8gdXRpbGl0eSBmdW5jdGlvbnNcblxuXHR2YXIgZGVmYXVsdF9jbXAgPSBmdW5jdGlvbiggYSwgYiApIHtcblxuXHRcdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdH1cblxuXHRcdFx0Ly9TcGVpY2FsIGhhbmRsZSBPUEVOIG9wdGlvbiB0byBtYWtlIGl0IGFsd2F5cyBzdGF5IHRvZ2V0aGVyXG5cdFx0XHRpZiAoIGEgPT09IGZhbHNlIHx8IGEgPT09ICdPUEVOJyApIHtcblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGIgPT09IGZhbHNlIHx8IGIgPT09ICdPUEVOJyApIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBhIDwgYiA/IC0xIDogMTtcblx0XHR9LFxuXHRcdGdldENtcEZ1bmMgPSBmdW5jdGlvbiggcHJpbWVyLCByZXZlcnNlICkge1xuXHRcdFx0dmFyIGNtcCA9IGRlZmF1bHRfY21wO1xuXHRcdFx0aWYgKCBwcmltZXIgKSB7XG5cdFx0XHRcdGNtcCA9IGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdFx0XHRcdHJldHVybiBkZWZhdWx0X2NtcCggcHJpbWVyKCBhICksIHByaW1lciggYiApICk7XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0XHRpZiAoIHJldmVyc2UgKSB7XG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiggYSwgYiApIHtcblx0XHRcdFx0XHRyZXR1cm4gLTEgKiBjbXAoIGEsIGIgKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBjbXA7XG5cdFx0fTtcblxuXHQvLyBhY3R1YWwgaW1wbGVtZW50YXRpb25cblx0dmFyIHNvcnRfYnkgPSBmdW5jdGlvbiggc29ydF9ieV9hcnJheSApIHtcblx0XHR2YXIgZmllbGRzID0gW10sXG5cdFx0XHRuX2ZpZWxkcyA9IHNvcnRfYnlfYXJyYXkubGVuZ3RoLFxuXHRcdFx0ZmllbGQsIG5hbWUsIHJldmVyc2UsIGNtcDtcblxuXHRcdC8vIHByZXByb2Nlc3Mgc29ydGluZyBvcHRpb25zXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgbl9maWVsZHM7IGkrKyApIHtcblx0XHRcdGZpZWxkID0gc29ydF9ieV9hcnJheVtpXTtcblx0XHRcdGlmICggdHlwZW9mIGZpZWxkID09PSAnc3RyaW5nJyApIHtcblx0XHRcdFx0bmFtZSA9IGZpZWxkO1xuXHRcdFx0XHRjbXAgPSBkZWZhdWx0X2NtcDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG5hbWUgPSBmaWVsZC5uYW1lO1xuXHRcdFx0XHRjbXAgPSBnZXRDbXBGdW5jKCBmaWVsZC5wcmltZXIsIGZpZWxkLnJldmVyc2UgKTtcblx0XHRcdH1cblx0XHRcdGZpZWxkcy5wdXNoKCB7XG5cdFx0XHRcdG5hbWU6IG5hbWUsXG5cdFx0XHRcdGNtcDogY21wXG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZ1bmN0aW9uKCBBLCBCICkge1xuXHRcdFx0dmFyIGEsIGIsIG5hbWUsIGNtcCwgcmVzdWx0O1xuXHRcdFx0Zm9yICggdmFyIGkgPSAwLCBsID0gbl9maWVsZHM7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdHJlc3VsdCA9IDA7XG5cdFx0XHRcdGZpZWxkID0gZmllbGRzW2ldO1xuXHRcdFx0XHRuYW1lID0gZmllbGQubmFtZTtcblx0XHRcdFx0Y21wID0gZmllbGQuY21wO1xuXG5cdFx0XHRcdHJlc3VsdCA9IGNtcCggQVtuYW1lXSwgQltuYW1lXSApO1xuXHRcdFx0XHRpZiAoIHJlc3VsdCAhPT0gMCApIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9O1xuXHR9O1xuXG5cdHJldHVybiBzb3J0X2J5O1xuXG59KCkgKTtcblxuJC5mbi5pbnZpc2libGUgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0JCggdGhpcyApLmNzcyggJ29wYWNpdHknLCAnMCcgKTtcblx0fSApO1xufTtcbiQuZm4udmlzaWJsZSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHQkKCB0aGlzICkuY3NzKCAnb3BhY2l0eScsICcxJyApO1xuXHR9ICk7XG59O1xuXG5HbG9iYWwudHJhY2tWaWV3ID0gZnVuY3Rpb24oIG5hbWUsIGFjdGlvbiApIHtcblx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYW5hbHl0aWNzX2VuYWJsZWQgPT09IHRydWUgKSB7XG5cdFx0dmFyIHRyYWNrX2FkZHJlc3M7XG5cblx0XHQvL0hvc3RuYW1lIGlzIGFscmVhZHkgc2VudCBzZXBhcmF0ZWx5LCBzbyB0aGlzIHNob3VsZCBqdXN0IGJlIHRoZSB2aWV3L2FjdGlvbiBpbiBmb3JtYXQ6XG5cdFx0Ly8gJyMhbT0nICsgbmFtZSArICcmYT0nICsgYWN0aW9uXG5cdFx0aWYgKCBuYW1lICkge1xuXHRcdFx0dHJhY2tfYWRkcmVzcyA9ICcjIW09JyArIG5hbWU7XG5cblx0XHRcdGlmICggYWN0aW9uICkge1xuXHRcdFx0XHR0cmFja19hZGRyZXNzICs9ICcmYT0nICsgYWN0aW9uO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvL0RlZmF1bHQgdG8gb25seSBkYXRhIGFmdGVyIChhbmQgaW5jbHVkaW5nKSB0aGUgIy5cblx0XHRcdHRyYWNrX2FkZHJlc3MgPSB3aW5kb3cubG9jYXRpb24uaGFzaC5zdWJzdHJpbmcoIDEgKTtcblx0XHR9XG5cblx0XHQvL1RyYWNrIGFkZHJlc3MgaXMgc2VudCBpbiBzZW5kQW5hbHl0aWNzIGFzIHRoZSAzcmQgcGFyYW1ldGVyLlxuXHRcdEdsb2JhbC5zZW5kQW5hbHl0aWNzUGFnZXZpZXcoIHRyYWNrX2FkZHJlc3MgKTtcblx0fVxufTtcblxuR2xvYmFsLnNldEFuYWx5dGljRGltZW5zaW9ucyA9IGZ1bmN0aW9uKCB1c2VyX25hbWUsIGNvbXBhbnlfbmFtZSApIHtcblx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYW5hbHl0aWNzX2VuYWJsZWQgPT09IHRydWUgKSB7XG5cdFx0aWYgKCB0eXBlb2YgKCBndGFnICkgIT09ICd1bmRlZmluZWQnICkge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Ly9BbGwgbmFtZXMgbXVzdCBiZSBtYXBwZWQgaW4gbWFpbi5qcyAnY3VzdG9tX21hcCdcblx0XHRcdFx0dmFyIHVzZXJfcHJvcGVydGllcyA9IHtcblx0XHRcdFx0XHQnYXBwbGljYXRpb25fdmVyc2lvbic6IEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5hcHBsaWNhdGlvbl92ZXJzaW9uLFxuXHRcdFx0XHRcdCdodHRwX2hvc3QnOiBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuaHR0cF9ob3N0LFxuXHRcdFx0XHRcdCdwcm9kdWN0X2VkaXRpb25fbmFtZSc6IEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5wcm9kdWN0X2VkaXRpb25fbmFtZSxcblx0XHRcdFx0XHQncmVnaXN0cmF0aW9uX2tleSc6IEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5yZWdpc3RyYXRpb25fa2V5LFxuXHRcdFx0XHRcdCdwcmltYXJ5X2NvbXBhbnlfbmFtZSc6IEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5wcmltYXJ5X2NvbXBhbnlfbmFtZSxcblx0XHRcdFx0fTtcblxuXHRcdFx0XHRpZiAoIHVzZXJfbmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdXNlcl9uYW1lICE9PSBudWxsICkge1xuXHRcdFx0XHRcdGlmICggQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLnByb2R1Y3Rpb24gIT09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnQW5hbHl0aWNzIFVzZXI6ICcgKyB1c2VyX25hbWUsICdHbG9iYWwuanMnLCAnJywgJ2RvUGluZycsIDEgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dXNlcl9wcm9wZXJ0aWVzLnVzZXJfbmFtZSA9IHVzZXJfbmFtZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggY29tcGFueV9uYW1lICE9PSAndW5kZWZpbmVkJyAmJiBjb21wYW55X25hbWUgIT09IG51bGwgKSB7XG5cdFx0XHRcdFx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEucHJvZHVjdGlvbiAhPT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdERlYnVnLlRleHQoICdBbmFseXRpY3MgQ29tcGFueTogJyArIGNvbXBhbnlfbmFtZSwgJ0dsb2JhbC5qcycsICcnLCAnc2V0QW5hbHl0aWNEaW1lbnNpb25zJywgMSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR1c2VyX3Byb3BlcnRpZXMuY29tcGFueV9uYW1lID0gY29tcGFueV9uYW1lO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Z3RhZyggJ3NldCcsICd1c2VyX3Byb3BlcnRpZXMnLCB1c2VyX3Byb3BlcnRpZXMgKTtcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0XHR0aHJvdyBlOyAvL0F0dGVtcHQgdG8gY2F0Y2ggYW55IGVycm9ycyB0aHJvd24gYnkgR29vZ2xlIEFuYWx5dGljcy5cblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbkdsb2JhbC5zZW5kQW5hbHl0aWNzUGFnZXZpZXcgPSBmdW5jdGlvbiggdHJhY2tfYWRkcmVzcyApIHtcblx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEuYW5hbHl0aWNzX2VuYWJsZWQgPT09IHRydWUgKSB7XG5cdFx0Ly8gQ2FsbCB0aGlzIGRlbGF5IHNvIHZpZXcgbG9hZCBnb2VzIGZpcnN0XG5cdFx0aWYgKCB0eXBlb2YgKCBndGFnICkgIT09ICd1bmRlZmluZWQnICkge1xuXHRcdFx0c2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0Z3RhZyggJ2V2ZW50JywgJ3BhZ2VfdmlldycsIHsgcGFnZV9wYXRoOiB0cmFja19hZGRyZXNzIH0gKVxuXHRcdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0XHR0aHJvdyBlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LCA1MDAgKTtcblx0XHR9XG5cblx0fVxufTtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYWN0dWFsbHkgc3VibWl0IHRoZSBhbmFseXRpY3MgcmVxdWVzdCB0byBnb29nbGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRfY2F0ZWdvcnkgLSBDYXRlZ29yeSByZWxhdGluZyB0byB0aGUgZXZlbnQgdHJhY2tlZCwgZS5nLiBmZWVkYmFjayBvciBjb250ZXh0X21lbnVcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudF9hY3Rpb24gLSBXaGF0IHRyaWdnZXJlZCB0aGUgZXZlbnQuIEUuZy4gY2xpY2ssIGNhbmNlbC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudF9sYWJlbCAtIFRoaXMgaXMgb2Z0ZW4gYSBjb21ibyBvZiB0aGUgYWN0dWFsIHZhbHVlIHN0cmluZyBjb21iaW5lZCB3aXRoIHNvbWUgb2YgdGhlIGFib3ZlIGZpZWxkcywgZm9yIGNsYXJpdHkuIGUuZy4gc3VibWl0OmZlZWRiYWNrOnNhZFxuICovXG5HbG9iYWwuc2VuZEFuYWx5dGljc0V2ZW50ID0gZnVuY3Rpb24oIGV2ZW50X2NhdGVnb3J5LCBldmVudF9hY3Rpb24sIGV2ZW50X2xhYmVsICkge1xuXHRpZiAoIHR5cGVvZiAoIGd0YWcgKSAhPT0gJ3VuZGVmaW5lZCcgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmFuYWx5dGljc19lbmFibGVkID09PSB0cnVlICkge1xuXHRcdC8vRGVidWcuQXJyKCBmaWVsZHNPYmplY3QsICdTZW5kaW5nIGFuYWx5dGljcyBldmVudCBwYXlsb2FkLiBFdmVudDogJyArIGV2ZW50X2NhdGVnb3J5ICsgJywgQWN0aW9uOiAnICsgZXZlbnRfYWN0aW9uICsgJywgTGFiZWw6ICcgKyBldmVudF9sYWJlbCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnc2VuZEFuYWx5dGljc0V2ZW50JywgMTEgKTtcblx0XHR0cnkge1xuXHRcdFx0Z3RhZyggJ2V2ZW50JywgZXZlbnRfY2F0ZWdvcnksIHsgYWN0aW9uOiBldmVudF9hY3Rpb24sIGxhYmVsOiBldmVudF9sYWJlbCB9IClcblx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdHRocm93IGU7XG5cdFx0fVxuXHR9XG59O1xuXG4vKipcbiAqXG4gKiBAcGFyYW0gY29udGV4dF9idG4gLSB0aGUgalF1ZXJ5IGVsZW1lbnQgdGhhdCB0cmlnZ2VyZWQgdGhlIGNsaWNrIGV2ZW50IG9uIHRoZSBjb250ZXh0IG1lbnVcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZW51X25hbWUgLSB0aGUgbmFtZSBvZiB0aGUgaWNvbiBpZiB0aGUgY2xpY2sgZXZlbnQgd2FzIHRyaWdnZXJlZCBieSB0aGUgcmlnaHQgY2xpY2sgY29udGV4dCBtZW51XG4gKi9cbkdsb2JhbC50cmlnZ2VyQW5hbHl0aWNzQ29udGV4dE1lbnVDbGljayA9IGZ1bmN0aW9uKCBjb250ZXh0X2J0biwgbWVudV9uYW1lICkge1xuXHQvLyBJZiBtb3JlIGRldGFpbCBpcyBuZWVkZWQgYWJvdmUgYW5kIGJleW9uZCBjb250ZXh0bWVudSBuYW1lLCB0aGVuIHVzZSAnTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ZpZXdfaWQnIGluIGFkZGl0aW9uLCBidXQgbm90IGluc3RlYWQgb2YsIGFzIHRoZXkgYXJlIGRpZmZlcmVudC5cblx0dmFyIGRvbV9jb250ZXh0X21lbnUgPSBMb2NhbENhY2hlRGF0YS5jdXJyZW50U2hvd25Db250ZXh0TWVudU5hbWUgfHwgJ2Vycm9yLXdpdGgtY29udGV4dC1tZW51JzsgLy8gJ3x8JyBpcyBmb3IgZ3JhY2VmdWwgZmFpbC4gaWRlbnRpZnkgY29ycmVjdCBjb250ZXh0IG1lbnUgKHZzIERPTSBzZWFyY2gsIHdoZXJlIHRoZXJlIGNvdWxkIGJlIG11bHRpcGxlIGluYWN0aXZlIGNvbnRleHQgbWVudXMpXG5cdHZhciBkb21fY29udGV4dF9tZW51X2dyb3VwO1xuXHR2YXIgYnV0dG9uX2lkO1xuXHR2YXIgZXZlbnRfY2F0ZWdvcnk7XG5cdHZhciBldmVudF9hY3Rpb247XG5cdHZhciBldmVudF9sYWJlbDtcblxuXHRpZiAoIGNvbnRleHRfYnRuICkge1xuXHRcdGlmICggY29udGV4dF9idG4uZ3JvdXAgJiYgY29udGV4dF9idG4uZ3JvdXAubGFiZWwgKSB7XG5cdFx0XHRkb21fY29udGV4dF9tZW51X2dyb3VwID0gY29udGV4dF9idG4uZ3JvdXAubGFiZWw7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRvbV9jb250ZXh0X21lbnVfZ3JvdXAgPSBjb250ZXh0X2J0bi5hY3Rpb25fZ3JvdXA7XG5cdFx0fVxuXHRcdGV2ZW50X2NhdGVnb3J5ID0gJ25hdmlnYXRpb246Y29udGV4dF9tZW51Jztcblx0XHRidXR0b25faWQgPSBjb250ZXh0X2J0bi5pZCB8fCAnZXJyb3Itd2l0aC1pY29uJztcblx0fSBlbHNlIHtcblx0XHQvLyBJZiBjb250ZXh0X2J0biBpcyBudWxsLCB0aGVuIHRoaXMgaXMgbGlrZWx5IGEgcmlnaHQgY2xpY2sgY29udGV4dCBtZW51IGNhbGwuXG5cdFx0ZXZlbnRfY2F0ZWdvcnkgPSAnbmF2aWdhdGlvbjpyaWdodF9jbGlja19tZW51Jztcblx0XHRkb21fY29udGV4dF9tZW51X2dyb3VwID0gJ3JpZ2h0X2NsaWNrJztcblx0XHRidXR0b25faWQgPSBtZW51X25hbWUgfHwgJ2Vycm9yLXdpdGgtcmlnaHRjbGljay1pY29uJztcblx0fVxuXG5cdC8vIEJlYXV0aWZ5IG91dHB1dFxuXHRkb21fY29udGV4dF9tZW51ID0gZG9tX2NvbnRleHRfbWVudS5yZXBsYWNlKCAnQ29udGV4dE1lbnUnLCAnJyApO1xuXHRidXR0b25faWQgPSBidXR0b25faWQucmVwbGFjZSggJ0ljb24nLCAnJyApOyAvL1JlbW92ZSBcImljb25cIiBmcm9tIGJ1dHRvbl9pZC5cblxuXHRldmVudF9hY3Rpb24gPSAnY2xpY2snO1xuXHRldmVudF9sYWJlbCA9IGRvbV9jb250ZXh0X21lbnUgKyAnOicgKyBkb21fY29udGV4dF9tZW51X2dyb3VwICsgJ3wnICsgYnV0dG9uX2lkO1xuXG5cdC8vIERlYnVnLlRleHQoICdDb250ZXh0IE1lbnU6IENhdGVnb3J5OiBuYXZpZ2F0aW9uX2NvbnRleHRfbWVudSBBY3Rpb246ICcgKyBldmVudF9hY3Rpb24gKyAnIExhYmVsOiAnICsgZXZlbnRfbGFiZWwsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ3RyaWdnZXJBbmFseXRpY3NDb250ZXh0TWVudUNsaWNrJywgMTAgKTtcblx0R2xvYmFsLnNlbmRBbmFseXRpY3NFdmVudCggZXZlbnRfY2F0ZWdvcnksIGV2ZW50X2FjdGlvbiwgZXZlbnRfbGFiZWwgKTtcbn07XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZXh0IC0gRXhwbGFpbnMgd2hhdCBlbGVtZW50IHRyaWdnZXJlZCB0aGUgZXZlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSB2aWV3X2lkIC0gTmFtZSBvZiB0aGUgY3VycmVudCB2aWV3IGluIHdoaWNoIGVsZW1lbnQgd2FzIHRyaWdnZXJlZFxuICovXG5HbG9iYWwudHJpZ2dlckFuYWx5dGljc0VkaXRWaWV3TmF2aWdhdGlvbiA9IGZ1bmN0aW9uKCBjb250ZXh0LCB2aWV3X2lkICkge1xuXHQvLyBjb250ZXh0IGluIHRoaXMgY2FzZSBjYW4gYmUgJ2xlZnQtYXJyb3cnLCAncmlnaHQtYXJyb3cnLCBvciAnYXdlc29tZWJveCdcblx0dmFyIGV2ZW50X2FjdGlvbiA9ICdjbGljayc7XG5cdHZhciBldmVudF9sYWJlbCA9IHZpZXdfaWQgKyAnOicgKyBjb250ZXh0O1xuXG5cdC8vIERlYnVnLlRleHQoICdDb250ZXh0IE1lbnU6IENhdGVnb3J5OiBuYXZpZ2F0aW9uX2VkaXRfdmlld19uYXZpZ2F0aW9uIEFjdGlvbjogJyArIGV2ZW50X2FjdGlvbiArICcgTGFiZWw6ICcgKyBldmVudF9sYWJlbCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAndHJpZ2dlckFuYWx5dGljc0NvbnRleHRNZW51Q2xpY2snLCAxMCApO1xuXHRHbG9iYWwuc2VuZEFuYWx5dGljc0V2ZW50KCAnbmF2aWdhdGlvbjplZGl0X3ZpZXdfbmF2aWdhdGlvbicsIGV2ZW50X2FjdGlvbiwgZXZlbnRfbGFiZWwgKTtcbn07XG5cbi8qKlxuICpcbiAqIEBwYXJhbSBldmVudCAtIHRoZSBldmVudCBvYmplY3QgZnJvbSB0aGUgalF1ZXJ5IFVJIHRhYnMuIEN1cnJlbnRseSBleHBlY3RpbmcgaXQgdG8gYmUgdHJpZ2dlcmVkIGJ5IHRoZSBhY3RpdmF0ZSBldmVudFxuICogQHBhcmFtIHVpIC0gdGhlIHVpIG9iamVjdCBmcm9tIGpRdWVyeSBVSSB0YWJzLCBjb250YWlucyBwcmV2IGFuZCB0YXJnZXQgdGFiIGluZm9cbiAqL1xuR2xvYmFsLnRyaWdnZXJBbmFseXRpY3NUYWJzID0gZnVuY3Rpb24oIGV2ZW50LCB1aSApIHtcblx0Ly8gYWN0aXZhdGUgZXZlbnQgdHJpZ2dlcmVkLCBlbnN1cmUgYWxsIHJlcXVpcmVkIHZhbHVlcyBhcmUgc2V0XG5cdGlmICggZXZlbnQgJiYgZXZlbnQudHlwZSAmJiB1aSAmJiB1aS5uZXdUYWIgKSB7XG5cdFx0dmFyIHRhYl90YXJnZXQgPSB1aS5uZXdUYWIuZmluZCggJy51aS10YWJzLWFuY2hvcicgKS5hdHRyKCAncmVmJyApIHx8ICd0YWItdGFyZ2V0LWVycm9yJzsgLy8gJ3x8JyBpcyBmb3IgZ3JhY2Z1bCBmYWlsXG5cdFx0dmFyIHZpZXdJZCA9IExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl92aWV3X2lkIHx8ICdlcnJvci12aWV3aWQnOyAvLyAnfHwnIGlzIGZvciBncmFjZWZ1bCBmYWlsXG5cblx0XHQvLyBCZWF1dGlmeSBvdXRwdXRcblx0XHR0YWJfdGFyZ2V0ID0gdGFiX3RhcmdldC5yZXBsYWNlKCAndGFiXycsICcnICk7XG5cblx0XHR2YXIgZXZlbnRfYWN0aW9uID0gJ2NsaWNrJztcblx0XHR2YXIgZXZlbnRfbGFiZWwgPSB2aWV3SWQgKyAnOnRhYnM6JyArIHRhYl90YXJnZXQ7XG5cblx0XHQvLyBEZWJ1Zy5UZXh0KCAnQ29udGV4dCBNZW51OiBDYXRlZ29yeTogbmF2aWdhdGlvbl90YWJzIEFjdGlvbjogJyArIGV2ZW50X2FjdGlvbiArICcgTGFiZWw6ICcgKyBldmVudF9sYWJlbCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAndHJpZ2dlckFuYWx5dGljc0NvbnRleHRNZW51Q2xpY2snLCAxMCApO1xuXHRcdEdsb2JhbC5zZW5kQW5hbHl0aWNzRXZlbnQoICduYXZpZ2F0aW9uOnRhYnMnLCBldmVudF9hY3Rpb24sIGV2ZW50X2xhYmVsICk7XG5cdH0gZWxzZSB7XG5cdFx0R2xvYmFsLnNlbmRBbmFseXRpY3NFdmVudCggJ2Vycm9yOm5hdmlnYXRpb246dGFicycsICdlcnJvci10YWJzJywgJ2Vycm9yJyApOyAvLyBTaG91bGQgbmV2ZXIgYmUgdHJpZ2dlcmVkLiBJZiB0aGlzIGFwcGVhcnMgaW4gYW5hbHl0aWNzIHJlc3VsdHMsIGludmVzdGlnYXRlLlxuXHR9XG59O1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY29udGV4dCAtIHRoZSBsYWJlbCBvZiB0aGUgb2JqZWN0IGludm9sdmVkIGluIHRoZSBldmVudC4gRS5nLiBjbG9zZSBidXR0b24gZm9yIGNsaWNrIGV2ZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gYWN0aW9uIC0gdGhlIGFjdGlvbiB0eXBlIG9mIHRoZSBldmVudC4gRS5nLiBjbGljay5cbiAqIEBwYXJhbSB7c3RyaW5nfSB2aWV3X2lkIC0gdGhlIHZpZXdJZCBpbiB3aGljaCB0aGUgZXZlbnQgb2NjdXJyZWQuIEUuZy4gVGltZVNoZWV0LlxuICovXG5HbG9iYWwudHJpZ2dlckFuYWx5dGljc05hdmlnYXRpb25PdGhlciA9IGZ1bmN0aW9uKCBjb250ZXh0LCBhY3Rpb24sIHZpZXdfaWQgKSB7XG5cdHZhciBldmVudF9hY3Rpb24gPSBhY3Rpb247XG5cdHZhciBldmVudF9sYWJlbCA9IHZpZXdfaWQgKyAnOicgKyBjb250ZXh0O1xuXG5cdC8vIERlYnVnLlRleHQoICdDb250ZXh0IE1lbnU6IENhdGVnb3J5OiBuYXZpZ2F0aW9uX290aGVyIEFjdGlvbjogJyArIGV2ZW50X2FjdGlvbiArICcgTGFiZWw6ICcgKyBldmVudF9sYWJlbCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAndHJpZ2dlckFuYWx5dGljc0NvbnRleHRNZW51Q2xpY2snLCAxMCApO1xuXHRHbG9iYWwuc2VuZEFuYWx5dGljc0V2ZW50KCAnbmF2aWdhdGlvbjpvdGhlcicsIGV2ZW50X2FjdGlvbiwgZXZlbnRfbGFiZWwgKTtcbn07XG5cbkdsb2JhbC5nZXRTZXNzaW9uSURLZXkgPSBmdW5jdGlvbigpIHtcblx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRBbGxVUkxBcmdzKCkgKSB7XG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRBbGxVUkxBcmdzKCkuaGFzT3duUHJvcGVydHkoICdjb21wYW55X2lkJyApICkge1xuXHRcdFx0cmV0dXJuICdTZXNzaW9uSUQtSkEnO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gJ1Nlc3Npb25JRCc7XG59O1xuXG5HbG9iYWwubG9hZFN0eWxlU2hlZXQgPSBmdW5jdGlvbiggcGF0aCwgZm4sIHNjb3BlICkge1xuXHR2YXIgaGVhZCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCAnaGVhZCcgKVswXSwgLy8gcmVmZXJlbmNlIHRvIGRvY3VtZW50LmhlYWQgZm9yIGFwcGVuZGluZy8gcmVtb3ZpbmcgbGluayBub2Rlc1xuXHRcdGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnbGluaycgKTsgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgbGluayBub2RlXG5cdGxpbmsuc2V0QXR0cmlidXRlKCAnaHJlZicsIHBhdGggKTtcblx0bGluay5zZXRBdHRyaWJ1dGUoICdyZWwnLCAnc3R5bGVzaGVldCcgKTtcblx0bGluay5zZXRBdHRyaWJ1dGUoICd0eXBlJywgJ3RleHQvY3NzJyApO1xuXHR2YXIgc2hlZXQsIGNzc1J1bGVzO1xuXHQvLyBnZXQgdGhlIGNvcnJlY3QgcHJvcGVydGllcyB0byBjaGVjayBmb3IgZGVwZW5kaW5nIG9uIHRoZSBicm93c2VyXG5cdGlmICggJ3NoZWV0JyBpbiBsaW5rICkge1xuXHRcdHNoZWV0ID0gJ3NoZWV0Jztcblx0XHRjc3NSdWxlcyA9ICdjc3NSdWxlcyc7XG5cdH0gZWxzZSB7XG5cdFx0c2hlZXQgPSAnc3R5bGVTaGVldCc7XG5cdFx0Y3NzUnVsZXMgPSAncnVsZXMnO1xuXHR9XG5cdHZhciBpbnRlcnZhbF9pZCA9IHNldEludGVydmFsKCBmdW5jdGlvbigpIHsgICAgICAgICAgICAgICAgICAgICAvLyBzdGFydCBjaGVja2luZyB3aGV0aGVyIHRoZSBzdHlsZSBzaGVldCBoYXMgc3VjY2Vzc2Z1bGx5IGxvYWRlZFxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKCBsaW5rW3NoZWV0XSAmJiBsaW5rW3NoZWV0XVtjc3NSdWxlc10ubGVuZ3RoICkgeyAvLyBTVUNDRVNTISBvdXIgc3R5bGUgc2hlZXQgaGFzIGxvYWRlZFxuXHRcdFx0XHRcdGNsZWFySW50ZXJ2YWwoIGludGVydmFsX2lkICk7ICAgICAgICAgICAgICAgICAgICAgIC8vIGNsZWFyIHRoZSBjb3VudGVyc1xuXHRcdFx0XHRcdGNsZWFyVGltZW91dCggdGltZW91dF9pZCApO1xuXHRcdFx0XHRcdGlmICggdHlwZW9mIGZuID09ICdmdW5jdGlvbicgKSB7XG5cdFx0XHRcdFx0XHRmbi5jYWxsKCBzY29wZSB8fCB3aW5kb3csIHRydWUsIGxpbmsgKTsgICAgICAgICAgIC8vIGZpcmUgdGhlIGNhbGxiYWNrIHdpdGggc3VjY2VzcyA9PSB0cnVlXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHR9XG5cdFx0fSwgMTAgKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBob3cgb2Z0ZW4gdG8gY2hlY2sgaWYgdGhlIHN0eWxlc2hlZXQgaXMgbG9hZGVkXG5cdFx0dGltZW91dF9pZCA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uKCkgeyAgICAgICAvLyBzdGFydCBjb3VudGluZyBkb3duIHRpbGwgZmFpbFxuXHRcdFx0Y2xlYXJJbnRlcnZhbCggdGltZW91dF9pZCApOyAgICAgICAgICAgICAvLyBjbGVhciB0aGUgY291bnRlcnNcblx0XHRcdGNsZWFyVGltZW91dCggdGltZW91dF9pZCApO1xuXHRcdFx0aGVhZC5yZW1vdmVDaGlsZCggbGluayApOyAgICAgICAgICAgICAgICAvLyBzaW5jZSB0aGUgc3R5bGUgc2hlZXQgZGlkbid0IGxvYWQsIHJlbW92ZSB0aGUgbGluayBub2RlIGZyb20gdGhlIERPTVxuXHRcdFx0aWYgKCB0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJyApIHtcblx0XHRcdFx0Zm4uY2FsbCggc2NvcGUgfHwgd2luZG93LCBmYWxzZSwgbGluayApOyAvLyBmaXJlIHRoZSBjYWxsYmFjayB3aXRoIHN1Y2Nlc3MgPT0gZmFsc2Vcblx0XHRcdH1cblx0XHR9LCAxNTAwMCApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhvdyBsb25nIHRvIHdhaXQgYmVmb3JlIGZhaWxpbmdcblx0aGVhZC5hcHBlbmRDaGlsZCggbGluayApOyAgLy8gaW5zZXJ0IHRoZSBsaW5rIG5vZGUgaW50byB0aGUgRE9NIGFuZCBzdGFydCBsb2FkaW5nIHRoZSBzdHlsZSBzaGVldFxuXHRyZXR1cm4gbGluazsgLy8gcmV0dXJuIHRoZSBsaW5rIG5vZGU7XG59O1xuXG5HbG9iYWwuZ2V0U2Vzc2lvbklES2V5ID0gZnVuY3Rpb24oKSB7XG5cdGlmICggTG9jYWxDYWNoZURhdGEuZ2V0QWxsVVJMQXJncygpICkge1xuXHRcdGlmICggTG9jYWxDYWNoZURhdGEuZ2V0QWxsVVJMQXJncygpLmhhc093blByb3BlcnR5KCAnY29tcGFueV9pZCcgKSApIHtcblx0XHRcdHJldHVybiAnU2Vzc2lvbklELUpBJztcblx0XHR9XG5cdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRBbGxVUkxBcmdzKCkuaGFzT3duUHJvcGVydHkoICdwdW5jaF91c2VyX2lkJyApICkge1xuXHRcdFx0cmV0dXJuICdTZXNzaW9uSUQtUVAnO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gJ1Nlc3Npb25JRCc7XG59O1xuXG4vL2Rvbid0IGxldCB0aGUgdXNlciBsZWF2ZSB3aXRob3V0IGNsaWNraW5nIE9LLlxuLy91c2VzIGxvY2FsY2FjaGVkYXRhIHNvIHRoYXQgaXQgd2lsbCB3b3JrIGluIHRoZSByaWJib25cbkdsb2JhbC5jaGVja0JlZm9yZUV4aXQgPSBmdW5jdGlvbiggZnVuY3Rpb25Ub0V4ZWN1dGUgKSB7XG5cdHZhciBhbGVydF9tZXNzYWdlID0gR2xvYmFsLm1vZGlmeV9hbGVydF9tZXNzYWdlO1xuXHRpZiAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlciAmJiBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fZWRpdF9vbmx5X2NvbnRyb2xsZXIuY29uZmlybV9vbl9leGl0ICYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlci5pc19jaGFuZ2VkID09PSBmYWxzZSApIHtcblx0XHRhbGVydF9tZXNzYWdlID0gR2xvYmFsLmNvbmZpcm1fb25fZXhpdF9tZXNzYWdlO1xuXHR9XG5cblx0VEFsZXJ0TWFuYWdlci5zaG93Q29uZmlybUFsZXJ0KCBhbGVydF9tZXNzYWdlLCBudWxsLCBmdW5jdGlvbiggY2xpY2tlZF95ZXMgKSB7XG5cdFx0aWYgKCBjbGlja2VkX3llcyA9PT0gdHJ1ZSApIHtcblx0XHRcdGZ1bmN0aW9uVG9FeGVjdXRlKCBjbGlja2VkX3llcyApO1xuXHRcdH1cblx0fSApO1xufTtcblxuR2xvYmFsLmRldGVjdE1vYmlsZUJyb3dzZXIgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIC9BbmRyb2lkfHdlYk9TfGlQaG9uZXxpUGFkfGlQb2R8QmxhY2tCZXJyeS9pLnRlc3QoIG5hdmlnYXRvci51c2VyQWdlbnQgKTtcbn07XG5cbkdsb2JhbC5nZXRCcm93c2VyVmVuZG9yID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEudXNlcl9hZ2VudF9kYXRhLmJyb3dzZXI7XG59O1xuLyoqXG4gKiBBbGxvd2luZyBkZWVwIGxpbmtpbmdcbiAqIEB0eXBlIHtib29sZWFufVxuICovXG5HbG9iYWwuZGVlcGxpbmsgPSBmYWxzZTtcblxuR2xvYmFsLmdldERlZXBMaW5rID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBHbG9iYWwuZGVlcGxpbms7XG59O1xuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgZGVlcGxpbmsgZnJvbSB0aGUgY3VycmVudCB1cmwuXG4gKi9cbkdsb2JhbC5zZXREZWVwTGluayA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgbmV3RGVlcExpbmsgPSB3aW5kb3cubG9jYXRpb24uaHJlZi5zcGxpdCggJyMhbT0nIClbMV07XG5cblx0Ly9CZWNhdXNlIHdlIGFkZCBzdGVwIHRvIGJyb3dzZXIgZHVyaW5nIGxvZ2luIG5vdyBzbyB0aGF0IHRoZSBicm93c2VyIGJhY2sgYnV0dG9uIHdvcmtzLCB3ZSBuZWVkIHRvIGNoZWNrIGZvciB0aGF0IG9yIGxvZ2luIGNhbiBmYWlsIGxlYXZpbmcgdGhlIHVzZXIgc3R1Y2suXG5cdGlmICggbmV3RGVlcExpbmsgPT0gJ0xvZ2luJyB8fCAoIG5ld0RlZXBMaW5rICYmIG5ld0RlZXBMaW5rLnN0YXJ0c1dpdGgoICdMb2dpbiYnICkgPT0gdHJ1ZSApICkgeyAvL1dlIGFyZSBub3QganVzdCBjaGVja2luZyBzdGFydHNXaXRoIGJlY2F1c2UgcG90ZW50aWFsIG90aGVyIHZpZXdzIHN0YXJ0IHdpdGggXCJMb2dpblwiIGluIHRoZSBmdXR1cmVcblx0XHR2YXIgYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSA9IGdldENvb2tpZSggJ0FsdGVybmF0ZVNlc3Npb25EYXRhJyApO1xuXHRcdGlmICggYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSApIHtcblx0XHRcdHRyeSB7IC8vUHJldmVudCBKUyBleGNlcHRpb24gaWYgd2UgY2FuJ3QgcGFyc2UgYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSBmb3Igc29tZSByZWFzb24uXG5cdFx0XHRcdGFsdGVybmF0ZV9zZXNzaW9uX2RhdGEgPSBKU09OLnBhcnNlKCBhbHRlcm5hdGVfc2Vzc2lvbl9kYXRhICk7XG5cdFx0XHRcdGlmICggYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSAmJiBhbHRlcm5hdGVfc2Vzc2lvbl9kYXRhLnByZXZpb3VzX3Nlc3Npb25fdmlldyApIHtcblx0XHRcdFx0XHRHbG9iYWwuZGVlcGxpbmsgPSBhbHRlcm5hdGVfc2Vzc2lvbl9kYXRhLnByZXZpb3VzX3Nlc3Npb25fdmlldztcblx0XHRcdFx0fVxuXHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdERlYnVnLlRleHQoIGUubWVzc2FnZSwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnc2V0RGVlcExpbmsnLCAxMCApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIGlmICggbmV3RGVlcExpbmsgIT0gdW5kZWZpbmVkICkge1xuXHRcdEdsb2JhbC5kZWVwbGluayA9IG5ld0RlZXBMaW5rO1xuXHR9XG59O1xuXG4vKipcbiBzb3J0cyBpdGVtcyBmb3IgdGhlIHJpYmJvbiBtZW51XG4gKiovXG5HbG9iYWwuY29tcGFyZU1lbnVJdGVtcyA9IGZ1bmN0aW9uKCBhLCBiICkge1xuXHRpZiAoIGEuYXR0cmlidXRlcy5zb3J0X29yZGVyID09IHVuZGVmaW5lZCApIHtcblx0XHRhLmF0dHJpYnV0ZXMuc29ydF9vcmRlciA9IDEwMDA7XG5cdH1cblx0aWYgKCBiLmF0dHJpYnV0ZXMuc29ydF9vcmRlciA9PSB1bmRlZmluZWQgKSB7XG5cdFx0Yi5hdHRyaWJ1dGVzLnNvcnRfb3JkZXIgPSAxMDAwO1xuXHR9XG5cblx0aWYgKCBhLmF0dHJpYnV0ZXMuc29ydF9vcmRlciA8IGIuYXR0cmlidXRlcy5zb3J0X29yZGVyICkge1xuXHRcdHJldHVybiAtMTtcblx0fVxuXG5cdGlmICggYS5hdHRyaWJ1dGVzLnNvcnRfb3JkZXIgPiBiLmF0dHJpYnV0ZXMuc29ydF9vcmRlciApIHtcblx0XHRyZXR1cm4gMTtcblx0fVxuXG5cdGlmICggYS5hdHRyaWJ1dGVzLnNvcnRfb3JkZXIgPT0gYi5hdHRyaWJ1dGVzLnNvcnRfb3JkZXIgKSB7XG5cdFx0aWYgKCBhLmF0dHJpYnV0ZXMuYWRkX29yZGVyIDwgYi5hdHRyaWJ1dGVzLmFkZF9vcmRlciApIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9XG5cdFx0aWYgKCBhLmF0dHJpYnV0ZXMuYWRkX29yZGVyID4gYi5hdHRyaWJ1dGVzLmFkZF9vcmRlciApIHtcblx0XHRcdHJldHVybiAxO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiAwO1xufTtcblxuR2xvYmFsLmdldERheXNJblNwYW4gPSBmdW5jdGlvbiggc3RhcnRfZGF0ZSwgZW5kX2RhdGUsIHN1biwgbW9uLCB0dWUsIHdlZCwgdGh1LCBmcmksIHNhdCApIHtcblx0dmFyIHN0YXJ0X2RhdGVfb2JqID0gR2xvYmFsLnN0clRvRGF0ZSggc3RhcnRfZGF0ZSApO1xuXHR2YXIgZW5kX2RhdGVfb2JqID0gR2xvYmFsLnN0clRvRGF0ZSggZW5kX2RhdGUgKTtcblxuXHRpZiAoIHN0YXJ0X2RhdGVfb2JqID09IG51bGwgKSB7XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHRpZiAoIGVuZF9kYXRlX29iaiA9PSBudWxsICkge1xuXHRcdHJldHVybiAwO1xuXHR9XG5cblx0dmFyIGRheXMgPSBNYXRoLnJvdW5kKCBNYXRoLmFicyggKCBzdGFydF9kYXRlX29iai5nZXRUaW1lKCkgLSBlbmRfZGF0ZV9vYmouZ2V0VGltZSgpICkgLyAoIDg2NDAwICogMTAwMCApICkgKSArIDE7XG5cblx0Ly9OZWVkIHRvIGxvb3Agb3ZlciB0aGUgd2hvbGUgcmFuZ2UgdG8gZW5zdXJlIHByb3BlciBjb3VudGluZyBvZiBlZmZlY3RpdmUgZGF5cyBvbiByYW5nZXMgdGhhdCBzcGFuIG11bHRpcGxlIHdlZWtzLlxuXHR3aGlsZSAoIHN0YXJ0X2RhdGVfb2JqIDw9IGVuZF9kYXRlX29iaiApIHtcblx0XHRzd2l0Y2ggKCBzdGFydF9kYXRlX29iai5nZXREYXkoKSApIHtcblx0XHRcdGNhc2UgMDpcblx0XHRcdFx0aWYgKCAhc3VuICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMTpcblx0XHRcdFx0aWYgKCAhbW9uICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMjpcblx0XHRcdFx0aWYgKCAhdHVlICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMzpcblx0XHRcdFx0aWYgKCAhd2VkICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgNDpcblx0XHRcdFx0aWYgKCAhdGh1ICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgNTpcblx0XHRcdFx0aWYgKCAhZnJpICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgNjpcblx0XHRcdFx0aWYgKCAhc2F0ICkge1xuXHRcdFx0XHRcdGRheXMgLT0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHRzdGFydF9kYXRlX29iai5zZXREYXRlKCBzdGFydF9kYXRlX29iai5nZXREYXRlKCkgKyAxICk7IC8vSW5jcmVtZW50IHRvIG5leHQgZGF5IGFuZCBjb250aW51ZSB0aGUgbG9vcC5cblx0fVxuXG5cdHJldHVybiBkYXlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBsYW5ndWFnZSBjb29raWUgdG8gcm9vdCBjb29raWUgdXJsXG4gKiBAcGFyYW0gbGFuZ1xuICovXG5HbG9iYWwuc2V0TGFuZ3VhZ2VDb29raWUgPSBmdW5jdGlvbiggbGFuZyApIHtcblx0c2V0Q29va2llKCAnbGFuZ3VhZ2UnLCBsYW5nLCAxMDAwMCwgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmNvb2tpZV9iYXNlX3VybCApO1xufTtcblxuLyoqXG4gKiBSZW1vdmVzIGNvb2tpZXMgZnJvbSBhbGwgcGF0aHMuIFB1dCBpbiBzcGVjaWZpY2FsbHkgdG8gbW92ZSB0aGUgbGFuZ3VhZ2UgY29va2llcyB0byByb290LlxuICogQHBhcmFtIG5hbWVcbiAqL1xuR2xvYmFsLmVyYXNlQ29va2llRnJvbUFsbFBhdGhzID0gZnVuY3Rpb24oIG5hbWUgKSB7XG5cdHZhciB2YWx1ZSA9IGdldENvb2tpZSggbmFtZSApO1xuXG5cdC8vIFRoaXMgZnVuY3Rpb24gd2lsbCBhdHRlbXB0IHRvIHJlbW92ZSBhIGNvb2tpZSBmcm9tIGFsbCBwYXRoc1xuXHR2YXIgcGF0aF9iaXRzID0gbG9jYXRpb24ucGF0aG5hbWUuc3BsaXQoICcvJyApO1xuXHR2YXIgcGF0aF9jdXJyZW50ID0gJyBwYXRoPSc7XG5cblx0Ly8gRG8gYSBzaW1wbGUgcGF0aGxlc3MgZGVsZXRlIGZpcnN0XG5cdGRvY3VtZW50LmNvb2tpZSA9IG5hbWUgKyAnPTsgZXhwaXJlcz1UaHUsIDAxLUphbi0xOTcwIDAwOjAwOjAxIEdNVDsnO1xuXHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBwYXRoX2JpdHMubGVuZ3RoOyBpKysgKSB7XG5cdFx0cGF0aF9jdXJyZW50ICs9ICggKCBwYXRoX2N1cnJlbnQuc3Vic3RyKCAtMSApICE9ICcvJyApID8gJy8nIDogJycgKSArIHBhdGhfYml0c1tpXTtcblx0XHREZWJ1Zy5UZXh0KCAnLS0tJyArIGkgKyAnLiBEZWxldGluZyBjb29raWU6ICcgKyBuYW1lICsgJyB3aXRoIHZhbHVlOiAnICsgdmFsdWUgKyAnIGFuZCBwYXRoOiAnICsgcGF0aF9jdXJyZW50LCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdlcmFzZUNvb2tpZUZyb21BbGxQYXRocycsIDEwICk7XG5cdFx0ZG9jdW1lbnQuY29va2llID0gbmFtZSArICc9OyBleHBpcmVzPVRodSwgMDEtSmFuLTE5NzAgMDA6MDA6MDEgR01UOyAnICsgcGF0aF9jdXJyZW50ICsgJy87Jztcblx0XHRkb2N1bWVudC5jb29raWUgPSBuYW1lICsgJz07IGV4cGlyZXM9VGh1LCAwMS1KYW4tMTk3MCAwMDowMDowMSBHTVQ7ICcgKyBwYXRoX2N1cnJlbnQgKyAnOyc7XG5cdH1cblxuXHREZWJ1Zy5UZXh0KCAnRGVsZXRpbmcgY29va2llOiAnICsgbmFtZSArICcgd2l0aCB2YWx1ZTonICsgdmFsdWUgKyAnIGFuZCBwYXRoOicgKyBwYXRoX2N1cnJlbnQsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2VyYXNlQ29va2llRnJvbUFsbFBhdGhzJywgMTAgKTtcblx0cmV0dXJuIHZhbHVlO1xufTtcblxuLyoqXG4gKiBNb3ZlcyBzcGVjaWZpYyBhcHAgY29va2llcyBmcm9tIGFsbCBvdmVyIHRvIHRoZSByb290IGNvb2tpZSBwYXRoIHNvIHRoYXQgdGhleSB3aWxsIGJlIGFjY2Vzc2libGUgZnJvbSBldmVyeXdoZXJlXG4gKi9cbkdsb2JhbC5tb3ZlQ29va2llc1RvTmV3UGF0aCA9IGZ1bmN0aW9uKCkge1xuXHREZWJ1Zy5BcnIoIGRvY3VtZW50LmNvb2tpZSwgJ0NPT0tJRSBCRUZPUkUgQ09OVEVOVDogJywgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnbW92ZUNvb2tpZXNUb05ld1BhdGgnLCAxMCApO1xuXHR2YXIgY29va2llcyA9IFsnbGFuZ3VhZ2UnLCAnU3RhdGlvbklEJywgJ1Nlc3Npb25JRCddO1xuXHR2YXIgeWVhciA9IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcblx0Zm9yICggdmFyIGkgPSAwOyBpIDwgY29va2llcy5sZW5ndGg7IGkrKyApIHtcblx0XHR2YXIgdmFsID0gR2xvYmFsLmVyYXNlQ29va2llRnJvbUFsbFBhdGhzKCBjb29raWVzW2ldICk7XG5cdFx0aWYgKCB2YWwgJiYgdmFsLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHREZWJ1Zy5UZXh0KCAnU2V0dGluZyBjb29raWU6JyArIGNvb2tpZXNbaV0gKyAnIHdpdGggdmFsdWU6JyArIHZhbCArICcgYW5kIHBhdGg6JyArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5jb29raWVfYmFzZV91cmwsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ21vdmVDb29raWVzVG9OZXdQYXRoJywgMTAgKTtcblx0XHRcdGRvY3VtZW50LmNvb2tpZSA9IGNvb2tpZXNbaV0gKyAnPScgKyB2YWwgKyAnOyBleHBpcmVzPVRodSwgMDEtSmFuLScgKyAoIHllYXIgKyAxMCApICsgJyAwMDowMDowMSBHTVQ7IHBhdGg9JyArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5jb29raWVfYmFzZV91cmwgKyAnOyc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdERlYnVnLlRleHQoICdOT1QgU2V0dGluZyBjb29raWU6JyArIGNvb2tpZXNbaV0gKyAnIHdpdGggdmFsdWU6JyArIHZhbCArICcgYW5kIHBhdGg6JyArIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5jb29raWVfYmFzZV91cmwsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ21vdmVDb29raWVzVG9OZXdQYXRoJywgMTAgKTtcblx0XHR9XG5cdH1cblx0RGVidWcuQXJyKCBkb2N1bWVudC5jb29raWUsICdDT09LSUUgQUZURVIgQ09OVEVOVDogJywgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnbW92ZUNvb2tpZXNUb05ld1BhdGgnLCAxMCApO1xufTtcblxuR2xvYmFsLmNsZWFyU2Vzc2lvbkNvb2tpZSA9IGZ1bmN0aW9uKCkge1xuXHRHbG9iYWwubW92ZUNvb2tpZXNUb05ld1BhdGgoKTtcblx0ZGVsZXRlQ29va2llKCBHbG9iYWwuZ2V0U2Vzc2lvbklES2V5KCkgKTtcbn07XG5HbG9iYWwuYXJyYXlfdW5pcXVlID0gZnVuY3Rpb24oIGFyciApIHtcblx0aWYgKCBHbG9iYWwuaXNBcnJheSggYXJyICkgPT0gZmFsc2UgKSB7XG5cdFx0cmV0dXJuIGFycjtcblx0fVxuXHR2YXIgY2xlYW5fYXJyID0gW107XG5cdGZvciAoIHZhciBuIGluIGFyciApIHtcblx0XHRpZiAoIGNsZWFuX2Fyci5pbmRleE9mKCBhcnJbbl0gKSA9PSAtMSApIHtcblx0XHRcdGNsZWFuX2Fyci5wdXNoKCBhcnJbbl0gKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGNsZWFuX2Fycjtcbn07XG5cbi8vUmV0dXJucyBwcm9wZXJ0eSBrZXlzIHRoYXQgaGF2ZSBkaWZmZXJlbnQgdmFsdWVzIG9yIHRoYXQgZG9uJ3QgZXhpc3QuIFNpbWlsYXIgdG8gUEhQJ3MgYXJyYXlfZGlmZl9hc3NvYygpIGZ1bmN0aW9uLlxuR2xvYmFsLkFycmF5RGlmZkFzc29jID0gZnVuY3Rpb24oIGFycjEgKSB7XG5cdGNvbnN0IHJldGFyciA9IHt9O1xuXHRjb25zdCBhcmdsID0gYXJndW1lbnRzLmxlbmd0aDtcblx0bGV0IGsxID0gJyc7XG5cdGxldCBpID0gMTtcblx0bGV0IGsgPSAnJztcblx0bGV0IGFyciA9IHt9O1xuXG5cdGFycjFfa2V5czogZm9yICggazEgaW4gYXJyMSApIHtcblx0XHRmb3IgKCBpID0gMTsgaSA8IGFyZ2w7IGkrKyApIHtcblx0XHRcdGFyciA9IGFyZ3VtZW50c1tpXTtcblxuXHRcdFx0Zm9yICggayBpbiBhcnIgKSB7XG5cdFx0XHRcdGlmICggYXJyW2tdID09PSBhcnIxW2sxXSAmJiBrID09PSBrMSApIHtcblx0XHRcdFx0XHQvLyBJZiBpdCByZWFjaGVzIGhlcmUsIGl0IHdhcyBmb3VuZCBpbiBhdCBsZWFzdCBvbmUgYXJyYXksIHNvIHRyeSBuZXh0IHZhbHVlXG5cdFx0XHRcdFx0Y29udGludWUgYXJyMV9rZXlzO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldGFycltrMV0gPSBhcnIxW2sxXTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gcmV0YXJyO1xufTtcblxuLy9TcGVjaWFsIHJvdW5kaW5nIGZ1bmN0aW9uIHRoYXQgaGFuZGxlcyB2YWx1ZXMgbGlrZSAxLjAwNSBvciAxLjAwNDk5OTk5OTk5OTk5OTkgcHJvcGVybHksIHNlZTogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMTgzMjkxNC9yb3VuZC10by1hdC1tb3N0LTItZGVjaW1hbC1wbGFjZXNcbkdsb2JhbC5Nb25leVJvdW5kID0gZnVuY3Rpb24oIG51bWJlciwgZGVjaW1hbHMgKSB7XG5cdGlmICggaXNOYU4oIG51bWJlciApICkge1xuXHRcdG51bWJlciA9IDA7XG5cdH1cblxuXHRpZiAoICFkZWNpbWFscyApIHtcblx0XHRkZWNpbWFscyA9IDI7XG5cdH1cblxuXHQvLyMyMjk0IC0gV2UgbXVzdCByb3VuZCB0aGUgYWJzb2x1dGUgdmFsdWUgb3IgbmVnYXRpdmUgbnVtYmVycyB3aWxsIHJvdW5kIHRvd2FyZCB6ZXJvLlxuXHR2YXIgbmVnYXRpdmUgPSBmYWxzZTtcblx0aWYgKCBudW1iZXIgPCAwICkge1xuXHRcdG5lZ2F0aXZlID0gdHJ1ZTtcblx0fVxuXHRudW1iZXIgPSBNYXRoLmFicyggbnVtYmVyICk7XG5cblx0dmFyIHJldHZhbCA9ICsoIE1hdGgucm91bmQoIG51bWJlciArICdlKycgKyBkZWNpbWFscyApICsgJ2UtJyArIGRlY2ltYWxzICk7XG5cblx0aWYgKCBuZWdhdGl2ZSApIHtcblx0XHRyZXR2YWwgPSByZXR2YWwgKiAtMTtcblx0fVxuXG5cdHJldHVybiByZXR2YWwudG9GaXhlZCggZGVjaW1hbHMgKTtcbn07XG5cbkdsb2JhbC5nZXRVSVJlYWR5U3RhdHVzID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBHbG9iYWwuVUlSZWFkeVN0YXR1cztcbn07XG5HbG9iYWwuc2V0VUlOb3RyZWFkeSA9IGZ1bmN0aW9uKCkge1xuXHRHbG9iYWwuVUlSZWFkeVN0YXR1cyA9IDA7XG5cdERlYnVnLlRleHQoICdHbG9iYWwgcmVhZHkgc3RhdHVzIGNoYW5nZWQ6IDAnLCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdzZXRVSVJlYWR5U3RhdHVzJywgMTAgKTtcbn07XG5HbG9iYWwuc2V0VUlSZWFkeSA9IGZ1bmN0aW9uKCkge1xuXHQvL25lZWQgdG8gY2hlY2sgdGhlIGRvY3VtZW50IGlzbid0IGFscmVhZHkgY29tcGxldGUgYW5kIHJlYWR5IGZvciBhIHNjcmVlbnNob3QuJ1xuXHRpZiAoIEdsb2JhbC5VSVJlYWR5U3RhdHVzID09IDAgKSB7XG5cdFx0R2xvYmFsLlVJUmVhZHlTdGF0dXMgPSAxO1xuXHRcdERlYnVnLlRleHQoICdHbG9iYWwgcmVhZHkgc3RhdHVzIGNoYW5nZWQ6IDEnLCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdzZXRVSVJlYWR5JywgMTAgKTtcblx0fVxufTtcbkdsb2JhbC5zZXRVSUluaXRDb21wbGV0ZSA9IGZ1bmN0aW9uKCkge1xuXHRHbG9iYWwuVUlSZWFkeVN0YXR1cyA9IDI7XG5cdERlYnVnLlRleHQoICdHbG9iYWwgcmVhZHkgc3RhdHVzIGNoYW5nZWQ6IDInLCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdzZXRVSVJlYWR5U3RhdHVzJywgMTAgKTtcbn07XG5cbkdsb2JhbC5zZXRVbml0VGVzdE1vZGUgPSBmdW5jdGlvbigpIHtcblx0R2xvYmFsLlVOSVRfVEVTVF9NT0RFID0gdHJ1ZTtcblx0JCggJ2JvZHknICkuYWRkQ2xhc3MoICdVTklUX1RFU1RfTU9ERScgKTtcblx0RGVidWcuc2V0RW5hYmxlKCB0cnVlICk7XG5cdERlYnVnLnNldFZlcmJvc2l0eSggMTEgKTtcbn07XG5cbkdsb2JhbC5jb252ZXJ0VmFsaWRhdGlvbkVycm9yVG9TdHJpbmcgPSBmdW5jdGlvbiggb2JqZWN0ICkge1xuXHQvL0RlYnVnLkFycihvYmplY3QsJ0NvbnZlcnRpbmcgRXJyb3IgdG8gU3RyaW5nOiAnLCdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2NvbnZlcnRWYWxpZGF0aW9uRXJyb3JUb1N0cmluZycsIDEwKTtcblx0dmFyIHJldHZhbCA9ICcnO1xuXG5cdC8vICMyMjg4IC0gSWYgeW91IGFyZSBkZWxldGluZyBzZXZlcmFsIHJlY29yZHMgYW5kIHJlY29yZHMgMiBhbmQgNCBjb250YWluIGVycm9ycywgdGhvc2UgYXJlIHRoZSBvYmplY3Qga2V5cyB0aGF0IHdpbGwgbmVlZCB0byBiZSByZWZlcmVuY2VkIGhlcmUuXG5cdC8vIFRvIGZpeCB0aGlzIHdlIG5lZWQgdG8gZ3JhYiB0aGUgZmlyc3QgZWxlbWVudCBpbmRlcGVuZGVudCBvZiB0aGUgaW5kZXggbnVtYmVyLlxuXHRpZiAoIE9iamVjdC5rZXlzKCBvYmplY3QgKS5sZW5ndGggPiAwICkge1xuXHRcdGZvciAoIHZhciBmaXJzdCBpbiBvYmplY3QgKSB7XG5cdFx0XHRvYmplY3QgPSBvYmplY3RbZmlyc3RdO1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0dmFyIGVycm9yX3N0cmluZ3MgPSBbXTtcblx0aWYgKCB0eXBlb2Ygb2JqZWN0ID09ICdzdHJpbmcnICkge1xuXHRcdC8vIzIyOTAgLSBlcnJvciBvYmplY3RzIGFyZSBub3QgYWx3YXlzIHVuaWZvcm0gYW5kIGNhbiBzb21ldGltZXMgY2F1c2UgbWFsZm9ybWVkIGVycm9yIHRpcHMgKHNlZSBzY3JlZW5zaG90KSBpZiB3ZSBkbyBub3QgY2hlY2sgZWFjaCBsZXZlbCBmb3Igc3RyaW5nIHR5cGVcblx0XHRlcnJvcl9zdHJpbmdzLnB1c2goIG9iamVjdCApO1xuXHR9IGVsc2Uge1xuXHRcdGZvciAoIHZhciBpbmRleCBpbiBvYmplY3QgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBvYmplY3RbaW5kZXhdID09ICdzdHJpbmcnICkge1xuXHRcdFx0XHRlcnJvcl9zdHJpbmdzLnB1c2goIG9iamVjdFtpbmRleF0gKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoIHZhciBrZXkgaW4gb2JqZWN0W2luZGV4XSApIHtcblx0XHRcdFx0XHRpZiAoIHR5cGVvZiAoIG9iamVjdFtpbmRleF1ba2V5XSApID09ICdzdHJpbmcnICkge1xuXHRcdFx0XHRcdFx0ZXJyb3Jfc3RyaW5ncy5wdXNoKCBvYmplY3RbaW5kZXhdW2tleV0gKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Zm9yICggdmFyIGkgaW4gb2JqZWN0W2luZGV4XVtrZXldICkge1xuXHRcdFx0XHRcdFx0XHRlcnJvcl9zdHJpbmdzLnB1c2goIG9iamVjdFtpbmRleF1ba2V5XVtpXSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmICggZXJyb3Jfc3RyaW5ncy5sZW5ndGggPiAxICkge1xuXHRcdHZhciBlcnJvcl9jb3VudCA9IDE7XG5cdFx0Zm9yICggdmFyIGluZGV4IGluIGVycm9yX3N0cmluZ3MgKSB7XG5cdFx0XHRyZXR2YWwgKz0gZXJyb3JfY291bnQgKyAnLiAnICsgZXJyb3Jfc3RyaW5nc1tpbmRleF0gKyAnLjxicj4nO1xuXHRcdFx0ZXJyb3JfY291bnQrKztcblx0XHR9XG5cdH0gZWxzZSBpZiAoIHR5cGVvZiBlcnJvcl9zdHJpbmdzWzBdID09ICdzdHJpbmcnICkge1xuXHRcdHJldHZhbCA9IGVycm9yX3N0cmluZ3NbMF0gKyAnLic7XG5cdH1cblxuXHRyZXR1cm4gcmV0dmFsO1xufTtcblxuR2xvYmFsLkFQSUZpbGVEb3dubG9hZCA9IGZ1bmN0aW9uKCBjbGFzc19uYW1lLCBtZXRob2QsIHBvc3RfZGF0YSwgdXJsICkge1xuXHRpZiAoIHVybCA9PSB1bmRlZmluZWQgKSB7XG5cdFx0dXJsID0gU2VydmljZUNhbGxlci5nZXRBUElVUkwoICdDbGFzcz0nICsgY2xhc3NfbmFtZSArICcmTWV0aG9kPScgKyBtZXRob2QgKTtcblx0fVxuXG5cdHZhciBtZXNzYWdlX2lkID0gVFRVVUlELmdlbmVyYXRlVVVJRCgpO1xuXHR1cmwgPSB1cmwgKyAnJk1lc3NhZ2VJRD0nICsgbWVzc2FnZV9pZDtcblxuXHR2YXIgdGVtcEZvcm0gPSAkKCAnPGZvcm0+PC9mb3JtPicgKTtcblx0dGVtcEZvcm0uYXR0ciggJ2lkJywgJ3RlbXBfZm9ybScgKTtcblx0dGVtcEZvcm0uYXR0ciggJ21ldGhvZCcsICdQT1NUJyApO1xuXHR0ZW1wRm9ybS5hdHRyKCAnYWN0aW9uJywgdXJsICk7XG5cblx0dGVtcEZvcm0uYXR0ciggJ3RhcmdldCcsIGlzX2Jyb3dzZXJfaU9TID8gJ19ibGFuaycgOiAnaGlkZVJlcG9ydElGcmFtZScgKTsgLy9oaWRlUmVwb3J0SUZyYW1lXG5cblx0dGVtcEZvcm0uYXBwZW5kKCAkKCAnPGlucHV0IHR5cGU9XFwnaGlkZGVuXFwnIG5hbWU9XFwnWC1DbGllbnQtSURcXCcgdmFsdWU9XFwnQnJvd3Nlci1UaW1lVHJleFxcJz4nICkgKTtcblx0dGVtcEZvcm0uYXBwZW5kKCAkKCAnPGlucHV0IHR5cGU9XFwnaGlkZGVuXFwnIG5hbWU9XFwnWC1DU1JGLVRva2VuXFwnIHZhbHVlPVxcJycgKyBnZXRDb29raWUoICdDU1JGLVRva2VuJyApICsgJ1xcJz4nICkgKTtcblxuXHR0ZW1wRm9ybS5jc3MoICdkaXNwbGF5JywgJ25vbmUnICk7XG5cdGlmICggcG9zdF9kYXRhICkge1xuXHRcdHZhciBoaWRlSW5wdXQgPSAkKCAnPGlucHV0IHR5cGU9XFwnaGlkZGVuXFwnIG5hbWU9XFwnanNvblxcJz4nICk7XG5cdFx0aGlkZUlucHV0LnZhbCggSlNPTi5zdHJpbmdpZnkoIHBvc3RfZGF0YSApICk7XG5cdFx0dGVtcEZvcm0uYXBwZW5kKCBoaWRlSW5wdXQgKTtcblx0fVxuXHR0ZW1wRm9ybS5hcHBlbmRUbyggJ2JvZHknICk7XG5cdHRlbXBGb3JtLmNzcyggJ2Rpc3BsYXknLCAnbm9uZScgKTtcblx0dGVtcEZvcm0uc3VibWl0KCk7XG5cdHRlbXBGb3JtLnJlbW92ZSgpO1xuXG5cdGlmICggIWlzX2Jyb3dzZXJfaU9TICkge1xuXHRcdFByb2dyZXNzQmFyLnNob3dQcm9ncmVzc0JhciggbWVzc2FnZV9pZCwgdHJ1ZSApO1xuXHR9XG59O1xuXG5HbG9iYWwuSlNGaWxlRG93bmxvYWQgPSBmdW5jdGlvbiggZmlsZV9uYW1lLCBjb250ZW50LCBtaW1lX3R5cGUgKSB7XG5cdHZhciBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ2EnICk7XG5cdG1pbWVfdHlwZSA9IG1pbWVfdHlwZSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJztcblxuXHRpZiAoIFVSTCAmJiAnZG93bmxvYWQnIGluIGEgKSB7IC8vaHRtbDUgQVtkb3dubG9hZF1cblx0XHRhLmhyZWYgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKCBuZXcgQmxvYiggW2NvbnRlbnRdLCB7XG5cdFx0XHR0eXBlOiBtaW1lX3R5cGVcblx0XHR9ICkgKTtcblx0XHRhLnNldEF0dHJpYnV0ZSggJ2Rvd25sb2FkJywgZmlsZV9uYW1lICk7XG5cdFx0ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCggYSApO1xuXHRcdGEuY2xpY2soKTtcblx0XHRkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKCBhICk7XG5cdH0gZWxzZSB7XG5cdFx0bG9jYXRpb24uaHJlZiA9ICdkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSwnICsgZW5jb2RlVVJJQ29tcG9uZW50KCBjb250ZW50ICk7IC8vIG9ubHkgdGhpcyBtaW1lIHR5cGUgaXMgc3VwcG9ydGVkXG5cdH1cbn07XG5cbi8vR2V0IGEgcmVmcmVzaGVkIENTUkYgdG9rZW4gY29va2llIGluIGNhc2UgaXQgZXhwaXJlcyBwcmlvciB0byB0aGUgdXNlciBjbGlja2luZyB0aGUgbG9naW4gYnV0dG9uLiBUaGlzIGhlbHBzIGF2b2lkIHNob3dpbmcgYW4gZXJyb3IgbWVzc2FnZSBhbmQgdHJpZ2dlcmluZyBhIGZ1bGwgYnJvd3NlciByZWZyZXNoLlxuR2xvYmFsLnJlZnJlc2hDU1JGVG9rZW4gPSBmdW5jdGlvbiggY2FsbGJhY2sgKSB7XG5cdGlmICggZ2V0Q29va2llKCAnQ1NSRi1Ub2tlbicgKSA9PSAnJyApIHtcblx0XHREZWJ1Zy5UZXh0KCAnQ1NSRiBUb2tlbiBjb29raWUgZG9lcyBub3QgZXhpc3QsIHJlZnJlc2hpbmcuLi4nLCAnR2xvYmFsLmpzJywgJycsICdyZWZyZXNoQ1NSRlRva2VuJywgMTAgKTtcblx0XHR0aGlzLmF1dGhlbnRpY2F0aW9uX2FwaSA9IFRUQVBJLkFQSUF1dGhlbnRpY2F0aW9uO1xuXHRcdHRoaXMuYXV0aGVudGljYXRpb25fYXBpLnNlbmRDU1JGVG9rZW5Db29raWUoIHtcblx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCBlICkge1xuXHRcdFx0XHRcdERlYnVnLlRleHQoICdDU1JGIFJlZnJlc2ggc3VjY2VzcyEuLi4nLCBudWxsLCBudWxsLCAncmVmcmVzaENTUkZUb2tlbicsIDEwICk7XG5cdFx0XHRcdFx0Y2FsbGJhY2soKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0b25FcnJvcjogZnVuY3Rpb24oIGUgKSB7XG5cdFx0XHRcdFx0RGVidWcuVGV4dCggJ0NTUkYgUmVmcmVzaCBFcnJvci4uLicsIG51bGwsIG51bGwsICdyZWZyZXNoQ1NSRlRva2VuJywgMTAgKTtcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xuXHRcdFx0XHR9LFxuXHRcdFx0fSk7XG5cdH0gZWxzZSB7XG5cdFx0Y2FsbGJhY2soKTtcblx0fVxuXG5cdHJldHVybiB0cnVlO1xufTtcblxuR2xvYmFsLnJlZnJlc2hQZXJtaXNzaW9ucyA9IGZ1bmN0aW9uKCkge1xuXHR0aGlzLmF1dGhlbnRpY2F0aW9uX2FwaSA9IFRUQVBJLkFQSVBlcm1pc3Npb247XG5cdHRoaXMuYXV0aGVudGljYXRpb25fYXBpLmdldFBlcm1pc3Npb25zKCB7XG5cdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXNwb25zZSApIHtcblx0XHRcdGxldCByZXN1bHQgPSByZXNwb25zZS5nZXRSZXN1bHQoKTtcblx0XHRcdGlmICggcmVzdWx0ICE9PSBmYWxzZSApIHtcblx0XHRcdFx0TG9jYWxDYWNoZURhdGEuc2V0UGVybWlzc2lvbkRhdGEoIHJlc3VsdCApO1xuXHRcdFx0XHREZWJ1Zy5UZXh0KCAnUGVybWlzc2lvbnMgUmVmcmVzaGVkIScsICdHbG9iYWwuanMnLCBudWxsLCAncmVmcmVzaFBlcm1pc3Npb25zJywgMTAgKTtcblx0XHRcdH1cblx0XHR9LFxuXHR9KTtcbn07XG5cbkdsb2JhbC5zZXRTdGF0aW9uSUQgPSBmdW5jdGlvbiggdmFsICkge1xuXHRzZXRDb29raWUoICdTdGF0aW9uSUQnLCB2YWwsIDEwMDAwICk7XG59O1xuXG5HbG9iYWwuZ2V0U3RhdGlvbklEID0gZnVuY3Rpb24oKSB7XG5cdHZhciByZXR2YWwgPSBnZXRDb29raWUoICdTdGF0aW9uSUQnICk7XG5cblx0Ly9DaGVjayB0byBzZWUgaWYgdGhlcmUgaXMgYSBcInN0aWNreVwiIHVzZXIgYWdlbnQgYmFzZWQgU3RhdGlvbiBJRCBkZWZpbmVkLlxuXHRpZiAoIG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZiggJ1N0YXRpb25JRDonICkgIT0gLTEgKSB7XG5cdFx0dmFyIHJlZ2V4ID0gL1N0YXRpb25JRDpcXHM/KFthLXpBLVowLTldezMwLDY0fSkvaTtcblx0XHR2YXIgbWF0Y2hlcyA9IHJlZ2V4LmV4ZWMoIG5hdmlnYXRvci51c2VyQWdlbnQgKTtcblx0XHRpZiAoIG1hdGNoZXNbMV0gKSB7XG5cdFx0XHREZWJ1Zy5UZXh0KCAnRm91bmQgU3RhdGlvbklEIGluIHVzZXIgYWdlbnQsIGZvcmNpbmcgdG8gdGhhdCBpbnN0ZWFkIScsICdHbG9iYWwuanMnLCAnJywgJ2dldFN0YXRpb25JRCcsIDExICk7XG5cdFx0XHRyZXR2YWwgPSBtYXRjaGVzWzFdO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiByZXR2YWw7XG59O1xuXG4vLyMyMzQyIC0gQ2xvc2UgYWxsIG9wZW4gZWRpdCB2aWV3cyBmcm9tIG9uZSBwbGFjZS5cbkdsb2JhbC5jbG9zZUVkaXRWaWV3cyA9IGZ1bmN0aW9uKCBjYWxsYmFjayApIHtcblx0Ly9Eb24ndCBjaGVjayB0aGUgLmlzX2NoYW5nZWQgZmxhZywgYXMgdGhhdCB3aWxsIHByZXZlbnQgZWRpdCB2aWV3cyBmcm9tIGJlaW5nIGNsb3NlZCBpZiBubyBkYXRhIGhhcyBiZWVuIGNoYW5nZWQuXG5cdC8vICBGb3IgZXhhbXBsZSBpZiB5b3UgZ28gdG8gTXlBY2NvdW50IC0+IFJlcXVlc3QgQXV0aG9yaXphdGlvbiwgVmlldyBhbnkgcmVxdWVzdCwgY2xpY2sgdGhlIFwiVGltZVNoZWV0XCIgaWNvbiwgdGhlbiBjbGljayB0aGUgUmVxdWVzdCB0aW1lc2hlZXQgY2VsbCAoanVzdCBiZWxvdyB0aGUgcHVuY2hlcykgdG8gbmF2aWdhdGUgYmFjayB0byB0aGUgcmVxdWVzdHMuXG5cdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3JlcG9ydF9jb250cm9sbGVyICkgeyAvLyYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9yZXBvcnRfY29udHJvbGxlci5pc19jaGFuZ2VkID09IHRydWUgKSB7XG5cdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3JlcG9ydF9jb250cm9sbGVyLm9uQ2FuY2VsQ2xpY2soIG51bGwsIG51bGwsIGZ1bmN0aW9uKCkge1xuXHRcdFx0R2xvYmFsLmNsb3NlRWRpdFZpZXdzKCBjYWxsYmFjayApO1xuXHRcdH0gKTtcblx0fSBlbHNlIGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX2VkaXRfb25seV9jb250cm9sbGVyICkgeyAvLyYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlci5pc19jaGFuZ2VkID09IHRydWUgKSB7XG5cdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX2VkaXRfb25seV9jb250cm9sbGVyLm9uQ2FuY2VsQ2xpY2soIG51bGwsIG51bGwsIGZ1bmN0aW9uKCkge1xuXHRcdFx0R2xvYmFsLmNsb3NlRWRpdFZpZXdzKCBjYWxsYmFjayApO1xuXHRcdH0gKTtcblx0fSBlbHNlIGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyICYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9zdWJfY29udHJvbGxlci5lZGl0X3ZpZXcgKSB7IC8vJiYgTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyLmlzX2NoYW5nZWQgPT0gdHJ1ZSApIHtcblx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fc3ViX2NvbnRyb2xsZXIub25DYW5jZWxDbGljayggbnVsbCwgbnVsbCwgZnVuY3Rpb24oKSB7XG5cdFx0XHRHbG9iYWwuY2xvc2VFZGl0Vmlld3MoIGNhbGxiYWNrICk7XG5cdFx0fSApO1xuXHR9IGVsc2UgaWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuZWRpdF92aWV3ICkgeyAvLyYmIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuaXNfY2hhbmdlZCA9PSB0cnVlICkge1xuXHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIub25DYW5jZWxDbGljayggbnVsbCwgbnVsbCwgZnVuY3Rpb24oKSB7XG5cdFx0XHRHbG9iYWwuY2xvc2VFZGl0Vmlld3MoIGNhbGxiYWNrICk7XG5cdFx0fSApO1xuXHR9IGVsc2UgaWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICYmXG5cdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci52aWV3SWQgPT09ICdUaW1lU2hlZXQnICYmXG5cdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5nZXRQdW5jaE1vZGUoKSA9PT0gJ21hbnVhbCcgKSB7XG5cdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5kb05leHRJZk5vVmFsdWVDaGFuZ2VJbk1hbnVhbEdyaWQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8jMjU2NyBNdXN0IGNvbmNsdWRlIGhlcmUuIFJlY3Vyc2lvbiB3b3VsZCBiZSBpbmZpbml0ZVxuXHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0Y2FsbGJhY2soKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0gZWxzZSB7XG5cdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0fVxuXHR9XG59O1xuXG4vLyMyMzUxIC0gcmVkIGJvcmRlciBmb3Igc2FuZGJveCBtb2RlXG5HbG9iYWwuc3R5bGVTYW5kYm94ID0gZnVuY3Rpb24oKSB7XG5cdGlmICggQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhWydzYW5kYm94J10gJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhWydzYW5kYm94J10gPT0gdHJ1ZSApIHtcblx0XHQkKCAnYm9keScgKS5hZGRDbGFzcyggJ3NhbmRib3hfY29udGFpbmVyJyApO1xuXHR9XG59O1xuXG4vLyMyMzUxIC0gVXNlZCBmb3IgbG9nZ2luZyBpbiBhcyBlbXBsb3llZS9jbGllbnQgb3Igc3dpdGNoaW5nIHRvIHNhbmRib3ggbW9kZS5cbkdsb2JhbC5OZXdTZXNzaW9uID0gZnVuY3Rpb24oIHVzZXJfaWQsIGNsaWVudF9pZCApIHtcblx0dmFyIGFwaV9hdXRoID0gVFRBUEkuQVBJQXV0aGVudGljYXRpb247XG5cdGFwaV9hdXRoLm5ld1Nlc3Npb24oIHVzZXJfaWQsIGNsaWVudF9pZCwge1xuXHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdFx0aWYgKCAhcmVzdWx0LmlzVmFsaWQoKSApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgcmVzdWx0X2RhdGEgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cdFx0XHRpZiAoIHJlc3VsdF9kYXRhICYmIHJlc3VsdF9kYXRhLnVybCApIHtcblx0XHRcdFx0dmFyIHVybCA9IHJlc3VsdF9kYXRhLnVybDtcblx0XHRcdFx0aWYgKCB1cmwuaW5kZXhPZiggJ2h0dHAnICkgPT09IC0xICkge1xuXHRcdFx0XHRcdHVybCA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArICcvLycgKyB1cmw7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR2YXIgYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSA9IHtcblx0XHRcdFx0XHRuZXdfc2Vzc2lvbl9pZDogcmVzdWx0X2RhdGEuc2Vzc2lvbl9pZCxcblx0XHRcdFx0XHRwcmV2aW91c19zZXNzaW9uX2lkOiBnZXRDb29raWUoIEdsb2JhbC5nZXRTZXNzaW9uSURLZXkoKSApLFxuXHRcdFx0XHRcdHByZXZpb3VzX3Nlc3Npb25fdXJsOiBHbG9iYWwuZ2V0QmFzZVVSTCgpLFxuXHRcdFx0XHRcdHByZXZpb3VzX3Nlc3Npb25fdmlldzogd2luZG93LmxvY2F0aW9uLmhyZWYuc3BsaXQoICcjIW09JyApWzFdLFxuXHRcdFx0XHRcdHByZXZpb3VzX2Nvb2tpZV9wYXRoOiBMb2NhbENhY2hlRGF0YS5jb29raWVfcGF0aFxuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdHNldENvb2tpZSggJ0FsdGVybmF0ZVNlc3Npb25EYXRhJywgSlNPTi5zdHJpbmdpZnkoIGFsdGVybmF0ZV9zZXNzaW9uX2RhdGEgKSwgMSwgcmVzdWx0X2RhdGEuY29va2llX2Jhc2VfdXJsLCBHbG9iYWwuZ2V0SG9zdCgpICk7XG5cblx0XHRcdFx0R2xvYmFsLnNldFVSTFRvQnJvd3NlciggdXJsICsgJ2h0bWw1LyMhbT1Mb2dpbicgKTtcblx0XHRcdFx0R2xvYmFsLm5lZWRSZWxvYWRCcm93c2VyID0gdHJ1ZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFRBbGVydE1hbmFnZXIuc2hvd0FsZXJ0KCAkLmkxOG4uXyggJ0VSUk9SOiBVbmFibGUgdG8gcGVyZm9ybSBhY3Rpb24sIHBsZWFzZSBjb250YWN0IHlvdXIgJXMgYWRtaW5pc3RyYXRvciBpbW1lZGlhdGVseS4nLCBMb2NhbENhY2hlRGF0YS5nZXRBcHBsaWNhdGlvbk5hbWUoKSApLCAkLmkxOG4uXyggJ0VSUk9SJyApICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG5cbn07XG5cbkdsb2JhbC5pc051bWVyaWMgPSBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdHZhciByZXR2YWwgPSBmYWxzZTtcblxuXHR2YWx1ZSA9IHBhcnNlRmxvYXQoIHZhbHVlICk7XG5cdGlmICggdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmICFpc05hTiggdmFsdWUgKSApIHtcblx0XHRyZXR2YWwgPSB0cnVlO1xuXHR9XG5cblx0cmV0dXJuIHJldHZhbDtcbn07XG5cbi8vQ2FsY3VsYXRlcyBhIFwic21hcnRcIiBkZWJvdW5jZSB0aW1lIGJhc2VkIG9uIHRoZSBuZXR3b3JrIHBpbmcgdGltZS5cbi8vRGVib3VuY2Ugb24gYXQgbGVhc3QgMS41eCB0aGUgcm91bmQtdHJpcCBwaW5nIHRpbWUuICggMzMzICogMS41ID0gNTAwbXMuIClcbi8vQmVjYXVzZSBhIHVzZXIgb24gYSByZWFsbHkgc2xvdyBjb25uZWN0aW9uIGNvdWxkIGNsaWNrIFNhdmUgMXMgYXBhcnQgYW5kIHRoZSBwYWNrZXRzIGNvdWxkIGFycml2ZSBjbG9zZSB0byBlYWNoIG90aGVyIGFuZCBjYXVzZSBkdXBsaWNhdGUgcmVxdWVzdCBlcnJvcnMgc3RpbGwuXG5HbG9iYWwuY2FsY0RlYm91bmNlV2FpdFRpbWVCYXNlZE9uTmV0d29yayA9IGZ1bmN0aW9uKCBtaW5fdGltZSA9IG51bGwsIG1heF90aW1lID0gbnVsbCApIHtcblx0dmFyIHBpbmcgPSBHbG9iYWwuY3VycmVudF9waW5nO1xuXG5cdGlmICggIW1pbl90aW1lICkge1xuXHRcdHZhciBtaW5fdGltZSA9IDUwMDsgLy9UdXJucyBpbnRvIDUwMG1zIGFmdGVyIDEuNXhcblx0fVxuXG5cdGlmICggIW1heF90aW1lICkge1xuXHRcdHZhciBtYXhfdGltZSA9IDEwMDAwOyAvL1R1cm5zIGludG8gMTBzIGFmdGVyIDEuNXhcblx0fVxuXG5cdHZhciByZXR2YWwgPSAoIHBpbmcgKiAxLjUgKTtcblxuXHRpZiAoIHJldHZhbCA8IG1pbl90aW1lICkge1xuXHRcdHJldHZhbCA9IG1pbl90aW1lO1xuXHR9XG5cblx0aWYgKCByZXR2YWwgPiBtYXhfdGltZSApIHtcblx0XHRyZXR2YWwgPSBtYXhfdGltZTtcblx0fVxuXG5cdHJldHVybiByZXR2YWw7XG59XG5cbi8vIFJldHVybnMgYSBmdW5jdGlvbiwgdGhhdCwgYXMgbG9uZyBhcyBpdCBjb250aW51ZXMgdG8gYmUgaW52b2tlZCwgd2lsbCBub3QgYmUgdHJpZ2dlcmVkLiBUaGUgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgaXQgc3RvcHMgYmVpbmcgY2FsbGVkIGZvciBOIG1pbGxpc2Vjb25kcy5cbi8vIElmIGBpbW1lZGlhdGVgIGlzIHBhc3NlZCwgdHJpZ2dlciB0aGUgZnVuY3Rpb24gb24gdGhlIGxlYWRpbmcgZWRnZSwgaW5zdGVhZCBvZiB0aGUgdHJhaWxpbmcuXG5HbG9iYWwuZGVib3VuY2UgPSBmdW5jdGlvbiggY2FsbGJhY2ssIHdhaXQsIGltbWVkaWF0ZSApIHtcblx0dmFyIHRpbWVvdXQ7XG5cblx0cmV0dXJuIGZ1bmN0aW9uKCkge1xuXHRcdHZhciBjb250ZXh0ID0gdGhpcztcblx0XHR2YXIgYXJncyA9IGFyZ3VtZW50cztcblxuXHRcdHZhciBjYWxsYmFja19uYW1lID0gKCBjYWxsYmFjay5uYW1lICkgPyBjYWxsYmFjay5uYW1lIDogJ04vQSc7XG5cblx0XHR2YXIgbGF0ZXIgPSBmdW5jdGlvbigpIHtcblx0XHRcdHRpbWVvdXQgPSBudWxsO1xuXHRcdFx0aWYgKCAhaW1tZWRpYXRlICkge1xuXHRcdFx0XHREZWJ1Zy5UZXh0KCAnQ2FsbGluZyBhZnRlciBkZWJvdW5jZSB3YWl0OiAnICsgY2FsbGJhY2tfbmFtZSArICcgV2FpdCBUaW1lOiAnICsgd2FpdCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnZGVib3VuY2UnLCAxMCApO1xuXHRcdFx0XHRjYWxsYmFjay5hcHBseSggY29udGV4dCwgYXJncyApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0RGVidWcuVGV4dCggJ1NraXBwaW5nIGR1ZSB0byBkZWJvdW5jZTogJyArIGNhbGxiYWNrX25hbWUgKyAnIFdhaXQgVGltZTogJyArIHdhaXQsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ2RlYm91bmNlJywgMTEgKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dmFyIGNhbGxfbm93ID0gaW1tZWRpYXRlICYmICF0aW1lb3V0O1xuXG5cdFx0Y2xlYXJUaW1lb3V0KCB0aW1lb3V0ICk7XG5cblx0XHR0aW1lb3V0ID0gc2V0VGltZW91dCggbGF0ZXIsIHdhaXQgKTtcblxuXHRcdGlmICggY2FsbF9ub3cgKSB7XG5cdFx0XHREZWJ1Zy5UZXh0KCAnQ2FsbGluZyBpbW1lZGlhdGUgZGVib3VuY2U6ICcgKyBjYWxsYmFja19uYW1lICsgJyBXYWl0IFRpbWU6ICcgKyB3YWl0LCAnR2xvYmFsLmpzJywgJ0dsb2JhbCcsICdkZWJvdW5jZScsIDEwICk7XG5cdFx0XHRjYWxsYmFjay5hcHBseSggY29udGV4dCwgYXJncyApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHREZWJ1Zy5UZXh0KCAnU2tpcHBpbmcgZHVlIHRvIGRlYm91bmNlOiAnICsgY2FsbGJhY2tfbmFtZSArICcgV2FpdCBUaW1lOiAnICsgd2FpdCwgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnZGVib3VuY2UnLCAxMSApO1xuXHRcdH1cblx0fTtcbn07XG5cbi8qKlxuICogRmlsdGVyIG91dHB1dCB0byBwcmV2ZW50IHRoZSB1c2VyIGZyb20gc2VlaW5nIHN0cmluZ3Mgc3VjaCBhcyB1bmRlZmluZWQsIGZhbHNlIG9yIG51bGwuXG4gKiBAcGFyYW0ge3N0cmluZ30gZW50cnkgdGhlIHN0cmluZyB0aGF0IG5lZWRzIHRvIGJlIHNhbml0aXplZC5cbiAqIEBwYXJhbSB7QXJyYXl9IFtmaWx0ZXJzXSBvcHRpb25hbCBhcnJheSBvZiBmaWx0ZXJzLiBJZiBub25lIGlzIHN1cHBsaWVkLCBkZWZhdWx0cyB3aWxsIGJlIHVzZWQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSByZXR1cm5zIHRoZSBzYW5pdGl6ZWQgc3RyaW5nIHJlc3VsdFxuICovXG5HbG9iYWwuZmlsdGVyT3V0cHV0ID0gZnVuY3Rpb24oIGVudHJ5LCBmaWx0ZXJzICkge1xuXHQvLyBkZWZhdWx0IGZpbHRlcnMgY2FuIGJlIG92ZXJyaWRkZW4gYnkgcGFzc2luZyBpbiBhIHNlY29uZCBwYXJhbVxuXG5cdGlmICggIWZpbHRlcnMgKSB7XG5cdFx0ZmlsdGVycyA9IFtmYWxzZSwgdW5kZWZpbmVkLCBudWxsLCAnZmFsc2UnLCAndW5kZWZpbmVkJywgJ251bGwnXTtcblx0fVxuXG5cdC8vIGlmIGZpbHRlciBtYXRjaGVzLCByZXBsYWNlIGNvbnRlbnRzIHdpdGggZW1wdHkgc3RyaW5nXG5cdGlmICggKCBmaWx0ZXJzLmluZGV4T2YoIGVudHJ5ICkgIT09IC0xICkgKSB7XG5cdFx0cmV0dXJuICcnO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBlbnRyeTtcblx0fVxufTtcblxuLyoqXG4gKiBncm91cEFycmF5RGF0YUJ5S2V5IC0gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGdyb3VwIGRhdGEgYnkgb2JqZWN0IGtleSAtIHVzZWQgKHNvIGZhcikgZm9yIHRoZSBnZW9mZW5jZSBmaWx0ZXJzXG4gKiBAcGFyYW0ge09iamVjdFtdfSBkYXRhIC0gdGhlIGFycmF5IGRhdGFzZXRcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW21ha2VVbmlxdWVdIC0gdHJ1ZSB3aWxsIG9ubHkgb3V0cHV0IG9uZSBvY2N1cmFuY2UgcGVyIGtleS4gZmFsc2Ugb3Igb21taXRpbmcgd2lsbCByZXR1cm4gYWxsIG9jY3VyYW5jZXNcbiAqIEByZXR1cm5zIHsqfVxuICovXG5HbG9iYWwuZ3JvdXBBcnJheURhdGFCeUtleSA9IGZ1bmN0aW9uKCBkYXRhLCBtYWtlVW5pcXVlICkge1xuXG5cdHJldHVybiBkYXRhLnJlZHVjZSggZnVuY3Rpb24oIGFjY3VtdWxhdG9yLCBjdXJyZW50VmFsdWUgKSB7XG5cdFx0Ly8gZ2V0IGEgbGlzdCBvZiBhbGwgb2JqZWN0IGtleXMgZm9yIGRhdGEgb2JqZWN0LCB0aGVuIGl0ZXJhdGUgdGhyb3VnaCBlYWNoXG5cdFx0T2JqZWN0LmVudHJpZXMoIGN1cnJlbnRWYWx1ZSApLmZvckVhY2goIGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0XHRhY2N1bXVsYXRvcltrZXlbMF1dID0gYWNjdW11bGF0b3Jba2V5WzBdXSB8fCBbXTtcblxuXHRcdFx0Ly8gY2hlY2sgaWYgdmFsdWUgZXhpc3RzIG9yIGFkZCBhbnl3YXkgaWYgbWFrZVVuaXF1ZSBpcyBmYWxzZVxuXHRcdFx0aWYgKCBhY2N1bXVsYXRvcltrZXlbMF1dLmluZGV4T2YoIGtleVsxXSApID09PSAtMSB8fCAhbWFrZVVuaXF1ZSApIHtcblx0XHRcdFx0YWNjdW11bGF0b3Jba2V5WzBdXS5wdXNoKCBrZXlbMV0gKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdFx0cmV0dXJuIGFjY3VtdWxhdG9yO1xuXHR9LCB7fSApO1xufTtcblxuLyoqXG4gKiBVc2VkIHRvIG1vZGlmeSB0aGUgdmlld3BvcnQgbWV0YSB0YWcgaW4gdGhlIGluZGV4LnBocCBoZWFkIHNlY3Rpb24uIFRoaXMgY29udHJvbHMgdGhlICd2aXJ0dWFsJyBkZXZpY2Ugdmlld3BvcnQgb24gbW9iaWxlIGRldmljZXMuXG4gKiBNb3JlIGluZm86IGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3dlYi91cGRhdGVzLzIwMTUvMDEvV2hhdC10aGUtVmlld3BvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBzZXR0aW5nIC0gbmFtZSBvZiBwcmUtZGVmaW5lZCB2aWV3cG9ydCBzZXR0aW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSByZXR1cm5zIHRoZSBuZXcgY29udGVudCB2YWx1ZSBmb3IgdGhlIHZpZXdwb3J0IG1ldGEgdGFnXG4gKiBAZXhhbXBsZSBBIHVzZSBjYXNlIGlzIFNldHRpbmcgbW9iaWxlIHZpZXcgb24gbG9naW4sIHRoZW4gYmFjayB0byBkZXNrdG9wICg5OTBweCB2aXJ0dWFsKSBhZnRlciBsb2dpbiwgdG8gYWxsb3cgcGFuICYgem9vbSwgYXMgbm90IHdob2xlIGFwcCBpcyBtb2JpbGUgb3B0aW1pemVkLlxuICovXG5HbG9iYWwuc2V0VmlydHVhbERldmljZVZpZXdwb3J0ID0gZnVuY3Rpb24oIHNldHRpbmcgKSB7XG5cdHZhciB3aWR0aDtcblx0dmFyIHNjYWxlO1xuXHR2YXIgbWV0YV90YWdfdmlld3BvcnQgPSAkKCAnbWV0YVtuYW1lPXZpZXdwb3J0XScgKTtcblxuXHRpZiAoICFzZXR0aW5nIHx8ICFtZXRhX3RhZ192aWV3cG9ydCB8fCBtZXRhX3RhZ192aWV3cG9ydC5sZW5ndGggIT09IDEgKSB7XG5cdFx0RGVidWcuVGV4dCggJ0Vycm9yOiBNaXNzaW5nIHBhcmFtcyBpbiBmdW5jdGlvbiBjYWxsJywgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnc2V0VmlydHVhbERldmljZVZpZXdwb3J0JywgMSApO1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0aWYgKCBzZXR0aW5nID09PSAnbW9iaWxlJyApIHtcblx0XHR3aWR0aCA9ICdkZXZpY2Utd2lkdGgnO1xuXHRcdHNjYWxlID0gMTtcblx0fSBlbHNlIGlmICggc2V0dGluZyA9PT0gJ2Rlc2t0b3AnICkge1xuXHRcdHdpZHRoID0gOTkwOyAvLyBNaW5pdW0gYXBwbGljYXRpb24gd2lkdGggd2hpY2ggd2FzIHByZXZpb3VzbHkgdXNlZCBlbHNld2hlcmUuXG5cdFx0c2NhbGUgPSAwLjU7XG5cdH0gZWxzZSB7XG5cdFx0RGVidWcuVGV4dCggJ0Vycm9yOiBJbnZhbGlkIHNldHRpbmcgcGFzc2VkIHRvIGZ1bmN0aW9uJywgJ0dsb2JhbC5qcycsICdHbG9iYWwnLCAnc2V0VmlydHVhbERldmljZVZpZXdwb3J0JywgMSApO1xuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblx0aWYgKCB3aWR0aCAmJiBzY2FsZSApIHtcblx0XHRtZXRhX3RhZ192aWV3cG9ydC5hdHRyKCAnY29udGVudCcsICd3aWR0aD0nICsgd2lkdGggKyAnLCBpbml0aWFsLXNjYWxlPScgKyBzY2FsZSApO1xuXHRcdHJldHVybiBtZXRhX3RhZ192aWV3cG9ydC5hdHRyKCAnY29udGVudCcgKTtcblx0fSBlbHNlIHtcblx0XHREZWJ1Zy5UZXh0KCAnRXJyb3I6IEludmFsaWQgZGV2aWNlIHNldHRpbmdzLiBFaXRoZXIgd2lkdGggb3Igc2NhbGUgaXMgaW52YWxpZCcsICdHbG9iYWwuanMnLCAnR2xvYmFsJywgJ3NldFZpcnR1YWxEZXZpY2VWaWV3cG9ydCcsIDEgKTtcblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG59O1xuXG4vL0NsZWFyIGFsbCBzZXNzaW9uIGFuZCBsb2NhbCBjYWNoZSBkYXRhIGZvciBsb2dvdXQuXG5HbG9iYWwuTG9nb3V0ID0gZnVuY3Rpb24oKSB7XG5cdFNlcnZpY2VDYWxsZXIuYWJvcnRBbGwoKTsgLy9BYm9ydCBhbnkgcGVuZGluZyBBSkFYIHJlcXVlc3RzIHNvIHRoZWlyIGNhbGxiYWNrcyBkb24ndCBnZXQgdHJpZ2dlcmVkIGFuZCBjYXVzZSBhbGwga2luZCBvZiB3ZWlyZG5lc3MuXG5cdExvY2FsQ2FjaGVEYXRhLmNsZWFuTmVjZXNzYXJ5Q2FjaGUoKTsgLy9CZWNhdXNlIHRoaXMgY2xvc2VzIFdpemFyZHMsIHdoaWNoIHRoZXkgY291bGQgcmVxdWlyZSBjYWNoZWQgZGF0YSB0byBtYWtlIEFQSSBjYWxscywgaXQgc2hvdWxkIHJ1biBiZWZvcmUgYW55IHRoaW5nIGlzIGFjdHVhbGx5IGNsZWFyZWQgZmlyc3QuXG5cdEdsb2JhbC5jbGVhclNlc3Npb25Db29raWUoKTtcblx0TG9jYWxDYWNoZURhdGEuc2V0U2Vzc2lvbklEKCAnJyApO1xuXHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fdmlld19pZCA9ICcnOyAvLyMxNTI4ICAtICBMb2dvdXQgaWNvbiBub3Qgd29ya2luZy5cblx0Ly9Mb2NhbENhY2hlRGF0YS5zZXRMb2dpbkRhdGEoIG51bGwgKTsgIC8vVGhpcyBpcyBjb21tb24gZGF0YSB0byB0aGUgVFQgaW5zdGFuY2UgKGllOiBhcHBsaWNhdGlvbl9uYW1lKSBhbmQgZG9lc24ndCByZWFsbHkgbmVlZCB0byBnZXQgcmVzZXQgb24gbG9nb3V0LlxuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2dpblVzZXIoIG51bGwgKTtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9naW5Vc2VyUHJlZmVyZW5jZSggbnVsbCApO1xuXHRMb2NhbENhY2hlRGF0YS5zZXRQZXJtaXNzaW9uRGF0YSggbnVsbCApO1xuXHRMb2NhbENhY2hlRGF0YS5zZXRDdXJyZW50Q29tcGFueSggbnVsbCApO1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMYXN0UHVuY2hUaW1lKCBudWxsICk7XG5cdExvY2FsQ2FjaGVEYXRhLnNldEpvYlF1ZXVlUHVuY2hEYXRhKCBudWxsICk7XG5cdHNlc3Npb25TdG9yYWdlLmNsZWFyKCk7XG5cblx0R2xvYmFsLmV2ZW50X2J1cy5lbWl0KCAnZ2xvYmFsJywgJ3Jlc2V0X3Z1ZV9kYXRhJyApOyAvLyBSZXNldCB2dWUgZGF0YSB0byBkZWZhdWx0IHZhbHVlcy4gT3RoZXJ3aXNlIHVzZXIgZGF0YSBmcm9tIHByZXZpb3VzIHNlc3Npb24gd2lsbCByZW1haW4uXG5cblx0Ly9Eb24ndCByZWxvYWQgb3IgY2hhbmdlIHZpZXdzLCBhbGxvdyB0aGF0IHRvIGJlIGRvbmUgYnkgdGhlIGNhbGxlci5cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG5cbkdsb2JhbC5nbG93QW5pbWF0aW9uID0ge1xuXHRzdGFydDogZnVuY3Rpb24oIGVsZW1lbnQsIGNvbG9yICkge1xuXHRcdGlmICggIWVsZW1lbnQgKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGlmICggIWNvbG9yICkge1xuXHRcdFx0Ly8gU2V0IGRlZmF1bHQgY29sb3IgdG8gZ3JlZW4uIFJlbWVtYmVyIHRoaXMgYWZmZWN0cyB0aGUgdGV4dCBjb2xvciBvZiB0aGUgZWxlbWVudCB0b28uIE1pZ2h0IHdhbnQgdG8gZGlzYWJsZSB0aGlzIGRlZmF1bHQgaW4gZnV0dXJlIGlmIHdlIHdhbnQgdG8gc2V0IGNvbG9yIHNlcGFyYXRlbHkgb3IgdXNlIGluaGVyaXRlZC9leGlzdGluZy5cblx0XHRcdGNvbG9yID0gJyMwMGZmMDAnO1xuXHRcdH1cblx0XHRyZXR1cm4gZWxlbWVudFxuXHRcdFx0LmNzcyggJ2NvbG9yJywgY29sb3IgKSAvLyBzZXRzIHRoZSBmb250IGNvbG9yIG9mIHRoZSBlbGVtZW50LiBUaGUgZ2xvdyB0aGVuIHVzZXMgdGhpcyB2YWx1ZSB2aWEgJ2N1cnJlbnRDb2xvcidcblx0XHRcdC5hZGRDbGFzcyggJ2FuaW1hdGUtZ2xvdycgKTtcblx0fSxcblx0c3RvcDogZnVuY3Rpb24oIGVsZW1lbnQgKSB7XG5cdFx0aWYgKCAhZWxlbWVudCApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIGVsZW1lbnQucmVtb3ZlQ2xhc3MoICdhbmltYXRlLWdsb3cnICk7XG5cdH1cbn07XG5cbkdsb2JhbC5idWlsZEFyZ0RpYyA9IGZ1bmN0aW9uKCBhcnJheSApIHtcblx0dmFyIGxlbiA9IGFycmF5Lmxlbmd0aDtcblx0dmFyIHJlc3VsdCA9IHt9O1xuXHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHR2YXIgaXRlbSA9IGFycmF5W2ldO1xuXHRcdGl0ZW0gPSBpdGVtLnNwbGl0KCAnPScgKTtcblx0XHRyZXN1bHRbaXRlbVswXV0gPSBpdGVtWzFdO1xuXHR9XG5cblx0cmV0dXJuIHJlc3VsdDtcbn07XG5cbkdsb2JhbC5nZXRGZWF0dXJlRmxhZyA9IGZ1bmN0aW9uKCBmbGFnLCBkZWZhdWx0X3ZhbHVlICkge1xuXHRsZXQgZmVhdHVyZV9mbGFncyA9IExvY2FsQ2FjaGVEYXRhLmdldEZlYXR1cmVGbGFnRGF0YSgpO1xuXG5cdC8vUG9zdCBsb2dpbiBoYXMgdXBkYXRlZCBmZWF0dXJlIGZsYWdzIGFuZCBhcmUgc3BlY2lmaWMgdG8gdGhlIGN1cnJlbnQgY29tcGFueS5cblx0aWYgKCBmZWF0dXJlX2ZsYWdzICYmIGZlYXR1cmVfZmxhZ3MuaGFzT3duUHJvcGVydHkoIGZsYWcgKSApIHtcblx0XHRyZXR1cm4gZmVhdHVyZV9mbGFnc1tmbGFnXTtcblx0fVxuXG5cdC8vSWYgd2Ugb25seSBoYXZlIHByZS1sb2dpbiBkcXRhLCB1c2UgdGhlIGZlYXR1cmUgZmxhZ3MgZm9yIHRoZSBpbnN0YWxsZWQgY29tcGFueS5cblx0aWYgKCBBUElHbG9iYWwucHJlX2xvZ2luX2RhdGEgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmZlYXR1cmVfZmxhZ3MgJiYgQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmZlYXR1cmVfZmxhZ3MuaGFzT3duUHJvcGVydHkoIGZsYWcgKSApIHtcblx0XHRyZXR1cm4gQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmZlYXR1cmVfZmxhZ3NbZmxhZ107XG5cdH1cblxuXHRyZXR1cm4gZGVmYXVsdF92YWx1ZTtcbn07XG5cbkdsb2JhbC5zaG93QXV0aGVudGljYXRpb25Nb2RhbCA9IGZ1bmN0aW9uKCB2aWV3X2lkLCBzZXNzaW9uX3R5cGUsIG1mYV9kYXRhLCBpc19yZWF1dGhlbnRpY2F0aW9uLCBhdXRoZW50aWNhdGVfY2FsbGJhY2ssIGVycm9yX3N0cmluZyA9ICcnLCBtb3VudF9pZCA9ICd0dF9hdXRoZW50aWNhdGVfdWknICkge1xuXHRUVFZ1ZVV0aWxzLm1vdW50Q29tcG9uZW50KCBtb3VudF9pZCwgVFRNdWx0aUZhY3RvckF1dGhlbnRpY2F0aW9uLCB7XG5cdFx0dmlld19pZDogdmlld19pZCxcblx0XHRzZXNzaW9uX3R5cGU6IHNlc3Npb25fdHlwZSxcblx0XHRjb21wb25lbnRfaWQ6IG1vdW50X2lkLFxuXHRcdG1mYV9kYXRhOiBtZmFfZGF0YSxcblx0XHR1c2VyX25hbWU6IExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlcigpID8gTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyKCkudXNlcl9uYW1lIDogJycsXG5cdFx0ZXJyb3Jfc3RyaW5nOiBMb2NhbENhY2hlRGF0YS5sb2dpbl9lcnJvcl9zdHJpbmcgfHwgZXJyb3Jfc3RyaW5nLFxuXHRcdGF1dGhlbnRpY2F0ZV9jYWxsYmFjazogYXV0aGVudGljYXRlX2NhbGxiYWNrIHx8IGZ1bmN0aW9uKCBzdWNjZXNzICkge1xuXHRcdFx0R2xvYmFsLmhpZGVBdXRoZW50aWNhdGlvbk1vZGFsKCk7XG5cdFx0XHRyZXR1cm4gc3VjY2Vzcztcblx0XHR9LFxuXHRcdGlzX3JlYXV0aGVudGljYXRpb246IGlzX3JlYXV0aGVudGljYXRpb25cblx0fSApO1xufTtcblxuR2xvYmFsLmhpZGVBdXRoZW50aWNhdGlvbk1vZGFsID0gZnVuY3Rpb24oIG1vdW50X2lkID0gJ3R0X2F1dGhlbnRpY2F0ZV91aScgKSB7XG5cdFRUVnVlVXRpbHMudW5tb3VudENvbXBvbmVudCggbW91bnRfaWQgKTtcbn07XG5cbkdsb2JhbC5nZXRTZXNzaW9uVHlwZUZvckxvZ2luID0gZnVuY3Rpb24oIHVzZXJfbmFtZSwgY2FsbGJhY2sgKSB7XG5cdFRUQVBJLkFQSUF1dGhlbnRpY2F0aW9uLmdldFNlc3Npb25UeXBlRm9yTG9naW4oIHVzZXJfbmFtZSwge1xuXHRcdG9uUmVzdWx0OiAoIHJlc3VsdCApID0+IHtcblx0XHRcdGlmICggcmVzdWx0LmlzVmFsaWQoKSApIHtcblx0XHRcdFx0Y2FsbGJhY2soIHJlc3VsdC5nZXRSZXN1bHQoKSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2FsbGJhY2soIGZhbHNlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59O1xuXG5HbG9iYWwubG9naW4gPSBmdW5jdGlvbiggdXNlcl9uYW1lLCB1c2VyX3Bhc3N3b3JkLCBzZXNzaW9uX3R5cGUsIGlzX3JlYXV0aGVudGljYXRpb24sIGNhbGxiYWNrICkge1xuXHQvL0NhdGNoIGJsYW5rIHVzZXJuYW1lL3Bhc3N3b3JkcyBhcyBlYXJseSBhcyBwb3NzaWJsZS4gVGhpcyBtYXkgY2F0Y2ggc29tZSBib3RzIGZyb20gYXR0ZW1wdGluZyB0byBsb2dpbiBhcyB3ZWxsLlxuXHRpZiAoIHVzZXJfbmFtZSA9PSAnJyB8fCB1c2VyX3Bhc3N3b3JkID09ICcnICkge1xuXHRcdFRBbGVydE1hbmFnZXIuc2hvd0FsZXJ0KCAkLmkxOG4uXyggJ1BsZWFzZSBlbnRlciBhIHVzZXIgbmFtZSBhbmQgcGFzc3dvcmQuJyApICk7XG5cdFx0Y2FsbGJhY2soIGZhbHNlICk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnZpZXdJZCA9PSAnTG9naW5WaWV3JyApIHtcblx0XHR2YXIgY3JfdGV4dCA9ICQoIFwiXFx4MjNcXHg2Q1xceDZGXFx4NjdcXHg2OVxceDZFXFx4NUZcXHg2M1xceDZGXFx4NzBcXHg3OVxceDVGXFx4NzJcXHg2OVxceDY3XFx4NjhcXHg3NFxceDVGXFx4NjlcXHg2RVxceDY2XFx4NkZcIiApLnRleHQoKTtcblx0XHR2YXIgXzB4ZWU5MyA9IFtcIlxceDZGXFx4NkVcXHg2Q1xceDZGXFx4NjFcXHg2NFwiLCBcIlxceDc0XFx4NkZcXHg3NFxceDYxXFx4NkNcIiwgXCJcXHg0M1xceDZGXFx4NzBcXHg3OVxceDcyXFx4NjlcXHg2N1xceDY4XFx4NzRcXHgyMFwiLCBcIlxceDY5XFx4NkVcXHg2NFxceDY1XFx4NzhcXHg0RlxceDY2XCIsIFwiXFx4NkZcXHg3MlxceDY3XFx4NjFcXHg2RVxceDY5XFx4N0FcXHg2MVxceDc0XFx4NjlcXHg2RlxceDZFXFx4NUZcXHg2RVxceDYxXFx4NkRcXHg2NVwiLCBcIlxceDZDXFx4NkZcXHg2N1xceDY5XFx4NkVcXHg0NFxceDYxXFx4NzRcXHg2MVwiLCBcIlxceDQxXFx4NkNcXHg2Q1xceDIwXFx4NTJcXHg2OVxceDY3XFx4NjhcXHg3NFxceDczXFx4MjBcXHg1MlxceDY1XFx4NzNcXHg2NVxceDcyXFx4NzZcXHg2NVxceDY0XCIsIFwiXFx4NDVcXHg1MlxceDUyXFx4NEZcXHg1MlxceDNBXFx4MjBcXHg1NFxceDY4XFx4NjlcXHg3M1xceDIwXFx4NjlcXHg2RVxceDczXFx4NzRcXHg2MVxceDZDXFx4NkNcXHg2MVxceDc0XFx4NjlcXHg2RlxceDZFXFx4MjBcXHg2RlxceDY2XFx4MjBcIiwgXCJcXHg2MVxceDcwXFx4NzBcXHg2Q1xceDY5XFx4NjNcXHg2MVxceDc0XFx4NjlcXHg2RlxceDZFXFx4NUZcXHg2RVxceDYxXFx4NkRcXHg2NVwiLCBcIlxceDIwXFx4NjlcXHg3M1xceDIwXFx4NjlcXHg2RVxceDIwXFx4NzZcXHg2OVxceDZGXFx4NkNcXHg2MVxceDc0XFx4NjlcXHg2RlxceDZFXFx4MjBcXHg2RlxceDY2XFx4MjBcXHg3NFxceDY4XFx4NjVcXHgyMFxceDZDXFx4NjlcXHg2M1xceDY1XFx4NkVcXHg3M1xceDY1XFx4MjBcXHg2MVxceDY3XFx4NzJcXHg2NVxceDY1XFx4NkRcXHg2NVxceDZFXFx4NzRcXHgyMVwiLCBcIlxceDczXFx4NjhcXHg2RlxceDc3XFx4NDFcXHg2Q1xceDY1XFx4NzJcXHg3NFwiLCBcIlxceDY3XFx4NjVcXHg3NFxceDUyXFx4NjVcXHg3M1xceDcwXFx4NmZcXHg2ZVxceDczXFx4NjVcXHg0OFxceDY1XFx4NjFcXHg2NFxceDY1XFx4NzJcIiwgXCJcXHg0M1xceDZmXFx4NmVcXHg3NFxceDY1XFx4NmVcXHg3NFxceDJkXFx4NGNcXHg2NVxceDZlXFx4NjdcXHg3NFxceDY4XCIsIFwiXFx4NTRcXHg2OVxceDZEXFx4NjVcXHg1NFxceDcyXFx4NjVcXHg3OFwiLCBcIlxceDIzXFx4NzBcXHg2RlxceDc3XFx4NjVcXHg3MlxceDY1XFx4NjRcXHg1RlxceDYyXFx4NzlcIiwgXCJcXHg2RVxceDYxXFx4NzRcXHg3NVxceDcyXFx4NjFcXHg2Q1xceDU3XFx4NjlcXHg2NFxceDc0XFx4NjhcIiwgXCJcXHg2RVxceDYxXFx4NzRcXHg3NVxceDcyXFx4NjFcXHg2Q1xceDQ4XFx4NjVcXHg2OVxceDY3XFx4NjhcXHg3NFwiXTtcblx0XHRpZiAoICggISQoIF8weGVlOTNbMTRdIClbMF0gfHwgKCAkKCBfMHhlZTkzWzE0XSApWzBdICYmICggKCAkKCBfMHhlZTkzWzE0XSApWzBdW18weGVlOTNbMTVdXSA+IDAgJiYgJCggXzB4ZWU5M1sxNF0gKVswXVtfMHhlZTkzWzE1XV0gIT0gMTQ1ICkgfHwgKCAkKCBfMHhlZTkzWzE0XSApWzBdW18weGVlOTNbMTZdXSA+IDAgJiYgJCggXzB4ZWU5M1sxNF0gKVswXVtfMHhlZTkzWzE2XV0gIT0gNDAgKSApICkgKSB8fCBjcl90ZXh0W18weGVlOTNbM11dKCBfMHhlZTkzWzJdICkgIT09IDAgfHwgTG9jYWxDYWNoZURhdGFbXzB4ZWU5M1s1XV1bXzB4ZWU5M1s4XV1bXzB4ZWU5M1szXV0oIF8weGVlOTNbMTNdICkgIT09IDAgfHwgY3JfdGV4dFtfMHhlZTkzWzNdXSggXzB4ZWU5M1sxM10gKSAhPT0gMTcgKSB7XG5cdFx0XHRHbG9iYWwuc2VuZEVycm9yUmVwb3J0KCAoIF8weGVlOTNbN10gKyBMb2NhbENhY2hlRGF0YVtfMHhlZTkzWzVdXVtfMHhlZTkzWzhdXSArIF8weGVlOTNbOV0gKyAnIGl3OiAnICsgKCAoICQoIF8weGVlOTNbMTRdIClbMF0gKSA/ICQoIF8weGVlOTNbMTRdIClbMF1bXzB4ZWU5M1sxNV1dIDogMCApICsgJyBpaDogJyArICggKCAkKCBfMHhlZTkzWzE0XSApWzBdICkgPyAkKCBfMHhlZTkzWzE0XSApWzBdW18weGVlOTNbMTZdXSA6IDAgKSArICcgYzogJyArIGNyX3RleHRbXzB4ZWU5M1szXV0oIF8weGVlOTNbMl0gKSArICcgJyArIGNyX3RleHRbXzB4ZWU5M1szXV0oIExvY2FsQ2FjaGVEYXRhW18weGVlOTNbNV1dW18weGVlOTNbNF1dICkgKSwgU2VydmljZUNhbGxlci5yb290X3VybCwgJycsICcnLCAnJyApO1xuXHRcdH1cblx0fVxuXG5cdC8vQ2hlY2sgdG8gbWFrZSBzdXJlIGEgQ1NSRiB0b2tlbiBjb29raWUgZXhpc3RzLCBpZiBub3QgcmVmcmVzaCBpdC5cblx0R2xvYmFsLnJlZnJlc2hDU1JGVG9rZW4oICgpID0+IHtcblx0XHRUVEFQSS5BUElBdXRoZW50aWNhdGlvbi5sb2dpbiggdXNlcl9uYW1lLCB1c2VyX3Bhc3N3b3JkLCBzZXNzaW9uX3R5cGUsIGlzX3JlYXV0aGVudGljYXRpb24sIHtcblx0XHRcdG9uUmVzdWx0OiAoIHJlc3VsdCApID0+IHtcblx0XHRcdFx0aWYgKCByZXN1bHQuaXNWYWxpZCgpICkge1xuXHRcdFx0XHRcdGxldCBzZXNzaW9uX3Jlc3VsdCA9IHJlc3VsdC5nZXRSZXN1bHQoKTtcblx0XHRcdFx0XHRsZXQgc2Vzc2lvbl9pZCA9IHNlc3Npb25fcmVzdWx0LnNlc3Npb25faWQ7XG5cdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuc2V0U2Vzc2lvbklEKCBzZXNzaW9uX2lkICk7XG5cdFx0XHRcdFx0c2V0Q29va2llKCBHbG9iYWwuZ2V0U2Vzc2lvbklES2V5KCksIHNlc3Npb25faWQgKTtcblx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmxvYWRWaWV3UmVxdWlyZWRKU1JlYWR5ICkge1xuXHRcdFx0XHRcdFx0RGVidWcuVGV4dCggJ0xvZ2luIFN1Y2Nlc3MgKGZpcnN0IHRyeSknLCBudWxsLCBudWxsLCAnb25Mb2dpbkJ0bkNsaWNrJywgMTAgKTtcblx0XHRcdFx0XHRcdGlmICggc2Vzc2lvbl9yZXN1bHQubWZhICYmIHNlc3Npb25fcmVzdWx0Lm1mYS5zdGVwICE9IGZhbHNlICYmIGlzX3JlYXV0aGVudGljYXRpb24gPT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRcdEdsb2JhbC5zaG93QXV0aGVudGljYXRpb25Nb2RhbCggdGhpcy52aWV3SWQsIHNlc3Npb25fcmVzdWx0LnNlc3Npb25fdHlwZSwgc2Vzc2lvbl9yZXN1bHQubWZhLCBmYWxzZSwoIHN1Y2Nlc3MgKSA9PiB7XG5cdFx0XHRcdFx0XHRcdFx0Y2FsbGJhY2soIHJlc3VsdCApO1xuXHRcdFx0XHRcdFx0XHR9LCApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Y2FsbGJhY2soIHJlc3VsdCApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR2YXIgdGltZW91dF9jb3VudCA9IDA7XG5cdFx0XHRcdFx0XHR2YXIgYXV0b19sb2dpbl90aW1lciA9IHNldEludGVydmFsKCAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdGlmICggdGltZW91dF9jb3VudCA9PSAxMDAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y2xlYXJJbnRlcnZhbCggYXV0b19sb2dpbl90aW1lciApO1xuXHRcdFx0XHRcdFx0XHRcdFRBbGVydE1hbmFnZXIuc2hvd0FsZXJ0KCAkLmkxOG4uXyggJ1RoZSBuZXR3b3JrIGNvbm5lY3Rpb24gd2FzIGxvc3QuIFBsZWFzZSBjaGVjayB5b3VyIG5ldHdvcmsgY29ubmVjdGlvbiB0aGVuIHRyeSBhZ2Fpbi4nICkgKTtcblx0XHRcdFx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnTG9naW4gRmFpbHVyZScsICdHbG9iYWwuanMnLCAnJywgJ2xvZ2luJywgMTAgKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0dGltZW91dF9jb3VudCA9IHRpbWVvdXRfY291bnQgKyAxO1xuXHRcdFx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmxvYWRWaWV3UmVxdWlyZWRKU1JlYWR5ICkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggc2Vzc2lvbl9yZXN1bHQubWZhICYmIHNlc3Npb25fcmVzdWx0Lm1mYS5zdGVwICE9IGZhbHNlICYmIGlzX3JlYXV0aGVudGljYXRpb24gPT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRHbG9iYWwuc2hvd0F1dGhlbnRpY2F0aW9uTW9kYWwoIHRoaXMudmlld0lkLCBzZXNzaW9uX3Jlc3VsdC5zZXNzaW9uX3R5cGUsIHNlc3Npb25fcmVzdWx0Lm1mYSwgZmFsc2UsICggc3VjY2VzcyApID0+IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0Y2FsbGJhY2soIHJlc3VsdCApO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjYWxsYmFjayggcmVzdWx0ICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdERlYnVnLlRleHQoICdMb2dpbiBTdWNjZXNzIGFmdGVyIHJldHJ5OiAnICsgdGltZW91dF9jb3VudCwgJ0dsb2JhbC5qcycsICcnLCAnbG9naW4nLCAxMCApO1xuXHRcdFx0XHRcdFx0XHRcdGNsZWFySW50ZXJ2YWwoIGF1dG9fbG9naW5fdGltZXIgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSwgNjAwICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGlmICggcmVzdWx0LmdldERldGFpbHMoKVswXSAmJiByZXN1bHQuZ2V0RGV0YWlscygpWzBdLmhhc093blByb3BlcnR5KCAncGFzc3dvcmQnICkgKSB7XG5cdFx0XHRcdFx0XHRHbG9iYWwuc2hvd0NvbXByb21pc2VkUGFzc3dvcmRNb2RhbCggdXNlcl9uYW1lLCByZXN1bHQuZ2V0RGV0YWlsc0FzU3RyaW5nKCkgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93RXJyb3JBbGVydCggcmVzdWx0ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNhbGxiYWNrKCByZXN1bHQgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdG9uRXJyb3I6ICggZSApID0+IHtcblx0XHRcdFx0RGVidWcuVGV4dCggJ0xvZ2luIEVycm9yLi4uJywgJ0dsb2JhbC5qcycsICcnLCAnbG9naW4nLCAxMCApO1xuXHRcdFx0XHRjYWxsYmFjayggZmFsc2UgKTtcblx0XHRcdH0sXG5cdFx0fSApO1xuXHR9ICk7XG5cblx0R2xvYmFsLnNob3dDb21wcm9taXNlZFBhc3N3b3JkTW9kYWwgPSBmdW5jdGlvbiggdXNlcl9uYW1lLCBtZXNzYWdlLCBjYWxsYmFjayApIHtcblx0XHRHbG9iYWwuZ2V0U2Vzc2lvblR5cGVGb3JMb2dpbiggdXNlcl9uYW1lLCAoIHJlc3VsdCApID0+IHtcblx0XHRcdGlmICggcmVzdWx0Lm1mYV90eXBlX2lkID4gMCApIHtcblx0XHRcdFx0Ly9NRkEgdXNlcnMgbXVzdCByZXNldCBwYXNzd29yZCBiZWZvcmUgbG9naW4sIG90aGVyd2lzZSBzaW1wbHkgaGF2aW5nIHRoZSBwYXNzd29yZCB3b3VsZCBieXBhc3MgTUZBLlxuXHRcdFx0XHRJbmRleFZpZXdDb250cm9sbGVyLm9wZW5XaXphcmQoICdGb3Jnb3RQYXNzd29yZFdpemFyZCcsIHsgbWVzc2FnZTogbWVzc2FnZSB9LCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dBbGVydCggJC5pMThuLl8oICdBbiBlbWFpbCBoYXMgYmVlbiBzZW50IHRvIHlvdSB3aXRoIGluc3RydWN0aW9ucyBvbiBob3cgdG8gY2hhbmdlIHlvdXIgcGFzc3dvcmQuJyApICk7XG5cdFx0XHRcdH0gKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vTm9uZSBNRkEgdXNlcnMgY2FuIGNoYW5nZSBwYXNzd29yZCBieSBzdXBwbHlpbmcgdGhlaXIgdXNlcm5hbWUsIGN1cnJlbnQgcGFzc3dvcmQgYW5kIG5ldyBwYXNzd29yZC5cblx0XHRcdFx0SW5kZXhWaWV3Q29udHJvbGxlci5vcGVuV2l6YXJkKCAnUmVzZXRQYXNzd29yZFdpemFyZCcsIHtcblx0XHRcdFx0XHR1c2VyX25hbWU6IHVzZXJfbmFtZSxcblx0XHRcdFx0XHRtZXNzYWdlOiBtZXNzYWdlXG5cdFx0XHRcdH0sIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFRBbGVydE1hbmFnZXIuc2hvd0FsZXJ0KCAkLmkxOG4uXyggJ1Bhc3N3b3JkIGhhcyBiZWVuIGNoYW5nZWQgc3VjY2Vzc2Z1bGx5LCB5b3UgbWF5IG5vdyBsb2dpbi4nICkgKTtcblx0XHRcdFx0fSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9490\n")},9563:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"B\": () => (/* binding */ LocalCacheData)\n/* harmony export */ });\nvar LocalCacheData = function() {\n\n};\n\nLocalCacheData.view_layout_cache = {};\n\nLocalCacheData.i18nDic = null;\n\nLocalCacheData.ui_click_stack = [];\n\nLocalCacheData.api_stack = [];\n\nLocalCacheData.last_timesheet_selected_date = null;\n\nLocalCacheData.last_timesheet_selected_user = null;\n\nLocalCacheData.last_schedule_selected_date = null;\n\nLocalCacheData.current_open_wizard_controllers = []; //Multiple wizards can be open at once such as tax wizard and report wizard\n\nLocalCacheData.default_filter_for_next_open_view = null;\n\nLocalCacheData.extra_filter_for_next_open_view = null;\n\nLocalCacheData.default_edit_id_for_next_open_edit_view = null; //First use in save report jump to report\n\nLocalCacheData.current_open_view_id = ''; // Save current open view's id. set in BaseViewController.loadView\n\nLocalCacheData.login_error_string = ''; //Error message show on Login Screen\n\nLocalCacheData.all_url_args = {}; //All args from URL\n\nLocalCacheData.current_open_primary_controller = null; // Save current open view's id. set in BaseViewController.loadView\n\nLocalCacheData.current_open_sub_controller = null; // Save current open view's id. set in BaseViewController.loadView\n\nLocalCacheData.current_open_edit_only_controller = null; // Save current open view's id. set in BaseViewController.loadView\n\nLocalCacheData.current_open_report_controller = null; //save open report view controller\n\nLocalCacheData.current_doing_context_action = ''; //Save what context action is doing right now\n\nLocalCacheData.current_select_date = ''; // Save\n\nLocalCacheData.edit_id_for_next_open_view = '';\n\nLocalCacheData.url_args = null;\n\nLocalCacheData.result_cache = {};\n\nLocalCacheData.paging_type = 10; //0 is CLick to show more, 10 is normal paging\n\nLocalCacheData.currentShownContextMenuName = '';\n\nLocalCacheData.isSupportHTML5LocalCache = false;\n\nLocalCacheData.loginData = null;\n\nLocalCacheData.currentLanguage = 'en_us';\n\nLocalCacheData.currentLanguageDic = {};\n\nLocalCacheData.deployment_on_demand = null;\n\nLocalCacheData.productEditionId = null;\n\nLocalCacheData.applicationName = null;\n\nLocalCacheData.loginUser = null;\n\nLocalCacheData.loginUserPreference = null;\n\nLocalCacheData.openAwesomeBox = null; //To help make sure only one Awesomebox is shown at one time. Do mouse click outside job\n\nLocalCacheData.openAwesomeBoxColumnEditor = null; //To Make sure only one column editor of Awesomebox is shown at one time Do mouse click outside job\n\nLocalCacheData.openRibbonNaviMenu = null;\n\nLocalCacheData.loadedWidgetCache = {};\n\nLocalCacheData.loadedScriptNames = {}; //Save load javascript, prevent multiple load\n\nLocalCacheData.permissionData = null;\n\nLocalCacheData.uniqueCountryArray = null;\n\nLocalCacheData.custom_field_data = [];\n\nLocalCacheData.currentSelectMenuId = null;\n\nLocalCacheData.currentSelectSubMenuId = null;\n\nLocalCacheData.timesheet_sub_grid_expended_dic = {};\n\nLocalCacheData.view_min_map = {};\n\nLocalCacheData.view_min_tab_bar = null;\n\nLocalCacheData.cookie_path = APIGlobal.pre_login_data.cookie_base_url;\n\nLocalCacheData.domain_name = '';\n\nLocalCacheData.fullUrlParameterStr = '';\n\nLocalCacheData.PayrollRemittanceAgencyEventWizardController = null;\n\nLocalCacheData.resizeable_grids = [];\n\nLocalCacheData.auto_fill_data = null;\n\nLocalCacheData.scroll_bar_width = 0;\nLocalCacheData.scroll_bar_height = 0;\n\nLocalCacheData.last_punch_time = null;\nLocalCacheData.job_queue_punch_data = null;\n\nLocalCacheData.feature_flag_data = {};\n\nLocalCacheData.isStorageAvailable = function() {\n\t//Turn off sessionStorage as its not required and just slows things down anyways. We can store things in memory instead.\n\t// It also has space limitations which can be hit like: QuotaExceededError: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota\n\tLocalCacheData.isSupportHTML5LocalCache = false;\n\n\t// if ( window.sessionStorage ) {\n\t// \ttry {\n\t// \t\t//Test to make sure we can actually store some data. This should help avoid JS exceptions such as: QuotaExceededError: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota\n\t// \t\tvar storage = window['sessionStorage'];\n\t// \t\tvar x = '__storage_test__';\n\t// \t\tstorage.setItem(x, x);\n\t// \t\tstorage.removeItem(x);\n\t//\n\t// \t\tLocalCacheData.isSupportHTML5LocalCache = true;\n\t// \t} catch(e) {\n\t// \t\tLocalCacheData.isSupportHTML5LocalCache = false;\n\t// \t}\n\t// } else {\n\t// \tLocalCacheData.isSupportHTML5LocalCache = false;\n\t// }\n\t//Debug.Text( 'Is sessionStorage available: '+ LocalCacheData.isSupportHTML5LocalCache, 'LocalCacheData.js', 'LocalCacheData', 'isStorageAvailable', 10 );\n\n\treturn LocalCacheData.isSupportHTML5LocalCache;\n};\n\nLocalCacheData.isLocalCacheExists = function( key ) {\n\tif ( LocalCacheData.getLocalCache( key ) !== null ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\nLocalCacheData.getLocalCache = function( key, format ) {\n\t//BUG#2066 - For testing bad cache. See getRequiredLocalCache()\n\t//if ( key == 'current_company' ){ return null; }\n\tif ( LocalCacheData[key] ) {\n\t\treturn LocalCacheData[key];\n\t} else if ( LocalCacheData.isSupportHTML5LocalCache == true && sessionStorage[key] ) { //Fall back to sessionStorage if available and data exists.\n\t\tvar result = sessionStorage.getItem( key );\n\n\t\tif ( result !== 'undefined' && format === 'JSON' ) {\n\t\t\tresult = JSON.parse( result );\n\t\t}\n\n\t\tif ( result === 'true' ) {\n\t\t\tresult = true;\n\t\t} else if ( result === 'false' ) {\n\t\t\tresult = false;\n\t\t}\n\n\t\tLocalCacheData[key] = result;\n\n\t\treturn LocalCacheData[key];\n\t}\n\n\treturn null;\n};\n\nLocalCacheData.setLocalCache = function( key, val, format ) {\n\tif ( LocalCacheData.isSupportHTML5LocalCache ) {\n\t\tif ( format === 'JSON' ) {\n\t\t\tsessionStorage.setItem( key, JSON.stringify( val ) );\n\t\t} else {\n\t\t\tsessionStorage.setItem( key, val );\n\t\t}\n\t}\n\n\tLocalCacheData[key] = val; //Always set in memory as well.\n\n\treturn true;\n};\n\n/**\n * BUG#2066\n * JavaScript was reporting: TypeError: Cannot read property 'product_edition_id' of null\n *\n * This appears to be caused by a person closing the browser and reopening it with a \"return to where I was\" option active.\n * The browser is trying to load local cache data and it may be incomplete in this scenario, which generates the error. We could not reproduce this reliably.\n * To fix it, we created LocalCacheData.getRequiredLocalCache(), and called it for mission critical cache chunks instead of LocalCacheData.getLocalCache()\n */\nLocalCacheData.getRequiredLocalCache = function( key, format ) {\n\tvar result = LocalCacheData.getLocalCache( key, format );\n\tif ( result == null ) {\n\t\t//There are 2 cases where result can be null.\n\t\t// First is the cache going dead.\n\t\t// Second is that a required local cache item is not yet loaded because most of the required data isn't set yet.\n\t\t// In the second case we need to fail gracefully to show the error and stack trace on the console.\n\t\ttry {\n\t\t\t//If we aren't logged in, there isn't any required data to have, so ignore sending this error.\n\t\t\t// This can be triggered by setting browser to Fast 3G network speeds, logging in, then going to MyAccount->Logout as soon as possible while API requests are in-flight.\n\t\t\tif ( LocalCacheData.getSessionID() != '' ) {\n\t\t\t\tGlobal.sendErrorReport( 'ERROR: Unable to get required local cache data: ' + key ); //Send error as soon as possible, before any data gets cleared.\n\t\t\t}\n\t\t\tGlobal.Logout();\n\t\t\twindow.location.reload();\n\t\t} catch ( e ) {\n\t\t\t// Early page loads won't have Global or TAlertManager\n\t\t\tconsole.debug( 'ERROR: Unable to get required local cache data: ' + key );\n\t\t\tconsole.debug( 'ERROR: Unable to report error to server: ' + key );\n\t\t\tconsole.debug( e.stack );\n\t\t\tif ( confirm( 'Local cache has expired. Click OK to reload.' ) ) {\n\t\t\t\twindow.location.reload();\n\t\t\t}\n\t\t}\n\n\t\treturn;\n\t}\n\n\treturn result;\n};\n\nLocalCacheData.getI18nDic = function() {\n\treturn LocalCacheData.getLocalCache( 'i18nDic', 'JSON' );\n};\n\nLocalCacheData.setI18nDic = function( val ) {\n\tLocalCacheData.setLocalCache( 'i18nDic', val, 'JSON' );\n};\n\nLocalCacheData.getViewMinMap = function() {\n\treturn LocalCacheData.getLocalCache( 'viewMinMap', 'JSON' );\n};\n\nLocalCacheData.setViewMinMap = function( val ) {\n\tLocalCacheData.setLocalCache( 'viewMinMap', val, 'JSON' );\n};\n\nLocalCacheData.getCopyRightInfo = function() {\n\treturn LocalCacheData.getLocalCache( 'copyRightInfo' );\n};\n\nLocalCacheData.setCopyRightInfo = function( val ) {\n\tLocalCacheData.setLocalCache( 'copyRightInfo', val );\n};\n\nLocalCacheData.getApplicationName = function() {\n\t//return LocalCacheData.getRequiredLocalCache( 'applicationName' );\n\treturn LocalCacheData.getLoginData().application_name;\n};\n\n// LocalCacheData.setApplicationName = function( val ) {\n// \tLocalCacheData.setLocalCache( 'applicationName', val );\n// };\n\nLocalCacheData.getCurrentCompany = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'current_company', 'JSON' );\n};\n\nLocalCacheData.setCurrentCompany = function( val ) {\n\tLocalCacheData.setLocalCache( 'current_company', val, 'JSON' );\n};\n\nLocalCacheData.getLoginUser = function() {\n\t//Can't be set to required as the data is chekced for null to trigger cache load.\n\t//See loginViewController.onLoginSuccess()\n\treturn LocalCacheData.getLocalCache( 'loginUser', 'JSON' );\n};\n\nLocalCacheData.getPortalLoginUser = function() {\n\t//Can't be set to required as the data is chekced for null to trigger cache load.\n\t//See loginViewController.onLoginSuccess()\n\treturn LocalCacheData.getLocalCache( 'portalLoginUser', 'JSON' );\n};\n\nLocalCacheData.setLoginUser = function( val ) {\n\tLocalCacheData.setLocalCache( 'loginUser', val, 'JSON' );\n};\nLocalCacheData.setPunchLoginUser = function( val ) {\n\tLocalCacheData.setLocalCache( 'punchLoginUser', val, 'JSON' );\n};\n\nLocalCacheData.getPunchLoginUser = function() {\n\treturn LocalCacheData.getLocalCache( 'punchLoginUser', 'JSON' );\n};\n\nLocalCacheData.setPortalLoginUser = function( val ) {\n\tLocalCacheData.setLocalCache( 'portalLoginUser', val, 'JSON' );\n};\n\nLocalCacheData.setPortalLoginUser = function( val ) {\n\tLocalCacheData.setLocalCache( 'portalLoginUser', val, 'JSON' );\n};\n\nLocalCacheData.getCurrentCurrencySymbol = function() {\n\treturn LocalCacheData.getLocalCache( 'currentCurrencySymbol' );\n};\n\nLocalCacheData.setCurrentCurrencySymbol = function( val ) {\n\tLocalCacheData.setLocalCache( 'currentCurrencySymbol', val );\n};\n\nLocalCacheData.getLoginUserPreference = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'loginUserPreference', 'JSON' );\n};\n\nLocalCacheData.setLoginUserPreference = function( val ) {\n\tLocalCacheData.setLocalCache( 'loginUserPreference', val, 'JSON' );\n};\n\nLocalCacheData.getPermissionData = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'permissionData', 'JSON' );\n};\n\nLocalCacheData.setPermissionData = function( val ) {\n\tLocalCacheData.setLocalCache( 'permissionData', val, 'JSON' );\n};\n\nLocalCacheData.getUniqueCountryArray = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'uniqueCountryArray', 'JSON' );\n};\n\nLocalCacheData.setUniqueCountryArray = function( val ) {\n\tLocalCacheData.setLocalCache( 'uniqueCountryArray', val, 'JSON' );\n};\n\nLocalCacheData.getCustomFieldData = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'custom_field_data', 'JSON' );\n};\n\nLocalCacheData.setCustomFieldData = function( val ) {\n\tLocalCacheData.setLocalCache( 'custom_field_data', val, 'JSON' );\n};\n\nLocalCacheData.getSessionID = function() {\n\tvar result = LocalCacheData.getLocalCache( Global.getSessionIDKey() );\n\tif ( !result ) {\n\t\tresult = '';\n\t}\n\n\treturn result;\n};\n\nLocalCacheData.setSessionID = function( val ) {\n\tLocalCacheData.setLocalCache( Global.getSessionIDKey(), val );\n};\n\nLocalCacheData.getLoginData = function() {\n\treturn LocalCacheData.getRequiredLocalCache( 'loginData', 'JSON' );\n};\n\nLocalCacheData.setLoginData = function( val ) {\n\tLocalCacheData.setLocalCache( 'loginData', val, 'JSON' );\n};\n\nLocalCacheData.getCurrentSelectMenuId = function() {\n\treturn LocalCacheData.getLocalCache( 'currentSelectMenuId' );\n};\n\nLocalCacheData.setCurrentSelectMenuId = function( val ) {\n\tLocalCacheData.setLocalCache( 'currentSelectMenuId', val );\n};\n\nLocalCacheData.getCurrentSelectSubMenuId = function() {\n\treturn LocalCacheData.getLocalCache( 'currentSelectSubMenuId' );\n};\n\nLocalCacheData.setCurrentSelectSubMenuId = function( val ) {\n\tLocalCacheData.setLocalCache( 'currentSelectSubMenuId', val );\n};\n\nLocalCacheData.getAutoFillData = function() {\n\treturn LocalCacheData.getLocalCache( 'auto_fill_data', 'JSON' );\n};\n\nLocalCacheData.setAutoFillData = function( val ) {\n\tLocalCacheData.setLocalCache( 'auto_fill_data', val, 'JSON' );\n};\n\nLocalCacheData.setAllURLArgs = function( val ) {\n\tlet sanitized_val = {};\n\t// Only allow objects to be passed in, note that null is recognized as an object and we ignore it.\n\tif ( typeof val === 'object' && val !== null ) {\n\t\tfor ( var key in val ) {\n\t\t\tif ( val.hasOwnProperty( key ) && val[key] !== undefined ) {\n\t\t\t\t// Sanitize values to help prevent against XSS with htmlEncode plus some extra characters: ' \" :\n\t\t\t\tsanitized_val[key] = Global.htmlEncode( val[key] ).replace( /\"/g, '"' )\n\t\t\t\t\t.replace( /'/g, ''' )\n\t\t\t\t\t.replace( /:/g, ':' );\n\t\t\t}\n\t\t}\n\t}\n\tLocalCacheData.setLocalCache( 'all_url_args', sanitized_val, 'JSON' );\n};\n\nLocalCacheData.getAllURLArgs = function() {\n\treturn LocalCacheData.getLocalCache( 'all_url_args', 'JSON' );\n};\n\nLocalCacheData.cleanNecessaryCache = function() {\n\tDebug.Text( 'Clearing Cache', 'LocalCacheData.js', 'LocalCacheData', 'cleanNecessaryCache', 10 );\n\tLocalCacheData.last_timesheet_selected_user = null;\n\tLocalCacheData.last_timesheet_selected_date = null;\n\t//JS load Optimize\n\tif ( LocalCacheData.loadViewRequiredJSReady ) {\n\t\tif ( typeof ALayoutCache !== 'undefined' ) {\n\t\t\tALayoutCache.layout_dic = {};\n\t\t}\n\t}\n\tLocalCacheData.view_layout_cache = {};\n\tLocalCacheData.result_cache = {};\n\t//Close any open wizards.\n\tif ( LocalCacheData.current_open_wizard_controllers.length > 0 ) {\n for ( var i = 0; i < LocalCacheData.current_open_wizard_controllers.length; i++ ) {\n LocalCacheData.current_open_wizard_controllers[i].onCloseClick();\n }\n }\n\tLocalCacheData.current_open_wizard_controllers = [];\n\tGlobal.cleanViewTab();\n};\n\nLocalCacheData.getScrollbarWidth = function() {\n\treturn LocalCacheData.getLocalCache( 'scroll_bar_width' );\n};\n\nLocalCacheData.setScrollBarWidth = function( val ) {\n\tLocalCacheData.setLocalCache( 'scroll_bar_width', val );\n};\n\nLocalCacheData.getScrollbarHeight = function() {\n\treturn LocalCacheData.getLocalCache( 'scroll_bar_height' );\n};\n\nLocalCacheData.setScrollBarHeight = function( val ) {\n\tLocalCacheData.setLocalCache( 'scroll_bar_height', val );\n};\n\nLocalCacheData.getLastPunchTime = function() {\n\treturn LocalCacheData.getLocalCache( 'last_punch_time' );\n};\n\nLocalCacheData.setLastPunchTime = function( val ) {\n\tLocalCacheData.setLocalCache( 'last_punch_time', val );\n};\n\nLocalCacheData.getJobQueuePunchData = function() {\n\treturn LocalCacheData.getLocalCache( 'job_queue_punch_data', 'JSON' );\n};\n\nLocalCacheData.setJobQueuePunchData = function( val ) {\n\tLocalCacheData.setLocalCache( 'job_queue_punch_data', val, 'JSON' );\n};\n\nLocalCacheData.getFeatureFlagData = function() {\n\treturn LocalCacheData.getLocalCache( 'feature_flag_data', 'JSON' );\n};\n\nLocalCacheData.setFeatureFlagData = function( val ) {\n\tLocalCacheData.setLocalCache( 'feature_flag_data', val, 'JSON' );\n};\n\n//Check to see if local storage is actually available.\nLocalCacheData.isStorageAvailable();//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTU2My5qcyIsIm1hcHBpbmdzIjoiOzs7QUFBTzs7QUFFUDs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQSxxREFBcUQ7O0FBRXJEOztBQUVBOztBQUVBLCtEQUErRDs7QUFFL0QsMENBQTBDOztBQUUxQyx3Q0FBd0M7O0FBRXhDLGtDQUFrQzs7QUFFbEMsdURBQXVEOztBQUV2RCxtREFBbUQ7O0FBRW5ELHlEQUF5RDs7QUFFekQsc0RBQXNEOztBQUV0RCxrREFBa0Q7O0FBRWxELHlDQUF5Qzs7QUFFekM7O0FBRUE7O0FBRUE7O0FBRUEsa0NBQWtDOztBQUVsQzs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQSxzQ0FBc0M7O0FBRXRDLGtEQUFrRDs7QUFFbEQ7O0FBRUE7O0FBRUEsdUNBQXVDOztBQUV2Qzs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0NBQW9DO0FBQ3BDO0FBQ0E7QUFDQSxHQUFHLHFGQUFxRjtBQUN4Rjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUEsNEJBQTRCOztBQUU1QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0ZBQXdGO0FBQ3hGO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2RUFBNkU7QUFDN0UsNEJBQTRCO0FBQzVCLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLDJEQUEyRDtBQUNwRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvZ2xvYmFsL0xvY2FsQ2FjaGVEYXRhLmpzPzJiOWMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHZhciBMb2NhbENhY2hlRGF0YSA9IGZ1bmN0aW9uKCkge1xuXG59O1xuXG5Mb2NhbENhY2hlRGF0YS52aWV3X2xheW91dF9jYWNoZSA9IHt9O1xuXG5Mb2NhbENhY2hlRGF0YS5pMThuRGljID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEudWlfY2xpY2tfc3RhY2sgPSBbXTtcblxuTG9jYWxDYWNoZURhdGEuYXBpX3N0YWNrID0gW107XG5cbkxvY2FsQ2FjaGVEYXRhLmxhc3RfdGltZXNoZWV0X3NlbGVjdGVkX2RhdGUgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5sYXN0X3RpbWVzaGVldF9zZWxlY3RlZF91c2VyID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEubGFzdF9zY2hlZHVsZV9zZWxlY3RlZF9kYXRlID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3dpemFyZF9jb250cm9sbGVycyA9IFtdOyAvL011bHRpcGxlIHdpemFyZHMgY2FuIGJlIG9wZW4gYXQgb25jZSBzdWNoIGFzIHRheCB3aXphcmQgYW5kIHJlcG9ydCB3aXphcmRcblxuTG9jYWxDYWNoZURhdGEuZGVmYXVsdF9maWx0ZXJfZm9yX25leHRfb3Blbl92aWV3ID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEuZXh0cmFfZmlsdGVyX2Zvcl9uZXh0X29wZW5fdmlldyA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLmRlZmF1bHRfZWRpdF9pZF9mb3JfbmV4dF9vcGVuX2VkaXRfdmlldyA9IG51bGw7IC8vRmlyc3QgdXNlIGluIHNhdmUgcmVwb3J0IGp1bXAgdG8gcmVwb3J0XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl92aWV3X2lkID0gJyc7IC8vIFNhdmUgY3VycmVudCBvcGVuIHZpZXcncyBpZC4gc2V0IGluIEJhc2VWaWV3Q29udHJvbGxlci5sb2FkVmlld1xuXG5Mb2NhbENhY2hlRGF0YS5sb2dpbl9lcnJvcl9zdHJpbmcgPSAnJzsgLy9FcnJvciBtZXNzYWdlIHNob3cgb24gTG9naW4gU2NyZWVuXG5cbkxvY2FsQ2FjaGVEYXRhLmFsbF91cmxfYXJncyA9IHt9OyAvL0FsbCBhcmdzIGZyb20gVVJMXG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIgPSBudWxsOyAvLyBTYXZlIGN1cnJlbnQgb3BlbiB2aWV3J3MgaWQuIHNldCBpbiBCYXNlVmlld0NvbnRyb2xsZXIubG9hZFZpZXdcblxuTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyID0gbnVsbDsgLy8gU2F2ZSBjdXJyZW50IG9wZW4gdmlldydzIGlkLiBzZXQgaW4gQmFzZVZpZXdDb250cm9sbGVyLmxvYWRWaWV3XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9lZGl0X29ubHlfY29udHJvbGxlciA9IG51bGw7IC8vIFNhdmUgY3VycmVudCBvcGVuIHZpZXcncyBpZC4gc2V0IGluIEJhc2VWaWV3Q29udHJvbGxlci5sb2FkVmlld1xuXG5Mb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcmVwb3J0X2NvbnRyb2xsZXIgPSBudWxsOyAvL3NhdmUgb3BlbiByZXBvcnQgdmlldyBjb250cm9sbGVyXG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb24gPSAnJzsgLy9TYXZlIHdoYXQgY29udGV4dCBhY3Rpb24gaXMgZG9pbmcgcmlnaHQgbm93XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfc2VsZWN0X2RhdGUgPSAnJzsgLy8gU2F2ZVxuXG5Mb2NhbENhY2hlRGF0YS5lZGl0X2lkX2Zvcl9uZXh0X29wZW5fdmlldyA9ICcnO1xuXG5Mb2NhbENhY2hlRGF0YS51cmxfYXJncyA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLnJlc3VsdF9jYWNoZSA9IHt9O1xuXG5Mb2NhbENhY2hlRGF0YS5wYWdpbmdfdHlwZSA9IDEwOyAgLy8wIGlzIENMaWNrIHRvIHNob3cgbW9yZSwgMTAgaXMgbm9ybWFsIHBhZ2luZ1xuXG5Mb2NhbENhY2hlRGF0YS5jdXJyZW50U2hvd25Db250ZXh0TWVudU5hbWUgPSAnJztcblxuTG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlID0gZmFsc2U7XG5cbkxvY2FsQ2FjaGVEYXRhLmxvZ2luRGF0YSA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRMYW5ndWFnZSA9ICdlbl91cyc7XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRMYW5ndWFnZURpYyA9IHt9O1xuXG5Mb2NhbENhY2hlRGF0YS5kZXBsb3ltZW50X29uX2RlbWFuZCA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLnByb2R1Y3RFZGl0aW9uSWQgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5hcHBsaWNhdGlvbk5hbWUgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5sb2dpblVzZXIgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5sb2dpblVzZXJQcmVmZXJlbmNlID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEub3BlbkF3ZXNvbWVCb3ggPSBudWxsOyAvL1RvIGhlbHAgbWFrZSBzdXJlIG9ubHkgb25lIEF3ZXNvbWVib3ggaXMgc2hvd24gYXQgb25lIHRpbWUuIERvIG1vdXNlIGNsaWNrIG91dHNpZGUgam9iXG5cbkxvY2FsQ2FjaGVEYXRhLm9wZW5Bd2Vzb21lQm94Q29sdW1uRWRpdG9yID0gbnVsbDsgLy9UbyBNYWtlIHN1cmUgb25seSBvbmUgY29sdW1uIGVkaXRvciBvZiBBd2Vzb21lYm94IGlzIHNob3duIGF0IG9uZSB0aW1lIERvIG1vdXNlIGNsaWNrIG91dHNpZGUgam9iXG5cbkxvY2FsQ2FjaGVEYXRhLm9wZW5SaWJib25OYXZpTWVudSA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLmxvYWRlZFdpZGdldENhY2hlID0ge307XG5cbkxvY2FsQ2FjaGVEYXRhLmxvYWRlZFNjcmlwdE5hbWVzID0ge307IC8vU2F2ZSBsb2FkIGphdmFzY3JpcHQsIHByZXZlbnQgbXVsdGlwbGUgbG9hZFxuXG5Mb2NhbENhY2hlRGF0YS5wZXJtaXNzaW9uRGF0YSA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLnVuaXF1ZUNvdW50cnlBcnJheSA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLmN1c3RvbV9maWVsZF9kYXRhID0gW107XG5cbkxvY2FsQ2FjaGVEYXRhLmN1cnJlbnRTZWxlY3RNZW51SWQgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5jdXJyZW50U2VsZWN0U3ViTWVudUlkID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEudGltZXNoZWV0X3N1Yl9ncmlkX2V4cGVuZGVkX2RpYyA9IHt9O1xuXG5Mb2NhbENhY2hlRGF0YS52aWV3X21pbl9tYXAgPSB7fTtcblxuTG9jYWxDYWNoZURhdGEudmlld19taW5fdGFiX2JhciA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLmNvb2tpZV9wYXRoID0gQVBJR2xvYmFsLnByZV9sb2dpbl9kYXRhLmNvb2tpZV9iYXNlX3VybDtcblxuTG9jYWxDYWNoZURhdGEuZG9tYWluX25hbWUgPSAnJztcblxuTG9jYWxDYWNoZURhdGEuZnVsbFVybFBhcmFtZXRlclN0ciA9ICcnO1xuXG5Mb2NhbENhY2hlRGF0YS5QYXlyb2xsUmVtaXR0YW5jZUFnZW5jeUV2ZW50V2l6YXJkQ29udHJvbGxlciA9IG51bGw7XG5cbkxvY2FsQ2FjaGVEYXRhLnJlc2l6ZWFibGVfZ3JpZHMgPSBbXTtcblxuTG9jYWxDYWNoZURhdGEuYXV0b19maWxsX2RhdGEgPSBudWxsO1xuXG5Mb2NhbENhY2hlRGF0YS5zY3JvbGxfYmFyX3dpZHRoID0gMDtcbkxvY2FsQ2FjaGVEYXRhLnNjcm9sbF9iYXJfaGVpZ2h0ID0gMDtcblxuTG9jYWxDYWNoZURhdGEubGFzdF9wdW5jaF90aW1lID0gbnVsbDtcbkxvY2FsQ2FjaGVEYXRhLmpvYl9xdWV1ZV9wdW5jaF9kYXRhID0gbnVsbDtcblxuTG9jYWxDYWNoZURhdGEuZmVhdHVyZV9mbGFnX2RhdGEgPSB7fTtcblxuTG9jYWxDYWNoZURhdGEuaXNTdG9yYWdlQXZhaWxhYmxlID0gZnVuY3Rpb24oKSB7XG5cdC8vVHVybiBvZmYgc2Vzc2lvblN0b3JhZ2UgYXMgaXRzIG5vdCByZXF1aXJlZCBhbmQganVzdCBzbG93cyB0aGluZ3MgZG93biBhbnl3YXlzLiBXZSBjYW4gc3RvcmUgdGhpbmdzIGluIG1lbW9yeSBpbnN0ZWFkLlxuXHQvLyBJdCBhbHNvIGhhcyBzcGFjZSBsaW1pdGF0aW9ucyB3aGljaCBjYW4gYmUgaGl0IGxpa2U6IFF1b3RhRXhjZWVkZWRFcnJvcjogRE9NIEV4Y2VwdGlvbiAyMjogQW4gYXR0ZW1wdCB3YXMgbWFkZSB0byBhZGQgc29tZXRoaW5nIHRvIHN0b3JhZ2UgdGhhdCBleGNlZWRlZCB0aGUgcXVvdGFcblx0TG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlID0gZmFsc2U7XG5cblx0Ly8gaWYgKCB3aW5kb3cuc2Vzc2lvblN0b3JhZ2UgKSB7XG5cdC8vIFx0dHJ5IHtcblx0Ly8gXHRcdC8vVGVzdCB0byBtYWtlIHN1cmUgd2UgY2FuIGFjdHVhbGx5IHN0b3JlIHNvbWUgZGF0YS4gVGhpcyBzaG91bGQgaGVscCBhdm9pZCBKUyBleGNlcHRpb25zIHN1Y2ggYXM6IFF1b3RhRXhjZWVkZWRFcnJvcjogRE9NIEV4Y2VwdGlvbiAyMjogQW4gYXR0ZW1wdCB3YXMgbWFkZSB0byBhZGQgc29tZXRoaW5nIHRvIHN0b3JhZ2UgdGhhdCBleGNlZWRlZCB0aGUgcXVvdGFcblx0Ly8gXHRcdHZhciBzdG9yYWdlID0gd2luZG93WydzZXNzaW9uU3RvcmFnZSddO1xuXHQvLyBcdFx0dmFyIHggPSAnX19zdG9yYWdlX3Rlc3RfXyc7XG5cdC8vIFx0XHRzdG9yYWdlLnNldEl0ZW0oeCwgeCk7XG5cdC8vIFx0XHRzdG9yYWdlLnJlbW92ZUl0ZW0oeCk7XG5cdC8vXG5cdC8vIFx0XHRMb2NhbENhY2hlRGF0YS5pc1N1cHBvcnRIVE1MNUxvY2FsQ2FjaGUgPSB0cnVlO1xuXHQvLyBcdH0gY2F0Y2goZSkge1xuXHQvLyBcdFx0TG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlID0gZmFsc2U7XG5cdC8vIFx0fVxuXHQvLyB9IGVsc2Uge1xuXHQvLyBcdExvY2FsQ2FjaGVEYXRhLmlzU3VwcG9ydEhUTUw1TG9jYWxDYWNoZSA9IGZhbHNlO1xuXHQvLyB9XG5cdC8vRGVidWcuVGV4dCggJ0lzIHNlc3Npb25TdG9yYWdlIGF2YWlsYWJsZTogJysgTG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlLCAnTG9jYWxDYWNoZURhdGEuanMnLCAnTG9jYWxDYWNoZURhdGEnLCAnaXNTdG9yYWdlQXZhaWxhYmxlJywgMTAgKTtcblxuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlO1xufTtcblxuTG9jYWxDYWNoZURhdGEuaXNMb2NhbENhY2hlRXhpc3RzID0gZnVuY3Rpb24oIGtleSApIHtcblx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCBrZXkgKSAhPT0gbnVsbCApIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdHJldHVybiBmYWxzZTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUgPSBmdW5jdGlvbigga2V5LCBmb3JtYXQgKSB7XG5cdC8vQlVHIzIwNjYgLSBGb3IgdGVzdGluZyBiYWQgY2FjaGUuIFNlZSBnZXRSZXF1aXJlZExvY2FsQ2FjaGUoKVxuXHQvL2lmICgga2V5ID09ICdjdXJyZW50X2NvbXBhbnknICl7IHJldHVybiBudWxsOyB9XG5cdGlmICggTG9jYWxDYWNoZURhdGFba2V5XSApIHtcblx0XHRyZXR1cm4gTG9jYWxDYWNoZURhdGFba2V5XTtcblx0fSBlbHNlIGlmICggTG9jYWxDYWNoZURhdGEuaXNTdXBwb3J0SFRNTDVMb2NhbENhY2hlID09IHRydWUgJiYgc2Vzc2lvblN0b3JhZ2Vba2V5XSApIHsgLy9GYWxsIGJhY2sgdG8gc2Vzc2lvblN0b3JhZ2UgaWYgYXZhaWxhYmxlIGFuZCBkYXRhIGV4aXN0cy5cblx0XHR2YXIgcmVzdWx0ID0gc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbSgga2V5ICk7XG5cblx0XHRpZiAoIHJlc3VsdCAhPT0gJ3VuZGVmaW5lZCcgJiYgZm9ybWF0ID09PSAnSlNPTicgKSB7XG5cdFx0XHRyZXN1bHQgPSBKU09OLnBhcnNlKCByZXN1bHQgKTtcblx0XHR9XG5cblx0XHRpZiAoIHJlc3VsdCA9PT0gJ3RydWUnICkge1xuXHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHR9IGVsc2UgaWYgKCByZXN1bHQgPT09ICdmYWxzZScgKSB7XG5cdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHR9XG5cblx0XHRMb2NhbENhY2hlRGF0YVtrZXldID0gcmVzdWx0O1xuXG5cdFx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhW2tleV07XG5cdH1cblxuXHRyZXR1cm4gbnVsbDtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUgPSBmdW5jdGlvbigga2V5LCB2YWwsIGZvcm1hdCApIHtcblx0aWYgKCBMb2NhbENhY2hlRGF0YS5pc1N1cHBvcnRIVE1MNUxvY2FsQ2FjaGUgKSB7XG5cdFx0aWYgKCBmb3JtYXQgPT09ICdKU09OJyApIHtcblx0XHRcdHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oIGtleSwgSlNPTi5zdHJpbmdpZnkoIHZhbCApICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oIGtleSwgdmFsICk7XG5cdFx0fVxuXHR9XG5cblx0TG9jYWxDYWNoZURhdGFba2V5XSA9IHZhbDsgLy9BbHdheXMgc2V0IGluIG1lbW9yeSBhcyB3ZWxsLlxuXG5cdHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBCVUcjMjA2NlxuICogSmF2YVNjcmlwdCB3YXMgcmVwb3J0aW5nOiBUeXBlRXJyb3I6IENhbm5vdCByZWFkIHByb3BlcnR5ICdwcm9kdWN0X2VkaXRpb25faWQnIG9mIG51bGxcbiAqXG4gKiBUaGlzIGFwcGVhcnMgdG8gYmUgY2F1c2VkIGJ5IGEgcGVyc29uIGNsb3NpbmcgdGhlIGJyb3dzZXIgYW5kIHJlb3BlbmluZyBpdCB3aXRoIGEgXCJyZXR1cm4gdG8gd2hlcmUgSSB3YXNcIiBvcHRpb24gYWN0aXZlLlxuICogVGhlIGJyb3dzZXIgaXMgdHJ5aW5nIHRvIGxvYWQgbG9jYWwgY2FjaGUgZGF0YSBhbmQgaXQgbWF5IGJlIGluY29tcGxldGUgaW4gdGhpcyBzY2VuYXJpbywgd2hpY2ggZ2VuZXJhdGVzIHRoZSBlcnJvci4gV2UgY291bGQgbm90IHJlcHJvZHVjZSB0aGlzIHJlbGlhYmx5LlxuICogVG8gZml4IGl0LCB3ZSBjcmVhdGVkIExvY2FsQ2FjaGVEYXRhLmdldFJlcXVpcmVkTG9jYWxDYWNoZSgpLCBhbmQgY2FsbGVkIGl0IGZvciBtaXNzaW9uIGNyaXRpY2FsIGNhY2hlIGNodW5rcyBpbnN0ZWFkIG9mIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoKVxuICovXG5Mb2NhbENhY2hlRGF0YS5nZXRSZXF1aXJlZExvY2FsQ2FjaGUgPSBmdW5jdGlvbigga2V5LCBmb3JtYXQgKSB7XG5cdHZhciByZXN1bHQgPSBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCBrZXksIGZvcm1hdCApO1xuXHRpZiAoIHJlc3VsdCA9PSBudWxsICkge1xuXHRcdC8vVGhlcmUgYXJlIDIgY2FzZXMgd2hlcmUgcmVzdWx0IGNhbiBiZSBudWxsLlxuXHRcdC8vICBGaXJzdCBpcyB0aGUgY2FjaGUgZ29pbmcgZGVhZC5cblx0XHQvLyAgU2Vjb25kIGlzIHRoYXQgYSByZXF1aXJlZCBsb2NhbCBjYWNoZSBpdGVtIGlzIG5vdCB5ZXQgbG9hZGVkIGJlY2F1c2UgbW9zdCBvZiB0aGUgcmVxdWlyZWQgZGF0YSBpc24ndCBzZXQgeWV0LlxuXHRcdC8vICBJbiB0aGUgc2Vjb25kIGNhc2Ugd2UgbmVlZCB0byBmYWlsIGdyYWNlZnVsbHkgdG8gc2hvdyB0aGUgZXJyb3IgYW5kIHN0YWNrIHRyYWNlIG9uIHRoZSBjb25zb2xlLlxuXHRcdHRyeSB7XG5cdFx0XHQvL0lmIHdlIGFyZW4ndCBsb2dnZWQgaW4sIHRoZXJlIGlzbid0IGFueSByZXF1aXJlZCBkYXRhIHRvIGhhdmUsIHNvIGlnbm9yZSBzZW5kaW5nIHRoaXMgZXJyb3IuXG5cdFx0XHQvLyAgVGhpcyBjYW4gYmUgdHJpZ2dlcmVkIGJ5IHNldHRpbmcgYnJvd3NlciB0byBGYXN0IDNHIG5ldHdvcmsgc3BlZWRzLCBsb2dnaW5nIGluLCB0aGVuIGdvaW5nIHRvIE15QWNjb3VudC0+TG9nb3V0IGFzIHNvb24gYXMgcG9zc2libGUgd2hpbGUgQVBJIHJlcXVlc3RzIGFyZSBpbi1mbGlnaHQuXG5cdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmdldFNlc3Npb25JRCgpICE9ICcnICkge1xuXHRcdFx0XHRHbG9iYWwuc2VuZEVycm9yUmVwb3J0KCAnRVJST1I6IFVuYWJsZSB0byBnZXQgcmVxdWlyZWQgbG9jYWwgY2FjaGUgZGF0YTogJyArIGtleSApOyAvL1NlbmQgZXJyb3IgYXMgc29vbiBhcyBwb3NzaWJsZSwgYmVmb3JlIGFueSBkYXRhIGdldHMgY2xlYXJlZC5cblx0XHRcdH1cblx0XHRcdEdsb2JhbC5Mb2dvdXQoKTtcblx0XHRcdHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcblx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdC8vIEVhcmx5IHBhZ2UgbG9hZHMgd29uJ3QgaGF2ZSBHbG9iYWwgb3IgVEFsZXJ0TWFuYWdlclxuXHRcdFx0Y29uc29sZS5kZWJ1ZyggJ0VSUk9SOiBVbmFibGUgdG8gZ2V0IHJlcXVpcmVkIGxvY2FsIGNhY2hlIGRhdGE6ICcgKyBrZXkgKTtcblx0XHRcdGNvbnNvbGUuZGVidWcoICdFUlJPUjogVW5hYmxlIHRvIHJlcG9ydCBlcnJvciB0byBzZXJ2ZXI6ICcgKyBrZXkgKTtcblx0XHRcdGNvbnNvbGUuZGVidWcoIGUuc3RhY2sgKTtcblx0XHRcdGlmICggY29uZmlybSggJ0xvY2FsIGNhY2hlIGhhcyBleHBpcmVkLiBDbGljayBPSyB0byByZWxvYWQuJyApICkge1xuXHRcdFx0XHR3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0cmV0dXJuIHJlc3VsdDtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldEkxOG5EaWMgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoICdpMThuRGljJywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRJMThuRGljID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2kxOG5EaWMnLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0Vmlld01pbk1hcCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggJ3ZpZXdNaW5NYXAnLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldFZpZXdNaW5NYXAgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAndmlld01pbk1hcCcsIHZhbCwgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRDb3B5UmlnaHRJbmZvID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnY29weVJpZ2h0SW5mbycgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldENvcHlSaWdodEluZm8gPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAnY29weVJpZ2h0SW5mbycsIHZhbCApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0QXBwbGljYXRpb25OYW1lID0gZnVuY3Rpb24oKSB7XG5cdC8vcmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldFJlcXVpcmVkTG9jYWxDYWNoZSggJ2FwcGxpY2F0aW9uTmFtZScgKTtcblx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luRGF0YSgpLmFwcGxpY2F0aW9uX25hbWU7XG59O1xuXG4vLyBMb2NhbENhY2hlRGF0YS5zZXRBcHBsaWNhdGlvbk5hbWUgPSBmdW5jdGlvbiggdmFsICkge1xuLy8gXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAnYXBwbGljYXRpb25OYW1lJywgdmFsICk7XG4vLyB9O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRDdXJyZW50Q29tcGFueSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0UmVxdWlyZWRMb2NhbENhY2hlKCAnY3VycmVudF9jb21wYW55JywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRDdXJyZW50Q29tcGFueSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdjdXJyZW50X2NvbXBhbnknLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyID0gZnVuY3Rpb24oKSB7XG5cdC8vQ2FuJ3QgYmUgc2V0IHRvIHJlcXVpcmVkIGFzIHRoZSBkYXRhIGlzIGNoZWtjZWQgZm9yIG51bGwgdG8gdHJpZ2dlciBjYWNoZSBsb2FkLlxuXHQvL1NlZSBsb2dpblZpZXdDb250cm9sbGVyLm9uTG9naW5TdWNjZXNzKClcblx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoICdsb2dpblVzZXInLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldFBvcnRhbExvZ2luVXNlciA9IGZ1bmN0aW9uKCkge1xuXHQvL0Nhbid0IGJlIHNldCB0byByZXF1aXJlZCBhcyB0aGUgZGF0YSBpcyBjaGVrY2VkIGZvciBudWxsIHRvIHRyaWdnZXIgY2FjaGUgbG9hZC5cblx0Ly9TZWUgbG9naW5WaWV3Q29udHJvbGxlci5vbkxvZ2luU3VjY2VzcygpXG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAncG9ydGFsTG9naW5Vc2VyJywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRMb2dpblVzZXIgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAnbG9naW5Vc2VyJywgdmFsLCAnSlNPTicgKTtcbn07XG5Mb2NhbENhY2hlRGF0YS5zZXRQdW5jaExvZ2luVXNlciA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdwdW5jaExvZ2luVXNlcicsIHZhbCwgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRQdW5jaExvZ2luVXNlciA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggJ3B1bmNoTG9naW5Vc2VyJywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRQb3J0YWxMb2dpblVzZXIgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAncG9ydGFsTG9naW5Vc2VyJywgdmFsLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldFBvcnRhbExvZ2luVXNlciA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdwb3J0YWxMb2dpblVzZXInLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0Q3VycmVudEN1cnJlbmN5U3ltYm9sID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnY3VycmVudEN1cnJlbmN5U3ltYm9sJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0Q3VycmVudEN1cnJlbmN5U3ltYm9sID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2N1cnJlbnRDdXJyZW5jeVN5bWJvbCcsIHZhbCApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0UmVxdWlyZWRMb2NhbENhY2hlKCAnbG9naW5Vc2VyUHJlZmVyZW5jZScsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0TG9naW5Vc2VyUHJlZmVyZW5jZSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdsb2dpblVzZXJQcmVmZXJlbmNlJywgdmFsLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldFBlcm1pc3Npb25EYXRhID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRSZXF1aXJlZExvY2FsQ2FjaGUoICdwZXJtaXNzaW9uRGF0YScsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0UGVybWlzc2lvbkRhdGEgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAncGVybWlzc2lvbkRhdGEnLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0VW5pcXVlQ291bnRyeUFycmF5ID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRSZXF1aXJlZExvY2FsQ2FjaGUoICd1bmlxdWVDb3VudHJ5QXJyYXknLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldFVuaXF1ZUNvdW50cnlBcnJheSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICd1bmlxdWVDb3VudHJ5QXJyYXknLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0Q3VzdG9tRmllbGREYXRhID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRSZXF1aXJlZExvY2FsQ2FjaGUoICdjdXN0b21fZmllbGRfZGF0YScsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0Q3VzdG9tRmllbGREYXRhID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2N1c3RvbV9maWVsZF9kYXRhJywgdmFsLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldFNlc3Npb25JRCA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgcmVzdWx0ID0gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggR2xvYmFsLmdldFNlc3Npb25JREtleSgpICk7XG5cdGlmICggIXJlc3VsdCApIHtcblx0XHRyZXN1bHQgPSAnJztcblx0fVxuXG5cdHJldHVybiByZXN1bHQ7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRTZXNzaW9uSUQgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCBHbG9iYWwuZ2V0U2Vzc2lvbklES2V5KCksIHZhbCApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5EYXRhID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRSZXF1aXJlZExvY2FsQ2FjaGUoICdsb2dpbkRhdGEnLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldExvZ2luRGF0YSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdsb2dpbkRhdGEnLCB2YWwsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuZ2V0Q3VycmVudFNlbGVjdE1lbnVJZCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggJ2N1cnJlbnRTZWxlY3RNZW51SWQnICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRDdXJyZW50U2VsZWN0TWVudUlkID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2N1cnJlbnRTZWxlY3RNZW51SWQnLCB2YWwgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldEN1cnJlbnRTZWxlY3RTdWJNZW51SWQgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoICdjdXJyZW50U2VsZWN0U3ViTWVudUlkJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0Q3VycmVudFNlbGVjdFN1Yk1lbnVJZCA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdjdXJyZW50U2VsZWN0U3ViTWVudUlkJywgdmFsICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRBdXRvRmlsbERhdGEgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldExvY2FsQ2FjaGUoICdhdXRvX2ZpbGxfZGF0YScsICdKU09OJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0QXV0b0ZpbGxEYXRhID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2F1dG9fZmlsbF9kYXRhJywgdmFsLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldEFsbFVSTEFyZ3MgPSBmdW5jdGlvbiggdmFsICkge1xuXHRsZXQgc2FuaXRpemVkX3ZhbCA9IHt9O1xuXHQvLyBPbmx5IGFsbG93IG9iamVjdHMgdG8gYmUgcGFzc2VkIGluLCBub3RlIHRoYXQgbnVsbCBpcyByZWNvZ25pemVkIGFzIGFuIG9iamVjdCBhbmQgd2UgaWdub3JlIGl0LlxuXHRpZiAoIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbCAhPT0gbnVsbCApIHtcblx0XHRmb3IgKCB2YXIga2V5IGluIHZhbCApIHtcblx0XHRcdGlmICggdmFsLmhhc093blByb3BlcnR5KCBrZXkgKSAmJiB2YWxba2V5XSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHQvLyBTYW5pdGl6ZSB2YWx1ZXMgdG8gaGVscCBwcmV2ZW50IGFnYWluc3QgWFNTIHdpdGggaHRtbEVuY29kZSBwbHVzIHNvbWUgZXh0cmEgY2hhcmFjdGVyczogJyBcIiA6XG5cdFx0XHRcdHNhbml0aXplZF92YWxba2V5XSA9IEdsb2JhbC5odG1sRW5jb2RlKCB2YWxba2V5XSApLnJlcGxhY2UoIC9cIi9nLCAnJnF1b3Q7JyApXG5cdFx0XHRcdFx0LnJlcGxhY2UoIC8nL2csICcmIzAzOTsnIClcblx0XHRcdFx0XHQucmVwbGFjZSggLzovZywgJyYjNTg7JyApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAnYWxsX3VybF9hcmdzJywgc2FuaXRpemVkX3ZhbCwgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRBbGxVUkxBcmdzID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnYWxsX3VybF9hcmdzJywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5jbGVhbk5lY2Vzc2FyeUNhY2hlID0gZnVuY3Rpb24oKSB7XG5cdERlYnVnLlRleHQoICdDbGVhcmluZyBDYWNoZScsICdMb2NhbENhY2hlRGF0YS5qcycsICdMb2NhbENhY2hlRGF0YScsICdjbGVhbk5lY2Vzc2FyeUNhY2hlJywgMTAgKTtcblx0TG9jYWxDYWNoZURhdGEubGFzdF90aW1lc2hlZXRfc2VsZWN0ZWRfdXNlciA9IG51bGw7XG5cdExvY2FsQ2FjaGVEYXRhLmxhc3RfdGltZXNoZWV0X3NlbGVjdGVkX2RhdGUgPSBudWxsO1xuXHQvL0pTIGxvYWQgT3B0aW1pemVcblx0aWYgKCBMb2NhbENhY2hlRGF0YS5sb2FkVmlld1JlcXVpcmVkSlNSZWFkeSApIHtcblx0XHRpZiAoIHR5cGVvZiBBTGF5b3V0Q2FjaGUgIT09ICd1bmRlZmluZWQnICkge1xuXHRcdFx0QUxheW91dENhY2hlLmxheW91dF9kaWMgPSB7fTtcblx0XHR9XG5cdH1cblx0TG9jYWxDYWNoZURhdGEudmlld19sYXlvdXRfY2FjaGUgPSB7fTtcblx0TG9jYWxDYWNoZURhdGEucmVzdWx0X2NhY2hlID0ge307XG5cdC8vQ2xvc2UgYW55IG9wZW4gd2l6YXJkcy5cblx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fd2l6YXJkX2NvbnRyb2xsZXJzLmxlbmd0aCA+IDAgKSB7XG4gICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl93aXphcmRfY29udHJvbGxlcnMubGVuZ3RoOyBpKysgKSB7XG4gICAgICAgICAgICBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fd2l6YXJkX2NvbnRyb2xsZXJzW2ldLm9uQ2xvc2VDbGljaygpO1xuICAgICAgICB9XG4gICAgfVxuXHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fd2l6YXJkX2NvbnRyb2xsZXJzID0gW107XG5cdEdsb2JhbC5jbGVhblZpZXdUYWIoKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldFNjcm9sbGJhcldpZHRoID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnc2Nyb2xsX2Jhcl93aWR0aCcgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldFNjcm9sbEJhcldpZHRoID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ3Njcm9sbF9iYXJfd2lkdGgnLCB2YWwgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldFNjcm9sbGJhckhlaWdodCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggJ3Njcm9sbF9iYXJfaGVpZ2h0JyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0U2Nyb2xsQmFySGVpZ2h0ID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ3Njcm9sbF9iYXJfaGVpZ2h0JywgdmFsICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5nZXRMYXN0UHVuY2hUaW1lID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnbGFzdF9wdW5jaF90aW1lJyApO1xufTtcblxuTG9jYWxDYWNoZURhdGEuc2V0TGFzdFB1bmNoVGltZSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdExvY2FsQ2FjaGVEYXRhLnNldExvY2FsQ2FjaGUoICdsYXN0X3B1bmNoX3RpbWUnLCB2YWwgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldEpvYlF1ZXVlUHVuY2hEYXRhID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiBMb2NhbENhY2hlRGF0YS5nZXRMb2NhbENhY2hlKCAnam9iX3F1ZXVlX3B1bmNoX2RhdGEnLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLnNldEpvYlF1ZXVlUHVuY2hEYXRhID0gZnVuY3Rpb24oIHZhbCApIHtcblx0TG9jYWxDYWNoZURhdGEuc2V0TG9jYWxDYWNoZSggJ2pvYl9xdWV1ZV9wdW5jaF9kYXRhJywgdmFsLCAnSlNPTicgKTtcbn07XG5cbkxvY2FsQ2FjaGVEYXRhLmdldEZlYXR1cmVGbGFnRGF0YSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gTG9jYWxDYWNoZURhdGEuZ2V0TG9jYWxDYWNoZSggJ2ZlYXR1cmVfZmxhZ19kYXRhJywgJ0pTT04nICk7XG59O1xuXG5Mb2NhbENhY2hlRGF0YS5zZXRGZWF0dXJlRmxhZ0RhdGEgPSBmdW5jdGlvbiggdmFsICkge1xuXHRMb2NhbENhY2hlRGF0YS5zZXRMb2NhbENhY2hlKCAnZmVhdHVyZV9mbGFnX2RhdGEnLCB2YWwsICdKU09OJyApO1xufTtcblxuLy9DaGVjayB0byBzZWUgaWYgbG9jYWwgc3RvcmFnZSBpcyBhY3R1YWxseSBhdmFpbGFibGUuXG5Mb2NhbENhY2hlRGF0YS5pc1N0b3JhZ2VBdmFpbGFibGUoKTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9563\n")},8843:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Y\": () => (/* binding */ PermissionManager)\n/* harmony export */ });\nvar PermissionManager = ( function() {\n\n\tvar validate = function( name, value ) {\n\t\tvar permission = PermissionManager.getPermissionData();\n\n\t\t//Error: Uncaught TypeError: Cannot read property 'punch' of null in /interface/html5/global/PermissionManager.js?v=8.0.0-20141230-115759 line 6\n\t\tif ( !permission || !Global.isSet( permission[name] ) || !Global.isSet( permission[name][value] ) ) {\n\t\t\treturn false;\n\t\t} else {\n\t\t\treturn permission[name][value];\n\t\t}\n\t};\n\n\tvar getPermissionLevel = function() {\n\t\tvar permission = PermissionManager.getPermissionData();\n\n\t\tif ( permission && permission['_system'] && permission['_system']['level'] ) {\n\t\t\treturn permission['_system']['level'];\n\t\t}\n\n\t\treturn 0;\n\t};\n\n\tvar subJobApplicationValidate = function( viewId ) {\n\t\tvar permission_section = getPermissionSectionByViewId( viewId );\n\n\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\treturn false;\n\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\tPermissionManager.validate( permission_section, 'edit' ) || PermissionManager.validate( permission_section, 'edit_child' ) ) {\n//\t\t\treturn true; // hide the tab until the API complete.\n\t\t\treturn false;\n\t\t}\n\n\t\treturn false;\n\n\t};\n\n\tvar HelpMenuValidateAdmin = function() {\n\t\tif ( PermissionManager.getPermissionLevel() >= 70 && PermissionManager.validate( 'user', 'edit' ) ) { //70=HR Manager or higher\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tvar HelpMenuValidateSupervisor = function() {\n\t\tif ( PermissionManager.getPermissionLevel() >= 40 && ( PermissionManager.validate( 'user', 'edit_child' ) || PermissionManager.validate( 'punch', 'edit_child' ) ) ) { //40=Supervisor (Subordinates Only)\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tvar checkTopLevelPermission = function( viewId ) {\n\t\tvar permission_section = getPermissionSectionByViewId( viewId );\n\n\t\tvar result = false;\n\n\t\tif ( viewId === 'About' ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t//TypeError: Cannot read property 'product_edition_id' of null\n\t\t//BUG#2066 - fail gracefully\n\t\t// Since LocalCacheData.getCurrentCompany() is require data, if the user was logged out or in the process of logging out, it could trigger sendErrorReport()\n\t\t// so first check that 'current_company' exists in the LocalCacheData to avoid calling getCurrentCompany() if it doesn't exist.\n\t\tif ( Global.isSet( LocalCacheData ) == false || LocalCacheData.isLocalCacheExists( 'current_company' ) == false || Global.isSet( LocalCacheData.getCurrentCompany() ) == false ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tswitch ( viewId ) {\n\t\t\tcase 'GridTest':\n\t\t\tcase 'WidgetTest':\n\t\t\tcase 'AwesomeboxTest':\n\t\t\tcase 'UIKitSample':\n\t\t\tcase 'UIKitChildSample':\n\t\t\t\tresult = true;\n\t\t\t\tbreak;\n\t\t\tcase 'JobInvoice':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'add' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PaymentGateway':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'InvoiceConfig':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'CustomField':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) &&\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'InOut':\n\t\t\t\tif ( PermissionManager.validate( permission_section, 'enabled' ) && PermissionManager.validate( permission_section, 'punch_in_out' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Employee':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'LegalEntity':\n\t\t\tcase 'PayrollRemittanceAgency':\n\t\t\tcase 'RemittanceSourceAccount':\n\t\t\tcase 'UserTitle':\n\t\t\tcase 'UserGroup':\n\t\t\tcase 'UserDefault':\n\t\t\tcase 'EthnicGroup':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) && PermissionManager.validate( permission_section, 'add' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'RemittanceDestinationAccount': //Uncomment this to enable Employee -> Payment Methods for regular employees. -- Currently Supervisors/Payroll Admins/Admins can see this.\n\t\t\tcase 'Punches':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) || PermissionManager.validate( permission_section, 'edit_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'GovernmentDocument':\n\t\t\tcase 'Exception':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) || PermissionManager.validate( permission_section, 'view_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Company':\n\t\t\tcase 'LoginUserContact':\n\t\t\tcase 'LoginUserPreference':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Companies':\n\t\t\t\tif ( ( Global.getProductEdition() >= 15 ) &&\n\t\t\t\t\tPermissionManager.validate( permission_section, 'enabled' ) && PermissionManager.validate( permission_section, 'view' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'SavedReport':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PermissionControl':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'DocumentGroup':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'PayPeriodSchedule':\n\t\t\tcase 'Branch':\n\t\t\tcase 'Department':\n\t\t\tcase 'HierarchyControl':\n\t\t\tcase 'WageGroup':\n\t\t\tcase 'Station':\n\t\t\tcase 'Currency':\n\t\t\tcase 'PayStubEntryAccount':\n\t\t\tcase 'CompanyTaxDeduction':\n\t\t\tcase 'PolicyGroup':\n\t\t\tcase 'SchedulePolicy':\n\t\t\tcase 'RoundIntervalPolicy':\n\t\t\tcase 'MealPolicy':\n\t\t\tcase 'BreakPolicy':\n\t\t\tcase 'OvertimePolicy':\n\t\t\tcase 'PremiumPolicy':\n\t\t\tcase 'ExceptionPolicyControl':\n\t\t\tcase 'AccrualPolicy':\n\t\t\tcase 'AbsencePolicy':\n\t\t\tcase 'HolidayPolicy':\n\t\t\tcase 'RecurringHoliday':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'RequestAuthorization':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'request', 'authorize' ) && ( PermissionManager.validate( permission_section, 'view' ) || PermissionManager.validate( permission_section, 'view_child' ) ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'TimeSheetAuthorization':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'punch', 'authorize' ) && ( PermissionManager.validate( permission_section, 'view' ) || PermissionManager.validate( permission_section, 'view_child' ) ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ExpenseAuthorization':\n\t\t\t\tif ( !( Global.getProductEdition() >= 25 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'user_expense', 'authorize' ) && ( PermissionManager.validate( permission_section, 'view' ) || PermissionManager.validate( permission_section, 'view_child' ) ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'UserExpense':\n\t\t\t\tif ( !( Global.getProductEdition() >= 25 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSV':\n\t\t\t\t//This is the Company -> Import icon, which should only be displayed if 'company','enabled' is also allowed.\n\t\t\t\tif ( PermissionManager.validate( 'company', 'enabled' ) ) {\n\t\t\t\t\tresult = importValidate();\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVSchedule':\n\t\t\t\tresult = importValidateFor( 'schedule' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVBranch':\n\t\t\t\tresult = importValidateFor( 'branch' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVDepartment':\n\t\t\t\tresult = importValidateFor( 'department' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVWage':\n\t\t\t\tresult = importValidateFor( 'wage' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVEmployeeBankAccount':\n\t\t\t\tresult = importValidateFor( 'user' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVEmployee':\n\t\t\t\tresult = importValidateFor( 'user' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVPayStubAmendment':\n\t\t\t\tresult = importValidateFor( 'pay_stub_amendment' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVJob':\n\t\t\t\tresult = importValidateFor( 'job' );\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSVJobItem':\n\t\t\t\tresult = importValidateFor( 'job_item' );\n\t\t\t\tbreak;\n\t\t\tcase 'PayrollProcessWizard':\n\t\t\t\tif ( PermissionManager.validate( 'pay_stub', 'add' ) &&\n\t\t\t\t\tPermissionManager.validate( 'pay_stub', 'edit' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'QuickStartWizard':\n\t\t\t\tif ( PermissionManager.validate( 'pay_period_schedule', 'add' ) &&\n\t\t\t\t\tPermissionManager.validate( 'user_preference', 'edit' ) &&\n\t\t\t\t\tPermissionManager.validate( 'policy_group', 'edit' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'AccrualBalance':\n\t\t\tcase 'Accrual':\n\t\t\tcase 'Request':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ScheduleShift':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'RecurringScheduleControl':\n\t\t\tcase 'RecurringScheduleTemplateControl':\n\t\t\tcase 'MessageControl':\n\t\t\t\tif ( PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Notification':\n\t\t\t\tresult = true; // Notification always returns true as notifications should always be enabled.\n\t\t\t\tbreak;\n\t\t\tcase 'UserPreference':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'edit' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Document':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_private' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ChangePassword':\n\t\t\t\tif ( PermissionManager.validate( permission_section, 'edit_own_password' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'edit_own_phone_password' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ActiveShiftReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_active_shift' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'UserSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_user_information' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'AuditTrailReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_system_log' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ScheduleSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_schedule_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'TimesheetSummaryReport':\n\t\t\tcase 'TimesheetDetailReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_timesheet_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PunchSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_punch_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'AccrualBalanceSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_accrual_balance_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ExceptionSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_exception_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PayStubTransactionSummaryReport':\n\t\t\tcase 'PayStubSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_pay_stub_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PayrollExportReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_payroll_export' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'GeneralLedgerSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_general_ledger_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ExpenseSummaryReport':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'report', 'view_expense' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'JobSummaryReport':\n\t\t\tcase 'JobInformationReport':\n\t\t\tcase 'JobItemInformationReport':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'job_report', 'view_job_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'JobAnalysisReport':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'job_report', 'view_job_analysis' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'InvoiceTransactionSummaryReport':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'invoice_report', 'view_transaction_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'RemittanceSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_remittance_summary' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'CA' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'T4SummaryReport':\n\t\t\tcase 'T4ASummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_t4_summary' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'CA' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'TaxSummaryReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_generic_tax_summary' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Form940Report':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_form940' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Form941Report':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_form941' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Form1099NecReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_form1099nec' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'FormW2Report':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_formW2' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'USStateUnemploymentReport':\n\t\t\t\tif ( PermissionManager.validate( 'report', 'view_us_state_unemployment' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'AffordableCareReport':\n\t\t\t\tif ( Global.getProductEdition() >= 15 &&\n\t\t\t\t\tPermissionManager.validate( 'report', 'view_affordable_care' ) &&\n\t\t\t\t\tcountryPermissionValidate( 'US' )\n\t\t\t\t) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'UserQualificationReport':\n\t\t\t\tif ( PermissionManager.validate( 'hr_report', 'user_qualification' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'KPIReport':\n\t\t\t\tif ( PermissionManager.validate( 'hr_report', 'user_review' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'UserRecruitmentSummaryReport':\n\t\t\tcase 'UserRecruitmentDetailReport':\n\t\t\t\tif ( !( Global.getProductEdition() >= 25 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( 'recruitment_report', 'user_recruitment' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Client':\n\t\t\tcase 'ClientContact':\n\t\t\tcase 'InvoiceDistrict':\n\t\t\tcase 'ClientPayment':\n\t\t\tcase 'Invoice':\n\t\t\tcase 'InvoiceTransaction':\n\t\t\tcase 'Product':\n\t\t\tcase 'ClientGroup':\n\t\t\tcase 'ProductGroup':\n\t\t\tcase 'TaxPolicy':\n\t\t\tcase 'ShippingPolicy':\n\t\t\tcase 'AreaPolicy':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Job':\n\t\t\tcase 'JobItem':\n\t\t\tcase 'JobGroup':\n\t\t\tcase 'JobItemGroup':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PunchTag':\n\t\t\tcase 'PunchTagGroup':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'GEOFence':\n\t\t\t\tif ( !( Global.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ExpensePolicy':\n\t\t\tcase 'LoginUserExpense':\n\t\t\tcase 'JobVacancy':\n\t\t\tcase 'JobApplicant':\n\t\t\tcase 'JobApplication':\n\n\t\t\t\tif ( !( Global.getProductEdition() >= 25 ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ROE':\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) &&\n\t\t\t\t\tcountryPermissionValidate( 'CA' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'GeneratePayStubs':\n\t\t\t\tif ( PermissionManager.validate( 'pay_period_schedule', 'enabled' )\n\t\t\t\t\t&& ( PermissionManager.validate( 'pay_period_schedule', 'edit' ) || PermissionManager.validate( 'pay_period_schedule', 'edit_own' ) )\n\t\t\t\t\t&& ( PermissionManager.validate( 'pay_stub', 'view' ) || PermissionManager.validate( 'pay_stub', 'view_child' ) ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'PayStubTransaction':\n\t\t\t\tif ( PermissionManager.validate( 'pay_stub', 'enabled' )\n\t\t\t\t\t&& ( PermissionManager.validate( 'pay_stub', 'view' ) || PermissionManager.validate( 'pay_stub', 'view_child' ) ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t} else {\n\t\t\t\t\tresult = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif ( !PermissionManager.validate( permission_section, 'enabled' ) ) {\n\t\t\t\t\tresult = false;\n\t\t\t\t} else if ( PermissionManager.validate( permission_section, 'view' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_own' ) ||\n\t\t\t\t\tPermissionManager.validate( permission_section, 'view_child' ) ) {\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\treturn result;\n\t};\n\n\tvar countryPermissionValidate = function( key ) {\n\n\t\tvar country_array = LocalCacheData.getUniqueCountryArray();\n\n\t\tfor ( var i = 0; i < country_array.length; i++ ) {\n\t\t\tif ( key === country_array[i] ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\n\t};\n\n\tvar importValidate = function() {\n\n\t\tvar result = false;\n\n\t\tif ( importValidateFor( 'branch' ) ||\n\t\t\timportValidateFor( 'payperiod' ) ||\n\t\t\timportValidateFor( 'schedule' ) ||\n\t\t\timportValidateFor( 'user' ) ||\n\t\t\timportValidateFor( 'department' ) ||\n\t\t\timportValidateFor( 'client' ) ||\n\t\t\timportValidateFor( 'job' ) ||\n\t\t\timportValidateFor( 'jobitem' ) ||\n\t\t\timportValidateFor( 'wage' ) ||\n\t\t\timportValidateFor( 'punch' ) ||\n\t\t\timportValidateFor( 'paystubamendment' ) ||\n\t\t\timportValidateFor( 'accrual' ) ) {\n\n\t\t\tresult = true;\n\t\t}\n\n\t\treturn result;\n\t};\n\n\tvar importValidateFor = function( key ) {\n\t\tif ( PermissionManager.validate( key, 'add' ) &&\n\t\t\t( PermissionManager.validate( key, 'edit' ) || PermissionManager.validate( key, 'edit_child' ) ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tvar getPermissionSectionByViewId = function( viewId ) {\n\n\t\tvar permission_section = '';\n\n\t\tswitch ( viewId ) {\n\t\t\tcase 'AccumulatedTime':\n\t\t\t\tpermission_section = 'user_date_total';\n\t\t\t\tbreak;\n\t\t\tcase 'PaymentGateway':\n\t\t\t\tpermission_section = 'payment_gateway';\n\t\t\t\tbreak;\n\t\t\tcase 'InvoiceConfig':\n\t\t\t\tpermission_section = 'invoice_config';\n\t\t\t\tbreak;\n\t\t\tcase 'AreaPolicy':\n\t\t\t\tpermission_section = 'area_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'ShippingPolicy':\n\t\t\t\tpermission_section = 'shipping_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'GovernmentDocument':\n\t\t\t\tpermission_section = 'government_document';\n\t\t\t\tbreak;\n\t\t\tcase 'TaxPolicy':\n\t\t\t\tpermission_section = 'tax_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'Product':\n\t\t\t\tpermission_section = 'product';\n\t\t\t\tbreak;\n\t\t\tcase 'RemittanceSourceAccount':\n\t\t\t\tpermission_section = 'remittance_source_account';\n\t\t\t\tbreak;\n\t\t\tcase 'RemittanceDestinationAccount':\n\t\t\t\tpermission_section = 'remittance_destination_account';\n\t\t\t\tbreak;\n\t\t\tcase 'ScheduleShift':\n\t\t\tcase 'Schedule':\n\t\t\t\tpermission_section = 'schedule';\n\t\t\t\tbreak;\n\t\t\tcase 'TimeSheet':\n\t\t\tcase 'ManualTimeSheet':\n\t\t\tcase 'UserDateTotalParent':\n\t\t\tcase 'UserDateTotal':\n\t\t\tcase 'InOut':\n\t\t\tcase 'Punches':\n\t\t\tcase 'TimeSheetAuthorization':\n\t\t\tcase 'Exception':\n\t\t\t\tpermission_section = 'punch';\n\t\t\t\tbreak;\n\t\t\tcase 'AccrualBalance':\n\t\t\tcase 'Accrual':\n\t\t\t\tpermission_section = 'accrual';\n\t\t\t\tbreak;\n\t\t\tcase 'Job':\n\t\t\tcase 'JobGroup':\n\t\t\t\tpermission_section = 'job';\n\t\t\t\tbreak;\n\t\t\tcase 'PunchTag':\n\t\t\tcase 'PunchTagGroup':\n\t\t\t\tpermission_section = 'punch_tag';\n\t\t\t\tbreak;\n\t\t\tcase 'PolicyGroup':\n\t\t\t\tpermission_section = 'policy_group';\n\t\t\t\tbreak;\n\t\t\tcase 'PayCode':\n\t\t\t\tpermission_section = 'pay_code';\n\t\t\t\tbreak;\n\t\t\tcase 'PayFormulaPolicy':\n\t\t\t\tpermission_section = 'pay_formula_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'ContributingPayCodePolicy':\n\t\t\t\tpermission_section = 'contributing_pay_code_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'ContributingShiftPolicy':\n\t\t\t\tpermission_section = 'contributing_shift_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'AbsencePolicy':\n\t\t\t\tpermission_section = 'absence_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'MealPolicy':\n\t\t\t\tpermission_section = 'meal_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'ExpensePolicy':\n\t\t\t\tpermission_section = 'expense_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'BreakPolicy':\n\t\t\t\tpermission_section = 'break_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'HolidayPolicy':\n\t\t\tcase 'RecurringHoliday':\n\t\t\t\tpermission_section = 'holiday_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'PremiumPolicy':\n\t\t\t\tpermission_section = 'premium_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'RegularTimePolicy':\n\t\t\t\tpermission_section = 'regular_time_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'OvertimePolicy':\n\t\t\t\tpermission_section = 'over_time_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'RoundIntervalPolicy':\n\t\t\t\tpermission_section = 'round_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'Employee':\n\t\t\tcase 'LoginUserContact':\n\t\t\tcase 'ChangePassword':\n\t\t\t\tpermission_section = 'user';\n\t\t\t\tbreak;\n\t\t\tcase 'UserDefault':\n\t\t\t\tpermission_section = 'user_default';\n\t\t\t\tbreak;\n\t\t\tcase 'UserTitle':\n\t\t\t\tpermission_section = 'user_title';\n\t\t\t\tbreak;\n\t\t\tcase 'UserGroup':\n\t\t\t\tpermission_section = 'user_group';\n\t\t\t\tbreak;\n\t\t\tcase 'EthnicGroup':\n\t\t\t\tpermission_section = 'ethnic_group';\n\t\t\t\tbreak;\n\t\t\tcase 'LegalEntity':\n\t\t\t\tpermission_section = 'legal_entity';\n\t\t\t\tbreak;\n\t\t\tcase 'PayrollRemittanceAgency':\n\t\t\t\tpermission_section = 'payroll_remittance_agency';\n\t\t\t\tbreak;\n\t\t\tcase 'MessageControl':\n\t\t\t\tpermission_section = 'message';\n\t\t\t\tbreak;\n\t\t\tcase 'Notification':\n\t\t\t\tpermission_section = 'notification';\n\t\t\t\tbreak;\n\t\t\tcase 'Wage':\n\t\t\tcase 'WageGroup':\n\t\t\t\tpermission_section = 'wage';\n\t\t\t\tbreak;\n\t\t\tcase 'UserContact':\n\t\t\t\tpermission_section = 'user_contact';\n\t\t\t\tbreak;\n\t\t\tcase 'LoginUserExpense':\n\t\t\tcase 'UserExpense':\n\t\t\t\tpermission_section = 'user_expense';\n\t\t\t\tbreak;\n\t\t\tcase 'UserSkill':\n\t\t\t\tpermission_section = 'user_skill';\n\t\t\t\tbreak;\n\t\t\tcase 'JobApplication':\n\t\t\t\tpermission_section = 'job_application';\n\t\t\t\tbreak;\n\t\t\tcase 'JobApplicant':\n\t\t\tcase 'RecruitmentPortalConfig':\n\t\t\t\tpermission_section = 'job_applicant';\n\t\t\t\tbreak;\n\t\t\tcase 'UserLicense':\n\t\t\t\tpermission_section = 'user_license';\n\t\t\t\tbreak;\n\t\t\tcase 'UserMembership':\n\t\t\t\tpermission_section = 'user_membership';\n\t\t\t\tbreak;\n\t\t\tcase 'UserEducation':\n\t\t\t\tpermission_section = 'user_education';\n\t\t\t\tbreak;\n\t\t\tcase 'UserPreference':\n\t\t\tcase 'LoginUserPreference':\n\t\t\t\tpermission_section = 'user_preference';\n\t\t\t\tbreak;\n\t\t\tcase 'UserLanguage':\n\t\t\t\tpermission_section = 'user_language';\n\t\t\t\tbreak;\n\t\t\tcase 'Company':\n\t\t\tcase 'Companies':\n\t\t\t\tpermission_section = 'company';\n\t\t\t\tbreak;\n\t\t\tcase 'GEOFence':\n\t\t\t\tpermission_section = 'geo_fence';\n\t\t\t\tbreak;\n\t\t\tcase 'Qualification':\n\t\t\tcase 'QualificationGroup':\n\t\t\t\tpermission_section = 'qualification';\n\t\t\t\tbreak;\n\t\t\tcase 'PayPeriodSchedule':\n\t\t\tcase 'PayPeriods':\n\t\t\t\tpermission_section = 'pay_period_schedule';\n\t\t\t\tbreak;\n\t\t\tcase 'PayStubAmendment':\n\t\t\tcase 'RecurringPayStubAmendment':\n\t\t\t\tpermission_section = 'pay_stub_amendment';\n\t\t\t\tbreak;\n\t\t\tcase 'PayStubTransactionSummaryReport':\n\t\t\tcase 'PayStub':\n\t\t\t\tpermission_section = 'pay_stub';\n\t\t\t\tbreak;\n\t\t\tcase 'Branch':\n\t\t\t\tpermission_section = 'branch';\n\t\t\t\tbreak;\n\t\t\tcase 'Department':\n\t\t\t\tpermission_section = 'department';\n\t\t\t\tbreak;\n\t\t\tcase 'HierarchyControl':\n\t\t\t\tpermission_section = 'hierarchy';\n\t\t\t\tbreak;\n\t\t\tcase 'Station':\n\t\t\t\tpermission_section = 'station';\n\t\t\t\tbreak;\n\t\t\tcase 'JobVacancy':\n\t\t\tcase 'PortalJobVacancy':\n\t\t\t\tpermission_section = 'job_vacancy';\n\t\t\t\tbreak;\n\t\t\tcase 'PayStubEntryAccount':\n\t\t\t\tpermission_section = 'pay_stub_account';\n\t\t\t\tbreak;\n\t\t\tcase 'ROE':\n\t\t\t\tpermission_section = 'roe';\n\t\t\t\tbreak;\n\t\t\tcase 'CustomField':\n\t\t\t\tpermission_section = 'custom_field';\n\t\t\t\tbreak;\n\t\t\tcase 'Currency':\n\t\t\t\tpermission_section = 'currency';\n\t\t\t\tbreak;\n\t\t\tcase 'PermissionControl':\n\t\t\t\tpermission_section = 'permission';\n\t\t\t\tbreak;\n\t\t\tcase 'CompanyTaxDeduction':\n\t\t\t\tpermission_section = 'company_tax_deduction';\n\t\t\t\tbreak;\n\t\t\tcase 'UserTaxDeduction':\n\t\t\t\tpermission_section = 'user_tax_deduction';\n\t\t\t\tbreak;\n\t\t\tcase 'Request':\n\t\t\t\tpermission_section = 'request';\n\t\t\t\tbreak;\n\t\t\tcase 'RequestAuthorization':\n\t\t\tcase 'ExpenseAuthorization':\n\t\t\t\tpermission_section = 'authorization';\n\t\t\t\tbreak;\n\t\t\tcase 'Document':\n\t\t\tcase 'DocumentGroup':\n\t\t\t\tpermission_section = 'document';\n\t\t\t\tbreak;\n\t\t\tcase 'SchedulePolicy':\n\t\t\t\tpermission_section = 'schedule_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'AccrualPolicyAccount':\n\t\t\tcase 'AccrualPolicy':\n\t\t\t\tpermission_section = 'accrual_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'Client':\n\t\t\tcase 'ClientContact':\n\t\t\tcase 'InvoiceDistrict':\n\t\t\tcase 'ClientPayment':\n\t\t\t\tpermission_section = 'client';\n\t\t\t\tbreak;\n\t\t\tcase 'InvoiceTransaction':\n\t\t\t\tpermission_section = 'transaction';\n\t\t\t\tbreak;\n\t\t\tcase 'JobItemGroup':\n\t\t\tcase 'JobItem':\n\t\t\t\tpermission_section = 'job_item';\n\t\t\t\tbreak;\n\t\t\tcase 'SavedReport':\n\t\t\t\tpermission_section = 'report';\n\t\t\t\tbreak;\n\t\t\tcase 'RecurringScheduleControl':\n\t\t\t\tpermission_section = 'recurring_schedule';\n\t\t\t\tbreak;\n\t\t\tcase 'RecurringScheduleTemplateControl':\n\t\t\t\tpermission_section = 'recurring_schedule_template';\n\t\t\t\tbreak;\n\t\t\tcase 'KPI':\n\t\t\tcase 'KPIGroup':\n\t\t\t\tpermission_section = 'kpi';\n\t\t\t\tbreak;\n\t\t\tcase 'UserReviewControl':\n\t\t\t\tpermission_section = 'user_review';\n\t\t\t\tbreak;\n\t\t\tcase 'ExceptionPolicyControl':\n\t\t\t\tpermission_section = 'exception_policy';\n\t\t\t\tbreak;\n\t\t\tcase 'ImportCSV':\n\t\t\t\tpermission_section = 'import_csv';\n\t\t\t\tbreak;\n\t\t\tcase 'Invoice':\n\t\t\tcase 'JobInvoice':\n\t\t\t\tpermission_section = 'invoice';\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn permission_section;\n\t};\n\n\tvar getPermissionData = function() {\n\t\treturn LocalCacheData.getPermissionData();\n\t};\n\n\treturn {\n\t\tcheckTopLevelPermission: checkTopLevelPermission,\n\t\tvalidate: validate,\n\t\tgetPermissionLevel: getPermissionLevel,\n\t\tgetPermissionData: getPermissionData,\n\t\tHelpMenuValidateAdmin: HelpMenuValidateAdmin,\n\t\tHelpMenuValidateSupervisor: HelpMenuValidateSupervisor,\n\t\timportValidate: importValidate,\n\t\tsubJobApplicationValidate: subJobApplicationValidate\n\t};\n\n} )();\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODg0My5qcyIsIm1hcHBpbmdzIjoiOzs7QUFBTzs7QUFFUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBLHdHQUF3RztBQUN4RztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSx5S0FBeUs7QUFDeks7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxtQkFBbUIsMEJBQTBCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsRUFBRSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvUGVybWlzc2lvbk1hbmFnZXIuanM/ZWFlNiJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdmFyIFBlcm1pc3Npb25NYW5hZ2VyID0gKCBmdW5jdGlvbigpIHtcblxuXHR2YXIgdmFsaWRhdGUgPSBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0dmFyIHBlcm1pc3Npb24gPSBQZXJtaXNzaW9uTWFuYWdlci5nZXRQZXJtaXNzaW9uRGF0YSgpO1xuXG5cdFx0Ly9FcnJvcjogVW5jYXVnaHQgVHlwZUVycm9yOiBDYW5ub3QgcmVhZCBwcm9wZXJ0eSAncHVuY2gnIG9mIG51bGwgaW4gL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvUGVybWlzc2lvbk1hbmFnZXIuanM/dj04LjAuMC0yMDE0MTIzMC0xMTU3NTkgbGluZSA2XG5cdFx0aWYgKCAhcGVybWlzc2lvbiB8fCAhR2xvYmFsLmlzU2V0KCBwZXJtaXNzaW9uW25hbWVdICkgfHwgIUdsb2JhbC5pc1NldCggcGVybWlzc2lvbltuYW1lXVt2YWx1ZV0gKSApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIHBlcm1pc3Npb25bbmFtZV1bdmFsdWVdO1xuXHRcdH1cblx0fTtcblxuXHR2YXIgZ2V0UGVybWlzc2lvbkxldmVsID0gZnVuY3Rpb24oKSB7XG5cdFx0dmFyIHBlcm1pc3Npb24gPSBQZXJtaXNzaW9uTWFuYWdlci5nZXRQZXJtaXNzaW9uRGF0YSgpO1xuXG5cdFx0aWYgKCBwZXJtaXNzaW9uICYmIHBlcm1pc3Npb25bJ19zeXN0ZW0nXSAmJiBwZXJtaXNzaW9uWydfc3lzdGVtJ11bJ2xldmVsJ10gKSB7XG5cdFx0XHRyZXR1cm4gcGVybWlzc2lvblsnX3N5c3RlbSddWydsZXZlbCddO1xuXHRcdH1cblxuXHRcdHJldHVybiAwO1xuXHR9O1xuXG5cdHZhciBzdWJKb2JBcHBsaWNhdGlvblZhbGlkYXRlID0gZnVuY3Rpb24oIHZpZXdJZCApIHtcblx0XHR2YXIgcGVybWlzc2lvbl9zZWN0aW9uID0gZ2V0UGVybWlzc2lvblNlY3Rpb25CeVZpZXdJZCggdmlld0lkICk7XG5cblx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSB8fFxuXHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXQnICkgfHwgUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfY2hpbGQnICkgKSB7XG4vL1x0XHRcdHJldHVybiB0cnVlOyAvLyBoaWRlIHRoZSB0YWIgdW50aWwgdGhlIEFQSSBjb21wbGV0ZS5cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cblx0fTtcblxuXHR2YXIgSGVscE1lbnVWYWxpZGF0ZUFkbWluID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci5nZXRQZXJtaXNzaW9uTGV2ZWwoKSA+PSA3MCAmJiBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3VzZXInLCAnZWRpdCcgKSApIHsgLy83MD1IUiBNYW5hZ2VyIG9yIGhpZ2hlclxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9O1xuXG5cdHZhciBIZWxwTWVudVZhbGlkYXRlU3VwZXJ2aXNvciA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIuZ2V0UGVybWlzc2lvbkxldmVsKCkgPj0gNDAgJiYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3VzZXInLCAnZWRpdF9jaGlsZCcgKSB8fCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3B1bmNoJywgJ2VkaXRfY2hpbGQnICkgKSApIHsgLy80MD1TdXBlcnZpc29yIChTdWJvcmRpbmF0ZXMgT25seSlcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fTtcblxuXHR2YXIgY2hlY2tUb3BMZXZlbFBlcm1pc3Npb24gPSBmdW5jdGlvbiggdmlld0lkICkge1xuXHRcdHZhciBwZXJtaXNzaW9uX3NlY3Rpb24gPSBnZXRQZXJtaXNzaW9uU2VjdGlvbkJ5Vmlld0lkKCB2aWV3SWQgKTtcblxuXHRcdHZhciByZXN1bHQgPSBmYWxzZTtcblxuXHRcdGlmICggdmlld0lkID09PSAnQWJvdXQnICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly9UeXBlRXJyb3I6IENhbm5vdCByZWFkIHByb3BlcnR5ICdwcm9kdWN0X2VkaXRpb25faWQnIG9mIG51bGxcblx0XHQvL0JVRyMyMDY2IC0gZmFpbCBncmFjZWZ1bGx5XG5cdFx0Ly8gU2luY2UgTG9jYWxDYWNoZURhdGEuZ2V0Q3VycmVudENvbXBhbnkoKSBpcyByZXF1aXJlIGRhdGEsIGlmIHRoZSB1c2VyIHdhcyBsb2dnZWQgb3V0IG9yIGluIHRoZSBwcm9jZXNzIG9mIGxvZ2dpbmcgb3V0LCBpdCBjb3VsZCB0cmlnZ2VyIHNlbmRFcnJvclJlcG9ydCgpXG5cdFx0Ly8gICBzbyBmaXJzdCBjaGVjayB0aGF0ICdjdXJyZW50X2NvbXBhbnknIGV4aXN0cyBpbiB0aGUgTG9jYWxDYWNoZURhdGEgdG8gYXZvaWQgY2FsbGluZyBnZXRDdXJyZW50Q29tcGFueSgpIGlmIGl0IGRvZXNuJ3QgZXhpc3QuXG5cdFx0aWYgKCBHbG9iYWwuaXNTZXQoIExvY2FsQ2FjaGVEYXRhICkgPT0gZmFsc2UgfHwgTG9jYWxDYWNoZURhdGEuaXNMb2NhbENhY2hlRXhpc3RzKCAnY3VycmVudF9jb21wYW55JyApID09IGZhbHNlIHx8IEdsb2JhbC5pc1NldCggTG9jYWxDYWNoZURhdGEuZ2V0Q3VycmVudENvbXBhbnkoKSApID09IGZhbHNlICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHN3aXRjaCAoIHZpZXdJZCApIHtcblx0XHRcdGNhc2UgJ0dyaWRUZXN0Jzpcblx0XHRcdGNhc2UgJ1dpZGdldFRlc3QnOlxuXHRcdFx0Y2FzZSAnQXdlc29tZWJveFRlc3QnOlxuXHRcdFx0Y2FzZSAnVUlLaXRTYW1wbGUnOlxuXHRcdFx0Y2FzZSAnVUlLaXRDaGlsZFNhbXBsZSc6XG5cdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSm9iSW52b2ljZSc6XG5cdFx0XHRcdGlmICggISggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMjAgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnYWRkJyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXQnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdF9vd24nICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1BheW1lbnRHYXRld2F5Jzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlZGl0JyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfb3duJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdJbnZvaWNlQ29uZmlnJzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlZGl0JyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfb3duJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdDdXN0b21GaWVsZCc6XG5cdFx0XHRcdGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSAmJlxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlZGl0JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdJbk91dCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgJiYgUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3B1bmNoX2luX291dCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRW1wbG95ZWUnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19jaGlsZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnTGVnYWxFbnRpdHknOlxuXHRcdFx0Y2FzZSAnUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3knOlxuXHRcdFx0Y2FzZSAnUmVtaXR0YW5jZVNvdXJjZUFjY291bnQnOlxuXHRcdFx0Y2FzZSAnVXNlclRpdGxlJzpcblx0XHRcdGNhc2UgJ1VzZXJHcm91cCc6XG5cdFx0XHRjYXNlICdVc2VyRGVmYXVsdCc6XG5cdFx0XHRjYXNlICdFdGhuaWNHcm91cCc6XG5cdFx0XHRcdGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdCcgKSAmJiBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnYWRkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdSZW1pdHRhbmNlRGVzdGluYXRpb25BY2NvdW50JzogLy9VbmNvbW1lbnQgdGhpcyB0byBlbmFibGUgRW1wbG95ZWUgLT4gUGF5bWVudCBNZXRob2RzIGZvciByZWd1bGFyIGVtcGxveWVlcy4gLS0gQ3VycmVudGx5IFN1cGVydmlzb3JzL1BheXJvbGwgQWRtaW5zL0FkbWlucyBjYW4gc2VlIHRoaXMuXG5cdFx0XHRjYXNlICdQdW5jaGVzJzpcblx0XHRcdFx0aWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlZGl0JyApIHx8IFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlZGl0X2NoaWxkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdHb3Zlcm5tZW50RG9jdW1lbnQnOlxuXHRcdFx0Y2FzZSAnRXhjZXB0aW9uJzpcblx0XHRcdFx0aWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3JyApIHx8IFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X293bicgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQ29tcGFueSc6XG5cdFx0XHRjYXNlICdMb2dpblVzZXJDb250YWN0Jzpcblx0XHRcdGNhc2UgJ0xvZ2luVXNlclByZWZlcmVuY2UnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfb3duJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdDb21wYW5pZXMnOlxuXHRcdFx0XHRpZiAoICggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMTUgKSAmJlxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICYmIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdTYXZlZFJlcG9ydCc6XG5cdFx0XHRcdGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQZXJtaXNzaW9uQ29udHJvbCc6XG5cdFx0XHRcdGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRG9jdW1lbnRHcm91cCc6XG5cdFx0XHRcdGlmICggISggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMjAgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRjYXNlICdQYXlQZXJpb2RTY2hlZHVsZSc6XG5cdFx0XHRjYXNlICdCcmFuY2gnOlxuXHRcdFx0Y2FzZSAnRGVwYXJ0bWVudCc6XG5cdFx0XHRjYXNlICdIaWVyYXJjaHlDb250cm9sJzpcblx0XHRcdGNhc2UgJ1dhZ2VHcm91cCc6XG5cdFx0XHRjYXNlICdTdGF0aW9uJzpcblx0XHRcdGNhc2UgJ0N1cnJlbmN5Jzpcblx0XHRcdGNhc2UgJ1BheVN0dWJFbnRyeUFjY291bnQnOlxuXHRcdFx0Y2FzZSAnQ29tcGFueVRheERlZHVjdGlvbic6XG5cdFx0XHRjYXNlICdQb2xpY3lHcm91cCc6XG5cdFx0XHRjYXNlICdTY2hlZHVsZVBvbGljeSc6XG5cdFx0XHRjYXNlICdSb3VuZEludGVydmFsUG9saWN5Jzpcblx0XHRcdGNhc2UgJ01lYWxQb2xpY3knOlxuXHRcdFx0Y2FzZSAnQnJlYWtQb2xpY3knOlxuXHRcdFx0Y2FzZSAnT3ZlcnRpbWVQb2xpY3knOlxuXHRcdFx0Y2FzZSAnUHJlbWl1bVBvbGljeSc6XG5cdFx0XHRjYXNlICdFeGNlcHRpb25Qb2xpY3lDb250cm9sJzpcblx0XHRcdGNhc2UgJ0FjY3J1YWxQb2xpY3knOlxuXHRcdFx0Y2FzZSAnQWJzZW5jZVBvbGljeSc6XG5cdFx0XHRjYXNlICdIb2xpZGF5UG9saWN5Jzpcblx0XHRcdGNhc2UgJ1JlY3VycmluZ0hvbGlkYXknOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1JlcXVlc3RBdXRob3JpemF0aW9uJzpcblx0XHRcdFx0aWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVxdWVzdCcsICdhdXRob3JpemUnICkgJiYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSB8fCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19jaGlsZCcgKSApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdUaW1lU2hlZXRBdXRob3JpemF0aW9uJzpcblx0XHRcdFx0aWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncHVuY2gnLCAnYXV0aG9yaXplJyApICYmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHwgUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfY2hpbGQnICkgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRXhwZW5zZUF1dGhvcml6YXRpb24nOlxuXHRcdFx0XHRpZiAoICEoIEdsb2JhbC5nZXRQcm9kdWN0RWRpdGlvbigpID49IDI1ICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICd1c2VyX2V4cGVuc2UnLCAnYXV0aG9yaXplJyApICYmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHwgUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfY2hpbGQnICkgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlckV4cGVuc2UnOlxuXHRcdFx0XHRpZiAoICEoIEdsb2JhbC5nZXRQcm9kdWN0RWRpdGlvbigpID49IDI1ICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0ltcG9ydENTVic6XG5cdFx0XHRcdC8vVGhpcyBpcyB0aGUgQ29tcGFueSAtPiBJbXBvcnQgaWNvbiwgd2hpY2ggc2hvdWxkIG9ubHkgYmUgZGlzcGxheWVkIGlmICdjb21wYW55JywnZW5hYmxlZCcgaXMgYWxzbyBhbGxvd2VkLlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAnY29tcGFueScsICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGltcG9ydFZhbGlkYXRlKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdJbXBvcnRDU1ZTY2hlZHVsZSc6XG5cdFx0XHRcdHJlc3VsdCA9IGltcG9ydFZhbGlkYXRlRm9yKCAnc2NoZWR1bGUnICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW1wb3J0Q1NWQnJhbmNoJzpcblx0XHRcdFx0cmVzdWx0ID0gaW1wb3J0VmFsaWRhdGVGb3IoICdicmFuY2gnICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW1wb3J0Q1NWRGVwYXJ0bWVudCc6XG5cdFx0XHRcdHJlc3VsdCA9IGltcG9ydFZhbGlkYXRlRm9yKCAnZGVwYXJ0bWVudCcgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdJbXBvcnRDU1ZXYWdlJzpcblx0XHRcdFx0cmVzdWx0ID0gaW1wb3J0VmFsaWRhdGVGb3IoICd3YWdlJyApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0ltcG9ydENTVkVtcGxveWVlQmFua0FjY291bnQnOlxuXHRcdFx0XHRyZXN1bHQgPSBpbXBvcnRWYWxpZGF0ZUZvciggJ3VzZXInICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW1wb3J0Q1NWRW1wbG95ZWUnOlxuXHRcdFx0XHRyZXN1bHQgPSBpbXBvcnRWYWxpZGF0ZUZvciggJ3VzZXInICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW1wb3J0Q1NWUGF5U3R1YkFtZW5kbWVudCc6XG5cdFx0XHRcdHJlc3VsdCA9IGltcG9ydFZhbGlkYXRlRm9yKCAncGF5X3N0dWJfYW1lbmRtZW50JyApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0ltcG9ydENTVkpvYic6XG5cdFx0XHRcdHJlc3VsdCA9IGltcG9ydFZhbGlkYXRlRm9yKCAnam9iJyApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0ltcG9ydENTVkpvYkl0ZW0nOlxuXHRcdFx0XHRyZXN1bHQgPSBpbXBvcnRWYWxpZGF0ZUZvciggJ2pvYl9pdGVtJyApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1BheXJvbGxQcm9jZXNzV2l6YXJkJzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3BheV9zdHViJywgJ2FkZCcgKSAmJlxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncGF5X3N0dWInLCAnZWRpdCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUXVpY2tTdGFydFdpemFyZCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdwYXlfcGVyaW9kX3NjaGVkdWxlJywgJ2FkZCcgKSAmJlxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAndXNlcl9wcmVmZXJlbmNlJywgJ2VkaXQnICkgJiZcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3BvbGljeV9ncm91cCcsICdlZGl0JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdBY2NydWFsQmFsYW5jZSc6XG5cdFx0XHRjYXNlICdBY2NydWFsJzpcblx0XHRcdGNhc2UgJ1JlcXVlc3QnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19vd24nICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1NjaGVkdWxlU2hpZnQnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXQnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdF9jaGlsZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUmVjdXJyaW5nU2NoZWR1bGVDb250cm9sJzpcblx0XHRcdGNhc2UgJ1JlY3VycmluZ1NjaGVkdWxlVGVtcGxhdGVDb250cm9sJzpcblx0XHRcdGNhc2UgJ01lc3NhZ2VDb250cm9sJzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnTm90aWZpY2F0aW9uJzpcblx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTsgLy8gTm90aWZpY2F0aW9uIGFsd2F5cyByZXR1cm5zIHRydWUgYXMgbm90aWZpY2F0aW9ucyBzaG91bGQgYWx3YXlzIGJlIGVuYWJsZWQuXG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlclByZWZlcmVuY2UnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXQnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZWRpdF9jaGlsZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRG9jdW1lbnQnOlxuXHRcdFx0XHRpZiAoICEoIEdsb2JhbC5nZXRQcm9kdWN0RWRpdGlvbigpID49IDIwICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19vd24nICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19wcml2YXRlJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdDaGFuZ2VQYXNzd29yZCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfb3duX3Bhc3N3b3JkJyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VkaXRfb3duX3Bob25lX3Bhc3N3b3JkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdBY3RpdmVTaGlmdFJlcG9ydCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdyZXBvcnQnLCAndmlld19hY3RpdmVfc2hpZnQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VzZXJTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X3VzZXJfaW5mb3JtYXRpb24nICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0F1ZGl0VHJhaWxSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfc3lzdGVtX2xvZycgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnU2NoZWR1bGVTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X3NjaGVkdWxlX3N1bW1hcnknICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1RpbWVzaGVldFN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0Y2FzZSAnVGltZXNoZWV0RGV0YWlsUmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X3RpbWVzaGVldF9zdW1tYXJ5JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQdW5jaFN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfcHVuY2hfc3VtbWFyeScgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQWNjcnVhbEJhbGFuY2VTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2FjY3J1YWxfYmFsYW5jZV9zdW1tYXJ5JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdFeGNlcHRpb25TdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2V4Y2VwdGlvbl9zdW1tYXJ5JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQYXlTdHViVHJhbnNhY3Rpb25TdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdGNhc2UgJ1BheVN0dWJTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X3BheV9zdHViX3N1bW1hcnknICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1BheXJvbGxFeHBvcnRSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfcGF5cm9sbF9leHBvcnQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0dlbmVyYWxMZWRnZXJTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2dlbmVyYWxfbGVkZ2VyX3N1bW1hcnknICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0V4cGVuc2VTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2V4cGVuc2UnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0pvYlN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0Y2FzZSAnSm9iSW5mb3JtYXRpb25SZXBvcnQnOlxuXHRcdFx0Y2FzZSAnSm9iSXRlbUluZm9ybWF0aW9uUmVwb3J0Jzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ2pvYl9yZXBvcnQnLCAndmlld19qb2Jfc3VtbWFyeScgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSm9iQW5hbHlzaXNSZXBvcnQnOlxuXHRcdFx0XHRpZiAoICEoIEdsb2JhbC5nZXRQcm9kdWN0RWRpdGlvbigpID49IDIwICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAnam9iX3JlcG9ydCcsICd2aWV3X2pvYl9hbmFseXNpcycgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW52b2ljZVRyYW5zYWN0aW9uU3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRcdGlmICggISggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMjAgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdpbnZvaWNlX3JlcG9ydCcsICd2aWV3X3RyYW5zYWN0aW9uX3N1bW1hcnknICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1JlbWl0dGFuY2VTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X3JlbWl0dGFuY2Vfc3VtbWFyeScgKSAmJlxuXHRcdFx0XHRcdGNvdW50cnlQZXJtaXNzaW9uVmFsaWRhdGUoICdDQScgKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVDRTdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdGNhc2UgJ1Q0QVN1bW1hcnlSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfdDRfc3VtbWFyeScgKSAmJlxuXHRcdFx0XHRcdGNvdW50cnlQZXJtaXNzaW9uVmFsaWRhdGUoICdDQScgKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVGF4U3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdyZXBvcnQnLCAndmlld19nZW5lcmljX3RheF9zdW1tYXJ5JyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdGb3JtOTQwUmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2Zvcm05NDAnICkgJiZcblx0XHRcdFx0XHRjb3VudHJ5UGVybWlzc2lvblZhbGlkYXRlKCAnVVMnIClcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0Zvcm05NDFSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfZm9ybTk0MScgKSAmJlxuXHRcdFx0XHRcdGNvdW50cnlQZXJtaXNzaW9uVmFsaWRhdGUoICdVUycgKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRm9ybTEwOTlOZWNSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfZm9ybTEwOTluZWMnICkgJiZcblx0XHRcdFx0XHRjb3VudHJ5UGVybWlzc2lvblZhbGlkYXRlKCAnVVMnIClcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0Zvcm1XMlJlcG9ydCc6XG5cdFx0XHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdyZXBvcnQnLCAndmlld19mb3JtVzInICkgJiZcblx0XHRcdFx0XHRjb3VudHJ5UGVybWlzc2lvblZhbGlkYXRlKCAnVVMnIClcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VTU3RhdGVVbmVtcGxveW1lbnRSZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVwb3J0JywgJ3ZpZXdfdXNfc3RhdGVfdW5lbXBsb3ltZW50JyApICYmXG5cdFx0XHRcdFx0Y291bnRyeVBlcm1pc3Npb25WYWxpZGF0ZSggJ1VTJyApXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdBZmZvcmRhYmxlQ2FyZVJlcG9ydCc6XG5cdFx0XHRcdGlmICggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMTUgJiZcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3JlcG9ydCcsICd2aWV3X2FmZm9yZGFibGVfY2FyZScgKSAmJlxuXHRcdFx0XHRcdGNvdW50cnlQZXJtaXNzaW9uVmFsaWRhdGUoICdVUycgKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlclF1YWxpZmljYXRpb25SZXBvcnQnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAnaHJfcmVwb3J0JywgJ3VzZXJfcXVhbGlmaWNhdGlvbicgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnS1BJUmVwb3J0Jzpcblx0XHRcdFx0aWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ2hyX3JlcG9ydCcsICd1c2VyX3JldmlldycgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlclJlY3J1aXRtZW50U3VtbWFyeVJlcG9ydCc6XG5cdFx0XHRjYXNlICdVc2VyUmVjcnVpdG1lbnREZXRhaWxSZXBvcnQnOlxuXHRcdFx0XHRpZiAoICEoIEdsb2JhbC5nZXRQcm9kdWN0RWRpdGlvbigpID49IDI1ICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncmVjcnVpdG1lbnRfcmVwb3J0JywgJ3VzZXJfcmVjcnVpdG1lbnQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0NsaWVudCc6XG5cdFx0XHRjYXNlICdDbGllbnRDb250YWN0Jzpcblx0XHRcdGNhc2UgJ0ludm9pY2VEaXN0cmljdCc6XG5cdFx0XHRjYXNlICdDbGllbnRQYXltZW50Jzpcblx0XHRcdGNhc2UgJ0ludm9pY2UnOlxuXHRcdFx0Y2FzZSAnSW52b2ljZVRyYW5zYWN0aW9uJzpcblx0XHRcdGNhc2UgJ1Byb2R1Y3QnOlxuXHRcdFx0Y2FzZSAnQ2xpZW50R3JvdXAnOlxuXHRcdFx0Y2FzZSAnUHJvZHVjdEdyb3VwJzpcblx0XHRcdGNhc2UgJ1RheFBvbGljeSc6XG5cdFx0XHRjYXNlICdTaGlwcGluZ1BvbGljeSc6XG5cdFx0XHRjYXNlICdBcmVhUG9saWN5Jzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3JyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfb3duJyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfY2hpbGQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0pvYic6XG5cdFx0XHRjYXNlICdKb2JJdGVtJzpcblx0XHRcdGNhc2UgJ0pvYkdyb3VwJzpcblx0XHRcdGNhc2UgJ0pvYkl0ZW1Hcm91cCc6XG5cdFx0XHRcdGlmICggISggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMjAgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X293bicgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X2NoaWxkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQdW5jaFRhZyc6XG5cdFx0XHRjYXNlICdQdW5jaFRhZ0dyb3VwJzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3JyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfb3duJyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfY2hpbGQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0dFT0ZlbmNlJzpcblx0XHRcdFx0aWYgKCAhKCBHbG9iYWwuZ2V0UHJvZHVjdEVkaXRpb24oKSA+PSAyMCApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCAhUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ2VuYWJsZWQnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3JyApIHx8XG5cdFx0XHRcdFx0UGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXdfb3duJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdFeHBlbnNlUG9saWN5Jzpcblx0XHRcdGNhc2UgJ0xvZ2luVXNlckV4cGVuc2UnOlxuXHRcdFx0Y2FzZSAnSm9iVmFjYW5jeSc6XG5cdFx0XHRjYXNlICdKb2JBcHBsaWNhbnQnOlxuXHRcdFx0Y2FzZSAnSm9iQXBwbGljYXRpb24nOlxuXG5cdFx0XHRcdGlmICggISggR2xvYmFsLmdldFByb2R1Y3RFZGl0aW9uKCkgPj0gMjUgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggIVBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICdlbmFibGVkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X293bicgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X2NoaWxkJyApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdST0UnOlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlldycgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X293bicgKSB8fFxuXHRcdFx0XHRcdFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCBwZXJtaXNzaW9uX3NlY3Rpb24sICd2aWV3X2NoaWxkJyApICkgJiZcblx0XHRcdFx0XHRjb3VudHJ5UGVybWlzc2lvblZhbGlkYXRlKCAnQ0EnICkgKSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0dlbmVyYXRlUGF5U3R1YnMnOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncGF5X3BlcmlvZF9zY2hlZHVsZScsICdlbmFibGVkJyApXG5cdFx0XHRcdFx0JiYgKCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3BheV9wZXJpb2Rfc2NoZWR1bGUnLCAnZWRpdCcgKSB8fCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggJ3BheV9wZXJpb2Rfc2NoZWR1bGUnLCAnZWRpdF9vd24nICkgKVxuXHRcdFx0XHRcdCYmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdwYXlfc3R1YicsICd2aWV3JyApIHx8IFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncGF5X3N0dWInLCAndmlld19jaGlsZCcgKSApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQYXlTdHViVHJhbnNhY3Rpb24nOlxuXHRcdFx0XHRpZiAoIFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncGF5X3N0dWInLCAnZW5hYmxlZCcgKVxuXHRcdFx0XHRcdCYmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoICdwYXlfc3R1YicsICd2aWV3JyApIHx8IFBlcm1pc3Npb25NYW5hZ2VyLnZhbGlkYXRlKCAncGF5X3N0dWInLCAndmlld19jaGlsZCcgKSApICkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRpZiAoICFQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAnZW5hYmxlZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIHBlcm1pc3Npb25fc2VjdGlvbiwgJ3ZpZXcnICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19vd24nICkgfHxcblx0XHRcdFx0XHRQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSggcGVybWlzc2lvbl9zZWN0aW9uLCAndmlld19jaGlsZCcgKSApIHtcblx0XHRcdFx0XHRyZXN1bHQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fTtcblxuXHR2YXIgY291bnRyeVBlcm1pc3Npb25WYWxpZGF0ZSA9IGZ1bmN0aW9uKCBrZXkgKSB7XG5cblx0XHR2YXIgY291bnRyeV9hcnJheSA9IExvY2FsQ2FjaGVEYXRhLmdldFVuaXF1ZUNvdW50cnlBcnJheSgpO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgY291bnRyeV9hcnJheS5sZW5ndGg7IGkrKyApIHtcblx0XHRcdGlmICgga2V5ID09PSBjb3VudHJ5X2FycmF5W2ldICkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cblx0fTtcblxuXHR2YXIgaW1wb3J0VmFsaWRhdGUgPSBmdW5jdGlvbigpIHtcblxuXHRcdHZhciByZXN1bHQgPSBmYWxzZTtcblxuXHRcdGlmICggaW1wb3J0VmFsaWRhdGVGb3IoICdicmFuY2gnICkgfHxcblx0XHRcdGltcG9ydFZhbGlkYXRlRm9yKCAncGF5cGVyaW9kJyApIHx8XG5cdFx0XHRpbXBvcnRWYWxpZGF0ZUZvciggJ3NjaGVkdWxlJyApIHx8XG5cdFx0XHRpbXBvcnRWYWxpZGF0ZUZvciggJ3VzZXInICkgfHxcblx0XHRcdGltcG9ydFZhbGlkYXRlRm9yKCAnZGVwYXJ0bWVudCcgKSB8fFxuXHRcdFx0aW1wb3J0VmFsaWRhdGVGb3IoICdjbGllbnQnICkgfHxcblx0XHRcdGltcG9ydFZhbGlkYXRlRm9yKCAnam9iJyApIHx8XG5cdFx0XHRpbXBvcnRWYWxpZGF0ZUZvciggJ2pvYml0ZW0nICkgfHxcblx0XHRcdGltcG9ydFZhbGlkYXRlRm9yKCAnd2FnZScgKSB8fFxuXHRcdFx0aW1wb3J0VmFsaWRhdGVGb3IoICdwdW5jaCcgKSB8fFxuXHRcdFx0aW1wb3J0VmFsaWRhdGVGb3IoICdwYXlzdHViYW1lbmRtZW50JyApIHx8XG5cdFx0XHRpbXBvcnRWYWxpZGF0ZUZvciggJ2FjY3J1YWwnICkgKSB7XG5cblx0XHRcdHJlc3VsdCA9IHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fTtcblxuXHR2YXIgaW1wb3J0VmFsaWRhdGVGb3IgPSBmdW5jdGlvbigga2V5ICkge1xuXHRcdGlmICggUGVybWlzc2lvbk1hbmFnZXIudmFsaWRhdGUoIGtleSwgJ2FkZCcgKSAmJlxuXHRcdFx0KCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSgga2V5LCAnZWRpdCcgKSB8fCBQZXJtaXNzaW9uTWFuYWdlci52YWxpZGF0ZSgga2V5LCAnZWRpdF9jaGlsZCcgKSApICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9O1xuXG5cdHZhciBnZXRQZXJtaXNzaW9uU2VjdGlvbkJ5Vmlld0lkID0gZnVuY3Rpb24oIHZpZXdJZCApIHtcblxuXHRcdHZhciBwZXJtaXNzaW9uX3NlY3Rpb24gPSAnJztcblxuXHRcdHN3aXRjaCAoIHZpZXdJZCApIHtcblx0XHRcdGNhc2UgJ0FjY3VtdWxhdGVkVGltZSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICd1c2VyX2RhdGVfdG90YWwnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1BheW1lbnRHYXRld2F5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3BheW1lbnRfZ2F0ZXdheSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW52b2ljZUNvbmZpZyc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdpbnZvaWNlX2NvbmZpZyc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQXJlYVBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdhcmVhX3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnU2hpcHBpbmdQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnc2hpcHBpbmdfcG9saWN5Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdHb3Zlcm5tZW50RG9jdW1lbnQnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnZ292ZXJubWVudF9kb2N1bWVudCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVGF4UG9saWN5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3RheF9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1Byb2R1Y3QnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncHJvZHVjdCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUmVtaXR0YW5jZVNvdXJjZUFjY291bnQnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncmVtaXR0YW5jZV9zb3VyY2VfYWNjb3VudCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUmVtaXR0YW5jZURlc3RpbmF0aW9uQWNjb3VudCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdyZW1pdHRhbmNlX2Rlc3RpbmF0aW9uX2FjY291bnQnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1NjaGVkdWxlU2hpZnQnOlxuXHRcdFx0Y2FzZSAnU2NoZWR1bGUnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnc2NoZWR1bGUnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1RpbWVTaGVldCc6XG5cdFx0XHRjYXNlICdNYW51YWxUaW1lU2hlZXQnOlxuXHRcdFx0Y2FzZSAnVXNlckRhdGVUb3RhbFBhcmVudCc6XG5cdFx0XHRjYXNlICdVc2VyRGF0ZVRvdGFsJzpcblx0XHRcdGNhc2UgJ0luT3V0Jzpcblx0XHRcdGNhc2UgJ1B1bmNoZXMnOlxuXHRcdFx0Y2FzZSAnVGltZVNoZWV0QXV0aG9yaXphdGlvbic6XG5cdFx0XHRjYXNlICdFeGNlcHRpb24nOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncHVuY2gnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0FjY3J1YWxCYWxhbmNlJzpcblx0XHRcdGNhc2UgJ0FjY3J1YWwnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnYWNjcnVhbCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSm9iJzpcblx0XHRcdGNhc2UgJ0pvYkdyb3VwJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2pvYic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUHVuY2hUYWcnOlxuXHRcdFx0Y2FzZSAnUHVuY2hUYWdHcm91cCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdwdW5jaF90YWcnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1BvbGljeUdyb3VwJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3BvbGljeV9ncm91cCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUGF5Q29kZSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdwYXlfY29kZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUGF5Rm9ybXVsYVBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdwYXlfZm9ybXVsYV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0NvbnRyaWJ1dGluZ1BheUNvZGVQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnY29udHJpYnV0aW5nX3BheV9jb2RlX3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQ29udHJpYnV0aW5nU2hpZnRQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnY29udHJpYnV0aW5nX3NoaWZ0X3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQWJzZW5jZVBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdhYnNlbmNlX3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnTWVhbFBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdtZWFsX3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnRXhwZW5zZVBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdleHBlbnNlX3BvbGljeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQnJlYWtQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnYnJlYWtfcG9saWN5Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdIb2xpZGF5UG9saWN5Jzpcblx0XHRcdGNhc2UgJ1JlY3VycmluZ0hvbGlkYXknOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnaG9saWRheV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1ByZW1pdW1Qb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncHJlbWl1bV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1JlZ3VsYXJUaW1lUG9saWN5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3JlZ3VsYXJfdGltZV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ092ZXJ0aW1lUG9saWN5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ292ZXJfdGltZV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1JvdW5kSW50ZXJ2YWxQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncm91bmRfcG9saWN5Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdFbXBsb3llZSc6XG5cdFx0XHRjYXNlICdMb2dpblVzZXJDb250YWN0Jzpcblx0XHRcdGNhc2UgJ0NoYW5nZVBhc3N3b3JkJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXInO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VzZXJEZWZhdWx0Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfZGVmYXVsdCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlclRpdGxlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfdGl0bGUnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VzZXJHcm91cCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICd1c2VyX2dyb3VwJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdFdGhuaWNHcm91cCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdldGhuaWNfZ3JvdXAnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0xlZ2FsRW50aXR5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2xlZ2FsX2VudGl0eSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncGF5cm9sbF9yZW1pdHRhbmNlX2FnZW5jeSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnTWVzc2FnZUNvbnRyb2wnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnbWVzc2FnZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnTm90aWZpY2F0aW9uJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ25vdGlmaWNhdGlvbic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnV2FnZSc6XG5cdFx0XHRjYXNlICdXYWdlR3JvdXAnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnd2FnZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlckNvbnRhY3QnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAndXNlcl9jb250YWN0Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdMb2dpblVzZXJFeHBlbnNlJzpcblx0XHRcdGNhc2UgJ1VzZXJFeHBlbnNlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfZXhwZW5zZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlclNraWxsJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfc2tpbGwnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0pvYkFwcGxpY2F0aW9uJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2pvYl9hcHBsaWNhdGlvbic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSm9iQXBwbGljYW50Jzpcblx0XHRcdGNhc2UgJ1JlY3J1aXRtZW50UG9ydGFsQ29uZmlnJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2pvYl9hcHBsaWNhbnQnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VzZXJMaWNlbnNlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfbGljZW5zZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlck1lbWJlcnNoaXAnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAndXNlcl9tZW1iZXJzaGlwJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdVc2VyRWR1Y2F0aW9uJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfZWR1Y2F0aW9uJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdVc2VyUHJlZmVyZW5jZSc6XG5cdFx0XHRjYXNlICdMb2dpblVzZXJQcmVmZXJlbmNlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfcHJlZmVyZW5jZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnVXNlckxhbmd1YWdlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfbGFuZ3VhZ2UnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0NvbXBhbnknOlxuXHRcdFx0Y2FzZSAnQ29tcGFuaWVzJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2NvbXBhbnknO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0dFT0ZlbmNlJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2dlb19mZW5jZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUXVhbGlmaWNhdGlvbic6XG5cdFx0XHRjYXNlICdRdWFsaWZpY2F0aW9uR3JvdXAnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncXVhbGlmaWNhdGlvbic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUGF5UGVyaW9kU2NoZWR1bGUnOlxuXHRcdFx0Y2FzZSAnUGF5UGVyaW9kcyc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdwYXlfcGVyaW9kX3NjaGVkdWxlJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQYXlTdHViQW1lbmRtZW50Jzpcblx0XHRcdGNhc2UgJ1JlY3VycmluZ1BheVN0dWJBbWVuZG1lbnQnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncGF5X3N0dWJfYW1lbmRtZW50Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQYXlTdHViVHJhbnNhY3Rpb25TdW1tYXJ5UmVwb3J0Jzpcblx0XHRcdGNhc2UgJ1BheVN0dWInOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncGF5X3N0dWInO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0JyYW5jaCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdicmFuY2gnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0RlcGFydG1lbnQnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnZGVwYXJ0bWVudCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSGllcmFyY2h5Q29udHJvbCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdoaWVyYXJjaHknO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1N0YXRpb24nOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnc3RhdGlvbic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSm9iVmFjYW5jeSc6XG5cdFx0XHRjYXNlICdQb3J0YWxKb2JWYWNhbmN5Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2pvYl92YWNhbmN5Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdQYXlTdHViRW50cnlBY2NvdW50Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3BheV9zdHViX2FjY291bnQnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1JPRSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdyb2UnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0N1c3RvbUZpZWxkJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2N1c3RvbV9maWVsZCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnQ3VycmVuY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnY3VycmVuY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1Blcm1pc3Npb25Db250cm9sJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3Blcm1pc3Npb24nO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0NvbXBhbnlUYXhEZWR1Y3Rpb24nOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnY29tcGFueV90YXhfZGVkdWN0aW9uJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdVc2VyVGF4RGVkdWN0aW9uJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfdGF4X2RlZHVjdGlvbic7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnUmVxdWVzdCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdyZXF1ZXN0Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdSZXF1ZXN0QXV0aG9yaXphdGlvbic6XG5cdFx0XHRjYXNlICdFeHBlbnNlQXV0aG9yaXphdGlvbic6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdhdXRob3JpemF0aW9uJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdEb2N1bWVudCc6XG5cdFx0XHRjYXNlICdEb2N1bWVudEdyb3VwJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2RvY3VtZW50Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdTY2hlZHVsZVBvbGljeSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdzY2hlZHVsZV9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0FjY3J1YWxQb2xpY3lBY2NvdW50Jzpcblx0XHRcdGNhc2UgJ0FjY3J1YWxQb2xpY3knOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnYWNjcnVhbF9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0NsaWVudCc6XG5cdFx0XHRjYXNlICdDbGllbnRDb250YWN0Jzpcblx0XHRcdGNhc2UgJ0ludm9pY2VEaXN0cmljdCc6XG5cdFx0XHRjYXNlICdDbGllbnRQYXltZW50Jzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2NsaWVudCc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnSW52b2ljZVRyYW5zYWN0aW9uJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3RyYW5zYWN0aW9uJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdKb2JJdGVtR3JvdXAnOlxuXHRcdFx0Y2FzZSAnSm9iSXRlbSc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdqb2JfaXRlbSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnU2F2ZWRSZXBvcnQnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncmVwb3J0Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdSZWN1cnJpbmdTY2hlZHVsZUNvbnRyb2wnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAncmVjdXJyaW5nX3NjaGVkdWxlJztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdSZWN1cnJpbmdTY2hlZHVsZVRlbXBsYXRlQ29udHJvbCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdyZWN1cnJpbmdfc2NoZWR1bGVfdGVtcGxhdGUnO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0tQSSc6XG5cdFx0XHRjYXNlICdLUElHcm91cCc6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdrcGknO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ1VzZXJSZXZpZXdDb250cm9sJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ3VzZXJfcmV2aWV3Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdFeGNlcHRpb25Qb2xpY3lDb250cm9sJzpcblx0XHRcdFx0cGVybWlzc2lvbl9zZWN0aW9uID0gJ2V4Y2VwdGlvbl9wb2xpY3knO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ0ltcG9ydENTVic6XG5cdFx0XHRcdHBlcm1pc3Npb25fc2VjdGlvbiA9ICdpbXBvcnRfY3N2Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdJbnZvaWNlJzpcblx0XHRcdGNhc2UgJ0pvYkludm9pY2UnOlxuXHRcdFx0XHRwZXJtaXNzaW9uX3NlY3Rpb24gPSAnaW52b2ljZSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblxuXHRcdHJldHVybiBwZXJtaXNzaW9uX3NlY3Rpb247XG5cdH07XG5cblx0dmFyIGdldFBlcm1pc3Npb25EYXRhID0gZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIExvY2FsQ2FjaGVEYXRhLmdldFBlcm1pc3Npb25EYXRhKCk7XG5cdH07XG5cblx0cmV0dXJuIHtcblx0XHRjaGVja1RvcExldmVsUGVybWlzc2lvbjogY2hlY2tUb3BMZXZlbFBlcm1pc3Npb24sXG5cdFx0dmFsaWRhdGU6IHZhbGlkYXRlLFxuXHRcdGdldFBlcm1pc3Npb25MZXZlbDogZ2V0UGVybWlzc2lvbkxldmVsLFxuXHRcdGdldFBlcm1pc3Npb25EYXRhOiBnZXRQZXJtaXNzaW9uRGF0YSxcblx0XHRIZWxwTWVudVZhbGlkYXRlQWRtaW46IEhlbHBNZW51VmFsaWRhdGVBZG1pbixcblx0XHRIZWxwTWVudVZhbGlkYXRlU3VwZXJ2aXNvcjogSGVscE1lbnVWYWxpZGF0ZVN1cGVydmlzb3IsXG5cdFx0aW1wb3J0VmFsaWRhdGU6IGltcG9ydFZhbGlkYXRlLFxuXHRcdHN1YkpvYkFwcGxpY2F0aW9uVmFsaWRhdGU6IHN1YkpvYkFwcGxpY2F0aW9uVmFsaWRhdGVcblx0fTtcblxufSApKCk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8843\n")},587:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"k\": () => (/* binding */ ProgressBar)\n/* harmony export */ });\n/* harmony import */ var _services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7526);\n/* harmony import */ var nanobar__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4893);\n/* harmony import */ var nanobar__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(nanobar__WEBPACK_IMPORTED_MODULE_1__);\n/* provided dependency */ var $ = __webpack_require__(9755);\n\n // need to rely on the default export via CommonJS syntax, hence no named import.\n\nvar ProgressBar = ( function() {\n\n\tvar loading_box = null;\n\t\n\tvar layout_content = null;\n\n\tvar left_offset = 0;\n\n\tvar process_number = false;\n\n\tvar can_close = false;\n\n\tvar timer = null;\n\n\tvar close_time = null;\n\n\tvar circle = null;\n\n\tvar doing_close = false;\n\n\tvar message_id_dic = {};\n\n\tvar updating_message_id = false;\n\n\tvar current_process_id = false;\n\n\tvar _progress_bar_api = false;\n\n\tvar get_progress_timer = null;\n\n\tvar first_start_get_progress_timer = false;\n\n\tvar start_progress_timer = false;\n\n\tvar auto_clear_message_id_dic = {}; //for which api calls don't have return; for example all report view calls\n\n\tvar last_iteration = null;\n\n\tvar temp_message_until_close = '';\n\n\tvar second_timer;\n\n\tvar time_offset;\n\n\tvar nanoBar;\n\n\tvar loading_bar_time;\n\n\tvar no_progress_for_next_call = false;\n\n\tvar showOverlay = function() {\n\t\tGlobal.overlay().addClass( 'overlay' );\n\t\tGlobal.setUINotready();\n\t\tTTPromise.add( 'ProgressBar', 'overlay_visible' );\n\t};\n\n\tvar closeOverlay = function() {\n\t\t//this variable is set in BaseViewController::onContextMenuClick\n\t\tif ( window.clickProcessing == true ) {\n\t\t\twindow.clickProcessing = false;\n\t\t\twindow.clearTimeout( window.clickProcessingHandle );\n\t\t}\n\t\tGlobal.overlay().removeClass( 'overlay' );\n\t\tGlobal.setUIReady();\n\t\tTTPromise.resolve( 'ProgressBar', 'overlay_visible' );\n\t};\n\n\tvar cancelProgressBar = function() {\n\t\tif ( get_progress_timer ) {\n\t\t\tclearInterval( get_progress_timer );\n\t\t\tget_progress_timer = false;\n\t\t}\n\t\tremoveProgressBar( current_process_id );\n\t\tget_progress_timer = false;\n\t\tcurrent_process_id = false;\n\t\tlast_iteration = null;\n\t\tfirst_start_get_progress_timer = false;\n\t};\n\n\tvar showProgressBar = function( message_id, auto_clear, instant ) {\n\n\t\tTTPromise.add( 'ProgressBar', 'MASTER' );\n\t\tif ( no_progress_for_next_call ) {\n\t\t\tno_progress_for_next_call = false;\n\t\t\treturn;\n\t\t}\n\t\tif ( instant ) {\n\t\t\tif ( process_number > 0 && loading_box ) {\n\t\t\t\tloading_box.css( 'display', 'block' );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( !timer ) {\n//\t\t\tclearTimeout( timer );\n\t\t\t\t//Display progress bar after 1 sec\n\t\t\t\ttimer = setTimeout( function() {\n\t\t\t\t\tif ( process_number > 0 && loading_box ) {\n\t\t\t\t\t\tloading_box.css( 'display', 'block' );\n\t\t\t\t\t}\n\n\t\t\t\t}, 1000 );\n\t\t\t}\n\t\t}\n\n\t\tif ( message_id ) {\n\t\t\tmessage_id_dic[message_id] = true;\n\n\t\t\tif ( auto_clear ) {\n\t\t\t\tauto_clear_message_id_dic[message_id] = true;\n\t\t\t}\n\n\t\t}\n\n\t\tif ( message_id && start_progress_timer === false ) {\n\t\t\tstart_progress_timer = setInterval( function() {\n\t\t\t\tgetProgressBarProcess();\n\t\t\t}, 3000 );\n\t\t\tfirst_start_get_progress_timer = true;\n\t\t}\n\n\t\tif ( process_number > 0 ) { //has multi call or the last call is not removed yet\n\t\t\tprocess_number = process_number + 1;\n\t\t\treturn;\n\t\t}\n\n\t\tprocess_number = 1;\n\n\t\tGlobal.addCss( 'global/widgets/loading_bar/LoadingBox.css' );\n\n\t\tclearTimeout( close_time );\n\t\tvar message_label;\n\n\t\tif ( !loading_box ) {\n\t\t\tvar loadingBoxWidget = `\n\t\t\t\t
\n\t\t\t\t\t
\n\t\t\t\t\tx\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t
100 / 5000 - 15% Complete
\n\t\t\t\t\t
11:11
\n\t\t\t\t
\n\t\t\t`;\n\n\t\t\tvar loadngBox = $( loadingBoxWidget ).attr( 'id', 'progressBar' );\n\n\t\t\tvar close_icon = loadngBox.find( '.close-icon' );\n\n\t\t\tclose_icon.unbind( 'click' ).click( function() {\n\t\t\t\tcancelProgressBar();\n\n\t\t\t} );\n\t\t\t// css only spinner - and yes, it does unfortunately need all those divs. They are for each of the spokes of the circle.\n\t\t\tcircle = $( '
' );\n\n\t\t\t$( 'body' ).append( loadngBox );\n\t\t\tloading_box = $( '#progressBar' );\n\t\t\tmessage_label = loading_box.find( '.processing' );\n\n\t\t\tif ( circle ) {\n\t\t\t\tmessage_label.after( circle );\n\t\t\t}\n\n\t\t\tloading_box.css( 'display', 'none' );\n\t\t\tlayout_content = document.querySelector( '.layout-content' );\n\n\t\t} else {\n\t\t\tmessage_label = loading_box.find( '.processing' );\n\n\t\t\t//If the user is logged in offset the progress bar to be centered inside the content portion of page taking into account the main left menu.\n\t\t\t//However if a wizard is displayed, the progress bar should be centered within the wizard overlay (entire page).\n\t\t\tif ( LocalCacheData.getLoginUser() && left_offset !== layout_content.offsetLeft && !document.querySelector( '.wizard-overlay' ) ) {\n\t\t\t\tleft_offset = ( layout_content.offsetLeft / 2 );\n\t\t\t\tloading_box.css( 'left', 'calc( 50% + ' + left_offset + 'px )' );\n\t\t\t} else {\n\t\t\t\tloading_box.css( 'left', '50%' );\n\t\t\t}\n\n\t\t\tif ( circle ) {\n\t\t\t\tmessage_label.after( circle );\n\t\t\t}\n\n\t\t}\n\n\t\tresetToDefault();\n\t};\n\n\tvar resetToDefault = function() {\n\n\t\tif ( temp_message_until_close ) {\n\t\t\t//Default process message, change this when update progress bar.\n\t\t\tloading_box.find( '.processing' ).text( temp_message_until_close );\n\t\t} else {\n\t\t\t//Default process message, change this when update progress bar.\n\t\t\t// Error: Unable to get property '_' of undefined or null reference in interface/html5/global/ProgressBarManager.js?v=9.0.6-20151231-155042 line 169\n\t\t\tloading_box.find( '.processing' ).text( $.i18n ? $.i18n._( 'Processing...' ) : 'Processing...' );\n\t\t}\n\n\t\tvar complete_info = loading_box.find( '.complete-info' );\n\t\tvar progress_bar = loading_box.find( '.progress-bar' );\n\t\tvar time_remaining = loading_box.find( '.time-remaining' );\n\n\t\tcomplete_info.css( 'display', 'none' );\n\t\tprogress_bar.css( 'display', 'none' );\n\t\ttime_remaining.css( 'display', 'none' );\n\n\t\tcomplete_info.text( 0 + ' / ' + 0 + ' ' + 0 + '%' );\n\t\tprogress_bar.val( 0 );\n\n\t\tlast_iteration = null;\n\n\t};\n\n\tvar changeProgressBarMessage = function( val ) {\n\t\ttemp_message_until_close = val;\n\t\tif ( loading_box ) {\n\t\t\tloading_box.find( '.processing' ).text( val );\n\t\t}\n\n\t};\n\n\tvar updateProgressbar = function( data ) {\n\n\t\tif ( !loading_box ) {\n\t\t\treturn;\n\t\t}\n\n\t\tloading_box.find( '.processing' ).text( data.message );\n\n\t\tvar percentage = data.current_iteration / data.total_iterations;\n\n\t\tvar complete_info = loading_box.find( '.complete-info' );\n\t\tvar progress_bar = loading_box.find( '.progress-bar' );\n\t\tvar time_remaining = loading_box.find( '.time-remaining' );\n\n\t\tcomplete_info.css( 'display', 'block' );\n\t\tprogress_bar.css( 'display', 'block' );\n\t\ttime_remaining.css( 'display', 'block' );\n\n\t\tcomplete_info.text( data.current_iteration + ' / ' + data.total_iterations + ' ' + ( percentage * 100 ).toFixed( 0 ) + '%' );\n\t\tprogress_bar.prop( 'value', ( percentage * 100 ) );\n\n\t\tif ( !last_iteration ) {\n\t\t\ttime_remaining.text( 'Calculating remaining time...' );\n\t\t} else {\n\n\t\t\tif ( last_iteration !== data.current_iteration || !second_timer ) {\n\n\t\t\t\ttime_offset = ( data.last_update_time - data.start_time ) * ( data.total_iterations / data.current_iteration );\n\t\t\t\ttime_offset = time_offset - ( data.last_update_time - data.start_time );\n\n\t\t\t\tif ( isNaN( time_offset ) || time_offset <= 0 ) {\n\t\t\t\t\ttime_offset = 0;\n\t\t\t\t}\n\n\t\t\t\t//Error: 'console' is undefined in /interface/html5/global/ProgressBarManager.js?v=8.0.0-20141117-153515 line 224\n\t\t\t\ttime_remaining.text( Global.getTimeUnit( time_offset, '99' ) );\n\t\t\t}\n\t\t\tsecondDown();\n\n\t\t}\n\n\t\tlast_iteration = data.current_iteration;\n\n\t};\n\n\tvar noProgressForNextCall = function() {\n\t\tno_progress_for_next_call = true;\n\t};\n\n\tvar secondDown = function() {\n\n\t\t//calculate down time every one second\n\t\tif ( !second_timer ) {\n\t\t\tvar time_remaining = loading_box.find( '.time-remaining' );\n\t\t\tsecond_timer = setInterval( function() {\n\n\t\t\t\tif ( isNaN( time_offset ) || time_offset <= 0 ) {\n\t\t\t\t\ttime_offset = 0;\n\t\t\t\t}\n\n\t\t\t\tif ( time_offset > 0 ) {\n\t\t\t\t\ttime_offset = ( time_offset - 1 );\n\t\t\t\t}\n\n\t\t\t\tif ( time_offset <= 0 ) {\n\t\t\t\t\ttime_offset = 0;\n\t\t\t\t}\n\n\t\t\t\ttime_remaining.text( Global.getTimeUnit( time_offset, '99' ) );\n\t\t\t}, 1000 );\n\t\t}\n\n\t};\n\n\tvar getProgressBarProcess = function() {\n\t\tif ( !LocalCacheData.getLoginData() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !current_process_id ) {\n\t\t\tfor ( var key in message_id_dic ) {\n\t\t\t\tcurrent_process_id = key;\n\n\t\t\t\tdelete message_id_dic[key];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif ( current_process_id && $.type( 'current_process_id' ) === 'string' ) {\n\t\t\t_services_TimeTrexClientAPI__WEBPACK_IMPORTED_MODULE_0__/* .TTAPI.APIProgressBar.getProgressBar */ .y.APIProgressBar.getProgressBar( current_process_id, {\n\t\t\t\tonResult: function( result ) {\n\t\t\t\t\tvar res_data = result.getResult();\n\n\t\t\t\t\t//Means error in progress bar\n\t\t\t\t\tif ( res_data.hasOwnProperty( 'status_id' ) && res_data.status_id === 9999 ) {\n\t\t\t\t\t\tstopProgress();\n\t\t\t\t\t\tTAlertManager.showAlert( res_data.message );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( res_data === true ||\n\t\t\t\t\t\t\t( $.type( res_data ) === 'array' && res_data.length === 0 ) || !res_data.total_iterations ||\n\t\t\t\t\t\t\t$.type( res_data.total_iterations ) !== 'number' ) {\n\t\t\t\t\t\t\tstopProgress();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tupdateProgressbar( res_data );\n\t\t\t\t\t\t\tif ( first_start_get_progress_timer ) {\n\t\t\t\t\t\t\t\tfirst_start_get_progress_timer = false;\n\n\t\t\t\t\t\t\t\t//prevent over-writing active handle. see bug #2196\n\t\t\t\t\t\t\t\tif ( start_progress_timer != false && get_progress_timer == false ) {\n\t\t\t\t\t\t\t\t\t//start interval needs to be reset to FALSE to trigger start code in showProgressBar\n\t\t\t\t\t\t\t\t\tclearInterval( start_progress_timer );\n\t\t\t\t\t\t\t\t\tstart_progress_timer = false;\n\n\t\t\t\t\t\t\t\t\tget_progress_timer = setInterval( function() {\n\t\t\t\t\t\t\t\t\t\tgetProgressBarProcess();\n\t\t\t\t\t\t\t\t\t}, 2000 );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tfunction stopProgress() {\n\t\t\tif ( start_progress_timer ) {\n\t\t\t\tclearInterval( start_progress_timer );\n\t\t\t\tstart_progress_timer = false;\n\t\t\t}\n\t\t\tif ( get_progress_timer ) {\n\t\t\t\tclearInterval( get_progress_timer );\n\t\t\t\tget_progress_timer = false;\n\t\t\t}\n\n\t\t\tif ( auto_clear_message_id_dic[current_process_id] ) {\n\t\t\t\tremoveProgressBar( current_process_id );\n\t\t\t}\n\n\t\t\tget_progress_timer = false;\n\t\t\tcurrent_process_id = false;\n\t\t\tlast_iteration = null;\n\t\t\tfirst_start_get_progress_timer = false;\n\t\t}\n\n\t};\n\n\tvar removeProgressBar = function( message_id ) {\n\t\tif ( message_id ) {\n\t\t\tdelete message_id_dic[message_id];\n\t\t\tdelete auto_clear_message_id_dic[message_id];\n\n\t\t\tif ( current_process_id === message_id ) {\n\t\t\t\tcurrent_process_id = false;\n\t\t\t}\n\n\t\t}\n\n\t\tif ( process_number > 0 ) {\n\t\t\tprocess_number = process_number - 1;\n\n\t\t\tif ( process_number === 0 ) {\n\t\t\t\tremoveProgressBar();\n\t\t\t}\n\n\t\t} else {\n\t\t\tif ( loading_box ) {\n\t\t\t\tdoing_close = true;\n\t\t\t\tclearTimeout( close_time );\n\n\t\t\t\t//shorten timeout in unit test mode.\n\t\t\t\tvar close_time_timeout = Global.UNIT_TEST_MODE ? 10 : 500;\n\t\t\t\tclose_time = setTimeout( function() {\n\t\t\t\t\tcloseOverlay();\n\n\t\t\t\t\tif ( second_timer ) {\n\t\t\t\t\t\tclearInterval( second_timer );\n\t\t\t\t\t\tsecond_timer = null;\n\t\t\t\t\t}\n\n\t\t\t\t\ttimer = null;\n\t\t\t\t\ttemp_message_until_close = '';\n\t\t\t\t\tif ( loading_box ) {\n\t\t\t\t\t\tloading_box.css( 'display', 'none' );\n\n\t\t\t\t\t\tif ( get_progress_timer ) {\n\t\t\t\t\t\t\tclearInterval( get_progress_timer );\n\t\t\t\t\t\t\tget_progress_timer = false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( start_progress_timer ) {\n\t\t\t\t\t\t\tclearInterval( start_progress_timer );\n\t\t\t\t\t\t\tstart_progress_timer = false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tTTPromise.resolve( 'ProgressBar', 'MASTER' );\n\t\t\t\t}, close_time_timeout );\n\t\t\t}\n\t\t}\n\n\t};\n\n\tvar showNanobar = function() {\n\t\tif ( !nanoBar ) {\n\t\t\tvar options = {\n\t\t\t\tbg: 'red',\n\t\t\t\tid: 'nano-bar'\n\t\t\t};\n\t\t\tnanoBar = new (nanobar__WEBPACK_IMPORTED_MODULE_1___default())( options );\n\t\t}\n\t\tvar percentage = 0;\n\t\tloading_bar_time && clearInterval( loading_bar_time );\n\t\tloading_bar_time = setInterval( function() {\n\t\t\tif ( percentage < 80 ) {\n\t\t\t\tpercentage = percentage + 20;\n\t\t\t\tnanoBar.go( percentage );\n\t\t\t} else if ( percentage === 80 ) {\n\t\t\t\tpercentage = percentage + 10;\n\t\t\t\tnanoBar.go( percentage );\n\t\t\t}\n\n\t\t}, 1000 );\n\t};\n\n\tvar removeNanobar = function() {\n\t\tloading_bar_time && clearInterval( loading_bar_time );\n\t\tnanoBar && nanoBar.go( 100 );\n\t\tcloseOverlay();\n\t};\n\n\treturn {\n\t\tshowProgressBar: showProgressBar,\n\t\tremoveProgressBar: removeProgressBar,\n\t\tshowOverlay: showOverlay,\n\t\tcloseOverlay: closeOverlay,\n\t\tmessage_id_dic: message_id_dic,\n\t\tchangeProgressBarMessage: changeProgressBarMessage,\n\t\tcancelProgressBar: cancelProgressBar,\n\t\tshowNanobar: showNanobar,\n\t\tremoveNanobar: removeNanobar,\n\t\tnoProgressForNextCall: noProgressForNextCall\n\t};\n\n} )();//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTg3LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBcUQ7QUFDdkIsQ0FBQzs7QUFFeEI7O0FBRVA7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBLHFDQUFxQyx5Q0FBeUM7O0FBRTlFOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUEsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLENBQUM7O0FBRXBCOztBQUVBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0EsWUFBWSxDQUFDOztBQUViLEdBQUcsQ0FBQztBQUNKLGlCQUFpQixDQUFDO0FBQ2xCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSwyQ0FBMkMsQ0FBQyxRQUFRLENBQUM7QUFDckQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDZCQUE2QixDQUFDO0FBQzlCLEdBQUcsbUlBQW1DO0FBQ3RDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxTQUFTLENBQUM7QUFDVixPQUFPLENBQUM7QUFDUjtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsZ0RBQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxFQUFFIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC9Qcm9ncmVzc0Jhck1hbmFnZXIuanM/MTRmMyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUVEFQSSB9IGZyb20gJ0Avc2VydmljZXMvVGltZVRyZXhDbGllbnRBUEknO1xuaW1wb3J0IE5hbm9iYXIgZnJvbSAnbmFub2Jhcic7IC8vIG5lZWQgdG8gcmVseSBvbiB0aGUgZGVmYXVsdCBleHBvcnQgdmlhIENvbW1vbkpTIHN5bnRheCwgaGVuY2Ugbm8gbmFtZWQgaW1wb3J0LlxuXG5leHBvcnQgdmFyIFByb2dyZXNzQmFyID0gKCBmdW5jdGlvbigpIHtcblxuXHR2YXIgbG9hZGluZ19ib3ggPSBudWxsO1xuXHRcblx0dmFyIGxheW91dF9jb250ZW50ID0gbnVsbDtcblxuXHR2YXIgbGVmdF9vZmZzZXQgPSAwO1xuXG5cdHZhciBwcm9jZXNzX251bWJlciA9IGZhbHNlO1xuXG5cdHZhciBjYW5fY2xvc2UgPSBmYWxzZTtcblxuXHR2YXIgdGltZXIgPSBudWxsO1xuXG5cdHZhciBjbG9zZV90aW1lID0gbnVsbDtcblxuXHR2YXIgY2lyY2xlID0gbnVsbDtcblxuXHR2YXIgZG9pbmdfY2xvc2UgPSBmYWxzZTtcblxuXHR2YXIgbWVzc2FnZV9pZF9kaWMgPSB7fTtcblxuXHR2YXIgdXBkYXRpbmdfbWVzc2FnZV9pZCA9IGZhbHNlO1xuXG5cdHZhciBjdXJyZW50X3Byb2Nlc3NfaWQgPSBmYWxzZTtcblxuXHR2YXIgX3Byb2dyZXNzX2Jhcl9hcGkgPSBmYWxzZTtcblxuXHR2YXIgZ2V0X3Byb2dyZXNzX3RpbWVyID0gbnVsbDtcblxuXHR2YXIgZmlyc3Rfc3RhcnRfZ2V0X3Byb2dyZXNzX3RpbWVyID0gZmFsc2U7XG5cblx0dmFyIHN0YXJ0X3Byb2dyZXNzX3RpbWVyID0gZmFsc2U7XG5cblx0dmFyIGF1dG9fY2xlYXJfbWVzc2FnZV9pZF9kaWMgPSB7fTsgLy9mb3Igd2hpY2ggYXBpIGNhbGxzIGRvbid0IGhhdmUgcmV0dXJuOyBmb3IgZXhhbXBsZSBhbGwgcmVwb3J0IHZpZXcgY2FsbHNcblxuXHR2YXIgbGFzdF9pdGVyYXRpb24gPSBudWxsO1xuXG5cdHZhciB0ZW1wX21lc3NhZ2VfdW50aWxfY2xvc2UgPSAnJztcblxuXHR2YXIgc2Vjb25kX3RpbWVyO1xuXG5cdHZhciB0aW1lX29mZnNldDtcblxuXHR2YXIgbmFub0JhcjtcblxuXHR2YXIgbG9hZGluZ19iYXJfdGltZTtcblxuXHR2YXIgbm9fcHJvZ3Jlc3NfZm9yX25leHRfY2FsbCA9IGZhbHNlO1xuXG5cdHZhciBzaG93T3ZlcmxheSA9IGZ1bmN0aW9uKCkge1xuXHRcdEdsb2JhbC5vdmVybGF5KCkuYWRkQ2xhc3MoICdvdmVybGF5JyApO1xuXHRcdEdsb2JhbC5zZXRVSU5vdHJlYWR5KCk7XG5cdFx0VFRQcm9taXNlLmFkZCggJ1Byb2dyZXNzQmFyJywgJ292ZXJsYXlfdmlzaWJsZScgKTtcblx0fTtcblxuXHR2YXIgY2xvc2VPdmVybGF5ID0gZnVuY3Rpb24oKSB7XG5cdFx0Ly90aGlzIHZhcmlhYmxlIGlzIHNldCBpbiBCYXNlVmlld0NvbnRyb2xsZXI6Om9uQ29udGV4dE1lbnVDbGlja1xuXHRcdGlmICggd2luZG93LmNsaWNrUHJvY2Vzc2luZyA9PSB0cnVlICkge1xuXHRcdFx0d2luZG93LmNsaWNrUHJvY2Vzc2luZyA9IGZhbHNlO1xuXHRcdFx0d2luZG93LmNsZWFyVGltZW91dCggd2luZG93LmNsaWNrUHJvY2Vzc2luZ0hhbmRsZSApO1xuXHRcdH1cblx0XHRHbG9iYWwub3ZlcmxheSgpLnJlbW92ZUNsYXNzKCAnb3ZlcmxheScgKTtcblx0XHRHbG9iYWwuc2V0VUlSZWFkeSgpO1xuXHRcdFRUUHJvbWlzZS5yZXNvbHZlKCAnUHJvZ3Jlc3NCYXInLCAnb3ZlcmxheV92aXNpYmxlJyApO1xuXHR9O1xuXG5cdHZhciBjYW5jZWxQcm9ncmVzc0JhciA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggZ2V0X3Byb2dyZXNzX3RpbWVyICkge1xuXHRcdFx0Y2xlYXJJbnRlcnZhbCggZ2V0X3Byb2dyZXNzX3RpbWVyICk7XG5cdFx0XHRnZXRfcHJvZ3Jlc3NfdGltZXIgPSBmYWxzZTtcblx0XHR9XG5cdFx0cmVtb3ZlUHJvZ3Jlc3NCYXIoIGN1cnJlbnRfcHJvY2Vzc19pZCApO1xuXHRcdGdldF9wcm9ncmVzc190aW1lciA9IGZhbHNlO1xuXHRcdGN1cnJlbnRfcHJvY2Vzc19pZCA9IGZhbHNlO1xuXHRcdGxhc3RfaXRlcmF0aW9uID0gbnVsbDtcblx0XHRmaXJzdF9zdGFydF9nZXRfcHJvZ3Jlc3NfdGltZXIgPSBmYWxzZTtcblx0fTtcblxuXHR2YXIgc2hvd1Byb2dyZXNzQmFyID0gZnVuY3Rpb24oIG1lc3NhZ2VfaWQsIGF1dG9fY2xlYXIsIGluc3RhbnQgKSB7XG5cblx0XHRUVFByb21pc2UuYWRkKCAnUHJvZ3Jlc3NCYXInLCAnTUFTVEVSJyApO1xuXHRcdGlmICggbm9fcHJvZ3Jlc3NfZm9yX25leHRfY2FsbCApIHtcblx0XHRcdG5vX3Byb2dyZXNzX2Zvcl9uZXh0X2NhbGwgPSBmYWxzZTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0aWYgKCBpbnN0YW50ICkge1xuXHRcdFx0aWYgKCBwcm9jZXNzX251bWJlciA+IDAgJiYgbG9hZGluZ19ib3ggKSB7XG5cdFx0XHRcdGxvYWRpbmdfYm94LmNzcyggJ2Rpc3BsYXknLCAnYmxvY2snICk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmICggIXRpbWVyICkge1xuLy9cdFx0XHRjbGVhclRpbWVvdXQoIHRpbWVyICk7XG5cdFx0XHRcdC8vRGlzcGxheSBwcm9ncmVzcyBiYXIgYWZ0ZXIgMSBzZWNcblx0XHRcdFx0dGltZXIgPSBzZXRUaW1lb3V0KCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRpZiAoIHByb2Nlc3NfbnVtYmVyID4gMCAmJiBsb2FkaW5nX2JveCApIHtcblx0XHRcdFx0XHRcdGxvYWRpbmdfYm94LmNzcyggJ2Rpc3BsYXknLCAnYmxvY2snICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0sIDEwMDAgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIG1lc3NhZ2VfaWQgKSB7XG5cdFx0XHRtZXNzYWdlX2lkX2RpY1ttZXNzYWdlX2lkXSA9IHRydWU7XG5cblx0XHRcdGlmICggYXV0b19jbGVhciApIHtcblx0XHRcdFx0YXV0b19jbGVhcl9tZXNzYWdlX2lkX2RpY1ttZXNzYWdlX2lkXSA9IHRydWU7XG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRpZiAoIG1lc3NhZ2VfaWQgJiYgc3RhcnRfcHJvZ3Jlc3NfdGltZXIgPT09IGZhbHNlICkge1xuXHRcdFx0c3RhcnRfcHJvZ3Jlc3NfdGltZXIgPSBzZXRJbnRlcnZhbCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGdldFByb2dyZXNzQmFyUHJvY2VzcygpO1xuXHRcdFx0fSwgMzAwMCApO1xuXHRcdFx0Zmlyc3Rfc3RhcnRfZ2V0X3Byb2dyZXNzX3RpbWVyID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAoIHByb2Nlc3NfbnVtYmVyID4gMCApIHsgLy9oYXMgbXVsdGkgY2FsbCBvciB0aGUgbGFzdCBjYWxsIGlzIG5vdCByZW1vdmVkIHlldFxuXHRcdFx0cHJvY2Vzc19udW1iZXIgPSBwcm9jZXNzX251bWJlciArIDE7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0cHJvY2Vzc19udW1iZXIgPSAxO1xuXG5cdFx0R2xvYmFsLmFkZENzcyggJ2dsb2JhbC93aWRnZXRzL2xvYWRpbmdfYmFyL0xvYWRpbmdCb3guY3NzJyApO1xuXG5cdFx0Y2xlYXJUaW1lb3V0KCBjbG9zZV90aW1lICk7XG5cdFx0dmFyIG1lc3NhZ2VfbGFiZWw7XG5cblx0XHRpZiAoICFsb2FkaW5nX2JveCApIHtcblx0XHRcdHZhciBsb2FkaW5nQm94V2lkZ2V0ID0gYFxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwicG9wdXAtbG9hZGluZ1wiPlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJwcm9jZXNzaW5nXCI+PC9kaXY+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJjbG9zZS1pY29uXCI+eDwvc3Bhbj5cblx0XHRcdFx0XHQ8cHJvZ3Jlc3MgY2xhc3M9XCJwcm9ncmVzcy1iYXJcIiBtYXg9XCIxMDBcIiB2YWx1ZT1cIjEwXCI+XG5cdFx0XHRcdFx0PC9wcm9ncmVzcz5cblx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwiY29tcGxldGUtaW5mb1wiPjEwMCAvIDUwMDAgLSAxNSUgQ29tcGxldGU8L2Rpdj5cblx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwidGltZS1yZW1haW5pbmdcIj4xMToxMTwvZGl2PlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdGA7XG5cblx0XHRcdHZhciBsb2FkbmdCb3ggPSAkKCBsb2FkaW5nQm94V2lkZ2V0ICkuYXR0ciggJ2lkJywgJ3Byb2dyZXNzQmFyJyApO1xuXG5cdFx0XHR2YXIgY2xvc2VfaWNvbiA9IGxvYWRuZ0JveC5maW5kKCAnLmNsb3NlLWljb24nICk7XG5cblx0XHRcdGNsb3NlX2ljb24udW5iaW5kKCAnY2xpY2snICkuY2xpY2soIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRjYW5jZWxQcm9ncmVzc0JhcigpO1xuXG5cdFx0XHR9ICk7XG5cdFx0XHQvLyBjc3Mgb25seSBzcGlubmVyIC0gYW5kIHllcywgaXQgZG9lcyB1bmZvcnR1bmF0ZWx5IG5lZWQgYWxsIHRob3NlIGRpdnMuIFRoZXkgYXJlIGZvciBlYWNoIG9mIHRoZSBzcG9rZXMgb2YgdGhlIGNpcmNsZS5cblx0XHRcdGNpcmNsZSA9ICQoICc8ZGl2IGNsYXNzPVwibGRzLXNwaW5uZXJcIj48ZGl2PjwvZGl2PjxkaXY+PC9kaXY+PGRpdj48L2Rpdj48ZGl2PjwvZGl2PjxkaXY+PC9kaXY+PGRpdj48L2Rpdj48ZGl2PjwvZGl2PjxkaXY+PC9kaXY+PGRpdj48L2Rpdj48ZGl2PjwvZGl2PjxkaXY+PC9kaXY+PGRpdj48L2Rpdj48L2Rpdj4nICk7XG5cblx0XHRcdCQoICdib2R5JyApLmFwcGVuZCggbG9hZG5nQm94ICk7XG5cdFx0XHRsb2FkaW5nX2JveCA9ICQoICcjcHJvZ3Jlc3NCYXInICk7XG5cdFx0XHRtZXNzYWdlX2xhYmVsID0gbG9hZGluZ19ib3guZmluZCggJy5wcm9jZXNzaW5nJyApO1xuXG5cdFx0XHRpZiAoIGNpcmNsZSApIHtcblx0XHRcdFx0bWVzc2FnZV9sYWJlbC5hZnRlciggY2lyY2xlICk7XG5cdFx0XHR9XG5cblx0XHRcdGxvYWRpbmdfYm94LmNzcyggJ2Rpc3BsYXknLCAnbm9uZScgKTtcblx0XHRcdGxheW91dF9jb250ZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvciggJy5sYXlvdXQtY29udGVudCcgKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRtZXNzYWdlX2xhYmVsID0gbG9hZGluZ19ib3guZmluZCggJy5wcm9jZXNzaW5nJyApO1xuXG5cdFx0XHQvL0lmIHRoZSB1c2VyIGlzIGxvZ2dlZCBpbiBvZmZzZXQgdGhlIHByb2dyZXNzIGJhciB0byBiZSBjZW50ZXJlZCBpbnNpZGUgdGhlIGNvbnRlbnQgcG9ydGlvbiBvZiBwYWdlIHRha2luZyBpbnRvIGFjY291bnQgdGhlIG1haW4gbGVmdCBtZW51LlxuXHRcdFx0Ly9Ib3dldmVyIGlmIGEgd2l6YXJkIGlzIGRpc3BsYXllZCwgdGhlIHByb2dyZXNzIGJhciBzaG91bGQgYmUgY2VudGVyZWQgd2l0aGluIHRoZSB3aXphcmQgb3ZlcmxheSAoZW50aXJlIHBhZ2UpLlxuXHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXIoKSAmJiBsZWZ0X29mZnNldCAhPT0gbGF5b3V0X2NvbnRlbnQub2Zmc2V0TGVmdCAmJiAhZG9jdW1lbnQucXVlcnlTZWxlY3RvciggJy53aXphcmQtb3ZlcmxheScgKSApIHtcblx0XHRcdFx0bGVmdF9vZmZzZXQgPSAoIGxheW91dF9jb250ZW50Lm9mZnNldExlZnQgLyAyICk7XG5cdFx0XHRcdGxvYWRpbmdfYm94LmNzcyggJ2xlZnQnLCAnY2FsYyggNTAlICsgJyArIGxlZnRfb2Zmc2V0ICsgJ3B4ICknICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRsb2FkaW5nX2JveC5jc3MoICdsZWZ0JywgJzUwJScgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBjaXJjbGUgKSB7XG5cdFx0XHRcdG1lc3NhZ2VfbGFiZWwuYWZ0ZXIoIGNpcmNsZSApO1xuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmVzZXRUb0RlZmF1bHQoKTtcblx0fTtcblxuXHR2YXIgcmVzZXRUb0RlZmF1bHQgPSBmdW5jdGlvbigpIHtcblxuXHRcdGlmICggdGVtcF9tZXNzYWdlX3VudGlsX2Nsb3NlICkge1xuXHRcdFx0Ly9EZWZhdWx0IHByb2Nlc3MgbWVzc2FnZSwgY2hhbmdlIHRoaXMgd2hlbiB1cGRhdGUgcHJvZ3Jlc3MgYmFyLlxuXHRcdFx0bG9hZGluZ19ib3guZmluZCggJy5wcm9jZXNzaW5nJyApLnRleHQoIHRlbXBfbWVzc2FnZV91bnRpbF9jbG9zZSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvL0RlZmF1bHQgcHJvY2VzcyBtZXNzYWdlLCBjaGFuZ2UgdGhpcyB3aGVuIHVwZGF0ZSBwcm9ncmVzcyBiYXIuXG5cdFx0XHQvLyBFcnJvcjogVW5hYmxlIHRvIGdldCBwcm9wZXJ0eSAnXycgb2YgdW5kZWZpbmVkIG9yIG51bGwgcmVmZXJlbmNlIGluIGludGVyZmFjZS9odG1sNS9nbG9iYWwvUHJvZ3Jlc3NCYXJNYW5hZ2VyLmpzP3Y9OS4wLjYtMjAxNTEyMzEtMTU1MDQyIGxpbmUgMTY5XG5cdFx0XHRsb2FkaW5nX2JveC5maW5kKCAnLnByb2Nlc3NpbmcnICkudGV4dCggJC5pMThuID8gJC5pMThuLl8oICdQcm9jZXNzaW5nLi4uJyApIDogJ1Byb2Nlc3NpbmcuLi4nICk7XG5cdFx0fVxuXG5cdFx0dmFyIGNvbXBsZXRlX2luZm8gPSBsb2FkaW5nX2JveC5maW5kKCAnLmNvbXBsZXRlLWluZm8nICk7XG5cdFx0dmFyIHByb2dyZXNzX2JhciA9IGxvYWRpbmdfYm94LmZpbmQoICcucHJvZ3Jlc3MtYmFyJyApO1xuXHRcdHZhciB0aW1lX3JlbWFpbmluZyA9IGxvYWRpbmdfYm94LmZpbmQoICcudGltZS1yZW1haW5pbmcnICk7XG5cblx0XHRjb21wbGV0ZV9pbmZvLmNzcyggJ2Rpc3BsYXknLCAnbm9uZScgKTtcblx0XHRwcm9ncmVzc19iYXIuY3NzKCAnZGlzcGxheScsICdub25lJyApO1xuXHRcdHRpbWVfcmVtYWluaW5nLmNzcyggJ2Rpc3BsYXknLCAnbm9uZScgKTtcblxuXHRcdGNvbXBsZXRlX2luZm8udGV4dCggMCArICcgLyAnICsgMCArICcgJyArIDAgKyAnJScgKTtcblx0XHRwcm9ncmVzc19iYXIudmFsKCAwICk7XG5cblx0XHRsYXN0X2l0ZXJhdGlvbiA9IG51bGw7XG5cblx0fTtcblxuXHR2YXIgY2hhbmdlUHJvZ3Jlc3NCYXJNZXNzYWdlID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHR0ZW1wX21lc3NhZ2VfdW50aWxfY2xvc2UgPSB2YWw7XG5cdFx0aWYgKCBsb2FkaW5nX2JveCApIHtcblx0XHRcdGxvYWRpbmdfYm94LmZpbmQoICcucHJvY2Vzc2luZycgKS50ZXh0KCB2YWwgKTtcblx0XHR9XG5cblx0fTtcblxuXHR2YXIgdXBkYXRlUHJvZ3Jlc3NiYXIgPSBmdW5jdGlvbiggZGF0YSApIHtcblxuXHRcdGlmICggIWxvYWRpbmdfYm94ICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGxvYWRpbmdfYm94LmZpbmQoICcucHJvY2Vzc2luZycgKS50ZXh0KCBkYXRhLm1lc3NhZ2UgKTtcblxuXHRcdHZhciBwZXJjZW50YWdlID0gZGF0YS5jdXJyZW50X2l0ZXJhdGlvbiAvIGRhdGEudG90YWxfaXRlcmF0aW9ucztcblxuXHRcdHZhciBjb21wbGV0ZV9pbmZvID0gbG9hZGluZ19ib3guZmluZCggJy5jb21wbGV0ZS1pbmZvJyApO1xuXHRcdHZhciBwcm9ncmVzc19iYXIgPSBsb2FkaW5nX2JveC5maW5kKCAnLnByb2dyZXNzLWJhcicgKTtcblx0XHR2YXIgdGltZV9yZW1haW5pbmcgPSBsb2FkaW5nX2JveC5maW5kKCAnLnRpbWUtcmVtYWluaW5nJyApO1xuXG5cdFx0Y29tcGxldGVfaW5mby5jc3MoICdkaXNwbGF5JywgJ2Jsb2NrJyApO1xuXHRcdHByb2dyZXNzX2Jhci5jc3MoICdkaXNwbGF5JywgJ2Jsb2NrJyApO1xuXHRcdHRpbWVfcmVtYWluaW5nLmNzcyggJ2Rpc3BsYXknLCAnYmxvY2snICk7XG5cblx0XHRjb21wbGV0ZV9pbmZvLnRleHQoIGRhdGEuY3VycmVudF9pdGVyYXRpb24gKyAnIC8gJyArIGRhdGEudG90YWxfaXRlcmF0aW9ucyArICcgJyArICggcGVyY2VudGFnZSAqIDEwMCApLnRvRml4ZWQoIDAgKSArICclJyApO1xuXHRcdHByb2dyZXNzX2Jhci5wcm9wKCAndmFsdWUnLCAoIHBlcmNlbnRhZ2UgKiAxMDAgKSApO1xuXG5cdFx0aWYgKCAhbGFzdF9pdGVyYXRpb24gKSB7XG5cdFx0XHR0aW1lX3JlbWFpbmluZy50ZXh0KCAnQ2FsY3VsYXRpbmcgcmVtYWluaW5nIHRpbWUuLi4nICk7XG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0aWYgKCBsYXN0X2l0ZXJhdGlvbiAhPT0gZGF0YS5jdXJyZW50X2l0ZXJhdGlvbiB8fCAhc2Vjb25kX3RpbWVyICkge1xuXG5cdFx0XHRcdHRpbWVfb2Zmc2V0ID0gKCBkYXRhLmxhc3RfdXBkYXRlX3RpbWUgLSBkYXRhLnN0YXJ0X3RpbWUgKSAqICggZGF0YS50b3RhbF9pdGVyYXRpb25zIC8gZGF0YS5jdXJyZW50X2l0ZXJhdGlvbiApO1xuXHRcdFx0XHR0aW1lX29mZnNldCA9IHRpbWVfb2Zmc2V0IC0gKCBkYXRhLmxhc3RfdXBkYXRlX3RpbWUgLSBkYXRhLnN0YXJ0X3RpbWUgKTtcblxuXHRcdFx0XHRpZiAoIGlzTmFOKCB0aW1lX29mZnNldCApIHx8IHRpbWVfb2Zmc2V0IDw9IDAgKSB7XG5cdFx0XHRcdFx0dGltZV9vZmZzZXQgPSAwO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly9FcnJvcjogJ2NvbnNvbGUnIGlzIHVuZGVmaW5lZCBpbiAvaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC9Qcm9ncmVzc0Jhck1hbmFnZXIuanM/dj04LjAuMC0yMDE0MTExNy0xNTM1MTUgbGluZSAyMjRcblx0XHRcdFx0dGltZV9yZW1haW5pbmcudGV4dCggR2xvYmFsLmdldFRpbWVVbml0KCB0aW1lX29mZnNldCwgJzk5JyApICk7XG5cdFx0XHR9XG5cdFx0XHRzZWNvbmREb3duKCk7XG5cblx0XHR9XG5cblx0XHRsYXN0X2l0ZXJhdGlvbiA9IGRhdGEuY3VycmVudF9pdGVyYXRpb247XG5cblx0fTtcblxuXHR2YXIgbm9Qcm9ncmVzc0Zvck5leHRDYWxsID0gZnVuY3Rpb24oKSB7XG5cdFx0bm9fcHJvZ3Jlc3NfZm9yX25leHRfY2FsbCA9IHRydWU7XG5cdH07XG5cblx0dmFyIHNlY29uZERvd24gPSBmdW5jdGlvbigpIHtcblxuXHRcdC8vY2FsY3VsYXRlIGRvd24gdGltZSBldmVyeSBvbmUgc2Vjb25kXG5cdFx0aWYgKCAhc2Vjb25kX3RpbWVyICkge1xuXHRcdFx0dmFyIHRpbWVfcmVtYWluaW5nID0gbG9hZGluZ19ib3guZmluZCggJy50aW1lLXJlbWFpbmluZycgKTtcblx0XHRcdHNlY29uZF90aW1lciA9IHNldEludGVydmFsKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHRpZiAoIGlzTmFOKCB0aW1lX29mZnNldCApIHx8IHRpbWVfb2Zmc2V0IDw9IDAgKSB7XG5cdFx0XHRcdFx0dGltZV9vZmZzZXQgPSAwO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCB0aW1lX29mZnNldCA+IDAgKSB7XG5cdFx0XHRcdFx0dGltZV9vZmZzZXQgPSAoIHRpbWVfb2Zmc2V0IC0gMSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCB0aW1lX29mZnNldCA8PSAwICkge1xuXHRcdFx0XHRcdHRpbWVfb2Zmc2V0ID0gMDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRpbWVfcmVtYWluaW5nLnRleHQoIEdsb2JhbC5nZXRUaW1lVW5pdCggdGltZV9vZmZzZXQsICc5OScgKSApO1xuXHRcdFx0fSwgMTAwMCApO1xuXHRcdH1cblxuXHR9O1xuXG5cdHZhciBnZXRQcm9ncmVzc0JhclByb2Nlc3MgPSBmdW5jdGlvbigpIHtcblx0XHRpZiAoICFMb2NhbENhY2hlRGF0YS5nZXRMb2dpbkRhdGEoKSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoICFjdXJyZW50X3Byb2Nlc3NfaWQgKSB7XG5cdFx0XHRmb3IgKCB2YXIga2V5IGluIG1lc3NhZ2VfaWRfZGljICkge1xuXHRcdFx0XHRjdXJyZW50X3Byb2Nlc3NfaWQgPSBrZXk7XG5cblx0XHRcdFx0ZGVsZXRlIG1lc3NhZ2VfaWRfZGljW2tleV07XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggY3VycmVudF9wcm9jZXNzX2lkICYmICQudHlwZSggJ2N1cnJlbnRfcHJvY2Vzc19pZCcgKSA9PT0gJ3N0cmluZycgKSB7XG5cdFx0XHRUVEFQSS5BUElQcm9ncmVzc0Jhci5nZXRQcm9ncmVzc0JhciggY3VycmVudF9wcm9jZXNzX2lkLCB7XG5cdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdFx0XHRcdHZhciByZXNfZGF0YSA9IHJlc3VsdC5nZXRSZXN1bHQoKTtcblxuXHRcdFx0XHRcdC8vTWVhbnMgZXJyb3IgaW4gcHJvZ3Jlc3MgYmFyXG5cdFx0XHRcdFx0aWYgKCByZXNfZGF0YS5oYXNPd25Qcm9wZXJ0eSggJ3N0YXR1c19pZCcgKSAmJiByZXNfZGF0YS5zdGF0dXNfaWQgPT09IDk5OTkgKSB7XG5cdFx0XHRcdFx0XHRzdG9wUHJvZ3Jlc3MoKTtcblx0XHRcdFx0XHRcdFRBbGVydE1hbmFnZXIuc2hvd0FsZXJ0KCByZXNfZGF0YS5tZXNzYWdlICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGlmICggcmVzX2RhdGEgPT09IHRydWUgfHxcblx0XHRcdFx0XHRcdFx0KCAkLnR5cGUoIHJlc19kYXRhICkgPT09ICdhcnJheScgJiYgcmVzX2RhdGEubGVuZ3RoID09PSAwICkgfHwgIXJlc19kYXRhLnRvdGFsX2l0ZXJhdGlvbnMgfHxcblx0XHRcdFx0XHRcdFx0JC50eXBlKCByZXNfZGF0YS50b3RhbF9pdGVyYXRpb25zICkgIT09ICdudW1iZXInICkge1xuXHRcdFx0XHRcdFx0XHRzdG9wUHJvZ3Jlc3MoKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0dXBkYXRlUHJvZ3Jlc3NiYXIoIHJlc19kYXRhICk7XG5cdFx0XHRcdFx0XHRcdGlmICggZmlyc3Rfc3RhcnRfZ2V0X3Byb2dyZXNzX3RpbWVyICkge1xuXHRcdFx0XHRcdFx0XHRcdGZpcnN0X3N0YXJ0X2dldF9wcm9ncmVzc190aW1lciA9IGZhbHNlO1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly9wcmV2ZW50IG92ZXItd3JpdGluZyBhY3RpdmUgaGFuZGxlLiBzZWUgYnVnICMyMTk2XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBzdGFydF9wcm9ncmVzc190aW1lciAhPSBmYWxzZSAmJiBnZXRfcHJvZ3Jlc3NfdGltZXIgPT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQvL3N0YXJ0IGludGVydmFsIG5lZWRzIHRvIGJlIHJlc2V0IHRvIEZBTFNFIHRvIHRyaWdnZXIgc3RhcnQgY29kZSBpbiBzaG93UHJvZ3Jlc3NCYXJcblx0XHRcdFx0XHRcdFx0XHRcdGNsZWFySW50ZXJ2YWwoIHN0YXJ0X3Byb2dyZXNzX3RpbWVyICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRzdGFydF9wcm9ncmVzc190aW1lciA9IGZhbHNlO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRnZXRfcHJvZ3Jlc3NfdGltZXIgPSBzZXRJbnRlcnZhbCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGdldFByb2dyZXNzQmFyUHJvY2VzcygpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fSwgMjAwMCApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIHN0b3BQcm9ncmVzcygpIHtcblx0XHRcdGlmICggc3RhcnRfcHJvZ3Jlc3NfdGltZXIgKSB7XG5cdFx0XHRcdGNsZWFySW50ZXJ2YWwoIHN0YXJ0X3Byb2dyZXNzX3RpbWVyICk7XG5cdFx0XHRcdHN0YXJ0X3Byb2dyZXNzX3RpbWVyID0gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGdldF9wcm9ncmVzc190aW1lciApIHtcblx0XHRcdFx0Y2xlYXJJbnRlcnZhbCggZ2V0X3Byb2dyZXNzX3RpbWVyICk7XG5cdFx0XHRcdGdldF9wcm9ncmVzc190aW1lciA9IGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGF1dG9fY2xlYXJfbWVzc2FnZV9pZF9kaWNbY3VycmVudF9wcm9jZXNzX2lkXSApIHtcblx0XHRcdFx0cmVtb3ZlUHJvZ3Jlc3NCYXIoIGN1cnJlbnRfcHJvY2Vzc19pZCApO1xuXHRcdFx0fVxuXG5cdFx0XHRnZXRfcHJvZ3Jlc3NfdGltZXIgPSBmYWxzZTtcblx0XHRcdGN1cnJlbnRfcHJvY2Vzc19pZCA9IGZhbHNlO1xuXHRcdFx0bGFzdF9pdGVyYXRpb24gPSBudWxsO1xuXHRcdFx0Zmlyc3Rfc3RhcnRfZ2V0X3Byb2dyZXNzX3RpbWVyID0gZmFsc2U7XG5cdFx0fVxuXG5cdH07XG5cblx0dmFyIHJlbW92ZVByb2dyZXNzQmFyID0gZnVuY3Rpb24oIG1lc3NhZ2VfaWQgKSB7XG5cdFx0aWYgKCBtZXNzYWdlX2lkICkge1xuXHRcdFx0ZGVsZXRlIG1lc3NhZ2VfaWRfZGljW21lc3NhZ2VfaWRdO1xuXHRcdFx0ZGVsZXRlIGF1dG9fY2xlYXJfbWVzc2FnZV9pZF9kaWNbbWVzc2FnZV9pZF07XG5cblx0XHRcdGlmICggY3VycmVudF9wcm9jZXNzX2lkID09PSBtZXNzYWdlX2lkICkge1xuXHRcdFx0XHRjdXJyZW50X3Byb2Nlc3NfaWQgPSBmYWxzZTtcblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmICggcHJvY2Vzc19udW1iZXIgPiAwICkge1xuXHRcdFx0cHJvY2Vzc19udW1iZXIgPSBwcm9jZXNzX251bWJlciAtIDE7XG5cblx0XHRcdGlmICggcHJvY2Vzc19udW1iZXIgPT09IDAgKSB7XG5cdFx0XHRcdHJlbW92ZVByb2dyZXNzQmFyKCk7XG5cdFx0XHR9XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKCBsb2FkaW5nX2JveCApIHtcblx0XHRcdFx0ZG9pbmdfY2xvc2UgPSB0cnVlO1xuXHRcdFx0XHRjbGVhclRpbWVvdXQoIGNsb3NlX3RpbWUgKTtcblxuXHRcdFx0XHQvL3Nob3J0ZW4gdGltZW91dCBpbiB1bml0IHRlc3QgbW9kZS5cblx0XHRcdFx0dmFyIGNsb3NlX3RpbWVfdGltZW91dCA9IEdsb2JhbC5VTklUX1RFU1RfTU9ERSA/IDEwIDogNTAwO1xuXHRcdFx0XHRjbG9zZV90aW1lID0gc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0Y2xvc2VPdmVybGF5KCk7XG5cblx0XHRcdFx0XHRpZiAoIHNlY29uZF90aW1lciApIHtcblx0XHRcdFx0XHRcdGNsZWFySW50ZXJ2YWwoIHNlY29uZF90aW1lciApO1xuXHRcdFx0XHRcdFx0c2Vjb25kX3RpbWVyID0gbnVsbDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR0aW1lciA9IG51bGw7XG5cdFx0XHRcdFx0dGVtcF9tZXNzYWdlX3VudGlsX2Nsb3NlID0gJyc7XG5cdFx0XHRcdFx0aWYgKCBsb2FkaW5nX2JveCApIHtcblx0XHRcdFx0XHRcdGxvYWRpbmdfYm94LmNzcyggJ2Rpc3BsYXknLCAnbm9uZScgKTtcblxuXHRcdFx0XHRcdFx0aWYgKCBnZXRfcHJvZ3Jlc3NfdGltZXIgKSB7XG5cdFx0XHRcdFx0XHRcdGNsZWFySW50ZXJ2YWwoIGdldF9wcm9ncmVzc190aW1lciApO1xuXHRcdFx0XHRcdFx0XHRnZXRfcHJvZ3Jlc3NfdGltZXIgPSBmYWxzZTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKCBzdGFydF9wcm9ncmVzc190aW1lciApIHtcblx0XHRcdFx0XHRcdFx0Y2xlYXJJbnRlcnZhbCggc3RhcnRfcHJvZ3Jlc3NfdGltZXIgKTtcblx0XHRcdFx0XHRcdFx0c3RhcnRfcHJvZ3Jlc3NfdGltZXIgPSBmYWxzZTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFRUUHJvbWlzZS5yZXNvbHZlKCAnUHJvZ3Jlc3NCYXInLCAnTUFTVEVSJyApO1xuXHRcdFx0XHR9LCBjbG9zZV90aW1lX3RpbWVvdXQgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0fTtcblxuXHR2YXIgc2hvd05hbm9iYXIgPSBmdW5jdGlvbigpIHtcblx0XHRpZiAoICFuYW5vQmFyICkge1xuXHRcdFx0dmFyIG9wdGlvbnMgPSB7XG5cdFx0XHRcdGJnOiAncmVkJyxcblx0XHRcdFx0aWQ6ICduYW5vLWJhcidcblx0XHRcdH07XG5cdFx0XHRuYW5vQmFyID0gbmV3IE5hbm9iYXIoIG9wdGlvbnMgKTtcblx0XHR9XG5cdFx0dmFyIHBlcmNlbnRhZ2UgPSAwO1xuXHRcdGxvYWRpbmdfYmFyX3RpbWUgJiYgY2xlYXJJbnRlcnZhbCggbG9hZGluZ19iYXJfdGltZSApO1xuXHRcdGxvYWRpbmdfYmFyX3RpbWUgPSBzZXRJbnRlcnZhbCggZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIHBlcmNlbnRhZ2UgPCA4MCApIHtcblx0XHRcdFx0cGVyY2VudGFnZSA9IHBlcmNlbnRhZ2UgKyAyMDtcblx0XHRcdFx0bmFub0Jhci5nbyggcGVyY2VudGFnZSApO1xuXHRcdFx0fSBlbHNlIGlmICggcGVyY2VudGFnZSA9PT0gODAgKSB7XG5cdFx0XHRcdHBlcmNlbnRhZ2UgPSBwZXJjZW50YWdlICsgMTA7XG5cdFx0XHRcdG5hbm9CYXIuZ28oIHBlcmNlbnRhZ2UgKTtcblx0XHRcdH1cblxuXHRcdH0sIDEwMDAgKTtcblx0fTtcblxuXHR2YXIgcmVtb3ZlTmFub2JhciA9IGZ1bmN0aW9uKCkge1xuXHRcdGxvYWRpbmdfYmFyX3RpbWUgJiYgY2xlYXJJbnRlcnZhbCggbG9hZGluZ19iYXJfdGltZSApO1xuXHRcdG5hbm9CYXIgJiYgbmFub0Jhci5nbyggMTAwICk7XG5cdFx0Y2xvc2VPdmVybGF5KCk7XG5cdH07XG5cblx0cmV0dXJuIHtcblx0XHRzaG93UHJvZ3Jlc3NCYXI6IHNob3dQcm9ncmVzc0Jhcixcblx0XHRyZW1vdmVQcm9ncmVzc0JhcjogcmVtb3ZlUHJvZ3Jlc3NCYXIsXG5cdFx0c2hvd092ZXJsYXk6IHNob3dPdmVybGF5LFxuXHRcdGNsb3NlT3ZlcmxheTogY2xvc2VPdmVybGF5LFxuXHRcdG1lc3NhZ2VfaWRfZGljOiBtZXNzYWdlX2lkX2RpYyxcblx0XHRjaGFuZ2VQcm9ncmVzc0Jhck1lc3NhZ2U6IGNoYW5nZVByb2dyZXNzQmFyTWVzc2FnZSxcblx0XHRjYW5jZWxQcm9ncmVzc0JhcjogY2FuY2VsUHJvZ3Jlc3NCYXIsXG5cdFx0c2hvd05hbm9iYXI6IHNob3dOYW5vYmFyLFxuXHRcdHJlbW92ZU5hbm9iYXI6IHJlbW92ZU5hbm9iYXIsXG5cdFx0bm9Qcm9ncmVzc0Zvck5leHRDYWxsOiBub1Byb2dyZXNzRm9yTmV4dENhbGxcblx0fTtcblxufSApKCk7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///587\n")},7046:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"b\": () => (/* binding */ RateLimit)\n/* harmony export */ });\n/**\n * RateLimit class\n * Based on classes/modules/core/RateLimit.class.php\n *\n * id: string to group similar calls\n * allowed_calls: integer that represents the number of calls in the time_frame\n * time_frame: integer number of seconds in which defined number of allowed_calls of specified id may be made\n *\n * Basic use case:\n *\n * RateLimit.setID( 101 ); //unique identifier for this group of calls\n * RateLimit.setAllowedCalls( 10 ); //max number of calls in time frame\n * RateLimit.setTimeFrame( 900 ); //15 minutes in seconds\n * if ( RateLimit.check() ) {\n * //do rate limited activity\n * } else {\n * //do not do rate limited activity\n * }\n *\n */\nvar RateLimit = function() {\n};\n\n//attributes\nRateLimit.memory = {};\nRateLimit.id = '';\nRateLimit.allowed_calls = 10;\nRateLimit.time_frame = 3600; //1 hr\n\nRateLimit.getID = function() {\n\treturn this.id;\n};\nRateLimit.setID = function( value ) {\n\tif ( value != '' ) {\n\t\tthis.id = value;\n\t\treturn true;\n\t}\n\treturn false;\n};\n\nRateLimit.getAllowedCalls = function() {\n\treturn this.allowed_calls;\n};\nRateLimit.setAllowedCalls = function( value ) {\n\tif ( value != '' ) {\n\t\tthis.allowed_calls = value;\n\t\treturn true;\n\t}\n\treturn false;\n};\n\nRateLimit.getTimeFrame = function() {\n\treturn this.time_frame;\n};\nRateLimit.setTimeFrame = function( value ) {\n\tif ( value != '' ) {\n\t\tthis.time_frame = value;\n\t\treturn true;\n\t}\n\treturn false;\n};\n\nRateLimit.getRateData = function() {\n\tif ( typeof ( this.memory[this.id] ) == 'undefined' ) {\n\t\treturn null;\n\t}\n\treturn this.memory[this.id];\n};\nRateLimit.setRateData = function( value ) {\n\tif ( typeof ( this.memory[this.id] ) == 'undefined' ) {\n\t\tthis.memory[this.id] = {};\n\t}\n\tif ( value != '' ) {\n\t\tthis.memory[this.id] = value;\n\t\treturn true;\n\t}\n\treturn false;\n};\n\nRateLimit.getAttempts = function() {\n\tvar rate_data = this.getRateData();\n\tif ( Global.isSet( rate_data['attempts'] ) ) {\n\t\treturn rate_data['attempts'];\n\t}\n\n\treturn false;\n};\n\n/**\n * @returns {boolean}\n */\nRateLimit.check = function() {\n\tif ( this.getID() != '' ) {\n\t\tvar rate_data = this.getRateData();\n\t\tvar new_time = ( new Date() ).getTime();\n\n\t\tif ( Global.isSet( rate_data ) == false ) {\n\t\t\trate_data = {\n\t\t\t\tfirst_date: new_time,\n\t\t\t\tattempts: 0\n\t\t\t};\n\t\t} else if ( Global.isSet( rate_data ) ) {\n\n\t\t\tvar time_frame_milliseconds = this.getTimeFrame() * 1000;\n\t\t\tif ( rate_data.attempts > this.getAllowedCalls() && rate_data.first_date >= ( new_time - time_frame_milliseconds ) ) {\n\t\t\t\tDebug.Text( 'RateLimit limiting [' + rate_data.attempts + '/' + this.getAllowedCalls() + '] in ' + ( Math.floor( ( new_time - rate_data.first_date ) / 1000 ) ) + '/' + this.getTimeFrame() + 'sec', 'RateLimit.js', 'RateLimit', 'check', 10 );\n\t\t\t\treturn false;\n\t\t\t} else if ( rate_data.first_date < new_time - time_frame_milliseconds ) {\n\t\t\t\trate_data = {\n\t\t\t\t\tfirst_date: new_time,\n\t\t\t\t\tattempts: 0\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\trate_data.attempts++;\n\t\tthis.setRateData( rate_data );\n\t}\n\treturn true;\n};\n\nRateLimit.delete = function( id ) {\n\tif ( id != null ) {\n\t\tthis.id = id;\n\t}\n\tdelete this.memory[this.id];\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzA0Ni5qcyIsIm1hcHBpbmdzIjoiOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QjtBQUM5Qix1Q0FBdUM7QUFDdkMscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCOztBQUU3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvZ2xvYmFsL1JhdGVMaW1pdC5qcz9lODAwIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUmF0ZUxpbWl0IGNsYXNzXG4gKiBCYXNlZCBvbiBjbGFzc2VzL21vZHVsZXMvY29yZS9SYXRlTGltaXQuY2xhc3MucGhwXG4gKlxuICogaWQ6IHN0cmluZyB0byBncm91cCBzaW1pbGFyIGNhbGxzXG4gKiBhbGxvd2VkX2NhbGxzOiBpbnRlZ2VyIHRoYXQgcmVwcmVzZW50cyB0aGUgbnVtYmVyIG9mIGNhbGxzIGluIHRoZSB0aW1lX2ZyYW1lXG4gKiB0aW1lX2ZyYW1lOiBpbnRlZ2VyIG51bWJlciBvZiBzZWNvbmRzIGluIHdoaWNoIGRlZmluZWQgbnVtYmVyIG9mIGFsbG93ZWRfY2FsbHMgb2Ygc3BlY2lmaWVkIGlkIG1heSBiZSBtYWRlXG4gKlxuICogQmFzaWMgdXNlIGNhc2U6XG4gKlxuICogICAgUmF0ZUxpbWl0LnNldElEKCAxMDEgKTsgLy91bmlxdWUgaWRlbnRpZmllciBmb3IgdGhpcyBncm91cCBvZiBjYWxsc1xuICogICAgUmF0ZUxpbWl0LnNldEFsbG93ZWRDYWxscyggMTAgKTsgLy9tYXggbnVtYmVyIG9mIGNhbGxzIGluIHRpbWUgZnJhbWVcbiAqICAgIFJhdGVMaW1pdC5zZXRUaW1lRnJhbWUoIDkwMCApOyAvLzE1IG1pbnV0ZXMgaW4gc2Vjb25kc1xuICogICAgaWYgKCBSYXRlTGltaXQuY2hlY2soKSApIHtcbiAqICAgICAgICAgIC8vZG8gcmF0ZSBsaW1pdGVkIGFjdGl2aXR5XG4gKiAgICB9IGVsc2Uge1xuICogICAgICAgICAgLy9kbyBub3QgZG8gcmF0ZSBsaW1pdGVkIGFjdGl2aXR5XG4gKiAgICB9XG4gKlxuICovXG5leHBvcnQgdmFyIFJhdGVMaW1pdCA9IGZ1bmN0aW9uKCkge1xufTtcblxuLy9hdHRyaWJ1dGVzXG5SYXRlTGltaXQubWVtb3J5ID0ge307XG5SYXRlTGltaXQuaWQgPSAnJztcblJhdGVMaW1pdC5hbGxvd2VkX2NhbGxzID0gMTA7XG5SYXRlTGltaXQudGltZV9mcmFtZSA9IDM2MDA7IC8vMSBoclxuXG5SYXRlTGltaXQuZ2V0SUQgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIHRoaXMuaWQ7XG59O1xuUmF0ZUxpbWl0LnNldElEID0gZnVuY3Rpb24oIHZhbHVlICkge1xuXHRpZiAoIHZhbHVlICE9ICcnICkge1xuXHRcdHRoaXMuaWQgPSB2YWx1ZTtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59O1xuXG5SYXRlTGltaXQuZ2V0QWxsb3dlZENhbGxzID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiB0aGlzLmFsbG93ZWRfY2FsbHM7XG59O1xuUmF0ZUxpbWl0LnNldEFsbG93ZWRDYWxscyA9IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0aWYgKCB2YWx1ZSAhPSAnJyApIHtcblx0XHR0aGlzLmFsbG93ZWRfY2FsbHMgPSB2YWx1ZTtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59O1xuXG5SYXRlTGltaXQuZ2V0VGltZUZyYW1lID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiB0aGlzLnRpbWVfZnJhbWU7XG59O1xuUmF0ZUxpbWl0LnNldFRpbWVGcmFtZSA9IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0aWYgKCB2YWx1ZSAhPSAnJyApIHtcblx0XHR0aGlzLnRpbWVfZnJhbWUgPSB2YWx1ZTtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59O1xuXG5SYXRlTGltaXQuZ2V0UmF0ZURhdGEgPSBmdW5jdGlvbigpIHtcblx0aWYgKCB0eXBlb2YgKCB0aGlzLm1lbW9yeVt0aGlzLmlkXSApID09ICd1bmRlZmluZWQnICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cdHJldHVybiB0aGlzLm1lbW9yeVt0aGlzLmlkXTtcbn07XG5SYXRlTGltaXQuc2V0UmF0ZURhdGEgPSBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdGlmICggdHlwZW9mICggdGhpcy5tZW1vcnlbdGhpcy5pZF0gKSA9PSAndW5kZWZpbmVkJyApIHtcblx0XHR0aGlzLm1lbW9yeVt0aGlzLmlkXSA9IHt9O1xuXHR9XG5cdGlmICggdmFsdWUgIT0gJycgKSB7XG5cdFx0dGhpcy5tZW1vcnlbdGhpcy5pZF0gPSB2YWx1ZTtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59O1xuXG5SYXRlTGltaXQuZ2V0QXR0ZW1wdHMgPSBmdW5jdGlvbigpIHtcblx0dmFyIHJhdGVfZGF0YSA9IHRoaXMuZ2V0UmF0ZURhdGEoKTtcblx0aWYgKCBHbG9iYWwuaXNTZXQoIHJhdGVfZGF0YVsnYXR0ZW1wdHMnXSApICkge1xuXHRcdHJldHVybiByYXRlX2RhdGFbJ2F0dGVtcHRzJ107XG5cdH1cblxuXHRyZXR1cm4gZmFsc2U7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5SYXRlTGltaXQuY2hlY2sgPSBmdW5jdGlvbigpIHtcblx0aWYgKCB0aGlzLmdldElEKCkgIT0gJycgKSB7XG5cdFx0dmFyIHJhdGVfZGF0YSA9IHRoaXMuZ2V0UmF0ZURhdGEoKTtcblx0XHR2YXIgbmV3X3RpbWUgPSAoIG5ldyBEYXRlKCkgKS5nZXRUaW1lKCk7XG5cblx0XHRpZiAoIEdsb2JhbC5pc1NldCggcmF0ZV9kYXRhICkgPT0gZmFsc2UgKSB7XG5cdFx0XHRyYXRlX2RhdGEgPSB7XG5cdFx0XHRcdGZpcnN0X2RhdGU6IG5ld190aW1lLFxuXHRcdFx0XHRhdHRlbXB0czogMFxuXHRcdFx0fTtcblx0XHR9IGVsc2UgaWYgKCBHbG9iYWwuaXNTZXQoIHJhdGVfZGF0YSApICkge1xuXG5cdFx0XHR2YXIgdGltZV9mcmFtZV9taWxsaXNlY29uZHMgPSB0aGlzLmdldFRpbWVGcmFtZSgpICogMTAwMDtcblx0XHRcdGlmICggcmF0ZV9kYXRhLmF0dGVtcHRzID4gdGhpcy5nZXRBbGxvd2VkQ2FsbHMoKSAmJiByYXRlX2RhdGEuZmlyc3RfZGF0ZSA+PSAoIG5ld190aW1lIC0gdGltZV9mcmFtZV9taWxsaXNlY29uZHMgKSApIHtcblx0XHRcdFx0RGVidWcuVGV4dCggJ1JhdGVMaW1pdCBsaW1pdGluZyBbJyArIHJhdGVfZGF0YS5hdHRlbXB0cyArICcvJyArIHRoaXMuZ2V0QWxsb3dlZENhbGxzKCkgKyAnXSBpbiAnICsgKCBNYXRoLmZsb29yKCAoIG5ld190aW1lIC0gcmF0ZV9kYXRhLmZpcnN0X2RhdGUgKSAvIDEwMDAgKSApICsgJy8nICsgdGhpcy5nZXRUaW1lRnJhbWUoKSArICdzZWMnLCAnUmF0ZUxpbWl0LmpzJywgJ1JhdGVMaW1pdCcsICdjaGVjaycsIDEwICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH0gZWxzZSBpZiAoIHJhdGVfZGF0YS5maXJzdF9kYXRlIDwgbmV3X3RpbWUgLSB0aW1lX2ZyYW1lX21pbGxpc2Vjb25kcyApIHtcblx0XHRcdFx0cmF0ZV9kYXRhID0ge1xuXHRcdFx0XHRcdGZpcnN0X2RhdGU6IG5ld190aW1lLFxuXHRcdFx0XHRcdGF0dGVtcHRzOiAwXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmF0ZV9kYXRhLmF0dGVtcHRzKys7XG5cdFx0dGhpcy5zZXRSYXRlRGF0YSggcmF0ZV9kYXRhICk7XG5cdH1cblx0cmV0dXJuIHRydWU7XG59O1xuXG5SYXRlTGltaXQuZGVsZXRlID0gZnVuY3Rpb24oIGlkICkge1xuXHRpZiAoIGlkICE9IG51bGwgKSB7XG5cdFx0dGhpcy5pZCA9IGlkO1xuXHR9XG5cdGRlbGV0ZSB0aGlzLm1lbW9yeVt0aGlzLmlkXTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///7046\n")},9239:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"K\": () => (/* binding */ TAlertManager)\n/* harmony export */ });\n/* provided dependency */ var $ = __webpack_require__(9755);\nvar TAlertManager = ( function() {\n\n\tvar view = null;\n\n\tvar isShownNetworkAlert = false;\n\n\tvar closeBrowserBanner = function() {\n\t\t$( '.browser-banner' ).remove();\n\t};\n\n\tvar showBrowserTopBanner = function() {\n\t\t// if ( ie && ie <= 11 ) {\n\t\t// \tvar div = $( '' );\n\t\t// \t$( 'body' ).append( div );\n\t\t// }\n\t};\n\n\tvar showNetworkErrorAlert = function( jqXHR, textStatus, errorThrown ) {\n\t\t//#2514 - status 0 is caused by browser cancelling the request. There is no status because there was no request.\n\t\tif ( jqXHR.status == 0 ) {\n\t\t\tif ( APIGlobal.pre_login_data.production !== true ) {\n\t\t\t\tconsole.error( 'Browser cancelled request... jqXHR: Status=0' );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif ( textStatus == 'parsererror' ) {\n\t\t\tGlobal.sendErrorReport( textStatus + ' (' + jqXHR.status + '): \"' + errorThrown + '\" FROM TAlertManager::showNetworkErrorAlert():\\n\\n' + ( jqXHR.responseText ? jqXHR.responseText : 'N/A' ), false, false, jqXHR );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !isShownNetworkAlert ) {\n\t\t\tTAlertManager.showAlert( Global.network_lost_msg + '

' + 'Error: ' + textStatus + ' (' + jqXHR.status + '):
\"' + errorThrown + '\"' + '

' + ( jqXHR.responseText ? jqXHR.responseText : 'N/A' ) + ' (' + jqXHR.status + ')', 'Error', function() {\n\t\t\t\tisShownNetworkAlert = false;\n\t\t\t} );\n\t\t\tisShownNetworkAlert = true;\n\t\t\tGlobal.sendAnalyticsEvent( 'alert-manager', 'error:network', 'network-error: jqXHR-status: ' + jqXHR.status + ' Error: ' + textStatus );\n\t\t}\n\t};\n\n\tvar showPreSessionAlert = function() {\n\t\tvar result = $( '
' +\n\t\t\t'X' +\n\t\t\t'' +\n\t\t\t'
' );\n\t\tsetTimeout( function() {\n\t\t\t$( 'body' ).append( result );\n\t\t\tresult.find( '.content' ).html( $.i18n._( 'Previous Session' ) );\n\t\t\tvar button = result.find( '.close-icon' );\n\t\t\tbutton.bind( 'click', function() {\n\t\t\t\tremovePreSession();\n\t\t\t} );\n\t\t\tresult.bind( 'click', function() {\n\t\t\t\tbackToPreSession();\n\t\t\t} );\n\t\t}, 100 );\n\n\t\tfunction removePreSession() {\n\t\t\tresult.remove();\n\t\t\tresult = null;\n\n\t\t\tdeleteCookie( 'AlternateSessionData', LocalCacheData.cookie_path, Global.getHost() );\n\t\t}\n\n\t\tfunction backToPreSession() {\n\t\t\tvar host = Global.getHost();\n\t\t\ttry { //Prevent JS exception if we can't parse alternate_session_data for some reason.\n\t\t\t\tvar alternate_session_data = JSON.parse( getCookie( 'AlternateSessionData' ) );\n\t\t\t\tif ( !alternate_session_data ) {\n\t\t\t\t\tDebug.Text( 'No alternate_session_data exists.', 'TAlertManager.js', 'TAlertManager', 'backToPreSession', 10 );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} catch ( e ) {\n\t\t\t\tDebug.Text( e.message, 'TAlertManager.js', 'showPreSessionAlert', 'backToPreSession', 10 );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar url = alternate_session_data.previous_session_url;\n\t\t\tvar previous_cookie_path = alternate_session_data.previous_cookie_path;\n\n\t\t\talternate_session_data = {\n\t\t\t\tnew_session_id: alternate_session_data.previous_session_id,\n\t\t\t\tprevious_session_view: alternate_session_data.previous_session_view\n\t\t\t};\n\n\t\t\tsetCookie( 'AlternateSessionData', JSON.stringify( alternate_session_data ), 1, previous_cookie_path, host );\n\n\t\t\tGlobal.setURLToBrowser( url + '#!m=Login' );\n\t\t\tGlobal.needReloadBrowser = true;\n\n\t\t\tresult.remove();\n\t\t\tresult = null;\n\t\t}\n\t};\n\n\tvar showErrorAlert = function( result ) {\n\t\tvar details = result.getDetails();\n\n\t\tif ( details.hasOwnProperty( 'error' ) ) {\n\n\t\t}\n\t\tif ( !details ) {\n\t\t\tdetails = result.getDescription(); // If the details is empty, try to get description to show.\n\t\t}\n\t\tvar error_string = '';\n\n\t\tif ( Global.isArray( details ) || typeof details === 'object' ) {\n\t\t\terror_string = Global.convertValidationErrorToString( details );\n\t\t} else {\n\n\t\t\terror_string = details;\n\t\t}\n\n\t\tshowAlert( error_string, 'Error' );\n\n\t};\n\n\tvar showWarningAlert = function( result, callBack ) {\n\t\tvar details = result.getDetails();\n\t\tvar ul_container = $( '
    ' );\n\t\tif ( Global.isArray( details ) || typeof details === 'object' ) {\n\t\t\t$.each( details, function( index, val ) {\n\t\t\t\tif ( val.hasOwnProperty( 'warning' ) ) {\n\t\t\t\t\tval = val.warning;\n\t\t\t\t}\n\t\t\t\tfor ( var key in val ) {\n\t\t\t\t\tvar li = $( '
  1. ' );\n\t\t\t\t\tvar child_val = val[key];\n\t\t\t\t\tvar has_child = false;\n\t\t\t\t\tfor ( var child_key in child_val ) {\n\t\t\t\t\t\tif ( child_val.hasOwnProperty( child_key ) ) {\n\t\t\t\t\t\t\thas_child = true;\n\t\t\t\t\t\t\tli = $( '
  2. ' );\n\t\t\t\t\t\t\tli.append( child_val[child_key] );\n\t\t\t\t\t\t\tul_container.append( li );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( !has_child ) {\n\t\t\t\t\t\tli.append( val[key] );\n\t\t\t\t\t\tul_container.append( li );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t\tvar div = $( '
    ' );\n\t\tvar p = $( '

    ' );\n\t\tp.append( $.i18n._( 'Are you sure you wish to save this record without correcting the above warnings?' ) );\n\t\tdiv.append( ul_container );\n\t\tdiv.append( p );\n\t\tshowConfirmAlert( div[0], 'Warning', callBack, 'Save', 'Cancel' );\n\t};\n\n\tvar showAlert = function( content, title, callBack ) {\n\t\tif ( !title ) {\n\t\t\ttitle = $.i18n._( 'Message' );\n\t\t}\n\n\t\tvar result = $( '

    ' +\n\t\t\t'
    ' +\n\t\t\t'' +\n\t\t\t'
    ' +\n\t\t\t'' +\n\t\t\t'
    ' +\n\t\t\t'
    ' );\n\t\tsetTimeout( function() {\n\t\t\tif ( view !== null ) {\n\n\t\t\t\tvar cContent = view.find( '.content' ).text();\n\n\t\t\t\tif ( cContent === content ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tremove();\n\n\t\t\t}\n\t\t\tview = result;\n\t\t\t$( 'body' ).append( result );\n\t\t\tresult.find( '.title' ).text( title );\n\t\t\tresult.find( '.content' ).html( content );\n\t\t\tvar button = result.find( '.t-button' );\n\t\t\tbutton.bind( 'click', function() {\n\t\t\t\tremove();\n\t\t\t\tif ( callBack ) {\n\t\t\t\t\tcallBack();\n\t\t\t\t}\n\t\t\t} );\n\t\t\tbutton.focus();\n\t\t\tbutton.bind( 'keydown', function( e ) {\n\t\t\t\te.stopPropagation();\n\t\t\t\tif ( e.keyCode === 13 ) {\n\t\t\t\t\tremove();\n\t\t\t\t\tif ( callBack ) {\n\t\t\t\t\t\tcallBack();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tGlobal.setUIInitComplete();\n\t\t}, 100 );\n\n\t};\n\n\tvar showConfirmAlert = function( content, title, callBackFunction, yesLabel, noLabel ) {\n\n\t\tif ( !Global.isSet( title ) ) {\n\t\t\ttitle = $.i18n._( 'Message' );\n\t\t}\n\n\t\tif ( !Global.isSet( yesLabel ) ) {\n\t\t\tyesLabel = $.i18n._( 'Yes' );\n\t\t}\n\n\t\tif ( !Global.isSet( noLabel ) ) {\n\t\t\tnoLabel = $.i18n._( 'No' );\n\t\t}\n\n\t\tif ( view !== null ) {\n\n\t\t\tvar cContent = view.find( '.content' ).text();\n\n\t\t\tif ( cContent === content ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tremove();\n\t\t}\n\t\tvar result = $( '
    ' +\n\t\t\t'
    ' +\n\t\t\t'' +\n\t\t\t'
    ' +\n\t\t\t'' +\n\t\t\t'' +\n\t\t\t'
    ' +\n\t\t\t'
    ' );\n\t\tview = result;\n\t\t$( 'body' ).append( result );\n\n\t\tresult.find( '#yesBtn' ).text( yesLabel );\n\t\tresult.find( '#noBtn' ).text( noLabel );\n\t\tresult.find( '.title' ).text( title );\n\n\t\tresult.find( '.content' ).html( content );\n\n\t\tresult.find( '#yesBtn' ).bind( 'click', function() {\n\t\t\tremove();\n\t\t\tcallBackFunction( true );\n\n\t\t} );\n\n\t\tresult.find( '#noBtn' ).bind( 'click', function() {\n\t\t\tremove();\n\t\t\tcallBackFunction( false );\n\n\t\t} );\n\n\t\tGlobal.setUIInitComplete();\n\t};\n\n\tvar showFlexAlert = function( title, content, form_type, form_data, callBackFunction, width, continue_label, cancel_label ) {\n\t\tGlobal.setUINotready();\n\n\t\tvar show_continue_button = true;\n\t\tvar show_cancel_button = true;\n\n\t\tif ( !continue_label ) {\n\t\t\tcontinue_label = $.i18n._( 'Continue' );\n\t\t}\n\n\t\tif ( !cancel_label ) {\n\t\t\tcancel_label = $.i18n._( 'Cancel' );\n\t\t}\n\n\t\tvar result = $( '
    ' +\n\t\t\t'
    ' +\n\t\t\t'' +\n\t\t\t'
    ' +\n\t\t\t'
    ' +\n\t\t\t'' +\n\t\t\t'' +\n\t\t\t'
    ' +\n\t\t\t'
    ' )\n\n\t\tif ( width ) {\n\t\t\tresult.css( 'width', width );\n\t\t}\n\n\t\tview = result;\n\t\t$( 'body' ).append( result );\n\n\t\tif ( form_type === 'dropdown' ) {\n\t\t\tvar form_item_input = Global.loadWidgetByName( FormItemType.COMBO_BOX );\n\t\t\tform_item_input.TComboBox();\n\t\t\tform_item_input.setSourceData( form_data );\n\n\t\t\tresult.find( '#yesBtn' ).bind( 'click', function() {\n\t\t\t\tremove();\n\t\t\t\tcallBackFunction( result.find( 'select' ).val() );\n\t\t\t} );\n\t\t} else if ( form_type === 'password' ) {\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.PASSWORD_INPUT );\n\t\t\tform_item_input.TPasswordInput();\n\n\t\t\tresult.find( '#yesBtn' ).bind( 'click', function() {\n\t\t\t\tremove();\n\t\t\t\tcallBackFunction( result.find( '[type=password]' ).val() );\n\t\t\t} );\n\t\t} else if ( form_type === 'text' ) {\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tform_item_input.TTextInput();\n\t\t\tform_item_input.setValue( form_data );\n\n\t\t\tif ( width ) {\n\t\t\t\tform_item_input.width( ( width - 20 ) );\n\t\t\t}\n\n\t\t\tshow_cancel_button = false;\n\n\t\t\tresult.find( '#yesBtn' ).bind( 'click', function() {\n\t\t\t\tremove();\n\t\t\t} );\n\t\t} else if ( form_type === 'word_match' ) {\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tform_item_input.TTextInput();\n\n\t\t\tresult.find( '#yesBtn' ).bind( 'click', function() {\n\t\t\t\tif ( result.find( '[type=text]' ).val() === form_data ) {\n\t\t\t\t\tremove();\n\t\t\t\t\tcallBackFunction( true );\n\t\t\t\t} else {\n\t\t\t\t\tcallBackFunction( false );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tresult.find( '#form-holder' ).append( form_item_input );\n\n\t\tresult.find( '#noBtn' ).bind( 'click', function() {\n\t\t\tremove();\n\t\t\tcallBackFunction( false );\n\t\t} );\n\n\t\tresult.find( '#yesBtn' ).text( continue_label );\n\t\tresult.find( '#noBtn' ).text( cancel_label );\n\n\t\tresult.find( '.title' ).text( title );\n\t\tresult.find( '.content' ).html( content );\n\n\t\tif ( show_continue_button == false ) {\n\t\t\tresult.find( '#yesBtn' ).hide();\n\t\t}\n\n\t\tif ( show_cancel_button == false ) {\n\t\t\tresult.find( '#noBtn' ).hide();\n\t\t}\n\n\t\tGlobal.setUIInitComplete();\n\t};\n\n\n\tvar showModalAlert = function( category, step, callBackFunction, img_src ) {\n\t\tlet top_image = '';\n\t\tlet title = '';\n\t\tlet content = '';\n\t\tlet additional_body_style = '';\n\t\tlet button_label = $.i18n._( 'Yes' );\n\t\tlet button_color = '#228b22';\n\n\t\tif ( category === 'push_notification' ) {\n\t\t\ttop_image = '';\n\t\t\ttitle = $.i18n._( 'Turn on Notifications' );\n\n\t\t\tswitch ( step ) {\n\t\t\t\tcase 'ask':\n\t\t\t\t\tbutton_label = $.i18n._( 'Yes, turn on notifications!' );\n\t\t\t\t\tcontent = LocalCacheData.getCurrentCompany().name + ' ' + $.i18n._( 'wants permission to notify you of important messages or alerts related to your employment. You can change your notification settings at anytime.' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'wait_for_permission':\n\t\t\t\t\tbutton_label = $.i18n._( 'I don\\'t see it?' );\n\t\t\t\t\tbutton_color = '#AE0000';\n\t\t\t\t\t// Some browsers by default block push notification permission we need to detect them to show user a different prompt.\n\t\t\t\t\tif ( NotificationConsumer.detectBrowserNeedsExtraPermission() === true || Notification.permission === 'denied' ) {\n\t\t\t\t\t\t// User needs to enable push notifications on the browser.\n\t\t\t\t\t\tcontent = $.i18n._( 'A popup should appear on your screen, click \"ALLOW\" to enable notifications. If you don\\'t see it, you may need to enable notifications in your browser settings.' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontent = $.i18n._( 'A popup should appear on your screen, click \"ALLOW\" to enable notifications.' );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'help_text':\n\t\t\t\t\tbutton_label = $.i18n._( 'Ok, done!' );\n\t\t\t\t\tif ( Global.getBrowserVendor() === 'Edge' ) {\n\t\t\t\t\t\tcontent = $.i18n._( '1. Click the icon to the left of the address (URL) bar to view settings.
    ' +\n\t\t\t\t\t\t\t'2. Click \"Permissions for this Site\"
    ' +\n\t\t\t\t\t\t\t'3. To the right of \"Notifications\" set the option to \"ALLOW\".' );\n\t\t\t\t\t} else if ( Global.getBrowserVendor() === 'Firefox' ) {\n\t\t\t\t\t\tcontent = $.i18n._( '1. Click the icon to the left of the address (URL) bar to view settings.
    ' +\n\t\t\t\t\t\t\t'2. Click the \"X\" next Notifications to remove blocked permissions and then refresh the browser.
    ' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontent = $.i18n._( '1. Click the icon to the left of the address (URL) bar to view settings.
    ' +\n\t\t\t\t\t\t\t'2. Click \"Site settings\"
    ' +\n\t\t\t\t\t\t\t'3. To the right of \"Notifications\" set the option to \"ALLOW\".' );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else if ( category === 'multifactor_authentication' ) {\n\t\t\ttitle = $.i18n._( 'Multifactor Authentication Instructions' );\n\n\t\t\tswitch ( step ) {\n\t\t\t\tcase 'download_instructions':\n\t\t\t\t\tbutton_label = $.i18n._( 'Ok' );\n\t\t\t\t\tbutton_color = '#426d9d';\n\t\t\t\t\tadditional_body_style = 'style=\"display: block; padding-left: 2rem; padding-right: 2rem; font-size: 1.1rem;\"';\n\n\t\t\t\t\tcontent = '
    ';\n\t\t\t\t\tcontent += '1.' + $.i18n._( 'Please download the TimeTrex app from the App Store on your device.' ) + '

    ';\n\t\t\t\t\tcontent += '2.' + $.i18n._( ' Once installed, on the first step of the \"Setup Wizard\", tap the \"QR Code\" icon at the bottom right to scan the below QR Code.' ) + '
    ';\n\t\t\t\t\tcontent += '';\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tGlobal.setUINotready();\n\n\t\tvar result = $( '
    ' +\n\t\t\t'
    ' +\n\t\t\t'×' +\n\t\t\ttop_image +\n\t\t\t'

    ' +\n\t\t\t'
    ' +\n\t\t\t'' +\n\t\t\t'
    ' +\n\t\t\t'
    ' );\n\t\tview = result;\n\t\t$( 'body' ).append( result );\n\n\t\tresult.find( '.permission-button-yes' ).text( button_label );\n\t\tresult.find( '.modal-alert-title' ).text( title );\n\n\t\tresult.find( '.modal-alert-body' ).html( content );\n\n\t\tresult.find( '.permission-button-yes' ).bind( 'click', function() {\n\t\t\tremove();\n\t\t\tif ( callBackFunction ) {\n\t\t\t\tcallBackFunction( true );\n\t\t\t}\n\t\t\tGlobal.setUIReady();\n\t\t} );\n\n\t\tresult.find( '.modal-alert-close' ).bind( 'click', function() {\n\t\t\tremove();\n\t\t\tif ( callBackFunction ) {\n\t\t\t\tcallBackFunction( false );\n\t\t\t}\n\t\t\tGlobal.setUIReady();\n\t\t} );\n\n\t\tGlobal.setUIInitComplete();\n\t};\n\n\tvar remove = function() {\n\n\t\tif ( view ) {\n\t\t\tview.remove();\n\t\t\tview = null;\n\t\t}\n\n\t};\n\n\treturn {\n\t\tshowBrowserTopBanner: showBrowserTopBanner,\n\t\tcloseBrowserBanner: closeBrowserBanner,\n\t\tshowConfirmAlert: showConfirmAlert,\n\t\tshowModalAlert: showModalAlert,\n\t\tshowAlert: showAlert,\n\t\tshowErrorAlert: showErrorAlert,\n\t\tshowPreSessionAlert: showPreSessionAlert,\n\t\tshowFlexAlert: showFlexAlert,\n\t\tshowWarningAlert: showWarningAlert,\n\t\tshowNetworkErrorAlert: showNetworkErrorAlert\n\t};\n\n} )();\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTIzOS5qcyIsIm1hcHBpbmdzIjoiOzs7O0FBQU87O0FBRVA7O0FBRUE7O0FBRUE7QUFDQSxFQUFFLENBQUM7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxlQUFlLENBQUM7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLENBQUM7QUFDSixtQ0FBbUMsQ0FBQztBQUNwQztBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHNDQUFzQztBQUN0QztBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHFCQUFxQixDQUFDO0FBQ3RCO0FBQ0EsR0FBRyxDQUFDO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLENBQUM7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxDQUFDO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsWUFBWSxDQUFDO0FBQ2IsVUFBVSxDQUFDO0FBQ1gsWUFBWSxDQUFDO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsQ0FBQztBQUNaOztBQUVBLGVBQWUsQ0FBQztBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRyxDQUFDO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0EsR0FBRzs7QUFFSDs7QUFFQTs7QUFFQTtBQUNBLFdBQVcsQ0FBQztBQUNaOztBQUVBO0FBQ0EsY0FBYyxDQUFDO0FBQ2Y7O0FBRUE7QUFDQSxhQUFhLENBQUM7QUFDZDs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGVBQWUsQ0FBQztBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRSxDQUFDOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7O0FBRUEsSUFBSTs7QUFFSjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLG9CQUFvQixDQUFDO0FBQ3JCOztBQUVBO0FBQ0Esa0JBQWtCLENBQUM7QUFDbkI7O0FBRUEsZUFBZSxDQUFDO0FBQ2hCO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFLENBQUM7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLENBQUM7QUFDdEI7O0FBRUE7QUFDQTtBQUNBLFdBQVcsQ0FBQzs7QUFFWjtBQUNBO0FBQ0Esb0JBQW9CLENBQUM7QUFDckIsK0RBQStELENBQUM7QUFDaEU7QUFDQTtBQUNBLG9CQUFvQixDQUFDO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLENBQUM7QUFDakIsT0FBTztBQUNQLGdCQUFnQixDQUFDO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixDQUFDO0FBQ3JCO0FBQ0EsZ0JBQWdCLENBQUM7QUFDakI7QUFDQTtBQUNBLE9BQU87QUFDUCxnQkFBZ0IsQ0FBQztBQUNqQjtBQUNBLE9BQU87QUFDUCxnQkFBZ0IsQ0FBQztBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLFdBQVcsQ0FBQzs7QUFFWjtBQUNBO0FBQ0Esb0JBQW9CLENBQUM7QUFDckI7QUFDQSxxREFBcUQsb0JBQW9CLHFCQUFxQixrQkFBa0I7O0FBRWhIO0FBQ0EsdUJBQXVCLENBQUM7QUFDeEIsdUJBQXVCLENBQUM7QUFDeEIseUVBQXlFO0FBQ3pFO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxlQUFlLENBQUM7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRSxDQUFDOztBQUVIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEVBQUUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvZ2xvYmFsL1RBbGVydE1hbmFnZXIuanM/ZWI1NSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdmFyIFRBbGVydE1hbmFnZXIgPSAoIGZ1bmN0aW9uKCkge1xuXG5cdHZhciB2aWV3ID0gbnVsbDtcblxuXHR2YXIgaXNTaG93bk5ldHdvcmtBbGVydCA9IGZhbHNlO1xuXG5cdHZhciBjbG9zZUJyb3dzZXJCYW5uZXIgPSBmdW5jdGlvbigpIHtcblx0XHQkKCAnLmJyb3dzZXItYmFubmVyJyApLnJlbW92ZSgpO1xuXHR9O1xuXG5cdHZhciBzaG93QnJvd3NlclRvcEJhbm5lciA9IGZ1bmN0aW9uKCkge1xuXHRcdC8vIGlmICggaWUgJiYgaWUgPD0gMTEgKSB7XG5cdFx0Ly8gXHR2YXIgZGl2ID0gJCggJzxkaXYgY2xhc3M9XCJicm93c2VyLWJhbm5lclwiPjxhIGhyZWY9XCJodHRwczovL3d3dy50aW1ldHJleC5jb20vc3VwcG9ydGVkLXdlYi1icm93c2Vyc1wiIHRhcmdldD1cIl9ibGFua1wiPjxzcGFuIGlkPVwiYnJvd3Nlci10b3AtYmFubmVyXCIgY2xhc3M9XCJsYWJlbFwiPjxzdHJvbmc+V0FSTklORzwvc3Ryb25nPjogJyArIExvY2FsQ2FjaGVEYXRhLmdldExvZ2luRGF0YSgpLmFwcGxpY2F0aW9uX25hbWUgKyAnIHdpbGwgbm8gbG9uZ2VyIHN1cHBvcnQgPHN0cm9uZz5JbnRlcm5ldCBFeHBsb3JlciAxMTwvc3Ryb25nPiBlZmZlY3RpdmUgPHN0cm9uZz5KYW51YXJ5IDE0dGgsIDIwMjA8L3N0cm9uZz4uPGJyPjxzdHJvbmc+UGxlYXNlIHVwZ3JhZGUgdG8gTWljcm9zb2Z0IEVkZ2UsIENocm9tZSBvciBGaXJlRm94IGltbWVkaWF0ZWx5IHRvIGNvbnRpbnVlIHVzaW5nIFRpbWVUcmV4Ljwvc3Ryb25nPjwvc3Bhbj48L2E+PC9kaXY+JyApO1xuXHRcdC8vIFx0JCggJ2JvZHknICkuYXBwZW5kKCBkaXYgKTtcblx0XHQvLyB9XG5cdH07XG5cblx0dmFyIHNob3dOZXR3b3JrRXJyb3JBbGVydCA9IGZ1bmN0aW9uKCBqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24gKSB7XG5cdFx0Ly8jMjUxNCAtIHN0YXR1cyAwIGlzIGNhdXNlZCBieSBicm93c2VyIGNhbmNlbGxpbmcgdGhlIHJlcXVlc3QuIFRoZXJlIGlzIG5vIHN0YXR1cyBiZWNhdXNlIHRoZXJlIHdhcyBubyByZXF1ZXN0LlxuXHRcdGlmICgganFYSFIuc3RhdHVzID09IDAgKSB7XG5cdFx0XHRpZiAoIEFQSUdsb2JhbC5wcmVfbG9naW5fZGF0YS5wcm9kdWN0aW9uICE9PSB0cnVlICkge1xuXHRcdFx0XHRjb25zb2xlLmVycm9yKCAnQnJvd3NlciBjYW5jZWxsZWQgcmVxdWVzdC4uLiBqcVhIUjogU3RhdHVzPTAnICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCB0ZXh0U3RhdHVzID09ICdwYXJzZXJlcnJvcicgKSB7XG5cdFx0XHRHbG9iYWwuc2VuZEVycm9yUmVwb3J0KCB0ZXh0U3RhdHVzICsgJyAoJyArIGpxWEhSLnN0YXR1cyArICcpOiBcIicgKyBlcnJvclRocm93biArICdcIiBGUk9NIFRBbGVydE1hbmFnZXI6OnNob3dOZXR3b3JrRXJyb3JBbGVydCgpOlxcblxcbicgKyAoIGpxWEhSLnJlc3BvbnNlVGV4dCA/IGpxWEhSLnJlc3BvbnNlVGV4dCA6ICdOL0EnICksIGZhbHNlLCBmYWxzZSwganFYSFIgKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoICFpc1Nob3duTmV0d29ya0FsZXJ0ICkge1xuXHRcdFx0VEFsZXJ0TWFuYWdlci5zaG93QWxlcnQoIEdsb2JhbC5uZXR3b3JrX2xvc3RfbXNnICsgJzxicj48YnI+JyArICdFcnJvcjogJyArIHRleHRTdGF0dXMgKyAnICgnICsganFYSFIuc3RhdHVzICsgJyk6IDxicj5cIicgKyBlcnJvclRocm93biArICdcIicgKyAnPGJyPjxocj4nICsgKCBqcVhIUi5yZXNwb25zZVRleHQgPyBqcVhIUi5yZXNwb25zZVRleHQgOiAnTi9BJyApICsgJyAoJyArIGpxWEhSLnN0YXR1cyArICcpJywgJ0Vycm9yJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlzU2hvd25OZXR3b3JrQWxlcnQgPSBmYWxzZTtcblx0XHRcdH0gKTtcblx0XHRcdGlzU2hvd25OZXR3b3JrQWxlcnQgPSB0cnVlO1xuXHRcdFx0R2xvYmFsLnNlbmRBbmFseXRpY3NFdmVudCggJ2FsZXJ0LW1hbmFnZXInLCAnZXJyb3I6bmV0d29yaycsICduZXR3b3JrLWVycm9yOiBqcVhIUi1zdGF0dXM6ICcgKyBqcVhIUi5zdGF0dXMgKyAnIEVycm9yOiAnICsgdGV4dFN0YXR1cyApO1xuXHRcdH1cblx0fTtcblxuXHR2YXIgc2hvd1ByZVNlc3Npb25BbGVydCA9IGZ1bmN0aW9uKCkge1xuXHRcdHZhciByZXN1bHQgPSAkKCAnPGRpdiBjbGFzcz1cInNlc3Npb24tYWxlcnRcIj4gJyArXG5cdFx0XHQnPHNwYW4gY2xhc3M9XCJjbG9zZS1pY29uXCI+WDwvc3Bhbj4nICtcblx0XHRcdCc8c3BhbiBjbGFzcz1cImNvbnRlbnRcIj48L3NwYW4+JyArXG5cdFx0XHQnPC9kaXY+JyApO1xuXHRcdHNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0JCggJ2JvZHknICkuYXBwZW5kKCByZXN1bHQgKTtcblx0XHRcdHJlc3VsdC5maW5kKCAnLmNvbnRlbnQnICkuaHRtbCggJC5pMThuLl8oICdQcmV2aW91cyBTZXNzaW9uJyApICk7XG5cdFx0XHR2YXIgYnV0dG9uID0gcmVzdWx0LmZpbmQoICcuY2xvc2UtaWNvbicgKTtcblx0XHRcdGJ1dHRvbi5iaW5kKCAnY2xpY2snLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmVtb3ZlUHJlU2Vzc2lvbigpO1xuXHRcdFx0fSApO1xuXHRcdFx0cmVzdWx0LmJpbmQoICdjbGljaycsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRiYWNrVG9QcmVTZXNzaW9uKCk7XG5cdFx0XHR9ICk7XG5cdFx0fSwgMTAwICk7XG5cblx0XHRmdW5jdGlvbiByZW1vdmVQcmVTZXNzaW9uKCkge1xuXHRcdFx0cmVzdWx0LnJlbW92ZSgpO1xuXHRcdFx0cmVzdWx0ID0gbnVsbDtcblxuXHRcdFx0ZGVsZXRlQ29va2llKCAnQWx0ZXJuYXRlU2Vzc2lvbkRhdGEnLCBMb2NhbENhY2hlRGF0YS5jb29raWVfcGF0aCwgR2xvYmFsLmdldEhvc3QoKSApO1xuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGJhY2tUb1ByZVNlc3Npb24oKSB7XG5cdFx0XHR2YXIgaG9zdCA9IEdsb2JhbC5nZXRIb3N0KCk7XG5cdFx0XHR0cnkgeyAvL1ByZXZlbnQgSlMgZXhjZXB0aW9uIGlmIHdlIGNhbid0IHBhcnNlIGFsdGVybmF0ZV9zZXNzaW9uX2RhdGEgZm9yIHNvbWUgcmVhc29uLlxuXHRcdFx0XHR2YXIgYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSA9IEpTT04ucGFyc2UoIGdldENvb2tpZSggJ0FsdGVybmF0ZVNlc3Npb25EYXRhJyApICk7XG5cdFx0XHRcdGlmICggIWFsdGVybmF0ZV9zZXNzaW9uX2RhdGEgKSB7XG5cdFx0XHRcdFx0RGVidWcuVGV4dCggJ05vIGFsdGVybmF0ZV9zZXNzaW9uX2RhdGEgZXhpc3RzLicsICdUQWxlcnRNYW5hZ2VyLmpzJywgJ1RBbGVydE1hbmFnZXInLCAnYmFja1RvUHJlU2Vzc2lvbicsIDEwICk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0RGVidWcuVGV4dCggZS5tZXNzYWdlLCAnVEFsZXJ0TWFuYWdlci5qcycsICdzaG93UHJlU2Vzc2lvbkFsZXJ0JywgJ2JhY2tUb1ByZVNlc3Npb24nLCAxMCApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHZhciB1cmwgPSBhbHRlcm5hdGVfc2Vzc2lvbl9kYXRhLnByZXZpb3VzX3Nlc3Npb25fdXJsO1xuXHRcdFx0dmFyIHByZXZpb3VzX2Nvb2tpZV9wYXRoID0gYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YS5wcmV2aW91c19jb29raWVfcGF0aDtcblxuXHRcdFx0YWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSA9IHtcblx0XHRcdFx0bmV3X3Nlc3Npb25faWQ6IGFsdGVybmF0ZV9zZXNzaW9uX2RhdGEucHJldmlvdXNfc2Vzc2lvbl9pZCxcblx0XHRcdFx0cHJldmlvdXNfc2Vzc2lvbl92aWV3OiBhbHRlcm5hdGVfc2Vzc2lvbl9kYXRhLnByZXZpb3VzX3Nlc3Npb25fdmlld1xuXHRcdFx0fTtcblxuXHRcdFx0c2V0Q29va2llKCAnQWx0ZXJuYXRlU2Vzc2lvbkRhdGEnLCBKU09OLnN0cmluZ2lmeSggYWx0ZXJuYXRlX3Nlc3Npb25fZGF0YSApLCAxLCBwcmV2aW91c19jb29raWVfcGF0aCwgaG9zdCApO1xuXG5cdFx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCB1cmwgKyAnIyFtPUxvZ2luJyApO1xuXHRcdFx0R2xvYmFsLm5lZWRSZWxvYWRCcm93c2VyID0gdHJ1ZTtcblxuXHRcdFx0cmVzdWx0LnJlbW92ZSgpO1xuXHRcdFx0cmVzdWx0ID0gbnVsbDtcblx0XHR9XG5cdH07XG5cblx0dmFyIHNob3dFcnJvckFsZXJ0ID0gZnVuY3Rpb24oIHJlc3VsdCApIHtcblx0XHR2YXIgZGV0YWlscyA9IHJlc3VsdC5nZXREZXRhaWxzKCk7XG5cblx0XHRpZiAoIGRldGFpbHMuaGFzT3duUHJvcGVydHkoICdlcnJvcicgKSApIHtcblxuXHRcdH1cblx0XHRpZiAoICFkZXRhaWxzICkge1xuXHRcdFx0ZGV0YWlscyA9IHJlc3VsdC5nZXREZXNjcmlwdGlvbigpOyAvLyBJZiB0aGUgZGV0YWlscyBpcyBlbXB0eSwgdHJ5IHRvIGdldCBkZXNjcmlwdGlvbiB0byBzaG93LlxuXHRcdH1cblx0XHR2YXIgZXJyb3Jfc3RyaW5nID0gJyc7XG5cblx0XHRpZiAoIEdsb2JhbC5pc0FycmF5KCBkZXRhaWxzICkgfHwgdHlwZW9mIGRldGFpbHMgPT09ICdvYmplY3QnICkge1xuXHRcdFx0ZXJyb3Jfc3RyaW5nID0gR2xvYmFsLmNvbnZlcnRWYWxpZGF0aW9uRXJyb3JUb1N0cmluZyggZGV0YWlscyApO1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGVycm9yX3N0cmluZyA9IGRldGFpbHM7XG5cdFx0fVxuXG5cdFx0c2hvd0FsZXJ0KCBlcnJvcl9zdHJpbmcsICdFcnJvcicgKTtcblxuXHR9O1xuXG5cdHZhciBzaG93V2FybmluZ0FsZXJ0ID0gZnVuY3Rpb24oIHJlc3VsdCwgY2FsbEJhY2sgKSB7XG5cdFx0dmFyIGRldGFpbHMgPSByZXN1bHQuZ2V0RGV0YWlscygpO1xuXHRcdHZhciB1bF9jb250YWluZXIgPSAkKCAnPG9sPicgKTtcblx0XHRpZiAoIEdsb2JhbC5pc0FycmF5KCBkZXRhaWxzICkgfHwgdHlwZW9mIGRldGFpbHMgPT09ICdvYmplY3QnICkge1xuXHRcdFx0JC5lYWNoKCBkZXRhaWxzLCBmdW5jdGlvbiggaW5kZXgsIHZhbCApIHtcblx0XHRcdFx0aWYgKCB2YWwuaGFzT3duUHJvcGVydHkoICd3YXJuaW5nJyApICkge1xuXHRcdFx0XHRcdHZhbCA9IHZhbC53YXJuaW5nO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGZvciAoIHZhciBrZXkgaW4gdmFsICkge1xuXHRcdFx0XHRcdHZhciBsaSA9ICQoICc8bGk+JyApO1xuXHRcdFx0XHRcdHZhciBjaGlsZF92YWwgPSB2YWxba2V5XTtcblx0XHRcdFx0XHR2YXIgaGFzX2NoaWxkID0gZmFsc2U7XG5cdFx0XHRcdFx0Zm9yICggdmFyIGNoaWxkX2tleSBpbiBjaGlsZF92YWwgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGNoaWxkX3ZhbC5oYXNPd25Qcm9wZXJ0eSggY2hpbGRfa2V5ICkgKSB7XG5cdFx0XHRcdFx0XHRcdGhhc19jaGlsZCA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdGxpID0gJCggJzxsaT4nICk7XG5cdFx0XHRcdFx0XHRcdGxpLmFwcGVuZCggY2hpbGRfdmFsW2NoaWxkX2tleV0gKTtcblx0XHRcdFx0XHRcdFx0dWxfY29udGFpbmVyLmFwcGVuZCggbGkgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCAhaGFzX2NoaWxkICkge1xuXHRcdFx0XHRcdFx0bGkuYXBwZW5kKCB2YWxba2V5XSApO1xuXHRcdFx0XHRcdFx0dWxfY29udGFpbmVyLmFwcGVuZCggbGkgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHR9XG5cdFx0dmFyIGRpdiA9ICQoICc8ZGl2PicgKTtcblx0XHR2YXIgcCA9ICQoICc8cD4nICk7XG5cdFx0cC5hcHBlbmQoICQuaTE4bi5fKCAnQXJlIHlvdSBzdXJlIHlvdSB3aXNoIHRvIHNhdmUgdGhpcyByZWNvcmQgd2l0aG91dCBjb3JyZWN0aW5nIHRoZSBhYm92ZSB3YXJuaW5ncz8nICkgKTtcblx0XHRkaXYuYXBwZW5kKCB1bF9jb250YWluZXIgKTtcblx0XHRkaXYuYXBwZW5kKCBwICk7XG5cdFx0c2hvd0NvbmZpcm1BbGVydCggZGl2WzBdLCAnV2FybmluZycsIGNhbGxCYWNrLCAnU2F2ZScsICdDYW5jZWwnICk7XG5cdH07XG5cblx0dmFyIHNob3dBbGVydCA9IGZ1bmN0aW9uKCBjb250ZW50LCB0aXRsZSwgY2FsbEJhY2sgKSB7XG5cdFx0aWYgKCAhdGl0bGUgKSB7XG5cdFx0XHR0aXRsZSA9ICQuaTE4bi5fKCAnTWVzc2FnZScgKTtcblx0XHR9XG5cblx0XHR2YXIgcmVzdWx0ID0gJCggJzxkaXYgY2xhc3M9XCJ0LWFsZXJ0XCI+JyArXG5cdFx0XHQnPGRpdiBjbGFzcz1cImNvbnRlbnQtZGl2XCI+PHNwYW4gY2xhc3M9XCJjb250ZW50XCI+PC9zcGFuPjwvZGl2PicgK1xuXHRcdFx0JzxzcGFuIGNsYXNzPVwidGl0bGVcIj48L3NwYW4+JyArXG5cdFx0XHQnPGRpdiBjbGFzcz1cImJvdHRvbS1iYXJcIj4nICtcblx0XHRcdCc8YnV0dG9uIGNsYXNzPVwidC1idXR0b25cIiBpZD1cInQtYWxlcnQtY2xvc2VcIj5DbG9zZTwvYnV0dG9uPicgK1xuXHRcdFx0JzwvZGl2PicgK1xuXHRcdFx0JzwvZGl2PicgKTtcblx0XHRzZXRUaW1lb3V0KCBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggdmlldyAhPT0gbnVsbCApIHtcblxuXHRcdFx0XHR2YXIgY0NvbnRlbnQgPSB2aWV3LmZpbmQoICcuY29udGVudCcgKS50ZXh0KCk7XG5cblx0XHRcdFx0aWYgKCBjQ29udGVudCA9PT0gY29udGVudCApIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZW1vdmUoKTtcblxuXHRcdFx0fVxuXHRcdFx0dmlldyA9IHJlc3VsdDtcblx0XHRcdCQoICdib2R5JyApLmFwcGVuZCggcmVzdWx0ICk7XG5cdFx0XHRyZXN1bHQuZmluZCggJy50aXRsZScgKS50ZXh0KCB0aXRsZSApO1xuXHRcdFx0cmVzdWx0LmZpbmQoICcuY29udGVudCcgKS5odG1sKCBjb250ZW50ICk7XG5cdFx0XHR2YXIgYnV0dG9uID0gcmVzdWx0LmZpbmQoICcudC1idXR0b24nICk7XG5cdFx0XHRidXR0b24uYmluZCggJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJlbW92ZSgpO1xuXHRcdFx0XHRpZiAoIGNhbGxCYWNrICkge1xuXHRcdFx0XHRcdGNhbGxCYWNrKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHRcdGJ1dHRvbi5mb2N1cygpO1xuXHRcdFx0YnV0dG9uLmJpbmQoICdrZXlkb3duJywgZnVuY3Rpb24oIGUgKSB7XG5cdFx0XHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdGlmICggZS5rZXlDb2RlID09PSAxMyApIHtcblx0XHRcdFx0XHRyZW1vdmUoKTtcblx0XHRcdFx0XHRpZiAoIGNhbGxCYWNrICkge1xuXHRcdFx0XHRcdFx0Y2FsbEJhY2soKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblxuXHRcdFx0R2xvYmFsLnNldFVJSW5pdENvbXBsZXRlKCk7XG5cdFx0fSwgMTAwICk7XG5cblx0fTtcblxuXHR2YXIgc2hvd0NvbmZpcm1BbGVydCA9IGZ1bmN0aW9uKCBjb250ZW50LCB0aXRsZSwgY2FsbEJhY2tGdW5jdGlvbiwgeWVzTGFiZWwsIG5vTGFiZWwgKSB7XG5cblx0XHRpZiAoICFHbG9iYWwuaXNTZXQoIHRpdGxlICkgKSB7XG5cdFx0XHR0aXRsZSA9ICQuaTE4bi5fKCAnTWVzc2FnZScgKTtcblx0XHR9XG5cblx0XHRpZiAoICFHbG9iYWwuaXNTZXQoIHllc0xhYmVsICkgKSB7XG5cdFx0XHR5ZXNMYWJlbCA9ICQuaTE4bi5fKCAnWWVzJyApO1xuXHRcdH1cblxuXHRcdGlmICggIUdsb2JhbC5pc1NldCggbm9MYWJlbCApICkge1xuXHRcdFx0bm9MYWJlbCA9ICQuaTE4bi5fKCAnTm8nICk7XG5cdFx0fVxuXG5cdFx0aWYgKCB2aWV3ICE9PSBudWxsICkge1xuXG5cdFx0XHR2YXIgY0NvbnRlbnQgPSB2aWV3LmZpbmQoICcuY29udGVudCcgKS50ZXh0KCk7XG5cblx0XHRcdGlmICggY0NvbnRlbnQgPT09IGNvbnRlbnQgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0cmVtb3ZlKCk7XG5cdFx0fVxuXHRcdHZhciByZXN1bHQgPSAkKCAnPGRpdiBjbGFzcz1cImNvbmZpcm0tYWxlcnRcIj4gJyArXG5cdFx0XHQnPGRpdiBjbGFzcz1cImNvbnRlbnQtZGl2XCI+PHNwYW4gY2xhc3M9XCJjb250ZW50XCI+PC9zcGFuPjwvZGl2PicgK1xuXHRcdFx0JzxzcGFuIGNsYXNzPVwidGl0bGVcIj48L3NwYW4+JyArXG5cdFx0XHQnPGRpdiBjbGFzcz1cImJvdHRvbS1iYXJcIj4nICtcblx0XHRcdCc8YnV0dG9uIGlkPVwieWVzQnRuXCIgY2xhc3M9XCJ0LWJ1dHRvbiBib3R0b20tYmFyLXllcy1idG5cIj48L2J1dHRvbj4nICtcblx0XHRcdCc8YnV0dG9uIGlkPVwibm9CdG5cIiBjbGFzcz1cInQtYnV0dG9uXCI+PC9idXR0b24+JyArXG5cdFx0XHQnPC9kaXY+JyArXG5cdFx0XHQnPC9kaXY+JyApO1xuXHRcdHZpZXcgPSByZXN1bHQ7XG5cdFx0JCggJ2JvZHknICkuYXBwZW5kKCByZXN1bHQgKTtcblxuXHRcdHJlc3VsdC5maW5kKCAnI3llc0J0bicgKS50ZXh0KCB5ZXNMYWJlbCApO1xuXHRcdHJlc3VsdC5maW5kKCAnI25vQnRuJyApLnRleHQoIG5vTGFiZWwgKTtcblx0XHRyZXN1bHQuZmluZCggJy50aXRsZScgKS50ZXh0KCB0aXRsZSApO1xuXG5cdFx0cmVzdWx0LmZpbmQoICcuY29udGVudCcgKS5odG1sKCBjb250ZW50ICk7XG5cblx0XHRyZXN1bHQuZmluZCggJyN5ZXNCdG4nICkuYmluZCggJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRyZW1vdmUoKTtcblx0XHRcdGNhbGxCYWNrRnVuY3Rpb24oIHRydWUgKTtcblxuXHRcdH0gKTtcblxuXHRcdHJlc3VsdC5maW5kKCAnI25vQnRuJyApLmJpbmQoICdjbGljaycsIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmVtb3ZlKCk7XG5cdFx0XHRjYWxsQmFja0Z1bmN0aW9uKCBmYWxzZSApO1xuXG5cdFx0fSApO1xuXG5cdFx0R2xvYmFsLnNldFVJSW5pdENvbXBsZXRlKCk7XG5cdH07XG5cblx0dmFyIHNob3dGbGV4QWxlcnQgPSBmdW5jdGlvbiggdGl0bGUsIGNvbnRlbnQsIGZvcm1fdHlwZSwgZm9ybV9kYXRhLCBjYWxsQmFja0Z1bmN0aW9uLCB3aWR0aCwgY29udGludWVfbGFiZWwsIGNhbmNlbF9sYWJlbCApIHtcblx0XHRHbG9iYWwuc2V0VUlOb3RyZWFkeSgpO1xuXG5cdFx0dmFyIHNob3dfY29udGludWVfYnV0dG9uID0gdHJ1ZTtcblx0XHR2YXIgc2hvd19jYW5jZWxfYnV0dG9uID0gdHJ1ZTtcblxuXHRcdGlmICggIWNvbnRpbnVlX2xhYmVsICkge1xuXHRcdFx0Y29udGludWVfbGFiZWwgPSAkLmkxOG4uXyggJ0NvbnRpbnVlJyApO1xuXHRcdH1cblxuXHRcdGlmICggIWNhbmNlbF9sYWJlbCApIHtcblx0XHRcdGNhbmNlbF9sYWJlbCA9ICQuaTE4bi5fKCAnQ2FuY2VsJyApO1xuXHRcdH1cblxuXHRcdHZhciByZXN1bHQgPSAkKCAnPGRpdiBjbGFzcz1cImNvbmZpcm0tYWxlcnRcIj4gJyArXG5cdFx0XHQnPGRpdj48c3BhbiBjbGFzcz1cImNvbnRlbnRcIj48L3NwYW4+PC9kaXY+JyArXG5cdFx0XHQnPHNwYW4gY2xhc3M9XCJ0aXRsZVwiPjwvc3Bhbj4nICtcblx0XHRcdCc8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogMnJlbTsgbWFyZ2luLWJvdHRvbTogMnJlbVwiIGlkPVwiZm9ybS1ob2xkZXJcIj48L2Rpdj4nICtcblx0XHRcdCc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMXJlbVwiIGNsYXNzPVwiYm90dG9tLWJhclwiPicgK1xuXHRcdFx0JzxidXR0b24gaWQ9XCJ5ZXNCdG5cIiBjbGFzcz1cInQtYnV0dG9uIGJvdHRvbS1iYXIteWVzLWJ0blwiPjwvYnV0dG9uPicgK1xuXHRcdFx0JzxidXR0b24gaWQ9XCJub0J0blwiIGNsYXNzPVwidC1idXR0b25cIj48L2J1dHRvbj4nICtcblx0XHRcdCc8L2Rpdj4nICtcblx0XHRcdCc8L2Rpdj4nIClcblxuXHRcdGlmICggd2lkdGggKSB7XG5cdFx0XHRyZXN1bHQuY3NzKCAnd2lkdGgnLCB3aWR0aCApO1xuXHRcdH1cblxuXHRcdHZpZXcgPSByZXN1bHQ7XG5cdFx0JCggJ2JvZHknICkuYXBwZW5kKCByZXN1bHQgKTtcblxuXHRcdGlmICggZm9ybV90eXBlID09PSAnZHJvcGRvd24nICkge1xuXHRcdFx0dmFyIGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuQ09NQk9fQk9YICk7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuVENvbWJvQm94KCk7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuc2V0U291cmNlRGF0YSggZm9ybV9kYXRhICk7XG5cblx0XHRcdHJlc3VsdC5maW5kKCAnI3llc0J0bicgKS5iaW5kKCAnY2xpY2snLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmVtb3ZlKCk7XG5cdFx0XHRcdGNhbGxCYWNrRnVuY3Rpb24oIHJlc3VsdC5maW5kKCAnc2VsZWN0JyApLnZhbCgpICk7XG5cdFx0XHR9ICk7XG5cdFx0fSBlbHNlIGlmICggZm9ybV90eXBlID09PSAncGFzc3dvcmQnICkge1xuXHRcdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5QQVNTV09SRF9JTlBVVCApO1xuXHRcdFx0Zm9ybV9pdGVtX2lucHV0LlRQYXNzd29yZElucHV0KCk7XG5cblx0XHRcdHJlc3VsdC5maW5kKCAnI3llc0J0bicgKS5iaW5kKCAnY2xpY2snLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmVtb3ZlKCk7XG5cdFx0XHRcdGNhbGxCYWNrRnVuY3Rpb24oIHJlc3VsdC5maW5kKCAnW3R5cGU9cGFzc3dvcmRdJyApLnZhbCgpICk7XG5cdFx0XHR9ICk7XG5cdFx0fSBlbHNlIGlmICggZm9ybV90eXBlID09PSAndGV4dCcgKSB7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLlRFWFRfSU5QVVQgKTtcblx0XHRcdGZvcm1faXRlbV9pbnB1dC5UVGV4dElucHV0KCk7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuc2V0VmFsdWUoIGZvcm1fZGF0YSApO1xuXG5cdFx0XHRpZiAoIHdpZHRoICkge1xuXHRcdFx0XHRmb3JtX2l0ZW1faW5wdXQud2lkdGgoICggd2lkdGggLSAyMCApICk7XG5cdFx0XHR9XG5cblx0XHRcdHNob3dfY2FuY2VsX2J1dHRvbiA9IGZhbHNlO1xuXG5cdFx0XHRyZXN1bHQuZmluZCggJyN5ZXNCdG4nICkuYmluZCggJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJlbW92ZSgpO1xuXHRcdFx0fSApO1xuXHRcdH0gZWxzZSBpZiAoIGZvcm1fdHlwZSA9PT0gJ3dvcmRfbWF0Y2gnICkge1xuXHRcdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5URVhUX0lOUFVUICk7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuVFRleHRJbnB1dCgpO1xuXG5cdFx0XHRyZXN1bHQuZmluZCggJyN5ZXNCdG4nICkuYmluZCggJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggcmVzdWx0LmZpbmQoICdbdHlwZT10ZXh0XScgKS52YWwoKSA9PT0gZm9ybV9kYXRhICkge1xuXHRcdFx0XHRcdHJlbW92ZSgpO1xuXHRcdFx0XHRcdGNhbGxCYWNrRnVuY3Rpb24oIHRydWUgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjYWxsQmFja0Z1bmN0aW9uKCBmYWxzZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0cmVzdWx0LmZpbmQoICcjZm9ybS1ob2xkZXInICkuYXBwZW5kKCBmb3JtX2l0ZW1faW5wdXQgKTtcblxuXHRcdHJlc3VsdC5maW5kKCAnI25vQnRuJyApLmJpbmQoICdjbGljaycsIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmVtb3ZlKCk7XG5cdFx0XHRjYWxsQmFja0Z1bmN0aW9uKCBmYWxzZSApO1xuXHRcdH0gKTtcblxuXHRcdHJlc3VsdC5maW5kKCAnI3llc0J0bicgKS50ZXh0KCBjb250aW51ZV9sYWJlbCApO1xuXHRcdHJlc3VsdC5maW5kKCAnI25vQnRuJyApLnRleHQoIGNhbmNlbF9sYWJlbCApO1xuXG5cdFx0cmVzdWx0LmZpbmQoICcudGl0bGUnICkudGV4dCggdGl0bGUgKTtcblx0XHRyZXN1bHQuZmluZCggJy5jb250ZW50JyApLmh0bWwoIGNvbnRlbnQgKTtcblxuXHRcdGlmICggc2hvd19jb250aW51ZV9idXR0b24gPT0gZmFsc2UgKSB7XG5cdFx0XHRyZXN1bHQuZmluZCggJyN5ZXNCdG4nICkuaGlkZSgpO1xuXHRcdH1cblxuXHRcdGlmICggc2hvd19jYW5jZWxfYnV0dG9uID09IGZhbHNlICkge1xuXHRcdFx0cmVzdWx0LmZpbmQoICcjbm9CdG4nICkuaGlkZSgpO1xuXHRcdH1cblxuXHRcdEdsb2JhbC5zZXRVSUluaXRDb21wbGV0ZSgpO1xuXHR9O1xuXG5cblx0dmFyIHNob3dNb2RhbEFsZXJ0ID0gZnVuY3Rpb24oIGNhdGVnb3J5LCBzdGVwLCBjYWxsQmFja0Z1bmN0aW9uLCBpbWdfc3JjICkge1xuXHRcdGxldCB0b3BfaW1hZ2UgPSAnJztcblx0XHRsZXQgdGl0bGUgPSAnJztcblx0XHRsZXQgY29udGVudCA9ICcnO1xuXHRcdGxldCBhZGRpdGlvbmFsX2JvZHlfc3R5bGUgPSAnJztcblx0XHRsZXQgYnV0dG9uX2xhYmVsID0gJC5pMThuLl8oICdZZXMnICk7XG5cdFx0bGV0IGJ1dHRvbl9jb2xvciA9ICcjMjI4YjIyJztcblxuXHRcdGlmICggY2F0ZWdvcnkgPT09ICdwdXNoX25vdGlmaWNhdGlvbicgKSB7XG5cdFx0XHR0b3BfaW1hZ2UgPSAnPGltZyBjbGFzcyA9XCJtb2RhbC1hbGVydC1pbWFnZVwiIHNyYyA9XCInICsgR2xvYmFsLmdldFJlYWxJbWFnZVBhdGgoICdpbWFnZXMvYmVsbF9wZXJtaXNzaW9ucy5zdmcnICkgKyAnXCI+Jztcblx0XHRcdHRpdGxlID0gJC5pMThuLl8oICdUdXJuIG9uIE5vdGlmaWNhdGlvbnMnICk7XG5cblx0XHRcdHN3aXRjaCAoIHN0ZXAgKSB7XG5cdFx0XHRcdGNhc2UgJ2Fzayc6XG5cdFx0XHRcdFx0YnV0dG9uX2xhYmVsID0gJC5pMThuLl8oICdZZXMsIHR1cm4gb24gbm90aWZpY2F0aW9ucyEnICk7XG5cdFx0XHRcdFx0Y29udGVudCA9IExvY2FsQ2FjaGVEYXRhLmdldEN1cnJlbnRDb21wYW55KCkubmFtZSArICcgJyArICQuaTE4bi5fKCAnd2FudHMgcGVybWlzc2lvbiB0byBub3RpZnkgeW91IG9mIGltcG9ydGFudCBtZXNzYWdlcyBvciBhbGVydHMgcmVsYXRlZCB0byB5b3VyIGVtcGxveW1lbnQuIFlvdSBjYW4gY2hhbmdlIHlvdXIgbm90aWZpY2F0aW9uIHNldHRpbmdzIGF0IGFueXRpbWUuJyApO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlICd3YWl0X2Zvcl9wZXJtaXNzaW9uJzpcblx0XHRcdFx0XHRidXR0b25fbGFiZWwgPSAkLmkxOG4uXyggJ0kgZG9uXFwndCBzZWUgaXQ/JyApO1xuXHRcdFx0XHRcdGJ1dHRvbl9jb2xvciA9ICcjQUUwMDAwJztcblx0XHRcdFx0XHQvLyBTb21lIGJyb3dzZXJzIGJ5IGRlZmF1bHQgYmxvY2sgcHVzaCBub3RpZmljYXRpb24gcGVybWlzc2lvbiB3ZSBuZWVkIHRvIGRldGVjdCB0aGVtIHRvIHNob3cgdXNlciBhIGRpZmZlcmVudCBwcm9tcHQuXG5cdFx0XHRcdFx0aWYgKCBOb3RpZmljYXRpb25Db25zdW1lci5kZXRlY3RCcm93c2VyTmVlZHNFeHRyYVBlcm1pc3Npb24oKSA9PT0gdHJ1ZSB8fCBOb3RpZmljYXRpb24ucGVybWlzc2lvbiA9PT0gJ2RlbmllZCcgKSB7XG5cdFx0XHRcdFx0XHQvLyBVc2VyIG5lZWRzIHRvIGVuYWJsZSBwdXNoIG5vdGlmaWNhdGlvbnMgb24gdGhlIGJyb3dzZXIuXG5cdFx0XHRcdFx0XHRjb250ZW50ID0gJC5pMThuLl8oICdBIHBvcHVwIHNob3VsZCBhcHBlYXIgb24geW91ciBzY3JlZW4sIGNsaWNrIFwiQUxMT1dcIiB0byBlbmFibGUgbm90aWZpY2F0aW9ucy4gSWYgeW91IGRvblxcJ3Qgc2VlIGl0LCB5b3UgbWF5IG5lZWQgdG8gZW5hYmxlIG5vdGlmaWNhdGlvbnMgaW4geW91ciBicm93c2VyIHNldHRpbmdzLicgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Y29udGVudCA9ICQuaTE4bi5fKCAnQSBwb3B1cCBzaG91bGQgYXBwZWFyIG9uIHlvdXIgc2NyZWVuLCBjbGljayBcIkFMTE9XXCIgdG8gZW5hYmxlIG5vdGlmaWNhdGlvbnMuJyApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnaGVscF90ZXh0Jzpcblx0XHRcdFx0XHRidXR0b25fbGFiZWwgPSAkLmkxOG4uXyggJ09rLCBkb25lIScgKTtcblx0XHRcdFx0XHRpZiAoIEdsb2JhbC5nZXRCcm93c2VyVmVuZG9yKCkgPT09ICdFZGdlJyApIHtcblx0XHRcdFx0XHRcdGNvbnRlbnQgPSAkLmkxOG4uXyggJzEuIENsaWNrIHRoZSBpY29uIHRvIHRoZSBsZWZ0IG9mIHRoZSBhZGRyZXNzIChVUkwpIGJhciB0byB2aWV3IHNldHRpbmdzLjxicj4nICtcblx0XHRcdFx0XHRcdFx0JzIuIENsaWNrIFwiUGVybWlzc2lvbnMgZm9yIHRoaXMgU2l0ZVwiPGJyPicgK1xuXHRcdFx0XHRcdFx0XHQnMy4gVG8gdGhlIHJpZ2h0IG9mIFwiTm90aWZpY2F0aW9uc1wiIHNldCB0aGUgb3B0aW9uIHRvIFwiQUxMT1dcIi4nICk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmICggR2xvYmFsLmdldEJyb3dzZXJWZW5kb3IoKSA9PT0gJ0ZpcmVmb3gnICkge1xuXHRcdFx0XHRcdFx0Y29udGVudCA9ICQuaTE4bi5fKCAnMS4gQ2xpY2sgdGhlIGljb24gdG8gdGhlIGxlZnQgb2YgdGhlIGFkZHJlc3MgKFVSTCkgYmFyIHRvIHZpZXcgc2V0dGluZ3MuPGJyPicgK1xuXHRcdFx0XHRcdFx0XHQnMi4gQ2xpY2sgdGhlIFwiWFwiIG5leHQgTm90aWZpY2F0aW9ucyB0byByZW1vdmUgYmxvY2tlZCBwZXJtaXNzaW9ucyBhbmQgdGhlbiByZWZyZXNoIHRoZSBicm93c2VyLjxicj4nICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGNvbnRlbnQgPSAkLmkxOG4uXyggJzEuIENsaWNrIHRoZSBpY29uIHRvIHRoZSBsZWZ0IG9mIHRoZSBhZGRyZXNzIChVUkwpIGJhciB0byB2aWV3IHNldHRpbmdzLjxicj4nICtcblx0XHRcdFx0XHRcdFx0JzIuIENsaWNrIFwiU2l0ZSBzZXR0aW5nc1wiPGJyPicgK1xuXHRcdFx0XHRcdFx0XHQnMy4gVG8gdGhlIHJpZ2h0IG9mIFwiTm90aWZpY2F0aW9uc1wiIHNldCB0aGUgb3B0aW9uIHRvIFwiQUxMT1dcIi4nICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAoIGNhdGVnb3J5ID09PSAnbXVsdGlmYWN0b3JfYXV0aGVudGljYXRpb24nICkge1xuXHRcdFx0dGl0bGUgPSAkLmkxOG4uXyggJ011bHRpZmFjdG9yIEF1dGhlbnRpY2F0aW9uIEluc3RydWN0aW9ucycgKTtcblxuXHRcdFx0c3dpdGNoICggc3RlcCApIHtcblx0XHRcdFx0Y2FzZSAnZG93bmxvYWRfaW5zdHJ1Y3Rpb25zJzpcblx0XHRcdFx0XHRidXR0b25fbGFiZWwgPSAkLmkxOG4uXyggJ09rJyApO1xuXHRcdFx0XHRcdGJ1dHRvbl9jb2xvciA9ICcjNDI2ZDlkJztcblx0XHRcdFx0XHRhZGRpdGlvbmFsX2JvZHlfc3R5bGUgPSAnc3R5bGU9XCJkaXNwbGF5OiBibG9jazsgcGFkZGluZy1sZWZ0OiAycmVtOyBwYWRkaW5nLXJpZ2h0OiAycmVtOyBmb250LXNpemU6IDEuMXJlbTtcIic7XG5cblx0XHRcdFx0XHRjb250ZW50ID0gJzxicj4nO1xuXHRcdFx0XHRcdGNvbnRlbnQgKz0gJzEuJyArICQuaTE4bi5fKCAnUGxlYXNlIGRvd25sb2FkIHRoZSBUaW1lVHJleCBhcHAgZnJvbSB0aGUgQXBwIFN0b3JlIG9uIHlvdXIgZGV2aWNlLicgKSArICc8YnI+PGJyPic7XG5cdFx0XHRcdFx0Y29udGVudCArPSAnMi4nICsgJC5pMThuLl8oICcgT25jZSBpbnN0YWxsZWQsIG9uIHRoZSBmaXJzdCBzdGVwIG9mIHRoZSBcIlNldHVwIFdpemFyZFwiLCB0YXAgdGhlIFwiUVIgQ29kZVwiIGljb24gYXQgdGhlIGJvdHRvbSByaWdodCB0byBzY2FuIHRoZSBiZWxvdyBRUiBDb2RlLicgKSArICc8YnI+Jztcblx0XHRcdFx0XHRjb250ZW50ICs9ICc8aW1nIGNsYXNzID1cIm1vZGFsLWFsZXJ0LWltYWdlXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxMHB4O1wiIHNyYyA9XCInICsgaW1nX3NyYyArICdcIj4nO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdEdsb2JhbC5zZXRVSU5vdHJlYWR5KCk7XG5cblx0XHR2YXIgcmVzdWx0ID0gJCggJzxkaXYgY2xhc3M9XCJtb2RhbC1hbGVydFwiPiAnICtcblx0XHRcdCc8ZGl2IGNsYXNzPVwibW9kYWwtYWxlcnQtY29udGVudFwiPicgK1xuXHRcdFx0JzxzcGFuIGNsYXNzPVwibW9kYWwtYWxlcnQtY2xvc2VcIj7Dlzwvc3Bhbj4nICtcblx0XHRcdHRvcF9pbWFnZSArXG5cdFx0XHQnPGgyIGNsYXNzPVwibW9kYWwtYWxlcnQtdGl0bGVcIj48L2gyPicgK1xuXHRcdFx0JzxkaXYgY2xhc3M9XCJtb2RhbC1hbGVydC1ib2R5XCIgJyArIGFkZGl0aW9uYWxfYm9keV9zdHlsZSArICc+PC9kaXY+JyArXG5cdFx0XHQnPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgY2xhc3M9XCJwZXJtaXNzaW9uLWJ1dHRvbi15ZXNcIiBzdHlsZT1cImJhY2tncm91bmQ6ICcgKyBidXR0b25fY29sb3IgKyAnXCI+PC9idXR0b24+JyArXG5cdFx0XHQnPC9kaXY+JyArXG5cdFx0XHQnPC9kaXY+JyApO1xuXHRcdHZpZXcgPSByZXN1bHQ7XG5cdFx0JCggJ2JvZHknICkuYXBwZW5kKCByZXN1bHQgKTtcblxuXHRcdHJlc3VsdC5maW5kKCAnLnBlcm1pc3Npb24tYnV0dG9uLXllcycgKS50ZXh0KCBidXR0b25fbGFiZWwgKTtcblx0XHRyZXN1bHQuZmluZCggJy5tb2RhbC1hbGVydC10aXRsZScgKS50ZXh0KCB0aXRsZSApO1xuXG5cdFx0cmVzdWx0LmZpbmQoICcubW9kYWwtYWxlcnQtYm9keScgKS5odG1sKCBjb250ZW50ICk7XG5cblx0XHRyZXN1bHQuZmluZCggJy5wZXJtaXNzaW9uLWJ1dHRvbi15ZXMnICkuYmluZCggJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRyZW1vdmUoKTtcblx0XHRcdGlmICggY2FsbEJhY2tGdW5jdGlvbiApIHtcblx0XHRcdFx0Y2FsbEJhY2tGdW5jdGlvbiggdHJ1ZSApO1xuXHRcdFx0fVxuXHRcdFx0R2xvYmFsLnNldFVJUmVhZHkoKTtcblx0XHR9ICk7XG5cblx0XHRyZXN1bHQuZmluZCggJy5tb2RhbC1hbGVydC1jbG9zZScgKS5iaW5kKCAnY2xpY2snLCBmdW5jdGlvbigpIHtcblx0XHRcdHJlbW92ZSgpO1xuXHRcdFx0aWYgKCBjYWxsQmFja0Z1bmN0aW9uICkge1xuXHRcdFx0XHRjYWxsQmFja0Z1bmN0aW9uKCBmYWxzZSApO1xuXHRcdFx0fVxuXHRcdFx0R2xvYmFsLnNldFVJUmVhZHkoKTtcblx0XHR9ICk7XG5cblx0XHRHbG9iYWwuc2V0VUlJbml0Q29tcGxldGUoKTtcblx0fTtcblxuXHR2YXIgcmVtb3ZlID0gZnVuY3Rpb24oKSB7XG5cblx0XHRpZiAoIHZpZXcgKSB7XG5cdFx0XHR2aWV3LnJlbW92ZSgpO1xuXHRcdFx0dmlldyA9IG51bGw7XG5cdFx0fVxuXG5cdH07XG5cblx0cmV0dXJuIHtcblx0XHRzaG93QnJvd3NlclRvcEJhbm5lcjogc2hvd0Jyb3dzZXJUb3BCYW5uZXIsXG5cdFx0Y2xvc2VCcm93c2VyQmFubmVyOiBjbG9zZUJyb3dzZXJCYW5uZXIsXG5cdFx0c2hvd0NvbmZpcm1BbGVydDogc2hvd0NvbmZpcm1BbGVydCxcblx0XHRzaG93TW9kYWxBbGVydDogc2hvd01vZGFsQWxlcnQsXG5cdFx0c2hvd0FsZXJ0OiBzaG93QWxlcnQsXG5cdFx0c2hvd0Vycm9yQWxlcnQ6IHNob3dFcnJvckFsZXJ0LFxuXHRcdHNob3dQcmVTZXNzaW9uQWxlcnQ6IHNob3dQcmVTZXNzaW9uQWxlcnQsXG5cdFx0c2hvd0ZsZXhBbGVydDogc2hvd0ZsZXhBbGVydCxcblx0XHRzaG93V2FybmluZ0FsZXJ0OiBzaG93V2FybmluZ0FsZXJ0LFxuXHRcdHNob3dOZXR3b3JrRXJyb3JBbGVydDogc2hvd05ldHdvcmtFcnJvckFsZXJ0XG5cdH07XG5cbn0gKSgpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9239\n")},9504:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"j\": () => (/* binding */ TTPromise)\n/* harmony export */ });\n/* provided dependency */ var $ = __webpack_require__(9755);\nvar TTPromise = {\n\tpromises: {},\n\n\tadd: function( category, key ) {\n\t\tif ( !this.promises[category] || !this.promises[category][key] || ( this.promises[category][key].state() != 'pending' ) ) {\n\t\t\tDebug.Text( 'Promise: add: ' + category + '|' + key, 'TTPromise.js', 'TTPromise.js', 'add', 11 );\n\t\t\tif ( typeof this.promises[category] == 'undefined' ) {\n\t\t\t\tthis.promises[category] = {};\n\t\t\t}\n\n\t\t\tthis.promises[category][key] = $.Deferred();\n\t\t\tthis.promises[category][key].extra_data = { category: category, key: key };\n\t\t} else {\n\t\t\tDebug.Text( 'Promise: already exists: ' + category + '|' + key, 'TTPromise.js', 'TTPromise.js', 'add', 11 );\n\t\t}\n\t},\n\n\tresolve: function( category, key ) {\n\t\tif ( this.promises && this.promises[category] && this.promises[category][key] ) {\n\t\t\tDebug.Text( 'Promise: resolved: ' + category + '|' + key, 'TTPromise.js', 'TTPromise.js', 'resolve', 11 );\n\t\t\tthis.promises[category][key].resolve( this.promises[category][key].extra_data );\n\t\t}\n\t},\n\n\treject: function( category, key ) {\n\t\tif ( this.promises && this.promises[category] && this.promises[category][key] ) {\n\t\t\tDebug.Text( 'Promise: rejected: ' + category + '|' + key, 'TTPromise.js', 'TTPromise.js', 'reject', 11 );\n\t\t\tthis.promises[category][key].reject( this.promises[category][key].extra_data );\n\t\t}\n\t},\n\n\t/**\n\t * Wait for all or specific category/key\n\t *\n\t * In the case of waiting on all promises, error_callback is triggered for each individual error (rejection), and success callback is called when all promises are resolved (either success or failure)\n\t * so when waiting for all promises, most times you don't want a failure callback because both \"success\" and \"failure\" can happen on the same wait.\n\t *\n\t * The function call should look like:\n\t * TTPromise.wait(null,null,function(){\n\t * \t//do stuff on success\n\t * });\n\t *\n\t * @param category\n\t * @param key\n\t * @param success_callback\n\t * @param error_callback\n\t */\n\twait: function( category, key, success_callback, error_callback ) {\n\t\tDebug.Arr( arguments, 'Promise: wait(' + category + '|' + key + ').', 'TTPromise.js', 'TTPromise.js', 'wait', 11 );\n\t\tif ( typeof success_callback != 'function' ) {\n\t\t\tsuccess_callback = function() {\n\t\t\t\tGlobal.setUIInitComplete();\n\t\t\t\tDebug.Text( 'Promise: resolved with default callback.', 'TTPromise.js', 'TTPromise.js', 'wait', 11 );\n\t\t\t};\n\t\t}\n\n\t\tif ( typeof error_callback != 'function' ) {\n\t\t\terror_callback = function() {\n\t\t\t\tGlobal.setUIInitComplete();\n\t\t\t\tDebug.Text( 'Promise failed with default callback.', 'TTPromise.js', 'TTPromise.js', 'wait', 1 );\n\t\t\t};\n\t\t}\n\n\t\tif ( Object.keys( TTPromise.promises ).length > 0 ) {\n\t\t\tvar onComplete = function() {\n\t\t\t\tfor ( var i = 0; i < arguments.length; i++ ) {\n\t\t\t\t\t//numerically indexed arguments come back from Promise resolution arguments.\n\t\t\t\t\tvar obj = arguments[i];\n\n\t\t\t\t\tvar category = obj.category;\n\t\t\t\t\tvar key = obj.key;\n\t\t\t\t\tvar wait_category = obj.wait_arguments.category;\n\t\t\t\t\tvar wait_key = obj.wait_arguments.key;\n\n\t\t\t\t\tTTPromise.clearCompletedPromise( category, key );\n\t\t\t\t}\n\n\t\t\t\tif ( !wait_category || TTPromise.filterPromiseArray( wait_category, wait_key ).length == 0 ) {\n\t\t\t\t\tDebug.Text( 'Promise: success callback', 'TTPromise.js', 'TTPromise.js', 'wait', 11 );\n\t\t\t\t\tsuccess_callback( true );\n\t\t\t\t} else {\n\t\t\t\t\tDebug.Text( 'Promise: waiting again ' + category + '|' + key, 'TTPromise.js', 'TTPromise.js', 'wait', 11 );\n\t\t\t\t\tTTPromise.wait( category, key, success_callback, error_callback );\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t};\n\n\t\t\tvar onError = function() {\n\t\t\t\t//When one promise fails in a category, we need to call the error_callback if waiting on that category, and *never* call the success callback.\n\t\t\t\tDebug.Text( 'Promise: ERROR callback', 'TTPromise.js', 'TTPromise.js', 'wait', 11 );\n\t\t\t\tfor ( var i = 0; i < arguments.length; i++ ) {\n\t\t\t\t\t//numerically indexed arguments come back from Promise resolution arguments.\n\t\t\t\t\tvar obj = arguments[i];\n\n\t\t\t\t\tvar category = obj.category;\n\t\t\t\t\tvar key = obj.key;\n\t\t\t\t\tvar wait_category = obj.wait_arguments.category;\n\t\t\t\t\tvar wait_key = obj.wait_arguments.key;\n\n\t\t\t\t\tTTPromise.clearCompletedPromise( category, key );\n\t\t\t\t}\n\n\t\t\t\t//Different than success because we always want to call the error_callback immediately, as the category can never be success after a single error.\n\t\t\t\tif ( typeof error_callback != 'undefined' ) {\n\t\t\t\t\terror_callback( false );\n\t\t\t\t}\n\n\t\t\t\t//Don't wait again, as that will cause success/error callbacks to be triggered multiple times and could cause an infinite loop too.\n\t\t\t\t//TTPromise.wait( wait_category, wait_key, success_callback, error_callback );\n\t\t\t\treturn true;\n\t\t\t};\n\n\t\t\tvar pending_promises = this.filterPromiseArray( category, key );\n\t\t\t$.when.apply( $, pending_promises ).pipe( onComplete, onError );\n\n\t\t} else {\n\t\t\tsuccess_callback( true );\n\t\t}\n\t},\n\n\tfilterPromiseArray: function( category, key ) {\n\t\tvar retval = [];\n\t\tfor ( var c in this.promises ) {\n\t\t\tif ( !category || c == category ) {\n\n\t\t\t\t//Debug.Text('Promise: processing category: '+ c, 'TTPromise.js', 'TTPromise.js', 'pending_to_waiting', 11);\n\t\t\t\tfor ( var k in this.promises[c] ) {\n\t\t\t\t\tif ( !key || k == key ) {\n\t\t\t\t\t\t//Debug.Text('Promise: processing key: '+ c+'|'+k, 'TTPromise.js', 'TTPromise.js', 'pending_to_waiting', 11);\n\t\t\t\t\t\tthis.promises[c][k].extra_data.wait_arguments = { category: category, key: key };\n\t\t\t\t\t\tretval.push( this.promises[c][k] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t//Debug.Text('Promise: ignoring key: '+ k, 'TTPromise.js', 'TTPromise.js', 'pending_to_waiting', 11);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t//Debug.Text('Promise: ignoring category: '+ c, 'TTPromise.js', 'TTPromise.js', 'pending_to_waiting', 11);\n\t\t\t}\n\t\t}\n\t\treturn retval;\n\t},\n\n\tclearCompletedPromise: function( category, key ) {\n\t\tif ( this.promises && category && key ) {\n\t\t\tif ( this.promises[category] && this.promises[category][key] ) {\n\t\t\t\tthis.promises[category][key] = false;\n\t\t\t\tdelete this.promises[category][key];\n\t\t\t\tDebug.Text( 'Promise: clear category: ' + category + '|' + key, 'TTPromise.js', 'TTPromise.js', 'init', 11 );\n\t\t\t}\n\n\t\t\tif ( this.promises[category] && Object.keys( this.promises[category] ).length == 0 ) {\n\t\t\t\tthis.promises[category] = false;\n\t\t\t\tDebug.Text( 'Promise: clear category: ' + category, 'TTPromise.js', 'TTPromise.js', 'init', 11 );\n\t\t\t\tdelete this.promises[category];\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t//clear existing promises (mostly for testing and first add)\n\tclearAllPromises: function() {\n\t\tDebug.Text( 'Promise: clear all promises.', 'TTPromise.js', 'TTPromise.js', 'init', 11 );\n\t\tthis.promises = {};\n\t},\n\n\tisPendingPromises: function( category, key ) {\n\t\tvar p = TTPromise.filterPromiseArray( category, key );\n\n\t\tvar pending_count = 0;\n\t\tfor ( var n in p ) {\n\t\t\tif ( p[n] && p[n].state() == 'pending' ) {\n\t\t\t\tconsole.debug( 'Category: ' + p[n].extra_data.category + ' Key: ' + p[n].extra_data.key + ' State: ' + p[n].state() );\n\t\t\t\tpending_count++;\n\t\t\t}\n\t\t}\n\n\t\tif ( pending_count > 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t},\n\n\tdebugPromises: function( category, key ) {\n\t\tvar p = TTPromise.filterPromiseArray( category, key );\n\n\t\tfor ( var n in p ) {\n\t\t\tconsole.debug( 'Category: ' + p[n].extra_data.category + ' Key: ' + p[n].extra_data.key + ' State: ' + p[n].state() );\n\t\t}\n\n\t\treturn true;\n\t}\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTUwNC5qcyIsIm1hcHBpbmdzIjoiOzs7O0FBQU87QUFDUCxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQ0FBa0MsQ0FBQztBQUNuQywrQ0FBK0M7QUFDL0MsSUFBSTtBQUNKO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLHNCQUFzQjtBQUMzQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixzQkFBc0I7QUFDM0M7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRyxDQUFDLGFBQWEsQ0FBQzs7QUFFbEIsSUFBSTtBQUNKO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0RBQXdEO0FBQ3hEO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvVFRQcm9taXNlLmpzPzFlZTQiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHZhciBUVFByb21pc2UgPSB7XG5cdHByb21pc2VzOiB7fSxcblxuXHRhZGQ6IGZ1bmN0aW9uKCBjYXRlZ29yeSwga2V5ICkge1xuXHRcdGlmICggIXRoaXMucHJvbWlzZXNbY2F0ZWdvcnldIHx8ICF0aGlzLnByb21pc2VzW2NhdGVnb3J5XVtrZXldIHx8ICggdGhpcy5wcm9taXNlc1tjYXRlZ29yeV1ba2V5XS5zdGF0ZSgpICE9ICdwZW5kaW5nJyApICkge1xuXHRcdFx0RGVidWcuVGV4dCggJ1Byb21pc2U6IGFkZDogJyArIGNhdGVnb3J5ICsgJ3wnICsga2V5LCAnVFRQcm9taXNlLmpzJywgJ1RUUHJvbWlzZS5qcycsICdhZGQnLCAxMSApO1xuXHRcdFx0aWYgKCB0eXBlb2YgdGhpcy5wcm9taXNlc1tjYXRlZ29yeV0gPT0gJ3VuZGVmaW5lZCcgKSB7XG5cdFx0XHRcdHRoaXMucHJvbWlzZXNbY2F0ZWdvcnldID0ge307XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMucHJvbWlzZXNbY2F0ZWdvcnldW2tleV0gPSAkLkRlZmVycmVkKCk7XG5cdFx0XHR0aGlzLnByb21pc2VzW2NhdGVnb3J5XVtrZXldLmV4dHJhX2RhdGEgPSB7IGNhdGVnb3J5OiBjYXRlZ29yeSwga2V5OiBrZXkgfTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0RGVidWcuVGV4dCggJ1Byb21pc2U6IGFscmVhZHkgZXhpc3RzOiAnICsgY2F0ZWdvcnkgKyAnfCcgKyBrZXksICdUVFByb21pc2UuanMnLCAnVFRQcm9taXNlLmpzJywgJ2FkZCcsIDExICk7XG5cdFx0fVxuXHR9LFxuXG5cdHJlc29sdmU6IGZ1bmN0aW9uKCBjYXRlZ29yeSwga2V5ICkge1xuXHRcdGlmICggdGhpcy5wcm9taXNlcyAmJiB0aGlzLnByb21pc2VzW2NhdGVnb3J5XSAmJiB0aGlzLnByb21pc2VzW2NhdGVnb3J5XVtrZXldICkge1xuXHRcdFx0RGVidWcuVGV4dCggJ1Byb21pc2U6IHJlc29sdmVkOiAnICsgY2F0ZWdvcnkgKyAnfCcgKyBrZXksICdUVFByb21pc2UuanMnLCAnVFRQcm9taXNlLmpzJywgJ3Jlc29sdmUnLCAxMSApO1xuXHRcdFx0dGhpcy5wcm9taXNlc1tjYXRlZ29yeV1ba2V5XS5yZXNvbHZlKCB0aGlzLnByb21pc2VzW2NhdGVnb3J5XVtrZXldLmV4dHJhX2RhdGEgKTtcblx0XHR9XG5cdH0sXG5cblx0cmVqZWN0OiBmdW5jdGlvbiggY2F0ZWdvcnksIGtleSApIHtcblx0XHRpZiAoIHRoaXMucHJvbWlzZXMgJiYgdGhpcy5wcm9taXNlc1tjYXRlZ29yeV0gJiYgdGhpcy5wcm9taXNlc1tjYXRlZ29yeV1ba2V5XSApIHtcblx0XHRcdERlYnVnLlRleHQoICdQcm9taXNlOiByZWplY3RlZDogJyArIGNhdGVnb3J5ICsgJ3wnICsga2V5LCAnVFRQcm9taXNlLmpzJywgJ1RUUHJvbWlzZS5qcycsICdyZWplY3QnLCAxMSApO1xuXHRcdFx0dGhpcy5wcm9taXNlc1tjYXRlZ29yeV1ba2V5XS5yZWplY3QoIHRoaXMucHJvbWlzZXNbY2F0ZWdvcnldW2tleV0uZXh0cmFfZGF0YSApO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogV2FpdCBmb3IgYWxsIG9yIHNwZWNpZmljIGNhdGVnb3J5L2tleVxuXHQgKlxuXHQgKiBJbiB0aGUgY2FzZSBvZiB3YWl0aW5nIG9uIGFsbCBwcm9taXNlcywgZXJyb3JfY2FsbGJhY2sgaXMgdHJpZ2dlcmVkIGZvciBlYWNoIGluZGl2aWR1YWwgZXJyb3IgKHJlamVjdGlvbiksIGFuZCBzdWNjZXNzIGNhbGxiYWNrIGlzIGNhbGxlZCB3aGVuIGFsbCBwcm9taXNlcyBhcmUgcmVzb2x2ZWQgKGVpdGhlciBzdWNjZXNzIG9yIGZhaWx1cmUpXG5cdCAqIHNvIHdoZW4gd2FpdGluZyBmb3IgYWxsIHByb21pc2VzLCBtb3N0IHRpbWVzIHlvdSBkb24ndCB3YW50IGEgZmFpbHVyZSBjYWxsYmFjayBiZWNhdXNlIGJvdGggXCJzdWNjZXNzXCIgYW5kIFwiZmFpbHVyZVwiIGNhbiBoYXBwZW4gb24gdGhlIHNhbWUgd2FpdC5cblx0ICpcblx0ICogVGhlIGZ1bmN0aW9uIGNhbGwgc2hvdWxkIGxvb2sgbGlrZTpcblx0ICogICAgVFRQcm9taXNlLndhaXQobnVsbCxudWxsLGZ1bmN0aW9uKCl7XG5cdCAqICAgIFx0Ly9kbyBzdHVmZiBvbiBzdWNjZXNzXG5cdCAqICAgIH0pO1xuXHQgKlxuXHQgKiBAcGFyYW0gY2F0ZWdvcnlcblx0ICogQHBhcmFtIGtleVxuXHQgKiBAcGFyYW0gc3VjY2Vzc19jYWxsYmFja1xuXHQgKiBAcGFyYW0gZXJyb3JfY2FsbGJhY2tcblx0ICovXG5cdHdhaXQ6IGZ1bmN0aW9uKCBjYXRlZ29yeSwga2V5LCBzdWNjZXNzX2NhbGxiYWNrLCBlcnJvcl9jYWxsYmFjayApIHtcblx0XHREZWJ1Zy5BcnIoIGFyZ3VtZW50cywgJ1Byb21pc2U6IHdhaXQoJyArIGNhdGVnb3J5ICsgJ3wnICsga2V5ICsgJykuJywgJ1RUUHJvbWlzZS5qcycsICdUVFByb21pc2UuanMnLCAnd2FpdCcsIDExICk7XG5cdFx0aWYgKCB0eXBlb2Ygc3VjY2Vzc19jYWxsYmFjayAhPSAnZnVuY3Rpb24nICkge1xuXHRcdFx0c3VjY2Vzc19jYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRHbG9iYWwuc2V0VUlJbml0Q29tcGxldGUoKTtcblx0XHRcdFx0RGVidWcuVGV4dCggJ1Byb21pc2U6IHJlc29sdmVkIHdpdGggZGVmYXVsdCBjYWxsYmFjay4nLCAnVFRQcm9taXNlLmpzJywgJ1RUUHJvbWlzZS5qcycsICd3YWl0JywgMTEgKTtcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0aWYgKCB0eXBlb2YgZXJyb3JfY2FsbGJhY2sgIT0gJ2Z1bmN0aW9uJyApIHtcblx0XHRcdGVycm9yX2NhbGxiYWNrID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdEdsb2JhbC5zZXRVSUluaXRDb21wbGV0ZSgpO1xuXHRcdFx0XHREZWJ1Zy5UZXh0KCAnUHJvbWlzZSBmYWlsZWQgd2l0aCBkZWZhdWx0IGNhbGxiYWNrLicsICdUVFByb21pc2UuanMnLCAnVFRQcm9taXNlLmpzJywgJ3dhaXQnLCAxICk7XG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmICggT2JqZWN0LmtleXMoIFRUUHJvbWlzZS5wcm9taXNlcyApLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHR2YXIgb25Db21wbGV0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0Ly9udW1lcmljYWxseSBpbmRleGVkIGFyZ3VtZW50cyBjb21lIGJhY2sgZnJvbSBQcm9taXNlIHJlc29sdXRpb24gYXJndW1lbnRzLlxuXHRcdFx0XHRcdHZhciBvYmogPSBhcmd1bWVudHNbaV07XG5cblx0XHRcdFx0XHR2YXIgY2F0ZWdvcnkgPSBvYmouY2F0ZWdvcnk7XG5cdFx0XHRcdFx0dmFyIGtleSA9IG9iai5rZXk7XG5cdFx0XHRcdFx0dmFyIHdhaXRfY2F0ZWdvcnkgPSBvYmoud2FpdF9hcmd1bWVudHMuY2F0ZWdvcnk7XG5cdFx0XHRcdFx0dmFyIHdhaXRfa2V5ID0gb2JqLndhaXRfYXJndW1lbnRzLmtleTtcblxuXHRcdFx0XHRcdFRUUHJvbWlzZS5jbGVhckNvbXBsZXRlZFByb21pc2UoIGNhdGVnb3J5LCBrZXkgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggIXdhaXRfY2F0ZWdvcnkgfHwgVFRQcm9taXNlLmZpbHRlclByb21pc2VBcnJheSggd2FpdF9jYXRlZ29yeSwgd2FpdF9rZXkgKS5sZW5ndGggPT0gMCApIHtcblx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnUHJvbWlzZTogc3VjY2VzcyBjYWxsYmFjaycsICdUVFByb21pc2UuanMnLCAnVFRQcm9taXNlLmpzJywgJ3dhaXQnLCAxMSApO1xuXHRcdFx0XHRcdHN1Y2Nlc3NfY2FsbGJhY2soIHRydWUgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnUHJvbWlzZTogd2FpdGluZyBhZ2FpbiAnICsgY2F0ZWdvcnkgKyAnfCcgKyBrZXksICdUVFByb21pc2UuanMnLCAnVFRQcm9taXNlLmpzJywgJ3dhaXQnLCAxMSApO1xuXHRcdFx0XHRcdFRUUHJvbWlzZS53YWl0KCBjYXRlZ29yeSwga2V5LCBzdWNjZXNzX2NhbGxiYWNrLCBlcnJvcl9jYWxsYmFjayApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9O1xuXG5cdFx0XHR2YXIgb25FcnJvciA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvL1doZW4gb25lIHByb21pc2UgZmFpbHMgaW4gYSBjYXRlZ29yeSwgd2UgbmVlZCB0byBjYWxsIHRoZSBlcnJvcl9jYWxsYmFjayBpZiB3YWl0aW5nIG9uIHRoYXQgY2F0ZWdvcnksIGFuZCAqbmV2ZXIqIGNhbGwgdGhlIHN1Y2Nlc3MgY2FsbGJhY2suXG5cdFx0XHRcdERlYnVnLlRleHQoICdQcm9taXNlOiBFUlJPUiBjYWxsYmFjaycsICdUVFByb21pc2UuanMnLCAnVFRQcm9taXNlLmpzJywgJ3dhaXQnLCAxMSApO1xuXHRcdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0Ly9udW1lcmljYWxseSBpbmRleGVkIGFyZ3VtZW50cyBjb21lIGJhY2sgZnJvbSBQcm9taXNlIHJlc29sdXRpb24gYXJndW1lbnRzLlxuXHRcdFx0XHRcdHZhciBvYmogPSBhcmd1bWVudHNbaV07XG5cblx0XHRcdFx0XHR2YXIgY2F0ZWdvcnkgPSBvYmouY2F0ZWdvcnk7XG5cdFx0XHRcdFx0dmFyIGtleSA9IG9iai5rZXk7XG5cdFx0XHRcdFx0dmFyIHdhaXRfY2F0ZWdvcnkgPSBvYmoud2FpdF9hcmd1bWVudHMuY2F0ZWdvcnk7XG5cdFx0XHRcdFx0dmFyIHdhaXRfa2V5ID0gb2JqLndhaXRfYXJndW1lbnRzLmtleTtcblxuXHRcdFx0XHRcdFRUUHJvbWlzZS5jbGVhckNvbXBsZXRlZFByb21pc2UoIGNhdGVnb3J5LCBrZXkgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vRGlmZmVyZW50IHRoYW4gc3VjY2VzcyBiZWNhdXNlIHdlIGFsd2F5cyB3YW50IHRvIGNhbGwgdGhlIGVycm9yX2NhbGxiYWNrIGltbWVkaWF0ZWx5LCBhcyB0aGUgY2F0ZWdvcnkgY2FuIG5ldmVyIGJlIHN1Y2Nlc3MgYWZ0ZXIgYSBzaW5nbGUgZXJyb3IuXG5cdFx0XHRcdGlmICggdHlwZW9mIGVycm9yX2NhbGxiYWNrICE9ICd1bmRlZmluZWQnICkge1xuXHRcdFx0XHRcdGVycm9yX2NhbGxiYWNrKCBmYWxzZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly9Eb24ndCB3YWl0IGFnYWluLCBhcyB0aGF0IHdpbGwgY2F1c2Ugc3VjY2Vzcy9lcnJvciBjYWxsYmFja3MgdG8gYmUgdHJpZ2dlcmVkIG11bHRpcGxlIHRpbWVzIGFuZCBjb3VsZCBjYXVzZSBhbiBpbmZpbml0ZSBsb29wIHRvby5cblx0XHRcdFx0Ly9UVFByb21pc2Uud2FpdCggd2FpdF9jYXRlZ29yeSwgd2FpdF9rZXksIHN1Y2Nlc3NfY2FsbGJhY2ssIGVycm9yX2NhbGxiYWNrICk7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fTtcblxuXHRcdFx0dmFyIHBlbmRpbmdfcHJvbWlzZXMgPSB0aGlzLmZpbHRlclByb21pc2VBcnJheSggY2F0ZWdvcnksIGtleSApO1xuXHRcdFx0JC53aGVuLmFwcGx5KCAkLCBwZW5kaW5nX3Byb21pc2VzICkucGlwZSggb25Db21wbGV0ZSwgb25FcnJvciApO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHN1Y2Nlc3NfY2FsbGJhY2soIHRydWUgKTtcblx0XHR9XG5cdH0sXG5cblx0ZmlsdGVyUHJvbWlzZUFycmF5OiBmdW5jdGlvbiggY2F0ZWdvcnksIGtleSApIHtcblx0XHR2YXIgcmV0dmFsID0gW107XG5cdFx0Zm9yICggdmFyIGMgaW4gdGhpcy5wcm9taXNlcyApIHtcblx0XHRcdGlmICggIWNhdGVnb3J5IHx8IGMgPT0gY2F0ZWdvcnkgKSB7XG5cblx0XHRcdFx0Ly9EZWJ1Zy5UZXh0KCdQcm9taXNlOiBwcm9jZXNzaW5nIGNhdGVnb3J5OiAnKyBjLCAnVFRQcm9taXNlLmpzJywgJ1RUUHJvbWlzZS5qcycsICdwZW5kaW5nX3RvX3dhaXRpbmcnLCAxMSk7XG5cdFx0XHRcdGZvciAoIHZhciBrIGluIHRoaXMucHJvbWlzZXNbY10gKSB7XG5cdFx0XHRcdFx0aWYgKCAha2V5IHx8IGsgPT0ga2V5ICkge1xuXHRcdFx0XHRcdFx0Ly9EZWJ1Zy5UZXh0KCdQcm9taXNlOiBwcm9jZXNzaW5nIGtleTogJysgYysnfCcraywgJ1RUUHJvbWlzZS5qcycsICdUVFByb21pc2UuanMnLCAncGVuZGluZ190b193YWl0aW5nJywgMTEpO1xuXHRcdFx0XHRcdFx0dGhpcy5wcm9taXNlc1tjXVtrXS5leHRyYV9kYXRhLndhaXRfYXJndW1lbnRzID0geyBjYXRlZ29yeTogY2F0ZWdvcnksIGtleToga2V5IH07XG5cdFx0XHRcdFx0XHRyZXR2YWwucHVzaCggdGhpcy5wcm9taXNlc1tjXVtrXSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQvL0RlYnVnLlRleHQoJ1Byb21pc2U6IGlnbm9yaW5nIGtleTogJysgaywgJ1RUUHJvbWlzZS5qcycsICdUVFByb21pc2UuanMnLCAncGVuZGluZ190b193YWl0aW5nJywgMTEpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly9EZWJ1Zy5UZXh0KCdQcm9taXNlOiBpZ25vcmluZyBjYXRlZ29yeTogJysgYywgJ1RUUHJvbWlzZS5qcycsICdUVFByb21pc2UuanMnLCAncGVuZGluZ190b193YWl0aW5nJywgMTEpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gcmV0dmFsO1xuXHR9LFxuXG5cdGNsZWFyQ29tcGxldGVkUHJvbWlzZTogZnVuY3Rpb24oIGNhdGVnb3J5LCBrZXkgKSB7XG5cdFx0aWYgKCB0aGlzLnByb21pc2VzICYmIGNhdGVnb3J5ICYmIGtleSApIHtcblx0XHRcdGlmICggdGhpcy5wcm9taXNlc1tjYXRlZ29yeV0gJiYgdGhpcy5wcm9taXNlc1tjYXRlZ29yeV1ba2V5XSApIHtcblx0XHRcdFx0dGhpcy5wcm9taXNlc1tjYXRlZ29yeV1ba2V5XSA9IGZhbHNlO1xuXHRcdFx0XHRkZWxldGUgdGhpcy5wcm9taXNlc1tjYXRlZ29yeV1ba2V5XTtcblx0XHRcdFx0RGVidWcuVGV4dCggJ1Byb21pc2U6IGNsZWFyIGNhdGVnb3J5OiAnICsgY2F0ZWdvcnkgKyAnfCcgKyBrZXksICdUVFByb21pc2UuanMnLCAnVFRQcm9taXNlLmpzJywgJ2luaXQnLCAxMSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHRoaXMucHJvbWlzZXNbY2F0ZWdvcnldICYmIE9iamVjdC5rZXlzKCB0aGlzLnByb21pc2VzW2NhdGVnb3J5XSApLmxlbmd0aCA9PSAwICkge1xuXHRcdFx0XHR0aGlzLnByb21pc2VzW2NhdGVnb3J5XSA9IGZhbHNlO1xuXHRcdFx0XHREZWJ1Zy5UZXh0KCAnUHJvbWlzZTogY2xlYXIgY2F0ZWdvcnk6ICcgKyBjYXRlZ29yeSwgJ1RUUHJvbWlzZS5qcycsICdUVFByb21pc2UuanMnLCAnaW5pdCcsIDExICk7XG5cdFx0XHRcdGRlbGV0ZSB0aGlzLnByb21pc2VzW2NhdGVnb3J5XTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9LFxuXG5cdC8vY2xlYXIgZXhpc3RpbmcgcHJvbWlzZXMgKG1vc3RseSBmb3IgdGVzdGluZyBhbmQgZmlyc3QgYWRkKVxuXHRjbGVhckFsbFByb21pc2VzOiBmdW5jdGlvbigpIHtcblx0XHREZWJ1Zy5UZXh0KCAnUHJvbWlzZTogY2xlYXIgYWxsIHByb21pc2VzLicsICdUVFByb21pc2UuanMnLCAnVFRQcm9taXNlLmpzJywgJ2luaXQnLCAxMSApO1xuXHRcdHRoaXMucHJvbWlzZXMgPSB7fTtcblx0fSxcblxuXHRpc1BlbmRpbmdQcm9taXNlczogZnVuY3Rpb24oIGNhdGVnb3J5LCBrZXkgKSB7XG5cdFx0dmFyIHAgPSBUVFByb21pc2UuZmlsdGVyUHJvbWlzZUFycmF5KCBjYXRlZ29yeSwga2V5ICk7XG5cblx0XHR2YXIgcGVuZGluZ19jb3VudCA9IDA7XG5cdFx0Zm9yICggdmFyIG4gaW4gcCApIHtcblx0XHRcdGlmICggcFtuXSAmJiBwW25dLnN0YXRlKCkgPT0gJ3BlbmRpbmcnICkge1xuXHRcdFx0XHRjb25zb2xlLmRlYnVnKCAnQ2F0ZWdvcnk6ICcgKyBwW25dLmV4dHJhX2RhdGEuY2F0ZWdvcnkgKyAnIEtleTogJyArIHBbbl0uZXh0cmFfZGF0YS5rZXkgKyAnIFN0YXRlOiAnICsgcFtuXS5zdGF0ZSgpICk7XG5cdFx0XHRcdHBlbmRpbmdfY291bnQrKztcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIHBlbmRpbmdfY291bnQgPiAwICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9LFxuXG5cdGRlYnVnUHJvbWlzZXM6IGZ1bmN0aW9uKCBjYXRlZ29yeSwga2V5ICkge1xuXHRcdHZhciBwID0gVFRQcm9taXNlLmZpbHRlclByb21pc2VBcnJheSggY2F0ZWdvcnksIGtleSApO1xuXG5cdFx0Zm9yICggdmFyIG4gaW4gcCApIHtcblx0XHRcdGNvbnNvbGUuZGVidWcoICdDYXRlZ29yeTogJyArIHBbbl0uZXh0cmFfZGF0YS5jYXRlZ29yeSArICcgS2V5OiAnICsgcFtuXS5leHRyYV9kYXRhLmtleSArICcgU3RhdGU6ICcgKyBwW25dLnN0YXRlKCkgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9504\n")},4936:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"d\": () => (/* binding */ TTUUID)\n/* harmony export */ });\nvar TTUUID = function() {\n};\n\nTTUUID.zero_id = '00000000-0000-0000-0000-000000000000';\nTTUUID.not_exist_id = 'ffffffff-ffff-ffff-ffff-ffffffffffff';\n\nTTUUID.counter = 0;\n\nTTUUID.generateUUID = function( seed ) {\n\tif ( !seed && LocalCacheData && LocalCacheData.loginUser && LocalCacheData.loginUser.id ) {\n\t\tvar user_id = LocalCacheData.loginUser.id.split( '-' );\n\t\tseed = user_id[1] + user_id[2] + user_id[3];\n\t}\n\n\tif ( seed == null || seed.length != 12 ) {\n\t\tseed = ( TTUUID.randomUI08() | 1 ) * 0x10000000000 + TTUUID.randomUI40();\n\t}\n\n\tvar sequence = TTUUID.randomUI14();\n\tvar node = seed;\n\tvar tick = TTUUID.randomUI04();\n\tvar timestamp = new Date().getTime();\n\n\t//Helps ensure no duplicate UUIDs in a tight loop.\n\ttimestamp += TTUUID.counter;\n\tTTUUID.counter += 1;\n\n\tvar tf = TTUUID.getTimeFieldValues( timestamp );\n\tvar tl = tf.low + tick;\n\tvar thav = ( tf.hi & 0xFFF ) | 0x1000;\n\n\tsequence &= 0x3FFF;\n\tvar cshar = ( sequence >>> 8 ) | 0x80;\n\tvar csl = sequence & 0xFF;\n\n\treturn TTUUID.fromParts( tl, tf.mid, thav, cshar, csl, node );\n};\n\nTTUUID.castUUID = function( uuid ) {\n\t//allow nulls for cases where the column allows it.\n\tif ( uuid === null || TTUUID.isUUID( uuid ) == true ) {\n\t\treturn uuid;\n\t}\n\n\treturn TTUUID.zero_id;\n};\n\nTTUUID.isUUID = function( uuid ) {\n\tvar regex = new RegExp( '[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}' );\n\tif ( uuid != '' && regex.test( uuid ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\nTTUUID.fromParts = function( timeLow, timeMid, timeHiAndVersion, clockSeqHiAndReserved, clockSeqLow, node ) {\n\tvar hex =\n\t\tTTUUID.paddedString( timeHiAndVersion.toString( 16 ), 4 ) + TTUUID.paddedString( timeMid.toString( 16 ), 4 )\n\t\t+ '-' + TTUUID.paddedString( timeLow.toString( 16 ).substring( 0, 4 ), 4 )\n\t\t+ '-' + TTUUID.paddedString( timeLow.toString( 16 ).substring( 5, 8 ), 4 )\n\t\t+ '-' + TTUUID.paddedString( clockSeqHiAndReserved.toString( 16 ), 2 ) + TTUUID.paddedString( clockSeqLow.toString( 16 ), 2 )\n\t\t+ '-' + node.toString().substring( 0, 12 );\n\n\treturn hex;\n};\n\nTTUUID.maxFromBits = function( bits ) {\n\treturn Math.pow( 2, bits );\n};\n\nTTUUID.limitUI04 = TTUUID.maxFromBits( 4 );\nTTUUID.limitUI08 = TTUUID.maxFromBits( 8 );\nTTUUID.limitUI14 = TTUUID.maxFromBits( 14 );\nTTUUID.limitUI16 = TTUUID.maxFromBits( 16 );\nTTUUID.limitUI40 = TTUUID.maxFromBits( 40 );\n\nTTUUID.randomUI04 = function() {\n\treturn TTUUID.getRandomInt( 0, ( TTUUID.limitUI04 - 1 ) );\n};\n\nTTUUID.randomUI08 = function() {\n\treturn TTUUID.getRandomInt( 0, ( TTUUID.limitUI08 - 1 ) );\n};\n\nTTUUID.randomUI14 = function() {\n\treturn TTUUID.getRandomInt( 0, ( TTUUID.limitUI14 - 1 ) );\n};\n\nTTUUID.randomUI40 = function() {\n\treturn ( 0 | Math.random() * ( 1 << 30 ) ) + ( 0 | Math.random() * ( 1 << 40 - 30 ) ) * ( 1 << 30 );\n};\n\nTTUUID.getTimeFieldValues = function( time ) {\n\tvar ts = time - Date.UTC( 1582, 9, 15 );\n\tvar hm = ( ( ts / 0x100000000 ) * 10000 ) & 0xFFFFFFF;\n\treturn { low: ( ( ts & 0xFFFFFFF ) * 10000 ) % 0x100000000, mid: hm & 0xFFFF, hi: hm >>> 16, timestamp: ts };\n};\n\nTTUUID.paddedString = function( string, length, z ) {\n\tstring = String( string );\n\tz = ( !z ) ? '0' : z;\n\tvar i = length - string.length;\n\tfor ( ; i > 0; i >>>= 1, z += z ) {\n\t\tif ( i & 1 ) {\n\t\t\tstring = z + string;\n\t\t}\n\t}\n\treturn string;\n};\n\nTTUUID.getRandomInt = function( min, max ) {\n\tvar random_num;\n\n\tvar crypto_obj = window.crypto || window.msCrypto; // for IE 11\n\tif ( crypto_obj ) {\n\t\tvar byte_array = new Uint8Array( 1 );\n\t\tcrypto_obj.getRandomValues( byte_array );\n\n\t\trandom_num = '0.' + byte_array[0].toString();\n\t} else {\n\t\trandom_num = Math.random();\n\t}\n\n\trandom_num = Math.floor( random_num * ( max - min + 1 ) ) + min;\n\n\treturn random_num;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDkzNi5qcyIsIm1hcHBpbmdzIjoiOzs7QUFBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxzQ0FBc0MsRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxhQUFhLEdBQUc7QUFDckc7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxPQUFPO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLG9EQUFvRDtBQUNwRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC9UVFVVSUQuanM/MjY5NCJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdmFyIFRUVVVJRCA9IGZ1bmN0aW9uKCkge1xufTtcblxuVFRVVUlELnplcm9faWQgPSAnMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwJztcblRUVVVJRC5ub3RfZXhpc3RfaWQgPSAnZmZmZmZmZmYtZmZmZi1mZmZmLWZmZmYtZmZmZmZmZmZmZmZmJztcblxuVFRVVUlELmNvdW50ZXIgPSAwO1xuXG5UVFVVSUQuZ2VuZXJhdGVVVUlEID0gZnVuY3Rpb24oIHNlZWQgKSB7XG5cdGlmICggIXNlZWQgJiYgTG9jYWxDYWNoZURhdGEgJiYgTG9jYWxDYWNoZURhdGEubG9naW5Vc2VyICYmIExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlci5pZCApIHtcblx0XHR2YXIgdXNlcl9pZCA9IExvY2FsQ2FjaGVEYXRhLmxvZ2luVXNlci5pZC5zcGxpdCggJy0nICk7XG5cdFx0c2VlZCA9IHVzZXJfaWRbMV0gKyB1c2VyX2lkWzJdICsgdXNlcl9pZFszXTtcblx0fVxuXG5cdGlmICggc2VlZCA9PSBudWxsIHx8IHNlZWQubGVuZ3RoICE9IDEyICkge1xuXHRcdHNlZWQgPSAoIFRUVVVJRC5yYW5kb21VSTA4KCkgfCAxICkgKiAweDEwMDAwMDAwMDAwICsgVFRVVUlELnJhbmRvbVVJNDAoKTtcblx0fVxuXG5cdHZhciBzZXF1ZW5jZSA9IFRUVVVJRC5yYW5kb21VSTE0KCk7XG5cdHZhciBub2RlID0gc2VlZDtcblx0dmFyIHRpY2sgPSBUVFVVSUQucmFuZG9tVUkwNCgpO1xuXHR2YXIgdGltZXN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cblx0Ly9IZWxwcyBlbnN1cmUgbm8gZHVwbGljYXRlIFVVSURzIGluIGEgdGlnaHQgbG9vcC5cblx0dGltZXN0YW1wICs9IFRUVVVJRC5jb3VudGVyO1xuXHRUVFVVSUQuY291bnRlciArPSAxO1xuXG5cdHZhciB0ZiA9IFRUVVVJRC5nZXRUaW1lRmllbGRWYWx1ZXMoIHRpbWVzdGFtcCApO1xuXHR2YXIgdGwgPSB0Zi5sb3cgKyB0aWNrO1xuXHR2YXIgdGhhdiA9ICggdGYuaGkgJiAweEZGRiApIHwgMHgxMDAwO1xuXG5cdHNlcXVlbmNlICY9IDB4M0ZGRjtcblx0dmFyIGNzaGFyID0gKCBzZXF1ZW5jZSA+Pj4gOCApIHwgMHg4MDtcblx0dmFyIGNzbCA9IHNlcXVlbmNlICYgMHhGRjtcblxuXHRyZXR1cm4gVFRVVUlELmZyb21QYXJ0cyggdGwsIHRmLm1pZCwgdGhhdiwgY3NoYXIsIGNzbCwgbm9kZSApO1xufTtcblxuVFRVVUlELmNhc3RVVUlEID0gZnVuY3Rpb24oIHV1aWQgKSB7XG5cdC8vYWxsb3cgbnVsbHMgZm9yIGNhc2VzIHdoZXJlIHRoZSBjb2x1bW4gYWxsb3dzIGl0LlxuXHRpZiAoIHV1aWQgPT09IG51bGwgfHwgVFRVVUlELmlzVVVJRCggdXVpZCApID09IHRydWUgKSB7XG5cdFx0cmV0dXJuIHV1aWQ7XG5cdH1cblxuXHRyZXR1cm4gVFRVVUlELnplcm9faWQ7XG59O1xuXG5UVFVVSUQuaXNVVUlEID0gZnVuY3Rpb24oIHV1aWQgKSB7XG5cdHZhciByZWdleCA9IG5ldyBSZWdFeHAoICdbYS16QS1aMC05XXs4fS1bYS16QS1aMC05XXs0fS1bYS16QS1aMC05XXs0fS1bYS16QS1aMC05XXs0fS1bYS16QS1aMC05XXsxMn0nICk7XG5cdGlmICggdXVpZCAhPSAnJyAmJiByZWdleC50ZXN0KCB1dWlkICkgKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRyZXR1cm4gZmFsc2U7XG59O1xuXG5UVFVVSUQuZnJvbVBhcnRzID0gZnVuY3Rpb24oIHRpbWVMb3csIHRpbWVNaWQsIHRpbWVIaUFuZFZlcnNpb24sIGNsb2NrU2VxSGlBbmRSZXNlcnZlZCwgY2xvY2tTZXFMb3csIG5vZGUgKSB7XG5cdHZhciBoZXggPVxuXHRcdFRUVVVJRC5wYWRkZWRTdHJpbmcoIHRpbWVIaUFuZFZlcnNpb24udG9TdHJpbmcoIDE2ICksIDQgKSArIFRUVVVJRC5wYWRkZWRTdHJpbmcoIHRpbWVNaWQudG9TdHJpbmcoIDE2ICksIDQgKVxuXHRcdCsgJy0nICsgVFRVVUlELnBhZGRlZFN0cmluZyggdGltZUxvdy50b1N0cmluZyggMTYgKS5zdWJzdHJpbmcoIDAsIDQgKSwgNCApXG5cdFx0KyAnLScgKyBUVFVVSUQucGFkZGVkU3RyaW5nKCB0aW1lTG93LnRvU3RyaW5nKCAxNiApLnN1YnN0cmluZyggNSwgOCApLCA0IClcblx0XHQrICctJyArIFRUVVVJRC5wYWRkZWRTdHJpbmcoIGNsb2NrU2VxSGlBbmRSZXNlcnZlZC50b1N0cmluZyggMTYgKSwgMiApICsgVFRVVUlELnBhZGRlZFN0cmluZyggY2xvY2tTZXFMb3cudG9TdHJpbmcoIDE2ICksIDIgKVxuXHRcdCsgJy0nICsgbm9kZS50b1N0cmluZygpLnN1YnN0cmluZyggMCwgMTIgKTtcblxuXHRyZXR1cm4gaGV4O1xufTtcblxuVFRVVUlELm1heEZyb21CaXRzID0gZnVuY3Rpb24oIGJpdHMgKSB7XG5cdHJldHVybiBNYXRoLnBvdyggMiwgYml0cyApO1xufTtcblxuVFRVVUlELmxpbWl0VUkwNCA9IFRUVVVJRC5tYXhGcm9tQml0cyggNCApO1xuVFRVVUlELmxpbWl0VUkwOCA9IFRUVVVJRC5tYXhGcm9tQml0cyggOCApO1xuVFRVVUlELmxpbWl0VUkxNCA9IFRUVVVJRC5tYXhGcm9tQml0cyggMTQgKTtcblRUVVVJRC5saW1pdFVJMTYgPSBUVFVVSUQubWF4RnJvbUJpdHMoIDE2ICk7XG5UVFVVSUQubGltaXRVSTQwID0gVFRVVUlELm1heEZyb21CaXRzKCA0MCApO1xuXG5UVFVVSUQucmFuZG9tVUkwNCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gVFRVVUlELmdldFJhbmRvbUludCggMCwgKCBUVFVVSUQubGltaXRVSTA0IC0gMSApICk7XG59O1xuXG5UVFVVSUQucmFuZG9tVUkwOCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gVFRVVUlELmdldFJhbmRvbUludCggMCwgKCBUVFVVSUQubGltaXRVSTA4IC0gMSApICk7XG59O1xuXG5UVFVVSUQucmFuZG9tVUkxNCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gVFRVVUlELmdldFJhbmRvbUludCggMCwgKCBUVFVVSUQubGltaXRVSTE0IC0gMSApICk7XG59O1xuXG5UVFVVSUQucmFuZG9tVUk0MCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gKCAwIHwgTWF0aC5yYW5kb20oKSAqICggMSA8PCAzMCApICkgKyAoIDAgfCBNYXRoLnJhbmRvbSgpICogKCAxIDw8IDQwIC0gMzAgKSApICogKCAxIDw8IDMwICk7XG59O1xuXG5UVFVVSUQuZ2V0VGltZUZpZWxkVmFsdWVzID0gZnVuY3Rpb24oIHRpbWUgKSB7XG5cdHZhciB0cyA9IHRpbWUgLSBEYXRlLlVUQyggMTU4MiwgOSwgMTUgKTtcblx0dmFyIGhtID0gKCAoIHRzIC8gMHgxMDAwMDAwMDAgKSAqIDEwMDAwICkgJiAweEZGRkZGRkY7XG5cdHJldHVybiB7IGxvdzogKCAoIHRzICYgMHhGRkZGRkZGICkgKiAxMDAwMCApICUgMHgxMDAwMDAwMDAsIG1pZDogaG0gJiAweEZGRkYsIGhpOiBobSA+Pj4gMTYsIHRpbWVzdGFtcDogdHMgfTtcbn07XG5cblRUVVVJRC5wYWRkZWRTdHJpbmcgPSBmdW5jdGlvbiggc3RyaW5nLCBsZW5ndGgsIHogKSB7XG5cdHN0cmluZyA9IFN0cmluZyggc3RyaW5nICk7XG5cdHogPSAoICF6ICkgPyAnMCcgOiB6O1xuXHR2YXIgaSA9IGxlbmd0aCAtIHN0cmluZy5sZW5ndGg7XG5cdGZvciAoIDsgaSA+IDA7IGkgPj4+PSAxLCB6ICs9IHogKSB7XG5cdFx0aWYgKCBpICYgMSApIHtcblx0XHRcdHN0cmluZyA9IHogKyBzdHJpbmc7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBzdHJpbmc7XG59O1xuXG5UVFVVSUQuZ2V0UmFuZG9tSW50ID0gZnVuY3Rpb24oIG1pbiwgbWF4ICkge1xuXHR2YXIgcmFuZG9tX251bTtcblxuXHR2YXIgY3J5cHRvX29iaiA9IHdpbmRvdy5jcnlwdG8gfHwgd2luZG93Lm1zQ3J5cHRvOyAvLyBmb3IgSUUgMTFcblx0aWYgKCBjcnlwdG9fb2JqICkge1xuXHRcdHZhciBieXRlX2FycmF5ID0gbmV3IFVpbnQ4QXJyYXkoIDEgKTtcblx0XHRjcnlwdG9fb2JqLmdldFJhbmRvbVZhbHVlcyggYnl0ZV9hcnJheSApO1xuXG5cdFx0cmFuZG9tX251bSA9ICcwLicgKyBieXRlX2FycmF5WzBdLnRvU3RyaW5nKCk7XG5cdH0gZWxzZSB7XG5cdFx0cmFuZG9tX251bSA9IE1hdGgucmFuZG9tKCk7XG5cdH1cblxuXHRyYW5kb21fbnVtID0gTWF0aC5mbG9vciggcmFuZG9tX251bSAqICggbWF4IC0gbWluICsgMSApICkgKyBtaW47XG5cblx0cmV0dXJuIHJhbmRvbV9udW07XG59OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4936\n")},5519:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/* provided dependency */ var jQuery = __webpack_require__(9755);\n( function( $ ) {\n\n\t$.fn.TComboBox = function( options ) {\n\t\tvar opts = $.extend( {}, $.fn.TComboBox.defaults, options );\n\t\tvar $this = this;\n\t\tvar field;\n\t\tvar source_data = null;\n\n\t\tvar select_value = null;\n\n\t\tvar set_empty = false;\n\n\t\tvar set_any = false;\n\n\t\tvar set_select_item_when_set_source_data = false;\n\n\t\tvar error_string = '';\n\n\t\tvar error_tip_box;\n\n\t\tvar mass_edit_mode = false;\n\n\t\tvar check_box = null;\n\n\t\tvar enabled = true;\n\n\t\tvar valueKey = 'value';\n\n\t\tvar labelKey = 'label';\n\n\t\tvar customFirstItemLabel = '';\n\n\t\tthis.setValueKey = function( val ) {\n\t\t\tvalueKey = val;\n\t\t};\n\n\t\tthis.setLabelKey = function( val ) {\n\t\t\tlabelKey = val;\n\t\t};\n\n\t\tthis.getEnabled = function() {\n\t\t\treturn enabled;\n\t\t};\n\n\t\tthis.setEnabled = function( val ) {\n\t\t\tenabled = val;\n\n\t\t\tif ( val === false || val === '' ) {\n\t\t\t\t$this.attr( 'disabled', 'true' );\n\t\t\t\t$this.addClass( 't-select-readonly' );\n\t\t\t} else {\n\t\t\t\t$this.removeAttr( 'disabled' );\n\t\t\t\t$this.removeClass( 't-select-readonly' );\n\t\t\t}\n\n\t\t};\n\n\t\tthis.setCheckBox = function( val ) {\n\t\t\tif ( check_box ) {\n\t\t\t\tcheck_box.children().eq( 0 )[0].checked = val;\n\t\t\t}\n\t\t};\n\n\t\tthis.isChecked = function() {\n\t\t\tif ( check_box ) {\n\t\t\t\tif ( check_box.children().eq( 0 )[0].checked === true ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t};\n\n\t\tthis.setMassEditMode = function( val ) {\n\t\t\tmass_edit_mode = val;\n\n\t\t\tif ( mass_edit_mode ) {\n\t\t\t\tcheck_box = $( '
    ' +\n\t\t\t\t\t'
    ' );\n\t\t\t\tcheck_box.insertBefore( $( this ) );\n\n\t\t\t\tcheck_box.change( function() {\n\t\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tif ( check_box ) {\n\t\t\t\t\tcheck_box.remove();\n\t\t\t\t\tcheck_box = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.setErrorStyle = function( errStr, show, isWarning ) {\n\t\t\tif ( isWarning ) {\n\t\t\t\t$( this ).addClass( 'warning-tip' );\n\t\t\t} else {\n\t\t\t\t$( this ).addClass( 'error-tip' );\n\t\t\t}\n\t\t\terror_string = errStr;\n\n\t\t\tif ( show ) {\n\t\t\t\tthis.showErrorTip();\n\t\t\t}\n\t\t};\n\n\t\tthis.showErrorTip = function( sec ) {\n\n\t\t\tif ( !Global.isSet( sec ) ) {\n\t\t\t\tsec = 2;\n\t\t\t}\n\n\t\t\tif ( !error_tip_box ) {\n\t\t\t\terror_tip_box = Global.loadWidgetByName( WidgetNamesDic.ERROR_TOOLTIP );\n\t\t\t\terror_tip_box = error_tip_box.ErrorTipBox();\n\t\t\t}\n\t\t\tif ( $( this ).hasClass( 'warning-tip' ) ) {\n\t\t\t\terror_tip_box.show( this, error_string, sec, true );\n\t\t\t} else {\n\t\t\t\terror_tip_box.show( this, error_string, sec );\n\t\t\t}\n\t\t};\n\n\t\tthis.hideErrorTip = function() {\n\n\t\t\tif ( Global.isSet( error_tip_box ) ) {\n\t\t\t\terror_tip_box.remove();\n\t\t\t}\n\n\t\t};\n\n\t\tthis.clearErrorStyle = function() {\n\t\t\t$( this ).removeClass( 'error-tip' );\n\t\t\t$( this ).removeClass( 'warning-tip' );\n\t\t\tthis.hideErrorTip();\n\t\t\terror_string = '';\n\t\t};\n\n\t\tthis.setField = function( val ) {\n\t\t\tfield = val;\n\t\t};\n\n\t\tthis.getField = function() {\n\t\t\treturn field;\n\t\t};\n\n\t\tthis.getLabel = function() {\n\n\t\t\tif ( !source_data || ( set_empty && source_data.length === 1 ) || ( set_any && source_data.length === 1 ) ) {\n\t\t\t\treturn select_value;\n\t\t\t}\n\t\t\t//if value is number convert to number type\n\t\t\tvar value = $( this ).children( 'option:selected' ).text();\n\n\t\t\treturn value;\n\t\t};\n\n\t\tthis.getValue = function() {\n\n\t\t\tif ( !source_data || ( set_empty && source_data.length === 1 ) || ( set_any && source_data.length === 1 ) ) {\n\t\t\t\treturn select_value;\n\t\t\t}\n\n\t\t\t//if value is number convert to number type\n\t\t\tvar value = $( this ).children( 'option:selected' ).attr( 'value' );\n\n\t\t\t//#2624 - Avoid parsing float value if we have a value larger than zero with a leading zero so that numeric string (eg province) ISO codes are not converted from '01' to 1\n\t\t\tif ( $.isNumeric( value ) && ( value === '0' || value.toString()[0] !== '0' ) ) {\n\t\t\t\tvalue = parseFloat( value );\n\t\t\t}\n\n\t\t\tif ( value === -1 || value === '-1' ) {\n\t\t\t\tvalue = -1;\n\t\t\t}\n\t\t\treturn value;\n\t\t};\n\n\t\tthis.getSelectedIndex = function() {\n\t\t\treturn this[0].selectedIndex;\n\t\t};\n\n\t\tthis.setSelectedIndex = function( set_index ) {\n\t\t\tif ( set_index < 0 ) {\n\t\t\t\tset_index = 0;\n\t\t\t}\n\t\t\tif ( set_index >= this[0].length ) {\n\t\t\t\tset_index = this[0].length - 1;\n\t\t\t}\n\t\t\tthis[0].selectedIndex = set_index;\n\t\t\tthis.setValue( this[0].value );\n\t\t}\n\t\t;\n\t\tthis.getLabel = function() {\n\t\t\t//if value is number convert to number type\n\t\t\tvar value = $( this ).children( 'option:selected' ).text();\n\t\t\treturn value;\n\t\t};\n\n\t\tthis.setValue = function( val ) {\n\t\t\tselect_value = val;\n\n\t\t\tif ( !source_data || source_data.length < 1 || ( set_empty && source_data.length === 1 ) || ( set_any && source_data.length === 1 ) ) {\n\t\t\t\tset_select_item_when_set_source_data = true;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t//When no value == undefined or null or default false\n\t\t\tif ( !Global.isSet( val ) || val === false ) {\n\t\t\t\tif ( set_empty ) {\n\t\t\t\t\tval = TTUUID.zero_id;\n\t\t\t\t} else if ( set_any ) {\n\t\t\t\t\tval = TTUUID.not_exist_id;\n\t\t\t\t} else {\n\t\t\t\t\t//If no empty value, default to select first item\n\t\t\t\t\tif ( source_data && source_data.length > 0 ) {\n\t\t\t\t\t\tthis.setValue( source_data[0][valueKey] );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$( $( this ).find( 'option' ) ).removeAttr( 'selected' );\n\n\t\t\t$( $( this ).find( 'option' ) ).filter( function() {\n\t\t\t\tif ( val === null || val === undefined ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn $( this ).attr( 'value' ) === val.toString();\n\t\t\t} ).prop( 'selected', true ).attr( 'selected', true );\n\t\t};\n\n\t\t/* jshint ignore:start */\n\t\tthis.setSourceData = function( val ) {\n\n\t\t\t$( this ).empty();\n\n\t\t\tif ( !Global.isSet( val ) || val.length < 1 ) {\n\t\t\t\tif ( set_empty ) {\n\t\t\t\t\tval = Global.addFirstItemToArray( val, 'empty', customFirstItemLabel );\n\t\t\t\t} else if ( set_any ) {\n\t\t\t\t\tval = Global.addFirstItemToArray( val, 'any', customFirstItemLabel );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( set_empty ) {\n\t\t\t\t\tif ( val && val.length > 0 && ( val[0].value != TTUUID.zero_id && val[0].value != 0 ) ) {\n\t\t\t\t\t\tval = Global.addFirstItemToArray( val, 'empty', customFirstItemLabel );\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( set_any ) {\n\t\t\t\t\tif ( val && val.length > 0 && ( val[0].value != TTUUID.not_exist_id && val[0].value != -1 ) ) {\n\t\t\t\t\t\tval = Global.addFirstItemToArray( val, 'any', customFirstItemLabel );\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsource_data = val;\n\t\t\t//var option_array = [];\n\n\t\t\tif ( $( this )[0] ) {\n\t\t\t\tif ( $.isArray( val ) ) {\n\t\t\t\t\tvar len = val.length;\n\t\t\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\t\t\t$( this ).append( $( '' ).text( val[i][labelKey] ) );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor ( var j in val ) {\n\t\t\t\t\t\t$( this ).append( $( '' ).text( val[j] ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( set_select_item_when_set_source_data ) {\n\t\t\t\tthis.setValue( select_value );\n\t\t\t}\n\n\t\t};\n\t\t/* jshint ignore:end */\n\n\t\tthis.each( function() {\n\n\t\t\tvar o = $.meta ? $.extend( {}, opts, $( this ).data() ) : opts;\n\n\t\t\tif ( o.set_empty ) {\n\t\t\t\tset_empty = o.set_empty;\n\t\t\t}\n\n\t\t\tif ( o.customFirstItemLabel ) {\n\t\t\t\tcustomFirstItemLabel = o.customFirstItemLabel;\n\t\t\t}\n\n\t\t\tif ( o.set_any ) {\n\t\t\t\tset_any = o.set_any;\n\t\t\t}\n\n\t\t\tif ( o.mass_edit_mode ) {\n\t\t\t\tmass_edit_mode = o.mass_edit_mode;\n\t\t\t}\n\n\t\t\tfield = o.field;\n\n\t\t\t$( this ).change( function() {\n\n\t\t\t\tif ( !enabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif ( check_box ) {\n\t\t\t\t\t$this.setCheckBox( true );\n\t\t\t\t}\n\n\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t} );\n\n\t\t\t$( this ).click( function() {\n\t\t\t\tif ( !enabled ) {\n\t\t\t\t\tif ( !check_box ) {\n\t\t\t\t\t\tif ( LocalCacheData.current_open_sub_controller &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_sub_controller.edit_view &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_sub_controller.is_viewing ) {\n\t\t\t\t\t\t\terror_string = LocalCacheData.current_open_sub_controller.getViewModeErrorMessage();\n\t\t\t\t\t\t\t$this.showErrorTip( 10 );\n\t\t\t\t\t\t} else if ( LocalCacheData.current_open_primary_controller &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.edit_view &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.is_viewing ) {\n\t\t\t\t\t\t\terror_string = LocalCacheData.current_open_primary_controller.getViewModeErrorMessage();\n\t\t\t\t\t\t\t$this.showErrorTip( 10 );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t$( this ).mouseover( function() {\n\n\t\t\t\tif ( enabled ) {\n\t\t\t\t\tif ( error_string && error_string.length > 0 ) {\n\t\t\t\t\t\t$this.showErrorTip( 20 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\t$( this ).mouseout( function() {\n\t\t\t\t$this.hideErrorTip();\n\t\t\t} );\n\n\t\t} );\n\n\t\treturn this;\n\n\t};\n\n\t$.fn.TComboBox.defaults = {};\n\t$.fn.TComboBox.html_template = ``;\n\n} )( jQuery );//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTUxOS5qcyIsIm1hcHBpbmdzIjoiO0FBQUE7O0FBRUE7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTixLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixTQUFTO0FBQy9CO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxnQ0FBZ0M7O0FBRWhDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUwsSUFBSTs7QUFFSjs7QUFFQTs7QUFFQTtBQUNBOztBQUVBLEVBQUUsR0FBRyxNQUFNIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC93aWRnZXRzL2NvbWJvYm94L1RDb21ib0JveC5qcz9hZjM2Il0sInNvdXJjZXNDb250ZW50IjpbIiggZnVuY3Rpb24oICQgKSB7XG5cblx0JC5mbi5UQ29tYm9Cb3ggPSBmdW5jdGlvbiggb3B0aW9ucyApIHtcblx0XHR2YXIgb3B0cyA9ICQuZXh0ZW5kKCB7fSwgJC5mbi5UQ29tYm9Cb3guZGVmYXVsdHMsIG9wdGlvbnMgKTtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXHRcdHZhciBmaWVsZDtcblx0XHR2YXIgc291cmNlX2RhdGEgPSBudWxsO1xuXG5cdFx0dmFyIHNlbGVjdF92YWx1ZSA9IG51bGw7XG5cblx0XHR2YXIgc2V0X2VtcHR5ID0gZmFsc2U7XG5cblx0XHR2YXIgc2V0X2FueSA9IGZhbHNlO1xuXG5cdFx0dmFyIHNldF9zZWxlY3RfaXRlbV93aGVuX3NldF9zb3VyY2VfZGF0YSA9IGZhbHNlO1xuXG5cdFx0dmFyIGVycm9yX3N0cmluZyA9ICcnO1xuXG5cdFx0dmFyIGVycm9yX3RpcF9ib3g7XG5cblx0XHR2YXIgbWFzc19lZGl0X21vZGUgPSBmYWxzZTtcblxuXHRcdHZhciBjaGVja19ib3ggPSBudWxsO1xuXG5cdFx0dmFyIGVuYWJsZWQgPSB0cnVlO1xuXG5cdFx0dmFyIHZhbHVlS2V5ID0gJ3ZhbHVlJztcblxuXHRcdHZhciBsYWJlbEtleSA9ICdsYWJlbCc7XG5cblx0XHR2YXIgY3VzdG9tRmlyc3RJdGVtTGFiZWwgPSAnJztcblxuXHRcdHRoaXMuc2V0VmFsdWVLZXkgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0dmFsdWVLZXkgPSB2YWw7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0TGFiZWxLZXkgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0bGFiZWxLZXkgPSB2YWw7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0RW5hYmxlZCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGVuYWJsZWQ7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0RW5hYmxlZCA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRlbmFibGVkID0gdmFsO1xuXG5cdFx0XHRpZiAoIHZhbCA9PT0gZmFsc2UgfHwgdmFsID09PSAnJyApIHtcblx0XHRcdFx0JHRoaXMuYXR0ciggJ2Rpc2FibGVkJywgJ3RydWUnICk7XG5cdFx0XHRcdCR0aGlzLmFkZENsYXNzKCAndC1zZWxlY3QtcmVhZG9ubHknICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQkdGhpcy5yZW1vdmVBdHRyKCAnZGlzYWJsZWQnICk7XG5cdFx0XHRcdCR0aGlzLnJlbW92ZUNsYXNzKCAndC1zZWxlY3QtcmVhZG9ubHknICk7XG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRDaGVja0JveCA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRpZiAoIGNoZWNrX2JveCApIHtcblx0XHRcdFx0Y2hlY2tfYm94LmNoaWxkcmVuKCkuZXEoIDAgKVswXS5jaGVja2VkID0gdmFsO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR0aGlzLmlzQ2hlY2tlZCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBjaGVja19ib3ggKSB7XG5cdFx0XHRcdGlmICggY2hlY2tfYm94LmNoaWxkcmVuKCkuZXEoIDAgKVswXS5jaGVja2VkID09PSB0cnVlICkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRNYXNzRWRpdE1vZGUgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0bWFzc19lZGl0X21vZGUgPSB2YWw7XG5cblx0XHRcdGlmICggbWFzc19lZGl0X21vZGUgKSB7XG5cdFx0XHRcdGNoZWNrX2JveCA9ICQoICcgPGRpdiBjbGFzcz1cIm1hc3MtZWRpdC1jaGVja2JveC13cmFwcGVyXCI+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwibWFzcy1lZGl0LWNoZWNrYm94XCI+PC9pbnB1dD4nICtcblx0XHRcdFx0XHQnPGxhYmVsIGZvcj1cImNoZWNrYm94LWlucHV0LTFcIiBjbGFzcz1cImlucHV0LWhlbHBlciBpbnB1dC1oZWxwZXItLWNoZWNrYm94XCI+PC9sYWJlbD48L2Rpdj4nICk7XG5cdFx0XHRcdGNoZWNrX2JveC5pbnNlcnRCZWZvcmUoICQoIHRoaXMgKSApO1xuXG5cdFx0XHRcdGNoZWNrX2JveC5jaGFuZ2UoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdCR0aGlzLnRyaWdnZXIoICdmb3JtSXRlbUNoYW5nZScsIFskdGhpc10gKTtcblx0XHRcdFx0fSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCBjaGVja19ib3ggKSB7XG5cdFx0XHRcdFx0Y2hlY2tfYm94LnJlbW92ZSgpO1xuXHRcdFx0XHRcdGNoZWNrX2JveCA9IG51bGw7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLnNldEVycm9yU3R5bGUgPSBmdW5jdGlvbiggZXJyU3RyLCBzaG93LCBpc1dhcm5pbmcgKSB7XG5cdFx0XHRpZiAoIGlzV2FybmluZyApIHtcblx0XHRcdFx0JCggdGhpcyApLmFkZENsYXNzKCAnd2FybmluZy10aXAnICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQkKCB0aGlzICkuYWRkQ2xhc3MoICdlcnJvci10aXAnICk7XG5cdFx0XHR9XG5cdFx0XHRlcnJvcl9zdHJpbmcgPSBlcnJTdHI7XG5cblx0XHRcdGlmICggc2hvdyApIHtcblx0XHRcdFx0dGhpcy5zaG93RXJyb3JUaXAoKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhpcy5zaG93RXJyb3JUaXAgPSBmdW5jdGlvbiggc2VjICkge1xuXG5cdFx0XHRpZiAoICFHbG9iYWwuaXNTZXQoIHNlYyApICkge1xuXHRcdFx0XHRzZWMgPSAyO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoICFlcnJvcl90aXBfYm94ICkge1xuXHRcdFx0XHRlcnJvcl90aXBfYm94ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIFdpZGdldE5hbWVzRGljLkVSUk9SX1RPT0xUSVAgKTtcblx0XHRcdFx0ZXJyb3JfdGlwX2JveCA9IGVycm9yX3RpcF9ib3guRXJyb3JUaXBCb3goKTtcblx0XHRcdH1cblx0XHRcdGlmICggJCggdGhpcyApLmhhc0NsYXNzKCAnd2FybmluZy10aXAnICkgKSB7XG5cdFx0XHRcdGVycm9yX3RpcF9ib3guc2hvdyggdGhpcywgZXJyb3Jfc3RyaW5nLCBzZWMsIHRydWUgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVycm9yX3RpcF9ib3guc2hvdyggdGhpcywgZXJyb3Jfc3RyaW5nLCBzZWMgKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhpcy5oaWRlRXJyb3JUaXAgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIGVycm9yX3RpcF9ib3ggKSApIHtcblx0XHRcdFx0ZXJyb3JfdGlwX2JveC5yZW1vdmUoKTtcblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLmNsZWFyRXJyb3JTdHlsZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0JCggdGhpcyApLnJlbW92ZUNsYXNzKCAnZXJyb3ItdGlwJyApO1xuXHRcdFx0JCggdGhpcyApLnJlbW92ZUNsYXNzKCAnd2FybmluZy10aXAnICk7XG5cdFx0XHR0aGlzLmhpZGVFcnJvclRpcCgpO1xuXHRcdFx0ZXJyb3Jfc3RyaW5nID0gJyc7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0RmllbGQgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0ZmllbGQgPSB2YWw7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0RmllbGQgPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBmaWVsZDtcblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRMYWJlbCA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRpZiAoICFzb3VyY2VfZGF0YSB8fCAoIHNldF9lbXB0eSAmJiBzb3VyY2VfZGF0YS5sZW5ndGggPT09IDEgKSB8fCAoIHNldF9hbnkgJiYgc291cmNlX2RhdGEubGVuZ3RoID09PSAxICkgKSB7XG5cdFx0XHRcdHJldHVybiBzZWxlY3RfdmFsdWU7XG5cdFx0XHR9XG5cdFx0XHQvL2lmIHZhbHVlIGlzIG51bWJlciBjb252ZXJ0IHRvIG51bWJlciB0eXBlXG5cdFx0XHR2YXIgdmFsdWUgPSAkKCB0aGlzICkuY2hpbGRyZW4oICdvcHRpb246c2VsZWN0ZWQnICkudGV4dCgpO1xuXG5cdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0VmFsdWUgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0aWYgKCAhc291cmNlX2RhdGEgfHwgKCBzZXRfZW1wdHkgJiYgc291cmNlX2RhdGEubGVuZ3RoID09PSAxICkgfHwgKCBzZXRfYW55ICYmIHNvdXJjZV9kYXRhLmxlbmd0aCA9PT0gMSApICkge1xuXHRcdFx0XHRyZXR1cm4gc2VsZWN0X3ZhbHVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvL2lmIHZhbHVlIGlzIG51bWJlciBjb252ZXJ0IHRvIG51bWJlciB0eXBlXG5cdFx0XHR2YXIgdmFsdWUgPSAkKCB0aGlzICkuY2hpbGRyZW4oICdvcHRpb246c2VsZWN0ZWQnICkuYXR0ciggJ3ZhbHVlJyApO1xuXG5cdFx0XHQvLyMyNjI0IC0gQXZvaWQgcGFyc2luZyBmbG9hdCB2YWx1ZSBpZiB3ZSBoYXZlIGEgdmFsdWUgbGFyZ2VyIHRoYW4gemVybyB3aXRoIGEgbGVhZGluZyB6ZXJvIHNvIHRoYXQgbnVtZXJpYyBzdHJpbmcgKGVnIHByb3ZpbmNlKSBJU08gY29kZXMgYXJlIG5vdCBjb252ZXJ0ZWQgZnJvbSAnMDEnIHRvIDFcblx0XHRcdGlmICggJC5pc051bWVyaWMoIHZhbHVlICkgJiYgKCB2YWx1ZSA9PT0gJzAnIHx8IHZhbHVlLnRvU3RyaW5nKClbMF0gIT09ICcwJyApICkge1xuXHRcdFx0XHR2YWx1ZSA9IHBhcnNlRmxvYXQoIHZhbHVlICk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggdmFsdWUgPT09IC0xIHx8IHZhbHVlID09PSAnLTEnICkge1xuXHRcdFx0XHR2YWx1ZSA9IC0xO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdH07XG5cblx0XHR0aGlzLmdldFNlbGVjdGVkSW5kZXggPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0aGlzWzBdLnNlbGVjdGVkSW5kZXg7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0U2VsZWN0ZWRJbmRleCA9IGZ1bmN0aW9uKCBzZXRfaW5kZXggKSB7XG5cdFx0XHRpZiAoIHNldF9pbmRleCA8IDAgKSB7XG5cdFx0XHRcdHNldF9pbmRleCA9IDA7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIHNldF9pbmRleCA+PSB0aGlzWzBdLmxlbmd0aCApIHtcblx0XHRcdFx0c2V0X2luZGV4ID0gdGhpc1swXS5sZW5ndGggLSAxO1xuXHRcdFx0fVxuXHRcdFx0dGhpc1swXS5zZWxlY3RlZEluZGV4ID0gc2V0X2luZGV4O1xuXHRcdFx0dGhpcy5zZXRWYWx1ZSggdGhpc1swXS52YWx1ZSApO1xuXHRcdH1cblx0XHQ7XG5cdFx0dGhpcy5nZXRMYWJlbCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly9pZiB2YWx1ZSBpcyBudW1iZXIgY29udmVydCB0byBudW1iZXIgdHlwZVxuXHRcdFx0dmFyIHZhbHVlID0gJCggdGhpcyApLmNoaWxkcmVuKCAnb3B0aW9uOnNlbGVjdGVkJyApLnRleHQoKTtcblx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRWYWx1ZSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRzZWxlY3RfdmFsdWUgPSB2YWw7XG5cblx0XHRcdGlmICggIXNvdXJjZV9kYXRhIHx8IHNvdXJjZV9kYXRhLmxlbmd0aCA8IDEgfHwgKCBzZXRfZW1wdHkgJiYgc291cmNlX2RhdGEubGVuZ3RoID09PSAxICkgfHwgKCBzZXRfYW55ICYmIHNvdXJjZV9kYXRhLmxlbmd0aCA9PT0gMSApICkge1xuXHRcdFx0XHRzZXRfc2VsZWN0X2l0ZW1fd2hlbl9zZXRfc291cmNlX2RhdGEgPSB0cnVlO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vV2hlbiBubyB2YWx1ZSA9PSB1bmRlZmluZWQgb3IgbnVsbCBvciBkZWZhdWx0IGZhbHNlXG5cdFx0XHRpZiAoICFHbG9iYWwuaXNTZXQoIHZhbCApIHx8IHZhbCA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdGlmICggc2V0X2VtcHR5ICkge1xuXHRcdFx0XHRcdHZhbCA9IFRUVVVJRC56ZXJvX2lkO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBzZXRfYW55ICkge1xuXHRcdFx0XHRcdHZhbCA9IFRUVVVJRC5ub3RfZXhpc3RfaWQ7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly9JZiBubyBlbXB0eSB2YWx1ZSwgZGVmYXVsdCB0byBzZWxlY3QgZmlyc3QgaXRlbVxuXHRcdFx0XHRcdGlmICggc291cmNlX2RhdGEgJiYgc291cmNlX2RhdGEubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHRcdHRoaXMuc2V0VmFsdWUoIHNvdXJjZV9kYXRhWzBdW3ZhbHVlS2V5XSApO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdCQoICQoIHRoaXMgKS5maW5kKCAnb3B0aW9uJyApICkucmVtb3ZlQXR0ciggJ3NlbGVjdGVkJyApO1xuXG5cdFx0XHQkKCAkKCB0aGlzICkuZmluZCggJ29wdGlvbicgKSApLmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggdmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gJCggdGhpcyApLmF0dHIoICd2YWx1ZScgKSA9PT0gdmFsLnRvU3RyaW5nKCk7XG5cdFx0XHR9ICkucHJvcCggJ3NlbGVjdGVkJywgdHJ1ZSApLmF0dHIoICdzZWxlY3RlZCcsIHRydWUgKTtcblx0XHR9O1xuXG5cdFx0LyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuXHRcdHRoaXMuc2V0U291cmNlRGF0YSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cblx0XHRcdCQoIHRoaXMgKS5lbXB0eSgpO1xuXG5cdFx0XHRpZiAoICFHbG9iYWwuaXNTZXQoIHZhbCApIHx8IHZhbC5sZW5ndGggPCAxICkge1xuXHRcdFx0XHRpZiAoIHNldF9lbXB0eSApIHtcblx0XHRcdFx0XHR2YWwgPSBHbG9iYWwuYWRkRmlyc3RJdGVtVG9BcnJheSggdmFsLCAnZW1wdHknLCBjdXN0b21GaXJzdEl0ZW1MYWJlbCApO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBzZXRfYW55ICkge1xuXHRcdFx0XHRcdHZhbCA9IEdsb2JhbC5hZGRGaXJzdEl0ZW1Ub0FycmF5KCB2YWwsICdhbnknLCBjdXN0b21GaXJzdEl0ZW1MYWJlbCApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAoIHNldF9lbXB0eSApIHtcblx0XHRcdFx0XHRpZiAoIHZhbCAmJiB2YWwubGVuZ3RoID4gMCAmJiAoIHZhbFswXS52YWx1ZSAhPSBUVFVVSUQuemVyb19pZCAmJiB2YWxbMF0udmFsdWUgIT0gMCApICkge1xuXHRcdFx0XHRcdFx0dmFsID0gR2xvYmFsLmFkZEZpcnN0SXRlbVRvQXJyYXkoIHZhbCwgJ2VtcHR5JywgY3VzdG9tRmlyc3RJdGVtTGFiZWwgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fSBlbHNlIGlmICggc2V0X2FueSApIHtcblx0XHRcdFx0XHRpZiAoIHZhbCAmJiB2YWwubGVuZ3RoID4gMCAmJiAoIHZhbFswXS52YWx1ZSAhPSBUVFVVSUQubm90X2V4aXN0X2lkICYmIHZhbFswXS52YWx1ZSAhPSAtMSApICkge1xuXHRcdFx0XHRcdFx0dmFsID0gR2xvYmFsLmFkZEZpcnN0SXRlbVRvQXJyYXkoIHZhbCwgJ2FueScsIGN1c3RvbUZpcnN0SXRlbUxhYmVsICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0c291cmNlX2RhdGEgPSB2YWw7XG5cdFx0XHQvL3ZhciBvcHRpb25fYXJyYXkgPSBbXTtcblxuXHRcdFx0aWYgKCAkKCB0aGlzIClbMF0gKSB7XG5cdFx0XHRcdGlmICggJC5pc0FycmF5KCB2YWwgKSApIHtcblx0XHRcdFx0XHR2YXIgbGVuID0gdmFsLmxlbmd0aDtcblx0XHRcdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRcdCQoIHRoaXMgKS5hcHBlbmQoICQoICc8b3B0aW9uIHZhbHVlPVwiJyArIHZhbFtpXVt2YWx1ZUtleV0gKyAnXCI+PC9vcHRpb24+JyApLnRleHQoIHZhbFtpXVtsYWJlbEtleV0gKSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRmb3IgKCB2YXIgaiBpbiB2YWwgKSB7XG5cdFx0XHRcdFx0XHQkKCB0aGlzICkuYXBwZW5kKCAkKCAnPG9wdGlvbiB2YWx1ZT1cIicgKyBqICsgJ1wiPjwvb3B0aW9uPicgKS50ZXh0KCB2YWxbal0gKSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHNldF9zZWxlY3RfaXRlbV93aGVuX3NldF9zb3VyY2VfZGF0YSApIHtcblx0XHRcdFx0dGhpcy5zZXRWYWx1ZSggc2VsZWN0X3ZhbHVlICk7XG5cdFx0XHR9XG5cblx0XHR9O1xuXHRcdC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG5cblx0XHR0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHR2YXIgbyA9ICQubWV0YSA/ICQuZXh0ZW5kKCB7fSwgb3B0cywgJCggdGhpcyApLmRhdGEoKSApIDogb3B0cztcblxuXHRcdFx0aWYgKCBvLnNldF9lbXB0eSApIHtcblx0XHRcdFx0c2V0X2VtcHR5ID0gby5zZXRfZW1wdHk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggby5jdXN0b21GaXJzdEl0ZW1MYWJlbCApIHtcblx0XHRcdFx0Y3VzdG9tRmlyc3RJdGVtTGFiZWwgPSBvLmN1c3RvbUZpcnN0SXRlbUxhYmVsO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8uc2V0X2FueSApIHtcblx0XHRcdFx0c2V0X2FueSA9IG8uc2V0X2FueTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLm1hc3NfZWRpdF9tb2RlICkge1xuXHRcdFx0XHRtYXNzX2VkaXRfbW9kZSA9IG8ubWFzc19lZGl0X21vZGU7XG5cdFx0XHR9XG5cblx0XHRcdGZpZWxkID0gby5maWVsZDtcblxuXHRcdFx0JCggdGhpcyApLmNoYW5nZSggZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0aWYgKCAhZW5hYmxlZCApIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIGNoZWNrX2JveCApIHtcblx0XHRcdFx0XHQkdGhpcy5zZXRDaGVja0JveCggdHJ1ZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0JHRoaXMudHJpZ2dlciggJ2Zvcm1JdGVtQ2hhbmdlJywgWyR0aGlzXSApO1xuXHRcdFx0fSApO1xuXG5cdFx0XHQkKCB0aGlzICkuY2xpY2soIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoICFlbmFibGVkICkge1xuXHRcdFx0XHRcdGlmICggIWNoZWNrX2JveCApIHtcblx0XHRcdFx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyICYmXG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9zdWJfY29udHJvbGxlci5lZGl0X3ZpZXcgJiZcblx0XHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyLmlzX3ZpZXdpbmcgKSB7XG5cdFx0XHRcdFx0XHRcdGVycm9yX3N0cmluZyA9IExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9zdWJfY29udHJvbGxlci5nZXRWaWV3TW9kZUVycm9yTWVzc2FnZSgpO1xuXHRcdFx0XHRcdFx0XHQkdGhpcy5zaG93RXJyb3JUaXAoIDEwICk7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyICYmXG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuZWRpdF92aWV3ICYmXG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuaXNfdmlld2luZyApIHtcblx0XHRcdFx0XHRcdFx0ZXJyb3Jfc3RyaW5nID0gTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5nZXRWaWV3TW9kZUVycm9yTWVzc2FnZSgpO1xuXHRcdFx0XHRcdFx0XHQkdGhpcy5zaG93RXJyb3JUaXAoIDEwICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cblx0XHRcdCQoIHRoaXMgKS5tb3VzZW92ZXIoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdGlmICggZW5hYmxlZCApIHtcblx0XHRcdFx0XHRpZiAoIGVycm9yX3N0cmluZyAmJiBlcnJvcl9zdHJpbmcubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHRcdCR0aGlzLnNob3dFcnJvclRpcCggMjAgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0fSApO1xuXG5cdFx0XHQkKCB0aGlzICkubW91c2VvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQkdGhpcy5oaWRlRXJyb3JUaXAoKTtcblx0XHRcdH0gKTtcblxuXHRcdH0gKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH07XG5cblx0JC5mbi5UQ29tYm9Cb3guZGVmYXVsdHMgPSB7fTtcblx0JC5mbi5UQ29tYm9Cb3guaHRtbF90ZW1wbGF0ZSA9IGA8c2VsZWN0IGNsYXNzPVwidC1zZWxlY3RcIj48L3NlbGVjdD5gO1xuXG59ICkoIGpRdWVyeSApOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5519\n")},5583:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/* provided dependency */ var jQuery = __webpack_require__(9755);\n( function( $ ) {\n\n\t$.fn.Paging2 = function( options ) {\n\t\tvar opts = $.extend( {}, $.fn.Paging2.defaults, options );\n\t\tvar $this = this;\n\t\tvar pager_data;\n\t\tvar start;\n\t\tvar last;\n\t\tvar next;\n\t\tvar end;\n\t\tvar paging_selector;\n\t\tvar left_buttons_div;\n\t\tvar right_buttons_div;\n\n\t\tvar left_buttons_enable;\n\t\tvar right_buttons_enable;\n\n\t\tthis.getPagerData = function() {\n\t\t\treturn pager_data;\n\t\t},\n\n\t\t\tthis.setPagerData = function( value ) {\n\n\t\t\t\tpager_data = value;\n\n\t\t\t\tif ( !pager_data ) {\n\t\t\t\t\t$( this.css( 'display', 'none' ) );\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\t$( this.css( 'display', 'block' ) );\n\t\t\t\t}\n\n\t\t\t\t$( paging_selector ).empty();\n\n\t\t\t\tvar len = pager_data.last_page_number;\n\n\t\t\t\tif ( len === -1 ) {\n\t\t\t\t\t$( paging_selector ).append( '' );\n\t\t\t\t} else {\n\t\t\t\t\tfor ( var i = 1; i <= len; i++ ) {\n\t\t\t\t\t\t$( paging_selector ).append( '' );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$( $( paging_selector ).find( 'option' ) ).filter( function() {\n\t\t\t\t\tvar current_value = parseInt( $( this ).attr( 'value' ) );\n\n\t\t\t\t\treturn current_value === pager_data.current_page;\n\t\t\t\t} ).prop( 'selected', true ).prop( 'selected', true );\n\n\t\t\t\tif ( pager_data.is_last_page === true ) {\n\t\t\t\t\tright_buttons_div.addClass( 'disabled' );\n\t\t\t\t\tright_buttons_div.addClass( 'disabled-image' );\n\t\t\t\t\tright_buttons_enable = false;\n\t\t\t\t} else {\n\t\t\t\t\tright_buttons_div.removeClass( 'disabled' );\n\t\t\t\t\tright_buttons_div.removeClass( 'disabled-image' );\n\t\t\t\t\tright_buttons_enable = true;\n\t\t\t\t}\n\n\t\t\t\tif ( pager_data.is_first_page ) {\n\t\t\t\t\tleft_buttons_div.addClass( 'disabled' );\n\t\t\t\t\tleft_buttons_div.addClass( 'disabled-image' );\n\t\t\t\t\tleft_buttons_enable = false;\n\n\t\t\t\t} else {\n\t\t\t\t\tleft_buttons_div.removeClass( 'disabled' );\n\t\t\t\t\tleft_buttons_div.removeClass( 'disabled-image' );\n\t\t\t\t\tleft_buttons_enable = true;\n\t\t\t\t}\n\n\t\t\t\tif ( len === -1 || ( pager_data.is_first_page && pager_data.is_last_page ) ) {\n\n\t\t\t\t\tleft_buttons_div.addClass( 'disabled' );\n\t\t\t\t\tleft_buttons_div.addClass( 'disabled-image' );\n\t\t\t\t\tleft_buttons_enable = false;\n\t\t\t\t\tright_buttons_div.addClass( 'disabled' );\n\t\t\t\t\tright_buttons_div.addClass( 'disabled-image' );\n\t\t\t\t\tright_buttons_enable = false;\n\n\t\t\t\t\t$this.hide();\n\t\t\t\t} else {\n\t\t\t\t\t$this.show();\n\t\t\t\t}\n\n\t\t\t};\n\n\t\tthis.each( function() {\n\n\t\t\tvar o = $.meta ? $.extend( {}, opts, $( this ).data() ) : opts;\n\n\t\t\tvar pages_label = $( this ).find( '.page-label-span' );\n\n\t\t\tpages_label.text( $.i18n._( 'Page' ) );\n\n\t\t\tleft_buttons_div = $( this ).find( '.left-buttons-div' );\n\t\t\tright_buttons_div = $( this ).find( '.right-buttons-div' );\n\n\t\t\tstart = $( this ).find( '.start' );\n\t\t\tlast = $( this ).find( '.last' );\n\t\t\tnext = $( this ).find( '.next' );\n\t\t\tend = $( this ).find( '.end' );\n\t\t\tpaging_selector = $( this ).find( '.paging-selector' );\n\n\t\t\tstart.text( $.i18n._( 'Start' ) );\n\t\t\tlast.text( $.i18n._( 'Previous' ) );\n\n\t\t\tnext.text( $.i18n._( 'Next' ) );\n\t\t\tend.text( $.i18n._( 'End' ) );\n\n\t\t\t$( this ).hide();\n\n\t\t\tstart.click( function() {\n\t\t\t\tif ( left_buttons_enable ) {\n\t\t\t\t\t$this.trigger( 'paging', ['start'] );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tlast.click( function() {\n\t\t\t\tif ( left_buttons_enable ) {\n\t\t\t\t\t$this.trigger( 'paging', ['last'] );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tnext.click( function() {\n\t\t\t\tif ( right_buttons_enable ) {\n\t\t\t\t\t$this.trigger( 'paging', ['next'] );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tend.click( function() {\n\t\t\t\tif ( right_buttons_enable ) {\n\t\t\t\t\t$this.trigger( 'paging', ['end'] );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t$( paging_selector ).change( $.proxy( function() {\n\n\t\t\t\t$( paging_selector ).find( 'option:selected' ).each( function() {\n\t\t\t\t\tvar page_number = $( this ).attr( 'value' );\n\t\t\t\t\t$this.trigger( 'paging', ['go_to', page_number] );\n\t\t\t\t} );\n\n\t\t\t}, this ) );\n\n\t\t} );\n\n\t\treturn this;\n\n\t};\n\n\t$.fn.Paging2.defaults = {};\n\t$.fn.Paging2.html = {\n\t\tpaging: `
    CLICK TO SHOW MORE
    `,\n\t\tpaging2: `\n\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
    \n\t\t\t\t\n\t\t\t\t\n\t\t\t\t
    \n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
    \n\t\t\t
    \n\t\t`\n\t};\n\n} )\n( jQuery );//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTU4My5qcyIsIm1hcHBpbmdzIjoiO0FBQUE7O0FBRUE7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTixzQkFBc0IsVUFBVTtBQUNoQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLE1BQU07O0FBRU47QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBOztBQUVBOztBQUVBLGdDQUFnQzs7QUFFaEM7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTs7QUFFTixJQUFJOztBQUVKLElBQUk7O0FBRUo7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxFQUFFO0FBQ0YsRUFBRSxNQUFNIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC93aWRnZXRzL3BhZ2luZy9QYWdpbmcyLmpzPzM3MTciXSwic291cmNlc0NvbnRlbnQiOlsiKCBmdW5jdGlvbiggJCApIHtcblxuXHQkLmZuLlBhZ2luZzIgPSBmdW5jdGlvbiggb3B0aW9ucyApIHtcblx0XHR2YXIgb3B0cyA9ICQuZXh0ZW5kKCB7fSwgJC5mbi5QYWdpbmcyLmRlZmF1bHRzLCBvcHRpb25zICk7XG5cdFx0dmFyICR0aGlzID0gdGhpcztcblx0XHR2YXIgcGFnZXJfZGF0YTtcblx0XHR2YXIgc3RhcnQ7XG5cdFx0dmFyIGxhc3Q7XG5cdFx0dmFyIG5leHQ7XG5cdFx0dmFyIGVuZDtcblx0XHR2YXIgcGFnaW5nX3NlbGVjdG9yO1xuXHRcdHZhciBsZWZ0X2J1dHRvbnNfZGl2O1xuXHRcdHZhciByaWdodF9idXR0b25zX2RpdjtcblxuXHRcdHZhciBsZWZ0X2J1dHRvbnNfZW5hYmxlO1xuXHRcdHZhciByaWdodF9idXR0b25zX2VuYWJsZTtcblxuXHRcdHRoaXMuZ2V0UGFnZXJEYXRhID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gcGFnZXJfZGF0YTtcblx0XHR9LFxuXG5cdFx0XHR0aGlzLnNldFBhZ2VyRGF0YSA9IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblxuXHRcdFx0XHRwYWdlcl9kYXRhID0gdmFsdWU7XG5cblx0XHRcdFx0aWYgKCAhcGFnZXJfZGF0YSApIHtcblx0XHRcdFx0XHQkKCB0aGlzLmNzcyggJ2Rpc3BsYXknLCAnbm9uZScgKSApO1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQkKCB0aGlzLmNzcyggJ2Rpc3BsYXknLCAnYmxvY2snICkgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdCQoIHBhZ2luZ19zZWxlY3RvciApLmVtcHR5KCk7XG5cblx0XHRcdFx0dmFyIGxlbiA9IHBhZ2VyX2RhdGEubGFzdF9wYWdlX251bWJlcjtcblxuXHRcdFx0XHRpZiAoIGxlbiA9PT0gLTEgKSB7XG5cdFx0XHRcdFx0JCggcGFnaW5nX3NlbGVjdG9yICkuYXBwZW5kKCAnPG9wdGlvbiB2YWx1ZT1cIicgKyAxICsgJ1wiPicgKyAxICsgJzwvb3B0aW9uPicgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRmb3IgKCB2YXIgaSA9IDE7IGkgPD0gbGVuOyBpKysgKSB7XG5cdFx0XHRcdFx0XHQkKCBwYWdpbmdfc2VsZWN0b3IgKS5hcHBlbmQoICc8b3B0aW9uIHZhbHVlPVwiJyArIGkgKyAnXCI+JyArIGkgKyAnPC9vcHRpb24+JyApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdCQoICQoIHBhZ2luZ19zZWxlY3RvciApLmZpbmQoICdvcHRpb24nICkgKS5maWx0ZXIoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHZhciBjdXJyZW50X3ZhbHVlID0gcGFyc2VJbnQoICQoIHRoaXMgKS5hdHRyKCAndmFsdWUnICkgKTtcblxuXHRcdFx0XHRcdHJldHVybiBjdXJyZW50X3ZhbHVlID09PSBwYWdlcl9kYXRhLmN1cnJlbnRfcGFnZTtcblx0XHRcdFx0fSApLnByb3AoICdzZWxlY3RlZCcsIHRydWUgKS5wcm9wKCAnc2VsZWN0ZWQnLCB0cnVlICk7XG5cblx0XHRcdFx0aWYgKCBwYWdlcl9kYXRhLmlzX2xhc3RfcGFnZSA9PT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRyaWdodF9idXR0b25zX2Rpdi5hZGRDbGFzcyggJ2Rpc2FibGVkJyApO1xuXHRcdFx0XHRcdHJpZ2h0X2J1dHRvbnNfZGl2LmFkZENsYXNzKCAnZGlzYWJsZWQtaW1hZ2UnICk7XG5cdFx0XHRcdFx0cmlnaHRfYnV0dG9uc19lbmFibGUgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyaWdodF9idXR0b25zX2Rpdi5yZW1vdmVDbGFzcyggJ2Rpc2FibGVkJyApO1xuXHRcdFx0XHRcdHJpZ2h0X2J1dHRvbnNfZGl2LnJlbW92ZUNsYXNzKCAnZGlzYWJsZWQtaW1hZ2UnICk7XG5cdFx0XHRcdFx0cmlnaHRfYnV0dG9uc19lbmFibGUgPSB0cnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBwYWdlcl9kYXRhLmlzX2ZpcnN0X3BhZ2UgKSB7XG5cdFx0XHRcdFx0bGVmdF9idXR0b25zX2Rpdi5hZGRDbGFzcyggJ2Rpc2FibGVkJyApO1xuXHRcdFx0XHRcdGxlZnRfYnV0dG9uc19kaXYuYWRkQ2xhc3MoICdkaXNhYmxlZC1pbWFnZScgKTtcblx0XHRcdFx0XHRsZWZ0X2J1dHRvbnNfZW5hYmxlID0gZmFsc2U7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRsZWZ0X2J1dHRvbnNfZGl2LnJlbW92ZUNsYXNzKCAnZGlzYWJsZWQnICk7XG5cdFx0XHRcdFx0bGVmdF9idXR0b25zX2Rpdi5yZW1vdmVDbGFzcyggJ2Rpc2FibGVkLWltYWdlJyApO1xuXHRcdFx0XHRcdGxlZnRfYnV0dG9uc19lbmFibGUgPSB0cnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBsZW4gPT09IC0xIHx8ICggcGFnZXJfZGF0YS5pc19maXJzdF9wYWdlICYmIHBhZ2VyX2RhdGEuaXNfbGFzdF9wYWdlICkgKSB7XG5cblx0XHRcdFx0XHRsZWZ0X2J1dHRvbnNfZGl2LmFkZENsYXNzKCAnZGlzYWJsZWQnICk7XG5cdFx0XHRcdFx0bGVmdF9idXR0b25zX2Rpdi5hZGRDbGFzcyggJ2Rpc2FibGVkLWltYWdlJyApO1xuXHRcdFx0XHRcdGxlZnRfYnV0dG9uc19lbmFibGUgPSBmYWxzZTtcblx0XHRcdFx0XHRyaWdodF9idXR0b25zX2Rpdi5hZGRDbGFzcyggJ2Rpc2FibGVkJyApO1xuXHRcdFx0XHRcdHJpZ2h0X2J1dHRvbnNfZGl2LmFkZENsYXNzKCAnZGlzYWJsZWQtaW1hZ2UnICk7XG5cdFx0XHRcdFx0cmlnaHRfYnV0dG9uc19lbmFibGUgPSBmYWxzZTtcblxuXHRcdFx0XHRcdCR0aGlzLmhpZGUoKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQkdGhpcy5zaG93KCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0fTtcblxuXHRcdHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cblx0XHRcdHZhciBvID0gJC5tZXRhID8gJC5leHRlbmQoIHt9LCBvcHRzLCAkKCB0aGlzICkuZGF0YSgpICkgOiBvcHRzO1xuXG5cdFx0XHR2YXIgcGFnZXNfbGFiZWwgPSAkKCB0aGlzICkuZmluZCggJy5wYWdlLWxhYmVsLXNwYW4nICk7XG5cblx0XHRcdHBhZ2VzX2xhYmVsLnRleHQoICQuaTE4bi5fKCAnUGFnZScgKSApO1xuXG5cdFx0XHRsZWZ0X2J1dHRvbnNfZGl2ID0gJCggdGhpcyApLmZpbmQoICcubGVmdC1idXR0b25zLWRpdicgKTtcblx0XHRcdHJpZ2h0X2J1dHRvbnNfZGl2ID0gJCggdGhpcyApLmZpbmQoICcucmlnaHQtYnV0dG9ucy1kaXYnICk7XG5cblx0XHRcdHN0YXJ0ID0gJCggdGhpcyApLmZpbmQoICcuc3RhcnQnICk7XG5cdFx0XHRsYXN0ID0gJCggdGhpcyApLmZpbmQoICcubGFzdCcgKTtcblx0XHRcdG5leHQgPSAkKCB0aGlzICkuZmluZCggJy5uZXh0JyApO1xuXHRcdFx0ZW5kID0gJCggdGhpcyApLmZpbmQoICcuZW5kJyApO1xuXHRcdFx0cGFnaW5nX3NlbGVjdG9yID0gJCggdGhpcyApLmZpbmQoICcucGFnaW5nLXNlbGVjdG9yJyApO1xuXG5cdFx0XHRzdGFydC50ZXh0KCAkLmkxOG4uXyggJ1N0YXJ0JyApICk7XG5cdFx0XHRsYXN0LnRleHQoICQuaTE4bi5fKCAnUHJldmlvdXMnICkgKTtcblxuXHRcdFx0bmV4dC50ZXh0KCAkLmkxOG4uXyggJ05leHQnICkgKTtcblx0XHRcdGVuZC50ZXh0KCAkLmkxOG4uXyggJ0VuZCcgKSApO1xuXG5cdFx0XHQkKCB0aGlzICkuaGlkZSgpO1xuXG5cdFx0XHRzdGFydC5jbGljayggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGVmdF9idXR0b25zX2VuYWJsZSApIHtcblx0XHRcdFx0XHQkdGhpcy50cmlnZ2VyKCAncGFnaW5nJywgWydzdGFydCddICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblxuXHRcdFx0bGFzdC5jbGljayggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGVmdF9idXR0b25zX2VuYWJsZSApIHtcblx0XHRcdFx0XHQkdGhpcy50cmlnZ2VyKCAncGFnaW5nJywgWydsYXN0J10gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXG5cdFx0XHRuZXh0LmNsaWNrKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCByaWdodF9idXR0b25zX2VuYWJsZSApIHtcblx0XHRcdFx0XHQkdGhpcy50cmlnZ2VyKCAncGFnaW5nJywgWyduZXh0J10gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXG5cdFx0XHRlbmQuY2xpY2soIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIHJpZ2h0X2J1dHRvbnNfZW5hYmxlICkge1xuXHRcdFx0XHRcdCR0aGlzLnRyaWdnZXIoICdwYWdpbmcnLCBbJ2VuZCddICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblxuXHRcdFx0JCggcGFnaW5nX3NlbGVjdG9yICkuY2hhbmdlKCAkLnByb3h5KCBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQkKCBwYWdpbmdfc2VsZWN0b3IgKS5maW5kKCAnb3B0aW9uOnNlbGVjdGVkJyApLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHZhciBwYWdlX251bWJlciA9ICQoIHRoaXMgKS5hdHRyKCAndmFsdWUnICk7XG5cdFx0XHRcdFx0JHRoaXMudHJpZ2dlciggJ3BhZ2luZycsIFsnZ29fdG8nLCBwYWdlX251bWJlcl0gKTtcblx0XHRcdFx0fSApO1xuXG5cdFx0XHR9LCB0aGlzICkgKTtcblxuXHRcdH0gKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH07XG5cblx0JC5mbi5QYWdpbmcyLmRlZmF1bHRzID0ge307XG5cdCQuZm4uUGFnaW5nMi5odG1sID0ge1xuXHRcdHBhZ2luZzogYDxkaXYgY2xhc3M9XCJwYWdpbmctZGl2XCI+PHNwYW4gY2xhc3M9XCJwYWdpbmctc3BhblwiPkNMSUNLIFRPIFNIT1cgTU9SRTwvc3Bhbj48L2Rpdj5gLFxuXHRcdHBhZ2luZzI6IGBcblx0XHRcdDxkaXYgY2xhc3M9XCJwYWdpbmctMi1kaXZcIj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cImxlZnQtYnV0dG9ucy1kaXZcIj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cImRvdWJsZS1sZWZ0LWFycm93IHBpIHBpLWFuZ2xlLWRvdWJsZS1sZWZ0XCIgdGl0bGU9XCJTdGFydFwiPjwvc3Bhbj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInBhZ2luZy0yLXNwYW4gc3RhcnRcIj48L3NwYW4+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJsZWZ0LWFycm93IHBpIHBpLWFuZ2xlLWxlZnRcIj48L3NwYW4+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJwYWdpbmctMi1zcGFuIGxhc3RcIj48L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8c3BhbiBjbGFzcz1cInBhZ2UtbGFiZWwtc3BhblwiPjwvc3Bhbj5cblx0XHRcdFx0PHNlbGVjdCBjbGFzcz1cInQtc2VsZWN0IHBhZ2luZy1zZWxlY3RvclwiPlxuXHRcdFx0XHQ8L3NlbGVjdD5cblx0XHRcdFx0PGRpdiBjbGFzcz1cInJpZ2h0LWJ1dHRvbnMtZGl2XCI+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJwYWdpbmctMi1zcGFuIG5leHRcIj48L3NwYW4+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJyaWdodC1hcnJvdyBwaSBwaS1hbmdsZS1yaWdodFwiPjwvc3Bhbj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInBhZ2luZy0yLXNwYW4gZW5kXCI+PC9zcGFuPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwiZG91YmxlLXJpZ2h0LWFycm93IHBpIHBpLWFuZ2xlLWRvdWJsZS1yaWdodFwiPjwvc3Bhbj5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQ8L2Rpdj5cblx0XHRgXG5cdH07XG5cbn0gKVxuKCBqUXVlcnkgKTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///5583\n")},2548:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"FormItemType\": () => (/* binding */ FormItemType),\n/* harmony export */ \"WidgetNamesDic\": () => (/* binding */ WidgetNamesDic)\n/* harmony export */ });\nvar FormItemType = function() {\n\n};\n\nFormItemType.TEXT = 'text';\nFormItemType.AWESOME_BOX = 'awesomeBox';\nFormItemType.AWESOME_DROPDOWN = 'awesomeDropdown';\nFormItemType.FORMULA_BUILDER = 'formulaBuilder';\nFormItemType.COMBO_BOX = 'comboBox';\nFormItemType.LIST = 'list';\nFormItemType.TEXT_INPUT = 'textInput';\nFormItemType.TIME_PICKER = 'timePicker';\nFormItemType.FEEDBACK_BOX = 'feedbackBox';\nFormItemType.PASSWORD_INPUT = 'passwordInput';\nFormItemType.TEXT_AREA = 'textArea';\nFormItemType.TINYMCE_TEXT_AREA = 'tinymceTextArea';\nFormItemType.TAG_INPUT = 'tagInput';\nFormItemType.DATE_PICKER = 'datePicker';\nFormItemType.RANGE_PICKER = 'range_date_picker';\nFormItemType.CHECKBOX = 'checkbox';\nFormItemType.SEPARATED_BOX = 'separatedBox';\nFormItemType.FILE_BROWSER = 'fileBrowser';\nFormItemType.IMAGE_BROWSER = 'imageBrowser';\nFormItemType.IMAGE_AVD_BROWSER = 'imageADVBrowser';\nFormItemType.CAMERA_BROWSER = 'cameraBrowser';\nFormItemType.IMAGE_CUT = 'imageCutArea';\nFormItemType.INSIDE_EDITOR = 'insideEditor';\nFormItemType.IMAGE = 'image';\nFormItemType.COLOR_PICKER = 'colorPicker';\n\nvar WidgetNamesDic = function() {\n\n};\n\nWidgetNamesDic.ERROR_TOOLTIP = 'errorToolTip';\n\nWidgetNamesDic.EDIT_VIEW_FORM_ITEM = 'editViewFormItem';\nWidgetNamesDic.EDIT_VIEW_SUB_FORM_ITEM = 'editViewSubFormItem';\nWidgetNamesDic.PAGING = 'paging';\nWidgetNamesDic.PAGING_2 = 'paging_2';\nWidgetNamesDic.NO_RESULT_BOX = 'no_result_box';\nWidgetNamesDic.VIEW_MIN_TAB_BAR = 'view_min_tab_bar';\nWidgetNamesDic.VIEW_MIN_TAB = 'view_min_tab';//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjU0OC5qcyIsIm1hcHBpbmdzIjoiOzs7OztBQUFPOztBQUVQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVPOztBQUVQOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC93aWRnZXRzL3NlYXJjaF9wYW5lbC9Gb3JtSXRlbVR5cGUuanM/MzNjMSJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdmFyIEZvcm1JdGVtVHlwZSA9IGZ1bmN0aW9uKCkge1xuXG59O1xuXG5Gb3JtSXRlbVR5cGUuVEVYVCA9ICd0ZXh0JztcbkZvcm1JdGVtVHlwZS5BV0VTT01FX0JPWCA9ICdhd2Vzb21lQm94JztcbkZvcm1JdGVtVHlwZS5BV0VTT01FX0RST1BET1dOID0gJ2F3ZXNvbWVEcm9wZG93bic7XG5Gb3JtSXRlbVR5cGUuRk9STVVMQV9CVUlMREVSID0gJ2Zvcm11bGFCdWlsZGVyJztcbkZvcm1JdGVtVHlwZS5DT01CT19CT1ggPSAnY29tYm9Cb3gnO1xuRm9ybUl0ZW1UeXBlLkxJU1QgPSAnbGlzdCc7XG5Gb3JtSXRlbVR5cGUuVEVYVF9JTlBVVCA9ICd0ZXh0SW5wdXQnO1xuRm9ybUl0ZW1UeXBlLlRJTUVfUElDS0VSID0gJ3RpbWVQaWNrZXInO1xuRm9ybUl0ZW1UeXBlLkZFRURCQUNLX0JPWCA9ICdmZWVkYmFja0JveCc7XG5Gb3JtSXRlbVR5cGUuUEFTU1dPUkRfSU5QVVQgPSAncGFzc3dvcmRJbnB1dCc7XG5Gb3JtSXRlbVR5cGUuVEVYVF9BUkVBID0gJ3RleHRBcmVhJztcbkZvcm1JdGVtVHlwZS5USU5ZTUNFX1RFWFRfQVJFQSA9ICd0aW55bWNlVGV4dEFyZWEnO1xuRm9ybUl0ZW1UeXBlLlRBR19JTlBVVCA9ICd0YWdJbnB1dCc7XG5Gb3JtSXRlbVR5cGUuREFURV9QSUNLRVIgPSAnZGF0ZVBpY2tlcic7XG5Gb3JtSXRlbVR5cGUuUkFOR0VfUElDS0VSID0gJ3JhbmdlX2RhdGVfcGlja2VyJztcbkZvcm1JdGVtVHlwZS5DSEVDS0JPWCA9ICdjaGVja2JveCc7XG5Gb3JtSXRlbVR5cGUuU0VQQVJBVEVEX0JPWCA9ICdzZXBhcmF0ZWRCb3gnO1xuRm9ybUl0ZW1UeXBlLkZJTEVfQlJPV1NFUiA9ICdmaWxlQnJvd3Nlcic7XG5Gb3JtSXRlbVR5cGUuSU1BR0VfQlJPV1NFUiA9ICdpbWFnZUJyb3dzZXInO1xuRm9ybUl0ZW1UeXBlLklNQUdFX0FWRF9CUk9XU0VSID0gJ2ltYWdlQURWQnJvd3Nlcic7XG5Gb3JtSXRlbVR5cGUuQ0FNRVJBX0JST1dTRVIgPSAnY2FtZXJhQnJvd3Nlcic7XG5Gb3JtSXRlbVR5cGUuSU1BR0VfQ1VUID0gJ2ltYWdlQ3V0QXJlYSc7XG5Gb3JtSXRlbVR5cGUuSU5TSURFX0VESVRPUiA9ICdpbnNpZGVFZGl0b3InO1xuRm9ybUl0ZW1UeXBlLklNQUdFID0gJ2ltYWdlJztcbkZvcm1JdGVtVHlwZS5DT0xPUl9QSUNLRVIgPSAnY29sb3JQaWNrZXInO1xuXG5leHBvcnQgdmFyIFdpZGdldE5hbWVzRGljID0gZnVuY3Rpb24oKSB7XG5cbn07XG5cbldpZGdldE5hbWVzRGljLkVSUk9SX1RPT0xUSVAgPSAnZXJyb3JUb29sVGlwJztcblxuV2lkZ2V0TmFtZXNEaWMuRURJVF9WSUVXX0ZPUk1fSVRFTSA9ICdlZGl0Vmlld0Zvcm1JdGVtJztcbldpZGdldE5hbWVzRGljLkVESVRfVklFV19TVUJfRk9STV9JVEVNID0gJ2VkaXRWaWV3U3ViRm9ybUl0ZW0nO1xuV2lkZ2V0TmFtZXNEaWMuUEFHSU5HID0gJ3BhZ2luZyc7XG5XaWRnZXROYW1lc0RpYy5QQUdJTkdfMiA9ICdwYWdpbmdfMic7XG5XaWRnZXROYW1lc0RpYy5OT19SRVNVTFRfQk9YID0gJ25vX3Jlc3VsdF9ib3gnO1xuV2lkZ2V0TmFtZXNEaWMuVklFV19NSU5fVEFCX0JBUiA9ICd2aWV3X21pbl90YWJfYmFyJztcbldpZGdldE5hbWVzRGljLlZJRVdfTUlOX1RBQiA9ICd2aWV3X21pbl90YWInOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///2548\n")},3133:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/* provided dependency */ var jQuery = __webpack_require__(9755);\n( function( $ ) {\n\n\t$.fn.TPasswordInput = function( options ) {\n\t\tvar opts = $.extend( {}, $.fn.TPasswordInput.defaults, options );\n\t\tvar $this = this;\n\t\tvar field;\n\t\tvar error_string = '';\n\t\tvar error_tip_box;\n\n\t\tvar mass_edit_mode = false;\n\t\tvar check_box = null;\n\n\t\tvar enabled = true;\n\n\t\tvar hasKeyEvent = null;\n\n\t\tvar validate_timer = null;\n\n\t\tthis.getEnabled = function() {\n\t\t\treturn enabled;\n\t\t};\n\n\t\tthis.setEnabled = function( val ) {\n\t\t\tenabled = val;\n\t\t\tif ( val === false || val === '' ) {\n\t\t\t\t$this.attr( 'readonly', 'true' );\n\t\t\t\t$this.addClass( 't-text-input-readonly' );\n\t\t\t} else {\n\t\t\t\t$this.removeAttr( 'readonly' );\n\t\t\t\t$this.removeClass( 't-text-input-readonly' );\n\t\t\t}\n\n\t\t};\n\n\t\tthis.setReadOnly = function( val ) {\n\t\t\tif ( val ) {\n\t\t\t\t$this.attr( 'disabled', 'true' );\n\t\t\t\t$this.addClass( 't-text-input-readonly-bg' );\n\t\t\t} else {\n\t\t\t\t$this.removeAttr( 'disabled' );\n\t\t\t\t$this.removeClass( 't-text-input-readonly-bg' );\n\t\t\t}\n\t\t};\n\n\t\tthis.setCheckBox = function( val ) {\n\t\t\tif ( check_box ) {\n\t\t\t\tcheck_box.children().eq( 0 )[0].checked = val;\n\t\t\t}\n\t\t};\n\n\t\tthis.isChecked = function() {\n\t\t\tif ( check_box ) {\n\t\t\t\tif ( check_box.children().eq( 0 )[0].checked === true ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t};\n\t\tthis.setMassEditMode = function( val ) {\n\n\t\t\tmass_edit_mode = val;\n\n\t\t\tif ( mass_edit_mode ) {\n\t\t\t\tcheck_box = $( '
    ' +\n\t\t\t\t\t'
    ' );\n\t\t\t\tcheck_box.insertBefore( $( this ) );\n\n\t\t\t\tcheck_box.change( function() {\n\t\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t\t} );\n\n\t\t\t} else {\n\t\t\t\tif ( check_box ) {\n\t\t\t\t\tcheck_box.remove();\n\t\t\t\t\tcheck_box = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.getField = function() {\n\t\t\treturn field;\n\t\t};\n\n\t\tthis.getValue = function() {\n\n\t\t\tvar val = $this.val();\n\t\t\treturn val;\n\n\t\t};\n\n\t\tthis.setValue = function( val ) {\n\n\t\t\tif ( !val && val !== 0 ) {\n\t\t\t\tval = '';\n\t\t\t}\n\n\t\t\t$this.val( val );\n\n\t\t};\n\n\t\tthis.setErrorStyle = function( errStr, show, isWarning ) {\n\t\t\tif ( isWarning ) {\n\t\t\t\t$( this ).addClass( 'warning-tip' );\n\t\t\t} else {\n\t\t\t\t$( this ).addClass( 'error-tip' );\n\t\t\t}\n\t\t\terror_string = errStr;\n\n\t\t\tif ( show ) {\n\t\t\t\tthis.showErrorTip();\n\t\t\t}\n\t\t};\n\n\t\tthis.showErrorTip = function( sec ) {\n\n\t\t\tif ( !Global.isSet( sec ) ) {\n\t\t\t\tsec = 2;\n\t\t\t}\n\n\t\t\tif ( !error_tip_box ) {\n\t\t\t\terror_tip_box = Global.loadWidgetByName( WidgetNamesDic.ERROR_TOOLTIP );\n\t\t\t\terror_tip_box = error_tip_box.ErrorTipBox();\n\t\t\t}\n\t\t\terror_tip_box.cancelRemove();\n\t\t\tif ( $( this ).hasClass( 'warning-tip' ) ) {\n\t\t\t\terror_tip_box.show( this, error_string, sec, true );\n\t\t\t} else {\n\t\t\t\terror_tip_box.show( this, error_string, sec );\n\t\t\t}\n\t\t};\n\n\t\tthis.hideErrorTip = function() {\n\n\t\t\tif ( Global.isSet( error_tip_box ) ) {\n\t\t\t\terror_tip_box.remove();\n\t\t\t}\n\n\t\t};\n\n\t\tthis.clearErrorStyle = function() {\n\t\t\t$( this ).removeClass( 'error-tip' );\n\t\t\t$( this ).removeClass( 'warning-tip' );\n\t\t\tthis.hideErrorTip();\n\t\t\terror_string = '';\n\t\t};\n\n\t\tthis.each( function() {\n\n\t\t\tvar o = $.meta ? $.extend( {}, opts, $( this ).data() ) : opts;\n\n\t\t\tfield = o.field;\n\t\t\thasKeyEvent = o.hasKeyEvent;\n\n\t\t\tif ( o.width > 0 ) {\n\t\t\t\t$this.width( o.width );\n\t\t\t}\n\n\t\t\t//NOTE: Do not add keyup/down events, as type-as-you-go validation should not be active on password fields.\n\t\t\t// Specifically because they must match exactly and the timer causes one character to be missed it could give an incorrect validation failure.\n\t\t\t// Also if they type slow enough it cause many password failures and they could be locked out before they finish typing their password.\n\t\t\t$( this ).change( function() {\n\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t} );\n\n\t\t\t$( this ).mouseover( function() {\n\n\t\t\t\tif ( enabled ) {\n\t\t\t\t\tif ( error_string && error_string.length > 0 ) {\n\t\t\t\t\t\t$this.showErrorTip( 20 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\t$( this ).mouseout( function() {\n\t\t\t\tif ( !$( $this ).is( ':focus' ) ) {\n\t\t\t\t\t$this.hideErrorTip();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t$( this ).focusin( function() {\n\n\t\t\t\tif ( !enabled ) {\n\t\t\t\t\tif ( !check_box ) {\n\t\t\t\t\t\tif ( LocalCacheData.current_open_sub_controller &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_sub_controller.edit_view &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_sub_controller.is_viewing ) {\n\t\t\t\t\t\t\terror_string = LocalCacheData.current_open_sub_controller.getViewModeErrorMessage();\n\t\t\t\t\t\t\t$this.showErrorTip( 10 );\n\t\t\t\t\t\t} else if ( LocalCacheData.current_open_primary_controller &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.edit_view &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.is_viewing ) {\n\t\t\t\t\t\t\terror_string = LocalCacheData.current_open_primary_controller.getViewModeErrorMessage();\n\t\t\t\t\t\t\t$this.showErrorTip( 10 );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( error_string && error_string.length > 0 ) {\n\t\t\t\t\t\t$this.showErrorTip( 20 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\t$( this ).focusout( function() {\n\t\t\t\t$this.hideErrorTip();\n\t\t\t} );\n\n\t\t} );\n\n\t\treturn this;\n\n\t};\n\n\t$.fn.TPasswordInput.defaults = {};\n\t$.fn.TPasswordInput.html_template = ``;\n\n} )( jQuery );//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzEzMy5qcyIsIm1hcHBpbmdzIjoiO0FBQUE7O0FBRUE7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNOztBQUVOLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxnQ0FBZ0M7O0FBRWhDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUwsSUFBSTs7QUFFSjs7QUFFQTs7QUFFQTtBQUNBOztBQUVBLEVBQUUsR0FBRyxNQUFNIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC93aWRnZXRzL3RleHRfaW5wdXQvVFBhc3N3b3JkSW5wdXQuanM/NjRlZSJdLCJzb3VyY2VzQ29udGVudCI6WyIoIGZ1bmN0aW9uKCAkICkge1xuXG5cdCQuZm4uVFBhc3N3b3JkSW5wdXQgPSBmdW5jdGlvbiggb3B0aW9ucyApIHtcblx0XHR2YXIgb3B0cyA9ICQuZXh0ZW5kKCB7fSwgJC5mbi5UUGFzc3dvcmRJbnB1dC5kZWZhdWx0cywgb3B0aW9ucyApO1xuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cdFx0dmFyIGZpZWxkO1xuXHRcdHZhciBlcnJvcl9zdHJpbmcgPSAnJztcblx0XHR2YXIgZXJyb3JfdGlwX2JveDtcblxuXHRcdHZhciBtYXNzX2VkaXRfbW9kZSA9IGZhbHNlO1xuXHRcdHZhciBjaGVja19ib3ggPSBudWxsO1xuXG5cdFx0dmFyIGVuYWJsZWQgPSB0cnVlO1xuXG5cdFx0dmFyIGhhc0tleUV2ZW50ID0gbnVsbDtcblxuXHRcdHZhciB2YWxpZGF0ZV90aW1lciA9IG51bGw7XG5cblx0XHR0aGlzLmdldEVuYWJsZWQgPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBlbmFibGVkO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldEVuYWJsZWQgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0ZW5hYmxlZCA9IHZhbDtcblx0XHRcdGlmICggdmFsID09PSBmYWxzZSB8fCB2YWwgPT09ICcnICkge1xuXHRcdFx0XHQkdGhpcy5hdHRyKCAncmVhZG9ubHknLCAndHJ1ZScgKTtcblx0XHRcdFx0JHRoaXMuYWRkQ2xhc3MoICd0LXRleHQtaW5wdXQtcmVhZG9ubHknICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQkdGhpcy5yZW1vdmVBdHRyKCAncmVhZG9ubHknICk7XG5cdFx0XHRcdCR0aGlzLnJlbW92ZUNsYXNzKCAndC10ZXh0LWlucHV0LXJlYWRvbmx5JyApO1xuXHRcdFx0fVxuXG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0UmVhZE9ubHkgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0aWYgKCB2YWwgKSB7XG5cdFx0XHRcdCR0aGlzLmF0dHIoICdkaXNhYmxlZCcsICd0cnVlJyApO1xuXHRcdFx0XHQkdGhpcy5hZGRDbGFzcyggJ3QtdGV4dC1pbnB1dC1yZWFkb25seS1iZycgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdCR0aGlzLnJlbW92ZUF0dHIoICdkaXNhYmxlZCcgKTtcblx0XHRcdFx0JHRoaXMucmVtb3ZlQ2xhc3MoICd0LXRleHQtaW5wdXQtcmVhZG9ubHktYmcnICk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0Q2hlY2tCb3ggPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0aWYgKCBjaGVja19ib3ggKSB7XG5cdFx0XHRcdGNoZWNrX2JveC5jaGlsZHJlbigpLmVxKCAwIClbMF0uY2hlY2tlZCA9IHZhbDtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhpcy5pc0NoZWNrZWQgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggY2hlY2tfYm94ICkge1xuXHRcdFx0XHRpZiAoIGNoZWNrX2JveC5jaGlsZHJlbigpLmVxKCAwIClbMF0uY2hlY2tlZCA9PT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fTtcblx0XHR0aGlzLnNldE1hc3NFZGl0TW9kZSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cblx0XHRcdG1hc3NfZWRpdF9tb2RlID0gdmFsO1xuXG5cdFx0XHRpZiAoIG1hc3NfZWRpdF9tb2RlICkge1xuXHRcdFx0XHRjaGVja19ib3ggPSAkKCAnIDxkaXYgY2xhc3M9XCJtYXNzLWVkaXQtY2hlY2tib3gtd3JhcHBlclwiPjxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cIm1hc3MtZWRpdC1jaGVja2JveFwiPjwvaW5wdXQ+JyArXG5cdFx0XHRcdFx0JzxsYWJlbCBmb3I9XCJjaGVja2JveC1pbnB1dC0xXCIgY2xhc3M9XCJpbnB1dC1oZWxwZXIgaW5wdXQtaGVscGVyLS1jaGVja2JveFwiPjwvbGFiZWw+PC9kaXY+JyApO1xuXHRcdFx0XHRjaGVja19ib3guaW5zZXJ0QmVmb3JlKCAkKCB0aGlzICkgKTtcblxuXHRcdFx0XHRjaGVja19ib3guY2hhbmdlKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHQkdGhpcy50cmlnZ2VyKCAnZm9ybUl0ZW1DaGFuZ2UnLCBbJHRoaXNdICk7XG5cdFx0XHRcdH0gKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCBjaGVja19ib3ggKSB7XG5cdFx0XHRcdFx0Y2hlY2tfYm94LnJlbW92ZSgpO1xuXHRcdFx0XHRcdGNoZWNrX2JveCA9IG51bGw7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLmdldEZpZWxkID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gZmllbGQ7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0VmFsdWUgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0dmFyIHZhbCA9ICR0aGlzLnZhbCgpO1xuXHRcdFx0cmV0dXJuIHZhbDtcblxuXHRcdH07XG5cblx0XHR0aGlzLnNldFZhbHVlID0gZnVuY3Rpb24oIHZhbCApIHtcblxuXHRcdFx0aWYgKCAhdmFsICYmIHZhbCAhPT0gMCApIHtcblx0XHRcdFx0dmFsID0gJyc7XG5cdFx0XHR9XG5cblx0XHRcdCR0aGlzLnZhbCggdmFsICk7XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRFcnJvclN0eWxlID0gZnVuY3Rpb24oIGVyclN0ciwgc2hvdywgaXNXYXJuaW5nICkge1xuXHRcdFx0aWYgKCBpc1dhcm5pbmcgKSB7XG5cdFx0XHRcdCQoIHRoaXMgKS5hZGRDbGFzcyggJ3dhcm5pbmctdGlwJyApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0JCggdGhpcyApLmFkZENsYXNzKCAnZXJyb3ItdGlwJyApO1xuXHRcdFx0fVxuXHRcdFx0ZXJyb3Jfc3RyaW5nID0gZXJyU3RyO1xuXG5cdFx0XHRpZiAoIHNob3cgKSB7XG5cdFx0XHRcdHRoaXMuc2hvd0Vycm9yVGlwKCk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoaXMuc2hvd0Vycm9yVGlwID0gZnVuY3Rpb24oIHNlYyApIHtcblxuXHRcdFx0aWYgKCAhR2xvYmFsLmlzU2V0KCBzZWMgKSApIHtcblx0XHRcdFx0c2VjID0gMjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCAhZXJyb3JfdGlwX2JveCApIHtcblx0XHRcdFx0ZXJyb3JfdGlwX2JveCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBXaWRnZXROYW1lc0RpYy5FUlJPUl9UT09MVElQICk7XG5cdFx0XHRcdGVycm9yX3RpcF9ib3ggPSBlcnJvcl90aXBfYm94LkVycm9yVGlwQm94KCk7XG5cdFx0XHR9XG5cdFx0XHRlcnJvcl90aXBfYm94LmNhbmNlbFJlbW92ZSgpO1xuXHRcdFx0aWYgKCAkKCB0aGlzICkuaGFzQ2xhc3MoICd3YXJuaW5nLXRpcCcgKSApIHtcblx0XHRcdFx0ZXJyb3JfdGlwX2JveC5zaG93KCB0aGlzLCBlcnJvcl9zdHJpbmcsIHNlYywgdHJ1ZSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZXJyb3JfdGlwX2JveC5zaG93KCB0aGlzLCBlcnJvcl9zdHJpbmcsIHNlYyApO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR0aGlzLmhpZGVFcnJvclRpcCA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRpZiAoIEdsb2JhbC5pc1NldCggZXJyb3JfdGlwX2JveCApICkge1xuXHRcdFx0XHRlcnJvcl90aXBfYm94LnJlbW92ZSgpO1xuXHRcdFx0fVxuXG5cdFx0fTtcblxuXHRcdHRoaXMuY2xlYXJFcnJvclN0eWxlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHQkKCB0aGlzICkucmVtb3ZlQ2xhc3MoICdlcnJvci10aXAnICk7XG5cdFx0XHQkKCB0aGlzICkucmVtb3ZlQ2xhc3MoICd3YXJuaW5nLXRpcCcgKTtcblx0XHRcdHRoaXMuaGlkZUVycm9yVGlwKCk7XG5cdFx0XHRlcnJvcl9zdHJpbmcgPSAnJztcblx0XHR9O1xuXG5cdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0dmFyIG8gPSAkLm1ldGEgPyAkLmV4dGVuZCgge30sIG9wdHMsICQoIHRoaXMgKS5kYXRhKCkgKSA6IG9wdHM7XG5cblx0XHRcdGZpZWxkID0gby5maWVsZDtcblx0XHRcdGhhc0tleUV2ZW50ID0gby5oYXNLZXlFdmVudDtcblxuXHRcdFx0aWYgKCBvLndpZHRoID4gMCApIHtcblx0XHRcdFx0JHRoaXMud2lkdGgoIG8ud2lkdGggKTtcblx0XHRcdH1cblxuXHRcdFx0Ly9OT1RFOiBEbyBub3QgYWRkIGtleXVwL2Rvd24gZXZlbnRzLCBhcyB0eXBlLWFzLXlvdS1nbyB2YWxpZGF0aW9uIHNob3VsZCBub3QgYmUgYWN0aXZlIG9uIHBhc3N3b3JkIGZpZWxkcy5cblx0XHRcdC8vICBTcGVjaWZpY2FsbHkgYmVjYXVzZSB0aGV5IG11c3QgbWF0Y2ggZXhhY3RseSBhbmQgdGhlIHRpbWVyIGNhdXNlcyBvbmUgY2hhcmFjdGVyIHRvIGJlIG1pc3NlZCBpdCBjb3VsZCBnaXZlIGFuIGluY29ycmVjdCB2YWxpZGF0aW9uIGZhaWx1cmUuXG5cdFx0XHQvLyAgQWxzbyBpZiB0aGV5IHR5cGUgc2xvdyBlbm91Z2ggaXQgY2F1c2UgbWFueSBwYXNzd29yZCBmYWlsdXJlcyBhbmQgdGhleSBjb3VsZCBiZSBsb2NrZWQgb3V0IGJlZm9yZSB0aGV5IGZpbmlzaCB0eXBpbmcgdGhlaXIgcGFzc3dvcmQuXG5cdFx0XHQkKCB0aGlzICkuY2hhbmdlKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0JHRoaXMudHJpZ2dlciggJ2Zvcm1JdGVtQ2hhbmdlJywgWyR0aGlzXSApO1xuXHRcdFx0fSApO1xuXG5cdFx0XHQkKCB0aGlzICkubW91c2VvdmVyKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHRpZiAoIGVuYWJsZWQgKSB7XG5cdFx0XHRcdFx0aWYgKCBlcnJvcl9zdHJpbmcgJiYgZXJyb3Jfc3RyaW5nLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRcdFx0XHQkdGhpcy5zaG93RXJyb3JUaXAoIDIwICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdH0gKTtcblxuXHRcdFx0JCggdGhpcyApLm1vdXNlb3V0KCBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCAhJCggJHRoaXMgKS5pcyggJzpmb2N1cycgKSApIHtcblx0XHRcdFx0XHQkdGhpcy5oaWRlRXJyb3JUaXAoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXG5cdFx0XHQkKCB0aGlzICkuZm9jdXNpbiggZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0aWYgKCAhZW5hYmxlZCApIHtcblx0XHRcdFx0XHRpZiAoICFjaGVja19ib3ggKSB7XG5cdFx0XHRcdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9zdWJfY29udHJvbGxlciAmJlxuXHRcdFx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fc3ViX2NvbnRyb2xsZXIuZWRpdF92aWV3ICYmXG5cdFx0XHRcdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9zdWJfY29udHJvbGxlci5pc192aWV3aW5nICkge1xuXHRcdFx0XHRcdFx0XHRlcnJvcl9zdHJpbmcgPSBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fc3ViX2NvbnRyb2xsZXIuZ2V0Vmlld01vZGVFcnJvck1lc3NhZ2UoKTtcblx0XHRcdFx0XHRcdFx0JHRoaXMuc2hvd0Vycm9yVGlwKCAxMCApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlciAmJlxuXHRcdFx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmVkaXRfdmlldyAmJlxuXHRcdFx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmlzX3ZpZXdpbmcgKSB7XG5cdFx0XHRcdFx0XHRcdGVycm9yX3N0cmluZyA9IExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuZ2V0Vmlld01vZGVFcnJvck1lc3NhZ2UoKTtcblx0XHRcdFx0XHRcdFx0JHRoaXMuc2hvd0Vycm9yVGlwKCAxMCApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpZiAoIGVycm9yX3N0cmluZyAmJiBlcnJvcl9zdHJpbmcubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHRcdCR0aGlzLnNob3dFcnJvclRpcCggMjAgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0fSApO1xuXG5cdFx0XHQkKCB0aGlzICkuZm9jdXNvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQkdGhpcy5oaWRlRXJyb3JUaXAoKTtcblx0XHRcdH0gKTtcblxuXHRcdH0gKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH07XG5cblx0JC5mbi5UUGFzc3dvcmRJbnB1dC5kZWZhdWx0cyA9IHt9O1xuXHQkLmZuLlRQYXNzd29yZElucHV0Lmh0bWxfdGVtcGxhdGUgPSBgPGlucHV0IHR5cGU9XCJwYXNzd29yZFwiIGNsYXNzPVwidC10ZXh0LWlucHV0XCIgYXV0b2NvbXBsZXRlPVwibmV3LXBhc3N3b3JkXCIvPmA7XG5cbn0gKSggalF1ZXJ5ICk7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///3133\n")},9264:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/* provided dependency */ var jQuery = __webpack_require__(9755);\n( function( $ ) {\n\n\t$.fn.TTextInput = function( options ) {\n\t\tvar opts = $.extend( {}, $.fn.TTextInput.defaults, options );\n\t\tvar $this = this;\n\t\tvar field;\n\t\tvar validation_field;\n\t\tvar error_string = '';\n\t\tvar error_tip_box;\n\n\t\tvar mass_edit_mode = false;\n\t\tvar check_box = null;\n\n\t\tvar enabled = true;\n\n\t\tvar hasKeyEvent = null;\n\n\t\t//DONT USE THIS ANY MORE\n\t\tvar need_parser_date = false;\n\n\t\tvar need_parser_sec = false;\n\n\t\tvar parsed_value = false; //work with need_parser_date\n\n\t\tvar api_date = null;\n\n\t\tvar validate_timer = null;\n\n\t\tvar no_validate_timer = null;\n\n\t\tvar no_validate_timer_sec = 0;\n\n\t\tvar password_style = false;\n\n\t\tvar disable_keyup_event = false; //set to not send change event when mouseup\n\n\t\tvar mode;\n\n\t\tvar is_static_width;\n\n\t\tvar static_width;\n\n\t\tvar display_na = true; // Display N/A when no value\n\n\t\t// var cancel_date_parse = false;\n\n\t\tvar do_validate = true;\n\n\t\t// var parseDateAsync = function( callBack ) {\n\t\t// \tparsed_value = -1;\n\t\t// \tif ( !api_date ) {\n\t\t// \t\tapi_date = TTAPI.APITTDate;\n\t\t// \t}\n\t\t// \tapi_date.parseTimeUnit( $this.val(), {\n\t\t// \t\tonResult: function( result ) {\n\t\t// \t\t\tif ( cancel_date_parse ) {\n\t\t// \t\t\t\treturn;\n\t\t// \t\t\t}\n\t\t// \t\t\tparsed_value = result.getResult();\n\t\t// \t\t\tif ( callBack ) {\n\t\t// \t\t\t\tcallBack();\n\t\t// \t\t\t}\n\t\t// \t\t\tProgressBar.closeOverlay();\n\t\t// \t\t}\n\t\t// \t} );\n\t\t//\n\t\t// \t//parsed_value = Global.parseTimeUnit( $this.val() );\n\t\t// };\n\n\t\tthis.setPlaceHolder = function( val ) {\n\t\t\t$this.attr( 'placeholder', val );\n\t\t};\n\n\t\tthis.setNeedParsDate = function( val ) {\n\t\t\tneed_parser_date = val;\n\t\t};\n\n\t\tthis.setNeedParseSec = function( val ) {\n\t\t\tif ( val ) {\n\t\t\t\t//parsed_value = parseDateAsync();\n\t\t\t\tparsed_value = Global.parseTimeUnit( $this.val() );\n\t\t\t}\n\t\t\tneed_parser_sec = val;\n\n\t\t};\n\n\t\tthis.getEnabled = function() {\n\t\t\treturn enabled;\n\t\t};\n\n\t\tthis.setEnabled = function( val ) {\n\t\t\tenabled = val;\n\t\t\tif ( val === false || val === '' ) {\n\t\t\t\t$this.attr( 'readonly', 'true' );\n\t\t\t\t$this.addClass( 't-text-input-readonly' );\n\t\t\t\tif ( check_box ) {\n\t\t\t\t\tcheck_box.hide();\n\t\t\t\t}\n\t\t\t\tif ( !this.getValue() && display_na ) {\n\t\t\t\t\tthis.val( $.i18n._( 'N/A' ) );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$this.removeAttr( 'readonly' );\n\t\t\t\t$this.removeClass( 't-text-input-readonly' );\n\t\t\t\tif ( check_box ) {\n\t\t\t\t\tcheck_box.show();\n\t\t\t\t}\n\t\t\t\tif ( this.val() === $.i18n._( 'N/A' ) ) {\n\t\t\t\t\tthis.val( '' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.setReadOnly = function( val ) {\n\t\t\tif ( val ) {\n\t\t\t\t$this.attr( 'disabled', 'true' );\n\t\t\t\t$this.addClass( 't-text-input-readonly-bg' );\n\t\t\t} else {\n\t\t\t\t$this.removeAttr( 'disabled' );\n\t\t\t\t$this.removeClass( 't-text-input-readonly-bg' );\n\t\t\t}\n\t\t};\n\n\t\tthis.setCheckBox = function( val ) {\n\t\t\tif ( check_box ) {\n\t\t\t\tcheck_box.children().eq( 0 )[0].checked = val;\n\t\t\t}\n\t\t};\n\n\t\tthis.isChecked = function() {\n\t\t\tif ( check_box ) {\n\t\t\t\tif ( check_box.children().eq( 0 )[0].checked === true ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t};\n\n\t\tthis.setMassEditMode = function( val ) {\n\n\t\t\tmass_edit_mode = val;\n\n\t\t\tif ( mass_edit_mode ) {\n\t\t\t\tcheck_box = $( '
    ' +\n\t\t\t\t\t'
    ' );\n\t\t\t\tcheck_box.insertBefore( $( this ) );\n\t\t\t\tcheck_box.change( function() {\n\t\t\t\t\tif ( need_parser_date || need_parser_sec ) {\n\t\t\t\t\t\tparsed_value = Global.parseTimeUnit( $this.val() );\n\t\t\t\t\t\t// parseDateAsync( function() {\n\t\t\t\t\t\t// \t$this.trigger( 'formItemChange', [$this] );\n\t\t\t\t\t\t// } );\n\t\t\t\t\t}\n\t\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t\t} );\n\n\t\t\t\tif ( is_static_width && static_width.toString().indexOf( '%' ) > 0 ) {\n\t\t\t\t\t$this.css( 'width', 'calc(' + static_width + ' - 25px)' );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( check_box ) {\n\t\t\t\t\tcheck_box.remove();\n\t\t\t\t\tcheck_box = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t};\n\n\t\tthis.setField = function( val ) {\n\t\t\tfield = val;\n\t\t};\n\n\t\tthis.getField = function() {\n\t\t\treturn field;\n\t\t};\n\n\t\tthis.getValidationField = function() {\n\t\t\treturn validation_field;\n\t\t};\n\n\t\tthis.getInputValue = function() {\n\n\t\t\tvar val = $this.val();\n\t\t\treturn val;\n\n\t\t};\n\t\tthis.getValue = function() {\n\t\t\tvar val = $this.val();\n\t\t\tif ( val === $.i18n._( 'N/A' ) ) {\n\t\t\t\tval = '';\n\t\t\t}\n\t\t\tif ( need_parser_sec || need_parser_date || parsed_value ) {\n\t\t\t\tif ( parsed_value === -1 ) {\n\t\t\t\t\tparsed_value = Global.parseTimeUnit( val );\n\t\t\t\t\t// cancel_date_parse = true; // cancel orginal date parse process\n\t\t\t\t\t// parsed_value = api_date.parseTimeUnit( val, { async: false } ).getResult();\n\t\t\t\t}\n\t\t\t\treturn parsed_value;\n\t\t\t} else {\n\t\t\t\treturn val;\n\t\t\t}\n\n\t\t};\n\n\t\tthis.setValue = function( val ) {\n\t\t\tif ( !val && val !== 0 ) {\n\t\t\t\tval = '';\n\t\t\t}\n\t\t\t$this.val( val );\n\t\t\tif ( need_parser_date ) {\n\t\t\t\t//parseDateAsync();\n\t\t\t\tparsed_value = Global.parseTimeUnit( $this.val() );\n\t\t\t} else if ( need_parser_sec ) {\n\t\t\t\tparsed_value = val;\n\t\t\t\t$this.val( Global.getTimeUnit( val ) );\n\t\t\t}\n\n\t\t\tthis.autoResize();\n\t\t};\n\n\t\tthis.setErrorStyle = function( errStr, show, isWarning ) {\n\t\t\tif ( isWarning ) {\n\t\t\t\t$( this ).addClass( 'warning-tip' );\n\t\t\t} else {\n\t\t\t\t$( this ).addClass( 'error-tip' );\n\t\t\t}\n\t\t\terror_string = errStr;\n\n\t\t\tif ( show ) {\n\t\t\t\tthis.showErrorTip();\n\t\t\t}\n\t\t};\n\n\t\tthis.setWidth = function( val ) {\n\t\t\tif ( val && ( val > 0 || val.indexOf( '%' ) > 0 ) ) {\n\t\t\t\t$this.width( val );\n\t\t\t\tstatic_width = val;\n\t\t\t\tis_static_width = true;\n\t\t\t}\n\t\t};\n\n\t\tthis.showErrorTip = function( sec ) {\n\n\t\t\tif ( !Global.isSet( sec ) ) {\n\t\t\t\tsec = 2;\n\t\t\t}\n\n\t\t\tif ( !error_tip_box ) {\n\t\t\t\terror_tip_box = Global.loadWidgetByName( WidgetNamesDic.ERROR_TOOLTIP );\n\t\t\t\terror_tip_box = error_tip_box.ErrorTipBox();\n\t\t\t}\n\t\t\terror_tip_box.cancelRemove();\n\n\t\t\tif ( $( this ).hasClass( 'warning-tip' ) ) {\n\t\t\t\terror_tip_box.show( this, error_string, sec, true );\n\t\t\t} else {\n\t\t\t\terror_tip_box.show( this, error_string, sec );\n\t\t\t}\n\n\t\t};\n\n\t\tthis.hideErrorTip = function() {\n\n\t\t\tif ( Global.isSet( error_tip_box ) ) {\n\t\t\t\terror_tip_box.remove();\n\t\t\t}\n\n\t\t};\n\n\t\tthis.clearErrorStyle = function() {\n\t\t\t$( this ).removeClass( 'error-tip' );\n\t\t\t$( this ).removeClass( 'warning-tip' );\n\t\t\tthis.hideErrorTip();\n\t\t\terror_string = '';\n\t\t};\n\n\t\tthis.autoResize = function() {\n\t\t\tvar content_width, example_width;\n\t\t\tif ( !is_static_width ) {\n\t\t\t\tif ( mode === 'time' ) {\n\t\t\t\t\texample_width = Global.calculateTextWidth( LocalCacheData.getLoginUserPreference().time_format_display );\n\t\t\t\t} else if ( mode == 'time_unit' ) {\n\t\t\t\t\texample_width = Global.calculateTextWidth( LocalCacheData.getLoginUserPreference().time_unit_format_display );\n\t\t\t\t} else {\n\t\t\t\t\texample_width = 156;\n\t\t\t\t}\n\t\t\t\tcontent_width = Global.calculateTextWidth( $this.getValue(), {\n\t\t\t\t\tmin_width: example_width,\n\t\t\t\t\tmax_width: 200\n\t\t\t\t} );\n\n\t\t\t} else {\n\t\t\t\tif ( static_width.toString().indexOf( '%' ) > 0 ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texample_width = static_width;\n\t\t\t\tcontent_width = Global.calculateTextWidth( $this.getValue(), {\n\t\t\t\t\tmin_width: example_width,\n\t\t\t\t\tmax_width: static_width > 200 ? static_width : 200\n\t\t\t\t} );\n\t\t\t}\n\t\t\t$this.width( content_width + 'px' );\n\t\t};\n\n\t\tthis.each( function() {\n\t\t\tvar o = $.meta ? $.extend( {}, opts, $( this ).data() ) : opts;\n\t\t\tfield = o.field;\n\n\t\t\t//Set autocomplete widget option is defined, set it here.\n\t\t\tif ( o.autocomplete ) {\n\t\t\t\t$this.attr( 'autocomplete', o.autocomplete );\n\t\t\t}\n\n\t\t\tif ( o.hasOwnProperty( 'do_validate' ) ) {\n\t\t\t\tdo_validate = o.do_validate;\n\t\t\t}\n\n\t\t\tif ( o.validation_field ) {\n\t\t\t\tvalidation_field = o.validation_field;\n\t\t\t}\n\t\t\tif ( o.hasOwnProperty( 'display_na' ) ) {\n\t\t\t\tdisplay_na = o.display_na;\n\t\t\t}\n\t\t\tif ( o.hasOwnProperty( 'no_validate_timer_sec' ) && o.no_validate_timer_sec > 0 ) {\n\t\t\t\tno_validate_timer_sec = o.no_validate_timer_sec;\n\t\t\t}\n\t\t\thasKeyEvent = o.hasKeyEvent;\n\t\t\tneed_parser_date = o.need_parser_date;\n\t\t\tneed_parser_sec = o.need_parser_sec;\n\n\t\t\tif ( need_parser_date || need_parser_sec ) {\n\t\t\t\tapi_date = TTAPI.APITTDate;\n\t\t\t}\n\n\t\t\tif ( o.mode ) {\n\t\t\t\tmode = o.mode;\n\t\t\t}\n\n\t\t\tif ( o.width && ( o.width > 0 || o.width.indexOf( '%' ) > 0 ) ) {\n\t\t\t\t$this.width( o.width );\n\t\t\t\tstatic_width = o.width;\n\t\t\t\tis_static_width = true;\n\t\t\t}\n\n\t\t\tif ( o.disable_keyup_event ) {\n\t\t\t\tdisable_keyup_event = o.disable_keyup_event;\n\t\t\t}\n\n\t\t\tif ( mode === 'time' ) {\n\t\t\t\t$this.setPlaceHolder( LocalCacheData.getLoginUserPreference().time_format_display );\n\t\t\t} else if ( mode === 'time_unit' ) {\n\t\t\t\t$this.setPlaceHolder( LocalCacheData.getLoginUserPreference().time_unit_format_display );\n\t\t\t}\n\t\t\t$this.autoResize();\n\n\t\t\t$( this ).keydown( function( e ) {\n\t\t\t\t// key is not TAB and ENTER\n\t\t\t\tif ( hasKeyEvent && e.keyCode !== 9 && e.keyCode !== 13 ) {\n\t\t\t\t\t$this.trigger( 'formItemKeyDown', [$this] );\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\t$( this ).keyup( function( e ) {\n\t\t\t\tvar validate_sec = 1000;\n\t\t\t\tif ( e.keyCode === 9 || e.keyCode === 13 ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar is_valid_input = Global.isValidInputCodes( e.keyCode );\n\t\t\t\tif ( !is_valid_input ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t//don't clean event when click tab\n\t\t\t\tif ( validate_timer ) {\n\t\t\t\t\tclearTimeout( validate_timer );\n\t\t\t\t\tvalidate_timer = null;\n\t\t\t\t}\n\n\t\t\t\tif ( no_validate_timer ) {\n\t\t\t\t\tclearTimeout( no_validate_timer );\n\t\t\t\t\tno_validate_timer = null;\n\t\t\t\t}\n\t\t\t\tif ( hasKeyEvent ) {\n\t\t\t\t\t$this.trigger( 'formItemKeyUp', [$this] );\n\t\t\t\t}\n\t\t\t\tif ( error_string && error_string.length > 0 ) {\n\t\t\t\t\tvalidate_sec = 500;\n\t\t\t\t}\n\t\t\t\tif ( do_validate ) {\n\t\t\t\t\tvalidate_timer = setTimeout( function() {\n\t\t\t\t\t\tif ( check_box ) {\n\t\t\t\t\t\t\t$this.setCheckBox( true );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( need_parser_date || need_parser_sec ) {\n\t\t\t\t\t\t\tparsed_value = -1; // parse date when get value\n\t\t\t\t\t\t\tif ( !disable_keyup_event ) {\n\t\t\t\t\t\t\t\t$this.trigger( 'formItemChange', [$this, true] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif ( !disable_keyup_event ) {\n\t\t\t\t\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}, validate_sec );\n\t\t\t\t}\n\n\t\t\t\t// TO make sure the value is set to currentEditRecord when user typing it, but not trigger validate\n\t\t\t\t// Do this immediately instead wait for 300 ms.\n\t\t\t\tno_validate_timer = setTimeout( function() {\n\n\t\t\t\t\tif ( check_box ) {\n\t\t\t\t\t\t$this.setCheckBox( true );\n\t\t\t\t\t}\n\t\t\t\t\tif ( need_parser_date || need_parser_sec ) {\n\t\t\t\t\t\tparsed_value = -1; // parse date when get value\n\t\t\t\t\t\tif ( !disable_keyup_event ) {\n\t\t\t\t\t\t\t$this.trigger( 'formItemChange', [$this, true] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( !disable_keyup_event ) {\n\t\t\t\t\t\t\t$this.trigger( 'formItemChange', [$this, true] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, no_validate_timer_sec );\n\t\t\t} );\n\n\t\t\t$( this ).mouseover( function() {\n\n\t\t\t\tif ( enabled ) {\n\t\t\t\t\tif ( error_string && error_string.length > 0 ) {\n\t\t\t\t\t\t$this.showErrorTip( 20 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\t$( this ).mouseout( function() {\n\t\t\t\tif ( !$( $this ).is( ':focus' ) ) {\n\t\t\t\t\t$this.hideErrorTip();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t$( this ).change( function() {\n\t\t\t\t$this.trigger( 'keyup', [$this] );\n\t\t\t\t//#2226 - When datetime or time unit fields specify need_parser_date or need_parser_sec it does not set disable_keyup_event == true. To validate those fields on change we need to check for those values.\n\t\t\t\tif ( disable_keyup_event || need_parser_date || need_parser_sec ) {\n\t\t\t\t\t$this.trigger( 'formItemChange', [$this] );\n\t\t\t\t}\n\t\t\t\tif ( !need_parser_date && !need_parser_sec ) {\n\t\t\t\t\t$this.autoResize();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t$( this ).focusin( function() {\n\n\t\t\t\tif ( !enabled ) {\n\n\t\t\t\t\tif ( !check_box ) {\n\t\t\t\t\t\tif ( LocalCacheData.current_open_sub_controller &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_sub_controller.edit_view &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_sub_controller.is_viewing ) {\n\t\t\t\t\t\t\terror_string = LocalCacheData.current_open_sub_controller.getViewModeErrorMessage();\n\t\t\t\t\t\t\t$this.showErrorTip( 10 );\n\t\t\t\t\t\t} else if ( LocalCacheData.current_open_primary_controller &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.edit_view &&\n\t\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.is_viewing ) {\n\t\t\t\t\t\t\terror_string = LocalCacheData.current_open_primary_controller.getViewModeErrorMessage();\n\t\t\t\t\t\t\t$this.showErrorTip( 10 );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\tif ( error_string && error_string.length > 0 ) {\n\t\t\t\t\t\t$this.showErrorTip( 20 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\t$( this ).focusout( function() {\n\t\t\t\t$this.hideErrorTip();\n\t\t\t} );\n\n\t\t} );\n\n\t\treturn this;\n\n\t};\n\n\t$.fn.TTextInput.defaults = {};\n\t$.fn.TTextInput.html_template = ``;\n\n} )( jQuery );//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTI2NC5qcyIsIm1hcHBpbmdzIjoiO0FBQUE7O0FBRUE7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsNEJBQTRCOztBQUU1Qjs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQSxtQ0FBbUM7O0FBRW5DOztBQUVBOztBQUVBOztBQUVBLHlCQUF5Qjs7QUFFekI7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0EsTUFBTTs7QUFFTjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQyxzREFBc0QsZUFBZTtBQUNyRTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07O0FBRU4sS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdDQUFnQztBQUNoQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7O0FBRUwsSUFBSTs7QUFFSjs7QUFFQTs7QUFFQTtBQUNBOztBQUVBLEVBQUUsR0FBRyxNQUFNIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC93aWRnZXRzL3RleHRfaW5wdXQvVFRleHRJbnB1dC5qcz84MmRmIl0sInNvdXJjZXNDb250ZW50IjpbIiggZnVuY3Rpb24oICQgKSB7XG5cblx0JC5mbi5UVGV4dElucHV0ID0gZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdFx0dmFyIG9wdHMgPSAkLmV4dGVuZCgge30sICQuZm4uVFRleHRJbnB1dC5kZWZhdWx0cywgb3B0aW9ucyApO1xuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cdFx0dmFyIGZpZWxkO1xuXHRcdHZhciB2YWxpZGF0aW9uX2ZpZWxkO1xuXHRcdHZhciBlcnJvcl9zdHJpbmcgPSAnJztcblx0XHR2YXIgZXJyb3JfdGlwX2JveDtcblxuXHRcdHZhciBtYXNzX2VkaXRfbW9kZSA9IGZhbHNlO1xuXHRcdHZhciBjaGVja19ib3ggPSBudWxsO1xuXG5cdFx0dmFyIGVuYWJsZWQgPSB0cnVlO1xuXG5cdFx0dmFyIGhhc0tleUV2ZW50ID0gbnVsbDtcblxuXHRcdC8vRE9OVCBVU0UgVEhJUyBBTlkgTU9SRVxuXHRcdHZhciBuZWVkX3BhcnNlcl9kYXRlID0gZmFsc2U7XG5cblx0XHR2YXIgbmVlZF9wYXJzZXJfc2VjID0gZmFsc2U7XG5cblx0XHR2YXIgcGFyc2VkX3ZhbHVlID0gZmFsc2U7IC8vd29yayB3aXRoIG5lZWRfcGFyc2VyX2RhdGVcblxuXHRcdHZhciBhcGlfZGF0ZSA9IG51bGw7XG5cblx0XHR2YXIgdmFsaWRhdGVfdGltZXIgPSBudWxsO1xuXG5cdFx0dmFyIG5vX3ZhbGlkYXRlX3RpbWVyID0gbnVsbDtcblxuXHRcdHZhciBub192YWxpZGF0ZV90aW1lcl9zZWMgPSAwO1xuXG5cdFx0dmFyIHBhc3N3b3JkX3N0eWxlID0gZmFsc2U7XG5cblx0XHR2YXIgZGlzYWJsZV9rZXl1cF9ldmVudCA9IGZhbHNlOyAvL3NldCB0byBub3Qgc2VuZCBjaGFuZ2UgZXZlbnQgd2hlbiBtb3VzZXVwXG5cblx0XHR2YXIgbW9kZTtcblxuXHRcdHZhciBpc19zdGF0aWNfd2lkdGg7XG5cblx0XHR2YXIgc3RhdGljX3dpZHRoO1xuXG5cdFx0dmFyIGRpc3BsYXlfbmEgPSB0cnVlOyAvLyBEaXNwbGF5IE4vQSB3aGVuIG5vIHZhbHVlXG5cblx0XHQvLyB2YXIgY2FuY2VsX2RhdGVfcGFyc2UgPSBmYWxzZTtcblxuXHRcdHZhciBkb192YWxpZGF0ZSA9IHRydWU7XG5cblx0XHQvLyB2YXIgcGFyc2VEYXRlQXN5bmMgPSBmdW5jdGlvbiggY2FsbEJhY2sgKSB7XG5cdFx0Ly8gXHRwYXJzZWRfdmFsdWUgPSAtMTtcblx0XHQvLyBcdGlmICggIWFwaV9kYXRlICkge1xuXHRcdC8vIFx0XHRhcGlfZGF0ZSA9IFRUQVBJLkFQSVRURGF0ZTtcblx0XHQvLyBcdH1cblx0XHQvLyBcdGFwaV9kYXRlLnBhcnNlVGltZVVuaXQoICR0aGlzLnZhbCgpLCB7XG5cdFx0Ly8gXHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdC8vIFx0XHRcdGlmICggY2FuY2VsX2RhdGVfcGFyc2UgKSB7XG5cdFx0Ly8gXHRcdFx0XHRyZXR1cm47XG5cdFx0Ly8gXHRcdFx0fVxuXHRcdC8vIFx0XHRcdHBhcnNlZF92YWx1ZSA9IHJlc3VsdC5nZXRSZXN1bHQoKTtcblx0XHQvLyBcdFx0XHRpZiAoIGNhbGxCYWNrICkge1xuXHRcdC8vIFx0XHRcdFx0Y2FsbEJhY2soKTtcblx0XHQvLyBcdFx0XHR9XG5cdFx0Ly8gXHRcdFx0UHJvZ3Jlc3NCYXIuY2xvc2VPdmVybGF5KCk7XG5cdFx0Ly8gXHRcdH1cblx0XHQvLyBcdH0gKTtcblx0XHQvL1xuXHRcdC8vIFx0Ly9wYXJzZWRfdmFsdWUgPSBHbG9iYWwucGFyc2VUaW1lVW5pdCggJHRoaXMudmFsKCkgKTtcblx0XHQvLyB9O1xuXG5cdFx0dGhpcy5zZXRQbGFjZUhvbGRlciA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHQkdGhpcy5hdHRyKCAncGxhY2Vob2xkZXInLCB2YWwgKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXROZWVkUGFyc0RhdGUgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0bmVlZF9wYXJzZXJfZGF0ZSA9IHZhbDtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXROZWVkUGFyc2VTZWMgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0aWYgKCB2YWwgKSB7XG5cdFx0XHRcdC8vcGFyc2VkX3ZhbHVlID0gcGFyc2VEYXRlQXN5bmMoKTtcblx0XHRcdFx0cGFyc2VkX3ZhbHVlID0gR2xvYmFsLnBhcnNlVGltZVVuaXQoICR0aGlzLnZhbCgpICk7XG5cdFx0XHR9XG5cdFx0XHRuZWVkX3BhcnNlcl9zZWMgPSB2YWw7XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRFbmFibGVkID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gZW5hYmxlZDtcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRFbmFibGVkID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdGVuYWJsZWQgPSB2YWw7XG5cdFx0XHRpZiAoIHZhbCA9PT0gZmFsc2UgfHwgdmFsID09PSAnJyApIHtcblx0XHRcdFx0JHRoaXMuYXR0ciggJ3JlYWRvbmx5JywgJ3RydWUnICk7XG5cdFx0XHRcdCR0aGlzLmFkZENsYXNzKCAndC10ZXh0LWlucHV0LXJlYWRvbmx5JyApO1xuXHRcdFx0XHRpZiAoIGNoZWNrX2JveCApIHtcblx0XHRcdFx0XHRjaGVja19ib3guaGlkZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICggIXRoaXMuZ2V0VmFsdWUoKSAmJiBkaXNwbGF5X25hICkge1xuXHRcdFx0XHRcdHRoaXMudmFsKCAkLmkxOG4uXyggJ04vQScgKSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQkdGhpcy5yZW1vdmVBdHRyKCAncmVhZG9ubHknICk7XG5cdFx0XHRcdCR0aGlzLnJlbW92ZUNsYXNzKCAndC10ZXh0LWlucHV0LXJlYWRvbmx5JyApO1xuXHRcdFx0XHRpZiAoIGNoZWNrX2JveCApIHtcblx0XHRcdFx0XHRjaGVja19ib3guc2hvdygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICggdGhpcy52YWwoKSA9PT0gJC5pMThuLl8oICdOL0EnICkgKSB7XG5cdFx0XHRcdFx0dGhpcy52YWwoICcnICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLnNldFJlYWRPbmx5ID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdGlmICggdmFsICkge1xuXHRcdFx0XHQkdGhpcy5hdHRyKCAnZGlzYWJsZWQnLCAndHJ1ZScgKTtcblx0XHRcdFx0JHRoaXMuYWRkQ2xhc3MoICd0LXRleHQtaW5wdXQtcmVhZG9ubHktYmcnICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQkdGhpcy5yZW1vdmVBdHRyKCAnZGlzYWJsZWQnICk7XG5cdFx0XHRcdCR0aGlzLnJlbW92ZUNsYXNzKCAndC10ZXh0LWlucHV0LXJlYWRvbmx5LWJnJyApO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR0aGlzLnNldENoZWNrQm94ID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdGlmICggY2hlY2tfYm94ICkge1xuXHRcdFx0XHRjaGVja19ib3guY2hpbGRyZW4oKS5lcSggMCApWzBdLmNoZWNrZWQgPSB2YWw7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoaXMuaXNDaGVja2VkID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGNoZWNrX2JveCApIHtcblx0XHRcdFx0aWYgKCBjaGVja19ib3guY2hpbGRyZW4oKS5lcSggMCApWzBdLmNoZWNrZWQgPT09IHRydWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH07XG5cblx0XHR0aGlzLnNldE1hc3NFZGl0TW9kZSA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cblx0XHRcdG1hc3NfZWRpdF9tb2RlID0gdmFsO1xuXG5cdFx0XHRpZiAoIG1hc3NfZWRpdF9tb2RlICkge1xuXHRcdFx0XHRjaGVja19ib3ggPSAkKCAnIDxkaXYgY2xhc3M9XCJtYXNzLWVkaXQtY2hlY2tib3gtd3JhcHBlclwiPjxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cIm1hc3MtZWRpdC1jaGVja2JveFwiPjwvaW5wdXQ+JyArXG5cdFx0XHRcdFx0JzxsYWJlbCBmb3I9XCJjaGVja2JveC1pbnB1dC0xXCIgY2xhc3M9XCJpbnB1dC1oZWxwZXIgaW5wdXQtaGVscGVyLS1jaGVja2JveFwiPjwvbGFiZWw+PC9kaXY+JyApO1xuXHRcdFx0XHRjaGVja19ib3guaW5zZXJ0QmVmb3JlKCAkKCB0aGlzICkgKTtcblx0XHRcdFx0Y2hlY2tfYm94LmNoYW5nZSggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKCBuZWVkX3BhcnNlcl9kYXRlIHx8IG5lZWRfcGFyc2VyX3NlYyApIHtcblx0XHRcdFx0XHRcdHBhcnNlZF92YWx1ZSA9IEdsb2JhbC5wYXJzZVRpbWVVbml0KCAkdGhpcy52YWwoKSApO1xuXHRcdFx0XHRcdFx0Ly8gcGFyc2VEYXRlQXN5bmMoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0Ly8gXHQkdGhpcy50cmlnZ2VyKCAnZm9ybUl0ZW1DaGFuZ2UnLCBbJHRoaXNdICk7XG5cdFx0XHRcdFx0XHQvLyB9ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdCR0aGlzLnRyaWdnZXIoICdmb3JtSXRlbUNoYW5nZScsIFskdGhpc10gKTtcblx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdGlmICggaXNfc3RhdGljX3dpZHRoICYmIHN0YXRpY193aWR0aC50b1N0cmluZygpLmluZGV4T2YoICclJyApID4gMCApIHtcblx0XHRcdFx0XHQkdGhpcy5jc3MoICd3aWR0aCcsICdjYWxjKCcgKyBzdGF0aWNfd2lkdGggKyAnIC0gMjVweCknICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGlmICggY2hlY2tfYm94ICkge1xuXHRcdFx0XHRcdGNoZWNrX2JveC5yZW1vdmUoKTtcblx0XHRcdFx0XHRjaGVja19ib3ggPSBudWxsO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5zZXRGaWVsZCA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRmaWVsZCA9IHZhbDtcblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRGaWVsZCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGZpZWxkO1xuXHRcdH07XG5cblx0XHR0aGlzLmdldFZhbGlkYXRpb25GaWVsZCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHZhbGlkYXRpb25fZmllbGQ7XG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0SW5wdXRWYWx1ZSA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHR2YXIgdmFsID0gJHRoaXMudmFsKCk7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXG5cdFx0fTtcblx0XHR0aGlzLmdldFZhbHVlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgdmFsID0gJHRoaXMudmFsKCk7XG5cdFx0XHRpZiAoIHZhbCA9PT0gJC5pMThuLl8oICdOL0EnICkgKSB7XG5cdFx0XHRcdHZhbCA9ICcnO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBuZWVkX3BhcnNlcl9zZWMgfHwgbmVlZF9wYXJzZXJfZGF0ZSB8fCBwYXJzZWRfdmFsdWUgKSB7XG5cdFx0XHRcdGlmICggcGFyc2VkX3ZhbHVlID09PSAtMSApIHtcblx0XHRcdFx0XHRwYXJzZWRfdmFsdWUgPSBHbG9iYWwucGFyc2VUaW1lVW5pdCggdmFsICk7XG5cdFx0XHRcdFx0Ly8gY2FuY2VsX2RhdGVfcGFyc2UgPSB0cnVlOyAvLyBjYW5jZWwgb3JnaW5hbCBkYXRlIHBhcnNlIHByb2Nlc3Ncblx0XHRcdFx0XHQvLyBwYXJzZWRfdmFsdWUgPSBhcGlfZGF0ZS5wYXJzZVRpbWVVbml0KCB2YWwsIHsgYXN5bmM6IGZhbHNlIH0gKS5nZXRSZXN1bHQoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gcGFyc2VkX3ZhbHVlO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIHZhbDtcblx0XHRcdH1cblxuXHRcdH07XG5cblx0XHR0aGlzLnNldFZhbHVlID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdGlmICggIXZhbCAmJiB2YWwgIT09IDAgKSB7XG5cdFx0XHRcdHZhbCA9ICcnO1xuXHRcdFx0fVxuXHRcdFx0JHRoaXMudmFsKCB2YWwgKTtcblx0XHRcdGlmICggbmVlZF9wYXJzZXJfZGF0ZSApIHtcblx0XHRcdFx0Ly9wYXJzZURhdGVBc3luYygpO1xuXHRcdFx0XHRwYXJzZWRfdmFsdWUgPSBHbG9iYWwucGFyc2VUaW1lVW5pdCggJHRoaXMudmFsKCkgKTtcblx0XHRcdH0gZWxzZSBpZiAoIG5lZWRfcGFyc2VyX3NlYyApIHtcblx0XHRcdFx0cGFyc2VkX3ZhbHVlID0gdmFsO1xuXHRcdFx0XHQkdGhpcy52YWwoIEdsb2JhbC5nZXRUaW1lVW5pdCggdmFsICkgKTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5hdXRvUmVzaXplKCk7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0RXJyb3JTdHlsZSA9IGZ1bmN0aW9uKCBlcnJTdHIsIHNob3csIGlzV2FybmluZyApIHtcblx0XHRcdGlmICggaXNXYXJuaW5nICkge1xuXHRcdFx0XHQkKCB0aGlzICkuYWRkQ2xhc3MoICd3YXJuaW5nLXRpcCcgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdCQoIHRoaXMgKS5hZGRDbGFzcyggJ2Vycm9yLXRpcCcgKTtcblx0XHRcdH1cblx0XHRcdGVycm9yX3N0cmluZyA9IGVyclN0cjtcblxuXHRcdFx0aWYgKCBzaG93ICkge1xuXHRcdFx0XHR0aGlzLnNob3dFcnJvclRpcCgpO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR0aGlzLnNldFdpZHRoID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdGlmICggdmFsICYmICggdmFsID4gMCB8fCB2YWwuaW5kZXhPZiggJyUnICkgPiAwICkgKSB7XG5cdFx0XHRcdCR0aGlzLndpZHRoKCB2YWwgKTtcblx0XHRcdFx0c3RhdGljX3dpZHRoID0gdmFsO1xuXHRcdFx0XHRpc19zdGF0aWNfd2lkdGggPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR0aGlzLnNob3dFcnJvclRpcCA9IGZ1bmN0aW9uKCBzZWMgKSB7XG5cblx0XHRcdGlmICggIUdsb2JhbC5pc1NldCggc2VjICkgKSB7XG5cdFx0XHRcdHNlYyA9IDI7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggIWVycm9yX3RpcF9ib3ggKSB7XG5cdFx0XHRcdGVycm9yX3RpcF9ib3ggPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggV2lkZ2V0TmFtZXNEaWMuRVJST1JfVE9PTFRJUCApO1xuXHRcdFx0XHRlcnJvcl90aXBfYm94ID0gZXJyb3JfdGlwX2JveC5FcnJvclRpcEJveCgpO1xuXHRcdFx0fVxuXHRcdFx0ZXJyb3JfdGlwX2JveC5jYW5jZWxSZW1vdmUoKTtcblxuXHRcdFx0aWYgKCAkKCB0aGlzICkuaGFzQ2xhc3MoICd3YXJuaW5nLXRpcCcgKSApIHtcblx0XHRcdFx0ZXJyb3JfdGlwX2JveC5zaG93KCB0aGlzLCBlcnJvcl9zdHJpbmcsIHNlYywgdHJ1ZSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZXJyb3JfdGlwX2JveC5zaG93KCB0aGlzLCBlcnJvcl9zdHJpbmcsIHNlYyApO1xuXHRcdFx0fVxuXG5cdFx0fTtcblxuXHRcdHRoaXMuaGlkZUVycm9yVGlwID0gZnVuY3Rpb24oKSB7XG5cblx0XHRcdGlmICggR2xvYmFsLmlzU2V0KCBlcnJvcl90aXBfYm94ICkgKSB7XG5cdFx0XHRcdGVycm9yX3RpcF9ib3gucmVtb3ZlKCk7XG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5jbGVhckVycm9yU3R5bGUgPSBmdW5jdGlvbigpIHtcblx0XHRcdCQoIHRoaXMgKS5yZW1vdmVDbGFzcyggJ2Vycm9yLXRpcCcgKTtcblx0XHRcdCQoIHRoaXMgKS5yZW1vdmVDbGFzcyggJ3dhcm5pbmctdGlwJyApO1xuXHRcdFx0dGhpcy5oaWRlRXJyb3JUaXAoKTtcblx0XHRcdGVycm9yX3N0cmluZyA9ICcnO1xuXHRcdH07XG5cblx0XHR0aGlzLmF1dG9SZXNpemUgPSBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBjb250ZW50X3dpZHRoLCBleGFtcGxlX3dpZHRoO1xuXHRcdFx0aWYgKCAhaXNfc3RhdGljX3dpZHRoICkge1xuXHRcdFx0XHRpZiAoIG1vZGUgPT09ICd0aW1lJyApIHtcblx0XHRcdFx0XHRleGFtcGxlX3dpZHRoID0gR2xvYmFsLmNhbGN1bGF0ZVRleHRXaWR0aCggTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLnRpbWVfZm9ybWF0X2Rpc3BsYXkgKTtcblx0XHRcdFx0fSBlbHNlIGlmICggbW9kZSA9PSAndGltZV91bml0JyApIHtcblx0XHRcdFx0XHRleGFtcGxlX3dpZHRoID0gR2xvYmFsLmNhbGN1bGF0ZVRleHRXaWR0aCggTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLnRpbWVfdW5pdF9mb3JtYXRfZGlzcGxheSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGV4YW1wbGVfd2lkdGggPSAxNTY7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y29udGVudF93aWR0aCA9IEdsb2JhbC5jYWxjdWxhdGVUZXh0V2lkdGgoICR0aGlzLmdldFZhbHVlKCksIHtcblx0XHRcdFx0XHRtaW5fd2lkdGg6IGV4YW1wbGVfd2lkdGgsXG5cdFx0XHRcdFx0bWF4X3dpZHRoOiAyMDBcblx0XHRcdFx0fSApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAoIHN0YXRpY193aWR0aC50b1N0cmluZygpLmluZGV4T2YoICclJyApID4gMCApIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0ZXhhbXBsZV93aWR0aCA9IHN0YXRpY193aWR0aDtcblx0XHRcdFx0Y29udGVudF93aWR0aCA9IEdsb2JhbC5jYWxjdWxhdGVUZXh0V2lkdGgoICR0aGlzLmdldFZhbHVlKCksIHtcblx0XHRcdFx0XHRtaW5fd2lkdGg6IGV4YW1wbGVfd2lkdGgsXG5cdFx0XHRcdFx0bWF4X3dpZHRoOiBzdGF0aWNfd2lkdGggPiAyMDAgPyBzdGF0aWNfd2lkdGggOiAyMDBcblx0XHRcdFx0fSApO1xuXHRcdFx0fVxuXHRcdFx0JHRoaXMud2lkdGgoIGNvbnRlbnRfd2lkdGggKyAncHgnICk7XG5cdFx0fTtcblxuXHRcdHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbyA9ICQubWV0YSA/ICQuZXh0ZW5kKCB7fSwgb3B0cywgJCggdGhpcyApLmRhdGEoKSApIDogb3B0cztcblx0XHRcdGZpZWxkID0gby5maWVsZDtcblxuXHRcdFx0Ly9TZXQgYXV0b2NvbXBsZXRlIHdpZGdldCBvcHRpb24gaXMgZGVmaW5lZCwgc2V0IGl0IGhlcmUuXG5cdFx0XHRpZiAoIG8uYXV0b2NvbXBsZXRlICkge1xuXHRcdFx0XHQkdGhpcy5hdHRyKCAnYXV0b2NvbXBsZXRlJywgby5hdXRvY29tcGxldGUgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLmhhc093blByb3BlcnR5KCAnZG9fdmFsaWRhdGUnICkgKSB7XG5cdFx0XHRcdGRvX3ZhbGlkYXRlID0gby5kb192YWxpZGF0ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLnZhbGlkYXRpb25fZmllbGQgKSB7XG5cdFx0XHRcdHZhbGlkYXRpb25fZmllbGQgPSBvLnZhbGlkYXRpb25fZmllbGQ7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIG8uaGFzT3duUHJvcGVydHkoICdkaXNwbGF5X25hJyApICkge1xuXHRcdFx0XHRkaXNwbGF5X25hID0gby5kaXNwbGF5X25hO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBvLmhhc093blByb3BlcnR5KCAnbm9fdmFsaWRhdGVfdGltZXJfc2VjJyApICYmIG8ubm9fdmFsaWRhdGVfdGltZXJfc2VjID4gMCApIHtcblx0XHRcdFx0bm9fdmFsaWRhdGVfdGltZXJfc2VjID0gby5ub192YWxpZGF0ZV90aW1lcl9zZWM7XG5cdFx0XHR9XG5cdFx0XHRoYXNLZXlFdmVudCA9IG8uaGFzS2V5RXZlbnQ7XG5cdFx0XHRuZWVkX3BhcnNlcl9kYXRlID0gby5uZWVkX3BhcnNlcl9kYXRlO1xuXHRcdFx0bmVlZF9wYXJzZXJfc2VjID0gby5uZWVkX3BhcnNlcl9zZWM7XG5cblx0XHRcdGlmICggbmVlZF9wYXJzZXJfZGF0ZSB8fCBuZWVkX3BhcnNlcl9zZWMgKSB7XG5cdFx0XHRcdGFwaV9kYXRlID0gVFRBUEkuQVBJVFREYXRlO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG8ubW9kZSApIHtcblx0XHRcdFx0bW9kZSA9IG8ubW9kZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLndpZHRoICYmICggby53aWR0aCA+IDAgfHwgby53aWR0aC5pbmRleE9mKCAnJScgKSA+IDAgKSApIHtcblx0XHRcdFx0JHRoaXMud2lkdGgoIG8ud2lkdGggKTtcblx0XHRcdFx0c3RhdGljX3dpZHRoID0gby53aWR0aDtcblx0XHRcdFx0aXNfc3RhdGljX3dpZHRoID0gdHJ1ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvLmRpc2FibGVfa2V5dXBfZXZlbnQgKSB7XG5cdFx0XHRcdGRpc2FibGVfa2V5dXBfZXZlbnQgPSBvLmRpc2FibGVfa2V5dXBfZXZlbnQ7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggbW9kZSA9PT0gJ3RpbWUnICkge1xuXHRcdFx0XHQkdGhpcy5zZXRQbGFjZUhvbGRlciggTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLnRpbWVfZm9ybWF0X2Rpc3BsYXkgKTtcblx0XHRcdH0gZWxzZSBpZiAoIG1vZGUgPT09ICd0aW1lX3VuaXQnICkge1xuXHRcdFx0XHQkdGhpcy5zZXRQbGFjZUhvbGRlciggTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyUHJlZmVyZW5jZSgpLnRpbWVfdW5pdF9mb3JtYXRfZGlzcGxheSApO1xuXHRcdFx0fVxuXHRcdFx0JHRoaXMuYXV0b1Jlc2l6ZSgpO1xuXG5cdFx0XHQkKCB0aGlzICkua2V5ZG93biggZnVuY3Rpb24oIGUgKSB7XG5cdFx0XHRcdC8vIGtleSBpcyBub3QgVEFCIGFuZCBFTlRFUlxuXHRcdFx0XHRpZiAoIGhhc0tleUV2ZW50ICYmIGUua2V5Q29kZSAhPT0gOSAmJiBlLmtleUNvZGUgIT09IDEzICkge1xuXHRcdFx0XHRcdCR0aGlzLnRyaWdnZXIoICdmb3JtSXRlbUtleURvd24nLCBbJHRoaXNdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0fSApO1xuXG5cdFx0XHQkKCB0aGlzICkua2V5dXAoIGZ1bmN0aW9uKCBlICkge1xuXHRcdFx0XHR2YXIgdmFsaWRhdGVfc2VjID0gMTAwMDtcblx0XHRcdFx0aWYgKCBlLmtleUNvZGUgPT09IDkgfHwgZS5rZXlDb2RlID09PSAxMyApIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0dmFyIGlzX3ZhbGlkX2lucHV0ID0gR2xvYmFsLmlzVmFsaWRJbnB1dENvZGVzKCBlLmtleUNvZGUgKTtcblx0XHRcdFx0aWYgKCAhaXNfdmFsaWRfaW5wdXQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vZG9uJ3QgY2xlYW4gZXZlbnQgd2hlbiBjbGljayB0YWJcblx0XHRcdFx0aWYgKCB2YWxpZGF0ZV90aW1lciApIHtcblx0XHRcdFx0XHRjbGVhclRpbWVvdXQoIHZhbGlkYXRlX3RpbWVyICk7XG5cdFx0XHRcdFx0dmFsaWRhdGVfdGltZXIgPSBudWxsO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBub192YWxpZGF0ZV90aW1lciApIHtcblx0XHRcdFx0XHRjbGVhclRpbWVvdXQoIG5vX3ZhbGlkYXRlX3RpbWVyICk7XG5cdFx0XHRcdFx0bm9fdmFsaWRhdGVfdGltZXIgPSBudWxsO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICggaGFzS2V5RXZlbnQgKSB7XG5cdFx0XHRcdFx0JHRoaXMudHJpZ2dlciggJ2Zvcm1JdGVtS2V5VXAnLCBbJHRoaXNdICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBlcnJvcl9zdHJpbmcgJiYgZXJyb3Jfc3RyaW5nLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRcdFx0dmFsaWRhdGVfc2VjID0gNTAwO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICggZG9fdmFsaWRhdGUgKSB7XG5cdFx0XHRcdFx0dmFsaWRhdGVfdGltZXIgPSBzZXRUaW1lb3V0KCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdGlmICggY2hlY2tfYm94ICkge1xuXHRcdFx0XHRcdFx0XHQkdGhpcy5zZXRDaGVja0JveCggdHJ1ZSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKCBuZWVkX3BhcnNlcl9kYXRlIHx8IG5lZWRfcGFyc2VyX3NlYyApIHtcblx0XHRcdFx0XHRcdFx0cGFyc2VkX3ZhbHVlID0gLTE7IC8vIHBhcnNlIGRhdGUgd2hlbiBnZXQgdmFsdWVcblx0XHRcdFx0XHRcdFx0aWYgKCAhZGlzYWJsZV9rZXl1cF9ldmVudCApIHtcblx0XHRcdFx0XHRcdFx0XHQkdGhpcy50cmlnZ2VyKCAnZm9ybUl0ZW1DaGFuZ2UnLCBbJHRoaXMsIHRydWVdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGlmICggIWRpc2FibGVfa2V5dXBfZXZlbnQgKSB7XG5cdFx0XHRcdFx0XHRcdFx0JHRoaXMudHJpZ2dlciggJ2Zvcm1JdGVtQ2hhbmdlJywgWyR0aGlzXSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR9LCB2YWxpZGF0ZV9zZWMgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFRPIG1ha2Ugc3VyZSB0aGUgdmFsdWUgaXMgc2V0IHRvIGN1cnJlbnRFZGl0UmVjb3JkIHdoZW4gdXNlciB0eXBpbmcgaXQsIGJ1dCBub3QgdHJpZ2dlciB2YWxpZGF0ZVxuXHRcdFx0XHQvLyBEbyB0aGlzIGltbWVkaWF0ZWx5IGluc3RlYWQgd2FpdCBmb3IgMzAwIG1zLlxuXHRcdFx0XHRub192YWxpZGF0ZV90aW1lciA9IHNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdFx0aWYgKCBjaGVja19ib3ggKSB7XG5cdFx0XHRcdFx0XHQkdGhpcy5zZXRDaGVja0JveCggdHJ1ZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIG5lZWRfcGFyc2VyX2RhdGUgfHwgbmVlZF9wYXJzZXJfc2VjICkge1xuXHRcdFx0XHRcdFx0cGFyc2VkX3ZhbHVlID0gLTE7IC8vIHBhcnNlIGRhdGUgd2hlbiBnZXQgdmFsdWVcblx0XHRcdFx0XHRcdGlmICggIWRpc2FibGVfa2V5dXBfZXZlbnQgKSB7XG5cdFx0XHRcdFx0XHRcdCR0aGlzLnRyaWdnZXIoICdmb3JtSXRlbUNoYW5nZScsIFskdGhpcywgdHJ1ZV0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0aWYgKCAhZGlzYWJsZV9rZXl1cF9ldmVudCApIHtcblx0XHRcdFx0XHRcdFx0JHRoaXMudHJpZ2dlciggJ2Zvcm1JdGVtQ2hhbmdlJywgWyR0aGlzLCB0cnVlXSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSwgbm9fdmFsaWRhdGVfdGltZXJfc2VjICk7XG5cdFx0XHR9ICk7XG5cblx0XHRcdCQoIHRoaXMgKS5tb3VzZW92ZXIoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdGlmICggZW5hYmxlZCApIHtcblx0XHRcdFx0XHRpZiAoIGVycm9yX3N0cmluZyAmJiBlcnJvcl9zdHJpbmcubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHRcdCR0aGlzLnNob3dFcnJvclRpcCggMjAgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0fSApO1xuXG5cdFx0XHQkKCB0aGlzICkubW91c2VvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoICEkKCAkdGhpcyApLmlzKCAnOmZvY3VzJyApICkge1xuXHRcdFx0XHRcdCR0aGlzLmhpZGVFcnJvclRpcCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cblx0XHRcdCQoIHRoaXMgKS5jaGFuZ2UoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQkdGhpcy50cmlnZ2VyKCAna2V5dXAnLCBbJHRoaXNdICk7XG5cdFx0XHRcdC8vIzIyMjYgLSBXaGVuIGRhdGV0aW1lIG9yIHRpbWUgdW5pdCBmaWVsZHMgc3BlY2lmeSBuZWVkX3BhcnNlcl9kYXRlIG9yIG5lZWRfcGFyc2VyX3NlYyBpdCBkb2VzIG5vdCBzZXQgZGlzYWJsZV9rZXl1cF9ldmVudCA9PSB0cnVlLiBUbyB2YWxpZGF0ZSB0aG9zZSBmaWVsZHMgb24gY2hhbmdlIHdlIG5lZWQgdG8gY2hlY2sgZm9yIHRob3NlIHZhbHVlcy5cblx0XHRcdFx0aWYgKCBkaXNhYmxlX2tleXVwX2V2ZW50IHx8IG5lZWRfcGFyc2VyX2RhdGUgfHwgbmVlZF9wYXJzZXJfc2VjICkge1xuXHRcdFx0XHRcdCR0aGlzLnRyaWdnZXIoICdmb3JtSXRlbUNoYW5nZScsIFskdGhpc10gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoICFuZWVkX3BhcnNlcl9kYXRlICYmICFuZWVkX3BhcnNlcl9zZWMgKSB7XG5cdFx0XHRcdFx0JHRoaXMuYXV0b1Jlc2l6ZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cblx0XHRcdCQoIHRoaXMgKS5mb2N1c2luKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHRpZiAoICFlbmFibGVkICkge1xuXG5cdFx0XHRcdFx0aWYgKCAhY2hlY2tfYm94ICkge1xuXHRcdFx0XHRcdFx0aWYgKCBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fc3ViX2NvbnRyb2xsZXIgJiZcblx0XHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyLmVkaXRfdmlldyAmJlxuXHRcdFx0XHRcdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fc3ViX2NvbnRyb2xsZXIuaXNfdmlld2luZyApIHtcblx0XHRcdFx0XHRcdFx0ZXJyb3Jfc3RyaW5nID0gTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyLmdldFZpZXdNb2RlRXJyb3JNZXNzYWdlKCk7XG5cdFx0XHRcdFx0XHRcdCR0aGlzLnNob3dFcnJvclRpcCggMTAgKTtcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIgJiZcblx0XHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5lZGl0X3ZpZXcgJiZcblx0XHRcdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlci5pc192aWV3aW5nICkge1xuXHRcdFx0XHRcdFx0XHRlcnJvcl9zdHJpbmcgPSBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmdldFZpZXdNb2RlRXJyb3JNZXNzYWdlKCk7XG5cdFx0XHRcdFx0XHRcdCR0aGlzLnNob3dFcnJvclRpcCggMTAgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpZiAoIGVycm9yX3N0cmluZyAmJiBlcnJvcl9zdHJpbmcubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0XHRcdCR0aGlzLnNob3dFcnJvclRpcCggMjAgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0fSApO1xuXG5cdFx0XHQkKCB0aGlzICkuZm9jdXNvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQkdGhpcy5oaWRlRXJyb3JUaXAoKTtcblx0XHRcdH0gKTtcblxuXHRcdH0gKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH07XG5cblx0JC5mbi5UVGV4dElucHV0LmRlZmF1bHRzID0ge307XG5cdCQuZm4uVFRleHRJbnB1dC5odG1sX3RlbXBsYXRlID0gYDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwidC10ZXh0LWlucHV0XCIgYXV0b2NvbXBsZXRlPVwidGltZXRyZXgtbm8tYXV0by1maWxsXCIvPmA7XG5cbn0gKSggalF1ZXJ5ICk7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///9264\n")},8287:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/* provided dependency */ var jQuery = __webpack_require__(9755);\n( function( $ ) {\n\n\t$.fn.ViewMinTabBar = function( options ) {\n\t\tvar opts = $.extend( {}, $.fn.ViewMinTabBar.defaults, options );\n\n\t\tvar $this = this;\n\n\t\tGlobal.addCss( 'global/widgets/view_min_tab/ViewMinTab.css' );\n\n\t\tvar createTab = function( view_id, view_label, url ) {\n\t\t\tvar tab = $( Global.loadWidgetByName( WidgetNamesDic.VIEW_MIN_TAB ) );\n\t\t\tvar view_name = tab.find( '.view-name' );\n\t\t\tview_name.text( view_label );\n\t\t\ttab.attr( 'id', 'min_tab_' + view_id );\n\n\t\t\ttab.attr( 'view_url', url );\n\n\t\t\tsetTimeout( function() {\n\t\t\t\ttab.addClass( 'show' );\n\t\t\t}, 100 );\n\n\t\t\tvar close_btn = tab.find( '.close-btn' );\n\n\t\t\ttab.unbind( 'click' ).click( function() {\n\t\t\t\tGlobal.setUINotready();\n\t\t\t\tvar view_id = $( this ).attr( 'id' ).replace( 'min_tab_', '' );\n\t\t\t\tvar url = $( this ).attr( 'view_url' );\n\t\t\t\tGlobal.removeViewTab( view_id );\n\n\t\t\t\tswitch ( view_id ) {\n\t\t\t\t\tcase 'ProcessPayrollWizard':\n\t\t\t\t\t\tIndexViewController.openWizard( view_id );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'PayrollRemittanceAgencyEventWizardController':\n\t\t\t\t\t\tIndexViewController.openWizardController( 'PayrollRemittanceAgencyEventWizardController' );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n//\t\t\t\t\t\tIndexViewController.goToView( view_id );\n\t\t\t\t\t\tGlobal.setURLToBrowser( url );\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\tclose_btn.unbind( 'click' ).click( function() {\n\t\t\t\tvar view_id = $( this ).parent().attr( 'id' ).replace( 'min_tab_', '' );\n\t\t\t\tGlobal.removeViewTab( view_id );\n\t\t\t} );\n\n\t\t\t$this.append( tab );\n\t\t};\n\n\t\tthis.buildTabs = function( tab_map ) {\n\n\t\t\t//$this.empty();\n\t\t\tvar i = 0;\n\t\t\tfor ( var key in tab_map ) {\n\t\t\t\tif ( tab_map.hasOwnProperty( key ) && key.indexOf( '_url' ) === -1 ) {\n\t\t\t\t\tvar view_id = key;\n\t\t\t\t\tvar view_label = tab_map[key];\n\t\t\t\t\tvar view_url = tab_map[key + '_url'];\n\t\t\t\t\tif ( $( '#min_tab_' + view_id ).length === 0 ) {\n\t\t\t\t\t\tcreateTab( view_id, view_label, view_url );\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\ti = i + 1;\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.each( function() {\n\n\t\t\tvar o = $.meta ? $.extend( {}, opts, $( this ).data() ) : opts;\n\n\t\t} );\n\n\t\treturn this;\n\n\t};\n\n\t$.fn.ViewMinTabBar.defaults = {};\n\t$.fn.ViewMinTabBar.html = {\n\t\ttab: `\n\t\t
    \n\t\t\t\n\t\t\t\n\t\t
    `,\n\t\ttab_bar: `
    `\n\t};\n\n} )( jQuery );//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODI4Ny5qcyIsIm1hcHBpbmdzIjoiO0FBQUE7O0FBRUE7QUFDQSx5QkFBeUI7O0FBRXpCOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLElBQUk7O0FBRUo7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUEsZ0NBQWdDOztBQUVoQyxJQUFJOztBQUVKOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxFQUFFLEdBQUcsTUFBTSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS9nbG9iYWwvd2lkZ2V0cy92aWV3X21pbl90YWIvVmlld01pblRhYkJhci5qcz9mODI5Il0sInNvdXJjZXNDb250ZW50IjpbIiggZnVuY3Rpb24oICQgKSB7XG5cblx0JC5mbi5WaWV3TWluVGFiQmFyID0gZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdFx0dmFyIG9wdHMgPSAkLmV4dGVuZCgge30sICQuZm4uVmlld01pblRhYkJhci5kZWZhdWx0cywgb3B0aW9ucyApO1xuXG5cdFx0dmFyICR0aGlzID0gdGhpcztcblxuXHRcdEdsb2JhbC5hZGRDc3MoICdnbG9iYWwvd2lkZ2V0cy92aWV3X21pbl90YWIvVmlld01pblRhYi5jc3MnICk7XG5cblx0XHR2YXIgY3JlYXRlVGFiID0gZnVuY3Rpb24oIHZpZXdfaWQsIHZpZXdfbGFiZWwsIHVybCApIHtcblx0XHRcdHZhciB0YWIgPSAkKCBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggV2lkZ2V0TmFtZXNEaWMuVklFV19NSU5fVEFCICkgKTtcblx0XHRcdHZhciB2aWV3X25hbWUgPSB0YWIuZmluZCggJy52aWV3LW5hbWUnICk7XG5cdFx0XHR2aWV3X25hbWUudGV4dCggdmlld19sYWJlbCApO1xuXHRcdFx0dGFiLmF0dHIoICdpZCcsICdtaW5fdGFiXycgKyB2aWV3X2lkICk7XG5cblx0XHRcdHRhYi5hdHRyKCAndmlld191cmwnLCB1cmwgKTtcblxuXHRcdFx0c2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHRhYi5hZGRDbGFzcyggJ3Nob3cnICk7XG5cdFx0XHR9LCAxMDAgKTtcblxuXHRcdFx0dmFyIGNsb3NlX2J0biA9IHRhYi5maW5kKCAnLmNsb3NlLWJ0bicgKTtcblxuXHRcdFx0dGFiLnVuYmluZCggJ2NsaWNrJyApLmNsaWNrKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0R2xvYmFsLnNldFVJTm90cmVhZHkoKTtcblx0XHRcdFx0dmFyIHZpZXdfaWQgPSAkKCB0aGlzICkuYXR0ciggJ2lkJyApLnJlcGxhY2UoICdtaW5fdGFiXycsICcnICk7XG5cdFx0XHRcdHZhciB1cmwgPSAkKCB0aGlzICkuYXR0ciggJ3ZpZXdfdXJsJyApO1xuXHRcdFx0XHRHbG9iYWwucmVtb3ZlVmlld1RhYiggdmlld19pZCApO1xuXG5cdFx0XHRcdHN3aXRjaCAoIHZpZXdfaWQgKSB7XG5cdFx0XHRcdFx0Y2FzZSAnUHJvY2Vzc1BheXJvbGxXaXphcmQnOlxuXHRcdFx0XHRcdFx0SW5kZXhWaWV3Q29udHJvbGxlci5vcGVuV2l6YXJkKCB2aWV3X2lkICk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdQYXlyb2xsUmVtaXR0YW5jZUFnZW5jeUV2ZW50V2l6YXJkQ29udHJvbGxlcic6XG5cdFx0XHRcdFx0XHRJbmRleFZpZXdDb250cm9sbGVyLm9wZW5XaXphcmRDb250cm9sbGVyKCAnUGF5cm9sbFJlbWl0dGFuY2VBZ2VuY3lFdmVudFdpemFyZENvbnRyb2xsZXInICk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRkZWZhdWx0OlxuLy9cdFx0XHRcdFx0XHRJbmRleFZpZXdDb250cm9sbGVyLmdvVG9WaWV3KCB2aWV3X2lkICk7XG5cdFx0XHRcdFx0XHRHbG9iYWwuc2V0VVJMVG9Ccm93c2VyKCB1cmwgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9ICk7XG5cblx0XHRcdGNsb3NlX2J0bi51bmJpbmQoICdjbGljaycgKS5jbGljayggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciB2aWV3X2lkID0gJCggdGhpcyApLnBhcmVudCgpLmF0dHIoICdpZCcgKS5yZXBsYWNlKCAnbWluX3RhYl8nLCAnJyApO1xuXHRcdFx0XHRHbG9iYWwucmVtb3ZlVmlld1RhYiggdmlld19pZCApO1xuXHRcdFx0fSApO1xuXG5cdFx0XHQkdGhpcy5hcHBlbmQoIHRhYiApO1xuXHRcdH07XG5cblx0XHR0aGlzLmJ1aWxkVGFicyA9IGZ1bmN0aW9uKCB0YWJfbWFwICkge1xuXG5cdFx0XHQvLyR0aGlzLmVtcHR5KCk7XG5cdFx0XHR2YXIgaSA9IDA7XG5cdFx0XHRmb3IgKCB2YXIga2V5IGluIHRhYl9tYXAgKSB7XG5cdFx0XHRcdGlmICggdGFiX21hcC5oYXNPd25Qcm9wZXJ0eSgga2V5ICkgJiYga2V5LmluZGV4T2YoICdfdXJsJyApID09PSAtMSApIHtcblx0XHRcdFx0XHR2YXIgdmlld19pZCA9IGtleTtcblx0XHRcdFx0XHR2YXIgdmlld19sYWJlbCA9IHRhYl9tYXBba2V5XTtcblx0XHRcdFx0XHR2YXIgdmlld191cmwgPSB0YWJfbWFwW2tleSArICdfdXJsJ107XG5cdFx0XHRcdFx0aWYgKCAkKCAnI21pbl90YWJfJyArIHZpZXdfaWQgKS5sZW5ndGggPT09IDAgKSB7XG5cdFx0XHRcdFx0XHRjcmVhdGVUYWIoIHZpZXdfaWQsIHZpZXdfbGFiZWwsIHZpZXdfdXJsICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblx0XHRcdFx0aSA9IGkgKyAxO1xuXG5cdFx0XHR9XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0dmFyIG8gPSAkLm1ldGEgPyAkLmV4dGVuZCgge30sIG9wdHMsICQoIHRoaXMgKS5kYXRhKCkgKSA6IG9wdHM7XG5cblx0XHR9ICk7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9O1xuXG5cdCQuZm4uVmlld01pblRhYkJhci5kZWZhdWx0cyA9IHt9O1xuXHQkLmZuLlZpZXdNaW5UYWJCYXIuaHRtbCA9IHtcblx0XHR0YWI6IGBcblx0XHQ8ZGl2IGNsYXNzPVwicC1idXR0b24gcC1jb21wb25lbnQgdmlldy1taW4tdGFiIGFuaW1hdGVkXCI+XG5cdFx0XHQ8c3BhbiBjbGFzcz1cInZpZXctbmFtZVwiPjwvc3Bhbj5cblx0XHRcdDxzcGFuIGNsYXNzPVwidHRpY29uIHR0aWNvbi1jYW5jZWxfYmxhY2tfMjRkcCBjbG9zZS1idG5cIj48L3NwYW4+XG5cdFx0PC9kaXY+YCxcblx0XHR0YWJfYmFyOiBgPGRpdiBjbGFzcz1cInZpZXctbWluLXRhYi1iYXJcIj48L2Rpdj5gXG5cdH07XG5cbn0gKSggalF1ZXJ5ICk7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8287\n")},9769:(t,g,I)=>{var n={"./awesomebox/AComboBox":[2897,7,"awesomebox-AComboBox"],"./awesomebox/AComboBox.js":[2897,7,"awesomebox-AComboBox"],"./awesomebox/ADropDown":[3234,7,"awesomebox-ADropDown"],"./awesomebox/ADropDown.js":[3234,7,"awesomebox-ADropDown"],"./awesomebox/ALayoutCache":[4243,9,"awesomebox-ALayoutCache"],"./awesomebox/ALayoutCache.js":[4243,9,"awesomebox-ALayoutCache"],"./awesomebox/ASearchInput":[7040,7,"awesomebox-ASearchInput"],"./awesomebox/ASearchInput.js":[7040,7,"awesomebox-ASearchInput"],"./checkbox/TCheckbox":[5529,7,"checkbox-TCheckbox"],"./checkbox/TCheckbox.js":[5529,7,"checkbox-TCheckbox"],"./color-picker/TColorPicker":[3161,9,"color-picker-TColorPicker"],"./color-picker/TColorPicker.js":[3161,9,"color-picker-TColorPicker"],"./column_editor/ColumnEditor":[9613,7,"column_editor-ColumnEditor"],"./column_editor/ColumnEditor.js":[9613,7,"column_editor-ColumnEditor"],"./combobox/TComboBox":[5519,7,"combobox-TComboBox"],"./combobox/TComboBox.js":[5519,7,"combobox-TComboBox"],"./datepicker/TDatePicker":[84,7,"datepicker-TDatePicker"],"./datepicker/TDatePicker.js":[84,7,"datepicker-TDatePicker"],"./datepicker/TRangePicker":[9300,7,"datepicker-TRangePicker"],"./datepicker/TRangePicker.js":[9300,7,"datepicker-TRangePicker"],"./error_tip/ErrorTipBox":[9876,7,"error_tip-ErrorTipBox"],"./error_tip/ErrorTipBox.js":[9876,7,"error_tip-ErrorTipBox"],"./feedback/TFeedback":[8218,7,"feedback-TFeedback"],"./feedback/TFeedback.js":[8218,7,"feedback-TFeedback"],"./filebrowser/CameraBrowser":[8128,7,"filebrowser-CameraBrowser"],"./filebrowser/CameraBrowser.js":[8128,7,"filebrowser-CameraBrowser"],"./filebrowser/TImage":[1469,7,"filebrowser-TImage"],"./filebrowser/TImage.js":[1469,7,"filebrowser-TImage"],"./filebrowser/TImageAdvBrowser":[8243,7,"filebrowser-TImageAdvBrowser"],"./filebrowser/TImageAdvBrowser.js":[8243,7,"filebrowser-TImageAdvBrowser"],"./filebrowser/TImageBrowser":[8326,7,"filebrowser-TImageBrowser"],"./filebrowser/TImageBrowser.js":[8326,7,"filebrowser-TImageBrowser"],"./filebrowser/TImageCutArea":[8453,7,"filebrowser-TImageCutArea"],"./filebrowser/TImageCutArea.js":[8453,7,"filebrowser-TImageCutArea"],"./formula_builder/FormulaBuilder":[9326,7,"formula_builder-FormulaBuilder"],"./formula_builder/FormulaBuilder.js":[9326,7,"formula_builder-FormulaBuilder"],"./inside_editor/InsideEditor":[1745,7,"inside_editor-InsideEditor"],"./inside_editor/InsideEditor.js":[1745,7,"inside_editor-InsideEditor"],"./jqgrid/TGridHeader":[754,7,"jqgrid-TGridHeader"],"./jqgrid/TGridHeader.js":[754,7,"jqgrid-TGridHeader"],"./list/TList":[802,7,"list-TList"],"./list/TList.js":[802,7,"list-TList"],"./live-chat/live-chat":[155,9,"live-chat"],"./live-chat/live-chat.js":[155,9,"live-chat"],"./message_box/NoHierarchyBox":[9110,7,"message_box-NoHierarchyBox"],"./message_box/NoHierarchyBox.js":[9110,7,"message_box-NoHierarchyBox"],"./message_box/NoResultBox":[4938,7,"message_box-NoResultBox"],"./message_box/NoResultBox.js":[4938,7,"message_box-NoResultBox"],"./message_box/SaveAndContinueBox":[350,7,"message_box-SaveAndContinueBox"],"./message_box/SaveAndContinueBox.js":[350,7,"message_box-SaveAndContinueBox"],"./paging/Paging2":[5583,7,"paging-Paging2"],"./paging/Paging2.js":[5583,7,"paging-Paging2"],"./search_panel/FormItemType":[2548,9],"./search_panel/FormItemType.js":[2548,9],"./search_panel/SearchPanel":[4057,7,"search_panel-SearchPanel"],"./search_panel/SearchPanel.js":[4057,7,"search_panel-SearchPanel"],"./separated_box/SeparatedBox":[7316,7,"separated_box-SeparatedBox"],"./separated_box/SeparatedBox.js":[7316,7,"separated_box-SeparatedBox"],"./switch_button/SwitchButton":[6618,9,"switch_button-SwitchButton"],"./switch_button/SwitchButton.js":[6618,9,"switch_button-SwitchButton"],"./tag_input/TTagInput":[4466,7,"tag_input-TTagInput"],"./tag_input/TTagInput.js":[4466,7,"tag_input-TTagInput"],"./text/TText":[7011,7,"text-TText"],"./text/TText.js":[7011,7,"text-TText"],"./text_input/TPasswordInput":[3133,7,"text_input-TPasswordInput"],"./text_input/TPasswordInput.js":[3133,7,"text_input-TPasswordInput"],"./text_input/TTextInput":[9264,7,"text_input-TTextInput"],"./text_input/TTextInput.js":[9264,7,"text_input-TTextInput"],"./textarea/TTextArea":[8917,7,"textarea-TTextArea"],"./textarea/TTextArea.js":[8917,7,"textarea-TTextArea"],"./timepicker/TTimePicker":[9680,7,"timepicker-TTimePicker"],"./timepicker/TTimePicker.js":[9680,7,"timepicker-TTimePicker"],"./toggle_button/TToggleButton":[5110,7,"toggle_button-TToggleButton"],"./toggle_button/TToggleButton.js":[5110,7,"toggle_button-TToggleButton"],"./ttgrid/TTGrid":[2185,7,"ttgrid-TTGrid"],"./ttgrid/TTGrid.js":[2185,7,"ttgrid-TTGrid"],"./view_min_tab/ViewMinTabBar":[8287,7],"./view_min_tab/ViewMinTabBar.js":[8287,7],"./wizard/Wizard":[3207,9,"wizard-Wizard"],"./wizard/Wizard.js":[3207,9,"wizard-Wizard"],"./wizard/WizardStep":[8880,9,"wizard-WizardStep"],"./wizard/WizardStep.js":[8880,9,"wizard-WizardStep"]};function e(t){if(!I.o(n,t))return Promise.resolve().then((()=>{var g=new Error("Cannot find module '"+t+"'");throw g.code="MODULE_NOT_FOUND",g}));var g=n[t],e=g[0];return Promise.all(g.slice(2).map(I.e)).then((()=>I.t(e,16|g[1])))}e.keys=()=>Object.keys(n),e.id=9769,t.exports=e},8981:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{"use strict";eval("\n// EXTERNAL MODULE: ./node_modules/stacktrace-js/stacktrace.js\nvar stacktrace = __webpack_require__(401);\n// EXTERNAL MODULE: ./node_modules/backbone/backbone.js\nvar backbone = __webpack_require__(2316);\n// EXTERNAL MODULE: ./node_modules/moment/moment.js\nvar moment = __webpack_require__(381);\n// EXTERNAL MODULE: ./interface/html5/framework/jquery.i18n.js\nvar jquery_i18n = __webpack_require__(6378);\n// EXTERNAL MODULE: ./node_modules/html2canvas/dist/html2canvas.js\nvar html2canvas = __webpack_require__(1120);\nvar html2canvas_default = /*#__PURE__*/__webpack_require__.n(html2canvas);\n// EXTERNAL MODULE: ./node_modules/vue/dist/vue.esm-bundler.js + 6 modules\nvar vue_esm_bundler = __webpack_require__(5166);\n// EXTERNAL MODULE: ./interface/html5/components/main_ui_router.js + 6 modules\nvar main_ui_router = __webpack_require__(2237);\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/TTMainUI.vue?vue&type=template&id=d0d32d98\n\n\nconst _hoisted_1 = { class: \"layout-content\" }\nconst _hoisted_2 = { class: \"layout-content-container\" }\nconst _hoisted_3 = {\n key: 0,\n class: \"layout-mask\"\n}\n\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_Toast = (0,vue_esm_bundler/* resolveComponent */.up)(\"Toast\")\n const _component_TTTopContainer = (0,vue_esm_bundler/* resolveComponent */.up)(\"TTTopContainer\")\n const _component_TTLeftContainer = (0,vue_esm_bundler/* resolveComponent */.up)(\"TTLeftContainer\")\n const _component_router_view = (0,vue_esm_bundler/* resolveComponent */.up)(\"router-view\")\n\n return (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", {\n class: (0,vue_esm_bundler/* normalizeClass */.C_)($options.containerClass),\n onClick: _cache[0] || (_cache[0] = (...args) => ($options.onDocumentClick && $options.onDocumentClick(...args)))\n }, [\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_Toast),\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_TTTopContainer, {\n class: \"hide-in-login\",\n topbarMenuActive: $data.topbarMenuActive,\n activeTopbarItem: $data.activeTopbarItem,\n onMenubuttonClick: $options.onMenuButtonClick,\n onTopbarMenubuttonClick: $options.onTopbarMenuButtonClick,\n onTopbarItemClick: $options.onTopbarItemClick\n }, null, 8 /* PROPS */, [\"topbarMenuActive\", \"activeTopbarItem\", \"onMenubuttonClick\", \"onTopbarMenubuttonClick\", \"onTopbarItemClick\"]),\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_TTLeftContainer, {\n class: \"hide-in-login\",\n isMenuVisible: $options.isMenuVisible(),\n layoutMode: $data.layoutMode,\n onMenuitemClick: $options.onMenuItemClick\n }, null, 8 /* PROPS */, [\"isMenuVisible\", \"layoutMode\", \"onMenuitemClick\"]),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_1, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_2, [\n (0,vue_esm_bundler/* createCommentVNode */.kq)(\" router-view\"),\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_router_view, {\n key: _ctx.$route.fullPath\n }),\n (0,vue_esm_bundler/* createCommentVNode */.kq)(\" The router view is setup with this :key to allow the LegacyView component to be re-used instead of cached, ensuring unique component state for each view. \")\n ]),\n ($data.staticMenuMobileActive)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", _hoisted_3))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true)\n ])\n ], 2 /* CLASS */)), [\n [vue_esm_bundler/* vShow */.F8, $data.showUI]\n ])\n}\n;// CONCATENATED MODULE: ./interface/html5/components/TTMainUI.vue?vue&type=template&id=d0d32d98\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/TTTopContainer.vue?vue&type=template&id=4c2a5485&scoped=true\n\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-4c2a5485\"),n=n(),_popScopeId(),n)\nconst TTTopContainervue_type_template_id_4c2a5485_scoped_true_hoisted_1 = { class: \"tt-top layout-topbar\" }\n\nfunction TTTopContainervue_type_template_id_4c2a5485_scoped_true_render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_TTTopBar = (0,vue_esm_bundler/* resolveComponent */.up)(\"TTTopBar\")\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", TTTopContainervue_type_template_id_4c2a5485_scoped_true_hoisted_1, [\n ($data.ready_to_load_top_bar)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(_component_TTTopBar, {\n key: 0,\n topbarMenuActive: $props.topbarMenuActive,\n activeTopbarItem: $props.activeTopbarItem,\n onMenubuttonClick: $options.onMenuButtonClick,\n onTopbarMenubuttonClick: $options.onTopbarMenuButtonClick,\n onTopbarItemClick: $options.onTopbarItemClick\n }, null, 8 /* PROPS */, [\"topbarMenuActive\", \"activeTopbarItem\", \"onMenubuttonClick\", \"onTopbarMenubuttonClick\", \"onTopbarItemClick\"]))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true)\n ]))\n}\n;// CONCATENATED MODULE: ./interface/html5/components/TTTopContainer.vue?vue&type=template&id=4c2a5485&scoped=true\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/TTTopbar.vue?vue&type=template&id=de74ea6e&scoped=true\n\n\nconst TTTopbarvue_type_template_id_de74ea6e_scoped_true_withScopeId = n => ((0,vue_esm_bundler/* pushScopeId */.dD)(\"data-v-de74ea6e\"),n=n(),(0,vue_esm_bundler/* popScopeId */.Cn)(),n)\nconst TTTopbarvue_type_template_id_de74ea6e_scoped_true_hoisted_1 = { class: \"topbar\" }\nconst TTTopbarvue_type_template_id_de74ea6e_scoped_true_hoisted_2 = { class: \"left-group\" }\nconst TTTopbarvue_type_template_id_de74ea6e_scoped_true_hoisted_3 = /*#__PURE__*/ TTTopbarvue_type_template_id_de74ea6e_scoped_true_withScopeId(() => /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"i\", { class: \"pi pi-bars\" }, null, -1 /* HOISTED */))\nconst _hoisted_4 = [\n TTTopbarvue_type_template_id_de74ea6e_scoped_true_hoisted_3\n]\nconst _hoisted_5 = { class: \"company-logo-container\" }\nconst _hoisted_6 = [\"src\"]\nconst _hoisted_7 = { class: \"slash-line company-name\" }\nconst _hoisted_8 = { class: \"middle-group\" }\nconst _hoisted_9 = {\n key: 0,\n class: \"sandbox-title\"\n}\nconst _hoisted_10 = { class: \"right-group\" }\nconst _hoisted_11 = { class: \"job-queue-list\" }\nconst _hoisted_12 = {\n key: 0,\n class: \"job-queue-item\"\n}\nconst _hoisted_13 = { class: \"job-queue-item\" }\nconst _hoisted_14 = { class: \"job-queue-item-summary\" }\nconst _hoisted_15 = { class: \"job-queue-item-detail\" }\nconst _hoisted_16 = {\n key: 1,\n class: \"topbar-icon topbar-inout\"\n}\nconst _hoisted_17 = { class: \"topbar-icon topbar-notification-bell\" }\nconst _hoisted_18 = { class: \"topbar-icon topbar-help\" }\nconst _hoisted_19 = { class: \"profile-menu-item\" }\nconst _hoisted_20 = {\n key: 0,\n class: \"profile-menu-separator\"\n}\nconst _hoisted_21 = [\"id\", \"onClick\"]\nconst _hoisted_22 = { class: \"topbar-item-name\" }\nconst _hoisted_23 = { key: 0 }\nconst _hoisted_24 = /*#__PURE__*/ TTTopbarvue_type_template_id_de74ea6e_scoped_true_withScopeId(() => /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\", { class: \"slash-line\" }, \" \", -1 /* HOISTED */))\nconst _hoisted_25 = { class: \"username\" }\nconst _hoisted_26 = { class: \"profile-image-holder\" }\nconst _hoisted_27 = [\"src\"]\nconst _hoisted_28 = {\n key: 0,\n class: \"pi pi-angle-down\"\n}\nconst _hoisted_29 = {\n key: 1,\n class: \"pi pi-angle-down\"\n}\nconst _hoisted_30 = { class: \"profile-menu-item\" }\nconst _hoisted_31 = {\n key: 0,\n class: \"profile-menu-separator\"\n}\nconst _hoisted_32 = [\"id\", \"onClick\"]\nconst _hoisted_33 = { class: \"topbar-item-name\" }\nconst _hoisted_34 = { key: 0 }\n\nfunction TTTopbarvue_type_template_id_de74ea6e_scoped_true_render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_router_link = (0,vue_esm_bundler/* resolveComponent */.up)(\"router-link\")\n const _component_ProgressSpinner = (0,vue_esm_bundler/* resolveComponent */.up)(\"ProgressSpinner\")\n const _component_OverlayPanel = (0,vue_esm_bundler/* resolveComponent */.up)(\"OverlayPanel\")\n const _directive_tooltip = (0,vue_esm_bundler/* resolveDirective */.Q2)(\"tooltip\")\n const _directive_badge = (0,vue_esm_bundler/* resolveDirective */.Q2)(\"badge\")\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", TTTopbarvue_type_template_id_de74ea6e_scoped_true_hoisted_1, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", TTTopbarvue_type_template_id_de74ea6e_scoped_true_hoisted_2, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"button\", {\n class: \"p-link menu-button\",\n onClick: _cache[0] || (_cache[0] = (...args) => ($options.onMenuButtonClick && $options.onMenuButtonClick(...args)))\n }, _hoisted_4),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_5, [\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_router_link, {\n to: \"/\",\n class: \"logo-link\"\n }, {\n default: (0,vue_esm_bundler/* withCtx */.w5)(() => [\n (0,vue_esm_bundler/* createElementVNode */._)(\"img\", {\n class: \"logo\",\n id: \"topbar-company-logo\",\n src: $data.company_logo,\n alt: \"company logo\",\n onClick: _cache[1] || (_cache[1] = (...args) => ($options.onCompanyLogoClicked && $options.onCompanyLogoClicked(...args)))\n }, null, 8 /* PROPS */, _hoisted_6)\n ]),\n _: 1 /* STABLE */\n })\n ]),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_7, (0,vue_esm_bundler/* toDisplayString */.zw)($data.company_name), 1 /* TEXT */)\n ]),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_8, [\n ($options.isSandboxMode())\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", _hoisted_9, (0,vue_esm_bundler/* toDisplayString */.zw)($data.sandbox_mode_text), 1 /* TEXT */))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true)\n ]),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_10, [\n ($data.progress_bar_visible)\n ? (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(_component_ProgressSpinner, {\n key: 0,\n class: \"job-queue-spinner\",\n style: {\"width\":\"30px\",\"height\":\"30px\"},\n strokeWidth: \"5\",\n animationDuration: \"2s\",\n onClick: $options.toggleJobQueuePanel\n }, null, 8 /* PROPS */, [\"onClick\"])), [\n [\n _directive_tooltip,\n $data.tooltips.job_queue,\n void 0,\n { bottom: true }\n ]\n ])\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_OverlayPanel, {\n ref: \"job-queue-panel\",\n onShow: $options.getRunningJobsData,\n onHide: $options.onHideJobQueuePanel\n }, {\n default: (0,vue_esm_bundler/* withCtx */.w5)(() => [\n (0,vue_esm_bundler/* createElementVNode */._)(\"ul\", _hoisted_11, [\n ($data.pending_job_queue_tasks.length === 0)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", _hoisted_12, (0,vue_esm_bundler/* toDisplayString */.zw)($data.job_queue_complete_text), 1 /* TEXT */))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createElementBlock */.iD)(vue_esm_bundler/* Fragment */.HY, null, (0,vue_esm_bundler/* renderList */.Ko)($data.pending_job_queue_tasks, (item) => {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", _hoisted_13, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_14, (0,vue_esm_bundler/* toDisplayString */.zw)(item.name), 1 /* TEXT */),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_15, \"Started \" + (0,vue_esm_bundler/* toDisplayString */.zw)(item.elapsed_time) + \" ago\", 1 /* TEXT */)\n ]))\n }), 256 /* UNKEYED_FRAGMENT */))\n ])\n ]),\n _: 1 /* STABLE */\n }, 8 /* PROPS */, [\"onShow\", \"onHide\"]),\n ($data.show_punch_in_out)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"span\", _hoisted_16, [\n (0,vue_esm_bundler/* withDirectives */.wy)((0,vue_esm_bundler/* createElementVNode */._)(\"i\", {\n class: \"tticon tticon-timer_black_24dp p-mr-4 p-text-secondary\",\n id: \"profile-in-out\",\n onClick: _cache[2] || (_cache[2] = (...args) => ($options.onInOutClick && $options.onInOutClick(...args)))\n }, null, 512 /* NEED_PATCH */), [\n [\n _directive_tooltip,\n $data.tooltips.in_out,\n void 0,\n { bottom: true }\n ]\n ])\n ]))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n (0,vue_esm_bundler/* createElementVNode */._)(\"span\", _hoisted_17, [\n ($data.notification_count === 0)\n ? (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"i\", {\n key: 0,\n class: \"tticon tticon-notifications_black_24dp p-mr-4 p-text-secondary\",\n id: \"profile-notifications\",\n onClick: _cache[3] || (_cache[3] = (...args) => ($options.onNotificationBellClick && $options.onNotificationBellClick(...args)))\n }, null, 512 /* NEED_PATCH */)), [\n [\n _directive_tooltip,\n $data.tooltips.notifications,\n void 0,\n { bottom: true }\n ]\n ])\n : (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"i\", {\n key: 1,\n class: \"tticon tticon-notifications_black_24dp p-mr-4 p-text-secondary\",\n id: \"profile-notifications\",\n onClick: _cache[4] || (_cache[4] = (...args) => ($options.onNotificationBellClick && $options.onNotificationBellClick(...args)))\n }, null, 512 /* NEED_PATCH */)), [\n [\n _directive_tooltip,\n $data.tooltips.notifications,\n void 0,\n { bottom: true }\n ],\n [\n _directive_badge,\n $data.notification_count,\n void 0,\n { info: true }\n ]\n ])\n ]),\n (0,vue_esm_bundler/* withDirectives */.wy)((0,vue_esm_bundler/* createElementVNode */._)(\"span\", _hoisted_18, [\n (0,vue_esm_bundler/* withDirectives */.wy)((0,vue_esm_bundler/* createElementVNode */._)(\"i\", {\n class: \"tticon tticon-help_center_black_24dp p-mr-4 p-text-secondary\",\n id: \"profile-help\",\n onClick: _cache[5] || (_cache[5] = (...args) => ($options.onTopbarMenuButtonClickHelp && $options.onTopbarMenuButtonClickHelp(...args)))\n }, null, 512 /* NEED_PATCH */), [\n [\n _directive_tooltip,\n $data.tooltips.help,\n void 0,\n { bottom: true }\n ]\n ])\n ], 512 /* NEED_PATCH */), [\n [vue_esm_bundler/* vShow */.F8, $data.help_menu_items.length > 0]\n ]),\n (0,vue_esm_bundler/* createElementVNode */._)(\"ul\", {\n class: (0,vue_esm_bundler/* normalizeClass */.C_)($options.topbarItemsClassHelp),\n role: \"menu\",\n id: \"profile-help-items\"\n }, [\n ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createElementBlock */.iD)(vue_esm_bundler/* Fragment */.HY, null, (0,vue_esm_bundler/* renderList */.Ko)($data.help_menu_items, (item) => {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"li\", _hoisted_19, [\n (item.separator === true)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", _hoisted_20))\n : ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"button\", {\n key: 1,\n class: \"p-link\",\n id: $options.createMenuId(item.id),\n onClick: $event => ($options.handleMenuClick(item))\n }, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"i\", {\n class: (0,vue_esm_bundler/* normalizeClass */.C_)([\"topbar-icon\", item.icon])\n }, null, 2 /* CLASS */),\n (0,vue_esm_bundler/* createElementVNode */._)(\"span\", _hoisted_22, (0,vue_esm_bundler/* toDisplayString */.zw)(item.label), 1 /* TEXT */),\n (item.badge_number)\n ? (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"span\", _hoisted_23, null, 512 /* NEED_PATCH */)), [\n [\n _directive_badge,\n item.badge_number,\n void 0,\n { info: true }\n ]\n ])\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true)\n ], 8 /* PROPS */, _hoisted_21))\n ]))\n }), 256 /* UNKEYED_FRAGMENT */))\n ], 2 /* CLASS */),\n _hoisted_24,\n (0,vue_esm_bundler/* createCommentVNode */.kq)(\"None breaking space required to show slash\"),\n (0,vue_esm_bundler/* withDirectives */.wy)((0,vue_esm_bundler/* createElementVNode */._)(\"button\", {\n class: \"p-link profile\",\n id: \"profile-button\",\n onClick: _cache[6] || (_cache[6] = (...args) => ($options.onTopbarMenuButtonClickProfile && $options.onTopbarMenuButtonClickProfile(...args)))\n }, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"span\", _hoisted_25, (0,vue_esm_bundler/* toDisplayString */.zw)($data.current_user.first_name) + \" \" + (0,vue_esm_bundler/* toDisplayString */.zw)($data.current_user.last_name), 1 /* TEXT */),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_26, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"img\", {\n class: \"profile-image\",\n src: $options.user_profile_image_url,\n alt: \"apollo-layout\"\n }, null, 8 /* PROPS */, _hoisted_27)\n ]),\n ($options.totalPendingCount === 0)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"i\", _hoisted_28))\n : (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"i\", _hoisted_29, null, 512 /* NEED_PATCH */)), [\n [\n _directive_badge,\n $options.totalPendingCount,\n void 0,\n { info: true }\n ]\n ])\n ], 512 /* NEED_PATCH */), [\n [\n _directive_tooltip,\n $data.tooltips.profile,\n void 0,\n { bottom: true }\n ]\n ]),\n (0,vue_esm_bundler/* createElementVNode */._)(\"ul\", {\n class: (0,vue_esm_bundler/* normalizeClass */.C_)($options.topbarItemsClassProfile),\n role: \"menu\",\n id: \"profile-menu-items\"\n }, [\n ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createElementBlock */.iD)(vue_esm_bundler/* Fragment */.HY, null, (0,vue_esm_bundler/* renderList */.Ko)($data.profile_menu_items, (item) => {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"li\", _hoisted_30, [\n (item.separator === true)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", _hoisted_31))\n : ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"button\", {\n key: 1,\n class: \"p-link\",\n id: $options.createMenuId(item.id),\n onClick: $event => ($options.handleMenuClick(item))\n }, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"i\", {\n class: (0,vue_esm_bundler/* normalizeClass */.C_)([\"topbar-icon\", item.icon])\n }, null, 2 /* CLASS */),\n (0,vue_esm_bundler/* createElementVNode */._)(\"span\", _hoisted_33, (0,vue_esm_bundler/* toDisplayString */.zw)(item.label), 1 /* TEXT */),\n (item.badge_number)\n ? (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"span\", _hoisted_34, null, 512 /* NEED_PATCH */)), [\n [\n _directive_badge,\n item.badge_number,\n void 0,\n { info: true }\n ]\n ])\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true)\n ], 8 /* PROPS */, _hoisted_32))\n ]))\n }), 256 /* UNKEYED_FRAGMENT */))\n ], 2 /* CLASS */)\n ])\n ]))\n}\n;// CONCATENATED MODULE: ./interface/html5/components/TTTopbar.vue?vue&type=template&id=de74ea6e&scoped=true\n\n// EXTERNAL MODULE: ./node_modules/primevue/inputtext/inputtext.esm.js\nvar inputtext_esm = __webpack_require__(6076);\n// EXTERNAL MODULE: ./interface/html5/global/Global.js\nvar global_Global = __webpack_require__(9490);\n// EXTERNAL MODULE: ./node_modules/primevue/progressspinner/progressspinner.esm.js\nvar progressspinner_esm = __webpack_require__(1895);\n// EXTERNAL MODULE: ./node_modules/primevue/utils/utils.esm.js\nvar utils_esm = __webpack_require__(6954);\n// EXTERNAL MODULE: ./node_modules/primevue/overlayeventbus/overlayeventbus.esm.js\nvar overlayeventbus_esm = __webpack_require__(590);\n// EXTERNAL MODULE: ./node_modules/primevue/ripple/ripple.esm.js\nvar ripple_esm = __webpack_require__(4019);\n;// CONCATENATED MODULE: ./node_modules/primevue/overlaypanel/overlaypanel.esm.js\n\n\n\n\n\nvar script = {\n name: 'OverlayPanel',\n inheritAttrs: false,\n props: {\n\t\tdismissable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true\n\t\t},\n\t\tshowCloseIcon: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false\n\t\t},\n appendTo: {\n\t\t\ttype: String,\n\t\t\tdefault: 'body'\n\t\t},\n baseZIndex: {\n type: Number,\n default: 0\n },\n autoZIndex: {\n type: Boolean,\n default: true\n },\n ariaCloseLabel: {\n type: String,\n default: 'close'\n },\n breakpoints: {\n type: Object,\n default: null\n }\n },\n emits: ['show', 'hide'],\n data() {\n return {\n visible: false\n }\n },\n selfClick: false,\n target: null,\n eventTarget: null,\n outsideClickListener: null,\n scrollHandler: null,\n resizeListener: null,\n container: null,\n styleElement: null,\n overlayEventListener: null,\n beforeUnmount() {\n if (this.dismissable) {\n this.unbindOutsideClickListener();\n }\n\n if (this.scrollHandler) {\n this.scrollHandler.destroy();\n this.scrollHandler = null;\n }\n this.destroyStyle();\n this.unbindResizeListener();\n this.target = null;\n\n if (this.container && this.autoZIndex) {\n utils_esm/* ZIndexUtils.clear */.P9.clear(this.container);\n }\n\n if (this.overlayEventListener) {\n overlayeventbus_esm/* default.off */.Z.off('overlay-click', this.overlayEventListener);\n this.overlayEventListener = null;\n }\n\n this.container = null;\n },\n mounted() {\n if (this.breakpoints) {\n this.createStyle();\n }\n },\n methods: {\n toggle(event, target) {\n if (this.visible)\n this.hide();\n else\n this.show(event, target);\n },\n show(event, target) {\n this.visible = true;\n this.eventTarget = event.currentTarget;\n this.target = target || event.currentTarget;\n },\n hide() {\n this.visible = false;\n },\n onContentClick() {\n this.selfClick = true;\n },\n onEnter(el) {\n this.container.setAttribute(this.attributeSelector, '');\n this.alignOverlay();\n if (this.dismissable) {\n this.bindOutsideClickListener();\n }\n\n this.bindScrollListener();\n this.bindResizeListener();\n\n if (this.autoZIndex) {\n utils_esm/* ZIndexUtils.set */.P9.set('overlay', el, this.baseZIndex + this.$primevue.config.zIndex.overlay);\n }\n\n this.overlayEventListener = (e) => {\n if (this.container.contains(e.target)) {\n this.selfClick = true;\n }\n };\n\n overlayeventbus_esm/* default.on */.Z.on('overlay-click', this.overlayEventListener);\n this.$emit('show');\n },\n onLeave() {\n this.unbindOutsideClickListener();\n this.unbindScrollListener();\n this.unbindResizeListener();\n overlayeventbus_esm/* default.off */.Z.off('overlay-click', this.overlayEventListener);\n this.overlayEventListener = null;\n this.$emit('hide');\n },\n onAfterLeave(el) {\n if (this.autoZIndex) {\n utils_esm/* ZIndexUtils.clear */.P9.clear(el);\n }\n },\n alignOverlay() {\n utils_esm/* DomHandler.absolutePosition */.p7.absolutePosition(this.container, this.target);\n\n const containerOffset = utils_esm/* DomHandler.getOffset */.p7.getOffset(this.container);\n const targetOffset = utils_esm/* DomHandler.getOffset */.p7.getOffset(this.target);\n let arrowLeft = 0;\n\n if (containerOffset.left < targetOffset.left) {\n arrowLeft = targetOffset.left - containerOffset.left;\n }\n this.container.style.setProperty('--overlayArrowLeft', `${arrowLeft}px`);\n\n if (containerOffset.top < targetOffset.top) {\n utils_esm/* DomHandler.addClass */.p7.addClass(this.container, 'p-overlaypanel-flipped');\n }\n },\n bindOutsideClickListener() {\n if (!this.outsideClickListener) {\n this.outsideClickListener = (event) => {\n if (this.visible && !this.selfClick && !this.isTargetClicked(event)) {\n this.visible = false;\n }\n this.selfClick = false;\n };\n document.addEventListener('click', this.outsideClickListener);\n }\n },\n unbindOutsideClickListener() {\n if (this.outsideClickListener) {\n document.removeEventListener('click', this.outsideClickListener);\n this.outsideClickListener = null;\n this.selfClick = false;\n }\n },\n bindScrollListener() {\n if (!this.scrollHandler) {\n this.scrollHandler = new utils_esm/* ConnectedOverlayScrollHandler */.Vr(this.target, () => {\n if (this.visible) {\n this.visible = false;\n }\n });\n }\n\n this.scrollHandler.bindScrollListener();\n },\n unbindScrollListener() {\n if (this.scrollHandler) {\n this.scrollHandler.unbindScrollListener();\n }\n },\n bindResizeListener() {\n if (!this.resizeListener) {\n this.resizeListener = () => {\n if (this.visible && !utils_esm/* DomHandler.isAndroid */.p7.isAndroid()) {\n this.visible = false;\n }\n };\n window.addEventListener('resize', this.resizeListener);\n }\n },\n unbindResizeListener() {\n if (this.resizeListener) {\n window.removeEventListener('resize', this.resizeListener);\n this.resizeListener = null;\n }\n },\n isTargetClicked(event) {\n return (this.eventTarget && (this.eventTarget === event.target || this.eventTarget.contains(event.target)));\n },\n containerRef(el) {\n this.container = el;\n },\n createStyle() {\n\t\t\tif (!this.styleElement) {\n\t\t\t\tthis.styleElement = document.createElement('style');\n\t\t\t\tthis.styleElement.type = 'text/css';\n\t\t\t\tdocument.head.appendChild(this.styleElement);\n\n let innerHTML = '';\n for (let breakpoint in this.breakpoints) {\n innerHTML += `\n @media screen and (max-width: ${breakpoint}) {\n .p-overlaypanel[${this.attributeSelector}] {\n width: ${this.breakpoints[breakpoint]} !important;\n }\n }\n `;\n }\n\n this.styleElement.innerHTML = innerHTML;\n\t\t\t}\n\t\t},\n destroyStyle() {\n if (this.styleElement) {\n document.head.removeChild(this.styleElement);\n this.styleElement = null;\n }\n },\n onOverlayClick(event) {\n overlayeventbus_esm/* default.emit */.Z.emit('overlay-click', {\n originalEvent: event,\n target: this.target\n });\n }\n },\n computed: {\n containerClass() {\n return ['p-overlaypanel p-component', {\n 'p-input-filled': this.$primevue.config.inputStyle === 'filled',\n 'p-ripple-disabled': this.$primevue.config.ripple === false\n }];\n },\n attributeSelector() {\n return (0,utils_esm/* UniqueComponentId */.Th)();\n }\n },\n directives: {\n 'ripple': ripple_esm/* default */.Z\n }\n};\n\nconst overlaypanel_esm_hoisted_1 = /*#__PURE__*/(0,vue_esm_bundler/* createVNode */.Wm)(\"span\", { class: \"p-overlaypanel-close-icon pi pi-times\" }, null, -1);\n\nfunction overlaypanel_esm_render(_ctx, _cache, $props, $setup, $data, $options) {\n const _directive_ripple = (0,vue_esm_bundler/* resolveDirective */.Q2)(\"ripple\");\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Teleport */.lR, { to: $props.appendTo }, [\n (0,vue_esm_bundler/* createVNode */.Wm)(vue_esm_bundler/* Transition */.uT, {\n name: \"p-overlaypanel\",\n onEnter: $options.onEnter,\n onLeave: $options.onLeave,\n onAfterLeave: $options.onAfterLeave\n }, {\n default: (0,vue_esm_bundler/* withCtx */.w5)(() => [\n ($data.visible)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"div\", (0,vue_esm_bundler/* mergeProps */.dG)({\n key: 0,\n class: $options.containerClass,\n ref: $options.containerRef\n }, _ctx.$attrs, {\n onClick: _cache[4] || (_cache[4] = (...args) => ($options.onOverlayClick && $options.onOverlayClick(...args)))\n }), [\n (0,vue_esm_bundler/* createVNode */.Wm)(\"div\", {\n class: \"p-overlaypanel-content\",\n onClick: _cache[1] || (_cache[1] = (...args) => ($options.onContentClick && $options.onContentClick(...args))),\n onMousedown: _cache[2] || (_cache[2] = (...args) => ($options.onContentClick && $options.onContentClick(...args)))\n }, [\n (0,vue_esm_bundler/* renderSlot */.WI)(_ctx.$slots, \"default\")\n ], 32),\n ($props.showCloseIcon)\n ? (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"button\", {\n key: 0,\n class: \"p-overlaypanel-close p-link\",\n onClick: _cache[3] || (_cache[3] = (...args) => ($options.hide && $options.hide(...args))),\n \"aria-label\": $props.ariaCloseLabel,\n type: \"button\"\n }, [\n overlaypanel_esm_hoisted_1\n ], 8, [\"aria-label\"])), [\n [_directive_ripple]\n ])\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true)\n ], 16))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true)\n ]),\n _: 3\n }, 8, [\"onEnter\", \"onLeave\", \"onAfterLeave\"])\n ], 8, [\"to\"]))\n}\n\nfunction styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar css_248z = \"\\n.p-overlaypanel {\\n position: absolute;\\n margin-top: 10px;\\n top: 0;\\n left: 0;\\n}\\n.p-overlaypanel-flipped {\\n margin-top: 0;\\n margin-bottom: 10px;\\n}\\n.p-overlaypanel-close {\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n -webkit-box-pack: center;\\n -ms-flex-pack: center;\\n justify-content: center;\\n -webkit-box-align: center;\\n -ms-flex-align: center;\\n align-items: center;\\n overflow: hidden;\\n position: relative;\\n}\\n\\n/* Animation */\\n.p-overlaypanel-enter-from {\\n opacity: 0;\\n -webkit-transform: scaleY(0.8);\\n transform: scaleY(0.8);\\n}\\n.p-overlaypanel-leave-to {\\n opacity: 0;\\n}\\n.p-overlaypanel-enter-active {\\n -webkit-transition: opacity .12s cubic-bezier(0, 0, 0.2, 1), -webkit-transform .12s cubic-bezier(0, 0, 0.2, 1);\\n transition: opacity .12s cubic-bezier(0, 0, 0.2, 1), -webkit-transform .12s cubic-bezier(0, 0, 0.2, 1);\\n transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1);\\n transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1), -webkit-transform .12s cubic-bezier(0, 0, 0.2, 1);\\n}\\n.p-overlaypanel-leave-active {\\n -webkit-transition: opacity .1s linear;\\n transition: opacity .1s linear;\\n}\\n.p-overlaypanel:after, .p-overlaypanel:before {\\n\\tbottom: 100%;\\n\\tleft: calc(var(--overlayArrowLeft, 0) + 1.25rem);\\n\\tcontent: \\\" \\\";\\n\\theight: 0;\\n\\twidth: 0;\\n\\tposition: absolute;\\n\\tpointer-events: none;\\n}\\n.p-overlaypanel:after {\\n\\tborder-width: 8px;\\n\\tmargin-left: -8px;\\n}\\n.p-overlaypanel:before {\\n\\tborder-width: 10px;\\n\\tmargin-left: -10px;\\n}\\n.p-overlaypanel-flipped:after, .p-overlaypanel-flipped:before {\\n bottom: auto;\\n top: 100%;\\n}\\n.p-overlaypanel.p-overlaypanel-flipped:after {\\n border-bottom-color: transparent;\\n}\\n.p-overlaypanel.p-overlaypanel-flipped:before {\\n border-bottom-color: transparent\\n}\\n\";\nstyleInject(css_248z);\n\nscript.render = overlaypanel_esm_render;\n\n/* harmony default export */ const overlaypanel_esm = (script);\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/TTTopbar.vue?vue&type=script&lang=js\n/* provided dependency */ var $ = __webpack_require__(9755);\n\n\n\n\n\n\n/* harmony default export */ const TTTopbarvue_type_script_lang_js = ({\n created() {\n this.event_bus = new TTEventBus( {\n component_id: this.component_id,\n } );\n this.event_bus.on( this.component_id, 'notification_bell', ( event_data ) => {\n this.updateNotificationCount( event_data.notification_count );\n } );\n this.event_bus.on( this.component_id, 'refresh_login_data', this.refreshCompanyAndUserInfo );\n this.event_bus.on( this.component_id, 'profile_menu_data', ( event_data ) => {\n // Get the account menu data from the main menu (MenuManager)\n this.refreshProfileMenuData( event_data.profile_menu_data );\n } );\n this.event_bus.on( this.component_id, 'help_menu_data', ( event_data ) => {\n // Get the help menu data from the main menu (MenuManager)\n this.refreshHelpMenuData( event_data.help_menu_data );\n } );\n this.event_bus.on( this.component_id, 'profile_pending_counts', ( event_data ) => {\n // Get the number of pending authorizations, notifications and messages for the current user.\n this.updateProfilePendingTotals( event_data.object_types );\n } );\n this.event_bus.on( 'global', 'reset_vue_data', this.resetData );\n this.event_bus.on( this.component_id, 'toggle_job_queue_spinner', ( event_data ) => {\n if ( event_data.get_job_data ) {\n this.getRunningJobsData();\n }\n if ( event_data.show ) {\n this.showJobQueueSpinner();\n }\n if ( event_data.check_completed ) {\n this.checkForJobQueuePendingTasks();\n }\n } );\n TTPromise.resolve( 'VueMenu', 'waitOnTopBarCreated' ); //Final promise before main menu is built, as this component needs to be created first.\n this.refreshCompanyAndUserInfo();\n },\n beforeUnmount() {\n this.hideJobQueueSpinner( false );\n },\n props: {\n topbarMenuActive: Boolean,\n activeTopbarItem: String\n },\n data() {\n return {\n component_id: 'tt_topbar',\n company_name: '',\n company_logo: '',\n current_user: {},\n notification_count: 0,\n profile_menu_items: [],\n help_menu_items: [],\n pending_job_queue_tasks: [],\n progress_bar_visible: false,\n show_punch_in_out: true,\n active_dropdown_menu: '', //Instead of using activeTopbarItem prop, only need to set active_dropdown_menu in this component.\n tooltips: {\n in_out: $.i18n._( 'In/Out' ),\n notifications: $.i18n._( 'Notifications' ),\n help: $.i18n._( 'Help' ),\n profile: $.i18n._( 'Employee Profile' ),\n job_queue: $.i18n._( 'Running Tasks' ),\n },\n sandbox_mode_text: $.i18n._( 'Sandbox Mode' ),\n job_queue_complete_text: $.i18n._( 'All Tasks Completed' )\n };\n },\n interval: null,\n computed: {\n topbarItemsClassProfile() {\n return ['topbar-menu fadeInDown', {\n 'topbar-menu-visible': this.topbarMenuActive && this.active_dropdown_menu === 'profile',\n }];\n },\n topbarItemsClassHelp() {\n return ['topbar-menu fadeInDown', {\n 'topbar-menu-visible': this.topbarMenuActive && this.active_dropdown_menu === 'help',\n }];\n },\n user_profile_image_url() {\n return ServiceCaller.getURLByObjectType( 'user_photo' ) + '&object_id=' + this.current_user.id;\n },\n totalPendingCount() {\n return this.profile_menu_items.filter( ( item ) => item.badge_number > 0 ).reduce( ( total, item ) => total + item.badge_number, 0 );\n }\n /*notificationsCount() {\n Notifications currently are not shown on profile dropdown but we may wish to show it there in the future;\n let notification_item = this.profile_menu_items.find( ( item ) => item.id === 'notification' );\n return notification_item && notification_item.badge_number ? notification_item.badge_number : 0;\n },*/\n },\n methods: {\n resetData() {\n this.hideJobQueueSpinner( false ); //Make sure job queue spinner is hidden and cancelled (especially during logout).\n Object.assign( this.$data, this.$options.data() );\n },\n handleMenuClick( item ) {\n item.command();\n },\n refreshProfileMenuData( data ) {\n this.profile_menu_items.length = 0;\n this.profile_menu_items.push( ...data );\n },\n refreshHelpMenuData( data ) {\n this.help_menu_items.length = 0;\n this.help_menu_items.push( ...data );\n },\n updateProfilePendingTotals( object_types ) {\n TTAPI.APIUser.getUserPendingTotals( object_types, {\n onResult: ( result ) => {\n let pending_counts = result.getResult();\n\n //Assign totals to the corresponding profile menu item badge number.\n this.profile_menu_items.forEach( item => {\n if ( pending_counts[item.id] || pending_counts[item.id] === 0 ) {\n if ( global_Global/* Global.UNIT_TEST_MODE */.x.UNIT_TEST_MODE == true ) {\n pending_counts[item.id] = 999;\n }\n item.badge_number = pending_counts[item.id];\n }\n } );\n\n if ( pending_counts['notification'] ) {\n if ( global_Global/* Global.UNIT_TEST_MODE */.x.UNIT_TEST_MODE == true ) {\n pending_counts['notification'] = 999;\n }\n this.notification_count = pending_counts['notification'];\n }\n }\n } );\n },\n onMenuButtonClick( event ) {\n this.$emit( 'menubutton-click', event );\n },\n onTopbarMenuButtonClickProfile( event ) {\n this.active_dropdown_menu = 'profile';\n if ( this.profile_menu_items.length === 0 ) {\n //This should never happen. It previously would happen consistently on FireFox and rarely Chrome/Other Browsers due to race conditions.\n Debug.Error( 'Error: Profile Menu Items are empty. Rebuilding the menu.', 'ContextMenuManager.js', 'ContextMenuManager', 'getMenuModelByMenuId', 1 );\n this.event_bus.emit( 'tt_left_container', 'rebuild_menu' );\n }\n this.$emit( 'topbar-menubutton-click', event );\n },\n onTopbarMenuButtonClickHelp( event ) {\n this.active_dropdown_menu = 'help';\n this.$emit( 'topbar-menubutton-click', event );\n },\n onCompanyLogoClicked() {\n global_Global/* Global.closeEditViews */.x.closeEditViews( function() {\n MenuManager.goToView( 'Home' );\n } );\n },\n onNotificationBellClick() {\n global_Global/* Global.closeEditViews */.x.closeEditViews( function() {\n MenuManager.goToView( 'Notification' );\n } );\n },\n onInOutClick() {\n if ( LocalCacheData.getLastPunchTime() === null || ( ( new Date().getTime() - LocalCacheData.getLastPunchTime() ) / 1000 ) > 60 ) {\n global_Global/* Global.closeEditViews */.x.closeEditViews( function() {\n MenuManager.openSelectView( 'InOut' );\n } );\n } else {\n let seconds_remaining = ( 60 - ( new Date().getTime() - LocalCacheData.getLastPunchTime() ) / 1000 );\n TAlertManager.showAlert( $.i18n._( 'Please wait at least ' ) + Math.round( seconds_remaining ) + $.i18n._( ' seconds to punch again.' ) );\n }\n },\n updateNotificationCount( count ) {\n if ( global_Global/* Global.UNIT_TEST_MODE */.x.UNIT_TEST_MODE == true ) {\n count = 999;\n }\n this.notification_count = count;\n },\n refreshCompanyAndUserInfo( force ) {\n if ( !this.company_name || force ) {\n if ( !this.current_user.id || ( this.current_user.id && LocalCacheData.getLoginUser().id !== this.current_user.id ) ) {\n //This condition triggers when a new user logs in or page is refreshed.\n\n //Setup notifications and ping check for the new user.\n IndexViewController.initializeNotifications( 'login' );\n global_Global/* Global.setupPing */.x.setupPing();\n\n //This ensures the main menu updates and shows the correct menu items for the current users permissions.\n //Otherwise the user may see menu items from the last logged in user.\n this.event_bus.emit( 'tt_left_container', 'rebuild_menu' );\n this.updateProfilePendingTotals( [] );\n }\n this.company_name = LocalCacheData.getCurrentCompany().name;\n this.current_user = LocalCacheData.getLoginUser();\n this.company_logo = ServiceCaller.getURLByObjectType( 'company_logo' );\n this.show_punch_in_out = PermissionManager.validate( 'punch', 'punch_in_out' );\n this.event_bus.emit( 'tt_main_ui', 'get_user_saved_layout_mode' );\n }\n },\n isSandboxMode() {\n return APIGlobal.pre_login_data['sandbox'];\n },\n toggleJobQueuePanel( event ) {\n this.$refs['job-queue-panel'].toggle( event );\n },\n showJobQueueSpinner() {\n this.progress_bar_visible = true;\n this.startIntervalJobQueueTimer();\n },\n hideJobQueueSpinner( update_timesheet ) {\n this.progress_bar_visible = false;\n this.pending_job_queue_tasks = [];\n clearInterval( this.interval );\n this.interval = null;\n this.$refs['job-queue-panel'].hide();\n\n LocalCacheData.setJobQueuePunchData( null );\n\n if ( update_timesheet && LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.viewId === 'TimeSheet' ) {\n LocalCacheData.current_open_primary_controller.search();\n }\n },\n getRunningJobsData() {\n let data = {};\n data.filter_data = { user_id: this.current_user.id, status_id: [10, 20] };\n TTAPI.APISystemJobQueue.getSystemJobQueue( data, {\n onResult: ( result ) => {\n if ( result.isValid() ) {\n let result_data = result.getResult();\n if ( Array.isArray( result_data ) ) {\n this.pending_job_queue_tasks = result_data;\n } else {\n this.pending_job_queue_tasks = [];\n }\n }\n }\n } );\n },\n startIntervalJobQueueTimer() {\n clearInterval( this.interval );\n this.interval = setInterval( () => {\n this.checkForJobQueuePendingTasks();\n }, 60000 );\n },\n checkForJobQueuePendingTasks() {\n TTAPI.APISystemJobQueue.getPendingAndRunningSystemJobQueue( {\n onResult: ( result ) => {\n let pending_counts = result.getResult();\n if ( pending_counts == 0 ) {\n this.hideJobQueueSpinner( true );\n }\n }\n } );\n },\n onHideJobQueuePanel() {\n if ( this.pending_job_queue_tasks.length === 0 ) {\n this.hideJobQueueSpinner( true );\n }\n },\n createMenuId( menu_id ) {\n return 'profile-menu-' + menu_id;\n },\n },\n components: {\n InputText: inputtext_esm[\"default\"], // Added by RT\n ProgressSpinner: progressspinner_esm/* default */.Z,\n OverlayPanel: overlaypanel_esm\n }\n});\n\n;// CONCATENATED MODULE: ./interface/html5/components/TTTopbar.vue?vue&type=script&lang=js\n \n// EXTERNAL MODULE: ./node_modules/vue-loader/dist/exportHelper.js\nvar exportHelper = __webpack_require__(3744);\n;// CONCATENATED MODULE: ./interface/html5/components/TTTopbar.vue\n\n\n\n\n;\n\n\nconst __exports__ = /*#__PURE__*/(0,exportHelper/* default */.Z)(TTTopbarvue_type_script_lang_js, [['render',TTTopbarvue_type_template_id_de74ea6e_scoped_true_render],['__scopeId',\"data-v-de74ea6e\"]])\n\n/* harmony default export */ const TTTopbar = (__exports__);\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/TTTopContainer.vue?vue&type=script&lang=js\n\n\n\n/* harmony default export */ const TTTopContainervue_type_script_lang_js = ({\n created() {\n this.event_bus = new TTEventBus( {\n component_id: this.component_id,\n } );\n this.event_bus.on( this.component_id, 'ready_to_load_top_bar', ( event_data ) => {\n this.ready_to_load_top_bar = true;\n });\n },\n data() {\n return {\n component_id: 'tt_top_container',\n ready_to_load_top_bar: false,\n }\n },\n props: {\n topbarMenuActive: Boolean,\n activeTopbarItem: String\n },\n methods: {\n onMenuButtonClick(event) {\n this.$emit('menubutton-click', event);\n },\n onTopbarMenuButtonClick(event){\n this.$emit('topbar-menubutton-click', event);\n },\n onTopbarItemClick(event){\n this.$emit('topbar-item-click', event);\n }\n },\n components: {\n TTTopBar: TTTopbar,\n }\n});\n\n;// CONCATENATED MODULE: ./interface/html5/components/TTTopContainer.vue?vue&type=script&lang=js\n \n;// CONCATENATED MODULE: ./interface/html5/components/TTTopContainer.vue\n\n\n\n\n;\n\n\nconst TTTopContainer_exports_ = /*#__PURE__*/(0,exportHelper/* default */.Z)(TTTopContainervue_type_script_lang_js, [['render',TTTopContainervue_type_template_id_4c2a5485_scoped_true_render],['__scopeId',\"data-v-4c2a5485\"]])\n\n/* harmony default export */ const TTTopContainer = (TTTopContainer_exports_);\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/TTLeftContainer.vue?vue&type=template&id=387d95cf\n\n\nconst TTLeftContainervue_type_template_id_387d95cf_hoisted_1 = { class: \"layout-menu-footer\" }\nconst TTLeftContainervue_type_template_id_387d95cf_hoisted_2 = { class: \"layout-menu-footer-content\" }\nconst TTLeftContainervue_type_template_id_387d95cf_hoisted_3 = /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"a\", {\n id: \"copy_right_logo_link\",\n class: \"copy-right-logo-link\",\n target: \"_blank\"\n}, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"img\", {\n id: \"copy_right_logo\",\n class: \"copy-right-logo\"\n })\n], -1 /* HOISTED */)\nconst TTLeftContainervue_type_template_id_387d95cf_hoisted_4 = { class: \"signal-copyright-container\" }\nconst TTLeftContainervue_type_template_id_387d95cf_hoisted_5 = /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\", null, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"ul\", { class: \"signal-strength\" }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"li\", { class: \"signal-strength-very-weak\" }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\")\n ]),\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"li\", { class: \"signal-strength-weak\" }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\")\n ]),\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"li\", { class: \"signal-strength-strong\" }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\")\n ]),\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"li\", { class: \"signal-strength-pretty-strong\" }, [\n /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\")\n ])\n ])\n], -1 /* HOISTED */)\nconst TTLeftContainervue_type_template_id_387d95cf_hoisted_6 = { class: \"copyright-container\" }\nconst TTLeftContainervue_type_template_id_387d95cf_hoisted_7 = [\"innerHTML\"]\nconst TTLeftContainervue_type_template_id_387d95cf_hoisted_8 = {\n key: 0,\n id: \"feedbackLinkContainer\",\n class: \"feedback-link-container\"\n}\nconst TTLeftContainervue_type_template_id_387d95cf_hoisted_9 = { id: \"feedback-link\" }\n\nfunction TTLeftContainervue_type_template_id_387d95cf_render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_TTMenuSearch = (0,vue_esm_bundler/* resolveComponent */.up)(\"TTMenuSearch\")\n const _component_TTAppMenu = (0,vue_esm_bundler/* resolveComponent */.up)(\"TTAppMenu\")\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Transition */.uT, { name: \"layout-menu-container\" }, {\n default: (0,vue_esm_bundler/* withCtx */.w5)(() => [\n (0,vue_esm_bundler/* withDirectives */.wy)((0,vue_esm_bundler/* createElementVNode */._)(\"div\", {\n class: \"layout-menu-container\",\n onClick: _cache[2] || (_cache[2] = (...args) => ($options.onMenuClick && $options.onMenuClick(...args)))\n }, [\n ($props.layoutMode === 'static')\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(_component_TTMenuSearch, {\n key: 0,\n model: $data.menu_model\n }, null, 8 /* PROPS */, [\"model\"]))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", {\n ref: \"layout-menu-content\",\n class: \"layout-menu-content\",\n onMouseover: _cache[0] || (_cache[0] = (...args) => ($options.onMenuContentMouseOver && $options.onMenuContentMouseOver(...args))),\n onMouseleave: _cache[1] || (_cache[1] = (...args) => ($options.onMenuContentMouseLeave && $options.onMenuContentMouseLeave(...args)))\n }, [\n (0,vue_esm_bundler/* createCommentVNode */.kq)(\"
    MENU
    \"),\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_TTAppMenu, {\n key: 'appmsenu',\n model: $data.menu_model,\n layoutMode: $props.layoutMode,\n active: $data.menuActive,\n mobileMenuActive: $props.staticMenuMobileActive,\n onMenuitemClick: $options.onMenuItemClick,\n onRootMenuitemClick: $options.onRootMenuItemClick\n }, null, 8 /* PROPS */, [\"model\", \"layoutMode\", \"active\", \"mobileMenuActive\", \"onMenuitemClick\", \"onRootMenuitemClick\"]),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", TTLeftContainervue_type_template_id_387d95cf_hoisted_1, [\n (0,vue_esm_bundler/* createCommentVNode */.kq)(\" \"),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", TTLeftContainervue_type_template_id_387d95cf_hoisted_2, [\n TTLeftContainervue_type_template_id_387d95cf_hoisted_3,\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", TTLeftContainervue_type_template_id_387d95cf_hoisted_4, [\n TTLeftContainervue_type_template_id_387d95cf_hoisted_5,\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", TTLeftContainervue_type_template_id_387d95cf_hoisted_6, [\n (0,vue_esm_bundler/* createCommentVNode */.kq)(\" REMOVING OR CHANGING THIS COPYRIGHT NOTICE IS IN STRICT VIOLATION OF THE LICENSE AND COPYRIGHT AGREEMENT \"),\n (0,vue_esm_bundler/* createElementVNode */._)(\"span\", {\n innerHTML: $data.copyright_notice,\n id: \"copy_right_info_1\",\n class: \"copy-right-info\",\n style: {\"display\":\"none\"}\n }, null, 8 /* PROPS */, TTLeftContainervue_type_template_id_387d95cf_hoisted_7)\n ])\n ]),\n ($data.disable_feedback === false)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", TTLeftContainervue_type_template_id_387d95cf_hoisted_8, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"span\", TTLeftContainervue_type_template_id_387d95cf_hoisted_9, \"Send feedback to \" + (0,vue_esm_bundler/* toDisplayString */.zw)($data.application_name), 1 /* TEXT */)\n ]))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true)\n ])\n ])\n ], 544 /* HYDRATE_EVENTS, NEED_PATCH */)\n ], 512 /* NEED_PATCH */), [\n [vue_esm_bundler/* vShow */.F8, $props.isMenuVisible]\n ])\n ]),\n _: 1 /* STABLE */\n }))\n}\n;// CONCATENATED MODULE: ./interface/html5/components/TTLeftContainer.vue?vue&type=template&id=387d95cf\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/main_menu/TTAppMenu.vue?vue&type=template&id=3d96fe3d\n\n\nfunction TTAppMenuvue_type_template_id_3d96fe3d_render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_AppSubmenu = (0,vue_esm_bundler/* resolveComponent */.up)(\"AppSubmenu\")\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(_component_AppSubmenu, {\n ref: \"appSubMenu\",\n id: \"main-menu\",\n class: \"layout-menu layout-main-menu clearfix\",\n items: $props.model,\n layoutMode: $props.layoutMode,\n menuActive: $props.active,\n root: false,\n parentMenuItemActive: true,\n mobileMenuActive: $props.mobileMenuActive\n }, null, 8 /* PROPS */, [\"items\", \"layoutMode\", \"menuActive\", \"mobileMenuActive\"]))\n}\n;// CONCATENATED MODULE: ./interface/html5/components/main_menu/TTAppMenu.vue?vue&type=template&id=3d96fe3d\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/framework/apollo-vue/src/AppSubmenu.vue?vue&type=template&id=6e9b067d\n\n\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_1 = {\n key: 0,\n role: \"menu\"\n}\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_2 = [\"id\"]\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_3 = {\n key: 0,\n class: \"arrow\"\n}\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_4 = { class: \"layout-menuitem-text\" }\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_5 = {\n key: 0,\n class: \"pi pi-fw pi-angle-down layout-menuitem-toggler\"\n}\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_6 = {\n key: 1,\n class: \"menuitem-badge\"\n}\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_7 = [\"href\", \"id\", \"target\", \"onClick\", \"onMouseenter\"]\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_8 = { class: \"layout-menuitem-text\" }\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_9 = {\n key: 0,\n class: \"pi pi-fw pi-angle-down layout-menuitem-toggler\"\n}\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_10 = {\n key: 1,\n class: \"menuitem-badge\"\n}\nconst AppSubmenuvue_type_template_id_6e9b067d_hoisted_11 = {\n key: 3,\n class: \"layout-menuitem-root-text\",\n style: {\"text-transform\":\"uppercase\"}\n}\n\nfunction AppSubmenuvue_type_template_id_6e9b067d_render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_router_link = (0,vue_esm_bundler/* resolveComponent */.up)(\"router-link\")\n const _component_appsubmenu = (0,vue_esm_bundler/* resolveComponent */.up)(\"appsubmenu\")\n const _directive_ripple = (0,vue_esm_bundler/* resolveDirective */.Q2)(\"ripple\")\n\n return ($props.items)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"ul\", AppSubmenuvue_type_template_id_6e9b067d_hoisted_1, [\n ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createElementBlock */.iD)(vue_esm_bundler/* Fragment */.HY, null, (0,vue_esm_bundler/* renderList */.Ko)($props.items, (item, i) => {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(vue_esm_bundler/* Fragment */.HY, null, [\n ($options.visible(item) && !item.separator)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"li\", {\n id: 'main-menu-item-'+item.id,\n key: item.label || i,\n class: (0,vue_esm_bundler/* normalizeClass */.C_)([{'layout-root-menuitem': $props.root, 'active-menuitem': $data.activeIndex === i && !item.disabled}]),\n role: \"none\"\n }, [\n (item.items && $props.root===true)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", AppSubmenuvue_type_template_id_6e9b067d_hoisted_3))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n (item.to)\n ? (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(_component_router_link, {\n key: 1,\n to: item.to,\n style: (0,vue_esm_bundler/* normalizeStyle */.j5)(item.style),\n class: (0,vue_esm_bundler/* normalizeClass */.C_)([item.class, 'p-ripple', {'p-disabled': item.disabled}]),\n target: item.target,\n exact: \"\",\n role: \"menuitem\",\n onClick: $event => ($options.onMenuItemClick($event,item,i)),\n onMouseenter: $event => ($options.onMenuItemMouseEnter(i))\n }, {\n default: (0,vue_esm_bundler/* withCtx */.w5)(() => [\n (0,vue_esm_bundler/* createElementVNode */._)(\"i\", {\n class: (0,vue_esm_bundler/* normalizeClass */.C_)(['layout-menuitem-icon', item.icon])\n }, null, 2 /* CLASS */),\n (0,vue_esm_bundler/* createElementVNode */._)(\"span\", AppSubmenuvue_type_template_id_6e9b067d_hoisted_4, (0,vue_esm_bundler/* toDisplayString */.zw)(item.label), 1 /* TEXT */),\n (item.items)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"i\", AppSubmenuvue_type_template_id_6e9b067d_hoisted_5))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n (item.badge)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"span\", AppSubmenuvue_type_template_id_6e9b067d_hoisted_6, (0,vue_esm_bundler/* toDisplayString */.zw)(item.badge), 1 /* TEXT */))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true)\n ]),\n _: 2 /* DYNAMIC */\n }, 1032 /* PROPS, DYNAMIC_SLOTS */, [\"to\", \"style\", \"class\", \"target\", \"onClick\", \"onMouseenter\"])), [\n [_directive_ripple]\n ])\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n (!item.to)\n ? (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"a\", {\n key: 2,\n href: item.url||'#',\n id: 'main-menu-link-'+item.id,\n style: (0,vue_esm_bundler/* normalizeStyle */.j5)(item.style),\n class: (0,vue_esm_bundler/* normalizeClass */.C_)([item.class, 'p-ripple', {'p-disabled': item.disabled}]),\n target: item.target,\n role: \"menuitem\",\n onClick: $event => ($options.onMenuItemClick($event,item,i)),\n onMouseenter: $event => ($options.onMenuItemMouseEnter(i))\n }, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"i\", {\n class: (0,vue_esm_bundler/* normalizeClass */.C_)(['layout-menuitem-icon', item.icon])\n }, null, 2 /* CLASS */),\n (0,vue_esm_bundler/* createElementVNode */._)(\"span\", AppSubmenuvue_type_template_id_6e9b067d_hoisted_8, (0,vue_esm_bundler/* toDisplayString */.zw)(item.label), 1 /* TEXT */),\n (item.items)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"i\", AppSubmenuvue_type_template_id_6e9b067d_hoisted_9))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n (item.badge)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"span\", AppSubmenuvue_type_template_id_6e9b067d_hoisted_10, (0,vue_esm_bundler/* toDisplayString */.zw)(item.badge), 1 /* TEXT */))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true)\n ], 46 /* CLASS, STYLE, PROPS, HYDRATE_EVENTS */, AppSubmenuvue_type_template_id_6e9b067d_hoisted_7)), [\n [_directive_ripple]\n ])\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n ($props.root)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", AppSubmenuvue_type_template_id_6e9b067d_hoisted_11, (0,vue_esm_bundler/* toDisplayString */.zw)(item.label), 1 /* TEXT */))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n (0,vue_esm_bundler/* createVNode */.Wm)(vue_esm_bundler/* Transition */.uT, { name: \"layout-submenu-container\" }, {\n default: (0,vue_esm_bundler/* withCtx */.w5)(() => [\n (0,vue_esm_bundler/* withDirectives */.wy)((0,vue_esm_bundler/* createVNode */.Wm)(_component_appsubmenu, {\n items: $options.visible(item) && item.items,\n onMenuitemClick: _cache[0] || (_cache[0] = $event => (_ctx.$emit('menuitem-click', $event))),\n layoutMode: $props.layoutMode,\n menuActive: $props.menuActive,\n parentMenuItemActive: $data.activeIndex === i\n }, null, 8 /* PROPS */, [\"items\", \"layoutMode\", \"menuActive\", \"parentMenuItemActive\"]), [\n [vue_esm_bundler/* vShow */.F8, item.items && ($props.root && (!$options.isHorizontal() || ($options.isHorizontal() && ($props.mobileMenuActive || $data.activeIndex !== null))) ? true : $data.activeIndex === i)]\n ])\n ]),\n _: 2 /* DYNAMIC */\n }, 1024 /* DYNAMIC_SLOTS */)\n ], 10 /* CLASS, PROPS */, AppSubmenuvue_type_template_id_6e9b067d_hoisted_2))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true),\n ($options.visible(item) && item.separator)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"li\", {\n class: \"p-menu-separator\",\n style: (0,vue_esm_bundler/* normalizeStyle */.j5)(item.style),\n key: 'separator' + i,\n role: \"separator\"\n }, null, 4 /* STYLE */))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true)\n ], 64 /* STABLE_FRAGMENT */))\n }), 256 /* UNKEYED_FRAGMENT */))\n ]))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"v-if\", true)\n}\n;// CONCATENATED MODULE: ./interface/html5/framework/apollo-vue/src/AppSubmenu.vue?vue&type=template&id=6e9b067d\n\n;// CONCATENATED MODULE: ./interface/html5/framework/apollo-vue/src/event-bus.js\n\n\n/* harmony default export */ const event_bus = ((0,utils_esm/* EventBus */.Nd)());\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/framework/apollo-vue/src/AppSubmenu.vue?vue&type=script&lang=js\n\n\n\n/* harmony default export */ const AppSubmenuvue_type_script_lang_js = ({\n\tname: 'appsubmenu',\n\temits: ['root-menuitem-click', 'menuitem-click'],\n\tprops: {\n\t\titems: Array,\n\t\tlayoutMode: String,\n\t\tmenuActive: Boolean,\n\t\tmobileMenuActive: Boolean,\n\t\troot: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false\n\t\t},\n\t\tparentMenuItemActive: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false\n\t\t}\n\t},\n\tdata() {\n\t\treturn {\n\t\t\tactiveIndex : null\n\t\t}\n\t},\n\tmounted() {\n\t\tevent_bus.on('reset-active-index', () => {\n\t\t\tif((this.layoutMode === 'horizontal' || this.layoutMode === 'slim')) {\n\t\t\t\tthis.activeIndex = null;\n\t\t\t}\n\t\t});\n\t},\n\tmethods: {\n\t\tonMenuItemClick(event, item, index) {\n\t\t\tif (item.disabled) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t//execute command\n\t\t\tif (item.command) {\n item.command({originalEvent: event, item: item});\n event.preventDefault();\n }\n\n if (item.items) {\n event.preventDefault();\n }\n\n\t\t\tif (this.root) {\n\t\t\t\tthis.$emit('root-menuitem-click', {\n\t\t\t\t\toriginalEvent: event\n\t\t\t\t});\n\t\t\t}\n\n if (item.items) {\n this.activeIndex = index === this.activeIndex ? null : index;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif(!this.isStatic()) {\n\t\t\t\t\tconst ink = this.getInk(event.currentTarget);\n\t\t\t\t\tif (ink) {\n\t\t\t\t\t\tthis.removeClass(ink, 'p-ink-active');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.$emit('menuitem-click', {\n\t\t\t\toriginalEvent: event,\n\t\t\t\titem: item\n\t\t\t});\n\t\t},\n\t\tgetInk(el) {\n\t\t\tfor (let i = 0; i < el.children.length; i++) {\n\t\t\t\tif (typeof el.children[i].className === 'string' && el.children[i].className.indexOf('p-ink') !== -1) {\n\t\t\t\t\treturn el.children[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tremoveClass(element, className) {\n\t\t\tif (element.classList)\n\t\t\t\telement.classList.remove(className);\n\t\t\telse\n\t\t\t\telement.className = element.className.replace(new RegExp('(^|\\\\b)' + className.split(' ').join('|') + '(\\\\b|$)', 'gi'), ' ');\n\t\t},\n\t\tisMobile() {\n\t\t\treturn window.innerWidth <= 640;\n\t\t},\n\t\tisHorizontal() {\n\t\t\treturn this.layoutMode === 'horizontal';\n\t\t},\n\t\tisSlim() {\n\t\t\treturn this.layoutMode === 'slim';\n },\n\t\tisStatic() {\n\t\t\treturn this.layoutMode === 'static';\n },\n\t\tonMenuItemMouseEnter(index) {\n\t\t\tif(this.root && this.menuActive && (this.layoutMode === 'horizontal' || this.layoutMode === 'slim') && !this.isMobile()) {\n\t\t\t\tthis.activeIndex = index;\n\t\t\t}\n },\n visible(item) {\n return (typeof item.visible === 'function' ? item.visible() : item.visible !== false);\n }\n\t}\n});\n\n;// CONCATENATED MODULE: ./interface/html5/framework/apollo-vue/src/AppSubmenu.vue?vue&type=script&lang=js\n \n;// CONCATENATED MODULE: ./interface/html5/framework/apollo-vue/src/AppSubmenu.vue\n\n\n\n\n;\nconst AppSubmenu_exports_ = /*#__PURE__*/(0,exportHelper/* default */.Z)(AppSubmenuvue_type_script_lang_js, [['render',AppSubmenuvue_type_template_id_6e9b067d_render]])\n\n/* harmony default export */ const AppSubmenu = (AppSubmenu_exports_);\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/main_menu/TTAppMenu.vue?vue&type=script&lang=js\n\n\n\n/* harmony default export */ const TTAppMenuvue_type_script_lang_js = ({\n created() {\n this.event_bus = new TTEventBus( {\n component_id: this.component_id,\n } );\n this.event_bus.on( this.component_id, 'set_active_index', ( event_data ) => {\n this.$refs.appSubMenu.activeIndex = event_data.index;\n } );\n },\n data() {\n return {\n component_id: 'app_menu',\n }\n },\n\tprops: {\n\t\tmodel: Array,\n\t\tlayoutMode: String,\n\t\tactive: Boolean,\n mobileMenuActive: Boolean\n\t},\n\tcomponents: {\n\t\t'AppSubmenu': AppSubmenu\n\t}\n});\n\n;// CONCATENATED MODULE: ./interface/html5/components/main_menu/TTAppMenu.vue?vue&type=script&lang=js\n \n;// CONCATENATED MODULE: ./interface/html5/components/main_menu/TTAppMenu.vue\n\n\n\n\n;\nconst TTAppMenu_exports_ = /*#__PURE__*/(0,exportHelper/* default */.Z)(TTAppMenuvue_type_script_lang_js, [['render',TTAppMenuvue_type_template_id_3d96fe3d_render]])\n\n/* harmony default export */ const TTAppMenu = (TTAppMenu_exports_);\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/main_menu/TTMenuSearch.vue?vue&type=template&id=53cb780c&scoped=true\n\n\nconst TTMenuSearchvue_type_template_id_53cb780c_scoped_true_withScopeId = n => ((0,vue_esm_bundler/* pushScopeId */.dD)(\"data-v-53cb780c\"),n=n(),(0,vue_esm_bundler/* popScopeId */.Cn)(),n)\nconst TTMenuSearchvue_type_template_id_53cb780c_scoped_true_hoisted_1 = { class: \"tt-menu-search-container\" }\nconst TTMenuSearchvue_type_template_id_53cb780c_scoped_true_hoisted_2 = /*#__PURE__*/ TTMenuSearchvue_type_template_id_53cb780c_scoped_true_withScopeId(() => /*#__PURE__*/(0,vue_esm_bundler/* createElementVNode */._)(\"div\", { class: \"search-separator\" }, null, -1 /* HOISTED */))\n\nfunction TTMenuSearchvue_type_template_id_53cb780c_scoped_true_render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_AutoComplete = (0,vue_esm_bundler/* resolveComponent */.up)(\"AutoComplete\")\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(vue_esm_bundler/* Fragment */.HY, null, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", TTMenuSearchvue_type_template_id_53cb780c_scoped_true_hoisted_1, [\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_AutoComplete, {\n class: \"tt-menu-search\",\n placeholder: \"Search Menu\",\n modelValue: $data.terms,\n \"onUpdate:modelValue\": _cache[0] || (_cache[0] = $event => (($data.terms) = $event)),\n suggestions: $data.searchSuggestions,\n optionGroupLabel: \"label\",\n optionGroupChildren: \"items\",\n onComplete: _cache[1] || (_cache[1] = $event => ($options.searchMenu($event))),\n onItemSelect: _cache[2] || (_cache[2] = $event => ($options.selectItem($event))),\n field: \"label\",\n minLength: $data.minLength\n }, null, 8 /* PROPS */, [\"modelValue\", \"suggestions\", \"minLength\"])\n ]),\n TTMenuSearchvue_type_template_id_53cb780c_scoped_true_hoisted_2\n ], 64 /* STABLE_FRAGMENT */))\n}\n;// CONCATENATED MODULE: ./interface/html5/components/main_menu/TTMenuSearch.vue?vue&type=template&id=53cb780c&scoped=true\n\n// EXTERNAL MODULE: ./node_modules/primevue/button/button.esm.js\nvar button_esm = __webpack_require__(4325);\n// EXTERNAL MODULE: ./node_modules/primevue/virtualscroller/virtualscroller.esm.js\nvar virtualscroller_esm = __webpack_require__(921);\n;// CONCATENATED MODULE: ./node_modules/primevue/autocomplete/autocomplete.esm.js\n\n\n\n\n\n\n\nvar autocomplete_esm_script = {\n name: 'AutoComplete',\n inheritAttrs: false,\n emits: ['update:modelValue', 'item-select', 'item-unselect', 'dropdown-click', 'clear', 'complete'],\n props: {\n modelValue: null,\n suggestions: {\n type: Array,\n default: null\n },\n field: {\n type: [String,Function],\n default: null\n },\n optionGroupLabel: null,\n optionGroupChildren: null,\n scrollHeight: {\n type: String,\n default: '200px'\n },\n dropdown: {\n type: Boolean,\n default: false\n },\n dropdownMode: {\n type: String,\n default: 'blank'\n },\n autoHighlight: {\n type: Boolean,\n default: false\n },\n multiple: {\n type: Boolean,\n default: false\n },\n minLength: {\n type: Number,\n default: 1\n },\n delay: {\n type: Number,\n default: 300\n },\n appendTo: {\n type: String,\n default: 'body'\n },\n forceSelection: {\n type: Boolean,\n default: false\n },\n completeOnFocus: {\n type: Boolean,\n default: false\n },\n inputClass: null,\n inputStyle: null,\n class: null,\n style: null,\n panelClass: null,\n virtualScrollerOptions: {\n type: Object,\n default: null\n }\n },\n timeout: null,\n outsideClickListener: null,\n resizeListener: null,\n scrollHandler: null,\n overlay: null,\n virtualScroller: null,\n data() {\n return {\n searching: false,\n focused: false,\n overlayVisible: false,\n inputTextValue: null,\n highlightItem: null\n };\n },\n watch: {\n suggestions() {\n if (this.searching) {\n if (this.suggestions && this.suggestions.length)\n this.showOverlay();\n else\n this.hideOverlay();\n\n this.searching = false;\n }\n }\n },\n beforeUnmount() {\n this.unbindOutsideClickListener();\n this.unbindResizeListener();\n\n if (this.scrollHandler) {\n this.scrollHandler.destroy();\n this.scrollHandler = null;\n }\n\n if (this.overlay) {\n utils_esm/* ZIndexUtils.clear */.P9.clear(this.overlay);\n this.overlay = null;\n }\n },\n updated() {\n if (this.overlayVisible) {\n this.alignOverlay();\n }\n },\n methods: {\n getOptionIndex(index, fn) {\n return this.virtualScrollerDisabled ? index : (fn && fn(index)['index']);\n },\n getOptionRenderKey(option) {\n return this.getItemContent(option);\n },\n getOptionGroupRenderKey(optionGroup) {\n return utils_esm/* ObjectUtils.resolveFieldData */.gb.resolveFieldData(optionGroup, this.optionGroupLabel);\n },\n getOptionGroupLabel(optionGroup) {\n return utils_esm/* ObjectUtils.resolveFieldData */.gb.resolveFieldData(optionGroup, this.optionGroupLabel);\n },\n getOptionGroupChildren(optionGroup) {\n return utils_esm/* ObjectUtils.resolveFieldData */.gb.resolveFieldData(optionGroup, this.optionGroupChildren);\n },\n onOverlayEnter(el) {\n utils_esm/* ZIndexUtils.set */.P9.set('overlay', el, this.$primevue.config.zIndex.overlay);\n this.alignOverlay();\n this.bindOutsideClickListener();\n this.bindScrollListener();\n this.bindResizeListener();\n\n if (this.autoHighlight && this.suggestions && this.suggestions.length) {\n utils_esm/* DomHandler.addClass */.p7.addClass(this.list.firstElementChild, 'p-highlight');\n }\n },\n onOverlayLeave() {\n this.unbindOutsideClickListener();\n this.unbindScrollListener();\n this.unbindResizeListener();\n this.overlay = null;\n },\n onOverlayAfterLeave(el) {\n utils_esm/* ZIndexUtils.clear */.P9.clear(el);\n },\n alignOverlay() {\n let target = this.multiple ? this.$refs.multiContainer : this.$refs.input;\n if (this.appendDisabled) {\n utils_esm/* DomHandler.relativePosition */.p7.relativePosition(this.overlay, target);\n }\n else {\n this.overlay.style.minWidth = utils_esm/* DomHandler.getOuterWidth */.p7.getOuterWidth(target) + 'px';\n utils_esm/* DomHandler.absolutePosition */.p7.absolutePosition(this.overlay, target);\n }\n },\n bindOutsideClickListener() {\n if (!this.outsideClickListener) {\n this.outsideClickListener = (event) => {\n if (this.overlayVisible && this.overlay && this.isOutsideClicked(event)) {\n this.hideOverlay();\n }\n };\n document.addEventListener('click', this.outsideClickListener);\n }\n },\n bindScrollListener() {\n if (!this.scrollHandler) {\n this.scrollHandler = new utils_esm/* ConnectedOverlayScrollHandler */.Vr(this.$refs.container, () => {\n if (this.overlayVisible) {\n this.hideOverlay();\n }\n });\n }\n\n this.scrollHandler.bindScrollListener();\n },\n unbindScrollListener() {\n if (this.scrollHandler) {\n this.scrollHandler.unbindScrollListener();\n }\n },\n bindResizeListener() {\n if (!this.resizeListener) {\n this.resizeListener = () => {\n if (this.overlayVisible) {\n this.hideOverlay();\n }\n };\n window.addEventListener('resize', this.resizeListener);\n }\n },\n unbindResizeListener() {\n if (this.resizeListener) {\n window.removeEventListener('resize', this.resizeListener);\n this.resizeListener = null;\n }\n },\n isOutsideClicked(event) {\n return !this.overlay.contains(event.target) && !this.isInputClicked(event) && !this.isDropdownClicked(event);\n },\n isInputClicked(event) {\n if (this.multiple)\n return event.target === this.$refs.multiContainer || this.$refs.multiContainer.contains(event.target);\n else\n return event.target === this.$refs.input;\n },\n isDropdownClicked(event) {\n return this.$refs.dropdownButton ? (event.target === this.$refs.dropdownButton || this.$refs.dropdownButton.$el.contains(event.target)) : false;\n },\n unbindOutsideClickListener() {\n if (this.outsideClickListener) {\n document.removeEventListener('click', this.outsideClickListener);\n this.outsideClickListener = null;\n }\n },\n selectItem(event, item) {\n if (this.multiple) {\n this.$refs.input.value = '';\n this.inputTextValue = '';\n\n if (!this.isSelected(item)) {\n let newValue = this.modelValue ? [...this.modelValue, item] : [item];\n this.$emit('update:modelValue', newValue);\n }\n }\n else {\n this.$emit('update:modelValue', item);\n }\n\n this.$emit('item-select', {\n originalEvent: event,\n value: item\n });\n\n this.focus();\n this.hideOverlay();\n },\n onMultiContainerClick(event) {\n this.focus();\n if(this.completeOnFocus) {\n this.search(event, '', 'click');\n }\n },\n removeItem(event, index) {\n let removedValue = this.modelValue[index];\n let newValue = this.modelValue.filter((val, i) => (index !== i));\n this.$emit('update:modelValue', newValue);\n this.$emit('item-unselect', {\n originalEvent: event,\n value: removedValue\n });\n },\n onDropdownClick(event) {\n this.focus();\n const query = this.$refs.input.value;\n\n if (this.dropdownMode === 'blank')\n this.search(event, '', 'dropdown');\n else if (this.dropdownMode === 'current')\n this.search(event, query, 'dropdown');\n\n this.$emit('dropdown-click', {\n originalEvent: event,\n query: query\n });\n },\n getItemContent(item) {\n return this.field ? utils_esm/* ObjectUtils.resolveFieldData */.gb.resolveFieldData(item, this.field) : item;\n },\n showOverlay() {\n this.overlayVisible = true;\n },\n hideOverlay() {\n this.overlayVisible = false;\n },\n focus() {\n this.$refs.input.focus();\n },\n search(event, query, source) {\n //allow empty string but not undefined or null\n if (query === undefined || query === null) {\n return;\n }\n\n //do not search blank values on input change\n if (source === 'input' && query.trim().length === 0) {\n return;\n }\n\n this.searching = true;\n this.$emit('complete', {\n originalEvent: event,\n query: query\n });\n },\n onInputClicked(event) {\n if(this.completeOnFocus) {\n this.search(event, '', 'click');\n }\n },\n onInput(event) {\n this.inputTextValue = event.target.value;\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n\n let query = event.target.value;\n if (!this.multiple) {\n this.$emit('update:modelValue', query);\n }\n\n if (query.length === 0) {\n this.hideOverlay();\n this.$emit('clear');\n }\n else {\n if (query.length >= this.minLength) {\n this.timeout = setTimeout(() => {\n this.search(event, query, 'input');\n }, this.delay);\n }\n else {\n this.hideOverlay();\n }\n }\n },\n onFocus() {\n this.focused = true;\n },\n onBlur() {\n this.focused = false;\n },\n onKeyDown(event) {\n if (this.overlayVisible) {\n let highlightItem = utils_esm/* DomHandler.findSingle */.p7.findSingle(this.list, 'li.p-highlight');\n\n switch(event.which) {\n //down\n case 40:\n if (highlightItem) {\n let nextElement = this.findNextItem(highlightItem);\n if (nextElement) {\n utils_esm/* DomHandler.addClass */.p7.addClass(nextElement, 'p-highlight');\n utils_esm/* DomHandler.removeClass */.p7.removeClass(highlightItem, 'p-highlight');\n nextElement.scrollIntoView({ block: 'nearest', inline: 'start' });\n }\n }\n else {\n highlightItem = this.list.firstElementChild;\n if (utils_esm/* DomHandler.hasClass */.p7.hasClass(highlightItem, 'p-autocomplete-item-group')) {\n highlightItem = this.findNextItem(highlightItem);\n }\n\n if (highlightItem) {\n utils_esm/* DomHandler.addClass */.p7.addClass(highlightItem, 'p-highlight');\n }\n }\n\n event.preventDefault();\n break;\n\n //up\n case 38:\n if (highlightItem) {\n let previousElement = this.findPrevItem(highlightItem);\n if (previousElement) {\n utils_esm/* DomHandler.addClass */.p7.addClass(previousElement, 'p-highlight');\n utils_esm/* DomHandler.removeClass */.p7.removeClass(highlightItem, 'p-highlight');\n previousElement.scrollIntoView({ block: 'nearest', inline: 'start' });\n }\n }\n\n event.preventDefault();\n break;\n\n //enter\n case 13:\n if (highlightItem) {\n this.selectHighlightItem(event, highlightItem);\n this.hideOverlay();\n }\n\n event.preventDefault();\n break;\n\n //escape\n case 27:\n this.hideOverlay();\n event.preventDefault();\n break;\n\n //tab\n case 9:\n if (highlightItem) {\n this.selectHighlightItem(event, highlightItem);\n }\n\n this.hideOverlay();\n break;\n }\n }\n\n if (this.multiple) {\n switch(event.which) {\n //backspace\n case 8:\n if (this.modelValue && this.modelValue.length && !this.$refs.input.value) {\n let removedValue = this.modelValue[this.modelValue.length - 1];\n let newValue = this.modelValue.slice(0, -1);\n\n this.$emit('update:modelValue', newValue);\n this.$emit('item-unselect', {\n originalEvent: event,\n value: removedValue\n });\n }\n break;\n }\n }\n },\n selectHighlightItem(event, item) {\n if (this.optionGroupLabel) {\n let optionGroup = this.suggestions[item.dataset.group];\n this.selectItem(event, this.getOptionGroupChildren(optionGroup)[item.dataset.index]);\n }\n else {\n this.selectItem(event, this.suggestions[item.dataset.index]);\n }\n },\n findNextItem(item) {\n let nextItem = item.nextElementSibling;\n\n if (nextItem)\n return utils_esm/* DomHandler.hasClass */.p7.hasClass(nextItem, 'p-autocomplete-item-group') ? this.findNextItem(nextItem) : nextItem;\n else\n return null;\n },\n findPrevItem(item) {\n let prevItem = item.previousElementSibling;\n\n if (prevItem)\n return utils_esm/* DomHandler.hasClass */.p7.hasClass(prevItem, 'p-autocomplete-item-group') ? this.findPrevItem(prevItem) : prevItem;\n else\n return null;\n },\n onChange(event) {\n if (this.forceSelection) {\n let valid = false;\n let inputValue = event.target.value.trim();\n\n if (this.suggestions) {\n for (let item of this.suggestions) {\n let itemValue = this.field ? utils_esm/* ObjectUtils.resolveFieldData */.gb.resolveFieldData(item, this.field) : item;\n if (itemValue && inputValue === itemValue.trim()) {\n valid = true;\n this.selectItem(event, item);\n break;\n }\n }\n }\n\n if (!valid) {\n this.$refs.input.value = '';\n this.inputTextValue = '';\n this.$emit('clear');\n if (!this.multiple) {\n this.$emit('update:modelValue', null);\n }\n }\n }\n },\n isSelected(val) {\n let selected = false;\n if (this.modelValue && this.modelValue.length) {\n for (let i = 0; i < this.modelValue.length; i++) {\n if (utils_esm/* ObjectUtils.equals */.gb.equals(this.modelValue[i], val)) {\n selected = true;\n break;\n }\n }\n }\n\n return selected;\n },\n overlayRef(el) {\n this.overlay = el;\n },\n listRef(el, contentRef) {\n this.list = el;\n contentRef && contentRef(el); // for virtualScroller\n },\n virtualScrollerRef(el) {\n this.virtualScroller = el;\n },\n onOverlayClick(event) {\n overlayeventbus_esm/* default.emit */.Z.emit('overlay-click', {\n originalEvent: event,\n target: this.$el\n });\n }\n },\n computed: {\n containerClass() {\n return ['p-autocomplete p-component p-inputwrapper', this.class, {\n 'p-autocomplete-dd': this.dropdown,\n 'p-autocomplete-multiple': this.multiple,\n 'p-inputwrapper-filled': ((this.modelValue) || (this.inputTextValue && this.inputTextValue.length)),\n 'p-inputwrapper-focus': this.focused\n }];\n },\n inputFieldClass() {\n return ['p-autocomplete-input p-inputtext p-component', this.inputClass, {\n 'p-autocomplete-dd-input': this.dropdown,\n 'p-disabled': this.$attrs.disabled\n }];\n },\n multiContainerClass() {\n return ['p-autocomplete-multiple-container p-component p-inputtext', {\n 'p-disabled': this.$attrs.disabled,\n 'p-focus': this.focused\n }];\n },\n panelStyleClass() {\n return [\n 'p-autocomplete-panel p-component', this.panelClass, {\n 'p-input-filled': this.$primevue.config.inputStyle === 'filled',\n 'p-ripple-disabled': this.$primevue.config.ripple === false\n }];\n },\n inputValue() {\n if (this.modelValue) {\n if (this.field && typeof this.modelValue === 'object') {\n const resolvedFieldData = utils_esm/* ObjectUtils.resolveFieldData */.gb.resolveFieldData(this.modelValue, this.field);\n return resolvedFieldData != null ? resolvedFieldData : this.modelValue;\n }\n else\n return this.modelValue;\n }\n else {\n return '';\n }\n },\n listId() {\n return (0,utils_esm/* UniqueComponentId */.Th)() + '_list';\n },\n appendDisabled() {\n return this.appendTo === 'self';\n },\n appendTarget() {\n return this.appendDisabled ? null : this.appendTo;\n },\n virtualScrollerDisabled() {\n return !this.virtualScrollerOptions;\n }\n },\n components: {\n 'Button': button_esm[\"default\"],\n 'VirtualScroller': virtualscroller_esm/* default */.Z\n },\n directives: {\n 'ripple': ripple_esm/* default */.Z\n }\n};\n\nconst autocomplete_esm_hoisted_1 = { class: \"p-autocomplete-token-label\" };\nconst autocomplete_esm_hoisted_2 = { class: \"p-autocomplete-input-token\" };\nconst autocomplete_esm_hoisted_3 = {\n key: 2,\n class: \"p-autocomplete-loader pi pi-spinner pi-spin\"\n};\nconst autocomplete_esm_hoisted_4 = { class: \"p-autocomplete-item-group\" };\n\nfunction autocomplete_esm_render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_Button = (0,vue_esm_bundler/* resolveComponent */.up)(\"Button\");\n const _component_VirtualScroller = (0,vue_esm_bundler/* resolveComponent */.up)(\"VirtualScroller\");\n const _directive_ripple = (0,vue_esm_bundler/* resolveDirective */.Q2)(\"ripple\");\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"span\", {\n ref: \"container\",\n class: $options.containerClass,\n \"aria-haspopup\": \"listbox\",\n \"aria-owns\": $options.listId,\n \"aria-expanded\": $data.overlayVisible,\n style: $props.style\n }, [\n (!$props.multiple)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"input\", (0,vue_esm_bundler/* mergeProps */.dG)({\n key: 0,\n ref: \"input\",\n class: $options.inputFieldClass,\n style: $props.inputStyle\n }, _ctx.$attrs, {\n value: $options.inputValue,\n onClick: _cache[1] || (_cache[1] = (...args) => ($options.onInputClicked && $options.onInputClicked(...args))),\n onInput: _cache[2] || (_cache[2] = (...args) => ($options.onInput && $options.onInput(...args))),\n onFocus: _cache[3] || (_cache[3] = (...args) => ($options.onFocus && $options.onFocus(...args))),\n onBlur: _cache[4] || (_cache[4] = (...args) => ($options.onBlur && $options.onBlur(...args))),\n onKeydown: _cache[5] || (_cache[5] = (...args) => ($options.onKeyDown && $options.onKeyDown(...args))),\n onChange: _cache[6] || (_cache[6] = (...args) => ($options.onChange && $options.onChange(...args))),\n type: \"text\",\n autoComplete: \"off\",\n role: \"searchbox\",\n \"aria-autocomplete\": \"list\",\n \"aria-controls\": $options.listId\n }), null, 16, [\"value\", \"aria-controls\"]))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true),\n ($props.multiple)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"ul\", {\n key: 1,\n ref: \"multiContainer\",\n class: $options.multiContainerClass,\n onClick: _cache[12] || (_cache[12] = (...args) => ($options.onMultiContainerClick && $options.onMultiContainerClick(...args)))\n }, [\n ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Fragment */.HY, null, (0,vue_esm_bundler/* renderList */.Ko)($props.modelValue, (item, i) => {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"li\", {\n key: i,\n class: \"p-autocomplete-token\"\n }, [\n (0,vue_esm_bundler/* renderSlot */.WI)(_ctx.$slots, \"chip\", { value: item }, () => [\n (0,vue_esm_bundler/* createVNode */.Wm)(\"span\", autocomplete_esm_hoisted_1, (0,vue_esm_bundler/* toDisplayString */.zw)($options.getItemContent(item)), 1)\n ]),\n (0,vue_esm_bundler/* createVNode */.Wm)(\"span\", {\n class: \"p-autocomplete-token-icon pi pi-times-circle\",\n onClick: $event => ($options.removeItem($event, i))\n }, null, 8, [\"onClick\"])\n ]))\n }), 128)),\n (0,vue_esm_bundler/* createVNode */.Wm)(\"li\", autocomplete_esm_hoisted_2, [\n (0,vue_esm_bundler/* createVNode */.Wm)(\"input\", (0,vue_esm_bundler/* mergeProps */.dG)({\n ref: \"input\",\n type: \"text\",\n autoComplete: \"off\"\n }, _ctx.$attrs, {\n onInput: _cache[7] || (_cache[7] = (...args) => ($options.onInput && $options.onInput(...args))),\n onFocus: _cache[8] || (_cache[8] = (...args) => ($options.onFocus && $options.onFocus(...args))),\n onBlur: _cache[9] || (_cache[9] = (...args) => ($options.onBlur && $options.onBlur(...args))),\n onKeydown: _cache[10] || (_cache[10] = (...args) => ($options.onKeyDown && $options.onKeyDown(...args))),\n onChange: _cache[11] || (_cache[11] = (...args) => ($options.onChange && $options.onChange(...args))),\n role: \"searchbox\",\n \"aria-autocomplete\": \"list\",\n \"aria-controls\": $options.listId\n }), null, 16, [\"aria-controls\"])\n ])\n ], 2))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true),\n ($data.searching)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"i\", autocomplete_esm_hoisted_3))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true),\n ($props.dropdown)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(_component_Button, {\n key: 3,\n ref: \"dropdownButton\",\n type: \"button\",\n icon: \"pi pi-chevron-down\",\n class: \"p-autocomplete-dropdown\",\n disabled: _ctx.$attrs.disabled,\n onClick: $options.onDropdownClick\n }, null, 8, [\"disabled\", \"onClick\"]))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true),\n ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Teleport */.lR, {\n to: $options.appendTarget,\n disabled: $options.appendDisabled\n }, [\n (0,vue_esm_bundler/* createVNode */.Wm)(vue_esm_bundler/* Transition */.uT, {\n name: \"p-connected-overlay\",\n onEnter: $options.onOverlayEnter,\n onLeave: $options.onOverlayLeave,\n onAfterLeave: $options.onOverlayAfterLeave\n }, {\n default: (0,vue_esm_bundler/* withCtx */.w5)(() => [\n ($data.overlayVisible)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"div\", {\n key: 0,\n ref: $options.overlayRef,\n class: $options.panelStyleClass,\n style: {'max-height': $options.virtualScrollerDisabled ? $props.scrollHeight : ''},\n onClick: _cache[13] || (_cache[13] = (...args) => ($options.onOverlayClick && $options.onOverlayClick(...args)))\n }, [\n (0,vue_esm_bundler/* renderSlot */.WI)(_ctx.$slots, \"header\", {\n value: $props.modelValue,\n suggestions: $props.suggestions\n }),\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_VirtualScroller, (0,vue_esm_bundler/* mergeProps */.dG)({ ref: $options.virtualScrollerRef }, $props.virtualScrollerOptions, {\n style: {'height': $props.scrollHeight},\n items: $props.suggestions,\n disabled: $options.virtualScrollerDisabled\n }), (0,vue_esm_bundler/* createSlots */.Nv)({\n content: (0,vue_esm_bundler/* withCtx */.w5)(({ styleClass, contentRef, items, getItemOptions }) => [\n (0,vue_esm_bundler/* createVNode */.Wm)(\"ul\", {\n id: $options.listId,\n ref: (el) => $options.listRef(el, contentRef),\n class: ['p-autocomplete-items', styleClass],\n role: \"listbox\"\n }, [\n (!$props.optionGroupLabel)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Fragment */.HY, { key: 0 }, (0,vue_esm_bundler/* renderList */.Ko)(items, (item, i) => {\n return (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"li\", {\n class: \"p-autocomplete-item\",\n key: $options.getOptionRenderKey(item),\n onClick: $event => ($options.selectItem($event, item)),\n role: \"option\",\n \"data-index\": $options.getOptionIndex(i, getItemOptions)\n }, [\n (0,vue_esm_bundler/* renderSlot */.WI)(_ctx.$slots, \"item\", {\n item: item,\n index: $options.getOptionIndex(i, getItemOptions)\n }, () => [\n (0,vue_esm_bundler/* createTextVNode */.Uk)((0,vue_esm_bundler/* toDisplayString */.zw)($options.getItemContent(item)), 1)\n ])\n ], 8, [\"onClick\", \"data-index\"])), [\n [_directive_ripple]\n ])\n }), 128))\n : ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Fragment */.HY, { key: 1 }, (0,vue_esm_bundler/* renderList */.Ko)(items, (optionGroup, i) => {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Fragment */.HY, {\n key: $options.getOptionGroupRenderKey(optionGroup)\n }, [\n (0,vue_esm_bundler/* createVNode */.Wm)(\"li\", autocomplete_esm_hoisted_4, [\n (0,vue_esm_bundler/* renderSlot */.WI)(_ctx.$slots, \"optiongroup\", {\n item: optionGroup,\n index: $options.getOptionIndex(i, getItemOptions)\n }, () => [\n (0,vue_esm_bundler/* createTextVNode */.Uk)((0,vue_esm_bundler/* toDisplayString */.zw)($options.getOptionGroupLabel(optionGroup)), 1)\n ])\n ]),\n ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Fragment */.HY, null, (0,vue_esm_bundler/* renderList */.Ko)($options.getOptionGroupChildren(optionGroup), (item, j) => {\n return (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"li\", {\n class: \"p-autocomplete-item\",\n key: j,\n onClick: $event => ($options.selectItem($event, item)),\n role: \"option\",\n \"data-group\": i,\n \"data-index\": $options.getOptionIndex(j, getItemOptions)\n }, [\n (0,vue_esm_bundler/* renderSlot */.WI)(_ctx.$slots, \"item\", {\n item: item,\n index: $options.getOptionIndex(j, getItemOptions)\n }, () => [\n (0,vue_esm_bundler/* createTextVNode */.Uk)((0,vue_esm_bundler/* toDisplayString */.zw)($options.getItemContent(item)), 1)\n ])\n ], 8, [\"onClick\", \"data-group\", \"data-index\"])), [\n [_directive_ripple]\n ])\n }), 128))\n ], 64))\n }), 128))\n ], 10, [\"id\"])\n ]),\n _: 2\n }, [\n (_ctx.$slots.loader)\n ? {\n name: \"loader\",\n fn: (0,vue_esm_bundler/* withCtx */.w5)(({ options }) => [\n (0,vue_esm_bundler/* renderSlot */.WI)(_ctx.$slots, \"loader\", { options: options })\n ])\n }\n : undefined\n ]), 1040, [\"style\", \"items\", \"disabled\"]),\n (0,vue_esm_bundler/* renderSlot */.WI)(_ctx.$slots, \"footer\", {\n value: $props.modelValue,\n suggestions: $props.suggestions\n })\n ], 6))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true)\n ]),\n _: 3\n }, 8, [\"onEnter\", \"onLeave\", \"onAfterLeave\"])\n ], 8, [\"to\", \"disabled\"]))\n ], 14, [\"aria-owns\", \"aria-expanded\"]))\n}\n\nfunction autocomplete_esm_styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar autocomplete_esm_css_248z = \"\\n.p-autocomplete {\\n display: -webkit-inline-box;\\n display: -ms-inline-flexbox;\\n display: inline-flex;\\n position: relative;\\n}\\n.p-autocomplete-loader {\\n position: absolute;\\n top: 50%;\\n margin-top: -.5rem;\\n}\\n.p-autocomplete-dd .p-autocomplete-input {\\n -webkit-box-flex: 1;\\n -ms-flex: 1 1 auto;\\n flex: 1 1 auto;\\n width: 1%;\\n}\\n.p-autocomplete-dd .p-autocomplete-input,\\n.p-autocomplete-dd .p-autocomplete-multiple-container {\\n border-top-right-radius: 0;\\n border-bottom-right-radius: 0;\\n}\\n.p-autocomplete-dd .p-autocomplete-dropdown {\\n border-top-left-radius: 0;\\n border-bottom-left-radius: 0px;\\n}\\n.p-autocomplete .p-autocomplete-panel {\\n min-width: 100%;\\n}\\n.p-autocomplete-panel {\\n position: absolute;\\n overflow: auto;\\n top: 0;\\n left: 0;\\n}\\n.p-autocomplete-items {\\n margin: 0;\\n padding: 0;\\n list-style-type: none;\\n}\\n.p-autocomplete-item {\\n cursor: pointer;\\n white-space: nowrap;\\n position: relative;\\n overflow: hidden;\\n}\\n.p-autocomplete-multiple-container {\\n margin: 0;\\n padding: 0;\\n list-style-type: none;\\n cursor: text;\\n overflow: hidden;\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n -webkit-box-align: center;\\n -ms-flex-align: center;\\n align-items: center;\\n -ms-flex-wrap: wrap;\\n flex-wrap: wrap;\\n}\\n.p-autocomplete-token {\\n cursor: default;\\n display: -webkit-inline-box;\\n display: -ms-inline-flexbox;\\n display: inline-flex;\\n -webkit-box-align: center;\\n -ms-flex-align: center;\\n align-items: center;\\n -webkit-box-flex: 0;\\n -ms-flex: 0 0 auto;\\n flex: 0 0 auto;\\n}\\n.p-autocomplete-token-icon {\\n cursor: pointer;\\n}\\n.p-autocomplete-input-token {\\n -webkit-box-flex: 1;\\n -ms-flex: 1 1 auto;\\n flex: 1 1 auto;\\n display: -webkit-inline-box;\\n display: -ms-inline-flexbox;\\n display: inline-flex;\\n}\\n.p-autocomplete-input-token input {\\n border: 0 none;\\n outline: 0 none;\\n background-color: transparent;\\n margin: 0;\\n padding: 0;\\n -webkit-box-shadow: none;\\n box-shadow: none;\\n border-radius: 0;\\n width: 100%;\\n}\\n.p-fluid .p-autocomplete {\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n}\\n.p-fluid .p-autocomplete-dd .p-autocomplete-input {\\n width: 1%;\\n}\\n\";\nautocomplete_esm_styleInject(autocomplete_esm_css_248z);\n\nautocomplete_esm_script.render = autocomplete_esm_render;\n\n/* harmony default export */ const autocomplete_esm = (autocomplete_esm_script);\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/main_menu/TTMenuSearch.vue?vue&type=script&lang=js\n\n\n\n/* harmony default export */ const TTMenuSearchvue_type_script_lang_js = ({\n name: 'TTMenuSearch',\n props: {\n model: Array,\n search: String,\n },\n data() {\n return {\n terms: null,\n searchSuggestions: null,\n minLength: 2\n };\n },\n methods: {\n searchMenu( event ) {\n let findItems = ( items, suggestions, group_header ) => {\n let filtered_items = [];\n for ( let i = 0; i < items.length; i++ ) {\n //If item is a valid menu link compare the label to the search term and add to filtered items if matches.\n if ( items[i].parent_id && items[i].command && items[i].label && items[i].label.toLowerCase().includes( event.query.toLowerCase() ) ) {\n filtered_items.push( items[i] );\n }\n //If item is a header and has child items, recursively search child items.\n if ( items[i].items && items[i].items.length > 0 ) {\n suggestions = findItems( items[i].items, suggestions, items[i].label );\n }\n //Finally add all items from that group to the suggestions by the group header.\n if ( i === items.length - 1 && filtered_items.length > 0 && group_header ) {\n suggestions.push( { label: group_header, items: filtered_items } );\n }\n }\n return suggestions;\n };\n\n this.searchSuggestions = findItems( this.model, [] );\n },\n selectItem( event ) {\n event.value.command();\n },\n },\n components: {\n AutoComplete: autocomplete_esm\n }\n});\n\n;// CONCATENATED MODULE: ./interface/html5/components/main_menu/TTMenuSearch.vue?vue&type=script&lang=js\n \n;// CONCATENATED MODULE: ./interface/html5/components/main_menu/TTMenuSearch.vue\n\n\n\n\n;\n\n\nconst TTMenuSearch_exports_ = /*#__PURE__*/(0,exportHelper/* default */.Z)(TTMenuSearchvue_type_script_lang_js, [['render',TTMenuSearchvue_type_template_id_53cb780c_scoped_true_render],['__scopeId',\"data-v-53cb780c\"]])\n\n/* harmony default export */ const TTMenuSearch = (TTMenuSearch_exports_);\n;// CONCATENATED MODULE: ./node_modules/primevue/progressbar/progressbar.esm.js\n\n\nvar progressbar_esm_script = {\n name: 'ProgressBar',\n props: {\n value: {\n type: Number,\n default: null\n },\n mode: {\n type: String,\n default: 'determinate'\n },\n showValue: {\n type: Boolean,\n default: true\n }\n },\n computed: {\n containerClass() {\n return [\n 'p-progressbar p-component',\n {\n 'p-progressbar-determinate': this.determinate,\n 'p-progressbar-indeterminate': this.indeterminate\n }\n ];\n },\n progressStyle() {\n return {\n width: this.value + '%',\n display: 'flex'\n };\n },\n indeterminate() {\n return this.mode === 'indeterminate';\n },\n determinate() {\n return this.mode === 'determinate';\n }\n }\n};\n\nconst progressbar_esm_hoisted_1 = {\n key: 0,\n class: \"p-progressbar-label\"\n};\nconst progressbar_esm_hoisted_2 = {\n key: 1,\n class: \"p-progressbar-indeterminate-container\"\n};\nconst progressbar_esm_hoisted_3 = /*#__PURE__*/(0,vue_esm_bundler/* createVNode */.Wm)(\"div\", { class: \"p-progressbar-value p-progressbar-value-animate\" }, null, -1);\n\nfunction progressbar_esm_render(_ctx, _cache, $props, $setup, $data, $options) {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"div\", {\n role: \"progressbar\",\n class: $options.containerClass,\n \"aria-valuemin\": \"0\",\n \"aria-valuenow\": $props.value,\n \"aria-valuemax\": \"100\"\n }, [\n ($options.determinate)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"div\", {\n key: 0,\n class: \"p-progressbar-value p-progressbar-value-animate\",\n style: $options.progressStyle\n }, [\n (($props.value != null && $props.value !== 0) && $props.showValue)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"div\", progressbar_esm_hoisted_1, [\n (0,vue_esm_bundler/* renderSlot */.WI)(_ctx.$slots, \"default\", {}, () => [\n (0,vue_esm_bundler/* createTextVNode */.Uk)((0,vue_esm_bundler/* toDisplayString */.zw)($props.value + '%'), 1)\n ])\n ]))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true)\n ], 4))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true),\n ($options.indeterminate)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"div\", progressbar_esm_hoisted_2, [\n progressbar_esm_hoisted_3\n ]))\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true)\n ], 10, [\"aria-valuenow\"]))\n}\n\nfunction progressbar_esm_styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar progressbar_esm_css_248z = \"\\n.p-progressbar {\\n position: relative;\\n overflow: hidden;\\n}\\n.p-progressbar-determinate .p-progressbar-value {\\n height: 100%;\\n width: 0%;\\n position: absolute;\\n display: none;\\n border: 0 none;\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n -webkit-box-align: center;\\n -ms-flex-align: center;\\n align-items: center;\\n -webkit-box-pack: center;\\n -ms-flex-pack: center;\\n justify-content: center;\\n overflow: hidden;\\n}\\n.p-progressbar-determinate .p-progressbar-label {\\n display: -webkit-inline-box;\\n display: -ms-inline-flexbox;\\n display: inline-flex;\\n}\\n.p-progressbar-determinate .p-progressbar-value-animate {\\n -webkit-transition: width 1s ease-in-out;\\n transition: width 1s ease-in-out;\\n}\\n.p-progressbar-indeterminate .p-progressbar-value::before {\\n content: '';\\n position: absolute;\\n background-color: inherit;\\n top: 0;\\n left: 0;\\n bottom: 0;\\n will-change: left, right;\\n -webkit-animation: p-progressbar-indeterminate-anim 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;\\n animation: p-progressbar-indeterminate-anim 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;\\n}\\n.p-progressbar-indeterminate .p-progressbar-value::after {\\n content: '';\\n position: absolute;\\n background-color: inherit;\\n top: 0;\\n left: 0;\\n bottom: 0;\\n will-change: left, right;\\n -webkit-animation: p-progressbar-indeterminate-anim-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;\\n animation: p-progressbar-indeterminate-anim-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;\\n -webkit-animation-delay: 1.15s;\\n animation-delay: 1.15s;\\n}\\n@-webkit-keyframes p-progressbar-indeterminate-anim {\\n0% {\\n left: -35%;\\n right: 100%;\\n}\\n60% {\\n left: 100%;\\n right: -90%;\\n}\\n100% {\\n left: 100%;\\n right: -90%;\\n}\\n}\\n@keyframes p-progressbar-indeterminate-anim {\\n0% {\\n left: -35%;\\n right: 100%;\\n}\\n60% {\\n left: 100%;\\n right: -90%;\\n}\\n100% {\\n left: 100%;\\n right: -90%;\\n}\\n}\\n@-webkit-keyframes p-progressbar-indeterminate-anim-short {\\n0% {\\n left: -200%;\\n right: 100%;\\n}\\n60% {\\n left: 107%;\\n right: -8%;\\n}\\n100% {\\n left: 107%;\\n right: -8%;\\n}\\n}\\n@keyframes p-progressbar-indeterminate-anim-short {\\n0% {\\n left: -200%;\\n right: 100%;\\n}\\n60% {\\n left: 107%;\\n right: -8%;\\n}\\n100% {\\n left: 107%;\\n right: -8%;\\n}\\n}\\n\";\nprogressbar_esm_styleInject(progressbar_esm_css_248z);\n\nprogressbar_esm_script.render = progressbar_esm_render;\n\n/* harmony default export */ const progressbar_esm = (progressbar_esm_script);\n\n// EXTERNAL MODULE: ./interface/html5/services/TTEventBus.js + 1 modules\nvar services_TTEventBus = __webpack_require__(7967);\n;// CONCATENATED MODULE: ./interface/html5/components/main_menu/MenuManager.js\n/* provided dependency */ var MenuManager_$ = __webpack_require__(9755);\n/* provided dependency */ var _ = __webpack_require__(9050);\n// Imports\n// Relies on Debug in @/global/Debug.js imported as a global in HTML tags.\n// Relies on TopMenuManager imported as a global in main.js\n\n\n// TODO: Add in the wizards and dialog (In/Out) options etc.\n// TODO: Check all items are present, compared to old menu. Check permissions!\n// TODO: Fix the group duplicate/missing errors in console. This was just after the big menu update of all items.\n// TODO: - Previously the link was parent -> subgroup -> item.\n// TODO: - And now, the item needs to link direct to the parent, and that association has to be edited manually, so quite a lot to get through.\n// TODO: Fix the menu width when the browser is resized down to mobile. This is related to the width override. Perhaps change the width in the SCSS source files.\n// TODO: Do the colour of the topbar correctly using SCSS 'theme' files so that the theme can be properly changed in future.\n// TODO: Add Account Menu dividers.\n// TODO: Build new context menu with PrimeVue buttons, spend about 20 mins on seeing if we can edit an existing button.\n// Otherwise use v-if vue options to show hide the Save and Save Next as diff buttons.\n// right click menu mirrors the context menu. it has to be completely flat, rather than the grouping for context.\n// context manager that controls both formats. start with the main menu class?\n// TODO: later on: the CSS changes together with moving the company name and support chat links\n// TODO: back burner: Ordering logic needs to be done for main menu. Do this after context menu.\n\nclass MenuManager_MenuManager {\n\tconstructor() {\n\t\tthis.event_bus = new services_TTEventBus/* default */.Z( {\n\t\t\tcomponent_id: 'menu_manager',\n\t\t} );\n\t\tthis.menu_items = [];\n\t\tthis.menu_locked = false; // Track state of menu built/unbuilt. Menu must be reset before items can be added. Otherwise there will be a mix of built and unbuilt items.\n\t\twindow._main_menu = this; // TODO: Temp for local debugging.\n\t}\n\n\tlockMenu() {\n\t\tthis.menu_locked = true;\n\t}\n\tunlockMenu() {\n\t\tthis.menu_locked = false;\n\t}\n\tisMenuLocked() {\n\t\treturn Boolean( this.menu_locked );\n\t}\n\taddItem( item ) {\n\t\tif( this.menu_locked ) {\n\t\t\tDebug.Error( 'Menu is built and locked. Reset menu before adding new items.', 'MenuManager.js', 'MenuManager', 'addItem', 2 );\n\t\t\treturn false;\n\t\t}\n\t\tif( typeof item !== 'object' || item === null || item === undefined ) {\n\t\tDebug.Error( 'Invalid menu item', 'MenuManager.js', 'MenuManager', 'addItem', 2 );\n\t\t\treturn false;\n\t\t}\n\t\tif( this.menu_items.filter( ( menu_item_check ) => menu_item_check.id === item.id ).length !== 0 ) {\n\t\t\tDebug.Error( 'Duplicate menu item. Item ID ('+ item.id +') already exists in menu.', 'MenuManager.js', 'MenuManager', 'addItem', 2 );\n\t\t\treturn false;\n\t\t}\n\t\titem = new TTMenuItem( item );\n\t\tthis.menu_items.push( item );\n\t}\n\n\t/**\n\t * Get the previously built menu model in PrimeVue format without rebuilding the menu on every request.\n\t * @returns {boolean|[]}\n\t */\n\tgetMenu() {\n\t\tif( !this.menu_locked ) {\n\t\t\tDebug.Error( 'Menu has not been built yet. Run convertMenuItemsToPrimeVueFormat() or rebuildMenu()', 'MenuManager.js', 'MenuManager', 'getMenu', 2 );\n\t\t\treturn false;\n\t\t}\n\t\treturn this.menu_items;\n\t}\n\n\trebuildMenu() {\n\t\tthis.initDefaultMenuItems();\n\t\tthis.getMenu();\n\t\treturn this.menu_items;\n\t}\n\n\tconvertMenuItemsToPrimeVueFormat() {\n\t\tif( this.menu_locked ) {\n\t\t\tDebug.Error( 'Menu is already built and locked. Reset menu before rebuilding.', 'MenuManager.js', 'MenuManager', 'convertMenuItemsToPrimeVueFormat', 2 );\n\t\t\treturn false;\n\t\t}\n\n\t\t// Starting build process, lock menu.\n\t\tthis.lockMenu();\n\n\t\tvar menu_output = [];\n\n\t\tthis.menu_items.forEach(( item ) => {\n\t\t\t// Make a copy of the item, by creating a TTMenuItem. Otherwise when items are added to group headers, the item[] array will keep growing on each generation run. Using a class instance also helps be more Object Orientated.\n\t\t\t//item = new TTMenuItem( item );\n\n\t\t\tif ( item.url_type === 'view' && item.destination ) {\n\t\t\t\titem.url = Global.getBaseURL() + '#!m=' + item.destination;\n\t\t\t} else if ( item.url_type === 'sub_view' && item.destination ) {\n\t\t\t\titem.url = Global.getBaseURL() + '#!m=Home&sm=' + item.destination;\n\t\t\t} else if ( !item.url && item.destination ) {\n\t\t\t\titem.url = Global.getBaseURL() + '#!m=Home'; //If view cannot be reached by a URL, go to Home.\n\t\t\t} else if ( !item.url ) {\n\t\t\t\titem.url = 'javascript:;'; // This is to prevent apollo-vue from adding a hash to the 'a href' , which forces a refresh of the page. Alternative is to edit AppSubmenu.vue but that involves duplicating the apollo code into TT codebase.\n\t\t\t}\n\n\t\t\t// check if permissions allow this icon for this user.\n\t\t\tif( item.permission_result === false ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Check if item already exists in menu.\n\t\t\tif( menu_output.filter( ( menu_item_check ) => menu_item_check.id === item.id ).length !== 0 ) {\n\t\t\t\t// Error: Item already exists.\n\t\t\t\tDebug.Error( 'Menu item ('+ item.id +') already exists. Duplicate warning.', 'MenuManager.js', 'MenuManager', 'convertMenuItemsToPrimeVueFormat', 2 );\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Handle tt_link data.\n\t\t\tif( item.destination && item.tt_link ) {\n\t\t\t\titem.parseTTLink();\n\t\t\t}\n\n\t\t\tif ( item.hide_in_main_menu ) {\n\t\t\t\titem.visible = false; //We do not want to show menu items that have been moved elsewhere (such as topbar) in the main menu.\n\t\t\t}\n\n\t\t\t// Grouping. Add item to a parent group, or if no group, add as a root menu element.\n\t\t\tif( item.parent_id ) {\n\n\t\t\t\t// Check if needle_value with that group already exists in output. If not error out and say groups must come before items.\n\n\t\t\t\t// menu_output.forEach(( array_item ) => {\n\t\t\t\t// var group_check = menu_output.map(copy).filter( function recursiveFilter( array_item ) {\n\n\t\t\t\tvar parent_result = this.menu_items.filter( ( parent_item_check ) => parent_item_check.id === item.parent_id )\n\n\t\t\t\tif ( parent_result.length === 1 ) {\n\t\t\t\t\t// Group exists. Add item to the group.\n\t\t\t\t\tparent_result[0].items = parent_result[0].items || []; // By creating a new items array here, rather than earlier (or during addItem), it will always be a fresh array reference on every menu model generation run.\n\t\t\t\t\tparent_result[0].items.push( item ); // relies on JS pass-by-reference to add the items.\n\t\t\t\t} else {\n\t\t\t\t\t// Error: Group either does not exist or duplicates.\n\t\t\t\t\tDebug.Error( 'Menu group ('+ item.parent_id +') for ('+ item.id +') does not exist or there are duplicates. Check addItem() ordering, as group must be added to menu before items can be added.', 'MenuManager.js', 'MenuManager', 'convertMenuItemsToPrimeVueFormat', 2 );\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\t// Item has no parent_id, treat as root menu element.\n\t\t\t\tmenu_output.push( item );\n\t\t\t}\n\t\t});\n\n\t\t// Return only menu item groups that have passed the following checks.\n\t\tvar validated_items = menu_output.filter( ( validation_item ) => {\n\t\t\tif ( validation_item.items ) {\n\t\t\t\t//Each report menu item is a potential dropdown with an array of items if permission checks succeed.\n\t\t\t\t//Checking one level deeper to remove those items if they do not contain items or are a link / separator themselves.\n\t\t\t\tvalidation_item.items = validation_item.items.filter( ( item, index, items_array ) => {\n\t\t\t\t\tif ( item.parent_id && !item.destination && !item.separator && ( !item.items || item.items.every( child_item => child_item.separator ) ) ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t//This fixes issues where due to user permissions there might be unwanted separators.\n\t\t\t\t\t//For example there might be multiple separators in a row or the first/last item might be a separator.\n\t\t\t\t\tif ( item.separator && ( index === 0 || index === items_array.length - 1 || items_array[index - 1].separator ) ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\tvar contains_items = Boolean( validation_item.items !== undefined && validation_item.items.length !== 0\n\t\t\t\t&& validation_item.items.some( item => !item.separator ) ); //Make sure top level contains an actual menu item and not only separators.\n\t\t\tvar has_destination = Boolean( validation_item.destination );\n\t\t\tvar is_separator = Boolean( validation_item.separator );\n\n\t\t\treturn ( contains_items || has_destination || is_separator );\n\t\t} );\n\n\t\tthis.menu_items = validated_items;\n\t}\n\n\tinitDefaultMenuItems() {\n\t\t// reset menu before building.\n\t\tthis.menu_items = [];\n\t\tthis.unlockMenu();\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Dashboard' ),\n\t\t\tid: 'home',\n\t\t\torder: 1000,\n\t\t\ticon: 'tticon tticon-speed_black_24dp',\n\t\t\tdestination: 'Home',\n\t\t\turl_type: 'view'\n\t\t} );\n\n\t\t//Attendance Menu\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Attendance' ),\n\t\t\tid: 'attendance_menu',\n\t\t\torder: 100000,\n\t\t\ticon: 'tticon tticon-schedule_black_24dp',\n\t\t} );\n\n\t\t//Attendance Group Sub Menu\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'TimeSheet' ),\n\t\t\tid: 'TimeSheet',\n\t\t\tdestination: 'TimeSheet',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_attendance',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'TimeSheet' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Punches' ),\n\t\t\tid: 'Punches',\n\t\t\tdestination: 'Punches',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_attendance',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Punches' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Exceptions' ),\n\t\t\tid: 'Exception',\n\t\t\tdestination: 'Exception',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_attendance',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Exception' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Accrual Balances' ),\n\t\t\tid: 'AccrualBalance',\n\t\t\tdestination: 'AccrualBalance',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_attendance',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'AccrualBalance' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Accruals' ),\n\t\t\tid: 'Accrual',\n\t\t\tdestination: 'Accrual',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_attendance',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Accrual' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_attendance_1',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Jobs' ),\n\t\t\tid: 'Job',\n\t\t\tdestination: 'Job',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_job_tracking',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Job' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Tasks' ),\n\t\t\tid: 'JobItem',\n\t\t\tdestination: 'JobItem',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_job_tracking',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobItem' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Punch Tags' ),\n\t\t\tid: 'PunchTag',\n\t\t\tdestination: 'PunchTag',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_job_tracking',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PunchTag' )\n\t\t} );\n\n\t\t//GeoFencing\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'GEO Fences' ),\n\t\t\tid: 'attendance_GEOFence',\n\t\t\tdestination: 'GEOFence',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_job_tracking',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'GEOFence' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Job Groups' ),\n\t\t\tid: 'JobGroup',\n\t\t\tdestination: 'JobGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_job_tracking',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobGroup' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Task Groups' ),\n\t\t\tid: 'JobItemGroup',\n\t\t\tdestination: 'JobItemGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_job_tracking',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobItemGroup' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Punch Tag Groups' ),\n\t\t\tid: 'PunchTagGroup',\n\t\t\tdestination: 'PunchTagGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'attendance_menu',\n\t\t\tsub_group_id: 'attendance_job_tracking',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PunchTagGroup' )\n\t\t} );\n\n\t\t//Schedule Menu\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Schedule' ),\n\t\t\tid: 'schedule_menu',\n\t\t\ticon: 'tticon tticon-calendar_today_black_24dp',\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Schedules' ),\n\t\t\tid: 'Schedule',\n\t\t\tdestination: 'Schedule',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'schedule_menu',\n\t\t\tsub_group_id: 'attendance_schedule',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Schedule' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Scheduled Shifts' ),\n\t\t\tid: 'ScheduleShift',\n\t\t\tdestination: 'ScheduleShift',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'schedule_menu',\n\t\t\tsub_group_id: 'attendance_schedule',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ScheduleShift' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Recurring Schedules' ),\n\t\t\tid: 'RecurringScheduleControl',\n\t\t\tdestination: 'RecurringScheduleControl',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'schedule_menu',\n\t\t\tsub_group_id: 'attendance_schedule',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'RecurringScheduleControl' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Recurring Templates' ),\n\t\t\tid: 'RecurringScheduleTemplateControl',\n\t\t\tdestination: 'RecurringScheduleTemplateControl',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'schedule_menu',\n\t\t\tsub_group_id: 'attendance_schedule',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'RecurringScheduleTemplateControl' )\n\t\t} );\n\n\t\t//Employee Menu\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Employee' ),\n\t\t\tid: 'employee_menu',\n\t\t\ticon: 'tticon tticon-people_alt_black_24dp',\n\t\t} );\n\n\t\t//Employee group Sub Menu\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Employees' ),\n\t\t\tid: 'Employee',\n\t\t\tdestination: 'Employee',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'employee_menu',\n\t\t\tsub_group_id: 'employee_employee',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Employee' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Employee Contacts' ),\n\t\t\tid: 'UserContact',\n\t\t\tdestination: 'UserContact',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'employee_menu',\n\t\t\tsub_group_id: 'employee_employee',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserContact' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Preferences' ),\n\t\t\tid: 'UserPreference',\n\t\t\tdestination: 'UserPreference',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'employee_menu',\n\t\t\tsub_group_id: 'employee_employee',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserPreference' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Wages' ),\n\t\t\tid: 'Wage',\n\t\t\tdestination: 'Wage',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'employee_menu',\n\t\t\tsub_group_id: 'employee_employee',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Wage' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Methods' ),\n\t\t\tid: 'RemittanceDestinationAccount',\n\t\t\tdestination: 'RemittanceDestinationAccount',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'employee_menu',\n\t\t\tsub_group_id: 'employee_employee',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'RemittanceDestinationAccount' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Titles' ),\n\t\t\tid: 'UserTitle',\n\t\t\tdestination: 'UserTitle',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'employee_menu',\n\t\t\tsub_group_id: 'employee_employee',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserTitle' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Employee Groups' ),\n\t\t\tid: 'UserGroup',\n\t\t\tdestination: 'UserGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'employee_menu',\n\t\t\tsub_group_id: 'employee_employee',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserGroup' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Ethnic Groups' ),\n\t\t\tid: 'EthnicGroup',\n\t\t\tdestination: 'EthnicGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'employee_menu',\n\t\t\tsub_group_id: 'employee_employee',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'EthnicGroup' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'New Hire Defaults' ),\n\t\t\tid: 'UserDefault',\n\t\t\tdestination: 'UserDefault',\n\t\t\turl_type: Global.getProductEdition() > 10 ? 'view' : 'sub_view',\n\t\t\tparent_id: 'employee_menu',\n\t\t\tsub_group_id: 'employee_employee',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserDefault' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Record of Employment' ),\n\t\t\tid: 'ROE',\n\t\t\tdestination: 'ROE',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'employee_menu',\n\t\t\tsub_group_id: 'employee_employee',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ROE' )\n\t\t} );\n\n\t\t//Company Menu\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Company' ),\n\t\t\tid: 'company_menu',\n\t\t\ticon: 'tticon tticon-business_black_24dp'\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Companies' ),\n\t\t\tid: 'Companies',\n\t\t\tdestination: 'Companies',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Companies' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Company Information' ),\n\t\t\tid: 'Company',\n\t\t\tdestination: 'Company',\n\t\t\turl_type: 'sub_view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Company' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: ( Global.getProductEdition() >= 15 ) ? MenuManager_$.i18n._( 'Legal Entities' ) : MenuManager_$.i18n._( 'Legal Entity' ),\n\t\t\tid: 'LegalEntity',\n\t\t\tdestination: 'LegalEntity',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'LegalEntity' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Branches' ),\n\t\t\tid: 'Branch',\n\t\t\tdestination: 'Branch',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Branch' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Departments' ),\n\t\t\tid: 'Department',\n\t\t\tdestination: 'Department',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Department' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Hierarchy' ),\n\t\t\tid: 'HierarchyControl',\n\t\t\tdestination: 'HierarchyControl',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'HierarchyControl' )\n\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Secondary Wage Groups' ),\n\t\t\tid: 'WageGroup',\n\t\t\tdestination: 'WageGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'WageGroup' )\n\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Stations' ),\n\t\t\tid: 'Station',\n\t\t\tdestination: 'Station',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Station' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Permission Groups' ),\n\t\t\tid: 'PermissionControl',\n\t\t\tdestination: 'PermissionControl',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PermissionControl' )\n\t\t} );\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Currencies' ),\n\t\t\tid: 'Currency',\n\t\t\tdestination: 'Currency',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Currency' )\n\n\t\t} );\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Custom Fields' ),\n\t\t\tid: 'CustomField',\n\t\t\tdestination: 'CustomField',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_company',\n\t\t\tpermission_result: ( PermissionManager.checkTopLevelPermission( 'CustomField' ) && Global.getFeatureFlag( 'custom_field' ) == true )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_company_1',\n\t\t\tparent_id: 'company_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Import' ),\n\t\t\tid: 'ImportCSV',\n\t\t\tdestination: 'ImportCSV',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_other',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ImportCSV' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Quick Start' ),\n\t\t\tid: 'QuickStartWizard',\n\t\t\tdestination: 'QuickStartWizard',\n\t\t\tparent_id: 'company_menu',\n\t\t\tsub_group_id: 'company_other',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'QuickStartWizard' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Payroll' ),\n\t\t\tid: 'payroll_menu',\n\t\t\ticon: 'tticon tticon-attach_money_black_24dp'\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Process Payroll' ),\n\t\t\tid: 'ProcessPayrollWizard',\n\t\t\tdestination: 'ProcessPayrollWizard',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayrollProcessWizard' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Tax Wizard' ),\n\t\t\tid: 'PayrollRemittanceAgencyEventWizardController',\n\t\t\tdestination: 'PayrollRemittanceAgencyEventWizardController',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayrollProcessWizard' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Stubs' ),\n\t\t\tid: 'PayStub',\n\t\t\tdestination: 'PayStub',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayStub' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Stub Transactions' ),\n\t\t\tid: 'PayStubTransaction',\n\t\t\tdestination: 'PayStubTransaction',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayStubTransaction' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Government Documents' ),\n\t\t\tid: 'GovernmentDocument',\n\t\t\tdestination: 'GovernmentDocument',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'GovernmentDocument' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Periods' ),\n\t\t\tid: 'PayPeriods',\n\t\t\tdestination: 'PayPeriods',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayPeriods' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Stub Amendments' ),\n\t\t\tid: 'PayStubAmendment',\n\t\t\tdestination: 'PayStubAmendment',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayStubAmendment' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Period Schedules' ),\n\t\t\tid: 'payroll_PayPeriodSchedule',\n\t\t\tdestination: 'PayPeriodSchedule',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayPeriodSchedule' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Stub Accounts' ),\n\t\t\tid: 'PayStubEntryAccount',\n\t\t\tdestination: 'PayStubEntryAccount',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayStubEntryAccount' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Taxes & Deductions' ),\n\t\t\tid: 'CompanyTaxDeduction',\n\t\t\tdestination: 'CompanyTaxDeduction',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'CompanyTaxDeduction' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Remittance Agencies' ),\n\t\t\tid: 'PayrollRemittanceAgency',\n\t\t\tdestination: 'PayrollRemittanceAgency',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayrollRemittanceAgency' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Remittance Sources' ),\n\t\t\tid: 'RemittanceSourceAccount',\n\t\t\tdestination: 'RemittanceSourceAccount',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'RemittanceSourceAccount' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Expenses' ),\n\t\t\tid: 'UserExpense',\n\t\t\tdestination: 'UserExpense',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'payroll_menu',\n\t\t\tsub_group_id: 'payroll_payroll',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserExpense' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Policy' ),\n\t\t\tid: 'policy_menu',\n\t\t\ticon: 'tticon tticon-rule_folder_black_24dp'\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Policy Groups' ),\n\t\t\tid: 'PolicyGroup',\n\t\t\tdestination: 'PolicyGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_building_blocks',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PolicyGroup' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_policy_1',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Codes' ),\n\t\t\tid: 'PayCode',\n\t\t\tdestination: 'PayCode',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_building_blocks',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayCode' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Formulas' ),\n\t\t\tid: 'PayFormulaPolicy',\n\t\t\tdestination: 'PayFormulaPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_building_blocks',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayFormulaPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Contributing Pay Codes' ),\n\t\t\tid: 'ContributingPayCodePolicy',\n\t\t\tdestination: 'ContributingPayCodePolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_building_blocks',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ContributingPayCodePolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Contributing Shifts' ),\n\t\t\tid: 'ContributingShiftPolicy',\n\t\t\tdestination: 'ContributingShiftPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_building_blocks',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ContributingShiftPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Accrual Accounts' ),\n\t\t\tid: 'AccrualPolicyAccount',\n\t\t\tdestination: 'AccrualPolicyAccount',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_building_blocks',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'AccrualPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Recurring Holidays' ),\n\t\t\tid: 'RecurringHoliday',\n\t\t\tdestination: 'RecurringHoliday',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_building_blocks',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'RecurringHoliday' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_policy_2',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Schedule Policies' ),\n\t\t\tid: 'SchedulePolicy',\n\t\t\tdestination: 'SchedulePolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'SchedulePolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Rounding Policies' ),\n\t\t\tid: 'RoundIntervalPolicy',\n\t\t\tdestination: 'RoundIntervalPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'RoundIntervalPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Meal Policies' ),\n\t\t\tid: 'MealPolicy',\n\t\t\tdestination: 'MealPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'MealPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Break Policies' ),\n\t\t\tid: 'BreakPolicy',\n\t\t\tdestination: 'BreakPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'BreakPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Regular Time Policies' ),\n\t\t\tid: 'RegularTimePolicy',\n\t\t\tdestination: 'RegularTimePolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'RegularTimePolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Overtime Policies' ),\n\t\t\tid: 'OvertimePolicy',\n\t\t\tdestination: 'OvertimePolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'OvertimePolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Premium Policies' ),\n\t\t\tid: 'PremiumPolicy',\n\t\t\tdestination: 'PremiumPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PremiumPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Exception Policies' ),\n\t\t\tid: 'ExceptionPolicyControl',\n\t\t\tdestination: 'ExceptionPolicyControl',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ExceptionPolicyControl' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Accrual Policies' ),\n\t\t\tid: 'AccrualPolicy',\n\t\t\tdestination: 'AccrualPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'AccrualPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Absence Policies' ),\n\t\t\tid: 'AbsencePolicy',\n\t\t\tdestination: 'AbsencePolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'AbsencePolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Expense Policies' ),\n\t\t\tid: 'ExpensePolicy',\n\t\t\tdestination: 'ExpensePolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ExpensePolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Holiday Policies' ),\n\t\t\tid: 'HolidayPolicy',\n\t\t\tdestination: 'HolidayPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'policy_menu',\n\t\t\tsub_group_id: 'policy_policy',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'HolidayPolicy' )\n\t\t} );\n\n\t\t// Invoice group\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Invoice' ),\n\t\t\tid: 'invoice_menu',\n\t\t\ticon: 'tticon tticon-receipt_long_black_24dp'\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Clients' ),\n\t\t\tid: 'Client',\n\t\t\tdestination: 'Client',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_invoice',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Client' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Client Contacts' ),\n\t\t\tid: 'ClientContact',\n\t\t\tdestination: 'ClientContact',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_invoice',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ClientContact' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Invoices' ),\n\t\t\tid: 'Invoice',\n\t\t\tdestination: 'Invoice',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_invoice',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Invoice' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Transactions' ),\n\t\t\tid: 'InvoiceTransaction',\n\t\t\tdestination: 'InvoiceTransaction',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_invoice',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'InvoiceTransaction' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Payment Methods' ),\n\t\t\tid: 'ClientPayment',\n\t\t\tdestination: 'ClientPayment',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_invoice',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ClientPayment' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Products' ),\n\t\t\tid: 'Product',\n\t\t\tdestination: 'Product',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_invoice',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Product' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'District' ),\n\t\t\tid: 'InvoiceDistrict',\n\t\t\tdestination: 'InvoiceDistrict',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_invoice',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'InvoiceDistrict' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_invoice_1',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Client Groups' ),\n\t\t\tid: 'ClientGroup',\n\t\t\tdestination: 'ClientGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_groups',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Client' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Product Groups' ),\n\t\t\tid: 'ProductGroup',\n\t\t\tdestination: 'ProductGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_groups',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Product' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_invoice_2',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Tax Policies' ),\n\t\t\tid: 'TaxPolicy',\n\t\t\tdestination: 'TaxPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_policies',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'TaxPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Shipping Policies' ),\n\t\t\tid: 'ShippingPolicy',\n\t\t\tdestination: 'ShippingPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_policies',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ShippingPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Area Policies' ),\n\t\t\tid: 'AreaPolicy',\n\t\t\tdestination: 'AreaPolicy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_policies',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'AreaPolicy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_invoice_3',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Payment Gateway' ),\n\t\t\tid: 'PaymentGateway',\n\t\t\tdestination: 'PaymentGateway',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_settings',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PaymentGateway' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Settings' ),\n\t\t\tid: 'InvoiceConfig',\n\t\t\tdestination: 'InvoiceConfig',\n\t\t\turl_type: 'sub_view',\n\t\t\tparent_id: 'invoice_menu',\n\t\t\tsub_group_id: 'invoice_settings',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'InvoiceConfig' )\n\t\t} );\n\n\t\t//HR Menu\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'HR' ),\n\t\t\tid: 'hr_menu',\n\t\t\ticon: 'tticon tticon-business_center_black_24dp'\n\t\t} );\n\n\t\t//reviews Group Sub Menu\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Reviews' ),\n\t\t\tid: 'UserReviewControl',\n\t\t\tdestination: 'UserReviewControl',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tsub_group_id: 'hr_reviews',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserReviewControl' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'KPI' ),\n\t\t\tid: 'KPI',\n\t\t\tdestination: 'KPI',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tsub_group_id: 'hr_reviews',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'KPI' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'KPI Groups' ),\n\t\t\tid: 'KPIGroup',\n\t\t\tdestination: 'KPIGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tsub_group_id: 'hr_reviews',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'KPIGroup' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_hr_1',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Qualifications' ),\n\t\t\tid: 'Qualification',\n\t\t\tdestination: 'Qualification',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tsub_group_id: 'hr_qualifications',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Qualification' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Qualification Groups' ),\n\t\t\tid: 'QualificationGroup',\n\t\t\tdestination: 'QualificationGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tsub_group_id: 'hr_qualifications',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'QualificationGroup' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Skills' ),\n\t\t\tid: 'UserSkill',\n\t\t\tdestination: 'UserSkill',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tsub_group_id: 'hr_qualifications',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserSkill' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Education' ),\n\t\t\tid: 'UserEducation',\n\t\t\tdestination: 'UserEducation',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tsub_group_id: 'hr_qualifications',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserEducation' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Memberships' ),\n\t\t\tid: 'UserMembership',\n\t\t\tdestination: 'UserMembership',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tsub_group_id: 'hr_qualifications',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserMembership' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Licenses' ),\n\t\t\tid: 'UserLicense',\n\t\t\tdestination: 'UserLicense',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tsub_group_id: 'hr_qualifications',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserLicense' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Languages' ),\n\t\t\tid: 'UserLanguage',\n\t\t\tdestination: 'UserLanguage',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'hr_menu',\n\t\t\tsub_group_id: 'hr_qualifications',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserLanguage' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Recruitment' ),\n\t\t\tid: 'recruitment_menu',\n\t\t\ticon: 'tticon tticon-switch_account_black_24dp'\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Job Vacancies' ),\n\t\t\tid: 'JobVacancy',\n\t\t\tdestination: 'JobVacancy',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'recruitment_menu',\n\t\t\tsub_group_id: 'hr_recruitment',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobVacancy' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Job Applicants' ),\n\t\t\tid: 'JobApplicant',\n\t\t\tdestination: 'JobApplicant',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'recruitment_menu',\n\t\t\tsub_group_id: 'hr_recruitment',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobApplicant' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Job Applications' ),\n\t\t\tid: 'JobApplication',\n\t\t\tdestination: 'JobApplication',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'recruitment_menu',\n\t\t\tsub_group_id: 'hr_recruitment',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobApplication' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Portal Settings' ),\n\t\t\tid: 'RecruitmentPortalConfig',\n\t\t\tdestination: 'RecruitmentPortalConfig',\n\t\t\turl_type: 'sub_view',\n\t\t\tparent_id: 'recruitment_menu',\n\t\t\tsub_group_id: 'hr_recruitment',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobApplicant' )\n\t\t} );\n\n\n\t\t// TODO: Above is done - next: Documents\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Document' ),\n\t\t\tid: 'document_menu',\n\t\t\ticon: 'tticon tticon-feed_black_24dp'\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Documents' ),\n\t\t\tid: 'Document',\n\t\t\tdestination: 'Document',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'document_menu',\n\t\t\tsub_group_id: 'documentsGroup',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Document' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Document Groups' ),\n\t\t\tid: 'DocumentGroup',\n\t\t\tdestination: 'DocumentGroup',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'document_menu',\n\t\t\tsub_group_id: 'documentsGroup',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'DocumentGroup' )\n\t\t} );\n\n\t\t// TODO: Above is done - next: Reports\n\n\t\t//Reports\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Report' ),\n\t\t\tid: 'report_menu',\n\t\t\ticon: 'tticon tticon-show_chart_black_24dp'\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Saved Reports' ),\n\t\t\tid: 'report_saved_reports',\n\t\t\tdestination: 'SavedReport',\n\t\t\turl_type: 'view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view' // the legacy 'saved reports' triggered the closeEditViews, setSelectSubMenu and openSelectView. Same as the wizard code in parseTTLink etc. Which is currently triggered by 'view'\n\t\t\t},\n\t\t\tparent_id: 'report_menu',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'SavedReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_report_saved_reports_1',\n\t\t\tparent_id: 'report_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Employee Reports' ),\n\t\t\tid: 'report_employee_reports',\n\t\t\tparent_id: 'report_menu',\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Whos In Summary' ),\n\t\t\tid: 'ActiveShiftReport',\n\t\t\tdestination: 'ActiveShiftReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_employee_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ActiveShiftReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Employee Information' ),\n\t\t\tid: 'UserSummaryReport',\n\t\t\tdestination: 'UserSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_employee_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Audit Trail' ),\n\t\t\tid: 'AuditTrailReport',\n\t\t\tdestination: 'AuditTrailReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_employee_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'AuditTrailReport' )\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'TimeSheet Reports' ),\n\t\t\tid: 'report_timesheet_reports',\n\t\t\tparent_id: 'report_menu',\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Schedule Summary' ),\n\t\t\tid: 'ScheduleSummaryReport',\n\t\t\tdestination: 'ScheduleSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_timesheet_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ScheduleSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'TimeSheet Summary' ),\n\t\t\tid: 'TimesheetSummaryReport',\n\t\t\tdestination: 'TimesheetSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_timesheet_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'TimesheetSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'TimeSheet Detail' ),\n\t\t\tid: 'TimesheetDetailReport',\n\t\t\tdestination: 'TimesheetDetailReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_timesheet_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'TimesheetDetailReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Punch Summary' ),\n\t\t\tid: 'PunchSummaryReport',\n\t\t\tdestination: 'PunchSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_timesheet_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PunchSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Accrual Balance Summary' ),\n\t\t\tid: 'AccrualBalanceSummaryReport',\n\t\t\tdestination: 'AccrualBalanceSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_timesheet_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'AccrualBalanceSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Exception Summary' ),\n\t\t\tid: 'ExceptionSummaryReport',\n\t\t\tdestination: 'ExceptionSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_timesheet_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ExceptionSummaryReport' )\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Payroll Reports' ),\n\t\t\tid: 'report_payroll_reports',\n\t\t\tparent_id: 'report_menu',\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Stub Summary' ),\n\t\t\tid: 'PayStubSummaryReport',\n\t\t\tdestination: 'PayStubSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_payroll_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayStubSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Pay Stub Transaction Summary' ),\n\t\t\tid: 'PayStubTransactionSummaryReport',\n\t\t\tdestination: 'PayStubTransactionSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_payroll_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayStubSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Payroll Export' ),\n\t\t\tid: 'PayrollExportReport',\n\t\t\tdestination: 'PayrollExportReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_payroll_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'PayrollExportReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'General Ledger Summary' ),\n\t\t\tid: 'GeneralLedgerSummaryReport',\n\t\t\tdestination: 'GeneralLedgerSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_payroll_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'GeneralLedgerSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Expense Summary' ),\n\t\t\tid: 'ExpenseSummaryReport',\n\t\t\tdestination: 'ExpenseSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_payroll_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ExpenseSummaryReport' )\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Job Tracking Reports' ),\n\t\t\tid: 'report_job_tracking_reports',\n\t\t\tparent_id: 'report_menu',\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Job Summary' ),\n\t\t\tid: 'JobSummaryReport',\n\t\t\tdestination: 'JobSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_job_tracking_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Job Analysis' ),\n\t\t\tid: 'JobAnalysisReport',\n\t\t\tdestination: 'JobAnalysisReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_job_tracking_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobAnalysisReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Job Information' ),\n\t\t\tid: 'JobInformationReport',\n\t\t\tdestination: 'JobInformationReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_job_tracking_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobInformationReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Task Information' ),\n\t\t\tid: 'JobItemInformationReport',\n\t\t\tdestination: 'JobItemInformationReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_job_tracking_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'JobItemInformationReport' )\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Invoice Reports' ),\n\t\t\tid: 'report_invoice_reports',\n\t\t\tparent_id: 'report_menu',\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Transaction Summary' ),\n\t\t\tid: 'InvoiceTransactionSummaryReport',\n\t\t\tdestination: 'InvoiceTransactionSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_invoice_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'InvoiceTransactionSummaryReport' )\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Tax Reports' ),\n\t\t\tid: 'report_tax_reports',\n\t\t\tparent_id: 'report_menu',\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Tax Summary (Generic)' ),\n\t\t\tid: 'TaxSummaryReport',\n\t\t\tdestination: 'TaxSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'TaxSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_report_tax_reports_1',\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Remittance Summary' ),\n\t\t\tid: 'RemittanceSummaryReport',\n\t\t\tdestination: 'RemittanceSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'RemittanceSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'T4 Summary' ),\n\t\t\tid: 'T4SummaryReport',\n\t\t\tdestination: 'T4SummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'T4SummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'T4A Summary' ),\n\t\t\tid: 'T4ASummaryReport',\n\t\t\tdestination: 'T4ASummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'T4ASummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_report_tax_reports_2',\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tseparator: true,\n\t\t\tpermission_result: ( PermissionManager.checkTopLevelPermission( 'RemittanceSummaryReport' ) && PermissionManager.checkTopLevelPermission( 'Form941Report' ) ) //Only show the 2nd separator if Canada and US tax forms are displayed too. Otherwise the separator is doubled up.\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'US State Unemployment' ),\n\t\t\tid: 'USStateUnemploymentReport',\n\t\t\tdestination: 'USStateUnemploymentReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'USStateUnemploymentReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Form 941' ),\n\t\t\tid: 'Form941Report',\n\t\t\tdestination: 'Form941Report',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Form941Report' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Form 940' ),\n\t\t\tid: 'Form940Report',\n\t\t\tdestination: 'Form940Report',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Form940Report' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Form 1099-NEC' ),\n\t\t\tid: 'Form1099NecReport',\n\t\t\tdestination: 'Form1099NecReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Form1099NecReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Form W2/W3' ),\n\t\t\tid: 'FormW2Report',\n\t\t\tdestination: 'FormW2Report',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'FormW2Report' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Affordable Care' ),\n\t\t\tid: 'AffordableCareReport',\n\t\t\tdestination: 'AffordableCareReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_tax_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'AffordableCareReport' )\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'HR Reports' ),\n\t\t\tid: 'report_hr_reports',\n\t\t\tparent_id: 'report_menu',\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Qualification Summary' ),\n\t\t\tid: 'UserQualificationReport',\n\t\t\tdestination: 'UserQualificationReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_hr_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserQualificationReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Review Summary' ),\n\t\t\tid: 'KPIReport',\n\t\t\tdestination: 'KPIReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_hr_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'KPIReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Recruitment Summary' ),\n\t\t\tid: 'UserRecruitmentSummaryReport',\n\t\t\tdestination: 'UserRecruitmentSummaryReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_hr_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserRecruitmentSummaryReport' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Recruitment Detail' ),\n\t\t\tid: 'UserRecruitmentDetailReport',\n\t\t\tdestination: 'UserRecruitmentDetailReport',\n\t\t\turl_type: 'sub_view',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'report'\n\t\t\t},\n\t\t\tparent_id: 'report_hr_reports',\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'UserRecruitmentDetailReport' )\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\t// End of reports\n\n\t\t/**************************************************/\n\n\t\t//My Account group\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'My Account' ),\n\t\t\tid: 'my_account_menu',\n\t\t\ticon: 'tticon tticon-person_black_24dp',\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\t// this.addItem( {\n\t\t// \tlabel: $.i18n._( 'Notifications' ),\n\t\t// \tid: 'notification',\n\t\t// \tdestination: 'Notification',\n\t\t// \tparent_id: 'my_account_menu',\n\t\t// \tsub_group_id: 'myAccountGroup',\n\t\t// \thide_in_main_menu: true,\n\t\t// \tpermission_result: true, // Notification always returns true as notifications should always be enabled.\n\t\t// } );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Messages' ),\n\t\t\tid: 'message',\n\t\t\tdestination: 'MessageControl',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tsub_group_id: 'myAccountGroup',\n\t\t\thide_in_main_menu: true,\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'MessageControl' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Requests' ),\n\t\t\tid: 'request',\n\t\t\tdestination: 'Request',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tsub_group_id: 'myAccountGroup',\n\t\t\thide_in_main_menu: true,\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'Request' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Expenses' ),\n\t\t\tid: 'LoginUserExpense',\n\t\t\tdestination: 'LoginUserExpense',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tsub_group_id: 'myAccountGroup',\n\t\t\thide_in_main_menu: true,\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'LoginUserExpense' )\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_my_account_1',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Request Authorizations' ),\n\t\t\tid: 'request_authorization',\n\t\t\tdestination: 'RequestAuthorization',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tsub_group_id: 'authorization',\n\t\t\thide_in_main_menu: true,\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'RequestAuthorization' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'TimeSheet Authorizations' ),\n\t\t\tid: 'timesheet_authorization',\n\t\t\tdestination: 'TimeSheetAuthorization',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tsub_group_id: 'authorization',\n\t\t\thide_in_main_menu: true,\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'TimeSheetAuthorization' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Expense Authorizations' ),\n\t\t\tid: 'expense_authorization',\n\t\t\tdestination: 'ExpenseAuthorization',\n\t\t\turl_type: 'view',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tsub_group_id: 'authorization',\n\t\t\thide_in_main_menu: true,\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ExpenseAuthorization' )\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_my_account_2',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Preferences' ),\n\t\t\tid: 'LoginUserPreference',\n\t\t\tdestination: 'LoginUserPreference',\n\t\t\turl_type: 'sub_view',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tsub_group_id: 'myAccountGroup',\n\t\t\thide_in_main_menu: true,\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'LoginUserPreference' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Contact Information' ),\n\t\t\tid: 'LoginUserContact',\n\t\t\tdestination: 'LoginUserContact',\n\t\t\turl_type: 'sub_view',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tsub_group_id: 'myAccountGroup',\n\t\t\thide_in_main_menu: true,\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'LoginUserContact' )\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Passwords / Security' ),\n\t\t\tid: 'ChangePassword',\n\t\t\tdestination: 'ChangePassword',\n\t\t\turl_type: 'sub_view',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tsub_group_id: 'securityGroup',\n\t\t\thide_in_main_menu: true,\n\t\t\tpermission_result: PermissionManager.checkTopLevelPermission( 'ChangePassword' )\n\t\t} );\n\n\t\t/**************************************************/\n\n\t\tthis.addItem( {\n\t\t\tid: 'separator_my_account_4',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tseparator: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Logout' ),\n\t\t\tid: 'Logout',\n\t\t\ticon: 'tticon tticon-logout_black_24dp',\n\t\t\tdestination: 'Logout',\n\t\t\tparent_id: 'my_account_menu',\n\t\t\tsub_group_id: 'logoutGroup',\n\t\t\thide_in_main_menu: true,\n\t\t\tpermission_result: true,\n\t\t} );\n\n\t\t//Help group\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Help' ),\n\t\t\tid: 'help_menu',\n\t\t\ticon: 'tticon tticon-help_center_black_24dp',\n\t\t\tpermission_result: true,\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Administrator Guide' ),\n\t\t\tid: 'AdminGuide',\n\t\t\tdestination: 'AdminGuide',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view_no_close'\n\t\t\t},\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: PermissionManager.HelpMenuValidateAdmin(),\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Supervisor Guide' ),\n\t\t\tid: 'SupervisorGuide',\n\t\t\tdestination: 'SupervisorGuide',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view_no_close'\n\t\t\t},\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: PermissionManager.HelpMenuValidateSupervisor(),\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Employee Guide' ),\n\t\t\tid: 'EmployeeGuide',\n\t\t\tdestination: 'EmployeeGuide',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view_no_close'\n\t\t\t},\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: true,\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\t//Only display one \"FAQ\" entry for the highest permission level they have. This keeps the menu a little smaller and less confusing.\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'FAQs' ),\n\t\t\tid: 'AdminFAQS',\n\t\t\tdestination: 'AdminFAQS',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view_no_close'\n\t\t\t},\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: PermissionManager.HelpMenuValidateAdmin(),\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'FAQs' ), //Supervisor FAQ\n\t\t\tid: 'SupervisorFAQS',\n\t\t\tdestination: 'SupervisorFAQS',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view_no_close'\n\t\t\t},\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: ( PermissionManager.HelpMenuValidateSupervisor() && !PermissionManager.HelpMenuValidateAdmin() ), //Supervisor FAQ\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'FAQs' ), //Employee FAQ\n\t\t\tid: 'EmployeeFAQS',\n\t\t\tdestination: 'EmployeeFAQS',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view_no_close'\n\t\t\t},\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: ( !PermissionManager.HelpMenuValidateSupervisor() && !PermissionManager.HelpMenuValidateAdmin() ), //Employee FAQ\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Chat w/Support' ),\n\t\t\tid: 'LiveChat',\n\t\t\tdestination: 'LiveChat',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view_no_close'\n\t\t\t},\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: ( ( PermissionManager.HelpMenuValidateAdmin() || PermissionManager.HelpMenuValidateSupervisor() ) && Global.getFeatureFlag( 'support_chat' ) == true && APIGlobal.pre_login_data.demo_mode === false && Global.getProductEdition() >= 15 ),\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: ( Global.getProductEdition() >= 15 ) ? MenuManager_$.i18n._( 'Email Support' ) : MenuManager_$.i18n._( 'Community Forums' ),\n\t\t\tid: 'EmailHelp',\n\t\t\tdestination: 'EmailHelp',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view_no_close'\n\t\t\t},\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: ( ( PermissionManager.HelpMenuValidateAdmin() || PermissionManager.HelpMenuValidateSupervisor() ) && ( Global.getProductEdition() == 10 || APIGlobal.pre_login_data.support_email != '' ) ),\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Screen Share Download' ),\n\t\t\tid: 'ScreenSharing',\n\t\t\tdestination: 'ScreenSharing',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view_no_close'\n\t\t\t},\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: ( ( PermissionManager.HelpMenuValidateAdmin() || PermissionManager.HelpMenuValidateSupervisor() ) && Global.getFeatureFlag( 'support_chat' ) == true && APIGlobal.pre_login_data.demo_mode === false && Global.getProductEdition() >= 15 ),\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Testing Sandbox' ),\n\t\t\tid: 'Sandbox',\n\t\t\tdestination: 'Sandbox',\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: ( PermissionManager.HelpMenuValidateAdmin() && Global.getProductEdition() >= 15 && APIGlobal.pre_login_data['sandbox_url'] && APIGlobal.pre_login_data['sandbox_url'] != false && APIGlobal.pre_login_data['sandbox_url'].length > 0 && !APIGlobal.pre_login_data['sandbox'] ),\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'What\\'s New' ),\n\t\t\tid: 'WhatsNew',\n\t\t\tdestination: 'WhatsNew',\n\t\t\ttt_link: {\n\t\t\t\ttype: 'view_no_close'\n\t\t\t},\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: ( PermissionManager.HelpMenuValidateAdmin() || PermissionManager.HelpMenuValidateSupervisor() ),\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'About' ),\n\t\t\tid: 'About',\n\t\t\tdestination: 'About',\n\t\t\tparent_id: 'help_menu',\n\t\t\tsub_group_id: 'help_group',\n\t\t\tpermission_result: PermissionManager.HelpMenuValidateAdmin(),\n\t\t\thide_in_main_menu: true,\n\t\t} );\n\n\t\t//UI Tests\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'UIKit Sample' ),\n\t\t\tid: 'ui_kit',\n\t\t\ticon: 'tticon tticon-verified_black_24dp',\n\t\t\tpermission_result: APIGlobal.pre_login_data && APIGlobal.pre_login_data.production == false && Global.UNIT_TEST_MODE == true\n\t\t} );\n\n\t\tthis.addItem( {\n\t\t\tlabel: MenuManager_$.i18n._( 'Sample List' ),\n\t\t\tid: 'sample_list',\n\t\t\tdestination: 'UIKitSample',\n\t\t\tparent_id: 'ui_kit',\n\t\t\tsub_group_id: 'ui_kit',\n\t\t\tpermission_result: true, //Will not show unless parent is shown.\n\t\t} );\n\n\t\t// Once all menu items added to this.menu_items in raw format, then convert to PrimeVue format.\n\t\tthis.convertMenuItemsToPrimeVueFormat();\n\n\t\t// Once menu data is generated, update the profile menu with the items for the 'My Account' sub menu.\n\t\tthis.event_bus.emit( 'tt_topbar','profile_menu_data', {\n\t\t\t// Extract the my account menu data and pass it to profile menu.\n\t\t\tprofile_menu_data: this.menu_items\n\t\t\t\t.find( ( item ) => item.id === 'my_account_menu' ).items\n\t\t} );\n\n\t\t//Not all employees can view help menu, so make sure items exist before attempting to send to tttopbar.\n\t\tlet help_menu = this.menu_items.find( ( item ) => item.id === 'help_menu' );\n\t\tif ( help_menu ) {\n\t\t\tthis.event_bus.emit( 'tt_topbar', 'help_menu_data', {\n\t\t\t\t// Extract the help menu data and pass it to the topbar help icon.\n\t\t\t\thelp_menu_data: help_menu.items\n\t\t\t} );\n\t\t}\n\t}\n\n\t//TODO: Jeremy -> Temporarily put the following code here that was originally in ribbonViewController and other files.\n\t//Do we want to export a MenuManager instance? (Currently exporting)\n\t//Have these functions be static?\n\t//Have them in another file?\n\t//The functions in question are - openSelectView(), goToView(), isCurrentView(), doLogout(), setCompanyLogo().\n\n\t//Replace this switch statement with something else?\n\topenSelectView( name ) {\n\t\tvar $this = this;\n\t\tGlobal.setUINotready();\n\t\tswitch ( name ) {\n\t\t\tcase 'ImportCSV':\n\t\t\t\tIndexViewController.openWizard( 'ImportCSVWizard', null, function() {\n\t\t\t\t\t//Error: TypeError: LocalCacheData.current_open_primary_controller.search is not a function in interface/html5/framework/jquery.min.js?v=9.0.0-20151016-110437 line 2 > eval line 248\n\t\t\t\t\tif ( LocalCacheData.current_open_primary_controller && typeof LocalCacheData.current_open_primary_controller.search === 'function' ) {\n\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.search();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\tbreak;\n\t\t\tcase 'QuickStartWizard':\n\t\t\t\tif ( PermissionManager.checkTopLevelPermission( 'QuickStartWizard' ) ) {\n\t\t\t\t\tIndexViewController.openWizard( 'QuickStartWizard' );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'UserDefault':\n\t\t\t\t//Community editions can only have 1 new hire default. For those editions do not show the list view.\n\t\t\t\tif ( Global.getProductEdition() > 10 ) {\n\t\t\t\t\tdefaultCase( name );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t//Fall through to below cases.\n\t\t\tcase 'InOut':\n\t\t\tcase 'Company':\n\t\t\tcase 'LoginUserContact':\n\t\t\tcase 'LoginUserPreference':\n\t\t\tcase 'ChangePassword':\n\t\t\tcase 'InvoiceConfig':\n\t\t\tcase 'RecruitmentPortalConfig':\n\t\t\tcase 'About':\n\t\t\t\tif ( LocalCacheData.current_open_edit_only_controller && LocalCacheData.current_open_edit_only_controller.viewId == name ) { //#2557 - A - Ensure that opening edit only views on top of same edit only view just resets the edit menu\n\t\t\t\t\tLocalCacheData.current_open_edit_only_controller.setEditMenu();\n\t\t\t\t} else if ( LocalCacheData.current_open_edit_only_controller ) { //#2557 - B - Ensure that opening edit only views on top of different edit only view sets the parent to the existing edit only view\n\t\t\t\t\tIndexViewController.openEditView( LocalCacheData.current_open_edit_only_controller, name );\n\t\t\t\t} else {\n\t\t\t\t\tIndexViewController.openEditView( LocalCacheData.current_open_primary_controller, name ); //#2557 - C - Ensure that opening edit views as normal works as before\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Logout':\n\t\t\t\tthis.doLogout();\n\t\t\t\tbreak;\n\t\t\tcase 'AdminGuide':\n\t\t\t\tvar url = 'https://www.timetrex.com/h?id=admin_guide&v=' + LocalCacheData.getLoginData().application_version + '&e=' + Global.getProductEdition();\n\t\t\t\twindow.open( url, '_blank' );\n\t\t\t\tbreak;\n\t\t\tcase 'SupervisorGuide':\n\t\t\t\tvar url = 'https://www.timetrex.com/h?id=supervisor_guide&v=' + LocalCacheData.getLoginData().application_version + '&e=' + Global.getProductEdition();\n\t\t\t\twindow.open( url, '_blank' );\n\t\t\t\tbreak;\n\t\t\tcase 'EmployeeGuide':\n\t\t\t\tvar url = 'https://www.timetrex.com/h?id=employee_guide&v=' + LocalCacheData.getLoginData().application_version + '&e=' + Global.getProductEdition();\n\t\t\t\twindow.open( url, '_blank' );\n\t\t\t\tbreak;\n\t\t\tcase 'AdminFAQS':\n\t\t\t\turl = 'https://www.timetrex.com/h?id=admin_faq&v=' + LocalCacheData.getLoginData().application_version + '&e=' + Global.getProductEdition();\n\t\t\t\twindow.open( url, '_blank' );\n\t\t\t\tbreak;\n\t\t\tcase 'SupervisorFAQS':\n\t\t\t\turl = 'https://www.timetrex.com/h?id=supervisor_faq&v=' + LocalCacheData.getLoginData().application_version + '&e=' + Global.getProductEdition();\n\t\t\t\twindow.open( url, '_blank' );\n\t\t\t\tbreak;\n\t\t\tcase 'EmployeeFAQS':\n\t\t\t\turl = 'https://www.timetrex.com/h?id=employee_faq&v=' + LocalCacheData.getLoginData().application_version + '&e=' + Global.getProductEdition();\n\t\t\t\twindow.open( url, '_blank' );\n\t\t\t\tbreak;\n\t\t\tcase 'WhatsNew':\n\t\t\t\turl = 'https://www.timetrex.com/h?id=changelog&v=' + LocalCacheData.getLoginData().application_version + '&e=' + Global.getProductEdition();\n\t\t\t\twindow.open( url, '_blank' );\n\t\t\t\tbreak;\n\t\t\tcase 'EmailHelp':\n\t\t\t\tif ( Global.getProductEdition() >= 15 ) {\n\t\t\t\t\tlocation.href = 'mailto:' + APIGlobal.pre_login_data.support_email + '?subject=Company: ' + LocalCacheData.getCurrentCompany().name + '&body=Company: ' + LocalCacheData.getCurrentCompany().name + ' ' + 'Registration Key: ' + LocalCacheData.getLoginData().registration_key;\n\t\t\t\t} else {\n\t\t\t\t\turl = 'https://www.timetrex.com/r?id=29';\n\t\t\t\t\twindow.open( url, '_blank' );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'LiveChat':\n\t\t\t\tif ( APIGlobal.pre_login_data.demo_mode === false && Global.getProductEdition() >= 15 ) {\n\t\t\t\t\tvar current_user = LocalCacheData.getLoginUser();\n\t\t\t\t\tIndexViewController.testInternetConnection();\n\t\t\t\t\tif ( PermissionManager.getPermissionLevel() > 40 ) { //40=Supervisor (Subordinates Only)\n\t\t\t\t\t\tvar check_connection_timer = setInterval( function() {\n\t\t\t\t\t\t\tif ( !is_testing_internet_connection ) {\n\t\t\t\t\t\t\t\tclearInterval( check_connection_timer );\n\t\t\t\t\t\t\t\tif ( internet_connection_available && current_user ) {\n\t\t\t\t\t\t\t\t\t__webpack_require__.e(/* import() | live-chat */ \"live-chat\").then(__webpack_require__.bind(__webpack_require__, 155))\n\t\t\t\t\t\t\t\t\t.then(function( module ) {\n\t\t\t\t\t\t\t\t\t\twindow.LHCChatOptions = module.LHCChatOptions;\n\t\t\t\t\t\t\t\t\t\twindow.openSupportChat = module.openSupportChat;\n\t\t\t\t\t\t\t\t\t\twindow.openSupportChat();\n\t\t\t\t\t\t\t\t\t} ).catch( Global.importErrorHandler );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tTAlertManager.showAlert( MenuManager_$.i18n._( 'No internet connection found. Cannot use live chat support.' ), MenuManager_$.i18n._( 'Live Chat Support' ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 500 );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ScreenSharing':\n\t\t\t\turl = 'https://www.timetrex.com/r.php?id=quicksupport&v=' + LocalCacheData.getLoginData().application_version + '&e=' + Global.getProductEdition();\n\t\t\t\twindow.open( url, '_blank' );\n\t\t\t\tbreak;\n\t\t\tcase 'Sandbox':\n\t\t\t\tif ( APIGlobal.pre_login_data['sandbox_url'] && APIGlobal.pre_login_data['sandbox_url'].length > 0 ) {\n\t\t\t\t\tvar user = LocalCacheData.getLoginUser();\n\t\t\t\t\tGlobal.NewSession( user.user_name, 'SANDBOX', true );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'ProcessPayrollWizard':\n\t\t\t\tIndexViewController.openWizard( 'ProcessPayrollWizard', null, function() {\n\t\t\t\t\t//Error: TypeError: LocalCacheData.current_open_primary_controller.search is not a function in interface/html5/framework/jquery.min.js?v=9.0.0-20151016-110437 line 2 > eval line 248\n\t\t\t\t\tif ( LocalCacheData.current_open_primary_controller && typeof LocalCacheData.current_open_primary_controller.search === 'function' ) {\n\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.search();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\tbreak;\n\t\t\tcase 'PayrollRemittanceAgencyEventWizardController':\n\t\t\t\tIndexViewController.openWizardController( 'PayrollRemittanceAgencyEventWizardController', null, function() {\n\t\t\t\t\t//Error: TypeError: LocalCacheData.current_open_primary_controller.search is not a function in interface/html5/framework/jquery.min.js?v=9.0.0-20151016-110437 line 2 > eval line 248\n\t\t\t\t\tif ( LocalCacheData.current_open_primary_controller && typeof LocalCacheData.current_open_primary_controller.search === 'function' ) {\n\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.search();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\tbreak;\n\t\t\tcase 'ProcessTransactionsWizard':\n\t\t\t\tIndexViewController.openWizardController( 'ProcessTransactionsWizard', null, function() {\n\t\t\t\t\t//Error: TypeError: LocalCacheData.current_open_primary_controller.search is not a function in interface/html5/framework/jquery.min.js?v=9.0.0-20151016-110437 line 2 > eval line 248\n\t\t\t\t\tif ( LocalCacheData.current_open_primary_controller && typeof LocalCacheData.current_open_primary_controller.search === 'function' ) {\n\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.search();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\tbreak;\n\t\t\tcase 'LegalEntity':\n\t\t\t\tif ( Global.getProductEdition() >= 15 ) {\n\t\t\t\t\tdefaultCase( name );\n\t\t\t\t} else {\n\t\t\t\t\tIndexViewController.openEditView( LocalCacheData.current_open_primary_controller, name, false );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tdefaultCase( name );\n\t\t\t\tbreak;\n\t\t}\n\n\t\t//To mitigate duplicate code the default case has been made into it's own function.\n\t\t//Some cases have multiple pathways. Such as a view that uses a list view or an edit only view.\n\t\tfunction defaultCase( name ) {\n\t\t\t//#2557 - When opening a view from the submenus, ensure that similarily named edit only views are cancelled (with confirm) first.\n\t\t\tif ( LocalCacheData.current_open_edit_only_controller && LocalCacheData.current_open_edit_only_controller.viewId == name ) {\n\t\t\t\tLocalCacheData.current_open_edit_only_controller.onCancelClick();\n\t\t\t\tTTPromise.wait( 'base', 'onCancelClick', function() {\n\t\t\t\t\t$this.goToView( name );\n\t\t\t\t}.bind( $this ) );\n\t\t\t} else {\n\t\t\t\t$this.goToView( name );\n\t\t\t}\n\t\t}\n\t}\n\n\tgoToView( subMenuId, force_refresh ) {\n\t\tif ( this.isCurrentView( subMenuId ) && force_refresh ) {\n\t\t\tIndexViewController.instance.router.reloadView( subMenuId );\n\t\t} else {\n\t\t\tdeleteCookie( 'OverrideUserPreference' ); //TimeSheet view has ability to override user preferences for using the employees timezone, make sure we clear this everytime we go to another view.\n\n\t\t\t//#2157 - needed for selenium screenshot test to prevent hanging on\n\t\t\t//various combinations of ribbon and topmenu clicks that are not a change to the hash\n\t\t\t// Check that we aren't trying to redirect back to the login screen, causing an infinite loop on logout in some cases.\n\t\t\tif ( subMenuId != 'Login' && location.hash == ( '#!m=' + subMenuId ) ) {\n\t\t\t\tTTPromise.wait();\n\t\t\t\t//TODO: Replace this jQuery selector.\n\t\t\t\tMenuManager_$( '#refreshBtn:visible' ).click();\n\t\t\t}\n\t\t\tGlobal.setURLToBrowser( Global.getBaseURL() + '#!m=' + subMenuId );\n\t\t}\n\t}\n\n\tisCurrentView( subMenuId ) {\n\t\tvar sub_menu_id_url = Global.getBaseURL() + '#!m=' + subMenuId;\n\t\tDebug.Text( 'URL: Current: ' + window.location.href + ' Switching To: ' + sub_menu_id_url, 'MenuManager.js', 'MenuManager', 'isCurrentView', 10 );\n\n\t\t//window.location.href.indexOf( sub_menu_id_url ) == 0 doesn't work here, as .../html5/#!m=PayStub matches when on .../html5/#!m=PayStubTransaction view.\n\t\t//So instead use a RegEx to match the end of the string, or a & in case there are more URL arguments.\n\t\tvar regex_pattern = sub_menu_id_url.replace( /[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&' ) + '(&.*)?$'; //replace() escapes the URL chars.\n\n\t\tif ( window.location.href.match( regex_pattern ) !== null ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tdoLogout() {\n\t\tthis.event_bus.emit( 'app_menu', 'set_active_index', {\n\t\t\tindex: null\n\t\t} );\n\n\t\t//Don't wait for result of logout in case of slow or disconnected internet. Just clear local cookies and move on.\n\t\tvar current_user_api = TTAPI.APIAuthentication;\n\t\tif ( typeof current_user_api.Logout !== 'undefined' ) { //Fix JS exception: Uncaught TypeError: current_user_api.Logout is not a function -- Which can occur when offline and clicking Logout.\n\t\t\tcurrent_user_api.Logout( {\n\t\t\t\tonResult() {\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tGlobal.setAnalyticDimensions();\n\n\t\t//A bare \"if\" wrapped around lh_inst doesn't work here for some reason.\n\t\tif ( typeof ( lh_inst ) != 'undefined' ) {\n\t\t\t//stop the update loop for live chat with support\n\t\t\tclearTimeout( lh_inst.timeoutStatuscheck );\n\t\t}\n\n\t\tGlobal.Logout();\n\t\tthis.goToView( 'Login' );\n\n\t\tTAlertManager.showBrowserTopBanner();\n\t}\n\n}\n\n/* harmony default export */ const main_menu_MenuManager = (new MenuManager_MenuManager());\n\n\n/**\n * A menu item in TimeTrex format. Will contain PrimeVue and TT attributes.\n * @property {string} label - Item label\n * @property {string} id - Unique menu item reference to use in automated testing.\n * @property {string} [parent_id] - ID of the parent group for the item.\n * @property {string} [sub_group_id] - legacy id of the ribbon menu groupings. Could be used to decide when a line needs to be placed between nav items.\n * @property {string} [destination] - Destination for router when link is clicked.\n * @property {boolean} [permission_result] - Decides if a user has access to this icon. Normally controlled by PermissionManager.checkTopLevelPermission()\n * @property {TTMenuLink} [tt_link] - Object containing link info.\n * @property {TTMenuItem[]} [items] - Array of further sub-menu items.\n */\nclass TTMenuItem {\n\tconstructor( options ) {\n\t\tif( options && options.destination ) {\n\t\t\t// Set default link handling logic if a destination is provided.\n\t\t\toptions.tt_link = options.tt_link || {};\n\t\t\t_.defaults( options.tt_link, {\n\t\t\t\t// destination is required, no default.\n\t\t\t\ttype: 'view', // view, wizard, report\n\t\t\t\ttarget: 'main' // main, left, right, footer, popup\n\t\t\t} );\n\t\t}\n\n\t\tObject.keys( options ).forEach( ( key ) => {\n\t\t\tthis[key] = options[key];\n\t\t} );\n\n\t\treturn this;\n\t}\n\n\tparseTTLink() {\n\t\tif( !this.destination || !this.tt_link.type || !this.tt_link.target ) {\n\t\t\tDebug.Error( 'Unable to parse TTLink without all parameters.', 'MenuManager.js', 'MenuManager', 'convertMenuItemsToPrimeVueFormat', 2 );\n\t\t\treturn false;\n\t\t}\n\n\t\tswitch ( this.tt_link.type ) {\n\t\t\tcase 'view':\n\t\t\t\tObject.assign( this, this.parseViewLink( this.destination, true ) );\n\t\t\t\tbreak;\n\t\t\tcase 'view_no_close':\n\t\t\t\t//Certain links such as \"What's New\", \"Email Support\" etc should not close edit views as they do not open new views.\n\t\t\t\t//Kept \"view\" in type name to be consistent as these types of links have always gone through \"openSelectView()\"\n\t\t\t\t//But we can rename to something else in future if we break up the \"openSelectView()\" function.\n\t\t\t\tObject.assign( this, this.parseViewLink( this.destination, false ) );\n\t\t\t\tbreak;\n\t\t\tcase 'report':\n\t\t\t\tObject.assign( this, this.parseReportLink( this.destination ) );\n\t\t\t\tbreak;\n\t\t\tdefault:\n\n\t\t}\n\t\treturn true;\n\t}\n\n/* For the different views, reference the following:\n * RibbonViewController.onSubMenuNavClick\n * RibbonViewController.setSelectSubMenu // might not need this. Is this related to just highlighting the currently clicked menu? Might be a simpler way to do it in vue.\n * RibbonViewController.openSelectView // theres lots of intricate logic here. Re-visit and check what we need here.\n *\n*/\n\n\t// Add all the various routing type parsers here.\n\tparseViewLink( destination, close_view ) {\n\t\treturn {\n\t\t\tcommand: () => {\n\t\t\t\tif ( close_view ) {\n\t\t\t\t\t//TODO: After we decide on where openSelectView() should exist. Stop using temp _main_menu variable.\n\t\t\t\t\tGlobal.closeEditViews( function() {\n\t\t\t\t\t\t_main_menu.openSelectView( destination );\n\t\t\t\t\t} );\n\t\t\t\t} else {\n\t\t\t\t\t//Certain links such as \"What's new\", \"Email Support\" etc should not close edit views as they do not open new views.\n\t\t\t\t\t_main_menu.openSelectView( destination );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\tparseReportLink( destination ) {\n\t\treturn {\n\t\t\tcommand: () => {\n\t\t\t\tGlobal.closeEditViews( function() {\n\t\t\t\t\tif ( destination === 'AffordableCareReport' && !( Global.getProductEdition() >= 15 ) ) {\n\t\t\t\t\t\tTAlertManager.showAlert( Global.getUpgradeMessage() );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar parent_view = LocalCacheData.current_open_edit_only_controller ? LocalCacheData.current_open_edit_only_controller : LocalCacheData.current_open_primary_controller;\n\t\t\t\t\t\tIndexViewController.openReport( parent_view, destination );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t};\n\t}\n\n\tparseWizardLink( destination ) {\n\t\treturn {\n\t\t\tcommand: () => {\n\t\t\t\tGlobal.closeEditViews( function() {\n\t\t\t\t\t//TODO: After we decide on where openSelectView() should exist. Stop using temp _main_menu variable.\n\t\t\t\t\t_main_menu.openSelectView( destination );\n\t\t\t\t} );\n\t\t\t}\n\t\t};\n\t}\n\n}\n\n/*\nCustom types for JSDoc\n */\n\n/**\n * A TT link object containing link info as well as TT specific attributes.\n * @typedef {Object} TTMenuLink\n * @property {string} type - view, wizard, report, popup.\n * @property {string} destination - The old-style TT hash reference for destination.\n * @property {string} target - Which Vue view container should this link open in. main, right, footer.\n */\n\n// Add the above to an actual class definition of the same. See namespace with defaults on https://jsdoc.app/tags-property.html\n\n/*\nSample Data\n\n{\n label: TTi18n::getText(‘Employee’),\n icon: null|myicon.svg,\n tt_id: 'employee', // Maybe make this ID match the destination by default? but its lowercase.\n tt_link: null|{ type: ‘wizard|report|view’, destination: ‘employee’, target: null|main|left|right|footer }\n items: [ {},{},... ]\n}\n\n*/\n\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/TTLeftContainer.vue?vue&type=script&lang=js\n\n\n\n\n\n\n/* harmony default export */ const TTLeftContainervue_type_script_lang_js = ({\n beforeCreate() {\n this.main_menu = new MenuManager_MenuManager();\n // Set a promise to wait for login to complete\n TTPromise.add( 'VueMenu', 'waitOnLoginSuccess' );\n TTPromise.add( 'VueMenu', 'waitOnTopBarCreated' );\n TTPromise.wait( 'VueMenu', null, () => {\n // We wait for login, as initDefaultMenuItems() within MenuManager needs permission data from login. If run too soon, no icons are shown, as permission_results will all return false.\n // Also needs to wait for TTTopbar to be created first so we do not run into race condition problems.\n this.main_menu.initDefaultMenuItems();\n this.menu_model = this.main_menu.getMenu(); // adding to [0] as there is a hidden top level menu in the PrimeVue menu. Can't replace whole menu as JS reference to menu object will be lost.\n } );\n },\n created() {\n this.event_bus = new TTEventBus( {\n component_id: this.component_id,\n } );\n this.event_bus.on( this.component_id, 'rebuild_menu', () => {\n this.rebuildMenu();\n } );\n this.event_bus.on( this.component_id,'reset_slim_offsets', () => {\n this.resetSlimSubmenuOffsets();\n } );\n this.event_bus.on( 'global','reset_vue_data', () => {\n // Reset the Vue data when the user logs out.\n this.resetData();\n } );\n },\n data() {\n return {\n component_id: 'tt_left_container',\n menuActive: false,\n application_name: window.APPLICATION_NAME,\n copyright_notice: APIGlobal.pre_login_data.copyright_notice,\n menu_model: [ // While we wait for login, initiatize the base menu model.\n {\n label: 'Navigation',\n items: [{ // The items array here is what we will be dynamically updating via updateMenu(). If auto update through TTPromise fails, menu can be updated using this menu option.\n label: 'Update Menu',\n icon: 'pi pi-fw pi-refresh',\n command: this.rebuildMenu\n }]\n }\n ],\n disable_feedback: APIGlobal.pre_login_data.disable_feedback\n };\n },\n props: {\n isMenuVisible: Boolean,\n layoutMode: String,\n staticMenuMobileActive: Boolean,\n },\n methods: {\n resetData() {\n Object.assign( this.$data, this.$options.data() );\n },\n rebuildMenu() {\n var items = this.main_menu.rebuildMenu();\n this.menu_model = items;\n },\n onMenuClick( event ) {\n this.$emit( 'menu-click', event );\n },\n onMenuItemClick( event ) {\n this.$emit( 'menuitem-click', event );\n //A slight delay is required before calculating if the scroll bar should be shown as the dropdown does not expand instantly.\n setTimeout( () => {\n if ( ( this.layoutMode === 'static' || this.layoutMode === 'overlay' ) && Global.isVerticalScrollBarRequired( this.$refs['layout-menu-content'] ) ) {\n this.toggleScrollBar( true );\n } else {\n this.toggleScrollBar( false );\n }\n }, 250 );\n if ( this.layoutMode === 'slim' && !event.item.parent_id ) {\n this.repositionSubMenu( event.item );\n }\n },\n onRootMenuItemClick( event ) {\n this.$emit( 'root-menuitem-click', event );\n },\n onTopbarItemClick( event ) {\n this.$emit( 'topbar-item-click', event );\n },\n onMenuContentMouseOver() {\n if ( Global.isVerticalScrollBarRequired( this.$refs['layout-menu-content'] ) ) {\n this.toggleScrollBar( true );\n } else {\n this.toggleScrollBar( false );\n }\n },\n onMenuContentMouseLeave() {\n this.toggleScrollBar( false );\n },\n toggleScrollBar( show ) {\n if ( show == true || Global.UNIT_TEST_MODE == true ) {\n this.$refs['layout-menu-content'].style.maskPosition = 'left top';\n this.$refs['layout-menu-content'].style.webkitMaskPosition = 'left top';\n } else {\n this.$refs['layout-menu-content'].style.maskPosition = 'left bottom';\n this.$refs['layout-menu-content'].style.webkitMaskPosition = 'left bottom';\n }\n },\n repositionSubMenu( menu_item ) {\n let menu = document.querySelector( '.layout-main-menu' );\n let submenu = null;\n\n //Find the dom sub menu to check if we need to reposition it.\n for ( let i = 0; i < menu.childNodes.length; i++ ) {\n if ( menu.children[i] && menu.children[i].children[1] ) {\n submenu = menu.children[i].children[1];\n submenu.style.top = '';\n submenu.style.overflowY = '';\n if ( menu.children[i].children[0].children[1].textContent === menu_item.label ) {\n //Sub menu needs to be visible to calculate dimensions and position.\n submenu.style.display = 'block';\n //Check if sub menu goes below the bottom of screen.\n if ( submenu.getBoundingClientRect().bottom > window.innerHeight ) {\n //Raise the sub menu up by the amount it is hidden. And an adjustment of 10px to make the menu mot flush with the bottom of the screen.\n submenu.style.top = '-' + ( submenu.getBoundingClientRect().bottom - ( window.innerHeight - 10 ) ) + 'px';\n }\n if ( menu_item.items.some( item => item.items ) ) {\n //If the menu has sub menus then we need to show the scroll bar and set a max height\n //so that further submenu expansion do not go off screen. (Report menu has multiple sections)\n submenu.style.maxHeight = submenu.offsetHeight + 'px';\n submenu.style.overflowY = 'scroll'; //Scroll instead of auto so that contents do not shift when expanding.\n }\n }\n }\n }\n },\n resetSlimSubmenuOffsets() {\n let menu = document.querySelector( '.layout-main-menu' );\n let submenu = null;\n\n //In slim mode we offset submenus to prevent the menu from going off screen.\n //This needs to be reset when switching from slim so that the changes do not carry over to other layout modes.\n for ( let i = 0; i < menu.childNodes.length; i++ ) {\n if ( menu.children[i] && menu.children[i].children[1] ) {\n submenu = menu.children[i].children[1];\n submenu.style.top = '';\n submenu.style.maxHeight = '';\n submenu.style.overflowY = '';\n }\n }\n }\n },\n components: {\n TTAppMenu: TTAppMenu,\n TTMenuSearch: TTMenuSearch,\n ProgressBar: progressbar_esm\n }\n});\n\n;// CONCATENATED MODULE: ./interface/html5/components/TTLeftContainer.vue?vue&type=script&lang=js\n \n;// CONCATENATED MODULE: ./interface/html5/components/TTLeftContainer.vue\n\n\n\n\n;\n\n\nconst TTLeftContainer_exports_ = /*#__PURE__*/(0,exportHelper/* default */.Z)(TTLeftContainervue_type_script_lang_js, [['render',TTLeftContainervue_type_template_id_387d95cf_render]])\n\n/* harmony default export */ const TTLeftContainer = (TTLeftContainer_exports_);\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/TTMainUI.vue?vue&type=script&lang=js\n/* provided dependency */ var TTMainUIvue_type_script_lang_js_$ = __webpack_require__(9755);\n\n// TODO: Bug: Noticed on a refresh that the main logo in top left flashes with the Apollo logo before showing the company logo.\n\n\n\n\n/* harmony default export */ const TTMainUIvue_type_script_lang_js = ({\n created() {\n this.event_bus = new TTEventBus( {\n component_id: this.component_id\n } );\n\n this.event_bus.on( 'global', 'reset_vue_data', this.resetData );\n this.event_bus.on( this.component_id, 'get_user_saved_layout_mode', this.getSavedLayoutMode );\n this.event_bus.on( this.component_id, 'toggle_ui', this.getSavedLayoutMode );\n\n TTMainUIvue_type_script_lang_js_$( window ).off( 'resize.tt_main' ).on( 'resize.tt_main', Global.debounce( function() {\n this.resizeContentLayout();\n }, 200 ).bind( this ) );\n },\n data() {\n return {\n component_id: 'tt_main_ui',\n layoutMode: 'static',\n savedLayoutId: '',\n showUI: true,\n staticMenuDesktopInactive: false,\n staticMenuMobileActive: false,\n overlayMenuActive: false,\n topbarMenuActive: false,\n activeTopbarItem: null,\n menuActive: false,\n };\n },\n methods: {\n resetData() {\n Object.assign( this.$data, this.$options.data() );\n },\n onDocumentClick() {\n if ( !this.topbarItemClick ) {\n this.activeTopbarItem = null;\n this.topbarMenuActive = false;\n }\n\n if ( !this.menuClick ) {\n if ( this.isHorizontal() || this.isSlim() ) {\n this.menuActive = false;\n this.event_bus.emit( 'app_menu', 'set_active_index', {\n index: null\n } );\n }\n\n this.hideOverlayMenu();\n }\n\n this.topbarItemClick = false;\n this.menuClick = false;\n },\n onMenuClick() {\n this.menuClick = true;\n },\n onMenuButtonClick( event ) {\n this.menuClick = true;\n this.topbarMenuActive = false;\n\n if ( this.layoutMode === 'overlay' && !this.isMobile() ) {\n this.overlayMenuActive = !this.overlayMenuActive;\n } else {\n if ( this.isDesktop() ) {\n // this.staticMenuDesktopInactive = !this.staticMenuDesktopInactive;\n //Close open menus when switching menu layout mode.\n this.event_bus.emit( 'app_menu', 'set_active_index', {\n index: null\n } );\n if ( this.layoutMode === 'slim' ) {\n //In slim mode we offset submenus to prevent the menu from going off screen.\n //This needs to be reset when switching from slim so that the changes do not carry over to layout modes.\n this.event_bus.emit( 'tt_left_container', 'reset_slim_offsets' );\n }\n // Override PrimeVue behaviour to use burger button to toggle menu between static, slim and horizontal layouts.\n this.layoutMode = this.layoutMode === 'static' ? 'slim' : this.layoutMode === 'slim' ? 'horizontal' : 'static';\n this.saveLayoutMode( this.layoutMode )\n } else {\n this.staticMenuMobileActive = !this.staticMenuMobileActive;\n }\n }\n \n this.dispatchResizeEvent();\n event.preventDefault();\n },\n onTopbarMenuButtonClick( event ) {\n this.topbarItemClick = true;\n this.topbarMenuActive = !this.topbarMenuActive;\n this.hideOverlayMenu();\n event.preventDefault();\n },\n onTopbarItemClick( event ) {\n this.topbarItemClick = true;\n\n if ( this.activeTopbarItem === event.item )\n this.activeTopbarItem = null;\n else\n this.activeTopbarItem = event.item;\n\n event.originalEvent.preventDefault();\n },\n isDesktop() {\n return window.innerWidth > 1024;\n },\n isMobile() {\n return window.innerWidth <= 640;\n },\n isHorizontal() {\n return this.layoutMode === 'horizontal';\n },\n isSlim() {\n return this.layoutMode === 'slim';\n },\n hideOverlayMenu() {\n this.overlayMenuActive = false;\n this.staticMenuMobileActive = false;\n },\n onMenuItemClick( event ) {\n if ( !event.item.items ) {\n this.event_bus.emit( this.component_id, 'reset-active-index' );\n this.hideOverlayMenu();\n } else {\n this.menuClick = true;\n }\n if ( !event.item.items && ( this.isHorizontal() || this.isSlim() ) ) {\n this.menuActive = false;\n }\n },\n onRootMenuItemClick() {\n this.menuActive = !this.menuActive;\n },\n isMenuVisible() {\n if ( this.isDesktop() ) {\n if ( this.layoutMode === 'static' ) {\n // return !this.staticMenuDesktopInactive;\n return true; // Always want to show the contents of the left menu, so that when it slides in/out, the menu doesn't just flash away, but properly slides away with the container.\n } else if ( this.layoutMode === 'overlay' )\n return this.overlayMenuActive;\n else\n return true;\n } else {\n return true;\n }\n },\n toggleConfigurator() {\n this.configuratorActive = !this.configuratorActive;\n },\n hideConfigurator() {\n this.configuratorActive = false;\n },\n onLayoutChange( layoutMode ) {\n this.layoutMode = layoutMode;\n this.dispatchResizeEvent();\n },\n resizeContentLayout() {\n //Need to resize main content area to account for height changes when horizontal bar stacks on lower widths.\n if ( this.isHorizontal() ) {\n setTimeout( () => {\n let content_container = document.querySelector( '.content-container-after-login' );\n if ( !content_container ) {\n return;\n }\n //Horizontal menu is only shown on desktop resolutions (1024px+).\n if ( this.isDesktop() ) {\n let height = window.innerHeight - document.querySelector( '.layout-menu-container ' ).getBoundingClientRect().bottom;\n content_container.style.height = height + 'px';\n } else {\n let height = window.innerHeight - document.querySelector( '.layout-topbar ' ).getBoundingClientRect().bottom;\n content_container.style.height = height + 'px';\n }\n }, 250 );\n }\n },\n dispatchResizeEvent() {\n //Trigger resize events such as dashlet resizing on homeview.\n //Delay used to trigger event after layout change to help prevent issues.\n setTimeout( () => {\n window.dispatchEvent( new Event( 'resize' ) );\n }, 250 );\n },\n saveLayoutMode( layoutMode ) {\n let args = {};\n args.script = 'global_main_menu';\n args.name = 'settings';\n args.is_default = false;\n args.data = {};\n args.data.layout_mode = layoutMode;\n\n if ( this.savedLayoutId ) { //If we have a saved layout id, then the api call is an update and not a create.\n args.id = this.savedLayoutId;\n }\n\n TTAPI.APIUserGenericData.setUserGenericData( args, {\n onResult: function( res ) {\n if ( !res.isValid() ) {\n Debug.Error( 'Error: Saving user layout mode selectiin failed', 'TTMainUI.vue', 'TTMainUI', 'saveLayoutMode', 10 );\n }\n }\n } );\n\n this.resizeContentLayout();\n },\n getSavedLayoutMode() {\n let $this = this;\n let filter_data = {};\n filter_data.script = 'global_main_menu';\n filter_data.name = 'settings';\n filter_data.deleted = false;\n\n TTAPI.APIUserGenericData.getUserGenericData( { filter_data: filter_data }, {\n onResult: function( results ) {\n var result_data = results.getResult();\n if ( result_data && result_data.length > 0 ) {\n if ( result_data[0].data.layout_mode ) {\n $this.layoutMode = result_data[0].data.layout_mode;\n $this.savedLayoutId = result_data[0].id;\n }\n }\n\n //Do not show main ui until user layout mode selection retrieved. Otherwise page contents would briefly\n //shift around going from default width of the static menu to the other layout modes.\n $this.toggleUI( true );\n $this.resizeContentLayout();\n }\n } );\n },\n toggleUI( show ) {\n this.showUI = show\n },\n },\n computed: {\n containerClass() {\n return ['layout-wrapper', {\n 'layout-horizontal': this.layoutMode === 'horizontal',\n 'layout-overlay': this.layoutMode === 'overlay',\n 'layout-static': this.layoutMode === 'static',\n 'layout-slim': this.layoutMode === 'slim',\n 'layout-static-inactive': this.staticMenuDesktopInactive,\n 'layout-mobile-active': this.staticMenuMobileActive,\n 'layout-overlay-active': this.overlayMenuActive,\n 'p-input-filled': this.$primevue.config.inputStyle === 'filled',\n 'p-ripple-disabled': this.$primevue.config.ripple === false\n }];\n }\n },\n components: {\n TTTopContainer: TTTopContainer,\n TTLeftContainer: TTLeftContainer\n }\n});\n\n;// CONCATENATED MODULE: ./interface/html5/components/TTMainUI.vue?vue&type=script&lang=js\n \n;// CONCATENATED MODULE: ./interface/html5/components/TTMainUI.vue\n\n\n\n\n;\n\n\nconst TTMainUI_exports_ = /*#__PURE__*/(0,exportHelper/* default */.Z)(TTMainUIvue_type_script_lang_js, [['render',render]])\n\n/* harmony default export */ const TTMainUI = (TTMainUI_exports_);\n// EXTERNAL MODULE: ./node_modules/primevue/config/config.esm.js\nvar config_esm = __webpack_require__(5475);\n;// CONCATENATED MODULE: ./node_modules/primevue/tooltip/tooltip.esm.js\n\n\nfunction bindEvents(el) {\n const modifiers = el.$_ptooltipModifiers;\n if (modifiers.focus) {\n el.addEventListener('focus', onFocus);\n el.addEventListener('blur', onBlur);\n }\n else {\n el.addEventListener('mouseenter', onMouseEnter);\n el.addEventListener('mouseleave', onMouseLeave);\n el.addEventListener('click', onClick);\n }\n}\n\nfunction unbindEvents(el) {\n const modifiers = el.$_ptooltipModifiers;\n if (modifiers.focus) {\n el.removeEventListener('focus', onFocus);\n el.removeEventListener('blur', onBlur);\n }\n else {\n el.removeEventListener('mouseenter', onMouseEnter);\n el.removeEventListener('mouseleave', onMouseLeave);\n el.removeEventListener('click', onClick);\n }\n}\n\nfunction bindScrollListener(el) {\n if (!el.$_ptooltipScrollHandler) {\n el.$_ptooltipScrollHandler = new utils_esm/* ConnectedOverlayScrollHandler */.Vr(el, function() {\n hide(el);\n });\n }\n\n el.$_ptooltipScrollHandler.bindScrollListener();\n}\n\nfunction unbindScrollListener(el) {\n if (el.$_ptooltipScrollHandler) {\n el.$_ptooltipScrollHandler.unbindScrollListener();\n }\n}\n\nfunction onMouseEnter(event) {\n show(event.currentTarget);\n}\n\nfunction onMouseLeave(event) {\n hide(event.currentTarget);\n}\n\nfunction onFocus(event) {\n show(event.currentTarget);\n}\n\nfunction onBlur(event) {\n hide(event.currentTarget);\n}\n\nfunction onClick(event) {\n hide(event.currentTarget);\n}\n\nfunction show(el) {\n if (el.$_ptooltipDisabled) {\n return;\n }\n\n let tooltipElement = create(el);\n align(el);\n utils_esm/* DomHandler.fadeIn */.p7.fadeIn(tooltipElement, 250);\n\n window.addEventListener('resize', function onWindowResize() {\n if (!utils_esm/* DomHandler.isAndroid */.p7.isAndroid()) {\n hide(el);\n }\n this.removeEventListener('resize', onWindowResize);\n });\n\n bindScrollListener(el);\n utils_esm/* ZIndexUtils.set */.P9.set('tooltip', tooltipElement, el.$_ptooltipZIndex);\n}\n\nfunction hide(el) {\n remove(el);\n unbindScrollListener(el);\n utils_esm/* ZIndexUtils.clear */.P9.clear(el);\n}\n\nfunction getTooltipElement(el) {\n return document.getElementById(el.$_ptooltipId);\n}\n\nfunction create(el) {\n const id = (0,utils_esm/* UniqueComponentId */.Th)() + '_tooltip';\n el.$_ptooltipId = id;\n\n let container = document.createElement('div');\n container.id = id;\n\n let tooltipArrow = document.createElement('div');\n tooltipArrow.className = 'p-tooltip-arrow';\n container.appendChild(tooltipArrow);\n\n let tooltipText = document.createElement('div');\n tooltipText.className = 'p-tooltip-text';\n tooltipText.innerHTML = el.$_ptooltipValue;\n\n container.appendChild(tooltipText);\n document.body.appendChild(container);\n\n container.style.display = 'inline-block';\n\n return container;\n}\n\nfunction remove(el) {\n if (el) {\n let tooltipElement = getTooltipElement(el);\n if (tooltipElement && tooltipElement.parentElement) {\n document.body.removeChild(tooltipElement);\n }\n el.$_ptooltipId = null;\n }\n}\n\nfunction align(el) {\n const modifiers = el.$_ptooltipModifiers;\n\n if (modifiers.top) {\n alignTop(el);\n if (isOutOfBounds(el)) {\n alignBottom(el);\n }\n }\n else if (modifiers.left) {\n alignLeft(el);\n if (isOutOfBounds(el)) {\n alignRight(el);\n\n if (isOutOfBounds(el)) {\n alignTop(el);\n\n if (isOutOfBounds(el)) {\n alignBottom(el);\n }\n }\n }\n }\n else if (modifiers.bottom) {\n alignBottom(el);\n if (isOutOfBounds(el)) {\n alignTop(el);\n }\n }\n else {\n alignRight(el);\n if (isOutOfBounds(el)) {\n alignLeft(el);\n\n if (isOutOfBounds(el)) {\n alignTop(el);\n\n if (isOutOfBounds(el)) {\n alignBottom(el);\n }\n }\n }\n }\n}\n\nfunction getHostOffset(el) {\n let offset = el.getBoundingClientRect();\n let targetLeft = offset.left + utils_esm/* DomHandler.getWindowScrollLeft */.p7.getWindowScrollLeft();\n let targetTop = offset.top + utils_esm/* DomHandler.getWindowScrollTop */.p7.getWindowScrollTop();\n\n return {left: targetLeft, top: targetTop};\n}\n\nfunction alignRight(el) {\n preAlign(el, 'right');\n let tooltipElement = getTooltipElement(el);\n let hostOffset = getHostOffset(el);\n let left = hostOffset.left + utils_esm/* DomHandler.getOuterWidth */.p7.getOuterWidth(el);\n let top = hostOffset.top + (utils_esm/* DomHandler.getOuterHeight */.p7.getOuterHeight(el) - utils_esm/* DomHandler.getOuterHeight */.p7.getOuterHeight(tooltipElement)) / 2;\n tooltipElement.style.left = left + 'px';\n tooltipElement.style.top = top + 'px';\n}\n\nfunction alignLeft(el) {\n preAlign(el, 'left');\n let tooltipElement = getTooltipElement(el);\n let hostOffset = getHostOffset(el);\n let left = hostOffset.left - utils_esm/* DomHandler.getOuterWidth */.p7.getOuterWidth(tooltipElement);\n let top = hostOffset.top + (utils_esm/* DomHandler.getOuterHeight */.p7.getOuterHeight(el) - utils_esm/* DomHandler.getOuterHeight */.p7.getOuterHeight(tooltipElement)) / 2;\n tooltipElement.style.left = left + 'px';\n tooltipElement.style.top = top + 'px';\n}\n\nfunction alignTop(el) {\n preAlign(el, 'top');\n let tooltipElement = getTooltipElement(el);\n let hostOffset = getHostOffset(el);\n let left = hostOffset.left + (utils_esm/* DomHandler.getOuterWidth */.p7.getOuterWidth(el) - utils_esm/* DomHandler.getOuterWidth */.p7.getOuterWidth(tooltipElement)) / 2;\n let top = hostOffset.top - utils_esm/* DomHandler.getOuterHeight */.p7.getOuterHeight(tooltipElement);\n tooltipElement.style.left = left + 'px';\n tooltipElement.style.top = top + 'px';\n}\n\nfunction alignBottom(el) {\n preAlign(el, 'bottom');\n let tooltipElement = getTooltipElement(el);\n let hostOffset = getHostOffset(el);\n let left = hostOffset.left + (utils_esm/* DomHandler.getOuterWidth */.p7.getOuterWidth(el) - utils_esm/* DomHandler.getOuterWidth */.p7.getOuterWidth(tooltipElement)) / 2;\n let top = hostOffset.top + utils_esm/* DomHandler.getOuterHeight */.p7.getOuterHeight(el);\n tooltipElement.style.left = left + 'px';\n tooltipElement.style.top = top + 'px';\n}\n\nfunction preAlign(el, position) {\n let tooltipElement = getTooltipElement(el);\n tooltipElement.style.left = -999 + 'px';\n tooltipElement.style.top = -999 + 'px';\n tooltipElement.className = `p-tooltip p-component p-tooltip-${position} ${el.$_ptooltipClass||''}`;\n}\n\nfunction isOutOfBounds(el) {\n let tooltipElement = getTooltipElement(el);\n let offset = tooltipElement.getBoundingClientRect();\n let targetTop = offset.top;\n let targetLeft = offset.left;\n let width = utils_esm/* DomHandler.getOuterWidth */.p7.getOuterWidth(tooltipElement);\n let height = utils_esm/* DomHandler.getOuterHeight */.p7.getOuterHeight(tooltipElement);\n let viewport = utils_esm/* DomHandler.getViewport */.p7.getViewport();\n\n return (targetLeft + width > viewport.width) || (targetLeft < 0) || (targetTop < 0) || (targetTop + height > viewport.height);\n}\n\nfunction getTarget(el) {\n return utils_esm/* DomHandler.hasClass */.p7.hasClass(el, 'p-inputwrapper') ? utils_esm/* DomHandler.findSingle */.p7.findSingle(el, 'input'): el;\n}\n\nfunction getModifiers(options) {\n // modifiers\n if (options.modifiers && Object.keys(options.modifiers).length) {\n return options.modifiers;\n }\n\n // arg\n if (options.arg && typeof options.arg === 'object') {\n return Object.entries(options.arg).reduce((acc, [key, val]) => {\n if (key === 'event' || key === 'position') acc[val] = true;\n return acc;\n }, {});\n }\n\n return {};\n}\n\nconst Tooltip = {\n beforeMount(el, options) {\n let target = getTarget(el);\n target.$_ptooltipModifiers = getModifiers(options);\n\n if (!options.value) return;\n else if (typeof options.value === 'string') {\n target.$_ptooltipValue = options.value;\n target.$_ptooltipDisabled = false;\n target.$_ptooltipClass = null;\n }\n else {\n target.$_ptooltipValue = options.value.value;\n target.$_ptooltipDisabled = options.value.disabled || false;\n target.$_ptooltipClass = options.value.class;\n }\n\n target.$_ptooltipZIndex = options.instance.$primevue && options.instance.$primevue.config && options.instance.$primevue.config.zIndex.tooltip;\n bindEvents(target);\n },\n unmounted(el) {\n let target = getTarget(el);\n remove(target);\n unbindEvents(target);\n\n if (target.$_ptooltipScrollHandler) {\n target.$_ptooltipScrollHandler.destroy();\n target.$_ptooltipScrollHandler = null;\n }\n\n utils_esm/* ZIndexUtils.clear */.P9.clear(el);\n },\n updated(el, options) {\n let target = getTarget(el);\n target.$_ptooltipModifiers = getModifiers(options);\n\n if (!options.value) return;\n if (typeof options.value === 'string') {\n target.$_ptooltipValue = options.value;\n target.$_ptooltipDisabled = false;\n target.$_ptooltipClass = null;\n }\n else {\n target.$_ptooltipValue = options.value.value;\n target.$_ptooltipDisabled = options.value.disabled || false;\n target.$_ptooltipClass = options.value.class;\n }\n }\n};\n\n/* harmony default export */ const tooltip_esm = (Tooltip);\n\n;// CONCATENATED MODULE: ./node_modules/primevue/toasteventbus/toasteventbus.esm.js\n\n\nvar ToastEventBus = (0,utils_esm/* EventBus */.Nd)();\n\n/* harmony default export */ const toasteventbus_esm = (ToastEventBus);\n\n;// CONCATENATED MODULE: ./node_modules/primevue/toast/toast.esm.js\n\n\n\n\n\nvar script$1 = {\n name: 'ToastMessage',\n emits: ['close'],\n props: {\n message: null,\n template: null\n },\n closeTimeout: null,\n mounted() {\n if (this.message.life) {\n this.closeTimeout = setTimeout(() => {\n this.close();\n }, this.message.life);\n }\n },\n beforeUnmount() {\n this.clearCloseTimeout();\n },\n methods: {\n close() {\n this.$emit('close', this.message);\n },\n onCloseClick() {\n this.clearCloseTimeout();\n this.close();\n },\n clearCloseTimeout() {\n if (this.closeTimeout) {\n clearTimeout(this.closeTimeout);\n this.closeTimeout = null;\n }\n }\n },\n computed: {\n containerClass() {\n return ['p-toast-message', this.message.styleClass, {\n 'p-toast-message-info': this.message.severity === 'info',\n 'p-toast-message-warn': this.message.severity === 'warn',\n 'p-toast-message-error': this.message.severity === 'error',\n 'p-toast-message-success': this.message.severity === 'success'\n }];\n },\n iconClass() {\n return ['p-toast-message-icon pi', {\n 'pi-info-circle': this.message.severity === 'info',\n 'pi-exclamation-triangle': this.message.severity === 'warn',\n 'pi-times': this.message.severity === 'error',\n 'pi-check': this.message.severity === 'success'\n }];\n }\n },\n directives: {\n 'ripple': ripple_esm/* default */.Z\n }\n};\n\nconst toast_esm_hoisted_1 = { class: \"p-toast-message-text\" };\nconst toast_esm_hoisted_2 = { class: \"p-toast-summary\" };\nconst toast_esm_hoisted_3 = { class: \"p-toast-detail\" };\nconst toast_esm_hoisted_4 = /*#__PURE__*/(0,vue_esm_bundler/* createVNode */.Wm)(\"span\", { class: \"p-toast-icon-close-icon pi pi-times\" }, null, -1);\n\nfunction render$1(_ctx, _cache, $props, $setup, $data, $options) {\n const _directive_ripple = (0,vue_esm_bundler/* resolveDirective */.Q2)(\"ripple\");\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"div\", {\n class: $options.containerClass,\n role: \"alert\",\n \"aria-live\": \"assertive\",\n \"aria-atomic\": \"true\"\n }, [\n (0,vue_esm_bundler/* createVNode */.Wm)(\"div\", {\n class: [\"p-toast-message-content\", $props.message.contentStyleClass]\n }, [\n (!$props.template)\n ? ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Fragment */.HY, { key: 0 }, [\n (0,vue_esm_bundler/* createVNode */.Wm)(\"span\", { class: $options.iconClass }, null, 2),\n (0,vue_esm_bundler/* createVNode */.Wm)(\"div\", toast_esm_hoisted_1, [\n (0,vue_esm_bundler/* createVNode */.Wm)(\"span\", toast_esm_hoisted_2, (0,vue_esm_bundler/* toDisplayString */.zw)($props.message.summary), 1),\n (0,vue_esm_bundler/* createVNode */.Wm)(\"div\", toast_esm_hoisted_3, (0,vue_esm_bundler/* toDisplayString */.zw)($props.message.detail), 1)\n ])\n ], 64))\n : ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)((0,vue_esm_bundler/* resolveDynamicComponent */.LL)($props.template), {\n key: 1,\n message: $props.message\n }, null, 8, [\"message\"])),\n ($props.message.closable !== false)\n ? (0,vue_esm_bundler/* withDirectives */.wy)(((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(\"button\", {\n key: 2,\n class: \"p-toast-icon-close p-link\",\n onClick: _cache[1] || (_cache[1] = (...args) => ($options.onCloseClick && $options.onCloseClick(...args))),\n type: \"button\"\n }, [\n toast_esm_hoisted_4\n ], 512)), [\n [_directive_ripple]\n ])\n : (0,vue_esm_bundler/* createCommentVNode */.kq)(\"\", true)\n ], 2)\n ], 2))\n}\n\nscript$1.render = render$1;\n\nvar messageIdx = 0;\n\nvar toast_esm_script = {\n name: 'Toast',\n inheritAttrs: false,\n props: {\n group: {\n type: String,\n default: null\n },\n position: {\n type: String,\n default: 'top-right'\n },\n autoZIndex: {\n type: Boolean,\n default: true\n },\n baseZIndex: {\n type: Number,\n default: 0\n },\n breakpoints: {\n type: Object,\n default: null\n }\n },\n data() {\n return {\n messages: []\n }\n },\n styleElement: null,\n mounted() {\n toasteventbus_esm.on('add', this.onAdd);\n toasteventbus_esm.on('remove-group', this.onRemoveGroup);\n toasteventbus_esm.on('remove-all-groups', this.onRemoveAllGroups);\n\n if (this.breakpoints) {\n this.createStyle();\n }\n },\n beforeUnmount() {\n this.destroyStyle();\n\n if (this.$refs.container && this.autoZIndex) {\n utils_esm/* ZIndexUtils.clear */.P9.clear(this.$refs.container);\n }\n\n toasteventbus_esm.off('add', this.onAdd);\n toasteventbus_esm.off('remove-group', this.onRemoveGroup);\n toasteventbus_esm.off('remove-all-groups', this.onRemoveAllGroups);\n },\n methods: {\n add(message) {\n if (message.id == null) {\n message.id = messageIdx++;\n }\n\n this.messages = [...this.messages, message];\n },\n remove(message) {\n let index = -1;\n for (let i = 0; i < this.messages.length; i++) {\n if (this.messages[i] === message) {\n index = i;\n break;\n }\n }\n\n this.messages.splice(index, 1);\n },\n onAdd(message) {\n if (this.group == message.group) {\n this.add(message);\n }\n },\n onRemoveGroup(group) {\n if (this.group === group) {\n this.messages = [];\n }\n },\n onRemoveAllGroups() {\n this.messages = [];\n },\n onEnter() {\n this.$refs.container.setAttribute(this.attributeSelector, '');\n\n if (this.autoZIndex) {\n utils_esm/* ZIndexUtils.set */.P9.set('modal', this.$refs.container, this.baseZIndex || this.$primevue.config.zIndex.modal);\n }\n },\n onLeave() {\n if (this.$refs.container && this.autoZIndex) {\n utils_esm/* ZIndexUtils.clear */.P9.clear(this.$refs.container);\n }\n },\n createStyle() {\n if (!this.styleElement) {\n this.styleElement = document.createElement('style');\n this.styleElement.type = 'text/css';\n document.head.appendChild(this.styleElement);\n\n let innerHTML = '';\n for (let breakpoint in this.breakpoints) {\n let breakpointStyle = '';\n for (let styleProp in this.breakpoints[breakpoint]) {\n breakpointStyle += styleProp + ':' + this.breakpoints[breakpoint][styleProp] + '!important;';\n }\n innerHTML += `\n @media screen and (max-width: ${breakpoint}) {\n .p-toast[${this.attributeSelector}] {\n ${breakpointStyle}\n }\n }\n `;\n }\n\n this.styleElement.innerHTML = innerHTML;\n }\n },\n destroyStyle() {\n if (this.styleElement) {\n document.head.removeChild(this.styleElement);\n this.styleElement = null;\n }\n }\n },\n components: {\n 'ToastMessage': script$1\n },\n computed: {\n containerClass() {\n return ['p-toast p-component p-toast-' + this.position, {\n 'p-input-filled': this.$primevue.config.inputStyle === 'filled',\n 'p-ripple-disabled': this.$primevue.config.ripple === false\n }];\n },\n attributeSelector() {\n return (0,utils_esm/* UniqueComponentId */.Th)();\n }\n }\n};\n\nfunction toast_esm_render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_ToastMessage = (0,vue_esm_bundler/* resolveComponent */.up)(\"ToastMessage\");\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Teleport */.lR, { to: \"body\" }, [\n (0,vue_esm_bundler/* createVNode */.Wm)(\"div\", (0,vue_esm_bundler/* mergeProps */.dG)({\n ref: \"container\",\n class: $options.containerClass\n }, _ctx.$attrs), [\n (0,vue_esm_bundler/* createVNode */.Wm)(vue_esm_bundler/* TransitionGroup */.W3, {\n name: \"p-toast-message\",\n tag: \"div\",\n onEnter: $options.onEnter,\n onLeave: $options.onLeave\n }, {\n default: (0,vue_esm_bundler/* withCtx */.w5)(() => [\n ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createBlock */.j4)(vue_esm_bundler/* Fragment */.HY, null, (0,vue_esm_bundler/* renderList */.Ko)($data.messages, (msg) => {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(_component_ToastMessage, {\n key: msg.id,\n message: msg,\n onClose: _cache[1] || (_cache[1] = $event => ($options.remove($event))),\n template: _ctx.$slots.message\n }, null, 8, [\"message\", \"template\"]))\n }), 128))\n ]),\n _: 1\n }, 8, [\"onEnter\", \"onLeave\"])\n ], 16)\n ]))\n}\n\nfunction toast_esm_styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar toast_esm_css_248z = \"\\n.p-toast {\\n position: fixed;\\n width: 25rem;\\n}\\n.p-toast-message-content {\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n -webkit-box-align: start;\\n -ms-flex-align: start;\\n align-items: flex-start;\\n}\\n.p-toast-message-text {\\n -webkit-box-flex: 1;\\n -ms-flex: 1 1 auto;\\n flex: 1 1 auto;\\n}\\n.p-toast-top-right {\\n\\ttop: 20px;\\n\\tright: 20px;\\n}\\n.p-toast-top-left {\\n\\ttop: 20px;\\n\\tleft: 20px;\\n}\\n.p-toast-bottom-left {\\n\\tbottom: 20px;\\n\\tleft: 20px;\\n}\\n.p-toast-bottom-right {\\n\\tbottom: 20px;\\n\\tright: 20px;\\n}\\n.p-toast-top-center {\\n\\ttop: 20px;\\n left: 50%;\\n -webkit-transform: translateX(-50%);\\n transform: translateX(-50%);\\n}\\n.p-toast-bottom-center {\\n\\tbottom: 20px;\\n left: 50%;\\n -webkit-transform: translateX(-50%);\\n transform: translateX(-50%);\\n}\\n.p-toast-center {\\n\\tleft: 50%;\\n\\ttop: 50%;\\n min-width: 20vw;\\n -webkit-transform: translate(-50%, -50%);\\n transform: translate(-50%, -50%);\\n}\\n.p-toast-icon-close {\\n display: -webkit-box;\\n display: -ms-flexbox;\\n display: flex;\\n -webkit-box-align: center;\\n -ms-flex-align: center;\\n align-items: center;\\n -webkit-box-pack: center;\\n -ms-flex-pack: center;\\n justify-content: center;\\n overflow: hidden;\\n position: relative;\\n}\\n.p-toast-icon-close.p-link {\\n\\tcursor: pointer;\\n}\\n\\n/* Animations */\\n.p-toast-message-enter-from {\\n opacity: 0;\\n -webkit-transform: translateY(50%);\\n transform: translateY(50%);\\n}\\n.p-toast-message-leave-from {\\n max-height: 1000px;\\n}\\n.p-toast .p-toast-message.p-toast-message-leave-to {\\n max-height: 0;\\n opacity: 0;\\n margin-bottom: 0;\\n overflow: hidden;\\n}\\n.p-toast-message-enter-active {\\n -webkit-transition: transform .3s, opacity .3s;\\n -webkit-transition: opacity .3s, -webkit-transform .3s;\\n transition: opacity .3s, -webkit-transform .3s;\\n transition: transform .3s, opacity .3s;\\n transition: transform .3s, opacity .3s, -webkit-transform .3s;\\n}\\n.p-toast-message-leave-active {\\n -webkit-transition: max-height .45s cubic-bezier(0, 1, 0, 1), opacity .3s, margin-bottom .3s;\\n transition: max-height .45s cubic-bezier(0, 1, 0, 1), opacity .3s, margin-bottom .3s;\\n}\\n\";\ntoast_esm_styleInject(toast_esm_css_248z);\n\ntoast_esm_script.render = toast_esm_render;\n\n/* harmony default export */ const toast_esm = (toast_esm_script);\n\n;// CONCATENATED MODULE: ./node_modules/primevue/usetoast/usetoast.esm.js\n\n\nconst PrimeVueToastSymbol = Symbol();\n\nfunction useToast() {\n const PrimeVueToast = inject(PrimeVueToastSymbol);\n if (!PrimeVueToast) {\n throw new Error('No PrimeVue Toast provided!');\n } \n\n return PrimeVueToast;\n}\n\n\n\n;// CONCATENATED MODULE: ./node_modules/primevue/toastservice/toastservice.esm.js\n\n\n\nvar ToastService = {\n install: (app) => {\n const ToastService = {\n add: (message) => {\n toasteventbus_esm.emit('add', message);\n },\n removeGroup: (group) => {\n toasteventbus_esm.emit('remove-group', group);\n },\n removeAllGroups: () => {\n toasteventbus_esm.emit('remove-all-groups');\n }\n };\n app.config.globalProperties.$toast = ToastService;\n app.provide(PrimeVueToastSymbol, ToastService);\n }\n};\n\n/* harmony default export */ const toastservice_esm = (ToastService);\n\n;// CONCATENATED MODULE: ./node_modules/primevue/badgedirective/badgedirective.esm.js\n\n\nconst BadgeDirective = {\n beforeMount(el, options) {\n const id = (0,utils_esm/* UniqueComponentId */.Th)() + '_badge';\n el.$_pbadgeId = id;\n\n let badge = document.createElement('span');\n badge.id = id;\n badge.className = 'p-badge p-component';\n\n for (let modifier in options.modifiers) {\n utils_esm/* DomHandler.addClass */.p7.addClass(badge, 'p-badge-' + modifier);\n }\n \n if (options.value != null) {\n badge.appendChild(document.createTextNode(options.value));\n \n if (String(options.value).length === 1) {\n utils_esm/* DomHandler.addClass */.p7.addClass(badge, 'p-badge-no-gutter');\n }\n }\n else {\n utils_esm/* DomHandler.addClass */.p7.addClass(badge, 'p-badge-dot');\n }\n\n utils_esm/* DomHandler.addClass */.p7.addClass(el, 'p-overlay-badge');\n el.appendChild(badge);\n },\n updated(el, options) {\n utils_esm/* DomHandler.addClass */.p7.addClass(el, 'p-overlay-badge');\n\n if (options.oldValue !== options.value) {\n let badge = document.getElementById(el.$_pbadgeId);\n\n if (options.value) {\n if (utils_esm/* DomHandler.hasClass */.p7.hasClass(badge, 'p-badge-dot')) {\n utils_esm/* DomHandler.removeClass */.p7.removeClass(badge, 'p-badge-dot');\n }\n\n if (String(options.value).length === 1)\n utils_esm/* DomHandler.addClass */.p7.addClass(badge, 'p-badge-no-gutter');\n else\n utils_esm/* DomHandler.removeClass */.p7.removeClass(badge, 'p-badge-no-gutter');\n }\n else if (!options.value && !utils_esm/* DomHandler.hasClass */.p7.hasClass(badge, 'p-badge-dot')) {\n utils_esm/* DomHandler.addClass */.p7.addClass(badge, 'p-badge-dot');\n }\n\n badge.innerHTML = '';\n badge.appendChild(document.createTextNode(options.value));\n }\n }\n};\n\n/* harmony default export */ const badgedirective_esm = (BadgeDirective);\n\n// EXTERNAL MODULE: ./interface/html5/global/LocalCacheData.js\nvar global_LocalCacheData = __webpack_require__(9563);\n// EXTERNAL MODULE: ./interface/html5/model/Base.js\nvar Base = __webpack_require__(3751);\n// EXTERNAL MODULE: ./interface/html5/views/BaseWindowController.js\nvar BaseWindowController = __webpack_require__(1807);\n// EXTERNAL MODULE: ./interface/html5/services/ServiceCaller.js + 2 modules\nvar services_ServiceCaller = __webpack_require__(12);\n// EXTERNAL MODULE: ./interface/html5/views/BaseViewController.js\nvar BaseViewController = __webpack_require__(121);\n// EXTERNAL MODULE: ./interface/html5/services/TimeTrexClientAPI.js\nvar TimeTrexClientAPI = __webpack_require__(7526);\n;// CONCATENATED MODULE: ./node_modules/tslib/tslib.es6.js\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nfunction __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nvar tslib_es6_assign = function() {\r\n tslib_es6_assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return tslib_es6_assign.apply(this, arguments);\r\n}\r\n\r\nfunction __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nfunction __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nfunction __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nfunction __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nfunction __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nfunction __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nvar __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nfunction __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nfunction __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nfunction __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nfunction __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nfunction __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nfunction __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nfunction __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nfunction __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nfunction __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nfunction __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nfunction __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nfunction __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nfunction __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nfunction __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\n;// CONCATENATED MODULE: ./node_modules/@firebase/util/dist/index.esm.js\n\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * @fileoverview Firebase constants. Some of these (@defines) can be overridden at compile-time.\r\n */\r\nvar CONSTANTS = {\r\n /**\r\n * @define {boolean} Whether this is the client Node.js SDK.\r\n */\r\n NODE_CLIENT: false,\r\n /**\r\n * @define {boolean} Whether this is the Admin Node.js SDK.\r\n */\r\n NODE_ADMIN: false,\r\n /**\r\n * Firebase SDK Version\r\n */\r\n SDK_VERSION: '${JSCORE_VERSION}'\r\n};\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Throws an error if the provided assertion is falsy\r\n */\r\nvar assert = function (assertion, message) {\r\n if (!assertion) {\r\n throw assertionError(message);\r\n }\r\n};\r\n/**\r\n * Returns an Error object suitable for throwing.\r\n */\r\nvar assertionError = function (message) {\r\n return new Error('Firebase Database (' +\r\n CONSTANTS.SDK_VERSION +\r\n ') INTERNAL ASSERT FAILED: ' +\r\n message);\r\n};\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar stringToByteArray$1 = function (str) {\r\n // TODO(user): Use native implementations if/when available\r\n var out = [];\r\n var p = 0;\r\n for (var i = 0; i < str.length; i++) {\r\n var c = str.charCodeAt(i);\r\n if (c < 128) {\r\n out[p++] = c;\r\n }\r\n else if (c < 2048) {\r\n out[p++] = (c >> 6) | 192;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n else if ((c & 0xfc00) === 0xd800 &&\r\n i + 1 < str.length &&\r\n (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00) {\r\n // Surrogate Pair\r\n c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);\r\n out[p++] = (c >> 18) | 240;\r\n out[p++] = ((c >> 12) & 63) | 128;\r\n out[p++] = ((c >> 6) & 63) | 128;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n else {\r\n out[p++] = (c >> 12) | 224;\r\n out[p++] = ((c >> 6) & 63) | 128;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n }\r\n return out;\r\n};\r\n/**\r\n * Turns an array of numbers into the string given by the concatenation of the\r\n * characters to which the numbers correspond.\r\n * @param bytes Array of numbers representing characters.\r\n * @return Stringification of the array.\r\n */\r\nvar byteArrayToString = function (bytes) {\r\n // TODO(user): Use native implementations if/when available\r\n var out = [];\r\n var pos = 0, c = 0;\r\n while (pos < bytes.length) {\r\n var c1 = bytes[pos++];\r\n if (c1 < 128) {\r\n out[c++] = String.fromCharCode(c1);\r\n }\r\n else if (c1 > 191 && c1 < 224) {\r\n var c2 = bytes[pos++];\r\n out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));\r\n }\r\n else if (c1 > 239 && c1 < 365) {\r\n // Surrogate Pair\r\n var c2 = bytes[pos++];\r\n var c3 = bytes[pos++];\r\n var c4 = bytes[pos++];\r\n var u = (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -\r\n 0x10000;\r\n out[c++] = String.fromCharCode(0xd800 + (u >> 10));\r\n out[c++] = String.fromCharCode(0xdc00 + (u & 1023));\r\n }\r\n else {\r\n var c2 = bytes[pos++];\r\n var c3 = bytes[pos++];\r\n out[c++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));\r\n }\r\n }\r\n return out.join('');\r\n};\r\n// We define it as an object literal instead of a class because a class compiled down to es5 can't\r\n// be treeshaked. https://github.com/rollup/rollup/issues/1691\r\n// Static lookup maps, lazily populated by init_()\r\nvar base64 = {\r\n /**\r\n * Maps bytes to characters.\r\n */\r\n byteToCharMap_: null,\r\n /**\r\n * Maps characters to bytes.\r\n */\r\n charToByteMap_: null,\r\n /**\r\n * Maps bytes to websafe characters.\r\n * @private\r\n */\r\n byteToCharMapWebSafe_: null,\r\n /**\r\n * Maps websafe characters to bytes.\r\n * @private\r\n */\r\n charToByteMapWebSafe_: null,\r\n /**\r\n * Our default alphabet, shared between\r\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\r\n */\r\n ENCODED_VALS_BASE: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789',\r\n /**\r\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\r\n */\r\n get ENCODED_VALS() {\r\n return this.ENCODED_VALS_BASE + '+/=';\r\n },\r\n /**\r\n * Our websafe alphabet.\r\n */\r\n get ENCODED_VALS_WEBSAFE() {\r\n return this.ENCODED_VALS_BASE + '-_.';\r\n },\r\n /**\r\n * Whether this browser supports the atob and btoa functions. This extension\r\n * started at Mozilla but is now implemented by many browsers. We use the\r\n * ASSUME_* variables to avoid pulling in the full useragent detection library\r\n * but still allowing the standard per-browser compilations.\r\n *\r\n */\r\n HAS_NATIVE_SUPPORT: typeof atob === 'function',\r\n /**\r\n * Base64-encode an array of bytes.\r\n *\r\n * @param input An array of bytes (numbers with\r\n * value in [0, 255]) to encode.\r\n * @param webSafe Boolean indicating we should use the\r\n * alternative alphabet.\r\n * @return The base64 encoded string.\r\n */\r\n encodeByteArray: function (input, webSafe) {\r\n if (!Array.isArray(input)) {\r\n throw Error('encodeByteArray takes an array as a parameter');\r\n }\r\n this.init_();\r\n var byteToCharMap = webSafe\r\n ? this.byteToCharMapWebSafe_\r\n : this.byteToCharMap_;\r\n var output = [];\r\n for (var i = 0; i < input.length; i += 3) {\r\n var byte1 = input[i];\r\n var haveByte2 = i + 1 < input.length;\r\n var byte2 = haveByte2 ? input[i + 1] : 0;\r\n var haveByte3 = i + 2 < input.length;\r\n var byte3 = haveByte3 ? input[i + 2] : 0;\r\n var outByte1 = byte1 >> 2;\r\n var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\r\n var outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);\r\n var outByte4 = byte3 & 0x3f;\r\n if (!haveByte3) {\r\n outByte4 = 64;\r\n if (!haveByte2) {\r\n outByte3 = 64;\r\n }\r\n }\r\n output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]);\r\n }\r\n return output.join('');\r\n },\r\n /**\r\n * Base64-encode a string.\r\n *\r\n * @param input A string to encode.\r\n * @param webSafe If true, we should use the\r\n * alternative alphabet.\r\n * @return The base64 encoded string.\r\n */\r\n encodeString: function (input, webSafe) {\r\n // Shortcut for Mozilla browsers that implement\r\n // a native base64 encoder in the form of \"btoa/atob\"\r\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\r\n return btoa(input);\r\n }\r\n return this.encodeByteArray(stringToByteArray$1(input), webSafe);\r\n },\r\n /**\r\n * Base64-decode a string.\r\n *\r\n * @param input to decode.\r\n * @param webSafe True if we should use the\r\n * alternative alphabet.\r\n * @return string representing the decoded value.\r\n */\r\n decodeString: function (input, webSafe) {\r\n // Shortcut for Mozilla browsers that implement\r\n // a native base64 encoder in the form of \"btoa/atob\"\r\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\r\n return atob(input);\r\n }\r\n return byteArrayToString(this.decodeStringToByteArray(input, webSafe));\r\n },\r\n /**\r\n * Base64-decode a string.\r\n *\r\n * In base-64 decoding, groups of four characters are converted into three\r\n * bytes. If the encoder did not apply padding, the input length may not\r\n * be a multiple of 4.\r\n *\r\n * In this case, the last group will have fewer than 4 characters, and\r\n * padding will be inferred. If the group has one or two characters, it decodes\r\n * to one byte. If the group has three characters, it decodes to two bytes.\r\n *\r\n * @param input Input to decode.\r\n * @param webSafe True if we should use the web-safe alphabet.\r\n * @return bytes representing the decoded value.\r\n */\r\n decodeStringToByteArray: function (input, webSafe) {\r\n this.init_();\r\n var charToByteMap = webSafe\r\n ? this.charToByteMapWebSafe_\r\n : this.charToByteMap_;\r\n var output = [];\r\n for (var i = 0; i < input.length;) {\r\n var byte1 = charToByteMap[input.charAt(i++)];\r\n var haveByte2 = i < input.length;\r\n var byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\r\n ++i;\r\n var haveByte3 = i < input.length;\r\n var byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\r\n ++i;\r\n var haveByte4 = i < input.length;\r\n var byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\r\n ++i;\r\n if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {\r\n throw Error();\r\n }\r\n var outByte1 = (byte1 << 2) | (byte2 >> 4);\r\n output.push(outByte1);\r\n if (byte3 !== 64) {\r\n var outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);\r\n output.push(outByte2);\r\n if (byte4 !== 64) {\r\n var outByte3 = ((byte3 << 6) & 0xc0) | byte4;\r\n output.push(outByte3);\r\n }\r\n }\r\n }\r\n return output;\r\n },\r\n /**\r\n * Lazy static initialization function. Called before\r\n * accessing any of the static map variables.\r\n * @private\r\n */\r\n init_: function () {\r\n if (!this.byteToCharMap_) {\r\n this.byteToCharMap_ = {};\r\n this.charToByteMap_ = {};\r\n this.byteToCharMapWebSafe_ = {};\r\n this.charToByteMapWebSafe_ = {};\r\n // We want quick mappings back and forth, so we precompute two maps.\r\n for (var i = 0; i < this.ENCODED_VALS.length; i++) {\r\n this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);\r\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\r\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\r\n this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;\r\n // Be forgiving when decoding and correctly decode both encodings.\r\n if (i >= this.ENCODED_VALS_BASE.length) {\r\n this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\r\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\r\n }\r\n }\r\n }\r\n }\r\n};\r\n/**\r\n * URL-safe base64 encoding\r\n */\r\nvar base64Encode = function (str) {\r\n var utf8Bytes = stringToByteArray$1(str);\r\n return base64.encodeByteArray(utf8Bytes, true);\r\n};\r\n/**\r\n * URL-safe base64 encoding (without \".\" padding in the end).\r\n * e.g. Used in JSON Web Token (JWT) parts.\r\n */\r\nvar base64urlEncodeWithoutPadding = function (str) {\r\n // Use base64url encoding and remove padding in the end (dot characters).\r\n return base64Encode(str).replace(/\\./g, '');\r\n};\r\n/**\r\n * URL-safe base64 decoding\r\n *\r\n * NOTE: DO NOT use the global atob() function - it does NOT support the\r\n * base64Url variant encoding.\r\n *\r\n * @param str To be decoded\r\n * @return Decoded result, if possible\r\n */\r\nvar base64Decode = function (str) {\r\n try {\r\n return base64.decodeString(str, true);\r\n }\r\n catch (e) {\r\n console.error('base64Decode failed: ', e);\r\n }\r\n return null;\r\n};\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Do a deep-copy of basic JavaScript Objects or Arrays.\r\n */\r\nfunction deepCopy(value) {\r\n return deepExtend(undefined, value);\r\n}\r\n/**\r\n * Copy properties from source to target (recursively allows extension\r\n * of Objects and Arrays). Scalar values in the target are over-written.\r\n * If target is undefined, an object of the appropriate type will be created\r\n * (and returned).\r\n *\r\n * We recursively copy all child properties of plain Objects in the source- so\r\n * that namespace- like dictionaries are merged.\r\n *\r\n * Note that the target can be a function, in which case the properties in\r\n * the source Object are copied onto it as static properties of the Function.\r\n *\r\n * Note: we don't merge __proto__ to prevent prototype pollution\r\n */\r\nfunction deepExtend(target, source) {\r\n if (!(source instanceof Object)) {\r\n return source;\r\n }\r\n switch (source.constructor) {\r\n case Date:\r\n // Treat Dates like scalars; if the target date object had any child\r\n // properties - they will be lost!\r\n var dateValue = source;\r\n return new Date(dateValue.getTime());\r\n case Object:\r\n if (target === undefined) {\r\n target = {};\r\n }\r\n break;\r\n case Array:\r\n // Always copy the array source and overwrite the target.\r\n target = [];\r\n break;\r\n default:\r\n // Not a plain Object - treat it as a scalar.\r\n return source;\r\n }\r\n for (var prop in source) {\r\n // use isValidKey to guard against prototype pollution. See https://snyk.io/vuln/SNYK-JS-LODASH-450202\r\n if (!source.hasOwnProperty(prop) || !isValidKey(prop)) {\r\n continue;\r\n }\r\n target[prop] = deepExtend(target[prop], source[prop]);\r\n }\r\n return target;\r\n}\r\nfunction isValidKey(key) {\r\n return key !== '__proto__';\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar Deferred = /** @class */ (function () {\r\n function Deferred() {\r\n var _this = this;\r\n this.reject = function () { };\r\n this.resolve = function () { };\r\n this.promise = new Promise(function (resolve, reject) {\r\n _this.resolve = resolve;\r\n _this.reject = reject;\r\n });\r\n }\r\n /**\r\n * Our API internals are not promiseified and cannot because our callback APIs have subtle expectations around\r\n * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback\r\n * and returns a node-style callback which will resolve or reject the Deferred's promise.\r\n */\r\n Deferred.prototype.wrapCallback = function (callback) {\r\n var _this = this;\r\n return function (error, value) {\r\n if (error) {\r\n _this.reject(error);\r\n }\r\n else {\r\n _this.resolve(value);\r\n }\r\n if (typeof callback === 'function') {\r\n // Attaching noop handler just in case developer wasn't expecting\r\n // promises\r\n _this.promise.catch(function () { });\r\n // Some of our callbacks don't expect a value and our own tests\r\n // assert that the parameter length is 1\r\n if (callback.length === 1) {\r\n callback(error);\r\n }\r\n else {\r\n callback(error, value);\r\n }\r\n }\r\n };\r\n };\r\n return Deferred;\r\n}());\n\n/**\r\n * @license\r\n * Copyright 2021 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction createMockUserToken(token, projectId) {\r\n if (token.uid) {\r\n throw new Error('The \"uid\" field is no longer supported by mockUserToken. Please use \"sub\" instead for Firebase Auth User ID.');\r\n }\r\n // Unsecured JWTs use \"none\" as the algorithm.\r\n var header = {\r\n alg: 'none',\r\n type: 'JWT'\r\n };\r\n var project = projectId || 'demo-project';\r\n var iat = token.iat || 0;\r\n var sub = token.sub || token.user_id;\r\n if (!sub) {\r\n throw new Error(\"mockUserToken must contain 'sub' or 'user_id' field!\");\r\n }\r\n var payload = __assign({ \r\n // Set all required fields to decent defaults\r\n iss: \"https://securetoken.google.com/\" + project, aud: project, iat: iat, exp: iat + 3600, auth_time: iat, sub: sub, user_id: sub, firebase: {\r\n sign_in_provider: 'custom',\r\n identities: {}\r\n } }, token);\r\n // Unsecured JWTs use the empty string as a signature.\r\n var signature = '';\r\n return [\r\n base64urlEncodeWithoutPadding(JSON.stringify(header)),\r\n base64urlEncodeWithoutPadding(JSON.stringify(payload)),\r\n signature\r\n ].join('.');\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Returns navigator.userAgent string or '' if it's not defined.\r\n * @return user agent string\r\n */\r\nfunction getUA() {\r\n if (typeof navigator !== 'undefined' &&\r\n typeof navigator['userAgent'] === 'string') {\r\n return navigator['userAgent'];\r\n }\r\n else {\r\n return '';\r\n }\r\n}\r\n/**\r\n * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device.\r\n *\r\n * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap\r\n * in the Ripple emulator) nor Cordova `onDeviceReady`, which would normally\r\n * wait for a callback.\r\n */\r\nfunction isMobileCordova() {\r\n return (typeof window !== 'undefined' &&\r\n // @ts-ignore Setting up an broadly applicable index signature for Window\r\n // just to deal with this case would probably be a bad idea.\r\n !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) &&\r\n /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA()));\r\n}\r\n/**\r\n * Detect Node.js.\r\n *\r\n * @return true if Node.js environment is detected.\r\n */\r\n// Node detection logic from: https://github.com/iliakan/detect-node/\r\nfunction isNode() {\r\n try {\r\n return (Object.prototype.toString.call(__webpack_require__.g.process) === '[object process]');\r\n }\r\n catch (e) {\r\n return false;\r\n }\r\n}\r\n/**\r\n * Detect Browser Environment\r\n */\r\nfunction isBrowser() {\r\n return typeof self === 'object' && self.self === self;\r\n}\r\nfunction isBrowserExtension() {\r\n var runtime = typeof chrome === 'object'\r\n ? chrome.runtime\r\n : typeof browser === 'object'\r\n ? browser.runtime\r\n : undefined;\r\n return typeof runtime === 'object' && runtime.id !== undefined;\r\n}\r\n/**\r\n * Detect React Native.\r\n *\r\n * @return true if ReactNative environment is detected.\r\n */\r\nfunction isReactNative() {\r\n return (typeof navigator === 'object' && navigator['product'] === 'ReactNative');\r\n}\r\n/** Detects Electron apps. */\r\nfunction isElectron() {\r\n return getUA().indexOf('Electron/') >= 0;\r\n}\r\n/** Detects Internet Explorer. */\r\nfunction isIE() {\r\n var ua = getUA();\r\n return ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;\r\n}\r\n/** Detects Universal Windows Platform apps. */\r\nfunction isUWP() {\r\n return getUA().indexOf('MSAppHost/') >= 0;\r\n}\r\n/**\r\n * Detect whether the current SDK build is the Node version.\r\n *\r\n * @return true if it's the Node SDK build.\r\n */\r\nfunction isNodeSdk() {\r\n return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true;\r\n}\r\n/** Returns true if we are running in Safari. */\r\nfunction isSafari() {\r\n return (!isNode() &&\r\n navigator.userAgent.includes('Safari') &&\r\n !navigator.userAgent.includes('Chrome'));\r\n}\r\n/**\r\n * This method checks if indexedDB is supported by current browser/service worker context\r\n * @return true if indexedDB is supported by current browser/service worker context\r\n */\r\nfunction isIndexedDBAvailable() {\r\n return 'indexedDB' in self && indexedDB != null;\r\n}\r\n/**\r\n * This method validates browser/sw context for indexedDB by opening a dummy indexedDB database and reject\r\n * if errors occur during the database open operation.\r\n *\r\n * @throws exception if current browser/sw context can't run idb.open (ex: Safari iframe, Firefox\r\n * private browsing)\r\n */\r\nfunction validateIndexedDBOpenable() {\r\n return new Promise(function (resolve, reject) {\r\n try {\r\n var preExist_1 = true;\r\n var DB_CHECK_NAME_1 = 'validate-browser-context-for-indexeddb-analytics-module';\r\n var request_1 = self.indexedDB.open(DB_CHECK_NAME_1);\r\n request_1.onsuccess = function () {\r\n request_1.result.close();\r\n // delete database only when it doesn't pre-exist\r\n if (!preExist_1) {\r\n self.indexedDB.deleteDatabase(DB_CHECK_NAME_1);\r\n }\r\n resolve(true);\r\n };\r\n request_1.onupgradeneeded = function () {\r\n preExist_1 = false;\r\n };\r\n request_1.onerror = function () {\r\n var _a;\r\n reject(((_a = request_1.error) === null || _a === void 0 ? void 0 : _a.message) || '');\r\n };\r\n }\r\n catch (error) {\r\n reject(error);\r\n }\r\n });\r\n}\r\n/**\r\n *\r\n * This method checks whether cookie is enabled within current browser\r\n * @return true if cookie is enabled within current browser\r\n */\r\nfunction areCookiesEnabled() {\r\n if (!navigator || !navigator.cookieEnabled) {\r\n return false;\r\n }\r\n return true;\r\n}\r\n/**\r\n * Polyfill for `globalThis` object.\r\n * @returns the `globalThis` object for the given environment.\r\n */\r\nfunction getGlobal() {\r\n if (typeof self !== 'undefined') {\r\n return self;\r\n }\r\n if (typeof window !== 'undefined') {\r\n return window;\r\n }\r\n if (typeof __webpack_require__.g !== 'undefined') {\r\n return __webpack_require__.g;\r\n }\r\n throw new Error('Unable to locate global object.');\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar ERROR_NAME = 'FirebaseError';\r\n// Based on code from:\r\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\r\nvar FirebaseError = /** @class */ (function (_super) {\r\n __extends(FirebaseError, _super);\r\n function FirebaseError(code, message, customData) {\r\n var _this = _super.call(this, message) || this;\r\n _this.code = code;\r\n _this.customData = customData;\r\n _this.name = ERROR_NAME;\r\n // Fix For ES5\r\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\r\n Object.setPrototypeOf(_this, FirebaseError.prototype);\r\n // Maintains proper stack trace for where our error was thrown.\r\n // Only available on V8.\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(_this, ErrorFactory.prototype.create);\r\n }\r\n return _this;\r\n }\r\n return FirebaseError;\r\n}(Error));\r\nvar ErrorFactory = /** @class */ (function () {\r\n function ErrorFactory(service, serviceName, errors) {\r\n this.service = service;\r\n this.serviceName = serviceName;\r\n this.errors = errors;\r\n }\r\n ErrorFactory.prototype.create = function (code) {\r\n var data = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n data[_i - 1] = arguments[_i];\r\n }\r\n var customData = data[0] || {};\r\n var fullCode = this.service + \"/\" + code;\r\n var template = this.errors[code];\r\n var message = template ? replaceTemplate(template, customData) : 'Error';\r\n // Service Name: Error message (service/code).\r\n var fullMessage = this.serviceName + \": \" + message + \" (\" + fullCode + \").\";\r\n var error = new FirebaseError(fullCode, fullMessage, customData);\r\n return error;\r\n };\r\n return ErrorFactory;\r\n}());\r\nfunction replaceTemplate(template, data) {\r\n return template.replace(PATTERN, function (_, key) {\r\n var value = data[key];\r\n return value != null ? String(value) : \"<\" + key + \"?>\";\r\n });\r\n}\r\nvar PATTERN = /\\{\\$([^}]+)}/g;\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Evaluates a JSON string into a javascript object.\r\n *\r\n * @param {string} str A string containing JSON.\r\n * @return {*} The javascript object representing the specified JSON.\r\n */\r\nfunction jsonEval(str) {\r\n return JSON.parse(str);\r\n}\r\n/**\r\n * Returns JSON representing a javascript object.\r\n * @param {*} data Javascript object to be stringified.\r\n * @return {string} The JSON contents of the object.\r\n */\r\nfunction stringify(data) {\r\n return JSON.stringify(data);\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Decodes a Firebase auth. token into constituent parts.\r\n *\r\n * Notes:\r\n * - May return with invalid / incomplete claims if there's no native base64 decoding support.\r\n * - Doesn't check if the token is actually valid.\r\n */\r\nvar decode = function (token) {\r\n var header = {}, claims = {}, data = {}, signature = '';\r\n try {\r\n var parts = token.split('.');\r\n header = jsonEval(base64Decode(parts[0]) || '');\r\n claims = jsonEval(base64Decode(parts[1]) || '');\r\n signature = parts[2];\r\n data = claims['d'] || {};\r\n delete claims['d'];\r\n }\r\n catch (e) { }\r\n return {\r\n header: header,\r\n claims: claims,\r\n data: data,\r\n signature: signature\r\n };\r\n};\r\n/**\r\n * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the\r\n * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims.\r\n *\r\n * Notes:\r\n * - May return a false negative if there's no native base64 decoding support.\r\n * - Doesn't check if the token is actually valid.\r\n */\r\nvar isValidTimestamp = function (token) {\r\n var claims = decode(token).claims;\r\n var now = Math.floor(new Date().getTime() / 1000);\r\n var validSince = 0, validUntil = 0;\r\n if (typeof claims === 'object') {\r\n if (claims.hasOwnProperty('nbf')) {\r\n validSince = claims['nbf'];\r\n }\r\n else if (claims.hasOwnProperty('iat')) {\r\n validSince = claims['iat'];\r\n }\r\n if (claims.hasOwnProperty('exp')) {\r\n validUntil = claims['exp'];\r\n }\r\n else {\r\n // token will expire after 24h by default\r\n validUntil = validSince + 86400;\r\n }\r\n }\r\n return (!!now &&\r\n !!validSince &&\r\n !!validUntil &&\r\n now >= validSince &&\r\n now <= validUntil);\r\n};\r\n/**\r\n * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise.\r\n *\r\n * Notes:\r\n * - May return null if there's no native base64 decoding support.\r\n * - Doesn't check if the token is actually valid.\r\n */\r\nvar issuedAtTime = function (token) {\r\n var claims = decode(token).claims;\r\n if (typeof claims === 'object' && claims.hasOwnProperty('iat')) {\r\n return claims['iat'];\r\n }\r\n return null;\r\n};\r\n/**\r\n * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time.\r\n *\r\n * Notes:\r\n * - May return a false negative if there's no native base64 decoding support.\r\n * - Doesn't check if the token is actually valid.\r\n */\r\nvar isValidFormat = function (token) {\r\n var decoded = decode(token), claims = decoded.claims;\r\n return !!claims && typeof claims === 'object' && claims.hasOwnProperty('iat');\r\n};\r\n/**\r\n * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion.\r\n *\r\n * Notes:\r\n * - May return a false negative if there's no native base64 decoding support.\r\n * - Doesn't check if the token is actually valid.\r\n */\r\nvar isAdmin = function (token) {\r\n var claims = decode(token).claims;\r\n return typeof claims === 'object' && claims['admin'] === true;\r\n};\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction contains(obj, key) {\r\n return Object.prototype.hasOwnProperty.call(obj, key);\r\n}\r\nfunction safeGet(obj, key) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n return obj[key];\r\n }\r\n else {\r\n return undefined;\r\n }\r\n}\r\nfunction isEmpty(obj) {\r\n for (var key in obj) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\nfunction map(obj, fn, contextObj) {\r\n var res = {};\r\n for (var key in obj) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n res[key] = fn.call(contextObj, obj[key], key, obj);\r\n }\r\n }\r\n return res;\r\n}\r\n/**\r\n * Deep equal two objects. Support Arrays and Objects.\r\n */\r\nfunction deepEqual(a, b) {\r\n if (a === b) {\r\n return true;\r\n }\r\n var aKeys = Object.keys(a);\r\n var bKeys = Object.keys(b);\r\n for (var _i = 0, aKeys_1 = aKeys; _i < aKeys_1.length; _i++) {\r\n var k = aKeys_1[_i];\r\n if (!bKeys.includes(k)) {\r\n return false;\r\n }\r\n var aProp = a[k];\r\n var bProp = b[k];\r\n if (isObject(aProp) && isObject(bProp)) {\r\n if (!deepEqual(aProp, bProp)) {\r\n return false;\r\n }\r\n }\r\n else if (aProp !== bProp) {\r\n return false;\r\n }\r\n }\r\n for (var _a = 0, bKeys_1 = bKeys; _a < bKeys_1.length; _a++) {\r\n var k = bKeys_1[_a];\r\n if (!aKeys.includes(k)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\nfunction isObject(thing) {\r\n return thing !== null && typeof thing === 'object';\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a\r\n * params object (e.g. {arg: 'val', arg2: 'val2'})\r\n * Note: You must prepend it with ? when adding it to a URL.\r\n */\r\nfunction querystring(querystringParams) {\r\n var params = [];\r\n var _loop_1 = function (key, value) {\r\n if (Array.isArray(value)) {\r\n value.forEach(function (arrayVal) {\r\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal));\r\n });\r\n }\r\n else {\r\n params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));\r\n }\r\n };\r\n for (var _i = 0, _a = Object.entries(querystringParams); _i < _a.length; _i++) {\r\n var _b = _a[_i], key = _b[0], value = _b[1];\r\n _loop_1(key, value);\r\n }\r\n return params.length ? '&' + params.join('&') : '';\r\n}\r\n/**\r\n * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object\r\n * (e.g. {arg: 'val', arg2: 'val2'})\r\n */\r\nfunction querystringDecode(querystring) {\r\n var obj = {};\r\n var tokens = querystring.replace(/^\\?/, '').split('&');\r\n tokens.forEach(function (token) {\r\n if (token) {\r\n var _a = token.split('='), key = _a[0], value = _a[1];\r\n obj[decodeURIComponent(key)] = decodeURIComponent(value);\r\n }\r\n });\r\n return obj;\r\n}\r\n/**\r\n * Extract the query string part of a URL, including the leading question mark (if present).\r\n */\r\nfunction extractQuerystring(url) {\r\n var queryStart = url.indexOf('?');\r\n if (!queryStart) {\r\n return '';\r\n }\r\n var fragmentStart = url.indexOf('#', queryStart);\r\n return url.substring(queryStart, fragmentStart > 0 ? fragmentStart : undefined);\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * @fileoverview SHA-1 cryptographic hash.\r\n * Variable names follow the notation in FIPS PUB 180-3:\r\n * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.\r\n *\r\n * Usage:\r\n * var sha1 = new sha1();\r\n * sha1.update(bytes);\r\n * var hash = sha1.digest();\r\n *\r\n * Performance:\r\n * Chrome 23: ~400 Mbit/s\r\n * Firefox 16: ~250 Mbit/s\r\n *\r\n */\r\n/**\r\n * SHA-1 cryptographic hash constructor.\r\n *\r\n * The properties declared here are discussed in the above algorithm document.\r\n * @constructor\r\n * @final\r\n * @struct\r\n */\r\nvar Sha1 = /** @class */ (function () {\r\n function Sha1() {\r\n /**\r\n * Holds the previous values of accumulated variables a-e in the compress_\r\n * function.\r\n * @private\r\n */\r\n this.chain_ = [];\r\n /**\r\n * A buffer holding the partially computed hash result.\r\n * @private\r\n */\r\n this.buf_ = [];\r\n /**\r\n * An array of 80 bytes, each a part of the message to be hashed. Referred to\r\n * as the message schedule in the docs.\r\n * @private\r\n */\r\n this.W_ = [];\r\n /**\r\n * Contains data needed to pad messages less than 64 bytes.\r\n * @private\r\n */\r\n this.pad_ = [];\r\n /**\r\n * @private {number}\r\n */\r\n this.inbuf_ = 0;\r\n /**\r\n * @private {number}\r\n */\r\n this.total_ = 0;\r\n this.blockSize = 512 / 8;\r\n this.pad_[0] = 128;\r\n for (var i = 1; i < this.blockSize; ++i) {\r\n this.pad_[i] = 0;\r\n }\r\n this.reset();\r\n }\r\n Sha1.prototype.reset = function () {\r\n this.chain_[0] = 0x67452301;\r\n this.chain_[1] = 0xefcdab89;\r\n this.chain_[2] = 0x98badcfe;\r\n this.chain_[3] = 0x10325476;\r\n this.chain_[4] = 0xc3d2e1f0;\r\n this.inbuf_ = 0;\r\n this.total_ = 0;\r\n };\r\n /**\r\n * Internal compress helper function.\r\n * @param buf Block to compress.\r\n * @param offset Offset of the block in the buffer.\r\n * @private\r\n */\r\n Sha1.prototype.compress_ = function (buf, offset) {\r\n if (!offset) {\r\n offset = 0;\r\n }\r\n var W = this.W_;\r\n // get 16 big endian words\r\n if (typeof buf === 'string') {\r\n for (var i = 0; i < 16; i++) {\r\n // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS\r\n // have a bug that turns the post-increment ++ operator into pre-increment\r\n // during JIT compilation. We have code that depends heavily on SHA-1 for\r\n // correctness and which is affected by this bug, so I've removed all uses\r\n // of post-increment ++ in which the result value is used. We can revert\r\n // this change once the Safari bug\r\n // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and\r\n // most clients have been updated.\r\n W[i] =\r\n (buf.charCodeAt(offset) << 24) |\r\n (buf.charCodeAt(offset + 1) << 16) |\r\n (buf.charCodeAt(offset + 2) << 8) |\r\n buf.charCodeAt(offset + 3);\r\n offset += 4;\r\n }\r\n }\r\n else {\r\n for (var i = 0; i < 16; i++) {\r\n W[i] =\r\n (buf[offset] << 24) |\r\n (buf[offset + 1] << 16) |\r\n (buf[offset + 2] << 8) |\r\n buf[offset + 3];\r\n offset += 4;\r\n }\r\n }\r\n // expand to 80 words\r\n for (var i = 16; i < 80; i++) {\r\n var t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\r\n W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff;\r\n }\r\n var a = this.chain_[0];\r\n var b = this.chain_[1];\r\n var c = this.chain_[2];\r\n var d = this.chain_[3];\r\n var e = this.chain_[4];\r\n var f, k;\r\n // TODO(user): Try to unroll this loop to speed up the computation.\r\n for (var i = 0; i < 80; i++) {\r\n if (i < 40) {\r\n if (i < 20) {\r\n f = d ^ (b & (c ^ d));\r\n k = 0x5a827999;\r\n }\r\n else {\r\n f = b ^ c ^ d;\r\n k = 0x6ed9eba1;\r\n }\r\n }\r\n else {\r\n if (i < 60) {\r\n f = (b & c) | (d & (b | c));\r\n k = 0x8f1bbcdc;\r\n }\r\n else {\r\n f = b ^ c ^ d;\r\n k = 0xca62c1d6;\r\n }\r\n }\r\n var t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff;\r\n e = d;\r\n d = c;\r\n c = ((b << 30) | (b >>> 2)) & 0xffffffff;\r\n b = a;\r\n a = t;\r\n }\r\n this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;\r\n this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;\r\n this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;\r\n this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;\r\n this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;\r\n };\r\n Sha1.prototype.update = function (bytes, length) {\r\n // TODO(johnlenz): tighten the function signature and remove this check\r\n if (bytes == null) {\r\n return;\r\n }\r\n if (length === undefined) {\r\n length = bytes.length;\r\n }\r\n var lengthMinusBlock = length - this.blockSize;\r\n var n = 0;\r\n // Using local instead of member variables gives ~5% speedup on Firefox 16.\r\n var buf = this.buf_;\r\n var inbuf = this.inbuf_;\r\n // The outer while loop should execute at most twice.\r\n while (n < length) {\r\n // When we have no data in the block to top up, we can directly process the\r\n // input buffer (assuming it contains sufficient data). This gives ~25%\r\n // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that\r\n // the data is provided in large chunks (or in multiples of 64 bytes).\r\n if (inbuf === 0) {\r\n while (n <= lengthMinusBlock) {\r\n this.compress_(bytes, n);\r\n n += this.blockSize;\r\n }\r\n }\r\n if (typeof bytes === 'string') {\r\n while (n < length) {\r\n buf[inbuf] = bytes.charCodeAt(n);\r\n ++inbuf;\r\n ++n;\r\n if (inbuf === this.blockSize) {\r\n this.compress_(buf);\r\n inbuf = 0;\r\n // Jump to the outer loop so we use the full-block optimization.\r\n break;\r\n }\r\n }\r\n }\r\n else {\r\n while (n < length) {\r\n buf[inbuf] = bytes[n];\r\n ++inbuf;\r\n ++n;\r\n if (inbuf === this.blockSize) {\r\n this.compress_(buf);\r\n inbuf = 0;\r\n // Jump to the outer loop so we use the full-block optimization.\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n this.inbuf_ = inbuf;\r\n this.total_ += length;\r\n };\r\n /** @override */\r\n Sha1.prototype.digest = function () {\r\n var digest = [];\r\n var totalBits = this.total_ * 8;\r\n // Add pad 0x80 0x00*.\r\n if (this.inbuf_ < 56) {\r\n this.update(this.pad_, 56 - this.inbuf_);\r\n }\r\n else {\r\n this.update(this.pad_, this.blockSize - (this.inbuf_ - 56));\r\n }\r\n // Add # bits.\r\n for (var i = this.blockSize - 1; i >= 56; i--) {\r\n this.buf_[i] = totalBits & 255;\r\n totalBits /= 256; // Don't use bit-shifting here!\r\n }\r\n this.compress_(this.buf_);\r\n var n = 0;\r\n for (var i = 0; i < 5; i++) {\r\n for (var j = 24; j >= 0; j -= 8) {\r\n digest[n] = (this.chain_[i] >> j) & 255;\r\n ++n;\r\n }\r\n }\r\n return digest;\r\n };\r\n return Sha1;\r\n}());\n\n/**\r\n * Helper to make a Subscribe function (just like Promise helps make a\r\n * Thenable).\r\n *\r\n * @param executor Function which can make calls to a single Observer\r\n * as a proxy.\r\n * @param onNoObservers Callback when count of Observers goes to zero.\r\n */\r\nfunction createSubscribe(executor, onNoObservers) {\r\n var proxy = new ObserverProxy(executor, onNoObservers);\r\n return proxy.subscribe.bind(proxy);\r\n}\r\n/**\r\n * Implement fan-out for any number of Observers attached via a subscribe\r\n * function.\r\n */\r\nvar ObserverProxy = /** @class */ (function () {\r\n /**\r\n * @param executor Function which can make calls to a single Observer\r\n * as a proxy.\r\n * @param onNoObservers Callback when count of Observers goes to zero.\r\n */\r\n function ObserverProxy(executor, onNoObservers) {\r\n var _this = this;\r\n this.observers = [];\r\n this.unsubscribes = [];\r\n this.observerCount = 0;\r\n // Micro-task scheduling by calling task.then().\r\n this.task = Promise.resolve();\r\n this.finalized = false;\r\n this.onNoObservers = onNoObservers;\r\n // Call the executor asynchronously so subscribers that are called\r\n // synchronously after the creation of the subscribe function\r\n // can still receive the very first value generated in the executor.\r\n this.task\r\n .then(function () {\r\n executor(_this);\r\n })\r\n .catch(function (e) {\r\n _this.error(e);\r\n });\r\n }\r\n ObserverProxy.prototype.next = function (value) {\r\n this.forEachObserver(function (observer) {\r\n observer.next(value);\r\n });\r\n };\r\n ObserverProxy.prototype.error = function (error) {\r\n this.forEachObserver(function (observer) {\r\n observer.error(error);\r\n });\r\n this.close(error);\r\n };\r\n ObserverProxy.prototype.complete = function () {\r\n this.forEachObserver(function (observer) {\r\n observer.complete();\r\n });\r\n this.close();\r\n };\r\n /**\r\n * Subscribe function that can be used to add an Observer to the fan-out list.\r\n *\r\n * - We require that no event is sent to a subscriber sychronously to their\r\n * call to subscribe().\r\n */\r\n ObserverProxy.prototype.subscribe = function (nextOrObserver, error, complete) {\r\n var _this = this;\r\n var observer;\r\n if (nextOrObserver === undefined &&\r\n error === undefined &&\r\n complete === undefined) {\r\n throw new Error('Missing Observer.');\r\n }\r\n // Assemble an Observer object when passed as callback functions.\r\n if (implementsAnyMethods(nextOrObserver, [\r\n 'next',\r\n 'error',\r\n 'complete'\r\n ])) {\r\n observer = nextOrObserver;\r\n }\r\n else {\r\n observer = {\r\n next: nextOrObserver,\r\n error: error,\r\n complete: complete\r\n };\r\n }\r\n if (observer.next === undefined) {\r\n observer.next = noop;\r\n }\r\n if (observer.error === undefined) {\r\n observer.error = noop;\r\n }\r\n if (observer.complete === undefined) {\r\n observer.complete = noop;\r\n }\r\n var unsub = this.unsubscribeOne.bind(this, this.observers.length);\r\n // Attempt to subscribe to a terminated Observable - we\r\n // just respond to the Observer with the final error or complete\r\n // event.\r\n if (this.finalized) {\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.task.then(function () {\r\n try {\r\n if (_this.finalError) {\r\n observer.error(_this.finalError);\r\n }\r\n else {\r\n observer.complete();\r\n }\r\n }\r\n catch (e) {\r\n // nothing\r\n }\r\n return;\r\n });\r\n }\r\n this.observers.push(observer);\r\n return unsub;\r\n };\r\n // Unsubscribe is synchronous - we guarantee that no events are sent to\r\n // any unsubscribed Observer.\r\n ObserverProxy.prototype.unsubscribeOne = function (i) {\r\n if (this.observers === undefined || this.observers[i] === undefined) {\r\n return;\r\n }\r\n delete this.observers[i];\r\n this.observerCount -= 1;\r\n if (this.observerCount === 0 && this.onNoObservers !== undefined) {\r\n this.onNoObservers(this);\r\n }\r\n };\r\n ObserverProxy.prototype.forEachObserver = function (fn) {\r\n if (this.finalized) {\r\n // Already closed by previous event....just eat the additional values.\r\n return;\r\n }\r\n // Since sendOne calls asynchronously - there is no chance that\r\n // this.observers will become undefined.\r\n for (var i = 0; i < this.observers.length; i++) {\r\n this.sendOne(i, fn);\r\n }\r\n };\r\n // Call the Observer via one of it's callback function. We are careful to\r\n // confirm that the observe has not been unsubscribed since this asynchronous\r\n // function had been queued.\r\n ObserverProxy.prototype.sendOne = function (i, fn) {\r\n var _this = this;\r\n // Execute the callback asynchronously\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.task.then(function () {\r\n if (_this.observers !== undefined && _this.observers[i] !== undefined) {\r\n try {\r\n fn(_this.observers[i]);\r\n }\r\n catch (e) {\r\n // Ignore exceptions raised in Observers or missing methods of an\r\n // Observer.\r\n // Log error to console. b/31404806\r\n if (typeof console !== 'undefined' && console.error) {\r\n console.error(e);\r\n }\r\n }\r\n }\r\n });\r\n };\r\n ObserverProxy.prototype.close = function (err) {\r\n var _this = this;\r\n if (this.finalized) {\r\n return;\r\n }\r\n this.finalized = true;\r\n if (err !== undefined) {\r\n this.finalError = err;\r\n }\r\n // Proxy is no longer needed - garbage collect references\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\r\n this.task.then(function () {\r\n _this.observers = undefined;\r\n _this.onNoObservers = undefined;\r\n });\r\n };\r\n return ObserverProxy;\r\n}());\r\n/** Turn synchronous function into one called asynchronously. */\r\n// eslint-disable-next-line @typescript-eslint/ban-types\r\nfunction index_esm_async(fn, onError) {\r\n return function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n Promise.resolve(true)\r\n .then(function () {\r\n fn.apply(void 0, args);\r\n })\r\n .catch(function (error) {\r\n if (onError) {\r\n onError(error);\r\n }\r\n });\r\n };\r\n}\r\n/**\r\n * Return true if the object passed in implements any of the named methods.\r\n */\r\nfunction implementsAnyMethods(obj, methods) {\r\n if (typeof obj !== 'object' || obj === null) {\r\n return false;\r\n }\r\n for (var _i = 0, methods_1 = methods; _i < methods_1.length; _i++) {\r\n var method = methods_1[_i];\r\n if (method in obj && typeof obj[method] === 'function') {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\nfunction noop() {\r\n // do nothing\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Check to make sure the appropriate number of arguments are provided for a public function.\r\n * Throws an error if it fails.\r\n *\r\n * @param fnName The function name\r\n * @param minCount The minimum number of arguments to allow for the function call\r\n * @param maxCount The maximum number of argument to allow for the function call\r\n * @param argCount The actual number of arguments provided.\r\n */\r\nvar validateArgCount = function (fnName, minCount, maxCount, argCount) {\r\n var argError;\r\n if (argCount < minCount) {\r\n argError = 'at least ' + minCount;\r\n }\r\n else if (argCount > maxCount) {\r\n argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount;\r\n }\r\n if (argError) {\r\n var error = fnName +\r\n ' failed: Was called with ' +\r\n argCount +\r\n (argCount === 1 ? ' argument.' : ' arguments.') +\r\n ' Expects ' +\r\n argError +\r\n '.';\r\n throw new Error(error);\r\n }\r\n};\r\n/**\r\n * Generates a string to prefix an error message about failed argument validation\r\n *\r\n * @param fnName The function name\r\n * @param argName The name of the argument\r\n * @return The prefix to add to the error thrown for validation.\r\n */\r\nfunction errorPrefix(fnName, argName) {\r\n return fnName + \" failed: \" + argName + \" argument \";\r\n}\r\n/**\r\n * @param fnName\r\n * @param argumentNumber\r\n * @param namespace\r\n * @param optional\r\n */\r\nfunction validateNamespace(fnName, namespace, optional) {\r\n if (optional && !namespace) {\r\n return;\r\n }\r\n if (typeof namespace !== 'string') {\r\n //TODO: I should do more validation here. We only allow certain chars in namespaces.\r\n throw new Error(errorPrefix(fnName, 'namespace') + 'must be a valid firebase namespace.');\r\n }\r\n}\r\nfunction validateCallback(fnName, argumentName, \r\n// eslint-disable-next-line @typescript-eslint/ban-types\r\ncallback, optional) {\r\n if (optional && !callback) {\r\n return;\r\n }\r\n if (typeof callback !== 'function') {\r\n throw new Error(errorPrefix(fnName, argumentName) + 'must be a valid function.');\r\n }\r\n}\r\nfunction validateContextObject(fnName, argumentName, context, optional) {\r\n if (optional && !context) {\r\n return;\r\n }\r\n if (typeof context !== 'object' || context === null) {\r\n throw new Error(errorPrefix(fnName, argumentName) + 'must be a valid context object.');\r\n }\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n// Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they\r\n// automatically replaced '\\r\\n' with '\\n', and they didn't handle surrogate pairs,\r\n// so it's been modified.\r\n// Note that not all Unicode characters appear as single characters in JavaScript strings.\r\n// fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters\r\n// use 2 characters in Javascript. All 4-byte UTF-8 characters begin with a first\r\n// character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate\r\n// pair).\r\n// See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3\r\n/**\r\n * @param {string} str\r\n * @return {Array}\r\n */\r\nvar stringToByteArray = function (str) {\r\n var out = [];\r\n var p = 0;\r\n for (var i = 0; i < str.length; i++) {\r\n var c = str.charCodeAt(i);\r\n // Is this the lead surrogate in a surrogate pair?\r\n if (c >= 0xd800 && c <= 0xdbff) {\r\n var high = c - 0xd800; // the high 10 bits.\r\n i++;\r\n assert(i < str.length, 'Surrogate pair missing trail surrogate.');\r\n var low = str.charCodeAt(i) - 0xdc00; // the low 10 bits.\r\n c = 0x10000 + (high << 10) + low;\r\n }\r\n if (c < 128) {\r\n out[p++] = c;\r\n }\r\n else if (c < 2048) {\r\n out[p++] = (c >> 6) | 192;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n else if (c < 65536) {\r\n out[p++] = (c >> 12) | 224;\r\n out[p++] = ((c >> 6) & 63) | 128;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n else {\r\n out[p++] = (c >> 18) | 240;\r\n out[p++] = ((c >> 12) & 63) | 128;\r\n out[p++] = ((c >> 6) & 63) | 128;\r\n out[p++] = (c & 63) | 128;\r\n }\r\n }\r\n return out;\r\n};\r\n/**\r\n * Calculate length without actually converting; useful for doing cheaper validation.\r\n * @param {string} str\r\n * @return {number}\r\n */\r\nvar stringLength = function (str) {\r\n var p = 0;\r\n for (var i = 0; i < str.length; i++) {\r\n var c = str.charCodeAt(i);\r\n if (c < 128) {\r\n p++;\r\n }\r\n else if (c < 2048) {\r\n p += 2;\r\n }\r\n else if (c >= 0xd800 && c <= 0xdbff) {\r\n // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent.\r\n p += 4;\r\n i++; // skip trail surrogate.\r\n }\r\n else {\r\n p += 3;\r\n }\r\n }\r\n return p;\r\n};\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * The amount of milliseconds to exponentially increase.\r\n */\r\nvar DEFAULT_INTERVAL_MILLIS = 1000;\r\n/**\r\n * The factor to backoff by.\r\n * Should be a number greater than 1.\r\n */\r\nvar DEFAULT_BACKOFF_FACTOR = 2;\r\n/**\r\n * The maximum milliseconds to increase to.\r\n *\r\n *

    Visible for testing\r\n */\r\nvar MAX_VALUE_MILLIS = (/* unused pure expression or super */ null && (4 * 60 * 60 * 1000)); // Four hours, like iOS and Android.\r\n/**\r\n * The percentage of backoff time to randomize by.\r\n * See\r\n * http://go/safe-client-behavior#step-1-determine-the-appropriate-retry-interval-to-handle-spike-traffic\r\n * for context.\r\n *\r\n *

    Visible for testing\r\n */\r\nvar RANDOM_FACTOR = 0.5;\r\n/**\r\n * Based on the backoff method from\r\n * https://github.com/google/closure-library/blob/master/closure/goog/math/exponentialbackoff.js.\r\n * Extracted here so we don't need to pass metadata and a stateful ExponentialBackoff object around.\r\n */\r\nfunction calculateBackoffMillis(backoffCount, intervalMillis, backoffFactor) {\r\n if (intervalMillis === void 0) { intervalMillis = DEFAULT_INTERVAL_MILLIS; }\r\n if (backoffFactor === void 0) { backoffFactor = DEFAULT_BACKOFF_FACTOR; }\r\n // Calculates an exponentially increasing value.\r\n // Deviation: calculates value from count and a constant interval, so we only need to save value\r\n // and count to restore state.\r\n var currBaseValue = intervalMillis * Math.pow(backoffFactor, backoffCount);\r\n // A random \"fuzz\" to avoid waves of retries.\r\n // Deviation: randomFactor is required.\r\n var randomWait = Math.round(\r\n // A fraction of the backoff value to add/subtract.\r\n // Deviation: changes multiplication order to improve readability.\r\n RANDOM_FACTOR *\r\n currBaseValue *\r\n // A random float (rounded to int by Math.round above) in the range [-1, 1]. Determines\r\n // if we add or subtract.\r\n (Math.random() - 0.5) *\r\n 2);\r\n // Limits backoff to max to avoid effectively permanent backoff.\r\n return Math.min(MAX_VALUE_MILLIS, currBaseValue + randomWait);\r\n}\n\n/**\r\n * @license\r\n * Copyright 2020 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Provide English ordinal letters after a number\r\n */\r\nfunction ordinal(i) {\r\n if (!Number.isFinite(i)) {\r\n return \"\" + i;\r\n }\r\n return i + indicator(i);\r\n}\r\nfunction indicator(i) {\r\n i = Math.abs(i);\r\n var cent = i % 100;\r\n if (cent >= 10 && cent <= 20) {\r\n return 'th';\r\n }\r\n var dec = i % 10;\r\n if (dec === 1) {\r\n return 'st';\r\n }\r\n if (dec === 2) {\r\n return 'nd';\r\n }\r\n if (dec === 3) {\r\n return 'rd';\r\n }\r\n return 'th';\r\n}\n\n/**\r\n * @license\r\n * Copyright 2021 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction getModularInstance(service) {\r\n if (service && service._delegate) {\r\n return service._delegate;\r\n }\r\n else {\r\n return service;\r\n }\r\n}\n\n\n//# sourceMappingURL=index.esm.js.map\n\n;// CONCATENATED MODULE: ./node_modules/@firebase/component/dist/index.esm.js\n\n\n\n/**\r\n * Component for service name T, e.g. `auth`, `auth-internal`\r\n */\r\nvar Component = /** @class */ (function () {\r\n /**\r\n *\r\n * @param name The public service name, e.g. app, auth, firestore, database\r\n * @param instanceFactory Service factory responsible for creating the public interface\r\n * @param type whether the service provided by the component is public or private\r\n */\r\n function Component(name, instanceFactory, type) {\r\n this.name = name;\r\n this.instanceFactory = instanceFactory;\r\n this.type = type;\r\n this.multipleInstances = false;\r\n /**\r\n * Properties to be added to the service namespace\r\n */\r\n this.serviceProps = {};\r\n this.instantiationMode = \"LAZY\" /* LAZY */;\r\n this.onInstanceCreated = null;\r\n }\r\n Component.prototype.setInstantiationMode = function (mode) {\r\n this.instantiationMode = mode;\r\n return this;\r\n };\r\n Component.prototype.setMultipleInstances = function (multipleInstances) {\r\n this.multipleInstances = multipleInstances;\r\n return this;\r\n };\r\n Component.prototype.setServiceProps = function (props) {\r\n this.serviceProps = props;\r\n return this;\r\n };\r\n Component.prototype.setInstanceCreatedCallback = function (callback) {\r\n this.onInstanceCreated = callback;\r\n return this;\r\n };\r\n return Component;\r\n}());\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar DEFAULT_ENTRY_NAME = '[DEFAULT]';\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Provider for instance for service name T, e.g. 'auth', 'auth-internal'\r\n * NameServiceMapping[T] is an alias for the type of the instance\r\n */\r\nvar Provider = /** @class */ (function () {\r\n function Provider(name, container) {\r\n this.name = name;\r\n this.container = container;\r\n this.component = null;\r\n this.instances = new Map();\r\n this.instancesDeferred = new Map();\r\n this.instancesOptions = new Map();\r\n this.onInitCallbacks = new Map();\r\n }\r\n /**\r\n * @param identifier A provider can provide mulitple instances of a service\r\n * if this.component.multipleInstances is true.\r\n */\r\n Provider.prototype.get = function (identifier) {\r\n // if multipleInstances is not supported, use the default name\r\n var normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\r\n if (!this.instancesDeferred.has(normalizedIdentifier)) {\r\n var deferred = new Deferred();\r\n this.instancesDeferred.set(normalizedIdentifier, deferred);\r\n if (this.isInitialized(normalizedIdentifier) ||\r\n this.shouldAutoInitialize()) {\r\n // initialize the service if it can be auto-initialized\r\n try {\r\n var instance = this.getOrInitializeService({\r\n instanceIdentifier: normalizedIdentifier\r\n });\r\n if (instance) {\r\n deferred.resolve(instance);\r\n }\r\n }\r\n catch (e) {\r\n // when the instance factory throws an exception during get(), it should not cause\r\n // a fatal error. We just return the unresolved promise in this case.\r\n }\r\n }\r\n }\r\n return this.instancesDeferred.get(normalizedIdentifier).promise;\r\n };\r\n Provider.prototype.getImmediate = function (options) {\r\n var _a;\r\n // if multipleInstances is not supported, use the default name\r\n var normalizedIdentifier = this.normalizeInstanceIdentifier(options === null || options === void 0 ? void 0 : options.identifier);\r\n var optional = (_a = options === null || options === void 0 ? void 0 : options.optional) !== null && _a !== void 0 ? _a : false;\r\n if (this.isInitialized(normalizedIdentifier) ||\r\n this.shouldAutoInitialize()) {\r\n try {\r\n return this.getOrInitializeService({\r\n instanceIdentifier: normalizedIdentifier\r\n });\r\n }\r\n catch (e) {\r\n if (optional) {\r\n return null;\r\n }\r\n else {\r\n throw e;\r\n }\r\n }\r\n }\r\n else {\r\n // In case a component is not initialized and should/can not be auto-initialized at the moment, return null if the optional flag is set, or throw\r\n if (optional) {\r\n return null;\r\n }\r\n else {\r\n throw Error(\"Service \" + this.name + \" is not available\");\r\n }\r\n }\r\n };\r\n Provider.prototype.getComponent = function () {\r\n return this.component;\r\n };\r\n Provider.prototype.setComponent = function (component) {\r\n var e_1, _a;\r\n if (component.name !== this.name) {\r\n throw Error(\"Mismatching Component \" + component.name + \" for Provider \" + this.name + \".\");\r\n }\r\n if (this.component) {\r\n throw Error(\"Component for \" + this.name + \" has already been provided\");\r\n }\r\n this.component = component;\r\n // return early without attempting to initialize the component if the component requires explicit initialization (calling `Provider.initialize()`)\r\n if (!this.shouldAutoInitialize()) {\r\n return;\r\n }\r\n // if the service is eager, initialize the default instance\r\n if (isComponentEager(component)) {\r\n try {\r\n this.getOrInitializeService({ instanceIdentifier: DEFAULT_ENTRY_NAME });\r\n }\r\n catch (e) {\r\n // when the instance factory for an eager Component throws an exception during the eager\r\n // initialization, it should not cause a fatal error.\r\n // TODO: Investigate if we need to make it configurable, because some component may want to cause\r\n // a fatal error in this case?\r\n }\r\n }\r\n try {\r\n // Create service instances for the pending promises and resolve them\r\n // NOTE: if this.multipleInstances is false, only the default instance will be created\r\n // and all promises with resolve with it regardless of the identifier.\r\n for (var _b = __values(this.instancesDeferred.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {\r\n var _d = __read(_c.value, 2), instanceIdentifier = _d[0], instanceDeferred = _d[1];\r\n var normalizedIdentifier = this.normalizeInstanceIdentifier(instanceIdentifier);\r\n try {\r\n // `getOrInitializeService()` should always return a valid instance since a component is guaranteed. use ! to make typescript happy.\r\n var instance = this.getOrInitializeService({\r\n instanceIdentifier: normalizedIdentifier\r\n });\r\n instanceDeferred.resolve(instance);\r\n }\r\n catch (e) {\r\n // when the instance factory throws an exception, it should not cause\r\n // a fatal error. We just leave the promise unresolved.\r\n }\r\n }\r\n }\r\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\r\n finally {\r\n try {\r\n if (_c && !_c.done && (_a = _b.return)) _a.call(_b);\r\n }\r\n finally { if (e_1) throw e_1.error; }\r\n }\r\n };\r\n Provider.prototype.clearInstance = function (identifier) {\r\n if (identifier === void 0) { identifier = DEFAULT_ENTRY_NAME; }\r\n this.instancesDeferred.delete(identifier);\r\n this.instancesOptions.delete(identifier);\r\n this.instances.delete(identifier);\r\n };\r\n // app.delete() will call this method on every provider to delete the services\r\n // TODO: should we mark the provider as deleted?\r\n Provider.prototype.delete = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var services;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n services = Array.from(this.instances.values());\r\n return [4 /*yield*/, Promise.all(__spreadArray(__spreadArray([], __read(services\r\n .filter(function (service) { return 'INTERNAL' in service; }) // legacy services\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n .map(function (service) { return service.INTERNAL.delete(); }))), __read(services\r\n .filter(function (service) { return '_delete' in service; }) // modularized services\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n .map(function (service) { return service._delete(); }))))];\r\n case 1:\r\n _a.sent();\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n Provider.prototype.isComponentSet = function () {\r\n return this.component != null;\r\n };\r\n Provider.prototype.isInitialized = function (identifier) {\r\n if (identifier === void 0) { identifier = DEFAULT_ENTRY_NAME; }\r\n return this.instances.has(identifier);\r\n };\r\n Provider.prototype.getOptions = function (identifier) {\r\n if (identifier === void 0) { identifier = DEFAULT_ENTRY_NAME; }\r\n return this.instancesOptions.get(identifier) || {};\r\n };\r\n Provider.prototype.initialize = function (opts) {\r\n var e_2, _a;\r\n if (opts === void 0) { opts = {}; }\r\n var _b = opts.options, options = _b === void 0 ? {} : _b;\r\n var normalizedIdentifier = this.normalizeInstanceIdentifier(opts.instanceIdentifier);\r\n if (this.isInitialized(normalizedIdentifier)) {\r\n throw Error(this.name + \"(\" + normalizedIdentifier + \") has already been initialized\");\r\n }\r\n if (!this.isComponentSet()) {\r\n throw Error(\"Component \" + this.name + \" has not been registered yet\");\r\n }\r\n var instance = this.getOrInitializeService({\r\n instanceIdentifier: normalizedIdentifier,\r\n options: options\r\n });\r\n try {\r\n // resolve any pending promise waiting for the service instance\r\n for (var _c = __values(this.instancesDeferred.entries()), _d = _c.next(); !_d.done; _d = _c.next()) {\r\n var _e = __read(_d.value, 2), instanceIdentifier = _e[0], instanceDeferred = _e[1];\r\n var normalizedDeferredIdentifier = this.normalizeInstanceIdentifier(instanceIdentifier);\r\n if (normalizedIdentifier === normalizedDeferredIdentifier) {\r\n instanceDeferred.resolve(instance);\r\n }\r\n }\r\n }\r\n catch (e_2_1) { e_2 = { error: e_2_1 }; }\r\n finally {\r\n try {\r\n if (_d && !_d.done && (_a = _c.return)) _a.call(_c);\r\n }\r\n finally { if (e_2) throw e_2.error; }\r\n }\r\n return instance;\r\n };\r\n /**\r\n *\r\n * @param callback - a function that will be invoked after the provider has been initialized by calling provider.initialize().\r\n * The function is invoked SYNCHRONOUSLY, so it should not execute any longrunning tasks in order to not block the program.\r\n *\r\n * @param identifier An optional instance identifier\r\n * @returns a function to unregister the callback\r\n */\r\n Provider.prototype.onInit = function (callback, identifier) {\r\n var _a;\r\n var normalizedIdentifier = this.normalizeInstanceIdentifier(identifier);\r\n var existingCallbacks = (_a = this.onInitCallbacks.get(normalizedIdentifier)) !== null && _a !== void 0 ? _a : new Set();\r\n existingCallbacks.add(callback);\r\n this.onInitCallbacks.set(normalizedIdentifier, existingCallbacks);\r\n var existingInstance = this.instances.get(normalizedIdentifier);\r\n if (existingInstance) {\r\n callback(existingInstance, normalizedIdentifier);\r\n }\r\n return function () {\r\n existingCallbacks.delete(callback);\r\n };\r\n };\r\n /**\r\n * Invoke onInit callbacks synchronously\r\n * @param instance the service instance`\r\n */\r\n Provider.prototype.invokeOnInitCallbacks = function (instance, identifier) {\r\n var e_3, _a;\r\n var callbacks = this.onInitCallbacks.get(identifier);\r\n if (!callbacks) {\r\n return;\r\n }\r\n try {\r\n for (var callbacks_1 = __values(callbacks), callbacks_1_1 = callbacks_1.next(); !callbacks_1_1.done; callbacks_1_1 = callbacks_1.next()) {\r\n var callback = callbacks_1_1.value;\r\n try {\r\n callback(instance, identifier);\r\n }\r\n catch (_b) {\r\n // ignore errors in the onInit callback\r\n }\r\n }\r\n }\r\n catch (e_3_1) { e_3 = { error: e_3_1 }; }\r\n finally {\r\n try {\r\n if (callbacks_1_1 && !callbacks_1_1.done && (_a = callbacks_1.return)) _a.call(callbacks_1);\r\n }\r\n finally { if (e_3) throw e_3.error; }\r\n }\r\n };\r\n Provider.prototype.getOrInitializeService = function (_a) {\r\n var instanceIdentifier = _a.instanceIdentifier, _b = _a.options, options = _b === void 0 ? {} : _b;\r\n var instance = this.instances.get(instanceIdentifier);\r\n if (!instance && this.component) {\r\n instance = this.component.instanceFactory(this.container, {\r\n instanceIdentifier: normalizeIdentifierForFactory(instanceIdentifier),\r\n options: options\r\n });\r\n this.instances.set(instanceIdentifier, instance);\r\n this.instancesOptions.set(instanceIdentifier, options);\r\n /**\r\n * Invoke onInit listeners.\r\n * Note this.component.onInstanceCreated is different, which is used by the component creator,\r\n * while onInit listeners are registered by consumers of the provider.\r\n */\r\n this.invokeOnInitCallbacks(instance, instanceIdentifier);\r\n /**\r\n * Order is important\r\n * onInstanceCreated() should be called after this.instances.set(instanceIdentifier, instance); which\r\n * makes `isInitialized()` return true.\r\n */\r\n if (this.component.onInstanceCreated) {\r\n try {\r\n this.component.onInstanceCreated(this.container, instanceIdentifier, instance);\r\n }\r\n catch (_c) {\r\n // ignore errors in the onInstanceCreatedCallback\r\n }\r\n }\r\n }\r\n return instance || null;\r\n };\r\n Provider.prototype.normalizeInstanceIdentifier = function (identifier) {\r\n if (identifier === void 0) { identifier = DEFAULT_ENTRY_NAME; }\r\n if (this.component) {\r\n return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME;\r\n }\r\n else {\r\n return identifier; // assume multiple instances are supported before the component is provided.\r\n }\r\n };\r\n Provider.prototype.shouldAutoInitialize = function () {\r\n return (!!this.component &&\r\n this.component.instantiationMode !== \"EXPLICIT\" /* EXPLICIT */);\r\n };\r\n return Provider;\r\n}());\r\n// undefined should be passed to the service factory for the default instance\r\nfunction normalizeIdentifierForFactory(identifier) {\r\n return identifier === DEFAULT_ENTRY_NAME ? undefined : identifier;\r\n}\r\nfunction isComponentEager(component) {\r\n return component.instantiationMode === \"EAGER\" /* EAGER */;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * ComponentContainer that provides Providers for service name T, e.g. `auth`, `auth-internal`\r\n */\r\nvar ComponentContainer = /** @class */ (function () {\r\n function ComponentContainer(name) {\r\n this.name = name;\r\n this.providers = new Map();\r\n }\r\n /**\r\n *\r\n * @param component Component being added\r\n * @param overwrite When a component with the same name has already been registered,\r\n * if overwrite is true: overwrite the existing component with the new component and create a new\r\n * provider with the new component. It can be useful in tests where you want to use different mocks\r\n * for different tests.\r\n * if overwrite is false: throw an exception\r\n */\r\n ComponentContainer.prototype.addComponent = function (component) {\r\n var provider = this.getProvider(component.name);\r\n if (provider.isComponentSet()) {\r\n throw new Error(\"Component \" + component.name + \" has already been registered with \" + this.name);\r\n }\r\n provider.setComponent(component);\r\n };\r\n ComponentContainer.prototype.addOrOverwriteComponent = function (component) {\r\n var provider = this.getProvider(component.name);\r\n if (provider.isComponentSet()) {\r\n // delete the existing provider from the container, so we can register the new component\r\n this.providers.delete(component.name);\r\n }\r\n this.addComponent(component);\r\n };\r\n /**\r\n * getProvider provides a type safe interface where it can only be called with a field name\r\n * present in NameServiceMapping interface.\r\n *\r\n * Firebase SDKs providing services should extend NameServiceMapping interface to register\r\n * themselves.\r\n */\r\n ComponentContainer.prototype.getProvider = function (name) {\r\n if (this.providers.has(name)) {\r\n return this.providers.get(name);\r\n }\r\n // create a Provider for a service that hasn't registered with Firebase\r\n var provider = new Provider(name, this);\r\n this.providers.set(name, provider);\r\n return provider;\r\n };\r\n ComponentContainer.prototype.getProviders = function () {\r\n return Array.from(this.providers.values());\r\n };\r\n return ComponentContainer;\r\n}());\n\n\n//# sourceMappingURL=index.esm.js.map\n\n;// CONCATENATED MODULE: ./node_modules/@firebase/logger/dist/index.esm.js\n/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n\r\nfunction index_esm_spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar _a;\r\n/**\r\n * A container for all of the Logger instances\r\n */\r\nvar instances = [];\r\n/**\r\n * The JS SDK supports 5 log levels and also allows a user the ability to\r\n * silence the logs altogether.\r\n *\r\n * The order is a follows:\r\n * DEBUG < VERBOSE < INFO < WARN < ERROR\r\n *\r\n * All of the log types above the current log level will be captured (i.e. if\r\n * you set the log level to `INFO`, errors will still be logged, but `DEBUG` and\r\n * `VERBOSE` logs will not)\r\n */\r\nvar LogLevel;\r\n(function (LogLevel) {\r\n LogLevel[LogLevel[\"DEBUG\"] = 0] = \"DEBUG\";\r\n LogLevel[LogLevel[\"VERBOSE\"] = 1] = \"VERBOSE\";\r\n LogLevel[LogLevel[\"INFO\"] = 2] = \"INFO\";\r\n LogLevel[LogLevel[\"WARN\"] = 3] = \"WARN\";\r\n LogLevel[LogLevel[\"ERROR\"] = 4] = \"ERROR\";\r\n LogLevel[LogLevel[\"SILENT\"] = 5] = \"SILENT\";\r\n})(LogLevel || (LogLevel = {}));\r\nvar levelStringToEnum = {\r\n 'debug': LogLevel.DEBUG,\r\n 'verbose': LogLevel.VERBOSE,\r\n 'info': LogLevel.INFO,\r\n 'warn': LogLevel.WARN,\r\n 'error': LogLevel.ERROR,\r\n 'silent': LogLevel.SILENT\r\n};\r\n/**\r\n * The default log level\r\n */\r\nvar defaultLogLevel = LogLevel.INFO;\r\n/**\r\n * By default, `console.debug` is not displayed in the developer console (in\r\n * chrome). To avoid forcing users to have to opt-in to these logs twice\r\n * (i.e. once for firebase, and once in the console), we are sending `DEBUG`\r\n * logs to the `console.log` function.\r\n */\r\nvar ConsoleMethod = (_a = {},\r\n _a[LogLevel.DEBUG] = 'log',\r\n _a[LogLevel.VERBOSE] = 'log',\r\n _a[LogLevel.INFO] = 'info',\r\n _a[LogLevel.WARN] = 'warn',\r\n _a[LogLevel.ERROR] = 'error',\r\n _a);\r\n/**\r\n * The default log handler will forward DEBUG, VERBOSE, INFO, WARN, and ERROR\r\n * messages on to their corresponding console counterparts (if the log method\r\n * is supported by the current log level)\r\n */\r\nvar defaultLogHandler = function (instance, logType) {\r\n var args = [];\r\n for (var _i = 2; _i < arguments.length; _i++) {\r\n args[_i - 2] = arguments[_i];\r\n }\r\n if (logType < instance.logLevel) {\r\n return;\r\n }\r\n var now = new Date().toISOString();\r\n var method = ConsoleMethod[logType];\r\n if (method) {\r\n console[method].apply(console, index_esm_spreadArrays([\"[\" + now + \"] \" + instance.name + \":\"], args));\r\n }\r\n else {\r\n throw new Error(\"Attempted to log a message with an invalid logType (value: \" + logType + \")\");\r\n }\r\n};\r\nvar Logger = /** @class */ (function () {\r\n /**\r\n * Gives you an instance of a Logger to capture messages according to\r\n * Firebase's logging scheme.\r\n *\r\n * @param name The name that the logs will be associated with\r\n */\r\n function Logger(name) {\r\n this.name = name;\r\n /**\r\n * The log level of the given Logger instance.\r\n */\r\n this._logLevel = defaultLogLevel;\r\n /**\r\n * The main (internal) log handler for the Logger instance.\r\n * Can be set to a new function in internal package code but not by user.\r\n */\r\n this._logHandler = defaultLogHandler;\r\n /**\r\n * The optional, additional, user-defined log handler for the Logger instance.\r\n */\r\n this._userLogHandler = null;\r\n /**\r\n * Capture the current instance for later use\r\n */\r\n instances.push(this);\r\n }\r\n Object.defineProperty(Logger.prototype, \"logLevel\", {\r\n get: function () {\r\n return this._logLevel;\r\n },\r\n set: function (val) {\r\n if (!(val in LogLevel)) {\r\n throw new TypeError(\"Invalid value \\\"\" + val + \"\\\" assigned to `logLevel`\");\r\n }\r\n this._logLevel = val;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n // Workaround for setter/getter having to be the same type.\r\n Logger.prototype.setLogLevel = function (val) {\r\n this._logLevel = typeof val === 'string' ? levelStringToEnum[val] : val;\r\n };\r\n Object.defineProperty(Logger.prototype, \"logHandler\", {\r\n get: function () {\r\n return this._logHandler;\r\n },\r\n set: function (val) {\r\n if (typeof val !== 'function') {\r\n throw new TypeError('Value assigned to `logHandler` must be a function');\r\n }\r\n this._logHandler = val;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n Object.defineProperty(Logger.prototype, \"userLogHandler\", {\r\n get: function () {\r\n return this._userLogHandler;\r\n },\r\n set: function (val) {\r\n this._userLogHandler = val;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n /**\r\n * The functions below are all based on the `console` interface\r\n */\r\n Logger.prototype.debug = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n this._userLogHandler && this._userLogHandler.apply(this, index_esm_spreadArrays([this, LogLevel.DEBUG], args));\r\n this._logHandler.apply(this, index_esm_spreadArrays([this, LogLevel.DEBUG], args));\r\n };\r\n Logger.prototype.log = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n this._userLogHandler && this._userLogHandler.apply(this, index_esm_spreadArrays([this, LogLevel.VERBOSE], args));\r\n this._logHandler.apply(this, index_esm_spreadArrays([this, LogLevel.VERBOSE], args));\r\n };\r\n Logger.prototype.info = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n this._userLogHandler && this._userLogHandler.apply(this, index_esm_spreadArrays([this, LogLevel.INFO], args));\r\n this._logHandler.apply(this, index_esm_spreadArrays([this, LogLevel.INFO], args));\r\n };\r\n Logger.prototype.warn = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n this._userLogHandler && this._userLogHandler.apply(this, index_esm_spreadArrays([this, LogLevel.WARN], args));\r\n this._logHandler.apply(this, index_esm_spreadArrays([this, LogLevel.WARN], args));\r\n };\r\n Logger.prototype.error = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n this._userLogHandler && this._userLogHandler.apply(this, index_esm_spreadArrays([this, LogLevel.ERROR], args));\r\n this._logHandler.apply(this, index_esm_spreadArrays([this, LogLevel.ERROR], args));\r\n };\r\n return Logger;\r\n}());\r\nfunction setLogLevel(level) {\r\n instances.forEach(function (inst) {\r\n inst.setLogLevel(level);\r\n });\r\n}\r\nfunction setUserLogHandler(logCallback, options) {\r\n var _loop_1 = function (instance) {\r\n var customLogLevel = null;\r\n if (options && options.level) {\r\n customLogLevel = levelStringToEnum[options.level];\r\n }\r\n if (logCallback === null) {\r\n instance.userLogHandler = null;\r\n }\r\n else {\r\n instance.userLogHandler = function (instance, level) {\r\n var args = [];\r\n for (var _i = 2; _i < arguments.length; _i++) {\r\n args[_i - 2] = arguments[_i];\r\n }\r\n var message = args\r\n .map(function (arg) {\r\n if (arg == null) {\r\n return null;\r\n }\r\n else if (typeof arg === 'string') {\r\n return arg;\r\n }\r\n else if (typeof arg === 'number' || typeof arg === 'boolean') {\r\n return arg.toString();\r\n }\r\n else if (arg instanceof Error) {\r\n return arg.message;\r\n }\r\n else {\r\n try {\r\n return JSON.stringify(arg);\r\n }\r\n catch (ignored) {\r\n return null;\r\n }\r\n }\r\n })\r\n .filter(function (arg) { return arg; })\r\n .join(' ');\r\n if (level >= (customLogLevel !== null && customLogLevel !== void 0 ? customLogLevel : instance.logLevel)) {\r\n logCallback({\r\n level: LogLevel[level].toLowerCase(),\r\n message: message,\r\n args: args,\r\n type: instance.name\r\n });\r\n }\r\n };\r\n }\r\n };\r\n for (var _i = 0, instances_1 = instances; _i < instances_1.length; _i++) {\r\n var instance = instances_1[_i];\r\n _loop_1(instance);\r\n }\r\n}\n\n\n//# sourceMappingURL=index.esm.js.map\n\n;// CONCATENATED MODULE: ./node_modules/@firebase/app/dist/index.esm.js\n\n\n\n\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar _a$1;\r\nvar ERRORS = (_a$1 = {},\r\n _a$1[\"no-app\" /* NO_APP */] = \"No Firebase App '{$appName}' has been created - \" +\r\n 'call Firebase App.initializeApp()',\r\n _a$1[\"bad-app-name\" /* BAD_APP_NAME */] = \"Illegal App name: '{$appName}\",\r\n _a$1[\"duplicate-app\" /* DUPLICATE_APP */] = \"Firebase App named '{$appName}' already exists\",\r\n _a$1[\"app-deleted\" /* APP_DELETED */] = \"Firebase App named '{$appName}' already deleted\",\r\n _a$1[\"invalid-app-argument\" /* INVALID_APP_ARGUMENT */] = 'firebase.{$appName}() takes either no argument or a ' +\r\n 'Firebase App instance.',\r\n _a$1[\"invalid-log-argument\" /* INVALID_LOG_ARGUMENT */] = 'First argument to `onLog` must be null or a function.',\r\n _a$1);\r\nvar ERROR_FACTORY = new ErrorFactory('app', 'Firebase', ERRORS);\n\nvar name$c = \"@firebase/app\";\nvar version$1 = \"0.6.30\";\n\nvar name$b = \"@firebase/analytics\";\n\nvar name$a = \"@firebase/app-check\";\n\nvar name$9 = \"@firebase/auth\";\n\nvar name$8 = \"@firebase/database\";\n\nvar name$7 = \"@firebase/functions\";\n\nvar name$6 = \"@firebase/installations\";\n\nvar name$5 = \"@firebase/messaging\";\n\nvar name$4 = \"@firebase/performance\";\n\nvar name$3 = \"@firebase/remote-config\";\n\nvar name$2 = \"@firebase/storage\";\n\nvar name$1 = \"@firebase/firestore\";\n\nvar index_esm_name = \"firebase-wrapper\";\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar index_esm_a;\r\nvar index_esm_DEFAULT_ENTRY_NAME = '[DEFAULT]';\r\nvar PLATFORM_LOG_STRING = (index_esm_a = {},\r\n index_esm_a[name$c] = 'fire-core',\r\n index_esm_a[name$b] = 'fire-analytics',\r\n index_esm_a[name$a] = 'fire-app-check',\r\n index_esm_a[name$9] = 'fire-auth',\r\n index_esm_a[name$8] = 'fire-rtdb',\r\n index_esm_a[name$7] = 'fire-fn',\r\n index_esm_a[name$6] = 'fire-iid',\r\n index_esm_a[name$5] = 'fire-fcm',\r\n index_esm_a[name$4] = 'fire-perf',\r\n index_esm_a[name$3] = 'fire-rc',\r\n index_esm_a[name$2] = 'fire-gcs',\r\n index_esm_a[name$1] = 'fire-fst',\r\n index_esm_a['fire-js'] = 'fire-js',\r\n index_esm_a[index_esm_name] = 'fire-js-all',\r\n index_esm_a);\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar logger = new Logger('@firebase/app');\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Global context object for a collection of services using\r\n * a shared authentication state.\r\n */\r\nvar FirebaseAppImpl = /** @class */ (function () {\r\n function FirebaseAppImpl(options, config, firebase_) {\r\n var _this = this;\r\n this.firebase_ = firebase_;\r\n this.isDeleted_ = false;\r\n this.name_ = config.name;\r\n this.automaticDataCollectionEnabled_ =\r\n config.automaticDataCollectionEnabled || false;\r\n this.options_ = deepCopy(options);\r\n this.container = new ComponentContainer(config.name);\r\n // add itself to container\r\n this._addComponent(new Component('app', function () { return _this; }, \"PUBLIC\" /* PUBLIC */));\r\n // populate ComponentContainer with existing components\r\n this.firebase_.INTERNAL.components.forEach(function (component) {\r\n return _this._addComponent(component);\r\n });\r\n }\r\n Object.defineProperty(FirebaseAppImpl.prototype, \"automaticDataCollectionEnabled\", {\r\n get: function () {\r\n this.checkDestroyed_();\r\n return this.automaticDataCollectionEnabled_;\r\n },\r\n set: function (val) {\r\n this.checkDestroyed_();\r\n this.automaticDataCollectionEnabled_ = val;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n Object.defineProperty(FirebaseAppImpl.prototype, \"name\", {\r\n get: function () {\r\n this.checkDestroyed_();\r\n return this.name_;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n Object.defineProperty(FirebaseAppImpl.prototype, \"options\", {\r\n get: function () {\r\n this.checkDestroyed_();\r\n return this.options_;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n FirebaseAppImpl.prototype.delete = function () {\r\n var _this = this;\r\n return new Promise(function (resolve) {\r\n _this.checkDestroyed_();\r\n resolve();\r\n })\r\n .then(function () {\r\n _this.firebase_.INTERNAL.removeApp(_this.name_);\r\n return Promise.all(_this.container.getProviders().map(function (provider) { return provider.delete(); }));\r\n })\r\n .then(function () {\r\n _this.isDeleted_ = true;\r\n });\r\n };\r\n /**\r\n * Return a service instance associated with this app (creating it\r\n * on demand), identified by the passed instanceIdentifier.\r\n *\r\n * NOTE: Currently storage and functions are the only ones that are leveraging this\r\n * functionality. They invoke it by calling:\r\n *\r\n * ```javascript\r\n * firebase.app().storage('STORAGE BUCKET ID')\r\n * ```\r\n *\r\n * The service name is passed to this already\r\n * @internal\r\n */\r\n FirebaseAppImpl.prototype._getService = function (name, instanceIdentifier) {\r\n var _a;\r\n if (instanceIdentifier === void 0) { instanceIdentifier = index_esm_DEFAULT_ENTRY_NAME; }\r\n this.checkDestroyed_();\r\n // Initialize instance if InstatiationMode is `EXPLICIT`.\r\n var provider = this.container.getProvider(name);\r\n if (!provider.isInitialized() &&\r\n ((_a = provider.getComponent()) === null || _a === void 0 ? void 0 : _a.instantiationMode) === \"EXPLICIT\" /* EXPLICIT */) {\r\n provider.initialize();\r\n }\r\n // getImmediate will always succeed because _getService is only called for registered components.\r\n return provider.getImmediate({\r\n identifier: instanceIdentifier\r\n });\r\n };\r\n /**\r\n * Remove a service instance from the cache, so we will create a new instance for this service\r\n * when people try to get this service again.\r\n *\r\n * NOTE: currently only firestore is using this functionality to support firestore shutdown.\r\n *\r\n * @param name The service name\r\n * @param instanceIdentifier instance identifier in case multiple instances are allowed\r\n * @internal\r\n */\r\n FirebaseAppImpl.prototype._removeServiceInstance = function (name, instanceIdentifier) {\r\n if (instanceIdentifier === void 0) { instanceIdentifier = index_esm_DEFAULT_ENTRY_NAME; }\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n this.container.getProvider(name).clearInstance(instanceIdentifier);\r\n };\r\n /**\r\n * @param component the component being added to this app's container\r\n */\r\n FirebaseAppImpl.prototype._addComponent = function (component) {\r\n try {\r\n this.container.addComponent(component);\r\n }\r\n catch (e) {\r\n logger.debug(\"Component \" + component.name + \" failed to register with FirebaseApp \" + this.name, e);\r\n }\r\n };\r\n FirebaseAppImpl.prototype._addOrOverwriteComponent = function (component) {\r\n this.container.addOrOverwriteComponent(component);\r\n };\r\n FirebaseAppImpl.prototype.toJSON = function () {\r\n return {\r\n name: this.name,\r\n automaticDataCollectionEnabled: this.automaticDataCollectionEnabled,\r\n options: this.options\r\n };\r\n };\r\n /**\r\n * This function will throw an Error if the App has already been deleted -\r\n * use before performing API actions on the App.\r\n */\r\n FirebaseAppImpl.prototype.checkDestroyed_ = function () {\r\n if (this.isDeleted_) {\r\n throw ERROR_FACTORY.create(\"app-deleted\" /* APP_DELETED */, { appName: this.name_ });\r\n }\r\n };\r\n return FirebaseAppImpl;\r\n}());\r\n// Prevent dead-code elimination of these methods w/o invalid property\r\n// copying.\r\n(FirebaseAppImpl.prototype.name && FirebaseAppImpl.prototype.options) ||\r\n FirebaseAppImpl.prototype.delete ||\r\n console.log('dc');\n\nvar version = \"8.10.0\";\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Because auth can't share code with other components, we attach the utility functions\r\n * in an internal namespace to share code.\r\n * This function return a firebase namespace object without\r\n * any utility functions, so it can be shared between the regular firebaseNamespace and\r\n * the lite version.\r\n */\r\nfunction createFirebaseNamespaceCore(firebaseAppImpl) {\r\n var apps = {};\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n var components = new Map();\r\n // A namespace is a plain JavaScript Object.\r\n var namespace = {\r\n // Hack to prevent Babel from modifying the object returned\r\n // as the firebase namespace.\r\n // @ts-ignore\r\n __esModule: true,\r\n initializeApp: initializeApp,\r\n // @ts-ignore\r\n app: app,\r\n registerVersion: registerVersion,\r\n setLogLevel: setLogLevel,\r\n onLog: onLog,\r\n // @ts-ignore\r\n apps: null,\r\n SDK_VERSION: version,\r\n INTERNAL: {\r\n registerComponent: registerComponent,\r\n removeApp: removeApp,\r\n components: components,\r\n useAsService: useAsService\r\n }\r\n };\r\n // Inject a circular default export to allow Babel users who were previously\r\n // using:\r\n //\r\n // import firebase from 'firebase';\r\n // which becomes: var firebase = require('firebase').default;\r\n //\r\n // instead of\r\n //\r\n // import * as firebase from 'firebase';\r\n // which becomes: var firebase = require('firebase');\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n namespace['default'] = namespace;\r\n // firebase.apps is a read-only getter.\r\n Object.defineProperty(namespace, 'apps', {\r\n get: getApps\r\n });\r\n /**\r\n * Called by App.delete() - but before any services associated with the App\r\n * are deleted.\r\n */\r\n function removeApp(name) {\r\n delete apps[name];\r\n }\r\n /**\r\n * Get the App object for a given name (or DEFAULT).\r\n */\r\n function app(name) {\r\n name = name || index_esm_DEFAULT_ENTRY_NAME;\r\n if (!contains(apps, name)) {\r\n throw ERROR_FACTORY.create(\"no-app\" /* NO_APP */, { appName: name });\r\n }\r\n return apps[name];\r\n }\r\n // @ts-ignore\r\n app['App'] = firebaseAppImpl;\r\n function initializeApp(options, rawConfig) {\r\n if (rawConfig === void 0) { rawConfig = {}; }\r\n if (typeof rawConfig !== 'object' || rawConfig === null) {\r\n var name_1 = rawConfig;\r\n rawConfig = { name: name_1 };\r\n }\r\n var config = rawConfig;\r\n if (config.name === undefined) {\r\n config.name = index_esm_DEFAULT_ENTRY_NAME;\r\n }\r\n var name = config.name;\r\n if (typeof name !== 'string' || !name) {\r\n throw ERROR_FACTORY.create(\"bad-app-name\" /* BAD_APP_NAME */, {\r\n appName: String(name)\r\n });\r\n }\r\n if (contains(apps, name)) {\r\n throw ERROR_FACTORY.create(\"duplicate-app\" /* DUPLICATE_APP */, { appName: name });\r\n }\r\n var app = new firebaseAppImpl(options, config, namespace);\r\n apps[name] = app;\r\n return app;\r\n }\r\n /*\r\n * Return an array of all the non-deleted FirebaseApps.\r\n */\r\n function getApps() {\r\n // Make a copy so caller cannot mutate the apps list.\r\n return Object.keys(apps).map(function (name) { return apps[name]; });\r\n }\r\n function registerComponent(component) {\r\n var componentName = component.name;\r\n if (components.has(componentName)) {\r\n logger.debug(\"There were multiple attempts to register component \" + componentName + \".\");\r\n return component.type === \"PUBLIC\" /* PUBLIC */\r\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n namespace[componentName]\r\n : null;\r\n }\r\n components.set(componentName, component);\r\n // create service namespace for public components\r\n if (component.type === \"PUBLIC\" /* PUBLIC */) {\r\n // The Service namespace is an accessor function ...\r\n var serviceNamespace = function (appArg) {\r\n if (appArg === void 0) { appArg = app(); }\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n if (typeof appArg[componentName] !== 'function') {\r\n // Invalid argument.\r\n // This happens in the following case: firebase.storage('gs:/')\r\n throw ERROR_FACTORY.create(\"invalid-app-argument\" /* INVALID_APP_ARGUMENT */, {\r\n appName: componentName\r\n });\r\n }\r\n // Forward service instance lookup to the FirebaseApp.\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return appArg[componentName]();\r\n };\r\n // ... and a container for service-level properties.\r\n if (component.serviceProps !== undefined) {\r\n deepExtend(serviceNamespace, component.serviceProps);\r\n }\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n namespace[componentName] = serviceNamespace;\r\n // Patch the FirebaseAppImpl prototype\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n firebaseAppImpl.prototype[componentName] =\r\n // TODO: The eslint disable can be removed and the 'ignoreRestArgs'\r\n // option added to the no-explicit-any rule when ESlint releases it.\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n var serviceFxn = this._getService.bind(this, componentName);\r\n return serviceFxn.apply(this, component.multipleInstances ? args : []);\r\n };\r\n }\r\n // add the component to existing app instances\r\n for (var _i = 0, _a = Object.keys(apps); _i < _a.length; _i++) {\r\n var appName = _a[_i];\r\n apps[appName]._addComponent(component);\r\n }\r\n return component.type === \"PUBLIC\" /* PUBLIC */\r\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n namespace[componentName]\r\n : null;\r\n }\r\n function registerVersion(libraryKeyOrName, version, variant) {\r\n var _a;\r\n // TODO: We can use this check to whitelist strings when/if we set up\r\n // a good whitelist system.\r\n var library = (_a = PLATFORM_LOG_STRING[libraryKeyOrName]) !== null && _a !== void 0 ? _a : libraryKeyOrName;\r\n if (variant) {\r\n library += \"-\" + variant;\r\n }\r\n var libraryMismatch = library.match(/\\s|\\//);\r\n var versionMismatch = version.match(/\\s|\\//);\r\n if (libraryMismatch || versionMismatch) {\r\n var warning = [\r\n \"Unable to register library \\\"\" + library + \"\\\" with version \\\"\" + version + \"\\\":\"\r\n ];\r\n if (libraryMismatch) {\r\n warning.push(\"library name \\\"\" + library + \"\\\" contains illegal characters (whitespace or \\\"/\\\")\");\r\n }\r\n if (libraryMismatch && versionMismatch) {\r\n warning.push('and');\r\n }\r\n if (versionMismatch) {\r\n warning.push(\"version name \\\"\" + version + \"\\\" contains illegal characters (whitespace or \\\"/\\\")\");\r\n }\r\n logger.warn(warning.join(' '));\r\n return;\r\n }\r\n registerComponent(new Component(library + \"-version\", function () { return ({ library: library, version: version }); }, \"VERSION\" /* VERSION */));\r\n }\r\n function onLog(logCallback, options) {\r\n if (logCallback !== null && typeof logCallback !== 'function') {\r\n throw ERROR_FACTORY.create(\"invalid-log-argument\" /* INVALID_LOG_ARGUMENT */);\r\n }\r\n setUserLogHandler(logCallback, options);\r\n }\r\n // Map the requested service to a registered service name\r\n // (used to map auth to serverAuth service when needed).\r\n function useAsService(app, name) {\r\n if (name === 'serverAuth') {\r\n return null;\r\n }\r\n var useService = name;\r\n return useService;\r\n }\r\n return namespace;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Return a firebase namespace object.\r\n *\r\n * In production, this will be called exactly once and the result\r\n * assigned to the 'firebase' global. It may be called multiple times\r\n * in unit tests.\r\n */\r\nfunction createFirebaseNamespace() {\r\n var namespace = createFirebaseNamespaceCore(FirebaseAppImpl);\r\n namespace.INTERNAL = tslib_es6_assign(tslib_es6_assign({}, namespace.INTERNAL), { createFirebaseNamespace: createFirebaseNamespace,\r\n extendNamespace: extendNamespace,\r\n createSubscribe: createSubscribe,\r\n ErrorFactory: ErrorFactory,\r\n deepExtend: deepExtend });\r\n /**\r\n * Patch the top-level firebase namespace with additional properties.\r\n *\r\n * firebase.INTERNAL.extendNamespace()\r\n */\r\n function extendNamespace(props) {\r\n deepExtend(namespace, props);\r\n }\r\n return namespace;\r\n}\r\nvar firebase$1 = createFirebaseNamespace();\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar PlatformLoggerService = /** @class */ (function () {\r\n function PlatformLoggerService(container) {\r\n this.container = container;\r\n }\r\n // In initial implementation, this will be called by installations on\r\n // auth token refresh, and installations will send this string.\r\n PlatformLoggerService.prototype.getPlatformInfoString = function () {\r\n var providers = this.container.getProviders();\r\n // Loop through providers and get library/version pairs from any that are\r\n // version components.\r\n return providers\r\n .map(function (provider) {\r\n if (isVersionServiceProvider(provider)) {\r\n var service = provider.getImmediate();\r\n return service.library + \"/\" + service.version;\r\n }\r\n else {\r\n return null;\r\n }\r\n })\r\n .filter(function (logString) { return logString; })\r\n .join(' ');\r\n };\r\n return PlatformLoggerService;\r\n}());\r\n/**\r\n *\r\n * @param provider check if this provider provides a VersionService\r\n *\r\n * NOTE: Using Provider<'app-version'> is a hack to indicate that the provider\r\n * provides VersionService. The provider is not necessarily a 'app-version'\r\n * provider.\r\n */\r\nfunction isVersionServiceProvider(provider) {\r\n var component = provider.getComponent();\r\n return (component === null || component === void 0 ? void 0 : component.type) === \"VERSION\" /* VERSION */;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction registerCoreComponents(firebase, variant) {\r\n firebase.INTERNAL.registerComponent(new Component('platform-logger', function (container) { return new PlatformLoggerService(container); }, \"PRIVATE\" /* PRIVATE */));\r\n // Register `app` package.\r\n firebase.registerVersion(name$c, version$1, variant);\r\n // Register platform SDK identifier (no version).\r\n firebase.registerVersion('fire-js', '');\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n// Firebase Lite detection test\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nif (isBrowser() && self.firebase !== undefined) {\r\n logger.warn(\"\\n Warning: Firebase is already defined in the global scope. Please make sure\\n Firebase library is only loaded once.\\n \");\r\n // eslint-disable-next-line\r\n var sdkVersion = self.firebase.SDK_VERSION;\r\n if (sdkVersion && sdkVersion.indexOf('LITE') >= 0) {\r\n logger.warn(\"\\n Warning: You are trying to load Firebase while using Firebase Performance standalone script.\\n You should load Firebase Performance with this instance of Firebase to avoid loading duplicate code.\\n \");\r\n }\r\n}\r\nvar initializeApp = firebase$1.initializeApp;\r\n// TODO: This disable can be removed and the 'ignoreRestArgs' option added to\r\n// the no-explicit-any rule when ESlint releases it.\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nfirebase$1.initializeApp = function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n // Environment check before initializing app\r\n // Do the check in initializeApp, so people have a chance to disable it by setting logLevel\r\n // in @firebase/logger\r\n if (isNode()) {\r\n logger.warn(\"\\n Warning: This is a browser-targeted Firebase bundle but it appears it is being\\n run in a Node environment. If running in a Node environment, make sure you\\n are using the bundle specified by the \\\"main\\\" field in package.json.\\n \\n If you are using Webpack, you can specify \\\"main\\\" as the first item in\\n \\\"resolve.mainFields\\\":\\n https://webpack.js.org/configuration/resolve/#resolvemainfields\\n \\n If using Rollup, use the @rollup/plugin-node-resolve plugin and specify \\\"main\\\"\\n as the first item in \\\"mainFields\\\", e.g. ['main', 'module'].\\n https://github.com/rollup/@rollup/plugin-node-resolve\\n \");\r\n }\r\n return initializeApp.apply(undefined, args);\r\n};\r\nvar firebase = firebase$1;\r\nregisterCoreComponents(firebase);\n\n/* harmony default export */ const index_esm = (firebase);\n\n//# sourceMappingURL=index.esm.js.map\n\n;// CONCATENATED MODULE: ./node_modules/firebase/app/dist/index.esm.js\n\n\n\nvar dist_index_esm_name = \"firebase\";\nvar index_esm_version = \"8.10.1\";\n\n/**\r\n * @license\r\n * Copyright 2018 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nindex_esm.registerVersion(dist_index_esm_name, index_esm_version, 'app');\r\nindex_esm.SDK_VERSION = index_esm_version;\n//# sourceMappingURL=index.esm.js.map\n\n// EXTERNAL MODULE: ./node_modules/idb/build/idb.js\nvar idb = __webpack_require__(8676);\n;// CONCATENATED MODULE: ./node_modules/@firebase/installations/dist/index.esm.js\n\n\n\n\n\n\nvar installations_dist_index_esm_name = \"@firebase/installations\";\nvar dist_index_esm_version = \"0.4.32\";\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar PENDING_TIMEOUT_MS = 10000;\r\nvar PACKAGE_VERSION = \"w:\" + dist_index_esm_version;\r\nvar INTERNAL_AUTH_VERSION = 'FIS_v2';\r\nvar INSTALLATIONS_API_URL = 'https://firebaseinstallations.googleapis.com/v1';\r\nvar TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour\r\nvar SERVICE = 'installations';\r\nvar SERVICE_NAME = 'Installations';\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar dist_index_esm_a;\r\nvar ERROR_DESCRIPTION_MAP = (dist_index_esm_a = {},\r\n dist_index_esm_a[\"missing-app-config-values\" /* MISSING_APP_CONFIG_VALUES */] = 'Missing App configuration value: \"{$valueName}\"',\r\n dist_index_esm_a[\"not-registered\" /* NOT_REGISTERED */] = 'Firebase Installation is not registered.',\r\n dist_index_esm_a[\"installation-not-found\" /* INSTALLATION_NOT_FOUND */] = 'Firebase Installation not found.',\r\n dist_index_esm_a[\"request-failed\" /* REQUEST_FAILED */] = '{$requestName} request failed with error \"{$serverCode} {$serverStatus}: {$serverMessage}\"',\r\n dist_index_esm_a[\"app-offline\" /* APP_OFFLINE */] = 'Could not process request. Application offline.',\r\n dist_index_esm_a[\"delete-pending-registration\" /* DELETE_PENDING_REGISTRATION */] = \"Can't delete installation while there is a pending registration request.\",\r\n dist_index_esm_a);\r\nvar index_esm_ERROR_FACTORY = new ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP);\r\n/** Returns true if error is a FirebaseError that is based on an error from the server. */\r\nfunction isServerError(error) {\r\n return (error instanceof FirebaseError &&\r\n error.code.includes(\"request-failed\" /* REQUEST_FAILED */));\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction getInstallationsEndpoint(_a) {\r\n var projectId = _a.projectId;\r\n return INSTALLATIONS_API_URL + \"/projects/\" + projectId + \"/installations\";\r\n}\r\nfunction extractAuthTokenInfoFromResponse(response) {\r\n return {\r\n token: response.token,\r\n requestStatus: 2 /* COMPLETED */,\r\n expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),\r\n creationTime: Date.now()\r\n };\r\n}\r\nfunction getErrorFromResponse(requestName, response) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var responseJson, errorData;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, response.json()];\r\n case 1:\r\n responseJson = _a.sent();\r\n errorData = responseJson.error;\r\n return [2 /*return*/, index_esm_ERROR_FACTORY.create(\"request-failed\" /* REQUEST_FAILED */, {\r\n requestName: requestName,\r\n serverCode: errorData.code,\r\n serverMessage: errorData.message,\r\n serverStatus: errorData.status\r\n })];\r\n }\r\n });\r\n });\r\n}\r\nfunction getHeaders(_a) {\r\n var apiKey = _a.apiKey;\r\n return new Headers({\r\n 'Content-Type': 'application/json',\r\n Accept: 'application/json',\r\n 'x-goog-api-key': apiKey\r\n });\r\n}\r\nfunction getHeadersWithAuth(appConfig, _a) {\r\n var refreshToken = _a.refreshToken;\r\n var headers = getHeaders(appConfig);\r\n headers.append('Authorization', getAuthorizationHeader(refreshToken));\r\n return headers;\r\n}\r\n/**\r\n * Calls the passed in fetch wrapper and returns the response.\r\n * If the returned response has a status of 5xx, re-runs the function once and\r\n * returns the response.\r\n */\r\nfunction retryIfServerError(fn) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var result;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, fn()];\r\n case 1:\r\n result = _a.sent();\r\n if (result.status >= 500 && result.status < 600) {\r\n // Internal Server Error. Retry request.\r\n return [2 /*return*/, fn()];\r\n }\r\n return [2 /*return*/, result];\r\n }\r\n });\r\n });\r\n}\r\nfunction getExpiresInFromResponseExpiresIn(responseExpiresIn) {\r\n // This works because the server will never respond with fractions of a second.\r\n return Number(responseExpiresIn.replace('s', '000'));\r\n}\r\nfunction getAuthorizationHeader(refreshToken) {\r\n return INTERNAL_AUTH_VERSION + \" \" + refreshToken;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction createInstallationRequest(appConfig, _a) {\r\n var fid = _a.fid;\r\n return __awaiter(this, void 0, void 0, function () {\r\n var endpoint, headers, body, request, response, responseValue, registeredInstallationEntry;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0:\r\n endpoint = getInstallationsEndpoint(appConfig);\r\n headers = getHeaders(appConfig);\r\n body = {\r\n fid: fid,\r\n authVersion: INTERNAL_AUTH_VERSION,\r\n appId: appConfig.appId,\r\n sdkVersion: PACKAGE_VERSION\r\n };\r\n request = {\r\n method: 'POST',\r\n headers: headers,\r\n body: JSON.stringify(body)\r\n };\r\n return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];\r\n case 1:\r\n response = _b.sent();\r\n if (!response.ok) return [3 /*break*/, 3];\r\n return [4 /*yield*/, response.json()];\r\n case 2:\r\n responseValue = _b.sent();\r\n registeredInstallationEntry = {\r\n fid: responseValue.fid || fid,\r\n registrationStatus: 2 /* COMPLETED */,\r\n refreshToken: responseValue.refreshToken,\r\n authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)\r\n };\r\n return [2 /*return*/, registeredInstallationEntry];\r\n case 3: return [4 /*yield*/, getErrorFromResponse('Create Installation', response)];\r\n case 4: throw _b.sent();\r\n }\r\n });\r\n });\r\n}\n\n/**\r\n * @license\r\n * Copyright 2020 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/** Returns a promise that resolves after given time passes. */\r\nfunction sleep(ms) {\r\n return new Promise(function (resolve) {\r\n setTimeout(resolve, ms);\r\n });\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction bufferToBase64UrlSafe(array) {\r\n var b64 = btoa(String.fromCharCode.apply(String, __spreadArray([], __read(array))));\r\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_');\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar VALID_FID_PATTERN = /^[cdef][\\w-]{21}$/;\r\nvar INVALID_FID = '';\r\n/**\r\n * Generates a new FID using random values from Web Crypto API.\r\n * Returns an empty string if FID generation fails for any reason.\r\n */\r\nfunction generateFid() {\r\n try {\r\n // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5\r\n // bytes. our implementation generates a 17 byte array instead.\r\n var fidByteArray = new Uint8Array(17);\r\n var crypto_1 = self.crypto || self.msCrypto;\r\n crypto_1.getRandomValues(fidByteArray);\r\n // Replace the first 4 random bits with the constant FID header of 0b0111.\r\n fidByteArray[0] = 112 + (fidByteArray[0] % 16);\r\n var fid = encode(fidByteArray);\r\n return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;\r\n }\r\n catch (_a) {\r\n // FID generation errored\r\n return INVALID_FID;\r\n }\r\n}\r\n/** Converts a FID Uint8Array to a base64 string representation. */\r\nfunction encode(fidByteArray) {\r\n var b64String = bufferToBase64UrlSafe(fidByteArray);\r\n // Remove the 23rd character that was added because of the extra 4 bits at the\r\n // end of our 17 byte array, and the '=' padding.\r\n return b64String.substr(0, 22);\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/** Returns a string key that can be used to identify the app. */\r\nfunction getKey(appConfig) {\r\n return appConfig.appName + \"!\" + appConfig.appId;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar fidChangeCallbacks = new Map();\r\n/**\r\n * Calls the onIdChange callbacks with the new FID value, and broadcasts the\r\n * change to other tabs.\r\n */\r\nfunction fidChanged(appConfig, fid) {\r\n var key = getKey(appConfig);\r\n callFidChangeCallbacks(key, fid);\r\n broadcastFidChange(key, fid);\r\n}\r\nfunction addCallback(appConfig, callback) {\r\n // Open the broadcast channel if it's not already open,\r\n // to be able to listen to change events from other tabs.\r\n getBroadcastChannel();\r\n var key = getKey(appConfig);\r\n var callbackSet = fidChangeCallbacks.get(key);\r\n if (!callbackSet) {\r\n callbackSet = new Set();\r\n fidChangeCallbacks.set(key, callbackSet);\r\n }\r\n callbackSet.add(callback);\r\n}\r\nfunction removeCallback(appConfig, callback) {\r\n var key = getKey(appConfig);\r\n var callbackSet = fidChangeCallbacks.get(key);\r\n if (!callbackSet) {\r\n return;\r\n }\r\n callbackSet.delete(callback);\r\n if (callbackSet.size === 0) {\r\n fidChangeCallbacks.delete(key);\r\n }\r\n // Close broadcast channel if there are no more callbacks.\r\n closeBroadcastChannel();\r\n}\r\nfunction callFidChangeCallbacks(key, fid) {\r\n var e_1, _a;\r\n var callbacks = fidChangeCallbacks.get(key);\r\n if (!callbacks) {\r\n return;\r\n }\r\n try {\r\n for (var callbacks_1 = __values(callbacks), callbacks_1_1 = callbacks_1.next(); !callbacks_1_1.done; callbacks_1_1 = callbacks_1.next()) {\r\n var callback = callbacks_1_1.value;\r\n callback(fid);\r\n }\r\n }\r\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\r\n finally {\r\n try {\r\n if (callbacks_1_1 && !callbacks_1_1.done && (_a = callbacks_1.return)) _a.call(callbacks_1);\r\n }\r\n finally { if (e_1) throw e_1.error; }\r\n }\r\n}\r\nfunction broadcastFidChange(key, fid) {\r\n var channel = getBroadcastChannel();\r\n if (channel) {\r\n channel.postMessage({ key: key, fid: fid });\r\n }\r\n closeBroadcastChannel();\r\n}\r\nvar broadcastChannel = null;\r\n/** Opens and returns a BroadcastChannel if it is supported by the browser. */\r\nfunction getBroadcastChannel() {\r\n if (!broadcastChannel && 'BroadcastChannel' in self) {\r\n broadcastChannel = new BroadcastChannel('[Firebase] FID Change');\r\n broadcastChannel.onmessage = function (e) {\r\n callFidChangeCallbacks(e.data.key, e.data.fid);\r\n };\r\n }\r\n return broadcastChannel;\r\n}\r\nfunction closeBroadcastChannel() {\r\n if (fidChangeCallbacks.size === 0 && broadcastChannel) {\r\n broadcastChannel.close();\r\n broadcastChannel = null;\r\n }\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar DATABASE_NAME = 'firebase-installations-database';\r\nvar DATABASE_VERSION = 1;\r\nvar OBJECT_STORE_NAME = 'firebase-installations-store';\r\nvar dbPromise = null;\r\nfunction getDbPromise() {\r\n if (!dbPromise) {\r\n dbPromise = (0,idb.openDb)(DATABASE_NAME, DATABASE_VERSION, function (upgradeDB) {\r\n // We don't use 'break' in this switch statement, the fall-through\r\n // behavior is what we want, because if there are multiple versions between\r\n // the old version and the current version, we want ALL the migrations\r\n // that correspond to those versions to run, not only the last one.\r\n // eslint-disable-next-line default-case\r\n switch (upgradeDB.oldVersion) {\r\n case 0:\r\n upgradeDB.createObjectStore(OBJECT_STORE_NAME);\r\n }\r\n });\r\n }\r\n return dbPromise;\r\n}\r\n/** Assigns or overwrites the record for the given key with the given value. */\r\nfunction set(appConfig, value) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var key, db, tx, objectStore, oldValue;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n key = getKey(appConfig);\r\n return [4 /*yield*/, getDbPromise()];\r\n case 1:\r\n db = _a.sent();\r\n tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\r\n objectStore = tx.objectStore(OBJECT_STORE_NAME);\r\n return [4 /*yield*/, objectStore.get(key)];\r\n case 2:\r\n oldValue = _a.sent();\r\n return [4 /*yield*/, objectStore.put(value, key)];\r\n case 3:\r\n _a.sent();\r\n return [4 /*yield*/, tx.complete];\r\n case 4:\r\n _a.sent();\r\n if (!oldValue || oldValue.fid !== value.fid) {\r\n fidChanged(appConfig, value.fid);\r\n }\r\n return [2 /*return*/, value];\r\n }\r\n });\r\n });\r\n}\r\n/** Removes record(s) from the objectStore that match the given key. */\r\nfunction index_esm_remove(appConfig) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var key, db, tx;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n key = getKey(appConfig);\r\n return [4 /*yield*/, getDbPromise()];\r\n case 1:\r\n db = _a.sent();\r\n tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\r\n return [4 /*yield*/, tx.objectStore(OBJECT_STORE_NAME).delete(key)];\r\n case 2:\r\n _a.sent();\r\n return [4 /*yield*/, tx.complete];\r\n case 3:\r\n _a.sent();\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\r\n/**\r\n * Atomically updates a record with the result of updateFn, which gets\r\n * called with the current value. If newValue is undefined, the record is\r\n * deleted instead.\r\n * @return Updated value\r\n */\r\nfunction update(appConfig, updateFn) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var key, db, tx, store, oldValue, newValue;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n key = getKey(appConfig);\r\n return [4 /*yield*/, getDbPromise()];\r\n case 1:\r\n db = _a.sent();\r\n tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\r\n store = tx.objectStore(OBJECT_STORE_NAME);\r\n return [4 /*yield*/, store.get(key)];\r\n case 2:\r\n oldValue = _a.sent();\r\n newValue = updateFn(oldValue);\r\n if (!(newValue === undefined)) return [3 /*break*/, 4];\r\n return [4 /*yield*/, store.delete(key)];\r\n case 3:\r\n _a.sent();\r\n return [3 /*break*/, 6];\r\n case 4: return [4 /*yield*/, store.put(newValue, key)];\r\n case 5:\r\n _a.sent();\r\n _a.label = 6;\r\n case 6: return [4 /*yield*/, tx.complete];\r\n case 7:\r\n _a.sent();\r\n if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {\r\n fidChanged(appConfig, newValue.fid);\r\n }\r\n return [2 /*return*/, newValue];\r\n }\r\n });\r\n });\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Updates and returns the InstallationEntry from the database.\r\n * Also triggers a registration request if it is necessary and possible.\r\n */\r\nfunction getInstallationEntry(appConfig) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var registrationPromise, installationEntry;\r\n var _a;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0: return [4 /*yield*/, update(appConfig, function (oldEntry) {\r\n var installationEntry = updateOrCreateInstallationEntry(oldEntry);\r\n var entryWithPromise = triggerRegistrationIfNecessary(appConfig, installationEntry);\r\n registrationPromise = entryWithPromise.registrationPromise;\r\n return entryWithPromise.installationEntry;\r\n })];\r\n case 1:\r\n installationEntry = _b.sent();\r\n if (!(installationEntry.fid === INVALID_FID)) return [3 /*break*/, 3];\r\n _a = {};\r\n return [4 /*yield*/, registrationPromise];\r\n case 2: \r\n // FID generation failed. Waiting for the FID from the server.\r\n return [2 /*return*/, (_a.installationEntry = _b.sent(), _a)];\r\n case 3: return [2 /*return*/, {\r\n installationEntry: installationEntry,\r\n registrationPromise: registrationPromise\r\n }];\r\n }\r\n });\r\n });\r\n}\r\n/**\r\n * Creates a new Installation Entry if one does not exist.\r\n * Also clears timed out pending requests.\r\n */\r\nfunction updateOrCreateInstallationEntry(oldEntry) {\r\n var entry = oldEntry || {\r\n fid: generateFid(),\r\n registrationStatus: 0 /* NOT_STARTED */\r\n };\r\n return clearTimedOutRequest(entry);\r\n}\r\n/**\r\n * If the Firebase Installation is not registered yet, this will trigger the\r\n * registration and return an InProgressInstallationEntry.\r\n *\r\n * If registrationPromise does not exist, the installationEntry is guaranteed\r\n * to be registered.\r\n */\r\nfunction triggerRegistrationIfNecessary(appConfig, installationEntry) {\r\n if (installationEntry.registrationStatus === 0 /* NOT_STARTED */) {\r\n if (!navigator.onLine) {\r\n // Registration required but app is offline.\r\n var registrationPromiseWithError = Promise.reject(index_esm_ERROR_FACTORY.create(\"app-offline\" /* APP_OFFLINE */));\r\n return {\r\n installationEntry: installationEntry,\r\n registrationPromise: registrationPromiseWithError\r\n };\r\n }\r\n // Try registering. Change status to IN_PROGRESS.\r\n var inProgressEntry = {\r\n fid: installationEntry.fid,\r\n registrationStatus: 1 /* IN_PROGRESS */,\r\n registrationTime: Date.now()\r\n };\r\n var registrationPromise = registerInstallation(appConfig, inProgressEntry);\r\n return { installationEntry: inProgressEntry, registrationPromise: registrationPromise };\r\n }\r\n else if (installationEntry.registrationStatus === 1 /* IN_PROGRESS */) {\r\n return {\r\n installationEntry: installationEntry,\r\n registrationPromise: waitUntilFidRegistration(appConfig)\r\n };\r\n }\r\n else {\r\n return { installationEntry: installationEntry };\r\n }\r\n}\r\n/** This will be executed only once for each new Firebase Installation. */\r\nfunction registerInstallation(appConfig, installationEntry) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var registeredInstallationEntry, e_1;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n _a.trys.push([0, 2, , 7]);\r\n return [4 /*yield*/, createInstallationRequest(appConfig, installationEntry)];\r\n case 1:\r\n registeredInstallationEntry = _a.sent();\r\n return [2 /*return*/, set(appConfig, registeredInstallationEntry)];\r\n case 2:\r\n e_1 = _a.sent();\r\n if (!(isServerError(e_1) && e_1.customData.serverCode === 409)) return [3 /*break*/, 4];\r\n // Server returned a \"FID can not be used\" error.\r\n // Generate a new ID next time.\r\n return [4 /*yield*/, index_esm_remove(appConfig)];\r\n case 3:\r\n // Server returned a \"FID can not be used\" error.\r\n // Generate a new ID next time.\r\n _a.sent();\r\n return [3 /*break*/, 6];\r\n case 4: \r\n // Registration failed. Set FID as not registered.\r\n return [4 /*yield*/, set(appConfig, {\r\n fid: installationEntry.fid,\r\n registrationStatus: 0 /* NOT_STARTED */\r\n })];\r\n case 5:\r\n // Registration failed. Set FID as not registered.\r\n _a.sent();\r\n _a.label = 6;\r\n case 6: throw e_1;\r\n case 7: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\r\n/** Call if FID registration is pending in another request. */\r\nfunction waitUntilFidRegistration(appConfig) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var entry, _a, installationEntry, registrationPromise;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0: return [4 /*yield*/, updateInstallationRequest(appConfig)];\r\n case 1:\r\n entry = _b.sent();\r\n _b.label = 2;\r\n case 2:\r\n if (!(entry.registrationStatus === 1 /* IN_PROGRESS */)) return [3 /*break*/, 5];\r\n // createInstallation request still in progress.\r\n return [4 /*yield*/, sleep(100)];\r\n case 3:\r\n // createInstallation request still in progress.\r\n _b.sent();\r\n return [4 /*yield*/, updateInstallationRequest(appConfig)];\r\n case 4:\r\n entry = _b.sent();\r\n return [3 /*break*/, 2];\r\n case 5:\r\n if (!(entry.registrationStatus === 0 /* NOT_STARTED */)) return [3 /*break*/, 7];\r\n return [4 /*yield*/, getInstallationEntry(appConfig)];\r\n case 6:\r\n _a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;\r\n if (registrationPromise) {\r\n return [2 /*return*/, registrationPromise];\r\n }\r\n else {\r\n // if there is no registrationPromise, entry is registered.\r\n return [2 /*return*/, installationEntry];\r\n }\r\n case 7: return [2 /*return*/, entry];\r\n }\r\n });\r\n });\r\n}\r\n/**\r\n * Called only if there is a CreateInstallation request in progress.\r\n *\r\n * Updates the InstallationEntry in the DB based on the status of the\r\n * CreateInstallation request.\r\n *\r\n * Returns the updated InstallationEntry.\r\n */\r\nfunction updateInstallationRequest(appConfig) {\r\n return update(appConfig, function (oldEntry) {\r\n if (!oldEntry) {\r\n throw index_esm_ERROR_FACTORY.create(\"installation-not-found\" /* INSTALLATION_NOT_FOUND */);\r\n }\r\n return clearTimedOutRequest(oldEntry);\r\n });\r\n}\r\nfunction clearTimedOutRequest(entry) {\r\n if (hasInstallationRequestTimedOut(entry)) {\r\n return {\r\n fid: entry.fid,\r\n registrationStatus: 0 /* NOT_STARTED */\r\n };\r\n }\r\n return entry;\r\n}\r\nfunction hasInstallationRequestTimedOut(installationEntry) {\r\n return (installationEntry.registrationStatus === 1 /* IN_PROGRESS */ &&\r\n installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now());\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction generateAuthTokenRequest(_a, installationEntry) {\r\n var appConfig = _a.appConfig, platformLoggerProvider = _a.platformLoggerProvider;\r\n return __awaiter(this, void 0, void 0, function () {\r\n var endpoint, headers, platformLogger, body, request, response, responseValue, completedAuthToken;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0:\r\n endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);\r\n headers = getHeadersWithAuth(appConfig, installationEntry);\r\n platformLogger = platformLoggerProvider.getImmediate({\r\n optional: true\r\n });\r\n if (platformLogger) {\r\n headers.append('x-firebase-client', platformLogger.getPlatformInfoString());\r\n }\r\n body = {\r\n installation: {\r\n sdkVersion: PACKAGE_VERSION\r\n }\r\n };\r\n request = {\r\n method: 'POST',\r\n headers: headers,\r\n body: JSON.stringify(body)\r\n };\r\n return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];\r\n case 1:\r\n response = _b.sent();\r\n if (!response.ok) return [3 /*break*/, 3];\r\n return [4 /*yield*/, response.json()];\r\n case 2:\r\n responseValue = _b.sent();\r\n completedAuthToken = extractAuthTokenInfoFromResponse(responseValue);\r\n return [2 /*return*/, completedAuthToken];\r\n case 3: return [4 /*yield*/, getErrorFromResponse('Generate Auth Token', response)];\r\n case 4: throw _b.sent();\r\n }\r\n });\r\n });\r\n}\r\nfunction getGenerateAuthTokenEndpoint(appConfig, _a) {\r\n var fid = _a.fid;\r\n return getInstallationsEndpoint(appConfig) + \"/\" + fid + \"/authTokens:generate\";\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Returns a valid authentication token for the installation. Generates a new\r\n * token if one doesn't exist, is expired or about to expire.\r\n *\r\n * Should only be called if the Firebase Installation is registered.\r\n */\r\nfunction refreshAuthToken(dependencies, forceRefresh) {\r\n if (forceRefresh === void 0) { forceRefresh = false; }\r\n return __awaiter(this, void 0, void 0, function () {\r\n var tokenPromise, entry, authToken, _a;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0: return [4 /*yield*/, update(dependencies.appConfig, function (oldEntry) {\r\n if (!isEntryRegistered(oldEntry)) {\r\n throw index_esm_ERROR_FACTORY.create(\"not-registered\" /* NOT_REGISTERED */);\r\n }\r\n var oldAuthToken = oldEntry.authToken;\r\n if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {\r\n // There is a valid token in the DB.\r\n return oldEntry;\r\n }\r\n else if (oldAuthToken.requestStatus === 1 /* IN_PROGRESS */) {\r\n // There already is a token request in progress.\r\n tokenPromise = waitUntilAuthTokenRequest(dependencies, forceRefresh);\r\n return oldEntry;\r\n }\r\n else {\r\n // No token or token expired.\r\n if (!navigator.onLine) {\r\n throw index_esm_ERROR_FACTORY.create(\"app-offline\" /* APP_OFFLINE */);\r\n }\r\n var inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);\r\n tokenPromise = fetchAuthTokenFromServer(dependencies, inProgressEntry);\r\n return inProgressEntry;\r\n }\r\n })];\r\n case 1:\r\n entry = _b.sent();\r\n if (!tokenPromise) return [3 /*break*/, 3];\r\n return [4 /*yield*/, tokenPromise];\r\n case 2:\r\n _a = _b.sent();\r\n return [3 /*break*/, 4];\r\n case 3:\r\n _a = entry.authToken;\r\n _b.label = 4;\r\n case 4:\r\n authToken = _a;\r\n return [2 /*return*/, authToken];\r\n }\r\n });\r\n });\r\n}\r\n/**\r\n * Call only if FID is registered and Auth Token request is in progress.\r\n *\r\n * Waits until the current pending request finishes. If the request times out,\r\n * tries once in this thread as well.\r\n */\r\nfunction waitUntilAuthTokenRequest(dependencies, forceRefresh) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var entry, authToken;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, updateAuthTokenRequest(dependencies.appConfig)];\r\n case 1:\r\n entry = _a.sent();\r\n _a.label = 2;\r\n case 2:\r\n if (!(entry.authToken.requestStatus === 1 /* IN_PROGRESS */)) return [3 /*break*/, 5];\r\n // generateAuthToken still in progress.\r\n return [4 /*yield*/, sleep(100)];\r\n case 3:\r\n // generateAuthToken still in progress.\r\n _a.sent();\r\n return [4 /*yield*/, updateAuthTokenRequest(dependencies.appConfig)];\r\n case 4:\r\n entry = _a.sent();\r\n return [3 /*break*/, 2];\r\n case 5:\r\n authToken = entry.authToken;\r\n if (authToken.requestStatus === 0 /* NOT_STARTED */) {\r\n // The request timed out or failed in a different call. Try again.\r\n return [2 /*return*/, refreshAuthToken(dependencies, forceRefresh)];\r\n }\r\n else {\r\n return [2 /*return*/, authToken];\r\n }\r\n }\r\n });\r\n });\r\n}\r\n/**\r\n * Called only if there is a GenerateAuthToken request in progress.\r\n *\r\n * Updates the InstallationEntry in the DB based on the status of the\r\n * GenerateAuthToken request.\r\n *\r\n * Returns the updated InstallationEntry.\r\n */\r\nfunction updateAuthTokenRequest(appConfig) {\r\n return update(appConfig, function (oldEntry) {\r\n if (!isEntryRegistered(oldEntry)) {\r\n throw index_esm_ERROR_FACTORY.create(\"not-registered\" /* NOT_REGISTERED */);\r\n }\r\n var oldAuthToken = oldEntry.authToken;\r\n if (hasAuthTokenRequestTimedOut(oldAuthToken)) {\r\n return tslib_es6_assign(tslib_es6_assign({}, oldEntry), { authToken: { requestStatus: 0 /* NOT_STARTED */ } });\r\n }\r\n return oldEntry;\r\n });\r\n}\r\nfunction fetchAuthTokenFromServer(dependencies, installationEntry) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var authToken, updatedInstallationEntry, e_1, updatedInstallationEntry;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n _a.trys.push([0, 3, , 8]);\r\n return [4 /*yield*/, generateAuthTokenRequest(dependencies, installationEntry)];\r\n case 1:\r\n authToken = _a.sent();\r\n updatedInstallationEntry = tslib_es6_assign(tslib_es6_assign({}, installationEntry), { authToken: authToken });\r\n return [4 /*yield*/, set(dependencies.appConfig, updatedInstallationEntry)];\r\n case 2:\r\n _a.sent();\r\n return [2 /*return*/, authToken];\r\n case 3:\r\n e_1 = _a.sent();\r\n if (!(isServerError(e_1) &&\r\n (e_1.customData.serverCode === 401 || e_1.customData.serverCode === 404))) return [3 /*break*/, 5];\r\n // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\r\n // Generate a new ID next time.\r\n return [4 /*yield*/, index_esm_remove(dependencies.appConfig)];\r\n case 4:\r\n // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\r\n // Generate a new ID next time.\r\n _a.sent();\r\n return [3 /*break*/, 7];\r\n case 5:\r\n updatedInstallationEntry = tslib_es6_assign(tslib_es6_assign({}, installationEntry), { authToken: { requestStatus: 0 /* NOT_STARTED */ } });\r\n return [4 /*yield*/, set(dependencies.appConfig, updatedInstallationEntry)];\r\n case 6:\r\n _a.sent();\r\n _a.label = 7;\r\n case 7: throw e_1;\r\n case 8: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\r\nfunction isEntryRegistered(installationEntry) {\r\n return (installationEntry !== undefined &&\r\n installationEntry.registrationStatus === 2 /* COMPLETED */);\r\n}\r\nfunction isAuthTokenValid(authToken) {\r\n return (authToken.requestStatus === 2 /* COMPLETED */ &&\r\n !isAuthTokenExpired(authToken));\r\n}\r\nfunction isAuthTokenExpired(authToken) {\r\n var now = Date.now();\r\n return (now < authToken.creationTime ||\r\n authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER);\r\n}\r\n/** Returns an updated InstallationEntry with an InProgressAuthToken. */\r\nfunction makeAuthTokenRequestInProgressEntry(oldEntry) {\r\n var inProgressAuthToken = {\r\n requestStatus: 1 /* IN_PROGRESS */,\r\n requestTime: Date.now()\r\n };\r\n return tslib_es6_assign(tslib_es6_assign({}, oldEntry), { authToken: inProgressAuthToken });\r\n}\r\nfunction hasAuthTokenRequestTimedOut(authToken) {\r\n return (authToken.requestStatus === 1 /* IN_PROGRESS */ &&\r\n authToken.requestTime + PENDING_TIMEOUT_MS < Date.now());\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction getId(dependencies) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var _a, installationEntry, registrationPromise;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0: return [4 /*yield*/, getInstallationEntry(dependencies.appConfig)];\r\n case 1:\r\n _a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;\r\n if (registrationPromise) {\r\n registrationPromise.catch(console.error);\r\n }\r\n else {\r\n // If the installation is already registered, update the authentication\r\n // token if needed.\r\n refreshAuthToken(dependencies).catch(console.error);\r\n }\r\n return [2 /*return*/, installationEntry.fid];\r\n }\r\n });\r\n });\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction getToken(dependencies, forceRefresh) {\r\n if (forceRefresh === void 0) { forceRefresh = false; }\r\n return __awaiter(this, void 0, void 0, function () {\r\n var authToken;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, completeInstallationRegistration(dependencies.appConfig)];\r\n case 1:\r\n _a.sent();\r\n return [4 /*yield*/, refreshAuthToken(dependencies, forceRefresh)];\r\n case 2:\r\n authToken = _a.sent();\r\n return [2 /*return*/, authToken.token];\r\n }\r\n });\r\n });\r\n}\r\nfunction completeInstallationRegistration(appConfig) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var registrationPromise;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, getInstallationEntry(appConfig)];\r\n case 1:\r\n registrationPromise = (_a.sent()).registrationPromise;\r\n if (!registrationPromise) return [3 /*break*/, 3];\r\n // A createInstallation request is in progress. Wait until it finishes.\r\n return [4 /*yield*/, registrationPromise];\r\n case 2:\r\n // A createInstallation request is in progress. Wait until it finishes.\r\n _a.sent();\r\n _a.label = 3;\r\n case 3: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction deleteInstallationRequest(appConfig, installationEntry) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var endpoint, headers, request, response;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n endpoint = getDeleteEndpoint(appConfig, installationEntry);\r\n headers = getHeadersWithAuth(appConfig, installationEntry);\r\n request = {\r\n method: 'DELETE',\r\n headers: headers\r\n };\r\n return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];\r\n case 1:\r\n response = _a.sent();\r\n if (!!response.ok) return [3 /*break*/, 3];\r\n return [4 /*yield*/, getErrorFromResponse('Delete Installation', response)];\r\n case 2: throw _a.sent();\r\n case 3: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\r\nfunction getDeleteEndpoint(appConfig, _a) {\r\n var fid = _a.fid;\r\n return getInstallationsEndpoint(appConfig) + \"/\" + fid;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction deleteInstallation(dependencies) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var appConfig, entry;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n appConfig = dependencies.appConfig;\r\n return [4 /*yield*/, update(appConfig, function (oldEntry) {\r\n if (oldEntry && oldEntry.registrationStatus === 0 /* NOT_STARTED */) {\r\n // Delete the unregistered entry without sending a deleteInstallation request.\r\n return undefined;\r\n }\r\n return oldEntry;\r\n })];\r\n case 1:\r\n entry = _a.sent();\r\n if (!entry) return [3 /*break*/, 6];\r\n if (!(entry.registrationStatus === 1 /* IN_PROGRESS */)) return [3 /*break*/, 2];\r\n // Can't delete while trying to register.\r\n throw index_esm_ERROR_FACTORY.create(\"delete-pending-registration\" /* DELETE_PENDING_REGISTRATION */);\r\n case 2:\r\n if (!(entry.registrationStatus === 2 /* COMPLETED */)) return [3 /*break*/, 6];\r\n if (!!navigator.onLine) return [3 /*break*/, 3];\r\n throw index_esm_ERROR_FACTORY.create(\"app-offline\" /* APP_OFFLINE */);\r\n case 3: return [4 /*yield*/, deleteInstallationRequest(appConfig, entry)];\r\n case 4:\r\n _a.sent();\r\n return [4 /*yield*/, index_esm_remove(appConfig)];\r\n case 5:\r\n _a.sent();\r\n _a.label = 6;\r\n case 6: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/**\r\n * Sets a new callback that will get called when Installation ID changes.\r\n * Returns an unsubscribe function that will remove the callback when called.\r\n */\r\nfunction onIdChange(_a, callback) {\r\n var appConfig = _a.appConfig;\r\n addCallback(appConfig, callback);\r\n return function () {\r\n removeCallback(appConfig, callback);\r\n };\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction extractAppConfig(app) {\r\n var e_1, _a;\r\n if (!app || !app.options) {\r\n throw getMissingValueError('App Configuration');\r\n }\r\n if (!app.name) {\r\n throw getMissingValueError('App Name');\r\n }\r\n // Required app config keys\r\n var configKeys = [\r\n 'projectId',\r\n 'apiKey',\r\n 'appId'\r\n ];\r\n try {\r\n for (var configKeys_1 = __values(configKeys), configKeys_1_1 = configKeys_1.next(); !configKeys_1_1.done; configKeys_1_1 = configKeys_1.next()) {\r\n var keyName = configKeys_1_1.value;\r\n if (!app.options[keyName]) {\r\n throw getMissingValueError(keyName);\r\n }\r\n }\r\n }\r\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\r\n finally {\r\n try {\r\n if (configKeys_1_1 && !configKeys_1_1.done && (_a = configKeys_1.return)) _a.call(configKeys_1);\r\n }\r\n finally { if (e_1) throw e_1.error; }\r\n }\r\n return {\r\n appName: app.name,\r\n projectId: app.options.projectId,\r\n apiKey: app.options.apiKey,\r\n appId: app.options.appId\r\n };\r\n}\r\nfunction getMissingValueError(valueName) {\r\n return index_esm_ERROR_FACTORY.create(\"missing-app-config-values\" /* MISSING_APP_CONFIG_VALUES */, {\r\n valueName: valueName\r\n });\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction registerInstallations(instance) {\r\n var installationsName = 'installations';\r\n instance.INTERNAL.registerComponent(new Component(installationsName, function (container) {\r\n var app = container.getProvider('app').getImmediate();\r\n // Throws if app isn't configured properly.\r\n var appConfig = extractAppConfig(app);\r\n var platformLoggerProvider = container.getProvider('platform-logger');\r\n var dependencies = {\r\n appConfig: appConfig,\r\n platformLoggerProvider: platformLoggerProvider\r\n };\r\n var installations = {\r\n app: app,\r\n getId: function () { return getId(dependencies); },\r\n getToken: function (forceRefresh) {\r\n return getToken(dependencies, forceRefresh);\r\n },\r\n delete: function () { return deleteInstallation(dependencies); },\r\n onIdChange: function (callback) {\r\n return onIdChange(dependencies, callback);\r\n }\r\n };\r\n return installations;\r\n }, \"PUBLIC\" /* PUBLIC */));\r\n instance.registerVersion(installations_dist_index_esm_name, dist_index_esm_version);\r\n}\r\nregisterInstallations(index_esm);\n\n\n//# sourceMappingURL=index.esm.js.map\n\n;// CONCATENATED MODULE: ./node_modules/@firebase/messaging/dist/index.esm.js\n\n\n\n\n\n\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar messaging_dist_index_esm_a;\r\nvar ERROR_MAP = (messaging_dist_index_esm_a = {},\r\n messaging_dist_index_esm_a[\"missing-app-config-values\" /* MISSING_APP_CONFIG_VALUES */] = 'Missing App configuration value: \"{$valueName}\"',\r\n messaging_dist_index_esm_a[\"only-available-in-window\" /* AVAILABLE_IN_WINDOW */] = 'This method is available in a Window context.',\r\n messaging_dist_index_esm_a[\"only-available-in-sw\" /* AVAILABLE_IN_SW */] = 'This method is available in a service worker context.',\r\n messaging_dist_index_esm_a[\"permission-default\" /* PERMISSION_DEFAULT */] = 'The notification permission was not granted and dismissed instead.',\r\n messaging_dist_index_esm_a[\"permission-blocked\" /* PERMISSION_BLOCKED */] = 'The notification permission was not granted and blocked instead.',\r\n messaging_dist_index_esm_a[\"unsupported-browser\" /* UNSUPPORTED_BROWSER */] = \"This browser doesn't support the API's required to use the firebase SDK.\",\r\n messaging_dist_index_esm_a[\"failed-service-worker-registration\" /* FAILED_DEFAULT_REGISTRATION */] = 'We are unable to register the default service worker. {$browserErrorMessage}',\r\n messaging_dist_index_esm_a[\"token-subscribe-failed\" /* TOKEN_SUBSCRIBE_FAILED */] = 'A problem occurred while subscribing the user to FCM: {$errorInfo}',\r\n messaging_dist_index_esm_a[\"token-subscribe-no-token\" /* TOKEN_SUBSCRIBE_NO_TOKEN */] = 'FCM returned no token when subscribing the user to push.',\r\n messaging_dist_index_esm_a[\"token-unsubscribe-failed\" /* TOKEN_UNSUBSCRIBE_FAILED */] = 'A problem occurred while unsubscribing the ' +\r\n 'user from FCM: {$errorInfo}',\r\n messaging_dist_index_esm_a[\"token-update-failed\" /* TOKEN_UPDATE_FAILED */] = 'A problem occurred while updating the user from FCM: {$errorInfo}',\r\n messaging_dist_index_esm_a[\"token-update-no-token\" /* TOKEN_UPDATE_NO_TOKEN */] = 'FCM returned no token when updating the user to push.',\r\n messaging_dist_index_esm_a[\"use-sw-after-get-token\" /* USE_SW_AFTER_GET_TOKEN */] = 'The useServiceWorker() method may only be called once and must be ' +\r\n 'called before calling getToken() to ensure your service worker is used.',\r\n messaging_dist_index_esm_a[\"invalid-sw-registration\" /* INVALID_SW_REGISTRATION */] = 'The input to useServiceWorker() must be a ServiceWorkerRegistration.',\r\n messaging_dist_index_esm_a[\"invalid-bg-handler\" /* INVALID_BG_HANDLER */] = 'The input to setBackgroundMessageHandler() must be a function.',\r\n messaging_dist_index_esm_a[\"invalid-vapid-key\" /* INVALID_VAPID_KEY */] = 'The public VAPID key must be a string.',\r\n messaging_dist_index_esm_a[\"use-vapid-key-after-get-token\" /* USE_VAPID_KEY_AFTER_GET_TOKEN */] = 'The usePublicVapidKey() method may only be called once and must be ' +\r\n 'called before calling getToken() to ensure your VAPID key is used.',\r\n messaging_dist_index_esm_a);\r\nvar dist_index_esm_ERROR_FACTORY = new ErrorFactory('messaging', 'Messaging', ERROR_MAP);\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar DEFAULT_SW_PATH = '/firebase-messaging-sw.js';\r\nvar DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope';\r\nvar DEFAULT_VAPID_KEY = 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4';\r\nvar ENDPOINT = 'https://fcmregistrations.googleapis.com/v1';\r\n// Key of FCM Payload in Notification's data field.\r\nvar FCM_MSG = 'FCM_MSG';\r\nvar TAG = 'FirebaseMessaging: ';\r\n// Set to '1' if Analytics is enabled for the campaign\r\nvar CONSOLE_CAMPAIGN_ANALYTICS_ENABLED = 'google.c.a.e';\r\nvar CONSOLE_CAMPAIGN_ID = 'google.c.a.c_id';\r\nvar CONSOLE_CAMPAIGN_TIME = 'google.c.a.ts';\r\nvar CONSOLE_CAMPAIGN_NAME = 'google.c.a.c_l';\r\n// Due to the fact that onBackgroundMessage can't be awaited (to support rxjs), a silent push\r\n// warning might be shown by the browser if the callback fails to completes by the end of onPush.\r\n// Experiments were ran to determine the majority onBackground message clock time. This brief\r\n// blocking time would allow majority of the onBackgroundMessage callback to finish.\r\nvar BACKGROUND_HANDLE_EXECUTION_TIME_LIMIT_MS = 1000;\r\n// Preparation time for client to initialize and set up the message handler.\r\nvar FOREGROUND_HANDLE_PREPARATION_TIME_MS = 3000;\n\n/**\r\n * @license\r\n * Copyright 2018 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\r\n * in compliance with the License. You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software distributed under the License\r\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\r\n * or implied. See the License for the specific language governing permissions and limitations under\r\n * the License.\r\n */\r\nvar MessageType;\r\n(function (MessageType) {\r\n MessageType[\"PUSH_RECEIVED\"] = \"push-received\";\r\n MessageType[\"NOTIFICATION_CLICKED\"] = \"notification-clicked\";\r\n})(MessageType || (MessageType = {}));\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction arrayToBase64(array) {\r\n var uint8Array = new Uint8Array(array);\r\n var base64String = btoa(String.fromCharCode.apply(String, __spreadArray([], __read(uint8Array))));\r\n return base64String.replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\r\n}\r\nfunction base64ToArray(base64String) {\r\n var padding = '='.repeat((4 - (base64String.length % 4)) % 4);\r\n var base64 = (base64String + padding)\r\n .replace(/\\-/g, '+')\r\n .replace(/_/g, '/');\r\n var rawData = atob(base64);\r\n var outputArray = new Uint8Array(rawData.length);\r\n for (var i = 0; i < rawData.length; ++i) {\r\n outputArray[i] = rawData.charCodeAt(i);\r\n }\r\n return outputArray;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar OLD_DB_NAME = 'fcm_token_details_db';\r\n/**\r\n * The last DB version of 'fcm_token_details_db' was 4. This is one higher, so that the upgrade\r\n * callback is called for all versions of the old DB.\r\n */\r\nvar OLD_DB_VERSION = 5;\r\nvar OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store';\r\nfunction migrateOldDatabase(senderId) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var databases, dbNames, tokenDetails, db;\r\n var _this = this;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n if (!('databases' in indexedDB)) return [3 /*break*/, 2];\r\n return [4 /*yield*/, indexedDB.databases()];\r\n case 1:\r\n databases = _a.sent();\r\n dbNames = databases.map(function (db) { return db.name; });\r\n if (!dbNames.includes(OLD_DB_NAME)) {\r\n // old DB didn't exist, no need to open.\r\n return [2 /*return*/, null];\r\n }\r\n _a.label = 2;\r\n case 2:\r\n tokenDetails = null;\r\n return [4 /*yield*/, (0,idb.openDb)(OLD_DB_NAME, OLD_DB_VERSION, function (db) { return __awaiter(_this, void 0, void 0, function () {\r\n var objectStore, value, oldDetails, oldDetails, oldDetails;\r\n var _a;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0:\r\n if (db.oldVersion < 2) {\r\n // Database too old, skip migration.\r\n return [2 /*return*/];\r\n }\r\n if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {\r\n // Database did not exist. Nothing to do.\r\n return [2 /*return*/];\r\n }\r\n objectStore = db.transaction.objectStore(OLD_OBJECT_STORE_NAME);\r\n return [4 /*yield*/, objectStore.index('fcmSenderId').get(senderId)];\r\n case 1:\r\n value = _b.sent();\r\n return [4 /*yield*/, objectStore.clear()];\r\n case 2:\r\n _b.sent();\r\n if (!value) {\r\n // No entry in the database, nothing to migrate.\r\n return [2 /*return*/];\r\n }\r\n if (db.oldVersion === 2) {\r\n oldDetails = value;\r\n if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) {\r\n return [2 /*return*/];\r\n }\r\n tokenDetails = {\r\n token: oldDetails.fcmToken,\r\n createTime: (_a = oldDetails.createTime) !== null && _a !== void 0 ? _a : Date.now(),\r\n subscriptionOptions: {\r\n auth: oldDetails.auth,\r\n p256dh: oldDetails.p256dh,\r\n endpoint: oldDetails.endpoint,\r\n swScope: oldDetails.swScope,\r\n vapidKey: typeof oldDetails.vapidKey === 'string'\r\n ? oldDetails.vapidKey\r\n : arrayToBase64(oldDetails.vapidKey)\r\n }\r\n };\r\n }\r\n else if (db.oldVersion === 3) {\r\n oldDetails = value;\r\n tokenDetails = {\r\n token: oldDetails.fcmToken,\r\n createTime: oldDetails.createTime,\r\n subscriptionOptions: {\r\n auth: arrayToBase64(oldDetails.auth),\r\n p256dh: arrayToBase64(oldDetails.p256dh),\r\n endpoint: oldDetails.endpoint,\r\n swScope: oldDetails.swScope,\r\n vapidKey: arrayToBase64(oldDetails.vapidKey)\r\n }\r\n };\r\n }\r\n else if (db.oldVersion === 4) {\r\n oldDetails = value;\r\n tokenDetails = {\r\n token: oldDetails.fcmToken,\r\n createTime: oldDetails.createTime,\r\n subscriptionOptions: {\r\n auth: arrayToBase64(oldDetails.auth),\r\n p256dh: arrayToBase64(oldDetails.p256dh),\r\n endpoint: oldDetails.endpoint,\r\n swScope: oldDetails.swScope,\r\n vapidKey: arrayToBase64(oldDetails.vapidKey)\r\n }\r\n };\r\n }\r\n return [2 /*return*/];\r\n }\r\n });\r\n }); })];\r\n case 3:\r\n db = _a.sent();\r\n db.close();\r\n // Delete all old databases.\r\n return [4 /*yield*/, (0,idb.deleteDb)(OLD_DB_NAME)];\r\n case 4:\r\n // Delete all old databases.\r\n _a.sent();\r\n return [4 /*yield*/, (0,idb.deleteDb)('fcm_vapid_details_db')];\r\n case 5:\r\n _a.sent();\r\n return [4 /*yield*/, (0,idb.deleteDb)('undefined')];\r\n case 6:\r\n _a.sent();\r\n return [2 /*return*/, checkTokenDetails(tokenDetails) ? tokenDetails : null];\r\n }\r\n });\r\n });\r\n}\r\nfunction checkTokenDetails(tokenDetails) {\r\n if (!tokenDetails || !tokenDetails.subscriptionOptions) {\r\n return false;\r\n }\r\n var subscriptionOptions = tokenDetails.subscriptionOptions;\r\n return (typeof tokenDetails.createTime === 'number' &&\r\n tokenDetails.createTime > 0 &&\r\n typeof tokenDetails.token === 'string' &&\r\n tokenDetails.token.length > 0 &&\r\n typeof subscriptionOptions.auth === 'string' &&\r\n subscriptionOptions.auth.length > 0 &&\r\n typeof subscriptionOptions.p256dh === 'string' &&\r\n subscriptionOptions.p256dh.length > 0 &&\r\n typeof subscriptionOptions.endpoint === 'string' &&\r\n subscriptionOptions.endpoint.length > 0 &&\r\n typeof subscriptionOptions.swScope === 'string' &&\r\n subscriptionOptions.swScope.length > 0 &&\r\n typeof subscriptionOptions.vapidKey === 'string' &&\r\n subscriptionOptions.vapidKey.length > 0);\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n// Exported for tests.\r\nvar index_esm_DATABASE_NAME = 'firebase-messaging-database';\r\nvar index_esm_DATABASE_VERSION = 1;\r\nvar index_esm_OBJECT_STORE_NAME = 'firebase-messaging-store';\r\nvar index_esm_dbPromise = null;\r\nfunction index_esm_getDbPromise() {\r\n if (!index_esm_dbPromise) {\r\n index_esm_dbPromise = (0,idb.openDb)(index_esm_DATABASE_NAME, index_esm_DATABASE_VERSION, function (upgradeDb) {\r\n // We don't use 'break' in this switch statement, the fall-through behavior is what we want,\r\n // because if there are multiple versions between the old version and the current version, we\r\n // want ALL the migrations that correspond to those versions to run, not only the last one.\r\n // eslint-disable-next-line default-case\r\n switch (upgradeDb.oldVersion) {\r\n case 0:\r\n upgradeDb.createObjectStore(index_esm_OBJECT_STORE_NAME);\r\n }\r\n });\r\n }\r\n return index_esm_dbPromise;\r\n}\r\n/** Gets record(s) from the objectStore that match the given key. */\r\nfunction dbGet(firebaseDependencies) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var key, db, tokenDetails, oldTokenDetails;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n key = index_esm_getKey(firebaseDependencies);\r\n return [4 /*yield*/, index_esm_getDbPromise()];\r\n case 1:\r\n db = _a.sent();\r\n return [4 /*yield*/, db\r\n .transaction(index_esm_OBJECT_STORE_NAME)\r\n .objectStore(index_esm_OBJECT_STORE_NAME)\r\n .get(key)];\r\n case 2:\r\n tokenDetails = _a.sent();\r\n if (!tokenDetails) return [3 /*break*/, 3];\r\n return [2 /*return*/, tokenDetails];\r\n case 3: return [4 /*yield*/, migrateOldDatabase(firebaseDependencies.appConfig.senderId)];\r\n case 4:\r\n oldTokenDetails = _a.sent();\r\n if (!oldTokenDetails) return [3 /*break*/, 6];\r\n return [4 /*yield*/, dbSet(firebaseDependencies, oldTokenDetails)];\r\n case 5:\r\n _a.sent();\r\n return [2 /*return*/, oldTokenDetails];\r\n case 6: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\r\n/** Assigns or overwrites the record for the given key with the given value. */\r\nfunction dbSet(firebaseDependencies, tokenDetails) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var key, db, tx;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n key = index_esm_getKey(firebaseDependencies);\r\n return [4 /*yield*/, index_esm_getDbPromise()];\r\n case 1:\r\n db = _a.sent();\r\n tx = db.transaction(index_esm_OBJECT_STORE_NAME, 'readwrite');\r\n return [4 /*yield*/, tx.objectStore(index_esm_OBJECT_STORE_NAME).put(tokenDetails, key)];\r\n case 2:\r\n _a.sent();\r\n return [4 /*yield*/, tx.complete];\r\n case 3:\r\n _a.sent();\r\n return [2 /*return*/, tokenDetails];\r\n }\r\n });\r\n });\r\n}\r\n/** Removes record(s) from the objectStore that match the given key. */\r\nfunction dbRemove(firebaseDependencies) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var key, db, tx;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n key = index_esm_getKey(firebaseDependencies);\r\n return [4 /*yield*/, index_esm_getDbPromise()];\r\n case 1:\r\n db = _a.sent();\r\n tx = db.transaction(index_esm_OBJECT_STORE_NAME, 'readwrite');\r\n return [4 /*yield*/, tx.objectStore(index_esm_OBJECT_STORE_NAME).delete(key)];\r\n case 2:\r\n _a.sent();\r\n return [4 /*yield*/, tx.complete];\r\n case 3:\r\n _a.sent();\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\r\nfunction index_esm_getKey(_a) {\r\n var appConfig = _a.appConfig;\r\n return appConfig.appId;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction requestGetToken(firebaseDependencies, subscriptionOptions) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var headers, body, subscribeOptions, responseData, response, err_1, message;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, index_esm_getHeaders(firebaseDependencies)];\r\n case 1:\r\n headers = _a.sent();\r\n body = getBody(subscriptionOptions);\r\n subscribeOptions = {\r\n method: 'POST',\r\n headers: headers,\r\n body: JSON.stringify(body)\r\n };\r\n _a.label = 2;\r\n case 2:\r\n _a.trys.push([2, 5, , 6]);\r\n return [4 /*yield*/, fetch(getEndpoint(firebaseDependencies.appConfig), subscribeOptions)];\r\n case 3:\r\n response = _a.sent();\r\n return [4 /*yield*/, response.json()];\r\n case 4:\r\n responseData = _a.sent();\r\n return [3 /*break*/, 6];\r\n case 5:\r\n err_1 = _a.sent();\r\n throw dist_index_esm_ERROR_FACTORY.create(\"token-subscribe-failed\" /* TOKEN_SUBSCRIBE_FAILED */, {\r\n errorInfo: err_1\r\n });\r\n case 6:\r\n if (responseData.error) {\r\n message = responseData.error.message;\r\n throw dist_index_esm_ERROR_FACTORY.create(\"token-subscribe-failed\" /* TOKEN_SUBSCRIBE_FAILED */, {\r\n errorInfo: message\r\n });\r\n }\r\n if (!responseData.token) {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"token-subscribe-no-token\" /* TOKEN_SUBSCRIBE_NO_TOKEN */);\r\n }\r\n return [2 /*return*/, responseData.token];\r\n }\r\n });\r\n });\r\n}\r\nfunction requestUpdateToken(firebaseDependencies, tokenDetails) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var headers, body, updateOptions, responseData, response, err_2, message;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, index_esm_getHeaders(firebaseDependencies)];\r\n case 1:\r\n headers = _a.sent();\r\n body = getBody(tokenDetails.subscriptionOptions);\r\n updateOptions = {\r\n method: 'PATCH',\r\n headers: headers,\r\n body: JSON.stringify(body)\r\n };\r\n _a.label = 2;\r\n case 2:\r\n _a.trys.push([2, 5, , 6]);\r\n return [4 /*yield*/, fetch(getEndpoint(firebaseDependencies.appConfig) + \"/\" + tokenDetails.token, updateOptions)];\r\n case 3:\r\n response = _a.sent();\r\n return [4 /*yield*/, response.json()];\r\n case 4:\r\n responseData = _a.sent();\r\n return [3 /*break*/, 6];\r\n case 5:\r\n err_2 = _a.sent();\r\n throw dist_index_esm_ERROR_FACTORY.create(\"token-update-failed\" /* TOKEN_UPDATE_FAILED */, {\r\n errorInfo: err_2\r\n });\r\n case 6:\r\n if (responseData.error) {\r\n message = responseData.error.message;\r\n throw dist_index_esm_ERROR_FACTORY.create(\"token-update-failed\" /* TOKEN_UPDATE_FAILED */, {\r\n errorInfo: message\r\n });\r\n }\r\n if (!responseData.token) {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"token-update-no-token\" /* TOKEN_UPDATE_NO_TOKEN */);\r\n }\r\n return [2 /*return*/, responseData.token];\r\n }\r\n });\r\n });\r\n}\r\nfunction requestDeleteToken(firebaseDependencies, token) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var headers, unsubscribeOptions, response, responseData, message, err_3;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, index_esm_getHeaders(firebaseDependencies)];\r\n case 1:\r\n headers = _a.sent();\r\n unsubscribeOptions = {\r\n method: 'DELETE',\r\n headers: headers\r\n };\r\n _a.label = 2;\r\n case 2:\r\n _a.trys.push([2, 5, , 6]);\r\n return [4 /*yield*/, fetch(getEndpoint(firebaseDependencies.appConfig) + \"/\" + token, unsubscribeOptions)];\r\n case 3:\r\n response = _a.sent();\r\n return [4 /*yield*/, response.json()];\r\n case 4:\r\n responseData = _a.sent();\r\n if (responseData.error) {\r\n message = responseData.error.message;\r\n throw dist_index_esm_ERROR_FACTORY.create(\"token-unsubscribe-failed\" /* TOKEN_UNSUBSCRIBE_FAILED */, {\r\n errorInfo: message\r\n });\r\n }\r\n return [3 /*break*/, 6];\r\n case 5:\r\n err_3 = _a.sent();\r\n throw dist_index_esm_ERROR_FACTORY.create(\"token-unsubscribe-failed\" /* TOKEN_UNSUBSCRIBE_FAILED */, {\r\n errorInfo: err_3\r\n });\r\n case 6: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\r\nfunction getEndpoint(_a) {\r\n var projectId = _a.projectId;\r\n return ENDPOINT + \"/projects/\" + projectId + \"/registrations\";\r\n}\r\nfunction index_esm_getHeaders(_a) {\r\n var appConfig = _a.appConfig, installations = _a.installations;\r\n return __awaiter(this, void 0, void 0, function () {\r\n var authToken;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0: return [4 /*yield*/, installations.getToken()];\r\n case 1:\r\n authToken = _b.sent();\r\n return [2 /*return*/, new Headers({\r\n 'Content-Type': 'application/json',\r\n Accept: 'application/json',\r\n 'x-goog-api-key': appConfig.apiKey,\r\n 'x-goog-firebase-installations-auth': \"FIS \" + authToken\r\n })];\r\n }\r\n });\r\n });\r\n}\r\nfunction getBody(_a) {\r\n var p256dh = _a.p256dh, auth = _a.auth, endpoint = _a.endpoint, vapidKey = _a.vapidKey;\r\n var body = {\r\n web: {\r\n endpoint: endpoint,\r\n auth: auth,\r\n p256dh: p256dh\r\n }\r\n };\r\n if (vapidKey !== DEFAULT_VAPID_KEY) {\r\n body.web.applicationPubKey = vapidKey;\r\n }\r\n return body;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/** UpdateRegistration will be called once every week. */\r\nvar TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\r\nfunction index_esm_getToken(firebaseDependencies, swRegistration, vapidKey) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var pushSubscription, tokenDetails, subscriptionOptions, e_1;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n if (Notification.permission !== 'granted') {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"permission-blocked\" /* PERMISSION_BLOCKED */);\r\n }\r\n return [4 /*yield*/, getPushSubscription(swRegistration, vapidKey)];\r\n case 1:\r\n pushSubscription = _a.sent();\r\n return [4 /*yield*/, dbGet(firebaseDependencies)];\r\n case 2:\r\n tokenDetails = _a.sent();\r\n subscriptionOptions = {\r\n vapidKey: vapidKey,\r\n swScope: swRegistration.scope,\r\n endpoint: pushSubscription.endpoint,\r\n auth: arrayToBase64(pushSubscription.getKey('auth')),\r\n p256dh: arrayToBase64(pushSubscription.getKey('p256dh'))\r\n };\r\n if (!!tokenDetails) return [3 /*break*/, 3];\r\n // No token, get a new one.\r\n return [2 /*return*/, getNewToken(firebaseDependencies, subscriptionOptions)];\r\n case 3:\r\n if (!!isTokenValid(tokenDetails.subscriptionOptions, subscriptionOptions)) return [3 /*break*/, 8];\r\n _a.label = 4;\r\n case 4:\r\n _a.trys.push([4, 6, , 7]);\r\n return [4 /*yield*/, requestDeleteToken(firebaseDependencies, tokenDetails.token)];\r\n case 5:\r\n _a.sent();\r\n return [3 /*break*/, 7];\r\n case 6:\r\n e_1 = _a.sent();\r\n // Suppress errors because of #2364\r\n console.warn(e_1);\r\n return [3 /*break*/, 7];\r\n case 7: return [2 /*return*/, getNewToken(firebaseDependencies, subscriptionOptions)];\r\n case 8:\r\n if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {\r\n // Weekly token refresh\r\n return [2 /*return*/, updateToken({\r\n token: tokenDetails.token,\r\n createTime: Date.now(),\r\n subscriptionOptions: subscriptionOptions\r\n }, firebaseDependencies, swRegistration)];\r\n }\r\n else {\r\n // Valid token, nothing to do.\r\n return [2 /*return*/, tokenDetails.token];\r\n }\r\n case 9: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\r\n/**\r\n * This method deletes the token from the database, unsubscribes the token from FCM, and unregisters\r\n * the push subscription if it exists.\r\n */\r\nfunction deleteToken(firebaseDependencies, swRegistration) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var tokenDetails, pushSubscription;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, dbGet(firebaseDependencies)];\r\n case 1:\r\n tokenDetails = _a.sent();\r\n if (!tokenDetails) return [3 /*break*/, 4];\r\n return [4 /*yield*/, requestDeleteToken(firebaseDependencies, tokenDetails.token)];\r\n case 2:\r\n _a.sent();\r\n return [4 /*yield*/, dbRemove(firebaseDependencies)];\r\n case 3:\r\n _a.sent();\r\n _a.label = 4;\r\n case 4: return [4 /*yield*/, swRegistration.pushManager.getSubscription()];\r\n case 5:\r\n pushSubscription = _a.sent();\r\n if (pushSubscription) {\r\n return [2 /*return*/, pushSubscription.unsubscribe()];\r\n }\r\n // If there's no SW, consider it a success.\r\n return [2 /*return*/, true];\r\n }\r\n });\r\n });\r\n}\r\nfunction updateToken(tokenDetails, firebaseDependencies, swRegistration) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var updatedToken, updatedTokenDetails, e_2;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n _a.trys.push([0, 3, , 5]);\r\n return [4 /*yield*/, requestUpdateToken(firebaseDependencies, tokenDetails)];\r\n case 1:\r\n updatedToken = _a.sent();\r\n updatedTokenDetails = tslib_es6_assign(tslib_es6_assign({}, tokenDetails), { token: updatedToken, createTime: Date.now() });\r\n return [4 /*yield*/, dbSet(firebaseDependencies, updatedTokenDetails)];\r\n case 2:\r\n _a.sent();\r\n return [2 /*return*/, updatedToken];\r\n case 3:\r\n e_2 = _a.sent();\r\n return [4 /*yield*/, deleteToken(firebaseDependencies, swRegistration)];\r\n case 4:\r\n _a.sent();\r\n throw e_2;\r\n case 5: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n}\r\nfunction getNewToken(firebaseDependencies, subscriptionOptions) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var token, tokenDetails;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, requestGetToken(firebaseDependencies, subscriptionOptions)];\r\n case 1:\r\n token = _a.sent();\r\n tokenDetails = {\r\n token: token,\r\n createTime: Date.now(),\r\n subscriptionOptions: subscriptionOptions\r\n };\r\n return [4 /*yield*/, dbSet(firebaseDependencies, tokenDetails)];\r\n case 2:\r\n _a.sent();\r\n return [2 /*return*/, tokenDetails.token];\r\n }\r\n });\r\n });\r\n}\r\n/**\r\n * Gets a PushSubscription for the current user.\r\n */\r\nfunction getPushSubscription(swRegistration, vapidKey) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var subscription;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0: return [4 /*yield*/, swRegistration.pushManager.getSubscription()];\r\n case 1:\r\n subscription = _a.sent();\r\n if (subscription) {\r\n return [2 /*return*/, subscription];\r\n }\r\n return [2 /*return*/, swRegistration.pushManager.subscribe({\r\n userVisibleOnly: true,\r\n // Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key\r\n // submitted to pushManager#subscribe must be of type Uint8Array.\r\n applicationServerKey: base64ToArray(vapidKey)\r\n })];\r\n }\r\n });\r\n });\r\n}\r\n/**\r\n * Checks if the saved tokenDetails object matches the configuration provided.\r\n */\r\nfunction isTokenValid(dbOptions, currentOptions) {\r\n var isVapidKeyEqual = currentOptions.vapidKey === dbOptions.vapidKey;\r\n var isEndpointEqual = currentOptions.endpoint === dbOptions.endpoint;\r\n var isAuthEqual = currentOptions.auth === dbOptions.auth;\r\n var isP256dhEqual = currentOptions.p256dh === dbOptions.p256dh;\r\n return isVapidKeyEqual && isEndpointEqual && isAuthEqual && isP256dhEqual;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2020 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction externalizePayload(internalPayload) {\r\n var payload = {\r\n from: internalPayload.from,\r\n // eslint-disable-next-line camelcase\r\n collapseKey: internalPayload.collapse_key,\r\n // eslint-disable-next-line camelcase\r\n messageId: internalPayload.fcm_message_id\r\n };\r\n propagateNotificationPayload(payload, internalPayload);\r\n propagateDataPayload(payload, internalPayload);\r\n propagateFcmOptions(payload, internalPayload);\r\n return payload;\r\n}\r\nfunction propagateNotificationPayload(payload, messagePayloadInternal) {\r\n if (!messagePayloadInternal.notification) {\r\n return;\r\n }\r\n payload.notification = {};\r\n var title = messagePayloadInternal.notification.title;\r\n if (!!title) {\r\n payload.notification.title = title;\r\n }\r\n var body = messagePayloadInternal.notification.body;\r\n if (!!body) {\r\n payload.notification.body = body;\r\n }\r\n var image = messagePayloadInternal.notification.image;\r\n if (!!image) {\r\n payload.notification.image = image;\r\n }\r\n}\r\nfunction propagateDataPayload(payload, messagePayloadInternal) {\r\n if (!messagePayloadInternal.data) {\r\n return;\r\n }\r\n payload.data = messagePayloadInternal.data;\r\n}\r\nfunction propagateFcmOptions(payload, messagePayloadInternal) {\r\n if (!messagePayloadInternal.fcmOptions) {\r\n return;\r\n }\r\n payload.fcmOptions = {};\r\n var link = messagePayloadInternal.fcmOptions.link;\r\n if (!!link) {\r\n payload.fcmOptions.link = link;\r\n }\r\n // eslint-disable-next-line camelcase\r\n var analyticsLabel = messagePayloadInternal.fcmOptions.analytics_label;\r\n if (!!analyticsLabel) {\r\n payload.fcmOptions.analyticsLabel = analyticsLabel;\r\n }\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction isConsoleMessage(data) {\r\n // This message has a campaign ID, meaning it was sent using the Firebase Console.\r\n return typeof data === 'object' && !!data && CONSOLE_CAMPAIGN_ID in data;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n/** Returns a promise that resolves after given time passes. */\r\nfunction index_esm_sleep(ms) {\r\n return new Promise(function (resolve) {\r\n setTimeout(resolve, ms);\r\n });\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar SwController = /** @class */ (function () {\r\n function SwController(firebaseDependencies) {\r\n var _this = this;\r\n this.firebaseDependencies = firebaseDependencies;\r\n // A boolean flag to determine wether an app is using onBackgroundMessage or\r\n // setBackgroundMessageHandler. onBackgroundMessage will receive a MessagePayload regardless of if\r\n // a notification is displayed. Whereas, setBackgroundMessageHandler will swallow the\r\n // MessagePayload if a NotificationPayload is included.\r\n this.isOnBackgroundMessageUsed = null;\r\n this.vapidKey = null;\r\n this.bgMessageHandler = null;\r\n self.addEventListener('push', function (e) {\r\n e.waitUntil(_this.onPush(e));\r\n });\r\n self.addEventListener('pushsubscriptionchange', function (e) {\r\n e.waitUntil(_this.onSubChange(e));\r\n });\r\n self.addEventListener('notificationclick', function (e) {\r\n e.waitUntil(_this.onNotificationClick(e));\r\n });\r\n }\r\n Object.defineProperty(SwController.prototype, \"app\", {\r\n get: function () {\r\n return this.firebaseDependencies.app;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n /**\r\n * @deprecated. Use onBackgroundMessage(nextOrObserver: NextFn | Observer):\r\n * Unsubscribe instead.\r\n *\r\n * Calling setBackgroundMessageHandler will opt in to some specific behaviors.\r\n *\r\n * 1.) If a notification doesn't need to be shown due to a window already being visible, then push\r\n * messages will be sent to the page. 2.) If a notification needs to be shown, and the message\r\n * contains no notification data this method will be called and the promise it returns will be\r\n * passed to event.waitUntil. If you do not set this callback then all push messages will let and\r\n * the developer can handle them in a their own 'push' event callback\r\n *\r\n * @param callback The callback to be called when a push message is received and a notification\r\n * must be shown. The callback will be given the data from the push message.\r\n */\r\n SwController.prototype.setBackgroundMessageHandler = function (callback) {\r\n this.isOnBackgroundMessageUsed = false;\r\n if (!callback || typeof callback !== 'function') {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"invalid-bg-handler\" /* INVALID_BG_HANDLER */);\r\n }\r\n this.bgMessageHandler = callback;\r\n };\r\n SwController.prototype.onBackgroundMessage = function (nextOrObserver) {\r\n var _this = this;\r\n this.isOnBackgroundMessageUsed = true;\r\n this.bgMessageHandler = nextOrObserver;\r\n return function () {\r\n _this.bgMessageHandler = null;\r\n };\r\n };\r\n // TODO: Remove getToken from SW Controller. Calling this from an old SW can cause all kinds of\r\n // trouble.\r\n SwController.prototype.getToken = function () {\r\n var _a, _b;\r\n return __awaiter(this, void 0, void 0, function () {\r\n var tokenDetails;\r\n return __generator(this, function (_c) {\r\n switch (_c.label) {\r\n case 0:\r\n if (!!this.vapidKey) return [3 /*break*/, 2];\r\n return [4 /*yield*/, dbGet(this.firebaseDependencies)];\r\n case 1:\r\n tokenDetails = _c.sent();\r\n this.vapidKey =\r\n (_b = (_a = tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.subscriptionOptions) === null || _a === void 0 ? void 0 : _a.vapidKey) !== null && _b !== void 0 ? _b : DEFAULT_VAPID_KEY;\r\n _c.label = 2;\r\n case 2: return [2 /*return*/, index_esm_getToken(this.firebaseDependencies, self.registration, this.vapidKey)];\r\n }\r\n });\r\n });\r\n };\r\n // TODO: Remove deleteToken from SW Controller. Calling this from an old SW can cause all kinds of\r\n // trouble.\r\n SwController.prototype.deleteToken = function () {\r\n return deleteToken(this.firebaseDependencies, self.registration);\r\n };\r\n SwController.prototype.requestPermission = function () {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"only-available-in-window\" /* AVAILABLE_IN_WINDOW */);\r\n };\r\n // TODO: Remove this together with getToken from SW Controller.\r\n SwController.prototype.usePublicVapidKey = function (vapidKey) {\r\n if (this.vapidKey !== null) {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"use-vapid-key-after-get-token\" /* USE_VAPID_KEY_AFTER_GET_TOKEN */);\r\n }\r\n if (typeof vapidKey !== 'string' || vapidKey.length === 0) {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"invalid-vapid-key\" /* INVALID_VAPID_KEY */);\r\n }\r\n this.vapidKey = vapidKey;\r\n };\r\n SwController.prototype.useServiceWorker = function () {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"only-available-in-window\" /* AVAILABLE_IN_WINDOW */);\r\n };\r\n SwController.prototype.onMessage = function () {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"only-available-in-window\" /* AVAILABLE_IN_WINDOW */);\r\n };\r\n SwController.prototype.onTokenRefresh = function () {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"only-available-in-window\" /* AVAILABLE_IN_WINDOW */);\r\n };\r\n /**\r\n * A handler for push events that shows notifications based on the content of the payload.\r\n *\r\n * The payload must be a JSON-encoded Object with a `notification` key. The value of the\r\n * `notification` property will be used as the NotificationOptions object passed to\r\n * showNotification. Additionally, the `title` property of the notification object will be used as\r\n * the title.\r\n *\r\n * If there is no notification data in the payload then no notification will be shown.\r\n */\r\n SwController.prototype.onPush = function (event) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var internalPayload, clientList, isNotificationShown, payload;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n internalPayload = getMessagePayloadInternal(event);\r\n if (!internalPayload) {\r\n console.debug(TAG +\r\n 'failed to get parsed MessagePayload from the PushEvent. Skip handling the push.');\r\n return [2 /*return*/];\r\n }\r\n return [4 /*yield*/, getClientList()];\r\n case 1:\r\n clientList = _a.sent();\r\n if (hasVisibleClients(clientList)) {\r\n return [2 /*return*/, sendMessagePayloadInternalToWindows(clientList, internalPayload)];\r\n }\r\n isNotificationShown = false;\r\n if (!!!internalPayload.notification) return [3 /*break*/, 3];\r\n return [4 /*yield*/, showNotification(wrapInternalPayload(internalPayload))];\r\n case 2:\r\n _a.sent();\r\n isNotificationShown = true;\r\n _a.label = 3;\r\n case 3:\r\n // MessagePayload is only passed to `onBackgroundMessage`. Skip passing MessagePayload for\r\n // the legacy `setBackgroundMessageHandler` to preserve the SDK behaviors.\r\n if (isNotificationShown === true &&\r\n this.isOnBackgroundMessageUsed === false) {\r\n return [2 /*return*/];\r\n }\r\n if (!!this.bgMessageHandler) {\r\n payload = externalizePayload(internalPayload);\r\n if (typeof this.bgMessageHandler === 'function') {\r\n this.bgMessageHandler(payload);\r\n }\r\n else {\r\n this.bgMessageHandler.next(payload);\r\n }\r\n }\r\n // wait briefly to allow onBackgroundMessage to complete\r\n return [4 /*yield*/, index_esm_sleep(BACKGROUND_HANDLE_EXECUTION_TIME_LIMIT_MS)];\r\n case 4:\r\n // wait briefly to allow onBackgroundMessage to complete\r\n _a.sent();\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n SwController.prototype.onSubChange = function (event) {\r\n var _a, _b;\r\n return __awaiter(this, void 0, void 0, function () {\r\n var newSubscription, tokenDetails;\r\n return __generator(this, function (_c) {\r\n switch (_c.label) {\r\n case 0:\r\n newSubscription = event.newSubscription;\r\n if (!!newSubscription) return [3 /*break*/, 2];\r\n // Subscription revoked, delete token\r\n return [4 /*yield*/, deleteToken(this.firebaseDependencies, self.registration)];\r\n case 1:\r\n // Subscription revoked, delete token\r\n _c.sent();\r\n return [2 /*return*/];\r\n case 2: return [4 /*yield*/, dbGet(this.firebaseDependencies)];\r\n case 3:\r\n tokenDetails = _c.sent();\r\n return [4 /*yield*/, deleteToken(this.firebaseDependencies, self.registration)];\r\n case 4:\r\n _c.sent();\r\n return [4 /*yield*/, index_esm_getToken(this.firebaseDependencies, self.registration, (_b = (_a = tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.subscriptionOptions) === null || _a === void 0 ? void 0 : _a.vapidKey) !== null && _b !== void 0 ? _b : DEFAULT_VAPID_KEY)];\r\n case 5:\r\n _c.sent();\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n SwController.prototype.onNotificationClick = function (event) {\r\n var _a, _b;\r\n return __awaiter(this, void 0, void 0, function () {\r\n var internalPayload, link, url, originUrl, client;\r\n return __generator(this, function (_c) {\r\n switch (_c.label) {\r\n case 0:\r\n internalPayload = (_b = (_a = event.notification) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b[FCM_MSG];\r\n if (!internalPayload) {\r\n return [2 /*return*/];\r\n }\r\n else if (event.action) {\r\n // User clicked on an action button. This will allow developers to act on action button clicks\r\n // by using a custom onNotificationClick listener that they define.\r\n return [2 /*return*/];\r\n }\r\n // Prevent other listeners from receiving the event\r\n event.stopImmediatePropagation();\r\n event.notification.close();\r\n link = getLink(internalPayload);\r\n if (!link) {\r\n return [2 /*return*/];\r\n }\r\n url = new URL(link, self.location.href);\r\n originUrl = new URL(self.location.origin);\r\n if (url.host !== originUrl.host) {\r\n return [2 /*return*/];\r\n }\r\n return [4 /*yield*/, getWindowClient(url)];\r\n case 1:\r\n client = _c.sent();\r\n if (!!client) return [3 /*break*/, 4];\r\n return [4 /*yield*/, self.clients.openWindow(link)];\r\n case 2:\r\n client = _c.sent();\r\n // Wait three seconds for the client to initialize and set up the message handler so that it\r\n // can receive the message.\r\n return [4 /*yield*/, index_esm_sleep(FOREGROUND_HANDLE_PREPARATION_TIME_MS)];\r\n case 3:\r\n // Wait three seconds for the client to initialize and set up the message handler so that it\r\n // can receive the message.\r\n _c.sent();\r\n return [3 /*break*/, 6];\r\n case 4: return [4 /*yield*/, client.focus()];\r\n case 5:\r\n client = _c.sent();\r\n _c.label = 6;\r\n case 6:\r\n if (!client) {\r\n // Window Client will not be returned if it's for a third party origin.\r\n return [2 /*return*/];\r\n }\r\n internalPayload.messageType = MessageType.NOTIFICATION_CLICKED;\r\n internalPayload.isFirebaseMessaging = true;\r\n return [2 /*return*/, client.postMessage(internalPayload)];\r\n }\r\n });\r\n });\r\n };\r\n return SwController;\r\n}());\r\nfunction wrapInternalPayload(internalPayload) {\r\n var _a;\r\n var wrappedInternalPayload = tslib_es6_assign({}, internalPayload.notification);\r\n // Put the message payload under FCM_MSG name so we can identify the notification as being an FCM\r\n // notification vs a notification from somewhere else (i.e. normal web push or developer generated\r\n // notification).\r\n wrappedInternalPayload.data = (_a = {},\r\n _a[FCM_MSG] = internalPayload,\r\n _a);\r\n return wrappedInternalPayload;\r\n}\r\nfunction getMessagePayloadInternal(_a) {\r\n var data = _a.data;\r\n if (!data) {\r\n return null;\r\n }\r\n try {\r\n return data.json();\r\n }\r\n catch (err) {\r\n // Not JSON so not an FCM message.\r\n return null;\r\n }\r\n}\r\n/**\r\n * @param url The URL to look for when focusing a client.\r\n * @return Returns an existing window client or a newly opened WindowClient.\r\n */\r\nfunction getWindowClient(url) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var clientList, clientList_1, clientList_1_1, client, clientUrl;\r\n var e_1, _a;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0: return [4 /*yield*/, getClientList()];\r\n case 1:\r\n clientList = _b.sent();\r\n try {\r\n for (clientList_1 = __values(clientList), clientList_1_1 = clientList_1.next(); !clientList_1_1.done; clientList_1_1 = clientList_1.next()) {\r\n client = clientList_1_1.value;\r\n clientUrl = new URL(client.url, self.location.href);\r\n if (url.host === clientUrl.host) {\r\n return [2 /*return*/, client];\r\n }\r\n }\r\n }\r\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\r\n finally {\r\n try {\r\n if (clientList_1_1 && !clientList_1_1.done && (_a = clientList_1.return)) _a.call(clientList_1);\r\n }\r\n finally { if (e_1) throw e_1.error; }\r\n }\r\n return [2 /*return*/, null];\r\n }\r\n });\r\n });\r\n}\r\n/**\r\n * @returns If there is currently a visible WindowClient, this method will resolve to true,\r\n * otherwise false.\r\n */\r\nfunction hasVisibleClients(clientList) {\r\n return clientList.some(function (client) {\r\n return client.visibilityState === 'visible' &&\r\n // Ignore chrome-extension clients as that matches the background pages of extensions, which\r\n // are always considered visible for some reason.\r\n !client.url.startsWith('chrome-extension://');\r\n });\r\n}\r\nfunction sendMessagePayloadInternalToWindows(clientList, internalPayload) {\r\n var e_2, _a;\r\n internalPayload.isFirebaseMessaging = true;\r\n internalPayload.messageType = MessageType.PUSH_RECEIVED;\r\n try {\r\n for (var clientList_2 = __values(clientList), clientList_2_1 = clientList_2.next(); !clientList_2_1.done; clientList_2_1 = clientList_2.next()) {\r\n var client = clientList_2_1.value;\r\n client.postMessage(internalPayload);\r\n }\r\n }\r\n catch (e_2_1) { e_2 = { error: e_2_1 }; }\r\n finally {\r\n try {\r\n if (clientList_2_1 && !clientList_2_1.done && (_a = clientList_2.return)) _a.call(clientList_2);\r\n }\r\n finally { if (e_2) throw e_2.error; }\r\n }\r\n}\r\nfunction getClientList() {\r\n return self.clients.matchAll({\r\n type: 'window',\r\n includeUncontrolled: true\r\n // TS doesn't know that \"type: 'window'\" means it'll return WindowClient[]\r\n });\r\n}\r\nfunction showNotification(notificationPayloadInternal) {\r\n var _a;\r\n // Note: Firefox does not support the maxActions property.\r\n // https://developer.mozilla.org/en-US/docs/Web/API/notification/maxActions\r\n var actions = notificationPayloadInternal.actions;\r\n var maxActions = Notification.maxActions;\r\n if (actions && maxActions && actions.length > maxActions) {\r\n console.warn(\"This browser only supports \" + maxActions + \" actions. The remaining actions will not be displayed.\");\r\n }\r\n return self.registration.showNotification(\r\n /* title= */ (_a = notificationPayloadInternal.title) !== null && _a !== void 0 ? _a : '', notificationPayloadInternal);\r\n}\r\nfunction getLink(payload) {\r\n var _a, _b, _c;\r\n // eslint-disable-next-line camelcase\r\n var link = (_b = (_a = payload.fcmOptions) === null || _a === void 0 ? void 0 : _a.link) !== null && _b !== void 0 ? _b : (_c = payload.notification) === null || _c === void 0 ? void 0 : _c.click_action;\r\n if (link) {\r\n return link;\r\n }\r\n if (isConsoleMessage(payload.data)) {\r\n // Notification created in the Firebase Console. Redirect to origin.\r\n return self.location.origin;\r\n }\r\n else {\r\n return null;\r\n }\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar WindowController = /** @class */ (function () {\r\n function WindowController(firebaseDependencies) {\r\n var _this = this;\r\n this.firebaseDependencies = firebaseDependencies;\r\n this.vapidKey = null;\r\n this.onMessageCallback = null;\r\n navigator.serviceWorker.addEventListener('message', function (e) {\r\n return _this.messageEventListener(e);\r\n });\r\n }\r\n Object.defineProperty(WindowController.prototype, \"app\", {\r\n get: function () {\r\n return this.firebaseDependencies.app;\r\n },\r\n enumerable: false,\r\n configurable: true\r\n });\r\n WindowController.prototype.messageEventListener = function (event) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var internalPayload, dataPayload;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n internalPayload = event.data;\r\n if (!internalPayload.isFirebaseMessaging) {\r\n return [2 /*return*/];\r\n }\r\n // onMessageCallback is either a function or observer/subscriber.\r\n // TODO: in the modularization release, have onMessage handle type MessagePayload as supposed to\r\n // the legacy payload where some fields are in snake cases.\r\n if (this.onMessageCallback &&\r\n internalPayload.messageType === MessageType.PUSH_RECEIVED) {\r\n if (typeof this.onMessageCallback === 'function') {\r\n this.onMessageCallback(stripInternalFields(Object.assign({}, internalPayload)));\r\n }\r\n else {\r\n this.onMessageCallback.next(Object.assign({}, internalPayload));\r\n }\r\n }\r\n dataPayload = internalPayload.data;\r\n if (!(isConsoleMessage(dataPayload) &&\r\n dataPayload[CONSOLE_CAMPAIGN_ANALYTICS_ENABLED] === '1')) return [3 /*break*/, 2];\r\n return [4 /*yield*/, this.logEvent(internalPayload.messageType, dataPayload)];\r\n case 1:\r\n _a.sent();\r\n _a.label = 2;\r\n case 2: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n WindowController.prototype.getVapidKey = function () {\r\n return this.vapidKey;\r\n };\r\n WindowController.prototype.getSwReg = function () {\r\n return this.swRegistration;\r\n };\r\n WindowController.prototype.getToken = function (options) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n if (!(Notification.permission === 'default')) return [3 /*break*/, 2];\r\n return [4 /*yield*/, Notification.requestPermission()];\r\n case 1:\r\n _a.sent();\r\n _a.label = 2;\r\n case 2:\r\n if (Notification.permission !== 'granted') {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"permission-blocked\" /* PERMISSION_BLOCKED */);\r\n }\r\n return [4 /*yield*/, this.updateVapidKey(options === null || options === void 0 ? void 0 : options.vapidKey)];\r\n case 3:\r\n _a.sent();\r\n return [4 /*yield*/, this.updateSwReg(options === null || options === void 0 ? void 0 : options.serviceWorkerRegistration)];\r\n case 4:\r\n _a.sent();\r\n return [2 /*return*/, index_esm_getToken(this.firebaseDependencies, this.swRegistration, this.vapidKey)];\r\n }\r\n });\r\n });\r\n };\r\n WindowController.prototype.updateVapidKey = function (vapidKey) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n return __generator(this, function (_a) {\r\n if (!!vapidKey) {\r\n this.vapidKey = vapidKey;\r\n }\r\n else if (!this.vapidKey) {\r\n this.vapidKey = DEFAULT_VAPID_KEY;\r\n }\r\n return [2 /*return*/];\r\n });\r\n });\r\n };\r\n WindowController.prototype.updateSwReg = function (swRegistration) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n if (!(!swRegistration && !this.swRegistration)) return [3 /*break*/, 2];\r\n return [4 /*yield*/, this.registerDefaultSw()];\r\n case 1:\r\n _a.sent();\r\n _a.label = 2;\r\n case 2:\r\n if (!swRegistration && !!this.swRegistration) {\r\n return [2 /*return*/];\r\n }\r\n if (!(swRegistration instanceof ServiceWorkerRegistration)) {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"invalid-sw-registration\" /* INVALID_SW_REGISTRATION */);\r\n }\r\n this.swRegistration = swRegistration;\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n WindowController.prototype.registerDefaultSw = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var _a, e_1;\r\n return __generator(this, function (_b) {\r\n switch (_b.label) {\r\n case 0:\r\n _b.trys.push([0, 2, , 3]);\r\n _a = this;\r\n return [4 /*yield*/, navigator.serviceWorker.register(DEFAULT_SW_PATH, {\r\n scope: DEFAULT_SW_SCOPE\r\n })];\r\n case 1:\r\n _a.swRegistration = _b.sent();\r\n // The timing when browser updates sw when sw has an update is unreliable by my experiment. It\r\n // leads to version conflict when the SDK upgrades to a newer version in the main page, but sw\r\n // is stuck with the old version. For example,\r\n // https://github.com/firebase/firebase-js-sdk/issues/2590 The following line reliably updates\r\n // sw if there was an update.\r\n this.swRegistration.update().catch(function () {\r\n /* it is non blocking and we don't care if it failed */\r\n });\r\n return [3 /*break*/, 3];\r\n case 2:\r\n e_1 = _b.sent();\r\n throw dist_index_esm_ERROR_FACTORY.create(\"failed-service-worker-registration\" /* FAILED_DEFAULT_REGISTRATION */, {\r\n browserErrorMessage: e_1.message\r\n });\r\n case 3: return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n WindowController.prototype.deleteToken = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n if (!!this.swRegistration) return [3 /*break*/, 2];\r\n return [4 /*yield*/, this.registerDefaultSw()];\r\n case 1:\r\n _a.sent();\r\n _a.label = 2;\r\n case 2: return [2 /*return*/, deleteToken(this.firebaseDependencies, this.swRegistration)];\r\n }\r\n });\r\n });\r\n };\r\n /**\r\n * Request permission if it is not currently granted.\r\n *\r\n * @return Resolves if the permission was granted, rejects otherwise.\r\n *\r\n * @deprecated Use Notification.requestPermission() instead.\r\n * https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission\r\n */\r\n WindowController.prototype.requestPermission = function () {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var permissionResult;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n if (Notification.permission === 'granted') {\r\n return [2 /*return*/];\r\n }\r\n return [4 /*yield*/, Notification.requestPermission()];\r\n case 1:\r\n permissionResult = _a.sent();\r\n if (permissionResult === 'granted') {\r\n return [2 /*return*/];\r\n }\r\n else if (permissionResult === 'denied') {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"permission-blocked\" /* PERMISSION_BLOCKED */);\r\n }\r\n else {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"permission-default\" /* PERMISSION_DEFAULT */);\r\n }\r\n }\r\n });\r\n });\r\n };\r\n /**\r\n * @deprecated. Use getToken(options?: {vapidKey?: string; serviceWorkerRegistration?:\r\n * ServiceWorkerRegistration;}): Promise instead.\r\n */\r\n WindowController.prototype.usePublicVapidKey = function (vapidKey) {\r\n if (this.vapidKey !== null) {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"use-vapid-key-after-get-token\" /* USE_VAPID_KEY_AFTER_GET_TOKEN */);\r\n }\r\n if (typeof vapidKey !== 'string' || vapidKey.length === 0) {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"invalid-vapid-key\" /* INVALID_VAPID_KEY */);\r\n }\r\n this.vapidKey = vapidKey;\r\n };\r\n /**\r\n * @deprecated. Use getToken(options?: {vapidKey?: string; serviceWorkerRegistration?:\r\n * ServiceWorkerRegistration;}): Promise instead.\r\n */\r\n WindowController.prototype.useServiceWorker = function (swRegistration) {\r\n if (!(swRegistration instanceof ServiceWorkerRegistration)) {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"invalid-sw-registration\" /* INVALID_SW_REGISTRATION */);\r\n }\r\n if (this.swRegistration) {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"use-sw-after-get-token\" /* USE_SW_AFTER_GET_TOKEN */);\r\n }\r\n this.swRegistration = swRegistration;\r\n };\r\n /**\r\n * @param nextOrObserver An observer object or a function triggered on message.\r\n *\r\n * @return The unsubscribe function for the observer.\r\n */\r\n WindowController.prototype.onMessage = function (nextOrObserver) {\r\n var _this = this;\r\n this.onMessageCallback = nextOrObserver;\r\n return function () {\r\n _this.onMessageCallback = null;\r\n };\r\n };\r\n WindowController.prototype.setBackgroundMessageHandler = function () {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"only-available-in-sw\" /* AVAILABLE_IN_SW */);\r\n };\r\n WindowController.prototype.onBackgroundMessage = function () {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"only-available-in-sw\" /* AVAILABLE_IN_SW */);\r\n };\r\n /**\r\n * @deprecated No-op. It was initially designed with token rotation requests from server in mind.\r\n * However, the plan to implement such feature was abandoned.\r\n */\r\n WindowController.prototype.onTokenRefresh = function () {\r\n return function () { };\r\n };\r\n WindowController.prototype.logEvent = function (messageType, data) {\r\n return __awaiter(this, void 0, void 0, function () {\r\n var eventType, analytics;\r\n return __generator(this, function (_a) {\r\n switch (_a.label) {\r\n case 0:\r\n eventType = getEventType(messageType);\r\n return [4 /*yield*/, this.firebaseDependencies.analyticsProvider.get()];\r\n case 1:\r\n analytics = _a.sent();\r\n analytics.logEvent(eventType, {\r\n /* eslint-disable camelcase */\r\n message_id: data[CONSOLE_CAMPAIGN_ID],\r\n message_name: data[CONSOLE_CAMPAIGN_NAME],\r\n message_time: data[CONSOLE_CAMPAIGN_TIME],\r\n message_device_time: Math.floor(Date.now() / 1000)\r\n /* eslint-enable camelcase */\r\n });\r\n return [2 /*return*/];\r\n }\r\n });\r\n });\r\n };\r\n return WindowController;\r\n}());\r\nfunction getEventType(messageType) {\r\n switch (messageType) {\r\n case MessageType.NOTIFICATION_CLICKED:\r\n return 'notification_open';\r\n case MessageType.PUSH_RECEIVED:\r\n return 'notification_foreground';\r\n default:\r\n throw new Error();\r\n }\r\n}\r\nfunction stripInternalFields(internalPayload) {\r\n delete internalPayload.messageType;\r\n delete internalPayload.isFirebaseMessaging;\r\n return internalPayload;\r\n}\n\n/**\r\n * @license\r\n * Copyright 2019 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nfunction index_esm_extractAppConfig(app) {\r\n var e_1, _a;\r\n if (!app || !app.options) {\r\n throw index_esm_getMissingValueError('App Configuration Object');\r\n }\r\n if (!app.name) {\r\n throw index_esm_getMissingValueError('App Name');\r\n }\r\n // Required app config keys\r\n var configKeys = [\r\n 'projectId',\r\n 'apiKey',\r\n 'appId',\r\n 'messagingSenderId'\r\n ];\r\n var options = app.options;\r\n try {\r\n for (var configKeys_1 = __values(configKeys), configKeys_1_1 = configKeys_1.next(); !configKeys_1_1.done; configKeys_1_1 = configKeys_1.next()) {\r\n var keyName = configKeys_1_1.value;\r\n if (!options[keyName]) {\r\n throw index_esm_getMissingValueError(keyName);\r\n }\r\n }\r\n }\r\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\r\n finally {\r\n try {\r\n if (configKeys_1_1 && !configKeys_1_1.done && (_a = configKeys_1.return)) _a.call(configKeys_1);\r\n }\r\n finally { if (e_1) throw e_1.error; }\r\n }\r\n return {\r\n appName: app.name,\r\n projectId: options.projectId,\r\n apiKey: options.apiKey,\r\n appId: options.appId,\r\n senderId: options.messagingSenderId\r\n };\r\n}\r\nfunction index_esm_getMissingValueError(valueName) {\r\n return dist_index_esm_ERROR_FACTORY.create(\"missing-app-config-values\" /* MISSING_APP_CONFIG_VALUES */, {\r\n valueName: valueName\r\n });\r\n}\n\n/**\r\n * @license\r\n * Copyright 2017 Google LLC\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\nvar MESSAGING_NAME = 'messaging';\r\nfunction factoryMethod(container) {\r\n // Dependencies.\r\n var app = container.getProvider('app').getImmediate();\r\n var appConfig = index_esm_extractAppConfig(app);\r\n var installations = container.getProvider('installations').getImmediate();\r\n var analyticsProvider = container.getProvider('analytics-internal');\r\n var firebaseDependencies = {\r\n app: app,\r\n appConfig: appConfig,\r\n installations: installations,\r\n analyticsProvider: analyticsProvider\r\n };\r\n if (!isSupported()) {\r\n throw dist_index_esm_ERROR_FACTORY.create(\"unsupported-browser\" /* UNSUPPORTED_BROWSER */);\r\n }\r\n if (self && 'ServiceWorkerGlobalScope' in self) {\r\n // Running in ServiceWorker context\r\n return new SwController(firebaseDependencies);\r\n }\r\n else {\r\n // Assume we are in the window context.\r\n return new WindowController(firebaseDependencies);\r\n }\r\n}\r\nvar NAMESPACE_EXPORTS = {\r\n isSupported: isSupported\r\n};\r\nindex_esm.INTERNAL.registerComponent(new Component(MESSAGING_NAME, factoryMethod, \"PUBLIC\" /* PUBLIC */).setServiceProps(NAMESPACE_EXPORTS));\r\nfunction isSupported() {\r\n if (self && 'ServiceWorkerGlobalScope' in self) {\r\n // Running in ServiceWorker context\r\n return isSWControllerSupported();\r\n }\r\n else {\r\n // Assume we are in the window context.\r\n return isWindowControllerSupported();\r\n }\r\n}\r\n/**\r\n * Checks to see if the required APIs exist.\r\n */\r\nfunction isWindowControllerSupported() {\r\n return ('indexedDB' in window &&\r\n indexedDB !== null &&\r\n navigator.cookieEnabled &&\r\n 'serviceWorker' in navigator &&\r\n 'PushManager' in window &&\r\n 'Notification' in window &&\r\n 'fetch' in window &&\r\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\r\n PushSubscription.prototype.hasOwnProperty('getKey'));\r\n}\r\n/**\r\n * Checks to see if the required APIs exist within SW Context.\r\n */\r\nfunction isSWControllerSupported() {\r\n return ('indexedDB' in self &&\r\n indexedDB !== null &&\r\n 'PushManager' in self &&\r\n 'Notification' in self &&\r\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\r\n PushSubscription.prototype.hasOwnProperty('getKey'));\r\n}\n//# sourceMappingURL=index.esm.js.map\n\n;// CONCATENATED MODULE: ./node_modules/firebase/messaging/dist/index.esm.js\n\n//# sourceMappingURL=index.esm.js.map\n\n// EXTERNAL MODULE: ./node_modules/bootstrap/dist/js/bootstrap.js\nvar bootstrap = __webpack_require__(3734);\n;// CONCATENATED MODULE: ./interface/html5/services/NotificationConsumer.js\n/* provided dependency */ var NotificationConsumer_$ = __webpack_require__(9755);\n\n\n\n\n\n\nclass NotificationConsumer {\n\n\tconstructor() {\n\n\t\tconst firebaseConfig = {\n\t\t\tapiKey: \"AIzaSyB9tM0QYb1D3JF07RqpeG-14ADGhezGRws\",\n\t\t\tauthDomain: \"timetrex-app.firebaseapp.com\",\n\t\t\tdatabaseURL: \"https://timetrex-app.firebaseio.com\",\n\t\t\tprojectId: \"timetrex-app\",\n\t\t\tstorageBucket: \"timetrex-app.appspot.com\",\n\t\t\tmessagingSenderId: \"462133047262\",\n\t\t\tappId: \"1:462133047262:web:1705b6bfca364bcd99b74f\"\n\t\t};\n\n\t\t// Initialize Firebase\n\t\tindex_esm.initializeApp( firebaseConfig );\n\t\tthis.browser_supported = index_esm.messaging.isSupported();\n\t\tthis.messaging = index_esm.messaging.isSupported() ? index_esm.messaging() : null;\n\t\tthis.user_notification_device_token_api = TimeTrexClientAPI/* TTAPI.APINotificationDeviceToken */.y.APINotificationDeviceToken;\n\t\tthis.notification_api = TimeTrexClientAPI/* TTAPI.APINotification */.y.APINotification;\n\t\tthis.user_preference_api = TimeTrexClientAPI/* TTAPI.APIUserPreference */.y.APIUserPreference;\n\t\tthis.notification_holder = document.querySelector( '#notification-holder' );\n\t\tthis.notification_duration = 120000;\n\t\tthis.token = '';\n\t\tthis.notification_total = 0;\n\t\tthis.notification_on_screen_total = 0; // How many notification pop ups are currently on screen.\n\t\tthis.create_event_listeners = true;\n\t\tthis.notification_sound = null;\n\t\tthis.sound_timer = null;\n\t\tthis.title_timer = null;\n\t\tthis.previous_page_title = document.title;\n\t\tthis.pending_events = [];\n\t\tthis.event_bus = new services_TTEventBus/* default */.Z({ view_id: 'notification_consumer' });\n\t}\n\n\tsetupUser( request_permission, refresh_token ) {\n\t\tif ( refresh_token === true ) {\n\t\t\tthis.deleteNotificationDeniedCookie();\n\t\t}\n\n\t\tif ( this.isBrowserSupported( refresh_token ) === false ) {\n\t\t\tif ( refresh_token === true ) {\n\t\t\t\tTAlertManager.showAlert( NotificationConsumer_$.i18n._( 'Sorry, this is browser does not support push notifications.' ), NotificationConsumer_$.i18n._( 'Push Notifications' ) );\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t//If impersonating other users do not show notification permission request pop ups or notifications.\n\t\tvar alternate_session_data = getCookie( 'AlternateSessionData' );\n\t\tif ( alternate_session_data && !refresh_token ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t//User has either repeatedly denied permissions or has disabled notifications for this browser in user preferences.\n\t\tif ( this.getNotificationDeniedCookie().asked_count >= 2 && refresh_token === false ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( LocalCacheData.getLoginUser() && APIGlobal.pre_login_data.production === true && APIGlobal.pre_login_data.demo_mode !== true && APIGlobal.pre_login_data.sandbox !== true ) {\n\t\t\tthis.notification_duration = parseInt( LocalCacheData.getLoginUserPreference().notification_duration ) * 1000;\n\n\t\t\tif ( Notification.permission === 'granted' && LocalCacheData.getLoginUserPreference().notification_status_id !== 2 ) {\n\t\t\t\tthis.registerWorkerAndGetToken( true );\n\t\t\t\tthis.createNotificationListeners();\n\t\t\t\tif ( refresh_token === true ) {\n\t\t\t\t\t// Provide feedback to user when they click refresh push notifications button.\n\t\t\t\t\tTAlertManager.showAlert( NotificationConsumer_$.i18n._( 'Push Notifications Enabled' ), NotificationConsumer_$.i18n._( 'Push Notifications' ) );\n\t\t\t\t}\n\t\t\t} else if ( request_permission && Notification.permission === 'default' ) {\n\t\t\t\t//Do not show mobile browsers notification permission alert unless they manually refresh notifications in My Account -> Preferences.\n\t\t\t\tif ( APIGlobal.pre_login_data.user_agent_data.is_mobile === true && refresh_token === false ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tthis.showNotificationPermissionAlert();\n\t\t\t} else if ( refresh_token === true ) {\n\t\t\t\tthis.showNotificationPermissionAlert();\n\t\t\t}\n\t\t} else {\n\t\t\t// Else user has declined permissions.\n\t\t\tif ( refresh_token === true ) {\n\t\t\t\tTAlertManager.showAlert( NotificationConsumer_$.i18n._( 'Sorry, push notifications are disabled on this server.' ), NotificationConsumer_$.i18n._( 'Push Notifications' ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Register our service worker and vapidKey.\n\t// Safari and Firefox require this to trigger on a user action and not just randomly ask.\n\tregisterWorkerAndGetToken( send_token ) {\n\t\ttry {\n\t\t\tnavigator.serviceWorker.register( './services/firebase-messaging-sw.js' )\n\t\t\t\t.then( ( registration ) => {\n\t\t\t\t\tthis.messaging.getToken( {\n\t\t\t\t\t\tserviceWorkerRegistration: registration,\n\t\t\t\t\t\tvapidKey: 'BAIFamGLNE689DChvdL8bWrvgiPFUMGzPwBrxuDiKQNTzpbQu-VZ3urH3SdIOSQ4DUYAOmeTrhmGTNQaNdtW-2I'\n\t\t\t\t\t} ).then( ( currentToken ) => {\n\t\t\t\t\t\tif ( currentToken ) {\n\t\t\t\t\t\t\tthis.token = currentToken;\n\t\t\t\t\t\t\tif ( send_token ) {\n\t\t\t\t\t\t\t\tthis.sendDeviceToken( this.token );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t//If permission alert exists, remove it.\n\t\t\t\t\t\t\tif ( NotificationConsumer_$( '.modal-alert' ).length ) {\n\t\t\t\t\t\t\t\tNotificationConsumer_$( '.modal-alert' ).remove();\n\t\t\t\t\t\t\t\tGlobal.setUIReady();\n\t\t\t\t\t\t\t\tthis.sendAnalytics( 'allow-confirm' ); //Only trigger this when the employee is actually asked to allow permissions. Not everytime the service worker is registered.\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t//request permission window happens\n\t\t\t\t\t\t}\n\t\t\t\t\t} ).catch( ( err ) => {\n\t\t\t\t\t\t// unexpected error\n\t\t\t\t\t} );\n\t\t\t\t} );\n\t\t} catch ( err ) {\n\t\t\tDebug.Text( 'Error attempting to register firebase service workers and push notification service: ' + err.message, 'NotificationConsumer.js', 'NotificationConsumer', 'registerWorkerAndGetToken', 9 );\n\t\t}\n\t}\n\n\tisBrowserSupported( show_message ) {\n\t\tif ( window.location.protocol !== 'https:' ) {\n\t\t\tDebug.Text( 'Not on a HTTPS connection. Push Notifications disabled.', 'NotificationConsumer.js', 'NotificationConsumer', 'checkBrowserSupported', 9 );\n\t\t\tif ( show_message === true ) {\n\t\t\t\t// Provide feedback to user why push notifications are not working if they clicked to refresh push notifications in My Account -> Preferences.\n\t\t\t\tTAlertManager.showAlert( NotificationConsumer_$.i18n._( 'Push Notification are only available on HTTPS connections.' ), NotificationConsumer_$.i18n._( 'Push Notifications' ) );\n\t\t\t}\n\t\t\treturn false;\n\t\t} else if ( this.browser_supported === false ) {\n\t\t\tDebug.Text( 'User on an unsupported browser.', 'NotificationConsumer.js', 'NotificationConsumer', 'checkBrowserSupported', 9 );\n\t\t\tif ( show_message === true ) {\n\t\t\t\t// Provide feedback to user why push notifications are not working if they clicked to refresh push notifications in My Account -> Preferences.\n\t\t\t\tTAlertManager.showAlert( NotificationConsumer_$.i18n._( 'Push Notification are not supported on this browser.' ), NotificationConsumer_$.i18n._( 'Push Notifications' ) );\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tsendDeviceToken( device_token ) {\n\t\tthis.user_notification_device_token_api.checkAndSetNotificationDeviceToken( device_token, 100, {\n\t\t\tonResult: function( res ) {\n\t\t\t\tlet result = res.getResult();\n\t\t\t}\n\t\t} );\n\t}\n\n\tdeleteToken() {\n\t\tvar $this = this;\n\t\tif ( this.token ) {\n\t\t\tthis.messaging.deleteToken().then( ( result ) => {\n\t\t\t\tlet data = {};\n\t\t\t\tdata.device_token = this.token;\n\t\t\t\tthis.user_notification_device_token_api.deleteNotificationDeviceToken( [data], {\n\t\t\t\t\tonResult: function( res ) {\n\t\t\t\t\t\t$this.token = '';\n\t\t\t\t\t\tvar result = res.getResult();\n\t\t\t\t\t\tif ( result ) {\n\t\t\t\t\t\t\tDebug.Text( 'Successfully deleted device token.', 'NotificationConsumer.js', 'NotificationConsumer', 'deleteToken', 9 );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDebug.Text( 'Failed to delete device token.', 'NotificationConsumer.js', 'NotificationConsumer', 'deleteToken', 9 );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} ).catch( ( err ) => {\n\t\t\t\tDebug.Text( 'ERROR: While attempting to delete notification device token.', 'NotificationConsumer.js', 'NotificationConsumer', 'deleteToken', 9 );\n\t\t\t} );\n\t\t}\n\t}\n\n\tdeleteAllTokens() {\n\t\t//This deletion path does necessarily mean the current session has a device token, but will attempt to delete all device tokens for the current user.\n\t\tvar $this = this;\n\t\tthis.user_notification_device_token_api.deleteAllNotificationDeviceTokens( {\n\t\t\tonResult: function( res ) {\n\t\t\t\t$this.token = '';\n\t\t\t\tvar result = res.getResult();\n\t\t\t\tif ( result ) {\n\t\t\t\t\tDebug.Text( 'Successfully deleted all device tokens.', 'NotificationConsumer.js', 'NotificationConsumer', 'DeleteAllDeviceTokens', 9 );\n\t\t\t\t} else {\n\t\t\t\t\tDebug.Text( 'Failed to delete all device tokens, none may exist.', 'NotificationConsumer.js', 'NotificationConsumer', 'DeleteAllDeviceTokens', 9 );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\tcreateNotificationListeners() {\n\t\tif ( this.create_event_listeners === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar $this = this;\n\t\tthis.create_event_listeners = false;\n\n\t\t// Handles foreground, background and background notification-clicked events.\n\t\tnavigator.serviceWorker.addEventListener( 'message', payload => {\n\t\t\tthis.handlePushNotificationEvent( payload.data.messageType === 'push-received', payload.data );\n\t\t} );\n\n\t\tthis.notification_holder.addEventListener( 'click', event => {\n\t\t\tvar element = event.target;\n\t\t\tif ( element.className === 'notification-close' ) {\n\t\t\t\t// Ignored notifications are not marked as read.\n\t\t\t\tthis.removeNotification( element.parentNode.parentNode.parentNode );\n\t\t\t} else if ( element.className === 'notification-link' ) {\n\t\t\t\t// Mark notification as read when user clicks \"view details\" and is sent to the notificwtion link.\n\t\t\t\tthis.setNotificationAsRead( element.id );\n\t\t\t\tthis.removeNotification( element.parentNode.parentNode );\n\n\t\t\t\t//If notification has an open_view event attached, trigger that event and then delete it.\n\t\t\t\tfor ( var i = this.pending_events.length - 1; i >= 0; i-- ) {\n\t\t\t\t\tif ( this.pending_events[i].id === element.id && this.pending_events[i].event === 'open_view' ) {\n\t\t\t\t\t\tthis.openViewLinkedToNotification( this.pending_events[i].event_data );\n\t\t\t\t\t\tevent.preventDefault(); //Stop default href from being followed.\n\t\t\t\t\t\tthis.pending_events.splice( i, 1 ); //Delete event from pending events.\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\twindow.addEventListener( 'focus', function( event ) {\n\t\t\t$this.cancelTimers();\n\t\t}, false );\n\t}\n\n\thandlePushNotificationEvent( foreground, payload ) {\n\t\tlet timetrex_data = JSON.parse( payload.data.timetrex );\n\n\t\tDebug.Arr( payload, 'Push notification received.', 'NotificationConsumer.js', 'NotificationConsumer', 'handlePushNotificationEvent', 9 );\n\n\t\tthis.event_bus.emit( 'tt_topbar', 'profile_pending_counts', { //When push notification received update all \"My Profile\" badges.\n\t\t\tobject_types: []\n\t\t} );\n\n\t\t// If on foreground displays the notification.\n\t\tif ( payload.messageType !== 'notification-clicked' && timetrex_data.user_id !== undefined && LocalCacheData.getLoginUser() && LocalCacheData.getLoginUser().id === timetrex_data.user_id && payload.notification && payload.notification.title ) {\n\t\t\t// Increment total on bell everytime a new notification comes in.\n\t\t\tthis.updateBell( true, this.notification_total + 1 );\n\t\t\tthis.showNotification( payload.notification.title, payload.notification.body, payload.notification.click_action, timetrex_data.id, timetrex_data.priority, payload.data.link_target ? payload.data.link_target : '' );\n\t\t\tDebug.Text( 'Showing Notification on UI as user_id matches and notification was not a system click.', 'NotificationConsumer.js', 'NotificationConsumer', 'handlePushNotificationEvent', 9 );\n\t\t}\n\n\t\tif ( payload.messageType === 'notification-clicked' ) {\n\t\t\tDebug.Text( 'Notification was clicked on from desktop.', 'NotificationConsumer.js', 'NotificationConsumer', 'handlePushNotificationEvent', 9 );\n\n\t\t\t// Set notification as read as we about to redirect the user to the notification.\n\t\t\tthis.setNotificationAsRead( timetrex_data.id );\n\t\t\t// If the notification toast is still on screen remove it.\n\t\t\tthis.removeNotificationById( timetrex_data.id );\n\n\t\t\t// User clicked desktop notification, redirect them directly to the notification if a click_action was given.\n\t\t\tif ( payload.notification.click_action !== undefined && payload.notification.click_action !== '' ) {\n\t\t\t\twindow.location = payload.notification.click_action;\n\t\t\t} else {\n\t\t\t\twindow.location = Global.getBaseURL() + '#!m=Notification';\n\t\t\t}\n\t\t} else {\n\t\t\t//Handle background events if any are in the payload.\n\t\t\tif ( timetrex_data.event !== undefined && timetrex_data.event.length > 0 ) {\n\t\t\t\tthis.handleBackgroundEvent( timetrex_data );\n\t\t\t}\n\t\t}\n\t}\n\n\thandleBackgroundEvent( timetrex_data ) {\n\t\t// Handles timetrex specific data of notification payload.\n\t\tDebug.Text( 'Background action was supplied in the push notification.', 'NotificationConsumer.js', 'NotificationConsumer', 'handlePushNotificationEvent', 9 );\n\t\tfor ( let i = 0; i < timetrex_data.event.length; i++ ) {\n\t\t\tswitch ( timetrex_data.event[i].type ) {\n\t\t\t\tcase 'clean_cache':\n\t\t\t\t\tLocalCacheData.cleanNecessaryCache();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'open_view':\n\t\t\t\t\t//Only triggered if user clicks the notification.\n\t\t\t\t\tthis.pending_events.push( {\n\t\t\t\t\t\tid: timetrex_data.id,\n\t\t\t\t\t\tevent: timetrex_data.event[i].type,\n\t\t\t\t\t\tevent_data: timetrex_data.event[i]\n\t\t\t\t\t} );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'open_view_immediate':\n\t\t\t\t\tthis.openViewLinkedToNotification( timetrex_data.event[i] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'redirect':\n\t\t\t\t\tif ( timetrex_data.event[i].ask === 1 ) {\n\t\t\t\t\t\tTAlertManager.showConfirmAlert( NotificationConsumer_$.i18n._( timetrex_data.event[i].text ), NotificationConsumer_$.i18n._( 'Redirect Confirmation' ), ( flag ) => {\n\t\t\t\t\t\t\tif ( flag === true ) {\n\t\t\t\t\t\t\t\tif ( timetrex_data.event[i].target && timetrex_data.event[i].target === '_blank' ) {\n\t\t\t\t\t\t\t\t\twindow.open(\n\t\t\t\t\t\t\t\t\t\ttimetrex_data.event[i].link,\n\t\t\t\t\t\t\t\t\t\t'_blank'\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\twindow.location = timetrex_data.event[i].link;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( timetrex_data.event[i].target && timetrex_data.event[i].target === '_blank' ) {\n\t\t\t\t\t\t\twindow.open(\n\t\t\t\t\t\t\t\ttimetrex_data.event[i].link,\n\t\t\t\t\t\t\t\t'_blank'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twindow.location = timetrex_data.event[i].link;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'refresh_job_queue':\n\t\t\t\t\tthis.event_bus.emit( 'tt_topbar', 'toggle_job_queue_spinner', {\n\t\t\t\t\t\t//Boolean events for job queue spinner.\n\t\t\t\t\t\tshow: timetrex_data.event[i].show, //Show the job queue spinner\n\t\t\t\t\t\tget_job_data: timetrex_data.event[i].get_job_data, //Update job queue panel data\n\t\t\t\t\t\tcheck_completed: timetrex_data.event[i].check_completed //Check if job queue is completed and hide the job queue spinner if no pending tasks.\n\t\t\t\t\t} );\n\n\t\t\t\t\t//Update TimeSheet is user is on it.\n\t\t\t\t\tif ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.viewId === 'TimeSheet' ) {\n\t\t\t\t\t\tLocalCacheData.current_open_primary_controller.search();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\topenViewLinkedToNotification( event_data ) {\n\t\t//Open a view with the option of pre-filling fields.\n\t\tLocalCacheData.setAutoFillData( event_data.data );\n\t\t// This is taking them to listview in some cases so a on a onAdd/onEdit click can be clicked afterwards.\n\t\tIndexViewController.goToViewByViewLabel( event_data.view_name );\n\n\t\t// Ignore edit only views that don't have list views.\n\t\tif ( event_data.view_name !== 'InOut' && event_data.view_name !== 'Contact Information' ) {\n\t\t\t// Need to add the promise before onTabShow is called where it's originally intended to be added otherwise the below wait is not triggered.\n\t\t\tTTPromise.add( 'BaseViewController', 'onTabShow' );\n\t\t\tTTPromise.wait( 'BaseViewController', 'onTabShow', function() {\n\t\t\t\tif ( event_data.action === 'add' ) {\n\t\t\t\t\tLocalCacheData.current_open_primary_controller.onAddClick();\n\t\t\t\t} else if ( event_data.action === 'edit' ) {\n\t\t\t\t\tLocalCacheData.current_open_primary_controller.onEditClick( event_data.view_id );\n\t\t\t\t} else if ( event_data.action === 'view' ) {\n\t\t\t\t\tLocalCacheData.current_open_primary_controller.onViewClick( event_data.view_id );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\tsetNotificationDeniedCookie( cookie_value ) {\n\t\tcookie_value.asked_count++;\n\t\tcookie_value.last_asked = new Date().getTime();\n\n\t\tsetCookie( 'disable_push_notification_ask', JSON.stringify( cookie_value ), 10000, APIGlobal.pre_login_data.cookie_base_url );\n\t}\n\n\tdeleteNotificationDeniedCookie() {\n\t\tdeleteCookie( 'disable_push_notification_ask' );\n\t}\n\n\tgetNotificationDeniedCookie() {\n\t\tif ( getCookie( 'disable_push_notification_ask' ) ) {\n\t\t\treturn JSON.parse( getCookie( 'disable_push_notification_ask' ) );\n\t\t}\n\n\t\tvar cookie_value = {};\n\t\tcookie_value.asked_count = 0;\n\t\tcookie_value.last_asked = 0;\n\n\t\treturn cookie_value;\n\t}\n\n\tshowNotificationPermissionAlert() {\n\t\t//Only ever ask twice to enable notification permissions for this browser.\n\t\t//If we have only asked once before and it has been 180 days since then, ask again.\n\t\tvar notification_denied_cookie = this.getNotificationDeniedCookie();\n\t\tif ( notification_denied_cookie.asked_count > 1 || notification_denied_cookie.last_asked + ( 180 * 24 * 60 * 60 * 1000 ) > new Date().getTime() ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tTAlertManager.showModalAlert( 'push_notification', 'ask', ( flag ) => {\n\t\t\tif ( flag === true ) {\n\t\t\t\tthis.showPermissionHelp();\n\t\t\t\tthis.setUserPreferencePushNotification( 1 );\n\t\t\t\tthis.sendAnalytics( 'allow' );\n\t\t\t} else {\n\t\t\t\tthis.setUserPreferencePushNotification( 0 );\n\t\t\t\tthis.sendAnalytics( 'deny' );\n\t\t\t\tthis.setNotificationDeniedCookie( notification_denied_cookie );\n\t\t\t}\n\t\t} );\n\t}\n\n\tshowPermissionHelp() {\n\t\tthis.registerWorkerAndGetToken( true );\n\t\tthis.createNotificationListeners();\n\n\t\tTAlertManager.showModalAlert( 'push_notification', 'wait_for_permission', ( flag ) => {\n\t\t\tif ( flag === true ) {\n\t\t\t\tTAlertManager.showModalAlert( 'push_notification', 'help_text', '' );\n\t\t\t\tthis.showArrowToEnablePushNotifications();\n\t\t\t\tthis.sendAnalytics( 'unsure' );\n\t\t\t}\n\t\t} );\n\t}\n\n\tshowArrowToEnablePushNotifications() {\n\t\tconst arrow = NotificationConsumer_$( '
    ' +\n\t\t\t'' +\n\t\t\t'
    ' );\n\n\t\tNotificationConsumer_$( '.modal-alert' ).append( arrow );\n\t}\n\n\tsetUserPreferencePushNotification( status ) {\n\t\tif ( LocalCacheData.getLoginUser() && LocalCacheData.getLoginUserPreference() ) {\n\t\t\tvar data = {};\n\n\t\t\tdata.user_id = LocalCacheData.getLoginUser().id;\n\t\t\tdata.id = LocalCacheData.getLoginUserPreference().id;\n\t\t\tdata.browser_permission_ask_date = Math.round( new Date().getTime() / 1000 );\n\t\t\t//If user agrees set notifications to enabled. Else only set last browser_permission_ask_date.\n\t\t\tif ( status === 1 ) {\n\t\t\t\tdata.notification_status_id = status;\n\t\t\t}\n\n\t\t\tthis.user_preference_api.setUserPreference( data, {\n\t\t\t\tonResult: function( res ) {\n\t\t\t\t\tlet result = res.getResult();\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\tsendAnalytics( choice ) {\n\t\tGlobal.sendAnalyticsEvent( 'push_notifications', 'click', 'click:push_notifications:' + choice );\n\t}\n\n\tgetUnreadNotifications() {\n\t\tthis.notification_api.getUnreadNotifications( {\n\t\t\tonResult: ( result ) => {\n\t\t\t\tthis.notification_total = parseInt( result.getResult() );\n\t\t\t\tthis.updateBell( false, this.notification_total );\n\t\t\t}\n\t\t} );\n\t}\n\n\tgetSystemNotifications( target ) {\n\t\tthis.notification_api.getSystemNotification( target, {\n\t\t\tonResult: ( result ) => {\n\t\t\t\tvar new_system_notifications = parseInt( result.getResult() );\n\n\t\t\t\tif ( new_system_notifications > 0 ) {\n\t\t\t\t\tthis.updateBell( true, this.notification_total + new_system_notifications );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\tsetNotificationAsRead( id ) {\n\t\tthis.notification_api.setNotificationStatus( [id], 20, {\n\t\t\tonResult: ( result ) => {\n\t\t\t\tthis.updateBell( true, this.notification_total - 1 );\n\t\t\t}\n\t\t} );\n\t}\n\n\tupdateBell( manual, amount ) {\n\t\tif ( manual ) {\n\t\t\tthis.notification_total = amount;\n\t\t}\n\n\t\tthis.event_bus.emit( 'tt_topbar', 'notification_bell', {\n\t\t\tnotification_count: this.notification_total\n\t\t});\n\t}\n\n\tplaySound() {\n\t\t// Only load notification sound when we first need it. Then reuse from then on.\n\t\tif ( this.notification_sound === null ) {\n\t\t\tthis.notification_sound = new Audio();\n\t\t\tthis.notification_sound.src = Global.getBaseURL( '../' ) + 'sounds/notification.mp3';\n\t\t\tthis.notification_sound.load();\n\t\t}\n\n\t\tconst playPromise = this.notification_sound.play();\n\t\tif ( playPromise !== undefined ) { //Older browsers play() does not return anything.\n\t\t\tplayPromise.then( () => {\n\t\t\t\t//Notification audio is playing.\n\t\t\t} )\n\t\t\t\t.catch( error => {\n\t\t\t\t\tconsole.log( error );\n\t\t\t\t} );\n\t\t}\n\t}\n\n\tstartTimers( notification ) {\n\t\tvar $this = this;\n\t\tif ( document.hasFocus() === false && this.sound_timer === null ) {\n\t\t\t//Change page title and repeat notififation sound if page does not have focus and no timer is already set.\n\t\t\tthis.sound_timer = setInterval( function() {\n\t\t\t\tif ( document.hasFocus() ) {\n\t\t\t\t\t//If tab is in focus cancel the timer.\n\t\t\t\t\t$this.cancelTimers();\n\t\t\t\t} else {\n\t\t\t\t\t$this.playSound();\n\t\t\t\t}\n\t\t\t}, 5000 );\n\n\t\t\tthis.title_timer = setInterval( function() {\n\t\t\t\tif ( document.hasFocus() ) {\n\t\t\t\t\t//If tab is in focus cancel the timer.\n\t\t\t\t\t$this.cancelTimers();\n\t\t\t\t} else {\n\t\t\t\t\tif ( document.title === '!!!!!!!!!!!!!' ) {\n\t\t\t\t\t\tdocument.title = NotificationConsumer_$.i18n._( 'NOTICE!' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdocument.title = '!!!!!!!!!!!!!';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, 2000 );\n\t\t}\n\t}\n\n\tcancelTimers() {\n\t\tif ( this.sound_timer !== null ) {\n\t\t\tclearInterval( this.sound_timer );\n\t\t\tthis.sound_timer = null;\n\t\t}\n\n\t\tif ( this.title_timer !== null ) {\n\t\t\tdocument.title = this.previous_page_title;\n\t\t\tclearInterval( this.title_timer );\n\t\t\tthis.title_timer = null;\n\t\t}\n\t}\n\n\tshowNotification( title, body, url, notification_id, priority, target ) {\n\t\tif ( priority == 10 ) {\n\t\t\t//User is not notified nor receives toast for low priority notifications.\n\t\t\treturn false;\n\t\t}\n\n\t\t//All notifications other than low play notification sound.\n\t\tthis.playSound();\n\n\t\t// To stop infinite stacking notifications on screen we only show up to 5 at a time.\n\t\t// Allow high and critical priority notifications with priority 1 or 2 through.\n\t\tif ( this.notification_on_screen_total >= 5 && priority > 2 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst notification = document.createElement( 'div' );\n\t\tnotification.className = 'toast show toast-spacing';\n\t\tnotification.style = 'width: 22rem; background-color: hsla(0, 0%, 100%, 1) !important; margin-bottom: 0.4rem !important;';\n\n\t\tconst notification_header = document.createElement( 'div' );\n\t\tnotification_header.className = 'toast-header';\n\n\t\tconst notification_title = document.createElement( 'strong' );\n\t\tnotification_title.className = 'mr-auto';\n\t\tnotification_title.textContent = title;\n\n\t\tconst notification_close_button = document.createElement( 'button' );\n\t\tnotification_close_button.className = 'ml-2 mb-1 close';\n\t\tnotification_close_button.setAttribute( 'aria-label', 'close' );\n\t\tnotification_close_button.innerHTML = '×';\n\n\t\tconst notification_body = document.createElement( 'div' );\n\t\tnotification_body.className = 'toast-body';\n\n\t\tconst notification_body_text = document.createElement( 'p' );\n\t\tnotification_body_text.textContent = body;\n\n\t\tconst notification_body_link = document.createElement( 'a' );\n\t\tnotification_body_link.textContent = 'View Details';\n\t\tnotification_body_link.id = notification_id;\n\t\tnotification_body_link.className = 'notification-link';\n\t\tif ( url !== undefined && url !== '' ) {\n\t\t\tnotification_body_link.href = url;\n\t\t} else {\n\t\t\tnotification_body_link.href = Global.getBaseURL() + '#!m=Notification';\n\t\t}\n\n\t\tif ( target === '_blank' ) {\n\t\t\tnotification_body_link.target = '_blank';\n\t\t}\n\n\t\tnotification_header.appendChild( notification_title );\n\t\tnotification_header.appendChild( notification_close_button );\n\t\tnotification.appendChild( notification_header );\n\n\t\tnotification_body.appendChild( notification_body_text );\n\t\tnotification_body.appendChild( notification_body_link );\n\t\tnotification.appendChild( notification_body );\n\n\t\tthis.notification_holder.appendChild( notification );\n\n\t\tthis.notification_on_screen_total++;\n\n\t\tif ( priority == 2 ) {\n\t\t\t//High priority notifications flash border twice around notification.\n\t\t\tnotification.className += ' notification-outline-repeat';\n\t\t} else if ( priority == 1 ) {\n\t\t\t//Critical priority notification repeat the notification sound, change document title and continuously flash border around toast.\n\t\t\tthis.startTimers( notification );\n\t\t\tnotification.className += ' notification-outline-infinite';\n\t\t}\n\n\t\tif ( this.notification_duration !== 0 && priority != 1 ) {\n\t\t\t// User notification preferences with 0 delay or critical notifications with priority 1 are never automatically removed.\n\t\t\tsetTimeout( () => {\n\t\t\t\tthis.removeNotification( notification );\n\t\t\t}, this.notification_duration );\n\t\t}\n\t}\n\n\tremoveNotification( notification ) {\n\t\tif ( notification ) {\n\t\t\tthis.notification_on_screen_total--;\n\t\t\tnotification.remove();\n\t\t}\n\t}\n\n\tremoveNotificationById( id ) {\n\t\tvar notification_link = document.getElementById( id );\n\t\tif ( notification_link ) {\n\t\t\tthis.removeNotification( notification_link.parentNode.parentNode );\n\t\t}\n\t}\n\n\tremoveAllNotifications() {\n\t\tvar notifications = document.querySelectorAll( \".toast\" );\n\t\tfor ( var i = 0; i < notifications.length; i++ ) {\n\t\t\tthis.removeNotification( notifications[i] );\n\t\t}\n\t\tthis.cancelTimers();\n\t}\n\n\tdetectBrowserNeedsExtraPermission() {\n\t\t// Some browsers by default block push notification permission so we need to detect them to show user a different prompt\n\t\tif ( Global.getBrowserVendor() === 'Edge' ) {\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n}\n\nconst NotificationConsumerObj = new NotificationConsumer();\n// EXTERNAL MODULE: ./interface/html5/IndexController.js\nvar IndexController = __webpack_require__(8678);\n// EXTERNAL MODULE: ./interface/html5/global/TTUUID.js\nvar TTUUID = __webpack_require__(4936);\n// EXTERNAL MODULE: ./interface/html5/global/TTPromise.js\nvar global_TTPromise = __webpack_require__(9504);\n// EXTERNAL MODULE: ./interface/html5/global/ProgressBarManager.js\nvar ProgressBarManager = __webpack_require__(587);\n// EXTERNAL MODULE: ./interface/html5/views/wizard/BaseWizardController.js\nvar BaseWizardController = __webpack_require__(9312);\n// EXTERNAL MODULE: ./interface/html5/global/PermissionManager.js\nvar global_PermissionManager = __webpack_require__(8843);\n// EXTERNAL MODULE: ./interface/html5/global/TAlertManager.js\nvar global_TAlertManager = __webpack_require__(9239);\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/context_menu/TTContextMenu.vue?vue&type=template&id=6ac4a152&scoped=true\n\n\nconst TTContextMenuvue_type_template_id_6ac4a152_scoped_true_withScopeId = n => (_pushScopeId(\"data-v-6ac4a152\"),n=n(),_popScopeId(),n)\nconst TTContextMenuvue_type_template_id_6ac4a152_scoped_true_hoisted_1 = { class: \"context-menu-bar\" }\nconst TTContextMenuvue_type_template_id_6ac4a152_scoped_true_hoisted_2 = { class: \"left-container\" }\nconst TTContextMenuvue_type_template_id_6ac4a152_scoped_true_hoisted_3 = { class: \"center-container\" }\nconst TTContextMenuvue_type_template_id_6ac4a152_scoped_true_hoisted_4 = { class: \"right-container\" }\n\nfunction TTContextMenuvue_type_template_id_6ac4a152_scoped_true_render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_TTContextButton = (0,vue_esm_bundler/* resolveComponent */.up)(\"TTContextButton\")\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", TTContextMenuvue_type_template_id_6ac4a152_scoped_true_hoisted_1, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", TTContextMenuvue_type_template_id_6ac4a152_scoped_true_hoisted_2, [\n ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createElementBlock */.iD)(vue_esm_bundler/* Fragment */.HY, null, (0,vue_esm_bundler/* renderList */.Ko)($options.alignItems.left, (item) => {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(_component_TTContextButton, {\n id: 'context-group-'+item.items[0].id,\n class: (0,vue_esm_bundler/* normalizeClass */.C_)([$options.dynamicClasses.nowrap, item.action_group_id]),\n items: item.items\n }, null, 8 /* PROPS */, [\"id\", \"class\", \"items\"]))\n }), 256 /* UNKEYED_FRAGMENT */))\n ]),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", TTContextMenuvue_type_template_id_6ac4a152_scoped_true_hoisted_3, [\n ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createElementBlock */.iD)(vue_esm_bundler/* Fragment */.HY, null, (0,vue_esm_bundler/* renderList */.Ko)($options.alignItems.center, (item) => {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(_component_TTContextButton, {\n id: 'context-group-'+item.items[0].id,\n class: (0,vue_esm_bundler/* normalizeClass */.C_)([$options.dynamicClasses.nowrap, item.action_group_id]),\n items: item.items\n }, null, 8 /* PROPS */, [\"id\", \"class\", \"items\"]))\n }), 256 /* UNKEYED_FRAGMENT */))\n ]),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", TTContextMenuvue_type_template_id_6ac4a152_scoped_true_hoisted_4, [\n ((0,vue_esm_bundler/* openBlock */.wg)(true), (0,vue_esm_bundler/* createElementBlock */.iD)(vue_esm_bundler/* Fragment */.HY, null, (0,vue_esm_bundler/* renderList */.Ko)($options.alignItems.right, (item) => {\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createBlock */.j4)(_component_TTContextButton, {\n id: 'context-group-'+item.items[0].id,\n class: (0,vue_esm_bundler/* normalizeClass */.C_)([$options.dynamicClasses.nowrap, item.action_group_id]),\n items: item.items\n }, null, 8 /* PROPS */, [\"id\", \"class\", \"items\"]))\n }), 256 /* UNKEYED_FRAGMENT */))\n ])\n ]))\n}\n;// CONCATENATED MODULE: ./interface/html5/components/context_menu/TTContextMenu.vue?vue&type=template&id=6ac4a152&scoped=true\n\n// EXTERNAL MODULE: ./interface/html5/components/context_menu/TTContextButton.vue + 24 modules\nvar TTContextButton = __webpack_require__(777);\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/context_menu/TTContextMenu.vue?vue&type=script&lang=js\n\n\n// Note: No longer need to import the context menu manager, as we only respond to events generated from it.\n\n/* harmony default export */ const TTContextMenuvue_type_script_lang_js = ({\n name: \"TTContextMenu\",\n created() {\n this.event_bus = new TTEventBus( {\n component_id: this.component_id + this.menu_id, //Context menu is unique to each view and is removed when the view is closed.\n } );\n // Debug.Text( 'Context menu created.', 'TTContextMenu.vue', 'TTContextMenu', 'created', 10 );\n\n /*\n * Init event listeners with EventBus to handle data coming from outside the component/Vue.\n */\n\n /* -------- Event Listener for MENU updates -------- */\n let onUpdateMenu = function ( event_data ) {\n // If the view id changes when the menu is re-built, update current view id. Only menu update should change active view id.\n // if( this.active_view_id !== event_data.view_id ) {\n // // Debug.Highlight('Active view for context menu updated to: '+event_data.view_id+', previous was: '+ this.active_view_id);\n // this.active_view_id = event_data.view_id;\n // }\n\n if( this.menu_id === event_data.menu_id ) {\n // Debug.Highlight('Context menu update received for: '+ event_data.menu_id, event_data );\n Debug.Text( 'Contextmenu\\n MENU update RECEIVED for: '+ event_data.menu_id, 'TTContextMenu.vue', 'TTContextMenu', 'created:EventBus:update_context_menu', 11 );\n this.rebuildMenu( event_data.menu_model );\n } else {\n Debug.Warn( 'Error: Context Menu update does not match menu id.\\nThis menu: '+ this.menu_id +'\\nEvent menu: '+event_data.menu_id, 'TTContextMenu.vue', 'TTContextMenu', 'created:EventBus:update_context_menu', 11 );\n }\n }.bind(this); // Must bind to this at variable definition, not in the EventBus on/off as each .bind creates a new function reference, so it wont be able to match up on delete.\n\n // EventBus.on( this.viewId + '.updateContextMenu', ( event_data ) => {\n this.event_bus.on( this.component_id, 'update_context_menu', onUpdateMenu, TTEventBusStatics.AUTO_CLEAR_ON_EXIT );\n\n /* -------- Event Listener for ITEM updates -------- */\n let onUpdateItem = function( event_data ) {\n if( this.menu_id === event_data.menu_id ) {\n Debug.Text( 'Contextmenu\\n ITEM update RECEIVED for: '+ event_data.menu_id + ':' + event_data.item_id, 'TTContextMenu.vue', 'TTContextMenu', 'created:EventBus:update_item', 11 );\n this.updateMenuItem( event_data.item_id, event_data.item_attributes );\n } else {\n // If the view id does not match active view, then ignore the update, as its probably the previous view.\n // Must ignore update if no match, otherwise item updates from old and new view will conflict and context menu items may then not display as expected. (BugFix: TimeSheet->JumpTo->AddRequest->Cancel. Visible icons not as expected. Cancel icon not disabled).\n Debug.Warn( 'Error: Context Menu Item update does not match menu id.\\nThis menu: '+ this.menu_id +'\\nEvent menu: '+event_data.menu_id, 'TTContextMenu.vue', 'TTContextMenu', 'created:EventBus:updateItem', 11 );\n }\n }.bind(this); // Must bind to this at variable definition, not in the EventBus on/off as each .bind creates a new function reference, so it wont be able to match up on delete.\n\n\n // EventBus.on( this.viewId + '.updateItem', ( event_data ) => {\n this.event_bus.on( this.component_id, 'update_item', onUpdateItem, TTEventBusStatics.AUTO_CLEAR_ON_EXIT );\n\n /* -------- Event Listener for MULTISELECTITEM updates -------- */\n let onActivateMultiSelectItem = function( event_data ) {\n if( this.menu_id === event_data.menu_id ) {\n Debug.Text( 'Contextmenu\\n MULTI_ITEM update RECEIVED for: '+ event_data.menu_id + ':' + event_data.item_id, 'TTContextMenu.vue', 'TTContextMenu', 'created:EventBus:activate_multi_select_item', 11 );\n this.activateMultiSelectItem( event_data.item_id );\n } else {\n // If the view id does not match active view, then ignore the update, as its probably the previous view.\n // Must ignore update if no match, otherwise item updates from old and new view will conflict and context menu items may then not display as expected. (BugFix: TimeSheet->JumpTo->AddRequest->Cancel. Visible icons not as expected. Cancel icon not disabled).\n Debug.Warn( 'Error: Context Menu Multi-select Item activation does not match menu id.\\nThis menu: '+ this.menu_id +'\\n Event menu: '+event_data.menu_id+' )', 'TTContextMenu.vue', 'TTContextMenu', 'created:EventBus:activate_multi_select_item', 11 );\n }\n }.bind(this); // Must bind to this at variable definition, not in the EventBus on/off as each .bind creates a new function reference, so it wont be able to match up on delete.\n\n this.event_bus.on( this.component_id, 'activate_multi_select_item', onActivateMultiSelectItem, TTEventBusStatics.AUTO_CLEAR_ON_EXIT );\n\n /* -------- Event Listener for SPLITBUTTON updates -------- */\n let onActivateSplitButtonItem = function( event_data ) {\n if ( this.menu_id === event_data.menu_id ) {\n Debug.Text( 'Contextmenu\\n SPLIT BUTTON update RECEIVED for: ' + event_data.menu_id + ':' + event_data.item_id, 'TTContextMenu.vue', 'TTContextMenu', 'created:EventBus:activate_split_button_item', 11 );\n this.activateSplitButtonItem( event_data.item_id );\n } else {\n // If the view id does not match active view, then ignore the update, as its probably the previous view.\n Debug.Warn( 'Error: Context Menu Split Button Item activation does not match menu id.\\nThis menu: ' + this.menu_id + '\\n Event menu: ' + event_data.menu_id + ' )', 'TTContextMenu.vue', 'TTContextMenu', 'created:EventBus:activate_split_button_item', 11 );\n }\n }.bind( this ); // Must bind to this at variable definition, not in the EventBus on/off as each .bind creates a new function reference, so it wont be able to match up on delete.\n\n this.event_bus.on( this.component_id, 'activate_split_button_item', onActivateSplitButtonItem,TTEventBusStatics.AUTO_CLEAR_ON_EXIT );\n\n let onFreezeSplitButtonActiveItem = function( event_data ) {\n if ( this.menu_id === event_data.menu_id ) {\n Debug.Text( 'Contextmenu\\n SPLIT BUTTON update RECEIVED for: ' + event_data.menu_id + ':' + event_data.item_id, 'TTContextMenu.vue', 'TTContextMenu', 'created:EventBus:activate_split_button_item', 11 );\n this.freezeSplitButtonActiveItem( event_data.item_id );\n } else {\n // If the view id does not match active view, then ignore the update, as its probably the previous view.\n Debug.Warn( 'Error: Context Menu Split Button Item activation does not match menu id.\\nThis menu: ' + this.menu_id + '\\n Event menu: ' + event_data.menu_id + ' )', 'TTContextMenu.vue', 'TTContextMenu', 'created:EventBus:activate_split_button_item', 11 );\n }\n }.bind( this ); // Must bind to this at variable definition, not in the EventBus on/off as each .bind creates a new function reference, so it wont be able to match up on delete.\n\n this.event_bus.on( this.component_id, 'freeze_split_button_active_item', onFreezeSplitButtonActiveItem, TTEventBusStatics.AUTO_CLEAR_ON_EXIT );\n },\n unmounted() {\n Debug.Text( 'Vue context menu component unmounted ('+ this.menu_id +').', 'TTContextMenu.vue', 'TTContextMenu', 'unmounted', 10 );\n this.event_bus.autoClear();\n },\n props: {\n menu_id: String\n },\n data() {\n return {\n component_id: 'context_menu',\n built_menu: [],\n removeEventsOnUnmount: [],\n nowrap_views: [ 'TimeSheet' ], // TimeSheet is to handle the New Punch label wrapping. This is here to test if this will work globally, nowrap might cause issues.\n }\n },\n computed: {\n alignItems() {\n let filter_left = ( element ) => element.menu_align === 'left';\n let filter_center = ( element ) => element.menu_align === 'center';\n let filter_right = ( element ) => element.menu_align === 'right';\n\n return {\n left: this.built_menu.filter( filter_left ),\n center: this.built_menu.filter( filter_center ),\n right: this.built_menu.filter( filter_right )\n };\n },\n dynamicClasses() {\n return {\n // 'nowrap': this.nowrap_views.includes( this.viewId ) ? 'no-wrap' : '', // If this returns true, this prevents the text label of a nav button wrapping to a new-line, affecting the button heights for the whole menu. Care needs to be taken if not all buttons will fit with no-wrap.\n nowrap: 'no-wrap', // Simplifing this while we no longer pass in viewId. If this feature is needed, then we need to get viewId another way.\n }\n }\n },\n methods: {\n rebuildMenu( menu_model ) {\n this.built_menu.length = 0; // TODO: Should not need to do this once TTContextMenu has an independant instance for each view. At the moment, all views are one Vue View (LegacyView).\n this.built_menu.push(...menu_model ); // TODO: Need to handle the eventuality where icons array needs to be cleared first without losing the JS reference to the array.\n },\n /**\n * Update several item params in one go.\n * This will also be useful for event driven updates, reduces the need to have an event function for each action.\n * @param {string} item_id - ID of the item to update\n * @param {Object} new_item_attributes - The new data as attributes in an object.\n * @returns {Object}\n */\n updateMenuItem( item_id, new_item_attributes ) {\n var item = this.getMenuItemById( item_id );\n if( item === undefined ) {\n // If this happens, it might be that the Vue menu has cleared already, and the menu is trying to set states on old icons no longer present. Might be a legacy->Vue issue on a view change. But the vue menu items should always match the legacy menu on the view controller. Trace the icons and try and fix the disconnect.\n Debug.Warn( 'Menu item not found ('+ item_id +') unable to update with: ' + JSON.stringify( new_item_attributes ), 'TTContextMenu.vue', 'TTContextMenu', 'updateMenuItem', 1 );\n return false;\n }\n return Object.assign( item, new_item_attributes);\n },\n activateMultiSelectItem( item_id ) {\n var item = this.getMenuItemById( item_id );\n if( item === undefined ) {\n // If this happens, it might be that the Vue menu has cleared already, and the menu is trying to set states on old icons no longer present. Might be a legacy->Vue issue on a view change. But the vue menu items should always match the legacy menu on the view controller. Trace the icons and try and fix the disconnect.\n Debug.Warn( 'Menu item not found ('+ item_id +') unable to update with: ' + JSON.stringify( new_item_attributes ), 'TTContextMenu.vue', 'TTContextMenu', 'updateMenuItem', 1 );\n return false;\n }\n if( item.setOnlySelfActive === undefined ) {\n item.default_active_item = true;\n return 1;\n } else {\n item.setOnlySelfActive();\n return 2;\n }\n },\n activateSplitButtonItem( item_id ) {\n for ( let i = 0; i < this.built_menu.length; i++ ) {\n //Only modify the action group that contains the item_id we want. This is to avoid affecting any other action groups active item.\n if ( this.built_menu[i].items.some(item => item.id === item_id ) ) {\n for ( let j = 0; j < this.built_menu[i].items.length; j++ ) {\n if ( this.built_menu[i].items[j].id === item_id ) {\n this.built_menu[i].items[j].menu_force_active = true;\n } else {\n this.built_menu[i].items[j].menu_force_active = false;\n }\n }\n }\n }\n },\n freezeSplitButtonActiveItem( item_id ) {\n var item = this.getMenuItemById( item_id );\n if ( item === undefined ) {\n // If this happens, it might be that the Vue menu has cleared already, and the menu is trying to set states on old icons no longer present. Might be a legacy->Vue issue on a view change. But the vue menu items should always match the legacy menu on the view controller. Trace the icons and try and fix the disconnect.\n Debug.Warn( 'Menu item not found (' + item_id + ') unable to update', 'TTContextMenu.vue', 'TTContextMenu', 'setSplitButtonTemporarilyIgnoreDisabled', 1 );\n return false;\n }\n item.freeze_active_item = true;\n },\n enableMenuItem( item_id ) {\n var item = this.getMenuItemById( item_id );\n item.disabled = false;\n },\n disableMenuItem( item_id ) {\n var item = this.getMenuItemById( item_id );\n item.disabled = true;\n },\n hideMenuItem( item_id ) {\n var item = this.getMenuItemById( item_id );\n item.visible = false;\n\n },\n showMenuItem( item_id ) {\n var item = this.getMenuItemById( item_id );\n item.visible = true;\n\n },\n getMenuItemById( item_id ) {\n // TODO: Have I already done a similar function elsewhere? It seems familiar, but with ES6 array functions instead of for loops?\n // Check the context menu class as well as the left menu class. Put in Global if found.\n\n var result;\n function recursiveFind( haystack_array, needle_id ) {\n return haystack_array.find( element => {\n if ( Array.isArray( element ) ) {\n return recursiveFind( element, needle_id );\n } else {\n if( element.id === undefined && Array.isArray( element.items ) ) {\n return recursiveFind( element.items, needle_id );\n } else if( element.id === needle_id ) {\n result = element;\n return true;\n }\n }\n } );\n }\n recursiveFind( this.built_menu, item_id );\n\n return result;\n }\n },\n components: { TTContextButton: TTContextButton/* default */.Z }\n});\n\n;// CONCATENATED MODULE: ./interface/html5/components/context_menu/TTContextMenu.vue?vue&type=script&lang=js\n \n;// CONCATENATED MODULE: ./interface/html5/components/context_menu/TTContextMenu.vue\n\n\n\n\n;\n\n\n\nconst TTContextMenu_exports_ = /*#__PURE__*/(0,exportHelper/* default */.Z)(TTContextMenuvue_type_script_lang_js, [['render',TTContextMenuvue_type_template_id_6ac4a152_scoped_true_render],['__scopeId',\"data-v-6ac4a152\"]])\n\n/* harmony default export */ const TTContextMenu = (TTContextMenu_exports_);\n;// CONCATENATED MODULE: ./interface/html5/components/context_menu/ContextMenuManager.js\n\n\n\n\n\n\n\n/*\n * -- Structure of the ContextMenuManager --\n * You can search the code for `#VueContextMenu#` which will help identify the key areas during development and refactor.\n * Dynamic: For the Dynamic creation of the menu, you can search for #VueContextMenu#Dynamic-View and #VueContextMenu#Dynamic-EditView and look at mountContextMenu\n *\n * There are 3 elements to the ContextMenuManager\n * 1) The TT applications view code, 2) the ContextMenuManager, and 3) the Vue context menu.\n * The Vue component is controlled by events, the events work as follows:\n * 1) The Vue component is setup to listen to events from the EventBus (mitt)\n * 2) The control events are fired from the ContextMenuManager.\n * 3) The view controller calls functions in the ContextMenuManager to trigger these events.\n * - ContextMenuManagers are created in BaseViewController.buildContextMenu\n * - ContextMenu Models are built in BaseViewController.buildContextMenuModels() and all other ViewControllers that override those functions.\n * - The Vue component is created currently by the LegacyView component, and only when a viewId is passed to the LegacyView, currently done by the Vue Router.\n * The Vue router in turn is triggered NOT by the hash changes, as this currently leads to some race conditions/out of sync with the TT app.\n * Instead, the Vue router is running in createMemoryHistory mode, and routing manually triggered by VueRouter.push, which is currently done from BaseViewController.loadView\n *\n * -- Creating a new Context Menu --\n * So step 1 in adding a new context menu, is make sure the Vue Router is triggered, to create a new menu.\n * The new contextMenu responds to a viewId, so this needs to be unique. (Approach might have to be re-evaluated for places with subviews.\n * Maybe in the router we pass a contextmenu id which can be the same as the viewId in most cases? Discuss with Mike.\n * Either way, having the router control that Vue contextmenu generation will control duplicates/clashes.\n * -- Points of note\n * - Make sure any new listeners in the Vue component are also destroyed once no longer used (e.g. when component is unMounted).\n *\n * Initialized from BaseViewController rather than the Vue component, so that each manager created is controlled from this point.\n * Every contextmenu Vue component will then listen to a given viewId which is triggered by BaseVC.loadview.\n * If it was the other way around, there could be more chance for a viewId manager to be overriden in the array.\n * Still, the organisation between when a Vue contextmenu is created, and a manager from the TT app side, could be improved.\n * Also, worst case scenario, a manager is created in BaseView, and no vue component to listen to it.\n * If the vue component was to control when a manager was created, then we would get problems when functions like this.context_menu.parseContextRibbonAction are called from setDefault menu functions within views. So BaseView MUST be in charge of creating the manager.\n * - An area to improve would be to have our own EventBus, not re-use the one from PrimeVue.\n */\n\nclass ContextMenu {\n\tconstructor( options ) {\n\t\t// Set validation to reject if minimum data not supplied.\n\t\tthis.id = options.id || null;\n\t\tthis.type = options.type || null;\n\t\tthis.vue_menu_instance = options.vue_menu_instance || null;\n\t\tthis.view_controller_instance = options.view_controller_instance || null;\n\t\tthis.menu_model = null;\n\t}\n}\n\n\nclass ContextMenuManager {\n\tconstructor() {\n\t\tthis._menus = {}; // Will contain ContextMenu's\n\t\tthis.event_bus = new services_TTEventBus/* default */.Z({ view_id: 'context_menu' });\n\t}\n\n\tcreateAndMountMenu( menu_id, parent_mount_container, parent_context ) {\n\t\tif( !menu_id || !parent_mount_container || !parent_context ) {\n\t\t\tDebug.Error( 'Error: Invalid parameters passed to function.', 'ContextMenuManager.js', 'ContextMenuManager', 'createAndMountMenu', 1 );\n\t\t\treturn false;\n\t\t}\n\t\tif( this.getMenu( menu_id ) !== undefined ) {\n\t\t\tDebug.Error( 'Error: Context Menu Manager ('+ menu_id +') already exists and mounted.', 'ContextMenuManager.js', 'ContextMenuManager', 'createAndMountMenu', 1 );\n\t\t\treturn false;\n\t\t}\n\t\t// TODO:\n\t\t// - Tie in a onDestroy function where the vue context and reference in the array are deleted if the menu is removed from the dom.\n\n\t\t// #VueContextMenu#Dynamic-View - Create dynamic container for the vue context menu\n\t\tparent_mount_container.prepend('
    ');\n\n\t\t// Create and mount unique context menu for this view.\n\t\tlet vue_context = this.mountContextMenu( menu_id );\n\n\t\tlet menu = new ContextMenu({\n\t\t\tid: menu_id,\n\t\t\tvue_menu_instance: vue_context,\n\t\t\tview_controller_instance: parent_context ,\n\t\t});\n\n\t\t// Add context menu to the array of active context menu's so we can track them.\n\t\tthis._menus[ menu_id ] = menu;\n\t\treturn menu.id;\n\t}\n\tgenerateMenuId( parent_type, parent_id ) {\n\t\tif( !parent_type || !parent_id ) {\n\t\t\tDebug.Error( 'Error: Invalid parameters passed to function.', 'ContextMenuManager.js', 'ContextMenuManager', 'generateMenuId', 1 );\n\t\t\treturn false;\n\t\t}\n\t\t/* -- Examples --\n\t\t* View: BranchView\n\t\t* EditView: BranchView -> Edit\n\t\t* EditView with tabs: Employee -> Edit\n\t\t* SubView: Example?\n\t\t* SubViewLists: Employee -> Edit -> Qualifications.\n\t\t* */\n\n\t\treturn `CM-${parent_id}-${parent_type}`; // Maybe need a unique menu on the end? or not?\n\t}\n\tgetMenu( id ) {\n\t\treturn this._menus[ id ];\n\t}\n\tmountContextMenu( menu_id ) {\n\t\tif( menu_id === undefined ) {\n\t\t\tDebug.Error( 'Error: Invalid parameters passed to function.', 'ContextMenuManager.js', 'ContextMenuManager', 'mountContextMenu', 1 );\n\t\t\treturn false;\n\t\t}\n\t\tif( this.getMenu( menu_id ) !== undefined ) {\n\t\t\tDebug.Error( 'Error: Context Menu Manager ('+ menu_id +') already exists and mounted.', 'ContextMenuManager.js', 'ContextMenuManager', 'mountContextMenu', 1 );\n\t\t\treturn false;\n\t\t}\n\n\t\t// Used by #VueContextMenu#Dynamic-View and #VueContextMenu#Dynamic-EditView\n\t\tlet mount_component = TTContextMenu;\n\t\tlet mount_reference = '#' + menu_id;\n\t\t// TODO: Check if component has not already been mounted or existing in the menu list.\n\n\t\tlet vue_menu_instance = (0,vue_esm_bundler/* createApp */.ri)( mount_component, { menu_id: menu_id } ); // Can pass an object in here too for proper JS only code, and allow data in without eventBus.\n\t\tvue_menu_instance.use( config_esm/* default */.Z, { ripple: true, inputStyle: 'filled' }); // From: AppConfig.vue this.$primevue.config.inputStyle value is filled/outlined as we dont use AppConfig in TT.\n\t\tvue_menu_instance.use( main_ui_router/* default */.Z ); // #VueContextMenu# FIXES: Failed to resolve component: router-link when TTOverlayMenuButton is opened. Because each context menu is a separate Vue instance, and they did not globally 'use' the Router, only in main ui.\n\t\tvue_menu_instance.mount( mount_reference ); // e.g. '#tt-edit-view-test'\n\n\t\treturn vue_menu_instance;\n\t}\n\tunmountContextMenu ( id ) {\n\t\tif( this._menus[ id ] ) {\n\t\t\tthis._menus[ id ].vue_menu_instance.unmount();\n\t\t\tdelete this._menus[ id ];\n\t\t\tDebug.Text( 'Context menu successfully unmounted ('+ id +').', 'ContextMenuManager.js', 'ContextMenuManager', 'unmountContextMenu', 11 );\n\t\t\treturn true;\n\t\t} else {\n\t\t\tDebug.Warn( 'Unable to unmount context menu. Menu not found ('+ id +'). Maybe already removed?', 'ContextMenuManager.js', 'ContextMenuManager', 'unmountContextMenu', 11 );\n\t\t\treturn false;\n\t\t}\n\t}\n\tbuildContextMenuModelFromBackbone( menu_id, final_context_menu_model, view_controller_context ) {\n\t\tif( menu_id === null ) return false;\n\n\t\tvar parsed_bb_menu = this.convertBackBoneMenuModelToPrimeVue( final_context_menu_model, view_controller_context );\n\t\tthis.updateMenuModel( menu_id, parsed_bb_menu );\n\n\t\tif ( this.getMenu( menu_id ) ) {\n\t\t\t//Fixes context menu flashing. For example when a user has lower permission levels context icons will appear and then dissapear half a second later.\n\t\t\t//NOTE: These branching paths may be removed in the future when setDefaultMenu() and setEditMenu() are consolidated and some changes may be needed to reduce duplicate calls to the set*Menu() functions.\n\t\t\tif ( !this.getMenu( menu_id ).view_controller_instance.is_edit && !this.getMenu( menu_id ).view_controller_instance.is_add && !this.getMenu( menu_id ).view_controller_instance.is_viewing ) {\n\t\t\t\tthis.getMenu( menu_id ).view_controller_instance.setDefaultMenu();\n\t\t\t} else {\n\t\t\t\t//Fixes issue where refreshing an edit view would flash context menus.\n\t\t\t\tthis.getMenu( menu_id ).view_controller_instance.setEditMenu();\n\t\t\t}\n\t\t} else {\n\t\t\tDebug.Error( 'Error: Cannot find Vue context menu.', 'ContextMenuManager.js', 'ContextMenuManager', 'getMenuModelByMenuId', 1 );\n\t\t}\n\t}\n\tconvertBackBoneMenuModelToPrimeVue( backbone_menu_format, view_controller_context ) {\n\t\t/*\n\t\t* This would have arrays for groups & icons\n\t\t* icons is very similar to the PrimeVue MenuModel.\n\t\t*\n\t\t* Note: This function only builds the menu when its asked to do so, like on view controller init.\n\t\t* However, if the menu icons are manipulated via permission controls or user selecting items in a data table, this function does not run.\n\t\t* Thats mostly fine, as the menu structure itself does not really change based on user interaction,\n\t\t* But some things might. E.g. (Paystubs ->Edit Employee) when the Save menu initially has all the options during this build run, but later ends up with only one Save option. That needs to be handled dynamically in Vue.\n\t\t* */\n\n\t\tvar icons = backbone_menu_format.icons;\n\t\tvar action_groups = {};\n\t\tvar parsed_icons = [];\n\n\t\t// TODO: Is the below still needed? And can we do this in a neater/clearer way.\n\t\tif ( icons && Object.keys( icons ).length && Object.keys( icons ).length < 1) {\n\t\t\t// Invalid data.\n\t\t\tconsole.error('ContextMenuManager: Invalid data format. No icons or not an array.');\n\t\t\treturn false;\n\t\t}\n\n\t\t// Sort icons by their sort_order attribute.\n\t\ticons = Object.values(backbone_menu_format.icons).sort(this.sortCompareIcons);\n\n\t\t// parse the icons item.icons further\n\t\tfor ( var key in icons ) {\n\t\t\t// Dev warning: iteration order is not guaranteed during for...in loops. And only modify the currently iterated key. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#deleted_added_or_modified_properties\n\t\t\tif(icons.hasOwnProperty( key )) {\n\t\t\t\tvar item = icons[key];\n\n\t\t\t\t// Validation checks and default values.\n\t\t\t\t// When modifying these, make sure to update sub_menu_item checks later on too.\n\t\t\t\tif( !item.id ) {\n\t\t\t\t\tDebug.Error( 'ERROR: Invalid data. Missing ID.', 'ContextMenuManager.js', 'ContextMenuManager', 'convertBackBoneMenuModelToPrimeVue', 1 );\n\t\t\t\t}\n\t\t\t\tif( item.icon ) delete item.icon; // Remove the .icon attribute, because it interferes with PrimeVue