@gravitee/ui-components 3.24.5 → 3.25.0-fix-gvcode-15ce1d2

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.
Files changed (114) hide show
  1. package/CHANGELOG.md +1270 -0
  2. package/LICENSE.txt +202 -0
  3. package/README.md +195 -0
  4. package/assets/i18n/en.json +3 -0
  5. package/assets/i18n/fr.json +3 -0
  6. package/assets/icons/design.svg +1 -1
  7. package/package.json +1 -1
  8. package/src/.eslintrc.js +19 -0
  9. package/src/atoms/gv-autocomplete.js +156 -132
  10. package/src/atoms/gv-button.js +248 -73
  11. package/src/atoms/gv-checkbox.js +103 -45
  12. package/src/atoms/gv-date-picker-calendar.js +393 -312
  13. package/src/atoms/gv-date-picker-cell.js +81 -57
  14. package/src/atoms/gv-date-picker.js +319 -180
  15. package/src/atoms/gv-file-upload.js +195 -85
  16. package/src/atoms/gv-icon.js +34 -13
  17. package/src/atoms/gv-image.js +66 -31
  18. package/src/atoms/gv-input-message.js +37 -12
  19. package/src/atoms/gv-input.js +148 -117
  20. package/src/atoms/gv-link.js +125 -47
  21. package/src/atoms/gv-message.js +69 -18
  22. package/src/atoms/gv-metric.js +68 -19
  23. package/src/atoms/gv-relative-time.js +38 -67
  24. package/src/atoms/gv-select-native.js +215 -96
  25. package/src/atoms/gv-select.js +230 -110
  26. package/src/atoms/gv-spinner.js +26 -5
  27. package/src/atoms/gv-state.js +66 -25
  28. package/src/atoms/gv-switch.js +160 -40
  29. package/src/atoms/gv-tag.js +78 -26
  30. package/src/atoms/gv-text.js +83 -22
  31. package/src/charts/gv-chart-bar.js +18 -22
  32. package/src/charts/gv-chart-gauge.js +31 -28
  33. package/src/charts/gv-chart-histogram.js +10 -18
  34. package/src/charts/gv-chart-line.js +59 -70
  35. package/src/charts/gv-chart-map.js +42 -44
  36. package/src/charts/gv-chart-pie.js +14 -18
  37. package/src/index.js +0 -1
  38. package/src/lib/cron-expression.js +35 -40
  39. package/src/lib/date.js +1 -10
  40. package/src/lib/events.js +1 -3
  41. package/src/lib/http-client-schema-form.js +12 -13
  42. package/src/lib/http.js +56 -57
  43. package/src/lib/i18n.js +22 -30
  44. package/src/lib/item.js +12 -13
  45. package/src/lib/properties.js +42 -77
  46. package/src/lib/schema-form.js +5 -4
  47. package/src/lib/studio.js +60 -13
  48. package/src/lib/style.js +8 -8
  49. package/src/lib/text-format.js +7 -14
  50. package/src/lib/theme.js +5 -8
  51. package/src/lib/utils.js +18 -17
  52. package/src/mixins/chart-element.js +54 -31
  53. package/src/mixins/input-element.js +47 -60
  54. package/src/mixins/item-resource.js +32 -34
  55. package/src/mixins/keyboard-element.js +5 -6
  56. package/src/mixins/update-after-browser.js +1 -4
  57. package/src/mixins/with-resize-observer.js +13 -23
  58. package/src/mixins/with-skeleton-attribute.js +48 -54
  59. package/src/molecules/gv-card-full.js +147 -26
  60. package/src/molecules/gv-card-list.js +42 -13
  61. package/src/molecules/gv-card.js +91 -17
  62. package/src/molecules/gv-category-list.js +17 -6
  63. package/src/molecules/gv-category.js +103 -23
  64. package/src/molecules/gv-code.js +143 -81
  65. package/src/molecules/gv-confirm.js +71 -41
  66. package/src/molecules/gv-cron-editor.js +389 -143
  67. package/src/molecules/gv-dropdown-menu.js +46 -14
  68. package/src/molecules/gv-expandable.js +59 -31
  69. package/src/molecules/gv-expression-language.js +138 -176
  70. package/src/molecules/gv-identity-picture.js +65 -42
  71. package/src/molecules/gv-list.js +134 -42
  72. package/src/molecules/gv-metrics.js +49 -37
  73. package/src/molecules/gv-modal.js +95 -28
  74. package/src/molecules/gv-nav.js +75 -49
  75. package/src/molecules/gv-option.js +130 -57
  76. package/src/molecules/gv-plans.js +209 -86
  77. package/src/molecules/gv-popover.js +177 -57
  78. package/src/molecules/gv-promote.js +146 -28
  79. package/src/molecules/gv-rating-list.js +195 -69
  80. package/src/molecules/gv-rating.js +105 -52
  81. package/src/molecules/gv-row-expandable.js +11 -5
  82. package/src/molecules/gv-row.js +147 -21
  83. package/src/molecules/gv-stats.js +48 -23
  84. package/src/molecules/gv-stepper.js +187 -43
  85. package/src/molecules/gv-table.js +309 -199
  86. package/src/molecules/gv-tree.js +156 -33
  87. package/src/organisms/gv-documentation.js +128 -45
  88. package/src/organisms/gv-header.js +195 -37
  89. package/src/organisms/gv-http-client.js +168 -32
  90. package/src/organisms/gv-menu.js +158 -37
  91. package/src/organisms/gv-newsletter-subscription.js +189 -48
  92. package/src/organisms/gv-pagination.js +77 -49
  93. package/src/organisms/gv-properties.js +492 -271
  94. package/src/organisms/gv-resizable-views.js +259 -41
  95. package/src/organisms/gv-resources.js +275 -168
  96. package/src/organisms/gv-schema-form-array.js +159 -49
  97. package/src/organisms/gv-schema-form-control-object.js +73 -59
  98. package/src/organisms/gv-schema-form-control.js +134 -107
  99. package/src/organisms/gv-schema-form.js +324 -195
  100. package/src/organisms/gv-tabs.js +98 -66
  101. package/src/organisms/gv-user-menu.js +201 -36
  102. package/src/organisms/gv-vertical-menu.js +61 -20
  103. package/src/policy-studio/gv-flow-step.js +266 -105
  104. package/src/policy-studio/gv-flow.js +304 -125
  105. package/src/policy-studio/gv-policy-studio-menu.js +471 -157
  106. package/src/policy-studio/gv-policy-studio.js +777 -686
  107. package/src/styles/empty.js +20 -3
  108. package/src/styles/input.js +247 -3
  109. package/src/styles/link.js +16 -3
  110. package/src/styles/shapes.js +0 -1
  111. package/src/styles/skeleton.js +37 -3
  112. package/src/styles/zoom.js +24 -3
  113. package/src/theme/definition.json +1762 -0
  114. package/src/theme/gv-theme.js +60 -21
@@ -16,6 +16,7 @@
16
16
  import { css, html, LitElement } from 'lit';
17
17
  import { methods } from '../lib/studio';
18
18
  import { dispatchCustomEvent } from '../lib/events';
19
+ import { i18n } from '../lib/i18n';
19
20
  import '../atoms/gv-button';
20
21
  import '../atoms/gv-icon';
21
22
  import '../molecules/gv-option';
@@ -32,7 +33,9 @@ import { empty } from '../styles/empty';
32
33
  import { cache } from 'lit/directives/cache';
33
34
  import { deepClone, deepEqual } from '../lib/utils';
34
35
  import { KeyboardElement, KEYS } from '../mixins/keyboard-element';
36
+
35
37
  const FLOW_STEP_FORM_ID = 'flow-step-form';
38
+
36
39
  /**
37
40
  * Studio Policy component
38
41
  *
@@ -65,168 +68,276 @@ const FLOW_STEP_FORM_ID = 'flow-step-form';
65
68
  * @attr {Boolean} has-policy-filter - true if policies have onRequest/onResponse properties
66
69
  * @attr {Boolean} can-debug - true if debug tab should be displayed
67
70
  * @attr {Object} debugResponse - true if debug tab should be displayed
71
+ * @attr {Boolean} has-conditional-steps - true if steps can be conditioned
68
72
  */
