@sapui5/sap.fe.core 1.124.2 → 1.126.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/sap/fe/core/.library +5 -1
- package/src/sap/fe/core/ActionRuntime.js +2 -2
- package/src/sap/fe/core/ActionRuntime.ts +4 -4
- package/src/sap/fe/core/AppComponent.js +2 -2
- package/src/sap/fe/core/AppComponent.ts +1 -1
- package/src/sap/fe/core/AppStateHandler.js +2 -2
- package/src/sap/fe/core/AppStateHandler.ts +1 -1
- package/src/sap/fe/core/BaseController.js +2 -2
- package/src/sap/fe/core/BaseController.ts +1 -1
- package/src/sap/fe/core/CommonUtils.js +3 -3
- package/src/sap/fe/core/CommonUtils.ts +12 -15
- package/src/sap/fe/core/ExtensionAPI.js +2 -2
- package/src/sap/fe/core/ExtensionAPI.ts +4 -3
- package/src/sap/fe/core/PageController.js +2 -2
- package/src/sap/fe/core/PageController.ts +1 -1
- package/src/sap/fe/core/ResourceModel.js +2 -2
- package/src/sap/fe/core/ResourceModel.ts +1 -1
- package/src/sap/fe/core/ReuseComponent.js +172 -0
- package/src/sap/fe/core/ReuseComponent.ts +165 -0
- package/src/sap/fe/core/TemplateComponent.js +2 -2
- package/src/sap/fe/core/TemplateComponent.ts +5 -1
- package/src/sap/fe/core/TemplateModel.js +2 -2
- package/src/sap/fe/core/TemplateModel.ts +1 -1
- package/src/sap/fe/core/buildingBlocks/BuildingBlockBase.js +92 -6
- package/src/sap/fe/core/buildingBlocks/BuildingBlockBase.ts +90 -10
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.js +1 -1
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.ts +1 -1
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.js +30 -3
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.ts +28 -4
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.js +10 -16
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.ts +19 -16
- package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlockFragment.js +3 -3
- package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlockFragment.ts +5 -5
- package/src/sap/fe/core/controllerextensions/BaseControllerExtension.js +2 -2
- package/src/sap/fe/core/controllerextensions/BaseControllerExtension.ts +1 -1
- package/src/sap/fe/core/controllerextensions/CollaborativeDraft.js +17 -5
- package/src/sap/fe/core/controllerextensions/CollaborativeDraft.ts +14 -6
- package/src/sap/fe/core/controllerextensions/ContextSharing.js +2 -2
- package/src/sap/fe/core/controllerextensions/ContextSharing.ts +1 -1
- package/src/sap/fe/core/controllerextensions/EditFlow.js +57 -43
- package/src/sap/fe/core/controllerextensions/EditFlow.ts +61 -46
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +2 -2
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +1 -1
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +8 -11
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +8 -16
- package/src/sap/fe/core/controllerextensions/InternalRouting.js +10 -7
- package/src/sap/fe/core/controllerextensions/InternalRouting.ts +5 -5
- package/src/sap/fe/core/controllerextensions/KPIManagement.js +22 -18
- package/src/sap/fe/core/controllerextensions/KPIManagement.ts +28 -23
- package/src/sap/fe/core/controllerextensions/MessageHandler.js +4 -4
- package/src/sap/fe/core/controllerextensions/MessageHandler.ts +4 -1
- package/src/sap/fe/core/controllerextensions/PageReady.js +21 -15
- package/src/sap/fe/core/controllerextensions/PageReady.ts +29 -20
- package/src/sap/fe/core/controllerextensions/Paginator.js +2 -2
- package/src/sap/fe/core/controllerextensions/Paginator.ts +1 -1
- package/src/sap/fe/core/controllerextensions/Placeholder.js +12 -6
- package/src/sap/fe/core/controllerextensions/Placeholder.ts +15 -1
- package/src/sap/fe/core/controllerextensions/Recommendations.js +26 -8
- package/src/sap/fe/core/controllerextensions/Recommendations.ts +29 -3
- package/src/sap/fe/core/controllerextensions/Routing.js +5 -7
- package/src/sap/fe/core/controllerextensions/Routing.ts +4 -4
- package/src/sap/fe/core/controllerextensions/Share.js +4 -4
- package/src/sap/fe/core/controllerextensions/Share.ts +10 -6
- package/src/sap/fe/core/controllerextensions/SideEffects.js +20 -5
- package/src/sap/fe/core/controllerextensions/SideEffects.ts +22 -2
- package/src/sap/fe/core/controllerextensions/Telemetry.js +2 -2
- package/src/sap/fe/core/controllerextensions/Telemetry.ts +1 -1
- package/src/sap/fe/core/controllerextensions/ViewState.js +79 -81
- package/src/sap/fe/core/controllerextensions/ViewState.ts +117 -105
- package/src/sap/fe/core/controllerextensions/cards/CollaborationManager.js +3 -3
- package/src/sap/fe/core/controllerextensions/cards/CollaborationManager.ts +1 -1
- package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.js +2 -2
- package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.ts +2 -2
- package/src/sap/fe/core/controllerextensions/dialog/OperationsDialog.block.js +17 -8
- package/src/sap/fe/core/controllerextensions/dialog/OperationsDialog.block.tsx +8 -2
- package/src/sap/fe/core/controllerextensions/editFlow/NotApplicableContextDialog.js +1 -1
- package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +10 -9
- package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.ts +15 -10
- package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.js +2 -2
- package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.ts +1 -1
- package/src/sap/fe/core/controllerextensions/editFlow/operations/facade.js +130 -158
- package/src/sap/fe/core/controllerextensions/editFlow/operations/facade.ts +240 -275
- package/src/sap/fe/core/controllerextensions/editFlow/sticky.js +2 -2
- package/src/sap/fe/core/controllerextensions/editFlow/sticky.ts +1 -1
- package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +46 -28
- package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.ts +60 -32
- package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +2 -2
- package/src/sap/fe/core/controllerextensions/routing/RouterProxy.ts +1 -1
- package/src/sap/fe/core/controllerextensions/viewState/IViewStateContributor.js +2 -2
- package/src/sap/fe/core/controllerextensions/viewState/IViewStateContributor.ts +27 -3
- package/src/sap/fe/core/controls/CommandExecution.js +2 -2
- package/src/sap/fe/core/controls/CommandExecution.ts +2 -2
- package/src/sap/fe/core/controls/ComponentLoader.js +3 -3
- package/src/sap/fe/core/controls/ComponentLoader.ts +2 -2
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.block.js +3 -3
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.block.tsx +2 -2
- package/src/sap/fe/core/controls/EventDelegateHook.js +2 -2
- package/src/sap/fe/core/controls/EventDelegateHook.ts +2 -2
- package/src/sap/fe/core/controls/FormElementWrapper.js +51 -6
- package/src/sap/fe/core/controls/FormElementWrapper.ts +43 -2
- package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.block.js +3 -3
- package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.block.tsx +3 -3
- package/src/sap/fe/core/converters/ConverterContext.js +4 -2
- package/src/sap/fe/core/converters/ConverterContext.ts +5 -2
- package/src/sap/fe/core/converters/ManifestSettings.js +8 -2
- package/src/sap/fe/core/converters/ManifestSettings.ts +25 -3
- package/src/sap/fe/core/converters/ManifestWrapper.js +12 -3
- package/src/sap/fe/core/converters/ManifestWrapper.ts +11 -1
- package/src/sap/fe/core/converters/MetaModelConverter.js +7 -6
- package/src/sap/fe/core/converters/MetaModelConverter.ts +6 -2
- package/src/sap/fe/core/converters/annotations/DataField.js +56 -16
- package/src/sap/fe/core/converters/annotations/DataField.ts +74 -25
- package/src/sap/fe/core/converters/common/AnnotationConverter.js +19 -18
- package/src/sap/fe/core/converters/controls/Common/Action.js +5 -5
- package/src/sap/fe/core/converters/controls/Common/Action.ts +14 -14
- package/src/sap/fe/core/converters/controls/Common/Chart.js +40 -7
- package/src/sap/fe/core/converters/controls/Common/Chart.ts +56 -20
- package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +8 -11
- package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +23 -27
- package/src/sap/fe/core/converters/controls/Common/Form.js +10 -3
- package/src/sap/fe/core/converters/controls/Common/Form.ts +13 -4
- package/src/sap/fe/core/converters/controls/Common/KPI.js +3 -2
- package/src/sap/fe/core/converters/controls/Common/KPI.ts +6 -2
- package/src/sap/fe/core/converters/controls/Common/Table.js +137 -48
- package/src/sap/fe/core/converters/controls/Common/Table.ts +174 -52
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +73 -21
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +91 -20
- package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +4 -4
- package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +2 -2
- package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.js +2 -2
- package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.ts +2 -2
- package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +3 -3
- package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +1 -1
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +17 -16
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +18 -17
- package/src/sap/fe/core/converters/helpers/InsightsHelpers.js +2 -2
- package/src/sap/fe/core/converters/helpers/InsightsHelpers.ts +1 -1
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +9 -9
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +12 -12
- package/src/sap/fe/core/converters/templates/ListReportConverter.js +13 -7
- package/src/sap/fe/core/converters/templates/ListReportConverter.ts +12 -5
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +9 -73
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +4 -74
- package/src/sap/fe/core/designtime/AppComponent.designtime.js +5 -10
- package/src/sap/fe/core/designtime/AppComponent.designtime.ts +3 -12
- package/src/sap/fe/core/formatters/CriticalityFormatter.js +4 -7
- package/src/sap/fe/core/formatters/CriticalityFormatter.ts +3 -3
- package/src/sap/fe/core/formatters/FiscalFormat.js +5 -3
- package/src/sap/fe/core/formatters/FiscalFormat.ts +4 -2
- package/src/sap/fe/core/formatters/StandardFormatter.js +2 -2
- package/src/sap/fe/core/formatters/StandardFormatter.ts +3 -3
- package/src/sap/fe/core/fpm/Component.js +3 -3
- package/src/sap/fe/core/fpm/Component.ts +3 -3
- package/src/sap/fe/core/fpm/manifest.json +1 -1
- package/src/sap/fe/core/helpers/AdaptiveCardExpressionCompiler.js +2 -2
- package/src/sap/fe/core/helpers/AdaptiveCardExpressionCompiler.ts +1 -1
- package/src/sap/fe/core/helpers/BindingHelper.js +2 -2
- package/src/sap/fe/core/helpers/BindingHelper.ts +2 -2
- package/src/sap/fe/core/helpers/BindingToolkitEvaluator.js +2 -2
- package/src/sap/fe/core/helpers/BindingToolkitEvaluator.ts +2 -2
- package/src/sap/fe/core/helpers/DeleteHelper.js +7 -4
- package/src/sap/fe/core/helpers/DeleteHelper.ts +9 -3
- package/src/sap/fe/core/helpers/MetaModelFunction.js +5 -5
- package/src/sap/fe/core/helpers/MetaModelFunction.ts +2 -2
- package/src/sap/fe/core/helpers/MetaPath.js +9 -3
- package/src/sap/fe/core/helpers/MetaPath.ts +8 -2
- package/src/sap/fe/core/helpers/ModelHelper.js +149 -3
- package/src/sap/fe/core/helpers/ModelHelper.ts +202 -6
- package/src/sap/fe/core/helpers/StandardRecommendationHelper.js +3 -3
- package/src/sap/fe/core/helpers/StandardRecommendationHelper.ts +2 -2
- package/src/sap/fe/core/helpers/TitleHelper.js +4 -4
- package/src/sap/fe/core/helpers/TitleHelper.ts +4 -4
- package/src/sap/fe/core/library.js +4 -4
- package/src/sap/fe/core/library.ts +2 -1
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +11 -3
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +10 -2
- package/src/sap/fe/core/messagebundle.properties +8 -57
- package/src/sap/fe/core/messagebundle_ar.properties +2 -0
- package/src/sap/fe/core/messagebundle_bg.properties +2 -0
- package/src/sap/fe/core/messagebundle_ca.properties +2 -0
- package/src/sap/fe/core/messagebundle_cnr.properties +2 -0
- package/src/sap/fe/core/messagebundle_cs.properties +2 -0
- package/src/sap/fe/core/messagebundle_cy.properties +4 -2
- package/src/sap/fe/core/messagebundle_da.properties +2 -0
- package/src/sap/fe/core/messagebundle_de.properties +2 -0
- package/src/sap/fe/core/messagebundle_el.properties +2 -0
- package/src/sap/fe/core/messagebundle_en.properties +6 -57
- package/src/sap/fe/core/messagebundle_en_GB.properties +2 -0
- package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +3 -36
- package/src/sap/fe/core/messagebundle_es.properties +2 -0
- package/src/sap/fe/core/messagebundle_es_MX.properties +2 -0
- package/src/sap/fe/core/messagebundle_et.properties +2 -0
- package/src/sap/fe/core/messagebundle_fi.properties +2 -0
- package/src/sap/fe/core/messagebundle_fr.properties +2 -0
- package/src/sap/fe/core/messagebundle_fr_CA.properties +3 -1
- package/src/sap/fe/core/messagebundle_hi.properties +2 -0
- package/src/sap/fe/core/messagebundle_hr.properties +2 -0
- package/src/sap/fe/core/messagebundle_hu.properties +3 -1
- package/src/sap/fe/core/messagebundle_id.properties +2 -0
- package/src/sap/fe/core/messagebundle_it.properties +2 -0
- package/src/sap/fe/core/messagebundle_iw.properties +3 -1
- package/src/sap/fe/core/messagebundle_ja.properties +2 -0
- package/src/sap/fe/core/messagebundle_kk.properties +2 -0
- package/src/sap/fe/core/messagebundle_ko.properties +2 -0
- package/src/sap/fe/core/messagebundle_lt.properties +2 -0
- package/src/sap/fe/core/messagebundle_lv.properties +2 -0
- package/src/sap/fe/core/messagebundle_mk.properties +2 -0
- package/src/sap/fe/core/messagebundle_ms.properties +2 -0
- package/src/sap/fe/core/messagebundle_nl.properties +2 -0
- package/src/sap/fe/core/messagebundle_no.properties +2 -0
- package/src/sap/fe/core/messagebundle_pl.properties +2 -0
- package/src/sap/fe/core/messagebundle_pt.properties +2 -0
- package/src/sap/fe/core/messagebundle_pt_PT.properties +2 -0
- package/src/sap/fe/core/messagebundle_ro.properties +2 -0
- package/src/sap/fe/core/messagebundle_ru.properties +2 -0
- package/src/sap/fe/core/messagebundle_sh.properties +64 -62
- package/src/sap/fe/core/messagebundle_sk.properties +2 -0
- package/src/sap/fe/core/messagebundle_sl.properties +2 -0
- package/src/sap/fe/core/messagebundle_sr.properties +2 -0
- package/src/sap/fe/core/messagebundle_sv.properties +2 -0
- package/src/sap/fe/core/messagebundle_th.properties +2 -0
- package/src/sap/fe/core/messagebundle_tr.properties +2 -0
- package/src/sap/fe/core/messagebundle_uk.properties +3 -1
- package/src/sap/fe/core/messagebundle_vi.properties +2 -0
- package/src/sap/fe/core/messagebundle_zh_CN.properties +2 -0
- package/src/sap/fe/core/messagebundle_zh_TW.properties +2 -0
- package/src/sap/fe/core/operationsHelper.js +3 -3
- package/src/sap/fe/core/operationsHelper.ts +2 -2
- package/src/sap/fe/core/rootView/Fcl.controller.js +3 -3
- package/src/sap/fe/core/rootView/Fcl.controller.ts +2 -2
- package/src/sap/fe/core/rootView/NavContainer.controller.js +2 -2
- package/src/sap/fe/core/rootView/NavContainer.controller.ts +1 -1
- package/src/sap/fe/core/rootView/RootViewBaseController.js +114 -92
- package/src/sap/fe/core/rootView/RootViewBaseController.ts +120 -106
- package/src/sap/fe/core/services/CollaborativeToolsServiceFactory.js +2 -2
- package/src/sap/fe/core/services/CollaborativeToolsServiceFactory.ts +1 -1
- package/src/sap/fe/core/services/NavigationServiceFactory.js +6 -4
- package/src/sap/fe/core/services/NavigationServiceFactory.ts +4 -3
- package/src/sap/fe/core/services/RoutingServiceFactory.js +2 -2
- package/src/sap/fe/core/services/RoutingServiceFactory.ts +1 -1
- package/src/sap/fe/core/services/ShellServicesFactory.js +1 -1
- package/src/sap/fe/core/services/ShellServicesFactory.ts +12 -2
- package/src/sap/fe/core/services/TelemetryServiceFactory.js +8 -2
- package/src/sap/fe/core/services/TelemetryServiceFactory.ts +7 -1
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +16 -9
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +22 -11
- package/src/sap/fe/core/services/ValueHelpHistoryServiceFactory.js +2 -2
- package/src/sap/fe/core/services/ValueHelpHistoryServiceFactory.ts +1 -1
- package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +2 -2
- package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +1 -1
- package/src/sap/fe/core/templating/ActionHelper.js +2 -2
- package/src/sap/fe/core/templating/ActionHelper.ts +2 -2
- package/src/sap/fe/core/templating/CommonFormatters.js +2 -2
- package/src/sap/fe/core/templating/CommonFormatters.ts +3 -3
- package/src/sap/fe/core/templating/CriticalityFormatters.js +2 -2
- package/src/sap/fe/core/templating/CriticalityFormatters.ts +2 -2
- package/src/sap/fe/core/templating/DataFieldFormatters.js +4 -4
- package/src/sap/fe/core/templating/DataFieldFormatters.ts +2 -2
- package/src/sap/fe/core/templating/DataModelPathHelper.js +2 -2
- package/src/sap/fe/core/templating/DataModelPathHelper.ts +2 -2
- package/src/sap/fe/core/templating/EntityTypeHelper.js +2 -2
- package/src/sap/fe/core/templating/EntityTypeHelper.ts +2 -2
- package/src/sap/fe/core/templating/FieldControlHelper.js +2 -2
- package/src/sap/fe/core/templating/FieldControlHelper.ts +2 -2
- package/src/sap/fe/core/templating/SemanticObjectHelper.js +2 -2
- package/src/sap/fe/core/templating/SemanticObjectHelper.ts +2 -2
- package/src/sap/fe/core/templating/UIFormatters.js +7 -7
- package/src/sap/fe/core/templating/UIFormatters.ts +6 -6
- package/src/sap/fe/core/type/DateTimeWithTimezone.js +2 -2
- package/src/sap/fe/core/type/DateTimeWithTimezone.ts +1 -1
- package/src/sap/fe/core/type/Email.js +2 -2
- package/src/sap/fe/core/type/Email.ts +1 -1
- package/src/sap/fe/core/type/FiscalDate.js +2 -2
- package/src/sap/fe/core/type/FiscalDate.ts +1 -1
- package/src/sap/fe/core/type/InputMask.js +124 -0
- package/src/sap/fe/core/type/InputMask.ts +131 -0
- package/ui5.yaml +19 -0
- package/src/sap/fe/core/controllerextensions/editFlow/operations/_internal.js +0 -81
- package/src/sap/fe/core/controllerextensions/editFlow/operations/_internal.ts +0 -117
- package/src/sap/fe/core/helpers/AnnotationEnum.js +0 -33
- package/src/sap/fe/core/helpers/AnnotationEnum.ts +0 -21
- package/src/sap/fe/core/helpers/BindingToolkit.js +0 -1813
- package/src/sap/fe/core/helpers/BindingToolkit.ts +0 -2450
- package/src/sap/fe/core/helpers/ClassSupport.js +0 -584
- package/src/sap/fe/core/helpers/ClassSupport.ts +0 -697
- package/src/sap/fe/core/jsx-runtime/Fragment.js +0 -14
- package/src/sap/fe/core/jsx-runtime/Fragment.ts +0 -3
- package/src/sap/fe/core/jsx-runtime/ViewLoader.js +0 -93
- package/src/sap/fe/core/jsx-runtime/ViewLoader.tsx +0 -86
- package/src/sap/fe/core/jsx-runtime/jsx-control.js +0 -177
- package/src/sap/fe/core/jsx-runtime/jsx-control.ts +0 -197
- package/src/sap/fe/core/jsx-runtime/jsx-xml.js +0 -237
- package/src/sap/fe/core/jsx-runtime/jsx-xml.ts +0 -246
- package/src/sap/fe/core/jsx-runtime/jsx.js +0 -47
- package/src/sap/fe/core/jsx-runtime/jsx.ts +0 -71
- package/src/sap/fe/core/jsx-runtime/jsxs.js +0 -10
- package/src/sap/fe/core/jsx-runtime/jsxs.ts +0 -3
- package/src/sap/fe/core/jsx-runtime/useMDXComponents.js +0 -172
- package/src/sap/fe/core/jsx-runtime/useMDXComponents.tsx +0 -194
|
@@ -1,1813 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* SAP UI development toolkit for HTML5 (SAPUI5)
|
|
3
|
-
* (c) Copyright 2009-2024 SAP SE. All rights reserved
|
|
4
|
-
*/
|
|
5
|
-
sap.ui.define(["sap/fe/core/helpers/TypeGuards", "./AnnotationEnum"], function (TypeGuards, AnnotationEnum) {
|
|
6
|
-
"use strict";
|
|
7
|
-
|
|
8
|
-
var _exports = {};
|
|
9
|
-
var resolveEnumValue = AnnotationEnum.resolveEnumValue;
|
|
10
|
-
var isProperty = TypeGuards.isProperty;
|
|
11
|
-
const EDM_TYPE_MAPPING = {
|
|
12
|
-
"Edm.Boolean": {
|
|
13
|
-
type: "sap.ui.model.odata.type.Boolean"
|
|
14
|
-
},
|
|
15
|
-
"Edm.Byte": {
|
|
16
|
-
type: "sap.ui.model.odata.type.Byte"
|
|
17
|
-
},
|
|
18
|
-
"Edm.Date": {
|
|
19
|
-
type: "sap.ui.model.odata.type.Date"
|
|
20
|
-
},
|
|
21
|
-
"Edm.DateTimeOffset": {
|
|
22
|
-
constraints: {
|
|
23
|
-
$Precision: "precision",
|
|
24
|
-
$V4: "V4"
|
|
25
|
-
},
|
|
26
|
-
type: "sap.ui.model.odata.type.DateTimeOffset"
|
|
27
|
-
},
|
|
28
|
-
"Edm.Decimal": {
|
|
29
|
-
constraints: {
|
|
30
|
-
"@Org.OData.Validation.V1.Minimum/$Decimal": "minimum",
|
|
31
|
-
"@Org.OData.Validation.V1.Minimum@Org.OData.Validation.V1.Exclusive": "minimumExclusive",
|
|
32
|
-
"@Org.OData.Validation.V1.Maximum/$Decimal": "maximum",
|
|
33
|
-
"@Org.OData.Validation.V1.Maximum@Org.OData.Validation.V1.Exclusive": "maximumExclusive",
|
|
34
|
-
$Precision: "precision",
|
|
35
|
-
$Scale: "scale"
|
|
36
|
-
},
|
|
37
|
-
type: "sap.ui.model.odata.type.Decimal"
|
|
38
|
-
},
|
|
39
|
-
"Edm.Double": {
|
|
40
|
-
type: "sap.ui.model.odata.type.Double"
|
|
41
|
-
},
|
|
42
|
-
"Edm.Guid": {
|
|
43
|
-
type: "sap.ui.model.odata.type.Guid"
|
|
44
|
-
},
|
|
45
|
-
"Edm.Int16": {
|
|
46
|
-
type: "sap.ui.model.odata.type.Int16"
|
|
47
|
-
},
|
|
48
|
-
"Edm.Int32": {
|
|
49
|
-
type: "sap.ui.model.odata.type.Int32"
|
|
50
|
-
},
|
|
51
|
-
"Edm.Int64": {
|
|
52
|
-
type: "sap.ui.model.odata.type.Int64"
|
|
53
|
-
},
|
|
54
|
-
"Edm.SByte": {
|
|
55
|
-
type: "sap.ui.model.odata.type.SByte"
|
|
56
|
-
},
|
|
57
|
-
"Edm.Single": {
|
|
58
|
-
type: "sap.ui.model.odata.type.Single"
|
|
59
|
-
},
|
|
60
|
-
"Edm.Stream": {
|
|
61
|
-
type: "sap.ui.model.odata.type.Stream"
|
|
62
|
-
},
|
|
63
|
-
"Edm.Binary": {
|
|
64
|
-
type: "sap.ui.model.odata.type.Stream"
|
|
65
|
-
},
|
|
66
|
-
"Edm.String": {
|
|
67
|
-
constraints: {
|
|
68
|
-
"@com.sap.vocabularies.Common.v1.IsDigitSequence": "isDigitSequence",
|
|
69
|
-
$MaxLength: "maxLength",
|
|
70
|
-
$Nullable: "nullable"
|
|
71
|
-
},
|
|
72
|
-
type: "sap.ui.model.odata.type.String"
|
|
73
|
-
},
|
|
74
|
-
"Edm.TimeOfDay": {
|
|
75
|
-
constraints: {
|
|
76
|
-
$Precision: "precision"
|
|
77
|
-
},
|
|
78
|
-
type: "sap.ui.model.odata.type.TimeOfDay"
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* An expression that evaluates to type T, or a constant value of type T
|
|
84
|
-
*/
|
|
85
|
-
_exports.EDM_TYPE_MAPPING = EDM_TYPE_MAPPING;
|
|
86
|
-
const unresolvableExpression = {
|
|
87
|
-
_type: "Unresolvable"
|
|
88
|
-
};
|
|
89
|
-
_exports.unresolvableExpression = unresolvableExpression;
|
|
90
|
-
function escapeXmlAttribute(inputString) {
|
|
91
|
-
return inputString.replace(/'/g, "\\'");
|
|
92
|
-
}
|
|
93
|
-
_exports.escapeXmlAttribute = escapeXmlAttribute;
|
|
94
|
-
function hasUnresolvableExpression() {
|
|
95
|
-
for (var _len = arguments.length, expressions = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
96
|
-
expressions[_key] = arguments[_key];
|
|
97
|
-
}
|
|
98
|
-
return expressions.find(expr => expr._type === "Unresolvable") !== undefined;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Check two expressions for (deep) equality.
|
|
102
|
-
*
|
|
103
|
-
* @param a
|
|
104
|
-
* @param b
|
|
105
|
-
* @returns `true` if the two expressions are equal
|
|
106
|
-
*/
|
|
107
|
-
_exports.hasUnresolvableExpression = hasUnresolvableExpression;
|
|
108
|
-
function _checkExpressionsAreEqual(a, b) {
|
|
109
|
-
if (a._type !== b._type) {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
switch (a._type) {
|
|
113
|
-
case "Unresolvable":
|
|
114
|
-
return false;
|
|
115
|
-
// Unresolvable is never equal to anything even itself
|
|
116
|
-
case "Constant":
|
|
117
|
-
case "EmbeddedBinding":
|
|
118
|
-
case "EmbeddedExpressionBinding":
|
|
119
|
-
return a.value === b.value;
|
|
120
|
-
case "Not":
|
|
121
|
-
return _checkExpressionsAreEqual(a.operand, b.operand);
|
|
122
|
-
case "Truthy":
|
|
123
|
-
return _checkExpressionsAreEqual(a.operand, b.operand);
|
|
124
|
-
case "Set":
|
|
125
|
-
return a.operator === b.operator && a.operands.length === b.operands.length && a.operands.every(expression => b.operands.some(otherExpression => _checkExpressionsAreEqual(expression, otherExpression)));
|
|
126
|
-
case "IfElse":
|
|
127
|
-
return _checkExpressionsAreEqual(a.condition, b.condition) && _checkExpressionsAreEqual(a.onTrue, b.onTrue) && _checkExpressionsAreEqual(a.onFalse, b.onFalse);
|
|
128
|
-
case "Comparison":
|
|
129
|
-
return a.operator === b.operator && _checkExpressionsAreEqual(a.operand1, b.operand1) && _checkExpressionsAreEqual(a.operand2, b.operand2);
|
|
130
|
-
case "Concat":
|
|
131
|
-
const aExpressions = a.expressions;
|
|
132
|
-
const bExpressions = b.expressions;
|
|
133
|
-
if (aExpressions.length !== bExpressions.length) {
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
return aExpressions.every((expression, index) => {
|
|
137
|
-
return _checkExpressionsAreEqual(expression, bExpressions[index]);
|
|
138
|
-
});
|
|
139
|
-
case "Length":
|
|
140
|
-
return _checkExpressionsAreEqual(a.pathInModel, b.pathInModel);
|
|
141
|
-
case "PathInModel":
|
|
142
|
-
return a.modelName === b.modelName && a.path === b.path && a.targetEntitySet === b.targetEntitySet;
|
|
143
|
-
case "Formatter":
|
|
144
|
-
return a.fn === b.fn && a.parameters.length === b.parameters.length && a.parameters.every((value, index) => _checkExpressionsAreEqual(b.parameters[index], value));
|
|
145
|
-
case "ComplexType":
|
|
146
|
-
return a.type === b.type && a.bindingParameters.length === b.bindingParameters.length && a.bindingParameters.every((value, index) => _checkExpressionsAreEqual(b.bindingParameters[index], value));
|
|
147
|
-
case "Function":
|
|
148
|
-
const otherFunction = b;
|
|
149
|
-
if (a.obj === undefined || otherFunction.obj === undefined) {
|
|
150
|
-
return a.obj === otherFunction;
|
|
151
|
-
}
|
|
152
|
-
return a.fn === otherFunction.fn && _checkExpressionsAreEqual(a.obj, otherFunction.obj) && a.parameters.length === otherFunction.parameters.length && a.parameters.every((value, index) => _checkExpressionsAreEqual(otherFunction.parameters[index], value));
|
|
153
|
-
case "Ref":
|
|
154
|
-
return a.ref === b.ref;
|
|
155
|
-
}
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Converts a nested SetExpression by inlining operands of type SetExpression with the same operator.
|
|
161
|
-
*
|
|
162
|
-
* @param expression The expression to flatten
|
|
163
|
-
* @returns A new SetExpression with the same operator
|
|
164
|
-
*/
|
|
165
|
-
_exports._checkExpressionsAreEqual = _checkExpressionsAreEqual;
|
|
166
|
-
function flattenSetExpression(expression) {
|
|
167
|
-
return expression.operands.reduce((result, operand) => {
|
|
168
|
-
const candidatesForFlattening = operand._type === "Set" && operand.operator === expression.operator ? operand.operands : [operand];
|
|
169
|
-
candidatesForFlattening.forEach(candidate => {
|
|
170
|
-
if (result.operands.every(e => !_checkExpressionsAreEqual(e, candidate))) {
|
|
171
|
-
result.operands.push(candidate);
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
return result;
|
|
175
|
-
}, {
|
|
176
|
-
_type: "Set",
|
|
177
|
-
operator: expression.operator,
|
|
178
|
-
operands: []
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Detects whether an array of boolean expressions contains an expression and its negation.
|
|
184
|
-
*
|
|
185
|
-
* @param expressions Array of expressions
|
|
186
|
-
* @returns `true` if the set of expressions contains an expression and its negation
|
|
187
|
-
*/
|
|
188
|
-
function hasOppositeExpressions(expressions) {
|
|
189
|
-
const negatedExpressions = expressions.map(not);
|
|
190
|
-
return expressions.some((expression, index) => {
|
|
191
|
-
for (let i = index + 1; i < negatedExpressions.length; i++) {
|
|
192
|
-
if (_checkExpressionsAreEqual(expression, negatedExpressions[i])) {
|
|
193
|
-
return true;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return false;
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Logical `and` expression.
|
|
202
|
-
*
|
|
203
|
-
* The expression is simplified to false if this can be decided statically (that is, if one operand is a constant
|
|
204
|
-
* false or if the expression contains an operand and its negation).
|
|
205
|
-
*
|
|
206
|
-
* @param operands Expressions to connect by `and`
|
|
207
|
-
* @returns Expression evaluating to boolean
|
|
208
|
-
*/
|
|
209
|
-
function and() {
|
|
210
|
-
for (var _len2 = arguments.length, operands = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
211
|
-
operands[_key2] = arguments[_key2];
|
|
212
|
-
}
|
|
213
|
-
const expressions = flattenSetExpression({
|
|
214
|
-
_type: "Set",
|
|
215
|
-
operator: "&&",
|
|
216
|
-
operands: operands.map(wrapPrimitive)
|
|
217
|
-
}).operands;
|
|
218
|
-
if (hasUnresolvableExpression(...expressions)) {
|
|
219
|
-
return unresolvableExpression;
|
|
220
|
-
}
|
|
221
|
-
let isStaticFalse = false;
|
|
222
|
-
const nonTrivialExpression = expressions.filter(expression => {
|
|
223
|
-
if (isFalse(expression)) {
|
|
224
|
-
isStaticFalse = true;
|
|
225
|
-
}
|
|
226
|
-
return !isConstant(expression);
|
|
227
|
-
});
|
|
228
|
-
if (isStaticFalse) {
|
|
229
|
-
return constant(false);
|
|
230
|
-
} else if (nonTrivialExpression.length === 0) {
|
|
231
|
-
// Resolve the constant then
|
|
232
|
-
const isValid = expressions.reduce((result, expression) => result && isTrue(expression), true);
|
|
233
|
-
return constant(isValid);
|
|
234
|
-
} else if (nonTrivialExpression.length === 1) {
|
|
235
|
-
return nonTrivialExpression[0];
|
|
236
|
-
} else if (hasOppositeExpressions(nonTrivialExpression)) {
|
|
237
|
-
return constant(false);
|
|
238
|
-
} else {
|
|
239
|
-
return {
|
|
240
|
-
_type: "Set",
|
|
241
|
-
operator: "&&",
|
|
242
|
-
operands: nonTrivialExpression
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Logical `or` expression.
|
|
249
|
-
*
|
|
250
|
-
* The expression is simplified to true if this can be decided statically (that is, if one operand is a constant
|
|
251
|
-
* true or if the expression contains an operand and its negation).
|
|
252
|
-
*
|
|
253
|
-
* @param operands Expressions to connect by `or`
|
|
254
|
-
* @returns Expression evaluating to boolean
|
|
255
|
-
*/
|
|
256
|
-
_exports.and = and;
|
|
257
|
-
function or() {
|
|
258
|
-
for (var _len3 = arguments.length, operands = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
259
|
-
operands[_key3] = arguments[_key3];
|
|
260
|
-
}
|
|
261
|
-
const expressions = flattenSetExpression({
|
|
262
|
-
_type: "Set",
|
|
263
|
-
operator: "||",
|
|
264
|
-
operands: operands.map(wrapPrimitive)
|
|
265
|
-
}).operands;
|
|
266
|
-
if (hasUnresolvableExpression(...expressions)) {
|
|
267
|
-
return unresolvableExpression;
|
|
268
|
-
}
|
|
269
|
-
let isStaticTrue = false;
|
|
270
|
-
const nonTrivialExpression = expressions.filter(expression => {
|
|
271
|
-
if (isTrue(expression)) {
|
|
272
|
-
isStaticTrue = true;
|
|
273
|
-
}
|
|
274
|
-
return !isConstant(expression) || expression.value;
|
|
275
|
-
});
|
|
276
|
-
if (isStaticTrue) {
|
|
277
|
-
return constant(true);
|
|
278
|
-
} else if (nonTrivialExpression.length === 0) {
|
|
279
|
-
// Resolve the constant then
|
|
280
|
-
const isValid = expressions.reduce((result, expression) => result && isTrue(expression), true);
|
|
281
|
-
return constant(isValid);
|
|
282
|
-
} else if (nonTrivialExpression.length === 1) {
|
|
283
|
-
return nonTrivialExpression[0];
|
|
284
|
-
} else if (hasOppositeExpressions(nonTrivialExpression)) {
|
|
285
|
-
return constant(true);
|
|
286
|
-
} else {
|
|
287
|
-
return {
|
|
288
|
-
_type: "Set",
|
|
289
|
-
operator: "||",
|
|
290
|
-
operands: nonTrivialExpression
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Logical `not` operator.
|
|
297
|
-
*
|
|
298
|
-
* @param operand The expression to reverse
|
|
299
|
-
* @returns The resulting expression that evaluates to boolean
|
|
300
|
-
*/
|
|
301
|
-
_exports.or = or;
|
|
302
|
-
function not(operand) {
|
|
303
|
-
operand = wrapPrimitive(operand);
|
|
304
|
-
if (hasUnresolvableExpression(operand)) {
|
|
305
|
-
return unresolvableExpression;
|
|
306
|
-
} else if (isConstant(operand)) {
|
|
307
|
-
return constant(!operand.value);
|
|
308
|
-
} else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "||" && operand.operands.every(expression => isConstant(expression) || isComparison(expression))) {
|
|
309
|
-
return and(...operand.operands.map(expression => not(expression)));
|
|
310
|
-
} else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "&&" && operand.operands.every(expression => isConstant(expression) || isComparison(expression))) {
|
|
311
|
-
return or(...operand.operands.map(expression => not(expression)));
|
|
312
|
-
} else if (isComparison(operand)) {
|
|
313
|
-
// Create the reverse comparison
|
|
314
|
-
switch (operand.operator) {
|
|
315
|
-
case "!==":
|
|
316
|
-
return {
|
|
317
|
-
...operand,
|
|
318
|
-
operator: "==="
|
|
319
|
-
};
|
|
320
|
-
case "<":
|
|
321
|
-
return {
|
|
322
|
-
...operand,
|
|
323
|
-
operator: ">="
|
|
324
|
-
};
|
|
325
|
-
case "<=":
|
|
326
|
-
return {
|
|
327
|
-
...operand,
|
|
328
|
-
operator: ">"
|
|
329
|
-
};
|
|
330
|
-
case "===":
|
|
331
|
-
return {
|
|
332
|
-
...operand,
|
|
333
|
-
operator: "!=="
|
|
334
|
-
};
|
|
335
|
-
case ">":
|
|
336
|
-
return {
|
|
337
|
-
...operand,
|
|
338
|
-
operator: "<="
|
|
339
|
-
};
|
|
340
|
-
case ">=":
|
|
341
|
-
return {
|
|
342
|
-
...operand,
|
|
343
|
-
operator: "<"
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
} else if (operand._type === "Not") {
|
|
347
|
-
return operand.operand;
|
|
348
|
-
}
|
|
349
|
-
return {
|
|
350
|
-
_type: "Not",
|
|
351
|
-
operand: operand
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Evaluates whether a binding expression is equal to true with a loose equality.
|
|
357
|
-
*
|
|
358
|
-
* @param operand The expression to check
|
|
359
|
-
* @returns The resulting expression that evaluates to boolean
|
|
360
|
-
*/
|
|
361
|
-
_exports.not = not;
|
|
362
|
-
function isTruthy(operand) {
|
|
363
|
-
if (isConstant(operand)) {
|
|
364
|
-
return constant(!!operand.value);
|
|
365
|
-
} else {
|
|
366
|
-
return {
|
|
367
|
-
_type: "Truthy",
|
|
368
|
-
operand: operand
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Creates a binding expression that will be evaluated by the corresponding model.
|
|
375
|
-
*
|
|
376
|
-
* @param path
|
|
377
|
-
* @param modelName
|
|
378
|
-
* @param visitedNavigationPaths
|
|
379
|
-
* @param pathVisitor
|
|
380
|
-
* @returns An expression representating that path in the model
|
|
381
|
-
* @deprecated use pathInModel instead
|
|
382
|
-
*/
|
|
383
|
-
_exports.isTruthy = isTruthy;
|
|
384
|
-
function bindingExpression(path, modelName) {
|
|
385
|
-
let visitedNavigationPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
386
|
-
let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
|
|
387
|
-
return pathInModel(path, modelName, visitedNavigationPaths, pathVisitor);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Creates a binding expression that will be evaluated by the corresponding model.
|
|
392
|
-
*
|
|
393
|
-
* @template TargetType
|
|
394
|
-
* @param path The path on the model
|
|
395
|
-
* @param [modelName] The name of the model
|
|
396
|
-
* @param [visitedNavigationPaths] The paths from the root entitySet
|
|
397
|
-
* @param [pathVisitor] A function to modify the resulting path
|
|
398
|
-
* @returns An expression representating that path in the model
|
|
399
|
-
*/
|
|
400
|
-
_exports.bindingExpression = bindingExpression;
|
|
401
|
-
function pathInModel(path, modelName) {
|
|
402
|
-
let visitedNavigationPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
403
|
-
let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
|
|
404
|
-
if (path === undefined) {
|
|
405
|
-
return unresolvableExpression;
|
|
406
|
-
}
|
|
407
|
-
let targetPath;
|
|
408
|
-
if (pathVisitor) {
|
|
409
|
-
targetPath = pathVisitor(path);
|
|
410
|
-
if (targetPath === undefined) {
|
|
411
|
-
return unresolvableExpression;
|
|
412
|
-
}
|
|
413
|
-
} else {
|
|
414
|
-
const localPath = visitedNavigationPaths.concat();
|
|
415
|
-
localPath.push(path);
|
|
416
|
-
targetPath = localPath.join("/");
|
|
417
|
-
}
|
|
418
|
-
return {
|
|
419
|
-
_type: "PathInModel",
|
|
420
|
-
modelName: modelName,
|
|
421
|
-
path: targetPath
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
_exports.pathInModel = pathInModel;
|
|
425
|
-
/**
|
|
426
|
-
* Creates a constant expression based on a primitive value.
|
|
427
|
-
*
|
|
428
|
-
* @template T
|
|
429
|
-
* @param value The constant to wrap in an expression
|
|
430
|
-
* @returns The constant expression
|
|
431
|
-
*/
|
|
432
|
-
function constant(value) {
|
|
433
|
-
let constantValue;
|
|
434
|
-
if (typeof value === "object" && value !== null && value !== undefined) {
|
|
435
|
-
if (Array.isArray(value)) {
|
|
436
|
-
constantValue = value.map(wrapPrimitive);
|
|
437
|
-
} else if (isPrimitiveObject(value)) {
|
|
438
|
-
constantValue = value.valueOf();
|
|
439
|
-
} else {
|
|
440
|
-
constantValue = Object.entries(value).reduce((plainExpression, _ref) => {
|
|
441
|
-
let [key, val] = _ref;
|
|
442
|
-
const wrappedValue = wrapPrimitive(val);
|
|
443
|
-
if (wrappedValue._type !== "Constant" || wrappedValue.value !== undefined) {
|
|
444
|
-
plainExpression[key] = wrappedValue;
|
|
445
|
-
}
|
|
446
|
-
return plainExpression;
|
|
447
|
-
}, {});
|
|
448
|
-
}
|
|
449
|
-
} else {
|
|
450
|
-
constantValue = value;
|
|
451
|
-
}
|
|
452
|
-
return {
|
|
453
|
-
_type: "Constant",
|
|
454
|
-
value: constantValue
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
_exports.constant = constant;
|
|
458
|
-
function resolveBindingString(value, targetType) {
|
|
459
|
-
if (value !== undefined && typeof value === "string" && value.startsWith("{")) {
|
|
460
|
-
const pathInModelRegex = /^{(.*)>(.+)}$/; // Matches model paths like "model>path" or ">path" (default model)
|
|
461
|
-
const pathInModelRegexMatch = pathInModelRegex.exec(value);
|
|
462
|
-
if (value.startsWith("{=")) {
|
|
463
|
-
// Expression binding, we can just remove the outer binding things
|
|
464
|
-
return {
|
|
465
|
-
_type: "EmbeddedExpressionBinding",
|
|
466
|
-
value: value
|
|
467
|
-
};
|
|
468
|
-
} else if (pathInModelRegexMatch) {
|
|
469
|
-
return pathInModel(pathInModelRegexMatch[2] || "", pathInModelRegexMatch[1] || undefined);
|
|
470
|
-
} else {
|
|
471
|
-
return {
|
|
472
|
-
_type: "EmbeddedBinding",
|
|
473
|
-
value: value
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
} else if (targetType === "boolean" && typeof value === "string" && (value === "true" || value === "false")) {
|
|
477
|
-
return constant(value === "true");
|
|
478
|
-
} else if (targetType === "number" && typeof value === "string" && (!isNaN(Number(value)) || value === "NaN")) {
|
|
479
|
-
return constant(Number(value));
|
|
480
|
-
} else {
|
|
481
|
-
return constant(value);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* A named reference.
|
|
487
|
-
*
|
|
488
|
-
* @see fn
|
|
489
|
-
* @param reference Reference
|
|
490
|
-
* @returns The object reference binding part
|
|
491
|
-
*/
|
|
492
|
-
_exports.resolveBindingString = resolveBindingString;
|
|
493
|
-
function ref(reference) {
|
|
494
|
-
return {
|
|
495
|
-
_type: "Ref",
|
|
496
|
-
ref: reference
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
/**
|
|
501
|
-
* Wrap a primitive into a constant expression if it is not already an expression.
|
|
502
|
-
*
|
|
503
|
-
* @template T
|
|
504
|
-
* @param something The object to wrap in a Constant expression
|
|
505
|
-
* @returns Either the original object or the wrapped one depending on the case
|
|
506
|
-
*/
|
|
507
|
-
_exports.ref = ref;
|
|
508
|
-
function wrapPrimitive(something) {
|
|
509
|
-
if (isBindingToolkitExpression(something)) {
|
|
510
|
-
return something;
|
|
511
|
-
}
|
|
512
|
-
return constant(something);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
/**
|
|
516
|
-
* Checks if the expression or value provided is a binding tooling expression or not.
|
|
517
|
-
*
|
|
518
|
-
* Every object having a property named `_type` of some value is considered an expression, even if there is actually
|
|
519
|
-
* no such expression type supported.
|
|
520
|
-
*
|
|
521
|
-
* @param expression
|
|
522
|
-
* @returns `true` if the expression is a binding toolkit expression
|
|
523
|
-
*/
|
|
524
|
-
_exports.wrapPrimitive = wrapPrimitive;
|
|
525
|
-
function isBindingToolkitExpression(expression) {
|
|
526
|
-
return (expression === null || expression === void 0 ? void 0 : expression._type) !== undefined;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Checks if the expression or value provided is constant or not.
|
|
531
|
-
*
|
|
532
|
-
* @template T The target type
|
|
533
|
-
* @param maybeConstant The expression or primitive value that is to be checked
|
|
534
|
-
* @returns `true` if it is constant
|
|
535
|
-
*/
|
|
536
|
-
_exports.isBindingToolkitExpression = isBindingToolkitExpression;
|
|
537
|
-
function isConstant(maybeConstant) {
|
|
538
|
-
return typeof maybeConstant !== "object" || maybeConstant._type === "Constant";
|
|
539
|
-
}
|
|
540
|
-
_exports.isConstant = isConstant;
|
|
541
|
-
function isTrue(expression) {
|
|
542
|
-
return isConstant(expression) && expression.value === true;
|
|
543
|
-
}
|
|
544
|
-
function isFalse(expression) {
|
|
545
|
-
return isConstant(expression) && expression.value === false;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
/**
|
|
549
|
-
* Checks if the expression or value provided is a path in model expression or not.
|
|
550
|
-
*
|
|
551
|
-
* @template T The target type
|
|
552
|
-
* @param maybeBinding The expression or primitive value that is to be checked
|
|
553
|
-
* @returns `true` if it is a path in model expression
|
|
554
|
-
*/
|
|
555
|
-
function isPathInModelExpression(maybeBinding) {
|
|
556
|
-
return (maybeBinding === null || maybeBinding === void 0 ? void 0 : maybeBinding._type) === "PathInModel";
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* Checks if the expression or value provided is a complex type expression.
|
|
561
|
-
*
|
|
562
|
-
* @template T The target type
|
|
563
|
-
* @param maybeBinding The expression or primitive value that is to be checked
|
|
564
|
-
* @returns `true` if it is a path in model expression
|
|
565
|
-
*/
|
|
566
|
-
_exports.isPathInModelExpression = isPathInModelExpression;
|
|
567
|
-
function isComplexTypeExpression(maybeBinding) {
|
|
568
|
-
return (maybeBinding === null || maybeBinding === void 0 ? void 0 : maybeBinding._type) === "ComplexType";
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
* Checks if the expression or value provided is a concat expression or not.
|
|
573
|
-
*
|
|
574
|
-
* @param expression
|
|
575
|
-
* @returns `true` if the expression is a ConcatExpression
|
|
576
|
-
*/
|
|
577
|
-
_exports.isComplexTypeExpression = isComplexTypeExpression;
|
|
578
|
-
function isConcatExpression(expression) {
|
|
579
|
-
return (expression === null || expression === void 0 ? void 0 : expression._type) === "Concat";
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
/**
|
|
583
|
-
* Checks if the expression or value provided is a IfElse expression or not.
|
|
584
|
-
*
|
|
585
|
-
* @param expression
|
|
586
|
-
* @returns `true` if the expression is a IfElseExpression
|
|
587
|
-
*/
|
|
588
|
-
function isIfElseExpression(expression) {
|
|
589
|
-
return (expression === null || expression === void 0 ? void 0 : expression._type) === "IfElse";
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
/**
|
|
593
|
-
* Checks if the expression provided is a comparison or not.
|
|
594
|
-
*
|
|
595
|
-
* @template T The target type
|
|
596
|
-
* @param expression The expression
|
|
597
|
-
* @returns `true` if the expression is a ComparisonExpression
|
|
598
|
-
*/
|
|
599
|
-
function isComparison(expression) {
|
|
600
|
-
return expression._type === "Comparison";
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
/**
|
|
604
|
-
* Checks whether the input parameter is a constant expression of type undefined.
|
|
605
|
-
*
|
|
606
|
-
* @param expression The input expression or object in general
|
|
607
|
-
* @returns `true` if the input is constant which has undefined for value
|
|
608
|
-
*/
|
|
609
|
-
function isUndefinedExpression(expression) {
|
|
610
|
-
const expressionAsExpression = expression;
|
|
611
|
-
return (expressionAsExpression === null || expressionAsExpression === void 0 ? void 0 : expressionAsExpression._type) === "Constant" && (expressionAsExpression === null || expressionAsExpression === void 0 ? void 0 : expressionAsExpression.value) === undefined;
|
|
612
|
-
}
|
|
613
|
-
_exports.isUndefinedExpression = isUndefinedExpression;
|
|
614
|
-
function isPrimitiveObject(objectType) {
|
|
615
|
-
switch (objectType.constructor.name) {
|
|
616
|
-
case "String":
|
|
617
|
-
case "Number":
|
|
618
|
-
case "Boolean":
|
|
619
|
-
return true;
|
|
620
|
-
default:
|
|
621
|
-
return false;
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
/**
|
|
625
|
-
* Check if the passed annotation annotationValue is a ComplexAnnotationExpression.
|
|
626
|
-
*
|
|
627
|
-
* @template T The target type
|
|
628
|
-
* @param annotationValue The annotation annotationValue to evaluate
|
|
629
|
-
* @returns `true` if the object is a {ComplexAnnotationExpression}
|
|
630
|
-
*/
|
|
631
|
-
function isComplexAnnotationExpression(annotationValue) {
|
|
632
|
-
return typeof annotationValue === "object" && !isPrimitiveObject(annotationValue);
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
/**
|
|
636
|
-
* Generate the corresponding annotationValue for a given annotation annotationValue.
|
|
637
|
-
*
|
|
638
|
-
* @template T The target type
|
|
639
|
-
* @param annotationValue The source annotation annotationValue
|
|
640
|
-
* @param visitedNavigationPaths The path from the root entity set
|
|
641
|
-
* @param defaultValue Default value if the annotationValue is undefined
|
|
642
|
-
* @param pathVisitor A function to modify the resulting path
|
|
643
|
-
* @returns The annotationValue equivalent to that annotation annotationValue
|
|
644
|
-
*/
|
|
645
|
-
function getExpressionFromAnnotation(annotationValue) {
|
|
646
|
-
var _annotationValue;
|
|
647
|
-
let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
648
|
-
let defaultValue = arguments.length > 2 ? arguments[2] : undefined;
|
|
649
|
-
let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
|
|
650
|
-
if (annotationValue === undefined) {
|
|
651
|
-
return wrapPrimitive(defaultValue);
|
|
652
|
-
}
|
|
653
|
-
annotationValue = (_annotationValue = annotationValue) === null || _annotationValue === void 0 ? void 0 : _annotationValue.valueOf();
|
|
654
|
-
if (!isComplexAnnotationExpression(annotationValue)) {
|
|
655
|
-
return constant(annotationValue);
|
|
656
|
-
}
|
|
657
|
-
switch (annotationValue.type) {
|
|
658
|
-
case "Path":
|
|
659
|
-
return pathInModel(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
|
|
660
|
-
case "If":
|
|
661
|
-
return annotationIfExpression(annotationValue.If, visitedNavigationPaths, pathVisitor);
|
|
662
|
-
case "Not":
|
|
663
|
-
return not(parseAnnotationCondition(annotationValue.Not, visitedNavigationPaths, pathVisitor));
|
|
664
|
-
case "Eq":
|
|
665
|
-
return equal(parseAnnotationCondition(annotationValue.Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Eq[1], visitedNavigationPaths, pathVisitor));
|
|
666
|
-
case "Ne":
|
|
667
|
-
return notEqual(parseAnnotationCondition(annotationValue.Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Ne[1], visitedNavigationPaths, pathVisitor));
|
|
668
|
-
case "Gt":
|
|
669
|
-
return greaterThan(parseAnnotationCondition(annotationValue.Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Gt[1], visitedNavigationPaths, pathVisitor));
|
|
670
|
-
case "Ge":
|
|
671
|
-
return greaterOrEqual(parseAnnotationCondition(annotationValue.Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Ge[1], visitedNavigationPaths, pathVisitor));
|
|
672
|
-
case "Lt":
|
|
673
|
-
return lessThan(parseAnnotationCondition(annotationValue.Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Lt[1], visitedNavigationPaths, pathVisitor));
|
|
674
|
-
case "Le":
|
|
675
|
-
return lessOrEqual(parseAnnotationCondition(annotationValue.Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Le[1], visitedNavigationPaths, pathVisitor));
|
|
676
|
-
case "Or":
|
|
677
|
-
return or(...annotationValue.Or.map(function (orCondition) {
|
|
678
|
-
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
679
|
-
}));
|
|
680
|
-
case "And":
|
|
681
|
-
return and(...annotationValue.And.map(function (andCondition) {
|
|
682
|
-
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
683
|
-
}));
|
|
684
|
-
case "Apply":
|
|
685
|
-
return annotationApplyExpression(annotationValue, visitedNavigationPaths, pathVisitor);
|
|
686
|
-
}
|
|
687
|
-
return unresolvableExpression;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
/**
|
|
691
|
-
* Parse the annotation condition into an expression.
|
|
692
|
-
*
|
|
693
|
-
* @template T The target type
|
|
694
|
-
* @param annotationValue The condition or value from the annotation
|
|
695
|
-
* @param visitedNavigationPaths The path from the root entity set
|
|
696
|
-
* @param pathVisitor A function to modify the resulting path
|
|
697
|
-
* @returns An equivalent expression
|
|
698
|
-
*/
|
|
699
|
-
_exports.getExpressionFromAnnotation = getExpressionFromAnnotation;
|
|
700
|
-
function parseAnnotationCondition(annotationValue) {
|
|
701
|
-
let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
702
|
-
let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
|
|
703
|
-
if (annotationValue === null || typeof annotationValue !== "object") {
|
|
704
|
-
return constant(annotationValue);
|
|
705
|
-
} else if (annotationValue.hasOwnProperty("$Or")) {
|
|
706
|
-
return or(...annotationValue.$Or.map(function (orCondition) {
|
|
707
|
-
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
708
|
-
}));
|
|
709
|
-
} else if (annotationValue.hasOwnProperty("$And")) {
|
|
710
|
-
return and(...annotationValue.$And.map(function (andCondition) {
|
|
711
|
-
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
712
|
-
}));
|
|
713
|
-
} else if (annotationValue.hasOwnProperty("$Not")) {
|
|
714
|
-
return not(parseAnnotationCondition(annotationValue.$Not, visitedNavigationPaths, pathVisitor));
|
|
715
|
-
} else if (annotationValue.hasOwnProperty("$Eq")) {
|
|
716
|
-
return equal(parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor));
|
|
717
|
-
} else if (annotationValue.hasOwnProperty("$Ne")) {
|
|
718
|
-
return notEqual(parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor));
|
|
719
|
-
} else if (annotationValue.hasOwnProperty("$Gt")) {
|
|
720
|
-
return greaterThan(parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor));
|
|
721
|
-
} else if (annotationValue.hasOwnProperty("$Ge")) {
|
|
722
|
-
return greaterOrEqual(parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor));
|
|
723
|
-
} else if (annotationValue.hasOwnProperty("$Lt")) {
|
|
724
|
-
return lessThan(parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor));
|
|
725
|
-
} else if (annotationValue.hasOwnProperty("$Le")) {
|
|
726
|
-
return lessOrEqual(parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor));
|
|
727
|
-
} else if (annotationValue.hasOwnProperty("$Path")) {
|
|
728
|
-
return pathInModel(annotationValue.$Path, undefined, visitedNavigationPaths, pathVisitor);
|
|
729
|
-
} else if (annotationValue.hasOwnProperty("$Apply")) {
|
|
730
|
-
return getExpressionFromAnnotation({
|
|
731
|
-
type: "Apply",
|
|
732
|
-
Function: annotationValue.$Function,
|
|
733
|
-
Apply: annotationValue.$Apply
|
|
734
|
-
}, visitedNavigationPaths, undefined, pathVisitor);
|
|
735
|
-
} else if (annotationValue.hasOwnProperty("$If")) {
|
|
736
|
-
return getExpressionFromAnnotation({
|
|
737
|
-
type: "If",
|
|
738
|
-
If: annotationValue.$If
|
|
739
|
-
}, visitedNavigationPaths, undefined, pathVisitor);
|
|
740
|
-
} else if (annotationValue.hasOwnProperty("$EnumMember")) {
|
|
741
|
-
return constant(resolveEnumValue(annotationValue.$EnumMember));
|
|
742
|
-
}
|
|
743
|
-
return constant(false);
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
/**
|
|
747
|
-
* Process the {IfAnnotationExpressionValue} into an expression.
|
|
748
|
-
*
|
|
749
|
-
* @template T The target type
|
|
750
|
-
* @param annotationValue An If expression returning the type T
|
|
751
|
-
* @param visitedNavigationPaths The path from the root entity set
|
|
752
|
-
* @param pathVisitor A function to modify the resulting path
|
|
753
|
-
* @returns The equivalent ifElse expression
|
|
754
|
-
*/
|
|
755
|
-
function annotationIfExpression(annotationValue) {
|
|
756
|
-
let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
757
|
-
let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
|
|
758
|
-
return ifElse(parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[1], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[2], visitedNavigationPaths, pathVisitor));
|
|
759
|
-
}
|
|
760
|
-
// This type is not recursively transformed from the metamodel content, as such we have some ugly things there
|
|
761
|
-
_exports.annotationIfExpression = annotationIfExpression;
|
|
762
|
-
function convertSubApplyParameters(applyParam) {
|
|
763
|
-
let applyParamConverted = applyParam;
|
|
764
|
-
if (applyParam.hasOwnProperty("$Path")) {
|
|
765
|
-
applyParamConverted = {
|
|
766
|
-
type: "Path",
|
|
767
|
-
path: applyParam.$Path
|
|
768
|
-
};
|
|
769
|
-
} else if (applyParam.hasOwnProperty("$If")) {
|
|
770
|
-
applyParamConverted = {
|
|
771
|
-
type: "If",
|
|
772
|
-
If: applyParam.$If
|
|
773
|
-
};
|
|
774
|
-
} else if (applyParam.hasOwnProperty("$Apply")) {
|
|
775
|
-
applyParamConverted = {
|
|
776
|
-
type: "Apply",
|
|
777
|
-
Function: applyParam.$Function,
|
|
778
|
-
Apply: applyParam.$Apply
|
|
779
|
-
};
|
|
780
|
-
}
|
|
781
|
-
return applyParamConverted;
|
|
782
|
-
}
|
|
783
|
-
function annotationApplyExpression(applyExpression) {
|
|
784
|
-
let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
785
|
-
let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
|
|
786
|
-
switch (applyExpression.Function) {
|
|
787
|
-
case "odata.concat":
|
|
788
|
-
return concat(...applyExpression.Apply.map(applyParam => {
|
|
789
|
-
return getExpressionFromAnnotation(convertSubApplyParameters(applyParam), visitedNavigationPaths, undefined, pathVisitor);
|
|
790
|
-
}));
|
|
791
|
-
case "odata.uriEncode":
|
|
792
|
-
const parameter = getExpressionFromAnnotation(convertSubApplyParameters(applyExpression.Apply[0]), visitedNavigationPaths, undefined, pathVisitor);
|
|
793
|
-
// The second parameter for uriEncode is always a string since the target evaluation is against a formatValue call in ODataUtils which expect the target type as second parameter
|
|
794
|
-
return fn("odata.uriEncode", [parameter, "Edm.String"], undefined, true);
|
|
795
|
-
case "odata.fillUriTemplate":
|
|
796
|
-
const template = applyExpression.Apply[0];
|
|
797
|
-
const templateParams = applyExpression.Apply.slice(1);
|
|
798
|
-
const targetObject = {};
|
|
799
|
-
templateParams.forEach(applyParam => {
|
|
800
|
-
targetObject[applyParam.$Name] = getExpressionFromAnnotation(convertSubApplyParameters(applyParam.$LabeledElement), visitedNavigationPaths, undefined, pathVisitor);
|
|
801
|
-
});
|
|
802
|
-
return fn("odata.fillUriTemplate", [template, targetObject], undefined, true);
|
|
803
|
-
}
|
|
804
|
-
return unresolvableExpression;
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
/**
|
|
808
|
-
* Generic helper for the comparison operations (equal, notEqual, ...).
|
|
809
|
-
*
|
|
810
|
-
* @template T The target type
|
|
811
|
-
* @param operator The operator to apply
|
|
812
|
-
* @param leftOperand The operand on the left side of the operator
|
|
813
|
-
* @param rightOperand The operand on the right side of the operator
|
|
814
|
-
* @returns An expression representing the comparison
|
|
815
|
-
*/
|
|
816
|
-
_exports.annotationApplyExpression = annotationApplyExpression;
|
|
817
|
-
function comparison(operator, leftOperand, rightOperand) {
|
|
818
|
-
const leftExpression = wrapPrimitive(leftOperand);
|
|
819
|
-
const rightExpression = wrapPrimitive(rightOperand);
|
|
820
|
-
if (hasUnresolvableExpression(leftExpression, rightExpression)) {
|
|
821
|
-
return unresolvableExpression;
|
|
822
|
-
}
|
|
823
|
-
if (isConstant(leftExpression) && isConstant(rightExpression)) {
|
|
824
|
-
switch (operator) {
|
|
825
|
-
case "!==":
|
|
826
|
-
return constant(leftExpression.value !== rightExpression.value);
|
|
827
|
-
case "===":
|
|
828
|
-
return constant(leftExpression.value === rightExpression.value);
|
|
829
|
-
case "<":
|
|
830
|
-
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
831
|
-
return constant(false);
|
|
832
|
-
}
|
|
833
|
-
return constant(leftExpression.value < rightExpression.value);
|
|
834
|
-
case "<=":
|
|
835
|
-
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
836
|
-
return constant(false);
|
|
837
|
-
}
|
|
838
|
-
return constant(leftExpression.value <= rightExpression.value);
|
|
839
|
-
case ">":
|
|
840
|
-
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
841
|
-
return constant(false);
|
|
842
|
-
}
|
|
843
|
-
return constant(leftExpression.value > rightExpression.value);
|
|
844
|
-
case ">=":
|
|
845
|
-
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
846
|
-
return constant(false);
|
|
847
|
-
}
|
|
848
|
-
return constant(leftExpression.value >= rightExpression.value);
|
|
849
|
-
}
|
|
850
|
-
} else {
|
|
851
|
-
return {
|
|
852
|
-
_type: "Comparison",
|
|
853
|
-
operator: operator,
|
|
854
|
-
operand1: leftExpression,
|
|
855
|
-
operand2: rightExpression
|
|
856
|
-
};
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
/**
|
|
861
|
-
* Generic helper for the length of an expression.
|
|
862
|
-
*
|
|
863
|
-
* @param expression The input expression pointing to an array
|
|
864
|
-
* @param checkUndefined Is the array potentially undefined
|
|
865
|
-
* @returns An expression representing the length
|
|
866
|
-
*/
|
|
867
|
-
function length(expression) {
|
|
868
|
-
let checkUndefined = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
869
|
-
if (expression._type === "Unresolvable") {
|
|
870
|
-
return expression;
|
|
871
|
-
}
|
|
872
|
-
if (!checkUndefined) {
|
|
873
|
-
return {
|
|
874
|
-
_type: "Length",
|
|
875
|
-
pathInModel: expression
|
|
876
|
-
};
|
|
877
|
-
}
|
|
878
|
-
return ifElse(equal(expression, undefined), -1, length(expression));
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
/**
|
|
882
|
-
* Comparison: "equal" (===).
|
|
883
|
-
*
|
|
884
|
-
* @template T The target type
|
|
885
|
-
* @param leftOperand The operand on the left side
|
|
886
|
-
* @param rightOperand The operand on the right side of the comparison
|
|
887
|
-
* @returns An expression representing the comparison
|
|
888
|
-
*/
|
|
889
|
-
_exports.length = length;
|
|
890
|
-
function equal(leftOperand, rightOperand) {
|
|
891
|
-
const leftExpression = wrapPrimitive(leftOperand);
|
|
892
|
-
const rightExpression = wrapPrimitive(rightOperand);
|
|
893
|
-
if (hasUnresolvableExpression(leftExpression, rightExpression)) {
|
|
894
|
-
return unresolvableExpression;
|
|
895
|
-
}
|
|
896
|
-
if (_checkExpressionsAreEqual(leftExpression, rightExpression)) {
|
|
897
|
-
return constant(true);
|
|
898
|
-
}
|
|
899
|
-
function reduce(left, right) {
|
|
900
|
-
if (left._type === "Comparison" && isTrue(right)) {
|
|
901
|
-
// compare(a, b) === true ~~> compare(a, b)
|
|
902
|
-
return left;
|
|
903
|
-
} else if (left._type === "Comparison" && isFalse(right)) {
|
|
904
|
-
// compare(a, b) === false ~~> !compare(a, b)
|
|
905
|
-
return not(left);
|
|
906
|
-
} else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onTrue, right)) {
|
|
907
|
-
// (if (x) { a } else { b }) === a ~~> x || (b === a)
|
|
908
|
-
return or(left.condition, equal(left.onFalse, right));
|
|
909
|
-
} else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onFalse, right)) {
|
|
910
|
-
// (if (x) { a } else { b }) === b ~~> !x || (a === b)
|
|
911
|
-
return or(not(left.condition), equal(left.onTrue, right));
|
|
912
|
-
} else if (left._type === "IfElse" && isConstant(left.onTrue) && isConstant(left.onFalse) && isConstant(right) && !_checkExpressionsAreEqual(left.onTrue, right) && !_checkExpressionsAreEqual(left.onFalse, right)) {
|
|
913
|
-
return constant(false);
|
|
914
|
-
}
|
|
915
|
-
return undefined;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
// exploit symmetry: a === b <~> b === a
|
|
919
|
-
const reduced = reduce(leftExpression, rightExpression) ?? reduce(rightExpression, leftExpression);
|
|
920
|
-
return reduced ?? comparison("===", leftExpression, rightExpression);
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
/**
|
|
924
|
-
* Comparison: "not equal" (!==).
|
|
925
|
-
*
|
|
926
|
-
* @template T The target type
|
|
927
|
-
* @param leftOperand The operand on the left side
|
|
928
|
-
* @param rightOperand The operand on the right side of the comparison
|
|
929
|
-
* @returns An expression representing the comparison
|
|
930
|
-
*/
|
|
931
|
-
_exports.equal = equal;
|
|
932
|
-
function notEqual(leftOperand, rightOperand) {
|
|
933
|
-
return not(equal(leftOperand, rightOperand));
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
/**
|
|
937
|
-
* Comparison: "greater or equal" (>=).
|
|
938
|
-
*
|
|
939
|
-
* @template T The target type
|
|
940
|
-
* @param leftOperand The operand on the left side
|
|
941
|
-
* @param rightOperand The operand on the right side of the comparison
|
|
942
|
-
* @returns An expression representing the comparison
|
|
943
|
-
*/
|
|
944
|
-
_exports.notEqual = notEqual;
|
|
945
|
-
function greaterOrEqual(leftOperand, rightOperand) {
|
|
946
|
-
return comparison(">=", leftOperand, rightOperand);
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
/**
|
|
950
|
-
* Comparison: "greater than" (>).
|
|
951
|
-
*
|
|
952
|
-
* @template T The target type
|
|
953
|
-
* @param leftOperand The operand on the left side
|
|
954
|
-
* @param rightOperand The operand on the right side of the comparison
|
|
955
|
-
* @returns An expression representing the comparison
|
|
956
|
-
*/
|
|
957
|
-
_exports.greaterOrEqual = greaterOrEqual;
|
|
958
|
-
function greaterThan(leftOperand, rightOperand) {
|
|
959
|
-
return comparison(">", leftOperand, rightOperand);
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
/**
|
|
963
|
-
* Comparison: "less or equal" (<=).
|
|
964
|
-
*
|
|
965
|
-
* @template T The target type
|
|
966
|
-
* @param leftOperand The operand on the left side
|
|
967
|
-
* @param rightOperand The operand on the right side of the comparison
|
|
968
|
-
* @returns An expression representing the comparison
|
|
969
|
-
*/
|
|
970
|
-
_exports.greaterThan = greaterThan;
|
|
971
|
-
function lessOrEqual(leftOperand, rightOperand) {
|
|
972
|
-
return comparison("<=", leftOperand, rightOperand);
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
/**
|
|
976
|
-
* Comparison: "less than" (<).
|
|
977
|
-
*
|
|
978
|
-
* @template T The target type
|
|
979
|
-
* @param leftOperand The operand on the left side
|
|
980
|
-
* @param rightOperand The operand on the right side of the comparison
|
|
981
|
-
* @returns An expression representing the comparison
|
|
982
|
-
*/
|
|
983
|
-
_exports.lessOrEqual = lessOrEqual;
|
|
984
|
-
function lessThan(leftOperand, rightOperand) {
|
|
985
|
-
return comparison("<", leftOperand, rightOperand);
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
/**
|
|
989
|
-
* If-then-else expression.
|
|
990
|
-
*
|
|
991
|
-
* Evaluates to onTrue if the condition evaluates to true, else evaluates to onFalse.
|
|
992
|
-
*
|
|
993
|
-
* @template T The target type
|
|
994
|
-
* @param condition The condition to evaluate
|
|
995
|
-
* @param onTrue Expression result if the condition evaluates to true
|
|
996
|
-
* @param onFalse Expression result if the condition evaluates to false
|
|
997
|
-
* @returns The expression that represents this conditional check
|
|
998
|
-
*/
|
|
999
|
-
_exports.lessThan = lessThan;
|
|
1000
|
-
function ifElse(condition, onTrue, onFalse) {
|
|
1001
|
-
let conditionExpression = wrapPrimitive(condition);
|
|
1002
|
-
let onTrueExpression = wrapPrimitive(onTrue);
|
|
1003
|
-
let onFalseExpression = wrapPrimitive(onFalse);
|
|
1004
|
-
|
|
1005
|
-
// swap branches if the condition is a negation
|
|
1006
|
-
if (conditionExpression._type === "Not") {
|
|
1007
|
-
// ifElse(not(X), a, b) --> ifElse(X, b, a)
|
|
1008
|
-
[onTrueExpression, onFalseExpression] = [onFalseExpression, onTrueExpression];
|
|
1009
|
-
conditionExpression = not(conditionExpression);
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
// inline nested if-else expressions: onTrue branch
|
|
1013
|
-
// ifElse(X, ifElse(X, a, b), c) ==> ifElse(X, a, c)
|
|
1014
|
-
if (onTrueExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onTrueExpression.condition)) {
|
|
1015
|
-
onTrueExpression = onTrueExpression.onTrue;
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
// inline nested if-else expressions: onFalse branch
|
|
1019
|
-
// ifElse(X, a, ifElse(X, b, c)) ==> ifElse(X, a, c)
|
|
1020
|
-
if (onFalseExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onFalseExpression.condition)) {
|
|
1021
|
-
onFalseExpression = onFalseExpression.onFalse;
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
// (if true then a else b) ~~> a
|
|
1025
|
-
// (if false then a else b) ~~> b
|
|
1026
|
-
if (isConstant(conditionExpression)) {
|
|
1027
|
-
return conditionExpression.value ? onTrueExpression : onFalseExpression;
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
// if (isConstantBoolean(onTrueExpression) || isConstantBoolean(onFalseExpression)) {
|
|
1031
|
-
// return or(and(condition, onTrueExpression as Expression<boolean>), and(not(condition), onFalseExpression as Expression<boolean>)) as Expression<T>
|
|
1032
|
-
// }
|
|
1033
|
-
|
|
1034
|
-
// (if X then a else a) ~~> a
|
|
1035
|
-
if (_checkExpressionsAreEqual(onTrueExpression, onFalseExpression)) {
|
|
1036
|
-
return onTrueExpression;
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
// if X then a else false ~~> X && a
|
|
1040
|
-
if (isFalse(onFalseExpression)) {
|
|
1041
|
-
return and(conditionExpression, onTrueExpression);
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
// if X then a else true ~~> !X || a
|
|
1045
|
-
if (isTrue(onFalseExpression)) {
|
|
1046
|
-
return or(not(conditionExpression), onTrueExpression);
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
// if X then false else a ~~> !X && a
|
|
1050
|
-
if (isFalse(onTrueExpression)) {
|
|
1051
|
-
return and(not(conditionExpression), onFalseExpression);
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
// if X then true else a ~~> X || a
|
|
1055
|
-
if (isTrue(onTrueExpression)) {
|
|
1056
|
-
return or(conditionExpression, onFalseExpression);
|
|
1057
|
-
}
|
|
1058
|
-
if (hasUnresolvableExpression(conditionExpression, onTrueExpression, onFalseExpression)) {
|
|
1059
|
-
return unresolvableExpression;
|
|
1060
|
-
}
|
|
1061
|
-
if (isComplexTypeExpression(condition) || isComplexTypeExpression(onTrue) || isComplexTypeExpression(onFalse)) {
|
|
1062
|
-
let pathIdx = 0;
|
|
1063
|
-
const myIfElseExpression = formatResult([condition, onTrue, onFalse], "sap.fe.core.formatters.StandardFormatter#ifElse");
|
|
1064
|
-
const allParts = [];
|
|
1065
|
-
transformRecursively(myIfElseExpression, "PathInModel", constantPath => {
|
|
1066
|
-
allParts.push(constantPath);
|
|
1067
|
-
return pathInModel(`$${pathIdx++}`, "$");
|
|
1068
|
-
}, true);
|
|
1069
|
-
allParts.unshift(constant(JSON.stringify(myIfElseExpression)));
|
|
1070
|
-
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
|
|
1071
|
-
}
|
|
1072
|
-
return {
|
|
1073
|
-
_type: "IfElse",
|
|
1074
|
-
condition: conditionExpression,
|
|
1075
|
-
onTrue: onTrueExpression,
|
|
1076
|
-
onFalse: onFalseExpression
|
|
1077
|
-
};
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
/**
|
|
1081
|
-
* Checks whether the current expression has a reference to the default model (undefined).
|
|
1082
|
-
*
|
|
1083
|
-
* @param expression The expression to evaluate
|
|
1084
|
-
* @returns `true` if there is a reference to the default context
|
|
1085
|
-
*/
|
|
1086
|
-
_exports.ifElse = ifElse;
|
|
1087
|
-
function hasReferenceToDefaultContext(expression) {
|
|
1088
|
-
switch (expression._type) {
|
|
1089
|
-
case "Constant":
|
|
1090
|
-
case "Formatter":
|
|
1091
|
-
case "ComplexType":
|
|
1092
|
-
return false;
|
|
1093
|
-
case "Set":
|
|
1094
|
-
return expression.operands.some(hasReferenceToDefaultContext);
|
|
1095
|
-
case "PathInModel":
|
|
1096
|
-
return expression.modelName === undefined;
|
|
1097
|
-
case "Comparison":
|
|
1098
|
-
return hasReferenceToDefaultContext(expression.operand1) || hasReferenceToDefaultContext(expression.operand2);
|
|
1099
|
-
case "IfElse":
|
|
1100
|
-
return hasReferenceToDefaultContext(expression.condition) || hasReferenceToDefaultContext(expression.onTrue) || hasReferenceToDefaultContext(expression.onFalse);
|
|
1101
|
-
case "Not":
|
|
1102
|
-
case "Truthy":
|
|
1103
|
-
return hasReferenceToDefaultContext(expression.operand);
|
|
1104
|
-
default:
|
|
1105
|
-
return false;
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
// This is one case where any does make sense...
|
|
1110
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1111
|
-
|
|
1112
|
-
/**
|
|
1113
|
-
* Calls a formatter function to process the parameters.
|
|
1114
|
-
* If requireContext is set to true and no context is passed a default context will be added automatically.
|
|
1115
|
-
*
|
|
1116
|
-
* @template T
|
|
1117
|
-
* @template U
|
|
1118
|
-
* @param parameters The list of parameter that should match the type and number of the formatter function
|
|
1119
|
-
* @param formatterFunction The function to call
|
|
1120
|
-
* @param [contextEntityType] If no parameter refers to the context then we use this information to add a reference to the keys from the entity type.
|
|
1121
|
-
* @param [ignoreComplexType] Whether to ignore the transgformation to the StandardFormatter or not
|
|
1122
|
-
* @returns The corresponding expression
|
|
1123
|
-
*/
|
|
1124
|
-
function formatResult(parameters, formatterFunction, contextEntityType) {
|
|
1125
|
-
let ignoreComplexType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1126
|
-
const parameterExpressions = parameters.map(wrapPrimitive);
|
|
1127
|
-
if (hasUnresolvableExpression(...parameterExpressions)) {
|
|
1128
|
-
return unresolvableExpression;
|
|
1129
|
-
}
|
|
1130
|
-
if (contextEntityType) {
|
|
1131
|
-
// Otherwise, if the context is required and no context is provided make sure to add the default binding
|
|
1132
|
-
if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
|
|
1133
|
-
contextEntityType.keys.forEach(key => parameterExpressions.push(pathInModel(key.name, "")));
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
let functionName = "";
|
|
1137
|
-
if (typeof formatterFunction === "string") {
|
|
1138
|
-
functionName = formatterFunction;
|
|
1139
|
-
} else {
|
|
1140
|
-
functionName = formatterFunction.__functionName;
|
|
1141
|
-
}
|
|
1142
|
-
// FormatterName can be of format sap.fe.core.xxx#methodName to have multiple formatter in one class
|
|
1143
|
-
const [formatterClass, formatterName] = functionName.split("#");
|
|
1144
|
-
|
|
1145
|
-
// In some case we also cannot call directly a function because of too complex input, in that case we need to convert to a simpler function call
|
|
1146
|
-
if (!ignoreComplexType && (parameterExpressions.some(isComplexTypeExpression) || parameterExpressions.some(isConcatExpression) || parameterExpressions.some(isIfElseExpression))) {
|
|
1147
|
-
let pathIdx = 0;
|
|
1148
|
-
const myFormatExpression = formatResult(parameterExpressions, functionName, undefined, true);
|
|
1149
|
-
const allParts = [];
|
|
1150
|
-
transformRecursively(myFormatExpression, "PathInModel", constantPath => {
|
|
1151
|
-
allParts.push(constantPath);
|
|
1152
|
-
return pathInModel(`$${pathIdx++}`, "$");
|
|
1153
|
-
}, true);
|
|
1154
|
-
allParts.unshift(constant(JSON.stringify(myFormatExpression)));
|
|
1155
|
-
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
|
|
1156
|
-
} else if (!!formatterName && formatterName.length > 0) {
|
|
1157
|
-
parameterExpressions.unshift(constant(formatterName));
|
|
1158
|
-
}
|
|
1159
|
-
return {
|
|
1160
|
-
_type: "Formatter",
|
|
1161
|
-
fn: formatterClass,
|
|
1162
|
-
parameters: parameterExpressions
|
|
1163
|
-
};
|
|
1164
|
-
}
|
|
1165
|
-
_exports.formatResult = formatResult;
|
|
1166
|
-
function setUpConstraints(targetMapping, property) {
|
|
1167
|
-
var _targetMapping$constr, _targetMapping$constr2, _targetMapping$constr3, _targetMapping$constr4, _property$annotations, _property$annotations2, _targetMapping$constr5, _property$annotations5, _property$annotations6, _property$annotations9, _property$annotations10, _targetMapping$constr6, _targetMapping$constr7;
|
|
1168
|
-
const constraints = {};
|
|
1169
|
-
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr = targetMapping.constraints) !== null && _targetMapping$constr !== void 0 && _targetMapping$constr.$Scale && property.scale !== undefined) {
|
|
1170
|
-
constraints.scale = property.scale;
|
|
1171
|
-
}
|
|
1172
|
-
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr2 = targetMapping.constraints) !== null && _targetMapping$constr2 !== void 0 && _targetMapping$constr2.$Precision && property.precision !== undefined) {
|
|
1173
|
-
constraints.precision = property.precision;
|
|
1174
|
-
}
|
|
1175
|
-
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr3 = targetMapping.constraints) !== null && _targetMapping$constr3 !== void 0 && _targetMapping$constr3.$MaxLength && property.maxLength !== undefined) {
|
|
1176
|
-
constraints.maxLength = property.maxLength;
|
|
1177
|
-
}
|
|
1178
|
-
if (property.nullable === false) {
|
|
1179
|
-
constraints.nullable = false;
|
|
1180
|
-
}
|
|
1181
|
-
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr4 = targetMapping.constraints) !== null && _targetMapping$constr4 !== void 0 && _targetMapping$constr4["@Org.OData.Validation.V1.Minimum/$Decimal"] && !isNaN((_property$annotations = property.annotations) === null || _property$annotations === void 0 ? void 0 : (_property$annotations2 = _property$annotations.Validation) === null || _property$annotations2 === void 0 ? void 0 : _property$annotations2.Minimum)) {
|
|
1182
|
-
var _property$annotations3, _property$annotations4;
|
|
1183
|
-
constraints.minimum = `${(_property$annotations3 = property.annotations) === null || _property$annotations3 === void 0 ? void 0 : (_property$annotations4 = _property$annotations3.Validation) === null || _property$annotations4 === void 0 ? void 0 : _property$annotations4.Minimum}`;
|
|
1184
|
-
}
|
|
1185
|
-
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr5 = targetMapping.constraints) !== null && _targetMapping$constr5 !== void 0 && _targetMapping$constr5["@Org.OData.Validation.V1.Maximum/$Decimal"] && !isNaN((_property$annotations5 = property.annotations) === null || _property$annotations5 === void 0 ? void 0 : (_property$annotations6 = _property$annotations5.Validation) === null || _property$annotations6 === void 0 ? void 0 : _property$annotations6.Maximum)) {
|
|
1186
|
-
var _property$annotations7, _property$annotations8;
|
|
1187
|
-
constraints.maximum = `${(_property$annotations7 = property.annotations) === null || _property$annotations7 === void 0 ? void 0 : (_property$annotations8 = _property$annotations7.Validation) === null || _property$annotations8 === void 0 ? void 0 : _property$annotations8.Maximum}`;
|
|
1188
|
-
}
|
|
1189
|
-
if ((_property$annotations9 = property.annotations) !== null && _property$annotations9 !== void 0 && (_property$annotations10 = _property$annotations9.Common) !== null && _property$annotations10 !== void 0 && _property$annotations10.IsDigitSequence && targetMapping.type === "sap.ui.model.odata.type.String" && targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr6 = targetMapping.constraints) !== null && _targetMapping$constr6 !== void 0 && _targetMapping$constr6["@com.sap.vocabularies.Common.v1.IsDigitSequence"]) {
|
|
1190
|
-
constraints.isDigitSequence = true;
|
|
1191
|
-
}
|
|
1192
|
-
if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr7 = targetMapping.constraints) !== null && _targetMapping$constr7 !== void 0 && _targetMapping$constr7.$V4) {
|
|
1193
|
-
constraints.V4 = true;
|
|
1194
|
-
}
|
|
1195
|
-
return constraints;
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
/**
|
|
1199
|
-
* Generates the binding expression for the property, and sets up the formatOptions and constraints.
|
|
1200
|
-
*
|
|
1201
|
-
* @param property The Property for which we are setting up the binding
|
|
1202
|
-
* @param propertyBindingExpression The BindingExpression of the property above. Serves as the basis to which information can be added
|
|
1203
|
-
* @param ignoreConstraints Ignore constraints of the property
|
|
1204
|
-
* @returns The binding expression for the property with formatOptions and constraints
|
|
1205
|
-
*/
|
|
1206
|
-
_exports.setUpConstraints = setUpConstraints;
|
|
1207
|
-
function formatWithTypeInformation(property, propertyBindingExpression) {
|
|
1208
|
-
var _outExpression$type, _outExpression$constr3, _outExpression$constr4;
|
|
1209
|
-
let ignoreConstraints = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1210
|
-
const outExpression = propertyBindingExpression;
|
|
1211
|
-
if (property._type !== "Property" && property._type !== "ActionParameter") {
|
|
1212
|
-
return outExpression;
|
|
1213
|
-
}
|
|
1214
|
-
const targetMapping = EDM_TYPE_MAPPING[property.type];
|
|
1215
|
-
if (!targetMapping) {
|
|
1216
|
-
return outExpression;
|
|
1217
|
-
}
|
|
1218
|
-
if (!outExpression.formatOptions) {
|
|
1219
|
-
outExpression.formatOptions = {};
|
|
1220
|
-
}
|
|
1221
|
-
outExpression.constraints = {};
|
|
1222
|
-
outExpression.type = targetMapping.type;
|
|
1223
|
-
if (!ignoreConstraints) {
|
|
1224
|
-
outExpression.constraints = setUpConstraints(targetMapping, property);
|
|
1225
|
-
}
|
|
1226
|
-
if ((outExpression === null || outExpression === void 0 ? void 0 : (_outExpression$type = outExpression.type) === null || _outExpression$type === void 0 ? void 0 : _outExpression$type.indexOf("sap.ui.model.odata.type.Int")) === 0 && (outExpression === null || outExpression === void 0 ? void 0 : outExpression.type) !== "sap.ui.model.odata.type.Int64" || (outExpression === null || outExpression === void 0 ? void 0 : outExpression.type) === "sap.ui.model.odata.type.Double") {
|
|
1227
|
-
outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
|
|
1228
|
-
parseAsString: false
|
|
1229
|
-
});
|
|
1230
|
-
}
|
|
1231
|
-
if (outExpression.type === "sap.ui.model.odata.type.String" && isProperty(property)) {
|
|
1232
|
-
var _outExpression$constr, _outExpression$constr2;
|
|
1233
|
-
if (!((_outExpression$constr = outExpression.constraints) !== null && _outExpression$constr !== void 0 && _outExpression$constr.isDigitSequence) || ((_outExpression$constr2 = outExpression.constraints) === null || _outExpression$constr2 === void 0 ? void 0 : _outExpression$constr2.nullable) === false) {
|
|
1234
|
-
outExpression.formatOptions.parseKeepsEmptyString = true;
|
|
1235
|
-
}
|
|
1236
|
-
const fiscalType = getFiscalType(property);
|
|
1237
|
-
if (fiscalType) {
|
|
1238
|
-
outExpression.formatOptions.fiscalType = fiscalType;
|
|
1239
|
-
outExpression.type = "sap.fe.core.type.FiscalDate";
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
const typesSupportingParseEmptyValueToZero = ["sap.ui.model.odata.type.Int16", "sap.ui.model.odata.type.Int32", "sap.ui.model.odata.type.Int64", "sap.ui.model.odata.type.Single", "sap.ui.model.odata.type.Double", "sap.ui.model.odata.type.Decimal", "sap.ui.model.odata.type.Byte", "sap.ui.model.odata.type.SByte"];
|
|
1243
|
-
if (((_outExpression$constr3 = outExpression.constraints) === null || _outExpression$constr3 === void 0 ? void 0 : _outExpression$constr3.nullable) === false && outExpression.type && typesSupportingParseEmptyValueToZero.includes(outExpression.type)) {
|
|
1244
|
-
outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
|
|
1245
|
-
parseEmptyValueToZero: true
|
|
1246
|
-
});
|
|
1247
|
-
}
|
|
1248
|
-
if (((_outExpression$constr4 = outExpression.constraints) === null || _outExpression$constr4 === void 0 ? void 0 : _outExpression$constr4.nullable) !== false && (outExpression.type === "sap.ui.model.odata.type.Int64" || outExpression.type === "sap.ui.model.odata.type.Decimal")) {
|
|
1249
|
-
outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
|
|
1250
|
-
emptyString: ""
|
|
1251
|
-
});
|
|
1252
|
-
}
|
|
1253
|
-
return outExpression;
|
|
1254
|
-
}
|
|
1255
|
-
_exports.formatWithTypeInformation = formatWithTypeInformation;
|
|
1256
|
-
const getFiscalType = function (property) {
|
|
1257
|
-
var _property$annotations11, _property$annotations12, _property$annotations13, _property$annotations14, _property$annotations15, _property$annotations16, _property$annotations17, _property$annotations18, _property$annotations19, _property$annotations20, _property$annotations21, _property$annotations22, _property$annotations23, _property$annotations24, _property$annotations25, _property$annotations26;
|
|
1258
|
-
if ((_property$annotations11 = property.annotations) !== null && _property$annotations11 !== void 0 && (_property$annotations12 = _property$annotations11.Common) !== null && _property$annotations12 !== void 0 && _property$annotations12.IsFiscalYear) {
|
|
1259
|
-
return "com.sap.vocabularies.Common.v1.IsFiscalYear";
|
|
1260
|
-
}
|
|
1261
|
-
if ((_property$annotations13 = property.annotations) !== null && _property$annotations13 !== void 0 && (_property$annotations14 = _property$annotations13.Common) !== null && _property$annotations14 !== void 0 && _property$annotations14.IsFiscalPeriod) {
|
|
1262
|
-
return "com.sap.vocabularies.Common.v1.IsFiscalPeriod";
|
|
1263
|
-
}
|
|
1264
|
-
if ((_property$annotations15 = property.annotations) !== null && _property$annotations15 !== void 0 && (_property$annotations16 = _property$annotations15.Common) !== null && _property$annotations16 !== void 0 && _property$annotations16.IsFiscalYearPeriod) {
|
|
1265
|
-
return "com.sap.vocabularies.Common.v1.IsFiscalYearPeriod";
|
|
1266
|
-
}
|
|
1267
|
-
if ((_property$annotations17 = property.annotations) !== null && _property$annotations17 !== void 0 && (_property$annotations18 = _property$annotations17.Common) !== null && _property$annotations18 !== void 0 && _property$annotations18.IsFiscalQuarter) {
|
|
1268
|
-
return "com.sap.vocabularies.Common.v1.IsFiscalQuarter";
|
|
1269
|
-
}
|
|
1270
|
-
if ((_property$annotations19 = property.annotations) !== null && _property$annotations19 !== void 0 && (_property$annotations20 = _property$annotations19.Common) !== null && _property$annotations20 !== void 0 && _property$annotations20.IsFiscalYearQuarter) {
|
|
1271
|
-
return "com.sap.vocabularies.Common.v1.IsFiscalYearQuarter";
|
|
1272
|
-
}
|
|
1273
|
-
if ((_property$annotations21 = property.annotations) !== null && _property$annotations21 !== void 0 && (_property$annotations22 = _property$annotations21.Common) !== null && _property$annotations22 !== void 0 && _property$annotations22.IsFiscalWeek) {
|
|
1274
|
-
return "com.sap.vocabularies.Common.v1.IsFiscalWeek";
|
|
1275
|
-
}
|
|
1276
|
-
if ((_property$annotations23 = property.annotations) !== null && _property$annotations23 !== void 0 && (_property$annotations24 = _property$annotations23.Common) !== null && _property$annotations24 !== void 0 && _property$annotations24.IsFiscalYearWeek) {
|
|
1277
|
-
return "com.sap.vocabularies.Common.v1.IsFiscalYearWeek";
|
|
1278
|
-
}
|
|
1279
|
-
if ((_property$annotations25 = property.annotations) !== null && _property$annotations25 !== void 0 && (_property$annotations26 = _property$annotations25.Common) !== null && _property$annotations26 !== void 0 && _property$annotations26.IsDayOfFiscalYear) {
|
|
1280
|
-
return "com.sap.vocabularies.Common.v1.IsDayOfFiscalYear";
|
|
1281
|
-
}
|
|
1282
|
-
};
|
|
1283
|
-
|
|
1284
|
-
/**
|
|
1285
|
-
* Calls a complex type to process the parameters.
|
|
1286
|
-
* If requireContext is set to true and no context is passed, a default context will be added automatically.
|
|
1287
|
-
*
|
|
1288
|
-
* @template T
|
|
1289
|
-
* @template U
|
|
1290
|
-
* @param parameters The list of parameters that should match the type for the complex type=
|
|
1291
|
-
* @param type The complex type to use
|
|
1292
|
-
* @param [contextEntityType] The context entity type to consider
|
|
1293
|
-
* @param oFormatOptions
|
|
1294
|
-
* @returns The corresponding expression
|
|
1295
|
-
*/
|
|
1296
|
-
_exports.getFiscalType = getFiscalType;
|
|
1297
|
-
function addTypeInformation(parameters, type, contextEntityType, oFormatOptions) {
|
|
1298
|
-
const parameterExpressions = parameters.map(wrapPrimitive);
|
|
1299
|
-
if (hasUnresolvableExpression(...parameterExpressions)) {
|
|
1300
|
-
return unresolvableExpression;
|
|
1301
|
-
}
|
|
1302
|
-
// If there is only one parameter and it is a constant and we don't expect the context then return the constant
|
|
1303
|
-
if (parameterExpressions.length === 1 && isConstant(parameterExpressions[0]) && !contextEntityType) {
|
|
1304
|
-
return parameterExpressions[0];
|
|
1305
|
-
} else if (contextEntityType) {
|
|
1306
|
-
// Otherwise, if the context is required and no context is provided make sure to add the default binding
|
|
1307
|
-
if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
|
|
1308
|
-
contextEntityType.keys.forEach(key => parameterExpressions.push(pathInModel(key.name, "")));
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
oFormatOptions = _getComplexTypeFormatOptionsFromFirstParam(parameters[0], oFormatOptions);
|
|
1312
|
-
if (type === "sap.ui.model.odata.type.Unit") {
|
|
1313
|
-
const uomPath = pathInModel("/##@@requestUnitsOfMeasure");
|
|
1314
|
-
uomPath.targetType = "any";
|
|
1315
|
-
uomPath.mode = "OneTime";
|
|
1316
|
-
parameterExpressions.push(uomPath);
|
|
1317
|
-
} else if (type === "sap.ui.model.odata.type.Currency") {
|
|
1318
|
-
const currencyPath = pathInModel("/##@@requestCurrencyCodes");
|
|
1319
|
-
currencyPath.targetType = "any";
|
|
1320
|
-
currencyPath.mode = "OneTime";
|
|
1321
|
-
parameterExpressions.push(currencyPath);
|
|
1322
|
-
}
|
|
1323
|
-
return {
|
|
1324
|
-
_type: "ComplexType",
|
|
1325
|
-
type: type,
|
|
1326
|
-
formatOptions: oFormatOptions || {},
|
|
1327
|
-
parameters: {},
|
|
1328
|
-
bindingParameters: parameterExpressions
|
|
1329
|
-
};
|
|
1330
|
-
}
|
|
1331
|
-
_exports.addTypeInformation = addTypeInformation;
|
|
1332
|
-
/**
|
|
1333
|
-
* Process the formatOptions for a complexType based on the first parameter.
|
|
1334
|
-
*
|
|
1335
|
-
* @param param The first parameter of the complex type
|
|
1336
|
-
* @param formatOptions Initial formatOptions
|
|
1337
|
-
* @returns The modified formatOptions
|
|
1338
|
-
*/
|
|
1339
|
-
function _getComplexTypeFormatOptionsFromFirstParam(param, formatOptions) {
|
|
1340
|
-
var _param$type;
|
|
1341
|
-
// if showMeasure is set to false we want to not parse as string to see the 0
|
|
1342
|
-
// we do that also for all bindings because otherwise the mdc Field isn't editable
|
|
1343
|
-
if (!(formatOptions && formatOptions.showNumber === false) && ((param === null || param === void 0 ? void 0 : (_param$type = param.type) === null || _param$type === void 0 ? void 0 : _param$type.indexOf("sap.ui.model.odata.type.Int")) === 0 || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Decimal" || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Double")) {
|
|
1344
|
-
if ((param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Int64" || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Decimal") {
|
|
1345
|
-
var _formatOptions;
|
|
1346
|
-
//sap.ui.model.odata.type.Int64 do not support parseAsString false
|
|
1347
|
-
formatOptions = ((_formatOptions = formatOptions) === null || _formatOptions === void 0 ? void 0 : _formatOptions.showMeasure) === false ? {
|
|
1348
|
-
showMeasure: false
|
|
1349
|
-
} : {};
|
|
1350
|
-
} else {
|
|
1351
|
-
var _formatOptions2;
|
|
1352
|
-
formatOptions = ((_formatOptions2 = formatOptions) === null || _formatOptions2 === void 0 ? void 0 : _formatOptions2.showMeasure) === false ? {
|
|
1353
|
-
parseAsString: false,
|
|
1354
|
-
showMeasure: false
|
|
1355
|
-
} : {
|
|
1356
|
-
parseAsString: false
|
|
1357
|
-
};
|
|
1358
|
-
}
|
|
1359
|
-
formatOptions.emptyString = null;
|
|
1360
|
-
}
|
|
1361
|
-
return formatOptions;
|
|
1362
|
-
}
|
|
1363
|
-
/**
|
|
1364
|
-
* Function call, optionally with arguments.
|
|
1365
|
-
*
|
|
1366
|
-
* @param func Function name or reference to function
|
|
1367
|
-
* @param parameters Arguments
|
|
1368
|
-
* @param on Object to call the function on
|
|
1369
|
-
* @param isFormattingFn
|
|
1370
|
-
* @returns Expression representing the function call (not the result of the function call!)
|
|
1371
|
-
*/
|
|
1372
|
-
function fn(func, parameters, on) {
|
|
1373
|
-
let isFormattingFn = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1374
|
-
const functionName = typeof func === "string" ? func : func.__functionName;
|
|
1375
|
-
return {
|
|
1376
|
-
_type: "Function",
|
|
1377
|
-
obj: on !== undefined ? wrapPrimitive(on) : undefined,
|
|
1378
|
-
fn: functionName,
|
|
1379
|
-
isFormattingFn: isFormattingFn,
|
|
1380
|
-
parameters: parameters.map(wrapPrimitive)
|
|
1381
|
-
};
|
|
1382
|
-
}
|
|
1383
|
-
|
|
1384
|
-
/**
|
|
1385
|
-
* Shortcut function to determine if a binding value is null, undefined or empty.
|
|
1386
|
-
*
|
|
1387
|
-
* @param expression
|
|
1388
|
-
* @returns A Boolean expression evaluating the fact that the current element is empty
|
|
1389
|
-
*/
|
|
1390
|
-
_exports.fn = fn;
|
|
1391
|
-
function isEmpty(expression) {
|
|
1392
|
-
const aBindings = [];
|
|
1393
|
-
transformRecursively(expression, "PathInModel", expr => {
|
|
1394
|
-
aBindings.push(or(equal(expr, ""), equal(expr, undefined), equal(expr, null)));
|
|
1395
|
-
return expr;
|
|
1396
|
-
});
|
|
1397
|
-
return and(...aBindings);
|
|
1398
|
-
}
|
|
1399
|
-
_exports.isEmpty = isEmpty;
|
|
1400
|
-
function concat() {
|
|
1401
|
-
for (var _len4 = arguments.length, inExpressions = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
1402
|
-
inExpressions[_key4] = arguments[_key4];
|
|
1403
|
-
}
|
|
1404
|
-
const expressions = inExpressions.map(wrapPrimitive);
|
|
1405
|
-
if (hasUnresolvableExpression(...expressions)) {
|
|
1406
|
-
return unresolvableExpression;
|
|
1407
|
-
}
|
|
1408
|
-
if (expressions.every(isConstant)) {
|
|
1409
|
-
return constant(expressions.reduce((concatenated, value) => {
|
|
1410
|
-
if (value.value !== undefined && value.value !== null) {
|
|
1411
|
-
return concatenated + value.value.toString();
|
|
1412
|
-
}
|
|
1413
|
-
return concatenated;
|
|
1414
|
-
}, ""));
|
|
1415
|
-
} else if (expressions.some(isComplexTypeExpression)) {
|
|
1416
|
-
let pathIdx = 0;
|
|
1417
|
-
const myConcatExpression = formatResult(expressions, "sap.fe.core.formatters.StandardFormatter#concat", undefined, true);
|
|
1418
|
-
const allParts = [];
|
|
1419
|
-
transformRecursively(myConcatExpression, "PathInModel", constantPath => {
|
|
1420
|
-
allParts.push(constantPath);
|
|
1421
|
-
return pathInModel(`$${pathIdx++}`, "$");
|
|
1422
|
-
});
|
|
1423
|
-
allParts.unshift(constant(JSON.stringify(myConcatExpression)));
|
|
1424
|
-
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
|
|
1425
|
-
}
|
|
1426
|
-
return {
|
|
1427
|
-
_type: "Concat",
|
|
1428
|
-
expressions: expressions
|
|
1429
|
-
};
|
|
1430
|
-
}
|
|
1431
|
-
_exports.concat = concat;
|
|
1432
|
-
function transformRecursively(inExpression, expressionType, transformFunction) {
|
|
1433
|
-
let includeAllExpression = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1434
|
-
let expression = inExpression;
|
|
1435
|
-
switch (expression._type) {
|
|
1436
|
-
case "Function":
|
|
1437
|
-
case "Formatter":
|
|
1438
|
-
expression.parameters = expression.parameters.map(parameter => transformRecursively(parameter, expressionType, transformFunction, includeAllExpression));
|
|
1439
|
-
break;
|
|
1440
|
-
case "Concat":
|
|
1441
|
-
expression.expressions = expression.expressions.map(subExpression => transformRecursively(subExpression, expressionType, transformFunction, includeAllExpression));
|
|
1442
|
-
expression = concat(...expression.expressions);
|
|
1443
|
-
break;
|
|
1444
|
-
case "ComplexType":
|
|
1445
|
-
expression.bindingParameters = expression.bindingParameters.map(bindingParameter => transformRecursively(bindingParameter, expressionType, transformFunction, includeAllExpression));
|
|
1446
|
-
break;
|
|
1447
|
-
case "IfElse":
|
|
1448
|
-
const onTrue = transformRecursively(expression.onTrue, expressionType, transformFunction, includeAllExpression);
|
|
1449
|
-
const onFalse = transformRecursively(expression.onFalse, expressionType, transformFunction, includeAllExpression);
|
|
1450
|
-
let condition = expression.condition;
|
|
1451
|
-
if (includeAllExpression) {
|
|
1452
|
-
condition = transformRecursively(expression.condition, expressionType, transformFunction, includeAllExpression);
|
|
1453
|
-
}
|
|
1454
|
-
expression = ifElse(condition, onTrue, onFalse);
|
|
1455
|
-
break;
|
|
1456
|
-
case "Not":
|
|
1457
|
-
if (includeAllExpression) {
|
|
1458
|
-
const operand = transformRecursively(expression.operand, expressionType, transformFunction, includeAllExpression);
|
|
1459
|
-
expression = not(operand);
|
|
1460
|
-
}
|
|
1461
|
-
break;
|
|
1462
|
-
case "Truthy":
|
|
1463
|
-
break;
|
|
1464
|
-
case "Set":
|
|
1465
|
-
if (includeAllExpression) {
|
|
1466
|
-
const operands = expression.operands.map(operand => transformRecursively(operand, expressionType, transformFunction, includeAllExpression));
|
|
1467
|
-
expression = expression.operator === "||" ? or(...operands) : and(...operands);
|
|
1468
|
-
}
|
|
1469
|
-
break;
|
|
1470
|
-
case "Comparison":
|
|
1471
|
-
if (includeAllExpression) {
|
|
1472
|
-
const operand1 = transformRecursively(expression.operand1, expressionType, transformFunction, includeAllExpression);
|
|
1473
|
-
const operand2 = transformRecursively(expression.operand2, expressionType, transformFunction, includeAllExpression);
|
|
1474
|
-
expression = comparison(expression.operator, operand1, operand2);
|
|
1475
|
-
}
|
|
1476
|
-
break;
|
|
1477
|
-
case "Constant":
|
|
1478
|
-
const constantValue = expression.value;
|
|
1479
|
-
if (typeof constantValue === "object" && constantValue) {
|
|
1480
|
-
Object.keys(constantValue).forEach(key => {
|
|
1481
|
-
constantValue[key] = transformRecursively(constantValue[key], expressionType, transformFunction, includeAllExpression);
|
|
1482
|
-
});
|
|
1483
|
-
}
|
|
1484
|
-
break;
|
|
1485
|
-
case "Ref":
|
|
1486
|
-
case "Length":
|
|
1487
|
-
case "PathInModel":
|
|
1488
|
-
case "EmbeddedBinding":
|
|
1489
|
-
case "EmbeddedExpressionBinding":
|
|
1490
|
-
case "Unresolvable":
|
|
1491
|
-
// Do nothing
|
|
1492
|
-
break;
|
|
1493
|
-
}
|
|
1494
|
-
if (expressionType === expression._type) {
|
|
1495
|
-
expression = transformFunction(inExpression);
|
|
1496
|
-
}
|
|
1497
|
-
return expression;
|
|
1498
|
-
}
|
|
1499
|
-
_exports.transformRecursively = transformRecursively;
|
|
1500
|
-
const needParenthesis = function (expr) {
|
|
1501
|
-
return !isConstant(expr) && !isPathInModelExpression(expr) && isBindingToolkitExpression(expr) && expr._type !== "IfElse" && expr._type !== "Function";
|
|
1502
|
-
};
|
|
1503
|
-
|
|
1504
|
-
/**
|
|
1505
|
-
* Compiles a constant object to a string.
|
|
1506
|
-
*
|
|
1507
|
-
* @param expr
|
|
1508
|
-
* @param isNullable
|
|
1509
|
-
* @returns The compiled string
|
|
1510
|
-
*/
|
|
1511
|
-
function compileConstantObject(expr) {
|
|
1512
|
-
let isNullable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1513
|
-
if (isNullable && Object.keys(expr.value).length === 0) {
|
|
1514
|
-
return "";
|
|
1515
|
-
}
|
|
1516
|
-
const objects = expr.value;
|
|
1517
|
-
const properties = [];
|
|
1518
|
-
Object.keys(objects).forEach(key => {
|
|
1519
|
-
const value = objects[key];
|
|
1520
|
-
const childResult = compileExpression(value, true, false, isNullable);
|
|
1521
|
-
if (childResult && childResult.length > 0) {
|
|
1522
|
-
properties.push(`${key}: ${childResult}`);
|
|
1523
|
-
}
|
|
1524
|
-
});
|
|
1525
|
-
return `{${properties.join(", ")}}`;
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
/**
|
|
1529
|
-
* Compiles a Constant Binding Expression.
|
|
1530
|
-
*
|
|
1531
|
-
* @param expr
|
|
1532
|
-
* @param embeddedInBinding
|
|
1533
|
-
* @param isNullable
|
|
1534
|
-
* @param doNotStringify
|
|
1535
|
-
* @returns The compiled string
|
|
1536
|
-
*/
|
|
1537
|
-
|
|
1538
|
-
function compileConstant(expr, embeddedInBinding) {
|
|
1539
|
-
let isNullable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1540
|
-
let doNotStringify = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1541
|
-
if (expr.value === null) {
|
|
1542
|
-
return doNotStringify ? null : "null";
|
|
1543
|
-
}
|
|
1544
|
-
if (expr.value === undefined) {
|
|
1545
|
-
return doNotStringify ? undefined : "undefined";
|
|
1546
|
-
}
|
|
1547
|
-
if (typeof expr.value === "object") {
|
|
1548
|
-
if (Array.isArray(expr.value)) {
|
|
1549
|
-
const entries = expr.value.map(expression => compileExpression(expression, true));
|
|
1550
|
-
return `[${entries.join(", ")}]`;
|
|
1551
|
-
} else {
|
|
1552
|
-
return compileConstantObject(expr, isNullable);
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
if (embeddedInBinding) {
|
|
1556
|
-
switch (typeof expr.value) {
|
|
1557
|
-
case "number":
|
|
1558
|
-
case "bigint":
|
|
1559
|
-
case "boolean":
|
|
1560
|
-
return expr.value.toString();
|
|
1561
|
-
case "string":
|
|
1562
|
-
return `'${escapeXmlAttribute(expr.value.toString())}'`;
|
|
1563
|
-
default:
|
|
1564
|
-
return "";
|
|
1565
|
-
}
|
|
1566
|
-
} else {
|
|
1567
|
-
return doNotStringify ? expr.value : expr.value.toString();
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
|
|
1571
|
-
/**
|
|
1572
|
-
* Generates the binding string for a Binding expression.
|
|
1573
|
-
*
|
|
1574
|
-
* @param expressionForBinding The expression to compile
|
|
1575
|
-
* @param embeddedInBinding Whether the expression to compile is embedded into another expression
|
|
1576
|
-
* @param embeddedSeparator The binding value evaluator ($ or % depending on whether we want to force the type or not)
|
|
1577
|
-
* @returns The corresponding expression binding
|
|
1578
|
-
*/
|
|
1579
|
-
_exports.compileConstant = compileConstant;
|
|
1580
|
-
function compilePathInModelExpression(expressionForBinding, embeddedInBinding, embeddedSeparator) {
|
|
1581
|
-
if (expressionForBinding.type || expressionForBinding.parameters || expressionForBinding.targetType || expressionForBinding.formatOptions || expressionForBinding.constraints) {
|
|
1582
|
-
// This is now a complex binding definition, let's prepare for it
|
|
1583
|
-
const complexBindingDefinition = {
|
|
1584
|
-
path: compilePathInModel(expressionForBinding),
|
|
1585
|
-
type: expressionForBinding.type,
|
|
1586
|
-
targetType: expressionForBinding.targetType,
|
|
1587
|
-
parameters: expressionForBinding.parameters,
|
|
1588
|
-
formatOptions: expressionForBinding.formatOptions,
|
|
1589
|
-
constraints: expressionForBinding.constraints
|
|
1590
|
-
};
|
|
1591
|
-
const outBinding = compileExpression(complexBindingDefinition, false, false, true);
|
|
1592
|
-
if (embeddedInBinding) {
|
|
1593
|
-
return `${embeddedSeparator}${outBinding}`;
|
|
1594
|
-
}
|
|
1595
|
-
return outBinding;
|
|
1596
|
-
} else if (embeddedInBinding) {
|
|
1597
|
-
return `${embeddedSeparator}{${compilePathInModel(expressionForBinding)}}`;
|
|
1598
|
-
} else {
|
|
1599
|
-
return `{${compilePathInModel(expressionForBinding)}}`;
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
function compileComplexTypeExpression(expression) {
|
|
1603
|
-
if (expression.bindingParameters.length === 1) {
|
|
1604
|
-
return `{${compilePathParameter(expression.bindingParameters[0], true)}, type: '${expression.type}'}`;
|
|
1605
|
-
}
|
|
1606
|
-
let outputEnd = `], type: '${expression.type}'`;
|
|
1607
|
-
if (hasElements(expression.formatOptions)) {
|
|
1608
|
-
outputEnd += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
|
|
1609
|
-
}
|
|
1610
|
-
if (hasElements(expression.parameters)) {
|
|
1611
|
-
outputEnd += `, parameters: ${compileExpression(expression.parameters)}`;
|
|
1612
|
-
}
|
|
1613
|
-
outputEnd += "}";
|
|
1614
|
-
return `{mode:'TwoWay', parts:[${expression.bindingParameters.map(param => compilePathParameter(param)).join(",")}${outputEnd}`;
|
|
1615
|
-
}
|
|
1616
|
-
|
|
1617
|
-
/**
|
|
1618
|
-
* Wrap the compiled binding string as required depending on its context.
|
|
1619
|
-
*
|
|
1620
|
-
* @param expression The compiled expression
|
|
1621
|
-
* @param embeddedInBinding True if the compiled expression is to be embedded in a binding
|
|
1622
|
-
* @param parenthesisRequired True if the embedded binding needs to be wrapped in parethesis so that it is evaluated as one
|
|
1623
|
-
* @returns Finalized compiled expression
|
|
1624
|
-
*/
|
|
1625
|
-
function wrapBindingExpression(expression, embeddedInBinding) {
|
|
1626
|
-
let parenthesisRequired = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1627
|
-
if (embeddedInBinding) {
|
|
1628
|
-
if (parenthesisRequired) {
|
|
1629
|
-
return `(${expression})`;
|
|
1630
|
-
} else {
|
|
1631
|
-
return expression;
|
|
1632
|
-
}
|
|
1633
|
-
} else {
|
|
1634
|
-
return `{= ${expression}}`;
|
|
1635
|
-
}
|
|
1636
|
-
}
|
|
1637
|
-
|
|
1638
|
-
/**
|
|
1639
|
-
* Compile an expression into an expression binding.
|
|
1640
|
-
*
|
|
1641
|
-
* @template T The target type
|
|
1642
|
-
* @param expression The expression to compile
|
|
1643
|
-
* @param embeddedInBinding Whether the expression to compile is embedded into another expression
|
|
1644
|
-
* @param keepTargetType Keep the target type of the embedded bindings instead of casting them to any
|
|
1645
|
-
* @param isNullable Whether binding expression can resolve to empty string or not
|
|
1646
|
-
* @returns The corresponding expression binding
|
|
1647
|
-
*/
|
|
1648
|
-
_exports.wrapBindingExpression = wrapBindingExpression;
|
|
1649
|
-
function compileExpression(expression) {
|
|
1650
|
-
let embeddedInBinding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1651
|
-
let keepTargetType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1652
|
-
let isNullable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1653
|
-
const expr = wrapPrimitive(expression);
|
|
1654
|
-
const embeddedSeparator = keepTargetType ? "$" : "%";
|
|
1655
|
-
switch (expr._type) {
|
|
1656
|
-
case "Unresolvable":
|
|
1657
|
-
return undefined;
|
|
1658
|
-
case "Constant":
|
|
1659
|
-
return compileConstant(expr, embeddedInBinding, isNullable);
|
|
1660
|
-
case "Ref":
|
|
1661
|
-
return expr.ref || "null";
|
|
1662
|
-
case "Function":
|
|
1663
|
-
let hasEmbeddedFunctionCallOrBinding = false;
|
|
1664
|
-
if (expr.isFormattingFn) {
|
|
1665
|
-
transformRecursively(expr, "Function", subFn => {
|
|
1666
|
-
if (subFn !== expr && subFn.obj === undefined) {
|
|
1667
|
-
hasEmbeddedFunctionCallOrBinding = true;
|
|
1668
|
-
}
|
|
1669
|
-
return subFn;
|
|
1670
|
-
}, true);
|
|
1671
|
-
transformRecursively(expr, "Constant", subFn => {
|
|
1672
|
-
if (subFn !== expr && typeof subFn.value === "object") {
|
|
1673
|
-
transformRecursively(subFn, "PathInModel", subSubFn => {
|
|
1674
|
-
hasEmbeddedFunctionCallOrBinding = true;
|
|
1675
|
-
return subSubFn;
|
|
1676
|
-
});
|
|
1677
|
-
}
|
|
1678
|
-
return subFn;
|
|
1679
|
-
}, true);
|
|
1680
|
-
}
|
|
1681
|
-
const argumentString = `${expr.parameters.map(arg => compileExpression(arg, true)).join(", ")}`;
|
|
1682
|
-
let fnCall = expr.obj === undefined ? `${expr.fn}(${argumentString})` : `${compileExpression(expr.obj, true)}.${expr.fn}(${argumentString})`;
|
|
1683
|
-
if (!embeddedInBinding && hasEmbeddedFunctionCallOrBinding) {
|
|
1684
|
-
fnCall = `{= ${fnCall}}`;
|
|
1685
|
-
}
|
|
1686
|
-
return fnCall;
|
|
1687
|
-
case "EmbeddedExpressionBinding":
|
|
1688
|
-
return embeddedInBinding ? `(${expr.value.substring(2, expr.value.length - 1)})` : `${expr.value}`;
|
|
1689
|
-
case "EmbeddedBinding":
|
|
1690
|
-
return embeddedInBinding ? `${embeddedSeparator}${expr.value}` : `${expr.value}`;
|
|
1691
|
-
case "PathInModel":
|
|
1692
|
-
return compilePathInModelExpression(expr, embeddedInBinding, embeddedSeparator);
|
|
1693
|
-
case "Comparison":
|
|
1694
|
-
const comparisonExpression = compileComparisonExpression(expr);
|
|
1695
|
-
return wrapBindingExpression(comparisonExpression, embeddedInBinding);
|
|
1696
|
-
case "IfElse":
|
|
1697
|
-
const ifElseExpression = `${compileExpression(expr.condition, true)} ? ${compileExpression(expr.onTrue, true, keepTargetType)} : ${compileExpression(expr.onFalse, true, keepTargetType)}`;
|
|
1698
|
-
return wrapBindingExpression(ifElseExpression, embeddedInBinding, true);
|
|
1699
|
-
case "Set":
|
|
1700
|
-
const setExpression = expr.operands.map(operand => compileExpression(operand, true)).join(` ${expr.operator} `);
|
|
1701
|
-
return wrapBindingExpression(setExpression, embeddedInBinding, true);
|
|
1702
|
-
case "Concat":
|
|
1703
|
-
const concatExpression = expr.expressions.map(nestedExpression => compileExpression(nestedExpression, true, true)).join(" + ");
|
|
1704
|
-
return wrapBindingExpression(concatExpression, embeddedInBinding);
|
|
1705
|
-
case "Length":
|
|
1706
|
-
const lengthExpression = `${compileExpression(expr.pathInModel, true)}.length`;
|
|
1707
|
-
return wrapBindingExpression(lengthExpression, embeddedInBinding);
|
|
1708
|
-
case "Not":
|
|
1709
|
-
const notExpression = `!${compileExpression(expr.operand, true)}`;
|
|
1710
|
-
return wrapBindingExpression(notExpression, embeddedInBinding);
|
|
1711
|
-
case "Truthy":
|
|
1712
|
-
const truthyExpression = `!!${compileExpression(expr.operand, true)}`;
|
|
1713
|
-
return wrapBindingExpression(truthyExpression, embeddedInBinding);
|
|
1714
|
-
case "Formatter":
|
|
1715
|
-
const formatterExpression = compileFormatterExpression(expr);
|
|
1716
|
-
return embeddedInBinding ? `$${formatterExpression}` : formatterExpression;
|
|
1717
|
-
case "ComplexType":
|
|
1718
|
-
const complexTypeExpression = compileComplexTypeExpression(expr);
|
|
1719
|
-
return embeddedInBinding ? `$${complexTypeExpression}` : complexTypeExpression;
|
|
1720
|
-
default:
|
|
1721
|
-
return "";
|
|
1722
|
-
}
|
|
1723
|
-
}
|
|
1724
|
-
|
|
1725
|
-
/**
|
|
1726
|
-
* Compile a comparison expression.
|
|
1727
|
-
*
|
|
1728
|
-
* @param expression The comparison expression.
|
|
1729
|
-
* @returns The compiled expression. Needs wrapping before it can be used as an expression binding.
|
|
1730
|
-
*/
|
|
1731
|
-
_exports.compileExpression = compileExpression;
|
|
1732
|
-
function compileComparisonExpression(expression) {
|
|
1733
|
-
function compileOperand(operand) {
|
|
1734
|
-
const compiledOperand = compileExpression(operand, true) ?? "undefined";
|
|
1735
|
-
return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
|
|
1736
|
-
}
|
|
1737
|
-
return `${compileOperand(expression.operand1)} ${expression.operator} ${compileOperand(expression.operand2)}`;
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
/**
|
|
1741
|
-
* Compile a formatter expression.
|
|
1742
|
-
*
|
|
1743
|
-
* @param expression The formatter expression.
|
|
1744
|
-
* @returns The compiled expression.
|
|
1745
|
-
*/
|
|
1746
|
-
function compileFormatterExpression(expression) {
|
|
1747
|
-
if (expression.parameters.length === 1) {
|
|
1748
|
-
return `{${compilePathParameter(expression.parameters[0], true)}, formatter: '${expression.fn}'}`;
|
|
1749
|
-
} else {
|
|
1750
|
-
const parts = expression.parameters.map(param => {
|
|
1751
|
-
if (param._type === "ComplexType") {
|
|
1752
|
-
return compileComplexTypeExpression(param);
|
|
1753
|
-
} else {
|
|
1754
|
-
return compilePathParameter(param);
|
|
1755
|
-
}
|
|
1756
|
-
});
|
|
1757
|
-
return `{parts: [${parts.join(", ")}], formatter: '${expression.fn}'}`;
|
|
1758
|
-
}
|
|
1759
|
-
}
|
|
1760
|
-
|
|
1761
|
-
/**
|
|
1762
|
-
* Compile the path parameter of a formatter call.
|
|
1763
|
-
*
|
|
1764
|
-
* @param expression The binding part to evaluate
|
|
1765
|
-
* @param singlePath Whether there is one or multiple path to consider
|
|
1766
|
-
* @returns The string snippet to include in the overall binding definition
|
|
1767
|
-
*/
|
|
1768
|
-
function compilePathParameter(expression) {
|
|
1769
|
-
let singlePath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1770
|
-
let outValue = "";
|
|
1771
|
-
if (expression._type === "Constant") {
|
|
1772
|
-
if (expression.value === undefined) {
|
|
1773
|
-
// Special case otherwise the JSTokenizer complains about incorrect content
|
|
1774
|
-
outValue = `value: 'undefined'`;
|
|
1775
|
-
} else {
|
|
1776
|
-
outValue = `value: ${compileConstant(expression, true)}`;
|
|
1777
|
-
}
|
|
1778
|
-
} else if (expression._type === "PathInModel") {
|
|
1779
|
-
outValue = `path: '${compilePathInModel(expression)}'`;
|
|
1780
|
-
outValue += expression.type ? `, type: '${expression.type}'` : `, targetType: 'any'`;
|
|
1781
|
-
if (expression.mode) {
|
|
1782
|
-
outValue += `, mode: '${compileExpression(expression.mode)}'`;
|
|
1783
|
-
}
|
|
1784
|
-
if (hasElements(expression.constraints)) {
|
|
1785
|
-
outValue += `, constraints: ${compileExpression(expression.constraints)}`;
|
|
1786
|
-
}
|
|
1787
|
-
if (hasElements(expression.formatOptions)) {
|
|
1788
|
-
outValue += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
|
|
1789
|
-
}
|
|
1790
|
-
if (hasElements(expression.parameters)) {
|
|
1791
|
-
outValue += `, parameters: ${compileExpression(expression.parameters)}`;
|
|
1792
|
-
}
|
|
1793
|
-
} else {
|
|
1794
|
-
return "";
|
|
1795
|
-
}
|
|
1796
|
-
return singlePath ? outValue : `{${outValue}}`;
|
|
1797
|
-
}
|
|
1798
|
-
function hasElements(obj) {
|
|
1799
|
-
return !!obj && Object.keys(obj).length > 0;
|
|
1800
|
-
}
|
|
1801
|
-
|
|
1802
|
-
/**
|
|
1803
|
-
* Compile a binding expression path.
|
|
1804
|
-
*
|
|
1805
|
-
* @param expression The expression to compile.
|
|
1806
|
-
* @returns The compiled path.
|
|
1807
|
-
*/
|
|
1808
|
-
function compilePathInModel(expression) {
|
|
1809
|
-
return `${expression.modelName ? expression.modelName + ">" : ""}${expression.path}`;
|
|
1810
|
-
}
|
|
1811
|
-
return _exports;
|
|
1812
|
-
}, false);
|
|
1813
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJFRE1fVFlQRV9NQVBQSU5HIiwidHlwZSIsImNvbnN0cmFpbnRzIiwiJFByZWNpc2lvbiIsIiRWNCIsIiRTY2FsZSIsIiRNYXhMZW5ndGgiLCIkTnVsbGFibGUiLCJ1bnJlc29sdmFibGVFeHByZXNzaW9uIiwiX3R5cGUiLCJlc2NhcGVYbWxBdHRyaWJ1dGUiLCJpbnB1dFN0cmluZyIsInJlcGxhY2UiLCJoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uIiwiZXhwcmVzc2lvbnMiLCJmaW5kIiwiZXhwciIsInVuZGVmaW5lZCIsIl9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwiLCJhIiwiYiIsInZhbHVlIiwib3BlcmFuZCIsIm9wZXJhdG9yIiwib3BlcmFuZHMiLCJsZW5ndGgiLCJldmVyeSIsImV4cHJlc3Npb24iLCJzb21lIiwib3RoZXJFeHByZXNzaW9uIiwiY29uZGl0aW9uIiwib25UcnVlIiwib25GYWxzZSIsIm9wZXJhbmQxIiwib3BlcmFuZDIiLCJhRXhwcmVzc2lvbnMiLCJiRXhwcmVzc2lvbnMiLCJpbmRleCIsInBhdGhJbk1vZGVsIiwibW9kZWxOYW1lIiwicGF0aCIsInRhcmdldEVudGl0eVNldCIsImZuIiwicGFyYW1ldGVycyIsImJpbmRpbmdQYXJhbWV0ZXJzIiwib3RoZXJGdW5jdGlvbiIsIm9iaiIsInJlZiIsImZsYXR0ZW5TZXRFeHByZXNzaW9uIiwicmVkdWNlIiwicmVzdWx0IiwiY2FuZGlkYXRlc0ZvckZsYXR0ZW5pbmciLCJmb3JFYWNoIiwiY2FuZGlkYXRlIiwiZSIsInB1c2giLCJoYXNPcHBvc2l0ZUV4cHJlc3Npb25zIiwibmVnYXRlZEV4cHJlc3Npb25zIiwibWFwIiwibm90IiwiaSIsImFuZCIsIndyYXBQcmltaXRpdmUiLCJpc1N0YXRpY0ZhbHNlIiwibm9uVHJpdmlhbEV4cHJlc3Npb24iLCJmaWx0ZXIiLCJpc0ZhbHNlIiwiaXNDb25zdGFudCIsImNvbnN0YW50IiwiaXNWYWxpZCIsImlzVHJ1ZSIsIm9yIiwiaXNTdGF0aWNUcnVlIiwiaXNDb21wYXJpc29uIiwiaXNUcnV0aHkiLCJiaW5kaW5nRXhwcmVzc2lvbiIsInZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMiLCJwYXRoVmlzaXRvciIsInRhcmdldFBhdGgiLCJsb2NhbFBhdGgiLCJjb25jYXQiLCJqb2luIiwiY29uc3RhbnRWYWx1ZSIsIkFycmF5IiwiaXNBcnJheSIsImlzUHJpbWl0aXZlT2JqZWN0IiwidmFsdWVPZiIsIk9iamVjdCIsImVudHJpZXMiLCJwbGFpbkV4cHJlc3Npb24iLCJrZXkiLCJ2YWwiLCJ3cmFwcGVkVmFsdWUiLCJyZXNvbHZlQmluZGluZ1N0cmluZyIsInRhcmdldFR5cGUiLCJzdGFydHNXaXRoIiwicGF0aEluTW9kZWxSZWdleCIsInBhdGhJbk1vZGVsUmVnZXhNYXRjaCIsImV4ZWMiLCJpc05hTiIsIk51bWJlciIsInJlZmVyZW5jZSIsInNvbWV0aGluZyIsImlzQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uIiwibWF5YmVDb25zdGFudCIsImlzUGF0aEluTW9kZWxFeHByZXNzaW9uIiwibWF5YmVCaW5kaW5nIiwiaXNDb21wbGV4VHlwZUV4cHJlc3Npb24iLCJpc0NvbmNhdEV4cHJlc3Npb24iLCJpc0lmRWxzZUV4cHJlc3Npb24iLCJpc1VuZGVmaW5lZEV4cHJlc3Npb24iLCJleHByZXNzaW9uQXNFeHByZXNzaW9uIiwib2JqZWN0VHlwZSIsImNvbnN0cnVjdG9yIiwibmFtZSIsImlzQ29tcGxleEFubm90YXRpb25FeHByZXNzaW9uIiwiYW5ub3RhdGlvblZhbHVlIiwiZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uIiwiZGVmYXVsdFZhbHVlIiwiYW5ub3RhdGlvbklmRXhwcmVzc2lvbiIsIklmIiwicGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uIiwiTm90IiwiZXF1YWwiLCJFcSIsIm5vdEVxdWFsIiwiTmUiLCJncmVhdGVyVGhhbiIsIkd0IiwiZ3JlYXRlck9yRXF1YWwiLCJHZSIsImxlc3NUaGFuIiwiTHQiLCJsZXNzT3JFcXVhbCIsIkxlIiwiT3IiLCJvckNvbmRpdGlvbiIsIkFuZCIsImFuZENvbmRpdGlvbiIsImFubm90YXRpb25BcHBseUV4cHJlc3Npb24iLCJoYXNPd25Qcm9wZXJ0eSIsIiRPciIsIiRBbmQiLCIkTm90IiwiJEVxIiwiJE5lIiwiJEd0IiwiJEdlIiwiJEx0IiwiJExlIiwiJFBhdGgiLCJGdW5jdGlvbiIsIiRGdW5jdGlvbiIsIkFwcGx5IiwiJEFwcGx5IiwiJElmIiwicmVzb2x2ZUVudW1WYWx1ZSIsIiRFbnVtTWVtYmVyIiwiaWZFbHNlIiwiY29udmVydFN1YkFwcGx5UGFyYW1ldGVycyIsImFwcGx5UGFyYW0iLCJhcHBseVBhcmFtQ29udmVydGVkIiwiYXBwbHlFeHByZXNzaW9uIiwicGFyYW1ldGVyIiwidGVtcGxhdGUiLCJ0ZW1wbGF0ZVBhcmFtcyIsInNsaWNlIiwidGFyZ2V0T2JqZWN0IiwiJE5hbWUiLCIkTGFiZWxlZEVsZW1lbnQiLCJjb21wYXJpc29uIiwibGVmdE9wZXJhbmQiLCJyaWdodE9wZXJhbmQiLCJsZWZ0RXhwcmVzc2lvbiIsInJpZ2h0RXhwcmVzc2lvbiIsImNoZWNrVW5kZWZpbmVkIiwibGVmdCIsInJpZ2h0IiwicmVkdWNlZCIsImNvbmRpdGlvbkV4cHJlc3Npb24iLCJvblRydWVFeHByZXNzaW9uIiwib25GYWxzZUV4cHJlc3Npb24iLCJwYXRoSWR4IiwibXlJZkVsc2VFeHByZXNzaW9uIiwiZm9ybWF0UmVzdWx0IiwiYWxsUGFydHMiLCJ0cmFuc2Zvcm1SZWN1cnNpdmVseSIsImNvbnN0YW50UGF0aCIsInVuc2hpZnQiLCJKU09OIiwic3RyaW5naWZ5IiwiaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dCIsImZvcm1hdHRlckZ1bmN0aW9uIiwiY29udGV4dEVudGl0eVR5cGUiLCJpZ25vcmVDb21wbGV4VHlwZSIsInBhcmFtZXRlckV4cHJlc3Npb25zIiwia2V5cyIsImZ1bmN0aW9uTmFtZSIsIl9fZnVuY3Rpb25OYW1lIiwiZm9ybWF0dGVyQ2xhc3MiLCJmb3JtYXR0ZXJOYW1lIiwic3BsaXQiLCJteUZvcm1hdEV4cHJlc3Npb24iLCJzZXRVcENvbnN0cmFpbnRzIiwidGFyZ2V0TWFwcGluZyIsInByb3BlcnR5Iiwic2NhbGUiLCJwcmVjaXNpb24iLCJtYXhMZW5ndGgiLCJudWxsYWJsZSIsImFubm90YXRpb25zIiwiVmFsaWRhdGlvbiIsIk1pbmltdW0iLCJtaW5pbXVtIiwiTWF4aW11bSIsIm1heGltdW0iLCJDb21tb24iLCJJc0RpZ2l0U2VxdWVuY2UiLCJpc0RpZ2l0U2VxdWVuY2UiLCJWNCIsImZvcm1hdFdpdGhUeXBlSW5mb3JtYXRpb24iLCJwcm9wZXJ0eUJpbmRpbmdFeHByZXNzaW9uIiwiaWdub3JlQ29uc3RyYWludHMiLCJvdXRFeHByZXNzaW9uIiwiZm9ybWF0T3B0aW9ucyIsImluZGV4T2YiLCJhc3NpZ24iLCJwYXJzZUFzU3RyaW5nIiwiaXNQcm9wZXJ0eSIsInBhcnNlS2VlcHNFbXB0eVN0cmluZyIsImZpc2NhbFR5cGUiLCJnZXRGaXNjYWxUeXBlIiwidHlwZXNTdXBwb3J0aW5nUGFyc2VFbXB0eVZhbHVlVG9aZXJvIiwiaW5jbHVkZXMiLCJwYXJzZUVtcHR5VmFsdWVUb1plcm8iLCJlbXB0eVN0cmluZyIsIklzRmlzY2FsWWVhciIsIklzRmlzY2FsUGVyaW9kIiwiSXNGaXNjYWxZZWFyUGVyaW9kIiwiSXNGaXNjYWxRdWFydGVyIiwiSXNGaXNjYWxZZWFyUXVhcnRlciIsIklzRmlzY2FsV2VlayIsIklzRmlzY2FsWWVhcldlZWsiLCJJc0RheU9mRmlzY2FsWWVhciIsImFkZFR5cGVJbmZvcm1hdGlvbiIsIm9Gb3JtYXRPcHRpb25zIiwiX2dldENvbXBsZXhUeXBlRm9ybWF0T3B0aW9uc0Zyb21GaXJzdFBhcmFtIiwidW9tUGF0aCIsIm1vZGUiLCJjdXJyZW5jeVBhdGgiLCJwYXJhbSIsInNob3dOdW1iZXIiLCJzaG93TWVhc3VyZSIsImZ1bmMiLCJvbiIsImlzRm9ybWF0dGluZ0ZuIiwiaXNFbXB0eSIsImFCaW5kaW5ncyIsImluRXhwcmVzc2lvbnMiLCJjb25jYXRlbmF0ZWQiLCJ0b1N0cmluZyIsIm15Q29uY2F0RXhwcmVzc2lvbiIsImluRXhwcmVzc2lvbiIsImV4cHJlc3Npb25UeXBlIiwidHJhbnNmb3JtRnVuY3Rpb24iLCJpbmNsdWRlQWxsRXhwcmVzc2lvbiIsInN1YkV4cHJlc3Npb24iLCJiaW5kaW5nUGFyYW1ldGVyIiwibmVlZFBhcmVudGhlc2lzIiwiY29tcGlsZUNvbnN0YW50T2JqZWN0IiwiaXNOdWxsYWJsZSIsIm9iamVjdHMiLCJwcm9wZXJ0aWVzIiwiY2hpbGRSZXN1bHQiLCJjb21waWxlRXhwcmVzc2lvbiIsImNvbXBpbGVDb25zdGFudCIsImVtYmVkZGVkSW5CaW5kaW5nIiwiZG9Ob3RTdHJpbmdpZnkiLCJjb21waWxlUGF0aEluTW9kZWxFeHByZXNzaW9uIiwiZXhwcmVzc2lvbkZvckJpbmRpbmciLCJlbWJlZGRlZFNlcGFyYXRvciIsImNvbXBsZXhCaW5kaW5nRGVmaW5pdGlvbiIsImNvbXBpbGVQYXRoSW5Nb2RlbCIsIm91dEJpbmRpbmciLCJjb21waWxlQ29tcGxleFR5cGVFeHByZXNzaW9uIiwiY29tcGlsZVBhdGhQYXJhbWV0ZXIiLCJvdXRwdXRFbmQiLCJoYXNFbGVtZW50cyIsIndyYXBCaW5kaW5nRXhwcmVzc2lvbiIsInBhcmVudGhlc2lzUmVxdWlyZWQiLCJrZWVwVGFyZ2V0VHlwZSIsImhhc0VtYmVkZGVkRnVuY3Rpb25DYWxsT3JCaW5kaW5nIiwic3ViRm4iLCJzdWJTdWJGbiIsImFyZ3VtZW50U3RyaW5nIiwiYXJnIiwiZm5DYWxsIiwic3Vic3RyaW5nIiwiY29tcGFyaXNvbkV4cHJlc3Npb24iLCJjb21waWxlQ29tcGFyaXNvbkV4cHJlc3Npb24iLCJpZkVsc2VFeHByZXNzaW9uIiwic2V0RXhwcmVzc2lvbiIsImNvbmNhdEV4cHJlc3Npb24iLCJuZXN0ZWRFeHByZXNzaW9uIiwibGVuZ3RoRXhwcmVzc2lvbiIsIm5vdEV4cHJlc3Npb24iLCJ0cnV0aHlFeHByZXNzaW9uIiwiZm9ybWF0dGVyRXhwcmVzc2lvbiIsImNvbXBpbGVGb3JtYXR0ZXJFeHByZXNzaW9uIiwiY29tcGxleFR5cGVFeHByZXNzaW9uIiwiY29tcGlsZU9wZXJhbmQiLCJjb21waWxlZE9wZXJhbmQiLCJwYXJ0cyIsInNpbmdsZVBhdGgiLCJvdXRWYWx1ZSJdLCJzb3VyY2VSb290IjoiLiIsInNvdXJjZXMiOlsiQmluZGluZ1Rvb2xraXQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUge1xuXHRBY3Rpb25QYXJhbWV0ZXIsXG5cdEFuZEFubm90YXRpb25FeHByZXNzaW9uLFxuXHRBbmRDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdEFwcGx5QW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEJvb2xlYW4sXG5cdENvbmRpdGlvbmFsQ2hlY2tPclZhbHVlLFxuXHRFbnRpdHlTZXQsXG5cdEVudGl0eVR5cGUsXG5cdEVxQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEVxQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRHZUFubm90YXRpb25FeHByZXNzaW9uLFxuXHRHZUNvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0R3RBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0R3RDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdElmQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdElmQW5ub3RhdGlvbkV4cHJlc3Npb25WYWx1ZSxcblx0TGVBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0TGVDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdEx0QW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEx0Q29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHROZUFubm90YXRpb25FeHByZXNzaW9uLFxuXHROZUNvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0Tm90QW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdE5vdENvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0T3JBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0T3JDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdFBhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0UGF0aENvbmRpdGlvbkV4cHJlc3Npb24sXG5cdFByb3BlcnR5LFxuXHRQcm9wZXJ0eUFubm90YXRpb25WYWx1ZVxufSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXNcIjtcbmltcG9ydCB7IENvbW1vbkFubm90YXRpb25UZXJtcyB9IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlcy92b2NhYnVsYXJpZXMvQ29tbW9uXCI7XG5pbXBvcnQgeyBpc1Byb3BlcnR5IH0gZnJvbSBcInNhcC9mZS9jb3JlL2hlbHBlcnMvVHlwZUd1YXJkc1wiO1xuaW1wb3J0IHsgcmVzb2x2ZUVudW1WYWx1ZSB9IGZyb20gXCIuL0Fubm90YXRpb25FbnVtXCI7XG5cbmV4cG9ydCB0eXBlIFByaW1pdGl2ZVR5cGUgPSBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQgfCBib29sZWFuIHwgb2JqZWN0IHwgbnVsbCB8IHVuZGVmaW5lZDtcbnR5cGUgRGVmaW5lZFByaW1pdGl2ZVR5cGUgPSBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQgfCBib29sZWFuIHwgb2JqZWN0O1xudHlwZSBQcmltaXRpdmVUeXBlQ2FzdDxQPiA9IFAgZXh0ZW5kcyBTdHJpbmcgPyBzdHJpbmcgOiBQIGV4dGVuZHMgQm9vbGVhbiA/IGJvb2xlYW4gOiBQIGV4dGVuZHMgTnVtYmVyID8gbnVtYmVyIDogUDtcbnR5cGUgQmFzZUV4cHJlc3Npb248X1Q+ID0ge1xuXHRfdHlwZTogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgRm9ybWF0T3B0aW9ucyA9IFBhcnRpYWw8e1xuXHRjdXN0b21Vbml0czogUmVjb3JkPHN0cmluZywgb2JqZWN0Pjtcblx0Y3VzdG9tQ3VycmVuY2llczogUmVjb3JkPHN0cmluZywgb2JqZWN0Pjtcblx0ZGVjaW1hbHM6IG51bWJlcjtcblx0ZW1wdHlTdHJpbmc6IG51bGwgfCBudW1iZXIgfCBzdHJpbmc7XG5cdGZpc2NhbFR5cGU6IHN0cmluZztcblx0Z3JvdXBpbmdFbmFibGVkOiBib29sZWFuO1xuXHRtYXhGcmFjdGlvbkRpZ2l0czogbnVtYmVyO1xuXHRtYXhJbnRlZ2VyRGlnaXRzOiBudW1iZXI7XG5cdG1pbkZyYWN0aW9uRGlnaXRzOiBudW1iZXI7XG5cdG1pbkludGVnZXJEaWdpdHM6IG51bWJlcjtcblx0cGFyc2VBc1N0cmluZzogYm9vbGVhbjtcblx0cGFyc2VLZWVwc0VtcHR5U3RyaW5nOiBib29sZWFuO1xuXHRwYXR0ZXJuOiBzdHJpbmc7XG5cdHByZWNpc2lvbjogbnVtYmVyO1xuXHRwcmVzZXJ2ZURlY2ltYWxzOiBib29sZWFuO1xuXHRzaG9ydERlY2ltYWxzOiBudW1iZXI7XG5cdHNob3J0UmVmTnVtYmVyOiBudW1iZXI7XG5cdHNob3dNZWFzdXJlOiBib29sZWFuO1xuXHRzaG93TnVtYmVyOiBib29sZWFuO1xuXHRzaG93U2NhbGU6IGJvb2xlYW47XG5cdHN0eWxlOiBzdHJpbmc7XG59PjtcblxuZXhwb3J0IHR5cGUgQ29uc3RhbnRFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkNvbnN0YW50XCI7XG5cdHZhbHVlOiBUO1xufTtcblxudHlwZSBTZXRPcGVyYXRvciA9IFwiJiZcIiB8IFwifHxcIjtcbmV4cG9ydCB0eXBlIFNldEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxib29sZWFuPiAmIHtcblx0X3R5cGU6IFwiU2V0XCI7XG5cdG9wZXJhdG9yOiBTZXRPcGVyYXRvcjtcblx0b3BlcmFuZHM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPltdO1xufTtcblxuZXhwb3J0IHR5cGUgTm90RXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPGJvb2xlYW4+ICYge1xuXHRfdHlwZTogXCJOb3RcIjtcblx0b3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+O1xufTtcblxuZXhwb3J0IHR5cGUgVHJ1dGh5RXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPGJvb2xlYW4+ICYge1xuXHRfdHlwZTogXCJUcnV0aHlcIjtcblx0b3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz47XG59O1xuXG5leHBvcnQgdHlwZSBSZWZlcmVuY2VFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248b2JqZWN0PiAmIHtcblx0X3R5cGU6IFwiUmVmXCI7XG5cdHJlZjogc3RyaW5nIHwgbnVsbDtcbn07XG5cbmV4cG9ydCB0eXBlIEZvcm1hdHRlckV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiRm9ybWF0dGVyXCI7XG5cdGZuOiBzdHJpbmc7XG5cdHBhcmFtZXRlcnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPltdO1xufTtcblxudHlwZSBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiQ29tcGxleFR5cGVcIjtcblx0dHlwZTogc3RyaW5nO1xuXHRmb3JtYXRPcHRpb25zOiBGb3JtYXRPcHRpb25zO1xuXHRwYXJhbWV0ZXJzOiBvYmplY3Q7XG5cdGJpbmRpbmdQYXJhbWV0ZXJzOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIEZ1bmN0aW9uRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJGdW5jdGlvblwiO1xuXHRvYmo/OiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248b2JqZWN0Pjtcblx0Zm46IHN0cmluZztcblx0aXNGb3JtYXR0aW5nRm46IGJvb2xlYW47XG5cdHBhcmFtZXRlcnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPltdO1xufTtcblxuZXhwb3J0IHR5cGUgQ29uY2F0RXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPHN0cmluZz4gJiB7XG5cdF90eXBlOiBcIkNvbmNhdFwiO1xuXHRleHByZXNzaW9uczogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIExlbmd0aEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxzdHJpbmc+ICYge1xuXHRfdHlwZTogXCJMZW5ndGhcIjtcblx0cGF0aEluTW9kZWw6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjx1bmtub3duPjtcbn07XG5cbnR5cGUgVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxzdHJpbmc+ICYge1xuXHRfdHlwZTogXCJVbnJlc29sdmFibGVcIjtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYgUGF0aEluTW9kZWxFeHByZXNzaW9uXG4gKi9cbmV4cG9ydCB0eXBlIFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJQYXRoSW5Nb2RlbFwiO1xuXHRtb2RlbE5hbWU/OiBzdHJpbmc7XG5cdHBhdGg6IHN0cmluZztcblx0dGFyZ2V0RW50aXR5U2V0PzogRW50aXR5U2V0O1xuXHR0eXBlPzogc3RyaW5nO1xuXHRjb25zdHJhaW50cz86IEJpbmRpbmdDb25zdHJhaW50cztcblx0cGFyYW1ldGVycz86IG9iamVjdDtcblx0dGFyZ2V0VHlwZT86IHN0cmluZztcblx0bW9kZT86IHN0cmluZztcblx0Zm9ybWF0T3B0aW9ucz86IEZvcm1hdE9wdGlvbnM7XG59O1xuXG5leHBvcnQgdHlwZSBFbWJlZGRlZFVJNUJpbmRpbmdFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkVtYmVkZGVkQmluZGluZ1wiO1xuXHR2YWx1ZTogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgRW1iZWRkZWRVSTVFeHByZXNzaW9uQmluZGluZ0V4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiO1xuXHR2YWx1ZTogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgQ29tcGFyaXNvbk9wZXJhdG9yID0gXCI9PT1cIiB8IFwiIT09XCIgfCBcIj49XCIgfCBcIj5cIiB8IFwiPD1cIiB8IFwiPFwiO1xuZXhwb3J0IHR5cGUgQ29tcGFyaXNvbkV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxib29sZWFuPiAmIHtcblx0X3R5cGU6IFwiQ29tcGFyaXNvblwiO1xuXHRvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yO1xuXHRvcGVyYW5kMTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+O1xuXHRvcGVyYW5kMjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+O1xufTtcblxuZXhwb3J0IHR5cGUgSWZFbHNlRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJJZkVsc2VcIjtcblx0Y29uZGl0aW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj47XG5cdG9uVHJ1ZTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRvbkZhbHNlOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG59O1xuXG4vKipcbiAqIEFuIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gdHlwZSBULlxuICpcbiAqIEB0eXBlZGVmIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvblxuICovXG5leHBvcnQgdHlwZSBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4gPVxuXHR8IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uXG5cdHwgQ29uc3RhbnRFeHByZXNzaW9uPFQ+XG5cdHwgU2V0RXhwcmVzc2lvblxuXHR8IE5vdEV4cHJlc3Npb25cblx0fCBUcnV0aHlFeHByZXNzaW9uXG5cdHwgQ29uY2F0RXhwcmVzc2lvblxuXHR8IExlbmd0aEV4cHJlc3Npb25cblx0fCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD5cblx0fCBFbWJlZGRlZFVJNUJpbmRpbmdFeHByZXNzaW9uPFQ+XG5cdHwgRW1iZWRkZWRVSTVFeHByZXNzaW9uQmluZGluZ0V4cHJlc3Npb248VD5cblx0fCBDb21wYXJpc29uRXhwcmVzc2lvblxuXHR8IElmRWxzZUV4cHJlc3Npb248VD5cblx0fCBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+XG5cdHwgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+XG5cdHwgUmVmZXJlbmNlRXhwcmVzc2lvblxuXHR8IEZ1bmN0aW9uRXhwcmVzc2lvbjxUPjtcblxudHlwZSBUeXBlTWFwcGluZ0RlZmluaXRpb24gPSB7XG5cdHR5cGU6IHN0cmluZztcblx0Y29uc3RyYWludHM/OiB7XG5cdFx0JFByZWNpc2lvbj86IHN0cmluZztcblx0XHQkVjQ/OiBzdHJpbmc7XG5cdFx0JFNjYWxlPzogc3RyaW5nO1xuXHRcdCRNYXhMZW5ndGg/OiBzdHJpbmc7XG5cdFx0JE51bGxhYmxlPzogc3RyaW5nO1xuXHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1pbmltdW0vJERlY2ltYWxcIj86IHN0cmluZztcblx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NaW5pbXVtQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLkV4Y2x1c2l2ZVwiPzogc3RyaW5nO1xuXHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1heGltdW0vJERlY2ltYWxcIj86IHN0cmluZztcblx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NYXhpbXVtQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLkV4Y2x1c2l2ZVwiPzogc3RyaW5nO1xuXHRcdFwiQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5Jc0RpZ2l0U2VxdWVuY2VcIj86IHN0cmluZztcblx0fTtcbn07XG5leHBvcnQgY29uc3QgRURNX1RZUEVfTUFQUElORzogUmVjb3JkPHN0cmluZywgVHlwZU1hcHBpbmdEZWZpbml0aW9uPiA9IHtcblx0XCJFZG0uQm9vbGVhblwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuQm9vbGVhblwiIH0sXG5cdFwiRWRtLkJ5dGVcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkJ5dGVcIiB9LFxuXHRcIkVkbS5EYXRlXCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EYXRlXCIgfSxcblx0XCJFZG0uRGF0ZVRpbWVPZmZzZXRcIjoge1xuXHRcdGNvbnN0cmFpbnRzOiB7XG5cdFx0XHQkUHJlY2lzaW9uOiBcInByZWNpc2lvblwiLFxuXHRcdFx0JFY0OiBcIlY0XCJcblx0XHR9LFxuXHRcdHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRGF0ZVRpbWVPZmZzZXRcIlxuXHR9LFxuXHRcIkVkbS5EZWNpbWFsXCI6IHtcblx0XHRjb25zdHJhaW50czoge1xuXHRcdFx0XCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWluaW11bS8kRGVjaW1hbFwiOiBcIm1pbmltdW1cIixcblx0XHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1pbmltdW1AT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuRXhjbHVzaXZlXCI6IFwibWluaW11bUV4Y2x1c2l2ZVwiLFxuXHRcdFx0XCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWF4aW11bS8kRGVjaW1hbFwiOiBcIm1heGltdW1cIixcblx0XHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1heGltdW1AT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuRXhjbHVzaXZlXCI6IFwibWF4aW11bUV4Y2x1c2l2ZVwiLFxuXHRcdFx0JFByZWNpc2lvbjogXCJwcmVjaXNpb25cIixcblx0XHRcdCRTY2FsZTogXCJzY2FsZVwiXG5cdFx0fSxcblx0XHR0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRlY2ltYWxcIlxuXHR9LFxuXHRcIkVkbS5Eb3VibGVcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRvdWJsZVwiIH0sXG5cdFwiRWRtLkd1aWRcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkd1aWRcIiB9LFxuXHRcIkVkbS5JbnQxNlwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50MTZcIiB9LFxuXHRcIkVkbS5JbnQzMlwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50MzJcIiB9LFxuXHRcIkVkbS5JbnQ2NFwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50NjRcIiB9LFxuXHRcIkVkbS5TQnl0ZVwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU0J5dGVcIiB9LFxuXHRcIkVkbS5TaW5nbGVcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlNpbmdsZVwiIH0sXG5cdFwiRWRtLlN0cmVhbVwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU3RyZWFtXCIgfSxcblx0XCJFZG0uQmluYXJ5XCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5TdHJlYW1cIiB9LFxuXHRcIkVkbS5TdHJpbmdcIjoge1xuXHRcdGNvbnN0cmFpbnRzOiB7XG5cdFx0XHRcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuSXNEaWdpdFNlcXVlbmNlXCI6IFwiaXNEaWdpdFNlcXVlbmNlXCIsXG5cdFx0XHQkTWF4TGVuZ3RoOiBcIm1heExlbmd0aFwiLFxuXHRcdFx0JE51bGxhYmxlOiBcIm51bGxhYmxlXCJcblx0XHR9LFxuXHRcdHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU3RyaW5nXCJcblx0fSxcblx0XCJFZG0uVGltZU9mRGF5XCI6IHtcblx0XHRjb25zdHJhaW50czoge1xuXHRcdFx0JFByZWNpc2lvbjogXCJwcmVjaXNpb25cIlxuXHRcdH0sXG5cdFx0dHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5UaW1lT2ZEYXlcIlxuXHR9XG59O1xuXG4vKipcbiAqIEFuIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gdHlwZSBULCBvciBhIGNvbnN0YW50IHZhbHVlIG9mIHR5cGUgVFxuICovXG5leHBvcnQgdHlwZSBFeHByZXNzaW9uT3JQcmltaXRpdmU8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+ID0gQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHwgVDtcblxuZXhwb3J0IGNvbnN0IHVucmVzb2x2YWJsZUV4cHJlc3Npb246IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uID0ge1xuXHRfdHlwZTogXCJVbnJlc29sdmFibGVcIlxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZVhtbEF0dHJpYnV0ZShpbnB1dFN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcblx0cmV0dXJuIGlucHV0U3RyaW5nLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24oLi4uZXhwcmVzc2lvbnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPltdKTogYm9vbGVhbiB7XG5cdHJldHVybiBleHByZXNzaW9ucy5maW5kKChleHByKSA9PiBleHByLl90eXBlID09PSBcIlVucmVzb2x2YWJsZVwiKSAhPT0gdW5kZWZpbmVkO1xufVxuLyoqXG4gKiBDaGVjayB0d28gZXhwcmVzc2lvbnMgZm9yIChkZWVwKSBlcXVhbGl0eS5cbiAqXG4gKiBAcGFyYW0gYVxuICogQHBhcmFtIGJcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgdHdvIGV4cHJlc3Npb25zIGFyZSBlcXVhbFxuICovXG5leHBvcnQgZnVuY3Rpb24gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbDxUPihhOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sIGI6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPik6IGJvb2xlYW4ge1xuXHRpZiAoYS5fdHlwZSAhPT0gYi5fdHlwZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHN3aXRjaCAoYS5fdHlwZSkge1xuXHRcdGNhc2UgXCJVbnJlc29sdmFibGVcIjpcblx0XHRcdHJldHVybiBmYWxzZTsgLy8gVW5yZXNvbHZhYmxlIGlzIG5ldmVyIGVxdWFsIHRvIGFueXRoaW5nIGV2ZW4gaXRzZWxmXG5cdFx0Y2FzZSBcIkNvbnN0YW50XCI6XG5cdFx0Y2FzZSBcIkVtYmVkZGVkQmluZGluZ1wiOlxuXHRcdGNhc2UgXCJFbWJlZGRlZEV4cHJlc3Npb25CaW5kaW5nXCI6XG5cdFx0XHRyZXR1cm4gYS52YWx1ZSA9PT0gKGIgYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+KS52YWx1ZTtcblxuXHRcdGNhc2UgXCJOb3RcIjpcblx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub3BlcmFuZCwgKGIgYXMgTm90RXhwcmVzc2lvbikub3BlcmFuZCk7XG5cdFx0Y2FzZSBcIlRydXRoeVwiOlxuXHRcdFx0cmV0dXJuIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vcGVyYW5kLCAoYiBhcyBUcnV0aHlFeHByZXNzaW9uKS5vcGVyYW5kKTtcblx0XHRjYXNlIFwiU2V0XCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLm9wZXJhdG9yID09PSAoYiBhcyBTZXRFeHByZXNzaW9uKS5vcGVyYXRvciAmJlxuXHRcdFx0XHRhLm9wZXJhbmRzLmxlbmd0aCA9PT0gKGIgYXMgU2V0RXhwcmVzc2lvbikub3BlcmFuZHMubGVuZ3RoICYmXG5cdFx0XHRcdGEub3BlcmFuZHMuZXZlcnkoKGV4cHJlc3Npb24pID0+XG5cdFx0XHRcdFx0KGIgYXMgU2V0RXhwcmVzc2lvbikub3BlcmFuZHMuc29tZSgob3RoZXJFeHByZXNzaW9uKSA9PiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGV4cHJlc3Npb24sIG90aGVyRXhwcmVzc2lvbikpXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cblx0XHRjYXNlIFwiSWZFbHNlXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEuY29uZGl0aW9uLCAoYiBhcyBJZkVsc2VFeHByZXNzaW9uPFQ+KS5jb25kaXRpb24pICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vblRydWUsIChiIGFzIElmRWxzZUV4cHJlc3Npb248VD4pLm9uVHJ1ZSkgJiZcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9uRmFsc2UsIChiIGFzIElmRWxzZUV4cHJlc3Npb248VD4pLm9uRmFsc2UpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIkNvbXBhcmlzb25cIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEub3BlcmF0b3IgPT09IChiIGFzIENvbXBhcmlzb25FeHByZXNzaW9uKS5vcGVyYXRvciAmJlxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub3BlcmFuZDEsIChiIGFzIENvbXBhcmlzb25FeHByZXNzaW9uKS5vcGVyYW5kMSkgJiZcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9wZXJhbmQyLCAoYiBhcyBDb21wYXJpc29uRXhwcmVzc2lvbikub3BlcmFuZDIpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIkNvbmNhdFwiOlxuXHRcdFx0Y29uc3QgYUV4cHJlc3Npb25zID0gYS5leHByZXNzaW9ucztcblx0XHRcdGNvbnN0IGJFeHByZXNzaW9ucyA9IChiIGFzIENvbmNhdEV4cHJlc3Npb24pLmV4cHJlc3Npb25zO1xuXHRcdFx0aWYgKGFFeHByZXNzaW9ucy5sZW5ndGggIT09IGJFeHByZXNzaW9ucy5sZW5ndGgpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGFFeHByZXNzaW9ucy5ldmVyeSgoZXhwcmVzc2lvbiwgaW5kZXgpID0+IHtcblx0XHRcdFx0cmV0dXJuIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoZXhwcmVzc2lvbiwgYkV4cHJlc3Npb25zW2luZGV4XSk7XG5cdFx0XHR9KTtcblxuXHRcdGNhc2UgXCJMZW5ndGhcIjpcblx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEucGF0aEluTW9kZWwsIChiIGFzIExlbmd0aEV4cHJlc3Npb24pLnBhdGhJbk1vZGVsKTtcblxuXHRcdGNhc2UgXCJQYXRoSW5Nb2RlbFwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS5tb2RlbE5hbWUgPT09IChiIGFzIFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPikubW9kZWxOYW1lICYmXG5cdFx0XHRcdGEucGF0aCA9PT0gKGIgYXMgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+KS5wYXRoICYmXG5cdFx0XHRcdGEudGFyZ2V0RW50aXR5U2V0ID09PSAoYiBhcyBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4pLnRhcmdldEVudGl0eVNldFxuXHRcdFx0KTtcblxuXHRcdGNhc2UgXCJGb3JtYXR0ZXJcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEuZm4gPT09IChiIGFzIEZvcm1hdHRlckV4cHJlc3Npb248VD4pLmZuICYmXG5cdFx0XHRcdGEucGFyYW1ldGVycy5sZW5ndGggPT09IChiIGFzIEZvcm1hdHRlckV4cHJlc3Npb248VD4pLnBhcmFtZXRlcnMubGVuZ3RoICYmXG5cdFx0XHRcdGEucGFyYW1ldGVycy5ldmVyeSgodmFsdWUsIGluZGV4KSA9PiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKChiIGFzIEZvcm1hdHRlckV4cHJlc3Npb248VD4pLnBhcmFtZXRlcnNbaW5kZXhdLCB2YWx1ZSkpXG5cdFx0XHQpO1xuXHRcdGNhc2UgXCJDb21wbGV4VHlwZVwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS50eXBlID09PSAoYiBhcyBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pLnR5cGUgJiZcblx0XHRcdFx0YS5iaW5kaW5nUGFyYW1ldGVycy5sZW5ndGggPT09IChiIGFzIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPikuYmluZGluZ1BhcmFtZXRlcnMubGVuZ3RoICYmXG5cdFx0XHRcdGEuYmluZGluZ1BhcmFtZXRlcnMuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT5cblx0XHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKChiIGFzIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPikuYmluZGluZ1BhcmFtZXRlcnNbaW5kZXhdLCB2YWx1ZSlcblx0XHRcdFx0KVxuXHRcdFx0KTtcblx0XHRjYXNlIFwiRnVuY3Rpb25cIjpcblx0XHRcdGNvbnN0IG90aGVyRnVuY3Rpb24gPSBiIGFzIEZ1bmN0aW9uRXhwcmVzc2lvbjxUPjtcblx0XHRcdGlmIChhLm9iaiA9PT0gdW5kZWZpbmVkIHx8IG90aGVyRnVuY3Rpb24ub2JqID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cmV0dXJuIGEub2JqID09PSBvdGhlckZ1bmN0aW9uO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLmZuID09PSBvdGhlckZ1bmN0aW9uLmZuICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vYmosIG90aGVyRnVuY3Rpb24ub2JqKSAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMubGVuZ3RoID09PSBvdGhlckZ1bmN0aW9uLnBhcmFtZXRlcnMubGVuZ3RoICYmXG5cdFx0XHRcdGEucGFyYW1ldGVycy5ldmVyeSgodmFsdWUsIGluZGV4KSA9PiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKG90aGVyRnVuY3Rpb24ucGFyYW1ldGVyc1tpbmRleF0sIHZhbHVlKSlcblx0XHRcdCk7XG5cblx0XHRjYXNlIFwiUmVmXCI6XG5cdFx0XHRyZXR1cm4gYS5yZWYgPT09IChiIGFzIFJlZmVyZW5jZUV4cHJlc3Npb24pLnJlZjtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBuZXN0ZWQgU2V0RXhwcmVzc2lvbiBieSBpbmxpbmluZyBvcGVyYW5kcyBvZiB0eXBlIFNldEV4cHJlc3Npb24gd2l0aCB0aGUgc2FtZSBvcGVyYXRvci5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgZXhwcmVzc2lvbiB0byBmbGF0dGVuXG4gKiBAcmV0dXJucyBBIG5ldyBTZXRFeHByZXNzaW9uIHdpdGggdGhlIHNhbWUgb3BlcmF0b3JcbiAqL1xuZnVuY3Rpb24gZmxhdHRlblNldEV4cHJlc3Npb24oZXhwcmVzc2lvbjogU2V0RXhwcmVzc2lvbik6IFNldEV4cHJlc3Npb24ge1xuXHRyZXR1cm4gZXhwcmVzc2lvbi5vcGVyYW5kcy5yZWR1Y2UoXG5cdFx0KHJlc3VsdDogU2V0RXhwcmVzc2lvbiwgb3BlcmFuZCkgPT4ge1xuXHRcdFx0Y29uc3QgY2FuZGlkYXRlc0ZvckZsYXR0ZW5pbmcgPVxuXHRcdFx0XHRvcGVyYW5kLl90eXBlID09PSBcIlNldFwiICYmIG9wZXJhbmQub3BlcmF0b3IgPT09IGV4cHJlc3Npb24ub3BlcmF0b3IgPyBvcGVyYW5kLm9wZXJhbmRzIDogW29wZXJhbmRdO1xuXHRcdFx0Y2FuZGlkYXRlc0ZvckZsYXR0ZW5pbmcuZm9yRWFjaCgoY2FuZGlkYXRlKSA9PiB7XG5cdFx0XHRcdGlmIChyZXN1bHQub3BlcmFuZHMuZXZlcnkoKGUpID0+ICFfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGUsIGNhbmRpZGF0ZSkpKSB7XG5cdFx0XHRcdFx0cmVzdWx0Lm9wZXJhbmRzLnB1c2goY2FuZGlkYXRlKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH0sXG5cdFx0eyBfdHlwZTogXCJTZXRcIiwgb3BlcmF0b3I6IGV4cHJlc3Npb24ub3BlcmF0b3IsIG9wZXJhbmRzOiBbXSB9XG5cdCk7XG59XG5cbi8qKlxuICogRGV0ZWN0cyB3aGV0aGVyIGFuIGFycmF5IG9mIGJvb2xlYW4gZXhwcmVzc2lvbnMgY29udGFpbnMgYW4gZXhwcmVzc2lvbiBhbmQgaXRzIG5lZ2F0aW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9ucyBBcnJheSBvZiBleHByZXNzaW9uc1xuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBzZXQgb2YgZXhwcmVzc2lvbnMgY29udGFpbnMgYW4gZXhwcmVzc2lvbiBhbmQgaXRzIG5lZ2F0aW9uXG4gKi9cbmZ1bmN0aW9uIGhhc09wcG9zaXRlRXhwcmVzc2lvbnMoZXhwcmVzc2lvbnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPltdKTogYm9vbGVhbiB7XG5cdGNvbnN0IG5lZ2F0ZWRFeHByZXNzaW9ucyA9IGV4cHJlc3Npb25zLm1hcChub3QpO1xuXHRyZXR1cm4gZXhwcmVzc2lvbnMuc29tZSgoZXhwcmVzc2lvbiwgaW5kZXgpID0+IHtcblx0XHRmb3IgKGxldCBpID0gaW5kZXggKyAxOyBpIDwgbmVnYXRlZEV4cHJlc3Npb25zLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChleHByZXNzaW9uLCBuZWdhdGVkRXhwcmVzc2lvbnNbaV0pKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH0pO1xufVxuXG4vKipcbiAqIExvZ2ljYWwgYGFuZGAgZXhwcmVzc2lvbi5cbiAqXG4gKiBUaGUgZXhwcmVzc2lvbiBpcyBzaW1wbGlmaWVkIHRvIGZhbHNlIGlmIHRoaXMgY2FuIGJlIGRlY2lkZWQgc3RhdGljYWxseSAodGhhdCBpcywgaWYgb25lIG9wZXJhbmQgaXMgYSBjb25zdGFudFxuICogZmFsc2Ugb3IgaWYgdGhlIGV4cHJlc3Npb24gY29udGFpbnMgYW4gb3BlcmFuZCBhbmQgaXRzIG5lZ2F0aW9uKS5cbiAqXG4gKiBAcGFyYW0gb3BlcmFuZHMgRXhwcmVzc2lvbnMgdG8gY29ubmVjdCBieSBgYW5kYFxuICogQHJldHVybnMgRXhwcmVzc2lvbiBldmFsdWF0aW5nIHRvIGJvb2xlYW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuZCguLi5vcGVyYW5kczogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPGJvb2xlYW4+W10pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRjb25zdCBleHByZXNzaW9ucyA9IGZsYXR0ZW5TZXRFeHByZXNzaW9uKHtcblx0XHRfdHlwZTogXCJTZXRcIixcblx0XHRvcGVyYXRvcjogXCImJlwiLFxuXHRcdG9wZXJhbmRzOiBvcGVyYW5kcy5tYXAod3JhcFByaW1pdGl2ZSlcblx0fSkub3BlcmFuZHM7XG5cblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24oLi4uZXhwcmVzc2lvbnMpKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0bGV0IGlzU3RhdGljRmFsc2UgPSBmYWxzZTtcblx0Y29uc3Qgbm9uVHJpdmlhbEV4cHJlc3Npb24gPSBleHByZXNzaW9ucy5maWx0ZXIoKGV4cHJlc3Npb24pID0+IHtcblx0XHRpZiAoaXNGYWxzZShleHByZXNzaW9uKSkge1xuXHRcdFx0aXNTdGF0aWNGYWxzZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAhaXNDb25zdGFudChleHByZXNzaW9uKTtcblx0fSk7XG5cdGlmIChpc1N0YXRpY0ZhbHNlKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0fSBlbHNlIGlmIChub25Ucml2aWFsRXhwcmVzc2lvbi5sZW5ndGggPT09IDApIHtcblx0XHQvLyBSZXNvbHZlIHRoZSBjb25zdGFudCB0aGVuXG5cdFx0Y29uc3QgaXNWYWxpZCA9IGV4cHJlc3Npb25zLnJlZHVjZSgocmVzdWx0LCBleHByZXNzaW9uKSA9PiByZXN1bHQgJiYgaXNUcnVlKGV4cHJlc3Npb24pLCB0cnVlKTtcblx0XHRyZXR1cm4gY29uc3RhbnQoaXNWYWxpZCk7XG5cdH0gZWxzZSBpZiAobm9uVHJpdmlhbEV4cHJlc3Npb24ubGVuZ3RoID09PSAxKSB7XG5cdFx0cmV0dXJuIG5vblRyaXZpYWxFeHByZXNzaW9uWzBdO1xuXHR9IGVsc2UgaWYgKGhhc09wcG9zaXRlRXhwcmVzc2lvbnMobm9uVHJpdmlhbEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0XHRvcGVyYXRvcjogXCImJlwiLFxuXHRcdFx0b3BlcmFuZHM6IG5vblRyaXZpYWxFeHByZXNzaW9uXG5cdFx0fTtcblx0fVxufVxuXG4vKipcbiAqIExvZ2ljYWwgYG9yYCBleHByZXNzaW9uLlxuICpcbiAqIFRoZSBleHByZXNzaW9uIGlzIHNpbXBsaWZpZWQgdG8gdHJ1ZSBpZiB0aGlzIGNhbiBiZSBkZWNpZGVkIHN0YXRpY2FsbHkgKHRoYXQgaXMsIGlmIG9uZSBvcGVyYW5kIGlzIGEgY29uc3RhbnRcbiAqIHRydWUgb3IgaWYgdGhlIGV4cHJlc3Npb24gY29udGFpbnMgYW4gb3BlcmFuZCBhbmQgaXRzIG5lZ2F0aW9uKS5cbiAqXG4gKiBAcGFyYW0gb3BlcmFuZHMgRXhwcmVzc2lvbnMgdG8gY29ubmVjdCBieSBgb3JgXG4gKiBAcmV0dXJucyBFeHByZXNzaW9uIGV2YWx1YXRpbmcgdG8gYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gb3IoLi4ub3BlcmFuZHM6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPltdKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0Y29uc3QgZXhwcmVzc2lvbnMgPSBmbGF0dGVuU2V0RXhwcmVzc2lvbih7XG5cdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0b3BlcmF0b3I6IFwifHxcIixcblx0XHRvcGVyYW5kczogb3BlcmFuZHMubWFwKHdyYXBQcmltaXRpdmUpXG5cdH0pLm9wZXJhbmRzO1xuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbiguLi5leHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRsZXQgaXNTdGF0aWNUcnVlID0gZmFsc2U7XG5cdGNvbnN0IG5vblRyaXZpYWxFeHByZXNzaW9uID0gZXhwcmVzc2lvbnMuZmlsdGVyKChleHByZXNzaW9uKSA9PiB7XG5cdFx0aWYgKGlzVHJ1ZShleHByZXNzaW9uKSkge1xuXHRcdFx0aXNTdGF0aWNUcnVlID0gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuICFpc0NvbnN0YW50KGV4cHJlc3Npb24pIHx8IGV4cHJlc3Npb24udmFsdWU7XG5cdH0pO1xuXHRpZiAoaXNTdGF0aWNUcnVlKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KHRydWUpO1xuXHR9IGVsc2UgaWYgKG5vblRyaXZpYWxFeHByZXNzaW9uLmxlbmd0aCA9PT0gMCkge1xuXHRcdC8vIFJlc29sdmUgdGhlIGNvbnN0YW50IHRoZW5cblx0XHRjb25zdCBpc1ZhbGlkID0gZXhwcmVzc2lvbnMucmVkdWNlKChyZXN1bHQsIGV4cHJlc3Npb24pID0+IHJlc3VsdCAmJiBpc1RydWUoZXhwcmVzc2lvbiksIHRydWUpO1xuXHRcdHJldHVybiBjb25zdGFudChpc1ZhbGlkKTtcblx0fSBlbHNlIGlmIChub25Ucml2aWFsRXhwcmVzc2lvbi5sZW5ndGggPT09IDEpIHtcblx0XHRyZXR1cm4gbm9uVHJpdmlhbEV4cHJlc3Npb25bMF07XG5cdH0gZWxzZSBpZiAoaGFzT3Bwb3NpdGVFeHByZXNzaW9ucyhub25Ucml2aWFsRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodHJ1ZSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIlNldFwiLFxuXHRcdFx0b3BlcmF0b3I6IFwifHxcIixcblx0XHRcdG9wZXJhbmRzOiBub25Ucml2aWFsRXhwcmVzc2lvblxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBMb2dpY2FsIGBub3RgIG9wZXJhdG9yLlxuICpcbiAqIEBwYXJhbSBvcGVyYW5kIFRoZSBleHByZXNzaW9uIHRvIHJldmVyc2VcbiAqIEByZXR1cm5zIFRoZSByZXN1bHRpbmcgZXhwcmVzc2lvbiB0aGF0IGV2YWx1YXRlcyB0byBib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3Qob3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPGJvb2xlYW4+KTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0b3BlcmFuZCA9IHdyYXBQcmltaXRpdmUob3BlcmFuZCk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKG9wZXJhbmQpKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH0gZWxzZSBpZiAoaXNDb25zdGFudChvcGVyYW5kKSkge1xuXHRcdHJldHVybiBjb25zdGFudCghb3BlcmFuZC52YWx1ZSk7XG5cdH0gZWxzZSBpZiAoXG5cdFx0dHlwZW9mIG9wZXJhbmQgPT09IFwib2JqZWN0XCIgJiZcblx0XHRvcGVyYW5kLl90eXBlID09PSBcIlNldFwiICYmXG5cdFx0b3BlcmFuZC5vcGVyYXRvciA9PT0gXCJ8fFwiICYmXG5cdFx0b3BlcmFuZC5vcGVyYW5kcy5ldmVyeSgoZXhwcmVzc2lvbikgPT4gaXNDb25zdGFudChleHByZXNzaW9uKSB8fCBpc0NvbXBhcmlzb24oZXhwcmVzc2lvbikpXG5cdCkge1xuXHRcdHJldHVybiBhbmQoLi4ub3BlcmFuZC5vcGVyYW5kcy5tYXAoKGV4cHJlc3Npb24pID0+IG5vdChleHByZXNzaW9uKSkpO1xuXHR9IGVsc2UgaWYgKFxuXHRcdHR5cGVvZiBvcGVyYW5kID09PSBcIm9iamVjdFwiICYmXG5cdFx0b3BlcmFuZC5fdHlwZSA9PT0gXCJTZXRcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmF0b3IgPT09IFwiJiZcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmFuZHMuZXZlcnkoKGV4cHJlc3Npb24pID0+IGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgfHwgaXNDb21wYXJpc29uKGV4cHJlc3Npb24pKVxuXHQpIHtcblx0XHRyZXR1cm4gb3IoLi4ub3BlcmFuZC5vcGVyYW5kcy5tYXAoKGV4cHJlc3Npb24pID0+IG5vdChleHByZXNzaW9uKSkpO1xuXHR9IGVsc2UgaWYgKGlzQ29tcGFyaXNvbihvcGVyYW5kKSkge1xuXHRcdC8vIENyZWF0ZSB0aGUgcmV2ZXJzZSBjb21wYXJpc29uXG5cdFx0c3dpdGNoIChvcGVyYW5kLm9wZXJhdG9yKSB7XG5cdFx0XHRjYXNlIFwiIT09XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIj09PVwiIH07XG5cdFx0XHRjYXNlIFwiPFwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCI+PVwiIH07XG5cdFx0XHRjYXNlIFwiPD1cIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPlwiIH07XG5cdFx0XHRjYXNlIFwiPT09XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIiE9PVwiIH07XG5cdFx0XHRjYXNlIFwiPlwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCI8PVwiIH07XG5cdFx0XHRjYXNlIFwiPj1cIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPFwiIH07XG5cdFx0fVxuXHR9IGVsc2UgaWYgKG9wZXJhbmQuX3R5cGUgPT09IFwiTm90XCIpIHtcblx0XHRyZXR1cm4gb3BlcmFuZC5vcGVyYW5kO1xuXHR9XG5cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJOb3RcIixcblx0XHRvcGVyYW5kOiBvcGVyYW5kXG5cdH07XG59XG5cbi8qKlxuICogRXZhbHVhdGVzIHdoZXRoZXIgYSBiaW5kaW5nIGV4cHJlc3Npb24gaXMgZXF1YWwgdG8gdHJ1ZSB3aXRoIGEgbG9vc2UgZXF1YWxpdHkuXG4gKlxuICogQHBhcmFtIG9wZXJhbmQgVGhlIGV4cHJlc3Npb24gdG8gY2hlY2tcbiAqIEByZXR1cm5zIFRoZSByZXN1bHRpbmcgZXhwcmVzc2lvbiB0aGF0IGV2YWx1YXRlcyB0byBib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1RydXRoeShvcGVyYW5kOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGlmIChpc0NvbnN0YW50KG9wZXJhbmQpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KCEhb3BlcmFuZC52YWx1ZSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIlRydXRoeVwiLFxuXHRcdFx0b3BlcmFuZDogb3BlcmFuZFxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgYmluZGluZyBleHByZXNzaW9uIHRoYXQgd2lsbCBiZSBldmFsdWF0ZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgbW9kZWwuXG4gKlxuICogQHBhcmFtIHBhdGhcbiAqIEBwYXJhbSBtb2RlbE5hbWVcbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzXG4gKiBAcGFyYW0gcGF0aFZpc2l0b3JcbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50YXRpbmcgdGhhdCBwYXRoIGluIHRoZSBtb2RlbFxuICogQGRlcHJlY2F0ZWQgdXNlIHBhdGhJbk1vZGVsIGluc3RlYWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJpbmRpbmdFeHByZXNzaW9uPFRhcmdldFR5cGUgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0cGF0aDogc3RyaW5nLFxuXHRtb2RlbE5hbWU/OiBzdHJpbmcsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM6IHN0cmluZ1tdID0gW10sXG5cdHBhdGhWaXNpdG9yPzogRnVuY3Rpb25cbik6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUYXJnZXRUeXBlPiB8IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uIHtcblx0cmV0dXJuIHBhdGhJbk1vZGVsKHBhdGgsIG1vZGVsTmFtZSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBiaW5kaW5nIGV4cHJlc3Npb24gdGhhdCB3aWxsIGJlIGV2YWx1YXRlZCBieSB0aGUgY29ycmVzcG9uZGluZyBtb2RlbC5cbiAqXG4gKiBAdGVtcGxhdGUgVGFyZ2V0VHlwZVxuICogQHBhcmFtIHBhdGggVGhlIHBhdGggb24gdGhlIG1vZGVsXG4gKiBAcGFyYW0gW21vZGVsTmFtZV0gVGhlIG5hbWUgb2YgdGhlIG1vZGVsXG4gKiBAcGFyYW0gW3Zpc2l0ZWROYXZpZ2F0aW9uUGF0aHNdIFRoZSBwYXRocyBmcm9tIHRoZSByb290IGVudGl0eVNldFxuICogQHBhcmFtIFtwYXRoVmlzaXRvcl0gQSBmdW5jdGlvbiB0byBtb2RpZnkgdGhlIHJlc3VsdGluZyBwYXRoXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGF0aW5nIHRoYXQgcGF0aCBpbiB0aGUgbW9kZWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGhJbk1vZGVsKFxuXHRwYXRoOiB1bmRlZmluZWQsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRocz86IHN0cmluZ1tdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbjtcbmV4cG9ydCBmdW5jdGlvbiBwYXRoSW5Nb2RlbDxUYXJnZXRUeXBlIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHBhdGg6IHN0cmluZyxcblx0bW9kZWxOYW1lPzogc3RyaW5nLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzPzogc3RyaW5nW10sXG5cdHBhdGhWaXNpdG9yPzogdW5kZWZpbmVkXG4pOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT47XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRocz86IHN0cmluZ1tdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbiB8IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUYXJnZXRUeXBlPjtcbmV4cG9ydCBmdW5jdGlvbiBwYXRoSW5Nb2RlbDxUYXJnZXRUeXBlIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZCxcblx0bW9kZWxOYW1lPzogc3RyaW5nLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbiB8IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUYXJnZXRUeXBlPiB7XG5cdGlmIChwYXRoID09PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRsZXQgdGFyZ2V0UGF0aDtcblx0aWYgKHBhdGhWaXNpdG9yKSB7XG5cdFx0dGFyZ2V0UGF0aCA9IHBhdGhWaXNpdG9yKHBhdGgpO1xuXHRcdGlmICh0YXJnZXRQYXRoID09PSB1bmRlZmluZWQpIHtcblx0XHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRjb25zdCBsb2NhbFBhdGggPSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLmNvbmNhdCgpO1xuXHRcdGxvY2FsUGF0aC5wdXNoKHBhdGgpO1xuXHRcdHRhcmdldFBhdGggPSBsb2NhbFBhdGguam9pbihcIi9cIik7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJQYXRoSW5Nb2RlbFwiLFxuXHRcdG1vZGVsTmFtZTogbW9kZWxOYW1lLFxuXHRcdHBhdGg6IHRhcmdldFBhdGhcblx0fTtcbn1cblxudHlwZSBQbGFpbkV4cHJlc3Npb25PYmplY3QgPSB7IFtpbmRleDogc3RyaW5nXTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+IH07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNvbnN0YW50IGV4cHJlc3Npb24gYmFzZWQgb24gYSBwcmltaXRpdmUgdmFsdWUuXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB2YWx1ZSBUaGUgY29uc3RhbnQgdG8gd3JhcCBpbiBhbiBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBUaGUgY29uc3RhbnQgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gY29uc3RhbnQ8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KHZhbHVlOiBUKTogQ29uc3RhbnRFeHByZXNzaW9uPFQ+IHtcblx0bGV0IGNvbnN0YW50VmFsdWU6IFQ7XG5cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0aWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG5cdFx0XHRjb25zdGFudFZhbHVlID0gdmFsdWUubWFwKHdyYXBQcmltaXRpdmUpIGFzIFQ7XG5cdFx0fSBlbHNlIGlmIChpc1ByaW1pdGl2ZU9iamVjdCh2YWx1ZSkpIHtcblx0XHRcdGNvbnN0YW50VmFsdWUgPSB2YWx1ZS52YWx1ZU9mKCkgYXMgVDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3RhbnRWYWx1ZSA9IE9iamVjdC5lbnRyaWVzKHZhbHVlKS5yZWR1Y2UoKHBsYWluRXhwcmVzc2lvbiwgW2tleSwgdmFsXSkgPT4ge1xuXHRcdFx0XHRjb25zdCB3cmFwcGVkVmFsdWUgPSB3cmFwUHJpbWl0aXZlKHZhbCk7XG5cdFx0XHRcdGlmICh3cmFwcGVkVmFsdWUuX3R5cGUgIT09IFwiQ29uc3RhbnRcIiB8fCB3cmFwcGVkVmFsdWUudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdHBsYWluRXhwcmVzc2lvbltrZXldID0gd3JhcHBlZFZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBwbGFpbkV4cHJlc3Npb247XG5cdFx0XHR9LCB7fSBhcyBQbGFpbkV4cHJlc3Npb25PYmplY3QpIGFzIFQ7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdGNvbnN0YW50VmFsdWUgPSB2YWx1ZTtcblx0fVxuXG5cdHJldHVybiB7IF90eXBlOiBcIkNvbnN0YW50XCIsIHZhbHVlOiBjb25zdGFudFZhbHVlIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQmluZGluZ1N0cmluZzxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHZhbHVlOiBzdHJpbmcgfCBib29sZWFuIHwgbnVtYmVyLFxuXHR0YXJnZXRUeXBlPzogc3RyaW5nXG4pOiBDb25zdGFudEV4cHJlc3Npb248VD4gfCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4gfCBFbWJlZGRlZFVJNUJpbmRpbmdFeHByZXNzaW9uPFQ+IHwgRW1iZWRkZWRVSTVFeHByZXNzaW9uQmluZGluZ0V4cHJlc3Npb248VD4ge1xuXHRpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgdmFsdWUuc3RhcnRzV2l0aChcIntcIikpIHtcblx0XHRjb25zdCBwYXRoSW5Nb2RlbFJlZ2V4ID0gL157KC4qKT4oLispfSQvOyAvLyBNYXRjaGVzIG1vZGVsIHBhdGhzIGxpa2UgXCJtb2RlbD5wYXRoXCIgb3IgXCI+cGF0aFwiIChkZWZhdWx0IG1vZGVsKVxuXHRcdGNvbnN0IHBhdGhJbk1vZGVsUmVnZXhNYXRjaCA9IHBhdGhJbk1vZGVsUmVnZXguZXhlYyh2YWx1ZSk7XG5cblx0XHRpZiAodmFsdWUuc3RhcnRzV2l0aChcIns9XCIpKSB7XG5cdFx0XHQvLyBFeHByZXNzaW9uIGJpbmRpbmcsIHdlIGNhbiBqdXN0IHJlbW92ZSB0aGUgb3V0ZXIgYmluZGluZyB0aGluZ3Ncblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdF90eXBlOiBcIkVtYmVkZGVkRXhwcmVzc2lvbkJpbmRpbmdcIixcblx0XHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0XHR9O1xuXHRcdH0gZWxzZSBpZiAocGF0aEluTW9kZWxSZWdleE1hdGNoKSB7XG5cdFx0XHRyZXR1cm4gcGF0aEluTW9kZWwocGF0aEluTW9kZWxSZWdleE1hdGNoWzJdIHx8IFwiXCIsIHBhdGhJbk1vZGVsUmVnZXhNYXRjaFsxXSB8fCB1bmRlZmluZWQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRfdHlwZTogXCJFbWJlZGRlZEJpbmRpbmdcIixcblx0XHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0XHR9O1xuXHRcdH1cblx0fSBlbHNlIGlmICh0YXJnZXRUeXBlID09PSBcImJvb2xlYW5cIiAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgKHZhbHVlID09PSBcInRydWVcIiB8fCB2YWx1ZSA9PT0gXCJmYWxzZVwiKSkge1xuXHRcdHJldHVybiBjb25zdGFudCh2YWx1ZSA9PT0gXCJ0cnVlXCIpIGFzIENvbnN0YW50RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmICh0YXJnZXRUeXBlID09PSBcIm51bWJlclwiICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAoIWlzTmFOKE51bWJlcih2YWx1ZSkpIHx8IHZhbHVlID09PSBcIk5hTlwiKSkge1xuXHRcdHJldHVybiBjb25zdGFudChOdW1iZXIodmFsdWUpKSBhcyBDb25zdGFudEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KHZhbHVlKSBhcyBDb25zdGFudEV4cHJlc3Npb248VD47XG5cdH1cbn1cblxuLyoqXG4gKiBBIG5hbWVkIHJlZmVyZW5jZS5cbiAqXG4gKiBAc2VlIGZuXG4gKiBAcGFyYW0gcmVmZXJlbmNlIFJlZmVyZW5jZVxuICogQHJldHVybnMgVGhlIG9iamVjdCByZWZlcmVuY2UgYmluZGluZyBwYXJ0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWYocmVmZXJlbmNlOiBzdHJpbmcgfCBudWxsKTogUmVmZXJlbmNlRXhwcmVzc2lvbiB7XG5cdHJldHVybiB7IF90eXBlOiBcIlJlZlwiLCByZWY6IHJlZmVyZW5jZSB9O1xufVxuXG4vKipcbiAqIFdyYXAgYSBwcmltaXRpdmUgaW50byBhIGNvbnN0YW50IGV4cHJlc3Npb24gaWYgaXQgaXMgbm90IGFscmVhZHkgYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHNvbWV0aGluZyBUaGUgb2JqZWN0IHRvIHdyYXAgaW4gYSBDb25zdGFudCBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBFaXRoZXIgdGhlIG9yaWdpbmFsIG9iamVjdCBvciB0aGUgd3JhcHBlZCBvbmUgZGVwZW5kaW5nIG9uIHRoZSBjYXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwUHJpbWl0aXZlPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihzb21ldGhpbmc6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGlmIChpc0JpbmRpbmdUb29sa2l0RXhwcmVzc2lvbihzb21ldGhpbmcpKSB7XG5cdFx0cmV0dXJuIHNvbWV0aGluZyBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH1cblxuXHRyZXR1cm4gY29uc3RhbnQoc29tZXRoaW5nKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgYSBiaW5kaW5nIHRvb2xpbmcgZXhwcmVzc2lvbiBvciBub3QuXG4gKlxuICogRXZlcnkgb2JqZWN0IGhhdmluZyBhIHByb3BlcnR5IG5hbWVkIGBfdHlwZWAgb2Ygc29tZSB2YWx1ZSBpcyBjb25zaWRlcmVkIGFuIGV4cHJlc3Npb24sIGV2ZW4gaWYgdGhlcmUgaXMgYWN0dWFsbHlcbiAqIG5vIHN1Y2ggZXhwcmVzc2lvbiB0eXBlIHN1cHBvcnRlZC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgYmluZGluZyB0b29sa2l0IGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uKFxuXHRleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj4gfCB1bmtub3duXG4pOiBleHByZXNzaW9uIGlzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPiB7XG5cdHJldHVybiAoZXhwcmVzc2lvbiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj4pPy5fdHlwZSAhPT0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBjb25zdGFudCBvciBub3QuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gIG1heWJlQ29uc3RhbnQgVGhlIGV4cHJlc3Npb24gb3IgcHJpbWl0aXZlIHZhbHVlIHRoYXQgaXMgdG8gYmUgY2hlY2tlZFxuICogQHJldHVybnMgYHRydWVgIGlmIGl0IGlzIGNvbnN0YW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbnN0YW50PFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihtYXliZUNvbnN0YW50OiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4pOiBtYXliZUNvbnN0YW50IGlzIENvbnN0YW50RXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiB0eXBlb2YgbWF5YmVDb25zdGFudCAhPT0gXCJvYmplY3RcIiB8fCAobWF5YmVDb25zdGFudCBhcyBCYXNlRXhwcmVzc2lvbjxUPikuX3R5cGUgPT09IFwiQ29uc3RhbnRcIjtcbn1cblxuZnVuY3Rpb24gaXNUcnVlKGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik6IGJvb2xlYW4ge1xuXHRyZXR1cm4gaXNDb25zdGFudChleHByZXNzaW9uKSAmJiBleHByZXNzaW9uLnZhbHVlID09PSB0cnVlO1xufVxuXG5mdW5jdGlvbiBpc0ZhbHNlKGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik6IGJvb2xlYW4ge1xuXHRyZXR1cm4gaXNDb25zdGFudChleHByZXNzaW9uKSAmJiBleHByZXNzaW9uLnZhbHVlID09PSBmYWxzZTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgYSBwYXRoIGluIG1vZGVsIGV4cHJlc3Npb24gb3Igbm90LlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtICBtYXliZUJpbmRpbmcgVGhlIGV4cHJlc3Npb24gb3IgcHJpbWl0aXZlIHZhbHVlIHRoYXQgaXMgdG8gYmUgY2hlY2tlZFxuICogQHJldHVybnMgYHRydWVgIGlmIGl0IGlzIGEgcGF0aCBpbiBtb2RlbCBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1BhdGhJbk1vZGVsRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdG1heWJlQmluZGluZzogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBtYXliZUJpbmRpbmcgaXMgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIChtYXliZUJpbmRpbmcgYXMgQmFzZUV4cHJlc3Npb248VD4pPy5fdHlwZSA9PT0gXCJQYXRoSW5Nb2RlbFwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBhIGNvbXBsZXggdHlwZSBleHByZXNzaW9uLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtICBtYXliZUJpbmRpbmcgVGhlIGV4cHJlc3Npb24gb3IgcHJpbWl0aXZlIHZhbHVlIHRoYXQgaXMgdG8gYmUgY2hlY2tlZFxuICogQHJldHVybnMgYHRydWVgIGlmIGl0IGlzIGEgcGF0aCBpbiBtb2RlbCBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdG1heWJlQmluZGluZzogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBtYXliZUJpbmRpbmcgaXMgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIChtYXliZUJpbmRpbmcgYXMgQmFzZUV4cHJlc3Npb248VD4pPy5fdHlwZSA9PT0gXCJDb21wbGV4VHlwZVwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBhIGNvbmNhdCBleHByZXNzaW9uIG9yIG5vdC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgQ29uY2F0RXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBpc0NvbmNhdEV4cHJlc3Npb24oZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KTogZXhwcmVzc2lvbiBpcyBDb25jYXRFeHByZXNzaW9uIHtcblx0cmV0dXJuIChleHByZXNzaW9uIGFzIEJhc2VFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KT8uX3R5cGUgPT09IFwiQ29uY2F0XCI7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBleHByZXNzaW9uIG9yIHZhbHVlIHByb3ZpZGVkIGlzIGEgSWZFbHNlIGV4cHJlc3Npb24gb3Igbm90LlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGV4cHJlc3Npb24gaXMgYSBJZkVsc2VFeHByZXNzaW9uXG4gKi9cbmZ1bmN0aW9uIGlzSWZFbHNlRXhwcmVzc2lvbihleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pOiBleHByZXNzaW9uIGlzIENvbmNhdEV4cHJlc3Npb24ge1xuXHRyZXR1cm4gKGV4cHJlc3Npb24gYXMgQmFzZUV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pPy5fdHlwZSA9PT0gXCJJZkVsc2VcIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gcHJvdmlkZWQgaXMgYSBjb21wYXJpc29uIG9yIG5vdC5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGV4cHJlc3Npb24gaXMgYSBDb21wYXJpc29uRXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBpc0NvbXBhcmlzb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPik6IGV4cHJlc3Npb24gaXMgQ29tcGFyaXNvbkV4cHJlc3Npb24ge1xuXHRyZXR1cm4gZXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJDb21wYXJpc29uXCI7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGlucHV0IHBhcmFtZXRlciBpcyBhIGNvbnN0YW50IGV4cHJlc3Npb24gb2YgdHlwZSB1bmRlZmluZWQuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGlucHV0IGV4cHJlc3Npb24gb3Igb2JqZWN0IGluIGdlbmVyYWxcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgaW5wdXQgaXMgY29uc3RhbnQgd2hpY2ggaGFzIHVuZGVmaW5lZCBmb3IgdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVW5kZWZpbmVkRXhwcmVzc2lvbihleHByZXNzaW9uOiB1bmtub3duKTogZXhwcmVzc2lvbiBpcyBDb25zdGFudEV4cHJlc3Npb248dW5kZWZpbmVkPiB7XG5cdGNvbnN0IGV4cHJlc3Npb25Bc0V4cHJlc3Npb24gPSBleHByZXNzaW9uIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPjtcblx0cmV0dXJuIGV4cHJlc3Npb25Bc0V4cHJlc3Npb24/Ll90eXBlID09PSBcIkNvbnN0YW50XCIgJiYgZXhwcmVzc2lvbkFzRXhwcmVzc2lvbj8udmFsdWUgPT09IHVuZGVmaW5lZDtcbn1cblxudHlwZSBDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb248UD4gPVxuXHR8IFBhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEFwcGx5QW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBJZkFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgT3JBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEFuZEFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgTmVBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEVxQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBOb3RBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEd0QW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBHZUFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgTGVBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEx0QW5ub3RhdGlvbkV4cHJlc3Npb248UD47XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlT2JqZWN0KG9iamVjdFR5cGU6IG9iamVjdCk6IGJvb2xlYW4ge1xuXHRzd2l0Y2ggKG9iamVjdFR5cGUuY29uc3RydWN0b3IubmFtZSkge1xuXHRcdGNhc2UgXCJTdHJpbmdcIjpcblx0XHRjYXNlIFwiTnVtYmVyXCI6XG5cdFx0Y2FzZSBcIkJvb2xlYW5cIjpcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cbi8qKlxuICogQ2hlY2sgaWYgdGhlIHBhc3NlZCBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZSBpcyBhIENvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSAgYW5ub3RhdGlvblZhbHVlIFRoZSBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZSB0byBldmFsdWF0ZVxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3QgaXMgYSB7Q29tcGxleEFubm90YXRpb25FeHByZXNzaW9ufVxuICovXG5mdW5jdGlvbiBpc0NvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbjxUPihhbm5vdGF0aW9uVmFsdWU6IFByb3BlcnR5QW5ub3RhdGlvblZhbHVlPFQ+KTogYW5ub3RhdGlvblZhbHVlIGlzIENvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiB0eXBlb2YgYW5ub3RhdGlvblZhbHVlID09PSBcIm9iamVjdFwiICYmICFpc1ByaW1pdGl2ZU9iamVjdChhbm5vdGF0aW9uVmFsdWUgYXMgb2JqZWN0KTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBhbm5vdGF0aW9uVmFsdWUgZm9yIGEgZ2l2ZW4gYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWUuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gYW5ub3RhdGlvblZhbHVlIFRoZSBzb3VyY2UgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWVcbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzIFRoZSBwYXRoIGZyb20gdGhlIHJvb3QgZW50aXR5IHNldFxuICogQHBhcmFtIGRlZmF1bHRWYWx1ZSBEZWZhdWx0IHZhbHVlIGlmIHRoZSBhbm5vdGF0aW9uVmFsdWUgaXMgdW5kZWZpbmVkXG4gKiBAcGFyYW0gcGF0aFZpc2l0b3IgQSBmdW5jdGlvbiB0byBtb2RpZnkgdGhlIHJlc3VsdGluZyBwYXRoXG4gKiBAcmV0dXJucyBUaGUgYW5ub3RhdGlvblZhbHVlIGVxdWl2YWxlbnQgdG8gdGhhdCBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0YW5ub3RhdGlvblZhbHVlOiBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxUPiB8IHVuZGVmaW5lZCxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0ZGVmYXVsdFZhbHVlPzogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZUNhc3Q8VD4+IHtcblx0aWYgKGFubm90YXRpb25WYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIHdyYXBQcmltaXRpdmUoZGVmYXVsdFZhbHVlIGFzIFByaW1pdGl2ZVR5cGVDYXN0PFQ+KTtcblx0fVxuXHRhbm5vdGF0aW9uVmFsdWUgPSBhbm5vdGF0aW9uVmFsdWU/LnZhbHVlT2YoKSBhcyBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxUPjtcblx0aWYgKCFpc0NvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbihhbm5vdGF0aW9uVmFsdWUpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGFubm90YXRpb25WYWx1ZSk7XG5cdH1cblxuXHRzd2l0Y2ggKGFubm90YXRpb25WYWx1ZS50eXBlKSB7XG5cdFx0Y2FzZSBcIlBhdGhcIjpcblx0XHRcdHJldHVybiBwYXRoSW5Nb2RlbChhbm5vdGF0aW9uVmFsdWUucGF0aCwgdW5kZWZpbmVkLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0Y2FzZSBcIklmXCI6XG5cdFx0XHRyZXR1cm4gYW5ub3RhdGlvbklmRXhwcmVzc2lvbihhbm5vdGF0aW9uVmFsdWUuSWYsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248XG5cdFx0XHRcdFByaW1pdGl2ZVR5cGVDYXN0PFQ+XG5cdFx0XHQ+O1xuXHRcdGNhc2UgXCJOb3RcIjpcblx0XHRcdHJldHVybiBub3QocGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5Ob3QsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFxuXHRcdFx0XHRQcmltaXRpdmVUeXBlQ2FzdDxUPlxuXHRcdFx0Pjtcblx0XHRjYXNlIFwiRXFcIjpcblx0XHRcdHJldHVybiBlcXVhbChcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5FcVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkVxWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiTmVcIjpcblx0XHRcdHJldHVybiBub3RFcXVhbChcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5OZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLk5lWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiR3RcIjpcblx0XHRcdHJldHVybiBncmVhdGVyVGhhbihcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5HdFswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkd0WzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiR2VcIjpcblx0XHRcdHJldHVybiBncmVhdGVyT3JFcXVhbChcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5HZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkdlWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiTHRcIjpcblx0XHRcdHJldHVybiBsZXNzVGhhbihcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5MdFswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkx0WzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiTGVcIjpcblx0XHRcdHJldHVybiBsZXNzT3JFcXVhbChcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5MZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkxlWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiT3JcIjpcblx0XHRcdHJldHVybiBvcihcblx0XHRcdFx0Li4uYW5ub3RhdGlvblZhbHVlLk9yLm1hcChmdW5jdGlvbiAob3JDb25kaXRpb24pIHtcblx0XHRcdFx0XHRyZXR1cm4gcGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uPGJvb2xlYW4+KG9yQ29uZGl0aW9uLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0XHRcdH0pXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkFuZFwiOlxuXHRcdFx0cmV0dXJuIGFuZChcblx0XHRcdFx0Li4uYW5ub3RhdGlvblZhbHVlLkFuZC5tYXAoZnVuY3Rpb24gKGFuZENvbmRpdGlvbikge1xuXHRcdFx0XHRcdHJldHVybiBwYXJzZUFubm90YXRpb25Db25kaXRpb248Ym9vbGVhbj4oYW5kQ29uZGl0aW9uLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0XHRcdH0pXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkFwcGx5XCI6XG5cdFx0XHRyZXR1cm4gYW5ub3RhdGlvbkFwcGx5RXhwcmVzc2lvbihcblx0XHRcdFx0YW5ub3RhdGlvblZhbHVlIGFzIEFwcGx5QW5ub3RhdGlvbkV4cHJlc3Npb248c3RyaW5nPixcblx0XHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdFx0cGF0aFZpc2l0b3Jcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0fVxuXHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcbn1cblxuLyoqXG4gKiBQYXJzZSB0aGUgYW5ub3RhdGlvbiBjb25kaXRpb24gaW50byBhbiBleHByZXNzaW9uLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGFubm90YXRpb25WYWx1ZSBUaGUgY29uZGl0aW9uIG9yIHZhbHVlIGZyb20gdGhlIGFubm90YXRpb25cbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzIFRoZSBwYXRoIGZyb20gdGhlIHJvb3QgZW50aXR5IHNldFxuICogQHBhcmFtIHBhdGhWaXNpdG9yIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgQW4gZXF1aXZhbGVudCBleHByZXNzaW9uXG4gKi9cbmZ1bmN0aW9uIHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGFubm90YXRpb25WYWx1ZTogQ29uZGl0aW9uYWxDaGVja09yVmFsdWUsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM6IHN0cmluZ1tdID0gW10sXG5cdHBhdGhWaXNpdG9yPzogRnVuY3Rpb25cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGlmIChhbm5vdGF0aW9uVmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIGFubm90YXRpb25WYWx1ZSAhPT0gXCJvYmplY3RcIikge1xuXHRcdHJldHVybiBjb25zdGFudChhbm5vdGF0aW9uVmFsdWUgYXMgVCk7XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJE9yXCIpKSB7XG5cdFx0cmV0dXJuIG9yKFxuXHRcdFx0Li4uKChhbm5vdGF0aW9uVmFsdWUgYXMgT3JDb25kaXRpb25hbEV4cHJlc3Npb24pLiRPci5tYXAoZnVuY3Rpb24gKG9yQ29uZGl0aW9uKSB7XG5cdFx0XHRcdHJldHVybiBwYXJzZUFubm90YXRpb25Db25kaXRpb24ob3JDb25kaXRpb24sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcblx0XHRcdH0pIGFzIHVua25vd24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+W10pXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEFuZFwiKSkge1xuXHRcdHJldHVybiBhbmQoXG5cdFx0XHQuLi4oKGFubm90YXRpb25WYWx1ZSBhcyBBbmRDb25kaXRpb25hbEV4cHJlc3Npb24pLiRBbmQubWFwKGZ1bmN0aW9uIChhbmRDb25kaXRpb24pIHtcblx0XHRcdFx0cmV0dXJuIHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbmRDb25kaXRpb24sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcblx0XHRcdH0pIGFzIHVua25vd24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+W10pXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJE5vdFwiKSkge1xuXHRcdHJldHVybiBub3QoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBOb3RDb25kaXRpb25hbEV4cHJlc3Npb24pLiROb3QsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRFcVwiKSkge1xuXHRcdHJldHVybiBlcXVhbChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEVxQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kRXFbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEVxQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kRXFbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiROZVwiKSkge1xuXHRcdHJldHVybiBub3RFcXVhbChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIE5lQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTmVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIE5lQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTmVbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRHdFwiKSkge1xuXHRcdHJldHVybiBncmVhdGVyVGhhbihcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEd0Q29uZGl0aW9uYWxFeHByZXNzaW9uKS4kR3RbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEd0Q29uZGl0aW9uYWxFeHByZXNzaW9uKS4kR3RbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRHZVwiKSkge1xuXHRcdHJldHVybiBncmVhdGVyT3JFcXVhbChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEdlQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kR2VbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEdlQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kR2VbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRMdFwiKSkge1xuXHRcdHJldHVybiBsZXNzVGhhbihcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEx0Q29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTHRbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEx0Q29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTHRbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRMZVwiKSkge1xuXHRcdHJldHVybiBsZXNzT3JFcXVhbChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIExlQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTGVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIExlQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTGVbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRQYXRoXCIpKSB7XG5cdFx0cmV0dXJuIHBhdGhJbk1vZGVsKChhbm5vdGF0aW9uVmFsdWUgYXMgUGF0aENvbmRpdGlvbkV4cHJlc3Npb248VD4pLiRQYXRoLCB1bmRlZmluZWQsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkQXBwbHlcIikpIHtcblx0XHRyZXR1cm4gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKFxuXHRcdFx0e1xuXHRcdFx0XHR0eXBlOiBcIkFwcGx5XCIsXG5cdFx0XHRcdEZ1bmN0aW9uOiAoYW5ub3RhdGlvblZhbHVlIGFzIHsgJEZ1bmN0aW9uPzogc3RyaW5nIH0pLiRGdW5jdGlvbixcblx0XHRcdFx0QXBwbHk6IChhbm5vdGF0aW9uVmFsdWUgYXMgeyAkQXBwbHk/OiB1bmtub3duIH0pLiRBcHBseVxuXHRcdFx0fSBhcyBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPFQ+LFxuXHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJElmXCIpKSB7XG5cdFx0cmV0dXJuIGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdHtcblx0XHRcdFx0dHlwZTogXCJJZlwiLFxuXHRcdFx0XHRJZjogKGFubm90YXRpb25WYWx1ZSBhcyB7ICRJZj86IHVua25vd24gfSkuJElmXG5cdFx0XHR9IGFzIElmQW5ub3RhdGlvbkV4cHJlc3Npb248VD4sXG5cdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0cGF0aFZpc2l0b3Jcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkRW51bU1lbWJlclwiKSkge1xuXHRcdHJldHVybiBjb25zdGFudChyZXNvbHZlRW51bVZhbHVlKChhbm5vdGF0aW9uVmFsdWUgYXMgeyAkRW51bU1lbWJlcj86IHN0cmluZyB9KS4kRW51bU1lbWJlcikgYXMgVCk7XG5cdH1cblx0cmV0dXJuIGNvbnN0YW50KGZhbHNlIGFzIFQpO1xufVxuXG4vKipcbiAqIFByb2Nlc3MgdGhlIHtJZkFubm90YXRpb25FeHByZXNzaW9uVmFsdWV9IGludG8gYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBhbm5vdGF0aW9uVmFsdWUgQW4gSWYgZXhwcmVzc2lvbiByZXR1cm5pbmcgdGhlIHR5cGUgVFxuICogQHBhcmFtIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMgVGhlIHBhdGggZnJvbSB0aGUgcm9vdCBlbnRpdHkgc2V0XG4gKiBAcGFyYW0gcGF0aFZpc2l0b3IgQSBmdW5jdGlvbiB0byBtb2RpZnkgdGhlIHJlc3VsdGluZyBwYXRoXG4gKiBAcmV0dXJucyBUaGUgZXF1aXZhbGVudCBpZkVsc2UgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5ub3RhdGlvbklmRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGFubm90YXRpb25WYWx1ZTogSWZBbm5vdGF0aW9uRXhwcmVzc2lvblZhbHVlPFQ+LFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4ge1xuXHRyZXR1cm4gaWZFbHNlKFxuXHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlWzFdIGFzIENvbmRpdGlvbmFsQ2hlY2tPclZhbHVlLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZVsyXSBhcyBDb25kaXRpb25hbENoZWNrT3JWYWx1ZSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdCk7XG59XG4vLyBUaGlzIHR5cGUgaXMgbm90IHJlY3Vyc2l2ZWx5IHRyYW5zZm9ybWVkIGZyb20gdGhlIG1ldGFtb2RlbCBjb250ZW50LCBhcyBzdWNoIHdlIGhhdmUgc29tZSB1Z2x5IHRoaW5ncyB0aGVyZVxudHlwZSBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5mdW5jdGlvbiBjb252ZXJ0U3ViQXBwbHlQYXJhbWV0ZXJzKGFwcGx5UGFyYW06IFN1YkFwcGx5RXhwcmVzc2lvbkZyb21NZXRhbW9kZWwpOiBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsIHtcblx0bGV0IGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSBhcHBseVBhcmFtO1xuXHRpZiAoYXBwbHlQYXJhbS5oYXNPd25Qcm9wZXJ0eShcIiRQYXRoXCIpKSB7XG5cdFx0YXBwbHlQYXJhbUNvbnZlcnRlZCA9IHtcblx0XHRcdHR5cGU6IFwiUGF0aFwiLFxuXHRcdFx0cGF0aDogYXBwbHlQYXJhbS4kUGF0aFxuXHRcdH0gYXMgUGF0aEFubm90YXRpb25FeHByZXNzaW9uPHN0cmluZz47XG5cdH0gZWxzZSBpZiAoYXBwbHlQYXJhbS5oYXNPd25Qcm9wZXJ0eShcIiRJZlwiKSkge1xuXHRcdGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSB7XG5cdFx0XHR0eXBlOiBcIklmXCIsXG5cdFx0XHRJZjogYXBwbHlQYXJhbS4kSWZcblx0XHR9IGFzIElmQW5ub3RhdGlvbkV4cHJlc3Npb248c3RyaW5nPjtcblx0fSBlbHNlIGlmIChhcHBseVBhcmFtLmhhc093blByb3BlcnR5KFwiJEFwcGx5XCIpKSB7XG5cdFx0YXBwbHlQYXJhbUNvbnZlcnRlZCA9IHtcblx0XHRcdHR5cGU6IFwiQXBwbHlcIixcblx0XHRcdEZ1bmN0aW9uOiBhcHBseVBhcmFtLiRGdW5jdGlvbixcblx0XHRcdEFwcGx5OiBhcHBseVBhcmFtLiRBcHBseVxuXHRcdH0gYXMgQXBwbHlBbm5vdGF0aW9uRXhwcmVzc2lvbjxzdHJpbmc+O1xuXHR9XG5cdHJldHVybiBhcHBseVBhcmFtQ29udmVydGVkO1xufVxuXG50eXBlIE9EYXRhRnVuY3Rpb24gPSBcIm9kYXRhLmNvbmNhdFwiIHwgXCJvZGF0YS5maWxsVXJpVGVtcGxhdGVcIiB8IFwib2RhdGEudXJpRW5jb2RlXCI7XG5leHBvcnQgZnVuY3Rpb24gYW5ub3RhdGlvbkFwcGx5RXhwcmVzc2lvbihcblx0YXBwbHlFeHByZXNzaW9uOiBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPHN0cmluZz4sXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM6IHN0cmluZ1tdID0gW10sXG5cdHBhdGhWaXNpdG9yPzogRnVuY3Rpb25cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxzdHJpbmc+IHtcblx0c3dpdGNoIChhcHBseUV4cHJlc3Npb24uRnVuY3Rpb24gYXMgT0RhdGFGdW5jdGlvbikge1xuXHRcdGNhc2UgXCJvZGF0YS5jb25jYXRcIjpcblx0XHRcdHJldHVybiBjb25jYXQoXG5cdFx0XHRcdC4uLmFwcGx5RXhwcmVzc2lvbi5BcHBseS5tYXAoKGFwcGx5UGFyYW0pID0+IHtcblx0XHRcdFx0XHRyZXR1cm4gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKFxuXHRcdFx0XHRcdFx0Y29udmVydFN1YkFwcGx5UGFyYW1ldGVycyhhcHBseVBhcmFtKSBhcyBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxzdHJpbmc+LFxuXHRcdFx0XHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdFx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdFx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0Y2FzZSBcIm9kYXRhLnVyaUVuY29kZVwiOlxuXHRcdFx0Y29uc3QgcGFyYW1ldGVyID0gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKFxuXHRcdFx0XHRjb252ZXJ0U3ViQXBwbHlQYXJhbWV0ZXJzKFxuXHRcdFx0XHRcdGFwcGx5RXhwcmVzc2lvbi5BcHBseVswXSBhcyB1bmtub3duIGFzIFN1YkFwcGx5RXhwcmVzc2lvbkZyb21NZXRhbW9kZWxcblx0XHRcdFx0KSBhcyBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxzdHJpbmc+LFxuXHRcdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0XHQpO1xuXHRcdFx0Ly8gVGhlIHNlY29uZCBwYXJhbWV0ZXIgZm9yIHVyaUVuY29kZSBpcyBhbHdheXMgYSBzdHJpbmcgc2luY2UgdGhlIHRhcmdldCBldmFsdWF0aW9uIGlzIGFnYWluc3QgYSBmb3JtYXRWYWx1ZSBjYWxsIGluIE9EYXRhVXRpbHMgd2hpY2ggZXhwZWN0IHRoZSB0YXJnZXQgdHlwZSBhcyBzZWNvbmQgcGFyYW1ldGVyXG5cdFx0XHRyZXR1cm4gZm4oXCJvZGF0YS51cmlFbmNvZGVcIiwgW3BhcmFtZXRlciwgXCJFZG0uU3RyaW5nXCJdLCB1bmRlZmluZWQsIHRydWUpO1xuXHRcdGNhc2UgXCJvZGF0YS5maWxsVXJpVGVtcGxhdGVcIjpcblx0XHRcdGNvbnN0IHRlbXBsYXRlID0gYXBwbHlFeHByZXNzaW9uLkFwcGx5WzBdO1xuXHRcdFx0Y29uc3QgdGVtcGxhdGVQYXJhbXMgPSBhcHBseUV4cHJlc3Npb24uQXBwbHkuc2xpY2UoMSkgYXMgdW5rbm93biBhcyBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsW107XG5cdFx0XHRjb25zdCB0YXJnZXRPYmplY3Q6IFJlY29yZDxzdHJpbmcsIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPj4gPSB7fTtcblx0XHRcdHRlbXBsYXRlUGFyYW1zLmZvckVhY2goKGFwcGx5UGFyYW0pID0+IHtcblx0XHRcdFx0dGFyZ2V0T2JqZWN0W2FwcGx5UGFyYW0uJE5hbWUgYXMgc3RyaW5nXSA9IGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdFx0XHRjb252ZXJ0U3ViQXBwbHlQYXJhbWV0ZXJzKFxuXHRcdFx0XHRcdFx0YXBwbHlQYXJhbS4kTGFiZWxlZEVsZW1lbnQgYXMgU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbFxuXHRcdFx0XHRcdCkgYXMgUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8c3RyaW5nPixcblx0XHRcdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdFx0XHRwYXRoVmlzaXRvclxuXHRcdFx0XHQpO1xuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gZm4oXCJvZGF0YS5maWxsVXJpVGVtcGxhdGVcIiwgW3RlbXBsYXRlLCB0YXJnZXRPYmplY3RdLCB1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xufVxuXG4vKipcbiAqIEdlbmVyaWMgaGVscGVyIGZvciB0aGUgY29tcGFyaXNvbiBvcGVyYXRpb25zIChlcXVhbCwgbm90RXF1YWwsIC4uLikuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gb3BlcmF0b3IgVGhlIG9wZXJhdG9yIHRvIGFwcGx5XG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZSBvZiB0aGUgb3BlcmF0b3JcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIG9wZXJhdG9yXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5mdW5jdGlvbiBjb21wYXJpc29uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0b3BlcmF0b3I6IENvbXBhcmlzb25PcGVyYXRvcixcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGNvbnN0IGxlZnRFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShsZWZ0T3BlcmFuZCk7XG5cdGNvbnN0IHJpZ2h0RXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUocmlnaHRPcGVyYW5kKTtcblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24obGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoaXNDb25zdGFudChsZWZ0RXhwcmVzc2lvbikgJiYgaXNDb25zdGFudChyaWdodEV4cHJlc3Npb24pKSB7XG5cdFx0c3dpdGNoIChvcGVyYXRvcikge1xuXHRcdFx0Y2FzZSBcIiE9PVwiOlxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgIT09IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPT09XCI6XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHRcdGNhc2UgXCI8XCI6XG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA8IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPD1cIjpcblx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZCB8fFxuXHRcdFx0XHRcdHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiBjb25zdGFudChmYWxzZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlIDw9IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPlwiOlxuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWRcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPiByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIj49XCI6XG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA+PSByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0X3R5cGU6IFwiQ29tcGFyaXNvblwiLFxuXHRcdFx0b3BlcmF0b3I6IG9wZXJhdG9yLFxuXHRcdFx0b3BlcmFuZDE6IGxlZnRFeHByZXNzaW9uLFxuXHRcdFx0b3BlcmFuZDI6IHJpZ2h0RXhwcmVzc2lvblxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBHZW5lcmljIGhlbHBlciBmb3IgdGhlIGxlbmd0aCBvZiBhbiBleHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBpbnB1dCBleHByZXNzaW9uIHBvaW50aW5nIHRvIGFuIGFycmF5XG4gKiBAcGFyYW0gY2hlY2tVbmRlZmluZWQgSXMgdGhlIGFycmF5IHBvdGVudGlhbGx5IHVuZGVmaW5lZFxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGxlbmd0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gbGVuZ3RoKFxuXHRleHByZXNzaW9uOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248dW5rbm93bj4gfCBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbixcblx0Y2hlY2tVbmRlZmluZWQgPSBmYWxzZVxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPG51bWJlcj4ge1xuXHRpZiAoZXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJVbnJlc29sdmFibGVcIikge1xuXHRcdHJldHVybiBleHByZXNzaW9uO1xuXHR9XG5cdGlmICghY2hlY2tVbmRlZmluZWQpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0X3R5cGU6IFwiTGVuZ3RoXCIsXG5cdFx0XHRwYXRoSW5Nb2RlbDogZXhwcmVzc2lvblxuXHRcdH07XG5cdH1cblx0cmV0dXJuIGlmRWxzZShlcXVhbChleHByZXNzaW9uLCB1bmRlZmluZWQpLCAtMSwgbGVuZ3RoKGV4cHJlc3Npb24pKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImVxdWFsXCIgKD09PSkuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZVxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgY29tcGFyaXNvblxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVxdWFsPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGNvbnN0IGxlZnRFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShsZWZ0T3BlcmFuZCk7XG5cdGNvbnN0IHJpZ2h0RXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUocmlnaHRPcGVyYW5kKTtcblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24obGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChsZWZ0RXhwcmVzc2lvbiwgcmlnaHRFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBjb25zdGFudCh0cnVlKTtcblx0fVxuXG5cdGZ1bmN0aW9uIHJlZHVjZShsZWZ0OiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sIHJpZ2h0OiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4gfCB1bmRlZmluZWQge1xuXHRcdGlmIChsZWZ0Ll90eXBlID09PSBcIkNvbXBhcmlzb25cIiAmJiBpc1RydWUocmlnaHQpKSB7XG5cdFx0XHQvLyBjb21wYXJlKGEsIGIpID09PSB0cnVlIH5+PiBjb21wYXJlKGEsIGIpXG5cdFx0XHRyZXR1cm4gbGVmdDtcblx0XHR9IGVsc2UgaWYgKGxlZnQuX3R5cGUgPT09IFwiQ29tcGFyaXNvblwiICYmIGlzRmFsc2UocmlnaHQpKSB7XG5cdFx0XHQvLyBjb21wYXJlKGEsIGIpID09PSBmYWxzZSB+fj4gIWNvbXBhcmUoYSwgYilcblx0XHRcdHJldHVybiBub3QobGVmdCk7XG5cdFx0fSBlbHNlIGlmIChsZWZ0Ll90eXBlID09PSBcIklmRWxzZVwiICYmIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwobGVmdC5vblRydWUsIHJpZ2h0KSkge1xuXHRcdFx0Ly8gKGlmICh4KSB7IGEgfSBlbHNlIHsgYiB9KSA9PT0gYSB+fj4geCB8fCAoYiA9PT0gYSlcblx0XHRcdHJldHVybiBvcihsZWZ0LmNvbmRpdGlvbiwgZXF1YWwobGVmdC5vbkZhbHNlLCByaWdodCkpO1xuXHRcdH0gZWxzZSBpZiAobGVmdC5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25GYWxzZSwgcmlnaHQpKSB7XG5cdFx0XHQvLyAoaWYgKHgpIHsgYSB9IGVsc2UgeyBiIH0pID09PSBiIH5+PiAheCB8fCAoYSA9PT0gYilcblx0XHRcdHJldHVybiBvcihub3QobGVmdC5jb25kaXRpb24pLCBlcXVhbChsZWZ0Lm9uVHJ1ZSwgcmlnaHQpKTtcblx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0bGVmdC5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJlxuXHRcdFx0aXNDb25zdGFudChsZWZ0Lm9uVHJ1ZSkgJiZcblx0XHRcdGlzQ29uc3RhbnQobGVmdC5vbkZhbHNlKSAmJlxuXHRcdFx0aXNDb25zdGFudChyaWdodCkgJiZcblx0XHRcdCFfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25UcnVlLCByaWdodCkgJiZcblx0XHRcdCFfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25GYWxzZSwgcmlnaHQpXG5cdFx0KSB7XG5cdFx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHRcdH1cblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cblx0Ly8gZXhwbG9pdCBzeW1tZXRyeTogYSA9PT0gYiA8fj4gYiA9PT0gYVxuXHRjb25zdCByZWR1Y2VkID0gcmVkdWNlKGxlZnRFeHByZXNzaW9uLCByaWdodEV4cHJlc3Npb24pID8/IHJlZHVjZShyaWdodEV4cHJlc3Npb24sIGxlZnRFeHByZXNzaW9uKTtcblx0cmV0dXJuIHJlZHVjZWQgPz8gY29tcGFyaXNvbihcIj09PVwiLCBsZWZ0RXhwcmVzc2lvbiwgcmlnaHRFeHByZXNzaW9uKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcIm5vdCBlcXVhbFwiICghPT0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3RFcXVhbDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRyZXR1cm4gbm90KGVxdWFsKGxlZnRPcGVyYW5kLCByaWdodE9wZXJhbmQpKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImdyZWF0ZXIgb3IgZXF1YWxcIiAoPj0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBncmVhdGVyT3JFcXVhbDxUIGV4dGVuZHMgRGVmaW5lZFByaW1pdGl2ZVR5cGU+KFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0cmV0dXJuIGNvbXBhcmlzb24oXCI+PVwiLCBsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImdyZWF0ZXIgdGhhblwiICg+KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JlYXRlclRoYW48VCBleHRlbmRzIERlZmluZWRQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPlwiLCBsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImxlc3Mgb3IgZXF1YWxcIiAoPD0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsZXNzT3JFcXVhbDxUIGV4dGVuZHMgRGVmaW5lZFByaW1pdGl2ZVR5cGU+KFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0cmV0dXJuIGNvbXBhcmlzb24oXCI8PVwiLCBsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImxlc3MgdGhhblwiICg8KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gbGVzc1RoYW48VCBleHRlbmRzIERlZmluZWRQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPFwiLCBsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKTtcbn1cblxuLyoqXG4gKiBJZi10aGVuLWVsc2UgZXhwcmVzc2lvbi5cbiAqXG4gKiBFdmFsdWF0ZXMgdG8gb25UcnVlIGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIHRydWUsIGVsc2UgZXZhbHVhdGVzIHRvIG9uRmFsc2UuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gY29uZGl0aW9uIFRoZSBjb25kaXRpb24gdG8gZXZhbHVhdGVcbiAqIEBwYXJhbSBvblRydWUgRXhwcmVzc2lvbiByZXN1bHQgaWYgdGhlIGNvbmRpdGlvbiBldmFsdWF0ZXMgdG8gdHJ1ZVxuICogQHBhcmFtIG9uRmFsc2UgRXhwcmVzc2lvbiByZXN1bHQgaWYgdGhlIGNvbmRpdGlvbiBldmFsdWF0ZXMgdG8gZmFsc2VcbiAqIEByZXR1cm5zIFRoZSBleHByZXNzaW9uIHRoYXQgcmVwcmVzZW50cyB0aGlzIGNvbmRpdGlvbmFsIGNoZWNrXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpZkVsc2U8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRjb25kaXRpb246IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPixcblx0b25UcnVlOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdG9uRmFsc2U6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHtcblx0bGV0IGNvbmRpdGlvbkV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKGNvbmRpdGlvbik7XG5cdGxldCBvblRydWVFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShvblRydWUpO1xuXHRsZXQgb25GYWxzZUV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKG9uRmFsc2UpO1xuXG5cdC8vIHN3YXAgYnJhbmNoZXMgaWYgdGhlIGNvbmRpdGlvbiBpcyBhIG5lZ2F0aW9uXG5cdGlmIChjb25kaXRpb25FeHByZXNzaW9uLl90eXBlID09PSBcIk5vdFwiKSB7XG5cdFx0Ly8gaWZFbHNlKG5vdChYKSwgYSwgYikgLS0+IGlmRWxzZShYLCBiLCBhKVxuXHRcdFtvblRydWVFeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbl0gPSBbb25GYWxzZUV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb25dO1xuXHRcdGNvbmRpdGlvbkV4cHJlc3Npb24gPSBub3QoY29uZGl0aW9uRXhwcmVzc2lvbik7XG5cdH1cblxuXHQvLyBpbmxpbmUgbmVzdGVkIGlmLWVsc2UgZXhwcmVzc2lvbnM6IG9uVHJ1ZSBicmFuY2hcblx0Ly8gaWZFbHNlKFgsIGlmRWxzZShYLCBhLCBiKSwgYykgPT0+IGlmRWxzZShYLCBhLCBjKVxuXHRpZiAob25UcnVlRXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb24uY29uZGl0aW9uKSkge1xuXHRcdG9uVHJ1ZUV4cHJlc3Npb24gPSBvblRydWVFeHByZXNzaW9uLm9uVHJ1ZTtcblx0fVxuXG5cdC8vIGlubGluZSBuZXN0ZWQgaWYtZWxzZSBleHByZXNzaW9uczogb25GYWxzZSBicmFuY2hcblx0Ly8gaWZFbHNlKFgsIGEsIGlmRWxzZShYLCBiLCBjKSkgPT0+IGlmRWxzZShYLCBhLCBjKVxuXHRpZiAob25GYWxzZUV4cHJlc3Npb24uX3R5cGUgPT09IFwiSWZFbHNlXCIgJiYgX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChjb25kaXRpb25FeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbi5jb25kaXRpb24pKSB7XG5cdFx0b25GYWxzZUV4cHJlc3Npb24gPSBvbkZhbHNlRXhwcmVzc2lvbi5vbkZhbHNlO1xuXHR9XG5cblx0Ly8gKGlmIHRydWUgdGhlbiBhIGVsc2UgYikgIH5+PiBhXG5cdC8vIChpZiBmYWxzZSB0aGVuIGEgZWxzZSBiKSB+fj4gYlxuXHRpZiAoaXNDb25zdGFudChjb25kaXRpb25FeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBjb25kaXRpb25FeHByZXNzaW9uLnZhbHVlID8gb25UcnVlRXhwcmVzc2lvbiA6IG9uRmFsc2VFeHByZXNzaW9uO1xuXHR9XG5cblx0Ly8gaWYgKGlzQ29uc3RhbnRCb29sZWFuKG9uVHJ1ZUV4cHJlc3Npb24pIHx8IGlzQ29uc3RhbnRCb29sZWFuKG9uRmFsc2VFeHByZXNzaW9uKSkge1xuXHQvLyBcdHJldHVybiBvcihhbmQoY29uZGl0aW9uLCBvblRydWVFeHByZXNzaW9uIGFzIEV4cHJlc3Npb248Ym9vbGVhbj4pLCBhbmQobm90KGNvbmRpdGlvbiksIG9uRmFsc2VFeHByZXNzaW9uIGFzIEV4cHJlc3Npb248Ym9vbGVhbj4pKSBhcyBFeHByZXNzaW9uPFQ+XG5cdC8vIH1cblxuXHQvLyAoaWYgWCB0aGVuIGEgZWxzZSBhKSB+fj4gYVxuXHRpZiAoX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChvblRydWVFeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gb25UcnVlRXhwcmVzc2lvbjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiBhIGVsc2UgZmFsc2Ugfn4+IFggJiYgYVxuXHRpZiAoaXNGYWxzZShvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gYW5kKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH1cblxuXHQvLyBpZiBYIHRoZW4gYSBlbHNlIHRydWUgfn4+ICFYIHx8IGFcblx0aWYgKGlzVHJ1ZShvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gb3Iobm90KGNvbmRpdGlvbkV4cHJlc3Npb24pLCBvblRydWVFeHByZXNzaW9uIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPikgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9XG5cblx0Ly8gaWYgWCB0aGVuIGZhbHNlIGVsc2UgYSB+fj4gIVggJiYgYVxuXHRpZiAoaXNGYWxzZShvblRydWVFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBhbmQobm90KGNvbmRpdGlvbkV4cHJlc3Npb24pLCBvbkZhbHNlRXhwcmVzc2lvbiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4pIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiB0cnVlIGVsc2UgYSB+fj4gWCB8fCBhXG5cdGlmIChpc1RydWUob25UcnVlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gb3IoY29uZGl0aW9uRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH1cblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24oY29uZGl0aW9uRXhwcmVzc2lvbiwgb25UcnVlRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0aWYgKGlzQ29tcGxleFR5cGVFeHByZXNzaW9uKGNvbmRpdGlvbikgfHwgaXNDb21wbGV4VHlwZUV4cHJlc3Npb24ob25UcnVlKSB8fCBpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbihvbkZhbHNlKSkge1xuXHRcdGxldCBwYXRoSWR4ID0gMDtcblx0XHRjb25zdCBteUlmRWxzZUV4cHJlc3Npb24gPSBmb3JtYXRSZXN1bHQoW2NvbmRpdGlvbiwgb25UcnVlLCBvbkZhbHNlXSwgXCJzYXAuZmUuY29yZS5mb3JtYXR0ZXJzLlN0YW5kYXJkRm9ybWF0dGVyI2lmRWxzZVwiKTtcblx0XHRjb25zdCBhbGxQYXJ0cyA9IFtdO1xuXHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0bXlJZkVsc2VFeHByZXNzaW9uLFxuXHRcdFx0XCJQYXRoSW5Nb2RlbFwiLFxuXHRcdFx0KGNvbnN0YW50UGF0aDogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+KSA9PiB7XG5cdFx0XHRcdGFsbFBhcnRzLnB1c2goY29uc3RhbnRQYXRoKTtcblx0XHRcdFx0cmV0dXJuIHBhdGhJbk1vZGVsKGAkJHtwYXRoSWR4Kyt9YCwgXCIkXCIpO1xuXHRcdFx0fSxcblx0XHRcdHRydWVcblx0XHQpO1xuXHRcdGFsbFBhcnRzLnVuc2hpZnQoY29uc3RhbnQoSlNPTi5zdHJpbmdpZnkobXlJZkVsc2VFeHByZXNzaW9uKSkpO1xuXHRcdHJldHVybiBmb3JtYXRSZXN1bHQoYWxsUGFydHMsIFwic2FwLmZlLmNvcmUuZm9ybWF0dGVycy5TdGFuZGFyZEZvcm1hdHRlciNldmFsdWF0ZUNvbXBsZXhFeHByZXNzaW9uXCIsIHVuZGVmaW5lZCwgdHJ1ZSk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJJZkVsc2VcIixcblx0XHRjb25kaXRpb246IGNvbmRpdGlvbkV4cHJlc3Npb24sXG5cdFx0b25UcnVlOiBvblRydWVFeHByZXNzaW9uLFxuXHRcdG9uRmFsc2U6IG9uRmFsc2VFeHByZXNzaW9uXG5cdH07XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGN1cnJlbnQgZXhwcmVzc2lvbiBoYXMgYSByZWZlcmVuY2UgdG8gdGhlIGRlZmF1bHQgbW9kZWwgKHVuZGVmaW5lZCkuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gZXZhbHVhdGVcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGVyZSBpcyBhIHJlZmVyZW5jZSB0byB0aGUgZGVmYXVsdCBjb250ZXh0XG4gKi9cbmZ1bmN0aW9uIGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+KTogYm9vbGVhbiB7XG5cdHN3aXRjaCAoZXhwcmVzc2lvbi5fdHlwZSkge1xuXHRcdGNhc2UgXCJDb25zdGFudFwiOlxuXHRcdGNhc2UgXCJGb3JtYXR0ZXJcIjpcblx0XHRjYXNlIFwiQ29tcGxleFR5cGVcIjpcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRjYXNlIFwiU2V0XCI6XG5cdFx0XHRyZXR1cm4gZXhwcmVzc2lvbi5vcGVyYW5kcy5zb21lKGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQpO1xuXHRcdGNhc2UgXCJQYXRoSW5Nb2RlbFwiOlxuXHRcdFx0cmV0dXJuIGV4cHJlc3Npb24ubW9kZWxOYW1lID09PSB1bmRlZmluZWQ7XG5cdFx0Y2FzZSBcIkNvbXBhcmlzb25cIjpcblx0XHRcdHJldHVybiBoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24ub3BlcmFuZDEpIHx8IGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5vcGVyYW5kMik7XG5cdFx0Y2FzZSBcIklmRWxzZVwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0aGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLmNvbmRpdGlvbikgfHxcblx0XHRcdFx0aGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLm9uVHJ1ZSkgfHxcblx0XHRcdFx0aGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLm9uRmFsc2UpXG5cdFx0XHQpO1xuXHRcdGNhc2UgXCJOb3RcIjpcblx0XHRjYXNlIFwiVHJ1dGh5XCI6XG5cdFx0XHRyZXR1cm4gaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLm9wZXJhbmQpO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cblxuLy8gVGhpcyBpcyBvbmUgY2FzZSB3aGVyZSBhbnkgZG9lcyBtYWtlIHNlbnNlLi4uXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuZXhwb3J0IHR5cGUgRm48VD4gPSAoKC4uLnBhcmFtczogYW55KSA9PiBUIHwgUHJvbWlzZTxUPikgJiB7XG5cdF9fZnVuY3Rpb25OYW1lOiBzdHJpbmc7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIFdyYXBwZWRUdXBsZVxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4vLyBAdHMtaWdub3JlXG50eXBlIFdyYXBwZWRUdXBsZTxUPiA9IHsgW0sgaW4ga2V5b2YgVF06IFdyYXBwZWRUdXBsZTxUW0tdPiB8IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUW0tdPiB8IHVuZGVmaW5lZCB9O1xuXG4vLyBTbywgdGhpcyB3b3JrcyBidXQgSSBjYW5ub3QgZ2V0IGl0IHRvIGNvbXBpbGUgOkQsIGJ1dCBpdCBzdGlsbCBkb2VzIHdoYXQgaXMgZXhwZWN0ZWQuLi5cblxuLyoqXG4gKiBBIGZ1bmN0aW9uIHJlZmVyZW5jZSBvciBhIGZ1bmN0aW9uIG5hbWUuXG4gKi9cbnR5cGUgRnVuY3Rpb25Pck5hbWU8VD4gPSBGbjxUPiB8IHN0cmluZztcblxuLyoqXG4gKiBGdW5jdGlvbiBwYXJhbWV0ZXJzLCBlaXRoZXIgZGVyaXZlZCBmcm9tIHRoZSBmdW5jdGlvbiBvciBhbiB1bnR5cGVkIGFycmF5LlxuICovXG50eXBlIEZ1bmN0aW9uUGFyYW1ldGVyczxULCBGIGV4dGVuZHMgRnVuY3Rpb25Pck5hbWU8VD4+ID0gRiBleHRlbmRzIEZuPFQ+ID8gUGFyYW1ldGVyczxGPiA6IHVua25vd25bXTtcblxuLyoqXG4gKiBDYWxscyBhIGZvcm1hdHRlciBmdW5jdGlvbiB0byBwcm9jZXNzIHRoZSBwYXJhbWV0ZXJzLlxuICogSWYgcmVxdWlyZUNvbnRleHQgaXMgc2V0IHRvIHRydWUgYW5kIG5vIGNvbnRleHQgaXMgcGFzc2VkIGEgZGVmYXVsdCBjb250ZXh0IHdpbGwgYmUgYWRkZWQgYXV0b21hdGljYWxseS5cbiAqXG4gKiBAdGVtcGxhdGUgVFxuICogQHRlbXBsYXRlIFVcbiAqIEBwYXJhbSBwYXJhbWV0ZXJzIFRoZSBsaXN0IG9mIHBhcmFtZXRlciB0aGF0IHNob3VsZCBtYXRjaCB0aGUgdHlwZSBhbmQgbnVtYmVyIG9mIHRoZSBmb3JtYXR0ZXIgZnVuY3Rpb25cbiAqIEBwYXJhbSBmb3JtYXR0ZXJGdW5jdGlvbiBUaGUgZnVuY3Rpb24gdG8gY2FsbFxuICogQHBhcmFtIFtjb250ZXh0RW50aXR5VHlwZV0gSWYgbm8gcGFyYW1ldGVyIHJlZmVycyB0byB0aGUgY29udGV4dCB0aGVuIHdlIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGFkZCBhIHJlZmVyZW5jZSB0byB0aGUga2V5cyBmcm9tIHRoZSBlbnRpdHkgdHlwZS5cbiAqIEBwYXJhbSBbaWdub3JlQ29tcGxleFR5cGVdIFdoZXRoZXIgdG8gaWdub3JlIHRoZSB0cmFuc2dmb3JtYXRpb24gdG8gdGhlIFN0YW5kYXJkRm9ybWF0dGVyIG9yIG5vdFxuICogQHJldHVybnMgVGhlIGNvcnJlc3BvbmRpbmcgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0UmVzdWx0PFQsIFUgZXh0ZW5kcyBGbjxUPj4oXG5cdHBhcmFtZXRlcnM6IFdyYXBwZWRUdXBsZTxQYXJhbWV0ZXJzPFU+Pixcblx0Zm9ybWF0dGVyRnVuY3Rpb246IFUgfCBzdHJpbmcsXG5cdGNvbnRleHRFbnRpdHlUeXBlPzogRW50aXR5VHlwZSxcblx0aWdub3JlQ29tcGxleFR5cGUgPSBmYWxzZVxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHtcblx0Y29uc3QgcGFyYW1ldGVyRXhwcmVzc2lvbnMgPSAocGFyYW1ldGVycyBhcyBFeHByZXNzaW9uT3JQcmltaXRpdmU8UHJpbWl0aXZlVHlwZT5bXSkubWFwKHdyYXBQcmltaXRpdmUpO1xuXG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLnBhcmFtZXRlckV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGlmIChjb250ZXh0RW50aXR5VHlwZSkge1xuXHRcdC8vIE90aGVyd2lzZSwgaWYgdGhlIGNvbnRleHQgaXMgcmVxdWlyZWQgYW5kIG5vIGNvbnRleHQgaXMgcHJvdmlkZWQgbWFrZSBzdXJlIHRvIGFkZCB0aGUgZGVmYXVsdCBiaW5kaW5nXG5cdFx0aWYgKCFwYXJhbWV0ZXJFeHByZXNzaW9ucy5zb21lKGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQpKSB7XG5cdFx0XHRjb250ZXh0RW50aXR5VHlwZS5rZXlzLmZvckVhY2goKGtleSkgPT4gcGFyYW1ldGVyRXhwcmVzc2lvbnMucHVzaChwYXRoSW5Nb2RlbChrZXkubmFtZSwgXCJcIikpKTtcblx0XHR9XG5cdH1cblx0bGV0IGZ1bmN0aW9uTmFtZSA9IFwiXCI7XG5cdGlmICh0eXBlb2YgZm9ybWF0dGVyRnVuY3Rpb24gPT09IFwic3RyaW5nXCIpIHtcblx0XHRmdW5jdGlvbk5hbWUgPSBmb3JtYXR0ZXJGdW5jdGlvbjtcblx0fSBlbHNlIHtcblx0XHRmdW5jdGlvbk5hbWUgPSBmb3JtYXR0ZXJGdW5jdGlvbi5fX2Z1bmN0aW9uTmFtZTtcblx0fVxuXHQvLyBGb3JtYXR0ZXJOYW1lIGNhbiBiZSBvZiBmb3JtYXQgc2FwLmZlLmNvcmUueHh4I21ldGhvZE5hbWUgdG8gaGF2ZSBtdWx0aXBsZSBmb3JtYXR0ZXIgaW4gb25lIGNsYXNzXG5cdGNvbnN0IFtmb3JtYXR0ZXJDbGFzcywgZm9ybWF0dGVyTmFtZV0gPSBmdW5jdGlvbk5hbWUuc3BsaXQoXCIjXCIpO1xuXG5cdC8vIEluIHNvbWUgY2FzZSB3ZSBhbHNvIGNhbm5vdCBjYWxsIGRpcmVjdGx5IGEgZnVuY3Rpb24gYmVjYXVzZSBvZiB0b28gY29tcGxleCBpbnB1dCwgaW4gdGhhdCBjYXNlIHdlIG5lZWQgdG8gY29udmVydCB0byBhIHNpbXBsZXIgZnVuY3Rpb24gY2FsbFxuXHRpZiAoXG5cdFx0IWlnbm9yZUNvbXBsZXhUeXBlICYmXG5cdFx0KHBhcmFtZXRlckV4cHJlc3Npb25zLnNvbWUoaXNDb21wbGV4VHlwZUV4cHJlc3Npb24pIHx8XG5cdFx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5zb21lKGlzQ29uY2F0RXhwcmVzc2lvbikgfHxcblx0XHRcdHBhcmFtZXRlckV4cHJlc3Npb25zLnNvbWUoaXNJZkVsc2VFeHByZXNzaW9uKSlcblx0KSB7XG5cdFx0bGV0IHBhdGhJZHggPSAwO1xuXHRcdGNvbnN0IG15Rm9ybWF0RXhwcmVzc2lvbiA9IGZvcm1hdFJlc3VsdChwYXJhbWV0ZXJFeHByZXNzaW9ucywgZnVuY3Rpb25OYW1lLCB1bmRlZmluZWQsIHRydWUpO1xuXHRcdGNvbnN0IGFsbFBhcnRzID0gW107XG5cdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRteUZvcm1hdEV4cHJlc3Npb24sXG5cdFx0XHRcIlBhdGhJbk1vZGVsXCIsXG5cdFx0XHQoY29uc3RhbnRQYXRoOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248dW5rbm93bj4pID0+IHtcblx0XHRcdFx0YWxsUGFydHMucHVzaChjb25zdGFudFBhdGgpO1xuXHRcdFx0XHRyZXR1cm4gcGF0aEluTW9kZWwoYCQke3BhdGhJZHgrK31gLCBcIiRcIik7XG5cdFx0XHR9LFxuXHRcdFx0dHJ1ZVxuXHRcdCk7XG5cdFx0YWxsUGFydHMudW5zaGlmdChjb25zdGFudChKU09OLnN0cmluZ2lmeShteUZvcm1hdEV4cHJlc3Npb24pKSk7XG5cdFx0cmV0dXJuIGZvcm1hdFJlc3VsdChhbGxQYXJ0cywgXCJzYXAuZmUuY29yZS5mb3JtYXR0ZXJzLlN0YW5kYXJkRm9ybWF0dGVyI2V2YWx1YXRlQ29tcGxleEV4cHJlc3Npb25cIiwgdW5kZWZpbmVkLCB0cnVlKTtcblx0fSBlbHNlIGlmICghIWZvcm1hdHRlck5hbWUgJiYgZm9ybWF0dGVyTmFtZS5sZW5ndGggPiAwKSB7XG5cdFx0cGFyYW1ldGVyRXhwcmVzc2lvbnMudW5zaGlmdChjb25zdGFudChmb3JtYXR0ZXJOYW1lKSk7XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkZvcm1hdHRlclwiLFxuXHRcdGZuOiBmb3JtYXR0ZXJDbGFzcyxcblx0XHRwYXJhbWV0ZXJzOiBwYXJhbWV0ZXJFeHByZXNzaW9uc1xuXHR9O1xufVxuXG50eXBlIEJpbmRpbmdDb25zdHJhaW50cyA9IHtcblx0c2NhbGU/OiBudW1iZXI7XG5cdHByZWNpc2lvbj86IG51bWJlcjtcblx0bWF4TGVuZ3RoPzogbnVtYmVyO1xuXHRudWxsYWJsZT86IGJvb2xlYW47XG5cdG1pbmltdW0/OiBzdHJpbmc7XG5cdG1heGltdW0/OiBzdHJpbmc7XG5cdGlzRGlnaXRTZXF1ZW5jZT86IGJvb2xlYW47XG5cdFY0PzogYm9vbGVhbjtcbn07XG5leHBvcnQgZnVuY3Rpb24gc2V0VXBDb25zdHJhaW50cyh0YXJnZXRNYXBwaW5nOiBUeXBlTWFwcGluZ0RlZmluaXRpb24sIHByb3BlcnR5OiBQcm9wZXJ0eSB8IEFjdGlvblBhcmFtZXRlcik6IEJpbmRpbmdDb25zdHJhaW50cyB7XG5cdGNvbnN0IGNvbnN0cmFpbnRzOiBCaW5kaW5nQ29uc3RyYWludHMgPSB7fTtcblx0aWYgKHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy4kU2NhbGUgJiYgcHJvcGVydHkuc2NhbGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdGNvbnN0cmFpbnRzLnNjYWxlID0gcHJvcGVydHkuc2NhbGU7XG5cdH1cblx0aWYgKHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy4kUHJlY2lzaW9uICYmIHByb3BlcnR5LnByZWNpc2lvbiAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0Y29uc3RyYWludHMucHJlY2lzaW9uID0gcHJvcGVydHkucHJlY2lzaW9uO1xuXHR9XG5cdGlmICh0YXJnZXRNYXBwaW5nPy5jb25zdHJhaW50cz8uJE1heExlbmd0aCAmJiBwcm9wZXJ0eS5tYXhMZW5ndGggIT09IHVuZGVmaW5lZCkge1xuXHRcdGNvbnN0cmFpbnRzLm1heExlbmd0aCA9IHByb3BlcnR5Lm1heExlbmd0aDtcblx0fVxuXHRpZiAocHJvcGVydHkubnVsbGFibGUgPT09IGZhbHNlKSB7XG5cdFx0Y29uc3RyYWludHMubnVsbGFibGUgPSBmYWxzZTtcblx0fVxuXHRpZiAodGFyZ2V0TWFwcGluZz8uY29uc3RyYWludHM/LltcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NaW5pbXVtLyREZWNpbWFsXCJdICYmICFpc05hTihwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uVmFsaWRhdGlvbj8uTWluaW11bSkpIHtcblx0XHRjb25zdHJhaW50cy5taW5pbXVtID0gYCR7cHJvcGVydHkuYW5ub3RhdGlvbnM/LlZhbGlkYXRpb24/Lk1pbmltdW19YDtcblx0fVxuXHRpZiAodGFyZ2V0TWFwcGluZz8uY29uc3RyYWludHM/LltcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NYXhpbXVtLyREZWNpbWFsXCJdICYmICFpc05hTihwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uVmFsaWRhdGlvbj8uTWF4aW11bSkpIHtcblx0XHRjb25zdHJhaW50cy5tYXhpbXVtID0gYCR7cHJvcGVydHkuYW5ub3RhdGlvbnM/LlZhbGlkYXRpb24/Lk1heGltdW19YDtcblx0fVxuXHRpZiAoXG5cdFx0cHJvcGVydHkuYW5ub3RhdGlvbnM/LkNvbW1vbj8uSXNEaWdpdFNlcXVlbmNlICYmXG5cdFx0dGFyZ2V0TWFwcGluZy50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlN0cmluZ1wiICYmXG5cdFx0dGFyZ2V0TWFwcGluZz8uY29uc3RyYWludHM/LltcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuSXNEaWdpdFNlcXVlbmNlXCJdXG5cdCkge1xuXHRcdGNvbnN0cmFpbnRzLmlzRGlnaXRTZXF1ZW5jZSA9IHRydWU7XG5cdH1cblx0aWYgKHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy4kVjQpIHtcblx0XHRjb25zdHJhaW50cy5WNCA9IHRydWU7XG5cdH1cblx0cmV0dXJuIGNvbnN0cmFpbnRzO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyB0aGUgYmluZGluZyBleHByZXNzaW9uIGZvciB0aGUgcHJvcGVydHksIGFuZCBzZXRzIHVwIHRoZSBmb3JtYXRPcHRpb25zIGFuZCBjb25zdHJhaW50cy5cbiAqXG4gKiBAcGFyYW0gcHJvcGVydHkgVGhlIFByb3BlcnR5IGZvciB3aGljaCB3ZSBhcmUgc2V0dGluZyB1cCB0aGUgYmluZGluZ1xuICogQHBhcmFtIHByb3BlcnR5QmluZGluZ0V4cHJlc3Npb24gVGhlIEJpbmRpbmdFeHByZXNzaW9uIG9mIHRoZSBwcm9wZXJ0eSBhYm92ZS4gU2VydmVzIGFzIHRoZSBiYXNpcyB0byB3aGljaCBpbmZvcm1hdGlvbiBjYW4gYmUgYWRkZWRcbiAqIEBwYXJhbSBpZ25vcmVDb25zdHJhaW50cyBJZ25vcmUgY29uc3RyYWludHMgb2YgdGhlIHByb3BlcnR5XG4gKiBAcmV0dXJucyBUaGUgYmluZGluZyBleHByZXNzaW9uIGZvciB0aGUgcHJvcGVydHkgd2l0aCBmb3JtYXRPcHRpb25zIGFuZCBjb25zdHJhaW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0V2l0aFR5cGVJbmZvcm1hdGlvbjxUPihcblx0cHJvcGVydHk6IFByb3BlcnR5IHwgQWN0aW9uUGFyYW1ldGVyLFxuXHRwcm9wZXJ0eUJpbmRpbmdFeHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPixcblx0aWdub3JlQ29uc3RyYWludHMgPSBmYWxzZVxuKTogUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+IHtcblx0Y29uc3Qgb3V0RXhwcmVzc2lvbjogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+ID0gcHJvcGVydHlCaW5kaW5nRXhwcmVzc2lvbiBhcyBQYXRoSW5Nb2RlbEV4cHJlc3Npb248dW5rbm93bj47XG5cdGlmIChwcm9wZXJ0eS5fdHlwZSAhPT0gXCJQcm9wZXJ0eVwiICYmIHByb3BlcnR5Ll90eXBlICE9PSBcIkFjdGlvblBhcmFtZXRlclwiKSB7XG5cdFx0cmV0dXJuIG91dEV4cHJlc3Npb247XG5cdH1cblx0Y29uc3QgdGFyZ2V0TWFwcGluZyA9IEVETV9UWVBFX01BUFBJTkdbcHJvcGVydHkudHlwZV07XG5cdGlmICghdGFyZ2V0TWFwcGluZykge1xuXHRcdHJldHVybiBvdXRFeHByZXNzaW9uO1xuXHR9XG5cdGlmICghb3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKSB7XG5cdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zID0ge307XG5cdH1cblx0b3V0RXhwcmVzc2lvbi5jb25zdHJhaW50cyA9IHt9O1xuXG5cdG91dEV4cHJlc3Npb24udHlwZSA9IHRhcmdldE1hcHBpbmcudHlwZTtcblx0aWYgKCFpZ25vcmVDb25zdHJhaW50cykge1xuXHRcdG91dEV4cHJlc3Npb24uY29uc3RyYWludHMgPSBzZXRVcENvbnN0cmFpbnRzKHRhcmdldE1hcHBpbmcsIHByb3BlcnR5KTtcblx0fVxuXG5cdGlmIChcblx0XHQob3V0RXhwcmVzc2lvbj8udHlwZT8uaW5kZXhPZihcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludFwiKSA9PT0gMCAmJiBvdXRFeHByZXNzaW9uPy50eXBlICE9PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDY0XCIpIHx8XG5cdFx0b3V0RXhwcmVzc2lvbj8udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5Eb3VibGVcIlxuXHQpIHtcblx0XHRvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKG91dEV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucywge1xuXHRcdFx0cGFyc2VBc1N0cmluZzogZmFsc2Vcblx0XHR9KTtcblx0fVxuXHRpZiAob3V0RXhwcmVzc2lvbi50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlN0cmluZ1wiICYmIGlzUHJvcGVydHkocHJvcGVydHkpKSB7XG5cdFx0aWYgKCFvdXRFeHByZXNzaW9uLmNvbnN0cmFpbnRzPy5pc0RpZ2l0U2VxdWVuY2UgfHwgb3V0RXhwcmVzc2lvbi5jb25zdHJhaW50cz8ubnVsbGFibGUgPT09IGZhbHNlKSB7XG5cdFx0XHRvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMucGFyc2VLZWVwc0VtcHR5U3RyaW5nID0gdHJ1ZTtcblx0XHR9XG5cdFx0Y29uc3QgZmlzY2FsVHlwZSA9IGdldEZpc2NhbFR5cGUocHJvcGVydHkpO1xuXHRcdGlmIChmaXNjYWxUeXBlKSB7XG5cdFx0XHRvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMuZmlzY2FsVHlwZSA9IGZpc2NhbFR5cGU7XG5cdFx0XHRvdXRFeHByZXNzaW9uLnR5cGUgPSBcInNhcC5mZS5jb3JlLnR5cGUuRmlzY2FsRGF0ZVwiO1xuXHRcdH1cblx0fVxuXHRjb25zdCB0eXBlc1N1cHBvcnRpbmdQYXJzZUVtcHR5VmFsdWVUb1plcm8gPSBbXG5cdFx0XCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQxNlwiLFxuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50MzJcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDY0XCIsXG5cdFx0XCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5TaW5nbGVcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRvdWJsZVwiLFxuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRGVjaW1hbFwiLFxuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuQnl0ZVwiLFxuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU0J5dGVcIlxuXHRdO1xuXHRpZiAoXG5cdFx0b3V0RXhwcmVzc2lvbi5jb25zdHJhaW50cz8ubnVsbGFibGUgPT09IGZhbHNlICYmXG5cdFx0b3V0RXhwcmVzc2lvbi50eXBlICYmXG5cdFx0dHlwZXNTdXBwb3J0aW5nUGFyc2VFbXB0eVZhbHVlVG9aZXJvLmluY2x1ZGVzKG91dEV4cHJlc3Npb24udHlwZSlcblx0KSB7XG5cdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zID0gT2JqZWN0LmFzc2lnbihvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMsIHtcblx0XHRcdHBhcnNlRW1wdHlWYWx1ZVRvWmVybzogdHJ1ZVxuXHRcdH0pO1xuXHR9XG5cdGlmIChcblx0XHRvdXRFeHByZXNzaW9uLmNvbnN0cmFpbnRzPy5udWxsYWJsZSAhPT0gZmFsc2UgJiZcblx0XHQob3V0RXhwcmVzc2lvbi50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDY0XCIgfHwgb3V0RXhwcmVzc2lvbi50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRlY2ltYWxcIilcblx0KSB7XG5cdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zID0gT2JqZWN0LmFzc2lnbihvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMsIHtcblx0XHRcdGVtcHR5U3RyaW5nOiBcIlwiXG5cdFx0fSk7XG5cdH1cblxuXHRyZXR1cm4gb3V0RXhwcmVzc2lvbjtcbn1cblxuZXhwb3J0IGNvbnN0IGdldEZpc2NhbFR5cGUgPSBmdW5jdGlvbiAocHJvcGVydHk6IFByb3BlcnR5KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRmlzY2FsWWVhcikge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxZZWFyO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0Zpc2NhbFBlcmlvZCkge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxQZXJpb2Q7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRmlzY2FsWWVhclBlcmlvZCkge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxZZWFyUGVyaW9kO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0Zpc2NhbFF1YXJ0ZXIpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsUXVhcnRlcjtcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnM/LkNvbW1vbj8uSXNGaXNjYWxZZWFyUXVhcnRlcikge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxZZWFyUXVhcnRlcjtcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnM/LkNvbW1vbj8uSXNGaXNjYWxXZWVrKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0Zpc2NhbFdlZWs7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRmlzY2FsWWVhcldlZWspIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsWWVhcldlZWs7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRGF5T2ZGaXNjYWxZZWFyKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0RheU9mRmlzY2FsWWVhcjtcblx0fVxufTtcblxuLyoqXG4gKiBDYWxscyBhIGNvbXBsZXggdHlwZSB0byBwcm9jZXNzIHRoZSBwYXJhbWV0ZXJzLlxuICogSWYgcmVxdWlyZUNvbnRleHQgaXMgc2V0IHRvIHRydWUgYW5kIG5vIGNvbnRleHQgaXMgcGFzc2VkLCBhIGRlZmF1bHQgY29udGV4dCB3aWxsIGJlIGFkZGVkIGF1dG9tYXRpY2FsbHkuXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0ZW1wbGF0ZSBVXG4gKiBAcGFyYW0gcGFyYW1ldGVycyBUaGUgbGlzdCBvZiBwYXJhbWV0ZXJzIHRoYXQgc2hvdWxkIG1hdGNoIHRoZSB0eXBlIGZvciB0aGUgY29tcGxleCB0eXBlPVxuICogQHBhcmFtIHR5cGUgVGhlIGNvbXBsZXggdHlwZSB0byB1c2VcbiAqIEBwYXJhbSBbY29udGV4dEVudGl0eVR5cGVdIFRoZSBjb250ZXh0IGVudGl0eSB0eXBlIHRvIGNvbnNpZGVyXG4gKiBAcGFyYW0gb0Zvcm1hdE9wdGlvbnNcbiAqIEByZXR1cm5zIFRoZSBjb3JyZXNwb25kaW5nIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFR5cGVJbmZvcm1hdGlvbjxULCBVIGV4dGVuZHMgRm48VD4+KFxuXHRwYXJhbWV0ZXJzOiBXcmFwcGVkVHVwbGU8UGFyYW1ldGVyczxVPj4sXG5cdHR5cGU6IHN0cmluZyxcblx0Y29udGV4dEVudGl0eVR5cGU/OiBFbnRpdHlUeXBlLFxuXHRvRm9ybWF0T3B0aW9ucz86IENvbXBsZXhUeXBlRm9ybWF0T3B0aW9uc1xuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gfCBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4gfCBDb25zdGFudEV4cHJlc3Npb248VD4ge1xuXHRjb25zdCBwYXJhbWV0ZXJFeHByZXNzaW9ucyA9IChwYXJhbWV0ZXJzIGFzIEV4cHJlc3Npb25PclByaW1pdGl2ZTxQcmltaXRpdmVUeXBlPltdKS5tYXAod3JhcFByaW1pdGl2ZSk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLnBhcmFtZXRlckV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdC8vIElmIHRoZXJlIGlzIG9ubHkgb25lIHBhcmFtZXRlciBhbmQgaXQgaXMgYSBjb25zdGFudCBhbmQgd2UgZG9uJ3QgZXhwZWN0IHRoZSBjb250ZXh0IHRoZW4gcmV0dXJuIHRoZSBjb25zdGFudFxuXHRpZiAocGFyYW1ldGVyRXhwcmVzc2lvbnMubGVuZ3RoID09PSAxICYmIGlzQ29uc3RhbnQocGFyYW1ldGVyRXhwcmVzc2lvbnNbMF0pICYmICFjb250ZXh0RW50aXR5VHlwZSkge1xuXHRcdHJldHVybiBwYXJhbWV0ZXJFeHByZXNzaW9uc1swXSBhcyBDb25zdGFudEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoY29udGV4dEVudGl0eVR5cGUpIHtcblx0XHQvLyBPdGhlcndpc2UsIGlmIHRoZSBjb250ZXh0IGlzIHJlcXVpcmVkIGFuZCBubyBjb250ZXh0IGlzIHByb3ZpZGVkIG1ha2Ugc3VyZSB0byBhZGQgdGhlIGRlZmF1bHQgYmluZGluZ1xuXHRcdGlmICghcGFyYW1ldGVyRXhwcmVzc2lvbnMuc29tZShoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KSkge1xuXHRcdFx0Y29udGV4dEVudGl0eVR5cGUua2V5cy5mb3JFYWNoKChrZXkpID0+IHBhcmFtZXRlckV4cHJlc3Npb25zLnB1c2gocGF0aEluTW9kZWwoa2V5Lm5hbWUsIFwiXCIpKSk7XG5cdFx0fVxuXHR9XG5cdG9Gb3JtYXRPcHRpb25zID0gX2dldENvbXBsZXhUeXBlRm9ybWF0T3B0aW9uc0Zyb21GaXJzdFBhcmFtKHBhcmFtZXRlcnNbMF0sIG9Gb3JtYXRPcHRpb25zKTtcblxuXHRpZiAodHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5Vbml0XCIpIHtcblx0XHRjb25zdCB1b21QYXRoID0gcGF0aEluTW9kZWwoXCIvIyNAQHJlcXVlc3RVbml0c09mTWVhc3VyZVwiKTtcblx0XHR1b21QYXRoLnRhcmdldFR5cGUgPSBcImFueVwiO1xuXHRcdHVvbVBhdGgubW9kZSA9IFwiT25lVGltZVwiO1xuXHRcdHBhcmFtZXRlckV4cHJlc3Npb25zLnB1c2godW9tUGF0aCk7XG5cdH0gZWxzZSBpZiAodHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5DdXJyZW5jeVwiKSB7XG5cdFx0Y29uc3QgY3VycmVuY3lQYXRoID0gcGF0aEluTW9kZWwoXCIvIyNAQHJlcXVlc3RDdXJyZW5jeUNvZGVzXCIpO1xuXHRcdGN1cnJlbmN5UGF0aC50YXJnZXRUeXBlID0gXCJhbnlcIjtcblx0XHRjdXJyZW5jeVBhdGgubW9kZSA9IFwiT25lVGltZVwiO1xuXHRcdHBhcmFtZXRlckV4cHJlc3Npb25zLnB1c2goY3VycmVuY3lQYXRoKTtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiQ29tcGxleFR5cGVcIixcblx0XHR0eXBlOiB0eXBlLFxuXHRcdGZvcm1hdE9wdGlvbnM6IG9Gb3JtYXRPcHRpb25zIHx8IHt9LFxuXHRcdHBhcmFtZXRlcnM6IHt9LFxuXHRcdGJpbmRpbmdQYXJhbWV0ZXJzOiBwYXJhbWV0ZXJFeHByZXNzaW9uc1xuXHR9O1xufVxuXG50eXBlIENvbXBsZXhUeXBlRm9ybWF0T3B0aW9ucyA9IHtcblx0c2hvd051bWJlcj86IGJvb2xlYW47XG5cdHNob3dNZWFzdXJlPzogYm9vbGVhbjtcblx0cGFyc2VBc1N0cmluZz86IGJvb2xlYW47XG5cdHBhcnNlS2VlcHNFbXB0eVN0cmluZz86IGJvb2xlYW47XG5cdGVtcHR5U3RyaW5nPzogc3RyaW5nIHwgbnVtYmVyIHwgbnVsbDtcblx0c2hvd1RpbWU/OiBib29sZWFuO1xuXHRzaG93RGF0ZT86IGJvb2xlYW47XG5cdHNob3dUaW1lem9uZT86IGJvb2xlYW47XG59O1xuXG4vKipcbiAqIFByb2Nlc3MgdGhlIGZvcm1hdE9wdGlvbnMgZm9yIGEgY29tcGxleFR5cGUgYmFzZWQgb24gdGhlIGZpcnN0IHBhcmFtZXRlci5cbiAqXG4gKiBAcGFyYW0gcGFyYW0gVGhlIGZpcnN0IHBhcmFtZXRlciBvZiB0aGUgY29tcGxleCB0eXBlXG4gKiBAcGFyYW0gZm9ybWF0T3B0aW9ucyBJbml0aWFsIGZvcm1hdE9wdGlvbnNcbiAqIEByZXR1cm5zIFRoZSBtb2RpZmllZCBmb3JtYXRPcHRpb25zXG4gKi9cbmZ1bmN0aW9uIF9nZXRDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnNGcm9tRmlyc3RQYXJhbTxULCBVIGV4dGVuZHMgRm48VD4+KFxuXHRwYXJhbTogUGFyYW1ldGVyczxVPixcblx0Zm9ybWF0T3B0aW9uczogdW5kZWZpbmVkIHwgQ29tcGxleFR5cGVGb3JtYXRPcHRpb25zXG4pOiBDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnMgfCB1bmRlZmluZWQge1xuXHQvLyBpZiBzaG93TWVhc3VyZSBpcyBzZXQgdG8gZmFsc2Ugd2Ugd2FudCB0byBub3QgcGFyc2UgYXMgc3RyaW5nIHRvIHNlZSB0aGUgMFxuXHQvLyB3ZSBkbyB0aGF0IGFsc28gZm9yIGFsbCBiaW5kaW5ncyBiZWNhdXNlIG90aGVyd2lzZSB0aGUgbWRjIEZpZWxkIGlzbid0IGVkaXRhYmxlXG5cdGlmIChcblx0XHQhKGZvcm1hdE9wdGlvbnMgJiYgZm9ybWF0T3B0aW9ucy5zaG93TnVtYmVyID09PSBmYWxzZSkgJiZcblx0XHQocGFyYW0/LnR5cGU/LmluZGV4T2YoXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnRcIikgPT09IDAgfHxcblx0XHRcdHBhcmFtPy50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRlY2ltYWxcIiB8fFxuXHRcdFx0cGFyYW0/LnR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRG91YmxlXCIpXG5cdCkge1xuXHRcdGlmIChwYXJhbT8udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQ2NFwiIHx8IHBhcmFtPy50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRlY2ltYWxcIikge1xuXHRcdFx0Ly9zYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQ2NCBkbyBub3Qgc3VwcG9ydCBwYXJzZUFzU3RyaW5nIGZhbHNlXG5cdFx0XHRmb3JtYXRPcHRpb25zID0gZm9ybWF0T3B0aW9ucz8uc2hvd01lYXN1cmUgPT09IGZhbHNlID8geyBzaG93TWVhc3VyZTogZmFsc2UgfSA6IHt9O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRmb3JtYXRPcHRpb25zID0gZm9ybWF0T3B0aW9ucz8uc2hvd01lYXN1cmUgPT09IGZhbHNlID8geyBwYXJzZUFzU3RyaW5nOiBmYWxzZSwgc2hvd01lYXN1cmU6IGZhbHNlIH0gOiB7IHBhcnNlQXNTdHJpbmc6IGZhbHNlIH07XG5cdFx0fVxuXHRcdGZvcm1hdE9wdGlvbnMuZW1wdHlTdHJpbmcgPSBudWxsO1xuXHR9XG5cdHJldHVybiBmb3JtYXRPcHRpb25zO1xufVxuLyoqXG4gKiBGdW5jdGlvbiBjYWxsLCBvcHRpb25hbGx5IHdpdGggYXJndW1lbnRzLlxuICpcbiAqIEBwYXJhbSBmdW5jIEZ1bmN0aW9uIG5hbWUgb3IgcmVmZXJlbmNlIHRvIGZ1bmN0aW9uXG4gKiBAcGFyYW0gcGFyYW1ldGVycyBBcmd1bWVudHNcbiAqIEBwYXJhbSBvbiBPYmplY3QgdG8gY2FsbCB0aGUgZnVuY3Rpb24gb25cbiAqIEBwYXJhbSBpc0Zvcm1hdHRpbmdGblxuICogQHJldHVybnMgRXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGZ1bmN0aW9uIGNhbGwgKG5vdCB0aGUgcmVzdWx0IG9mIHRoZSBmdW5jdGlvbiBjYWxsISlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZuPFQsIFUgZXh0ZW5kcyBGdW5jdGlvbk9yTmFtZTxUPj4oXG5cdGZ1bmM6IFUsXG5cdHBhcmFtZXRlcnM6IFdyYXBwZWRUdXBsZTxGdW5jdGlvblBhcmFtZXRlcnM8VCwgVT4+LFxuXHRvbj86IEV4cHJlc3Npb25PclByaW1pdGl2ZTxvYmplY3Q+LFxuXHRpc0Zvcm1hdHRpbmdGbiA9IGZhbHNlXG4pOiBGdW5jdGlvbkV4cHJlc3Npb248VD4ge1xuXHRjb25zdCBmdW5jdGlvbk5hbWUgPSB0eXBlb2YgZnVuYyA9PT0gXCJzdHJpbmdcIiA/IGZ1bmMgOiBmdW5jLl9fZnVuY3Rpb25OYW1lO1xuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkZ1bmN0aW9uXCIsXG5cdFx0b2JqOiBvbiAhPT0gdW5kZWZpbmVkID8gd3JhcFByaW1pdGl2ZShvbikgOiB1bmRlZmluZWQsXG5cdFx0Zm46IGZ1bmN0aW9uTmFtZSxcblx0XHRpc0Zvcm1hdHRpbmdGbjogaXNGb3JtYXR0aW5nRm4sXG5cdFx0cGFyYW1ldGVyczogKHBhcmFtZXRlcnMgYXMgRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFByaW1pdGl2ZVR5cGU+W10pLm1hcCh3cmFwUHJpbWl0aXZlKVxuXHR9O1xufVxuXG4vKipcbiAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiBhIGJpbmRpbmcgdmFsdWUgaXMgbnVsbCwgdW5kZWZpbmVkIG9yIGVtcHR5LlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBBIEJvb2xlYW4gZXhwcmVzc2lvbiBldmFsdWF0aW5nIHRoZSBmYWN0IHRoYXQgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBlbXB0eVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbXB0eShleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGNvbnN0IGFCaW5kaW5nczogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPGJvb2xlYW4+W10gPSBbXTtcblx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoZXhwcmVzc2lvbiwgXCJQYXRoSW5Nb2RlbFwiLCAoZXhwcikgPT4ge1xuXHRcdGFCaW5kaW5ncy5wdXNoKG9yKGVxdWFsKGV4cHIsIFwiXCIpLCBlcXVhbChleHByLCB1bmRlZmluZWQpLCBlcXVhbChleHByLCBudWxsKSkpO1xuXHRcdHJldHVybiBleHByO1xuXHR9KTtcblx0cmV0dXJuIGFuZCguLi5hQmluZGluZ3MpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29uY2F0KC4uLmluRXhwcmVzc2lvbnM6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxzdHJpbmc+W10pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPiB7XG5cdGNvbnN0IGV4cHJlc3Npb25zID0gaW5FeHByZXNzaW9ucy5tYXAod3JhcFByaW1pdGl2ZSk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLmV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGlmIChleHByZXNzaW9ucy5ldmVyeShpc0NvbnN0YW50KSkge1xuXHRcdHJldHVybiBjb25zdGFudChcblx0XHRcdGV4cHJlc3Npb25zLnJlZHVjZSgoY29uY2F0ZW5hdGVkOiBzdHJpbmcsIHZhbHVlKSA9PiB7XG5cdFx0XHRcdGlmICh2YWx1ZS52YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLnZhbHVlICE9PSBudWxsKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbmNhdGVuYXRlZCArIHZhbHVlLnZhbHVlLnRvU3RyaW5nKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGNvbmNhdGVuYXRlZDtcblx0XHRcdH0sIFwiXCIpXG5cdFx0KTtcblx0fSBlbHNlIGlmIChleHByZXNzaW9ucy5zb21lKGlzQ29tcGxleFR5cGVFeHByZXNzaW9uKSkge1xuXHRcdGxldCBwYXRoSWR4ID0gMDtcblx0XHRjb25zdCBteUNvbmNhdEV4cHJlc3Npb24gPSBmb3JtYXRSZXN1bHQoZXhwcmVzc2lvbnMsIFwic2FwLmZlLmNvcmUuZm9ybWF0dGVycy5TdGFuZGFyZEZvcm1hdHRlciNjb25jYXRcIiwgdW5kZWZpbmVkLCB0cnVlKTtcblx0XHRjb25zdCBhbGxQYXJ0cyA9IFtdO1xuXHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KG15Q29uY2F0RXhwcmVzc2lvbiwgXCJQYXRoSW5Nb2RlbFwiLCAoY29uc3RhbnRQYXRoOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248dW5rbm93bj4pID0+IHtcblx0XHRcdGFsbFBhcnRzLnB1c2goY29uc3RhbnRQYXRoKTtcblx0XHRcdHJldHVybiBwYXRoSW5Nb2RlbChgJCR7cGF0aElkeCsrfWAsIFwiJFwiKTtcblx0XHR9KTtcblx0XHRhbGxQYXJ0cy51bnNoaWZ0KGNvbnN0YW50KEpTT04uc3RyaW5naWZ5KG15Q29uY2F0RXhwcmVzc2lvbikpKTtcblx0XHRyZXR1cm4gZm9ybWF0UmVzdWx0KGFsbFBhcnRzLCBcInNhcC5mZS5jb3JlLmZvcm1hdHRlcnMuU3RhbmRhcmRGb3JtYXR0ZXIjZXZhbHVhdGVDb21wbGV4RXhwcmVzc2lvblwiLCB1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiQ29uY2F0XCIsXG5cdFx0ZXhwcmVzc2lvbnM6IGV4cHJlc3Npb25zXG5cdH07XG59XG5cbnR5cGUgRXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248VCBleHRlbmRzIEV4cHJlc3Npb25UeXBlLCBWPiA9IFQgZXh0ZW5kcyBcIkNvbnN0YW50XCJcblx0PyBDb25zdGFudEV4cHJlc3Npb248Vj5cblx0OiBUIGV4dGVuZHMgXCJQYXRoSW5Nb2RlbFwiXG5cdD8gUGF0aEluTW9kZWxFeHByZXNzaW9uPFY+XG5cdDogVCBleHRlbmRzIFwiRnVuY3Rpb25cIlxuXHQ/IEZ1bmN0aW9uRXhwcmVzc2lvbjxWPlxuXHQ6IFQgZXh0ZW5kcyBcIlVucmVzb2x2YWJsZVwiXG5cdD8gVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb25cblx0OiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Vj47XG5cbmV4cG9ydCB0eXBlIFRyYW5zZm9ybUZ1bmN0aW9uPFQsIFY+ID0gKGV4cHJlc3Npb25QYXJ0OiBUKSA9PiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Vj47XG5leHBvcnQgdHlwZSBFeHByZXNzaW9uVHlwZSA9IFBpY2s8QmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+LCBcIl90eXBlXCI+W1wiX3R5cGVcIl07XG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtUmVjdXJzaXZlbHk8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGUgfCB1bmtub3duLCBFVCBleHRlbmRzIEV4cHJlc3Npb25UeXBlPihcblx0aW5FeHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sXG5cdGV4cHJlc3Npb25UeXBlOiBFVCxcblx0dHJhbnNmb3JtRnVuY3Rpb246IFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCBUPiwgVD4sXG5cdGluY2x1ZGVBbGxFeHByZXNzaW9uID0gZmFsc2Vcbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGxldCBleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4gPSBpbkV4cHJlc3Npb247XG5cdHN3aXRjaCAoZXhwcmVzc2lvbi5fdHlwZSkge1xuXHRcdGNhc2UgXCJGdW5jdGlvblwiOlxuXHRcdGNhc2UgXCJGb3JtYXR0ZXJcIjpcblx0XHRcdGV4cHJlc3Npb24ucGFyYW1ldGVycyA9IGV4cHJlc3Npb24ucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT5cblx0XHRcdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkocGFyYW1ldGVyIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiwgZXhwcmVzc2lvblR5cGUsIHRyYW5zZm9ybUZ1bmN0aW9uLCBpbmNsdWRlQWxsRXhwcmVzc2lvbilcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiQ29uY2F0XCI6XG5cdFx0XHRleHByZXNzaW9uLmV4cHJlc3Npb25zID0gZXhwcmVzc2lvbi5leHByZXNzaW9ucy5tYXAoKHN1YkV4cHJlc3Npb24pID0+XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdHN1YkV4cHJlc3Npb24sXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24gYXMgdW5rbm93biBhcyBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgc3RyaW5nPiwgc3RyaW5nPixcblx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdFx0ZXhwcmVzc2lvbiA9IGNvbmNhdCguLi5leHByZXNzaW9uLmV4cHJlc3Npb25zKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiQ29tcGxleFR5cGVcIjpcblx0XHRcdGV4cHJlc3Npb24uYmluZGluZ1BhcmFtZXRlcnMgPSBleHByZXNzaW9uLmJpbmRpbmdQYXJhbWV0ZXJzLm1hcCgoYmluZGluZ1BhcmFtZXRlcikgPT5cblx0XHRcdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0YmluZGluZ1BhcmFtZXRlciBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KVxuXHRcdFx0KTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJJZkVsc2VcIjpcblx0XHRcdGNvbnN0IG9uVHJ1ZSA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRleHByZXNzaW9uLm9uVHJ1ZSxcblx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIHVua25vd24+LCB1bmtub3duPixcblx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdCk7XG5cdFx0XHRjb25zdCBvbkZhbHNlID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdGV4cHJlc3Npb24ub25GYWxzZSxcblx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIHVua25vd24+LCB1bmtub3duPixcblx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdCk7XG5cdFx0XHRsZXQgY29uZGl0aW9uID0gZXhwcmVzc2lvbi5jb25kaXRpb247XG5cdFx0XHRpZiAoaW5jbHVkZUFsbEV4cHJlc3Npb24pIHtcblx0XHRcdFx0Y29uZGl0aW9uID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0ZXhwcmVzc2lvbi5jb25kaXRpb24sXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24gYXMgdW5rbm93biBhcyBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgYm9vbGVhbj4sIGJvb2xlYW4+LFxuXHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRleHByZXNzaW9uID0gaWZFbHNlKGNvbmRpdGlvbiwgb25UcnVlLCBvbkZhbHNlKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0XHRpZiAoaW5jbHVkZUFsbEV4cHJlc3Npb24pIHtcblx0XHRcdFx0Y29uc3Qgb3BlcmFuZCA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHJlc3Npb24ub3BlcmFuZCxcblx0XHRcdFx0XHRleHByZXNzaW9uVHlwZSxcblx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCBib29sZWFuPiwgYm9vbGVhbj4sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KTtcblx0XHRcdFx0ZXhwcmVzc2lvbiA9IG5vdChvcGVyYW5kKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0XHR9XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiVHJ1dGh5XCI6XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiU2V0XCI6XG5cdFx0XHRpZiAoaW5jbHVkZUFsbEV4cHJlc3Npb24pIHtcblx0XHRcdFx0Y29uc3Qgb3BlcmFuZHMgPSBleHByZXNzaW9uLm9wZXJhbmRzLm1hcCgob3BlcmFuZCkgPT5cblx0XHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRcdG9wZXJhbmQsXG5cdFx0XHRcdFx0XHRleHByZXNzaW9uVHlwZSxcblx0XHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIGJvb2xlYW4+LCBib29sZWFuPixcblx0XHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHQpO1xuXHRcdFx0XHRleHByZXNzaW9uID1cblx0XHRcdFx0XHRleHByZXNzaW9uLm9wZXJhdG9yID09PSBcInx8XCJcblx0XHRcdFx0XHRcdD8gKG9yKC4uLm9wZXJhbmRzKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pXG5cdFx0XHRcdFx0XHQ6IChhbmQoLi4ub3BlcmFuZHMpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPik7XG5cdFx0XHR9XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiQ29tcGFyaXNvblwiOlxuXHRcdFx0aWYgKGluY2x1ZGVBbGxFeHByZXNzaW9uKSB7XG5cdFx0XHRcdGNvbnN0IG9wZXJhbmQxID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0ZXhwcmVzc2lvbi5vcGVyYW5kMSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KTtcblx0XHRcdFx0Y29uc3Qgb3BlcmFuZDIgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRleHByZXNzaW9uLm9wZXJhbmQyIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPixcblx0XHRcdFx0XHRleHByZXNzaW9uVHlwZSxcblx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbixcblx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHQpO1xuXHRcdFx0XHRleHByZXNzaW9uID0gY29tcGFyaXNvbihleHByZXNzaW9uLm9wZXJhdG9yLCBvcGVyYW5kMSwgb3BlcmFuZDIpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0XHRcdH1cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJDb25zdGFudFwiOlxuXHRcdFx0Y29uc3QgY29uc3RhbnRWYWx1ZTogUmVjb3JkPHN0cmluZywgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+PiA9IGV4cHJlc3Npb24udmFsdWUgYXMgUmVjb3JkPFxuXHRcdFx0XHRzdHJpbmcsXG5cdFx0XHRcdEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPlxuXHRcdFx0Pjtcblx0XHRcdGlmICh0eXBlb2YgY29uc3RhbnRWYWx1ZSA9PT0gXCJvYmplY3RcIiAmJiBjb25zdGFudFZhbHVlKSB7XG5cdFx0XHRcdE9iamVjdC5rZXlzKGNvbnN0YW50VmFsdWUpLmZvckVhY2goKGtleSkgPT4ge1xuXHRcdFx0XHRcdGNvbnN0YW50VmFsdWVba2V5XSA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdFx0Y29uc3RhbnRWYWx1ZVtrZXldLFxuXHRcdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCB1bmtub3duPiwgdW5rbm93bj4sXG5cdFx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIlJlZlwiOlxuXHRcdGNhc2UgXCJMZW5ndGhcIjpcblx0XHRjYXNlIFwiUGF0aEluTW9kZWxcIjpcblx0XHRjYXNlIFwiRW1iZWRkZWRCaW5kaW5nXCI6XG5cdFx0Y2FzZSBcIkVtYmVkZGVkRXhwcmVzc2lvbkJpbmRpbmdcIjpcblx0XHRjYXNlIFwiVW5yZXNvbHZhYmxlXCI6XG5cdFx0XHQvLyBEbyBub3RoaW5nXG5cdFx0XHRicmVhaztcblx0fVxuXHRpZiAoZXhwcmVzc2lvblR5cGUgPT09IGV4cHJlc3Npb24uX3R5cGUpIHtcblx0XHRleHByZXNzaW9uID0gdHJhbnNmb3JtRnVuY3Rpb24oaW5FeHByZXNzaW9uIGFzIEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCBUPik7XG5cdH1cblx0cmV0dXJuIGV4cHJlc3Npb247XG59XG5cbmV4cG9ydCB0eXBlIENvbXBpbGVkQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uID0gc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG5jb25zdCBuZWVkUGFyZW50aGVzaXMgPSBmdW5jdGlvbiA8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHI6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPik6IGJvb2xlYW4ge1xuXHRyZXR1cm4gKFxuXHRcdCFpc0NvbnN0YW50KGV4cHIpICYmXG5cdFx0IWlzUGF0aEluTW9kZWxFeHByZXNzaW9uKGV4cHIpICYmXG5cdFx0aXNCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24oZXhwcikgJiZcblx0XHRleHByLl90eXBlICE9PSBcIklmRWxzZVwiICYmXG5cdFx0ZXhwci5fdHlwZSAhPT0gXCJGdW5jdGlvblwiXG5cdCk7XG59O1xuXG4vKipcbiAqIENvbXBpbGVzIGEgY29uc3RhbnQgb2JqZWN0IHRvIGEgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSBleHByXG4gKiBAcGFyYW0gaXNOdWxsYWJsZVxuICogQHJldHVybnMgVGhlIGNvbXBpbGVkIHN0cmluZ1xuICovXG5mdW5jdGlvbiBjb21waWxlQ29uc3RhbnRPYmplY3QoZXhwcjogQ29uc3RhbnRFeHByZXNzaW9uPG9iamVjdD4sIGlzTnVsbGFibGUgPSBmYWxzZSk6IHN0cmluZyB7XG5cdGlmIChpc051bGxhYmxlICYmIE9iamVjdC5rZXlzKGV4cHIudmFsdWUpLmxlbmd0aCA9PT0gMCkge1xuXHRcdHJldHVybiBcIlwiO1xuXHR9XG5cdGNvbnN0IG9iamVjdHMgPSBleHByLnZhbHVlIGFzIFBsYWluRXhwcmVzc2lvbk9iamVjdDtcblx0Y29uc3QgcHJvcGVydGllczogc3RyaW5nW10gPSBbXTtcblx0T2JqZWN0LmtleXMob2JqZWN0cykuZm9yRWFjaCgoa2V5KSA9PiB7XG5cdFx0Y29uc3QgdmFsdWUgPSBvYmplY3RzW2tleV07XG5cdFx0Y29uc3QgY2hpbGRSZXN1bHQgPSBjb21waWxlRXhwcmVzc2lvbih2YWx1ZSwgdHJ1ZSwgZmFsc2UsIGlzTnVsbGFibGUpO1xuXHRcdGlmIChjaGlsZFJlc3VsdCAmJiBjaGlsZFJlc3VsdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRwcm9wZXJ0aWVzLnB1c2goYCR7a2V5fTogJHtjaGlsZFJlc3VsdH1gKTtcblx0XHR9XG5cdH0pO1xuXHRyZXR1cm4gYHske3Byb3BlcnRpZXMuam9pbihcIiwgXCIpfX1gO1xufVxuXG4vKipcbiAqIENvbXBpbGVzIGEgQ29uc3RhbnQgQmluZGluZyBFeHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByXG4gKiBAcGFyYW0gZW1iZWRkZWRJbkJpbmRpbmdcbiAqIEBwYXJhbSBpc051bGxhYmxlXG4gKiBAcGFyYW0gZG9Ob3RTdHJpbmdpZnlcbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBpbGVDb25zdGFudDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGV4cHI6IENvbnN0YW50RXhwcmVzc2lvbjxUPixcblx0ZW1iZWRkZWRJbkJpbmRpbmc6IGJvb2xlYW4sXG5cdGlzTnVsbGFibGU/OiBib29sZWFuLFxuXHRkb05vdFN0cmluZ2lmeT86IGZhbHNlXG4pOiBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjtcbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlQ29uc3RhbnQ8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRleHByOiBDb25zdGFudEV4cHJlc3Npb248VD4sXG5cdGVtYmVkZGVkSW5CaW5kaW5nOiBib29sZWFuLFxuXHRpc051bGxhYmxlPzogYm9vbGVhbixcblx0ZG9Ob3RTdHJpbmdpZnk/OiB0cnVlXG4pOiBQcmltaXRpdmVUeXBlO1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBpbGVDb25zdGFudDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGV4cHI6IENvbnN0YW50RXhwcmVzc2lvbjxUPixcblx0ZW1iZWRkZWRJbkJpbmRpbmc6IGJvb2xlYW4sXG5cdGlzTnVsbGFibGUgPSBmYWxzZSxcblx0ZG9Ob3RTdHJpbmdpZnkgPSBmYWxzZVxuKTogQ29tcGlsZWRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24gfCBQcmltaXRpdmVUeXBlIHtcblx0aWYgKGV4cHIudmFsdWUgPT09IG51bGwpIHtcblx0XHRyZXR1cm4gZG9Ob3RTdHJpbmdpZnkgPyBudWxsIDogXCJudWxsXCI7XG5cdH1cblx0aWYgKGV4cHIudmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBkb05vdFN0cmluZ2lmeSA/IHVuZGVmaW5lZCA6IFwidW5kZWZpbmVkXCI7XG5cdH1cblx0aWYgKHR5cGVvZiBleHByLnZhbHVlID09PSBcIm9iamVjdFwiKSB7XG5cdFx0aWYgKEFycmF5LmlzQXJyYXkoZXhwci52YWx1ZSkpIHtcblx0XHRcdGNvbnN0IGVudHJpZXMgPSBleHByLnZhbHVlLm1hcCgoZXhwcmVzc2lvbikgPT4gY29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbiwgdHJ1ZSkpO1xuXHRcdFx0cmV0dXJuIGBbJHtlbnRyaWVzLmpvaW4oXCIsIFwiKX1dYDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIGNvbXBpbGVDb25zdGFudE9iamVjdChleHByIGFzIENvbnN0YW50RXhwcmVzc2lvbjxvYmplY3Q+LCBpc051bGxhYmxlKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoZW1iZWRkZWRJbkJpbmRpbmcpIHtcblx0XHRzd2l0Y2ggKHR5cGVvZiBleHByLnZhbHVlKSB7XG5cdFx0XHRjYXNlIFwibnVtYmVyXCI6XG5cdFx0XHRjYXNlIFwiYmlnaW50XCI6XG5cdFx0XHRjYXNlIFwiYm9vbGVhblwiOlxuXHRcdFx0XHRyZXR1cm4gZXhwci52YWx1ZS50b1N0cmluZygpO1xuXHRcdFx0Y2FzZSBcInN0cmluZ1wiOlxuXHRcdFx0XHRyZXR1cm4gYCcke2VzY2FwZVhtbEF0dHJpYnV0ZShleHByLnZhbHVlLnRvU3RyaW5nKCkpfSdgO1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0cmV0dXJuIFwiXCI7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBkb05vdFN0cmluZ2lmeSA/IGV4cHIudmFsdWUgOiBleHByLnZhbHVlLnRvU3RyaW5nKCk7XG5cdH1cbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGJpbmRpbmcgc3RyaW5nIGZvciBhIEJpbmRpbmcgZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbkZvckJpbmRpbmcgVGhlIGV4cHJlc3Npb24gdG8gY29tcGlsZVxuICogQHBhcmFtIGVtYmVkZGVkSW5CaW5kaW5nIFdoZXRoZXIgdGhlIGV4cHJlc3Npb24gdG8gY29tcGlsZSBpcyBlbWJlZGRlZCBpbnRvIGFub3RoZXIgZXhwcmVzc2lvblxuICogQHBhcmFtIGVtYmVkZGVkU2VwYXJhdG9yIFRoZSBiaW5kaW5nIHZhbHVlIGV2YWx1YXRvciAoJCBvciAlIGRlcGVuZGluZyBvbiB3aGV0aGVyIHdlIHdhbnQgdG8gZm9yY2UgdGhlIHR5cGUgb3Igbm90KVxuICogQHJldHVybnMgVGhlIGNvcnJlc3BvbmRpbmcgZXhwcmVzc2lvbiBiaW5kaW5nXG4gKi9cbmZ1bmN0aW9uIGNvbXBpbGVQYXRoSW5Nb2RlbEV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRleHByZXNzaW9uRm9yQmluZGluZzogUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+LFxuXHRlbWJlZGRlZEluQmluZGluZzogYm9vbGVhbixcblx0ZW1iZWRkZWRTZXBhcmF0b3I6IHN0cmluZ1xuKTogQ29tcGlsZWRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24ge1xuXHRpZiAoXG5cdFx0ZXhwcmVzc2lvbkZvckJpbmRpbmcudHlwZSB8fFxuXHRcdGV4cHJlc3Npb25Gb3JCaW5kaW5nLnBhcmFtZXRlcnMgfHxcblx0XHRleHByZXNzaW9uRm9yQmluZGluZy50YXJnZXRUeXBlIHx8XG5cdFx0ZXhwcmVzc2lvbkZvckJpbmRpbmcuZm9ybWF0T3B0aW9ucyB8fFxuXHRcdGV4cHJlc3Npb25Gb3JCaW5kaW5nLmNvbnN0cmFpbnRzXG5cdCkge1xuXHRcdC8vIFRoaXMgaXMgbm93IGEgY29tcGxleCBiaW5kaW5nIGRlZmluaXRpb24sIGxldCdzIHByZXBhcmUgZm9yIGl0XG5cdFx0Y29uc3QgY29tcGxleEJpbmRpbmdEZWZpbml0aW9uID0ge1xuXHRcdFx0cGF0aDogY29tcGlsZVBhdGhJbk1vZGVsKGV4cHJlc3Npb25Gb3JCaW5kaW5nKSxcblx0XHRcdHR5cGU6IGV4cHJlc3Npb25Gb3JCaW5kaW5nLnR5cGUsXG5cdFx0XHR0YXJnZXRUeXBlOiBleHByZXNzaW9uRm9yQmluZGluZy50YXJnZXRUeXBlLFxuXHRcdFx0cGFyYW1ldGVyczogZXhwcmVzc2lvbkZvckJpbmRpbmcucGFyYW1ldGVycyxcblx0XHRcdGZvcm1hdE9wdGlvbnM6IGV4cHJlc3Npb25Gb3JCaW5kaW5nLmZvcm1hdE9wdGlvbnMsXG5cdFx0XHRjb25zdHJhaW50czogZXhwcmVzc2lvbkZvckJpbmRpbmcuY29uc3RyYWludHNcblx0XHR9O1xuXHRcdGNvbnN0IG91dEJpbmRpbmcgPSBjb21waWxlRXhwcmVzc2lvbihjb21wbGV4QmluZGluZ0RlZmluaXRpb24sIGZhbHNlLCBmYWxzZSwgdHJ1ZSk7XG5cdFx0aWYgKGVtYmVkZGVkSW5CaW5kaW5nKSB7XG5cdFx0XHRyZXR1cm4gYCR7ZW1iZWRkZWRTZXBhcmF0b3J9JHtvdXRCaW5kaW5nfWA7XG5cdFx0fVxuXHRcdHJldHVybiBvdXRCaW5kaW5nO1xuXHR9IGVsc2UgaWYgKGVtYmVkZGVkSW5CaW5kaW5nKSB7XG5cdFx0cmV0dXJuIGAke2VtYmVkZGVkU2VwYXJhdG9yfXske2NvbXBpbGVQYXRoSW5Nb2RlbChleHByZXNzaW9uRm9yQmluZGluZyl9fWA7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGB7JHtjb21waWxlUGF0aEluTW9kZWwoZXhwcmVzc2lvbkZvckJpbmRpbmcpfX1gO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVDb21wbGV4VHlwZUV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPik6IHN0cmluZyB7XG5cdGlmIChleHByZXNzaW9uLmJpbmRpbmdQYXJhbWV0ZXJzLmxlbmd0aCA9PT0gMSkge1xuXHRcdHJldHVybiBgeyR7Y29tcGlsZVBhdGhQYXJhbWV0ZXIoZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVyc1swXSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4sIHRydWUpfSwgdHlwZTogJyR7XG5cdFx0XHRleHByZXNzaW9uLnR5cGVcblx0XHR9J31gO1xuXHR9XG5cblx0bGV0IG91dHB1dEVuZCA9IGBdLCB0eXBlOiAnJHtleHByZXNzaW9uLnR5cGV9J2A7XG5cdGlmIChoYXNFbGVtZW50cyhleHByZXNzaW9uLmZvcm1hdE9wdGlvbnMpKSB7XG5cdFx0b3V0cHV0RW5kICs9IGAsIGZvcm1hdE9wdGlvbnM6ICR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKX1gO1xuXHR9XG5cdGlmIChoYXNFbGVtZW50cyhleHByZXNzaW9uLnBhcmFtZXRlcnMpKSB7XG5cdFx0b3V0cHV0RW5kICs9IGAsIHBhcmFtZXRlcnM6ICR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5wYXJhbWV0ZXJzKX1gO1xuXHR9XG5cdG91dHB1dEVuZCArPSBcIn1cIjtcblxuXHRyZXR1cm4gYHttb2RlOidUd29XYXknLCBwYXJ0czpbJHtleHByZXNzaW9uLmJpbmRpbmdQYXJhbWV0ZXJzXG5cdFx0Lm1hcCgocGFyYW0pID0+IGNvbXBpbGVQYXRoUGFyYW1ldGVyKHBhcmFtIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPikpXG5cdFx0LmpvaW4oXCIsXCIpfSR7b3V0cHV0RW5kfWA7XG59XG5cbi8qKlxuICogV3JhcCB0aGUgY29tcGlsZWQgYmluZGluZyBzdHJpbmcgYXMgcmVxdWlyZWQgZGVwZW5kaW5nIG9uIGl0cyBjb250ZXh0LlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBjb21waWxlZCBleHByZXNzaW9uXG4gKiBAcGFyYW0gZW1iZWRkZWRJbkJpbmRpbmcgVHJ1ZSBpZiB0aGUgY29tcGlsZWQgZXhwcmVzc2lvbiBpcyB0byBiZSBlbWJlZGRlZCBpbiBhIGJpbmRpbmdcbiAqIEBwYXJhbSBwYXJlbnRoZXNpc1JlcXVpcmVkIFRydWUgaWYgdGhlIGVtYmVkZGVkIGJpbmRpbmcgbmVlZHMgdG8gYmUgd3JhcHBlZCBpbiBwYXJldGhlc2lzIHNvIHRoYXQgaXQgaXMgZXZhbHVhdGVkIGFzIG9uZVxuICogQHJldHVybnMgRmluYWxpemVkIGNvbXBpbGVkIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihcblx0ZXhwcmVzc2lvbjogc3RyaW5nLFxuXHRlbWJlZGRlZEluQmluZGluZzogYm9vbGVhbixcblx0cGFyZW50aGVzaXNSZXF1aXJlZCA9IGZhbHNlXG4pOiBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbiB7XG5cdGlmIChlbWJlZGRlZEluQmluZGluZykge1xuXHRcdGlmIChwYXJlbnRoZXNpc1JlcXVpcmVkKSB7XG5cdFx0XHRyZXR1cm4gYCgke2V4cHJlc3Npb259KWA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBleHByZXNzaW9uO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gYHs9ICR7ZXhwcmVzc2lvbn19YDtcblx0fVxufVxuXG4vKipcbiAqIENvbXBpbGUgYW4gZXhwcmVzc2lvbiBpbnRvIGFuIGV4cHJlc3Npb24gYmluZGluZy5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGVcbiAqIEBwYXJhbSBlbWJlZGRlZEluQmluZGluZyBXaGV0aGVyIHRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGUgaXMgZW1iZWRkZWQgaW50byBhbm90aGVyIGV4cHJlc3Npb25cbiAqIEBwYXJhbSBrZWVwVGFyZ2V0VHlwZSBLZWVwIHRoZSB0YXJnZXQgdHlwZSBvZiB0aGUgZW1iZWRkZWQgYmluZGluZ3MgaW5zdGVhZCBvZiBjYXN0aW5nIHRoZW0gdG8gYW55XG4gKiBAcGFyYW0gaXNOdWxsYWJsZSBXaGV0aGVyIGJpbmRpbmcgZXhwcmVzc2lvbiBjYW4gcmVzb2x2ZSB0byBlbXB0eSBzdHJpbmcgb3Igbm90XG4gKiBAcmV0dXJucyBUaGUgY29ycmVzcG9uZGluZyBleHByZXNzaW9uIGJpbmRpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBpbGVFeHByZXNzaW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0ZXhwcmVzc2lvbjogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRlbWJlZGRlZEluQmluZGluZyA9IGZhbHNlLFxuXHRrZWVwVGFyZ2V0VHlwZSA9IGZhbHNlLFxuXHRpc051bGxhYmxlID0gZmFsc2Vcbik6IENvbXBpbGVkQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uIHtcblx0Y29uc3QgZXhwciA9IHdyYXBQcmltaXRpdmUoZXhwcmVzc2lvbik7XG5cdGNvbnN0IGVtYmVkZGVkU2VwYXJhdG9yID0ga2VlcFRhcmdldFR5cGUgPyBcIiRcIiA6IFwiJVwiO1xuXG5cdHN3aXRjaCAoZXhwci5fdHlwZSkge1xuXHRcdGNhc2UgXCJVbnJlc29sdmFibGVcIjpcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cblx0XHRjYXNlIFwiQ29uc3RhbnRcIjpcblx0XHRcdHJldHVybiBjb21waWxlQ29uc3RhbnQoZXhwciwgZW1iZWRkZWRJbkJpbmRpbmcsIGlzTnVsbGFibGUpO1xuXG5cdFx0Y2FzZSBcIlJlZlwiOlxuXHRcdFx0cmV0dXJuIGV4cHIucmVmIHx8IFwibnVsbFwiO1xuXG5cdFx0Y2FzZSBcIkZ1bmN0aW9uXCI6XG5cdFx0XHRsZXQgaGFzRW1iZWRkZWRGdW5jdGlvbkNhbGxPckJpbmRpbmcgPSBmYWxzZTtcblx0XHRcdGlmIChleHByLmlzRm9ybWF0dGluZ0ZuKSB7XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHIsXG5cdFx0XHRcdFx0XCJGdW5jdGlvblwiLFxuXHRcdFx0XHRcdChzdWJGbikgPT4ge1xuXHRcdFx0XHRcdFx0aWYgKHN1YkZuICE9PSBleHByICYmIHN1YkZuLm9iaiA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHRcdGhhc0VtYmVkZGVkRnVuY3Rpb25DYWxsT3JCaW5kaW5nID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHJldHVybiBzdWJGbjtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdHRydWVcblx0XHRcdFx0KTtcblx0XHRcdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0ZXhwcixcblx0XHRcdFx0XHRcIkNvbnN0YW50XCIsXG5cdFx0XHRcdFx0KHN1YkZuOiBDb25zdGFudEV4cHJlc3Npb248VD4pID0+IHtcblx0XHRcdFx0XHRcdGlmICgoc3ViRm4gYXMgdW5rbm93bikgIT09IGV4cHIgJiYgdHlwZW9mIHN1YkZuLnZhbHVlID09PSBcIm9iamVjdFwiKSB7XG5cdFx0XHRcdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KHN1YkZuLCBcIlBhdGhJbk1vZGVsXCIsIChzdWJTdWJGbikgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdGhhc0VtYmVkZGVkRnVuY3Rpb25DYWxsT3JCaW5kaW5nID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gc3ViU3ViRm47XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRyZXR1cm4gc3ViRm47XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHR0cnVlXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBhcmd1bWVudFN0cmluZyA9IGAke2V4cHIucGFyYW1ldGVycy5tYXAoKGFyZykgPT4gY29tcGlsZUV4cHJlc3Npb24oYXJnLCB0cnVlKSkuam9pbihcIiwgXCIpfWA7XG5cdFx0XHRsZXQgZm5DYWxsID1cblx0XHRcdFx0ZXhwci5vYmogPT09IHVuZGVmaW5lZFxuXHRcdFx0XHRcdD8gYCR7ZXhwci5mbn0oJHthcmd1bWVudFN0cmluZ30pYFxuXHRcdFx0XHRcdDogYCR7Y29tcGlsZUV4cHJlc3Npb24oZXhwci5vYmosIHRydWUpfS4ke2V4cHIuZm59KCR7YXJndW1lbnRTdHJpbmd9KWA7XG5cdFx0XHRpZiAoIWVtYmVkZGVkSW5CaW5kaW5nICYmIGhhc0VtYmVkZGVkRnVuY3Rpb25DYWxsT3JCaW5kaW5nKSB7XG5cdFx0XHRcdGZuQ2FsbCA9IGB7PSAke2ZuQ2FsbH19YDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBmbkNhbGw7XG5cblx0XHRjYXNlIFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiOlxuXHRcdFx0cmV0dXJuIGVtYmVkZGVkSW5CaW5kaW5nID8gYCgke2V4cHIudmFsdWUuc3Vic3RyaW5nKDIsIGV4cHIudmFsdWUubGVuZ3RoIC0gMSl9KWAgOiBgJHtleHByLnZhbHVlfWA7XG5cblx0XHRjYXNlIFwiRW1iZWRkZWRCaW5kaW5nXCI6XG5cdFx0XHRyZXR1cm4gZW1iZWRkZWRJbkJpbmRpbmcgPyBgJHtlbWJlZGRlZFNlcGFyYXRvcn0ke2V4cHIudmFsdWV9YCA6IGAke2V4cHIudmFsdWV9YDtcblxuXHRcdGNhc2UgXCJQYXRoSW5Nb2RlbFwiOlxuXHRcdFx0cmV0dXJuIGNvbXBpbGVQYXRoSW5Nb2RlbEV4cHJlc3Npb24oZXhwciwgZW1iZWRkZWRJbkJpbmRpbmcsIGVtYmVkZGVkU2VwYXJhdG9yKTtcblxuXHRcdGNhc2UgXCJDb21wYXJpc29uXCI6XG5cdFx0XHRjb25zdCBjb21wYXJpc29uRXhwcmVzc2lvbiA9IGNvbXBpbGVDb21wYXJpc29uRXhwcmVzc2lvbihleHByKTtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24oY29tcGFyaXNvbkV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nKTtcblxuXHRcdGNhc2UgXCJJZkVsc2VcIjpcblx0XHRcdGNvbnN0IGlmRWxzZUV4cHJlc3Npb24gPSBgJHtjb21waWxlRXhwcmVzc2lvbihleHByLmNvbmRpdGlvbiwgdHJ1ZSl9ID8gJHtjb21waWxlRXhwcmVzc2lvbihcblx0XHRcdFx0ZXhwci5vblRydWUsXG5cdFx0XHRcdHRydWUsXG5cdFx0XHRcdGtlZXBUYXJnZXRUeXBlXG5cdFx0XHQpfSA6ICR7Y29tcGlsZUV4cHJlc3Npb24oZXhwci5vbkZhbHNlLCB0cnVlLCBrZWVwVGFyZ2V0VHlwZSl9YDtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24oaWZFbHNlRXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcsIHRydWUpO1xuXG5cdFx0Y2FzZSBcIlNldFwiOlxuXHRcdFx0Y29uc3Qgc2V0RXhwcmVzc2lvbiA9IGV4cHIub3BlcmFuZHMubWFwKChvcGVyYW5kKSA9PiBjb21waWxlRXhwcmVzc2lvbihvcGVyYW5kLCB0cnVlKSkuam9pbihgICR7ZXhwci5vcGVyYXRvcn0gYCk7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKHNldEV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nLCB0cnVlKTtcblxuXHRcdGNhc2UgXCJDb25jYXRcIjpcblx0XHRcdGNvbnN0IGNvbmNhdEV4cHJlc3Npb24gPSBleHByLmV4cHJlc3Npb25zXG5cdFx0XHRcdC5tYXAoKG5lc3RlZEV4cHJlc3Npb24pID0+IGNvbXBpbGVFeHByZXNzaW9uKG5lc3RlZEV4cHJlc3Npb24sIHRydWUsIHRydWUpKVxuXHRcdFx0XHQuam9pbihcIiArIFwiKTtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24oY29uY2F0RXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIkxlbmd0aFwiOlxuXHRcdFx0Y29uc3QgbGVuZ3RoRXhwcmVzc2lvbiA9IGAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIucGF0aEluTW9kZWwsIHRydWUpfS5sZW5ndGhgO1xuXHRcdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihsZW5ndGhFeHByZXNzaW9uLCBlbWJlZGRlZEluQmluZGluZyk7XG5cblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0XHRjb25zdCBub3RFeHByZXNzaW9uID0gYCEke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIub3BlcmFuZCwgdHJ1ZSl9YDtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24obm90RXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIlRydXRoeVwiOlxuXHRcdFx0Y29uc3QgdHJ1dGh5RXhwcmVzc2lvbiA9IGAhISR7Y29tcGlsZUV4cHJlc3Npb24oZXhwci5vcGVyYW5kLCB0cnVlKX1gO1xuXHRcdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbih0cnV0aHlFeHByZXNzaW9uLCBlbWJlZGRlZEluQmluZGluZyk7XG5cblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0XHRjb25zdCBmb3JtYXR0ZXJFeHByZXNzaW9uID0gY29tcGlsZUZvcm1hdHRlckV4cHJlc3Npb24oZXhwcik7XG5cdFx0XHRyZXR1cm4gZW1iZWRkZWRJbkJpbmRpbmcgPyBgJCR7Zm9ybWF0dGVyRXhwcmVzc2lvbn1gIDogZm9ybWF0dGVyRXhwcmVzc2lvbjtcblxuXHRcdGNhc2UgXCJDb21wbGV4VHlwZVwiOlxuXHRcdFx0Y29uc3QgY29tcGxleFR5cGVFeHByZXNzaW9uID0gY29tcGlsZUNvbXBsZXhUeXBlRXhwcmVzc2lvbihleHByKTtcblx0XHRcdHJldHVybiBlbWJlZGRlZEluQmluZGluZyA/IGAkJHtjb21wbGV4VHlwZUV4cHJlc3Npb259YCA6IGNvbXBsZXhUeXBlRXhwcmVzc2lvbjtcblxuXHRcdGRlZmF1bHQ6XG5cdFx0XHRyZXR1cm4gXCJcIjtcblx0fVxufVxuXG4vKipcbiAqIENvbXBpbGUgYSBjb21wYXJpc29uIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGNvbXBhcmlzb24gZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBleHByZXNzaW9uLiBOZWVkcyB3cmFwcGluZyBiZWZvcmUgaXQgY2FuIGJlIHVzZWQgYXMgYW4gZXhwcmVzc2lvbiBiaW5kaW5nLlxuICovXG5mdW5jdGlvbiBjb21waWxlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcmVzc2lvbjogQ29tcGFyaXNvbkV4cHJlc3Npb24pOiBzdHJpbmcge1xuXHRmdW5jdGlvbiBjb21waWxlT3BlcmFuZChvcGVyYW5kOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj4pOiBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbiB7XG5cdFx0Y29uc3QgY29tcGlsZWRPcGVyYW5kID0gY29tcGlsZUV4cHJlc3Npb24ob3BlcmFuZCwgdHJ1ZSkgPz8gXCJ1bmRlZmluZWRcIjtcblx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKGNvbXBpbGVkT3BlcmFuZCwgdHJ1ZSwgbmVlZFBhcmVudGhlc2lzKG9wZXJhbmQpKTtcblx0fVxuXG5cdHJldHVybiBgJHtjb21waWxlT3BlcmFuZChleHByZXNzaW9uLm9wZXJhbmQxKX0gJHtleHByZXNzaW9uLm9wZXJhdG9yfSAke2NvbXBpbGVPcGVyYW5kKGV4cHJlc3Npb24ub3BlcmFuZDIpfWA7XG59XG5cbi8qKlxuICogQ29tcGlsZSBhIGZvcm1hdHRlciBleHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBmb3JtYXR0ZXIgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBleHByZXNzaW9uLlxuICovXG5mdW5jdGlvbiBjb21waWxlRm9ybWF0dGVyRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oZXhwcmVzc2lvbjogRm9ybWF0dGVyRXhwcmVzc2lvbjxUPik6IHN0cmluZyB7XG5cdGlmIChleHByZXNzaW9uLnBhcmFtZXRlcnMubGVuZ3RoID09PSAxKSB7XG5cdFx0cmV0dXJuIGB7JHtjb21waWxlUGF0aFBhcmFtZXRlcihleHByZXNzaW9uLnBhcmFtZXRlcnNbMF0gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+LCB0cnVlKX0sIGZvcm1hdHRlcjogJyR7XG5cdFx0XHRleHByZXNzaW9uLmZuXG5cdFx0fSd9YDtcblx0fSBlbHNlIHtcblx0XHRjb25zdCBwYXJ0cyA9IGV4cHJlc3Npb24ucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG5cdFx0XHRpZiAocGFyYW0uX3R5cGUgPT09IFwiQ29tcGxleFR5cGVcIikge1xuXHRcdFx0XHRyZXR1cm4gY29tcGlsZUNvbXBsZXhUeXBlRXhwcmVzc2lvbihwYXJhbSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gY29tcGlsZVBhdGhQYXJhbWV0ZXIocGFyYW0gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRyZXR1cm4gYHtwYXJ0czogWyR7cGFydHMuam9pbihcIiwgXCIpfV0sIGZvcm1hdHRlcjogJyR7ZXhwcmVzc2lvbi5mbn0nfWA7XG5cdH1cbn1cblxuLyoqXG4gKiBDb21waWxlIHRoZSBwYXRoIHBhcmFtZXRlciBvZiBhIGZvcm1hdHRlciBjYWxsLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBiaW5kaW5nIHBhcnQgdG8gZXZhbHVhdGVcbiAqIEBwYXJhbSBzaW5nbGVQYXRoIFdoZXRoZXIgdGhlcmUgaXMgb25lIG9yIG11bHRpcGxlIHBhdGggdG8gY29uc2lkZXJcbiAqIEByZXR1cm5zIFRoZSBzdHJpbmcgc25pcHBldCB0byBpbmNsdWRlIGluIHRoZSBvdmVyYWxsIGJpbmRpbmcgZGVmaW5pdGlvblxuICovXG5mdW5jdGlvbiBjb21waWxlUGF0aFBhcmFtZXRlcihleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4sIHNpbmdsZVBhdGggPSBmYWxzZSk6IHN0cmluZyB7XG5cdGxldCBvdXRWYWx1ZSA9IFwiXCI7XG5cdGlmIChleHByZXNzaW9uLl90eXBlID09PSBcIkNvbnN0YW50XCIpIHtcblx0XHRpZiAoZXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHQvLyBTcGVjaWFsIGNhc2Ugb3RoZXJ3aXNlIHRoZSBKU1Rva2VuaXplciBjb21wbGFpbnMgYWJvdXQgaW5jb3JyZWN0IGNvbnRlbnRcblx0XHRcdG91dFZhbHVlID0gYHZhbHVlOiAndW5kZWZpbmVkJ2A7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG91dFZhbHVlID0gYHZhbHVlOiAke2NvbXBpbGVDb25zdGFudChleHByZXNzaW9uLCB0cnVlKX1gO1xuXHRcdH1cblx0fSBlbHNlIGlmIChleHByZXNzaW9uLl90eXBlID09PSBcIlBhdGhJbk1vZGVsXCIpIHtcblx0XHRvdXRWYWx1ZSA9IGBwYXRoOiAnJHtjb21waWxlUGF0aEluTW9kZWwoZXhwcmVzc2lvbil9J2A7XG5cblx0XHRvdXRWYWx1ZSArPSBleHByZXNzaW9uLnR5cGUgPyBgLCB0eXBlOiAnJHtleHByZXNzaW9uLnR5cGV9J2AgOiBgLCB0YXJnZXRUeXBlOiAnYW55J2A7XG5cdFx0aWYgKGV4cHJlc3Npb24ubW9kZSkge1xuXHRcdFx0b3V0VmFsdWUgKz0gYCwgbW9kZTogJyR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5tb2RlKX0nYDtcblx0XHR9XG5cdFx0aWYgKGhhc0VsZW1lbnRzKGV4cHJlc3Npb24uY29uc3RyYWludHMpKSB7XG5cdFx0XHRvdXRWYWx1ZSArPSBgLCBjb25zdHJhaW50czogJHtjb21waWxlRXhwcmVzc2lvbihleHByZXNzaW9uLmNvbnN0cmFpbnRzKX1gO1xuXHRcdH1cblx0XHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKSkge1xuXHRcdFx0b3V0VmFsdWUgKz0gYCwgZm9ybWF0T3B0aW9uczogJHtjb21waWxlRXhwcmVzc2lvbihleHByZXNzaW9uLmZvcm1hdE9wdGlvbnMpfWA7XG5cdFx0fVxuXHRcdGlmIChoYXNFbGVtZW50cyhleHByZXNzaW9uLnBhcmFtZXRlcnMpKSB7XG5cdFx0XHRvdXRWYWx1ZSArPSBgLCBwYXJhbWV0ZXJzOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24ucGFyYW1ldGVycyl9YDtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIFwiXCI7XG5cdH1cblx0cmV0dXJuIHNpbmdsZVBhdGggPyBvdXRWYWx1ZSA6IGB7JHtvdXRWYWx1ZX19YDtcbn1cblxuZnVuY3Rpb24gaGFzRWxlbWVudHMob2JqOiBvYmplY3QgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcblx0cmV0dXJuICEhb2JqICYmIE9iamVjdC5rZXlzKG9iaikubGVuZ3RoID4gMDtcbn1cblxuLyoqXG4gKiBDb21waWxlIGEgYmluZGluZyBleHByZXNzaW9uIHBhdGguXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gY29tcGlsZS5cbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBwYXRoLlxuICovXG5mdW5jdGlvbiBjb21waWxlUGF0aEluTW9kZWw8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPik6IHN0cmluZyB7XG5cdHJldHVybiBgJHtleHByZXNzaW9uLm1vZGVsTmFtZSA/IGV4cHJlc3Npb24ubW9kZWxOYW1lICsgXCI+XCIgOiBcIlwifSR7ZXhwcmVzc2lvbi5wYXRofWA7XG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQTtBQUFBO0FBQUE7Ozs7Ozs7RUFpTk8sTUFBTUEs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
|