@sapui5/sap.fe.core 1.127.2 → 1.129.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 +1 -1
- package/src/sap/fe/core/ActionRuntime.js +3 -9
- package/src/sap/fe/core/ActionRuntime.ts +3 -7
- package/src/sap/fe/core/AppComponent.js +9 -19
- package/src/sap/fe/core/AppComponent.ts +2 -12
- package/src/sap/fe/core/AppStateHandler.js +3 -11
- package/src/sap/fe/core/AppStateHandler.ts +0 -7
- package/src/sap/fe/core/BaseController.js +4 -8
- package/src/sap/fe/core/BaseController.ts +0 -5
- package/src/sap/fe/core/CommonUtils.js +1 -9
- package/src/sap/fe/core/CommonUtils.ts +4 -8
- package/src/sap/fe/core/ExtensionAPI.js +10 -25
- package/src/sap/fe/core/ExtensionAPI.ts +4 -19
- package/src/sap/fe/core/InsightsFormattersExtension.js +5 -3
- package/src/sap/fe/core/PageController.js +7 -10
- package/src/sap/fe/core/PageController.ts +0 -3
- package/src/sap/fe/core/ResourceModel.js +3 -5
- package/src/sap/fe/core/ResourceModel.ts +0 -2
- package/src/sap/fe/core/ReuseComponent.js +8 -14
- package/src/sap/fe/core/ReuseComponent.ts +0 -6
- package/src/sap/fe/core/TemplateComponent.js +37 -9
- package/src/sap/fe/core/TemplateComponent.ts +3 -2
- package/src/sap/fe/core/TemplateModel.js +5 -5
- package/src/sap/fe/core/TemplateModel.ts +0 -1
- package/src/sap/fe/core/UIProvider.js +1 -1
- package/src/sap/fe/core/UIProvider.ts +44 -1
- package/src/sap/fe/core/buildingBlocks/BuildingBlockBase.js +7 -12
- package/src/sap/fe/core/buildingBlocks/BuildingBlockBase.ts +0 -5
- package/src/sap/fe/core/buildingBlocks/TraceInfo.js +61 -65
- package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +60 -63
- package/src/sap/fe/core/buildingBlocks/templating/AttributeModel.js +3 -3
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockFormatter.js +1 -1
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.js +21 -5
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.ts +0 -4
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.js +6 -18
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.ts +3 -20
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.js +5 -11
- package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.ts +0 -6
- package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlock.js +3 -3
- package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlockFragment.js +11 -10
- package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlockFragment.ts +0 -1
- package/src/sap/fe/core/controllerextensions/BaseControllerExtension.js +5 -7
- package/src/sap/fe/core/controllerextensions/BaseControllerExtension.ts +0 -1
- package/src/sap/fe/core/controllerextensions/BusyLocker.js +1 -1
- package/src/sap/fe/core/controllerextensions/CollaborativeDraft.js +3 -10
- package/src/sap/fe/core/controllerextensions/CollaborativeDraft.ts +0 -7
- package/src/sap/fe/core/controllerextensions/ContextSharing.js +5 -8
- package/src/sap/fe/core/controllerextensions/ContextSharing.ts +0 -2
- package/src/sap/fe/core/controllerextensions/EditFlow.js +225 -155
- package/src/sap/fe/core/controllerextensions/EditFlow.ts +248 -164
- package/src/sap/fe/core/controllerextensions/Feedback.js +1 -3
- package/src/sap/fe/core/controllerextensions/Feedback.ts +0 -2
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +4 -7
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +0 -3
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +8 -25
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +2 -21
- package/src/sap/fe/core/controllerextensions/InternalRouting.js +22 -34
- package/src/sap/fe/core/controllerextensions/InternalRouting.ts +25 -31
- package/src/sap/fe/core/controllerextensions/KPIManagement.js +8 -21
- package/src/sap/fe/core/controllerextensions/KPIManagement.ts +4 -15
- package/src/sap/fe/core/controllerextensions/MessageHandler.js +68 -31
- package/src/sap/fe/core/controllerextensions/MessageHandler.ts +78 -32
- package/src/sap/fe/core/controllerextensions/PageReady.js +4 -4
- package/src/sap/fe/core/controllerextensions/Paginator.js +4 -8
- package/src/sap/fe/core/controllerextensions/Paginator.ts +0 -4
- package/src/sap/fe/core/controllerextensions/Placeholder.js +4 -4
- package/src/sap/fe/core/controllerextensions/Recommendations.js +15 -24
- package/src/sap/fe/core/controllerextensions/Recommendations.ts +13 -20
- package/src/sap/fe/core/controllerextensions/Routing.js +4 -10
- package/src/sap/fe/core/controllerextensions/Routing.ts +0 -6
- package/src/sap/fe/core/controllerextensions/RoutingListener.js +1 -1
- package/src/sap/fe/core/controllerextensions/Share.js +17 -11
- package/src/sap/fe/core/controllerextensions/Share.ts +10 -5
- package/src/sap/fe/core/controllerextensions/SideEffects.js +49 -45
- package/src/sap/fe/core/controllerextensions/SideEffects.ts +54 -41
- package/src/sap/fe/core/controllerextensions/Telemetry.js +4 -4
- package/src/sap/fe/core/controllerextensions/ViewState.js +10 -34
- package/src/sap/fe/core/controllerextensions/ViewState.ts +3 -49
- package/src/sap/fe/core/controllerextensions/cards/CollaborationManager.js +6 -8
- package/src/sap/fe/core/controllerextensions/cards/CollaborationManager.ts +0 -1
- package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.js +1 -2
- package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.ts +0 -1
- package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.js +4 -3
- package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.ts +1 -1
- package/src/sap/fe/core/controllerextensions/dialog/OperationsDialog.block.js +16 -12
- package/src/sap/fe/core/controllerextensions/dialog/OperationsDialog.block.tsx +4 -1
- package/src/sap/fe/core/controllerextensions/editFlow/NotApplicableContextDialog.js +1 -1
- package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +126 -74
- package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.ts +158 -91
- package/src/sap/fe/core/controllerextensions/editFlow/draft.js +1 -22
- package/src/sap/fe/core/controllerextensions/editFlow/draft.ts +0 -20
- package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.js +10 -20
- package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.ts +11 -17
- package/src/sap/fe/core/controllerextensions/editFlow/editFlowConstants.js +1 -1
- package/src/sap/fe/core/controllerextensions/editFlow/operations/facade.js +191 -767
- package/src/sap/fe/core/controllerextensions/editFlow/operations/facade.ts +277 -1024
- package/src/sap/fe/core/controllerextensions/editFlow/operations.js +1 -1
- package/src/sap/fe/core/controllerextensions/editFlow/sticky.js +1 -6
- package/src/sap/fe/core/controllerextensions/editFlow/sticky.ts +0 -5
- package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +381 -250
- package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.ts +467 -301
- package/src/sap/fe/core/controllerextensions/pageReady/DataQueryWatcher.js +2 -6
- package/src/sap/fe/core/controllerextensions/pageReady/DataQueryWatcher.ts +0 -5
- package/src/sap/fe/core/controllerextensions/recommendations/Telemetry.js +2 -6
- package/src/sap/fe/core/controllerextensions/recommendations/Telemetry.ts +4 -6
- package/src/sap/fe/core/controllerextensions/routing/ContextPathHelper.js +1 -6
- package/src/sap/fe/core/controllerextensions/routing/ContextPathHelper.ts +0 -4
- package/src/sap/fe/core/controllerextensions/routing/NavigationReason.js +1 -1
- package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +4 -41
- package/src/sap/fe/core/controllerextensions/routing/RouterProxy.ts +1 -37
- package/src/sap/fe/core/controllerextensions/viewState/IViewStateContributor.js +1 -1
- package/src/sap/fe/core/controllerextensions/viewState/IViewStateContributor.ts +0 -1
- package/src/sap/fe/core/controls/Any.js +1 -2
- package/src/sap/fe/core/controls/Any.ts +0 -1
- package/src/sap/fe/core/controls/AnyElement.js +1 -2
- package/src/sap/fe/core/controls/AnyElement.ts +0 -1
- package/src/sap/fe/core/controls/CommandExecution.js +3 -3
- package/src/sap/fe/core/controls/ComponentLoader.js +23 -10
- package/src/sap/fe/core/controls/ComponentLoader.ts +0 -1
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.block.js +10 -13
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.block.tsx +0 -6
- package/src/sap/fe/core/controls/EventDelegateHook.js +8 -9
- package/src/sap/fe/core/controls/FormElementWrapper.js +7 -7
- package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +3 -1
- package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.block.js +140 -24
- package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.block.tsx +141 -10
- package/src/sap/fe/core/converters/ConverterContext.js +8 -30
- package/src/sap/fe/core/converters/ConverterContext.ts +7 -29
- package/src/sap/fe/core/converters/ManifestSettings.js +37 -1
- package/src/sap/fe/core/converters/ManifestSettings.ts +12 -3
- package/src/sap/fe/core/converters/ManifestWrapper.js +12 -40
- package/src/sap/fe/core/converters/ManifestWrapper.ts +13 -46
- package/src/sap/fe/core/converters/MetaModelConverter.js +44 -48
- package/src/sap/fe/core/converters/MetaModelConverter.ts +50 -48
- package/src/sap/fe/core/converters/TemplateConverter.js +3 -2
- package/src/sap/fe/core/converters/TemplateConverter.ts +0 -1
- package/src/sap/fe/core/converters/annotations/DataField.js +1 -28
- package/src/sap/fe/core/converters/annotations/DataField.ts +0 -26
- package/src/sap/fe/core/converters/common/AnnotationConverter.js +24 -19
- package/src/sap/fe/core/converters/controls/Common/Action.js +13 -26
- package/src/sap/fe/core/converters/controls/Common/Action.ts +13 -31
- package/src/sap/fe/core/converters/controls/Common/Chart.js +5 -6
- package/src/sap/fe/core/converters/controls/Common/Chart.ts +0 -5
- package/src/sap/fe/core/converters/controls/Common/Criticality.js +2 -4
- package/src/sap/fe/core/converters/controls/Common/Criticality.ts +1 -2
- package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +1 -5
- package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +0 -4
- package/src/sap/fe/core/converters/controls/Common/Form.js +3 -2
- package/src/sap/fe/core/converters/controls/Common/Form.ts +2 -1
- package/src/sap/fe/core/converters/controls/Common/KPI.js +11 -7
- package/src/sap/fe/core/converters/controls/Common/KPI.ts +11 -6
- package/src/sap/fe/core/converters/controls/Common/Table.js +159 -141
- package/src/sap/fe/core/converters/controls/Common/Table.ts +166 -122
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +5 -30
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +3 -29
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +43 -55
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +43 -47
- package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +1 -4
- package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +0 -3
- package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.js +1 -1
- package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +3 -8
- package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +2 -7
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +1 -11
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +0 -9
- package/src/sap/fe/core/converters/helpers/Aggregation.js +1 -10
- package/src/sap/fe/core/converters/helpers/Aggregation.ts +0 -9
- package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +1 -7
- package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +0 -6
- package/src/sap/fe/core/converters/helpers/DataFieldHelper.js +1 -9
- package/src/sap/fe/core/converters/helpers/DataFieldHelper.ts +0 -8
- package/src/sap/fe/core/converters/helpers/ID.js +1 -2
- package/src/sap/fe/core/converters/helpers/ID.ts +0 -1
- package/src/sap/fe/core/converters/helpers/InsightsHelpers.js +1 -2
- package/src/sap/fe/core/converters/helpers/InsightsHelpers.ts +0 -1
- package/src/sap/fe/core/converters/helpers/IssueManager.js +1 -1
- package/src/sap/fe/core/converters/helpers/Key.js +1 -5
- package/src/sap/fe/core/converters/helpers/Key.ts +0 -4
- package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.js +1 -2
- package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.ts +0 -1
- package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +1 -1
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +1 -7
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +0 -6
- package/src/sap/fe/core/converters/templates/ListReportConverter.js +6 -27
- package/src/sap/fe/core/converters/templates/ListReportConverter.ts +9 -26
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +1 -16
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +0 -15
- package/src/sap/fe/core/definition/FEDefinition.js +2550 -0
- package/src/sap/fe/core/designtime/AppComponent.designtime.js +11 -12
- package/src/sap/fe/core/designtime/AppComponent.designtime.ts +9 -10
- package/src/sap/fe/core/formatters/CollaborationFormatter.js +8 -2
- package/src/sap/fe/core/formatters/CollaborationFormatter.ts +0 -2
- package/src/sap/fe/core/formatters/CriticalityFormatter.js +1 -1
- package/src/sap/fe/core/formatters/FPMFormatter.js +1 -2
- package/src/sap/fe/core/formatters/FPMFormatter.ts +0 -1
- package/src/sap/fe/core/formatters/FiscalFormat.js +9 -14
- package/src/sap/fe/core/formatters/FiscalFormat.ts +0 -11
- package/src/sap/fe/core/formatters/KPIFormatter.js +1 -4
- package/src/sap/fe/core/formatters/KPIFormatter.ts +0 -3
- package/src/sap/fe/core/formatters/StandardFormatter.js +6 -3
- package/src/sap/fe/core/formatters/StandardFormatter.ts +6 -2
- package/src/sap/fe/core/formatters/ValueFormatter.js +1 -4
- package/src/sap/fe/core/formatters/ValueFormatter.ts +0 -3
- package/src/sap/fe/core/fpm/Component.js +14 -17
- package/src/sap/fe/core/fpm/Component.ts +7 -10
- package/src/sap/fe/core/fpm/manifest.json +1 -1
- package/src/sap/fe/core/helpers/AdaptiveCardExpressionCompiler.js +3 -10
- package/src/sap/fe/core/helpers/AdaptiveCardExpressionCompiler.ts +0 -9
- package/src/sap/fe/core/helpers/AppStartupHelper.js +1 -13
- package/src/sap/fe/core/helpers/AppStartupHelper.ts +0 -11
- package/src/sap/fe/core/helpers/BindingHelper.js +1 -4
- package/src/sap/fe/core/helpers/BindingHelper.ts +0 -3
- package/src/sap/fe/core/helpers/BindingToolkitEvaluator.js +1 -2
- package/src/sap/fe/core/helpers/BindingToolkitEvaluator.ts +0 -1
- package/src/sap/fe/core/helpers/DeleteHelper.js +61 -32
- package/src/sap/fe/core/helpers/DeleteHelper.ts +79 -33
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +1 -2
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +0 -1
- package/src/sap/fe/core/helpers/EditState.js +1 -1
- package/src/sap/fe/core/helpers/ExcelFormatHelper.js +1 -2
- package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +0 -1
- package/src/sap/fe/core/helpers/FPMHelper.js +1 -2
- package/src/sap/fe/core/helpers/FPMHelper.ts +0 -1
- package/src/sap/fe/core/helpers/KeepAliveHelper.js +1 -8
- package/src/sap/fe/core/helpers/KeepAliveHelper.ts +0 -7
- package/src/sap/fe/core/helpers/KeepAliveRefreshTypes.js +7 -1
- package/src/sap/fe/core/helpers/LoaderUtils.js +1 -1
- package/src/sap/fe/core/helpers/ManifestHelper.js +1 -3
- package/src/sap/fe/core/helpers/ManifestHelper.ts +0 -2
- package/src/sap/fe/core/helpers/MessageStrip.js +1 -1
- package/src/sap/fe/core/helpers/MetaModelFunction.js +3 -8
- package/src/sap/fe/core/helpers/MetaModelFunction.ts +0 -5
- package/src/sap/fe/core/helpers/MetaPath.js +1 -7
- package/src/sap/fe/core/helpers/MetaPath.ts +0 -6
- package/src/sap/fe/core/helpers/ModelHelper.js +55 -35
- package/src/sap/fe/core/helpers/ModelHelper.ts +64 -38
- package/src/sap/fe/core/helpers/PasteHelper.js +77 -24
- package/src/sap/fe/core/helpers/PasteHelper.ts +105 -23
- package/src/sap/fe/core/helpers/PromiseKeeper.js +1 -3
- package/src/sap/fe/core/helpers/PromiseKeeper.ts +0 -2
- package/src/sap/fe/core/helpers/RecommendationHelper.js +1 -4
- package/src/sap/fe/core/helpers/RecommendationHelper.ts +0 -3
- package/src/sap/fe/core/helpers/ResourceModelHelper.js +1 -3
- package/src/sap/fe/core/helpers/ResourceModelHelper.ts +3 -4
- package/src/sap/fe/core/helpers/SemanticKeyHelper.js +1 -2
- package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +0 -1
- package/src/sap/fe/core/helpers/SizeHelper.js +1 -2
- package/src/sap/fe/core/helpers/SizeHelper.ts +0 -1
- package/src/sap/fe/core/helpers/StableIdHelper.js +7 -17
- package/src/sap/fe/core/helpers/StableIdHelper.ts +7 -17
- package/src/sap/fe/core/helpers/StandardRecommendationHelper.js +1 -12
- package/src/sap/fe/core/helpers/StandardRecommendationHelper.ts +0 -11
- package/src/sap/fe/core/helpers/Synchronization.js +1 -1
- package/src/sap/fe/core/helpers/TitleHelper.js +1 -10
- package/src/sap/fe/core/helpers/TitleHelper.ts +0 -9
- package/src/sap/fe/core/helpers/ToES6Promise.js +1 -2
- package/src/sap/fe/core/helpers/ToES6Promise.ts +0 -1
- package/src/sap/fe/core/helpers/TypeGuards.js +1 -15
- package/src/sap/fe/core/helpers/TypeGuards.ts +0 -14
- package/src/sap/fe/core/helpers/WebSocket.js +1 -1
- package/src/sap/fe/core/library.js +10 -44
- package/src/sap/fe/core/library.support.js +1 -1
- package/src/sap/fe/core/library.ts +8 -45
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +1 -6
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +0 -5
- package/src/sap/fe/core/messagebundle.properties +12 -1
- package/src/sap/fe/core/messagebundle_ar.properties +8 -0
- package/src/sap/fe/core/messagebundle_bg.properties +8 -0
- package/src/sap/fe/core/messagebundle_ca.properties +8 -0
- package/src/sap/fe/core/messagebundle_cnr.properties +8 -0
- package/src/sap/fe/core/messagebundle_cs.properties +9 -1
- package/src/sap/fe/core/messagebundle_cy.properties +8 -0
- package/src/sap/fe/core/messagebundle_da.properties +8 -0
- package/src/sap/fe/core/messagebundle_de.properties +8 -0
- package/src/sap/fe/core/messagebundle_el.properties +8 -0
- package/src/sap/fe/core/messagebundle_en.properties +8 -0
- package/src/sap/fe/core/messagebundle_en_GB.properties +8 -0
- package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +144 -65
- package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +8 -0
- package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +273 -194
- package/src/sap/fe/core/messagebundle_es.properties +9 -1
- package/src/sap/fe/core/messagebundle_es_MX.properties +8 -0
- package/src/sap/fe/core/messagebundle_et.properties +8 -0
- package/src/sap/fe/core/messagebundle_fi.properties +8 -0
- package/src/sap/fe/core/messagebundle_fr.properties +8 -0
- package/src/sap/fe/core/messagebundle_fr_CA.properties +8 -0
- package/src/sap/fe/core/messagebundle_hi.properties +9 -1
- package/src/sap/fe/core/messagebundle_hr.properties +8 -0
- package/src/sap/fe/core/messagebundle_hu.properties +8 -0
- package/src/sap/fe/core/messagebundle_id.properties +12 -4
- package/src/sap/fe/core/messagebundle_it.properties +8 -0
- package/src/sap/fe/core/messagebundle_iw.properties +8 -0
- package/src/sap/fe/core/messagebundle_ja.properties +8 -0
- package/src/sap/fe/core/messagebundle_kk.properties +8 -0
- package/src/sap/fe/core/messagebundle_ko.properties +8 -0
- package/src/sap/fe/core/messagebundle_lt.properties +8 -0
- package/src/sap/fe/core/messagebundle_lv.properties +8 -0
- package/src/sap/fe/core/messagebundle_mk.properties +8 -0
- package/src/sap/fe/core/messagebundle_ms.properties +8 -0
- package/src/sap/fe/core/messagebundle_nl.properties +16 -8
- package/src/sap/fe/core/messagebundle_no.properties +8 -0
- package/src/sap/fe/core/messagebundle_pl.properties +8 -0
- package/src/sap/fe/core/messagebundle_pt.properties +8 -0
- package/src/sap/fe/core/messagebundle_pt_PT.properties +8 -0
- package/src/sap/fe/core/messagebundle_ro.properties +8 -0
- package/src/sap/fe/core/messagebundle_ru.properties +8 -0
- package/src/sap/fe/core/messagebundle_sh.properties +8 -0
- package/src/sap/fe/core/messagebundle_sk.properties +8 -0
- package/src/sap/fe/core/messagebundle_sl.properties +8 -0
- package/src/sap/fe/core/messagebundle_sr.properties +8 -0
- package/src/sap/fe/core/messagebundle_sv.properties +8 -0
- package/src/sap/fe/core/messagebundle_th.properties +12 -4
- package/src/sap/fe/core/messagebundle_tr.properties +8 -0
- package/src/sap/fe/core/messagebundle_uk.properties +10 -2
- package/src/sap/fe/core/messagebundle_vi.properties +8 -0
- package/src/sap/fe/core/messagebundle_zh_CN.properties +8 -0
- package/src/sap/fe/core/messagebundle_zh_TW.properties +8 -0
- package/src/sap/fe/core/operationsHelper.js +22 -7
- package/src/sap/fe/core/operationsHelper.ts +24 -5
- package/src/sap/fe/core/rootView/Fcl.controller.js +7 -27
- package/src/sap/fe/core/rootView/Fcl.controller.ts +0 -18
- package/src/sap/fe/core/rootView/NavContainer.controller.js +7 -12
- package/src/sap/fe/core/rootView/NavContainer.controller.ts +0 -5
- package/src/sap/fe/core/rootView/RootViewBaseController.js +10 -24
- package/src/sap/fe/core/rootView/RootViewBaseController.ts +3 -16
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +3 -3
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +3 -3
- package/src/sap/fe/core/services/CollaborationManagerServiceFactory.js +4 -4
- package/src/sap/fe/core/services/CollaborativeToolsServiceFactory.js +3 -3
- package/src/sap/fe/core/services/ContextSharingServiceFactory.js +3 -4
- package/src/sap/fe/core/services/ContextSharingServiceFactory.ts +0 -1
- package/src/sap/fe/core/services/EnvironmentServiceFactory.js +13 -20
- package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +11 -17
- package/src/sap/fe/core/services/NavigationServiceFactory.js +11 -21
- package/src/sap/fe/core/services/NavigationServiceFactory.ts +4 -17
- package/src/sap/fe/core/services/ResourceModelServiceFactory.js +3 -3
- package/src/sap/fe/core/services/RoutingServiceFactory.js +7 -19
- package/src/sap/fe/core/services/RoutingServiceFactory.ts +0 -12
- package/src/sap/fe/core/services/ShellServicesFactory.js +8 -44
- package/src/sap/fe/core/services/ShellServicesFactory.ts +1 -41
- package/src/sap/fe/core/services/SideEffectsServiceFactory.js +19 -60
- package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +14 -57
- package/src/sap/fe/core/services/TelemetryServiceFactory.js +6 -14
- package/src/sap/fe/core/services/TelemetryServiceFactory.ts +2 -10
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +17 -7
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +17 -3
- package/src/sap/fe/core/services/ValueHelpHistoryServiceFactory.js +11 -24
- package/src/sap/fe/core/services/ValueHelpHistoryServiceFactory.ts +0 -19
- package/src/sap/fe/core/services/collaborativeDraftServiceFactory.js +3 -31
- package/src/sap/fe/core/services/collaborativeDraftServiceFactory.ts +0 -27
- package/src/sap/fe/core/services/valueHelpService/HistoryOptOutProvider.js +1 -4
- package/src/sap/fe/core/services/valueHelpService/HistoryOptOutProvider.ts +0 -3
- package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +7 -7
- package/src/sap/fe/core/support/AnnotationIssue.support.js +1 -1
- package/src/sap/fe/core/support/CollectionFacetMissingID.support.js +1 -1
- package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.js +1 -1
- package/src/sap/fe/core/support/CommonHelper.js +4 -1
- package/src/sap/fe/core/support/Diagnostics.js +1 -1
- package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.js +1 -1
- package/src/sap/fe/core/templating/ActionHelper.js +1 -2
- package/src/sap/fe/core/templating/ActionHelper.ts +0 -1
- package/src/sap/fe/core/templating/CommonFormatters.js +1 -2
- package/src/sap/fe/core/templating/CommonFormatters.ts +0 -1
- package/src/sap/fe/core/templating/CriticalityFormatters.js +1 -6
- package/src/sap/fe/core/templating/CriticalityFormatters.ts +0 -5
- package/src/sap/fe/core/templating/DataFieldFormatters.js +1 -2
- package/src/sap/fe/core/templating/DataFieldFormatters.ts +0 -1
- package/src/sap/fe/core/templating/DataModelPathHelper.js +1 -18
- package/src/sap/fe/core/templating/DataModelPathHelper.ts +0 -17
- package/src/sap/fe/core/templating/DisplayModeFormatter.js +6 -1
- package/src/sap/fe/core/templating/EntitySetHelper.js +1 -4
- package/src/sap/fe/core/templating/EntitySetHelper.ts +0 -3
- package/src/sap/fe/core/templating/EntityTypeHelper.js +4 -5
- package/src/sap/fe/core/templating/EntityTypeHelper.ts +3 -4
- package/src/sap/fe/core/templating/FieldControlHelper.js +4 -9
- package/src/sap/fe/core/templating/FieldControlHelper.ts +3 -9
- package/src/sap/fe/core/templating/FilterTemplating.js +1 -1
- package/src/sap/fe/core/templating/PropertyFormatters.js +1 -1
- package/src/sap/fe/core/templating/PropertyHelper.js +1 -31
- package/src/sap/fe/core/templating/PropertyHelper.ts +0 -30
- package/src/sap/fe/core/templating/SemanticObjectHelper.js +1 -7
- package/src/sap/fe/core/templating/SemanticObjectHelper.ts +0 -6
- package/src/sap/fe/core/templating/UIFormatters.js +18 -14
- package/src/sap/fe/core/templating/UIFormatters.ts +30 -18
- package/src/sap/fe/core/type/Date.js +3 -6
- package/src/sap/fe/core/type/Date.ts +0 -3
- package/src/sap/fe/core/type/DateTimeWithTimezone.js +3 -3
- package/src/sap/fe/core/type/EDM.js +1 -1
- package/src/sap/fe/core/type/Email.js +3 -3
- package/src/sap/fe/core/type/FiscalDate.js +3 -9
- package/src/sap/fe/core/type/FiscalDate.ts +0 -6
- package/src/sap/fe/core/type/InputMask.js +3 -7
- package/src/sap/fe/core/type/InputMask.ts +0 -4
|
@@ -0,0 +1,2550 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* SAP UI development toolkit for HTML5 (SAPUI5)
|
|
3
|
+
* (c) Copyright 2009-2024 SAP SE. All rights reserved
|
|
4
|
+
*/
|
|
5
|
+
sap.ui.define([], function() {
|
|
6
|
+
var FEDefinition;
|
|
7
|
+
/******/ (function() { // webpackBootstrap
|
|
8
|
+
/******/ "use strict";
|
|
9
|
+
/******/ var __webpack_modules__ = ({
|
|
10
|
+
|
|
11
|
+
/***/ 462:
|
|
12
|
+
/***/ (function(__unused_webpack_module, exports) {
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
17
|
+
value: true
|
|
18
|
+
}));
|
|
19
|
+
exports.Placement = exports.BaseDefinition = void 0;
|
|
20
|
+
exports.annotation = annotation;
|
|
21
|
+
exports.configurable = configurable;
|
|
22
|
+
let Placement = exports.Placement = /*#__PURE__*/function (Placement) {
|
|
23
|
+
Placement["After"] = "After";
|
|
24
|
+
Placement["Before"] = "Before";
|
|
25
|
+
Placement["End"] = "End";
|
|
26
|
+
return Placement;
|
|
27
|
+
}({});
|
|
28
|
+
class BaseDefinition {
|
|
29
|
+
constructor(metaPath, configuration) {
|
|
30
|
+
this.annotationPath = metaPath?.getPath();
|
|
31
|
+
for (const configurablePropertiesKey in this.__configurableProperties) {
|
|
32
|
+
const configSettings = this.__configurableProperties[configurablePropertiesKey];
|
|
33
|
+
if (configSettings) {
|
|
34
|
+
const configurationValue = configuration[configSettings.aliasFor];
|
|
35
|
+
if (configurationValue !== undefined) {
|
|
36
|
+
this[configurablePropertiesKey] = configSettings.validator(configurationValue);
|
|
37
|
+
} else {
|
|
38
|
+
this[configurablePropertiesKey] = configSettings.defaultValue;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const targetObject = metaPath?.getTarget();
|
|
43
|
+
if (targetObject) {
|
|
44
|
+
for (const annotationPropertiesKey in this.__annotationProperties) {
|
|
45
|
+
const configSettings = this.__annotationProperties[annotationPropertiesKey];
|
|
46
|
+
if (configSettings) {
|
|
47
|
+
const configurationValue = targetObject.annotations._annotations?.[configSettings.term];
|
|
48
|
+
if (configurationValue !== undefined && configurationValue !== null) {
|
|
49
|
+
this[annotationPropertiesKey] = configurationValue.valueOf();
|
|
50
|
+
} else {
|
|
51
|
+
this[annotationPropertiesKey] = configSettings.defaultValue;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
getConfiguration() {
|
|
58
|
+
const outObj = {};
|
|
59
|
+
for (const configurablePropertiesKey in this.__configurableProperties) {
|
|
60
|
+
const configSettings = this.__configurableProperties[configurablePropertiesKey];
|
|
61
|
+
if (configSettings) {
|
|
62
|
+
outObj[configSettings.aliasFor] = this[configurablePropertiesKey];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return outObj;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.BaseDefinition = BaseDefinition;
|
|
69
|
+
function noop(value) {
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
function configurable(propertyConfiguration = {}) {
|
|
73
|
+
return function (target, propertyKey, propertyDescriptor) {
|
|
74
|
+
const localPropertyConfiguration = {
|
|
75
|
+
name: propertyKey,
|
|
76
|
+
validator: propertyConfiguration.validator || noop,
|
|
77
|
+
aliasFor: propertyConfiguration.aliasFor || propertyKey,
|
|
78
|
+
defaultValue: propertyDescriptor.initializer?.()
|
|
79
|
+
};
|
|
80
|
+
const targetPrototype = target.constructor.prototype;
|
|
81
|
+
if (!targetPrototype.__configurableProperties) {
|
|
82
|
+
targetPrototype.__configurableProperties = {};
|
|
83
|
+
}
|
|
84
|
+
delete propertyDescriptor?.initializer;
|
|
85
|
+
targetPrototype.__configurableProperties[propertyKey] = localPropertyConfiguration;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function annotation(annotationConfiguration) {
|
|
89
|
+
return function (target, propertyKey, propertyDescriptor) {
|
|
90
|
+
const localAnnotationConfiguration = {
|
|
91
|
+
name: propertyKey,
|
|
92
|
+
term: annotationConfiguration.term,
|
|
93
|
+
defaultValue: propertyDescriptor.initializer?.()
|
|
94
|
+
};
|
|
95
|
+
const targetPrototype = target.constructor.prototype;
|
|
96
|
+
if (!targetPrototype.__annotationProperties) {
|
|
97
|
+
targetPrototype.__annotationProperties = {};
|
|
98
|
+
}
|
|
99
|
+
targetPrototype.__annotationProperties[propertyKey] = localAnnotationConfiguration;
|
|
100
|
+
delete propertyDescriptor.initializer;
|
|
101
|
+
return propertyDescriptor;
|
|
102
|
+
}; // This is technically an accessor decorator, but somehow the compiler doesn't like it if i declare it as such.;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
/***/ }),
|
|
107
|
+
|
|
108
|
+
/***/ 333:
|
|
109
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
114
|
+
value: true
|
|
115
|
+
}));
|
|
116
|
+
exports["default"] = void 0;
|
|
117
|
+
var _TypeGuards = __webpack_require__(331);
|
|
118
|
+
function enhancePath(sBasePath, sPathAddition) {
|
|
119
|
+
if (sPathAddition) {
|
|
120
|
+
if (sPathAddition.startsWith("/")) {
|
|
121
|
+
return sPathAddition;
|
|
122
|
+
} else if (sPathAddition.startsWith("@")) {
|
|
123
|
+
return sBasePath + sPathAddition;
|
|
124
|
+
} else if (!sBasePath.endsWith("/")) {
|
|
125
|
+
return sBasePath + "/" + sPathAddition;
|
|
126
|
+
} else {
|
|
127
|
+
return sBasePath + sPathAddition;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return sBasePath;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
*
|
|
134
|
+
*/
|
|
135
|
+
class MetaPath {
|
|
136
|
+
/**
|
|
137
|
+
* Create the MetaPath object.
|
|
138
|
+
* @param convertedMetadata The current model converter output
|
|
139
|
+
* @param metaPath The current object metaPath
|
|
140
|
+
* @param contextPath The current context
|
|
141
|
+
*/
|
|
142
|
+
constructor(convertedMetadata, metaPath, contextPath) {
|
|
143
|
+
this.convertedMetadata = convertedMetadata;
|
|
144
|
+
this.metaPath = metaPath;
|
|
145
|
+
this.contextPath = contextPath;
|
|
146
|
+
this.navigationProperties = [];
|
|
147
|
+
this.contextNavigationProperties = [];
|
|
148
|
+
this.absolutePath = enhancePath(contextPath, metaPath);
|
|
149
|
+
this.relativePath = this.absolutePath.replace(contextPath, "");
|
|
150
|
+
if (this.relativePath.startsWith("/")) {
|
|
151
|
+
this.relativePath = this.relativePath.substring(1);
|
|
152
|
+
}
|
|
153
|
+
const resolvedMetaPath = this.convertedMetadata.resolvePath(this.absolutePath);
|
|
154
|
+
const resolvedContextPath = this.convertedMetadata.resolvePath(contextPath);
|
|
155
|
+
if (resolvedMetaPath.target === undefined || resolvedMetaPath.target === null) {
|
|
156
|
+
throw new Error(`No annotation target found for ${metaPath}`);
|
|
157
|
+
}
|
|
158
|
+
this.targetObject = resolvedMetaPath.target;
|
|
159
|
+
let rootEntitySet;
|
|
160
|
+
let currentEntitySet;
|
|
161
|
+
let currentEntityType;
|
|
162
|
+
let navigatedPaths = [];
|
|
163
|
+
resolvedMetaPath.objectPath.forEach(objectPart => {
|
|
164
|
+
if ((0, _TypeGuards.isServiceObject)(objectPart)) {
|
|
165
|
+
switch (objectPart._type) {
|
|
166
|
+
case "NavigationProperty":
|
|
167
|
+
navigatedPaths.push(objectPart.name);
|
|
168
|
+
this.navigationProperties.push(objectPart);
|
|
169
|
+
currentEntityType = objectPart.targetType;
|
|
170
|
+
if (currentEntitySet?.navigationPropertyBinding.hasOwnProperty(navigatedPaths.join("/"))) {
|
|
171
|
+
currentEntitySet = currentEntitySet.navigationPropertyBinding[navigatedPaths.join("/")];
|
|
172
|
+
navigatedPaths = [];
|
|
173
|
+
}
|
|
174
|
+
break;
|
|
175
|
+
case "EntitySet":
|
|
176
|
+
if (rootEntitySet === undefined) {
|
|
177
|
+
rootEntitySet = objectPart;
|
|
178
|
+
}
|
|
179
|
+
currentEntitySet = objectPart;
|
|
180
|
+
currentEntityType = currentEntitySet.entityType;
|
|
181
|
+
break;
|
|
182
|
+
case "EntityType":
|
|
183
|
+
if (currentEntityType === undefined) {
|
|
184
|
+
currentEntityType = objectPart;
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
default:
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
resolvedContextPath.objectPath.forEach(objectPart => {
|
|
193
|
+
rootEntitySet = this.getResolvedContextPath(objectPart, currentEntityType, rootEntitySet);
|
|
194
|
+
});
|
|
195
|
+
if (rootEntitySet === undefined || currentEntityType === undefined) {
|
|
196
|
+
throw new Error("MetaPath doesn't contain an entitySet -> Should never happen");
|
|
197
|
+
}
|
|
198
|
+
this.serviceObjectPath = this.contextPath;
|
|
199
|
+
if (this.navigationProperties.length) {
|
|
200
|
+
this.serviceObjectPath += "/" + this.navigationProperties.map(nav => nav.name).join("/");
|
|
201
|
+
}
|
|
202
|
+
this.rootEntitySet = rootEntitySet;
|
|
203
|
+
this.currentEntitySet = currentEntitySet;
|
|
204
|
+
this.currentEntityType = currentEntityType;
|
|
205
|
+
}
|
|
206
|
+
getResolvedContextPath(objectPart, currentEntityType, rootEntitySet) {
|
|
207
|
+
if ((0, _TypeGuards.isServiceObject)(objectPart)) {
|
|
208
|
+
switch (objectPart._type) {
|
|
209
|
+
case "NavigationProperty":
|
|
210
|
+
this.contextNavigationProperties.push(objectPart);
|
|
211
|
+
break;
|
|
212
|
+
case "EntitySet":
|
|
213
|
+
if (this.contextRootEntitySet === undefined) {
|
|
214
|
+
this.contextRootEntitySet = objectPart;
|
|
215
|
+
}
|
|
216
|
+
if (rootEntitySet === undefined && objectPart.entityType === currentEntityType) {
|
|
217
|
+
rootEntitySet = objectPart;
|
|
218
|
+
}
|
|
219
|
+
break;
|
|
220
|
+
default:
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return rootEntitySet;
|
|
225
|
+
}
|
|
226
|
+
getContextPath() {
|
|
227
|
+
return this.contextPath;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Retrieve the absolute path for this MetaPath.
|
|
232
|
+
* @param sPathPart The path to evaluate
|
|
233
|
+
* @returns The absolute path
|
|
234
|
+
*/
|
|
235
|
+
getPath(sPathPart) {
|
|
236
|
+
return enhancePath(this.absolutePath, sPathPart);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Retrieve the path relative to the context for this MetaPath.
|
|
241
|
+
* @param sPathPart The path to evaluate
|
|
242
|
+
* @returns The relative path
|
|
243
|
+
*/
|
|
244
|
+
getRelativePath(sPathPart) {
|
|
245
|
+
return enhancePath(this.relativePath, sPathPart);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Retrieve the typed target for this object call.
|
|
250
|
+
* @returns The typed target object
|
|
251
|
+
*/
|
|
252
|
+
getTarget() {
|
|
253
|
+
return this.targetObject;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Retrieve the closest entityset in the path.
|
|
258
|
+
* @returns The closest entityset
|
|
259
|
+
*/
|
|
260
|
+
getClosestEntitySet() {
|
|
261
|
+
let closestEntitySet = this.rootEntitySet;
|
|
262
|
+
for (const navigationProperty of this.navigationProperties) {
|
|
263
|
+
const navigationPropertyBindingElement = closestEntitySet.navigationPropertyBinding[navigationProperty.name];
|
|
264
|
+
if (navigationPropertyBindingElement) {
|
|
265
|
+
closestEntitySet = navigationPropertyBindingElement;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return closestEntitySet;
|
|
269
|
+
}
|
|
270
|
+
getClosestEntityType() {
|
|
271
|
+
let closestEntityType = this.rootEntitySet.entityType;
|
|
272
|
+
for (const navigationProperty of this.navigationProperties) {
|
|
273
|
+
closestEntityType = navigationProperty.targetType;
|
|
274
|
+
}
|
|
275
|
+
return closestEntityType;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Retrieve the closest entityset in the path.
|
|
280
|
+
* @returns The closest entityset
|
|
281
|
+
*/
|
|
282
|
+
getContextClosestEntitySet() {
|
|
283
|
+
let closestEntitySet = this.contextRootEntitySet;
|
|
284
|
+
if (closestEntitySet === undefined) {
|
|
285
|
+
return closestEntitySet;
|
|
286
|
+
}
|
|
287
|
+
const nonNullEntitySet = closestEntitySet;
|
|
288
|
+
for (const navigationProperty of this.contextNavigationProperties) {
|
|
289
|
+
if (nonNullEntitySet.navigationPropertyBinding[navigationProperty.name]) {
|
|
290
|
+
closestEntitySet = nonNullEntitySet.navigationPropertyBinding[navigationProperty.name];
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return closestEntitySet;
|
|
294
|
+
}
|
|
295
|
+
getNavigationProperties() {
|
|
296
|
+
return this.navigationProperties;
|
|
297
|
+
}
|
|
298
|
+
getMetaPathForPath(targetPath) {
|
|
299
|
+
try {
|
|
300
|
+
return new MetaPath(this.convertedMetadata, enhancePath(this.serviceObjectPath, targetPath), this.contextPath);
|
|
301
|
+
} catch (_error) {
|
|
302
|
+
return undefined;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
getMetaPathForObject(targetObject) {
|
|
306
|
+
if ((0, _TypeGuards.isAnnotationPath)(targetObject)) {
|
|
307
|
+
return this.getMetaPathForPath(targetObject.value);
|
|
308
|
+
} else if ((0, _TypeGuards.isPathAnnotationExpression)(targetObject)) {
|
|
309
|
+
return this.getMetaPathForPath(targetObject.path);
|
|
310
|
+
} else {
|
|
311
|
+
const metaPathApp = targetObject.fullyQualifiedName.replace(this.rootEntitySet.entityType.fullyQualifiedName, this.contextPath);
|
|
312
|
+
return new MetaPath(this.convertedMetadata, metaPathApp, this.contextPath);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
getConvertedMetadata() {
|
|
316
|
+
return this.convertedMetadata;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
exports["default"] = MetaPath;
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
/***/ }),
|
|
323
|
+
|
|
324
|
+
/***/ 438:
|
|
325
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
330
|
+
value: true
|
|
331
|
+
}));
|
|
332
|
+
exports["default"] = void 0;
|
|
333
|
+
var _BaseDefinition = __webpack_require__(462);
|
|
334
|
+
var _EntitySet2 = _interopRequireDefault(__webpack_require__(827));
|
|
335
|
+
var _TypeGuards = __webpack_require__(331);
|
|
336
|
+
var _dec, _dec2, _dec3, _class, _descriptor, _descriptor2, _descriptor3;
|
|
337
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
338
|
+
function _initializerDefineProperty(e, i, r, l) { r && Object.defineProperty(e, i, { enumerable: r.enumerable, configurable: r.configurable, writable: r.writable, value: r.initializer ? r.initializer.call(l) : void 0 }); }
|
|
339
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
340
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
341
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
342
|
+
function _applyDecoratedDescriptor(i, e, r, n, l) { var a = {}; return Object.keys(n).forEach(function (i) { a[i] = n[i]; }), a.enumerable = !!a.enumerable, a.configurable = !!a.configurable, ("value" in a || a.initializer) && (a.writable = !0), a = r.slice().reverse().reduce(function (r, n) { return n(i, e, r) || r; }, a), l && void 0 !== a.initializer && (a.value = a.initializer ? a.initializer.call(l) : void 0, a.initializer = void 0), void 0 === a.initializer ? (Object.defineProperty(i, e, a), null) : a; }
|
|
343
|
+
function _initializerWarningHelper(r, e) { throw Error("Decorating class property failed. Please ensure that transform-class-properties is enabled and runs after the decorators transform."); }
|
|
344
|
+
let FilterField = (_dec = (0, _BaseDefinition.configurable)(), _dec2 = (0, _BaseDefinition.configurable)(), _dec3 = (0, _BaseDefinition.configurable)(), (_class = class FilterField extends _BaseDefinition.BaseDefinition {
|
|
345
|
+
get label() {
|
|
346
|
+
return this.filterFieldProperty.getTarget().annotations.Common?.Label?.toString() ?? this.filterFieldProperty.getTarget().name;
|
|
347
|
+
}
|
|
348
|
+
constructor(filterFieldProperty, filterFieldConfiguration) {
|
|
349
|
+
super(filterFieldProperty, filterFieldConfiguration);
|
|
350
|
+
_initializerDefineProperty(this, "group", _descriptor, this);
|
|
351
|
+
_initializerDefineProperty(this, "groupLabel", _descriptor2, this);
|
|
352
|
+
_initializerDefineProperty(this, "visible", _descriptor3, this);
|
|
353
|
+
this.filterFieldProperty = filterFieldProperty;
|
|
354
|
+
}
|
|
355
|
+
}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, "group", [_dec], {
|
|
356
|
+
configurable: true,
|
|
357
|
+
enumerable: true,
|
|
358
|
+
writable: true,
|
|
359
|
+
initializer: null
|
|
360
|
+
}), _descriptor2 = _applyDecoratedDescriptor(_class.prototype, "groupLabel", [_dec2], {
|
|
361
|
+
configurable: true,
|
|
362
|
+
enumerable: true,
|
|
363
|
+
writable: true,
|
|
364
|
+
initializer: null
|
|
365
|
+
}), _descriptor3 = _applyDecoratedDescriptor(_class.prototype, "visible", [_dec3], {
|
|
366
|
+
configurable: true,
|
|
367
|
+
enumerable: true,
|
|
368
|
+
writable: true,
|
|
369
|
+
initializer: null
|
|
370
|
+
})), _class));
|
|
371
|
+
class FilterBar {
|
|
372
|
+
constructor(selectionFields, filterBarConfiguration, metaPath) {
|
|
373
|
+
this.selectionFields = selectionFields;
|
|
374
|
+
this.filterBarConfiguration = filterBarConfiguration;
|
|
375
|
+
this.metaPath = metaPath;
|
|
376
|
+
}
|
|
377
|
+
getFilterGroups() {
|
|
378
|
+
const filterFacets = this.metaPath.getClosestEntityType().annotations.UI?.FilterFacets;
|
|
379
|
+
const filterFieldsGroup = {};
|
|
380
|
+
if (!filterFacets) {
|
|
381
|
+
const fieldGroups = Object.keys(this.metaPath.getClosestEntityType().annotations.UI ?? {}).filter(key => {
|
|
382
|
+
return key.startsWith("FieldGroup");
|
|
383
|
+
}).map(key => {
|
|
384
|
+
return this.metaPath.getClosestEntityType().annotations.UI?.[key];
|
|
385
|
+
});
|
|
386
|
+
for (const fieldGroup of fieldGroups) {
|
|
387
|
+
fieldGroup.Data.forEach(fieldGroupEntry => {
|
|
388
|
+
switch (fieldGroupEntry.$Type) {
|
|
389
|
+
case "com.sap.vocabularies.UI.v1.DataField":
|
|
390
|
+
{
|
|
391
|
+
const fieldGroupValue = fieldGroupEntry.Value;
|
|
392
|
+
if ((0, _TypeGuards.isPathAnnotationExpression)(fieldGroupValue) && fieldGroupValue.$target) {
|
|
393
|
+
filterFieldsGroup[fieldGroupValue.$target.fullyQualifiedName] = {
|
|
394
|
+
group: fieldGroup.fullyQualifiedName,
|
|
395
|
+
groupLabel: fieldGroup.Label?.toString() ?? fieldGroup.annotations?.Common?.Label?.toString() ?? fieldGroup.qualifier
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
default:
|
|
401
|
+
// Not supported
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
} else {
|
|
407
|
+
filterFacets.forEach(filterFacet => {
|
|
408
|
+
const filterFacetTarget = filterFacet.Target.$target;
|
|
409
|
+
if ((0, _TypeGuards.isAnnotationOfType)(filterFacetTarget, "com.sap.vocabularies.UI.v1.FieldGroupType")) {
|
|
410
|
+
filterFacetTarget.Data.forEach(fieldGroupEntry => {
|
|
411
|
+
switch (fieldGroupEntry.$Type) {
|
|
412
|
+
case "com.sap.vocabularies.UI.v1.DataField":
|
|
413
|
+
{
|
|
414
|
+
const fieldGroupValue = fieldGroupEntry.Value;
|
|
415
|
+
if ((0, _TypeGuards.isPathAnnotationExpression)(fieldGroupValue) && fieldGroupValue.$target) {
|
|
416
|
+
filterFieldsGroup[fieldGroupValue.$target.fullyQualifiedName] = {
|
|
417
|
+
group: filterFacet.ID?.toString(),
|
|
418
|
+
groupLabel: filterFacet.Label?.toString()
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
default:
|
|
424
|
+
// Not supported
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
return filterFieldsGroup;
|
|
432
|
+
}
|
|
433
|
+
getFilterFields() {
|
|
434
|
+
const filterGroups = this.getFilterGroups();
|
|
435
|
+
const consideredProperties = {};
|
|
436
|
+
const fromSelectionField = this.selectionFields.filter(_TypeGuards.isValidPropertyPathExpression).map(field => {
|
|
437
|
+
const metaPathForProperty = this.metaPath.getMetaPathForPath(field.value);
|
|
438
|
+
if (metaPathForProperty) {
|
|
439
|
+
consideredProperties[metaPathForProperty.getTarget().fullyQualifiedName] = true;
|
|
440
|
+
return new FilterField(metaPathForProperty, {
|
|
441
|
+
group: filterGroups[metaPathForProperty.getTarget().fullyQualifiedName]?.group,
|
|
442
|
+
groupLabel: filterGroups[metaPathForProperty.getTarget().fullyQualifiedName]?.groupLabel,
|
|
443
|
+
visible: true
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}).filter(field => {
|
|
447
|
+
return !!field;
|
|
448
|
+
});
|
|
449
|
+
const nonFilterableProperties = new _EntitySet2.default(this.metaPath).getNonFilterableProperties();
|
|
450
|
+
this.metaPath.getClosestEntityType().entityProperties.forEach(property => {
|
|
451
|
+
if (!consideredProperties[property.fullyQualifiedName] && !nonFilterableProperties.includes(property) && property.targetType === undefined && property.annotations.UI?.Hidden?.valueOf() !== true) {
|
|
452
|
+
consideredProperties[property.fullyQualifiedName] = true;
|
|
453
|
+
fromSelectionField.push(new FilterField(this.metaPath.getMetaPathForPath(property.name), {
|
|
454
|
+
group: filterGroups[property.fullyQualifiedName]?.group,
|
|
455
|
+
groupLabel: filterGroups[property.fullyQualifiedName]?.groupLabel,
|
|
456
|
+
visible: false
|
|
457
|
+
}));
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
return fromSelectionField;
|
|
461
|
+
}
|
|
462
|
+
isSearchSupported() {
|
|
463
|
+
return new _EntitySet2.default(this.metaPath).isSearchAllowed();
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
exports["default"] = FilterBar;
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
/***/ }),
|
|
470
|
+
|
|
471
|
+
/***/ 274:
|
|
472
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
477
|
+
value: true
|
|
478
|
+
}));
|
|
479
|
+
exports.DefinitionPage = void 0;
|
|
480
|
+
var _FilterBar = _interopRequireDefault(__webpack_require__(438));
|
|
481
|
+
var _Identification2 = __webpack_require__(877);
|
|
482
|
+
var _LineItem2 = __webpack_require__(384);
|
|
483
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
484
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
485
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
486
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
487
|
+
class DefinitionPage {
|
|
488
|
+
constructor(metaPath) {
|
|
489
|
+
_defineProperty(this, "requestSet", new Set());
|
|
490
|
+
this.metaPath = metaPath;
|
|
491
|
+
}
|
|
492
|
+
getMetaPath() {
|
|
493
|
+
return this.metaPath;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Gets the target entity set identification annotation if available.
|
|
498
|
+
*
|
|
499
|
+
* @returns Identification annotation wrapper
|
|
500
|
+
*/
|
|
501
|
+
getIdentification() {
|
|
502
|
+
const targetEntityType = this.metaPath.getClosestEntityType();
|
|
503
|
+
const idAnnotation = targetEntityType.annotations.UI?.Identification;
|
|
504
|
+
if (idAnnotation) {
|
|
505
|
+
return new _Identification2._Identification(idAnnotation, this.metaPath);
|
|
506
|
+
} else {
|
|
507
|
+
return undefined;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Retrieves the LineItem annotation for the target entity set
|
|
513
|
+
* @returns LineItem annotation
|
|
514
|
+
*/
|
|
515
|
+
getTableVisualization() {
|
|
516
|
+
return _LineItem2._LineItem.fromSPV(this._getTableVisualizationAnnotation(), this.metaPath);
|
|
517
|
+
}
|
|
518
|
+
getFilterBarDefinition(filterBarConfiguration) {
|
|
519
|
+
const targetEntityType = this.metaPath.getClosestEntityType();
|
|
520
|
+
//this.tracer.markRequest("Page.getFilterBarDefinition", targetEntityType);
|
|
521
|
+
let selectionField = targetEntityType.annotations.UI?.SelectionFields;
|
|
522
|
+
if (!selectionField) {
|
|
523
|
+
selectionField = Object.assign([], {
|
|
524
|
+
term: "com.sap.vocabularies.UI.v1.SelectionFields"
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
//this.tracer.endMarkRequest("Page.getFilterBarDefinition");
|
|
528
|
+
return new _FilterBar.default(selectionField, filterBarConfiguration, this.metaPath);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Create a default LineItem annotation for the target entity type based on properties
|
|
533
|
+
* @returns LineItem annotation
|
|
534
|
+
*/
|
|
535
|
+
createDefaultTableVisualization() {
|
|
536
|
+
return _LineItem2._LineItem.createDefault(this.metaPath);
|
|
537
|
+
}
|
|
538
|
+
_getTableVisualizationAnnotation() {
|
|
539
|
+
const targetEntityType = this.metaPath.getClosestEntityType();
|
|
540
|
+
const spv = targetEntityType.annotations.UI?.SelectionPresentationVariant;
|
|
541
|
+
if (spv) {
|
|
542
|
+
if (spv.PresentationVariant.Visualizations.find(v => v.$target?.term === "com.sap.vocabularies.UI.v1.LineItem")) {
|
|
543
|
+
return spv;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
const pv = targetEntityType.annotations.UI?.PresentationVariant;
|
|
547
|
+
if (pv?.Visualizations) {
|
|
548
|
+
if (pv.Visualizations.find(v => v.$target?.term === "com.sap.vocabularies.UI.v1.LineItem")) {
|
|
549
|
+
return pv;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return targetEntityType.annotations.UI?.LineItem;
|
|
553
|
+
}
|
|
554
|
+
addDataToRequest(propertyPath) {
|
|
555
|
+
// Add data to request
|
|
556
|
+
this.requestSet.add(propertyPath);
|
|
557
|
+
}
|
|
558
|
+
getQueryComponents() {
|
|
559
|
+
const select = [];
|
|
560
|
+
const expand = [];
|
|
561
|
+
this.requestSet.forEach(property => {
|
|
562
|
+
const parts = property.split("/");
|
|
563
|
+
if (parts.length > 1 && parts[0]) {
|
|
564
|
+
expand.push(parts[0]);
|
|
565
|
+
} else {
|
|
566
|
+
select.push(property);
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
const query = {
|
|
570
|
+
$format: "json",
|
|
571
|
+
$select: select.join(",")
|
|
572
|
+
};
|
|
573
|
+
if (expand.length > 0) {
|
|
574
|
+
query.$expand = expand.join(",");
|
|
575
|
+
}
|
|
576
|
+
return query;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
exports.DefinitionPage = DefinitionPage;
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
/***/ }),
|
|
583
|
+
|
|
584
|
+
/***/ 829:
|
|
585
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
590
|
+
value: true
|
|
591
|
+
}));
|
|
592
|
+
var _exportNames = {
|
|
593
|
+
DefinitionPage: true,
|
|
594
|
+
_DataField: true,
|
|
595
|
+
_LineItem: true,
|
|
596
|
+
DefinitionContext: true
|
|
597
|
+
};
|
|
598
|
+
Object.defineProperty(exports, "DefinitionContext", ({
|
|
599
|
+
enumerable: true,
|
|
600
|
+
get: function () {
|
|
601
|
+
return _DefinitionContext.DefinitionContext;
|
|
602
|
+
}
|
|
603
|
+
}));
|
|
604
|
+
Object.defineProperty(exports, "DefinitionPage", ({
|
|
605
|
+
enumerable: true,
|
|
606
|
+
get: function () {
|
|
607
|
+
return _DefinitionPage.DefinitionPage;
|
|
608
|
+
}
|
|
609
|
+
}));
|
|
610
|
+
Object.defineProperty(exports, "_DataField", ({
|
|
611
|
+
enumerable: true,
|
|
612
|
+
get: function () {
|
|
613
|
+
return _DataField._DataField;
|
|
614
|
+
}
|
|
615
|
+
}));
|
|
616
|
+
Object.defineProperty(exports, "_LineItem", ({
|
|
617
|
+
enumerable: true,
|
|
618
|
+
get: function () {
|
|
619
|
+
return _LineItem._LineItem;
|
|
620
|
+
}
|
|
621
|
+
}));
|
|
622
|
+
var _DefinitionPage = __webpack_require__(274);
|
|
623
|
+
var _DataField = __webpack_require__(596);
|
|
624
|
+
var _LineItem = __webpack_require__(384);
|
|
625
|
+
var _DefinitionContext = __webpack_require__(747);
|
|
626
|
+
var _TypeGuards = __webpack_require__(331);
|
|
627
|
+
Object.keys(_TypeGuards).forEach(function (key) {
|
|
628
|
+
if (key === "default" || key === "__esModule") return;
|
|
629
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
630
|
+
if (key in exports && exports[key] === _TypeGuards[key]) return;
|
|
631
|
+
Object.defineProperty(exports, key, {
|
|
632
|
+
enumerable: true,
|
|
633
|
+
get: function () {
|
|
634
|
+
return _TypeGuards[key];
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
/***/ }),
|
|
641
|
+
|
|
642
|
+
/***/ 747:
|
|
643
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
648
|
+
value: true
|
|
649
|
+
}));
|
|
650
|
+
exports.DefinitionContext = void 0;
|
|
651
|
+
var _MetaPath = _interopRequireDefault(__webpack_require__(333));
|
|
652
|
+
var _DefinitionPage = __webpack_require__(274);
|
|
653
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
654
|
+
class DefinitionContext {
|
|
655
|
+
constructor(convertedMetadata) {
|
|
656
|
+
this.convertedMetadata = convertedMetadata;
|
|
657
|
+
}
|
|
658
|
+
addApplicationManifest(manifest) {
|
|
659
|
+
this.manifest = manifest;
|
|
660
|
+
}
|
|
661
|
+
getEntitySets() {
|
|
662
|
+
return this.convertedMetadata.entitySets;
|
|
663
|
+
}
|
|
664
|
+
getEntitySet(entitySetName) {
|
|
665
|
+
return this.convertedMetadata.entitySets.by_name(entitySetName);
|
|
666
|
+
}
|
|
667
|
+
getRootEntitySet() {
|
|
668
|
+
if (this.manifest) {
|
|
669
|
+
// Use the ui5 routing config to identify the root entityset
|
|
670
|
+
const initialRoutePattern = ":?query:";
|
|
671
|
+
const initialRoute = (this.manifest["sap.ui5"]?.routing?.routes).find(r => r.pattern === initialRoutePattern);
|
|
672
|
+
if (initialRoute?.target && this.manifest["sap.ui5"]?.routing?.targets) {
|
|
673
|
+
const target = this.manifest["sap.ui5"].routing.targets[initialRoute.target];
|
|
674
|
+
if (target?.name) {
|
|
675
|
+
const options = target.options;
|
|
676
|
+
const settings = options?.settings;
|
|
677
|
+
const entitySet = this.convertedMetadata.resolvePath(settings?.contextPath ?? `${settings?.entitySet}`);
|
|
678
|
+
return entitySet.target;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
// Try to determine the root entity set from the metadata
|
|
683
|
+
}
|
|
684
|
+
getMetaPath(metaPath, contextPath) {
|
|
685
|
+
return new _MetaPath.default(this.convertedMetadata, metaPath, contextPath);
|
|
686
|
+
}
|
|
687
|
+
getPageFor(contextPath) {
|
|
688
|
+
// A page could point to
|
|
689
|
+
// - An entitySet (/SalesOrder)
|
|
690
|
+
// - A singleton (/Me)
|
|
691
|
+
// - A navigation property (/SalesOrder/Set)
|
|
692
|
+
return new _DefinitionPage.DefinitionPage(new _MetaPath.default(this.convertedMetadata, contextPath, contextPath));
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
exports.DefinitionContext = DefinitionContext;
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
/***/ }),
|
|
699
|
+
|
|
700
|
+
/***/ 827:
|
|
701
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
706
|
+
value: true
|
|
707
|
+
}));
|
|
708
|
+
exports["default"] = void 0;
|
|
709
|
+
var _BaseDefinition = __webpack_require__(462);
|
|
710
|
+
class _EntitySet extends _BaseDefinition.BaseDefinition {
|
|
711
|
+
constructor(entitySet, entitySetConfiguration = {}) {
|
|
712
|
+
super(entitySet, entitySetConfiguration);
|
|
713
|
+
this.entitySet = entitySet;
|
|
714
|
+
this.entitySetConfiguration = entitySetConfiguration;
|
|
715
|
+
}
|
|
716
|
+
//
|
|
717
|
+
// @annotation({
|
|
718
|
+
// term: CapabilitiesAnnotationTerms.FilterRestrictions,
|
|
719
|
+
// processor: (filterRestrictions?: FilterRestrictions): Property[] => {
|
|
720
|
+
// const requiredProperties =
|
|
721
|
+
// filterRestrictions?.RequiredProperties ?? [];
|
|
722
|
+
// return requiredProperties
|
|
723
|
+
// .map((propertyPath) => {
|
|
724
|
+
// return propertyPath.$target;
|
|
725
|
+
// })
|
|
726
|
+
// .filter((property): property is Property => {
|
|
727
|
+
// return !!property;
|
|
728
|
+
// });
|
|
729
|
+
// }
|
|
730
|
+
// })
|
|
731
|
+
// requiredProperties: Property[];
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Retrieves the required properties for the entity set.
|
|
735
|
+
*/
|
|
736
|
+
getRequiredProperties() {
|
|
737
|
+
const requiredProperties = this.entitySet.getTarget().annotations.Capabilities?.FilterRestrictions?.RequiredProperties ?? [];
|
|
738
|
+
return requiredProperties.map(propertyPath => {
|
|
739
|
+
return propertyPath.$target;
|
|
740
|
+
}).filter(property => {
|
|
741
|
+
return !!property;
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* Retrieves the required properties for the entity set.
|
|
747
|
+
*/
|
|
748
|
+
getNonFilterableProperties() {
|
|
749
|
+
const nonFilterableProperties = this.entitySet.getTarget().annotations.Capabilities?.FilterRestrictions?.NonFilterableProperties ?? [];
|
|
750
|
+
return nonFilterableProperties.map(propertyPath => {
|
|
751
|
+
return propertyPath.$target;
|
|
752
|
+
}).filter(property => {
|
|
753
|
+
return !!property;
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Retrieves the required properties for the entity set.
|
|
759
|
+
* @param property
|
|
760
|
+
*/
|
|
761
|
+
getAllowedFilterExpression(property) {
|
|
762
|
+
const filterExpressionRestrictions = this.entitySet.getTarget().annotations.Capabilities?.FilterRestrictions?.FilterExpressionRestrictions ?? [];
|
|
763
|
+
const propertyRestrictions = filterExpressionRestrictions.filter(filterExpressionRestriction => filterExpressionRestriction.Property?.$target === property);
|
|
764
|
+
return propertyRestrictions.map(propertyRestriction => {
|
|
765
|
+
return propertyRestriction.AllowedExpressions;
|
|
766
|
+
}).filter(propertyRestriction => {
|
|
767
|
+
return !!propertyRestriction;
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
isSearchAllowed() {
|
|
771
|
+
return !!this.entitySet.getTarget().annotations.Capabilities?.SearchRestrictions?.Searchable;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
exports["default"] = _EntitySet;
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
/***/ }),
|
|
778
|
+
|
|
779
|
+
/***/ 596:
|
|
780
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
785
|
+
value: true
|
|
786
|
+
}));
|
|
787
|
+
exports._DataField = void 0;
|
|
788
|
+
var _Expression = __webpack_require__(238);
|
|
789
|
+
var _TypeGuards = __webpack_require__(331);
|
|
790
|
+
class _DataField {
|
|
791
|
+
constructor(dataField, pageMetaPath) {
|
|
792
|
+
this.dataField = dataField;
|
|
793
|
+
this.pageMetaPath = pageMetaPath;
|
|
794
|
+
}
|
|
795
|
+
getValue() {
|
|
796
|
+
return (0, _Expression.getExpressionFromAnnotation)(this.dataField.Value);
|
|
797
|
+
}
|
|
798
|
+
getFormattedValue() {
|
|
799
|
+
// Compute display mode and then return the formatted value
|
|
800
|
+
// Also consider units and currency
|
|
801
|
+
const targetValue = (0, _Expression.getExpressionFromAnnotation)(this.dataField.Value);
|
|
802
|
+
return (0, _Expression.transformRecursively)(targetValue, "PathInModel", value => {
|
|
803
|
+
const propertyMetaPath = this.pageMetaPath.getMetaPathForPath(value.path);
|
|
804
|
+
if (!propertyMetaPath) {
|
|
805
|
+
return _Expression.unresolvableExpression;
|
|
806
|
+
}
|
|
807
|
+
const measure = this.getMeasure(propertyMetaPath);
|
|
808
|
+
if (measure) {
|
|
809
|
+
return (0, _Expression.concat)(value, " ", measure);
|
|
810
|
+
}
|
|
811
|
+
const displayMode = this.getDisplayMode(propertyMetaPath);
|
|
812
|
+
if (displayMode !== "Value") {
|
|
813
|
+
const text = (0, _Expression.getExpressionFromAnnotation)(propertyMetaPath.getTarget().annotations.Common?.Text);
|
|
814
|
+
if (displayMode === "Description") {
|
|
815
|
+
return text;
|
|
816
|
+
} else if (displayMode === "DescriptionValue") {
|
|
817
|
+
return (0, _Expression.concat)(text, " (", value, ")");
|
|
818
|
+
} else if (displayMode === "ValueDescription") {
|
|
819
|
+
return (0, _Expression.concat)(value, (0, _Expression.ifElse)((0, _Expression.notEqual)(text, undefined), (0, _Expression.concat)(" (", text, ")"), ""));
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
return value;
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Checks if the given property has a Unit or ISOCurrency annotation and returns it.
|
|
828
|
+
*
|
|
829
|
+
* @param property property to get the measure for
|
|
830
|
+
* @returns the measure annotation or undefined
|
|
831
|
+
*/
|
|
832
|
+
getMeasure(property) {
|
|
833
|
+
const measures = property.getTarget().annotations.Measures;
|
|
834
|
+
if (measures) {
|
|
835
|
+
const measure = measures.Unit ?? measures.ISOCurrency;
|
|
836
|
+
if (measure) {
|
|
837
|
+
return (0, _Expression.getExpressionFromAnnotation)(measure);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
return undefined;
|
|
841
|
+
}
|
|
842
|
+
getDisplayMode(property) {
|
|
843
|
+
const currentEntityType = property.getClosestEntityType();
|
|
844
|
+
const textAnnotation = property.getTarget().annotations.Common?.Text;
|
|
845
|
+
const textArrangement = textAnnotation?.annotations?.UI?.TextArrangement ?? currentEntityType.annotations.UI?.TextArrangement;
|
|
846
|
+
let displayMode = textAnnotation ? "DescriptionValue" : "Value";
|
|
847
|
+
if (textAnnotation && textArrangement != null) {
|
|
848
|
+
if (textArrangement === "UI.TextArrangementType/TextOnly") {
|
|
849
|
+
displayMode = "Description";
|
|
850
|
+
} else if (textArrangement === "UI.TextArrangementType/TextLast") {
|
|
851
|
+
displayMode = "ValueDescription";
|
|
852
|
+
} else if (textArrangement === "UI.TextArrangementType/TextSeparate") {
|
|
853
|
+
displayMode = "Value";
|
|
854
|
+
} else {
|
|
855
|
+
//Default should be TextFirst if there is a Text annotation and neither TextOnly nor TextLast are set
|
|
856
|
+
displayMode = "DescriptionValue";
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return displayMode;
|
|
860
|
+
}
|
|
861
|
+
getLabel() {
|
|
862
|
+
let label = this.dataField.Label?.toString() ?? this.dataField.annotations?.Common?.Label?.toString();
|
|
863
|
+
if (!label) {
|
|
864
|
+
const valueTarget = this.dataField.Value;
|
|
865
|
+
if ((0, _TypeGuards.isPathAnnotationExpression)(valueTarget)) {
|
|
866
|
+
label = valueTarget.$target?.annotations.Common?.Label?.toString() ?? valueTarget.$target?.name ?? valueTarget.path;
|
|
867
|
+
} else {
|
|
868
|
+
label = this.dataField.fullyQualifiedName;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
return label;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* Retrieve a property from the data field IF it can be easily determined (no complex exression)
|
|
876
|
+
*/
|
|
877
|
+
getProperty() {
|
|
878
|
+
const valueTarget = this.dataField.Value;
|
|
879
|
+
if ((0, _TypeGuards.isPathAnnotationExpression)(valueTarget)) {
|
|
880
|
+
return valueTarget.$target;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
getFullyQualifiedName() {
|
|
884
|
+
return this.dataField.fullyQualifiedName;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
exports._DataField = _DataField;
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
/***/ }),
|
|
891
|
+
|
|
892
|
+
/***/ 877:
|
|
893
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
898
|
+
value: true
|
|
899
|
+
}));
|
|
900
|
+
exports._Identification = void 0;
|
|
901
|
+
var _DataField2 = __webpack_require__(596);
|
|
902
|
+
class _Identification {
|
|
903
|
+
constructor(id, pageMetaPath) {
|
|
904
|
+
this.id = id;
|
|
905
|
+
this.pageMetaPath = pageMetaPath;
|
|
906
|
+
}
|
|
907
|
+
getDataFields(options) {
|
|
908
|
+
return this.id.filter(item => {
|
|
909
|
+
if (options?.restrictTypes && !options.restrictTypes.includes(item.$Type)) {
|
|
910
|
+
return false;
|
|
911
|
+
}
|
|
912
|
+
switch (item.$Type) {
|
|
913
|
+
case "com.sap.vocabularies.UI.v1.DataField":
|
|
914
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithUrl":
|
|
915
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithAction":
|
|
916
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithActionGroup":
|
|
917
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithIntentBasedNavigation":
|
|
918
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithNavigationPath":
|
|
919
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForAnnotation":
|
|
920
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForAction":
|
|
921
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation":
|
|
922
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForActionGroup":
|
|
923
|
+
return options?.importance === undefined || options.importance.includes(item.annotations?.UI?.Importance?.toString());
|
|
924
|
+
default:
|
|
925
|
+
return false;
|
|
926
|
+
}
|
|
927
|
+
}).map(item => {
|
|
928
|
+
return new _DataField2._DataField(item, this.pageMetaPath);
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
exports._Identification = _Identification;
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
/***/ }),
|
|
936
|
+
|
|
937
|
+
/***/ 384:
|
|
938
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
943
|
+
value: true
|
|
944
|
+
}));
|
|
945
|
+
exports._LineItem = void 0;
|
|
946
|
+
var _DataField2 = __webpack_require__(596);
|
|
947
|
+
class _LineItem {
|
|
948
|
+
constructor(lineItem, pageMetaPath) {
|
|
949
|
+
this.lineItem = lineItem;
|
|
950
|
+
this.pageMetaPath = pageMetaPath;
|
|
951
|
+
}
|
|
952
|
+
static createDefault(pageMetaPath) {
|
|
953
|
+
const fakeLineItemAnnotation = pageMetaPath.getClosestEntityType().entityProperties.map(prop => {
|
|
954
|
+
if (prop.annotations.UI?.DataFieldDefault) {
|
|
955
|
+
return prop.annotations.UI.DataFieldDefault;
|
|
956
|
+
} else {
|
|
957
|
+
return {
|
|
958
|
+
$Type: "com.sap.vocabularies.UI.v1.DataField",
|
|
959
|
+
Value: {
|
|
960
|
+
type: "Path",
|
|
961
|
+
path: prop.name,
|
|
962
|
+
$target: prop
|
|
963
|
+
}
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
fakeLineItemAnnotation.term = "com.sap.vocabularies.UI.v1.LineItem";
|
|
968
|
+
return new _LineItem(fakeLineItemAnnotation, pageMetaPath);
|
|
969
|
+
}
|
|
970
|
+
static fromSPV(spv, pageMetaPath) {
|
|
971
|
+
switch (spv?.term) {
|
|
972
|
+
case "com.sap.vocabularies.UI.v1.LineItem":
|
|
973
|
+
return new _LineItem(spv, pageMetaPath);
|
|
974
|
+
case "com.sap.vocabularies.UI.v1.PresentationVariant":
|
|
975
|
+
return new _LineItem(spv.Visualizations[0].$target, pageMetaPath);
|
|
976
|
+
case "com.sap.vocabularies.UI.v1.SelectionPresentationVariant":
|
|
977
|
+
return new _LineItem(spv.PresentationVariant.Visualizations[0].$target, pageMetaPath);
|
|
978
|
+
case undefined:
|
|
979
|
+
return undefined;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
getActions() {
|
|
983
|
+
return this.lineItem.filter(item => item.$Type === "com.sap.vocabularies.UI.v1.DataFieldForAction");
|
|
984
|
+
}
|
|
985
|
+
getHeaderActions() {
|
|
986
|
+
return this.getActions().filter(action => action.Determining === true);
|
|
987
|
+
}
|
|
988
|
+
getDataFields(options) {
|
|
989
|
+
return this.lineItem.filter(item => {
|
|
990
|
+
if (options?.restrictTypes && !options.restrictTypes.includes(item.$Type)) {
|
|
991
|
+
return false;
|
|
992
|
+
}
|
|
993
|
+
switch (item.$Type) {
|
|
994
|
+
case "com.sap.vocabularies.UI.v1.DataField":
|
|
995
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithUrl":
|
|
996
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithAction":
|
|
997
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithActionGroup":
|
|
998
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithIntentBasedNavigation":
|
|
999
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithNavigationPath":
|
|
1000
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForAnnotation":
|
|
1001
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForAction":
|
|
1002
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation":
|
|
1003
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForActionGroup":
|
|
1004
|
+
return options?.importance === undefined || options.importance.includes(item.annotations?.UI?.Importance?.toString());
|
|
1005
|
+
default:
|
|
1006
|
+
return false;
|
|
1007
|
+
}
|
|
1008
|
+
}).map(item => {
|
|
1009
|
+
return new _DataField2._DataField(item, this.pageMetaPath);
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
exports._LineItem = _LineItem;
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
/***/ }),
|
|
1017
|
+
|
|
1018
|
+
/***/ 238:
|
|
1019
|
+
/***/ (function(__unused_webpack_module, exports) {
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
1024
|
+
value: true
|
|
1025
|
+
}));
|
|
1026
|
+
exports._checkExpressionsAreEqual = _checkExpressionsAreEqual;
|
|
1027
|
+
exports.and = and;
|
|
1028
|
+
exports.annotationApplyExpression = annotationApplyExpression;
|
|
1029
|
+
exports.annotationIfExpression = annotationIfExpression;
|
|
1030
|
+
exports.concat = concat;
|
|
1031
|
+
exports.constant = constant;
|
|
1032
|
+
exports.equal = equal;
|
|
1033
|
+
exports.fn = fn;
|
|
1034
|
+
exports.formatResult = formatResult;
|
|
1035
|
+
exports.getExpressionFromAnnotation = getExpressionFromAnnotation;
|
|
1036
|
+
exports.getFiscalType = void 0;
|
|
1037
|
+
exports.greaterOrEqual = greaterOrEqual;
|
|
1038
|
+
exports.greaterThan = greaterThan;
|
|
1039
|
+
exports.hasUnresolvableExpression = hasUnresolvableExpression;
|
|
1040
|
+
exports.ifElse = ifElse;
|
|
1041
|
+
exports.isComplexTypeExpression = isComplexTypeExpression;
|
|
1042
|
+
exports.isConstant = isConstant;
|
|
1043
|
+
exports.isEmpty = isEmpty;
|
|
1044
|
+
exports.isExpression = isExpression;
|
|
1045
|
+
exports.isPathInModelExpression = isPathInModelExpression;
|
|
1046
|
+
exports.isTruthy = isTruthy;
|
|
1047
|
+
exports.isUndefinedExpression = isUndefinedExpression;
|
|
1048
|
+
exports.length = length;
|
|
1049
|
+
exports.lessOrEqual = lessOrEqual;
|
|
1050
|
+
exports.lessThan = lessThan;
|
|
1051
|
+
exports.not = not;
|
|
1052
|
+
exports.notEqual = notEqual;
|
|
1053
|
+
exports.objectPath = objectPath;
|
|
1054
|
+
exports.or = or;
|
|
1055
|
+
exports.pathInModel = pathInModel;
|
|
1056
|
+
exports.ref = ref;
|
|
1057
|
+
exports.resolveBindingString = resolveBindingString;
|
|
1058
|
+
exports.transformRecursively = transformRecursively;
|
|
1059
|
+
exports.unresolvableExpression = void 0;
|
|
1060
|
+
exports.wrapPrimitive = wrapPrimitive;
|
|
1061
|
+
/**
|
|
1062
|
+
*/
|
|
1063
|
+
|
|
1064
|
+
/**
|
|
1065
|
+
* An expression that evaluates to type T.
|
|
1066
|
+
*
|
|
1067
|
+
*/
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* An expression that evaluates to type T, or a constant value of type T
|
|
1071
|
+
*/
|
|
1072
|
+
|
|
1073
|
+
const unresolvableExpression = exports.unresolvableExpression = {
|
|
1074
|
+
_type: "Unresolvable"
|
|
1075
|
+
};
|
|
1076
|
+
function hasUnresolvableExpression(...expressions) {
|
|
1077
|
+
return expressions.find(expr => expr._type === "Unresolvable") !== undefined;
|
|
1078
|
+
}
|
|
1079
|
+
/**
|
|
1080
|
+
* Check two expressions for (deep) equality.
|
|
1081
|
+
*
|
|
1082
|
+
* @param a
|
|
1083
|
+
* @param b
|
|
1084
|
+
* @returns `true` if the two expressions are equal
|
|
1085
|
+
*/
|
|
1086
|
+
function _checkExpressionsAreEqual(a, b) {
|
|
1087
|
+
if (!a || !b) {
|
|
1088
|
+
return false;
|
|
1089
|
+
}
|
|
1090
|
+
if (a._type !== b._type) {
|
|
1091
|
+
return false;
|
|
1092
|
+
}
|
|
1093
|
+
switch (a._type) {
|
|
1094
|
+
case "Unresolvable":
|
|
1095
|
+
return false;
|
|
1096
|
+
// Unresolvable is never equal to anything even itself
|
|
1097
|
+
case "Constant":
|
|
1098
|
+
case "EmbeddedBinding":
|
|
1099
|
+
case "EmbeddedExpressionBinding":
|
|
1100
|
+
return a.value === b.value;
|
|
1101
|
+
case "Not":
|
|
1102
|
+
return _checkExpressionsAreEqual(a.operand, b.operand);
|
|
1103
|
+
case "Truthy":
|
|
1104
|
+
return _checkExpressionsAreEqual(a.operand, b.operand);
|
|
1105
|
+
case "Set":
|
|
1106
|
+
return a.operator === b.operator && a.operands.length === b.operands.length && a.operands.every(expression => b.operands.some(otherExpression => _checkExpressionsAreEqual(expression, otherExpression)));
|
|
1107
|
+
case "IfElse":
|
|
1108
|
+
return _checkExpressionsAreEqual(a.condition, b.condition) && _checkExpressionsAreEqual(a.onTrue, b.onTrue) && _checkExpressionsAreEqual(a.onFalse, b.onFalse);
|
|
1109
|
+
case "Comparison":
|
|
1110
|
+
return a.operator === b.operator && _checkExpressionsAreEqual(a.operand1, b.operand1) && _checkExpressionsAreEqual(a.operand2, b.operand2);
|
|
1111
|
+
case "Concat":
|
|
1112
|
+
{
|
|
1113
|
+
const aExpressions = a.expressions;
|
|
1114
|
+
const bExpressions = b.expressions;
|
|
1115
|
+
if (aExpressions.length !== bExpressions.length) {
|
|
1116
|
+
return false;
|
|
1117
|
+
}
|
|
1118
|
+
return aExpressions.every((expression, index) => {
|
|
1119
|
+
return _checkExpressionsAreEqual(expression, bExpressions[index]);
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
case "Length":
|
|
1123
|
+
return _checkExpressionsAreEqual(a.pathInModel, b.pathInModel);
|
|
1124
|
+
case "PathInModel":
|
|
1125
|
+
return a.modelName === b.modelName && a.path === b.path && a.targetEntitySet === b.targetEntitySet;
|
|
1126
|
+
case "Formatter":
|
|
1127
|
+
return a.fn === b.fn && a.parameters.length === b.parameters.length && a.parameters.every((value, index) => _checkExpressionsAreEqual(b.parameters[index], value));
|
|
1128
|
+
case "ComplexType":
|
|
1129
|
+
return a.type === b.type && a.bindingParameters.length === b.bindingParameters.length && a.bindingParameters.every((value, index) => _checkExpressionsAreEqual(b.bindingParameters[index], value));
|
|
1130
|
+
case "Function":
|
|
1131
|
+
const otherFunction = b;
|
|
1132
|
+
if (a.obj === undefined || otherFunction.obj === undefined) {
|
|
1133
|
+
return a.obj === otherFunction;
|
|
1134
|
+
}
|
|
1135
|
+
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));
|
|
1136
|
+
case "Ref":
|
|
1137
|
+
return a.ref === b.ref;
|
|
1138
|
+
}
|
|
1139
|
+
return false;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
/**
|
|
1143
|
+
* Converts a nested SetExpression by inlining operands of type SetExpression with the same operator.
|
|
1144
|
+
*
|
|
1145
|
+
* @param expression The expression to flatten
|
|
1146
|
+
* @returns A new SetExpression with the same operator
|
|
1147
|
+
*/
|
|
1148
|
+
function flattenSetExpression(expression) {
|
|
1149
|
+
return expression.operands.reduce((result, operand) => {
|
|
1150
|
+
const candidatesForFlattening = operand._type === "Set" && operand.operator === expression.operator ? operand.operands : [operand];
|
|
1151
|
+
candidatesForFlattening.forEach(candidate => {
|
|
1152
|
+
if (result.operands.every(e => !_checkExpressionsAreEqual(e, candidate))) {
|
|
1153
|
+
result.operands.push(candidate);
|
|
1154
|
+
}
|
|
1155
|
+
});
|
|
1156
|
+
return result;
|
|
1157
|
+
}, {
|
|
1158
|
+
_type: "Set",
|
|
1159
|
+
operator: expression.operator,
|
|
1160
|
+
operands: []
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
/**
|
|
1165
|
+
* Detects whether an array of boolean expressions contains an expression and its negation.
|
|
1166
|
+
*
|
|
1167
|
+
* @param expressions Array of expressions
|
|
1168
|
+
* @returns `true` if the set of expressions contains an expression and its negation
|
|
1169
|
+
*/
|
|
1170
|
+
function hasOppositeExpressions(expressions) {
|
|
1171
|
+
const negatedExpressions = expressions.map(not);
|
|
1172
|
+
return expressions.some((expression, index) => {
|
|
1173
|
+
for (let i = index + 1; i < negatedExpressions.length; i++) {
|
|
1174
|
+
if (_checkExpressionsAreEqual(expression, negatedExpressions[i])) {
|
|
1175
|
+
return true;
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
return false;
|
|
1179
|
+
});
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* Logical `and` expression.
|
|
1184
|
+
*
|
|
1185
|
+
* The expression is simplified to false if this can be decided statically (that is, if one operand is a constant
|
|
1186
|
+
* false or if the expression contains an operand and its negation).
|
|
1187
|
+
*
|
|
1188
|
+
* @param operands Expressions to connect by `and`
|
|
1189
|
+
* @returns Expression evaluating to boolean
|
|
1190
|
+
*/
|
|
1191
|
+
function and(...operands) {
|
|
1192
|
+
const expressions = flattenSetExpression({
|
|
1193
|
+
_type: "Set",
|
|
1194
|
+
operator: "&&",
|
|
1195
|
+
operands: operands.map(wrapPrimitive)
|
|
1196
|
+
}).operands;
|
|
1197
|
+
if (hasUnresolvableExpression(...expressions)) {
|
|
1198
|
+
return unresolvableExpression;
|
|
1199
|
+
}
|
|
1200
|
+
let isStaticFalse = false;
|
|
1201
|
+
const nonTrivialExpression = expressions.filter(expression => {
|
|
1202
|
+
if (isFalse(expression)) {
|
|
1203
|
+
isStaticFalse = true;
|
|
1204
|
+
}
|
|
1205
|
+
return !isConstant(expression);
|
|
1206
|
+
});
|
|
1207
|
+
if (isStaticFalse) {
|
|
1208
|
+
return constant(false);
|
|
1209
|
+
} else if (nonTrivialExpression.length === 0) {
|
|
1210
|
+
// Resolve the constant then
|
|
1211
|
+
const isValid = expressions.reduce((result, expression) => result && isTrue(expression), true);
|
|
1212
|
+
return constant(isValid);
|
|
1213
|
+
} else if (nonTrivialExpression.length === 1) {
|
|
1214
|
+
return nonTrivialExpression[0];
|
|
1215
|
+
} else if (hasOppositeExpressions(nonTrivialExpression)) {
|
|
1216
|
+
return constant(false);
|
|
1217
|
+
} else {
|
|
1218
|
+
return {
|
|
1219
|
+
_type: "Set",
|
|
1220
|
+
operator: "&&",
|
|
1221
|
+
operands: nonTrivialExpression
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
// let tracer: any;
|
|
1227
|
+
// export function traceExpression(inTracer: never): void {
|
|
1228
|
+
// tracer = inTracer;
|
|
1229
|
+
// }
|
|
1230
|
+
//
|
|
1231
|
+
// export function pickFirstNonNull(
|
|
1232
|
+
// ...operands: ExpressionOrPrimitive<PrimitiveType>[]
|
|
1233
|
+
// ): ExpressionOrPrimitive<PrimitiveType> {
|
|
1234
|
+
// const result = operands.find((operand) => operand !== undefined);
|
|
1235
|
+
// if (tracer) {
|
|
1236
|
+
// tracer.logConditional("pickFirstNonNull", operands, result);
|
|
1237
|
+
// }
|
|
1238
|
+
// return result;
|
|
1239
|
+
// }
|
|
1240
|
+
/**
|
|
1241
|
+
* Logical `or` expression.
|
|
1242
|
+
*
|
|
1243
|
+
* The expression is simplified to true if this can be decided statically (that is, if one operand is a constant
|
|
1244
|
+
* true or if the expression contains an operand and its negation).
|
|
1245
|
+
*
|
|
1246
|
+
* @param operands Expressions to connect by `or`
|
|
1247
|
+
* @returns Expression evaluating to boolean
|
|
1248
|
+
*/
|
|
1249
|
+
function or(...operands) {
|
|
1250
|
+
const expressions = flattenSetExpression({
|
|
1251
|
+
_type: "Set",
|
|
1252
|
+
operator: "||",
|
|
1253
|
+
operands: operands.map(wrapPrimitive)
|
|
1254
|
+
}).operands;
|
|
1255
|
+
if (hasUnresolvableExpression(...expressions)) {
|
|
1256
|
+
return unresolvableExpression;
|
|
1257
|
+
}
|
|
1258
|
+
let isStaticTrue = false;
|
|
1259
|
+
const nonTrivialExpression = expressions.filter(expression => {
|
|
1260
|
+
if (isTrue(expression)) {
|
|
1261
|
+
isStaticTrue = true;
|
|
1262
|
+
}
|
|
1263
|
+
return !isConstant(expression) || expression.value;
|
|
1264
|
+
});
|
|
1265
|
+
if (isStaticTrue) {
|
|
1266
|
+
return constant(true);
|
|
1267
|
+
} else if (nonTrivialExpression.length === 0) {
|
|
1268
|
+
// Resolve the constant then
|
|
1269
|
+
const isValid = expressions.reduce((result, expression) => result && isTrue(expression), true);
|
|
1270
|
+
return constant(isValid);
|
|
1271
|
+
} else if (nonTrivialExpression.length === 1) {
|
|
1272
|
+
return nonTrivialExpression[0];
|
|
1273
|
+
} else if (hasOppositeExpressions(nonTrivialExpression)) {
|
|
1274
|
+
return constant(true);
|
|
1275
|
+
} else {
|
|
1276
|
+
return {
|
|
1277
|
+
_type: "Set",
|
|
1278
|
+
operator: "||",
|
|
1279
|
+
operands: nonTrivialExpression
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
/**
|
|
1285
|
+
* Logical `not` operator.
|
|
1286
|
+
*
|
|
1287
|
+
* @param operand The expression to reverse
|
|
1288
|
+
* @returns The resulting expression that evaluates to boolean
|
|
1289
|
+
*/
|
|
1290
|
+
function not(operand) {
|
|
1291
|
+
operand = wrapPrimitive(operand);
|
|
1292
|
+
if (hasUnresolvableExpression(operand)) {
|
|
1293
|
+
return unresolvableExpression;
|
|
1294
|
+
} else if (isConstant(operand)) {
|
|
1295
|
+
return constant(!operand.value);
|
|
1296
|
+
} else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "||" && operand.operands.every(expression => isConstant(expression) || isComparison(expression))) {
|
|
1297
|
+
return and(...operand.operands.map(expression => not(expression)));
|
|
1298
|
+
} else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "&&" && operand.operands.every(expression => isConstant(expression) || isComparison(expression))) {
|
|
1299
|
+
return or(...operand.operands.map(expression => not(expression)));
|
|
1300
|
+
} else if (isComparison(operand)) {
|
|
1301
|
+
// Create the reverse comparison
|
|
1302
|
+
switch (operand.operator) {
|
|
1303
|
+
case "!==":
|
|
1304
|
+
return {
|
|
1305
|
+
...operand,
|
|
1306
|
+
operator: "==="
|
|
1307
|
+
};
|
|
1308
|
+
case "<":
|
|
1309
|
+
return {
|
|
1310
|
+
...operand,
|
|
1311
|
+
operator: ">="
|
|
1312
|
+
};
|
|
1313
|
+
case "<=":
|
|
1314
|
+
return {
|
|
1315
|
+
...operand,
|
|
1316
|
+
operator: ">"
|
|
1317
|
+
};
|
|
1318
|
+
case "===":
|
|
1319
|
+
return {
|
|
1320
|
+
...operand,
|
|
1321
|
+
operator: "!=="
|
|
1322
|
+
};
|
|
1323
|
+
case ">":
|
|
1324
|
+
return {
|
|
1325
|
+
...operand,
|
|
1326
|
+
operator: "<="
|
|
1327
|
+
};
|
|
1328
|
+
case ">=":
|
|
1329
|
+
return {
|
|
1330
|
+
...operand,
|
|
1331
|
+
operator: "<"
|
|
1332
|
+
};
|
|
1333
|
+
}
|
|
1334
|
+
} else if (operand._type === "Not") {
|
|
1335
|
+
return operand.operand;
|
|
1336
|
+
}
|
|
1337
|
+
return {
|
|
1338
|
+
_type: "Not",
|
|
1339
|
+
operand: operand
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
/**
|
|
1344
|
+
* Evaluates whether a binding expression is equal to true with a loose equality.
|
|
1345
|
+
*
|
|
1346
|
+
* @param operand The expression to check
|
|
1347
|
+
* @returns The resulting expression that evaluates to boolean
|
|
1348
|
+
*/
|
|
1349
|
+
function isTruthy(operand) {
|
|
1350
|
+
if (isConstant(operand)) {
|
|
1351
|
+
return constant(!!operand.value);
|
|
1352
|
+
} else {
|
|
1353
|
+
return {
|
|
1354
|
+
_type: "Truthy",
|
|
1355
|
+
operand: operand
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
/**
|
|
1361
|
+
* Creates a binding expression that will be evaluated by the corresponding model.
|
|
1362
|
+
*
|
|
1363
|
+
* @param path
|
|
1364
|
+
* @param modelName
|
|
1365
|
+
* @param visitedNavigationPaths
|
|
1366
|
+
* @param pathVisitor
|
|
1367
|
+
* @returns An expression representating that path in the model
|
|
1368
|
+
*/
|
|
1369
|
+
function objectPath(path, modelName, visitedNavigationPaths = [], pathVisitor) {
|
|
1370
|
+
return pathInModel(path, modelName, visitedNavigationPaths, pathVisitor);
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
/**
|
|
1374
|
+
* Creates a binding expression that will be evaluated by the corresponding model.
|
|
1375
|
+
*
|
|
1376
|
+
* @template TargetType
|
|
1377
|
+
* @param path The path on the model
|
|
1378
|
+
* @param [modelName] The name of the model
|
|
1379
|
+
* @param [visitedNavigationPaths] The paths from the root entitySet
|
|
1380
|
+
* @param [pathVisitor] A function to modify the resulting path
|
|
1381
|
+
* @returns An expression representating that path in the model
|
|
1382
|
+
*/
|
|
1383
|
+
|
|
1384
|
+
function pathInModel(path, modelName, visitedNavigationPaths = [], pathVisitor) {
|
|
1385
|
+
if (path === undefined) {
|
|
1386
|
+
return unresolvableExpression;
|
|
1387
|
+
}
|
|
1388
|
+
let targetPath;
|
|
1389
|
+
if (pathVisitor) {
|
|
1390
|
+
targetPath = pathVisitor(path);
|
|
1391
|
+
if (targetPath === undefined) {
|
|
1392
|
+
return unresolvableExpression;
|
|
1393
|
+
}
|
|
1394
|
+
} else {
|
|
1395
|
+
const localPath = visitedNavigationPaths.concat();
|
|
1396
|
+
localPath.push(path);
|
|
1397
|
+
targetPath = localPath.join("/");
|
|
1398
|
+
}
|
|
1399
|
+
return {
|
|
1400
|
+
_type: "PathInModel",
|
|
1401
|
+
modelName: modelName,
|
|
1402
|
+
path: targetPath
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Creates a constant expression based on a primitive value.
|
|
1407
|
+
*
|
|
1408
|
+
* @template T
|
|
1409
|
+
* @param value The constant to wrap in an expression
|
|
1410
|
+
* @returns The constant expression
|
|
1411
|
+
*/
|
|
1412
|
+
function constant(value) {
|
|
1413
|
+
let constantValue;
|
|
1414
|
+
if (typeof value === "object" && value !== null && value !== undefined) {
|
|
1415
|
+
if (Array.isArray(value)) {
|
|
1416
|
+
constantValue = value.map(wrapPrimitive);
|
|
1417
|
+
} else if (isPrimitiveObject(value)) {
|
|
1418
|
+
constantValue = value.valueOf();
|
|
1419
|
+
} else {
|
|
1420
|
+
constantValue = Object.entries(value).reduce((plainExpression, [key, val]) => {
|
|
1421
|
+
const wrappedValue = wrapPrimitive(val);
|
|
1422
|
+
if (wrappedValue._type !== "Constant" || wrappedValue.value !== undefined) {
|
|
1423
|
+
plainExpression[key] = wrappedValue;
|
|
1424
|
+
}
|
|
1425
|
+
return plainExpression;
|
|
1426
|
+
}, {});
|
|
1427
|
+
}
|
|
1428
|
+
} else {
|
|
1429
|
+
constantValue = value;
|
|
1430
|
+
}
|
|
1431
|
+
return {
|
|
1432
|
+
_type: "Constant",
|
|
1433
|
+
value: constantValue
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
function resolveBindingString(value, targetType) {
|
|
1437
|
+
if (value !== undefined && typeof value === "string" && value.startsWith("{")) {
|
|
1438
|
+
const pathInModelRegex = /^{(.*)>(.+)}$/; // Matches model paths like "model>path" or ">path" (default model)
|
|
1439
|
+
const pathInModelRegexMatch = pathInModelRegex.exec(value);
|
|
1440
|
+
if (value.startsWith("{=")) {
|
|
1441
|
+
// Expression binding, we can just remove the outer binding things
|
|
1442
|
+
return {
|
|
1443
|
+
_type: "EmbeddedExpressionBinding",
|
|
1444
|
+
value: value
|
|
1445
|
+
};
|
|
1446
|
+
} else if (pathInModelRegexMatch) {
|
|
1447
|
+
return pathInModel(pathInModelRegexMatch[2] || "", pathInModelRegexMatch[1] || undefined);
|
|
1448
|
+
} else {
|
|
1449
|
+
return {
|
|
1450
|
+
_type: "EmbeddedBinding",
|
|
1451
|
+
value: value
|
|
1452
|
+
};
|
|
1453
|
+
}
|
|
1454
|
+
} else if (targetType === "boolean" && typeof value === "string" && (value === "true" || value === "false")) {
|
|
1455
|
+
return constant(value === "true");
|
|
1456
|
+
} else if (targetType === "number" && typeof value === "string" && (!isNaN(Number(value)) || value === "NaN")) {
|
|
1457
|
+
return constant(Number(value));
|
|
1458
|
+
} else {
|
|
1459
|
+
return constant(value);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
/**
|
|
1464
|
+
* A named reference.
|
|
1465
|
+
*
|
|
1466
|
+
* @see fn
|
|
1467
|
+
* @param reference Reference
|
|
1468
|
+
* @returns The object reference binding part
|
|
1469
|
+
*/
|
|
1470
|
+
function ref(reference) {
|
|
1471
|
+
return {
|
|
1472
|
+
_type: "Ref",
|
|
1473
|
+
ref: reference
|
|
1474
|
+
};
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
/**
|
|
1478
|
+
* Wrap a primitive into a constant expression if it is not already an expression.
|
|
1479
|
+
*
|
|
1480
|
+
* @template T
|
|
1481
|
+
* @param something The object to wrap in a Constant expression
|
|
1482
|
+
* @returns Either the original object or the wrapped one depending on the case
|
|
1483
|
+
*/
|
|
1484
|
+
function wrapPrimitive(something) {
|
|
1485
|
+
if (isExpression(something)) {
|
|
1486
|
+
return something;
|
|
1487
|
+
}
|
|
1488
|
+
return constant(something);
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
/**
|
|
1492
|
+
* Checks if the expression or value provided is a binding tooling expression or not.
|
|
1493
|
+
*
|
|
1494
|
+
* Every object having a property named `_type` of some value is considered an expression, even if there is actually
|
|
1495
|
+
* no such expression type supported.
|
|
1496
|
+
*
|
|
1497
|
+
* @param expression
|
|
1498
|
+
* @returns `true` if the expression is a binding toolkit expression
|
|
1499
|
+
*/
|
|
1500
|
+
function isExpression(expression) {
|
|
1501
|
+
return expression?._type !== undefined;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
/**
|
|
1505
|
+
* Checks if the expression or value provided is constant or not.
|
|
1506
|
+
*
|
|
1507
|
+
* @template T The target type
|
|
1508
|
+
* @param maybeConstant The expression or primitive value that is to be checked
|
|
1509
|
+
* @returns `true` if it is constant
|
|
1510
|
+
*/
|
|
1511
|
+
function isConstant(maybeConstant) {
|
|
1512
|
+
return typeof maybeConstant !== "object" || maybeConstant._type === "Constant";
|
|
1513
|
+
}
|
|
1514
|
+
function isTrue(expression) {
|
|
1515
|
+
return isConstant(expression) && expression.value === true;
|
|
1516
|
+
}
|
|
1517
|
+
function isFalse(expression) {
|
|
1518
|
+
return isConstant(expression) && expression.value === false;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
/**
|
|
1522
|
+
* Checks if the expression or value provided is a path in model expression or not.
|
|
1523
|
+
*
|
|
1524
|
+
* @template T The target type
|
|
1525
|
+
* @param maybeBinding The expression or primitive value that is to be checked
|
|
1526
|
+
* @returns `true` if it is a path in model expression
|
|
1527
|
+
*/
|
|
1528
|
+
function isPathInModelExpression(maybeBinding) {
|
|
1529
|
+
return maybeBinding._type === "PathInModel";
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
/**
|
|
1533
|
+
* Checks if the expression or value provided is a complex type expression.
|
|
1534
|
+
*
|
|
1535
|
+
* @template T The target type
|
|
1536
|
+
* @param maybeBinding The expression or primitive value that is to be checked
|
|
1537
|
+
* @returns `true` if it is a path in model expression
|
|
1538
|
+
*/
|
|
1539
|
+
function isComplexTypeExpression(maybeBinding) {
|
|
1540
|
+
return maybeBinding._type === "ComplexType";
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
/**
|
|
1544
|
+
* Checks if the expression or value provided is a concat expression or not.
|
|
1545
|
+
*
|
|
1546
|
+
* @param expression
|
|
1547
|
+
* @returns `true` if the expression is a ConcatExpression
|
|
1548
|
+
*/
|
|
1549
|
+
function isConcatExpression(expression) {
|
|
1550
|
+
return expression._type === "Concat";
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
/**
|
|
1554
|
+
* Checks if the expression or value provided is a IfElse expression or not.
|
|
1555
|
+
*
|
|
1556
|
+
* @param expression
|
|
1557
|
+
* @returns `true` if the expression is a IfElseExpression
|
|
1558
|
+
*/
|
|
1559
|
+
function isIfElseExpression(expression) {
|
|
1560
|
+
return expression._type === "IfElse";
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
/**
|
|
1564
|
+
* Checks if the expression provided is a comparison or not.
|
|
1565
|
+
*
|
|
1566
|
+
* @template T The target type
|
|
1567
|
+
* @param expression The expression
|
|
1568
|
+
* @returns `true` if the expression is a ComparisonExpression
|
|
1569
|
+
*/
|
|
1570
|
+
function isComparison(expression) {
|
|
1571
|
+
return expression._type === "Comparison";
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
/**
|
|
1575
|
+
* Checks whether the input parameter is a constant expression of type undefined.
|
|
1576
|
+
*
|
|
1577
|
+
* @param expression The input expression or object in general
|
|
1578
|
+
* @returns `true` if the input is constant which has undefined for value
|
|
1579
|
+
*/
|
|
1580
|
+
function isUndefinedExpression(expression) {
|
|
1581
|
+
const expressionAsExpression = expression;
|
|
1582
|
+
return expressionAsExpression._type === "Constant" && expressionAsExpression.value === undefined;
|
|
1583
|
+
}
|
|
1584
|
+
function isPrimitiveObject(objectType) {
|
|
1585
|
+
switch (objectType.constructor.name) {
|
|
1586
|
+
case "String":
|
|
1587
|
+
case "Number":
|
|
1588
|
+
case "Boolean":
|
|
1589
|
+
return true;
|
|
1590
|
+
default:
|
|
1591
|
+
return false;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
/**
|
|
1595
|
+
* Check if the passed annotation annotationValue is a ComplexAnnotationExpression.
|
|
1596
|
+
*
|
|
1597
|
+
* @template T The target type
|
|
1598
|
+
* @param annotationValue The annotation annotationValue to evaluate
|
|
1599
|
+
* @returns `true` if the object is a {ComplexAnnotationExpression}
|
|
1600
|
+
*/
|
|
1601
|
+
function isComplexAnnotationExpression(annotationValue) {
|
|
1602
|
+
return typeof annotationValue === "object" && !isPrimitiveObject(annotationValue);
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
/**
|
|
1606
|
+
* Generate the corresponding annotationValue for a given annotation annotationValue.
|
|
1607
|
+
*
|
|
1608
|
+
* @template T The target type
|
|
1609
|
+
* @param annotationValue The source annotation annotationValue
|
|
1610
|
+
* @param visitedNavigationPaths The path from the root entity set
|
|
1611
|
+
* @param defaultValue Default value if the annotationValue is undefined
|
|
1612
|
+
* @param pathVisitor A function to modify the resulting path
|
|
1613
|
+
* @returns The annotationValue equivalent to that annotation annotationValue
|
|
1614
|
+
*/
|
|
1615
|
+
function getExpressionFromAnnotation(annotationValue, visitedNavigationPaths = [], defaultValue, pathVisitor) {
|
|
1616
|
+
if (annotationValue === undefined) {
|
|
1617
|
+
return wrapPrimitive(defaultValue);
|
|
1618
|
+
}
|
|
1619
|
+
annotationValue = annotationValue.valueOf();
|
|
1620
|
+
if (!isComplexAnnotationExpression(annotationValue)) {
|
|
1621
|
+
return constant(annotationValue);
|
|
1622
|
+
}
|
|
1623
|
+
switch (annotationValue.type) {
|
|
1624
|
+
case "Path":
|
|
1625
|
+
return pathInModel(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
|
|
1626
|
+
case "If":
|
|
1627
|
+
return annotationIfExpression(annotationValue.$If, visitedNavigationPaths, pathVisitor);
|
|
1628
|
+
case "Not":
|
|
1629
|
+
return not(parseAnnotationCondition(annotationValue.$Not, visitedNavigationPaths, pathVisitor));
|
|
1630
|
+
case "Eq":
|
|
1631
|
+
return equal(parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor));
|
|
1632
|
+
case "Ne":
|
|
1633
|
+
return notEqual(parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor));
|
|
1634
|
+
case "Gt":
|
|
1635
|
+
return greaterThan(parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor));
|
|
1636
|
+
case "Ge":
|
|
1637
|
+
return greaterOrEqual(parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor));
|
|
1638
|
+
case "Lt":
|
|
1639
|
+
return lessThan(parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor));
|
|
1640
|
+
case "Le":
|
|
1641
|
+
return lessOrEqual(parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor));
|
|
1642
|
+
case "Or":
|
|
1643
|
+
return or(...annotationValue.$Or.map(function (orCondition) {
|
|
1644
|
+
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
1645
|
+
}));
|
|
1646
|
+
case "And":
|
|
1647
|
+
return and(...annotationValue.$And.map(function (andCondition) {
|
|
1648
|
+
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
1649
|
+
}));
|
|
1650
|
+
case "Apply":
|
|
1651
|
+
return annotationApplyExpression(annotationValue, visitedNavigationPaths, pathVisitor);
|
|
1652
|
+
}
|
|
1653
|
+
return unresolvableExpression;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
/**
|
|
1657
|
+
* Parse the annotation condition into an expression.
|
|
1658
|
+
*
|
|
1659
|
+
* @template T The target type
|
|
1660
|
+
* @param annotationValue The condition or value from the annotation
|
|
1661
|
+
* @param visitedNavigationPaths The path from the root entity set
|
|
1662
|
+
* @param pathVisitor A function to modify the resulting path
|
|
1663
|
+
* @returns An equivalent expression
|
|
1664
|
+
*/
|
|
1665
|
+
function parseAnnotationCondition(annotationValue, visitedNavigationPaths = [], pathVisitor) {
|
|
1666
|
+
if (annotationValue === null || typeof annotationValue !== "object") {
|
|
1667
|
+
return constant(annotationValue);
|
|
1668
|
+
} else if (annotationValue.hasOwnProperty("$Or")) {
|
|
1669
|
+
return or(...annotationValue.$Or.map(function (orCondition) {
|
|
1670
|
+
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
1671
|
+
}));
|
|
1672
|
+
} else if (annotationValue.hasOwnProperty("$And")) {
|
|
1673
|
+
return and(...annotationValue.$And.map(function (andCondition) {
|
|
1674
|
+
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
1675
|
+
}));
|
|
1676
|
+
} else if (annotationValue.hasOwnProperty("$Not")) {
|
|
1677
|
+
return not(parseAnnotationCondition(annotationValue.$Not, visitedNavigationPaths, pathVisitor));
|
|
1678
|
+
} else if (annotationValue.hasOwnProperty("$Eq")) {
|
|
1679
|
+
return equal(parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor));
|
|
1680
|
+
} else if (annotationValue.hasOwnProperty("$Ne")) {
|
|
1681
|
+
return notEqual(parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor));
|
|
1682
|
+
} else if (annotationValue.hasOwnProperty("$Gt")) {
|
|
1683
|
+
return greaterThan(parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor));
|
|
1684
|
+
} else if (annotationValue.hasOwnProperty("$Ge")) {
|
|
1685
|
+
return greaterOrEqual(parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor));
|
|
1686
|
+
} else if (annotationValue.hasOwnProperty("$Lt")) {
|
|
1687
|
+
return lessThan(parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor));
|
|
1688
|
+
} else if (annotationValue.hasOwnProperty("$Le")) {
|
|
1689
|
+
return lessOrEqual(parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor));
|
|
1690
|
+
} else if (annotationValue.hasOwnProperty("$Path")) {
|
|
1691
|
+
return pathInModel(annotationValue.$Path, undefined, visitedNavigationPaths, pathVisitor);
|
|
1692
|
+
} else if (annotationValue.hasOwnProperty("Path")) {
|
|
1693
|
+
return pathInModel(annotationValue.Path, undefined, visitedNavigationPaths, pathVisitor);
|
|
1694
|
+
} else if (annotationValue.hasOwnProperty("$Apply")) {
|
|
1695
|
+
return getExpressionFromAnnotation({
|
|
1696
|
+
type: "Apply",
|
|
1697
|
+
$Function: annotationValue.$Function,
|
|
1698
|
+
$Apply: annotationValue.$Apply
|
|
1699
|
+
}, visitedNavigationPaths, undefined, pathVisitor);
|
|
1700
|
+
} else if (annotationValue.hasOwnProperty("$If")) {
|
|
1701
|
+
return getExpressionFromAnnotation({
|
|
1702
|
+
type: "If",
|
|
1703
|
+
$If: annotationValue.$If
|
|
1704
|
+
}, visitedNavigationPaths, undefined, pathVisitor);
|
|
1705
|
+
} else if (annotationValue.hasOwnProperty("$EnumMember")) {
|
|
1706
|
+
return constant(annotationValue.$EnumMember);
|
|
1707
|
+
} else if (annotationValue.hasOwnProperty("String")) {
|
|
1708
|
+
return constant(annotationValue.String);
|
|
1709
|
+
} else if (annotationValue.hasOwnProperty("Bool")) {
|
|
1710
|
+
return constant(annotationValue.Bool);
|
|
1711
|
+
} else if (annotationValue.hasOwnProperty("Int")) {
|
|
1712
|
+
return constant(annotationValue.Int);
|
|
1713
|
+
} else if (annotationValue.hasOwnProperty("Decimal")) {
|
|
1714
|
+
return constant(annotationValue.Decimal);
|
|
1715
|
+
} else if (annotationValue.hasOwnProperty("type") && annotationValue.type === "Null") {
|
|
1716
|
+
return constant(null);
|
|
1717
|
+
}
|
|
1718
|
+
return constant(false);
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
/**
|
|
1722
|
+
* Process the {IfAnnotationExpressionValue} into an expression.
|
|
1723
|
+
*
|
|
1724
|
+
* @template T The target type
|
|
1725
|
+
* @param annotationValue An If expression returning the type T
|
|
1726
|
+
* @param visitedNavigationPaths The path from the root entity set
|
|
1727
|
+
* @param pathVisitor A function to modify the resulting path
|
|
1728
|
+
* @returns The equivalent ifElse expression
|
|
1729
|
+
*/
|
|
1730
|
+
function annotationIfExpression(annotationValue, visitedNavigationPaths = [], pathVisitor) {
|
|
1731
|
+
return ifElse(parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[1], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[2], visitedNavigationPaths, pathVisitor));
|
|
1732
|
+
}
|
|
1733
|
+
// This type is not recursively transformed from the metamodel content, as such we have some ugly things there
|
|
1734
|
+
|
|
1735
|
+
function convertSubApplyParameters(applyParam) {
|
|
1736
|
+
let applyParamConverted = applyParam;
|
|
1737
|
+
if (applyParam.hasOwnProperty("$Path")) {
|
|
1738
|
+
applyParamConverted = {
|
|
1739
|
+
type: "Path",
|
|
1740
|
+
path: applyParam.$Path
|
|
1741
|
+
};
|
|
1742
|
+
} else if (applyParam.hasOwnProperty("$If")) {
|
|
1743
|
+
applyParamConverted = {
|
|
1744
|
+
type: "If",
|
|
1745
|
+
$If: applyParam.$If
|
|
1746
|
+
};
|
|
1747
|
+
} else if (applyParam.hasOwnProperty("$Apply")) {
|
|
1748
|
+
applyParamConverted = {
|
|
1749
|
+
type: "Apply",
|
|
1750
|
+
$Function: applyParam.$Function,
|
|
1751
|
+
$Apply: applyParam.$Apply
|
|
1752
|
+
};
|
|
1753
|
+
}
|
|
1754
|
+
return applyParamConverted;
|
|
1755
|
+
}
|
|
1756
|
+
function annotationApplyExpression(applyExpression, visitedNavigationPaths = [], pathVisitor) {
|
|
1757
|
+
switch (applyExpression.$Function) {
|
|
1758
|
+
case "odata.concat":
|
|
1759
|
+
return concat(...applyExpression.$Apply.map(applyParam => {
|
|
1760
|
+
return getExpressionFromAnnotation(convertSubApplyParameters(applyParam), visitedNavigationPaths, undefined, pathVisitor);
|
|
1761
|
+
}));
|
|
1762
|
+
case "odata.uriEncode":
|
|
1763
|
+
const parameter = getExpressionFromAnnotation(convertSubApplyParameters(applyExpression.$Apply[0]), visitedNavigationPaths, undefined, pathVisitor);
|
|
1764
|
+
// 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
|
|
1765
|
+
return fn("odata.uriEncode", [parameter, "Edm.String"], undefined, true);
|
|
1766
|
+
case "odata.fillUriTemplate":
|
|
1767
|
+
const template = applyExpression.$Apply[0];
|
|
1768
|
+
const templateParams = applyExpression.$Apply.slice(1);
|
|
1769
|
+
const targetObject = {};
|
|
1770
|
+
templateParams.forEach(applyParam => {
|
|
1771
|
+
targetObject[applyParam.$Name] = getExpressionFromAnnotation(convertSubApplyParameters(applyParam.$LabeledElement), visitedNavigationPaths, undefined, pathVisitor);
|
|
1772
|
+
});
|
|
1773
|
+
return fn("odata.fillUriTemplate", [template, targetObject], undefined, true);
|
|
1774
|
+
}
|
|
1775
|
+
return unresolvableExpression;
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
/**
|
|
1779
|
+
* Generic helper for the comparison operations (equal, notEqual, ...).
|
|
1780
|
+
*
|
|
1781
|
+
* @template T The target type
|
|
1782
|
+
* @param operator The operator to apply
|
|
1783
|
+
* @param leftOperand The operand on the left side of the operator
|
|
1784
|
+
* @param rightOperand The operand on the right side of the operator
|
|
1785
|
+
* @returns An expression representing the comparison
|
|
1786
|
+
*/
|
|
1787
|
+
function comparison(operator, leftOperand, rightOperand) {
|
|
1788
|
+
const leftExpression = wrapPrimitive(leftOperand);
|
|
1789
|
+
const rightExpression = wrapPrimitive(rightOperand);
|
|
1790
|
+
if (hasUnresolvableExpression(leftExpression, rightExpression)) {
|
|
1791
|
+
return unresolvableExpression;
|
|
1792
|
+
}
|
|
1793
|
+
if (isConstant(leftExpression) && isConstant(rightExpression)) {
|
|
1794
|
+
switch (operator) {
|
|
1795
|
+
case "!==":
|
|
1796
|
+
return constant(leftExpression.value !== rightExpression.value);
|
|
1797
|
+
case "===":
|
|
1798
|
+
return constant(leftExpression.value === rightExpression.value);
|
|
1799
|
+
case "<":
|
|
1800
|
+
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
1801
|
+
return constant(false);
|
|
1802
|
+
}
|
|
1803
|
+
return constant(leftExpression.value < rightExpression.value);
|
|
1804
|
+
case "<=":
|
|
1805
|
+
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
1806
|
+
return constant(false);
|
|
1807
|
+
}
|
|
1808
|
+
return constant(leftExpression.value <= rightExpression.value);
|
|
1809
|
+
case ">":
|
|
1810
|
+
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
1811
|
+
return constant(false);
|
|
1812
|
+
}
|
|
1813
|
+
return constant(leftExpression.value > rightExpression.value);
|
|
1814
|
+
case ">=":
|
|
1815
|
+
if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
|
|
1816
|
+
return constant(false);
|
|
1817
|
+
}
|
|
1818
|
+
return constant(leftExpression.value >= rightExpression.value);
|
|
1819
|
+
}
|
|
1820
|
+
} else {
|
|
1821
|
+
return {
|
|
1822
|
+
_type: "Comparison",
|
|
1823
|
+
operator: operator,
|
|
1824
|
+
operand1: leftExpression,
|
|
1825
|
+
operand2: rightExpression
|
|
1826
|
+
};
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
/**
|
|
1831
|
+
* Generic helper for the length of an expression.
|
|
1832
|
+
*
|
|
1833
|
+
* @param expression The input expression pointing to an array
|
|
1834
|
+
* @param checkUndefined Is the array potentially undefined
|
|
1835
|
+
* @returns An expression representing the length
|
|
1836
|
+
*/
|
|
1837
|
+
function length(expression, checkUndefined = false) {
|
|
1838
|
+
if (expression._type === "Unresolvable") {
|
|
1839
|
+
return expression;
|
|
1840
|
+
}
|
|
1841
|
+
if (!checkUndefined) {
|
|
1842
|
+
return {
|
|
1843
|
+
_type: "Length",
|
|
1844
|
+
pathInModel: expression
|
|
1845
|
+
};
|
|
1846
|
+
}
|
|
1847
|
+
return ifElse(equal(expression, undefined), -1, length(expression));
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
/**
|
|
1851
|
+
* Comparison: "equal" (===).
|
|
1852
|
+
*
|
|
1853
|
+
* @template T The target type
|
|
1854
|
+
* @param leftOperand The operand on the left side
|
|
1855
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1856
|
+
* @returns An expression representing the comparison
|
|
1857
|
+
*/
|
|
1858
|
+
function equal(leftOperand, rightOperand) {
|
|
1859
|
+
const leftExpression = wrapPrimitive(leftOperand);
|
|
1860
|
+
const rightExpression = wrapPrimitive(rightOperand);
|
|
1861
|
+
if (hasUnresolvableExpression(leftExpression, rightExpression)) {
|
|
1862
|
+
return unresolvableExpression;
|
|
1863
|
+
}
|
|
1864
|
+
if (_checkExpressionsAreEqual(leftExpression, rightExpression)) {
|
|
1865
|
+
return constant(true);
|
|
1866
|
+
}
|
|
1867
|
+
function reduce(left, right) {
|
|
1868
|
+
if (left._type === "Comparison" && isTrue(right)) {
|
|
1869
|
+
// compare(a, b) === true ~~> compare(a, b)
|
|
1870
|
+
return left;
|
|
1871
|
+
} else if (left._type === "Comparison" && isFalse(right)) {
|
|
1872
|
+
// compare(a, b) === false ~~> !compare(a, b)
|
|
1873
|
+
return not(left);
|
|
1874
|
+
} else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onTrue, right)) {
|
|
1875
|
+
// (if (x) { a } else { b }) === a ~~> x || (b === a)
|
|
1876
|
+
return or(left.condition, equal(left.onFalse, right));
|
|
1877
|
+
} else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onFalse, right)) {
|
|
1878
|
+
// (if (x) { a } else { b }) === b ~~> !x || (a === b)
|
|
1879
|
+
return or(not(left.condition), equal(left.onTrue, right));
|
|
1880
|
+
} else if (left._type === "IfElse" && isConstant(left.onTrue) && isConstant(left.onFalse) && isConstant(right) && !_checkExpressionsAreEqual(left.onTrue, right) && !_checkExpressionsAreEqual(left.onFalse, right)) {
|
|
1881
|
+
return constant(false);
|
|
1882
|
+
}
|
|
1883
|
+
return undefined;
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
// exploit symmetry: a === b <~> b === a
|
|
1887
|
+
const reduced = reduce(leftExpression, rightExpression) ?? reduce(rightExpression, leftExpression);
|
|
1888
|
+
return reduced ?? comparison("===", leftExpression, rightExpression);
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
/**
|
|
1892
|
+
* Comparison: "not equal" (!==).
|
|
1893
|
+
*
|
|
1894
|
+
* @template T The target type
|
|
1895
|
+
* @param leftOperand The operand on the left side
|
|
1896
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1897
|
+
* @returns An expression representing the comparison
|
|
1898
|
+
*/
|
|
1899
|
+
function notEqual(leftOperand, rightOperand) {
|
|
1900
|
+
return not(equal(leftOperand, rightOperand));
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
/**
|
|
1904
|
+
* Comparison: "greater or equal" (>=).
|
|
1905
|
+
*
|
|
1906
|
+
* @template T The target type
|
|
1907
|
+
* @param leftOperand The operand on the left side
|
|
1908
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1909
|
+
* @returns An expression representing the comparison
|
|
1910
|
+
*/
|
|
1911
|
+
function greaterOrEqual(leftOperand, rightOperand) {
|
|
1912
|
+
return comparison(">=", leftOperand, rightOperand);
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
/**
|
|
1916
|
+
* Comparison: "greater than" (>).
|
|
1917
|
+
*
|
|
1918
|
+
* @template T The target type
|
|
1919
|
+
* @param leftOperand The operand on the left side
|
|
1920
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1921
|
+
* @returns An expression representing the comparison
|
|
1922
|
+
*/
|
|
1923
|
+
function greaterThan(leftOperand, rightOperand) {
|
|
1924
|
+
return comparison(">", leftOperand, rightOperand);
|
|
1925
|
+
}
|
|
1926
|
+
|
|
1927
|
+
/**
|
|
1928
|
+
* Comparison: "less or equal" (<=).
|
|
1929
|
+
*
|
|
1930
|
+
* @template T The target type
|
|
1931
|
+
* @param leftOperand The operand on the left side
|
|
1932
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1933
|
+
* @returns An expression representing the comparison
|
|
1934
|
+
*/
|
|
1935
|
+
function lessOrEqual(leftOperand, rightOperand) {
|
|
1936
|
+
return comparison("<=", leftOperand, rightOperand);
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
/**
|
|
1940
|
+
* Comparison: "less than" (<).
|
|
1941
|
+
*
|
|
1942
|
+
* @template T The target type
|
|
1943
|
+
* @param leftOperand The operand on the left side
|
|
1944
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1945
|
+
* @returns An expression representing the comparison
|
|
1946
|
+
*/
|
|
1947
|
+
function lessThan(leftOperand, rightOperand) {
|
|
1948
|
+
return comparison("<", leftOperand, rightOperand);
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
/**
|
|
1952
|
+
* If-then-else expression.
|
|
1953
|
+
*
|
|
1954
|
+
* Evaluates to onTrue if the condition evaluates to true, else evaluates to onFalse.
|
|
1955
|
+
*
|
|
1956
|
+
* @template T The target type
|
|
1957
|
+
* @param condition The condition to evaluate
|
|
1958
|
+
* @param onTrue Expression result if the condition evaluates to true
|
|
1959
|
+
* @param onFalse Expression result if the condition evaluates to false
|
|
1960
|
+
* @returns The expression that represents this conditional check
|
|
1961
|
+
*/
|
|
1962
|
+
function ifElse(condition, onTrue, onFalse) {
|
|
1963
|
+
let conditionExpression = wrapPrimitive(condition);
|
|
1964
|
+
let onTrueExpression = wrapPrimitive(onTrue);
|
|
1965
|
+
let onFalseExpression = wrapPrimitive(onFalse);
|
|
1966
|
+
|
|
1967
|
+
// swap branches if the condition is a negation
|
|
1968
|
+
if (conditionExpression._type === "Not") {
|
|
1969
|
+
// ifElse(not(X), a, b) --> ifElse(X, b, a)
|
|
1970
|
+
[onTrueExpression, onFalseExpression] = [onFalseExpression, onTrueExpression];
|
|
1971
|
+
conditionExpression = not(conditionExpression);
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
// inline nested if-else expressions: onTrue branch
|
|
1975
|
+
// ifElse(X, ifElse(X, a, b), c) ==> ifElse(X, a, c)
|
|
1976
|
+
if (onTrueExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onTrueExpression.condition)) {
|
|
1977
|
+
onTrueExpression = onTrueExpression.onTrue;
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
// inline nested if-else expressions: onFalse branch
|
|
1981
|
+
// ifElse(X, a, ifElse(X, b, c)) ==> ifElse(X, a, c)
|
|
1982
|
+
if (onFalseExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onFalseExpression.condition)) {
|
|
1983
|
+
onFalseExpression = onFalseExpression.onFalse;
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
// (if true then a else b) ~~> a
|
|
1987
|
+
// (if false then a else b) ~~> b
|
|
1988
|
+
if (isConstant(conditionExpression)) {
|
|
1989
|
+
return conditionExpression.value ? onTrueExpression : onFalseExpression;
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
// if (isConstantBoolean(onTrueExpression) || isConstantBoolean(onFalseExpression)) {
|
|
1993
|
+
// return or(and(condition, onTrueExpression as Expression<boolean>), and(not(condition), onFalseExpression as Expression<boolean>)) as Expression<T>
|
|
1994
|
+
// }
|
|
1995
|
+
|
|
1996
|
+
// (if X then a else a) ~~> a
|
|
1997
|
+
if (_checkExpressionsAreEqual(onTrueExpression, onFalseExpression)) {
|
|
1998
|
+
return onTrueExpression;
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
// if X then a else false ~~> X && a
|
|
2002
|
+
if (isFalse(onFalseExpression)) {
|
|
2003
|
+
return and(conditionExpression, onTrueExpression);
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
// if X then a else true ~~> !X || a
|
|
2007
|
+
if (isTrue(onFalseExpression)) {
|
|
2008
|
+
return or(not(conditionExpression), onTrueExpression);
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
// if X then false else a ~~> !X && a
|
|
2012
|
+
if (isFalse(onTrueExpression)) {
|
|
2013
|
+
return and(not(conditionExpression), onFalseExpression);
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
// if X then true else a ~~> X || a
|
|
2017
|
+
if (isTrue(onTrueExpression)) {
|
|
2018
|
+
return or(conditionExpression, onFalseExpression);
|
|
2019
|
+
}
|
|
2020
|
+
if (hasUnresolvableExpression(conditionExpression, onTrueExpression, onFalseExpression)) {
|
|
2021
|
+
return unresolvableExpression;
|
|
2022
|
+
}
|
|
2023
|
+
if (isComplexTypeExpression(condition) || isComplexTypeExpression(onTrue) || isComplexTypeExpression(onFalse)) {
|
|
2024
|
+
let pathIdx = 0;
|
|
2025
|
+
const myIfElseExpression = formatResult([condition, onTrue, onFalse], "sap.fe.core.formatters.StandardFormatter#ifElse");
|
|
2026
|
+
const allParts = [];
|
|
2027
|
+
transformRecursively(myIfElseExpression, "PathInModel", constantPath => {
|
|
2028
|
+
allParts.push(constantPath);
|
|
2029
|
+
return pathInModel(`$${pathIdx++}`, "$");
|
|
2030
|
+
}, true);
|
|
2031
|
+
allParts.unshift(constant(JSON.stringify(myIfElseExpression)));
|
|
2032
|
+
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
|
|
2033
|
+
}
|
|
2034
|
+
return {
|
|
2035
|
+
_type: "IfElse",
|
|
2036
|
+
condition: conditionExpression,
|
|
2037
|
+
onTrue: onTrueExpression,
|
|
2038
|
+
onFalse: onFalseExpression
|
|
2039
|
+
};
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
/**
|
|
2043
|
+
* Checks whether the current expression has a reference to the default model (undefined).
|
|
2044
|
+
*
|
|
2045
|
+
* @param expression The expression to evaluate
|
|
2046
|
+
* @returns `true` if there is a reference to the default context
|
|
2047
|
+
*/
|
|
2048
|
+
function hasReferenceToDefaultContext(expression) {
|
|
2049
|
+
switch (expression._type) {
|
|
2050
|
+
case "Constant":
|
|
2051
|
+
case "Formatter":
|
|
2052
|
+
case "ComplexType":
|
|
2053
|
+
return false;
|
|
2054
|
+
case "Set":
|
|
2055
|
+
return expression.operands.some(hasReferenceToDefaultContext);
|
|
2056
|
+
case "PathInModel":
|
|
2057
|
+
return expression.modelName === undefined;
|
|
2058
|
+
case "Comparison":
|
|
2059
|
+
return hasReferenceToDefaultContext(expression.operand1) || hasReferenceToDefaultContext(expression.operand2);
|
|
2060
|
+
case "IfElse":
|
|
2061
|
+
return hasReferenceToDefaultContext(expression.condition) || hasReferenceToDefaultContext(expression.onTrue) || hasReferenceToDefaultContext(expression.onFalse);
|
|
2062
|
+
case "Not":
|
|
2063
|
+
case "Truthy":
|
|
2064
|
+
return hasReferenceToDefaultContext(expression.operand);
|
|
2065
|
+
default:
|
|
2066
|
+
return false;
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
// This is one case where any does make sense...
|
|
2071
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2072
|
+
|
|
2073
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2074
|
+
// @ts-ignore
|
|
2075
|
+
|
|
2076
|
+
// So, this works but I cannot get it to compile :D, but it still does what is expected...
|
|
2077
|
+
|
|
2078
|
+
/**
|
|
2079
|
+
* A function reference or a function name.
|
|
2080
|
+
*/
|
|
2081
|
+
|
|
2082
|
+
/**
|
|
2083
|
+
* Function parameters, either derived from the function or an untyped array.
|
|
2084
|
+
*/
|
|
2085
|
+
|
|
2086
|
+
/**
|
|
2087
|
+
* Calls a formatter function to process the parameters.
|
|
2088
|
+
* If requireContext is set to true and no context is passed a default context will be added automatically.
|
|
2089
|
+
*
|
|
2090
|
+
* @template T
|
|
2091
|
+
* @template U
|
|
2092
|
+
* @param parameters The list of parameter that should match the type and number of the formatter function
|
|
2093
|
+
* @param formatterFunction The function to call
|
|
2094
|
+
* @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.
|
|
2095
|
+
* @param [ignoreComplexType] Whether to ignore the transgformation to the StandardFormatter or not
|
|
2096
|
+
* @returns The corresponding expression
|
|
2097
|
+
*/
|
|
2098
|
+
function formatResult(parameters, formatterFunction, contextEntityType, ignoreComplexType = false) {
|
|
2099
|
+
const parameterExpressions = parameters.map(wrapPrimitive);
|
|
2100
|
+
if (hasUnresolvableExpression(...parameterExpressions)) {
|
|
2101
|
+
return unresolvableExpression;
|
|
2102
|
+
}
|
|
2103
|
+
if (contextEntityType) {
|
|
2104
|
+
// Otherwise, if the context is required and no context is provided make sure to add the default binding
|
|
2105
|
+
if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
|
|
2106
|
+
contextEntityType.keys.forEach(key => parameterExpressions.push(pathInModel(key.name, "")));
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
let functionName = "";
|
|
2110
|
+
if (typeof formatterFunction === "string") {
|
|
2111
|
+
functionName = formatterFunction;
|
|
2112
|
+
} else {
|
|
2113
|
+
functionName = formatterFunction.__functionName;
|
|
2114
|
+
}
|
|
2115
|
+
// FormatterName can be of format sap.fe.core.xxx#methodName to have multiple formatter in one class
|
|
2116
|
+
const [formatterClass, formatterName] = functionName.split("#");
|
|
2117
|
+
|
|
2118
|
+
// 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
|
|
2119
|
+
if (!ignoreComplexType && (parameterExpressions.some(isComplexTypeExpression) || parameterExpressions.some(isConcatExpression) || parameterExpressions.some(isIfElseExpression))) {
|
|
2120
|
+
let pathIdx = 0;
|
|
2121
|
+
const myFormatExpression = formatResult(parameterExpressions, functionName, undefined, true);
|
|
2122
|
+
const allParts = [];
|
|
2123
|
+
transformRecursively(myFormatExpression, "PathInModel", constantPath => {
|
|
2124
|
+
allParts.push(constantPath);
|
|
2125
|
+
return pathInModel(`$${pathIdx++}`, "$");
|
|
2126
|
+
}, true);
|
|
2127
|
+
allParts.unshift(constant(JSON.stringify(myFormatExpression)));
|
|
2128
|
+
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
|
|
2129
|
+
} else if (!!formatterName && formatterName.length > 0) {
|
|
2130
|
+
parameterExpressions.unshift(constant(formatterName));
|
|
2131
|
+
}
|
|
2132
|
+
return {
|
|
2133
|
+
_type: "Formatter",
|
|
2134
|
+
fn: formatterClass,
|
|
2135
|
+
parameters: parameterExpressions
|
|
2136
|
+
};
|
|
2137
|
+
}
|
|
2138
|
+
const getFiscalType = function (property) {
|
|
2139
|
+
if (property.annotations.Common?.IsFiscalYear) {
|
|
2140
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalYear";
|
|
2141
|
+
}
|
|
2142
|
+
if (property.annotations.Common?.IsFiscalPeriod) {
|
|
2143
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalPeriod";
|
|
2144
|
+
}
|
|
2145
|
+
if (property.annotations.Common?.IsFiscalYearPeriod) {
|
|
2146
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalYearPeriod";
|
|
2147
|
+
}
|
|
2148
|
+
if (property.annotations.Common?.IsFiscalQuarter) {
|
|
2149
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalQuarter";
|
|
2150
|
+
}
|
|
2151
|
+
if (property.annotations.Common?.IsFiscalYearQuarter) {
|
|
2152
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalYearQuarter";
|
|
2153
|
+
}
|
|
2154
|
+
if (property.annotations.Common?.IsFiscalWeek) {
|
|
2155
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalWeek";
|
|
2156
|
+
}
|
|
2157
|
+
if (property.annotations.Common?.IsFiscalYearWeek) {
|
|
2158
|
+
return "com.sap.vocabularies.Common.v1.IsFiscalYearWeek";
|
|
2159
|
+
}
|
|
2160
|
+
if (property.annotations.Common?.IsDayOfFiscalYear) {
|
|
2161
|
+
return "com.sap.vocabularies.Common.v1.IsDayOfFiscalYear";
|
|
2162
|
+
}
|
|
2163
|
+
};
|
|
2164
|
+
|
|
2165
|
+
/**
|
|
2166
|
+
* Function call, optionally with arguments.
|
|
2167
|
+
*
|
|
2168
|
+
* @param func Function name or reference to function
|
|
2169
|
+
* @param parameters Arguments
|
|
2170
|
+
* @param on Object to call the function on
|
|
2171
|
+
* @param isFormattingFn
|
|
2172
|
+
* @returns Expression representing the function call (not the result of the function call!)
|
|
2173
|
+
*/
|
|
2174
|
+
exports.getFiscalType = getFiscalType;
|
|
2175
|
+
function fn(func, parameters, on, isFormattingFn = false) {
|
|
2176
|
+
const functionName = typeof func === "string" ? func : func.__functionName;
|
|
2177
|
+
return {
|
|
2178
|
+
_type: "Function",
|
|
2179
|
+
obj: on !== undefined ? wrapPrimitive(on) : undefined,
|
|
2180
|
+
fn: functionName,
|
|
2181
|
+
isFormattingFn: isFormattingFn,
|
|
2182
|
+
parameters: parameters.map(wrapPrimitive)
|
|
2183
|
+
};
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
/**
|
|
2187
|
+
* Shortcut function to determine if a binding value is null, undefined or empty.
|
|
2188
|
+
*
|
|
2189
|
+
* @param expression
|
|
2190
|
+
* @returns A Boolean expression evaluating the fact that the current element is empty
|
|
2191
|
+
*/
|
|
2192
|
+
function isEmpty(expression) {
|
|
2193
|
+
const aBindings = [];
|
|
2194
|
+
transformRecursively(expression, "PathInModel", expr => {
|
|
2195
|
+
aBindings.push(or(equal(expr, ""), equal(expr, undefined), equal(expr, null)));
|
|
2196
|
+
return expr;
|
|
2197
|
+
});
|
|
2198
|
+
return and(...aBindings);
|
|
2199
|
+
}
|
|
2200
|
+
function concat(
|
|
2201
|
+
//eslint-disable-next-line @typescript-eslint/no-wrapper-object-types
|
|
2202
|
+
...inExpressions) {
|
|
2203
|
+
const expressions = inExpressions.map(wrapPrimitive);
|
|
2204
|
+
if (hasUnresolvableExpression(...expressions)) {
|
|
2205
|
+
return unresolvableExpression;
|
|
2206
|
+
}
|
|
2207
|
+
if (expressions.every(isConstant)) {
|
|
2208
|
+
return constant(expressions.reduce((concatenated, value) => {
|
|
2209
|
+
if (value.value !== undefined && value.value !== null) {
|
|
2210
|
+
return concatenated + value.value.toString();
|
|
2211
|
+
}
|
|
2212
|
+
return concatenated;
|
|
2213
|
+
}, ""));
|
|
2214
|
+
} else if (expressions.some(isComplexTypeExpression)) {
|
|
2215
|
+
let pathIdx = 0;
|
|
2216
|
+
const myConcatExpression = formatResult(expressions, "sap.fe.core.formatters.StandardFormatter#concat", undefined, true);
|
|
2217
|
+
const allParts = [];
|
|
2218
|
+
transformRecursively(myConcatExpression, "PathInModel", constantPath => {
|
|
2219
|
+
allParts.push(constantPath);
|
|
2220
|
+
return pathInModel(`$${pathIdx++}`, "$");
|
|
2221
|
+
});
|
|
2222
|
+
allParts.unshift(constant(JSON.stringify(myConcatExpression)));
|
|
2223
|
+
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
|
|
2224
|
+
}
|
|
2225
|
+
return {
|
|
2226
|
+
_type: "Concat",
|
|
2227
|
+
expressions: expressions
|
|
2228
|
+
};
|
|
2229
|
+
}
|
|
2230
|
+
function transformRecursively(inExpression, expressionType, transformFunction, includeAllExpression = false) {
|
|
2231
|
+
let expression = inExpression;
|
|
2232
|
+
switch (expression._type) {
|
|
2233
|
+
case "Function":
|
|
2234
|
+
case "Formatter":
|
|
2235
|
+
expression.parameters = expression.parameters.map(parameter => transformRecursively(parameter, expressionType, transformFunction, includeAllExpression));
|
|
2236
|
+
break;
|
|
2237
|
+
case "Concat":
|
|
2238
|
+
expression.expressions = expression.expressions.map(subExpression => transformRecursively(subExpression, expressionType, transformFunction, includeAllExpression));
|
|
2239
|
+
expression = concat(...expression.expressions);
|
|
2240
|
+
break;
|
|
2241
|
+
case "ComplexType":
|
|
2242
|
+
expression.bindingParameters = expression.bindingParameters.map(bindingParameter => transformRecursively(bindingParameter, expressionType, transformFunction, includeAllExpression));
|
|
2243
|
+
break;
|
|
2244
|
+
case "IfElse":
|
|
2245
|
+
{
|
|
2246
|
+
const onTrue = transformRecursively(expression.onTrue, expressionType, transformFunction, includeAllExpression);
|
|
2247
|
+
const onFalse = transformRecursively(expression.onFalse, expressionType, transformFunction, includeAllExpression);
|
|
2248
|
+
let condition = expression.condition;
|
|
2249
|
+
if (includeAllExpression) {
|
|
2250
|
+
condition = transformRecursively(expression.condition, expressionType, transformFunction, includeAllExpression);
|
|
2251
|
+
}
|
|
2252
|
+
expression = ifElse(condition, onTrue, onFalse);
|
|
2253
|
+
break;
|
|
2254
|
+
}
|
|
2255
|
+
case "Not":
|
|
2256
|
+
if (includeAllExpression) {
|
|
2257
|
+
const operand = transformRecursively(expression.operand, expressionType, transformFunction, includeAllExpression);
|
|
2258
|
+
expression = not(operand);
|
|
2259
|
+
}
|
|
2260
|
+
break;
|
|
2261
|
+
case "Truthy":
|
|
2262
|
+
break;
|
|
2263
|
+
case "Set":
|
|
2264
|
+
if (includeAllExpression) {
|
|
2265
|
+
const operands = expression.operands.map(operand => transformRecursively(operand, expressionType, transformFunction, includeAllExpression));
|
|
2266
|
+
expression = expression.operator === "||" ? or(...operands) : and(...operands);
|
|
2267
|
+
}
|
|
2268
|
+
break;
|
|
2269
|
+
case "Comparison":
|
|
2270
|
+
if (includeAllExpression) {
|
|
2271
|
+
const operand1 = transformRecursively(expression.operand1, expressionType, transformFunction, includeAllExpression);
|
|
2272
|
+
const operand2 = transformRecursively(expression.operand2, expressionType, transformFunction, includeAllExpression);
|
|
2273
|
+
expression = comparison(expression.operator, operand1, operand2);
|
|
2274
|
+
}
|
|
2275
|
+
break;
|
|
2276
|
+
case "Constant":
|
|
2277
|
+
{
|
|
2278
|
+
const constantValue = expression.value;
|
|
2279
|
+
if (typeof constantValue === "object" && constantValue) {
|
|
2280
|
+
Object.keys(constantValue).forEach(key => {
|
|
2281
|
+
constantValue[key] = transformRecursively(constantValue[key], expressionType, transformFunction, includeAllExpression);
|
|
2282
|
+
});
|
|
2283
|
+
}
|
|
2284
|
+
break;
|
|
2285
|
+
}
|
|
2286
|
+
case "Ref":
|
|
2287
|
+
case "Length":
|
|
2288
|
+
case "PathInModel":
|
|
2289
|
+
case "EmbeddedBinding":
|
|
2290
|
+
case "EmbeddedExpressionBinding":
|
|
2291
|
+
case "Unresolvable":
|
|
2292
|
+
// Do nothing
|
|
2293
|
+
break;
|
|
2294
|
+
}
|
|
2295
|
+
if (expressionType === expression._type) {
|
|
2296
|
+
expression = transformFunction(inExpression);
|
|
2297
|
+
}
|
|
2298
|
+
return expression;
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
|
|
2302
|
+
/***/ }),
|
|
2303
|
+
|
|
2304
|
+
/***/ 331:
|
|
2305
|
+
/***/ (function(__unused_webpack_module, exports) {
|
|
2306
|
+
|
|
2307
|
+
|
|
2308
|
+
|
|
2309
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
2310
|
+
value: true
|
|
2311
|
+
}));
|
|
2312
|
+
exports.isAnnotationOfTerm = isAnnotationOfTerm;
|
|
2313
|
+
exports.isAnnotationOfType = isAnnotationOfType;
|
|
2314
|
+
exports.isAnnotationPath = isAnnotationPath;
|
|
2315
|
+
exports.isAnnotationTerm = isAnnotationTerm;
|
|
2316
|
+
exports.isComplexType = isComplexType;
|
|
2317
|
+
exports.isEntityContainer = isEntityContainer;
|
|
2318
|
+
exports.isEntitySet = isEntitySet;
|
|
2319
|
+
exports.isEntityType = isEntityType;
|
|
2320
|
+
exports.isMultipleNavigationProperty = isMultipleNavigationProperty;
|
|
2321
|
+
exports.isNavigationProperty = isNavigationProperty;
|
|
2322
|
+
exports.isPathAnnotationExpression = isPathAnnotationExpression;
|
|
2323
|
+
exports.isProperty = isProperty;
|
|
2324
|
+
exports.isPropertyPathExpression = isPropertyPathExpression;
|
|
2325
|
+
exports.isServiceObject = isServiceObject;
|
|
2326
|
+
exports.isSingleNavigationProperty = isSingleNavigationProperty;
|
|
2327
|
+
exports.isSingleton = isSingleton;
|
|
2328
|
+
exports.isTypeDefinition = isTypeDefinition;
|
|
2329
|
+
exports.isValidPropertyPathExpression = isValidPropertyPathExpression;
|
|
2330
|
+
/**
|
|
2331
|
+
* Checks whether the argument is an annotation of the given type.
|
|
2332
|
+
* @param potentialAnnotationType The annotation to check
|
|
2333
|
+
* @param typeName The type to check for
|
|
2334
|
+
* @returns Whether the argument is an annotation of the given type
|
|
2335
|
+
*/
|
|
2336
|
+
function isAnnotationOfType(potentialAnnotationType, typeName) {
|
|
2337
|
+
if (Array.isArray(typeName)) {
|
|
2338
|
+
return typeName.includes(potentialAnnotationType.$Type);
|
|
2339
|
+
}
|
|
2340
|
+
return potentialAnnotationType.$Type === typeName;
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
/**
|
|
2344
|
+
* Checks whether the argument is an annotation of the given term.
|
|
2345
|
+
* @param potentialAnnotation The annotation to check
|
|
2346
|
+
* @param termName The term to check for
|
|
2347
|
+
* @returns Whether the argument is an annotation of the given term
|
|
2348
|
+
*/
|
|
2349
|
+
function isAnnotationOfTerm(potentialAnnotation, termName) {
|
|
2350
|
+
return potentialAnnotation.term === termName;
|
|
2351
|
+
}
|
|
2352
|
+
function isAnnotationTerm(potentialAnnotation) {
|
|
2353
|
+
return potentialAnnotation.hasOwnProperty("term");
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
/**
|
|
2357
|
+
* Checks whether the argument is a {@link ServiceObject}.
|
|
2358
|
+
*
|
|
2359
|
+
* @param serviceObject The object to be checked.
|
|
2360
|
+
* @returns Whether the argument is a {@link ServiceObject}.
|
|
2361
|
+
*/
|
|
2362
|
+
function isServiceObject(serviceObject) {
|
|
2363
|
+
return serviceObject?.hasOwnProperty("_type") ?? false;
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
/**
|
|
2367
|
+
* Checks whether the argument is a {@link ComplexType}.
|
|
2368
|
+
*
|
|
2369
|
+
* @param serviceObject The object to be checked.
|
|
2370
|
+
* @returns Whether the argument is a {@link ComplexType}.
|
|
2371
|
+
*/
|
|
2372
|
+
function isComplexType(serviceObject) {
|
|
2373
|
+
return serviceObject._type === "ComplexType";
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
/**
|
|
2377
|
+
* Checks whether the argument is a {@link TypeDefinition}.
|
|
2378
|
+
*
|
|
2379
|
+
* @param serviceObject The object to be checked.
|
|
2380
|
+
* @returns Whether the argument is a {@link TypeDefinition}.
|
|
2381
|
+
*/
|
|
2382
|
+
function isTypeDefinition(serviceObject) {
|
|
2383
|
+
return serviceObject._type === "TypeDefinition";
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
/**
|
|
2387
|
+
* Checks whether the argument is an {@link EntityContainer}.
|
|
2388
|
+
*
|
|
2389
|
+
* @param serviceObject The object to be checked.
|
|
2390
|
+
* @returns Whether the argument is an {@link EntityContainer}.
|
|
2391
|
+
*/
|
|
2392
|
+
function isEntityContainer(serviceObject) {
|
|
2393
|
+
return serviceObject._type === "EntityContainer";
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
/**
|
|
2397
|
+
* Checks whether the argument is an {@link EntitySet}.
|
|
2398
|
+
*
|
|
2399
|
+
* @param serviceObject The object to be checked.
|
|
2400
|
+
* @returns Whether the argument is an {@link EntitySet}.
|
|
2401
|
+
*/
|
|
2402
|
+
function isEntitySet(serviceObject) {
|
|
2403
|
+
return serviceObject._type === "EntitySet";
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2406
|
+
/**
|
|
2407
|
+
* Checks whether the argument is a {@link Singleton}.
|
|
2408
|
+
*
|
|
2409
|
+
* @param serviceObject The object to be checked.
|
|
2410
|
+
* @returns Whether the argument is a {@link Singleton}
|
|
2411
|
+
*/
|
|
2412
|
+
function isSingleton(serviceObject) {
|
|
2413
|
+
return serviceObject._type === "Singleton";
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2416
|
+
/**
|
|
2417
|
+
* Checks whether the argument is an {@link EntityType}.
|
|
2418
|
+
*
|
|
2419
|
+
* @param serviceObject The object to be checked.
|
|
2420
|
+
* @returns Whether the argument is an {@link EntityType}
|
|
2421
|
+
*/
|
|
2422
|
+
function isEntityType(serviceObject) {
|
|
2423
|
+
return serviceObject._type === "EntityType";
|
|
2424
|
+
}
|
|
2425
|
+
|
|
2426
|
+
/**
|
|
2427
|
+
* Checks whether the argument is a {@link Property}.
|
|
2428
|
+
*
|
|
2429
|
+
* @param serviceObject The object to be checked.
|
|
2430
|
+
* @returns Whether the argument is a {@link Property}.
|
|
2431
|
+
*/
|
|
2432
|
+
function isProperty(serviceObject) {
|
|
2433
|
+
return serviceObject._type === "Property";
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
/**
|
|
2437
|
+
* Checks whether the argument is a {@link NavigationProperty}.
|
|
2438
|
+
*
|
|
2439
|
+
* Hint: There are also the more specific functions {@link isSingleNavigationProperty} and {@link isMultipleNavigationProperty}. These can be
|
|
2440
|
+
* used to check for to-one and to-many navigation properties, respectively.
|
|
2441
|
+
*
|
|
2442
|
+
* @param serviceObject The object to be checked.
|
|
2443
|
+
* @returns Whether the argument is a {@link NavigationProperty}.
|
|
2444
|
+
*/
|
|
2445
|
+
function isNavigationProperty(serviceObject) {
|
|
2446
|
+
return serviceObject._type === "NavigationProperty";
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2449
|
+
/**
|
|
2450
|
+
* Checks whether the argument is a {@link SingleNavigationProperty}.
|
|
2451
|
+
*
|
|
2452
|
+
* @param serviceObject The object to be checked.
|
|
2453
|
+
* @returns Whether the argument is a {@link SingleNavigationProperty}.
|
|
2454
|
+
*/
|
|
2455
|
+
function isSingleNavigationProperty(serviceObject) {
|
|
2456
|
+
return isNavigationProperty(serviceObject) && !serviceObject.isCollection;
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
/**
|
|
2460
|
+
* Checks whether the argument is a {@link MultipleNavigationProperty}.
|
|
2461
|
+
*
|
|
2462
|
+
* @param serviceObject The object to be checked.
|
|
2463
|
+
* @returns Whether the argument is a {@link MultipleNavigationProperty}.
|
|
2464
|
+
*/
|
|
2465
|
+
function isMultipleNavigationProperty(serviceObject) {
|
|
2466
|
+
return isNavigationProperty(serviceObject) && serviceObject.isCollection;
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
/**
|
|
2470
|
+
* Checks whether the argument is a {@link PathAnnotationExpression}.
|
|
2471
|
+
*
|
|
2472
|
+
* @param expression The object to be checked.
|
|
2473
|
+
* @returns Whether the argument is a {@link PathAnnotationExpression}.
|
|
2474
|
+
*/
|
|
2475
|
+
function isPathAnnotationExpression(expression) {
|
|
2476
|
+
return expression.type === "Path";
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
/**
|
|
2480
|
+
* Checks whether the argument is a {@link AnnotationPathExpression}.
|
|
2481
|
+
*
|
|
2482
|
+
* @param expression The object to be checked.
|
|
2483
|
+
* @returns Whether the argument is a {@link AnnotationPathExpression}.
|
|
2484
|
+
*/
|
|
2485
|
+
function isAnnotationPath(expression) {
|
|
2486
|
+
return expression.type == "AnnotationPath";
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
/**
|
|
2490
|
+
* Checks whether the argument is a {@link PropertyPath}.
|
|
2491
|
+
*
|
|
2492
|
+
* @param expression The object to be checked.
|
|
2493
|
+
* @returns Whether the argument is a {@link PropertyPath}.
|
|
2494
|
+
*/
|
|
2495
|
+
function isPropertyPathExpression(expression) {
|
|
2496
|
+
return expression.type === "PropertyPath";
|
|
2497
|
+
}
|
|
2498
|
+
/**
|
|
2499
|
+
* Checks whether the argument is a {@link PropertyPath}.
|
|
2500
|
+
*
|
|
2501
|
+
* @param expression The object to be checked.
|
|
2502
|
+
* @returns Whether the argument is a {@link PropertyPath}.
|
|
2503
|
+
*/
|
|
2504
|
+
function isValidPropertyPathExpression(expression) {
|
|
2505
|
+
return expression.type === "PropertyPath" && !!expression.$target;
|
|
2506
|
+
}
|
|
2507
|
+
|
|
2508
|
+
|
|
2509
|
+
/***/ })
|
|
2510
|
+
|
|
2511
|
+
/******/ });
|
|
2512
|
+
/************************************************************************/
|
|
2513
|
+
/******/ // The module cache
|
|
2514
|
+
/******/ var __webpack_module_cache__ = {};
|
|
2515
|
+
/******/
|
|
2516
|
+
/******/ // The require function
|
|
2517
|
+
/******/ function __webpack_require__(moduleId) {
|
|
2518
|
+
/******/ // Check if module is in cache
|
|
2519
|
+
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
2520
|
+
/******/ if (cachedModule !== undefined) {
|
|
2521
|
+
/******/ return cachedModule.exports;
|
|
2522
|
+
/******/ }
|
|
2523
|
+
/******/ // Create a new module (and put it into the cache)
|
|
2524
|
+
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
2525
|
+
/******/ // no module.id needed
|
|
2526
|
+
/******/ // no module.loaded needed
|
|
2527
|
+
/******/ exports: {}
|
|
2528
|
+
/******/ };
|
|
2529
|
+
/******/
|
|
2530
|
+
/******/ // Execute the module function
|
|
2531
|
+
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
2532
|
+
/******/
|
|
2533
|
+
/******/ // Return the exports of the module
|
|
2534
|
+
/******/ return module.exports;
|
|
2535
|
+
/******/ }
|
|
2536
|
+
/******/
|
|
2537
|
+
/************************************************************************/
|
|
2538
|
+
/******/
|
|
2539
|
+
/******/ // startup
|
|
2540
|
+
/******/ // Load entry module and return exports
|
|
2541
|
+
/******/ // This entry module is referenced by other modules so it can't be inlined
|
|
2542
|
+
/******/ var __webpack_exports__ = __webpack_require__(829);
|
|
2543
|
+
/******/ FEDefinition = __webpack_exports__;
|
|
2544
|
+
/******/
|
|
2545
|
+
/******/ })()
|
|
2546
|
+
;
|
|
2547
|
+
|
|
2548
|
+
return FEDefinition;
|
|
2549
|
+
},true);
|
|
2550
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9GRURlZmluaXRpb24vbm9kZV9tb2R1bGVzLy5wbnBtL0BzYXAtdXgrc2FwLmZlLmRlZmluaXRpb25AMC4wLjExL25vZGVfbW9kdWxlcy9Ac2FwLXV4L3NhcC5mZS5kZWZpbml0aW9uL3NyYy9CYXNlRGVmaW5pdGlvbi50cyIsIndlYnBhY2s6Ly9GRURlZmluaXRpb24vbm9kZV9tb2R1bGVzLy5wbnBtL0BzYXAtdXgrc2FwLmZlLmRlZmluaXRpb25AMC4wLjExL25vZGVfbW9kdWxlcy9Ac2FwLXV4L3NhcC5mZS5kZWZpbml0aW9uL3NyYy9NZXRhUGF0aC50cyIsIndlYnBhY2s6Ly9GRURlZmluaXRpb24vbm9kZV9tb2R1bGVzLy5wbnBtL0BzYXAtdXgrc2FwLmZlLmRlZmluaXRpb25AMC4wLjExL25vZGVfbW9kdWxlcy9Ac2FwLXV4L3NhcC5mZS5kZWZpbml0aW9uL3NyYy9lbGVtZW50cy9GaWx0ZXJCYXIudHMiLCJ3ZWJwYWNrOi8vRkVEZWZpbml0aW9uL25vZGVfbW9kdWxlcy8ucG5wbS9Ac2FwLXV4K3NhcC5mZS5kZWZpbml0aW9uQDAuMC4xMS9ub2RlX21vZHVsZXMvQHNhcC11eC9zYXAuZmUuZGVmaW5pdGlvbi9zcmMvZmxvb3JwbGFucy9EZWZpbml0aW9uUGFnZS50cyIsIndlYnBhY2s6Ly9GRURlZmluaXRpb24vbm9kZV9tb2R1bGVzLy5wbnBtL0BzYXAtdXgrc2FwLmZlLmRlZmluaXRpb25AMC4wLjExL25vZGVfbW9kdWxlcy9Ac2FwLXV4L3NhcC5mZS5kZWZpbml0aW9uL3NyYy9pbmRleC50cyIsIndlYnBhY2s6Ly9GRURlZmluaXRpb24vbm9kZV9tb2R1bGVzLy5wbnBtL0BzYXAtdXgrc2FwLmZlLmRlZmluaXRpb25AMC4wLjExL25vZGVfbW9kdWxlcy9Ac2FwLXV4L3NhcC5mZS5kZWZpbml0aW9uL3NyYy9vZGF0YS9EZWZpbml0aW9uQ29udGV4dC50cyIsIndlYnBhY2s6Ly9GRURlZmluaXRpb24vbm9kZV9tb2R1bGVzLy5wbnBtL0BzYXAtdXgrc2FwLmZlLmRlZmluaXRpb25AMC4wLjExL25vZGVfbW9kdWxlcy9Ac2FwLXV4L3NhcC5mZS5kZWZpbml0aW9uL3NyYy9vZGF0YS9FbnRpdHlTZXQudHMiLCJ3ZWJwYWNrOi8vRkVEZWZpbml0aW9uL25vZGVfbW9kdWxlcy8ucG5wbS9Ac2FwLXV4K3NhcC5mZS5kZWZpbml0aW9uQDAuMC4xMS9ub2RlX21vZHVsZXMvQHNhcC11eC9zYXAuZmUuZGVmaW5pdGlvbi9zcmMvb2RhdGEvYW5ub3RhdGlvbnMvVUkvX0RhdGFGaWVsZC50cyIsIndlYnBhY2s6Ly9GRURlZmluaXRpb24vbm9kZV9tb2R1bGVzLy5wbnBtL0BzYXAtdXgrc2FwLmZlLmRlZmluaXRpb25AMC4wLjExL25vZGVfbW9kdWxlcy9Ac2FwLXV4L3NhcC5mZS5kZWZpbml0aW9uL3NyYy9vZGF0YS9hbm5vdGF0aW9ucy9VSS9fSWRlbnRpZmljYXRpb24udHMiLCJ3ZWJwYWNrOi8vRkVEZWZpbml0aW9uL25vZGVfbW9kdWxlcy8ucG5wbS9Ac2FwLXV4K3NhcC5mZS5kZWZpbml0aW9uQDAuMC4xMS9ub2RlX21vZHVsZXMvQHNhcC11eC9zYXAuZmUuZGVmaW5pdGlvbi9zcmMvb2RhdGEvYW5ub3RhdGlvbnMvVUkvX0xpbmVJdGVtLnRzIiwid2VicGFjazovL0ZFRGVmaW5pdGlvbi9ub2RlX21vZHVsZXMvLnBucG0vQHNhcC11eCtzYXAuZmUuZGVmaW5pdGlvbkAwLjAuMTEvbm9kZV9tb2R1bGVzL0BzYXAtdXgvc2FwLmZlLmRlZmluaXRpb24vc3JjL3V0aWxzL0V4cHJlc3Npb24udHMiLCJ3ZWJwYWNrOi8vRkVEZWZpbml0aW9uL25vZGVfbW9kdWxlcy8ucG5wbS9Ac2FwLXV4K3NhcC5mZS5kZWZpbml0aW9uQDAuMC4xMS9ub2RlX21vZHVsZXMvQHNhcC11eC9zYXAuZmUuZGVmaW5pdGlvbi9zcmMvdXRpbHMvVHlwZUd1YXJkcy50cyIsIndlYnBhY2s6Ly9GRURlZmluaXRpb24vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vRkVEZWZpbml0aW9uL3dlYnBhY2svc3RhcnR1cCJdLCJuYW1lcyI6WyJQbGFjZW1lbnQiLCJleHBvcnRzIiwiQmFzZURlZmluaXRpb24iLCJjb25zdHJ1Y3RvciIsIm1ldGFQYXRoIiwiY29uZmlndXJhdGlvbiIsImFubm90YXRpb25QYXRoIiwiZ2V0UGF0aCIsImNvbmZpZ3VyYWJsZVByb3BlcnRpZXNLZXkiLCJfX2NvbmZpZ3VyYWJsZVByb3BlcnRpZXMiLCJjb25maWdTZXR0aW5ncyIsImNvbmZpZ3VyYXRpb25WYWx1ZSIsImFsaWFzRm9yIiwidW5kZWZpbmVkIiwidmFsaWRhdG9yIiwiZGVmYXVsdFZhbHVlIiwidGFyZ2V0T2JqZWN0IiwiZ2V0VGFyZ2V0IiwiYW5ub3RhdGlvblByb3BlcnRpZXNLZXkiLCJfX2Fubm90YXRpb25Qcm9wZXJ0aWVzIiwiYW5ub3RhdGlvbnMiLCJfYW5ub3RhdGlvbnMiLCJ0ZXJtIiwidmFsdWVPZiIsImdldENvbmZpZ3VyYXRpb24iLCJvdXRPYmoiLCJub29wIiwidmFsdWUiLCJjb25maWd1cmFibGUiLCJwcm9wZXJ0eUNvbmZpZ3VyYXRpb24iLCJ0YXJnZXQiLCJwcm9wZXJ0eUtleSIsInByb3BlcnR5RGVzY3JpcHRvciIsImxvY2FsUHJvcGVydHlDb25maWd1cmF0aW9uIiwibmFtZSIsImluaXRpYWxpemVyIiwidGFyZ2V0UHJvdG90eXBlIiwicHJvdG90eXBlIiwiYW5ub3RhdGlvbiIsImFubm90YXRpb25Db25maWd1cmF0aW9uIiwibG9jYWxBbm5vdGF0aW9uQ29uZmlndXJhdGlvbiIsIl9UeXBlR3VhcmRzIiwicmVxdWlyZSIsImVuaGFuY2VQYXRoIiwic0Jhc2VQYXRoIiwic1BhdGhBZGRpdGlvbiIsInN0YXJ0c1dpdGgiLCJlbmRzV2l0aCIsIk1ldGFQYXRoIiwiY29udmVydGVkTWV0YWRhdGEiLCJjb250ZXh0UGF0aCIsIm5hdmlnYXRpb25Qcm9wZXJ0aWVzIiwiY29udGV4dE5hdmlnYXRpb25Qcm9wZXJ0aWVzIiwiYWJzb2x1dGVQYXRoIiwicmVsYXRpdmVQYXRoIiwicmVwbGFjZSIsInN1YnN0cmluZyIsInJlc29sdmVkTWV0YVBhdGgiLCJyZXNvbHZlUGF0aCIsInJlc29sdmVkQ29udGV4dFBhdGgiLCJFcnJvciIsInJvb3RFbnRpdHlTZXQiLCJjdXJyZW50RW50aXR5U2V0IiwiY3VycmVudEVudGl0eVR5cGUiLCJuYXZpZ2F0ZWRQYXRocyIsIm9iamVjdFBhdGgiLCJmb3JFYWNoIiwib2JqZWN0UGFydCIsImlzU2VydmljZU9iamVjdCIsIl90eXBlIiwicHVzaCIsInRhcmdldFR5cGUiLCJuYXZpZ2F0aW9uUHJvcGVydHlCaW5kaW5nIiwiaGFzT3duUHJvcGVydHkiLCJqb2luIiwiZW50aXR5VHlwZSIsImdldFJlc29sdmVkQ29udGV4dFBhdGgiLCJzZXJ2aWNlT2JqZWN0UGF0aCIsImxlbmd0aCIsIm1hcCIsIm5hdiIsImNvbnRleHRSb290RW50aXR5U2V0IiwiZ2V0Q29udGV4dFBhdGgiLCJzUGF0aFBhcnQiLCJnZXRSZWxhdGl2ZVBhdGgiLCJnZXRDbG9zZXN0RW50aXR5U2V0IiwiY2xvc2VzdEVudGl0eVNldCIsIm5hdmlnYXRpb25Qcm9wZXJ0eSIsIm5hdmlnYXRpb25Qcm9wZXJ0eUJpbmRpbmdFbGVtZW50IiwiZ2V0Q2xvc2VzdEVudGl0eVR5cGUiLCJjbG9zZXN0RW50aXR5VHlwZSIsImdldENvbnRleHRDbG9zZXN0RW50aXR5U2V0Iiwibm9uTnVsbEVudGl0eVNldCIsImdldE5hdmlnYXRpb25Qcm9wZXJ0aWVzIiwiZ2V0TWV0YVBhdGhGb3JQYXRoIiwidGFyZ2V0UGF0aCIsIl9lcnJvciIsImdldE1ldGFQYXRoRm9yT2JqZWN0IiwiaXNBbm5vdGF0aW9uUGF0aCIsImlzUGF0aEFubm90YXRpb25FeHByZXNzaW9uIiwicGF0aCIsIm1ldGFQYXRoQXBwIiwiZnVsbHlRdWFsaWZpZWROYW1lIiwiZ2V0Q29udmVydGVkTWV0YWRhdGEiLCJfQmFzZURlZmluaXRpb24iLCJfRW50aXR5U2V0MiIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfZGVjIiwiX2RlYzIiLCJfZGVjMyIsIl9jbGFzcyIsIl9kZXNjcmlwdG9yIiwiX2Rlc2NyaXB0b3IyIiwiX2Rlc2NyaXB0b3IzIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiX2luaXRpYWxpemVyRGVmaW5lUHJvcGVydHkiLCJpIiwiciIsImwiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImVudW1lcmFibGUiLCJ3cml0YWJsZSIsImNhbGwiLCJfZGVmaW5lUHJvcGVydHkiLCJ0IiwiX3RvUHJvcGVydHlLZXkiLCJfdG9QcmltaXRpdmUiLCJTeW1ib2wiLCJ0b1ByaW1pdGl2ZSIsIlR5cGVFcnJvciIsIlN0cmluZyIsIk51bWJlciIsIl9hcHBseURlY29yYXRlZERlc2NyaXB0b3IiLCJuIiwiYSIsImtleXMiLCJzbGljZSIsInJldmVyc2UiLCJyZWR1Y2UiLCJfaW5pdGlhbGl6ZXJXYXJuaW5nSGVscGVyIiwiRmlsdGVyRmllbGQiLCJsYWJlbCIsImZpbHRlckZpZWxkUHJvcGVydHkiLCJDb21tb24iLCJMYWJlbCIsInRvU3RyaW5nIiwiZmlsdGVyRmllbGRDb25maWd1cmF0aW9uIiwiRmlsdGVyQmFyIiwic2VsZWN0aW9uRmllbGRzIiwiZmlsdGVyQmFyQ29uZmlndXJhdGlvbiIsImdldEZpbHRlckdyb3VwcyIsImZpbHRlckZhY2V0cyIsIlVJIiwiRmlsdGVyRmFjZXRzIiwiZmlsdGVyRmllbGRzR3JvdXAiLCJmaWVsZEdyb3VwcyIsImZpbHRlciIsImtleSIsImZpZWxkR3JvdXAiLCJEYXRhIiwiZmllbGRHcm91cEVudHJ5IiwiJFR5cGUiLCJmaWVsZEdyb3VwVmFsdWUiLCJWYWx1ZSIsIiR0YXJnZXQiLCJncm91cCIsImdyb3VwTGFiZWwiLCJxdWFsaWZpZXIiLCJmaWx0ZXJGYWNldCIsImZpbHRlckZhY2V0VGFyZ2V0IiwiVGFyZ2V0IiwiaXNBbm5vdGF0aW9uT2ZUeXBlIiwiSUQiLCJnZXRGaWx0ZXJGaWVsZHMiLCJmaWx0ZXJHcm91cHMiLCJjb25zaWRlcmVkUHJvcGVydGllcyIsImZyb21TZWxlY3Rpb25GaWVsZCIsImlzVmFsaWRQcm9wZXJ0eVBhdGhFeHByZXNzaW9uIiwiZmllbGQiLCJtZXRhUGF0aEZvclByb3BlcnR5IiwidmlzaWJsZSIsIm5vbkZpbHRlcmFibGVQcm9wZXJ0aWVzIiwiX0VudGl0eVNldCIsImdldE5vbkZpbHRlcmFibGVQcm9wZXJ0aWVzIiwiZW50aXR5UHJvcGVydGllcyIsInByb3BlcnR5IiwiaW5jbHVkZXMiLCJIaWRkZW4iLCJpc1NlYXJjaFN1cHBvcnRlZCIsImlzU2VhcmNoQWxsb3dlZCIsIl9GaWx0ZXJCYXIiLCJfSWRlbnRpZmljYXRpb24yIiwiX0xpbmVJdGVtMiIsIkRlZmluaXRpb25QYWdlIiwiU2V0IiwiZ2V0TWV0YVBhdGgiLCJnZXRJZGVudGlmaWNhdGlvbiIsInRhcmdldEVudGl0eVR5cGUiLCJpZEFubm90YXRpb24iLCJJZGVudGlmaWNhdGlvbiIsIl9JZGVudGlmaWNhdGlvbiIsImdldFRhYmxlVmlzdWFsaXphdGlvbiIsIl9MaW5lSXRlbSIsImZyb21TUFYiLCJfZ2V0VGFibGVWaXN1YWxpemF0aW9uQW5ub3RhdGlvbiIsImdldEZpbHRlckJhckRlZmluaXRpb24iLCJzZWxlY3Rpb25GaWVsZCIsIlNlbGVjdGlvbkZpZWxkcyIsImFzc2lnbiIsImNyZWF0ZURlZmF1bHRUYWJsZVZpc3VhbGl6YXRpb24iLCJjcmVhdGVEZWZhdWx0Iiwic3B2IiwiU2VsZWN0aW9uUHJlc2VudGF0aW9uVmFyaWFudCIsIlByZXNlbnRhdGlvblZhcmlhbnQiLCJWaXN1YWxpemF0aW9ucyIsImZpbmQiLCJ2IiwicHYiLCJMaW5lSXRlbSIsImFkZERhdGFUb1JlcXVlc3QiLCJwcm9wZXJ0eVBhdGgiLCJyZXF1ZXN0U2V0IiwiYWRkIiwiZ2V0UXVlcnlDb21wb25lbnRzIiwic2VsZWN0IiwiZXhwYW5kIiwicGFydHMiLCJzcGxpdCIsInF1ZXJ5IiwiJGZvcm1hdCIsIiRzZWxlY3QiLCIkZXhwYW5kIiwiX0RlZmluaXRpb25QYWdlIiwiX0RhdGFGaWVsZCIsIl9EZWZpbml0aW9uQ29udGV4dCIsIl9leHBvcnROYW1lcyIsImdldCIsIl9NZXRhUGF0aCIsIkRlZmluaXRpb25Db250ZXh0IiwiYWRkQXBwbGljYXRpb25NYW5pZmVzdCIsIm1hbmlmZXN0IiwiZ2V0RW50aXR5U2V0cyIsImVudGl0eVNldHMiLCJnZXRFbnRpdHlTZXQiLCJlbnRpdHlTZXROYW1lIiwiYnlfbmFtZSIsImdldFJvb3RFbnRpdHlTZXQiLCJpbml0aWFsUm91dGVQYXR0ZXJuIiwiaW5pdGlhbFJvdXRlIiwicm91dGluZyIsInJvdXRlcyIsInBhdHRlcm4iLCJ0YXJnZXRzIiwib3B0aW9ucyIsInNldHRpbmdzIiwiZW50aXR5U2V0IiwiZ2V0UGFnZUZvciIsImVudGl0eVNldENvbmZpZ3VyYXRpb24iLCJnZXRSZXF1aXJlZFByb3BlcnRpZXMiLCJyZXF1aXJlZFByb3BlcnRpZXMiLCJDYXBhYmlsaXRpZXMiLCJGaWx0ZXJSZXN0cmljdGlvbnMiLCJSZXF1aXJlZFByb3BlcnRpZXMiLCJOb25GaWx0ZXJhYmxlUHJvcGVydGllcyIsImdldEFsbG93ZWRGaWx0ZXJFeHByZXNzaW9uIiwiZmlsdGVyRXhwcmVzc2lvblJlc3RyaWN0aW9ucyIsIkZpbHRlckV4cHJlc3Npb25SZXN0cmljdGlvbnMiLCJwcm9wZXJ0eVJlc3RyaWN0aW9ucyIsImZpbHRlckV4cHJlc3Npb25SZXN0cmljdGlvbiIsIlByb3BlcnR5IiwicHJvcGVydHlSZXN0cmljdGlvbiIsIkFsbG93ZWRFeHByZXNzaW9ucyIsIlNlYXJjaFJlc3RyaWN0aW9ucyIsIlNlYXJjaGFibGUiLCJfRXhwcmVzc2lvbiIsImRhdGFGaWVsZCIsInBhZ2VNZXRhUGF0aCIsImdldFZhbHVlIiwiZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uIiwiZ2V0Rm9ybWF0dGVkVmFsdWUiLCJ0YXJnZXRWYWx1ZSIsInRyYW5zZm9ybVJlY3Vyc2l2ZWx5IiwicHJvcGVydHlNZXRhUGF0aCIsInVucmVzb2x2YWJsZUV4cHJlc3Npb24iLCJtZWFzdXJlIiwiZ2V0TWVhc3VyZSIsImNvbmNhdCIsImRpc3BsYXlNb2RlIiwiZ2V0RGlzcGxheU1vZGUiLCJ0ZXh0IiwiVGV4dCIsImlmRWxzZSIsIm5vdEVxdWFsIiwibWVhc3VyZXMiLCJNZWFzdXJlcyIsIlVuaXQiLCJJU09DdXJyZW5jeSIsInRleHRBbm5vdGF0aW9uIiwidGV4dEFycmFuZ2VtZW50IiwiVGV4dEFycmFuZ2VtZW50IiwiZ2V0TGFiZWwiLCJ2YWx1ZVRhcmdldCIsImdldFByb3BlcnR5IiwiZ2V0RnVsbHlRdWFsaWZpZWROYW1lIiwiX0RhdGFGaWVsZDIiLCJpZCIsImdldERhdGFGaWVsZHMiLCJpdGVtIiwicmVzdHJpY3RUeXBlcyIsImltcG9ydGFuY2UiLCJJbXBvcnRhbmNlIiwibGluZUl0ZW0iLCJmYWtlTGluZUl0ZW1Bbm5vdGF0aW9uIiwicHJvcCIsIkRhdGFGaWVsZERlZmF1bHQiLCJ0eXBlIiwiZ2V0QWN0aW9ucyIsImdldEhlYWRlckFjdGlvbnMiLCJhY3Rpb24iLCJEZXRlcm1pbmluZyIsImhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24iLCJleHByZXNzaW9ucyIsImV4cHIiLCJfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsIiwiYiIsIm9wZXJhbmQiLCJvcGVyYXRvciIsIm9wZXJhbmRzIiwiZXZlcnkiLCJleHByZXNzaW9uIiwic29tZSIsIm90aGVyRXhwcmVzc2lvbiIsImNvbmRpdGlvbiIsIm9uVHJ1ZSIsIm9uRmFsc2UiLCJvcGVyYW5kMSIsIm9wZXJhbmQyIiwiYUV4cHJlc3Npb25zIiwiYkV4cHJlc3Npb25zIiwiaW5kZXgiLCJwYXRoSW5Nb2RlbCIsIm1vZGVsTmFtZSIsInRhcmdldEVudGl0eVNldCIsImZuIiwicGFyYW1ldGVycyIsImJpbmRpbmdQYXJhbWV0ZXJzIiwib3RoZXJGdW5jdGlvbiIsIm9iaiIsInJlZiIsImZsYXR0ZW5TZXRFeHByZXNzaW9uIiwicmVzdWx0IiwiY2FuZGlkYXRlc0ZvckZsYXR0ZW5pbmciLCJjYW5kaWRhdGUiLCJoYXNPcHBvc2l0ZUV4cHJlc3Npb25zIiwibmVnYXRlZEV4cHJlc3Npb25zIiwibm90IiwiYW5kIiwid3JhcFByaW1pdGl2ZSIsImlzU3RhdGljRmFsc2UiLCJub25Ucml2aWFsRXhwcmVzc2lvbiIsImlzRmFsc2UiLCJpc0NvbnN0YW50IiwiY29uc3RhbnQiLCJpc1ZhbGlkIiwiaXNUcnVlIiwib3IiLCJpc1N0YXRpY1RydWUiLCJpc0NvbXBhcmlzb24iLCJpc1RydXRoeSIsInZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMiLCJwYXRoVmlzaXRvciIsImxvY2FsUGF0aCIsImNvbnN0YW50VmFsdWUiLCJBcnJheSIsImlzQXJyYXkiLCJpc1ByaW1pdGl2ZU9iamVjdCIsImVudHJpZXMiLCJwbGFpbkV4cHJlc3Npb24iLCJ2YWwiLCJ3cmFwcGVkVmFsdWUiLCJyZXNvbHZlQmluZGluZ1N0cmluZyIsInBhdGhJbk1vZGVsUmVnZXgiLCJwYXRoSW5Nb2RlbFJlZ2V4TWF0Y2giLCJleGVjIiwiaXNOYU4iLCJyZWZlcmVuY2UiLCJzb21ldGhpbmciLCJpc0V4cHJlc3Npb24iLCJtYXliZUNvbnN0YW50IiwiaXNQYXRoSW5Nb2RlbEV4cHJlc3Npb24iLCJtYXliZUJpbmRpbmciLCJpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbiIsImlzQ29uY2F0RXhwcmVzc2lvbiIsImlzSWZFbHNlRXhwcmVzc2lvbiIsImlzVW5kZWZpbmVkRXhwcmVzc2lvbiIsImV4cHJlc3Npb25Bc0V4cHJlc3Npb24iLCJvYmplY3RUeXBlIiwiaXNDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb24iLCJhbm5vdGF0aW9uVmFsdWUiLCJhbm5vdGF0aW9uSWZFeHByZXNzaW9uIiwiJElmIiwicGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uIiwiJE5vdCIsImVxdWFsIiwiJEVxIiwiJE5lIiwiZ3JlYXRlclRoYW4iLCIkR3QiLCJncmVhdGVyT3JFcXVhbCIsIiRHZSIsImxlc3NUaGFuIiwiJEx0IiwibGVzc09yRXF1YWwiLCIkTGUiLCIkT3IiLCJvckNvbmRpdGlvbiIsIiRBbmQiLCJhbmRDb25kaXRpb24iLCJhbm5vdGF0aW9uQXBwbHlFeHByZXNzaW9uIiwiJFBhdGgiLCJQYXRoIiwiJEZ1bmN0aW9uIiwiJEFwcGx5IiwiJEVudW1NZW1iZXIiLCJCb29sIiwiSW50IiwiRGVjaW1hbCIsImNvbnZlcnRTdWJBcHBseVBhcmFtZXRlcnMiLCJhcHBseVBhcmFtIiwiYXBwbHlQYXJhbUNvbnZlcnRlZCIsImFwcGx5RXhwcmVzc2lvbiIsInBhcmFtZXRlciIsInRlbXBsYXRlIiwidGVtcGxhdGVQYXJhbXMiLCIkTmFtZSIsIiRMYWJlbGVkRWxlbWVudCIsImNvbXBhcmlzb24iLCJsZWZ0T3BlcmFuZCIsInJpZ2h0T3BlcmFuZCIsImxlZnRFeHByZXNzaW9uIiwicmlnaHRFeHByZXNzaW9uIiwiY2hlY2tVbmRlZmluZWQiLCJsZWZ0IiwicmlnaHQiLCJyZWR1Y2VkIiwiY29uZGl0aW9uRXhwcmVzc2lvbiIsIm9uVHJ1ZUV4cHJlc3Npb24iLCJvbkZhbHNlRXhwcmVzc2lvbiIsInBhdGhJZHgiLCJteUlmRWxzZUV4cHJlc3Npb24iLCJmb3JtYXRSZXN1bHQiLCJhbGxQYXJ0cyIsImNvbnN0YW50UGF0aCIsInVuc2hpZnQiLCJKU09OIiwic3RyaW5naWZ5IiwiaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dCIsImZvcm1hdHRlckZ1bmN0aW9uIiwiY29udGV4dEVudGl0eVR5cGUiLCJpZ25vcmVDb21wbGV4VHlwZSIsInBhcmFtZXRlckV4cHJlc3Npb25zIiwiZnVuY3Rpb25OYW1lIiwiX19mdW5jdGlvbk5hbWUiLCJmb3JtYXR0ZXJDbGFzcyIsImZvcm1hdHRlck5hbWUiLCJteUZvcm1hdEV4cHJlc3Npb24iLCJnZXRGaXNjYWxUeXBlIiwiSXNGaXNjYWxZZWFyIiwiSXNGaXNjYWxQZXJpb2QiLCJJc0Zpc2NhbFllYXJQZXJpb2QiLCJJc0Zpc2NhbFF1YXJ0ZXIiLCJJc0Zpc2NhbFllYXJRdWFydGVyIiwiSXNGaXNjYWxXZWVrIiwiSXNGaXNjYWxZZWFyV2VlayIsIklzRGF5T2ZGaXNjYWxZZWFyIiwiZnVuYyIsIm9uIiwiaXNGb3JtYXR0aW5nRm4iLCJpc0VtcHR5IiwiYUJpbmRpbmdzIiwiaW5FeHByZXNzaW9ucyIsImNvbmNhdGVuYXRlZCIsIm15Q29uY2F0RXhwcmVzc2lvbiIsImluRXhwcmVzc2lvbiIsImV4cHJlc3Npb25UeXBlIiwidHJhbnNmb3JtRnVuY3Rpb24iLCJpbmNsdWRlQWxsRXhwcmVzc2lvbiIsInN1YkV4cHJlc3Npb24iLCJiaW5kaW5nUGFyYW1ldGVyIiwicG90ZW50aWFsQW5ub3RhdGlvblR5cGUiLCJ0eXBlTmFtZSIsImlzQW5ub3RhdGlvbk9mVGVybSIsInBvdGVudGlhbEFubm90YXRpb24iLCJ0ZXJtTmFtZSIsImlzQW5ub3RhdGlvblRlcm0iLCJzZXJ2aWNlT2JqZWN0IiwiaXNDb21wbGV4VHlwZSIsImlzVHlwZURlZmluaXRpb24iLCJpc0VudGl0eUNvbnRhaW5lciIsImlzRW50aXR5U2V0IiwiaXNTaW5nbGV0b24iLCJpc0VudGl0eVR5cGUiLCJpc1Byb3BlcnR5IiwiaXNOYXZpZ2F0aW9uUHJvcGVydHkiLCJpc1NpbmdsZU5hdmlnYXRpb25Qcm9wZXJ0eSIsImlzQ29sbGVjdGlvbiIsImlzTXVsdGlwbGVOYXZpZ2F0aW9uUHJvcGVydHkiLCJpc1Byb3BlcnR5UGF0aEV4cHJlc3Npb24iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQXlCWUEsU0FBUyxHQUFBQyxpQkFBQSwwQkFBVEQsU0FBUztFQUFUQSxTQUFTO0VBQVRBLFNBQVM7RUFBVEEsU0FBUztFQUFBLE9BQVRBLFNBQVM7QUFBQTtBQU1kLE1BQU1FLGNBQWMsQ0FBOEI7RUFPeERDLFdBQVdBLENBQUNDLFFBQTJFLEVBQUVDLGFBQWdCLEVBQUU7SUFDMUcsSUFBSSxDQUFDQyxjQUFjLEdBQUdGLFFBQVEsRUFBRUcsT0FBTyxDQUFDLENBQUM7SUFDekMsS0FBSyxNQUFNQyx5QkFBeUIsSUFBSSxJQUFJLENBQUNDLHdCQUF3QixFQUFFO01BQ3RFLE1BQU1DLGNBQWMsR0FBRyxJ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QTtVQUNBOztVQUVBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBOztVQUVBO1VBQ0E7O1VBRUE7VUFDQTtVQUNBOzs7O1VDdEJBO1VBQ0E7VUFDQTtVQUNBIiwiZmlsZSI6IkZFRGVmaW5pdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFNlcnZpY2VPYmplY3QgfSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXNcIjtcbmltcG9ydCB0eXBlIHsgQW5ub3RhdGlvblRlcm0gfSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXMvRWRtXCI7XG5pbXBvcnQgdHlwZSBNZXRhUGF0aCBmcm9tIFwiLi9NZXRhUGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBQcmltaXRpdmVUeXBlIH0gZnJvbSBcIi4vdXRpbHMvRXhwcmVzc2lvblwiO1xuXG5leHBvcnQgdHlwZSBCYXNlQ29uZmlndXJhdGlvbiA9IFJlY29yZDxzdHJpbmcsIFByaW1pdGl2ZVR5cGU+O1xudHlwZSBJblByb3BlcnR5Q29uZmlndXJhdGlvbiA9IHtcblx0YWxpYXNGb3I/OiBzdHJpbmc7XG5cdHZhbGlkYXRvcj86IEZ1bmN0aW9uO1xufTtcbnR5cGUgUHJvcGVydHlDb25maWd1cmF0aW9uID0ge1xuXHRhbGlhc0Zvcjogc3RyaW5nO1xuXHR2YWxpZGF0b3I6IEZ1bmN0aW9uO1xuXHRuYW1lOiBzdHJpbmc7XG5cdGRlZmF1bHRWYWx1ZTogdW5rbm93bjtcbn07XG50eXBlIEluQW5ub3RhdGlvbkNvbmZpZ3VyYXRpb24gPSB7XG5cdHRlcm06IHN0cmluZztcbn07XG50eXBlIEFubm90YXRpb25Db25maWd1cmF0aW9uID0ge1xuXHRuYW1lOiBzdHJpbmc7XG5cdGRlZmF1bHRWYWx1ZTogdW5rbm93bjtcblx0dGVybTogc3RyaW5nO1xufTtcblxuZXhwb3J0IGVudW0gUGxhY2VtZW50IHtcblx0QWZ0ZXIgPSBcIkFmdGVyXCIsXG5cdEJlZm9yZSA9IFwiQmVmb3JlXCIsXG5cdEVuZCA9IFwiRW5kXCJcbn1cblxuZXhwb3J0IGNsYXNzIEJhc2VEZWZpbml0aW9uPFQgZXh0ZW5kcyBCYXNlQ29uZmlndXJhdGlvbj4ge1xuXHRwdWJsaWMgYW5ub3RhdGlvblBhdGg/OiBzdHJpbmc7XG5cblx0X19jb25maWd1cmFibGVQcm9wZXJ0aWVzITogUmVjb3JkPHN0cmluZywgUHJvcGVydHlDb25maWd1cmF0aW9uPjtcblxuXHRfX2Fubm90YXRpb25Qcm9wZXJ0aWVzITogUmVjb3JkPHN0cmluZywgQW5ub3RhdGlvbkNvbmZpZ3VyYXRpb24+O1xuXG5cdGNvbnN0cnVjdG9yKG1ldGFQYXRoOiBNZXRhUGF0aDxTZXJ2aWNlT2JqZWN0IHwgQW5ub3RhdGlvblRlcm08eyB0ZXJtOiBzdHJpbmcgfT4+IHwgbnVsbCwgY29uZmlndXJhdGlvbjogVCkge1xuXHRcdHRoaXMuYW5ub3RhdGlvblBhdGggPSBtZXRhUGF0aD8uZ2V0UGF0aCgpO1xuXHRcdGZvciAoY29uc3QgY29uZmlndXJhYmxlUHJvcGVydGllc0tleSBpbiB0aGlzLl9fY29uZmlndXJhYmxlUHJvcGVydGllcykge1xuXHRcdFx0Y29uc3QgY29uZmlnU2V0dGluZ3MgPSB0aGlzLl9fY29uZmlndXJhYmxlUHJvcGVydGllc1tjb25maWd1cmFibGVQcm9wZXJ0aWVzS2V5XTtcblx0XHRcdGlmIChjb25maWdTZXR0aW5ncykge1xuXHRcdFx0XHRjb25zdCBjb25maWd1cmF0aW9uVmFsdWUgPSBjb25maWd1cmF0aW9uW2NvbmZpZ1NldHRpbmdzLmFsaWFzRm9yXTtcblx0XHRcdFx0aWYgKGNvbmZpZ3VyYXRpb25WYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0dGhpc1tjb25maWd1cmFibGVQcm9wZXJ0aWVzS2V5IGFzIGtleW9mIHRoaXNdID0gY29uZmlnU2V0dGluZ3MudmFsaWRhdG9yKGNvbmZpZ3VyYXRpb25WYWx1ZSkgYXMgbmV2ZXI7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpc1tjb25maWd1cmFibGVQcm9wZXJ0aWVzS2V5IGFzIGtleW9mIHRoaXNdID0gY29uZmlnU2V0dGluZ3MuZGVmYXVsdFZhbHVlIGFzIG5ldmVyO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGNvbnN0IHRhcmdldE9iamVjdCA9IG1ldGFQYXRoPy5nZXRUYXJnZXQoKTtcblx0XHRpZiAodGFyZ2V0T2JqZWN0KSB7XG5cdFx0XHRmb3IgKGNvbnN0IGFubm90YXRpb25Qcm9wZXJ0aWVzS2V5IGluIHRoaXMuX19hbm5vdGF0aW9uUHJvcGVydGllcykge1xuXHRcdFx0XHRjb25zdCBjb25maWdTZXR0aW5ncyA9IHRoaXMuX19hbm5vdGF0aW9uUHJvcGVydGllc1thbm5vdGF0aW9uUHJvcGVydGllc0tleV07XG5cdFx0XHRcdGlmIChjb25maWdTZXR0aW5ncykge1xuXHRcdFx0XHRcdGNvbnN0IGNvbmZpZ3VyYXRpb25WYWx1ZSA9IChcblx0XHRcdFx0XHRcdHRhcmdldE9iamVjdC5hbm5vdGF0aW9ucyBhcyB1bmtub3duIGFzIHtcblx0XHRcdFx0XHRcdFx0X2Fubm90YXRpb25zPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0KS5fYW5ub3RhdGlvbnM/Lltjb25maWdTZXR0aW5ncy50ZXJtXTtcblx0XHRcdFx0XHRpZiAoY29uZmlndXJhdGlvblZhbHVlICE9PSB1bmRlZmluZWQgJiYgY29uZmlndXJhdGlvblZhbHVlICE9PSBudWxsKSB7XG5cdFx0XHRcdFx0XHR0aGlzW2Fubm90YXRpb25Qcm9wZXJ0aWVzS2V5IGFzIGtleW9mIHRoaXNdID0gY29uZmlndXJhdGlvblZhbHVlLnZhbHVlT2YoKSBhcyBuZXZlcjtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dGhpc1thbm5vdGF0aW9uUHJvcGVydGllc0tleSBhcyBrZXlvZiB0aGlzXSA9IGNvbmZpZ1NldHRpbmdzLmRlZmF1bHRWYWx1ZSBhcyBuZXZlcjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRnZXRDb25maWd1cmF0aW9uKCk6IFQge1xuXHRcdGNvbnN0IG91dE9iajogQmFzZUNvbmZpZ3VyYXRpb24gPSB7fTtcblx0XHRmb3IgKGNvbnN0IGNvbmZpZ3VyYWJsZVByb3BlcnRpZXNLZXkgaW4gdGhpcy5fX2NvbmZpZ3VyYWJsZVByb3BlcnRpZXMpIHtcblx0XHRcdGNvbnN0IGNvbmZpZ1NldHRpbmdzID0gdGhpcy5fX2NvbmZpZ3VyYWJsZVByb3BlcnRpZXNbY29uZmlndXJhYmxlUHJvcGVydGllc0tleV07XG5cdFx0XHRpZiAoY29uZmlnU2V0dGluZ3MpIHtcblx0XHRcdFx0b3V0T2JqW2NvbmZpZ1NldHRpbmdzLmFsaWFzRm9yXSA9IHRoaXNbY29uZmlndXJhYmxlUHJvcGVydGllc0tleSBhcyBrZXlvZiB0aGlzXSBhcyBQcmltaXRpdmVUeXBlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gb3V0T2JqIGFzIFQ7XG5cdH1cbn1cblxuZnVuY3Rpb24gbm9vcCh2YWx1ZTogUHJpbWl0aXZlVHlwZSk6IFByaW1pdGl2ZVR5cGUge1xuXHRyZXR1cm4gdmFsdWU7XG59XG5leHBvcnQgZnVuY3Rpb24gY29uZmlndXJhYmxlKHByb3BlcnR5Q29uZmlndXJhdGlvbjogSW5Qcm9wZXJ0eUNvbmZpZ3VyYXRpb24gPSB7fSk6IFByb3BlcnR5RGVjb3JhdG9yIHtcblx0cmV0dXJuIGZ1bmN0aW9uIChcblx0XHR0YXJnZXQ6IEJhc2VEZWZpbml0aW9uPEJhc2VDb25maWd1cmF0aW9uPixcblx0XHRwcm9wZXJ0eUtleTogc3RyaW5nLFxuXHRcdHByb3BlcnR5RGVzY3JpcHRvcjogVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I8UHJpbWl0aXZlVHlwZT5cblx0KSB7XG5cdFx0Y29uc3QgbG9jYWxQcm9wZXJ0eUNvbmZpZ3VyYXRpb246IFByb3BlcnR5Q29uZmlndXJhdGlvbiA9IHtcblx0XHRcdG5hbWU6IHByb3BlcnR5S2V5LFxuXHRcdFx0dmFsaWRhdG9yOiBwcm9wZXJ0eUNvbmZpZ3VyYXRpb24udmFsaWRhdG9yIHx8IG5vb3AsXG5cdFx0XHRhbGlhc0ZvcjogcHJvcGVydHlDb25maWd1cmF0aW9uLmFsaWFzRm9yIHx8IHByb3BlcnR5S2V5LFxuXHRcdFx0ZGVmYXVsdFZhbHVlOiAocHJvcGVydHlEZXNjcmlwdG9yIGFzIHsgaW5pdGlhbGl6ZXI/OiBGdW5jdGlvbiB9KS5pbml0aWFsaXplcj8uKClcblx0XHR9O1xuXHRcdGNvbnN0IHRhcmdldFByb3RvdHlwZSA9IHRhcmdldC5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgYXMgQmFzZURlZmluaXRpb248QmFzZUNvbmZpZ3VyYXRpb24+O1xuXHRcdGlmICghdGFyZ2V0UHJvdG90eXBlLl9fY29uZmlndXJhYmxlUHJvcGVydGllcykge1xuXHRcdFx0dGFyZ2V0UHJvdG90eXBlLl9fY29uZmlndXJhYmxlUHJvcGVydGllcyA9IHt9O1xuXHRcdH1cblx0XHRkZWxldGUgKHByb3BlcnR5RGVzY3JpcHRvciBhcyB7IGluaXRpYWxpemVyPzogRnVuY3Rpb24gfSB8IHVuZGVmaW5lZCk/LmluaXRpYWxpemVyO1xuXG5cdFx0dGFyZ2V0UHJvdG90eXBlLl9fY29uZmlndXJhYmxlUHJvcGVydGllc1twcm9wZXJ0eUtleV0gPSBsb2NhbFByb3BlcnR5Q29uZmlndXJhdGlvbjtcblx0fSBhcyB1bmtub3duIGFzIFByb3BlcnR5RGVjb3JhdG9yO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYW5ub3RhdGlvbihhbm5vdGF0aW9uQ29uZmlndXJhdGlvbjogSW5Bbm5vdGF0aW9uQ29uZmlndXJhdGlvbik6IFByb3BlcnR5RGVjb3JhdG9yIHtcblx0cmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQ6IEJhc2VEZWZpbml0aW9uPEJhc2VDb25maWd1cmF0aW9uPiwgcHJvcGVydHlLZXk6IHN0cmluZywgcHJvcGVydHlEZXNjcmlwdG9yOiBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjx1bmtub3duPikge1xuXHRcdGNvbnN0IGxvY2FsQW5ub3RhdGlvbkNvbmZpZ3VyYXRpb246IEFubm90YXRpb25Db25maWd1cmF0aW9uID0ge1xuXHRcdFx0bmFtZTogcHJvcGVydHlLZXksXG5cdFx0XHR0ZXJtOiBhbm5vdGF0aW9uQ29uZmlndXJhdGlvbi50ZXJtLFxuXHRcdFx0ZGVmYXVsdFZhbHVlOiAocHJvcGVydHlEZXNjcmlwdG9yIGFzIHsgaW5pdGlhbGl6ZXI/OiBGdW5jdGlvbiB9KS5pbml0aWFsaXplcj8uKClcblx0XHR9O1xuXHRcdGNvbnN0IHRhcmdldFByb3RvdHlwZSA9IHRhcmdldC5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgYXMgQmFzZURlZmluaXRpb248QmFzZUNvbmZpZ3VyYXRpb24+O1xuXHRcdGlmICghdGFyZ2V0UHJvdG90eXBlLl9fYW5ub3RhdGlvblByb3BlcnRpZXMpIHtcblx0XHRcdHRhcmdldFByb3RvdHlwZS5fX2Fubm90YXRpb25Qcm9wZXJ0aWVzID0ge307XG5cdFx0fVxuXHRcdHRhcmdldFByb3RvdHlwZS5fX2Fubm90YXRpb25Qcm9wZXJ0aWVzW3Byb3BlcnR5S2V5XSA9IGxvY2FsQW5ub3RhdGlvbkNvbmZpZ3VyYXRpb247XG5cdFx0ZGVsZXRlIChwcm9wZXJ0eURlc2NyaXB0b3IgYXMgeyBpbml0aWFsaXplcj86IEZ1bmN0aW9uIH0pLmluaXRpYWxpemVyO1xuXHRcdHJldHVybiBwcm9wZXJ0eURlc2NyaXB0b3I7XG5cdH0gYXMgdW5rbm93biBhcyBQcm9wZXJ0eURlY29yYXRvcjsgLy8gVGhpcyBpcyB0ZWNobmljYWxseSBhbiBhY2Nlc3NvciBkZWNvcmF0b3IsIGJ1dCBzb21laG93IHRoZSBjb21waWxlciBkb2Vzbid0IGxpa2UgaXQgaWYgaSBkZWNsYXJlIGl0IGFzIHN1Y2guO1xufVxuIiwiaW1wb3J0IHR5cGUge1xuXHRDb252ZXJ0ZWRNZXRhZGF0YSxcblx0RW50aXR5U2V0LFxuXHRFbnRpdHlUeXBlLFxuXHROYXZpZ2F0aW9uUHJvcGVydHksXG5cdFBhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0UmVzb2x1dGlvblRhcmdldCxcblx0U2VydmljZU9iamVjdEFuZEFubm90YXRpb24sXG5cdFNpbmdsZXRvblxufSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXNcIjtcbmltcG9ydCB0eXBlIHsgQW5ub3RhdGlvblBhdGgsIFByb3BlcnR5LCBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZSB9IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlcy9FZG1cIjtcbmltcG9ydCB7IGlzQW5ub3RhdGlvblBhdGgsIGlzUGF0aEFubm90YXRpb25FeHByZXNzaW9uLCBpc1NlcnZpY2VPYmplY3QgfSBmcm9tIFwiLi91dGlscy9UeXBlR3VhcmRzXCI7XG5cbmZ1bmN0aW9uIGVuaGFuY2VQYXRoKHNCYXNlUGF0aDogc3RyaW5nLCBzUGF0aEFkZGl0aW9uPzogc3RyaW5nKTogc3RyaW5nIHtcblx0aWYgKHNQYXRoQWRkaXRpb24pIHtcblx0XHRpZiAoc1BhdGhBZGRpdGlvbi5zdGFydHNXaXRoKFwiL1wiKSkge1xuXHRcdFx0cmV0dXJuIHNQYXRoQWRkaXRpb247XG5cdFx0fSBlbHNlIGlmIChzUGF0aEFkZGl0aW9uLnN0YXJ0c1dpdGgoXCJAXCIpKSB7XG5cdFx0XHRyZXR1cm4gc0Jhc2VQYXRoICsgc1BhdGhBZGRpdGlvbjtcblx0XHR9IGVsc2UgaWYgKCFzQmFzZVBhdGguZW5kc1dpdGgoXCIvXCIpKSB7XG5cdFx0XHRyZXR1cm4gc0Jhc2VQYXRoICsgXCIvXCIgKyBzUGF0aEFkZGl0aW9uO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gc0Jhc2VQYXRoICsgc1BhdGhBZGRpdGlvbjtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHNCYXNlUGF0aDtcbn1cblxudHlwZSBSZXNvbHZlZFRhcmdldDxUPiA9XG5cdFQgZXh0ZW5kcyBBbm5vdGF0aW9uUGF0aDxpbmZlciBLPlxuXHRcdD8gS1xuXHRcdDogVCBleHRlbmRzIFByb3BlcnR5QW5ub3RhdGlvblZhbHVlPGluZmVyIFYgZXh0ZW5kcyBzdHJpbmc+XG5cdFx0XHQ/IFZcblx0XHRcdDogVCBleHRlbmRzIFBhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbjx1bmtub3duPlxuXHRcdFx0XHQ/IFByb3BlcnR5IHwgdW5kZWZpbmVkXG5cdFx0XHRcdDogVDtcblxuLyoqXG4gKlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXRhUGF0aDxUPiB7XG5cdHByaXZhdGUgcm9vdEVudGl0eVNldDogRW50aXR5U2V0O1xuXG5cdHByaXZhdGUgY29udGV4dFJvb3RFbnRpdHlTZXQ6IEVudGl0eVNldCB8IHVuZGVmaW5lZDtcblxuXHRwcml2YXRlIGFic29sdXRlUGF0aDogc3RyaW5nO1xuXG5cdHByaXZhdGUgc2VydmljZU9iamVjdFBhdGg6IHN0cmluZztcblxuXHRwcml2YXRlIHJlbGF0aXZlUGF0aDogc3RyaW5nO1xuXG5cdHByaXZhdGUgbmF2aWdhdGlvblByb3BlcnRpZXM6IE5hdmlnYXRpb25Qcm9wZXJ0eVtdO1xuXG5cdHByaXZhdGUgY29udGV4dE5hdmlnYXRpb25Qcm9wZXJ0aWVzOiBOYXZpZ2F0aW9uUHJvcGVydHlbXTtcblxuXHRwcml2YXRlIGN1cnJlbnRFbnRpdHlTZXQ6IEVudGl0eVNldCB8IFNpbmdsZXRvbiB8IHVuZGVmaW5lZDtcblxuXHRwcml2YXRlIGN1cnJlbnRFbnRpdHlUeXBlPzogRW50aXR5VHlwZTtcblxuXHRwcml2YXRlIHRhcmdldE9iamVjdDogVDtcblxuXHQvKipcblx0ICogQ3JlYXRlIHRoZSBNZXRhUGF0aCBvYmplY3QuXG5cdCAqIEBwYXJhbSBjb252ZXJ0ZWRNZXRhZGF0YSBUaGUgY3VycmVudCBtb2RlbCBjb252ZXJ0ZXIgb3V0cHV0XG5cdCAqIEBwYXJhbSBtZXRhUGF0aCBUaGUgY3VycmVudCBvYmplY3QgbWV0YVBhdGhcblx0ICogQHBhcmFtIGNvbnRleHRQYXRoIFRoZSBjdXJyZW50IGNvbnRleHRcblx0ICovXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByaXZhdGUgY29udmVydGVkTWV0YWRhdGE6IENvbnZlcnRlZE1ldGFkYXRhLFxuXHRcdHByaXZhdGUgbWV0YVBhdGg6IHN0cmluZyxcblx0XHRwcml2YXRlIGNvbnRleHRQYXRoOiBzdHJpbmdcblx0KSB7XG5cdFx0dGhpcy5uYXZpZ2F0aW9uUHJvcGVydGllcyA9IFtdO1xuXHRcdHRoaXMuY29udGV4dE5hdmlnYXRpb25Qcm9wZXJ0aWVzID0gW107XG5cdFx0dGhpcy5hYnNvbHV0ZVBhdGggPSBlbmhhbmNlUGF0aChjb250ZXh0UGF0aCwgbWV0YVBhdGgpO1xuXHRcdHRoaXMucmVsYXRpdmVQYXRoID0gdGhpcy5hYnNvbHV0ZVBhdGgucmVwbGFjZShjb250ZXh0UGF0aCwgXCJcIik7XG5cdFx0aWYgKHRoaXMucmVsYXRpdmVQYXRoLnN0YXJ0c1dpdGgoXCIvXCIpKSB7XG5cdFx0XHR0aGlzLnJlbGF0aXZlUGF0aCA9IHRoaXMucmVsYXRpdmVQYXRoLnN1YnN0cmluZygxKTtcblx0XHR9XG5cblx0XHRjb25zdCByZXNvbHZlZE1ldGFQYXRoOiBSZXNvbHV0aW9uVGFyZ2V0PFQ+ID0gdGhpcy5jb252ZXJ0ZWRNZXRhZGF0YS5yZXNvbHZlUGF0aCh0aGlzLmFic29sdXRlUGF0aCk7XG5cdFx0Y29uc3QgcmVzb2x2ZWRDb250ZXh0UGF0aDogUmVzb2x1dGlvblRhcmdldDxUPiA9IHRoaXMuY29udmVydGVkTWV0YWRhdGEucmVzb2x2ZVBhdGgoY29udGV4dFBhdGgpO1xuXHRcdGlmIChyZXNvbHZlZE1ldGFQYXRoLnRhcmdldCA9PT0gdW5kZWZpbmVkIHx8IHJlc29sdmVkTWV0YVBhdGgudGFyZ2V0ID09PSBudWxsKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYE5vIGFubm90YXRpb24gdGFyZ2V0IGZvdW5kIGZvciAke21ldGFQYXRofWApO1xuXHRcdH1cblx0XHR0aGlzLnRhcmdldE9iamVjdCA9IHJlc29sdmVkTWV0YVBhdGgudGFyZ2V0O1xuXHRcdGxldCByb290RW50aXR5U2V0OiBFbnRpdHlTZXQgfCB1bmRlZmluZWQ7XG5cdFx0bGV0IGN1cnJlbnRFbnRpdHlTZXQ6IEVudGl0eVNldCB8IFNpbmdsZXRvbiB8IHVuZGVmaW5lZDtcblx0XHRsZXQgY3VycmVudEVudGl0eVR5cGU6IEVudGl0eVR5cGUgfCB1bmRlZmluZWQ7XG5cdFx0bGV0IG5hdmlnYXRlZFBhdGhzOiBzdHJpbmdbXSA9IFtdO1xuXHRcdHJlc29sdmVkTWV0YVBhdGgub2JqZWN0UGF0aC5mb3JFYWNoKChvYmplY3RQYXJ0OiBTZXJ2aWNlT2JqZWN0QW5kQW5ub3RhdGlvbikgPT4ge1xuXHRcdFx0aWYgKGlzU2VydmljZU9iamVjdChvYmplY3RQYXJ0KSkge1xuXHRcdFx0XHRzd2l0Y2ggKG9iamVjdFBhcnQuX3R5cGUpIHtcblx0XHRcdFx0XHRjYXNlIFwiTmF2aWdhdGlvblByb3BlcnR5XCI6XG5cdFx0XHRcdFx0XHRuYXZpZ2F0ZWRQYXRocy5wdXNoKG9iamVjdFBhcnQubmFtZSk7XG5cdFx0XHRcdFx0XHR0aGlzLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLnB1c2gob2JqZWN0UGFydCk7XG5cdFx0XHRcdFx0XHRjdXJyZW50RW50aXR5VHlwZSA9IG9iamVjdFBhcnQudGFyZ2V0VHlwZTtcblx0XHRcdFx0XHRcdGlmIChjdXJyZW50RW50aXR5U2V0Py5uYXZpZ2F0aW9uUHJvcGVydHlCaW5kaW5nLmhhc093blByb3BlcnR5KG5hdmlnYXRlZFBhdGhzLmpvaW4oXCIvXCIpKSkge1xuXHRcdFx0XHRcdFx0XHRjdXJyZW50RW50aXR5U2V0ID0gY3VycmVudEVudGl0eVNldC5uYXZpZ2F0aW9uUHJvcGVydHlCaW5kaW5nW25hdmlnYXRlZFBhdGhzLmpvaW4oXCIvXCIpXTtcblx0XHRcdFx0XHRcdFx0bmF2aWdhdGVkUGF0aHMgPSBbXTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgXCJFbnRpdHlTZXRcIjpcblx0XHRcdFx0XHRcdGlmIChyb290RW50aXR5U2V0ID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRcdFx0cm9vdEVudGl0eVNldCA9IG9iamVjdFBhcnQ7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRjdXJyZW50RW50aXR5U2V0ID0gb2JqZWN0UGFydDtcblx0XHRcdFx0XHRcdGN1cnJlbnRFbnRpdHlUeXBlID0gY3VycmVudEVudGl0eVNldC5lbnRpdHlUeXBlO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBcIkVudGl0eVR5cGVcIjpcblx0XHRcdFx0XHRcdGlmIChjdXJyZW50RW50aXR5VHlwZSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHRcdGN1cnJlbnRFbnRpdHlUeXBlID0gb2JqZWN0UGFydDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdHJlc29sdmVkQ29udGV4dFBhdGgub2JqZWN0UGF0aC5mb3JFYWNoKChvYmplY3RQYXJ0OiBTZXJ2aWNlT2JqZWN0QW5kQW5ub3RhdGlvbikgPT4ge1xuXHRcdFx0cm9vdEVudGl0eVNldCA9IHRoaXMuZ2V0UmVzb2x2ZWRDb250ZXh0UGF0aChvYmplY3RQYXJ0LCBjdXJyZW50RW50aXR5VHlwZSwgcm9vdEVudGl0eVNldCk7XG5cdFx0fSk7XG5cdFx0aWYgKHJvb3RFbnRpdHlTZXQgPT09IHVuZGVmaW5lZCB8fCBjdXJyZW50RW50aXR5VHlwZSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJNZXRhUGF0aCBkb2Vzbid0IGNvbnRhaW4gYW4gZW50aXR5U2V0IC0+IFNob3VsZCBuZXZlciBoYXBwZW5cIik7XG5cdFx0fVxuXHRcdHRoaXMuc2VydmljZU9iamVjdFBhdGggPSB0aGlzLmNvbnRleHRQYXRoO1xuXHRcdGlmICh0aGlzLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLmxlbmd0aCkge1xuXHRcdFx0dGhpcy5zZXJ2aWNlT2JqZWN0UGF0aCArPSBcIi9cIiArIHRoaXMubmF2aWdhdGlvblByb3BlcnRpZXMubWFwKChuYXYpID0+IG5hdi5uYW1lKS5qb2luKFwiL1wiKTtcblx0XHR9XG5cdFx0dGhpcy5yb290RW50aXR5U2V0ID0gcm9vdEVudGl0eVNldDtcblx0XHR0aGlzLmN1cnJlbnRFbnRpdHlTZXQgPSBjdXJyZW50RW50aXR5U2V0O1xuXHRcdHRoaXMuY3VycmVudEVudGl0eVR5cGUgPSBjdXJyZW50RW50aXR5VHlwZTtcblx0fVxuXG5cdHByaXZhdGUgZ2V0UmVzb2x2ZWRDb250ZXh0UGF0aChcblx0XHRvYmplY3RQYXJ0OiBTZXJ2aWNlT2JqZWN0QW5kQW5ub3RhdGlvbixcblx0XHRjdXJyZW50RW50aXR5VHlwZTogRW50aXR5VHlwZSB8IHVuZGVmaW5lZCxcblx0XHRyb290RW50aXR5U2V0OiBFbnRpdHlTZXQgfCB1bmRlZmluZWRcblx0KTogRW50aXR5U2V0IHwgdW5kZWZpbmVkIHtcblx0XHRpZiAoaXNTZXJ2aWNlT2JqZWN0KG9iamVjdFBhcnQpKSB7XG5cdFx0XHRzd2l0Y2ggKG9iamVjdFBhcnQuX3R5cGUpIHtcblx0XHRcdFx0Y2FzZSBcIk5hdmlnYXRpb25Qcm9wZXJ0eVwiOlxuXHRcdFx0XHRcdHRoaXMuY29udGV4dE5hdmlnYXRpb25Qcm9wZXJ0aWVzLnB1c2gob2JqZWN0UGFydCk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgXCJFbnRpdHlTZXRcIjpcblx0XHRcdFx0XHRpZiAodGhpcy5jb250ZXh0Um9vdEVudGl0eVNldCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmNvbnRleHRSb290RW50aXR5U2V0ID0gb2JqZWN0UGFydDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKHJvb3RFbnRpdHlTZXQgPT09IHVuZGVmaW5lZCAmJiBvYmplY3RQYXJ0LmVudGl0eVR5cGUgPT09IGN1cnJlbnRFbnRpdHlUeXBlKSB7XG5cdFx0XHRcdFx0XHRyb290RW50aXR5U2V0ID0gb2JqZWN0UGFydDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiByb290RW50aXR5U2V0O1xuXHR9XG5cblx0cHVibGljIGdldENvbnRleHRQYXRoKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMuY29udGV4dFBhdGg7XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmUgdGhlIGFic29sdXRlIHBhdGggZm9yIHRoaXMgTWV0YVBhdGguXG5cdCAqIEBwYXJhbSBzUGF0aFBhcnQgVGhlIHBhdGggdG8gZXZhbHVhdGVcblx0ICogQHJldHVybnMgVGhlIGFic29sdXRlIHBhdGhcblx0ICovXG5cdHB1YmxpYyBnZXRQYXRoKHNQYXRoUGFydD86IHN0cmluZyk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIGVuaGFuY2VQYXRoKHRoaXMuYWJzb2x1dGVQYXRoLCBzUGF0aFBhcnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHJpZXZlIHRoZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBjb250ZXh0IGZvciB0aGlzIE1ldGFQYXRoLlxuXHQgKiBAcGFyYW0gc1BhdGhQYXJ0IFRoZSBwYXRoIHRvIGV2YWx1YXRlXG5cdCAqIEByZXR1cm5zIFRoZSByZWxhdGl2ZSBwYXRoXG5cdCAqL1xuXHRwdWJsaWMgZ2V0UmVsYXRpdmVQYXRoKHNQYXRoUGFydD86IHN0cmluZyk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIGVuaGFuY2VQYXRoKHRoaXMucmVsYXRpdmVQYXRoLCBzUGF0aFBhcnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHJpZXZlIHRoZSB0eXBlZCB0YXJnZXQgZm9yIHRoaXMgb2JqZWN0IGNhbGwuXG5cdCAqIEByZXR1cm5zIFRoZSB0eXBlZCB0YXJnZXQgb2JqZWN0XG5cdCAqL1xuXHRwdWJsaWMgZ2V0VGFyZ2V0KCk6IFQge1xuXHRcdHJldHVybiB0aGlzLnRhcmdldE9iamVjdDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXRyaWV2ZSB0aGUgY2xvc2VzdCBlbnRpdHlzZXQgaW4gdGhlIHBhdGguXG5cdCAqIEByZXR1cm5zIFRoZSBjbG9zZXN0IGVudGl0eXNldFxuXHQgKi9cblx0cHVibGljIGdldENsb3Nlc3RFbnRpdHlTZXQoKTogRW50aXR5U2V0IHwgU2luZ2xldG9uIHtcblx0XHRsZXQgY2xvc2VzdEVudGl0eVNldDogRW50aXR5U2V0IHwgU2luZ2xldG9uID0gdGhpcy5yb290RW50aXR5U2V0O1xuXHRcdGZvciAoY29uc3QgbmF2aWdhdGlvblByb3BlcnR5IG9mIHRoaXMubmF2aWdhdGlvblByb3BlcnRpZXMpIHtcblx0XHRcdGNvbnN0IG5hdmlnYXRpb25Qcm9wZXJ0eUJpbmRpbmdFbGVtZW50OiBFbnRpdHlTZXQgfCBTaW5nbGV0b24gfCB1bmRlZmluZWQgPVxuXHRcdFx0XHRjbG9zZXN0RW50aXR5U2V0Lm5hdmlnYXRpb25Qcm9wZXJ0eUJpbmRpbmdbbmF2aWdhdGlvblByb3BlcnR5Lm5hbWVdO1xuXHRcdFx0aWYgKG5hdmlnYXRpb25Qcm9wZXJ0eUJpbmRpbmdFbGVtZW50KSB7XG5cdFx0XHRcdGNsb3Nlc3RFbnRpdHlTZXQgPSBuYXZpZ2F0aW9uUHJvcGVydHlCaW5kaW5nRWxlbWVudDtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGNsb3Nlc3RFbnRpdHlTZXQ7XG5cdH1cblxuXHRwdWJsaWMgZ2V0Q2xvc2VzdEVudGl0eVR5cGUoKTogRW50aXR5VHlwZSB7XG5cdFx0bGV0IGNsb3Nlc3RFbnRpdHlUeXBlOiBFbnRpdHlUeXBlID0gdGhpcy5yb290RW50aXR5U2V0LmVudGl0eVR5cGU7XG5cdFx0Zm9yIChjb25zdCBuYXZpZ2F0aW9uUHJvcGVydHkgb2YgdGhpcy5uYXZpZ2F0aW9uUHJvcGVydGllcykge1xuXHRcdFx0Y2xvc2VzdEVudGl0eVR5cGUgPSBuYXZpZ2F0aW9uUHJvcGVydHkudGFyZ2V0VHlwZTtcblx0XHR9XG5cdFx0cmV0dXJuIGNsb3Nlc3RFbnRpdHlUeXBlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHJpZXZlIHRoZSBjbG9zZXN0IGVudGl0eXNldCBpbiB0aGUgcGF0aC5cblx0ICogQHJldHVybnMgVGhlIGNsb3Nlc3QgZW50aXR5c2V0XG5cdCAqL1xuXHRwdWJsaWMgZ2V0Q29udGV4dENsb3Nlc3RFbnRpdHlTZXQoKTogRW50aXR5U2V0IHwgU2luZ2xldG9uIHwgdW5kZWZpbmVkIHtcblx0XHRsZXQgY2xvc2VzdEVudGl0eVNldDogRW50aXR5U2V0IHwgU2luZ2xldG9uIHwgdW5kZWZpbmVkID0gdGhpcy5jb250ZXh0Um9vdEVudGl0eVNldDtcblx0XHRpZiAoY2xvc2VzdEVudGl0eVNldCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gY2xvc2VzdEVudGl0eVNldDtcblx0XHR9XG5cdFx0Y29uc3Qgbm9uTnVsbEVudGl0eVNldDogRW50aXR5U2V0IHwgU2luZ2xldG9uID0gY2xvc2VzdEVudGl0eVNldDtcblx0XHRmb3IgKGNvbnN0IG5hdmlnYXRpb25Qcm9wZXJ0eSBvZiB0aGlzLmNvbnRleHROYXZpZ2F0aW9uUHJvcGVydGllcykge1xuXHRcdFx0aWYgKG5vbk51bGxFbnRpdHlTZXQubmF2aWdhdGlvblByb3BlcnR5QmluZGluZ1tuYXZpZ2F0aW9uUHJvcGVydHkubmFtZV0pIHtcblx0XHRcdFx0Y2xvc2VzdEVudGl0eVNldCA9IG5vbk51bGxFbnRpdHlTZXQubmF2aWdhdGlvblByb3BlcnR5QmluZGluZ1tuYXZpZ2F0aW9uUHJvcGVydHkubmFtZV07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBjbG9zZXN0RW50aXR5U2V0O1xuXHR9XG5cblx0cHVibGljIGdldE5hdmlnYXRpb25Qcm9wZXJ0aWVzKCk6IE5hdmlnYXRpb25Qcm9wZXJ0eVtdIHtcblx0XHRyZXR1cm4gdGhpcy5uYXZpZ2F0aW9uUHJvcGVydGllcztcblx0fVxuXG5cdHB1YmxpYyBnZXRNZXRhUGF0aEZvclBhdGg8U3ViVHlwZT4odGFyZ2V0UGF0aDogc3RyaW5nKTogTWV0YVBhdGg8U3ViVHlwZT4gfCB1bmRlZmluZWQge1xuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gbmV3IE1ldGFQYXRoPFN1YlR5cGU+KHRoaXMuY29udmVydGVkTWV0YWRhdGEsIGVuaGFuY2VQYXRoKHRoaXMuc2VydmljZU9iamVjdFBhdGgsIHRhcmdldFBhdGgpLCB0aGlzLmNvbnRleHRQYXRoKTtcblx0XHR9IGNhdGNoIChfZXJyb3IpIHtcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGdldE1ldGFQYXRoRm9yT2JqZWN0PFN1YlR5cGUgZXh0ZW5kcyB7IGZ1bGx5UXVhbGlmaWVkTmFtZTogc3RyaW5nIH0+KFxuXHRcdHRhcmdldE9iamVjdDogU3ViVHlwZVxuXHQpOiBNZXRhUGF0aDxSZXNvbHZlZFRhcmdldDxTdWJUeXBlPj4gfCB1bmRlZmluZWQge1xuXHRcdGlmIChpc0Fubm90YXRpb25QYXRoKHRhcmdldE9iamVjdCkpIHtcblx0XHRcdHJldHVybiB0aGlzLmdldE1ldGFQYXRoRm9yUGF0aDxSZXNvbHZlZFRhcmdldDxTdWJUeXBlPj4odGFyZ2V0T2JqZWN0LnZhbHVlKTtcblx0XHR9IGVsc2UgaWYgKGlzUGF0aEFubm90YXRpb25FeHByZXNzaW9uKHRhcmdldE9iamVjdCkpIHtcblx0XHRcdHJldHVybiB0aGlzLmdldE1ldGFQYXRoRm9yUGF0aDxSZXNvbHZlZFRhcmdldDxTdWJUeXBlPj4odGFyZ2V0T2JqZWN0LnBhdGgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBtZXRhUGF0aEFwcCA9IHRhcmdldE9iamVjdC5mdWxseVF1YWxpZmllZE5hbWUucmVwbGFjZSh0aGlzLnJvb3RFbnRpdHlTZXQuZW50aXR5VHlwZS5mdWxseVF1YWxpZmllZE5hbWUsIHRoaXMuY29udGV4dFBhdGgpO1xuXHRcdFx0cmV0dXJuIG5ldyBNZXRhUGF0aDxSZXNvbHZlZFRhcmdldDxTdWJUeXBlPj4odGhpcy5jb252ZXJ0ZWRNZXRhZGF0YSwgbWV0YVBhdGhBcHAsIHRoaXMuY29udGV4dFBhdGgpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBnZXRDb252ZXJ0ZWRNZXRhZGF0YSgpOiBDb252ZXJ0ZWRNZXRhZGF0YSB7XG5cdFx0cmV0dXJuIHRoaXMuY29udmVydGVkTWV0YWRhdGE7XG5cdH1cbn1cbiIsImltcG9ydCB0eXBlIHsgRW50aXR5U2V0IH0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzXCI7XG5pbXBvcnQgdHlwZSB7IFByb3BlcnR5IH0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzL0VkbVwiO1xuaW1wb3J0IHR5cGUgeyBGaWVsZEdyb3VwLCBTZWxlY3Rpb25GaWVsZHMgfSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXMvdm9jYWJ1bGFyaWVzL1VJXCI7XG5pbXBvcnQgeyBVSUFubm90YXRpb25UeXBlcyB9IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlcy92b2NhYnVsYXJpZXMvVUlcIjtcbmltcG9ydCB0eXBlIHsgRW50aXR5VHlwZUFubm90YXRpb25zX1VJIH0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzL3ZvY2FidWxhcmllcy9VSV9FZG1cIjtcbmltcG9ydCB7IEJhc2VEZWZpbml0aW9uLCBjb25maWd1cmFibGUgfSBmcm9tIFwiLi4vQmFzZURlZmluaXRpb25cIjtcbmltcG9ydCB0eXBlIHsgUGFnZVRhcmdldEVudGl0eSB9IGZyb20gXCIuLi9mbG9vcnBsYW5zL0RlZmluaXRpb25QYWdlXCI7XG5pbXBvcnQgdHlwZSBNZXRhUGF0aCBmcm9tIFwiLi4vTWV0YVBhdGhcIjtcbmltcG9ydCBfRW50aXR5U2V0IGZyb20gXCIuLi9vZGF0YS9FbnRpdHlTZXRcIjtcbmltcG9ydCB7IGlzQW5ub3RhdGlvbk9mVHlwZSwgaXNQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb24sIGlzVmFsaWRQcm9wZXJ0eVBhdGhFeHByZXNzaW9uIH0gZnJvbSBcIi4uL3V0aWxzL1R5cGVHdWFyZHNcIjtcblxuZXhwb3J0IHR5cGUgRmlsdGVyRmllbGRDb25maWd1cmF0aW9uID0ge1xuXHRncm91cD86IHN0cmluZztcblx0Z3JvdXBMYWJlbD86IHN0cmluZztcblx0dmlzaWJsZT86IGJvb2xlYW47XG59O1xuXG5jbGFzcyBGaWx0ZXJGaWVsZCBleHRlbmRzIEJhc2VEZWZpbml0aW9uPEZpbHRlckZpZWxkQ29uZmlndXJhdGlvbj4ge1xuXHRAY29uZmlndXJhYmxlKClcblx0Z3JvdXA/OiBzdHJpbmc7XG5cblx0QGNvbmZpZ3VyYWJsZSgpXG5cdGdyb3VwTGFiZWw/OiBzdHJpbmc7XG5cblx0QGNvbmZpZ3VyYWJsZSgpXG5cdHZpc2libGU/OiBib29sZWFuO1xuXG5cdGdldCBsYWJlbCgpOiBzdHJpbmcge1xuXHRcdHJldHVybiB0aGlzLmZpbHRlckZpZWxkUHJvcGVydHkuZ2V0VGFyZ2V0KCkuYW5ub3RhdGlvbnMuQ29tbW9uPy5MYWJlbD8udG9TdHJpbmcoKSA/PyB0aGlzLmZpbHRlckZpZWxkUHJvcGVydHkuZ2V0VGFyZ2V0KCkubmFtZTtcblx0fVxuXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByaXZhdGUgcmVhZG9ubHkgZmlsdGVyRmllbGRQcm9wZXJ0eTogTWV0YVBhdGg8UHJvcGVydHk+LFxuXHRcdGZpbHRlckZpZWxkQ29uZmlndXJhdGlvbjogRmlsdGVyRmllbGRDb25maWd1cmF0aW9uXG5cdCkge1xuXHRcdHN1cGVyKGZpbHRlckZpZWxkUHJvcGVydHksIGZpbHRlckZpZWxkQ29uZmlndXJhdGlvbik7XG5cdH1cbn1cbmV4cG9ydCB0eXBlIEZpbHRlckJhckNvbmZpZ3VyYXRpb24gPSB7XG5cdGZpbHRlckZpZWxkcz86IFJlY29yZDxzdHJpbmcsIEZpbHRlckZpZWxkQ29uZmlndXJhdGlvbltdPjtcbn07XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGaWx0ZXJCYXIge1xuXHRjb25zdHJ1Y3Rvcihcblx0XHRwcml2YXRlIHJlYWRvbmx5IHNlbGVjdGlvbkZpZWxkczogU2VsZWN0aW9uRmllbGRzLFxuXHRcdHByaXZhdGUgcmVhZG9ubHkgZmlsdGVyQmFyQ29uZmlndXJhdGlvbjogRmlsdGVyQmFyQ29uZmlndXJhdGlvbixcblx0XHRwcml2YXRlIHJlYWRvbmx5IG1ldGFQYXRoOiBNZXRhUGF0aDxQYWdlVGFyZ2V0RW50aXR5PlxuXHQpIHt9XG5cblx0Z2V0RmlsdGVyR3JvdXBzKCk6IFJlY29yZDxzdHJpbmcsIHsgZ3JvdXA/OiBzdHJpbmc7IGdyb3VwTGFiZWw/OiBzdHJpbmcgfT4ge1xuXHRcdGNvbnN0IGZpbHRlckZhY2V0cyA9IHRoaXMubWV0YVBhdGguZ2V0Q2xvc2VzdEVudGl0eVR5cGUoKS5hbm5vdGF0aW9ucy5VST8uRmlsdGVyRmFjZXRzO1xuXHRcdGNvbnN0IGZpbHRlckZpZWxkc0dyb3VwOiBSZWNvcmQ8c3RyaW5nLCB7IGdyb3VwPzogc3RyaW5nOyBncm91cExhYmVsPzogc3RyaW5nIH0+ID0ge307XG5cdFx0aWYgKCFmaWx0ZXJGYWNldHMpIHtcblx0XHRcdGNvbnN0IGZpZWxkR3JvdXBzID0gT2JqZWN0LmtleXModGhpcy5tZXRhUGF0aC5nZXRDbG9zZXN0RW50aXR5VHlwZSgpLmFubm90YXRpb25zLlVJID8/IHt9KVxuXHRcdFx0XHQuZmlsdGVyKChrZXkpID0+IHtcblx0XHRcdFx0XHRyZXR1cm4ga2V5LnN0YXJ0c1dpdGgoXCJGaWVsZEdyb3VwXCIpO1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQubWFwKChrZXkpID0+IHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5tZXRhUGF0aC5nZXRDbG9zZXN0RW50aXR5VHlwZSgpLmFubm90YXRpb25zLlVJPy5ba2V5IGFzIGtleW9mIEVudGl0eVR5cGVBbm5vdGF0aW9uc19VSV07XG5cdFx0XHRcdH0pIGFzIEZpZWxkR3JvdXBbXTtcblx0XHRcdGZvciAoY29uc3QgZmllbGRHcm91cCBvZiBmaWVsZEdyb3Vwcykge1xuXHRcdFx0XHRmaWVsZEdyb3VwLkRhdGEuZm9yRWFjaCgoZmllbGRHcm91cEVudHJ5KSA9PiB7XG5cdFx0XHRcdFx0c3dpdGNoIChmaWVsZEdyb3VwRW50cnkuJFR5cGUpIHtcblx0XHRcdFx0XHRcdGNhc2UgVUlBbm5vdGF0aW9uVHlwZXMuRGF0YUZpZWxkOiB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IGZpZWxkR3JvdXBWYWx1ZSA9IGZpZWxkR3JvdXBFbnRyeS5WYWx1ZSBhcyB1bmtub3duO1xuXHRcdFx0XHRcdFx0XHRpZiAoaXNQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb24oZmllbGRHcm91cFZhbHVlKSAmJiBmaWVsZEdyb3VwVmFsdWUuJHRhcmdldCkge1xuXHRcdFx0XHRcdFx0XHRcdGZpbHRlckZpZWxkc0dyb3VwW2ZpZWxkR3JvdXBWYWx1ZS4kdGFyZ2V0LmZ1bGx5UXVhbGlmaWVkTmFtZV0gPSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRncm91cDogZmllbGRHcm91cC5mdWxseVF1YWxpZmllZE5hbWUsXG5cdFx0XHRcdFx0XHRcdFx0XHRncm91cExhYmVsOlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRmaWVsZEdyb3VwLkxhYmVsPy50b1N0cmluZygpID8/XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGZpZWxkR3JvdXAuYW5ub3RhdGlvbnM/LkNvbW1vbj8uTGFiZWw/LnRvU3RyaW5nKCkgPz9cblx0XHRcdFx0XHRcdFx0XHRcdFx0ZmllbGRHcm91cC5xdWFsaWZpZXJcblx0XHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdFx0Ly8gTm90IHN1cHBvcnRlZFxuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRmaWx0ZXJGYWNldHMuZm9yRWFjaCgoZmlsdGVyRmFjZXQpID0+IHtcblx0XHRcdFx0Y29uc3QgZmlsdGVyRmFjZXRUYXJnZXQgPSBmaWx0ZXJGYWNldC5UYXJnZXQuJHRhcmdldDtcblx0XHRcdFx0aWYgKGlzQW5ub3RhdGlvbk9mVHlwZTxGaWVsZEdyb3VwPihmaWx0ZXJGYWNldFRhcmdldCwgVUlBbm5vdGF0aW9uVHlwZXMuRmllbGRHcm91cFR5cGUpKSB7XG5cdFx0XHRcdFx0ZmlsdGVyRmFjZXRUYXJnZXQuRGF0YS5mb3JFYWNoKChmaWVsZEdyb3VwRW50cnkpID0+IHtcblx0XHRcdFx0XHRcdHN3aXRjaCAoZmllbGRHcm91cEVudHJ5LiRUeXBlKSB7XG5cdFx0XHRcdFx0XHRcdGNhc2UgVUlBbm5vdGF0aW9uVHlwZXMuRGF0YUZpZWxkOiB7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZmllbGRHcm91cFZhbHVlID0gZmllbGRHcm91cEVudHJ5LlZhbHVlIGFzIHVua25vd247XG5cdFx0XHRcdFx0XHRcdFx0aWYgKGlzUGF0aEFubm90YXRpb25FeHByZXNzaW9uKGZpZWxkR3JvdXBWYWx1ZSkgJiYgZmllbGRHcm91cFZhbHVlLiR0YXJnZXQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGZpbHRlckZpZWxkc0dyb3VwW2ZpZWxkR3JvdXBWYWx1ZS4kdGFyZ2V0LmZ1bGx5UXVhbGlmaWVkTmFtZV0gPSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGdyb3VwOiBmaWx0ZXJGYWNldC5JRD8udG9TdHJpbmcoKSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0Z3JvdXBMYWJlbDogZmlsdGVyRmFjZXQuTGFiZWw/LnRvU3RyaW5nKClcblx0XHRcdFx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRcdFx0Ly8gTm90IHN1cHBvcnRlZFxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0cmV0dXJuIGZpbHRlckZpZWxkc0dyb3VwO1xuXHR9XG5cblx0Z2V0RmlsdGVyRmllbGRzKCk6IEZpbHRlckZpZWxkW10ge1xuXHRcdGNvbnN0IGZpbHRlckdyb3VwcyA9IHRoaXMuZ2V0RmlsdGVyR3JvdXBzKCk7XG5cdFx0Y29uc3QgY29uc2lkZXJlZFByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+ID0ge307XG5cdFx0Y29uc3QgZnJvbVNlbGVjdGlvbkZpZWxkID0gdGhpcy5zZWxlY3Rpb25GaWVsZHNcblx0XHRcdC5maWx0ZXIoaXNWYWxpZFByb3BlcnR5UGF0aEV4cHJlc3Npb24pXG5cdFx0XHQubWFwKChmaWVsZCkgPT4ge1xuXHRcdFx0XHRjb25zdCBtZXRhUGF0aEZvclByb3BlcnR5ID0gdGhpcy5tZXRhUGF0aC5nZXRNZXRhUGF0aEZvclBhdGg8UHJvcGVydHk+KGZpZWxkLnZhbHVlKTtcblx0XHRcdFx0aWYgKG1ldGFQYXRoRm9yUHJvcGVydHkpIHtcblx0XHRcdFx0XHRjb25zaWRlcmVkUHJvcGVydGllc1ttZXRhUGF0aEZvclByb3BlcnR5LmdldFRhcmdldCgpLmZ1bGx5UXVhbGlmaWVkTmFtZV0gPSB0cnVlO1xuXHRcdFx0XHRcdHJldHVybiBuZXcgRmlsdGVyRmllbGQobWV0YVBhdGhGb3JQcm9wZXJ0eSwge1xuXHRcdFx0XHRcdFx0Z3JvdXA6IGZpbHRlckdyb3Vwc1ttZXRhUGF0aEZvclByb3BlcnR5LmdldFRhcmdldCgpLmZ1bGx5UXVhbGlmaWVkTmFtZV0/Lmdyb3VwLFxuXHRcdFx0XHRcdFx0Z3JvdXBMYWJlbDogZmlsdGVyR3JvdXBzW21ldGFQYXRoRm9yUHJvcGVydHkuZ2V0VGFyZ2V0KCkuZnVsbHlRdWFsaWZpZWROYW1lXT8uZ3JvdXBMYWJlbCxcblx0XHRcdFx0XHRcdHZpc2libGU6IHRydWVcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC5maWx0ZXIoKGZpZWxkKTogZmllbGQgaXMgRmlsdGVyRmllbGQgPT4ge1xuXHRcdFx0XHRyZXR1cm4gISFmaWVsZDtcblx0XHRcdH0pO1xuXHRcdGNvbnN0IG5vbkZpbHRlcmFibGVQcm9wZXJ0aWVzID0gbmV3IF9FbnRpdHlTZXQodGhpcy5tZXRhUGF0aCBhcyBNZXRhUGF0aDxFbnRpdHlTZXQ+KS5nZXROb25GaWx0ZXJhYmxlUHJvcGVydGllcygpO1xuXHRcdHRoaXMubWV0YVBhdGguZ2V0Q2xvc2VzdEVudGl0eVR5cGUoKS5lbnRpdHlQcm9wZXJ0aWVzLmZvckVhY2goKHByb3BlcnR5KSA9PiB7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdCFjb25zaWRlcmVkUHJvcGVydGllc1twcm9wZXJ0eS5mdWxseVF1YWxpZmllZE5hbWVdICYmXG5cdFx0XHRcdCFub25GaWx0ZXJhYmxlUHJvcGVydGllcy5pbmNsdWRlcyhwcm9wZXJ0eSkgJiZcblx0XHRcdFx0cHJvcGVydHkudGFyZ2V0VHlwZSA9PT0gdW5kZWZpbmVkICYmXG5cdFx0XHRcdHByb3BlcnR5LmFubm90YXRpb25zLlVJPy5IaWRkZW4/LnZhbHVlT2YoKSAhPT0gdHJ1ZVxuXHRcdFx0KSB7XG5cdFx0XHRcdGNvbnNpZGVyZWRQcm9wZXJ0aWVzW3Byb3BlcnR5LmZ1bGx5UXVhbGlmaWVkTmFtZV0gPSB0cnVlO1xuXHRcdFx0XHRmcm9tU2VsZWN0aW9uRmllbGQucHVzaChcblx0XHRcdFx0XHRuZXcgRmlsdGVyRmllbGQodGhpcy5tZXRhUGF0aC5nZXRNZXRhUGF0aEZvclBhdGg8UHJvcGVydHk+KHByb3BlcnR5Lm5hbWUpISwge1xuXHRcdFx0XHRcdFx0Z3JvdXA6IGZpbHRlckdyb3Vwc1twcm9wZXJ0eS5mdWxseVF1YWxpZmllZE5hbWVdPy5ncm91cCxcblx0XHRcdFx0XHRcdGdyb3VwTGFiZWw6IGZpbHRlckdyb3Vwc1twcm9wZXJ0eS5mdWxseVF1YWxpZmllZE5hbWVdPy5ncm91cExhYmVsLFxuXHRcdFx0XHRcdFx0dmlzaWJsZTogZmFsc2Vcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIGZyb21TZWxlY3Rpb25GaWVsZDtcblx0fVxuXG5cdGlzU2VhcmNoU3VwcG9ydGVkKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiBuZXcgX0VudGl0eVNldCh0aGlzLm1ldGFQYXRoIGFzIE1ldGFQYXRoPEVudGl0eVNldD4pLmlzU2VhcmNoQWxsb3dlZCgpO1xuXHR9XG59XG4iLCJpbXBvcnQgdHlwZSB7IEVudGl0eVNldCwgTmF2aWdhdGlvblByb3BlcnR5LCBQcm9wZXJ0eVBhdGgsIFNpbmdsZXRvbiB9IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlc1wiO1xuaW1wb3J0IHR5cGUge1xuXHRMaW5lSXRlbSxcblx0UHJlc2VudGF0aW9uVmFyaWFudCxcblx0U2VsZWN0aW9uRmllbGRzLFxuXHRTZWxlY3Rpb25QcmVzZW50YXRpb25WYXJpYW50XG59IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlcy92b2NhYnVsYXJpZXMvVUlcIjtcbmltcG9ydCB7IFVJQW5ub3RhdGlvblRlcm1zIH0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzL3ZvY2FidWxhcmllcy9VSVwiO1xuaW1wb3J0IHR5cGUgeyBGaWx0ZXJCYXJDb25maWd1cmF0aW9uIH0gZnJvbSBcIi4uL2VsZW1lbnRzL0ZpbHRlckJhclwiO1xuaW1wb3J0IEZpbHRlckJhciBmcm9tIFwiLi4vZWxlbWVudHMvRmlsdGVyQmFyXCI7XG5pbXBvcnQgdHlwZSBNZXRhUGF0aCBmcm9tIFwiLi4vTWV0YVBhdGhcIjtcbmltcG9ydCB7IF9JZGVudGlmaWNhdGlvbiB9IGZyb20gXCIuLi9vZGF0YS9hbm5vdGF0aW9ucy9VSS9fSWRlbnRpZmljYXRpb25cIjtcbmltcG9ydCB7IF9MaW5lSXRlbSB9IGZyb20gXCIuLi9vZGF0YS9hbm5vdGF0aW9ucy9VSS9fTGluZUl0ZW1cIjtcblxuZXhwb3J0IHR5cGUgUGFnZVRhcmdldEVudGl0eSA9IEVudGl0eVNldCB8IFNpbmdsZXRvbiB8IE5hdmlnYXRpb25Qcm9wZXJ0eTtcbmV4cG9ydCBjbGFzcyBEZWZpbml0aW9uUGFnZSB7XG5cdHByaXZhdGUgcmVxdWVzdFNldDogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG5cblx0Y29uc3RydWN0b3IocHJpdmF0ZSBtZXRhUGF0aDogTWV0YVBhdGg8UGFnZVRhcmdldEVudGl0eT4pIHt9XG5cblx0Z2V0TWV0YVBhdGgoKTogTWV0YVBhdGg8UGFnZVRhcmdldEVudGl0eT4ge1xuXHRcdHJldHVybiB0aGlzLm1ldGFQYXRoO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIHRhcmdldCBlbnRpdHkgc2V0IGlkZW50aWZpY2F0aW9uIGFubm90YXRpb24gaWYgYXZhaWxhYmxlLlxuXHQgKlxuXHQgKiBAcmV0dXJucyBJZGVudGlmaWNhdGlvbiBhbm5vdGF0aW9uIHdyYXBwZXJcblx0ICovXG5cdHB1YmxpYyBnZXRJZGVudGlmaWNhdGlvbigpOiBfSWRlbnRpZmljYXRpb24gfCB1bmRlZmluZWQge1xuXHRcdGNvbnN0IHRhcmdldEVudGl0eVR5cGUgPSB0aGlzLm1ldGFQYXRoLmdldENsb3Nlc3RFbnRpdHlUeXBlKCk7XG5cdFx0Y29uc3QgaWRBbm5vdGF0aW9uID0gdGFyZ2V0RW50aXR5VHlwZS5hbm5vdGF0aW9ucy5VST8uSWRlbnRpZmljYXRpb247XG5cdFx0aWYgKGlkQW5ub3RhdGlvbikge1xuXHRcdFx0cmV0dXJuIG5ldyBfSWRlbnRpZmljYXRpb24oaWRBbm5vdGF0aW9uLCB0aGlzLm1ldGFQYXRoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmVzIHRoZSBMaW5lSXRlbSBhbm5vdGF0aW9uIGZvciB0aGUgdGFyZ2V0IGVudGl0eSBzZXRcblx0ICogQHJldHVybnMgTGluZUl0ZW0gYW5ub3RhdGlvblxuXHQgKi9cblx0cHVibGljIGdldFRhYmxlVmlzdWFsaXphdGlvbigpOiBfTGluZUl0ZW0gfCB1bmRlZmluZWQge1xuXHRcdHJldHVybiBfTGluZUl0ZW0uZnJvbVNQVih0aGlzLl9nZXRUYWJsZVZpc3VhbGl6YXRpb25Bbm5vdGF0aW9uKCksIHRoaXMubWV0YVBhdGgpO1xuXHR9XG5cblx0cHVibGljIGdldEZpbHRlckJhckRlZmluaXRpb24oZmlsdGVyQmFyQ29uZmlndXJhdGlvbjogRmlsdGVyQmFyQ29uZmlndXJhdGlvbik6IEZpbHRlckJhciB7XG5cdFx0Y29uc3QgdGFyZ2V0RW50aXR5VHlwZSA9IHRoaXMubWV0YVBhdGguZ2V0Q2xvc2VzdEVudGl0eVR5cGUoKTtcblx0XHQvL3RoaXMudHJhY2VyLm1hcmtSZXF1ZXN0KFwiUGFnZS5nZXRGaWx0ZXJCYXJEZWZpbml0aW9uXCIsIHRhcmdldEVudGl0eVR5cGUpO1xuXHRcdGxldCBzZWxlY3Rpb25GaWVsZCA9IHRhcmdldEVudGl0eVR5cGUuYW5ub3RhdGlvbnMuVUk/LlNlbGVjdGlvbkZpZWxkcztcblx0XHRpZiAoIXNlbGVjdGlvbkZpZWxkKSB7XG5cdFx0XHRzZWxlY3Rpb25GaWVsZCA9IE9iamVjdC5hc3NpZ24oW10gYXMgUHJvcGVydHlQYXRoW10sIHtcblx0XHRcdFx0dGVybTogVUlBbm5vdGF0aW9uVGVybXMuU2VsZWN0aW9uRmllbGRzXG5cdFx0XHR9KSBhcyBTZWxlY3Rpb25GaWVsZHM7XG5cdFx0fVxuXHRcdC8vdGhpcy50cmFjZXIuZW5kTWFya1JlcXVlc3QoXCJQYWdlLmdldEZpbHRlckJhckRlZmluaXRpb25cIik7XG5cdFx0cmV0dXJuIG5ldyBGaWx0ZXJCYXIoc2VsZWN0aW9uRmllbGQsIGZpbHRlckJhckNvbmZpZ3VyYXRpb24sIHRoaXMubWV0YVBhdGgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZSBhIGRlZmF1bHQgTGluZUl0ZW0gYW5ub3RhdGlvbiBmb3IgdGhlIHRhcmdldCBlbnRpdHkgdHlwZSBiYXNlZCBvbiBwcm9wZXJ0aWVzXG5cdCAqIEByZXR1cm5zIExpbmVJdGVtIGFubm90YXRpb25cblx0ICovXG5cdHB1YmxpYyBjcmVhdGVEZWZhdWx0VGFibGVWaXN1YWxpemF0aW9uKCk6IF9MaW5lSXRlbSB7XG5cdFx0cmV0dXJuIF9MaW5lSXRlbS5jcmVhdGVEZWZhdWx0KHRoaXMubWV0YVBhdGgpO1xuXHR9XG5cblx0cHJpdmF0ZSBfZ2V0VGFibGVWaXN1YWxpemF0aW9uQW5ub3RhdGlvbigpOiBMaW5lSXRlbSB8IFNlbGVjdGlvblByZXNlbnRhdGlvblZhcmlhbnQgfCBQcmVzZW50YXRpb25WYXJpYW50IHwgdW5kZWZpbmVkIHtcblx0XHRjb25zdCB0YXJnZXRFbnRpdHlUeXBlID0gdGhpcy5tZXRhUGF0aC5nZXRDbG9zZXN0RW50aXR5VHlwZSgpO1xuXHRcdGNvbnN0IHNwdiA9IHRhcmdldEVudGl0eVR5cGUuYW5ub3RhdGlvbnMuVUk/LlNlbGVjdGlvblByZXNlbnRhdGlvblZhcmlhbnQ7XG5cdFx0aWYgKHNwdikge1xuXHRcdFx0aWYgKHNwdi5QcmVzZW50YXRpb25WYXJpYW50LlZpc3VhbGl6YXRpb25zLmZpbmQoKHYpID0+IHYuJHRhcmdldD8udGVybSA9PT0gVUlBbm5vdGF0aW9uVGVybXMuTGluZUl0ZW0pKSB7XG5cdFx0XHRcdHJldHVybiBzcHY7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGNvbnN0IHB2ID0gdGFyZ2V0RW50aXR5VHlwZS5hbm5vdGF0aW9ucy5VST8uUHJlc2VudGF0aW9uVmFyaWFudDtcblx0XHRpZiAocHY/LlZpc3VhbGl6YXRpb25zKSB7XG5cdFx0XHRpZiAocHYuVmlzdWFsaXphdGlvbnMuZmluZCgodikgPT4gdi4kdGFyZ2V0Py50ZXJtID09PSBVSUFubm90YXRpb25UZXJtcy5MaW5lSXRlbSkpIHtcblx0XHRcdFx0cmV0dXJuIHB2O1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGFyZ2V0RW50aXR5VHlwZS5hbm5vdGF0aW9ucy5VST8uTGluZUl0ZW07XG5cdH1cblxuXHRhZGREYXRhVG9SZXF1ZXN0KHByb3BlcnR5UGF0aDogc3RyaW5nKTogdm9pZCB7XG5cdFx0Ly8gQWRkIGRhdGEgdG8gcmVxdWVzdFxuXHRcdHRoaXMucmVxdWVzdFNldC5hZGQocHJvcGVydHlQYXRoKTtcblx0fVxuXG5cdGdldFF1ZXJ5Q29tcG9uZW50cygpOiB7XG5cdFx0JHNlbGVjdDogc3RyaW5nO1xuXHRcdCRleHBhbmQ/OiBzdHJpbmc7XG5cdFx0JGZvcm1hdDogXCJqc29uXCI7XG5cdH0ge1xuXHRcdGNvbnN0IHNlbGVjdDogc3RyaW5nW10gPSBbXTtcblx0XHRjb25zdCBleHBhbmQ6IHN0cmluZ1tdID0gW107XG5cdFx0dGhpcy5yZXF1ZXN0U2V0LmZvckVhY2goKHByb3BlcnR5KSA9PiB7XG5cdFx0XHRjb25zdCBwYXJ0cyA9IHByb3BlcnR5LnNwbGl0KFwiL1wiKTtcblx0XHRcdGlmIChwYXJ0cy5sZW5ndGggPiAxICYmIHBhcnRzWzBdKSB7XG5cdFx0XHRcdGV4cGFuZC5wdXNoKHBhcnRzWzBdKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNlbGVjdC5wdXNoKHByb3BlcnR5KTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRjb25zdCBxdWVyeToge1xuXHRcdFx0JHNlbGVjdDogc3RyaW5nO1xuXHRcdFx0JGV4cGFuZD86IHN0cmluZztcblx0XHRcdCRmb3JtYXQ6IFwianNvblwiO1xuXHRcdH0gPSB7XG5cdFx0XHQkZm9ybWF0OiBcImpzb25cIixcblx0XHRcdCRzZWxlY3Q6IHNlbGVjdC5qb2luKFwiLFwiKVxuXHRcdH07XG5cdFx0aWYgKGV4cGFuZC5sZW5ndGggPiAwKSB7XG5cdFx0XHRxdWVyeS4kZXhwYW5kID0gZXhwYW5kLmpvaW4oXCIsXCIpO1xuXHRcdH1cblx0XHRyZXR1cm4gcXVlcnk7XG5cdH1cbn1cbiIsImV4cG9ydCB7IERlZmluaXRpb25QYWdlIH0gZnJvbSBcIi4vZmxvb3JwbGFucy9EZWZpbml0aW9uUGFnZVwiO1xuZXhwb3J0IHsgX0RhdGFGaWVsZCB9IGZyb20gXCIuL29kYXRhL2Fubm90YXRpb25zL1VJL19EYXRhRmllbGRcIjtcbmV4cG9ydCB7IF9MaW5lSXRlbSB9IGZyb20gXCIuL29kYXRhL2Fubm90YXRpb25zL1VJL19MaW5lSXRlbVwiO1xuZXhwb3J0IHsgRGVmaW5pdGlvbkNvbnRleHQgfSBmcm9tIFwiLi9vZGF0YS9EZWZpbml0aW9uQ29udGV4dFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHMvVHlwZUd1YXJkc1wiO1xuIiwiaW1wb3J0IHR5cGUgeyBDb252ZXJ0ZWRNZXRhZGF0YSwgRW50aXR5U2V0LCBOYXZpZ2F0aW9uUHJvcGVydHksIFNpbmdsZXRvbiB9IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlc1wiO1xuaW1wb3J0IHR5cGUgeyBTQVBKU09OU2NoZW1hRm9yV2ViQXBwbGljYXRpb25NYW5pZmVzdEZpbGUgYXMgQXBwbGljYXRpb25NYW5pZmVzdCwgUm91dGUgfSBmcm9tIFwiQHVpNS9tYW5pZmVzdC90eXBlcy9tYW5pZmVzdFwiO1xuaW1wb3J0IE1ldGFQYXRoIGZyb20gXCIuLi9NZXRhUGF0aFwiO1xuaW1wb3J0IHsgRGVmaW5pdGlvblBhZ2UgfSBmcm9tIFwiLi4vZmxvb3JwbGFucy9EZWZpbml0aW9uUGFnZVwiO1xuXG5leHBvcnQgY2xhc3MgRGVmaW5pdGlvbkNvbnRleHQge1xuXHRwcml2YXRlIG1hbmlmZXN0PzogQXBwbGljYXRpb25NYW5pZmVzdDtcblxuXHRjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGNvbnZlcnRlZE1ldGFkYXRhOiBDb252ZXJ0ZWRNZXRhZGF0YSkge31cblxuXHRhZGRBcHBsaWNhdGlvbk1hbmlmZXN0KG1hbmlmZXN0OiBBcHBsaWNhdGlvbk1hbmlmZXN0KTogdm9pZCB7XG5cdFx0dGhpcy5tYW5pZmVzdCA9IG1hbmlmZXN0O1xuXHR9XG5cblx0Z2V0RW50aXR5U2V0cygpOiBFbnRpdHlTZXRbXSB7XG5cdFx0cmV0dXJuIHRoaXMuY29udmVydGVkTWV0YWRhdGEuZW50aXR5U2V0cztcblx0fVxuXG5cdGdldEVudGl0eVNldChlbnRpdHlTZXROYW1lOiBzdHJpbmcpOiBFbnRpdHlTZXQgfCB1bmRlZmluZWQge1xuXHRcdHJldHVybiB0aGlzLmNvbnZlcnRlZE1ldGFkYXRhLmVudGl0eVNldHMuYnlfbmFtZShlbnRpdHlTZXROYW1lKTtcblx0fVxuXG5cdGdldFJvb3RFbnRpdHlTZXQoKTogRW50aXR5U2V0IHwgU2luZ2xldG9uIHwgdW5kZWZpbmVkIHtcblx0XHRpZiAodGhpcy5tYW5pZmVzdCkge1xuXHRcdFx0Ly8gVXNlIHRoZSB1aTUgcm91dGluZyBjb25maWcgdG8gaWRlbnRpZnkgdGhlIHJvb3QgZW50aXR5c2V0XG5cdFx0XHRjb25zdCBpbml0aWFsUm91dGVQYXR0ZXJuID0gXCI6P3F1ZXJ5OlwiO1xuXHRcdFx0Y29uc3QgaW5pdGlhbFJvdXRlID0gKHRoaXMubWFuaWZlc3RbXCJzYXAudWk1XCJdPy5yb3V0aW5nPy5yb3V0ZXMgYXMgUm91dGVbXSkuZmluZCgocikgPT4gci5wYXR0ZXJuID09PSBpbml0aWFsUm91dGVQYXR0ZXJuKTtcblx0XHRcdGlmIChpbml0aWFsUm91dGU/LnRhcmdldCAmJiB0aGlzLm1hbmlmZXN0W1wic2FwLnVpNVwiXT8ucm91dGluZz8udGFyZ2V0cykge1xuXHRcdFx0XHRjb25zdCB0YXJnZXQgPSB0aGlzLm1hbmlmZXN0W1wic2FwLnVpNVwiXS5yb3V0aW5nLnRhcmdldHNbaW5pdGlhbFJvdXRlLnRhcmdldCBhcyBzdHJpbmddO1xuXHRcdFx0XHRpZiAodGFyZ2V0Py5uYW1lKSB7XG5cdFx0XHRcdFx0Y29uc3Qgb3B0aW9ucyA9IHRhcmdldC5vcHRpb25zIGFzXG5cdFx0XHRcdFx0XHR8IHtcblx0XHRcdFx0XHRcdFx0XHRzZXR0aW5ncz86IHtcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnRleHRQYXRoPzogc3RyaW5nO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZW50aXR5U2V0OiBzdHJpbmc7XG5cdFx0XHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdCAgfVxuXHRcdFx0XHRcdFx0fCB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0Y29uc3Qgc2V0dGluZ3MgPSBvcHRpb25zPy5zZXR0aW5ncztcblx0XHRcdFx0XHRjb25zdCBlbnRpdHlTZXQgPSB0aGlzLmNvbnZlcnRlZE1ldGFkYXRhLnJlc29sdmVQYXRoPEVudGl0eVNldCB8IFNpbmdsZXRvbj4oXG5cdFx0XHRcdFx0XHRzZXR0aW5ncz8uY29udGV4dFBhdGggPz8gYCR7c2V0dGluZ3M/LmVudGl0eVNldH1gXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRyZXR1cm4gZW50aXR5U2V0LnRhcmdldDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHQvLyBUcnkgdG8gZGV0ZXJtaW5lIHRoZSByb290IGVudGl0eSBzZXQgZnJvbSB0aGUgbWV0YWRhdGFcblx0fVxuXG5cdGdldE1ldGFQYXRoPFQ+KG1ldGFQYXRoOiBzdHJpbmcsIGNvbnRleHRQYXRoOiBzdHJpbmcpOiBNZXRhUGF0aDxUPiB7XG5cdFx0cmV0dXJuIG5ldyBNZXRhUGF0aDxUPih0aGlzLmNvbnZlcnRlZE1ldGFkYXRhLCBtZXRhUGF0aCwgY29udGV4dFBhdGgpO1xuXHR9XG5cblx0Z2V0UGFnZUZvcihjb250ZXh0UGF0aDogc3RyaW5nKTogRGVmaW5pdGlvblBhZ2Uge1xuXHRcdC8vIEEgcGFnZSBjb3VsZCBwb2ludCB0b1xuXHRcdC8vIC0gQW4gZW50aXR5U2V0ICgvU2FsZXNPcmRlcilcblx0XHQvLyAtIEEgc2luZ2xldG9uICgvTWUpXG5cdFx0Ly8gLSBBIG5hdmlnYXRpb24gcHJvcGVydHkgKC9TYWxlc09yZGVyL1NldClcblx0XHRyZXR1cm4gbmV3IERlZmluaXRpb25QYWdlKFxuXHRcdFx0bmV3IE1ldGFQYXRoPEVudGl0eVNldCB8IFNpbmdsZXRvbiB8IE5hdmlnYXRpb25Qcm9wZXJ0eT4odGhpcy5jb252ZXJ0ZWRNZXRhZGF0YSwgY29udGV4dFBhdGgsIGNvbnRleHRQYXRoKVxuXHRcdCk7XG5cdH1cbn1cbiIsImltcG9ydCB0eXBlIHsgRW50aXR5U2V0IH0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzXCI7XG5pbXBvcnQgdHlwZSB7IFByb3BlcnR5IH0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzL0VkbVwiO1xuaW1wb3J0IHR5cGUgeyBGaWx0ZXJFeHByZXNzaW9uVHlwZSB9IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlcy92b2NhYnVsYXJpZXMvQ2FwYWJpbGl0aWVzXCI7XG5pbXBvcnQgdHlwZSB7IEJhc2VDb25maWd1cmF0aW9uIH0gZnJvbSBcIi4uL0Jhc2VEZWZpbml0aW9uXCI7XG5pbXBvcnQgeyBCYXNlRGVmaW5pdGlvbiB9IGZyb20gXCIuLi9CYXNlRGVmaW5pdGlvblwiO1xuaW1wb3J0IHR5cGUgTWV0YVBhdGggZnJvbSBcIi4uL01ldGFQYXRoXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIF9FbnRpdHlTZXQgZXh0ZW5kcyBCYXNlRGVmaW5pdGlvbjxCYXNlQ29uZmlndXJhdGlvbj4ge1xuXHRjb25zdHJ1Y3Rvcihcblx0XHRwcml2YXRlIHJlYWRvbmx5IGVudGl0eVNldDogTWV0YVBhdGg8RW50aXR5U2V0Pixcblx0XHRwcml2YXRlIHJlYWRvbmx5IGVudGl0eVNldENvbmZpZ3VyYXRpb246IEJhc2VDb25maWd1cmF0aW9uID0ge31cblx0KSB7XG5cdFx0c3VwZXIoZW50aXR5U2V0LCBlbnRpdHlTZXRDb25maWd1cmF0aW9uKTtcblx0fVxuXHQvL1xuXHQvLyBAYW5ub3RhdGlvbih7XG5cdC8vIFx0dGVybTogQ2FwYWJpbGl0aWVzQW5ub3RhdGlvblRlcm1zLkZpbHRlclJlc3RyaWN0aW9ucyxcblx0Ly8gXHRwcm9jZXNzb3I6IChmaWx0ZXJSZXN0cmljdGlvbnM/OiBGaWx0ZXJSZXN0cmljdGlvbnMpOiBQcm9wZXJ0eVtdID0+IHtcblx0Ly8gXHRcdGNvbnN0IHJlcXVpcmVkUHJvcGVydGllcyA9XG5cdC8vIFx0XHRcdGZpbHRlclJlc3RyaWN0aW9ucz8uUmVxdWlyZWRQcm9wZXJ0aWVzID8/IFtdO1xuXHQvLyBcdFx0cmV0dXJuIHJlcXVpcmVkUHJvcGVydGllc1xuXHQvLyBcdFx0XHQubWFwKChwcm9wZXJ0eVBhdGgpID0+IHtcblx0Ly8gXHRcdFx0XHRyZXR1cm4gcHJvcGVydHlQYXRoLiR0YXJnZXQ7XG5cdC8vIFx0XHRcdH0pXG5cdC8vIFx0XHRcdC5maWx0ZXIoKHByb3BlcnR5KTogcHJvcGVydHkgaXMgUHJvcGVydHkgPT4ge1xuXHQvLyBcdFx0XHRcdHJldHVybiAhIXByb3BlcnR5O1xuXHQvLyBcdFx0XHR9KTtcblx0Ly8gXHR9XG5cdC8vIH0pXG5cdC8vIHJlcXVpcmVkUHJvcGVydGllczogUHJvcGVydHlbXTtcblxuXHQvKipcblx0ICogUmV0cmlldmVzIHRoZSByZXF1aXJlZCBwcm9wZXJ0aWVzIGZvciB0aGUgZW50aXR5IHNldC5cblx0ICovXG5cdGdldFJlcXVpcmVkUHJvcGVydGllcygpOiBQcm9wZXJ0eVtdIHtcblx0XHRjb25zdCByZXF1aXJlZFByb3BlcnRpZXMgPSB0aGlzLmVudGl0eVNldC5nZXRUYXJnZXQoKS5hbm5vdGF0aW9ucy5DYXBhYmlsaXRpZXM/LkZpbHRlclJlc3RyaWN0aW9ucz8uUmVxdWlyZWRQcm9wZXJ0aWVzID8/IFtdO1xuXHRcdHJldHVybiByZXF1aXJlZFByb3BlcnRpZXNcblx0XHRcdC5tYXAoKHByb3BlcnR5UGF0aCkgPT4ge1xuXHRcdFx0XHRyZXR1cm4gcHJvcGVydHlQYXRoLiR0YXJnZXQ7XG5cdFx0XHR9KVxuXHRcdFx0LmZpbHRlcigocHJvcGVydHkpOiBwcm9wZXJ0eSBpcyBQcm9wZXJ0eSA9PiB7XG5cdFx0XHRcdHJldHVybiAhIXByb3BlcnR5O1xuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmVzIHRoZSByZXF1aXJlZCBwcm9wZXJ0aWVzIGZvciB0aGUgZW50aXR5IHNldC5cblx0ICovXG5cdGdldE5vbkZpbHRlcmFibGVQcm9wZXJ0aWVzKCk6IFByb3BlcnR5W10ge1xuXHRcdGNvbnN0IG5vbkZpbHRlcmFibGVQcm9wZXJ0aWVzID1cblx0XHRcdHRoaXMuZW50aXR5U2V0LmdldFRhcmdldCgpLmFubm90YXRpb25zLkNhcGFiaWxpdGllcz8uRmlsdGVyUmVzdHJpY3Rpb25zPy5Ob25GaWx0ZXJhYmxlUHJvcGVydGllcyA/PyBbXTtcblx0XHRyZXR1cm4gbm9uRmlsdGVyYWJsZVByb3BlcnRpZXNcblx0XHRcdC5tYXAoKHByb3BlcnR5UGF0aCkgPT4ge1xuXHRcdFx0XHRyZXR1cm4gcHJvcGVydHlQYXRoLiR0YXJnZXQ7XG5cdFx0XHR9KVxuXHRcdFx0LmZpbHRlcigocHJvcGVydHkpOiBwcm9wZXJ0eSBpcyBQcm9wZXJ0eSA9PiB7XG5cdFx0XHRcdHJldHVybiAhIXByb3BlcnR5O1xuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmVzIHRoZSByZXF1aXJlZCBwcm9wZXJ0aWVzIGZvciB0aGUgZW50aXR5IHNldC5cblx0ICogQHBhcmFtIHByb3BlcnR5XG5cdCAqL1xuXHRnZXRBbGxvd2VkRmlsdGVyRXhwcmVzc2lvbihwcm9wZXJ0eTogUHJvcGVydHkpOiBGaWx0ZXJFeHByZXNzaW9uVHlwZVtdIHtcblx0XHRjb25zdCBmaWx0ZXJFeHByZXNzaW9uUmVzdHJpY3Rpb25zID1cblx0XHRcdHRoaXMuZW50aXR5U2V0LmdldFRhcmdldCgpLmFubm90YXRpb25zLkNhcGFiaWxpdGllcz8uRmlsdGVyUmVzdHJpY3Rpb25zPy5GaWx0ZXJFeHByZXNzaW9uUmVzdHJpY3Rpb25zID8/IFtdO1xuXHRcdGNvbnN0IHByb3BlcnR5UmVzdHJpY3Rpb25zID0gZmlsdGVyRXhwcmVzc2lvblJlc3RyaWN0aW9ucy5maWx0ZXIoXG5cdFx0XHQoZmlsdGVyRXhwcmVzc2lvblJlc3RyaWN0aW9uKSA9PiBmaWx0ZXJFeHByZXNzaW9uUmVzdHJpY3Rpb24uUHJvcGVydHk/LiR0YXJnZXQgPT09IHByb3BlcnR5XG5cdFx0KTtcblx0XHRyZXR1cm4gcHJvcGVydHlSZXN0cmljdGlvbnNcblx0XHRcdC5tYXAoKHByb3BlcnR5UmVzdHJpY3Rpb24pID0+IHtcblx0XHRcdFx0cmV0dXJuIHByb3BlcnR5UmVzdHJpY3Rpb24uQWxsb3dlZEV4cHJlc3Npb25zO1xuXHRcdFx0fSlcblx0XHRcdC5maWx0ZXIoKHByb3BlcnR5UmVzdHJpY3Rpb24pOiBwcm9wZXJ0eVJlc3RyaWN0aW9uIGlzIEZpbHRlckV4cHJlc3Npb25UeXBlID0+IHtcblx0XHRcdFx0cmV0dXJuICEhcHJvcGVydHlSZXN0cmljdGlvbjtcblx0XHRcdH0pO1xuXHR9XG5cblx0aXNTZWFyY2hBbGxvd2VkKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiAhIXRoaXMuZW50aXR5U2V0LmdldFRhcmdldCgpLmFubm90YXRpb25zLkNhcGFiaWxpdGllcz8uU2VhcmNoUmVzdHJpY3Rpb25zPy5TZWFyY2hhYmxlO1xuXHR9XG59XG4iLCJpbXBvcnQgdHlwZSB7IER5bmFtaWNBbm5vdGF0aW9uRXhwcmVzc2lvbiwgUHJvcGVydHksIFN0cmluZyB9IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlc1wiO1xuaW1wb3J0IHR5cGUgeyBEYXRhRmllbGRUeXBlcyB9IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlcy92b2NhYnVsYXJpZXMvVUlcIjtcbmltcG9ydCB7IFRleHRBcnJhbmdlbWVudFR5cGUgfSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXMvdm9jYWJ1bGFyaWVzL1VJXCI7XG5pbXBvcnQgdHlwZSBNZXRhUGF0aCBmcm9tIFwiLi4vLi4vLi4vTWV0YVBhdGhcIjtcbmltcG9ydCB0eXBlIHsgUGFnZVRhcmdldEVudGl0eSB9IGZyb20gXCIuLi8uLi8uLi9mbG9vcnBsYW5zL0RlZmluaXRpb25QYWdlXCI7XG5pbXBvcnQgdHlwZSB7IEV4cHJlc3Npb24sIFByaW1pdGl2ZVR5cGUgfSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvRXhwcmVzc2lvblwiO1xuaW1wb3J0IHtcblx0Y29uY2F0LFxuXHRnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24sXG5cdGlmRWxzZSxcblx0bm90RXF1YWwsXG5cdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5LFxuXHR1bnJlc29sdmFibGVFeHByZXNzaW9uXG59IGZyb20gXCIuLi8uLi8uLi91dGlscy9FeHByZXNzaW9uXCI7XG5pbXBvcnQgeyBpc1BhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbiB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9UeXBlR3VhcmRzXCI7XG5cbmV4cG9ydCBjbGFzcyBfRGF0YUZpZWxkIHtcblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSByZWFkb25seSBkYXRhRmllbGQ6IERhdGFGaWVsZFR5cGVzLFxuXHRcdHByaXZhdGUgcmVhZG9ubHkgcGFnZU1ldGFQYXRoOiBNZXRhUGF0aDxQYWdlVGFyZ2V0RW50aXR5PlxuXHQpIHt9XG5cblx0Z2V0VmFsdWUoKTogRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPiB7XG5cdFx0cmV0dXJuIGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbjxQcmltaXRpdmVUeXBlPih0aGlzLmRhdGFGaWVsZC5WYWx1ZSBhcyBEeW5hbWljQW5ub3RhdGlvbkV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pO1xuXHR9XG5cblx0Z2V0Rm9ybWF0dGVkVmFsdWUoKTogRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPiB7XG5cdFx0Ly8gQ29tcHV0ZSBkaXNwbGF5IG1vZGUgYW5kIHRoZW4gcmV0dXJuIHRoZSBmb3JtYXR0ZWQgdmFsdWVcblx0XHQvLyBBbHNvIGNvbnNpZGVyIHVuaXRzIGFuZCBjdXJyZW5jeVxuXHRcdGNvbnN0IHRhcmdldFZhbHVlID0gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKHRoaXMuZGF0YUZpZWxkLlZhbHVlIGFzIER5bmFtaWNBbm5vdGF0aW9uRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik7XG5cdFx0cmV0dXJuIHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KHRhcmdldFZhbHVlLCBcIlBhdGhJbk1vZGVsXCIsICh2YWx1ZSk6IEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4gPT4ge1xuXHRcdFx0Y29uc3QgcHJvcGVydHlNZXRhUGF0aCA9IHRoaXMucGFnZU1ldGFQYXRoLmdldE1ldGFQYXRoRm9yUGF0aDxQcm9wZXJ0eT4odmFsdWUucGF0aCk7XG5cdFx0XHRpZiAoIXByb3BlcnR5TWV0YVBhdGgpIHtcblx0XHRcdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IG1lYXN1cmUgPSB0aGlzLmdldE1lYXN1cmUocHJvcGVydHlNZXRhUGF0aCk7XG5cdFx0XHRpZiAobWVhc3VyZSkge1xuXHRcdFx0XHRyZXR1cm4gY29uY2F0KHZhbHVlLCBcIiBcIiwgbWVhc3VyZSk7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IGRpc3BsYXlNb2RlID0gdGhpcy5nZXREaXNwbGF5TW9kZShwcm9wZXJ0eU1ldGFQYXRoKTtcblx0XHRcdGlmIChkaXNwbGF5TW9kZSAhPT0gXCJWYWx1ZVwiKSB7XG5cdFx0XHRcdGNvbnN0IHRleHQgPSBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24ocHJvcGVydHlNZXRhUGF0aC5nZXRUYXJnZXQoKS5hbm5vdGF0aW9ucy5Db21tb24/LlRleHQpO1xuXHRcdFx0XHRpZiAoZGlzcGxheU1vZGUgPT09IFwiRGVzY3JpcHRpb25cIikge1xuXHRcdFx0XHRcdHJldHVybiB0ZXh0O1xuXHRcdFx0XHR9IGVsc2UgaWYgKGRpc3BsYXlNb2RlID09PSBcIkRlc2NyaXB0aW9uVmFsdWVcIikge1xuXHRcdFx0XHRcdHJldHVybiBjb25jYXQodGV4dCwgXCIgKFwiLCB2YWx1ZSwgXCIpXCIpO1xuXHRcdFx0XHR9IGVsc2UgaWYgKGRpc3BsYXlNb2RlID09PSBcIlZhbHVlRGVzY3JpcHRpb25cIikge1xuXHRcdFx0XHRcdHJldHVybiBjb25jYXQodmFsdWUsIGlmRWxzZShub3RFcXVhbCh0ZXh0LCB1bmRlZmluZWQpLCBjb25jYXQoXCIgKFwiLCB0ZXh0LCBcIilcIiksIFwiXCIpKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdH0pIGFzIEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT47XG5cdH1cblxuXHQvKipcblx0ICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBwcm9wZXJ0eSBoYXMgYSBVbml0IG9yIElTT0N1cnJlbmN5IGFubm90YXRpb24gYW5kIHJldHVybnMgaXQuXG5cdCAqXG5cdCAqIEBwYXJhbSBwcm9wZXJ0eSBwcm9wZXJ0eSB0byBnZXQgdGhlIG1lYXN1cmUgZm9yXG5cdCAqIEByZXR1cm5zIHRoZSBtZWFzdXJlIGFubm90YXRpb24gb3IgdW5kZWZpbmVkXG5cdCAqL1xuXHRnZXRNZWFzdXJlKHByb3BlcnR5OiBNZXRhUGF0aDxQcm9wZXJ0eT4pOiBFeHByZXNzaW9uPFN0cmluZz4gfCB1bmRlZmluZWQge1xuXHRcdGNvbnN0IG1lYXN1cmVzID0gcHJvcGVydHkuZ2V0VGFyZ2V0KCkuYW5ub3RhdGlvbnMuTWVhc3VyZXM7XG5cdFx0aWYgKG1lYXN1cmVzKSB7XG5cdFx0XHRjb25zdCBtZWFzdXJlID0gbWVhc3VyZXMuVW5pdCA/PyBtZWFzdXJlcy5JU09DdXJyZW5jeTtcblx0XHRcdGlmIChtZWFzdXJlKSB7XG5cdFx0XHRcdHJldHVybiBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24obWVhc3VyZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblxuXHRnZXREaXNwbGF5TW9kZShwcm9wZXJ0eTogTWV0YVBhdGg8UHJvcGVydHk+KTogXCJEZXNjcmlwdGlvblwiIHwgXCJWYWx1ZVwiIHwgXCJEZXNjcmlwdGlvblZhbHVlXCIgfCBcIlZhbHVlRGVzY3JpcHRpb25cIiB7XG5cdFx0Y29uc3QgY3VycmVudEVudGl0eVR5cGUgPSBwcm9wZXJ0eS5nZXRDbG9zZXN0RW50aXR5VHlwZSgpO1xuXHRcdGNvbnN0IHRleHRBbm5vdGF0aW9uID0gcHJvcGVydHkuZ2V0VGFyZ2V0KCkuYW5ub3RhdGlvbnMuQ29tbW9uPy5UZXh0O1xuXHRcdGNvbnN0IHRleHRBcnJhbmdlbWVudCA9IHRleHRBbm5vdGF0aW9uPy5hbm5vdGF0aW9ucz8uVUk/LlRleHRBcnJhbmdlbWVudCA/PyBjdXJyZW50RW50aXR5VHlwZS5hbm5vdGF0aW9ucy5VST8uVGV4dEFycmFuZ2VtZW50O1xuXG5cdFx0bGV0IGRpc3BsYXlNb2RlOiBcIkRlc2NyaXB0aW9uXCIgfCBcIlZhbHVlXCIgfCBcIkRlc2NyaXB0aW9uVmFsdWVcIiB8IFwiVmFsdWVEZXNjcmlwdGlvblwiID0gdGV4dEFubm90YXRpb24gPyBcIkRlc2NyaXB0aW9uVmFsdWVcIiA6IFwiVmFsdWVcIjtcblx0XHRpZiAodGV4dEFubm90YXRpb24gJiYgdGV4dEFycmFuZ2VtZW50ICE9IG51bGwpIHtcblx0XHRcdGlmICh0ZXh0QXJyYW5nZW1lbnQgPT09IFRleHRBcnJhbmdlbWVudFR5cGUuVGV4dE9ubHkpIHtcblx0XHRcdFx0ZGlzcGxheU1vZGUgPSBcIkRlc2NyaXB0aW9uXCI7XG5cdFx0XHR9IGVsc2UgaWYgKHRleHRBcnJhbmdlbWVudCA9PT0gVGV4dEFycmFuZ2VtZW50VHlwZS5UZXh0TGFzdCkge1xuXHRcdFx0XHRkaXNwbGF5TW9kZSA9IFwiVmFsdWVEZXNjcmlwdGlvblwiO1xuXHRcdFx0fSBlbHNlIGlmICh0ZXh0QXJyYW5nZW1lbnQgPT09IFRleHRBcnJhbmdlbWVudFR5cGUuVGV4dFNlcGFyYXRlKSB7XG5cdFx0XHRcdGRpc3BsYXlNb2RlID0gXCJWYWx1ZVwiO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly9EZWZhdWx0IHNob3VsZCBiZSBUZXh0Rmlyc3QgaWYgdGhlcmUgaXMgYSBUZXh0IGFubm90YXRpb24gYW5kIG5laXRoZXIgVGV4dE9ubHkgbm9yIFRleHRMYXN0IGFyZSBzZXRcblx0XHRcdFx0ZGlzcGxheU1vZGUgPSBcIkRlc2NyaXB0aW9uVmFsdWVcIjtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGRpc3BsYXlNb2RlO1xuXHR9XG5cblx0Z2V0TGFiZWwoKTogc3RyaW5nIHtcblx0XHRsZXQgbGFiZWwgPSB0aGlzLmRhdGFGaWVsZC5MYWJlbD8udG9TdHJpbmcoKSA/PyB0aGlzLmRhdGFGaWVsZC5hbm5vdGF0aW9ucz8uQ29tbW9uPy5MYWJlbD8udG9TdHJpbmcoKTtcblx0XHRpZiAoIWxhYmVsKSB7XG5cdFx0XHRjb25zdCB2YWx1ZVRhcmdldCA9IHRoaXMuZGF0YUZpZWxkLlZhbHVlIGFzIER5bmFtaWNBbm5vdGF0aW9uRXhwcmVzc2lvbjx1bmtub3duPjtcblx0XHRcdGlmIChpc1BhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbih2YWx1ZVRhcmdldCkpIHtcblx0XHRcdFx0bGFiZWwgPSB2YWx1ZVRhcmdldC4kdGFyZ2V0Py5hbm5vdGF0aW9ucy5Db21tb24/LkxhYmVsPy50b1N0cmluZygpID8/IHZhbHVlVGFyZ2V0LiR0YXJnZXQ/Lm5hbWUgPz8gdmFsdWVUYXJnZXQucGF0aDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGxhYmVsID0gdGhpcy5kYXRhRmllbGQuZnVsbHlRdWFsaWZpZWROYW1lO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gbGFiZWw7XG5cdH1cblxuXHQvKipcblx0ICogUmV0cmlldmUgYSBwcm9wZXJ0eSBmcm9tIHRoZSBkYXRhIGZpZWxkIElGIGl0IGNhbiBiZSBlYXNpbHkgZGV0ZXJtaW5lZCAobm8gY29tcGxleCBleHJlc3Npb24pXG5cdCAqL1xuXHRnZXRQcm9wZXJ0eSgpOiBQcm9wZXJ0eSB8IHVuZGVmaW5lZCB7XG5cdFx0Y29uc3QgdmFsdWVUYXJnZXQgPSB0aGlzLmRhdGFGaWVsZC5WYWx1ZSBhcyBEeW5hbWljQW5ub3RhdGlvbkV4cHJlc3Npb248dW5rbm93bj47XG5cdFx0aWYgKGlzUGF0aEFubm90YXRpb25FeHByZXNzaW9uKHZhbHVlVGFyZ2V0KSkge1xuXHRcdFx0cmV0dXJuIHZhbHVlVGFyZ2V0LiR0YXJnZXQ7XG5cdFx0fVxuXHR9XG5cblx0Z2V0RnVsbHlRdWFsaWZpZWROYW1lKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMuZGF0YUZpZWxkLmZ1bGx5UXVhbGlmaWVkTmFtZTtcblx0fVxufVxuIiwiaW1wb3J0IHtcblx0VUlBbm5vdGF0aW9uVHlwZXMsXG5cdHR5cGUgRGF0YUZpZWxkVHlwZXMsXG5cdHR5cGUgSWRlbnRpZmljYXRpb24sXG5cdHR5cGUgSW1wb3J0YW5jZVR5cGVcbn0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzL3ZvY2FidWxhcmllcy9VSVwiO1xuaW1wb3J0IHR5cGUgTWV0YVBhdGggZnJvbSBcIi4uLy4uLy4uL01ldGFQYXRoXCI7XG5pbXBvcnQgdHlwZSB7IFBhZ2VUYXJnZXRFbnRpdHkgfSBmcm9tIFwiLi4vLi4vLi4vZmxvb3JwbGFucy9EZWZpbml0aW9uUGFnZVwiO1xuaW1wb3J0IHsgX0RhdGFGaWVsZCB9IGZyb20gXCIuL19EYXRhRmllbGRcIjtcblxuZXhwb3J0IGNsYXNzIF9JZGVudGlmaWNhdGlvbiB7XG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByb3RlY3RlZCByZWFkb25seSBpZDogSWRlbnRpZmljYXRpb24sXG5cdFx0cHJvdGVjdGVkIHJlYWRvbmx5IHBhZ2VNZXRhUGF0aDogTWV0YVBhdGg8UGFnZVRhcmdldEVudGl0eT5cblx0KSB7fVxuXG5cdGdldERhdGFGaWVsZHMob3B0aW9ucz86IHsgaW1wb3J0YW5jZT86IEltcG9ydGFuY2VUeXBlW107IHJlc3RyaWN0VHlwZXM/OiBzdHJpbmdbXSB9KTogX0RhdGFGaWVsZFtdIHtcblx0XHRyZXR1cm4gdGhpcy5pZFxuXHRcdFx0LmZpbHRlcigoaXRlbSk6IGl0ZW0gaXMgRGF0YUZpZWxkVHlwZXMgPT4ge1xuXHRcdFx0XHRpZiAob3B0aW9ucz8ucmVzdHJpY3RUeXBlcyAmJiAhb3B0aW9ucy5yZXN0cmljdFR5cGVzLmluY2x1ZGVzKGl0ZW0uJFR5cGUpKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHN3aXRjaCAoaXRlbS4kVHlwZSkge1xuXHRcdFx0XHRcdGNhc2UgVUlBbm5vdGF0aW9uVHlwZXMuRGF0YUZpZWxkOlxuXHRcdFx0XHRcdGNhc2UgVUlBbm5vdGF0aW9uVHlwZXMuRGF0YUZpZWxkV2l0aFVybDpcblx0XHRcdFx0XHRjYXNlIFVJQW5ub3RhdGlvblR5cGVzLkRhdGFGaWVsZFdpdGhBY3Rpb246XG5cdFx0XHRcdFx0Y2FzZSBVSUFubm90YXRpb25UeXBlcy5EYXRhRmllbGRXaXRoQWN0aW9uR3JvdXA6XG5cdFx0XHRcdFx0Y2FzZSBVSUFubm90YXRpb25UeXBlcy5EYXRhRmllbGRXaXRoSW50ZW50QmFzZWROYXZpZ2F0aW9uOlxuXHRcdFx0XHRcdGNhc2UgVUlBbm5vdGF0aW9uVHlwZXMuRGF0YUZpZWxkV2l0aE5hdmlnYXRpb25QYXRoOlxuXHRcdFx0XHRcdGNhc2UgVUlBbm5vdGF0aW9uVHlwZXMuRGF0YUZpZWxkRm9yQW5ub3RhdGlvbjpcblx0XHRcdFx0XHRjYXNlIFVJQW5ub3RhdGlvblR5cGVzLkRhdGFGaWVsZEZvckFjdGlvbjpcblx0XHRcdFx0XHRjYXNlIFVJQW5ub3RhdGlvblR5cGVzLkRhdGFGaWVsZEZvckludGVudEJhc2VkTmF2aWdhdGlvbjpcblx0XHRcdFx0XHRjYXNlIFVJQW5ub3RhdGlvblR5cGVzLkRhdGFGaWVsZEZvckFjdGlvbkdyb3VwOlxuXHRcdFx0XHRcdFx0cmV0dXJuIChcblx0XHRcdFx0XHRcdFx0b3B0aW9ucz8uaW1wb3J0YW5jZSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdFx0XHRcdG9wdGlvbnMuaW1wb3J0YW5jZS5pbmNsdWRlcyhpdGVtLmFubm90YXRpb25zPy5VST8uSW1wb3J0YW5jZT8udG9TdHJpbmcoKSBhcyBJbXBvcnRhbmNlVHlwZSlcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC5tYXAoKGl0ZW0pID0+IHtcblx0XHRcdFx0cmV0dXJuIG5ldyBfRGF0YUZpZWxkKGl0ZW0sIHRoaXMucGFnZU1ldGFQYXRoKTtcblx0XHRcdH0pO1xuXHR9XG59XG4iLCJpbXBvcnQgdHlwZSB7XG5cdERhdGFGaWVsZEZvckFjdGlvbixcblx0RGF0YUZpZWxkVHlwZXMsXG5cdEltcG9ydGFuY2VUeXBlLFxuXHRMaW5lSXRlbSxcblx0UHJlc2VudGF0aW9uVmFyaWFudCxcblx0U2VsZWN0aW9uUHJlc2VudGF0aW9uVmFyaWFudFxufSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXMvdm9jYWJ1bGFyaWVzL1VJXCI7XG5pbXBvcnQgeyBVSUFubm90YXRpb25UZXJtcywgVUlBbm5vdGF0aW9uVHlwZXMgfSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXMvdm9jYWJ1bGFyaWVzL1VJXCI7XG5pbXBvcnQgdHlwZSBNZXRhUGF0aCBmcm9tIFwiLi4vLi4vLi4vTWV0YVBhdGhcIjtcbmltcG9ydCB0eXBlIHsgUGFnZVRhcmdldEVudGl0eSB9IGZyb20gXCIuLi8uLi8uLi9mbG9vcnBsYW5zL0RlZmluaXRpb25QYWdlXCI7XG5pbXBvcnQgeyBfRGF0YUZpZWxkIH0gZnJvbSBcIi4vX0RhdGFGaWVsZFwiO1xuXG5leHBvcnQgY2xhc3MgX0xpbmVJdGVtIHtcblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSByZWFkb25seSBsaW5lSXRlbTogTGluZUl0ZW0sXG5cdFx0cHJpdmF0ZSByZWFkb25seSBwYWdlTWV0YVBhdGg6IE1ldGFQYXRoPFBhZ2VUYXJnZXRFbnRpdHk+XG5cdCkge31cblxuXHRzdGF0aWMgY3JlYXRlRGVmYXVsdChwYWdlTWV0YVBhdGg6IE1ldGFQYXRoPFBhZ2VUYXJnZXRFbnRpdHk+KTogX0xpbmVJdGVtIHtcblx0XHRjb25zdCBmYWtlTGluZUl0ZW1Bbm5vdGF0aW9uOiBMaW5lSXRlbSA9IHBhZ2VNZXRhUGF0aC5nZXRDbG9zZXN0RW50aXR5VHlwZSgpLmVudGl0eVByb3BlcnRpZXMubWFwKChwcm9wKSA9PiB7XG5cdFx0XHRpZiAocHJvcC5hbm5vdGF0aW9ucy5VST8uRGF0YUZpZWxkRGVmYXVsdCkge1xuXHRcdFx0XHRyZXR1cm4gcHJvcC5hbm5vdGF0aW9ucy5VSS5EYXRhRmllbGREZWZhdWx0O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHQkVHlwZTogVUlBbm5vdGF0aW9uVHlwZXMuRGF0YUZpZWxkLFxuXHRcdFx0XHRcdFZhbHVlOiB7XG5cdFx0XHRcdFx0XHR0eXBlOiBcIlBhdGhcIixcblx0XHRcdFx0XHRcdHBhdGg6IHByb3AubmFtZSxcblx0XHRcdFx0XHRcdCR0YXJnZXQ6IHByb3Bcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0fSkgYXMgTGluZUl0ZW07XG5cdFx0ZmFrZUxpbmVJdGVtQW5ub3RhdGlvbi50ZXJtID0gVUlBbm5vdGF0aW9uVGVybXMuTGluZUl0ZW07XG5cdFx0cmV0dXJuIG5ldyBfTGluZUl0ZW0oZmFrZUxpbmVJdGVtQW5ub3RhdGlvbiwgcGFnZU1ldGFQYXRoKTtcblx0fVxuXG5cdHN0YXRpYyBmcm9tU1BWKFxuXHRcdHNwdjogTGluZUl0ZW0gfCBQcmVzZW50YXRpb25WYXJpYW50IHwgU2VsZWN0aW9uUHJlc2VudGF0aW9uVmFyaWFudCB8IHVuZGVmaW5lZCxcblx0XHRwYWdlTWV0YVBhdGg6IE1ldGFQYXRoPFBhZ2VUYXJnZXRFbnRpdHk+XG5cdCk6IF9MaW5lSXRlbSB8IHVuZGVmaW5lZCB7XG5cdFx0c3dpdGNoIChzcHY/LnRlcm0pIHtcblx0XHRcdGNhc2UgVUlBbm5vdGF0aW9uVGVybXMuTGluZUl0ZW06XG5cdFx0XHRcdHJldHVybiBuZXcgX0xpbmVJdGVtKHNwdiwgcGFnZU1ldGFQYXRoKTtcblx0XHRcdGNhc2UgVUlBbm5vdGF0aW9uVGVybXMuUHJlc2VudGF0aW9uVmFyaWFudDpcblx0XHRcdFx0cmV0dXJuIG5ldyBfTGluZUl0ZW0oc3B2LlZpc3VhbGl6YXRpb25zWzBdIS4kdGFyZ2V0IGFzIExpbmVJdGVtLCBwYWdlTWV0YVBhdGgpO1xuXHRcdFx0Y2FzZSBVSUFubm90YXRpb25UZXJtcy5TZWxlY3Rpb25QcmVzZW50YXRpb25WYXJpYW50OlxuXHRcdFx0XHRyZXR1cm4gbmV3IF9MaW5lSXRlbShzcHYuUHJlc2VudGF0aW9uVmFyaWFudC5WaXN1YWxpemF0aW9uc1swXSEuJHRhcmdldCBhcyBMaW5lSXRlbSwgcGFnZU1ldGFQYXRoKTtcblx0XHRcdGNhc2UgdW5kZWZpbmVkOlxuXHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0fVxuXG5cdGdldEFjdGlvbnMoKTogRGF0YUZpZWxkRm9yQWN0aW9uW10ge1xuXHRcdHJldHVybiB0aGlzLmxpbmVJdGVtLmZpbHRlcigoaXRlbSk6IGl0ZW0gaXMgRGF0YUZpZWxkRm9yQWN0aW9uID0+IGl0ZW0uJFR5cGUgPT09IFVJQW5ub3RhdGlvblR5cGVzLkRhdGFGaWVsZEZvckFjdGlvbik7XG5cdH1cblxuXHRnZXRIZWFkZXJBY3Rpb25zKCk6IERhdGFGaWVsZEZvckFjdGlvbltdIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRBY3Rpb25zKCkuZmlsdGVyKChhY3Rpb24pID0+IGFjdGlvbi5EZXRlcm1pbmluZyA9PT0gdHJ1ZSk7XG5cdH1cblxuXHRnZXREYXRhRmllbGRzKG9wdGlvbnM/OiB7IGltcG9ydGFuY2U/OiBJbXBvcnRhbmNlVHlwZVtdOyByZXN0cmljdFR5cGVzPzogc3RyaW5nW10gfSk6IF9EYXRhRmllbGRbXSB7XG5cdFx0cmV0dXJuIHRoaXMubGluZUl0ZW1cblx0XHRcdC5maWx0ZXIoKGl0ZW0pOiBpdGVtIGlzIERhdGFGaWVsZFR5cGVzID0+IHtcblx0XHRcdFx0aWYgKG9wdGlvbnM/LnJlc3RyaWN0VHlwZXMgJiYgIW9wdGlvbnMucmVzdHJpY3RUeXBlcy5pbmNsdWRlcyhpdGVtLiRUeXBlKSkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRzd2l0Y2ggKGl0ZW0uJFR5cGUpIHtcblx0XHRcdFx0XHRjYXNlIFVJQW5ub3RhdGlvblR5cGVzLkRhdGFGaWVsZDpcblx0XHRcdFx0XHRjYXNlIFVJQW5ub3RhdGlvblR5cGVzLkRhdGFGaWVsZFdpdGhVcmw6XG5cdFx0XHRcdFx0Y2FzZSBVSUFubm90YXRpb25UeXBlcy5EYXRhRmllbGRXaXRoQWN0aW9uOlxuXHRcdFx0XHRcdGNhc2UgVUlBbm5vdGF0aW9uVHlwZXMuRGF0YUZpZWxkV2l0aEFjdGlvbkdyb3VwOlxuXHRcdFx0XHRcdGNhc2UgVUlBbm5vdGF0aW9uVHlwZXMuRGF0YUZpZWxkV2l0aEludGVudEJhc2VkTmF2aWdhdGlvbjpcblx0XHRcdFx0XHRjYXNlIFVJQW5ub3RhdGlvblR5cGVzLkRhdGFGaWVsZFdpdGhOYXZpZ2F0aW9uUGF0aDpcblx0XHRcdFx0XHRjYXNlIFVJQW5ub3RhdGlvblR5cGVzLkRhdGFGaWVsZEZvckFubm90YXRpb246XG5cdFx0XHRcdFx0Y2FzZSBVSUFubm90YXRpb25UeXBlcy5EYXRhRmllbGRGb3JBY3Rpb246XG5cdFx0XHRcdFx0Y2FzZSBVSUFubm90YXRpb25UeXBlcy5EYXRhRmllbGRGb3JJbnRlbnRCYXNlZE5hdmlnYXRpb246XG5cdFx0XHRcdFx0Y2FzZSBVSUFubm90YXRpb25UeXBlcy5EYXRhRmllbGRGb3JBY3Rpb25Hcm91cDpcblx0XHRcdFx0XHRcdHJldHVybiAoXG5cdFx0XHRcdFx0XHRcdG9wdGlvbnM/LmltcG9ydGFuY2UgPT09IHVuZGVmaW5lZCB8fFxuXHRcdFx0XHRcdFx0XHRvcHRpb25zLmltcG9ydGFuY2UuaW5jbHVkZXMoaXRlbS5hbm5vdGF0aW9ucz8uVUk/LkltcG9ydGFuY2U/LnRvU3RyaW5nKCkgYXMgSW1wb3J0YW5jZVR5cGUpXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cdFx0XHQubWFwKChpdGVtKSA9PiB7XG5cdFx0XHRcdHJldHVybiBuZXcgX0RhdGFGaWVsZChpdGVtLCB0aGlzLnBhZ2VNZXRhUGF0aCk7XG5cdFx0XHR9KTtcblx0fVxufVxuIiwiaW1wb3J0IHR5cGUge1xuXHRBbmRBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0QW5kQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRBcHBseUFubm90YXRpb25FeHByZXNzaW9uLFxuXHRCb29sZWFuLFxuXHRDb25kaXRpb25hbENoZWNrT3JWYWx1ZSxcblx0RW50aXR5U2V0LFxuXHRFbnRpdHlUeXBlLFxuXHRFcUFubm90YXRpb25FeHByZXNzaW9uLFxuXHRFcUNvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0R2VBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0R2VDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdEd0QW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEd0Q29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRJZkFubm90YXRpb25FeHByZXNzaW9uLFxuXHRJZkFubm90YXRpb25FeHByZXNzaW9uVmFsdWUsXG5cdExlQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdExlQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRMdEFubm90YXRpb25FeHByZXNzaW9uLFxuXHRMdENvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0TmVBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0TmVDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdE5vdEFubm90YXRpb25FeHByZXNzaW9uLFxuXHROb3RDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdE9yQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdE9yQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdFBhdGhDb25kaXRpb25FeHByZXNzaW9uLFxuXHRQcm9wZXJ0eSxcblx0UHJvcGVydHlBbm5vdGF0aW9uVmFsdWVcbn0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzXCI7XG5pbXBvcnQgeyBDb21tb25Bbm5vdGF0aW9uVGVybXMgfSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXMvdm9jYWJ1bGFyaWVzL0NvbW1vblwiO1xuXG5leHBvcnQgdHlwZSBQcmltaXRpdmVUeXBlID0gc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHwgYm9vbGVhbiB8IG9iamVjdCB8IG51bGwgfCB1bmRlZmluZWQ7XG50eXBlIERlZmluZWRQcmltaXRpdmVUeXBlID0gc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHwgYm9vbGVhbiB8IG9iamVjdDtcbnR5cGUgUHJpbWl0aXZlVHlwZUNhc3Q8UD4gPSBQIGV4dGVuZHMgc3RyaW5nID8gc3RyaW5nIDogUCBleHRlbmRzIEJvb2xlYW4gPyBib29sZWFuIDogUCBleHRlbmRzIG51bWJlciA/IG51bWJlciA6IFA7XG50eXBlIEJhc2VFeHByZXNzaW9uPF9UPiA9IHtcblx0X3R5cGU6IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIEZvcm1hdE9wdGlvbnMgPSBQYXJ0aWFsPHtcblx0Y3VzdG9tVW5pdHM6IFJlY29yZDxzdHJpbmcsIG9iamVjdD47XG5cdGN1c3RvbUN1cnJlbmNpZXM6IFJlY29yZDxzdHJpbmcsIG9iamVjdD47XG5cdGRlY2ltYWxzOiBudW1iZXI7XG5cdGVtcHR5U3RyaW5nOiBudWxsIHwgbnVtYmVyIHwgc3RyaW5nO1xuXHRmaXNjYWxUeXBlOiBzdHJpbmc7XG5cdGdyb3VwaW5nRW5hYmxlZDogYm9vbGVhbjtcblx0bWF4RnJhY3Rpb25EaWdpdHM6IG51bWJlcjtcblx0bWF4SW50ZWdlckRpZ2l0czogbnVtYmVyO1xuXHRtaW5GcmFjdGlvbkRpZ2l0czogbnVtYmVyO1xuXHRtaW5JbnRlZ2VyRGlnaXRzOiBudW1iZXI7XG5cdHBhcnNlQXNTdHJpbmc6IGJvb2xlYW47XG5cdHBhcnNlS2VlcHNFbXB0eVN0cmluZzogYm9vbGVhbjtcblx0cGF0dGVybjogc3RyaW5nO1xuXHRwcmVjaXNpb246IG51bWJlcjtcblx0cHJlc2VydmVEZWNpbWFsczogYm9vbGVhbjtcblx0c2hvcnREZWNpbWFsczogbnVtYmVyO1xuXHRzaG9ydFJlZk51bWJlcjogbnVtYmVyO1xuXHRzaG93TWVhc3VyZTogYm9vbGVhbjtcblx0c2hvd051bWJlcjogYm9vbGVhbjtcblx0c2hvd1NjYWxlOiBib29sZWFuO1xuXHRzdHlsZTogc3RyaW5nO1xufT47XG5cbmV4cG9ydCB0eXBlIENvbnN0YW50RXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJDb25zdGFudFwiO1xuXHR2YWx1ZTogVDtcbn07XG5cbnR5cGUgU2V0T3BlcmF0b3IgPSBcIiYmXCIgfCBcInx8XCI7XG5leHBvcnQgdHlwZSBTZXRFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248Ym9vbGVhbj4gJiB7XG5cdF90eXBlOiBcIlNldFwiO1xuXHRvcGVyYXRvcjogU2V0T3BlcmF0b3I7XG5cdG9wZXJhbmRzOiBFeHByZXNzaW9uPGJvb2xlYW4+W107XG59O1xuXG5leHBvcnQgdHlwZSBOb3RFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248Ym9vbGVhbj4gJiB7XG5cdF90eXBlOiBcIk5vdFwiO1xuXHRvcGVyYW5kOiBFeHByZXNzaW9uPGJvb2xlYW4+O1xufTtcblxuZXhwb3J0IHR5cGUgVHJ1dGh5RXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPGJvb2xlYW4+ICYge1xuXHRfdHlwZTogXCJUcnV0aHlcIjtcblx0b3BlcmFuZDogRXhwcmVzc2lvbjxzdHJpbmc+O1xufTtcblxuZXhwb3J0IHR5cGUgUmVmZXJlbmNlRXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPG9iamVjdD4gJiB7XG5cdF90eXBlOiBcIlJlZlwiO1xuXHRyZWY6IHN0cmluZyB8IG51bGw7XG59O1xuXG5leHBvcnQgdHlwZSBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkZvcm1hdHRlclwiO1xuXHRmbjogc3RyaW5nO1xuXHRwYXJhbWV0ZXJzOiBFeHByZXNzaW9uPHVua25vd24+W107XG59O1xuXG50eXBlIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJDb21wbGV4VHlwZVwiO1xuXHR0eXBlOiBzdHJpbmc7XG5cdGZvcm1hdE9wdGlvbnM6IEZvcm1hdE9wdGlvbnM7XG5cdHBhcmFtZXRlcnM6IG9iamVjdDtcblx0YmluZGluZ1BhcmFtZXRlcnM6IEV4cHJlc3Npb248dW5rbm93bj5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIEZ1bmN0aW9uRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJGdW5jdGlvblwiO1xuXHRvYmo/OiBFeHByZXNzaW9uPG9iamVjdD47XG5cdGZuOiBzdHJpbmc7XG5cdGlzRm9ybWF0dGluZ0ZuOiBib29sZWFuO1xuXHRwYXJhbWV0ZXJzOiBFeHByZXNzaW9uPHVua25vd24+W107XG59O1xuXG5leHBvcnQgdHlwZSBDb25jYXRFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248c3RyaW5nPiAmIHtcblx0X3R5cGU6IFwiQ29uY2F0XCI7XG5cdGV4cHJlc3Npb25zOiBFeHByZXNzaW9uPHN0cmluZz5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIExlbmd0aEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxzdHJpbmc+ICYge1xuXHRfdHlwZTogXCJMZW5ndGhcIjtcblx0cGF0aEluTW9kZWw6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjx1bmtub3duPjtcbn07XG5cbnR5cGUgVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxzdHJpbmc+ICYge1xuXHRfdHlwZTogXCJVbnJlc29sdmFibGVcIjtcbn07XG5cbi8qKlxuICovXG5leHBvcnQgdHlwZSBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiUGF0aEluTW9kZWxcIjtcblx0bW9kZWxOYW1lPzogc3RyaW5nO1xuXHRwYXRoOiBzdHJpbmc7XG5cdHRhcmdldEVudGl0eVNldD86IEVudGl0eVNldDtcblx0dHlwZT86IHN0cmluZztcblx0cGFyYW1ldGVycz86IG9iamVjdDtcblx0dGFyZ2V0VHlwZT86IHN0cmluZztcblx0bW9kZT86IHN0cmluZztcblx0Zm9ybWF0T3B0aW9ucz86IEZvcm1hdE9wdGlvbnM7XG59O1xuXG5leHBvcnQgdHlwZSBFbWJlZGRlZFVJNUJpbmRpbmdFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkVtYmVkZGVkQmluZGluZ1wiO1xuXHR2YWx1ZTogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgRW1iZWRkZWRVSTVFeHByZXNzaW9uQmluZGluZ0V4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiO1xuXHR2YWx1ZTogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgQ29tcGFyaXNvbk9wZXJhdG9yID0gXCI9PT1cIiB8IFwiIT09XCIgfCBcIj49XCIgfCBcIj5cIiB8IFwiPD1cIiB8IFwiPFwiO1xuZXhwb3J0IHR5cGUgQ29tcGFyaXNvbkV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxib29sZWFuPiAmIHtcblx0X3R5cGU6IFwiQ29tcGFyaXNvblwiO1xuXHRvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yO1xuXHRvcGVyYW5kMTogRXhwcmVzc2lvbjx1bmtub3duPjtcblx0b3BlcmFuZDI6IEV4cHJlc3Npb248dW5rbm93bj47XG59O1xuXG5leHBvcnQgdHlwZSBJZkVsc2VFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIklmRWxzZVwiO1xuXHRjb25kaXRpb246IEV4cHJlc3Npb248Ym9vbGVhbj47XG5cdG9uVHJ1ZTogRXhwcmVzc2lvbjxUPjtcblx0b25GYWxzZTogRXhwcmVzc2lvbjxUPjtcbn07XG5cbi8qKlxuICogQW4gZXhwcmVzc2lvbiB0aGF0IGV2YWx1YXRlcyB0byB0eXBlIFQuXG4gKlxuICovXG5leHBvcnQgdHlwZSBFeHByZXNzaW9uPFQ+ID1cblx0fCBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvblxuXHR8IENvbnN0YW50RXhwcmVzc2lvbjxUPlxuXHR8IFNldEV4cHJlc3Npb25cblx0fCBOb3RFeHByZXNzaW9uXG5cdHwgVHJ1dGh5RXhwcmVzc2lvblxuXHR8IENvbmNhdEV4cHJlc3Npb25cblx0fCBMZW5ndGhFeHByZXNzaW9uXG5cdHwgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+XG5cdHwgRW1iZWRkZWRVSTVCaW5kaW5nRXhwcmVzc2lvbjxUPlxuXHR8IEVtYmVkZGVkVUk1RXhwcmVzc2lvbkJpbmRpbmdFeHByZXNzaW9uPFQ+XG5cdHwgQ29tcGFyaXNvbkV4cHJlc3Npb25cblx0fCBJZkVsc2VFeHByZXNzaW9uPFQ+XG5cdHwgRm9ybWF0dGVyRXhwcmVzc2lvbjxUPlxuXHR8IENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPlxuXHR8IFJlZmVyZW5jZUV4cHJlc3Npb25cblx0fCBGdW5jdGlvbkV4cHJlc3Npb248VD47XG5cbi8qKlxuICogQW4gZXhwcmVzc2lvbiB0aGF0IGV2YWx1YXRlcyB0byB0eXBlIFQsIG9yIGEgY29uc3RhbnQgdmFsdWUgb2YgdHlwZSBUXG4gKi9cbmV4cG9ydCB0eXBlIEV4cHJlc3Npb25PclByaW1pdGl2ZTxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4gPSBFeHByZXNzaW9uPFQ+IHwgVDtcblxuZXhwb3J0IGNvbnN0IHVucmVzb2x2YWJsZUV4cHJlc3Npb246IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uID0ge1xuXHRfdHlwZTogXCJVbnJlc29sdmFibGVcIlxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24oLi4uZXhwcmVzc2lvbnM6IEV4cHJlc3Npb248dW5rbm93bj5bXSk6IGJvb2xlYW4ge1xuXHRyZXR1cm4gZXhwcmVzc2lvbnMuZmluZCgoZXhwcikgPT4gZXhwci5fdHlwZSA9PT0gXCJVbnJlc29sdmFibGVcIikgIT09IHVuZGVmaW5lZDtcbn1cbi8qKlxuICogQ2hlY2sgdHdvIGV4cHJlc3Npb25zIGZvciAoZGVlcCkgZXF1YWxpdHkuXG4gKlxuICogQHBhcmFtIGFcbiAqIEBwYXJhbSBiXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHR3byBleHByZXNzaW9ucyBhcmUgZXF1YWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWw8VD4oYT86IEV4cHJlc3Npb248VD4sIGI/OiBFeHByZXNzaW9uPFQ+KTogYm9vbGVhbiB7XG5cdGlmICghYSB8fCAhYikge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRpZiAoYS5fdHlwZSAhPT0gYi5fdHlwZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHN3aXRjaCAoYS5fdHlwZSkge1xuXHRcdGNhc2UgXCJVbnJlc29sdmFibGVcIjpcblx0XHRcdHJldHVybiBmYWxzZTsgLy8gVW5yZXNvbHZhYmxlIGlzIG5ldmVyIGVxdWFsIHRvIGFueXRoaW5nIGV2ZW4gaXRzZWxmXG5cdFx0Y2FzZSBcIkNvbnN0YW50XCI6XG5cdFx0Y2FzZSBcIkVtYmVkZGVkQmluZGluZ1wiOlxuXHRcdGNhc2UgXCJFbWJlZGRlZEV4cHJlc3Npb25CaW5kaW5nXCI6XG5cdFx0XHRyZXR1cm4gYS52YWx1ZSA9PT0gKGIgYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+KS52YWx1ZTtcblxuXHRcdGNhc2UgXCJOb3RcIjpcblx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub3BlcmFuZCwgKGIgYXMgTm90RXhwcmVzc2lvbikub3BlcmFuZCk7XG5cdFx0Y2FzZSBcIlRydXRoeVwiOlxuXHRcdFx0cmV0dXJuIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vcGVyYW5kLCAoYiBhcyBUcnV0aHlFeHByZXNzaW9uKS5vcGVyYW5kKTtcblx0XHRjYXNlIFwiU2V0XCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLm9wZXJhdG9yID09PSAoYiBhcyBTZXRFeHByZXNzaW9uKS5vcGVyYXRvciAmJlxuXHRcdFx0XHRhLm9wZXJhbmRzLmxlbmd0aCA9PT0gKGIgYXMgU2V0RXhwcmVzc2lvbikub3BlcmFuZHMubGVuZ3RoICYmXG5cdFx0XHRcdGEub3BlcmFuZHMuZXZlcnkoKGV4cHJlc3Npb24pID0+XG5cdFx0XHRcdFx0KGIgYXMgU2V0RXhwcmVzc2lvbikub3BlcmFuZHMuc29tZSgob3RoZXJFeHByZXNzaW9uKSA9PiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGV4cHJlc3Npb24sIG90aGVyRXhwcmVzc2lvbikpXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cblx0XHRjYXNlIFwiSWZFbHNlXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEuY29uZGl0aW9uLCAoYiBhcyBJZkVsc2VFeHByZXNzaW9uPFQ+KS5jb25kaXRpb24pICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vblRydWUsIChiIGFzIElmRWxzZUV4cHJlc3Npb248VD4pLm9uVHJ1ZSkgJiZcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9uRmFsc2UsIChiIGFzIElmRWxzZUV4cHJlc3Npb248VD4pLm9uRmFsc2UpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIkNvbXBhcmlzb25cIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEub3BlcmF0b3IgPT09IChiIGFzIENvbXBhcmlzb25FeHByZXNzaW9uKS5vcGVyYXRvciAmJlxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub3BlcmFuZDEsIChiIGFzIENvbXBhcmlzb25FeHByZXNzaW9uKS5vcGVyYW5kMSkgJiZcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9wZXJhbmQyLCAoYiBhcyBDb21wYXJpc29uRXhwcmVzc2lvbikub3BlcmFuZDIpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIkNvbmNhdFwiOiB7XG5cdFx0XHRjb25zdCBhRXhwcmVzc2lvbnMgPSBhLmV4cHJlc3Npb25zO1xuXHRcdFx0Y29uc3QgYkV4cHJlc3Npb25zID0gKGIgYXMgQ29uY2F0RXhwcmVzc2lvbikuZXhwcmVzc2lvbnM7XG5cdFx0XHRpZiAoYUV4cHJlc3Npb25zLmxlbmd0aCAhPT0gYkV4cHJlc3Npb25zLmxlbmd0aCkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gYUV4cHJlc3Npb25zLmV2ZXJ5KChleHByZXNzaW9uLCBpbmRleCkgPT4ge1xuXHRcdFx0XHRyZXR1cm4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChleHByZXNzaW9uLCBiRXhwcmVzc2lvbnNbaW5kZXhdKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGNhc2UgXCJMZW5ndGhcIjpcblx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEucGF0aEluTW9kZWwsIChiIGFzIExlbmd0aEV4cHJlc3Npb24pLnBhdGhJbk1vZGVsKTtcblxuXHRcdGNhc2UgXCJQYXRoSW5Nb2RlbFwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS5tb2RlbE5hbWUgPT09IChiIGFzIFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPikubW9kZWxOYW1lICYmXG5cdFx0XHRcdGEucGF0aCA9PT0gKGIgYXMgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+KS5wYXRoICYmXG5cdFx0XHRcdGEudGFyZ2V0RW50aXR5U2V0ID09PSAoYiBhcyBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4pLnRhcmdldEVudGl0eVNldFxuXHRcdFx0KTtcblxuXHRcdGNhc2UgXCJGb3JtYXR0ZXJcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEuZm4gPT09IChiIGFzIEZvcm1hdHRlckV4cHJlc3Npb248VD4pLmZuICYmXG5cdFx0XHRcdGEucGFyYW1ldGVycy5sZW5ndGggPT09IChiIGFzIEZvcm1hdHRlckV4cHJlc3Npb248VD4pLnBhcmFtZXRlcnMubGVuZ3RoICYmXG5cdFx0XHRcdGEucGFyYW1ldGVycy5ldmVyeSgodmFsdWUsIGluZGV4KSA9PiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKChiIGFzIEZvcm1hdHRlckV4cHJlc3Npb248VD4pLnBhcmFtZXRlcnNbaW5kZXhdLCB2YWx1ZSkpXG5cdFx0XHQpO1xuXHRcdGNhc2UgXCJDb21wbGV4VHlwZVwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS50eXBlID09PSAoYiBhcyBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pLnR5cGUgJiZcblx0XHRcdFx0YS5iaW5kaW5nUGFyYW1ldGVycy5sZW5ndGggPT09IChiIGFzIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPikuYmluZGluZ1BhcmFtZXRlcnMubGVuZ3RoICYmXG5cdFx0XHRcdGEuYmluZGluZ1BhcmFtZXRlcnMuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT5cblx0XHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKChiIGFzIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPikuYmluZGluZ1BhcmFtZXRlcnNbaW5kZXhdLCB2YWx1ZSlcblx0XHRcdFx0KVxuXHRcdFx0KTtcblx0XHRjYXNlIFwiRnVuY3Rpb25cIjpcblx0XHRcdGNvbnN0IG90aGVyRnVuY3Rpb24gPSBiIGFzIEZ1bmN0aW9uRXhwcmVzc2lvbjxUPjtcblx0XHRcdGlmIChhLm9iaiA9PT0gdW5kZWZpbmVkIHx8IG90aGVyRnVuY3Rpb24ub2JqID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cmV0dXJuIGEub2JqID09PSBvdGhlckZ1bmN0aW9uO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLmZuID09PSBvdGhlckZ1bmN0aW9uLmZuICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vYmosIG90aGVyRnVuY3Rpb24ub2JqKSAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMubGVuZ3RoID09PSBvdGhlckZ1bmN0aW9uLnBhcmFtZXRlcnMubGVuZ3RoICYmXG5cdFx0XHRcdGEucGFyYW1ldGVycy5ldmVyeSgodmFsdWUsIGluZGV4KSA9PiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKG90aGVyRnVuY3Rpb24ucGFyYW1ldGVyc1tpbmRleF0sIHZhbHVlKSlcblx0XHRcdCk7XG5cblx0XHRjYXNlIFwiUmVmXCI6XG5cdFx0XHRyZXR1cm4gYS5yZWYgPT09IChiIGFzIFJlZmVyZW5jZUV4cHJlc3Npb24pLnJlZjtcblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBuZXN0ZWQgU2V0RXhwcmVzc2lvbiBieSBpbmxpbmluZyBvcGVyYW5kcyBvZiB0eXBlIFNldEV4cHJlc3Npb24gd2l0aCB0aGUgc2FtZSBvcGVyYXRvci5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgZXhwcmVzc2lvbiB0byBmbGF0dGVuXG4gKiBAcmV0dXJucyBBIG5ldyBTZXRFeHByZXNzaW9uIHdpdGggdGhlIHNhbWUgb3BlcmF0b3JcbiAqL1xuZnVuY3Rpb24gZmxhdHRlblNldEV4cHJlc3Npb24oZXhwcmVzc2lvbjogU2V0RXhwcmVzc2lvbik6IFNldEV4cHJlc3Npb24ge1xuXHRyZXR1cm4gZXhwcmVzc2lvbi5vcGVyYW5kcy5yZWR1Y2U8U2V0RXhwcmVzc2lvbj4oXG5cdFx0KHJlc3VsdDogU2V0RXhwcmVzc2lvbiwgb3BlcmFuZCkgPT4ge1xuXHRcdFx0Y29uc3QgY2FuZGlkYXRlc0ZvckZsYXR0ZW5pbmcgPVxuXHRcdFx0XHRvcGVyYW5kLl90eXBlID09PSBcIlNldFwiICYmIG9wZXJhbmQub3BlcmF0b3IgPT09IGV4cHJlc3Npb24ub3BlcmF0b3IgPyBvcGVyYW5kLm9wZXJhbmRzIDogW29wZXJhbmRdO1xuXHRcdFx0Y2FuZGlkYXRlc0ZvckZsYXR0ZW5pbmcuZm9yRWFjaCgoY2FuZGlkYXRlKSA9PiB7XG5cdFx0XHRcdGlmIChyZXN1bHQub3BlcmFuZHMuZXZlcnkoKGUpID0+ICFfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGUsIGNhbmRpZGF0ZSkpKSB7XG5cdFx0XHRcdFx0cmVzdWx0Lm9wZXJhbmRzLnB1c2goY2FuZGlkYXRlKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH0sXG5cdFx0eyBfdHlwZTogXCJTZXRcIiwgb3BlcmF0b3I6IGV4cHJlc3Npb24ub3BlcmF0b3IsIG9wZXJhbmRzOiBbXSB9XG5cdCk7XG59XG5cbi8qKlxuICogRGV0ZWN0cyB3aGV0aGVyIGFuIGFycmF5IG9mIGJvb2xlYW4gZXhwcmVzc2lvbnMgY29udGFpbnMgYW4gZXhwcmVzc2lvbiBhbmQgaXRzIG5lZ2F0aW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9ucyBBcnJheSBvZiBleHByZXNzaW9uc1xuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBzZXQgb2YgZXhwcmVzc2lvbnMgY29udGFpbnMgYW4gZXhwcmVzc2lvbiBhbmQgaXRzIG5lZ2F0aW9uXG4gKi9cbmZ1bmN0aW9uIGhhc09wcG9zaXRlRXhwcmVzc2lvbnMoZXhwcmVzc2lvbnM6IEV4cHJlc3Npb248Ym9vbGVhbj5bXSk6IGJvb2xlYW4ge1xuXHRjb25zdCBuZWdhdGVkRXhwcmVzc2lvbnMgPSBleHByZXNzaW9ucy5tYXAobm90KTtcblx0cmV0dXJuIGV4cHJlc3Npb25zLnNvbWUoKGV4cHJlc3Npb24sIGluZGV4KSA9PiB7XG5cdFx0Zm9yIChsZXQgaSA9IGluZGV4ICsgMTsgaSA8IG5lZ2F0ZWRFeHByZXNzaW9ucy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoZXhwcmVzc2lvbiwgbmVnYXRlZEV4cHJlc3Npb25zW2ldKSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9KTtcbn1cblxuLyoqXG4gKiBMb2dpY2FsIGBhbmRgIGV4cHJlc3Npb24uXG4gKlxuICogVGhlIGV4cHJlc3Npb24gaXMgc2ltcGxpZmllZCB0byBmYWxzZSBpZiB0aGlzIGNhbiBiZSBkZWNpZGVkIHN0YXRpY2FsbHkgKHRoYXQgaXMsIGlmIG9uZSBvcGVyYW5kIGlzIGEgY29uc3RhbnRcbiAqIGZhbHNlIG9yIGlmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGFuIG9wZXJhbmQgYW5kIGl0cyBuZWdhdGlvbikuXG4gKlxuICogQHBhcmFtIG9wZXJhbmRzIEV4cHJlc3Npb25zIHRvIGNvbm5lY3QgYnkgYGFuZGBcbiAqIEByZXR1cm5zIEV4cHJlc3Npb24gZXZhbHVhdGluZyB0byBib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmQoLi4ub3BlcmFuZHM6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPltdKTogRXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGNvbnN0IGV4cHJlc3Npb25zID0gZmxhdHRlblNldEV4cHJlc3Npb24oe1xuXHRcdF90eXBlOiBcIlNldFwiLFxuXHRcdG9wZXJhdG9yOiBcIiYmXCIsXG5cdFx0b3BlcmFuZHM6IG9wZXJhbmRzLm1hcCh3cmFwUHJpbWl0aXZlKVxuXHR9KS5vcGVyYW5kcztcblxuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbiguLi5leHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRsZXQgaXNTdGF0aWNGYWxzZSA9IGZhbHNlO1xuXHRjb25zdCBub25Ucml2aWFsRXhwcmVzc2lvbiA9IGV4cHJlc3Npb25zLmZpbHRlcigoZXhwcmVzc2lvbikgPT4ge1xuXHRcdGlmIChpc0ZhbHNlKGV4cHJlc3Npb24pKSB7XG5cdFx0XHRpc1N0YXRpY0ZhbHNlID0gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuICFpc0NvbnN0YW50KGV4cHJlc3Npb24pO1xuXHR9KTtcblx0aWYgKGlzU3RhdGljRmFsc2UpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHR9IGVsc2UgaWYgKG5vblRyaXZpYWxFeHByZXNzaW9uLmxlbmd0aCA9PT0gMCkge1xuXHRcdC8vIFJlc29sdmUgdGhlIGNvbnN0YW50IHRoZW5cblx0XHRjb25zdCBpc1ZhbGlkID0gZXhwcmVzc2lvbnMucmVkdWNlKChyZXN1bHQsIGV4cHJlc3Npb24pID0+IHJlc3VsdCAmJiBpc1RydWUoZXhwcmVzc2lvbiksIHRydWUpO1xuXHRcdHJldHVybiBjb25zdGFudChpc1ZhbGlkKTtcblx0fSBlbHNlIGlmIChub25Ucml2aWFsRXhwcmVzc2lvbi5sZW5ndGggPT09IDEpIHtcblx0XHRyZXR1cm4gbm9uVHJpdmlhbEV4cHJlc3Npb25bMF0hO1xuXHR9IGVsc2UgaWYgKGhhc09wcG9zaXRlRXhwcmVzc2lvbnMobm9uVHJpdmlhbEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0XHRvcGVyYXRvcjogXCImJlwiLFxuXHRcdFx0b3BlcmFuZHM6IG5vblRyaXZpYWxFeHByZXNzaW9uXG5cdFx0fTtcblx0fVxufVxuXG4vLyBsZXQgdHJhY2VyOiBhbnk7XG4vLyBleHBvcnQgZnVuY3Rpb24gdHJhY2VFeHByZXNzaW9uKGluVHJhY2VyOiBuZXZlcik6IHZvaWQge1xuLy8gXHR0cmFjZXIgPSBpblRyYWNlcjtcbi8vIH1cbi8vXG4vLyBleHBvcnQgZnVuY3Rpb24gcGlja0ZpcnN0Tm9uTnVsbChcbi8vIFx0Li4ub3BlcmFuZHM6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxQcmltaXRpdmVUeXBlPltdXG4vLyApOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8UHJpbWl0aXZlVHlwZT4ge1xuLy8gXHRjb25zdCByZXN1bHQgPSBvcGVyYW5kcy5maW5kKChvcGVyYW5kKSA9PiBvcGVyYW5kICE9PSB1bmRlZmluZWQpO1xuLy8gXHRpZiAodHJhY2VyKSB7XG4vLyBcdFx0dHJhY2VyLmxvZ0NvbmRpdGlvbmFsKFwicGlja0ZpcnN0Tm9uTnVsbFwiLCBvcGVyYW5kcywgcmVzdWx0KTtcbi8vIFx0fVxuLy8gXHRyZXR1cm4gcmVzdWx0O1xuLy8gfVxuLyoqXG4gKiBMb2dpY2FsIGBvcmAgZXhwcmVzc2lvbi5cbiAqXG4gKiBUaGUgZXhwcmVzc2lvbiBpcyBzaW1wbGlmaWVkIHRvIHRydWUgaWYgdGhpcyBjYW4gYmUgZGVjaWRlZCBzdGF0aWNhbGx5ICh0aGF0IGlzLCBpZiBvbmUgb3BlcmFuZCBpcyBhIGNvbnN0YW50XG4gKiB0cnVlIG9yIGlmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGFuIG9wZXJhbmQgYW5kIGl0cyBuZWdhdGlvbikuXG4gKlxuICogQHBhcmFtIG9wZXJhbmRzIEV4cHJlc3Npb25zIHRvIGNvbm5lY3QgYnkgYG9yYFxuICogQHJldHVybnMgRXhwcmVzc2lvbiBldmFsdWF0aW5nIHRvIGJvb2xlYW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9yKC4uLm9wZXJhbmRzOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8Ym9vbGVhbj5bXSk6IEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRjb25zdCBleHByZXNzaW9ucyA9IGZsYXR0ZW5TZXRFeHByZXNzaW9uKHtcblx0XHRfdHlwZTogXCJTZXRcIixcblx0XHRvcGVyYXRvcjogXCJ8fFwiLFxuXHRcdG9wZXJhbmRzOiBvcGVyYW5kcy5tYXAod3JhcFByaW1pdGl2ZSlcblx0fSkub3BlcmFuZHM7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLmV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGxldCBpc1N0YXRpY1RydWUgPSBmYWxzZTtcblx0Y29uc3Qgbm9uVHJpdmlhbEV4cHJlc3Npb24gPSBleHByZXNzaW9ucy5maWx0ZXIoKGV4cHJlc3Npb24pID0+IHtcblx0XHRpZiAoaXNUcnVlKGV4cHJlc3Npb24pKSB7XG5cdFx0XHRpc1N0YXRpY1RydWUgPSB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gIWlzQ29uc3RhbnQoZXhwcmVzc2lvbikgfHwgZXhwcmVzc2lvbi52YWx1ZTtcblx0fSk7XG5cdGlmIChpc1N0YXRpY1RydWUpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodHJ1ZSk7XG5cdH0gZWxzZSBpZiAobm9uVHJpdmlhbEV4cHJlc3Npb24ubGVuZ3RoID09PSAwKSB7XG5cdFx0Ly8gUmVzb2x2ZSB0aGUgY29uc3RhbnQgdGhlblxuXHRcdGNvbnN0IGlzVmFsaWQgPSBleHByZXNzaW9ucy5yZWR1Y2UoKHJlc3VsdCwgZXhwcmVzc2lvbikgPT4gcmVzdWx0ICYmIGlzVHJ1ZShleHByZXNzaW9uKSwgdHJ1ZSk7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGlzVmFsaWQpO1xuXHR9IGVsc2UgaWYgKG5vblRyaXZpYWxFeHByZXNzaW9uLmxlbmd0aCA9PT0gMSkge1xuXHRcdHJldHVybiBub25Ucml2aWFsRXhwcmVzc2lvblswXSE7XG5cdH0gZWxzZSBpZiAoaGFzT3Bwb3NpdGVFeHByZXNzaW9ucyhub25Ucml2aWFsRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodHJ1ZSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIlNldFwiLFxuXHRcdFx0b3BlcmF0b3I6IFwifHxcIixcblx0XHRcdG9wZXJhbmRzOiBub25Ucml2aWFsRXhwcmVzc2lvblxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBMb2dpY2FsIGBub3RgIG9wZXJhdG9yLlxuICpcbiAqIEBwYXJhbSBvcGVyYW5kIFRoZSBleHByZXNzaW9uIHRvIHJldmVyc2VcbiAqIEByZXR1cm5zIFRoZSByZXN1bHRpbmcgZXhwcmVzc2lvbiB0aGF0IGV2YWx1YXRlcyB0byBib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3Qob3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPGJvb2xlYW4+KTogRXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdG9wZXJhbmQgPSB3cmFwUHJpbWl0aXZlKG9wZXJhbmQpO1xuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbihvcGVyYW5kKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9IGVsc2UgaWYgKGlzQ29uc3RhbnQob3BlcmFuZCkpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoIW9wZXJhbmQudmFsdWUpO1xuXHR9IGVsc2UgaWYgKFxuXHRcdHR5cGVvZiBvcGVyYW5kID09PSBcIm9iamVjdFwiICYmXG5cdFx0b3BlcmFuZC5fdHlwZSA9PT0gXCJTZXRcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmF0b3IgPT09IFwifHxcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmFuZHMuZXZlcnkoKGV4cHJlc3Npb24pID0+IGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgfHwgaXNDb21wYXJpc29uKGV4cHJlc3Npb24pKVxuXHQpIHtcblx0XHRyZXR1cm4gYW5kKC4uLm9wZXJhbmQub3BlcmFuZHMubWFwKChleHByZXNzaW9uKSA9PiBub3QoZXhwcmVzc2lvbikpKTtcblx0fSBlbHNlIGlmIChcblx0XHR0eXBlb2Ygb3BlcmFuZCA9PT0gXCJvYmplY3RcIiAmJlxuXHRcdG9wZXJhbmQuX3R5cGUgPT09IFwiU2V0XCIgJiZcblx0XHRvcGVyYW5kLm9wZXJhdG9yID09PSBcIiYmXCIgJiZcblx0XHRvcGVyYW5kLm9wZXJhbmRzLmV2ZXJ5KChleHByZXNzaW9uKSA9PiBpc0NvbnN0YW50KGV4cHJlc3Npb24pIHx8IGlzQ29tcGFyaXNvbihleHByZXNzaW9uKSlcblx0KSB7XG5cdFx0cmV0dXJuIG9yKC4uLm9wZXJhbmQub3BlcmFuZHMubWFwKChleHByZXNzaW9uKSA9PiBub3QoZXhwcmVzc2lvbikpKTtcblx0fSBlbHNlIGlmIChpc0NvbXBhcmlzb24ob3BlcmFuZCkpIHtcblx0XHQvLyBDcmVhdGUgdGhlIHJldmVyc2UgY29tcGFyaXNvblxuXHRcdHN3aXRjaCAob3BlcmFuZC5vcGVyYXRvcikge1xuXHRcdFx0Y2FzZSBcIiE9PVwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCI9PT1cIiB9O1xuXHRcdFx0Y2FzZSBcIjxcIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPj1cIiB9O1xuXHRcdFx0Y2FzZSBcIjw9XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIj5cIiB9O1xuXHRcdFx0Y2FzZSBcIj09PVwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCIhPT1cIiB9O1xuXHRcdFx0Y2FzZSBcIj5cIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPD1cIiB9O1xuXHRcdFx0Y2FzZSBcIj49XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIjxcIiB9O1xuXHRcdH1cblx0fSBlbHNlIGlmIChvcGVyYW5kLl90eXBlID09PSBcIk5vdFwiKSB7XG5cdFx0cmV0dXJuIG9wZXJhbmQub3BlcmFuZDtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiTm90XCIsXG5cdFx0b3BlcmFuZDogb3BlcmFuZFxuXHR9O1xufVxuXG4vKipcbiAqIEV2YWx1YXRlcyB3aGV0aGVyIGEgYmluZGluZyBleHByZXNzaW9uIGlzIGVxdWFsIHRvIHRydWUgd2l0aCBhIGxvb3NlIGVxdWFsaXR5LlxuICpcbiAqIEBwYXJhbSBvcGVyYW5kIFRoZSBleHByZXNzaW9uIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBUaGUgcmVzdWx0aW5nIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNUcnV0aHkob3BlcmFuZDogRXhwcmVzc2lvbjxzdHJpbmc+KTogRXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGlmIChpc0NvbnN0YW50KG9wZXJhbmQpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KCEhb3BlcmFuZC52YWx1ZSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIlRydXRoeVwiLFxuXHRcdFx0b3BlcmFuZDogb3BlcmFuZFxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgYmluZGluZyBleHByZXNzaW9uIHRoYXQgd2lsbCBiZSBldmFsdWF0ZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgbW9kZWwuXG4gKlxuICogQHBhcmFtIHBhdGhcbiAqIEBwYXJhbSBtb2RlbE5hbWVcbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzXG4gKiBAcGFyYW0gcGF0aFZpc2l0b3JcbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50YXRpbmcgdGhhdCBwYXRoIGluIHRoZSBtb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gb2JqZWN0UGF0aDxUYXJnZXRUeXBlIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHBhdGg6IHN0cmluZyxcblx0bW9kZWxOYW1lPzogc3RyaW5nLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT4gfCBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbiB7XG5cdHJldHVybiBwYXRoSW5Nb2RlbChwYXRoLCBtb2RlbE5hbWUsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgYmluZGluZyBleHByZXNzaW9uIHRoYXQgd2lsbCBiZSBldmFsdWF0ZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgbW9kZWwuXG4gKlxuICogQHRlbXBsYXRlIFRhcmdldFR5cGVcbiAqIEBwYXJhbSBwYXRoIFRoZSBwYXRoIG9uIHRoZSBtb2RlbFxuICogQHBhcmFtIFttb2RlbE5hbWVdIFRoZSBuYW1lIG9mIHRoZSBtb2RlbFxuICogQHBhcmFtIFt2aXNpdGVkTmF2aWdhdGlvblBhdGhzXSBUaGUgcGF0aHMgZnJvbSB0aGUgcm9vdCBlbnRpdHlTZXRcbiAqIEBwYXJhbSBbcGF0aFZpc2l0b3JdIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRhdGluZyB0aGF0IHBhdGggaW4gdGhlIG1vZGVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXRoSW5Nb2RlbChcblx0cGF0aDogdW5kZWZpbmVkLFxuXHRtb2RlbE5hbWU/OiBzdHJpbmcsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM/OiBzdHJpbmdbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb247XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRocz86IHN0cmluZ1tdLFxuXHRwYXRoVmlzaXRvcj86IHVuZGVmaW5lZFxuKTogUGF0aEluTW9kZWxFeHByZXNzaW9uPFRhcmdldFR5cGU+O1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGhJbk1vZGVsPFRhcmdldFR5cGUgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0cGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuXHRtb2RlbE5hbWU/OiBzdHJpbmcsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM/OiBzdHJpbmdbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gfCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT47XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gfCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT4ge1xuXHRpZiAocGF0aCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0bGV0IHRhcmdldFBhdGg6IHN0cmluZztcblx0aWYgKHBhdGhWaXNpdG9yKSB7XG5cdFx0dGFyZ2V0UGF0aCA9IHBhdGhWaXNpdG9yKHBhdGgpIGFzIHN0cmluZztcblx0XHRpZiAodGFyZ2V0UGF0aCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0Y29uc3QgbG9jYWxQYXRoID0gdmlzaXRlZE5hdmlnYXRpb25QYXRocy5jb25jYXQoKTtcblx0XHRsb2NhbFBhdGgucHVzaChwYXRoKTtcblx0XHR0YXJnZXRQYXRoID0gbG9jYWxQYXRoLmpvaW4oXCIvXCIpO1xuXHR9XG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiUGF0aEluTW9kZWxcIixcblx0XHRtb2RlbE5hbWU6IG1vZGVsTmFtZSxcblx0XHRwYXRoOiB0YXJnZXRQYXRoXG5cdH07XG59XG5cbnR5cGUgUGxhaW5FeHByZXNzaW9uT2JqZWN0ID0geyBbaW5kZXg6IHN0cmluZ106IEV4cHJlc3Npb248dW5rbm93bj4gfTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY29uc3RhbnQgZXhwcmVzc2lvbiBiYXNlZCBvbiBhIHByaW1pdGl2ZSB2YWx1ZS5cbiAqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHZhbHVlIFRoZSBjb25zdGFudCB0byB3cmFwIGluIGFuIGV4cHJlc3Npb25cbiAqIEByZXR1cm5zIFRoZSBjb25zdGFudCBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25zdGFudDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4odmFsdWU6IFQpOiBDb25zdGFudEV4cHJlc3Npb248VD4ge1xuXHRsZXQgY29uc3RhbnRWYWx1ZTogVDtcblxuXHRpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWQpIHtcblx0XHRpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcblx0XHRcdGNvbnN0YW50VmFsdWUgPSB2YWx1ZS5tYXAod3JhcFByaW1pdGl2ZSkgYXMgVDtcblx0XHR9IGVsc2UgaWYgKGlzUHJpbWl0aXZlT2JqZWN0KHZhbHVlKSkge1xuXHRcdFx0Y29uc3RhbnRWYWx1ZSA9IHZhbHVlLnZhbHVlT2YoKSBhcyBUO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdGFudFZhbHVlID0gT2JqZWN0LmVudHJpZXModmFsdWUpLnJlZHVjZSgocGxhaW5FeHByZXNzaW9uLCBba2V5LCB2YWxdKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHdyYXBwZWRWYWx1ZSA9IHdyYXBQcmltaXRpdmUodmFsKTtcblx0XHRcdFx0aWYgKHdyYXBwZWRWYWx1ZS5fdHlwZSAhPT0gXCJDb25zdGFudFwiIHx8IHdyYXBwZWRWYWx1ZS52YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0cGxhaW5FeHByZXNzaW9uW2tleSBhcyBrZXlvZiB0eXBlb2YgcGxhaW5FeHByZXNzaW9uXSA9IHdyYXBwZWRWYWx1ZSBhcyBuZXZlcjtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gcGxhaW5FeHByZXNzaW9uO1xuXHRcdFx0fSwge30gc2F0aXNmaWVzIFBsYWluRXhwcmVzc2lvbk9iamVjdCkgYXMgVDtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0Y29uc3RhbnRWYWx1ZSA9IHZhbHVlO1xuXHR9XG5cblx0cmV0dXJuIHsgX3R5cGU6IFwiQ29uc3RhbnRcIiwgdmFsdWU6IGNvbnN0YW50VmFsdWUgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVCaW5kaW5nU3RyaW5nPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0dmFsdWU6IHN0cmluZyB8IGJvb2xlYW4gfCBudW1iZXIsXG5cdHRhcmdldFR5cGU/OiBzdHJpbmdcbik6IENvbnN0YW50RXhwcmVzc2lvbjxUPiB8IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPiB8IEVtYmVkZGVkVUk1QmluZGluZ0V4cHJlc3Npb248VD4gfCBFbWJlZGRlZFVJNUV4cHJlc3Npb25CaW5kaW5nRXhwcmVzc2lvbjxUPiB7XG5cdGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZS5zdGFydHNXaXRoKFwie1wiKSkge1xuXHRcdGNvbnN0IHBhdGhJbk1vZGVsUmVnZXggPSAvXnsoLiopPiguKyl9JC87IC8vIE1hdGNoZXMgbW9kZWwgcGF0aHMgbGlrZSBcIm1vZGVsPnBhdGhcIiBvciBcIj5wYXRoXCIgKGRlZmF1bHQgbW9kZWwpXG5cdFx0Y29uc3QgcGF0aEluTW9kZWxSZWdleE1hdGNoID0gcGF0aEluTW9kZWxSZWdleC5leGVjKHZhbHVlKTtcblxuXHRcdGlmICh2YWx1ZS5zdGFydHNXaXRoKFwiez1cIikpIHtcblx0XHRcdC8vIEV4cHJlc3Npb24gYmluZGluZywgd2UgY2FuIGp1c3QgcmVtb3ZlIHRoZSBvdXRlciBiaW5kaW5nIHRoaW5nc1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0X3R5cGU6IFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiLFxuXHRcdFx0XHR2YWx1ZTogdmFsdWVcblx0XHRcdH07XG5cdFx0fSBlbHNlIGlmIChwYXRoSW5Nb2RlbFJlZ2V4TWF0Y2gpIHtcblx0XHRcdHJldHVybiBwYXRoSW5Nb2RlbChwYXRoSW5Nb2RlbFJlZ2V4TWF0Y2hbMl0gfHwgXCJcIiwgcGF0aEluTW9kZWxSZWdleE1hdGNoWzFdIHx8IHVuZGVmaW5lZCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdF90eXBlOiBcIkVtYmVkZGVkQmluZGluZ1wiLFxuXHRcdFx0XHR2YWx1ZTogdmFsdWVcblx0XHRcdH07XG5cdFx0fVxuXHR9IGVsc2UgaWYgKHRhcmdldFR5cGUgPT09IFwiYm9vbGVhblwiICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAodmFsdWUgPT09IFwidHJ1ZVwiIHx8IHZhbHVlID09PSBcImZhbHNlXCIpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KHZhbHVlID09PSBcInRydWVcIikgYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKHRhcmdldFR5cGUgPT09IFwibnVtYmVyXCIgJiYgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmICghaXNOYU4oTnVtYmVyKHZhbHVlKSkgfHwgdmFsdWUgPT09IFwiTmFOXCIpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KE51bWJlcih2YWx1ZSkpIGFzIENvbnN0YW50RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodmFsdWUpIGFzIENvbnN0YW50RXhwcmVzc2lvbjxUPjtcblx0fVxufVxuXG4vKipcbiAqIEEgbmFtZWQgcmVmZXJlbmNlLlxuICpcbiAqIEBzZWUgZm5cbiAqIEBwYXJhbSByZWZlcmVuY2UgUmVmZXJlbmNlXG4gKiBAcmV0dXJucyBUaGUgb2JqZWN0IHJlZmVyZW5jZSBiaW5kaW5nIHBhcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZihyZWZlcmVuY2U6IHN0cmluZyB8IG51bGwpOiBSZWZlcmVuY2VFeHByZXNzaW9uIHtcblx0cmV0dXJuIHsgX3R5cGU6IFwiUmVmXCIsIHJlZjogcmVmZXJlbmNlIH07XG59XG5cbi8qKlxuICogV3JhcCBhIHByaW1pdGl2ZSBpbnRvIGEgY29uc3RhbnQgZXhwcmVzc2lvbiBpZiBpdCBpcyBub3QgYWxyZWFkeSBhbiBleHByZXNzaW9uLlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0gc29tZXRoaW5nIFRoZSBvYmplY3QgdG8gd3JhcCBpbiBhIENvbnN0YW50IGV4cHJlc3Npb25cbiAqIEByZXR1cm5zIEVpdGhlciB0aGUgb3JpZ2luYWwgb2JqZWN0IG9yIHRoZSB3cmFwcGVkIG9uZSBkZXBlbmRpbmcgb24gdGhlIGNhc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyYXBQcmltaXRpdmU8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KHNvbWV0aGluZzogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+KTogRXhwcmVzc2lvbjxUPiB7XG5cdGlmIChpc0V4cHJlc3Npb24oc29tZXRoaW5nIGFzIEV4cHJlc3Npb248VD4pKSB7XG5cdFx0cmV0dXJuIHNvbWV0aGluZyBhcyBFeHByZXNzaW9uPFQ+O1xuXHR9XG5cblx0cmV0dXJuIGNvbnN0YW50KHNvbWV0aGluZyBhcyBUKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgYSBiaW5kaW5nIHRvb2xpbmcgZXhwcmVzc2lvbiBvciBub3QuXG4gKlxuICogRXZlcnkgb2JqZWN0IGhhdmluZyBhIHByb3BlcnR5IG5hbWVkIGBfdHlwZWAgb2Ygc29tZSB2YWx1ZSBpcyBjb25zaWRlcmVkIGFuIGV4cHJlc3Npb24sIGV2ZW4gaWYgdGhlcmUgaXMgYWN0dWFsbHlcbiAqIG5vIHN1Y2ggZXhwcmVzc2lvbiB0eXBlIHN1cHBvcnRlZC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgYmluZGluZyB0b29sa2l0IGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRXhwcmVzc2lvbihleHByZXNzaW9uOiB1bmtub3duKTogZXhwcmVzc2lvbiBpcyBFeHByZXNzaW9uPHVua25vd24+IHtcblx0cmV0dXJuIChleHByZXNzaW9uIGFzIEV4cHJlc3Npb248dW5rbm93bj4gfCB1bmRlZmluZWQpPy5fdHlwZSAhPT0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBjb25zdGFudCBvciBub3QuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gIG1heWJlQ29uc3RhbnQgVGhlIGV4cHJlc3Npb24gb3IgcHJpbWl0aXZlIHZhbHVlIHRoYXQgaXMgdG8gYmUgY2hlY2tlZFxuICogQHJldHVybnMgYHRydWVgIGlmIGl0IGlzIGNvbnN0YW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbnN0YW50PFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihtYXliZUNvbnN0YW50OiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4pOiBtYXliZUNvbnN0YW50IGlzIENvbnN0YW50RXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiB0eXBlb2YgbWF5YmVDb25zdGFudCAhPT0gXCJvYmplY3RcIiB8fCAobWF5YmVDb25zdGFudCBhcyBCYXNlRXhwcmVzc2lvbjxUPikuX3R5cGUgPT09IFwiQ29uc3RhbnRcIjtcbn1cblxuZnVuY3Rpb24gaXNUcnVlKGV4cHJlc3Npb246IEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pOiBib29sZWFuIHtcblx0cmV0dXJuIGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgJiYgZXhwcmVzc2lvbi52YWx1ZSA9PT0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaXNGYWxzZShleHByZXNzaW9uOiBFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KTogYm9vbGVhbiB7XG5cdHJldHVybiBpc0NvbnN0YW50KGV4cHJlc3Npb24pICYmIGV4cHJlc3Npb24udmFsdWUgPT09IGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBhIHBhdGggaW4gbW9kZWwgZXhwcmVzc2lvbiBvciBub3QuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gIG1heWJlQmluZGluZyBUaGUgZXhwcmVzc2lvbiBvciBwcmltaXRpdmUgdmFsdWUgdGhhdCBpcyB0byBiZSBjaGVja2VkXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgaXQgaXMgYSBwYXRoIGluIG1vZGVsIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUGF0aEluTW9kZWxFeHByZXNzaW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0bWF5YmVCaW5kaW5nOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IG1heWJlQmluZGluZyBpcyBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4ge1xuXHRyZXR1cm4gKG1heWJlQmluZGluZyBhcyBCYXNlRXhwcmVzc2lvbjxUPikuX3R5cGUgPT09IFwiUGF0aEluTW9kZWxcIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgYSBjb21wbGV4IHR5cGUgZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSAgbWF5YmVCaW5kaW5nIFRoZSBleHByZXNzaW9uIG9yIHByaW1pdGl2ZSB2YWx1ZSB0aGF0IGlzIHRvIGJlIGNoZWNrZWRcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiBpdCBpcyBhIHBhdGggaW4gbW9kZWwgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb21wbGV4VHlwZUV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRtYXliZUJpbmRpbmc6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogbWF5YmVCaW5kaW5nIGlzIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiAobWF5YmVCaW5kaW5nIGFzIEJhc2VFeHByZXNzaW9uPFQ+KS5fdHlwZSA9PT0gXCJDb21wbGV4VHlwZVwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBhIGNvbmNhdCBleHByZXNzaW9uIG9yIG5vdC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgQ29uY2F0RXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBpc0NvbmNhdEV4cHJlc3Npb24oZXhwcmVzc2lvbjogRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik6IGV4cHJlc3Npb24gaXMgQ29uY2F0RXhwcmVzc2lvbiB7XG5cdHJldHVybiAoZXhwcmVzc2lvbiBhcyBCYXNlRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPikuX3R5cGUgPT09IFwiQ29uY2F0XCI7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBleHByZXNzaW9uIG9yIHZhbHVlIHByb3ZpZGVkIGlzIGEgSWZFbHNlIGV4cHJlc3Npb24gb3Igbm90LlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGV4cHJlc3Npb24gaXMgYSBJZkVsc2VFeHByZXNzaW9uXG4gKi9cbmZ1bmN0aW9uIGlzSWZFbHNlRXhwcmVzc2lvbihleHByZXNzaW9uOiBFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KTogZXhwcmVzc2lvbiBpcyBDb25jYXRFeHByZXNzaW9uIHtcblx0cmV0dXJuIChleHByZXNzaW9uIGFzIEJhc2VFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KS5fdHlwZSA9PT0gXCJJZkVsc2VcIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gcHJvdmlkZWQgaXMgYSBjb21wYXJpc29uIG9yIG5vdC5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGV4cHJlc3Npb24gaXMgYSBDb21wYXJpc29uRXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBpc0NvbXBhcmlzb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IEV4cHJlc3Npb248VD4pOiBleHByZXNzaW9uIGlzIENvbXBhcmlzb25FeHByZXNzaW9uIHtcblx0cmV0dXJuIGV4cHJlc3Npb24uX3R5cGUgPT09IFwiQ29tcGFyaXNvblwiO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBpbnB1dCBwYXJhbWV0ZXIgaXMgYSBjb25zdGFudCBleHByZXNzaW9uIG9mIHR5cGUgdW5kZWZpbmVkLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBpbnB1dCBleHByZXNzaW9uIG9yIG9iamVjdCBpbiBnZW5lcmFsXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGlucHV0IGlzIGNvbnN0YW50IHdoaWNoIGhhcyB1bmRlZmluZWQgZm9yIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1VuZGVmaW5lZEV4cHJlc3Npb24oZXhwcmVzc2lvbjogdW5rbm93bik6IGV4cHJlc3Npb24gaXMgQ29uc3RhbnRFeHByZXNzaW9uPHVuZGVmaW5lZD4ge1xuXHRjb25zdCBleHByZXNzaW9uQXNFeHByZXNzaW9uID0gZXhwcmVzc2lvbiBhcyBFeHByZXNzaW9uPHVua25vd24+O1xuXHRyZXR1cm4gZXhwcmVzc2lvbkFzRXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJDb25zdGFudFwiICYmIGV4cHJlc3Npb25Bc0V4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZDtcbn1cblxudHlwZSBDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb248UD4gPVxuXHR8IFBhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEFwcGx5QW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBJZkFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgT3JBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEFuZEFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgTmVBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEVxQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBOb3RBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEd0QW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBHZUFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgTGVBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IEx0QW5ub3RhdGlvbkV4cHJlc3Npb248UD47XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlT2JqZWN0KG9iamVjdFR5cGU6IG9iamVjdCk6IGJvb2xlYW4ge1xuXHRzd2l0Y2ggKG9iamVjdFR5cGUuY29uc3RydWN0b3IubmFtZSkge1xuXHRcdGNhc2UgXCJTdHJpbmdcIjpcblx0XHRjYXNlIFwiTnVtYmVyXCI6XG5cdFx0Y2FzZSBcIkJvb2xlYW5cIjpcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cbi8qKlxuICogQ2hlY2sgaWYgdGhlIHBhc3NlZCBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZSBpcyBhIENvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSAgYW5ub3RhdGlvblZhbHVlIFRoZSBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZSB0byBldmFsdWF0ZVxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3QgaXMgYSB7Q29tcGxleEFubm90YXRpb25FeHByZXNzaW9ufVxuICovXG5mdW5jdGlvbiBpc0NvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbjxUPihhbm5vdGF0aW9uVmFsdWU6IFByb3BlcnR5QW5ub3RhdGlvblZhbHVlPFQ+KTogYW5ub3RhdGlvblZhbHVlIGlzIENvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiB0eXBlb2YgYW5ub3RhdGlvblZhbHVlID09PSBcIm9iamVjdFwiICYmICFpc1ByaW1pdGl2ZU9iamVjdChhbm5vdGF0aW9uVmFsdWUgYXMgb2JqZWN0KTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBhbm5vdGF0aW9uVmFsdWUgZm9yIGEgZ2l2ZW4gYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWUuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gYW5ub3RhdGlvblZhbHVlIFRoZSBzb3VyY2UgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWVcbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzIFRoZSBwYXRoIGZyb20gdGhlIHJvb3QgZW50aXR5IHNldFxuICogQHBhcmFtIGRlZmF1bHRWYWx1ZSBEZWZhdWx0IHZhbHVlIGlmIHRoZSBhbm5vdGF0aW9uVmFsdWUgaXMgdW5kZWZpbmVkXG4gKiBAcGFyYW0gcGF0aFZpc2l0b3IgQSBmdW5jdGlvbiB0byBtb2RpZnkgdGhlIHJlc3VsdGluZyBwYXRoXG4gKiBAcmV0dXJucyBUaGUgYW5ub3RhdGlvblZhbHVlIGVxdWl2YWxlbnQgdG8gdGhhdCBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0YW5ub3RhdGlvblZhbHVlOiBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxUPiB8IHVuZGVmaW5lZCxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0ZGVmYXVsdFZhbHVlPzogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+PiB7XG5cdGlmIChhbm5vdGF0aW9uVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiB3cmFwUHJpbWl0aXZlKGRlZmF1bHRWYWx1ZSBhcyBQcmltaXRpdmVUeXBlQ2FzdDxUPik7XG5cdH1cblx0YW5ub3RhdGlvblZhbHVlID0gYW5ub3RhdGlvblZhbHVlLnZhbHVlT2YoKSBhcyBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxUPjtcblx0aWYgKCFpc0NvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbihhbm5vdGF0aW9uVmFsdWUpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGFubm90YXRpb25WYWx1ZSk7XG5cdH1cblxuXHRzd2l0Y2ggKGFubm90YXRpb25WYWx1ZS50eXBlKSB7XG5cdFx0Y2FzZSBcIlBhdGhcIjpcblx0XHRcdHJldHVybiBwYXRoSW5Nb2RlbChhbm5vdGF0aW9uVmFsdWUucGF0aCwgdW5kZWZpbmVkLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0Y2FzZSBcIklmXCI6XG5cdFx0XHRyZXR1cm4gYW5ub3RhdGlvbklmRXhwcmVzc2lvbihhbm5vdGF0aW9uVmFsdWUuJElmLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcikgYXMgRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIk5vdFwiOlxuXHRcdFx0cmV0dXJuIG5vdChwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLiROb3QsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSkgYXMgRXhwcmVzc2lvbjxcblx0XHRcdFx0UHJpbWl0aXZlVHlwZUNhc3Q8VD5cblx0XHRcdD47XG5cdFx0Y2FzZSBcIkVxXCI6XG5cdFx0XHRyZXR1cm4gZXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuJEVxWzBdISwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLiRFcVsxXSEsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdFx0KSBhcyBFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiTmVcIjpcblx0XHRcdHJldHVybiBub3RFcXVhbChcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS4kTmVbMF0hLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuJE5lWzFdISwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZUNhc3Q8VD4+O1xuXHRcdGNhc2UgXCJHdFwiOlxuXHRcdFx0cmV0dXJuIGdyZWF0ZXJUaGFuKFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLiRHdFswXSEsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS4kR3RbMV0hLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkdlXCI6XG5cdFx0XHRyZXR1cm4gZ3JlYXRlck9yRXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuJEdlWzBdISwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLiRHZVsxXSEsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdFx0KSBhcyBFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiTHRcIjpcblx0XHRcdHJldHVybiBsZXNzVGhhbihcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS4kTHRbMF0hLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuJEx0WzFdISwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZUNhc3Q8VD4+O1xuXHRcdGNhc2UgXCJMZVwiOlxuXHRcdFx0cmV0dXJuIGxlc3NPckVxdWFsKFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLiRMZVswXSEsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS4kTGVbMV0hLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIk9yXCI6XG5cdFx0XHRyZXR1cm4gb3IoXG5cdFx0XHRcdC4uLmFubm90YXRpb25WYWx1ZS4kT3IubWFwKGZ1bmN0aW9uIChvckNvbmRpdGlvbikge1xuXHRcdFx0XHRcdHJldHVybiBwYXJzZUFubm90YXRpb25Db25kaXRpb248Ym9vbGVhbj4ob3JDb25kaXRpb24sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcblx0XHRcdFx0fSlcblx0XHRcdCkgYXMgRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkFuZFwiOlxuXHRcdFx0cmV0dXJuIGFuZChcblx0XHRcdFx0Li4uYW5ub3RhdGlvblZhbHVlLiRBbmQubWFwKGZ1bmN0aW9uIChhbmRDb25kaXRpb24pIHtcblx0XHRcdFx0XHRyZXR1cm4gcGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uPGJvb2xlYW4+KGFuZENvbmRpdGlvbiwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KSBhcyBFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0XHRjYXNlIFwiQXBwbHlcIjpcblx0XHRcdHJldHVybiBhbm5vdGF0aW9uQXBwbHlFeHByZXNzaW9uKFxuXHRcdFx0XHRhbm5vdGF0aW9uVmFsdWUgYXMgQXBwbHlBbm5vdGF0aW9uRXhwcmVzc2lvbjxzdHJpbmc+LFxuXHRcdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0XHRwYXRoVmlzaXRvclxuXHRcdFx0KSBhcyBFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+Pjtcblx0fVxuXHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcbn1cblxuLyoqXG4gKiBQYXJzZSB0aGUgYW5ub3RhdGlvbiBjb25kaXRpb24gaW50byBhbiBleHByZXNzaW9uLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGFubm90YXRpb25WYWx1ZSBUaGUgY29uZGl0aW9uIG9yIHZhbHVlIGZyb20gdGhlIGFubm90YXRpb25cbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzIFRoZSBwYXRoIGZyb20gdGhlIHJvb3QgZW50aXR5IHNldFxuICogQHBhcmFtIHBhdGhWaXNpdG9yIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgQW4gZXF1aXZhbGVudCBleHByZXNzaW9uXG4gKi9cbmZ1bmN0aW9uIHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGFubm90YXRpb25WYWx1ZTogQ29uZGl0aW9uYWxDaGVja09yVmFsdWUsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM6IHN0cmluZ1tdID0gW10sXG5cdHBhdGhWaXNpdG9yPzogRnVuY3Rpb25cbik6IEV4cHJlc3Npb248VD4ge1xuXHRpZiAoYW5ub3RhdGlvblZhbHVlID09PSBudWxsIHx8IHR5cGVvZiBhbm5vdGF0aW9uVmFsdWUgIT09IFwib2JqZWN0XCIpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoYW5ub3RhdGlvblZhbHVlIGFzIFQpO1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRPclwiKSkge1xuXHRcdHJldHVybiBvcihcblx0XHRcdC4uLigoYW5ub3RhdGlvblZhbHVlIGFzIE9yQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kT3IubWFwKGZ1bmN0aW9uIChvckNvbmRpdGlvbikge1xuXHRcdFx0XHRyZXR1cm4gcGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKG9yQ29uZGl0aW9uLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0XHR9KSBhcyB1bmtub3duIGFzIEV4cHJlc3Npb248Ym9vbGVhbj5bXSlcblx0XHQpIGFzIEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEFuZFwiKSkge1xuXHRcdHJldHVybiBhbmQoXG5cdFx0XHQuLi4oKGFubm90YXRpb25WYWx1ZSBhcyBBbmRDb25kaXRpb25hbEV4cHJlc3Npb24pLiRBbmQubWFwKGZ1bmN0aW9uIChhbmRDb25kaXRpb24pIHtcblx0XHRcdFx0cmV0dXJuIHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbmRDb25kaXRpb24sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcblx0XHRcdH0pIGFzIHVua25vd24gYXMgRXhwcmVzc2lvbjxib29sZWFuPltdKVxuXHRcdCkgYXMgRXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkTm90XCIpKSB7XG5cdFx0cmV0dXJuIG5vdChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIE5vdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJE5vdCwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0KSBhcyBFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRFcVwiKSkge1xuXHRcdHJldHVybiBlcXVhbChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEVxQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kRXFbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEVxQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kRXFbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgRXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkTmVcIikpIHtcblx0XHRyZXR1cm4gbm90RXF1YWwoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBOZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJE5lWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBOZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJE5lWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEd0XCIpKSB7XG5cdFx0cmV0dXJuIGdyZWF0ZXJUaGFuKFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgR3RDb25kaXRpb25hbEV4cHJlc3Npb24pLiRHdFswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgR3RDb25kaXRpb25hbEV4cHJlc3Npb24pLiRHdFsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0KSBhcyBFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRHZVwiKSkge1xuXHRcdHJldHVybiBncmVhdGVyT3JFcXVhbChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEdlQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kR2VbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIEdlQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kR2VbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdCkgYXMgRXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkTHRcIikpIHtcblx0XHRyZXR1cm4gbGVzc1RoYW4oXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBMdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEx0WzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBMdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEx0WzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJExlXCIpKSB7XG5cdFx0cmV0dXJuIGxlc3NPckVxdWFsKFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgTGVDb25kaXRpb25hbEV4cHJlc3Npb24pLiRMZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgTGVDb25kaXRpb25hbEV4cHJlc3Npb24pLiRMZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0KSBhcyBFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRQYXRoXCIpKSB7XG5cdFx0cmV0dXJuIHBhdGhJbk1vZGVsKChhbm5vdGF0aW9uVmFsdWUgYXMgUGF0aENvbmRpdGlvbkV4cHJlc3Npb248VD4pLiRQYXRoLCB1bmRlZmluZWQsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCJQYXRoXCIpKSB7XG5cdFx0cmV0dXJuIHBhdGhJbk1vZGVsKChhbm5vdGF0aW9uVmFsdWUgYXMgdW5rbm93biBhcyB7IFBhdGg6IHN0cmluZyB9KS5QYXRoLCB1bmRlZmluZWQsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkQXBwbHlcIikpIHtcblx0XHRyZXR1cm4gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKFxuXHRcdFx0e1xuXHRcdFx0XHR0eXBlOiBcIkFwcGx5XCIsXG5cdFx0XHRcdCRGdW5jdGlvbjogKGFubm90YXRpb25WYWx1ZSBhcyB7ICRGdW5jdGlvbj86IHN0cmluZyB9KS4kRnVuY3Rpb24gYXMgXCJvZGF0YS5jb25jYXRcIixcblx0XHRcdFx0JEFwcGx5OiAoYW5ub3RhdGlvblZhbHVlIGFzIHsgJEFwcGx5PzogUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8VD5bXSB9KS4kQXBwbHkhXG5cdFx0XHR9IHNhdGlzZmllcyBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPFQ+LFxuXHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0KSBhcyBFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRJZlwiKSkge1xuXHRcdHJldHVybiBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24oXG5cdFx0XHR7XG5cdFx0XHRcdHR5cGU6IFwiSWZcIixcblx0XHRcdFx0JElmOiAoYW5ub3RhdGlvblZhbHVlIGFzIHsgJElmPzogSWZBbm5vdGF0aW9uRXhwcmVzc2lvblZhbHVlPFQ+IH0pLiRJZiFcblx0XHRcdH0gc2F0aXNmaWVzIElmQW5ub3RhdGlvbkV4cHJlc3Npb248VD4sXG5cdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0cGF0aFZpc2l0b3Jcblx0XHQpIGFzIEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEVudW1NZW1iZXJcIikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoKGFubm90YXRpb25WYWx1ZSBhcyB7ICRFbnVtTWVtYmVyPzogc3RyaW5nIH0pLiRFbnVtTWVtYmVyIGFzIFQpO1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIlN0cmluZ1wiKSkge1xuXHRcdHJldHVybiBjb25zdGFudCgoYW5ub3RhdGlvblZhbHVlIGFzIHVua25vd24gYXMgeyBTdHJpbmc6IHN0cmluZyB9KS5TdHJpbmcpIGFzIEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiQm9vbFwiKSkge1xuXHRcdHJldHVybiBjb25zdGFudCgoYW5ub3RhdGlvblZhbHVlIGFzIHVua25vd24gYXMgeyBCb29sOiBib29sZWFuIH0pLkJvb2wpIGFzIEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiSW50XCIpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KChhbm5vdGF0aW9uVmFsdWUgYXMgdW5rbm93biBhcyB7IEludDogbnVtYmVyIH0pLkludCkgYXMgRXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCJEZWNpbWFsXCIpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KChhbm5vdGF0aW9uVmFsdWUgYXMgdW5rbm93biBhcyB7IERlY2ltYWw6IG51bWJlciB9KS5EZWNpbWFsKSBhcyBFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcInR5cGVcIikgJiYgKGFubm90YXRpb25WYWx1ZSBhcyB1bmtub3duIGFzIHsgdHlwZTogc3RyaW5nIH0pLnR5cGUgPT09IFwiTnVsbFwiKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KG51bGwpIGFzIEV4cHJlc3Npb248VD47XG5cdH1cblx0cmV0dXJuIGNvbnN0YW50KGZhbHNlIGFzIFQpO1xufVxuXG4vKipcbiAqIFByb2Nlc3MgdGhlIHtJZkFubm90YXRpb25FeHByZXNzaW9uVmFsdWV9IGludG8gYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBhbm5vdGF0aW9uVmFsdWUgQW4gSWYgZXhwcmVzc2lvbiByZXR1cm5pbmcgdGhlIHR5cGUgVFxuICogQHBhcmFtIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMgVGhlIHBhdGggZnJvbSB0aGUgcm9vdCBlbnRpdHkgc2V0XG4gKiBAcGFyYW0gcGF0aFZpc2l0b3IgQSBmdW5jdGlvbiB0byBtb2RpZnkgdGhlIHJlc3VsdGluZyBwYXRoXG4gKiBAcmV0dXJucyBUaGUgZXF1aXZhbGVudCBpZkVsc2UgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5ub3RhdGlvbklmRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGFubm90YXRpb25WYWx1ZTogSWZBbm5vdGF0aW9uRXhwcmVzc2lvblZhbHVlPFQ+LFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBFeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIGlmRWxzZShcblx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZVsxXSBhcyBDb25kaXRpb25hbENoZWNrT3JWYWx1ZSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWVbMl0gYXMgQ29uZGl0aW9uYWxDaGVja09yVmFsdWUsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHQpO1xufVxuLy8gVGhpcyB0eXBlIGlzIG5vdCByZWN1cnNpdmVseSB0cmFuc2Zvcm1lZCBmcm9tIHRoZSBtZXRhbW9kZWwgY29udGVudCwgYXMgc3VjaCB3ZSBoYXZlIHNvbWUgdWdseSB0aGluZ3MgdGhlcmVcbnR5cGUgU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbCA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuZnVuY3Rpb24gY29udmVydFN1YkFwcGx5UGFyYW1ldGVycyhhcHBseVBhcmFtOiBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsKTogU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbCB7XG5cdGxldCBhcHBseVBhcmFtQ29udmVydGVkID0gYXBwbHlQYXJhbTtcblx0aWYgKGFwcGx5UGFyYW0uaGFzT3duUHJvcGVydHkoXCIkUGF0aFwiKSkge1xuXHRcdGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSB7XG5cdFx0XHR0eXBlOiBcIlBhdGhcIixcblx0XHRcdHBhdGg6IGFwcGx5UGFyYW0uJFBhdGggYXMgc3RyaW5nXG5cdFx0fSBzYXRpc2ZpZXMgUGFydGlhbDxQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb248c3RyaW5nPj47XG5cdH0gZWxzZSBpZiAoYXBwbHlQYXJhbS5oYXNPd25Qcm9wZXJ0eShcIiRJZlwiKSkge1xuXHRcdGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSB7XG5cdFx0XHR0eXBlOiBcIklmXCIsXG5cdFx0XHQkSWY6IGFwcGx5UGFyYW0uJElmIGFzIElmQW5ub3RhdGlvbkV4cHJlc3Npb25WYWx1ZTxzdHJpbmc+XG5cdFx0fSBzYXRpc2ZpZXMgSWZBbm5vdGF0aW9uRXhwcmVzc2lvbjxzdHJpbmc+O1xuXHR9IGVsc2UgaWYgKGFwcGx5UGFyYW0uaGFzT3duUHJvcGVydHkoXCIkQXBwbHlcIikpIHtcblx0XHRhcHBseVBhcmFtQ29udmVydGVkID0ge1xuXHRcdFx0dHlwZTogXCJBcHBseVwiLFxuXHRcdFx0JEZ1bmN0aW9uOiBhcHBseVBhcmFtLiRGdW5jdGlvbiBhcyBcIm9kYXRhLmNvbmNhdFwiLFxuXHRcdFx0JEFwcGx5OiBhcHBseVBhcmFtLiRBcHBseSBhcyBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxzdHJpbmc+W11cblx0XHR9IHNhdGlzZmllcyBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPHN0cmluZz47XG5cdH1cblx0cmV0dXJuIGFwcGx5UGFyYW1Db252ZXJ0ZWQ7XG59XG5cbnR5cGUgT0RhdGFGdW5jdGlvbiA9IFwib2RhdGEuY29uY2F0XCIgfCBcIm9kYXRhLmZpbGxVcmlUZW1wbGF0ZVwiIHwgXCJvZGF0YS51cmlFbmNvZGVcIjtcbmV4cG9ydCBmdW5jdGlvbiBhbm5vdGF0aW9uQXBwbHlFeHByZXNzaW9uKFxuXHRhcHBseUV4cHJlc3Npb246IEFwcGx5QW5ub3RhdGlvbkV4cHJlc3Npb248c3RyaW5nPixcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogRXhwcmVzc2lvbjxzdHJpbmc+IHtcblx0c3dpdGNoIChhcHBseUV4cHJlc3Npb24uJEZ1bmN0aW9uIGFzIE9EYXRhRnVuY3Rpb24pIHtcblx0XHRjYXNlIFwib2RhdGEuY29uY2F0XCI6XG5cdFx0XHRyZXR1cm4gY29uY2F0KFxuXHRcdFx0XHQuLi5hcHBseUV4cHJlc3Npb24uJEFwcGx5Lm1hcCgoYXBwbHlQYXJhbSkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24oXG5cdFx0XHRcdFx0XHRjb252ZXJ0U3ViQXBwbHlQYXJhbWV0ZXJzKGFwcGx5UGFyYW0pIGFzIFByb3BlcnR5QW5ub3RhdGlvblZhbHVlPHN0cmluZz4sXG5cdFx0XHRcdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0XHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0XHRcdFx0cGF0aFZpc2l0b3Jcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KTtcblx0XHRjYXNlIFwib2RhdGEudXJpRW5jb2RlXCI6XG5cdFx0XHRjb25zdCBwYXJhbWV0ZXIgPSBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24oXG5cdFx0XHRcdGNvbnZlcnRTdWJBcHBseVBhcmFtZXRlcnMoXG5cdFx0XHRcdFx0YXBwbHlFeHByZXNzaW9uLiRBcHBseVswXSBhcyB1bmtub3duIGFzIFN1YkFwcGx5RXhwcmVzc2lvbkZyb21NZXRhbW9kZWxcblx0XHRcdFx0KSBhcyBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxzdHJpbmc+LFxuXHRcdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0XHQpO1xuXHRcdFx0Ly8gVGhlIHNlY29uZCBwYXJhbWV0ZXIgZm9yIHVyaUVuY29kZSBpcyBhbHdheXMgYSBzdHJpbmcgc2luY2UgdGhlIHRhcmdldCBldmFsdWF0aW9uIGlzIGFnYWluc3QgYSBmb3JtYXRWYWx1ZSBjYWxsIGluIE9EYXRhVXRpbHMgd2hpY2ggZXhwZWN0IHRoZSB0YXJnZXQgdHlwZSBhcyBzZWNvbmQgcGFyYW1ldGVyXG5cdFx0XHRyZXR1cm4gZm4oXCJvZGF0YS51cmlFbmNvZGVcIiwgW3BhcmFtZXRlciwgXCJFZG0uU3RyaW5nXCJdLCB1bmRlZmluZWQsIHRydWUpO1xuXHRcdGNhc2UgXCJvZGF0YS5maWxsVXJpVGVtcGxhdGVcIjpcblx0XHRcdGNvbnN0IHRlbXBsYXRlID0gYXBwbHlFeHByZXNzaW9uLiRBcHBseVswXTtcblx0XHRcdGNvbnN0IHRlbXBsYXRlUGFyYW1zID0gYXBwbHlFeHByZXNzaW9uLiRBcHBseS5zbGljZSgxKSBhcyB1bmtub3duIGFzIFN1YkFwcGx5RXhwcmVzc2lvbkZyb21NZXRhbW9kZWxbXTtcblx0XHRcdGNvbnN0IHRhcmdldE9iamVjdDogUmVjb3JkPHN0cmluZywgRXhwcmVzc2lvbjx1bmtub3duPj4gPSB7fTtcblx0XHRcdHRlbXBsYXRlUGFyYW1zLmZvckVhY2goKGFwcGx5UGFyYW0pID0+IHtcblx0XHRcdFx0dGFyZ2V0T2JqZWN0W2FwcGx5UGFyYW0uJE5hbWUgYXMgc3RyaW5nXSA9IGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdFx0XHRjb252ZXJ0U3ViQXBwbHlQYXJhbWV0ZXJzKFxuXHRcdFx0XHRcdFx0YXBwbHlQYXJhbS4kTGFiZWxlZEVsZW1lbnQgYXMgU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbFxuXHRcdFx0XHRcdCkgYXMgUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8c3RyaW5nPixcblx0XHRcdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdFx0XHRwYXRoVmlzaXRvclxuXHRcdFx0XHQpO1xuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gZm4oXCJvZGF0YS5maWxsVXJpVGVtcGxhdGVcIiwgW3RlbXBsYXRlLCB0YXJnZXRPYmplY3RdLCB1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xufVxuXG4vKipcbiAqIEdlbmVyaWMgaGVscGVyIGZvciB0aGUgY29tcGFyaXNvbiBvcGVyYXRpb25zIChlcXVhbCwgbm90RXF1YWwsIC4uLikuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gb3BlcmF0b3IgVGhlIG9wZXJhdG9yIHRvIGFwcGx5XG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZSBvZiB0aGUgb3BlcmF0b3JcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIG9wZXJhdG9yXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5mdW5jdGlvbiBjb21wYXJpc29uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0b3BlcmF0b3I6IENvbXBhcmlzb25PcGVyYXRvcixcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRjb25zdCBsZWZ0RXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUobGVmdE9wZXJhbmQpO1xuXHRjb25zdCByaWdodEV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKHJpZ2h0T3BlcmFuZCk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKGxlZnRFeHByZXNzaW9uLCByaWdodEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0aWYgKGlzQ29uc3RhbnQobGVmdEV4cHJlc3Npb24pICYmIGlzQ29uc3RhbnQocmlnaHRFeHByZXNzaW9uKSkge1xuXHRcdHN3aXRjaCAob3BlcmF0b3IpIHtcblx0XHRcdGNhc2UgXCIhPT1cIjpcblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlICE9PSByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIj09PVwiOlxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPT09IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPFwiOlxuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWRcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPCByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIjw9XCI6XG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA8PSByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIj5cIjpcblx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZCB8fFxuXHRcdFx0XHRcdHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiBjb25zdGFudChmYWxzZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlID4gcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHRcdGNhc2UgXCI+PVwiOlxuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWRcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPj0gcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIkNvbXBhcmlzb25cIixcblx0XHRcdG9wZXJhdG9yOiBvcGVyYXRvcixcblx0XHRcdG9wZXJhbmQxOiBsZWZ0RXhwcmVzc2lvbixcblx0XHRcdG9wZXJhbmQyOiByaWdodEV4cHJlc3Npb25cblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogR2VuZXJpYyBoZWxwZXIgZm9yIHRoZSBsZW5ndGggb2YgYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgaW5wdXQgZXhwcmVzc2lvbiBwb2ludGluZyB0byBhbiBhcnJheVxuICogQHBhcmFtIGNoZWNrVW5kZWZpbmVkIElzIHRoZSBhcnJheSBwb3RlbnRpYWxseSB1bmRlZmluZWRcbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBsZW5ndGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxlbmd0aChcblx0ZXhwcmVzc2lvbjogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+IHwgVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24sXG5cdGNoZWNrVW5kZWZpbmVkID0gZmFsc2Vcbik6IEV4cHJlc3Npb248bnVtYmVyPiB7XG5cdGlmIChleHByZXNzaW9uLl90eXBlID09PSBcIlVucmVzb2x2YWJsZVwiKSB7XG5cdFx0cmV0dXJuIGV4cHJlc3Npb247XG5cdH1cblx0aWYgKCFjaGVja1VuZGVmaW5lZCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHRfdHlwZTogXCJMZW5ndGhcIixcblx0XHRcdHBhdGhJbk1vZGVsOiBleHByZXNzaW9uXG5cdFx0fTtcblx0fVxuXHRyZXR1cm4gaWZFbHNlKGVxdWFsKGV4cHJlc3Npb24sIHVuZGVmaW5lZCksIC0xLCBsZW5ndGgoZXhwcmVzc2lvbikpO1xufVxuXG4vKipcbiAqIENvbXBhcmlzb246IFwiZXF1YWxcIiAoPT09KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZXF1YWw8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogRXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGNvbnN0IGxlZnRFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShsZWZ0T3BlcmFuZCk7XG5cdGNvbnN0IHJpZ2h0RXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUocmlnaHRPcGVyYW5kKTtcblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24obGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChsZWZ0RXhwcmVzc2lvbiwgcmlnaHRFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBjb25zdGFudCh0cnVlKTtcblx0fVxuXG5cdGZ1bmN0aW9uIHJlZHVjZShsZWZ0OiBFeHByZXNzaW9uPFQ+LCByaWdodDogRXhwcmVzc2lvbjxUPik6IEV4cHJlc3Npb248Ym9vbGVhbj4gfCB1bmRlZmluZWQge1xuXHRcdGlmIChsZWZ0Ll90eXBlID09PSBcIkNvbXBhcmlzb25cIiAmJiBpc1RydWUocmlnaHQpKSB7XG5cdFx0XHQvLyBjb21wYXJlKGEsIGIpID09PSB0cnVlIH5+PiBjb21wYXJlKGEsIGIpXG5cdFx0XHRyZXR1cm4gbGVmdDtcblx0XHR9IGVsc2UgaWYgKGxlZnQuX3R5cGUgPT09IFwiQ29tcGFyaXNvblwiICYmIGlzRmFsc2UocmlnaHQpKSB7XG5cdFx0XHQvLyBjb21wYXJlKGEsIGIpID09PSBmYWxzZSB+fj4gIWNvbXBhcmUoYSwgYilcblx0XHRcdHJldHVybiBub3QobGVmdCk7XG5cdFx0fSBlbHNlIGlmIChsZWZ0Ll90eXBlID09PSBcIklmRWxzZVwiICYmIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwobGVmdC5vblRydWUsIHJpZ2h0KSkge1xuXHRcdFx0Ly8gKGlmICh4KSB7IGEgfSBlbHNlIHsgYiB9KSA9PT0gYSB+fj4geCB8fCAoYiA9PT0gYSlcblx0XHRcdHJldHVybiBvcihsZWZ0LmNvbmRpdGlvbiwgZXF1YWwobGVmdC5vbkZhbHNlLCByaWdodCkpO1xuXHRcdH0gZWxzZSBpZiAobGVmdC5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25GYWxzZSwgcmlnaHQpKSB7XG5cdFx0XHQvLyAoaWYgKHgpIHsgYSB9IGVsc2UgeyBiIH0pID09PSBiIH5+PiAheCB8fCAoYSA9PT0gYilcblx0XHRcdHJldHVybiBvcihub3QobGVmdC5jb25kaXRpb24pLCBlcXVhbChsZWZ0Lm9uVHJ1ZSwgcmlnaHQpKTtcblx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0bGVmdC5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJlxuXHRcdFx0aXNDb25zdGFudChsZWZ0Lm9uVHJ1ZSkgJiZcblx0XHRcdGlzQ29uc3RhbnQobGVmdC5vbkZhbHNlKSAmJlxuXHRcdFx0aXNDb25zdGFudChyaWdodCkgJiZcblx0XHRcdCFfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25UcnVlLCByaWdodCkgJiZcblx0XHRcdCFfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25GYWxzZSwgcmlnaHQpXG5cdFx0KSB7XG5cdFx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHRcdH1cblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cblx0Ly8gZXhwbG9pdCBzeW1tZXRyeTogYSA9PT0gYiA8fj4gYiA9PT0gYVxuXHRjb25zdCByZWR1Y2VkID0gcmVkdWNlKGxlZnRFeHByZXNzaW9uLCByaWdodEV4cHJlc3Npb24pID8/IHJlZHVjZShyaWdodEV4cHJlc3Npb24sIGxlZnRFeHByZXNzaW9uKTtcblx0cmV0dXJuIHJlZHVjZWQgPz8gY29tcGFyaXNvbihcIj09PVwiLCBsZWZ0RXhwcmVzc2lvbiwgcmlnaHRFeHByZXNzaW9uKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcIm5vdCBlcXVhbFwiICghPT0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3RFcXVhbDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0cmV0dXJuIG5vdChlcXVhbChsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKSk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJncmVhdGVyIG9yIGVxdWFsXCIgKD49KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JlYXRlck9yRXF1YWw8VCBleHRlbmRzIERlZmluZWRQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRyZXR1cm4gY29tcGFyaXNvbihcIj49XCIsIGxlZnRPcGVyYW5kLCByaWdodE9wZXJhbmQpO1xufVxuXG4vKipcbiAqIENvbXBhcmlzb246IFwiZ3JlYXRlciB0aGFuXCIgKD4pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBncmVhdGVyVGhhbjxUIGV4dGVuZHMgRGVmaW5lZFByaW1pdGl2ZVR5cGU+KFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogRXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPlwiLCBsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImxlc3Mgb3IgZXF1YWxcIiAoPD0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsZXNzT3JFcXVhbDxUIGV4dGVuZHMgRGVmaW5lZFByaW1pdGl2ZVR5cGU+KFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogRXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPD1cIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJsZXNzIHRoYW5cIiAoPCkuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZVxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgY29tcGFyaXNvblxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxlc3NUaGFuPFQgZXh0ZW5kcyBEZWZpbmVkUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0cmV0dXJuIGNvbXBhcmlzb24oXCI8XCIsIGxlZnRPcGVyYW5kLCByaWdodE9wZXJhbmQpO1xufVxuXG4vKipcbiAqIElmLXRoZW4tZWxzZSBleHByZXNzaW9uLlxuICpcbiAqIEV2YWx1YXRlcyB0byBvblRydWUgaWYgdGhlIGNvbmRpdGlvbiBldmFsdWF0ZXMgdG8gdHJ1ZSwgZWxzZSBldmFsdWF0ZXMgdG8gb25GYWxzZS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBjb25kaXRpb24gVGhlIGNvbmRpdGlvbiB0byBldmFsdWF0ZVxuICogQHBhcmFtIG9uVHJ1ZSBFeHByZXNzaW9uIHJlc3VsdCBpZiB0aGUgY29uZGl0aW9uIGV2YWx1YXRlcyB0byB0cnVlXG4gKiBAcGFyYW0gb25GYWxzZSBFeHByZXNzaW9uIHJlc3VsdCBpZiB0aGUgY29uZGl0aW9uIGV2YWx1YXRlcyB0byBmYWxzZVxuICogQHJldHVybnMgVGhlIGV4cHJlc3Npb24gdGhhdCByZXByZXNlbnRzIHRoaXMgY29uZGl0aW9uYWwgY2hlY2tcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlmRWxzZTxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGNvbmRpdGlvbjogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPGJvb2xlYW4+LFxuXHRvblRydWU6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0b25GYWxzZTogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBFeHByZXNzaW9uPFQ+IHtcblx0bGV0IGNvbmRpdGlvbkV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKGNvbmRpdGlvbik7XG5cdGxldCBvblRydWVFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShvblRydWUpO1xuXHRsZXQgb25GYWxzZUV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKG9uRmFsc2UpO1xuXG5cdC8vIHN3YXAgYnJhbmNoZXMgaWYgdGhlIGNvbmRpdGlvbiBpcyBhIG5lZ2F0aW9uXG5cdGlmIChjb25kaXRpb25FeHByZXNzaW9uLl90eXBlID09PSBcIk5vdFwiKSB7XG5cdFx0Ly8gaWZFbHNlKG5vdChYKSwgYSwgYikgLS0+IGlmRWxzZShYLCBiLCBhKVxuXHRcdFtvblRydWVFeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbl0gPSBbb25GYWxzZUV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb25dO1xuXHRcdGNvbmRpdGlvbkV4cHJlc3Npb24gPSBub3QoY29uZGl0aW9uRXhwcmVzc2lvbik7XG5cdH1cblxuXHQvLyBpbmxpbmUgbmVzdGVkIGlmLWVsc2UgZXhwcmVzc2lvbnM6IG9uVHJ1ZSBicmFuY2hcblx0Ly8gaWZFbHNlKFgsIGlmRWxzZShYLCBhLCBiKSwgYykgPT0+IGlmRWxzZShYLCBhLCBjKVxuXHRpZiAob25UcnVlRXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb24uY29uZGl0aW9uKSkge1xuXHRcdG9uVHJ1ZUV4cHJlc3Npb24gPSBvblRydWVFeHByZXNzaW9uLm9uVHJ1ZTtcblx0fVxuXG5cdC8vIGlubGluZSBuZXN0ZWQgaWYtZWxzZSBleHByZXNzaW9uczogb25GYWxzZSBicmFuY2hcblx0Ly8gaWZFbHNlKFgsIGEsIGlmRWxzZShYLCBiLCBjKSkgPT0+IGlmRWxzZShYLCBhLCBjKVxuXHRpZiAob25GYWxzZUV4cHJlc3Npb24uX3R5cGUgPT09IFwiSWZFbHNlXCIgJiYgX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChjb25kaXRpb25FeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbi5jb25kaXRpb24pKSB7XG5cdFx0b25GYWxzZUV4cHJlc3Npb24gPSBvbkZhbHNlRXhwcmVzc2lvbi5vbkZhbHNlO1xuXHR9XG5cblx0Ly8gKGlmIHRydWUgdGhlbiBhIGVsc2UgYikgIH5+PiBhXG5cdC8vIChpZiBmYWxzZSB0aGVuIGEgZWxzZSBiKSB+fj4gYlxuXHRpZiAoaXNDb25zdGFudChjb25kaXRpb25FeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBjb25kaXRpb25FeHByZXNzaW9uLnZhbHVlID8gb25UcnVlRXhwcmVzc2lvbiA6IG9uRmFsc2VFeHByZXNzaW9uO1xuXHR9XG5cblx0Ly8gaWYgKGlzQ29uc3RhbnRCb29sZWFuKG9uVHJ1ZUV4cHJlc3Npb24pIHx8IGlzQ29uc3RhbnRCb29sZWFuKG9uRmFsc2VFeHByZXNzaW9uKSkge1xuXHQvLyBcdHJldHVybiBvcihhbmQoY29uZGl0aW9uLCBvblRydWVFeHByZXNzaW9uIGFzIEV4cHJlc3Npb248Ym9vbGVhbj4pLCBhbmQobm90KGNvbmRpdGlvbiksIG9uRmFsc2VFeHByZXNzaW9uIGFzIEV4cHJlc3Npb248Ym9vbGVhbj4pKSBhcyBFeHByZXNzaW9uPFQ+XG5cdC8vIH1cblxuXHQvLyAoaWYgWCB0aGVuIGEgZWxzZSBhKSB+fj4gYVxuXHRpZiAoX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChvblRydWVFeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gb25UcnVlRXhwcmVzc2lvbjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiBhIGVsc2UgZmFsc2Ugfn4+IFggJiYgYVxuXHRpZiAoaXNGYWxzZShvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gYW5kKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb24gYXMgRXhwcmVzc2lvbjxib29sZWFuPikgYXMgRXhwcmVzc2lvbjxUPjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiBhIGVsc2UgdHJ1ZSB+fj4gIVggfHwgYVxuXHRpZiAoaXNUcnVlKG9uRmFsc2VFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBvcihub3QoY29uZGl0aW9uRXhwcmVzc2lvbiksIG9uVHJ1ZUV4cHJlc3Npb24gYXMgRXhwcmVzc2lvbjxib29sZWFuPikgYXMgRXhwcmVzc2lvbjxUPjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiBmYWxzZSBlbHNlIGEgfn4+ICFYICYmIGFcblx0aWYgKGlzRmFsc2Uob25UcnVlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gYW5kKG5vdChjb25kaXRpb25FeHByZXNzaW9uKSwgb25GYWxzZUV4cHJlc3Npb24gYXMgRXhwcmVzc2lvbjxib29sZWFuPikgYXMgRXhwcmVzc2lvbjxUPjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiB0cnVlIGVsc2UgYSB+fj4gWCB8fCBhXG5cdGlmIChpc1RydWUob25UcnVlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gb3IoY29uZGl0aW9uRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24gYXMgRXhwcmVzc2lvbjxib29sZWFuPikgYXMgRXhwcmVzc2lvbjxUPjtcblx0fVxuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbihjb25kaXRpb25FeHByZXNzaW9uLCBvblRydWVFeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoaXNDb21wbGV4VHlwZUV4cHJlc3Npb24oY29uZGl0aW9uKSB8fCBpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbihvblRydWUpIHx8IGlzQ29tcGxleFR5cGVFeHByZXNzaW9uKG9uRmFsc2UpKSB7XG5cdFx0bGV0IHBhdGhJZHggPSAwO1xuXHRcdGNvbnN0IG15SWZFbHNlRXhwcmVzc2lvbiA9IGZvcm1hdFJlc3VsdChbY29uZGl0aW9uLCBvblRydWUsIG9uRmFsc2VdLCBcInNhcC5mZS5jb3JlLmZvcm1hdHRlcnMuU3RhbmRhcmRGb3JtYXR0ZXIjaWZFbHNlXCIpO1xuXHRcdGNvbnN0IGFsbFBhcnRzID0gW107XG5cdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRteUlmRWxzZUV4cHJlc3Npb24gYXMgRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPixcblx0XHRcdFwiUGF0aEluTW9kZWxcIixcblx0XHRcdChjb25zdGFudFBhdGg6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjx1bmtub3duPikgPT4ge1xuXHRcdFx0XHRhbGxQYXJ0cy5wdXNoKGNvbnN0YW50UGF0aCk7XG5cdFx0XHRcdHJldHVybiBwYXRoSW5Nb2RlbChgJCR7cGF0aElkeCsrfWAsIFwiJFwiKTtcblx0XHRcdH0sXG5cdFx0XHR0cnVlXG5cdFx0KTtcblx0XHRhbGxQYXJ0cy51bnNoaWZ0KGNvbnN0YW50KEpTT04uc3RyaW5naWZ5KG15SWZFbHNlRXhwcmVzc2lvbikpKTtcblx0XHRyZXR1cm4gZm9ybWF0UmVzdWx0KGFsbFBhcnRzLCBcInNhcC5mZS5jb3JlLmZvcm1hdHRlcnMuU3RhbmRhcmRGb3JtYXR0ZXIjZXZhbHVhdGVDb21wbGV4RXhwcmVzc2lvblwiLCB1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiSWZFbHNlXCIsXG5cdFx0Y29uZGl0aW9uOiBjb25kaXRpb25FeHByZXNzaW9uLFxuXHRcdG9uVHJ1ZTogb25UcnVlRXhwcmVzc2lvbixcblx0XHRvbkZhbHNlOiBvbkZhbHNlRXhwcmVzc2lvblxuXHR9O1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBjdXJyZW50IGV4cHJlc3Npb24gaGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBkZWZhdWx0IG1vZGVsICh1bmRlZmluZWQpLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uIHRvIGV2YWx1YXRlXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlcmUgaXMgYSByZWZlcmVuY2UgdG8gdGhlIGRlZmF1bHQgY29udGV4dFxuICovXG5mdW5jdGlvbiBoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb246IEV4cHJlc3Npb248dW5rbm93bj4pOiBib29sZWFuIHtcblx0c3dpdGNoIChleHByZXNzaW9uLl90eXBlKSB7XG5cdFx0Y2FzZSBcIkNvbnN0YW50XCI6XG5cdFx0Y2FzZSBcIkZvcm1hdHRlclwiOlxuXHRcdGNhc2UgXCJDb21wbGV4VHlwZVwiOlxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdGNhc2UgXCJTZXRcIjpcblx0XHRcdHJldHVybiBleHByZXNzaW9uLm9wZXJhbmRzLnNvbWUoaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dCk7XG5cdFx0Y2FzZSBcIlBhdGhJbk1vZGVsXCI6XG5cdFx0XHRyZXR1cm4gZXhwcmVzc2lvbi5tb2RlbE5hbWUgPT09IHVuZGVmaW5lZDtcblx0XHRjYXNlIFwiQ29tcGFyaXNvblwiOlxuXHRcdFx0cmV0dXJuIGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5vcGVyYW5kMSkgfHwgaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLm9wZXJhbmQyKTtcblx0XHRjYXNlIFwiSWZFbHNlXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24uY29uZGl0aW9uKSB8fFxuXHRcdFx0XHRoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24ub25UcnVlKSB8fFxuXHRcdFx0XHRoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24ub25GYWxzZSlcblx0XHRcdCk7XG5cdFx0Y2FzZSBcIk5vdFwiOlxuXHRcdGNhc2UgXCJUcnV0aHlcIjpcblx0XHRcdHJldHVybiBoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24ub3BlcmFuZCk7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG4vLyBUaGlzIGlzIG9uZSBjYXNlIHdoZXJlIGFueSBkb2VzIG1ha2Ugc2Vuc2UuLi5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5leHBvcnQgdHlwZSBGbjxUPiA9ICgoLi4ucGFyYW1zOiBhbnkpID0+IFQgfCBQcm9taXNlPFQ+KSAmIHtcblx0X19mdW5jdGlvbk5hbWU6IHN0cmluZztcbn07XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnRcbi8vIEB0cy1pZ25vcmVcbnR5cGUgV3JhcHBlZFR1cGxlPFQ+ID0ge1xuXHRbSyBpbiBrZXlvZiBUXTpcblx0XHR8IFdyYXBwZWRUdXBsZTxUW0tdPlxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnRcblx0XHQvLyBAdHMtaWdub3JlXG5cdFx0fCBFeHByZXNzaW9uT3JQcmltaXRpdmU8VFtLXT5cblx0XHR8IHVuZGVmaW5lZDtcbn07XG5cbi8vIFNvLCB0aGlzIHdvcmtzIGJ1dCBJIGNhbm5vdCBnZXQgaXQgdG8gY29tcGlsZSA6RCwgYnV0IGl0IHN0aWxsIGRvZXMgd2hhdCBpcyBleHBlY3RlZC4uLlxuXG4vKipcbiAqIEEgZnVuY3Rpb24gcmVmZXJlbmNlIG9yIGEgZnVuY3Rpb24gbmFtZS5cbiAqL1xudHlwZSBGdW5jdGlvbk9yTmFtZTxUPiA9IEZuPFQ+IHwgc3RyaW5nO1xuXG4vKipcbiAqIEZ1bmN0aW9uIHBhcmFtZXRlcnMsIGVpdGhlciBkZXJpdmVkIGZyb20gdGhlIGZ1bmN0aW9uIG9yIGFuIHVudHlwZWQgYXJyYXkuXG4gKi9cbnR5cGUgRnVuY3Rpb25QYXJhbWV0ZXJzPFQsIEYgZXh0ZW5kcyBGdW5jdGlvbk9yTmFtZTxUPj4gPSBGIGV4dGVuZHMgRm48VD4gPyBQYXJhbWV0ZXJzPEY+IDogdW5rbm93bltdO1xuXG4vKipcbiAqIENhbGxzIGEgZm9ybWF0dGVyIGZ1bmN0aW9uIHRvIHByb2Nlc3MgdGhlIHBhcmFtZXRlcnMuXG4gKiBJZiByZXF1aXJlQ29udGV4dCBpcyBzZXQgdG8gdHJ1ZSBhbmQgbm8gY29udGV4dCBpcyBwYXNzZWQgYSBkZWZhdWx0IGNvbnRleHQgd2lsbCBiZSBhZGRlZCBhdXRvbWF0aWNhbGx5LlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdGVtcGxhdGUgVVxuICogQHBhcmFtIHBhcmFtZXRlcnMgVGhlIGxpc3Qgb2YgcGFyYW1ldGVyIHRoYXQgc2hvdWxkIG1hdGNoIHRoZSB0eXBlIGFuZCBudW1iZXIgb2YgdGhlIGZvcm1hdHRlciBmdW5jdGlvblxuICogQHBhcmFtIGZvcm1hdHRlckZ1bmN0aW9uIFRoZSBmdW5jdGlvbiB0byBjYWxsXG4gKiBAcGFyYW0gW2NvbnRleHRFbnRpdHlUeXBlXSBJZiBubyBwYXJhbWV0ZXIgcmVmZXJzIHRvIHRoZSBjb250ZXh0IHRoZW4gd2UgdXNlIHRoaXMgaW5mb3JtYXRpb24gdG8gYWRkIGEgcmVmZXJlbmNlIHRvIHRoZSBrZXlzIGZyb20gdGhlIGVudGl0eSB0eXBlLlxuICogQHBhcmFtIFtpZ25vcmVDb21wbGV4VHlwZV0gV2hldGhlciB0byBpZ25vcmUgdGhlIHRyYW5zZ2Zvcm1hdGlvbiB0byB0aGUgU3RhbmRhcmRGb3JtYXR0ZXIgb3Igbm90XG4gKiBAcmV0dXJucyBUaGUgY29ycmVzcG9uZGluZyBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRSZXN1bHQ8VCwgVSBleHRlbmRzIEZuPFQ+Pihcblx0cGFyYW1ldGVyczogV3JhcHBlZFR1cGxlPFBhcmFtZXRlcnM8VT4+LFxuXHRmb3JtYXR0ZXJGdW5jdGlvbjogVSB8IHN0cmluZyxcblx0Y29udGV4dEVudGl0eVR5cGU/OiBFbnRpdHlUeXBlLFxuXHRpZ25vcmVDb21wbGV4VHlwZSA9IGZhbHNlXG4pOiBFeHByZXNzaW9uPFQ+IHtcblx0Y29uc3QgcGFyYW1ldGVyRXhwcmVzc2lvbnMgPSAocGFyYW1ldGVycyBhcyBFeHByZXNzaW9uT3JQcmltaXRpdmU8UHJpbWl0aXZlVHlwZT5bXSkubWFwKHdyYXBQcmltaXRpdmUpO1xuXG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLnBhcmFtZXRlckV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGlmIChjb250ZXh0RW50aXR5VHlwZSkge1xuXHRcdC8vIE90aGVyd2lzZSwgaWYgdGhlIGNvbnRleHQgaXMgcmVxdWlyZWQgYW5kIG5vIGNvbnRleHQgaXMgcHJvdmlkZWQgbWFrZSBzdXJlIHRvIGFkZCB0aGUgZGVmYXVsdCBiaW5kaW5nXG5cdFx0aWYgKCFwYXJhbWV0ZXJFeHByZXNzaW9ucy5zb21lKGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQpKSB7XG5cdFx0XHRjb250ZXh0RW50aXR5VHlwZS5rZXlzLmZvckVhY2goKGtleSkgPT4gcGFyYW1ldGVyRXhwcmVzc2lvbnMucHVzaChwYXRoSW5Nb2RlbChrZXkubmFtZSwgXCJcIikpKTtcblx0XHR9XG5cdH1cblx0bGV0IGZ1bmN0aW9uTmFtZSA9IFwiXCI7XG5cdGlmICh0eXBlb2YgZm9ybWF0dGVyRnVuY3Rpb24gPT09IFwic3RyaW5nXCIpIHtcblx0XHRmdW5jdGlvbk5hbWUgPSBmb3JtYXR0ZXJGdW5jdGlvbjtcblx0fSBlbHNlIHtcblx0XHRmdW5jdGlvbk5hbWUgPSBmb3JtYXR0ZXJGdW5jdGlvbi5fX2Z1bmN0aW9uTmFtZTtcblx0fVxuXHQvLyBGb3JtYXR0ZXJOYW1lIGNhbiBiZSBvZiBmb3JtYXQgc2FwLmZlLmNvcmUueHh4I21ldGhvZE5hbWUgdG8gaGF2ZSBtdWx0aXBsZSBmb3JtYXR0ZXIgaW4gb25lIGNsYXNzXG5cdGNvbnN0IFtmb3JtYXR0ZXJDbGFzcywgZm9ybWF0dGVyTmFtZV0gPSBmdW5jdGlvbk5hbWUuc3BsaXQoXCIjXCIpO1xuXG5cdC8vIEluIHNvbWUgY2FzZSB3ZSBhbHNvIGNhbm5vdCBjYWxsIGRpcmVjdGx5IGEgZnVuY3Rpb24gYmVjYXVzZSBvZiB0b28gY29tcGxleCBpbnB1dCwgaW4gdGhhdCBjYXNlIHdlIG5lZWQgdG8gY29udmVydCB0byBhIHNpbXBsZXIgZnVuY3Rpb24gY2FsbFxuXHRpZiAoXG5cdFx0IWlnbm9yZUNvbXBsZXhUeXBlICYmXG5cdFx0KHBhcmFtZXRlckV4cHJlc3Npb25zLnNvbWUoaXNDb21wbGV4VHlwZUV4cHJlc3Npb24pIHx8XG5cdFx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5zb21lKGlzQ29uY2F0RXhwcmVzc2lvbikgfHxcblx0XHRcdHBhcmFtZXRlckV4cHJlc3Npb25zLnNvbWUoaXNJZkVsc2VFeHByZXNzaW9uKSlcblx0KSB7XG5cdFx0bGV0IHBhdGhJZHggPSAwO1xuXHRcdGNvbnN0IG15Rm9ybWF0RXhwcmVzc2lvbiA9IGZvcm1hdFJlc3VsdChwYXJhbWV0ZXJFeHByZXNzaW9ucywgZnVuY3Rpb25OYW1lLCB1bmRlZmluZWQsIHRydWUpO1xuXHRcdGNvbnN0IGFsbFBhcnRzID0gW107XG5cdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRteUZvcm1hdEV4cHJlc3Npb24gYXMgRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPixcblx0XHRcdFwiUGF0aEluTW9kZWxcIixcblx0XHRcdChjb25zdGFudFBhdGg6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjx1bmtub3duPikgPT4ge1xuXHRcdFx0XHRhbGxQYXJ0cy5wdXNoKGNvbnN0YW50UGF0aCk7XG5cdFx0XHRcdHJldHVybiBwYXRoSW5Nb2RlbChgJCR7cGF0aElkeCsrfWAsIFwiJFwiKTtcblx0XHRcdH0sXG5cdFx0XHR0cnVlXG5cdFx0KTtcblx0XHRhbGxQYXJ0cy51bnNoaWZ0KGNvbnN0YW50KEpTT04uc3RyaW5naWZ5KG15Rm9ybWF0RXhwcmVzc2lvbikpKTtcblx0XHRyZXR1cm4gZm9ybWF0UmVzdWx0KGFsbFBhcnRzLCBcInNhcC5mZS5jb3JlLmZvcm1hdHRlcnMuU3RhbmRhcmRGb3JtYXR0ZXIjZXZhbHVhdGVDb21wbGV4RXhwcmVzc2lvblwiLCB1bmRlZmluZWQsIHRydWUpO1xuXHR9IGVsc2UgaWYgKCEhZm9ybWF0dGVyTmFtZSAmJiBmb3JtYXR0ZXJOYW1lLmxlbmd0aCA+IDApIHtcblx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy51bnNoaWZ0KGNvbnN0YW50KGZvcm1hdHRlck5hbWUpKTtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiRm9ybWF0dGVyXCIsXG5cdFx0Zm46IGZvcm1hdHRlckNsYXNzISxcblx0XHRwYXJhbWV0ZXJzOiBwYXJhbWV0ZXJFeHByZXNzaW9uc1xuXHR9O1xufVxuXG5leHBvcnQgY29uc3QgZ2V0RmlzY2FsVHlwZSA9IGZ1bmN0aW9uIChwcm9wZXJ0eTogUHJvcGVydHkpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnMuQ29tbW9uPy5Jc0Zpc2NhbFllYXIpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsWWVhcjtcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnMuQ29tbW9uPy5Jc0Zpc2NhbFBlcmlvZCkge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxQZXJpb2Q7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zLkNvbW1vbj8uSXNGaXNjYWxZZWFyUGVyaW9kKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0Zpc2NhbFllYXJQZXJpb2Q7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zLkNvbW1vbj8uSXNGaXNjYWxRdWFydGVyKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0Zpc2NhbFF1YXJ0ZXI7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zLkNvbW1vbj8uSXNGaXNjYWxZZWFyUXVhcnRlcikge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxZZWFyUXVhcnRlcjtcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnMuQ29tbW9uPy5Jc0Zpc2NhbFdlZWspIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsV2Vlaztcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnMuQ29tbW9uPy5Jc0Zpc2NhbFllYXJXZWVrKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0Zpc2NhbFllYXJXZWVrO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucy5Db21tb24/LklzRGF5T2ZGaXNjYWxZZWFyKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0RheU9mRmlzY2FsWWVhcjtcblx0fVxufTtcblxuLyoqXG4gKiBGdW5jdGlvbiBjYWxsLCBvcHRpb25hbGx5IHdpdGggYXJndW1lbnRzLlxuICpcbiAqIEBwYXJhbSBmdW5jIEZ1bmN0aW9uIG5hbWUgb3IgcmVmZXJlbmNlIHRvIGZ1bmN0aW9uXG4gKiBAcGFyYW0gcGFyYW1ldGVycyBBcmd1bWVudHNcbiAqIEBwYXJhbSBvbiBPYmplY3QgdG8gY2FsbCB0aGUgZnVuY3Rpb24gb25cbiAqIEBwYXJhbSBpc0Zvcm1hdHRpbmdGblxuICogQHJldHVybnMgRXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGZ1bmN0aW9uIGNhbGwgKG5vdCB0aGUgcmVzdWx0IG9mIHRoZSBmdW5jdGlvbiBjYWxsISlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZuPFQsIFUgZXh0ZW5kcyBGdW5jdGlvbk9yTmFtZTxUPj4oXG5cdGZ1bmM6IFUsXG5cdHBhcmFtZXRlcnM6IFdyYXBwZWRUdXBsZTxGdW5jdGlvblBhcmFtZXRlcnM8VCwgVT4+LFxuXHRvbj86IEV4cHJlc3Npb25PclByaW1pdGl2ZTxvYmplY3Q+LFxuXHRpc0Zvcm1hdHRpbmdGbiA9IGZhbHNlXG4pOiBGdW5jdGlvbkV4cHJlc3Npb248VD4ge1xuXHRjb25zdCBmdW5jdGlvbk5hbWUgPSB0eXBlb2YgZnVuYyA9PT0gXCJzdHJpbmdcIiA/IGZ1bmMgOiBmdW5jLl9fZnVuY3Rpb25OYW1lO1xuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkZ1bmN0aW9uXCIsXG5cdFx0b2JqOiBvbiAhPT0gdW5kZWZpbmVkID8gd3JhcFByaW1pdGl2ZShvbikgOiB1bmRlZmluZWQsXG5cdFx0Zm46IGZ1bmN0aW9uTmFtZSxcblx0XHRpc0Zvcm1hdHRpbmdGbjogaXNGb3JtYXR0aW5nRm4sXG5cdFx0cGFyYW1ldGVyczogKHBhcmFtZXRlcnMgYXMgRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFByaW1pdGl2ZVR5cGU+W10pLm1hcCh3cmFwUHJpbWl0aXZlKVxuXHR9O1xufVxuXG4vKipcbiAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIGRldGVybWluZSBpZiBhIGJpbmRpbmcgdmFsdWUgaXMgbnVsbCwgdW5kZWZpbmVkIG9yIGVtcHR5LlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBBIEJvb2xlYW4gZXhwcmVzc2lvbiBldmFsdWF0aW5nIHRoZSBmYWN0IHRoYXQgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBlbXB0eVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbXB0eShleHByZXNzaW9uOiBFeHByZXNzaW9uPHN0cmluZz4pOiBFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0Y29uc3QgYUJpbmRpbmdzOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8Ym9vbGVhbj5bXSA9IFtdO1xuXHR0cmFuc2Zvcm1SZWN1cnNpdmVseShleHByZXNzaW9uLCBcIlBhdGhJbk1vZGVsXCIsIChleHByKSA9PiB7XG5cdFx0YUJpbmRpbmdzLnB1c2gob3IoZXF1YWwoZXhwciwgXCJcIiksIGVxdWFsKGV4cHIsIHVuZGVmaW5lZCksIGVxdWFsKGV4cHIsIG51bGwpKSk7XG5cdFx0cmV0dXJuIGV4cHI7XG5cdH0pO1xuXHRyZXR1cm4gYW5kKC4uLmFCaW5kaW5ncyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb25jYXQoXG5cdC8vZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby13cmFwcGVyLW9iamVjdC10eXBlc1xuXHQuLi5pbkV4cHJlc3Npb25zOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8c3RyaW5nIHwgU3RyaW5nPltdXG4pOiBFeHByZXNzaW9uPHN0cmluZz4ge1xuXHRjb25zdCBleHByZXNzaW9ucyA9IGluRXhwcmVzc2lvbnMubWFwKHdyYXBQcmltaXRpdmUpO1xuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbiguLi5leHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoZXhwcmVzc2lvbnMuZXZlcnkoaXNDb25zdGFudCkpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoXG5cdFx0XHRleHByZXNzaW9ucy5yZWR1Y2UoKGNvbmNhdGVuYXRlZDogc3RyaW5nLCB2YWx1ZSkgPT4ge1xuXHRcdFx0XHRpZiAodmFsdWUudmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZS52YWx1ZSAhPT0gbnVsbCkge1xuXHRcdFx0XHRcdHJldHVybiBjb25jYXRlbmF0ZWQgKyB2YWx1ZS52YWx1ZS50b1N0cmluZygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb25jYXRlbmF0ZWQ7XG5cdFx0XHR9LCBcIlwiKVxuXHRcdCk7XG5cdH0gZWxzZSBpZiAoZXhwcmVzc2lvbnMuc29tZShpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbikpIHtcblx0XHRsZXQgcGF0aElkeCA9IDA7XG5cdFx0Y29uc3QgbXlDb25jYXRFeHByZXNzaW9uID0gZm9ybWF0UmVzdWx0KGV4cHJlc3Npb25zLCBcInNhcC5mZS5jb3JlLmZvcm1hdHRlcnMuU3RhbmRhcmRGb3JtYXR0ZXIjY29uY2F0XCIsIHVuZGVmaW5lZCwgdHJ1ZSk7XG5cdFx0Y29uc3QgYWxsUGFydHMgPSBbXTtcblx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdG15Q29uY2F0RXhwcmVzc2lvbiBhcyBFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+LFxuXHRcdFx0XCJQYXRoSW5Nb2RlbFwiLFxuXHRcdFx0KGNvbnN0YW50UGF0aDogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+KSA9PiB7XG5cdFx0XHRcdGFsbFBhcnRzLnB1c2goY29uc3RhbnRQYXRoKTtcblx0XHRcdFx0cmV0dXJuIHBhdGhJbk1vZGVsKGAkJHtwYXRoSWR4Kyt9YCwgXCIkXCIpO1xuXHRcdFx0fVxuXHRcdCk7XG5cdFx0YWxsUGFydHMudW5zaGlmdChjb25zdGFudChKU09OLnN0cmluZ2lmeShteUNvbmNhdEV4cHJlc3Npb24pKSk7XG5cdFx0cmV0dXJuIGZvcm1hdFJlc3VsdChhbGxQYXJ0cywgXCJzYXAuZmUuY29yZS5mb3JtYXR0ZXJzLlN0YW5kYXJkRm9ybWF0dGVyI2V2YWx1YXRlQ29tcGxleEV4cHJlc3Npb25cIiwgdW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkNvbmNhdFwiLFxuXHRcdGV4cHJlc3Npb25zOiBleHByZXNzaW9ucyBhcyBFeHByZXNzaW9uPHN0cmluZz5bXVxuXHR9O1xufVxuXG50eXBlIEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPFQgZXh0ZW5kcyBFeHByZXNzaW9uVHlwZSwgVj4gPSBUIGV4dGVuZHMgXCJDb25zdGFudFwiXG5cdD8gQ29uc3RhbnRFeHByZXNzaW9uPFY+XG5cdDogVCBleHRlbmRzIFwiUGF0aEluTW9kZWxcIlxuXHRcdD8gUGF0aEluTW9kZWxFeHByZXNzaW9uPFY+XG5cdFx0OiBUIGV4dGVuZHMgXCJGdW5jdGlvblwiXG5cdFx0XHQ/IEZ1bmN0aW9uRXhwcmVzc2lvbjxWPlxuXHRcdFx0OiBUIGV4dGVuZHMgXCJVbnJlc29sdmFibGVcIlxuXHRcdFx0XHQ/IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uXG5cdFx0XHRcdDogRXhwcmVzc2lvbjxWPjtcblxuZXhwb3J0IHR5cGUgVHJhbnNmb3JtRnVuY3Rpb248VCwgVj4gPSAoZXhwcmVzc2lvblBhcnQ6IFQpID0+IEV4cHJlc3Npb248Vj47XG5leHBvcnQgdHlwZSBFeHByZXNzaW9uVHlwZSA9IFBpY2s8RXhwcmVzc2lvbjx1bmtub3duPiwgXCJfdHlwZVwiPltcIl90eXBlXCJdO1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVJlY3Vyc2l2ZWx5PFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlLCBFVCBleHRlbmRzIEV4cHJlc3Npb25UeXBlPihcblx0aW5FeHByZXNzaW9uOiBFeHByZXNzaW9uPFQ+LFxuXHRleHByZXNzaW9uVHlwZTogRVQsXG5cdHRyYW5zZm9ybUZ1bmN0aW9uOiBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgVD4sIFQ+LFxuXHRpbmNsdWRlQWxsRXhwcmVzc2lvbiA9IGZhbHNlXG4pOiBFeHByZXNzaW9uPFQ+IHtcblx0bGV0IGV4cHJlc3Npb246IEV4cHJlc3Npb248VD4gPSBpbkV4cHJlc3Npb247XG5cdHN3aXRjaCAoZXhwcmVzc2lvbi5fdHlwZSkge1xuXHRcdGNhc2UgXCJGdW5jdGlvblwiOlxuXHRcdGNhc2UgXCJGb3JtYXR0ZXJcIjpcblx0XHRcdGV4cHJlc3Npb24ucGFyYW1ldGVycyA9IGV4cHJlc3Npb24ucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT5cblx0XHRcdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkocGFyYW1ldGVyIGFzIEV4cHJlc3Npb248VD4sIGV4cHJlc3Npb25UeXBlLCB0cmFuc2Zvcm1GdW5jdGlvbiwgaW5jbHVkZUFsbEV4cHJlc3Npb24pXG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIkNvbmNhdFwiOlxuXHRcdFx0ZXhwcmVzc2lvbi5leHByZXNzaW9ucyA9IGV4cHJlc3Npb24uZXhwcmVzc2lvbnMubWFwKChzdWJFeHByZXNzaW9uKSA9PlxuXHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRzdWJFeHByZXNzaW9uLFxuXHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIHN0cmluZz4sIHN0cmluZz4sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KVxuXHRcdFx0KTtcblx0XHRcdGV4cHJlc3Npb24gPSBjb25jYXQoLi4uZXhwcmVzc2lvbi5leHByZXNzaW9ucykgYXMgRXhwcmVzc2lvbjxUPjtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJDb21wbGV4VHlwZVwiOlxuXHRcdFx0ZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVycyA9IGV4cHJlc3Npb24uYmluZGluZ1BhcmFtZXRlcnMubWFwKChiaW5kaW5nUGFyYW1ldGVyKSA9PlxuXHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShiaW5kaW5nUGFyYW1ldGVyIGFzIEV4cHJlc3Npb248VD4sIGV4cHJlc3Npb25UeXBlLCB0cmFuc2Zvcm1GdW5jdGlvbiwgaW5jbHVkZUFsbEV4cHJlc3Npb24pXG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIklmRWxzZVwiOiB7XG5cdFx0XHRjb25zdCBvblRydWUgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShleHByZXNzaW9uLm9uVHJ1ZSwgZXhwcmVzc2lvblR5cGUsIHRyYW5zZm9ybUZ1bmN0aW9uLCBpbmNsdWRlQWxsRXhwcmVzc2lvbik7XG5cdFx0XHRjb25zdCBvbkZhbHNlID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoZXhwcmVzc2lvbi5vbkZhbHNlLCBleHByZXNzaW9uVHlwZSwgdHJhbnNmb3JtRnVuY3Rpb24sIGluY2x1ZGVBbGxFeHByZXNzaW9uKTtcblx0XHRcdGxldCBjb25kaXRpb24gPSBleHByZXNzaW9uLmNvbmRpdGlvbjtcblx0XHRcdGlmIChpbmNsdWRlQWxsRXhwcmVzc2lvbikge1xuXHRcdFx0XHRjb25kaXRpb24gPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRleHByZXNzaW9uLmNvbmRpdGlvbixcblx0XHRcdFx0XHRleHByZXNzaW9uVHlwZSxcblx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCBib29sZWFuPiwgYm9vbGVhbj4sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHRcdGV4cHJlc3Npb24gPSBpZkVsc2UoY29uZGl0aW9uLCBvblRydWUsIG9uRmFsc2UpO1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdGNhc2UgXCJOb3RcIjpcblx0XHRcdGlmIChpbmNsdWRlQWxsRXhwcmVzc2lvbikge1xuXHRcdFx0XHRjb25zdCBvcGVyYW5kID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0ZXhwcmVzc2lvbi5vcGVyYW5kLFxuXHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIGJvb2xlYW4+LCBib29sZWFuPixcblx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHQpO1xuXHRcdFx0XHRleHByZXNzaW9uID0gbm90KG9wZXJhbmQpIGFzIEV4cHJlc3Npb248VD47XG5cdFx0XHR9XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiVHJ1dGh5XCI6XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiU2V0XCI6XG5cdFx0XHRpZiAoaW5jbHVkZUFsbEV4cHJlc3Npb24pIHtcblx0XHRcdFx0Y29uc3Qgb3BlcmFuZHMgPSBleHByZXNzaW9uLm9wZXJhbmRzLm1hcCgob3BlcmFuZCkgPT5cblx0XHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRcdG9wZXJhbmQsXG5cdFx0XHRcdFx0XHRleHByZXNzaW9uVHlwZSxcblx0XHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIGJvb2xlYW4+LCBib29sZWFuPixcblx0XHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHQpO1xuXHRcdFx0XHRleHByZXNzaW9uID0gZXhwcmVzc2lvbi5vcGVyYXRvciA9PT0gXCJ8fFwiID8gKG9yKC4uLm9wZXJhbmRzKSBhcyBFeHByZXNzaW9uPFQ+KSA6IChhbmQoLi4ub3BlcmFuZHMpIGFzIEV4cHJlc3Npb248VD4pO1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIkNvbXBhcmlzb25cIjpcblx0XHRcdGlmIChpbmNsdWRlQWxsRXhwcmVzc2lvbikge1xuXHRcdFx0XHRjb25zdCBvcGVyYW5kMSA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHJlc3Npb24ub3BlcmFuZDEgYXMgRXhwcmVzc2lvbjxUPixcblx0XHRcdFx0XHRleHByZXNzaW9uVHlwZSxcblx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbixcblx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHQpO1xuXHRcdFx0XHRjb25zdCBvcGVyYW5kMiA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHJlc3Npb24ub3BlcmFuZDIgYXMgRXhwcmVzc2lvbjxUPixcblx0XHRcdFx0XHRleHByZXNzaW9uVHlwZSxcblx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbixcblx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHQpO1xuXHRcdFx0XHRleHByZXNzaW9uID0gY29tcGFyaXNvbihleHByZXNzaW9uLm9wZXJhdG9yLCBvcGVyYW5kMSwgb3BlcmFuZDIpIGFzIEV4cHJlc3Npb248VD47XG5cdFx0XHR9XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiQ29uc3RhbnRcIjoge1xuXHRcdFx0Y29uc3QgY29uc3RhbnRWYWx1ZTogUmVjb3JkPHN0cmluZywgRXhwcmVzc2lvbjx1bmtub3duPj4gPSBleHByZXNzaW9uLnZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIEV4cHJlc3Npb248dW5rbm93bj4+O1xuXHRcdFx0aWYgKHR5cGVvZiBjb25zdGFudFZhbHVlID09PSBcIm9iamVjdFwiICYmIGNvbnN0YW50VmFsdWUpIHtcblx0XHRcdFx0T2JqZWN0LmtleXMoY29uc3RhbnRWYWx1ZSkuZm9yRWFjaCgoa2V5KSA9PiB7XG5cdFx0XHRcdFx0Y29uc3RhbnRWYWx1ZVtrZXldID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0XHRjb25zdGFudFZhbHVlW2tleV0gYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+LFxuXHRcdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbixcblx0XHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdFx0Y2FzZSBcIlJlZlwiOlxuXHRcdGNhc2UgXCJMZW5ndGhcIjpcblx0XHRjYXNlIFwiUGF0aEluTW9kZWxcIjpcblx0XHRjYXNlIFwiRW1iZWRkZWRCaW5kaW5nXCI6XG5cdFx0Y2FzZSBcIkVtYmVkZGVkRXhwcmVzc2lvbkJpbmRpbmdcIjpcblx0XHRjYXNlIFwiVW5yZXNvbHZhYmxlXCI6XG5cdFx0XHQvLyBEbyBub3RoaW5nXG5cdFx0XHRicmVhaztcblx0fVxuXHRpZiAoZXhwcmVzc2lvblR5cGUgPT09IGV4cHJlc3Npb24uX3R5cGUpIHtcblx0XHRleHByZXNzaW9uID0gdHJhbnNmb3JtRnVuY3Rpb24oaW5FeHByZXNzaW9uIGFzIEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCBUPik7XG5cdH1cblx0cmV0dXJuIGV4cHJlc3Npb247XG59XG4iLCJpbXBvcnQgdHlwZSB7XG5cdEFubm90YXRpb25UZXJtLFxuXHRDb21wbGV4VHlwZSxcblx0RW50aXR5Q29udGFpbmVyLFxuXHRFbnRpdHlTZXQsXG5cdEVudGl0eVR5cGUsXG5cdE11bHRpcGxlTmF2aWdhdGlvblByb3BlcnR5LFxuXHROYXZpZ2F0aW9uUHJvcGVydHksXG5cdFBhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0UHJvcGVydHksXG5cdFByb3BlcnR5UGF0aCxcblx0U2VydmljZU9iamVjdCxcblx0U2luZ2xlTmF2aWdhdGlvblByb3BlcnR5LFxuXHRTaW5nbGV0b24sXG5cdFR5cGVEZWZpbml0aW9uXG59IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlc1wiO1xuaW1wb3J0IHR5cGUgeyBBbm5vdGF0aW9uUGF0aCB9IGZyb20gXCJAc2FwLXV4L3ZvY2FidWxhcmllcy10eXBlcy9FZG1cIjtcblxudHlwZSBBbm5vdGF0aW9uVHlwZSA9IHtcblx0JFR5cGU/OiBzdHJpbmc7XG5cdGZ1bGx5UXVhbGlmaWVkTmFtZT86IHN0cmluZztcbn07XG5leHBvcnQgdHlwZSBfQW5ub3RhdGlvblRlcm0gPSB7XG5cdHRlcm06IHN0cmluZztcblx0cXVhbGlmaWVyPzogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgYXJndW1lbnQgaXMgYW4gYW5ub3RhdGlvbiBvZiB0aGUgZ2l2ZW4gdHlwZS5cbiAqIEBwYXJhbSBwb3RlbnRpYWxBbm5vdGF0aW9uVHlwZSBUaGUgYW5ub3RhdGlvbiB0byBjaGVja1xuICogQHBhcmFtIHR5cGVOYW1lIFRoZSB0eXBlIHRvIGNoZWNrIGZvclxuICogQHJldHVybnMgV2hldGhlciB0aGUgYXJndW1lbnQgaXMgYW4gYW5ub3RhdGlvbiBvZiB0aGUgZ2l2ZW4gdHlwZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBbm5vdGF0aW9uT2ZUeXBlPFQgZXh0ZW5kcyBvYmplY3QgJiBBbm5vdGF0aW9uVHlwZT4oXG5cdHBvdGVudGlhbEFubm90YXRpb25UeXBlOiB1bmtub3duLFxuXHR0eXBlTmFtZTogVFtcIiRUeXBlXCJdIHwgVFtcIiRUeXBlXCJdW11cbik6IHBvdGVudGlhbEFubm90YXRpb25UeXBlIGlzIFQge1xuXHRpZiAoQXJyYXkuaXNBcnJheSh0eXBlTmFtZSkpIHtcblx0XHRyZXR1cm4gdHlwZU5hbWUuaW5jbHVkZXMoKHBvdGVudGlhbEFubm90YXRpb25UeXBlIGFzIEFubm90YXRpb25UeXBlKS4kVHlwZSk7XG5cdH1cblx0cmV0dXJuIChwb3RlbnRpYWxBbm5vdGF0aW9uVHlwZSBhcyBBbm5vdGF0aW9uVHlwZSkuJFR5cGUgPT09IHR5cGVOYW1lO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhbiBhbm5vdGF0aW9uIG9mIHRoZSBnaXZlbiB0ZXJtLlxuICogQHBhcmFtIHBvdGVudGlhbEFubm90YXRpb24gVGhlIGFubm90YXRpb24gdG8gY2hlY2tcbiAqIEBwYXJhbSB0ZXJtTmFtZSBUaGUgdGVybSB0byBjaGVjayBmb3JcbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGFuIGFubm90YXRpb24gb2YgdGhlIGdpdmVuIHRlcm1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQW5ub3RhdGlvbk9mVGVybTxUIGV4dGVuZHMgb2JqZWN0ICYgX0Fubm90YXRpb25UZXJtPihcblx0cG90ZW50aWFsQW5ub3RhdGlvbjogdW5rbm93bixcblx0dGVybU5hbWU6IFRbXCJ0ZXJtXCJdXG4pOiBwb3RlbnRpYWxBbm5vdGF0aW9uIGlzIEFubm90YXRpb25UZXJtPFQ+IHtcblx0cmV0dXJuIChwb3RlbnRpYWxBbm5vdGF0aW9uIGFzIF9Bbm5vdGF0aW9uVGVybSkudGVybSA9PT0gdGVybU5hbWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0Fubm90YXRpb25UZXJtKHBvdGVudGlhbEFubm90YXRpb246IHVua25vd24pOiBwb3RlbnRpYWxBbm5vdGF0aW9uIGlzIF9Bbm5vdGF0aW9uVGVybSB7XG5cdHJldHVybiAocG90ZW50aWFsQW5ub3RhdGlvbiBhcyBfQW5ub3RhdGlvblRlcm0pLmhhc093blByb3BlcnR5KFwidGVybVwiKTtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgYXJndW1lbnQgaXMgYSB7QGxpbmsgU2VydmljZU9iamVjdH0uXG4gKlxuICogQHBhcmFtIHNlcnZpY2VPYmplY3QgVGhlIG9iamVjdCB0byBiZSBjaGVja2VkLlxuICogQHJldHVybnMgV2hldGhlciB0aGUgYXJndW1lbnQgaXMgYSB7QGxpbmsgU2VydmljZU9iamVjdH0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NlcnZpY2VPYmplY3Qoc2VydmljZU9iamVjdDogdW5rbm93bik6IHNlcnZpY2VPYmplY3QgaXMgU2VydmljZU9iamVjdCB7XG5cdHJldHVybiBzZXJ2aWNlT2JqZWN0Py5oYXNPd25Qcm9wZXJ0eShcIl90eXBlXCIpID8/IGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhIHtAbGluayBDb21wbGV4VHlwZX0uXG4gKlxuICogQHBhcmFtIHNlcnZpY2VPYmplY3QgVGhlIG9iamVjdCB0byBiZSBjaGVja2VkLlxuICogQHJldHVybnMgV2hldGhlciB0aGUgYXJndW1lbnQgaXMgYSB7QGxpbmsgQ29tcGxleFR5cGV9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb21wbGV4VHlwZShzZXJ2aWNlT2JqZWN0OiB1bmtub3duKTogc2VydmljZU9iamVjdCBpcyBDb21wbGV4VHlwZSB7XG5cdHJldHVybiAoc2VydmljZU9iamVjdCBhcyB7IF90eXBlOiBzdHJpbmcgfSkuX3R5cGUgPT09IFwiQ29tcGxleFR5cGVcIjtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgYXJndW1lbnQgaXMgYSB7QGxpbmsgVHlwZURlZmluaXRpb259LlxuICpcbiAqIEBwYXJhbSBzZXJ2aWNlT2JqZWN0IFRoZSBvYmplY3QgdG8gYmUgY2hlY2tlZC5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGEge0BsaW5rIFR5cGVEZWZpbml0aW9ufS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVHlwZURlZmluaXRpb24oc2VydmljZU9iamVjdDogdW5rbm93bik6IHNlcnZpY2VPYmplY3QgaXMgVHlwZURlZmluaXRpb24ge1xuXHRyZXR1cm4gKHNlcnZpY2VPYmplY3QgYXMgeyBfdHlwZTogc3RyaW5nIH0pLl90eXBlID09PSBcIlR5cGVEZWZpbml0aW9uXCI7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGFuIHtAbGluayBFbnRpdHlDb250YWluZXJ9LlxuICpcbiAqIEBwYXJhbSBzZXJ2aWNlT2JqZWN0IFRoZSBvYmplY3QgdG8gYmUgY2hlY2tlZC5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGFuIHtAbGluayBFbnRpdHlDb250YWluZXJ9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbnRpdHlDb250YWluZXIoc2VydmljZU9iamVjdDogdW5rbm93bik6IHNlcnZpY2VPYmplY3QgaXMgRW50aXR5Q29udGFpbmVyIHtcblx0cmV0dXJuIChzZXJ2aWNlT2JqZWN0IGFzIHsgX3R5cGU6IHN0cmluZyB9KS5fdHlwZSA9PT0gXCJFbnRpdHlDb250YWluZXJcIjtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgYXJndW1lbnQgaXMgYW4ge0BsaW5rIEVudGl0eVNldH0uXG4gKlxuICogQHBhcmFtIHNlcnZpY2VPYmplY3QgVGhlIG9iamVjdCB0byBiZSBjaGVja2VkLlxuICogQHJldHVybnMgV2hldGhlciB0aGUgYXJndW1lbnQgaXMgYW4ge0BsaW5rIEVudGl0eVNldH0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0VudGl0eVNldChzZXJ2aWNlT2JqZWN0OiB1bmtub3duKTogc2VydmljZU9iamVjdCBpcyBFbnRpdHlTZXQge1xuXHRyZXR1cm4gKHNlcnZpY2VPYmplY3QgYXMgeyBfdHlwZTogc3RyaW5nIH0pLl90eXBlID09PSBcIkVudGl0eVNldFwiO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhIHtAbGluayBTaW5nbGV0b259LlxuICpcbiAqIEBwYXJhbSBzZXJ2aWNlT2JqZWN0IFRoZSBvYmplY3QgdG8gYmUgY2hlY2tlZC5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGEge0BsaW5rIFNpbmdsZXRvbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2luZ2xldG9uKHNlcnZpY2VPYmplY3Q6IHVua25vd24pOiBzZXJ2aWNlT2JqZWN0IGlzIFNpbmdsZXRvbiB7XG5cdHJldHVybiAoc2VydmljZU9iamVjdCBhcyB7IF90eXBlOiBzdHJpbmcgfSkuX3R5cGUgPT09IFwiU2luZ2xldG9uXCI7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGFuIHtAbGluayBFbnRpdHlUeXBlfS5cbiAqXG4gKiBAcGFyYW0gc2VydmljZU9iamVjdCBUaGUgb2JqZWN0IHRvIGJlIGNoZWNrZWQuXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhbiB7QGxpbmsgRW50aXR5VHlwZX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW50aXR5VHlwZShzZXJ2aWNlT2JqZWN0OiB1bmtub3duKTogc2VydmljZU9iamVjdCBpcyBFbnRpdHlUeXBlIHtcblx0cmV0dXJuIChzZXJ2aWNlT2JqZWN0IGFzIHsgX3R5cGU6IHN0cmluZyB9KS5fdHlwZSA9PT0gXCJFbnRpdHlUeXBlXCI7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGEge0BsaW5rIFByb3BlcnR5fS5cbiAqXG4gKiBAcGFyYW0gc2VydmljZU9iamVjdCBUaGUgb2JqZWN0IHRvIGJlIGNoZWNrZWQuXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhIHtAbGluayBQcm9wZXJ0eX0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1Byb3BlcnR5KHNlcnZpY2VPYmplY3Q6IHVua25vd24pOiBzZXJ2aWNlT2JqZWN0IGlzIFByb3BlcnR5IHtcblx0cmV0dXJuIChzZXJ2aWNlT2JqZWN0IGFzIHsgX3R5cGU6IHN0cmluZyB9KS5fdHlwZSA9PT0gXCJQcm9wZXJ0eVwiO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhIHtAbGluayBOYXZpZ2F0aW9uUHJvcGVydHl9LlxuICpcbiAqIEhpbnQ6IFRoZXJlIGFyZSBhbHNvIHRoZSBtb3JlIHNwZWNpZmljIGZ1bmN0aW9ucyB7QGxpbmsgaXNTaW5nbGVOYXZpZ2F0aW9uUHJvcGVydHl9IGFuZCB7QGxpbmsgaXNNdWx0aXBsZU5hdmlnYXRpb25Qcm9wZXJ0eX0uIFRoZXNlIGNhbiBiZVxuICogdXNlZCB0byBjaGVjayBmb3IgdG8tb25lIGFuZCB0by1tYW55IG5hdmlnYXRpb24gcHJvcGVydGllcywgcmVzcGVjdGl2ZWx5LlxuICpcbiAqIEBwYXJhbSBzZXJ2aWNlT2JqZWN0IFRoZSBvYmplY3QgdG8gYmUgY2hlY2tlZC5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGEge0BsaW5rIE5hdmlnYXRpb25Qcm9wZXJ0eX0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc05hdmlnYXRpb25Qcm9wZXJ0eShzZXJ2aWNlT2JqZWN0OiB1bmtub3duKTogc2VydmljZU9iamVjdCBpcyBOYXZpZ2F0aW9uUHJvcGVydHkge1xuXHRyZXR1cm4gKHNlcnZpY2VPYmplY3QgYXMgeyBfdHlwZTogc3RyaW5nIH0pLl90eXBlID09PSBcIk5hdmlnYXRpb25Qcm9wZXJ0eVwiO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhIHtAbGluayBTaW5nbGVOYXZpZ2F0aW9uUHJvcGVydHl9LlxuICpcbiAqIEBwYXJhbSBzZXJ2aWNlT2JqZWN0IFRoZSBvYmplY3QgdG8gYmUgY2hlY2tlZC5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGEge0BsaW5rIFNpbmdsZU5hdmlnYXRpb25Qcm9wZXJ0eX0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NpbmdsZU5hdmlnYXRpb25Qcm9wZXJ0eShzZXJ2aWNlT2JqZWN0OiB1bmtub3duKTogc2VydmljZU9iamVjdCBpcyBTaW5nbGVOYXZpZ2F0aW9uUHJvcGVydHkge1xuXHRyZXR1cm4gaXNOYXZpZ2F0aW9uUHJvcGVydHkoc2VydmljZU9iamVjdCkgJiYgIXNlcnZpY2VPYmplY3QuaXNDb2xsZWN0aW9uO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhIHtAbGluayBNdWx0aXBsZU5hdmlnYXRpb25Qcm9wZXJ0eX0uXG4gKlxuICogQHBhcmFtIHNlcnZpY2VPYmplY3QgVGhlIG9iamVjdCB0byBiZSBjaGVja2VkLlxuICogQHJldHVybnMgV2hldGhlciB0aGUgYXJndW1lbnQgaXMgYSB7QGxpbmsgTXVsdGlwbGVOYXZpZ2F0aW9uUHJvcGVydHl9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNNdWx0aXBsZU5hdmlnYXRpb25Qcm9wZXJ0eShzZXJ2aWNlT2JqZWN0OiB1bmtub3duKTogc2VydmljZU9iamVjdCBpcyBNdWx0aXBsZU5hdmlnYXRpb25Qcm9wZXJ0eSB7XG5cdHJldHVybiBpc05hdmlnYXRpb25Qcm9wZXJ0eShzZXJ2aWNlT2JqZWN0KSAmJiBzZXJ2aWNlT2JqZWN0LmlzQ29sbGVjdGlvbjtcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgYXJndW1lbnQgaXMgYSB7QGxpbmsgUGF0aEFubm90YXRpb25FeHByZXNzaW9ufS5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgb2JqZWN0IHRvIGJlIGNoZWNrZWQuXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhIHtAbGluayBQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb259LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb248VD4oZXhwcmVzc2lvbjogdW5rbm93bik6IGV4cHJlc3Npb24gaXMgUGF0aEFubm90YXRpb25FeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIChleHByZXNzaW9uIGFzIHsgdHlwZTogc3RyaW5nIH0pLnR5cGUgPT09IFwiUGF0aFwiO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhIHtAbGluayBBbm5vdGF0aW9uUGF0aEV4cHJlc3Npb259LlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBvYmplY3QgdG8gYmUgY2hlY2tlZC5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGEge0BsaW5rIEFubm90YXRpb25QYXRoRXhwcmVzc2lvbn0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Fubm90YXRpb25QYXRoPFQ+KGV4cHJlc3Npb246IHVua25vd24pOiBleHByZXNzaW9uIGlzIEFubm90YXRpb25QYXRoPFQ+IHtcblx0cmV0dXJuIChleHByZXNzaW9uIGFzIHsgdHlwZTogc3RyaW5nIH0pLnR5cGUgPT0gXCJBbm5vdGF0aW9uUGF0aFwiO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhIHtAbGluayBQcm9wZXJ0eVBhdGh9LlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBvYmplY3QgdG8gYmUgY2hlY2tlZC5cbiAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGFyZ3VtZW50IGlzIGEge0BsaW5rIFByb3BlcnR5UGF0aH0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1Byb3BlcnR5UGF0aEV4cHJlc3Npb24oZXhwcmVzc2lvbjogdW5rbm93bik6IGV4cHJlc3Npb24gaXMgUHJvcGVydHlQYXRoIHtcblx0cmV0dXJuIChleHByZXNzaW9uIGFzIHsgdHlwZTogc3RyaW5nIH0pLnR5cGUgPT09IFwiUHJvcGVydHlQYXRoXCI7XG59XG5leHBvcnQgdHlwZSBWYWxpZFByb3BlcnR5UGF0aCA9IFByb3BlcnR5UGF0aCAmIHsgJHRhcmdldDogUHJvcGVydHkgfTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgYXJndW1lbnQgaXMgYSB7QGxpbmsgUHJvcGVydHlQYXRofS5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgb2JqZWN0IHRvIGJlIGNoZWNrZWQuXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBhcmd1bWVudCBpcyBhIHtAbGluayBQcm9wZXJ0eVBhdGh9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFByb3BlcnR5UGF0aEV4cHJlc3Npb24oZXhwcmVzc2lvbjogdW5rbm93bik6IGV4cHJlc3Npb24gaXMgVmFsaWRQcm9wZXJ0eVBhdGgge1xuXHRyZXR1cm4gKGV4cHJlc3Npb24gYXMgeyB0eXBlOiBzdHJpbmcgfSkudHlwZSA9PT0gXCJQcm9wZXJ0eVBhdGhcIiAmJiAhIShleHByZXNzaW9uIGFzIHsgJHRhcmdldDogUHJvcGVydHkgfSkuJHRhcmdldDtcbn1cbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuXHRcdC8vIG5vIG1vZHVsZS5sb2FkZWQgbmVlZGVkXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIiLCIvLyBzdGFydHVwXG4vLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbi8vIFRoaXMgZW50cnkgbW9kdWxlIGlzIHJlZmVyZW5jZWQgYnkgb3RoZXIgbW9kdWxlcyBzbyBpdCBjYW4ndCBiZSBpbmxpbmVkXG52YXIgX193ZWJwYWNrX2V4cG9ydHNfXyA9IF9fd2VicGFja19yZXF1aXJlX18oODI5KTtcbiIsIiJdfQ==
|