@mediusinc/mng-commons 0.10.3-rc → 0.11.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/esm2020/lib/api/models/builders/query-param.builder.mjs +58 -58
- package/esm2020/lib/api/models/filter-match-type.model.mjs +24 -24
- package/esm2020/lib/api/models/filter-param.model.mjs +32 -32
- package/esm2020/lib/api/models/index.mjs +8 -8
- package/esm2020/lib/api/models/mappers.mjs +12 -12
- package/esm2020/lib/api/models/query-mode.model.mjs +17 -17
- package/esm2020/lib/api/models/query-param.model.mjs +67 -67
- package/esm2020/lib/api/models/query-result.model.mjs +17 -17
- package/esm2020/lib/api/models/serialization.model.mjs +1 -1
- package/esm2020/lib/api/services/api.abstract.service.mjs +55 -55
- package/esm2020/lib/api/services/crud-api.abstract.service.mjs +67 -67
- package/esm2020/lib/api/services/get-all-api.abstract.service.mjs +22 -22
- package/esm2020/lib/api/services/index.mjs +3 -3
- package/esm2020/lib/api/utils/index.mjs +2 -2
- package/esm2020/lib/api/utils/medius-rest.util.mjs +151 -151
- package/esm2020/lib/api/utils/object-serializer.util.mjs +243 -243
- package/esm2020/lib/components/action/action.component.mjs +199 -199
- package/esm2020/lib/components/action/editor/action-editor.component.mjs +247 -247
- package/esm2020/lib/components/action/index.mjs +3 -3
- package/esm2020/lib/components/action/models/action-confirmation-service.model.mjs +1 -1
- package/esm2020/lib/components/action/models/action-execution.model.mjs +235 -235
- package/esm2020/lib/components/action/models/index.mjs +2 -2
- package/esm2020/lib/components/action/route/action-route.component.mjs +124 -124
- package/esm2020/lib/components/form/autocomplete/autocomplete.component.mjs +277 -277
- package/esm2020/lib/components/form/dropdown/dropdown.component.mjs +168 -168
- package/esm2020/lib/components/form/editor/form-editor.component.mjs +212 -212
- package/esm2020/lib/components/form/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.mjs +48 -48
- package/esm2020/lib/components/form/formly/fields/formly-field-dropdown/formly-field-dropdown.component.mjs +43 -43
- package/esm2020/lib/components/form/formly/fields/formly-field-fieldset/formly-field-fieldset.component.mjs +25 -25
- package/esm2020/lib/components/form/formly/fields/formly-field-input/formly-field-input.component.mjs +102 -102
- package/esm2020/lib/components/form/formly/fields/formly-field-label/formly-field-label.component.mjs +22 -22
- package/esm2020/lib/components/form/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.mjs +179 -179
- package/esm2020/lib/components/form/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.mjs +173 -173
- package/esm2020/lib/components/form/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.mjs +150 -155
- package/esm2020/lib/components/form/formly/fields/formly-field-tabs/formly-field-tabs.component.mjs +17 -17
- package/esm2020/lib/components/form/formly/fields/index.mjs +9 -9
- package/esm2020/lib/components/form/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.mjs +14 -14
- package/esm2020/lib/components/form/formly/wrappers/formly-table-wrapper/formly-table-wrapper.component.mjs +14 -14
- package/esm2020/lib/components/form/formly/wrappers/index.mjs +2 -2
- package/esm2020/lib/components/form/index.mjs +3 -3
- package/esm2020/lib/components/form/models/form-editor.event.mjs +33 -33
- package/esm2020/lib/components/form/models/index.mjs +1 -1
- package/esm2020/lib/components/layout/breadcrumb.component.mjs +16 -16
- package/esm2020/lib/components/layout/footer.component.mjs +16 -16
- package/esm2020/lib/components/layout/index.mjs +7 -7
- package/esm2020/lib/components/layout/main-layout.component.mjs +51 -51
- package/esm2020/lib/components/layout/menu-item.component.mjs +238 -238
- package/esm2020/lib/components/layout/menu.component.mjs +20 -20
- package/esm2020/lib/components/layout/services/index.mjs +1 -1
- package/esm2020/lib/components/layout/services/main-layout.component.service.mjs +192 -192
- package/esm2020/lib/components/layout/topbar.component.mjs +57 -57
- package/esm2020/lib/components/layout/version.component.mjs +57 -57
- package/esm2020/lib/components/tableview/index.mjs +6 -6
- package/esm2020/lib/components/tableview/models/index.mjs +1 -1
- package/esm2020/lib/components/tableview/models/table.event.mjs +15 -15
- package/esm2020/lib/components/tableview/route/tableview-route.abstract.component.mjs +57 -57
- package/esm2020/lib/components/tableview/route/tableview-route.component.mjs +60 -60
- package/esm2020/lib/components/tableview/table/column-filter/column-filter.component.mjs +101 -101
- package/esm2020/lib/components/tableview/table/column-value/column-value.component.mjs +70 -70
- package/esm2020/lib/components/tableview/table/table.component.mjs +497 -497
- package/esm2020/lib/components/tableview/tableview.component.mjs +91 -91
- package/esm2020/lib/config/formly.config.mjs +181 -181
- package/esm2020/lib/config/index.mjs +1 -1
- package/esm2020/lib/config/models/index.mjs +3 -2
- package/esm2020/lib/config/models/mng-config.model.mjs +1 -1
- package/esm2020/lib/config/models/mng-formly-config-model.mjs +2 -0
- package/esm2020/lib/data-providers/base.data-provider.mjs +16 -16
- package/esm2020/lib/data-providers/editor.data-provider.mjs +36 -36
- package/esm2020/lib/data-providers/index.mjs +5 -5
- package/esm2020/lib/data-providers/lookup.data-provider.mjs +15 -15
- package/esm2020/lib/data-providers/table.data-provider.mjs +16 -16
- package/esm2020/lib/data-providers/tableview.data-provider.mjs +16 -16
- package/esm2020/lib/descriptors/action.descriptor.mjs +587 -587
- package/esm2020/lib/descriptors/column.descriptor.mjs +264 -264
- package/esm2020/lib/descriptors/editor.descriptor.mjs +146 -146
- package/esm2020/lib/descriptors/field-validation.descriptor.mjs +20 -20
- package/esm2020/lib/descriptors/field.descriptor.mjs +819 -819
- package/esm2020/lib/descriptors/filter.descriptor.mjs +288 -288
- package/esm2020/lib/descriptors/index.mjs +9 -9
- package/esm2020/lib/descriptors/interfaces/field-config.interface.mjs +1 -1
- package/esm2020/lib/descriptors/interfaces/index.mjs +2 -2
- package/esm2020/lib/descriptors/interfaces/lookup-descriptor.interface.mjs +1 -1
- package/esm2020/lib/descriptors/model.descriptor.mjs +33 -33
- package/esm2020/lib/descriptors/table.descriptor.mjs +197 -197
- package/esm2020/lib/descriptors/tableview.descriptor.mjs +134 -134
- package/esm2020/lib/descriptors/types/action.type.mjs +52 -52
- package/esm2020/lib/descriptors/types/column.type.mjs +10 -10
- package/esm2020/lib/descriptors/types/editor.type.mjs +7 -7
- package/esm2020/lib/descriptors/types/field.type.mjs +52 -52
- package/esm2020/lib/descriptors/types/filter.type.mjs +30 -30
- package/esm2020/lib/descriptors/types/index.mjs +6 -6
- package/esm2020/lib/descriptors/types/table.type.mjs +16 -16
- package/esm2020/lib/directives/component.directive.mjs +43 -43
- package/esm2020/lib/directives/index.mjs +2 -2
- package/esm2020/lib/directives/template.directive.mjs +27 -27
- package/esm2020/lib/mng-commons.module.mjs +441 -441
- package/esm2020/lib/models/column-value.model.mjs +1 -1
- package/esm2020/lib/models/enum.model.mjs +1 -1
- package/esm2020/lib/models/error.model.mjs +1 -1
- package/esm2020/lib/models/formly-field.model.mjs +2 -0
- package/esm2020/lib/models/index.mjs +9 -8
- package/esm2020/lib/models/menu.model.mjs +1 -1
- package/esm2020/lib/models/user.model.mjs +1 -1
- package/esm2020/lib/models/version.model.mjs +1 -1
- package/esm2020/lib/models/view-container.model.mjs +1 -1
- package/esm2020/lib/pipes/boolean.pipe.mjs +26 -26
- package/esm2020/lib/pipes/enum.pipe.mjs +24 -24
- package/esm2020/lib/pipes/i18n-property.pipe.mjs +17 -17
- package/esm2020/lib/pipes/index.mjs +5 -5
- package/esm2020/lib/pipes/json-path.pipe.mjs +79 -79
- package/esm2020/lib/pipes/link-formatter.pipe.mjs +38 -38
- package/esm2020/lib/router/index.mjs +2 -2
- package/esm2020/lib/router/models/index.mjs +1 -1
- package/esm2020/lib/router/models/router.model.mjs +1 -1
- package/esm2020/lib/router/route-builder.mjs +425 -425
- package/esm2020/lib/router/tableview-route-builder.mjs +159 -159
- package/esm2020/lib/security/authorization.guard.mjs +25 -25
- package/esm2020/lib/security/authorization.service.mjs +46 -46
- package/esm2020/lib/security/authorization.util.mjs +15 -15
- package/esm2020/lib/security/index.mjs +3 -3
- package/esm2020/lib/security/model/authorization.type.mjs +7 -7
- package/esm2020/lib/security/model/index.mjs +3 -3
- package/esm2020/lib/security/model/permission-service.interface.mjs +1 -1
- package/esm2020/lib/security/model/permissions.model.mjs +94 -94
- package/esm2020/lib/services/action-executor.service.mjs +535 -535
- package/esm2020/lib/services/commons.service.mjs +342 -342
- package/esm2020/lib/services/configuration.service.mjs +110 -110
- package/esm2020/lib/services/error-mapper.service.mjs +13 -13
- package/esm2020/lib/services/index.mjs +6 -6
- package/esm2020/lib/services/internal/commons-init.provider.mjs +3 -3
- package/esm2020/lib/services/internal/commons-init.service.mjs +43 -43
- package/esm2020/lib/services/internal/index.mjs +2 -2
- package/esm2020/lib/services/navigation.service.mjs +47 -47
- package/esm2020/lib/services/providers/config-service.provider.mjs +29 -29
- package/esm2020/lib/services/providers/formly-config.provider.mjs +30 -30
- package/esm2020/lib/services/providers/index.mjs +2 -2
- package/esm2020/lib/services/tokens/browser-storage.token.mjs +5 -5
- package/esm2020/lib/services/tokens/commons-init.token.mjs +2 -2
- package/esm2020/lib/services/tokens/default-setting.token.mjs +2 -2
- package/esm2020/lib/services/tokens/index.mjs +4 -4
- package/esm2020/lib/services/tokens/module-config.token.mjs +2 -2
- package/esm2020/lib/services/version.service.mjs +38 -38
- package/esm2020/lib/services/view-container.component.service.mjs +34 -34
- package/esm2020/lib/types/index.mjs +2 -2
- package/esm2020/lib/types/type.decorator.mjs +12 -12
- package/esm2020/lib/types/type.model.mjs +1 -1
- package/esm2020/lib/utils/action-data-provider.util.mjs +144 -144
- package/esm2020/lib/utils/editor-formly.util.mjs +251 -243
- package/esm2020/lib/utils/enum.util.mjs +81 -81
- package/esm2020/lib/utils/i18n.util.mjs +232 -232
- package/esm2020/lib/utils/index.mjs +7 -7
- package/esm2020/lib/utils/model.util.mjs +59 -59
- package/esm2020/lib/utils/notification.util.mjs +45 -45
- package/esm2020/lib/utils/route.util.mjs +23 -23
- package/esm2020/lib/utils/styles.util.mjs +40 -40
- package/esm2020/lib/utils/type.util.mjs +76 -76
- package/esm2020/mediusinc-mng-commons.mjs +4 -4
- package/esm2020/public-api.mjs +51 -51
- package/fesm2015/mediusinc-mng-commons.mjs +10636 -10637
- package/fesm2015/mediusinc-mng-commons.mjs.map +1 -1
- package/fesm2020/mediusinc-mng-commons.mjs +10489 -10486
- package/fesm2020/mediusinc-mng-commons.mjs.map +1 -1
- package/lib/api/models/builders/query-param.builder.d.ts +13 -13
- package/lib/api/models/filter-match-type.model.d.ts +23 -23
- package/lib/api/models/filter-param.model.d.ts +23 -23
- package/lib/api/models/index.d.ts +8 -8
- package/lib/api/models/mappers.d.ts +6 -6
- package/lib/api/models/query-mode.model.d.ts +16 -16
- package/lib/api/models/query-param.model.d.ts +31 -31
- package/lib/api/models/query-result.model.d.ts +23 -23
- package/lib/api/models/serialization.model.d.ts +8 -8
- package/lib/api/services/api.abstract.service.d.ts +24 -24
- package/lib/api/services/crud-api.abstract.service.d.ts +22 -22
- package/lib/api/services/get-all-api.abstract.service.d.ts +14 -14
- package/lib/api/services/index.d.ts +3 -3
- package/lib/api/utils/index.d.ts +2 -2
- package/lib/api/utils/medius-rest.util.d.ts +15 -15
- package/lib/api/utils/object-serializer.util.d.ts +33 -33
- package/lib/components/action/action.component.d.ts +75 -75
- package/lib/components/action/editor/action-editor.component.d.ts +64 -64
- package/lib/components/action/index.d.ts +3 -3
- package/lib/components/action/models/action-confirmation-service.model.d.ts +6 -6
- package/lib/components/action/models/action-execution.model.d.ts +129 -129
- package/lib/components/action/models/index.d.ts +2 -2
- package/lib/components/action/route/action-route.component.d.ts +31 -31
- package/lib/components/form/autocomplete/autocomplete.component.d.ts +56 -56
- package/lib/components/form/dropdown/dropdown.component.d.ts +47 -47
- package/lib/components/form/editor/form-editor.component.d.ts +45 -45
- package/lib/components/form/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.d.ts +15 -15
- package/lib/components/form/formly/fields/formly-field-dropdown/formly-field-dropdown.component.d.ts +14 -14
- package/lib/components/form/formly/fields/formly-field-fieldset/formly-field-fieldset.component.d.ts +13 -13
- package/lib/components/form/formly/fields/formly-field-input/formly-field-input.component.d.ts +23 -23
- package/lib/components/form/formly/fields/formly-field-label/formly-field-label.component.d.ts +10 -10
- package/lib/components/form/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.d.ts +45 -45
- package/lib/components/form/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.d.ts +23 -23
- package/lib/components/form/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.d.ts +38 -38
- package/lib/components/form/formly/fields/formly-field-tabs/formly-field-tabs.component.d.ts +6 -6
- package/lib/components/form/formly/fields/index.d.ts +9 -9
- package/lib/components/form/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.d.ts +6 -6
- package/lib/components/form/formly/wrappers/formly-table-wrapper/formly-table-wrapper.component.d.ts +6 -6
- package/lib/components/form/formly/wrappers/index.d.ts +2 -2
- package/lib/components/form/index.d.ts +3 -3
- package/lib/components/form/models/form-editor.event.d.ts +37 -37
- package/lib/components/form/models/index.d.ts +1 -1
- package/lib/components/layout/breadcrumb.component.d.ts +8 -8
- package/lib/components/layout/footer.component.d.ts +9 -9
- package/lib/components/layout/index.d.ts +7 -7
- package/lib/components/layout/main-layout.component.d.ts +20 -20
- package/lib/components/layout/menu-item.component.d.ts +44 -44
- package/lib/components/layout/menu.component.d.ts +10 -10
- package/lib/components/layout/services/index.d.ts +1 -1
- package/lib/components/layout/services/main-layout.component.service.d.ts +65 -65
- package/lib/components/layout/topbar.component.d.ts +24 -24
- package/lib/components/layout/version.component.d.ts +19 -19
- package/lib/components/tableview/index.d.ts +6 -6
- package/lib/components/tableview/models/index.d.ts +1 -1
- package/lib/components/tableview/models/table.event.d.ts +17 -17
- package/lib/components/tableview/route/tableview-route.abstract.component.d.ts +20 -20
- package/lib/components/tableview/route/tableview-route.component.d.ts +23 -23
- package/lib/components/tableview/table/column-filter/column-filter.component.d.ts +32 -32
- package/lib/components/tableview/table/column-value/column-value.component.d.ts +29 -29
- package/lib/components/tableview/table/table.component.d.ts +108 -108
- package/lib/components/tableview/tableview.component.d.ts +41 -41
- package/lib/config/formly.config.d.ts +16 -15
- package/lib/config/index.d.ts +1 -1
- package/lib/config/models/index.d.ts +2 -1
- package/lib/config/models/mng-config.model.d.ts +36 -36
- package/lib/config/models/mng-formly-config-model.d.ts +17 -0
- package/lib/data-providers/base.data-provider.d.ts +14 -14
- package/lib/data-providers/editor.data-provider.d.ts +25 -25
- package/lib/data-providers/index.d.ts +5 -5
- package/lib/data-providers/lookup.data-provider.d.ts +14 -14
- package/lib/data-providers/table.data-provider.d.ts +14 -14
- package/lib/data-providers/tableview.data-provider.d.ts +15 -15
- package/lib/descriptors/action.descriptor.d.ts +234 -234
- package/lib/descriptors/column.descriptor.d.ts +82 -82
- package/lib/descriptors/editor.descriptor.d.ts +37 -37
- package/lib/descriptors/field-validation.descriptor.d.ts +18 -18
- package/lib/descriptors/field.descriptor.d.ts +300 -294
- package/lib/descriptors/filter.descriptor.d.ts +106 -106
- package/lib/descriptors/index.d.ts +9 -9
- package/lib/descriptors/interfaces/field-config.interface.d.ts +9 -9
- package/lib/descriptors/interfaces/index.d.ts +2 -2
- package/lib/descriptors/interfaces/lookup-descriptor.interface.d.ts +17 -17
- package/lib/descriptors/model.descriptor.d.ts +15 -15
- package/lib/descriptors/table.descriptor.d.ts +66 -66
- package/lib/descriptors/tableview.descriptor.d.ts +42 -42
- package/lib/descriptors/types/action.type.d.ts +45 -45
- package/lib/descriptors/types/column.type.d.ts +9 -9
- package/lib/descriptors/types/editor.type.d.ts +6 -6
- package/lib/descriptors/types/field.type.d.ts +44 -44
- package/lib/descriptors/types/filter.type.d.ts +27 -27
- package/lib/descriptors/types/index.d.ts +6 -6
- package/lib/descriptors/types/table.type.d.ts +13 -13
- package/lib/directives/component.directive.d.ts +16 -16
- package/lib/directives/index.d.ts +2 -2
- package/lib/directives/template.directive.d.ts +13 -13
- package/lib/mng-commons.module.d.ts +87 -87
- package/lib/models/column-value.model.d.ts +4 -4
- package/lib/models/enum.model.d.ts +6 -6
- package/lib/models/error.model.d.ts +14 -14
- package/lib/models/formly-field.model.d.ts +16 -0
- package/lib/models/index.d.ts +8 -7
- package/lib/models/menu.model.d.ts +27 -27
- package/lib/models/user.model.d.ts +8 -8
- package/lib/models/version.model.d.ts +18 -18
- package/lib/models/view-container.model.d.ts +6 -6
- package/lib/pipes/boolean.pipe.d.ts +7 -7
- package/lib/pipes/enum.pipe.d.ts +8 -8
- package/lib/pipes/i18n-property.pipe.d.ts +8 -8
- package/lib/pipes/index.d.ts +5 -5
- package/lib/pipes/json-path.pipe.d.ts +13 -13
- package/lib/pipes/link-formatter.pipe.d.ts +11 -11
- package/lib/router/index.d.ts +2 -2
- package/lib/router/models/index.d.ts +1 -1
- package/lib/router/models/router.model.d.ts +27 -27
- package/lib/router/route-builder.d.ts +98 -98
- package/lib/router/tableview-route-builder.d.ts +34 -34
- package/lib/security/authorization.guard.d.ts +11 -11
- package/lib/security/authorization.service.d.ts +19 -19
- package/lib/security/authorization.util.d.ts +5 -5
- package/lib/security/index.d.ts +3 -3
- package/lib/security/model/authorization.type.d.ts +6 -6
- package/lib/security/model/index.d.ts +3 -3
- package/lib/security/model/permission-service.interface.d.ts +6 -6
- package/lib/security/model/permissions.model.d.ts +44 -44
- package/lib/services/action-executor.service.d.ts +149 -149
- package/lib/services/commons.service.d.ts +78 -78
- package/lib/services/configuration.service.d.ts +36 -36
- package/lib/services/error-mapper.service.d.ts +7 -7
- package/lib/services/index.d.ts +6 -6
- package/lib/services/internal/commons-init.provider.d.ts +3 -3
- package/lib/services/internal/commons-init.service.d.ts +16 -16
- package/lib/services/internal/index.d.ts +2 -2
- package/lib/services/navigation.service.d.ts +14 -14
- package/lib/services/providers/config-service.provider.d.ts +6 -6
- package/lib/services/providers/formly-config.provider.d.ts +4 -4
- package/lib/services/providers/index.d.ts +2 -2
- package/lib/services/tokens/browser-storage.token.d.ts +2 -2
- package/lib/services/tokens/commons-init.token.d.ts +3 -3
- package/lib/services/tokens/default-setting.token.d.ts +2 -2
- package/lib/services/tokens/index.d.ts +4 -4
- package/lib/services/tokens/module-config.token.d.ts +3 -3
- package/lib/services/version.service.d.ts +13 -13
- package/lib/services/view-container.component.service.d.ts +22 -22
- package/lib/types/index.d.ts +2 -2
- package/lib/types/type.decorator.d.ts +4 -4
- package/lib/types/type.model.d.ts +23 -23
- package/lib/utils/action-data-provider.util.d.ts +20 -20
- package/lib/utils/editor-formly.util.d.ts +11 -11
- package/lib/utils/enum.util.d.ts +50 -50
- package/lib/utils/i18n.util.d.ts +56 -56
- package/lib/utils/index.d.ts +7 -7
- package/lib/utils/model.util.d.ts +8 -8
- package/lib/utils/notification.util.d.ts +11 -11
- package/lib/utils/route.util.d.ts +4 -4
- package/lib/utils/styles.util.d.ts +14 -14
- package/lib/utils/type.util.d.ts +36 -36
- package/mediusinc-mng-commons.d.ts +5 -5
- package/package.json +2 -2
- package/public-api.d.ts +32 -32
- package/version-info.json +6 -6
- package/mediusinc-mng-commons-0.10.3-rc.tgz +0 -0
|
@@ -1,536 +1,536 @@
|
|
|
1
|
-
import { HttpErrorResponse } from '@angular/common/http';
|
|
2
|
-
import { Inject, Injectable } from '@angular/core';
|
|
3
|
-
import { from, mergeMap, of, switchMap, throwError } from 'rxjs';
|
|
4
|
-
import { catchError, filter, first, map } from 'rxjs/operators';
|
|
5
|
-
import { ActionContext, ActionContextValidation, ActionInstance, ActionInstanceStateEnum, ActionParameters } from '../components/action/models';
|
|
6
|
-
import { ActionEditorDescriptor } from '../descriptors';
|
|
7
|
-
import { ActionActivationTriggerEnum, ActionEditorDialogSizeEnum, ActionTypeEnum } from '../descriptors/types';
|
|
8
|
-
import { I18nUtils, NotificationUtil } from '../utils';
|
|
9
|
-
import { ACTION_EDITOR_DIALOG_COMPONENT_SETTING } from './tokens';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
import * as i1 from "@angular/router";
|
|
12
|
-
import * as i2 from "primeng/dynamicdialog";
|
|
13
|
-
import * as i3 from "primeng/api";
|
|
14
|
-
import * as i4 from "@ngx-translate/core";
|
|
15
|
-
import * as i5 from "./configuration.service";
|
|
16
|
-
import * as i6 from "./navigation.service";
|
|
17
|
-
import * as i7 from "./error-mapper.service";
|
|
18
|
-
import * as i8 from "../pipes";
|
|
19
|
-
export class MngActionExecutorService {
|
|
20
|
-
constructor(injector, router, dialogService, confirmationService, translate, configurationService, navigationService, errorMapper, linkFormatter, defaultEditorDialogComponent) {
|
|
21
|
-
this.injector = injector;
|
|
22
|
-
this.router = router;
|
|
23
|
-
this.dialogService = dialogService;
|
|
24
|
-
this.confirmationService = confirmationService;
|
|
25
|
-
this.translate = translate;
|
|
26
|
-
this.configurationService = configurationService;
|
|
27
|
-
this.navigationService = navigationService;
|
|
28
|
-
this.errorMapper = errorMapper;
|
|
29
|
-
this.linkFormatter = linkFormatter;
|
|
30
|
-
this.defaultEditorDialogComponent = defaultEditorDialogComponent;
|
|
31
|
-
this.debug = false;
|
|
32
|
-
// this.debug = true;
|
|
33
|
-
}
|
|
34
|
-
prepareActionContextValidation(action, parameters, dataProvider) {
|
|
35
|
-
const ctxDataProvider = dataProvider ?? action.dataProvider ?? parameters.viewContainer?.getDataProvider();
|
|
36
|
-
const ctx = new ActionContextValidation(action, parameters, ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
|
|
37
|
-
return ctx;
|
|
38
|
-
}
|
|
39
|
-
prepareActionContext(instance, parameters, dataProvider, previousActionInstance) {
|
|
40
|
-
const ctxDataProvider = dataProvider ?? instance.action.dataProvider ?? parameters.viewContainer?.getDataProvider();
|
|
41
|
-
const ctx = new ActionContext(instance, parameters, 'run', ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
|
|
42
|
-
ctx.previousActionInstance = previousActionInstance;
|
|
43
|
-
instance.newContext(ctx);
|
|
44
|
-
return ctx;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Prepares action exec context for action of type editor.
|
|
48
|
-
*
|
|
49
|
-
* @param item Item instance (if exists).
|
|
50
|
-
* @param itemId Item id (if exists).
|
|
51
|
-
* @param dataProvider Data provider.
|
|
52
|
-
* @param sourceComponent Source component from where the context preparation was called.
|
|
53
|
-
* @param viewContainer View container/service.
|
|
54
|
-
* @param actionData Additional action data.
|
|
55
|
-
*/
|
|
56
|
-
prepareContextForEditor(instance, parameters, functionName, dataProvider, previousActionInstance) {
|
|
57
|
-
const editorAction = instance.action;
|
|
58
|
-
let ctxDataProvider = dataProvider;
|
|
59
|
-
if (!ctxDataProvider && editorAction.dataProvider) {
|
|
60
|
-
ctxDataProvider = editorAction.dataProvider;
|
|
61
|
-
}
|
|
62
|
-
if (!ctxDataProvider) {
|
|
63
|
-
const viewContainerDataProvider = parameters.viewContainer?.getDataProvider();
|
|
64
|
-
if (viewContainerDataProvider) {
|
|
65
|
-
ctxDataProvider = viewContainerDataProvider;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
const ctx = new ActionContext(instance, parameters, functionName, ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
|
|
69
|
-
ctx.previousActionInstance = previousActionInstance;
|
|
70
|
-
instance.newContext(ctx);
|
|
71
|
-
return ctx;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Runs action context by submitting execution results/errors to context, watching over instance results/errors, displaying notifications,
|
|
75
|
-
* running next/error action and triggering dismiss of action.
|
|
76
|
-
*
|
|
77
|
-
* @param action Action descriptor.
|
|
78
|
-
* @param parameters Action parameters for context.
|
|
79
|
-
* @param dataProvider Editor data provider for context.
|
|
80
|
-
* @param instance Optional existing action instance (if non provided, new will be created).
|
|
81
|
-
* @param previousActionInstance Optional previous action instance to link in next instance.
|
|
82
|
-
*
|
|
83
|
-
* @return Action context for submit (=run) function.
|
|
84
|
-
*/
|
|
85
|
-
runActionContext(ctx) {
|
|
86
|
-
const isMainRunFn = ctx.functionName === 'submit' || ctx.functionName === 'run';
|
|
87
|
-
let actionEditor;
|
|
88
|
-
let fnObs;
|
|
89
|
-
switch (ctx.functionName) {
|
|
90
|
-
case 'submit':
|
|
91
|
-
actionEditor = ctx.instance.action;
|
|
92
|
-
if (typeof actionEditor.submitFunction !== 'function') {
|
|
93
|
-
return throwError(() => new Error(`Submit function for action ${actionEditor.actionNameLong} cannot be invoked.`));
|
|
94
|
-
}
|
|
95
|
-
fnObs = actionEditor.submitFunction;
|
|
96
|
-
break;
|
|
97
|
-
case 'fetch':
|
|
98
|
-
actionEditor = ctx.instance.action;
|
|
99
|
-
fnObs = actionEditor.fetchFunction;
|
|
100
|
-
break;
|
|
101
|
-
case 'run':
|
|
102
|
-
default:
|
|
103
|
-
fnObs = ctx.instance.action.runFunction;
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
const retObs = of(void 0).pipe(first(), switchMap(() => {
|
|
107
|
-
if (isMainRunFn) {
|
|
108
|
-
// if main run function, also set loading to true
|
|
109
|
-
ctx.instance.state = ActionInstanceStateEnum.RunStart;
|
|
110
|
-
ctx.instance.isRunLoadingSubject.next(true);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
ctx.instance.state = ActionInstanceStateEnum.FetchStart;
|
|
114
|
-
}
|
|
115
|
-
// start context execution to mark execution loading
|
|
116
|
-
ctx.executionStart();
|
|
117
|
-
return fnObs(ctx);
|
|
118
|
-
}), mergeMap(runResult => {
|
|
119
|
-
// set next state depending on run
|
|
120
|
-
ctx.instance.state = isMainRunFn ? ActionInstanceStateEnum.RunEnd : ActionInstanceStateEnum.FetchEnd;
|
|
121
|
-
// set execution result
|
|
122
|
-
ctx.executionNext(runResult, isMainRunFn);
|
|
123
|
-
if (isMainRunFn) {
|
|
124
|
-
// set instance final result on main run execution
|
|
125
|
-
ctx.instance.result = runResult;
|
|
126
|
-
ctx.instance.isRunLoadingSubject.next(false);
|
|
127
|
-
// handle notification
|
|
128
|
-
if (ctx.instance.action.hasRunNotificationSuccess) {
|
|
129
|
-
ctx.notification = NotificationUtil.actionNotificationSuccess(this.translate, ctx.instance.action, ctx.functionName, ctx.instance.action.runNotificationSuccessTitle, ctx.instance.action.runNotificationSuccessMessage, ctx.parameters.viewContainer ?? undefined, ctx.parameters?.item);
|
|
130
|
-
}
|
|
131
|
-
// handle possible after run action
|
|
132
|
-
if (ctx.instance.action.afterRunAction) {
|
|
133
|
-
// mark new state for next action start
|
|
134
|
-
ctx.instance.state = ActionInstanceStateEnum.NextActionStart;
|
|
135
|
-
const nextActionInstance = this.activateAction(ctx.instance.action.afterRunAction, new ActionParameters(ctx.parameters.itemId, runResult)
|
|
136
|
-
.withActionData(ctx.parameters.actionData)
|
|
137
|
-
.withRoute(ctx.parameters.route)
|
|
138
|
-
.withSourceComponent(ctx.parameters.sourceComponent)
|
|
139
|
-
.withViewContainer(ctx.parameters.viewContainer), undefined, ctx.instance);
|
|
140
|
-
ctx.instance.nextActionInstance = nextActionInstance;
|
|
141
|
-
// finish current action when next action finishes
|
|
142
|
-
return nextActionInstance.state$.pipe(filter(state => state >= ActionInstanceStateEnum.FinishSuccess), map(() => {
|
|
143
|
-
ctx.instance.state = ActionInstanceStateEnum.NextActionEnd;
|
|
144
|
-
return runResult;
|
|
145
|
-
}));
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return of(runResult);
|
|
149
|
-
}), map(runResult => {
|
|
150
|
-
if (isMainRunFn) {
|
|
151
|
-
// deactivate action
|
|
152
|
-
this.deactivateAction(ctx.instance);
|
|
153
|
-
}
|
|
154
|
-
return runResult;
|
|
155
|
-
}), catchError(err => {
|
|
156
|
-
// transform error to mng action error
|
|
157
|
-
const actionError = this.toMngActionError(err);
|
|
158
|
-
// set instance state to error
|
|
159
|
-
ctx.instance.state = isMainRunFn ? ActionInstanceStateEnum.RunError : ActionInstanceStateEnum.FetchError;
|
|
160
|
-
// mark execution error on context
|
|
161
|
-
ctx.executionError(actionError);
|
|
162
|
-
let errorObs = of(void 0);
|
|
163
|
-
if (isMainRunFn) {
|
|
164
|
-
ctx.instance.error = err;
|
|
165
|
-
ctx.instance.isRunLoadingSubject.next(false);
|
|
166
|
-
// handle error notification
|
|
167
|
-
if (ctx.instance.action.hasRunNotificationError) {
|
|
168
|
-
actionError.notification = NotificationUtil.actionNotificationError(this.translate, ctx.instance.action, actionError, ctx.functionName, ctx.parameters.viewContainer ?? undefined, ctx.parameters.item);
|
|
169
|
-
}
|
|
170
|
-
// handle possible error action if run
|
|
171
|
-
if (isMainRunFn && ctx.instance.action.onRunErrorAction) {
|
|
172
|
-
// cannot start with trigger, because routing might be problematic (lousing previous results etc.)
|
|
173
|
-
const errorActionInstance = this.activateAction(ctx.instance.action.onRunErrorAction, new ActionParameters(ctx.parameters.itemId, ctx.parameters.item)
|
|
174
|
-
.withActionData(ctx.parameters.actionData)
|
|
175
|
-
.withRoute(ctx.parameters.route)
|
|
176
|
-
.withSourceComponent(ctx.parameters.sourceComponent)
|
|
177
|
-
.withViewContainer(ctx.parameters.viewContainer));
|
|
178
|
-
ctx.instance.errorActionInstance = errorActionInstance;
|
|
179
|
-
errorObs = errorActionInstance.state$.pipe(filter(state => state >= ActionInstanceStateEnum.FinishSuccess), map(() => void 0));
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
// liste and map only to mark instance state as finished error state
|
|
183
|
-
return errorObs.pipe(map(() => {
|
|
184
|
-
// deactivate action
|
|
185
|
-
this.deactivateAction(ctx.instance);
|
|
186
|
-
// rethrow error to propagate furher
|
|
187
|
-
throw actionError;
|
|
188
|
-
}));
|
|
189
|
-
}));
|
|
190
|
-
retObs.subscribe({
|
|
191
|
-
next: res => {
|
|
192
|
-
if (this.debug) {
|
|
193
|
-
console.debug(`ActionContext ${ctx.contextLongName} execution next event`, res);
|
|
194
|
-
}
|
|
195
|
-
},
|
|
196
|
-
error: err => {
|
|
197
|
-
if (this.debug) {
|
|
198
|
-
console.debug(`ActionContext ${ctx.contextLongName} execution error event`, err);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
return retObs;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Runs editor action's submit (=main run) function by creating new action context for action instance.
|
|
206
|
-
*
|
|
207
|
-
* @param action Action descriptor.
|
|
208
|
-
* @param parameters Action parameters for context.
|
|
209
|
-
* @param dataProvider Editor data provider for context.
|
|
210
|
-
* @param instance Optional existing action instance (if non provided, new will be created).
|
|
211
|
-
* @param previousActionInstance Optional previous action instance to link in next instance.
|
|
212
|
-
*
|
|
213
|
-
* @return Action context for submit (=run) function.
|
|
214
|
-
*/
|
|
215
|
-
runEditorSave(action, parameters, dataProvider, instance, previousActionInstance) {
|
|
216
|
-
if (!instance) {
|
|
217
|
-
// create new instance if non provided
|
|
218
|
-
instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
|
|
219
|
-
}
|
|
220
|
-
const context = this.prepareContextForEditor(instance, parameters, 'submit', dataProvider, previousActionInstance);
|
|
221
|
-
this.runActionContext(context);
|
|
222
|
-
return context;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Gets service instance of data provider.
|
|
226
|
-
*
|
|
227
|
-
* @param dataProvider Data provider instance.
|
|
228
|
-
*/
|
|
229
|
-
getDataProviderService(dataProvider) {
|
|
230
|
-
if (dataProvider?.serviceType) {
|
|
231
|
-
return this.injector.get(dataProvider.serviceType);
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
return null;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Runs editor action's fetch function by creating new action context for action instance.
|
|
239
|
-
*
|
|
240
|
-
* @param action Action descriptor.
|
|
241
|
-
* @param parameters Action parameters for context.
|
|
242
|
-
* @param dataProvider Editor data provider for context.
|
|
243
|
-
* @param instance Optional existing action instance (if non provided, new will be created).
|
|
244
|
-
* @param previousActionInstance Optional previous action instance to link in next instance.
|
|
245
|
-
*
|
|
246
|
-
* @return Action context for fetch function.
|
|
247
|
-
*/
|
|
248
|
-
runEditorFetch(action, parameters, dataProvider, instance, previousActionInstance) {
|
|
249
|
-
if (!instance) {
|
|
250
|
-
// create new instance if non provided
|
|
251
|
-
instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
|
|
252
|
-
}
|
|
253
|
-
const context = this.prepareContextForEditor(instance, parameters, 'fetch', dataProvider, previousActionInstance);
|
|
254
|
-
this.runActionContext(context);
|
|
255
|
-
return context;
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Runs action's main run function by creating new action context for action instance.
|
|
259
|
-
*
|
|
260
|
-
* @param action Action descriptor.
|
|
261
|
-
* @param parameters Action parameters for context run.
|
|
262
|
-
* @param dataProvider Data provider for context run.
|
|
263
|
-
* @param instance Optional existing action instance (if non provided, new will be created).
|
|
264
|
-
* @param previousActionInstance Optional previous action instance to link in next instance.
|
|
265
|
-
*
|
|
266
|
-
* @return Action context for run function.
|
|
267
|
-
*/
|
|
268
|
-
runAction(action, parameters, dataProvider, instance, previousActionInstance) {
|
|
269
|
-
if (!instance) {
|
|
270
|
-
// create new instance if non provided
|
|
271
|
-
instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
|
|
272
|
-
}
|
|
273
|
-
const context = this.prepareActionContext(instance, parameters, dataProvider, previousActionInstance);
|
|
274
|
-
if (action.hasRunConfirmation) {
|
|
275
|
-
const sourceComponent = parameters?.sourceComponent;
|
|
276
|
-
if (typeof sourceComponent?.getConfirmationService !== 'function' || typeof sourceComponent?.getConfirmationServiceInstanceKey !== 'function') {
|
|
277
|
-
throw new Error(`Source component ${sourceComponent} should be implementing IConfirmationService interface to be able to provide confirmation functionality.`);
|
|
278
|
-
}
|
|
279
|
-
const srcConfirmComponent = sourceComponent;
|
|
280
|
-
let confirmParams = {
|
|
281
|
-
key: srcConfirmComponent.getConfirmationServiceInstanceKey(action),
|
|
282
|
-
acceptVisible: false,
|
|
283
|
-
rejectVisible: false
|
|
284
|
-
};
|
|
285
|
-
const item = parameters.item;
|
|
286
|
-
if (action.runConfirmationTitle !== null) {
|
|
287
|
-
confirmParams.header = I18nUtils.Action.get(this.translate, action, 'confirm.title', action.runConfirmationTitle, item, 'general.confirmation') ?? undefined;
|
|
288
|
-
}
|
|
289
|
-
if (action.runConfirmationMessage !== null) {
|
|
290
|
-
confirmParams.message = I18nUtils.Action.get(this.translate, action, 'confirm.message', action.runConfirmationMessage, item, 'general.confirmation') ?? undefined;
|
|
291
|
-
}
|
|
292
|
-
if (action.runConfirmationIcon !== null) {
|
|
293
|
-
confirmParams.icon = action.runConfirmationIcon === undefined ? 'pi pi-exclamation-triangle' : action.runConfirmationIcon;
|
|
294
|
-
}
|
|
295
|
-
if (action.runConfirmationAcceptTitle !== null) {
|
|
296
|
-
confirmParams.acceptLabel = I18nUtils.Action.get(this.translate, action, 'confirm.accept', action.runConfirmationAcceptTitle, item, 'general.yes') ?? undefined;
|
|
297
|
-
confirmParams.acceptVisible = true;
|
|
298
|
-
}
|
|
299
|
-
if (action.runConfirmationRejectTitle !== null) {
|
|
300
|
-
confirmParams.rejectLabel = I18nUtils.Action.get(this.translate, action, 'confirm.reject', action.runConfirmationRejectTitle, item, 'general.no') ?? undefined;
|
|
301
|
-
confirmParams.rejectVisible = true;
|
|
302
|
-
}
|
|
303
|
-
confirmParams.accept = () => {
|
|
304
|
-
instance.state = ActionInstanceStateEnum.RunConfirmationEndAccept;
|
|
305
|
-
this.runActionContext(context);
|
|
306
|
-
};
|
|
307
|
-
confirmParams.reject = () => {
|
|
308
|
-
instance.state = ActionInstanceStateEnum.RunConfirmationEndReject;
|
|
309
|
-
this.deactivateAction(instance);
|
|
310
|
-
};
|
|
311
|
-
if (action.runConfirmationConfigMapFn) {
|
|
312
|
-
confirmParams = action.runConfirmationConfigMapFn(context, confirmParams);
|
|
313
|
-
}
|
|
314
|
-
context.confirmation = confirmParams;
|
|
315
|
-
instance.state = ActionInstanceStateEnum.RunConfirmationStart;
|
|
316
|
-
srcConfirmComponent.getConfirmationService().confirm(confirmParams);
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
this.runActionContext(context);
|
|
320
|
-
}
|
|
321
|
-
return context;
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Activates action (in case of dialog, dialog will be opened).
|
|
325
|
-
*
|
|
326
|
-
* @param action Action descriptor.
|
|
327
|
-
* @param parameters Action parameters for activation of action instance.
|
|
328
|
-
* @param instance Optional existing action instance (if non provided, new will be created).
|
|
329
|
-
* @param previousActionInstance Optional previous action instance to link in next instance.
|
|
330
|
-
*
|
|
331
|
-
* @return Action instance - if non provided in parameters, the newly created will be returned.
|
|
332
|
-
*/
|
|
333
|
-
activateAction(action, parameters, instance, previousActionInstance) {
|
|
334
|
-
if (!instance) {
|
|
335
|
-
// create new instance if non provided
|
|
336
|
-
instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationStart, this.debug);
|
|
337
|
-
}
|
|
338
|
-
instance.activationParameters = parameters;
|
|
339
|
-
// start activation instance
|
|
340
|
-
instance.state = ActionInstanceStateEnum.ActivationStart;
|
|
341
|
-
if (action.type === ActionTypeEnum.Editor) {
|
|
342
|
-
let dialogComponent = this.defaultEditorDialogComponent;
|
|
343
|
-
let dialogClassName = '';
|
|
344
|
-
if (action instanceof ActionEditorDescriptor) {
|
|
345
|
-
dialogClassName = action.dialogClassName ?? 'mng-action-editor-dialog';
|
|
346
|
-
let dialogSizeClassName = '';
|
|
347
|
-
switch (action.dialogSize) {
|
|
348
|
-
case ActionEditorDialogSizeEnum.ExtraSmall:
|
|
349
|
-
dialogSizeClassName = 'mng-action-editor-dialog-xs';
|
|
350
|
-
break;
|
|
351
|
-
case ActionEditorDialogSizeEnum.Small:
|
|
352
|
-
dialogSizeClassName = 'mng-action-editor-dialog-sm';
|
|
353
|
-
break;
|
|
354
|
-
case ActionEditorDialogSizeEnum.Large:
|
|
355
|
-
dialogSizeClassName = 'mng-action-editor-dialog-lg';
|
|
356
|
-
break;
|
|
357
|
-
case ActionEditorDialogSizeEnum.ExtraLarge:
|
|
358
|
-
dialogSizeClassName = 'mng-action-editor-dialog-xl';
|
|
359
|
-
break;
|
|
360
|
-
case ActionEditorDialogSizeEnum.Normal:
|
|
361
|
-
default:
|
|
362
|
-
break;
|
|
363
|
-
}
|
|
364
|
-
if (dialogSizeClassName.length) {
|
|
365
|
-
dialogClassName += ` ${dialogSizeClassName}`;
|
|
366
|
-
}
|
|
367
|
-
if (action.editorComponent) {
|
|
368
|
-
dialogComponent = action.editorComponent;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
const dialogConfig = {
|
|
372
|
-
data: {},
|
|
373
|
-
styleClass: dialogClassName
|
|
374
|
-
};
|
|
375
|
-
dialogConfig.data.actionInstance = instance;
|
|
376
|
-
dialogConfig.data.previousActionInstance = previousActionInstance;
|
|
377
|
-
const dialogRef = this.dialogService.open(dialogComponent, dialogConfig);
|
|
378
|
-
dialogRef.onClose.pipe(first()).subscribe(() => {
|
|
379
|
-
this.deactivateAction(instance, true);
|
|
380
|
-
});
|
|
381
|
-
instance.activationDialogRef = dialogRef;
|
|
382
|
-
return instance;
|
|
383
|
-
}
|
|
384
|
-
else {
|
|
385
|
-
// directly execute action
|
|
386
|
-
instance.state = ActionInstanceStateEnum.ActivationEnd;
|
|
387
|
-
const context = this.runAction(action, parameters, undefined, instance, previousActionInstance);
|
|
388
|
-
return context.instance;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Deactivates action by choosing final state, closing dialog and completing all subjects in instance and contexts.
|
|
393
|
-
*
|
|
394
|
-
* @param instance Action instance.
|
|
395
|
-
* @param fromDialogListener Deactivation called from dialog listener, in this case deactivation happens only if true.
|
|
396
|
-
*/
|
|
397
|
-
deactivateAction(instance, fromDialogListener = false) {
|
|
398
|
-
if (!fromDialogListener && instance.state >= ActionInstanceStateEnum.FinishSuccess) {
|
|
399
|
-
if (this.debug) {
|
|
400
|
-
console.debug(`ActionInstance ${instance.instanceLongName} already finished`);
|
|
401
|
-
}
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
let finalState;
|
|
405
|
-
if (typeof instance.result !== 'undefined') {
|
|
406
|
-
finalState = ActionInstanceStateEnum.FinishSuccess;
|
|
407
|
-
}
|
|
408
|
-
else if (typeof instance.error !== 'undefined') {
|
|
409
|
-
finalState = ActionInstanceStateEnum.FinishError;
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
finalState = ActionInstanceStateEnum.FinishDismissed;
|
|
413
|
-
}
|
|
414
|
-
if (instance.action.type === ActionTypeEnum.Editor) {
|
|
415
|
-
const hasDialog = typeof instance.activationDialogRef !== 'undefined';
|
|
416
|
-
if (hasDialog && !fromDialogListener) {
|
|
417
|
-
if (finalState === ActionInstanceStateEnum.FinishSuccess) {
|
|
418
|
-
// if state is finish and not called from dialog listener, close the dialog first which will retrigger this function, then finish it
|
|
419
|
-
instance.activationDialogRef.close(instance.result);
|
|
420
|
-
}
|
|
421
|
-
// error and dismissed must both have fromDialogListener to be able to finish
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
// set final state on instance
|
|
426
|
-
instance.state = finalState;
|
|
427
|
-
// complete all subjects
|
|
428
|
-
instance.finish();
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* Triggers action from table row click position.
|
|
432
|
-
*
|
|
433
|
-
* @param action Action descriptor.
|
|
434
|
-
* @param event Target table click event.
|
|
435
|
-
* @param route Currently activate route.
|
|
436
|
-
* @param tableDescriptor Table descriptor.
|
|
437
|
-
* @param dataKeyProperty Data key property.
|
|
438
|
-
*/
|
|
439
|
-
triggerRowClickAction(action, event, route, tableDescriptor, dataKeyProperty) {
|
|
440
|
-
const idProperty = dataKeyProperty ?? tableDescriptor?.dataKeyProperty ?? action?.model?.idPropertyName ?? dataKeyProperty;
|
|
441
|
-
if (!idProperty) {
|
|
442
|
-
throw new Error(`Row click action ${action.actionNameLong} can not be triggered, because id property could not be found.`);
|
|
443
|
-
}
|
|
444
|
-
const rowItem = event?.rowItem;
|
|
445
|
-
return this.triggerAction(action, new ActionParameters(rowItem[idProperty], event.rowItem).withRoute(route));
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* Triggers action with parameters.
|
|
449
|
-
*
|
|
450
|
-
* @param action Action descriptor.
|
|
451
|
-
* @param parameters Action parameters for action execution to construct new route.
|
|
452
|
-
*
|
|
453
|
-
* @return Action instance - if non provided in parameters, the newly created will be returned.
|
|
454
|
-
*/
|
|
455
|
-
triggerAction(action, parameters) {
|
|
456
|
-
const instance = new ActionInstance(action, undefined, this.debug);
|
|
457
|
-
instance.triggerParameters = parameters;
|
|
458
|
-
if (action.activationTrigger === ActionActivationTriggerEnum.OnRoute) {
|
|
459
|
-
const baseUrl = this.router.url.split('?')[0];
|
|
460
|
-
const parsedUrl = this.router.parseUrl(this.router.url);
|
|
461
|
-
let actionUrl = action.routeUrl ?? '';
|
|
462
|
-
// TODO: dont strip '/', but use it accordingly with Angular's router patterns (/, ./, ../)
|
|
463
|
-
if (actionUrl.startsWith('/')) {
|
|
464
|
-
actionUrl = actionUrl.substring(1);
|
|
465
|
-
}
|
|
466
|
-
const actionUrlSegments = this.linkFormatter.transform(actionUrl, parameters.itemId, parameters.item, action.model, parameters.actionData);
|
|
467
|
-
instance.triggerRouteNavigation = from(this.router.navigate([baseUrl, ...actionUrlSegments], { relativeTo: parameters.route, queryParams: parsedUrl.queryParams }));
|
|
468
|
-
return instance;
|
|
469
|
-
}
|
|
470
|
-
else {
|
|
471
|
-
instance.state = ActionInstanceStateEnum.TriggerEnd;
|
|
472
|
-
return this.activateAction(action, parameters);
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
/**
|
|
476
|
-
* Deactivates on route triggered action by trying to reroute back to location where action was triggered.
|
|
477
|
-
* @param instance Action instance.
|
|
478
|
-
*/
|
|
479
|
-
deactivateOnRouteTriggeredAction(instance) {
|
|
480
|
-
if (instance.action.activationTrigger !== ActionActivationTriggerEnum.OnRoute) {
|
|
481
|
-
return;
|
|
482
|
-
}
|
|
483
|
-
if (this.navigationService.getPreviousLocation()) {
|
|
484
|
-
// there are internal history records, so back can be normally called
|
|
485
|
-
this.navigationService.back();
|
|
486
|
-
}
|
|
487
|
-
else {
|
|
488
|
-
// there is no internal history records, figure out the base url by eliminating action specific url
|
|
489
|
-
let url = this.navigationService.getCurrentLocation();
|
|
490
|
-
if (!url) {
|
|
491
|
-
this.navigationService.back();
|
|
492
|
-
}
|
|
493
|
-
else {
|
|
494
|
-
if (url.startsWith('/')) {
|
|
495
|
-
url = url.substring(1);
|
|
496
|
-
}
|
|
497
|
-
const urlPathSegments = url.split('?')[0].split('#')[0].split('/');
|
|
498
|
-
let actionUrl = instance.action?.routeUrl ?? '';
|
|
499
|
-
if (actionUrl.startsWith('/')) {
|
|
500
|
-
actionUrl = actionUrl.substring(1);
|
|
501
|
-
}
|
|
502
|
-
const actionUrlSegments = actionUrl.split('/');
|
|
503
|
-
const redirectUrl = urlPathSegments.slice(0, urlPathSegments.length - actionUrlSegments.length).join('/');
|
|
504
|
-
this.router.navigateByUrl(`/${redirectUrl}`, { replaceUrl: true });
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
/**
|
|
509
|
-
* Transform error of any type to mng error by using error mapper that could be provided by final project.
|
|
510
|
-
* @param error error of any type.
|
|
511
|
-
*
|
|
512
|
-
* @return mapped MngError.
|
|
513
|
-
*/
|
|
514
|
-
toMngActionError(error) {
|
|
515
|
-
const actionError = {
|
|
516
|
-
name: error?.name ?? 'UnknownError',
|
|
517
|
-
message: error?.message ?? 'Unknown error',
|
|
518
|
-
cause: error
|
|
519
|
-
};
|
|
520
|
-
if (error instanceof HttpErrorResponse) {
|
|
521
|
-
actionError.status = error.status;
|
|
522
|
-
actionError.statusDescription = error.statusText;
|
|
523
|
-
actionError.url = error.url ?? undefined;
|
|
524
|
-
}
|
|
525
|
-
return this.errorMapper.toMngError(error, actionError);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
MngActionExecutorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: MngActionExecutorService, deps: [{ token: i0.Injector }, { token: i1.Router }, { token: i2.DialogService }, { token: i3.ConfirmationService }, { token: i4.TranslateService }, { token: i5.MngConfigurationService }, { token: i6.MngNavigationService }, { token: i7.MngErrorMapperService }, { token: i8.MngLinkFormatterPipe }, { token: ACTION_EDITOR_DIALOG_COMPONENT_SETTING }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
529
|
-
MngActionExecutorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: MngActionExecutorService });
|
|
530
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: MngActionExecutorService, decorators: [{
|
|
531
|
-
type: Injectable
|
|
532
|
-
}], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.Router }, { type: i2.DialogService }, { type: i3.ConfirmationService }, { type: i4.TranslateService }, { type: i5.MngConfigurationService }, { type: i6.MngNavigationService }, { type: i7.MngErrorMapperService }, { type: i8.MngLinkFormatterPipe }, { type: i0.Type, decorators: [{
|
|
533
|
-
type: Inject,
|
|
534
|
-
args: [ACTION_EDITOR_DIALOG_COMPONENT_SETTING]
|
|
535
|
-
}] }]; } });
|
|
1
|
+
import { HttpErrorResponse } from '@angular/common/http';
|
|
2
|
+
import { Inject, Injectable } from '@angular/core';
|
|
3
|
+
import { from, mergeMap, of, switchMap, throwError } from 'rxjs';
|
|
4
|
+
import { catchError, filter, first, map } from 'rxjs/operators';
|
|
5
|
+
import { ActionContext, ActionContextValidation, ActionInstance, ActionInstanceStateEnum, ActionParameters } from '../components/action/models';
|
|
6
|
+
import { ActionEditorDescriptor } from '../descriptors';
|
|
7
|
+
import { ActionActivationTriggerEnum, ActionEditorDialogSizeEnum, ActionTypeEnum } from '../descriptors/types';
|
|
8
|
+
import { I18nUtils, NotificationUtil } from '../utils';
|
|
9
|
+
import { ACTION_EDITOR_DIALOG_COMPONENT_SETTING } from './tokens';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
import * as i1 from "@angular/router";
|
|
12
|
+
import * as i2 from "primeng/dynamicdialog";
|
|
13
|
+
import * as i3 from "primeng/api";
|
|
14
|
+
import * as i4 from "@ngx-translate/core";
|
|
15
|
+
import * as i5 from "./configuration.service";
|
|
16
|
+
import * as i6 from "./navigation.service";
|
|
17
|
+
import * as i7 from "./error-mapper.service";
|
|
18
|
+
import * as i8 from "../pipes";
|
|
19
|
+
export class MngActionExecutorService {
|
|
20
|
+
constructor(injector, router, dialogService, confirmationService, translate, configurationService, navigationService, errorMapper, linkFormatter, defaultEditorDialogComponent) {
|
|
21
|
+
this.injector = injector;
|
|
22
|
+
this.router = router;
|
|
23
|
+
this.dialogService = dialogService;
|
|
24
|
+
this.confirmationService = confirmationService;
|
|
25
|
+
this.translate = translate;
|
|
26
|
+
this.configurationService = configurationService;
|
|
27
|
+
this.navigationService = navigationService;
|
|
28
|
+
this.errorMapper = errorMapper;
|
|
29
|
+
this.linkFormatter = linkFormatter;
|
|
30
|
+
this.defaultEditorDialogComponent = defaultEditorDialogComponent;
|
|
31
|
+
this.debug = false;
|
|
32
|
+
// this.debug = true;
|
|
33
|
+
}
|
|
34
|
+
prepareActionContextValidation(action, parameters, dataProvider) {
|
|
35
|
+
const ctxDataProvider = dataProvider ?? action.dataProvider ?? parameters.viewContainer?.getDataProvider();
|
|
36
|
+
const ctx = new ActionContextValidation(action, parameters, ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
|
|
37
|
+
return ctx;
|
|
38
|
+
}
|
|
39
|
+
prepareActionContext(instance, parameters, dataProvider, previousActionInstance) {
|
|
40
|
+
const ctxDataProvider = dataProvider ?? instance.action.dataProvider ?? parameters.viewContainer?.getDataProvider();
|
|
41
|
+
const ctx = new ActionContext(instance, parameters, 'run', ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
|
|
42
|
+
ctx.previousActionInstance = previousActionInstance;
|
|
43
|
+
instance.newContext(ctx);
|
|
44
|
+
return ctx;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Prepares action exec context for action of type editor.
|
|
48
|
+
*
|
|
49
|
+
* @param item Item instance (if exists).
|
|
50
|
+
* @param itemId Item id (if exists).
|
|
51
|
+
* @param dataProvider Data provider.
|
|
52
|
+
* @param sourceComponent Source component from where the context preparation was called.
|
|
53
|
+
* @param viewContainer View container/service.
|
|
54
|
+
* @param actionData Additional action data.
|
|
55
|
+
*/
|
|
56
|
+
prepareContextForEditor(instance, parameters, functionName, dataProvider, previousActionInstance) {
|
|
57
|
+
const editorAction = instance.action;
|
|
58
|
+
let ctxDataProvider = dataProvider;
|
|
59
|
+
if (!ctxDataProvider && editorAction.dataProvider) {
|
|
60
|
+
ctxDataProvider = editorAction.dataProvider;
|
|
61
|
+
}
|
|
62
|
+
if (!ctxDataProvider) {
|
|
63
|
+
const viewContainerDataProvider = parameters.viewContainer?.getDataProvider();
|
|
64
|
+
if (viewContainerDataProvider) {
|
|
65
|
+
ctxDataProvider = viewContainerDataProvider;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const ctx = new ActionContext(instance, parameters, functionName, ctxDataProvider, this.getDataProviderService(ctxDataProvider) ?? undefined);
|
|
69
|
+
ctx.previousActionInstance = previousActionInstance;
|
|
70
|
+
instance.newContext(ctx);
|
|
71
|
+
return ctx;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Runs action context by submitting execution results/errors to context, watching over instance results/errors, displaying notifications,
|
|
75
|
+
* running next/error action and triggering dismiss of action.
|
|
76
|
+
*
|
|
77
|
+
* @param action Action descriptor.
|
|
78
|
+
* @param parameters Action parameters for context.
|
|
79
|
+
* @param dataProvider Editor data provider for context.
|
|
80
|
+
* @param instance Optional existing action instance (if non provided, new will be created).
|
|
81
|
+
* @param previousActionInstance Optional previous action instance to link in next instance.
|
|
82
|
+
*
|
|
83
|
+
* @return Action context for submit (=run) function.
|
|
84
|
+
*/
|
|
85
|
+
runActionContext(ctx) {
|
|
86
|
+
const isMainRunFn = ctx.functionName === 'submit' || ctx.functionName === 'run';
|
|
87
|
+
let actionEditor;
|
|
88
|
+
let fnObs;
|
|
89
|
+
switch (ctx.functionName) {
|
|
90
|
+
case 'submit':
|
|
91
|
+
actionEditor = ctx.instance.action;
|
|
92
|
+
if (typeof actionEditor.submitFunction !== 'function') {
|
|
93
|
+
return throwError(() => new Error(`Submit function for action ${actionEditor.actionNameLong} cannot be invoked.`));
|
|
94
|
+
}
|
|
95
|
+
fnObs = actionEditor.submitFunction;
|
|
96
|
+
break;
|
|
97
|
+
case 'fetch':
|
|
98
|
+
actionEditor = ctx.instance.action;
|
|
99
|
+
fnObs = actionEditor.fetchFunction;
|
|
100
|
+
break;
|
|
101
|
+
case 'run':
|
|
102
|
+
default:
|
|
103
|
+
fnObs = ctx.instance.action.runFunction;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
const retObs = of(void 0).pipe(first(), switchMap(() => {
|
|
107
|
+
if (isMainRunFn) {
|
|
108
|
+
// if main run function, also set loading to true
|
|
109
|
+
ctx.instance.state = ActionInstanceStateEnum.RunStart;
|
|
110
|
+
ctx.instance.isRunLoadingSubject.next(true);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
ctx.instance.state = ActionInstanceStateEnum.FetchStart;
|
|
114
|
+
}
|
|
115
|
+
// start context execution to mark execution loading
|
|
116
|
+
ctx.executionStart();
|
|
117
|
+
return fnObs(ctx);
|
|
118
|
+
}), mergeMap(runResult => {
|
|
119
|
+
// set next state depending on run
|
|
120
|
+
ctx.instance.state = isMainRunFn ? ActionInstanceStateEnum.RunEnd : ActionInstanceStateEnum.FetchEnd;
|
|
121
|
+
// set execution result
|
|
122
|
+
ctx.executionNext(runResult, isMainRunFn);
|
|
123
|
+
if (isMainRunFn) {
|
|
124
|
+
// set instance final result on main run execution
|
|
125
|
+
ctx.instance.result = runResult;
|
|
126
|
+
ctx.instance.isRunLoadingSubject.next(false);
|
|
127
|
+
// handle notification
|
|
128
|
+
if (ctx.instance.action.hasRunNotificationSuccess) {
|
|
129
|
+
ctx.notification = NotificationUtil.actionNotificationSuccess(this.translate, ctx.instance.action, ctx.functionName, ctx.instance.action.runNotificationSuccessTitle, ctx.instance.action.runNotificationSuccessMessage, ctx.parameters.viewContainer ?? undefined, ctx.parameters?.item);
|
|
130
|
+
}
|
|
131
|
+
// handle possible after run action
|
|
132
|
+
if (ctx.instance.action.afterRunAction) {
|
|
133
|
+
// mark new state for next action start
|
|
134
|
+
ctx.instance.state = ActionInstanceStateEnum.NextActionStart;
|
|
135
|
+
const nextActionInstance = this.activateAction(ctx.instance.action.afterRunAction, new ActionParameters(ctx.parameters.itemId, runResult)
|
|
136
|
+
.withActionData(ctx.parameters.actionData)
|
|
137
|
+
.withRoute(ctx.parameters.route)
|
|
138
|
+
.withSourceComponent(ctx.parameters.sourceComponent)
|
|
139
|
+
.withViewContainer(ctx.parameters.viewContainer), undefined, ctx.instance);
|
|
140
|
+
ctx.instance.nextActionInstance = nextActionInstance;
|
|
141
|
+
// finish current action when next action finishes
|
|
142
|
+
return nextActionInstance.state$.pipe(filter(state => state >= ActionInstanceStateEnum.FinishSuccess), map(() => {
|
|
143
|
+
ctx.instance.state = ActionInstanceStateEnum.NextActionEnd;
|
|
144
|
+
return runResult;
|
|
145
|
+
}));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return of(runResult);
|
|
149
|
+
}), map(runResult => {
|
|
150
|
+
if (isMainRunFn) {
|
|
151
|
+
// deactivate action
|
|
152
|
+
this.deactivateAction(ctx.instance);
|
|
153
|
+
}
|
|
154
|
+
return runResult;
|
|
155
|
+
}), catchError(err => {
|
|
156
|
+
// transform error to mng action error
|
|
157
|
+
const actionError = this.toMngActionError(err);
|
|
158
|
+
// set instance state to error
|
|
159
|
+
ctx.instance.state = isMainRunFn ? ActionInstanceStateEnum.RunError : ActionInstanceStateEnum.FetchError;
|
|
160
|
+
// mark execution error on context
|
|
161
|
+
ctx.executionError(actionError);
|
|
162
|
+
let errorObs = of(void 0);
|
|
163
|
+
if (isMainRunFn) {
|
|
164
|
+
ctx.instance.error = err;
|
|
165
|
+
ctx.instance.isRunLoadingSubject.next(false);
|
|
166
|
+
// handle error notification
|
|
167
|
+
if (ctx.instance.action.hasRunNotificationError) {
|
|
168
|
+
actionError.notification = NotificationUtil.actionNotificationError(this.translate, ctx.instance.action, actionError, ctx.functionName, ctx.parameters.viewContainer ?? undefined, ctx.parameters.item);
|
|
169
|
+
}
|
|
170
|
+
// handle possible error action if run
|
|
171
|
+
if (isMainRunFn && ctx.instance.action.onRunErrorAction) {
|
|
172
|
+
// cannot start with trigger, because routing might be problematic (lousing previous results etc.)
|
|
173
|
+
const errorActionInstance = this.activateAction(ctx.instance.action.onRunErrorAction, new ActionParameters(ctx.parameters.itemId, ctx.parameters.item)
|
|
174
|
+
.withActionData(ctx.parameters.actionData)
|
|
175
|
+
.withRoute(ctx.parameters.route)
|
|
176
|
+
.withSourceComponent(ctx.parameters.sourceComponent)
|
|
177
|
+
.withViewContainer(ctx.parameters.viewContainer));
|
|
178
|
+
ctx.instance.errorActionInstance = errorActionInstance;
|
|
179
|
+
errorObs = errorActionInstance.state$.pipe(filter(state => state >= ActionInstanceStateEnum.FinishSuccess), map(() => void 0));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// liste and map only to mark instance state as finished error state
|
|
183
|
+
return errorObs.pipe(map(() => {
|
|
184
|
+
// deactivate action
|
|
185
|
+
this.deactivateAction(ctx.instance);
|
|
186
|
+
// rethrow error to propagate furher
|
|
187
|
+
throw actionError;
|
|
188
|
+
}));
|
|
189
|
+
}));
|
|
190
|
+
retObs.subscribe({
|
|
191
|
+
next: res => {
|
|
192
|
+
if (this.debug) {
|
|
193
|
+
console.debug(`ActionContext ${ctx.contextLongName} execution next event`, res);
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
error: err => {
|
|
197
|
+
if (this.debug) {
|
|
198
|
+
console.debug(`ActionContext ${ctx.contextLongName} execution error event`, err);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
return retObs;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Runs editor action's submit (=main run) function by creating new action context for action instance.
|
|
206
|
+
*
|
|
207
|
+
* @param action Action descriptor.
|
|
208
|
+
* @param parameters Action parameters for context.
|
|
209
|
+
* @param dataProvider Editor data provider for context.
|
|
210
|
+
* @param instance Optional existing action instance (if non provided, new will be created).
|
|
211
|
+
* @param previousActionInstance Optional previous action instance to link in next instance.
|
|
212
|
+
*
|
|
213
|
+
* @return Action context for submit (=run) function.
|
|
214
|
+
*/
|
|
215
|
+
runEditorSave(action, parameters, dataProvider, instance, previousActionInstance) {
|
|
216
|
+
if (!instance) {
|
|
217
|
+
// create new instance if non provided
|
|
218
|
+
instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
|
|
219
|
+
}
|
|
220
|
+
const context = this.prepareContextForEditor(instance, parameters, 'submit', dataProvider, previousActionInstance);
|
|
221
|
+
this.runActionContext(context);
|
|
222
|
+
return context;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Gets service instance of data provider.
|
|
226
|
+
*
|
|
227
|
+
* @param dataProvider Data provider instance.
|
|
228
|
+
*/
|
|
229
|
+
getDataProviderService(dataProvider) {
|
|
230
|
+
if (dataProvider?.serviceType) {
|
|
231
|
+
return this.injector.get(dataProvider.serviceType);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Runs editor action's fetch function by creating new action context for action instance.
|
|
239
|
+
*
|
|
240
|
+
* @param action Action descriptor.
|
|
241
|
+
* @param parameters Action parameters for context.
|
|
242
|
+
* @param dataProvider Editor data provider for context.
|
|
243
|
+
* @param instance Optional existing action instance (if non provided, new will be created).
|
|
244
|
+
* @param previousActionInstance Optional previous action instance to link in next instance.
|
|
245
|
+
*
|
|
246
|
+
* @return Action context for fetch function.
|
|
247
|
+
*/
|
|
248
|
+
runEditorFetch(action, parameters, dataProvider, instance, previousActionInstance) {
|
|
249
|
+
if (!instance) {
|
|
250
|
+
// create new instance if non provided
|
|
251
|
+
instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
|
|
252
|
+
}
|
|
253
|
+
const context = this.prepareContextForEditor(instance, parameters, 'fetch', dataProvider, previousActionInstance);
|
|
254
|
+
this.runActionContext(context);
|
|
255
|
+
return context;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Runs action's main run function by creating new action context for action instance.
|
|
259
|
+
*
|
|
260
|
+
* @param action Action descriptor.
|
|
261
|
+
* @param parameters Action parameters for context run.
|
|
262
|
+
* @param dataProvider Data provider for context run.
|
|
263
|
+
* @param instance Optional existing action instance (if non provided, new will be created).
|
|
264
|
+
* @param previousActionInstance Optional previous action instance to link in next instance.
|
|
265
|
+
*
|
|
266
|
+
* @return Action context for run function.
|
|
267
|
+
*/
|
|
268
|
+
runAction(action, parameters, dataProvider, instance, previousActionInstance) {
|
|
269
|
+
if (!instance) {
|
|
270
|
+
// create new instance if non provided
|
|
271
|
+
instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationEnd, this.debug);
|
|
272
|
+
}
|
|
273
|
+
const context = this.prepareActionContext(instance, parameters, dataProvider, previousActionInstance);
|
|
274
|
+
if (action.hasRunConfirmation) {
|
|
275
|
+
const sourceComponent = parameters?.sourceComponent;
|
|
276
|
+
if (typeof sourceComponent?.getConfirmationService !== 'function' || typeof sourceComponent?.getConfirmationServiceInstanceKey !== 'function') {
|
|
277
|
+
throw new Error(`Source component ${sourceComponent} should be implementing IConfirmationService interface to be able to provide confirmation functionality.`);
|
|
278
|
+
}
|
|
279
|
+
const srcConfirmComponent = sourceComponent;
|
|
280
|
+
let confirmParams = {
|
|
281
|
+
key: srcConfirmComponent.getConfirmationServiceInstanceKey(action),
|
|
282
|
+
acceptVisible: false,
|
|
283
|
+
rejectVisible: false
|
|
284
|
+
};
|
|
285
|
+
const item = parameters.item;
|
|
286
|
+
if (action.runConfirmationTitle !== null) {
|
|
287
|
+
confirmParams.header = I18nUtils.Action.get(this.translate, action, 'confirm.title', action.runConfirmationTitle, item, 'general.confirmation') ?? undefined;
|
|
288
|
+
}
|
|
289
|
+
if (action.runConfirmationMessage !== null) {
|
|
290
|
+
confirmParams.message = I18nUtils.Action.get(this.translate, action, 'confirm.message', action.runConfirmationMessage, item, 'general.confirmation') ?? undefined;
|
|
291
|
+
}
|
|
292
|
+
if (action.runConfirmationIcon !== null) {
|
|
293
|
+
confirmParams.icon = action.runConfirmationIcon === undefined ? 'pi pi-exclamation-triangle' : action.runConfirmationIcon;
|
|
294
|
+
}
|
|
295
|
+
if (action.runConfirmationAcceptTitle !== null) {
|
|
296
|
+
confirmParams.acceptLabel = I18nUtils.Action.get(this.translate, action, 'confirm.accept', action.runConfirmationAcceptTitle, item, 'general.yes') ?? undefined;
|
|
297
|
+
confirmParams.acceptVisible = true;
|
|
298
|
+
}
|
|
299
|
+
if (action.runConfirmationRejectTitle !== null) {
|
|
300
|
+
confirmParams.rejectLabel = I18nUtils.Action.get(this.translate, action, 'confirm.reject', action.runConfirmationRejectTitle, item, 'general.no') ?? undefined;
|
|
301
|
+
confirmParams.rejectVisible = true;
|
|
302
|
+
}
|
|
303
|
+
confirmParams.accept = () => {
|
|
304
|
+
instance.state = ActionInstanceStateEnum.RunConfirmationEndAccept;
|
|
305
|
+
this.runActionContext(context);
|
|
306
|
+
};
|
|
307
|
+
confirmParams.reject = () => {
|
|
308
|
+
instance.state = ActionInstanceStateEnum.RunConfirmationEndReject;
|
|
309
|
+
this.deactivateAction(instance);
|
|
310
|
+
};
|
|
311
|
+
if (action.runConfirmationConfigMapFn) {
|
|
312
|
+
confirmParams = action.runConfirmationConfigMapFn(context, confirmParams);
|
|
313
|
+
}
|
|
314
|
+
context.confirmation = confirmParams;
|
|
315
|
+
instance.state = ActionInstanceStateEnum.RunConfirmationStart;
|
|
316
|
+
srcConfirmComponent.getConfirmationService().confirm(confirmParams);
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
this.runActionContext(context);
|
|
320
|
+
}
|
|
321
|
+
return context;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Activates action (in case of dialog, dialog will be opened).
|
|
325
|
+
*
|
|
326
|
+
* @param action Action descriptor.
|
|
327
|
+
* @param parameters Action parameters for activation of action instance.
|
|
328
|
+
* @param instance Optional existing action instance (if non provided, new will be created).
|
|
329
|
+
* @param previousActionInstance Optional previous action instance to link in next instance.
|
|
330
|
+
*
|
|
331
|
+
* @return Action instance - if non provided in parameters, the newly created will be returned.
|
|
332
|
+
*/
|
|
333
|
+
activateAction(action, parameters, instance, previousActionInstance) {
|
|
334
|
+
if (!instance) {
|
|
335
|
+
// create new instance if non provided
|
|
336
|
+
instance = new ActionInstance(action, ActionInstanceStateEnum.ActivationStart, this.debug);
|
|
337
|
+
}
|
|
338
|
+
instance.activationParameters = parameters;
|
|
339
|
+
// start activation instance
|
|
340
|
+
instance.state = ActionInstanceStateEnum.ActivationStart;
|
|
341
|
+
if (action.type === ActionTypeEnum.Editor) {
|
|
342
|
+
let dialogComponent = this.defaultEditorDialogComponent;
|
|
343
|
+
let dialogClassName = '';
|
|
344
|
+
if (action instanceof ActionEditorDescriptor) {
|
|
345
|
+
dialogClassName = action.dialogClassName ?? 'mng-action-editor-dialog';
|
|
346
|
+
let dialogSizeClassName = '';
|
|
347
|
+
switch (action.dialogSize) {
|
|
348
|
+
case ActionEditorDialogSizeEnum.ExtraSmall:
|
|
349
|
+
dialogSizeClassName = 'mng-action-editor-dialog-xs';
|
|
350
|
+
break;
|
|
351
|
+
case ActionEditorDialogSizeEnum.Small:
|
|
352
|
+
dialogSizeClassName = 'mng-action-editor-dialog-sm';
|
|
353
|
+
break;
|
|
354
|
+
case ActionEditorDialogSizeEnum.Large:
|
|
355
|
+
dialogSizeClassName = 'mng-action-editor-dialog-lg';
|
|
356
|
+
break;
|
|
357
|
+
case ActionEditorDialogSizeEnum.ExtraLarge:
|
|
358
|
+
dialogSizeClassName = 'mng-action-editor-dialog-xl';
|
|
359
|
+
break;
|
|
360
|
+
case ActionEditorDialogSizeEnum.Normal:
|
|
361
|
+
default:
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
if (dialogSizeClassName.length) {
|
|
365
|
+
dialogClassName += ` ${dialogSizeClassName}`;
|
|
366
|
+
}
|
|
367
|
+
if (action.editorComponent) {
|
|
368
|
+
dialogComponent = action.editorComponent;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const dialogConfig = {
|
|
372
|
+
data: {},
|
|
373
|
+
styleClass: dialogClassName
|
|
374
|
+
};
|
|
375
|
+
dialogConfig.data.actionInstance = instance;
|
|
376
|
+
dialogConfig.data.previousActionInstance = previousActionInstance;
|
|
377
|
+
const dialogRef = this.dialogService.open(dialogComponent, dialogConfig);
|
|
378
|
+
dialogRef.onClose.pipe(first()).subscribe(() => {
|
|
379
|
+
this.deactivateAction(instance, true);
|
|
380
|
+
});
|
|
381
|
+
instance.activationDialogRef = dialogRef;
|
|
382
|
+
return instance;
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
// directly execute action
|
|
386
|
+
instance.state = ActionInstanceStateEnum.ActivationEnd;
|
|
387
|
+
const context = this.runAction(action, parameters, undefined, instance, previousActionInstance);
|
|
388
|
+
return context.instance;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Deactivates action by choosing final state, closing dialog and completing all subjects in instance and contexts.
|
|
393
|
+
*
|
|
394
|
+
* @param instance Action instance.
|
|
395
|
+
* @param fromDialogListener Deactivation called from dialog listener, in this case deactivation happens only if true.
|
|
396
|
+
*/
|
|
397
|
+
deactivateAction(instance, fromDialogListener = false) {
|
|
398
|
+
if (!fromDialogListener && instance.state >= ActionInstanceStateEnum.FinishSuccess) {
|
|
399
|
+
if (this.debug) {
|
|
400
|
+
console.debug(`ActionInstance ${instance.instanceLongName} already finished`);
|
|
401
|
+
}
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
let finalState;
|
|
405
|
+
if (typeof instance.result !== 'undefined') {
|
|
406
|
+
finalState = ActionInstanceStateEnum.FinishSuccess;
|
|
407
|
+
}
|
|
408
|
+
else if (typeof instance.error !== 'undefined') {
|
|
409
|
+
finalState = ActionInstanceStateEnum.FinishError;
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
finalState = ActionInstanceStateEnum.FinishDismissed;
|
|
413
|
+
}
|
|
414
|
+
if (instance.action.type === ActionTypeEnum.Editor) {
|
|
415
|
+
const hasDialog = typeof instance.activationDialogRef !== 'undefined';
|
|
416
|
+
if (hasDialog && !fromDialogListener) {
|
|
417
|
+
if (finalState === ActionInstanceStateEnum.FinishSuccess) {
|
|
418
|
+
// if state is finish and not called from dialog listener, close the dialog first which will retrigger this function, then finish it
|
|
419
|
+
instance.activationDialogRef.close(instance.result);
|
|
420
|
+
}
|
|
421
|
+
// error and dismissed must both have fromDialogListener to be able to finish
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
// set final state on instance
|
|
426
|
+
instance.state = finalState;
|
|
427
|
+
// complete all subjects
|
|
428
|
+
instance.finish();
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Triggers action from table row click position.
|
|
432
|
+
*
|
|
433
|
+
* @param action Action descriptor.
|
|
434
|
+
* @param event Target table click event.
|
|
435
|
+
* @param route Currently activate route.
|
|
436
|
+
* @param tableDescriptor Table descriptor.
|
|
437
|
+
* @param dataKeyProperty Data key property.
|
|
438
|
+
*/
|
|
439
|
+
triggerRowClickAction(action, event, route, tableDescriptor, dataKeyProperty) {
|
|
440
|
+
const idProperty = dataKeyProperty ?? tableDescriptor?.dataKeyProperty ?? action?.model?.idPropertyName ?? dataKeyProperty;
|
|
441
|
+
if (!idProperty) {
|
|
442
|
+
throw new Error(`Row click action ${action.actionNameLong} can not be triggered, because id property could not be found.`);
|
|
443
|
+
}
|
|
444
|
+
const rowItem = event?.rowItem;
|
|
445
|
+
return this.triggerAction(action, new ActionParameters(rowItem[idProperty], event.rowItem).withRoute(route));
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Triggers action with parameters.
|
|
449
|
+
*
|
|
450
|
+
* @param action Action descriptor.
|
|
451
|
+
* @param parameters Action parameters for action execution to construct new route.
|
|
452
|
+
*
|
|
453
|
+
* @return Action instance - if non provided in parameters, the newly created will be returned.
|
|
454
|
+
*/
|
|
455
|
+
triggerAction(action, parameters) {
|
|
456
|
+
const instance = new ActionInstance(action, undefined, this.debug);
|
|
457
|
+
instance.triggerParameters = parameters;
|
|
458
|
+
if (action.activationTrigger === ActionActivationTriggerEnum.OnRoute) {
|
|
459
|
+
const baseUrl = this.router.url.split('?')[0];
|
|
460
|
+
const parsedUrl = this.router.parseUrl(this.router.url);
|
|
461
|
+
let actionUrl = action.routeUrl ?? '';
|
|
462
|
+
// TODO: dont strip '/', but use it accordingly with Angular's router patterns (/, ./, ../)
|
|
463
|
+
if (actionUrl.startsWith('/')) {
|
|
464
|
+
actionUrl = actionUrl.substring(1);
|
|
465
|
+
}
|
|
466
|
+
const actionUrlSegments = this.linkFormatter.transform(actionUrl, parameters.itemId, parameters.item, action.model, parameters.actionData);
|
|
467
|
+
instance.triggerRouteNavigation = from(this.router.navigate([baseUrl, ...actionUrlSegments], { relativeTo: parameters.route, queryParams: parsedUrl.queryParams }));
|
|
468
|
+
return instance;
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
instance.state = ActionInstanceStateEnum.TriggerEnd;
|
|
472
|
+
return this.activateAction(action, parameters);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Deactivates on route triggered action by trying to reroute back to location where action was triggered.
|
|
477
|
+
* @param instance Action instance.
|
|
478
|
+
*/
|
|
479
|
+
deactivateOnRouteTriggeredAction(instance) {
|
|
480
|
+
if (instance.action.activationTrigger !== ActionActivationTriggerEnum.OnRoute) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
if (this.navigationService.getPreviousLocation()) {
|
|
484
|
+
// there are internal history records, so back can be normally called
|
|
485
|
+
this.navigationService.back();
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
// there is no internal history records, figure out the base url by eliminating action specific url
|
|
489
|
+
let url = this.navigationService.getCurrentLocation();
|
|
490
|
+
if (!url) {
|
|
491
|
+
this.navigationService.back();
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
if (url.startsWith('/')) {
|
|
495
|
+
url = url.substring(1);
|
|
496
|
+
}
|
|
497
|
+
const urlPathSegments = url.split('?')[0].split('#')[0].split('/');
|
|
498
|
+
let actionUrl = instance.action?.routeUrl ?? '';
|
|
499
|
+
if (actionUrl.startsWith('/')) {
|
|
500
|
+
actionUrl = actionUrl.substring(1);
|
|
501
|
+
}
|
|
502
|
+
const actionUrlSegments = actionUrl.split('/');
|
|
503
|
+
const redirectUrl = urlPathSegments.slice(0, urlPathSegments.length - actionUrlSegments.length).join('/');
|
|
504
|
+
this.router.navigateByUrl(`/${redirectUrl}`, { replaceUrl: true });
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Transform error of any type to mng error by using error mapper that could be provided by final project.
|
|
510
|
+
* @param error error of any type.
|
|
511
|
+
*
|
|
512
|
+
* @return mapped MngError.
|
|
513
|
+
*/
|
|
514
|
+
toMngActionError(error) {
|
|
515
|
+
const actionError = {
|
|
516
|
+
name: error?.name ?? 'UnknownError',
|
|
517
|
+
message: error?.message ?? 'Unknown error',
|
|
518
|
+
cause: error
|
|
519
|
+
};
|
|
520
|
+
if (error instanceof HttpErrorResponse) {
|
|
521
|
+
actionError.status = error.status;
|
|
522
|
+
actionError.statusDescription = error.statusText;
|
|
523
|
+
actionError.url = error.url ?? undefined;
|
|
524
|
+
}
|
|
525
|
+
return this.errorMapper.toMngError(error, actionError);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
MngActionExecutorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: MngActionExecutorService, deps: [{ token: i0.Injector }, { token: i1.Router }, { token: i2.DialogService }, { token: i3.ConfirmationService }, { token: i4.TranslateService }, { token: i5.MngConfigurationService }, { token: i6.MngNavigationService }, { token: i7.MngErrorMapperService }, { token: i8.MngLinkFormatterPipe }, { token: ACTION_EDITOR_DIALOG_COMPONENT_SETTING }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
529
|
+
MngActionExecutorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: MngActionExecutorService });
|
|
530
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: MngActionExecutorService, decorators: [{
|
|
531
|
+
type: Injectable
|
|
532
|
+
}], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.Router }, { type: i2.DialogService }, { type: i3.ConfirmationService }, { type: i4.TranslateService }, { type: i5.MngConfigurationService }, { type: i6.MngNavigationService }, { type: i7.MngErrorMapperService }, { type: i8.MngLinkFormatterPipe }, { type: i0.Type, decorators: [{
|
|
533
|
+
type: Inject,
|
|
534
|
+
args: [ACTION_EDITOR_DIALOG_COMPONENT_SETTING]
|
|
535
|
+
}] }]; } });
|
|
536
536
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWV4ZWN1dG9yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2FjdGlvbi1leGVjdXRvci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQ3ZELE9BQU8sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFpQixNQUFNLGVBQWUsQ0FBQztBQU1qRSxPQUFPLEVBQWEsSUFBSSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUMzRSxPQUFPLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUQsT0FBTyxFQUFDLGFBQWEsRUFBRSx1QkFBdUIsRUFBRSxjQUFjLEVBQUUsdUJBQXVCLEVBQUUsZ0JBQWdCLEVBQTZCLE1BQU0sNkJBQTZCLENBQUM7QUFHMUssT0FBTyxFQUFtQixzQkFBc0IsRUFBa0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RixPQUFPLEVBQUMsMkJBQTJCLEVBQUUsMEJBQTBCLEVBQUUsY0FBYyxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFHN0csT0FBTyxFQUFDLFNBQVMsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUlyRCxPQUFPLEVBQUMsc0NBQXNDLEVBQUMsTUFBTSxVQUFVLENBQUM7Ozs7Ozs7Ozs7QUFHaEUsTUFBTSxPQUFPLHdCQUF3QjtJQUdqQyxZQUNZLFFBQWtCLEVBQ2xCLE1BQWMsRUFDZCxhQUE0QixFQUM1QixtQkFBd0MsRUFDeEMsU0FBMkIsRUFDM0Isb0JBQTZDLEVBQzdDLGlCQUF1QyxFQUN2QyxXQUFrQyxFQUNsQyxhQUFtQyxFQUNhLDRCQUF1QztRQVR2RixhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ2xCLFdB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QWU7WUFDMUMsS0FBSyxFQUFFLEtBQUs7U0FDZixDQUFDO1FBQ0YsSUFBSSxLQUFLLFlBQVksaUJBQWlCLEVBQUU7WUFDcEMsV0FBVyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQ2xDLFdBQVcsQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDO1lBQ2pELFdBQVcsQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsSUFBSSxTQUFTLENBQUM7U0FDNUM7UUFDRCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztJQUMzRCxDQUFDOztxSEF6bUJRLHdCQUF3QixvVEFhckIsc0NBQXNDO3lIQWJ6Qyx3QkFBd0I7MkZBQXhCLHdCQUF3QjtrQkFEcEMsVUFBVTs7MEJBY0YsTUFBTTsyQkFBQyxzQ0FBc0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0h0dHBFcnJvclJlc3BvbnNlfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQge0luamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0b3IsIFR5cGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyLCBVcmxUcmVlfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuXG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtDb25maXJtYXRpb24sIENvbmZpcm1hdGlvblNlcnZpY2V9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7RGlhbG9nU2VydmljZSwgRHluYW1pY0RpYWxvZ0NvbmZpZ30gZnJvbSAncHJpbWVuZy9keW5hbWljZGlhbG9nJztcbmltcG9ydCB7T2JzZXJ2YWJsZSwgZnJvbSwgbWVyZ2VNYXAsIG9mLCBzd2l0Y2hNYXAsIHRocm93RXJyb3J9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtjYXRjaEVycm9yLCBmaWx0ZXIsIGZpcnN0LCBtYXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtBY3Rpb25Db250ZXh0LCBBY3Rpb25Db250ZXh0VmFsaWRhdGlvbiwgQWN0aW9uSW5zdGFuY2UsIEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLCBBY3Rpb25QYXJhbWV0ZXJzLCBJQWN0aW9uQ29uZmlybWF0aW9uU2VydmljZX0gZnJvbSAnLi4vY29tcG9uZW50cy9hY3Rpb24vbW9kZWxzJztcbmltcG9ydCB7TW5nVGFibGVDZWxsQ2xpY2tFdmVudH0gZnJvbSAnLi4vY29tcG9uZW50cy90YWJsZXZpZXcvbW9kZWxzJztcbmltcG9ydCB7SURhdGFQcm92aWRlciwgSUVkaXRvckRhdGFQcm92aWRlcn0gZnJvbSAnLi4vZGF0YS1wcm92aWRlcnMnO1xuaW1wb3J0IHtBY3Rpb25EZXNjcmlwdG9yLCBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yLCBUYWJsZURlc2NyaXB0b3J9IGZyb20gJy4uL2Rlc2NyaXB0b3JzJztcbmltcG9ydCB7QWN0aW9uQWN0aXZhdGlvblRyaWdnZXJFbnVtLCBBY3Rpb25FZGl0b3JEaWFsb2dTaXplRW51bSwgQWN0aW9uVHlwZUVudW19IGZyb20gJy4uL2Rlc2NyaXB0b3JzL3R5cGVzJztcbmltcG9ydCB7TW5nRXJyb3J9IGZyb20gJy4uL21vZGVscyc7XG5pbXBvcnQge01uZ0xpbmtGb3JtYXR0ZXJQaXBlfSBmcm9tICcuLi9waXBlcyc7XG5pbXBvcnQge0kxOG5VdGlscywgTm90aWZpY2F0aW9uVXRpbH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHtNbmdDb25maWd1cmF0aW9uU2VydmljZX0gZnJvbSAnLi9jb25maWd1cmF0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHtNbmdFcnJvck1hcHBlclNlcnZpY2V9IGZyb20gJy4vZXJyb3ItbWFwcGVyLnNlcnZpY2UnO1xuaW1wb3J0IHtNbmdOYXZpZ2F0aW9uU2VydmljZX0gZnJvbSAnLi9uYXZpZ2F0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHtBQ1RJT05fRURJVE9SX0RJQUxPR19DT01QT05FTlRfU0VUVElOR30gZnJvbSAnLi90b2tlbnMnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTW5nQWN0aW9uRXhlY3V0b3JTZXJ2aWNlIHtcbiAgICBwcml2YXRlIGRlYnVnID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgIHByaXZhdGUgZGlhbG9nU2VydmljZTogRGlhbG9nU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjb25maXJtYXRpb25TZXJ2aWNlOiBDb25maXJtYXRpb25TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjb25maWd1cmF0aW9uU2VydmljZTogTW5nQ29uZmlndXJhdGlvblNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbmF2aWdhdGlvblNlcnZpY2U6IE1uZ05hdmlnYXRpb25TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGVycm9yTWFwcGVyOiBNbmdFcnJvck1hcHBlclNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbGlua0Zvcm1hdHRlcjogTW5nTGlua0Zvcm1hdHRlclBpcGUsXG4gICAgICAgIEBJbmplY3QoQUNUSU9OX0VESVRPUl9ESUFMT0dfQ09NUE9ORU5UX1NFVFRJTkcpIHByaXZhdGUgZGVmYXVsdEVkaXRvckRpYWxvZ0NvbXBvbmVudDogVHlwZTxhbnk+XG4gICAgKSB7XG4gICAgICAgIC8vIHRoaXMuZGVidWcgPSB0cnVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBwcmVwYXJlQWN0aW9uQ29udGV4dFZhbGlkYXRpb248VCwgUz4oYWN0aW9uOiBBY3Rpb25EZXNjcmlwdG9yPFQ+LCBwYXJhbWV0ZXJzOiBBY3Rpb25QYXJhbWV0ZXJzPFQ+LCBkYXRhUHJvdmlkZXI/OiBJRGF0YVByb3ZpZGVyPFQsIFM+KTogQWN0aW9uQ29udGV4dFZhbGlkYXRpb248VCwgUz4ge1xuICAgICAgICBjb25zdCBjdHhEYXRhUHJvdmlkZXIgPSBkYXRhUHJvdmlkZXIgPz8gYWN0aW9uLmRhdGFQcm92aWRlciA/PyBwYXJhbWV0ZXJzLnZpZXdDb250YWluZXI/LmdldERhdGFQcm92aWRlcigpO1xuICAgICAgICBjb25zdCBjdHggPSBuZXcgQWN0aW9uQ29udGV4dFZhbGlkYXRpb248VCwgUz4oYWN0aW9uLCBwYXJhbWV0ZXJzLCBjdHhEYXRhUHJvdmlkZXIsIHRoaXMuZ2V0RGF0YVByb3ZpZGVyU2VydmljZShjdHhEYXRhUHJvdmlkZXIpID8/IHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiBjdHg7XG4gICAgfVxuXG4gICAgcHVibGljIHByZXBhcmVBY3Rpb25Db250ZXh0PFQsIFM+KFxuICAgICAgICBpbnN0YW5jZTogQWN0aW9uSW5zdGFuY2U8VCwgUz4sXG4gICAgICAgIHBhcmFtZXRlcnM6IEFjdGlvblBhcmFtZXRlcnM8VD4sXG4gICAgICAgIGRhdGFQcm92aWRlcj86IElEYXRhUHJvdmlkZXI8VCwgUz4sXG4gICAgICAgIHByZXZpb3VzQWN0aW9uSW5zdGFuY2U/OiBBY3Rpb25JbnN0YW5jZTx1bmtub3duLCB1bmtub3duPlxuICAgICk6IEFjdGlvbkNvbnRleHQ8VCwgUz4ge1xuICAgICAgICBjb25zdCBjdHhEYXRhUHJvdmlkZXIgPSBkYXRhUHJvdmlkZXIgPz8gaW5zdGFuY2UuYWN0aW9uLmRhdGFQcm92aWRlciA/PyBwYXJhbWV0ZXJzLnZpZXdDb250YWluZXI/LmdldERhdGFQcm92aWRlcigpO1xuICAgICAgICBjb25zdCBjdHggPSBuZXcgQWN0aW9uQ29udGV4dDxULCBTPihpbnN0YW5jZSwgcGFyYW1ldGVycywgJ3J1bicsIGN0eERhdGFQcm92aWRlciwgdGhpcy5nZXREYXRhUHJvdmlkZXJTZXJ2aWNlKGN0eERhdGFQcm92aWRlcikgPz8gdW5kZWZpbmVkKTtcbiAgICAgICAgY3R4LnByZXZpb3VzQWN0aW9uSW5zdGFuY2UgPSBwcmV2aW91c0FjdGlvbkluc3RhbmNlO1xuICAgICAgICBpbnN0YW5jZS5uZXdDb250ZXh0KGN0eCk7XG4gICAgICAgIHJldHVybiBjdHg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJlcGFyZXMgYWN0aW9uIGV4ZWMgY29udGV4dCBmb3IgYWN0aW9uIG9mIHR5cGUgZWRpdG9yLlxuICAgICAqXG4gICAgICogQHBhcmFtIGl0ZW0gSXRlbSBpbnN0YW5jZSAoaWYgZXhpc3RzKS5cbiAgICAgKiBAcGFyYW0gaXRlbUlkIEl0ZW0gaWQgKGlmIGV4aXN0cykuXG4gICAgICogQHBhcmFtIGRhdGFQcm92aWRlciBEYXRhIHByb3ZpZGVyLlxuICAgICAqIEBwYXJhbSBzb3VyY2VDb21wb25lbnQgU291cmNlIGNvbXBvbmVudCBmcm9tIHdoZXJlIHRoZSBjb250ZXh0IHByZXBhcmF0aW9uIHdhcyBjYWxsZWQuXG4gICAgICogQHBhcmFtIHZpZXdDb250YWluZXIgVmlldyBjb250YWluZXIvc2VydmljZS5cbiAgICAgKiBAcGFyYW0gYWN0aW9uRGF0YSBBZGRpdGlvbmFsIGFjdGlvbiBkYXRhLlxuICAgICAqL1xuICAgIHByaXZhdGUgcHJlcGFyZUNvbnRleHRGb3JFZGl0b3I8VCwgUz4oXG4gICAgICAgIGluc3RhbmNlOiBBY3Rpb25JbnN0YW5jZTxULCBTPixcbiAgICAgICAgcGFyYW1ldGVyczogQWN0aW9uUGFyYW1ldGVyczxUPixcbiAgICAgICAgZnVuY3Rpb25OYW1lOiAnc3VibWl0JyB8ICdmZXRjaCcsXG4gICAgICAgIGRhdGFQcm92aWRlcj86IElFZGl0b3JEYXRhUHJvdmlkZXI8VCwgUz4sXG4gICAgICAgIHByZXZpb3VzQWN0aW9uSW5zdGFuY2U/OiBBY3Rpb25JbnN0YW5jZTx1bmtub3duLCB1bmtub3duPlxuICAgICk6IEFjdGlvbkNvbnRleHQ8VCwgUz4ge1xuICAgICAgICBjb25zdCBlZGl0b3JBY3Rpb24gPSBpbnN0YW5jZS5hY3Rpb24gYXMgQWN0aW9uRWRpdG9yRGVzY3JpcHRvcjxUPjtcbiAgICAgICAgbGV0IGN0eERhdGFQcm92aWRlciA9IGRhdGFQcm92aWRlcjtcbiAgICAgICAgaWYgKCFjdHhEYXRhUHJvdmlkZXIgJiYgZWRpdG9yQWN0aW9uLmRhdGFQcm92aWRlcikge1xuICAgICAgICAgICAgY3R4RGF0YVByb3ZpZGVyID0gZWRpdG9yQWN0aW9uLmRhdGFQcm92aWRlcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWN0eERhdGFQcm92aWRlcikge1xuICAgICAgICAgICAgY29uc3Qgdmlld0NvbnRhaW5lckRhdGFQcm92aWRlciA9IHBhcmFtZXRlcnMudmlld0NvbnRhaW5lcj8uZ2V0RGF0YVByb3ZpZGVyKCk7XG4gICAgICAgICAgICBpZiAodmlld0NvbnRhaW5lckRhdGFQcm92aWRlcikge1xuICAgICAgICAgICAgICAgIGN0eERhdGFQcm92aWRlciA9IHZpZXdDb250YWluZXJEYXRhUHJvdmlkZXIgYXMgSUVkaXRvckRhdGFQcm92aWRlcjxULCBTPjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjdHggPSBuZXcgQWN0aW9uQ29udGV4dDxULCBTPihpbnN0YW5jZSwgcGFyYW1ldGVycywgZnVuY3Rpb25OYW1lLCBjdHhEYXRhUHJvdmlkZXIsIHRoaXMuZ2V0RGF0YVByb3ZpZGVyU2VydmljZShjdHhEYXRhUHJvdmlkZXIpID8/IHVuZGVmaW5lZCk7XG4gICAgICAgIGN0eC5wcmV2aW91c0FjdGlvbkluc3RhbmNlID0gcHJldmlvdXNBY3Rpb25JbnN0YW5jZTtcbiAgICAgICAgaW5zdGFuY2UubmV3Q29udGV4dChjdHgpO1xuICAgICAgICByZXR1cm4gY3R4O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJ1bnMgYWN0aW9uIGNvbnRleHQgYnkgc3VibWl0dGluZyBleGVjdXRpb24gcmVzdWx0cy9lcnJvcnMgdG8gY29udGV4dCwgd2F0Y2hpbmcgb3ZlciBpbnN0YW5jZSByZXN1bHRzL2Vycm9ycywgZGlzcGxheWluZyBub3RpZmljYXRpb25zLFxuICAgICAqIHJ1bm5pbmcgbmV4dC9lcnJvciBhY3Rpb24gYW5kIHRyaWdnZXJpbmcgZGlzbWlzcyBvZiBhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIEFjdGlvbiBwYXJhbWV0ZXJzIGZvciBjb250ZXh0LlxuICAgICAqIEBwYXJhbSBkYXRhUHJvdmlkZXIgRWRpdG9yIGRhdGEgcHJvdmlkZXIgZm9yIGNvbnRleHQuXG4gICAgICogQHBhcmFtIGluc3RhbmNlIE9wdGlvbmFsIGV4aXN0aW5nIGFjdGlvbiBpbnN0YW5jZSAoaWYgbm9uIHByb3ZpZGVkLCBuZXcgd2lsbCBiZSBjcmVhdGVkKS5cbiAgICAgKiBAcGFyYW0gcHJldmlvdXNBY3Rpb25JbnN0YW5jZSBPcHRpb25hbCBwcmV2aW91cyBhY3Rpb24gaW5zdGFuY2UgdG8gbGluayBpbiBuZXh0IGluc3RhbmNlLlxuICAgICAqXG4gICAgICogQHJldHVybiBBY3Rpb24gY29udGV4dCBmb3Igc3VibWl0ICg9cnVuKSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcnVuQWN0aW9uQ29udGV4dDxULCBTPihjdHg6IEFjdGlvbkNvbnRleHQ8VCwgUz4pOiBPYnNlcnZhYmxlPFQgfCBudWxsIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGNvbnN0IGlzTWFpblJ1bkZuID0gY3R4LmZ1bmN0aW9uTmFtZSA9PT0gJ3N1Ym1pdCcgfHwgY3R4LmZ1bmN0aW9uTmFtZSA9PT0gJ3J1bic7XG4gICAgICAgIGxldCBhY3Rpb25FZGl0b3I6IEFjdGlvbkVkaXRvckRlc2NyaXB0b3I8VD47XG5cbiAgICAgICAgbGV0IGZuT2JzOiAoY3R4OiBBY3Rpb25Db250ZXh0PFQsIFM+KSA9PiBPYnNlcnZhYmxlPFQgfCBudWxsIHwgdW5kZWZpbmVkPjtcbiAgICAgICAgc3dpdGNoIChjdHguZnVuY3Rpb25OYW1lKSB7XG4gICAgICAgICAgICBjYXNlICdzdWJtaXQnOlxuICAgICAgICAgICAgICAgIGFjdGlvbkVkaXRvciA9IGN0eC5pbnN0YW5jZS5hY3Rpb24gYXMgQWN0aW9uRWRpdG9yRGVzY3JpcHRvcjxUPjtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbkVkaXRvci5zdWJtaXRGdW5jdGlvbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgRXJyb3IoYFN1Ym1pdCBmdW5jdGlvbiBmb3IgYWN0aW9uICR7YWN0aW9uRWRpdG9yLmFjdGlvbk5hbWVMb25nfSBjYW5ub3QgYmUgaW52b2tlZC5gKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZuT2JzID0gYWN0aW9uRWRpdG9yLnN1Ym1pdEZ1bmN0aW9uO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZmV0Y2gnOlxuICAgICAgICAgICAgICAgIGFjdGlvbkVkaXRvciA9IGN0eC5pbnN0YW5jZS5hY3Rpb24gYXMgQWN0aW9uRWRpdG9yRGVzY3JpcHRvcjxUPjtcbiAgICAgICAgICAgICAgICBmbk9icyA9IGFjdGlvbkVkaXRvci5mZXRjaEZ1bmN0aW9uO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncnVuJzpcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgZm5PYnMgPSBjdHguaW5zdGFuY2UuYWN0aW9uLnJ1bkZ1bmN0aW9uO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmV0T2JzID0gb2Yodm9pZCAwKS5waXBlKFxuICAgICAgICAgICAgZmlyc3QoKSxcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGlzTWFpblJ1bkZuKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIG1haW4gcnVuIGZ1bmN0aW9uLCBhbHNvIHNldCBsb2FkaW5nIHRvIHRydWVcbiAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uUnVuU3RhcnQ7XG4gICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5pc1J1bkxvYWRpbmdTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmV0Y2hTdGFydDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gc3RhcnQgY29udGV4dCBleGVjdXRpb24gdG8gbWFyayBleGVjdXRpb24gbG9hZGluZ1xuICAgICAgICAgICAgICAgIGN0eC5leGVjdXRpb25TdGFydCgpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZuT2JzKGN0eCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG1lcmdlTWFwKHJ1blJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgLy8gc2V0IG5leHQgc3RhdGUgZGVwZW5kaW5nIG9uIHJ1blxuICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5zdGF0ZSA9IGlzTWFpblJ1bkZuID8gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uUnVuRW5kIDogQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmV0Y2hFbmQ7XG4gICAgICAgICAgICAgICAgLy8gc2V0IGV4ZWN1dGlvbiByZXN1bHRcbiAgICAgICAgICAgICAgICBjdHguZXhlY3V0aW9uTmV4dChydW5SZXN1bHQsIGlzTWFpblJ1bkZuKTtcblxuICAgICAgICAgICAgICAgIGlmIChpc01haW5SdW5Gbikge1xuICAgICAgICAgICAgICAgICAgICAvLyBzZXQgaW5zdGFuY2UgZmluYWwgcmVzdWx0IG9uIG1haW4gcnVuIGV4ZWN1dGlvblxuICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UucmVzdWx0ID0gcnVuUmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuaXNSdW5Mb2FkaW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgbm90aWZpY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgIGlmIChjdHguaW5zdGFuY2UuYWN0aW9uLmhhc1J1bk5vdGlmaWNhdGlvblN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5ub3RpZmljYXRpb24gPSBOb3RpZmljYXRpb25VdGlsLmFjdGlvbk5vdGlmaWNhdGlvblN1Y2Nlc3MoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc2xhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmFjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguZnVuY3Rpb25OYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5hY3Rpb24ucnVuTm90aWZpY2F0aW9uU3VjY2Vzc1RpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5hY3Rpb24ucnVuTm90aWZpY2F0aW9uU3VjY2Vzc01lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnBhcmFtZXRlcnMudmlld0NvbnRhaW5lciA/PyB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LnBhcmFtZXRlcnM/Lml0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgcG9zc2libGUgYWZ0ZXIgcnVuIGFjdGlvblxuICAgICAgICAgICAgICAgICAgICBpZiAoY3R4Lmluc3RhbmNlLmFjdGlvbi5hZnRlclJ1bkFjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFyayBuZXcgc3RhdGUgZm9yIG5leHQgYWN0aW9uIHN0YXJ0XG4gICAgICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5OZXh0QWN0aW9uU3RhcnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXh0QWN0aW9uSW5zdGFuY2UgPSB0aGlzLmFjdGl2YXRlQWN0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5hY3Rpb24uYWZ0ZXJSdW5BY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEFjdGlvblBhcmFtZXRlcnMoY3R4LnBhcmFtZXRlcnMuaXRlbUlkLCBydW5SZXN1bHQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC53aXRoQWN0aW9uRGF0YShjdHgucGFyYW1ldGVycy5hY3Rpb25EYXRhKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud2l0aFJvdXRlKGN0eC5wYXJhbWV0ZXJzLnJvdXRlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud2l0aFNvdXJjZUNvbXBvbmVudChjdHgucGFyYW1ldGVycy5zb3VyY2VDb21wb25lbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC53aXRoVmlld0NvbnRhaW5lcihjdHgucGFyYW1ldGVycy52aWV3Q29udGFpbmVyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlIGFzIEFjdGlvbkluc3RhbmNlPHVua25vd24sIHVua25vd24+XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLm5leHRBY3Rpb25JbnN0YW5jZSA9IG5leHRBY3Rpb25JbnN0YW5jZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmluaXNoIGN1cnJlbnQgYWN0aW9uIHdoZW4gbmV4dCBhY3Rpb24gZmluaXNoZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXh0QWN0aW9uSW5zdGFuY2Uuc3RhdGUkLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHN0YXRlID0+IHN0YXRlID49IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZpbmlzaFN1Y2Nlc3MpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5zdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLk5leHRBY3Rpb25FbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBydW5SZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gb2YocnVuUmVzdWx0KTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbWFwKHJ1blJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGlzTWFpblJ1bkZuKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGRlYWN0aXZhdGUgYWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVhY3RpdmF0ZUFjdGlvbihjdHguaW5zdGFuY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcnVuUmVzdWx0O1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBjYXRjaEVycm9yKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgLy8gdHJhbnNmb3JtIGVycm9yIHRvIG1uZyBhY3Rpb24gZXJyb3JcbiAgICAgICAgICAgICAgICBjb25zdCBhY3Rpb25FcnJvciA9IHRoaXMudG9NbmdBY3Rpb25FcnJvcihlcnIpO1xuXG4gICAgICAgICAgICAgICAgLy8gc2V0IGluc3RhbmNlIHN0YXRlIHRvIGVycm9yXG4gICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLnN0YXRlID0gaXNNYWluUnVuRm4gPyBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5SdW5FcnJvciA6IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkZldGNoRXJyb3I7XG4gICAgICAgICAgICAgICAgLy8gbWFyayBleGVjdXRpb24gZXJyb3Igb24gY29udGV4dFxuICAgICAgICAgICAgICAgIGN0eC5leGVjdXRpb25FcnJvcihhY3Rpb25FcnJvcik7XG5cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JPYnMgPSBvZih2b2lkIDApO1xuICAgICAgICAgICAgICAgIGlmIChpc01haW5SdW5Gbikge1xuICAgICAgICAgICAgICAgICAgICBjdHguaW5zdGFuY2UuZXJyb3IgPSBlcnI7XG4gICAgICAgICAgICAgICAgICAgIGN0eC5pbnN0YW5jZS5pc1J1bkxvYWRpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBlcnJvciBub3RpZmljYXRpb25cbiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eC5pbnN0YW5jZS5hY3Rpb24uaGFzUnVuTm90aWZpY2F0aW9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkVycm9yLm5vdGlmaWNhdGlvbiA9IE5vdGlmaWNhdGlvblV0aWwuYWN0aW9uTm90aWZpY2F0aW9uRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc2xhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmFjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25FcnJvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHguZnVuY3Rpb25OYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5wYXJhbWV0ZXJzLnZpZXdDb250YWluZXIgPz8gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5wYXJhbWV0ZXJzLml0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgcG9zc2libGUgZXJyb3IgYWN0aW9uIGlmIHJ1blxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNNYWluUnVuRm4gJiYgY3R4Lmluc3RhbmNlLmFjdGlvbi5vblJ1bkVycm9yQWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjYW5ub3Qgc3RhcnQgd2l0aCB0cmlnZ2VyLCBiZWNhdXNlIHJvdXRpbmcgbWlnaHQgYmUgcHJvYmxlbWF0aWMgKGxvdXNpbmcgcHJldmlvdXMgcmVzdWx0cyBldGMuKVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JBY3Rpb25JbnN0YW5jZSA9IHRoaXMuYWN0aXZhdGVBY3Rpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmFjdGlvbi5vblJ1bkVycm9yQWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBBY3Rpb25QYXJhbWV0ZXJzKGN0eC5wYXJhbWV0ZXJzLml0ZW1JZCwgY3R4LnBhcmFtZXRlcnMuaXRlbSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhBY3Rpb25EYXRhKGN0eC5wYXJhbWV0ZXJzLmFjdGlvbkRhdGEpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC53aXRoUm91dGUoY3R4LnBhcmFtZXRlcnMucm91dGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC53aXRoU291cmNlQ29tcG9uZW50KGN0eC5wYXJhbWV0ZXJzLnNvdXJjZUNvbXBvbmVudClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhWaWV3Q29udGFpbmVyKGN0eC5wYXJhbWV0ZXJzLnZpZXdDb250YWluZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lmluc3RhbmNlLmVycm9yQWN0aW9uSW5zdGFuY2UgPSBlcnJvckFjdGlvbkluc3RhbmNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JPYnMgPSBlcnJvckFjdGlvbkluc3RhbmNlLnN0YXRlJC5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihzdGF0ZSA9PiBzdGF0ZSA+PSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GaW5pc2hTdWNjZXNzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXAoKCkgPT4gdm9pZCAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIGxpc3RlIGFuZCBtYXAgb25seSB0byBtYXJrIGluc3RhbmNlIHN0YXRlIGFzIGZpbmlzaGVkIGVycm9yIHN0YXRlXG4gICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yT2JzLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWFjdGl2YXRlIGFjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWFjdGl2YXRlQWN0aW9uKGN0eC5pbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyByZXRocm93IGVycm9yIHRvIHByb3BhZ2F0ZSBmdXJoZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGFjdGlvbkVycm9yO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuXG4gICAgICAgIHJldE9icy5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgbmV4dDogcmVzID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1Zykge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKGBBY3Rpb25Db250ZXh0ICR7Y3R4LmNvbnRleHRMb25nTmFtZX0gZXhlY3V0aW9uIG5leHQgZXZlbnRgLCByZXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZXJyID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1Zykge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKGBBY3Rpb25Db250ZXh0ICR7Y3R4LmNvbnRleHRMb25nTmFtZX0gZXhlY3V0aW9uIGVycm9yIGV2ZW50YCwgZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXRPYnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVucyBlZGl0b3IgYWN0aW9uJ3Mgc3VibWl0ICg9bWFpbiBydW4pIGZ1bmN0aW9uIGJ5IGNyZWF0aW5nIG5ldyBhY3Rpb24gY29udGV4dCBmb3IgYWN0aW9uIGluc3RhbmNlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGFjdGlvbiBBY3Rpb24gZGVzY3JpcHRvci5cbiAgICAgKiBAcGFyYW0gcGFyYW1ldGVycyBBY3Rpb24gcGFyYW1ldGVycyBmb3IgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gZGF0YVByb3ZpZGVyIEVkaXRvciBkYXRhIHByb3ZpZGVyIGZvciBjb250ZXh0LlxuICAgICAqIEBwYXJhbSBpbnN0YW5jZSBPcHRpb25hbCBleGlzdGluZyBhY3Rpb24gaW5zdGFuY2UgKGlmIG5vbiBwcm92aWRlZCwgbmV3IHdpbGwgYmUgY3JlYXRlZCkuXG4gICAgICogQHBhcmFtIHByZXZpb3VzQWN0aW9uSW5zdGFuY2UgT3B0aW9uYWwgcHJldmlvdXMgYWN0aW9uIGluc3RhbmNlIHRvIGxpbmsgaW4gbmV4dCBpbnN0YW5jZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gQWN0aW9uIGNvbnRleHQgZm9yIHN1Ym1pdCAoPXJ1bikgZnVuY3Rpb24uXG4gICAgICovXG4gICAgcHVibGljIHJ1bkVkaXRvclNhdmU8VCwgUz4oXG4gICAgICAgIGFjdGlvbjogQWN0aW9uRWRpdG9yRGVzY3JpcHRvcjxUPixcbiAgICAgICAgcGFyYW1ldGVyczogQWN0aW9uUGFyYW1ldGVyczxUPixcbiAgICAgICAgZGF0YVByb3ZpZGVyPzogSUVkaXRvckRhdGFQcm92aWRlcjxULCBTPixcbiAgICAgICAgaW5zdGFuY2U/OiBBY3Rpb25JbnN0YW5jZTxULCBTPixcbiAgICAgICAgcHJldmlvdXNBY3Rpb25JbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPHVua25vd24sIHVua25vd24+XG4gICAgKTogQWN0aW9uQ29udGV4dDxULCBTPiB7XG4gICAgICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBuZXcgaW5zdGFuY2UgaWYgbm9uIHByb3ZpZGVkXG4gICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBBY3Rpb25JbnN0YW5jZTxULCBTPihhY3Rpb24sIEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkFjdGl2YXRpb25FbmQsIHRoaXMuZGVidWcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLnByZXBhcmVDb250ZXh0Rm9yRWRpdG9yKGluc3RhbmNlLCBwYXJhbWV0ZXJzLCAnc3VibWl0JywgZGF0YVByb3ZpZGVyLCBwcmV2aW91c0FjdGlvbkluc3RhbmNlKTtcbiAgICAgICAgdGhpcy5ydW5BY3Rpb25Db250ZXh0KGNvbnRleHQpO1xuICAgICAgICByZXR1cm4gY29udGV4dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHNlcnZpY2UgaW5zdGFuY2Ugb2YgZGF0YSBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBkYXRhUHJvdmlkZXIgRGF0YSBwcm92aWRlciBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBwcml2YXRlIGdldERhdGFQcm92aWRlclNlcnZpY2U8VCwgUz4oZGF0YVByb3ZpZGVyPzogSURhdGFQcm92aWRlcjxULCBTPik6IFMgfCBudWxsIHtcbiAgICAgICAgaWYgKGRhdGFQcm92aWRlcj8uc2VydmljZVR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmluamVjdG9yLmdldDxTPihkYXRhUHJvdmlkZXIuc2VydmljZVR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSdW5zIGVkaXRvciBhY3Rpb24ncyBmZXRjaCBmdW5jdGlvbiBieSBjcmVhdGluZyBuZXcgYWN0aW9uIGNvbnRleHQgZm9yIGFjdGlvbiBpbnN0YW5jZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhY3Rpb24gQWN0aW9uIGRlc2NyaXB0b3IuXG4gICAgICogQHBhcmFtIHBhcmFtZXRlcnMgQWN0aW9uIHBhcmFtZXRlcnMgZm9yIGNvbnRleHQuXG4gICAgICogQHBhcmFtIGRhdGFQcm92aWRlciBFZGl0b3IgZGF0YSBwcm92aWRlciBmb3IgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgT3B0aW9uYWwgZXhpc3RpbmcgYWN0aW9uIGluc3RhbmNlIChpZiBub24gcHJvdmlkZWQsIG5ldyB3aWxsIGJlIGNyZWF0ZWQpLlxuICAgICAqIEBwYXJhbSBwcmV2aW91c0FjdGlvbkluc3RhbmNlIE9wdGlvbmFsIHByZXZpb3VzIGFjdGlvbiBpbnN0YW5jZSB0byBsaW5rIGluIG5leHQgaW5zdGFuY2UuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIEFjdGlvbiBjb250ZXh0IGZvciBmZXRjaCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcnVuRWRpdG9yRmV0Y2g8VCwgUz4oXG4gICAgICAgIGFjdGlvbjogQWN0aW9uRWRpdG9yRGVzY3JpcHRvcjxUPixcbiAgICAgICAgcGFyYW1ldGVyczogQWN0aW9uUGFyYW1ldGVyczxUPixcbiAgICAgICAgZGF0YVByb3ZpZGVyPzogSUVkaXRvckRhdGFQcm92aWRlcjxULCBTPixcbiAgICAgICAgaW5zdGFuY2U/OiBBY3Rpb25JbnN0YW5jZTxULCBTPixcbiAgICAgICAgcHJldmlvdXNBY3Rpb25JbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPHVua25vd24sIHVua25vd24+XG4gICAgKTogQWN0aW9uQ29udGV4dDxULCBTPiB7XG4gICAgICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBuZXcgaW5zdGFuY2UgaWYgbm9uIHByb3ZpZGVkXG4gICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBBY3Rpb25JbnN0YW5jZTxULCBTPihhY3Rpb24sIEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkFjdGl2YXRpb25FbmQsIHRoaXMuZGVidWcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLnByZXBhcmVDb250ZXh0Rm9yRWRpdG9yKGluc3RhbmNlLCBwYXJhbWV0ZXJzLCAnZmV0Y2gnLCBkYXRhUHJvdmlkZXIsIHByZXZpb3VzQWN0aW9uSW5zdGFuY2UpO1xuICAgICAgICB0aGlzLnJ1bkFjdGlvbkNvbnRleHQoY29udGV4dCk7XG4gICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJ1bnMgYWN0aW9uJ3MgbWFpbiBydW4gZnVuY3Rpb24gYnkgY3JlYXRpbmcgbmV3IGFjdGlvbiBjb250ZXh0IGZvciBhY3Rpb24gaW5zdGFuY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIEFjdGlvbiBwYXJhbWV0ZXJzIGZvciBjb250ZXh0IHJ1bi5cbiAgICAgKiBAcGFyYW0gZGF0YVByb3ZpZGVyIERhdGEgcHJvdmlkZXIgZm9yIGNvbnRleHQgcnVuLlxuICAgICAqIEBwYXJhbSBpbnN0YW5jZSBPcHRpb25hbCBleGlzdGluZyBhY3Rpb24gaW5zdGFuY2UgKGlmIG5vbiBwcm92aWRlZCwgbmV3IHdpbGwgYmUgY3JlYXRlZCkuXG4gICAgICogQHBhcmFtIHByZXZpb3VzQWN0aW9uSW5zdGFuY2UgT3B0aW9uYWwgcHJldmlvdXMgYWN0aW9uIGluc3RhbmNlIHRvIGxpbmsgaW4gbmV4dCBpbnN0YW5jZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gQWN0aW9uIGNvbnRleHQgZm9yIHJ1biBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcnVuQWN0aW9uPFQsIFM+KFxuICAgICAgICBhY3Rpb246IEFjdGlvbkRlc2NyaXB0b3I8VD4sXG4gICAgICAgIHBhcmFtZXRlcnM6IEFjdGlvblBhcmFtZXRlcnM8VD4sXG4gICAgICAgIGRhdGFQcm92aWRlcj86IElEYXRhUHJvdmlkZXI8VCwgUz4sXG4gICAgICAgIGluc3RhbmNlPzogQWN0aW9uSW5zdGFuY2U8VCwgUz4sXG4gICAgICAgIHByZXZpb3VzQWN0aW9uSW5zdGFuY2U/OiBBY3Rpb25JbnN0YW5jZTx1bmtub3duLCB1bmtub3duPlxuICAgICk6IEFjdGlvbkNvbnRleHQ8VCwgUz4ge1xuICAgICAgICBpZiAoIWluc3RhbmNlKSB7XG4gICAgICAgICAgICAvLyBjcmVhdGUgbmV3IGluc3RhbmNlIGlmIG5vbiBwcm92aWRlZFxuICAgICAgICAgICAgaW5zdGFuY2UgPSBuZXcgQWN0aW9uSW5zdGFuY2U8VCwgUz4oYWN0aW9uLCBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5BY3RpdmF0aW9uRW5kLCB0aGlzLmRlYnVnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5wcmVwYXJlQWN0aW9uQ29udGV4dChpbnN0YW5jZSwgcGFyYW1ldGVycywgZGF0YVByb3ZpZGVyLCBwcmV2aW91c0FjdGlvbkluc3RhbmNlKTtcbiAgICAgICAgaWYgKGFjdGlvbi5oYXNSdW5Db25maXJtYXRpb24pIHtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUNvbXBvbmVudCA9IHBhcmFtZXRlcnM/LnNvdXJjZUNvbXBvbmVudDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc291cmNlQ29tcG9uZW50Py5nZXRDb25maXJtYXRpb25TZXJ2aWNlICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBzb3VyY2VDb21wb25lbnQ/LmdldENvbmZpcm1hdGlvblNlcnZpY2VJbnN0YW5jZUtleSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU291cmNlIGNvbXBvbmVudCAke3NvdXJjZUNvbXBvbmVudH0gc2hvdWxkIGJlIGltcGxlbWVudGluZyBJQ29uZmlybWF0aW9uU2VydmljZSBpbnRlcmZhY2UgdG8gYmUgYWJsZSB0byBwcm92aWRlIGNvbmZpcm1hdGlvbiBmdW5jdGlvbmFsaXR5LmApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzcmNDb25maXJtQ29tcG9uZW50ID0gc291cmNlQ29tcG9uZW50IGFzIElBY3Rpb25Db25maXJtYXRpb25TZXJ2aWNlO1xuICAgICAgICAgICAgbGV0IGNvbmZpcm1QYXJhbXM6IENvbmZpcm1hdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBrZXk6IHNyY0NvbmZpcm1Db21wb25lbnQuZ2V0Q29uZmlybWF0aW9uU2VydmljZUluc3RhbmNlS2V5KGFjdGlvbiksXG4gICAgICAgICAgICAgICAgYWNjZXB0VmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVqZWN0VmlzaWJsZTogZmFsc2VcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBwYXJhbWV0ZXJzLml0ZW07XG4gICAgICAgICAgICBpZiAoYWN0aW9uLnJ1bkNvbmZpcm1hdGlvblRpdGxlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcy5oZWFkZXIgPSBJMThuVXRpbHMuQWN0aW9uLmdldCh0aGlzLnRyYW5zbGF0ZSwgYWN0aW9uLCAnY29uZmlybS50aXRsZScsIGFjdGlvbi5ydW5Db25maXJtYXRpb25UaXRsZSwgaXRlbSwgJ2dlbmVyYWwuY29uZmlybWF0aW9uJykgPz8gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFjdGlvbi5ydW5Db25maXJtYXRpb25NZXNzYWdlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcy5tZXNzYWdlID0gSTE4blV0aWxzLkFjdGlvbi5nZXQodGhpcy50cmFuc2xhdGUsIGFjdGlvbiwgJ2NvbmZpcm0ubWVzc2FnZScsIGFjdGlvbi5ydW5Db25maXJtYXRpb25NZXNzYWdlLCBpdGVtLCAnZ2VuZXJhbC5jb25maXJtYXRpb24nKSA/PyB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYWN0aW9uLnJ1bkNvbmZpcm1hdGlvbkljb24gIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25maXJtUGFyYW1zLmljb24gPSBhY3Rpb24ucnVuQ29uZmlybWF0aW9uSWNvbiA9PT0gdW5kZWZpbmVkID8gJ3BpIHBpLWV4Y2xhbWF0aW9uLXRyaWFuZ2xlJyA6IGFjdGlvbi5ydW5Db25maXJtYXRpb25JY29uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFjdGlvbi5ydW5Db25maXJtYXRpb25BY2NlcHRUaXRsZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbmZpcm1QYXJhbXMuYWNjZXB0TGFiZWwgPSBJMThuVXRpbHMuQWN0aW9uLmdldCh0aGlzLnRyYW5zbGF0ZSwgYWN0aW9uLCAnY29uZmlybS5hY2NlcHQnLCBhY3Rpb24ucnVuQ29uZmlybWF0aW9uQWNjZXB0VGl0bGUsIGl0ZW0sICdnZW5lcmFsLnllcycpID8/IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBjb25maXJtUGFyYW1zLmFjY2VwdFZpc2libGUgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFjdGlvbi5ydW5Db25maXJtYXRpb25SZWplY3RUaXRsZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbmZpcm1QYXJhbXMucmVqZWN0TGFiZWwgPSBJMThuVXRpbHMuQWN0aW9uLmdldCh0aGlzLnRyYW5zbGF0ZSwgYWN0aW9uLCAnY29uZmlybS5yZWplY3QnLCBhY3Rpb24ucnVuQ29uZmlybWF0aW9uUmVqZWN0VGl0bGUsIGl0ZW0sICdnZW5lcmFsLm5vJykgPz8gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGNvbmZpcm1QYXJhbXMucmVqZWN0VmlzaWJsZSA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbmZpcm1QYXJhbXMuYWNjZXB0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGluc3RhbmNlIS5zdGF0ZSA9IEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLlJ1bkNvbmZpcm1hdGlvbkVuZEFjY2VwdDtcbiAgICAgICAgICAgICAgICB0aGlzLnJ1bkFjdGlvbkNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25maXJtUGFyYW1zLnJlamVjdCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZSEuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5SdW5Db25maXJtYXRpb25FbmRSZWplY3Q7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWFjdGl2YXRlQWN0aW9uKGluc3RhbmNlISk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoYWN0aW9uLnJ1bkNvbmZpcm1hdGlvbkNvbmZpZ01hcEZuKSB7XG4gICAgICAgICAgICAgICAgY29uZmlybVBhcmFtcyA9IGFjdGlvbi5ydW5Db25maXJtYXRpb25Db25maWdNYXBGbihjb250ZXh0LCBjb25maXJtUGFyYW1zKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29udGV4dC5jb25maXJtYXRpb24gPSBjb25maXJtUGFyYW1zO1xuICAgICAgICAgICAgaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5SdW5Db25maXJtYXRpb25TdGFydDtcbiAgICAgICAgICAgIHNyY0NvbmZpcm1Db21wb25lbnQuZ2V0Q29uZmlybWF0aW9uU2VydmljZSgpLmNvbmZpcm0oY29uZmlybVBhcmFtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJ1bkFjdGlvbkNvbnRleHQoY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWN0aXZhdGVzIGFjdGlvbiAoaW4gY2FzZSBvZiBkaWFsb2csIGRpYWxvZyB3aWxsIGJlIG9wZW5lZCkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBwYXJhbWV0ZXJzIEFjdGlvbiBwYXJhbWV0ZXJzIGZvciBhY3RpdmF0aW9uIG9mIGFjdGlvbiBpbnN0YW5jZS5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgT3B0aW9uYWwgZXhpc3RpbmcgYWN0aW9uIGluc3RhbmNlIChpZiBub24gcHJvdmlkZWQsIG5ldyB3aWxsIGJlIGNyZWF0ZWQpLlxuICAgICAqIEBwYXJhbSBwcmV2aW91c0FjdGlvbkluc3RhbmNlIE9wdGlvbmFsIHByZXZpb3VzIGFjdGlvbiBpbnN0YW5jZSB0byBsaW5rIGluIG5leHQgaW5zdGFuY2UuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIEFjdGlvbiBpbnN0YW5jZSAtIGlmIG5vbiBwcm92aWRlZCBpbiBwYXJhbWV0ZXJzLCB0aGUgbmV3bHkgY3JlYXRlZCB3aWxsIGJlIHJldHVybmVkLlxuICAgICAqL1xuICAgIHB1YmxpYyBhY3RpdmF0ZUFjdGlvbjxULCBTPihcbiAgICAgICAgYWN0aW9uOiBBY3Rpb25EZXNjcmlwdG9yPFQ+LFxuICAgICAgICBwYXJhbWV0ZXJzOiBBY3Rpb25QYXJhbWV0ZXJzPFQ+LFxuICAgICAgICBpbnN0YW5jZT86IEFjdGlvbkluc3RhbmNlPFQsIFM+LFxuICAgICAgICBwcmV2aW91c0FjdGlvbkluc3RhbmNlPzogQWN0aW9uSW5zdGFuY2U8dW5rbm93biwgdW5rbm93bj5cbiAgICApOiBBY3Rpb25JbnN0YW5jZTxULCBTPiB7XG4gICAgICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBuZXcgaW5zdGFuY2UgaWYgbm9uIHByb3ZpZGVkXG4gICAgICAgICAgICBpbnN0YW5jZSA9IG5ldyBBY3Rpb25JbnN0YW5jZTxULCBTPihhY3Rpb24sIEFjdGlvbkluc3RhbmNlU3RhdGVFbnVtLkFjdGl2YXRpb25TdGFydCwgdGhpcy5kZWJ1Zyk7XG4gICAgICAgIH1cbiAgICAgICAgaW5zdGFuY2UuYWN0aXZhdGlvblBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzO1xuICAgICAgICAvLyBzdGFydCBhY3RpdmF0aW9uIGluc3RhbmNlXG4gICAgICAgIGluc3RhbmNlLnN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uQWN0aXZhdGlvblN0YXJ0O1xuICAgICAgICBpZiAoYWN0aW9uLnR5cGUgPT09IEFjdGlvblR5cGVFbnVtLkVkaXRvcikge1xuICAgICAgICAgICAgbGV0IGRpYWxvZ0NvbXBvbmVudCA9IHRoaXMuZGVmYXVsdEVkaXRvckRpYWxvZ0NvbXBvbmVudDtcbiAgICAgICAgICAgIGxldCBkaWFsb2dDbGFzc05hbWUgPSAnJztcbiAgICAgICAgICAgIGlmIChhY3Rpb24gaW5zdGFuY2VvZiBBY3Rpb25FZGl0b3JEZXNjcmlwdG9yKSB7XG4gICAgICAgICAgICAgICAgZGlhbG9nQ2xhc3NOYW1lID0gYWN0aW9uLmRpYWxvZ0NsYXNzTmFtZSA/PyAnbW5nLWFjdGlvbi1lZGl0b3ItZGlhbG9nJztcbiAgICAgICAgICAgICAgICBsZXQgZGlhbG9nU2l6ZUNsYXNzTmFtZSA9ICcnO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoYWN0aW9uLmRpYWxvZ1NpemUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBBY3Rpb25FZGl0b3JEaWFsb2dTaXplRW51bS5FeHRyYVNtYWxsOlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nU2l6ZUNsYXNzTmFtZSA9ICdtbmctYWN0aW9uLWVkaXRvci1kaWFsb2cteHMnO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgQWN0aW9uRWRpdG9yRGlhbG9nU2l6ZUVudW0uU21hbGw6XG4gICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dTaXplQ2xhc3NOYW1lID0gJ21uZy1hY3Rpb24tZWRpdG9yLWRpYWxvZy1zbSc7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBBY3Rpb25FZGl0b3JEaWFsb2dTaXplRW51bS5MYXJnZTpcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpYWxvZ1NpemVDbGFzc05hbWUgPSAnbW5nLWFjdGlvbi1lZGl0b3ItZGlhbG9nLWxnJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIEFjdGlvbkVkaXRvckRpYWxvZ1NpemVFbnVtLkV4dHJhTGFyZ2U6XG4gICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dTaXplQ2xhc3NOYW1lID0gJ21uZy1hY3Rpb24tZWRpdG9yLWRpYWxvZy14bCc7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBBY3Rpb25FZGl0b3JEaWFsb2dTaXplRW51bS5Ob3JtYWw6XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRpYWxvZ1NpemVDbGFzc05hbWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpYWxvZ0NsYXNzTmFtZSArPSBgICR7ZGlhbG9nU2l6ZUNsYXNzTmFtZX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uLmVkaXRvckNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgICAgICBkaWFsb2dDb21wb25lbnQgPSBhY3Rpb24uZWRpdG9yQ29tcG9uZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGRpYWxvZ0NvbmZpZzogRHluYW1pY0RpYWxvZ0NvbmZpZyA9IHtcbiAgICAgICAgICAgICAgICBkYXRhOiB7fSxcbiAgICAgICAgICAgICAgICBzdHlsZUNsYXNzOiBkaWFsb2dDbGFzc05hbWVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkaWFsb2dDb25maWcuZGF0YS5hY3Rpb25JbnN0YW5jZSA9IGluc3RhbmNlO1xuICAgICAgICAgICAgZGlhbG9nQ29uZmlnLmRhdGEucHJldmlvdXNBY3Rpb25JbnN0YW5jZSA9IHByZXZpb3VzQWN0aW9uSW5zdGFuY2U7XG4gICAgICAgICAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZ1NlcnZpY2Uub3BlbihkaWFsb2dDb21wb25lbnQsIGRpYWxvZ0NvbmZpZyk7XG4gICAgICAgICAgICBkaWFsb2dSZWYub25DbG9zZS5waXBlKGZpcnN0KCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWFjdGl2YXRlQWN0aW9uKGluc3RhbmNlISwgdHJ1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGluc3RhbmNlLmFjdGl2YXRpb25EaWFsb2dSZWYgPSBkaWFsb2dSZWY7XG4gICAgICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBkaXJlY3RseSBleGVjdXRlIGFjdGlvblxuICAgICAgICAgICAgaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5BY3RpdmF0aW9uRW5kO1xuICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMucnVuQWN0aW9uPFQsIFM+KGFjdGlvbiwgcGFyYW1ldGVycywgdW5kZWZpbmVkLCBpbnN0YW5jZSwgcHJldmlvdXNBY3Rpb25JbnN0YW5jZSk7XG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5pbnN0YW5jZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlYWN0aXZhdGVzIGFjdGlvbiBieSBjaG9vc2luZyBmaW5hbCBzdGF0ZSwgY2xvc2luZyBkaWFsb2cgYW5kIGNvbXBsZXRpbmcgYWxsIHN1YmplY3RzIGluIGluc3RhbmNlIGFuZCBjb250ZXh0cy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbnN0YW5jZSBBY3Rpb24gaW5zdGFuY2UuXG4gICAgICogQHBhcmFtIGZyb21EaWFsb2dMaXN0ZW5lciBEZWFjdGl2YXRpb24gY2FsbGVkIGZyb20gZGlhbG9nIGxpc3RlbmVyLCBpbiB0aGlzIGNhc2UgZGVhY3RpdmF0aW9uIGhhcHBlbnMgb25seSBpZiB0cnVlLlxuICAgICAqL1xuICAgIHB1YmxpYyBkZWFjdGl2YXRlQWN0aW9uPFQsIFM+KGluc3RhbmNlOiBBY3Rpb25JbnN0YW5jZTxULCBTPiwgZnJvbURpYWxvZ0xpc3RlbmVyID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKCFmcm9tRGlhbG9nTGlzdGVuZXIgJiYgaW5zdGFuY2Uuc3RhdGUgPj0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmluaXNoU3VjY2Vzcykge1xuICAgICAgICAgICAgaWYgKHRoaXMuZGVidWcpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKGBBY3Rpb25JbnN0YW5jZSAke2luc3RhbmNlLmluc3RhbmNlTG9uZ05hbWV9IGFscmVhZHkgZmluaXNoZWRgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBmaW5hbFN0YXRlOiBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bTtcbiAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5yZXN1bHQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBmaW5hbFN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmluaXNoU3VjY2VzcztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXJyb3IgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBmaW5hbFN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmluaXNoRXJyb3I7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmaW5hbFN0YXRlID0gQWN0aW9uSW5zdGFuY2VTdGF0ZUVudW0uRmluaXNoRGlzbWlzc2VkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluc3RhbmNlLmFjdGlvbi50eXBlID09PSBBY3Rpb25UeXBlRW51bS5FZGl0b3IpIHtcbiAgICAgICAgICAgIGNvbnN0IGhhc0RpYWxvZyA9IHR5cGVvZiBpbnN0YW5jZS5hY3RpdmF0aW9uRGlhbG9nUmVmICE9PSAndW5kZWZpbmVkJztcbiAgICAgICAgICAgIGlmIChoYXNEaWFsb2cgJiYgIWZyb21EaWFsb2dMaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIGlmIChmaW5hbFN0YXRlID09PSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5GaW5pc2hTdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIHN0YXRlIGlzIGZpbmlzaCBhbmQgbm90IGNhbGxlZCBmcm9tIGRpYWxvZyBsaXN0ZW5lciwgY2xvc2UgdGhlIGRpYWxvZyBmaXJzdCB3aGljaCB3aWxsIHJldHJpZ2dlciB0aGlzIGZ1bmN0aW9uLCB0aGVuIGZpbmlzaCBpdFxuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5hY3RpdmF0aW9uRGlhbG9nUmVmIS5jbG9zZShpbnN0YW5jZS5yZXN1bHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBlcnJvciBhbmQgZGlzbWlzc2VkIG11c3QgYm90aCBoYXZlIGZyb21EaWFsb2dMaXN0ZW5lciB0byBiZSBhYmxlIHRvIGZpbmlzaFxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNldCBmaW5hbCBzdGF0ZSBvbiBpbnN0YW5jZVxuICAgICAgICBpbnN0YW5jZS5zdGF0ZSA9IGZpbmFsU3RhdGU7XG4gICAgICAgIC8vIGNvbXBsZXRlIGFsbCBzdWJqZWN0c1xuICAgICAgICBpbnN0YW5jZS5maW5pc2goKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VycyBhY3Rpb24gZnJvbSB0YWJsZSByb3cgY2xpY2sgcG9zaXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiBkZXNjcmlwdG9yLlxuICAgICAqIEBwYXJhbSBldmVudCBUYXJnZXQgdGFibGUgY2xpY2sgZXZlbnQuXG4gICAgICogQHBhcmFtIHJvdXRlIEN1cnJlbnRseSBhY3RpdmF0ZSByb3V0ZS5cbiAgICAgKiBAcGFyYW0gdGFibGVEZXNjcmlwdG9yIFRhYmxlIGRlc2NyaXB0b3IuXG4gICAgICogQHBhcmFtIGRhdGFLZXlQcm9wZXJ0eSBEYXRhIGtleSBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBwdWJsaWMgdHJpZ2dlclJvd0NsaWNrQWN0aW9uPFQ+KFxuICAgICAgICBhY3Rpb246IEFjdGlvbkRlc2NyaXB0b3I8VD4sXG4gICAgICAgIGV2ZW50OiBNbmdUYWJsZUNlbGxDbGlja0V2ZW50PFQ+LFxuICAgICAgICByb3V0ZT86IEFjdGl2YXRlZFJvdXRlLFxuICAgICAgICB0YWJsZURlc2NyaXB0b3I/OiBUYWJsZURlc2NyaXB0b3I8VD4sXG4gICAgICAgIGRhdGFLZXlQcm9wZXJ0eT86IHN0cmluZ1xuICAgICkge1xuICAgICAgICBjb25zdCBpZFByb3BlcnR5ID0gZGF0YUtleVByb3BlcnR5ID8/IHRhYmxlRGVzY3JpcHRvcj8uZGF0YUtleVByb3BlcnR5ID8/IGFjdGlvbj8ubW9kZWw/LmlkUHJvcGVydHlOYW1lID8/IGRhdGFLZXlQcm9wZXJ0eTtcbiAgICAgICAgaWYgKCFpZFByb3BlcnR5KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJvdyBjbGljayBhY3Rpb24gJHthY3Rpb24uYWN0aW9uTmFtZUxvbmd9IGNhbiBub3QgYmUgdHJpZ2dlcmVkLCBiZWNhdXNlIGlkIHByb3BlcnR5IGNvdWxkIG5vdCBiZSBmb3VuZC5gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByb3dJdGVtID0gZXZlbnQ/LnJvd0l0ZW0gYXMgYW55O1xuICAgICAgICByZXR1cm4gdGhpcy50cmlnZ2VyQWN0aW9uKGFjdGlvbiwgbmV3IEFjdGlvblBhcmFtZXRlcnM8VD4ocm93SXRlbVtpZFByb3BlcnR5XSwgZXZlbnQucm93SXRlbSkud2l0aFJvdXRlKHJvdXRlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJpZ2dlcnMgYWN0aW9uIHdpdGggcGFyYW1ldGVycy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhY3Rpb24gQWN0aW9uIGRlc2NyaXB0b3IuXG4gICAgICogQHBhcmFtIHBhcmFtZXRlcnMgQWN0aW9uIHBhcmFtZXRlcnMgZm9yIGFjdGlvbiBleGVjdXRpb24gdG8gY29uc3RydWN0IG5ldyByb3V0ZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm4gQWN0aW9uIGluc3RhbmNlIC0gaWYgbm9uIHByb3ZpZGVkIGluIHBhcmFtZXRlcnMsIHRoZSBuZXdseSBjcmVhdGVkIHdpbGwgYmUgcmV0dXJuZWQuXG4gICAgICovXG4gICAgcHVibGljIHRyaWdnZXJBY3Rpb248VCwgUz4oYWN0aW9uOiBBY3Rpb25EZXNjcmlwdG9yPFQ+LCBwYXJhbWV0ZXJzOiBBY3Rpb25QYXJhbWV0ZXJzPFQ+KTogQWN0aW9uSW5zdGFuY2U8VCwgUz4ge1xuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyBBY3Rpb25JbnN0YW5jZTxULCBTPihhY3Rpb24sIHVuZGVmaW5lZCwgdGhpcy5kZWJ1Zyk7XG4gICAgICAgIGluc3RhbmNlLnRyaWdnZXJQYXJhbWV0ZXJzID0gcGFyYW1ldGVycztcbiAgICAgICAgaWYgKGFjdGlvbi5hY3RpdmF0aW9uVHJpZ2dlciA9PT0gQWN0aW9uQWN0aXZhdGlvblRyaWdnZXJFbnVtLk9uUm91dGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGJhc2VVcmwgPSB0aGlzLnJvdXRlci51cmwuc3BsaXQoJz8nKVswXTtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZFVybDogVXJsVHJlZSA9IHRoaXMucm91dGVyLnBhcnNlVXJsKHRoaXMucm91dGVyLnVybCk7XG4gICAgICAgICAgICBsZXQgYWN0aW9uVXJsID0gYWN0aW9uLnJvdXRlVXJsID8/ICcnO1xuICAgICAgICAgICAgLy8gVE9ETzogZG9udCBzdHJpcCAnLycsIGJ1dCB1c2UgaXQgYWNjb3JkaW5nbHkgd2l0aCBBbmd1bGFyJ3Mgcm91dGVyIHBhdHRlcm5zICgvLCAuLywgLi4vKVxuICAgICAgICAgICAgaWYgKGFjdGlvblVybC5zdGFydHNXaXRoKCcvJykpIHtcbiAgICAgICAgICAgICAgICBhY3Rpb25VcmwgPSBhY3Rpb25Vcmwuc3Vic3RyaW5nKDEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBhY3Rpb25VcmxTZWdtZW50cyA9IHRoaXMubGlua0Zvcm1hdHRlci50cmFuc2Zvcm0oYWN0aW9uVXJsLCBwYXJhbWV0ZXJzLml0ZW1JZCwgcGFyYW1ldGVycy5pdGVtLCBhY3Rpb24ubW9kZWwsIHBhcmFtZXRlcnMuYWN0aW9uRGF0YSk7XG4gICAgICAgICAgICBpbnN0YW5jZS50cmlnZ2VyUm91dGVOYXZpZ2F0aW9uID0gZnJvbSh0aGlzLnJvdXRlci5uYXZpZ2F0ZShbYmFzZVVybCwgLi4uYWN0aW9uVXJsU2VnbWVudHNdLCB7cmVsYXRpdmVUbzogcGFyYW1ldGVycy5yb3V0ZSwgcXVlcnlQYXJhbXM6IHBhcnNlZFVybC5xdWVyeVBhcmFtc30pKTtcblxuICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5zdGFuY2Uuc3RhdGUgPSBBY3Rpb25JbnN0YW5jZVN0YXRlRW51bS5UcmlnZ2VyRW5kO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZhdGVBY3Rpb24oYWN0aW9uLCBwYXJhbWV0ZXJzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlYWN0aXZhdGVzIG9uIHJvdXRlIHRyaWdnZXJlZCBhY3Rpb24gYnkgdHJ5aW5nIHRvIHJlcm91dGUgYmFjayB0byBsb2NhdGlvbiB3aGVyZSBhY3Rpb24gd2FzIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0gaW5zdGFuY2UgQWN0aW9uIGluc3RhbmNlLlxuICAgICAqL1xuICAgIHB1YmxpYyBkZWFjdGl2YXRlT25Sb3V0ZVRyaWdnZXJlZEFjdGlvbjxULCBTPihpbnN0YW5jZTogQWN0aW9uSW5zdGFuY2U8VCwgUz4pIHtcbiAgICAgICAgaWYgKGluc3RhbmNlLmFjdGlvbi5hY3RpdmF0aW9uVHJpZ2dlciAhPT0gQWN0aW9uQWN0aXZhdGlvblRyaWdnZXJFbnVtLk9uUm91dGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5uYXZpZ2F0aW9uU2VydmljZS5nZXRQcmV2aW91c0xvY2F0aW9uKCkpIHtcbiAgICAgICAgICAgIC8vIHRoZXJlIGFyZSBpbnRlcm5hbCBoaXN0b3J5IHJlY29yZHMsIHNvIGJhY2sgY2FuIGJlIG5vcm1hbGx5IGNhbGxlZFxuICAgICAgICAgICAgdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5iYWNrKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyB0aGVyZSBpcyBubyBpbnRlcm5hbCBoaXN0b3J5IHJlY29yZHMsIGZpZ3VyZSBvdXQgdGhlIGJhc2UgdXJsIGJ5IGVsaW1pbmF0aW5nIGFjdGlvbiBzcGVjaWZpYyB1cmxcbiAgICAgICAgICAgIGxldCB1cmwgPSB0aGlzLm5hdmlnYXRpb25TZXJ2aWNlLmdldEN1cnJlbnRMb2NhdGlvbigpO1xuICAgICAgICAgICAgaWYgKCF1cmwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5hdmlnYXRpb25TZXJ2aWNlLmJhY2soKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHVybC5zdGFydHNXaXRoKCcvJykpIHtcbiAgICAgICAgICAgICAgICAgICAgdXJsID0gdXJsLnN1YnN0cmluZygxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgdXJsUGF0aFNlZ21lbnRzID0gdXJsLnNwbGl0KCc/JylbMF0uc3BsaXQoJyMnKVswXS5zcGxpdCgnLycpO1xuICAgICAgICAgICAgICAgIGxldCBhY3Rpb25VcmwgPSBpbnN0YW5jZS5hY3Rpb24/LnJvdXRlVXJsID8/ICcnO1xuICAgICAgICAgICAgICAgIGlmIChhY3Rpb25Vcmwuc3RhcnRzV2l0aCgnLycpKSB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvblVybCA9IGFjdGlvblVybC5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGFjdGlvblVybFNlZ21lbnRzID0gYWN0aW9uVXJsLnNwbGl0KCcvJyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVkaXJlY3RVcmwgPSB1cmxQYXRoU2VnbWVudHMuc2xpY2UoMCwgdXJsUGF0aFNlZ21lbnRzLmxlbmd0aCAtIGFjdGlvblVybFNlZ21lbnRzLmxlbmd0aCkuam9pbignLycpO1xuICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlQnlVcmwoYC8ke3JlZGlyZWN0VXJsfWAsIHtyZXBsYWNlVXJsOiB0cnVlfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm0gZXJyb3Igb2YgYW55IHR5cGUgdG8gbW5nIGVycm9yIGJ5IHVzaW5nIGVycm9yIG1hcHBlciB0aGF0IGNvdWxkIGJlIHByb3ZpZGVkIGJ5IGZpbmFsIHByb2plY3QuXG4gICAgICogQHBhcmFtIGVycm9yIGVycm9yIG9mIGFueSB0eXBlLlxuICAgICAqXG4gICAgICogQHJldHVybiBtYXBwZWQgTW5nRXJyb3IuXG4gICAgICovXG4gICAgcHVibGljIHRvTW5nQWN0aW9uRXJyb3IoZXJyb3I/OiBhbnkpOiBNbmdFcnJvciB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkVycm9yOiBNbmdFcnJvciA9IHtcbiAgICAgICAgICAgIG5hbWU6IGVycm9yPy5uYW1lID8/ICdVbmtub3duRXJyb3InLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3I/Lm1lc3NhZ2UgPz8gJ1Vua25vd24gZXJyb3InLFxuICAgICAgICAgICAgY2F1c2U6IGVycm9yXG4gICAgICAgIH07XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlKSB7XG4gICAgICAgICAgICBhY3Rpb25FcnJvci5zdGF0dXMgPSBlcnJvci5zdGF0dXM7XG4gICAgICAgICAgICBhY3Rpb25FcnJvci5zdGF0dXNEZXNjcmlwdGlvbiA9IGVycm9yLnN0YXR1c1RleHQ7XG4gICAgICAgICAgICBhY3Rpb25FcnJvci51cmwgPSBlcnJvci51cmwgPz8gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmVycm9yTWFwcGVyLnRvTW5nRXJyb3IoZXJyb3IsIGFjdGlvbkVycm9yKTtcbiAgICB9XG59XG4iXX0=
|