@openziti/ziti-console-lib 1.0.2 → 1.1.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/assets/styles/global.scss +70 -0
- package/fesm2022/openziti-ziti-console-lib.mjs +2136 -1327
- package/fesm2022/openziti-ziti-console-lib.mjs.map +1 -1
- package/index.d.ts +5689 -6
- package/index.d.ts.map +1 -0
- package/package.json +10 -12
- package/esm2022/lib/ZAC_VERSION.mjs +0 -4
- package/esm2022/lib/app.initializer.mjs +0 -24
- package/esm2022/lib/default-app-config.mjs +0 -5
- package/esm2022/lib/features/card/card.component.mjs +0 -34
- package/esm2022/lib/features/card-list/card-list.component.mjs +0 -55
- package/esm2022/lib/features/config-editor/config-editor.component.mjs +0 -337
- package/esm2022/lib/features/confirm/confirm.component.mjs +0 -77
- package/esm2022/lib/features/creation-summary-dialog/creation-summary-dialog.component.mjs +0 -93
- package/esm2022/lib/features/custom-tags/custom-tags.component.mjs +0 -111
- package/esm2022/lib/features/data-table/cells/table-cell-menu/table-cell-menu.component.mjs +0 -46
- package/esm2022/lib/features/data-table/cells/table-cell-name/table-cell-name.component.mjs +0 -49
- package/esm2022/lib/features/data-table/cells/table-cell-select/table-cell-select.component.mjs +0 -58
- package/esm2022/lib/features/data-table/cells/table-cell-token/table-cell-token.component.mjs +0 -123
- package/esm2022/lib/features/data-table/column-headers/table-column-default/table-column-default.component.mjs +0 -268
- package/esm2022/lib/features/data-table/column-headers/table-column-filter/table-column-filter.component.mjs +0 -93
- package/esm2022/lib/features/data-table/column-headers/table-column-menu/table-column-menu.component.mjs +0 -37
- package/esm2022/lib/features/data-table/column-headers/table-column-select/table-column-select.component.mjs +0 -33
- package/esm2022/lib/features/data-table/data-table-filter.service.mjs +0 -138
- package/esm2022/lib/features/data-table/data-table.component.mjs +0 -918
- package/esm2022/lib/features/data-table/data-table.service.mjs +0 -98
- package/esm2022/lib/features/data-table/table-filter-bar/filter-bar.component.mjs +0 -108
- package/esm2022/lib/features/data-table/table-hidden-columns-bar/hidden-columns-bar.component.mjs +0 -26
- package/esm2022/lib/features/data-table/tooltips/os-tooltip.component.mjs +0 -29
- package/esm2022/lib/features/data-table/tooltips/sdk-tooltip.component.mjs +0 -34
- package/esm2022/lib/features/dynamic-widgets/boolean/boolean-toggle-input.component.mjs +0 -72
- package/esm2022/lib/features/dynamic-widgets/checkbox-list/checkbox-list-input.component.mjs +0 -134
- package/esm2022/lib/features/dynamic-widgets/forwarding-config/forwarding-config.component.mjs +0 -189
- package/esm2022/lib/features/dynamic-widgets/forwarding-config/forwarding-config.service.mjs +0 -50
- package/esm2022/lib/features/dynamic-widgets/number/number-input.component.mjs +0 -95
- package/esm2022/lib/features/dynamic-widgets/object/object.component.mjs +0 -121
- package/esm2022/lib/features/dynamic-widgets/password/password-input.component.mjs +0 -83
- package/esm2022/lib/features/dynamic-widgets/port-ranges/port-ranges.component.mjs +0 -100
- package/esm2022/lib/features/dynamic-widgets/protocol-address-port/protocol-address-port-input.component.mjs +0 -201
- package/esm2022/lib/features/dynamic-widgets/selector/selector-input.component.mjs +0 -166
- package/esm2022/lib/features/dynamic-widgets/string/string-input.component.mjs +0 -108
- package/esm2022/lib/features/dynamic-widgets/text-list/text-list-input.component.mjs +0 -126
- package/esm2022/lib/features/extendable/extendable.component.mjs +0 -55
- package/esm2022/lib/features/extendable/extensions-noop.service.mjs +0 -52
- package/esm2022/lib/features/header-bar/header-bar.component.mjs +0 -105
- package/esm2022/lib/features/json-view/json-view.component.mjs +0 -212
- package/esm2022/lib/features/list-page-features/list-page-form/list-page-form.component.mjs +0 -138
- package/esm2022/lib/features/list-page-features/list-page-header/list-page-header.component.mjs +0 -66
- package/esm2022/lib/features/loading-indicator/loading-indicator.component.mjs +0 -29
- package/esm2022/lib/features/login/login-dialog.component.mjs +0 -121
- package/esm2022/lib/features/messaging/growler.component.mjs +0 -62
- package/esm2022/lib/features/messaging/growler.model.mjs +0 -24
- package/esm2022/lib/features/messaging/growler.module.mjs +0 -34
- package/esm2022/lib/features/messaging/growler.service.mjs +0 -71
- package/esm2022/lib/features/messaging/logger.service.mjs +0 -174
- package/esm2022/lib/features/multi-action-button/multi-action-button.component.mjs +0 -30
- package/esm2022/lib/features/no-items/no-items.component.mjs +0 -46
- package/esm2022/lib/features/overrides/overrides.component.mjs +0 -118
- package/esm2022/lib/features/overrides/overrides.service.mjs +0 -114
- package/esm2022/lib/features/preview-list/preview-list.component.mjs +0 -151
- package/esm2022/lib/features/preview-selections/preview-selections.component.mjs +0 -114
- package/esm2022/lib/features/progress-meter/progress-meter.component.mjs +0 -43
- package/esm2022/lib/features/progress-wizard/progress-wizard.component.mjs +0 -90
- package/esm2022/lib/features/projectable-forms/api-session/api-session-form.component.mjs +0 -143
- package/esm2022/lib/features/projectable-forms/api-session/api-session-form.service.mjs +0 -118
- package/esm2022/lib/features/projectable-forms/auth-policy/auth-policy-form.component.mjs +0 -337
- package/esm2022/lib/features/projectable-forms/auth-policy/auth-policy-form.service.mjs +0 -114
- package/esm2022/lib/features/projectable-forms/certificate-authority/certificate-authority-form.component.mjs +0 -399
- package/esm2022/lib/features/projectable-forms/certificate-authority/certificate-authority-form.service.mjs +0 -95
- package/esm2022/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.component.mjs +0 -217
- package/esm2022/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.service.mjs +0 -54
- package/esm2022/lib/features/projectable-forms/config-type/config-type-form.component.mjs +0 -244
- package/esm2022/lib/features/projectable-forms/config-type/config-type-form.service.mjs +0 -92
- package/esm2022/lib/features/projectable-forms/configuration/configuration-form.component.mjs +0 -275
- package/esm2022/lib/features/projectable-forms/configuration/configuration.service.mjs +0 -137
- package/esm2022/lib/features/projectable-forms/edge-router/edge-router-form.component.mjs +0 -231
- package/esm2022/lib/features/projectable-forms/edge-router/edge-router-form.service.mjs +0 -118
- package/esm2022/lib/features/projectable-forms/edge-router-policy/edge-router-policy-form.component.mjs +0 -277
- package/esm2022/lib/features/projectable-forms/edge-router-policy/edge-router-policy-form.service.mjs +0 -188
- package/esm2022/lib/features/projectable-forms/form-field-container/form-field-container.component.mjs +0 -101
- package/esm2022/lib/features/projectable-forms/form-field-toggle/form-field-toggle.component.mjs +0 -54
- package/esm2022/lib/features/projectable-forms/form-header/form-header.component.mjs +0 -135
- package/esm2022/lib/features/projectable-forms/identity/identity-form.component.mjs +0 -471
- package/esm2022/lib/features/projectable-forms/identity/identity-form.service.mjs +0 -131
- package/esm2022/lib/features/projectable-forms/jwt-signer/jwt-signer-form.component.mjs +0 -533
- package/esm2022/lib/features/projectable-forms/jwt-signer/jwt-signer-form.service.mjs +0 -79
- package/esm2022/lib/features/projectable-forms/posture-check/posture-check-form.component.mjs +0 -437
- package/esm2022/lib/features/projectable-forms/posture-check/posture-check-form.service.mjs +0 -81
- package/esm2022/lib/features/projectable-forms/projectable-form.class.mjs +0 -315
- package/esm2022/lib/features/projectable-forms/service/service-form.component.mjs +0 -330
- package/esm2022/lib/features/projectable-forms/service/service-form.service.mjs +0 -591
- package/esm2022/lib/features/projectable-forms/service/simple-service/simple-service.component.mjs +0 -1036
- package/esm2022/lib/features/projectable-forms/service-edge-router-policy/service-edge-router-policy-form.component.mjs +0 -275
- package/esm2022/lib/features/projectable-forms/service-edge-router-policy/service-edge-router-policy-form.service.mjs +0 -172
- package/esm2022/lib/features/projectable-forms/service-policy/service-policy-form.component.mjs +0 -279
- package/esm2022/lib/features/projectable-forms/service-policy/service-policy-form.service.mjs +0 -230
- package/esm2022/lib/features/projectable-forms/session/session-form.component.mjs +0 -213
- package/esm2022/lib/features/projectable-forms/session/session-form.service.mjs +0 -84
- package/esm2022/lib/features/projectable-forms/terminator/terminator-form.component.mjs +0 -244
- package/esm2022/lib/features/projectable-forms/terminator/terminator-form.service.mjs +0 -130
- package/esm2022/lib/features/projectable-forms/transit-router/transit-router-form.component.mjs +0 -224
- package/esm2022/lib/features/projectable-forms/transit-router/transit-router-form.service.mjs +0 -118
- package/esm2022/lib/features/qr-code/qr-code.component.mjs +0 -166
- package/esm2022/lib/features/quick-add/quick-add.component.mjs +0 -50
- package/esm2022/lib/features/reset-enrollment/reset-enrollment.component.mjs +0 -86
- package/esm2022/lib/features/reset-enrollment/reset-enrollment.service.mjs +0 -61
- package/esm2022/lib/features/side-modal/side-modal.component.mjs +0 -45
- package/esm2022/lib/features/side-navigator/side-navigator.component.mjs +0 -127
- package/esm2022/lib/features/sidebars/side-navbar/side-navbar.component.mjs +0 -54
- package/esm2022/lib/features/tag-selector/tag-selector.component.mjs +0 -291
- package/esm2022/lib/features/visualizer/identity-service-path/identity-service-path.component.mjs +0 -586
- package/esm2022/lib/features/visualizer/identity-service-path/identity-service-path.helper.mjs +0 -373
- package/esm2022/lib/features/visualizer/network-visualizer/network-visualizer.component.mjs +0 -1706
- package/esm2022/lib/features/visualizer/network-visualizer/network-visualizer.helper.mjs +0 -591
- package/esm2022/lib/features/visualizer/network-visualizer/network-visualizer.treenodeprocessor.mjs +0 -883
- package/esm2022/lib/features/visualizer/visualizer-service.class.mjs +0 -32
- package/esm2022/lib/models/api-session.mjs +0 -7
- package/esm2022/lib/models/auth-policy.mjs +0 -31
- package/esm2022/lib/models/certificate-authority.mjs +0 -16
- package/esm2022/lib/models/config-type.mjs +0 -10
- package/esm2022/lib/models/config.mjs +0 -10
- package/esm2022/lib/models/edge-router-policy.mjs +0 -11
- package/esm2022/lib/models/edge-router.mjs +0 -13
- package/esm2022/lib/models/identity.mjs +0 -34
- package/esm2022/lib/models/jwt-signer.mjs +0 -20
- package/esm2022/lib/models/posture-check.mjs +0 -29
- package/esm2022/lib/models/service-edge-router-policy.mjs +0 -11
- package/esm2022/lib/models/service-policy.mjs +0 -13
- package/esm2022/lib/models/service.mjs +0 -12
- package/esm2022/lib/models/session.mjs +0 -7
- package/esm2022/lib/models/terminator.mjs +0 -14
- package/esm2022/lib/pages/api-sessions/api-sessions-page.component.mjs +0 -112
- package/esm2022/lib/pages/api-sessions/api-sessions-page.service.mjs +0 -235
- package/esm2022/lib/pages/attributes/attributes.component.mjs +0 -104
- package/esm2022/lib/pages/auth-policies/auth-policies-page.component.mjs +0 -120
- package/esm2022/lib/pages/auth-policies/auth-policies-page.service.mjs +0 -215
- package/esm2022/lib/pages/callback/callback.component.mjs +0 -155
- package/esm2022/lib/pages/certificate-authorities/certificate-authorities-page.component.mjs +0 -119
- package/esm2022/lib/pages/certificate-authorities/certificate-authorities-page.service.mjs +0 -240
- package/esm2022/lib/pages/config-types/config-types-page.component.mjs +0 -130
- package/esm2022/lib/pages/config-types/config-types-page.service.mjs +0 -134
- package/esm2022/lib/pages/configurations/configurations-page.component.mjs +0 -134
- package/esm2022/lib/pages/configurations/configurations-page.service.mjs +0 -251
- package/esm2022/lib/pages/edge-router-policies/edge-router-policies-page.component.mjs +0 -128
- package/esm2022/lib/pages/edge-router-policies/edge-router-policies-page.service.mjs +0 -407
- package/esm2022/lib/pages/edge-routers/edge-routers-page.component.mjs +0 -136
- package/esm2022/lib/pages/edge-routers/edge-routers-page.service.mjs +0 -354
- package/esm2022/lib/pages/geolocate/geolocate.component.mjs +0 -130
- package/esm2022/lib/pages/identities/identities-page.component.mjs +0 -221
- package/esm2022/lib/pages/identities/identities-page.service.mjs +0 -591
- package/esm2022/lib/pages/jwt-signers/jwt-signers-page.component.mjs +0 -160
- package/esm2022/lib/pages/jwt-signers/jwt-signers-page.service.mjs +0 -177
- package/esm2022/lib/pages/posture-checks/posture-checks-page.component.mjs +0 -103
- package/esm2022/lib/pages/posture-checks/posture-checks-page.service.mjs +0 -200
- package/esm2022/lib/pages/profile/profile.component.mjs +0 -58
- package/esm2022/lib/pages/service-edge-router-policies/service-edge-router-policies-page.component.mjs +0 -122
- package/esm2022/lib/pages/service-edge-router-policies/service-edge-router-policies-page.service.mjs +0 -367
- package/esm2022/lib/pages/service-policies/service-policies-page.component.mjs +0 -124
- package/esm2022/lib/pages/service-policies/service-policies-page.service.mjs +0 -446
- package/esm2022/lib/pages/services/services-page.component.mjs +0 -218
- package/esm2022/lib/pages/services/services-page.service.mjs +0 -378
- package/esm2022/lib/pages/sessions/sessions-page.component.mjs +0 -112
- package/esm2022/lib/pages/sessions/sessions-page.service.mjs +0 -228
- package/esm2022/lib/pages/settings/settings.component.mjs +0 -61
- package/esm2022/lib/pages/terminators/terminators-page.component.mjs +0 -97
- package/esm2022/lib/pages/terminators/terminators-page.service.mjs +0 -235
- package/esm2022/lib/pages/transit-routers/transit-routers-page.component.mjs +0 -129
- package/esm2022/lib/pages/transit-routers/transit-routers-page.service.mjs +0 -248
- package/esm2022/lib/safe.pipe.mjs +0 -18
- package/esm2022/lib/services/auth.service.mjs +0 -94
- package/esm2022/lib/services/console-events.service.mjs +0 -20
- package/esm2022/lib/services/csv-download.service.mjs +0 -91
- package/esm2022/lib/services/deactivate-guard.service.mjs +0 -17
- package/esm2022/lib/services/login-service.class.mjs +0 -47
- package/esm2022/lib/services/node-data.service.mjs +0 -397
- package/esm2022/lib/services/noop-login.service.mjs +0 -41
- package/esm2022/lib/services/schema.service.mjs +0 -807
- package/esm2022/lib/services/settings-service.class.mjs +0 -120
- package/esm2022/lib/services/settings.service.mjs +0 -203
- package/esm2022/lib/services/tab-name.service.mjs +0 -76
- package/esm2022/lib/services/validation.service.mjs +0 -156
- package/esm2022/lib/services/ziti-controller-data.service.mjs +0 -340
- package/esm2022/lib/services/ziti-data.service.mjs +0 -100
- package/esm2022/lib/services/ziti-domain-controller.service.mjs +0 -3
- package/esm2022/lib/shared/list-page-component.class.mjs +0 -186
- package/esm2022/lib/shared/list-page-service.class.mjs +0 -244
- package/esm2022/lib/urls.mjs +0 -34
- package/esm2022/lib/zac-routing.module.mjs +0 -34
- package/esm2022/lib/ziti-console-lib.module.mjs +0 -538
- package/esm2022/lib/ziti-console.constants.mjs +0 -20
- package/esm2022/openziti-ziti-console-lib.mjs +0 -5
- package/esm2022/public-api.mjs +0 -130
- package/lib/ZAC_VERSION.d.ts +0 -4
- package/lib/ZAC_VERSION.d.ts.map +0 -1
- package/lib/app.initializer.d.ts +0 -3
- package/lib/app.initializer.d.ts.map +0 -1
- package/lib/default-app-config.d.ts +0 -9
- package/lib/default-app-config.d.ts.map +0 -1
- package/lib/features/card/card.component.d.ts +0 -13
- package/lib/features/card/card.component.d.ts.map +0 -1
- package/lib/features/card-list/card-list.component.d.ts +0 -27
- package/lib/features/card-list/card-list.component.d.ts.map +0 -1
- package/lib/features/config-editor/config-editor.component.d.ts +0 -50
- package/lib/features/config-editor/config-editor.component.d.ts.map +0 -1
- package/lib/features/confirm/confirm.component.d.ts +0 -34
- package/lib/features/confirm/confirm.component.d.ts.map +0 -1
- package/lib/features/creation-summary-dialog/creation-summary-dialog.component.d.ts +0 -32
- package/lib/features/creation-summary-dialog/creation-summary-dialog.component.d.ts.map +0 -1
- package/lib/features/custom-tags/custom-tags.component.d.ts +0 -37
- package/lib/features/custom-tags/custom-tags.component.d.ts.map +0 -1
- package/lib/features/data-table/cells/table-cell-menu/table-cell-menu.component.d.ts +0 -16
- package/lib/features/data-table/cells/table-cell-menu/table-cell-menu.component.d.ts.map +0 -1
- package/lib/features/data-table/cells/table-cell-name/table-cell-name.component.d.ts +0 -20
- package/lib/features/data-table/cells/table-cell-name/table-cell-name.component.d.ts.map +0 -1
- package/lib/features/data-table/cells/table-cell-select/table-cell-select.component.d.ts +0 -15
- package/lib/features/data-table/cells/table-cell-select/table-cell-select.component.d.ts.map +0 -1
- package/lib/features/data-table/cells/table-cell-token/table-cell-token.component.d.ts +0 -22
- package/lib/features/data-table/cells/table-cell-token/table-cell-token.component.d.ts.map +0 -1
- package/lib/features/data-table/column-headers/table-column-default/table-column-default.component.d.ts +0 -52
- package/lib/features/data-table/column-headers/table-column-default/table-column-default.component.d.ts.map +0 -1
- package/lib/features/data-table/column-headers/table-column-filter/table-column-filter.component.d.ts +0 -27
- package/lib/features/data-table/column-headers/table-column-filter/table-column-filter.component.d.ts.map +0 -1
- package/lib/features/data-table/column-headers/table-column-menu/table-column-menu.component.d.ts +0 -19
- package/lib/features/data-table/column-headers/table-column-menu/table-column-menu.component.d.ts.map +0 -1
- package/lib/features/data-table/column-headers/table-column-select/table-column-select.component.d.ts +0 -15
- package/lib/features/data-table/column-headers/table-column-select/table-column-select.component.d.ts.map +0 -1
- package/lib/features/data-table/data-table-filter.service.d.ts +0 -37
- package/lib/features/data-table/data-table-filter.service.d.ts.map +0 -1
- package/lib/features/data-table/data-table.component.d.ts +0 -164
- package/lib/features/data-table/data-table.component.d.ts.map +0 -1
- package/lib/features/data-table/data-table.service.d.ts +0 -20
- package/lib/features/data-table/data-table.service.d.ts.map +0 -1
- package/lib/features/data-table/table-filter-bar/filter-bar.component.d.ts +0 -25
- package/lib/features/data-table/table-filter-bar/filter-bar.component.d.ts.map +0 -1
- package/lib/features/data-table/table-hidden-columns-bar/hidden-columns-bar.component.d.ts +0 -10
- package/lib/features/data-table/table-hidden-columns-bar/hidden-columns-bar.component.d.ts.map +0 -1
- package/lib/features/data-table/tooltips/os-tooltip.component.d.ts +0 -15
- package/lib/features/data-table/tooltips/os-tooltip.component.d.ts.map +0 -1
- package/lib/features/data-table/tooltips/sdk-tooltip.component.d.ts +0 -15
- package/lib/features/data-table/tooltips/sdk-tooltip.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/boolean/boolean-toggle-input.component.d.ts +0 -19
- package/lib/features/dynamic-widgets/boolean/boolean-toggle-input.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/checkbox-list/checkbox-list-input.component.d.ts +0 -28
- package/lib/features/dynamic-widgets/checkbox-list/checkbox-list-input.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/forwarding-config/forwarding-config.component.d.ts +0 -50
- package/lib/features/dynamic-widgets/forwarding-config/forwarding-config.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/forwarding-config/forwarding-config.service.d.ts +0 -14
- package/lib/features/dynamic-widgets/forwarding-config/forwarding-config.service.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/number/number-input.component.d.ts +0 -23
- package/lib/features/dynamic-widgets/number/number-input.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/object/object.component.d.ts +0 -26
- package/lib/features/dynamic-widgets/object/object.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/password/password-input.component.d.ts +0 -24
- package/lib/features/dynamic-widgets/password/password-input.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/port-ranges/port-ranges.component.d.ts +0 -22
- package/lib/features/dynamic-widgets/port-ranges/port-ranges.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/protocol-address-port/protocol-address-port-input.component.d.ts +0 -60
- package/lib/features/dynamic-widgets/protocol-address-port/protocol-address-port-input.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/selector/selector-input.component.d.ts +0 -30
- package/lib/features/dynamic-widgets/selector/selector-input.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/string/string-input.component.d.ts +0 -27
- package/lib/features/dynamic-widgets/string/string-input.component.d.ts.map +0 -1
- package/lib/features/dynamic-widgets/text-list/text-list-input.component.d.ts +0 -26
- package/lib/features/dynamic-widgets/text-list/text-list-input.component.d.ts.map +0 -1
- package/lib/features/extendable/extendable.component.d.ts +0 -15
- package/lib/features/extendable/extendable.component.d.ts.map +0 -1
- package/lib/features/extendable/extensions-noop.service.d.ts +0 -35
- package/lib/features/extendable/extensions-noop.service.d.ts.map +0 -1
- package/lib/features/header-bar/header-bar.component.d.ts +0 -29
- package/lib/features/header-bar/header-bar.component.d.ts.map +0 -1
- package/lib/features/json-view/json-view.component.d.ts +0 -40
- package/lib/features/json-view/json-view.component.d.ts.map +0 -1
- package/lib/features/list-page-features/list-page-form/list-page-form.component.d.ts +0 -35
- package/lib/features/list-page-features/list-page-form/list-page-form.component.d.ts.map +0 -1
- package/lib/features/list-page-features/list-page-header/list-page-header.component.d.ts +0 -14
- package/lib/features/list-page-features/list-page-header/list-page-header.component.d.ts.map +0 -1
- package/lib/features/loading-indicator/loading-indicator.component.d.ts +0 -11
- package/lib/features/loading-indicator/loading-indicator.component.d.ts.map +0 -1
- package/lib/features/login/login-dialog.component.d.ts +0 -30
- package/lib/features/login/login-dialog.component.d.ts.map +0 -1
- package/lib/features/messaging/growler.component.d.ts +0 -19
- package/lib/features/messaging/growler.component.d.ts.map +0 -1
- package/lib/features/messaging/growler.model.d.ts +0 -8
- package/lib/features/messaging/growler.model.d.ts.map +0 -1
- package/lib/features/messaging/growler.module.d.ts +0 -10
- package/lib/features/messaging/growler.module.d.ts.map +0 -1
- package/lib/features/messaging/growler.service.d.ts +0 -18
- package/lib/features/messaging/growler.service.d.ts.map +0 -1
- package/lib/features/messaging/logger.service.d.ts +0 -27
- package/lib/features/messaging/logger.service.d.ts.map +0 -1
- package/lib/features/multi-action-button/multi-action-button.component.d.ts +0 -13
- package/lib/features/multi-action-button/multi-action-button.component.d.ts.map +0 -1
- package/lib/features/no-items/no-items.component.d.ts +0 -19
- package/lib/features/no-items/no-items.component.d.ts.map +0 -1
- package/lib/features/overrides/overrides.component.d.ts +0 -33
- package/lib/features/overrides/overrides.component.d.ts.map +0 -1
- package/lib/features/overrides/overrides.service.d.ts +0 -18
- package/lib/features/overrides/overrides.service.d.ts.map +0 -1
- package/lib/features/preview-list/preview-list.component.d.ts +0 -34
- package/lib/features/preview-list/preview-list.component.d.ts.map +0 -1
- package/lib/features/preview-selections/preview-selections.component.d.ts +0 -39
- package/lib/features/preview-selections/preview-selections.component.d.ts.map +0 -1
- package/lib/features/progress-meter/progress-meter.component.d.ts +0 -19
- package/lib/features/progress-meter/progress-meter.component.d.ts.map +0 -1
- package/lib/features/progress-wizard/progress-wizard.component.d.ts +0 -31
- package/lib/features/progress-wizard/progress-wizard.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/api-session/api-session-form.component.d.ts +0 -50
- package/lib/features/projectable-forms/api-session/api-session-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/api-session/api-session-form.service.d.ts +0 -27
- package/lib/features/projectable-forms/api-session/api-session-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/auth-policy/auth-policy-form.component.d.ts +0 -74
- package/lib/features/projectable-forms/auth-policy/auth-policy-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/auth-policy/auth-policy-form.service.d.ts +0 -38
- package/lib/features/projectable-forms/auth-policy/auth-policy-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/certificate-authority/certificate-authority-form.component.d.ts +0 -80
- package/lib/features/projectable-forms/certificate-authority/certificate-authority-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/certificate-authority/certificate-authority-form.service.d.ts +0 -37
- package/lib/features/projectable-forms/certificate-authority/certificate-authority-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.component.d.ts +0 -62
- package/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.service.d.ts +0 -28
- package/lib/features/projectable-forms/certificate-authority/verify-certificate/verify-certificate.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/config-type/config-type-form.component.d.ts +0 -63
- package/lib/features/projectable-forms/config-type/config-type-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/config-type/config-type-form.service.d.ts +0 -27
- package/lib/features/projectable-forms/config-type/config-type-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/configuration/configuration-form.component.d.ts +0 -62
- package/lib/features/projectable-forms/configuration/configuration-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/configuration/configuration.service.d.ts +0 -33
- package/lib/features/projectable-forms/configuration/configuration.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/edge-router/edge-router-form.component.d.ts +0 -53
- package/lib/features/projectable-forms/edge-router/edge-router-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/edge-router/edge-router-form.service.d.ts +0 -29
- package/lib/features/projectable-forms/edge-router/edge-router-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/edge-router-policy/edge-router-policy-form.component.d.ts +0 -54
- package/lib/features/projectable-forms/edge-router-policy/edge-router-policy-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/edge-router-policy/edge-router-policy-form.service.d.ts +0 -40
- package/lib/features/projectable-forms/edge-router-policy/edge-router-policy-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/form-field-container/form-field-container.component.d.ts +0 -29
- package/lib/features/projectable-forms/form-field-container/form-field-container.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/form-field-toggle/form-field-toggle.component.d.ts +0 -15
- package/lib/features/projectable-forms/form-field-toggle/form-field-toggle.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/form-header/form-header.component.d.ts +0 -38
- package/lib/features/projectable-forms/form-header/form-header.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/identity/identity-form.component.d.ts +0 -93
- package/lib/features/projectable-forms/identity/identity-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/identity/identity-form.service.d.ts +0 -20
- package/lib/features/projectable-forms/identity/identity-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/jwt-signer/jwt-signer-form.component.d.ts +0 -97
- package/lib/features/projectable-forms/jwt-signer/jwt-signer-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/jwt-signer/jwt-signer-form.service.d.ts +0 -21
- package/lib/features/projectable-forms/jwt-signer/jwt-signer-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/posture-check/posture-check-form.component.d.ts +0 -134
- package/lib/features/projectable-forms/posture-check/posture-check-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/posture-check/posture-check-form.service.d.ts +0 -23
- package/lib/features/projectable-forms/posture-check/posture-check-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/projectable-form.class.d.ts +0 -92
- package/lib/features/projectable-forms/projectable-form.class.d.ts.map +0 -1
- package/lib/features/projectable-forms/service/service-form.component.d.ts +0 -70
- package/lib/features/projectable-forms/service/service-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/service/service-form.service.d.ts +0 -123
- package/lib/features/projectable-forms/service/service-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/service/simple-service/simple-service.component.d.ts +0 -173
- package/lib/features/projectable-forms/service/simple-service/simple-service.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/service-edge-router-policy/service-edge-router-policy-form.component.d.ts +0 -53
- package/lib/features/projectable-forms/service-edge-router-policy/service-edge-router-policy-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/service-edge-router-policy/service-edge-router-policy-form.service.d.ts +0 -38
- package/lib/features/projectable-forms/service-edge-router-policy/service-edge-router-policy-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/service-policy/service-policy-form.component.d.ts +0 -55
- package/lib/features/projectable-forms/service-policy/service-policy-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/service-policy/service-policy-form.service.d.ts +0 -48
- package/lib/features/projectable-forms/service-policy/service-policy-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/session/session-form.component.d.ts +0 -63
- package/lib/features/projectable-forms/session/session-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/session/session-form.service.d.ts +0 -23
- package/lib/features/projectable-forms/session/session-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/terminator/terminator-form.component.d.ts +0 -58
- package/lib/features/projectable-forms/terminator/terminator-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/terminator/terminator-form.service.d.ts +0 -33
- package/lib/features/projectable-forms/terminator/terminator-form.service.d.ts.map +0 -1
- package/lib/features/projectable-forms/transit-router/transit-router-form.component.d.ts +0 -50
- package/lib/features/projectable-forms/transit-router/transit-router-form.component.d.ts.map +0 -1
- package/lib/features/projectable-forms/transit-router/transit-router-form.service.d.ts +0 -27
- package/lib/features/projectable-forms/transit-router/transit-router-form.service.d.ts.map +0 -1
- package/lib/features/qr-code/qr-code.component.d.ts +0 -45
- package/lib/features/qr-code/qr-code.component.d.ts.map +0 -1
- package/lib/features/quick-add/quick-add.component.d.ts +0 -15
- package/lib/features/quick-add/quick-add.component.d.ts.map +0 -1
- package/lib/features/reset-enrollment/reset-enrollment.component.d.ts +0 -27
- package/lib/features/reset-enrollment/reset-enrollment.component.d.ts.map +0 -1
- package/lib/features/reset-enrollment/reset-enrollment.service.d.ts +0 -13
- package/lib/features/reset-enrollment/reset-enrollment.service.d.ts.map +0 -1
- package/lib/features/side-modal/side-modal.component.d.ts +0 -15
- package/lib/features/side-modal/side-modal.component.d.ts.map +0 -1
- package/lib/features/side-navigator/side-navigator.component.d.ts +0 -33
- package/lib/features/side-navigator/side-navigator.component.d.ts.map +0 -1
- package/lib/features/sidebars/side-navbar/side-navbar.component.d.ts +0 -16
- package/lib/features/sidebars/side-navbar/side-navbar.component.d.ts.map +0 -1
- package/lib/features/tag-selector/tag-selector.component.d.ts +0 -59
- package/lib/features/tag-selector/tag-selector.component.d.ts.map +0 -1
- package/lib/features/visualizer/identity-service-path/identity-service-path.component.d.ts +0 -54
- package/lib/features/visualizer/identity-service-path/identity-service-path.component.d.ts.map +0 -1
- package/lib/features/visualizer/identity-service-path/identity-service-path.helper.d.ts +0 -21
- package/lib/features/visualizer/identity-service-path/identity-service-path.helper.d.ts.map +0 -1
- package/lib/features/visualizer/network-visualizer/network-visualizer.component.d.ts +0 -146
- package/lib/features/visualizer/network-visualizer/network-visualizer.component.d.ts.map +0 -1
- package/lib/features/visualizer/network-visualizer/network-visualizer.helper.d.ts +0 -172
- package/lib/features/visualizer/network-visualizer/network-visualizer.helper.d.ts.map +0 -1
- package/lib/features/visualizer/network-visualizer/network-visualizer.treenodeprocessor.d.ts +0 -35
- package/lib/features/visualizer/network-visualizer/network-visualizer.treenodeprocessor.d.ts.map +0 -1
- package/lib/features/visualizer/visualizer-service.class.d.ts +0 -10
- package/lib/features/visualizer/visualizer-service.class.d.ts.map +0 -1
- package/lib/models/api-session.d.ts +0 -18
- package/lib/models/api-session.d.ts.map +0 -1
- package/lib/models/auth-policy.d.ts +0 -8
- package/lib/models/auth-policy.d.ts.map +0 -1
- package/lib/models/certificate-authority.d.ts +0 -14
- package/lib/models/certificate-authority.d.ts.map +0 -1
- package/lib/models/config-type.d.ts +0 -7
- package/lib/models/config-type.d.ts.map +0 -1
- package/lib/models/config.d.ts +0 -7
- package/lib/models/config.d.ts.map +0 -1
- package/lib/models/edge-router-policy.d.ts +0 -8
- package/lib/models/edge-router-policy.d.ts.map +0 -1
- package/lib/models/edge-router.d.ts +0 -10
- package/lib/models/edge-router.d.ts.map +0 -1
- package/lib/models/identity.d.ts +0 -16
- package/lib/models/identity.d.ts.map +0 -1
- package/lib/models/jwt-signer.d.ts +0 -17
- package/lib/models/jwt-signer.d.ts.map +0 -1
- package/lib/models/posture-check.d.ts +0 -17
- package/lib/models/posture-check.d.ts.map +0 -1
- package/lib/models/service-edge-router-policy.d.ts +0 -8
- package/lib/models/service-edge-router-policy.d.ts.map +0 -1
- package/lib/models/service-policy.d.ts +0 -10
- package/lib/models/service-policy.d.ts.map +0 -1
- package/lib/models/service.d.ts +0 -9
- package/lib/models/service.d.ts.map +0 -1
- package/lib/models/session.d.ts +0 -17
- package/lib/models/session.d.ts.map +0 -1
- package/lib/models/terminator.d.ts +0 -11
- package/lib/models/terminator.d.ts.map +0 -1
- package/lib/pages/api-sessions/api-sessions-page.component.d.ts +0 -30
- package/lib/pages/api-sessions/api-sessions-page.component.d.ts.map +0 -1
- package/lib/pages/api-sessions/api-sessions-page.service.d.ts +0 -31
- package/lib/pages/api-sessions/api-sessions-page.service.d.ts.map +0 -1
- package/lib/pages/attributes/attributes.component.d.ts +0 -31
- package/lib/pages/attributes/attributes.component.d.ts.map +0 -1
- package/lib/pages/auth-policies/auth-policies-page.component.d.ts +0 -29
- package/lib/pages/auth-policies/auth-policies-page.component.d.ts.map +0 -1
- package/lib/pages/auth-policies/auth-policies-page.service.d.ts +0 -34
- package/lib/pages/auth-policies/auth-policies-page.service.d.ts.map +0 -1
- package/lib/pages/callback/callback.component.d.ts +0 -22
- package/lib/pages/callback/callback.component.d.ts.map +0 -1
- package/lib/pages/certificate-authorities/certificate-authorities-page.component.d.ts +0 -30
- package/lib/pages/certificate-authorities/certificate-authorities-page.component.d.ts.map +0 -1
- package/lib/pages/certificate-authorities/certificate-authorities-page.service.d.ts +0 -35
- package/lib/pages/certificate-authorities/certificate-authorities-page.service.d.ts.map +0 -1
- package/lib/pages/config-types/config-types-page.component.d.ts +0 -31
- package/lib/pages/config-types/config-types-page.component.d.ts.map +0 -1
- package/lib/pages/config-types/config-types-page.service.d.ts +0 -29
- package/lib/pages/config-types/config-types-page.service.d.ts.map +0 -1
- package/lib/pages/configurations/configurations-page.component.d.ts +0 -30
- package/lib/pages/configurations/configurations-page.component.d.ts.map +0 -1
- package/lib/pages/configurations/configurations-page.service.d.ts +0 -80
- package/lib/pages/configurations/configurations-page.service.d.ts.map +0 -1
- package/lib/pages/edge-router-policies/edge-router-policies-page.component.d.ts +0 -33
- package/lib/pages/edge-router-policies/edge-router-policies-page.component.d.ts.map +0 -1
- package/lib/pages/edge-router-policies/edge-router-policies-page.service.d.ts +0 -63
- package/lib/pages/edge-router-policies/edge-router-policies-page.service.d.ts.map +0 -1
- package/lib/pages/edge-routers/edge-routers-page.component.d.ts +0 -36
- package/lib/pages/edge-routers/edge-routers-page.component.d.ts.map +0 -1
- package/lib/pages/edge-routers/edge-routers-page.service.d.ts +0 -51
- package/lib/pages/edge-routers/edge-routers-page.service.d.ts.map +0 -1
- package/lib/pages/geolocate/geolocate.component.d.ts +0 -32
- package/lib/pages/geolocate/geolocate.component.d.ts.map +0 -1
- package/lib/pages/identities/identities-page.component.d.ts +0 -40
- package/lib/pages/identities/identities-page.component.d.ts.map +0 -1
- package/lib/pages/identities/identities-page.service.d.ts +0 -64
- package/lib/pages/identities/identities-page.service.d.ts.map +0 -1
- package/lib/pages/jwt-signers/jwt-signers-page.component.d.ts +0 -34
- package/lib/pages/jwt-signers/jwt-signers-page.component.d.ts.map +0 -1
- package/lib/pages/jwt-signers/jwt-signers-page.service.d.ts +0 -31
- package/lib/pages/jwt-signers/jwt-signers-page.service.d.ts.map +0 -1
- package/lib/pages/posture-checks/posture-checks-page.component.d.ts +0 -29
- package/lib/pages/posture-checks/posture-checks-page.component.d.ts.map +0 -1
- package/lib/pages/posture-checks/posture-checks-page.service.d.ts +0 -28
- package/lib/pages/posture-checks/posture-checks-page.service.d.ts.map +0 -1
- package/lib/pages/profile/profile.component.d.ts +0 -17
- package/lib/pages/profile/profile.component.d.ts.map +0 -1
- package/lib/pages/service-edge-router-policies/service-edge-router-policies-page.component.d.ts +0 -33
- package/lib/pages/service-edge-router-policies/service-edge-router-policies-page.component.d.ts.map +0 -1
- package/lib/pages/service-edge-router-policies/service-edge-router-policies-page.service.d.ts +0 -57
- package/lib/pages/service-edge-router-policies/service-edge-router-policies-page.service.d.ts.map +0 -1
- package/lib/pages/service-policies/service-policies-page.component.d.ts +0 -34
- package/lib/pages/service-policies/service-policies-page.component.d.ts.map +0 -1
- package/lib/pages/service-policies/service-policies-page.service.d.ts +0 -63
- package/lib/pages/service-policies/service-policies-page.service.d.ts.map +0 -1
- package/lib/pages/services/services-page.component.d.ts +0 -42
- package/lib/pages/services/services-page.component.d.ts.map +0 -1
- package/lib/pages/services/services-page.service.d.ts +0 -69
- package/lib/pages/services/services-page.service.d.ts.map +0 -1
- package/lib/pages/sessions/sessions-page.component.d.ts +0 -30
- package/lib/pages/sessions/sessions-page.component.d.ts.map +0 -1
- package/lib/pages/sessions/sessions-page.service.d.ts +0 -30
- package/lib/pages/sessions/sessions-page.service.d.ts.map +0 -1
- package/lib/pages/settings/settings.component.d.ts +0 -23
- package/lib/pages/settings/settings.component.d.ts.map +0 -1
- package/lib/pages/terminators/terminators-page.component.d.ts +0 -29
- package/lib/pages/terminators/terminators-page.component.d.ts.map +0 -1
- package/lib/pages/terminators/terminators-page.service.d.ts +0 -32
- package/lib/pages/terminators/terminators-page.service.d.ts.map +0 -1
- package/lib/pages/transit-routers/transit-routers-page.component.d.ts +0 -35
- package/lib/pages/transit-routers/transit-routers-page.component.d.ts.map +0 -1
- package/lib/pages/transit-routers/transit-routers-page.service.d.ts +0 -50
- package/lib/pages/transit-routers/transit-routers-page.service.d.ts.map +0 -1
- package/lib/safe.pipe.d.ts +0 -11
- package/lib/safe.pipe.d.ts.map +0 -1
- package/lib/services/auth.service.d.ts +0 -21
- package/lib/services/auth.service.d.ts.map +0 -1
- package/lib/services/console-events.service.d.ts +0 -12
- package/lib/services/console-events.service.d.ts.map +0 -1
- package/lib/services/csv-download.service.d.ts +0 -11
- package/lib/services/csv-download.service.d.ts.map +0 -1
- package/lib/services/deactivate-guard.service.d.ts +0 -14
- package/lib/services/deactivate-guard.service.d.ts.map +0 -1
- package/lib/services/login-service.class.d.ts +0 -30
- package/lib/services/login-service.class.d.ts.map +0 -1
- package/lib/services/node-data.service.d.ts +0 -38
- package/lib/services/node-data.service.d.ts.map +0 -1
- package/lib/services/noop-login.service.d.ts +0 -22
- package/lib/services/noop-login.service.d.ts.map +0 -1
- package/lib/services/schema.service.d.ts +0 -63
- package/lib/services/schema.service.d.ts.map +0 -1
- package/lib/services/settings-service.class.d.ts +0 -36
- package/lib/services/settings-service.class.d.ts.map +0 -1
- package/lib/services/settings.service.d.ts +0 -20
- package/lib/services/settings.service.d.ts.map +0 -1
- package/lib/services/tab-name.service.d.ts +0 -20
- package/lib/services/tab-name.service.d.ts.map +0 -1
- package/lib/services/validation.service.d.ts +0 -20
- package/lib/services/validation.service.d.ts.map +0 -1
- package/lib/services/ziti-controller-data.service.d.ts +0 -36
- package/lib/services/ziti-controller-data.service.d.ts.map +0 -1
- package/lib/services/ziti-data.service.d.ts +0 -49
- package/lib/services/ziti-data.service.d.ts.map +0 -1
- package/lib/services/ziti-domain-controller.service.d.ts +0 -13
- package/lib/services/ziti-domain-controller.service.d.ts.map +0 -1
- package/lib/shared/list-page-component.class.d.ts +0 -57
- package/lib/shared/list-page-component.class.d.ts.map +0 -1
- package/lib/shared/list-page-service.class.d.ts +0 -81
- package/lib/shared/list-page-service.class.d.ts.map +0 -1
- package/lib/urls.d.ts +0 -34
- package/lib/urls.d.ts.map +0 -1
- package/lib/zac-routing.module.d.ts +0 -8
- package/lib/zac-routing.module.d.ts.map +0 -1
- package/lib/ziti-console-lib.module.d.ts +0 -121
- package/lib/ziti-console-lib.module.d.ts.map +0 -1
- package/lib/ziti-console.constants.d.ts +0 -5
- package/lib/ziti-console.constants.d.ts.map +0 -1
- package/openziti-ziti-console-lib.d.ts.map +0 -1
- package/public-api.d.ts +0 -127
- package/public-api.d.ts.map +0 -1
package/esm2022/lib/features/projectable-forms/service/simple-service/simple-service.component.mjs
DELETED
|
@@ -1,1036 +0,0 @@
|
|
|
1
|
-
import { Component, EventEmitter, Inject, Input, Output } from '@angular/core';
|
|
2
|
-
import { ProjectableForm } from "../../projectable-form.class";
|
|
3
|
-
import { SETTINGS_SERVICE } from "../../../../services/settings.service";
|
|
4
|
-
import { SERVICE_EXTENSION_SERVICE } from "../service-form.service";
|
|
5
|
-
import { ZITI_DATA_SERVICE } from "../../../../services/ziti-data.service";
|
|
6
|
-
import { GrowlerModel } from "../../../messaging/growler.model";
|
|
7
|
-
import { CreationSummaryDialogComponent } from "../../../creation-summary-dialog/creation-summary-dialog.component";
|
|
8
|
-
import { isEmpty, isNil, isNaN, unset, cloneDeep, isEqual, set, get } from 'lodash';
|
|
9
|
-
import { ConfirmComponent } from "../../../confirm/confirm.component";
|
|
10
|
-
import { URLS } from "../../../../urls";
|
|
11
|
-
import { BehaviorSubject } from "rxjs";
|
|
12
|
-
import * as i0 from "@angular/core";
|
|
13
|
-
import * as i1 from "../service-form.service";
|
|
14
|
-
import * as i2 from "../../../messaging/growler.service";
|
|
15
|
-
import * as i3 from "@angular/material/dialog";
|
|
16
|
-
import * as i4 from "../../../../services/validation.service";
|
|
17
|
-
import * as i5 from "../../../../pages/services/services-page.service";
|
|
18
|
-
import * as i6 from "@angular/router";
|
|
19
|
-
import * as i7 from "@angular/common";
|
|
20
|
-
import * as i8 from "@angular/forms";
|
|
21
|
-
import * as i9 from "@angular/material/tooltip";
|
|
22
|
-
import * as i10 from "../../form-header/form-header.component";
|
|
23
|
-
import * as i11 from "../../form-field-container/form-field-container.component";
|
|
24
|
-
import * as i12 from "../../../loading-indicator/loading-indicator.component";
|
|
25
|
-
import * as i13 from "../../../tag-selector/tag-selector.component";
|
|
26
|
-
import * as i14 from "../../../../services/settings.service";
|
|
27
|
-
import * as i15 from "../../../../services/ziti-data.service";
|
|
28
|
-
export class SimpleServiceComponent extends ProjectableForm {
|
|
29
|
-
constructor(settingsService, svc, zitiService, growlerService, extService, dialogForm, validationService, servicesPageService, router, route, location) {
|
|
30
|
-
super(growlerService, extService, zitiService, router, route, location, settingsService);
|
|
31
|
-
this.settingsService = settingsService;
|
|
32
|
-
this.svc = svc;
|
|
33
|
-
this.zitiService = zitiService;
|
|
34
|
-
this.dialogForm = dialogForm;
|
|
35
|
-
this.validationService = validationService;
|
|
36
|
-
this.servicesPageService = servicesPageService;
|
|
37
|
-
this.router = router;
|
|
38
|
-
this.route = route;
|
|
39
|
-
this.serviceRoleAttributes = [];
|
|
40
|
-
this.identityRoleAttributes = [];
|
|
41
|
-
this.identityNamedAttributes = [];
|
|
42
|
-
this.showForm = true;
|
|
43
|
-
this.formView = 'simple';
|
|
44
|
-
this.controllerDomain = '';
|
|
45
|
-
this.hostProtocol = 'tcp';
|
|
46
|
-
this.serviceCliCommand = '';
|
|
47
|
-
this.interceptConfigCliCommand = '';
|
|
48
|
-
this.hostConfigCliCommand = '';
|
|
49
|
-
this.dialPolicyCliCommand = '';
|
|
50
|
-
this.bindPolicyCliCommand = '';
|
|
51
|
-
this.serviceApiUrl = '';
|
|
52
|
-
this.interceptConfigApiUrl = '';
|
|
53
|
-
this.hostConfigApiUrl = '';
|
|
54
|
-
this.dialPolicyApiUrl = '';
|
|
55
|
-
this.bindPolicyApiUrl = '';
|
|
56
|
-
this.initServiceApiData = {
|
|
57
|
-
name: "",
|
|
58
|
-
roleAttributes: [],
|
|
59
|
-
configs: [],
|
|
60
|
-
encryptionRequired: true
|
|
61
|
-
};
|
|
62
|
-
this.initInterceptConfigApiData = {
|
|
63
|
-
name: "",
|
|
64
|
-
configTypeId: "g7cIWbcGg",
|
|
65
|
-
data: {
|
|
66
|
-
portRanges: [],
|
|
67
|
-
addresses: [],
|
|
68
|
-
protocols: ['tcp', 'udp']
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
this.initHostConfigApiData = {
|
|
72
|
-
name: '',
|
|
73
|
-
configTypeId: "NH5p4FpGR",
|
|
74
|
-
data: {
|
|
75
|
-
address: "",
|
|
76
|
-
port: undefined,
|
|
77
|
-
forwardProtocol: true,
|
|
78
|
-
allowedProtocols: ['tcp']
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
this.initDialPolicyApiData = {
|
|
82
|
-
name: "",
|
|
83
|
-
type: "Dial",
|
|
84
|
-
semantic: "AnyOf",
|
|
85
|
-
serviceRoles: [],
|
|
86
|
-
identityRoles: []
|
|
87
|
-
};
|
|
88
|
-
this.initBindPolicyApiData = {
|
|
89
|
-
name: "",
|
|
90
|
-
type: "Bind",
|
|
91
|
-
semantic: "AnyOf",
|
|
92
|
-
serviceRoles: [],
|
|
93
|
-
identityRoles: []
|
|
94
|
-
};
|
|
95
|
-
this.dialPolicyNamedAttributes = [];
|
|
96
|
-
this.dialPolicyRoleAttributes = [];
|
|
97
|
-
this.bindPolicyNamedAttributes = [];
|
|
98
|
-
this.bindPolicyRoleAttributes = [];
|
|
99
|
-
this.identitiesNameIdMap = {};
|
|
100
|
-
this.identitiesIdNameMap = {};
|
|
101
|
-
this.sdkOnlyDial = false;
|
|
102
|
-
this.sdkOnlyBind = false;
|
|
103
|
-
this.interceptIncrement = -1;
|
|
104
|
-
this.hostIncrement = -1;
|
|
105
|
-
this.serviceIncrement = -1;
|
|
106
|
-
this.dialIncrement = -1;
|
|
107
|
-
this.bindIncrement = -1;
|
|
108
|
-
this.serviceDataChange = false;
|
|
109
|
-
this.interceptDataChange = false;
|
|
110
|
-
this.hostDataChange = false;
|
|
111
|
-
this.dialDataChange = false;
|
|
112
|
-
this.bindDataChange = false;
|
|
113
|
-
this.identitiesInit = new BehaviorSubject(false);
|
|
114
|
-
this.entitiesInit = false;
|
|
115
|
-
this.multiActions = [];
|
|
116
|
-
this.entityType = 'services';
|
|
117
|
-
this.close = new EventEmitter();
|
|
118
|
-
this.selected = new EventEmitter();
|
|
119
|
-
this.formDataSet = false;
|
|
120
|
-
this.svc.formData = {};
|
|
121
|
-
}
|
|
122
|
-
set formData(data) {
|
|
123
|
-
if (!data?.configs) {
|
|
124
|
-
data.configs = [];
|
|
125
|
-
}
|
|
126
|
-
this.svc.formData = data;
|
|
127
|
-
if (!isEmpty(data?.id)) {
|
|
128
|
-
this.initAssociatedData();
|
|
129
|
-
if (get(this.formData, 'tags.service-type') === 'simple') {
|
|
130
|
-
this.multiActions = [
|
|
131
|
-
{ id: 'convert-to-advanced', label: 'Convert to Advanced', hidden: false }
|
|
132
|
-
];
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
this.multiActions = [];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
this.associatedDataInit = true;
|
|
140
|
-
}
|
|
141
|
-
this.serviceDataSet = true;
|
|
142
|
-
this.checkAllDataInit();
|
|
143
|
-
}
|
|
144
|
-
get formData() {
|
|
145
|
-
return this.svc?.formData;
|
|
146
|
-
}
|
|
147
|
-
set entityId(id) {
|
|
148
|
-
this._entityId = id;
|
|
149
|
-
if (isEmpty(id) || id === 'create') {
|
|
150
|
-
this.serviceDataSet = true;
|
|
151
|
-
this.associatedDataInit = true;
|
|
152
|
-
}
|
|
153
|
-
this.entityIdInit = true;
|
|
154
|
-
this.checkAllDataInit();
|
|
155
|
-
}
|
|
156
|
-
get entityId() {
|
|
157
|
-
return this._entityId;
|
|
158
|
-
}
|
|
159
|
-
ngOnInit() {
|
|
160
|
-
super.ngOnInit();
|
|
161
|
-
this.controllerDomain = this.settingsService?.settings?.selectedEdgeController;
|
|
162
|
-
this.zitiSessionId = this.settingsService?.settings?.session?.id;
|
|
163
|
-
this.initFormData();
|
|
164
|
-
this.getIdentityNamedAttributes();
|
|
165
|
-
}
|
|
166
|
-
initFormData() {
|
|
167
|
-
this.serviceApiUrl = `${this.controllerDomain}/edge/management/v1/services`;
|
|
168
|
-
this.interceptConfigApiUrl = `${this.controllerDomain}/edge/management/v1/configs`;
|
|
169
|
-
this.hostConfigApiUrl = `${this.controllerDomain}/edge/management/v1/configs`;
|
|
170
|
-
this.dialPolicyApiUrl = `${this.controllerDomain}/edge/management/v1/service-policies`;
|
|
171
|
-
this.bindPolicyApiUrl = `${this.controllerDomain}/edge/management/v1/service-policies`;
|
|
172
|
-
this.serviceCliCommand = '';
|
|
173
|
-
this.interceptConfigCliCommand = '';
|
|
174
|
-
this.hostConfigCliCommand = '';
|
|
175
|
-
this.dialPolicyCliCommand = '';
|
|
176
|
-
this.bindPolicyCliCommand = '';
|
|
177
|
-
this.interceptConfigId = '';
|
|
178
|
-
this.hostConfigId = '';
|
|
179
|
-
this.serviceId = '';
|
|
180
|
-
this.sdkOnlyDial = false;
|
|
181
|
-
this.sdkOnlyBind = false;
|
|
182
|
-
this.interceptPort = undefined;
|
|
183
|
-
this.dialPolicyNamedAttributes = [];
|
|
184
|
-
this.dialPolicyRoleAttributes = [];
|
|
185
|
-
this.bindPolicyNamedAttributes = [];
|
|
186
|
-
this.bindPolicyRoleAttributes = [];
|
|
187
|
-
this.serviceApiData = cloneDeep(this.initServiceApiData);
|
|
188
|
-
this.interceptConfigApiData = cloneDeep(this.initInterceptConfigApiData);
|
|
189
|
-
this.hostConfigApiData = cloneDeep(this.initHostConfigApiData);
|
|
190
|
-
this.dialPolicyApiData = cloneDeep(this.initDialPolicyApiData);
|
|
191
|
-
this.bindPolicyApiData = cloneDeep(this.initBindPolicyApiData);
|
|
192
|
-
const serviceRolesPromise = this.servicesPageService.getServiceRoleAttributes().then((result) => {
|
|
193
|
-
this.serviceRoleAttributes = result.data;
|
|
194
|
-
});
|
|
195
|
-
const identityRolesPromise = this.servicesPageService.getIdentityRoleAttributes().then((result) => {
|
|
196
|
-
this.identityRoleAttributes = result.data;
|
|
197
|
-
});
|
|
198
|
-
return Promise.all([serviceRolesPromise, identityRolesPromise]).finally(() => {
|
|
199
|
-
this.formDataSet = true;
|
|
200
|
-
this.checkAllDataInit();
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
initAssociatedData() {
|
|
204
|
-
if (this.entitiesInit) {
|
|
205
|
-
this.dataInit = true;
|
|
206
|
-
this.isLoading = false;
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
this.entitiesInit = true;
|
|
210
|
-
this.serviceApiData = this.svc.formData;
|
|
211
|
-
this.identitiesInit.subscribe((val) => {
|
|
212
|
-
if (val === true) {
|
|
213
|
-
const configsPromise = this.getAssociatedConfigs();
|
|
214
|
-
const policiesPromise = this.getAssocaitedPolicies();
|
|
215
|
-
Promise.all([configsPromise, policiesPromise]).finally(() => {
|
|
216
|
-
this.associatedDataInit = true;
|
|
217
|
-
this.setInitData();
|
|
218
|
-
this.checkAllDataInit();
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
setInitData() {
|
|
224
|
-
this.initServiceApiData = cloneDeep(this.serviceApiData);
|
|
225
|
-
this.initInterceptConfigApiData = cloneDeep(this.interceptConfigApiData);
|
|
226
|
-
this.initHostConfigApiData = cloneDeep(this.hostConfigApiData);
|
|
227
|
-
this.initDialPolicyApiData = cloneDeep(this.dialPolicyApiData);
|
|
228
|
-
this.initBindPolicyApiData = cloneDeep(this.bindPolicyApiData);
|
|
229
|
-
this._dataChange = false;
|
|
230
|
-
}
|
|
231
|
-
getAssociatedConfigs() {
|
|
232
|
-
return this.zitiService.getSubdata('services', this.formData.id, 'configs').then((result) => {
|
|
233
|
-
const associatedConfigs = result.data;
|
|
234
|
-
associatedConfigs.forEach((config) => {
|
|
235
|
-
if (config.configTypeId == this.initInterceptConfigApiData.configTypeId) {
|
|
236
|
-
this.interceptConfigApiData = config;
|
|
237
|
-
const portRange = this.interceptConfigApiData.data.portRanges[0];
|
|
238
|
-
this.interceptPort = portRange?.high;
|
|
239
|
-
}
|
|
240
|
-
else if (config.configTypeId == this.initHostConfigApiData.configTypeId) {
|
|
241
|
-
this.hostConfigApiData = config;
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
getAssocaitedPolicies() {
|
|
247
|
-
return this.zitiService.getSubdata('services', this.formData.id, 'service-policies').then((result) => {
|
|
248
|
-
const associatedServicePolicies = result.data;
|
|
249
|
-
associatedServicePolicies.forEach((policy) => {
|
|
250
|
-
if (policy.type?.toLowerCase() == 'dial') {
|
|
251
|
-
this.dialPolicyApiData = policy;
|
|
252
|
-
const roleAttributes = [];
|
|
253
|
-
const namedAttributes = [];
|
|
254
|
-
policy.identityRoles.forEach((attr) => {
|
|
255
|
-
if (attr.charAt(0) === '#') {
|
|
256
|
-
roleAttributes.push(attr.slice(1));
|
|
257
|
-
}
|
|
258
|
-
else if (attr.charAt(0) === '@') {
|
|
259
|
-
namedAttributes.push(this.identitiesIdNameMap[attr.slice(1)]);
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
this.dialPolicyRoleAttributes = roleAttributes;
|
|
263
|
-
this.dialPolicyNamedAttributes = namedAttributes;
|
|
264
|
-
}
|
|
265
|
-
else if (policy.type?.toLowerCase() == 'bind') {
|
|
266
|
-
const roleAttributes = [];
|
|
267
|
-
const namedAttributes = [];
|
|
268
|
-
policy.identityRoles.forEach((attr) => {
|
|
269
|
-
if (attr.charAt(0) === '#') {
|
|
270
|
-
roleAttributes.push(attr.slice(1));
|
|
271
|
-
}
|
|
272
|
-
else if (attr.charAt(0) === '@') {
|
|
273
|
-
namedAttributes.push(this.identitiesIdNameMap[attr.slice(1)]);
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
this.bindPolicyRoleAttributes = roleAttributes;
|
|
277
|
-
this.bindPolicyNamedAttributes = namedAttributes;
|
|
278
|
-
this.bindPolicyApiData = policy;
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
getIdentityNamedAttributes(filter) {
|
|
284
|
-
const paging = {
|
|
285
|
-
searchOn: 'name',
|
|
286
|
-
filter: filter || '',
|
|
287
|
-
total: 30,
|
|
288
|
-
page: 1,
|
|
289
|
-
sort: 'name',
|
|
290
|
-
order: 'asc'
|
|
291
|
-
};
|
|
292
|
-
const filters = [];
|
|
293
|
-
if (!isEmpty(filter)) {
|
|
294
|
-
filters.push({
|
|
295
|
-
filterName: 'name',
|
|
296
|
-
columnId: 'name',
|
|
297
|
-
value: filter || '%',
|
|
298
|
-
label: '',
|
|
299
|
-
type: 'TEXTINPUT',
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
this.zitiService.get('identities', paging, filters).then((result) => {
|
|
303
|
-
const namedAttributes = result.data.map((identity) => {
|
|
304
|
-
this.identitiesNameIdMap[identity.name] = identity.id;
|
|
305
|
-
this.identitiesIdNameMap[identity.id] = identity.name;
|
|
306
|
-
return identity.name;
|
|
307
|
-
});
|
|
308
|
-
this.identityNamedAttributes = namedAttributes;
|
|
309
|
-
}).finally(() => {
|
|
310
|
-
this.identitiesInit.next(true);
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
checkAllDataInit() {
|
|
314
|
-
if (this.associatedDataInit && this.formDataSet && this.entityIdInit && this.serviceDataSet) {
|
|
315
|
-
this.dataInit = true;
|
|
316
|
-
this.isLoading = false;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
multiActionRequested(action) {
|
|
320
|
-
switch (action.id) {
|
|
321
|
-
case 'save':
|
|
322
|
-
this.save();
|
|
323
|
-
break;
|
|
324
|
-
case 'convert-to-advanced':
|
|
325
|
-
this.convertToAdvanced();
|
|
326
|
-
break;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
headerActionRequested(action) {
|
|
330
|
-
switch (action.name) {
|
|
331
|
-
case 'save':
|
|
332
|
-
this.save();
|
|
333
|
-
break;
|
|
334
|
-
case 'close':
|
|
335
|
-
if (this.isEdit) {
|
|
336
|
-
this.router?.navigateByUrl(URLS.ZITI_SERVICES);
|
|
337
|
-
}
|
|
338
|
-
else {
|
|
339
|
-
this.router?.navigateByUrl(URLS.ZITI_SERVICE_SELECT);
|
|
340
|
-
}
|
|
341
|
-
break;
|
|
342
|
-
case 'toggle-view':
|
|
343
|
-
this.formView = action.data;
|
|
344
|
-
break;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
toggleSdkOnlyDial() {
|
|
348
|
-
this.sdkOnlyDial = !this.sdkOnlyDial;
|
|
349
|
-
}
|
|
350
|
-
toggleSdkOnlyBind() {
|
|
351
|
-
this.sdkOnlyBind = !this.sdkOnlyBind;
|
|
352
|
-
}
|
|
353
|
-
serviceNameChanged(event) {
|
|
354
|
-
this.interceptConfigApiData.name = `${this.serviceApiData.name}-intercept-config`;
|
|
355
|
-
this.hostConfigApiData.name = `${this.serviceApiData.name}-host-config`;
|
|
356
|
-
this.dialPolicyApiData.name = `${this.serviceApiData.name}-dial-policy`;
|
|
357
|
-
this.bindPolicyApiData.name = `${this.serviceApiData.name}-bind-policy`;
|
|
358
|
-
}
|
|
359
|
-
interceptPortChanged($event) {
|
|
360
|
-
if (isNil(this.interceptPort) || isNaN(this.interceptPort)) {
|
|
361
|
-
this.interceptConfigApiData.data.portRanges = [];
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
this.interceptConfigApiData.data.portRanges[0] = {
|
|
365
|
-
high: this.interceptPort,
|
|
366
|
-
low: this.interceptPort
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
hostProtocolsChanged($event) {
|
|
370
|
-
switch (this.hostProtocol) {
|
|
371
|
-
case 'both':
|
|
372
|
-
this.hostConfigApiData.data.allowedProtocols = ['tcp', 'udp'];
|
|
373
|
-
break;
|
|
374
|
-
default:
|
|
375
|
-
this.hostConfigApiData.data.allowedProtocols = [this.hostProtocol];
|
|
376
|
-
break;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
async save(refresh) {
|
|
380
|
-
this.serviceApiData.name = this.serviceApiData.name.trim();
|
|
381
|
-
if (!this.validate()) {
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
const isNewService = isEmpty(this.serviceApiData?.id);
|
|
385
|
-
if (isNewService) {
|
|
386
|
-
const hasConflicts = await this.checkNameConflicts();
|
|
387
|
-
if (hasConflicts) {
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
const summaryData = this.showSummary();
|
|
392
|
-
this.serviceApiData.configs = [];
|
|
393
|
-
const interceptCfgPromise = await this.saveInterceptConfig(summaryData);
|
|
394
|
-
const hostCfgPromise = await this.saveHostConfig(summaryData);
|
|
395
|
-
const servicePromise = await this.saveService(summaryData);
|
|
396
|
-
const dialPolicyPromise = await this.savePolicy(summaryData, 'Dial');
|
|
397
|
-
const bindPolicyPromise = await this.savePolicy(summaryData, 'Bind');
|
|
398
|
-
summaryData?.forEach((entityType) => {
|
|
399
|
-
entityType.entities?.forEach((entity) => {
|
|
400
|
-
if (entity.type === 'services') {
|
|
401
|
-
entity.cliCommand = this.serviceCliCommand;
|
|
402
|
-
entity.apiRequest = this.getServicesApiRequest();
|
|
403
|
-
}
|
|
404
|
-
else if (entity.type === 'configs' && entity.subtype === 'intercept') {
|
|
405
|
-
entity.cliCommand = this.interceptConfigCliCommand;
|
|
406
|
-
entity.apiRequest = this.getInterceptConfigApiRequest();
|
|
407
|
-
}
|
|
408
|
-
else if (entity.type === 'configs' && entity.subtype === 'host') {
|
|
409
|
-
entity.cliCommand = this.hostConfigCliCommand;
|
|
410
|
-
entity.apiRequest = this.getHostConfigApiRequest();
|
|
411
|
-
}
|
|
412
|
-
else if (entity.type === 'service-policies' && entity.subtype === 'dial') {
|
|
413
|
-
entity.cliCommand = this.dialPolicyCliCommand;
|
|
414
|
-
entity.apiRequest = this.getDialApiRequest();
|
|
415
|
-
}
|
|
416
|
-
else if (entity.type === 'service-policies' && entity.subtype === 'bind') {
|
|
417
|
-
entity.cliCommand = this.bindPolicyCliCommand;
|
|
418
|
-
entity.apiRequest = this.getBindApiRequest();
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
showSummary() {
|
|
424
|
-
const interceptSummary = {
|
|
425
|
-
name: this.interceptConfigApiData.name,
|
|
426
|
-
type: 'configs',
|
|
427
|
-
subtype: 'intercept',
|
|
428
|
-
apiData: this.interceptConfigApiData,
|
|
429
|
-
cliCommand: this.interceptConfigCliCommand,
|
|
430
|
-
apiRequest: '',
|
|
431
|
-
apiUrl: this.interceptConfigApiUrl,
|
|
432
|
-
status: 'loading',
|
|
433
|
-
retry: this.saveInterceptConfig.bind(this),
|
|
434
|
-
};
|
|
435
|
-
const hostSummary = {
|
|
436
|
-
name: this.hostConfigApiData.name,
|
|
437
|
-
type: 'configs',
|
|
438
|
-
subtype: 'host',
|
|
439
|
-
apiData: this.hostConfigApiData,
|
|
440
|
-
cliCommand: this.hostConfigCliCommand,
|
|
441
|
-
apiRequest: '',
|
|
442
|
-
apiUrl: this.hostConfigApiUrl,
|
|
443
|
-
status: 'loading',
|
|
444
|
-
retry: this.saveHostConfig.bind(this)
|
|
445
|
-
};
|
|
446
|
-
const summaryData = [
|
|
447
|
-
{
|
|
448
|
-
title: 'Services',
|
|
449
|
-
entities: [
|
|
450
|
-
{
|
|
451
|
-
name: this.serviceApiData.name,
|
|
452
|
-
type: 'services',
|
|
453
|
-
apiData: this.serviceApiData,
|
|
454
|
-
cliCommand: this.serviceCliCommand,
|
|
455
|
-
apiRequest: '',
|
|
456
|
-
apiUrl: this.serviceApiUrl,
|
|
457
|
-
status: 'loading',
|
|
458
|
-
retry: this.saveService.bind(this)
|
|
459
|
-
}
|
|
460
|
-
]
|
|
461
|
-
},
|
|
462
|
-
{
|
|
463
|
-
title: 'Service Policies',
|
|
464
|
-
entities: [
|
|
465
|
-
{
|
|
466
|
-
name: this.dialPolicyApiData.name,
|
|
467
|
-
type: 'service-policies',
|
|
468
|
-
subtype: 'dial',
|
|
469
|
-
apiData: this.dialPolicyApiData,
|
|
470
|
-
cliCommand: this.dialPolicyCliCommand,
|
|
471
|
-
apiRequest: '',
|
|
472
|
-
apiUrl: this.dialPolicyApiUrl,
|
|
473
|
-
status: 'loading',
|
|
474
|
-
retry: (summaryData) => { this.savePolicy(summaryData, 'Dial'); }
|
|
475
|
-
},
|
|
476
|
-
{
|
|
477
|
-
name: this.bindPolicyApiData.name,
|
|
478
|
-
type: 'service-policies',
|
|
479
|
-
subtype: 'bind',
|
|
480
|
-
apiData: this.bindPolicyApiData,
|
|
481
|
-
cliCommand: this.bindPolicyCliCommand,
|
|
482
|
-
apiRequest: '',
|
|
483
|
-
apiUrl: this.bindPolicyApiUrl,
|
|
484
|
-
status: 'loading',
|
|
485
|
-
retry: (summaryData) => { this.savePolicy(summaryData, 'Bind'); }
|
|
486
|
-
}
|
|
487
|
-
]
|
|
488
|
-
}
|
|
489
|
-
];
|
|
490
|
-
if (!this.sdkOnlyDial && !this.sdkOnlyBind) {
|
|
491
|
-
summaryData.splice(0, 0, {
|
|
492
|
-
title: 'Configurations',
|
|
493
|
-
entities: [interceptSummary, hostSummary]
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
else if (!this.sdkOnlyDial) {
|
|
497
|
-
summaryData.splice(0, 0, {
|
|
498
|
-
title: 'Configurations',
|
|
499
|
-
entities: [interceptSummary]
|
|
500
|
-
});
|
|
501
|
-
}
|
|
502
|
-
else if (!this.sdkOnlyBind) {
|
|
503
|
-
summaryData.splice(0, 0, {
|
|
504
|
-
title: 'Configurations',
|
|
505
|
-
entities: [hostSummary]
|
|
506
|
-
});
|
|
507
|
-
}
|
|
508
|
-
const data = {
|
|
509
|
-
summaryData: summaryData,
|
|
510
|
-
isEdit: this.isEdit
|
|
511
|
-
};
|
|
512
|
-
this.dialogRef = this.dialogForm.open(CreationSummaryDialogComponent, {
|
|
513
|
-
data: data,
|
|
514
|
-
autoFocus: false,
|
|
515
|
-
});
|
|
516
|
-
this.dialogRef.afterClosed().subscribe((result) => {
|
|
517
|
-
if (result === 'new') {
|
|
518
|
-
this.initFormData();
|
|
519
|
-
}
|
|
520
|
-
else if (result === 'cancel') {
|
|
521
|
-
/// Do nothing, stay on page
|
|
522
|
-
}
|
|
523
|
-
else {
|
|
524
|
-
this.initDataModels();
|
|
525
|
-
this._dataChange = false;
|
|
526
|
-
this.router?.navigateByUrl(`${this.basePath}`);
|
|
527
|
-
}
|
|
528
|
-
});
|
|
529
|
-
return summaryData;
|
|
530
|
-
}
|
|
531
|
-
async checkNameConflicts() {
|
|
532
|
-
const filter = {
|
|
533
|
-
filterName: 'name',
|
|
534
|
-
columnId: 'name',
|
|
535
|
-
value: this.serviceApiData.name,
|
|
536
|
-
label: '',
|
|
537
|
-
type: 'TEXTINPUT',
|
|
538
|
-
hidden: false,
|
|
539
|
-
verb: '='
|
|
540
|
-
};
|
|
541
|
-
const results = {
|
|
542
|
-
serviceConflict: false,
|
|
543
|
-
interceptConflict: false,
|
|
544
|
-
hostConflict: false,
|
|
545
|
-
dialPolicyConflict: false,
|
|
546
|
-
bindPolicyConflict: false,
|
|
547
|
-
names: []
|
|
548
|
-
};
|
|
549
|
-
const paging = cloneDeep(this.zitiService.DEFAULT_PAGING);
|
|
550
|
-
paging.noSearch = false;
|
|
551
|
-
const serviceProm = this.zitiService.get('services', paging, [filter]).then((result) => {
|
|
552
|
-
if (result.data?.length > 0) {
|
|
553
|
-
results.serviceConflict = true;
|
|
554
|
-
results.names.push(this.serviceApiData.name);
|
|
555
|
-
}
|
|
556
|
-
});
|
|
557
|
-
filter.value = this.interceptConfigApiData.name;
|
|
558
|
-
const interceptProm = this.zitiService.get('configs', paging, [filter]).then((result) => {
|
|
559
|
-
if (result.data?.length > 0) {
|
|
560
|
-
results.interceptConflict = true;
|
|
561
|
-
results.names.push(this.interceptConfigApiData.name);
|
|
562
|
-
}
|
|
563
|
-
});
|
|
564
|
-
filter.value = this.hostConfigApiData.name;
|
|
565
|
-
const hostProm = this.zitiService.get('configs', paging, [filter]).then((result) => {
|
|
566
|
-
if (result.data?.length > 0) {
|
|
567
|
-
results.hostConflict = true;
|
|
568
|
-
results.names.push(this.hostConfigApiData.name);
|
|
569
|
-
}
|
|
570
|
-
});
|
|
571
|
-
filter.value = this.dialPolicyApiData.name;
|
|
572
|
-
const dialProm = this.zitiService.get('service-policies', paging, [filter]).then((result) => {
|
|
573
|
-
if (result.data?.length > 0) {
|
|
574
|
-
results.dialPolicyConflict = true;
|
|
575
|
-
results.names.push(this.dialPolicyApiData.name);
|
|
576
|
-
}
|
|
577
|
-
});
|
|
578
|
-
filter.value = this.bindPolicyApiData.name;
|
|
579
|
-
const bindProm = this.zitiService.get('service-policies', paging, [filter]).then((result) => {
|
|
580
|
-
if (result.data?.length > 0) {
|
|
581
|
-
results.bindPolicyConflict = true;
|
|
582
|
-
results.names.push(this.bindPolicyApiData.name);
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
return Promise.all([serviceProm, interceptProm, hostProm, dialProm, bindProm]).then(() => {
|
|
586
|
-
let hasConflict = results.names.length > 0;
|
|
587
|
-
if (hasConflict) {
|
|
588
|
-
this.errors.name = true;
|
|
589
|
-
this.showConflictWarning(results);
|
|
590
|
-
}
|
|
591
|
-
return hasConflict;
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
showConflictWarning(conflictData) {
|
|
595
|
-
const data = {
|
|
596
|
-
appendId: 'SimpleServiceConflicts',
|
|
597
|
-
title: 'Name Conflict',
|
|
598
|
-
message: `The name you have entered has conflicts for the following entities`,
|
|
599
|
-
bulletList: conflictData.names,
|
|
600
|
-
submessage: `Please update the entered name and try again.`,
|
|
601
|
-
confirmLabel: 'Return',
|
|
602
|
-
showCancelLink: false,
|
|
603
|
-
imageUrl: '../../assets/svgs/Growl_Error.svg'
|
|
604
|
-
};
|
|
605
|
-
this.dialogRef = this.dialogForm.open(ConfirmComponent, {
|
|
606
|
-
data: data,
|
|
607
|
-
autoFocus: false,
|
|
608
|
-
});
|
|
609
|
-
this.dialogRef.afterClosed(() => {
|
|
610
|
-
this.nameFieldInput.nativeElement.focus();
|
|
611
|
-
});
|
|
612
|
-
}
|
|
613
|
-
async saveInterceptConfig(summaryData) {
|
|
614
|
-
const isNewConfig = isEmpty(this.interceptConfigApiData?.id);
|
|
615
|
-
// Conditional Deletion (Identical Logic)
|
|
616
|
-
if (this.sdkOnlyDial && !isNewConfig) {
|
|
617
|
-
return this.zitiService.delete('configs', this.interceptConfigApiData.id);
|
|
618
|
-
}
|
|
619
|
-
else if (this.sdkOnlyDial && isNewConfig) {
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
// Use the Helper Function
|
|
623
|
-
const { status } = await this.saveConfig(this.interceptConfigApiData, 'interceptIncrement', 'interceptConfigId', 'interceptConfigCliCommand');
|
|
624
|
-
// Apply final status logic
|
|
625
|
-
summaryData[0].entities[0].status = status;
|
|
626
|
-
}
|
|
627
|
-
async saveHostConfig(summaryData) {
|
|
628
|
-
const isNewConfig = isEmpty(this.hostConfigApiData?.id);
|
|
629
|
-
// Conditional Deletion (Identical Logic)
|
|
630
|
-
if (this.sdkOnlyDial && !isNewConfig) {
|
|
631
|
-
return this.zitiService.delete('configs', this.hostConfigApiData.id);
|
|
632
|
-
}
|
|
633
|
-
else if (this.sdkOnlyDial && isNewConfig) {
|
|
634
|
-
return;
|
|
635
|
-
}
|
|
636
|
-
// Use the Helper Function
|
|
637
|
-
const { status, configApiData } = await this.saveConfig(this.hostConfigApiData, 'hostIncrement', 'hostConfigId', 'hostConfigCliCommand');
|
|
638
|
-
// Apply final status logic (slightly different than intercept)
|
|
639
|
-
if (this.sdkOnlyDial) {
|
|
640
|
-
summaryData[0].entities[0].status = status;
|
|
641
|
-
summaryData[0].entities[0].apiData = configApiData;
|
|
642
|
-
}
|
|
643
|
-
else {
|
|
644
|
-
summaryData[0].entities[1].status = status;
|
|
645
|
-
summaryData[0].entities[0].apiData = configApiData;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
async saveConfig(configApiData, // e.g., this.interceptConfigApiData
|
|
649
|
-
incrementer, // The name of the incrementer property ('interceptIncrement' or 'hostIncrement')
|
|
650
|
-
configIdProp, // The name of the ID property ('interceptConfigId' or 'hostConfigId')
|
|
651
|
-
cliCommandProp // The name of the CLI command property ('interceptConfigCliCommand' or 'hostConfigCliCommand')
|
|
652
|
-
) {
|
|
653
|
-
const isNewConfig = isEmpty(configApiData?.id);
|
|
654
|
-
const incrementValue = this[incrementer]; // Get current increment value
|
|
655
|
-
let status;
|
|
656
|
-
let configResult;
|
|
657
|
-
if (isNewConfig) {
|
|
658
|
-
this[incrementer] = incrementValue + 1; // Increment for naming
|
|
659
|
-
let postFix = '';
|
|
660
|
-
if (this[incrementer] > 0) {
|
|
661
|
-
postFix = '_' + this[incrementer];
|
|
662
|
-
}
|
|
663
|
-
configApiData.name = configApiData.name + postFix;
|
|
664
|
-
configResult = await this.saveEntity('configs', configApiData).catch((result) => result);
|
|
665
|
-
}
|
|
666
|
-
else {
|
|
667
|
-
configResult = await this.updateEntity('configs', configApiData).catch((result) => result);
|
|
668
|
-
}
|
|
669
|
-
if (configResult.error) {
|
|
670
|
-
status = 'error';
|
|
671
|
-
}
|
|
672
|
-
else {
|
|
673
|
-
// Set the config ID property dynamically (e.g., this.interceptConfigId)
|
|
674
|
-
this[configIdProp] = configApiData.id || configResult.id || configResult.data.id;
|
|
675
|
-
// Add the new config ID to serviceApiData (assuming serviceApiData is accessible via 'this')
|
|
676
|
-
this.serviceApiData.configs.push(this[configIdProp]);
|
|
677
|
-
// Set the CLI command dynamically
|
|
678
|
-
this[cliCommandProp] = `ziti edge create config '${configApiData.name}' '${configApiData.configTypeId}' '${JSON.stringify(configApiData.data)}'`;
|
|
679
|
-
status = 'done';
|
|
680
|
-
this[incrementer] = -1; // Reset incrementer
|
|
681
|
-
}
|
|
682
|
-
return { status, configResult, configApiData };
|
|
683
|
-
}
|
|
684
|
-
async saveService(summaryData) {
|
|
685
|
-
const isNewService = isEmpty(this.serviceApiData?.id);
|
|
686
|
-
let serviceResult;
|
|
687
|
-
if (isNewService) {
|
|
688
|
-
this.serviceIncrement++;
|
|
689
|
-
let postFix = '';
|
|
690
|
-
if (this.serviceIncrement > 0) {
|
|
691
|
-
postFix = '_' + this.serviceIncrement;
|
|
692
|
-
}
|
|
693
|
-
this.serviceApiData.name = this.serviceApiData.name + postFix;
|
|
694
|
-
set(this.serviceApiData, 'tags.service-type', 'simple');
|
|
695
|
-
serviceResult = await this.saveEntity('services', this.serviceApiData).catch((result) => {
|
|
696
|
-
return result;
|
|
697
|
-
});
|
|
698
|
-
}
|
|
699
|
-
else {
|
|
700
|
-
serviceResult = await this.updateEntity('services', this.serviceApiData).catch((result) => {
|
|
701
|
-
return result;
|
|
702
|
-
});
|
|
703
|
-
}
|
|
704
|
-
let serviceStatus;
|
|
705
|
-
if (serviceResult.error) {
|
|
706
|
-
serviceStatus = 'error';
|
|
707
|
-
}
|
|
708
|
-
else {
|
|
709
|
-
this.serviceId = this.serviceApiData.id ? this.serviceApiData.id : (serviceResult.id ? serviceResult.id : serviceResult.data.id);
|
|
710
|
-
serviceStatus = 'done';
|
|
711
|
-
let cliConfigIds = '';
|
|
712
|
-
if (!this.sdkOnlyDial && !this.sdkOnlyBind) {
|
|
713
|
-
cliConfigIds = `--configs '${this.interceptConfigId},${this.hostConfigId}'`;
|
|
714
|
-
}
|
|
715
|
-
else if (!this.sdkOnlyBind && this.sdkOnlyBind) {
|
|
716
|
-
cliConfigIds = `--configs '${this.interceptConfigId}'`;
|
|
717
|
-
}
|
|
718
|
-
else if (this.sdkOnlyBind && !this.sdkOnlyBind) {
|
|
719
|
-
cliConfigIds = `--configs '${this.interceptConfigId}'`;
|
|
720
|
-
}
|
|
721
|
-
this.serviceCliCommand = `ziti edge create service '${this.serviceApiData.name}' ${cliConfigIds}`;
|
|
722
|
-
this.serviceIncrement = -1;
|
|
723
|
-
}
|
|
724
|
-
const summaryIndex = (this.sdkOnlyDial && this.sdkOnlyBind) ? 0 : 1;
|
|
725
|
-
summaryData[summaryIndex].entities[0].status = serviceStatus;
|
|
726
|
-
}
|
|
727
|
-
async savePolicy(summaryData, type = 'Dial') {
|
|
728
|
-
const isNewPolicy = isEmpty(this.serviceApiData?.id);
|
|
729
|
-
let policyApiData, policyResult, roleAttributes, namedAttributes;
|
|
730
|
-
let cliRoles = '';
|
|
731
|
-
let status = '';
|
|
732
|
-
if (isNewPolicy) {
|
|
733
|
-
if (type === 'Dial') {
|
|
734
|
-
this.dialIncrement++;
|
|
735
|
-
let postFix = '';
|
|
736
|
-
if (this.dialIncrement > 0) {
|
|
737
|
-
postFix = '_' + this.dialIncrement;
|
|
738
|
-
}
|
|
739
|
-
this.dialPolicyApiData.name = this.dialPolicyApiData.name + postFix;
|
|
740
|
-
policyApiData = this.dialPolicyApiData;
|
|
741
|
-
roleAttributes = this.dialPolicyRoleAttributes;
|
|
742
|
-
namedAttributes = this.dialPolicyNamedAttributes;
|
|
743
|
-
}
|
|
744
|
-
else {
|
|
745
|
-
this.bindIncrement++;
|
|
746
|
-
let postFix = '';
|
|
747
|
-
if (this.bindIncrement > 0) {
|
|
748
|
-
postFix = '_' + this.bindIncrement;
|
|
749
|
-
}
|
|
750
|
-
this.bindPolicyApiData.name = this.bindPolicyApiData.name + postFix;
|
|
751
|
-
policyApiData = this.bindPolicyApiData;
|
|
752
|
-
roleAttributes = this.bindPolicyRoleAttributes;
|
|
753
|
-
namedAttributes = this.bindPolicyNamedAttributes;
|
|
754
|
-
}
|
|
755
|
-
policyApiData.serviceRoles = [`@${this.serviceId}`];
|
|
756
|
-
policyApiData.identityRoles = namedAttributes.map((name) => {
|
|
757
|
-
cliRoles += '@' + this.identitiesNameIdMap[name] + ',';
|
|
758
|
-
return '@' + this.identitiesNameIdMap[name];
|
|
759
|
-
});
|
|
760
|
-
policyApiData.identityRoles = [...policyApiData.identityRoles, ...roleAttributes.map((role) => {
|
|
761
|
-
cliRoles += '#' + role + ',';
|
|
762
|
-
return '#' + role;
|
|
763
|
-
})];
|
|
764
|
-
cliRoles = cliRoles.slice(0, -1);
|
|
765
|
-
policyResult = await this.saveEntity('service-policies', policyApiData).catch((result) => {
|
|
766
|
-
return result;
|
|
767
|
-
});
|
|
768
|
-
}
|
|
769
|
-
else {
|
|
770
|
-
if (type === 'Dial') {
|
|
771
|
-
policyApiData = this.dialPolicyApiData;
|
|
772
|
-
roleAttributes = this.dialPolicyRoleAttributes;
|
|
773
|
-
namedAttributes = this.dialPolicyNamedAttributes;
|
|
774
|
-
}
|
|
775
|
-
else {
|
|
776
|
-
policyApiData = this.bindPolicyApiData;
|
|
777
|
-
roleAttributes = this.bindPolicyRoleAttributes;
|
|
778
|
-
namedAttributes = this.bindPolicyNamedAttributes;
|
|
779
|
-
}
|
|
780
|
-
policyApiData.serviceRoles = [`@${this.serviceId}`];
|
|
781
|
-
policyApiData.identityRoles = namedAttributes.map((name) => {
|
|
782
|
-
cliRoles += '@' + this.identitiesNameIdMap[name] + ',';
|
|
783
|
-
return '@' + this.identitiesNameIdMap[name];
|
|
784
|
-
});
|
|
785
|
-
policyApiData.identityRoles = [...policyApiData.identityRoles, ...roleAttributes.map((role) => {
|
|
786
|
-
cliRoles += '#' + role + ',';
|
|
787
|
-
return '#' + role;
|
|
788
|
-
})];
|
|
789
|
-
cliRoles = cliRoles.slice(0, -1);
|
|
790
|
-
policyResult = await this.updateEntity('service-policies', policyApiData).catch((result) => {
|
|
791
|
-
return result;
|
|
792
|
-
});
|
|
793
|
-
}
|
|
794
|
-
if (policyResult.error) {
|
|
795
|
-
status = 'error';
|
|
796
|
-
}
|
|
797
|
-
else {
|
|
798
|
-
status = 'done';
|
|
799
|
-
}
|
|
800
|
-
const summaryIndex = (this.sdkOnlyDial && this.sdkOnlyBind) ? 1 : 2;
|
|
801
|
-
const entityIndex = type === 'Dial' ? 0 : 1;
|
|
802
|
-
summaryData[summaryIndex].entities[entityIndex].status = status;
|
|
803
|
-
const cliCommand = `ziti edge create service-policy '${policyApiData.name}' ${type} --semantic AnyOf --service-roles '@${this.serviceId}' --identity-roles '${cliRoles}'`;
|
|
804
|
-
if (type === 'Dial') {
|
|
805
|
-
this.dialPolicyCliCommand = cliCommand;
|
|
806
|
-
if (status === 'done') {
|
|
807
|
-
this.dialIncrement = -1;
|
|
808
|
-
}
|
|
809
|
-
else {
|
|
810
|
-
this.bindIncrement = -1;
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
else {
|
|
814
|
-
this.bindPolicyCliCommand = cliCommand;
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
saveEntity(type, data) {
|
|
818
|
-
return this.zitiService.post(type, data, true);
|
|
819
|
-
}
|
|
820
|
-
updateEntity(type, data) {
|
|
821
|
-
return this.zitiService.patch(type, data, data.id, true);
|
|
822
|
-
}
|
|
823
|
-
validate() {
|
|
824
|
-
this.errors = {};
|
|
825
|
-
this.validateServiceName();
|
|
826
|
-
this.validateInterceptAddress();
|
|
827
|
-
this.validateInterceptPort();
|
|
828
|
-
this.validateHostAddress();
|
|
829
|
-
this.validateHostPort();
|
|
830
|
-
this.validateDialIdentities();
|
|
831
|
-
this.validateBindIdentities();
|
|
832
|
-
return isEmpty(this.errors);
|
|
833
|
-
}
|
|
834
|
-
validateServiceName() {
|
|
835
|
-
if (isEmpty(this.serviceApiData.name)) {
|
|
836
|
-
this.errors.name = true;
|
|
837
|
-
}
|
|
838
|
-
else {
|
|
839
|
-
unset(this.errors, 'name');
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
validateInterceptAddress() {
|
|
843
|
-
if (this.sdkOnlyDial) {
|
|
844
|
-
unset(this.errors, 'interceptAddress');
|
|
845
|
-
unset(this.errors, 'interceptAddressFormat');
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
if (isEmpty(this.interceptConfigApiData.data.addresses) || isEmpty(this.interceptConfigApiData.data.addresses[0])) {
|
|
849
|
-
this.errors.interceptAddress = true;
|
|
850
|
-
}
|
|
851
|
-
else if (!this.validationService.isValidInterceptHost(this.interceptConfigApiData.data.addresses[0])) {
|
|
852
|
-
this.errors.interceptAddress = true;
|
|
853
|
-
this.errors.interceptAddressFormat = true;
|
|
854
|
-
}
|
|
855
|
-
else {
|
|
856
|
-
unset(this.errors, 'interceptAddress');
|
|
857
|
-
unset(this.errors, 'interceptAddressFormat');
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
validateInterceptPort() {
|
|
861
|
-
if (this.sdkOnlyDial) {
|
|
862
|
-
unset(this.errors, 'interceptPort');
|
|
863
|
-
return;
|
|
864
|
-
}
|
|
865
|
-
if (isEmpty(this.interceptConfigApiData.data.portRanges)) {
|
|
866
|
-
this.errors.interceptPort = true;
|
|
867
|
-
}
|
|
868
|
-
else if (this.validationService.validatePortRanges(this.interceptConfigApiData.data.portRanges)) {
|
|
869
|
-
this.errors.interceptPort = true;
|
|
870
|
-
}
|
|
871
|
-
else {
|
|
872
|
-
unset(this.errors, 'interceptPort');
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
validateHostAddress() {
|
|
876
|
-
if (!this.sdkOnlyBind && isEmpty(this.hostConfigApiData.data.address)) {
|
|
877
|
-
this.errors.hostAddress = true;
|
|
878
|
-
}
|
|
879
|
-
else {
|
|
880
|
-
unset(this.errors, 'hostAddress');
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
validateHostPort() {
|
|
884
|
-
if (this.sdkOnlyBind) {
|
|
885
|
-
unset(this.errors, 'hostPort');
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
if (isNil(this.hostConfigApiData.data.port) || isNaN(this.hostConfigApiData.data.port)) {
|
|
889
|
-
this.errors.hostPort = true;
|
|
890
|
-
}
|
|
891
|
-
else if (!this.validationService.isValidPort(this.hostConfigApiData.data.port)) {
|
|
892
|
-
this.errors.hostPort = true;
|
|
893
|
-
}
|
|
894
|
-
else {
|
|
895
|
-
unset(this.errors, 'hostPort');
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
validateDialIdentities() {
|
|
899
|
-
if (isEmpty([...this.dialPolicyNamedAttributes, ...this.dialPolicyRoleAttributes])) {
|
|
900
|
-
this.errors.dialIdentities = true;
|
|
901
|
-
}
|
|
902
|
-
else {
|
|
903
|
-
unset(this.errors, 'dialIdentities');
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
validateBindIdentities() {
|
|
907
|
-
if (isEmpty([...this.bindPolicyNamedAttributes, ...this.bindPolicyRoleAttributes])) {
|
|
908
|
-
this.errors.bindIdentities = true;
|
|
909
|
-
}
|
|
910
|
-
else {
|
|
911
|
-
unset(this.errors, 'bindIdentities');
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
getServicesApiRequest() {
|
|
915
|
-
return `curl '${this.controllerDomain}/edge/management/v1/services' \\
|
|
916
|
-
-H 'accept: application/json, text/plain, */*' \\
|
|
917
|
-
-H 'content-type: application/json' \\
|
|
918
|
-
-H 'zt-session: ${this.zitiSessionId}' \\
|
|
919
|
-
--data-raw '${JSON.stringify(this.serviceApiData)}' \\`;
|
|
920
|
-
}
|
|
921
|
-
getInterceptConfigApiRequest() {
|
|
922
|
-
return `curl '${this.controllerDomain}/edge/management/v1/configs' \\
|
|
923
|
-
-H 'accept: application/json, text/plain, */*' \\
|
|
924
|
-
-H 'content-type: application/json' \\
|
|
925
|
-
-H 'zt-session: ${this.zitiSessionId}' \\
|
|
926
|
-
--data-raw '${JSON.stringify(this.interceptConfigApiData)}' \\`;
|
|
927
|
-
}
|
|
928
|
-
getHostConfigApiRequest() {
|
|
929
|
-
return `curl '${this.controllerDomain}/edge/management/v1/configs' \\
|
|
930
|
-
-H 'accept: application/json, text/plain, */*' \\
|
|
931
|
-
-H 'content-type: application/json' \\
|
|
932
|
-
-H 'zt-session: ${this.zitiSessionId}' \\
|
|
933
|
-
--data-raw '${JSON.stringify(this.hostConfigApiData)}' \\`;
|
|
934
|
-
}
|
|
935
|
-
getDialApiRequest() {
|
|
936
|
-
return `curl '${this.controllerDomain}/edge/management/v1/service-policies' \\
|
|
937
|
-
-H 'accept: application/json, text/plain, */*' \\
|
|
938
|
-
-H 'content-type: application/json' \\
|
|
939
|
-
-H 'zt-session: ${this.zitiSessionId}' \\
|
|
940
|
-
--data-raw '${JSON.stringify(this.dialPolicyApiData)}' \\`;
|
|
941
|
-
}
|
|
942
|
-
getBindApiRequest() {
|
|
943
|
-
return `curl '${this.controllerDomain}/edge/management/v1/service-policies' \\
|
|
944
|
-
-H 'accept: application/json, text/plain, */*' \\
|
|
945
|
-
-H 'content-type: application/json' \\
|
|
946
|
-
-H 'zt-session: ${this.zitiSessionId}' \\
|
|
947
|
-
--data-raw '${JSON.stringify(this.bindPolicyApiData)}' \\`;
|
|
948
|
-
}
|
|
949
|
-
initDataModels() {
|
|
950
|
-
this.serviceApiData = this.initServiceApiData;
|
|
951
|
-
this.interceptConfigApiData.data = this.initInterceptConfigApiData.data;
|
|
952
|
-
this.hostConfigApiData.data = this.initHostConfigApiData.data;
|
|
953
|
-
this.dialPolicyApiData = this.initDialPolicyApiData;
|
|
954
|
-
this.bindPolicyApiData = this.initBindPolicyApiData;
|
|
955
|
-
}
|
|
956
|
-
convertToAdvanced() {
|
|
957
|
-
const data = {
|
|
958
|
-
appendId: 'ConvertSimpleService',
|
|
959
|
-
title: 'Convert Service',
|
|
960
|
-
message: `Are you sure you would like to convert this simple service to an advanced service? This change cannot be undone.`,
|
|
961
|
-
bulletList: [],
|
|
962
|
-
confirmLabel: 'Yes',
|
|
963
|
-
cancelLabel: 'Oops, no get me out of here',
|
|
964
|
-
imageUrl: '../../assets/svgs/Growl_Warning.svg',
|
|
965
|
-
showCancelLink: true
|
|
966
|
-
};
|
|
967
|
-
this.dialogRef = this.dialogForm.open(ConfirmComponent, {
|
|
968
|
-
data: data,
|
|
969
|
-
autoFocus: false,
|
|
970
|
-
});
|
|
971
|
-
this.dialogRef.afterClosed().subscribe((result) => {
|
|
972
|
-
if (result?.confirmed) {
|
|
973
|
-
this.serviceApiData.tags['service-type'] = 'advanced';
|
|
974
|
-
this.updateEntity('services', this.serviceApiData)
|
|
975
|
-
.then(() => {
|
|
976
|
-
const growlerData = new GrowlerModel('success', 'Success', `Service Updated`, `Successfully converted ${this.serviceApiData.name} to an advanced service.`);
|
|
977
|
-
this.growlerService.show(growlerData);
|
|
978
|
-
this.setInitData();
|
|
979
|
-
this.router.navigate([URLS.ZITI_ADVANCED_SERVICE + '/' + this.serviceApiData.id]);
|
|
980
|
-
})
|
|
981
|
-
.catch((result) => {
|
|
982
|
-
const growlerData = new GrowlerModel('error', 'Error', `Failed to Update Service`, `Unable to convert ${this.serviceApiData.name} to an advanced service.`);
|
|
983
|
-
this.growlerService.show(growlerData);
|
|
984
|
-
});
|
|
985
|
-
}
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
checkDataChange() {
|
|
989
|
-
const serviceDataChange = !isEqual(this.initServiceApiData, this.serviceApiData);
|
|
990
|
-
const interceptDataChange = !isEqual(this.initInterceptConfigApiData.data, this.interceptConfigApiData.data);
|
|
991
|
-
const hostDataChange = !isEqual(this.initHostConfigApiData.data, this.hostConfigApiData.data);
|
|
992
|
-
const dialDataChange = !isEqual(this.initDialPolicyApiData, this.dialPolicyApiData);
|
|
993
|
-
const bindDataChange = !isEqual(this.initBindPolicyApiData, this.bindPolicyApiData);
|
|
994
|
-
const dataChange = serviceDataChange !== this.serviceDataChange || interceptDataChange !== this.interceptDataChange || hostDataChange !== this.hostDataChange ||
|
|
995
|
-
dialDataChange !== this.dialDataChange || bindDataChange !== this.bindDataChange;
|
|
996
|
-
if (dataChange) {
|
|
997
|
-
this.serviceDataChange = serviceDataChange;
|
|
998
|
-
this.interceptDataChange = interceptDataChange;
|
|
999
|
-
this.hostDataChange = hostDataChange;
|
|
1000
|
-
this.dialDataChange = dialDataChange;
|
|
1001
|
-
this.bindDataChange = bindDataChange;
|
|
1002
|
-
this.dataChange.emit(dataChange);
|
|
1003
|
-
}
|
|
1004
|
-
this._dataChange = serviceDataChange || interceptDataChange || hostDataChange || dialDataChange || bindDataChange;
|
|
1005
|
-
}
|
|
1006
|
-
clear() {
|
|
1007
|
-
}
|
|
1008
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SimpleServiceComponent, deps: [{ token: SETTINGS_SERVICE }, { token: i1.ServiceFormService }, { token: ZITI_DATA_SERVICE }, { token: i2.GrowlerService }, { token: SERVICE_EXTENSION_SERVICE }, { token: i3.MatDialog }, { token: i4.ValidationService }, { token: i5.ServicesPageService }, { token: i6.Router }, { token: i6.ActivatedRoute }, { token: i7.Location }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1009
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SimpleServiceComponent, selector: "lib-simple-service", inputs: { serviceRoleAttributes: "serviceRoleAttributes", identityRoleAttributes: "identityRoleAttributes", identityNamedAttributes: "identityNamedAttributes", formData: "formData" }, outputs: { close: "close", selected: "selected" }, usesInheritance: true, ngImport: i0, template: "<div class=\"projectable-form-wrapper simple-service-wrapper\"\n (keyup.enter)=\"save($event)\"\n (keyup.escape)=\"closeModal(true, false, 'cards', $event)\"\n tabindex=\"0\"\n [class.projectable-form-hidden]=\"!dataInit\"\n>\n <lib-form-header\n [data]=\"formData\"\n [title]=\"isEdit ? 'Edit Simple Service' : 'Create a Simple Service'\"\n [actionButtonText]=\"'Save'\"\n [multiActions]=\"multiActions\"\n (actionRequested)=\"headerActionRequested($event)\"\n (multiActionRequested)=\"multiActionRequested($event)\"\n [(formView)]=\"formView\"\n [moreActions]=\"moreActions\"\n [class.is-scrolled]=\"isScrolled\"\n ></lib-form-header>\n\n <div class=\"simple-service-form-container projectable-form-container\" #formContainer>\n <div class=\"form-group-column three-fifths\" *ngIf=\"showForm\">\n <div id=\"InlineServiceArea\" class=\"anyadd\">\n <div class=\"simple-service-inputs\">\n <lib-form-field-container [title]=\"'Service Details'\">\n <div class=\"form-field-input-group service-group\">\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">Service Name</span>\n </div>\n <input\n class=\"form-field-input\"\n placeholder=\"Name this service\"\n autofocus\n #nameFieldInput\n [ngClass]=\"{error: errors.name}\"\n [(ngModel)]=\"serviceApiData.name\"\n (keyup)=\"serviceNameChanged($event)\"\n (change)=\"validateServiceName()\"\n />\n </div>\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">SELECT OR CREATE SERVICE ATTRIBUTES</span>\n </div>\n <lib-tag-selector\n [(selectedRoleAttributes)]=\"serviceApiData.roleAttributes\"\n [availableRoleAttributes]=\"serviceRoleAttributes\"\n [placeholder]=\"'Add attributes to group services'\"\n ></lib-tag-selector>\n </div>\n </div>\n </lib-form-field-container>\n </div>\n </div>\n </div>\n <div class=\"simple-service-center-content\" *ngIf=\"showForm\">\n <div class=\"form-group-row\">\n <lib-form-field-container\n [title]=\"'ACCESSING CONFIGURATION'\"\n [contentStyle]=\"'z-index: 10001'\"\n [helpText]=\"'How will client applications use this service? Specify an address and port, or use the "SDK Only" toggle for an application embedded configuration.'\"\n >\n <div class=\"form-field-input-group accessing-group\">\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">What identities can access this service?</span>\n </div>\n <lib-tag-selector\n [(selectedNamedAttributes)]=\"dialPolicyNamedAttributes\"\n [(selectedRoleAttributes)]=\"dialPolicyRoleAttributes\"\n [availableNamedAttributes]=\"identityNamedAttributes\"\n [availableRoleAttributes]=\"identityRoleAttributes\"\n [placeholder]=\"'Select identity attributes to grant access'\"\n [hasError]=\"errors.dialIdentities\"\n (selectedNamedAttributesChange)=\"validateDialIdentities()\"\n (selectedRoleAttributesChange)=\"validateDialIdentities()\"\n (filterChange)=\"getIdentityNamedAttributes($event)\"\n ></lib-tag-selector>\n </div>\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">How will the service be accessed?</span>\n </div>\n <div class=\"grid addressPort\">\n <div class=\"config-item-container\">\n <span class=\"config-item-label\">SDK ONLY</span>\n <div\n class=\"sdk-toggle form-field-toggle\"\n >\n <div class=\"switchGrid\">\n <div>\n <div\n (click)=\"toggleSdkOnlyDial()\"\n [ngClass]=\"{ on: sdkOnlyDial }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!sdkOnlyDial\" class=\"on-label\">YES</span>\n <span [hidden]=\"sdkOnlyDial\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"config-item-container\" [ngClass]=\"{disabled: sdkOnlyDial}\">\n <div class=\"config-hostname-label\">\n <span class=\"config-item-label\">Address</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Accessing hostnames must include a '.'\"\n matTooltipPosition=\"above\"\n ></div>\n <span *ngIf=\"errors.interceptAddressFormat\" class=\"error-label\">Accessing address must include a '.'</span>\n </div>\n <input id=\"HowTo\" type=\"text\" maxlength=\"100\" data-i18n=\"EgHost\" (change)=\"validateInterceptAddress()\" [ngClass]=\"{error: errors.interceptAddress}\" [placeholder]=\"sdkOnlyDial ? '' : 'e.g. myservice.ziti'\" [(ngModel)]=\"sdkOnlyDial ? '' : interceptConfigApiData.data.addresses[0]\">\n </div>\n <div class=\"config-item-container\" [ngClass]=\"{disabled: sdkOnlyDial}\">\n <span class=\"config-item-label\">PORT</span>\n <input id=\"HowToPort\" type=\"number\" maxlength=\"10\" (change)=\"validateInterceptPort()\" [ngClass]=\"{error: errors.interceptPort}\" [placeholder]=\"sdkOnlyDial ? '' : 443\" (keyup)=\"interceptPortChanged($event)\" [(ngModel)]=\"sdkOnlyDial ? '' : interceptPort\">\n </div>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'HOSTING CONFIGURATION'\"\n [contentStyle]=\"'z-index: 10000'\"\n [helpText]=\"'Where should traffic for this service be sent? Specify a protocol, address, and port, or use the "SDK Only" toggle for an application embedded configuration.'\"\n\n >\n <div class=\"form-field-input-group hosting-group\">\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">What identities can host this service?</span>\n </div>\n <lib-tag-selector\n [(selectedNamedAttributes)]=\"bindPolicyNamedAttributes\"\n [(selectedRoleAttributes)]=\"bindPolicyRoleAttributes\"\n [availableNamedAttributes]=\"identityNamedAttributes\"\n [availableRoleAttributes]=\"identityRoleAttributes\"\n [placeholder]=\"'Select identity attributes'\"\n [hasError]=\"errors.bindIdentities\"\n (selectedNamedAttributesChange)=\"validateBindIdentities()\"\n (selectedRoleAttributesChange)=\"validateBindIdentities()\"\n (filterChange)=\"getIdentityNamedAttributes($event)\"\n ></lib-tag-selector>\n </div>\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">Where should traffic be sent?</span>\n </div>\n <div class=\"grid addressFull\">\n <div class=\"config-item-container\">\n <span class=\"config-item-label\">SDK ONLY</span>\n <div\n class=\"sdk-toggle form-field-toggle\"\n >\n <div class=\"switchGrid\">\n <div>\n <div\n (click)=\"toggleSdkOnlyBind()\"\n [ngClass]=\"{ on: sdkOnlyBind }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!sdkOnlyBind\" class=\"on-label\">YES</span>\n <span [hidden]=\"sdkOnlyBind\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"config-item-container\" [ngClass]=\"{disabled: sdkOnlyBind}\">\n <span class=\"config-item-label\">PROTOCOL</span>\n <select id=\"HostedProtocol\" (change)=\"hostProtocolsChanged($event)\" [(ngModel)]=\"sdkOnlyBind ? '' : hostProtocol\">\n <option value=\"tcp\">TCP</option>\n <option value=\"udp\" >UDP</option>\n <option value=\"both\" >TCP/UDP</option>\n </select>\n </div>\n <div class=\"config-item-container\" [ngClass]=\"{disabled: sdkOnlyBind}\">\n <span class=\"config-item-label\">Address</span>\n <input id=\"HostedHost\" type=\"text\" maxlength=\"100\" data-i18n=\"EgHost\" (change)=\"validateHostAddress()\" [ngClass]=\"{error: errors.hostAddress}\" [placeholder]=\"sdkOnlyBind ? '' : 'e.g. myservice.ziti'\" [(ngModel)]=\"sdkOnlyBind ? '' : hostConfigApiData.data.address\">\n </div>\n <div class=\"config-item-container\" [ngClass]=\"{disabled: sdkOnlyBind}\">\n <span class=\"config-item-label\">PORT</span>\n <input id=\"HostedPort\" type=\"number\" maxlength=\"10\" (change)=\"validateHostPort()\" [ngClass]=\"{error: errors.hostPort}\" [placeholder]=\"sdkOnlyBind ? '' : 443\" [(ngModel)]=\"sdkOnlyBind ? '' : hostConfigApiData.data.port\">\n </div>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n </div>\n </div>\n </div>\n</div>\n<lib-loading-indicator *ngIf=\"isLoading || !dataInit\" [isLoading]=\"isLoading || !dataInit\"></lib-loading-indicator>\n", styles: [".service-header-container{display:flex;flex-direction:row;justify-content:space-between;align-items:center;position:relative}.simple-service-wrapper .simple-service-form-container .form-group-column{height:-moz-fit-content;height:fit-content;max-width:40.625rem;width:100%;transition:var(--transition);flex-grow:0;padding-bottom:0}.simple-service-wrapper .simple-service-form-container .simple-service-center-content lib-form-field-container{min-width:23.4375rem}.simple-service-wrapper .simple-service-form-container .simple-service-center-content .form-field-input-group{display:flex;flex-direction:column;gap:.9375rem}.simple-service-wrapper .grid.addressFull{grid-template-columns:4.375rem 5.9375rem auto 4.0625rem}.simple-service-wrapper .grid.addressPort{grid-template-columns:4.375rem auto 4.0625rem}.simple-service-wrapper input:disabled{opacity:.5!important}.simple-service-wrapper .addressPort .config-item-container.disabled,.simple-service-wrapper .addressFull .config-item-container.disabled{opacity:.3;pointer-events:none}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle{color:var(--white);display:flex;justify-content:space-between;height:var(--defaultInputHeight);align-items:center;margin-bottom:0}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .label,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .label{display:flex;font-size:.875rem;font-weight:600;text-transform:uppercase}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle{margin:0;display:flex;align-items:center;width:3.75rem;height:1.75rem;font-size:.875rem;line-height:1.5625rem;font-weight:800;font-family:Open Sans,Arial,sans-serif;background-color:var(--icon);color:var(--white);text-align:center;cursor:pointer;position:relative;float:left;border-radius:.8125rem}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle.on,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle.on{background-color:var(--green)}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle .switch,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle .switch{width:1.25rem;height:1.25rem;border-radius:.625rem;background-color:var(--white);transition:var(--transition);position:absolute;top:.25rem;z-index:10}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle .switch.on,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle .switch.on{left:2.1875rem}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle .on-label,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle .on-label{margin-left:.4375rem}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle .off-label,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle .off-label{margin-left:2rem}.simple-service-wrapper .addressPort .config-item-container .config-hostname-label,.simple-service-wrapper .addressFull .config-item-container .config-hostname-label{display:flex;flex-direction:row;justify-content:flex-start;white-space:nowrap}.simple-service-wrapper .addressPort .config-item-container .config-hostname-label .form-field-info,.simple-service-wrapper .addressFull .config-item-container .config-hostname-label .form-field-info{margin-top:.0625rem}.simple-service-wrapper .addressPort .config-item-container .config-hostname-label .error-label,.simple-service-wrapper .addressFull .config-item-container .config-hostname-label .error-label{margin-left:.3125rem}.simple-service-wrapper .form-field-input-group.service-group{gap:.625rem;display:flex;flex-direction:column}.simple-service-wrapper .form-field-input-group.accessing-group{gap:.9375rem;display:flex;flex-direction:column}.simple-service-wrapper .form-field-input-group .form-field-sub-group{display:flex;flex-direction:column;gap:.3125rem}.simple-service-wrapper .form-field-input-group .form-field-sub-group .config-title-row{height:.875rem}.simple-service-wrapper .form-field-input-group .form-field-sub-group .addressFull,.simple-service-wrapper .form-field-input-group .form-field-sub-group .addressPort{gap:.625rem}.simple-service-wrapper .form-field-input-group .form-field-sub-group .addressFull select{height:var(--defaultInputHeight)}.simple-service-wrapper .simple-service-center-content{display:flex;flex-direction:column;width:100%;align-items:center;justify-content:center}.simple-service-wrapper .simple-service-center-content .form-group-row{flex-wrap:wrap;gap:.9375rem;max-width:40.625rem;justify-content:center;padding:0}.config-item-label{color:#a9abaf;font-weight:600;margin-bottom:.3125rem;position:relative;display:flex;text-transform:uppercase}.simple-service-inputs{display:flex;flex-direction:column;gap:.9375rem}.form-field-input-group .form-field-title{color:var(--offWhite);margin-bottom:.625rem}.config-item .config-container.encryption-pod{background-color:#222f3e;background-image:linear-gradient(90deg,#232f3e,#f6f7fb);background-image:-ms-linear-gradient(90deg,rgb(35,47,62) 0%,rgb(246,247,251) 100%);border-radius:var(--inputBorderRadius)}.config-item .config-container .config-container-label{color:#fff}.convert-service-button{background-color:var(--primaryColor);width:2.0625rem;height:2.0625rem;color:var(--white);font-family:icomoon!important;font-size:1.5rem;border:none;border-radius:var(--inputBorderRadius);position:relative}::ng-deep .simple-service-wrapper input{max-height:var(--defaultInputHeight);min-height:0rem;height:var(--defaultInputHeight)}::ng-deep .simple-service-wrapper .select2-search__field{height:100%;min-height:2.5rem;max-height:2.5rem}::ng-deep .simple-service-wrapper .select2-selection__rendered{padding:0;max-height:7.1875rem!important;overflow:auto}::ng-deep .simple-service-wrapper .form-header-container{align-items:center}::ng-deep .simple-service-wrapper .form-header-container .form-header-group{width:40.625rem!important}::ng-deep .simple-service-wrapper .form-header-container .header-actions-container{min-width:0rem}::ng-deep .simple-service-wrapper .form-header-container .form-header-toggle-container{display:none}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i8.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i8.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i8.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i10.FormHeaderComponent, selector: "lib-form-header", inputs: ["data", "badges", "title", "moreActions", "formView", "saveDisabled", "saveTooltip", "actionButtonText", "moreActionsText", "showHeaderToggle", "showHeaderButton", "multiActions"], outputs: ["formViewChange", "actionRequested", "multiActionRequested"] }, { kind: "component", type: i11.FormFieldContainerComponent, selector: "lib-form-field-container", inputs: ["title", "title2", "titleIcon", "layout", "helpText", "helpText2", "label", "count", "action", "actionLabel", "class", "contentStyle", "contentClass", "showHeader", "showToggle", "headerActions", "headerToggle"], outputs: ["actionRequested", "headerToggleChange"] }, { kind: "component", type: i12.LoadingIndicatorComponent, selector: "lib-loading-indicator", inputs: ["isLoading"] }, { kind: "component", type: i13.TagSelectorComponent, selector: "lib-tag-selector", inputs: ["placeholder", "disableField", "disableCreate", "hideOption", "isLoading", "errorMessage", "focusOnInit", "selectedRoleAttributes", "selectedNamedAttributes", "hasError", "availableRoleAttributes", "availableNamedAttributes"], outputs: ["addRoleAttribute", "addNamedAttribute", "roleAttributeRemoved", "namedAttributeRemoved", "selectedRoleAttributesChange", "selectedNamedAttributesChange", "filterChange"] }] }); }
|
|
1010
|
-
}
|
|
1011
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SimpleServiceComponent, decorators: [{
|
|
1012
|
-
type: Component,
|
|
1013
|
-
args: [{ selector: 'lib-simple-service', template: "<div class=\"projectable-form-wrapper simple-service-wrapper\"\n (keyup.enter)=\"save($event)\"\n (keyup.escape)=\"closeModal(true, false, 'cards', $event)\"\n tabindex=\"0\"\n [class.projectable-form-hidden]=\"!dataInit\"\n>\n <lib-form-header\n [data]=\"formData\"\n [title]=\"isEdit ? 'Edit Simple Service' : 'Create a Simple Service'\"\n [actionButtonText]=\"'Save'\"\n [multiActions]=\"multiActions\"\n (actionRequested)=\"headerActionRequested($event)\"\n (multiActionRequested)=\"multiActionRequested($event)\"\n [(formView)]=\"formView\"\n [moreActions]=\"moreActions\"\n [class.is-scrolled]=\"isScrolled\"\n ></lib-form-header>\n\n <div class=\"simple-service-form-container projectable-form-container\" #formContainer>\n <div class=\"form-group-column three-fifths\" *ngIf=\"showForm\">\n <div id=\"InlineServiceArea\" class=\"anyadd\">\n <div class=\"simple-service-inputs\">\n <lib-form-field-container [title]=\"'Service Details'\">\n <div class=\"form-field-input-group service-group\">\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">Service Name</span>\n </div>\n <input\n class=\"form-field-input\"\n placeholder=\"Name this service\"\n autofocus\n #nameFieldInput\n [ngClass]=\"{error: errors.name}\"\n [(ngModel)]=\"serviceApiData.name\"\n (keyup)=\"serviceNameChanged($event)\"\n (change)=\"validateServiceName()\"\n />\n </div>\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">SELECT OR CREATE SERVICE ATTRIBUTES</span>\n </div>\n <lib-tag-selector\n [(selectedRoleAttributes)]=\"serviceApiData.roleAttributes\"\n [availableRoleAttributes]=\"serviceRoleAttributes\"\n [placeholder]=\"'Add attributes to group services'\"\n ></lib-tag-selector>\n </div>\n </div>\n </lib-form-field-container>\n </div>\n </div>\n </div>\n <div class=\"simple-service-center-content\" *ngIf=\"showForm\">\n <div class=\"form-group-row\">\n <lib-form-field-container\n [title]=\"'ACCESSING CONFIGURATION'\"\n [contentStyle]=\"'z-index: 10001'\"\n [helpText]=\"'How will client applications use this service? Specify an address and port, or use the "SDK Only" toggle for an application embedded configuration.'\"\n >\n <div class=\"form-field-input-group accessing-group\">\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">What identities can access this service?</span>\n </div>\n <lib-tag-selector\n [(selectedNamedAttributes)]=\"dialPolicyNamedAttributes\"\n [(selectedRoleAttributes)]=\"dialPolicyRoleAttributes\"\n [availableNamedAttributes]=\"identityNamedAttributes\"\n [availableRoleAttributes]=\"identityRoleAttributes\"\n [placeholder]=\"'Select identity attributes to grant access'\"\n [hasError]=\"errors.dialIdentities\"\n (selectedNamedAttributesChange)=\"validateDialIdentities()\"\n (selectedRoleAttributesChange)=\"validateDialIdentities()\"\n (filterChange)=\"getIdentityNamedAttributes($event)\"\n ></lib-tag-selector>\n </div>\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">How will the service be accessed?</span>\n </div>\n <div class=\"grid addressPort\">\n <div class=\"config-item-container\">\n <span class=\"config-item-label\">SDK ONLY</span>\n <div\n class=\"sdk-toggle form-field-toggle\"\n >\n <div class=\"switchGrid\">\n <div>\n <div\n (click)=\"toggleSdkOnlyDial()\"\n [ngClass]=\"{ on: sdkOnlyDial }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!sdkOnlyDial\" class=\"on-label\">YES</span>\n <span [hidden]=\"sdkOnlyDial\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"config-item-container\" [ngClass]=\"{disabled: sdkOnlyDial}\">\n <div class=\"config-hostname-label\">\n <span class=\"config-item-label\">Address</span>\n <div\n class=\"form-field-info infoicon\"\n matTooltip=\"Accessing hostnames must include a '.'\"\n matTooltipPosition=\"above\"\n ></div>\n <span *ngIf=\"errors.interceptAddressFormat\" class=\"error-label\">Accessing address must include a '.'</span>\n </div>\n <input id=\"HowTo\" type=\"text\" maxlength=\"100\" data-i18n=\"EgHost\" (change)=\"validateInterceptAddress()\" [ngClass]=\"{error: errors.interceptAddress}\" [placeholder]=\"sdkOnlyDial ? '' : 'e.g. myservice.ziti'\" [(ngModel)]=\"sdkOnlyDial ? '' : interceptConfigApiData.data.addresses[0]\">\n </div>\n <div class=\"config-item-container\" [ngClass]=\"{disabled: sdkOnlyDial}\">\n <span class=\"config-item-label\">PORT</span>\n <input id=\"HowToPort\" type=\"number\" maxlength=\"10\" (change)=\"validateInterceptPort()\" [ngClass]=\"{error: errors.interceptPort}\" [placeholder]=\"sdkOnlyDial ? '' : 443\" (keyup)=\"interceptPortChanged($event)\" [(ngModel)]=\"sdkOnlyDial ? '' : interceptPort\">\n </div>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n <lib-form-field-container\n [title]=\"'HOSTING CONFIGURATION'\"\n [contentStyle]=\"'z-index: 10000'\"\n [helpText]=\"'Where should traffic for this service be sent? Specify a protocol, address, and port, or use the "SDK Only" toggle for an application embedded configuration.'\"\n\n >\n <div class=\"form-field-input-group hosting-group\">\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">What identities can host this service?</span>\n </div>\n <lib-tag-selector\n [(selectedNamedAttributes)]=\"bindPolicyNamedAttributes\"\n [(selectedRoleAttributes)]=\"bindPolicyRoleAttributes\"\n [availableNamedAttributes]=\"identityNamedAttributes\"\n [availableRoleAttributes]=\"identityRoleAttributes\"\n [placeholder]=\"'Select identity attributes'\"\n [hasError]=\"errors.bindIdentities\"\n (selectedNamedAttributesChange)=\"validateBindIdentities()\"\n (selectedRoleAttributesChange)=\"validateBindIdentities()\"\n (filterChange)=\"getIdentityNamedAttributes($event)\"\n ></lib-tag-selector>\n </div>\n <div class=\"form-field-sub-group\">\n <div class=\"config-title-row\">\n <span class=\"form-field-title\">Where should traffic be sent?</span>\n </div>\n <div class=\"grid addressFull\">\n <div class=\"config-item-container\">\n <span class=\"config-item-label\">SDK ONLY</span>\n <div\n class=\"sdk-toggle form-field-toggle\"\n >\n <div class=\"switchGrid\">\n <div>\n <div\n (click)=\"toggleSdkOnlyBind()\"\n [ngClass]=\"{ on: sdkOnlyBind }\"\n class=\"toggle\"\n >\n <span [hidden]=\"!sdkOnlyBind\" class=\"on-label\">YES</span>\n <span [hidden]=\"sdkOnlyBind\" class=\"off-label\">NO</span>\n <div class=\"switch\"></div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"config-item-container\" [ngClass]=\"{disabled: sdkOnlyBind}\">\n <span class=\"config-item-label\">PROTOCOL</span>\n <select id=\"HostedProtocol\" (change)=\"hostProtocolsChanged($event)\" [(ngModel)]=\"sdkOnlyBind ? '' : hostProtocol\">\n <option value=\"tcp\">TCP</option>\n <option value=\"udp\" >UDP</option>\n <option value=\"both\" >TCP/UDP</option>\n </select>\n </div>\n <div class=\"config-item-container\" [ngClass]=\"{disabled: sdkOnlyBind}\">\n <span class=\"config-item-label\">Address</span>\n <input id=\"HostedHost\" type=\"text\" maxlength=\"100\" data-i18n=\"EgHost\" (change)=\"validateHostAddress()\" [ngClass]=\"{error: errors.hostAddress}\" [placeholder]=\"sdkOnlyBind ? '' : 'e.g. myservice.ziti'\" [(ngModel)]=\"sdkOnlyBind ? '' : hostConfigApiData.data.address\">\n </div>\n <div class=\"config-item-container\" [ngClass]=\"{disabled: sdkOnlyBind}\">\n <span class=\"config-item-label\">PORT</span>\n <input id=\"HostedPort\" type=\"number\" maxlength=\"10\" (change)=\"validateHostPort()\" [ngClass]=\"{error: errors.hostPort}\" [placeholder]=\"sdkOnlyBind ? '' : 443\" [(ngModel)]=\"sdkOnlyBind ? '' : hostConfigApiData.data.port\">\n </div>\n </div>\n </div>\n </div>\n </lib-form-field-container>\n </div>\n </div>\n </div>\n</div>\n<lib-loading-indicator *ngIf=\"isLoading || !dataInit\" [isLoading]=\"isLoading || !dataInit\"></lib-loading-indicator>\n", styles: [".service-header-container{display:flex;flex-direction:row;justify-content:space-between;align-items:center;position:relative}.simple-service-wrapper .simple-service-form-container .form-group-column{height:-moz-fit-content;height:fit-content;max-width:40.625rem;width:100%;transition:var(--transition);flex-grow:0;padding-bottom:0}.simple-service-wrapper .simple-service-form-container .simple-service-center-content lib-form-field-container{min-width:23.4375rem}.simple-service-wrapper .simple-service-form-container .simple-service-center-content .form-field-input-group{display:flex;flex-direction:column;gap:.9375rem}.simple-service-wrapper .grid.addressFull{grid-template-columns:4.375rem 5.9375rem auto 4.0625rem}.simple-service-wrapper .grid.addressPort{grid-template-columns:4.375rem auto 4.0625rem}.simple-service-wrapper input:disabled{opacity:.5!important}.simple-service-wrapper .addressPort .config-item-container.disabled,.simple-service-wrapper .addressFull .config-item-container.disabled{opacity:.3;pointer-events:none}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle{color:var(--white);display:flex;justify-content:space-between;height:var(--defaultInputHeight);align-items:center;margin-bottom:0}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .label,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .label{display:flex;font-size:.875rem;font-weight:600;text-transform:uppercase}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle{margin:0;display:flex;align-items:center;width:3.75rem;height:1.75rem;font-size:.875rem;line-height:1.5625rem;font-weight:800;font-family:Open Sans,Arial,sans-serif;background-color:var(--icon);color:var(--white);text-align:center;cursor:pointer;position:relative;float:left;border-radius:.8125rem}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle.on,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle.on{background-color:var(--green)}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle .switch,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle .switch{width:1.25rem;height:1.25rem;border-radius:.625rem;background-color:var(--white);transition:var(--transition);position:absolute;top:.25rem;z-index:10}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle .switch.on,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle .switch.on{left:2.1875rem}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle .on-label,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle .on-label{margin-left:.4375rem}.simple-service-wrapper .addressPort .config-item-container .sdk-toggle .toggle .off-label,.simple-service-wrapper .addressFull .config-item-container .sdk-toggle .toggle .off-label{margin-left:2rem}.simple-service-wrapper .addressPort .config-item-container .config-hostname-label,.simple-service-wrapper .addressFull .config-item-container .config-hostname-label{display:flex;flex-direction:row;justify-content:flex-start;white-space:nowrap}.simple-service-wrapper .addressPort .config-item-container .config-hostname-label .form-field-info,.simple-service-wrapper .addressFull .config-item-container .config-hostname-label .form-field-info{margin-top:.0625rem}.simple-service-wrapper .addressPort .config-item-container .config-hostname-label .error-label,.simple-service-wrapper .addressFull .config-item-container .config-hostname-label .error-label{margin-left:.3125rem}.simple-service-wrapper .form-field-input-group.service-group{gap:.625rem;display:flex;flex-direction:column}.simple-service-wrapper .form-field-input-group.accessing-group{gap:.9375rem;display:flex;flex-direction:column}.simple-service-wrapper .form-field-input-group .form-field-sub-group{display:flex;flex-direction:column;gap:.3125rem}.simple-service-wrapper .form-field-input-group .form-field-sub-group .config-title-row{height:.875rem}.simple-service-wrapper .form-field-input-group .form-field-sub-group .addressFull,.simple-service-wrapper .form-field-input-group .form-field-sub-group .addressPort{gap:.625rem}.simple-service-wrapper .form-field-input-group .form-field-sub-group .addressFull select{height:var(--defaultInputHeight)}.simple-service-wrapper .simple-service-center-content{display:flex;flex-direction:column;width:100%;align-items:center;justify-content:center}.simple-service-wrapper .simple-service-center-content .form-group-row{flex-wrap:wrap;gap:.9375rem;max-width:40.625rem;justify-content:center;padding:0}.config-item-label{color:#a9abaf;font-weight:600;margin-bottom:.3125rem;position:relative;display:flex;text-transform:uppercase}.simple-service-inputs{display:flex;flex-direction:column;gap:.9375rem}.form-field-input-group .form-field-title{color:var(--offWhite);margin-bottom:.625rem}.config-item .config-container.encryption-pod{background-color:#222f3e;background-image:linear-gradient(90deg,#232f3e,#f6f7fb);background-image:-ms-linear-gradient(90deg,rgb(35,47,62) 0%,rgb(246,247,251) 100%);border-radius:var(--inputBorderRadius)}.config-item .config-container .config-container-label{color:#fff}.convert-service-button{background-color:var(--primaryColor);width:2.0625rem;height:2.0625rem;color:var(--white);font-family:icomoon!important;font-size:1.5rem;border:none;border-radius:var(--inputBorderRadius);position:relative}::ng-deep .simple-service-wrapper input{max-height:var(--defaultInputHeight);min-height:0rem;height:var(--defaultInputHeight)}::ng-deep .simple-service-wrapper .select2-search__field{height:100%;min-height:2.5rem;max-height:2.5rem}::ng-deep .simple-service-wrapper .select2-selection__rendered{padding:0;max-height:7.1875rem!important;overflow:auto}::ng-deep .simple-service-wrapper .form-header-container{align-items:center}::ng-deep .simple-service-wrapper .form-header-container .form-header-group{width:40.625rem!important}::ng-deep .simple-service-wrapper .form-header-container .header-actions-container{min-width:0rem}::ng-deep .simple-service-wrapper .form-header-container .form-header-toggle-container{display:none}\n"] }]
|
|
1014
|
-
}], ctorParameters: function () { return [{ type: i14.SettingsService, decorators: [{
|
|
1015
|
-
type: Inject,
|
|
1016
|
-
args: [SETTINGS_SERVICE]
|
|
1017
|
-
}] }, { type: i1.ServiceFormService }, { type: i15.ZitiDataService, decorators: [{
|
|
1018
|
-
type: Inject,
|
|
1019
|
-
args: [ZITI_DATA_SERVICE]
|
|
1020
|
-
}] }, { type: i2.GrowlerService }, { type: undefined, decorators: [{
|
|
1021
|
-
type: Inject,
|
|
1022
|
-
args: [SERVICE_EXTENSION_SERVICE]
|
|
1023
|
-
}] }, { type: i3.MatDialog }, { type: i4.ValidationService }, { type: i5.ServicesPageService }, { type: i6.Router }, { type: i6.ActivatedRoute }, { type: i7.Location }]; }, propDecorators: { serviceRoleAttributes: [{
|
|
1024
|
-
type: Input
|
|
1025
|
-
}], identityRoleAttributes: [{
|
|
1026
|
-
type: Input
|
|
1027
|
-
}], identityNamedAttributes: [{
|
|
1028
|
-
type: Input
|
|
1029
|
-
}], close: [{
|
|
1030
|
-
type: Output
|
|
1031
|
-
}], selected: [{
|
|
1032
|
-
type: Output
|
|
1033
|
-
}], formData: [{
|
|
1034
|
-
type: Input
|
|
1035
|
-
}] } });
|
|
1036
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2ltcGxlLXNlcnZpY2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMveml0aS1jb25zb2xlLWxpYi9zcmMvbGliL2ZlYXR1cmVzL3Byb2plY3RhYmxlLWZvcm1zL3NlcnZpY2Uvc2ltcGxlLXNlcnZpY2Uvc2ltcGxlLXNlcnZpY2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMveml0aS1jb25zb2xlLWxpYi9zcmMvbGliL2ZlYXR1cmVzL3Byb2plY3RhYmxlLWZvcm1zL3NlcnZpY2Uvc2ltcGxlLXNlcnZpY2Uvc2ltcGxlLXNlcnZpY2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDN0UsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBQzdELE9BQU8sRUFBQyxnQkFBZ0IsRUFBa0IsTUFBTSx1Q0FBdUMsQ0FBQztBQUN4RixPQUFPLEVBQUMseUJBQXlCLEVBQXFCLE1BQU0seUJBQXlCLENBQUM7QUFDdEYsT0FBTyxFQUFDLGlCQUFpQixFQUFrQixNQUFNLHdDQUF3QyxDQUFDO0FBRzFGLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxrQ0FBa0MsQ0FBQztBQUU5RCxPQUFPLEVBQUMsOEJBQThCLEVBQUMsTUFBTSxvRUFBb0UsQ0FBQztBQUNsSCxPQUFPLEVBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQVcsR0FBRyxFQUFFLEdBQUcsRUFBQyxNQUFNLFFBQVEsQ0FBQztBQUszRixPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUVwRSxPQUFPLEVBQUMs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QWMsR0FBRyxjQUFjLENBQUM7WUFDckMsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7WUFDckMsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7WUFDckMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDbEM7UUFDRCxJQUFJLENBQUMsV0FBVyxHQUFHLGlCQUFpQixJQUFJLG1CQUFtQixJQUFJLGNBQWMsSUFBSSxjQUFjLElBQUksY0FBYyxDQUFDO0lBQ3BILENBQUM7SUFFRCxLQUFLO0lBQ0wsQ0FBQzsrR0FuaUNVLHNCQUFzQixrQkFvR3JCLGdCQUFnQiwrQ0FFaEIsaUJBQWlCLDJDQUVqQix5QkFBeUI7bUdBeEcxQixzQkFBc0IsNFRDekJuQyxnNmFBb01BOzs0RkQzS2Esc0JBQXNCO2tCQUxsQyxTQUFTOytCQUNFLG9CQUFvQjs7MEJBd0d6QixNQUFNOzJCQUFDLGdCQUFnQjs7MEJBRXZCLE1BQU07MkJBQUMsaUJBQWlCOzswQkFFeEIsTUFBTTsyQkFBQyx5QkFBeUI7K01Bdkc1QixxQkFBcUI7c0JBQTdCLEtBQUs7Z0JBQ0csc0JBQXNCO3NCQUE5QixLQUFLO2dCQUNHLHVCQUF1QjtzQkFBL0IsS0FBSztnQkE2RkksS0FBSztzQkFBZCxNQUFNO2dCQUNHLFFBQVE7c0JBQWpCLE1BQU07Z0JBb0JlLFFBQVE7c0JBQTdCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbmplY3QsIElucHV0LCBPdXRwdXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtQcm9qZWN0YWJsZUZvcm19IGZyb20gXCIuLi8uLi9wcm9qZWN0YWJsZS1mb3JtLmNsYXNzXCI7XG5pbXBvcnQge1NFVFRJTkdTX1NFUlZJQ0UsIFNldHRpbmdzU2VydmljZX0gZnJvbSBcIi4uLy4uLy4uLy4uL3NlcnZpY2VzL3NldHRpbmdzLnNlcnZpY2VcIjtcbmltcG9ydCB7U0VSVklDRV9FWFRFTlNJT05fU0VSVklDRSwgU2VydmljZUZvcm1TZXJ2aWNlfSBmcm9tIFwiLi4vc2VydmljZS1mb3JtLnNlcnZpY2VcIjtcbmltcG9ydCB7WklUSV9EQVRBX1NFUlZJQ0UsIFppdGlEYXRhU2VydmljZX0gZnJvbSBcIi4uLy4uLy4uLy4uL3NlcnZpY2VzL3ppdGktZGF0YS5zZXJ2aWNlXCI7XG5pbXBvcnQge0dyb3dsZXJTZXJ2aWNlfSBmcm9tIFwiLi4vLi4vLi4vbWVzc2FnaW5nL2dyb3dsZXIuc2VydmljZVwiO1xuaW1wb3J0IHtFeHRlbnNpb25TZXJ2aWNlfSBmcm9tIFwiLi4vLi4vLi4vZXh0ZW5kYWJsZS9leHRlbnNpb25zLW5vb3Auc2VydmljZVwiO1xuaW1wb3J0IHtHcm93bGVyTW9kZWx9IGZyb20gXCIuLi8uLi8uLi9tZXNzYWdpbmcvZ3Jvd2xlci5tb2RlbFwiO1xuaW1wb3J0IHtNYXREaWFsb2d9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2dcIjtcbmltcG9ydCB7Q3JlYXRpb25TdW1tYXJ5RGlhbG9nQ29tcG9uZW50fSBmcm9tIFwiLi4vLi4vLi4vY3JlYXRpb24tc3VtbWFyeS1kaWFsb2cvY3JlYXRpb24tc3VtbWFyeS1kaWFsb2cuY29tcG9uZW50XCI7XG5pbXBvcnQge2lzRW1wdHksIGlzTmlsLCBpc05hTiwgdW5zZXQsIGNsb25lRGVlcCwgaXNFcXVhbCwgZm9yRWFjaCwgc2V0LCBnZXR9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQge1ZhbGlkYXRpb25TZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy92YWxpZGF0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHtTZXJ2aWNlc1BhZ2VTZXJ2aWNlfSBmcm9tIFwiLi4vLi4vLi4vLi4vcGFnZXMvc2VydmljZXMvc2VydmljZXMtcGFnZS5zZXJ2aWNlXCI7XG5pbXBvcnQge0FjdGl2YXRlZFJvdXRlLCBSb3V0ZXJ9IGZyb20gXCJAYW5ndWxhci9yb3V0ZXJcIjtcbmltcG9ydCB7RmlsdGVyT2JqfSBmcm9tIFwiLi4vLi4vLi4vZGF0YS10YWJsZS9kYXRhLXRhYmxlLWZpbHRlci5zZXJ2aWNlXCI7XG5pbXBvcnQge0NvbmZpcm1Db21wb25lbnR9IGZyb20gXCIuLi8uLi8uLi9jb25maXJtL2NvbmZpcm0uY29tcG9uZW50XCI7XG5pbXBvcnQge0xvY2F0aW9ufSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQge1VSTFN9IGZyb20gXCIuLi8uLi8uLi8uLi91cmxzXCI7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgZm9ya0pvaW4sIE9ic2VydmFibGUsIG9mfSBmcm9tIFwicnhqc1wiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsaWItc2ltcGxlLXNlcnZpY2UnLFxuICB0ZW1wbGF0ZVVybDogJy4vc2ltcGxlLXNlcnZpY2UuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zaW1wbGUtc2VydmljZS5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIFNpbXBsZVNlcnZpY2VDb21wb25lbnQgZXh0ZW5kcyBQcm9qZWN0YWJsZUZvcm0ge1xuICBASW5wdXQoKSBzZXJ2aWNlUm9sZUF0dHJpYnV0ZXM6IGFueVtdID0gW107XG4gIEBJbnB1dCgpIGlkZW50aXR5Um9sZUF0dHJpYnV0ZXM6IGFueVtdID0gW107XG4gIEBJbnB1dCgpIGlkZW50aXR5TmFtZWRBdHRyaWJ1dGVzOiBhbnlbXSA9IFtdO1xuXG4gIHNob3dGb3JtID0gdHJ1ZTtcbiAgZm9ybVZpZXcgPSAnc2ltcGxlJztcbiAgY29udHJvbGxlckRvbWFpbiA9ICcnO1xuICB6aXRpU2Vzc2lvbklkO1xuICBpbnRlcmNlcHRQb3J0O1xuICBob3N0UHJvdG9jb2wgPSAndGNwJztcbiAgc2VydmljZUNsaUNvbW1hbmQgPSAnJztcbiAgaW50ZXJjZXB0Q29uZmlnQ2xpQ29tbWFuZCA9ICcnO1xuICBob3N0Q29uZmlnQ2xpQ29tbWFuZCA9ICcnO1xuICBkaWFsUG9saWN5Q2xpQ29tbWFuZCA9ICcnO1xuICBiaW5kUG9saWN5Q2xpQ29tbWFuZCA9ICcnO1xuICBzZXJ2aWNlQXBpVXJsID0gJyc7XG4gIGludGVyY2VwdENvbmZpZ0FwaVVybCA9ICcnO1xuICBob3N0Q29uZmlnQXBpVXJsID0gJyc7XG4gIGRpYWxQb2xpY3lBcGlVcmwgPSAnJztcbiAgYmluZFBvbGljeUFwaVVybCA9ICcnO1xuICBpbml0U2VydmljZUFwaURhdGEgPSB7XG4gICAgbmFtZTogXCJcIixcbiAgICByb2xlQXR0cmlidXRlczogW10sXG4gICAgY29uZmlnczogW10sXG4gICAgZW5jcnlwdGlvblJlcXVpcmVkOiB0cnVlXG4gIH07XG4gIGluaXRJbnRlcmNlcHRDb25maWdBcGlEYXRhID0ge1xuICAgIG5hbWU6IFwiXCIsXG4gICAgY29uZmlnVHlwZUlkOlwiZzdjSVdiY0dnXCIsXG4gICAgZGF0YToge1xuICAgICAgcG9ydFJhbmdlczogW10sXG4gICAgICBhZGRyZXNzZXM6IFtdLFxuICAgICAgcHJvdG9jb2xzOiBbJ3RjcCcsICd1ZHAnXVxuICAgIH1cbiAgfTtcbiAgaW5pdEhvc3RDb25maWdBcGlEYXRhID0ge1xuICAgIG5hbWU6ICcnLFxuICAgIGNvbmZpZ1R5cGVJZDogXCJOSDVwNEZwR1JcIixcbiAgICBkYXRhOiB7XG4gICAgICBhZGRyZXNzOiBcIlwiLFxuICAgICAgcG9ydDogdW5kZWZpbmVkLFxuICAgICAgZm9yd2FyZFByb3RvY29sOiB0cnVlLFxuICAgICAgYWxsb3dlZFByb3RvY29sczogWyd0Y3AnXVxuICAgIH1cbiAgfTtcbiAgaW5pdERpYWxQb2xpY3lBcGlEYXRhID0ge1xuICAgIG5hbWU6IFwiXCIsXG4gICAgdHlwZTogXCJEaWFsXCIsXG4gICAgc2VtYW50aWM6IFwiQW55T2ZcIixcbiAgICBzZXJ2aWNlUm9sZXM6IFtdLFxuICAgIGlkZW50aXR5Um9sZXM6IFtdXG4gIH07XG4gIGluaXRCaW5kUG9saWN5QXBpRGF0YSA9IHtcbiAgICBuYW1lOiBcIlwiLFxuICAgIHR5cGU6IFwiQmluZFwiLFxuICAgIHNlbWFudGljOiBcIkFueU9mXCIsXG4gICAgc2VydmljZVJvbGVzOiBbXSxcbiAgICBpZGVudGl0eVJvbGVzOiBbXVxuICB9O1xuICBzZXJ2aWNlQXBpRGF0YTtcbiAgaW50ZXJjZXB0Q29uZmlnQXBpRGF0YTtcbiAgaG9zdENvbmZpZ0FwaURhdGE7XG4gIGRpYWxQb2xpY3lBcGlEYXRhO1xuICBiaW5kUG9saWN5QXBpRGF0YTtcbiAgZGlhbFBvbGljeU5hbWVkQXR0cmlidXRlcyA9IFtdO1xuICBkaWFsUG9saWN5Um9sZUF0dHJpYnV0ZXMgPSBbXTtcbiAgYmluZFBvbGljeU5hbWVkQXR0cmlidXRlcyA9IFtdO1xuICBiaW5kUG9saWN5Um9sZUF0dHJpYnV0ZXMgPSBbXTtcbiAgaWRlbnRpdGllc05hbWVJZE1hcCA9IHt9O1xuICBpZGVudGl0aWVzSWROYW1lTWFwID0ge307XG4gIGludGVyY2VwdENvbmZpZ0lkO1xuICBob3N0Q29uZmlnSWQ7XG4gIHNlcnZpY2VJZDtcbiAgc2RrT25seURpYWwgPSBmYWxzZTtcbiAgc2RrT25seUJpbmQgPSBmYWxzZTtcbiAgZGlhbG9nUmVmOiBhbnk7XG5cbiAgaW50ZXJjZXB0SW5jcmVtZW50ID0gLTE7XG4gIGhvc3RJbmNyZW1lbnQgPSAtMTtcbiAgc2VydmljZUluY3JlbWVudCA9IC0xO1xuICBkaWFsSW5jcmVtZW50ID0gLTE7XG4gIGJpbmRJbmNyZW1lbnQgPSAtMTtcblxuICBzZXJ2aWNlRGF0YUNoYW5nZSA9IGZhbHNlO1xuICBpbnRlcmNlcHREYXRhQ2hhbmdlID0gZmFsc2U7XG4gIGhvc3REYXRhQ2hhbmdlID0gZmFsc2U7XG4gIGRpYWxEYXRhQ2hhbmdlID0gZmFsc2U7XG4gIGJpbmREYXRhQ2hhbmdlID0gZmFsc2U7XG4gIGlkZW50aXRpZXNJbml0OiBCZWhhdmlvclN1YmplY3Q8YW55PiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55PihmYWxzZSk7XG4gIGVudGl0aWVzSW5pdCA9IGZhbHNlO1xuXG4gIG11bHRpQWN0aW9ucyA9IFtdO1xuXG4gIG92ZXJyaWRlIGVudGl0eVR5cGUgPSAnc2VydmljZXMnO1xuXG4gIEBPdXRwdXQoKSBjbG9zZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIHNlbGVjdGVkOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgQEluamVjdChTRVRUSU5HU19TRVJWSUNFKSBwcm90ZWN0ZWQgb3ZlcnJpZGUgc2V0dGluZ3NTZXJ2aWNlOiBTZXR0aW5nc1NlcnZpY2UsXG4gICAgICBwdWJsaWMgc3ZjOiBTZXJ2aWNlRm9ybVNlcnZpY2UsXG4gICAgICBASW5qZWN0KFpJVElfREFUQV9TRVJWSUNFKSBvdmVycmlkZSB6aXRpU2VydmljZTogWml0aURhdGFTZXJ2aWNlLFxuICAgICAgZ3Jvd2xlclNlcnZpY2U6IEdyb3dsZXJTZXJ2aWNlLFxuICAgICAgQEluamVjdChTRVJWSUNFX0VYVEVOU0lPTl9TRVJWSUNFKSBleHRTZXJ2aWNlOiBFeHRlbnNpb25TZXJ2aWNlLFxuICAgICAgcHJpdmF0ZSBkaWFsb2dGb3JtOiBNYXREaWFsb2csXG4gICAgICBwcml2YXRlIHZhbGlkYXRpb25TZXJ2aWNlOiBWYWxpZGF0aW9uU2VydmljZSxcbiAgICAgIHByaXZhdGUgc2VydmljZXNQYWdlU2VydmljZTogU2VydmljZXNQYWdlU2VydmljZSxcbiAgICAgIHByb3RlY3RlZCBvdmVycmlkZSByb3V0ZXI6IFJvdXRlcixcbiAgICAgIHByb3RlY3RlZCBvdmVycmlkZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICBsb2NhdGlvbjogTG9jYXRpb25cbiAgKSB7XG4gICAgc3VwZXIoZ3Jvd2xlclNlcnZpY2UsIGV4dFNlcnZpY2UsIHppdGlTZXJ2aWNlLCByb3V0ZXIsIHJvdXRlLCBsb2NhdGlvbiwgc2V0dGluZ3NTZXJ2aWNlKTtcbiAgICB0aGlzLnN2Yy5mb3JtRGF0YSA9IHt9O1xuICB9XG5cbiAgc2VydmljZURhdGFTZXQ6IGJvb2xlYW47XG4gIEBJbnB1dCgpIG92ZXJyaWRlIHNldCBmb3JtRGF0YShkYXRhKSB7XG4gICAgaWYgKCFkYXRhPy5jb25maWdzKSB7XG4gICAgICBkYXRhLmNvbmZpZ3MgPSBbXTtcbiAgICB9XG4gICAgdGhpcy5zdmMuZm9ybURhdGEgPSBkYXRhO1xuICAgIGlmICghaXNFbXB0eShkYXRhPy5pZCkpIHtcbiAgICAgIHRoaXMuaW5pdEFzc29jaWF0ZWREYXRhKCk7XG4gICAgICBpZiAoZ2V0KHRoaXMuZm9ybURhdGEsICd0YWdzLnNlcnZpY2UtdHlwZScpID09PSAnc2ltcGxlJykge1xuICAgICAgICB0aGlzLm11bHRpQWN0aW9ucyA9IFtcbiAgICAgICAgICB7aWQ6ICdjb252ZXJ0LXRvLWFkdmFuY2VkJywgbGFiZWw6ICdDb252ZXJ0IHRvIEFkdmFuY2VkJywgaGlkZGVuOiBmYWxzZX1cbiAgICAgICAgXVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5tdWx0aUFjdGlvbnMgPSBbXVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc29jaWF0ZWREYXRhSW5pdCA9IHRydWU7XG4gICAgfVxuICAgIHRoaXMuc2VydmljZURhdGFTZXQgPSB0cnVlO1xuICAgIHRoaXMuY2hlY2tBbGxEYXRhSW5pdCgpO1xuICB9XG5cbiAgb3ZlcnJpZGUgZ2V0IGZvcm1EYXRhKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuc3ZjPy5mb3JtRGF0YTtcbiAgfVxuXG4gIGVudGl0eUlkSW5pdDogYm9vbGVhbjtcbiAgb3ZlcnJpZGUgc2V0IGVudGl0eUlkKGlkOiBTdHJpbmcpIHtcbiAgICB0aGlzLl9lbnRpdHlJZCA9IGlkO1xuICAgIGlmIChpc0VtcHR5KGlkKSB8fCBpZCA9PT0gJ2NyZWF0ZScpIHtcbiAgICAgIHRoaXMuc2VydmljZURhdGFTZXQgPSB0cnVlO1xuICAgICAgdGhpcy5hc3NvY2lhdGVkRGF0YUluaXQgPSB0cnVlO1xuICAgIH1cbiAgICB0aGlzLmVudGl0eUlkSW5pdCA9IHRydWU7XG4gICAgdGhpcy5jaGVja0FsbERhdGFJbml0KCk7XG4gIH1cblxuICBvdmVycmlkZSBnZXQgZW50aXR5SWQoKTogU3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fZW50aXR5SWQ7XG4gIH1cblxuICBvdmVycmlkZSBuZ09uSW5pdCgpIHtcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuICAgIHRoaXMuY29udHJvbGxlckRvbWFpbiA9IHRoaXMuc2V0dGluZ3NTZXJ2aWNlPy5zZXR0aW5ncz8uc2VsZWN0ZWRFZGdlQ29udHJvbGxlcjtcbiAgICB0aGlzLnppdGlTZXNzaW9uSWQgPSB0aGlzLnNldHRpbmdzU2VydmljZT8uc2V0dGluZ3M/LnNlc3Npb24/LmlkO1xuICAgIHRoaXMuaW5pdEZvcm1EYXRhKCk7XG4gICAgdGhpcy5nZXRJZGVudGl0eU5hbWVkQXR0cmlidXRlcygpO1xuICB9XG5cbiAgZm9ybURhdGFTZXQgPSBmYWxzZTtcbiAgaW5pdEZvcm1EYXRhKCkge1xuICAgIHRoaXMuc2VydmljZUFwaVVybCA9IGAke3RoaXMuY29udHJvbGxlckRvbWFpbn0vZWRnZS9tYW5hZ2VtZW50L3YxL3NlcnZpY2VzYDtcbiAgICB0aGlzLmludGVyY2VwdENvbmZpZ0FwaVVybCA9IGAke3RoaXMuY29udHJvbGxlckRvbWFpbn0vZWRnZS9tYW5hZ2VtZW50L3YxL2NvbmZpZ3NgO1xuICAgIHRoaXMuaG9zdENvbmZpZ0FwaVVybCA9IGAke3RoaXMuY29udHJvbGxlckRvbWFpbn0vZWRnZS9tYW5hZ2VtZW50L3YxL2NvbmZpZ3NgO1xuICAgIHRoaXMuZGlhbFBvbGljeUFwaVVybCA9IGAke3RoaXMuY29udHJvbGxlckRvbWFpbn0vZWRnZS9tYW5hZ2VtZW50L3YxL3NlcnZpY2UtcG9saWNpZXNgO1xuICAgIHRoaXMuYmluZFBvbGljeUFwaVVybCA9IGAke3RoaXMuY29udHJvbGxlckRvbWFpbn0vZWRnZS9tYW5hZ2VtZW50L3YxL3NlcnZpY2UtcG9saWNpZXNgO1xuICAgIHRoaXMuc2VydmljZUNsaUNvbW1hbmQgPSAnJztcbiAgICB0aGlzLmludGVyY2VwdENvbmZpZ0NsaUNvbW1hbmQgPSAnJztcbiAgICB0aGlzLmhvc3RDb25maWdDbGlDb21tYW5kID0gJyc7XG4gICAgdGhpcy5kaWFsUG9saWN5Q2xpQ29tbWFuZCA9ICcnO1xuICAgIHRoaXMuYmluZFBvbGljeUNsaUNvbW1hbmQgPSAnJztcbiAgICB0aGlzLmludGVyY2VwdENvbmZpZ0lkID0gJyc7XG4gICAgdGhpcy5ob3N0Q29uZmlnSWQgPSAnJztcbiAgICB0aGlzLnNlcnZpY2VJZCA9ICcnO1xuICAgIHRoaXMuc2RrT25seURpYWwgPSBmYWxzZTtcbiAgICB0aGlzLnNka09ubHlCaW5kID0gZmFsc2U7XG4gICAgdGhpcy5pbnRlcmNlcHRQb3J0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuZGlhbFBvbGljeU5hbWVkQXR0cmlidXRlcyA9IFtdO1xuICAgIHRoaXMuZGlhbFBvbGljeVJvbGVBdHRyaWJ1dGVzID0gW107XG4gICAgdGhpcy5iaW5kUG9saWN5TmFtZWRBdHRyaWJ1dGVzID0gW107XG4gICAgdGhpcy5iaW5kUG9saWN5Um9sZUF0dHJpYnV0ZXMgPSBbXTtcbiAgICB0aGlzLnNlcnZpY2VBcGlEYXRhID0gY2xvbmVEZWVwKHRoaXMuaW5pdFNlcnZpY2VBcGlEYXRhKTtcbiAgICB0aGlzLmludGVyY2VwdENvbmZpZ0FwaURhdGEgPSBjbG9uZURlZXAodGhpcy5pbml0SW50ZXJjZXB0Q29uZmlnQXBpRGF0YSk7XG4gICAgdGhpcy5ob3N0Q29uZmlnQXBpRGF0YSA9IGNsb25lRGVlcCh0aGlzLmluaXRIb3N0Q29uZmlnQXBpRGF0YSk7XG4gICAgdGhpcy5kaWFsUG9saWN5QXBpRGF0YSA9IGNsb25lRGVlcCh0aGlzLmluaXREaWFsUG9saWN5QXBpRGF0YSk7XG4gICAgdGhpcy5iaW5kUG9saWN5QXBpRGF0YSA9IGNsb25lRGVlcCh0aGlzLmluaXRCaW5kUG9saWN5QXBpRGF0YSk7XG4gICAgY29uc3Qgc2VydmljZVJvbGVzUHJvbWlzZSA9IHRoaXMuc2VydmljZXNQYWdlU2VydmljZS5nZXRTZXJ2aWNlUm9sZUF0dHJpYnV0ZXMoKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgIHRoaXMuc2VydmljZVJvbGVBdHRyaWJ1dGVzID0gcmVzdWx0LmRhdGE7XG4gICAgfSk7XG4gICAgY29uc3QgaWRlbnRpdHlSb2xlc1Byb21pc2UgPSB0aGlzLnNlcnZpY2VzUGFnZVNlcnZpY2UuZ2V0SWRlbnRpdHlSb2xlQXR0cmlidXRlcygpLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgdGhpcy5pZGVudGl0eVJvbGVBdHRyaWJ1dGVzID0gcmVzdWx0LmRhdGE7XG4gICAgfSk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFtzZXJ2aWNlUm9sZXNQcm9taXNlLCBpZGVudGl0eVJvbGVzUHJvbWlzZV0pLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgdGhpcy5mb3JtRGF0YVNldCA9IHRydWU7XG4gICAgICB0aGlzLmNoZWNrQWxsRGF0YUluaXQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzc29jaWF0ZWREYXRhSW5pdDogYm9vbGVhbjtcbiAgaW5pdEFzc29jaWF0ZWREYXRhKCkge1xuICAgIGlmICh0aGlzLmVudGl0aWVzSW5pdCkge1xuICAgICAgdGhpcy5kYXRhSW5pdCA9IHRydWU7XG4gICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVudGl0aWVzSW5pdCA9IHRydWU7XG4gICAgdGhpcy5zZXJ2aWNlQXBpRGF0YSA9IHRoaXMuc3ZjLmZvcm1EYXRhO1xuICAgIHRoaXMuaWRlbnRpdGllc0luaXQuc3Vic2NyaWJlKCh2YWwpID0+IHtcbiAgICAgIGlmICh2YWwgPT09IHRydWUpIHtcbiAgICAgICAgY29uc3QgY29uZmlnc1Byb21pc2UgPSB0aGlzLmdldEFzc29jaWF0ZWRDb25maWdzKCk7XG4gICAgICAgIGNvbnN0IHBvbGljaWVzUHJvbWlzZSA9IHRoaXMuZ2V0QXNzb2NhaXRlZFBvbGljaWVzKCk7XG4gICAgICAgIFByb21pc2UuYWxsKFtjb25maWdzUHJvbWlzZSwgcG9saWNpZXNQcm9taXNlXSkuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hc3NvY2lhdGVkRGF0YUluaXQgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuc2V0SW5pdERhdGEoKTtcbiAgICAgICAgICB0aGlzLmNoZWNrQWxsRGF0YUluaXQoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzZXRJbml0RGF0YSgpIHtcbiAgICB0aGlzLmluaXRTZXJ2aWNlQXBpRGF0YSA9IGNsb25lRGVlcCh0aGlzLnNlcnZpY2VBcGlEYXRhKTtcbiAgICB0aGlzLmluaXRJbnRlcmNlcHRDb25maWdBcGlEYXRhID0gY2xvbmVEZWVwKHRoaXMuaW50ZXJjZXB0Q29uZmlnQXBpRGF0YSk7XG4gICAgdGhpcy5pbml0SG9zdENvbmZpZ0FwaURhdGEgPSBjbG9uZURlZXAodGhpcy5ob3N0Q29uZmlnQXBpRGF0YSk7XG4gICAgdGhpcy5pbml0RGlhbFBvbGljeUFwaURhdGEgPSBjbG9uZURlZXAodGhpcy5kaWFsUG9saWN5QXBpRGF0YSk7XG4gICAgdGhpcy5pbml0QmluZFBvbGljeUFwaURhdGEgPSBjbG9uZURlZXAodGhpcy5iaW5kUG9saWN5QXBpRGF0YSk7XG4gICAgdGhpcy5fZGF0YUNoYW5nZSA9IGZhbHNlO1xuICB9XG5cbiAgZ2V0QXNzb2NpYXRlZENvbmZpZ3MoKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy56aXRpU2VydmljZS5nZXRTdWJkYXRhKCdzZXJ2aWNlcycsIHRoaXMuZm9ybURhdGEuaWQsICdjb25maWdzJykudGhlbigocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IGFzc29jaWF0ZWRDb25maWdzID0gcmVzdWx0LmRhdGE7XG4gICAgICBhc3NvY2lhdGVkQ29uZmlncy5mb3JFYWNoKChjb25maWcpID0+IHtcbiAgICAgICAgaWYgKGNvbmZpZy5jb25maWdUeXBlSWQgPT0gdGhpcy5pbml0SW50ZXJjZXB0Q29uZmlnQXBpRGF0YS5jb25maWdUeXBlSWQpIHtcbiAgICAgICAgICB0aGlzLmludGVyY2VwdENvbmZpZ0FwaURhdGEgPSBjb25maWc7XG4gICAgICAgICAgY29uc3QgcG9ydFJhbmdlID0gdGhpcy5pbnRlcmNlcHRDb25maWdBcGlEYXRhLmRhdGEucG9ydFJhbmdlc1swXTtcbiAgICAgICAgICB0aGlzLmludGVyY2VwdFBvcnQgPSBwb3J0UmFuZ2U/LmhpZ2g7XG4gICAgICAgIH0gZWxzZSBpZiAoY29uZmlnLmNvbmZpZ1R5cGVJZCA9PSB0aGlzLmluaXRIb3N0Q29uZmlnQXBpRGF0YS5jb25maWdUeXBlSWQpIHtcbiAgICAgICAgICB0aGlzLmhvc3RDb25maWdBcGlEYXRhID0gY29uZmlnO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldEFzc29jYWl0ZWRQb2xpY2llcygpOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnppdGlTZXJ2aWNlLmdldFN1YmRhdGEoJ3NlcnZpY2VzJywgdGhpcy5mb3JtRGF0YS5pZCwgJ3NlcnZpY2UtcG9saWNpZXMnKS50aGVuKChyZXN1bHQ6IGFueSkgPT4ge1xuICAgICAgY29uc3QgYXNzb2NpYXRlZFNlcnZpY2VQb2xpY2llcyA9IHJlc3VsdC5kYXRhO1xuICAgICAgYXNzb2NpYXRlZFNlcnZpY2VQb2xpY2llcy5mb3JFYWNoKChwb2xpY3kpID0+IHtcbiAgICAgICAgaWYgKHBvbGljeS50eXBlPy50b0xvd2VyQ2FzZSgpID09ICdkaWFsJykge1xuICAgICAgICAgIHRoaXMuZGlhbFBvbGljeUFwaURhdGEgPSBwb2xpY3k7XG4gICAgICAgICAgY29uc3Qgcm9sZUF0dHJpYnV0ZXMgPSBbXTtcbiAgICAgICAgICBjb25zdCBuYW1lZEF0dHJpYnV0ZXMgPSBbXTtcbiAgICAgICAgICBwb2xpY3kuaWRlbnRpdHlSb2xlcy5mb3JFYWNoKChhdHRyKSA9PiB7XG4gICAgICAgICAgICBpZiAoYXR0ci5jaGFyQXQoMCkgPT09ICcjJykge1xuICAgICAgICAgICAgICByb2xlQXR0cmlidXRlcy5wdXNoKGF0dHIuc2xpY2UoMSkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhdHRyLmNoYXJBdCgwKSA9PT0gJ0AnKSB7XG4gICAgICAgICAgICAgIG5hbWVkQXR0cmlidXRlcy5wdXNoKHRoaXMuaWRlbnRpdGllc0lkTmFtZU1hcFthdHRyLnNsaWNlKDEpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5kaWFsUG9saWN5Um9sZUF0dHJpYnV0ZXMgPSByb2xlQXR0cmlidXRlcztcbiAgICAgICAgICB0aGlzLmRpYWxQb2xpY3lOYW1lZEF0dHJpYnV0ZXMgPSBuYW1lZEF0dHJpYnV0ZXM7XG4gICAgICAgIH0gZWxzZSBpZiAocG9saWN5LnR5cGU/LnRvTG93ZXJDYXNlKCkgPT0gJ2JpbmQnKSB7XG4gICAgICAgICAgY29uc3Qgcm9sZUF0dHJpYnV0ZXMgPSBbXTtcbiAgICAgICAgICBjb25zdCBuYW1lZEF0dHJpYnV0ZXMgPSBbXTtcbiAgICAgICAgICBwb2xpY3kuaWRlbnRpdHlSb2xlcy5mb3JFYWNoKChhdHRyKSA9PiB7XG4gICAgICAgICAgICBpZiAoYXR0ci5jaGFyQXQoMCkgPT09ICcjJykge1xuICAgICAgICAgICAgICByb2xlQXR0cmlidXRlcy5wdXNoKGF0dHIuc2xpY2UoMSkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhdHRyLmNoYXJBdCgwKSA9PT0gJ0AnKSB7XG4gICAgICAgICAgICAgIG5hbWVkQXR0cmlidXRlcy5wdXNoKHRoaXMuaWRlbnRpdGllc0lkTmFtZU1hcFthdHRyLnNsaWNlKDEpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5iaW5kUG9saWN5Um9sZUF0dHJpYnV0ZXMgPSByb2xlQXR0cmlidXRlcztcbiAgICAgICAgICB0aGlzLmJpbmRQb2xpY3lOYW1lZEF0dHJpYnV0ZXMgPSBuYW1lZEF0dHJpYnV0ZXM7XG4gICAgICAgICAgdGhpcy5iaW5kUG9saWN5QXBpRGF0YSA9IHBvbGljeTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSlcbiAgfVxuXG4gIGdldElkZW50aXR5TmFtZWRBdHRyaWJ1dGVzKGZpbHRlcj8pIHtcbiAgICBjb25zdCBwYWdpbmcgPSB7XG4gICAgICBzZWFyY2hPbjogJ25hbWUnLFxuICAgICAgZmlsdGVyOiBmaWx0ZXIgfHwgJycsXG4gICAgICB0b3RhbDogMzAsXG4gICAgICBwYWdlOiAxLFxuICAgICAgc29ydDogJ25hbWUnLFxuICAgICAgb3JkZXI6ICdhc2MnXG4gICAgfTtcbiAgICBjb25zdCBmaWx0ZXJzID0gW107XG4gICAgaWYgKCFpc0VtcHR5KGZpbHRlcikpIHtcbiAgICAgIGZpbHRlcnMucHVzaCh7XG4gICAgICAgIGZpbHRlck5hbWU6ICduYW1lJyxcbiAgICAgICAgY29sdW1uSWQ6ICduYW1lJyxcbiAgICAgICAgdmFsdWU6IGZpbHRlciB8fCAnJScsXG4gICAgICAgIGxhYmVsOiAnJyxcbiAgICAgICAgdHlwZTogJ1RFWFRJTlBVVCcsXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy56aXRpU2VydmljZS5nZXQoJ2lkZW50aXRpZXMnLCBwYWdpbmcsIGZpbHRlcnMpLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgY29uc3QgbmFtZWRBdHRyaWJ1dGVzID0gcmVzdWx0LmRhdGEubWFwKChpZGVudGl0eSkgPT4ge1xuICAgICAgICB0aGlzLmlkZW50aXRpZXNOYW1lSWRNYXBbaWRlbnRpdHkubmFtZV0gPSBpZGVudGl0eS5pZDtcbiAgICAgICAgdGhpcy5pZGVudGl0aWVzSWROYW1lTWFwW2lkZW50aXR5LmlkXSA9IGlkZW50aXR5Lm5hbWU7XG4gICAgICAgIHJldHVybiBpZGVudGl0eS5uYW1lO1xuICAgICAgfSk7XG4gICAgICB0aGlzLmlkZW50aXR5TmFtZWRBdHRyaWJ1dGVzID0gbmFtZWRBdHRyaWJ1dGVzO1xuICAgIH0pLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgdGhpcy5pZGVudGl0aWVzSW5pdC5uZXh0KHRydWUpO1xuICAgIH0pO1xuICB9XG5cbiAgY2hlY2tBbGxEYXRhSW5pdCgpIHtcbiAgICBpZiAodGhpcy5hc3NvY2lhdGVkRGF0YUluaXQgJiYgdGhpcy5mb3JtRGF0YVNldCAmJiB0aGlzLmVudGl0eUlkSW5pdCAmJiB0aGlzLnNlcnZpY2VEYXRhU2V0KSB7XG4gICAgICB0aGlzLmRhdGFJbml0ID0gdHJ1ZTtcbiAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgbXVsdGlBY3Rpb25SZXF1ZXN0ZWQoYWN0aW9uKSB7XG4gICAgc3dpdGNoKGFjdGlvbi5pZCkge1xuICAgICAgY2FzZSAnc2F2ZSc6XG4gICAgICAgIHRoaXMuc2F2ZSgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NvbnZlcnQtdG8tYWR2YW5jZWQnOlxuICAgICAgICB0aGlzLmNvbnZlcnRUb0FkdmFuY2VkKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGhlYWRlckFjdGlvblJlcXVlc3RlZChhY3Rpb24pIHtcbiAgICBzd2l0Y2goYWN0aW9uLm5hbWUpIHtcbiAgICAgIGNhc2UgJ3NhdmUnOlxuICAgICAgICB0aGlzLnNhdmUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjbG9zZSc6XG4gICAgICAgIGlmICh0aGlzLmlzRWRpdCkge1xuICAgICAgICAgIHRoaXMucm91dGVyPy5uYXZpZ2F0ZUJ5VXJsKFVSTFMuWklUSV9TRVJWSUNFUyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5yb3V0ZXI/Lm5hdmlnYXRlQnlVcmwoVVJMUy5aSVRJX1NFUlZJQ0VfU0VMRUNUKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3RvZ2dsZS12aWV3JzpcbiAgICAgICAgdGhpcy5mb3JtVmlldyA9IGFjdGlvbi5kYXRhO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICB0b2dnbGVTZGtPbmx5RGlhbCgpIHtcbiAgICB0aGlzLnNka09ubHlEaWFsID0gIXRoaXMuc2RrT25seURpYWw7XG4gIH1cblxuICB0b2dnbGVTZGtPbmx5QmluZCgpIHtcbiAgICB0aGlzLnNka09ubHlCaW5kID0gIXRoaXMuc2RrT25seUJpbmQ7XG4gIH1cblxuICBzZXJ2aWNlTmFtZUNoYW5nZWQoZXZlbnQpIHtcbiAgICB0aGlzLmludGVyY2VwdENvbmZpZ0FwaURhdGEubmFtZSA9IGAke3RoaXMuc2VydmljZUFwaURhdGEubmFtZX0taW50ZXJjZXB0LWNvbmZpZ2BcbiAgICB0aGlzLmhvc3RDb25maWdBcGlEYXRhLm5hbWUgPSBgJHt0aGlzLnNlcnZpY2VBcGlEYXRhLm5hbWV9LWhvc3QtY29uZmlnYFxuICAgIHRoaXMuZGlhbFBvbGljeUFwaURhdGEubmFtZSA9IGAke3RoaXMuc2VydmljZUFwaURhdGEubmFtZX0tZGlhbC1wb2xpY3lgXG4gICAgdGhpcy5iaW5kUG9saWN5QXBpRGF0YS5uYW1lID0gYCR7dGhpcy5zZXJ2aWNlQXBpRGF0YS5uYW1lfS1iaW5kLXBvbGljeWBcbiAgfVxuXG4gIGludGVyY2VwdFBvcnRDaGFuZ2VkKCRldmVudCkge1xuICAgIGlmIChpc05pbCh0aGlzLmludGVyY2VwdFBvcnQpIHx8IGlzTmFOKHRoaXMuaW50ZXJjZXB0UG9ydCkpIHtcbiAgICAgIHRoaXMuaW50ZXJjZXB0Q29uZmlnQXBpRGF0YS5kYXRhLnBvcnRSYW5nZXMgPSBbXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pbnRlcmNlcHRDb25maWdBcGlEYXRhLmRhdGEucG9ydFJhbmdlc1swXSA9IHtcbiAgICAgIGhpZ2g6IHRoaXMuaW50ZXJjZXB0UG9ydCxcbiAgICAgIGxvdzogdGhpcy5pbnRlcmNlcHRQb3J0XG4gICAgfTtcbiAgfVxuXG4gIGhvc3RQcm90b2NvbHNDaGFuZ2VkKCRldmVudCkge1xuICAgIHN3aXRjaCAodGhpcy5ob3N0UHJvdG9jb2wpIHtcbiAgICAgIGNhc2UgJ2JvdGgnOlxuICAgICAgICB0aGlzLmhvc3RDb25maWdBcGlEYXRhLmRhdGEuYWxsb3dlZFByb3RvY29scyA9IFsndGNwJywgJ3VkcCddXG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhpcy5ob3N0Q29uZmlnQXBpRGF0YS5kYXRhLmFsbG93ZWRQcm90b2NvbHMgPSBbdGhpcy5ob3N0UHJvdG9jb2xdO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlKHJlZnJlc2g/KSB7XG4gICAgdGhpcy5zZXJ2aWNlQXBpRGF0YS5uYW1lID0gdGhpcy5zZXJ2aWNlQXBpRGF0YS5uYW1lLnRyaW0oKTtcbiAgICBpZiAoIXRoaXMudmFsaWRhdGUoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpc05ld1NlcnZpY2UgPSBpc0VtcHR5KHRoaXMuc2VydmljZUFwaURhdGE/LmlkKTtcbiAgICBpZiAoaXNOZXdTZXJ2aWNlKSB7XG4gICAgICBjb25zdCBoYXNDb25mbGljdHM6IGFueSA9IGF3YWl0IHRoaXMuY2hlY2tOYW1lQ29uZmxpY3RzKCk7XG4gICAgICBpZiAoaGFzQ29uZmxpY3RzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzdW1tYXJ5RGF0YSA9IHRoaXMuc2hvd1N1bW1hcnkoKTtcbiAgICB0aGlzLnNlcnZpY2VBcGlEYXRhLmNvbmZpZ3MgPSBbXTtcblxuICAgIGNvbnN0IGludGVyY2VwdENmZ1Byb21pc2UgPSBhd2FpdCB0aGlzLnNhdmVJbnRlcmNlcHRDb25maWcoc3VtbWFyeURhdGEpO1xuICAgIGNvbnN0IGhvc3RDZmdQcm9taXNlID0gYXdhaXQgdGhpcy5zYXZlSG9zdENvbmZpZyhzdW1tYXJ5RGF0YSk7XG4gICAgY29uc3Qgc2VydmljZVByb21pc2UgPSBhd2FpdCB0aGlzLnNhdmVTZXJ2aWNlKHN1bW1hcnlEYXRhKTtcbiAgICBjb25zdCBkaWFsUG9saWN5UHJvbWlzZSA9IGF3YWl0IHRoaXMuc2F2ZVBvbGljeShzdW1tYXJ5RGF0YSwgJ0RpYWwnKTtcbiAgICBjb25zdCBiaW5kUG9saWN5UHJvbWlzZSA9IGF3YWl0IHRoaXMuc2F2ZVBvbGljeShzdW1tYXJ5RGF0YSwgJ0JpbmQnKTtcblxuICAgIHN1bW1hcnlEYXRhPy5mb3JFYWNoKChlbnRpdHlUeXBlKSA9PiB7XG4gICAgICBlbnRpdHlUeXBlLmVudGl0aWVzPy5mb3JFYWNoKChlbnRpdHkpID0+IHtcbiAgICAgICAgaWYgKGVudGl0eS50eXBlID09PSAnc2VydmljZXMnKSB7XG4gICAgICAgICAgZW50aXR5LmNsaUNvbW1hbmQgPSB0aGlzLnNlcnZpY2VDbGlDb21tYW5kO1xuICAgICAgICAgIGVudGl0eS5hcGlSZXF1ZXN0ID0gdGhpcy5nZXRTZXJ2aWNlc0FwaVJlcXVlc3QoKTtcbiAgICAgICAgfSBlbHNlIGlmIChlbnRpdHkudHlwZSA9PT0gJ2NvbmZpZ3MnICYmIGVudGl0eS5zdWJ0eXBlID09PSAnaW50ZXJjZXB0Jykge1xuICAgICAgICAgIGVudGl0eS5jbGlDb21tYW5kID0gdGhpcy5pbnRlcmNlcHRDb25maWdDbGlDb21tYW5kO1xuICAgICAgICAgIGVudGl0eS5hcGlSZXF1ZXN0ID0gdGhpcy5nZXRJbnRlcmNlcHRDb25maWdBcGlSZXF1ZXN0KCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZW50aXR5LnR5cGUgPT09ICdjb25maWdzJyAmJiBlbnRpdHkuc3VidHlwZSA9PT0gJ2hvc3QnKSB7XG4gICAgICAgICAgZW50aXR5LmNsaUNvbW1hbmQgPSB0aGlzLmhvc3RDb25maWdDbGlDb21tYW5kO1xuICAgICAgICAgIGVudGl0eS5hcGlSZXF1ZXN0ID0gdGhpcy5nZXRIb3N0Q29uZmlnQXBpUmVxdWVzdCgpO1xuICAgICAgICB9IGVsc2UgaWYgKGVudGl0eS50eXBlID09PSAnc2VydmljZS1wb2xpY2llcycgJiYgZW50aXR5LnN1YnR5cGUgPT09ICdkaWFsJykge1xuICAgICAgICAgIGVudGl0eS5jbGlDb21tYW5kID0gdGhpcy5kaWFsUG9saWN5Q2xpQ29tbWFuZDtcbiAgICAgICAgICBlbnRpdHkuYXBpUmVxdWVzdCA9IHRoaXMuZ2V0RGlhbEFwaVJlcXVlc3QoKTtcbiAgICAgICAgfSBlbHNlIGlmIChlbnRpdHkudHlwZSA9PT0gJ3NlcnZpY2UtcG9saWNpZXMnICYmIGVudGl0eS5zdWJ0eXBlID09PSAnYmluZCcpIHtcbiAgICAgICAgICBlbnRpdHkuY2xpQ29tbWFuZCA9IHRoaXMuYmluZFBvbGljeUNsaUNvbW1hbmQ7XG4gICAgICAgICAgZW50aXR5LmFwaVJlcXVlc3QgPSB0aGlzLmdldEJpbmRBcGlSZXF1ZXN0KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgc2hvd1N1bW1hcnkoKSB7XG4gICAgY29uc3QgaW50ZXJjZXB0U3VtbWFyeSA9IHtcbiAgICAgIG5hbWU6IHRoaXMuaW50ZXJjZXB0Q29uZmlnQXBpRGF0YS5uYW1lLFxuICAgICAgdHlwZTogJ2NvbmZpZ3MnLFxuICAgICAgc3VidHlwZTogJ2ludGVyY2VwdCcsXG4gICAgICBhcGlEYXRhOiB0aGlzLmludGVyY2VwdENvbmZpZ0FwaURhdGEsXG4gICAgICBjbGlDb21tYW5kOiB0aGlzLmludGVyY2VwdENvbmZpZ0NsaUNvbW1hbmQsXG4gICAgICBhcGlSZXF1ZXN0OiAnJyxcbiAgICAgIGFwaVVybDogdGhpcy5pbnRlcmNlcHRDb25maWdBcGlVcmwsXG4gICAgICBzdGF0dXM6ICdsb2FkaW5nJyxcbiAgICAgIHJldHJ5OiB0aGlzLnNhdmVJbnRlcmNlcHRDb25maWcuYmluZCh0aGlzKSxcbiAgICB9O1xuICAgIGNvbnN0IGhvc3RTdW1tYXJ5ID0ge1xuICAgICAgbmFtZTogdGhpcy5ob3N0Q29uZmlnQXBpRGF0YS5uYW1lLFxuICAgICAgdHlwZTogJ2NvbmZpZ3MnLFxuICAgICAgc3VidHlwZTogJ2hvc3QnLFxuICAgICAgYXBpRGF0YTogdGhpcy5ob3N0Q29uZmlnQXBpRGF0YSxcbiAgICAgIGNsaUNvbW1hbmQ6IHRoaXMuaG9zdENvbmZpZ0NsaUNvbW1hbmQsXG4gICAgICBhcGlSZXF1ZXN0OiAnJyxcbiAgICAgIGFwaVVybDogdGhpcy5ob3N0Q29uZmlnQXBpVXJsLFxuICAgICAgc3RhdHVzOiAnbG9hZGluZycsXG4gICAgICByZXRyeTogdGhpcy5zYXZlSG9zdENvbmZpZy5iaW5kKHRoaXMpXG4gICAgfTtcbiAgICBjb25zdCBzdW1tYXJ5RGF0YTogYW55ID0gW1xuICAgICAge1xuICAgICAgICB0aXRsZTogJ1NlcnZpY2VzJyxcbiAgICAgICAgZW50aXRpZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiB0aGlzLnNlcnZpY2VBcGlEYXRhLm5hbWUsXG4gICAgICAgICAgICB0eXBlOiAnc2VydmljZXMnLFxuICAgICAgICAgICAgYXBpRGF0YTogdGhpcy5zZXJ2aWNlQXBpRGF0YSxcbiAgICAgICAgICAgIGNsaUNvbW1hbmQ6IHRoaXMuc2VydmljZUNsaUNvbW1hbmQsXG4gICAgICAgICAgICBhcGlSZXF1ZXN0OiAnJyxcbiAgICAgICAgICAgIGFwaVVybDogdGhpcy5zZXJ2aWNlQXBpVXJsLFxuICAgICAgICAgICAgc3RhdHVzOiAnbG9hZGluZycsXG4gICAgICAgICAgICByZXRyeTogdGhpcy5zYXZlU2VydmljZS5iaW5kKHRoaXMpXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0aXRsZTogJ1NlcnZpY2UgUG9saWNpZXMnLFxuICAgICAgICBlbnRpdGllczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6IHRoaXMuZGlhbFBvbGljeUFwaURhdGEubmFtZSxcbiAgICAgICAgICAgIHR5cGU6ICdzZXJ2aWNlLXBvbGljaWVzJyxcbiAgICAgICAgICAgIHN1YnR5cGU6ICdkaWFsJyxcbiAgICAgICAgICAgIGFwaURhdGE6IHRoaXMuZGlhbFBvbGljeUFwaURhdGEsXG4gICAgICAgICAgICBjbGlDb21tYW5kOiB0aGlzLmRpYWxQb2xpY3lDbGlDb21tYW5kLFxuICAgICAgICAgICAgYXBpUmVxdWVzdDogJycsXG4gICAgICAgICAgICBhcGlVcmw6IHRoaXMuZGlhbFBvbGljeUFwaVVybCxcbiAgICAgICAgICAgIHN0YXR1czogJ2xvYWRpbmcnLFxuICAgICAgICAgICAgcmV0cnk6IChzdW1tYXJ5RGF0YSkgPT4geyB0aGlzLnNhdmVQb2xpY3koc3VtbWFyeURhdGEsICdEaWFsJykgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogdGhpcy5iaW5kUG9saWN5QXBpRGF0YS5uYW1lLFxuICAgICAgICAgICAgdHlwZTogJ3NlcnZpY2UtcG9saWNpZXMnLFxuICAgICAgICAgICAgc3VidHlwZTogJ2JpbmQnLFxuICAgICAgICAgICAgYXBpRGF0YTogdGhpcy5iaW5kUG9saWN5QXBpRGF0YSxcbiAgICAgICAgICAgIGNsaUNvbW1hbmQ6IHRoaXMuYmluZFBvbGljeUNsaUNvbW1hbmQsXG4gICAgICAgICAgICBhcGlSZXF1ZXN0OiAnJyxcbiAgICAgICAgICAgIGFwaVVybDogdGhpcy5iaW5kUG9saWN5QXBpVXJsLFxuICAgICAgICAgICAgc3RhdHVzOiAnbG9hZGluZycsXG4gICAgICAgICAgICByZXRyeTogKHN1bW1hcnlEYXRhKSA9PiB7IHRoaXMuc2F2ZVBvbGljeShzdW1tYXJ5RGF0YSwgJ0JpbmQnKSB9XG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9XG4gICAgXTtcbiAgICBpZiAoIXRoaXMuc2RrT25seURpYWwgJiYgIXRoaXMuc2RrT25seUJpbmQpIHtcbiAgICAgIHN1bW1hcnlEYXRhLnNwbGljZSgwLDAse1xuICAgICAgICB0aXRsZTogJ0NvbmZpZ3VyYXRpb25zJyxcbiAgICAgICAgZW50aXRpZXM6IFtpbnRlcmNlcHRTdW1tYXJ5LCBob3N0U3VtbWFyeV1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoIXRoaXMuc2RrT25seURpYWwpIHtcbiAgICAgIHN1bW1hcnlEYXRhLnNwbGljZSgwLDAse1xuICAgICAgICB0aXRsZTogJ0NvbmZpZ3VyYXRpb25zJyxcbiAgICAgICAgZW50aXRpZXM6IFtpbnRlcmNlcHRTdW1tYXJ5XVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICghdGhpcy5zZGtPbmx5QmluZCkge1xuICAgICAgc3VtbWFyeURhdGEuc3BsaWNlKDAsMCx7XG4gICAgICAgIHRpdGxlOiAnQ29uZmlndXJhdGlvbnMnLFxuICAgICAgICBlbnRpdGllczogW2hvc3RTdW1tYXJ5XVxuICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBzdW1tYXJ5RGF0YTogc3VtbWFyeURhdGEsXG4gICAgICBpc0VkaXQ6IHRoaXMuaXNFZGl0XG4gICAgfTtcbiAgICB0aGlzLmRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nRm9ybS5vcGVuKENyZWF0aW9uU3VtbWFyeURpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgZGF0YTogZGF0YSxcbiAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgfSk7XG4gICAgdGhpcy5kaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoKHJlc3VsdCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdCA9PT0gJ25ldycpIHtcbiAgICAgICAgdGhpcy5pbml0Rm9ybURhdGEoKTtcbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0ID09PSAnY2FuY2VsJykge1xuICAgICAgICAvLy8gRG8gbm90aGluZywgc3RheSBvbiBwYWdlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmluaXREYXRhTW9kZWxzKCk7XG4gICAgICAgIHRoaXMuX2RhdGFDaGFuZ2UgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yb3V0ZXI/Lm5hdmlnYXRlQnlVcmwoYCR7dGhpcy5iYXNlUGF0aH1gKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gc3VtbWFyeURhdGE7XG4gIH1cblxuICBhc3luYyBjaGVja05hbWVDb25mbGljdHMoKSB7XG4gICAgY29uc3QgZmlsdGVyOiBGaWx0ZXJPYmogPSB7XG4gICAgICBmaWx0ZXJOYW1lOiAnbmFtZScsXG4gICAgICBjb2x1bW5JZDogJ25hbWUnLFxuICAgICAgdmFsdWU6IHRoaXMuc2VydmljZUFwaURhdGEubmFtZSxcbiAgICAgIGxhYmVsOiAnJyxcbiAgICAgIHR5cGU6ICdURVhUSU5QVVQnLFxuICAgICAgaGlkZGVuOiBmYWxzZSxcbiAgICAgIHZlcmI6ICc9J1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdHM6IGFueSA9IHtcbiAgICAgIHNlcnZpY2VDb25mbGljdDogZmFsc2UsXG4gICAgICBpbnRlcmNlcHRDb25mbGljdDogZmFsc2UsXG4gICAgICBob3N0Q29uZmxpY3Q6IGZhbHNlLFxuICAgICAgZGlhbFBvbGljeUNvbmZsaWN0OiBmYWxzZSxcbiAgICAgIGJpbmRQb2xpY3lDb25mbGljdDogZmFsc2UsXG4gICAgICBuYW1lczogW11cbiAgICB9O1xuICAgIGNvbnN0IHBhZ2luZyA9IGNsb25lRGVlcCh0aGlzLnppdGlTZXJ2aWNlLkRFRkFVTFRfUEFHSU5HKTtcbiAgICBwYWdpbmcubm9TZWFyY2ggPSBmYWxzZTtcbiAgICBjb25zdCBzZXJ2aWNlUHJvbSA9IHRoaXMueml0aVNlcnZpY2UuZ2V0KCdzZXJ2aWNlcycsIHBhZ2luZywgW2ZpbHRlcl0pLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdC5kYXRhPy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJlc3VsdHMuc2VydmljZUNvbmZsaWN0ID0gdHJ1ZTtcbiAgICAgICAgcmVzdWx0cy5uYW1lcy5wdXNoKHRoaXMuc2VydmljZUFwaURhdGEubmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZmlsdGVyLnZhbHVlID0gdGhpcy5pbnRlcmNlcHRDb25maWdBcGlEYXRhLm5hbWU7XG4gICAgY29uc3QgaW50ZXJjZXB0UHJvbSA9IHRoaXMueml0aVNlcnZpY2UuZ2V0KCdjb25maWdzJywgcGFnaW5nLCBbZmlsdGVyXSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICBpZiAocmVzdWx0LmRhdGE/Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVzdWx0cy5pbnRlcmNlcHRDb25mbGljdCA9IHRydWU7XG4gICAgICAgIHJlc3VsdHMubmFtZXMucHVzaCh0aGlzLmludGVyY2VwdENvbmZpZ0FwaURhdGEubmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZmlsdGVyLnZhbHVlID0gdGhpcy5ob3N0Q29uZmlnQXBpRGF0YS5uYW1lO1xuICAgIGNvbnN0IGhvc3RQcm9tID0gdGhpcy56aXRpU2VydmljZS5nZXQoJ2NvbmZpZ3MnLCBwYWdpbmcsIFtmaWx0ZXJdKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgIGlmIChyZXN1bHQuZGF0YT8ubGVuZ3RoID4gMCkge1xuICAgICAgICByZXN1bHRzLmhvc3RDb25mbGljdCA9IHRydWU7XG4gICAgICAgIHJlc3VsdHMubmFtZXMucHVzaCh0aGlzLmhvc3RDb25maWdBcGlEYXRhLm5hbWUpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGZpbHRlci52YWx1ZSA9IHRoaXMuZGlhbFBvbGljeUFwaURhdGEubmFtZTtcbiAgICBjb25zdCBkaWFsUHJvbSA9IHRoaXMueml0aVNlcnZpY2UuZ2V0KCdzZXJ2aWNlLXBvbGljaWVzJywgcGFnaW5nLCBbZmlsdGVyXSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICBpZiAocmVzdWx0LmRhdGE/Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVzdWx0cy5kaWFsUG9saWN5Q29uZmxpY3QgPSB0cnVlO1xuICAgICAgICByZXN1bHRzLm5hbWVzLnB1c2godGhpcy5kaWFsUG9saWN5QXBpRGF0YS5uYW1lKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBmaWx0ZXIudmFsdWUgPSB0aGlzLmJpbmRQb2xpY3lBcGlEYXRhLm5hbWU7XG4gICAgY29uc3QgYmluZFByb20gPSB0aGlzLnppdGlTZXJ2aWNlLmdldCgnc2VydmljZS1wb2xpY2llcycsIHBhZ2luZywgW2ZpbHRlcl0pLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdC5kYXRhPy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJlc3VsdHMuYmluZFBvbGljeUNvbmZsaWN0ID0gdHJ1ZTtcbiAgICAgICAgcmVzdWx0cy5uYW1lcy5wdXNoKHRoaXMuYmluZFBvbGljeUFwaURhdGEubmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoW3NlcnZpY2VQcm9tLCBpbnRlcmNlcHRQcm9tLCBob3N0UHJvbSwgZGlhbFByb20sIGJpbmRQcm9tXSkudGhlbigoKSA9PiB7XG4gICAgICBsZXQgaGFzQ29uZmxpY3QgPSByZXN1bHRzLm5hbWVzLmxlbmd0aCA+IDA7XG4gICAgICBpZiAoaGFzQ29uZmxpY3QpIHtcbiAgICAgICAgdGhpcy5lcnJvcnMubmFtZSA9IHRydWU7XG4gICAgICAgIHRoaXMuc2hvd0NvbmZsaWN0V2FybmluZyhyZXN1bHRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBoYXNDb25mbGljdDtcbiAgICB9KTtcbiAgfVxuXG4gIHNob3dDb25mbGljdFdhcm5pbmcoY29uZmxpY3REYXRhKSB7XG5cbiAgICBjb25zdCBkYXRhID0ge1xuICAgICAgYXBwZW5kSWQ6ICdTaW1wbGVTZXJ2aWNlQ29uZmxpY3RzJyxcbiAgICAgIHRpdGxlOiAnTmFtZSBDb25mbGljdCcsXG4gICAgICBtZXNzYWdlOiBgVGhlIG5hbWUgeW91IGhhdmUgZW50ZXJlZCBoYXMgY29uZmxpY3RzIGZvciB0aGUgZm9sbG93aW5nIGVudGl0aWVzYCxcbiAgICAgIGJ1bGxldExpc3Q6IGNvbmZsaWN0RGF0YS5uYW1lcyxcbiAgICAgIHN1Ym1lc3NhZ2U6IGBQbGVhc2UgdXBkYXRlIHRoZSBlbnRlcmVkIG5hbWUgYW5kIHRyeSBhZ2Fpbi5gLFxuICAgICAgY29uZmlybUxhYmVsOiAnUmV0dXJuJyxcbiAgICAgIHNob3dDYW5jZWxMaW5rOiBmYWxzZSxcbiAgICAgIGltYWdlVXJsOiAnLi4vLi4vYXNzZXRzL3N2Z3MvR3Jvd2xfRXJyb3Iuc3ZnJ1xuICAgIH07XG4gICAgdGhpcy5kaWFsb2dSZWYgPSB0aGlzLmRpYWxvZ0Zvcm0ub3BlbihDb25maXJtQ29tcG9uZW50LCB7XG4gICAgICBkYXRhOiBkYXRhLFxuICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICB9KTtcbiAgICB0aGlzLmRpYWxvZ1JlZi5hZnRlckNsb3NlZCgoKSA9PiB7XG4gICAgICB0aGlzLm5hbWVGaWVsZElucHV0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICB9KVxuICB9XG5cbiAgYXN5bmMgc2F2ZUludGVyY2VwdENvbmZpZyhzdW1tYXJ5RGF0YSkge1xuICAgIGNvbnN0IGlzTmV3Q29uZmlnID0gaXNFbXB0eSh0aGlzLmludGVyY2VwdENvbmZpZ0FwaURhdGE/LmlkKTtcblxuICAgIC8vIENvbmRpdGlvbmFsIERlbGV0aW9uIChJZGVudGljYWwgTG9naWMpXG4gICAgaWYgKHRoaXMuc2RrT25seURpYWwgJiYgIWlzTmV3Q29uZmlnKSB7XG4gICAgICByZXR1cm4gdGhpcy56aXRpU2VydmljZS5kZWxldGUoJ2NvbmZpZ3MnLCB0aGlzLmludGVyY2VwdENvbmZpZ0FwaURhdGEuaWQpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zZGtPbmx5RGlhbCAmJiBpc05ld0NvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFVzZSB0aGUgSGVscGVyIEZ1bmN0aW9uXG4gICAgY29uc3QgeyBzdGF0dXMgfSA9IGF3YWl0IHRoaXMuc2F2ZUNvbmZpZyhcbiAgICAgICAgdGhpcy5pbnRlcmNlcHRDb25maWdBcGlEYXRhLFxuICAgICAgICAnaW50ZXJjZXB0SW5jcmVtZW50JyxcbiAgICAgICAgJ2ludGVyY2VwdENvbmZpZ0lkJyxcbiAgICAgICAgJ2ludGVyY2VwdENvbmZpZ0NsaUNvbW1hbmQnXG4gICAgKTtcblxuICAgIC8vIEFwcGx5IGZpbmFsIHN0YXR1cyBsb2dpY1xuICAgIHN1bW1hcnlEYXRhWzBdLmVudGl0aWVzWzBdLnN0YXR1cyA9IHN0YXR1cztcbiAgfVxuXG4gIGFzeW5jIHNhdmVIb3N0Q29uZmlnKHN1bW1hcnlEYXRhKSB7XG4gICAgY29uc3QgaXNOZXdDb25maWcgPSBpc0VtcHR5KHRoaXMuaG9zdENvbmZpZ0FwaURhdGE/LmlkKTtcblxuICAgIC8vIENvbmRpdGlvbmFsIERlbGV0aW9uIChJZGVudGljYWwgTG9naWMpXG4gICAgaWYgKHRoaXMuc2RrT25seURpYWwgJiYgIWlzTmV3Q29uZmlnKSB7XG4gICAgICByZXR1cm4gdGhpcy56aXRpU2VydmljZS5kZWxldGUoJ2NvbmZpZ3MnLCB0aGlzLmhvc3RDb25maWdBcGlEYXRhLmlkKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc2RrT25seURpYWwgJiYgaXNOZXdDb25maWcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBVc2UgdGhlIEhlbHBlciBGdW5jdGlvblxuICAgIGNvbnN0IHsgc3RhdHVzLCBjb25maWdBcGlEYXRhIH0gPSBhd2FpdCB0aGlzLnNhdmVDb25maWcoXG4gICAgICAgIHRoaXMuaG9zdENvbmZpZ0FwaURhdGEsXG4gICAgICAgICdob3N0SW5jcmVtZW50JyxcbiAgICAgICAgJ2hvc3RDb25maWdJZCcsXG4gICAgICAgICdob3N0Q29uZmlnQ2xpQ29tbWFuZCdcbiAgICApO1xuXG4gICAgLy8gQXBwbHkgZmluYWwgc3RhdHVzIGxvZ2ljIChzbGlnaHRseSBkaWZmZXJlbnQgdGhhbiBpbnRlcmNlcHQpXG4gICAgaWYgKHRoaXMuc2RrT25seURpYWwpIHtcbiAgICAgIHN1bW1hcnlEYXRhWzBdLmVudGl0aWVzWzBdLnN0YXR1cyA9IHN0YXR1cztcbiAgICAgIHN1bW1hcnlEYXRhWzBdLmVudGl0aWVzWzBdLmFwaURhdGEgPSBjb25maWdBcGlEYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdW1tYXJ5RGF0YVswXS5lbnRpdGllc1sxXS5zdGF0dXMgPSBzdGF0dXM7XG4gICAgICBzdW1tYXJ5RGF0YVswXS5lbnRpdGllc1swXS5hcGlEYXRhID0gY29uZmlnQXBpRGF0YTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlQ29uZmlnKFxuICAgICAgY29uZmlnQXBpRGF0YTogYW55LCAgICAgIC8vIGUuZy4sIHRoaXMuaW50ZXJjZXB0Q29uZmlnQXBpRGF0YVxuICAgICAgaW5jcmVtZW50ZXI6IHN0cmluZywgICAgIC8vIFRoZSBuYW1lIG9mIHRoZSBpbmNyZW1lbnRlciBwcm9wZXJ0eSAoJ2ludGVyY2VwdEluY3JlbWVudCcgb3IgJ2hvc3RJbmNyZW1lbnQnKVxuICAgICAgY29uZmlnSWRQcm9wOiBzdHJpbmcsICAgIC8vIFRoZSBuYW1lIG9mIHRoZSBJRCBwcm9wZXJ0eSAoJ2ludGVyY2VwdENvbmZpZ0lkJyBvciAnaG9zdENvbmZpZ0lkJylcbiAgICAgIGNsaUNvbW1hbmRQcm9wOiBzdHJpbmcgICAvLyBUaGUgbmFtZSBvZiB0aGUgQ0xJIGNvbW1hbmQgcHJvcGVydHkgKCdpbnRlcmNlcHRDb25maWdDbGlDb21tYW5kJyBvciAnaG9zdENvbmZpZ0NsaUNvbW1hbmQnKVxuICApOiBQcm9taXNlPGFueT4ge1xuXG4gICAgY29uc3QgaXNOZXdDb25maWcgPSBpc0VtcHR5KGNvbmZpZ0FwaURhdGE/LmlkKTtcbiAgICBjb25zdCBpbmNyZW1lbnRWYWx1ZSA9IHRoaXNbaW5jcmVtZW50ZXJdIGFzIG51bWJlcjsgLy8gR2V0IGN1cnJlbnQgaW5jcmVtZW50IHZhbHVlXG4gICAgbGV0IHN0YXR1czogc3RyaW5nO1xuICAgIGxldCBjb25maWdSZXN1bHQ6IGFueTtcblxuICAgIGlmIChpc05ld0NvbmZpZykge1xuICAgICAgdGhpc1tpbmNyZW1lbnRlcl0gPSBpbmNyZW1lbnRWYWx1ZSArIDE7IC8vIEluY3JlbWVudCBmb3IgbmFtaW5nXG5cbiAgICAgIGxldCBwb3N0Rml4ID0gJyc7XG4gICAgICBpZiAodGhpc1tpbmNyZW1lbnRlcl0gPiAwKSB7XG4gICAgICAgIHBvc3RGaXggPSAnXycgKyB0aGlzW2luY3JlbWVudGVyXTtcbiAgICAgIH1cblxuICAgICAgY29uZmlnQXBpRGF0YS5uYW1lID0gY29uZmlnQXBpRGF0YS5uYW1lICsgcG9zdEZpeDtcblxuICAgICAgY29uZmlnUmVzdWx0ID0gYXdhaXQgdGhpcy5zYXZlRW50aXR5KCdjb25maWdzJywgY29uZmlnQXBpRGF0YSkuY2F0Y2goKHJlc3VsdCkgPT4gcmVzdWx0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uZmlnUmVzdWx0ID0gYXdhaXQgdGhpcy51cGRhdGVFbnRpdHkoJ2NvbmZpZ3MnLCBjb25maWdBcGlEYXRhKS5jYXRjaCgocmVzdWx0KSA9PiByZXN1bHQpO1xuICAgIH1cblxuICAgIGlmIChjb25maWdSZXN1bHQuZXJyb3IpIHtcbiAgICAgIHN0YXR1cyA9ICdlcnJvcic7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFNldCB0aGUgY29uZmlnIElEIHByb3BlcnR5IGR5bmFtaWNhbGx5IChlLmcuLCB0aGlzLmludGVyY2VwdENvbmZpZ0lkKVxuICAgICAgdGhpc1tjb25maWdJZFByb3BdID0gY29uZmlnQXBpRGF0YS5pZCB8fCBjb25maWdSZXN1bHQuaWQgfHwgY29uZmlnUmVzdWx0LmRhdGEuaWQ7XG5cbiAgICAgIC8vIEFkZCB0aGUgbmV3IGNvbmZpZyBJRCB0byBzZXJ2aWNlQXBpRGF0YSAoYXNzdW1pbmcgc2VydmljZUFwaURhdGEgaXMgYWNjZXNzaWJsZSB2aWEgJ3RoaXMnKVxuICAgICAgdGhpcy5zZXJ2aWNlQXBpRGF0YS5jb25maWdzLnB1c2godGhpc1tjb25maWdJZFByb3BdKTtcblxuICAgICAgLy8gU2V0IHRoZSBDTEkgY29tbWFuZCBkeW5hbWljYWxseVxuICAgICAgdGhpc1tjbGlDb21tYW5kUHJvcF0gPSBgeml0aSBlZGdlIGNyZWF0ZSBjb25maWcgJyR7Y29uZmlnQXBpRGF0YS5uYW1lfScgJyR7Y29uZmlnQXBpRGF0YS5jb25maWdUeXBlSWR9JyAnJHtKU09OLnN0cmluZ2lmeShjb25maWdBcGlEYXRhLmRhdGEpfSdgO1xuXG4gICAgICBzdGF0dXMgPSAnZG9uZSc7XG4gICAgICB0aGlzW2luY3JlbWVudGVyXSA9IC0xOyAvLyBSZXNldCBpbmNyZW1lbnRlclxuICAgIH1cblxuICAgIHJldHVybiB7IHN0YXR1cywgY29uZmlnUmVzdWx0LCBjb25maWdBcGlEYXRhIH07XG4gIH1cblxuICBhc3luYyBzYXZlU2VydmljZShzdW1tYXJ5RGF0YSkge1xuICAgIGNvbnN0IGlzTmV3U2VydmljZSA9IGlzRW1wdHkodGhpcy5zZXJ2aWNlQXBpRGF0YT8uaWQpO1xuXG4gICAgbGV0IHNlcnZpY2VSZXN1bHQ7XG4gICAgaWYgKGlzTmV3U2VydmljZSkge1xuICAgICAgdGhpcy5zZXJ2aWNlSW5jcmVtZW50Kys7XG4gICAgICBsZXQgcG9zdEZpeCA9ICcnO1xuICAgICAgaWYgKHRoaXMuc2VydmljZUluY3JlbWVudCA+IDApIHtcbiAgICAgICAgcG9zdEZpeCA9ICdfJyArIHRoaXMuc2VydmljZUluY3JlbWVudDtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2VydmljZUFwaURhdGEubmFtZSA9IHRoaXMuc2VydmljZUFwaURhdGEubmFtZSArIHBvc3RGaXg7XG4gICAgICBzZXQodGhpcy5zZXJ2aWNlQXBpRGF0YSwgJ3RhZ3Muc2VydmljZS10eXBlJywgJ3NpbXBsZScpO1xuICAgICAgc2VydmljZVJlc3VsdCA9IGF3YWl0IHRoaXMuc2F2ZUVudGl0eSgnc2VydmljZXMnLCB0aGlzLnNlcnZpY2VBcGlEYXRhKS5jYXRjaCgocmVzdWx0KSA9PiB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VydmljZVJlc3VsdCA9IGF3YWl0IHRoaXMudXBkYXRlRW50aXR5KCdzZXJ2aWNlcycsIHRoaXMuc2VydmljZUFwaURhdGEpLmNhdGNoKChyZXN1bHQpID0+IHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCBzZXJ2aWNlU3RhdHVzO1xuICAgIGlmIChzZXJ2aWNlUmVzdWx0LmVycm9yKSB7XG4gICAgICBzZXJ2aWNlU3RhdHVzID0gJ2Vycm9yJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXJ2aWNlSWQgPSB0aGlzLnNlcnZpY2VBcGlEYXRhLmlkID8gdGhpcy5zZXJ2aWNlQXBpRGF0YS5pZCA6IChzZXJ2aWNlUmVzdWx0LmlkID8gc2VydmljZVJlc3VsdC5pZCA6IHNlcnZpY2VSZXN1bHQuZGF0YS5pZCk7XG4gICAgICBzZXJ2aWNlU3RhdHVzID0gJ2RvbmUnO1xuICAgICAgbGV0IGNsaUNvbmZpZ0lkcyA9ICcnO1xuICAgICAgaWYgKCF0aGlzLnNka09ubHlEaWFsICYmICF0aGlzLnNka09ubHlCaW5kKSB7XG4gICAgICAgIGNsaUNvbmZpZ0lkcyA9IGAtLWNvbmZpZ3MgJyR7dGhpcy5pbnRlcmNlcHRDb25maWdJZH0sJHt0aGlzLmhvc3RDb25maWdJZH0nYDtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMuc2RrT25seUJpbmQgJiYgdGhpcy5zZGtPbmx5QmluZCkge1xuICAgICAgICBjbGlDb25maWdJZHMgPSBgLS1jb25maWdzICcke3RoaXMuaW50ZXJjZXB0Q29uZmlnSWR9J2A7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc2RrT25seUJpbmQgJiYgIXRoaXMuc2RrT25seUJpbmQpIHtcbiAgICAgICAgY2xpQ29uZmlnSWRzID0gYC0tY29uZmlncyAnJHt0aGlzLmludGVyY2VwdENvbmZpZ0lkfSdgO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXJ2aWNlQ2xpQ29tbWFuZCA9IGB6aXRpIGVkZ2UgY3JlYXRlIHNlcnZpY2UgJyR7dGhpcy5zZXJ2aWNlQXBpRGF0YS5uYW1lfScgJHtjbGlDb25maWdJZHN9YFxuICAgICAgdGhpcy5zZXJ2aWNlSW5jcmVtZW50ID0gLTE7XG4gICAgfVxuICAgIGNvbnN0IHN1bW1hcnlJbmRleCA9ICh0aGlzLnNka09ubHlEaWFsICYmIHRoaXMuc2RrT25seUJpbmQpID8gMCA6IDE7XG4gICAgc3VtbWFyeURhdGFbc3VtbWFyeUluZGV4XS5lbnRpdGllc1swXS5zdGF0dXMgPSBzZXJ2aWNlU3RhdHVzO1xuICB9XG5cbiAgYXN5bmMgc2F2ZVBvbGljeShzdW1tYXJ5RGF0YSwgdHlwZSA9ICdEaWFsJykge1xuICAgIGNvbnN0IGlzTmV3UG9saWN5ID0gaXNFbXB0eSh0aGlzLnNlcnZpY2VBcGlEYXRhPy5pZCk7XG5cbiAgICBsZXQgcG9saWN5QXBpRGF0YSwgcG9saWN5UmVzdWx0LCByb2xlQXR0cmlidXRlcywgbmFtZWRBdHRyaWJ1dGVzO1xuICAgIGxldCBjbGlSb2xlcyA9ICcnO1xuICAgIGxldCBzdGF0dXMgPSAnJztcbiAgICBpZiAoaXNOZXdQb2xpY3kpIHtcbiAgICAgIGlmICh0eXBlID09PSAnRGlhbCcpIHtcbiAgICAgICAgdGhpcy5kaWFsSW5jcmVtZW50Kys7XG4gICAgICAgIGxldCBwb3N0Rml4ID0gJyc7XG4gICAgICAgIGlmICh0aGlzLmRpYWxJbmNyZW1lbnQgPiAwKSB7XG4gICAgICAgICAgcG9zdEZpeCA9ICdfJyArIHRoaXMuZGlhbEluY3JlbWVudDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpYWxQb2xpY3lBcGlEYXRhLm5hbWUgPSB0aGlzLmRpYWxQb2xpY3lBcGlEYXRhLm5hbWUgKyBwb3N0Rml4O1xuICAgICAgICBwb2xpY3lBcGlEYXRhID0gdGhpcy5kaWFsUG9saWN5QXBpRGF0YTtcbiAgICAgICAgcm9sZUF0dHJpYnV0ZXMgPSB0aGlzLmRpYWxQb2xpY3lSb2xlQXR0cmlidXRlcztcbiAgICAgICAgbmFtZWRBdHRyaWJ1dGVzID0gdGhpcy5kaWFsUG9saWN5TmFtZWRBdHRyaWJ1dGVzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5iaW5kSW5jcmVtZW50Kys7XG4gICAgICAgIGxldCBwb3N0Rml4ID0gJyc7XG4gICAgICAgIGlmICh0aGlzLmJpbmRJbmNyZW1lbnQgPiAwKSB7XG4gICAgICAgICAgcG9zdEZpeCA9ICdfJyArIHRoaXMuYmluZEluY3JlbWVudDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmJpbmRQb2xpY3lBcGlEYXRhLm5hbWUgPSB0aGlzLmJpbmRQb2xpY3lBcGlEYXRhLm5hbWUgKyBwb3N0Rml4O1xuICAgICAgICBwb2xpY3lBcGlEYXRhID0gdGhpcy5iaW5kUG9saWN5QXBpRGF0YTtcbiAgICAgICAgcm9sZUF0dHJpYnV0ZXMgPSB0aGlzLmJpbmRQb2xpY3lSb2xlQXR0cmlidXRlcztcbiAgICAgICAgbmFtZWRBdHRyaWJ1dGVzID0gdGhpcy5iaW5kUG9saWN5TmFtZWRBdHRyaWJ1dGVzO1xuICAgICAgfVxuICAgICAgcG9saWN5QXBpRGF0YS5zZXJ2aWNlUm9sZXMgPSBbYEAke3RoaXMuc2VydmljZUlkfWBdO1xuICAgICAgcG9saWN5QXBpRGF0YS5pZGVudGl0eVJvbGVzID0gbmFtZWRBdHRyaWJ1dGVzLm1hcCgobmFtZSkgPT4ge1xuICAgICAgICBjbGlSb2xlcyArPSAnQCcgKyB0aGlzLmlkZW50aXRpZXNOYW1lSWRNYXBbbmFtZV0gKyAnLCc7XG4gICAgICAgIHJldHVybiAnQCcgKyB0aGlzLmlkZW50aXRpZXNOYW1lSWRNYXBbbmFtZV07XG4gICAgICB9KTtcbiAgICAgIHBvbGljeUFwaURhdGEuaWRlbnRpdHlSb2xlcyA9IFsuLi5wb2xpY3lBcGlEYXRhLmlkZW50aXR5Um9sZXMsIC4uLnJvbGVBdHRyaWJ1dGVzLm1hcCgocm9sZSkgPT4ge1xuICAgICAgICBjbGlSb2xlcyArPSAnIycgKyByb2xlICsgJywnO1xuICAgICAgICByZXR1cm4gJyMnICsgcm9sZTtcbiAgICAgIH0pXTtcbiAgICAgIGNsaVJvbGVzID0gY2xpUm9sZXMuc2xpY2UoMCwgLTEpO1xuICAgICAgcG9saWN5UmVzdWx0ID0gYXdhaXQgdGhpcy5zYXZlRW50aXR5KCdzZXJ2aWNlLXBvbGljaWVzJywgcG9saWN5QXBpRGF0YSkuY2F0Y2goKHJlc3VsdCkgPT4ge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlID09PSAnRGlhbCcpIHtcbiAgICAgICAgcG9saWN5QXBpRGF0YSA9IHRoaXMuZGlhbFBvbGljeUFwaURhdGE7XG4gICAgICAgIHJvbGVBdHRyaWJ1dGVzID0gdGhpcy5kaWFsUG9saWN5Um9sZUF0dHJpYnV0ZXM7XG4gICAgICAgIG5hbWVkQXR0cmlidXRlcyA9IHRoaXMuZGlhbFBvbGljeU5hbWVkQXR0cmlidXRlcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBvbGljeUFwaURhdGEgPSB0aGlzLmJpbmRQb2xpY3lBcGlEYXRhO1xuICAgICAgICByb2xlQXR0cmlidXRlcyA9IHRoaXMuYmluZFBvbGljeVJvbGVBdHRyaWJ1dGVzO1xuICAgICAgICBuYW1lZEF0dHJpYnV0ZXMgPSB0aGlzLmJpbmRQb2xpY3lOYW1lZEF0dHJpYnV0ZXM7XG4gICAgICB9XG4gICAgICBwb2xpY3lBcGlEYXRhLnNlcnZpY2VSb2xlcyA9IFtgQCR7dGhpcy5zZXJ2aWNlSWR9YF07XG4gICAgICBwb2xpY3lBcGlEYXRhLmlkZW50aXR5Um9sZXMgPSBuYW1lZEF0dHJpYnV0ZXMubWFwKChuYW1lKSA9PiB7XG4gICAgICAgIGNsaVJvbGVzICs9ICdAJyArIHRoaXMuaWRlbnRpdGllc05hbWVJZE1hcFtuYW1lXSArICcsJztcbiAgICAgICAgcmV0dXJuICdAJyArIHRoaXMuaWRlbnRpdGllc05hbWVJZE1hcFtuYW1lXTtcbiAgICAgIH0pO1xuICAgICAgcG9saWN5QXBpRGF0YS5pZGVudGl0eVJvbGVzID0gWy4uLnBvbGljeUFwaURhdGEuaWRlbnRpdHlSb2xlcywgLi4ucm9sZUF0dHJpYnV0ZXMubWFwKChyb2xlKSA9PiB7XG4gICAgICAgIGNsaVJvbGVzICs9ICcjJyArIHJvbGUgKyAnLCc7XG4gICAgICAgIHJldHVybiAnIycgKyByb2xlO1xuICAgICAgfSldO1xuICAgICAgY2xpUm9sZXMgPSBjbGlSb2xlcy5zbGljZSgwLCAtMSk7XG4gICAgICBwb2xpY3lSZXN1bHQgPSBhd2FpdCB0aGlzLnVwZGF0ZUVudGl0eSgnc2VydmljZS1wb2xpY2llcycsIHBvbGljeUFwaURhdGEpLmNhdGNoKChyZXN1bHQpID0+IHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChwb2xpY3lSZXN1bHQuZXJyb3IpIHtcbiAgICAgIHN0YXR1cyA9ICdlcnJvcic7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXR1cyA9ICdkb25lJztcbiAgICB9XG4gICAgY29uc3Qgc3VtbWFyeUluZGV4ID0gKHRoaXMuc2RrT25seURpYWwgJiYgdGhpcy5zZGtPbmx5QmluZCkgPyAxIDogMjtcbiAgICBjb25zdCBlbnRpdHlJbmRleCA9IHR5cGUgPT09ICdEaWFsJyA/IDAgOiAxO1xuICAgIHN1bW1hcnlEYXRhW3N1bW1hcnlJbmRleF0uZW50aXRpZXNbZW50aXR5SW5kZXhdLnN0YXR1cyA9IHN0YXR1cztcbiAgICBjb25zdCBjbGlDb21tYW5kID0gYHppdGkgZWRnZSBjcmVhdGUgc2VydmljZS1wb2xpY3kgJyR7cG9saWN5QXBpRGF0YS5uYW1lfScgJHt0eXBlfSAtLXNlbWFudGljIEFueU9mIC0tc2VydmljZS1yb2xlcyAnQCR7dGhpcy5zZXJ2aWNlSWR9JyAtLWlkZW50aXR5LXJvbGVzICcke2NsaVJvbGVzfSdgO1xuICAgIGlmICh0eXBlID09PSAnRGlhbCcpIHtcbiAgICAgIHRoaXMuZGlhbFBvbGljeUNsaUNvbW1hbmQgPSBjbGlDb21tYW5kO1xuICAgICAgaWYgKHN0YXR1cyA9PT0gJ2RvbmUnKSB7XG4gICAgICAgIHRoaXMuZGlhbEluY3JlbWVudCA9IC0xO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5iaW5kSW5jcmVtZW50ID0gLTE7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYmluZFBvbGljeUNsaUNvbW1hbmQgPSBjbGlDb21tYW5kO1xuICAgIH1cbiAgfVxuXG4gIHNhdmVFbnRpdHkodHlwZSwgZGF0YSkge1xuICAgIHJldHVybiB0aGlzLnppdGlTZXJ2aWNlLnBvc3QodHlwZSwgZGF0YSwgdHJ1ZSk7XG4gIH1cblxuICB1cGRhdGVFbnRpdHkodHlwZSwgZGF0YSkge1xuICAgIHJldHVybiB0aGlzLnppdGlTZXJ2aWNlLnBhdGNoKHR5cGUsIGRhdGEsIGRhdGEuaWQsIHRydWUpO1xuICB9XG5cbiAgdmFsaWRhdGUoKSB7XG4gICAgdGhpcy5lcnJvcnMgPSB7fTtcbiAgICB0aGlzLnZhbGlkYXRlU2VydmljZU5hbWUoKTtcbiAgICB0aGlzLnZhbGlkYXRlSW50ZXJjZXB0QWRkcmVzcygpO1xuICAgIHRoaXMudmFsaWRhdGVJbnRlcmNlcHRQb3J0KCk7XG4gICAgdGhpcy52YWxpZGF0ZUhvc3RBZGRyZXNzKCk7XG4gICAgdGhpcy52YWxpZGF0ZUhvc3RQb3J0KCk7XG4gICAgdGhpcy52YWxpZGF0ZURpYWxJZGVudGl0aWVzKClcbiAgICB0aGlzLnZhbGlkYXRlQmluZElkZW50aXRpZXMoKTtcbiAgICByZXR1cm4gaXNFbXB0eSh0aGlzLmVycm9ycyk7XG4gIH1cblxuICB2YWxpZGF0ZVNlcnZpY2VOYW1lKCkge1xuICAgIGlmIChpc0VtcHR5KHRoaXMuc2VydmljZUFwaURhdGEubmFtZSkpIHtcbiAgICAgIHRoaXMuZXJyb3JzLm5hbWUgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bnNldCh0aGlzLmVycm9ycywgJ25hbWUnKTtcbiAgICB9XG4gIH1cblxuICB2YWxpZGF0ZUludGVyY2VwdEFkZHJlc3MoKSB7XG4gICAgaWYgKHRoaXMuc2RrT25seURpYWwpIHtcbiAgICAgIHVuc2V0KHRoaXMuZXJyb3JzLCAnaW50ZXJjZXB0QWRkcmVzcycpO1xuICAgICAgdW5zZXQodGhpcy5lcnJvcnMsICdpbnRlcmNlcHRBZGRyZXNzRm9ybWF0Jyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpc0VtcHR5KHRoaXMuaW50ZXJjZXB0Q29uZmlnQXBpRGF0YS5kYXRhLmFkZHJlc3NlcykgfHwgaXNFbXB0eSh0aGlzLmludGVyY2VwdENvbmZpZ0FwaURhdGEuZGF0YS5hZGRyZXNzZXNbMF0pKSB7XG4gICAgICB0aGlzLmVycm9ycy5pbnRlcmNlcHRBZGRyZXNzID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCF0aGlzLnZhbGlkYXRpb25TZXJ2aWNlLmlzVmFsaWRJbnRlcmNlcHRIb3N0KHRoaXMuaW50ZXJjZXB0Q29uZmlnQXBpRGF0YS5kYXRhLmFkZHJlc3Nlc1swXSkpIHtcbiAgICAgIHRoaXMuZXJyb3JzLmludGVyY2VwdEFkZHJlc3MgPSB0cnVlO1xuICAgICAgdGhpcy5lcnJvcnMuaW50ZXJjZXB0QWRkcmVzc0Zvcm1hdCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuc2V0KHRoaXMuZXJyb3JzLCAnaW50ZXJjZXB0QWRkcmVzcycpO1xuICAgICAgdW5zZXQodGhpcy5lcnJvcnMsICdpbnRlcmNlcHRBZGRyZXNzRm9ybWF0Jyk7XG4gICAgfVxuICB9XG5cbiAgdmFsaWRhdGVJbnRlcmNlcHRQb3J0KCkge1xuICAgIGlmICh0aGlzLnNka09ubHlEaWFsKSB7XG4gICAgICB1bnNldCh0aGlzLmVycm9ycywgJ2ludGVyY2VwdFBvcnQnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGlzRW1wdHkodGhpcy5pbnRlcmNlcHRDb25maWdBcGlEYXRhLmRhdGEucG9ydFJhbmdlcykpIHtcbiAgICAgIHRoaXMuZXJyb3JzLmludGVyY2VwdFBvcnQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAodGhpcy52YWxpZGF0aW9uU2VydmljZS52YWxpZGF0ZVBvcnRSYW5nZXModGhpcy5pbnRlcmNlcHRDb25maWdBcGlEYXRhLmRhdGEucG9ydFJhbmdlcykpIHtcbiAgICAgIHRoaXMuZXJyb3JzLmludGVyY2VwdFBvcnQgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bnNldCh0aGlzLmVycm9ycywgJ2ludGVyY2VwdFBvcnQnKTtcbiAgICB9XG4gIH1cblxuICB2YWxpZGF0ZUhvc3RBZGRyZXNzKCkge1xuICAgIGlmICghdGhpcy5zZGtPbmx5QmluZCAmJiBpc0VtcHR5KHRoaXMuaG9zdENvbmZpZ0FwaURhdGEuZGF0YS5hZGRyZXNzKSkge1xuICAgICAgdGhpcy5lcnJvcnMuaG9zdEFkZHJlc3MgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bnNldCh0aGlzLmVycm9ycywgJ2hvc3RBZGRyZXNzJyk7XG4gICAgfVxuICB9XG5cbiAgdmFsaWRhdGVIb3N0UG9ydCgpIHtcbiAgICBpZiAodGhpcy5zZGtPbmx5QmluZCkge1xuICAgICAgdW5zZXQodGhpcy5lcnJvcnMsICdob3N0UG9ydCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaXNOaWwodGhpcy5ob3N0Q29uZmlnQXBpRGF0YS5kYXRhLnBvcnQpIHx8IGlzTmFOKHRoaXMuaG9zdENvbmZpZ0FwaURhdGEuZGF0YS5wb3J0KSkge1xuICAgICAgdGhpcy5lcnJvcnMuaG9zdFBvcnQgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoIXRoaXMudmFsaWRhdGlvblNlcnZpY2UuaXNWYWxpZFBvcnQodGhpcy5ob3N0Q29uZmlnQXBpRGF0YS5kYXRhLnBvcnQpKSB7XG4gICAgICB0aGlzLmVycm9ycy5ob3N0UG9ydCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuc2V0KHRoaXMuZXJyb3JzLCAnaG9zdFBvcnQnKTtcbiAgICB9XG4gIH1cblxuICB2YWxpZGF0ZURpYWxJZGVudGl0aWVzKCkge1xuICAgIGlmIChpc0VtcHR5KFsuLi50aGlzLmRpYWxQb2xpY3lOYW1lZEF0dHJpYnV0ZXMsIC4uLnRoaXMuZGlhbFBvbGljeVJvbGVBdHRyaWJ1dGVzXSkpIHtcbiAgICAgIHRoaXMuZXJyb3JzLmRpYWxJZGVudGl0aWVzID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdW5zZXQodGhpcy5lcnJvcnMsICdkaWFsSWRlbnRpdGllcycpO1xuICAgIH1cbiAgfVxuXG4gIHZhbGlkYXRlQmluZElkZW50aXRpZXMoKSB7XG4gICAgaWYgKGlzRW1wdHkoWy4uLnRoaXMuYmluZFBvbGljeU5hbWVkQXR0cmlidXRlcywgLi4udGhpcy5iaW5kUG9saWN5Um9sZUF0dHJpYnV0ZXNdKSkge1xuICAgICAgdGhpcy5lcnJvcnMuYmluZElkZW50aXRpZXMgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bnNldCh0aGlzLmVycm9ycywgJ2JpbmRJZGVudGl0aWVzJyk7XG4gICAgfVxuICB9XG5cbiAgZ2V0U2VydmljZXNBcGlSZXF1ZXN0KCkge1xuICAgIHJldHVybiBgY3VybCAnJHt0aGlzLmNvbnRyb2xsZXJEb21haW59L2VkZ2UvbWFuYWdlbWVudC92MS9zZXJ2aWNlcycgXFxcXFxuICAgICAgLUggJ2FjY2VwdDogYXBwbGljYXRpb24vanNvbiwgdGV4dC9wbGFpbiwgKi8qJyBcXFxcXG4gICAgICAtSCAnY29udGVudC10eXBlOiBhcHBsaWNhdGlvbi9qc29uJyBcXFxcXG4gICAgICAtSCAnenQtc2Vzc2lvbjogJHt0aGlzLnppdGlTZXNzaW9uSWR9JyBcXFxcXG4gICAgICAtLWRhdGEtcmF3ICcke0pTT04uc3RyaW5naWZ5KHRoaXMuc2VydmljZUFwaURhdGEpfScgXFxcXGBcbiAgfVxuXG4gIGdldEludGVyY2VwdENvbmZpZ0FwaVJlcXVlc3QoKSB7XG4gICAgcmV0dXJuIGBjdXJsICcke3RoaXMuY29udHJvbGxlckRvbWFpbn0vZWRnZS9tYW5hZ2VtZW50L3YxL2NvbmZpZ3MnIFxcXFxcbiAgICAgIC1IICdhY2NlcHQ6IGFwcGxpY2F0aW9uL2pzb24sIHRleHQvcGxhaW4sICovKicgXFxcXFxuICAgICAgLUggJ2NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vanNvbicgXFxcXFxuICAgICAgLUggJ3p0LXNlc3Npb246ICR7dGhpcy56aXRpU2Vzc2lvbklkfScgXFxcXFxuICAgICAgLS1kYXRhLXJhdyAnJHtKU09OLnN0cmluZ2lmeSh0aGlzLmludGVyY2VwdENvbmZpZ0FwaURhdGEpfScgXFxcXGBcbiAgfVxuXG4gIGdldEhvc3RDb25maWdBcGlSZXF1ZXN0KCkge1xuICAgIHJldHVybiBgY3VybCAnJHt0aGlzLmNvbnRyb2xsZXJEb21haW59L2VkZ2UvbWFuYWdlbWVudC92MS9jb25maWdzJyBcXFxcXG4gICAgICAtSCAnYWNjZXB0OiBhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L3BsYWluLCAqLyonIFxcXFxcbiAgICAgIC1IICdjb250ZW50LXR5cGU6IGFwcGxpY2F0aW9uL2pzb24nIFxcXFxcbiAgICAgIC1IICd6dC1zZXNzaW9uOiAke3RoaXMueml0aVNlc3Npb25JZH0nIFxcXFxcbiAgICAgIC0tZGF0YS1yYXcgJyR7SlNPTi5zdHJpbmdpZnkodGhpcy5ob3N0Q29uZmlnQXBpRGF0YSl9JyBcXFxcYFxuICB9XG5cbiAgZ2V0RGlhbEFwaVJlcXVlc3QoKSB7XG4gICAgcmV0dXJuIGBjdXJsICcke3RoaXMuY29udHJvbGxlckRvbWFpbn0vZWRnZS9tYW5hZ2VtZW50L3YxL3NlcnZpY2UtcG9saWNpZXMnIFxcXFxcbiAgICAgIC1IICdhY2NlcHQ6IGFwcGxpY2F0aW9uL2pzb24sIHRleHQvcGxhaW4sICovKicgXFxcXFxuICAgICAgLUggJ2NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vanNvbicgXFxcXFxuICAgICAgLUggJ3p0LXNlc3Npb246ICR7dGhpcy56aXRpU2Vzc2lvbklkfScgXFxcXFxuICAgICAgLS1kYXRhLXJhdyAnJHtKU09OLnN0cmluZ2lmeSh0aGlzLmRpYWxQb2xpY3lBcGlEYXRhKX0nIFxcXFxgO1xuICB9XG5cbiAgZ2V0QmluZEFwaVJlcXVlc3QoKSB7XG4gICAgcmV0dXJuIGBjdXJsICcke3RoaXMuY29udHJvbGxlckRvbWFpbn0vZWRnZS9tYW5hZ2VtZW50L3YxL3NlcnZpY2UtcG9saWNpZXMnIFxcXFxcbiAgICAgIC1IICdhY2NlcHQ6IGFwcGxpY2F0aW9uL2pzb24sIHRleHQvcGxhaW4sICovKicgXFxcXFxuICAgICAgLUggJ2NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vanNvbicgXFxcXFxuICAgICAgLUggJ3p0LXNlc3Npb246ICR7dGhpcy56aXRpU2Vzc2lvbklkfScgXFxcXFxuICAgICAgLS1kYXRhLXJhdyAnJHtKU09OLnN0cmluZ2lmeSh0aGlzLmJpbmRQb2xpY3lBcGlEYXRhKX0nIFxcXFxgO1xuICB9XG5cbiAgaW5pdERhdGFNb2RlbHMoKSB7XG4gICAgdGhpcy5zZXJ2aWNlQXBpRGF0YSA9IHRoaXMuaW5pdFNlcnZpY2VBcGlEYXRhO1xuICAgIHRoaXMuaW50ZXJjZXB0Q29uZmlnQXBpRGF0YS5kYXRhID0gdGhpcy5pbml0SW50ZXJjZXB0Q29uZmlnQXBpRGF0YS5kYXRhO1xuICAgIHRoaXMuaG9zdENvbmZpZ0FwaURhdGEuZGF0YSA9IHRoaXMuaW5pdEhvc3RDb25maWdBcGlEYXRhLmRhdGE7XG4gICAgdGhpcy5kaWFsUG9saWN5QXBpRGF0YSA9IHRoaXMuaW5pdERpYWxQb2xpY3lBcGlEYXRhO1xuICAgIHRoaXMuYmluZFBvbGljeUFwaURhdGEgPSB0aGlzLmluaXRCaW5kUG9saWN5QXBpRGF0YTtcbiAgfVxuXG4gIGNvbnZlcnRUb0FkdmFuY2VkKCkge1xuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBhcHBlbmRJZDogJ0NvbnZlcnRTaW1wbGVTZXJ2aWNlJyxcbiAgICAgIHRpdGxlOiAnQ29udmVydCBTZXJ2aWNlJyxcbiAgICAgIG1lc3NhZ2U6IGBBcmUgeW91IHN1cmUgeW91IHdvdWxkIGxpa2UgdG8gY29udmVydCB0aGlzIHNpbXBsZSBzZXJ2aWNlIHRvIGFuIGFkdmFuY2VkIHNlcnZpY2U/IFRoaXMgY2hhbmdlIGNhbm5vdCBiZSB1bmRvbmUuYCxcbiAgICAgIGJ1bGxldExpc3Q6IFtdLFxuICAgICAgY29uZmlybUxhYmVsOiAnWWVzJyxcbiAgICAgIGNhbmNlbExhYmVsOiAnT29wcywgbm8gZ2V0IG1lIG91dCBvZiBoZXJlJyxcbiAgICAgIGltYWdlVXJsOiAnLi4vLi4vYXNzZXRzL3N2Z3MvR3Jvd2xfV2FybmluZy5zdmcnLFxuICAgICAgc2hvd0NhbmNlbExpbms6IHRydWVcbiAgICB9O1xuICAgIHRoaXMuZGlhbG9nUmVmID0gdGhpcy5kaWFsb2dGb3JtLm9wZW4oQ29uZmlybUNvbXBvbmVudCwge1xuICAgICAgZGF0YTogZGF0YSxcbiAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgfSk7XG4gICAgdGhpcy5kaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoKHJlc3VsdCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdD8uY29uZmlybWVkKSB7XG4gICAgICAgIHRoaXMuc2VydmljZUFwaURhdGEudGFnc1snc2VydmljZS10eXBlJ10gPSAnYWR2YW5jZWQnO1xuICAgICAgICB0aGlzLnVwZGF0ZUVudGl0eSgnc2VydmljZXMnLCB0aGlzLnNlcnZpY2VBcGlEYXRhKVxuICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGdyb3dsZXJEYXRhID0gbmV3IEdyb3dsZXJNb2RlbChcbiAgICAgICAgICAgICAgICAnc3VjY2VzcycsXG4gICAgICAgICAgICAgICAgJ1N1Y2Nlc3MnLFxuICAgICAgICAgICAgICAgIGBTZXJ2aWNlIFVwZGF0ZWRgLFxuICAgICAgICAgICAgICAgIGBTdWNjZXNzZnVsbHkgY29udmVydGVkICR7dGhpcy5zZXJ2aWNlQXBpRGF0YS5uYW1lfSB0byBhbiBhZHZhbmNlZCBzZXJ2aWNlLmAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5ncm93bGVyU2VydmljZS5zaG93KGdyb3dsZXJEYXRhKTtcbiAgICAgICAgICAgIHRoaXMuc2V0SW5pdERhdGEoKTtcbiAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFtVUkxTLlpJVElfQURWQU5DRURfU0VSVklDRSArICcvJyArIHRoaXMuc2VydmljZUFwaURhdGEuaWRdKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5jYXRjaCgocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBncm93bGVyRGF0YSA9IG5ldyBHcm93bGVyTW9kZWwoXG4gICAgICAgICAgICAgICAgJ2Vycm9yJyxcbiAgICAgICAgICAgICAgICAnRXJyb3InLFxuICAgICAgICAgICAgICAgIGBGYWlsZWQgdG8gVXBkYXRlIFNlcnZpY2VgLFxuICAgICAgICAgICAgICAgIGBVbmFibGUgdG8gY29udmVydCAke3RoaXMuc2VydmljZUFwaURhdGEubmFtZX0gdG8gYW4gYWR2YW5jZWQgc2VydmljZS5gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuZ3Jvd2xlclNlcnZpY2Uuc2hvdyhncm93bGVyRGF0YSk7XG4gICAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgfVxuXG4gIG92ZXJyaWRlIGNoZWNrRGF0YUNoYW5nZSgpIHtcbiAgICBjb25zdCBzZXJ2aWNlRGF0YUNoYW5nZSA9ICFpc0VxdWFsKHRoaXMuaW5pdFNlcnZpY2VBcGlEYXRhLCB0aGlzLnNlcnZpY2VBcGlEYXRhKTtcbiAgICBjb25zdCBpbnRlcmNlcHREYXRhQ2hhbmdlID0gIWlzRXF1YWwodGhpcy5pbml0SW50ZXJjZXB0Q29uZmlnQXBpRGF0YS5kYXRhLCB0aGlzLmludGVyY2VwdENvbmZpZ0FwaURhdGEuZGF0YSk7XG4gICAgY29uc3QgaG9zdERhdGFDaGFuZ2UgPSAhaXNFcXVhbCh0aGlzLmluaXRIb3N0Q29uZmlnQXBpRGF0YS5kYXRhLCB0aGlzLmhvc3RDb25maWdBcGlEYXRhLmRhdGEpO1xuICAgIGNvbnN0IGRpYWxEYXRhQ2hhbmdlID0gIWlzRXF1YWwodGhpcy5pbml0RGlhbFBvbGljeUFwaURhdGEsIHRoaXMuZGlhbFBvbGljeUFwaURhdGEpO1xuICAgIGNvbnN0IGJpbmREYXRhQ2hhbmdlID0gIWlzRXF1YWwodGhpcy5pbml0QmluZFBvbGljeUFwaURhdGEsIHRoaXMuYmluZFBvbGljeUFwaURhdGEpO1xuICAgIGNvbnN0IGRhdGFDaGFuZ2UgPSBzZXJ2aWNlRGF0YUNoYW5nZSAhPT0gdGhpcy5zZXJ2aWNlRGF0YUNoYW5nZSB8fCBpbnRlcmNlcHREYXRhQ2hhbmdlICE9PSB0aGlzLmludGVyY2VwdERhdGFDaGFuZ2UgfHwgaG9zdERhdGFDaGFuZ2UgIT09IHRoaXMuaG9zdERhdGFDaGFuZ2UgfHxcbiAgICAgICAgZGlhbERhdGFDaGFuZ2UgIT09IHRoaXMuZGlhbERhdGFDaGFuZ2UgfHwgYmluZERhdGFDaGFuZ2UgIT09IHRoaXMuYmluZERhdGFDaGFuZ2U7XG4gICAgaWYgKGRhdGFDaGFuZ2UpIHtcbiAgICAgIHRoaXMuc2VydmljZURhdGFDaGFuZ2UgPSBzZXJ2aWNlRGF0YUNoYW5nZTtcbiAgICAgIHRoaXMuaW50ZXJjZXB0RGF0YUNoYW5nZSA9IGludGVyY2VwdERhdGFDaGFuZ2U7XG4gICAgICB0aGlzLmhvc3REYXRhQ2hhbmdlID0gaG9zdERhdGFDaGFuZ2U7XG4gICAgICB0aGlzLmRpYWxEYXRhQ2hhbmdlID0gZGlhbERhdGFDaGFuZ2U7XG4gICAgICB0aGlzLmJpbmREYXRhQ2hhbmdlID0gYmluZERhdGFDaGFuZ2U7XG4gICAgICB0aGlzLmRhdGFDaGFuZ2UuZW1pdChkYXRhQ2hhbmdlKTtcbiAgICB9XG4gICAgdGhpcy5fZGF0YUNoYW5nZSA9IHNlcnZpY2VEYXRhQ2hhbmdlIHx8IGludGVyY2VwdERhdGFDaGFuZ2UgfHwgaG9zdERhdGFDaGFuZ2UgfHwgZGlhbERhdGFDaGFuZ2UgfHwgYmluZERhdGFDaGFuZ2U7XG4gIH1cblxuICBjbGVhcigpOiB2b2lkIHtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInByb2plY3RhYmxlLWZvcm0td3JhcHBlciBzaW1wbGUtc2VydmljZS13cmFwcGVyXCJcbiAgICAgKGtleXVwLmVudGVyKT1cInNhdmUoJGV2ZW50KVwiXG4gICAgIChrZXl1cC5lc2NhcGUpPVwiY2xvc2VNb2RhbCh0cnVlLCBmYWxzZSwgJ2NhcmRzJywgJGV2ZW50KVwiXG4gICAgIHRhYmluZGV4PVwiMFwiXG4gICAgIFtjbGFzcy5wcm9qZWN0YWJsZS1mb3JtLWhpZGRlbl09XCIhZGF0YUluaXRcIlxuPlxuICAgIDxsaWItZm9ybS1oZWFkZXJcbiAgICAgICAgICAgIFtkYXRhXT1cImZvcm1EYXRhXCJcbiAgICAgICAgICAgIFt0aXRsZV09XCJpc0VkaXQgPyAnRWRpdCBTaW1wbGUgU2VydmljZScgOiAnQ3JlYXRlIGEgU2ltcGxlIFNlcnZpY2UnXCJcbiAgICAgICAgICAgIFthY3Rpb25CdXR0b25UZXh0XT1cIidTYXZlJ1wiXG4gICAgICAgICAgICBbbXVsdGlBY3Rpb25zXT1cIm11bHRpQWN0aW9uc1wiXG4gICAgICAgICAgICAoYWN0aW9uUmVxdWVzdGVkKT1cImhlYWRlckFjdGlvblJlcXVlc3RlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChtdWx0aUFjdGlvblJlcXVlc3RlZCk9XCJtdWx0aUFjdGlvblJlcXVlc3RlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgIFsoZm9ybVZpZXcpXT1cImZvcm1WaWV3XCJcbiAgICAgICAgICAgIFttb3JlQWN0aW9uc109XCJtb3JlQWN0aW9uc1wiXG4gICAgICAgICAgICBbY2xhc3MuaXMtc2Nyb2xsZWRdPVwiaXNTY3JvbGxlZFwiXG4gICAgPjwvbGliLWZvcm0taGVhZGVyPlxuXG4gICAgPGRpdiBjbGFzcz1cInNpbXBsZS1zZXJ2aWNlLWZvcm0tY29udGFpbmVyIHByb2plY3RhYmxlLWZvcm0tY29udGFpbmVyXCIgI2Zvcm1Db250YWluZXI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwLWNvbHVtbiB0aHJlZS1maWZ0aHNcIiAqbmdJZj1cInNob3dGb3JtXCI+XG4gICAgICAgICAgICA8ZGl2ICBpZD1cIklubGluZVNlcnZpY2VBcmVhXCIgY2xhc3M9XCJhbnlhZGRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2ltcGxlLXNlcnZpY2UtaW5wdXRzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsaWItZm9ybS1maWVsZC1jb250YWluZXIgW3RpdGxlXT1cIidTZXJ2aWNlIERldGFpbHMnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1pbnB1dC1ncm91cCBzZXJ2aWNlLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtc3ViLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctdGl0bGUtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvcm0tZmllbGQtdGl0bGVcIj5TZXJ2aWNlIE5hbWU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1maWVsZC1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIk5hbWUgdGhpcyBzZXJ2aWNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9mb2N1c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI25hbWVGaWVsZElucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ZXJyb3I6IGVycm9ycy5uYW1lfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlcnZpY2VBcGlEYXRhLm5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleXVwKT1cInNlcnZpY2VOYW1lQ2hhbmdlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwidmFsaWRhdGVTZXJ2aWNlTmFtZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1maWVsZC1zdWItZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy10aXRsZS1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9ybS1maWVsZC10aXRsZVwiPlNFTEVDVCBPUiBDUkVBVEUgU0VSVklDRSBBVFRSSUJVVEVTPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpYi10YWctc2VsZWN0b3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsoc2VsZWN0ZWRSb2xlQXR0cmlidXRlcyldPVwic2VydmljZUFwaURhdGEucm9sZUF0dHJpYnV0ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F2YWlsYWJsZVJvbGVBdHRyaWJ1dGVzXT1cInNlcnZpY2VSb2xlQXR0cmlidXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0FkZCBhdHRyaWJ1dGVzIHRvIGdyb3VwIHNlcnZpY2VzJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2xpYi10YWctc2VsZWN0b3I+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9saWItZm9ybS1maWVsZC1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzaW1wbGUtc2VydmljZS1jZW50ZXItY29udGVudFwiICpuZ0lmPVwic2hvd0Zvcm1cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwLXJvd1wiPlxuICAgICAgICAgICAgICAgIDxsaWItZm9ybS1maWVsZC1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCInQUNDRVNTSU5HIENPTkZJR1VSQVRJT04nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjb250ZW50U3R5bGVdPVwiJ3otaW5kZXg6IDEwMDAxJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaGVscFRleHRdPVwiJ0hvdyB3aWxsIGNsaWVudCBhcHBsaWNhdGlvbnMgdXNlIHRoaXMgc2VydmljZT8gU3BlY2lmeSBhbiBhZGRyZXNzIGFuZCBwb3J0LCBvciB1c2UgdGhlICZxdW90O1NESyBPbmx5JnF1b3Q7IHRvZ2dsZSBmb3IgYW4gYXBwbGljYXRpb24gZW1iZWRkZWQgY29uZmlndXJhdGlvbi4nXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWZpZWxkLWlucHV0LWdyb3VwIGFjY2Vzc2luZy1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtc3ViLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy10aXRsZS1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlXCI+V2hhdCBpZGVudGl0aWVzIGNhbiBhY2Nlc3MgdGhpcyBzZXJ2aWNlPzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGliLXRhZy1zZWxlY3RvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhzZWxlY3RlZE5hbWVkQXR0cmlidXRlcyldPVwiZGlhbFBvbGljeU5hbWVkQXR0cmlidXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKHNlbGVjdGVkUm9sZUF0dHJpYnV0ZXMpXT1cImRpYWxQb2xpY3lSb2xlQXR0cmlidXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXZhaWxhYmxlTmFtZWRBdHRyaWJ1dGVzXT1cImlkZW50aXR5TmFtZWRBdHRyaWJ1dGVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdmFpbGFibGVSb2xlQXR0cmlidXRlc109XCJpZGVudGl0eVJvbGVBdHRyaWJ1dGVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInU2VsZWN0IGlkZW50aXR5IGF0dHJpYnV0ZXMgdG8gZ3JhbnQgYWNjZXNzJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGFzRXJyb3JdPVwiZXJyb3JzLmRpYWxJZGVudGl0aWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3RlZE5hbWVkQXR0cmlidXRlc0NoYW5nZSk9XCJ2YWxpZGF0ZURpYWxJZGVudGl0aWVzKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdGVkUm9sZUF0dHJpYnV0ZXNDaGFuZ2UpPVwidmFsaWRhdGVEaWFsSWRlbnRpdGllcygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmaWx0ZXJDaGFuZ2UpPVwiZ2V0SWRlbnRpdHlOYW1lZEF0dHJpYnV0ZXMoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvbGliLXRhZy1zZWxlY3Rvcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtc3ViLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy10aXRsZS1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlXCI+SG93IHdpbGwgdGhlIHNlcnZpY2UgYmUgYWNjZXNzZWQ/PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkIGFkZHJlc3NQb3J0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctaXRlbS1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29uZmlnLWl0ZW0tbGFiZWxcIj5TREsgT05MWTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzZGstdG9nZ2xlIGZvcm0tZmllbGQtdG9nZ2xlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3dpdGNoR3JpZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlU2RrT25seURpYWwoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgb246IHNka09ubHlEaWFsIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRvZ2dsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2hpZGRlbl09XCIhc2RrT25seURpYWxcIiBjbGFzcz1cIm9uLWxhYmVsXCI+WUVTPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwic2RrT25seURpYWxcIiBjbGFzcz1cIm9mZi1sYWJlbFwiPk5PPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzd2l0Y2hcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1pdGVtLWNvbnRhaW5lclwiIFtuZ0NsYXNzXT1cIntkaXNhYmxlZDogc2RrT25seURpYWx9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWhvc3RuYW1lLWxhYmVsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb25maWctaXRlbS1sYWJlbFwiPkFkZHJlc3M8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tZmllbGQtaW5mbyBpbmZvaWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJBY2Nlc3NpbmcgaG9zdG5hbWVzIG11c3QgaW5jbHVkZSBhICcuJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImFib3ZlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJlcnJvcnMuaW50ZXJjZXB0QWRkcmVzc0Zvcm1hdFwiIGNsYXNzPVwiZXJyb3ItbGFiZWxcIj5BY2Nlc3NpbmcgYWRkcmVzcyBtdXN0IGluY2x1ZGUgYSAnLic8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cIkhvd1RvXCIgdHlwZT1cInRleHRcIiBtYXhsZW5ndGg9XCIxMDBcIiBkYXRhLWkxOG49XCJFZ0hvc3RcIiAoY2hhbmdlKT1cInZhbGlkYXRlSW50ZXJjZXB0QWRkcmVzcygpXCIgW25nQ2xhc3NdPVwie2Vycm9yOiBlcnJvcnMuaW50ZXJjZXB0QWRkcmVzc31cIiBbcGxhY2Vob2xkZXJdPVwic2RrT25seURpYWwgPyAnJyA6ICdlLmcuIG15c2VydmljZS56aXRpJ1wiIFsobmdNb2RlbCldPVwic2RrT25seURpYWwgPyAnJyA6IGludGVyY2VwdENvbmZpZ0FwaURhdGEuZGF0YS5hZGRyZXNzZXNbMF1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctaXRlbS1jb250YWluZXJcIiBbbmdDbGFzc109XCJ7ZGlzYWJsZWQ6IHNka09ubHlEaWFsfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb25maWctaXRlbS1sYWJlbFwiPlBPUlQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9XCJIb3dUb1BvcnRcIiB0eXBlPVwibnVtYmVyXCIgbWF4bGVuZ3RoPVwiMTBcIiAoY2hhbmdlKT1cInZhbGlkYXRlSW50ZXJjZXB0UG9ydCgpXCIgW25nQ2xhc3NdPVwie2Vycm9yOiBlcnJvcnMuaW50ZXJjZXB0UG9ydH1cIiBbcGxhY2Vob2xkZXJdPVwic2RrT25seURpYWwgPyAnJyA6IDQ0M1wiIChrZXl1cCk9XCJpbnRlcmNlcHRQb3J0Q2hhbmdlZCgkZXZlbnQpXCIgWyhuZ01vZGVsKV09XCJzZGtPbmx5RGlhbCA/ICcnIDogaW50ZXJjZXB0UG9ydFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2xpYi1mb3JtLWZpZWxkLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8bGliLWZvcm0tZmllbGQtY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiJ0hPU1RJTkcgQ09ORklHVVJBVElPTidcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NvbnRlbnRTdHlsZV09XCInei1pbmRleDogMTAwMDAnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtoZWxwVGV4dF09XCInV2hlcmUgc2hvdWxkIHRyYWZmaWMgZm9yIHRoaXMgc2VydmljZSBiZSBzZW50PyBTcGVjaWZ5IGEgcHJvdG9jb2wsIGFkZHJlc3MsIGFuZCBwb3J0LCBvciB1c2UgdGhlICZxdW90O1NESyBPbmx5JnF1b3Q7IHRvZ2dsZSBmb3IgYW4gYXBwbGljYXRpb24gZW1iZWRkZWQgY29uZmlndXJhdGlvbi4nXCJcblxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtaW5wdXQtZ3JvdXAgaG9zdGluZy1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtc3ViLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy10aXRsZS1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlXCI+V2hhdCBpZGVudGl0aWVzIGNhbiBob3N0IHRoaXMgc2VydmljZT88L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpYi10YWctc2VsZWN0b3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsoc2VsZWN0ZWROYW1lZEF0dHJpYnV0ZXMpXT1cImJpbmRQb2xpY3lOYW1lZEF0dHJpYnV0ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhzZWxlY3RlZFJvbGVBdHRyaWJ1dGVzKV09XCJiaW5kUG9saWN5Um9sZUF0dHJpYnV0ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F2YWlsYWJsZU5hbWVkQXR0cmlidXRlc109XCJpZGVudGl0eU5hbWVkQXR0cmlidXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXZhaWxhYmxlUm9sZUF0dHJpYnV0ZXNdPVwiaWRlbnRpdHlSb2xlQXR0cmlidXRlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ1NlbGVjdCBpZGVudGl0eSBhdHRyaWJ1dGVzJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGFzRXJyb3JdPVwiZXJyb3JzLmJpbmRJZGVudGl0aWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxlY3RlZE5hbWVkQXR0cmlidXRlc0NoYW5nZSk9XCJ2YWxpZGF0ZUJpbmRJZGVudGl0aWVzKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdGVkUm9sZUF0dHJpYnV0ZXNDaGFuZ2UpPVwidmFsaWRhdGVCaW5kSWRlbnRpdGllcygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmaWx0ZXJDaGFuZ2UpPVwiZ2V0SWRlbnRpdHlOYW1lZEF0dHJpYnV0ZXMoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvbGliLXRhZy1zZWxlY3Rvcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZmllbGQtc3ViLWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy10aXRsZS1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb3JtLWZpZWxkLXRpdGxlXCI+V2hlcmUgc2hvdWxkIHRyYWZmaWMgYmUgc2VudD88L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQgYWRkcmVzc0Z1bGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1pdGVtLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb25maWctaXRlbS1sYWJlbFwiPlNESyBPTkxZPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNkay10b2dnbGUgZm9ybS1maWVsZC10b2dnbGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzd2l0Y2hHcmlkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVTZGtPbmx5QmluZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyBvbjogc2RrT25seUJpbmQgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidG9nZ2xlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbaGlkZGVuXT1cIiFzZGtPbmx5QmluZFwiIGNsYXNzPVwib24tbGFiZWxcIj5ZRVM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW2hpZGRlbl09XCJzZGtPbmx5QmluZFwiIGNsYXNzPVwib2ZmLWxhYmVsXCI+Tk88L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN3aXRjaFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29uZmlnLWl0ZW0tY29udGFpbmVyXCIgW25nQ2xhc3NdPVwie2Rpc2FibGVkOiBzZGtPbmx5QmluZH1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29uZmlnLWl0ZW0tbGFiZWxcIj5QUk9UT0NPTDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9XCJIb3N0ZWRQcm90b2NvbFwiIChjaGFuZ2UpPVwiaG9zdFByb3RvY29sc0NoYW5nZWQoJGV2ZW50KVwiIFsobmdNb2RlbCldPVwic2RrT25seUJpbmQgPyAnJyA6IGhvc3RQcm90b2NvbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ0Y3BcIj5UQ1A8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwidWRwXCIgPlVEUDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJib3RoXCIgPlRDUC9VRFA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbmZpZy1pdGVtLWNvbnRhaW5lclwiIFtuZ0NsYXNzXT1cIntkaXNhYmxlZDogc2RrT25seUJpbmR9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbmZpZy1pdGVtLWxhYmVsXCI+QWRkcmVzczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cIkhvc3RlZEhvc3RcIiB0eXBlPVwidGV4dFwiIG1heGxlbmd0aD1cIjEwMFwiIGRhdGEtaTE4bj1cIkVnSG9zdFwiIChjaGFuZ2UpPVwidmFsaWRhdGVIb3N0QWRkcmVzcygpXCIgW25nQ2xhc3NdPVwie2Vycm9yOiBlcnJvcnMuaG9zdEFkZHJlc3N9XCIgW3BsYWNlaG9sZGVyXT1cInNka09ubHlCaW5kID8gJycgOiAnZS5nLiBteXNlcnZpY2Uueml0aSdcIiBbKG5nTW9kZWwpXT1cInNka09ubHlCaW5kID8gJycgOiBob3N0Q29uZmlnQXBpRGF0YS5kYXRhLmFkZHJlc3NcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb25maWctaXRlbS1jb250YWluZXJcIiBbbmdDbGFzc109XCJ7ZGlzYWJsZWQ6IHNka09ubHlCaW5kfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb25maWctaXRlbS1sYWJlbFwiPlBPUlQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9XCJIb3N0ZWRQb3J0XCIgdHlwZT1cIm51bWJlclwiIG1heGxlbmd0aD1cIjEwXCIgKGNoYW5nZSk9XCJ2YWxpZGF0ZUhvc3RQb3J0KClcIiBbbmdDbGFzc109XCJ7ZXJyb3I6IGVycm9ycy5ob3N0UG9ydH1cIiBbcGxhY2Vob2xkZXJdPVwic2RrT25seUJpbmQgPyAnJyA6IDQ0M1wiIFsobmdNb2RlbCldPVwic2RrT25seUJpbmQgPyAnJyA6IGhvc3RDb25maWdBcGlEYXRhLmRhdGEucG9ydFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2xpYi1mb3JtLWZpZWxkLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuPGxpYi1sb2FkaW5nLWluZGljYXRvciAqbmdJZj1cImlzTG9hZGluZyB8fCAhZGF0YUluaXRcIiBbaXNMb2FkaW5nXT1cImlzTG9hZGluZyB8fCAhZGF0YUluaXRcIj48L2xpYi1sb2FkaW5nLWluZGljYXRvcj5cbiJdfQ==
|