ngx-wapp-components 2.0.2-alpha.1 → 2.0.2-alpha.3

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 (37) hide show
  1. package/esm2020/lib/misc/w-code-block/w-code-block.component.mjs +6 -5
  2. package/esm2020/lib/misc/w-filter-panel/query-builder/query-arrow-icon.directive.mjs +14 -0
  3. package/esm2020/lib/misc/w-filter-panel/query-builder/query-builder.component.mjs +738 -0
  4. package/esm2020/lib/misc/w-filter-panel/query-builder/query-builder.interfaces.mjs +2 -0
  5. package/esm2020/lib/misc/w-filter-panel/query-builder/query-button-group.directive.mjs +14 -0
  6. package/esm2020/lib/misc/w-filter-panel/query-builder/query-empty-warning.directive.mjs +14 -0
  7. package/esm2020/lib/misc/w-filter-panel/query-builder/query-entity.directive.mjs +14 -0
  8. package/esm2020/lib/misc/w-filter-panel/query-builder/query-field.directive.mjs +14 -0
  9. package/esm2020/lib/misc/w-filter-panel/query-builder/query-input.directive.mjs +26 -0
  10. package/esm2020/lib/misc/w-filter-panel/query-builder/query-operator.directive.mjs +14 -0
  11. package/esm2020/lib/misc/w-filter-panel/query-builder/query-remove-button.directive.mjs +14 -0
  12. package/esm2020/lib/misc/w-filter-panel/query-builder/query-switch-group.directive.mjs +14 -0
  13. package/esm2020/lib/misc/w-filter-panel/w-filter-panel.component.mjs +25 -17
  14. package/esm2020/lib/shared/models/filter-panel/query-results.model.mjs +1 -1
  15. package/esm2020/lib/wapp-components.module.mjs +52 -10
  16. package/esm2020/public-api.mjs +13 -1
  17. package/fesm2015/ngx-wapp-components.mjs +894 -21
  18. package/fesm2015/ngx-wapp-components.mjs.map +1 -1
  19. package/fesm2020/ngx-wapp-components.mjs +894 -21
  20. package/fesm2020/ngx-wapp-components.mjs.map +1 -1
  21. package/lib/misc/w-code-block/w-code-block.component.d.ts +1 -0
  22. package/lib/misc/w-filter-panel/query-builder/query-arrow-icon.directive.d.ts +8 -0
  23. package/lib/misc/w-filter-panel/query-builder/query-builder.component.d.ts +129 -0
  24. package/lib/misc/w-filter-panel/query-builder/query-builder.interfaces.d.ts +143 -0
  25. package/lib/misc/w-filter-panel/query-builder/query-button-group.directive.d.ts +8 -0
  26. package/lib/misc/w-filter-panel/query-builder/query-empty-warning.directive.d.ts +8 -0
  27. package/lib/misc/w-filter-panel/query-builder/query-entity.directive.d.ts +8 -0
  28. package/lib/misc/w-filter-panel/query-builder/query-field.directive.d.ts +8 -0
  29. package/lib/misc/w-filter-panel/query-builder/query-input.directive.d.ts +12 -0
  30. package/lib/misc/w-filter-panel/query-builder/query-operator.directive.d.ts +8 -0
  31. package/lib/misc/w-filter-panel/query-builder/query-remove-button.directive.d.ts +8 -0
  32. package/lib/misc/w-filter-panel/query-builder/query-switch-group.directive.d.ts +8 -0
  33. package/lib/misc/w-filter-panel/w-filter-panel.component.d.ts +1 -1
  34. package/lib/shared/models/filter-panel/query-results.model.d.ts +1 -1
  35. package/lib/wapp-components.module.d.ts +67 -58
  36. package/package.json +1 -2
  37. package/public-api.d.ts +11 -0
