@firestitch/form 15.0.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/app/components/form-dialog-actions/form-dialog-actions.component.d.ts +1 -1
  2. package/app/components/form-template/form-template.component.d.ts +1 -1
  3. package/app/components/form-template-outlet/form-template-outlet.component.d.ts +1 -1
  4. package/app/directives/button.directive.d.ts +1 -1
  5. package/app/directives/form/form.directive.d.ts +1 -1
  6. package/app/directives/form-dialog-close.directive.d.ts +1 -1
  7. package/app/directives/validators/compare.directive.d.ts +1 -1
  8. package/app/directives/validators/control.directive.d.ts +1 -1
  9. package/app/directives/validators/daterange.directive.d.ts +1 -1
  10. package/app/directives/validators/email.directive.d.ts +1 -1
  11. package/app/directives/validators/emails.directive.d.ts +1 -1
  12. package/app/directives/validators/function.directive.d.ts +1 -1
  13. package/app/directives/validators/greater-equal.directive.d.ts +1 -1
  14. package/app/directives/validators/greater.directive.d.ts +1 -1
  15. package/app/directives/validators/integer.directive.d.ts +1 -1
  16. package/app/directives/validators/lesser-equal.directive.d.ts +1 -1
  17. package/app/directives/validators/lesser.directive.d.ts +1 -1
  18. package/app/directives/validators/max.directive.d.ts +1 -1
  19. package/app/directives/validators/maxlength.directive.d.ts +1 -1
  20. package/app/directives/validators/min.directive.d.ts +1 -1
  21. package/app/directives/validators/minlength.directive.d.ts +1 -1
  22. package/app/directives/validators/numeric.directive.d.ts +1 -1
  23. package/app/directives/validators/pattern.directive.d.ts +1 -1
  24. package/app/directives/validators/phone.directive.d.ts +1 -1
  25. package/app/directives/validators/required.directive.d.ts +1 -1
  26. package/app/directives/validators/url.directive.d.ts +1 -1
  27. package/app/directives/validators/validate.directive.d.ts +1 -1
  28. package/app/guards/form-deactivate.guard.d.ts +2 -2
  29. package/esm2022/app/components/confirm-unsaved/confirm-unsaved.component.mjs +51 -0
  30. package/esm2022/app/components/form-dialog-actions/form-dialog-actions.component.mjs +79 -0
  31. package/esm2022/app/components/form-template/form-template.component.mjs +34 -0
  32. package/esm2022/app/components/form-template-outlet/form-template-outlet.component.mjs +32 -0
  33. package/esm2022/app/directives/button.directive.mjs +172 -0
  34. package/esm2022/app/directives/form/form.directive.mjs +702 -0
  35. package/esm2022/app/directives/form-dialog-close.directive.mjs +57 -0
  36. package/esm2022/app/directives/form-template.directive.mjs +21 -0
  37. package/{esm2020 → esm2022}/app/directives/submit-button.directive.mjs +4 -4
  38. package/esm2022/app/directives/validators/compare.directive.mjs +48 -0
  39. package/esm2022/app/directives/validators/control.directive.mjs +269 -0
  40. package/esm2022/app/directives/validators/daterange.directive.mjs +42 -0
  41. package/esm2022/app/directives/validators/email.directive.mjs +42 -0
  42. package/esm2022/app/directives/validators/emails.directive.mjs +42 -0
  43. package/esm2022/app/directives/validators/function.directive.mjs +40 -0
  44. package/esm2022/app/directives/validators/greater-equal.directive.mjs +41 -0
  45. package/esm2022/app/directives/validators/greater.directive.mjs +41 -0
  46. package/esm2022/app/directives/validators/integer.directive.mjs +40 -0
  47. package/esm2022/app/directives/validators/lesser-equal.directive.mjs +41 -0
  48. package/esm2022/app/directives/validators/lesser.directive.mjs +41 -0
  49. package/esm2022/app/directives/validators/max.directive.mjs +37 -0
  50. package/esm2022/app/directives/validators/maxlength.directive.mjs +36 -0
  51. package/esm2022/app/directives/validators/min.directive.mjs +37 -0
  52. package/esm2022/app/directives/validators/minlength.directive.mjs +36 -0
  53. package/{esm2020 → esm2022}/app/directives/validators/no-fs-validators.directive.mjs +6 -6
  54. package/esm2022/app/directives/validators/numeric.directive.mjs +42 -0
  55. package/esm2022/app/directives/validators/pattern.directive.mjs +36 -0
  56. package/esm2022/app/directives/validators/phone.directive.mjs +42 -0
  57. package/esm2022/app/directives/validators/required.directive.mjs +66 -0
  58. package/esm2022/app/directives/validators/url.directive.mjs +43 -0
  59. package/esm2022/app/directives/validators/validate.directive.mjs +42 -0
  60. package/esm2022/app/fs-form.module.mjs +209 -0
  61. package/esm2022/app/guards/form-deactivate.guard.mjs +44 -0
  62. package/esm2022/app/services/fsform.service.mjs +94 -0
  63. package/{fesm2020 → fesm2022}/firestitch-form.mjs +354 -291
  64. package/fesm2022/firestitch-form.mjs.map +1 -0
  65. package/package.json +5 -11
  66. package/esm2020/app/components/confirm-unsaved/confirm-unsaved.component.mjs +0 -44
  67. package/esm2020/app/components/form-dialog-actions/form-dialog-actions.component.mjs +0 -75
  68. package/esm2020/app/components/form-template/form-template.component.mjs +0 -31
  69. package/esm2020/app/components/form-template-outlet/form-template-outlet.component.mjs +0 -30
  70. package/esm2020/app/directives/button.directive.mjs +0 -166
  71. package/esm2020/app/directives/form/form.directive.mjs +0 -689
  72. package/esm2020/app/directives/form-dialog-close.directive.mjs +0 -54
  73. package/esm2020/app/directives/form-template.directive.mjs +0 -20
  74. package/esm2020/app/directives/validators/compare.directive.mjs +0 -47
  75. package/esm2020/app/directives/validators/control.directive.mjs +0 -258
  76. package/esm2020/app/directives/validators/daterange.directive.mjs +0 -41
  77. package/esm2020/app/directives/validators/email.directive.mjs +0 -41
  78. package/esm2020/app/directives/validators/emails.directive.mjs +0 -41
  79. package/esm2020/app/directives/validators/function.directive.mjs +0 -41
  80. package/esm2020/app/directives/validators/greater-equal.directive.mjs +0 -40
  81. package/esm2020/app/directives/validators/greater.directive.mjs +0 -40
  82. package/esm2020/app/directives/validators/integer.directive.mjs +0 -39
  83. package/esm2020/app/directives/validators/lesser-equal.directive.mjs +0 -40
  84. package/esm2020/app/directives/validators/lesser.directive.mjs +0 -40
  85. package/esm2020/app/directives/validators/max.directive.mjs +0 -36
  86. package/esm2020/app/directives/validators/maxlength.directive.mjs +0 -35
  87. package/esm2020/app/directives/validators/min.directive.mjs +0 -36
  88. package/esm2020/app/directives/validators/minlength.directive.mjs +0 -35
  89. package/esm2020/app/directives/validators/numeric.directive.mjs +0 -41
  90. package/esm2020/app/directives/validators/pattern.directive.mjs +0 -35
  91. package/esm2020/app/directives/validators/phone.directive.mjs +0 -41
  92. package/esm2020/app/directives/validators/required.directive.mjs +0 -69
  93. package/esm2020/app/directives/validators/url.directive.mjs +0 -45
  94. package/esm2020/app/directives/validators/validate.directive.mjs +0 -43
  95. package/esm2020/app/fs-form.module.mjs +0 -209
  96. package/esm2020/app/guards/form-deactivate.guard.mjs +0 -42
  97. package/esm2020/app/services/fsform.service.mjs +0 -92
  98. package/fesm2015/firestitch-form.mjs +0 -2579
  99. package/fesm2015/firestitch-form.mjs.map +0 -1
  100. package/fesm2020/firestitch-form.mjs.map +0 -1
  101. /package/{esm2020 → esm2022}/app/components/confirm-unsaved/index.mjs +0 -0
  102. /package/{esm2020 → esm2022}/app/components/form-dialog-actions/index.mjs +0 -0
  103. /package/{esm2020 → esm2022}/app/components/form-template/index.mjs +0 -0
  104. /package/{esm2020 → esm2022}/app/components/form-template-outlet/index.mjs +0 -0
  105. /package/{esm2020 → esm2022}/app/components/index.mjs +0 -0
  106. /package/{esm2020 → esm2022}/app/consts/error-messages.const.mjs +0 -0
  107. /package/{esm2020 → esm2022}/app/directives/form/index.mjs +0 -0
  108. /package/{esm2020 → esm2022}/app/directives/index.mjs +0 -0
  109. /package/{esm2020 → esm2022}/app/directives/validators/index.mjs +0 -0
  110. /package/{esm2020 → esm2022}/app/enums/confirm-result.mjs +0 -0
  111. /package/{esm2020 → esm2022}/app/enums/form-status.mjs +0 -0
  112. /package/{esm2020 → esm2022}/app/enums/index.mjs +0 -0
  113. /package/{esm2020 → esm2022}/app/helpers/confirm-result-continue.mjs +0 -0
  114. /package/{esm2020 → esm2022}/app/helpers/get-active-route.mjs +0 -0
  115. /package/{esm2020 → esm2022}/app/helpers/get-form-errors.mjs +0 -0
  116. /package/{esm2020 → esm2022}/app/helpers/index.mjs +0 -0
  117. /package/{esm2020 → esm2022}/app/helpers/is-enabled.mjs +0 -0
  118. /package/{esm2020 → esm2022}/app/interfaces/async-validator.mjs +0 -0
  119. /package/{esm2020 → esm2022}/app/interfaces/confirm-config.mjs +0 -0
  120. /package/{esm2020 → esm2022}/app/interfaces/confirm-tab-group.mjs +0 -0
  121. /package/{esm2020 → esm2022}/app/interfaces/index.mjs +0 -0
  122. /package/{esm2020 → esm2022}/app/interfaces/submit-event.mjs +0 -0
  123. /package/{esm2020 → esm2022}/app/interfaces/submitted-event.mjs +0 -0
  124. /package/{esm2020 → esm2022}/app/interfaces/validator.mjs +0 -0
  125. /package/{esm2020 → esm2022}/app/providers/validate-messages.provider.mjs +0 -0
  126. /package/{esm2020 → esm2022}/app/validators/validators.mjs +0 -0
  127. /package/{esm2020 → esm2022}/firestitch-form.mjs +0 -0
  128. /package/{esm2020 → esm2022}/public_api.mjs +0 -0
