@sapui5/sap.fe.core 1.102.3 → 1.105.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 +6 -6
- package/src/sap/fe/core/.library +1 -1
- package/src/sap/fe/core/ActionRuntime.js +120 -0
- package/src/sap/fe/core/ActionRuntime.ts +108 -0
- package/src/sap/fe/core/AppComponent.js +81 -35
- package/src/sap/fe/core/AppComponent.ts +68 -44
- package/src/sap/fe/core/AppStateHandler.js +82 -70
- package/src/sap/fe/core/AppStateHandler.ts +32 -37
- package/src/sap/fe/core/BaseController.js +12 -10
- package/src/sap/fe/core/BaseController.ts +15 -13
- package/src/sap/fe/core/CommonUtils.js +291 -218
- package/src/sap/fe/core/CommonUtils.ts +315 -251
- package/src/sap/fe/core/ExtensionAPI.js +25 -28
- package/src/sap/fe/core/ExtensionAPI.ts +36 -38
- package/src/sap/fe/core/PageController.js +5 -5
- package/src/sap/fe/core/PageController.ts +4 -5
- package/src/sap/fe/core/TemplateComponent.js +21 -10
- package/src/sap/fe/core/TemplateComponent.ts +9 -6
- package/src/sap/fe/core/TemplateModel.js +2 -2
- package/src/sap/fe/core/TemplateModel.ts +1 -1
- package/src/sap/fe/core/buildingBlocks/AttributeModel.js +11 -3
- package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +8 -2
- package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +197 -43
- package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +164 -24
- package/src/sap/fe/core/buildingBlocks/BuildingBlockFormatter.js +14 -0
- package/src/sap/fe/core/buildingBlocks/BuildingBlockFormatter.ts +5 -0
- package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +609 -230
- package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +275 -128
- package/src/sap/fe/core/buildingBlocks/TraceInfo.js +30 -30
- package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +32 -29
- package/src/sap/fe/core/controllerextensions/BusyLocker.js +1 -1
- package/src/sap/fe/core/controllerextensions/EditFlow.js +761 -700
- package/src/sap/fe/core/controllerextensions/EditFlow.ts +478 -514
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +10 -10
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +10 -10
- package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +104 -75
- package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +71 -79
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +68 -68
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +76 -76
- package/src/sap/fe/core/controllerextensions/InternalRouting.js +162 -102
- package/src/sap/fe/core/controllerextensions/InternalRouting.ts +177 -121
- package/src/sap/fe/core/controllerextensions/KPIManagement.js +67 -69
- package/src/sap/fe/core/controllerextensions/KPIManagement.ts +106 -123
- package/src/sap/fe/core/controllerextensions/MassEdit.js +10 -10
- package/src/sap/fe/core/controllerextensions/MassEdit.ts +20 -27
- package/src/sap/fe/core/controllerextensions/MessageHandler.js +21 -13
- package/src/sap/fe/core/controllerextensions/MessageHandler.ts +21 -14
- package/src/sap/fe/core/controllerextensions/PageReady.js +98 -26
- package/src/sap/fe/core/controllerextensions/PageReady.ts +98 -34
- package/src/sap/fe/core/controllerextensions/Paginator.js +31 -32
- package/src/sap/fe/core/controllerextensions/Paginator.ts +33 -34
- package/src/sap/fe/core/controllerextensions/Placeholder.js +5 -7
- package/src/sap/fe/core/controllerextensions/Placeholder.ts +12 -14
- package/src/sap/fe/core/controllerextensions/Routing.js +11 -12
- package/src/sap/fe/core/controllerextensions/Routing.ts +12 -13
- package/src/sap/fe/core/controllerextensions/RoutingListener.js +1 -1
- package/src/sap/fe/core/controllerextensions/Share.js +171 -140
- package/src/sap/fe/core/controllerextensions/Share.ts +117 -118
- package/src/sap/fe/core/controllerextensions/SideEffects.js +47 -51
- package/src/sap/fe/core/controllerextensions/SideEffects.ts +56 -60
- package/src/sap/fe/core/controllerextensions/ViewState.js +201 -132
- package/src/sap/fe/core/controllerextensions/ViewState.ts +141 -148
- package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.js +5 -5
- package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.ts +8 -7
- package/src/sap/fe/core/controllerextensions/collaboration/ActivitySync.js +13 -12
- package/src/sap/fe/core/controllerextensions/collaboration/ActivitySync.ts +17 -20
- package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.js +13 -12
- package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.ts +15 -15
- package/src/sap/fe/core/controllerextensions/collaboration/Manage.js +57 -18
- package/src/sap/fe/core/controllerextensions/collaboration/Manage.ts +60 -28
- package/src/sap/fe/core/controllerextensions/collaboration/ManageDialog.fragment.xml +29 -21
- package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +1424 -940
- package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.ts +799 -836
- package/src/sap/fe/core/controllerextensions/editFlow/draft.js +410 -377
- package/src/sap/fe/core/controllerextensions/editFlow/draft.ts +275 -358
- package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.js +309 -0
- package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.ts +320 -0
- package/src/sap/fe/core/controllerextensions/editFlow/operations.js +752 -579
- package/src/sap/fe/core/controllerextensions/editFlow/operations.ts +631 -599
- package/src/sap/fe/core/controllerextensions/editFlow/sticky.js +92 -74
- package/src/sap/fe/core/controllerextensions/editFlow/sticky.ts +49 -52
- package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +78 -41
- package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.ts +110 -84
- package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +69 -81
- package/src/sap/fe/core/controllerextensions/routing/RouterProxy.ts +64 -73
- package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +18 -2
- package/src/sap/fe/core/controls/ActionParameterDialogFieldValueHelp.fragment.xml +35 -0
- package/src/sap/fe/core/controls/ActionParameterDialogValueHelp.fragment.xml +25 -24
- package/src/sap/fe/core/controls/Any.js +9 -5
- package/src/sap/fe/core/controls/Any.ts +10 -4
- package/src/sap/fe/core/controls/CommandExecution.js +12 -26
- package/src/sap/fe/core/controls/CommandExecution.ts +11 -25
- package/src/sap/fe/core/controls/ConditionalWrapper.js +3 -3
- package/src/sap/fe/core/controls/ConditionalWrapper.ts +3 -3
- package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +26 -26
- package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +25 -24
- package/src/sap/fe/core/controls/CustomQuickViewPage.js +3 -3
- package/src/sap/fe/core/controls/CustomQuickViewPage.ts +2 -2
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +3 -3
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +5 -5
- package/src/sap/fe/core/controls/FieldWrapper.js +3 -3
- package/src/sap/fe/core/controls/FieldWrapper.ts +3 -3
- package/src/sap/fe/core/controls/FileWrapper.js +9 -4
- package/src/sap/fe/core/controls/FileWrapper.ts +16 -12
- package/src/sap/fe/core/controls/FilterBar.js +7 -3
- package/src/sap/fe/core/controls/FilterBar.ts +13 -9
- package/src/sap/fe/core/controls/FormElementWrapper.js +2 -2
- package/src/sap/fe/core/controls/FormElementWrapper.ts +2 -2
- package/src/sap/fe/core/controls/MassEditSelect.js +1 -1
- package/src/sap/fe/core/controls/MassEditSelect.ts +0 -4
- package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +1 -1
- package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +44 -19
- package/src/sap/fe/core/controls/filterbar/FilterContainer.js +2 -2
- package/src/sap/fe/core/controls/filterbar/VisualFilter.js +17 -13
- package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +20 -22
- package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +4 -4
- package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +8 -8
- package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +49 -49
- package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +54 -54
- package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +8 -2
- package/src/sap/fe/core/controls/massEdit/MassEditField.fragment.xml +22 -35
- package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +89 -88
- package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +107 -106
- package/src/sap/fe/core/converters/ConverterContext.js +48 -34
- package/src/sap/fe/core/converters/ConverterContext.ts +81 -67
- package/src/sap/fe/core/converters/ManifestSettings.js +1 -1
- package/src/sap/fe/core/converters/ManifestSettings.ts +18 -15
- package/src/sap/fe/core/converters/ManifestWrapper.js +59 -45
- package/src/sap/fe/core/converters/ManifestWrapper.ts +55 -45
- package/src/sap/fe/core/converters/MetaModelConverter.js +74 -40
- package/src/sap/fe/core/converters/MetaModelConverter.ts +176 -140
- package/src/sap/fe/core/converters/TemplateConverter.js +21 -20
- package/src/sap/fe/core/converters/TemplateConverter.ts +27 -24
- package/src/sap/fe/core/converters/annotations/DataField.js +58 -35
- package/src/sap/fe/core/converters/annotations/DataField.ts +102 -76
- package/src/sap/fe/core/converters/common/AnnotationConverter.js +1956 -1494
- package/src/sap/fe/core/converters/controls/Common/Action.js +78 -51
- package/src/sap/fe/core/converters/controls/Common/Action.ts +87 -52
- package/src/sap/fe/core/converters/controls/Common/Chart.js +22 -16
- package/src/sap/fe/core/converters/controls/Common/Chart.ts +42 -43
- package/src/sap/fe/core/converters/controls/Common/Criticality.js +3 -3
- package/src/sap/fe/core/converters/controls/Common/Criticality.ts +4 -4
- package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +65 -29
- package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +93 -62
- package/src/sap/fe/core/converters/controls/Common/Form.js +31 -31
- package/src/sap/fe/core/converters/controls/Common/Form.ts +46 -57
- package/src/sap/fe/core/converters/controls/Common/KPI.js +11 -11
- package/src/sap/fe/core/converters/controls/Common/KPI.ts +49 -52
- package/src/sap/fe/core/converters/controls/Common/Table.js +251 -264
- package/src/sap/fe/core/converters/controls/Common/Table.ts +344 -370
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +119 -119
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +147 -144
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +89 -59
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +118 -71
- package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +28 -26
- package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +46 -43
- package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.js +9 -9
- package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.ts +14 -13
- package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +131 -95
- package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +123 -87
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +98 -87
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +121 -117
- package/src/sap/fe/core/converters/helpers/Aggregation.js +2 -4
- package/src/sap/fe/core/converters/helpers/Aggregation.ts +12 -15
- package/src/sap/fe/core/converters/helpers/BindingHelper.js +31 -31
- package/src/sap/fe/core/converters/helpers/BindingHelper.ts +30 -29
- package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +8 -6
- package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +18 -10
- package/src/sap/fe/core/converters/helpers/DataFieldHelper.js +136 -0
- package/src/sap/fe/core/converters/helpers/DataFieldHelper.ts +139 -0
- package/src/sap/fe/core/converters/helpers/ID.js +48 -46
- package/src/sap/fe/core/converters/helpers/ID.ts +26 -25
- package/src/sap/fe/core/converters/helpers/IssueManager.js +1 -1
- package/src/sap/fe/core/converters/helpers/Key.js +7 -7
- package/src/sap/fe/core/converters/helpers/Key.ts +7 -7
- package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.js +1 -1
- package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.ts +4 -5
- package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +6 -6
- package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +10 -10
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +53 -75
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +59 -90
- package/src/sap/fe/core/converters/templates/ListReportConverter.js +58 -57
- package/src/sap/fe/core/converters/templates/ListReportConverter.ts +93 -86
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +58 -44
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +87 -80
- package/src/sap/fe/core/designtime/AppComponent.designtime.js +4 -4
- package/src/sap/fe/core/designtime/AppComponent.designtime.ts +4 -4
- package/src/sap/fe/core/formatters/CollaborationFormatter.js +2 -2
- package/src/sap/fe/core/formatters/CollaborationFormatter.ts +3 -3
- package/src/sap/fe/core/formatters/FPMFormatter.js +5 -5
- package/src/sap/fe/core/formatters/FPMFormatter.ts +10 -10
- package/src/sap/fe/core/formatters/KPIFormatter.js +7 -7
- package/src/sap/fe/core/formatters/KPIFormatter.ts +10 -10
- package/src/sap/fe/core/formatters/StandardFormatter.js +96 -0
- package/src/sap/fe/core/formatters/StandardFormatter.ts +70 -0
- package/src/sap/fe/core/formatters/TableFormatter.js +11 -11
- package/src/sap/fe/core/formatters/TableFormatter.ts +12 -12
- package/src/sap/fe/core/formatters/TableFormatterTypes.js +1 -1
- package/src/sap/fe/core/formatters/ValueFormatter.js +8 -8
- package/src/sap/fe/core/formatters/ValueFormatter.ts +9 -9
- package/src/sap/fe/core/fpm/Component.js +33 -7
- package/src/sap/fe/core/fpm/Component.ts +14 -0
- package/src/sap/fe/core/helpers/AnnotationEnum.js +1 -1
- package/src/sap/fe/core/helpers/AppStartupHelper.js +19 -18
- package/src/sap/fe/core/helpers/AppStartupHelper.ts +41 -43
- package/src/sap/fe/core/helpers/BindingToolkit.js +1836 -0
- package/src/sap/fe/core/helpers/{BindingExpression.ts → BindingToolkit.ts} +397 -270
- package/src/sap/fe/core/helpers/ClassSupport.js +49 -12
- package/src/sap/fe/core/helpers/ClassSupport.ts +37 -10
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +2 -2
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -1
- package/src/sap/fe/core/helpers/EditState.js +1 -6
- package/src/sap/fe/core/helpers/EditState.ts +5 -10
- package/src/sap/fe/core/helpers/ExcelFormatHelper.js +2 -2
- package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +4 -4
- package/src/sap/fe/core/helpers/FPMHelper.js +1 -1
- package/src/sap/fe/core/helpers/FPMHelper.ts +2 -2
- package/src/sap/fe/core/helpers/KeepAliveHelper.js +31 -31
- package/src/sap/fe/core/helpers/KeepAliveHelper.ts +52 -56
- package/src/sap/fe/core/helpers/KeepAliveRefreshTypes.js +1 -1
- package/src/sap/fe/core/helpers/MassEditHelper.js +306 -280
- package/src/sap/fe/core/helpers/MassEditHelper.ts +380 -360
- package/src/sap/fe/core/helpers/MessageStrip.js +81 -0
- package/src/sap/fe/core/helpers/MessageStrip.ts +79 -0
- package/src/sap/fe/core/helpers/ModelHelper.js +25 -25
- package/src/sap/fe/core/helpers/ModelHelper.ts +34 -32
- package/src/sap/fe/core/helpers/PasteHelper.js +3 -10
- package/src/sap/fe/core/helpers/PasteHelper.ts +20 -25
- package/src/sap/fe/core/helpers/SemanticDateOperators.js +1 -1
- package/src/sap/fe/core/helpers/SemanticDateOperators.ts +11 -11
- package/src/sap/fe/core/helpers/SemanticKeyHelper.js +3 -3
- package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +8 -8
- package/src/sap/fe/core/helpers/StableIdHelper.js +12 -12
- package/src/sap/fe/core/helpers/StableIdHelper.ts +12 -12
- package/src/sap/fe/core/helpers/Synchronization.js +1 -1
- package/src/sap/fe/core/helpers/ToES6Promise.js +32 -0
- package/src/sap/fe/core/helpers/ToES6Promise.ts +19 -0
- package/src/sap/fe/core/jsx-runtime/Fragment.js +16 -0
- package/src/sap/fe/core/jsx-runtime/Fragment.ts +3 -0
- package/src/sap/fe/core/jsx-runtime/ViewLoader.js +109 -0
- package/src/sap/fe/core/jsx-runtime/ViewLoader.tsx +47 -0
- package/src/sap/fe/core/jsx-runtime/jsx-control.js +110 -0
- package/src/sap/fe/core/jsx-runtime/jsx-control.ts +92 -0
- package/src/sap/fe/core/jsx-runtime/jsx-xml.js +105 -0
- package/src/sap/fe/core/jsx-runtime/jsx-xml.ts +89 -0
- package/src/sap/fe/core/jsx-runtime/jsx.js +12 -90
- package/src/sap/fe/core/jsx-runtime/jsx.ts +24 -85
- package/src/sap/fe/core/jsx-runtime/jsxs.js +1 -1
- package/src/sap/fe/core/jsx-runtime/useMDXComponents.js +179 -0
- package/src/sap/fe/core/jsx-runtime/useMDXComponents.tsx +150 -0
- package/src/sap/fe/core/library.js +42 -3
- package/src/sap/fe/core/library.support.js +1 -1
- package/src/sap/fe/core/library.ts +38 -0
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +3 -3
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +2 -2
- package/src/sap/fe/core/messagebundle.properties +39 -67
- package/src/sap/fe/core/messagebundle_ar.properties +27 -44
- package/src/sap/fe/core/messagebundle_bg.properties +27 -44
- package/src/sap/fe/core/messagebundle_ca.properties +27 -44
- package/src/sap/fe/core/messagebundle_cs.properties +27 -44
- package/src/sap/fe/core/messagebundle_cy.properties +26 -43
- package/src/sap/fe/core/messagebundle_da.properties +27 -44
- package/src/sap/fe/core/messagebundle_de.properties +25 -42
- package/src/sap/fe/core/messagebundle_el.properties +28 -45
- package/src/sap/fe/core/messagebundle_en.properties +27 -44
- package/src/sap/fe/core/messagebundle_en_GB.properties +27 -44
- package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +25 -42
- package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +26 -40
- package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +25 -42
- package/src/sap/fe/core/messagebundle_es.properties +27 -44
- package/src/sap/fe/core/messagebundle_es_MX.properties +27 -44
- package/src/sap/fe/core/messagebundle_et.properties +27 -44
- package/src/sap/fe/core/messagebundle_fi.properties +27 -44
- package/src/sap/fe/core/messagebundle_fr.properties +26 -43
- package/src/sap/fe/core/messagebundle_fr_CA.properties +25 -42
- package/src/sap/fe/core/messagebundle_hi.properties +27 -44
- package/src/sap/fe/core/messagebundle_hr.properties +27 -44
- package/src/sap/fe/core/messagebundle_hu.properties +27 -44
- package/src/sap/fe/core/messagebundle_id.properties +27 -44
- package/src/sap/fe/core/messagebundle_it.properties +43 -60
- package/src/sap/fe/core/messagebundle_iw.properties +27 -44
- package/src/sap/fe/core/messagebundle_ja.properties +27 -44
- package/src/sap/fe/core/messagebundle_kk.properties +27 -44
- package/src/sap/fe/core/messagebundle_ko.properties +30 -47
- package/src/sap/fe/core/messagebundle_lt.properties +27 -44
- package/src/sap/fe/core/messagebundle_lv.properties +27 -44
- package/src/sap/fe/core/messagebundle_ms.properties +27 -44
- package/src/sap/fe/core/messagebundle_nl.properties +29 -46
- package/src/sap/fe/core/messagebundle_no.properties +27 -44
- package/src/sap/fe/core/messagebundle_pl.properties +28 -45
- package/src/sap/fe/core/messagebundle_pt.properties +28 -45
- package/src/sap/fe/core/messagebundle_pt_PT.properties +27 -44
- package/src/sap/fe/core/messagebundle_ro.properties +27 -44
- package/src/sap/fe/core/messagebundle_ru.properties +27 -44
- package/src/sap/fe/core/messagebundle_sh.properties +27 -44
- package/src/sap/fe/core/messagebundle_sk.properties +27 -44
- package/src/sap/fe/core/messagebundle_sl.properties +27 -44
- package/src/sap/fe/core/messagebundle_sv.properties +27 -44
- package/src/sap/fe/core/messagebundle_th.properties +25 -42
- package/src/sap/fe/core/messagebundle_tr.properties +27 -44
- package/src/sap/fe/core/messagebundle_uk.properties +27 -44
- package/src/sap/fe/core/messagebundle_vi.properties +27 -44
- package/src/sap/fe/core/messagebundle_zh_CN.properties +27 -44
- package/src/sap/fe/core/messagebundle_zh_TW.properties +27 -44
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +3 -3
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +5 -5
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +103 -75
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +72 -73
- package/src/sap/fe/core/services/EnvironmentServiceFactory.js +2 -2
- package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +3 -2
- package/src/sap/fe/core/services/NavigationServiceFactory.js +62 -50
- package/src/sap/fe/core/services/NavigationServiceFactory.ts +63 -52
- package/src/sap/fe/core/services/ResourceModelServiceFactory.js +3 -3
- package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +4 -4
- package/src/sap/fe/core/services/RoutingServiceFactory.js +56 -56
- package/src/sap/fe/core/services/RoutingServiceFactory.ts +67 -65
- package/src/sap/fe/core/services/ShellServicesFactory.js +93 -77
- package/src/sap/fe/core/services/ShellServicesFactory.ts +95 -82
- package/src/sap/fe/core/services/SideEffectsServiceFactory.js +64 -64
- package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +102 -92
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +232 -200
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +145 -142
- package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +2 -2
- 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 +3 -2
- package/src/sap/fe/core/support/CommonHelper.ts +9 -13
- package/src/sap/fe/core/support/Diagnostics.js +1 -1
- package/src/sap/fe/core/support/Diagnostics.ts +5 -5
- package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.js +1 -1
- package/src/sap/fe/core/templating/CommonFormatters.js +85 -0
- package/src/sap/fe/core/templating/CommonFormatters.ts +90 -0
- package/src/sap/fe/core/templating/CriticalityFormatters.js +31 -31
- package/src/sap/fe/core/templating/CriticalityFormatters.ts +42 -40
- package/src/sap/fe/core/templating/DataFieldFormatters.js +8 -8
- package/src/sap/fe/core/templating/DataFieldFormatters.ts +13 -10
- package/src/sap/fe/core/templating/DataModelPathHelper.js +23 -15
- package/src/sap/fe/core/templating/DataModelPathHelper.ts +47 -34
- package/src/sap/fe/core/templating/DisplayModeFormatter.js +1 -1
- package/src/sap/fe/core/templating/DisplayModeFormatter.ts +2 -3
- package/src/sap/fe/core/templating/EntitySetHelper.js +7 -7
- package/src/sap/fe/core/templating/EntitySetHelper.ts +6 -8
- package/src/sap/fe/core/templating/FieldControlHelper.js +35 -34
- package/src/sap/fe/core/templating/FieldControlHelper.ts +29 -46
- package/src/sap/fe/core/templating/FilterHelper.js +18 -17
- package/src/sap/fe/core/templating/FilterHelper.ts +18 -18
- package/src/sap/fe/core/templating/FilterTemplating.js +1 -1
- package/src/sap/fe/core/templating/FilterTemplating.ts +3 -3
- package/src/sap/fe/core/templating/PropertyFormatters.js +7 -7
- package/src/sap/fe/core/templating/PropertyFormatters.ts +21 -19
- package/src/sap/fe/core/templating/PropertyHelper.js +25 -25
- package/src/sap/fe/core/templating/PropertyHelper.ts +25 -26
- package/src/sap/fe/core/templating/UIFormatters.js +152 -95
- package/src/sap/fe/core/templating/UIFormatters.ts +202 -128
- package/src/sap/fe/core/type/DateTimeWithTimezone.js +2 -2
- package/src/sap/fe/core/type/Email.js +3 -3
- package/src/sap/fe/core/type/Email.ts +2 -2
- package/src/sap/fe/core/helpers/BindingExpression.js +0 -1732
|
@@ -0,0 +1,1836 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* SAP UI development toolkit for HTML5 (SAPUI5)
|
|
3
|
+
* (c) Copyright 2009-2021 SAP SE. All rights reserved
|
|
4
|
+
*/
|
|
5
|
+
sap.ui.define(["./AnnotationEnum"], function (AnnotationEnum) {
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
var _exports = {};
|
|
9
|
+
var resolveEnumValue = AnnotationEnum.resolveEnumValue;
|
|
10
|
+
|
|
11
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
12
|
+
|
|
13
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
14
|
+
|
|
15
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
16
|
+
|
|
17
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
18
|
+
|
|
19
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
20
|
+
|
|
21
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
22
|
+
|
|
23
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
24
|
+
|
|
25
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
26
|
+
|
|
27
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
28
|
+
|
|
29
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
30
|
+
|
|
31
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
32
|
+
|
|
33
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
34
|
+
|
|
35
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
36
|
+
|
|
37
|
+
var unresolveableExpression = {
|
|
38
|
+
_type: "Unresolvable"
|
|
39
|
+
};
|
|
40
|
+
_exports.unresolveableExpression = unresolveableExpression;
|
|
41
|
+
|
|
42
|
+
function escapeXmlAttribute(inputString) {
|
|
43
|
+
return inputString.replace(/'/g, "\\'");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function hasUnresolveableExpression() {
|
|
47
|
+
for (var _len = arguments.length, expressions = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
48
|
+
expressions[_key] = arguments[_key];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return expressions.find(function (expr) {
|
|
52
|
+
return expr._type === "Unresolvable";
|
|
53
|
+
}) !== undefined;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check two expressions for (deep) equality.
|
|
57
|
+
*
|
|
58
|
+
* @param a
|
|
59
|
+
* @param b
|
|
60
|
+
* @returns `true` if the two expressions are equal
|
|
61
|
+
* @private
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
_exports.hasUnresolveableExpression = hasUnresolveableExpression;
|
|
66
|
+
|
|
67
|
+
function _checkExpressionsAreEqual(a, b) {
|
|
68
|
+
if (a._type !== b._type) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
switch (a._type) {
|
|
73
|
+
case "Unresolvable":
|
|
74
|
+
return false;
|
|
75
|
+
// Unresolvable is never equal to anything even itself
|
|
76
|
+
|
|
77
|
+
case "Constant":
|
|
78
|
+
case "EmbeddedBinding":
|
|
79
|
+
case "EmbeddedExpressionBinding":
|
|
80
|
+
return a.value === b.value;
|
|
81
|
+
|
|
82
|
+
case "Not":
|
|
83
|
+
return _checkExpressionsAreEqual(a.operand, b.operand);
|
|
84
|
+
|
|
85
|
+
case "Truthy":
|
|
86
|
+
return _checkExpressionsAreEqual(a.operand, b.operand);
|
|
87
|
+
|
|
88
|
+
case "Set":
|
|
89
|
+
return a.operator === b.operator && a.operands.length === b.operands.length && a.operands.every(function (expression) {
|
|
90
|
+
return b.operands.some(function (otherExpression) {
|
|
91
|
+
return _checkExpressionsAreEqual(expression, otherExpression);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
case "IfElse":
|
|
96
|
+
return _checkExpressionsAreEqual(a.condition, b.condition) && _checkExpressionsAreEqual(a.onTrue, b.onTrue) && _checkExpressionsAreEqual(a.onFalse, b.onFalse);
|
|
97
|
+
|
|
98
|
+
case "Comparison":
|
|
99
|
+
return a.operator === b.operator && _checkExpressionsAreEqual(a.operand1, b.operand1) && _checkExpressionsAreEqual(a.operand2, b.operand2);
|
|
100
|
+
|
|
101
|
+
case "Concat":
|
|
102
|
+
var aExpressions = a.expressions;
|
|
103
|
+
var bExpressions = b.expressions;
|
|
104
|
+
|
|
105
|
+
if (aExpressions.length !== bExpressions.length) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return aExpressions.every(function (expression, index) {
|
|
110
|
+
return _checkExpressionsAreEqual(expression, bExpressions[index]);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
case "Length":
|
|
114
|
+
return _checkExpressionsAreEqual(a.pathInModel, b.pathInModel);
|
|
115
|
+
|
|
116
|
+
case "PathInModel":
|
|
117
|
+
return a.modelName === b.modelName && a.path === b.path && a.targetEntitySet === b.targetEntitySet;
|
|
118
|
+
|
|
119
|
+
case "Formatter":
|
|
120
|
+
return a.fn === b.fn && a.parameters.length === b.parameters.length && a.parameters.every(function (value, index) {
|
|
121
|
+
return _checkExpressionsAreEqual(b.parameters[index], value);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
case "ComplexType":
|
|
125
|
+
return a.type === b.type && a.bindingParameters.length === b.bindingParameters.length && a.bindingParameters.every(function (value, index) {
|
|
126
|
+
return _checkExpressionsAreEqual(b.bindingParameters[index], value);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
case "Function":
|
|
130
|
+
var otherFunction = b;
|
|
131
|
+
|
|
132
|
+
if (a.obj === undefined || otherFunction.obj === undefined) {
|
|
133
|
+
return a.obj === otherFunction;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return a.fn === otherFunction.fn && _checkExpressionsAreEqual(a.obj, otherFunction.obj) && a.parameters.length === otherFunction.parameters.length && a.parameters.every(function (value, index) {
|
|
137
|
+
return _checkExpressionsAreEqual(otherFunction.parameters[index], value);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
case "Ref":
|
|
141
|
+
return a.ref === b.ref;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Converts a nested SetExpression by inlining operands of type SetExpression with the same operator.
|
|
148
|
+
*
|
|
149
|
+
* @param expression The expression to flatten
|
|
150
|
+
* @returns A new SetExpression with the same operator
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
_exports._checkExpressionsAreEqual = _checkExpressionsAreEqual;
|
|
155
|
+
|
|
156
|
+
function flattenSetExpression(expression) {
|
|
157
|
+
return expression.operands.reduce(function (result, operand) {
|
|
158
|
+
var candidatesForFlattening = operand._type === "Set" && operand.operator === expression.operator ? operand.operands : [operand];
|
|
159
|
+
candidatesForFlattening.forEach(function (candidate) {
|
|
160
|
+
if (result.operands.every(function (e) {
|
|
161
|
+
return !_checkExpressionsAreEqual(e, candidate);
|
|
162
|
+
})) {
|
|
163
|
+
result.operands.push(candidate);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
return result;
|
|
167
|
+
}, {
|
|
168
|
+
_type: "Set",
|
|
169
|
+
operator: expression.operator,
|
|
170
|
+
operands: []
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Detects whether an array of boolean expressions contains an expression and its negation.
|
|
175
|
+
*
|
|
176
|
+
* @param expressions Array of expressions
|
|
177
|
+
* @returns `true` if the set of expressions contains an expression and its negation
|
|
178
|
+
*/
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
function hasOppositeExpressions(expressions) {
|
|
182
|
+
var negatedExpressions = expressions.map(not);
|
|
183
|
+
return expressions.some(function (expression, index) {
|
|
184
|
+
for (var i = index + 1; i < negatedExpressions.length; i++) {
|
|
185
|
+
if (_checkExpressionsAreEqual(expression, negatedExpressions[i])) {
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return false;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Logical `and` expression.
|
|
195
|
+
*
|
|
196
|
+
* The expression is simplified to false if this can be decided statically (that is, if one operand is a constant
|
|
197
|
+
* false or if the expression contains an operand and its negation).
|
|
198
|
+
*
|
|
199
|
+
* @param operands Expressions to connect by `and`
|
|
200
|
+
* @returns Expression evaluating to boolean
|
|
201
|
+
*/
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
function and() {
|
|
205
|
+
for (var _len2 = arguments.length, operands = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
206
|
+
operands[_key2] = arguments[_key2];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
var expressions = flattenSetExpression({
|
|
210
|
+
_type: "Set",
|
|
211
|
+
operator: "&&",
|
|
212
|
+
operands: operands.map(wrapPrimitive)
|
|
213
|
+
}).operands;
|
|
214
|
+
|
|
215
|
+
if (hasUnresolveableExpression.apply(void 0, _toConsumableArray(expressions))) {
|
|
216
|
+
return unresolveableExpression;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
var isStaticFalse = false;
|
|
220
|
+
var nonTrivialExpression = expressions.filter(function (expression) {
|
|
221
|
+
if (isFalse(expression)) {
|
|
222
|
+
isStaticFalse = true;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return !isConstant(expression);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
if (isStaticFalse) {
|
|
229
|
+
return constant(false);
|
|
230
|
+
} else if (nonTrivialExpression.length === 0) {
|
|
231
|
+
// Resolve the constant then
|
|
232
|
+
var isValid = expressions.reduce(function (result, expression) {
|
|
233
|
+
return result && isTrue(expression);
|
|
234
|
+
}, true);
|
|
235
|
+
return constant(isValid);
|
|
236
|
+
} else if (nonTrivialExpression.length === 1) {
|
|
237
|
+
return nonTrivialExpression[0];
|
|
238
|
+
} else if (hasOppositeExpressions(nonTrivialExpression)) {
|
|
239
|
+
return constant(false);
|
|
240
|
+
} else {
|
|
241
|
+
return {
|
|
242
|
+
_type: "Set",
|
|
243
|
+
operator: "&&",
|
|
244
|
+
operands: nonTrivialExpression
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Logical `or` expression.
|
|
250
|
+
*
|
|
251
|
+
* The expression is simplified to true if this can be decided statically (that is, if one operand is a constant
|
|
252
|
+
* true or if the expression contains an operand and its negation).
|
|
253
|
+
*
|
|
254
|
+
* @param operands Expressions to connect by `or`
|
|
255
|
+
* @returns Expression evaluating to boolean
|
|
256
|
+
*/
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
_exports.and = and;
|
|
260
|
+
|
|
261
|
+
function or() {
|
|
262
|
+
for (var _len3 = arguments.length, operands = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
263
|
+
operands[_key3] = arguments[_key3];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
var expressions = flattenSetExpression({
|
|
267
|
+
_type: "Set",
|
|
268
|
+
operator: "||",
|
|
269
|
+
operands: operands.map(wrapPrimitive)
|
|
270
|
+
}).operands;
|
|
271
|
+
|
|
272
|
+
if (hasUnresolveableExpression.apply(void 0, _toConsumableArray(expressions))) {
|
|
273
|
+
return unresolveableExpression;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
var isStaticTrue = false;
|
|
277
|
+
var nonTrivialExpression = expressions.filter(function (expression) {
|
|
278
|
+
if (isTrue(expression)) {
|
|
279
|
+
isStaticTrue = true;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return !isConstant(expression) || expression.value;
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
if (isStaticTrue) {
|
|
286
|
+
return constant(true);
|
|
287
|
+
} else if (nonTrivialExpression.length === 0) {
|
|
288
|
+
// Resolve the constant then
|
|
289
|
+
var isValid = expressions.reduce(function (result, expression) {
|
|
290
|
+
return result && isTrue(expression);
|
|
291
|
+
}, true);
|
|
292
|
+
return constant(isValid);
|
|
293
|
+
} else if (nonTrivialExpression.length === 1) {
|
|
294
|
+
return nonTrivialExpression[0];
|
|
295
|
+
} else if (hasOppositeExpressions(nonTrivialExpression)) {
|
|
296
|
+
return constant(true);
|
|
297
|
+
} else {
|
|
298
|
+
return {
|
|
299
|
+
_type: "Set",
|
|
300
|
+
operator: "||",
|
|
301
|
+
operands: nonTrivialExpression
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Logical `not` operator.
|
|
307
|
+
*
|
|
308
|
+
* @param operand The expression to reverse
|
|
309
|
+
* @returns The resulting expression that evaluates to boolean
|
|
310
|
+
*/
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
_exports.or = or;
|
|
314
|
+
|
|
315
|
+
function not(operand) {
|
|
316
|
+
operand = wrapPrimitive(operand);
|
|
317
|
+
|
|
318
|
+
if (hasUnresolveableExpression(operand)) {
|
|
319
|
+
return unresolveableExpression;
|
|
320
|
+
} else if (isConstant(operand)) {
|
|
321
|
+
return constant(!operand.value);
|
|
322
|
+
} else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "||" && operand.operands.every(function (expression) {
|
|
323
|
+
return isConstant(expression) || isComparison(expression);
|
|
324
|
+
})) {
|
|
325
|
+
return and.apply(void 0, _toConsumableArray(operand.operands.map(function (expression) {
|
|
326
|
+
return not(expression);
|
|
327
|
+
})));
|
|
328
|
+
} else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "&&" && operand.operands.every(function (expression) {
|
|
329
|
+
return isConstant(expression) || isComparison(expression);
|
|
330
|
+
})) {
|
|
331
|
+
return or.apply(void 0, _toConsumableArray(operand.operands.map(function (expression) {
|
|
332
|
+
return not(expression);
|
|
333
|
+
})));
|
|
334
|
+
} else if (isComparison(operand)) {
|
|
335
|
+
// Create the reverse comparison
|
|
336
|
+
switch (operand.operator) {
|
|
337
|
+
case "!==":
|
|
338
|
+
return _objectSpread(_objectSpread({}, operand), {}, {
|
|
339
|
+
operator: "==="
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
case "<":
|
|
343
|
+
return _objectSpread(_objectSpread({}, operand), {}, {
|
|
344
|
+
operator: ">="
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
case "<=":
|
|
348
|
+
return _objectSpread(_objectSpread({}, operand), {}, {
|
|
349
|
+
operator: ">"
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
case "===":
|
|
353
|
+
return _objectSpread(_objectSpread({}, operand), {}, {
|
|
354
|
+
operator: "!=="
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
case ">":
|
|
358
|
+
return _objectSpread(_objectSpread({}, operand), {}, {
|
|
359
|
+
operator: "<="
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
case ">=":
|
|
363
|
+
return _objectSpread(_objectSpread({}, operand), {}, {
|
|
364
|
+
operator: "<"
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
} else if (operand._type === "Not") {
|
|
368
|
+
return operand.operand;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return {
|
|
372
|
+
_type: "Not",
|
|
373
|
+
operand: operand
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Evaluates whether a binding expression is equal to true with a loose equality.
|
|
378
|
+
*
|
|
379
|
+
* @param operand The expression to check
|
|
380
|
+
* @returns The resulting expression that evaluates to boolean
|
|
381
|
+
*/
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
_exports.not = not;
|
|
385
|
+
|
|
386
|
+
function isTruthy(operand) {
|
|
387
|
+
if (isConstant(operand)) {
|
|
388
|
+
return constant(!!operand.value);
|
|
389
|
+
} else {
|
|
390
|
+
return {
|
|
391
|
+
_type: "Truthy",
|
|
392
|
+
operand: operand
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Creates a binding expression that will be evaluated by the corresponding model.
|
|
398
|
+
*
|
|
399
|
+
* @param path
|
|
400
|
+
* @param modelName
|
|
401
|
+
* @param visitedNavigationPaths
|
|
402
|
+
* @param pathVisitor
|
|
403
|
+
* @returns An expression representating that path in the model
|
|
404
|
+
* @deprecated use pathInModel instead
|
|
405
|
+
*/
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
_exports.isTruthy = isTruthy;
|
|
409
|
+
|
|
410
|
+
function bindingExpression(path, modelName) {
|
|
411
|
+
var visitedNavigationPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
412
|
+
var pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
|
|
413
|
+
return pathInModel(path, modelName, visitedNavigationPaths, pathVisitor);
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Creates a binding expression that will be evaluated by the corresponding model.
|
|
417
|
+
*
|
|
418
|
+
* @template TargetType
|
|
419
|
+
* @param path The path on the model
|
|
420
|
+
* @param [modelName] The name of the model
|
|
421
|
+
* @param [visitedNavigationPaths] The paths from the root entitySet
|
|
422
|
+
* @param [pathVisitor] A function to modify the resulting path
|
|
423
|
+
* @returns An expression representating that path in the model
|
|
424
|
+
*/
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
_exports.bindingExpression = bindingExpression;
|
|
428
|
+
|
|
429
|
+
function pathInModel(path, modelName) {
|
|
430
|
+
var visitedNavigationPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
431
|
+
var pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
|
|
432
|
+
|
|
433
|
+
if (path === undefined) {
|
|
434
|
+
return unresolveableExpression;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
var targetPath;
|
|
438
|
+
|
|
439
|
+
if (pathVisitor) {
|
|
440
|
+
targetPath = pathVisitor(path);
|
|
441
|
+
|
|
442
|
+
if (targetPath === undefined) {
|
|
443
|
+
return unresolveableExpression;
|
|
444
|
+
}
|
|
445
|
+
} else {
|
|
446
|
+
var localPath = visitedNavigationPaths.concat();
|
|
447
|
+
localPath.push(path);
|
|
448
|
+
targetPath = localPath.join("/");
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return {
|
|
452
|
+
_type: "PathInModel",
|
|
453
|
+
modelName: modelName,
|
|
454
|
+
path: targetPath
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
_exports.pathInModel = pathInModel;
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Creates a constant expression based on a primitive value.
|
|
462
|
+
*
|
|
463
|
+
* @template T
|
|
464
|
+
* @param value The constant to wrap in an expression
|
|
465
|
+
* @returns The constant expression
|
|
466
|
+
*/
|
|
467
|
+
function constant(value) {
|
|
468
|
+
var constantValue;
|
|
469
|
+
|
|
470
|
+
if (typeof value === "object" && value !== null && value !== undefined) {
|
|
471
|
+
if (Array.isArray(value)) {
|
|
472
|
+
constantValue = value.map(wrapPrimitive);
|
|
473
|
+
} else if (isPrimitiveObject(value)) {
|
|
474
|
+
constantValue = value.valueOf();
|
|
475
|
+
} else {
|
|
476
|
+
constantValue = Object.entries(value).reduce(function (plainExpression, _ref) {
|
|
477
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
478
|
+
key = _ref2[0],
|
|
479
|
+
val = _ref2[1];
|
|
480
|
+
|
|
481
|
+
var wrappedValue = wrapPrimitive(val);
|
|
482
|
+
|
|
483
|
+
if (wrappedValue._type !== "Constant" || wrappedValue.value !== undefined) {
|
|
484
|
+
plainExpression[key] = wrappedValue;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return plainExpression;
|
|
488
|
+
}, {});
|
|
489
|
+
}
|
|
490
|
+
} else {
|
|
491
|
+
constantValue = value;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
return {
|
|
495
|
+
_type: "Constant",
|
|
496
|
+
value: constantValue
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
_exports.constant = constant;
|
|
501
|
+
|
|
502
|
+
function resolveBindingString(value, targetType) {
|
|
503
|
+
if (value !== undefined && typeof value === "string" && value.startsWith("{")) {
|
|
504
|
+
if (value.startsWith("{=")) {
|
|
505
|
+
// Expression binding, we can just remove the outer binding things
|
|
506
|
+
return {
|
|
507
|
+
_type: "EmbeddedExpressionBinding",
|
|
508
|
+
value: value
|
|
509
|
+
};
|
|
510
|
+
} else {
|
|
511
|
+
return {
|
|
512
|
+
_type: "EmbeddedBinding",
|
|
513
|
+
value: value
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
} else if (targetType === "boolean" && typeof value === "string" && (value === "true" || value === "false")) {
|
|
517
|
+
return constant(value === "true");
|
|
518
|
+
} else {
|
|
519
|
+
return constant(value);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* A named reference.
|
|
524
|
+
*
|
|
525
|
+
* @see fn
|
|
526
|
+
* @param reference Reference
|
|
527
|
+
* @returns The object reference binding part
|
|
528
|
+
*/
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
_exports.resolveBindingString = resolveBindingString;
|
|
532
|
+
|
|
533
|
+
function ref(reference) {
|
|
534
|
+
return {
|
|
535
|
+
_type: "Ref",
|
|
536
|
+
ref: reference
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Determine whether the type is an expression.
|
|
541
|
+
*
|
|
542
|
+
* Every object having a property named `_type` of some value is considered an expression, even if there is actually
|
|
543
|
+
* no such expression type supported.
|
|
544
|
+
*
|
|
545
|
+
* @param something Type to check
|
|
546
|
+
* @returns `true` if the type is considered to be an expression
|
|
547
|
+
*/
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
_exports.ref = ref;
|
|
551
|
+
|
|
552
|
+
function isExpression(something) {
|
|
553
|
+
return something !== null && typeof something === "object" && something._type !== undefined;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Wrap a primitive into a constant expression if it is not already an expression.
|
|
557
|
+
*
|
|
558
|
+
* @template T
|
|
559
|
+
* @param something The object to wrap in a Constant expression
|
|
560
|
+
* @returns Either the original object or the wrapped one depending on the case
|
|
561
|
+
*/
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
function wrapPrimitive(something) {
|
|
565
|
+
if (isExpression(something)) {
|
|
566
|
+
return something;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
return constant(something);
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Checks if the expression or value provided is constant or not.
|
|
573
|
+
*
|
|
574
|
+
* @template T The target type
|
|
575
|
+
* @param maybeConstant The expression or primitive value that is to be checked
|
|
576
|
+
* @returns `true` if it is constant
|
|
577
|
+
*/
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
function isConstant(maybeConstant) {
|
|
581
|
+
return typeof maybeConstant !== "object" || maybeConstant._type === "Constant";
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
_exports.isConstant = isConstant;
|
|
585
|
+
|
|
586
|
+
function isTrue(expression) {
|
|
587
|
+
return isConstant(expression) && expression.value === true;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
function isFalse(expression) {
|
|
591
|
+
return isConstant(expression) && expression.value === false;
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Checks if the expression or value provided is a path in model expression or not.
|
|
595
|
+
*
|
|
596
|
+
* @template T The target type
|
|
597
|
+
* @param maybeBinding The expression or primitive value that is to be checked
|
|
598
|
+
* @returns `true` if it is a path in model expression
|
|
599
|
+
*/
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
function isPathInModelExpression(maybeBinding) {
|
|
603
|
+
return typeof maybeBinding === "object" && maybeBinding._type === "PathInModel";
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Checks if the expression or value provided is a complex type expression.
|
|
607
|
+
*
|
|
608
|
+
* @template T The target type
|
|
609
|
+
* @param maybeBinding The expression or primitive value that is to be checked
|
|
610
|
+
* @returns `true` if it is a path in model expression
|
|
611
|
+
*/
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
_exports.isPathInModelExpression = isPathInModelExpression;
|
|
615
|
+
|
|
616
|
+
function isComplexTypeExpression(maybeBinding) {
|
|
617
|
+
return typeof maybeBinding === "object" && maybeBinding._type === "ComplexType";
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Checks if the expression provided is a comparison or not.
|
|
621
|
+
*
|
|
622
|
+
* @template T The target type
|
|
623
|
+
* @param expression The expression
|
|
624
|
+
* @returns `true` if the expression is a ComparisonExpression
|
|
625
|
+
*/
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
_exports.isComplexTypeExpression = isComplexTypeExpression;
|
|
629
|
+
|
|
630
|
+
function isComparison(expression) {
|
|
631
|
+
return expression._type === "Comparison";
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
function isPrimitiveObject(objectType) {
|
|
635
|
+
switch (objectType.constructor.name) {
|
|
636
|
+
case "String":
|
|
637
|
+
case "Number":
|
|
638
|
+
case "Boolean":
|
|
639
|
+
return true;
|
|
640
|
+
|
|
641
|
+
default:
|
|
642
|
+
return false;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Check if the passed annotation annotationValue is a ComplexAnnotationExpression.
|
|
647
|
+
*
|
|
648
|
+
* @template T The target type
|
|
649
|
+
* @param annotationValue The annotation annotationValue to evaluate
|
|
650
|
+
* @returns `true` if the object is a {ComplexAnnotationExpression}
|
|
651
|
+
*/
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
function isComplexAnnotationExpression(annotationValue) {
|
|
655
|
+
return typeof annotationValue === "object" && !isPrimitiveObject(annotationValue);
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Generate the corresponding annotationValue for a given annotation annotationValue.
|
|
659
|
+
*
|
|
660
|
+
* @template T The target type
|
|
661
|
+
* @param annotationValue The source annotation annotationValue
|
|
662
|
+
* @param visitedNavigationPaths The path from the root entity set
|
|
663
|
+
* @param defaultValue Default value if the annotationValue is undefined
|
|
664
|
+
* @param pathVisitor A function to modify the resulting path
|
|
665
|
+
* @returns The annotationValue equivalent to that annotation annotationValue
|
|
666
|
+
* @deprecated use getExpressionFromAnnotation instead
|
|
667
|
+
*/
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
function annotationExpression(annotationValue) {
|
|
671
|
+
var visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
672
|
+
var defaultValue = arguments.length > 2 ? arguments[2] : undefined;
|
|
673
|
+
var pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
|
|
674
|
+
return getExpressionFromAnnotation(annotationValue, visitedNavigationPaths, defaultValue, pathVisitor);
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Generate the corresponding annotationValue for a given annotation annotationValue.
|
|
678
|
+
*
|
|
679
|
+
* @template T The target type
|
|
680
|
+
* @param annotationValue The source annotation annotationValue
|
|
681
|
+
* @param visitedNavigationPaths The path from the root entity set
|
|
682
|
+
* @param defaultValue Default value if the annotationValue is undefined
|
|
683
|
+
* @param pathVisitor A function to modify the resulting path
|
|
684
|
+
* @returns The annotationValue equivalent to that annotation annotationValue
|
|
685
|
+
*/
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
_exports.annotationExpression = annotationExpression;
|
|
689
|
+
|
|
690
|
+
function getExpressionFromAnnotation(annotationValue) {
|
|
691
|
+
var _annotationValue;
|
|
692
|
+
|
|
693
|
+
var visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
694
|
+
var defaultValue = arguments.length > 2 ? arguments[2] : undefined;
|
|
695
|
+
var pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
|
|
696
|
+
|
|
697
|
+
if (annotationValue === undefined) {
|
|
698
|
+
return wrapPrimitive(defaultValue);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
annotationValue = (_annotationValue = annotationValue) === null || _annotationValue === void 0 ? void 0 : _annotationValue.valueOf();
|
|
702
|
+
|
|
703
|
+
if (!isComplexAnnotationExpression(annotationValue)) {
|
|
704
|
+
return constant(annotationValue);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
switch (annotationValue.type) {
|
|
708
|
+
case "Path":
|
|
709
|
+
return pathInModel(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
|
|
710
|
+
|
|
711
|
+
case "If":
|
|
712
|
+
return annotationIfExpression(annotationValue.If, visitedNavigationPaths, pathVisitor);
|
|
713
|
+
|
|
714
|
+
case "Not":
|
|
715
|
+
return not(parseAnnotationCondition(annotationValue.Not, visitedNavigationPaths, pathVisitor));
|
|
716
|
+
|
|
717
|
+
case "Eq":
|
|
718
|
+
return equal(parseAnnotationCondition(annotationValue.Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Eq[1], visitedNavigationPaths, pathVisitor));
|
|
719
|
+
|
|
720
|
+
case "Ne":
|
|
721
|
+
return notEqual(parseAnnotationCondition(annotationValue.Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Ne[1], visitedNavigationPaths, pathVisitor));
|
|
722
|
+
|
|
723
|
+
case "Gt":
|
|
724
|
+
return greaterThan(parseAnnotationCondition(annotationValue.Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Gt[1], visitedNavigationPaths, pathVisitor));
|
|
725
|
+
|
|
726
|
+
case "Ge":
|
|
727
|
+
return greaterOrEqual(parseAnnotationCondition(annotationValue.Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Ge[1], visitedNavigationPaths, pathVisitor));
|
|
728
|
+
|
|
729
|
+
case "Lt":
|
|
730
|
+
return lessThan(parseAnnotationCondition(annotationValue.Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Lt[1], visitedNavigationPaths, pathVisitor));
|
|
731
|
+
|
|
732
|
+
case "Le":
|
|
733
|
+
return lessOrEqual(parseAnnotationCondition(annotationValue.Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Le[1], visitedNavigationPaths, pathVisitor));
|
|
734
|
+
|
|
735
|
+
case "Or":
|
|
736
|
+
return or.apply(void 0, _toConsumableArray(annotationValue.Or.map(function (orCondition) {
|
|
737
|
+
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
738
|
+
})));
|
|
739
|
+
|
|
740
|
+
case "And":
|
|
741
|
+
return and.apply(void 0, _toConsumableArray(annotationValue.And.map(function (andCondition) {
|
|
742
|
+
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
743
|
+
})));
|
|
744
|
+
|
|
745
|
+
case "Apply":
|
|
746
|
+
return annotationApplyExpression(annotationValue, visitedNavigationPaths, pathVisitor);
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
return unresolveableExpression;
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Parse the annotation condition into an expression.
|
|
753
|
+
*
|
|
754
|
+
* @template T The target type
|
|
755
|
+
* @param annotationValue The condition or value from the annotation
|
|
756
|
+
* @param visitedNavigationPaths The path from the root entity set
|
|
757
|
+
* @param pathVisitor A function to modify the resulting path
|
|
758
|
+
* @returns An equivalent expression
|
|
759
|
+
*/
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
_exports.getExpressionFromAnnotation = getExpressionFromAnnotation;
|
|
763
|
+
|
|
764
|
+
function parseAnnotationCondition(annotationValue) {
|
|
765
|
+
var visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
766
|
+
var pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
|
|
767
|
+
|
|
768
|
+
if (annotationValue === null || typeof annotationValue !== "object") {
|
|
769
|
+
return constant(annotationValue);
|
|
770
|
+
} else if (annotationValue.hasOwnProperty("$Or")) {
|
|
771
|
+
return or.apply(void 0, _toConsumableArray(annotationValue.$Or.map(function (orCondition) {
|
|
772
|
+
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
773
|
+
})));
|
|
774
|
+
} else if (annotationValue.hasOwnProperty("$And")) {
|
|
775
|
+
return and.apply(void 0, _toConsumableArray(annotationValue.$And.map(function (andCondition) {
|
|
776
|
+
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
777
|
+
})));
|
|
778
|
+
} else if (annotationValue.hasOwnProperty("$Not")) {
|
|
779
|
+
return not(parseAnnotationCondition(annotationValue.$Not, visitedNavigationPaths, pathVisitor));
|
|
780
|
+
} else if (annotationValue.hasOwnProperty("$Eq")) {
|
|
781
|
+
return equal(parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor));
|
|
782
|
+
} else if (annotationValue.hasOwnProperty("$Ne")) {
|
|
783
|
+
return notEqual(parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor));
|
|
784
|
+
} else if (annotationValue.hasOwnProperty("$Gt")) {
|
|
785
|
+
return greaterThan(parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor));
|
|
786
|
+
} else if (annotationValue.hasOwnProperty("$Ge")) {
|
|
787
|
+
return greaterOrEqual(parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor));
|
|
788
|
+
} else if (annotationValue.hasOwnProperty("$Lt")) {
|
|
789
|
+
return lessThan(parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor));
|
|
790
|
+
} else if (annotationValue.hasOwnProperty("$Le")) {
|
|
791
|
+
return lessOrEqual(parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor));
|
|
792
|
+
} else if (annotationValue.hasOwnProperty("$Path")) {
|
|
793
|
+
return pathInModel(annotationValue.$Path, undefined, visitedNavigationPaths, pathVisitor);
|
|
794
|
+
} else if (annotationValue.hasOwnProperty("$Apply")) {
|
|
795
|
+
return getExpressionFromAnnotation({
|
|
796
|
+
type: "Apply",
|
|
797
|
+
Function: annotationValue.$Function,
|
|
798
|
+
Apply: annotationValue.$Apply
|
|
799
|
+
}, visitedNavigationPaths, undefined, pathVisitor);
|
|
800
|
+
} else if (annotationValue.hasOwnProperty("$If")) {
|
|
801
|
+
return getExpressionFromAnnotation({
|
|
802
|
+
type: "If",
|
|
803
|
+
If: annotationValue.$If
|
|
804
|
+
}, visitedNavigationPaths, undefined, pathVisitor);
|
|
805
|
+
} else if (annotationValue.hasOwnProperty("$EnumMember")) {
|
|
806
|
+
return constant(resolveEnumValue(annotationValue.$EnumMember));
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
return constant(false);
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Process the {IfAnnotationExpressionValue} into an expression.
|
|
813
|
+
*
|
|
814
|
+
* @template T The target type
|
|
815
|
+
* @param annotationValue An If expression returning the type T
|
|
816
|
+
* @param visitedNavigationPaths The path from the root entity set
|
|
817
|
+
* @param pathVisitor A function to modify the resulting path
|
|
818
|
+
* @returns The equivalent ifElse expression
|
|
819
|
+
*/
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
function annotationIfExpression(annotationValue) {
|
|
823
|
+
var visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
824
|
+
var pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
|
|
825
|
+
return ifElse(parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[1], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[2], visitedNavigationPaths, pathVisitor));
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
_exports.annotationIfExpression = annotationIfExpression;
|
|
829
|
+
|
|
830
|
+
function annotationApplyExpression(applyExpression) {
|
|
831
|
+
var visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
832
|
+
var pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
|
|
833
|
+
|
|
834
|
+
switch (applyExpression.Function) {
|
|
835
|
+
case "odata.concat":
|
|
836
|
+
return concat.apply(void 0, _toConsumableArray(applyExpression.Apply.map(function (applyParam) {
|
|
837
|
+
var applyParamConverted = applyParam;
|
|
838
|
+
|
|
839
|
+
if (applyParam.hasOwnProperty("$Path")) {
|
|
840
|
+
applyParamConverted = {
|
|
841
|
+
type: "Path",
|
|
842
|
+
path: applyParam.$Path
|
|
843
|
+
};
|
|
844
|
+
} else if (applyParam.hasOwnProperty("$If")) {
|
|
845
|
+
applyParamConverted = {
|
|
846
|
+
type: "If",
|
|
847
|
+
If: applyParam.$If
|
|
848
|
+
};
|
|
849
|
+
} else if (applyParam.hasOwnProperty("$Apply")) {
|
|
850
|
+
applyParamConverted = {
|
|
851
|
+
type: "Apply",
|
|
852
|
+
Function: applyParam.$Function,
|
|
853
|
+
Apply: applyParam.$Apply
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
return getExpressionFromAnnotation(applyParamConverted, visitedNavigationPaths, undefined, pathVisitor);
|
|
858
|
+
})));
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
return unresolveableExpression;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Generic helper for the comparison operations (equal, notEqual, ...).
|
|
865
|
+
*
|
|
866
|
+
* @template T The target type
|
|
867
|
+
* @param operator The operator to apply
|
|
868
|
+
* @param leftOperand The operand on the left side of the operator
|
|
869
|
+
* @param rightOperand The operand on the right side of the operator
|
|
870
|
+
* @returns An expression representing the comparison
|
|
871
|
+
*/
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
_exports.annotationApplyExpression = annotationApplyExpression;
|
|
875
|
+
|
|
876
|
+
function comparison(operator, leftOperand, rightOperand) {
|
|
877
|
+
var leftExpression = wrapPrimitive(leftOperand);
|
|
878
|
+
var rightExpression = wrapPrimitive(rightOperand);
|
|
879
|
+
|
|
880
|
+
if (hasUnresolveableExpression(leftExpression, rightExpression)) {
|
|
881
|
+
return unresolveableExpression;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
if (isConstant(leftExpression) && isConstant(rightExpression)) {
|
|
885
|
+
switch (operator) {
|
|
886
|
+
case "!==":
|
|
887
|
+
return constant(leftExpression.value !== rightExpression.value);
|
|
888
|
+
|
|
889
|
+
case "<":
|
|
890
|
+
return constant(leftExpression.value < rightExpression.value);
|
|
891
|
+
|
|
892
|
+
case "<=":
|
|
893
|
+
return constant(leftExpression.value <= rightExpression.value);
|
|
894
|
+
|
|
895
|
+
case ">":
|
|
896
|
+
return constant(leftExpression.value > rightExpression.value);
|
|
897
|
+
|
|
898
|
+
case ">=":
|
|
899
|
+
return constant(leftExpression.value >= rightExpression.value);
|
|
900
|
+
|
|
901
|
+
case "===":
|
|
902
|
+
return constant(leftExpression.value === rightExpression.value);
|
|
903
|
+
}
|
|
904
|
+
} else {
|
|
905
|
+
return {
|
|
906
|
+
_type: "Comparison",
|
|
907
|
+
operator: operator,
|
|
908
|
+
operand1: leftExpression,
|
|
909
|
+
operand2: rightExpression
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
function length(expression) {
|
|
915
|
+
if (expression._type === "Unresolvable") {
|
|
916
|
+
return expression;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
return {
|
|
920
|
+
_type: "Length",
|
|
921
|
+
pathInModel: expression
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* Comparison: "equal" (===).
|
|
926
|
+
*
|
|
927
|
+
* @template T The target type
|
|
928
|
+
* @param leftOperand The operand on the left side
|
|
929
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
930
|
+
* @returns An expression representing the comparison
|
|
931
|
+
*/
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
_exports.length = length;
|
|
935
|
+
|
|
936
|
+
function equal(leftOperand, rightOperand) {
|
|
937
|
+
var _reduce;
|
|
938
|
+
|
|
939
|
+
var leftExpression = wrapPrimitive(leftOperand);
|
|
940
|
+
var rightExpression = wrapPrimitive(rightOperand);
|
|
941
|
+
|
|
942
|
+
if (hasUnresolveableExpression(leftExpression, rightExpression)) {
|
|
943
|
+
return unresolveableExpression;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
if (_checkExpressionsAreEqual(leftExpression, rightExpression)) {
|
|
947
|
+
return constant(true);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
function reduce(left, right) {
|
|
951
|
+
if (left._type === "Comparison" && isTrue(right)) {
|
|
952
|
+
// compare(a, b) === true ~~> compare(a, b)
|
|
953
|
+
return left;
|
|
954
|
+
} else if (left._type === "Comparison" && isFalse(right)) {
|
|
955
|
+
// compare(a, b) === false ~~> !compare(a, b)
|
|
956
|
+
return not(left);
|
|
957
|
+
} else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onTrue, right)) {
|
|
958
|
+
// (if (x) { a } else { b }) === a ~~> x || (b === a)
|
|
959
|
+
return or(left.condition, equal(left.onFalse, right));
|
|
960
|
+
} else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onFalse, right)) {
|
|
961
|
+
// (if (x) { a } else { b }) === b ~~> !x || (a === b)
|
|
962
|
+
return or(not(left.condition), equal(left.onTrue, right));
|
|
963
|
+
} else if (left._type === "IfElse" && isConstant(left.onTrue) && isConstant(left.onFalse) && isConstant(right) && !_checkExpressionsAreEqual(left.onTrue, right) && !_checkExpressionsAreEqual(left.onFalse, right)) {
|
|
964
|
+
return constant(false);
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
return undefined;
|
|
968
|
+
} // exploit symmetry: a === b <~> b === a
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
var reduced = (_reduce = reduce(leftExpression, rightExpression)) !== null && _reduce !== void 0 ? _reduce : reduce(rightExpression, leftExpression);
|
|
972
|
+
return reduced !== null && reduced !== void 0 ? reduced : comparison("===", leftExpression, rightExpression);
|
|
973
|
+
}
|
|
974
|
+
/**
|
|
975
|
+
* Comparison: "not equal" (!==).
|
|
976
|
+
*
|
|
977
|
+
* @template T The target type
|
|
978
|
+
* @param leftOperand The operand on the left side
|
|
979
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
980
|
+
* @returns An expression representing the comparison
|
|
981
|
+
*/
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
_exports.equal = equal;
|
|
985
|
+
|
|
986
|
+
function notEqual(leftOperand, rightOperand) {
|
|
987
|
+
return not(equal(leftOperand, rightOperand));
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* Comparison: "greater or equal" (>=).
|
|
991
|
+
*
|
|
992
|
+
* @template T The target type
|
|
993
|
+
* @param leftOperand The operand on the left side
|
|
994
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
995
|
+
* @returns An expression representing the comparison
|
|
996
|
+
*/
|
|
997
|
+
|
|
998
|
+
|
|
999
|
+
_exports.notEqual = notEqual;
|
|
1000
|
+
|
|
1001
|
+
function greaterOrEqual(leftOperand, rightOperand) {
|
|
1002
|
+
return comparison(">=", leftOperand, rightOperand);
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Comparison: "greater than" (>).
|
|
1006
|
+
*
|
|
1007
|
+
* @template T The target type
|
|
1008
|
+
* @param leftOperand The operand on the left side
|
|
1009
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1010
|
+
* @returns An expression representing the comparison
|
|
1011
|
+
*/
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
_exports.greaterOrEqual = greaterOrEqual;
|
|
1015
|
+
|
|
1016
|
+
function greaterThan(leftOperand, rightOperand) {
|
|
1017
|
+
return comparison(">", leftOperand, rightOperand);
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Comparison: "less or equal" (<=).
|
|
1021
|
+
*
|
|
1022
|
+
* @template T The target type
|
|
1023
|
+
* @param leftOperand The operand on the left side
|
|
1024
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1025
|
+
* @returns An expression representing the comparison
|
|
1026
|
+
*/
|
|
1027
|
+
|
|
1028
|
+
|
|
1029
|
+
_exports.greaterThan = greaterThan;
|
|
1030
|
+
|
|
1031
|
+
function lessOrEqual(leftOperand, rightOperand) {
|
|
1032
|
+
return comparison("<=", leftOperand, rightOperand);
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* Comparison: "less than" (<).
|
|
1036
|
+
*
|
|
1037
|
+
* @template T The target type
|
|
1038
|
+
* @param leftOperand The operand on the left side
|
|
1039
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1040
|
+
* @returns An expression representing the comparison
|
|
1041
|
+
*/
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
_exports.lessOrEqual = lessOrEqual;
|
|
1045
|
+
|
|
1046
|
+
function lessThan(leftOperand, rightOperand) {
|
|
1047
|
+
return comparison("<", leftOperand, rightOperand);
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* If-then-else expression.
|
|
1051
|
+
*
|
|
1052
|
+
* Evaluates to onTrue if the condition evaluates to true, else evaluates to onFalse.
|
|
1053
|
+
*
|
|
1054
|
+
* @template T The target type
|
|
1055
|
+
* @param condition The condition to evaluate
|
|
1056
|
+
* @param onTrue Expression result if the condition evaluates to true
|
|
1057
|
+
* @param onFalse Expression result if the condition evaluates to false
|
|
1058
|
+
* @returns The expression that represents this conditional check
|
|
1059
|
+
*/
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
_exports.lessThan = lessThan;
|
|
1063
|
+
|
|
1064
|
+
function ifElse(condition, onTrue, onFalse) {
|
|
1065
|
+
var conditionExpression = wrapPrimitive(condition);
|
|
1066
|
+
var onTrueExpression = wrapPrimitive(onTrue);
|
|
1067
|
+
var onFalseExpression = wrapPrimitive(onFalse);
|
|
1068
|
+
|
|
1069
|
+
if (hasUnresolveableExpression(conditionExpression, onTrueExpression, onFalseExpression)) {
|
|
1070
|
+
return unresolveableExpression;
|
|
1071
|
+
} // swap branches if the condition is a negation
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
if (conditionExpression._type === "Not") {
|
|
1075
|
+
// ifElse(not(X), a, b) --> ifElse(X, b, a)
|
|
1076
|
+
var _ref3 = [onFalseExpression, onTrueExpression];
|
|
1077
|
+
onTrueExpression = _ref3[0];
|
|
1078
|
+
onFalseExpression = _ref3[1];
|
|
1079
|
+
conditionExpression = not(conditionExpression);
|
|
1080
|
+
} // inline nested if-else expressions: onTrue branch
|
|
1081
|
+
// ifElse(X, ifElse(X, a, b), c) ==> ifElse(X, a, c)
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
if (onTrueExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onTrueExpression.condition)) {
|
|
1085
|
+
onTrueExpression = onTrueExpression.onTrue;
|
|
1086
|
+
} // inline nested if-else expressions: onFalse branch
|
|
1087
|
+
// ifElse(X, a, ifElse(X, b, c)) ==> ifElse(X, a, c)
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
if (onFalseExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onFalseExpression.condition)) {
|
|
1091
|
+
onFalseExpression = onFalseExpression.onFalse;
|
|
1092
|
+
} // (if true then a else b) ~~> a
|
|
1093
|
+
// (if false then a else b) ~~> b
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
if (isConstant(conditionExpression)) {
|
|
1097
|
+
return conditionExpression.value ? onTrueExpression : onFalseExpression;
|
|
1098
|
+
} // if (isConstantBoolean(onTrueExpression) || isConstantBoolean(onFalseExpression)) {
|
|
1099
|
+
// return or(and(condition, onTrueExpression as Expression<boolean>), and(not(condition), onFalseExpression as Expression<boolean>)) as Expression<T>
|
|
1100
|
+
// }
|
|
1101
|
+
// (if X then a else a) ~~> a
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
if (_checkExpressionsAreEqual(onTrueExpression, onFalseExpression)) {
|
|
1105
|
+
return onTrueExpression;
|
|
1106
|
+
} // if X then a else false ~~> X && a
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
if (isFalse(onFalseExpression)) {
|
|
1110
|
+
return and(conditionExpression, onTrueExpression);
|
|
1111
|
+
} // if X then a else true ~~> !X || a
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
if (isTrue(onFalseExpression)) {
|
|
1115
|
+
return or(not(conditionExpression), onTrueExpression);
|
|
1116
|
+
} // if X then false else a ~~> !X && a
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
if (isFalse(onTrueExpression)) {
|
|
1120
|
+
return and(not(conditionExpression), onFalseExpression);
|
|
1121
|
+
} // if X then true else a ~~> X || a
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
if (isTrue(onTrueExpression)) {
|
|
1125
|
+
return or(conditionExpression, onFalseExpression);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
if (isComplexTypeExpression(condition) || isComplexTypeExpression(onTrue) || isComplexTypeExpression(onFalse)) {
|
|
1129
|
+
var pathIdx = 0;
|
|
1130
|
+
var myIfElseExpression = formatResult([condition, onTrue, onFalse], "sap.fe.core.formatters.StandardFormatter#ifElse");
|
|
1131
|
+
var allParts = [];
|
|
1132
|
+
transformRecursively(myIfElseExpression, "PathInModel", function (constantPath) {
|
|
1133
|
+
allParts.push(constantPath);
|
|
1134
|
+
return pathInModel("$".concat(pathIdx++), "$");
|
|
1135
|
+
}, true);
|
|
1136
|
+
allParts.unshift(constant(JSON.stringify(myIfElseExpression)));
|
|
1137
|
+
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression");
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
return {
|
|
1141
|
+
_type: "IfElse",
|
|
1142
|
+
condition: conditionExpression,
|
|
1143
|
+
onTrue: onTrueExpression,
|
|
1144
|
+
onFalse: onFalseExpression
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Checks whether the current expression has a reference to the default model (undefined).
|
|
1149
|
+
*
|
|
1150
|
+
* @param expression The expression to evaluate
|
|
1151
|
+
* @returns `true` if there is a reference to the default context
|
|
1152
|
+
*/
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
_exports.ifElse = ifElse;
|
|
1156
|
+
|
|
1157
|
+
function hasReferenceToDefaultContext(expression) {
|
|
1158
|
+
switch (expression._type) {
|
|
1159
|
+
case "Constant":
|
|
1160
|
+
case "Formatter":
|
|
1161
|
+
case "ComplexType":
|
|
1162
|
+
return false;
|
|
1163
|
+
|
|
1164
|
+
case "Set":
|
|
1165
|
+
return expression.operands.some(hasReferenceToDefaultContext);
|
|
1166
|
+
|
|
1167
|
+
case "PathInModel":
|
|
1168
|
+
return expression.modelName === undefined;
|
|
1169
|
+
|
|
1170
|
+
case "Comparison":
|
|
1171
|
+
return hasReferenceToDefaultContext(expression.operand1) || hasReferenceToDefaultContext(expression.operand2);
|
|
1172
|
+
|
|
1173
|
+
case "IfElse":
|
|
1174
|
+
return hasReferenceToDefaultContext(expression.condition) || hasReferenceToDefaultContext(expression.onTrue) || hasReferenceToDefaultContext(expression.onFalse);
|
|
1175
|
+
|
|
1176
|
+
case "Not":
|
|
1177
|
+
case "Truthy":
|
|
1178
|
+
return hasReferenceToDefaultContext(expression.operand);
|
|
1179
|
+
|
|
1180
|
+
default:
|
|
1181
|
+
return false;
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
/**
|
|
1186
|
+
* Calls a formatter function to process the parameters.
|
|
1187
|
+
* If requireContext is set to true and no context is passed a default context will be added automatically.
|
|
1188
|
+
*
|
|
1189
|
+
* @template T
|
|
1190
|
+
* @template U
|
|
1191
|
+
* @param parameters The list of parameter that should match the type and number of the formatter function
|
|
1192
|
+
* @param formatterFunction The function to call
|
|
1193
|
+
* @param [contextEntityType] The context entity type to consider
|
|
1194
|
+
* @returns The corresponding expression
|
|
1195
|
+
*/
|
|
1196
|
+
function formatResult(parameters, formatterFunction, contextEntityType) {
|
|
1197
|
+
var parameterExpressions = parameters.map(wrapPrimitive);
|
|
1198
|
+
|
|
1199
|
+
if (hasUnresolveableExpression.apply(void 0, _toConsumableArray(parameterExpressions))) {
|
|
1200
|
+
return unresolveableExpression;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
if (contextEntityType) {
|
|
1204
|
+
// Otherwise, if the context is required and no context is provided make sure to add the default binding
|
|
1205
|
+
if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
|
|
1206
|
+
contextEntityType.keys.forEach(function (key) {
|
|
1207
|
+
return parameterExpressions.push(pathInModel(key.name, ""));
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
var functionName = "";
|
|
1213
|
+
|
|
1214
|
+
if (typeof formatterFunction === "string") {
|
|
1215
|
+
functionName = formatterFunction;
|
|
1216
|
+
} else {
|
|
1217
|
+
functionName = formatterFunction.__functionName;
|
|
1218
|
+
} // FormatterName can be of format sap.fe.core.xxx#methodName to have multiple formatter in one class
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
var _functionName$split = functionName.split("#"),
|
|
1222
|
+
_functionName$split2 = _slicedToArray(_functionName$split, 2),
|
|
1223
|
+
formatterClass = _functionName$split2[0],
|
|
1224
|
+
formatterName = _functionName$split2[1];
|
|
1225
|
+
|
|
1226
|
+
if (!!formatterName && formatterName.length > 0) {
|
|
1227
|
+
parameterExpressions.unshift(constant(formatterName));
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
return {
|
|
1231
|
+
_type: "Formatter",
|
|
1232
|
+
fn: formatterClass,
|
|
1233
|
+
parameters: parameterExpressions
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Calls a complex type to process the parameters.
|
|
1238
|
+
* If requireContext is set to true and no context is passed, a default context will be added automatically.
|
|
1239
|
+
*
|
|
1240
|
+
* @template T
|
|
1241
|
+
* @template U
|
|
1242
|
+
* @param parameters The list of parameters that should match the type for the complex type=
|
|
1243
|
+
* @param type The complex type to use
|
|
1244
|
+
* @param [contextEntityType] The context entity type to consider
|
|
1245
|
+
* @param oFormatOptions
|
|
1246
|
+
* @returns The corresponding expression
|
|
1247
|
+
*/
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
_exports.formatResult = formatResult;
|
|
1251
|
+
|
|
1252
|
+
function addTypeInformation(parameters, type, contextEntityType, oFormatOptions) {
|
|
1253
|
+
var _parameters$, _parameters$$type, _parameters$2, _parameters$2$type, _parameters$3, _parameters$3$type;
|
|
1254
|
+
|
|
1255
|
+
var parameterExpressions = parameters.map(wrapPrimitive);
|
|
1256
|
+
|
|
1257
|
+
if (hasUnresolveableExpression.apply(void 0, _toConsumableArray(parameterExpressions))) {
|
|
1258
|
+
return unresolveableExpression;
|
|
1259
|
+
} // If there is only one parameter and it is a constant and we don't expect the context then return the constant
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
if (parameterExpressions.length === 1 && isConstant(parameterExpressions[0]) && !contextEntityType) {
|
|
1263
|
+
return parameterExpressions[0];
|
|
1264
|
+
} else if (contextEntityType) {
|
|
1265
|
+
// Otherwise, if the context is required and no context is provided make sure to add the default binding
|
|
1266
|
+
if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
|
|
1267
|
+
contextEntityType.keys.forEach(function (key) {
|
|
1268
|
+
return parameterExpressions.push(pathInModel(key.name, ""));
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1271
|
+
} // if showMeasure is set to false we want to not parse as string to see the 0
|
|
1272
|
+
// we do that also for all bindings because otherwise the mdc Field isn't editable
|
|
1273
|
+
|
|
1274
|
+
|
|
1275
|
+
if (!(oFormatOptions && oFormatOptions.showNumber === false) && (((_parameters$ = parameters[0]) === null || _parameters$ === void 0 ? void 0 : (_parameters$$type = _parameters$.type) === null || _parameters$$type === void 0 ? void 0 : _parameters$$type.indexOf("sap.ui.model.odata.type.Int")) === 0 || ((_parameters$2 = parameters[0]) === null || _parameters$2 === void 0 ? void 0 : (_parameters$2$type = _parameters$2.type) === null || _parameters$2$type === void 0 ? void 0 : _parameters$2$type.indexOf("sap.ui.model.odata.type.Decimal")) === 0 || ((_parameters$3 = parameters[0]) === null || _parameters$3 === void 0 ? void 0 : (_parameters$3$type = _parameters$3.type) === null || _parameters$3$type === void 0 ? void 0 : _parameters$3$type.indexOf("sap.ui.model.odata.type.Double")) === 0)) {
|
|
1276
|
+
var _parameters$4, _parameters$5;
|
|
1277
|
+
|
|
1278
|
+
if (((_parameters$4 = parameters[0]) === null || _parameters$4 === void 0 ? void 0 : _parameters$4.type) === "sap.ui.model.odata.type.Int64" || ((_parameters$5 = parameters[0]) === null || _parameters$5 === void 0 ? void 0 : _parameters$5.type) === "sap.ui.model.odata.type.Decimal") {
|
|
1279
|
+
var _oFormatOptions;
|
|
1280
|
+
|
|
1281
|
+
//sap.ui.model.odata.type.Int64 do not support parseAsString false
|
|
1282
|
+
oFormatOptions = ((_oFormatOptions = oFormatOptions) === null || _oFormatOptions === void 0 ? void 0 : _oFormatOptions.showMeasure) === false ? {
|
|
1283
|
+
emptyString: "",
|
|
1284
|
+
showMeasure: false
|
|
1285
|
+
} : {
|
|
1286
|
+
emptyString: ""
|
|
1287
|
+
};
|
|
1288
|
+
} else {
|
|
1289
|
+
var _oFormatOptions2;
|
|
1290
|
+
|
|
1291
|
+
oFormatOptions = ((_oFormatOptions2 = oFormatOptions) === null || _oFormatOptions2 === void 0 ? void 0 : _oFormatOptions2.showMeasure) === false ? {
|
|
1292
|
+
parseAsString: false,
|
|
1293
|
+
emptyString: "",
|
|
1294
|
+
showMeasure: false
|
|
1295
|
+
} : {
|
|
1296
|
+
parseAsString: false,
|
|
1297
|
+
emptyString: ""
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
if (type === "sap.ui.model.odata.type.Unit") {
|
|
1303
|
+
var uomPath = pathInModel("/##@@requestUnitsOfMeasure");
|
|
1304
|
+
uomPath.targetType = "any";
|
|
1305
|
+
uomPath.mode = "OneTime";
|
|
1306
|
+
parameterExpressions.push(uomPath);
|
|
1307
|
+
} else if (type === "sap.ui.model.odata.type.Currency") {
|
|
1308
|
+
var currencyPath = pathInModel("/##@@requestCurrencyCodes");
|
|
1309
|
+
currencyPath.targetType = "any";
|
|
1310
|
+
currencyPath.mode = "OneTime";
|
|
1311
|
+
parameterExpressions.push(currencyPath);
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
return {
|
|
1315
|
+
_type: "ComplexType",
|
|
1316
|
+
type: type,
|
|
1317
|
+
formatOptions: oFormatOptions || {},
|
|
1318
|
+
parameters: {},
|
|
1319
|
+
bindingParameters: parameterExpressions
|
|
1320
|
+
};
|
|
1321
|
+
}
|
|
1322
|
+
/**
|
|
1323
|
+
* Function call, optionally with arguments.
|
|
1324
|
+
*
|
|
1325
|
+
* @param func Function name or reference to function
|
|
1326
|
+
* @param parameters Arguments
|
|
1327
|
+
* @param on Object to call the function on
|
|
1328
|
+
* @returns Expression representing the function call (not the result of the function call!)
|
|
1329
|
+
*/
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
_exports.addTypeInformation = addTypeInformation;
|
|
1333
|
+
|
|
1334
|
+
function fn(func, parameters, on) {
|
|
1335
|
+
var functionName = typeof func === "string" ? func : func.__functionName;
|
|
1336
|
+
return {
|
|
1337
|
+
_type: "Function",
|
|
1338
|
+
obj: on !== undefined ? wrapPrimitive(on) : undefined,
|
|
1339
|
+
fn: functionName,
|
|
1340
|
+
parameters: parameters.map(wrapPrimitive)
|
|
1341
|
+
};
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Shortcut function to determine if a binding value is null, undefined or empty.
|
|
1345
|
+
*
|
|
1346
|
+
* @param expression
|
|
1347
|
+
* @returns A boolean expression evaluating the fact that the current element is empty
|
|
1348
|
+
*/
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
_exports.fn = fn;
|
|
1352
|
+
|
|
1353
|
+
function isEmpty(expression) {
|
|
1354
|
+
if (expression._type === "Concat") {
|
|
1355
|
+
return or.apply(void 0, _toConsumableArray(expression.expressions.map(isEmpty)));
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
return or(equal(expression, ""), equal(expression, undefined), equal(expression, null));
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
_exports.isEmpty = isEmpty;
|
|
1362
|
+
|
|
1363
|
+
function concat() {
|
|
1364
|
+
for (var _len4 = arguments.length, inExpressions = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
1365
|
+
inExpressions[_key4] = arguments[_key4];
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
var expressions = inExpressions.map(wrapPrimitive);
|
|
1369
|
+
|
|
1370
|
+
if (hasUnresolveableExpression.apply(void 0, _toConsumableArray(expressions))) {
|
|
1371
|
+
return unresolveableExpression;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
if (expressions.every(isConstant)) {
|
|
1375
|
+
return constant(expressions.reduce(function (concatenated, value) {
|
|
1376
|
+
return concatenated + value.value.toString();
|
|
1377
|
+
}, ""));
|
|
1378
|
+
} else if (expressions.some(isComplexTypeExpression)) {
|
|
1379
|
+
var pathIdx = 0;
|
|
1380
|
+
var myConcatExpression = formatResult(expressions, "sap.fe.core.formatters.StandardFormatter#concat");
|
|
1381
|
+
var allParts = [];
|
|
1382
|
+
transformRecursively(myConcatExpression, "PathInModel", function (constantPath) {
|
|
1383
|
+
allParts.push(constantPath);
|
|
1384
|
+
return pathInModel("$".concat(pathIdx++), "$");
|
|
1385
|
+
});
|
|
1386
|
+
allParts.unshift(constant(JSON.stringify(myConcatExpression)));
|
|
1387
|
+
return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression");
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
return {
|
|
1391
|
+
_type: "Concat",
|
|
1392
|
+
expressions: expressions
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
_exports.concat = concat;
|
|
1397
|
+
|
|
1398
|
+
function transformRecursively(inExpression, expressionType, transformFunction) {
|
|
1399
|
+
var includeAllExpression = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1400
|
+
var expression = inExpression;
|
|
1401
|
+
|
|
1402
|
+
switch (expression._type) {
|
|
1403
|
+
case "Function":
|
|
1404
|
+
case "Formatter":
|
|
1405
|
+
expression.parameters = expression.parameters.map(function (parameter) {
|
|
1406
|
+
return transformRecursively(parameter, expressionType, transformFunction, includeAllExpression);
|
|
1407
|
+
});
|
|
1408
|
+
break;
|
|
1409
|
+
|
|
1410
|
+
case "Concat":
|
|
1411
|
+
expression.expressions = expression.expressions.map(function (subExpression) {
|
|
1412
|
+
return transformRecursively(subExpression, expressionType, transformFunction, includeAllExpression);
|
|
1413
|
+
});
|
|
1414
|
+
break;
|
|
1415
|
+
|
|
1416
|
+
case "ComplexType":
|
|
1417
|
+
expression.bindingParameters = expression.bindingParameters.map(function (bindingParameter) {
|
|
1418
|
+
return transformRecursively(bindingParameter, expressionType, transformFunction, includeAllExpression);
|
|
1419
|
+
});
|
|
1420
|
+
break;
|
|
1421
|
+
|
|
1422
|
+
case "IfElse":
|
|
1423
|
+
var onTrue = transformRecursively(expression.onTrue, expressionType, transformFunction, includeAllExpression);
|
|
1424
|
+
var onFalse = transformRecursively(expression.onFalse, expressionType, transformFunction, includeAllExpression);
|
|
1425
|
+
var condition = expression.condition;
|
|
1426
|
+
|
|
1427
|
+
if (includeAllExpression) {
|
|
1428
|
+
condition = transformRecursively(expression.condition, expressionType, transformFunction, includeAllExpression);
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
expression = ifElse(condition, onTrue, onFalse);
|
|
1432
|
+
break;
|
|
1433
|
+
|
|
1434
|
+
case "Not":
|
|
1435
|
+
if (includeAllExpression) {
|
|
1436
|
+
var operand = transformRecursively(expression.operand, expressionType, transformFunction, includeAllExpression);
|
|
1437
|
+
expression = not(operand);
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
break;
|
|
1441
|
+
|
|
1442
|
+
case "Truthy":
|
|
1443
|
+
break;
|
|
1444
|
+
|
|
1445
|
+
case "Set":
|
|
1446
|
+
if (includeAllExpression) {
|
|
1447
|
+
var operands = expression.operands.map(function (operand) {
|
|
1448
|
+
return transformRecursively(operand, expressionType, transformFunction, includeAllExpression);
|
|
1449
|
+
});
|
|
1450
|
+
expression = expression.operator === "||" ? or.apply(void 0, _toConsumableArray(operands)) : and.apply(void 0, _toConsumableArray(operands));
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
break;
|
|
1454
|
+
|
|
1455
|
+
case "Comparison":
|
|
1456
|
+
if (includeAllExpression) {
|
|
1457
|
+
var operand1 = transformRecursively(expression.operand1, expressionType, transformFunction, includeAllExpression);
|
|
1458
|
+
var operand2 = transformRecursively(expression.operand2, expressionType, transformFunction, includeAllExpression);
|
|
1459
|
+
expression = comparison(expression.operator, operand1, operand2);
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
break;
|
|
1463
|
+
|
|
1464
|
+
case "Ref":
|
|
1465
|
+
case "Length":
|
|
1466
|
+
case "PathInModel":
|
|
1467
|
+
case "Constant":
|
|
1468
|
+
case "EmbeddedBinding":
|
|
1469
|
+
case "EmbeddedExpressionBinding":
|
|
1470
|
+
case "Unresolvable":
|
|
1471
|
+
// Do nothing
|
|
1472
|
+
break;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
if (expressionType === expression._type) {
|
|
1476
|
+
expression = transformFunction(inExpression);
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
return expression;
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
_exports.transformRecursively = transformRecursively;
|
|
1483
|
+
|
|
1484
|
+
var needParenthesis = function (expr) {
|
|
1485
|
+
return !isConstant(expr) && !isPathInModelExpression(expr) && isExpression(expr) && expr._type !== "IfElse" && expr._type !== "Function";
|
|
1486
|
+
};
|
|
1487
|
+
/**
|
|
1488
|
+
* Compiles a constant object to a string.
|
|
1489
|
+
*
|
|
1490
|
+
* @param expr
|
|
1491
|
+
* @param isNullable
|
|
1492
|
+
* @returns The compiled string
|
|
1493
|
+
*/
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
function compileConstantObject(expr) {
|
|
1497
|
+
var isNullable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1498
|
+
|
|
1499
|
+
if (isNullable && Object.keys(expr.value).length === 0) {
|
|
1500
|
+
return "";
|
|
1501
|
+
} // Objects
|
|
1502
|
+
|
|
1503
|
+
|
|
1504
|
+
var o = expr.value;
|
|
1505
|
+
var properties = [];
|
|
1506
|
+
Object.keys(o).forEach(function (key) {
|
|
1507
|
+
var value = o[key];
|
|
1508
|
+
var childResult = compileExpression(value, true, false, true);
|
|
1509
|
+
|
|
1510
|
+
if (childResult && childResult.length > 0) {
|
|
1511
|
+
properties.push("".concat(key, ": ").concat(childResult));
|
|
1512
|
+
}
|
|
1513
|
+
});
|
|
1514
|
+
return "{".concat(properties.join(", "), "}");
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Compiles a Constant Binding Expression.
|
|
1518
|
+
*
|
|
1519
|
+
* @param expr
|
|
1520
|
+
* @param embeddedInBinding
|
|
1521
|
+
* @param isNullable
|
|
1522
|
+
* @returns The compiled string
|
|
1523
|
+
*/
|
|
1524
|
+
|
|
1525
|
+
|
|
1526
|
+
function compileConstant(expr, embeddedInBinding) {
|
|
1527
|
+
var isNullable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1528
|
+
|
|
1529
|
+
if (expr.value === null) {
|
|
1530
|
+
return "null";
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
if (expr.value === undefined) {
|
|
1534
|
+
return "undefined";
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
if (typeof expr.value === "object") {
|
|
1538
|
+
if (Array.isArray(expr.value)) {
|
|
1539
|
+
var entries = expr.value.map(function (expression) {
|
|
1540
|
+
return compileExpression(expression, true);
|
|
1541
|
+
});
|
|
1542
|
+
return "[".concat(entries.join(", "), "]");
|
|
1543
|
+
} else {
|
|
1544
|
+
return compileConstantObject(expr, isNullable);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
if (embeddedInBinding) {
|
|
1549
|
+
switch (typeof expr.value) {
|
|
1550
|
+
case "number":
|
|
1551
|
+
case "bigint":
|
|
1552
|
+
case "boolean":
|
|
1553
|
+
return expr.value.toString();
|
|
1554
|
+
|
|
1555
|
+
case "string":
|
|
1556
|
+
return "'".concat(escapeXmlAttribute(expr.value.toString()), "'");
|
|
1557
|
+
|
|
1558
|
+
default:
|
|
1559
|
+
return "";
|
|
1560
|
+
}
|
|
1561
|
+
} else {
|
|
1562
|
+
return expr.value.toString();
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Generates the binding string for a Binding expression.
|
|
1567
|
+
*
|
|
1568
|
+
* @param expressionForBinding The expression to compile
|
|
1569
|
+
* @param embeddedInBinding Whether the expression to compile is embedded into another expression
|
|
1570
|
+
* @param embeddedSeparator The binding value evaluator ($ or % depending on whether we want to force the type or not)
|
|
1571
|
+
* @returns The corresponding expression binding
|
|
1572
|
+
*/
|
|
1573
|
+
|
|
1574
|
+
|
|
1575
|
+
function compilePathInModelExpression(expressionForBinding, embeddedInBinding, embeddedSeparator) {
|
|
1576
|
+
if (expressionForBinding.type || expressionForBinding.parameters || expressionForBinding.targetType || expressionForBinding.formatOptions || expressionForBinding.constraints) {
|
|
1577
|
+
// This is now a complex binding definition, let's prepare for it
|
|
1578
|
+
var complexBindingDefinition = {
|
|
1579
|
+
path: compilePathInModel(expressionForBinding),
|
|
1580
|
+
type: expressionForBinding.type,
|
|
1581
|
+
targetType: expressionForBinding.targetType,
|
|
1582
|
+
parameters: expressionForBinding.parameters,
|
|
1583
|
+
formatOptions: expressionForBinding.formatOptions,
|
|
1584
|
+
constraints: expressionForBinding.constraints
|
|
1585
|
+
};
|
|
1586
|
+
var outBinding = compileExpression(complexBindingDefinition);
|
|
1587
|
+
|
|
1588
|
+
if (embeddedInBinding) {
|
|
1589
|
+
outBinding = "".concat(embeddedSeparator).concat(outBinding);
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
return outBinding;
|
|
1593
|
+
} else if (embeddedInBinding) {
|
|
1594
|
+
return "".concat(embeddedSeparator, "{").concat(compilePathInModel(expressionForBinding), "}");
|
|
1595
|
+
} else {
|
|
1596
|
+
return "{".concat(compilePathInModel(expressionForBinding), "}");
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
function compileComplexTypeExpression(expression) {
|
|
1601
|
+
if (expression.bindingParameters.length === 1) {
|
|
1602
|
+
return "{".concat(compilePathParameter(expression.bindingParameters[0], true), ", type: '").concat(expression.type, "'}");
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
var outputEnd = "], type: '".concat(expression.type, "'");
|
|
1606
|
+
|
|
1607
|
+
if (hasElements(expression.formatOptions)) {
|
|
1608
|
+
outputEnd += ", formatOptions: ".concat(compileExpression(expression.formatOptions));
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
if (hasElements(expression.parameters)) {
|
|
1612
|
+
outputEnd += ", parameters: ".concat(compileExpression(expression.parameters));
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
outputEnd += "}";
|
|
1616
|
+
return "{mode:'TwoWay', parts:[".concat(expression.bindingParameters.map(function (param) {
|
|
1617
|
+
return compilePathParameter(param);
|
|
1618
|
+
}).join(",")).concat(outputEnd);
|
|
1619
|
+
}
|
|
1620
|
+
/**
|
|
1621
|
+
* Wrap the compiled binding string as required dependening on its context.
|
|
1622
|
+
*
|
|
1623
|
+
* @param expression The compiled expression
|
|
1624
|
+
* @param embeddedInBinding True if the compiled expression is to be embedded in a binding
|
|
1625
|
+
* @param parenthesisRequired True if the embedded binding needs to be wrapped in parethesis so that it is evaluated as one
|
|
1626
|
+
* @returns Finalized compiled expression
|
|
1627
|
+
*/
|
|
1628
|
+
|
|
1629
|
+
|
|
1630
|
+
function wrapBindingExpression(expression, embeddedInBinding) {
|
|
1631
|
+
var parenthesisRequired = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1632
|
+
|
|
1633
|
+
if (embeddedInBinding) {
|
|
1634
|
+
if (parenthesisRequired) {
|
|
1635
|
+
return "(".concat(expression, ")");
|
|
1636
|
+
} else {
|
|
1637
|
+
return expression;
|
|
1638
|
+
}
|
|
1639
|
+
} else {
|
|
1640
|
+
return "{= ".concat(expression, "}");
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
/**
|
|
1644
|
+
* Compile an expression into an expression binding.
|
|
1645
|
+
*
|
|
1646
|
+
* @template T The target type
|
|
1647
|
+
* @param expression The expression to compile
|
|
1648
|
+
* @param embeddedInBinding Whether the expression to compile is embedded into another expression
|
|
1649
|
+
* @param keepTargetType Keep the target type of the embedded bindings instead of casting them to any
|
|
1650
|
+
* @param isNullable Whether binding expression can resolve to empty string or not
|
|
1651
|
+
* @returns The corresponding expression binding
|
|
1652
|
+
*/
|
|
1653
|
+
|
|
1654
|
+
|
|
1655
|
+
function compileExpression(expression) {
|
|
1656
|
+
var embeddedInBinding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1657
|
+
var keepTargetType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1658
|
+
var isNullable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1659
|
+
var expr = wrapPrimitive(expression);
|
|
1660
|
+
var embeddedSeparator = keepTargetType ? "$" : "%";
|
|
1661
|
+
|
|
1662
|
+
switch (expr._type) {
|
|
1663
|
+
case "Unresolvable":
|
|
1664
|
+
return undefined;
|
|
1665
|
+
|
|
1666
|
+
case "Constant":
|
|
1667
|
+
return compileConstant(expr, embeddedInBinding, isNullable);
|
|
1668
|
+
|
|
1669
|
+
case "Ref":
|
|
1670
|
+
return expr.ref || "null";
|
|
1671
|
+
|
|
1672
|
+
case "Function":
|
|
1673
|
+
var argumentString = "".concat(expr.parameters.map(function (arg) {
|
|
1674
|
+
return compileExpression(arg, true);
|
|
1675
|
+
}).join(", "));
|
|
1676
|
+
return expr.obj === undefined ? "".concat(expr.fn, "(").concat(argumentString, ")") : "".concat(compileExpression(expr.obj, true), ".").concat(expr.fn, "(").concat(argumentString, ")");
|
|
1677
|
+
|
|
1678
|
+
case "EmbeddedExpressionBinding":
|
|
1679
|
+
return embeddedInBinding ? "(".concat(expr.value.substr(2, expr.value.length - 3), ")") : "".concat(expr.value);
|
|
1680
|
+
|
|
1681
|
+
case "EmbeddedBinding":
|
|
1682
|
+
return embeddedInBinding ? "".concat(embeddedSeparator).concat(expr.value) : "".concat(expr.value);
|
|
1683
|
+
|
|
1684
|
+
case "PathInModel":
|
|
1685
|
+
return compilePathInModelExpression(expr, embeddedInBinding, embeddedSeparator);
|
|
1686
|
+
|
|
1687
|
+
case "Comparison":
|
|
1688
|
+
var comparisonExpression = compileComparisonExpression(expr);
|
|
1689
|
+
return wrapBindingExpression(comparisonExpression, embeddedInBinding);
|
|
1690
|
+
|
|
1691
|
+
case "IfElse":
|
|
1692
|
+
var ifElseExpression = "".concat(compileExpression(expr.condition, true), " ? ").concat(compileExpression(expr.onTrue, true), " : ").concat(compileExpression(expr.onFalse, true));
|
|
1693
|
+
return wrapBindingExpression(ifElseExpression, embeddedInBinding, true);
|
|
1694
|
+
|
|
1695
|
+
case "Set":
|
|
1696
|
+
var setExpression = expr.operands.map(function (operand) {
|
|
1697
|
+
return compileExpression(operand, true);
|
|
1698
|
+
}).join(" ".concat(expr.operator, " "));
|
|
1699
|
+
return wrapBindingExpression(setExpression, embeddedInBinding, true);
|
|
1700
|
+
|
|
1701
|
+
case "Concat":
|
|
1702
|
+
var concatExpression = expr.expressions.map(function (nestedExpression) {
|
|
1703
|
+
return compileExpression(nestedExpression, true, true);
|
|
1704
|
+
}).join(" + ");
|
|
1705
|
+
return wrapBindingExpression(concatExpression, embeddedInBinding);
|
|
1706
|
+
|
|
1707
|
+
case "Length":
|
|
1708
|
+
var lengthExpression = "".concat(compileExpression(expr.pathInModel, true), ".length");
|
|
1709
|
+
return wrapBindingExpression(lengthExpression, embeddedInBinding);
|
|
1710
|
+
|
|
1711
|
+
case "Not":
|
|
1712
|
+
var notExpression = "!".concat(compileExpression(expr.operand, true));
|
|
1713
|
+
return wrapBindingExpression(notExpression, embeddedInBinding);
|
|
1714
|
+
|
|
1715
|
+
case "Truthy":
|
|
1716
|
+
var truthyExpression = "!!".concat(compileExpression(expr.operand, true));
|
|
1717
|
+
return wrapBindingExpression(truthyExpression, embeddedInBinding);
|
|
1718
|
+
|
|
1719
|
+
case "Formatter":
|
|
1720
|
+
var formatterExpression = compileFormatterExpression(expr);
|
|
1721
|
+
return embeddedInBinding ? "$".concat(formatterExpression) : formatterExpression;
|
|
1722
|
+
|
|
1723
|
+
case "ComplexType":
|
|
1724
|
+
var complexTypeExpression = compileComplexTypeExpression(expr);
|
|
1725
|
+
return embeddedInBinding ? "$".concat(complexTypeExpression) : complexTypeExpression;
|
|
1726
|
+
|
|
1727
|
+
default:
|
|
1728
|
+
return "";
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
/**
|
|
1732
|
+
* Compile a comparison expression.
|
|
1733
|
+
*
|
|
1734
|
+
* @param expression The comparison expression.
|
|
1735
|
+
* @returns The compiled expression. Needs wrapping before it can be used as an expression binding.
|
|
1736
|
+
*/
|
|
1737
|
+
|
|
1738
|
+
|
|
1739
|
+
_exports.compileExpression = compileExpression;
|
|
1740
|
+
|
|
1741
|
+
function compileComparisonExpression(expression) {
|
|
1742
|
+
function compileOperand(operand) {
|
|
1743
|
+
var _compileExpression;
|
|
1744
|
+
|
|
1745
|
+
var compiledOperand = (_compileExpression = compileExpression(operand, true)) !== null && _compileExpression !== void 0 ? _compileExpression : "undefined";
|
|
1746
|
+
return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
return "".concat(compileOperand(expression.operand1), " ").concat(expression.operator, " ").concat(compileOperand(expression.operand2));
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1752
|
+
* Compile a formatter expression.
|
|
1753
|
+
*
|
|
1754
|
+
* @param expression The formatter expression.
|
|
1755
|
+
* @returns The compiled expression.
|
|
1756
|
+
*/
|
|
1757
|
+
|
|
1758
|
+
|
|
1759
|
+
function compileFormatterExpression(expression) {
|
|
1760
|
+
if (expression.parameters.length === 1) {
|
|
1761
|
+
return "{".concat(compilePathParameter(expression.parameters[0], true), ", formatter: '").concat(expression.fn, "'}");
|
|
1762
|
+
} else {
|
|
1763
|
+
var parts = expression.parameters.map(function (param) {
|
|
1764
|
+
if (param._type === "ComplexType") {
|
|
1765
|
+
return compileComplexTypeExpression(param);
|
|
1766
|
+
} else {
|
|
1767
|
+
return compilePathParameter(param);
|
|
1768
|
+
}
|
|
1769
|
+
});
|
|
1770
|
+
return "{parts: [".concat(parts.join(", "), "], formatter: '").concat(expression.fn, "'}");
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
/**
|
|
1774
|
+
* Compile the path parameter of a formatter call.
|
|
1775
|
+
*
|
|
1776
|
+
* @param expression The binding part to evaluate
|
|
1777
|
+
* @param singlePath Whether there is one or multiple path to consider
|
|
1778
|
+
* @returns The string snippet to include in the overall binding definition
|
|
1779
|
+
*/
|
|
1780
|
+
|
|
1781
|
+
|
|
1782
|
+
function compilePathParameter(expression) {
|
|
1783
|
+
var singlePath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1784
|
+
var outValue = "";
|
|
1785
|
+
|
|
1786
|
+
if (expression._type === "Constant") {
|
|
1787
|
+
if (expression.value === undefined) {
|
|
1788
|
+
// Special case otherwise the JSTokenizer complains about incorrect content
|
|
1789
|
+
outValue = "value: 'undefined'";
|
|
1790
|
+
} else {
|
|
1791
|
+
outValue = "value: ".concat(compileConstant(expression, true));
|
|
1792
|
+
}
|
|
1793
|
+
} else if (expression._type === "PathInModel") {
|
|
1794
|
+
outValue = "path: '".concat(compilePathInModel(expression), "'");
|
|
1795
|
+
outValue += expression.type ? ", type: '".concat(expression.type, "'") : ", targetType: 'any'";
|
|
1796
|
+
|
|
1797
|
+
if (hasElements(expression.mode)) {
|
|
1798
|
+
outValue += ", mode: '".concat(compileExpression(expression.mode), "'");
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
if (hasElements(expression.constraints)) {
|
|
1802
|
+
outValue += ", constraints: ".concat(compileExpression(expression.constraints));
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
if (hasElements(expression.formatOptions)) {
|
|
1806
|
+
outValue += ", formatOptions: ".concat(compileExpression(expression.formatOptions));
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
if (hasElements(expression.parameters)) {
|
|
1810
|
+
outValue += ", parameters: ".concat(compileExpression(expression.parameters));
|
|
1811
|
+
}
|
|
1812
|
+
} else {
|
|
1813
|
+
return "";
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
return singlePath ? outValue : "{".concat(outValue, "}");
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
function hasElements(obj) {
|
|
1820
|
+
return obj && Object.keys(obj).length > 0;
|
|
1821
|
+
}
|
|
1822
|
+
/**
|
|
1823
|
+
* Compile a binding expression path.
|
|
1824
|
+
*
|
|
1825
|
+
* @param expression The expression to compile.
|
|
1826
|
+
* @returns The compiled path.
|
|
1827
|
+
*/
|
|
1828
|
+
|
|
1829
|
+
|
|
1830
|
+
function compilePathInModel(expression) {
|
|
1831
|
+
return "".concat(expression.modelName ? "".concat(expression.modelName, ">") : "").concat(expression.path);
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
return _exports;
|
|
1835
|
+
}, false);
|
|
1836
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1bnJlc29sdmVhYmxlRXhwcmVzc2lvbiIsIl90eXBlIiwiZXNjYXBlWG1sQXR0cmlidXRlIiwiaW5wdXRTdHJpbmciLCJyZXBsYWNlIiwiaGFzVW5yZXNvbHZlYWJsZUV4cHJlc3Npb24iLCJleHByZXNzaW9ucyIsImZpbmQiLCJleHByIiwidW5kZWZpbmVkIiwiX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbCIsImEiLCJiIiwidmFsdWUiLCJvcGVyYW5kIiwib3BlcmF0b3IiLCJvcGVyYW5kcyIsImxlbmd0aCIsImV2ZXJ5IiwiZXhwcmVzc2lvbiIsInNvbWUiLCJvdGhlckV4cHJlc3Npb24iLCJjb25kaXRpb24iLCJvblRydWUiLCJvbkZhbHNlIiwib3BlcmFuZDEiLCJvcGVyYW5kMiIsImFFeHByZXNzaW9ucyIsImJFeHByZXNzaW9ucyIsImluZGV4IiwicGF0aEluTW9kZWwiLCJtb2RlbE5hbWUiLCJwYXRoIiwidGFyZ2V0RW50aXR5U2V0IiwiZm4iLCJwYXJhbWV0ZXJzIiwidHlwZSIsImJpbmRpbmdQYXJhbWV0ZXJzIiwib3RoZXJGdW5jdGlvbiIsIm9iaiIsInJlZiIsImZsYXR0ZW5TZXRFeHByZXNzaW9uIiwicmVkdWNlIiwicmVzdWx0IiwiY2FuZGlkYXRlc0ZvckZsYXR0ZW5pbmciLCJmb3JFYWNoIiwiY2FuZGlkYXRlIiwiZSIsInB1c2giLCJoYXNPcHBvc2l0ZUV4cHJlc3Npb25zIiwibmVnYXRlZEV4cHJlc3Npb25zIiwibWFwIiwibm90IiwiaSIsImFuZCIsIndyYXBQcmltaXRpdmUiLCJpc1N0YXRpY0ZhbHNlIiwibm9uVHJpdmlhbEV4cHJlc3Npb24iLCJmaWx0ZXIiLCJpc0ZhbHNlIiwiaXNDb25zdGFudCIsImNvbnN0YW50IiwiaXNWYWxpZCIsImlzVHJ1ZSIsIm9yIiwiaXNTdGF0aWNUcnVlIiwiaXNDb21wYXJpc29uIiwiaXNUcnV0aHkiLCJiaW5kaW5nRXhwcmVzc2lvbiIsInZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMiLCJwYXRoVmlzaXRvciIsInRhcmdldFBhdGgiLCJsb2NhbFBhdGgiLCJjb25jYXQiLCJqb2luIiwiY29uc3RhbnRWYWx1ZSIsIkFycmF5IiwiaXNBcnJheSIsImlzUHJpbWl0aXZlT2JqZWN0IiwidmFsdWVPZiIsIk9iamVjdCIsImVudHJpZXMiLCJwbGFpbkV4cHJlc3Npb24iLCJrZXkiLCJ2YWwiLCJ3cmFwcGVkVmFsdWUiLCJyZXNvbHZlQmluZGluZ1N0cmluZyIsInRhcmdldFR5cGUiLCJzdGFydHNXaXRoIiwicmVmZXJlbmNlIiwiaXNFeHByZXNzaW9uIiwic29tZXRoaW5nIiwibWF5YmVDb25zdGFudCIsImlzUGF0aEluTW9kZWxFeHByZXNzaW9uIiwibWF5YmVCaW5kaW5nIiwiaXNDb21wbGV4VHlwZUV4cHJlc3Npb24iLCJvYmplY3RUeXBlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiaXNDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb24iLCJhbm5vdGF0aW9uVmFsdWUiLCJhbm5vdGF0aW9uRXhwcmVzc2lvbiIsImRlZmF1bHRWYWx1ZSIsImdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbiIsImFubm90YXRpb25JZkV4cHJlc3Npb24iLCJJZiIsInBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbiIsIk5vdCIsImVxdWFsIiwiRXEiLCJub3RFcXVhbCIsIk5lIiwiZ3JlYXRlclRoYW4iLCJHdCIsImdyZWF0ZXJPckVxdWFsIiwiR2UiLCJsZXNzVGhhbiIsIkx0IiwibGVzc09yRXF1YWwiLCJMZSIsIk9yIiwib3JDb25kaXRpb24iLCJBbmQiLCJhbmRDb25kaXRpb24iLCJhbm5vdGF0aW9uQXBwbHlFeHByZXNzaW9uIiwiaGFzT3duUHJvcGVydHkiLCIkT3IiLCIkQW5kIiwiJE5vdCIsIiRFcSIsIiROZSIsIiRHdCIsIiRHZSIsIiRMdCIsIiRMZSIsIiRQYXRoIiwiRnVuY3Rpb24iLCIkRnVuY3Rpb24iLCJBcHBseSIsIiRBcHBseSIsIiRJZiIsInJlc29sdmVFbnVtVmFsdWUiLCIkRW51bU1lbWJlciIsImlmRWxzZSIsImFwcGx5RXhwcmVzc2lvbiIsImFwcGx5UGFyYW0iLCJhcHBseVBhcmFtQ29udmVydGVkIiwiY29tcGFyaXNvbiIsImxlZnRPcGVyYW5kIiwicmlnaHRPcGVyYW5kIiwibGVmdEV4cHJlc3Npb24iLCJyaWdodEV4cHJlc3Npb24iLCJsZWZ0IiwicmlnaHQiLCJyZWR1Y2VkIiwiY29uZGl0aW9uRXhwcmVzc2lvbiIsIm9uVHJ1ZUV4cHJlc3Npb24iLCJvbkZhbHNlRXhwcmVzc2lvbiIsInBhdGhJZHgiLCJteUlmRWxzZUV4cHJlc3Npb24iLCJmb3JtYXRSZXN1bHQiLCJhbGxQYXJ0cyIsInRyYW5zZm9ybVJlY3Vyc2l2ZWx5IiwiY29uc3RhbnRQYXRoIiwidW5zaGlmdCIsIkpTT04iLCJzdHJpbmdpZnkiLCJoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0IiwiZm9ybWF0dGVyRnVuY3Rpb24iLCJjb250ZXh0RW50aXR5VHlwZSIsInBhcmFtZXRlckV4cHJlc3Npb25zIiwia2V5cyIsImZ1bmN0aW9uTmFtZSIsIl9fZnVuY3Rpb25OYW1lIiwic3BsaXQiLCJmb3JtYXR0ZXJDbGFzcyIsImZvcm1hdHRlck5hbWUiLCJhZGRUeXBlSW5mb3JtYXRpb24iLCJvRm9ybWF0T3B0aW9ucyIsInNob3dOdW1iZXIiLCJpbmRleE9mIiwic2hvd01lYXN1cmUiLCJlbXB0eVN0cmluZyIsInBhcnNlQXNTdHJpbmciLCJ1b21QYXRoIiwibW9kZSIsImN1cnJlbmN5UGF0aCIsImZvcm1hdE9wdGlvbnMiLCJmdW5jIiwib24iLCJpc0VtcHR5IiwiaW5FeHByZXNzaW9ucyIsImNvbmNhdGVuYXRlZCIsInRvU3RyaW5nIiwibXlDb25jYXRFeHByZXNzaW9uIiwiaW5FeHByZXNzaW9uIiwiZXhwcmVzc2lvblR5cGUiLCJ0cmFuc2Zvcm1GdW5jdGlvbiIsImluY2x1ZGVBbGxFeHByZXNzaW9uIiwicGFyYW1ldGVyIiwic3ViRXhwcmVzc2lvbiIsImJpbmRpbmdQYXJhbWV0ZXIiLCJuZWVkUGFyZW50aGVzaXMiLCJjb21waWxlQ29uc3RhbnRPYmplY3QiLCJpc051bGxhYmxlIiwibyIsInByb3BlcnRpZXMiLCJjaGlsZFJlc3VsdCIsImNvbXBpbGVFeHByZXNzaW9uIiwiY29tcGlsZUNvbnN0YW50IiwiZW1iZWRkZWRJbkJpbmRpbmciLCJjb21waWxlUGF0aEluTW9kZWxFeHByZXNzaW9uIiwiZXhwcmVzc2lvbkZvckJpbmRpbmciLCJlbWJlZGRlZFNlcGFyYXRvciIsImNvbnN0cmFpbnRzIiwiY29tcGxleEJpbmRpbmdEZWZpbml0aW9uIiwiY29tcGlsZVBhdGhJbk1vZGVsIiwib3V0QmluZGluZyIsImNvbXBpbGVDb21wbGV4VHlwZUV4cHJlc3Npb24iLCJjb21waWxlUGF0aFBhcmFtZXRlciIsIm91dHB1dEVuZCIsImhhc0VsZW1lbnRzIiwicGFyYW0iLCJ3cmFwQmluZGluZ0V4cHJlc3Npb24iLCJwYXJlbnRoZXNpc1JlcXVpcmVkIiwia2VlcFRhcmdldFR5cGUiLCJhcmd1bWVudFN0cmluZyIsImFyZyIsInN1YnN0ciIsImNvbXBhcmlzb25FeHByZXNzaW9uIiwiY29tcGlsZUNvbXBhcmlzb25FeHByZXNzaW9uIiwiaWZFbHNlRXhwcmVzc2lvbiIsInNldEV4cHJlc3Npb24iLCJjb25jYXRFeHByZXNzaW9uIiwibmVzdGVkRXhwcmVzc2lvbiIsImxlbmd0aEV4cHJlc3Npb24iLCJub3RFeHByZXNzaW9uIiwidHJ1dGh5RXhwcmVzc2lvbiIsImZvcm1hdHRlckV4cHJlc3Npb24iLCJjb21waWxlRm9ybWF0dGVyRXhwcmVzc2lvbiIsImNvbXBsZXhUeXBlRXhwcmVzc2lvbiIsImNvbXBpbGVPcGVyYW5kIiwiY29tcGlsZWRPcGVyYW5kIiwicGFydHMiLCJzaW5nbGVQYXRoIiwib3V0VmFsdWUiXSwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzIjpbIkJpbmRpbmdUb29sa2l0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHtcblx0QW5kQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEFuZENvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0QXBwbHlBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0Q29uZGl0aW9uYWxDaGVja09yVmFsdWUsXG5cdEVudGl0eVNldCxcblx0RW50aXR5VHlwZSxcblx0RXFBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0RXFDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdEdlQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEdlQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRHdEFubm90YXRpb25FeHByZXNzaW9uLFxuXHRHdENvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0SWZBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0SWZBbm5vdGF0aW9uRXhwcmVzc2lvblZhbHVlLFxuXHRMZUFubm90YXRpb25FeHByZXNzaW9uLFxuXHRMZUNvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0THRBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0THRDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdE5lQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdE5lQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHROb3RBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0Tm90Q29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRPckFubm90YXRpb25FeHByZXNzaW9uLFxuXHRPckNvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0UGF0aEFubm90YXRpb25FeHByZXNzaW9uLFxuXHRQYXRoQ29uZGl0aW9uRXhwcmVzc2lvbixcblx0UHJvcGVydHlBbm5vdGF0aW9uVmFsdWVcbn0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzXCI7XG5pbXBvcnQgeyByZXNvbHZlRW51bVZhbHVlIH0gZnJvbSBcIi4vQW5ub3RhdGlvbkVudW1cIjtcblxudHlwZSBQcmltaXRpdmVUeXBlID0gc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHwgYm9vbGVhbiB8IG9iamVjdCB8IG51bGwgfCB1bmRlZmluZWQ7XG50eXBlIFByaW1pdGl2ZVR5cGVDYXN0PFA+ID1cblx0fCAoUCBleHRlbmRzIEJvb2xlYW4gPyBib29sZWFuIDogbmV2ZXIpXG5cdHwgKFAgZXh0ZW5kcyBOdW1iZXIgPyBudW1iZXIgOiBuZXZlcilcblx0fCAoUCBleHRlbmRzIFN0cmluZyA/IHN0cmluZyA6IG5ldmVyKVxuXHR8IFA7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG50eXBlIEJhc2VFeHByZXNzaW9uPFQ+ID0ge1xuXHRfdHlwZTogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgQ29uc3RhbnRFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkNvbnN0YW50XCI7XG5cdHZhbHVlOiBUO1xufTtcblxudHlwZSBTZXRPcGVyYXRvciA9IFwiJiZcIiB8IFwifHxcIjtcbmV4cG9ydCB0eXBlIFNldEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxib29sZWFuPiAmIHtcblx0X3R5cGU6IFwiU2V0XCI7XG5cdG9wZXJhdG9yOiBTZXRPcGVyYXRvcjtcblx0b3BlcmFuZHM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPltdO1xufTtcblxuZXhwb3J0IHR5cGUgTm90RXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPGJvb2xlYW4+ICYge1xuXHRfdHlwZTogXCJOb3RcIjtcblx0b3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+O1xufTtcblxuZXhwb3J0IHR5cGUgVHJ1dGh5RXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPGJvb2xlYW4+ICYge1xuXHRfdHlwZTogXCJUcnV0aHlcIjtcblx0b3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz47XG59O1xuXG5leHBvcnQgdHlwZSBSZWZlcmVuY2VFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248b2JqZWN0PiAmIHtcblx0X3R5cGU6IFwiUmVmXCI7XG5cdHJlZjogc3RyaW5nIHwgbnVsbDtcbn07XG5cbmV4cG9ydCB0eXBlIEZvcm1hdHRlckV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiRm9ybWF0dGVyXCI7XG5cdGZuOiBzdHJpbmc7XG5cdHBhcmFtZXRlcnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxhbnk+W107XG59O1xuXG50eXBlIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJDb21wbGV4VHlwZVwiO1xuXHR0eXBlOiBzdHJpbmc7XG5cdGZvcm1hdE9wdGlvbnM6IGFueTtcblx0cGFyYW1ldGVyczogb2JqZWN0O1xuXHRiaW5kaW5nUGFyYW1ldGVyczogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGFueT5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIEZ1bmN0aW9uRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJGdW5jdGlvblwiO1xuXHRvYmo/OiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248b2JqZWN0Pjtcblx0Zm46IHN0cmluZztcblx0cGFyYW1ldGVyczogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGFueT5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIENvbmNhdEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxzdHJpbmc+ICYge1xuXHRfdHlwZTogXCJDb25jYXRcIjtcblx0ZXhwcmVzc2lvbnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxzdHJpbmc+W107XG59O1xuXG5leHBvcnQgdHlwZSBMZW5ndGhFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248c3RyaW5nPiAmIHtcblx0X3R5cGU6IFwiTGVuZ3RoXCI7XG5cdHBhdGhJbk1vZGVsOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248YW55Pjtcbn07XG5cbnR5cGUgVW5yZXNvbHZlYWJsZVBhdGhFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248c3RyaW5nPiAmIHtcblx0X3R5cGU6IFwiVW5yZXNvbHZhYmxlXCI7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIFBhdGhJbk1vZGVsRXhwcmVzc2lvblxuICovXG5leHBvcnQgdHlwZSBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiUGF0aEluTW9kZWxcIjtcblx0bW9kZWxOYW1lPzogc3RyaW5nO1xuXHRwYXRoOiBzdHJpbmc7XG5cdHRhcmdldEVudGl0eVNldD86IEVudGl0eVNldDtcblx0dHlwZT86IHN0cmluZztcblx0Y29uc3RyYWludHM/OiBhbnk7XG5cdHBhcmFtZXRlcnM/OiBhbnk7XG5cdHRhcmdldFR5cGU/OiBzdHJpbmc7XG5cdG1vZGU/OiBzdHJpbmc7XG5cdGZvcm1hdE9wdGlvbnM/OiBhbnk7XG59O1xuXG5leHBvcnQgdHlwZSBFbWJlZGRlZFVJNUJpbmRpbmdFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkVtYmVkZGVkQmluZGluZ1wiO1xuXHR2YWx1ZTogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgRW1iZWRkZWRVSTVFeHByZXNzaW9uQmluZGluZ0V4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiO1xuXHR2YWx1ZTogc3RyaW5nO1xufTtcblxudHlwZSBDb21wYXJpc29uT3BlcmF0b3IgPSBcIj09PVwiIHwgXCIhPT1cIiB8IFwiPj1cIiB8IFwiPlwiIHwgXCI8PVwiIHwgXCI8XCI7XG5leHBvcnQgdHlwZSBDb21wYXJpc29uRXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPGJvb2xlYW4+ICYge1xuXHRfdHlwZTogXCJDb21wYXJpc29uXCI7XG5cdG9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3I7XG5cdG9wZXJhbmQxOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248YW55Pjtcblx0b3BlcmFuZDI6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxhbnk+O1xufTtcblxuZXhwb3J0IHR5cGUgSWZFbHNlRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJJZkVsc2VcIjtcblx0Y29uZGl0aW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj47XG5cdG9uVHJ1ZTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRvbkZhbHNlOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG59O1xuXG4vKipcbiAqIEFuIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gdHlwZSBULlxuICpcbiAqIEB0eXBlZGVmIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvblxuICovXG5leHBvcnQgdHlwZSBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4gPVxuXHR8IFVucmVzb2x2ZWFibGVQYXRoRXhwcmVzc2lvblxuXHR8IENvbnN0YW50RXhwcmVzc2lvbjxUPlxuXHR8IFNldEV4cHJlc3Npb25cblx0fCBOb3RFeHByZXNzaW9uXG5cdHwgVHJ1dGh5RXhwcmVzc2lvblxuXHR8IENvbmNhdEV4cHJlc3Npb25cblx0fCBMZW5ndGhFeHByZXNzaW9uXG5cdHwgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+XG5cdHwgRW1iZWRkZWRVSTVCaW5kaW5nRXhwcmVzc2lvbjxUPlxuXHR8IEVtYmVkZGVkVUk1RXhwcmVzc2lvbkJpbmRpbmdFeHByZXNzaW9uPFQ+XG5cdHwgQ29tcGFyaXNvbkV4cHJlc3Npb25cblx0fCBJZkVsc2VFeHByZXNzaW9uPFQ+XG5cdHwgRm9ybWF0dGVyRXhwcmVzc2lvbjxUPlxuXHR8IENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPlxuXHR8IFJlZmVyZW5jZUV4cHJlc3Npb25cblx0fCBGdW5jdGlvbkV4cHJlc3Npb248VD47XG5cbi8qKlxuICogQW4gZXhwcmVzc2lvbiB0aGF0IGV2YWx1YXRlcyB0byB0eXBlIFQsIG9yIGEgY29uc3RhbnQgdmFsdWUgb2YgdHlwZSBUXG4gKi9cbnR5cGUgRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPiA9IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB8IFQ7XG5cbmV4cG9ydCBjb25zdCB1bnJlc29sdmVhYmxlRXhwcmVzc2lvbjogVW5yZXNvbHZlYWJsZVBhdGhFeHByZXNzaW9uID0ge1xuXHRfdHlwZTogXCJVbnJlc29sdmFibGVcIlxufTtcblxuZnVuY3Rpb24gZXNjYXBlWG1sQXR0cmlidXRlKGlucHV0U3RyaW5nOiBzdHJpbmcpIHtcblx0cmV0dXJuIGlucHV0U3RyaW5nLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc1VucmVzb2x2ZWFibGVFeHByZXNzaW9uKC4uLmV4cHJlc3Npb25zOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248YW55PltdKTogYm9vbGVhbiB7XG5cdHJldHVybiBleHByZXNzaW9ucy5maW5kKChleHByKSA9PiBleHByLl90eXBlID09PSBcIlVucmVzb2x2YWJsZVwiKSAhPT0gdW5kZWZpbmVkO1xufVxuLyoqXG4gKiBDaGVjayB0d28gZXhwcmVzc2lvbnMgZm9yIChkZWVwKSBlcXVhbGl0eS5cbiAqXG4gKiBAcGFyYW0gYVxuICogQHBhcmFtIGJcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgdHdvIGV4cHJlc3Npb25zIGFyZSBlcXVhbFxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWw8VD4oYTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LCBiOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pOiBib29sZWFuIHtcblx0aWYgKGEuX3R5cGUgIT09IGIuX3R5cGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRzd2l0Y2ggKGEuX3R5cGUpIHtcblx0XHRjYXNlIFwiVW5yZXNvbHZhYmxlXCI6XG5cdFx0XHRyZXR1cm4gZmFsc2U7IC8vIFVucmVzb2x2YWJsZSBpcyBuZXZlciBlcXVhbCB0byBhbnl0aGluZyBldmVuIGl0c2VsZlxuXHRcdGNhc2UgXCJDb25zdGFudFwiOlxuXHRcdGNhc2UgXCJFbWJlZGRlZEJpbmRpbmdcIjpcblx0XHRjYXNlIFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiOlxuXHRcdFx0cmV0dXJuIGEudmFsdWUgPT09IChiIGFzIENvbnN0YW50RXhwcmVzc2lvbjxUPikudmFsdWU7XG5cblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0XHRyZXR1cm4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9wZXJhbmQsIChiIGFzIE5vdEV4cHJlc3Npb24pLm9wZXJhbmQpO1xuXHRcdGNhc2UgXCJUcnV0aHlcIjpcblx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub3BlcmFuZCwgKGIgYXMgVHJ1dGh5RXhwcmVzc2lvbikub3BlcmFuZCk7XG5cdFx0Y2FzZSBcIlNldFwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS5vcGVyYXRvciA9PT0gKGIgYXMgU2V0RXhwcmVzc2lvbikub3BlcmF0b3IgJiZcblx0XHRcdFx0YS5vcGVyYW5kcy5sZW5ndGggPT09IChiIGFzIFNldEV4cHJlc3Npb24pLm9wZXJhbmRzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLm9wZXJhbmRzLmV2ZXJ5KChleHByZXNzaW9uKSA9PlxuXHRcdFx0XHRcdChiIGFzIFNldEV4cHJlc3Npb24pLm9wZXJhbmRzLnNvbWUoKG90aGVyRXhwcmVzc2lvbikgPT4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChleHByZXNzaW9uLCBvdGhlckV4cHJlc3Npb24pKVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIklmRWxzZVwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLmNvbmRpdGlvbiwgKGIgYXMgSWZFbHNlRXhwcmVzc2lvbjxUPikuY29uZGl0aW9uKSAmJlxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub25UcnVlLCAoYiBhcyBJZkVsc2VFeHByZXNzaW9uPFQ+KS5vblRydWUpICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vbkZhbHNlLCAoYiBhcyBJZkVsc2VFeHByZXNzaW9uPFQ+KS5vbkZhbHNlKVxuXHRcdFx0KTtcblxuXHRcdGNhc2UgXCJDb21wYXJpc29uXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLm9wZXJhdG9yID09PSAoYiBhcyBDb21wYXJpc29uRXhwcmVzc2lvbikub3BlcmF0b3IgJiZcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9wZXJhbmQxLCAoYiBhcyBDb21wYXJpc29uRXhwcmVzc2lvbikub3BlcmFuZDEpICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vcGVyYW5kMiwgKGIgYXMgQ29tcGFyaXNvbkV4cHJlc3Npb24pLm9wZXJhbmQyKVxuXHRcdFx0KTtcblxuXHRcdGNhc2UgXCJDb25jYXRcIjpcblx0XHRcdGNvbnN0IGFFeHByZXNzaW9ucyA9IGEuZXhwcmVzc2lvbnM7XG5cdFx0XHRjb25zdCBiRXhwcmVzc2lvbnMgPSAoYiBhcyBDb25jYXRFeHByZXNzaW9uKS5leHByZXNzaW9ucztcblx0XHRcdGlmIChhRXhwcmVzc2lvbnMubGVuZ3RoICE9PSBiRXhwcmVzc2lvbnMubGVuZ3RoKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBhRXhwcmVzc2lvbnMuZXZlcnkoKGV4cHJlc3Npb24sIGluZGV4KSA9PiB7XG5cdFx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGV4cHJlc3Npb24sIGJFeHByZXNzaW9uc1tpbmRleF0pO1xuXHRcdFx0fSk7XG5cblx0XHRjYXNlIFwiTGVuZ3RoXCI6XG5cdFx0XHRyZXR1cm4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLnBhdGhJbk1vZGVsLCAoYiBhcyBMZW5ndGhFeHByZXNzaW9uKS5wYXRoSW5Nb2RlbCk7XG5cblx0XHRjYXNlIFwiUGF0aEluTW9kZWxcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEubW9kZWxOYW1lID09PSAoYiBhcyBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4pLm1vZGVsTmFtZSAmJlxuXHRcdFx0XHRhLnBhdGggPT09IChiIGFzIFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPikucGF0aCAmJlxuXHRcdFx0XHRhLnRhcmdldEVudGl0eVNldCA9PT0gKGIgYXMgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+KS50YXJnZXRFbnRpdHlTZXRcblx0XHRcdCk7XG5cblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLmZuID09PSAoYiBhcyBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+KS5mbiAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMubGVuZ3RoID09PSAoYiBhcyBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+KS5wYXJhbWV0ZXJzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbCgoYiBhcyBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+KS5wYXJhbWV0ZXJzW2luZGV4XSwgdmFsdWUpKVxuXHRcdFx0KTtcblx0XHRjYXNlIFwiQ29tcGxleFR5cGVcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEudHlwZSA9PT0gKGIgYXMgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+KS50eXBlICYmXG5cdFx0XHRcdGEuYmluZGluZ1BhcmFtZXRlcnMubGVuZ3RoID09PSAoYiBhcyBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pLmJpbmRpbmdQYXJhbWV0ZXJzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLmJpbmRpbmdQYXJhbWV0ZXJzLmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+XG5cdFx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbCgoYiBhcyBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pLmJpbmRpbmdQYXJhbWV0ZXJzW2luZGV4XSwgdmFsdWUpXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cdFx0Y2FzZSBcIkZ1bmN0aW9uXCI6XG5cdFx0XHRjb25zdCBvdGhlckZ1bmN0aW9uID0gYiBhcyBGdW5jdGlvbkV4cHJlc3Npb248VD47XG5cdFx0XHRpZiAoYS5vYmogPT09IHVuZGVmaW5lZCB8fCBvdGhlckZ1bmN0aW9uLm9iaiA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHJldHVybiBhLm9iaiA9PT0gb3RoZXJGdW5jdGlvbjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS5mbiA9PT0gb3RoZXJGdW5jdGlvbi5mbiAmJlxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub2JqLCBvdGhlckZ1bmN0aW9uLm9iaikgJiZcblx0XHRcdFx0YS5wYXJhbWV0ZXJzLmxlbmd0aCA9PT0gb3RoZXJGdW5jdGlvbi5wYXJhbWV0ZXJzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChvdGhlckZ1bmN0aW9uLnBhcmFtZXRlcnNbaW5kZXhdLCB2YWx1ZSkpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIlJlZlwiOlxuXHRcdFx0cmV0dXJuIGEucmVmID09PSAoYiBhcyBSZWZlcmVuY2VFeHByZXNzaW9uKS5yZWY7XG5cdH1cblx0cmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgbmVzdGVkIFNldEV4cHJlc3Npb24gYnkgaW5saW5pbmcgb3BlcmFuZHMgb2YgdHlwZSBTZXRFeHByZXNzaW9uIHdpdGggdGhlIHNhbWUgb3BlcmF0b3IuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gZmxhdHRlblxuICogQHJldHVybnMgQSBuZXcgU2V0RXhwcmVzc2lvbiB3aXRoIHRoZSBzYW1lIG9wZXJhdG9yXG4gKi9cbmZ1bmN0aW9uIGZsYXR0ZW5TZXRFeHByZXNzaW9uKGV4cHJlc3Npb246IFNldEV4cHJlc3Npb24pOiBTZXRFeHByZXNzaW9uIHtcblx0cmV0dXJuIGV4cHJlc3Npb24ub3BlcmFuZHMucmVkdWNlKFxuXHRcdChyZXN1bHQ6IFNldEV4cHJlc3Npb24sIG9wZXJhbmQpID0+IHtcblx0XHRcdGNvbnN0IGNhbmRpZGF0ZXNGb3JGbGF0dGVuaW5nID1cblx0XHRcdFx0b3BlcmFuZC5fdHlwZSA9PT0gXCJTZXRcIiAmJiBvcGVyYW5kLm9wZXJhdG9yID09PSBleHByZXNzaW9uLm9wZXJhdG9yID8gb3BlcmFuZC5vcGVyYW5kcyA6IFtvcGVyYW5kXTtcblx0XHRcdGNhbmRpZGF0ZXNGb3JGbGF0dGVuaW5nLmZvckVhY2goKGNhbmRpZGF0ZSkgPT4ge1xuXHRcdFx0XHRpZiAocmVzdWx0Lm9wZXJhbmRzLmV2ZXJ5KChlKSA9PiAhX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChlLCBjYW5kaWRhdGUpKSkge1xuXHRcdFx0XHRcdHJlc3VsdC5vcGVyYW5kcy5wdXNoKGNhbmRpZGF0ZSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9LFxuXHRcdHsgX3R5cGU6IFwiU2V0XCIsIG9wZXJhdG9yOiBleHByZXNzaW9uLm9wZXJhdG9yLCBvcGVyYW5kczogW10gfVxuXHQpO1xufVxuXG4vKipcbiAqIERldGVjdHMgd2hldGhlciBhbiBhcnJheSBvZiBib29sZWFuIGV4cHJlc3Npb25zIGNvbnRhaW5zIGFuIGV4cHJlc3Npb24gYW5kIGl0cyBuZWdhdGlvbi5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbnMgQXJyYXkgb2YgZXhwcmVzc2lvbnNcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgc2V0IG9mIGV4cHJlc3Npb25zIGNvbnRhaW5zIGFuIGV4cHJlc3Npb24gYW5kIGl0cyBuZWdhdGlvblxuICovXG5mdW5jdGlvbiBoYXNPcHBvc2l0ZUV4cHJlc3Npb25zKGV4cHJlc3Npb25zOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj5bXSk6IGJvb2xlYW4ge1xuXHRjb25zdCBuZWdhdGVkRXhwcmVzc2lvbnMgPSBleHByZXNzaW9ucy5tYXAobm90KTtcblx0cmV0dXJuIGV4cHJlc3Npb25zLnNvbWUoKGV4cHJlc3Npb24sIGluZGV4KSA9PiB7XG5cdFx0Zm9yIChsZXQgaSA9IGluZGV4ICsgMTsgaSA8IG5lZ2F0ZWRFeHByZXNzaW9ucy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoZXhwcmVzc2lvbiwgbmVnYXRlZEV4cHJlc3Npb25zW2ldKSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9KTtcbn1cblxuLyoqXG4gKiBMb2dpY2FsIGBhbmRgIGV4cHJlc3Npb24uXG4gKlxuICogVGhlIGV4cHJlc3Npb24gaXMgc2ltcGxpZmllZCB0byBmYWxzZSBpZiB0aGlzIGNhbiBiZSBkZWNpZGVkIHN0YXRpY2FsbHkgKHRoYXQgaXMsIGlmIG9uZSBvcGVyYW5kIGlzIGEgY29uc3RhbnRcbiAqIGZhbHNlIG9yIGlmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGFuIG9wZXJhbmQgYW5kIGl0cyBuZWdhdGlvbikuXG4gKlxuICogQHBhcmFtIG9wZXJhbmRzIEV4cHJlc3Npb25zIHRvIGNvbm5lY3QgYnkgYGFuZGBcbiAqIEByZXR1cm5zIEV4cHJlc3Npb24gZXZhbHVhdGluZyB0byBib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmQoLi4ub3BlcmFuZHM6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPltdKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0Y29uc3QgZXhwcmVzc2lvbnMgPSBmbGF0dGVuU2V0RXhwcmVzc2lvbih7XG5cdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0b3BlcmF0b3I6IFwiJiZcIixcblx0XHRvcGVyYW5kczogb3BlcmFuZHMubWFwKHdyYXBQcmltaXRpdmUpXG5cdH0pLm9wZXJhbmRzO1xuXG5cdGlmIChoYXNVbnJlc29sdmVhYmxlRXhwcmVzc2lvbiguLi5leHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZlYWJsZUV4cHJlc3Npb247XG5cdH1cblx0bGV0IGlzU3RhdGljRmFsc2UgPSBmYWxzZTtcblx0Y29uc3Qgbm9uVHJpdmlhbEV4cHJlc3Npb24gPSBleHByZXNzaW9ucy5maWx0ZXIoKGV4cHJlc3Npb24pID0+IHtcblx0XHRpZiAoaXNGYWxzZShleHByZXNzaW9uKSkge1xuXHRcdFx0aXNTdGF0aWNGYWxzZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAhaXNDb25zdGFudChleHByZXNzaW9uKTtcblx0fSk7XG5cdGlmIChpc1N0YXRpY0ZhbHNlKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0fSBlbHNlIGlmIChub25Ucml2aWFsRXhwcmVzc2lvbi5sZW5ndGggPT09IDApIHtcblx0XHQvLyBSZXNvbHZlIHRoZSBjb25zdGFudCB0aGVuXG5cdFx0Y29uc3QgaXNWYWxpZCA9IGV4cHJlc3Npb25zLnJlZHVjZSgocmVzdWx0LCBleHByZXNzaW9uKSA9PiByZXN1bHQgJiYgaXNUcnVlKGV4cHJlc3Npb24pLCB0cnVlKTtcblx0XHRyZXR1cm4gY29uc3RhbnQoaXNWYWxpZCk7XG5cdH0gZWxzZSBpZiAobm9uVHJpdmlhbEV4cHJlc3Npb24ubGVuZ3RoID09PSAxKSB7XG5cdFx0cmV0dXJuIG5vblRyaXZpYWxFeHByZXNzaW9uWzBdO1xuXHR9IGVsc2UgaWYgKGhhc09wcG9zaXRlRXhwcmVzc2lvbnMobm9uVHJpdmlhbEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0XHRvcGVyYXRvcjogXCImJlwiLFxuXHRcdFx0b3BlcmFuZHM6IG5vblRyaXZpYWxFeHByZXNzaW9uXG5cdFx0fTtcblx0fVxufVxuXG4vKipcbiAqIExvZ2ljYWwgYG9yYCBleHByZXNzaW9uLlxuICpcbiAqIFRoZSBleHByZXNzaW9uIGlzIHNpbXBsaWZpZWQgdG8gdHJ1ZSBpZiB0aGlzIGNhbiBiZSBkZWNpZGVkIHN0YXRpY2FsbHkgKHRoYXQgaXMsIGlmIG9uZSBvcGVyYW5kIGlzIGEgY29uc3RhbnRcbiAqIHRydWUgb3IgaWYgdGhlIGV4cHJlc3Npb24gY29udGFpbnMgYW4gb3BlcmFuZCBhbmQgaXRzIG5lZ2F0aW9uKS5cbiAqXG4gKiBAcGFyYW0gb3BlcmFuZHMgRXhwcmVzc2lvbnMgdG8gY29ubmVjdCBieSBgb3JgXG4gKiBAcmV0dXJucyBFeHByZXNzaW9uIGV2YWx1YXRpbmcgdG8gYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gb3IoLi4ub3BlcmFuZHM6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPltdKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0Y29uc3QgZXhwcmVzc2lvbnMgPSBmbGF0dGVuU2V0RXhwcmVzc2lvbih7XG5cdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0b3BlcmF0b3I6IFwifHxcIixcblx0XHRvcGVyYW5kczogb3BlcmFuZHMubWFwKHdyYXBQcmltaXRpdmUpXG5cdH0pLm9wZXJhbmRzO1xuXHRpZiAoaGFzVW5yZXNvbHZlYWJsZUV4cHJlc3Npb24oLi4uZXhwcmVzc2lvbnMpKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2ZWFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGxldCBpc1N0YXRpY1RydWUgPSBmYWxzZTtcblx0Y29uc3Qgbm9uVHJpdmlhbEV4cHJlc3Npb24gPSBleHByZXNzaW9ucy5maWx0ZXIoKGV4cHJlc3Npb24pID0+IHtcblx0XHRpZiAoaXNUcnVlKGV4cHJlc3Npb24pKSB7XG5cdFx0XHRpc1N0YXRpY1RydWUgPSB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gIWlzQ29uc3RhbnQoZXhwcmVzc2lvbikgfHwgZXhwcmVzc2lvbi52YWx1ZTtcblx0fSk7XG5cdGlmIChpc1N0YXRpY1RydWUpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodHJ1ZSk7XG5cdH0gZWxzZSBpZiAobm9uVHJpdmlhbEV4cHJlc3Npb24ubGVuZ3RoID09PSAwKSB7XG5cdFx0Ly8gUmVzb2x2ZSB0aGUgY29uc3RhbnQgdGhlblxuXHRcdGNvbnN0IGlzVmFsaWQgPSBleHByZXNzaW9ucy5yZWR1Y2UoKHJlc3VsdCwgZXhwcmVzc2lvbikgPT4gcmVzdWx0ICYmIGlzVHJ1ZShleHByZXNzaW9uKSwgdHJ1ZSk7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGlzVmFsaWQpO1xuXHR9IGVsc2UgaWYgKG5vblRyaXZpYWxFeHByZXNzaW9uLmxlbmd0aCA9PT0gMSkge1xuXHRcdHJldHVybiBub25Ucml2aWFsRXhwcmVzc2lvblswXTtcblx0fSBlbHNlIGlmIChoYXNPcHBvc2l0ZUV4cHJlc3Npb25zKG5vblRyaXZpYWxFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBjb25zdGFudCh0cnVlKTtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0XHRvcGVyYXRvcjogXCJ8fFwiLFxuXHRcdFx0b3BlcmFuZHM6IG5vblRyaXZpYWxFeHByZXNzaW9uXG5cdFx0fTtcblx0fVxufVxuXG4vKipcbiAqIExvZ2ljYWwgYG5vdGAgb3BlcmF0b3IuXG4gKlxuICogQHBhcmFtIG9wZXJhbmQgVGhlIGV4cHJlc3Npb24gdG8gcmV2ZXJzZVxuICogQHJldHVybnMgVGhlIHJlc3VsdGluZyBleHByZXNzaW9uIHRoYXQgZXZhbHVhdGVzIHRvIGJvb2xlYW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vdChvcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8Ym9vbGVhbj4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRvcGVyYW5kID0gd3JhcFByaW1pdGl2ZShvcGVyYW5kKTtcblx0aWYgKGhhc1VucmVzb2x2ZWFibGVFeHByZXNzaW9uKG9wZXJhbmQpKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2ZWFibGVFeHByZXNzaW9uO1xuXHR9IGVsc2UgaWYgKGlzQ29uc3RhbnQob3BlcmFuZCkpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoIW9wZXJhbmQudmFsdWUpO1xuXHR9IGVsc2UgaWYgKFxuXHRcdHR5cGVvZiBvcGVyYW5kID09PSBcIm9iamVjdFwiICYmXG5cdFx0b3BlcmFuZC5fdHlwZSA9PT0gXCJTZXRcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmF0b3IgPT09IFwifHxcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmFuZHMuZXZlcnkoKGV4cHJlc3Npb24pID0+IGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgfHwgaXNDb21wYXJpc29uKGV4cHJlc3Npb24pKVxuXHQpIHtcblx0XHRyZXR1cm4gYW5kKC4uLm9wZXJhbmQub3BlcmFuZHMubWFwKChleHByZXNzaW9uKSA9PiBub3QoZXhwcmVzc2lvbikpKTtcblx0fSBlbHNlIGlmIChcblx0XHR0eXBlb2Ygb3BlcmFuZCA9PT0gXCJvYmplY3RcIiAmJlxuXHRcdG9wZXJhbmQuX3R5cGUgPT09IFwiU2V0XCIgJiZcblx0XHRvcGVyYW5kLm9wZXJhdG9yID09PSBcIiYmXCIgJiZcblx0XHRvcGVyYW5kLm9wZXJhbmRzLmV2ZXJ5KChleHByZXNzaW9uKSA9PiBpc0NvbnN0YW50KGV4cHJlc3Npb24pIHx8IGlzQ29tcGFyaXNvbihleHByZXNzaW9uKSlcblx0KSB7XG5cdFx0cmV0dXJuIG9yKC4uLm9wZXJhbmQub3BlcmFuZHMubWFwKChleHByZXNzaW9uKSA9PiBub3QoZXhwcmVzc2lvbikpKTtcblx0fSBlbHNlIGlmIChpc0NvbXBhcmlzb24ob3BlcmFuZCkpIHtcblx0XHQvLyBDcmVhdGUgdGhlIHJldmVyc2UgY29tcGFyaXNvblxuXHRcdHN3aXRjaCAob3BlcmFuZC5vcGVyYXRvcikge1xuXHRcdFx0Y2FzZSBcIiE9PVwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCI9PT1cIiB9O1xuXHRcdFx0Y2FzZSBcIjxcIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPj1cIiB9O1xuXHRcdFx0Y2FzZSBcIjw9XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIj5cIiB9O1xuXHRcdFx0Y2FzZSBcIj09PVwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCIhPT1cIiB9O1xuXHRcdFx0Y2FzZSBcIj5cIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPD1cIiB9O1xuXHRcdFx0Y2FzZSBcIj49XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIjxcIiB9O1xuXHRcdH1cblx0fSBlbHNlIGlmIChvcGVyYW5kLl90eXBlID09PSBcIk5vdFwiKSB7XG5cdFx0cmV0dXJuIG9wZXJhbmQub3BlcmFuZDtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiTm90XCIsXG5cdFx0b3BlcmFuZDogb3BlcmFuZFxuXHR9O1xufVxuXG4vKipcbiAqIEV2YWx1YXRlcyB3aGV0aGVyIGEgYmluZGluZyBleHByZXNzaW9uIGlzIGVxdWFsIHRvIHRydWUgd2l0aCBhIGxvb3NlIGVxdWFsaXR5LlxuICpcbiAqIEBwYXJhbSBvcGVyYW5kIFRoZSBleHByZXNzaW9uIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBUaGUgcmVzdWx0aW5nIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNUcnV0aHkob3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRpZiAoaXNDb25zdGFudChvcGVyYW5kKSkge1xuXHRcdHJldHVybiBjb25zdGFudCghIW9wZXJhbmQudmFsdWUpO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiB7XG5cdFx0XHRfdHlwZTogXCJUcnV0aHlcIixcblx0XHRcdG9wZXJhbmQ6IG9wZXJhbmRcblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGJpbmRpbmcgZXhwcmVzc2lvbiB0aGF0IHdpbGwgYmUgZXZhbHVhdGVkIGJ5IHRoZSBjb3JyZXNwb25kaW5nIG1vZGVsLlxuICpcbiAqIEBwYXJhbSBwYXRoXG4gKiBAcGFyYW0gbW9kZWxOYW1lXG4gKiBAcGFyYW0gdmlzaXRlZE5hdmlnYXRpb25QYXRoc1xuICogQHBhcmFtIHBhdGhWaXNpdG9yXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGF0aW5nIHRoYXQgcGF0aCBpbiB0aGUgbW9kZWxcbiAqIEBkZXByZWNhdGVkIHVzZSBwYXRoSW5Nb2RlbCBpbnN0ZWFkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiaW5kaW5nRXhwcmVzc2lvbjxUYXJnZXRUeXBlIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHBhdGg6IGFueSxcblx0bW9kZWxOYW1lPzogc3RyaW5nLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT4gfCBVbnJlc29sdmVhYmxlUGF0aEV4cHJlc3Npb24ge1xuXHRyZXR1cm4gcGF0aEluTW9kZWwocGF0aCwgbW9kZWxOYW1lLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGJpbmRpbmcgZXhwcmVzc2lvbiB0aGF0IHdpbGwgYmUgZXZhbHVhdGVkIGJ5IHRoZSBjb3JyZXNwb25kaW5nIG1vZGVsLlxuICpcbiAqIEB0ZW1wbGF0ZSBUYXJnZXRUeXBlXG4gKiBAcGFyYW0gcGF0aCBUaGUgcGF0aCBvbiB0aGUgbW9kZWxcbiAqIEBwYXJhbSBbbW9kZWxOYW1lXSBUaGUgbmFtZSBvZiB0aGUgbW9kZWxcbiAqIEBwYXJhbSBbdmlzaXRlZE5hdmlnYXRpb25QYXRoc10gVGhlIHBhdGhzIGZyb20gdGhlIHJvb3QgZW50aXR5U2V0XG4gKiBAcGFyYW0gW3BhdGhWaXNpdG9yXSBBIGZ1bmN0aW9uIHRvIG1vZGlmeSB0aGUgcmVzdWx0aW5nIHBhdGhcbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50YXRpbmcgdGhhdCBwYXRoIGluIHRoZSBtb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWwoXG5cdHBhdGg6IHVuZGVmaW5lZCxcblx0bW9kZWxOYW1lPzogc3RyaW5nLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzPzogc3RyaW5nW10sXG5cdHBhdGhWaXNpdG9yPzogRnVuY3Rpb25cbik6IFVucmVzb2x2ZWFibGVQYXRoRXhwcmVzc2lvbjtcbmV4cG9ydCBmdW5jdGlvbiBwYXRoSW5Nb2RlbDxUYXJnZXRUeXBlIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHBhdGg6IHN0cmluZyxcblx0bW9kZWxOYW1lPzogc3RyaW5nLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzPzogc3RyaW5nW10sXG5cdHBhdGhWaXNpdG9yPzogdW5kZWZpbmVkXG4pOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT47XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRocz86IHN0cmluZ1tdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBVbnJlc29sdmVhYmxlUGF0aEV4cHJlc3Npb24gfCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT47XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRocz86IHN0cmluZ1tdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBVbnJlc29sdmVhYmxlUGF0aEV4cHJlc3Npb24gfCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT47XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogVW5yZXNvbHZlYWJsZVBhdGhFeHByZXNzaW9uIHwgUGF0aEluTW9kZWxFeHByZXNzaW9uPFRhcmdldFR5cGU+IHtcblx0aWYgKHBhdGggPT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiB1bnJlc29sdmVhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRsZXQgdGFyZ2V0UGF0aDtcblx0aWYgKHBhdGhWaXNpdG9yKSB7XG5cdFx0dGFyZ2V0UGF0aCA9IHBhdGhWaXNpdG9yKHBhdGgpO1xuXHRcdGlmICh0YXJnZXRQYXRoID09PSB1bmRlZmluZWQpIHtcblx0XHRcdHJldHVybiB1bnJlc29sdmVhYmxlRXhwcmVzc2lvbjtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0Y29uc3QgbG9jYWxQYXRoID0gdmlzaXRlZE5hdmlnYXRpb25QYXRocy5jb25jYXQoKTtcblx0XHRsb2NhbFBhdGgucHVzaChwYXRoKTtcblx0XHR0YXJnZXRQYXRoID0gbG9jYWxQYXRoLmpvaW4oXCIvXCIpO1xuXHR9XG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiUGF0aEluTW9kZWxcIixcblx0XHRtb2RlbE5hbWU6IG1vZGVsTmFtZSxcblx0XHRwYXRoOiB0YXJnZXRQYXRoXG5cdH07XG59XG5cbnR5cGUgUGxhaW5FeHByZXNzaW9uT2JqZWN0ID0geyBbaW5kZXg6IHN0cmluZ106IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxhbnk+IH07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNvbnN0YW50IGV4cHJlc3Npb24gYmFzZWQgb24gYSBwcmltaXRpdmUgdmFsdWUuXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB2YWx1ZSBUaGUgY29uc3RhbnQgdG8gd3JhcCBpbiBhbiBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBUaGUgY29uc3RhbnQgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gY29uc3RhbnQ8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KHZhbHVlOiBUKTogQ29uc3RhbnRFeHByZXNzaW9uPFQ+IHtcblx0bGV0IGNvbnN0YW50VmFsdWU6IFQ7XG5cblx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0aWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG5cdFx0XHRjb25zdGFudFZhbHVlID0gdmFsdWUubWFwKHdyYXBQcmltaXRpdmUpIGFzIFQ7XG5cdFx0fSBlbHNlIGlmIChpc1ByaW1pdGl2ZU9iamVjdCh2YWx1ZSkpIHtcblx0XHRcdGNvbnN0YW50VmFsdWUgPSB2YWx1ZS52YWx1ZU9mKCkgYXMgVDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3RhbnRWYWx1ZSA9IE9iamVjdC5lbnRyaWVzKHZhbHVlKS5yZWR1Y2UoKHBsYWluRXhwcmVzc2lvbiwgW2tleSwgdmFsXSkgPT4ge1xuXHRcdFx0XHRjb25zdCB3cmFwcGVkVmFsdWUgPSB3cmFwUHJpbWl0aXZlKHZhbCk7XG5cdFx0XHRcdGlmICh3cmFwcGVkVmFsdWUuX3R5cGUgIT09IFwiQ29uc3RhbnRcIiB8fCB3cmFwcGVkVmFsdWUudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdHBsYWluRXhwcmVzc2lvbltrZXldID0gd3JhcHBlZFZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBwbGFpbkV4cHJlc3Npb247XG5cdFx0XHR9LCB7fSBhcyBQbGFpbkV4cHJlc3Npb25PYmplY3QpIGFzIFQ7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdGNvbnN0YW50VmFsdWUgPSB2YWx1ZTtcblx0fVxuXG5cdHJldHVybiB7IF90eXBlOiBcIkNvbnN0YW50XCIsIHZhbHVlOiBjb25zdGFudFZhbHVlIH07XG59XG5cbnR5cGUgRXZhbHVhdGlvblR5cGUgPSBcImJvb2xlYW5cIjtcbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQmluZGluZ1N0cmluZzxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHZhbHVlOiBzdHJpbmcgfCBib29sZWFuIHwgbnVtYmVyLFxuXHR0YXJnZXRUeXBlPzogRXZhbHVhdGlvblR5cGVcbik6IENvbnN0YW50RXhwcmVzc2lvbjxUPiB8IEVtYmVkZGVkVUk1QmluZGluZ0V4cHJlc3Npb248VD4gfCBFbWJlZGRlZFVJNUV4cHJlc3Npb25CaW5kaW5nRXhwcmVzc2lvbjxUPiB7XG5cdGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZS5zdGFydHNXaXRoKFwie1wiKSkge1xuXHRcdGlmICh2YWx1ZS5zdGFydHNXaXRoKFwiez1cIikpIHtcblx0XHRcdC8vIEV4cHJlc3Npb24gYmluZGluZywgd2UgY2FuIGp1c3QgcmVtb3ZlIHRoZSBvdXRlciBiaW5kaW5nIHRoaW5nc1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0X3R5cGU6IFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiLFxuXHRcdFx0XHR2YWx1ZTogdmFsdWVcblx0XHRcdH07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdF90eXBlOiBcIkVtYmVkZGVkQmluZGluZ1wiLFxuXHRcdFx0XHR2YWx1ZTogdmFsdWVcblx0XHRcdH07XG5cdFx0fVxuXHR9IGVsc2UgaWYgKHRhcmdldFR5cGUgPT09IFwiYm9vbGVhblwiICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAodmFsdWUgPT09IFwidHJ1ZVwiIHx8IHZhbHVlID09PSBcImZhbHNlXCIpKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KHZhbHVlID09PSBcInRydWVcIikgYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBjb25zdGFudCh2YWx1ZSkgYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+O1xuXHR9XG59XG5cbi8qKlxuICogQSBuYW1lZCByZWZlcmVuY2UuXG4gKlxuICogQHNlZSBmblxuICogQHBhcmFtIHJlZmVyZW5jZSBSZWZlcmVuY2VcbiAqIEByZXR1cm5zIFRoZSBvYmplY3QgcmVmZXJlbmNlIGJpbmRpbmcgcGFydFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVmKHJlZmVyZW5jZTogc3RyaW5nIHwgbnVsbCk6IFJlZmVyZW5jZUV4cHJlc3Npb24ge1xuXHRyZXR1cm4geyBfdHlwZTogXCJSZWZcIiwgcmVmOiByZWZlcmVuY2UgfTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgdHlwZSBpcyBhbiBleHByZXNzaW9uLlxuICpcbiAqIEV2ZXJ5IG9iamVjdCBoYXZpbmcgYSBwcm9wZXJ0eSBuYW1lZCBgX3R5cGVgIG9mIHNvbWUgdmFsdWUgaXMgY29uc2lkZXJlZCBhbiBleHByZXNzaW9uLCBldmVuIGlmIHRoZXJlIGlzIGFjdHVhbGx5XG4gKiBubyBzdWNoIGV4cHJlc3Npb24gdHlwZSBzdXBwb3J0ZWQuXG4gKlxuICogQHBhcmFtIHNvbWV0aGluZyBUeXBlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHR5cGUgaXMgY29uc2lkZXJlZCB0byBiZSBhbiBleHByZXNzaW9uXG4gKi9cbmZ1bmN0aW9uIGlzRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oc29tZXRoaW5nOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4pOiBzb21ldGhpbmcgaXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIHNvbWV0aGluZyAhPT0gbnVsbCAmJiB0eXBlb2Ygc29tZXRoaW5nID09PSBcIm9iamVjdFwiICYmIChzb21ldGhpbmcgYXMgQmFzZUV4cHJlc3Npb248VD4pLl90eXBlICE9PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogV3JhcCBhIHByaW1pdGl2ZSBpbnRvIGEgY29uc3RhbnQgZXhwcmVzc2lvbiBpZiBpdCBpcyBub3QgYWxyZWFkeSBhbiBleHByZXNzaW9uLlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0gc29tZXRoaW5nIFRoZSBvYmplY3QgdG8gd3JhcCBpbiBhIENvbnN0YW50IGV4cHJlc3Npb25cbiAqIEByZXR1cm5zIEVpdGhlciB0aGUgb3JpZ2luYWwgb2JqZWN0IG9yIHRoZSB3cmFwcGVkIG9uZSBkZXBlbmRpbmcgb24gdGhlIGNhc2VcbiAqL1xuZnVuY3Rpb24gd3JhcFByaW1pdGl2ZTxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oc29tZXRoaW5nOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4ge1xuXHRpZiAoaXNFeHByZXNzaW9uKHNvbWV0aGluZykpIHtcblx0XHRyZXR1cm4gc29tZXRoaW5nO1xuXHR9XG5cblx0cmV0dXJuIGNvbnN0YW50KHNvbWV0aGluZyk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBleHByZXNzaW9uIG9yIHZhbHVlIHByb3ZpZGVkIGlzIGNvbnN0YW50IG9yIG5vdC5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSAgbWF5YmVDb25zdGFudCBUaGUgZXhwcmVzc2lvbiBvciBwcmltaXRpdmUgdmFsdWUgdGhhdCBpcyB0byBiZSBjaGVja2VkXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgaXQgaXMgY29uc3RhbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ29uc3RhbnQ8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KG1heWJlQ29uc3RhbnQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPik6IG1heWJlQ29uc3RhbnQgaXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIHR5cGVvZiBtYXliZUNvbnN0YW50ICE9PSBcIm9iamVjdFwiIHx8IChtYXliZUNvbnN0YW50IGFzIEJhc2VFeHByZXNzaW9uPFQ+KS5fdHlwZSA9PT0gXCJDb25zdGFudFwiO1xufVxuXG5mdW5jdGlvbiBpc1RydWUoZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KSB7XG5cdHJldHVybiBpc0NvbnN0YW50KGV4cHJlc3Npb24pICYmIGV4cHJlc3Npb24udmFsdWUgPT09IHRydWU7XG59XG5cbmZ1bmN0aW9uIGlzRmFsc2UoZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KSB7XG5cdHJldHVybiBpc0NvbnN0YW50KGV4cHJlc3Npb24pICYmIGV4cHJlc3Npb24udmFsdWUgPT09IGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBhIHBhdGggaW4gbW9kZWwgZXhwcmVzc2lvbiBvciBub3QuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gIG1heWJlQmluZGluZyBUaGUgZXhwcmVzc2lvbiBvciBwcmltaXRpdmUgdmFsdWUgdGhhdCBpcyB0byBiZSBjaGVja2VkXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgaXQgaXMgYSBwYXRoIGluIG1vZGVsIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUGF0aEluTW9kZWxFeHByZXNzaW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0bWF5YmVCaW5kaW5nOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IG1heWJlQmluZGluZyBpcyBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4ge1xuXHRyZXR1cm4gdHlwZW9mIG1heWJlQmluZGluZyA9PT0gXCJvYmplY3RcIiAmJiAobWF5YmVCaW5kaW5nIGFzIEJhc2VFeHByZXNzaW9uPFQ+KS5fdHlwZSA9PT0gXCJQYXRoSW5Nb2RlbFwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBhIGNvbXBsZXggdHlwZSBleHByZXNzaW9uLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtICBtYXliZUJpbmRpbmcgVGhlIGV4cHJlc3Npb24gb3IgcHJpbWl0aXZlIHZhbHVlIHRoYXQgaXMgdG8gYmUgY2hlY2tlZFxuICogQHJldHVybnMgYHRydWVgIGlmIGl0IGlzIGEgcGF0aCBpbiBtb2RlbCBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdG1heWJlQmluZGluZzogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBtYXliZUJpbmRpbmcgaXMgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIHR5cGVvZiBtYXliZUJpbmRpbmcgPT09IFwib2JqZWN0XCIgJiYgKG1heWJlQmluZGluZyBhcyBCYXNlRXhwcmVzc2lvbjxUPikuX3R5cGUgPT09IFwiQ29tcGxleFR5cGVcIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gcHJvdmlkZWQgaXMgYSBjb21wYXJpc29uIG9yIG5vdC5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGV4cHJlc3Npb24gaXMgYSBDb21wYXJpc29uRXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBpc0NvbXBhcmlzb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPik6IGV4cHJlc3Npb24gaXMgQ29tcGFyaXNvbkV4cHJlc3Npb24ge1xuXHRyZXR1cm4gZXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJDb21wYXJpc29uXCI7XG59XG5cbnR5cGUgQ29tcGxleEFubm90YXRpb25FeHByZXNzaW9uPFA+ID1cblx0fCBQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgSWZBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IE9yQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBBbmRBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IE5lQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBFcUFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgTm90QW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBHdEFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgR2VBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IExlQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBMdEFubm90YXRpb25FeHByZXNzaW9uPFA+O1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZU9iamVjdChvYmplY3RUeXBlOiBvYmplY3QpOiBib29sZWFuIHtcblx0c3dpdGNoIChvYmplY3RUeXBlLmNvbnN0cnVjdG9yLm5hbWUpIHtcblx0XHRjYXNlIFwiU3RyaW5nXCI6XG5cdFx0Y2FzZSBcIk51bWJlclwiOlxuXHRcdGNhc2UgXCJCb29sZWFuXCI6XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG4vKipcbiAqIENoZWNrIGlmIHRoZSBwYXNzZWQgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWUgaXMgYSBDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb24uXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gIGFubm90YXRpb25WYWx1ZSBUaGUgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWUgdG8gZXZhbHVhdGVcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0IGlzIGEge0NvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbn1cbiAqL1xuZnVuY3Rpb24gaXNDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb248VD4oYW5ub3RhdGlvblZhbHVlOiBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxUPik6IGFubm90YXRpb25WYWx1ZSBpcyBDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb248VD4ge1xuXHRyZXR1cm4gdHlwZW9mIGFubm90YXRpb25WYWx1ZSA9PT0gXCJvYmplY3RcIiAmJiAhaXNQcmltaXRpdmVPYmplY3QoYW5ub3RhdGlvblZhbHVlIGFzIG9iamVjdCk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgdGhlIGNvcnJlc3BvbmRpbmcgYW5ub3RhdGlvblZhbHVlIGZvciBhIGdpdmVuIGFubm90YXRpb24gYW5ub3RhdGlvblZhbHVlLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGFubm90YXRpb25WYWx1ZSBUaGUgc291cmNlIGFubm90YXRpb24gYW5ub3RhdGlvblZhbHVlXG4gKiBAcGFyYW0gdmlzaXRlZE5hdmlnYXRpb25QYXRocyBUaGUgcGF0aCBmcm9tIHRoZSByb290IGVudGl0eSBzZXRcbiAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgRGVmYXVsdCB2YWx1ZSBpZiB0aGUgYW5ub3RhdGlvblZhbHVlIGlzIHVuZGVmaW5lZFxuICogQHBhcmFtIHBhdGhWaXNpdG9yIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgVGhlIGFubm90YXRpb25WYWx1ZSBlcXVpdmFsZW50IHRvIHRoYXQgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWVcbiAqIEBkZXByZWNhdGVkIHVzZSBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24gaW5zdGVhZFxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5ub3RhdGlvbkV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRhbm5vdGF0aW9uVmFsdWU6IFByb3BlcnR5QW5ub3RhdGlvblZhbHVlPFQ+LFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRkZWZhdWx0VmFsdWU/OiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHBhdGhWaXNpdG9yPzogRnVuY3Rpb25cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj4ge1xuXHRyZXR1cm4gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKGFubm90YXRpb25WYWx1ZSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgZGVmYXVsdFZhbHVlLCBwYXRoVmlzaXRvcik7XG59XG4vKipcbiAqIEdlbmVyYXRlIHRoZSBjb3JyZXNwb25kaW5nIGFubm90YXRpb25WYWx1ZSBmb3IgYSBnaXZlbiBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBhbm5vdGF0aW9uVmFsdWUgVGhlIHNvdXJjZSBhbm5vdGF0aW9uIGFubm90YXRpb25WYWx1ZVxuICogQHBhcmFtIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMgVGhlIHBhdGggZnJvbSB0aGUgcm9vdCBlbnRpdHkgc2V0XG4gKiBAcGFyYW0gZGVmYXVsdFZhbHVlIERlZmF1bHQgdmFsdWUgaWYgdGhlIGFubm90YXRpb25WYWx1ZSBpcyB1bmRlZmluZWRcbiAqIEBwYXJhbSBwYXRoVmlzaXRvciBBIGZ1bmN0aW9uIHRvIG1vZGlmeSB0aGUgcmVzdWx0aW5nIHBhdGhcbiAqIEByZXR1cm5zIFRoZSBhbm5vdGF0aW9uVmFsdWUgZXF1aXZhbGVudCB0byB0aGF0IGFubm90YXRpb24gYW5ub3RhdGlvblZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRhbm5vdGF0aW9uVmFsdWU6IFByb3BlcnR5QW5ub3RhdGlvblZhbHVlPFQ+LFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRkZWZhdWx0VmFsdWU/OiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHBhdGhWaXNpdG9yPzogRnVuY3Rpb25cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj4ge1xuXHRpZiAoYW5ub3RhdGlvblZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gd3JhcFByaW1pdGl2ZShkZWZhdWx0VmFsdWUgYXMgVCk7XG5cdH1cblx0YW5ub3RhdGlvblZhbHVlID0gYW5ub3RhdGlvblZhbHVlPy52YWx1ZU9mKCkgYXMgUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8VD47XG5cdGlmICghaXNDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb24oYW5ub3RhdGlvblZhbHVlKSkge1xuXHRcdHJldHVybiBjb25zdGFudChhbm5vdGF0aW9uVmFsdWUpO1xuXHR9XG5cblx0c3dpdGNoIChhbm5vdGF0aW9uVmFsdWUudHlwZSkge1xuXHRcdGNhc2UgXCJQYXRoXCI6XG5cdFx0XHRyZXR1cm4gcGF0aEluTW9kZWwoYW5ub3RhdGlvblZhbHVlLnBhdGgsIHVuZGVmaW5lZCwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdGNhc2UgXCJJZlwiOlxuXHRcdFx0cmV0dXJuIGFubm90YXRpb25JZkV4cHJlc3Npb24oYW5ub3RhdGlvblZhbHVlLklmLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0Y2FzZSBcIk5vdFwiOlxuXHRcdFx0cmV0dXJuIG5vdChwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLk5vdCwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0Y2FzZSBcIkVxXCI6XG5cdFx0XHRyZXR1cm4gZXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuRXFbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5FcVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0XHRjYXNlIFwiTmVcIjpcblx0XHRcdHJldHVybiBub3RFcXVhbChcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5OZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLk5lWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRcdGNhc2UgXCJHdFwiOlxuXHRcdFx0cmV0dXJuIGdyZWF0ZXJUaGFuKFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkd0WzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuR3RbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0Y2FzZSBcIkdlXCI6XG5cdFx0XHRyZXR1cm4gZ3JlYXRlck9yRXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuR2VbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5HZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0XHRjYXNlIFwiTHRcIjpcblx0XHRcdHJldHVybiBsZXNzVGhhbihcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5MdFswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkx0WzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRcdGNhc2UgXCJMZVwiOlxuXHRcdFx0cmV0dXJuIGxlc3NPckVxdWFsKFxuXHRcdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlLkxlWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuTGVbMV0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHRcdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0Y2FzZSBcIk9yXCI6XG5cdFx0XHRyZXR1cm4gb3IoXG5cdFx0XHRcdC4uLmFubm90YXRpb25WYWx1ZS5Pci5tYXAoZnVuY3Rpb24gKG9yQ29uZGl0aW9uKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbjxib29sZWFuPihvckNvbmRpdGlvbiwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0Y2FzZSBcIkFuZFwiOlxuXHRcdFx0cmV0dXJuIGFuZChcblx0XHRcdFx0Li4uYW5ub3RhdGlvblZhbHVlLkFuZC5tYXAoZnVuY3Rpb24gKGFuZENvbmRpdGlvbikge1xuXHRcdFx0XHRcdHJldHVybiBwYXJzZUFubm90YXRpb25Db25kaXRpb248Ym9vbGVhbj4oYW5kQ29uZGl0aW9uLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0XHRcdH0pXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0XHRjYXNlIFwiQXBwbHlcIjpcblx0XHRcdHJldHVybiBhbm5vdGF0aW9uQXBwbHlFeHByZXNzaW9uKFxuXHRcdFx0XHRhbm5vdGF0aW9uVmFsdWUgYXMgQXBwbHlBbm5vdGF0aW9uRXhwcmVzc2lvbjxzdHJpbmc+LFxuXHRcdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0XHRwYXRoVmlzaXRvclxuXHRcdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH1cblx0cmV0dXJuIHVucmVzb2x2ZWFibGVFeHByZXNzaW9uO1xufVxuXG4vKipcbiAqIFBhcnNlIHRoZSBhbm5vdGF0aW9uIGNvbmRpdGlvbiBpbnRvIGFuIGV4cHJlc3Npb24uXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gYW5ub3RhdGlvblZhbHVlIFRoZSBjb25kaXRpb24gb3IgdmFsdWUgZnJvbSB0aGUgYW5ub3RhdGlvblxuICogQHBhcmFtIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMgVGhlIHBhdGggZnJvbSB0aGUgcm9vdCBlbnRpdHkgc2V0XG4gKiBAcGFyYW0gcGF0aFZpc2l0b3IgQSBmdW5jdGlvbiB0byBtb2RpZnkgdGhlIHJlc3VsdGluZyBwYXRoXG4gKiBAcmV0dXJucyBBbiBlcXVpdmFsZW50IGV4cHJlc3Npb25cbiAqL1xuZnVuY3Rpb24gcGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0YW5ub3RhdGlvblZhbHVlOiBDb25kaXRpb25hbENoZWNrT3JWYWx1ZSxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHtcblx0aWYgKGFubm90YXRpb25WYWx1ZSA9PT0gbnVsbCB8fCB0eXBlb2YgYW5ub3RhdGlvblZhbHVlICE9PSBcIm9iamVjdFwiKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGFubm90YXRpb25WYWx1ZSBhcyBUKTtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkT3JcIikpIHtcblx0XHRyZXR1cm4gb3IoXG5cdFx0XHQuLi4oKGFubm90YXRpb25WYWx1ZSBhcyBPckNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJE9yLm1hcChmdW5jdGlvbiAob3JDb25kaXRpb24pIHtcblx0XHRcdFx0cmV0dXJuIHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihvckNvbmRpdGlvbiwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdFx0fSkgYXMgdW5rbm93biBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj5bXSlcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkQW5kXCIpKSB7XG5cdFx0cmV0dXJuIGFuZChcblx0XHRcdC4uLigoYW5ub3RhdGlvblZhbHVlIGFzIEFuZENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEFuZC5tYXAoZnVuY3Rpb24gKGFuZENvbmRpdGlvbikge1xuXHRcdFx0XHRyZXR1cm4gcGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFuZENvbmRpdGlvbiwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdFx0fSkgYXMgdW5rbm93biBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj5bXSlcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkTm90XCIpKSB7XG5cdFx0cmV0dXJuIG5vdChcblx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbigoYW5ub3RhdGlvblZhbHVlIGFzIE5vdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJE5vdCwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEVxXCIpKSB7XG5cdFx0cmV0dXJuIGVxdWFsKFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgRXFDb25kaXRpb25hbEV4cHJlc3Npb24pLiRFcVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgRXFDb25kaXRpb25hbEV4cHJlc3Npb24pLiRFcVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJE5lXCIpKSB7XG5cdFx0cmV0dXJuIG5vdEVxdWFsKFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgTmVDb25kaXRpb25hbEV4cHJlc3Npb24pLiROZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgTmVDb25kaXRpb25hbEV4cHJlc3Npb24pLiROZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEd0XCIpKSB7XG5cdFx0cmV0dXJuIGdyZWF0ZXJUaGFuKFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgR3RDb25kaXRpb25hbEV4cHJlc3Npb24pLiRHdFswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgR3RDb25kaXRpb25hbEV4cHJlc3Npb24pLiRHdFsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEdlXCIpKSB7XG5cdFx0cmV0dXJuIGdyZWF0ZXJPckVxdWFsKFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgR2VDb25kaXRpb25hbEV4cHJlc3Npb24pLiRHZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgR2VDb25kaXRpb25hbEV4cHJlc3Npb24pLiRHZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEx0XCIpKSB7XG5cdFx0cmV0dXJuIGxlc3NUaGFuKFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgTHRDb25kaXRpb25hbEV4cHJlc3Npb24pLiRMdFswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgTHRDb25kaXRpb25hbEV4cHJlc3Npb24pLiRMdFsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJExlXCIpKSB7XG5cdFx0cmV0dXJuIGxlc3NPckVxdWFsKFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgTGVDb25kaXRpb25hbEV4cHJlc3Npb24pLiRMZVswXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgTGVDb25kaXRpb25hbEV4cHJlc3Npb24pLiRMZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJFBhdGhcIikpIHtcblx0XHRyZXR1cm4gcGF0aEluTW9kZWwoKGFubm90YXRpb25WYWx1ZSBhcyBQYXRoQ29uZGl0aW9uRXhwcmVzc2lvbjxUPikuJFBhdGgsIHVuZGVmaW5lZCwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRBcHBseVwiKSkge1xuXHRcdHJldHVybiBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24oXG5cdFx0XHR7XG5cdFx0XHRcdHR5cGU6IFwiQXBwbHlcIixcblx0XHRcdFx0RnVuY3Rpb246IChhbm5vdGF0aW9uVmFsdWUgYXMgYW55KS4kRnVuY3Rpb24sXG5cdFx0XHRcdEFwcGx5OiAoYW5ub3RhdGlvblZhbHVlIGFzIGFueSkuJEFwcGx5XG5cdFx0XHR9IGFzIFQsXG5cdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0cGF0aFZpc2l0b3Jcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkSWZcIikpIHtcblx0XHRyZXR1cm4gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKFxuXHRcdFx0e1xuXHRcdFx0XHR0eXBlOiBcIklmXCIsXG5cdFx0XHRcdElmOiAoYW5ub3RhdGlvblZhbHVlIGFzIGFueSkuJElmXG5cdFx0XHR9IGFzIFQsXG5cdFx0XHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzLFxuXHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0cGF0aFZpc2l0b3Jcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkRW51bU1lbWJlclwiKSkge1xuXHRcdHJldHVybiBjb25zdGFudChyZXNvbHZlRW51bVZhbHVlKChhbm5vdGF0aW9uVmFsdWUgYXMgYW55KS4kRW51bU1lbWJlcikgYXMgVCk7XG5cdH1cblx0cmV0dXJuIGNvbnN0YW50KGZhbHNlIGFzIFQpO1xufVxuXG4vKipcbiAqIFByb2Nlc3MgdGhlIHtJZkFubm90YXRpb25FeHByZXNzaW9uVmFsdWV9IGludG8gYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBhbm5vdGF0aW9uVmFsdWUgQW4gSWYgZXhwcmVzc2lvbiByZXR1cm5pbmcgdGhlIHR5cGUgVFxuICogQHBhcmFtIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMgVGhlIHBhdGggZnJvbSB0aGUgcm9vdCBlbnRpdHkgc2V0XG4gKiBAcGFyYW0gcGF0aFZpc2l0b3IgQSBmdW5jdGlvbiB0byBtb2RpZnkgdGhlIHJlc3VsdGluZyBwYXRoXG4gKiBAcmV0dXJucyBUaGUgZXF1aXZhbGVudCBpZkVsc2UgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5ub3RhdGlvbklmRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGFubm90YXRpb25WYWx1ZTogSWZBbm5vdGF0aW9uRXhwcmVzc2lvblZhbHVlPFQ+LFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4ge1xuXHRyZXR1cm4gaWZFbHNlKFxuXHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlWzFdIGFzIGFueSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWVbMl0gYXMgYW55LCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFubm90YXRpb25BcHBseUV4cHJlc3Npb24oXG5cdGFwcGx5RXhwcmVzc2lvbjogQXBwbHlBbm5vdGF0aW9uRXhwcmVzc2lvbjxzdHJpbmc+LFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPiB7XG5cdHN3aXRjaCAoYXBwbHlFeHByZXNzaW9uLkZ1bmN0aW9uKSB7XG5cdFx0Y2FzZSBcIm9kYXRhLmNvbmNhdFwiOlxuXHRcdFx0cmV0dXJuIGNvbmNhdChcblx0XHRcdFx0Li4uYXBwbHlFeHByZXNzaW9uLkFwcGx5Lm1hcCgoYXBwbHlQYXJhbTogYW55KSA9PiB7XG5cdFx0XHRcdFx0bGV0IGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSBhcHBseVBhcmFtO1xuXHRcdFx0XHRcdGlmIChhcHBseVBhcmFtLmhhc093blByb3BlcnR5KFwiJFBhdGhcIikpIHtcblx0XHRcdFx0XHRcdGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSB7XG5cdFx0XHRcdFx0XHRcdHR5cGU6IFwiUGF0aFwiLFxuXHRcdFx0XHRcdFx0XHRwYXRoOiBhcHBseVBhcmFtLiRQYXRoXG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoYXBwbHlQYXJhbS5oYXNPd25Qcm9wZXJ0eShcIiRJZlwiKSkge1xuXHRcdFx0XHRcdFx0YXBwbHlQYXJhbUNvbnZlcnRlZCA9IHtcblx0XHRcdFx0XHRcdFx0dHlwZTogXCJJZlwiLFxuXHRcdFx0XHRcdFx0XHRJZjogYXBwbHlQYXJhbS4kSWZcblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChhcHBseVBhcmFtLmhhc093blByb3BlcnR5KFwiJEFwcGx5XCIpKSB7XG5cdFx0XHRcdFx0XHRhcHBseVBhcmFtQ29udmVydGVkID0ge1xuXHRcdFx0XHRcdFx0XHR0eXBlOiBcIkFwcGx5XCIsXG5cdFx0XHRcdFx0XHRcdEZ1bmN0aW9uOiBhcHBseVBhcmFtLiRGdW5jdGlvbixcblx0XHRcdFx0XHRcdFx0QXBwbHk6IGFwcGx5UGFyYW0uJEFwcGx5XG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gZ2V0RXhwcmVzc2lvbkZyb21Bbm5vdGF0aW9uKGFwcGx5UGFyYW1Db252ZXJ0ZWQsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHVuZGVmaW5lZCwgcGF0aFZpc2l0b3IpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KTtcblx0fVxuXHRyZXR1cm4gdW5yZXNvbHZlYWJsZUV4cHJlc3Npb247XG59XG5cbi8qKlxuICogR2VuZXJpYyBoZWxwZXIgZm9yIHRoZSBjb21wYXJpc29uIG9wZXJhdGlvbnMgKGVxdWFsLCBub3RFcXVhbCwgLi4uKS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBvcGVyYXRvciBUaGUgb3BlcmF0b3IgdG8gYXBwbHlcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlIG9mIHRoZSBvcGVyYXRvclxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgb3BlcmF0b3JcbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmlzb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0Y29uc3QgbGVmdEV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKGxlZnRPcGVyYW5kKTtcblx0Y29uc3QgcmlnaHRFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShyaWdodE9wZXJhbmQpO1xuXHRpZiAoaGFzVW5yZXNvbHZlYWJsZUV4cHJlc3Npb24obGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZlYWJsZUV4cHJlc3Npb247XG5cdH1cblx0aWYgKGlzQ29uc3RhbnQobGVmdEV4cHJlc3Npb24pICYmIGlzQ29uc3RhbnQocmlnaHRFeHByZXNzaW9uKSkge1xuXHRcdHN3aXRjaCAob3BlcmF0b3IpIHtcblx0XHRcdGNhc2UgXCIhPT1cIjpcblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlICE9PSByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIjxcIjpcblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlIDwgcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHRcdGNhc2UgXCI8PVwiOlxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPD0gcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHRcdGNhc2UgXCI+XCI6XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA+IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPj1cIjpcblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlID49IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPT09XCI6XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIkNvbXBhcmlzb25cIixcblx0XHRcdG9wZXJhdG9yOiBvcGVyYXRvcixcblx0XHRcdG9wZXJhbmQxOiBsZWZ0RXhwcmVzc2lvbixcblx0XHRcdG9wZXJhbmQyOiByaWdodEV4cHJlc3Npb25cblx0XHR9O1xuXHR9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsZW5ndGgoZXhwcmVzc2lvbjogUGF0aEluTW9kZWxFeHByZXNzaW9uPGFueT4gfCBVbnJlc29sdmVhYmxlUGF0aEV4cHJlc3Npb24pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248bnVtYmVyPiB7XG5cdGlmIChleHByZXNzaW9uLl90eXBlID09PSBcIlVucmVzb2x2YWJsZVwiKSB7XG5cdFx0cmV0dXJuIGV4cHJlc3Npb247XG5cdH1cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJMZW5ndGhcIixcblx0XHRwYXRoSW5Nb2RlbDogZXhwcmVzc2lvblxuXHR9O1xufVxuXG4vKipcbiAqIENvbXBhcmlzb246IFwiZXF1YWxcIiAoPT09KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZXF1YWw8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0Y29uc3QgbGVmdEV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKGxlZnRPcGVyYW5kKTtcblx0Y29uc3QgcmlnaHRFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShyaWdodE9wZXJhbmQpO1xuXHRpZiAoaGFzVW5yZXNvbHZlYWJsZUV4cHJlc3Npb24obGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZlYWJsZUV4cHJlc3Npb247XG5cdH1cblx0aWYgKF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwobGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodHJ1ZSk7XG5cdH1cblxuXHRmdW5jdGlvbiByZWR1Y2UobGVmdDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LCByaWdodDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+KSB7XG5cdFx0aWYgKGxlZnQuX3R5cGUgPT09IFwiQ29tcGFyaXNvblwiICYmIGlzVHJ1ZShyaWdodCkpIHtcblx0XHRcdC8vIGNvbXBhcmUoYSwgYikgPT09IHRydWUgfn4+IGNvbXBhcmUoYSwgYilcblx0XHRcdHJldHVybiBsZWZ0O1xuXHRcdH0gZWxzZSBpZiAobGVmdC5fdHlwZSA9PT0gXCJDb21wYXJpc29uXCIgJiYgaXNGYWxzZShyaWdodCkpIHtcblx0XHRcdC8vIGNvbXBhcmUoYSwgYikgPT09IGZhbHNlIH5+PiAhY29tcGFyZShhLCBiKVxuXHRcdFx0cmV0dXJuIG5vdChsZWZ0KTtcblx0XHR9IGVsc2UgaWYgKGxlZnQuX3R5cGUgPT09IFwiSWZFbHNlXCIgJiYgX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChsZWZ0Lm9uVHJ1ZSwgcmlnaHQpKSB7XG5cdFx0XHQvLyAoaWYgKHgpIHsgYSB9IGVsc2UgeyBiIH0pID09PSBhIH5+PiB4IHx8IChiID09PSBhKVxuXHRcdFx0cmV0dXJuIG9yKGxlZnQuY29uZGl0aW9uLCBlcXVhbChsZWZ0Lm9uRmFsc2UsIHJpZ2h0KSk7XG5cdFx0fSBlbHNlIGlmIChsZWZ0Ll90eXBlID09PSBcIklmRWxzZVwiICYmIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwobGVmdC5vbkZhbHNlLCByaWdodCkpIHtcblx0XHRcdC8vIChpZiAoeCkgeyBhIH0gZWxzZSB7IGIgfSkgPT09IGIgfn4+ICF4IHx8IChhID09PSBiKVxuXHRcdFx0cmV0dXJuIG9yKG5vdChsZWZ0LmNvbmRpdGlvbiksIGVxdWFsKGxlZnQub25UcnVlLCByaWdodCkpO1xuXHRcdH0gZWxzZSBpZiAoXG5cdFx0XHRsZWZ0Ll90eXBlID09PSBcIklmRWxzZVwiICYmXG5cdFx0XHRpc0NvbnN0YW50KGxlZnQub25UcnVlKSAmJlxuXHRcdFx0aXNDb25zdGFudChsZWZ0Lm9uRmFsc2UpICYmXG5cdFx0XHRpc0NvbnN0YW50KHJpZ2h0KSAmJlxuXHRcdFx0IV9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwobGVmdC5vblRydWUsIHJpZ2h0KSAmJlxuXHRcdFx0IV9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwobGVmdC5vbkZhbHNlLCByaWdodClcblx0XHQpIHtcblx0XHRcdHJldHVybiBjb25zdGFudChmYWxzZSk7XG5cdFx0fVxuXHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdH1cblxuXHQvLyBleHBsb2l0IHN5bW1ldHJ5OiBhID09PSBiIDx+PiBiID09PSBhXG5cdGNvbnN0IHJlZHVjZWQgPSByZWR1Y2UobGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikgPz8gcmVkdWNlKHJpZ2h0RXhwcmVzc2lvbiwgbGVmdEV4cHJlc3Npb24pO1xuXHRyZXR1cm4gcmVkdWNlZCA/PyBjb21wYXJpc29uKFwiPT09XCIsIGxlZnRFeHByZXNzaW9uLCByaWdodEV4cHJlc3Npb24pO1xufVxuXG4vKipcbiAqIENvbXBhcmlzb246IFwibm90IGVxdWFsXCIgKCE9PSkuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZVxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgY29tcGFyaXNvblxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vdEVxdWFsPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBub3QoZXF1YWwobGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCkpO1xufVxuXG4vKipcbiAqIENvbXBhcmlzb246IFwiZ3JlYXRlciBvciBlcXVhbFwiICg+PSkuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZVxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgY29tcGFyaXNvblxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyZWF0ZXJPckVxdWFsPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPj1cIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJncmVhdGVyIHRoYW5cIiAoPikuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZVxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgY29tcGFyaXNvblxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPlwiLCBsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKTtcbn1cblxuLyoqXG4gKiBDb21wYXJpc29uOiBcImxlc3Mgb3IgZXF1YWxcIiAoPD0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsZXNzT3JFcXVhbDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRyZXR1cm4gY29tcGFyaXNvbihcIjw9XCIsIGxlZnRPcGVyYW5kLCByaWdodE9wZXJhbmQpO1xufVxuXG4vKipcbiAqIENvbXBhcmlzb246IFwibGVzcyB0aGFuXCIgKDwpLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsZXNzVGhhbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRyZXR1cm4gY29tcGFyaXNvbihcIjxcIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogSWYtdGhlbi1lbHNlIGV4cHJlc3Npb24uXG4gKlxuICogRXZhbHVhdGVzIHRvIG9uVHJ1ZSBpZiB0aGUgY29uZGl0aW9uIGV2YWx1YXRlcyB0byB0cnVlLCBlbHNlIGV2YWx1YXRlcyB0byBvbkZhbHNlLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGNvbmRpdGlvbiBUaGUgY29uZGl0aW9uIHRvIGV2YWx1YXRlXG4gKiBAcGFyYW0gb25UcnVlIEV4cHJlc3Npb24gcmVzdWx0IGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIHRydWVcbiAqIEBwYXJhbSBvbkZhbHNlIEV4cHJlc3Npb24gcmVzdWx0IGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIGZhbHNlXG4gKiBAcmV0dXJucyBUaGUgZXhwcmVzc2lvbiB0aGF0IHJlcHJlc2VudHMgdGhpcyBjb25kaXRpb25hbCBjaGVja1xuICovXG5leHBvcnQgZnVuY3Rpb24gaWZFbHNlPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0Y29uZGl0aW9uOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8Ym9vbGVhbj4sXG5cdG9uVHJ1ZTogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRvbkZhbHNlOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGxldCBjb25kaXRpb25FeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShjb25kaXRpb24pO1xuXHRsZXQgb25UcnVlRXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUob25UcnVlKTtcblx0bGV0IG9uRmFsc2VFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShvbkZhbHNlKTtcblxuXHRpZiAoaGFzVW5yZXNvbHZlYWJsZUV4cHJlc3Npb24oY29uZGl0aW9uRXhwcmVzc2lvbiwgb25UcnVlRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2ZWFibGVFeHByZXNzaW9uO1xuXHR9XG5cdC8vIHN3YXAgYnJhbmNoZXMgaWYgdGhlIGNvbmRpdGlvbiBpcyBhIG5lZ2F0aW9uXG5cdGlmIChjb25kaXRpb25FeHByZXNzaW9uLl90eXBlID09PSBcIk5vdFwiKSB7XG5cdFx0Ly8gaWZFbHNlKG5vdChYKSwgYSwgYikgLS0+IGlmRWxzZShYLCBiLCBhKVxuXHRcdFtvblRydWVFeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbl0gPSBbb25GYWxzZUV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb25dO1xuXHRcdGNvbmRpdGlvbkV4cHJlc3Npb24gPSBub3QoY29uZGl0aW9uRXhwcmVzc2lvbik7XG5cdH1cblxuXHQvLyBpbmxpbmUgbmVzdGVkIGlmLWVsc2UgZXhwcmVzc2lvbnM6IG9uVHJ1ZSBicmFuY2hcblx0Ly8gaWZFbHNlKFgsIGlmRWxzZShYLCBhLCBiKSwgYykgPT0+IGlmRWxzZShYLCBhLCBjKVxuXHRpZiAob25UcnVlRXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb24uY29uZGl0aW9uKSkge1xuXHRcdG9uVHJ1ZUV4cHJlc3Npb24gPSBvblRydWVFeHByZXNzaW9uLm9uVHJ1ZTtcblx0fVxuXG5cdC8vIGlubGluZSBuZXN0ZWQgaWYtZWxzZSBleHByZXNzaW9uczogb25GYWxzZSBicmFuY2hcblx0Ly8gaWZFbHNlKFgsIGEsIGlmRWxzZShYLCBiLCBjKSkgPT0+IGlmRWxzZShYLCBhLCBjKVxuXHRpZiAob25GYWxzZUV4cHJlc3Npb24uX3R5cGUgPT09IFwiSWZFbHNlXCIgJiYgX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChjb25kaXRpb25FeHByZXNzaW9uLCBvbkZhbHNlRXhwcmVzc2lvbi5jb25kaXRpb24pKSB7XG5cdFx0b25GYWxzZUV4cHJlc3Npb24gPSBvbkZhbHNlRXhwcmVzc2lvbi5vbkZhbHNlO1xuXHR9XG5cblx0Ly8gKGlmIHRydWUgdGhlbiBhIGVsc2UgYikgIH5+PiBhXG5cdC8vIChpZiBmYWxzZSB0aGVuIGEgZWxzZSBiKSB+fj4gYlxuXHRpZiAoaXNDb25zdGFudChjb25kaXRpb25FeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBjb25kaXRpb25FeHByZXNzaW9uLnZhbHVlID8gb25UcnVlRXhwcmVzc2lvbiA6IG9uRmFsc2VFeHByZXNzaW9uO1xuXHR9XG5cblx0Ly8gaWYgKGlzQ29uc3RhbnRCb29sZWFuKG9uVHJ1ZUV4cHJlc3Npb24pIHx8IGlzQ29uc3RhbnRCb29sZWFuKG9uRmFsc2VFeHByZXNzaW9uKSkge1xuXHQvLyBcdHJldHVybiBvcihhbmQoY29uZGl0aW9uLCBvblRydWVFeHByZXNzaW9uIGFzIEV4cHJlc3Npb248Ym9vbGVhbj4pLCBhbmQobm90KGNvbmRpdGlvbiksIG9uRmFsc2VFeHByZXNzaW9uIGFzIEV4cHJlc3Npb248Ym9vbGVhbj4pKSBhcyBFeHByZXNzaW9uPFQ+XG5cdC8vIH1cblx0Ly8gKGlmIFggdGhlbiBhIGVsc2UgYSkgfn4+IGFcblx0aWYgKF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwob25UcnVlRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIG9uVHJ1ZUV4cHJlc3Npb247XG5cdH1cblxuXHQvLyBpZiBYIHRoZW4gYSBlbHNlIGZhbHNlIH5+PiBYICYmIGFcblx0aWYgKGlzRmFsc2Uob25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIGFuZChjb25kaXRpb25FeHByZXNzaW9uLCBvblRydWVFeHByZXNzaW9uIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPikgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9XG5cblx0Ly8gaWYgWCB0aGVuIGEgZWxzZSB0cnVlIH5+PiAhWCB8fCBhXG5cdGlmIChpc1RydWUob25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIG9yKG5vdChjb25kaXRpb25FeHByZXNzaW9uKSwgb25UcnVlRXhwcmVzc2lvbiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4pIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiBmYWxzZSBlbHNlIGEgfn4+ICFYICYmIGFcblx0aWYgKGlzRmFsc2Uob25UcnVlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gYW5kKG5vdChjb25kaXRpb25FeHByZXNzaW9uKSwgb25GYWxzZUV4cHJlc3Npb24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH1cblxuXHQvLyBpZiBYIHRoZW4gdHJ1ZSBlbHNlIGEgfn4+IFggfHwgYVxuXHRpZiAoaXNUcnVlKG9uVHJ1ZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIG9yKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uRmFsc2VFeHByZXNzaW9uIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPikgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9XG5cdGlmIChpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbihjb25kaXRpb24pIHx8IGlzQ29tcGxleFR5cGVFeHByZXNzaW9uKG9uVHJ1ZSkgfHwgaXNDb21wbGV4VHlwZUV4cHJlc3Npb24ob25GYWxzZSkpIHtcblx0XHRsZXQgcGF0aElkeCA9IDA7XG5cdFx0Y29uc3QgbXlJZkVsc2VFeHByZXNzaW9uID0gZm9ybWF0UmVzdWx0KFtjb25kaXRpb24sIG9uVHJ1ZSwgb25GYWxzZV0sIFwic2FwLmZlLmNvcmUuZm9ybWF0dGVycy5TdGFuZGFyZEZvcm1hdHRlciNpZkVsc2VcIik7XG5cdFx0Y29uc3QgYWxsUGFydHMgPSBbXTtcblx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdG15SWZFbHNlRXhwcmVzc2lvbixcblx0XHRcdFwiUGF0aEluTW9kZWxcIixcblx0XHRcdChjb25zdGFudFBhdGg6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxhbnk+KSA9PiB7XG5cdFx0XHRcdGFsbFBhcnRzLnB1c2goY29uc3RhbnRQYXRoKTtcblx0XHRcdFx0cmV0dXJuIHBhdGhJbk1vZGVsKGBcXCQke3BhdGhJZHgrK31gLCBcIiRcIik7XG5cdFx0XHR9LFxuXHRcdFx0dHJ1ZVxuXHRcdCk7XG5cdFx0YWxsUGFydHMudW5zaGlmdChjb25zdGFudChKU09OLnN0cmluZ2lmeShteUlmRWxzZUV4cHJlc3Npb24pKSk7XG5cdFx0cmV0dXJuIGZvcm1hdFJlc3VsdChhbGxQYXJ0cywgXCJzYXAuZmUuY29yZS5mb3JtYXR0ZXJzLlN0YW5kYXJkRm9ybWF0dGVyI2V2YWx1YXRlQ29tcGxleEV4cHJlc3Npb25cIik7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJJZkVsc2VcIixcblx0XHRjb25kaXRpb246IGNvbmRpdGlvbkV4cHJlc3Npb24sXG5cdFx0b25UcnVlOiBvblRydWVFeHByZXNzaW9uLFxuXHRcdG9uRmFsc2U6IG9uRmFsc2VFeHByZXNzaW9uXG5cdH07XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGN1cnJlbnQgZXhwcmVzc2lvbiBoYXMgYSByZWZlcmVuY2UgdG8gdGhlIGRlZmF1bHQgbW9kZWwgKHVuZGVmaW5lZCkuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gZXZhbHVhdGVcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGVyZSBpcyBhIHJlZmVyZW5jZSB0byB0aGUgZGVmYXVsdCBjb250ZXh0XG4gKi9cbmZ1bmN0aW9uIGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGFueT4pOiBib29sZWFuIHtcblx0c3dpdGNoIChleHByZXNzaW9uLl90eXBlKSB7XG5cdFx0Y2FzZSBcIkNvbnN0YW50XCI6XG5cdFx0Y2FzZSBcIkZvcm1hdHRlclwiOlxuXHRcdGNhc2UgXCJDb21wbGV4VHlwZVwiOlxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdGNhc2UgXCJTZXRcIjpcblx0XHRcdHJldHVybiBleHByZXNzaW9uLm9wZXJhbmRzLnNvbWUoaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dCk7XG5cdFx0Y2FzZSBcIlBhdGhJbk1vZGVsXCI6XG5cdFx0XHRyZXR1cm4gZXhwcmVzc2lvbi5tb2RlbE5hbWUgPT09IHVuZGVmaW5lZDtcblx0XHRjYXNlIFwiQ29tcGFyaXNvblwiOlxuXHRcdFx0cmV0dXJuIGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5vcGVyYW5kMSkgfHwgaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLm9wZXJhbmQyKTtcblx0XHRjYXNlIFwiSWZFbHNlXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24uY29uZGl0aW9uKSB8fFxuXHRcdFx0XHRoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24ub25UcnVlKSB8fFxuXHRcdFx0XHRoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24ub25GYWxzZSlcblx0XHRcdCk7XG5cdFx0Y2FzZSBcIk5vdFwiOlxuXHRcdGNhc2UgXCJUcnV0aHlcIjpcblx0XHRcdHJldHVybiBoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24ub3BlcmFuZCk7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG50eXBlIEZuPFQ+ID0gKCguLi5wYXJhbXM6IGFueSkgPT4gVCkgJiB7XG5cdF9fZnVuY3Rpb25OYW1lOiBzdHJpbmc7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIFdyYXBwZWRUdXBsZVxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4vLyBAdHMtaWdub3JlXG50eXBlIFdyYXBwZWRUdXBsZTxUPiA9IHsgW0sgaW4ga2V5b2YgVF06IFdyYXBwZWRUdXBsZTxUW0tdPiB8IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUW0tdPiB9O1xuXG4vLyBTbywgdGhpcyB3b3JrcyBidXQgSSBjYW5ub3QgZ2V0IGl0IHRvIGNvbXBpbGUgOkQsIGJ1dCBpdCBzdGlsbCBkb2VzIHdoYXQgaXMgZXhwZWN0ZWQuLi5cblxuLyoqXG4gKiBBIGZ1bmN0aW9uIHJlZmVyZW5jZSBvciBhIGZ1bmN0aW9uIG5hbWUuXG4gKi9cbnR5cGUgRnVuY3Rpb25Pck5hbWU8VD4gPSBGbjxUPiB8IHN0cmluZztcblxuLyoqXG4gKiBGdW5jdGlvbiBwYXJhbWV0ZXJzLCBlaXRoZXIgZGVyaXZlZCBmcm9tIHRoZSBmdW5jdGlvbiBvciBhbiB1bnR5cGVkIGFycmF5LlxuICovXG50eXBlIEZ1bmN0aW9uUGFyYW1ldGVyczxULCBGIGV4dGVuZHMgRnVuY3Rpb25Pck5hbWU8VD4+ID0gRiBleHRlbmRzIEZuPFQ+ID8gUGFyYW1ldGVyczxGPiA6IGFueVtdO1xuXG4vKipcbiAqIENhbGxzIGEgZm9ybWF0dGVyIGZ1bmN0aW9uIHRvIHByb2Nlc3MgdGhlIHBhcmFtZXRlcnMuXG4gKiBJZiByZXF1aXJlQ29udGV4dCBpcyBzZXQgdG8gdHJ1ZSBhbmQgbm8gY29udGV4dCBpcyBwYXNzZWQgYSBkZWZhdWx0IGNvbnRleHQgd2lsbCBiZSBhZGRlZCBhdXRvbWF0aWNhbGx5LlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdGVtcGxhdGUgVVxuICogQHBhcmFtIHBhcmFtZXRlcnMgVGhlIGxpc3Qgb2YgcGFyYW1ldGVyIHRoYXQgc2hvdWxkIG1hdGNoIHRoZSB0eXBlIGFuZCBudW1iZXIgb2YgdGhlIGZvcm1hdHRlciBmdW5jdGlvblxuICogQHBhcmFtIGZvcm1hdHRlckZ1bmN0aW9uIFRoZSBmdW5jdGlvbiB0byBjYWxsXG4gKiBAcGFyYW0gW2NvbnRleHRFbnRpdHlUeXBlXSBUaGUgY29udGV4dCBlbnRpdHkgdHlwZSB0byBjb25zaWRlclxuICogQHJldHVybnMgVGhlIGNvcnJlc3BvbmRpbmcgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0UmVzdWx0PFQsIFUgZXh0ZW5kcyBGbjxUPj4oXG5cdHBhcmFtZXRlcnM6IFdyYXBwZWRUdXBsZTxQYXJhbWV0ZXJzPFU+Pixcblx0Zm9ybWF0dGVyRnVuY3Rpb246IFUgfCBzdHJpbmcsXG5cdGNvbnRleHRFbnRpdHlUeXBlPzogRW50aXR5VHlwZVxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHtcblx0Y29uc3QgcGFyYW1ldGVyRXhwcmVzc2lvbnMgPSAocGFyYW1ldGVycyBhcyBhbnlbXSkubWFwKHdyYXBQcmltaXRpdmUpO1xuXG5cdGlmIChoYXNVbnJlc29sdmVhYmxlRXhwcmVzc2lvbiguLi5wYXJhbWV0ZXJFeHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZlYWJsZUV4cHJlc3Npb247XG5cdH1cblx0aWYgKGNvbnRleHRFbnRpdHlUeXBlKSB7XG5cdFx0Ly8gT3RoZXJ3aXNlLCBpZiB0aGUgY29udGV4dCBpcyByZXF1aXJlZCBhbmQgbm8gY29udGV4dCBpcyBwcm92aWRlZCBtYWtlIHN1cmUgdG8gYWRkIHRoZSBkZWZhdWx0IGJpbmRpbmdcblx0XHRpZiAoIXBhcmFtZXRlckV4cHJlc3Npb25zLnNvbWUoaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dCkpIHtcblx0XHRcdGNvbnRleHRFbnRpdHlUeXBlLmtleXMuZm9yRWFjaCgoa2V5KSA9PiBwYXJhbWV0ZXJFeHByZXNzaW9ucy5wdXNoKHBhdGhJbk1vZGVsKGtleS5uYW1lLCBcIlwiKSkpO1xuXHRcdH1cblx0fVxuXHRsZXQgZnVuY3Rpb25OYW1lID0gXCJcIjtcblx0aWYgKHR5cGVvZiBmb3JtYXR0ZXJGdW5jdGlvbiA9PT0gXCJzdHJpbmdcIikge1xuXHRcdGZ1bmN0aW9uTmFtZSA9IGZvcm1hdHRlckZ1bmN0aW9uO1xuXHR9IGVsc2Uge1xuXHRcdGZ1bmN0aW9uTmFtZSA9IGZvcm1hdHRlckZ1bmN0aW9uLl9fZnVuY3Rpb25OYW1lO1xuXHR9XG5cdC8vIEZvcm1hdHRlck5hbWUgY2FuIGJlIG9mIGZvcm1hdCBzYXAuZmUuY29yZS54eHgjbWV0aG9kTmFtZSB0byBoYXZlIG11bHRpcGxlIGZvcm1hdHRlciBpbiBvbmUgY2xhc3Ncblx0Y29uc3QgW2Zvcm1hdHRlckNsYXNzLCBmb3JtYXR0ZXJOYW1lXSA9IGZ1bmN0aW9uTmFtZS5zcGxpdChcIiNcIik7XG5cblx0aWYgKCEhZm9ybWF0dGVyTmFtZSAmJiBmb3JtYXR0ZXJOYW1lLmxlbmd0aCA+IDApIHtcblx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy51bnNoaWZ0KGNvbnN0YW50KGZvcm1hdHRlck5hbWUpKTtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiRm9ybWF0dGVyXCIsXG5cdFx0Zm46IGZvcm1hdHRlckNsYXNzLFxuXHRcdHBhcmFtZXRlcnM6IHBhcmFtZXRlckV4cHJlc3Npb25zXG5cdH07XG59XG5cbi8qKlxuICogQ2FsbHMgYSBjb21wbGV4IHR5cGUgdG8gcHJvY2VzcyB0aGUgcGFyYW1ldGVycy5cbiAqIElmIHJlcXVpcmVDb250ZXh0IGlzIHNldCB0byB0cnVlIGFuZCBubyBjb250ZXh0IGlzIHBhc3NlZCwgYSBkZWZhdWx0IGNvbnRleHQgd2lsbCBiZSBhZGRlZCBhdXRvbWF0aWNhbGx5LlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdGVtcGxhdGUgVVxuICogQHBhcmFtIHBhcmFtZXRlcnMgVGhlIGxpc3Qgb2YgcGFyYW1ldGVycyB0aGF0IHNob3VsZCBtYXRjaCB0aGUgdHlwZSBmb3IgdGhlIGNvbXBsZXggdHlwZT1cbiAqIEBwYXJhbSB0eXBlIFRoZSBjb21wbGV4IHR5cGUgdG8gdXNlXG4gKiBAcGFyYW0gW2NvbnRleHRFbnRpdHlUeXBlXSBUaGUgY29udGV4dCBlbnRpdHkgdHlwZSB0byBjb25zaWRlclxuICogQHBhcmFtIG9Gb3JtYXRPcHRpb25zXG4gKiBAcmV0dXJucyBUaGUgY29ycmVzcG9uZGluZyBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRUeXBlSW5mb3JtYXRpb248VCwgVSBleHRlbmRzIEZuPFQ+Pihcblx0cGFyYW1ldGVyczogV3JhcHBlZFR1cGxlPFBhcmFtZXRlcnM8VT4+LFxuXHR0eXBlOiBzdHJpbmcsXG5cdGNvbnRleHRFbnRpdHlUeXBlPzogRW50aXR5VHlwZSxcblx0b0Zvcm1hdE9wdGlvbnM/OiBhbnlcbik6IFVucmVzb2x2ZWFibGVQYXRoRXhwcmVzc2lvbiB8IENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPiB8IENvbnN0YW50RXhwcmVzc2lvbjxUPiB7XG5cdGNvbnN0IHBhcmFtZXRlckV4cHJlc3Npb25zID0gKHBhcmFtZXRlcnMgYXMgYW55W10pLm1hcCh3cmFwUHJpbWl0aXZlKTtcblx0aWYgKGhhc1VucmVzb2x2ZWFibGVFeHByZXNzaW9uKC4uLnBhcmFtZXRlckV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmVhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHQvLyBJZiB0aGVyZSBpcyBvbmx5IG9uZSBwYXJhbWV0ZXIgYW5kIGl0IGlzIGEgY29uc3RhbnQgYW5kIHdlIGRvbid0IGV4cGVjdCB0aGUgY29udGV4dCB0aGVuIHJldHVybiB0aGUgY29uc3RhbnRcblx0aWYgKHBhcmFtZXRlckV4cHJlc3Npb25zLmxlbmd0aCA9PT0gMSAmJiBpc0NvbnN0YW50KHBhcmFtZXRlckV4cHJlc3Npb25zWzBdKSAmJiAhY29udGV4dEVudGl0eVR5cGUpIHtcblx0XHRyZXR1cm4gcGFyYW1ldGVyRXhwcmVzc2lvbnNbMF07XG5cdH0gZWxzZSBpZiAoY29udGV4dEVudGl0eVR5cGUpIHtcblx0XHQvLyBPdGhlcndpc2UsIGlmIHRoZSBjb250ZXh0IGlzIHJlcXVpcmVkIGFuZCBubyBjb250ZXh0IGlzIHByb3ZpZGVkIG1ha2Ugc3VyZSB0byBhZGQgdGhlIGRlZmF1bHQgYmluZGluZ1xuXHRcdGlmICghcGFyYW1ldGVyRXhwcmVzc2lvbnMuc29tZShoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KSkge1xuXHRcdFx0Y29udGV4dEVudGl0eVR5cGUua2V5cy5mb3JFYWNoKChrZXkpID0+IHBhcmFtZXRlckV4cHJlc3Npb25zLnB1c2gocGF0aEluTW9kZWwoa2V5Lm5hbWUsIFwiXCIpKSk7XG5cdFx0fVxuXHR9XG5cdC8vIGlmIHNob3dNZWFzdXJlIGlzIHNldCB0byBmYWxzZSB3ZSB3YW50IHRvIG5vdCBwYXJzZSBhcyBzdHJpbmcgdG8gc2VlIHRoZSAwXG5cdC8vIHdlIGRvIHRoYXQgYWxzbyBmb3IgYWxsIGJpbmRpbmdzIGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZSBtZGMgRmllbGQgaXNuJ3QgZWRpdGFibGVcblx0aWYgKFxuXHRcdCEob0Zvcm1hdE9wdGlvbnMgJiYgb0Zvcm1hdE9wdGlvbnMuc2hvd051bWJlciA9PT0gZmFsc2UpICYmXG5cdFx0KChwYXJhbWV0ZXJzWzBdIGFzIGFueSk/LnR5cGU/LmluZGV4T2YoXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnRcIikgPT09IDAgfHxcblx0XHRcdChwYXJhbWV0ZXJzWzBdIGFzIGFueSk/LnR5cGU/LmluZGV4T2YoXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EZWNpbWFsXCIpID09PSAwIHx8XG5cdFx0XHQocGFyYW1ldGVyc1swXSBhcyBhbnkpPy50eXBlPy5pbmRleE9mKFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRG91YmxlXCIpID09PSAwKVxuXHQpIHtcblx0XHRpZiAoXG5cdFx0XHQocGFyYW1ldGVyc1swXSBhcyBhbnkpPy50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDY0XCIgfHxcblx0XHRcdChwYXJhbWV0ZXJzWzBdIGFzIGFueSk/LnR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRGVjaW1hbFwiXG5cdFx0KSB7XG5cdFx0XHQvL3NhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDY0IGRvIG5vdCBzdXBwb3J0IHBhcnNlQXNTdHJpbmcgZmFsc2Vcblx0XHRcdG9Gb3JtYXRPcHRpb25zID0gb0Zvcm1hdE9wdGlvbnM/LnNob3dNZWFzdXJlID09PSBmYWxzZSA/IHsgZW1wdHlTdHJpbmc6IFwiXCIsIHNob3dNZWFzdXJlOiBmYWxzZSB9IDogeyBlbXB0eVN0cmluZzogXCJcIiB9O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvRm9ybWF0T3B0aW9ucyA9XG5cdFx0XHRcdG9Gb3JtYXRPcHRpb25zPy5zaG93TWVhc3VyZSA9PT0gZmFsc2Vcblx0XHRcdFx0XHQ/IHsgcGFyc2VBc1N0cmluZzogZmFsc2UsIGVtcHR5U3RyaW5nOiBcIlwiLCBzaG93TWVhc3VyZTogZmFsc2UgfVxuXHRcdFx0XHRcdDogeyBwYXJzZUFzU3RyaW5nOiBmYWxzZSwgZW1wdHlTdHJpbmc6IFwiXCIgfTtcblx0XHR9XG5cdH1cblx0aWYgKHR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuVW5pdFwiKSB7XG5cdFx0Y29uc3QgdW9tUGF0aCA9IHBhdGhJbk1vZGVsKFwiLyMjQEByZXF1ZXN0VW5pdHNPZk1lYXN1cmVcIik7XG5cdFx0dW9tUGF0aC50YXJnZXRUeXBlID0gXCJhbnlcIjtcblx0XHR1b21QYXRoLm1vZGUgPSBcIk9uZVRpbWVcIjtcblx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5wdXNoKHVvbVBhdGgpO1xuXHR9IGVsc2UgaWYgKHR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuQ3VycmVuY3lcIikge1xuXHRcdGNvbnN0IGN1cnJlbmN5UGF0aCA9IHBhdGhJbk1vZGVsKFwiLyMjQEByZXF1ZXN0Q3VycmVuY3lDb2Rlc1wiKTtcblx0XHRjdXJyZW5jeVBhdGgudGFyZ2V0VHlwZSA9IFwiYW55XCI7XG5cdFx0Y3VycmVuY3lQYXRoLm1vZGUgPSBcIk9uZVRpbWVcIjtcblx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5wdXNoKGN1cnJlbmN5UGF0aCk7XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkNvbXBsZXhUeXBlXCIsXG5cdFx0dHlwZTogdHlwZSxcblx0XHRmb3JtYXRPcHRpb25zOiBvRm9ybWF0T3B0aW9ucyB8fCB7fSxcblx0XHRwYXJhbWV0ZXJzOiB7fSxcblx0XHRiaW5kaW5nUGFyYW1ldGVyczogcGFyYW1ldGVyRXhwcmVzc2lvbnNcblx0fTtcbn1cbi8qKlxuICogRnVuY3Rpb24gY2FsbCwgb3B0aW9uYWxseSB3aXRoIGFyZ3VtZW50cy5cbiAqXG4gKiBAcGFyYW0gZnVuYyBGdW5jdGlvbiBuYW1lIG9yIHJlZmVyZW5jZSB0byBmdW5jdGlvblxuICogQHBhcmFtIHBhcmFtZXRlcnMgQXJndW1lbnRzXG4gKiBAcGFyYW0gb24gT2JqZWN0IHRvIGNhbGwgdGhlIGZ1bmN0aW9uIG9uXG4gKiBAcmV0dXJucyBFeHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgZnVuY3Rpb24gY2FsbCAobm90IHRoZSByZXN1bHQgb2YgdGhlIGZ1bmN0aW9uIGNhbGwhKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZm48VCwgVSBleHRlbmRzIEZ1bmN0aW9uT3JOYW1lPFQ+Pihcblx0ZnVuYzogVSxcblx0cGFyYW1ldGVyczogV3JhcHBlZFR1cGxlPEZ1bmN0aW9uUGFyYW1ldGVyczxULCBVPj4sXG5cdG9uPzogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPG9iamVjdD5cbik6IEZ1bmN0aW9uRXhwcmVzc2lvbjxUPiB7XG5cdGNvbnN0IGZ1bmN0aW9uTmFtZSA9IHR5cGVvZiBmdW5jID09PSBcInN0cmluZ1wiID8gZnVuYyA6IGZ1bmMuX19mdW5jdGlvbk5hbWU7XG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiRnVuY3Rpb25cIixcblx0XHRvYmo6IG9uICE9PSB1bmRlZmluZWQgPyB3cmFwUHJpbWl0aXZlKG9uKSA6IHVuZGVmaW5lZCxcblx0XHRmbjogZnVuY3Rpb25OYW1lLFxuXHRcdHBhcmFtZXRlcnM6IChwYXJhbWV0ZXJzIGFzIGFueVtdKS5tYXAod3JhcFByaW1pdGl2ZSlcblx0fTtcbn1cblxuLyoqXG4gKiBTaG9ydGN1dCBmdW5jdGlvbiB0byBkZXRlcm1pbmUgaWYgYSBiaW5kaW5nIHZhbHVlIGlzIG51bGwsIHVuZGVmaW5lZCBvciBlbXB0eS5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgQSBib29sZWFuIGV4cHJlc3Npb24gZXZhbHVhdGluZyB0aGUgZmFjdCB0aGF0IHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgZW1wdHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHkoZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRpZiAoZXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJDb25jYXRcIikge1xuXHRcdHJldHVybiBvciguLi5leHByZXNzaW9uLmV4cHJlc3Npb25zLm1hcChpc0VtcHR5KSk7XG5cdH1cblx0cmV0dXJuIG9yKGVxdWFsKGV4cHJlc3Npb24sIFwiXCIpLCBlcXVhbChleHByZXNzaW9uLCB1bmRlZmluZWQpLCBlcXVhbChleHByZXNzaW9uLCBudWxsKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb25jYXQoLi4uaW5FeHByZXNzaW9uczogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPHN0cmluZz5bXSk6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxzdHJpbmc+IHtcblx0Y29uc3QgZXhwcmVzc2lvbnMgPSBpbkV4cHJlc3Npb25zLm1hcCh3cmFwUHJpbWl0aXZlKTtcblx0aWYgKGhhc1VucmVzb2x2ZWFibGVFeHByZXNzaW9uKC4uLmV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmVhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoZXhwcmVzc2lvbnMuZXZlcnkoaXNDb25zdGFudCkpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoXG5cdFx0XHRleHByZXNzaW9ucy5yZWR1Y2UoKGNvbmNhdGVuYXRlZDogc3RyaW5nLCB2YWx1ZSkgPT4ge1xuXHRcdFx0XHRyZXR1cm4gY29uY2F0ZW5hdGVkICsgKHZhbHVlIGFzIENvbnN0YW50RXhwcmVzc2lvbjxhbnk+KS52YWx1ZS50b1N0cmluZygpO1xuXHRcdFx0fSwgXCJcIilcblx0XHQpO1xuXHR9IGVsc2UgaWYgKGV4cHJlc3Npb25zLnNvbWUoaXNDb21wbGV4VHlwZUV4cHJlc3Npb24pKSB7XG5cdFx0bGV0IHBhdGhJZHggPSAwO1xuXHRcdGNvbnN0IG15Q29uY2F0RXhwcmVzc2lvbiA9IGZvcm1hdFJlc3VsdChleHByZXNzaW9ucywgXCJzYXAuZmUuY29yZS5mb3JtYXR0ZXJzLlN0YW5kYXJkRm9ybWF0dGVyI2NvbmNhdFwiKTtcblx0XHRjb25zdCBhbGxQYXJ0cyA9IFtdO1xuXHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KG15Q29uY2F0RXhwcmVzc2lvbiwgXCJQYXRoSW5Nb2RlbFwiLCAoY29uc3RhbnRQYXRoOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248YW55PikgPT4ge1xuXHRcdFx0YWxsUGFydHMucHVzaChjb25zdGFudFBhdGgpO1xuXHRcdFx0cmV0dXJuIHBhdGhJbk1vZGVsKGBcXCQke3BhdGhJZHgrK31gLCBcIiRcIik7XG5cdFx0fSk7XG5cdFx0YWxsUGFydHMudW5zaGlmdChjb25zdGFudChKU09OLnN0cmluZ2lmeShteUNvbmNhdEV4cHJlc3Npb24pKSk7XG5cdFx0cmV0dXJuIGZvcm1hdFJlc3VsdChhbGxQYXJ0cywgXCJzYXAuZmUuY29yZS5mb3JtYXR0ZXJzLlN0YW5kYXJkRm9ybWF0dGVyI2V2YWx1YXRlQ29tcGxleEV4cHJlc3Npb25cIik7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJDb25jYXRcIixcblx0XHRleHByZXNzaW9uczogZXhwcmVzc2lvbnNcblx0fTtcbn1cblxuZXhwb3J0IHR5cGUgVHJhbnNmb3JtRnVuY3Rpb24gPSA8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGUgfCB1bmtub3duPihleHByZXNzaW9uUGFydDogYW55KSA9PiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5leHBvcnQgdHlwZSBFeHByZXNzaW9uVHlwZSA9IFBpY2s8QmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGFueT4sIFwiX3R5cGVcIj5bXCJfdHlwZVwiXTtcbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1SZWN1cnNpdmVseTxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZSB8IHVua25vd24+KFxuXHRpbkV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPixcblx0ZXhwcmVzc2lvblR5cGU6IEV4cHJlc3Npb25UeXBlLFxuXHR0cmFuc2Zvcm1GdW5jdGlvbjogVHJhbnNmb3JtRnVuY3Rpb24sXG5cdGluY2x1ZGVBbGxFeHByZXNzaW9uID0gZmFsc2Vcbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGxldCBleHByZXNzaW9uID0gaW5FeHByZXNzaW9uO1xuXHRzd2l0Y2ggKGV4cHJlc3Npb24uX3R5cGUpIHtcblx0XHRjYXNlIFwiRnVuY3Rpb25cIjpcblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0XHRleHByZXNzaW9uLnBhcmFtZXRlcnMgPSBleHByZXNzaW9uLnBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KHBhcmFtZXRlciwgZXhwcmVzc2lvblR5cGUsIHRyYW5zZm9ybUZ1bmN0aW9uLCBpbmNsdWRlQWxsRXhwcmVzc2lvbilcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiQ29uY2F0XCI6XG5cdFx0XHRleHByZXNzaW9uLmV4cHJlc3Npb25zID0gZXhwcmVzc2lvbi5leHByZXNzaW9ucy5tYXAoKHN1YkV4cHJlc3Npb24pID0+XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KHN1YkV4cHJlc3Npb24sIGV4cHJlc3Npb25UeXBlLCB0cmFuc2Zvcm1GdW5jdGlvbiwgaW5jbHVkZUFsbEV4cHJlc3Npb24pXG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIkNvbXBsZXhUeXBlXCI6XG5cdFx0XHRleHByZXNzaW9uLmJpbmRpbmdQYXJhbWV0ZXJzID0gZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVycy5tYXAoKGJpbmRpbmdQYXJhbWV0ZXIpID0+XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KGJpbmRpbmdQYXJhbWV0ZXIsIGV4cHJlc3Npb25UeXBlLCB0cmFuc2Zvcm1GdW5jdGlvbiwgaW5jbHVkZUFsbEV4cHJlc3Npb24pXG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIklmRWxzZVwiOlxuXHRcdFx0Y29uc3Qgb25UcnVlID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoZXhwcmVzc2lvbi5vblRydWUsIGV4cHJlc3Npb25UeXBlLCB0cmFuc2Zvcm1GdW5jdGlvbiwgaW5jbHVkZUFsbEV4cHJlc3Npb24pO1xuXHRcdFx0Y29uc3Qgb25GYWxzZSA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KGV4cHJlc3Npb24ub25GYWxzZSwgZXhwcmVzc2lvblR5cGUsIHRyYW5zZm9ybUZ1bmN0aW9uLCBpbmNsdWRlQWxsRXhwcmVzc2lvbik7XG5cdFx0XHRsZXQgY29uZGl0aW9uID0gZXhwcmVzc2lvbi5jb25kaXRpb247XG5cdFx0XHRpZiAoaW5jbHVkZUFsbEV4cHJlc3Npb24pIHtcblx0XHRcdFx0Y29uZGl0aW9uID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoZXhwcmVzc2lvbi5jb25kaXRpb24sIGV4cHJlc3Npb25UeXBlLCB0cmFuc2Zvcm1GdW5jdGlvbiwgaW5jbHVkZUFsbEV4cHJlc3Npb24pO1xuXHRcdFx0fVxuXHRcdFx0ZXhwcmVzc2lvbiA9IGlmRWxzZShjb25kaXRpb24sIG9uVHJ1ZSwgb25GYWxzZSkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIk5vdFwiOlxuXHRcdFx0aWYgKGluY2x1ZGVBbGxFeHByZXNzaW9uKSB7XG5cdFx0XHRcdGNvbnN0IG9wZXJhbmQgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShleHByZXNzaW9uLm9wZXJhbmQsIGV4cHJlc3Npb25UeXBlLCB0cmFuc2Zvcm1GdW5jdGlvbiwgaW5jbHVkZUFsbEV4cHJlc3Npb24pO1xuXHRcdFx0XHRleHByZXNzaW9uID0gbm90KG9wZXJhbmQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0XHRcdH1cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJUcnV0aHlcIjpcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJTZXRcIjpcblx0XHRcdGlmIChpbmNsdWRlQWxsRXhwcmVzc2lvbikge1xuXHRcdFx0XHRjb25zdCBvcGVyYW5kcyA9IGV4cHJlc3Npb24ub3BlcmFuZHMubWFwKChvcGVyYW5kKSA9PlxuXHRcdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KG9wZXJhbmQsIGV4cHJlc3Npb25UeXBlLCB0cmFuc2Zvcm1GdW5jdGlvbiwgaW5jbHVkZUFsbEV4cHJlc3Npb24pXG5cdFx0XHRcdCk7XG5cdFx0XHRcdGV4cHJlc3Npb24gPVxuXHRcdFx0XHRcdGV4cHJlc3Npb24ub3BlcmF0b3IgPT09IFwifHxcIlxuXHRcdFx0XHRcdFx0PyAob3IoLi4ub3BlcmFuZHMpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPilcblx0XHRcdFx0XHRcdDogKGFuZCguLi5vcGVyYW5kcykgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+KTtcblx0XHRcdH1cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJDb21wYXJpc29uXCI6XG5cdFx0XHRpZiAoaW5jbHVkZUFsbEV4cHJlc3Npb24pIHtcblx0XHRcdFx0Y29uc3Qgb3BlcmFuZDEgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShleHByZXNzaW9uLm9wZXJhbmQxLCBleHByZXNzaW9uVHlwZSwgdHJhbnNmb3JtRnVuY3Rpb24sIGluY2x1ZGVBbGxFeHByZXNzaW9uKTtcblx0XHRcdFx0Y29uc3Qgb3BlcmFuZDIgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShleHByZXNzaW9uLm9wZXJhbmQyLCBleHByZXNzaW9uVHlwZSwgdHJhbnNmb3JtRnVuY3Rpb24sIGluY2x1ZGVBbGxFeHByZXNzaW9uKTtcblx0XHRcdFx0ZXhwcmVzc2lvbiA9IGNvbXBhcmlzb24oZXhwcmVzc2lvbi5vcGVyYXRvciwgb3BlcmFuZDEsIG9wZXJhbmQyKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0XHR9XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiUmVmXCI6XG5cdFx0Y2FzZSBcIkxlbmd0aFwiOlxuXHRcdGNhc2UgXCJQYXRoSW5Nb2RlbFwiOlxuXHRcdGNhc2UgXCJDb25zdGFudFwiOlxuXHRcdGNhc2UgXCJFbWJlZGRlZEJpbmRpbmdcIjpcblx0XHRjYXNlIFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiOlxuXHRcdGNhc2UgXCJVbnJlc29sdmFibGVcIjpcblx0XHRcdC8vIERvIG5vdGhpbmdcblx0XHRcdGJyZWFrO1xuXHR9XG5cdGlmIChleHByZXNzaW9uVHlwZSA9PT0gZXhwcmVzc2lvbi5fdHlwZSkge1xuXHRcdGV4cHJlc3Npb24gPSB0cmFuc2Zvcm1GdW5jdGlvbihpbkV4cHJlc3Npb24pO1xuXHR9XG5cdHJldHVybiBleHByZXNzaW9uO1xufVxuXG5leHBvcnQgdHlwZSBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbiA9IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuY29uc3QgbmVlZFBhcmVudGhlc2lzID0gZnVuY3Rpb24gPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihleHByOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4pOiBib29sZWFuIHtcblx0cmV0dXJuIChcblx0XHQhaXNDb25zdGFudChleHByKSAmJiAhaXNQYXRoSW5Nb2RlbEV4cHJlc3Npb24oZXhwcikgJiYgaXNFeHByZXNzaW9uKGV4cHIpICYmIGV4cHIuX3R5cGUgIT09IFwiSWZFbHNlXCIgJiYgZXhwci5fdHlwZSAhPT0gXCJGdW5jdGlvblwiXG5cdCk7XG59O1xuXG4vKipcbiAqIENvbXBpbGVzIGEgY29uc3RhbnQgb2JqZWN0IHRvIGEgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSBleHByXG4gKiBAcGFyYW0gaXNOdWxsYWJsZVxuICogQHJldHVybnMgVGhlIGNvbXBpbGVkIHN0cmluZ1xuICovXG5mdW5jdGlvbiBjb21waWxlQ29uc3RhbnRPYmplY3QoZXhwcjogQ29uc3RhbnRFeHByZXNzaW9uPG9iamVjdD4sIGlzTnVsbGFibGUgPSBmYWxzZSkge1xuXHRpZiAoaXNOdWxsYWJsZSAmJiBPYmplY3Qua2V5cyhleHByLnZhbHVlKS5sZW5ndGggPT09IDApIHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXHQvLyBPYmplY3RzXG5cdGNvbnN0IG8gPSBleHByLnZhbHVlIGFzIFBsYWluRXhwcmVzc2lvbk9iamVjdDtcblx0Y29uc3QgcHJvcGVydGllczogc3RyaW5nW10gPSBbXTtcblx0T2JqZWN0LmtleXMobykuZm9yRWFjaCgoa2V5KSA9PiB7XG5cdFx0Y29uc3QgdmFsdWUgPSBvW2tleV07XG5cdFx0Y29uc3QgY2hpbGRSZXN1bHQgPSBjb21waWxlRXhwcmVzc2lvbih2YWx1ZSwgdHJ1ZSwgZmFsc2UsIHRydWUpO1xuXHRcdGlmIChjaGlsZFJlc3VsdCAmJiBjaGlsZFJlc3VsdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRwcm9wZXJ0aWVzLnB1c2goYCR7a2V5fTogJHtjaGlsZFJlc3VsdH1gKTtcblx0XHR9XG5cdH0pO1xuXHRyZXR1cm4gYHske3Byb3BlcnRpZXMuam9pbihcIiwgXCIpfX1gO1xufVxuXG4vKipcbiAqIENvbXBpbGVzIGEgQ29uc3RhbnQgQmluZGluZyBFeHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByXG4gKiBAcGFyYW0gZW1iZWRkZWRJbkJpbmRpbmdcbiAqIEBwYXJhbSBpc051bGxhYmxlXG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGNvbXBpbGVDb25zdGFudDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oZXhwcjogQ29uc3RhbnRFeHByZXNzaW9uPFQ+LCBlbWJlZGRlZEluQmluZGluZzogYm9vbGVhbiwgaXNOdWxsYWJsZSA9IGZhbHNlKSB7XG5cdGlmIChleHByLnZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIFwibnVsbFwiO1xuXHR9XG5cdGlmIChleHByLnZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gXCJ1bmRlZmluZWRcIjtcblx0fVxuXHRpZiAodHlwZW9mIGV4cHIudmFsdWUgPT09IFwib2JqZWN0XCIpIHtcblx0XHRpZiAoQXJyYXkuaXNBcnJheShleHByLnZhbHVlKSkge1xuXHRcdFx0Y29uc3QgZW50cmllcyA9IGV4cHIudmFsdWUubWFwKChleHByZXNzaW9uKSA9PiBjb21waWxlRXhwcmVzc2lvbihleHByZXNzaW9uLCB0cnVlKSk7XG5cdFx0XHRyZXR1cm4gYFske2VudHJpZXMuam9pbihcIiwgXCIpfV1gO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gY29tcGlsZUNvbnN0YW50T2JqZWN0KGV4cHIgYXMgQ29uc3RhbnRFeHByZXNzaW9uPG9iamVjdD4sIGlzTnVsbGFibGUpO1xuXHRcdH1cblx0fVxuXG5cdGlmIChlbWJlZGRlZEluQmluZGluZykge1xuXHRcdHN3aXRjaCAodHlwZW9mIGV4cHIudmFsdWUpIHtcblx0XHRcdGNhc2UgXCJudW1iZXJcIjpcblx0XHRcdGNhc2UgXCJiaWdpbnRcIjpcblx0XHRcdGNhc2UgXCJib29sZWFuXCI6XG5cdFx0XHRcdHJldHVybiBleHByLnZhbHVlLnRvU3RyaW5nKCk7XG5cdFx0XHRjYXNlIFwic3RyaW5nXCI6XG5cdFx0XHRcdHJldHVybiBgJyR7ZXNjYXBlWG1sQXR0cmlidXRlKGV4cHIudmFsdWUudG9TdHJpbmcoKSl9J2A7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRyZXR1cm4gXCJcIjtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGV4cHIudmFsdWUudG9TdHJpbmcoKTtcblx0fVxufVxuXG4vKipcbiAqIEdlbmVyYXRlcyB0aGUgYmluZGluZyBzdHJpbmcgZm9yIGEgQmluZGluZyBleHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uRm9yQmluZGluZyBUaGUgZXhwcmVzc2lvbiB0byBjb21waWxlXG4gKiBAcGFyYW0gZW1iZWRkZWRJbkJpbmRpbmcgV2hldGhlciB0aGUgZXhwcmVzc2lvbiB0byBjb21waWxlIGlzIGVtYmVkZGVkIGludG8gYW5vdGhlciBleHByZXNzaW9uXG4gKiBAcGFyYW0gZW1iZWRkZWRTZXBhcmF0b3IgVGhlIGJpbmRpbmcgdmFsdWUgZXZhbHVhdG9yICgkIG9yICUgZGVwZW5kaW5nIG9uIHdoZXRoZXIgd2Ugd2FudCB0byBmb3JjZSB0aGUgdHlwZSBvciBub3QpXG4gKiBAcmV0dXJucyBUaGUgY29ycmVzcG9uZGluZyBleHByZXNzaW9uIGJpbmRpbmdcbiAqL1xuZnVuY3Rpb24gY29tcGlsZVBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGV4cHJlc3Npb25Gb3JCaW5kaW5nOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4sXG5cdGVtYmVkZGVkSW5CaW5kaW5nOiBib29sZWFuLFxuXHRlbWJlZGRlZFNlcGFyYXRvcjogc3RyaW5nXG4pIHtcblx0aWYgKFxuXHRcdGV4cHJlc3Npb25Gb3JCaW5kaW5nLnR5cGUgfHxcblx0XHRleHByZXNzaW9uRm9yQmluZGluZy5wYXJhbWV0ZXJzIHx8XG5cdFx0ZXhwcmVzc2lvbkZvckJpbmRpbmcudGFyZ2V0VHlwZSB8fFxuXHRcdGV4cHJlc3Npb25Gb3JCaW5kaW5nLmZvcm1hdE9wdGlvbnMgfHxcblx0XHRleHByZXNzaW9uRm9yQmluZGluZy5jb25zdHJhaW50c1xuXHQpIHtcblx0XHQvLyBUaGlzIGlzIG5vdyBhIGNvbXBsZXggYmluZGluZyBkZWZpbml0aW9uLCBsZXQncyBwcmVwYXJlIGZvciBpdFxuXHRcdGNvbnN0IGNvbXBsZXhCaW5kaW5nRGVmaW5pdGlvbiA9IHtcblx0XHRcdHBhdGg6IGNvbXBpbGVQYXRoSW5Nb2RlbChleHByZXNzaW9uRm9yQmluZGluZyksXG5cdFx0XHR0eXBlOiBleHByZXNzaW9uRm9yQmluZGluZy50eXBlLFxuXHRcdFx0dGFyZ2V0VHlwZTogZXhwcmVzc2lvbkZvckJpbmRpbmcudGFyZ2V0VHlwZSxcblx0XHRcdHBhcmFtZXRlcnM6IGV4cHJlc3Npb25Gb3JCaW5kaW5nLnBhcmFtZXRlcnMsXG5cdFx0XHRmb3JtYXRPcHRpb25zOiBleHByZXNzaW9uRm9yQmluZGluZy5mb3JtYXRPcHRpb25zLFxuXHRcdFx0Y29uc3RyYWludHM6IGV4cHJlc3Npb25Gb3JCaW5kaW5nLmNvbnN0cmFpbnRzXG5cdFx0fTtcblx0XHRsZXQgb3V0QmluZGluZyA9IGNvbXBpbGVFeHByZXNzaW9uKGNvbXBsZXhCaW5kaW5nRGVmaW5pdGlvbik7XG5cdFx0aWYgKGVtYmVkZGVkSW5CaW5kaW5nKSB7XG5cdFx0XHRvdXRCaW5kaW5nID0gYCR7ZW1iZWRkZWRTZXBhcmF0b3J9JHtvdXRCaW5kaW5nfWA7XG5cdFx0fVxuXHRcdHJldHVybiBvdXRCaW5kaW5nO1xuXHR9IGVsc2UgaWYgKGVtYmVkZGVkSW5CaW5kaW5nKSB7XG5cdFx0cmV0dXJuIGAke2VtYmVkZGVkU2VwYXJhdG9yfXske2NvbXBpbGVQYXRoSW5Nb2RlbChleHByZXNzaW9uRm9yQmluZGluZyl9fWA7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGB7JHtjb21waWxlUGF0aEluTW9kZWwoZXhwcmVzc2lvbkZvckJpbmRpbmcpfX1gO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVDb21wbGV4VHlwZUV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPikge1xuXHRpZiAoZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVycy5sZW5ndGggPT09IDEpIHtcblx0XHRyZXR1cm4gYHske2NvbXBpbGVQYXRoUGFyYW1ldGVyKGV4cHJlc3Npb24uYmluZGluZ1BhcmFtZXRlcnNbMF0sIHRydWUpfSwgdHlwZTogJyR7ZXhwcmVzc2lvbi50eXBlfSd9YDtcblx0fVxuXG5cdGxldCBvdXRwdXRFbmQgPSBgXSwgdHlwZTogJyR7ZXhwcmVzc2lvbi50eXBlfSdgO1xuXHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKSkge1xuXHRcdG91dHB1dEVuZCArPSBgLCBmb3JtYXRPcHRpb25zOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucyl9YDtcblx0fVxuXHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzKSkge1xuXHRcdG91dHB1dEVuZCArPSBgLCBwYXJhbWV0ZXJzOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24ucGFyYW1ldGVycyl9YDtcblx0fVxuXHRvdXRwdXRFbmQgKz0gXCJ9XCI7XG5cblx0cmV0dXJuIGB7bW9kZTonVHdvV2F5JywgcGFydHM6WyR7ZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVycy5tYXAoKHBhcmFtOiBhbnkpID0+IGNvbXBpbGVQYXRoUGFyYW1ldGVyKHBhcmFtKSkuam9pbihcIixcIil9JHtvdXRwdXRFbmR9YDtcbn1cblxuLyoqXG4gKiBXcmFwIHRoZSBjb21waWxlZCBiaW5kaW5nIHN0cmluZyBhcyByZXF1aXJlZCBkZXBlbmRlbmluZyBvbiBpdHMgY29udGV4dC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgY29tcGlsZWQgZXhwcmVzc2lvblxuICogQHBhcmFtIGVtYmVkZGVkSW5CaW5kaW5nIFRydWUgaWYgdGhlIGNvbXBpbGVkIGV4cHJlc3Npb24gaXMgdG8gYmUgZW1iZWRkZWQgaW4gYSBiaW5kaW5nXG4gKiBAcGFyYW0gcGFyZW50aGVzaXNSZXF1aXJlZCBUcnVlIGlmIHRoZSBlbWJlZGRlZCBiaW5kaW5nIG5lZWRzIHRvIGJlIHdyYXBwZWQgaW4gcGFyZXRoZXNpcyBzbyB0aGF0IGl0IGlzIGV2YWx1YXRlZCBhcyBvbmVcbiAqIEByZXR1cm5zIEZpbmFsaXplZCBjb21waWxlZCBleHByZXNzaW9uXG4gKi9cbmZ1bmN0aW9uIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihcblx0ZXhwcmVzc2lvbjogc3RyaW5nLFxuXHRlbWJlZGRlZEluQmluZGluZzogYm9vbGVhbixcblx0cGFyZW50aGVzaXNSZXF1aXJlZCA9IGZhbHNlXG4pOiBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbiB7XG5cdGlmIChlbWJlZGRlZEluQmluZGluZykge1xuXHRcdGlmIChwYXJlbnRoZXNpc1JlcXVpcmVkKSB7XG5cdFx0XHRyZXR1cm4gYCgke2V4cHJlc3Npb259KWA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBleHByZXNzaW9uO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gYHs9ICR7ZXhwcmVzc2lvbn19YDtcblx0fVxufVxuXG4vKipcbiAqIENvbXBpbGUgYW4gZXhwcmVzc2lvbiBpbnRvIGFuIGV4cHJlc3Npb24gYmluZGluZy5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGVcbiAqIEBwYXJhbSBlbWJlZGRlZEluQmluZGluZyBXaGV0aGVyIHRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGUgaXMgZW1iZWRkZWQgaW50byBhbm90aGVyIGV4cHJlc3Npb25cbiAqIEBwYXJhbSBrZWVwVGFyZ2V0VHlwZSBLZWVwIHRoZSB0YXJnZXQgdHlwZSBvZiB0aGUgZW1iZWRkZWQgYmluZGluZ3MgaW5zdGVhZCBvZiBjYXN0aW5nIHRoZW0gdG8gYW55XG4gKiBAcGFyYW0gaXNOdWxsYWJsZSBXaGV0aGVyIGJpbmRpbmcgZXhwcmVzc2lvbiBjYW4gcmVzb2x2ZSB0byBlbXB0eSBzdHJpbmcgb3Igbm90XG4gKiBAcmV0dXJucyBUaGUgY29ycmVzcG9uZGluZyBleHByZXNzaW9uIGJpbmRpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBpbGVFeHByZXNzaW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0ZXhwcmVzc2lvbjogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRlbWJlZGRlZEluQmluZGluZyA9IGZhbHNlLFxuXHRrZWVwVGFyZ2V0VHlwZSA9IGZhbHNlLFxuXHRpc051bGxhYmxlID0gZmFsc2Vcbik6IENvbXBpbGVkQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uIHtcblx0Y29uc3QgZXhwciA9IHdyYXBQcmltaXRpdmUoZXhwcmVzc2lvbik7XG5cdGNvbnN0IGVtYmVkZGVkU2VwYXJhdG9yID0ga2VlcFRhcmdldFR5cGUgPyBcIiRcIiA6IFwiJVwiO1xuXG5cdHN3aXRjaCAoZXhwci5fdHlwZSkge1xuXHRcdGNhc2UgXCJVbnJlc29sdmFibGVcIjpcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cblx0XHRjYXNlIFwiQ29uc3RhbnRcIjpcblx0XHRcdHJldHVybiBjb21waWxlQ29uc3RhbnQoZXhwciwgZW1iZWRkZWRJbkJpbmRpbmcsIGlzTnVsbGFibGUpO1xuXG5cdFx0Y2FzZSBcIlJlZlwiOlxuXHRcdFx0cmV0dXJuIGV4cHIucmVmIHx8IFwibnVsbFwiO1xuXG5cdFx0Y2FzZSBcIkZ1bmN0aW9uXCI6XG5cdFx0XHRjb25zdCBhcmd1bWVudFN0cmluZyA9IGAke2V4cHIucGFyYW1ldGVycy5tYXAoKGFyZykgPT4gY29tcGlsZUV4cHJlc3Npb24oYXJnLCB0cnVlKSkuam9pbihcIiwgXCIpfWA7XG5cdFx0XHRyZXR1cm4gZXhwci5vYmogPT09IHVuZGVmaW5lZFxuXHRcdFx0XHQ/IGAke2V4cHIuZm59KCR7YXJndW1lbnRTdHJpbmd9KWBcblx0XHRcdFx0OiBgJHtjb21waWxlRXhwcmVzc2lvbihleHByLm9iaiwgdHJ1ZSl9LiR7ZXhwci5mbn0oJHthcmd1bWVudFN0cmluZ30pYDtcblxuXHRcdGNhc2UgXCJFbWJlZGRlZEV4cHJlc3Npb25CaW5kaW5nXCI6XG5cdFx0XHRyZXR1cm4gZW1iZWRkZWRJbkJpbmRpbmcgPyBgKCR7ZXhwci52YWx1ZS5zdWJzdHIoMiwgZXhwci52YWx1ZS5sZW5ndGggLSAzKX0pYCA6IGAke2V4cHIudmFsdWV9YDtcblxuXHRcdGNhc2UgXCJFbWJlZGRlZEJpbmRpbmdcIjpcblx0XHRcdHJldHVybiBlbWJlZGRlZEluQmluZGluZyA/IGAke2VtYmVkZGVkU2VwYXJhdG9yfSR7ZXhwci52YWx1ZX1gIDogYCR7ZXhwci52YWx1ZX1gO1xuXG5cdFx0Y2FzZSBcIlBhdGhJbk1vZGVsXCI6XG5cdFx0XHRyZXR1cm4gY29tcGlsZVBhdGhJbk1vZGVsRXhwcmVzc2lvbihleHByLCBlbWJlZGRlZEluQmluZGluZywgZW1iZWRkZWRTZXBhcmF0b3IpO1xuXG5cdFx0Y2FzZSBcIkNvbXBhcmlzb25cIjpcblx0XHRcdGNvbnN0IGNvbXBhcmlzb25FeHByZXNzaW9uID0gY29tcGlsZUNvbXBhcmlzb25FeHByZXNzaW9uKGV4cHIpO1xuXHRcdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihjb21wYXJpc29uRXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIklmRWxzZVwiOlxuXHRcdFx0Y29uc3QgaWZFbHNlRXhwcmVzc2lvbiA9IGAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIuY29uZGl0aW9uLCB0cnVlKX0gPyAke2NvbXBpbGVFeHByZXNzaW9uKFxuXHRcdFx0XHRleHByLm9uVHJ1ZSxcblx0XHRcdFx0dHJ1ZVxuXHRcdFx0KX0gOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIub25GYWxzZSwgdHJ1ZSl9YDtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24oaWZFbHNlRXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcsIHRydWUpO1xuXG5cdFx0Y2FzZSBcIlNldFwiOlxuXHRcdFx0Y29uc3Qgc2V0RXhwcmVzc2lvbiA9IGV4cHIub3BlcmFuZHMubWFwKChvcGVyYW5kKSA9PiBjb21waWxlRXhwcmVzc2lvbihvcGVyYW5kLCB0cnVlKSkuam9pbihgICR7ZXhwci5vcGVyYXRvcn0gYCk7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKHNldEV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nLCB0cnVlKTtcblxuXHRcdGNhc2UgXCJDb25jYXRcIjpcblx0XHRcdGNvbnN0IGNvbmNhdEV4cHJlc3Npb24gPSBleHByLmV4cHJlc3Npb25zXG5cdFx0XHRcdC5tYXAoKG5lc3RlZEV4cHJlc3Npb24pID0+IGNvbXBpbGVFeHByZXNzaW9uKG5lc3RlZEV4cHJlc3Npb24sIHRydWUsIHRydWUpKVxuXHRcdFx0XHQuam9pbihcIiArIFwiKTtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24oY29uY2F0RXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIkxlbmd0aFwiOlxuXHRcdFx0Y29uc3QgbGVuZ3RoRXhwcmVzc2lvbiA9IGAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIucGF0aEluTW9kZWwsIHRydWUpfS5sZW5ndGhgO1xuXHRcdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihsZW5ndGhFeHByZXNzaW9uLCBlbWJlZGRlZEluQmluZGluZyk7XG5cblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0XHRjb25zdCBub3RFeHByZXNzaW9uID0gYCEke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIub3BlcmFuZCwgdHJ1ZSl9YDtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24obm90RXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIlRydXRoeVwiOlxuXHRcdFx0Y29uc3QgdHJ1dGh5RXhwcmVzc2lvbiA9IGAhISR7Y29tcGlsZUV4cHJlc3Npb24oZXhwci5vcGVyYW5kLCB0cnVlKX1gO1xuXHRcdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbih0cnV0aHlFeHByZXNzaW9uLCBlbWJlZGRlZEluQmluZGluZyk7XG5cblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0XHRjb25zdCBmb3JtYXR0ZXJFeHByZXNzaW9uID0gY29tcGlsZUZvcm1hdHRlckV4cHJlc3Npb24oZXhwcik7XG5cdFx0XHRyZXR1cm4gZW1iZWRkZWRJbkJpbmRpbmcgPyBgXFwkJHtmb3JtYXR0ZXJFeHByZXNzaW9ufWAgOiBmb3JtYXR0ZXJFeHByZXNzaW9uO1xuXG5cdFx0Y2FzZSBcIkNvbXBsZXhUeXBlXCI6XG5cdFx0XHRjb25zdCBjb21wbGV4VHlwZUV4cHJlc3Npb24gPSBjb21waWxlQ29tcGxleFR5cGVFeHByZXNzaW9uKGV4cHIpO1xuXHRcdFx0cmV0dXJuIGVtYmVkZGVkSW5CaW5kaW5nID8gYFxcJCR7Y29tcGxleFR5cGVFeHByZXNzaW9ufWAgOiBjb21wbGV4VHlwZUV4cHJlc3Npb247XG5cblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIFwiXCI7XG5cdH1cbn1cblxuLyoqXG4gKiBDb21waWxlIGEgY29tcGFyaXNvbiBleHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBjb21wYXJpc29uIGV4cHJlc3Npb24uXG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgZXhwcmVzc2lvbi4gTmVlZHMgd3JhcHBpbmcgYmVmb3JlIGl0IGNhbiBiZSB1c2VkIGFzIGFuIGV4cHJlc3Npb24gYmluZGluZy5cbiAqL1xuZnVuY3Rpb24gY29tcGlsZUNvbXBhcmlzb25FeHByZXNzaW9uKGV4cHJlc3Npb246IENvbXBhcmlzb25FeHByZXNzaW9uKSB7XG5cdGZ1bmN0aW9uIGNvbXBpbGVPcGVyYW5kKG9wZXJhbmQ6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxhbnk+KSB7XG5cdFx0Y29uc3QgY29tcGlsZWRPcGVyYW5kID0gY29tcGlsZUV4cHJlc3Npb24ob3BlcmFuZCwgdHJ1ZSkgPz8gXCJ1bmRlZmluZWRcIjtcblx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKGNvbXBpbGVkT3BlcmFuZCwgdHJ1ZSwgbmVlZFBhcmVudGhlc2lzKG9wZXJhbmQpKTtcblx0fVxuXG5cdHJldHVybiBgJHtjb21waWxlT3BlcmFuZChleHByZXNzaW9uLm9wZXJhbmQxKX0gJHtleHByZXNzaW9uLm9wZXJhdG9yfSAke2NvbXBpbGVPcGVyYW5kKGV4cHJlc3Npb24ub3BlcmFuZDIpfWA7XG59XG5cbi8qKlxuICogQ29tcGlsZSBhIGZvcm1hdHRlciBleHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBmb3JtYXR0ZXIgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBleHByZXNzaW9uLlxuICovXG5mdW5jdGlvbiBjb21waWxlRm9ybWF0dGVyRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oZXhwcmVzc2lvbjogRm9ybWF0dGVyRXhwcmVzc2lvbjxUPikge1xuXHRpZiAoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzLmxlbmd0aCA9PT0gMSkge1xuXHRcdHJldHVybiBgeyR7Y29tcGlsZVBhdGhQYXJhbWV0ZXIoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzWzBdLCB0cnVlKX0sIGZvcm1hdHRlcjogJyR7ZXhwcmVzc2lvbi5mbn0nfWA7XG5cdH0gZWxzZSB7XG5cdFx0Y29uc3QgcGFydHMgPSBleHByZXNzaW9uLnBhcmFtZXRlcnMubWFwKChwYXJhbSkgPT4ge1xuXHRcdFx0aWYgKHBhcmFtLl90eXBlID09PSBcIkNvbXBsZXhUeXBlXCIpIHtcblx0XHRcdFx0cmV0dXJuIGNvbXBpbGVDb21wbGV4VHlwZUV4cHJlc3Npb24ocGFyYW0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIGNvbXBpbGVQYXRoUGFyYW1ldGVyKHBhcmFtKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRyZXR1cm4gYHtwYXJ0czogWyR7cGFydHMuam9pbihcIiwgXCIpfV0sIGZvcm1hdHRlcjogJyR7ZXhwcmVzc2lvbi5mbn0nfWA7XG5cdH1cbn1cblxuLyoqXG4gKiBDb21waWxlIHRoZSBwYXRoIHBhcmFtZXRlciBvZiBhIGZvcm1hdHRlciBjYWxsLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBiaW5kaW5nIHBhcnQgdG8gZXZhbHVhdGVcbiAqIEBwYXJhbSBzaW5nbGVQYXRoIFdoZXRoZXIgdGhlcmUgaXMgb25lIG9yIG11bHRpcGxlIHBhdGggdG8gY29uc2lkZXJcbiAqIEByZXR1cm5zIFRoZSBzdHJpbmcgc25pcHBldCB0byBpbmNsdWRlIGluIHRoZSBvdmVyYWxsIGJpbmRpbmcgZGVmaW5pdGlvblxuICovXG5mdW5jdGlvbiBjb21waWxlUGF0aFBhcmFtZXRlcihleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248YW55Piwgc2luZ2xlUGF0aCA9IGZhbHNlKTogc3RyaW5nIHtcblx0bGV0IG91dFZhbHVlID0gXCJcIjtcblx0aWYgKGV4cHJlc3Npb24uX3R5cGUgPT09IFwiQ29uc3RhbnRcIikge1xuXHRcdGlmIChleHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0XHRcdC8vIFNwZWNpYWwgY2FzZSBvdGhlcndpc2UgdGhlIEpTVG9rZW5pemVyIGNvbXBsYWlucyBhYm91dCBpbmNvcnJlY3QgY29udGVudFxuXHRcdFx0b3V0VmFsdWUgPSBgdmFsdWU6ICd1bmRlZmluZWQnYDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0b3V0VmFsdWUgPSBgdmFsdWU6ICR7Y29tcGlsZUNvbnN0YW50KGV4cHJlc3Npb24sIHRydWUpfWA7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKGV4cHJlc3Npb24uX3R5cGUgPT09IFwiUGF0aEluTW9kZWxcIikge1xuXHRcdG91dFZhbHVlID0gYHBhdGg6ICcke2NvbXBpbGVQYXRoSW5Nb2RlbChleHByZXNzaW9uKX0nYDtcblxuXHRcdG91dFZhbHVlICs9IGV4cHJlc3Npb24udHlwZSA/IGAsIHR5cGU6ICcke2V4cHJlc3Npb24udHlwZX0nYCA6IGAsIHRhcmdldFR5cGU6ICdhbnknYDtcblx0XHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5tb2RlKSkge1xuXHRcdFx0b3V0VmFsdWUgKz0gYCwgbW9kZTogJyR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5tb2RlKX0nYDtcblx0XHR9XG5cdFx0aWYgKGhhc0VsZW1lbnRzKGV4cHJlc3Npb24uY29uc3RyYWludHMpKSB7XG5cdFx0XHRvdXRWYWx1ZSArPSBgLCBjb25zdHJhaW50czogJHtjb21waWxlRXhwcmVzc2lvbihleHByZXNzaW9uLmNvbnN0cmFpbnRzKX1gO1xuXHRcdH1cblx0XHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKSkge1xuXHRcdFx0b3V0VmFsdWUgKz0gYCwgZm9ybWF0T3B0aW9uczogJHtjb21waWxlRXhwcmVzc2lvbihleHByZXNzaW9uLmZvcm1hdE9wdGlvbnMpfWA7XG5cdFx0fVxuXHRcdGlmIChoYXNFbGVtZW50cyhleHByZXNzaW9uLnBhcmFtZXRlcnMpKSB7XG5cdFx0XHRvdXRWYWx1ZSArPSBgLCBwYXJhbWV0ZXJzOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24ucGFyYW1ldGVycyl9YDtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIFwiXCI7XG5cdH1cblx0cmV0dXJuIHNpbmdsZVBhdGggPyBvdXRWYWx1ZSA6IGB7JHtvdXRWYWx1ZX19YDtcbn1cblxuZnVuY3Rpb24gaGFzRWxlbWVudHMob2JqOiBhbnkpIHtcblx0cmV0dXJuIG9iaiAmJiBPYmplY3Qua2V5cyhvYmopLmxlbmd0aCA+IDA7XG59XG5cbi8qKlxuICogQ29tcGlsZSBhIGJpbmRpbmcgZXhwcmVzc2lvbiBwYXRoLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGUuXG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgcGF0aC5cbiAqL1xuZnVuY3Rpb24gY29tcGlsZVBhdGhJbk1vZGVsPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihleHByZXNzaW9uOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4pIHtcblx0cmV0dXJuIGAke2V4cHJlc3Npb24ubW9kZWxOYW1lID8gYCR7ZXhwcmVzc2lvbi5tb2RlbE5hbWV9PmAgOiBcIlwifSR7ZXhwcmVzc2lvbi5wYXRofWA7XG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQTtBQUFBO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQTZLTyxJQUFNQSx1QkFBb0QsR0FBRztJQUNuRUMsS0FBSyxFQUFFO0VBRDRELENBQTdEOzs7RUFJUCxTQUFTQyxrQkFBVCxDQUE0QkMsV0FBNUIsRUFBaUQ7SUFDaEQsT0FBT0EsV0FBVyxDQUFDQyxPQUFaLENBQW9CLElBQXBCLEVBQTBCLEtBQTFCLENBQVA7RUFDQTs7RUFFTSxTQUFTQywwQkFBVCxHQUE4RjtJQUFBLGtDQUF2REMsV0FBdUQ7TUFBdkRBLFdBQXVEO0lBQUE7O0lBQ3BHLE9BQU9BLFdBQVcsQ0FBQ0MsSUFBWixDQUFpQixVQUFDQyxJQUFEO01BQUEsT0FBVUEsSUFBSSxDQUFDUCxLQUFMLEtBQWUsY0FBekI7SUFBQSxDQUFqQixNQUE4RFEsU0FBckU7RUFDQTtFQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0VBQ08sU0FBU0MseUJBQVQsQ0FBc0NDLENBQXRDLEVBQXNFQyxDQUF0RSxFQUErRztJQUNySCxJQUFJRCxDQUFDLENBQUNWLEtBQUYsS0FBWVcsQ0FBQyxDQUFDWCxLQUFsQixFQUF5QjtNQUN4QixPQUFPLEtBQVA7SUFDQTs7SUFFRCxRQUFRVSxDQUFDLENBQUNWLEtBQVY7TUFDQyxLQUFLLGNBQUw7UUFDQyxPQUFPLEtBQVA7TUFBYzs7TUFDZixLQUFLLFVBQUw7TUFDQSxLQUFLLGlCQUFMO01BQ0EsS0FBSywyQkFBTDtRQUNDLE9BQU9VLENBQUMsQ0FBQ0UsS0FBRixLQUFhRCxDQUFELENBQTZCQyxLQUFoRDs7TUFFRCxLQUFLLEtBQUw7UUFDQyxPQUFPSCx5QkFBeUIsQ0FBQ0MsQ0FBQyxDQUFDRyxPQUFILEVBQWFGLENBQUQsQ0FBcUJFLE9BQWpDLENBQWhDOztNQUNELEtBQUssUUFBTDtRQUNDLE9B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
|