@@ -0,0 +1,738 @@
1
+ import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
2
+ import { QueryOperatorDirective } from './query-operator.directive';
3
+ import { QueryFieldDirective } from './query-field.directive';
4
+ import { QueryEntityDirective } from './query-entity.directive';
5
+ import { QuerySwitchGroupDirective } from './query-switch-group.directive';
6
+ import { QueryButtonGroupDirective } from './query-button-group.directive';
7
+ import { QueryInputDirective } from './query-input.directive';
8
+ import { QueryRemoveButtonDirective } from './query-remove-button.directive';
9
+ import { QueryEmptyWarningDirective } from './query-empty-warning.directive';
10
+ import { QueryArrowIconDirective } from './query-arrow-icon.directive';
11
+ import { Component, ContentChild, ContentChildren, forwardRef, Input, ViewChild } from '@angular/core';
12
+ import * as i0 from "@angular/core";
13
+ import * as i1 from "@angular/forms";
14
+ import * as i2 from "@angular/common";
15
+ import * as i3 from "@angular/flex-layout/extended";
16
+ export const CONTROL_VALUE_ACCESSOR = {
17
+ provide: NG_VALUE_ACCESSOR,
18
+ useExisting: forwardRef(() => QueryBuilderComponent),
19
+ multi: true
20
+ };
21
+ export const VALIDATOR = {
22
+ provide: NG_VALIDATORS,
23
+ useExisting: forwardRef(() => QueryBuilderComponent),
24
+ multi: true
25
+ };
26
+ export class QueryBuilderComponent {
27
+ constructor(changeDetectorRef) {
28
+ this.changeDetectorRef = changeDetectorRef;
29
+ this.defaultClassNames = {
30
+ arrowIconButton: 'q-arrow-icon-button',
31
+ arrowIcon: 'q-icon q-arrow-icon',
32
+ removeIcon: 'q-icon q-remove-icon',
33
+ addIcon: 'q-icon q-add-icon',
34
+ button: 'q-button',
35
+ buttonGroup: 'q-button-group',
36
+ removeButton: 'q-remove-button',
37
+ switchGroup: 'q-switch-group',
38
+ switchLabel: 'q-switch-label',
39
+ switchRadio: 'q-switch-radio',
40
+ rightAlign: 'q-right-align',
41
+ transition: 'q-transition',
42
+ collapsed: 'q-collapsed',
43
+ treeContainer: 'q-tree-container',
44
+ tree: 'q-tree',
45
+ row: 'q-row',
46
+ connector: 'q-connector',
47
+ rule: 'q-rule',
48
+ ruleSet: 'q-ruleset',
49
+ invalidRuleSet: 'q-invalid-ruleset',
50
+ emptyWarning: 'q-empty-warning',
51
+ fieldControl: 'q-field-control',
52
+ fieldControlSize: 'q-control-size',
53
+ entityControl: 'q-entity-control',
54
+ entityControlSize: 'q-control-size',
55
+ operatorControl: 'q-operator-control',
56
+ operatorControlSize: 'q-control-size',
57
+ inputControl: 'q-input-control',
58
+ inputControlSize: 'q-control-size'
59
+ };
60
+ this.defaultOperatorMap = {
61
+ string: ['=', '!=', 'contains', 'like'],
62
+ number: ['=', '!=', '>', '>=', '<', '<='],
63
+ time: ['=', '!=', '>', '>=', '<', '<='],
64
+ date: ['=', '!=', '>', '>=', '<', '<='],
65
+ category: ['=', '!=', 'in', 'not in'],
66
+ boolean: ['=']
67
+ };
68
+ this.data = { condition: 'and', rules: [] };
69
+ this.allowRuleset = true;
70
+ this.allowCollapse = false;
71
+ this.emptyMessage = 'A ruleset cannot be empty. Please add a rule or remove it all together.';
72
+ this.config = { fields: {} };
73
+ this.persistValueOnFieldChange = false;
74
+ this.defaultTemplateTypes = [
75
+ 'string', 'number', 'time', 'date', 'category', 'boolean', 'multiselect'
76
+ ];
77
+ this.defaultPersistValueTypes = [
78
+ 'string', 'number', 'time', 'date', 'boolean'
79
+ ];
80
+ this.defaultEmptyList = [];
81
+ this.inputContextCache = new Map();
82
+ this.operatorContextCache = new Map();
83
+ this.fieldContextCache = new Map();
84
+ this.entityContextCache = new Map();
85
+ this.removeButtonContextCache = new Map();
86
+ // ----------END----------
87
+ this.getDisabledState = () => {
88
+ return this.disabled;
89
+ };
90
+ }
91
+ // ----------OnInit Implementation----------
92
+ ngOnInit() { }
93
+ // ----------OnChanges Implementation----------
94
+ ngOnChanges(changes) {
95
+ const config = this.config;
96
+ const type = typeof config;
97
+ if (type === 'object') {
98
+ this.fields = Object.keys(config.fields).map((value) => {
99
+ const field = config.fields[value];
100
+ field.value = field.value || value;
101
+ return field;
102
+ });
103
+ if (config.entities) {
104
+ this.entities = Object.keys(config.entities).map((value) => {
105
+ const entity = config.entities[value];
106
+ entity.value = entity.value || value;
107
+ return entity;
108
+ });
109
+ }
110
+ else {
111
+ this.entities = null;
112
+ }
113
+ this.operatorsCache = {};
114
+ }
115
+ else {
116
+ throw new Error(`Expected 'config' must be a valid object, got ${type} instead.`);
117
+ }
118
+ }
119
+ // ----------Validator Implementation----------
120
+ validate(control) {
121
+ const errors = {};
122
+ const ruleErrorStore = [];
123
+ let hasErrors = false;
124
+ if (!this.config.allowEmptyRulesets && this.checkEmptyRuleInRuleset(this.data)) {
125
+ errors['empty'] = 'Empty rulesets are not allowed.';
126
+ hasErrors = true;
127
+ }
128
+ this.validateRulesInRuleset(this.data, ruleErrorStore);
129
+ if (ruleErrorStore.length) {
130
+ errors['rules'] = ruleErrorStore;
131
+ hasErrors = true;
132
+ }
133
+ return hasErrors ? errors : null;
134
+ }
135
+ // ----------ControlValueAccessor Implementation----------
136
+ get value() {
137
+ return this.data;
138
+ }
139
+ set value(value) {
140
+ // When component is initialized without a formControl, null is passed to value
141
+ this.data = value || { condition: 'and', rules: [] };
142
+ this.handleDataChange();
143
+ }
144
+ writeValue(obj) {
145
+ this.value = obj;
146
+ }
147
+ registerOnChange(fn) {
148
+ this.onChangeCallback = () => fn(this.data);
149
+ }
150
+ registerOnTouched(fn) {
151
+ this.onTouchedCallback = () => fn(this.data);
152
+ }
153
+ setDisabledState(isDisabled) {
154
+ this.disabled = isDisabled;
155
+ this.changeDetectorRef.detectChanges();
156
+ }
157
+ findTemplateForRule(rule) {
158
+ const type = this.getInputType(rule.field, rule.operator);
159
+ if (type) {
160
+ const queryInput = this.findQueryInput(type);
161
+ if (queryInput) {
162
+ return queryInput.template;
163
+ }
164
+ else {
165
+ if (this.defaultTemplateTypes.indexOf(type) === -1) {
166
+ console.warn(`Could not find template for field with type: ${type}`);
167
+ }
168
+ return null;
169
+ }
170
+ }
171
+ }
172
+ findQueryInput(type) {
173
+ const templates = this.parentInputTemplates || this.inputTemplates;
174
+ return templates.find((item) => item.queryInputType === type);
175
+ }
176
+ getOperators(field) {
177
+ if (this.operatorsCache[field]) {
178
+ return this.operatorsCache[field];
179
+ }
180
+ let operators = this.defaultEmptyList;
181
+ const fieldObject = this.config.fields[field];
182
+ if (this.config.getOperators) {
183
+ return this.config.getOperators(field, fieldObject);
184
+ }
185
+ const type = fieldObject.type;
186
+ if (fieldObject && fieldObject.operators) {
187
+ operators = fieldObject.operators;
188
+ }
189
+ else if (type) {
190
+ operators = (this.operatorMap && this.operatorMap[type]) || this.defaultOperatorMap[type] || this.defaultEmptyList;
191
+ if (operators.length === 0) {
192
+ console.warn(`No operators found for field '${field}' with type ${fieldObject.type}. ` +
193
+ `Please define an 'operators' property on the field or use the 'operatorMap' binding to fix this.`);
194
+ }
195
+ if (fieldObject.nullable) {
196
+ operators = operators.concat(['is null', 'is not null']);
197
+ }
198
+ }
199
+ else {
200
+ console.warn(`No 'type' property found on field: '${field}'`);
201
+ }
202
+ // Cache reference to array object, so it won't be computed next time and trigger a rerender.
203
+ this.operatorsCache[field] = operators;
204
+ return operators;
205
+ }
206
+ getFields(entity) {
207
+ if (this.entities && entity) {
208
+ return this.fields.filter((field) => {
209
+ return field && field.entity === entity;
210
+ });
211
+ }
212
+ else {
213
+ return this.fields;
214
+ }
215
+ }
216
+ getInputType(field, operator) {
217
+ if (this.config.getInputType) {
218
+ return this.config.getInputType(field, operator);
219
+ }
220
+ if (!this.config.fields[field]) {
221
+ throw new Error(`No configuration for field '${field}' could be found! Please add it to config.fields.`);
222
+ }
223
+ const type = this.config.fields[field].type;
224
+ switch (operator) {
225
+ case 'is null':
226
+ case 'is not null':
227
+ return null; // No displayed component
228
+ case 'in':
229
+ case 'not in':
230
+ return type === 'category' || type === 'boolean' ? 'multiselect' : type;
231
+ default:
232
+ return type;
233
+ }
234
+ }
235
+ getOptions(field) {
236
+ if (this.config.getOptions) {
237
+ return this.config.getOptions(field);
238
+ }
239
+ return this.config.fields[field].options || this.defaultEmptyList;
240
+ }
241
+ getClassNames(...args) {
242
+ const clsLookup = this.classNames ? this.classNames : this.defaultClassNames;
243
+ const classNames = args
244
+ .map((id) => clsLookup[id] || this.defaultClassNames[id])
245
+ .filter((c) => !!c);
246
+ return classNames.length ? classNames.join(' ') : null;
247
+ }
248
+ getDefaultField(entity) {
249
+ if (!entity) {
250
+ return null;
251
+ }
252
+ else if (entity.defaultField !== undefined) {
253
+ return this.getDefaultValue(entity.defaultField);
254
+ }
255
+ else {
256
+ const entityFields = this.fields.filter((field) => {
257
+ return field && field.entity === entity.value;
258
+ });
259
+ if (entityFields && entityFields.length) {
260
+ return entityFields[0];
261
+ }
262
+ else {
263
+ console.warn(`No fields found for entity '${entity.name}'. ` +
264
+ `A 'defaultOperator' is also not specified on the field config. Operator value will default to null.`);
265
+ return null;
266
+ }
267
+ }
268
+ }
269
+ getDefaultOperator(field) {
270
+ if (field && field.defaultOperator !== undefined) {
271
+ return this.getDefaultValue(field.defaultOperator);
272
+ }
273
+ else {
274
+ const operators = this.getOperators(field.value);
275
+ if (operators && operators.length) {
276
+ return operators[0];
277
+ }
278
+ else {
279
+ console.warn(`No operators found for field '${field.value}'. ` +
280
+ `A 'defaultOperator' is also not specified on the field config. Operator value will default to null.`);
281
+ return null;
282
+ }
283
+ }
284
+ }
285
+ addRule(parent) {
286
+ if (this.disabled) {
287
+ return;
288
+ }
289
+ parent = parent || this.data;
290
+ if (this.config.addRule) {
291
+ this.config.addRule(parent);
292
+ }
293
+ else {
294
+ const field = this.fields[0];
295
+ parent.rules = parent.rules.concat([{
296
+ field: field.value,
297
+ operator: this.getDefaultOperator(field),
298
+ value: this.getDefaultValue(field.defaultValue),
299
+ entity: field.entity
300
+ }]);
301
+ }
302
+ this.handleTouched();
303
+ this.handleDataChange();
304
+ }
305
+ removeRule(rule, parent) {
306
+ if (this.disabled) {
307
+ return;
308
+ }
309
+ parent = parent || this.data;
310
+ if (this.config.removeRule) {
311
+ this.config.removeRule(rule, parent);
312
+ }
313
+ else {
314
+ parent.rules = parent.rules.filter((r) => r !== rule);
315
+ }
316
+ this.inputContextCache.delete(rule);
317
+ this.operatorContextCache.delete(rule);
318
+ this.fieldContextCache.delete(rule);
319
+ this.entityContextCache.delete(rule);
320
+ this.removeButtonContextCache.delete(rule);
321
+ this.handleTouched();
322
+ this.handleDataChange();
323
+ }
324
+ addRuleSet(parent) {
325
+ if (this.disabled) {
326
+ return;
327
+ }
328
+ parent = parent || this.data;
329
+ if (this.config.addRuleSet) {
330
+ this.config.addRuleSet(parent);
331
+ }
332
+ else {
333
+ parent.rules = parent.rules.concat([{ condition: 'and', rules: [] }]);
334
+ }
335
+ this.handleTouched();
336
+ this.handleDataChange();
337
+ }
338
+ removeRuleSet(ruleset, parent) {
339
+ if (this.disabled) {
340
+ return;
341
+ }
342
+ ruleset = ruleset || this.data;
343
+ parent = parent || this.parentValue;
344
+ if (this.config.removeRuleSet) {
345
+ this.config.removeRuleSet(ruleset, parent);
346
+ }
347
+ else {
348
+ parent.rules = parent.rules.filter((r) => r !== ruleset);
349
+ }
350
+ this.handleTouched();
351
+ this.handleDataChange();
352
+ }
353
+ transitionEnd(e) {
354
+ this.treeContainer.nativeElement.style.maxHeight = null;
355
+ }
356
+ toggleCollapse() {
357
+ this.computedTreeContainerHeight();
358
+ setTimeout(() => {
359
+ this.data.collapsed = !this.data.collapsed;
360
+ }, 100);
361
+ }
362
+ computedTreeContainerHeight() {
363
+ const nativeElement = this.treeContainer.nativeElement;
364
+ if (nativeElement && nativeElement.firstElementChild) {
365
+ nativeElement.style.maxHeight = (nativeElement.firstElementChild.clientHeight + 8) + 'px';
366
+ }
367
+ }
368
+ changeCondition(value) {
369
+ if (this.disabled) {
370
+ return;
371
+ }
372
+ this.data.condition = value;
373
+ this.handleTouched();
374
+ this.handleDataChange();
375
+ }
376
+ changeOperator(rule) {
377
+ if (this.disabled) {
378
+ return;
379
+ }
380
+ if (this.config.coerceValueForOperator) {
381
+ rule.value = this.config.coerceValueForOperator(rule.operator, rule.value, rule);
382
+ }
383
+ else {
384
+ rule.value = this.coerceValueForOperator(rule.operator, rule.value, rule);
385
+ }
386
+ this.handleTouched();
387
+ this.handleDataChange();
388
+ }
389
+ coerceValueForOperator(operator, value, rule) {
390
+ const inputType = this.getInputType(rule.field, operator);
391
+ if (inputType === 'multiselect' && !Array.isArray(value)) {
392
+ return [value];
393
+ }
394
+ return value;
395
+ }
396
+ changeInput() {
397
+ if (this.disabled) {
398
+ return;
399
+ }
400
+ this.handleTouched();
401
+ this.handleDataChange();
402
+ }
403
+ changeField(fieldValue, rule) {
404
+ if (this.disabled) {
405
+ return;
406
+ }
407
+ const inputContext = this.inputContextCache.get(rule);
408
+ const currentField = inputContext && inputContext.field;
409
+ const nextField = this.config.fields[fieldValue];
410
+ const nextValue = this.calculateFieldChangeValue(currentField, nextField, rule.value);
411
+ if (nextValue !== undefined) {
412
+ rule.value = nextValue;
413
+ }
414
+ else {
415
+ delete rule.value;
416
+ }
417
+ rule.operator = this.getDefaultOperator(nextField);
418
+ // Create new context objects so templates will automatically update
419
+ this.inputContextCache.delete(rule);
420
+ this.operatorContextCache.delete(rule);
421
+ this.fieldContextCache.delete(rule);
422
+ this.entityContextCache.delete(rule);
423
+ this.getInputContext(rule);
424
+ this.getFieldContext(rule);
425
+ this.getOperatorContext(rule);
426
+ this.getEntityContext(rule);
427
+ this.handleTouched();
428
+ this.handleDataChange();
429
+ }
430
+ changeEntity(entityValue, rule, index, data) {
431
+ if (this.disabled) {
432
+ return;
433
+ }
434
+ let i = index;
435
+ let rs = data;
436
+ const entity = this.entities.find((e) => e.value === entityValue);
437
+ const defaultField = this.getDefaultField(entity);
438
+ if (!rs) {
439
+ rs = this.data;
440
+ i = rs.rules.findIndex((x) => x === rule);
441
+ }
442
+ rule.field = defaultField.value;
443
+ rs.rules[i] = rule;
444
+ if (defaultField) {
445
+ this.changeField(defaultField.value, rule);
446
+ }
447
+ else {
448
+ this.handleTouched();
449
+ this.handleDataChange();
450
+ }
451
+ }
452
+ getDefaultValue(defaultValue) {
453
+ switch (typeof defaultValue) {
454
+ case 'function':
455
+ return defaultValue();
456
+ default:
457
+ return defaultValue;
458
+ }
459
+ }
460
+ getOperatorTemplate() {
461
+ const t = this.parentOperatorTemplate || this.operatorTemplate;
462
+ return t ? t.template : null;
463
+ }
464
+ getFieldTemplate() {
465
+ const t = this.parentFieldTemplate || this.fieldTemplate;
466
+ return t ? t.template : null;
467
+ }
468
+ getEntityTemplate() {
469
+ const t = this.parentEntityTemplate || this.entityTemplate;
470
+ return t ? t.template : null;
471
+ }
472
+ getArrowIconTemplate() {
473
+ const t = this.parentArrowIconTemplate || this.arrowIconTemplate;
474
+ return t ? t.template : null;
475
+ }
476
+ getButtonGroupTemplate() {
477
+ const t = this.parentButtonGroupTemplate || this.buttonGroupTemplate;
478
+ return t ? t.template : null;
479
+ }
480
+ getSwitchGroupTemplate() {
481
+ const t = this.parentSwitchGroupTemplate || this.switchGroupTemplate;
482
+ return t ? t.template : null;
483
+ }
484
+ getRemoveButtonTemplate() {
485
+ const t = this.parentRemoveButtonTemplate || this.removeButtonTemplate;
486
+ return t ? t.template : null;
487
+ }
488
+ getEmptyWarningTemplate() {
489
+ const t = this.parentEmptyWarningTemplate || this.emptyWarningTemplate;
490
+ return t ? t.template : null;
491
+ }
492
+ getQueryItemClassName(local) {
493
+ let cls = this.getClassNames('row', 'connector', 'transition');
494
+ cls += ' ' + this.getClassNames(local.ruleset ? 'ruleSet' : 'rule');
495
+ if (local.invalid) {
496
+ cls += ' ' + this.getClassNames('invalidRuleSet');
497
+ }
498
+ return cls;
499
+ }
500
+ getButtonGroupContext() {
501
+ if (!this.buttonGroupContext) {
502
+ this.buttonGroupContext = {
503
+ addRule: this.addRule.bind(this),
504
+ addRuleSet: this.allowRuleset && this.addRuleSet.bind(this),
505
+ removeRuleSet: this.allowRuleset && this.parentValue && this.removeRuleSet.bind(this),
506
+ getDisabledState: this.getDisabledState,
507
+ $implicit: this.data
508
+ };
509
+ }
510
+ return this.buttonGroupContext;
511
+ }
512
+ getRemoveButtonContext(rule) {
513
+ if (!this.removeButtonContextCache.has(rule)) {
514
+ this.removeButtonContextCache.set(rule, {
515
+ removeRule: this.removeRule.bind(this),
516
+ getDisabledState: this.getDisabledState,
517
+ $implicit: rule
518
+ });
519
+ }
520
+ return this.removeButtonContextCache.get(rule);
521
+ }
522
+ getFieldContext(rule) {
523
+ if (!this.fieldContextCache.has(rule)) {
524
+ this.fieldContextCache.set(rule, {
525
+ onChange: this.changeField.bind(this),
526
+ getFields: this.getFields.bind(this),
527
+ getDisabledState: this.getDisabledState,
528
+ fields: this.fields,
529
+ $implicit: rule
530
+ });
531
+ }
532
+ return this.fieldContextCache.get(rule);
533
+ }
534
+ getEntityContext(rule) {
535
+ if (!this.entityContextCache.has(rule)) {
536
+ this.entityContextCache.set(rule, {
537
+ onChange: (entityValue, r) => this.changeEntity(entityValue, r, undefined, undefined),
538
+ getDisabledState: this.getDisabledState,
539
+ entities: this.entities,
540
+ $implicit: rule
541
+ });
542
+ }
543
+ return this.entityContextCache.get(rule);
544
+ }
545
+ getSwitchGroupContext() {
546
+ return {
547
+ onChange: this.changeCondition.bind(this),
548
+ getDisabledState: this.getDisabledState,
549
+ $implicit: this.data
550
+ };
551
+ }
552
+ getArrowIconContext() {
553
+ return {
554
+ getDisabledState: this.getDisabledState,
555
+ $implicit: this.data
556
+ };
557
+ }
558
+ getEmptyWarningContext() {
559
+ return {
560
+ getDisabledState: this.getDisabledState,
561
+ message: this.emptyMessage,
562
+ $implicit: this.data
563
+ };
564
+ }
565
+ getOperatorContext(rule) {
566
+ if (!this.operatorContextCache.has(rule)) {
567
+ this.operatorContextCache.set(rule, {
568
+ onChange: this.changeOperator.bind(this, rule),
569
+ getDisabledState: this.getDisabledState,
570
+ operators: this.getOperators(rule.field),
571
+ $implicit: rule
572
+ });
573
+ }
574
+ return this.operatorContextCache.get(rule);
575
+ }
576
+ getInputContext(rule) {
577
+ if (!this.inputContextCache.has(rule)) {
578
+ this.inputContextCache.set(rule, {
579
+ onChange: this.changeInput.bind(this),
580
+ getDisabledState: this.getDisabledState,
581
+ options: this.getOptions(rule.field),
582
+ field: this.config.fields[rule.field],
583
+ $implicit: rule
584
+ });
585
+ }
586
+ return this.inputContextCache.get(rule);
587
+ }
588
+ calculateFieldChangeValue(currentField, nextField, currentValue) {
589
+ if (this.config.calculateFieldChangeValue != null) {
590
+ return this.config.calculateFieldChangeValue(currentField, nextField, currentValue);
591
+ }
592
+ const canKeepValue = () => {
593
+ if (currentField == null || nextField == null) {
594
+ return false;
595
+ }
596
+ return currentField.type === nextField.type
597
+ && this.defaultPersistValueTypes.indexOf(currentField.type) !== -1;
598
+ };
599
+ if (this.persistValueOnFieldChange && canKeepValue()) {
600
+ return currentValue;
601
+ }
602
+ if (nextField && nextField.defaultValue !== undefined) {
603
+ return this.getDefaultValue(nextField.defaultValue);
604
+ }
605
+ return undefined;
606
+ }
607
+ checkEmptyRuleInRuleset(ruleset) {
608
+ if (!ruleset || !ruleset.rules || ruleset.rules.length === 0) {
609
+ return true;
610
+ }
611
+ else {
612
+ return ruleset.rules.some((item) => {
613
+ if (item.rules) {
614
+ return this.checkEmptyRuleInRuleset(item);
615
+ }
616
+ else {
617
+ return false;
618
+ }
619
+ });
620
+ }
621
+ }
622
+ validateRulesInRuleset(ruleset, errorStore) {
623
+ if (ruleset && ruleset.rules && ruleset.rules.length > 0) {
624
+ ruleset.rules.forEach((item) => {
625
+ if (item.rules) {
626
+ return this.validateRulesInRuleset(item, errorStore);
627
+ }
628
+ else if (item.field) {
629
+ const field = this.config.fields[item.field];
630
+ if (field && field.validator && field.validator.apply) {
631
+ const error = field.validator(item, ruleset);
632
+ if (error != null) {
633
+ errorStore.push(error);
634
+ }
635
+ }
636
+ }
637
+ });
638
+ }
639
+ }
640
+ handleDataChange() {
641
+ this.changeDetectorRef.markForCheck();
642
+ if (this.onChangeCallback) {
643
+ this.onChangeCallback();
644
+ }
645
+ if (this.parentChangeCallback) {
646
+ this.parentChangeCallback();
647
+ }
648
+ }
649
+ handleTouched() {
650
+ if (this.onTouchedCallback) {
651
+ this.onTouchedCallback();
652
+ }
653
+ if (this.parentTouchedCallback) {
654
+ this.parentTouchedCallback();
655
+ }
656
+ }
657
+ }
658
+ QueryBuilderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: QueryBuilderComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
659
+ QueryBuilderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: QueryBuilderComponent, selector: "query-builder", inputs: { disabled: "disabled", data: "data", allowRuleset: "allowRuleset", allowCollapse: "allowCollapse", emptyMessage: "emptyMessage", classNames: "classNames", operatorMap: "operatorMap", parentValue: "parentValue", config: "config", parentArrowIconTemplate: "parentArrowIconTemplate", parentInputTemplates: "parentInputTemplates", parentOperatorTemplate: "parentOperatorTemplate", parentFieldTemplate: "parentFieldTemplate", parentEntityTemplate: "parentEntityTemplate", parentSwitchGroupTemplate: "parentSwitchGroupTemplate", parentButtonGroupTemplate: "parentButtonGroupTemplate", parentRemoveButtonTemplate: "parentRemoveButtonTemplate", parentEmptyWarningTemplate: "parentEmptyWarningTemplate", parentChangeCallback: "parentChangeCallback", parentTouchedCallback: "parentTouchedCallback", persistValueOnFieldChange: "persistValueOnFieldChange", value: "value" }, providers: [CONTROL_VALUE_ACCESSOR, VALIDATOR], queries: [{ propertyName: "buttonGroupTemplate", first: true, predicate: QueryButtonGroupDirective, descendants: true }, { propertyName: "switchGroupTemplate", first: true, predicate: QuerySwitchGroupDirective, descendants: true }, { propertyName: "fieldTemplate", first: true, predicate: QueryFieldDirective, descendants: true }, { propertyName: "entityTemplate", first: true, predicate: QueryEntityDirective, descendants: true }, { propertyName: "operatorTemplate", first: true, predicate: QueryOperatorDirective, descendants: true }, { propertyName: "removeButtonTemplate", first: true, predicate: QueryRemoveButtonDirective, descendants: true }, { propertyName: "emptyWarningTemplate", first: true, predicate: QueryEmptyWarningDirective, descendants: true }, { propertyName: "arrowIconTemplate", first: true, predicate: QueryArrowIconDirective, descendants: true }, { propertyName: "inputTemplates", predicate: QueryInputDirective }], viewQueries: [{ propertyName: "treeContainer", first: true, predicate: ["treeContainer"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div [ngClass]=\"getClassNames('switchRow')\">\n <ng-template #defaultArrowIcon>\n <i [ngClass]=\"getClassNames('arrowIcon')\"></i>\n </ng-template>\n\n <a *ngIf=\"allowCollapse\" (click)=\"toggleCollapse()\" [ngClass]=\"getClassNames('arrowIconButton', data.collapsed ? 'collapsed' : null)\">\n <ng-container *ngIf=\"getArrowIconTemplate() as template; else defaultArrowIcon\">\n <ng-container *ngTemplateOutlet=\"template; context: getArrowIconContext()\"></ng-container>\n </ng-container>\n </a>\n\n <ng-container *ngIf=\"getButtonGroupTemplate() as template; else defaultButtonGroup\">\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\n <ng-container *ngTemplateOutlet=\"template; context: getButtonGroupContext()\"></ng-container>\n </div>\n </ng-container>\n\n <ng-template #defaultButtonGroup>\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\n <button type=\"button\" (click)=\"addRule()\" [ngClass]=\"getClassNames('button')\" [disabled]=disabled>\n <i [ngClass]=\"getClassNames('addIcon')\"></i> Rule\n </button>\n <button type=\"button\" (click)=\"addRuleSet()\" [ngClass]=\"getClassNames('button')\" *ngIf=\"allowRuleset\" [disabled]=disabled>\n <i [ngClass]=\"getClassNames('addIcon')\"></i> Ruleset\n </button>\n <ng-container *ngIf=\"!!parentValue && allowRuleset\">\n <button type=\"button\" (click)=\"removeRuleSet()\" [ngClass]=\"getClassNames('button', 'removeButton')\" [disabled]=disabled>\n <i [ngClass]=\"getClassNames('removeIcon')\"></i>\n </button>\n </ng-container>\n </div>\n </ng-template>\n\n <ng-container *ngIf=\"getSwitchGroupTemplate() as template; else defaultSwitchGroup\">\n <ng-container *ngTemplateOutlet=\"template; context: getSwitchGroupContext()\"></ng-container>\n </ng-container>\n\n <ng-template #defaultSwitchGroup>\n <div [ngClass]=\"getClassNames('switchGroup', 'transition')\" *ngIf=\"data\">\n <div [ngClass]=\"getClassNames('switchControl')\">\n <input type=\"radio\" [ngClass]=\"getClassNames('switchRadio')\" [(ngModel)]=\"data.condition\" [disabled]=disabled\n value=\"and\" #andOption />\n <label (click)=\"changeCondition(andOption.value)\" [ngClass]=\"getClassNames('switchLabel')\">AND</label>\n </div>\n <div [ngClass]=\"getClassNames('switchControl')\">\n <input type=\"radio\" [ngClass]=\"getClassNames('switchRadio')\" [(ngModel)]=\"data.condition\" [disabled]=disabled\n value=\"or\" #orOption />\n <label (click)=\"changeCondition(orOption.value)\" [ngClass]=\"getClassNames('switchLabel')\">OR</label>\n </div>\n </div>\n </ng-template>\n</div>\n\n<div #treeContainer (transitionend)=\"transitionEnd($event)\" [ngClass]=\"getClassNames('treeContainer', data.collapsed ? 'collapsed' : null)\">\n <ul [ngClass]=\"getClassNames('tree')\" *ngIf=\"data && data.rules\">\n <ng-container *ngFor=\"let rule of data.rules;let i=index\">\n\n <ng-container *ngIf=\"{ruleset: !!rule.rules, invalid: !config.allowEmptyRulesets && rule.rules && rule.rules.length === 0} as local\">\n <li [ngClass]=\"getQueryItemClassName(local)\">\n <ng-container *ngIf=\"!local.ruleset\">\n\n <ng-container *ngIf=\"getRemoveButtonTemplate() as template; else defaultRemoveButton\">\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\n <ng-container *ngTemplateOutlet=\"template; context: getRemoveButtonContext(rule)\"></ng-container>\n </div>\n </ng-container>\n\n <ng-template #defaultRemoveButton>\n <div [ngClass]=\"getClassNames('removeButtonSize', 'rightAlign')\">\n <button type=\"button\" [ngClass]=\"getClassNames('button', 'removeButton')\" (click)=\"removeRule(rule, data)\" [disabled]=disabled>\n <i [ngClass]=\"getClassNames('removeIcon')\"></i>\n </button>\n </div>\n </ng-template>\n\n <div *ngIf=\"entities?.length! > 0\" class=\"q-inline-block-display\">\n <ng-container *ngIf=\"getEntityTemplate() as template; else defaultEntity\">\n <ng-container *ngTemplateOutlet=\"template; context: getEntityContext(rule)\"></ng-container>\n </ng-container>\n </div>\n\n <ng-template #defaultEntity>\n <div [ngClass]=\"getClassNames('entityControlSize')\">\n <select [ngClass]=\"getClassNames('entityControl')\" [(ngModel)]=\"rule.entity\" (ngModelChange)=\"changeEntity($event, rule,i,data)\"\n [disabled]=\"disabled\">\n <option *ngFor=\"let entity of entities\" [ngValue]=\"entity.value\">\n {{entity.name}}\n </option>\n </select>\n </div>\n </ng-template>\n\n <ng-container *ngIf=\"getFieldTemplate() as template; else defaultField\">\n <ng-container *ngTemplateOutlet=\"template; context: getFieldContext(rule)\"></ng-container>\n </ng-container>\n\n <ng-template #defaultField>\n <div [ngClass]=\"getClassNames('fieldControlSize')\">\n <select [ngClass]=\"getClassNames('fieldControl')\" [(ngModel)]=\"rule.field\" (ngModelChange)=\"changeField($event, rule)\"\n [disabled]=\"disabled\">\n <option *ngFor=\"let field of getFields(rule.entity)\" [ngValue]=\"field.value\">\n {{field.name}}\n </option>\n </select>\n </div>\n </ng-template>\n\n <ng-container *ngIf=\"getOperatorTemplate() as template; else defaultOperator\">\n <ng-container *ngTemplateOutlet=\"template; context: getOperatorContext(rule)\"></ng-container>\n </ng-container>\n\n <ng-template #defaultOperator>\n <div [ngClass]=\"getClassNames('operatorControlSize')\">\n <select [ngClass]=\"getClassNames('operatorControl')\" [(ngModel)]=\"rule.operator\" (ngModelChange)=\"changeOperator(rule)\"\n [disabled]=\"disabled\">\n <option *ngFor=\"let operator of getOperators(rule.field)\" [ngValue]=\"operator\">\n {{operator}}\n </option>\n </select>\n </div>\n </ng-template>\n\n <ng-container *ngIf=\"findTemplateForRule(rule) as template; else defaultInput\">\n <ng-container *ngTemplateOutlet=\"template; context: getInputContext(rule)\"></ng-container>\n </ng-container>\n\n <ng-template #defaultInput>\n <div [ngClass]=\"getClassNames('inputControlSize')\" [ngSwitch]=\"getInputType(rule.field, rule.operator)\">\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'string'\" type=\"text\">\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'number'\" type=\"number\">\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'date'\" type=\"date\">\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'time'\" type=\"time\">\n <select [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'category'\">\n <option *ngFor=\"let opt of getOptions(rule.field)\" [ngValue]=\"opt.value\">\n {{opt.name}}\n </option>\n </select>\n <ng-container *ngSwitchCase=\"'multiselect'\">\n <select [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" multiple>\n <option *ngFor=\"let opt of getOptions(rule.field)\" [ngValue]=\"opt.value\">\n {{opt.name}}\n </option>\n </select>\n </ng-container>\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'boolean'\" type=\"checkbox\">\n </div>\n </ng-template>\n\n </ng-container>\n <query-builder *ngIf=\"local.ruleset\" [data]=\"rule\" [disabled]=\"disabled\" [parentTouchedCallback]=\"parentTouchedCallback || onTouchedCallback\"\n [parentChangeCallback]=\"parentChangeCallback || onChangeCallback\" [parentInputTemplates]=\"parentInputTemplates || inputTemplates\"\n [parentOperatorTemplate]=\"parentOperatorTemplate || operatorTemplate\" [parentFieldTemplate]=\"parentFieldTemplate || fieldTemplate\"\n [parentEntityTemplate]=\"parentEntityTemplate || entityTemplate\" [parentSwitchGroupTemplate]=\"parentSwitchGroupTemplate || switchGroupTemplate\"\n [parentButtonGroupTemplate]=\"parentButtonGroupTemplate || buttonGroupTemplate\" [parentRemoveButtonTemplate]=\"parentRemoveButtonTemplate || removeButtonTemplate\"\n [parentEmptyWarningTemplate]=\"parentEmptyWarningTemplate || emptyWarningTemplate\" [parentArrowIconTemplate]=\"parentArrowIconTemplate || arrowIconTemplate\"\n [parentValue]=\"data\" [classNames]=\"classNames\" [config]=\"config\" [allowRuleset]=\"allowRuleset\"\n [allowCollapse]=\"allowCollapse\" [emptyMessage]=\"emptyMessage\" [operatorMap]=\"operatorMap\">\n </query-builder>\n\n <ng-container *ngIf=\"getEmptyWarningTemplate() as template; else defaultEmptyWarning\">\n <ng-container *ngIf=\"local.invalid\">\n <ng-container *ngTemplateOutlet=\"template; context: getEmptyWarningContext()\"></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #defaultEmptyWarning>\n <p [ngClass]=\"getClassNames('emptyWarning')\" *ngIf=\"local.invalid\">\n {{emptyMessage}}\n </p>\n </ng-template>\n </li>\n </ng-container>\n </ng-container>\n </ul>\n</div>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}:host .q-icon{font-style:normal;font-size:12px}:host .q-remove-icon:before{content:\"\\274c\"}:host .q-arrow-icon-button{float:left;margin:4px 6px 4px 0;transform:rotate(90deg);transition:linear .25s transform;cursor:pointer}:host .q-arrow-icon-button.q-collapsed{transform:rotate(0)}:host .q-arrow-icon:before{content:\"\\25b6\"}:host .q-add-icon{color:#555}:host .q-add-icon:before{content:\"\\2795\"}:host .q-remove-button{color:#b3415d;width:31px}:host .q-switch-group,:host .q-button-group{font-family:Lucida Grande,Tahoma,Verdana,sans-serif;overflow:hidden}:host .q-right-align{float:right}:host .q-button{margin-left:8px;padding:0 8px;background-color:#fff}:host .q-button:disabled{display:none}:host .q-control-size{display:inline-block;vertical-align:top;padding-right:10px}:host .q-input-control,:host .q-operator-control,:host .q-field-control,:host .q-entity-control{display:inline-block;padding:5px 8px;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;box-sizing:border-box;width:auto}:host .q-input-control:disabled,:host .q-operator-control:disabled,:host .q-field-control:disabled,:host .q-entity-control:disabled{border-color:transparent}:host .q-operator-control,:host .q-field-control,:host .q-entity-control,:host .q-input-control:not([type=checkbox]){min-height:32px;-webkit-appearance:none}:host .q-switch-label,:host .q-button{float:left;margin-bottom:0;font-size:14px;line-height:30px;font-weight:400;text-align:center;text-shadow:none;border:1px solid rgba(0,0,0,.2);box-sizing:border-box}:host .q-switch-label:hover,:host .q-button:hover{cursor:pointer;background-color:#f0f0f0}:host .q-switch-label{background-color:#e4e4e4;padding:0 8px}:host .q-switch-radio{position:absolute;clip:rect(0,0,0,0);height:1px;width:1px;border:0;overflow:hidden}:host .q-switch-radio:checked+.q-switch-label{border:1px solid rgb(97,158,215);background:white;color:#3176b3}:host .q-switch-radio:disabled+.q-switch-label{display:none}:host .q-switch-radio:checked:disabled+.q-switch-label{display:initial;color:initial;cursor:default;border-color:transparent}:host .q-invalid-ruleset{border:1px solid rgba(179,65,93,.5)!important;background:rgba(179,65,93,.1)!important}:host .q-empty-warning{color:#8d252e;text-align:center}:host .q-ruleset{border:1px solid #CCC}:host .q-rule{border:1px solid #CCC;background:white}:host .q-transition{transition:all .1s ease-in-out}:host .q-tree-container{width:100%;overflow:hidden;transition:ease-in .25s max-height}:host .q-tree-container.q-collapsed{max-height:0!important}:host .q-tree{list-style:none;margin:4px 0 2px}:host .q-row{padding:6px 8px;margin-top:6px}:host .q-connector{position:relative}:host .q-connector:before{top:-5px;border-width:0 0 2px 2px}:host .q-connector:after{border-width:0 0 0 2px;top:50%}:host .q-connector:before,:host .q-connector:after{content:\"\";left:-12px;border-color:#ccc;border-style:solid;width:9px;height:calc(50% + 6px);position:absolute}:host .q-connector:last-child:after{content:none}:host .q-inline-block-display{display:inline-block;vertical-align:top}\n"], dependencies: [{ kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.SelectMultipleControlValueAccessor, selector: "select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "component", type: QueryBuilderComponent, selector: "query-builder", inputs: ["disabled", "data", "allowRuleset", "allowCollapse", "emptyMessage", "classNames", "operatorMap", "parentValue", "config", "parentArrowIconTemplate", "parentInputTemplates", "parentOperatorTemplate", "parentFieldTemplate", "parentEntityTemplate", "parentSwitchGroupTemplate", "parentButtonGroupTemplate", "parentRemoveButtonTemplate", "parentEmptyWarningTemplate", "parentChangeCallback", "parentTouchedCallback", "persistValueOnFieldChange", "value"] }] });
660
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: QueryBuilderComponent, decorators: [{
661
+ type: Component,
662
+ args: [{ selector: 'query-builder', providers: [CONTROL_VALUE_ACCESSOR, VALIDATOR], template: "<div [ngClass]=\"getClassNames('switchRow')\">\n <ng-template #defaultArrowIcon>\n <i [ngClass]=\"getClassNames('arrowIcon')\"></i>\n </ng-template>\n\n <a *ngIf=\"allowCollapse\" (click)=\"toggleCollapse()\" [ngClass]=\"getClassNames('arrowIconButton', data.collapsed ? 'collapsed' : null)\">\n <ng-container *ngIf=\"getArrowIconTemplate() as template; else defaultArrowIcon\">\n <ng-container *ngTemplateOutlet=\"template; context: getArrowIconContext()\"></ng-container>\n </ng-container>\n </a>\n\n <ng-container *ngIf=\"getButtonGroupTemplate() as template; else defaultButtonGroup\">\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\n <ng-container *ngTemplateOutlet=\"template; context: getButtonGroupContext()\"></ng-container>\n </div>\n </ng-container>\n\n <ng-template #defaultButtonGroup>\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\n <button type=\"button\" (click)=\"addRule()\" [ngClass]=\"getClassNames('button')\" [disabled]=disabled>\n <i [ngClass]=\"getClassNames('addIcon')\"></i> Rule\n </button>\n <button type=\"button\" (click)=\"addRuleSet()\" [ngClass]=\"getClassNames('button')\" *ngIf=\"allowRuleset\" [disabled]=disabled>\n <i [ngClass]=\"getClassNames('addIcon')\"></i> Ruleset\n </button>\n <ng-container *ngIf=\"!!parentValue && allowRuleset\">\n <button type=\"button\" (click)=\"removeRuleSet()\" [ngClass]=\"getClassNames('button', 'removeButton')\" [disabled]=disabled>\n <i [ngClass]=\"getClassNames('removeIcon')\"></i>\n </button>\n </ng-container>\n </div>\n </ng-template>\n\n <ng-container *ngIf=\"getSwitchGroupTemplate() as template; else defaultSwitchGroup\">\n <ng-container *ngTemplateOutlet=\"template; context: getSwitchGroupContext()\"></ng-container>\n </ng-container>\n\n <ng-template #defaultSwitchGroup>\n <div [ngClass]=\"getClassNames('switchGroup', 'transition')\" *ngIf=\"data\">\n <div [ngClass]=\"getClassNames('switchControl')\">\n <input type=\"radio\" [ngClass]=\"getClassNames('switchRadio')\" [(ngModel)]=\"data.condition\" [disabled]=disabled\n value=\"and\" #andOption />\n <label (click)=\"changeCondition(andOption.value)\" [ngClass]=\"getClassNames('switchLabel')\">AND</label>\n </div>\n <div [ngClass]=\"getClassNames('switchControl')\">\n <input type=\"radio\" [ngClass]=\"getClassNames('switchRadio')\" [(ngModel)]=\"data.condition\" [disabled]=disabled\n value=\"or\" #orOption />\n <label (click)=\"changeCondition(orOption.value)\" [ngClass]=\"getClassNames('switchLabel')\">OR</label>\n </div>\n </div>\n </ng-template>\n</div>\n\n<div #treeContainer (transitionend)=\"transitionEnd($event)\" [ngClass]=\"getClassNames('treeContainer', data.collapsed ? 'collapsed' : null)\">\n <ul [ngClass]=\"getClassNames('tree')\" *ngIf=\"data && data.rules\">\n <ng-container *ngFor=\"let rule of data.rules;let i=index\">\n\n <ng-container *ngIf=\"{ruleset: !!rule.rules, invalid: !config.allowEmptyRulesets && rule.rules && rule.rules.length === 0} as local\">\n <li [ngClass]=\"getQueryItemClassName(local)\">\n <ng-container *ngIf=\"!local.ruleset\">\n\n <ng-container *ngIf=\"getRemoveButtonTemplate() as template; else defaultRemoveButton\">\n <div [ngClass]=\"getClassNames('buttonGroup', 'rightAlign')\">\n <ng-container *ngTemplateOutlet=\"template; context: getRemoveButtonContext(rule)\"></ng-container>\n </div>\n </ng-container>\n\n <ng-template #defaultRemoveButton>\n <div [ngClass]=\"getClassNames('removeButtonSize', 'rightAlign')\">\n <button type=\"button\" [ngClass]=\"getClassNames('button', 'removeButton')\" (click)=\"removeRule(rule, data)\" [disabled]=disabled>\n <i [ngClass]=\"getClassNames('removeIcon')\"></i>\n </button>\n </div>\n </ng-template>\n\n <div *ngIf=\"entities?.length! > 0\" class=\"q-inline-block-display\">\n <ng-container *ngIf=\"getEntityTemplate() as template; else defaultEntity\">\n <ng-container *ngTemplateOutlet=\"template; context: getEntityContext(rule)\"></ng-container>\n </ng-container>\n </div>\n\n <ng-template #defaultEntity>\n <div [ngClass]=\"getClassNames('entityControlSize')\">\n <select [ngClass]=\"getClassNames('entityControl')\" [(ngModel)]=\"rule.entity\" (ngModelChange)=\"changeEntity($event, rule,i,data)\"\n [disabled]=\"disabled\">\n <option *ngFor=\"let entity of entities\" [ngValue]=\"entity.value\">\n {{entity.name}}\n </option>\n </select>\n </div>\n </ng-template>\n\n <ng-container *ngIf=\"getFieldTemplate() as template; else defaultField\">\n <ng-container *ngTemplateOutlet=\"template; context: getFieldContext(rule)\"></ng-container>\n </ng-container>\n\n <ng-template #defaultField>\n <div [ngClass]=\"getClassNames('fieldControlSize')\">\n <select [ngClass]=\"getClassNames('fieldControl')\" [(ngModel)]=\"rule.field\" (ngModelChange)=\"changeField($event, rule)\"\n [disabled]=\"disabled\">\n <option *ngFor=\"let field of getFields(rule.entity)\" [ngValue]=\"field.value\">\n {{field.name}}\n </option>\n </select>\n </div>\n </ng-template>\n\n <ng-container *ngIf=\"getOperatorTemplate() as template; else defaultOperator\">\n <ng-container *ngTemplateOutlet=\"template; context: getOperatorContext(rule)\"></ng-container>\n </ng-container>\n\n <ng-template #defaultOperator>\n <div [ngClass]=\"getClassNames('operatorControlSize')\">\n <select [ngClass]=\"getClassNames('operatorControl')\" [(ngModel)]=\"rule.operator\" (ngModelChange)=\"changeOperator(rule)\"\n [disabled]=\"disabled\">\n <option *ngFor=\"let operator of getOperators(rule.field)\" [ngValue]=\"operator\">\n {{operator}}\n </option>\n </select>\n </div>\n </ng-template>\n\n <ng-container *ngIf=\"findTemplateForRule(rule) as template; else defaultInput\">\n <ng-container *ngTemplateOutlet=\"template; context: getInputContext(rule)\"></ng-container>\n </ng-container>\n\n <ng-template #defaultInput>\n <div [ngClass]=\"getClassNames('inputControlSize')\" [ngSwitch]=\"getInputType(rule.field, rule.operator)\">\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'string'\" type=\"text\">\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'number'\" type=\"number\">\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'date'\" type=\"date\">\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'time'\" type=\"time\">\n <select [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'category'\">\n <option *ngFor=\"let opt of getOptions(rule.field)\" [ngValue]=\"opt.value\">\n {{opt.name}}\n </option>\n </select>\n <ng-container *ngSwitchCase=\"'multiselect'\">\n <select [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" multiple>\n <option *ngFor=\"let opt of getOptions(rule.field)\" [ngValue]=\"opt.value\">\n {{opt.name}}\n </option>\n </select>\n </ng-container>\n <input [ngClass]=\"getClassNames('inputControl')\" [(ngModel)]=\"rule.value\" (ngModelChange)=\"changeInput()\"\n [disabled]=\"disabled\" *ngSwitchCase=\"'boolean'\" type=\"checkbox\">\n </div>\n </ng-template>\n\n </ng-container>\n <query-builder *ngIf=\"local.ruleset\" [data]=\"rule\" [disabled]=\"disabled\" [parentTouchedCallback]=\"parentTouchedCallback || onTouchedCallback\"\n [parentChangeCallback]=\"parentChangeCallback || onChangeCallback\" [parentInputTemplates]=\"parentInputTemplates || inputTemplates\"\n [parentOperatorTemplate]=\"parentOperatorTemplate || operatorTemplate\" [parentFieldTemplate]=\"parentFieldTemplate || fieldTemplate\"\n [parentEntityTemplate]=\"parentEntityTemplate || entityTemplate\" [parentSwitchGroupTemplate]=\"parentSwitchGroupTemplate || switchGroupTemplate\"\n [parentButtonGroupTemplate]=\"parentButtonGroupTemplate || buttonGroupTemplate\" [parentRemoveButtonTemplate]=\"parentRemoveButtonTemplate || removeButtonTemplate\"\n [parentEmptyWarningTemplate]=\"parentEmptyWarningTemplate || emptyWarningTemplate\" [parentArrowIconTemplate]=\"parentArrowIconTemplate || arrowIconTemplate\"\n [parentValue]=\"data\" [classNames]=\"classNames\" [config]=\"config\" [allowRuleset]=\"allowRuleset\"\n [allowCollapse]=\"allowCollapse\" [emptyMessage]=\"emptyMessage\" [operatorMap]=\"operatorMap\">\n </query-builder>\n\n <ng-container *ngIf=\"getEmptyWarningTemplate() as template; else defaultEmptyWarning\">\n <ng-container *ngIf=\"local.invalid\">\n <ng-container *ngTemplateOutlet=\"template; context: getEmptyWarningContext()\"></ng-container>\n </ng-container>\n </ng-container>\n\n <ng-template #defaultEmptyWarning>\n <p [ngClass]=\"getClassNames('emptyWarning')\" *ngIf=\"local.invalid\">\n {{emptyMessage}}\n </p>\n </ng-template>\n </li>\n </ng-container>\n </ng-container>\n </ul>\n</div>", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}:host .q-icon{font-style:normal;font-size:12px}:host .q-remove-icon:before{content:\"\\274c\"}:host .q-arrow-icon-button{float:left;margin:4px 6px 4px 0;transform:rotate(90deg);transition:linear .25s transform;cursor:pointer}:host .q-arrow-icon-button.q-collapsed{transform:rotate(0)}:host .q-arrow-icon:before{content:\"\\25b6\"}:host .q-add-icon{color:#555}:host .q-add-icon:before{content:\"\\2795\"}:host .q-remove-button{color:#b3415d;width:31px}:host .q-switch-group,:host .q-button-group{font-family:Lucida Grande,Tahoma,Verdana,sans-serif;overflow:hidden}:host .q-right-align{float:right}:host .q-button{margin-left:8px;padding:0 8px;background-color:#fff}:host .q-button:disabled{display:none}:host .q-control-size{display:inline-block;vertical-align:top;padding-right:10px}:host .q-input-control,:host .q-operator-control,:host .q-field-control,:host .q-entity-control{display:inline-block;padding:5px 8px;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;box-sizing:border-box;width:auto}:host .q-input-control:disabled,:host .q-operator-control:disabled,:host .q-field-control:disabled,:host .q-entity-control:disabled{border-color:transparent}:host .q-operator-control,:host .q-field-control,:host .q-entity-control,:host .q-input-control:not([type=checkbox]){min-height:32px;-webkit-appearance:none}:host .q-switch-label,:host .q-button{float:left;margin-bottom:0;font-size:14px;line-height:30px;font-weight:400;text-align:center;text-shadow:none;border:1px solid rgba(0,0,0,.2);box-sizing:border-box}:host .q-switch-label:hover,:host .q-button:hover{cursor:pointer;background-color:#f0f0f0}:host .q-switch-label{background-color:#e4e4e4;padding:0 8px}:host .q-switch-radio{position:absolute;clip:rect(0,0,0,0);height:1px;width:1px;border:0;overflow:hidden}:host .q-switch-radio:checked+.q-switch-label{border:1px solid rgb(97,158,215);background:white;color:#3176b3}:host .q-switch-radio:disabled+.q-switch-label{display:none}:host .q-switch-radio:checked:disabled+.q-switch-label{display:initial;color:initial;cursor:default;border-color:transparent}:host .q-invalid-ruleset{border:1px solid rgba(179,65,93,.5)!important;background:rgba(179,65,93,.1)!important}:host .q-empty-warning{color:#8d252e;text-align:center}:host .q-ruleset{border:1px solid #CCC}:host .q-rule{border:1px solid #CCC;background:white}:host .q-transition{transition:all .1s ease-in-out}:host .q-tree-container{width:100%;overflow:hidden;transition:ease-in .25s max-height}:host .q-tree-container.q-collapsed{max-height:0!important}:host .q-tree{list-style:none;margin:4px 0 2px}:host .q-row{padding:6px 8px;margin-top:6px}:host .q-connector{position:relative}:host .q-connector:before{top:-5px;border-width:0 0 2px 2px}:host .q-connector:after{border-width:0 0 0 2px;top:50%}:host .q-connector:before,:host .q-connector:after{content:\"\";left:-12px;border-color:#ccc;border-style:solid;width:9px;height:calc(50% + 6px);position:absolute}:host .q-connector:last-child:after{content:none}:host .q-inline-block-display{display:inline-block;vertical-align:top}\n"] }]
663
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { disabled: [{
664
+ type: Input
665
+ }], data: [{
666
+ type: Input
667
+ }], allowRuleset: [{
668
+ type: Input
669
+ }], allowCollapse: [{
670
+ type: Input
671
+ }], emptyMessage: [{
672
+ type: Input
673
+ }], classNames: [{
674
+ type: Input
675
+ }], operatorMap: [{
676
+ type: Input
677
+ }], parentValue: [{
678
+ type: Input
679
+ }], config: [{
680
+ type: Input
681
+ }], parentArrowIconTemplate: [{
682
+ type: Input
683
+ }], parentInputTemplates: [{
684
+ type: Input
685
+ }], parentOperatorTemplate: [{
686
+ type: Input
687
+ }], parentFieldTemplate: [{
688
+ type: Input
689
+ }], parentEntityTemplate: [{
690
+ type: Input
691
+ }], parentSwitchGroupTemplate: [{
692
+ type: Input
693
+ }], parentButtonGroupTemplate: [{
694
+ type: Input
695
+ }], parentRemoveButtonTemplate: [{
696
+ type: Input
697
+ }], parentEmptyWarningTemplate: [{
698
+ type: Input
699
+ }], parentChangeCallback: [{
700
+ type: Input
701
+ }], parentTouchedCallback: [{
702
+ type: Input
703
+ }], persistValueOnFieldChange: [{
704
+ type: Input
705
+ }], treeContainer: [{
706
+ type: ViewChild,
707
+ args: ['treeContainer', { static: true }]
708
+ }], buttonGroupTemplate: [{
709
+ type: ContentChild,
710
+ args: [QueryButtonGroupDirective]
711
+ }], switchGroupTemplate: [{
712
+ type: ContentChild,
713
+ args: [QuerySwitchGroupDirective]
714
+ }], fieldTemplate: [{
715
+ type: ContentChild,
716
+ args: [QueryFieldDirective]
717
+ }], entityTemplate: [{
718
+ type: ContentChild,
719
+ args: [QueryEntityDirective]
720
+ }], operatorTemplate: [{
721
+ type: ContentChild,
722
+ args: [QueryOperatorDirective]
723
+ }], removeButtonTemplate: [{
724
+ type: ContentChild,
725
+ args: [QueryRemoveButtonDirective]
726
+ }], emptyWarningTemplate: [{
727
+ type: ContentChild,
728
+ args: [QueryEmptyWarningDirective]
729
+ }], inputTemplates: [{
730
+ type: ContentChildren,
731
+ args: [QueryInputDirective]
732
+ }], arrowIconTemplate: [{
733
+ type: ContentChild,
734
+ args: [QueryArrowIconDirective]
735
+ }], value: [{
736
+ type: Input
737
+ }] } });
738
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktYnVpbGRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93YXBwLWNvbXBvbmVudHMvc3JjL2xpYi9taXNjL3ctZmlsdGVyLXBhbmVsL3F1ZXJ5LWJ1aWxkZXIvcXVlcnktYnVpbGRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93YXBwLWNvbXBvbmVudHMvc3JjL2xpYi9taXNjL3ctZmlsdGVyLXBhbmVsL3F1ZXJ5LWJ1aWxkZXIvcXVlcnktYnVpbGRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0wsaUJBQWlCLEVBQ2pCLGFBQWEsRUFHZCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzlELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzlELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzdFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzdFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBb0J2RSxPQUFPLEVBRUwsU0FBUyxFQUNULFlBQVksRUFDWixlQUFlLEVBQ2YsVUFBVSxFQUNWLEtBQUssRUFNTCxTQUFTLEVBRVYsTUFBTSxlQUFlLENBQUM7Ozs7O0FBRXZCLE1B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QXVCO2dCQXVFakMsS0FBSztzQkFEUixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWJzdHJhY3RDb250cm9sLFxuICBDb250cm9sVmFsdWVBY2Nlc3NvcixcbiAgTkdfVkFMVUVfQUNDRVNTT1IsXG4gIE5HX1ZBTElEQVRPUlMsXG4gIFZhbGlkYXRpb25FcnJvcnMsXG4gIFZhbGlkYXRvclxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBRdWVyeU9wZXJhdG9yRGlyZWN0aXZlIH0gZnJvbSAnLi9xdWVyeS1vcGVyYXRvci5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgUXVlcnlGaWVsZERpcmVjdGl2ZSB9IGZyb20gJy4vcXVlcnktZmllbGQuZGlyZWN0aXZlJztcbmltcG9ydCB7IFF1ZXJ5RW50aXR5RGlyZWN0aXZlIH0gZnJvbSAnLi9xdWVyeS1lbnRpdHkuZGlyZWN0aXZlJztcbmltcG9ydCB7IFF1ZXJ5U3dpdGNoR3JvdXBEaXJlY3RpdmUgfSBmcm9tICcuL3F1ZXJ5LXN3aXRjaC1ncm91cC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgUXVlcnlCdXR0b25Hcm91cERpcmVjdGl2ZSB9IGZyb20gJy4vcXVlcnktYnV0dG9uLWdyb3VwLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBRdWVyeUlucHV0RGlyZWN0aXZlIH0gZnJvbSAnLi9xdWVyeS1pbnB1dC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgUXVlcnlSZW1vdmVCdXR0b25EaXJlY3RpdmUgfSBmcm9tICcuL3F1ZXJ5LXJlbW92ZS1idXR0b24uZGlyZWN0aXZlJztcbmltcG9ydCB7IFF1ZXJ5RW1wdHlXYXJuaW5nRGlyZWN0aXZlIH0gZnJvbSAnLi9xdWVyeS1lbXB0eS13YXJuaW5nLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBRdWVyeUFycm93SWNvbkRpcmVjdGl2ZSB9IGZyb20gJy4vcXVlcnktYXJyb3ctaWNvbi5kaXJlY3RpdmUnO1xuaW1wb3J0IHtcbiAgQnV0dG9uR3JvdXBDb250ZXh0LFxuICBFbnRpdHksXG4gIEZpZWxkLFxuICBTd2l0Y2hHcm91cENvbnRleHQsXG4gIEVudGl0eUNvbnRleHQsXG4gIEZpZWxkQ29udGV4dCxcbiAgSW5wdXRDb250ZXh0LFxuICBMb2NhbFJ1bGVNZXRhLFxuICBPcGVyYXRvckNvbnRleHQsXG4gIE9wdGlvbixcbiAgUXVlcnlCdWlsZGVyQ2xhc3NOYW1lcyxcbiAgUXVlcnlCdWlsZGVyQ29uZmlnLFxuICBSZW1vdmVCdXR0b25Db250ZXh0LFxuICBBcnJvd0ljb25Db250ZXh0LFxuICBSdWxlLFxuICBSdWxlU2V0LFxuICBFbXB0eVdhcm5pbmdDb250ZXh0LFxufSBmcm9tICcuL3F1ZXJ5LWJ1aWxkZXIuaW50ZXJmYWNlcyc7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgZm9yd2FyZFJlZixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25Jbml0LFxuICBRdWVyeUxpc3QsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG4gIEVsZW1lbnRSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmV4cG9ydCBjb25zdCBDT05UUk9MX1ZBTFVFX0FDQ0VTU09SOiBhbnkgPSB7XG4gIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBRdWVyeUJ1aWxkZXJDb21wb25lbnQpLFxuICBtdWx0aTogdHJ1ZVxufTtcblxuZXhwb3J0IGNvbnN0IFZBTElEQVRPUjogYW55ID0ge1xuICBwcm92aWRlOiBOR19WQUxJREFUT1JTLFxuICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBRdWVyeUJ1aWxkZXJDb21wb25lbnQpLFxuICBtdWx0aTogdHJ1ZVxufTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncXVlcnktYnVpbGRlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9xdWVyeS1idWlsZGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcXVlcnktYnVpbGRlci5jb21wb25lbnQuc2NzcyddLFxuICBwcm92aWRlcnM6IFtDT05UUk9MX1ZBTFVFX0FDQ0VTU09SLCBWQUxJREFUT1JdXG59KVxuZXhwb3J0IGNsYXNzIFF1ZXJ5QnVpbGRlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBDb250cm9sVmFsdWVBY2Nlc3NvciwgVmFsaWRhdG9yIHtcbiAgcHVibGljIGZpZWxkcyE6IEZpZWxkW107XG4gIHB1YmxpYyBmaWx0ZXJGaWVsZHMhOiBGaWVsZFtdO1xuICBwdWJsaWMgZW50aXRpZXMhOiBFbnRpdHlbXSB8IG51bGw7XG4gIHB1YmxpYyBkZWZhdWx0Q2xhc3NOYW1lczogUXVlcnlCdWlsZGVyQ2xhc3NOYW1lcyA9IHtcbiAgICBhcnJvd0ljb25CdXR0b246ICdxLWFycm93LWljb24tYnV0dG9uJyxcbiAgICBhcnJvd0ljb246ICdxLWljb24gcS1hcnJvdy1pY29uJyxcbiAgICByZW1vdmVJY29uOiAncS1pY29uIHEtcmVtb3ZlLWljb24nLFxuICAgIGFkZEljb246ICdxLWljb24gcS1hZGQtaWNvbicsXG4gICAgYnV0dG9uOiAncS1idXR0b24nLFxuICAgIGJ1dHRvbkdyb3VwOiAncS1idXR0b24tZ3JvdXAnLFxuICAgIHJlbW92ZUJ1dHRvbjogJ3EtcmVtb3ZlLWJ1dHRvbicsXG4gICAgc3dpdGNoR3JvdXA6ICdxLXN3aXRjaC1ncm91cCcsXG4gICAgc3dpdGNoTGFiZWw6ICdxLXN3aXRjaC1sYWJlbCcsXG4gICAgc3dpdGNoUmFkaW86ICdxLXN3aXRjaC1yYWRpbycsXG4gICAgcmlnaHRBbGlnbjogJ3EtcmlnaHQtYWxpZ24nLFxuICAgIHRyYW5zaXRpb246ICdxLXRyYW5zaXRpb24nLFxuICAgIGNvbGxhcHNlZDogJ3EtY29sbGFwc2VkJyxcbiAgICB0cmVlQ29udGFpbmVyOiAncS10cmVlLWNvbnRhaW5lcicsXG4gICAgdHJlZTogJ3EtdHJlZScsXG4gICAgcm93OiAncS1yb3cnLFxuICAgIGNvbm5lY3RvcjogJ3EtY29ubmVjdG9yJyxcbiAgICBydWxlOiAncS1ydWxlJyxcbiAgICBydWxlU2V0OiAncS1ydWxlc2V0JyxcbiAgICBpbnZhbGlkUnVsZVNldDogJ3EtaW52YWxpZC1ydWxlc2V0JyxcbiAgICBlbXB0eVdhcm5pbmc6ICdxLWVtcHR5LXdhcm5pbmcnLFxuICAgIGZpZWxkQ29udHJvbDogJ3EtZmllbGQtY29udHJvbCcsXG4gICAgZmllbGRDb250cm9sU2l6ZTogJ3EtY29udHJvbC1zaXplJyxcbiAgICBlbnRpdHlDb250cm9sOiAncS1lbnRpdHktY29udHJvbCcsXG4gICAgZW50aXR5Q29udHJvbFNpemU6ICdxLWNvbnRyb2wtc2l6ZScsXG4gICAgb3BlcmF0b3JDb250cm9sOiAncS1vcGVyYXRvci1jb250cm9sJyxcbiAgICBvcGVyYXRvckNvbnRyb2xTaXplOiAncS1jb250cm9sLXNpemUnLFxuICAgIGlucHV0Q29udHJvbDogJ3EtaW5wdXQtY29udHJvbCcsXG4gICAgaW5wdXRDb250cm9sU2l6ZTogJ3EtY29udHJvbC1zaXplJ1xuICB9O1xuICBwdWJsaWMgZGVmYXVsdE9wZXJhdG9yTWFwOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZ1tdIH0gPSB7XG4gICAgc3RyaW5nOiBbJz0nLCAnIT0nLCAnY29udGFpbnMnLCAnbGlrZSddLFxuICAgIG51bWJlcjogWyc9JywgJyE9JywgJz4nLCAnPj0nLCAnPCcsICc8PSddLFxuICAgIHRpbWU6IFsnPScsICchPScsICc+JywgJz49JywgJzwnLCAnPD0nXSxcbiAgICBkYXRlOiBbJz0nLCAnIT0nLCAnPicsICc+PScsICc8JywgJzw9J10sXG4gICAgY2F0ZWdvcnk6IFsnPScsICchPScsICdpbicsICdub3QgaW4nXSxcbiAgICBib29sZWFuOiBbJz0nXVxuICB9O1xuICBASW5wdXQoKSBkaXNhYmxlZCE6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGRhdGE6IFJ1bGVTZXQgPSB7IGNvbmRpdGlvbjogJ2FuZCcsIHJ1bGVzOiBbXSB9O1xuXG4gIC8vIEZvciBDb250cm9sVmFsdWVBY2Nlc3NvciBpbnRlcmZhY2VcbiAgcHVibGljIG9uQ2hhbmdlQ2FsbGJhY2shOiAoKSA9PiB2b2lkO1xuICBwdWJsaWMgb25Ub3VjaGVkQ2FsbGJhY2shOiAoKSA9PiBhbnk7XG5cbiAgQElucHV0KCkgYWxsb3dSdWxlc2V0OiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgYWxsb3dDb2xsYXBzZTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBlbXB0eU1lc3NhZ2U6IHN0cmluZyA9ICdBIHJ1bGVzZXQgY2Fubm90IGJlIGVtcHR5LiBQbGVhc2UgYWRkIGEgcnVsZSBvciByZW1vdmUgaXQgYWxsIHRvZ2V0aGVyLic7XG4gIEBJbnB1dCgpIGNsYXNzTmFtZXMhOiBRdWVyeUJ1aWxkZXJDbGFzc05hbWVzO1xuICBASW5wdXQoKSBvcGVyYXRvck1hcCE6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfTtcbiAgQElucHV0KCkgcGFyZW50VmFsdWUhOiBSdWxlU2V0O1xuICBASW5wdXQoKSBjb25maWc6IFF1ZXJ5QnVpbGRlckNvbmZpZyA9IHsgZmllbGRzOiB7fSB9O1xuICBASW5wdXQoKSBwYXJlbnRBcnJvd0ljb25UZW1wbGF0ZSE6IFF1ZXJ5QXJyb3dJY29uRGlyZWN0aXZlO1xuICBASW5wdXQoKSBwYXJlbnRJbnB1dFRlbXBsYXRlcyE6IFF1ZXJ5TGlzdDxRdWVyeUlucHV0RGlyZWN0aXZlPjtcbiAgQElucHV0KCkgcGFyZW50T3BlcmF0b3JUZW1wbGF0ZSE6IFF1ZXJ5T3BlcmF0b3JEaXJlY3RpdmU7XG4gIEBJbnB1dCgpIHBhcmVudEZpZWxkVGVtcGxhdGUhOiBRdWVyeUZpZWxkRGlyZWN0aXZlO1xuICBASW5wdXQoKSBwYXJlbnRFbnRpdHlUZW1wbGF0ZSE6IFF1ZXJ5RW50aXR5RGlyZWN0aXZlO1xuICBASW5wdXQoKSBwYXJlbnRTd2l0Y2hHcm91cFRlbXBsYXRlITogUXVlcnlTd2l0Y2hHcm91cERpcmVjdGl2ZTtcbiAgQElucHV0KCkgcGFyZW50QnV0dG9uR3JvdXBUZW1wbGF0ZSE6IFF1ZXJ5QnV0dG9uR3JvdXBEaXJlY3RpdmU7XG4gIEBJbnB1dCgpIHBhcmVudFJlbW92ZUJ1dHRvblRlbXBsYXRlITogUXVlcnlSZW1vdmVCdXR0b25EaXJlY3RpdmU7XG4gIEBJbnB1dCgpIHBhcmVudEVtcHR5V2FybmluZ1RlbXBsYXRlITogUXVlcnlFbXB0eVdhcm5pbmdEaXJlY3RpdmU7XG4gIEBJbnB1dCgpIHBhcmVudENoYW5nZUNhbGxiYWNrITogKCkgPT4gdm9pZDtcbiAgQElucHV0KCkgcGFyZW50VG91Y2hlZENhbGxiYWNrITogKCkgPT4gdm9pZDtcbiAgQElucHV0KCkgcGVyc2lzdFZhbHVlT25GaWVsZENoYW5nZTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIEBWaWV3Q2hpbGQoJ3RyZWVDb250YWluZXInLCB7c3RhdGljOiB0cnVlfSkgdHJlZUNvbnRhaW5lciE6IEVsZW1lbnRSZWY7XG5cbiAgQENvbnRlbnRDaGlsZChRdWVyeUJ1dHRvbkdyb3VwRGlyZWN0aXZlKSBidXR0b25Hcm91cFRlbXBsYXRlITogUXVlcnlCdXR0b25Hcm91cERpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZChRdWVyeVN3aXRjaEdyb3VwRGlyZWN0aXZlKSBzd2l0Y2hHcm91cFRlbXBsYXRlITogUXVlcnlTd2l0Y2hHcm91cERpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZChRdWVyeUZpZWxkRGlyZWN0aXZlKSBmaWVsZFRlbXBsYXRlITogUXVlcnlGaWVsZERpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZChRdWVyeUVudGl0eURpcmVjdGl2ZSkgZW50aXR5VGVtcGxhdGUhOiBRdWVyeUVudGl0eURpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZChRdWVyeU9wZXJhdG9yRGlyZWN0aXZlKSBvcGVyYXRvclRlbXBsYXRlITogUXVlcnlPcGVyYXRvckRpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZChRdWVyeVJlbW92ZUJ1dHRvbkRpcmVjdGl2ZSkgcmVtb3ZlQnV0dG9uVGVtcGxhdGUhOiBRdWVyeVJlbW92ZUJ1dHRvbkRpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZChRdWVyeUVtcHR5V2FybmluZ0RpcmVjdGl2ZSkgZW1wdHlXYXJuaW5nVGVtcGxhdGUhOiBRdWVyeUVtcHR5V2FybmluZ0RpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZHJlbihRdWVyeUlucHV0RGlyZWN0aXZlKSBpbnB1dFRlbXBsYXRlcyE6IFF1ZXJ5TGlzdDxRdWVyeUlucHV0RGlyZWN0aXZlPjtcbiAgQENvbnRlbnRDaGlsZChRdWVyeUFycm93SWNvbkRpcmVjdGl2ZSkgYXJyb3dJY29uVGVtcGxhdGUhOiBRdWVyeUFycm93SWNvbkRpcmVjdGl2ZTtcblxuICBwcml2YXRlIGRlZmF1bHRUZW1wbGF0ZVR5cGVzOiBzdHJpbmdbXSA9IFtcbiAgICAnc3RyaW5nJywgJ251bWJlcicsICd0aW1lJywgJ2RhdGUnLCAnY2F0ZWdvcnknLCAnYm9vbGVhbicsICdtdWx0aXNlbGVjdCddO1xuICBwcml2YXRlIGRlZmF1bHRQZXJzaXN0VmFsdWVUeXBlczogc3RyaW5nW10gPSBbXG4gICAgJ3N0cmluZycsICdudW1iZXInLCAndGltZScsICdkYXRlJywgJ2Jvb2xlYW4nXTtcbiAgcHJpdmF0ZSBkZWZhdWx0RW1wdHlMaXN0OiBhbnlbXSA9IFtdO1xuICBwcml2YXRlIG9wZXJhdG9yc0NhY2hlITogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9O1xuICBwcml2YXRlIGlucHV0Q29udGV4dENhY2hlID0gbmV3IE1hcDxSdWxlLCBJbnB1dENvbnRleHQ+KCk7XG4gIHByaXZhdGUgb3BlcmF0b3JDb250ZXh0Q2FjaGUgPSBuZXcgTWFwPFJ1bGUsIE9wZXJhdG9yQ29udGV4dD4oKTtcbiAgcHJpdmF0ZSBmaWVsZENvbnRleHRDYWNoZSA9IG5ldyBNYXA8UnVsZSwgRmllbGRDb250ZXh0PigpO1xuICBwcml2YXRlIGVudGl0eUNvbnRleHRDYWNoZSA9IG5ldyBNYXA8UnVsZSwgRW50aXR5Q29udGV4dD4oKTtcbiAgcHJpdmF0ZSByZW1vdmVCdXR0b25Db250ZXh0Q2FjaGUgPSBuZXcgTWFwPFJ1bGUsIFJlbW92ZUJ1dHRvbkNvbnRleHQ+KCk7XG4gIHByaXZhdGUgYnV0dG9uR3JvdXBDb250ZXh0ITogYW55O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7IH1cblxuICAvLyAtLS0tLS0tLS0tT25Jbml0IEltcGxlbWVudGF0aW9uLS0tLS0tLS0tLVxuXG4gIG5nT25Jbml0KCkgeyB9XG5cbiAgLy8gLS0tLS0tLS0tLU9uQ2hhbmdlcyBJbXBsZW1lbnRhdGlvbi0tLS0tLS0tLS1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5jb25maWc7XG4gICAgY29uc3QgdHlwZSA9IHR5cGVvZiBjb25maWc7XG4gICAgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICB0aGlzLmZpZWxkcyA9IE9iamVjdC5rZXlzKGNvbmZpZy5maWVsZHMpLm1hcCgodmFsdWUpID0+IHtcbiAgICAgICAgY29uc3QgZmllbGQgPSBjb25maWcuZmllbGRzW3ZhbHVlXTtcbiAgICAgICAgZmllbGQudmFsdWUgPSBmaWVsZC52YWx1ZSB8fCB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIGZpZWxkO1xuICAgICAgfSk7XG4gICAgICBpZiAoY29uZmlnLmVudGl0aWVzKSB7XG4gICAgICAgIHRoaXMuZW50aXRpZXMgPSBPYmplY3Qua2V5cyhjb25maWcuZW50aXRpZXMpLm1hcCgodmFsdWUpID0+IHtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBjb25maWcuZW50aXRpZXMhW3ZhbHVlXTtcbiAgICAgICAgICBlbnRpdHkudmFsdWUgPSBlbnRpdHkudmFsdWUgfHwgdmFsdWU7XG4gICAgICAgICAgcmV0dXJuIGVudGl0eTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmVudGl0aWVzID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRoaXMub3BlcmF0b3JzQ2FjaGUgPSB7fTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAnY29uZmlnJyBtdXN0IGJlIGEgdmFsaWQgb2JqZWN0LCBnb3QgJHt0eXBlfSBpbnN0ZWFkLmApO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS1WYWxpZGF0b3IgSW1wbGVtZW50YXRpb24tLS0tLS0tLS0tXG5cbiAgdmFsaWRhdGUoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xuICAgIGNvbnN0IGVycm9yczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9O1xuICAgIGNvbnN0IHJ1bGVFcnJvclN0b3JlOiBhbnlbXSA9IFtdO1xuICAgIGxldCBoYXNFcnJvcnMgPSBmYWxzZTtcblxuICAgIGlmICghdGhpcy5jb25maWcuYWxsb3dFbXB0eVJ1bGVzZXRzICYmIHRoaXMuY2hlY2tFbXB0eVJ1bGVJblJ1bGVzZXQodGhpcy5kYXRhKSkge1xuICAgICAgZXJyb3JzWydlbXB0eSddID0gJ0VtcHR5IHJ1bGVzZXRzIGFyZSBub3QgYWxsb3dlZC4nO1xuICAgICAgaGFzRXJyb3JzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLnZhbGlkYXRlUnVsZXNJblJ1bGVzZXQodGhpcy5kYXRhLCBydWxlRXJyb3JTdG9yZSk7XG5cbiAgICBpZiAocnVsZUVycm9yU3RvcmUubGVuZ3RoKSB7XG4gICAgICBlcnJvcnNbJ3J1bGVzJ10gPSBydWxlRXJyb3JTdG9yZTtcbiAgICAgIGhhc0Vycm9ycyA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBoYXNFcnJvcnMgPyBlcnJvcnMgOiBudWxsO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLUNvbnRyb2xWYWx1ZUFjY2Vzc29yIEltcGxlbWVudGF0aW9uLS0tLS0tLS0tLVxuXG4gIEBJbnB1dCgpXG4gIGdldCB2YWx1ZSgpOiBSdWxlU2V0IHtcbiAgICByZXR1cm4gdGhpcy5kYXRhO1xuICB9XG4gIHNldCB2YWx1ZSh2YWx1ZTogUnVsZVNldCkge1xuICAgIC8vIFdoZW4gY29tcG9uZW50IGlzIGluaXRpYWxpemVkIHdpdGhvdXQgYSBmb3JtQ29udHJvbCwgbnVsbCBpcyBwYXNzZWQgdG8gdmFsdWVcbiAgICB0aGlzLmRhdGEgPSB2YWx1ZSB8fCB7IGNvbmRpdGlvbjogJ2FuZCcsIHJ1bGVzOiBbXSB9O1xuICAgIHRoaXMuaGFuZGxlRGF0YUNoYW5nZSgpO1xuICB9XG5cbiAgd3JpdGVWYWx1ZShvYmo6IGFueSk6IHZvaWQge1xuICAgIHRoaXMudmFsdWUgPSBvYmo7XG4gIH1cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vbkNoYW5nZUNhbGxiYWNrID0gKCkgPT4gZm4odGhpcy5kYXRhKTtcbiAgfVxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoZWRDYWxsYmFjayA9ICgpID0+IGZuKHRoaXMuZGF0YSk7XG4gIH1cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tRU5ELS0tLS0tLS0tLVxuXG4gIGdldERpc2FibGVkU3RhdGUgPSAoKTogYm9vbGVhbiA9PiB7XG4gICAgcmV0dXJuIHRoaXMuZGlzYWJsZWQ7XG4gIH1cblxuICBmaW5kVGVtcGxhdGVGb3JSdWxlKHJ1bGU6IGFueSk6IGFueSB7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMuZ2V0SW5wdXRUeXBlKHJ1bGUuZmllbGQsIHJ1bGUub3BlcmF0b3IhKTtcbiAgICBpZiAodHlwZSkge1xuICAgICAgY29uc3QgcXVlcnlJbnB1dCA9IHRoaXMuZmluZFF1ZXJ5SW5wdXQodHlwZSk7XG4gICAgICBpZiAocXVlcnlJbnB1dCkge1xuICAgICAgICByZXR1cm4gcXVlcnlJbnB1dC50ZW1wbGF0ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLmRlZmF1bHRUZW1wbGF0ZVR5cGVzLmluZGV4T2YodHlwZSkgPT09IC0xKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGBDb3VsZCBub3QgZmluZCB0ZW1wbGF0ZSBmb3IgZmllbGQgd2l0aCB0eXBlOiAke3R5cGV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZmluZFF1ZXJ5SW5wdXQodHlwZTogc3RyaW5nKTogYW55IHtcbiAgICBjb25zdCB0ZW1wbGF0ZXMgPSB0aGlzLnBhcmVudElucHV0VGVtcGxhdGVzIHx8IHRoaXMuaW5wdXRUZW1wbGF0ZXM7XG4gICAgcmV0dXJuIHRlbXBsYXRlcy5maW5kKChpdGVtKSA9PiBpdGVtLnF1ZXJ5SW5wdXRUeXBlID09PSB0eXBlKTtcbiAgfVxuXG4gIGdldE9wZXJhdG9ycyhmaWVsZDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGlmICh0aGlzLm9wZXJhdG9yc0NhY2hlW2ZpZWxkXSkge1xuICAgICAgcmV0dXJuIHRoaXMub3BlcmF0b3JzQ2FjaGVbZmllbGRdO1xuICAgIH1cbiAgICBsZXQgb3BlcmF0b3JzID0gdGhpcy5kZWZhdWx0RW1wdHlMaXN0O1xuICAgIGNvbnN0IGZpZWxkT2JqZWN0ID0gdGhpcy5jb25maWcuZmllbGRzW2ZpZWxkXTtcblxuICAgIGlmICh0aGlzLmNvbmZpZy5nZXRPcGVyYXRvcnMpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5nZXRPcGVyYXRvcnMoZmllbGQsIGZpZWxkT2JqZWN0KTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlID0gZmllbGRPYmplY3QudHlwZTtcblxuICAgIGlmIChmaWVsZE9iamVjdCAmJiBmaWVsZE9iamVjdC5vcGVyYXRvcnMpIHtcbiAgICAgIG9wZXJhdG9ycyA9IGZpZWxkT2JqZWN0Lm9wZXJhdG9ycztcbiAgICB9IGVsc2UgaWYgKHR5cGUpIHtcbiAgICAgIG9wZXJhdG9ycyA9ICh0aGlzLm9wZXJhdG9yTWFwICYmIHRoaXMub3BlcmF0b3JNYXBbdHlwZV0pIHx8IHRoaXMuZGVmYXVsdE9wZXJhdG9yTWFwW3R5cGVdIHx8IHRoaXMuZGVmYXVsdEVtcHR5TGlzdDtcbiAgICAgIGlmIChvcGVyYXRvcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICBgTm8gb3BlcmF0b3JzIGZvdW5kIGZvciBmaWVsZCAnJHtmaWVsZH0nIHdpdGggdHlwZSAke2ZpZWxkT2JqZWN0LnR5cGV9LiBgICtcbiAgICAgICAgICBgUGxlYXNlIGRlZmluZSBhbiAnb3BlcmF0b3JzJyBwcm9wZXJ0eSBvbiB0aGUgZmllbGQgb3IgdXNlIHRoZSAnb3BlcmF0b3JNYXAnIGJpbmRpbmcgdG8gZml4IHRoaXMuYCk7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGRPYmplY3QubnVsbGFibGUpIHtcbiAgICAgICAgb3BlcmF0b3JzID0gb3BlcmF0b3JzLmNvbmNhdChbJ2lzIG51bGwnLCAnaXMgbm90IG51bGwnXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybihgTm8gJ3R5cGUnIHByb3BlcnR5IGZvdW5kIG9uIGZpZWxkOiAnJHtmaWVsZH0nYCk7XG4gICAgfVxuXG4gICAgLy8gQ2FjaGUgcmVmZXJlbmNlIHRvIGFycmF5IG9iamVjdCwgc28gaXQgd29uJ3QgYmUgY29tcHV0ZWQgbmV4dCB0aW1lIGFuZCB0cmlnZ2VyIGEgcmVyZW5kZXIuXG4gICAgdGhpcy5vcGVyYXRvcnNDYWNoZVtmaWVsZF0gPSBvcGVyYXRvcnM7XG4gICAgcmV0dXJuIG9wZXJhdG9ycztcbiAgfVxuXG4gIGdldEZpZWxkcyhlbnRpdHk6IHN0cmluZyk6IEZpZWxkW10ge1xuICAgIGlmICh0aGlzLmVudGl0aWVzICYmIGVudGl0eSkge1xuICAgICAgcmV0dXJuIHRoaXMuZmllbGRzLmZpbHRlcigoZmllbGQpID0+IHtcbiAgICAgICAgcmV0dXJuIGZpZWxkICYmIGZpZWxkLmVudGl0eSA9PT0gZW50aXR5O1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmZpZWxkcztcbiAgICB9XG4gIH1cblxuICBnZXRJbnB1dFR5cGUoZmllbGQ6IHN0cmluZywgb3BlcmF0b3I6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICh0aGlzLmNvbmZpZy5nZXRJbnB1dFR5cGUpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5nZXRJbnB1dFR5cGUoZmllbGQsIG9wZXJhdG9yKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuY29uZmlnLmZpZWxkc1tmaWVsZF0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gY29uZmlndXJhdGlvbiBmb3IgZmllbGQgJyR7ZmllbGR9JyBjb3VsZCBiZSBmb3VuZCEgUGxlYXNlIGFkZCBpdCB0byBjb25maWcuZmllbGRzLmApO1xuICAgIH1cblxuICAgIGNvbnN0IHR5cGUgPSB0aGlzLmNvbmZpZy5maWVsZHNbZmllbGRdLnR5cGU7XG4gICAgc3dpdGNoIChvcGVyYXRvcikge1xuICAgICAgY2FzZSAnaXMgbnVsbCc6XG4gICAgICBjYXNlICdpcyBub3QgbnVsbCc6XG4gICAgICAgIHJldHVybiBudWxsOyAgLy8gTm8gZGlzcGxheWVkIGNvbXBvbmVudFxuICAgICAgY2FzZSAnaW4nOlxuICAgICAgY2FzZSAnbm90IGluJzpcbiAgICAgICAgcmV0dXJuIHR5cGUgPT09ICdjYXRlZ29yeScgfHwgdHlwZSA9PT0gJ2Jvb2xlYW4nID8gJ211bHRpc2VsZWN0JyA6IHR5cGU7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdHlwZTtcbiAgICB9XG4gIH1cblxuICBnZXRPcHRpb25zKGZpZWxkOiBzdHJpbmcpOiBPcHRpb25bXSB7XG4gICAgaWYgKHRoaXMuY29uZmlnLmdldE9wdGlvbnMpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5nZXRPcHRpb25zKGZpZWxkKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmZpZWxkc1tmaWVsZF0ub3B0aW9ucyB8fCB0aGlzLmRlZmF1bHRFbXB0eUxpc3Q7XG4gIH1cblxuICBnZXRDbGFzc05hbWVzKC4uLmFyZ3M6IGFueSk6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IGNsc0xvb2t1cDogUXVlcnlCdWlsZGVyQ2xhc3NOYW1lcyA9IHRoaXMuY2xhc3NOYW1lcyA/IHRoaXMuY2xhc3NOYW1lcyA6IHRoaXMuZGVmYXVsdENsYXNzTmFtZXM7XG4gICAgY29uc3QgY2xhc3NOYW1lcyA9IGFyZ3NcbiAgICAgIC5tYXAoKGlkOiBrZXlvZiBRdWVyeUJ1aWxkZXJDbGFzc05hbWVzKSA9PiBjbHNMb29rdXBbaWRdIHx8IHRoaXMuZGVmYXVsdENsYXNzTmFtZXNbaWRdKVxuICAgICAgLmZpbHRlcigoYzogYW55KTogYyBpcyBzdHJpbmcgPT4gISFjKTtcbiAgICByZXR1cm4gY2xhc3NOYW1lcy5sZW5ndGggPyBjbGFzc05hbWVzLmpvaW4oJyAnKSA6IG51bGw7XG4gIH1cblxuICBnZXREZWZhdWx0RmllbGQoZW50aXR5OiBFbnRpdHkpOiBGaWVsZCB8IG51bGwge1xuICAgIGlmICghZW50aXR5KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGVsc2UgaWYgKGVudGl0eS5kZWZhdWx0RmllbGQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0RGVmYXVsdFZhbHVlKGVudGl0eS5kZWZhdWx0RmllbGQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBlbnRpdHlGaWVsZHMgPSB0aGlzLmZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PiB7XG4gICAgICAgIHJldHVybiBmaWVsZCAmJiBmaWVsZC5lbnRpdHkgPT09IGVudGl0eS52YWx1ZTtcbiAgICAgIH0pO1xuICAgICAgaWYgKGVudGl0eUZpZWxkcyAmJiBlbnRpdHlGaWVsZHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBlbnRpdHlGaWVsZHNbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oYE5vIGZpZWxkcyBmb3VuZCBmb3IgZW50aXR5ICcke2VudGl0eS5uYW1lfScuIGAgK1xuICAgICAgICAgIGBBICdkZWZhdWx0T3BlcmF0b3InIGlzIGFsc28gbm90IHNwZWNpZmllZCBvbiB0aGUgZmllbGQgY29uZmlnLiBPcGVyYXRvciB2YWx1ZSB3aWxsIGRlZmF1bHQgdG8gbnVsbC5gKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0RGVmYXVsdE9wZXJhdG9yKGZpZWxkOiBGaWVsZCk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmIChmaWVsZCAmJiBmaWVsZC5kZWZhdWx0T3BlcmF0b3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0RGVmYXVsdFZhbHVlKGZpZWxkLmRlZmF1bHRPcGVyYXRvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG9wZXJhdG9ycyA9IHRoaXMuZ2V0T3BlcmF0b3JzKGZpZWxkLnZhbHVlISk7XG4gICAgICBpZiAob3BlcmF0b3JzICYmIG9wZXJhdG9ycy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG9wZXJhdG9yc1swXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgTm8gb3BlcmF0b3JzIGZvdW5kIGZvciBmaWVsZCAnJHtmaWVsZC52YWx1ZX0nLiBgICtcbiAgICAgICAgICBgQSAnZGVmYXVsdE9wZXJhdG9yJyBpcyBhbHNvIG5vdCBzcGVjaWZpZWQgb24gdGhlIGZpZWxkIGNvbmZpZy4gT3BlcmF0b3IgdmFsdWUgd2lsbCBkZWZhdWx0IHRvIG51bGwuYCk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFkZFJ1bGUocGFyZW50PzogUnVsZVNldCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcGFyZW50ID0gcGFyZW50IHx8IHRoaXMuZGF0YTtcbiAgICBpZiAodGhpcy5jb25maWcuYWRkUnVsZSkge1xuICAgICAgdGhpcy5jb25maWcuYWRkUnVsZShwYXJlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBmaWVsZCA9IHRoaXMuZmllbGRzWzBdO1xuICAgICAgcGFyZW50LnJ1bGVzID0gcGFyZW50LnJ1bGVzLmNvbmNhdChbe1xuICAgICAgICBmaWVsZDogZmllbGQudmFsdWUhLFxuICAgICAgICBvcGVyYXRvcjogdGhpcy5nZXREZWZhdWx0T3BlcmF0b3IoZmllbGQpISxcbiAgICAgICAgdmFsdWU6IHRoaXMuZ2V0RGVmYXVsdFZhbHVlKGZpZWxkLmRlZmF1bHRWYWx1ZSksXG4gICAgICAgIGVudGl0eTogZmllbGQuZW50aXR5XG4gICAgICB9XSk7XG4gICAgfVxuXG4gICAgdGhpcy5oYW5kbGVUb3VjaGVkKCk7XG4gICAgdGhpcy5oYW5kbGVEYXRhQ2hhbmdlKCk7XG4gIH1cblxuICByZW1vdmVSdWxlKHJ1bGU6IGFueSwgcGFyZW50PzogUnVsZVNldCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcGFyZW50ID0gcGFyZW50IHx8IHRoaXMuZGF0YTtcbiAgICBpZiAodGhpcy5jb25maWcucmVtb3ZlUnVsZSkge1xuICAgICAgdGhpcy5jb25maWcucmVtb3ZlUnVsZShydWxlLCBwYXJlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJlbnQucnVsZXMgPSBwYXJlbnQucnVsZXMuZmlsdGVyKChyKSA9PiByICE9PSBydWxlKTtcbiAgICB9XG4gICAgdGhpcy5pbnB1dENvbnRleHRDYWNoZS5kZWxldGUocnVsZSk7XG4gICAgdGhpcy5vcGVyYXRvckNvbnRleHRDYWNoZS5kZWxldGUocnVsZSk7XG4gICAgdGhpcy5maWVsZENvbnRleHRDYWNoZS5kZWxldGUocnVsZSk7XG4gICAgdGhpcy5lbnRpdHlDb250ZXh0Q2FjaGUuZGVsZXRlKHJ1bGUpO1xuICAgIHRoaXMucmVtb3ZlQnV0dG9uQ29udGV4dENhY2hlLmRlbGV0ZShydWxlKTtcblxuICAgIHRoaXMuaGFuZGxlVG91Y2hlZCgpO1xuICAgIHRoaXMuaGFuZGxlRGF0YUNoYW5nZSgpO1xuICB9XG5cbiAgYWRkUnVsZVNldChwYXJlbnQ/OiBSdWxlU2V0KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwYXJlbnQgPSBwYXJlbnQgfHwgdGhpcy5kYXRhO1xuICAgIGlmICh0aGlzLmNvbmZpZy5hZGRSdWxlU2V0KSB7XG4gICAgICB0aGlzLmNvbmZpZy5hZGRSdWxlU2V0KHBhcmVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcmVudC5ydWxlcyA9IHBhcmVudC5ydWxlcy5jb25jYXQoW3sgY29uZGl0aW9uOiAnYW5kJywgcnVsZXM6IFtdIH1dKTtcbiAgICB9XG5cbiAgICB0aGlzLmhhbmRsZVRvdWNoZWQoKTtcbiAgICB0aGlzLmhhbmRsZURhdGFDaGFuZ2UoKTtcbiAgfVxuXG4gIHJlbW92ZVJ1bGVTZXQocnVsZXNldD86IFJ1bGVTZXQsIHBhcmVudD86IFJ1bGVTZXQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHJ1bGVzZXQgPSBydWxlc2V0IHx8IHRoaXMuZGF0YTtcbiAgICBwYXJlbnQgPSBwYXJlbnQgfHwgdGhpcy5wYXJlbnRWYWx1ZTtcbiAgICBpZiAodGhpcy5jb25maWcucmVtb3ZlUnVsZVNldCkge1xuICAgICAgdGhpcy5jb25maWcucmVtb3ZlUnVsZVNldChydWxlc2V0LCBwYXJlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJlbnQucnVsZXMgPSBwYXJlbnQucnVsZXMuZmlsdGVyKChyKSA9PiByICE9PSBydWxlc2V0KTtcbiAgICB9XG5cbiAgICB0aGlzLmhhbmRsZVRvdWNoZWQoKTtcbiAgICB0aGlzLmhhbmRsZURhdGFDaGFuZ2UoKTtcbiAgfVxuXG4gIHRyYW5zaXRpb25FbmQoZTogRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLnRyZWVDb250YWluZXIubmF0aXZlRWxlbWVudC5zdHlsZS5tYXhIZWlnaHQgPSBudWxsO1xuICB9XG5cbiAgdG9nZ2xlQ29sbGFwc2UoKTogdm9pZCB7XG4gICAgdGhpcy5jb21wdXRlZFRyZWVDb250YWluZXJIZWlnaHQoKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuZGF0YS5jb2xsYXBzZWQgPSAhdGhpcy5kYXRhLmNvbGxhcHNlZDtcbiAgICB9LCAxMDApO1xuICB9XG5cbiAgY29tcHV0ZWRUcmVlQ29udGFpbmVySGVpZ2h0KCk6IHZvaWQge1xuICAgIGNvbnN0IG5hdGl2ZUVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gdGhpcy50cmVlQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKG5hdGl2ZUVsZW1lbnQgJiYgbmF0aXZlRWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZCkge1xuICAgICAgbmF0aXZlRWxlbWVudC5zdHlsZS5tYXhIZWlnaHQgPSAobmF0aXZlRWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZC5jbGllbnRIZWlnaHQgKyA4KSArICdweCc7XG4gICAgfVxuICB9XG5cbiAgY2hhbmdlQ29uZGl0aW9uKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZGF0YS5jb25kaXRpb24gPSB2YWx1ZTtcbiAgICB0aGlzLmhhbmRsZVRvdWNoZWQoKTtcbiAgICB0aGlzLmhhbmRsZURhdGFDaGFuZ2UoKTtcbiAgfVxuXG4gIGNoYW5nZU9wZXJhdG9yKHJ1bGU6IFJ1bGUpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5jb2VyY2VWYWx1ZUZvck9wZXJhdG9yKSB7XG4gICAgICBydWxlLnZhbHVlID0gdGhpcy5jb25maWcuY29lcmNlVmFsdWVGb3JPcGVyYXRvcihydWxlLm9wZXJhdG9yISwgcnVsZS52YWx1ZSwgcnVsZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJ1bGUudmFsdWUgPSB0aGlzLmNvZXJjZVZhbHVlRm9yT3BlcmF0b3IocnVsZS5vcGVyYXRvciEsIHJ1bGUudmFsdWUsIHJ1bGUpO1xuICAgIH1cblxuICAgIHRoaXMuaGFuZGxlVG91Y2hlZCgpO1xuICAgIHRoaXMuaGFuZGxlRGF0YUNoYW5nZSgpO1xuICB9XG5cbiAgY29lcmNlVmFsdWVGb3JPcGVyYXRvcihvcGVyYXRvcjogc3RyaW5nLCB2YWx1ZTogYW55LCBydWxlOiBSdWxlKTogYW55IHtcbiAgICBjb25zdCBpbnB1dFR5cGU6IGFueSA9IHRoaXMuZ2V0SW5wdXRUeXBlKHJ1bGUuZmllbGQsIG9wZXJhdG9yKTtcbiAgICBpZiAoaW5wdXRUeXBlID09PSAnbXVsdGlzZWxlY3QnICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIFt2YWx1ZV07XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGNoYW5nZUlucHV0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5oYW5kbGVUb3VjaGVkKCk7XG4gICAgdGhpcy5oYW5kbGVEYXRhQ2hhbmdlKCk7XG4gIH1cblxuICBjaGFuZ2VGaWVsZChmaWVsZFZhbHVlOiBzdHJpbmcsIHJ1bGU6IFJ1bGUpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGlucHV0Q29udGV4dCA9IHRoaXMuaW5wdXRDb250ZXh0Q2FjaGUuZ2V0KHJ1bGUpO1xuICAgIGNvbnN0IGN1cnJlbnRGaWVsZCA9IGlucHV0Q29udGV4dCAmJiBpbnB1dENvbnRleHQuZmllbGQ7XG5cbiAgICBjb25zdCBuZXh0RmllbGQ6IEZpZWxkID0gdGhpcy5jb25maWcuZmllbGRzW2ZpZWxkVmFsdWVdO1xuXG4gICAgY29uc3QgbmV4dFZhbHVlID0gdGhpcy5jYWxjdWxhdGVGaWVsZENoYW5nZVZhbHVlKFxuICAgICAgY3VycmVudEZpZWxkISwgbmV4dEZpZWxkLCBydWxlLnZhbHVlKTtcblxuICAgIGlmIChuZXh0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcnVsZS52YWx1ZSA9IG5leHRWYWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVsZXRlIHJ1bGUudmFsdWU7XG4gICAgfVxuXG4gICAgcnVsZS5vcGVyYXRvciA9IHRoaXMuZ2V0RGVmYXVsdE9wZXJhdG9yKG5leHRGaWVsZCkhO1xuXG4gICAgLy8gQ3JlYXRlIG5ldyBjb250ZXh0IG9iamVjdHMgc28gdGVtcGxhdGVzIHdpbGwgYXV0b21hdGljYWxseSB1cGRhdGVcbiAgICB0aGlzLmlucHV0Q29udGV4dENhY2hlLmRlbGV0ZShydWxlKTtcbiAgICB0aGlzLm9wZXJhdG9yQ29udGV4dENhY2hlLmRlbGV0ZShydWxlKTtcbiAgICB0aGlzLmZpZWxkQ29udGV4dENhY2hlLmRlbGV0ZShydWxlKTtcbiAgICB0aGlzLmVudGl0eUNvbnRleHRDYWNoZS5kZWxldGUocnVsZSk7XG4gICAgdGhpcy5nZXRJbnB1dENvbnRleHQocnVsZSk7XG4gICAgdGhpcy5nZXRGaWVsZENvbnRleHQocnVsZSk7XG4gICAgdGhpcy5nZXRPcGVyYXRvckNvbnRleHQocnVsZSk7XG4gICAgdGhpcy5nZXRFbnRpdHlDb250ZXh0KHJ1bGUpO1xuXG4gICAgdGhpcy5oYW5kbGVUb3VjaGVkKCk7XG4gICAgdGhpcy5oYW5kbGVEYXRhQ2hhbmdlKCk7XG4gIH1cblxuICBjaGFuZ2VFbnRpdHkoZW50aXR5VmFsdWU6IHN0cmluZywgcnVsZTogUnVsZSwgaW5kZXg6IG51bWJlciwgZGF0YTogUnVsZVNldCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBpID0gaW5kZXg7XG4gICAgbGV0IHJzID0gZGF0YTtcbiAgICBjb25zdCBlbnRpdHk6IGFueSA9IHRoaXMuZW50aXRpZXMhLmZpbmQoKGUpID0+IGUudmFsdWUgPT09IGVudGl0eVZhbHVlKTtcbiAgICBjb25zdCBkZWZhdWx0RmllbGQ6IEZpZWxkID0gdGhpcy5nZXREZWZhdWx0RmllbGQoZW50aXR5KSE7XG4gICAgaWYgKCFycykge1xuICAgICAgcnMgPSB0aGlzLmRhdGE7XG4gICAgICBpID0gcnMucnVsZXMuZmluZEluZGV4KCh4KSA9PiB4ID09PSBydWxlKTtcbiAgICB9XG4gICAgcnVsZS5maWVsZCA9IGRlZmF1bHRGaWVsZC52YWx1ZSE7XG4gICAgcnMucnVsZXNbaV0gPSBydWxlO1xuICAgIGlmIChkZWZhdWx0RmllbGQpIHtcbiAgICAgIHRoaXMuY2hhbmdlRmllbGQoZGVmYXVsdEZpZWxkLnZhbHVlISwgcnVsZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaGFuZGxlVG91Y2hlZCgpO1xuICAgICAgdGhpcy5oYW5kbGVEYXRhQ2hhbmdlKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0RGVmYXVsdFZhbHVlKGRlZmF1bHRWYWx1ZTogYW55KTogYW55IHtcbiAgICBzd2l0Y2ggKHR5cGVvZiBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZSgpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICB9XG4gIH1cblxuICBnZXRPcGVyYXRvclRlbXBsYXRlKCk6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsIHtcbiAgICBjb25zdCB0ID0gdGhpcy5wYXJlbnRPcGVyYXRvclRlbXBsYXRlIHx8IHRoaXMub3BlcmF0b3JUZW1wbGF0ZTtcbiAgICByZXR1cm4gdCA/IHQudGVtcGxhdGUgOiBudWxsO1xuICB9XG5cbiAgZ2V0RmllbGRUZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbCB7XG4gICAgY29uc3QgdCA9IHRoaXMucGFyZW50RmllbGRUZW1wbGF0ZSB8fCB0aGlzLmZpZWxkVGVtcGxhdGU7XG4gICAgcmV0dXJuIHQgPyB0LnRlbXBsYXRlIDogbnVsbDtcbiAgfVxuXG4gIGdldEVudGl0eVRlbXBsYXRlKCk6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsIHtcbiAgICBjb25zdCB0ID0gdGhpcy5wYXJlbnRFbnRpdHlUZW1wbGF0ZSB8fCB0aGlzLmVudGl0eVRlbXBsYXRlO1xuICAgIHJldHVybiB0ID8gdC50ZW1wbGF0ZSA6IG51bGw7XG4gIH1cblxuICBnZXRBcnJvd0ljb25UZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbCB7XG4gICAgY29uc3QgdCA9IHRoaXMucGFyZW50QXJyb3dJY29uVGVtcGxhdGUgfHwgdGhpcy5hcnJvd0ljb25UZW1wbGF0ZTtcbiAgICByZXR1cm4gdCA/IHQudGVtcGxhdGUgOiBudWxsO1xuICB9XG5cbiAgZ2V0QnV0dG9uR3JvdXBUZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbCB7XG4gICAgY29uc3QgdCA9IHRoaXMucGFyZW50QnV0dG9uR3JvdXBUZW1wbGF0ZSB8fCB0aGlzLmJ1dHRvbkdyb3VwVGVtcGxhdGU7XG4gICAgcmV0dXJuIHQgPyB0LnRlbXBsYXRlIDogbnVsbDtcbiAgfVxuXG4gIGdldFN3aXRjaEdyb3VwVGVtcGxhdGUoKTogVGVtcGxhdGVSZWY8YW55PiB8IG51bGwge1xuICAgIGNvbnN0IHQgPSB0aGlzLnBhcmVudFN3aXRjaEdyb3VwVGVtcGxhdGUgfHwgdGhpcy5zd2l0Y2hHcm91cFRlbXBsYXRlO1xuICAgIHJldHVybiB0ID8gdC50ZW1wbGF0ZSA6IG51bGw7XG4gIH1cblxuICBnZXRSZW1vdmVCdXR0b25UZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbCB7XG4gICAgY29uc3QgdCA9IHRoaXMucGFyZW50UmVtb3ZlQnV0dG9uVGVtcGxhdGUgfHwgdGhpcy5yZW1vdmVCdXR0b25UZW1wbGF0ZTtcbiAgICByZXR1cm4gdCA/IHQudGVtcGxhdGUgOiBudWxsO1xuICB9XG5cbiAgZ2V0RW1wdHlXYXJuaW5nVGVtcGxhdGUoKTogVGVtcGxhdGVSZWY8YW55PiB8IG51bGwge1xuICAgIGNvbnN0IHQgPSB0aGlzLnBhcmVudEVtcHR5V2FybmluZ1RlbXBsYXRlIHx8IHRoaXMuZW1wdHlXYXJuaW5nVGVtcGxhdGU7XG4gICAgcmV0dXJuIHQgPyB0LnRlbXBsYXRlIDogbnVsbDtcbiAgfVxuXG4gIGdldFF1ZXJ5SXRlbUNsYXNzTmFtZShsb2NhbDogYW55KTogc3RyaW5nIHtcbiAgICBsZXQgY2xzID0gdGhpcy5nZXRDbGFzc05hbWVzKCdyb3cnLCAnY29ubmVjdG9yJywgJ3RyYW5zaXRpb24nKTtcbiAgICBjbHMgKz0gJyAnICsgdGhpcy5nZXRDbGFzc05hbWVzKGxvY2FsLnJ1bGVzZXQgPyAncnVsZVNldCcgOiAncnVsZScpO1xuICAgIGlmIChsb2NhbC5pbnZhbGlkKSB7XG4gICAgICBjbHMgKz0gJyAnICsgdGhpcy5nZXRDbGFzc05hbWVzKCdpbnZhbGlkUnVsZVNldCcpO1xuICAgIH1cbiAgICByZXR1cm4gY2xzITtcbiAgfVxuXG4gIGdldEJ1dHRvbkdyb3VwQ29udGV4dCgpOiBCdXR0b25Hcm91cENvbnRleHQge1xuICAgIGlmICghdGhpcy5idXR0b25Hcm91cENvbnRleHQpIHtcbiAgICAgIHRoaXMuYnV0dG9uR3JvdXBDb250ZXh0ID0ge1xuICAgICAgICBhZGRSdWxlOiB0aGlzLmFkZFJ1bGUuYmluZCh0aGlzKSxcbiAgICAgICAgYWRkUnVsZVNldDogdGhpcy5hbGxvd1J1bGVzZXQgJiYgdGhpcy5hZGRSdWxlU2V0LmJpbmQodGhpcyksXG4gICAgICAgIHJlbW92ZVJ1bGVTZXQ6IHRoaXMuYWxsb3dSdWxlc2V0ICYmIHRoaXMucGFyZW50VmFsdWUgJiYgdGhpcy5yZW1vdmVSdWxlU2V0LmJpbmQodGhpcyksXG4gICAgICAgIGdldERpc2FibGVkU3RhdGU6IHRoaXMuZ2V0RGlzYWJsZWRTdGF0ZSxcbiAgICAgICAgJGltcGxpY2l0OiB0aGlzLmRhdGFcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmJ1dHRvbkdyb3VwQ29udGV4dDtcbiAgfVxuXG4gIGdldFJlbW92ZUJ1dHRvbkNvbnRleHQocnVsZTogYW55KTogUmVtb3ZlQnV0dG9uQ29udGV4dCB7XG4gICAgaWYgKCF0aGlzLnJlbW92ZUJ1dHRvbkNvbnRleHRDYWNoZS5oYXMocnVsZSkpIHtcbiAgICAgIHRoaXMucmVtb3ZlQnV0dG9uQ29udGV4dENhY2hlLnNldChydWxlLCB7XG4gICAgICAgIHJlbW92ZVJ1bGU6IHRoaXMucmVtb3ZlUnVsZS5iaW5kKHRoaXMpLFxuICAgICAgICBnZXREaXNhYmxlZFN0YXRlOiB0aGlzLmdldERpc2FibGVkU3RhdGUsXG4gICAgICAgICRpbXBsaWNpdDogcnVsZVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlbW92ZUJ1dHRvbkNvbnRleHRDYWNoZS5nZXQocnVsZSkhO1xuICB9XG5cbiAgZ2V0RmllbGRDb250ZXh0KHJ1bGU6IGFueSk6IEZpZWxkQ29udGV4dCB7XG4gICAgaWYgKCF0aGlzLmZpZWxkQ29udGV4dENhY2hlLmhhcyhydWxlKSkge1xuICAgICAgdGhpcy5maWVsZENvbnRleHRDYWNoZS5zZXQocnVsZSwge1xuICAgICAgICBvbkNoYW5nZTogdGhpcy5jaGFuZ2VGaWVsZC5iaW5kKHRoaXMpLFxuICAgICAgICBnZXRGaWVsZHM6IHRoaXMuZ2V0RmllbGRzLmJpbmQodGhpcyksXG4gICAgICAgIGdldERpc2FibGVkU3RhdGU6IHRoaXMuZ2V0RGlzYWJsZWRTdGF0ZSxcbiAgICAgICAgZmllbGRzOiB0aGlzLmZpZWxkcyxcbiAgICAgICAgJGltcGxpY2l0OiBydWxlXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZmllbGRDb250ZXh0Q2FjaGUuZ2V0KHJ1bGUpITtcbiAgfVxuXG4gIGdldEVudGl0eUNvbnRleHQocnVsZTogYW55KTogRW50aXR5Q29udGV4dCB7XG4gICAgaWYgKCF0aGlzLmVudGl0eUNvbnRleHRDYWNoZS5oYXMocnVsZSkpIHtcbiAgICAgIHRoaXMuZW50aXR5Q29udGV4dENhY2hlLnNldChydWxlLCB7XG4gICAgICAgIG9uQ2hhbmdlOiAoZW50aXR5VmFsdWU6IHN0cmluZywgcjogUnVsZSkgPT4gdGhpcy5jaGFuZ2VFbnRpdHkoZW50aXR5VmFsdWUsIHIsIHVuZGVmaW5lZCBhcyBhbnksIHVuZGVmaW5lZCBhcyBhbnkpLFxuICAgICAgICBnZXREaXNhYmxlZFN0YXRlOiB0aGlzLmdldERpc2FibGVkU3RhdGUsXG4gICAgICAgIGVudGl0aWVzOiB0aGlzLmVudGl0aWVzISxcbiAgICAgICAgJGltcGxpY2l0OiBydWxlXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5Q29udGV4dENhY2hlLmdldChydWxlKSE7XG4gIH1cblxuICBnZXRTd2l0Y2hHcm91cENvbnRleHQoKTogU3dpdGNoR3JvdXBDb250ZXh0IHtcbiAgICByZXR1cm4ge1xuICAgICAgb25DaGFuZ2U6IHRoaXMuY2hhbmdlQ29uZGl0aW9uLmJpbmQodGhpcyksXG4gICAgICBnZXREaXNhYmxlZFN0YXRlOiB0aGlzLmdldERpc2FibGVkU3RhdGUsXG4gICAgICAkaW1wbGljaXQ6IHRoaXMuZGF0YVxuICAgIH07XG4gIH1cblxuICBnZXRBcnJvd0ljb25Db250ZXh0KCk6IEFycm93SWNvbkNvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICBnZXREaXNhYmxlZFN0YXRlOiB0aGlzLmdldERpc2FibGVkU3RhdGUsXG4gICAgICAkaW1wbGljaXQ6IHRoaXMuZGF0YVxuICAgIH07XG4gIH1cblxuICBnZXRFbXB0eVdhcm5pbmdDb250ZXh0KCk6IEVtcHR5V2FybmluZ0NvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICBnZXREaXNhYmxlZFN0YXRlOiB0aGlzLmdldERpc2FibGVkU3RhdGUsXG4gICAgICBtZXNzYWdlOiB0aGlzLmVtcHR5TWVzc2FnZSxcbiAgICAgICRpbXBsaWNpdDogdGhpcy5kYXRhXG4gICAgfTtcbiAgfVxuXG4gIGdldE9wZXJhdG9yQ29udGV4dChydWxlOiBSdWxlKTogT3BlcmF0b3JDb250ZXh0IHtcbiAgICBpZiAoIXRoaXMub3BlcmF0b3JDb250ZXh0Q2FjaGUuaGFzKHJ1bGUpKSB7XG4gICAgICB0aGlzLm9wZXJhdG9yQ29udGV4dENhY2hlLnNldChydWxlLCB7XG4gICAgICAgIG9uQ2hhbmdlOiB0aGlzLmNoYW5nZU9wZXJhdG9yLmJpbmQodGhpcywgcnVsZSksXG4gICAgICAgIGdldERpc2FibGVkU3RhdGU6IHRoaXMuZ2V0RGlzYWJsZWRTdGF0ZSxcbiAgICAgICAgb3BlcmF0b3JzOiB0aGlzLmdldE9wZXJhdG9ycyhydWxlLmZpZWxkKSxcbiAgICAgICAgJGltcGxpY2l0OiBydWxlXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMub3BlcmF0b3JDb250ZXh0Q2FjaGUuZ2V0KHJ1bGUpITtcbiAgfVxuXG4gIGdldElucHV0Q29udGV4dChydWxlOiBhbnkpOiBJbnB1dENvbnRleHQge1xuICAgIGlmICghdGhpcy5pbnB1dENvbnRleHRDYWNoZS5oYXMocnVsZSkpIHtcbiAgICAgIHRoaXMuaW5wdXRDb250ZXh0Q2FjaGUuc2V0KHJ1bGUsIHtcbiAgICAgICAgb25DaGFuZ2U6IHRoaXMuY2hhbmdlSW5wdXQuYmluZCh0aGlzKSxcbiAgICAgICAgZ2V0RGlzYWJsZWRTdGF0ZTogdGhpcy5nZXREaXNhYmxlZFN0YXRlLFxuICAgICAgICBvcHRpb25zOiB0aGlzLmdldE9wdGlvbnMocnVsZS5maWVsZCksXG4gICAgICAgIGZpZWxkOiB0aGlzLmNvbmZpZy5maWVsZHNbcnVsZS5maWVsZF0sXG4gICAgICAgICRpbXBsaWNpdDogcnVsZVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlucHV0Q29udGV4dENhY2hlLmdldChydWxlKSE7XG4gIH1cblxuICBwcml2YXRlIGNhbGN1bGF0ZUZpZWxkQ2hhbmdlVmFsdWUoXG4gICAgY3VycmVudEZpZWxkOiBGaWVsZCxcbiAgICBuZXh0RmllbGQ6IEZpZWxkLFxuICAgIGN1cnJlbnRWYWx1ZTogYW55XG4gICk6IGFueSB7XG5cbiAgICBpZiAodGhpcy5jb25maWcuY2FsY3VsYXRlRmllbGRDaGFuZ2VWYWx1ZSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuY2FsY3VsYXRlRmllbGRDaGFuZ2VWYWx1ZShcbiAgICAgICAgY3VycmVudEZpZWxkLCBuZXh0RmllbGQsIGN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuXG4gICAgY29uc3QgY2FuS2VlcFZhbHVlID0gKCkgPT4ge1xuICAgICAgaWYgKGN1cnJlbnRGaWVsZCA9PSBudWxsIHx8IG5leHRGaWVsZCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjdXJyZW50RmllbGQudHlwZSA9PT0gbmV4dEZpZWxkLnR5cGVcbiAgICAgICAgJiYgdGhpcy5kZWZhdWx0UGVyc2lzdFZhbHVlVHlwZXMuaW5kZXhPZihjdXJyZW50RmllbGQudHlwZSkgIT09IC0xO1xuICAgIH07XG5cbiAgICBpZiAodGhpcy5wZXJzaXN0VmFsdWVPbkZpZWxkQ2hhbmdlICYmIGNhbktlZXBWYWx1ZSgpKSB7XG4gICAgICByZXR1cm4gY3VycmVudFZhbHVlO1xuICAgIH1cblxuICAgIGlmIChuZXh0RmllbGQgJiYgbmV4dEZpZWxkLmRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXREZWZhdWx0VmFsdWUobmV4dEZpZWxkLmRlZmF1bHRWYWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tFbXB0eVJ1bGVJblJ1bGVzZXQocnVsZXNldDogUnVsZVNldCk6IGJvb2xlYW4ge1xuICAgIGlmICghcnVsZXNldCB8fCAhcnVsZXNldC5ydWxlcyB8fCBydWxlc2V0LnJ1bGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBydWxlc2V0LnJ1bGVzLnNvbWUoKGl0ZW06IGFueSkgPT4ge1xuICAgICAgICBpZiAoaXRlbS5ydWxlcykge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNoZWNrRW1wdHlSdWxlSW5SdWxlc2V0KGl0ZW0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZVJ1bGVzSW5SdWxlc2V0KHJ1bGVzZXQ6IFJ1bGVTZXQsIGVycm9yU3RvcmU6IGFueVtdKSB7XG4gICAgaWYgKHJ1bGVzZXQgJiYgcnVsZXNldC5ydWxlcyAmJiBydWxlc2V0LnJ1bGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJ1bGVzZXQucnVsZXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICBpZiAoKGl0ZW0gYXMgUnVsZVNldCkucnVsZXMpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZVJ1bGVzSW5SdWxlc2V0KGl0ZW0gYXMgUnVsZVNldCwgZXJyb3JTdG9yZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoKGl0ZW0gYXMgUnVsZSkuZmllbGQpIHtcbiAgICAgICAgICBjb25zdCBmaWVsZCA9IHRoaXMuY29uZmlnLmZpZWxkc1soaXRlbSBhcyBSdWxlKS5maWVsZF07XG4gICAgICAgICAgaWYgKGZpZWxkICYmIGZpZWxkLnZhbGlkYXRvciAmJiBmaWVsZC52YWxpZGF0b3IuYXBwbHkhKSB7XG4gICAgICAgICAgICBjb25zdCBlcnJvciA9IGZpZWxkLnZhbGlkYXRvcihpdGVtIGFzIFJ1bGUsIHJ1bGVzZXQpO1xuICAgICAgICAgICAgaWYgKGVycm9yICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgZXJyb3JTdG9yZS5wdXNoKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlRGF0YUNoYW5nZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgIGlmICh0aGlzLm9uQ2hhbmdlQ2FsbGJhY2spIHtcbiAgICAgIHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wYXJlbnRDaGFuZ2VDYWxsYmFjaykge1xuICAgICAgdGhpcy5wYXJlbnRDaGFuZ2VDYWxsYmFjaygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlVG91Y2hlZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vblRvdWNoZWRDYWxsYmFjaykge1xuICAgICAgdGhpcy5vblRvdWNoZWRDYWxsYmFjaygpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wYXJlbnRUb3VjaGVkQ2FsbGJhY2spIHtcbiAgICAgIHRoaXMucGFyZW50VG91Y2hlZENhbGxiYWNrKCk7XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ3N3aXRjaFJvdycpXCI+XG4gIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdEFycm93SWNvbj5cbiAgICA8aSBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdhcnJvd0ljb24nKVwiPjwvaT5cbiAgPC9uZy10ZW1wbGF0ZT5cblxuICA8YSAqbmdJZj1cImFsbG93Q29sbGFwc2VcIiAoY2xpY2spPVwidG9nZ2xlQ29sbGFwc2UoKVwiIFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2Fycm93SWNvbkJ1dHRvbicsIGRhdGEuY29sbGFwc2VkID8gJ2NvbGxhcHNlZCcgOiBudWxsKVwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRBcnJvd0ljb25UZW1wbGF0ZSgpIGFzIHRlbXBsYXRlOyBlbHNlIGRlZmF1bHRBcnJvd0ljb25cIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0ZW1wbGF0ZTsgY29udGV4dDogZ2V0QXJyb3dJY29uQ29udGV4dCgpXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvYT5cblxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0QnV0dG9uR3JvdXBUZW1wbGF0ZSgpIGFzIHRlbXBsYXRlOyBlbHNlIGRlZmF1bHRCdXR0b25Hcm91cFwiPlxuICAgIDxkaXYgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnYnV0dG9uR3JvdXAnLCAncmlnaHRBbGlnbicpXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGVtcGxhdGU7IGNvbnRleHQ6IGdldEJ1dHRvbkdyb3VwQ29udGV4dCgpXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdEJ1dHRvbkdyb3VwPlxuICAgIDxkaXYgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnYnV0dG9uR3JvdXAnLCAncmlnaHRBbGlnbicpXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiYWRkUnVsZSgpXCIgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnYnV0dG9uJylcIiBbZGlzYWJsZWRdPWRpc2FibGVkPlxuICAgICAgICA8aSBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdhZGRJY29uJylcIj48L2k+IFJ1bGVcbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFkZFJ1bGVTZXQoKVwiIFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2J1dHRvbicpXCIgKm5nSWY9XCJhbGxvd1J1bGVzZXRcIiBbZGlzYWJsZWRdPWRpc2FibGVkPlxuICAgICAgICA8aSBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdhZGRJY29uJylcIj48L2k+IFJ1bGVzZXRcbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiEhcGFyZW50VmFsdWUgJiYgYWxsb3dSdWxlc2V0XCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJyZW1vdmVSdWxlU2V0KClcIiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdidXR0b24nLCAncmVtb3ZlQnV0dG9uJylcIiBbZGlzYWJsZWRdPWRpc2FibGVkPlxuICAgICAgICAgIDxpIFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ3JlbW92ZUljb24nKVwiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cblxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0U3dpdGNoR3JvdXBUZW1wbGF0ZSgpIGFzIHRlbXBsYXRlOyBlbHNlIGRlZmF1bHRTd2l0Y2hHcm91cFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0ZW1wbGF0ZTsgY29udGV4dDogZ2V0U3dpdGNoR3JvdXBDb250ZXh0KClcIj48L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPG5nLXRlbXBsYXRlICNkZWZhdWx0U3dpdGNoR3JvdXA+XG4gICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdzd2l0Y2hHcm91cCcsICd0cmFuc2l0aW9uJylcIiAqbmdJZj1cImRhdGFcIj5cbiAgICAgIDxkaXYgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnc3dpdGNoQ29udHJvbCcpXCI+XG4gICAgICAgIDxpbnB1dCB0eXBlPVwicmFkaW9cIiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdzd2l0Y2hSYWRpbycpXCIgWyhuZ01vZGVsKV09XCJkYXRhLmNvbmRpdGlvblwiIFtkaXNhYmxlZF09ZGlzYWJsZWRcbiAgICAgICAgICB2YWx1ZT1cImFuZFwiICNhbmRPcHRpb24gLz5cbiAgICAgICAgPGxhYmVsIChjbGljayk9XCJjaGFuZ2VDb25kaXRpb24oYW5kT3B0aW9uLnZhbHVlKVwiIFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ3N3aXRjaExhYmVsJylcIj5BTkQ8L2xhYmVsPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ3N3aXRjaENvbnRyb2wnKVwiPlxuICAgICAgICA8aW5wdXQgdHlwZT1cInJhZGlvXCIgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnc3dpdGNoUmFkaW8nKVwiIFsobmdNb2RlbCldPVwiZGF0YS5jb25kaXRpb25cIiBbZGlzYWJsZWRdPWRpc2FibGVkXG4gICAgICAgICAgdmFsdWU9XCJvclwiICNvck9wdGlvbiAvPlxuICAgICAgICA8bGFiZWwgKGNsaWNrKT1cImNoYW5nZUNvbmRpdGlvbihvck9wdGlvbi52YWx1ZSlcIiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdzd2l0Y2hMYWJlbCcpXCI+T1I8L2xhYmVsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctdGVtcGxhdGU+XG48L2Rpdj5cblxuPGRpdiAjdHJlZUNvbnRhaW5lciAodHJhbnNpdGlvbmVuZCk9XCJ0cmFuc2l0aW9uRW5kKCRldmVudClcIiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCd0cmVlQ29udGFpbmVyJywgZGF0YS5jb2xsYXBzZWQgPyAnY29sbGFwc2VkJyA6IG51bGwpXCI+XG4gIDx1bCBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCd0cmVlJylcIiAqbmdJZj1cImRhdGEgJiYgZGF0YS5ydWxlc1wiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHJ1bGUgb2YgZGF0YS5ydWxlcztsZXQgaT1pbmRleFwiPlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwie3J1bGVzZXQ6ICEhcnVsZS5ydWxlcywgaW52YWxpZDogIWNvbmZpZy5hbGxvd0VtcHR5UnVsZXNldHMgJiYgcnVsZS5ydWxlcyAmJiBydWxlLnJ1bGVzLmxlbmd0aCA9PT0gMH0gYXMgbG9jYWxcIj5cbiAgICAgICAgPGxpIFtuZ0NsYXNzXT1cImdldFF1ZXJ5SXRlbUNsYXNzTmFtZShsb2NhbClcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWxvY2FsLnJ1bGVzZXRcIj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldFJlbW92ZUJ1dHRvblRlbXBsYXRlKCkgYXMgdGVtcGxhdGU7IGVsc2UgZGVmYXVsdFJlbW92ZUJ1dHRvblwiPlxuICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2J1dHRvbkdyb3VwJywgJ3JpZ2h0QWxpZ24nKVwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0ZW1wbGF0ZTsgY29udGV4dDogZ2V0UmVtb3ZlQnV0dG9uQ29udGV4dChydWxlKVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRSZW1vdmVCdXR0b24+XG4gICAgICAgICAgICAgIDxkaXYgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygncmVtb3ZlQnV0dG9uU2l6ZScsICdyaWdodEFsaWduJylcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdidXR0b24nLCAncmVtb3ZlQnV0dG9uJylcIiAoY2xpY2spPVwicmVtb3ZlUnVsZShydWxlLCBkYXRhKVwiIFtkaXNhYmxlZF09ZGlzYWJsZWQ+XG4gICAgICAgICAgICAgICAgICA8aSBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdyZW1vdmVJY29uJylcIj48L2k+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImVudGl0aWVzPy5sZW5ndGghID4gMFwiIGNsYXNzPVwicS1pbmxpbmUtYmxvY2stZGlzcGxheVwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0RW50aXR5VGVtcGxhdGUoKSBhcyB0ZW1wbGF0ZTsgZWxzZSBkZWZhdWx0RW50aXR5XCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRlbXBsYXRlOyBjb250ZXh0OiBnZXRFbnRpdHlDb250ZXh0KHJ1bGUpXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdEVudGl0eT5cbiAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdlbnRpdHlDb250cm9sU2l6ZScpXCI+XG4gICAgICAgICAgICAgICAgPHNlbGVjdCBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdlbnRpdHlDb250cm9sJylcIiBbKG5nTW9kZWwpXT1cInJ1bGUuZW50aXR5XCIgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlRW50aXR5KCRldmVudCwgcnVsZSxpLGRhdGEpXCJcbiAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiPlxuICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgZW50aXR5IG9mIGVudGl0aWVzXCIgW25nVmFsdWVdPVwiZW50aXR5LnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7ZW50aXR5Lm5hbWV9fVxuICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldEZpZWxkVGVtcGxhdGUoKSBhcyB0ZW1wbGF0ZTsgZWxzZSBkZWZhdWx0RmllbGRcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRlbXBsYXRlOyBjb250ZXh0OiBnZXRGaWVsZENvbnRleHQocnVsZSlcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRGaWVsZD5cbiAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdmaWVsZENvbnRyb2xTaXplJylcIj5cbiAgICAgICAgICAgICAgICA8c2VsZWN0IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2ZpZWxkQ29udHJvbCcpXCIgWyhuZ01vZGVsKV09XCJydWxlLmZpZWxkXCIgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlRmllbGQoJGV2ZW50LCBydWxlKVwiXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIj5cbiAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGZpZWxkIG9mIGdldEZpZWxkcyhydWxlLmVudGl0eSlcIiBbbmdWYWx1ZV09XCJmaWVsZC52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICB7e2ZpZWxkLm5hbWV9fVxuICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldE9wZXJhdG9yVGVtcGxhdGUoKSBhcyB0ZW1wbGF0ZTsgZWxzZSBkZWZhdWx0T3BlcmF0b3JcIj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRlbXBsYXRlOyBjb250ZXh0OiBnZXRPcGVyYXRvckNvbnRleHQocnVsZSlcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRPcGVyYXRvcj5cbiAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdvcGVyYXRvckNvbnRyb2xTaXplJylcIj5cbiAgICAgICAgICAgICAgICA8c2VsZWN0IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ29wZXJhdG9yQ29udHJvbCcpXCIgWyhuZ01vZGVsKV09XCJydWxlLm9wZXJhdG9yXCIgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlT3BlcmF0b3IocnVsZSlcIlxuICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCI+XG4gICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcGVyYXRvciBvZiBnZXRPcGVyYXRvcnMocnVsZS5maWVsZClcIiBbbmdWYWx1ZV09XCJvcGVyYXRvclwiPlxuICAgICAgICAgICAgICAgICAgICB7e29wZXJhdG9yfX1cbiAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmaW5kVGVtcGxhdGVGb3JSdWxlKHJ1bGUpIGFzIHRlbXBsYXRlOyBlbHNlIGRlZmF1bHRJbnB1dFwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGVtcGxhdGU7IGNvbnRleHQ6IGdldElucHV0Q29udGV4dChydWxlKVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdElucHV0PlxuICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2lucHV0Q29udHJvbFNpemUnKVwiIFtuZ1N3aXRjaF09XCJnZXRJbnB1dFR5cGUocnVsZS5maWVsZCwgcnVsZS5vcGVyYXRvcilcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnaW5wdXRDb250cm9sJylcIiBbKG5nTW9kZWwpXT1cInJ1bGUudmFsdWVcIiAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VJbnB1dCgpXCJcbiAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiICpuZ1N3aXRjaENhc2U9XCInc3RyaW5nJ1wiIHR5cGU9XCJ0ZXh0XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2lucHV0Q29udHJvbCcpXCIgWyhuZ01vZGVsKV09XCJydWxlLnZhbHVlXCIgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlSW5wdXQoKVwiXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiAqbmdTd2l0Y2hDYXNlPVwiJ251bWJlcidcIiB0eXBlPVwibnVtYmVyXCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2lucHV0Q29udHJvbCcpXCIgWyhuZ01vZGVsKV09XCJydWxlLnZhbHVlXCIgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlSW5wdXQoKVwiXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiAqbmdTd2l0Y2hDYXNlPVwiJ2RhdGUnXCIgdHlwZT1cImRhdGVcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnaW5wdXRDb250cm9sJylcIiBbKG5nTW9kZWwpXT1cInJ1bGUudmFsdWVcIiAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VJbnB1dCgpXCJcbiAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiICpuZ1N3aXRjaENhc2U9XCIndGltZSdcIiB0eXBlPVwidGltZVwiPlxuICAgICAgICAgICAgICAgIDxzZWxlY3QgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnaW5wdXRDb250cm9sJylcIiBbKG5nTW9kZWwpXT1cInJ1bGUudmFsdWVcIiAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VJbnB1dCgpXCJcbiAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiICpuZ1N3aXRjaENhc2U9XCInY2F0ZWdvcnknXCI+XG4gICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcHQgb2YgZ2V0T3B0aW9ucyhydWxlLmZpZWxkKVwiIFtuZ1ZhbHVlXT1cIm9wdC52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICB7e29wdC5uYW1lfX1cbiAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidtdWx0aXNlbGVjdCdcIj5cbiAgICAgICAgICAgICAgICAgIDxzZWxlY3QgW25nQ2xhc3NdPVwiZ2V0Q2xhc3NOYW1lcygnaW5wdXRDb250cm9sJylcIiBbKG5nTW9kZWwpXT1cInJ1bGUudmFsdWVcIiAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VJbnB1dCgpXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCIgbXVsdGlwbGU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdCBvZiBnZXRPcHRpb25zKHJ1bGUuZmllbGQpXCIgW25nVmFsdWVdPVwib3B0LnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3tvcHQubmFtZX19XG4gICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPGlucHV0IFtuZ0NsYXNzXT1cImdldENsYXNzTmFtZXMoJ2lucHV0Q29udHJvbCcpXCIgWyhuZ01vZGVsKV09XCJydWxlLnZhbHVlXCIgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlSW5wdXQoKVwiXG4gICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiAqbmdTd2l0Y2hDYXNlPVwiJ2Jvb2xlYW4nXCIgdHlwZT1cImNoZWNrYm94XCI+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDxxdWVyeS1idWlsZGVyICpuZ0lmPVwibG9jYWwucnVsZXNldFwiIFtkYXRhXT1cInJ1bGVcIiBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiBbcGFyZW50VG91Y2hlZENhbGxiYWNrXT1cInBhcmVudFRvdWNoZWRDYWxsYmFjayB8fCBvblRvdWNoZWRDYWxsYmFja1wiXG4gICAgICAgICAgICBbcGFyZW50Q2hhbmdlQ2FsbGJhY2tdPVwicGFyZW50Q2hhbmdlQ2FsbGJhY2sgfHwgb25DaGFuZ2VDYWxsYmFja1wiIFtwYXJlbnRJbnB1dFRlbXBsYXRlc109XCJwYXJlbnRJbnB1dFRlbXBsYXRlcyB8fCBpbnB1dFRlbXBsYXRlc1wiXG4gICAgICAgICAgICBbcGFyZW50T3BlcmF0b3JUZW1wbGF0ZV09XCJwYXJlbnRPcGVyYXRvclRlbXBsYXRlIHx8IG9wZXJhdG9yVGVtcGxhdGVcIiBbcGFyZW50RmllbGRUZW1wbGF0ZV09XCJwYXJlbnRGaWVsZFRlbXBsYXRlIHx8IGZpZWxkVGVtcGxhdGVcIlxuICAgICAgICAgICAgW3BhcmVudEVudGl0eVRlbXBsYXRlXT1cInBhcmVudEVudGl0eVRlbXBsYXRlIHx8IGVudGl0eVRlbXBsYXRlXCIgW3BhcmVudFN3aXRjaEdyb3VwVGVtcGxhdGVdPVwicGFyZW50U3dpdGNoR3JvdXBUZW1wbGF0ZSB8fCBzd2l0Y2hHcm91cFRlbXBsYXRlXCJcbiAgICAgICAgICAgIFtwYXJlbnRCdXR0b25Hcm91cFRlbXBsYXRlXT1cInBhcmVudEJ1dHRvbkdyb3VwVGVtcGxhdGUgfHwgYnV0dG9uR3JvdXBUZW1wbGF0ZVwiIFtwYXJlbnRSZW1vdmVCdXR0b25UZW1wbGF0ZV09XCJwYXJlbnRSZW1vdmVCdXR0b25UZW1wbGF0ZSB8fCByZW1vdmVCdXR0b25UZW1wbGF0ZVwiXG4gICAgICAgICAgICBbcGFyZW50RW1wdHlXYXJuaW5nVGVtcGxhdGVdPVwicGFyZW50RW1wdHlXYXJuaW5nVGVtcGxhdGUgfHwgZW1wdHlXYXJuaW5nVGVtcGxhdGVcIiBbcGFyZW50QXJyb3dJY29uVGVtcGxhdGVdPVwicGFyZW50QXJyb3dJY29uVGVtcGxhdGUgfHwgYXJyb3dJY29uVGVtcGxhdGVcIlxuICAgICAgICAgICAgW3BhcmVudFZhbHVlXT1cImRhdGFcIiBbY2xhc3NOYW1lc109XCJjbGFzc05hbWVzXCIgW2NvbmZpZ109XCJjb25maWdcIiBbYWxsb3dSdWxlc2V0XT1cImFsbG93UnVsZXNldFwiXG4gICAgICAgICAgICBbYWxsb3dDb2xsYXBzZV09XCJhbGxvd0NvbGxhcHNlXCIgW2VtcHR5TWVzc2FnZV09XCJlbXB0eU1lc3NhZ2VcIiBbb3BlcmF0b3JNYXBdPVwib3BlcmF0b3JNYXBcIj5cbiAgICAgICAgICA8L3F1ZXJ5LWJ1aWxkZXI+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0RW1wdHlXYXJuaW5nVGVtcGxhdGUoKSBhcyB0ZW1wbGF0ZTsgZWxzZSBkZWZhdWx0RW1wdHlXYXJuaW5nXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9jYWwuaW52YWxpZFwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGVtcGxhdGU7IGNvbnRleHQ6IGdldEVtcHR5V2FybmluZ0NvbnRleHQoKVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRFbXB0eVdhcm5pbmc+XG4gICAgICAgICAgICA8cCBbbmdDbGFzc109XCJnZXRDbGFzc05hbWVzKCdlbXB0eVdhcm5pbmcnKVwiICpuZ0lmPVwibG9jYWwuaW52YWxpZFwiPlxuICAgICAgICAgICAgICB7e2VtcHR5TWVzc2FnZX19XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9saT5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L3VsPlxuPC9kaXY+Il19