@@ -0,0 +1,702 @@
1
+ import { ChangeDetectorRef, ContentChildren, Directive, ElementRef, EventEmitter, HostBinding, Inject, Input, NgZone, Optional, Output, QueryList, } from '@angular/core';
2
+ import { NgForm } from '@angular/forms';
3
+ import { ActivatedRoute } from '@angular/router';
4
+ import { MatDialogRef } from '@angular/material/dialog';
5
+ import { MatTabGroup } from '@angular/material/tabs';
6
+ import { guid } from '@firestitch/common';
7
+ import { DrawerRef } from '@firestitch/drawer';
8
+ import { FsMessage, MessageMode } from '@firestitch/message';
9
+ import { BehaviorSubject, defer, fromEvent, iif, of, Subject, throwError, } from 'rxjs';
10
+ import { catchError, delay, filter, first, map, mapTo, mergeMap, startWith, switchMap, take, takeUntil, tap, } from 'rxjs/operators';
11
+ import { FormDeactivateGuard } from '../../guards/form-deactivate.guard';
12
+ import { confirmResultContinue } from '../../helpers/confirm-result-continue';
13
+ import { getActiveRoute } from '../../helpers/get-active-route';
14
+ import { getFormErrors } from '../../helpers/get-form-errors';
15
+ import { FsForm } from '../../services/fsform.service';
16
+ import { ConfirmResult } from './../../enums/confirm-result';
17
+ import { FormStatus } from './../../enums/form-status';
18
+ import * as i0 from "@angular/core";
19
+ import * as i1 from "../../services/fsform.service";
20
+ import * as i2 from "@firestitch/message";
21
+ import * as i3 from "@angular/router";
22
+ import * as i4 from "@angular/forms";
23
+ import * as i5 from "@angular/material/dialog";
24
+ import * as i6 from "@firestitch/drawer";
25
+ export class FsFormDirective {
26
+ ngForm;
27
+ _form;
28
+ _element;
29
+ _message;
30
+ _ngZone;
31
+ _cdRef;
32
+ _dialogRef;
33
+ _drawerRef;
34
+ _route;
35
+ wrapperSelector = '.fs-form-wrapper,.mat-form-field';
36
+ messageSelector = '.fs-form-message,.mat-form-field-subscript-wrapper';
37
+ hintSelector = '.fs-form-hint,.mat-form-field-hint-wrapper';
38
+ labelSelector = '.fs-form-label,.mat-form-field-label';
39
+ autocomplete = false;
40
+ shortcuts = true; // Ctrl + s
41
+ confirm = true;
42
+ confirmDialog = true;
43
+ confirmDrawer = true;
44
+ confirmBrowser = true;
45
+ confirmTabs = true;
46
+ dirtySubmitButton = true;
47
+ set submit(submit$) {
48
+ this._submit$ = submit$;
49
+ }
50
+ get submit() {
51
+ return this._submit$;
52
+ }
53
+ successDelay = 0;
54
+ errorDelay = 1000;
55
+ tabGroup;
56
+ deactivationGuard = true;
57
+ submitEvent = new EventEmitter();
58
+ invalid = new EventEmitter();
59
+ valid = new EventEmitter();
60
+ submitted = new EventEmitter();
61
+ reseted = new EventEmitter();
62
+ cleared = new EventEmitter();
63
+ fsFormClass = true;
64
+ _tabGroups = new QueryList();
65
+ _buttons = new QueryList();
66
+ _registerControl;
67
+ _activeSubmitButton;
68
+ _dialogBackdropEscape = false;
69
+ _snapshot = {};
70
+ _activatedRouteConfig;
71
+ _status$ = new BehaviorSubject(FormStatus.Valid);
72
+ _destroy$ = new Subject();
73
+ _confirmed = false;
74
+ _submit$ = null;
75
+ constructor(ngForm, _form, _element, _message, _ngZone, _cdRef, _dialogRef, _drawerRef, _route) {
76
+ this.ngForm = ngForm;
77
+ this._form = _form;
78
+ this._element = _element;
79
+ this._message = _message;
80
+ this._ngZone = _ngZone;
81
+ this._cdRef = _cdRef;
82
+ this._dialogRef = _dialogRef;
83
+ this._drawerRef = _drawerRef;
84
+ this._route = _route;
85
+ }
86
+ get submitting() {
87
+ return this._status$.getValue() === FormStatus.Submitting;
88
+ }
89
+ get validating() {
90
+ return this._status$.getValue() === FormStatus.Validating;
91
+ }
92
+ get completing() {
93
+ return this._status$.getValue() === FormStatus.Completing;
94
+ }
95
+ get _submitEvent() {
96
+ return {
97
+ ngForm: this.ngForm,
98
+ submitter: this._submitter,
99
+ };
100
+ }
101
+ get _formValidState$() {
102
+ this._form.broadcast('valid', this._submitEvent);
103
+ this.submitEvent.emit(this._submitEvent);
104
+ this.valid.emit(this._submitEvent);
105
+ const submittedEvent = {
106
+ ngForm: this.ngForm,
107
+ submitter: this._submitter,
108
+ response: null,
109
+ };
110
+ const submit$ = this._submit$ ?
111
+ this._submit$(this._submitEvent) : of(submittedEvent);
112
+ return submit$
113
+ .pipe(map((response) => {
114
+ submittedEvent.response = response;
115
+ return submittedEvent;
116
+ }), takeUntil(this._destroy$));
117
+ }
118
+ get _formInvalidState$() {
119
+ this._form.broadcast('invalid', this._submitEvent);
120
+ if (this.invalid) {
121
+ this.invalid.emit(this._submitEvent);
122
+ }
123
+ const message = 'Please review errors highlighted in red';
124
+ this._message.error(message, { mode: MessageMode.Toast });
125
+ const el = this._element.nativeElement.querySelector('.ng-invalid');
126
+ if (el) {
127
+ el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
128
+ }
129
+ return throwError('Form validation error');
130
+ }
131
+ get _submitter() {
132
+ return this._activeSubmitButton
133
+ ? this._activeSubmitButton.name
134
+ : null;
135
+ }
136
+ ngOnInit() {
137
+ if (this.deactivationGuard) {
138
+ this._registerCanDeactivateGuard();
139
+ }
140
+ this._registerConfirmDialogBackdropEscape();
141
+ this._listenHotKeys();
142
+ this._listenWindowClose();
143
+ this._listenSubmit();
144
+ this._listenFormStatus();
145
+ if (!this.autocomplete) {
146
+ this._registerAutocomplete();
147
+ }
148
+ }
149
+ ngOnChanges(changes) {
150
+ if (changes.confirm) {
151
+ this._updateDirtySubmitButtons();
152
+ }
153
+ }
154
+ clearSubmit() {
155
+ this._submit$ = null;
156
+ setTimeout(() => {
157
+ this._cdRef.markForCheck();
158
+ });
159
+ }
160
+ registerSubmit(submit$) {
161
+ this._submit$ = submit$;
162
+ setTimeout(() => {
163
+ this._cdRef.markForCheck();
164
+ });
165
+ }
166
+ ngAfterContentInit() {
167
+ this._registerConfirm();
168
+ this._registerConfirmDrawerClose();
169
+ this._registerConfirmTabs();
170
+ this._registerDrawerClose();
171
+ this._registerDirtySubmitButton();
172
+ }
173
+ ngOnDestroy() {
174
+ this._cleanupCanDeactivate();
175
+ this._destroy$.next();
176
+ this._destroy$.complete();
177
+ }
178
+ createSnapshot() {
179
+ this._snapshot = this.ngForm.value;
180
+ }
181
+ getSnapshot() {
182
+ return this._snapshot || {};
183
+ }
184
+ reset() {
185
+ this.ngForm.resetForm();
186
+ Object.keys(this.ngForm.controls)
187
+ .forEach((name) => {
188
+ const control = this.ngForm.controls[name];
189
+ control.reset(this._snapshot[name]);
190
+ });
191
+ this.reseted.emit();
192
+ }
193
+ clear() {
194
+ this.ngForm.resetForm();
195
+ this.cleared.emit();
196
+ }
197
+ dirty() {
198
+ this.ngForm.form.markAsDirty();
199
+ this._updateDirtySubmitButtons();
200
+ }
201
+ triggerSubmit(options) {
202
+ this._confirmed = options?.confirmed;
203
+ this.ngForm.ngSubmit.emit();
204
+ }
205
+ triggerConfirm() {
206
+ const submitted = this.submitting ? this.submitted.asObservable() : of({});
207
+ return submitted
208
+ .pipe(take(1), mergeMap(() => this._form.confirmUnsaved([this])));
209
+ }
210
+ enable() {
211
+ this.ngForm.control.enable();
212
+ this._updateDirtySubmitButtons();
213
+ }
214
+ disable() {
215
+ this.ngForm.control.disable();
216
+ this._buttons.forEach((button) => {
217
+ button.disable();
218
+ });
219
+ }
220
+ addButton(button) {
221
+ this._buttons.reset([
222
+ ...this._buttons.toArray(),
223
+ button,
224
+ ]);
225
+ }
226
+ removeButton(button) {
227
+ this._buttons.reset([
228
+ ...this._buttons.toArray()
229
+ .filter((item) => (button !== item)),
230
+ ]);
231
+ }
232
+ validate() {
233
+ Object.values(this.ngForm.controls)
234
+ .forEach((control) => {
235
+ control.markAsDirty();
236
+ control.markAsTouched();
237
+ control.updateValueAndValidity();
238
+ });
239
+ }
240
+ _listenSubmit() {
241
+ this.ngForm
242
+ .ngSubmit
243
+ .pipe(tap((event) => {
244
+ event?.preventDefault();
245
+ }), map((event) => {
246
+ return { event, confirmed: this._confirmed };
247
+ }), tap(() => this._confirmed = false), filter(() => {
248
+ return [FormStatus.Valid, FormStatus.Invalid]
249
+ .includes(this._status$.getValue());
250
+ }), tap(() => this._broadcasValidatingEvents()), tap(() => this.validate()), tap(() => this._broadcastSubmittingEvents()), switchMap((data) => this._waitUntilStatusPending()
251
+ .pipe(mapTo(data))), tap(() => this._setupActiveSubmitButton()), tap(() => this._disableButtons()), mergeMap((data) => {
252
+ if (this.ngForm.status === 'INVALID') {
253
+ return this._formInvalidState$;
254
+ }
255
+ return this._formValidState$
256
+ .pipe(map((submitEvent) => ({
257
+ ...submitEvent,
258
+ confirmed: data.confirmed,
259
+ })));
260
+ }), catchError((e, source$) => {
261
+ this._handleError(e);
262
+ return source$;
263
+ }), tap((submittedEvent) => {
264
+ this._completeSubmit(true, submittedEvent);
265
+ }), takeUntil(this._destroy$))
266
+ .subscribe();
267
+ }
268
+ _listenFormStatus() {
269
+ this._status$
270
+ .pipe(takeUntil(this._destroy$))
271
+ .subscribe((formStatus) => {
272
+ const cls = [FormStatus.Submitting, FormStatus.Validating];
273
+ const classList = this._element.nativeElement.classList;
274
+ classList.remove(...cls);
275
+ if (cls.indexOf(formStatus) !== -1) {
276
+ classList.add(formStatus);
277
+ }
278
+ });
279
+ }
280
+ _listenWindowClose() {
281
+ fromEvent(window, 'beforeunload')
282
+ .pipe(takeUntil(this._destroy$))
283
+ .subscribe((event) => {
284
+ if (this.confirm && this.confirmBrowser && this.ngForm.dirty) {
285
+ event.returnValue = false;
286
+ }
287
+ });
288
+ }
289
+ _activeDialog(el, dialog) {
290
+ if (el.isSameNode(dialog)) {
291
+ return true;
292
+ }
293
+ else if (el.parentElement) {
294
+ return this._activeDialog(el.parentElement, dialog);
295
+ }
296
+ return false;
297
+ }
298
+ _listenHotKeys() {
299
+ this._ngZone.runOutsideAngular(() => {
300
+ fromEvent(document, 'keydown')
301
+ .pipe(takeUntil(this._destroy$))
302
+ .subscribe((event) => {
303
+ if (this._dialogBackdropEscape && event.code === 'Escape') {
304
+ const cdkOverlayPane = Array
305
+ .from(document.querySelectorAll('.cdk-overlay-pane')).pop();
306
+ const activeDialog = this
307
+ ._activeDialog(document.getElementById(this._dialogRef.id), cdkOverlayPane);
308
+ if (activeDialog) {
309
+ this._ngZone.run(() => {
310
+ this._formClose();
311
+ });
312
+ }
313
+ }
314
+ if ((event.ctrlKey || event.metaKey) && event.code === 'KeyS') {
315
+ event.preventDefault();
316
+ if (this.shortcuts) {
317
+ if (this._elementInForm(document.activeElement)) {
318
+ this.ngForm.ngSubmit.next();
319
+ }
320
+ }
321
+ }
322
+ });
323
+ });
324
+ }
325
+ _formClose() {
326
+ if (this.confirm && this.confirmDialog) {
327
+ this.triggerConfirm()
328
+ .pipe(filter((result) => confirmResultContinue(result)), switchMap((result) => {
329
+ return result === ConfirmResult.Pristine || result === ConfirmResult.Discard
330
+ ? of(null)
331
+ : this.submitted.asObservable();
332
+ }), takeUntil(this._destroy$))
333
+ .subscribe((result) => {
334
+ this._dialogRef.close(result?.response);
335
+ });
336
+ }
337
+ else {
338
+ this._dialogRef.close(null);
339
+ }
340
+ }
341
+ _getActiveSubmitButton() {
342
+ const submitButtons = this._buttons
343
+ .filter((button) => button.submit);
344
+ const activeButton = submitButtons
345
+ .find((button) => {
346
+ return button.active;
347
+ });
348
+ return activeButton ? activeButton : submitButtons[0];
349
+ }
350
+ _elementInForm(el) {
351
+ if (el.isSameNode(this._element.nativeElement)) {
352
+ return true;
353
+ }
354
+ else if (el.parentElement) {
355
+ return this._elementInForm(el.parentElement);
356
+ }
357
+ return false;
358
+ }
359
+ _completeSubmit(success, submitEvent) {
360
+ if (success) {
361
+ this.ngForm.control.markAsPristine();
362
+ this.createSnapshot();
363
+ this.submitted.emit(submitEvent);
364
+ }
365
+ else {
366
+ this._resetButtons();
367
+ }
368
+ if (this._activeSubmitButton) {
369
+ if (success) {
370
+ this._activeSubmitButton.success();
371
+ }
372
+ else {
373
+ this._activeSubmitButton.error();
374
+ }
375
+ }
376
+ this._status$.next(FormStatus.Submitted);
377
+ if (success) {
378
+ this._status$.next(FormStatus.Success);
379
+ }
380
+ else {
381
+ this._status$.next(FormStatus.Error);
382
+ }
383
+ this._status$.next(FormStatus.Completing);
384
+ const resetDelay = success ? this.successDelay : this.errorDelay;
385
+ of(true)
386
+ .pipe(delay(resetDelay), first(), takeUntil(this._destroy$)).subscribe(() => {
387
+ if (this.ngForm.form.status === 'VALID') {
388
+ this._status$.next(FormStatus.Valid);
389
+ }
390
+ else {
391
+ this._status$.next(FormStatus.Invalid);
392
+ }
393
+ this._resetButtons();
394
+ this._resetActiveButtons();
395
+ this._updateDirtySubmitButtons();
396
+ });
397
+ }
398
+ _resetButtons() {
399
+ this._buttons.forEach((button) => {
400
+ button.reset();
401
+ });
402
+ }
403
+ _resetActiveButtons() {
404
+ this._buttons.forEach((button) => {
405
+ button.resetActive();
406
+ });
407
+ }
408
+ _registerConfirm() {
409
+ this.ngForm.form.valueChanges
410
+ .pipe(takeUntil(this._destroy$))
411
+ .subscribe((changes) => {
412
+ if (this._dialogBackdropEscape && this._dialogRef) {
413
+ this._dialogRef.disableClose = true;
414
+ }
415
+ if (this.confirm) {
416
+ const existing = Object.keys(this._snapshot);
417
+ Object.keys(changes)
418
+ .forEach((name) => {
419
+ if (existing.indexOf(name) === -1) {
420
+ this._snapshot[name] = changes[name];
421
+ }
422
+ });
423
+ }
424
+ });
425
+ }
426
+ _registerDrawerClose() {
427
+ if (this._drawerRef) {
428
+ this._drawerRef.closeStart$
429
+ .pipe(takeUntil(this._destroy$))
430
+ .subscribe((subscriber) => {
431
+ if (this.submitting) {
432
+ this._status$
433
+ .pipe(filter((status) => status === FormStatus.Success || status === FormStatus.Error), takeUntil(this._destroy$))
434
+ .subscribe((status) => {
435
+ if (status === FormStatus.Success) {
436
+ subscriber.next();
437
+ subscriber.complete();
438
+ }
439
+ else {
440
+ subscriber.error();
441
+ }
442
+ });
443
+ }
444
+ else {
445
+ subscriber.next();
446
+ subscriber.complete();
447
+ }
448
+ });
449
+ }
450
+ }
451
+ _registerConfirmDrawerClose() {
452
+ if (this._drawerRef) {
453
+ this._drawerRef.closeStart$
454
+ .pipe(switchMap((subscriber) => {
455
+ return iif(() => this.confirm && this.confirmDrawer, this.triggerConfirm()
456
+ .pipe(map((result) => confirmResultContinue(result)), tap((result) => {
457
+ if (result) {
458
+ subscriber.next();
459
+ subscriber.complete();
460
+ }
461
+ })), defer(() => {
462
+ subscriber.next();
463
+ subscriber.complete();
464
+ }));
465
+ }), takeUntil(this._destroy$))
466
+ .subscribe();
467
+ }
468
+ }
469
+ _registerConfirmTabs() {
470
+ if (this.tabGroup) {
471
+ this._registerConfirmTabGroup(this.tabGroup);
472
+ }
473
+ this._registerConfirmTabGroups(this._tabGroups.toArray());
474
+ this._tabGroups.changes
475
+ .pipe(takeUntil(this._destroy$))
476
+ .subscribe(() => {
477
+ this._registerConfirmTabGroups(this._tabGroups.toArray());
478
+ });
479
+ }
480
+ _registerConfirmTabGroups(tabGroups) {
481
+ tabGroups.forEach((tabGroup) => {
482
+ this._registerConfirmTabGroup(tabGroup);
483
+ });
484
+ }
485
+ _registerConfirmTabGroup(tabGroup) {
486
+ const confirmTabGroup = tabGroup;
487
+ if (!confirmTabGroup._originalHandleClick) {
488
+ confirmTabGroup._originalHandleClick = tabGroup._handleClick;
489
+ confirmTabGroup._handlClick$ = new Subject();
490
+ confirmTabGroup._handleClick = (tab, tabHeader, idx) => {
491
+ if (confirmTabGroup._handlClick$.observers.length) {
492
+ confirmTabGroup._handlClick$.next({ tab, tabHeader, idx });
493
+ }
494
+ else {
495
+ confirmTabGroup._originalHandleClick(tab, tabHeader, idx);
496
+ }
497
+ };
498
+ }
499
+ confirmTabGroup._handlClick$
500
+ .pipe(filter(() => !this.submitting), switchMap((event) => {
501
+ if (this.confirm && this.confirmTabs) {
502
+ return this.triggerConfirm()
503
+ .pipe(tap((result) => {
504
+ if (confirmResultContinue(result)) {
505
+ confirmTabGroup.selectedIndex = event.idx;
506
+ }
507
+ }));
508
+ }
509
+ confirmTabGroup._originalHandleClick(event.tab, event.tabHeader, event.idx);
510
+ return of(null);
511
+ }), takeUntil(this._destroy$))
512
+ .subscribe();
513
+ }
514
+ _registerConfirmDialogBackdropEscape() {
515
+ if (this._dialogRef) {
516
+ this._dialogBackdropEscape = !this._dialogRef?.disableClose;
517
+ if (this._dialogBackdropEscape) {
518
+ this._dialogRef.backdropClick()
519
+ .pipe(takeUntil(this._destroy$))
520
+ .subscribe(() => {
521
+ this._formClose();
522
+ });
523
+ this._destroy$
524
+ .subscribe(() => {
525
+ this._dialogRef.disableClose = false;
526
+ });
527
+ }
528
+ }
529
+ }
530
+ _registerAutocomplete() {
531
+ this._registerControl = this.ngForm.form.registerControl.bind(this.ngForm.form);
532
+ this.ngForm.form.registerControl = (name, control) => {
533
+ const el = this._element.nativeElement.querySelector(`input[name='${name}']`);
534
+ if (el) {
535
+ if (!el.getAttribute('autocomplete')) {
536
+ el.setAttribute('autocomplete', 'none');
537
+ el.setAttribute('name', `${name}-${guid()}`);
538
+ }
539
+ }
540
+ return this._registerControl(name, control);
541
+ };
542
+ }
543
+ _registerDirtySubmitButton() {
544
+ if (!this.ngForm) {
545
+ return;
546
+ }
547
+ this.ngForm.form.valueChanges
548
+ .pipe(takeUntil(this._destroy$))
549
+ .subscribe(() => {
550
+ this._updateDirtySubmitButtons();
551
+ });
552
+ this._buttons.changes
553
+ .pipe(takeUntil(this._destroy$))
554
+ .subscribe(() => {
555
+ this._updateDirtySubmitButtons();
556
+ });
557
+ }
558
+ _updateDirtySubmitButtons() {
559
+ this._buttons
560
+ .filter((button) => button.submit)
561
+ .forEach((submitButton) => {
562
+ if (!this.confirm || !this.dirtySubmitButton || this.ngForm.dirty || !submitButton.dirtySubmit) {
563
+ submitButton.enable();
564
+ }
565
+ else {
566
+ submitButton.disable();
567
+ }
568
+ });
569
+ }
570
+ _broadcastSubmittingEvents() {
571
+ this._status$.next(FormStatus.Submitting);
572
+ this._form.broadcast('submit', this.ngForm);
573
+ }
574
+ _broadcasValidatingEvents() {
575
+ this._status$.next(FormStatus.Validating);
576
+ }
577
+ _setupActiveSubmitButton() {
578
+ this._activeSubmitButton = this._getActiveSubmitButton();
579
+ this._resetButtons();
580
+ if (this._activeSubmitButton) {
581
+ this._activeSubmitButton.process();
582
+ }
583
+ }
584
+ _disableButtons() {
585
+ this._buttons.forEach((button) => {
586
+ button.disable();
587
+ });
588
+ }
589
+ _waitUntilStatusPending() {
590
+ return this.ngForm.statusChanges
591
+ .pipe(startWith(this.ngForm.status), first((state) => state !== 'PENDING'));
592
+ }
593
+ _handleError(e) {
594
+ console.log('%c Form Submit ', 'color: white; background-color: #D33F49', 'Error occured');
595
+ console.group('Error Details:');
596
+ console.log('Message: ', e);
597
+ console.log('FormRef: ', this);
598
+ if (this.ngForm.invalid) {
599
+ const errors = getFormErrors(this.ngForm.control, null);
600
+ console.log('Validation Errors: ', errors);
601
+ }
602
+ console.groupEnd();
603
+ this._completeSubmit(false, null);
604
+ }
605
+ _registerCanDeactivateGuard() {
606
+ this._activatedRouteConfig = getActiveRoute(this._route).routeConfig;
607
+ if (!this._activatedRouteConfig) {
608
+ return;
609
+ }
610
+ this._form.registerFormDirective(this._activatedRouteConfig.component, this);
611
+ if (!Array.isArray(this._activatedRouteConfig.canDeactivate)) {
612
+ this._activatedRouteConfig.canDeactivate = [];
613
+ }
614
+ if (this._activatedRouteConfig.canDeactivate.indexOf(FormDeactivateGuard) === -1) {
615
+ this._activatedRouteConfig.canDeactivate.push(FormDeactivateGuard);
616
+ }
617
+ }
618
+ _cleanupCanDeactivate() {
619
+ if (!this._activatedRouteConfig) {
620
+ return;
621
+ }
622
+ const guardIndex = this._activatedRouteConfig.canDeactivate.indexOf(FormDeactivateGuard);
623
+ this._activatedRouteConfig.canDeactivate.splice(guardIndex, 1);
624
+ this._form.removeFormDirective(this._activatedRouteConfig.component);
625
+ }
626
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FsFormDirective, deps: [{ token: NgForm }, { token: i1.FsForm }, { token: i0.ElementRef }, { token: i2.FsMessage }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: MatDialogRef, optional: true }, { token: DrawerRef, optional: true }, { token: i3.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Directive });
627
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: FsFormDirective, selector: "[fsForm]", inputs: { wrapperSelector: "wrapperSelector", messageSelector: "messageSelector", hintSelector: "hintSelector", labelSelector: "labelSelector", autocomplete: "autocomplete", shortcuts: "shortcuts", confirm: "confirm", confirmDialog: "confirmDialog", confirmDrawer: "confirmDrawer", confirmBrowser: "confirmBrowser", confirmTabs: "confirmTabs", dirtySubmitButton: "dirtySubmitButton", submit: "submit", successDelay: "successDelay", errorDelay: "errorDelay", tabGroup: "tabGroup", deactivationGuard: "deactivationGuard" }, outputs: { submitEvent: "fsForm", invalid: "invalid", valid: "valid", submitted: "submitted", reseted: "reseted", cleared: "cleared" }, host: { properties: { "class.fs-form": "this.fsFormClass" } }, queries: [{ propertyName: "_tabGroups", predicate: MatTabGroup, descendants: true }], exportAs: ["fsForm"], usesOnChanges: true, ngImport: i0 });
628
+ }
629
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FsFormDirective, decorators: [{
630
+ type: Directive,
631
+ args: [{
632
+ selector: '[fsForm]',
633
+ exportAs: 'fsForm',
634
+ }]
635
+ }], ctorParameters: function () { return [{ type: i4.NgForm, decorators: [{
636
+ type: Inject,
637
+ args: [NgForm]
638
+ }] }, { type: i1.FsForm }, { type: i0.ElementRef }, { type: i2.FsMessage }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i5.MatDialogRef, decorators: [{
639
+ type: Optional
640
+ }, {
641
+ type: Inject,
642
+ args: [MatDialogRef]
643
+ }] }, { type: i6.DrawerRef, decorators: [{
644
+ type: Optional
645
+ }, {
646
+ type: Inject,
647
+ args: [DrawerRef]
648
+ }] }, { type: i3.ActivatedRoute }]; }, propDecorators: { wrapperSelector: [{
649
+ type: Input
650
+ }], messageSelector: [{
651
+ type: Input
652
+ }], hintSelector: [{
653
+ type: Input
654
+ }], labelSelector: [{
655
+ type: Input
656
+ }], autocomplete: [{
657
+ type: Input
658
+ }], shortcuts: [{
659
+ type: Input
660
+ }], confirm: [{
661
+ type: Input
662
+ }], confirmDialog: [{
663
+ type: Input
664
+ }], confirmDrawer: [{
665
+ type: Input
666
+ }], confirmBrowser: [{
667
+ type: Input
668
+ }], confirmTabs: [{
669
+ type: Input
670
+ }], dirtySubmitButton: [{
671
+ type: Input
672
+ }], submit: [{
673
+ type: Input
674
+ }], successDelay: [{
675
+ type: Input
676
+ }], errorDelay: [{
677
+ type: Input
678
+ }], tabGroup: [{
679
+ type: Input
680
+ }], deactivationGuard: [{
681
+ type: Input
682
+ }], submitEvent: [{
683
+ type: Output,
684
+ args: ['fsForm']
685
+ }], invalid: [{
686
+ type: Output
687
+ }], valid: [{
688
+ type: Output
689
+ }], submitted: [{
690
+ type: Output
691
+ }], reseted: [{
692
+ type: Output
693
+ }], cleared: [{
694
+ type: Output
695
+ }], fsFormClass: [{
696
+ type: HostBinding,
697
+ args: ['class.fs-form']
698
+ }], _tabGroups: [{
699
+ type: ContentChildren,
700
+ args: [MatTabGroup, { descendants: true }]
701
+ }] } });
702
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2RpcmVjdGl2ZXMvZm9ybS9mb3JtLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLGVBQWUsRUFDZixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixXQUFXLEVBQ1gsTUFBTSxFQUNOLEtBQUssRUFDTCxNQUFNLEVBSU4sUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEdBRVYsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFtQixNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsY0FBYyxFQUFTLE1BQU0saUJBQWlCLENBQUM7QUFFeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3hELE9BQU8sRUFBVSxXQUFXLEVBQWdCLE1BQU0sd0JBQXdCLENBQUM7QUFFM0UsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRTdELE9BQU8sRUFDTCxlQUFlLEVBQ2YsS0FBSyxFQUNMLFNBQVMsRUFDVCxHQUFHLEVBRUgsRUFBRSxFQUNGLE9BQU8sRUFDUCxVQUFVLEdBQ1gsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQ0wsVUFBVSxFQUNWLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLEdBQUcsRUFDSCxLQUFLLEVBQ0wsUUFBUSxFQUNSLFNBQVMsRUFDVCxTQUFTLEVBQ1QsSUFBSSxFQUNKLFNBQVMsRUFDVCxHQUFHLEdBQ0osTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFB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SUEsT0FBTztzQkFEYixNQUFNO2dCQUlBLFdBQVc7c0JBRGpCLFdBQVc7dUJBQUMsZUFBZTtnQkFJcEIsVUFBVTtzQkFEakIsZUFBZTt1QkFBQyxXQUFXLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbnRlbnRDaGlsZHJlbixcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RCaW5kaW5nLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIE5nRm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5cbmltcG9ydCB7IE1hdERpYWxvZ1JlZiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBNYXRUYWIsIE1hdFRhYkdyb3VwLCBNYXRUYWJIZWFkZXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJzJztcblxuaW1wb3J0IHsgZ3VpZCB9IGZyb20gJ0BmaXJlc3RpdGNoL2NvbW1vbic7XG5pbXBvcnQgeyBEcmF3ZXJSZWYgfSBmcm9tICdAZmlyZXN0aXRjaC9kcmF3ZXInO1xuaW1wb3J0IHsgRnNNZXNzYWdlLCBNZXNzYWdlTW9kZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuXG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIGRlZmVyLFxuICBmcm9tRXZlbnQsXG4gIGlpZixcbiAgT2JzZXJ2YWJsZSxcbiAgb2YsXG4gIFN1YmplY3QsXG4gIHRocm93RXJyb3IsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgY2F0Y2hFcnJvcixcbiAgZGVsYXksXG4gIGZpbHRlcixcbiAgZmlyc3QsXG4gIG1hcCxcbiAgbWFwVG8sXG4gIG1lcmdlTWFwLFxuICBzdGFydFdpdGgsXG4gIHN3aXRjaE1hcCxcbiAgdGFrZSxcbiAgdGFrZVVudGlsLFxuICB0YXAsXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgRm9ybURlYWN0aXZhdGVHdWFyZCB9IGZyb20gJy4uLy4uL2d1YXJkcy9mb3JtLWRlYWN0aXZhdGUuZ3VhcmQnO1xuaW1wb3J0IHsgY29uZmlybVJlc3VsdENvbnRpbnVlIH0gZnJvbSAnLi4vLi4vaGVscGVycy9jb25maXJtLXJlc3VsdC1jb250aW51ZSc7XG5pbXBvcnQgeyBnZXRBY3RpdmVSb3V0ZSB9IGZyb20gJy4uLy4uL2hlbHBlcnMvZ2V0LWFjdGl2ZS1yb3V0ZSc7XG5pbXBvcnQgeyBnZXRGb3JtRXJyb3JzIH0gZnJvbSAnLi4vLi4vaGVscGVycy9nZXQtZm9ybS1lcnJvcnMnO1xuaW1wb3J0IHsgRnNGb3JtIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZnNmb3JtLnNlcnZpY2UnO1xuaW1wb3J0IHsgRnNCdXR0b25EaXJlY3RpdmUgfSBmcm9tICcuLi9idXR0b24uZGlyZWN0aXZlJztcblxuaW1wb3J0IHsgQ29uZmlybVJlc3VsdCB9IGZyb20gJy4vLi4vLi4vZW51bXMvY29uZmlybS1yZXN1bHQnO1xuaW1wb3J0IHsgRm9ybVN0YXR1cyB9IGZyb20gJy4vLi4vLi4vZW51bXMvZm9ybS1zdGF0dXMnO1xuaW1wb3J0IHsgQ29uZmlybUNvbmZpZywgQ29uZmlybVRhYkdyb3VwLCBTdWJtaXR0ZWRFdmVudCB9IGZyb20gJy4vLi4vLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBTdWJtaXRFdmVudCB9IGZyb20gJy4vLi4vLi4vaW50ZXJmYWNlcy9zdWJtaXQtZXZlbnQnO1xuXG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tmc0Zvcm1dJyxcbiAgZXhwb3J0QXM6ICdmc0Zvcm0nLFxufSlcbmV4cG9ydCBjbGFzcyBGc0Zvcm1EaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQWZ0ZXJDb250ZW50SW5pdCwgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgd3JhcHBlclNlbGVjdG9yID0gJy5mcy1mb3JtLXdyYXBwZXIsLm1hdC1mb3JtLWZpZWxkJztcblxuICBASW5wdXQoKVxuICBwdWJsaWMgbWVzc2FnZVNlbGVjdG9yID0gJy5mcy1mb3JtLW1lc3NhZ2UsLm1hdC1mb3JtLWZpZWxkLXN1YnNjcmlwdC13cmFwcGVyJztcblxuICBASW5wdXQoKVxuICBwdWJsaWMgaGludFNlbGVjdG9yID0gJy5mcy1mb3JtLWhpbnQsLm1hdC1mb3JtLWZpZWxkLWhpbnQtd3JhcHBlcic7XG5cbiAgQElucHV0KClcbiAgcHVibGljIGxhYmVsU2VsZWN0b3IgPSAnLmZzLWZvcm0tbGFiZWwsLm1hdC1mb3JtLWZpZWxkLWxhYmVsJztcblxuICBASW5wdXQoKVxuICBwdWJsaWMgYXV0b2NvbXBsZXRlID0gZmFsc2U7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNob3J0Y3V0cyA9IHRydWU7IC8vIEN0cmwgKyBzXG5cbiAgQElucHV0KClcbiAgcHVibGljIGNvbmZpcm06IENvbmZpcm1Db25maWcgfCBib29sZWFuID0gdHJ1ZTtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgY29uZmlybURpYWxvZyA9IHRydWU7XG5cbiAgQElucHV0KClcbiAgcHVibGljIGNvbmZpcm1EcmF3ZXIgPSB0cnVlO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjb25maXJtQnJvd3NlciA9IHRydWU7XG5cbiAgQElucHV0KClcbiAgcHVibGljIGNvbmZpcm1UYWJzID0gdHJ1ZTtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgZGlydHlTdWJtaXRCdXR0b24gPSB0cnVlO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzZXQgc3VibWl0KHN1Ym1pdCQ6IChldmVudDogU3VibWl0RXZlbnQpID0+IE9ic2VydmFibGU8YW55Pikge1xuICAgIHRoaXMuX3N1Ym1pdCQgPSBzdWJtaXQkO1xuICB9XG5cbiAgcHVibGljIGdldCBzdWJtaXQoKTogKGV2ZW50OiBTdWJtaXRFdmVudCkgPT4gT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5fc3VibWl0JDtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzdWNjZXNzRGVsYXkgPSAwO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBlcnJvckRlbGF5ID0gMTAwMDtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgdGFiR3JvdXA6IE1hdFRhYkdyb3VwO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBkZWFjdGl2YXRpb25HdWFyZCA9IHRydWU7XG5cbiAgQE91dHB1dCgnZnNGb3JtJylcbiAgcHVibGljIHN1Ym1pdEV2ZW50OiBFdmVudEVtaXR0ZXI8U3VibWl0RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgaW52YWxpZDogRXZlbnRFbWl0dGVyPFN1Ym1pdEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBAT3V0cHV0KClcbiAgcHVibGljIHZhbGlkOiBFdmVudEVtaXR0ZXI8U3VibWl0RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgc3VibWl0dGVkOiBFdmVudEVtaXR0ZXI8U3VibWl0RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgcmVzZXRlZDogRXZlbnRFbWl0dGVyPFN1Ym1pdEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBAT3V0cHV0KClcbiAgcHVibGljIGNsZWFyZWQ6IEV2ZW50RW1pdHRlcjxTdWJtaXRFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5mcy1mb3JtJylcbiAgcHVibGljIGZzRm9ybUNsYXNzID0gdHJ1ZTtcblxuICBAQ29udGVudENoaWxkcmVuKE1hdFRhYkdyb3VwLCB7IGRlc2NlbmRhbnRzOiB0cnVlIH0pXG4gIHByaXZhdGUgX3RhYkdyb3VwczogUXVlcnlMaXN0PE1hdFRhYkdyb3VwPiA9IG5ldyBRdWVyeUxpc3QoKTtcblxuICBwcml2YXRlIF9idXR0b25zID0gbmV3IFF1ZXJ5TGlzdDxGc0J1dHRvbkRpcmVjdGl2ZT4oKTtcbiAgcHJpdmF0ZSBfcmVnaXN0ZXJDb250cm9sO1xuICBwcml2YXRlIF9hY3RpdmVTdWJtaXRCdXR0b246IEZzQnV0dG9uRGlyZWN0aXZlO1xuICBwcml2YXRlIF9kaWFsb2dCYWNrZHJvcEVzY2FwZSA9IGZhbHNlO1xuICBwcml2YXRlIF9zbmFwc2hvdDogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9O1xuICBwcml2YXRlIF9hY3RpdmF0ZWRSb3V0ZUNvbmZpZzogUm91dGUgfCBudWxsO1xuICBwcml2YXRlIF9zdGF0dXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdChGb3JtU3RhdHVzLlZhbGlkKTtcbiAgcHJpdmF0ZSBfZGVzdHJveSQgPSBuZXcgU3ViamVjdCgpO1xuICBwcml2YXRlIF9jb25maXJtZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfc3VibWl0JDogKGV2ZW50OiBTdWJtaXRFdmVudCkgPT4gT2JzZXJ2YWJsZTxhbnk+ID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KE5nRm9ybSlcbiAgICBwdWJsaWMgbmdGb3JtOiBOZ0Zvcm0sXG4gICAgcHJpdmF0ZSBfZm9ybTogRnNGb3JtLFxuICAgIHByaXZhdGUgX2VsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBfbWVzc2FnZTogRnNNZXNzYWdlLFxuICAgIHByaXZhdGUgX25nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgX2NkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcblxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTWF0RGlhbG9nUmVmKVxuICAgIHByaXZhdGUgX2RpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPGFueT4sXG5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERyYXdlclJlZilcbiAgICBwcml2YXRlIF9kcmF3ZXJSZWY6IERyYXdlclJlZjxhbnk+LFxuXG4gICAgcHJpdmF0ZSBfcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICApIHsgfVxuXG4gIHB1YmxpYyBnZXQgc3VibWl0dGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdHVzJC5nZXRWYWx1ZSgpID09PSBGb3JtU3RhdHVzLlN1Ym1pdHRpbmc7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHZhbGlkYXRpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXR1cyQuZ2V0VmFsdWUoKSA9PT0gRm9ybVN0YXR1cy5WYWxpZGF0aW5nO1xuICB9XG5cbiAgcHVibGljIGdldCBjb21wbGV0aW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9zdGF0dXMkLmdldFZhbHVlKCkgPT09IEZvcm1TdGF0dXMuQ29tcGxldGluZztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IF9zdWJtaXRFdmVudCgpOiBTdWJtaXRFdmVudCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5nRm9ybTogdGhpcy5uZ0Zvcm0sXG4gICAgICBzdWJtaXR0ZXI6IHRoaXMuX3N1Ym1pdHRlcixcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgX2Zvcm1WYWxpZFN0YXRlJCgpOiBPYnNlcnZhYmxlPFN1Ym1pdHRlZEV2ZW50PiB7XG4gICAgdGhpcy5fZm9ybS5icm9hZGNhc3QoJ3ZhbGlkJywgdGhpcy5fc3VibWl0RXZlbnQpO1xuICAgIHRoaXMuc3VibWl0RXZlbnQuZW1pdCh0aGlzLl9zdWJtaXRFdmVudCk7XG4gICAgdGhpcy52YWxpZC5lbWl0KHRoaXMuX3N1Ym1pdEV2ZW50KTtcblxuICAgIGNvbnN0IHN1Ym1pdHRlZEV2ZW50OiBTdWJtaXR0ZWRFdmVudCA9IHtcbiAgICAgIG5nRm9ybTogdGhpcy5uZ0Zvcm0sXG4gICAgICBzdWJtaXR0ZXI6IHRoaXMuX3N1Ym1pdHRlcixcbiAgICAgIHJlc3BvbnNlOiBudWxsLFxuICAgIH07XG5cbiAgICBjb25zdCBzdWJtaXQkOiBPYnNlcnZhYmxlPGFueT4gPSB0aGlzLl9zdWJtaXQkID9cbiAgICAgIHRoaXMuX3N1Ym1pdCQodGhpcy5fc3VibWl0RXZlbnQpIDogb2Yoc3VibWl0dGVkRXZlbnQpO1xuXG4gICAgcmV0dXJuIHN1Ym1pdCRcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgc3VibWl0dGVkRXZlbnQucmVzcG9uc2UgPSByZXNwb25zZTtcblxuICAgICAgICAgIHJldHVybiBzdWJtaXR0ZWRFdmVudDtcbiAgICAgICAgfSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgX2Zvcm1JbnZhbGlkU3RhdGUkKCk6IE9ic2VydmFibGU8bmV2ZXI+IHtcbiAgICB0aGlzLl9mb3JtLmJyb2FkY2FzdCgnaW52YWxpZCcsIHRoaXMuX3N1Ym1pdEV2ZW50KTtcblxuICAgIGlmICh0aGlzLmludmFsaWQpIHtcbiAgICAgIHRoaXMuaW52YWxpZC5lbWl0KHRoaXMuX3N1Ym1pdEV2ZW50KTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXNzYWdlID0gJ1BsZWFzZSByZXZpZXcgZXJyb3JzIGhpZ2hsaWdodGVkIGluIHJlZCc7XG4gICAgdGhpcy5fbWVzc2FnZS5lcnJvcihtZXNzYWdlLCB7IG1vZGU6IE1lc3NhZ2VNb2RlLlRvYXN0IH0pO1xuXG4gICAgY29uc3QgZWwgPSB0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLm5nLWludmFsaWQnKTtcblxuICAgIGlmIChlbCkge1xuICAgICAgZWwuc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogJ3Ntb290aCcsIGJsb2NrOiAnbmVhcmVzdCcgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRocm93RXJyb3IoJ0Zvcm0gdmFsaWRhdGlvbiBlcnJvcicpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgX3N1Ym1pdHRlcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9hY3RpdmVTdWJtaXRCdXR0b25cbiAgICAgID8gdGhpcy5fYWN0aXZlU3VibWl0QnV0dG9uLm5hbWVcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICBpZiAodGhpcy5kZWFjdGl2YXRpb25HdWFyZCkge1xuICAgICAgdGhpcy5fcmVnaXN0ZXJDYW5EZWFjdGl2YXRlR3VhcmQoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9yZWdpc3RlckNvbmZpcm1EaWFsb2dCYWNrZHJvcEVzY2FwZSgpO1xuICAgIHRoaXMuX2xpc3RlbkhvdEtleXMoKTtcbiAgICB0aGlzLl9saXN0ZW5XaW5kb3dDbG9zZSgpO1xuICAgIHRoaXMuX2xpc3RlblN1Ym1pdCgpO1xuICAgIHRoaXMuX2xpc3RlbkZvcm1TdGF0dXMoKTtcblxuICAgIGlmICghdGhpcy5hdXRvY29tcGxldGUpIHtcbiAgICAgIHRoaXMuX3JlZ2lzdGVyQXV0b2NvbXBsZXRlKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlcy5jb25maXJtKSB7XG4gICAgICB0aGlzLl91cGRhdGVEaXJ0eVN1Ym1pdEJ1dHRvbnMoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgY2xlYXJTdWJtaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fc3VibWl0JCA9IG51bGw7XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyU3VibWl0KHN1Ym1pdCQ6ICgpID0+IE9ic2VydmFibGU8YW55Pik6IHZvaWQge1xuICAgIHRoaXMuX3N1Ym1pdCQgPSBzdWJtaXQkO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLl9jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fcmVnaXN0ZXJDb25maXJtKCk7XG4gICAgdGhpcy5fcmVnaXN0ZXJDb25maXJtRHJhd2VyQ2xvc2UoKTtcbiAgICB0aGlzLl9yZWdpc3RlckNvbmZpcm1UYWJzKCk7XG4gICAgdGhpcy5fcmVnaXN0ZXJEcmF3ZXJDbG9zZSgpO1xuICAgIHRoaXMuX3JlZ2lzdGVyRGlydHlTdWJtaXRCdXR0b24oKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9jbGVhbnVwQ2FuRGVhY3RpdmF0ZSgpO1xuICAgIHRoaXMuX2Rlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLl9kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHVibGljIGNyZWF0ZVNuYXBzaG90KCk6IHZvaWQge1xuICAgIHRoaXMuX3NuYXBzaG90ID0gdGhpcy5uZ0Zvcm0udmFsdWU7XG4gIH1cblxuICBwdWJsaWMgZ2V0U25hcHNob3QoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gICAgcmV0dXJuIHRoaXMuX3NuYXBzaG90IHx8IHt9O1xuICB9XG5cbiAgcHVibGljIHJlc2V0KCk6IHZvaWQge1xuICAgIHRoaXMubmdGb3JtLnJlc2V0Rm9ybSgpO1xuXG4gICAgT2JqZWN0LmtleXModGhpcy5uZ0Zvcm0uY29udHJvbHMpXG4gICAgICAuZm9yRWFjaCgobmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLm5nRm9ybS5jb250cm9sc1tuYW1lXTtcbiAgICAgICAgY29udHJvbC5yZXNldCh0aGlzLl9zbmFwc2hvdFtuYW1lXSk7XG4gICAgICB9KTtcblxuICAgIHRoaXMucmVzZXRlZC5lbWl0KCk7XG4gIH1cblxuICBwdWJsaWMgY2xlYXIoKTogdm9pZCB7XG4gICAgdGhpcy5uZ0Zvcm0ucmVzZXRGb3JtKCk7XG4gICAgdGhpcy5jbGVhcmVkLmVtaXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXJ0eSgpOiB2b2lkIHtcbiAgICB0aGlzLm5nRm9ybS5mb3JtLm1hcmtBc0RpcnR5KCk7XG4gICAgdGhpcy5fdXBkYXRlRGlydHlTdWJtaXRCdXR0b25zKCk7XG4gIH1cblxuICBwdWJsaWMgdHJpZ2dlclN1Ym1pdChvcHRpb25zPzogeyBjb25maXJtZWQ6IGJvb2xlYW4gfSk6IHZvaWQge1xuICAgIHRoaXMuX2NvbmZpcm1lZCA9IG9wdGlvbnM/LmNvbmZpcm1lZDtcbiAgICB0aGlzLm5nRm9ybS5uZ1N1Ym1pdC5lbWl0KCk7XG4gIH1cblxuICBwdWJsaWMgdHJpZ2dlckNvbmZpcm0oKTogT2JzZXJ2YWJsZTxDb25maXJtUmVzdWx0PiB7XG4gICAgY29uc3Qgc3VibWl0dGVkID0gdGhpcy5zdWJtaXR0aW5nID8gdGhpcy5zdWJtaXR0ZWQuYXNPYnNlcnZhYmxlKCkgOiBvZih7fSk7XG5cbiAgICByZXR1cm4gc3VibWl0dGVkXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgbWVyZ2VNYXAoKCkgPT4gdGhpcy5fZm9ybS5jb25maXJtVW5zYXZlZChbdGhpc10pKSxcbiAgICAgICk7XG4gIH1cblxuICBwdWJsaWMgZW5hYmxlKCk6IHZvaWQge1xuICAgIHRoaXMubmdGb3JtLmNvbnRyb2wuZW5hYmxlKCk7XG5cbiAgICB0aGlzLl91cGRhdGVEaXJ0eVN1Ym1pdEJ1dHRvbnMoKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNhYmxlKCk6IHZvaWQge1xuICAgIHRoaXMubmdGb3JtLmNvbnRyb2wuZGlzYWJsZSgpO1xuXG4gICAgdGhpcy5fYnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgIGJ1dHRvbi5kaXNhYmxlKCk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYWRkQnV0dG9uKGJ1dHRvbjogRnNCdXR0b25EaXJlY3RpdmUpOiB2b2lkIHtcbiAgICB0aGlzLl9idXR0b25zLnJlc2V0KFxuICAgICAgW1xuICAgICAgICAuLi50aGlzLl9idXR0b25zLnRvQXJyYXkoKSxcbiAgICAgICAgYnV0dG9uLFxuICAgICAgXSk7XG4gIH1cblxuICBwdWJsaWMgcmVtb3ZlQnV0dG9uKGJ1dHRvbjogRnNCdXR0b25EaXJlY3RpdmUpOiB2b2lkIHtcbiAgICB0aGlzLl9idXR0b25zLnJlc2V0KFxuICAgICAgW1xuICAgICAgICAuLi50aGlzLl9idXR0b25zLnRvQXJyYXkoKVxuICAgICAgICAgIC5maWx0ZXIoKGl0ZW0pID0+IChidXR0b24gIT09IGl0ZW0pKSxcbiAgICAgIF0pO1xuICB9XG5cbiAgcHVibGljIHZhbGlkYXRlKCk6IHZvaWQge1xuICAgIE9iamVjdC52YWx1ZXModGhpcy5uZ0Zvcm0uY29udHJvbHMpXG4gICAgICAuZm9yRWFjaCgoY29udHJvbCkgPT4ge1xuICAgICAgICBjb250cm9sLm1hcmtBc0RpcnR5KCk7XG4gICAgICAgIGNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xuICAgICAgICBjb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfbGlzdGVuU3VibWl0KCk6IHZvaWQge1xuICAgIHRoaXMubmdGb3JtXG4gICAgICAubmdTdWJtaXRcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgZXZlbnQ/LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH0pLFxuICAgICAgICBtYXAoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHsgZXZlbnQsIGNvbmZpcm1lZDogdGhpcy5fY29uZmlybWVkIH07XG4gICAgICAgIH0pLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5fY29uZmlybWVkID0gZmFsc2UpLFxuICAgICAgICBmaWx0ZXIoKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBbRm9ybVN0YXR1cy5WYWxpZCwgRm9ybVN0YXR1cy5JbnZhbGlkXVxuICAgICAgICAgICAgLmluY2x1ZGVzKHRoaXMuX3N0YXR1cyQuZ2V0VmFsdWUoKSk7XG4gICAgICAgIH0pLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5fYnJvYWRjYXNWYWxpZGF0aW5nRXZlbnRzKCkpLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy52YWxpZGF0ZSgpKSxcbiAgICAgICAgdGFwKCgpID0+IHRoaXMuX2Jyb2FkY2FzdFN1Ym1pdHRpbmdFdmVudHMoKSksXG4gICAgICAgIHN3aXRjaE1hcCgoZGF0YSkgPT4gdGhpcy5fd2FpdFVudGlsU3RhdHVzUGVuZGluZygpXG4gICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICBtYXBUbyhkYXRhKSxcbiAgICAgICAgICApKSxcbiAgICAgICAgdGFwKCgpID0+IHRoaXMuX3NldHVwQWN0aXZlU3VibWl0QnV0dG9uKCkpLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5fZGlzYWJsZUJ1dHRvbnMoKSksXG4gICAgICAgIG1lcmdlTWFwKChkYXRhKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMubmdGb3JtLnN0YXR1cyA9PT0gJ0lOVkFMSUQnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZm9ybUludmFsaWRTdGF0ZSQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2Zvcm1WYWxpZFN0YXRlJFxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgIG1hcCgoc3VibWl0RXZlbnQpID0+ICh7XG4gICAgICAgICAgICAgICAgLi4uc3VibWl0RXZlbnQsXG4gICAgICAgICAgICAgICAgY29uZmlybWVkOiBkYXRhLmNvbmZpcm1lZCxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApO1xuICAgICAgICB9KSxcbiAgICAgICAgY2F0Y2hFcnJvcigoZSwgc291cmNlJCkgPT4ge1xuICAgICAgICAgIHRoaXMuX2hhbmRsZUVycm9yKGUpO1xuXG4gICAgICAgICAgcmV0dXJuIHNvdXJjZSQ7XG4gICAgICAgIH0pLFxuICAgICAgICB0YXAoKHN1Ym1pdHRlZEV2ZW50OiBTdWJtaXR0ZWRFdmVudCkgPT4ge1xuICAgICAgICAgIHRoaXMuX2NvbXBsZXRlU3VibWl0KHRydWUsIHN1Ym1pdHRlZEV2ZW50KTtcbiAgICAgICAgfSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBwcml2YXRlIF9saXN0ZW5Gb3JtU3RhdHVzKCk6IHZvaWQge1xuICAgIHRoaXMuX3N0YXR1cyRcbiAgICAgIC5waXBlKFxuICAgICAgICB0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoZm9ybVN0YXR1czogRm9ybVN0YXR1cykgPT4ge1xuICAgICAgICBjb25zdCBjbHMgPSBbRm9ybVN0YXR1cy5TdWJtaXR0aW5nLCBGb3JtU3RhdHVzLlZhbGlkYXRpbmddO1xuICAgICAgICBjb25zdCBjbGFzc0xpc3QgPSB0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0O1xuICAgICAgICBjbGFzc0xpc3QucmVtb3ZlKC4uLmNscyk7XG4gICAgICAgIGlmIChjbHMuaW5kZXhPZihmb3JtU3RhdHVzKSAhPT0gLTEpIHtcbiAgICAgICAgICBjbGFzc0xpc3QuYWRkKGZvcm1TdGF0dXMpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICB9XG5cbiAgcHJpdmF0ZSBfbGlzdGVuV2luZG93Q2xvc2UoKTogdm9pZCB7XG4gICAgZnJvbUV2ZW50KHdpbmRvdywgJ2JlZm9yZXVubG9hZCcpXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5jb25maXJtICYmIHRoaXMuY29uZmlybUJyb3dzZXIgJiYgdGhpcy5uZ0Zvcm0uZGlydHkpIHtcbiAgICAgICAgICBldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2FjdGl2ZURpYWxvZyhlbCwgZGlhbG9nOiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIGlmIChlbC5pc1NhbWVOb2RlKGRpYWxvZykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAoZWwucGFyZW50RWxlbWVudCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2FjdGl2ZURpYWxvZyhlbC5wYXJlbnRFbGVtZW50LCBkaWFsb2cpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgX2xpc3RlbkhvdEtleXMoKTogdm9pZCB7XG4gICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGZyb21FdmVudChkb2N1bWVudCwgJ2tleWRvd24nKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpLFxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuX2RpYWxvZ0JhY2tkcm9wRXNjYXBlICYmIGV2ZW50LmNvZGUgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgICAgICBjb25zdCBjZGtPdmVybGF5UGFuZSA9IEFycmF5XG4gICAgICAgICAgICAgIC5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTEVsZW1lbnQ+KCcuY2RrLW92ZXJsYXktcGFuZScpKS5wb3AoKTtcbiAgICBcbiAgICAgICAgICAgIGNvbnN0IGFjdGl2ZURpYWxvZyA9IHRoaXNcbiAgICAgICAgICAgICAgLl9hY3RpdmVEaWFsb2coZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5fZGlhbG9nUmVmLmlkKSwgY2RrT3ZlcmxheVBhbmUpO1xuXG4gICAgICAgICAgICBpZiAoYWN0aXZlRGlhbG9nKSB7XG4gICAgICAgICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX2Zvcm1DbG9zZSgpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkgJiYgZXZlbnQuY29kZSA9PT0gJ0tleVMnKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5zaG9ydGN1dHMpIHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuX2VsZW1lbnRJbkZvcm0oZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5nRm9ybS5uZ1N1Ym1pdC5uZXh0KCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfZm9ybUNsb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbmZpcm0gJiYgdGhpcy5jb25maXJtRGlhbG9nKSB7XG4gICAgICB0aGlzLnRyaWdnZXJDb25maXJtKClcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgZmlsdGVyKChyZXN1bHQpID0+IGNvbmZpcm1SZXN1bHRDb250aW51ZShyZXN1bHQpKSxcbiAgICAgICAgICBzd2l0Y2hNYXAoKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gQ29uZmlybVJlc3VsdC5QcmlzdGluZSB8fCByZXN1bHQgPT09IENvbmZpcm1SZXN1bHQuRGlzY2FyZFxuICAgICAgICAgICAgICA/IG9mKG51bGwpXG4gICAgICAgICAgICAgIDogdGhpcy5zdWJtaXR0ZWQuYXNPYnNlcnZhYmxlKCk7XG4gICAgICAgICAgfSksXG4gICAgICAgICAgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSxcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKChyZXN1bHQ6IFN1Ym1pdHRlZEV2ZW50KSA9PiB7XG4gICAgICAgICAgdGhpcy5fZGlhbG9nUmVmLmNsb3NlKHJlc3VsdD8ucmVzcG9uc2UpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZGlhbG9nUmVmLmNsb3NlKG51bGwpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2dldEFjdGl2ZVN1Ym1pdEJ1dHRvbigpOiBGc0J1dHRvbkRpcmVjdGl2ZSB7XG4gICAgY29uc3Qgc3VibWl0QnV0dG9ucyA9IHRoaXMuX2J1dHRvbnNcbiAgICAgIC5maWx0ZXIoKGJ1dHRvbikgPT4gYnV0dG9uLnN1Ym1pdCk7XG5cbiAgICBjb25zdCBhY3RpdmVCdXR0b24gPSBzdWJtaXRCdXR0b25zXG4gICAgICAuZmluZCgoYnV0dG9uKSA9PiB7XG4gICAgICAgIHJldHVybiBidXR0b24uYWN0aXZlO1xuICAgICAgfSk7XG5cbiAgICByZXR1cm4gYWN0aXZlQnV0dG9uID8gYWN0aXZlQnV0dG9uIDogc3VibWl0QnV0dG9uc1swXTtcbiAgfVxuXG4gIHByaXZhdGUgX2VsZW1lbnRJbkZvcm0oZWw6IEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICBpZiAoZWwuaXNTYW1lTm9kZSh0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKGVsLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9lbGVtZW50SW5Gb3JtKGVsLnBhcmVudEVsZW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbXBsZXRlU3VibWl0KHN1Y2Nlc3MsIHN1Ym1pdEV2ZW50OiBTdWJtaXR0ZWRFdmVudCk6IHZvaWQge1xuICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICB0aGlzLm5nRm9ybS5jb250cm9sLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgICB0aGlzLmNyZWF0ZVNuYXBzaG90KCk7XG4gICAgICB0aGlzLnN1Ym1pdHRlZC5lbWl0KHN1Ym1pdEV2ZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcmVzZXRCdXR0b25zKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2FjdGl2ZVN1Ym1pdEJ1dHRvbikge1xuICAgICAgaWYgKHN1Y2Nlc3MpIHtcbiAgICAgICAgdGhpcy5fYWN0aXZlU3VibWl0QnV0dG9uLnN1Y2Nlc3MoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVN1Ym1pdEJ1dHRvbi5lcnJvcigpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX3N0YXR1cyQubmV4dChGb3JtU3RhdHVzLlN1Ym1pdHRlZCk7XG5cbiAgICBpZiAoc3VjY2Vzcykge1xuICAgICAgdGhpcy5fc3RhdHVzJC5uZXh0KEZvcm1TdGF0dXMuU3VjY2Vzcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3N0YXR1cyQubmV4dChGb3JtU3RhdHVzLkVycm9yKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdGF0dXMkLm5leHQoRm9ybVN0YXR1cy5Db21wbGV0aW5nKTtcblxuICAgIGNvbnN0IHJlc2V0RGVsYXkgPSBzdWNjZXNzID8gdGhpcy5zdWNjZXNzRGVsYXkgOiB0aGlzLmVycm9yRGVsYXk7XG5cbiAgICBvZih0cnVlKVxuICAgICAgLnBpcGUoXG4gICAgICAgIGRlbGF5KHJlc2V0RGVsYXkpLFxuICAgICAgICBmaXJzdCgpLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpLFxuICAgICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5uZ0Zvcm0uZm9ybS5zdGF0dXMgPT09ICdWQUxJRCcpIHtcbiAgICAgICAgICB0aGlzLl9zdGF0dXMkLm5leHQoRm9ybVN0YXR1cy5WYWxpZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fc3RhdHVzJC5uZXh0KEZvcm1TdGF0dXMuSW52YWxpZCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9yZXNldEJ1dHRvbnMoKTtcbiAgICAgICAgdGhpcy5fcmVzZXRBY3RpdmVCdXR0b25zKCk7XG4gICAgICAgIHRoaXMuX3VwZGF0ZURpcnR5U3VibWl0QnV0dG9ucygpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZXNldEJ1dHRvbnMoKTogdm9pZCB7XG4gICAgdGhpcy5fYnV0dG9ucy5mb3JFYWNoKChidXR0b24pID0+IHtcbiAgICAgIGJ1dHRvbi5yZXNldCgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVzZXRBY3RpdmVCdXR0b25zKCk6IHZvaWQge1xuICAgIHRoaXMuX2J1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiB7XG4gICAgICBidXR0b24ucmVzZXRBY3RpdmUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlZ2lzdGVyQ29uZmlybSgpOiB2b2lkIHtcbiAgICB0aGlzLm5nRm9ybS5mb3JtLnZhbHVlQ2hhbmdlc1xuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKChjaGFuZ2VzKSA9PiB7XG4gICAgICAgIGlmKHRoaXMuX2RpYWxvZ0JhY2tkcm9wRXNjYXBlICYmIHRoaXMuX2RpYWxvZ1JlZikge1xuICAgICAgICAgIHRoaXMuX2RpYWxvZ1JlZi5kaXNhYmxlQ2xvc2UgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY29uZmlybSkge1xuICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gT2JqZWN0LmtleXModGhpcy5fc25hcHNob3QpO1xuXG4gICAgICAgICAgT2JqZWN0LmtleXMoY2hhbmdlcylcbiAgICAgICAgICAgIC5mb3JFYWNoKChuYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nLmluZGV4T2YobmFtZSkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc25hcHNob3RbbmFtZV0gPSBjaGFuZ2VzW25hbWVdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZWdpc3RlckRyYXdlckNsb3NlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9kcmF3ZXJSZWYpIHtcbiAgICAgIHRoaXMuX2RyYXdlclJlZi5jbG9zZVN0YXJ0JFxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpLFxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKHN1YnNjcmliZXIpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5zdWJtaXR0aW5nKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0dXMkXG4gICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIGZpbHRlcigoc3RhdHVzKSA9PiBzdGF0dXMgPT09IEZvcm1TdGF0dXMuU3VjY2VzcyB8fCBzdGF0dXMgPT09IEZvcm1TdGF0dXMuRXJyb3IpLFxuICAgICAgICAgICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgLnN1YnNjcmliZSgoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PT0gRm9ybVN0YXR1cy5TdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQoKTtcbiAgICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlci5lcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN1YnNjcmliZXIubmV4dCgpO1xuICAgICAgICAgICAgc3Vic2NyaWJlci5jb21wbGV0ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfcmVnaXN0ZXJDb25maXJtRHJhd2VyQ2xvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2RyYXdlclJlZikge1xuICAgICAgdGhpcy5fZHJhd2VyUmVmLmNsb3NlU3RhcnQkXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHN3aXRjaE1hcCgoc3Vic2NyaWJlcikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGlpZihcbiAgICAgICAgICAgICAgKCkgPT4gdGhpcy5jb25maXJtICYmIHRoaXMuY29uZmlybURyYXdlcixcbiAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyQ29uZmlybSgpXG4gICAgICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgICBtYXAoKHJlc3VsdCkgPT4gY29uZmlybVJlc3VsdENvbnRpbnVlKHJlc3VsdCkpLFxuICAgICAgICAgICAgICAgICAgdGFwKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZXIubmV4dCgpO1xuICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgZGVmZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIubmV4dCgpO1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3JlZ2lzdGVyQ29uZmlybVRhYnMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudGFiR3JvdXApIHtcbiAgICAgIHRoaXMuX3JlZ2lzdGVyQ29uZmlybVRhYkdyb3VwKHRoaXMudGFiR3JvdXApO1xuICAgIH1cblxuICAgIHRoaXMuX3JlZ2lzdGVyQ29uZmlybVRhYkdyb3Vwcyh0aGlzLl90YWJHcm91cHMudG9BcnJheSgpKTtcbiAgICB0aGlzLl90YWJHcm91cHMuY2hhbmdlc1xuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5fcmVnaXN0ZXJDb25maXJtVGFiR3JvdXBzKHRoaXMuX3RhYkdyb3Vwcy50b0FycmF5KCkpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZWdpc3RlckNvbmZpcm1UYWJHcm91cHModGFiR3JvdXBzOiBNYXRUYWJHcm91cFtdKTogdm9pZCB7XG4gICAgdGFiR3JvdXBzLmZvckVhY2goKHRhYkdyb3VwOiBNYXRUYWJHcm91cCkgPT4ge1xuICAgICAgdGhpcy5fcmVnaXN0ZXJDb25maXJtVGFiR3JvdXAodGFiR3JvdXApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVnaXN0ZXJDb25maXJtVGFiR3JvdXAodGFiR3JvdXA6IE1hdFRhYkdyb3VwKTogdm9pZCB7XG4gICAgY29uc3QgY29uZmlybVRhYkdyb3VwID0gdGFiR3JvdXAgYXMgQ29uZmlybVRhYkdyb3VwO1xuICAgIGlmICghY29uZmlybVRhYkdyb3VwLl9vcmlnaW5hbEhhbmRsZUNsaWNrKSB7XG4gICAgICBjb25maXJtVGFiR3JvdXAuX29yaWdpbmFsSGFuZGxlQ2xpY2sgPSB0YWJHcm91cC5faGFuZGxlQ2xpY2s7XG4gICAgICBjb25maXJtVGFiR3JvdXAuX2hhbmRsQ2xpY2skID0gbmV3IFN1YmplY3Q8e1xuICAgICAgICAgdGFiOiBNYXRUYWI7IFxuICAgICAgICAgdGFiSGVhZGVyOiBNYXRUYWJIZWFkZXI7IFxuICAgICAgICAgaWR4OiBudW1iZXIgXG4gICAgICAgIH0+KCk7XG4gICAgICBjb25maXJtVGFiR3JvdXAuX2hhbmRsZUNsaWNrID0gKHRhYjogTWF0VGFiLCB0YWJIZWFkZXI6IE1hdFRhYkhlYWRlciwgaWR4OiBudW1iZXIpID0+IHtcbiAgICAgICAgaWYgKGNvbmZpcm1UYWJHcm91cC5faGFuZGxDbGljayQub2JzZXJ2ZXJzLmxlbmd0aCkge1xuICAgICAgICAgIGNvbmZpcm1UYWJHcm91cC5faGFuZGxDbGljayQubmV4dCh7IHRhYiwgdGFiSGVhZGVyLCBpZHggfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uZmlybVRhYkdyb3VwLl9vcmlnaW5hbEhhbmRsZUNsaWNrKHRhYiwgdGFiSGVhZGVyLCBpZHgpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbmZpcm1UYWJHcm91cC5faGFuZGxDbGljayRcbiAgICAgIC5waXBlKFxuICAgICAgICBmaWx0ZXIoKCkgPT4gIXRoaXMuc3VibWl0dGluZyksXG4gICAgICAgIHN3aXRjaE1hcCgoZXZlbnQpID0+IHtcbiAgICAgICAgICBpZih0aGlzLmNvbmZpcm0gJiYgdGhpcy5jb25maXJtVGFicykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHJpZ2dlckNvbmZpcm0oKVxuICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICB0YXAoKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgaWYgKGNvbmZpcm1SZXN1bHRDb250aW51ZShyZXN1bHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpcm1UYWJHcm91cC5zZWxlY3RlZEluZGV4ID0gZXZlbnQuaWR4O1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbmZpcm1UYWJHcm91cC5fb3JpZ2luYWxIYW5kbGVDbGljayhldmVudC50YWIsIGV2ZW50LnRhYkhlYWRlciwgZXZlbnQuaWR4KTtcblxuICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgfSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBwcml2YXRlIF9yZWdpc3RlckNvbmZpcm1EaWFsb2dCYWNrZHJvcEVzY2FwZSgpOiB2b2lkIHtcbiAgICBpZih0aGlzLl9kaWFsb2dSZWYpIHtcbiAgICAgIHRoaXMuX2RpYWxvZ0JhY2tkcm9wRXNjYXBlID0gIXRoaXMuX2RpYWxvZ1JlZj8uZGlzYWJsZUNsb3NlO1xuXG4gICAgICBpZiAodGhpcy5fZGlhbG9nQmFja2Ryb3BFc2NhcGUpIHtcbiAgICAgICAgdGhpcy5fZGlhbG9nUmVmLmJhY2tkcm9wQ2xpY2soKVxuICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSxcbiAgICAgICAgICApXG4gICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9mb3JtQ2xvc2UoKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLl9kZXN0cm95JFxuICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fZGlhbG9nUmVmLmRpc2FibGVDbG9zZSA9IGZhbHNlO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3JlZ2lzdGVyQXV0b2NvbXBsZXRlKCk6IHZvaWQge1xuICAgIHRoaXMuX3JlZ2lzdGVyQ29udHJvbCA9IHRoaXMubmdGb3JtLmZvcm0ucmVnaXN0ZXJDb250cm9sLmJpbmQodGhpcy5uZ0Zvcm0uZm9ybSk7XG5cbiAgICB0aGlzLm5nRm9ybS5mb3JtLnJlZ2lzdGVyQ29udHJvbCA9IChuYW1lOiBzdHJpbmcsIGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4ge1xuXG4gICAgICBjb25zdCBlbDogRWxlbWVudCA9IHRoaXMuX2VsZW1lbnQubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKGBpbnB1dFtuYW1lPScke25hbWV9J11gKTtcblxuICAgICAgaWYgKGVsKSB7XG4gICAgICAgIGlmICghZWwuZ2V0QXR0cmlidXRlKCdhdXRvY29tcGxldGUnKSkge1xuICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnYXV0b2NvbXBsZXRlJywgJ25vbmUnKTtcbiAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ25hbWUnLCBgJHtuYW1lfS0ke2d1aWQoKX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5fcmVnaXN0ZXJDb250cm9sKG5hbWUsIGNvbnRyb2wpO1xuICAgIH07XG4gIH1cblxuICBwcml2YXRlIF9yZWdpc3RlckRpcnR5U3VibWl0QnV0dG9uKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5uZ0Zvcm0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm5nRm9ybS5mb3JtLnZhbHVlQ2hhbmdlc1xuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5fdXBkYXRlRGlydHlTdWJtaXRCdXR0b25zKCk7XG4gICAgICB9KTtcblxuICAgIHRoaXMuX2J1dHRvbnMuY2hhbmdlc1xuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5fdXBkYXRlRGlydHlTdWJtaXRCdXR0b25zKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3VwZGF0ZURpcnR5U3VibWl0QnV0dG9ucygpOiB2b2lkIHtcbiAgICB0aGlzLl9idXR0b25zXG4gICAgICAuZmlsdGVyKChidXR0b24pID0+IGJ1dHRvbi5zdWJtaXQpXG4gICAgICAuZm9yRWFjaCgoc3VibWl0QnV0dG9uOiBGc0J1dHRvbkRpcmVjdGl2ZSkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMuY29uZmlybSB8fCAhdGhpcy5kaXJ0eVN1Ym1pdEJ1dHRvbiB8fCB0aGlzLm5nRm9ybS5kaXJ0eSB8fCAhc3VibWl0QnV0dG9uLmRpcnR5U3VibWl0KSB7XG4gICAgICAgICAgc3VibWl0QnV0dG9uLmVuYWJsZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN1Ym1pdEJ1dHRvbi5kaXNhYmxlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfYnJvYWRjYXN0U3VibWl0dGluZ0V2ZW50cygpOiB2b2lkIHtcbiAgICB0aGlzLl9zdGF0dXMkLm5leHQoRm9ybVN0YXR1cy5TdWJtaXR0aW5nKTtcbiAgICB0aGlzLl9mb3JtLmJyb2FkY2FzdCgnc3VibWl0JywgdGhpcy5uZ0Zvcm0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfYnJvYWRjYXNWYWxpZGF0aW5nRXZlbnRzKCk6IHZvaWQge1xuICAgIHRoaXMuX3N0YXR1cyQubmV4dChGb3JtU3RhdHVzLlZhbGlkYXRpbmcpO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2V0dXBBY3RpdmVTdWJtaXRCdXR0b24oKTogdm9pZCB7XG4gICAgdGhpcy5fYWN0aXZlU3VibWl0QnV0dG9uID0gdGhpcy5fZ2V0QWN0aXZlU3VibWl0QnV0dG9uKCk7XG4gICAgdGhpcy5fcmVzZXRCdXR0b25zKCk7XG5cbiAgICBpZiAodGhpcy5fYWN0aXZlU3VibWl0QnV0dG9uKSB7XG4gICAgICB0aGlzLl9hY3RpdmVTdWJtaXRCdXR0b24ucHJvY2VzcygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2Rpc2FibGVCdXR0b25zKCk6IHZvaWQge1xuICAgIHRoaXMuX2J1dHRvbnMuZm9yRWFjaCgoYnV0dG9uKSA9PiB7XG4gICAgICBidXR0b24uZGlzYWJsZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfd2FpdFVudGlsU3RhdHVzUGVuZGluZygpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLm5nRm9ybS5zdGF0dXNDaGFuZ2VzXG4gICAgICAucGlwZShcbiAgICAgICAgc3RhcnRXaXRoKHRoaXMubmdGb3JtLnN0YXR1cyksXG4gICAgICAgIGZpcnN0KChzdGF0ZSkgPT4gc3RhdGUgIT09ICdQRU5ESU5HJyksXG4gICAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBfaGFuZGxlRXJyb3IoZTogU3VibWl0dGVkRXZlbnQpIHtcbiAgICBjb25zb2xlLmxvZygnJWMgRm9ybSBTdWJtaXQgJywgJ2NvbG9yOiB3aGl0ZTsgYmFja2dyb3VuZC1jb2xvcjogI0QzM0Y0OScsICdFcnJvciBvY2N1cmVkJyk7XG4gICAgY29uc29sZS5ncm91cCgnRXJyb3IgRGV0YWlsczonKTtcbiAgICBjb25zb2xlLmxvZygnTWVzc2FnZTogJywgZSk7XG4gICAgY29uc29sZS5sb2coJ0Zvcm1SZWY6ICcsIHRoaXMpO1xuXG4gICAgaWYgKHRoaXMubmdGb3JtLmludmFsaWQpIHtcbiAgICAgIGNvbnN0IGVycm9ycyA9IGdldEZvcm1FcnJvcnModGhpcy5uZ0Zvcm0uY29udHJvbCwgbnVsbCk7XG4gICAgICBjb25zb2xlLmxvZygnVmFsaWRhdGlvbiBFcnJvcnM6ICcsIGVycm9ycyk7XG4gICAgfVxuXG4gICAgY29uc29sZS5ncm91cEVuZCgpO1xuICAgIHRoaXMuX2NvbXBsZXRlU3VibWl0KGZhbHNlLCBudWxsKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlZ2lzdGVyQ2FuRGVhY3RpdmF0ZUd1YXJkKCk6IHZvaWQge1xuICAgIHRoaXMuX2FjdGl2YXRlZFJvdXRlQ29uZmlnID0gZ2V0QWN0aXZlUm91dGUodGhpcy5fcm91dGUpLnJvdXRlQ29uZmlnO1xuXG4gICAgaWYgKCF0aGlzLl9hY3RpdmF0ZWRSb3V0ZUNvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2Zvcm0ucmVnaXN0ZXJGb3JtRGlyZWN0aXZlKHRoaXMuX2FjdGl2YXRlZFJvdXRlQ29uZmlnLmNvbXBvbmVudCwgdGhpcyk7XG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodGhpcy5fYWN0aXZhdGVkUm91dGVDb25maWcuY2FuRGVhY3RpdmF0ZSkpIHtcbiAgICAgIHRoaXMuX2FjdGl2YXRlZFJvdXRlQ29uZmlnLmNhbkRlYWN0aXZhdGUgPSBbXTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fYWN0aXZhdGVkUm91dGVDb25maWcuY2FuRGVhY3RpdmF0ZS5pbmRleE9mKEZvcm1EZWFjdGl2YXRlR3VhcmQpID09PSAtMSkge1xuICAgICAgdGhpcy5fYWN0aXZhdGVkUm91dGVDb25maWcuY2FuRGVhY3RpdmF0ZS5wdXNoKEZvcm1EZWFjdGl2YXRlR3VhcmQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2NsZWFudXBDYW5EZWFjdGl2YXRlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5fYWN0aXZhdGVkUm91dGVDb25maWcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBndWFyZEluZGV4ID0gdGhpcy5fYWN0aXZhdGVkUm91dGVDb25maWcuY2FuRGVhY3RpdmF0ZS5pbmRleE9mKEZvcm1EZWFjdGl2YXRlR3VhcmQpO1xuICAgIHRoaXMuX2FjdGl2YXRlZFJvdXRlQ29uZmlnLmNhbkRlYWN0aXZhdGUuc3BsaWNlKGd1YXJkSW5kZXgsIDEpO1xuXG4gICAgdGhpcy5fZm9ybS5yZW1vdmVGb3JtRGlyZWN0aXZlKHRoaXMuX2FjdGl2YXRlZFJvdXRlQ29uZmlnLmNvbXBvbmVudCk7XG4gIH1cblxufVxuIl19