@c8y/ngx-components 1021.13.3 → 1021.22.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/alarms/alarm-details.component.d.ts +1 -3
- package/alarms/alarm-details.component.d.ts.map +1 -1
- package/alarms/alarm-info.component.d.ts +9 -14
- package/alarms/alarm-info.component.d.ts.map +1 -1
- package/alarms/alarms-list.component.d.ts +2 -17
- package/alarms/alarms-list.component.d.ts.map +1 -1
- package/alarms/alarms-view.service.d.ts +1 -0
- package/alarms/alarms-view.service.d.ts.map +1 -1
- package/alarms/alarms.component.d.ts.map +1 -1
- package/alarms/alarms.helper.d.ts +5 -0
- package/alarms/alarms.helper.d.ts.map +1 -0
- package/alarms/alarms.model.d.ts +30 -0
- package/alarms/alarms.model.d.ts.map +1 -1
- package/alarms/alarms.module.d.ts.map +1 -1
- package/alarms/cockpit/index.d.ts.map +1 -1
- package/alarms/devicemanagement/index.d.ts.map +1 -1
- package/alarms/index.d.ts +5 -4
- package/alarms/index.d.ts.map +1 -1
- package/context-dashboard/context-dashboard.model.d.ts +1 -0
- package/context-dashboard/context-dashboard.model.d.ts.map +1 -1
- package/context-dashboard/context-dashboard.service.d.ts +7 -5
- package/context-dashboard/context-dashboard.service.d.ts.map +1 -1
- package/context-dashboard/dashboard-detail.component.d.ts +4 -7
- package/context-dashboard/dashboard-detail.component.d.ts.map +1 -1
- package/context-dashboard/dashboard-detail.service.d.ts +4 -4
- package/context-dashboard/dashboard-detail.service.d.ts.map +1 -1
- package/context-dashboard/dashboard-settings/dashboard-general-settings.component.d.ts +2 -2
- package/context-dashboard/dashboard-settings/dashboard-general-settings.component.d.ts.map +1 -1
- package/context-dashboard/dashboard-settings/typed-dashboard-settings.component.d.ts +19 -6
- package/context-dashboard/dashboard-settings/typed-dashboard-settings.component.d.ts.map +1 -1
- package/core/action-bar/action-bar-item.component.d.ts +1 -1
- package/core/action-bar/action-bar-item.component.d.ts.map +1 -1
- package/core/action-bar/action-bar.module.d.ts +6 -6
- package/core/action-bar/action-bar.module.d.ts.map +1 -1
- package/core/bootstrap/bootstrap.component.d.ts +3 -1
- package/core/bootstrap/bootstrap.component.d.ts.map +1 -1
- package/core/common/aggregation/aggregation.model.d.ts +39 -0
- package/core/common/aggregation/aggregation.model.d.ts.map +1 -0
- package/core/common/aggregation/aggregation.service.d.ts +17 -0
- package/core/common/aggregation/aggregation.service.d.ts.map +1 -0
- package/core/common/index.d.ts +4 -0
- package/core/common/index.d.ts.map +1 -1
- package/core/common/inter-app.service.d.ts +48 -0
- package/core/common/inter-app.service.d.ts.map +1 -0
- package/core/common/interval-based-reload.abstract.d.ts +120 -0
- package/core/common/interval-based-reload.abstract.d.ts.map +1 -0
- package/core/dashboard/dashboard.module.d.ts +24 -18
- package/core/dashboard/dashboard.module.d.ts.map +1 -1
- package/core/dashboard/index.d.ts +3 -0
- package/core/dashboard/index.d.ts.map +1 -1
- package/core/dashboard/widget-auto-refresh-context/auto-refresh-control.component.d.ts +31 -0
- package/core/dashboard/widget-auto-refresh-context/auto-refresh-control.component.d.ts.map +1 -0
- package/core/dashboard/widget-auto-refresh-context/auto-refresh-select-control.component.d.ts +17 -0
- package/core/dashboard/widget-auto-refresh-context/auto-refresh-select-control.component.d.ts.map +1 -0
- package/core/dashboard/widget-auto-refresh-context/global-refresh-loading.operator.d.ts +4 -0
- package/core/dashboard/widget-auto-refresh-context/global-refresh-loading.operator.d.ts.map +1 -0
- package/core/dashboard/widget-auto-refresh-context/index.d.ts +8 -0
- package/core/dashboard/widget-auto-refresh-context/index.d.ts.map +1 -0
- package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context-icon-bar.component.d.ts +7 -0
- package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context-icon-bar.component.d.ts.map +1 -0
- package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.component.d.ts +29 -0
- package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.component.d.ts.map +1 -0
- package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.model.d.ts +15 -0
- package/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.model.d.ts.map +1 -0
- package/core/dashboard/widget-auto-refresh-context/widget-global-auto-refresh.service.d.ts +169 -0
- package/core/dashboard/widget-auto-refresh-context/widget-global-auto-refresh.service.d.ts.map +1 -0
- package/core/dashboard/widgets-dashboard.component.d.ts +6 -3
- package/core/dashboard/widgets-dashboard.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts +2 -2
- package/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.d.ts +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context-query.service.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts +11 -8
- package/core/dashboard/wiget-time-context/widget-time-context.component.d.ts.map +1 -1
- package/core/dashboard/wiget-time-context/widget-time-context.model.d.ts +6 -12
- package/core/dashboard/wiget-time-context/widget-time-context.model.d.ts.map +1 -1
- package/core/header/header.module.d.ts +18 -18
- package/core/header/header.module.d.ts.map +1 -1
- package/core/header/title/title.component.d.ts +1 -1
- package/core/header/title/title.component.d.ts.map +1 -1
- package/core/i18n/cached-locale-dictionary.service.d.ts +5 -1
- package/core/i18n/cached-locale-dictionary.service.d.ts.map +1 -1
- package/core/i18n/i18n.module.d.ts +0 -4
- package/core/i18n/i18n.module.d.ts.map +1 -1
- package/core/i18n/index.d.ts +2 -1
- package/core/i18n/index.d.ts.map +1 -1
- package/core/i18n/translation-loader.service.d.ts +50 -0
- package/core/i18n/translation-loader.service.d.ts.map +1 -0
- package/core/i18n/translation-utils.d.ts +14 -0
- package/core/i18n/translation-utils.d.ts.map +1 -0
- package/core/plugins/plugins-resolve.service.d.ts +7 -10
- package/core/plugins/plugins-resolve.service.d.ts.map +1 -1
- package/core/router/context-route.component.d.ts +8 -3
- package/core/router/context-route.component.d.ts.map +1 -1
- package/core/router/context-route.service.d.ts +29 -3
- package/core/router/context-route.service.d.ts.map +1 -1
- package/core/router/router-tabs.resolver.d.ts +4 -1
- package/core/router/router-tabs.resolver.d.ts.map +1 -1
- package/core/router/router.model.d.ts +40 -3
- package/core/router/router.model.d.ts.map +1 -1
- package/core/router/router.module.d.ts +2 -1
- package/core/router/router.module.d.ts.map +1 -1
- package/core/router/router.service.d.ts +5 -4
- package/core/router/router.service.d.ts.map +1 -1
- package/core/router/scoped-context-route.service.d.ts +57 -0
- package/core/router/scoped-context-route.service.d.ts.map +1 -0
- package/core/router/view-context.service.d.ts +8 -18
- package/core/router/view-context.service.d.ts.map +1 -1
- package/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form-validation.service.d.ts +2 -1
- package/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form-validation.service.d.ts.map +1 -1
- package/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form.component.d.ts +11 -2
- package/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form.component.d.ts.map +1 -1
- package/datapoint-selector/datapoint-selection.model.d.ts +6 -0
- package/datapoint-selector/datapoint-selection.model.d.ts.map +1 -1
- package/datapoints-export-selector/c8y-ngx-components-datapoints-export-selector.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.d.ts +117 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-processing.service.d.ts +90 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-processing.service.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.d.ts +160 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.d.ts +89 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-preview/datapoints-export-selector-preview.component.d.ts +11 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-preview/datapoints-export-selector-preview.component.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-data-scope/datapoints-exports-selector-data-scope.component.d.ts +27 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-data-scope/datapoints-exports-selector-data-scope.component.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-file-types/datapoints-exports-selector-file-types.component.d.ts +12 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-file-types/datapoints-exports-selector-file-types.component.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-time-range/datapoints-exports-selector-time-range.component.d.ts +22 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-time-range/datapoints-exports-selector-time-range.component.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/csv-generator.d.ts +3 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/csv-generator.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/excel-generator.d.ts +9 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/excel-generator.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/utils.service.d.ts +56 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/utils.service.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-modal.component.d.ts +21 -0
- package/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-modal.component.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector.component.d.ts +14 -0
- package/datapoints-export-selector/datapoints-export-selector.component.d.ts.map +1 -0
- package/datapoints-export-selector/datapoints-export-selector.model.d.ts +232 -0
- package/datapoints-export-selector/datapoints-export-selector.model.d.ts.map +1 -0
- package/datapoints-export-selector/index.d.ts +15 -0
- package/datapoints-export-selector/index.d.ts.map +1 -0
- package/device-list/device-list.module.d.ts +4 -2
- package/device-list/device-list.module.d.ts.map +1 -1
- package/esm2022/alarms/alarm-details.component.mjs +7 -9
- package/esm2022/alarms/alarm-info.component.mjs +23 -33
- package/esm2022/alarms/alarms-list.component.mjs +5 -16
- package/esm2022/alarms/alarms-view.service.mjs +3 -2
- package/esm2022/alarms/alarms.component.mjs +10 -3
- package/esm2022/alarms/alarms.helper.mjs +32 -0
- package/esm2022/alarms/alarms.model.mjs +1 -1
- package/esm2022/alarms/alarms.module.mjs +5 -5
- package/esm2022/alarms/cockpit/index.mjs +13 -17
- package/esm2022/alarms/devicemanagement/index.mjs +15 -18
- package/esm2022/alarms/index.mjs +6 -5
- package/esm2022/context-dashboard/context-dashboard.component.mjs +4 -4
- package/esm2022/context-dashboard/context-dashboard.model.mjs +1 -1
- package/esm2022/context-dashboard/context-dashboard.service.mjs +47 -21
- package/esm2022/context-dashboard/dashboard-detail.component.mjs +8 -16
- package/esm2022/context-dashboard/dashboard-detail.service.mjs +13 -6
- package/esm2022/context-dashboard/dashboard-settings/dashboard-general-settings.component.mjs +3 -3
- package/esm2022/context-dashboard/dashboard-settings/typed-dashboard-settings.component.mjs +32 -11
- package/esm2022/core/action-bar/action-bar-item.component.mjs +3 -3
- package/esm2022/core/action-bar/action-bar.module.mjs +16 -5
- package/esm2022/core/bootstrap/bootstrap.component.mjs +21 -16
- package/esm2022/core/common/aggregation/aggregation.model.mjs +46 -0
- package/esm2022/core/common/aggregation/aggregation.service.mjs +34 -0
- package/esm2022/core/common/humanize-app-name.model.mjs +2 -2
- package/esm2022/core/common/humanize-app-name.pipe.mjs +2 -2
- package/esm2022/core/common/index.mjs +5 -1
- package/esm2022/core/common/inter-app.service.mjs +76 -0
- package/esm2022/core/common/interval-based-reload.abstract.mjs +110 -0
- package/esm2022/core/countdown-interval/countdown-interval.component.mjs +3 -3
- package/esm2022/core/dashboard/dashboard-child.component.mjs +6 -5
- package/esm2022/core/dashboard/dashboard.module.mjs +18 -1
- package/esm2022/core/dashboard/index.mjs +4 -1
- package/esm2022/core/dashboard/widget-auto-refresh-context/auto-refresh-control.component.mjs +101 -0
- package/esm2022/core/dashboard/widget-auto-refresh-context/auto-refresh-select-control.component.mjs +50 -0
- package/esm2022/core/dashboard/widget-auto-refresh-context/global-refresh-loading.operator.mjs +7 -0
- package/esm2022/core/dashboard/widget-auto-refresh-context/index.mjs +8 -0
- package/esm2022/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context-icon-bar.component.mjs +18 -0
- package/esm2022/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.component.mjs +127 -0
- package/esm2022/core/dashboard/widget-auto-refresh-context/widget-auto-refresh-context.model.mjs +5 -0
- package/esm2022/core/dashboard/widget-auto-refresh-context/widget-global-auto-refresh.service.mjs +233 -0
- package/esm2022/core/dashboard/widgets-dashboard.component.mjs +35 -30
- package/esm2022/core/dashboard/wiget-time-context/aggregation-picker/aggregation-picker.component.mjs +4 -4
- package/esm2022/core/dashboard/wiget-time-context/realtime-control/realtime-control.component.mjs +2 -2
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context-icon-bar/widget-time-context-icon-bar.component.mjs +5 -5
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context-query.service.mjs +7 -4
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context.component.mjs +37 -37
- package/esm2022/core/dashboard/wiget-time-context/widget-time-context.model.mjs +1 -28
- package/esm2022/core/date-time-picker/date-time-picker.component.mjs +3 -3
- package/esm2022/core/header/header.module.mjs +7 -5
- package/esm2022/core/header/title/title.component.mjs +3 -3
- package/esm2022/core/i18n/cached-locale-dictionary.service.mjs +1 -1
- package/esm2022/core/i18n/i18n.module.mjs +7 -14
- package/esm2022/core/i18n/index.mjs +3 -2
- package/esm2022/core/i18n/translate.parser.mjs +2 -2
- package/esm2022/core/i18n/translation-loader.service.mjs +132 -0
- package/esm2022/core/i18n/translation-utils.mjs +24 -0
- package/esm2022/core/plugins/plugins-resolve.service.mjs +12 -37
- package/esm2022/core/router/context-route.component.mjs +23 -13
- package/esm2022/core/router/context-route.service.mjs +37 -5
- package/esm2022/core/router/router-tabs.resolver.mjs +46 -15
- package/esm2022/core/router/router.model.mjs +6 -1
- package/esm2022/core/router/router.module.mjs +20 -13
- package/esm2022/core/router/router.service.mjs +24 -10
- package/esm2022/core/router/scoped-context-route.service.mjs +152 -0
- package/esm2022/core/router/view-context.service.mjs +59 -16
- package/esm2022/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form-validation.service.mjs +13 -6
- package/esm2022/datapoint-selector/datapoint-attributes-form/datapoint-attributes-form.component.mjs +22 -5
- package/esm2022/datapoint-selector/datapoint-selection-list/datapoint-selection-list.component.mjs +3 -3
- package/esm2022/datapoint-selector/datapoint-selection.model.mjs +1 -1
- package/esm2022/datapoint-selector/datapoint-selector-list-item/datapoint-selector-list-item.component.mjs +3 -3
- package/esm2022/datapoints-export-selector/c8y-ngx-components-datapoints-export-selector.mjs +5 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-fetching.service.mjs +407 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/data-processing.service.mjs +207 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.component.mjs +467 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-file-exporter.service.mjs +187 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-export-selector-preview/datapoints-export-selector-preview.component.mjs +27 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-data-scope/datapoints-exports-selector-data-scope.component.mjs +41 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-file-types/datapoints-exports-selector-file-types.component.mjs +23 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/datapoints-exports-selector-time-range/datapoints-exports-selector-time-range.component.mjs +42 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/csv-generator.mjs +120 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/generators/excel-generator.mjs +282 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-file-exporter/utils.service.mjs +76 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector-modal/datapoints-export-selector-modal.component.mjs +46 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector.component.mjs +42 -0
- package/esm2022/datapoints-export-selector/datapoints-export-selector.model.mjs +43 -0
- package/esm2022/datapoints-export-selector/index.mjs +15 -0
- package/esm2022/device-list/add-smart-group.component.mjs +4 -3
- package/esm2022/device-list/device-list.module.mjs +22 -4
- package/esm2022/map/cluster-map.component.mjs +41 -13
- package/esm2022/map/map-status.component.mjs +6 -5
- package/esm2022/map/map.component.mjs +9 -5
- package/esm2022/map/map.model.mjs +1 -1
- package/esm2022/translation-editor/c8y-ngx-components-translation-editor.mjs +5 -0
- package/esm2022/translation-editor/data/c8y-ngx-components-translation-editor-data.mjs +5 -0
- package/esm2022/translation-editor/data/index.mjs +2 -0
- package/esm2022/translation-editor/data/translation-store.service.mjs +175 -0
- package/esm2022/translation-editor/index.mjs +10 -0
- package/esm2022/translation-editor/lazy/add-translation-modal/add-translation-modal.component.mjs +70 -0
- package/esm2022/translation-editor/lazy/c8y-ngx-components-translation-editor-lazy.mjs +5 -0
- package/esm2022/translation-editor/lazy/index.mjs +2 -0
- package/esm2022/translation-editor/lazy/manage-translation-cell-renderer/manage-translation-cell-renderer.component.mjs +53 -0
- package/esm2022/translation-editor/lazy/translation-editor/translation-editor.component.mjs +124 -0
- package/esm2022/translation-editor/translation-editor-naviagtor-factory.service.mjs +31 -0
- package/esm2022/widgets/cockpit/index.mjs +4 -2
- package/esm2022/widgets/cockpit-exports/index.mjs +8 -1
- package/esm2022/widgets/definitions/alarms/alarm-list/index.mjs +6 -2
- package/esm2022/widgets/definitions/alarms/all-critical-alarms/index.mjs +6 -2
- package/esm2022/widgets/definitions/alarms/recent-alarms/index.mjs +6 -2
- package/esm2022/widgets/definitions/datapoints-table/c8y-ngx-components-widgets-definitions-datapoints-table.mjs +5 -0
- package/esm2022/widgets/definitions/datapoints-table/index.mjs +34 -0
- package/esm2022/widgets/definitions/index.mjs +2 -1
- package/esm2022/widgets/definitions/map/index.mjs +4 -2
- package/esm2022/widgets/implementations/alarms/alarm-list-widget-config/alarm-list-widget-config.component.mjs +29 -15
- package/esm2022/widgets/implementations/alarms/alarm-list-widget-view/alarm-list-widget.component.mjs +57 -25
- package/esm2022/widgets/implementations/alarms/alarm-list-widget.model.mjs +2 -1
- package/esm2022/widgets/implementations/alarms/alarm-widget-alarms-reload.component.mjs +19 -21
- package/esm2022/widgets/implementations/datapoints-table/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +5 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.mjs +383 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.mjs +124 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/adjust-aggregated-time-range.pipe.mjs +191 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/apply-range-class.pipe.mjs +36 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/column-title.pipe.mjs +45 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.mjs +116 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/datapoints-table.component.mjs +116 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/dynamic-column.directive.mjs +43 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.mjs +282 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.mjs +430 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-view/virtual-scroll-listener.directive.mjs +75 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table-widget.model.mjs +76 -0
- package/esm2022/widgets/implementations/datapoints-table/datapoints-table.service.mjs +52 -0
- package/esm2022/widgets/implementations/datapoints-table/date-range-picker.component.mjs +68 -0
- package/esm2022/widgets/implementations/datapoints-table/index.mjs +10 -0
- package/esm2022/widgets/implementations/map/map-widget-config.component.mjs +19 -11
- package/esm2022/widgets/implementations/map/map-widget.component.mjs +20 -2
- package/esm2022/widgets/implementations/map/map-widget.model.mjs +1 -1
- package/fesm2022/c8y-ngx-components-alarms-cockpit.mjs +12 -16
- package/fesm2022/c8y-ngx-components-alarms-cockpit.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-alarms-devicemanagement.mjs +14 -17
- package/fesm2022/c8y-ngx-components-alarms-devicemanagement.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-alarms.mjs +203 -185
- package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs +135 -91
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +37 -13
- package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs +1928 -0
- package/fesm2022/c8y-ngx-components-datapoints-export-selector.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-device-list.mjs +24 -5
- package/fesm2022/c8y-ngx-components-device-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-map.mjs +52 -19
- package/fesm2022/c8y-ngx-components-map.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-translation-editor-data.mjs +181 -0
- package/fesm2022/c8y-ngx-components-translation-editor-data.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs +236 -0
- package/fesm2022/c8y-ngx-components-translation-editor-lazy.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-translation-editor.mjs +46 -0
- package/fesm2022/c8y-ngx-components-translation-editor.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-widgets-cockpit-exports.mjs +7 -0
- package/fesm2022/c8y-ngx-components-widgets-cockpit-exports.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-cockpit.mjs +3 -1
- package/fesm2022/c8y-ngx-components-widgets-cockpit.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs +5 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-all-critical-alarms.mjs +5 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-all-critical-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-recent-alarms.mjs +5 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-recent-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs +41 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions-map.mjs +3 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-map.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions.mjs +1 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +101 -58
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs +1967 -0
- package/fesm2022/c8y-ngx-components-widgets-implementations-datapoints-table.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-widgets-implementations-map.mjs +37 -11
- package/fesm2022/c8y-ngx-components-widgets-implementations-map.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +5476 -4396
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/locales/de.po +289 -18
- package/locales/en.po +12 -0
- package/locales/en_US.po +3 -0
- package/locales/es.po +253 -18
- package/locales/fr.po +253 -18
- package/locales/ja_JP.po +282 -18
- package/locales/locales.pot +257 -18
- package/locales/nl.po +253 -18
- package/locales/pl.po +253 -18
- package/locales/pt_BR.po +253 -18
- package/map/cluster-map.component.d.ts +8 -3
- package/map/cluster-map.component.d.ts.map +1 -1
- package/map/map-status.component.d.ts +0 -3
- package/map/map-status.component.d.ts.map +1 -1
- package/map/map.component.d.ts +4 -2
- package/map/map.component.d.ts.map +1 -1
- package/map/map.model.d.ts +2 -1
- package/map/map.model.d.ts.map +1 -1
- package/package.json +1 -1
- package/translation-editor/c8y-ngx-components-translation-editor.d.ts.map +1 -0
- package/translation-editor/data/c8y-ngx-components-translation-editor-data.d.ts.map +1 -0
- package/translation-editor/data/index.d.ts +2 -0
- package/translation-editor/data/index.d.ts.map +1 -0
- package/translation-editor/data/translation-store.service.d.ts +61 -0
- package/translation-editor/data/translation-store.service.d.ts.map +1 -0
- package/translation-editor/index.d.ts +2 -0
- package/translation-editor/index.d.ts.map +1 -0
- package/translation-editor/lazy/add-translation-modal/add-translation-modal.component.d.ts +30 -0
- package/translation-editor/lazy/add-translation-modal/add-translation-modal.component.d.ts.map +1 -0
- package/translation-editor/lazy/c8y-ngx-components-translation-editor-lazy.d.ts.map +1 -0
- package/translation-editor/lazy/index.d.ts +2 -0
- package/translation-editor/lazy/index.d.ts.map +1 -0
- package/translation-editor/lazy/manage-translation-cell-renderer/manage-translation-cell-renderer.component.d.ts +22 -0
- package/translation-editor/lazy/manage-translation-cell-renderer/manage-translation-cell-renderer.component.d.ts.map +1 -0
- package/translation-editor/lazy/translation-editor/translation-editor.component.d.ts +34 -0
- package/translation-editor/lazy/translation-editor/translation-editor.component.d.ts.map +1 -0
- package/translation-editor/translation-editor-naviagtor-factory.service.d.ts +11 -0
- package/translation-editor/translation-editor-naviagtor-factory.service.d.ts.map +1 -0
- package/widgets/cockpit/index.d.ts +13 -0
- package/widgets/cockpit/index.d.ts.map +1 -1
- package/widgets/cockpit-exports/index.d.ts +6 -0
- package/widgets/cockpit-exports/index.d.ts.map +1 -1
- package/widgets/definitions/alarms/alarm-list/index.d.ts +2 -0
- package/widgets/definitions/alarms/alarm-list/index.d.ts.map +1 -1
- package/widgets/definitions/alarms/all-critical-alarms/index.d.ts +2 -0
- package/widgets/definitions/alarms/all-critical-alarms/index.d.ts.map +1 -1
- package/widgets/definitions/alarms/recent-alarms/index.d.ts +2 -0
- package/widgets/definitions/alarms/recent-alarms/index.d.ts.map +1 -1
- package/widgets/definitions/datapoints-table/c8y-ngx-components-widgets-definitions-datapoints-table.d.ts.map +1 -0
- package/widgets/definitions/datapoints-table/index.d.ts +14 -0
- package/widgets/definitions/datapoints-table/index.d.ts.map +1 -0
- package/widgets/definitions/index.d.ts +1 -0
- package/widgets/definitions/index.d.ts.map +1 -1
- package/widgets/definitions/map/index.d.ts +2 -1
- package/widgets/definitions/map/index.d.ts.map +1 -1
- package/widgets/implementations/alarms/alarm-list-widget-config/alarm-list-widget-config.component.d.ts +5 -9
- package/widgets/implementations/alarms/alarm-list-widget-config/alarm-list-widget-config.component.d.ts.map +1 -1
- package/widgets/implementations/alarms/alarm-list-widget-view/alarm-list-widget.component.d.ts +17 -10
- package/widgets/implementations/alarms/alarm-list-widget-view/alarm-list-widget.component.d.ts.map +1 -1
- package/widgets/implementations/alarms/alarm-list-widget.model.d.ts +5 -1
- package/widgets/implementations/alarms/alarm-list-widget.model.d.ts.map +1 -1
- package/widgets/implementations/alarms/alarm-widget-alarms-reload.component.d.ts +5 -11
- package/widgets/implementations/alarms/alarm-widget-alarms-reload.component.d.ts.map +1 -1
- package/widgets/implementations/datapoints-table/c8y-ngx-components-widgets-implementations-datapoints-table.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.d.ts +129 -0
- package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.component.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.d.ts +56 -0
- package/widgets/implementations/datapoints-table/datapoints-table-config/datapoints-table-config.service.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/adjust-aggregated-time-range.pipe.d.ts +88 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/adjust-aggregated-time-range.pipe.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/apply-range-class.pipe.d.ts +19 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/apply-range-class.pipe.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/column-title.pipe.d.ts +26 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/column-title.pipe.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.d.ts +63 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-reload/datapoints-reload.component.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/datapoints-table.component.d.ts +38 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/datapoints-table.component.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/dynamic-column.directive.d.ts +13 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table/dynamic-column.directive.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.d.ts +123 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.component.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.d.ts +196 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/datapoints-table-view.service.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/virtual-scroll-listener.directive.d.ts +41 -0
- package/widgets/implementations/datapoints-table/datapoints-table-view/virtual-scroll-listener.directive.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table-widget.model.d.ts +175 -0
- package/widgets/implementations/datapoints-table/datapoints-table-widget.model.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/datapoints-table.service.d.ts +12 -0
- package/widgets/implementations/datapoints-table/datapoints-table.service.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/date-range-picker.component.d.ts +34 -0
- package/widgets/implementations/datapoints-table/date-range-picker.component.d.ts.map +1 -0
- package/widgets/implementations/datapoints-table/index.d.ts +10 -0
- package/widgets/implementations/datapoints-table/index.d.ts.map +1 -0
- package/widgets/implementations/map/map-widget-config.component.d.ts +4 -4
- package/widgets/implementations/map/map-widget-config.component.d.ts.map +1 -1
- package/widgets/implementations/map/map-widget.component.d.ts +8 -3
- package/widgets/implementations/map/map-widget.component.d.ts.map +1 -1
- package/widgets/implementations/map/map-widget.model.d.ts +4 -3
- package/widgets/implementations/map/map-widget.model.d.ts.map +1 -1
- package/core/i18n/translate.loader.d.ts +0 -31
- package/core/i18n/translate.loader.d.ts.map +0 -1
- package/esm2022/core/i18n/translate.loader.mjs +0 -71
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
3
|
+
import { MeasurementService } from '@c8y/client';
|
|
4
|
+
import { AGGREGATION_VALUES, AlertService, gettext } from '@c8y/ngx-components';
|
|
5
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
6
|
+
import { MEASUREMENTS_PREVIEW_ITEMS_LIMIT } from '../../datapoints-export-selector.model';
|
|
7
|
+
import { UtilsService } from './utils.service';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "@c8y/ngx-components";
|
|
10
|
+
import * as i2 from "@c8y/client";
|
|
11
|
+
import * as i3 from "@angular/platform-browser";
|
|
12
|
+
import * as i4 from "@ngx-translate/core";
|
|
13
|
+
import * as i5 from "./utils.service";
|
|
14
|
+
export class DataFetchingService {
|
|
15
|
+
constructor(alertService, measurementService, sanitizer, translateService, utilsService) {
|
|
16
|
+
this.alertService = alertService;
|
|
17
|
+
this.measurementService = measurementService;
|
|
18
|
+
this.sanitizer = sanitizer;
|
|
19
|
+
this.translateService = translateService;
|
|
20
|
+
this.utilsService = utilsService;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Checks if any of measurements requests may exceeded the limit,
|
|
24
|
+
* after which the export data is processed by the backend and the generated CSV/Excel file is sent by email.
|
|
25
|
+
*
|
|
26
|
+
* The threshold is set to 50_000 records in application's core properties (export.data.synchronous.limit).
|
|
27
|
+
*
|
|
28
|
+
* @param exportConfig - The export configuration.
|
|
29
|
+
* @returns A promise that returns an array of objects representing datapoints files that will be sent by email.
|
|
30
|
+
*/
|
|
31
|
+
async getDatapointsExceedingLimit(exportConfig) {
|
|
32
|
+
const backendProcessingLimit = 50_000;
|
|
33
|
+
const promises = exportConfig.datapointDetails.map(async (details) => {
|
|
34
|
+
try {
|
|
35
|
+
const filter = {
|
|
36
|
+
dateFrom: exportConfig.dateFrom,
|
|
37
|
+
dateTo: exportConfig.dateTo,
|
|
38
|
+
pageSize: 1,
|
|
39
|
+
source: details.source,
|
|
40
|
+
valueFragmentSeries: details.valueFragmentSeries,
|
|
41
|
+
valueFragmentType: details.valueFragmentType,
|
|
42
|
+
withTotalElements: true
|
|
43
|
+
};
|
|
44
|
+
const response = await this.measurementService.list(filter);
|
|
45
|
+
if (response?.paging?.totalElements > backendProcessingLimit) {
|
|
46
|
+
return {
|
|
47
|
+
datapointDetail: {
|
|
48
|
+
source: details.source,
|
|
49
|
+
valueFragmentSeries: details.valueFragmentSeries,
|
|
50
|
+
valueFragmentType: details.valueFragmentType
|
|
51
|
+
},
|
|
52
|
+
totalElements: response.paging.totalElements
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
this.alertService.addServerFailure(error);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
const results = await Promise.all(promises);
|
|
64
|
+
const datapointsExceedingLimit = results.filter(result => result !== null);
|
|
65
|
+
return datapointsExceedingLimit;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Retrieves the message to be displayed when the limit of datapoints is exceeded during file export.
|
|
69
|
+
*
|
|
70
|
+
* @param hasNoExportableData - Indicates if there is no exportable data because the date range of all selected datapoints exceeds 1,000,000 records.
|
|
71
|
+
* @param emailDeliverableCount - The number of datapoint exports that exceed the limit, will be proceeded by the backend and sent by email.
|
|
72
|
+
* @param browserDownloadableCount - The number of datapoint exports that can be downloaded directly.
|
|
73
|
+
* @param skippedDatapointCount - The number of datapoint exports skipped due to exceeding the measurements API limit of 1,000,000 records.
|
|
74
|
+
* @param totalDatapointsSelectedForExportCount - Total number of datapoint selected for exports.
|
|
75
|
+
* @returns The message that can be injected.
|
|
76
|
+
*/
|
|
77
|
+
getLimitExceededMessage(hasNoExportableData, emailDeliverableCount, browserDownloadableCount, nonRetrievableCount, totalDatapointsSelectedForExportCount) {
|
|
78
|
+
if (hasNoExportableData) {
|
|
79
|
+
const message = this.translateService.instant(gettext(`The data for selected datapoint(s) exceed 1,000,000 records, which is the limit for backend processing. To export this data, please reduce the date range.`));
|
|
80
|
+
return message;
|
|
81
|
+
}
|
|
82
|
+
const message = this.translateService.instant(gettext(`After clicking "Download":<br>
|
|
83
|
+
<ul>
|
|
84
|
+
<li><strong>{{$browserDownloadableCount}}</strong> datapoint(s) exports will be downloaded directly within one file: <em>exported_[csv/excel].zip</em></li>
|
|
85
|
+
<li><strong>{{$emailDeliverableCount}}</strong> datapoint(s) exports require further processing. The files will be sent to you via separate emails once completed, which may take some time.</li>
|
|
86
|
+
<li><strong>{{$nonRetrievableCount}}</strong> datapoint(s) exports exceeded 1,000,000 records, which is the limit for backend processing. To export these data, please reduce the date range. Otherwise, the data will neither be downloaded nor sent via email.</li>
|
|
87
|
+
</ul>
|
|
88
|
+
<p>The total number of data points that can be exported is: <strong>{{$totalExportableDatapointsCount}} out of {{$totalDatapointsSelectedForExportCount}}</strong>.
|
|
89
|
+
<p><strong>Note:</strong> The file name convention of files within zip file is: <code>[source]_[fragment_series].[csv/xls]</code></p>`), {
|
|
90
|
+
$browserDownloadableCount: browserDownloadableCount,
|
|
91
|
+
$emailDeliverableCount: emailDeliverableCount,
|
|
92
|
+
$nonRetrievableCount: nonRetrievableCount,
|
|
93
|
+
$totalDatapointsSelectedForExportCount: totalDatapointsSelectedForExportCount,
|
|
94
|
+
$totalExportableDatapointsCount: browserDownloadableCount + emailDeliverableCount
|
|
95
|
+
});
|
|
96
|
+
const trimmedMessage = this.removeZeroCountListItems(message, [
|
|
97
|
+
browserDownloadableCount,
|
|
98
|
+
emailDeliverableCount,
|
|
99
|
+
nonRetrievableCount
|
|
100
|
+
]);
|
|
101
|
+
return trimmedMessage;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Displays an information alert about sending data via email.
|
|
105
|
+
*
|
|
106
|
+
* Only measurements API can send files via email.
|
|
107
|
+
*
|
|
108
|
+
* @param fileType - The type of file to be sent.
|
|
109
|
+
* @param datapointsExceedingLimit - The array of datapoints exceeding the limit.
|
|
110
|
+
*/
|
|
111
|
+
showSendViaEmailInfoAlert(fileType, datapointsExceedingLimit) {
|
|
112
|
+
const messageTemplate = this.translateService.instant(gettext(`You will get {{$fileTypeText}} file(s) for {{$count}} series via email.`), { $count: datapointsExceedingLimit.length, $fileTypeText: fileType });
|
|
113
|
+
const formattedList = datapointsExceedingLimit
|
|
114
|
+
.map(datapoint => `• ${datapoint.datapointDetail.source}_${datapoint.datapointDetail.valueFragmentType}_${datapoint.datapointDetail.valueFragmentSeries}`)
|
|
115
|
+
.join('\n');
|
|
116
|
+
this.alertService.info(messageTemplate, formattedList);
|
|
117
|
+
}
|
|
118
|
+
async fetchMeasurementDataFilesAndPairWithSourceDetails(acceptFileType, exportConfig) {
|
|
119
|
+
const measurementFileConfig = {
|
|
120
|
+
exportConfig,
|
|
121
|
+
acceptFileType
|
|
122
|
+
};
|
|
123
|
+
const filePromises = exportConfig.datapointDetails.map(details => this.fetchAndProcessMeasurementFile(details, measurementFileConfig));
|
|
124
|
+
return Promise.all(filePromises);
|
|
125
|
+
}
|
|
126
|
+
async fetchAndProcessMeasurementFile(details, measurementFileConfig) {
|
|
127
|
+
const filter = this.prepareMeasurementsFilter(details, measurementFileConfig.exportConfig);
|
|
128
|
+
const header = { accept: measurementFileConfig.acceptFileType };
|
|
129
|
+
try {
|
|
130
|
+
const measurementFileResponse = await this.measurementService.getMeasurementsFile(filter, header);
|
|
131
|
+
// If the status is 200, then the file is in the response.
|
|
132
|
+
// If the status is 202, then the file is being processed by the backend and will be sent by email.
|
|
133
|
+
if (measurementFileResponse.status === 200) {
|
|
134
|
+
return this.mergeMeasurementsWithItsSourceDetails(details, measurementFileResponse);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
this.alertService.addServerFailure(error);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async mergeMeasurementsWithItsSourceDetails(details, measurementFile) {
|
|
142
|
+
return {
|
|
143
|
+
source: details.source,
|
|
144
|
+
valueFragmentSeries: details.valueFragmentSeries,
|
|
145
|
+
valueFragmentType: details.valueFragmentType,
|
|
146
|
+
fetchedMeasurementsBlobFile: await measurementFile.blob()
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
async fetchAndPrepareDataToExport(exportConfig, isMeasurement) {
|
|
150
|
+
return isMeasurement
|
|
151
|
+
? await this.fetchAndPrepareMeasurementDataToExportForPreview(exportConfig)
|
|
152
|
+
: await this.fetchAndPrepareSeriesDataToExport(exportConfig);
|
|
153
|
+
}
|
|
154
|
+
async getSourcesWithPermissionsToRead(datapointDetails) {
|
|
155
|
+
const dateFrom = new Date();
|
|
156
|
+
const dateTo = new Date(dateFrom);
|
|
157
|
+
const fetchedDataPromises = datapointDetails.map(async (datapoint) => {
|
|
158
|
+
const rawFilter = {
|
|
159
|
+
dateFrom,
|
|
160
|
+
dateTo,
|
|
161
|
+
source: datapoint.source
|
|
162
|
+
};
|
|
163
|
+
try {
|
|
164
|
+
const { res } = await this.fetchSeriesData(rawFilter);
|
|
165
|
+
if (res?.status === 200) {
|
|
166
|
+
return datapoint.source;
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
// If an error occurs during fetch, return null to prevent promise rejection
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
const fetchedSources = await Promise.all(fetchedDataPromises);
|
|
176
|
+
return fetchedSources.filter((source) => source !== null);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Fetches and prepares measurement data for preview.
|
|
180
|
+
*
|
|
181
|
+
* Empty DataToExport object can be returned, because unlike series data,
|
|
182
|
+
* measurement data is not further processed besides showing only in the preview.
|
|
183
|
+
* CSV/Excel files are generated by the backend for measurements.
|
|
184
|
+
*
|
|
185
|
+
* @param exportConfig - The export configuration.
|
|
186
|
+
* @returns A promise that resolves to an array of DataToExport objects or null when no data is fetched.
|
|
187
|
+
*/
|
|
188
|
+
async fetchAndPrepareMeasurementDataToExportForPreview(exportConfig) {
|
|
189
|
+
const dataToExportPromises = exportConfig.datapointDetails.map(async (details) => {
|
|
190
|
+
const fetchedMeasurementData = await this.fetchMeasurementDataForPreview(details, exportConfig);
|
|
191
|
+
if (fetchedMeasurementData?.data?.length) {
|
|
192
|
+
return this.processMeasurementDataForPreview(details, fetchedMeasurementData.data);
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
});
|
|
196
|
+
return await Promise.all(dataToExportPromises);
|
|
197
|
+
}
|
|
198
|
+
async fetchMeasurementDataForPreview(details, exportConfig) {
|
|
199
|
+
let measurements;
|
|
200
|
+
const filter = this.prepareMeasurementsFilter(details, exportConfig, MEASUREMENTS_PREVIEW_ITEMS_LIMIT);
|
|
201
|
+
try {
|
|
202
|
+
// TODO: consider adding a cache mechanism -> MTM-60289
|
|
203
|
+
// When user switches between report types, and rest of the settings are the same, then the data should not be fetched again?
|
|
204
|
+
measurements = await this.measurementService.list(filter);
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
this.alertService.addServerFailure(error);
|
|
208
|
+
}
|
|
209
|
+
return measurements;
|
|
210
|
+
}
|
|
211
|
+
prepareMeasurementsFilter(details, exportConfig, pageSize) {
|
|
212
|
+
const filter = {
|
|
213
|
+
// Round the 'from' time to the previous full minute.
|
|
214
|
+
dateFrom: this.adjustDate(exportConfig.dateFrom, -1),
|
|
215
|
+
// Round the 'to' time to the nearest full minute.
|
|
216
|
+
dateTo: this.adjustDate(exportConfig.dateTo, 1),
|
|
217
|
+
source: details.source,
|
|
218
|
+
valueFragmentSeries: details.valueFragmentSeries,
|
|
219
|
+
valueFragmentType: details.valueFragmentType
|
|
220
|
+
};
|
|
221
|
+
if (pageSize) {
|
|
222
|
+
filter.pageSize = pageSize;
|
|
223
|
+
}
|
|
224
|
+
return filter;
|
|
225
|
+
}
|
|
226
|
+
processMeasurementDataForPreview(details, data) {
|
|
227
|
+
const unit = data[0][details.valueFragmentType][details.valueFragmentSeries]?.unit || '';
|
|
228
|
+
const values = {};
|
|
229
|
+
data.forEach(measurement => {
|
|
230
|
+
values[measurement.time] =
|
|
231
|
+
measurement[details.valueFragmentType][details.valueFragmentSeries].value;
|
|
232
|
+
});
|
|
233
|
+
return { ...details, unit, timeValueMap: values };
|
|
234
|
+
}
|
|
235
|
+
async fetchAndPrepareSeriesDataToExport(exportConfig) {
|
|
236
|
+
const datapointsValuesDataMap = this.groupSeriesByDeviceId(exportConfig.datapointDetails);
|
|
237
|
+
const fetchedDataPromises = Array.from(datapointsValuesDataMap).map(async ([source, series]) => {
|
|
238
|
+
const { dateFrom, dateTo, aggregation } = exportConfig;
|
|
239
|
+
const rawFilter = {
|
|
240
|
+
dateFrom,
|
|
241
|
+
dateTo,
|
|
242
|
+
source,
|
|
243
|
+
series,
|
|
244
|
+
aggregationType: aggregation
|
|
245
|
+
};
|
|
246
|
+
const { data } = await this.fetchSeriesData(rawFilter);
|
|
247
|
+
return { source, data };
|
|
248
|
+
});
|
|
249
|
+
const fetchedDataGroupedBySource = await Promise.all(fetchedDataPromises);
|
|
250
|
+
return this.processSeriesData(exportConfig.datapointDetails, fetchedDataGroupedBySource);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Returns a map of active data points device IDs with their corresponding series.
|
|
254
|
+
*
|
|
255
|
+
* Example output:
|
|
256
|
+
* ```typescript
|
|
257
|
+
* new Map([
|
|
258
|
+
* ['844657202', ['c8y_Temperature.T']],
|
|
259
|
+
* ['32666427', ['c8y_Battery.Battery']]
|
|
260
|
+
* ]);
|
|
261
|
+
* ```
|
|
262
|
+
* @param datapointDetails - An array of data points details.
|
|
263
|
+
* @returns A map where the key is the data point ID and the value is an array of data point series.
|
|
264
|
+
*/
|
|
265
|
+
groupSeriesByDeviceId(datapointDetails) {
|
|
266
|
+
return datapointDetails.reduce((map, { valueFragmentType, valueFragmentSeries, source }) => {
|
|
267
|
+
const value = `${valueFragmentType}.${valueFragmentSeries}`;
|
|
268
|
+
const existingValue = map.get(source) ?? [];
|
|
269
|
+
map.set(source, [...existingValue, value]);
|
|
270
|
+
return map;
|
|
271
|
+
}, new Map());
|
|
272
|
+
}
|
|
273
|
+
async fetchSeriesData(rawFilter) {
|
|
274
|
+
let seriesData;
|
|
275
|
+
const filter = this.prepareSeriesFilter({
|
|
276
|
+
dateFrom: rawFilter.dateFrom,
|
|
277
|
+
dateTo: rawFilter.dateTo,
|
|
278
|
+
source: rawFilter.source,
|
|
279
|
+
series: rawFilter.series,
|
|
280
|
+
aggregationType: rawFilter.aggregationType
|
|
281
|
+
});
|
|
282
|
+
try {
|
|
283
|
+
// TODO: consider adding a cache mechanism -> MTM-60289
|
|
284
|
+
// When user switches between report types, and rest of the settings are the same, then the data should not be fetched again?
|
|
285
|
+
seriesData = await this.measurementService.listSeries(filter);
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
this.alertService.addServerFailure(error);
|
|
289
|
+
}
|
|
290
|
+
return seriesData;
|
|
291
|
+
}
|
|
292
|
+
prepareSeriesFilter(filters) {
|
|
293
|
+
const { dateFrom, dateTo, source, series, aggregationType } = filters;
|
|
294
|
+
// Round the 'from' time to the previous full minute.
|
|
295
|
+
const from = this.adjustDate(dateFrom, -1);
|
|
296
|
+
// Round the 'to' time to the nearest full minute.
|
|
297
|
+
const to = this.adjustDate(dateTo, 1);
|
|
298
|
+
const filter = {
|
|
299
|
+
dateFrom: from,
|
|
300
|
+
dateTo: to,
|
|
301
|
+
source: source,
|
|
302
|
+
revert: true
|
|
303
|
+
};
|
|
304
|
+
// The 'NONE' aggregation type is not handled by a backend, so even when is selected, it is not passed as a filter parameter.
|
|
305
|
+
if (aggregationType && aggregationType !== AGGREGATION_VALUES.none) {
|
|
306
|
+
filter.aggregationType = aggregationType;
|
|
307
|
+
}
|
|
308
|
+
// TODO: it is a temporal workaround for a bug in the backend,
|
|
309
|
+
// where the series with more than one dot are impossible to retrieve:
|
|
310
|
+
// https://cumulocity.atlassian.net/browse/MTM-59277
|
|
311
|
+
if (series) {
|
|
312
|
+
const hasMoreThanOneDot = series.some(s => s.split('.').length > 2);
|
|
313
|
+
if (!hasMoreThanOneDot) {
|
|
314
|
+
filter.series = series;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return filter;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Processes the fetched series data and prepares it for export.
|
|
321
|
+
*
|
|
322
|
+
* @param datapointDetails - An array of data point details.
|
|
323
|
+
* @param fetchedDataMap - A map of fetched series data grouped by source.
|
|
324
|
+
* @returns An array of DataToExport objects.
|
|
325
|
+
*/
|
|
326
|
+
processSeriesData(datapointDetails, fetchedDataMap) {
|
|
327
|
+
const valuesGroupedBySource = this.utilsService.transformDataStructure(fetchedDataMap);
|
|
328
|
+
return datapointDetails.map((details) => {
|
|
329
|
+
let unit;
|
|
330
|
+
let data;
|
|
331
|
+
/**
|
|
332
|
+
* Unique key to distinguish between different series from same source,
|
|
333
|
+
* e.g.: c8y_Acceleration.accelerationX, c8y_Acceleration.accelerationY, c8y_Acceleration.accelerationZ
|
|
334
|
+
*/
|
|
335
|
+
const seriesKey = `${details.valueFragmentType}.${details.valueFragmentSeries}`;
|
|
336
|
+
if (valuesGroupedBySource[details.source][seriesKey]) {
|
|
337
|
+
unit = valuesGroupedBySource[details.source][seriesKey].seriesDetails.unit;
|
|
338
|
+
data = valuesGroupedBySource[details.source][seriesKey].values;
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
...details,
|
|
342
|
+
unit,
|
|
343
|
+
timeValueMap: data
|
|
344
|
+
};
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Adjusts the given date by adding the specified number of minutes and setting seconds to 0.
|
|
349
|
+
*
|
|
350
|
+
* @param date - The date to be adjusted in string format.
|
|
351
|
+
* @param minutes - The number of minutes to add to the date.
|
|
352
|
+
* @returns The adjusted date in the format 'YYYY-MM-DDTHH:mm:ss+HH:MM'.
|
|
353
|
+
*/
|
|
354
|
+
adjustDate(date, minutes) {
|
|
355
|
+
const dateTime = new Date(date);
|
|
356
|
+
dateTime.setMinutes(dateTime.getMinutes() + minutes);
|
|
357
|
+
dateTime.setSeconds(0);
|
|
358
|
+
const offset = -dateTime.getTimezoneOffset();
|
|
359
|
+
const offsetSign = offset >= 0 ? '+' : '-';
|
|
360
|
+
const pad = (num) => (num < 10 ? '0' + num : num.toString());
|
|
361
|
+
const offsetHours = pad(Math.floor(Math.abs(offset) / 60));
|
|
362
|
+
const offsetMinutes = pad(Math.abs(offset) % 60);
|
|
363
|
+
const year = dateTime.getFullYear();
|
|
364
|
+
const month = pad(dateTime.getMonth() + 1);
|
|
365
|
+
const day = pad(dateTime.getDate());
|
|
366
|
+
const hours = pad(dateTime.getHours());
|
|
367
|
+
const minutesString = pad(dateTime.getMinutes());
|
|
368
|
+
const seconds = '00';
|
|
369
|
+
return `${year}-${month}-${day}T${hours}:${minutesString}:${seconds}${offsetSign}${offsetHours}:${offsetMinutes}`;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Trims the given HTML message by removing list items that correspond to zero counts.
|
|
373
|
+
*
|
|
374
|
+
* @param message - The HTML string containing the message with list items.
|
|
375
|
+
* @param counts - An array of number values corresponding to each list item.
|
|
376
|
+
* @param countToTrim - A count that will be trimmed with corresponding list item.
|
|
377
|
+
* @returns A trimmed HTML string with list items removed where the corresponding count is zero.
|
|
378
|
+
*
|
|
379
|
+
* Example:
|
|
380
|
+
* ```typescript
|
|
381
|
+
* const message = '<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>';
|
|
382
|
+
* const counts = [1, 0, 2];
|
|
383
|
+
* const trimmedMessage = this.removeZeroCountListItems(message, counts);
|
|
384
|
+
* // Result: '<ul><li>Item 1</li><li>Item 3</li></ul>'
|
|
385
|
+
* ```
|
|
386
|
+
*/
|
|
387
|
+
removeZeroCountListItems(message, counts, countToTrim = 0) {
|
|
388
|
+
const parser = new DOMParser();
|
|
389
|
+
const doc = parser.parseFromString(message, 'text/html');
|
|
390
|
+
const listItems = doc.querySelectorAll('ul li');
|
|
391
|
+
listItems.forEach((item, index) => {
|
|
392
|
+
if (counts[index] === countToTrim) {
|
|
393
|
+
item.remove();
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
return doc.body.innerHTML;
|
|
397
|
+
}
|
|
398
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, deps: [{ token: i1.AlertService }, { token: i2.MeasurementService }, { token: i3.DomSanitizer }, { token: i4.TranslateService }, { token: i5.UtilsService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
399
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, providedIn: 'root' }); }
|
|
400
|
+
}
|
|
401
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DataFetchingService, decorators: [{
|
|
402
|
+
type: Injectable,
|
|
403
|
+
args: [{
|
|
404
|
+
providedIn: 'root'
|
|
405
|
+
}]
|
|
406
|
+
}], ctorParameters: () => [{ type: i1.AlertService }, { type: i2.MeasurementService }, { type: i3.DomSanitizer }, { type: i4.TranslateService }, { type: i5.UtilsService }] });
|
|
407
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1mZXRjaGluZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3IvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3ItbW9kYWwvZGF0YXBvaW50cy1leHBvcnQtc2VsZWN0b3ItZmlsZS1leHBvcnRlci9kYXRhLWZldGNoaW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQVNMLGtCQUFrQixFQUNuQixNQUFNLGFBQWEsQ0FBQztBQUNyQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFRTCxnQ0FBZ0MsRUFFakMsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRCxPQUFPLEVBQWMsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7Ozs7QUFLM0QsTUFBTSxPQUFPLG1CQUFtQjtJQUM5QixZQUNVLFlBQTBCLEVBQzFCLGtCQUFzQyxFQUN0QyxTQUF1QixFQUN2QixnQkFBa0MsRUFDbEMsWUFBMEI7UUFKMUIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN0QyxjQUFTLEdBQVQsU0FBUyxDQUFjO1FBQ3ZCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsaUJBQVksR0FBWixZQUFZLENBQWM7SUFDakMsQ0FBQztJQUVKOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLDJCQUEyQixDQUMvQixZQUEwQjtRQUUxQixNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FB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QUssSUFBSSxhQUFhLElBQUksT0FBTyxHQUFHLFVBQVUsR0FBRyxXQUFXLElBQUksYUFBYSxFQUFFLENBQUM7SUFDcEgsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7T0FlRztJQUNLLHdCQUF3QixDQUFDLE9BQWUsRUFBRSxNQUFnQixFQUFFLFdBQVcsR0FBRyxDQUFDO1FBQ2pGLE1BQU0sTUFBTSxHQUFHLElBQUksU0FBUyxFQUFFLENBQUM7UUFDL0IsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDekQsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWhELFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDaEMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQzVCLENBQUM7OEdBcmdCVSxtQkFBbUI7a0hBQW5CLG1CQUFtQixjQUZsQixNQUFNOzsyRkFFUCxtQkFBbUI7a0JBSC9CLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQge1xuICBhZ2dyZWdhdGlvblR5cGUsXG4gIElGZXRjaFJlc3BvbnNlLFxuICBJTWVhc3VyZW1lbnQsXG4gIElNZWFzdXJlbWVudEZpbHRlcixcbiAgSVJlc3VsdCxcbiAgSVJlc3VsdExpc3QsXG4gIElTZXJpZXMsXG4gIElTZXJpZXNGaWx0ZXIsXG4gIE1lYXN1cmVtZW50U2VydmljZVxufSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQgeyBBR0dSRUdBVElPTl9WQUxVRVMsIEFsZXJ0U2VydmljZSwgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHtcbiAgRGF0YXBvaW50RGV0YWlscyxcbiAgRGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0LFxuICBEYXRhcG9pbnRzVmFsdWVzRGF0YU1hcCxcbiAgRGF0YVRvRXhwb3J0LFxuICBEYXRhVG9FeHBvcnRXaXRoQmFja2VuZENyZWF0ZWRGaWxlLFxuICBFeHBvcnRDb25maWcsXG4gIE1lYXN1cmVtZW50RmlsZUNvbmZpZyxcbiAgTUVBU1VSRU1FTlRTX1BSRVZJRVdfSVRFTVNfTElNSVQsXG4gIFRpbWVTZXJpZXNEYXRhXG59IGZyb20gJy4uLy4uL2RhdGFwb2ludHMtZXhwb3J0LXNlbGVjdG9yLm1vZGVsJztcbmltcG9ydCB7IFNvdXJjZUl0ZW0sIFV0aWxzU2VydmljZSB9IGZyb20gJy4vdXRpbHMuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIERhdGFGZXRjaGluZ1NlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGFsZXJ0U2VydmljZTogQWxlcnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgbWVhc3VyZW1lbnRTZXJ2aWNlOiBNZWFzdXJlbWVudFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcbiAgICBwcml2YXRlIHRyYW5zbGF0ZVNlcnZpY2U6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSB1dGlsc1NlcnZpY2U6IFV0aWxzU2VydmljZVxuICApIHt9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhbnkgb2YgbWVhc3VyZW1lbnRzIHJlcXVlc3RzIG1heSBleGNlZWRlZCB0aGUgbGltaXQsXG4gICAqIGFmdGVyIHdoaWNoIHRoZSBleHBvcnQgZGF0YSBpcyBwcm9jZXNzZWQgYnkgdGhlIGJhY2tlbmQgYW5kIHRoZSBnZW5lcmF0ZWQgQ1NWL0V4Y2VsIGZpbGUgaXMgc2VudCBieSBlbWFpbC5cbiAgICpcbiAgICogVGhlIHRocmVzaG9sZCBpcyBzZXQgdG8gNTBfMDAwIHJlY29yZHMgaW4gYXBwbGljYXRpb24ncyBjb3JlIHByb3BlcnRpZXMgKGV4cG9ydC5kYXRhLnN5bmNocm9ub3VzLmxpbWl0KS5cbiAgICpcbiAgICogQHBhcmFtIGV4cG9ydENvbmZpZyAtIFRoZSBleHBvcnQgY29uZmlndXJhdGlvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmV0dXJucyBhbiBhcnJheSBvZiBvYmplY3RzIHJlcHJlc2VudGluZyBkYXRhcG9pbnRzIGZpbGVzIHRoYXQgd2lsbCBiZSBzZW50IGJ5IGVtYWlsLlxuICAgKi9cbiAgYXN5bmMgZ2V0RGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0KFxuICAgIGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnXG4gICk6IFByb21pc2U8RGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0W10+IHtcbiAgICBjb25zdCBiYWNrZW5kUHJvY2Vzc2luZ0xpbWl0ID0gNTBfMDAwO1xuXG4gICAgY29uc3QgcHJvbWlzZXM6IFByb21pc2U8RGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0PltdID0gZXhwb3J0Q29uZmlnLmRhdGFwb2ludERldGFpbHMubWFwKFxuICAgICAgYXN5bmMgZGV0YWlscyA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZmlsdGVyOiBJTWVhc3VyZW1lbnRGaWx0ZXIgPSB7XG4gICAgICAgICAgICBkYXRlRnJvbTogZXhwb3J0Q29uZmlnLmRhdGVGcm9tLFxuICAgICAgICAgICAgZGF0ZVRvOiBleHBvcnRDb25maWcuZGF0ZVRvLFxuICAgICAgICAgICAgcGFnZVNpemU6IDEsXG4gICAgICAgICAgICBzb3VyY2U6IGRldGFpbHMuc291cmNlLFxuICAgICAgICAgICAgdmFsdWVGcmFnbWVudFNlcmllczogZGV0YWlscy52YWx1ZUZyYWdtZW50U2VyaWVzLFxuICAgICAgICAgICAgdmFsdWVGcmFnbWVudFR5cGU6IGRldGFpbHMudmFsdWVGcmFnbWVudFR5cGUsXG4gICAgICAgICAgICB3aXRoVG90YWxFbGVtZW50czogdHJ1ZVxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMubWVhc3VyZW1lbnRTZXJ2aWNlLmxpc3QoZmlsdGVyKTtcblxuICAgICAgICAgIGlmIChyZXNwb25zZT8ucGFnaW5nPy50b3RhbEVsZW1lbnRzID4gYmFja2VuZFByb2Nlc3NpbmdMaW1pdCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZGF0YXBvaW50RGV0YWlsOiB7XG4gICAgICAgICAgICAgICAgc291cmNlOiBkZXRhaWxzLnNvdXJjZSxcbiAgICAgICAgICAgICAgICB2YWx1ZUZyYWdtZW50U2VyaWVzOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXMsXG4gICAgICAgICAgICAgICAgdmFsdWVGcmFnbWVudFR5cGU6IGRldGFpbHMudmFsdWVGcmFnbWVudFR5cGVcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdG90YWxFbGVtZW50czogcmVzcG9uc2UucGFnaW5nLnRvdGFsRWxlbWVudHNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHRzOiBEYXRhcG9pbnRzRXhjZWVkaW5nTGltaXRbXSA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcblxuICAgIGNvbnN0IGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdCA9IHJlc3VsdHMuZmlsdGVyKHJlc3VsdCA9PiByZXN1bHQgIT09IG51bGwpO1xuXG4gICAgcmV0dXJuIGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIG1lc3NhZ2UgdG8gYmUgZGlzcGxheWVkIHdoZW4gdGhlIGxpbWl0IG9mIGRhdGFwb2ludHMgaXMgZXhjZWVkZWQgZHVyaW5nIGZpbGUgZXhwb3J0LlxuICAgKlxuICAgKiBAcGFyYW0gaGFzTm9FeHBvcnRhYmxlRGF0YSAtIEluZGljYXRlcyBpZiB0aGVyZSBpcyBubyBleHBvcnRhYmxlIGRhdGEgYmVjYXVzZSB0aGUgZGF0ZSByYW5nZSBvZiBhbGwgc2VsZWN0ZWQgZGF0YXBvaW50cyBleGNlZWRzIDEsMDAwLDAwMCByZWNvcmRzLlxuICAgKiBAcGFyYW0gZW1haWxEZWxpdmVyYWJsZUNvdW50IC0gVGhlIG51bWJlciBvZiBkYXRhcG9pbnQgZXhwb3J0cyB0aGF0IGV4Y2VlZCB0aGUgbGltaXQsIHdpbGwgYmUgcHJvY2VlZGVkIGJ5IHRoZSBiYWNrZW5kIGFuZCBzZW50IGJ5IGVtYWlsLlxuICAgKiBAcGFyYW0gYnJvd3NlckRvd25sb2FkYWJsZUNvdW50IC0gVGhlIG51bWJlciBvZiBkYXRhcG9pbnQgZXhwb3J0cyB0aGF0IGNhbiBiZSBkb3dubG9hZGVkIGRpcmVjdGx5LlxuICAgKiBAcGFyYW0gc2tpcHBlZERhdGFwb2ludENvdW50IC0gVGhlIG51bWJlciBvZiBkYXRhcG9pbnQgZXhwb3J0cyBza2lwcGVkIGR1ZSB0byBleGNlZWRpbmcgdGhlIG1lYXN1cmVtZW50cyBBUEkgbGltaXQgb2YgMSwwMDAsMDAwIHJlY29yZHMuXG4gICAqIEBwYXJhbSB0b3RhbERhdGFwb2ludHNTZWxlY3RlZEZvckV4cG9ydENvdW50IC0gVG90YWwgbnVtYmVyIG9mIGRhdGFwb2ludCBzZWxlY3RlZCBmb3IgZXhwb3J0cy5cbiAgICogQHJldHVybnMgVGhlIG1lc3NhZ2UgdGhhdCBjYW4gYmUgaW5qZWN0ZWQuXG4gICAqL1xuICBnZXRMaW1pdEV4Y2VlZGVkTWVzc2FnZShcbiAgICBoYXNOb0V4cG9ydGFibGVEYXRhOiBib29sZWFuLFxuICAgIGVtYWlsRGVsaXZlcmFibGVDb3VudD86IG51bWJlcixcbiAgICBicm93c2VyRG93bmxvYWRhYmxlQ291bnQ/OiBudW1iZXIsXG4gICAgbm9uUmV0cmlldmFibGVDb3VudD86IG51bWJlcixcbiAgICB0b3RhbERhdGFwb2ludHNTZWxlY3RlZEZvckV4cG9ydENvdW50PzogbnVtYmVyXG4gICk6IHN0cmluZyB7XG4gICAgaWYgKGhhc05vRXhwb3J0YWJsZURhdGEpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICAgICAgZ2V0dGV4dChcbiAgICAgICAgICBgVGhlIGRhdGEgZm9yIHNlbGVjdGVkIGRhdGFwb2ludChzKSBleGNlZWQgMSwwMDAsMDAwIHJlY29yZHMsIHdoaWNoIGlzIHRoZSBsaW1pdCBmb3IgYmFja2VuZCBwcm9jZXNzaW5nLiBUbyBleHBvcnQgdGhpcyBkYXRhLCBwbGVhc2UgcmVkdWNlIHRoZSBkYXRlIHJhbmdlLmBcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cblxuICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChcbiAgICAgIGdldHRleHQoXG4gICAgICAgIGBBZnRlciBjbGlja2luZyBcIkRvd25sb2FkXCI6PGJyPlxuICAgICAgICA8dWw+XG4gICAgICAgICAgPGxpPjxzdHJvbmc+e3skYnJvd3NlckRvd25sb2FkYWJsZUNvdW50fX08L3N0cm9uZz4gZGF0YXBvaW50KHMpIGV4cG9ydHMgd2lsbCBiZSBkb3dubG9hZGVkIGRpcmVjdGx5IHdpdGhpbiBvbmUgZmlsZTogPGVtPmV4cG9ydGVkX1tjc3YvZXhjZWxdLnppcDwvZW0+PC9saT5cbiAgICAgICAgICA8bGk+PHN0cm9uZz57eyRlbWFpbERlbGl2ZXJhYmxlQ291bnR9fTwvc3Ryb25nPiBkYXRhcG9pbnQocykgZXhwb3J0cyByZXF1aXJlIGZ1cnRoZXIgcHJvY2Vzc2luZy4gVGhlIGZpbGVzIHdpbGwgYmUgc2VudCB0byB5b3UgdmlhIHNlcGFyYXRlIGVtYWlscyBvbmNlIGNvbXBsZXRlZCwgd2hpY2ggbWF5IHRha2Ugc29tZSB0aW1lLjwvbGk+XG4gICAgICAgICAgPGxpPjxzdHJvbmc+e3skbm9uUmV0cmlldmFibGVDb3VudH19PC9zdHJvbmc+IGRhdGFwb2ludChzKSBleHBvcnRzIGV4Y2VlZGVkIDEsMDAwLDAwMCByZWNvcmRzLCB3aGljaCBpcyB0aGUgbGltaXQgZm9yIGJhY2tlbmQgcHJvY2Vzc2luZy4gVG8gZXhwb3J0IHRoZXNlIGRhdGEsIHBsZWFzZSByZWR1Y2UgdGhlIGRhdGUgcmFuZ2UuIE90aGVyd2lzZSwgdGhlIGRhdGEgd2lsbCBuZWl0aGVyIGJlIGRvd25sb2FkZWQgbm9yIHNlbnQgdmlhIGVtYWlsLjwvbGk+XG4gICAgICAgIDwvdWw+XG4gICAgICAgIDxwPlRoZSB0b3RhbCBudW1iZXIgb2YgZGF0YSBwb2ludHMgdGhhdCBjYW4gYmUgZXhwb3J0ZWQgaXM6IDxzdHJvbmc+e3skdG90YWxFeHBvcnRhYmxlRGF0YXBvaW50c0NvdW50fX0gb3V0IG9mIHt7JHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnR9fTwvc3Ryb25nPi5cbiAgICAgICAgPHA+PHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiBUaGUgZmlsZSBuYW1lIGNvbnZlbnRpb24gb2YgZmlsZXMgd2l0aGluIHppcCBmaWxlIGlzOiA8Y29kZT5bc291cmNlXV9bZnJhZ21lbnRfc2VyaWVzXS5bY3N2L3hsc108L2NvZGU+PC9wPmBcbiAgICAgICksXG4gICAgICB7XG4gICAgICAgICRicm93c2VyRG93bmxvYWRhYmxlQ291bnQ6IGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCxcbiAgICAgICAgJGVtYWlsRGVsaXZlcmFibGVDb3VudDogZW1haWxEZWxpdmVyYWJsZUNvdW50LFxuICAgICAgICAkbm9uUmV0cmlldmFibGVDb3VudDogbm9uUmV0cmlldmFibGVDb3VudCxcbiAgICAgICAgJHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQ6IHRvdGFsRGF0YXBvaW50c1NlbGVjdGVkRm9yRXhwb3J0Q291bnQsXG4gICAgICAgICR0b3RhbEV4cG9ydGFibGVEYXRhcG9pbnRzQ291bnQ6IGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCArIGVtYWlsRGVsaXZlcmFibGVDb3VudFxuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCB0cmltbWVkTWVzc2FnZSA9IHRoaXMucmVtb3ZlWmVyb0NvdW50TGlzdEl0ZW1zKG1lc3NhZ2UsIFtcbiAgICAgIGJyb3dzZXJEb3dubG9hZGFibGVDb3VudCxcbiAgICAgIGVtYWlsRGVsaXZlcmFibGVDb3VudCxcbiAgICAgIG5vblJldHJpZXZhYmxlQ291bnRcbiAgICBdKTtcblxuICAgIHJldHVybiB0cmltbWVkTWVzc2FnZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwbGF5cyBhbiBpbmZvcm1hdGlvbiBhbGVydCBhYm91dCBzZW5kaW5nIGRhdGEgdmlhIGVtYWlsLlxuICAgKlxuICAgKiBPbmx5IG1lYXN1cmVtZW50cyBBUEkgY2FuIHNlbmQgZmlsZXMgdmlhIGVtYWlsLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsZVR5cGUgLSBUaGUgdHlwZSBvZiBmaWxlIHRvIGJlIHNlbnQuXG4gICAqIEBwYXJhbSBkYXRhcG9pbnRzRXhjZWVkaW5nTGltaXQgLSBUaGUgYXJyYXkgb2YgZGF0YXBvaW50cyBleGNlZWRpbmcgdGhlIGxpbWl0LlxuICAgKi9cbiAgc2hvd1NlbmRWaWFFbWFpbEluZm9BbGVydChcbiAgICBmaWxlVHlwZTogc3RyaW5nLFxuICAgIGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdDogRGF0YXBvaW50c0V4Y2VlZGluZ0xpbWl0W11cbiAgKTogdm9pZCB7XG4gICAgY29uc3QgbWVzc2FnZVRlbXBsYXRlID0gdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICBnZXR0ZXh0KGBZb3Ugd2lsbCBnZXQge3skZmlsZVR5cGVUZXh0fX0gZmlsZShzKSBmb3Ige3skY291bnR9fSBzZXJpZXMgdmlhIGVtYWlsLmApLFxuICAgICAgeyAkY291bnQ6IGRhdGFwb2ludHNFeGNlZWRpbmdMaW1pdC5sZW5ndGgsICRmaWxlVHlwZVRleHQ6IGZpbGVUeXBlIH1cbiAgICApO1xuICAgIGNvbnN0IGZvcm1hdHRlZExpc3QgPSBkYXRhcG9pbnRzRXhjZWVkaW5nTGltaXRcbiAgICAgIC5tYXAoXG4gICAgICAgIGRhdGFwb2ludCA9PlxuICAgICAgICAgIGDigKIgJHtkYXRhcG9pbnQuZGF0YXBvaW50RGV0YWlsLnNvdXJjZX1fJHtkYXRhcG9pbnQuZGF0YXBvaW50RGV0YWlsLnZhbHVlRnJhZ21lbnRUeXBlfV8ke2RhdGFwb2ludC5kYXRhcG9pbnREZXRhaWwudmFsdWVGcmFnbWVudFNlcmllc31gXG4gICAgICApXG4gICAgICAuam9pbignXFxuJyk7XG5cbiAgICB0aGlzLmFsZXJ0U2VydmljZS5pbmZvKG1lc3NhZ2VUZW1wbGF0ZSwgZm9ybWF0dGVkTGlzdCk7XG4gIH1cblxuICBhc3luYyBmZXRjaE1lYXN1cmVtZW50RGF0YUZpbGVzQW5kUGFpcldpdGhTb3VyY2VEZXRhaWxzKFxuICAgIGFjY2VwdEZpbGVUeXBlOiBzdHJpbmcsXG4gICAgZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWdcbiAgKTogUHJvbWlzZTxEYXRhVG9FeHBvcnRXaXRoQmFja2VuZENyZWF0ZWRGaWxlW10+IHtcbiAgICBjb25zdCBtZWFzdXJlbWVudEZpbGVDb25maWc6IE1lYXN1cmVtZW50RmlsZUNvbmZpZyA9IHtcbiAgICAgIGV4cG9ydENvbmZpZyxcbiAgICAgIGFjY2VwdEZpbGVUeXBlXG4gICAgfTtcbiAgICBjb25zdCBmaWxlUHJvbWlzZXMgPSBleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscy5tYXAoZGV0YWlscyA9PlxuICAgICAgdGhpcy5mZXRjaEFuZFByb2Nlc3NNZWFzdXJlbWVudEZpbGUoZGV0YWlscywgbWVhc3VyZW1lbnRGaWxlQ29uZmlnKVxuICAgICk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGZpbGVQcm9taXNlcyk7XG4gIH1cblxuICBhc3luYyBmZXRjaEFuZFByb2Nlc3NNZWFzdXJlbWVudEZpbGUoXG4gICAgZGV0YWlsczogRGF0YXBvaW50RGV0YWlscyxcbiAgICBtZWFzdXJlbWVudEZpbGVDb25maWc6IE1lYXN1cmVtZW50RmlsZUNvbmZpZ1xuICApOiBQcm9taXNlPERhdGFUb0V4cG9ydFdpdGhCYWNrZW5kQ3JlYXRlZEZpbGUgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBmaWx0ZXI6IElNZWFzdXJlbWVudEZpbHRlciA9IHRoaXMucHJlcGFyZU1lYXN1cmVtZW50c0ZpbHRlcihcbiAgICAgIGRldGFpbHMsXG4gICAgICBtZWFzdXJlbWVudEZpbGVDb25maWcuZXhwb3J0Q29uZmlnXG4gICAgKTtcbiAgICBjb25zdCBoZWFkZXIgPSB7IGFjY2VwdDogbWVhc3VyZW1lbnRGaWxlQ29uZmlnLmFjY2VwdEZpbGVUeXBlIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgbWVhc3VyZW1lbnRGaWxlUmVzcG9uc2U6IElGZXRjaFJlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UuZ2V0TWVhc3VyZW1lbnRzRmlsZShmaWx0ZXIsIGhlYWRlcik7XG5cbiAgICAgIC8vIElmIHRoZSBzdGF0dXMgaXMgMjAwLCB0aGVuIHRoZSBmaWxlIGlzIGluIHRoZSByZXNwb25zZS5cbiAgICAgIC8vIElmIHRoZSBzdGF0dXMgaXMgMjAyLCB0aGVuIHRoZSBmaWxlIGlzIGJlaW5nIHByb2Nlc3NlZCBieSB0aGUgYmFja2VuZCBhbmQgd2lsbCBiZSBzZW50IGJ5IGVtYWlsLlxuICAgICAgaWYgKG1lYXN1cmVtZW50RmlsZVJlc3BvbnNlLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lcmdlTWVhc3VyZW1lbnRzV2l0aEl0c1NvdXJjZURldGFpbHMoZGV0YWlscywgbWVhc3VyZW1lbnRGaWxlUmVzcG9uc2UpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBtZXJnZU1lYXN1cmVtZW50c1dpdGhJdHNTb3VyY2VEZXRhaWxzKFxuICAgIGRldGFpbHM6IERhdGFwb2ludERldGFpbHMsXG4gICAgbWVhc3VyZW1lbnRGaWxlOiBJRmV0Y2hSZXNwb25zZVxuICApOiBQcm9taXNlPERhdGFUb0V4cG9ydFdpdGhCYWNrZW5kQ3JlYXRlZEZpbGU+IHtcbiAgICByZXR1cm4ge1xuICAgICAgc291cmNlOiBkZXRhaWxzLnNvdXJjZSxcbiAgICAgIHZhbHVlRnJhZ21lbnRTZXJpZXM6IGRldGFpbHMudmFsdWVGcmFnbWVudFNlcmllcyxcbiAgICAgIHZhbHVlRnJhZ21lbnRUeXBlOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRUeXBlLFxuICAgICAgZmV0Y2hlZE1lYXN1cmVtZW50c0Jsb2JGaWxlOiBhd2FpdCBtZWFzdXJlbWVudEZpbGUuYmxvYigpXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoQW5kUHJlcGFyZURhdGFUb0V4cG9ydChcbiAgICBleHBvcnRDb25maWc6IEV4cG9ydENvbmZpZyxcbiAgICBpc01lYXN1cmVtZW50OiBib29sZWFuXG4gICk6IFByb21pc2U8RGF0YVRvRXhwb3J0W10+IHtcbiAgICByZXR1cm4gaXNNZWFzdXJlbWVudFxuICAgICAgPyBhd2FpdCB0aGlzLmZldGNoQW5kUHJlcGFyZU1lYXN1cmVtZW50RGF0YVRvRXhwb3J0Rm9yUHJldmlldyhleHBvcnRDb25maWcpXG4gICAgICA6IGF3YWl0IHRoaXMuZmV0Y2hBbmRQcmVwYXJlU2VyaWVzRGF0YVRvRXhwb3J0KGV4cG9ydENvbmZpZyk7XG4gIH1cblxuICBhc3luYyBnZXRTb3VyY2VzV2l0aFBlcm1pc3Npb25zVG9SZWFkKGRhdGFwb2ludERldGFpbHM6IERhdGFwb2ludERldGFpbHNbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBjb25zdCBkYXRlRnJvbSA9IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgZGF0ZVRvID0gbmV3IERhdGUoZGF0ZUZyb20pO1xuXG4gICAgY29uc3QgZmV0Y2hlZERhdGFQcm9taXNlcyA9IGRhdGFwb2ludERldGFpbHMubWFwKGFzeW5jIGRhdGFwb2ludCA9PiB7XG4gICAgICBjb25zdCByYXdGaWx0ZXI6IElTZXJpZXNGaWx0ZXIgPSB7XG4gICAgICAgIGRhdGVGcm9tLFxuICAgICAgICBkYXRlVG8sXG4gICAgICAgIHNvdXJjZTogZGF0YXBvaW50LnNvdXJjZVxuICAgICAgfTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyByZXMgfTogSVJlc3VsdDxJU2VyaWVzPiA9IGF3YWl0IHRoaXMuZmV0Y2hTZXJpZXNEYXRhKHJhd0ZpbHRlcik7XG4gICAgICAgIGlmIChyZXM/LnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICAgICAgcmV0dXJuIGRhdGFwb2ludC5zb3VyY2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBJZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIGZldGNoLCByZXR1cm4gbnVsbCB0byBwcmV2ZW50IHByb21pc2UgcmVqZWN0aW9uXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgZmV0Y2hlZFNvdXJjZXMgPSBhd2FpdCBQcm9taXNlLmFsbChmZXRjaGVkRGF0YVByb21pc2VzKTtcbiAgICByZXR1cm4gZmV0Y2hlZFNvdXJjZXMuZmlsdGVyKChzb3VyY2UpOiBzb3VyY2UgaXMgc3RyaW5nID0+IHNvdXJjZSAhPT0gbnVsbCk7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2hlcyBhbmQgcHJlcGFyZXMgbWVhc3VyZW1lbnQgZGF0YSBmb3IgcHJldmlldy5cbiAgICpcbiAgICogRW1wdHkgRGF0YVRvRXhwb3J0IG9iamVjdCBjYW4gYmUgcmV0dXJuZWQsIGJlY2F1c2UgdW5saWtlIHNlcmllcyBkYXRhLFxuICAgKiBtZWFzdXJlbWVudCBkYXRhIGlzIG5vdCBmdXJ0aGVyIHByb2Nlc3NlZCBiZXNpZGVzIHNob3dpbmcgb25seSBpbiB0aGUgcHJldmlldy5cbiAgICogQ1NWL0V4Y2VsIGZpbGVzIGFyZSBnZW5lcmF0ZWQgYnkgdGhlIGJhY2tlbmQgZm9yIG1lYXN1cmVtZW50cy5cbiAgICpcbiAgICogQHBhcmFtIGV4cG9ydENvbmZpZyAtIFRoZSBleHBvcnQgY29uZmlndXJhdGlvbi5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgb2YgRGF0YVRvRXhwb3J0IG9iamVjdHMgb3IgbnVsbCB3aGVuIG5vIGRhdGEgaXMgZmV0Y2hlZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hBbmRQcmVwYXJlTWVhc3VyZW1lbnREYXRhVG9FeHBvcnRGb3JQcmV2aWV3KFxuICAgIGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnXG4gICk6IFByb21pc2U8RGF0YVRvRXhwb3J0W10+IHwgbnVsbCB7XG4gICAgY29uc3QgZGF0YVRvRXhwb3J0UHJvbWlzZXM6IFByb21pc2U8RGF0YVRvRXhwb3J0PltdID0gZXhwb3J0Q29uZmlnLmRhdGFwb2ludERldGFpbHMubWFwKFxuICAgICAgYXN5bmMgZGV0YWlscyA9PiB7XG4gICAgICAgIGNvbnN0IGZldGNoZWRNZWFzdXJlbWVudERhdGE6IElSZXN1bHRMaXN0PElNZWFzdXJlbWVudD4gPVxuICAgICAgICAgIGF3YWl0IHRoaXMuZmV0Y2hNZWFzdXJlbWVudERhdGFGb3JQcmV2aWV3KGRldGFpbHMsIGV4cG9ydENvbmZpZyk7XG5cbiAgICAgICAgaWYgKGZldGNoZWRNZWFzdXJlbWVudERhdGE/LmRhdGE/Lmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NNZWFzdXJlbWVudERhdGFGb3JQcmV2aWV3KGRldGFpbHMsIGZldGNoZWRNZWFzdXJlbWVudERhdGEuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHJldHVybiBhd2FpdCBQcm9taXNlLmFsbChkYXRhVG9FeHBvcnRQcm9taXNlcyk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGZldGNoTWVhc3VyZW1lbnREYXRhRm9yUHJldmlldyhcbiAgICBkZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzLFxuICAgIGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnXG4gICk6IFByb21pc2U8SVJlc3VsdExpc3Q8SU1lYXN1cmVtZW50Pj4gfCB1bmRlZmluZWQge1xuICAgIGxldCBtZWFzdXJlbWVudHM6IElSZXN1bHRMaXN0PElNZWFzdXJlbWVudD4gfCB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBmaWx0ZXI6IElNZWFzdXJlbWVudEZpbHRlciA9IHRoaXMucHJlcGFyZU1lYXN1cmVtZW50c0ZpbHRlcihcbiAgICAgIGRldGFpbHMsXG4gICAgICBleHBvcnRDb25maWcsXG4gICAgICBNRUFTVVJFTUVOVFNfUFJFVklFV19JVEVNU19MSU1JVFxuICAgICk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gVE9ETzogY29uc2lkZXIgYWRkaW5nIGEgY2FjaGUgbWVjaGFuaXNtIC0+IE1UTS02MDI4OVxuICAgICAgLy8gV2hlbiB1c2VyIHN3aXRjaGVzIGJldHdlZW4gcmVwb3J0IHR5cGVzLCBhbmQgcmVzdCBvZiB0aGUgc2V0dGluZ3MgYXJlIHRoZSBzYW1lLCB0aGVuIHRoZSBkYXRhIHNob3VsZCBub3QgYmUgZmV0Y2hlZCBhZ2Fpbj9cbiAgICAgIG1lYXN1cmVtZW50cyA9IGF3YWl0IHRoaXMubWVhc3VyZW1lbnRTZXJ2aWNlLmxpc3QoZmlsdGVyKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkU2VydmVyRmFpbHVyZShlcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1lYXN1cmVtZW50cztcbiAgfVxuXG4gIHByaXZhdGUgcHJlcGFyZU1lYXN1cmVtZW50c0ZpbHRlcihcbiAgICBkZXRhaWxzOiBEYXRhcG9pbnREZXRhaWxzLFxuICAgIGV4cG9ydENvbmZpZzogRXhwb3J0Q29uZmlnLFxuICAgIHBhZ2VTaXplPzogbnVtYmVyXG4gICk6IElNZWFzdXJlbWVudEZpbHRlciB7XG4gICAgY29uc3QgZmlsdGVyOiBJTWVhc3VyZW1lbnRGaWx0ZXIgPSB7XG4gICAgICAvLyBSb3VuZCB0aGUgJ2Zyb20nIHRpbWUgdG8gdGhlIHByZXZpb3VzIGZ1bGwgbWludXRlLlxuICAgICAgZGF0ZUZyb206IHRoaXMuYWRqdXN0RGF0ZShleHBvcnRDb25maWcuZGF0ZUZyb20sIC0xKSxcbiAgICAgIC8vIFJvdW5kIHRoZSAndG8nIHRpbWUgdG8gdGhlIG5lYXJlc3QgZnVsbCBtaW51dGUuXG4gICAgICBkYXRlVG86IHRoaXMuYWRqdXN0RGF0ZShleHBvcnRDb25maWcuZGF0ZVRvLCAxKSxcbiAgICAgIHNvdXJjZTogZGV0YWlscy5zb3VyY2UsXG4gICAgICB2YWx1ZUZyYWdtZW50U2VyaWVzOiBkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXMsXG4gICAgICB2YWx1ZUZyYWdtZW50VHlwZTogZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZVxuICAgIH07XG5cbiAgICBpZiAocGFnZVNpemUpIHtcbiAgICAgIGZpbHRlci5wYWdlU2l6ZSA9IHBhZ2VTaXplO1xuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXI7XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NNZWFzdXJlbWVudERhdGFGb3JQcmV2aWV3KFxuICAgIGRldGFpbHM6IERhdGFwb2ludERldGFpbHMsXG4gICAgZGF0YTogSU1lYXN1cmVtZW50W11cbiAgKTogRGF0YVRvRXhwb3J0IHtcbiAgICBjb25zdCB1bml0ID0gZGF0YVswXVtkZXRhaWxzLnZhbHVlRnJhZ21lbnRUeXBlXVtkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXNdPy51bml0IHx8ICcnO1xuXG4gICAgY29uc3QgdmFsdWVzOiB7IFt0aW1lc3RhbXA6IHN0cmluZ106IG51bWJlciB9ID0ge307XG4gICAgZGF0YS5mb3JFYWNoKG1lYXN1cmVtZW50ID0+IHtcbiAgICAgIHZhbHVlc1ttZWFzdXJlbWVudC50aW1lXSA9XG4gICAgICAgIG1lYXN1cmVtZW50W2RldGFpbHMudmFsdWVGcmFnbWVudFR5cGVdW2RldGFpbHMudmFsdWVGcmFnbWVudFNlcmllc10udmFsdWU7XG4gICAgfSk7XG5cbiAgICByZXR1cm4geyAuLi5kZXRhaWxzLCB1bml0LCB0aW1lVmFsdWVNYXA6IHZhbHVlcyB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaEFuZFByZXBhcmVTZXJpZXNEYXRhVG9FeHBvcnQoZXhwb3J0Q29uZmlnOiBFeHBvcnRDb25maWcpIHtcbiAgICBjb25zdCBkYXRhcG9pbnRzVmFsdWVzRGF0YU1hcDogRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAgPSB0aGlzLmdyb3VwU2VyaWVzQnlEZXZpY2VJZChcbiAgICAgIGV4cG9ydENvbmZpZy5kYXRhcG9pbnREZXRhaWxzXG4gICAgKTtcblxuICAgIGNvbnN0IGZldGNoZWREYXRhUHJvbWlzZXMgPSBBcnJheS5mcm9tKGRhdGFwb2ludHNWYWx1ZXNEYXRhTWFwKS5tYXAoXG4gICAgICBhc3luYyAoW3NvdXJjZSwgc2VyaWVzXSkgPT4ge1xuICAgICAgICBjb25zdCB7IGRhdGVGcm9tLCBkYXRlVG8sIGFnZ3JlZ2F0aW9uIH0gPSBleHBvcnRDb25maWc7XG5cbiAgICAgICAgY29uc3QgcmF3RmlsdGVyOiBJU2VyaWVzRmlsdGVyID0ge1xuICAgICAgICAgIGRhdGVGcm9tLFxuICAgICAgICAgIGRhdGVUbyxcbiAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgc2VyaWVzLFxuICAgICAgICAgIGFnZ3JlZ2F0aW9uVHlwZTogYWdncmVnYXRpb24gYXMgYWdncmVnYXRpb25UeXBlXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgeyBkYXRhIH06IElSZXN1bHQ8SVNlcmllcz4gPSBhd2FpdCB0aGlzLmZldGNoU2VyaWVzRGF0YShyYXdGaWx0ZXIpO1xuXG4gICAgICAgIHJldHVybiB7IHNvdXJjZSwgZGF0YSB9O1xuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25zdCBmZXRjaGVkRGF0YUdyb3VwZWRCeVNvdXJjZTogU291cmNlSXRlbVtdID0gYXdhaXQgUHJvbWlzZS5hbGwoZmV0Y2hlZERhdGFQcm9taXNlcyk7XG5cbiAgICByZXR1cm4gdGhpcy5wcm9jZXNzU2VyaWVzRGF0YShleHBvcnRDb25maWcuZGF0YXBvaW50RGV0YWlscywgZmV0Y2hlZERhdGFHcm91cGVkQnlTb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBtYXAgb2YgYWN0aXZlIGRhdGEgcG9pbnRzIGRldmljZSBJRHMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIHNlcmllcy5cbiAgICpcbiAgICogRXhhbXBsZSBvdXRwdXQ6XG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogbmV3IE1hcChbXG4gICAqICAgWyc4NDQ2NTcyMDInLCBbJ2M4eV9UZW1wZXJhdHVyZS5UJ11dLFxuICAgKiAgIFsnMzI2NjY0MjcnLCBbJ2M4eV9CYXR0ZXJ5LkJhdHRlcnknXV1cbiAgICogXSk7XG4gICAqIGBgYFxuICAgKiBAcGFyYW0gZGF0YXBvaW50RGV0YWlscyAtIEFuIGFycmF5IG9mIGRhdGEgcG9pbnRzIGRldGFpbHMuXG4gICAqIEByZXR1cm5zIEEgbWFwIHdoZXJlIHRoZSBrZXkgaXMgdGhlIGRhdGEgcG9pbnQgSUQgYW5kIHRoZSB2YWx1ZSBpcyBhbiBhcnJheSBvZiBkYXRhIHBvaW50IHNlcmllcy5cbiAgICovXG4gIHByaXZhdGUgZ3JvdXBTZXJpZXNCeURldmljZUlkKGRhdGFwb2ludERldGFpbHM6IERhdGFwb2ludERldGFpbHNbXSk6IERhdGFwb2ludHNWYWx1ZXNEYXRhTWFwIHtcbiAgICByZXR1cm4gZGF0YXBvaW50RGV0YWlscy5yZWR1Y2UoXG4gICAgICAoXG4gICAgICAgIG1hcDogRGF0YXBvaW50c1ZhbHVlc0RhdGFNYXAsXG4gICAgICAgIHsgdmFsdWVGcmFnbWVudFR5cGUsIHZhbHVlRnJhZ21lbnRTZXJpZXMsIHNvdXJjZSB9OiBEYXRhcG9pbnREZXRhaWxzXG4gICAgICApID0+IHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBgJHt2YWx1ZUZyYWdtZW50VHlwZX0uJHt2YWx1ZUZyYWdtZW50U2VyaWVzfWA7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nVmFsdWUgPSBtYXAuZ2V0KHNvdXJjZSkgPz8gW107XG4gICAgICAgIG1hcC5zZXQoc291cmNlLCBbLi4uZXhpc3RpbmdWYWx1ZSwgdmFsdWVdKTtcbiAgICAgICAgcmV0dXJuIG1hcDtcbiAgICAgIH0sXG4gICAgICBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KClcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaFNlcmllc0RhdGEocmF3RmlsdGVyOiBJU2VyaWVzRmlsdGVyKTogUHJvbWlzZTxJUmVzdWx0PElTZXJpZXM+PiB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IHNlcmllc0RhdGE6IElSZXN1bHQ8SVNlcmllcz4gfCB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBmaWx0ZXI6IElTZXJpZXNGaWx0ZXIgPSB0aGlzLnByZXBhcmVTZXJpZXNGaWx0ZXIoe1xuICAgICAgZGF0ZUZyb206IHJhd0ZpbHRlci5kYXRlRnJvbSxcbiAgICAgIGRhdGVUbzogcmF3RmlsdGVyLmRhdGVUbyxcbiAgICAgIHNvdXJjZTogcmF3RmlsdGVyLnNvdXJjZSxcbiAgICAgIHNlcmllczogcmF3RmlsdGVyLnNlcmllcyxcbiAgICAgIGFnZ3JlZ2F0aW9uVHlwZTogcmF3RmlsdGVyLmFnZ3JlZ2F0aW9uVHlwZVxuICAgIH0pO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFRPRE86IGNvbnNpZGVyIGFkZGluZyBhIGNhY2hlIG1lY2hhbmlzbSAtPiBNVE0tNjAyODlcbiAgICAgIC8vIFdoZW4gdXNlciBzd2l0Y2hlcyBiZXR3ZWVuIHJlcG9ydCB0eXBlcywgYW5kIHJlc3Qgb2YgdGhlIHNldHRpbmdzIGFyZSB0aGUgc2FtZSwgdGhlbiB0aGUgZGF0YSBzaG91bGQgbm90IGJlIGZldGNoZWQgYWdhaW4/XG4gICAgICBzZXJpZXNEYXRhID0gYXdhaXQgdGhpcy5tZWFzdXJlbWVudFNlcnZpY2UubGlzdFNlcmllcyhmaWx0ZXIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRTZXJ2ZXJGYWlsdXJlKGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VyaWVzRGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgcHJlcGFyZVNlcmllc0ZpbHRlcihmaWx0ZXJzOiBJU2VyaWVzRmlsdGVyKTogSVNlcmllc0ZpbHRlciB7XG4gICAgY29uc3QgeyBkYXRlRnJvbSwgZGF0ZVRvLCBzb3VyY2UsIHNlcmllcywgYWdncmVnYXRpb25UeXBlIH0gPSBmaWx0ZXJzO1xuICAgIC8vIFJvdW5kIHRoZSAnZnJvbScgdGltZSB0byB0aGUgcHJldmlvdXMgZnVsbCBtaW51dGUuXG4gICAgY29uc3QgZnJvbSA9IHRoaXMuYWRqdXN0RGF0ZShkYXRlRnJvbSwgLTEpO1xuICAgIC8vIFJvdW5kIHRoZSAndG8nIHRpbWUgdG8gdGhlIG5lYXJlc3QgZnVsbCBtaW51dGUuXG4gICAgY29uc3QgdG8gPSB0aGlzLmFkanVzdERhdGUoZGF0ZVRvLCAxKTtcblxuICAgIGNvbnN0IGZpbHRlcjogSVNlcmllc0ZpbHRlciA9IHtcbiAgICAgIGRhdGVGcm9tOiBmcm9tLFxuICAgICAgZGF0ZVRvOiB0byxcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgcmV2ZXJ0OiB0cnVlXG4gICAgfTtcblxuICAgIC8vIFRoZSAnTk9ORScgYWdncmVnYXRpb24gdHlwZSBpcyBub3QgaGFuZGxlZCBieSBhIGJhY2tlbmQsIHNvIGV2ZW4gd2hlbiBpcyBzZWxlY3RlZCwgaXQgaXMgbm90IHBhc3NlZCBhcyBhIGZpbHRlciBwYXJhbWV0ZXIuXG4gICAgaWYgKGFnZ3JlZ2F0aW9uVHlwZSAmJiBhZ2dyZWdhdGlvblR5cGUgIT09IChBR0dSRUdBVElPTl9WQUxVRVMubm9uZSBhcyBhZ2dyZWdhdGlvblR5cGUpKSB7XG4gICAgICBmaWx0ZXIuYWdncmVnYXRpb25UeXBlID0gYWdncmVnYXRpb25UeXBlO1xuICAgIH1cblxuICAgIC8vIFRPRE86IGl0IGlzIGEgdGVtcG9yYWwgd29ya2Fyb3VuZCBmb3IgYSBidWcgaW4gdGhlIGJhY2tlbmQsXG4gICAgLy8gd2hlcmUgdGhlIHNlcmllcyB3aXRoIG1vcmUgdGhhbiBvbmUgZG90IGFyZSBpbXBvc3NpYmxlIHRvIHJldHJpZXZlOlxuICAgIC8vIGh0dHBzOi8vY3VtdWxvY2l0eS5hdGxhc3NpYW4ubmV0L2Jyb3dzZS9NVE0tNTkyNzdcbiAgICBpZiAoc2VyaWVzKSB7XG4gICAgICBjb25zdCBoYXNNb3JlVGhhbk9uZURvdCA9IChzZXJpZXMgYXMgc3RyaW5nW10pLnNvbWUocyA9PiBzLnNwbGl0KCcuJykubGVuZ3RoID4gMik7XG4gICAgICBpZiAoIWhhc01vcmVUaGFuT25lRG90KSB7XG4gICAgICAgIGZpbHRlci5zZXJpZXMgPSBzZXJpZXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzZXMgdGhlIGZldGNoZWQgc2VyaWVzIGRhdGEgYW5kIHByZXBhcmVzIGl0IGZvciBleHBvcnQuXG4gICAqXG4gICAqIEBwYXJhbSBkYXRhcG9pbnREZXRhaWxzIC0gQW4gYXJyYXkgb2YgZGF0YSBwb2ludCBkZXRhaWxzLlxuICAgKiBAcGFyYW0gZmV0Y2hlZERhdGFNYXAgLSBBIG1hcCBvZiBmZXRjaGVkIHNlcmllcyBkYXRhIGdyb3VwZWQgYnkgc291cmNlLlxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBEYXRhVG9FeHBvcnQgb2JqZWN0cy5cbiAgICovXG4gIHByaXZhdGUgcHJvY2Vzc1Nlcmllc0RhdGEoZGF0YXBvaW50RGV0YWlsczogRGF0YXBvaW50RGV0YWlsc1tdLCBmZXRjaGVkRGF0YU1hcDogU291cmNlSXRlbVtdKSB7XG4gICAgY29uc3QgdmFsdWVzR3JvdXBlZEJ5U291cmNlID0gdGhpcy51dGlsc1NlcnZpY2UudHJhbnNmb3JtRGF0YVN0cnVjdHVyZShmZXRjaGVkRGF0YU1hcCk7XG5cbiAgICByZXR1cm4gZGF0YXBvaW50RGV0YWlscy5tYXAoKGRldGFpbHM6IERhdGFwb2ludERldGFpbHMpID0+IHtcbiAgICAgIGxldCB1bml0OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBsZXQgZGF0YTogVGltZVNlcmllc0RhdGE7XG5cbiAgICAgIC8qKlxuICAgICAgICogVW5pcXVlIGtleSB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIGRpZmZlcmVudCBzZXJpZXMgZnJvbSBzYW1lIHNvdXJjZSxcbiAgICAgICAqIGUuZy46IGM4eV9BY2NlbGVyYXRpb24uYWNjZWxlcmF0aW9uWCwgYzh5X0FjY2VsZXJhdGlvbi5hY2NlbGVyYXRpb25ZLCBjOHlfQWNjZWxlcmF0aW9uLmFjY2VsZXJhdGlvblpcbiAgICAgICAqL1xuICAgICAgY29uc3Qgc2VyaWVzS2V5ID0gYCR7ZGV0YWlscy52YWx1ZUZyYWdtZW50VHlwZX0uJHtkZXRhaWxzLnZhbHVlRnJhZ21lbnRTZXJpZXN9YDtcblxuICAgICAgaWYgKHZhbHVlc0dyb3VwZWRCeVNvdXJjZVtkZXRhaWxzLnNvdXJjZV1bc2VyaWVzS2V5XSkge1xuICAgICAgICB1bml0ID0gdmFsdWVzR3JvdXBlZEJ5U291cmNlW2RldGFpbHMuc291cmNlXVtzZXJpZXNLZXldLnNlcmllc0RldGFpbHMudW5pdDtcbiAgICAgICAgZGF0YSA9IHZhbHVlc0dyb3VwZWRCeVNvdXJjZVtkZXRhaWxzLnNvdXJjZV1bc2VyaWVzS2V5XS52YWx1ZXM7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmRldGFpbHMsXG4gICAgICAgIHVuaXQsXG4gICAgICAgIHRpbWVWYWx1ZU1hcDogZGF0YVxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGp1c3RzIHRoZSBnaXZlbiBkYXRlIGJ5IGFkZGluZyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBtaW51dGVzIGFuZCBzZXR0aW5nIHNlY29uZHMgdG8gMC5cbiAgICpcbiAgICogQHBhcmFtIGRhdGUgLSBUaGUgZGF0ZSB0byBiZSBhZGp1c3RlZCBpbiBzdHJpbmcgZm9ybWF0LlxuICAgKiBAcGFyYW0gbWludXRlcyAtIFRoZSBudW1iZXIgb2YgbWludXRlcyB0byBhZGQgdG8gdGhlIGRhdGUuXG4gICAqIEByZXR1cm5zIFRoZSBhZGp1c3RlZCBkYXRlIGluIHRoZSBmb3JtYXQgJ1lZWVktTU0tRERUSEg6bW06c3MrSEg6TU0nLlxuICAgKi9cbiAgcHJpdmF0ZSBhZGp1c3REYXRlKGRhdGU6IHN0cmluZyB8IERhdGUsIG1pbnV0ZXM6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgZGF0ZVRpbWUgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICBkYXRlVGltZS5zZXRNaW51dGVzKGRhdGVUaW1lLmdldE1pbnV0ZXMoKSArIG1pbnV0ZXMpO1xuICAgIGRhdGVUaW1lLnNldFNlY29uZHMoMCk7XG5cbiAgICBjb25zdCBvZmZzZXQgPSAtZGF0ZVRpbWUuZ2V0VGltZXpvbmVPZmZzZXQoKTtcbiAgICBjb25zdCBvZmZzZXRTaWduID0gb2Zmc2V0ID49IDAgPyAnKycgOiAnLSc7XG4gICAgY29uc3QgcGFkID0gKG51bTogbnVtYmVyKTogc3RyaW5nID0+IChudW0gPCAxMCA/ICcwJyArIG51bSA6IG51bS50b1N0cmluZygpKTtcbiAgICBjb25zdCBvZmZzZXRIb3VycyA9IHBhZChNYXRoLmZsb29yKE1hdGguYWJzKG9mZnNldCkgLyA2MCkpO1xuICAgIGNvbnN0IG9mZnNldE1pbnV0ZXMgPSBwYWQoTWF0aC5hYnMob2Zmc2V0KSAlIDYwKTtcblxuICAgIGNvbnN0IHllYXIgPSBkYXRlVGltZS5nZXRGdWxsWWVhcigpO1xuICAgIGNvbnN0IG1vbnRoID0gcGFkKGRhdGVUaW1lLmdldE1vbnRoKCkgKyAxKTtcbiAgICBjb25zdCBkYXkgPSBwYWQoZGF0ZVRpbWUuZ2V0RGF0ZSgpKTtcbiAgICBjb25zdCBob3VycyA9IHBhZChkYXRlVGltZS5nZXRIb3VycygpKTtcbiAgICBjb25zdCBtaW51dGVzU3RyaW5nID0gcGFkKGRhdGVUaW1lLmdldE1pbnV0ZXMoKSk7XG4gICAgY29uc3Qgc2Vjb25kcyA9ICcwMCc7XG5cbiAgICByZXR1cm4gYCR7eWVhcn0tJHttb250aH0tJHtkYXl9VCR7aG91cnN9OiR7bWludXRlc1N0cmluZ306JHtzZWNvbmRzfSR7b2Zmc2V0U2lnbn0ke29mZnNldEhvdXJzfToke29mZnNldE1pbnV0ZXN9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmltcyB0aGUgZ2l2ZW4gSFRNTCBtZXNzYWdlIGJ5IHJlbW92aW5nIGxpc3QgaXRlbXMgdGhhdCBjb3JyZXNwb25kIHRvIHplcm8gY291bnRzLlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSAtIFRoZSBIVE1MIHN0cmluZyBjb250YWluaW5nIHRoZSBtZXNzYWdlIHdpdGggbGlzdCBpdGVtcy5cbiAgICogQHBhcmFtIGNvdW50cyAtIEFuIGFycmF5IG9mIG51bWJlciB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byBlYWNoIGxpc3QgaXRlbS5cbiAgICogQHBhcmFtIGNvdW50VG9UcmltIC0gQSBjb3VudCB0aGF0IHdpbGwgYmUgdHJpbW1lZCB3aXRoIGNvcnJlc3BvbmRpbmcgbGlzdCBpdGVtLlxuICAgKiBAcmV0dXJucyBBIHRyaW1tZWQgSFRNTCBzdHJpbmcgd2l0aCBsaXN0IGl0ZW1zIHJlbW92ZWQgd2hlcmUgdGhlIGNvcnJlc3BvbmRpbmcgY291bnQgaXMgemVyby5cbiAgICpcbiAgICogRXhhbXBsZTpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBtZXNzYWdlID0gJzx1bD48bGk+SXRlbSAxPC9saT48bGk+SXRlbSAyPC9saT48bGk+SXRlbSAzPC9saT48L3VsPic7XG4gICAqIGNvbnN0IGNvdW50cyA9IFsxLCAwLCAyXTtcbiAgICogY29uc3QgdHJpbW1lZE1lc3NhZ2UgPSB0aGlzLnJlbW92ZVplcm9Db3VudExpc3RJdGVtcyhtZXNzYWdlLCBjb3VudHMpO1xuICAgKiAvLyBSZXN1bHQ6ICc8dWw+PGxpPkl0ZW0gMTwvbGk+PGxpPkl0ZW0gMzwvbGk+PC91bD4nXG4gICAqIGBgYFxuICAgKi9cbiAgcHJpdmF0ZSByZW1vdmVaZXJvQ291bnRMaXN0SXRlbXMobWVzc2FnZTogc3RyaW5nLCBjb3VudHM6IG51bWJlcltdLCBjb3VudFRvVHJpbSA9IDApOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICBjb25zdCBkb2MgPSBwYXJzZXIucGFyc2VGcm9tU3RyaW5nKG1lc3NhZ2UsICd0ZXh0L2h0bWwnKTtcbiAgICBjb25zdCBsaXN0SXRlbXMgPSBkb2MucXVlcnlTZWxlY3RvckFsbCgndWwgbGknKTtcblxuICAgIGxpc3RJdGVtcy5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGNvdW50c1tpbmRleF0gPT09IGNvdW50VG9UcmltKSB7XG4gICAgICAgIGl0ZW0ucmVtb3ZlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZG9jLmJvZHkuaW5uZXJIVE1MO1xuICB9XG59XG4iXX0=
|