69
-
70
73
  export class GvPolicyStudio extends KeyboardElement(LitElement) {
71
74
  static get properties() {
72
75
  return {
73
- policies: {
74
- type: Array
75
- },
76
- services: {
77
- type: Object
78
- },
79
- resourceTypes: {
80
- type: Array,
81
- attribute: 'resource-types'
82
- },
83
- propertyProviders: {
84
- type: Array,
85
- attribute: 'property-providers'
86
- },
87
- dynamicPropertySchema: {
88
- type: Object,
89
- attribute: 'dynamic-property-schema'
90
- },
91
- tabId: {
92
- type: String,
93
- attribute: 'tab-id'
94
- },
95
- _tabId: {
96
- type: String,
97
- attribute: false
98
- },
99
- definition: {
100
- type: Object
101
- },
102
- _definition: {
103
- type: Object,
104
- attribute: false
105
- },
106
- documentation: {
107
- type: Object
108
- },
109
- flowSchema: {
110
- type: Object,
111
- attribute: 'flow-schema'
112
- },
113
- configurationSchema: {
114
- type: Object,
115
- attribute: 'configuration-schema'
116
- },
117
- _configurationSchema: {
118
- type: Object,
119
- attribute: false
120
- },
121
- configurationInformation: {
122
- type: String,
123
- attribute: 'configuration-information'
124
- },
125
- isDirty: {
126
- type: Boolean,
127
- attribute: 'dirty',
128
- reflect: true
129
- },
130
- _dragPolicy: {
131
- type: Object,
132
- attribute: false
133
- },
134
- _dropPolicy: {
135
- type: Object,
136
- attribute: false
137
- },
138
- selectedFlowsId: {
139
- type: Array,
140
- attribute: 'selected-flows-id'
141
- },
142
- _selectedFlowsId: {
143
- type: Array,
144
- attribute: false
145
- },
146
- _currentPolicyId: {
147
- type: String,
148
- attribute: false
149
- },
150
- _searchPolicyQuery: {
151
- type: String,
152
- attribute: false
153
- },
154
- _searchFlowQuery: {
155
- type: String,
156
- attribute: false
157
- },
158
- _flowStepSchema: {
159
- type: Object,
160
- attribute: false
161
- },
162
- _currentFlowStep: {
163
- type: Object,
164
- attribute: false
165
- },
166
- _policyFilter: {
167
- type: Array,
168
- attribute: false
169
- },
170
- _flowFilter: {
171
- type: Array,
172
- attribute: false
173
- },
174
- _currentAskConfirmation: {
175
- type: Boolean,
176
- attribute: false
177
- },
178
- hasProperties: {
179
- type: Boolean,
180
- attribute: 'has-properties'
181
- },
182
- _hasProperties: {
183
- type: Boolean,
184
- attribute: false
185
- },
186
- hasResources: {
187
- type: Boolean,
188
- attribute: 'has-resources'
189
- },
190
- hasPolicyFilter: {
191
- type: Boolean,
192
- attribute: 'has-policy-filter'
193
- },
194
- flowsTitle: {
195
- type: String,
196
- attribute: 'flows-title'
197
- },
198
- sortable: {
199
- type: Boolean
200
- },
201
- canAdd: {
202
- type: Boolean,
203
- attribute: 'can-add'
204
- },
205
- readonly: {
206
- type: Boolean
207
- },
208
- readonlyPlans: {
209
- type: Boolean,
210
- attribute: 'readonly-plans'
211
- },
212
- canDebug: {
213
- type: Boolean,
214
- attribute: 'can-debug'
215
- },
216
- _canDebug: {
217
- type: Boolean,
218
- attribute: false
219
- },
220
- debugResponse: {
221
- type: Object,
222
- attribute: 'debug-response'
223
- }
76
+ policies: { type: Array },
77
+ services: { type: Object },
78
+ resourceTypes: { type: Array, attribute: 'resource-types' },
79
+ propertyProviders: { type: Array, attribute: 'property-providers' },
80
+ dynamicPropertySchema: { type: Object, attribute: 'dynamic-property-schema' },
81
+ tabId: { type: String, attribute: 'tab-id' },
82
+ _tabId: { type: String, attribute: false },
83
+ definition: { type: Object },
84
+ _definition: { type: Object, attribute: false },
85
+ documentation: { type: Object },
86
+ flowSchema: { type: Object, attribute: 'flow-schema' },
87
+ configurationSchema: { type: Object, attribute: 'configuration-schema' },
88
+ _configurationSchema: { type: Object, attribute: false },
89
+ configurationInformation: { type: String, attribute: 'configuration-information' },
90
+ isDirty: { type: Boolean, attribute: 'dirty', reflect: true },
91
+ _dragPolicy: { type: Object, attribute: false },
92
+ _dropPolicy: { type: Object, attribute: false },
93
+ selectedFlowsId: { type: Array, attribute: 'selected-flows-id' },
94
+ _selectedFlowsId: { type: Array, attribute: false },
95
+ _currentPolicyId: { type: String, attribute: false },
96
+ _searchPolicyQuery: { type: String, attribute: false },
97
+ _searchFlowQuery: { type: String, attribute: false },
98
+ _flowStepSchema: { type: Object, attribute: false },
99
+ _currentFlowStep: { type: Object, attribute: false },
100
+ _policyFilter: { type: Array, attribute: false },
101
+ _flowFilter: { type: Array, attribute: false },
102
+ _currentAskConfirmation: { type: Boolean, attribute: false },
103
+ hasProperties: { type: Boolean, attribute: 'has-properties' },
104
+ _hasProperties: { type: Boolean, attribute: false },
105
+ hasResources: { type: Boolean, attribute: 'has-resources' },
106
+ hasPolicyFilter: { type: Boolean, attribute: 'has-policy-filter' },
107
+ flowsTitle: { type: String, attribute: 'flows-title' },
108
+ sortable: { type: Boolean },
109
+ canAdd: { type: Boolean, attribute: 'can-add' },
110
+ readonly: { type: Boolean },
111
+ readonlyPlans: { type: Boolean, attribute: 'readonly-plans' },
112
+ canDebug: { type: Boolean, attribute: 'can-debug' },
113
+ _canDebug: { type: Boolean, attribute: false },
114
+ debugResponse: { type: Object, attribute: 'debug-response' },
115
+ hasConditionalSteps: { type: Boolean, attribute: 'has-conditional-steps' },
224
116
  };
225
117
  }
226
118
 
227
119
  static get styles() {
228
- return [empty, methods, // language=CSS
229
- css`:host{box-sizing:border-box;--height:var(--gv-policy-studio--h, calc(100vh - 32px));height:var(--height);--height-in-tabs:calc(var(--height) - 25px)}.box{height:var(--height);display:flex}.design,.properties{display:flex}gv-resizable-views{width:100%}.editable-name{padding:.5rem 1rem;font-size:16px}.editable-name span{color:#bfbfbf;font-size:12px}.form__control{margin:.5rem}gv-input{width:100%}.flow-name{display:flex;align-items:center}.flow-name.dirty{font-style:italic;opacity:.8}.flow-name gv-icon{--gv-icon--s:24px;margin-right:.2rem}.flow-path{margin-left:.2rem}.title_methods{margin-left:.5rem}.two-cols{display:flex;width:100%;height:100%}.two-cols>*{flex:1}.left-menu{border-left:1px solid #d9d9d9;height:var(--height-in-tabs)}.right-menu{border-right:1px solid #d9d9d9;height:var(--height-in-tabs)}.two-cols>:first-child{border-right:1px solid #d9d9d9}.flow-step__container{overflow:hidden;position:relative;overflow:hidden;height:99%}.flow-step__form{padding:0 .5rem;overflow:auto}.flow-step__form-title{text-transform:uppercase;letter-spacing:.2rem}gv-tabs{width:100%;height:100%;display:inline-block}gv-properties,gv-resizable-views,gv-resources{height:var(--height-in-tabs)}gv-properties,gv-resources{width:100%}gv-properties.properties{--gv-properties-table--colmg:10px}.api-settings{display:flex;flex-direction:column;border-left:1px solid #bfbfbf;height:var(--height-in-tabs)}.debug{display:flex;flex-direction:column;border-left:1px solid #bfbfbf;height:var(--height-in-tabs)}.api-settings-information{display:flex;align-items:center}.api-settings-information__icon{--gv-icon--c:var(--gv-theme-color, #5a7684);--gv-icon-opacity--c:var(--gv-theme-color-info-light, #64b5f6)}.api-settings-information__blockquote,.debug-information__blockquote{border-left:1px solid var(--gv-theme-color,#5a7684);margin:15px;padding-left:15px;font-size:14px}.flow-settings gv-schema-form{flex:1;padding:.5rem}.search{display:flex;justify-content:stretch}gv-input{margin:.2rem 0;width:100%}.header-actions,.search-policies{display:flex;flex-direction:column;align-items:center;margin:.5rem}.search-policies{margin:1.5rem .5rem .5rem}.footer-actions>gv-button.btn-large,.footer-actions>gv-option{width:100%}.footer-actions{display:flex;flex-direction:column;align-items:center;padding:.5rem 0;margin:.5rem 15px;border-top:1px solid #bfbfbf}.header-actions .title{text-transform:uppercase;text-align:center;letter-spacing:.3rem;color:#bfbfbf;font-size:18px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:240px;min-height:25px}.header-actions>*,.search-policies>*{margin-bottom:1rem}`];
120
+ return [
121
+ empty,
122
+ methods,
123
+ // language=CSS
124
+ css`
125
+ :host {
126
+ box-sizing: border-box;
127
+ --height: var(--gv-policy-studio--h, calc(100vh - 32px));
128
+ height: var(--height);
129
+ --height-in-tabs: calc(var(--height) - 25px);
130
+ }
131
+
132
+ .box {
133
+ height: var(--height);
134
+ display: flex;
135
+ }
136
+
137
+ .design,
138
+ .properties {
139
+ display: flex;
140
+ }
141
+
142
+ gv-resizable-views {
143
+ width: 100%;
144
+ }
145
+
146
+ .editable-name {
147
+ padding: 0.5rem 1rem;
148
+ font-size: 16px;
149
+ }
150
+
151
+ .editable-name span {
152
+ color: #bfbfbf;
153
+ font-size: 12px;
154
+ }
155
+
156
+ .form__control {
157
+ margin: 0.5rem;
158
+ }
159
+
160
+ gv-input {
161
+ width: 100%;
162
+ }
163
+
164
+ .flow-name {
165
+ display: flex;
166
+ align-items: center;
167
+ }
168
+
169
+ .flow-name.dirty {
170
+ font-style: italic;
171
+ opacity: 0.8;
172
+ }
173
+
174
+ .flow-name gv-icon {
175
+ --gv-icon--s: 24px;
176
+ margin-right: 0.2rem;
177
+ }
178
+
179
+ .flow-path {
180
+ margin-left: 0.2rem;
181
+ }
182
+
183
+ .title_methods {
184
+ margin-left: 0.5rem;
185
+ }
186
+
187
+ .two-cols {
188
+ display: flex;
189
+ width: 100%;
190
+ height: 100%;
191
+ }
192
+
193
+ .two-cols > * {
194
+ flex: 1;
195
+ }
196
+
197
+ .left-menu {
198
+ border-left: 1px solid #d9d9d9;
199
+ height: var(--height-in-tabs);
200
+ }
201
+
202
+ .right-menu {
203
+ border-right: 1px solid #d9d9d9;
204
+ height: var(--height-in-tabs);
205
+ }
206
+
207
+ .two-cols > *:first-child {
208
+ border-right: 1px solid #d9d9d9;
209
+ }
210
+
211
+ .flow-step__container {
212
+ overflow: hidden;
213
+ position: relative;
214
+ overflow: hidden;
215
+ height: 99%;
216
+ }
217
+
218
+ .flow-step__form {
219
+ padding: 0 0.5rem;
220
+ overflow: auto;
221
+ }
222
+
223
+ .flow-step__form-title {
224
+ text-transform: uppercase;
225
+ letter-spacing: 0.2rem;
226
+ }
227
+
228
+ gv-tabs {
229
+ width: 100%;
230
+ height: 100%;
231
+ display: inline-block;
232
+ }
233
+
234
+ gv-resizable-views,
235
+ gv-properties,
236
+ gv-resources {
237
+ height: var(--height-in-tabs);
238
+ }
239
+
240
+ gv-properties,
241
+ gv-resources {
242
+ width: 100%;
243
+ }
244
+
245
+ gv-properties.properties {
246
+ --gv-properties-table--colmg: 10px;
247
+ }
248
+
249
+ .api-settings {
250
+ display: flex;
251
+ flex-direction: column;
252
+ border-left: 1px solid #bfbfbf;
253
+ height: var(--height-in-tabs);
254
+ }
255
+
256
+ .debug {
257
+ display: flex;
258
+ flex-direction: column;
259
+ border-left: 1px solid #bfbfbf;
260
+ height: var(--height-in-tabs);
261
+ }
262
+
263
+ .api-settings-information {
264
+ display: flex;
265
+ align-items: center;
266
+ }
267
+
268
+ .api-settings-information__icon {
269
+ --gv-icon--c: var(--gv-theme-color, #5a7684);
270
+ --gv-icon-opacity--c: var(--gv-theme-color-info-light, #64b5f6);
271
+ }
272
+
273
+ .api-settings-information__blockquote,
274
+ .debug-information__blockquote {
275
+ border-left: 1px solid var(--gv-theme-color, #5a7684);
276
+ margin: 15px;
277
+ padding-left: 15px;
278
+ font-size: 14px;
279
+ }
280
+
281
+ .flow-settings gv-schema-form {
282
+ flex: 1;
283
+ padding: 0.5rem;
284
+ }
285
+
286
+ .search {
287
+ display: flex;
288
+ justify-content: stretch;
289
+ }
290
+
291
+ gv-input {
292
+ margin: 0.2rem 0;
293
+ width: 100%;
294
+ }
295
+
296
+ .header-actions,
297
+ .search-policies {
298
+ display: flex;
299
+ flex-direction: column;
300
+ align-items: center;
301
+ margin: 0.5rem;
302
+ }
303
+
304
+ .search-policies {
305
+ margin: 1.5rem 0.5rem 0.5rem;
306
+ }
307
+
308
+ .footer-actions > gv-button.btn-large,
309
+ .footer-actions > gv-option {
310
+ width: 100%;
311
+ }
312
+
313
+ .footer-actions {
314
+ display: flex;
315
+ flex-direction: column;
316
+ align-items: center;
317
+ padding: 0.5rem 0;
318
+ margin: 0.5rem 15px;
319
+ border-top: 1px solid #bfbfbf;
320
+ }
321
+
322
+ .header-actions .title {
323
+ text-transform: uppercase;
324
+ text-align: center;
325
+ letter-spacing: 0.3rem;
326
+ color: #bfbfbf;
327
+ font-size: 18px;
328
+ white-space: nowrap;
329
+ overflow: hidden;
330
+ text-overflow: ellipsis;
331
+ width: 240px;
332
+ min-height: 25px;
333
+ }
334
+
335
+ .header-actions > *,
336
+ .search-policies > * {
337
+ margin-bottom: 1rem;
338
+ }
339
+ `,
340
+ ];
230
341
  }
231
342
 
232
343
  constructor() {
@@ -240,13 +351,9 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
240
351
  this.sortable = false;
241
352
  this.services = {};
242
353
  this._definition = {
243
- flows: []
354
+ flows: [],
244
355
  };
245
- this._tabs = [{
246
- id: 'design',
247
- title: 'Design',
248
- icon: 'navigation:exchange'
249
- }];
356
+ this._tabs = [{ id: 'design', title: 'Design', icon: 'navigation:exchange' }];
250
357
  this._policyFilter = [];
251
358
  this._flowFilter = [];
252
359
  }
@@ -254,15 +361,10 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
254
361
  set hasProperties(value) {
255
362
  if (value) {
256
363
  import('../organisms/gv-properties').then(() => {
257
- this._tabs = [...this._tabs, {
258
- id: 'properties',
259
- title: 'Properties',
260
- icon: 'general:settings#1'
261
- }];
364
+ this._tabs = [...this._tabs, { id: 'properties', title: 'Properties', icon: 'general:settings#1' }];
262
365
  this.requestUpdate();
263
366
  });
264
367
  }
265
-
266
368
  this._hasProperties = value;
267
369
  }
268
370
 
@@ -273,11 +375,7 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
273
375
  set hasResources(value) {
274
376
  if (value) {
275
377
  import('../organisms/gv-resources').then(() => {
276
- this._tabs = [...this._tabs, {
277
- id: 'resources',
278
- title: 'Resources',
279
- icon: 'general:settings#5'
280
- }];
378
+ this._tabs = [...this._tabs, { id: 'resources', title: 'Resources', icon: 'general:settings#5' }];
281
379
  this.requestUpdate();
282
380
  });
283
381
  }
@@ -285,49 +383,31 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
285
383
 
286
384
  set canDebug(value) {
287
385
  if (value) {
288
- this._tabs = [...this._tabs, {
289
- id: 'debug',
290
- title: 'Try it',
291
- icon: 'content:send'
292
- }];
386
+ this._tabs = [...this._tabs, { id: 'debug', title: 'Try it', icon: 'content:send' }];
293
387
  }
294
388
  }
295
389
 
296
390
  get _flowFilterOptions() {
297
391
  if (this.definedPlans.length > 0) {
298
- return [{
299
- id: 'api',
300
- title: 'Api',
301
- icon: 'shopping:box#3'
302
- }, {
303
- id: 'plan',
304
- title: 'Plans',
305
- icon: 'shopping:sale#2'
306
- }];
392
+ return [
393
+ { id: 'api', title: 'Api', icon: 'shopping:box#3' },
394
+ { id: 'plan', title: 'Plans', icon: 'shopping:sale#2' },
395
+ ];
307
396
  }
308
397
  }
309
398
 
310
399
  set hasPolicyFilter(value) {
311
400
  if (value) {
312
- this._policyFilterOptions = [{
313
- id: 'onRequest',
314
- title: 'Request',
315
- icon: 'navigation:arrow-from-left'
316
- }, {
317
- id: 'onResponse',
318
- title: 'Response',
319
- icon: 'navigation:arrow-from-right'
320
- }];
401
+ this._policyFilterOptions = [
402
+ { id: 'onRequest', title: 'Request', icon: 'navigation:arrow-from-left' },
403
+ { id: 'onResponse', title: 'Response', icon: 'navigation:arrow-from-right' },
404
+ ];
321
405
  }
322
406
  }
323
407
 
324
408
  set configurationSchema(value) {
325
409
  if (value) {
326
- this._tabs.splice(1, 0, {
327
- id: 'settings',
328
- title: 'Configuration',
329
- icon: 'general:settings#2'
330
- });
410
+ this._tabs.splice(1, 0, { id: 'settings', title: 'Configuration', icon: 'general:settings#2' });
331
411
  }
332
412
 
333
413
  this._configurationSchema = value;
@@ -341,13 +421,11 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
341
421
  if (this._currentAskConfirmation == null) {
342
422
  if (this.isPressed(KEYS.Shift, KEYS.Ctrl, KEYS.Space)) {
343
423
  const search = this.shadowRoot.querySelector('#search-policy');
344
-
345
424
  if (search) {
346
425
  search.focus();
347
426
  }
348
427
  } else if (this.isPressed(KEYS.Ctrl, KEYS.Space)) {
349
428
  const search = this.shadowRoot.querySelector('#search-flow');
350
-
351
429
  if (search) {
352
430
  search.focus();
353
431
  }
@@ -370,22 +448,16 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
370
448
  set definition(definition) {
371
449
  if (definition) {
372
450
  const flows = this._generateFlowsId(definition.flows);
373
-
374
451
  const resources = this._generateId('resource-', definition.resources);
375
-
376
- const plans = definition.plans == null ? [] : definition.plans.map(plan => {
377
- return { ...plan,
378
- flows: this._generatePlanFlowsId(plan)
379
- };
380
- });
381
- this._initialDefinition = { ...definition,
382
- flows,
383
- resources,
384
- plans
385
- };
452
+ const plans =
453
+ definition.plans == null
454
+ ? []
455
+ : definition.plans.map((plan) => {
456
+ return { ...plan, flows: this._generatePlanFlowsId(plan) };
457
+ });
458
+ this._initialDefinition = { ...definition, flows, resources, plans };
386
459
  this._definition = deepClone(this._initialDefinition);
387
460
  this.isDirty = false;
388
-
389
461
  this._selectFirstFlow();
390
462
  }
391
463
  }
@@ -396,8 +468,7 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
396
468
 
397
469
  set selectedFlowsId(selectedFlowsId) {
398
470
  if (selectedFlowsId != null && Array.isArray(selectedFlowsId)) {
399
- this._selectedFlowsId = selectedFlowsId.filter(id => this._findFlowById(id) != null);
400
-
471
+ this._selectedFlowsId = selectedFlowsId.filter((id) => this._findFlowById(id) != null);
401
472
  if (selectedFlowsId.length !== this._selectedFlowsId.length) {
402
473
  this._selectFirstFlow(true);
403
474
  }
@@ -405,30 +476,25 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
405
476
  }
406
477
 
407
478
  get selectedFlowsId() {
408
- return this._selectedFlowsId.filter(id => this._findFlowById(id) != null);
479
+ return this._selectedFlowsId.filter((id) => this._findFlowById(id) != null);
409
480
  }
410
481
 
411
482
  _updateSelectedFlows(selectedFlowsId) {
412
483
  this.selectedFlowsId = selectedFlowsId;
413
- dispatchCustomEvent(this, 'select-flows', {
414
- flows: this.selectedFlowsId
415
- });
484
+ dispatchCustomEvent(this, 'select-flows', { flows: this.selectedFlowsId });
416
485
  }
417
486
 
418
487
  _selectFirstFlow(dispatch = false) {
419
488
  if (this.selectedFlowsId.length === 0) {
420
489
  let candidate = null;
421
-
422
490
  if (this.definedFlows.length > 0 && this.definedFlows[0]._id != null) {
423
491
  candidate = this.definedFlows[0];
424
492
  } else if (this.definedPlans.length > 0) {
425
- const plan = this.definedPlans.find(plan => plan.flows != null && plan.flows.length > 0 && plan.flows[0]._id != null);
426
-
493
+ const plan = this.definedPlans.find((plan) => plan.flows != null && plan.flows.length > 0 && plan.flows[0]._id != null);
427
494
  if (plan) {
428
495
  candidate = plan.flows[0];
429
496
  }
430
497
  }
431
-
432
498
  if (candidate != null) {
433
499
  if (dispatch) {
434
500
  this._updateSelectedFlows([candidate._id]);
@@ -444,26 +510,21 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
444
510
  }
445
511
 
446
512
  _onDragEndPolicy() {
447
- this.shadowRoot.querySelectorAll('gv-flow').forEach(e => e.onDragEnd());
513
+ this.shadowRoot.querySelectorAll('gv-flow').forEach((e) => e.onDragEnd());
448
514
  }
449
515
 
450
- async _onDropPolicy({
451
- detail
452
- }) {
516
+ async _onDropPolicy({ detail }) {
453
517
  try {
454
518
  await this._askToValidateForms();
455
- const policy = detail.policy;
456
519
 
520
+ const policy = detail.policy;
457
521
  const targetFlow = this._findFlowById(detail.flowId);
458
522
 
459
523
  let name = policy.name;
460
524
  let description = '';
461
525
  let configuration = {};
462
-
463
526
  let _id;
464
-
465
527
  let _new = false;
466
-
467
528
  if (detail.flowStep) {
468
529
  _id = detail.flowStep._id;
469
530
  name = detail.flowStep.name;
@@ -474,28 +535,18 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
474
535
  _new = true;
475
536
  }
476
537
 
477
- const flowStep = {
478
- _id,
479
- _new,
480
- name,
481
- policy: policy.id,
482
- description,
483
- enabled: true,
484
- configuration
485
- };
538
+ const flowStep = { _id, _new, name, policy: policy.id, description, enabled: true, configuration };
486
539
  const sourceFlow = detail.sourceFlowId != null ? this._findFlowById(detail.sourceFlowId) : targetFlow;
487
540
 
488
541
  if (detail.sourcePosition != null) {
489
542
  if (detail.sourceFlowKey && detail.sourceFlowKey !== detail.flowKey) {
490
543
  sourceFlow[detail.sourceFlowKey].splice(detail.sourcePosition, 1);
491
544
  targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
492
-
493
545
  if (this._currentFlowStep != null && this._currentFlowStep.step._id === _id) {
494
- this._currentFlowStep.group = detail.flowKey; // Special case for update schema after change request to response or inverse
495
-
546
+ this._currentFlowStep.group = detail.flowKey;
547
+ // Special case for update schema after change request to response or inverse
496
548
  const schema = this.buildSchema(this._currentFlowStep.policy);
497
549
  await this._setCurrentFlowStep(this._currentFlowStep, schema, true);
498
-
499
550
  this._getFlowElement(targetFlow._id).requestUpdate();
500
551
  }
501
552
  } else {
@@ -506,20 +557,16 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
506
557
  sourceFlow[detail.flowKey].splice(detail.sourcePosition, 1);
507
558
  targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
508
559
  }
509
- } // Force Refresh source flow element when move to other flow
510
-
511
-
560
+ }
561
+ // Force Refresh source flow element when move to other flow
512
562
  if (targetFlow._id !== sourceFlow._id) {
513
563
  this._getFlowElement(targetFlow._id).requestUpdate();
514
564
  }
515
565
  } else {
516
566
  targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
517
-
518
567
  const currentFlowForm = this._getFlowStepForm();
519
-
520
568
  if (currentFlowForm == null || currentFlowForm.dirty !== true) {
521
569
  let step = targetFlow[detail.flowKey][detail.position];
522
-
523
570
  if (step == null) {
524
571
  // When confirm lose change after drop policy
525
572
  step = targetFlow[detail.flowKey][detail.position - 1];
@@ -527,15 +574,9 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
527
574
 
528
575
  if (detail.cancelEdit !== true) {
529
576
  setTimeout(async () => {
530
- await this._editFlowStep({
531
- step,
532
- policy,
533
- flow: targetFlow,
534
- group: detail.flowKey
535
- });
577
+ await this._editFlowStep({ step, policy, flow: targetFlow, group: detail.flowKey });
536
578
  this.updateComplete.then(() => {
537
579
  const flowElement = this._getFlowElement(targetFlow._id);
538
-
539
580
  flowElement.selectedStepId = step._id;
540
581
  flowElement.requestUpdate();
541
582
  });
@@ -543,11 +584,10 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
543
584
  }
544
585
  }
545
586
  }
546
-
547
587
  targetFlow._dirty = true;
548
588
  sourceFlow._dirty = true;
549
589
  this.isDirty = true;
550
- this.shadowRoot.querySelectorAll('gv-flow').forEach(gvFlow => gvFlow.removeCandidate());
590
+ this.shadowRoot.querySelectorAll('gv-flow').forEach((gvFlow) => gvFlow.removeCandidate());
551
591
  setTimeout(() => {
552
592
  this._dragPolicy = null;
553
593
  this._dropPolicy = null;
@@ -557,78 +597,53 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
557
597
  }
558
598
  }
559
599
 
560
- _onDeletePolicy({
561
- detail
562
- }) {
600
+ _onDeletePolicy({ detail }) {
563
601
  const targetFlow = this._findFlowById(detail.flowId);
564
-
565
602
  targetFlow[detail.flowKey].splice(detail.position, 1);
566
603
  targetFlow._dirty = true;
567
604
  this.isDirty = true;
568
-
569
605
  if (detail.target.editing) {
570
606
  this._closeFlowStepForm(true);
571
607
  }
572
-
573
608
  this._getFlowElement(detail.flowId).requestUpdate();
574
609
  }
575
610
 
576
611
  _onDesign() {
577
612
  this._changeTab('design');
578
-
579
613
  this._splitMainViews();
580
614
  }
581
615
 
582
- buildSchema({
583
- schema
584
- }) {
616
+ buildSchema({ schema }) {
585
617
  const description = {
586
618
  title: 'Description',
587
619
  description: 'Description of flow step',
588
- type: 'string'
620
+ type: 'string',
621
+ };
622
+ const condition = {
623
+ title: 'Condition',
624
+ description: 'Condition the execution of the flow step (support EL)',
625
+ type: 'string',
626
+ 'x-schema-form': {
627
+ 'expression-language': true,
628
+ },
589
629
  };
590
-
591
630
  if (schema) {
592
631
  const jsonSchema = typeof schema === 'string' ? JSON.parse(schema) : schema;
593
- const properties = {
594
- description,
595
- ...jsonSchema.properties
596
- };
597
- return { ...jsonSchema,
598
- properties
599
- };
632
+ const properties = { description, ...(this.hasConditionalSteps ? { condition } : {}), ...jsonSchema.properties };
633
+ return { ...jsonSchema, properties };
600
634
  }
601
-
602
- return {
603
- properties: {
604
- description
605
- }
606
- };
635
+ return { properties: { description, ...(this.hasConditionalSteps ? { condition } : {}) } };
607
636
  }
608
637
 
609
- async _editFlowStep({
610
- step,
611
- flow,
612
- policy,
613
- group
614
- }) {
638
+ async _editFlowStep({ step, flow, policy, group }) {
615
639
  if (step) {
616
640
  this._currentPolicyId = policy.id;
617
- const currentFlowStep = {
618
- flow,
619
- step,
620
- policy,
621
- group
622
- };
641
+ const currentFlowStep = { flow, step, policy, group };
623
642
  const schema = this.buildSchema(policy);
624
-
625
643
  try {
626
644
  await this._setCurrentFlowStep(currentFlowStep, schema);
627
-
628
645
  this._updateSelectedFlows([flow._id]);
629
-
630
646
  this._splitMainViews();
631
-
632
647
  if (localStorage.getItem('gv-policy-studio:keep-documentation-close') == null) {
633
648
  this._onOpenDocumentation();
634
649
  }
@@ -637,25 +652,12 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
637
652
  }
638
653
  } else {
639
654
  await this._closeFlowStepForm();
640
-
641
655
  this._maximizeTopView();
642
656
  }
643
657
  }
644
658
 
645
- async _onEditFlowStep({
646
- detail: {
647
- step,
648
- flow,
649
- policy,
650
- group
651
- }
652
- }) {
653
- return this._editFlowStep({
654
- step,
655
- flow,
656
- policy,
657
- group
658
- });
659
+ async _onEditFlowStep({ detail: { step, flow, policy, group } }) {
660
+ return this._editFlowStep({ step, flow, policy, group });
659
661
  }
660
662
 
661
663
  _getResizableViews() {
@@ -676,11 +678,8 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
676
678
  this._getResizableViews().split();
677
679
  }
678
680
 
679
- _onChangeFlowStepState({
680
- detail
681
- }) {
681
+ _onChangeFlowStepState({ detail }) {
682
682
  const targetFlow = this._findFlowById(detail.flowId);
683
-
684
683
  const step = targetFlow[detail.flowKey][detail.position];
685
684
  step.enabled = detail.enabled;
686
685
  targetFlow._dirty = true;
@@ -702,13 +701,13 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
702
701
  async _askToValidateForms() {
703
702
  if (this._currentAskConfirmation == null) {
704
703
  this._currentAskConfirmation = true;
705
- return Promise.all(this._submitOrConfirmForms()).then(forms => {
706
- if (forms.filter(r => r != null).length > 0) {
704
+ return Promise.all(this._submitOrConfirmForms()).then((forms) => {
705
+ if (forms.filter((r) => r != null).length > 0) {
707
706
  this._definition = this._buildDefinitionToSave();
708
- this.getChildren().forEach(e => e.requestUpdate()); // Refresh if lose changes lost current step selection
709
-
707
+ this.getChildren().forEach((e) => e.requestUpdate());
708
+ // Refresh if lose changes lost current step selection
710
709
  return this._checkCurrentFlowStep().then(() => {
711
- this.getChildren().forEach(e => e.requestUpdate());
710
+ this.getChildren().forEach((e) => e.requestUpdate());
712
711
  return this.updateComplete.then(() => {
713
712
  this._currentAskConfirmation = null;
714
713
  return forms;
@@ -720,7 +719,6 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
720
719
  }
721
720
  });
722
721
  }
723
-
724
722
  throw new Error('ask already waiting');
725
723
  }
726
724
 
@@ -730,33 +728,26 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
730
728
  }
731
729
 
732
730
  const schema = deepClone(flowStepSchema);
733
-
734
731
  if (currentFlowStep != null) {
735
- const configuration = typeof currentFlowStep.step.configuration === 'string' ? JSON.parse(currentFlowStep.step.configuration) : currentFlowStep.step.configuration;
736
- const step = { ...currentFlowStep.step,
737
- configuration
738
- };
739
- const _initialValues = { ...step.configuration,
740
- description: step.description
741
- };
742
- this._currentFlowStep = { ...currentFlowStep,
743
- step,
744
- _initialValues
745
- };
732
+ const configuration =
733
+ typeof currentFlowStep.step.configuration === 'string'
734
+ ? JSON.parse(currentFlowStep.step.configuration)
735
+ : currentFlowStep.step.configuration;
736
+ const step = { ...currentFlowStep.step, configuration };
737
+
738
+ const _initialValues = { ...step.configuration, description: step.description, condition: step.condition };
739
+ this._currentFlowStep = { ...currentFlowStep, step, _initialValues };
746
740
 
747
741
  if (flowStepSchema && flowStepSchema.properties.scope) {
748
742
  const _enum = schema.properties.scope.enum;
749
-
750
- if (_enum.find(scope => ['REQUEST', 'REQUEST_CONTENT', 'RESPONSE', 'RESPONSE_CONTENT'].includes(scope)) != null) {
743
+ if (_enum.find((scope) => ['REQUEST', 'REQUEST_CONTENT', 'RESPONSE', 'RESPONSE_CONTENT'].includes(scope)) != null) {
751
744
  const filtered = this._currentFlowStep.group === 'pre' ? ['REQUEST', 'REQUEST_CONTENT'] : ['RESPONSE', 'RESPONSE_CONTENT'];
752
- schema.properties.scope.enum = _enum.filter(scope => filtered.includes(scope));
745
+ schema.properties.scope.enum = _enum.filter((scope) => filtered.includes(scope));
753
746
  const scope = this._currentFlowStep.step.configuration.scope;
754
-
755
747
  if (scope == null || !schema.properties.scope.enum.includes(scope)) {
756
748
  schema.properties.scope.default = schema.properties.scope.enum[0];
757
749
  this._currentFlowStep.step.configuration.scope = schema.properties.scope.enum[0];
758
750
  this._currentFlowStep._initialValues.scope = schema.properties.scope.enum[0];
759
-
760
751
  if (this._currentFlowStep._values) {
761
752
  this._currentFlowStep._values.scope = schema.properties.scope.enum[0];
762
753
  }
@@ -774,54 +765,38 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
774
765
  if (closeStepForm) {
775
766
  this._closeFlowStepForm(true);
776
767
  }
777
-
778
768
  this._definition = deepClone(this._definition);
779
769
  }
780
770
 
781
- async _onSelectFlows({
782
- detail
783
- }) {
771
+ async _onSelectFlows({ detail }) {
784
772
  try {
785
773
  await this._closeFlowStepForm();
786
-
787
774
  this._onCloseDocumentation();
788
-
789
775
  this._updateSelectedFlows(detail.flows);
790
-
791
776
  this._onDesign();
792
777
  } catch (e) {
793
778
  this._currentAskConfirmation = null;
794
779
  }
795
780
  }
796
781
 
797
- async _onOpenDocumentationFromMenu({
798
- detail: {
799
- policy
800
- }
801
- }) {
782
+ async _onOpenDocumentationFromMenu({ detail: { policy } }) {
802
783
  try {
803
784
  if (this.documentation == null || this.documentation.id !== policy.id) {
804
785
  await this._closeFlowStepForm();
805
786
  this._currentPolicyId = policy.id;
806
-
807
787
  if (this.getSelectedFlow()) {
808
788
  this._splitMainViews();
809
789
  } else {
810
790
  this._maximizeBottomView();
811
791
  }
812
-
813
- dispatchCustomEvent(this, 'fetch-documentation', {
814
- policy
815
- });
792
+ dispatchCustomEvent(this, 'fetch-documentation', { policy });
816
793
  }
817
794
  } catch (e) {}
818
795
  }
819
796
 
820
797
  _fetchDocumentation(policy) {
821
798
  if (this.documentation == null || this.documentation.id !== policy.id) {
822
- dispatchCustomEvent(this, 'fetch-documentation', {
823
- policy
824
- });
799
+ dispatchCustomEvent(this, 'fetch-documentation', { policy });
825
800
  }
826
801
  }
827
802
 
@@ -833,26 +808,20 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
833
808
 
834
809
  _onOpenDocumentationFromForm() {
835
810
  localStorage.removeItem('gv-policy-studio:keep-documentation-close');
836
-
837
811
  this._onOpenDocumentation();
838
812
  }
839
813
 
840
814
  _findFlowCollection(flowId) {
841
- const plan = this.definedPlans.find(plan => plan.flows.find(flow => flow._id === flowId) != null);
842
- return {
843
- plan,
844
- flows: plan != null ? plan.flows : this.definedFlows
845
- };
815
+ const plan = this.definedPlans.find((plan) => plan.flows.find((flow) => flow._id === flowId) != null);
816
+ return { plan, flows: plan != null ? plan.flows : this.definedFlows };
846
817
  }
847
818
 
848
819
  _findFlowById(flowId) {
849
- let flow = this.definedFlows.find(flow => flow._id === flowId);
850
-
820
+ let flow = this.definedFlows.find((flow) => flow._id === flowId);
851
821
  if (flow == null) {
852
- const plansFlows = this.definedPlans.map(plan => plan.flows).reduce((acc, val) => acc.concat(val), []);
853
- flow = plansFlows.find(flow => flow._id === flowId);
822
+ const plansFlows = this.definedPlans.map((plan) => plan.flows).reduce((acc, val) => acc.concat(val), []);
823
+ flow = plansFlows.find((flow) => flow._id === flowId);
854
824
  }
855
-
856
825
  return flow;
857
826
  }
858
827
 
@@ -861,32 +830,29 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
861
830
  return this._findFlowById(selectedFlowId);
862
831
  }
863
832
 
864
- _onTargetPolicy({
865
- detail
866
- }) {
833
+ _onTargetPolicy({ detail }) {
867
834
  if (this._currentAskConfirmation == null) {
868
835
  this._dragPolicy = detail;
869
836
  }
870
837
  }
871
838
 
872
- _onChangeFlowStep({
873
- detail
874
- }) {
839
+ _onChangeFlowStep({ detail }) {
875
840
  this._currentFlowStep._values = detail.values;
876
841
  }
877
842
 
878
843
  _writeFlowStep(values) {
879
- const {
880
- description,
881
- ...configuration
882
- } = values;
883
-
884
- if (this._currentFlowStep.step._new || this._currentFlowStep.step.description !== description || !deepEqual(this._currentFlowStep.step.configuration, configuration)) {
844
+ const { description, condition, ...configuration } = values;
845
+ if (
846
+ this._currentFlowStep.step._new ||
847
+ this._currentFlowStep.step.description !== description ||
848
+ this._currentFlowStep.step.condition !== condition ||
849
+ !deepEqual(this._currentFlowStep.step.configuration, configuration)
850
+ ) {
885
851
  const flow = this._findFlowById(this._currentFlowStep.flow._id);
886
-
887
- const position = flow[this._currentFlowStep.group].findIndex(step => step._id === this._currentFlowStep.step._id);
852
+ const position = flow[this._currentFlowStep.group].findIndex((step) => step._id === this._currentFlowStep.step._id);
888
853
 
889
854
  flow[this._currentFlowStep.group][position].description = description;
855
+ flow[this._currentFlowStep.group][position].condition = condition;
890
856
  flow[this._currentFlowStep.group][position].configuration = deepClone(configuration);
891
857
  delete flow[this._currentFlowStep.group][position]._new;
892
858
  flow[this._currentFlowStep.group][position]._dirty = true;
@@ -897,36 +863,23 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
897
863
  }
898
864
  }
899
865
 
900
- async _onSubmitFlowStep({
901
- detail
902
- }) {
866
+ async _onSubmitFlowStep({ detail }) {
903
867
  this._writeFlowStep(detail.values);
904
-
905
868
  await this.requestUpdate('_definition');
906
- this.getChildren().forEach(c => c.requestUpdate());
869
+ this.getChildren().forEach((c) => c.requestUpdate());
907
870
  }
908
871
 
909
872
  _onCancelFlow() {
910
873
  this._onDesign();
911
874
  }
912
875
 
913
- _onSubmitFlow({
914
- detail: {
915
- values
916
- }
917
- }) {
876
+ _onSubmitFlow({ detail: { values } }) {
918
877
  const selectedFlow = this.getSelectedFlow();
919
-
920
878
  const _values = Object.assign({}, this._createFlowFromSchema(), values);
921
-
922
879
  const selectedFlowUpdated = Object.assign({}, selectedFlow, _values);
923
-
924
880
  if (!deepEqual(selectedFlow, selectedFlowUpdated)) {
925
- Object.assign(selectedFlow, selectedFlowUpdated, {
926
- _dirty: true
927
- });
881
+ Object.assign(selectedFlow, selectedFlowUpdated, { _dirty: true });
928
882
  this.isDirty = true;
929
-
930
883
  this._refresh();
931
884
  }
932
885
  }
@@ -935,36 +888,24 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
935
888
  this._onDesign();
936
889
  }
937
890
 
938
- _onSubmitFlowMode({
939
- detail: {
940
- values
941
- }
942
- }) {
891
+ _onSubmitFlowMode({ detail: { values } }) {
943
892
  this._definition['flow-mode'] = values['flow-mode'] || 'DEFAULT';
944
893
  this.isDirty = true;
945
-
946
894
  this._refresh();
947
895
  }
948
896
 
949
- _onChangeTab({
950
- detail
951
- }) {
897
+ _onChangeTab({ detail }) {
952
898
  this._changeTab(detail.value);
953
899
  }
954
900
 
955
- async _changeTabValidator({
956
- from,
957
- to
958
- }) {
901
+ async _changeTabValidator({ from, to }) {
959
902
  if (from === 'properties') {
960
903
  const component = this.shadowRoot.querySelector('gv-properties');
961
-
962
904
  if (component.dirty) {
963
905
  return component.confirm();
964
906
  }
965
907
  } else if (from === 'resources') {
966
908
  const component = this.shadowRoot.querySelector('gv-resources');
967
-
968
909
  if (component.dirty) {
969
910
  return component.confirm();
970
911
  }
@@ -976,7 +917,6 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
976
917
  throw e;
977
918
  }
978
919
  }
979
-
980
920
  return Promise.resolve();
981
921
  }
982
922
 
@@ -987,9 +927,7 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
987
927
  }
988
928
  }
989
929
 
990
- _onDragStartFlowStep(flow, {
991
- detail
992
- }) {
930
+ _onDragStartFlowStep(flow, { detail }) {
993
931
  if (this._currentAskConfirmation == null) {
994
932
  this._dropPolicy = detail;
995
933
  this._dragPolicy = detail;
@@ -997,57 +935,88 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
997
935
  }
998
936
 
999
937
  _renderFlowEmptyState(readonlyMode) {
1000
- return html`<div slot="content" class="empty"> <div> Select a flow ${readonlyMode !== true ? html`or <gv-button @gv-button:click="${this._onAddFlow}" outlined icon="code:plus" large>design new one</gv-button>` : ''} </div> </div>`;
938
+ return html`<div slot="content" class="empty">
939
+ <div>
940
+ Select a flow
941
+ ${readonlyMode !== true
942
+ ? html`or <gv-button @gv-button:click="${this._onAddFlow}" outlined icon="code:plus" large>design new one</gv-button>`
943
+ : ''}
944
+ </div>
945
+ </div>`;
1001
946
  }
1002
947
 
1003
948
  _renderFlow(index = 0, hasEmptyState = true, readonlyMode) {
1004
949
  const flow = this.getSelectedFlow(index);
1005
-
1006
950
  if (flow) {
1007
- const {
1008
- plan
1009
- } = this._findFlowCollection(flow._id);
1010
-
951
+ const { plan } = this._findFlowCollection(flow._id);
1011
952
  const selectedStepId = this._currentFlowStep ? this._currentFlowStep.step._id : null;
1012
- return html` <gv-flow style="height:100%" .id="${flow._id}" .flow="${flow}" .plan="${plan}" .policies="${this.policies}" slot="content" ?disabled="${this._currentAskConfirmation}" .dragPolicy="${this._dragPolicy}" .dropPolicy="${this._dropPolicy}" .selectedStepId="${selectedStepId}" ?readonly="${readonlyMode}" ?has-policy-filter="${this._policyFilterOptions != null}" flows-title="${this.flowsTitle}" @gv-flow:drag-start="${this._onDragStartFlowStep.bind(this, flow)}" @gv-flow:edit="${this._onEditFlowStep}" @gv-flow:change-state="${this._onChangeFlowStepState}" @gv-flow:drop="${this._onDropPolicy}" @gv-flow:delete="${this._onDeletePolicy}"></gv-flow>`;
953
+ return html` <gv-flow
954
+ style="height: 100%"
955
+ .id="${flow._id}"
956
+ .flow="${flow}"
957
+ .plan="${plan}"
958
+ .policies="${this.policies}"
959
+ slot="content"
960
+ ?disabled="${this._currentAskConfirmation}"
961
+ .dragPolicy="${this._dragPolicy}"
962
+ .dropPolicy="${this._dropPolicy}"
963
+ .selectedStepId="${selectedStepId}"
964
+ ?readonly="${readonlyMode}"
965
+ ?has-policy-filter="${this._policyFilterOptions != null}"
966
+ flows-title="${this.flowsTitle}"
967
+ @gv-flow:drag-start="${this._onDragStartFlowStep.bind(this, flow)}"
968
+ @gv-flow:edit="${this._onEditFlowStep}"
969
+ @gv-flow:change-state="${this._onChangeFlowStepState}"
970
+ @gv-flow:drop="${this._onDropPolicy}"
971
+ @gv-flow:delete="${this._onDeletePolicy}"
972
+ ></gv-flow>`;
1013
973
  } else if (hasEmptyState) {
1014
974
  return this._renderFlowEmptyState(readonlyMode);
1015
975
  }
1016
-
1017
976
  return html``;
1018
977
  }
1019
978
 
1020
979
  _onFetchResources(event) {
1021
- const {
1022
- currentTarget,
1023
- regexTypes
1024
- } = event.detail;
1025
- const options = this.definedResources.filter(resource => regexTypes == null || new RegExp(regexTypes).test(resource.type)).map((resource, index) => {
1026
- const resourceType = this.resourceTypes.find(type => type.id === resource.type);
1027
- const row = document.createElement('gv-row');
1028
- const picture = resourceType.icon ? resourceType.icon : null;
1029
- row.item = {
1030
- picture,
1031
- name: resource.name
1032
- };
1033
- return {
1034
- element: row,
1035
- value: resource.name,
1036
- id: resource.type
1037
- };
1038
- });
980
+ const { currentTarget, regexTypes } = event.detail;
981
+ const options = this.definedResources
982
+ .filter((resource) => regexTypes == null || new RegExp(regexTypes).test(resource.type))
983
+ .map((resource, index) => {
984
+ const resourceType = this.resourceTypes.find((type) => type.id === resource.type);
985
+ const row = document.createElement('gv-row');
986
+ const picture = resourceType.icon ? resourceType.icon : null;
987
+ row.item = { picture, name: resource.name };
988
+ return {
989
+ element: row,
990
+ value: resource.name,
991
+ id: resource.type,
992
+ };
993
+ });
1039
994
  currentTarget.options = options;
1040
995
  }
1041
996
 
1042
997
  _renderPolicy(readonlyMode) {
1043
998
  if (this._flowStepSchema && this.documentation) {
1044
- return html`<gv-resizable-views direction="horizontal" no-overflow> <div slot="top">${this._renderFlowStepForm(readonlyMode)}</div> <div slot="bottom"> <gv-documentation .text="${this.documentation.content}" .image="${this.documentation.image}" ?disabled="${this._currentAskConfirmation}" @gv-documentation:close="${this._onCloseDocumentation}"></gv-documentation> </div> </gv-resizable-views>`;
999
+ return html`<gv-resizable-views direction="horizontal" no-overflow>
1000
+ <div slot="top">${this._renderFlowStepForm(readonlyMode)}</div>
1001
+ <div slot="bottom">
1002
+ <gv-documentation
1003
+ .text="${this.documentation.content}"
1004
+ .image="${this.documentation.image}"
1005
+ ?disabled="${this._currentAskConfirmation}"
1006
+ @gv-documentation:close="${this._onCloseDocumentation}"
1007
+ ></gv-documentation>
1008
+ </div>
1009
+ </gv-resizable-views>`;
1045
1010
  } else if (this.documentation) {
1046
- return html`<gv-documentation .text="${this.documentation.content}" .image="${this.documentation.image}" ?disabled="${this._currentAskConfirmation}" @gv-documentation:close="${this._onCloseDocumentation}"></gv-documentation>`;
1011
+ return html`<gv-documentation
1012
+ .text="${this.documentation.content}"
1013
+ .image="${this.documentation.image}"
1014
+ ?disabled="${this._currentAskConfirmation}"
1015
+ @gv-documentation:close="${this._onCloseDocumentation}"
1016
+ ></gv-documentation>`;
1047
1017
  } else if (this._flowStepSchema) {
1048
1018
  return this._renderFlowStepForm(readonlyMode);
1049
1019
  }
1050
-
1051
1020
  return html``;
1052
1021
  }
1053
1022
 
@@ -1058,7 +1027,6 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1058
1027
  _onResetFlowStep() {
1059
1028
  if (this._currentFlowStep) {
1060
1029
  delete this._currentFlowStep._values;
1061
-
1062
1030
  this._getFlowStepForm().reset();
1063
1031
  }
1064
1032
  }
@@ -1079,51 +1047,45 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1079
1047
  if (list) {
1080
1048
  return list.map((e, index) => {
1081
1049
  const _id = `${prefix}_${index}`;
1082
-
1083
1050
  if (isFlow) {
1084
1051
  if (e.pre) {
1085
- e.pre.forEach((step, stepIndex) => step._id = this._generateFlowStepId(_id, 'pre', stepIndex));
1052
+ e.pre.forEach((step, stepIndex) => (step._id = this._generateFlowStepId(_id, 'pre', stepIndex)));
1086
1053
  }
1087
-
1088
1054
  if (e.post) {
1089
- e.post.forEach((step, stepIndex) => step._id = this._generateFlowStepId(_id, 'post', stepIndex));
1055
+ e.post.forEach((step, stepIndex) => (step._id = this._generateFlowStepId(_id, 'post', stepIndex)));
1090
1056
  }
1091
1057
  }
1092
-
1093
1058
  if (force || e._id == null) {
1094
- return { ...e,
1095
- _id
1096
- };
1059
+ return { ...e, _id };
1097
1060
  }
1098
-
1099
1061
  return e;
1100
1062
  });
1101
1063
  }
1102
-
1103
1064
  return list;
1104
1065
  }
1105
1066
 
1106
1067
  getChildren() {
1107
- return [...Array.from(this.shadowRoot.querySelectorAll('gv-flow')), ...Array.from(this.shadowRoot.querySelectorAll('gv-resizable-views'))];
1068
+ return [
1069
+ ...Array.from(this.shadowRoot.querySelectorAll('gv-flow')),
1070
+ ...Array.from(this.shadowRoot.querySelectorAll('gv-resizable-views')),
1071
+ ];
1108
1072
  }
1109
1073
 
1110
1074
  async getUpdateComplete() {
1111
1075
  await super.getUpdateComplete();
1112
- await Promise.all(this.getChildren().map(e => e.updateComplete));
1076
+ await Promise.all(this.getChildren().map((e) => e.updateComplete));
1113
1077
  }
1114
1078
 
1115
1079
  shouldUpdate(changedProperties) {
1116
1080
  // Just refresh gv-flow components
1117
1081
  if (changedProperties.has('_dragPolicy')) {
1118
- this.shadowRoot.querySelectorAll('gv-flow').forEach(flow => flow.dragPolicy = this._dragPolicy);
1082
+ this.shadowRoot.querySelectorAll('gv-flow').forEach((flow) => (flow.dragPolicy = this._dragPolicy));
1119
1083
  return false;
1120
1084
  }
1121
-
1122
1085
  if (changedProperties.has('_dropPolicy')) {
1123
- this.shadowRoot.querySelectorAll('gv-flow').forEach(flow => flow.dropPolicy = this._dropPolicy);
1086
+ this.shadowRoot.querySelectorAll('gv-flow').forEach((flow) => (flow.dropPolicy = this._dropPolicy));
1124
1087
  return false;
1125
1088
  }
1126
-
1127
1089
  return super.shouldUpdate(changedProperties);
1128
1090
  }
1129
1091
 
@@ -1135,12 +1097,55 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1135
1097
 
1136
1098
  _renderFlowStepForm(readonlyMode) {
1137
1099
  const values = this._currentFlowStep._values || this._currentFlowStep._initialValues;
1138
- return html`${cache(this._flowStepSchema && this._currentFlowStep ? html`<div class="flow-step__container"> <div class="flow-step__form"> <gv-schema-form .id="${FLOW_STEP_FORM_ID}" .schema="${this._flowStepSchema}" .icon="design:edit" has-header validate-on-render .values="${values}" .dirty="${this._currentFlowStep._values != null}" ?readonly="${readonlyMode}" scrollable @gv-schema-form:change="${this._onChangeFlowStep}" @gv-schema-form:reset="${this._onResetFlowStep}" @gv-schema-form:fetch-resources="${this._onFetchResources}" @gv-schema-form:submit="${this._onSubmitFlowStep}"> <div slot="title" class="flow-step__form-title">${this._currentFlowStep.step.name}</div> <gv-button slot="header-left" icon="general:close" outlined small @gv-button:click="${this._onCloseFlowStepForm}" title="Close"></gv-button> <gv-button slot="header-left" icon="home:book" ?disabled="${this.documentation != null}" outlined small @gv-button:click="${this._onOpenDocumentationFromForm}" title="Open documentation"></gv-button> </gv-schema-form> </div> </div>` : '')}`;
1100
+
1101
+ const groups = [{ items: ['description', 'condition'] }, { name: i18n('gv-policy-studio.policy-settings'), default: true }];
1102
+ return html`${cache(
1103
+ this._flowStepSchema && this._currentFlowStep
1104
+ ? html`<div class="flow-step__container">
1105
+ <div class="flow-step__form">
1106
+ <gv-schema-form
1107
+ .id="${FLOW_STEP_FORM_ID}"
1108
+ .schema="${this._flowStepSchema}"
1109
+ .icon="design:edit"
1110
+ has-header
1111
+ validate-on-render
1112
+ .values="${values}"
1113
+ .dirty="${this._currentFlowStep._values != null}"
1114
+ ?readonly="${readonlyMode}"
1115
+ scrollable
1116
+ .groups="${groups}"
1117
+ @gv-schema-form:change="${this._onChangeFlowStep}"
1118
+ @gv-schema-form:reset="${this._onResetFlowStep}"
1119
+ @gv-schema-form:fetch-resources="${this._onFetchResources}"
1120
+ @gv-schema-form:submit="${this._onSubmitFlowStep}"
1121
+ >
1122
+ <div slot="title" class="flow-step__form-title">${this._currentFlowStep.step.name}</div>
1123
+ <gv-button
1124
+ slot="header-left"
1125
+ icon="general:close"
1126
+ outlined
1127
+ small
1128
+ @gv-button:click="${this._onCloseFlowStepForm}"
1129
+ title="Close"
1130
+ ></gv-button>
1131
+ <gv-button
1132
+ slot="header-left"
1133
+ icon="home:book"
1134
+ ?disabled="${this.documentation != null}"
1135
+ outlined
1136
+ small
1137
+ @gv-button:click="${this._onOpenDocumentationFromForm}"
1138
+ title="Open documentation"
1139
+ ></gv-button>
1140
+ </gv-schema-form>
1141
+ </div>
1142
+ </div>`
1143
+ : '',
1144
+ )}`;
1139
1145
  }
1140
1146
 
1141
1147
  _onCloseDocumentation() {
1142
1148
  this.documentation = null;
1143
-
1144
1149
  if (this._currentFlowStep == null) {
1145
1150
  this._maximizeTopView();
1146
1151
  } else {
@@ -1148,17 +1153,10 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1148
1153
  }
1149
1154
  }
1150
1155
 
1151
- _onDeleteFlow({
1152
- detail
1153
- }) {
1156
+ _onDeleteFlow({ detail }) {
1154
1157
  const flowId = detail.content._id;
1155
-
1156
- const {
1157
- flows
1158
- } = this._findFlowCollection(flowId);
1159
-
1160
- const flow = flows.find(flow => flow._id === flowId);
1161
-
1158
+ const { flows } = this._findFlowCollection(flowId);
1159
+ const flow = flows.find((flow) => flow._id === flowId);
1162
1160
  this._deleteFlow(flows, flow);
1163
1161
  }
1164
1162
 
@@ -1178,20 +1176,13 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1178
1176
  return this._definition && this._definition.properties ? this._definition.properties : [];
1179
1177
  }
1180
1178
 
1181
- async _onDuplicateFlow({
1182
- detail
1183
- }) {
1179
+ async _onDuplicateFlow({ detail }) {
1184
1180
  try {
1185
1181
  await this._askToValidateForms();
1186
- const flowId = detail.content._id;
1187
-
1188
- const {
1189
- plan,
1190
- flows
1191
- } = this._findFlowCollection(flowId);
1192
1182
 
1183
+ const flowId = detail.content._id;
1184
+ const { plan, flows } = this._findFlowCollection(flowId);
1193
1185
  this._addFlow(flows, this._findFlowById(flowId));
1194
-
1195
1186
  if (plan != null) {
1196
1187
  let planIndex = null;
1197
1188
  this.definedPlans.find((p, i) => {
@@ -1199,16 +1190,13 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1199
1190
  planIndex = i;
1200
1191
  return true;
1201
1192
  }
1202
-
1203
1193
  return false;
1204
1194
  });
1205
1195
  plan.flows = flows;
1206
1196
  this.definedPlans[planIndex].flows = this._generatePlanFlowsId(plan, true);
1207
-
1208
1197
  this._updateSelectedFlows([this.definedPlans[planIndex].flows[flows.length - 1]._id]);
1209
1198
  } else {
1210
1199
  this._definition.flows = this._generateFlowsId(this._definition.flows);
1211
-
1212
1200
  this._updateSelectedFlows([this._definition.flows[this._definition.flows.length - 1]._id]);
1213
1201
  }
1214
1202
  } catch (err) {
@@ -1216,26 +1204,18 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1216
1204
  }
1217
1205
  }
1218
1206
 
1219
- _onChangeFlowState({
1220
- detail
1221
- }) {
1207
+ _onChangeFlowState({ detail }) {
1222
1208
  const flow = this._findFlowById(detail.content._id);
1223
-
1224
1209
  flow.enabled = detail.enabled;
1225
1210
  flow._dirty = true;
1226
1211
  this.isDirty = true;
1227
1212
  }
1228
1213
 
1229
- async _onAddFlowPlan({
1230
- detail
1231
- }) {
1214
+ async _onAddFlowPlan({ detail }) {
1232
1215
  try {
1233
1216
  await this._askToValidateForms();
1234
-
1235
1217
  this._addFlow(this.definedPlans[detail.planIndex].flows);
1236
-
1237
1218
  this.definedPlans[detail.planIndex].flows = this._generatePlanFlowsId(this.definedPlans[detail.planIndex]);
1238
-
1239
1219
  this._updateSelectedFlows([this.definedPlans[detail.planIndex].flows[this.definedPlans[detail.planIndex].flows.length - 1]._id]);
1240
1220
  } catch (err) {
1241
1221
  this._currentAskConfirmation = null;
@@ -1247,9 +1227,7 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1247
1227
  await this._askToValidateForms();
1248
1228
 
1249
1229
  this._addFlow(this._definition.flows);
1250
-
1251
1230
  this._definition.flows = this._generateFlowsId(this._definition.flows);
1252
-
1253
1231
  this._updateSelectedFlows([this._definition.flows[this._definition.flows.length - 1]._id]);
1254
1232
  } catch (err) {
1255
1233
  this._currentAskConfirmation = null;
@@ -1257,12 +1235,17 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1257
1235
  }
1258
1236
 
1259
1237
  _addFlow(collection, duplicate = null) {
1260
- const flow = duplicate == null ? this._createFlowFromSchema() : { ...duplicate,
1261
- _id: null,
1262
- // reset the id to avoid issue with AM that persists the ID
1263
- id: null,
1264
- _dirty: true
1265
- };
1238
+ const flow =
1239
+ duplicate == null
1240
+ ? this._createFlowFromSchema()
1241
+ : {
1242
+ ...duplicate,
1243
+ _id: null,
1244
+ // reset the id to avoid issue with AM that persists the ID
1245
+ id: null,
1246
+ _dirty: true,
1247
+ };
1248
+
1266
1249
  collection.push(flow);
1267
1250
  this.isDirty = true;
1268
1251
  return collection;
@@ -1273,23 +1256,22 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1273
1256
  name: '',
1274
1257
  pre: [],
1275
1258
  post: [],
1276
- _dirty: true
1259
+ _dirty: true,
1277
1260
  };
1261
+
1278
1262
  return this._instantiate(this.flowSchema.properties, newFlow);
1279
1263
  }
1280
1264
 
1281
1265
  _instantiate(propertiesDefinition, initiator = {}) {
1282
- const property = { ...initiator
1283
- };
1266
+ const property = { ...initiator };
1284
1267
 
1285
1268
  if (propertiesDefinition) {
1286
1269
  for (const key of Object.keys(propertiesDefinition)) {
1287
1270
  const entry = propertiesDefinition[key];
1288
1271
 
1289
1272
  if (entry.type === 'object') {
1290
- property[key] = this._instantiate(entry.properties, initiator = {});
1273
+ property[key] = this._instantiate(entry.properties, (initiator = {}));
1291
1274
  }
1292
-
1293
1275
  if (entry.default !== undefined) {
1294
1276
  property[key] = entry.default;
1295
1277
  } else if (entry.type === 'string') {
@@ -1304,18 +1286,14 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1304
1286
  _deleteFlow(collection, flow) {
1305
1287
  const index = collection.indexOf(flow);
1306
1288
  collection.splice(index, 1);
1307
- const selectedFlows = this.selectedFlowsId.filter(flowId => flowId !== flow._id);
1308
-
1289
+ const selectedFlows = this.selectedFlowsId.filter((flowId) => flowId !== flow._id);
1309
1290
  if (selectedFlows.length === 1) {
1310
1291
  this._updateSelectedFlows(selectedFlows);
1311
1292
  } else {
1312
1293
  this._selectFirstFlow(true);
1313
1294
  }
1314
-
1315
1295
  this._changeTab('design');
1316
-
1317
1296
  this._refresh();
1318
-
1319
1297
  this.isDirty = true;
1320
1298
  }
1321
1299
 
@@ -1326,44 +1304,36 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1326
1304
  index = i;
1327
1305
  return true;
1328
1306
  }
1329
-
1330
1307
  return false;
1331
1308
  });
1332
1309
  return index;
1333
1310
  }
1334
1311
 
1335
- async _onReorderFlows({
1336
- detail: {
1337
- plan
1338
- }
1339
- }) {
1312
+ async _onReorderFlows({ detail: { plan } }) {
1340
1313
  try {
1341
1314
  await this._askToValidateForms();
1342
1315
  this.isDirty = true;
1343
-
1344
1316
  if (plan != null) {
1345
1317
  const newOrder = this._generatePlanFlowsId(plan, true);
1346
-
1347
1318
  if (this.selectedFlowsId) {
1348
- this._updateSelectedFlows(this.selectedFlowsId.map(flowId => {
1349
- const index = this._findFlowIndex(plan.flows, flowId);
1350
-
1351
- return index != null ? newOrder[index]._id : flowId;
1352
- }));
1319
+ this._updateSelectedFlows(
1320
+ this.selectedFlowsId.map((flowId) => {
1321
+ const index = this._findFlowIndex(plan.flows, flowId);
1322
+ return index != null ? newOrder[index]._id : flowId;
1323
+ }),
1324
+ );
1353
1325
  }
1354
-
1355
1326
  plan.flows = newOrder;
1356
1327
  } else {
1357
1328
  const newOrder = this._generateFlowsId(this._definition.flows, true);
1358
-
1359
1329
  if (this.selectedFlowsId) {
1360
- this._updateSelectedFlows(this.selectedFlowsId.map(flowId => {
1361
- const index = this._findFlowIndex(this._definition.flows, flowId);
1362
-
1363
- return index != null ? newOrder[index]._id : flowId;
1364
- }));
1330
+ this._updateSelectedFlows(
1331
+ this.selectedFlowsId.map((flowId) => {
1332
+ const index = this._findFlowIndex(this._definition.flows, flowId);
1333
+ return index != null ? newOrder[index]._id : flowId;
1334
+ }),
1335
+ );
1365
1336
  }
1366
-
1367
1337
  this._definition.flows = newOrder;
1368
1338
  }
1369
1339
  } catch (err) {
@@ -1371,9 +1341,7 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1371
1341
  }
1372
1342
  }
1373
1343
 
1374
- _onSearchPolicy({
1375
- detail
1376
- }) {
1344
+ _onSearchPolicy({ detail }) {
1377
1345
  this._searchPolicyQuery = detail;
1378
1346
  }
1379
1347
 
@@ -1381,9 +1349,7 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1381
1349
  this._searchPolicyQuery = null;
1382
1350
  }
1383
1351
 
1384
- _onSearchFlows({
1385
- detail
1386
- }) {
1352
+ _onSearchFlows({ detail }) {
1387
1353
  this._searchFlowQuery = detail;
1388
1354
  }
1389
1355
 
@@ -1405,26 +1371,27 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1405
1371
  }
1406
1372
 
1407
1373
  _removePrivateProperties(o) {
1408
- const copy = { ...o
1409
- };
1410
- Object.keys(o).filter(key => key.startsWith('_')).forEach(key => {
1411
- delete copy[key];
1412
- });
1374
+ const copy = { ...o };
1375
+ Object.keys(o)
1376
+ .filter((key) => key.startsWith('_'))
1377
+ .forEach((key) => {
1378
+ delete copy[key];
1379
+ });
1413
1380
  return copy;
1414
1381
  }
1415
1382
 
1416
1383
  _submitOrConfirmForms() {
1417
- return [...this.shadowRoot.querySelectorAll('gv-schema-form')].filter(form => {
1418
- const isValid = form.isValid();
1419
-
1420
- if (isValid) {
1421
- form.submit();
1422
- } else {
1423
- form.dirty = true;
1424
- }
1425
-
1426
- return !isValid;
1427
- }).map(form => form.confirm());
1384
+ return [...this.shadowRoot.querySelectorAll('gv-schema-form')]
1385
+ .filter((form) => {
1386
+ const isValid = form.isValid();
1387
+ if (isValid) {
1388
+ form.submit();
1389
+ } else {
1390
+ form.dirty = true;
1391
+ }
1392
+ return !isValid;
1393
+ })
1394
+ .map((form) => form.confirm());
1428
1395
  }
1429
1396
 
1430
1397
  getPropertiesElement() {
@@ -1433,20 +1400,18 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1433
1400
 
1434
1401
  async _checkCurrentFlowStep() {
1435
1402
  if (this._currentFlowStep && this.selectedFlowsId) {
1436
- const closePromises = this.selectedFlowsId.map(flowId => {
1437
- const flow = this._findFlowById(flowId);
1438
-
1439
- const currentStep = [...flow.pre, ...flow.post].find(step => step._id === this._currentFlowStep.step._id);
1440
-
1441
- if (currentStep == null) {
1442
- return this._closeFlowStepForm(true);
1443
- }
1444
-
1445
- return null;
1446
- }).filter(p => p !== null);
1403
+ const closePromises = this.selectedFlowsId
1404
+ .map((flowId) => {
1405
+ const flow = this._findFlowById(flowId);
1406
+ const currentStep = [...flow.pre, ...flow.post].find((step) => step._id === this._currentFlowStep.step._id);
1407
+ if (currentStep == null) {
1408
+ return this._closeFlowStepForm(true);
1409
+ }
1410
+ return null;
1411
+ })
1412
+ .filter((p) => p !== null);
1447
1413
  return Promise.all(closePromises);
1448
1414
  }
1449
-
1450
1415
  return Promise.resolve();
1451
1416
  }
1452
1417
 
@@ -1456,95 +1421,71 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1456
1421
  this._definition = deepClone(this._definitionSaved);
1457
1422
  this._definitionSaved = null;
1458
1423
  this.isDirty = false;
1459
-
1460
1424
  this._checkCurrentFlowStep();
1461
-
1462
- this.definedPlans.forEach(plan => {
1463
- plan.flows.forEach(flow => flow._dirty = false);
1425
+ this.definedPlans.forEach((plan) => {
1426
+ plan.flows.forEach((flow) => (flow._dirty = false));
1464
1427
  });
1465
- this.definedFlows.forEach(flow => flow._dirty = false);
1466
- this.getChildren().forEach(e => e.requestUpdate());
1428
+ this.definedFlows.forEach((flow) => (flow._dirty = false));
1429
+ this.getChildren().forEach((e) => e.requestUpdate());
1467
1430
  }
1468
1431
  }
1469
1432
 
1470
1433
  _buildDefinitionToSave() {
1471
1434
  // Copy definition and remove invalid step
1472
1435
  // Keep private properties like _id and others stuff useful for render
1473
- const flows = this._definition.flows.map(flow => {
1436
+ const flows = this._definition.flows.map((flow) => {
1474
1437
  flow.pre = flow.pre.filter(this._filterNotValidStep);
1475
1438
  flow.post = flow.post.filter(this._filterNotValidStep);
1476
1439
  return flow;
1477
1440
  });
1478
1441
 
1479
- let definition = { ...this._definition,
1480
- flows
1481
- };
1442
+ let definition = { ...this._definition, flows };
1482
1443
 
1483
1444
  if (this._definition.plans != null) {
1484
- const plans = this._definition.plans.map(plan => {
1485
- const flows = plan.flows.map(flow => {
1445
+ const plans = this._definition.plans.map((plan) => {
1446
+ const flows = plan.flows.map((flow) => {
1486
1447
  flow.pre = flow.pre.filter(this._filterNotValidStep);
1487
1448
  flow.post = flow.post.filter(this._filterNotValidStep);
1488
1449
  return flow;
1489
1450
  });
1490
- return { ...plan,
1491
- flows
1492
- };
1451
+ return { ...plan, flows };
1493
1452
  });
1494
-
1495
- definition = { ...definition,
1496
- plans
1497
- };
1453
+ definition = { ...definition, plans };
1498
1454
  }
1499
-
1500
1455
  return definition;
1501
1456
  }
1502
1457
 
1503
1458
  _buildDefinitionToSend(definitionToSave) {
1504
1459
  // Copy definition and remove all private properties
1505
- const flows = definitionToSave.flows.map(f => {
1460
+ const flows = definitionToSave.flows.map((f) => {
1506
1461
  const flow = this._removePrivateProperties(f);
1507
-
1508
1462
  flow.pre = flow.pre.map(this._removePrivateProperties);
1509
1463
  flow.post = flow.post.map(this._removePrivateProperties);
1510
1464
  return flow;
1511
1465
  });
1512
- let definition = { ...this._definition,
1513
- flows
1514
- };
1515
1466
 
1467
+ let definition = { ...this._definition, flows };
1516
1468
  if (this._definition.plans != null) {
1517
- const plans = definitionToSave.plans.map(plan => {
1518
- const flows = plan.flows.map(f => {
1469
+ const plans = definitionToSave.plans.map((plan) => {
1470
+ const flows = plan.flows.map((f) => {
1519
1471
  const flow = this._removePrivateProperties(f);
1520
-
1521
1472
  flow.pre = flow.pre.map(this._removePrivateProperties);
1522
1473
  flow.post = flow.post.map(this._removePrivateProperties);
1523
1474
  return flow;
1524
1475
  });
1525
- return { ...plan,
1526
- flows
1527
- };
1476
+ return { ...plan, flows };
1528
1477
  });
1529
- definition = { ...definition,
1530
- plans
1531
- };
1478
+ definition = { ...definition, plans };
1532
1479
  }
1533
1480
 
1534
1481
  if (this._definition.properties != null) {
1535
1482
  const properties = this._definition.properties.map(this._removePrivateProperties);
1536
-
1537
- definition = { ...definition,
1538
- properties
1539
- };
1483
+ definition = { ...definition, properties };
1540
1484
  }
1541
1485
 
1542
1486
  if (this._definition.resources != null) {
1543
1487
  const resources = this._definition.resources.map(this._removePrivateProperties);
1544
-
1545
- definition = { ...definition,
1546
- resources
1547
- };
1488
+ definition = { ...definition, resources };
1548
1489
  }
1549
1490
 
1550
1491
  return definition;
@@ -1555,18 +1496,15 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1555
1496
  this.getPropertiesElement().submit();
1556
1497
  }
1557
1498
 
1558
- Promise.all(this._submitOrConfirmForms()).then(() => {
1559
- this._definitionSaved = this._buildDefinitionToSave();
1560
-
1561
- const definition = this._buildDefinitionToSend(this._definitionSaved);
1562
-
1563
- dispatchCustomEvent(this, 'save', {
1564
- definition,
1565
- services: this.services
1499
+ Promise.all(this._submitOrConfirmForms())
1500
+ .then(() => {
1501
+ this._definitionSaved = this._buildDefinitionToSave();
1502
+ const definition = this._buildDefinitionToSend(this._definitionSaved);
1503
+ dispatchCustomEvent(this, 'save', { definition, services: this.services });
1504
+ })
1505
+ .catch((err) => {
1506
+ console.error(`[policy-studio] Error on save`, err);
1566
1507
  });
1567
- }).catch(err => {
1568
- console.error(`[policy-studio] Error on save`, err);
1569
- });
1570
1508
  }
1571
1509
 
1572
1510
  _onDebug(requestEvent) {
@@ -1574,24 +1512,20 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1574
1512
  this.getPropertiesElement().submit();
1575
1513
  }
1576
1514
 
1577
- Promise.all(this._submitOrConfirmForms()).then(() => {
1578
- const definition = this._buildDefinitionToSend(this._buildDefinitionToSave());
1579
-
1580
- dispatchCustomEvent(this, 'debug', {
1581
- definition,
1582
- services: this.services,
1583
- request: requestEvent.detail.request
1515
+ Promise.all(this._submitOrConfirmForms())
1516
+ .then(() => {
1517
+ const definition = this._buildDefinitionToSend(this._buildDefinitionToSave());
1518
+ dispatchCustomEvent(this, 'debug', { definition, services: this.services, request: requestEvent.detail.request });
1519
+ })
1520
+ .catch((err) => {
1521
+ console.error(`[policy-studio] Error on debug`, err);
1584
1522
  });
1585
- }).catch(err => {
1586
- console.error(`[policy-studio] Error on debug`, err);
1587
- });
1588
1523
  }
1589
1524
 
1590
1525
  get filteredFlows() {
1591
1526
  if (this._flowFilter.length === 0 || this._flowFilter.includes('api')) {
1592
1527
  return this.definedFlows;
1593
1528
  }
1594
-
1595
1529
  return null;
1596
1530
  }
1597
1531
 
@@ -1599,13 +1533,10 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1599
1533
  if (this._flowFilter.length === 0 || this._flowFilter.includes('plan')) {
1600
1534
  return this.definedPlans;
1601
1535
  }
1602
-
1603
1536
  return null;
1604
1537
  }
1605
1538
 
1606
- _onFilterFlows({
1607
- detail
1608
- }) {
1539
+ _onFilterFlows({ detail }) {
1609
1540
  if (this._flowFilter.includes(detail.id)) {
1610
1541
  this._flowFilter = [];
1611
1542
  } else {
@@ -1615,17 +1546,16 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1615
1546
 
1616
1547
  _getFilteredPolicies() {
1617
1548
  if (this._policyFilter.length > 0) {
1618
- return this.policies.filter(policy => {
1619
- return policy.onRequest && this._policyFilter.includes('onRequest') || policy.onResponse && this._policyFilter.includes('onResponse');
1549
+ return this.policies.filter((policy) => {
1550
+ return (
1551
+ (policy.onRequest && this._policyFilter.includes('onRequest')) || (policy.onResponse && this._policyFilter.includes('onResponse'))
1552
+ );
1620
1553
  });
1621
1554
  }
1622
-
1623
1555
  return this.policies;
1624
1556
  }
1625
1557
 
1626
- _onFilterPolicies({
1627
- detail
1628
- }) {
1558
+ _onFilterPolicies({ detail }) {
1629
1559
  if (this._policyFilter.includes(detail.id)) {
1630
1560
  this._policyFilter = [];
1631
1561
  } else {
@@ -1634,7 +1564,52 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1634
1564
  }
1635
1565
 
1636
1566
  _renderDesign(readonlyMode) {
1637
- return html` <div id="design" slot="content" class="design"> <gv-resizable-views no-overflow> <div slot="top">${this._renderFlow(0, true, readonlyMode)}</div> <div slot="bottom"> ${this._renderFlow(1, false, readonlyMode)} ${this._renderPolicy(readonlyMode)} ${this._renderFlowForm(readonlyMode)} </div> </gv-resizable-views> ${readonlyMode !== true ? html`<gv-policy-studio-menu class="right-menu" ?disabled="${this._currentAskConfirmation}" .policies="${this._getFilteredPolicies()}" .selectedIds="${[this._currentPolicyId]}" .query="${this._searchPolicyQuery}" ?has-policy-filter="${this._policyFilterOptions != null}" ?readonly="${readonlyMode}" @gv-policy-studio-menu:target-policy="${this._onTargetPolicy}" @gv-policy-studio-menu:fetch-documentation="${this._onOpenDocumentationFromMenu}" @gv-policy-studio-menu:dragend-policy="${this._onDragEndPolicy}"> <div slot="header" class="search-policies"> ${this._policyFilterOptions != null ? html`<gv-option ?disabled="${this._currentAskConfirmation}" .options="${this._policyFilterOptions}" multiple="multiple" outlined .value="${this._policyFilter}" small @gv-option:select="${this._onFilterPolicies}"></gv-option>` : ''} <gv-input id="search-policy" ?disabled="${this._currentAskConfirmation}" placeholder="Filter policies (Shift + Ctrl + Space)" type="search" small @gv-input:input="${this._onSearchPolicy}" @gv-input:clear="${this._onClearPolicy}"></gv-input> </div> </gv-policy-studio-menu>` : ''} </div>`;
1567
+ return html` <div id="design" slot="content" class="design">
1568
+ <gv-resizable-views no-overflow>
1569
+ <div slot="top">${this._renderFlow(0, true, readonlyMode)}</div>
1570
+
1571
+ <div slot="bottom">
1572
+ ${this._renderFlow(1, false, readonlyMode)} ${this._renderPolicy(readonlyMode)} ${this._renderFlowForm(readonlyMode)}
1573
+ </div>
1574
+ </gv-resizable-views>
1575
+ ${readonlyMode !== true
1576
+ ? html`<gv-policy-studio-menu
1577
+ class="right-menu"
1578
+ ?disabled="${this._currentAskConfirmation}"
1579
+ .policies="${this._getFilteredPolicies()}"
1580
+ .selectedIds="${[this._currentPolicyId]}"
1581
+ .query="${this._searchPolicyQuery}"
1582
+ ?has-policy-filter="${this._policyFilterOptions != null}"
1583
+ ?readonly="${readonlyMode}"
1584
+ @gv-policy-studio-menu:target-policy="${this._onTargetPolicy}"
1585
+ @gv-policy-studio-menu:fetch-documentation="${this._onOpenDocumentationFromMenu}"
1586
+ @gv-policy-studio-menu:dragend-policy="${this._onDragEndPolicy}"
1587
+ >
1588
+ <div slot="header" class="search-policies">
1589
+ ${this._policyFilterOptions != null
1590
+ ? html`<gv-option
1591
+ ?disabled="${this._currentAskConfirmation}"
1592
+ .options="${this._policyFilterOptions}"
1593
+ multiple
1594
+ outlined
1595
+ .value="${this._policyFilter}"
1596
+ small
1597
+ @gv-option:select="${this._onFilterPolicies}"
1598
+ ></gv-option>`
1599
+ : ''}
1600
+ <gv-input
1601
+ id="search-policy"
1602
+ ?disabled="${this._currentAskConfirmation}"
1603
+ placeholder="Filter policies (Shift + Ctrl + Space)"
1604
+ type="search"
1605
+ small
1606
+ @gv-input:input="${this._onSearchPolicy}"
1607
+ @gv-input:clear="${this._onClearPolicy}"
1608
+ ></gv-input>
1609
+ </div>
1610
+ </gv-policy-studio-menu>`
1611
+ : ''}
1612
+ </div>`;
1638
1613
  }
1639
1614
 
1640
1615
  _renderDebug() {
@@ -1642,61 +1617,189 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1642
1617
  const isLoading = this.debugResponse ? this.debugResponse.isLoading : undefined;
1643
1618
  const path = this.debugResponse && this.debugResponse.request ? this.debugResponse.request.path : undefined;
1644
1619
  const method = this.debugResponse && this.debugResponse.request ? this.debugResponse.request.method : undefined;
1645
- return html`<gv-http-client id="debug" slot="content" class="debug" @gv-http-client:send="${this._onDebug}" .response="${response}" .path="${path}" .method="${method}" ?loading="${isLoading}"> </gv-http-client>`;
1620
+ return html`<gv-http-client
1621
+ id="debug"
1622
+ slot="content"
1623
+ class="debug"
1624
+ @gv-http-client:send="${this._onDebug}"
1625
+ .response="${response}"
1626
+ .path="${path}"
1627
+ .method="${method}"
1628
+ ?loading="${isLoading}"
1629
+ >
1630
+ </gv-http-client>`;
1646
1631
  }
1647
1632
 
1648
1633
  _renderConfigurationForm(readonlyMode) {
1649
1634
  if (this.configurationSchema) {
1650
1635
  const values = deepClone(this._definition);
1651
- return html` <div id="settings" slot="content" class="api-settings" @dragover="${this._onDesign}"> <gv-schema-form .schema="${this.configurationSchema}" id="api-settings-form" .values="${values}" has-header has-footer scrollable ?readonly="${readonlyMode}" @gv-schema-form:cancel="${this._onCancelFlowMode}" @gv-schema-form:submit="${this._onSubmitFlowMode}"> ${!this.configurationInformation ? '' : html` <div class="api-settings-information" slot="title"> <gv-icon class="api-settings-information__icon" title="Info" shape="code:info"></gv-icon> <blockquote class="api-settings-information__blockquote">${this.configurationInformation}</blockquote> </div> `} </gv-schema-form> </div>`;
1636
+ return html` <div id="settings" slot="content" class="api-settings" @dragover="${this._onDesign}">
1637
+ <gv-schema-form
1638
+ .schema="${this.configurationSchema}"
1639
+ id="api-settings-form"
1640
+ .values="${values}"
1641
+ has-header
1642
+ has-footer
1643
+ scrollable
1644
+ ?readonly="${readonlyMode}"
1645
+ @gv-schema-form:cancel="${this._onCancelFlowMode}"
1646
+ @gv-schema-form:submit="${this._onSubmitFlowMode}"
1647
+ >
1648
+ ${!this.configurationInformation
1649
+ ? ''
1650
+ : html`
1651
+ <div class="api-settings-information" slot="title">
1652
+ <gv-icon class="api-settings-information__icon" title="Info" shape="code:info"></gv-icon>
1653
+ <blockquote class="api-settings-information__blockquote">${this.configurationInformation}</blockquote>
1654
+ </div>
1655
+ `}
1656
+ </gv-schema-form>
1657
+ </div>`;
1652
1658
  }
1653
-
1654
1659
  return html``;
1655
1660
  }
1656
1661
 
1657
1662
  _renderFlowForm(readonlyMode) {
1658
1663
  if (this.flowSchema && this._flowStepSchema == null && this.documentation == null && this.selectedFlowsId.length === 1) {
1659
1664
  const flow = this.getSelectedFlow();
1660
-
1661
1665
  if (flow) {
1662
1666
  const values = deepClone(flow);
1663
- return html`<div slot="content" class="flow-settings"> <gv-schema-form .schema="${this.flowSchema}" id="settings-form" .values="${values}" has-header scrollable ?readonly="${readonlyMode}" @gv-schema-form:cancel="${this._onCancelFlow}" @gv-schema-form:submit="${this._onSubmitFlow}"> <div slot="title" class="flow-step__form-title">Flow configuration</div> </gv-schema-form> </div>`;
1667
+ return html`<div slot="content" class="flow-settings">
1668
+ <gv-schema-form
1669
+ .schema="${this.flowSchema}"
1670
+ id="settings-form"
1671
+ .values="${values}"
1672
+ has-header
1673
+ scrollable
1674
+ ?readonly="${readonlyMode}"
1675
+ @gv-schema-form:cancel="${this._onCancelFlow}"
1676
+ @gv-schema-form:submit="${this._onSubmitFlow}"
1677
+ >
1678
+ <div slot="title" class="flow-step__form-title">Flow configuration</div>
1679
+ </gv-schema-form>
1680
+ </div>`;
1664
1681
  }
1665
1682
  }
1666
1683
  }
1667
1684
 
1668
- _onResourcesChange({
1669
- detail
1670
- }) {
1685
+ _onResourcesChange({ detail }) {
1671
1686
  this.definition.resources = detail.resources;
1672
1687
  this.isDirty = true;
1673
1688
  }
1674
1689
 
1675
- _onPropertiesChange({
1676
- detail
1677
- }) {
1690
+ _onPropertiesChange({ detail }) {
1678
1691
  this.definition.properties = detail.properties;
1679
1692
  this.isDirty = true;
1680
1693
  }
1681
1694
 
1682
- _onSaveProvider({
1683
- detail
1684
- }) {
1695
+ _onSaveProvider({ detail }) {
1685
1696
  this.services['dynamic-property'] = detail.provider;
1686
1697
  this.isDirty = true;
1687
1698
  }
1688
1699
 
1689
- _onSwitchEncryptedProperty({
1690
- detail
1691
- }) {
1700
+ _onSwitchEncryptedProperty({ detail }) {
1692
1701
  this.isDirty = true;
1693
1702
  }
1694
1703
 
1695
1704
  render() {
1696
1705
  const readonlyMode = this._getReadonlyModeForDesign();
1697
1706
 
1698
- return html`<div class="box"> <gv-policy-studio-menu class="left-menu" .api-name="${this._definition.name}" .flows="${this.filteredFlows}" .plans="${this.filteredPlans}" .selectedIds="${this.selectedFlowsId}" ?disabled="${this._currentAskConfirmation}" ?sortable="${this.sortable && this.readonly !== true}" ?readonly="${this.readonly}" ?readonlyPlans="${this.readonlyPlans}" flows-title="${this.flowsTitle}" .query="${this._searchFlowQuery}" ?can-add="${this.canAdd && !this.readonly}" @gv-policy-studio-menu:reorder-flows="${this._onReorderFlows}" @gv-policy-studio-menu:change-flow-state="${this._onChangeFlowState}" @gv-policy-studio-menu:add-flow="${this._onAddFlow}" @gv-policy-studio-menu:add-flow-plan="${this._onAddFlowPlan}" @gv-policy-studio-menu:delete-flow="${this._onDeleteFlow}" @gv-policy-studio-menu:duplicate-flow="${this._onDuplicateFlow}" @gv-policy-studio-menu:select-flows="${this._onSelectFlows}"> <div slot="header" class="header-actions"> <div class="title">${this._definition.name}</div> ${this._flowFilterOptions != null ? html`<gv-option ?disabled="${this._currentAskConfirmation}" .options="${this._flowFilterOptions}" multiple="multiple" outlined .value="${this._flowFilter}" small @gv-option:select="${this._onFilterFlows}"></gv-option>` : ''} <gv-input ?disabled="${this._currentAskConfirmation}" id="search-flow" placeholder="Filter flows (Ctrl + Space)" type="search" small @gv-input:input="${this._onSearchFlows}" @gv-input:clear="${this._onClearFlows}"></gv-input> </div> ${this.readonly !== true ? html` <div slot="footer" class="footer-actions"> <gv-button class="btn-large" .disabled="${!this.isDirty || this._currentAskConfirmation}" @gv-button:click="${this._onSaveAll}">Save</gv-button> <gv-button link .disabled="${!this.isDirty || this._currentAskConfirmation}" @gv-button:click="${this._onResetAll}">Reset</gv-button> </div>` : ''} </gv-policy-studio-menu> <gv-tabs .value="${this.tabId}" .options="${this._tabs}" .disabled="${this._currentAskConfirmation}" @gv-tabs:change="${this._onChangeTab}" .validator="${this._changeTabValidator.bind(this)}"> ${this._renderDesign(readonlyMode)} ${this._renderConfigurationForm(readonlyMode)} ${this._renderDebug()} <gv-properties id="properties" slot="content" class="properties" .provider="${this.services['dynamic-property']}" @gv-properties:change="${this._onPropertiesChange}" @gv-properties:save-provider="${this._onSaveProvider}" @gv-properties:switch-encrypted="${this._onSwitchEncryptedProperty}" ?readonly="${readonlyMode}" encryptable="true" .properties="${this.definedProperties}" .providers="${this.propertyProviders}" .dynamicPropertySchema="${this.dynamicPropertySchema}"></gv-properties> <gv-resources id="resources" slot="content" class="resources" @gv-resources:change="${this._onResourcesChange}" ?readonly="${readonlyMode}" .resources="${this.definedResources}" .types="${this.resourceTypes}"></gv-resources> </gv-tabs> </div>`;
1707
+ return html`<div class="box">
1708
+ <gv-policy-studio-menu
1709
+ class="left-menu"
1710
+ .api-name="${this._definition.name}"
1711
+ .flows="${this.filteredFlows}"
1712
+ .plans="${this.filteredPlans}"
1713
+ .selectedIds="${this.selectedFlowsId}"
1714
+ ?disabled="${this._currentAskConfirmation}"
1715
+ ?sortable="${this.sortable && this.readonly !== true}"
1716
+ ?readonly="${this.readonly}"
1717
+ ?readonlyPlans="${this.readonlyPlans}"
1718
+ flows-title="${this.flowsTitle}"
1719
+ .query="${this._searchFlowQuery}"
1720
+ ?can-add="${this.canAdd && !this.readonly}"
1721
+ @gv-policy-studio-menu:reorder-flows="${this._onReorderFlows}"
1722
+ @gv-policy-studio-menu:change-flow-state="${this._onChangeFlowState}"
1723
+ @gv-policy-studio-menu:add-flow="${this._onAddFlow}"
1724
+ @gv-policy-studio-menu:add-flow-plan="${this._onAddFlowPlan}"
1725
+ @gv-policy-studio-menu:delete-flow="${this._onDeleteFlow}"
1726
+ @gv-policy-studio-menu:duplicate-flow="${this._onDuplicateFlow}"
1727
+ @gv-policy-studio-menu:select-flows="${this._onSelectFlows}"
1728
+ >
1729
+ <div slot="header" class="header-actions">
1730
+ <div class="title">${this._definition.name}</div>
1731
+ ${this._flowFilterOptions != null
1732
+ ? html`<gv-option
1733
+ ?disabled="${this._currentAskConfirmation}"
1734
+ .options="${this._flowFilterOptions}"
1735
+ multiple
1736
+ outlined
1737
+ .value="${this._flowFilter}"
1738
+ small
1739
+ @gv-option:select="${this._onFilterFlows}"
1740
+ ></gv-option>`
1741
+ : ''}
1742
+ <gv-input
1743
+ ?disabled="${this._currentAskConfirmation}"
1744
+ id="search-flow"
1745
+ placeholder="Filter flows (Ctrl + Space)"
1746
+ type="search"
1747
+ small
1748
+ @gv-input:input="${this._onSearchFlows}"
1749
+ @gv-input:clear="${this._onClearFlows}"
1750
+ ></gv-input>
1751
+ </div>
1752
+
1753
+ ${this.readonly !== true
1754
+ ? html` <div slot="footer" class="footer-actions">
1755
+ <gv-button
1756
+ class="btn-large"
1757
+ .disabled="${!this.isDirty || this._currentAskConfirmation}"
1758
+ @gv-button:click="${this._onSaveAll}"
1759
+ >Save</gv-button
1760
+ >
1761
+ <gv-button link .disabled="${!this.isDirty || this._currentAskConfirmation}" @gv-button:click="${this._onResetAll}"
1762
+ >Reset</gv-button
1763
+ >
1764
+ </div>`
1765
+ : ''}
1766
+ </gv-policy-studio-menu>
1767
+
1768
+ <gv-tabs
1769
+ .value="${this.tabId}"
1770
+ .options="${this._tabs}"
1771
+ .disabled="${this._currentAskConfirmation}"
1772
+ @gv-tabs:change="${this._onChangeTab}"
1773
+ .validator="${this._changeTabValidator.bind(this)}"
1774
+ >
1775
+ ${this._renderDesign(readonlyMode)} ${this._renderConfigurationForm(readonlyMode)} ${this._renderDebug()}
1776
+ <gv-properties
1777
+ id="properties"
1778
+ slot="content"
1779
+ class="properties"
1780
+ .provider="${this.services['dynamic-property']}"
1781
+ @gv-properties:change="${this._onPropertiesChange}"
1782
+ @gv-properties:save-provider="${this._onSaveProvider}"
1783
+ @gv-properties:switch-encrypted="${this._onSwitchEncryptedProperty}"
1784
+ ?readonly="${readonlyMode}"
1785
+ encryptable="true"
1786
+ .properties="${this.definedProperties}"
1787
+ .providers="${this.propertyProviders}"
1788
+ .dynamicPropertySchema="${this.dynamicPropertySchema}"
1789
+ ></gv-properties>
1790
+ <gv-resources
1791
+ id="resources"
1792
+ slot="content"
1793
+ class="resources"
1794
+ @gv-resources:change="${this._onResourcesChange}"
1795
+ ?readonly="${readonlyMode}"
1796
+ .resources="${this.definedResources}"
1797
+ .types="${this.resourceTypes}"
1798
+ ></gv-resources>
1799
+ </gv-tabs>
1800
+ </div>`;
1699
1801
  }
1802
+
1700
1803
  /**
1701
1804
  * Determine if the design view should be in readonly mode or not
1702
1805
  * It is in readonly mode if:
@@ -1708,42 +1811,30 @@ export class GvPolicyStudio extends KeyboardElement(LitElement) {
1708
1811
  * @returns {boolean|*|{type: BooleanConstructor}|{attribute: string, type: BooleanConstructor}|{type: *}|{attribute: string, type: *}}
1709
1812
  * @private
1710
1813
  */
1711
-
1712
-
1713
1814
  _getReadonlyModeForDesign() {
1714
1815
  if (this.readonly) {
1715
1816
  return true;
1716
1817
  }
1717
1818
 
1718
1819
  const flow = this.getSelectedFlow(0);
1719
-
1720
1820
  if (!flow) {
1721
1821
  return false;
1722
1822
  }
1723
1823
 
1724
- const {
1725
- plan: flowPlan
1726
- } = this._findFlowCollection(flow._id);
1727
-
1824
+ const { plan: flowPlan } = this._findFlowCollection(flow._id);
1728
1825
  const readonlyMode = flowPlan && this.readonlyPlans;
1729
-
1730
1826
  if (readonlyMode) {
1731
1827
  return true;
1732
1828
  }
1733
1829
 
1734
1830
  const comparedFlow = this.getSelectedFlow(1);
1735
-
1736
1831
  if (!comparedFlow) {
1737
1832
  return false;
1738
1833
  }
1739
1834
 
1740
- const {
1741
- plan: comparedFlowPlan
1742
- } = this._findFlowCollection(comparedFlow._id);
1743
-
1835
+ const { plan: comparedFlowPlan } = this._findFlowCollection(comparedFlow._id);
1744
1836
  return comparedFlowPlan && this.readonlyPlans;
1745
1837
  }
1746
-
1747
1838
  }
1839
+
1748
1840
  window.customElements.define('gv-policy-studio', GvPolicyStudio);
1749
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4vbm9kZV9tb2R1bGVzL0BncmF2aXRlZS91aS1jb21wb25lbnRzL3BvbGljeS1zdHVkaW8vZ3YtcG9saWN5LXN0dWRpby5qcyJdLCJuYW1lcyI6WyJjc3MiLCJodG1sIiwiTGl0RWxlbWVudCIsIm1ldGhvZHMiLCJkaXNwYXRjaEN1c3RvbUV2ZW50IiwiZW1wdHkiLCJjYWNoZSIsImRlZXBDbG9uZSIsImRlZXBFcXVhbCIsIktleWJvYXJkRWxlbWVudCIsIktFWVMiLCJGTE9XX1NURVBfRk9STV9JRCIsIkd2UG9saWN5U3R1ZGlvIiwicHJvcGVydGllcyIsInBvbGljaWVzIiwidHlwZSIsIkFycmF5Iiwic2VydmljZXMiLCJPYmplY3QiLCJyZXNvdXJjZVR5cGVzIiwiYXR0cmlidXRlIiwicHJvcGVydHlQcm92aWRlcnMiLCJkeW5hbWljUHJvcGVydHlTY2hlbWEiLCJ0YWJJZCIsIlN0cmluZyIsIl90YWJJZCIsImRlZmluaXRpb24iLCJfZGVmaW5pdGlvbiIsImRvY3VtZW50YXRpb24iLCJmbG93U2NoZW1hIiwiY29uZmlndXJhdGlvblNjaGVtYSIsIl9jb25maWd1cmF0aW9uU2NoZW1hIiwiY29uZmlndXJhdGlvbkluZm9ybWF0aW9uIiwiaXNEaXJ0eSIsIkJvb2xlYW4iLCJyZWZsZWN0IiwiX2RyYWdQb2xpY3kiLCJfZHJvcFBvbGljeSIsInNlbGVjdGVkRmxvd3NJZCIsIl9zZWxlY3RlZEZsb3dzSWQiLCJfY3VycmVudFBvbGljeUlkIiwiX3NlYXJjaFBvbGljeVF1ZXJ5IiwiX3NlYXJjaEZsb3dRdWVyeSIsIl9mbG93U3RlcFNjaGVtYSIsIl9jdXJyZW50Rmxvd1N0ZXAiLCJfcG9saWN5RmlsdGVyIiwiX2Zsb3dGaWx0ZXIiLCJfY3VycmVudEFza0NvbmZpcm1hdGlvbiIsImhhc1Byb3BlcnRpZXMiLCJfaGFzUHJvcGVydGllcyIsImhhc1Jlc291cmNlcyIsImhhc1BvbGljeUZpbHRlciIsImZsb3dzVGl0bGUiLCJzb3J0YWJsZSIsImNhbkFkZCIsInJlYWRvbmx5IiwicmVhZG9ubHlQbGFucyIsImNhbkRlYnVnIiwiX2NhbkRlYnVnIiwiZGVidWdSZXNwb25zZSIsInN0eWxlcyIsImNvbnN0cnVjdG9yIiwiZmxvd3MiLCJfdGFicyIsImlkIiwidGl0bGUiLCJpY29uIiwidmFsdWUiLCJ0aGVuIiwicmVxdWVzdFVwZGF0ZSIsIl9mbG93RmlsdGVyT3B0aW9ucyIsImRlZmluZWRQbGFucyIsImxlbmd0aCIsIl9wb2xpY3lGaWx0ZXJPcHRpb25zIiwic3BsaWNlIiwib25LZXlib2FyZCIsImlzUHJlc3NlZCIsIlNoaWZ0IiwiQ3RybCIsIlNwYWNlIiwic2VhcmNoIiwic2hhZG93Um9vdCIsInF1ZXJ5U2VsZWN0b3IiLCJmb2N1cyIsImluY2x1ZGVzIiwiX2dlbmVyYXRlRmxvd3NJZCIsInJlc291cmNlcyIsIl9nZW5lcmF0ZUlkIiwicGxhbnMiLCJtYXAiLCJwbGFuIiwiX2dlbmVyYXRlUGxhbkZsb3dzSWQiLCJfaW5pdGlhbERlZmluaXRpb24iLCJfc2VsZWN0Rmlyc3RGbG93IiwiaXNBcnJheSIsImZpbHRlciIsIl9maW5kRmxvd0J5SWQiLCJfdXBkYXRlU2VsZWN0ZWRGbG93cyIsImRpc3BhdGNoIiwiY2FuZGlkYXRlIiwiZGVmaW5lZEZsb3dzIiwiX2lkIiwiZmluZCIsIl9nZXRGbG93RWxlbWVudCIsImZsb3dJZCIsIl9vbkRyYWdFbmRQb2xpY3kiLCJxdWVyeVNlbGVjdG9yQWxsIiwiZm9yRWFjaCIsImUiLCJvbkRyYWdFbmQiLCJfb25Ecm9wUG9saWN5IiwiZGV0YWlsIiwiX2Fza1RvVmFsaWRhdGVGb3JtcyIsInBvbGljeSIsInRhcmdldEZsb3ciLCJuYW1lIiwiZGVzY3JpcHRpb24iLCJjb25maWd1cmF0aW9uIiwiX25ldyIsImZsb3dTdGVwIiwiX2dlbmVyYXRlRmxvd1N0ZXBJZCIsImZsb3dLZXkiLCJwb3NpdGlvbiIsImVuYWJsZWQiLCJzb3VyY2VGbG93Iiwic291cmNlRmxvd0lkIiwic291cmNlUG9zaXRpb24iLCJzb3VyY2VGbG93S2V5Iiwic3RlcCIsImdyb3VwIiwic2NoZW1hIiwiYnVpbGRTY2hlbWEiLCJfc2V0Q3VycmVudEZsb3dTdGVwIiwiY3VycmVudEZsb3dGb3JtIiwiX2dldEZsb3dTdGVwRm9ybSIsImRpcnR5IiwiY2FuY2VsRWRpdCIsInNldFRpbWVvdXQiLCJfZWRpdEZsb3dTdGVwIiwiZmxvdyIsInVwZGF0ZUNvbXBsZXRlIiwiZmxvd0VsZW1lbnQiLCJzZWxlY3RlZFN0ZXBJZCIsIl9kaXJ0eSIsImd2RmxvdyIsInJlbW92ZUNhbmRpZGF0ZSIsIl9vbkRlbGV0ZVBvbGljeSIsInRhcmdldCIsImVkaXRpbmciLCJfY2xvc2VGbG93U3RlcEZvcm0iLCJfb25EZXNpZ24iLCJfY2hhbmdlVGFiIiwiX3NwbGl0TWFpblZpZXdzIiwianNvblNjaGVtYSIsIkpTT04iLCJwYXJzZSIsImN1cnJlbnRGbG93U3RlcCIsImxvY2FsU3RvcmFnZSIsImdldEl0ZW0iLCJfb25PcGVuRG9jdW1lbnRhdGlvbiIsIl9tYXhpbWl6ZVRvcFZpZXciLCJfb25FZGl0Rmxvd1N0ZXAiLCJfZ2V0UmVzaXphYmxlVmlld3MiLCJtYXhpbWl6ZVRvcCIsIl9tYXhpbWl6ZUJvdHRvbVZpZXciLCJtYXhpbWl6ZUJvdHRvbSIsInNwbGl0IiwiX29uQ2hhbmdlRmxvd1N0ZXBTdGF0ZSIsIl9vbkNsb3NlRmxvd1N0ZXBGb3JtIiwiZXJyIiwiZm9yY2UiLCJQcm9taXNlIiwiYWxsIiwiX3N1Ym1pdE9yQ29uZmlybUZvcm1zIiwiZm9ybXMiLCJyIiwiX2J1aWxkRGVmaW5pdGlvblRvU2F2ZSIsImdldENoaWxkcmVuIiwiX2NoZWNrQ3VycmVudEZsb3dTdGVwIiwiRXJyb3IiLCJmbG93U3RlcFNjaGVtYSIsIl9pbml0aWFsVmFsdWVzIiwic2NvcGUiLCJfZW51bSIsImVudW0iLCJmaWx0ZXJlZCIsImRlZmF1bHQiLCJfdmFsdWVzIiwiX3JlZnJlc2giLCJjbG9zZVN0ZXBGb3JtIiwiX29uU2VsZWN0Rmxvd3MiLCJfb25DbG9zZURvY3VtZW50YXRpb24iLCJfb25PcGVuRG9jdW1lbnRhdGlvbkZyb21NZW51IiwiZ2V0U2VsZWN0ZWRGbG93IiwiX2ZldGNoRG9jdW1lbnRhdGlvbiIsIl9vbk9wZW5Eb2N1bWVudGF0aW9uRnJvbUZvcm0iLCJyZW1vdmVJdGVtIiwiX2ZpbmRGbG93Q29sbGVjdGlvbiIsInBsYW5zRmxvd3MiLCJyZWR1Y2UiLCJhY2MiLCJ2YWwiLCJjb25jYXQiLCJpbmRleCIsInNlbGVjdGVkRmxvd0lkIiwiX29uVGFyZ2V0UG9saWN5IiwiX29uQ2hhbmdlRmxvd1N0ZXAiLCJ2YWx1ZXMiLCJfd3JpdGVGbG93U3RlcCIsImZpbmRJbmRleCIsIl9vblN1Ym1pdEZsb3dTdGVwIiwiYyIsIl9vbkNhbmNlbEZsb3ciLCJfb25TdWJtaXRGbG93Iiwic2VsZWN0ZWRGbG93IiwiYXNzaWduIiwiX2NyZWF0ZUZsb3dGcm9tU2NoZW1hIiwic2VsZWN0ZWRGbG93VXBkYXRlZCIsIl9vbkNhbmNlbEZsb3dNb2RlIiwiX29uU3VibWl0Rmxvd01vZGUiLCJfb25DaGFuZ2VUYWIiLCJfY2hhbmdlVGFiVmFsaWRhdG9yIiwiZnJvbSIsInRvIiwiY29tcG9uZW50IiwiY29uZmlybSIsInJlc29sdmUiLCJfb25EcmFnU3RhcnRGbG93U3RlcCIsIl9yZW5kZXJGbG93RW1wdHlTdGF0ZSIsInJlYWRvbmx5TW9kZSIsIl9vbkFkZEZsb3ciLCJfcmVuZGVyRmxvdyIsImhhc0VtcHR5U3RhdGUiLCJiaW5kIiwiX29uRmV0Y2hSZXNvdXJjZXMiLCJldmVudCIsImN1cnJlbnRUYXJnZXQiLCJyZWdleFR5cGVzIiwib3B0aW9ucyIsImRlZmluZWRSZXNvdXJjZXMiLCJyZXNvdXJjZSIsIlJlZ0V4cCIsInRlc3QiLCJyZXNvdXJjZVR5cGUiLCJyb3ciLCJkb2N1bWVudCIsImNyZWF0ZUVsZW1lbnQiLCJwaWN0dXJlIiwiaXRlbSIsImVsZW1lbnQiLCJfcmVuZGVyUG9saWN5IiwiX3JlbmRlckZsb3dTdGVwRm9ybSIsImNvbnRlbnQiLCJpbWFnZSIsIl9vblJlc2V0Rmxvd1N0ZXAiLCJyZXNldCIsImxpc3QiLCJwcmVmaXgiLCJpc0Zsb3ciLCJwcmUiLCJzdGVwSW5kZXgiLCJwb3N0IiwiZ2V0VXBkYXRlQ29tcGxldGUiLCJzaG91bGRVcGRhdGUiLCJjaGFuZ2VkUHJvcGVydGllcyIsImhhcyIsImRyYWdQb2xpY3kiLCJkcm9wUG9saWN5IiwidXBkYXRlZCIsInByb3BzIiwic2V0SXRlbSIsIl9vbkRlbGV0ZUZsb3ciLCJfZGVsZXRlRmxvdyIsImRlZmluZWRQcm9wZXJ0aWVzIiwiX29uRHVwbGljYXRlRmxvdyIsIl9hZGRGbG93IiwicGxhbkluZGV4IiwicCIsImkiLCJfb25DaGFuZ2VGbG93U3RhdGUiLCJfb25BZGRGbG93UGxhbiIsImNvbGxlY3Rpb24iLCJkdXBsaWNhdGUiLCJwdXNoIiwibmV3RmxvdyIsIl9pbnN0YW50aWF0ZSIsInByb3BlcnRpZXNEZWZpbml0aW9uIiwiaW5pdGlhdG9yIiwicHJvcGVydHkiLCJrZXkiLCJrZXlzIiwiZW50cnkiLCJ1bmRlZmluZWQiLCJpbmRleE9mIiwic2VsZWN0ZWRGbG93cyIsIl9maW5kRmxvd0luZGV4IiwiZiIsIl9vblJlb3JkZXJGbG93cyIsIm5ld09yZGVyIiwiX29uU2VhcmNoUG9saWN5IiwiX29uQ2xlYXJQb2xpY3kiLCJfb25TZWFyY2hGbG93cyIsIl9vbkNsZWFyRmxvd3MiLCJfb25SZXNldEFsbCIsIl9maWx0ZXJOb3RWYWxpZFN0ZXAiLCJfcmVtb3ZlUHJpdmF0ZVByb3BlcnRpZXMiLCJvIiwiY29weSIsInN0YXJ0c1dpdGgiLCJmb3JtIiwiaXNWYWxpZCIsInN1Ym1pdCIsImdldFByb3BlcnRpZXNFbGVtZW50IiwiY2xvc2VQcm9taXNlcyIsImN1cnJlbnRTdGVwIiwic2F2ZWQiLCJfZGVmaW5pdGlvblNhdmVkIiwiX2J1aWxkRGVmaW5pdGlvblRvU2VuZCIsImRlZmluaXRpb25Ub1NhdmUiLCJfb25TYXZlQWxsIiwiY2F0Y2giLCJjb25zb2xlIiwiZXJyb3IiLCJfb25EZWJ1ZyIsInJlcXVlc3RFdmVudCIsInJlcXVlc3QiLCJmaWx0ZXJlZEZsb3dzIiwiZmlsdGVyZWRQbGFucyIsIl9vbkZpbHRlckZsb3dzIiwiX2dldEZpbHRlcmVkUG9saWNpZXMiLCJvblJlcXVlc3QiLCJvblJlc3BvbnNlIiwiX29uRmlsdGVyUG9saWNpZXMiLCJfcmVuZGVyRGVzaWduIiwiX3JlbmRlckZsb3dGb3JtIiwiX3JlbmRlckRlYnVnIiwicmVzcG9uc2UiLCJpc0xvYWRpbmciLCJwYXRoIiwibWV0aG9kIiwiX3JlbmRlckNvbmZpZ3VyYXRpb25Gb3JtIiwiX29uUmVzb3VyY2VzQ2hhbmdlIiwiX29uUHJvcGVydGllc0NoYW5nZSIsIl9vblNhdmVQcm92aWRlciIsInByb3ZpZGVyIiwiX29uU3dpdGNoRW5jcnlwdGVkUHJvcGVydHkiLCJyZW5kZXIiLCJfZ2V0UmVhZG9ubHlNb2RlRm9yRGVzaWduIiwiZmxvd1BsYW4iLCJjb21wYXJlZEZsb3ciLCJjb21wYXJlZEZsb3dQbGFuIiwid2luZG93IiwiY3VzdG9tRWxlbWVudHMiLCJkZWZpbmUiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVNBLEdBQVQsRUFBY0MsSUFBZCxFQUFvQkMsVUFBcEIsUUFBc0MsS0FBdEM7QUFDQSxTQUFTQyxPQUFULFFBQXdCLGVBQXhCO0FBQ0EsU0FBU0MsbUJBQVQsUUFBb0MsZUFBcEM7QUFDQSxPQUFPLG9CQUFQO0FBQ0EsT0FBTyxrQkFBUDtBQUNBLE9BQU8sd0JBQVA7QUFDQSxPQUFPLCtCQUFQO0FBQ0EsT0FBTyxpQ0FBUDtBQUNBLE9BQU8sNkJBQVA7QUFDQSxPQUFPLDZCQUFQO0FBQ0EsT0FBTyxzQkFBUDtBQUNBLE9BQU8scUJBQVA7QUFDQSxPQUFPLFdBQVA7QUFDQSxPQUFPLGdCQUFQO0FBQ0EsT0FBTyx5QkFBUDtBQUNBLFNBQVNDLEtBQVQsUUFBc0IsaUJBQXRCO0FBQ0EsU0FBU0MsS0FBVCxRQUFzQixzQkFBdEI7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QUNBLFFBQUksQ0FBQzRKLFlBQUwsRUFBbUI7QUFDakIsYUFBTyxLQUFQO0FBQ0Q7O0FBRUQsVUFBTTtBQUFFblEsTUFBQUEsSUFBSSxFQUFFb1E7QUFBUixRQUE2QixLQUFLekosbUJBQUwsQ0FBeUJ3SixZQUFZLENBQUN4UCxHQUF0QyxDQUFuQzs7QUFDQSxXQUFPeVAsZ0JBQWdCLElBQUksS0FBS3RTLGFBQWhDO0FBQ0Q7O0FBdHRENkQ7QUF5dERoRXVTLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQkMsTUFBdEIsQ0FBNkIsa0JBQTdCLEVBQWlEclYsY0FBakQiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChDKSAyMDE1IFRoZSBHcmF2aXRlZSB0ZWFtIChodHRwOi8vZ3Jhdml0ZWUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuaW1wb3J0IHsgY3NzLCBodG1sLCBMaXRFbGVtZW50IH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IG1ldGhvZHMgfSBmcm9tICcuLi9saWIvc3R1ZGlvJztcbmltcG9ydCB7IGRpc3BhdGNoQ3VzdG9tRXZlbnQgfSBmcm9tICcuLi9saWIvZXZlbnRzJztcbmltcG9ydCAnLi4vYXRvbXMvZ3YtYnV0dG9uJztcbmltcG9ydCAnLi4vYXRvbXMvZ3YtaWNvbic7XG5pbXBvcnQgJy4uL21vbGVjdWxlcy9ndi1vcHRpb24nO1xuaW1wb3J0ICcuLi9vcmdhbmlzbXMvZ3YtZG9jdW1lbnRhdGlvbic7XG5pbXBvcnQgJy4uL29yZ2FuaXNtcy9ndi1yZXNpemFibGUtdmlld3MnO1xuaW1wb3J0ICcuLi9vcmdhbmlzbXMvZ3Ytc2NoZW1hLWZvcm0nO1xuaW1wb3J0ICcuLi9vcmdhbmlzbXMvZ3YtaHR0cC1jbGllbnQnO1xuaW1wb3J0ICcuLi9vcmdhbmlzbXMvZ3YtdGFicyc7XG5pbXBvcnQgJy4uL21vbGVjdWxlcy9ndi1yb3cnO1xuaW1wb3J0ICcuL2d2LWZsb3cnO1xuaW1wb3J0ICcuL2d2LWZsb3ctc3RlcCc7XG5pbXBvcnQgJy4vZ3YtcG9saWN5LXN0dWRpby1tZW51JztcbmltcG9ydCB7IGVtcHR5IH0gZnJvbSAnLi4vc3R5bGVzL2VtcHR5JztcbmltcG9ydCB7IGNhY2hlIH0gZnJvbSAnbGl0L2RpcmVjdGl2ZXMvY2FjaGUnO1xuaW1wb3J0IHsgZGVlcENsb25lLCBkZWVwRXF1YWwgfSBmcm9tICcuLi9saWIvdXRpbHMnO1xuaW1wb3J0IHsgS2V5Ym9hcmRFbGVtZW50LCBLRVlTIH0gZnJvbSAnLi4vbWl4aW5zL2tleWJvYXJkLWVsZW1lbnQnO1xuXG5jb25zdCBGTE9XX1NURVBfRk9STV9JRCA9ICdmbG93LXN0ZXAtZm9ybSc7XG5cbi8qKlxuICogIFN0dWRpbyBQb2xpY3kgY29tcG9uZW50XG4gKlxuICog4pqg77iPIFRoaXMgY29tcG9uZW50IGlzIGJhc2VkIG9uIGBhc2NpaWRvY3RvcmAsIGBoaWdobGlnaHQuanNgIGFuZCBgYXNjaWlkb2N0b3ItaGlnaGxpZ2h0LmpzYC5cbiAqIFRvIHVzZSB0aGlzIGNvbXBvbmVudCBpbiB5b3VyIHByb2plY3QgYmUgc3VyZSB0aGUgZGVwZW5kZW5jaWVzIGFyZSBpbnN0YWxsZWQgb3JcbiAqIGluc3RhbGwgdGhlbSB3aXRoOiBgbnBtIGluc3RhbGwgYXNjaWlkb2N0b3IgaGlnaGxpZ2h0LmpzIGFzY2lpZG9jdG9yLWhpZ2hsaWdodC5qcyAtLXNhdmVgXG4gKlxuICogQGZpcmVzIGd2LXBvbGljeS1zdHVkaW86c2VsZWN0LXBvbGljeSAtIFNlbGVjdCBwb2xpY3kgZXZlbnRcbiAqIEBmaXJlcyBndi1wb2xpY3ktc3R1ZGlvOnNhdmUgLSBFdmVudCBzZW50IHdoZW4gXCJTYXZlXCIgYnV0dG9uIGlzIGNsaWNrZWQsIGl0IGNvbnRhaW5zIHRoZSB3aG9sZSBkZWZpbml0aW9uIG9mIHRoZSBBUElcbiAqIEBmaXJlcyBndi1wb2xpY3ktc3R1ZGlvOmRlYnVnIC0gRXZlbnQgc2VudCB3aGVuIHZhbGlkYXRpb24gYnV0dG9uIG9mIHRoZSAnVHJ5IGl0JyB0YWIgaXMgY2xpY2tlZCwgaXQgY29udGFpbnMgdGhlIHdob2xlIGRlZmluaXRpb24gb2YgdGhlIEFQSSBhbmQgdGhlIGluZm9ybWF0aW9uIGFib3V0IHRoZSB0cnkgaXQgcmVxdWVzdC5cbiAqXG4gKiBAYXR0ciB7QXJyYXl9IHBvbGljaWVzIC0gUG9saWNpZXMgYXZhaWxhYmxlXG4gKiBAYXR0ciB7QXJyYXl9IHNlcnZpY2VzIC0gU2VydmljZXMgYXZhaWxhYmxlXG4gKiBAYXR0ciB7QXJyYXl9IHJlc291cmNlVHlwZXMgLSBSZXNvdXJjZXMgdHlwZXMgYXZhaWxhYmxlXG4gKiBAYXR0ciB7QXJyYXl9IHByb3BlcnR5UHJvdmlkZXJzIC0gUHJvdmlkZXJzIG9mIHByb3BlcnRpZXNcbiAqIEBhdHRyIHtBcnJheX0gZHluYW1pY1Byb3BlcnR5U2NoZW1hIC0gU2NoZW1hIGZvciB0aGUgZHluYW1pYyBwcm9wZXJ0eSBmb3JtXG4gKiBAYXR0ciB7U3RyaW5nfSB0YWJJZCAtIEN1cnJlbnQgdGFiSWQgdG8gZGlzcGxheSAoZGVzaWduLCBzZXR0aW5ncywgcHJvcGVydGllcyBvciByZXNvdXJjZXMpXG4gKiBAYXR0ciB7T2JqZWN0fSBkZWZpbml0aW9uIC0gVGhlIGRlZmluaXRpb24gb2YgZmxvd3NcbiAqIEBhdHRyIHtPYmplY3R9IGRvY3VtZW50YXRpb24gLSBUaGUgZG9jdW1lbnRhdGlvbiB0byBkaXNwbGF5XG4gKiBAYXR0ciB7T2JqZWN0fSBmbG93U2NoZW1hIC0gVGhlIGZsb3cgZm9ybSBjb25maWd1cmF0aW9uIHRvIGRpc3BsYXkgaW4gZ3Ytc2NoZW1hLWZvcm0gY29tcG9uZW50XG4gKiBAYXR0ciB7T2JqZWN0fSBjb25maWd1cmF0aW9uU2NoZW1hIC0gVGhlIGZvcm0gY29uZmlndXJhdGlvbiB0byBkaXNwbGF5IGluIGd2LXNjaGVtYS1mb3JtIGNvbXBvbmVudFxuICogQGF0dHIge09iamVjdH0gY29uZmlndXJhdGlvbkluZm9ybWF0aW9uIC0gVGhlIGluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gYXBpIGNvbmZpZ3VyYXRpb24gdGFiXG4gKiBAYXR0ciB7Qm9vbGVhbn0gaXNEaXJ0eSAtIHRydWUgaWYgY29tcG9uZW50IGlzIGRpcnR5XG4gKiBAYXR0ciB7QXJyYXl9IHNlbGVjdGVkRmxvd3NJZCAtIFRoZSBzZWxlY3RlZCBmbG93cyBpZFxuICogQGF0dHIge0Jvb2xlYW59IHNvcnRhYmxlIC0gdHJ1ZSBpZiBmbG93cyBhcmUgc29ydGFibGVcbiAqIEBhdHRyIHtCb29sZWFufSByZWFkb25seSAtIHRydWUgaWYgcmVhZG9ubHlcbiAqIEBhdHRyIHtCb29sZWFufSByZWFkb25seS1wbGFucyAtIHRydWUgaWYgcGxhbnMnIGZsb3dzIGNhbid0IGJlIG1vZGlmaWVkXG4gKiBAYXR0ciB7Qm9vbGVhbn0gY2FuLWFkZCAtIHRydWUgaWYgdXNlciBjYW4gYWRkIGZsb3dcbiAqIEBhdHRyIHtTdHJpbmd9IGZsb3dzVGl0bGUgLSBmbG93cyBtZW51IHRpdGxlXG4gKiBAYXR0ciB7Qm9vbGVhbn0gaGFzLXBvbGljeS1maWx0ZXIgLSB0cnVlIGlmIHBvbGljaWVzIGhhdmUgb25SZXF1ZXN0L29uUmVzcG9uc2UgcHJvcGVydGllc1xuICogQGF0dHIge0Jvb2xlYW59IGNhbi1kZWJ1ZyAtIHRydWUgaWYgZGVidWcgdGFiIHNob3VsZCBiZSBkaXNwbGF5ZWRcbiAqIEBhdHRyIHtPYmplY3R9IGRlYnVnUmVzcG9uc2UgLSB0cnVlIGlmIGRlYnVnIHRhYiBzaG91bGQgYmUgZGlzcGxheWVkXG4gKi9cbmV4cG9ydCBjbGFzcyBHdlBvbGljeVN0dWRpbyBleHRlbmRzIEtleWJvYXJkRWxlbWVudChMaXRFbGVtZW50KSB7XG4gIHN0YXRpYyBnZXQgcHJvcGVydGllcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgcG9saWNpZXM6IHsgdHlwZTogQXJyYXkgfSxcbiAgICAgIHNlcnZpY2VzOiB7IHR5cGU6IE9iamVjdCB9LFxuICAgICAgcmVzb3VyY2VUeXBlczogeyB0eXBlOiBBcnJheSwgYXR0cmlidXRlOiAncmVzb3VyY2UtdHlwZXMnIH0sXG4gICAgICBwcm9wZXJ0eVByb3ZpZGVyczogeyB0eXBlOiBBcnJheSwgYXR0cmlidXRlOiAncHJvcGVydHktcHJvdmlkZXJzJyB9LFxuICAgICAgZHluYW1pY1Byb3BlcnR5U2NoZW1hOiB7IHR5cGU6IE9iamVjdCwgYXR0cmlidXRlOiAnZHluYW1pYy1wcm9wZXJ0eS1zY2hlbWEnIH0sXG4gICAgICB0YWJJZDogeyB0eXBlOiBTdHJpbmcsIGF0dHJpYnV0ZTogJ3RhYi1pZCcgfSxcbiAgICAgIF90YWJJZDogeyB0eXBlOiBTdHJpbmcsIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIGRlZmluaXRpb246IHsgdHlwZTogT2JqZWN0IH0sXG4gICAgICBfZGVmaW5pdGlvbjogeyB0eXBlOiBPYmplY3QsIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIGRvY3VtZW50YXRpb246IHsgdHlwZTogT2JqZWN0IH0sXG4gICAgICBmbG93U2NoZW1hOiB7IHR5cGU6IE9iamVjdCwgYXR0cmlidXRlOiAnZmxvdy1zY2hlbWEnIH0sXG4gICAgICBjb25maWd1cmF0aW9uU2NoZW1hOiB7IHR5cGU6IE9iamVjdCwgYXR0cmlidXRlOiAnY29uZmlndXJhdGlvbi1zY2hlbWEnIH0sXG4gICAgICBfY29uZmlndXJhdGlvblNjaGVtYTogeyB0eXBlOiBPYmplY3QsIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIGNvbmZpZ3VyYXRpb25JbmZvcm1hdGlvbjogeyB0eXBlOiBTdHJpbmcsIGF0dHJpYnV0ZTogJ2NvbmZpZ3VyYXRpb24taW5mb3JtYXRpb24nIH0sXG4gICAgICBpc0RpcnR5OiB7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogJ2RpcnR5JywgcmVmbGVjdDogdHJ1ZSB9LFxuICAgICAgX2RyYWdQb2xpY3k6IHsgdHlwZTogT2JqZWN0LCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBfZHJvcFBvbGljeTogeyB0eXBlOiBPYmplY3QsIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIHNlbGVjdGVkRmxvd3NJZDogeyB0eXBlOiBBcnJheSwgYXR0cmlidXRlOiAnc2VsZWN0ZWQtZmxvd3MtaWQnIH0sXG4gICAgICBfc2VsZWN0ZWRGbG93c0lkOiB7IHR5cGU6IEFycmF5LCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBfY3VycmVudFBvbGljeUlkOiB7IHR5cGU6IFN0cmluZywgYXR0cmlidXRlOiBmYWxzZSB9LFxuICAgICAgX3NlYXJjaFBvbGljeVF1ZXJ5OiB7IHR5cGU6IFN0cmluZywgYXR0cmlidXRlOiBmYWxzZSB9LFxuICAgICAgX3NlYXJjaEZsb3dRdWVyeTogeyB0eXBlOiBTdHJpbmcsIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIF9mbG93U3RlcFNjaGVtYTogeyB0eXBlOiBPYmplY3QsIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIF9jdXJyZW50Rmxvd1N0ZXA6IHsgdHlwZTogT2JqZWN0LCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBfcG9saWN5RmlsdGVyOiB7IHR5cGU6IEFycmF5LCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBfZmxvd0ZpbHRlcjogeyB0eXBlOiBBcnJheSwgYXR0cmlidXRlOiBmYWxzZSB9LFxuICAgICAgX2N1cnJlbnRBc2tDb25maXJtYXRpb246IHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiBmYWxzZSB9LFxuICAgICAgaGFzUHJvcGVydGllczogeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdoYXMtcHJvcGVydGllcycgfSxcbiAgICAgIF9oYXNQcm9wZXJ0aWVzOiB7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIGhhc1Jlc291cmNlczogeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdoYXMtcmVzb3VyY2VzJyB9LFxuICAgICAgaGFzUG9saWN5RmlsdGVyOiB7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogJ2hhcy1wb2xpY3ktZmlsdGVyJyB9LFxuICAgICAgZmxvd3NUaXRsZTogeyB0eXBlOiBTdHJpbmcsIGF0dHJpYnV0ZTogJ2Zsb3dzLXRpdGxlJyB9LFxuICAgICAgc29ydGFibGU6IHsgdHlwZTogQm9vbGVhbiB9LFxuICAgICAgY2FuQWRkOiB7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogJ2Nhbi1hZGQnIH0sXG4gICAgICByZWFkb25seTogeyB0eXBlOiBCb29sZWFuIH0sXG4gICAgICByZWFkb25seVBsYW5zOiB7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogJ3JlYWRvbmx5LXBsYW5zJyB9LFxuICAgICAgY2FuRGVidWc6IHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnY2FuLWRlYnVnJyB9LFxuICAgICAgX2NhbkRlYnVnOiB7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIGRlYnVnUmVzcG9uc2U6IHsgdHlwZTogT2JqZWN0LCBhdHRyaWJ1dGU6ICdkZWJ1Zy1yZXNwb25zZScgfSxcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIGdldCBzdHlsZXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIGVtcHR5LFxuICAgICAgbWV0aG9kcyxcbiAgICAgIC8vIGxhbmd1YWdlPUNTU1xuICAgICAgY3NzYFxuICAgICAgICA6aG9zdCB7XG4gICAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgICAtLWhlaWdodDogdmFyKC0tZ3YtcG9saWN5LXN0dWRpby0taCwgY2FsYygxMDB2aCAtIDMycHgpKTtcbiAgICAgICAgICBoZWlnaHQ6IHZhcigtLWhlaWdodCk7XG4gICAgICAgICAgLS1oZWlnaHQtaW4tdGFiczogY2FsYyh2YXIoLS1oZWlnaHQpIC0gMjVweCk7XG4gICAgICAgIH1cblxuICAgICAgICAuYm94IHtcbiAgICAgICAgICBoZWlnaHQ6IHZhcigtLWhlaWdodCk7XG4gICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgfVxuXG4gICAgICAgIC5kZXNpZ24sXG4gICAgICAgIC5wcm9wZXJ0aWVzIHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICB9XG5cbiAgICAgICAgZ3YtcmVzaXphYmxlLXZpZXdzIHtcbiAgICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5lZGl0YWJsZS1uYW1lIHtcbiAgICAgICAgICBwYWRkaW5nOiAwLjVyZW0gMXJlbTtcbiAgICAgICAgICBmb250LXNpemU6IDE2cHg7XG4gICAgICAgIH1cblxuICAgICAgICAuZWRpdGFibGUtbmFtZSBzcGFuIHtcbiAgICAgICAgICBjb2xvcjogI2JmYmZiZjtcbiAgICAgICAgICBmb250LXNpemU6IDEycHg7XG4gICAgICAgIH1cblxuICAgICAgICAuZm9ybV9fY29udHJvbCB7XG4gICAgICAgICAgbWFyZ2luOiAwLjVyZW07XG4gICAgICAgIH1cblxuICAgICAgICBndi1pbnB1dCB7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIH1cblxuICAgICAgICAuZmxvdy1uYW1lIHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIH1cblxuICAgICAgICAuZmxvdy1uYW1lLmRpcnR5IHtcbiAgICAgICAgICBmb250LXN0eWxlOiBpdGFsaWM7XG4gICAgICAgICAgb3BhY2l0eTogMC44O1xuICAgICAgICB9XG5cbiAgICAgICAgLmZsb3ctbmFtZSBndi1pY29uIHtcbiAgICAgICAgICAtLWd2LWljb24tLXM6IDI0cHg7XG4gICAgICAgICAgbWFyZ2luLXJpZ2h0OiAwLjJyZW07XG4gICAgICAgIH1cblxuICAgICAgICAuZmxvdy1wYXRoIHtcbiAgICAgICAgICBtYXJnaW4tbGVmdDogMC4ycmVtO1xuICAgICAgICB9XG5cbiAgICAgICAgLnRpdGxlX21ldGhvZHMge1xuICAgICAgICAgIG1hcmdpbi1sZWZ0OiAwLjVyZW07XG4gICAgICAgIH1cblxuICAgICAgICAudHdvLWNvbHMge1xuICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICB9XG5cbiAgICAgICAgLnR3by1jb2xzID4gKiB7XG4gICAgICAgICAgZmxleDogMTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5sZWZ0LW1lbnUge1xuICAgICAgICAgIGJvcmRlci1sZWZ0OiAxcHggc29saWQgI2Q5ZDlkOTtcbiAgICAgICAgICBoZWlnaHQ6IHZhcigtLWhlaWdodC1pbi10YWJzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5yaWdodC1tZW51IHtcbiAgICAgICAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZDlkOWQ5O1xuICAgICAgICAgIGhlaWdodDogdmFyKC0taGVpZ2h0LWluLXRhYnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLnR3by1jb2xzID4gKjpmaXJzdC1jaGlsZCB7XG4gICAgICAgICAgYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgI2Q5ZDlkOTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5mbG93LXN0ZXBfX2NvbnRhaW5lciB7XG4gICAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgICBoZWlnaHQ6IDk5JTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5mbG93LXN0ZXBfX2Zvcm0ge1xuICAgICAgICAgIHBhZGRpbmc6IDAgMC41cmVtO1xuICAgICAgICAgIG92ZXJmbG93OiBhdXRvO1xuICAgICAgICB9XG5cbiAgICAgICAgLmZsb3ctc3RlcF9fZm9ybS10aXRsZSB7XG4gICAgICAgICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgICAgICAgICBsZXR0ZXItc3BhY2luZzogMC4ycmVtO1xuICAgICAgICB9XG5cbiAgICAgICAgZ3YtdGFicyB7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICAgICAgfVxuXG4gICAgICAgIGd2LXJlc2l6YWJsZS12aWV3cyxcbiAgICAgICAgZ3YtcHJvcGVydGllcyxcbiAgICAgICAgZ3YtcmVzb3VyY2VzIHtcbiAgICAgICAgICBoZWlnaHQ6IHZhcigtLWhlaWdodC1pbi10YWJzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGd2LXByb3BlcnRpZXMsXG4gICAgICAgIGd2LXJlc291cmNlcyB7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIH1cblxuICAgICAgICBndi1wcm9wZXJ0aWVzLnByb3BlcnRpZXMge1xuICAgICAgICAgIC0tZ3YtcHJvcGVydGllcy10YWJsZS0tY29sbWc6IDEwcHg7XG4gICAgICAgIH1cblxuICAgICAgICAuYXBpLXNldHRpbmdzIHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgICAgYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCAjYmZiZmJmO1xuICAgICAgICAgIGhlaWdodDogdmFyKC0taGVpZ2h0LWluLXRhYnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLmRlYnVnIHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgICAgYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCAjYmZiZmJmO1xuICAgICAgICAgIGhlaWdodDogdmFyKC0taGVpZ2h0LWluLXRhYnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLmFwaS1zZXR0aW5ncy1pbmZvcm1hdGlvbiB7XG4gICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgLmFwaS1zZXR0aW5ncy1pbmZvcm1hdGlvbl9faWNvbiB7XG4gICAgICAgICAgLS1ndi1pY29uLS1jOiB2YXIoLS1ndi10aGVtZS1jb2xvciwgIzVhNzY4NCk7XG4gICAgICAgICAgLS1ndi1pY29uLW9wYWNpdHktLWM6IHZhcigtLWd2LXRoZW1lLWNvbG9yLWluZm8tbGlnaHQsICM2NGI1ZjYpO1xuICAgICAgICB9XG5cbiAgICAgICAgLmFwaS1zZXR0aW5ncy1pbmZvcm1hdGlvbl9fYmxvY2txdW90ZSxcbiAgICAgICAgLmRlYnVnLWluZm9ybWF0aW9uX19ibG9ja3F1b3RlIHtcbiAgICAgICAgICBib3JkZXItbGVmdDogMXB4IHNvbGlkIHZhcigtLWd2LXRoZW1lLWNvbG9yLCAjNWE3Njg0KTtcbiAgICAgICAgICBtYXJnaW46IDE1cHg7XG4gICAgICAgICAgcGFkZGluZy1sZWZ0OiAxNXB4O1xuICAgICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgfVxuXG4gICAgICAgIC5mbG93LXNldHRpbmdzIGd2LXNjaGVtYS1mb3JtIHtcbiAgICAgICAgICBmbGV4OiAxO1xuICAgICAgICAgIHBhZGRpbmc6IDAuNXJlbTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5zZWFyY2gge1xuICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAganVzdGlmeS1jb250ZW50OiBzdHJldGNoO1xuICAgICAgICB9XG5cbiAgICAgICAgZ3YtaW5wdXQge1xuICAgICAgICAgIG1hcmdpbjogMC4ycmVtIDA7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIH1cblxuICAgICAgICAuaGVhZGVyLWFjdGlvbnMsXG4gICAgICAgIC5zZWFyY2gtcG9saWNpZXMge1xuICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgIG1hcmdpbjogMC41cmVtO1xuICAgICAgICB9XG5cbiAgICAgICAgLnNlYXJjaC1wb2xpY2llcyB7XG4gICAgICAgICAgbWFyZ2luOiAxLjVyZW0gMC41cmVtIDAuNXJlbTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5mb290ZXItYWN0aW9ucyA+IGd2LWJ1dHRvbi5idG4tbGFyZ2UsXG4gICAgICAgIC5mb290ZXItYWN0aW9ucyA+IGd2LW9wdGlvbiB7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIH1cblxuICAgICAgICAuZm9vdGVyLWFjdGlvbnMge1xuICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgIHBhZGRpbmc6IDAuNXJlbSAwO1xuICAgICAgICAgIG1hcmdpbjogMC41cmVtIDE1cHg7XG4gICAgICAgICAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICNiZmJmYmY7XG4gICAgICAgIH1cblxuICAgICAgICAuaGVhZGVyLWFjdGlvbnMgLnRpdGxlIHtcbiAgICAgICAgICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlO1xuICAgICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICAgICAgICBsZXR0ZXItc3BhY2luZzogMC4zcmVtO1xuICAgICAgICAgIGNvbG9yOiAjYmZiZmJmO1xuICAgICAgICAgIGZvbnQtc2l6ZTogMThweDtcbiAgICAgICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgICAgICAgd2lkdGg6IDI0MHB4O1xuICAgICAgICAgIG1pbi1oZWlnaHQ6IDI1cHg7XG4gICAgICAgIH1cblxuICAgICAgICAuaGVhZGVyLWFjdGlvbnMgPiAqLFxuICAgICAgICAuc2VhcmNoLXBvbGljaWVzID4gKiB7XG4gICAgICAgICAgbWFyZ2luLWJvdHRvbTogMXJlbTtcbiAgICAgICAgfVxuICAgICAgYCxcbiAgICBdO1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmlzRGlydHkgPSBmYWxzZTtcbiAgICB0aGlzLnBvbGljaWVzID0gW107XG4gICAgdGhpcy5yZXNvdXJjZVR5cGVzID0gW107XG4gICAgdGhpcy50YWJJZCA9ICdkZXNpZ24nO1xuICAgIHRoaXMuc2VsZWN0ZWRGbG93c0lkID0gW107XG4gICAgdGhpcy5mbG93c1RpdGxlID0gJ0Zsb3dzJztcbiAgICB0aGlzLnNvcnRhYmxlID0gZmFsc2U7XG4gICAgdGhpcy5zZXJ2aWNlcyA9IHt9O1xuICAgIHRoaXMuX2RlZmluaXRpb24gPSB7XG4gICAgICBmbG93czogW10sXG4gICAgfTtcbiAgICB0aGlzLl90YWJzID0gW3sgaWQ6ICdkZXNpZ24nLCB0aXRsZTogJ0Rlc2lnbicsIGljb246ICduYXZpZ2F0aW9uOmV4Y2hhbmdlJyB9XTtcbiAgICB0aGlzLl9wb2xpY3lGaWx0ZXIgPSBbXTtcbiAgICB0aGlzLl9mbG93RmlsdGVyID0gW107XG4gIH1cblxuICBzZXQgaGFzUHJvcGVydGllcyh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgaW1wb3J0KCcuLi9vcmdhbmlzbXMvZ3YtcHJvcGVydGllcycpLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLl90YWJzID0gWy4uLnRoaXMuX3RhYnMsIHsgaWQ6ICdwcm9wZXJ0aWVzJywgdGl0bGU6ICdQcm9wZXJ0aWVzJywgaWNvbjogJ2dlbmVyYWw6c2V0dGluZ3MjMScgfV07XG4gICAgICAgIHRoaXMucmVxdWVzdFVwZGF0ZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuX2hhc1Byb3BlcnRpZXMgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBoYXNQcm9wZXJ0aWVzKCkge1xuICAgIHJldHVybiB0aGlzLl9oYXNQcm9wZXJ0aWVzO1xuICB9XG5cbiAgc2V0IGhhc1Jlc291cmNlcyh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgaW1wb3J0KCcuLi9vcmdhbmlzbXMvZ3YtcmVzb3VyY2VzJykudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuX3RhYnMgPSBbLi4udGhpcy5fdGFicywgeyBpZDogJ3Jlc291cmNlcycsIHRpdGxlOiAnUmVzb3VyY2VzJywgaWNvbjogJ2dlbmVyYWw6c2V0dGluZ3MjNScgfV07XG4gICAgICAgIHRoaXMucmVxdWVzdFVwZGF0ZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc2V0IGNhbkRlYnVnKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLl90YWJzID0gWy4uLnRoaXMuX3RhYnMsIHsgaWQ6ICdkZWJ1ZycsIHRpdGxlOiAnVHJ5IGl0JywgaWNvbjogJ2NvbnRlbnQ6c2VuZCcgfV07XG4gICAgfVxuICB9XG5cbiAgZ2V0IF9mbG93RmlsdGVyT3B0aW9ucygpIHtcbiAgICBpZiAodGhpcy5kZWZpbmVkUGxhbnMubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAgeyBpZDogJ2FwaScsIHRpdGxlOiAnQXBpJywgaWNvbjogJ3Nob3BwaW5nOmJveCMzJyB9LFxuICAgICAgICB7IGlkOiAncGxhbicsIHRpdGxlOiAnUGxhbnMnLCBpY29uOiAnc2hvcHBpbmc6c2FsZSMyJyB9LFxuICAgICAgXTtcbiAgICB9XG4gIH1cblxuICBzZXQgaGFzUG9saWN5RmlsdGVyKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLl9wb2xpY3lGaWx0ZXJPcHRpb25zID0gW1xuICAgICAgICB7IGlkOiAnb25SZXF1ZXN0JywgdGl0bGU6ICdSZXF1ZXN0JywgaWNvbjogJ25hdmlnYXRpb246YXJyb3ctZnJvbS1sZWZ0JyB9LFxuICAgICAgICB7IGlkOiAnb25SZXNwb25zZScsIHRpdGxlOiAnUmVzcG9uc2UnLCBpY29uOiAnbmF2aWdhdGlvbjphcnJvdy1mcm9tLXJpZ2h0JyB9LFxuICAgICAgXTtcbiAgICB9XG4gIH1cblxuICBzZXQgY29uZmlndXJhdGlvblNjaGVtYSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5fdGFicy5zcGxpY2UoMSwgMCwgeyBpZDogJ3NldHRpbmdzJywgdGl0bGU6ICdDb25maWd1cmF0aW9uJywgaWNvbjogJ2dlbmVyYWw6c2V0dGluZ3MjMicgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fY29uZmlndXJhdGlvblNjaGVtYSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGNvbmZpZ3VyYXRpb25TY2hlbWEoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZ3VyYXRpb25TY2hlbWE7XG4gIH1cblxuICBvbktleWJvYXJkKCkge1xuICAgIGlmICh0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID09IG51bGwpIHtcbiAgICAgIGlmICh0aGlzLmlzUHJlc3NlZChLRVlTLlNoaWZ0LCBLRVlTLkN0cmwsIEtFWVMuU3BhY2UpKSB7XG4gICAgICAgIGNvbnN0IHNlYXJjaCA9IHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKCcjc2VhcmNoLXBvbGljeScpO1xuICAgICAgICBpZiAoc2VhcmNoKSB7XG4gICAgICAgICAgc2VhcmNoLmZvY3VzKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1ByZXNzZWQoS0VZUy5DdHJsLCBLRVlTLlNwYWNlKSkge1xuICAgICAgICBjb25zdCBzZWFyY2ggPSB0aGlzLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcignI3NlYXJjaC1mbG93Jyk7XG4gICAgICAgIGlmIChzZWFyY2gpIHtcbiAgICAgICAgICBzZWFyY2guZm9jdXMoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNldCB0YWJJZCh0YWJJZCkge1xuICAgIGlmICh0YWJJZCAhPSBudWxsICYmIFsnZGVzaWduJywgJ3NldHRpbmdzJywgJ3Byb3BlcnRpZXMnLCAncmVzb3VyY2VzJywgJ2RlYnVnJ10uaW5jbHVkZXModGFiSWQpKSB7XG4gICAgICB0aGlzLl90YWJJZCA9IHRhYklkO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl90YWJJZCA9ICdkZXNpZ24nO1xuICAgIH1cbiAgfVxuXG4gIGdldCB0YWJJZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdGFiSWQ7XG4gIH1cblxuICBzZXQgZGVmaW5pdGlvbihkZWZpbml0aW9uKSB7XG4gICAgaWYgKGRlZmluaXRpb24pIHtcbiAgICAgIGNvbnN0IGZsb3dzID0gdGhpcy5fZ2VuZXJhdGVGbG93c0lkKGRlZmluaXRpb24uZmxvd3MpO1xuICAgICAgY29uc3QgcmVzb3VyY2VzID0gdGhpcy5fZ2VuZXJhdGVJZCgncmVzb3VyY2UtJywgZGVmaW5pdGlvbi5yZXNvdXJjZXMpO1xuICAgICAgY29uc3QgcGxhbnMgPVxuICAgICAgICBkZWZpbml0aW9uLnBsYW5zID09IG51bGxcbiAgICAgICAgICA/IFtdXG4gICAgICAgICAgOiBkZWZpbml0aW9uLnBsYW5zLm1hcCgocGxhbikgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4geyAuLi5wbGFuLCBmbG93czogdGhpcy5fZ2VuZXJhdGVQbGFuRmxvd3NJZChwbGFuKSB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICB0aGlzLl9pbml0aWFsRGVmaW5pdGlvbiA9IHsgLi4uZGVmaW5pdGlvbiwgZmxvd3MsIHJlc291cmNlcywgcGxhbnMgfTtcbiAgICAgIHRoaXMuX2RlZmluaXRpb24gPSBkZWVwQ2xvbmUodGhpcy5faW5pdGlhbERlZmluaXRpb24pO1xuICAgICAgdGhpcy5pc0RpcnR5ID0gZmFsc2U7XG4gICAgICB0aGlzLl9zZWxlY3RGaXJzdEZsb3coKTtcbiAgICB9XG4gIH1cblxuICBnZXQgZGVmaW5pdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVmaW5pdGlvbjtcbiAgfVxuXG4gIHNldCBzZWxlY3RlZEZsb3dzSWQoc2VsZWN0ZWRGbG93c0lkKSB7XG4gICAgaWYgKHNlbGVjdGVkRmxvd3NJZCAhPSBudWxsICYmIEFycmF5LmlzQXJyYXkoc2VsZWN0ZWRGbG93c0lkKSkge1xuICAgICAgdGhpcy5fc2VsZWN0ZWRGbG93c0lkID0gc2VsZWN0ZWRGbG93c0lkLmZpbHRlcigoaWQpID0+IHRoaXMuX2ZpbmRGbG93QnlJZChpZCkgIT0gbnVsbCk7XG4gICAgICBpZiAoc2VsZWN0ZWRGbG93c0lkLmxlbmd0aCAhPT0gdGhpcy5fc2VsZWN0ZWRGbG93c0lkLmxlbmd0aCkge1xuICAgICAgICB0aGlzLl9zZWxlY3RGaXJzdEZsb3codHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IHNlbGVjdGVkRmxvd3NJZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRGbG93c0lkLmZpbHRlcigoaWQpID0+IHRoaXMuX2ZpbmRGbG93QnlJZChpZCkgIT0gbnVsbCk7XG4gIH1cblxuICBfdXBkYXRlU2VsZWN0ZWRGbG93cyhzZWxlY3RlZEZsb3dzSWQpIHtcbiAgICB0aGlzLnNlbGVjdGVkRmxvd3NJZCA9IHNlbGVjdGVkRmxvd3NJZDtcbiAgICBkaXNwYXRjaEN1c3RvbUV2ZW50KHRoaXMsICdzZWxlY3QtZmxvd3MnLCB7IGZsb3dzOiB0aGlzLnNlbGVjdGVkRmxvd3NJZCB9KTtcbiAgfVxuXG4gIF9zZWxlY3RGaXJzdEZsb3coZGlzcGF0Y2ggPSBmYWxzZSkge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkRmxvd3NJZC5sZW5ndGggPT09IDApIHtcbiAgICAgIGxldCBjYW5kaWRhdGUgPSBudWxsO1xuICAgICAgaWYgKHRoaXMuZGVmaW5lZEZsb3dzLmxlbmd0aCA+IDAgJiYgdGhpcy5kZWZpbmVkRmxvd3NbMF0uX2lkICE9IG51bGwpIHtcbiAgICAgICAgY2FuZGlkYXRlID0gdGhpcy5kZWZpbmVkRmxvd3NbMF07XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuZGVmaW5lZFBsYW5zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgcGxhbiA9IHRoaXMuZGVmaW5lZFBsYW5zLmZpbmQoKHBsYW4pID0+IHBsYW4uZmxvd3MgIT0gbnVsbCAmJiBwbGFuLmZsb3dzLmxlbmd0aCA+IDAgJiYgcGxhbi5mbG93c1swXS5faWQgIT0gbnVsbCk7XG4gICAgICAgIGlmIChwbGFuKSB7XG4gICAgICAgICAgY2FuZGlkYXRlID0gcGxhbi5mbG93c1swXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGNhbmRpZGF0ZSAhPSBudWxsKSB7XG4gICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdGVkRmxvd3MoW2NhbmRpZGF0ZS5faWRdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkRmxvd3NJZCA9IFtjYW5kaWRhdGUuX2lkXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9nZXRGbG93RWxlbWVudChmbG93SWQpIHtcbiAgICByZXR1cm4gdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoYFtpZD1cIiR7Zmxvd0lkfVwiXWApO1xuICB9XG5cbiAgX29uRHJhZ0VuZFBvbGljeSgpIHtcbiAgICB0aGlzLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvckFsbCgnZ3YtZmxvdycpLmZvckVhY2goKGUpID0+IGUub25EcmFnRW5kKCkpO1xuICB9XG5cbiAgYXN5bmMgX29uRHJvcFBvbGljeSh7IGRldGFpbCB9KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuX2Fza1RvVmFsaWRhdGVGb3JtcygpO1xuXG4gICAgICBjb25zdCBwb2xpY3kgPSBkZXRhaWwucG9saWN5O1xuICAgICAgY29uc3QgdGFyZ2V0RmxvdyA9IHRoaXMuX2ZpbmRGbG93QnlJZChkZXRhaWwuZmxvd0lkKTtcblxuICAgICAgbGV0IG5hbWUgPSBwb2xpY3kubmFtZTtcbiAgICAgIGxldCBkZXNjcmlwdGlvbiA9ICcnO1xuICAgICAgbGV0IGNvbmZpZ3VyYXRpb24gPSB7fTtcbiAgICAgIGxldCBfaWQ7XG4gICAgICBsZXQgX25ldyA9IGZhbHNlO1xuICAgICAgaWYgKGRldGFpbC5mbG93U3RlcCkge1xuICAgICAgICBfaWQgPSBkZXRhaWwuZmxvd1N0ZXAuX2lkO1xuICAgICAgICBuYW1lID0gZGV0YWlsLmZsb3dTdGVwLm5hbWU7XG4gICAgICAgIGRlc2NyaXB0aW9uID0gZGV0YWlsLmZsb3dTdGVwLmRlc2NyaXB0aW9uIHx8ICcnO1xuICAgICAgICBjb25maWd1cmF0aW9uID0gZGV0YWlsLmZsb3dTdGVwLmNvbmZpZ3VyYXRpb247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaWQgPSB0aGlzLl9nZW5lcmF0ZUZsb3dTdGVwSWQodGFyZ2V0Rmxvdy5faWQsIGRldGFpbC5mbG93S2V5LCBkZXRhaWwucG9zaXRpb24pO1xuICAgICAgICBfbmV3ID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmxvd1N0ZXAgPSB7IF9pZCwgX25ldywgbmFtZSwgcG9saWN5OiBwb2xpY3kuaWQsIGRlc2NyaXB0aW9uLCBlbmFibGVkOiB0cnVlLCBjb25maWd1cmF0aW9uIH07XG4gICAgICBjb25zdCBzb3VyY2VGbG93ID0gZGV0YWlsLnNvdXJjZUZsb3dJZCAhPSBudWxsID8gdGhpcy5fZmluZEZsb3dCeUlkKGRldGFpbC5zb3VyY2VGbG93SWQpIDogdGFyZ2V0RmxvdztcblxuICAgICAgaWYgKGRldGFpbC5zb3VyY2VQb3NpdGlvbiAhPSBudWxsKSB7XG4gICAgICAgIGlmIChkZXRhaWwuc291cmNlRmxvd0tleSAmJiBkZXRhaWwuc291cmNlRmxvd0tleSAhPT0gZGV0YWlsLmZsb3dLZXkpIHtcbiAgICAgICAgICBzb3VyY2VGbG93W2RldGFpbC5zb3VyY2VGbG93S2V5XS5zcGxpY2UoZGV0YWlsLnNvdXJjZVBvc2l0aW9uLCAxKTtcbiAgICAgICAgICB0YXJnZXRGbG93W2RldGFpbC5mbG93S2V5XS5zcGxpY2UoZGV0YWlsLnBvc2l0aW9uLCAwLCBmbG93U3RlcCk7XG4gICAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnRGbG93U3RlcCAhPSBudWxsICYmIHRoaXMuX2N1cnJlbnRGbG93U3RlcC5zdGVwLl9pZCA9PT0gX2lkKSB7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuZ3JvdXAgPSBkZXRhaWwuZmxvd0tleTtcbiAgICAgICAgICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgdXBkYXRlIHNjaGVtYSBhZnRlciBjaGFuZ2UgcmVxdWVzdCB0byByZXNwb25zZSBvciBpbnZlcnNlXG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB0aGlzLmJ1aWxkU2NoZW1hKHRoaXMuX2N1cnJlbnRGbG93U3RlcC5wb2xpY3kpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5fc2V0Q3VycmVudEZsb3dTdGVwKHRoaXMuX2N1cnJlbnRGbG93U3RlcCwgc2NoZW1hLCB0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuX2dldEZsb3dFbGVtZW50KHRhcmdldEZsb3cuX2lkKS5yZXF1ZXN0VXBkYXRlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChkZXRhaWwucG9zaXRpb24gPiBkZXRhaWwuc291cmNlUG9zaXRpb24pIHtcbiAgICAgICAgICAgIHRhcmdldEZsb3dbZGV0YWlsLmZsb3dLZXldLnNwbGljZShkZXRhaWwucG9zaXRpb24sIDAsIGZsb3dTdGVwKTtcbiAgICAgICAgICAgIHNvdXJjZUZsb3dbZGV0YWlsLmZsb3dLZXldLnNwbGljZShkZXRhaWwuc291cmNlUG9zaXRpb24sIDEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzb3VyY2VGbG93W2RldGFpbC5mbG93S2V5XS5zcGxpY2UoZGV0YWlsLnNvdXJjZVBvc2l0aW9uLCAxKTtcbiAgICAgICAgICAgIHRhcmdldEZsb3dbZGV0YWlsLmZsb3dLZXldLnNwbGljZShkZXRhaWwucG9zaXRpb24sIDAsIGZsb3dTdGVwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gRm9yY2UgUmVmcmVzaCBzb3VyY2UgZmxvdyBlbGVtZW50IHdoZW4gbW92ZSB0byBvdGhlciBmbG93XG4gICAgICAgIGlmICh0YXJnZXRGbG93Ll9pZCAhPT0gc291cmNlRmxvdy5faWQpIHtcbiAgICAgICAgICB0aGlzLl9nZXRGbG93RWxlbWVudCh0YXJnZXRGbG93Ll9pZCkucmVxdWVzdFVwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YXJnZXRGbG93W2RldGFpbC5mbG93S2V5XS5zcGxpY2UoZGV0YWlsLnBvc2l0aW9uLCAwLCBmbG93U3RlcCk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRGbG93Rm9ybSA9IHRoaXMuX2dldEZsb3dTdGVwRm9ybSgpO1xuICAgICAgICBpZiAoY3VycmVudEZsb3dGb3JtID09IG51bGwgfHwgY3VycmVudEZsb3dGb3JtLmRpcnR5ICE9PSB0cnVlKSB7XG4gICAgICAgICAgbGV0IHN0ZXAgPSB0YXJnZXRGbG93W2RldGFpbC5mbG93S2V5XVtkZXRhaWwucG9zaXRpb25dO1xuICAgICAgICAgIGlmIChzdGVwID09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFdoZW4gY29uZmlybSBsb3NlIGNoYW5nZSBhZnRlciBkcm9wIHBvbGljeVxuICAgICAgICAgICAgc3RlcCA9IHRhcmdldEZsb3dbZGV0YWlsLmZsb3dLZXldW2RldGFpbC5wb3NpdGlvbiAtIDFdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChkZXRhaWwuY2FuY2VsRWRpdCAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgc2V0VGltZW91dChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuX2VkaXRGbG93U3RlcCh7IHN0ZXAsIHBvbGljeSwgZmxvdzogdGFyZ2V0RmxvdywgZ3JvdXA6IGRldGFpbC5mbG93S2V5IH0pO1xuICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUNvbXBsZXRlLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZsb3dFbGVtZW50ID0gdGhpcy5fZ2V0Rmxvd0VsZW1lbnQodGFyZ2V0Rmxvdy5faWQpO1xuICAgICAgICAgICAgICAgIGZsb3dFbGVtZW50LnNlbGVjdGVkU3RlcElkID0gc3RlcC5faWQ7XG4gICAgICAgICAgICAgICAgZmxvd0VsZW1lbnQucmVxdWVzdFVwZGF0ZSgpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGFyZ2V0Rmxvdy5fZGlydHkgPSB0cnVlO1xuICAgICAgc291cmNlRmxvdy5fZGlydHkgPSB0cnVlO1xuICAgICAgdGhpcy5pc0RpcnR5ID0gdHJ1ZTtcbiAgICAgIHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yQWxsKCdndi1mbG93JykuZm9yRWFjaCgoZ3ZGbG93KSA9PiBndkZsb3cucmVtb3ZlQ2FuZGlkYXRlKCkpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuX2RyYWdQb2xpY3kgPSBudWxsO1xuICAgICAgICB0aGlzLl9kcm9wUG9saWN5ID0gbnVsbDtcbiAgICAgIH0sIDApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb24gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIF9vbkRlbGV0ZVBvbGljeSh7IGRldGFpbCB9KSB7XG4gICAgY29uc3QgdGFyZ2V0RmxvdyA9IHRoaXMuX2ZpbmRGbG93QnlJZChkZXRhaWwuZmxvd0lkKTtcbiAgICB0YXJnZXRGbG93W2RldGFpbC5mbG93S2V5XS5zcGxpY2UoZGV0YWlsLnBvc2l0aW9uLCAxKTtcbiAgICB0YXJnZXRGbG93Ll9kaXJ0eSA9IHRydWU7XG4gICAgdGhpcy5pc0RpcnR5ID0gdHJ1ZTtcbiAgICBpZiAoZGV0YWlsLnRhcmdldC5lZGl0aW5nKSB7XG4gICAgICB0aGlzLl9jbG9zZUZsb3dTdGVwRm9ybSh0cnVlKTtcbiAgICB9XG4gICAgdGhpcy5fZ2V0Rmxvd0VsZW1lbnQoZGV0YWlsLmZsb3dJZCkucmVxdWVzdFVwZGF0ZSgpO1xuICB9XG5cbiAgX29uRGVzaWduKCkge1xuICAgIHRoaXMuX2NoYW5nZVRhYignZGVzaWduJyk7XG4gICAgdGhpcy5fc3BsaXRNYWluVmlld3MoKTtcbiAgfVxuXG4gIGJ1aWxkU2NoZW1hKHsgc2NoZW1hIH0pIHtcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9IHtcbiAgICAgIHRpdGxlOiAnRGVzY3JpcHRpb24nLFxuICAgICAgZGVzY3JpcHRpb246ICdEZXNjcmlwdGlvbiBvZiBmbG93IHN0ZXAnLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfTtcbiAgICBpZiAoc2NoZW1hKSB7XG4gICAgICBjb25zdCBqc29uU2NoZW1hID0gdHlwZW9mIHNjaGVtYSA9PT0gJ3N0cmluZycgPyBKU09OLnBhcnNlKHNjaGVtYSkgOiBzY2hlbWE7XG4gICAgICBjb25zdCBwcm9wZXJ0aWVzID0geyBkZXNjcmlwdGlvbiwgLi4uanNvblNjaGVtYS5wcm9wZXJ0aWVzIH07XG4gICAgICByZXR1cm4geyAuLi5qc29uU2NoZW1hLCBwcm9wZXJ0aWVzIH07XG4gICAgfVxuICAgIHJldHVybiB7IHByb3BlcnRpZXM6IHsgZGVzY3JpcHRpb24gfSB9O1xuICB9XG5cbiAgYXN5bmMgX2VkaXRGbG93U3RlcCh7IHN0ZXAsIGZsb3csIHBvbGljeSwgZ3JvdXAgfSkge1xuICAgIGlmIChzdGVwKSB7XG4gICAgICB0aGlzLl9jdXJyZW50UG9saWN5SWQgPSBwb2xpY3kuaWQ7XG4gICAgICBjb25zdCBjdXJyZW50Rmxvd1N0ZXAgPSB7IGZsb3csIHN0ZXAsIHBvbGljeSwgZ3JvdXAgfTtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IHRoaXMuYnVpbGRTY2hlbWEocG9saWN5KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuX3NldEN1cnJlbnRGbG93U3RlcChjdXJyZW50Rmxvd1N0ZXAsIHNjaGVtYSk7XG4gICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdGVkRmxvd3MoW2Zsb3cuX2lkXSk7XG4gICAgICAgIHRoaXMuX3NwbGl0TWFpblZpZXdzKCk7XG4gICAgICAgIGlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnZ3YtcG9saWN5LXN0dWRpbzprZWVwLWRvY3VtZW50YXRpb24tY2xvc2UnKSA9PSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5fb25PcGVuRG9jdW1lbnRhdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb24gPSBudWxsO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCB0aGlzLl9jbG9zZUZsb3dTdGVwRm9ybSgpO1xuICAgICAgdGhpcy5fbWF4aW1pemVUb3BWaWV3KCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgX29uRWRpdEZsb3dTdGVwKHsgZGV0YWlsOiB7IHN0ZXAsIGZsb3csIHBvbGljeSwgZ3JvdXAgfSB9KSB7XG4gICAgcmV0dXJuIHRoaXMuX2VkaXRGbG93U3RlcCh7IHN0ZXAsIGZsb3csIHBvbGljeSwgZ3JvdXAgfSk7XG4gIH1cblxuICBfZ2V0UmVzaXphYmxlVmlld3MoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKCdndi1yZXNpemFibGUtdmlld3MnKTtcbiAgfVxuXG4gIF9tYXhpbWl6ZVRvcFZpZXcoKSB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRGbG93c0lkLmxlbmd0aCA8PSAxKSB7XG4gICAgICB0aGlzLl9nZXRSZXNpemFibGVWaWV3cygpLm1heGltaXplVG9wKCk7XG4gICAgfVxuICB9XG5cbiAgX21heGltaXplQm90dG9tVmlldygpIHtcbiAgICB0aGlzLl9nZXRSZXNpemFibGVWaWV3cygpLm1heGltaXplQm90dG9tKCk7XG4gIH1cblxuICBfc3BsaXRNYWluVmlld3MoKSB7XG4gICAgdGhpcy5fZ2V0UmVzaXphYmxlVmlld3MoKS5zcGxpdCgpO1xuICB9XG5cbiAgX29uQ2hhbmdlRmxvd1N0ZXBTdGF0ZSh7IGRldGFpbCB9KSB7XG4gICAgY29uc3QgdGFyZ2V0RmxvdyA9IHRoaXMuX2ZpbmRGbG93QnlJZChkZXRhaWwuZmxvd0lkKTtcbiAgICBjb25zdCBzdGVwID0gdGFyZ2V0Rmxvd1tkZXRhaWwuZmxvd0tleV1bZGV0YWlsLnBvc2l0aW9uXTtcbiAgICBzdGVwLmVuYWJsZWQgPSBkZXRhaWwuZW5hYmxlZDtcbiAgICB0YXJnZXRGbG93Ll9kaXJ0eSA9IHRydWU7XG4gICAgdGhpcy5pc0RpcnR5ID0gdHJ1ZTtcbiAgfVxuXG4gIGFzeW5jIF9vbkNsb3NlRmxvd1N0ZXBGb3JtKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLl9jbG9zZUZsb3dTdGVwRm9ybSgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgX2Nsb3NlRmxvd1N0ZXBGb3JtKGZvcmNlID0gZmFsc2UpIHtcbiAgICBhd2FpdCB0aGlzLl9zZXRDdXJyZW50Rmxvd1N0ZXAobnVsbCwgbnVsbCwgZm9yY2UpO1xuICB9XG5cbiAgYXN5bmMgX2Fza1RvVmFsaWRhdGVGb3JtcygpIHtcbiAgICBpZiAodGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9PSBudWxsKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID0gdHJ1ZTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbCh0aGlzLl9zdWJtaXRPckNvbmZpcm1Gb3JtcygpKS50aGVuKChmb3JtcykgPT4ge1xuICAgICAgICBpZiAoZm9ybXMuZmlsdGVyKChyKSA9PiByICE9IG51bGwpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aGlzLl9kZWZpbml0aW9uID0gdGhpcy5fYnVpbGREZWZpbml0aW9uVG9TYXZlKCk7XG4gICAgICAgICAgdGhpcy5nZXRDaGlsZHJlbigpLmZvckVhY2goKGUpID0+IGUucmVxdWVzdFVwZGF0ZSgpKTtcbiAgICAgICAgICAvLyBSZWZyZXNoIGlmIGxvc2UgY2hhbmdlcyBsb3N0IGN1cnJlbnQgc3RlcCBzZWxlY3Rpb25cbiAgICAgICAgICByZXR1cm4gdGhpcy5fY2hlY2tDdXJyZW50Rmxvd1N0ZXAoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ2V0Q2hpbGRyZW4oKS5mb3JFYWNoKChlKSA9PiBlLnJlcXVlc3RVcGRhdGUoKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy51cGRhdGVDb21wbGV0ZS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9IG51bGw7XG4gICAgICAgICAgICAgIHJldHVybiBmb3JtcztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb24gPSBudWxsO1xuICAgICAgICAgIHJldHVybiBmb3JtcztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcignYXNrIGFscmVhZHkgd2FpdGluZycpO1xuICB9XG5cbiAgYXN5bmMgX3NldEN1cnJlbnRGbG93U3RlcChjdXJyZW50Rmxvd1N0ZXAsIGZsb3dTdGVwU2NoZW1hLCBmb3JjZSA9IGZhbHNlKSB7XG4gICAgaWYgKCFmb3JjZSkge1xuICAgICAgYXdhaXQgdGhpcy5fYXNrVG9WYWxpZGF0ZUZvcm1zKCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2NoZW1hID0gZGVlcENsb25lKGZsb3dTdGVwU2NoZW1hKTtcbiAgICBpZiAoY3VycmVudEZsb3dTdGVwICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPVxuICAgICAgICB0eXBlb2YgY3VycmVudEZsb3dTdGVwLnN0ZXAuY29uZmlndXJhdGlvbiA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IEpTT04ucGFyc2UoY3VycmVudEZsb3dTdGVwLnN0ZXAuY29uZmlndXJhdGlvbilcbiAgICAgICAgICA6IGN1cnJlbnRGbG93U3RlcC5zdGVwLmNvbmZpZ3VyYXRpb247XG4gICAgICBjb25zdCBzdGVwID0geyAuLi5jdXJyZW50Rmxvd1N0ZXAuc3RlcCwgY29uZmlndXJhdGlvbiB9O1xuXG4gICAgICBjb25zdCBfaW5pdGlhbFZhbHVlcyA9IHsgLi4uc3RlcC5jb25maWd1cmF0aW9uLCBkZXNjcmlwdGlvbjogc3RlcC5kZXNjcmlwdGlvbiB9O1xuICAgICAgdGhpcy5fY3VycmVudEZsb3dTdGVwID0geyAuLi5jdXJyZW50Rmxvd1N0ZXAsIHN0ZXAsIF9pbml0aWFsVmFsdWVzIH07XG5cbiAgICAgIGlmIChmbG93U3RlcFNjaGVtYSAmJiBmbG93U3RlcFNjaGVtYS5wcm9wZXJ0aWVzLnNjb3BlKSB7XG4gICAgICAgIGNvbnN0IF9lbnVtID0gc2NoZW1hLnByb3BlcnRpZXMuc2NvcGUuZW51bTtcbiAgICAgICAgaWYgKF9lbnVtLmZpbmQoKHNjb3BlKSA9PiBbJ1JFUVVFU1QnLCAnUkVRVUVTVF9DT05URU5UJywgJ1JFU1BPTlNFJywgJ1JFU1BPTlNFX0NPTlRFTlQnXS5pbmNsdWRlcyhzY29wZSkpICE9IG51bGwpIHtcbiAgICAgICAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMuX2N1cnJlbnRGbG93U3RlcC5ncm91cCA9PT0gJ3ByZScgPyBbJ1JFUVVFU1QnLCAnUkVRVUVTVF9DT05URU5UJ10gOiBbJ1JFU1BPTlNFJywgJ1JFU1BPTlNFX0NPTlRFTlQnXTtcbiAgICAgICAgICBzY2hlbWEucHJvcGVydGllcy5zY29wZS5lbnVtID0gX2VudW0uZmlsdGVyKChzY29wZSkgPT4gZmlsdGVyZWQuaW5jbHVkZXMoc2NvcGUpKTtcbiAgICAgICAgICBjb25zdCBzY29wZSA9IHRoaXMuX2N1cnJlbnRGbG93U3RlcC5zdGVwLmNvbmZpZ3VyYXRpb24uc2NvcGU7XG4gICAgICAgICAgaWYgKHNjb3BlID09IG51bGwgfHwgIXNjaGVtYS5wcm9wZXJ0aWVzLnNjb3BlLmVudW0uaW5jbHVkZXMoc2NvcGUpKSB7XG4gICAgICAgICAgICBzY2hlbWEucHJvcGVydGllcy5zY29wZS5kZWZhdWx0ID0gc2NoZW1hLnByb3BlcnRpZXMuc2NvcGUuZW51bVswXTtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRGbG93U3RlcC5zdGVwLmNvbmZpZ3VyYXRpb24uc2NvcGUgPSBzY2hlbWEucHJvcGVydGllcy5zY29wZS5lbnVtWzBdO1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudEZsb3dTdGVwLl9pbml0aWFsVmFsdWVzLnNjb3BlID0gc2NoZW1hLnByb3BlcnRpZXMuc2NvcGUuZW51bVswXTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuX3ZhbHVlcykge1xuICAgICAgICAgICAgICB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuX3ZhbHVlcy5zY29wZSA9IHNjaGVtYS5wcm9wZXJ0aWVzLnNjb3BlLmVudW1bMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2N1cnJlbnRGbG93U3RlcCA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5fZmxvd1N0ZXBTY2hlbWEgPSBzY2hlbWE7XG4gIH1cblxuICBfcmVmcmVzaChjbG9zZVN0ZXBGb3JtID0gdHJ1ZSkge1xuICAgIGlmIChjbG9zZVN0ZXBGb3JtKSB7XG4gICAgICB0aGlzLl9jbG9zZUZsb3dTdGVwRm9ybSh0cnVlKTtcbiAgICB9XG4gICAgdGhpcy5fZGVmaW5pdGlvbiA9IGRlZXBDbG9uZSh0aGlzLl9kZWZpbml0aW9uKTtcbiAgfVxuXG4gIGFzeW5jIF9vblNlbGVjdEZsb3dzKHsgZGV0YWlsIH0pIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5fY2xvc2VGbG93U3RlcEZvcm0oKTtcbiAgICAgIHRoaXMuX29uQ2xvc2VEb2N1bWVudGF0aW9uKCk7XG4gICAgICB0aGlzLl91cGRhdGVTZWxlY3RlZEZsb3dzKGRldGFpbC5mbG93cyk7XG4gICAgICB0aGlzLl9vbkRlc2lnbigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb24gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9vbk9wZW5Eb2N1bWVudGF0aW9uRnJvbU1lbnUoeyBkZXRhaWw6IHsgcG9saWN5IH0gfSkge1xuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5kb2N1bWVudGF0aW9uID09IG51bGwgfHwgdGhpcy5kb2N1bWVudGF0aW9uLmlkICE9PSBwb2xpY3kuaWQpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5fY2xvc2VGbG93U3RlcEZvcm0oKTtcbiAgICAgICAgdGhpcy5fY3VycmVudFBvbGljeUlkID0gcG9saWN5LmlkO1xuICAgICAgICBpZiAodGhpcy5nZXRTZWxlY3RlZEZsb3coKSkge1xuICAgICAgICAgIHRoaXMuX3NwbGl0TWFpblZpZXdzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fbWF4aW1pemVCb3R0b21WaWV3KCk7XG4gICAgICAgIH1cbiAgICAgICAgZGlzcGF0Y2hDdXN0b21FdmVudCh0aGlzLCAnZmV0Y2gtZG9jdW1lbnRhdGlvbicsIHsgcG9saWN5IH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHt9XG4gIH1cblxuICBfZmV0Y2hEb2N1bWVudGF0aW9uKHBvbGljeSkge1xuICAgIGlmICh0aGlzLmRvY3VtZW50YXRpb24gPT0gbnVsbCB8fCB0aGlzLmRvY3VtZW50YXRpb24uaWQgIT09IHBvbGljeS5pZCkge1xuICAgICAgZGlzcGF0Y2hDdXN0b21FdmVudCh0aGlzLCAnZmV0Y2gtZG9jdW1lbnRhdGlvbicsIHsgcG9saWN5IH0pO1xuICAgIH1cbiAgfVxuXG4gIF9vbk9wZW5Eb2N1bWVudGF0aW9uKCkge1xuICAgIGlmICh0aGlzLl9jdXJyZW50Rmxvd1N0ZXAgJiYgdGhpcy5fY3VycmVudEZsb3dTdGVwLnBvbGljeSkge1xuICAgICAgdGhpcy5fZmV0Y2hEb2N1bWVudGF0aW9uKHRoaXMuX2N1cnJlbnRGbG93U3RlcC5wb2xpY3kpO1xuICAgIH1cbiAgfVxuXG4gIF9vbk9wZW5Eb2N1bWVudGF0aW9uRnJvbUZvcm0oKSB7XG4gICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oJ2d2LXBvbGljeS1zdHVkaW86a2VlcC1kb2N1bWVudGF0aW9uLWNsb3NlJyk7XG4gICAgdGhpcy5fb25PcGVuRG9jdW1lbnRhdGlvbigpO1xuICB9XG5cbiAgX2ZpbmRGbG93Q29sbGVjdGlvbihmbG93SWQpIHtcbiAgICBjb25zdCBwbGFuID0gdGhpcy5kZWZpbmVkUGxhbnMuZmluZCgocGxhbikgPT4gcGxhbi5mbG93cy5maW5kKChmbG93KSA9PiBmbG93Ll9pZCA9PT0gZmxvd0lkKSAhPSBudWxsKTtcbiAgICByZXR1cm4geyBwbGFuLCBmbG93czogcGxhbiAhPSBudWxsID8gcGxhbi5mbG93cyA6IHRoaXMuZGVmaW5lZEZsb3dzIH07XG4gIH1cblxuICBfZmluZEZsb3dCeUlkKGZsb3dJZCkge1xuICAgIGxldCBmbG93ID0gdGhpcy5kZWZpbmVkRmxvd3MuZmluZCgoZmxvdykgPT4gZmxvdy5faWQgPT09IGZsb3dJZCk7XG4gICAgaWYgKGZsb3cgPT0gbnVsbCkge1xuICAgICAgY29uc3QgcGxhbnNGbG93cyA9IHRoaXMuZGVmaW5lZFBsYW5zLm1hcCgocGxhbikgPT4gcGxhbi5mbG93cykucmVkdWNlKChhY2MsIHZhbCkgPT4gYWNjLmNvbmNhdCh2YWwpLCBbXSk7XG4gICAgICBmbG93ID0gcGxhbnNGbG93cy5maW5kKChmbG93KSA9PiBmbG93Ll9pZCA9PT0gZmxvd0lkKTtcbiAgICB9XG4gICAgcmV0dXJuIGZsb3c7XG4gIH1cblxuICBnZXRTZWxlY3RlZEZsb3coaW5kZXggPSAwKSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRGbG93SWQgPSB0aGlzLnNlbGVjdGVkRmxvd3NJZFtpbmRleF07XG4gICAgcmV0dXJuIHRoaXMuX2ZpbmRGbG93QnlJZChzZWxlY3RlZEZsb3dJZCk7XG4gIH1cblxuICBfb25UYXJnZXRQb2xpY3koeyBkZXRhaWwgfSkge1xuICAgIGlmICh0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID09IG51bGwpIHtcbiAgICAgIHRoaXMuX2RyYWdQb2xpY3kgPSBkZXRhaWw7XG4gICAgfVxuICB9XG5cbiAgX29uQ2hhbmdlRmxvd1N0ZXAoeyBkZXRhaWwgfSkge1xuICAgIHRoaXMuX2N1cnJlbnRGbG93U3RlcC5fdmFsdWVzID0gZGV0YWlsLnZhbHVlcztcbiAgfVxuXG4gIF93cml0ZUZsb3dTdGVwKHZhbHVlcykge1xuICAgIGNvbnN0IHsgZGVzY3JpcHRpb24sIC4uLmNvbmZpZ3VyYXRpb24gfSA9IHZhbHVlcztcbiAgICBpZiAoXG4gICAgICB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5fbmV3IHx8XG4gICAgICB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5kZXNjcmlwdGlvbiAhPT0gZGVzY3JpcHRpb24gfHxcbiAgICAgICFkZWVwRXF1YWwodGhpcy5fY3VycmVudEZsb3dTdGVwLnN0ZXAuY29uZmlndXJhdGlvbiwgY29uZmlndXJhdGlvbilcbiAgICApIHtcbiAgICAgIGNvbnN0IGZsb3cgPSB0aGlzLl9maW5kRmxvd0J5SWQodGhpcy5fY3VycmVudEZsb3dTdGVwLmZsb3cuX2lkKTtcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gZmxvd1t0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuZ3JvdXBdLmZpbmRJbmRleCgoc3RlcCkgPT4gc3RlcC5faWQgPT09IHRoaXMuX2N1cnJlbnRGbG93U3RlcC5zdGVwLl9pZCk7XG5cbiAgICAgIGZsb3dbdGhpcy5fY3VycmVudEZsb3dTdGVwLmdyb3VwXVtwb3NpdGlvbl0uZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjtcbiAgICAgIGZsb3dbdGhpcy5fY3VycmVudEZsb3dTdGVwLmdyb3VwXVtwb3NpdGlvbl0uY29uZmlndXJhdGlvbiA9IGRlZXBDbG9uZShjb25maWd1cmF0aW9uKTtcbiAgICAgIGRlbGV0ZSBmbG93W3RoaXMuX2N1cnJlbnRGbG93U3RlcC5ncm91cF1bcG9zaXRpb25dLl9uZXc7XG4gICAgICBmbG93W3RoaXMuX2N1cnJlbnRGbG93U3RlcC5ncm91cF1bcG9zaXRpb25dLl9kaXJ0eSA9IHRydWU7XG4gICAgICBmbG93Ll9kaXJ0eSA9IHRydWU7XG4gICAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgICAgdGhpcy5fY3VycmVudEZsb3dTdGVwLmZsb3cgPSBmbG93O1xuICAgICAgdGhpcy5fY3VycmVudEZsb3dTdGVwLnN0ZXAgPSBmbG93W3RoaXMuX2N1cnJlbnRGbG93U3RlcC5ncm91cF1bcG9zaXRpb25dO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9vblN1Ym1pdEZsb3dTdGVwKHsgZGV0YWlsIH0pIHtcbiAgICB0aGlzLl93cml0ZUZsb3dTdGVwKGRldGFpbC52YWx1ZXMpO1xuICAgIGF3YWl0IHRoaXMucmVxdWVzdFVwZGF0ZSgnX2RlZmluaXRpb24nKTtcbiAgICB0aGlzLmdldENoaWxkcmVuKCkuZm9yRWFjaCgoYykgPT4gYy5yZXF1ZXN0VXBkYXRlKCkpO1xuICB9XG5cbiAgX29uQ2FuY2VsRmxvdygpIHtcbiAgICB0aGlzLl9vbkRlc2lnbigpO1xuICB9XG5cbiAgX29uU3VibWl0Rmxvdyh7IGRldGFpbDogeyB2YWx1ZXMgfSB9KSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRGbG93ID0gdGhpcy5nZXRTZWxlY3RlZEZsb3coKTtcbiAgICBjb25zdCBfdmFsdWVzID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5fY3JlYXRlRmxvd0Zyb21TY2hlbWEoKSwgdmFsdWVzKTtcbiAgICBjb25zdCBzZWxlY3RlZEZsb3dVcGRhdGVkID0gT2JqZWN0LmFzc2lnbih7fSwgc2VsZWN0ZWRGbG93LCBfdmFsdWVzKTtcbiAgICBpZiAoIWRlZXBFcXVhbChzZWxlY3RlZEZsb3csIHNlbGVjdGVkRmxvd1VwZGF0ZWQpKSB7XG4gICAgICBPYmplY3QuYXNzaWduKHNlbGVjdGVkRmxvdywgc2VsZWN0ZWRGbG93VXBkYXRlZCwgeyBfZGlydHk6IHRydWUgfSk7XG4gICAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgICAgdGhpcy5fcmVmcmVzaCgpO1xuICAgIH1cbiAgfVxuXG4gIF9vbkNhbmNlbEZsb3dNb2RlKCkge1xuICAgIHRoaXMuX29uRGVzaWduKCk7XG4gIH1cblxuICBfb25TdWJtaXRGbG93TW9kZSh7IGRldGFpbDogeyB2YWx1ZXMgfSB9KSB7XG4gICAgdGhpcy5fZGVmaW5pdGlvblsnZmxvdy1tb2RlJ10gPSB2YWx1ZXNbJ2Zsb3ctbW9kZSddIHx8ICdERUZBVUxUJztcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgIHRoaXMuX3JlZnJlc2goKTtcbiAgfVxuXG4gIF9vbkNoYW5nZVRhYih7IGRldGFpbCB9KSB7XG4gICAgdGhpcy5fY2hhbmdlVGFiKGRldGFpbC52YWx1ZSk7XG4gIH1cblxuICBhc3luYyBfY2hhbmdlVGFiVmFsaWRhdG9yKHsgZnJvbSwgdG8gfSkge1xuICAgIGlmIChmcm9tID09PSAncHJvcGVydGllcycpIHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKCdndi1wcm9wZXJ0aWVzJyk7XG4gICAgICBpZiAoY29tcG9uZW50LmRpcnR5KSB7XG4gICAgICAgIHJldHVybiBjb21wb25lbnQuY29uZmlybSgpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZnJvbSA9PT0gJ3Jlc291cmNlcycpIHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKCdndi1yZXNvdXJjZXMnKTtcbiAgICAgIGlmIChjb21wb25lbnQuZGlydHkpIHtcbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudC5jb25maXJtKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9hc2tUb1ZhbGlkYXRlRm9ybXMoKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9IG51bGw7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIF9jaGFuZ2VUYWIodGFiSWQpIHtcbiAgICBpZiAodGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9PSBudWxsKSB7XG4gICAgICB0aGlzLnRhYklkID0gdGFiSWQ7XG4gICAgICBkaXNwYXRjaEN1c3RvbUV2ZW50KHRoaXMsICdjaGFuZ2UtdGFiJywgdGhpcy50YWJJZCk7XG4gICAgfVxuICB9XG5cbiAgX29uRHJhZ1N0YXJ0Rmxvd1N0ZXAoZmxvdywgeyBkZXRhaWwgfSkge1xuICAgIGlmICh0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID09IG51bGwpIHtcbiAgICAgIHRoaXMuX2Ryb3BQb2xpY3kgPSBkZXRhaWw7XG4gICAgICB0aGlzLl9kcmFnUG9saWN5ID0gZGV0YWlsO1xuICAgIH1cbiAgfVxuXG4gIF9yZW5kZXJGbG93RW1wdHlTdGF0ZShyZWFkb25seU1vZGUpIHtcbiAgICByZXR1cm4gaHRtbGA8ZGl2IHNsb3Q9XCJjb250ZW50XCIgY2xhc3M9XCJlbXB0eVwiPlxuICAgICAgPGRpdj5cbiAgICAgICAgU2VsZWN0IGEgZmxvd1xuICAgICAgICAke3JlYWRvbmx5TW9kZSAhPT0gdHJ1ZVxuICAgICAgICAgID8gaHRtbGBvciA8Z3YtYnV0dG9uIEBndi1idXR0b246Y2xpY2s9XCIke3RoaXMuX29uQWRkRmxvd31cIiBvdXRsaW5lZCBpY29uPVwiY29kZTpwbHVzXCIgbGFyZ2U+ZGVzaWduIG5ldyBvbmU8L2d2LWJ1dHRvbj5gXG4gICAgICAgICAgOiAnJ31cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PmA7XG4gIH1cblxuICBfcmVuZGVyRmxvdyhpbmRleCA9IDAsIGhhc0VtcHR5U3RhdGUgPSB0cnVlLCByZWFkb25seU1vZGUpIHtcbiAgICBjb25zdCBmbG93ID0gdGhpcy5nZXRTZWxlY3RlZEZsb3coaW5kZXgpO1xuICAgIGlmIChmbG93KSB7XG4gICAgICBjb25zdCB7IHBsYW4gfSA9IHRoaXMuX2ZpbmRGbG93Q29sbGVjdGlvbihmbG93Ll9pZCk7XG4gICAgICBjb25zdCBzZWxlY3RlZFN0ZXBJZCA9IHRoaXMuX2N1cnJlbnRGbG93U3RlcCA/IHRoaXMuX2N1cnJlbnRGbG93U3RlcC5zdGVwLl9pZCA6IG51bGw7XG4gICAgICByZXR1cm4gaHRtbGAgPGd2LWZsb3dcbiAgICAgICAgc3R5bGU9XCJoZWlnaHQ6IDEwMCVcIlxuICAgICAgICAuaWQ9XCIke2Zsb3cuX2lkfVwiXG4gICAgICAgIC5mbG93PVwiJHtmbG93fVwiXG4gICAgICAgIC5wbGFuPVwiJHtwbGFufVwiXG4gICAgICAgIC5wb2xpY2llcz1cIiR7dGhpcy5wb2xpY2llc31cIlxuICAgICAgICBzbG90PVwiY29udGVudFwiXG4gICAgICAgID9kaXNhYmxlZD1cIiR7dGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbn1cIlxuICAgICAgICAuZHJhZ1BvbGljeT1cIiR7dGhpcy5fZHJhZ1BvbGljeX1cIlxuICAgICAgICAuZHJvcFBvbGljeT1cIiR7dGhpcy5fZHJvcFBvbGljeX1cIlxuICAgICAgICAuc2VsZWN0ZWRTdGVwSWQ9XCIke3NlbGVjdGVkU3RlcElkfVwiXG4gICAgICAgID9yZWFkb25seT1cIiR7cmVhZG9ubHlNb2RlfVwiXG4gICAgICAgID9oYXMtcG9saWN5LWZpbHRlcj1cIiR7dGhpcy5fcG9saWN5RmlsdGVyT3B0aW9ucyAhPSBudWxsfVwiXG4gICAgICAgIGZsb3dzLXRpdGxlPVwiJHt0aGlzLmZsb3dzVGl0bGV9XCJcbiAgICAgICAgQGd2LWZsb3c6ZHJhZy1zdGFydD1cIiR7dGhpcy5fb25EcmFnU3RhcnRGbG93U3RlcC5iaW5kKHRoaXMsIGZsb3cpfVwiXG4gICAgICAgIEBndi1mbG93OmVkaXQ9XCIke3RoaXMuX29uRWRpdEZsb3dTdGVwfVwiXG4gICAgICAgIEBndi1mbG93OmNoYW5nZS1zdGF0ZT1cIiR7dGhpcy5fb25DaGFuZ2VGbG93U3RlcFN0YXRlfVwiXG4gICAgICAgIEBndi1mbG93OmRyb3A9XCIke3RoaXMuX29uRHJvcFBvbGljeX1cIlxuICAgICAgICBAZ3YtZmxvdzpkZWxldGU9XCIke3RoaXMuX29uRGVsZXRlUG9saWN5fVwiXG4gICAgICA+PC9ndi1mbG93PmA7XG4gICAgfSBlbHNlIGlmIChoYXNFbXB0eVN0YXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fcmVuZGVyRmxvd0VtcHR5U3RhdGUocmVhZG9ubHlNb2RlKTtcbiAgICB9XG4gICAgcmV0dXJuIGh0bWxgYDtcbiAgfVxuXG4gIF9vbkZldGNoUmVzb3VyY2VzKGV2ZW50KSB7XG4gICAgY29uc3QgeyBjdXJyZW50VGFyZ2V0LCByZWdleFR5cGVzIH0gPSBldmVudC5kZXRhaWw7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZGVmaW5lZFJlc291cmNlc1xuICAgICAgLmZpbHRlcigocmVzb3VyY2UpID0+IHJlZ2V4VHlwZXMgPT0gbnVsbCB8fCBuZXcgUmVnRXhwKHJlZ2V4VHlwZXMpLnRlc3QocmVzb3VyY2UudHlwZSkpXG4gICAgICAubWFwKChyZXNvdXJjZSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VUeXBlID0gdGhpcy5yZXNvdXJjZVR5cGVzLmZpbmQoKHR5cGUpID0+IHR5cGUuaWQgPT09IHJlc291cmNlLnR5cGUpO1xuICAgICAgICBjb25zdCByb3cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdndi1yb3cnKTtcbiAgICAgICAgY29uc3QgcGljdHVyZSA9IHJlc291cmNlVHlwZS5pY29uID8gcmVzb3VyY2VUeXBlLmljb24gOiBudWxsO1xuICAgICAgICByb3cuaXRlbSA9IHsgcGljdHVyZSwgbmFtZTogcmVzb3VyY2UubmFtZSB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVsZW1lbnQ6IHJvdyxcbiAgICAgICAgICB2YWx1ZTogcmVzb3VyY2UubmFtZSxcbiAgICAgICAgICBpZDogcmVzb3VyY2UudHlwZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIGN1cnJlbnRUYXJnZXQub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICBfcmVuZGVyUG9saWN5KHJlYWRvbmx5TW9kZSkge1xuICAgIGlmICh0aGlzLl9mbG93U3RlcFNjaGVtYSAmJiB0aGlzLmRvY3VtZW50YXRpb24pIHtcbiAgICAgIHJldHVybiBodG1sYDxndi1yZXNpemFibGUtdmlld3MgZGlyZWN0aW9uPVwiaG9yaXpvbnRhbFwiIG5vLW92ZXJmbG93PlxuICAgICAgICA8ZGl2IHNsb3Q9XCJ0b3BcIj4ke3RoaXMuX3JlbmRlckZsb3dTdGVwRm9ybShyZWFkb25seU1vZGUpfTwvZGl2PlxuICAgICAgICA8ZGl2IHNsb3Q9XCJib3R0b21cIj5cbiAgICAgICAgICA8Z3YtZG9jdW1lbnRhdGlvblxuICAgICAgICAgICAgLnRleHQ9XCIke3RoaXMuZG9jdW1lbnRhdGlvbi5jb250ZW50fVwiXG4gICAgICAgICAgICAuaW1hZ2U9XCIke3RoaXMuZG9jdW1lbnRhdGlvbi5pbWFnZX1cIlxuICAgICAgICAgICAgP2Rpc2FibGVkPVwiJHt0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9ufVwiXG4gICAgICAgICAgICBAZ3YtZG9jdW1lbnRhdGlvbjpjbG9zZT1cIiR7dGhpcy5fb25DbG9zZURvY3VtZW50YXRpb259XCJcbiAgICAgICAgICA+PC9ndi1kb2N1bWVudGF0aW9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZ3YtcmVzaXphYmxlLXZpZXdzPmA7XG4gICAgfSBlbHNlIGlmICh0aGlzLmRvY3VtZW50YXRpb24pIHtcbiAgICAgIHJldHVybiBodG1sYDxndi1kb2N1bWVudGF0aW9uXG4gICAgICAgIC50ZXh0PVwiJHt0aGlzLmRvY3VtZW50YXRpb24uY29udGVudH1cIlxuICAgICAgICAuaW1hZ2U9XCIke3RoaXMuZG9jdW1lbnRhdGlvbi5pbWFnZX1cIlxuICAgICAgICA/ZGlzYWJsZWQ9XCIke3RoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb259XCJcbiAgICAgICAgQGd2LWRvY3VtZW50YXRpb246Y2xvc2U9XCIke3RoaXMuX29uQ2xvc2VEb2N1bWVudGF0aW9ufVwiXG4gICAgICA+PC9ndi1kb2N1bWVudGF0aW9uPmA7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9mbG93U3RlcFNjaGVtYSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3JlbmRlckZsb3dTdGVwRm9ybShyZWFkb25seU1vZGUpO1xuICAgIH1cbiAgICByZXR1cm4gaHRtbGBgO1xuICB9XG5cbiAgX2dldEZsb3dTdGVwRm9ybSgpIHtcbiAgICByZXR1cm4gdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoYCMke0ZMT1dfU1RFUF9GT1JNX0lEfWApO1xuICB9XG5cbiAgX29uUmVzZXRGbG93U3RlcCgpIHtcbiAgICBpZiAodGhpcy5fY3VycmVudEZsb3dTdGVwKSB7XG4gICAgICBkZWxldGUgdGhpcy5fY3VycmVudEZsb3dTdGVwLl92YWx1ZXM7XG4gICAgICB0aGlzLl9nZXRGbG93U3RlcEZvcm0oKS5yZXNldCgpO1xuICAgIH1cbiAgfVxuXG4gIF9nZW5lcmF0ZUZsb3dzSWQobGlzdCwgZm9yY2UgPSBmYWxzZSkge1xuICAgIHJldHVybiB0aGlzLl9nZW5lcmF0ZUlkKCdmJywgbGlzdCwgZm9yY2UsIHRydWUpO1xuICB9XG5cbiAgX2dlbmVyYXRlUGxhbkZsb3dzSWQocGxhbiwgZm9yY2UgPSBmYWxzZSkge1xuICAgIHJldHVybiB0aGlzLl9nZW5lcmF0ZUlkKHBsYW4uaWQsIHBsYW4uZmxvd3MsIGZvcmNlLCB0cnVlKTtcbiAgfVxuXG4gIF9nZW5lcmF0ZUZsb3dTdGVwSWQoZmxvd0lkLCBmbG93S2V5LCBwb3NpdGlvbikge1xuICAgIHJldHVybiBgJHtmbG93SWR9XyR7Zmxvd0tleX1fJHtwb3NpdGlvbn1gO1xuICB9XG5cbiAgX2dlbmVyYXRlSWQocHJlZml4LCBsaXN0LCBmb3JjZSA9IGZhbHNlLCBpc0Zsb3cgPSBmYWxzZSkge1xuICAgIGlmIChsaXN0KSB7XG4gICAgICByZXR1cm4gbGlzdC5tYXAoKGUsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IF9pZCA9IGAke3ByZWZpeH1fJHtpbmRleH1gO1xuICAgICAgICBpZiAoaXNGbG93KSB7XG4gICAgICAgICAgaWYgKGUucHJlKSB7XG4gICAgICAgICAgICBlLnByZS5mb3JFYWNoKChzdGVwLCBzdGVwSW5kZXgpID0+IChzdGVwLl9pZCA9IHRoaXMuX2dlbmVyYXRlRmxvd1N0ZXBJZChfaWQsICdwcmUnLCBzdGVwSW5kZXgpKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChlLnBvc3QpIHtcbiAgICAgICAgICAgIGUucG9zdC5mb3JFYWNoKChzdGVwLCBzdGVwSW5kZXgpID0+IChzdGVwLl9pZCA9IHRoaXMuX2dlbmVyYXRlRmxvd1N0ZXBJZChfaWQsICdwb3N0Jywgc3RlcEluZGV4KSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZm9yY2UgfHwgZS5faWQgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiB7IC4uLmUsIF9pZCB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBsaXN0O1xuICB9XG5cbiAgZ2V0Q2hpbGRyZW4oKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLkFycmF5LmZyb20odGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ2d2LWZsb3cnKSksXG4gICAgICAuLi5BcnJheS5mcm9tKHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yQWxsKCdndi1yZXNpemFibGUtdmlld3MnKSksXG4gICAgXTtcbiAgfVxuXG4gIGFzeW5jIGdldFVwZGF0ZUNvbXBsZXRlKCkge1xuICAgIGF3YWl0IHN1cGVyLmdldFVwZGF0ZUNvbXBsZXRlKCk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwodGhpcy5nZXRDaGlsZHJlbigpLm1hcCgoZSkgPT4gZS51cGRhdGVDb21wbGV0ZSkpO1xuICB9XG5cbiAgc2hvdWxkVXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzKSB7XG4gICAgLy8gSnVzdCByZWZyZXNoIGd2LWZsb3cgY29tcG9uZW50c1xuICAgIGlmIChjaGFuZ2VkUHJvcGVydGllcy5oYXMoJ19kcmFnUG9saWN5JykpIHtcbiAgICAgIHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yQWxsKCdndi1mbG93JykuZm9yRWFjaCgoZmxvdykgPT4gKGZsb3cuZHJhZ1BvbGljeSA9IHRoaXMuX2RyYWdQb2xpY3kpKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzLmhhcygnX2Ryb3BQb2xpY3knKSkge1xuICAgICAgdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ2d2LWZsb3cnKS5mb3JFYWNoKChmbG93KSA9PiAoZmxvdy5kcm9wUG9saWN5ID0gdGhpcy5fZHJvcFBvbGljeSkpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gc3VwZXIuc2hvdWxkVXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzKTtcbiAgfVxuXG4gIHVwZGF0ZWQocHJvcHMpIHtcbiAgICBpZiAocHJvcHMuaGFzKCdkb2N1bWVudGF0aW9uJykgJiYgdGhpcy5kb2N1bWVudGF0aW9uICE9IG51bGwgJiYgdGhpcy5zZWxlY3RlZEZsb3dzSWQubGVuZ3RoID4gMSkge1xuICAgICAgdGhpcy5fdXBkYXRlU2VsZWN0ZWRGbG93cyhbdGhpcy5zZWxlY3RlZEZsb3dzSWRbMF1dKTtcbiAgICB9XG4gIH1cblxuICBfcmVuZGVyRmxvd1N0ZXBGb3JtKHJlYWRvbmx5TW9kZSkge1xuICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuX2N1cnJlbnRGbG93U3RlcC5fdmFsdWVzIHx8IHRoaXMuX2N1cnJlbnRGbG93U3RlcC5faW5pdGlhbFZhbHVlcztcbiAgICByZXR1cm4gaHRtbGAke2NhY2hlKFxuICAgICAgdGhpcy5fZmxvd1N0ZXBTY2hlbWEgJiYgdGhpcy5fY3VycmVudEZsb3dTdGVwXG4gICAgICAgID8gaHRtbGA8ZGl2IGNsYXNzPVwiZmxvdy1zdGVwX19jb250YWluZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbG93LXN0ZXBfX2Zvcm1cIj5cbiAgICAgICAgICAgICAgPGd2LXNjaGVtYS1mb3JtXG4gICAgICAgICAgICAgICAgLmlkPVwiJHtGTE9XX1NURVBfRk9STV9JRH1cIlxuICAgICAgICAgICAgICAgIC5zY2hlbWE9XCIke3RoaXMuX2Zsb3dTdGVwU2NoZW1hfVwiXG4gICAgICAgICAgICAgICAgLmljb249XCJkZXNpZ246ZWRpdFwiXG4gICAgICAgICAgICAgICAgaGFzLWhlYWRlclxuICAgICAgICAgICAgICAgIHZhbGlkYXRlLW9uLXJlbmRlclxuICAgICAgICAgICAgICAgIC52YWx1ZXM9XCIke3ZhbHVlc31cIlxuICAgICAgICAgICAgICAgIC5kaXJ0eT1cIiR7dGhpcy5fY3VycmVudEZsb3dTdGVwLl92YWx1ZXMgIT0gbnVsbH1cIlxuICAgICAgICAgICAgICAgID9yZWFkb25seT1cIiR7cmVhZG9ubHlNb2RlfVwiXG4gICAgICAgICAgICAgICAgc2Nyb2xsYWJsZVxuICAgICAgICAgICAgICAgIEBndi1zY2hlbWEtZm9ybTpjaGFuZ2U9XCIke3RoaXMuX29uQ2hhbmdlRmxvd1N0ZXB9XCJcbiAgICAgICAgICAgICAgICBAZ3Ytc2NoZW1hLWZvcm06cmVzZXQ9XCIke3RoaXMuX29uUmVzZXRGbG93U3RlcH1cIlxuICAgICAgICAgICAgICAgIEBndi1zY2hlbWEtZm9ybTpmZXRjaC1yZXNvdXJjZXM9XCIke3RoaXMuX29uRmV0Y2hSZXNvdXJjZXN9XCJcbiAgICAgICAgICAgICAgICBAZ3Ytc2NoZW1hLWZvcm06c3VibWl0PVwiJHt0aGlzLl9vblN1Ym1pdEZsb3dTdGVwfVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8ZGl2IHNsb3Q9XCJ0aXRsZVwiIGNsYXNzPVwiZmxvdy1zdGVwX19mb3JtLXRpdGxlXCI+JHt0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5uYW1lfTwvZGl2PlxuICAgICAgICAgICAgICAgIDxndi1idXR0b25cbiAgICAgICAgICAgICAgICAgIHNsb3Q9XCJoZWFkZXItbGVmdFwiXG4gICAgICAgICAgICAgICAgICBpY29uPVwiZ2VuZXJhbDpjbG9zZVwiXG4gICAgICAgICAgICAgICAgICBvdXRsaW5lZFxuICAgICAgICAgICAgICAgICAgc21hbGxcbiAgICAgICAgICAgICAgICAgIEBndi1idXR0b246Y2xpY2s9XCIke3RoaXMuX29uQ2xvc2VGbG93U3RlcEZvcm19XCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQ2xvc2VcIlxuICAgICAgICAgICAgICAgID48L2d2LWJ1dHRvbj5cbiAgICAgICAgICAgICAgICA8Z3YtYnV0dG9uXG4gICAgICAgICAgICAgICAgICBzbG90PVwiaGVhZGVyLWxlZnRcIlxuICAgICAgICAgICAgICAgICAgaWNvbj1cImhvbWU6Ym9va1wiXG4gICAgICAgICAgICAgICAgICA/ZGlzYWJsZWQ9XCIke3RoaXMuZG9jdW1lbnRhdGlvbiAhPSBudWxsfVwiXG4gICAgICAgICAgICAgICAgICBvdXRsaW5lZFxuICAgICAgICAgICAgICAgICAgc21hbGxcbiAgICAgICAgICAgICAgICAgIEBndi1idXR0b246Y2xpY2s9XCIke3RoaXMuX29uT3BlbkRvY3VtZW50YXRpb25Gcm9tRm9ybX1cIlxuICAgICAgICAgICAgICAgICAgdGl0bGU9XCJPcGVuIGRvY3VtZW50YXRpb25cIlxuICAgICAgICAgICAgICAgID48L2d2LWJ1dHRvbj5cbiAgICAgICAgICAgICAgPC9ndi1zY2hlbWEtZm9ybT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PmBcbiAgICAgICAgOiAnJyxcbiAgICApfWA7XG4gIH1cblxuICBfb25DbG9zZURvY3VtZW50YXRpb24oKSB7XG4gICAgdGhpcy5kb2N1bWVudGF0aW9uID0gbnVsbDtcbiAgICBpZiAodGhpcy5fY3VycmVudEZsb3dTdGVwID09IG51bGwpIHtcbiAgICAgIHRoaXMuX21heGltaXplVG9wVmlldygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnZ3YtcG9saWN5LXN0dWRpbzprZWVwLWRvY3VtZW50YXRpb24tY2xvc2UnLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBfb25EZWxldGVGbG93KHsgZGV0YWlsIH0pIHtcbiAgICBjb25zdCBmbG93SWQgPSBkZXRhaWwuY29udGVudC5faWQ7XG4gICAgY29uc3QgeyBmbG93cyB9ID0gdGhpcy5fZmluZEZsb3dDb2xsZWN0aW9uKGZsb3dJZCk7XG4gICAgY29uc3QgZmxvdyA9IGZsb3dzLmZpbmQoKGZsb3cpID0+IGZsb3cuX2lkID09PSBmbG93SWQpO1xuICAgIHRoaXMuX2RlbGV0ZUZsb3coZmxvd3MsIGZsb3cpO1xuICB9XG5cbiAgZ2V0IGRlZmluZWRGbG93cygpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVmaW5pdGlvbiAmJiB0aGlzLl9kZWZpbml0aW9uLmZsb3dzID8gdGhpcy5fZGVmaW5pdGlvbi5mbG93cyA6IFtdO1xuICB9XG5cbiAgZ2V0IGRlZmluZWRQbGFucygpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVmaW5pdGlvbiAmJiB0aGlzLl9kZWZpbml0aW9uLnBsYW5zID8gdGhpcy5fZGVmaW5pdGlvbi5wbGFucyA6IFtdO1xuICB9XG5cbiAgZ2V0IGRlZmluZWRSZXNvdXJjZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZmluaXRpb24gJiYgdGhpcy5fZGVmaW5pdGlvbi5yZXNvdXJjZXMgPyB0aGlzLl9kZWZpbml0aW9uLnJlc291cmNlcyA6IFtdO1xuICB9XG5cbiAgZ2V0IGRlZmluZWRQcm9wZXJ0aWVzKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWZpbml0aW9uICYmIHRoaXMuX2RlZmluaXRpb24ucHJvcGVydGllcyA/IHRoaXMuX2RlZmluaXRpb24ucHJvcGVydGllcyA6IFtdO1xuICB9XG5cbiAgYXN5bmMgX29uRHVwbGljYXRlRmxvdyh7IGRldGFpbCB9KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuX2Fza1RvVmFsaWRhdGVGb3JtcygpO1xuXG4gICAgICBjb25zdCBmbG93SWQgPSBkZXRhaWwuY29udGVudC5faWQ7XG4gICAgICBjb25zdCB7IHBsYW4sIGZsb3dzIH0gPSB0aGlzLl9maW5kRmxvd0NvbGxlY3Rpb24oZmxvd0lkKTtcbiAgICAgIHRoaXMuX2FkZEZsb3coZmxvd3MsIHRoaXMuX2ZpbmRGbG93QnlJZChmbG93SWQpKTtcbiAgICAgIGlmIChwbGFuICE9IG51bGwpIHtcbiAgICAgICAgbGV0IHBsYW5JbmRleCA9IG51bGw7XG4gICAgICAgIHRoaXMuZGVmaW5lZFBsYW5zLmZpbmQoKHAsIGkpID0+IHtcbiAgICAgICAgICBpZiAocC5pZCA9PT0gcGxhbi5pZCkge1xuICAgICAgICAgICAgcGxhbkluZGV4ID0gaTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgICAgICBwbGFuLmZsb3dzID0gZmxvd3M7XG4gICAgICAgIHRoaXMuZGVmaW5lZFBsYW5zW3BsYW5JbmRleF0uZmxvd3MgPSB0aGlzLl9nZW5lcmF0ZVBsYW5GbG93c0lkKHBsYW4sIHRydWUpO1xuICAgICAgICB0aGlzLl91cGRhdGVTZWxlY3RlZEZsb3dzKFt0aGlzLmRlZmluZWRQbGFuc1twbGFuSW5kZXhdLmZsb3dzW2Zsb3dzLmxlbmd0aCAtIDFdLl9pZF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fZGVmaW5pdGlvbi5mbG93cyA9IHRoaXMuX2dlbmVyYXRlRmxvd3NJZCh0aGlzLl9kZWZpbml0aW9uLmZsb3dzKTtcbiAgICAgICAgdGhpcy5fdXBkYXRlU2VsZWN0ZWRGbG93cyhbdGhpcy5fZGVmaW5pdGlvbi5mbG93c1t0aGlzLl9kZWZpbml0aW9uLmZsb3dzLmxlbmd0aCAtIDFdLl9pZF0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgX29uQ2hhbmdlRmxvd1N0YXRlKHsgZGV0YWlsIH0pIHtcbiAgICBjb25zdCBmbG93ID0gdGhpcy5fZmluZEZsb3dCeUlkKGRldGFpbC5jb250ZW50Ll9pZCk7XG4gICAgZmxvdy5lbmFibGVkID0gZGV0YWlsLmVuYWJsZWQ7XG4gICAgZmxvdy5fZGlydHkgPSB0cnVlO1xuICAgIHRoaXMuaXNEaXJ0eSA9IHRydWU7XG4gIH1cblxuICBhc3luYyBfb25BZGRGbG93UGxhbih7IGRldGFpbCB9KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuX2Fza1RvVmFsaWRhdGVGb3JtcygpO1xuICAgICAgdGhpcy5fYWRkRmxvdyh0aGlzLmRlZmluZWRQbGFuc1tkZXRhaWwucGxhbkluZGV4XS5mbG93cyk7XG4gICAgICB0aGlzLmRlZmluZWRQbGFuc1tkZXRhaWwucGxhbkluZGV4XS5mbG93cyA9IHRoaXMuX2dlbmVyYXRlUGxhbkZsb3dzSWQodGhpcy5kZWZpbmVkUGxhbnNbZGV0YWlsLnBsYW5JbmRleF0pO1xuICAgICAgdGhpcy5fdXBkYXRlU2VsZWN0ZWRGbG93cyhbdGhpcy5kZWZpbmVkUGxhbnNbZGV0YWlsLnBsYW5JbmRleF0uZmxvd3NbdGhpcy5kZWZpbmVkUGxhbnNbZGV0YWlsLnBsYW5JbmRleF0uZmxvd3MubGVuZ3RoIC0gMV0uX2lkXSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBfb25BZGRGbG93KCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLl9hc2tUb1ZhbGlkYXRlRm9ybXMoKTtcblxuICAgICAgdGhpcy5fYWRkRmxvdyh0aGlzLl9kZWZpbml0aW9uLmZsb3dzKTtcbiAgICAgIHRoaXMuX2RlZmluaXRpb24uZmxvd3MgPSB0aGlzLl9nZW5lcmF0ZUZsb3dzSWQodGhpcy5fZGVmaW5pdGlvbi5mbG93cyk7XG4gICAgICB0aGlzLl91cGRhdGVTZWxlY3RlZEZsb3dzKFt0aGlzLl9kZWZpbml0aW9uLmZsb3dzW3RoaXMuX2RlZmluaXRpb24uZmxvd3MubGVuZ3RoIC0gMV0uX2lkXSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBfYWRkRmxvdyhjb2xsZWN0aW9uLCBkdXBsaWNhdGUgPSBudWxsKSB7XG4gICAgY29uc3QgZmxvdyA9XG4gICAgICBkdXBsaWNhdGUgPT0gbnVsbFxuICAgICAgICA/IHRoaXMuX2NyZWF0ZUZsb3dGcm9tU2NoZW1hKClcbiAgICAgICAgOiB7XG4gICAgICAgICAgICAuLi5kdXBsaWNhdGUsXG4gICAgICAgICAgICBfaWQ6IG51bGwsXG4gICAgICAgICAgICAvLyByZXNldCB0aGUgaWQgdG8gYXZvaWQgaXNzdWUgd2l0aCBBTSB0aGF0IHBlcnNpc3RzIHRoZSBJRFxuICAgICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgICAgICBfZGlydHk6IHRydWUsXG4gICAgICAgICAgfTtcblxuICAgIGNvbGxlY3Rpb24ucHVzaChmbG93KTtcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICB9XG5cbiAgX2NyZWF0ZUZsb3dGcm9tU2NoZW1hKCkge1xuICAgIGNvbnN0IG5ld0Zsb3cgPSB7XG4gICAgICBuYW1lOiAnJyxcbiAgICAgIHByZTogW10sXG4gICAgICBwb3N0OiBbXSxcbiAgICAgIF9kaXJ0eTogdHJ1ZSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMuX2luc3RhbnRpYXRlKHRoaXMuZmxvd1NjaGVtYS5wcm9wZXJ0aWVzLCBuZXdGbG93KTtcbiAgfVxuXG4gIF9pbnN0YW50aWF0ZShwcm9wZXJ0aWVzRGVmaW5pdGlvbiwgaW5pdGlhdG9yID0ge30pIHtcbiAgICBjb25zdCBwcm9wZXJ0eSA9IHsgLi4uaW5pdGlhdG9yIH07XG5cbiAgICBpZiAocHJvcGVydGllc0RlZmluaXRpb24pIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHByb3BlcnRpZXNEZWZpbml0aW9uKSkge1xuICAgICAgICBjb25zdCBlbnRyeSA9IHByb3BlcnRpZXNEZWZpbml0aW9uW2tleV07XG5cbiAgICAgICAgaWYgKGVudHJ5LnR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgcHJvcGVydHlba2V5XSA9IHRoaXMuX2luc3RhbnRpYXRlKGVudHJ5LnByb3BlcnRpZXMsIChpbml0aWF0b3IgPSB7fSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbnRyeS5kZWZhdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBwcm9wZXJ0eVtrZXldID0gZW50cnkuZGVmYXVsdDtcbiAgICAgICAgfSBlbHNlIGlmIChlbnRyeS50eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHByb3BlcnR5W2tleV0gPSAnJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwcm9wZXJ0eTtcbiAgfVxuXG4gIF9kZWxldGVGbG93KGNvbGxlY3Rpb24sIGZsb3cpIHtcbiAgICBjb25zdCBpbmRleCA9IGNvbGxlY3Rpb24uaW5kZXhPZihmbG93KTtcbiAgICBjb2xsZWN0aW9uLnNwbGljZShpbmRleCwgMSk7XG4gICAgY29uc3Qgc2VsZWN0ZWRGbG93cyA9IHRoaXMuc2VsZWN0ZWRGbG93c0lkLmZpbHRlcigoZmxvd0lkKSA9PiBmbG93SWQgIT09IGZsb3cuX2lkKTtcbiAgICBpZiAoc2VsZWN0ZWRGbG93cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdGVkRmxvd3Moc2VsZWN0ZWRGbG93cyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3NlbGVjdEZpcnN0Rmxvdyh0cnVlKTtcbiAgICB9XG4gICAgdGhpcy5fY2hhbmdlVGFiKCdkZXNpZ24nKTtcbiAgICB0aGlzLl9yZWZyZXNoKCk7XG4gICAgdGhpcy5pc0RpcnR5ID0gdHJ1ZTtcbiAgfVxuXG4gIF9maW5kRmxvd0luZGV4KGxpc3QsIGlkKSB7XG4gICAgbGV0IGluZGV4ID0gbnVsbDtcbiAgICBsaXN0LmZpbmQoKGYsIGkpID0+IHtcbiAgICAgIGlmIChmLl9pZCA9PT0gaWQpIHtcbiAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9KTtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBhc3luYyBfb25SZW9yZGVyRmxvd3MoeyBkZXRhaWw6IHsgcGxhbiB9IH0pIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5fYXNrVG9WYWxpZGF0ZUZvcm1zKCk7XG4gICAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgICAgaWYgKHBsYW4gIT0gbnVsbCkge1xuICAgICAgICBjb25zdCBuZXdPcmRlciA9IHRoaXMuX2dlbmVyYXRlUGxhbkZsb3dzSWQocGxhbiwgdHJ1ZSk7XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkRmxvd3NJZCkge1xuICAgICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdGVkRmxvd3MoXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkRmxvd3NJZC5tYXAoKGZsb3dJZCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX2ZpbmRGbG93SW5kZXgocGxhbi5mbG93cywgZmxvd0lkKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGluZGV4ICE9IG51bGwgPyBuZXdPcmRlcltpbmRleF0uX2lkIDogZmxvd0lkO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBwbGFuLmZsb3dzID0gbmV3T3JkZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBuZXdPcmRlciA9IHRoaXMuX2dlbmVyYXRlRmxvd3NJZCh0aGlzLl9kZWZpbml0aW9uLmZsb3dzLCB0cnVlKTtcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRGbG93c0lkKSB7XG4gICAgICAgICAgdGhpcy5fdXBkYXRlU2VsZWN0ZWRGbG93cyhcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGbG93c0lkLm1hcCgoZmxvd0lkKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fZmluZEZsb3dJbmRleCh0aGlzLl9kZWZpbml0aW9uLmZsb3dzLCBmbG93SWQpO1xuICAgICAgICAgICAgICByZXR1cm4gaW5kZXggIT0gbnVsbCA/IG5ld09yZGVyW2luZGV4XS5faWQgOiBmbG93SWQ7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2RlZmluaXRpb24uZmxvd3MgPSBuZXdPcmRlcjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb24gPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBfb25TZWFyY2hQb2xpY3koeyBkZXRhaWwgfSkge1xuICAgIHRoaXMuX3NlYXJjaFBvbGljeVF1ZXJ5ID0gZGV0YWlsO1xuICB9XG5cbiAgX29uQ2xlYXJQb2xpY3koKSB7XG4gICAgdGhpcy5fc2VhcmNoUG9saWN5UXVlcnkgPSBudWxsO1xuICB9XG5cbiAgX29uU2VhcmNoRmxvd3MoeyBkZXRhaWwgfSkge1xuICAgIHRoaXMuX3NlYXJjaEZsb3dRdWVyeSA9IGRldGFpbDtcbiAgfVxuXG4gIF9vbkNsZWFyRmxvd3MoKSB7XG4gICAgdGhpcy5fc2VhcmNoRmxvd1F1ZXJ5ID0gbnVsbDtcbiAgfVxuXG4gIGFzeW5jIF9vblJlc2V0QWxsKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLl9jbG9zZUZsb3dTdGVwRm9ybSgpO1xuICAgICAgdGhpcy5kZWZpbml0aW9uID0gZGVlcENsb25lKHRoaXMuX2luaXRpYWxEZWZpbml0aW9uKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBfZmlsdGVyTm90VmFsaWRTdGVwKHN0ZXApIHtcbiAgICByZXR1cm4gc3RlcC5fbmV3ICE9PSB0cnVlO1xuICB9XG5cbiAgX3JlbW92ZVByaXZhdGVQcm9wZXJ0aWVzKG8pIHtcbiAgICBjb25zdCBjb3B5ID0geyAuLi5vIH07XG4gICAgT2JqZWN0LmtleXMobylcbiAgICAgIC5maWx0ZXIoKGtleSkgPT4ga2V5LnN0YXJ0c1dpdGgoJ18nKSlcbiAgICAgIC5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgZGVsZXRlIGNvcHlba2V5XTtcbiAgICAgIH0pO1xuICAgIHJldHVybiBjb3B5O1xuICB9XG5cbiAgX3N1Ym1pdE9yQ29uZmlybUZvcm1zKCkge1xuICAgIHJldHVybiBbLi4udGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ2d2LXNjaGVtYS1mb3JtJyldXG4gICAgICAuZmlsdGVyKChmb3JtKSA9PiB7XG4gICAgICAgIGNvbnN0IGlzVmFsaWQgPSBmb3JtLmlzVmFsaWQoKTtcbiAgICAgICAgaWYgKGlzVmFsaWQpIHtcbiAgICAgICAgICBmb3JtLnN1Ym1pdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZvcm0uZGlydHkgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhaXNWYWxpZDtcbiAgICAgIH0pXG4gICAgICAubWFwKChmb3JtKSA9PiBmb3JtLmNvbmZpcm0oKSk7XG4gIH1cblxuICBnZXRQcm9wZXJ0aWVzRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoJ2d2LXByb3BlcnRpZXMnKTtcbiAgfVxuXG4gIGFzeW5jIF9jaGVja0N1cnJlbnRGbG93U3RlcCgpIHtcbiAgICBpZiAodGhpcy5fY3VycmVudEZsb3dTdGVwICYmIHRoaXMuc2VsZWN0ZWRGbG93c0lkKSB7XG4gICAgICBjb25zdCBjbG9zZVByb21pc2VzID0gdGhpcy5zZWxlY3RlZEZsb3dzSWRcbiAgICAgICAgLm1hcCgoZmxvd0lkKSA9PiB7XG4gICAgICAgICAgY29uc3QgZmxvdyA9IHRoaXMuX2ZpbmRGbG93QnlJZChmbG93SWQpO1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRTdGVwID0gWy4uLmZsb3cucHJlLCAuLi5mbG93LnBvc3RdLmZpbmQoKHN0ZXApID0+IHN0ZXAuX2lkID09PSB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5faWQpO1xuICAgICAgICAgIGlmIChjdXJyZW50U3RlcCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2VGbG93U3RlcEZvcm0odHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9KVxuICAgICAgICAuZmlsdGVyKChwKSA9PiBwICE9PSBudWxsKTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChjbG9zZVByb21pc2VzKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgc2F2ZWQoKSB7XG4gICAgaWYgKHRoaXMuaXNEaXJ0eSkge1xuICAgICAgdGhpcy5faW5pdGlhbERlZmluaXRpb24gPSBkZWVwQ2xvbmUodGhpcy5fZGVmaW5pdGlvblNhdmVkKTtcbiAgICAgIHRoaXMuX2RlZmluaXRpb24gPSBkZWVwQ2xvbmUodGhpcy5fZGVmaW5pdGlvblNhdmVkKTtcbiAgICAgIHRoaXMuX2RlZmluaXRpb25TYXZlZCA9IG51bGw7XG4gICAgICB0aGlzLmlzRGlydHkgPSBmYWxzZTtcbiAgICAgIHRoaXMuX2NoZWNrQ3VycmVudEZsb3dTdGVwKCk7XG4gICAgICB0aGlzLmRlZmluZWRQbGFucy5mb3JFYWNoKChwbGFuKSA9PiB7XG4gICAgICAgIHBsYW4uZmxvd3MuZm9yRWFjaCgoZmxvdykgPT4gKGZsb3cuX2RpcnR5ID0gZmFsc2UpKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kZWZpbmVkRmxvd3MuZm9yRWFjaCgoZmxvdykgPT4gKGZsb3cuX2RpcnR5ID0gZmFsc2UpKTtcbiAgICAgIHRoaXMuZ2V0Q2hpbGRyZW4oKS5mb3JFYWNoKChlKSA9PiBlLnJlcXVlc3RVcGRhdGUoKSk7XG4gICAgfVxuICB9XG5cbiAgX2J1aWxkRGVmaW5pdGlvblRvU2F2ZSgpIHtcbiAgICAvLyBDb3B5IGRlZmluaXRpb24gYW5kIHJlbW92ZSBpbnZhbGlkIHN0ZXBcbiAgICAvLyBLZWVwIHByaXZhdGUgcHJvcGVydGllcyBsaWtlIF9pZCBhbmQgb3RoZXJzIHN0dWZmIHVzZWZ1bCBmb3IgcmVuZGVyXG4gICAgY29uc3QgZmxvd3MgPSB0aGlzLl9kZWZpbml0aW9uLmZsb3dzLm1hcCgoZmxvdykgPT4ge1xuICAgICAgZmxvdy5wcmUgPSBmbG93LnByZS5maWx0ZXIodGhpcy5fZmlsdGVyTm90VmFsaWRTdGVwKTtcbiAgICAgIGZsb3cucG9zdCA9IGZsb3cucG9zdC5maWx0ZXIodGhpcy5fZmlsdGVyTm90VmFsaWRTdGVwKTtcbiAgICAgIHJldHVybiBmbG93O1xuICAgIH0pO1xuXG4gICAgbGV0IGRlZmluaXRpb24gPSB7IC4uLnRoaXMuX2RlZmluaXRpb24sIGZsb3dzIH07XG5cbiAgICBpZiAodGhpcy5fZGVmaW5pdGlvbi5wbGFucyAhPSBudWxsKSB7XG4gICAgICBjb25zdCBwbGFucyA9IHRoaXMuX2RlZmluaXRpb24ucGxhbnMubWFwKChwbGFuKSA9PiB7XG4gICAgICAgIGNvbnN0IGZsb3dzID0gcGxhbi5mbG93cy5tYXAoKGZsb3cpID0+IHtcbiAgICAgICAgICBmbG93LnByZSA9IGZsb3cucHJlLmZpbHRlcih0aGlzLl9maWx0ZXJOb3RWYWxpZFN0ZXApO1xuICAgICAgICAgIGZsb3cucG9zdCA9IGZsb3cucG9zdC5maWx0ZXIodGhpcy5fZmlsdGVyTm90VmFsaWRTdGVwKTtcbiAgICAgICAgICByZXR1cm4gZmxvdztcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7IC4uLnBsYW4sIGZsb3dzIH07XG4gICAgICB9KTtcbiAgICAgIGRlZmluaXRpb24gPSB7IC4uLmRlZmluaXRpb24sIHBsYW5zIH07XG4gICAgfVxuICAgIHJldHVybiBkZWZpbml0aW9uO1xuICB9XG5cbiAgX2J1aWxkRGVmaW5pdGlvblRvU2VuZChkZWZpbml0aW9uVG9TYXZlKSB7XG4gICAgLy8gQ29weSBkZWZpbml0aW9uIGFuZCByZW1vdmUgYWxsIHByaXZhdGUgcHJvcGVydGllc1xuICAgIGNvbnN0IGZsb3dzID0gZGVmaW5pdGlvblRvU2F2ZS5mbG93cy5tYXAoKGYpID0+IHtcbiAgICAgIGNvbnN0IGZsb3cgPSB0aGlzLl9yZW1vdmVQcml2YXRlUHJvcGVydGllcyhmKTtcbiAgICAgIGZsb3cucHJlID0gZmxvdy5wcmUubWFwKHRoaXMuX3JlbW92ZVByaXZhdGVQcm9wZXJ0aWVzKTtcbiAgICAgIGZsb3cucG9zdCA9IGZsb3cucG9zdC5tYXAodGhpcy5fcmVtb3ZlUHJpdmF0ZVByb3BlcnRpZXMpO1xuICAgICAgcmV0dXJuIGZsb3c7XG4gICAgfSk7XG5cbiAgICBsZXQgZGVmaW5pdGlvbiA9IHsgLi4udGhpcy5fZGVmaW5pdGlvbiwgZmxvd3MgfTtcbiAgICBpZiAodGhpcy5fZGVmaW5pdGlvbi5wbGFucyAhPSBudWxsKSB7XG4gICAgICBjb25zdCBwbGFucyA9IGRlZmluaXRpb25Ub1NhdmUucGxhbnMubWFwKChwbGFuKSA9PiB7XG4gICAgICAgIGNvbnN0IGZsb3dzID0gcGxhbi5mbG93cy5tYXAoKGYpID0+IHtcbiAgICAgICAgICBjb25zdCBmbG93ID0gdGhpcy5fcmVtb3ZlUHJpdmF0ZVByb3BlcnRpZXMoZik7XG4gICAgICAgICAgZmxvdy5wcmUgPSBmbG93LnByZS5tYXAodGhpcy5fcmVtb3ZlUHJpdmF0ZVByb3BlcnRpZXMpO1xuICAgICAgICAgIGZsb3cucG9zdCA9IGZsb3cucG9zdC5tYXAodGhpcy5fcmVtb3ZlUHJpdmF0ZVByb3BlcnRpZXMpO1xuICAgICAgICAgIHJldHVybiBmbG93O1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHsgLi4ucGxhbiwgZmxvd3MgfTtcbiAgICAgIH0pO1xuICAgICAgZGVmaW5pdGlvbiA9IHsgLi4uZGVmaW5pdGlvbiwgcGxhbnMgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZGVmaW5pdGlvbi5wcm9wZXJ0aWVzICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSB0aGlzLl9kZWZpbml0aW9uLnByb3BlcnRpZXMubWFwKHRoaXMuX3JlbW92ZVByaXZhdGVQcm9wZXJ0aWVzKTtcbiAgICAgIGRlZmluaXRpb24gPSB7IC4uLmRlZmluaXRpb24sIHByb3BlcnRpZXMgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZGVmaW5pdGlvbi5yZXNvdXJjZXMgIT0gbnVsbCkge1xuICAgICAgY29uc3QgcmVzb3VyY2VzID0gdGhpcy5fZGVmaW5pdGlvbi5yZXNvdXJjZXMubWFwKHRoaXMuX3JlbW92ZVByaXZhdGVQcm9wZXJ0aWVzKTtcbiAgICAgIGRlZmluaXRpb24gPSB7IC4uLmRlZmluaXRpb24sIHJlc291cmNlcyB9O1xuICAgIH1cblxuICAgIHJldHVybiBkZWZpbml0aW9uO1xuICB9XG5cbiAgX29uU2F2ZUFsbCgpIHtcbiAgICBpZiAodGhpcy5oYXNQcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmdldFByb3BlcnRpZXNFbGVtZW50KCkuc3VibWl0KCk7XG4gICAgfVxuXG4gICAgUHJvbWlzZS5hbGwodGhpcy5fc3VibWl0T3JDb25maXJtRm9ybXMoKSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5fZGVmaW5pdGlvblNhdmVkID0gdGhpcy5fYnVpbGREZWZpbml0aW9uVG9TYXZlKCk7XG4gICAgICAgIGNvbnN0IGRlZmluaXRpb24gPSB0aGlzLl9idWlsZERlZmluaXRpb25Ub1NlbmQodGhpcy5fZGVmaW5pdGlvblNhdmVkKTtcbiAgICAgICAgZGlzcGF0Y2hDdXN0b21FdmVudCh0aGlzLCAnc2F2ZScsIHsgZGVmaW5pdGlvbiwgc2VydmljZXM6IHRoaXMuc2VydmljZXMgfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgW3BvbGljeS1zdHVkaW9dIEVycm9yIG9uIHNhdmVgLCBlcnIpO1xuICAgICAgfSk7XG4gIH1cblxuICBfb25EZWJ1ZyhyZXF1ZXN0RXZlbnQpIHtcbiAgICBpZiAodGhpcy5oYXNQcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmdldFByb3BlcnRpZXNFbGVtZW50KCkuc3VibWl0KCk7XG4gICAgfVxuXG4gICAgUHJvbWlzZS5hbGwodGhpcy5fc3VibWl0T3JDb25maXJtRm9ybXMoKSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgY29uc3QgZGVmaW5pdGlvbiA9IHRoaXMuX2J1aWxkRGVmaW5pdGlvblRvU2VuZCh0aGlzLl9idWlsZERlZmluaXRpb25Ub1NhdmUoKSk7XG4gICAgICAgIGRpc3BhdGNoQ3VzdG9tRXZlbnQodGhpcywgJ2RlYnVnJywgeyBkZWZpbml0aW9uLCBzZXJ2aWNlczogdGhpcy5zZXJ2aWNlcywgcmVxdWVzdDogcmVxdWVzdEV2ZW50LmRldGFpbC5yZXF1ZXN0IH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFtwb2xpY3ktc3R1ZGlvXSBFcnJvciBvbiBkZWJ1Z2AsIGVycik7XG4gICAgICB9KTtcbiAgfVxuXG4gIGdldCBmaWx0ZXJlZEZsb3dzKCkge1xuICAgIGlmICh0aGlzLl9mbG93RmlsdGVyLmxlbmd0aCA9PT0gMCB8fCB0aGlzLl9mbG93RmlsdGVyLmluY2x1ZGVzKCdhcGknKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVmaW5lZEZsb3dzO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGdldCBmaWx0ZXJlZFBsYW5zKCkge1xuICAgIGlmICh0aGlzLl9mbG93RmlsdGVyLmxlbmd0aCA9PT0gMCB8fCB0aGlzLl9mbG93RmlsdGVyLmluY2x1ZGVzKCdwbGFuJykpIHtcbiAgICAgIHJldHVybiB0aGlzLmRlZmluZWRQbGFucztcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBfb25GaWx0ZXJGbG93cyh7IGRldGFpbCB9KSB7XG4gICAgaWYgKHRoaXMuX2Zsb3dGaWx0ZXIuaW5jbHVkZXMoZGV0YWlsLmlkKSkge1xuICAgICAgdGhpcy5fZmxvd0ZpbHRlciA9IFtdO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9mbG93RmlsdGVyID0gW2RldGFpbC5pZF07XG4gICAgfVxuICB9XG5cbiAgX2dldEZpbHRlcmVkUG9saWNpZXMoKSB7XG4gICAgaWYgKHRoaXMuX3BvbGljeUZpbHRlci5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb2xpY2llcy5maWx0ZXIoKHBvbGljeSkgPT4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIChwb2xpY3kub25SZXF1ZXN0ICYmIHRoaXMuX3BvbGljeUZpbHRlci5pbmNsdWRlcygnb25SZXF1ZXN0JykpIHx8IChwb2xpY3kub25SZXNwb25zZSAmJiB0aGlzLl9wb2xpY3lGaWx0ZXIuaW5jbHVkZXMoJ29uUmVzcG9uc2UnKSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wb2xpY2llcztcbiAgfVxuXG4gIF9vbkZpbHRlclBvbGljaWVzKHsgZGV0YWlsIH0pIHtcbiAgICBpZiAodGhpcy5fcG9saWN5RmlsdGVyLmluY2x1ZGVzKGRldGFpbC5pZCkpIHtcbiAgICAgIHRoaXMuX3BvbGljeUZpbHRlciA9IFtdO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9wb2xpY3lGaWx0ZXIgPSBbZGV0YWlsLmlkXTtcbiAgICB9XG4gIH1cblxuICBfcmVuZGVyRGVzaWduKHJlYWRvbmx5TW9kZSkge1xuICAgIHJldHVybiBodG1sYCA8ZGl2IGlkPVwiZGVzaWduXCIgc2xvdD1cImNvbnRlbnRcIiBjbGFzcz1cImRlc2lnblwiPlxuICAgICAgPGd2LXJlc2l6YWJsZS12aWV3cyBuby1vdmVyZmxvdz5cbiAgICAgICAgPGRpdiBzbG90PVwidG9wXCI+JHt0aGlzLl9yZW5kZXJGbG93KDAsIHRydWUsIHJlYWRvbmx5TW9kZSl9PC9kaXY+XG5cbiAgICAgICAgPGRpdiBzbG90PVwiYm90dG9tXCI+XG4gICAgICAgICAgJHt0aGlzLl9yZW5kZXJGbG93KDEsIGZhbHNlLCByZWFkb25seU1vZGUpfSAke3RoaXMuX3JlbmRlclBvbGljeShyZWFkb25seU1vZGUpfSAke3RoaXMuX3JlbmRlckZsb3dGb3JtKHJlYWRvbmx5TW9kZSl9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9ndi1yZXNpemFibGUtdmlld3M+XG4gICAgICAke3JlYWRvbmx5TW9kZSAhPT0gdHJ1ZVxuICAgICAgICA/IGh0bWxgPGd2LXBvbGljeS1zdHVkaW8tbWVudVxuICAgICAgICAgICAgY2xhc3M9XCJyaWdodC1tZW51XCJcbiAgICAgICAgICAgID9kaXNhYmxlZD1cIiR7dGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbn1cIlxuICAgICAgICAgICAgLnBvbGljaWVzPVwiJHt0aGlzLl9nZXRGaWx0ZXJlZFBvbGljaWVzKCl9XCJcbiAgICAgICAgICAgIC5zZWxlY3RlZElkcz1cIiR7W3RoaXMuX2N1cnJlbnRQb2xpY3lJZF19XCJcbiAgICAgICAgICAgIC5xdWVyeT1cIiR7dGhpcy5fc2VhcmNoUG9saWN5UXVlcnl9XCJcbiAgICAgICAgICAgID9oYXMtcG9saWN5LWZpbHRlcj1cIiR7dGhpcy5fcG9saWN5RmlsdGVyT3B0aW9ucyAhPSBudWxsfVwiXG4gICAgICAgICAgICA/cmVhZG9ubHk9XCIke3JlYWRvbmx5TW9kZX1cIlxuICAgICAgICAgICAgQGd2LXBvbGljeS1zdHVkaW8tbWVudTp0YXJnZXQtcG9saWN5PVwiJHt0aGlzLl9vblRhcmdldFBvbGljeX1cIlxuICAgICAgICAgICAgQGd2LXBvbGljeS1zdHVkaW8tbWVudTpmZXRjaC1kb2N1bWVudGF0aW9uPVwiJHt0aGlzLl9vbk9wZW5Eb2N1bWVudGF0aW9uRnJvbU1lbnV9XCJcbiAgICAgICAgICAgIEBndi1wb2xpY3ktc3R1ZGlvLW1lbnU6ZHJhZ2VuZC1wb2xpY3k9XCIke3RoaXMuX29uRHJhZ0VuZFBvbGljeX1cIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxkaXYgc2xvdD1cImhlYWRlclwiIGNsYXNzPVwic2VhcmNoLXBvbGljaWVzXCI+XG4gICAgICAgICAgICAgICR7dGhpcy5fcG9saWN5RmlsdGVyT3B0aW9ucyAhPSBudWxsXG4gICAgICAgICAgICAgICAgPyBodG1sYDxndi1vcHRpb25cbiAgICAgICAgICAgICAgICAgICAgP2Rpc2FibGVkPVwiJHt0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9ufVwiXG4gICAgICAgICAgICAgICAgICAgIC5vcHRpb25zPVwiJHt0aGlzLl9wb2xpY3lGaWx0ZXJPcHRpb25zfVwiXG4gICAgICAgICAgICAgICAgICAgIG11bHRpcGxlXG4gICAgICAgICAgICAgICAgICAgIG91dGxpbmVkXG4gICAgICAgICAgICAgICAgICAgIC52YWx1ZT1cIiR7dGhpcy5fcG9saWN5RmlsdGVyfVwiXG4gICAgICAgICAgICAgICAgICAgIHNtYWxsXG4gICAgICAgICAgICAgICAgICAgIEBndi1vcHRpb246c2VsZWN0PVwiJHt0aGlzLl9vbkZpbHRlclBvbGljaWVzfVwiXG4gICAgICAgICAgICAgICAgICA+PC9ndi1vcHRpb24+YFxuICAgICAgICAgICAgICAgIDogJyd9XG4gICAgICAgICAgICAgIDxndi1pbnB1dFxuICAgICAgICAgICAgICAgIGlkPVwic2VhcmNoLXBvbGljeVwiXG4gICAgICAgICAgICAgICAgP2Rpc2FibGVkPVwiJHt0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9ufVwiXG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJGaWx0ZXIgcG9saWNpZXMgKFNoaWZ0ICsgQ3RybCArIFNwYWNlKVwiXG4gICAgICAgICAgICAgICAgdHlwZT1cInNlYXJjaFwiXG4gICAgICAgICAgICAgICAgc21hbGxcbiAgICAgICAgICAgICAgICBAZ3YtaW5wdXQ6aW5wdXQ9XCIke3RoaXMuX29uU2VhcmNoUG9saWN5fVwiXG4gICAgICAgICAgICAgICAgQGd2LWlucHV0OmNsZWFyPVwiJHt0aGlzLl9vbkNsZWFyUG9saWN5fVwiXG4gICAgICAgICAgICAgID48L2d2LWlucHV0PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9ndi1wb2xpY3ktc3R1ZGlvLW1lbnU+YFxuICAgICAgICA6ICcnfVxuICAgIDwvZGl2PmA7XG4gIH1cblxuICBfcmVuZGVyRGVidWcoKSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLmRlYnVnUmVzcG9uc2UgPyB0aGlzLmRlYnVnUmVzcG9uc2UucmVzcG9uc2UgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgaXNMb2FkaW5nID0gdGhpcy5kZWJ1Z1Jlc3BvbnNlID8gdGhpcy5kZWJ1Z1Jlc3BvbnNlLmlzTG9hZGluZyA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBwYXRoID0gdGhpcy5kZWJ1Z1Jlc3BvbnNlICYmIHRoaXMuZGVidWdSZXNwb25zZS5yZXF1ZXN0ID8gdGhpcy5kZWJ1Z1Jlc3BvbnNlLnJlcXVlc3QucGF0aCA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBtZXRob2QgPSB0aGlzLmRlYnVnUmVzcG9uc2UgJiYgdGhpcy5kZWJ1Z1Jlc3BvbnNlLnJlcXVlc3QgPyB0aGlzLmRlYnVnUmVzcG9uc2UucmVxdWVzdC5tZXRob2QgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIGh0bWxgPGd2LWh0dHAtY2xpZW50XG4gICAgICBpZD1cImRlYnVnXCJcbiAgICAgIHNsb3Q9XCJjb250ZW50XCJcbiAgICAgIGNsYXNzPVwiZGVidWdcIlxuICAgICAgQGd2LWh0dHAtY2xpZW50OnNlbmQ9XCIke3RoaXMuX29uRGVidWd9XCJcbiAgICAgIC5yZXNwb25zZT1cIiR7cmVzcG9uc2V9XCJcbiAgICAgIC5wYXRoPVwiJHtwYXRofVwiXG4gICAgICAubWV0aG9kPVwiJHttZXRob2R9XCJcbiAgICAgID9sb2FkaW5nPVwiJHtpc0xvYWRpbmd9XCJcbiAgICA+XG4gICAgPC9ndi1odHRwLWNsaWVudD5gO1xuICB9XG5cbiAgX3JlbmRlckNvbmZpZ3VyYXRpb25Gb3JtKHJlYWRvbmx5TW9kZSkge1xuICAgIGlmICh0aGlzLmNvbmZpZ3VyYXRpb25TY2hlbWEpIHtcbiAgICAgIGNvbnN0IHZhbHVlcyA9IGRlZXBDbG9uZSh0aGlzLl9kZWZpbml0aW9uKTtcbiAgICAgIHJldHVybiBodG1sYCA8ZGl2IGlkPVwic2V0dGluZ3NcIiBzbG90PVwiY29udGVudFwiIGNsYXNzPVwiYXBpLXNldHRpbmdzXCIgQGRyYWdvdmVyPVwiJHt0aGlzLl9vbkRlc2lnbn1cIj5cbiAgICAgICAgPGd2LXNjaGVtYS1mb3JtXG4gICAgICAgICAgLnNjaGVtYT1cIiR7dGhpcy5jb25maWd1cmF0aW9uU2NoZW1hfVwiXG4gICAgICAgICAgaWQ9XCJhcGktc2V0dGluZ3MtZm9ybVwiXG4gICAgICAgICAgLnZhbHVlcz1cIiR7dmFsdWVzfVwiXG4gICAgICAgICAgaGFzLWhlYWRlclxuICAgICAgICAgIGhhcy1mb290ZXJcbiAgICAgICAgICBzY3JvbGxhYmxlXG4gICAgICAgICAgP3JlYWRvbmx5PVwiJHtyZWFkb25seU1vZGV9XCJcbiAgICAgICAgICBAZ3Ytc2NoZW1hLWZvcm06Y2FuY2VsPVwiJHt0aGlzLl9vbkNhbmNlbEZsb3dNb2RlfVwiXG4gICAgICAgICAgQGd2LXNjaGVtYS1mb3JtOnN1Ym1pdD1cIiR7dGhpcy5fb25TdWJtaXRGbG93TW9kZX1cIlxuICAgICAgICA+XG4gICAgICAgICAgJHshdGhpcy5jb25maWd1cmF0aW9uSW5mb3JtYXRpb25cbiAgICAgICAgICAgID8gJydcbiAgICAgICAgICAgIDogaHRtbGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXBpLXNldHRpbmdzLWluZm9ybWF0aW9uXCIgc2xvdD1cInRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICA8Z3YtaWNvbiBjbGFzcz1cImFwaS1zZXR0aW5ncy1pbmZvcm1hdGlvbl9faWNvblwiIHRpdGxlPVwiSW5mb1wiIHNoYXBlPVwiY29kZTppbmZvXCI+PC9ndi1pY29uPlxuICAgICAgICAgICAgICAgICAgPGJsb2NrcXVvdGUgY2xhc3M9XCJhcGktc2V0dGluZ3MtaW5mb3JtYXRpb25fX2Jsb2NrcXVvdGVcIj4ke3RoaXMuY29uZmlndXJhdGlvbkluZm9ybWF0aW9ufTwvYmxvY2txdW90ZT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgYH1cbiAgICAgICAgPC9ndi1zY2hlbWEtZm9ybT5cbiAgICAgIDwvZGl2PmA7XG4gICAgfVxuICAgIHJldHVybiBodG1sYGA7XG4gIH1cblxuICBfcmVuZGVyRmxvd0Zvcm0ocmVhZG9ubHlNb2RlKSB7XG4gICAgaWYgKHRoaXMuZmxvd1NjaGVtYSAmJiB0aGlzLl9mbG93U3RlcFNjaGVtYSA9PSBudWxsICYmIHRoaXMuZG9jdW1lbnRhdGlvbiA9PSBudWxsICYmIHRoaXMuc2VsZWN0ZWRGbG93c0lkLmxlbmd0aCA9PT0gMSkge1xuICAgICAgY29uc3QgZmxvdyA9IHRoaXMuZ2V0U2VsZWN0ZWRGbG93KCk7XG4gICAgICBpZiAoZmxvdykge1xuICAgICAgICBjb25zdCB2YWx1ZXMgPSBkZWVwQ2xvbmUoZmxvdyk7XG4gICAgICAgIHJldHVybiBodG1sYDxkaXYgc2xvdD1cImNvbnRlbnRcIiBjbGFzcz1cImZsb3ctc2V0dGluZ3NcIj5cbiAgICAgICAgICA8Z3Ytc2NoZW1hLWZvcm1cbiAgICAgICAgICAgIC5zY2hlbWE9XCIke3RoaXMuZmxvd1NjaGVtYX1cIlxuICAgICAgICAgICAgaWQ9XCJzZXR0aW5ncy1mb3JtXCJcbiAgICAgICAgICAgIC52YWx1ZXM9XCIke3ZhbHVlc31cIlxuICAgICAgICAgICAgaGFzLWhlYWRlclxuICAgICAgICAgICAgc2Nyb2xsYWJsZVxuICAgICAgICAgICAgP3JlYWRvbmx5PVwiJHtyZWFkb25seU1vZGV9XCJcbiAgICAgICAgICAgIEBndi1zY2hlbWEtZm9ybTpjYW5jZWw9XCIke3RoaXMuX29uQ2FuY2VsRmxvd31cIlxuICAgICAgICAgICAgQGd2LXNjaGVtYS1mb3JtOnN1Ym1pdD1cIiR7dGhpcy5fb25TdWJtaXRGbG93fVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGRpdiBzbG90PVwidGl0bGVcIiBjbGFzcz1cImZsb3ctc3RlcF9fZm9ybS10aXRsZVwiPkZsb3cgY29uZmlndXJhdGlvbjwvZGl2PlxuICAgICAgICAgIDwvZ3Ytc2NoZW1hLWZvcm0+XG4gICAgICAgIDwvZGl2PmA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgX29uUmVzb3VyY2VzQ2hhbmdlKHsgZGV0YWlsIH0pIHtcbiAgICB0aGlzLmRlZmluaXRpb24ucmVzb3VyY2VzID0gZGV0YWlsLnJlc291cmNlcztcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICB9XG5cbiAgX29uUHJvcGVydGllc0NoYW5nZSh7IGRldGFpbCB9KSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLnByb3BlcnRpZXMgPSBkZXRhaWwucHJvcGVydGllcztcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICB9XG5cbiAgX29uU2F2ZVByb3ZpZGVyKHsgZGV0YWlsIH0pIHtcbiAgICB0aGlzLnNlcnZpY2VzWydkeW5hbWljLXByb3BlcnR5J10gPSBkZXRhaWwucHJvdmlkZXI7XG4gICAgdGhpcy5pc0RpcnR5ID0gdHJ1ZTtcbiAgfVxuXG4gIF9vblN3aXRjaEVuY3J5cHRlZFByb3BlcnR5KHsgZGV0YWlsIH0pIHtcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGNvbnN0IHJlYWRvbmx5TW9kZSA9IHRoaXMuX2dldFJlYWRvbmx5TW9kZUZvckRlc2lnbigpO1xuXG4gICAgcmV0dXJuIGh0bWxgPGRpdiBjbGFzcz1cImJveFwiPlxuICAgICAgPGd2LXBvbGljeS1zdHVkaW8tbWVudVxuICAgICAgICBjbGFzcz1cImxlZnQtbWVudVwiXG4gICAgICAgIC5hcGktbmFtZT1cIiR7dGhpcy5fZGVmaW5pdGlvbi5uYW1lfVwiXG4gICAgICAgIC5mbG93cz1cIiR7dGhpcy5maWx0ZXJlZEZsb3dzfVwiXG4gICAgICAgIC5wbGFucz1cIiR7dGhpcy5maWx0ZXJlZFBsYW5zfVwiXG4gICAgICAgIC5zZWxlY3RlZElkcz1cIiR7dGhpcy5zZWxlY3RlZEZsb3dzSWR9XCJcbiAgICAgICAgP2Rpc2FibGVkPVwiJHt0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9ufVwiXG4gICAgICAgID9zb3J0YWJsZT1cIiR7dGhpcy5zb3J0YWJsZSAmJiB0aGlzLnJlYWRvbmx5ICE9PSB0cnVlfVwiXG4gICAgICAgID9yZWFkb25seT1cIiR7dGhpcy5yZWFkb25seX1cIlxuICAgICAgICA/cmVhZG9ubHlQbGFucz1cIiR7dGhpcy5yZWFkb25seVBsYW5zfVwiXG4gICAgICAgIGZsb3dzLXRpdGxlPVwiJHt0aGlzLmZsb3dzVGl0bGV9XCJcbiAgICAgICAgLnF1ZXJ5PVwiJHt0aGlzLl9zZWFyY2hGbG93UXVlcnl9XCJcbiAgICAgICAgP2Nhbi1hZGQ9XCIke3RoaXMuY2FuQWRkICYmICF0aGlzLnJlYWRvbmx5fVwiXG4gICAgICAgIEBndi1wb2xpY3ktc3R1ZGlvLW1lbnU6cmVvcmRlci1mbG93cz1cIiR7dGhpcy5fb25SZW9yZGVyRmxvd3N9XCJcbiAgICAgICAgQGd2LXBvbGljeS1zdHVkaW8tbWVudTpjaGFuZ2UtZmxvdy1zdGF0ZT1cIiR7dGhpcy5fb25DaGFuZ2VGbG93U3RhdGV9XCJcbiAgICAgICAgQGd2LXBvbGljeS1zdHVkaW8tbWVudTphZGQtZmxvdz1cIiR7dGhpcy5fb25BZGRGbG93fVwiXG4gICAgICAgIEBndi1wb2xpY3ktc3R1ZGlvLW1lbnU6YWRkLWZsb3ctcGxhbj1cIiR7dGhpcy5fb25BZGRGbG93UGxhbn1cIlxuICAgICAgICBAZ3YtcG9saWN5LXN0dWRpby1tZW51OmRlbGV0ZS1mbG93PVwiJHt0aGlzLl9vbkRlbGV0ZUZsb3d9XCJcbiAgICAgICAgQGd2LXBvbGljeS1zdHVkaW8tbWVudTpkdXBsaWNhdGUtZmxvdz1cIiR7dGhpcy5fb25EdXBsaWNhdGVGbG93fVwiXG4gICAgICAgIEBndi1wb2xpY3ktc3R1ZGlvLW1lbnU6c2VsZWN0LWZsb3dzPVwiJHt0aGlzLl9vblNlbGVjdEZsb3dzfVwiXG4gICAgICA+XG4gICAgICAgIDxkaXYgc2xvdD1cImhlYWRlclwiIGNsYXNzPVwiaGVhZGVyLWFjdGlvbnNcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGl0bGVcIj4ke3RoaXMuX2RlZmluaXRpb24ubmFtZX08L2Rpdj5cbiAgICAgICAgICAke3RoaXMuX2Zsb3dGaWx0ZXJPcHRpb25zICE9IG51bGxcbiAgICAgICAgICAgID8gaHRtbGA8Z3Ytb3B0aW9uXG4gICAgICAgICAgICAgICAgP2Rpc2FibGVkPVwiJHt0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9ufVwiXG4gICAgICAgICAgICAgICAgLm9wdGlvbnM9XCIke3RoaXMuX2Zsb3dGaWx0ZXJPcHRpb25zfVwiXG4gICAgICAgICAgICAgICAgbXVsdGlwbGVcbiAgICAgICAgICAgICAgICBvdXRsaW5lZFxuICAgICAgICAgICAgICAgIC52YWx1ZT1cIiR7dGhpcy5fZmxvd0ZpbHRlcn1cIlxuICAgICAgICAgICAgICAgIHNtYWxsXG4gICAgICAgICAgICAgICAgQGd2LW9wdGlvbjpzZWxlY3Q9XCIke3RoaXMuX29uRmlsdGVyRmxvd3N9XCJcbiAgICAgICAgICAgICAgPjwvZ3Ytb3B0aW9uPmBcbiAgICAgICAgICAgIDogJyd9XG4gICAgICAgICAgPGd2LWlucHV0XG4gICAgICAgICAgICA/ZGlzYWJsZWQ9XCIke3RoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb259XCJcbiAgICAgICAgICAgIGlkPVwic2VhcmNoLWZsb3dcIlxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJGaWx0ZXIgZmxvd3MgKEN0cmwgKyBTcGFjZSlcIlxuICAgICAgICAgICAgdHlwZT1cInNlYXJjaFwiXG4gICAgICAgICAgICBzbWFsbFxuICAgICAgICAgICAgQGd2LWlucHV0OmlucHV0PVwiJHt0aGlzLl9vblNlYXJjaEZsb3dzfVwiXG4gICAgICAgICAgICBAZ3YtaW5wdXQ6Y2xlYXI9XCIke3RoaXMuX29uQ2xlYXJGbG93c31cIlxuICAgICAgICAgID48L2d2LWlucHV0PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICAke3RoaXMucmVhZG9ubHkgIT09IHRydWVcbiAgICAgICAgICA/IGh0bWxgIDxkaXYgc2xvdD1cImZvb3RlclwiIGNsYXNzPVwiZm9vdGVyLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgPGd2LWJ1dHRvblxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuLWxhcmdlXCJcbiAgICAgICAgICAgICAgICAuZGlzYWJsZWQ9XCIkeyF0aGlzLmlzRGlydHkgfHwgdGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbn1cIlxuICAgICAgICAgICAgICAgIEBndi1idXR0b246Y2xpY2s9XCIke3RoaXMuX29uU2F2ZUFsbH1cIlxuICAgICAgICAgICAgICAgID5TYXZlPC9ndi1idXR0b25cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8Z3YtYnV0dG9uIGxpbmsgLmRpc2FibGVkPVwiJHshdGhpcy5pc0RpcnR5IHx8IHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb259XCIgQGd2LWJ1dHRvbjpjbGljaz1cIiR7dGhpcy5fb25SZXNldEFsbH1cIlxuICAgICAgICAgICAgICAgID5SZXNldDwvZ3YtYnV0dG9uXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvZGl2PmBcbiAgICAgICAgICA6ICcnfVxuICAgICAgPC9ndi1wb2xpY3ktc3R1ZGlvLW1lbnU+XG5cbiAgICAgIDxndi10YWJzXG4gICAgICAgIC52YWx1ZT1cIiR7dGhpcy50YWJJZH1cIlxuICAgICAgICAub3B0aW9ucz1cIiR7dGhpcy5fdGFic31cIlxuICAgICAgICAuZGlzYWJsZWQ9XCIke3RoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb259XCJcbiAgICAgICAgQGd2LXRhYnM6Y2hhbmdlPVwiJHt0aGlzLl9vbkNoYW5nZVRhYn1cIlxuICAgICAgICAudmFsaWRhdG9yPVwiJHt0aGlzLl9jaGFuZ2VUYWJWYWxpZGF0b3IuYmluZCh0aGlzKX1cIlxuICAgICAgPlxuICAgICAgICAke3RoaXMuX3JlbmRlckRlc2lnbihyZWFkb25seU1vZGUpfSAke3RoaXMuX3JlbmRlckNvbmZpZ3VyYXRpb25Gb3JtKHJlYWRvbmx5TW9kZSl9ICR7dGhpcy5fcmVuZGVyRGVidWcoKX1cbiAgICAgICAgPGd2LXByb3BlcnRpZXNcbiAgICAgICAgICBpZD1cInByb3BlcnRpZXNcIlxuICAgICAgICAgIHNsb3Q9XCJjb250ZW50XCJcbiAgICAgICAgICBjbGFzcz1cInByb3BlcnRpZXNcIlxuICAgICAgICAgIC5wcm92aWRlcj1cIiR7dGhpcy5zZXJ2aWNlc1snZHluYW1pYy1wcm9wZXJ0eSddfVwiXG4gICAgICAgICAgQGd2LXByb3BlcnRpZXM6Y2hhbmdlPVwiJHt0aGlzLl9vblByb3BlcnRpZXNDaGFuZ2V9XCJcbiAgICAgICAgICBAZ3YtcHJvcGVydGllczpzYXZlLXByb3ZpZGVyPVwiJHt0aGlzLl9vblNhdmVQcm92aWRlcn1cIlxuICAgICAgICAgIEBndi1wcm9wZXJ0aWVzOnN3aXRjaC1lbmNyeXB0ZWQ9XCIke3RoaXMuX29uU3dpdGNoRW5jcnlwdGVkUHJvcGVydHl9XCJcbiAgICAgICAgICA/cmVhZG9ubHk9XCIke3JlYWRvbmx5TW9kZX1cIlxuICAgICAgICAgIGVuY3J5cHRhYmxlPVwidHJ1ZVwiXG4gICAgICAgICAgLnByb3BlcnRpZXM9XCIke3RoaXMuZGVmaW5lZFByb3BlcnRpZXN9XCJcbiAgICAgICAgICAucHJvdmlkZXJzPVwiJHt0aGlzLnByb3BlcnR5UHJvdmlkZXJzfVwiXG4gICAgICAgICAgLmR5bmFtaWNQcm9wZXJ0eVNjaGVtYT1cIiR7dGhpcy5keW5hbWljUHJvcGVydHlTY2hlbWF9XCJcbiAgICAgICAgPjwvZ3YtcHJvcGVydGllcz5cbiAgICAgICAgPGd2LXJlc291cmNlc1xuICAgICAgICAgIGlkPVwicmVzb3VyY2VzXCJcbiAgICAgICAgICBzbG90PVwiY29udGVudFwiXG4gICAgICAgICAgY2xhc3M9XCJyZXNvdXJjZXNcIlxuICAgICAgICAgIEBndi1yZXNvdXJjZXM6Y2hhbmdlPVwiJHt0aGlzLl9vblJlc291cmNlc0NoYW5nZX1cIlxuICAgICAgICAgID9yZWFkb25seT1cIiR7cmVhZG9ubHlNb2RlfVwiXG4gICAgICAgICAgLnJlc291cmNlcz1cIiR7dGhpcy5kZWZpbmVkUmVzb3VyY2VzfVwiXG4gICAgICAgICAgLnR5cGVzPVwiJHt0aGlzLnJlc291cmNlVHlwZXN9XCJcbiAgICAgICAgPjwvZ3YtcmVzb3VyY2VzPlxuICAgICAgPC9ndi10YWJzPlxuICAgIDwvZGl2PmA7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIHRoZSBkZXNpZ24gdmlldyBzaG91bGQgYmUgaW4gcmVhZG9ubHkgbW9kZSBvciBub3RcbiAgICogSXQgaXMgaW4gcmVhZG9ubHkgbW9kZSBpZjpcbiAgICogIHRoZSByZWFkb25seSBhdHRyaWJ1dGUgaXMgc2V0IHRvIHRydWVcbiAgICogIE9SXG4gICAqICB0aGUgbWFpbiBzZWxlY3RlZCBmbG93IGJlbG9uZ3MgdG8gYSBwbGFuIGFuZCB0aGUgcmVhZG9ubHktcGxhbnMgYXR0cmlidXRlIGlzIHNldCB0byB0cnVlXG4gICAqICBPUlxuICAgKiAgdGhlIHNlY29uZCBmbG93IGZvciBjb21wYXJpc29uIGJlbG9uZ3MgdG8gYSBwbGFuIGFuZCB0aGUgcmVhZG9ubHktcGxhbnMgYXR0cmlidXRlIGlzIHNldCB0byB0cnVlXG4gICAqIEByZXR1cm5zIHtib29sZWFufCp8e3R5cGU6IEJvb2xlYW5Db25zdHJ1Y3Rvcn18e2F0dHJpYnV0ZTogc3RyaW5nLCB0eXBlOiBCb29sZWFuQ29uc3RydWN0b3J9fHt0eXBlOiAqfXx7YXR0cmlidXRlOiBzdHJpbmcsIHR5cGU6ICp9fVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX2dldFJlYWRvbmx5TW9kZUZvckRlc2lnbigpIHtcbiAgICBpZiAodGhpcy5yZWFkb25seSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgY29uc3QgZmxvdyA9IHRoaXMuZ2V0U2VsZWN0ZWRGbG93KDApO1xuICAgIGlmICghZmxvdykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHsgcGxhbjogZmxvd1BsYW4gfSA9IHRoaXMuX2ZpbmRGbG93Q29sbGVjdGlvbihmbG93Ll9pZCk7XG4gICAgY29uc3QgcmVhZG9ubHlNb2RlID0gZmxvd1BsYW4gJiYgdGhpcy5yZWFkb25seVBsYW5zO1xuICAgIGlmIChyZWFkb25seU1vZGUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbXBhcmVkRmxvdyA9IHRoaXMuZ2V0U2VsZWN0ZWRGbG93KDEpO1xuICAgIGlmICghY29tcGFyZWRGbG93KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgeyBwbGFuOiBjb21wYXJlZEZsb3dQbGFuIH0gPSB0aGlzLl9maW5kRmxvd0NvbGxlY3Rpb24oY29tcGFyZWRGbG93Ll9pZCk7XG4gICAgcmV0dXJuIGNvbXBhcmVkRmxvd1BsYW4gJiYgdGhpcy5yZWFkb25seVBsYW5zO1xuICB9XG59XG5cbndpbmRvdy5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ2d2LXBvbGljeS1zdHVkaW8nLCBHdlBvbGljeVN0dWRpbyk7XG4iXX0=