@sumaris-net/ngx-components 18.23.21 → 18.23.23

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.
@@ -4,7 +4,7 @@ import { PUBKEY_REGEXP } from '../constants';
4
4
  import { isEmptyArray, isNil, isNilOrBlank, isNotNil, isNotNilOrBlank, isNotNilOrNaN, toBoolean, toNumber } from '../functions';
5
5
  import { DateUtils, fromDateISOString } from '../dates';
6
6
  import { delay, from, isObservable, merge, of, Subject, Subscription } from 'rxjs';
7
- import { catchError, first, switchMap, takeUntil, tap } from 'rxjs/operators';
7
+ import { catchError, finalize, first, switchMap, takeUntil, tap } from 'rxjs/operators';
8
8
  // @dynamic
9
9
  export class SharedValidators {
10
10
  static _DOUBLE_REGEXP_CACHE = {
@@ -581,14 +581,20 @@ export class SharedAsyncValidators {
581
581
  return of(res);
582
582
  }),
583
583
  // DEBUG
584
- tap((res) => debug && console.debug(logPrefix + `Finished in ${Date.now() - now}ms (${res ? 'with errors' : 'no error'})`, res)), catchError((error) => {
585
- console.error('[debounceTime-validator] Error while executing validator. Stopping job', error);
586
- $disposeSubject.next();
587
- throw error;
588
- }),
584
+ tap((res) => debug && console.debug(logPrefix + `Finished in ${Date.now() - now}ms (${res ? 'with errors' : 'no error'})`, res)),
589
585
  // Refresh UI, after a successful execution
590
586
  tap(() => opts?.markForCheck && opts?.markForCheck()),
591
- // Make sure to stop, because of the switchMap
587
+ // Catch error
588
+ catchError((error) => {
589
+ console.error(logPrefix + 'Error while executing validator. Stopping job', error);
590
+ $disposeSubject.next();
591
+ return of(null);
592
+ }), finalize(() => {
593
+ if (debug)
594
+ console.debug(logPrefix + 'Validator disposed.');
595
+ $disposeSubject.unsubscribe();
596
+ }),
597
+ // Make sure to stop
592
598
  takeUntil(disposeEvent$));
593
599
  };
594
600
  }
@@ -600,8 +606,10 @@ export class SharedAsyncValidators {
600
606
  * @param opts
601
607
  */
602
608
  static registerAsyncValidator(form, validatorFn, opts) {
609
+ if (!form)
610
+ throw new Error('Cannot register async validator: form control is null or undefined.');
603
611
  if (form.asyncValidator)
604
- throw Error('Form already have an async validator. Cannot configure job');
612
+ throw new Error(`Form control already has an async validator. Clear it first or use a different control.`);
605
613
  const debounceTime = toNumber(opts?.debounceTime, 250);
606
614
  const $dispose = new Subject();
607
615
  const asyncValidatorFn = SharedAsyncValidators.debounceTime(validatorFn, { ...opts, debounceTime, dispose: $dispose });
@@ -611,7 +619,6 @@ export class SharedAsyncValidators {
611
619
  subscription.add(() => {
612
620
  // Clear added validator. Must be done NOW (without delay) because generally a new Job is given just after
613
621
  form.clearAsyncValidators();
614
- // Stop the job, with a delay to let the last execution finished
615
622
  setTimeout(() => {
616
623
  $dispose.next();
617
624
  $dispose.unsubscribe();
@@ -620,4 +627,4 @@ export class SharedAsyncValidators {
620
627
  return subscription;
621
628
  }
622
629
  }
623
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL3ZhbGlkYXRvci92YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxlQUFlLEdBT2hCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUFFLFFBQVEsRUFBc0IsTUFBTSxRQUFRLENBQUM7QUFDdEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNoSSxPQUFPLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ3hELE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0YsT0FBTyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU5RSxXQUFXO0FBQ1gsTUFBTSxPQUFPLGdCQUFnQjtJQUNuQixNQUFNLENBQUMsb0JBQW9CLEdBQUc7UUFDcEMsUUFBUSxFQUFFLG1CQUFtQjtRQUM3QixDQUFDLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCO1FBQ3ZDLENBQUMsRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUI7UUFDN0MsQ0FBQyxFQUFFLHVCQUF1QixFQUFFLGlCQUFpQjtLQUM5QyxDQUFDO0lBRU0sTUFBTSxDQUFDLGVBQWUsQ0FBQyxXQUFtQjtRQUNoRCxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUM7WUFBRSxPQUFPLElBQUksQ0FB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biAgQWJzdHJhY3RDb250cm9sLFxuICBBc3luY1ZhbGlkYXRvckZuLFxuICBVbnR5cGVkRm9ybUFycmF5LFxuICBVbnR5cGVkRm9ybUNvbnRyb2wsXG4gIFVudHlwZWRGb3JtR3JvdXAsXG4gIFZhbGlkYXRpb25FcnJvcnMsXG4gIFZhbGlkYXRvckZuLFxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBpc01vbWVudCwgTW9tZW50LCB1bml0T2ZUaW1lIH0gZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IFBVQktFWV9SRUdFWFAgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgaXNFbXB0eUFycmF5LCBpc05pbCwgaXNOaWxPckJsYW5rLCBpc05vdE5pbCwgaXNOb3ROaWxPckJsYW5rLCBpc05vdE5pbE9yTmFOLCB0b0Jvb2xlYW4sIHRvTnVtYmVyIH0gZnJvbSAnLi4vZnVuY3Rpb25zJztcbmltcG9ydCB7IERhdGVVdGlscywgZnJvbURhdGVJU09TdHJpbmcgfSBmcm9tICcuLi9kYXRlcyc7XG5pbXBvcnQgeyBkZWxheSwgZnJvbSwgaXNPYnNlcnZhYmxlLCBtZXJnZSwgT2JzZXJ2YWJsZSwgb2YsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgZmlyc3QsIHN3aXRjaE1hcCwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbi8vIEBkeW5hbWljXG5leHBvcnQgY2xhc3MgU2hhcmVkVmFsaWRhdG9ycyB7XG4gIHByaXZhdGUgc3RhdGljIF9ET1VCTEVfUkVHRVhQX0NBQ0hFID0ge1xuICAgIE5PX0xJTUlUOiAvXi0/XFxkKyhbLixdXFxkKik/JC8sXG4gICAgMTogL14tP1xcZCsoWy4sXVxcZCk/JC8sIC8vIDEgZGVjaW1hbCBtYXhcbiAgICAyOiAvXi0/XFxkKyhbLixdXFxkezEsMn0pPyQvLCAvLyAyIGRlY2ltYWxzIG1heFxuICAgIDM6IC9eLT9cXGQrKFsuLF1cXGR7MSwzfSk/JC8sIC8vIDMgZGVjaW1hbHMgbWF4XG4gIH07XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0RG91YmxlUmVnZXhwKG1heERlY2ltYWxzOiBudW1iZXIpOiBSZWdFeHAge1xuICAgIGlmIChpc05pbChtYXhEZWNpbWFscykpIHJldHVybiB0aGlzLl9ET1VCTEVfUkVHRVhQX0NBQ0hFLk5PX0xJTUlUO1xuXG4gICAgaWYgKG1heERlY2ltYWxzIDwgMCkgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG1heERlY2ltYWxzIHZhbHVlOiAke21heERlY2ltYWxzfWApO1xuICAgIGNvbnN0IHJlZ2V4cCA9IHRoaXMuX0RPVUJMRV9SRUdFWFBfQ0FDSEVbbWF4RGVjaW1hbHNdO1xuICAgIGlmIChyZWdleHApIHJldHVybiByZWdleHA7XG5cbiAgICAvLyBOZXc6IGFkZCB0byBjYWNoZVxuICAgIHRoaXMuX0RPVUJMRV9SRUdFWFBfQ0FDSEVbbWF4RGVjaW1hbHNdID0gbmV3IFJlZ0V4cChgXi0/XFxcXGQrKFsuLF1cXFxcZHsxLCR7bWF4RGVjaW1hbHN9fSk/JGApO1xuICAgIHJldHVybiB0aGlzLl9ET1VCTEVfUkVHRVhQX0NBQ0hFW21heERlY2ltYWxzXTtcbiAgfVxuXG4gIHN0YXRpYyBlcXVhbHMob3RoZXJDb250cm9sTmFtZTogc3RyaW5nKTogVmFsaWRhdG9yRm4ge1xuICAgIHJldHVybiAoYzogQWJzdHJhY3RDb250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgY29uc3Qgb3RoZXJDb250cm9sID0gYy5wYXJlbnQ/LmdldChvdGhlckNvbnRyb2xOYW1lKTtcbiAgICAgIGlmIChvdGhlckNvbnRyb2wgJiYgYy52YWx1ZSAhPT0gb3RoZXJDb250cm9sLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZXF1YWxzOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyByZWFkb25seSBJMThOX0VSUk9SX0tFWVMgPSB7XG4gICAgcmVxdWlyZWQ6ICdFUlJPUi5GSUVMRF9SRVFVSVJFRCcsXG4gICAgbWluOiAnRVJST1IuRklFTERfTUlOJyxcbiAgICBtYXg6ICdFUlJPUi5GSUVMRF9NQVgnLFxuICAgIG1pbmxlbmd0aDogJ0VSUk9SLkZJRUxEX01JTl9MRU5HVEgnLFxuICAgIG1heGxlbmd0aDogJ0VSUk9SLkZJRUxEX01BWF9MRU5HVEgnLFxuICAgIHB1YmtleTogJ0VSUk9SLkZJRUxEX05PVF9WQUxJRF9QVUJLRVknLFxuICAgIHZhbGlkRGF0ZTogJ0VSUk9SLkZJRUxEX05PVF9WQUxJRF9EQVRFJyxcbiAgICBkYXRlSXNBZnRlcjogJ0VSUk9SLkZJRUxEX05PVF9WQUxJRF9EQVRFX0FGVEVSJyxcbiAgICBkYXRlSXNCZWZvcmU6ICdFUlJPUi5GSUVMRF9OT1RfVkFMSURfREFURV9CRUZPUkUnLFxuICAgIGRhdGVSYW5nZTogJ0VSUk9SLkZJRUxEX05PVF9WQUxJRF9EQVRFX1JBTkdFJyxcbiAgICBkYXRlTWluRHVyYXRpb246ICdFUlJPUi5GSUVMRF9OT1RfVkFMSURfREFURV9NSU5fRFVSQVRJT04nLFxuICAgIGRhdGVNYXhEdXJhdGlvbjogJ0VSUk9SLkZJRUxEX05PVF9WQUxJRF9EQVRFX01BWF9EVVJBVElPTicsXG4gICAgbWF4RGVjaW1hbHM6ICdFUlJPUi5GSUVMRF9NQVhJTVVNX0RFQ0lNQUxTJyxcbiAgICBkZWNpbWFsOiAnRVJST1IuRklFTERfTk9UX1ZBTElEX0RFQ0lNQUwnLFxuICAgIGludGVnZXI6ICdFUlJPUi5GSUVMRF9OT1RfVkFMSURfSU5URUdFUicsXG4gICAgcHJlY2lzaW9uOiAnRVJST1IuRklFTERfTk9UX1ZBTElEX1BSRUNJU0lPTicsXG4gICAgZW1haWw6ICdFUlJPUi5GSUVMRF9OT1RfVkFMSURfRU1BSUwnLFxuICAgIGxhdGl0dWRlOiAnRVJST1IuRklFTERfTk9UX1ZBTElEX0xBVElUVURFJyxcbiAgICBsb25naXR1ZGU6ICdFUlJPUi5GSUVMRF9OT1RfVkFMSURfTE9OR0lUVURFJyxcbiAgICBwYXR0ZXJuOiAnRVJST1IuRklFTERfTk9UX1ZBTElEX1BBVFRFUk4nLFxuICAgIHVuaXF1ZTogJ0VSUk9SLkZJRUxEX05PVF9VTklRVUUnLFxuICAgIGVudGl0eTogJ0VSUk9SLkZJRUxEX0lOVkFMSUQnLFxuICAgIGludmFsaWQ6ICdFUlJPUi5GSUVMRF9JTlZBTElEJyxcbiAgICBpbmNvbnNpc3RlbnQ6ICdFUlJPUi5GSUVMRF9JTkNPTlNJU1RFTlQnLFxuICAgIGVxdWFsczogJ0VSUk9SLkZJRUxEX05PVF9FUVVBTFMnLFxuICB9O1xuXG4gIHN0YXRpYyBsYXRpdHVkZShjb250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCB7XG4gICAgY29uc3QgdmFsdWUgPSBjb250cm9sLnZhbHVlO1xuICAgIGlmIChpc05vdE5pbCh2YWx1ZSkgJiYgKHZhbHVlIDwgLTkwIHx8IHZhbHVlID4gOTApKSB7XG4gICAgICByZXR1cm4geyBsYXRpdHVkZTogdHJ1ZSB9O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBsb25naXR1ZGUoY29udHJvbDogVW50eXBlZEZvcm1Db250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xuICAgIGNvbnN0IHZhbHVlID0gY29udHJvbC52YWx1ZTtcbiAgICBpZiAoaXNOb3ROaWwodmFsdWUpICYmICh2YWx1ZSA8IC0xODAgfHwgdmFsdWUgPiAxODApKSB7XG4gICAgICByZXR1cm4geyBsb25naXR1ZGU6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzdGF0aWMgb2JqZWN0KGNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcbiAgICBjb25zdCB2YWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHJldHVybiB7IG9iamVjdDogdHJ1ZSB9O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBlbnRpdHkoY29udHJvbDogVW50eXBlZEZvcm1Db250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xuICAgIGNvbnN0IHZhbHVlID0gY29udHJvbC52YWx1ZTtcbiAgICBpZiAodmFsdWUgJiYgKHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcgfHwgaXNOaWwodmFsdWUuaWQpKSkge1xuICAgICAgcmV0dXJuIHsgZW50aXR5OiB0cnVlIH07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3RhdGljIGVudGl0aWVzKGNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcbiAgICBjb25zdCB2YWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgaWYgKHZhbHVlICYmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkgfHwgdmFsdWUuZXZlcnkoKGUpID0+IGlzTmlsKGU/LmlkKSkpKSB7XG4gICAgICByZXR1cm4geyBlbnRpdHk6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzdGF0aWMgZW1wdHkoY29udHJvbDogVW50eXBlZEZvcm1Db250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xuICAgIGlmIChpc05vdE5pbE9yQmxhbmsoY29udHJvbC52YWx1ZSkpIHtcbiAgICAgIHJldHVybiB7IGVtcHR5OiB0cnVlIH07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3RhdGljIHB1YmtleShjb250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCB7XG4gICAgY29uc3QgdmFsdWUgPSBjb250cm9sLnZhbHVlO1xuICAgIGlmICh2YWx1ZSAmJiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyB8fCAhUFVCS0VZX1JFR0VYUC50ZXN0KHZhbHVlKSkpIHtcbiAgICAgIHJldHVybiB7IHB1YmtleTogdHJ1ZSB9O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBpbnRlZ2VyKGNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcbiAgICBpZiAoaXNOaWxPckJsYW5rKGNvbnRyb2wudmFsdWUpKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCB2YWx1ZSA9IHBhcnNlRmxvYXQoY29udHJvbC52YWx1ZSk7XG4gICAgaWYgKGlzTmFOKHZhbHVlKSB8fCAodmFsdWUgfCAwKSAhPT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiB7IGludGVnZXI6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzdGF0aWMgZGVjaW1hbChvcHRzPzogeyBtYXhEZWNpbWFscz86IG51bWJlciB9KTogVmFsaWRhdG9yRm4ge1xuICAgIGNvbnN0IHJlZ2V4cCA9IHRoaXMuZ2V0RG91YmxlUmVnZXhwKG9wdHM/Lm1heERlY2ltYWxzKTtcbiAgICByZXR1cm4gKGNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gY29udHJvbC52YWx1ZTtcbiAgICAgIGlmIChOdW1iZXIuaXNOYU4odmFsdWUpKSB7XG4gICAgICAgIC8vIERFQlVHXG4gICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIldBUk46IEdldHRpbmcgYSBOYU4gdmFsdWUgKGRlY2ltYWwgd2FzIGV4cGVjdGVkKSAhXCIpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChpc05vdE5pbCh2YWx1ZSkgJiYgdmFsdWUgIT09ICcnICYmICFyZWdleHAudGVzdCh2YWx1ZSBhcyBzdHJpbmcpKSB7XG4gICAgICAgIHJldHVybiBpc05vdE5pbChvcHRzPy5tYXhEZWNpbWFscykgPyB7IG1heERlY2ltYWxzOiB7IG1heERlY2ltYWxzOiBvcHRzLm1heERlY2ltYWxzIH0gfSA6IHsgZGVjaW1hbDogdHJ1ZSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBwcmVjaXNpb24uIGUuZy4gaWYgcHJlY2lzaW9uPTAuNSB0aGVuIHZhbHVlPTAuNiBpcyBpbnZhbGlkLCBidXQgMS41IGlzIHZhbGlkXG4gICAqXG4gICAqIEBwYXJhbSBwcmVjaXNpb25cbiAgICovXG4gIHN0YXRpYyBwcmVjaXNpb24ocHJlY2lzaW9uOiBudW1iZXIpOiBWYWxpZGF0b3JGbiB7XG4gICAgaWYgKGlzTmlsKHByZWNpc2lvbikpIHRocm93IG5ldyBFcnJvcignUmVxdWlyZWQgYSBub3QgbmlsIHByZWNpc2lvbicpO1xuXG4gICAgLy8gV0FSTjogd2Ugc2hvdWxkIGRlZmluZSBhIG11bHRpcGxpZXIsIGJlY2F1c2UgbW9kdWxvIGluIGphdmFzY3JpcHQgd2lsbCBvbmx5IHdvcmsgb24gaW50ZWdlclxuICAgIC8vIChlLmcuIFwiNyAlIDAuMVwiIGluIGphdmFzY3JpcHQgd2lsbCBOT1QgcmV0dXJuIHplcm8gKGJ1dCAwLjA5OTk5OTk5OTk5OTk5OTYyKVxuICAgIGNvbnN0IHByZWNpc2lvbk5iRGVjaW1hbHMgPSAocHJlY2lzaW9uLnRvU3RyaW5nKCkuc3BsaXQoJy4nKVsxXSB8fCAnJykubGVuZ3RoO1xuICAgIGNvbnN0IG11bHRpcGxpZXIgPSBNYXRoLnBvdygxMCwgcHJlY2lzaW9uTmJEZWNpbWFscyk7XG4gICAgY29uc3QgbXVsdGlwbGllZFByZWNpc2lvbiA9IE1hdGgucm91bmQobXVsdGlwbGllciAqIHByZWNpc2lvbik7XG5cbiAgICAvLyBUaGUgdmFsaWRhdG9yIGZ1bmN0aW9uXG4gICAgcmV0dXJuIChjb250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgICBpZiAoaXNOaWxPckJsYW5rKHZhbHVlKSB8fCBOdW1iZXIuaXNOYU4odmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgLy8gV0FSTjogQ29udmVydCB2YWx1ZSBpbnRvIGludGVnZXIsIGJlZm9yZSBhcHBseWluZyBtb2R1bG8gb3BlcmF0b3JcbiAgICAgIGNvbnN0IG1vZCA9IE1hdGgucm91bmQoK3ZhbHVlICogbXVsdGlwbGllcikgJSBtdWx0aXBsaWVkUHJlY2lzaW9uO1xuICAgICAgaWYgKG1vZCAhPT0gMCkge1xuICAgICAgICAvLyBERUJVR1xuICAgICAgICAvL2NvbnNvbGUuZGVidWcoYFdBUk4gR2V0dGluZyBhICR7dmFsdWV9IHdpdGggYW4gaW52YWxpZCBwcmVjaXNpb24gKGV4cGVjdGVkIHByZWNpc2lvbiBpczogJHtwcmVjaXNpb259KWApO1xuICAgICAgICByZXR1cm4geyBwcmVjaXNpb246IHsgcHJlY2lzaW9uIH0gfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgdmFsaWREYXRlVGltZShyZXF1aXJlZFRpbWUgPSB0cnVlKTogVmFsaWRhdG9yRm4ge1xuICAgIHJldHVybiAoY29udHJvbDogVW50eXBlZEZvcm1Db250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBjb250cm9sLnZhbHVlO1xuICAgICAgY29uc3QgZGF0ZSA9ICF2YWx1ZSB8fCBpc01vbWVudCh2YWx1ZSkgPyB2YWx1ZSA6IGZyb21EYXRlSVNPU3RyaW5nKHZhbHVlLCB7c3RyaWN0OiBmYWxzZSwgdW5kZWZpbmVkSWZJbnZhbGlkOiBmYWxzZSwgcmVxdWlyZWRUaW1lfSk7XG4gICAgICBpZiAoZGF0ZSAmJiAoIWRhdGUuaXNWYWxpZCgpIHx8IGRhdGUueWVhcigpIDwgMTkwMCB8fCAocmVxdWlyZWRUaW1lICYmIERhdGVVdGlscy5pc05vVGltZShkYXRlKSkpKSB7XG4gICAgICAgIHJldHVybiB7IHZhbGlkRGF0ZTogdHJ1ZSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZERhdGUgPSBTaGFyZWRWYWxpZGF0b3JzLnZhbGlkRGF0ZVRpbWUodHJ1ZSk7XG4gIHN0YXRpYyB2YWxpZERhdGVBbGxvd05vVGltZSA9IFNoYXJlZFZhbGlkYXRvcnMudmFsaWREYXRlVGltZShmYWxzZSk7XG5cbiAgc3RhdGljIGRhdGVJc0FmdGVyKHByZXZpb3VzVmFsdWU6IE1vbWVudCwgZXJyb3JQYXJhbTogc3RyaW5nLCBncmFudWxhcml0eT86IHVuaXRPZlRpbWUuU3RhcnRPZik6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gZnJvbURhdGVJU09TdHJpbmcoY29udHJvbC52YWx1ZSk7XG4gICAgICBpZiAoaXNOb3ROaWwodmFsdWUpICYmIGlzTm90TmlsKHByZXZpb3VzVmFsdWUpICYmIHZhbHVlLmlzU2FtZU9yQmVmb3JlKHByZXZpb3VzVmFsdWUsIGdyYW51bGFyaXR5KSkge1xuICAgICAgICAvLyBSZXR1cm4gdGhlIGVycm9yXG4gICAgICAgIHJldHVybiB7IGRhdGVJc0FmdGVyOiB7IG1pbkRhdGU6IGVycm9yUGFyYW0gfSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBkYXRlSXNCZWZvcmUobWF4VmFsdWU6IE1vbWVudCwgZXJyb3JQYXJhbTogc3RyaW5nLCBncmFudWxhcml0eT86IHVuaXRPZlRpbWUuU3RhcnRPZik6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gZnJvbURhdGVJU09TdHJpbmcoY29udHJvbC52YWx1ZSk7XG4gICAgICBpZiAoaXNOb3ROaWwodmFsdWUpICYmIGlzTm90TmlsKG1heFZhbHVlKSAmJiB2YWx1ZS5pc1NhbWVPckFmdGVyKG1heFZhbHVlLCBncmFudWxhcml0eSkpIHtcbiAgICAgICAgLy8gUmV0dXJuIHRoZSBlcnJvclxuICAgICAgICByZXR1cm4geyBkYXRlSXNCZWZvcmU6IHsgbWF4RGF0ZTogZXJyb3JQYXJhbSB9IH07XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIGRhdGVSYW5nZUVuZChzdGFydERhdGVGaWVsZE5hbWU6IHN0cmluZywgbXNnPzogc3RyaW5nKTogVmFsaWRhdG9yRm4ge1xuICAgIGNvbnN0IGVycm9yQ29kZSA9IG1zZyA/ICdtc2cnIDogJ2RhdGVSYW5nZSc7XG4gICAgY29uc3QgZXJyb3IgPSBtc2cgPyB7IG1zZyB9IDogeyBkYXRlUmFuZ2U6IHRydWUgfTtcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIC8vIEZvcm0gZ3JvdXAgbm90IGNyZWF0ZWQgeWV0OiBza2lwXG4gICAgICBpZiAoIWNvbnRyb2wucGFyZW50KSByZXR1cm4gbnVsbDtcblxuICAgICAgY29uc3Qgc3RhcnRDb250cm9sID0gY29udHJvbC5wYXJlbnQuZ2V0KHN0YXJ0RGF0ZUZpZWxkTmFtZSk7XG4gICAgICBpZiAoIXN0YXJ0Q29udHJvbCkge1xuICAgICAgICBjb25zb2xlLndhcm4oYENhbm5vdCBmaW5kIGJyb3RoZXIgY29udHJvbCAnJHtzdGFydERhdGVGaWVsZE5hbWV9JyBpbiB0aGUgcGFyZW50IGZvcm1gKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBjb25zdCBzdGFydERhdGUgPSBmcm9tRGF0ZUlTT1N0cmluZyhzdGFydENvbnRyb2wudmFsdWUpO1xuICAgICAgY29uc3QgZW5kRGF0ZSA9IGZyb21EYXRlSVNPU3RyaW5nKGNvbnRyb2wudmFsdWUpO1xuICAgICAgLy8gRXJyb3IgaWYgdmFsdWUgPD0gYmVmb3JlRGF0ZVxuICAgICAgaWYgKGlzTm90TmlsKGVuZERhdGUpICYmIGlzTm90TmlsKHN0YXJ0RGF0ZSkgJiYgZW5kRGF0ZS5pc1NhbWVPckJlZm9yZShzdGFydERhdGUpKSB7XG4gICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgIH1cbiAgICAgIC8vIE9LOiBjbGVhciBleGlzdGluZyBlcnJvcnNcbiAgICAgIFNoYXJlZFZhbGlkYXRvcnMuY2xlYXJFcnJvcihjb250cm9sLCBlcnJvckNvZGUpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBkYXRlUmFuZ2VTdGFydChlbmREYXRlRmllbGROYW1lOiBzdHJpbmcsIG1zZz86IHN0cmluZyk6IFZhbGlkYXRvckZuIHtcbiAgICBjb25zdCBlcnJvckNvZGUgPSBtc2cgPyAnbXNnJyA6ICdkYXRlUmFuZ2UnO1xuICAgIGNvbnN0IGVycm9yID0gbXNnID8geyBtc2cgfSA6IHsgZGF0ZVJhbmdlOiB0cnVlIH07XG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICAvLyBGb3JtIGdyb3VwIG5vdCBjcmVhdGVkIHlldDogc2tpcFxuICAgICAgaWYgKCFjb250cm9sLnBhcmVudCkgcmV0dXJuIG51bGw7XG5cbiAgICAgIGNvbnN0IGVuZERhdGVDb250cm9sID0gY29udHJvbC5wYXJlbnQuZ2V0KGVuZERhdGVGaWVsZE5hbWUpO1xuICAgICAgaWYgKCFlbmREYXRlQ29udHJvbCkge1xuICAgICAgICBjb25zb2xlLndhcm4oYENhbm5vdCBmaW5kIGNvbnRyb2wgJyR7ZW5kRGF0ZUZpZWxkTmFtZX0nIGluIHRoZSBwYXJlbnQgZm9ybWApO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGVuZERhdGUgPSBmcm9tRGF0ZUlTT1N0cmluZyhlbmREYXRlQ29udHJvbC52YWx1ZSk7XG4gICAgICBjb25zdCBzdGFydERhdGUgPSBmcm9tRGF0ZUlTT1N0cmluZyhjb250cm9sLnZhbHVlKTtcbiAgICAgIC8vIEVycm9yIGlmIHZhbHVlIDw9IGJlZm9yZURhdGVcbiAgICAgIGlmIChpc05vdE5pbChzdGFydERhdGUpICYmIGlzTm90TmlsKGVuZERhdGUpICYmIHN0YXJ0RGF0ZS5pc1NhbWVPckFmdGVyKGVuZERhdGUpKSB7XG4gICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgIH1cbiAgICAgIC8vIE9LOiBjbGVhciBleGlzdGluZyBlcnJvcnNcbiAgICAgIFNoYXJlZFZhbGlkYXRvcnMuY2xlYXJFcnJvcihjb250cm9sLCBlcnJvckNvZGUpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBjb3B5UGFyZW50RXJyb3JzKGVycm9yTmFtZXM/OiBzdHJpbmdbXSk6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIC8vIFNraXAgaWYgY29udHJvbCBhbHJlYWR5IGhhcyBzb21lIGVycm9yc1xuICAgICAgaWYgKGNvbnRyb2wuZXJyb3JzKSByZXR1cm4gbnVsbDtcbiAgICAgIC8vIFNraXAgaWYgcGFyZW50IGZvcm0gZ3JvdXAgbm90IGNyZWF0ZWQgeWV0XG4gICAgICBpZiAoIWNvbnRyb2wucGFyZW50KSByZXR1cm4gbnVsbDtcblxuICAgICAgLy8gRm9ybSBncm91cCBub3QgY3JlYXRlZCB5ZXRcbiAgICAgIGlmICghY29udHJvbC5wYXJlbnQpIHJldHVybiBudWxsO1xuXG4gICAgICBjb25zdCBlcnJvcnMgPSBjb250cm9sLnBhcmVudC5lcnJvcnM7XG5cbiAgICAgIC8vIE5vIGVycm9ycywgb3IgY29weSBhbGwgZXJyb3JzXG4gICAgICBpZiAoIWVycm9ycyB8fCBpc0VtcHR5QXJyYXkoZXJyb3JOYW1lcykpIHJldHVybiBlcnJvcnM7XG5cbiAgICAgIC8vIENvcHkgb25seSBleHBlY3RlZCBlcnJvcnNcbiAgICAgIHJldHVybiBPYmplY3Qua2V5cyhlcnJvcnMpLnJlZHVjZSgocmVzLCBrZXkpID0+IHtcbiAgICAgICAgaWYgKGVycm9yTmFtZXMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgIHJlc1trZXldID0gZXJyb3JzW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgIH0sIHt9KTtcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIGNsZWFyRXJyb3IoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBlcnJvckNvZGU6IHN0cmluZykge1xuICAgIGlmIChjb250cm9sLmhhc0Vycm9yKGVycm9yQ29kZSkpIHtcbiAgICAgIGNvbnN0IGVycm9ycyA9IGNvbnRyb2wuZXJyb3JzO1xuICAgICAgaWYgKGVycm9ycyAmJiBlcnJvcnNbZXJyb3JDb2RlXSkge1xuICAgICAgICAvLyBPbmx5IG9uZSBlcnJvcjogcmVzZXQgZXJyb3JzXG4gICAgICAgIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhlcnJvcnMpLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKG51bGwpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE90aGVyIGVycm9ycyBleGlzdHM6IGp1c3QgcmVtb3ZlIHRoaXMgZXJyb3JcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGVycm9yc1tlcnJvckNvZGVdO1xuICAgICAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKGVycm9ycyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gQGR5bmFtaWNcbmV4cG9ydCBjbGFzcyBTaGFyZWRGb3JtR3JvdXBWYWxpZGF0b3JzIHtcbiAgc3RhdGljIGRhdGVSYW5nZShcbiAgICBzdGFydERhdGVGaWVsZDogc3RyaW5nLFxuICAgIGVuZERhdGVGaWVsZDogc3RyaW5nLFxuICAgIG9wdHM/OiB7IG1zZz86IHN0cmluZzsgZmllbGRPbmx5PzogYm9vbGVhbjsgc2tpcElmTm9UaW1lPzogYm9vbGVhbiB9IHwgc3RyaW5nXG4gICk6IFZhbGlkYXRvckZuIHtcbiAgICBjb25zdCBtc2cgPSB0eXBlb2Ygb3B0cyA9PT0gJ3N0cmluZycgPyBvcHRzIDogb3B0cz8ubXNnO1xuICAgIGNvbnN0IGZpZWxkT25seSA9IHR5cGVvZiBvcHRzID09PSAnb2JqZWN0JyA/IG9wdHM/LmZpZWxkT25seSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBza2lwSWZOb1RpbWUgPSB0eXBlb2Ygb3B0cyA9PT0gJ29iamVjdCcgPyBvcHRzPy5za2lwSWZOb1RpbWUgOiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBlcnJvckNvZGUgPSBpc05vdE5pbE9yQmxhbmsobXNnKSA/ICdtc2cnIDogJ2RhdGVSYW5nZSc7XG4gICAgY29uc3QgcmFuZ2VFcnJvciA9IG1zZyA/IHsgbXNnIH0gOiB7IGRhdGVSYW5nZTogdHJ1ZSB9O1xuICAgIHJldHVybiAoZ3JvdXA6IFVudHlwZWRGb3JtR3JvdXApOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCBzdGFydERhdGUgPSBmcm9tRGF0ZUlTT1N0cmluZyhncm91cC5nZXQoc3RhcnREYXRlRmllbGQpLnZhbHVlKTtcbiAgICAgIGNvbnN0IGVuZEZpZWxkID0gZ3JvdXAuZ2V0KGVuZERhdGVGaWVsZCk7XG4gICAgICBjb25zdCBlbmREYXRlID0gZnJvbURhdGVJU09TdHJpbmcoZW5kRmllbGQudmFsdWUpO1xuXG4gICAgICBjb25zdCBoYXNTdGFydERhdGUgPSBpc05vdE5pbChzdGFydERhdGUpICYmICghc2tpcElmTm9UaW1lIHx8IERhdGVVdGlscy5pc05vVGltZShzdGFydERhdGUpKTtcbiAgICAgIGNvbnN0IGhhc0VuZERhdGUgPSBpc05vdE5pbChlbmREYXRlKSAmJiAoIXNraXBJZk5vVGltZSB8fCBEYXRlVXRpbHMuaXNOb1RpbWUoZW5kRGF0ZSkpO1xuICAgICAgaWYgKGhhc1N0YXJ0RGF0ZSAmJiBoYXNFbmREYXRlICYmIHN0YXJ0RGF0ZS5pc0FmdGVyKGVuZERhdGUpKSB7XG4gICAgICAgIC8vIFVwZGF0ZSBlbmQgZmllbGRcbiAgICAgICAgZW5kRmllbGQubWFya0FzUGVuZGluZygpO1xuICAgICAgICBlbmRGaWVsZC5zZXRFcnJvcnMoe1xuICAgICAgICAgIC4uLmVuZEZpZWxkLmVycm9ycyxcbiAgICAgICAgICAuLi5yYW5nZUVycm9yLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gUmV0dXJuIHRoZSBlcnJvciAoc2hvdWxkIGJlIGFwcGxpZWQgdG8gdGhlIHBhcmVudCBmb3JtLCBieSBkZWZhdWx0KVxuICAgICAgICByZXR1cm4gZmllbGRPbmx5ID8gbnVsbCA6IHJhbmdlRXJyb3I7XG4gICAgICB9XG4gICAgICAvLyBPSzogcmVtb3ZlIHRoZSBleGlzdGluZyBvbiB0aGUgZW5kIGZpZWxkXG4gICAgICBTaGFyZWRWYWxpZGF0b3JzLmNsZWFyRXJyb3IoZW5kRmllbGQsIGVycm9yQ29kZSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIGRhdGVNYXhEdXJhdGlvbihcbiAgICBzdGFydERhdGVGaWVsZDogc3RyaW5nLFxuICAgIGVuZERhdGVGaWVsZDogc3RyaW5nLFxuICAgIG1heER1cmF0aW9uOiBudW1iZXIsXG4gICAgZHVyYXRpb25Vbml0PzogbW9tZW50LnVuaXRPZlRpbWUuRGlmZixcbiAgICBvcHRzPzogeyBza2lwSWZOb1RpbWU/OiBib29sZWFuIH1cbiAgKTogVmFsaWRhdG9yRm4ge1xuICAgIGNvbnN0IG1heER1cmF0aW9uRXJyb3IgPSB7IGRhdGVNYXhEdXJhdGlvbjogdHJ1ZSB9O1xuICAgIGNvbnN0IHNraXBJZk5vVGltZSA9IG9wdHM/LnNraXBJZk5vVGltZTtcblxuICAgIHJldHVybiAoZ3JvdXA6IFVudHlwZWRGb3JtR3JvdXApOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCBzdGFydERhdGUgPSBmcm9tRGF0ZUlTT1N0cmluZyhncm91cC5nZXQoc3RhcnREYXRlRmllbGQpLnZhbHVlKTtcbiAgICAgIGNvbnN0IGVuZEZpZWxkID0gZ3JvdXAuZ2V0KGVuZERhdGVGaWVsZCk7XG4gICAgICBjb25zdCBlbmREYXRlID0gZnJvbURhdGVJU09TdHJpbmcoZW5kRmllbGQudmFsdWUpO1xuXG4gICAgICBjb25zdCBoYXNTdGFydERhdGUgPSBpc05vdE5pbChzdGFydERhdGUpICYmICghc2tpcElmTm9UaW1lIHx8IERhdGVVdGlscy5pc05vVGltZShzdGFydERhdGUpKTtcbiAgICAgIGNvbnN0IGhhc0VuZERhdGUgPSBpc05vdE5pbChlbmREYXRlKSAmJiAoIXNraXBJZk5vVGltZSB8fCBEYXRlVXRpbHMuaXNOb1RpbWUoZW5kRGF0ZSkpO1xuXG4gICAgICBpZiAoaGFzU3RhcnREYXRlICYmIGhhc0VuZERhdGUgJiYgTWF0aC5hYnMoc3RhcnREYXRlLmRpZmYoZW5kRGF0ZSwgZHVyYXRpb25Vbml0KSkgPiBtYXhEdXJhdGlvbikge1xuICAgICAgICAvLyBVcGRhdGUgZW5kIGZpZWxkXG4gICAgICAgIGVuZEZpZWxkLm1hcmtBc1RvdWNoZWQoeyBvbmx5U2VsZjogdHJ1ZSB9KTtcbiAgICAgICAgZW5kRmllbGQubWFya0FzUGVuZGluZygpO1xuICAgICAgICBlbmRGaWVsZC5zZXRFcnJvcnMoe1xuICAgICAgICAgIC4uLmVuZEZpZWxkLmVycm9ycyxcbiAgICAgICAgICAuLi5tYXhEdXJhdGlvbkVycm9yLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gUmV0dXJuIHRoZSBlcnJvciAoc2hvdWxkIGJlIGFwcGx5IHRvIHRoZSBwYXJlbnQgZm9ybSlcbiAgICAgICAgcmV0dXJuIG1heER1cmF0aW9uRXJyb3I7XG4gICAgICB9XG4gICAgICAvLyBPSzogcmVtb3ZlIHRoZSBleGlzdGluZyBvbiB0aGUgZW5kIGZpZWxkXG4gICAgICBTaGFyZWRWYWxpZGF0b3JzLmNsZWFyRXJyb3IoZW5kRmllbGQsICdkYXRlTWF4RHVyYXRpb24nKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgZGF0ZU1pbkR1cmF0aW9uKHN0YXJ0RGF0ZUZpZWxkOiBzdHJpbmcsIGVuZERhdGVGaWVsZDogc3RyaW5nLCBtaW5EdXJhdGlvbjogbnVtYmVyLCBkdXJhdGlvblVuaXQ/OiBtb21lbnQudW5pdE9mVGltZS5EaWZmKTogVmFsaWRhdG9yRm4ge1xuICAgIHJldHVybiAoZ3JvdXA6IFVudHlwZWRGb3JtR3JvdXApOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCBlbmRGaWVsZCA9IGdyb3VwLmdldChlbmREYXRlRmllbGQpO1xuICAgICAgY29uc3Qgc3RhcnREYXRlID0gZnJvbURhdGVJU09TdHJpbmcoZ3JvdXAuZ2V0KHN0YXJ0RGF0ZUZpZWxkKS52YWx1ZSk7XG4gICAgICBjb25zdCBlbmREYXRlID0gZnJvbURhdGVJU09TdHJpbmcoZW5kRmllbGQudmFsdWUpO1xuICAgICAgaWYgKGlzTm90TmlsKHN0YXJ0RGF0ZSkgJiYgaXNOb3ROaWwoZW5kRGF0ZSkgJiYgTWF0aC5hYnMoc3RhcnREYXRlLmRpZmYoZW5kRGF0ZSwgZHVyYXRpb25Vbml0KSkgPCBtaW5EdXJhdGlvbikge1xuICAgICAgICAvLyBVcGRhdGUgZW5kIGZpZWxkXG4gICAgICAgIGNvbnN0IGVuZEZpZWxkRXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JzID0gZW5kRmllbGQuZXJyb3JzIHx8IHt9O1xuICAgICAgICBlbmRGaWVsZEVycm9yc1snZGF0ZU1pbkR1cmF0aW9uJ10gPSB0cnVlO1xuICAgICAgICBlbmRGaWVsZC5zZXRFcnJvcnMoZW5kRmllbGRFcnJvcnMpO1xuICAgICAgICBlbmRGaWVsZC5tYXJrQXNUb3VjaGVkKHsgb25seVNlbGY6IHRydWUgfSk7XG4gICAgICAgIC8vIFJldHVybiB0aGUgZXJyb3IgKHNob3VsZCBiZSBhcHBseSB0byB0aGUgcGFyZW50IGZvcm0pXG4gICAgICAgIHJldHVybiB7IGRhdGVNaW5EdXJhdGlvbjogdHJ1ZSB9O1xuICAgICAgfVxuICAgICAgLy8gT0s6IHJlbW92ZSB0aGUgZXhpc3Rpbmcgb24gdGhlIGVuZCBmaWVsZFxuICAgICAgZWxzZSB7XG4gICAgICAgIFNoYXJlZFZhbGlkYXRvcnMuY2xlYXJFcnJvcihlbmRGaWVsZCwgJ2RhdGVNaW5EdXJhdGlvbicpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyByZXF1aXJlZElmKFxuICAgIGZpZWxkTmFtZTogc3RyaW5nLFxuICAgIGFub3RoZXJGaWVsZFRvQ2hlY2s6IHN0cmluZyB8IEFic3RyYWN0Q29udHJvbCxcbiAgICBvcHRzPzoge1xuICAgICAgZmllbGRPbmx5PzogYm9vbGVhbjtcbiAgICAgIGlzRW1wdHk/OiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiBib29sZWFuO1xuICAgICAgcHJlZGljYXRlPzogKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4gYm9vbGVhbjtcbiAgICB9XG4gICk6IFZhbGlkYXRvckZuIHtcbiAgICBjb25zdCBpc0VtcHR5ID0gb3B0cz8uaXNFbXB0eSB8fCAoKGNvbnRyb2wpID0+IGlzTmlsT3JCbGFuayhjb250cm9sPy52YWx1ZSkpO1xuICAgIGNvbnN0IHByZWRpY2F0ZSA9IG9wdHM/LnByZWRpY2F0ZSB8fCAoKGNvbnRyb2wpID0+IGlzTm90TmlsT3JCbGFuayhjb250cm9sPy52YWx1ZSkpO1xuICAgIHJldHVybiAoZ3JvdXA6IFVudHlwZWRGb3JtR3JvdXApOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCBjb250cm9sID0gZ3JvdXAuZ2V0KGZpZWxkTmFtZSk7XG4gICAgICBpZiAoIWNvbnRyb2wpIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGZpbmQgY29udHJvbCAnJHtmaWVsZE5hbWV9JyB1c2VkIGJ5IFNoYXJlRm9ybUdyb3VwVmFsaWRhdG9ycy5yZXF1aXJlZElmIHZhbGlkYXRvciFgKTtcbiAgICAgIGNvbnN0IGFub3RoZXJDb250cm9sID0gYW5vdGhlckZpZWxkVG9DaGVjayBpbnN0YW5jZW9mIEFic3RyYWN0Q29udHJvbCA/IGFub3RoZXJGaWVsZFRvQ2hlY2sgOiBncm91cC5nZXQoYW5vdGhlckZpZWxkVG9DaGVjayk7XG4gICAgICBpZiAoIWFub3RoZXJDb250cm9sKSB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBmaW5kIGNvbnRyb2wgJHt0eXBlb2YgYW5vdGhlckZpZWxkVG9DaGVjayA9PT0gJ3N0cmluZycgPyBhbm90aGVyRmllbGRUb0NoZWNrICArICcgJyA6ICcnfXVzZWQgYnkgU2hhcmVGb3JtR3JvdXBWYWxpZGF0b3JzLnJlcXVpcmVkSWYgdmFsaWRhdG9yIWApO1xuICAgICAgaWYgKGlzRW1wdHkoY29udHJvbCkgJiYgcHJlZGljYXRlKGFub3RoZXJDb250cm9sKSkge1xuICAgICAgICBjb25zdCBlcnJvciA9IHsgcmVxdWlyZWQ6IHRydWUgfTtcbiAgICAgICAgY29udHJvbC5zZXRFcnJvcnMoZXJyb3IpO1xuICAgICAgICBjb250cm9sLm1hcmtBc1RvdWNoZWQoeyBvbmx5U2VsZjogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuIG9wdHM/LmZpZWxkT25seSA/IG51bGwgOiBlcnJvcjtcbiAgICAgIH1cbiAgICAgIFNoYXJlZFZhbGlkYXRvcnMuY2xlYXJFcnJvcihjb250cm9sLCAncmVxdWlyZWQnKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgcmVxdWlyZWRJZlRydWUoXG4gICAgZmllbGROYW1lOiBzdHJpbmcsXG4gICAgYW5vdGhlckZpZWxkVG9DaGVjazogc3RyaW5nIHwgQWJzdHJhY3RDb250cm9sLFxuICAgIG9wdHM/OiB7XG4gICAgICBmaWVsZE9ubHk/OiBib29sZWFuO1xuICAgICAgaXNFbXB0eT86IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IGJvb2xlYW47XG4gICAgfVxuICApOiBWYWxpZGF0b3JGbiB7XG4gICAgY29uc3QgaXNFbXB0eSA9IG9wdHM/LmlzRW1wdHkgfHwgKChjb250cm9sKSA9PiBpc05pbE9yQmxhbmsoY29udHJvbC52YWx1ZSkpO1xuICAgIHJldHVybiAoZ3JvdXA6IFVudHlwZWRGb3JtR3JvdXApOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCBjb250cm9sID0gZ3JvdXAuZ2V0KGZpZWxkTmFtZSk7XG4gICAgICBjb25zdCBhbm90aGVyQ29udHJvbCA9IGFub3RoZXJGaWVsZFRvQ2hlY2sgaW5zdGFuY2VvZiBBYnN0cmFjdENvbnRyb2wgPyBhbm90aGVyRmllbGRUb0NoZWNrIDogZ3JvdXAuZ2V0KGFub3RoZXJGaWVsZFRvQ2hlY2spO1xuICAgICAgaWYgKCFhbm90aGVyQ29udHJvbCkgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBmaWVsZCB0byBjaGVjayEnKTtcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wpICYmIHRvQm9vbGVhbihhbm90aGVyQ29udHJvbC52YWx1ZSwgZmFsc2UpKSB7XG4gICAgICAgIGNvbnN0IGVycm9yID0geyByZXF1aXJlZDogdHJ1ZSB9O1xuICAgICAgICBjb250cm9sLnNldEVycm9ycyhlcnJvcik7XG4gICAgICAgIGNvbnRyb2wubWFya0FzVG91Y2hlZCh7IG9ubHlTZWxmOiB0cnVlIH0pO1xuICAgICAgICByZXR1cm4gb3B0cz8uZmllbGRPbmx5ID8gbnVsbCA6IGVycm9yO1xuICAgICAgfVxuICAgICAgU2hhcmVkVmFsaWRhdG9ycy5jbGVhckVycm9yKGNvbnRyb2wsICdyZXF1aXJlZCcpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyByZXF1aXJlZElmRW1wdHkoXG4gICAgZmllbGROYW1lOiBzdHJpbmcsXG4gICAgYW5vdGhlckZpZWxkVG9DaGVjazogc3RyaW5nLFxuICAgIG9wdHM/OiB7XG4gICAgICBmaWVsZE9ubHk/OiBib29sZWFuO1xuICAgICAgaXNFbXB0eT86IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IGJvb2xlYW47XG4gICAgfVxuICApOiBWYWxpZGF0b3JGbiB7XG4gICAgY29uc3QgaXNFbXB0eSA9IG9wdHM/LmlzRW1wdHkgfHwgKChjb250cm9sKSA9PiBpc05pbE9yQmxhbmsoY29udHJvbC52YWx1ZSkpO1xuICAgIHJldHVybiAoZ3JvdXA6IFVudHlwZWRGb3JtR3JvdXApOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCBjb250cm9sID0gZ3JvdXAuZ2V0KGZpZWxkTmFtZSk7XG4gICAgICBpZiAoaXNFbXB0eShjb250cm9sKSAmJiBpc05pbE9yQmxhbmsoZ3JvdXAuZ2V0KGFub3RoZXJGaWVsZFRvQ2hlY2spLnZhbHVlKSkge1xuICAgICAgICBjb25zdCBlcnJvciA9IHsgcmVxdWlyZWQ6IHRydWUgfTtcbiAgICAgICAgY29udHJvbC5zZXRFcnJvcnMoZXJyb3IpO1xuICAgICAgICBjb250cm9sLm1hcmtBc1RvdWNoZWQoeyBvbmx5U2VsZjogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuIG9wdHM/LmZpZWxkT25seSA/IG51bGwgOiBlcnJvcjtcbiAgICAgIH1cbiAgICAgIFNoYXJlZFZhbGlkYXRvcnMuY2xlYXJFcnJvcihjb250cm9sLCAncmVxdWlyZWQnKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgcHJvcGFnYXRlSWZEaXJ0eShmaWVsZE5hbWU6IHN0cmluZywgZmllbGROYW1lVG9Qcm9wYWdhdGU6IHN0cmluZywgdmFsdWVUb1Byb3BhZ2F0ZTogYW55KTogVmFsaWRhdG9yRm4ge1xuICAgIHJldHVybiAoZ3JvdXA6IFVudHlwZWRGb3JtR3JvdXApOiBudWxsID0+IHtcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSBncm91cC5nZXQoZmllbGROYW1lKTtcbiAgICAgIGNvbnN0IGNvbnRyb2xUb1Byb3BhZ2F0ZSA9IGdyb3VwLmdldChmaWVsZE5hbWVUb1Byb3BhZ2F0ZSk7XG4gICAgICBpZiAoY29udHJvbC5kaXJ0eSAmJiBjb250cm9sVG9Qcm9wYWdhdGUudmFsdWUgIT09IHZhbHVlVG9Qcm9wYWdhdGUpIHtcbiAgICAgICAgY29udHJvbFRvUHJvcGFnYXRlLnNldFZhbHVlKHZhbHVlVG9Qcm9wYWdhdGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTYW1lIGFzIGNvbXBvc2UsIGJ1dCBrZWVwIG9ubHkgdGhlIGZpcnN0IGVycm9ycyAoaW5zdGVhZCBvZiB0aGUgdW5pb24pXG4gICAqXG4gICAqIEBwYXJhbSB2YWxpZGF0b3JzXG4gICAqL1xuICBmaXJzdCh2YWxpZGF0b3JzOiAoVmFsaWRhdG9yRm4gfCBudWxsIHwgdW5kZWZpbmVkKVtdKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xuICAgIHJldHVybiAoY29udHJvbCkgPT5cbiAgICAgIHZhbGlkYXRvcnNcbiAgICAgICAgLmZpbHRlcihpc05vdE5pbClcbiAgICAgICAgLm1hcCgodmFsaWRhdG9yKSA9PiB2YWxpZGF0b3IoY29udHJvbCkpXG4gICAgICAgIC5maW5kKGlzTm90TmlsKSB8fCBudWxsO1xuICB9XG59XG5cbi8vIEBkeW5hbWljXG5leHBvcnQgY2xhc3MgU2hhcmVkRm9ybUFycmF5VmFsaWRhdG9ycyB7XG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB1bmlxdWVuZXNzIG9mIGFuIGVudGl0eSBpbiBhIEZvcm1BcnJheVxuICAgKlxuICAgKiBAcGFyYW0gY29udHJvbE5hbWUgdGhlIG5hbWUgb2YgdGhlIGNvbnRyb2wgaW4gRm9ybUFycmF5XG4gICAqL1xuICBzdGF0aWMgdW5pcXVlRW50aXR5KGNvbnRyb2xOYW1lOiBzdHJpbmcpOiBWYWxpZGF0b3JGbiB7XG4gICAgcmV0dXJuIChhcnJheTogVW50eXBlZEZvcm1BcnJheSk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IGNvbnRyb2xzOiBBYnN0cmFjdENvbnRyb2xbXSA9IFtdO1xuICAgICAgaWYgKGFycmF5Lmxlbmd0aCkge1xuICAgICAgICAvLyBnYXRoZXIgY29udHJvbHMgaW4gYXJyYXkgd2l0aCB2YWxpZCBlbnRpdHlcbiAgICAgICAgZm9yIChjb25zdCBjb250cm9sIG9mIGFycmF5LmNvbnRyb2xzKSB7XG4gICAgICAgICAgY29uc3QgZnJvbUdyb3VwID0gY29udHJvbCBhcyBVbnR5cGVkRm9ybUdyb3VwO1xuICAgICAgICAgIGlmIChmcm9tR3JvdXAuY29udHJvbHNbY29udHJvbE5hbWVdKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGZyb21Hcm91cC5jb250cm9sc1tjb250cm9sTmFtZV0udmFsdWU7XG4gICAgICAgICAgICBpZiAoISF2YWx1ZSAmJiAhIXZhbHVlLmlkKSBjb250cm9scy5wdXNoKGZyb21Hcm91cC5jb250cm9sc1tjb250cm9sTmFtZV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBnZXQgb2NjdXJyZW5jZXMgb2YgZW50aXR5IGJ5IGlkXG4gICAgICAgIGNvbnN0IG9jY3VycmVuY2VzID0gY29udHJvbHMucmVkdWNlKChhY2MsIGNvbnRyb2wpID0+IHtcbiAgICAgICAgICBjb25zdCBpZCA9IGNvbnRyb2wudmFsdWUuaWQ7XG4gICAgICAgICAgaWYgKGFjY1tpZF0pIGFjY1tpZF0rKztcbiAgICAgICAgICBlbHNlIGFjY1tpZF0gPSAxO1xuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sIHt9KTtcbiAgICAgICAgLy8gZ2V0IGNvbnRyb2xzIHdpdGggdmFsdWUgb2NjdXJyZW5jZXMgPiAxXG4gICAgICAgIGNvbnN0IGVycm9yID0geyB1bmlxdWVFbnRpdHk6IHRydWUgfTtcbiAgICAgICAgbGV0IHJldHVybkVycm9yID0gZmFsc2U7XG4gICAgICAgIGNvbnRyb2xzXG4gICAgICAgICAgLmZpbHRlcigoY29udHJvbCkgPT4gb2NjdXJyZW5jZXNbY29udHJvbC52YWx1ZS5pZF0gPiAxKVxuICAgICAgICAgIC5mb3JFYWNoKChjb250cm9sKSA9PiB7XG4gICAgICAgICAgICBsZXQgZXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JzID0gY29udHJvbC5lcnJvcnMgfHwge307XG4gICAgICAgICAgICBlcnJvcnMgPSB7IC4uLmVycm9ycywgLi4uZXJyb3IgfTtcbiAgICAgICAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKGVycm9ycyk7XG4gICAgICAgICAgICBjb250cm9sLm1hcmtBc1RvdWNoZWQoeyBvbmx5U2VsZjogdHJ1ZSB9KTtcbiAgICAgICAgICAgIHJldHVybkVycm9yID0gdHJ1ZTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJldHVybkVycm9yKSByZXR1cm4gZXJyb3I7XG4gICAgICB9XG4gICAgICBjb250cm9scy5mb3JFYWNoKChjb250cm9sKSA9PiBTaGFyZWRWYWxpZGF0b3JzLmNsZWFyRXJyb3IoY29udHJvbCwgJ3VuaXF1ZUVudGl0eScpKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgcmVxdWlyZWRBcnJheU1pbkxlbmd0aChtaW5MZW5ndGg/OiBudW1iZXIpOiBWYWxpZGF0b3JGbiB7XG4gICAgbWluTGVuZ3RoID0gbWluTGVuZ3RoIHx8IDE7XG4gICAgcmV0dXJuIChhcnJheTogVW50eXBlZEZvcm1BcnJheSk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGlmICghYXJyYXkgfHwgYXJyYXkubGVuZ3RoIDwgbWluTGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiB7IHJlcXVpcmVkOiB0cnVlIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIGFycmF5TWF4TGVuZ3RoKG1heExlbmd0aD86IG51bWJlcik6IFZhbGlkYXRvckZuIHtcbiAgICBtYXhMZW5ndGggPSBtYXhMZW5ndGggfHwgMTtcbiAgICByZXR1cm4gKGFycmF5OiBVbnR5cGVkRm9ybUFycmF5KTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgaWYgKGFycmF5ICYmIGFycmF5Lmxlbmd0aCA+IG1heExlbmd0aCkge1xuICAgICAgICByZXR1cm4geyBtYXhMZW5ndGg6IG1heExlbmd0aCB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGUgc3VtIG9mIGNvbnRyb2wgdmFsdWVzIGluIGFuIEZvcm1BcnJheSBub3Qgb3ZlcmZsb3cgdGhlIG1heCB2YWx1ZVxuICAgKlxuICAgKiBAcGFyYW0gY29udHJvbE5hbWUgdGhlIG5hbWUgb2YgdGhlIGNvbnRyb2wgaW4gRm9ybUFycmF5XG4gICAqIEBwYXJhbSBtYXggdGhlIG1heGltdW0gdmFsdWVcbiAgICovXG4gIHN0YXRpYyB2YWxpZFN1bU1heFZhbHVlKGNvbnRyb2xOYW1lOiBzdHJpbmcsIG1heDogbnVtYmVyKTogVmFsaWRhdG9yRm4ge1xuICAgIHJldHVybiAoYXJyYXk6IFVudHlwZWRGb3JtQXJyYXkpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCBjb250cm9sczogQWJzdHJhY3RDb250cm9sW10gPSBbXTtcbiAgICAgIGlmIChhcnJheS5sZW5ndGgpIHtcbiAgICAgICAgZm9yIChjb25zdCBjb250cm9sIG9mIGFycmF5LmNvbnRyb2xzKSB7XG4gICAgICAgICAgY29uc3QgZnJvbUdyb3VwID0gY29udHJvbCBhcyBVbnR5cGVkRm9ybUdyb3VwO1xuICAgICAgICAgIGlmIChmcm9tR3JvdXAuY29udHJvbHNbY29udHJvbE5hbWVdICYmIGlzTm90TmlsT3JOYU4oZnJvbUdyb3VwLmNvbnRyb2xzW2NvbnRyb2xOYW1lXS52YWx1ZSkpIHtcbiAgICAgICAgICAgIGNvbnRyb2xzLnB1c2goZnJvbUdyb3VwLmNvbnRyb2xzW2NvbnRyb2xOYW1lXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb250cm9scy5yZWR1Y2UoKHN1bSwgY29udHJvbCkgPT4gc3VtICsgY29udHJvbC52YWx1ZSwgMCkgPiBtYXgpIHtcbiAgICAgICAgICBjb25zdCBlcnJvciA9IHsgc3VtTWF4VmFsdWU6IHRydWUgfTtcbiAgICAgICAgICBjb250cm9scy5mb3JFYWNoKChjb250cm9sKSA9PiB7XG4gICAgICAgICAgICBsZXQgZXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JzID0gY29udHJvbC5lcnJvcnMgfHwge307XG4gICAgICAgICAgICBlcnJvcnMgPSB7IC4uLmVycm9ycywgLi4uZXJyb3IgfTtcbiAgICAgICAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKGVycm9ycyk7XG4gICAgICAgICAgICBjb250cm9sLm1hcmtBc1RvdWNoZWQoeyBvbmx5U2VsZjogdHJ1ZSB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnRyb2xzLmZvckVhY2goKGNvbnRyb2wpID0+IFNoYXJlZFZhbGlkYXRvcnMuY2xlYXJFcnJvcihjb250cm9sLCAnc3VtTWF4VmFsdWUnKSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIE9ic2VydmFibGVWYWxpZGF0b3JGbiA9IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IE9ic2VydmFibGU8VmFsaWRhdGlvbkVycm9ycyB8IG51bGw+O1xuZXhwb3J0IHR5cGUgUHJvbWlzZVZhbGlkYXRvckZuID0gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4gUHJvbWlzZTxWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbD47XG5cbi8vIEBkeW5hbWljXG5leHBvcnQgY2xhc3MgU2hhcmVkQXN5bmNWYWxpZGF0b3JzIHtcbiAgcHJpdmF0ZSBzdGF0aWMgREVCT1VOQ0VfVElNRV9WQUxJREFUT1JfSUQgPSAwO1xuXG4gIC8qKlxuICAgKiBBZGQgYSBkZWJvdW5jZSB0aW1lIHRvIGEgdmFsaWRhdG9yLlxuICAgKlxuICAgKiBAcGFyYW0gZm9ybVxuICAgKiBAcGFyYW0gdmFsaWRhdG9yRm5cbiAgICogQHBhcmFtIG9wdHMgVXNlIG9wdHMuc3RvcFN1YmplY3QgdG8gc3RvcCB0aGUgdmFsaWRhdG9yLCBiZWZvcmUgZW5kXG4gICAqL1xuICBzdGF0aWMgZGVib3VuY2VUaW1lKFxuICAgIHZhbGlkYXRvckZuOiBWYWxpZGF0b3JGbiB8IEFzeW5jVmFsaWRhdG9yRm4sXG4gICAgb3B0cz86IHtcbiAgICAgIGRpc3Bvc2U/OiBPYnNlcnZhYmxlPGFueT47XG4gICAgICBkZWJvdW5jZVRpbWU/OiBudW1iZXI7XG4gICAgICBtYXJrRm9yQ2hlY2s/OiAoKSA9PiB2b2lkO1xuICAgICAgZGVidWc/OiBib29sZWFuO1xuICAgIH1cbiAgKTogT2JzZXJ2YWJsZVZhbGlkYXRvckZuIHtcbiAgICAvLyBERUJVRyBvbmx5XG4gICAgY29uc3QgZGVidWcgPSBvcHRzPy5kZWJ1ZyB8fCBmYWxzZTtcbiAgICBjb25zdCBsb2dQcmVmaXggPSBkZWJ1ZyAmJiBgW2RlYm91bmNlVGltZS12YWxpZGF0b3JdICMke1NoYXJlZEFzeW5jVmFsaWRhdG9ycy5ERUJPVU5DRV9USU1FX1ZBTElEQVRPUl9JRCsrfSAtIGA7XG4gICAgY29uc3QgZGVib3VuY2VUaW1lID0gdG9OdW1iZXIob3B0cz8uZGVib3VuY2VUaW1lLCAyNTApO1xuXG4gICAgLy8gREVCVUdcbiAgICBpZiAoZGVidWcpIGNvbnNvbGUuZGVidWcobG9nUHJlZml4ICsgYE5ldyB2YWxpZGF0b3Igd2l0aCBhIGRlYm91bmNlVGltZSBhdCAke2RlYm91bmNlVGltZX1tc2ApO1xuXG4gICAgY29uc3QgJGRpc3Bvc2VTdWJqZWN0ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgICBjb25zdCBkaXNwb3NlRXZlbnQkID0gb3B0cz8uZGlzcG9zZSA/IG1lcmdlKCRkaXNwb3NlU3ViamVjdCwgb3B0cz8uZGlzcG9zZSkgOiAkZGlzcG9zZVN1YmplY3Q7XG5cbiAgICAvLyBERUJVR1xuICAgIGlmIChkZWJ1ZyAmJiBvcHRzPy5kaXNwb3NlKSB7XG4gICAgICBvcHRzPy5kaXNwb3NlLnBpcGUoZmlyc3QoKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgY29uc29sZS5kZWJ1Zyhsb2dQcmVmaXggKyAnU3RvcHBpbmcnKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiAoY29udHJvbCkgPT4ge1xuICAgICAgaWYgKGRlYnVnKSBjb25zb2xlLmRlYnVnKGxvZ1ByZWZpeCArICdGb3JtIGFzayB2YWxpZGF0aW9uLi4uJyk7XG5cbiAgICAgIC8vIFN0b3AgcHJldmlvdXMgb2JzZXJ2YWJsZXNcbiAgICAgICRkaXNwb3NlU3ViamVjdC5uZXh0KCk7XG4gICAgICBsZXQgbm93OiBudW1iZXI7XG5cbiAgICAgIHJldHVybiBvZihudWxsKS5waXBlKFxuICAgICAgICAvLyBBZGQgYSBkZWxheSBiZWZvcmUgZXhlY3V0aW9uXG4gICAgICAgIGRlbGF5KGRlYm91bmNlVGltZSksXG4gICAgICAgIC8vIERFQlVHXG4gICAgICAgIHRhcCgoXykgPT4ge1xuICAgICAgICAgIGlmIChkZWJ1Zykge1xuICAgICAgICAgICAgY29uc29sZS5kZWJ1Zyhsb2dQcmVmaXggKyAnRXhlY3V0aW5nLi4uJyk7XG4gICAgICAgICAgICBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICAgIHN3aXRjaE1hcCgoXykgPT4ge1xuICAgICAgICAgIC8vIENhbGwgdGhlIHZhbGlkYXRvclxuICAgICAgICAgIGNvbnN0IHJlcyA9IHZhbGlkYXRvckZuKGNvbnRyb2wpO1xuICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0byByZXR1cm4gYW4gT2JzZXJ2YWJsZVxuICAgICAgICAgIGlmIChpc09ic2VydmFibGUocmVzKSkgcmV0dXJuIHJlcztcbiAgICAgICAgICBpZiAocmVzIGluc3RhbmNlb2YgUHJvbWlzZSkgcmV0dXJuIGZyb20ocmVzKTtcbiAgICAgICAgICByZXR1cm4gb2YocmVzKTtcbiAgICAgICAgfSksXG4gICAgICAgIC8vIERFQlVHXG4gICAgICAgIHRhcCgocmVzKSA9PiBkZWJ1ZyAmJiBjb25zb2xlLmRlYnVnKGxvZ1ByZWZpeCArIGBGaW5pc2hlZCBpbiAke0RhdGUubm93KCkgLSBub3d9bXMgKCR7cmVzID8gJ3dpdGggZXJyb3JzJyA6ICdubyBlcnJvcid9KWAsIHJlcykpLFxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tkZWJvdW5jZVRpbWUtdmFsaWRhdG9yXSBFcnJvciB3aGlsZSBleGVjdXRpbmcgdmFsaWRhdG9yLiBTdG9wcGluZyBqb2InLCBlcnJvcik7XG4gICAgICAgICAgJGRpc3Bvc2VTdWJqZWN0Lm5leHQoKTtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfSksXG4gICAgICAgIC8vIFJlZnJlc2ggVUksIGFmdGVyIGEgc3VjY2Vzc2Z1bCBleGVjdXRpb25cbiAgICAgICAgdGFwKCgpID0+IG9wdHM/Lm1hcmtGb3JDaGVjayAmJiBvcHRzPy5tYXJrRm9yQ2hlY2soKSksXG4gICAgICAgIC8vIE1ha2Ugc3VyZSB0byBzdG9wLCBiZWNhdXNlIG9mIHRoZSBzd2l0Y2hNYXBcbiAgICAgICAgdGFrZVVudGlsKGRpc3Bvc2VFdmVudCQpXG4gICAgICApO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQWRkIGFuIGFzeW5jIHZhbGlkYXRvciwgdGhhdCBjYW4gYmUgZGlzcG9zZWQgYnkgdGhlIHJldHVybmVkIHN1YnNjcmlwdGlvblxuICAgKlxuICAgKiBAcGFyYW0gZm9ybVxuICAgKiBAcGFyYW0gdmFsaWRhdG9yRm4gdGhlIHZhbGlkYXRvciBvciBqb2IgdG8gZXhlY3V0ZVxuICAgKiBAcGFyYW0gb3B0c1xuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyQXN5bmNWYWxpZGF0b3IoXG4gICAgZm9ybTogQWJzdHJhY3RDb250cm9sLFxuICAgIHZhbGlkYXRvckZuOiBWYWxpZGF0b3JGbiB8IEFzeW5jVmFsaWRhdG9yRm4sXG4gICAgb3B0cz86IHtcbiAgICAgIGRlYm91bmNlVGltZT86IG51bWJlcjtcbiAgICAgIG1hcmtGb3JDaGVjaz86ICgpID0+IHZvaWQ7XG4gICAgICBkZWJ1Zz86IGJvb2xlYW47XG4gICAgfVxuICApOiBTdWJzY3JpcHRpb24ge1xuICAgIGlmIChmb3JtLmFzeW5jVmFsaWRhdG9yKSB0aHJvdyBFcnJvcignRm9ybSBhbHJlYWR5IGhhdmUgYW4gYXN5bmMgdmFsaWRhdG9yLiBDYW5ub3QgY29uZmlndXJlIGpvYicpO1xuXG4gICAgY29uc3QgZGVib3VuY2VUaW1lID0gdG9OdW1iZXIob3B0cz8uZGVib3VuY2VUaW1lLCAyNTApO1xuICAgIGNvbnN0ICRkaXNwb3NlID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIGNvbnN0IGFzeW5jVmFsaWRhdG9yRm4gPSBTaGFyZWRBc3luY1ZhbGlkYXRvcnMuZGVib3VuY2VUaW1lKHZhbGlkYXRvckZuLCB7IC4uLm9wdHMsIGRlYm91bmNlVGltZSwgZGlzcG9zZTogJGRpc3Bvc2UgfSk7XG4gICAgZm9ybS5zZXRBc3luY1ZhbGlkYXRvcnMoYXN5bmNWYWxpZGF0b3JGbik7XG5cbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgICAvLyBXaGVuIHVuc3Vic2NyaWJpbmcsIHJlbW92ZSBhc3luYyB2YWxpZGF0b3JcbiAgICBzdWJzY3JpcHRpb24uYWRkKCgpID0+IHtcbiAgICAgIC8vIENsZWFyIGFkZGVkIHZhbGlkYXRvci4gTXVzdCBiZSBkb25lIE5PVyAod2l0aG91dCBkZWxheSkgYmVjYXVzZSBnZW5lcmFsbHkgYSBuZXcgSm9iIGlzIGdpdmVuIGp1c3QgYWZ0ZXJcbiAgICAgIGZvcm0uY2xlYXJBc3luY1ZhbGlkYXRvcnMoKTtcblxuICAgICAgLy8gU3RvcCB0aGUgam9iLCB3aXRoIGEgZGVsYXkgdG8gbGV0IHRoZSBsYXN0IGV4ZWN1dGlvbiBmaW5pc2hlZFxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICRkaXNwb3NlLm5leHQoKTtcbiAgICAgICAgJGRpc3Bvc2UudW5zdWJzY3JpYmUoKTtcbiAgICAgIH0sIGRlYm91bmNlVGltZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc3Vic2NyaXB0aW9uO1xuICB9XG59XG4iXX0=
630
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvc2hhcmVkL3ZhbGlkYXRvci92YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxlQUFlLEdBT2hCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUFFLFFBQVEsRUFBc0IsTUFBTSxRQUFRLENBQUM7QUFDdEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNoSSxPQUFPLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ3hELE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0YsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEYsV0FBVztBQUNYLE1BQU0sT0FBTyxnQkFBZ0I7SUFDbkIsTUFBTSxDQUFDLG9CQUFvQixHQUFHO1FBQ3BDLFFBQVEsRUFBRSxtQkFBbUI7UUFDN0IsQ0FBQyxFQUFFLGtCQUFrQixFQUFFLGdCQUFnQjtRQUN2QyxDQUFDLEVBQUUsdUJBQXVCLEVBQUUsaUJBQWlCO1FBQzdDLENBQUMsRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUI7S0FDOUMsQ0FBQztJQUVNLE1BQU0sQ0FBQyxlQUFlLENBQUMsV0FBbUI7UUFDaEQsSUFBSSxLQUFLLENBQUMsV0FBVyxDQUFDO1lBQUUsT0FB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QiwwR0FBMEc7WUFDMUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7WUFFNUIsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2hCLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN6QixDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDbkIsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLFlBQVksQ0FBQztJQUN0QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWJzdHJhY3RDb250cm9sLFxuICBBc3luY1ZhbGlkYXRvckZuLFxuICBVbnR5cGVkRm9ybUFycmF5LFxuICBVbnR5cGVkRm9ybUNvbnRyb2wsXG4gIFVudHlwZWRGb3JtR3JvdXAsXG4gIFZhbGlkYXRpb25FcnJvcnMsXG4gIFZhbGlkYXRvckZuLFxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBpc01vbWVudCwgTW9tZW50LCB1bml0T2ZUaW1lIH0gZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IFBVQktFWV9SRUdFWFAgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgaXNFbXB0eUFycmF5LCBpc05pbCwgaXNOaWxPckJsYW5rLCBpc05vdE5pbCwgaXNOb3ROaWxPckJsYW5rLCBpc05vdE5pbE9yTmFOLCB0b0Jvb2xlYW4sIHRvTnVtYmVyIH0gZnJvbSAnLi4vZnVuY3Rpb25zJztcbmltcG9ydCB7IERhdGVVdGlscywgZnJvbURhdGVJU09TdHJpbmcgfSBmcm9tICcuLi9kYXRlcyc7XG5pbXBvcnQgeyBkZWxheSwgZnJvbSwgaXNPYnNlcnZhYmxlLCBtZXJnZSwgT2JzZXJ2YWJsZSwgb2YsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgZmluYWxpemUsIGZpcnN0LCBzd2l0Y2hNYXAsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG4vLyBAZHluYW1pY1xuZXhwb3J0IGNsYXNzIFNoYXJlZFZhbGlkYXRvcnMge1xuICBwcml2YXRlIHN0YXRpYyBfRE9VQkxFX1JFR0VYUF9DQUNIRSA9IHtcbiAgICBOT19MSU1JVDogL14tP1xcZCsoWy4sXVxcZCopPyQvLFxuICAgIDE6IC9eLT9cXGQrKFsuLF1cXGQpPyQvLCAvLyAxIGRlY2ltYWwgbWF4XG4gICAgMjogL14tP1xcZCsoWy4sXVxcZHsxLDJ9KT8kLywgLy8gMiBkZWNpbWFscyBtYXhcbiAgICAzOiAvXi0/XFxkKyhbLixdXFxkezEsM30pPyQvLCAvLyAzIGRlY2ltYWxzIG1heFxuICB9O1xuXG4gIHByaXZhdGUgc3RhdGljIGdldERvdWJsZVJlZ2V4cChtYXhEZWNpbWFsczogbnVtYmVyKTogUmVnRXhwIHtcbiAgICBpZiAoaXNOaWwobWF4RGVjaW1hbHMpKSByZXR1cm4gdGhpcy5fRE9VQkxFX1JFR0VYUF9DQUNIRS5OT19MSU1JVDtcblxuICAgIGlmIChtYXhEZWNpbWFscyA8IDApIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBtYXhEZWNpbWFscyB2YWx1ZTogJHttYXhEZWNpbWFsc31gKTtcbiAgICBjb25zdCByZWdleHAgPSB0aGlzLl9ET1VCTEVfUkVHRVhQX0NBQ0hFW21heERlY2ltYWxzXTtcbiAgICBpZiAocmVnZXhwKSByZXR1cm4gcmVnZXhwO1xuXG4gICAgLy8gTmV3OiBhZGQgdG8gY2FjaGVcbiAgICB0aGlzLl9ET1VCTEVfUkVHRVhQX0NBQ0hFW21heERlY2ltYWxzXSA9IG5ldyBSZWdFeHAoYF4tP1xcXFxkKyhbLixdXFxcXGR7MSwke21heERlY2ltYWxzfX0pPyRgKTtcbiAgICByZXR1cm4gdGhpcy5fRE9VQkxFX1JFR0VYUF9DQUNIRVttYXhEZWNpbWFsc107XG4gIH1cblxuICBzdGF0aWMgZXF1YWxzKG90aGVyQ29udHJvbE5hbWU6IHN0cmluZyk6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKGM6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IG90aGVyQ29udHJvbCA9IGMucGFyZW50Py5nZXQob3RoZXJDb250cm9sTmFtZSk7XG4gICAgICBpZiAob3RoZXJDb250cm9sICYmIGMudmFsdWUgIT09IG90aGVyQ29udHJvbC52YWx1ZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVxdWFsczogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgcmVhZG9ubHkgSTE4Tl9FUlJPUl9LRVlTID0ge1xuICAgIHJlcXVpcmVkOiAnRVJST1IuRklFTERfUkVRVUlSRUQnLFxuICAgIG1pbjogJ0VSUk9SLkZJRUxEX01JTicsXG4gICAgbWF4OiAnRVJST1IuRklFTERfTUFYJyxcbiAgICBtaW5sZW5ndGg6ICdFUlJPUi5GSUVMRF9NSU5fTEVOR1RIJyxcbiAgICBtYXhsZW5ndGg6ICdFUlJPUi5GSUVMRF9NQVhfTEVOR1RIJyxcbiAgICBwdWJrZXk6ICdFUlJPUi5GSUVMRF9OT1RfVkFMSURfUFVCS0VZJyxcbiAgICB2YWxpZERhdGU6ICdFUlJPUi5GSUVMRF9OT1RfVkFMSURfREFURScsXG4gICAgZGF0ZUlzQWZ0ZXI6ICdFUlJPUi5GSUVMRF9OT1RfVkFMSURfREFURV9BRlRFUicsXG4gICAgZGF0ZUlzQmVmb3JlOiAnRVJST1IuRklFTERfTk9UX1ZBTElEX0RBVEVfQkVGT1JFJyxcbiAgICBkYXRlUmFuZ2U6ICdFUlJPUi5GSUVMRF9OT1RfVkFMSURfREFURV9SQU5HRScsXG4gICAgZGF0ZU1pbkR1cmF0aW9uOiAnRVJST1IuRklFTERfTk9UX1ZBTElEX0RBVEVfTUlOX0RVUkFUSU9OJyxcbiAgICBkYXRlTWF4RHVyYXRpb246ICdFUlJPUi5GSUVMRF9OT1RfVkFMSURfREFURV9NQVhfRFVSQVRJT04nLFxuICAgIG1heERlY2ltYWxzOiAnRVJST1IuRklFTERfTUFYSU1VTV9ERUNJTUFMUycsXG4gICAgZGVjaW1hbDogJ0VSUk9SLkZJRUxEX05PVF9WQUxJRF9ERUNJTUFMJyxcbiAgICBpbnRlZ2VyOiAnRVJST1IuRklFTERfTk9UX1ZBTElEX0lOVEVHRVInLFxuICAgIHByZWNpc2lvbjogJ0VSUk9SLkZJRUxEX05PVF9WQUxJRF9QUkVDSVNJT04nLFxuICAgIGVtYWlsOiAnRVJST1IuRklFTERfTk9UX1ZBTElEX0VNQUlMJyxcbiAgICBsYXRpdHVkZTogJ0VSUk9SLkZJRUxEX05PVF9WQUxJRF9MQVRJVFVERScsXG4gICAgbG9uZ2l0dWRlOiAnRVJST1IuRklFTERfTk9UX1ZBTElEX0xPTkdJVFVERScsXG4gICAgcGF0dGVybjogJ0VSUk9SLkZJRUxEX05PVF9WQUxJRF9QQVRURVJOJyxcbiAgICB1bmlxdWU6ICdFUlJPUi5GSUVMRF9OT1RfVU5JUVVFJyxcbiAgICBlbnRpdHk6ICdFUlJPUi5GSUVMRF9JTlZBTElEJyxcbiAgICBpbnZhbGlkOiAnRVJST1IuRklFTERfSU5WQUxJRCcsXG4gICAgaW5jb25zaXN0ZW50OiAnRVJST1IuRklFTERfSU5DT05TSVNURU5UJyxcbiAgICBlcXVhbHM6ICdFUlJPUi5GSUVMRF9OT1RfRVFVQUxTJyxcbiAgfTtcblxuICBzdGF0aWMgbGF0aXR1ZGUoY29udHJvbDogVW50eXBlZEZvcm1Db250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xuICAgIGNvbnN0IHZhbHVlID0gY29udHJvbC52YWx1ZTtcbiAgICBpZiAoaXNOb3ROaWwodmFsdWUpICYmICh2YWx1ZSA8IC05MCB8fCB2YWx1ZSA+IDkwKSkge1xuICAgICAgcmV0dXJuIHsgbGF0aXR1ZGU6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzdGF0aWMgbG9uZ2l0dWRlKGNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcbiAgICBjb25zdCB2YWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgaWYgKGlzTm90TmlsKHZhbHVlKSAmJiAodmFsdWUgPCAtMTgwIHx8IHZhbHVlID4gMTgwKSkge1xuICAgICAgcmV0dXJuIHsgbG9uZ2l0dWRlOiB0cnVlIH07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3RhdGljIG9iamVjdChjb250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCB7XG4gICAgY29uc3QgdmFsdWUgPSBjb250cm9sLnZhbHVlO1xuICAgIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4geyBvYmplY3Q6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzdGF0aWMgZW50aXR5KGNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcbiAgICBjb25zdCB2YWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgaWYgKHZhbHVlICYmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnIHx8IGlzTmlsKHZhbHVlLmlkKSkpIHtcbiAgICAgIHJldHVybiB7IGVudGl0eTogdHJ1ZSB9O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBlbnRpdGllcyhjb250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCB7XG4gICAgY29uc3QgdmFsdWUgPSBjb250cm9sLnZhbHVlO1xuICAgIGlmICh2YWx1ZSAmJiAoIUFycmF5LmlzQXJyYXkodmFsdWUpIHx8IHZhbHVlLmV2ZXJ5KChlKSA9PiBpc05pbChlPy5pZCkpKSkge1xuICAgICAgcmV0dXJuIHsgZW50aXR5OiB0cnVlIH07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3RhdGljIGVtcHR5KGNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcbiAgICBpZiAoaXNOb3ROaWxPckJsYW5rKGNvbnRyb2wudmFsdWUpKSB7XG4gICAgICByZXR1cm4geyBlbXB0eTogdHJ1ZSB9O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBwdWJrZXkoY29udHJvbDogVW50eXBlZEZvcm1Db250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xuICAgIGNvbnN0IHZhbHVlID0gY29udHJvbC52YWx1ZTtcbiAgICBpZiAodmFsdWUgJiYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycgfHwgIVBVQktFWV9SRUdFWFAudGVzdCh2YWx1ZSkpKSB7XG4gICAgICByZXR1cm4geyBwdWJrZXk6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzdGF0aWMgaW50ZWdlcihjb250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCB7XG4gICAgaWYgKGlzTmlsT3JCbGFuayhjb250cm9sLnZhbHVlKSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJzZUZsb2F0KGNvbnRyb2wudmFsdWUpO1xuICAgIGlmIChpc05hTih2YWx1ZSkgfHwgKHZhbHVlIHwgMCkgIT09IHZhbHVlKSB7XG4gICAgICByZXR1cm4geyBpbnRlZ2VyOiB0cnVlIH07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3RhdGljIGRlY2ltYWwob3B0cz86IHsgbWF4RGVjaW1hbHM/OiBudW1iZXIgfSk6IFZhbGlkYXRvckZuIHtcbiAgICBjb25zdCByZWdleHAgPSB0aGlzLmdldERvdWJsZVJlZ2V4cChvcHRzPy5tYXhEZWNpbWFscyk7XG4gICAgcmV0dXJuIChjb250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbnRyb2wudmFsdWU7XG4gICAgICBpZiAoTnVtYmVyLmlzTmFOKHZhbHVlKSkge1xuICAgICAgICAvLyBERUJVR1xuICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJXQVJOOiBHZXR0aW5nIGEgTmFOIHZhbHVlIChkZWNpbWFsIHdhcyBleHBlY3RlZCkgIVwiKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBpZiAoaXNOb3ROaWwodmFsdWUpICYmIHZhbHVlICE9PSAnJyAmJiAhcmVnZXhwLnRlc3QodmFsdWUgYXMgc3RyaW5nKSkge1xuICAgICAgICByZXR1cm4gaXNOb3ROaWwob3B0cz8ubWF4RGVjaW1hbHMpID8geyBtYXhEZWNpbWFsczogeyBtYXhEZWNpbWFsczogb3B0cy5tYXhEZWNpbWFscyB9IH0gOiB7IGRlY2ltYWw6IHRydWUgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgcHJlY2lzaW9uLiBlLmcuIGlmIHByZWNpc2lvbj0wLjUgdGhlbiB2YWx1ZT0wLjYgaXMgaW52YWxpZCwgYnV0IDEuNSBpcyB2YWxpZFxuICAgKlxuICAgKiBAcGFyYW0gcHJlY2lzaW9uXG4gICAqL1xuICBzdGF0aWMgcHJlY2lzaW9uKHByZWNpc2lvbjogbnVtYmVyKTogVmFsaWRhdG9yRm4ge1xuICAgIGlmIChpc05pbChwcmVjaXNpb24pKSB0aHJvdyBuZXcgRXJyb3IoJ1JlcXVpcmVkIGEgbm90IG5pbCBwcmVjaXNpb24nKTtcblxuICAgIC8vIFdBUk46IHdlIHNob3VsZCBkZWZpbmUgYSBtdWx0aXBsaWVyLCBiZWNhdXNlIG1vZHVsbyBpbiBqYXZhc2NyaXB0IHdpbGwgb25seSB3b3JrIG9uIGludGVnZXJcbiAgICAvLyAoZS5nLiBcIjcgJSAwLjFcIiBpbiBqYXZhc2NyaXB0IHdpbGwgTk9UIHJldHVybiB6ZXJvIChidXQgMC4wOTk5OTk5OTk5OTk5OTk2MilcbiAgICBjb25zdCBwcmVjaXNpb25OYkRlY2ltYWxzID0gKHByZWNpc2lvbi50b1N0cmluZygpLnNwbGl0KCcuJylbMV0gfHwgJycpLmxlbmd0aDtcbiAgICBjb25zdCBtdWx0aXBsaWVyID0gTWF0aC5wb3coMTAsIHByZWNpc2lvbk5iRGVjaW1hbHMpO1xuICAgIGNvbnN0IG11bHRpcGxpZWRQcmVjaXNpb24gPSBNYXRoLnJvdW5kKG11bHRpcGxpZXIgKiBwcmVjaXNpb24pO1xuXG4gICAgLy8gVGhlIHZhbGlkYXRvciBmdW5jdGlvblxuICAgIHJldHVybiAoY29udHJvbDogVW50eXBlZEZvcm1Db250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBjb250cm9sLnZhbHVlO1xuICAgICAgaWYgKGlzTmlsT3JCbGFuayh2YWx1ZSkgfHwgTnVtYmVyLmlzTmFOKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFdBUk46IENvbnZlcnQgdmFsdWUgaW50byBpbnRlZ2VyLCBiZWZvcmUgYXBwbHlpbmcgbW9kdWxvIG9wZXJhdG9yXG4gICAgICBjb25zdCBtb2QgPSBNYXRoLnJvdW5kKCt2YWx1ZSAqIG11bHRpcGxpZXIpICUgbXVsdGlwbGllZFByZWNpc2lvbjtcbiAgICAgIGlmIChtb2QgIT09IDApIHtcbiAgICAgICAgLy8gREVCVUdcbiAgICAgICAgLy9jb25zb2xlLmRlYnVnKGBXQVJOIEdldHRpbmcgYSAke3ZhbHVlfSB3aXRoIGFuIGludmFsaWQgcHJlY2lzaW9uIChleHBlY3RlZCBwcmVjaXNpb24gaXM6ICR7cHJlY2lzaW9ufSlgKTtcbiAgICAgICAgcmV0dXJuIHsgcHJlY2lzaW9uOiB7IHByZWNpc2lvbiB9IH07XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIHZhbGlkRGF0ZVRpbWUocmVxdWlyZWRUaW1lID0gdHJ1ZSk6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKGNvbnRyb2w6IFVudHlwZWRGb3JtQ29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gY29udHJvbC52YWx1ZTtcbiAgICAgIGNvbnN0IGRhdGUgPSAhdmFsdWUgfHwgaXNNb21lbnQodmFsdWUpID8gdmFsdWUgOiBmcm9tRGF0ZUlTT1N0cmluZyh2YWx1ZSwge3N0cmljdDogZmFsc2UsIHVuZGVmaW5lZElmSW52YWxpZDogZmFsc2UsIHJlcXVpcmVkVGltZX0pO1xuICAgICAgaWYgKGRhdGUgJiYgKCFkYXRlLmlzVmFsaWQoKSB8fCBkYXRlLnllYXIoKSA8IDE5MDAgfHwgKHJlcXVpcmVkVGltZSAmJiBEYXRlVXRpbHMuaXNOb1RpbWUoZGF0ZSkpKSkge1xuICAgICAgICByZXR1cm4geyB2YWxpZERhdGU6IHRydWUgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgdmFsaWREYXRlID0gU2hhcmVkVmFsaWRhdG9ycy52YWxpZERhdGVUaW1lKHRydWUpO1xuICBzdGF0aWMgdmFsaWREYXRlQWxsb3dOb1RpbWUgPSBTaGFyZWRWYWxpZGF0b3JzLnZhbGlkRGF0ZVRpbWUoZmFsc2UpO1xuXG4gIHN0YXRpYyBkYXRlSXNBZnRlcihwcmV2aW91c1ZhbHVlOiBNb21lbnQsIGVycm9yUGFyYW06IHN0cmluZywgZ3JhbnVsYXJpdHk/OiB1bml0T2ZUaW1lLlN0YXJ0T2YpOiBWYWxpZGF0b3JGbiB7XG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGZyb21EYXRlSVNPU3RyaW5nKGNvbnRyb2wudmFsdWUpO1xuICAgICAgaWYgKGlzTm90TmlsKHZhbHVlKSAmJiBpc05vdE5pbChwcmV2aW91c1ZhbHVlKSAmJiB2YWx1ZS5pc1NhbWVPckJlZm9yZShwcmV2aW91c1ZhbHVlLCBncmFudWxhcml0eSkpIHtcbiAgICAgICAgLy8gUmV0dXJuIHRoZSBlcnJvclxuICAgICAgICByZXR1cm4geyBkYXRlSXNBZnRlcjogeyBtaW5EYXRlOiBlcnJvclBhcmFtIH0gfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgZGF0ZUlzQmVmb3JlKG1heFZhbHVlOiBNb21lbnQsIGVycm9yUGFyYW06IHN0cmluZywgZ3JhbnVsYXJpdHk/OiB1bml0T2ZUaW1lLlN0YXJ0T2YpOiBWYWxpZGF0b3JGbiB7XG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGZyb21EYXRlSVNPU3RyaW5nKGNvbnRyb2wudmFsdWUpO1xuICAgICAgaWYgKGlzTm90TmlsKHZhbHVlKSAmJiBpc05vdE5pbChtYXhWYWx1ZSkgJiYgdmFsdWUuaXNTYW1lT3JBZnRlcihtYXhWYWx1ZSwgZ3JhbnVsYXJpdHkpKSB7XG4gICAgICAgIC8vIFJldHVybiB0aGUgZXJyb3JcbiAgICAgICAgcmV0dXJuIHsgZGF0ZUlzQmVmb3JlOiB7IG1heERhdGU6IGVycm9yUGFyYW0gfSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBkYXRlUmFuZ2VFbmQoc3RhcnREYXRlRmllbGROYW1lOiBzdHJpbmcsIG1zZz86IHN0cmluZyk6IFZhbGlkYXRvckZuIHtcbiAgICBjb25zdCBlcnJvckNvZGUgPSBtc2cgPyAnbXNnJyA6ICdkYXRlUmFuZ2UnO1xuICAgIGNvbnN0IGVycm9yID0gbXNnID8geyBtc2cgfSA6IHsgZGF0ZVJhbmdlOiB0cnVlIH07XG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICAvLyBGb3JtIGdyb3VwIG5vdCBjcmVhdGVkIHlldDogc2tpcFxuICAgICAgaWYgKCFjb250cm9sLnBhcmVudCkgcmV0dXJuIG51bGw7XG5cbiAgICAgIGNvbnN0IHN0YXJ0Q29udHJvbCA9IGNvbnRyb2wucGFyZW50LmdldChzdGFydERhdGVGaWVsZE5hbWUpO1xuICAgICAgaWYgKCFzdGFydENvbnRyb2wpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBDYW5ub3QgZmluZCBicm90aGVyIGNvbnRyb2wgJyR7c3RhcnREYXRlRmllbGROYW1lfScgaW4gdGhlIHBhcmVudCBmb3JtYCk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhcnREYXRlID0gZnJvbURhdGVJU09TdHJpbmcoc3RhcnRDb250cm9sLnZhbHVlKTtcbiAgICAgIGNvbnN0IGVuZERhdGUgPSBmcm9tRGF0ZUlTT1N0cmluZyhjb250cm9sLnZhbHVlKTtcbiAgICAgIC8vIEVycm9yIGlmIHZhbHVlIDw9IGJlZm9yZURhdGVcbiAgICAgIGlmIChpc05vdE5pbChlbmREYXRlKSAmJiBpc05vdE5pbChzdGFydERhdGUpICYmIGVuZERhdGUuaXNTYW1lT3JCZWZvcmUoc3RhcnREYXRlKSkge1xuICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICB9XG4gICAgICAvLyBPSzogY2xlYXIgZXhpc3RpbmcgZXJyb3JzXG4gICAgICBTaGFyZWRWYWxpZGF0b3JzLmNsZWFyRXJyb3IoY29udHJvbCwgZXJyb3JDb2RlKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgZGF0ZVJhbmdlU3RhcnQoZW5kRGF0ZUZpZWxkTmFtZTogc3RyaW5nLCBtc2c/OiBzdHJpbmcpOiBWYWxpZGF0b3JGbiB7XG4gICAgY29uc3QgZXJyb3JDb2RlID0gbXNnID8gJ21zZycgOiAnZGF0ZVJhbmdlJztcbiAgICBjb25zdCBlcnJvciA9IG1zZyA/IHsgbXNnIH0gOiB7IGRhdGVSYW5nZTogdHJ1ZSB9O1xuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgLy8gRm9ybSBncm91cCBub3QgY3JlYXRlZCB5ZXQ6IHNraXBcbiAgICAgIGlmICghY29udHJvbC5wYXJlbnQpIHJldHVybiBudWxsO1xuXG4gICAgICBjb25zdCBlbmREYXRlQ29udHJvbCA9IGNvbnRyb2wucGFyZW50LmdldChlbmREYXRlRmllbGROYW1lKTtcbiAgICAgIGlmICghZW5kRGF0ZUNvbnRyb2wpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBDYW5ub3QgZmluZCBjb250cm9sICcke2VuZERhdGVGaWVsZE5hbWV9JyBpbiB0aGUgcGFyZW50IGZvcm1gKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBjb25zdCBlbmREYXRlID0gZnJvbURhdGVJU09TdHJpbmcoZW5kRGF0ZUNvbnRyb2wudmFsdWUpO1xuICAgICAgY29uc3Qgc3RhcnREYXRlID0gZnJvbURhdGVJU09TdHJpbmcoY29udHJvbC52YWx1ZSk7XG4gICAgICAvLyBFcnJvciBpZiB2YWx1ZSA8PSBiZWZvcmVEYXRlXG4gICAgICBpZiAoaXNOb3ROaWwoc3RhcnREYXRlKSAmJiBpc05vdE5pbChlbmREYXRlKSAmJiBzdGFydERhdGUuaXNTYW1lT3JBZnRlcihlbmREYXRlKSkge1xuICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICB9XG4gICAgICAvLyBPSzogY2xlYXIgZXhpc3RpbmcgZXJyb3JzXG4gICAgICBTaGFyZWRWYWxpZGF0b3JzLmNsZWFyRXJyb3IoY29udHJvbCwgZXJyb3JDb2RlKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgY29weVBhcmVudEVycm9ycyhlcnJvck5hbWVzPzogc3RyaW5nW10pOiBWYWxpZGF0b3JGbiB7XG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICAvLyBTa2lwIGlmIGNvbnRyb2wgYWxyZWFkeSBoYXMgc29tZSBlcnJvcnNcbiAgICAgIGlmIChjb250cm9sLmVycm9ycykgcmV0dXJuIG51bGw7XG4gICAgICAvLyBTa2lwIGlmIHBhcmVudCBmb3JtIGdyb3VwIG5vdCBjcmVhdGVkIHlldFxuICAgICAgaWYgKCFjb250cm9sLnBhcmVudCkgcmV0dXJuIG51bGw7XG5cbiAgICAgIC8vIEZvcm0gZ3JvdXAgbm90IGNyZWF0ZWQgeWV0XG4gICAgICBpZiAoIWNvbnRyb2wucGFyZW50KSByZXR1cm4gbnVsbDtcblxuICAgICAgY29uc3QgZXJyb3JzID0gY29udHJvbC5wYXJlbnQuZXJyb3JzO1xuXG4gICAgICAvLyBObyBlcnJvcnMsIG9yIGNvcHkgYWxsIGVycm9yc1xuICAgICAgaWYgKCFlcnJvcnMgfHwgaXNFbXB0eUFycmF5KGVycm9yTmFtZXMpKSByZXR1cm4gZXJyb3JzO1xuXG4gICAgICAvLyBDb3B5IG9ubHkgZXhwZWN0ZWQgZXJyb3JzXG4gICAgICByZXR1cm4gT2JqZWN0LmtleXMoZXJyb3JzKS5yZWR1Y2UoKHJlcywga2V5KSA9PiB7XG4gICAgICAgIGlmIChlcnJvck5hbWVzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgICByZXNba2V5XSA9IGVycm9yc1trZXldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9LCB7fSk7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBjbGVhckVycm9yKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgZXJyb3JDb2RlOiBzdHJpbmcpIHtcbiAgICBpZiAoY29udHJvbC5oYXNFcnJvcihlcnJvckNvZGUpKSB7XG4gICAgICBjb25zdCBlcnJvcnMgPSBjb250cm9sLmVycm9ycztcbiAgICAgIGlmIChlcnJvcnMgJiYgZXJyb3JzW2Vycm9yQ29kZV0pIHtcbiAgICAgICAgLy8gT25seSBvbmUgZXJyb3I6IHJlc2V0IGVycm9yc1xuICAgICAgICBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoZXJyb3JzKS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBjb250cm9sLnNldEVycm9ycyhudWxsKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBPdGhlciBlcnJvcnMgZXhpc3RzOiBqdXN0IHJlbW92ZSB0aGlzIGVycm9yXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBlcnJvcnNbZXJyb3JDb2RlXTtcbiAgICAgICAgICBjb250cm9sLnNldEVycm9ycyhlcnJvcnMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIEBkeW5hbWljXG5leHBvcnQgY2xhc3MgU2hhcmVkRm9ybUdyb3VwVmFsaWRhdG9ycyB7XG4gIHN0YXRpYyBkYXRlUmFuZ2UoXG4gICAgc3RhcnREYXRlRmllbGQ6IHN0cmluZyxcbiAgICBlbmREYXRlRmllbGQ6IHN0cmluZyxcbiAgICBvcHRzPzogeyBtc2c/OiBzdHJpbmc7IGZpZWxkT25seT86IGJvb2xlYW47IHNraXBJZk5vVGltZT86IGJvb2xlYW4gfSB8IHN0cmluZ1xuICApOiBWYWxpZGF0b3JGbiB7XG4gICAgY29uc3QgbXNnID0gdHlwZW9mIG9wdHMgPT09ICdzdHJpbmcnID8gb3B0cyA6IG9wdHM/Lm1zZztcbiAgICBjb25zdCBmaWVsZE9ubHkgPSB0eXBlb2Ygb3B0cyA9PT0gJ29iamVjdCcgPyBvcHRzPy5maWVsZE9ubHkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3Qgc2tpcElmTm9UaW1lID0gdHlwZW9mIG9wdHMgPT09ICdvYmplY3QnID8gb3B0cz8uc2tpcElmTm9UaW1lIDogdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgZXJyb3JDb2RlID0gaXNOb3ROaWxPckJsYW5rKG1zZykgPyAnbXNnJyA6ICdkYXRlUmFuZ2UnO1xuICAgIGNvbnN0IHJhbmdlRXJyb3IgPSBtc2cgPyB7IG1zZyB9IDogeyBkYXRlUmFuZ2U6IHRydWUgfTtcbiAgICByZXR1cm4gKGdyb3VwOiBVbnR5cGVkRm9ybUdyb3VwKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgY29uc3Qgc3RhcnREYXRlID0gZnJvbURhdGVJU09TdHJpbmcoZ3JvdXAuZ2V0KHN0YXJ0RGF0ZUZpZWxkKS52YWx1ZSk7XG4gICAgICBjb25zdCBlbmRGaWVsZCA9IGdyb3VwLmdldChlbmREYXRlRmllbGQpO1xuICAgICAgY29uc3QgZW5kRGF0ZSA9IGZyb21EYXRlSVNPU3RyaW5nKGVuZEZpZWxkLnZhbHVlKTtcblxuICAgICAgY29uc3QgaGFzU3RhcnREYXRlID0gaXNOb3ROaWwoc3RhcnREYXRlKSAmJiAoIXNraXBJZk5vVGltZSB8fCBEYXRlVXRpbHMuaXNOb1RpbWUoc3RhcnREYXRlKSk7XG4gICAgICBjb25zdCBoYXNFbmREYXRlID0gaXNOb3ROaWwoZW5kRGF0ZSkgJiYgKCFza2lwSWZOb1RpbWUgfHwgRGF0ZVV0aWxzLmlzTm9UaW1lKGVuZERhdGUpKTtcbiAgICAgIGlmIChoYXNTdGFydERhdGUgJiYgaGFzRW5kRGF0ZSAmJiBzdGFydERhdGUuaXNBZnRlcihlbmREYXRlKSkge1xuICAgICAgICAvLyBVcGRhdGUgZW5kIGZpZWxkXG4gICAgICAgIGVuZEZpZWxkLm1hcmtBc1BlbmRpbmcoKTtcbiAgICAgICAgZW5kRmllbGQuc2V0RXJyb3JzKHtcbiAgICAgICAgICAuLi5lbmRGaWVsZC5lcnJvcnMsXG4gICAgICAgICAgLi4ucmFuZ2VFcnJvcixcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFJldHVybiB0aGUgZXJyb3IgKHNob3VsZCBiZSBhcHBsaWVkIHRvIHRoZSBwYXJlbnQgZm9ybSwgYnkgZGVmYXVsdClcbiAgICAgICAgcmV0dXJuIGZpZWxkT25seSA/IG51bGwgOiByYW5nZUVycm9yO1xuICAgICAgfVxuICAgICAgLy8gT0s6IHJlbW92ZSB0aGUgZXhpc3Rpbmcgb24gdGhlIGVuZCBmaWVsZFxuICAgICAgU2hhcmVkVmFsaWRhdG9ycy5jbGVhckVycm9yKGVuZEZpZWxkLCBlcnJvckNvZGUpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBkYXRlTWF4RHVyYXRpb24oXG4gICAgc3RhcnREYXRlRmllbGQ6IHN0cmluZyxcbiAgICBlbmREYXRlRmllbGQ6IHN0cmluZyxcbiAgICBtYXhEdXJhdGlvbjogbnVtYmVyLFxuICAgIGR1cmF0aW9uVW5pdD86IG1vbWVudC51bml0T2ZUaW1lLkRpZmYsXG4gICAgb3B0cz86IHsgc2tpcElmTm9UaW1lPzogYm9vbGVhbiB9XG4gICk6IFZhbGlkYXRvckZuIHtcbiAgICBjb25zdCBtYXhEdXJhdGlvbkVycm9yID0geyBkYXRlTWF4RHVyYXRpb246IHRydWUgfTtcbiAgICBjb25zdCBza2lwSWZOb1RpbWUgPSBvcHRzPy5za2lwSWZOb1RpbWU7XG5cbiAgICByZXR1cm4gKGdyb3VwOiBVbnR5cGVkRm9ybUdyb3VwKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgY29uc3Qgc3RhcnREYXRlID0gZnJvbURhdGVJU09TdHJpbmcoZ3JvdXAuZ2V0KHN0YXJ0RGF0ZUZpZWxkKS52YWx1ZSk7XG4gICAgICBjb25zdCBlbmRGaWVsZCA9IGdyb3VwLmdldChlbmREYXRlRmllbGQpO1xuICAgICAgY29uc3QgZW5kRGF0ZSA9IGZyb21EYXRlSVNPU3RyaW5nKGVuZEZpZWxkLnZhbHVlKTtcblxuICAgICAgY29uc3QgaGFzU3RhcnREYXRlID0gaXNOb3ROaWwoc3RhcnREYXRlKSAmJiAoIXNraXBJZk5vVGltZSB8fCBEYXRlVXRpbHMuaXNOb1RpbWUoc3RhcnREYXRlKSk7XG4gICAgICBjb25zdCBoYXNFbmREYXRlID0gaXNOb3ROaWwoZW5kRGF0ZSkgJiYgKCFza2lwSWZOb1RpbWUgfHwgRGF0ZVV0aWxzLmlzTm9UaW1lKGVuZERhdGUpKTtcblxuICAgICAgaWYgKGhhc1N0YXJ0RGF0ZSAmJiBoYXNFbmREYXRlICYmIE1hdGguYWJzKHN0YXJ0RGF0ZS5kaWZmKGVuZERhdGUsIGR1cmF0aW9uVW5pdCkpID4gbWF4RHVyYXRpb24pIHtcbiAgICAgICAgLy8gVXBkYXRlIGVuZCBmaWVsZFxuICAgICAgICBlbmRGaWVsZC5tYXJrQXNUb3VjaGVkKHsgb25seVNlbGY6IHRydWUgfSk7XG4gICAgICAgIGVuZEZpZWxkLm1hcmtBc1BlbmRpbmcoKTtcbiAgICAgICAgZW5kRmllbGQuc2V0RXJyb3JzKHtcbiAgICAgICAgICAuLi5lbmRGaWVsZC5lcnJvcnMsXG4gICAgICAgICAgLi4ubWF4RHVyYXRpb25FcnJvcixcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFJldHVybiB0aGUgZXJyb3IgKHNob3VsZCBiZSBhcHBseSB0byB0aGUgcGFyZW50IGZvcm0pXG4gICAgICAgIHJldHVybiBtYXhEdXJhdGlvbkVycm9yO1xuICAgICAgfVxuICAgICAgLy8gT0s6IHJlbW92ZSB0aGUgZXhpc3Rpbmcgb24gdGhlIGVuZCBmaWVsZFxuICAgICAgU2hhcmVkVmFsaWRhdG9ycy5jbGVhckVycm9yKGVuZEZpZWxkLCAnZGF0ZU1heER1cmF0aW9uJyk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIGRhdGVNaW5EdXJhdGlvbihzdGFydERhdGVGaWVsZDogc3RyaW5nLCBlbmREYXRlRmllbGQ6IHN0cmluZywgbWluRHVyYXRpb246IG51bWJlciwgZHVyYXRpb25Vbml0PzogbW9tZW50LnVuaXRPZlRpbWUuRGlmZik6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKGdyb3VwOiBVbnR5cGVkRm9ybUdyb3VwKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgY29uc3QgZW5kRmllbGQgPSBncm91cC5nZXQoZW5kRGF0ZUZpZWxkKTtcbiAgICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IGZyb21EYXRlSVNPU3RyaW5nKGdyb3VwLmdldChzdGFydERhdGVGaWVsZCkudmFsdWUpO1xuICAgICAgY29uc3QgZW5kRGF0ZSA9IGZyb21EYXRlSVNPU3RyaW5nKGVuZEZpZWxkLnZhbHVlKTtcbiAgICAgIGlmIChpc05vdE5pbChzdGFydERhdGUpICYmIGlzTm90TmlsKGVuZERhdGUpICYmIE1hdGguYWJzKHN0YXJ0RGF0ZS5kaWZmKGVuZERhdGUsIGR1cmF0aW9uVW5pdCkpIDwgbWluRHVyYXRpb24pIHtcbiAgICAgICAgLy8gVXBkYXRlIGVuZCBmaWVsZFxuICAgICAgICBjb25zdCBlbmRGaWVsZEVycm9yczogVmFsaWRhdGlvbkVycm9ycyA9IGVuZEZpZWxkLmVycm9ycyB8fCB7fTtcbiAgICAgICAgZW5kRmllbGRFcnJvcnNbJ2RhdGVNaW5EdXJhdGlvbiddID0gdHJ1ZTtcbiAgICAgICAgZW5kRmllbGQuc2V0RXJyb3JzKGVuZEZpZWxkRXJyb3JzKTtcbiAgICAgICAgZW5kRmllbGQubWFya0FzVG91Y2hlZCh7IG9ubHlTZWxmOiB0cnVlIH0pO1xuICAgICAgICAvLyBSZXR1cm4gdGhlIGVycm9yIChzaG91bGQgYmUgYXBwbHkgdG8gdGhlIHBhcmVudCBmb3JtKVxuICAgICAgICByZXR1cm4geyBkYXRlTWluRHVyYXRpb246IHRydWUgfTtcbiAgICAgIH1cbiAgICAgIC8vIE9LOiByZW1vdmUgdGhlIGV4aXN0aW5nIG9uIHRoZSBlbmQgZmllbGRcbiAgICAgIGVsc2Uge1xuICAgICAgICBTaGFyZWRWYWxpZGF0b3JzLmNsZWFyRXJyb3IoZW5kRmllbGQsICdkYXRlTWluRHVyYXRpb24nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgcmVxdWlyZWRJZihcbiAgICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgICBhbm90aGVyRmllbGRUb0NoZWNrOiBzdHJpbmcgfCBBYnN0cmFjdENvbnRyb2wsXG4gICAgb3B0cz86IHtcbiAgICAgIGZpZWxkT25seT86IGJvb2xlYW47XG4gICAgICBpc0VtcHR5PzogKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4gYm9vbGVhbjtcbiAgICAgIHByZWRpY2F0ZT86IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IGJvb2xlYW47XG4gICAgfVxuICApOiBWYWxpZGF0b3JGbiB7XG4gICAgY29uc3QgaXNFbXB0eSA9IG9wdHM/LmlzRW1wdHkgfHwgKChjb250cm9sKSA9PiBpc05pbE9yQmxhbmsoY29udHJvbD8udmFsdWUpKTtcbiAgICBjb25zdCBwcmVkaWNhdGUgPSBvcHRzPy5wcmVkaWNhdGUgfHwgKChjb250cm9sKSA9PiBpc05vdE5pbE9yQmxhbmsoY29udHJvbD8udmFsdWUpKTtcbiAgICByZXR1cm4gKGdyb3VwOiBVbnR5cGVkRm9ybUdyb3VwKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgY29uc3QgY29udHJvbCA9IGdyb3VwLmdldChmaWVsZE5hbWUpO1xuICAgICAgaWYgKCFjb250cm9sKSB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBmaW5kIGNvbnRyb2wgJyR7ZmllbGROYW1lfScgdXNlZCBieSBTaGFyZUZvcm1Hcm91cFZhbGlkYXRvcnMucmVxdWlyZWRJZiB2YWxpZGF0b3IhYCk7XG4gICAgICBjb25zdCBhbm90aGVyQ29udHJvbCA9IGFub3RoZXJGaWVsZFRvQ2hlY2sgaW5zdGFuY2VvZiBBYnN0cmFjdENvbnRyb2wgPyBhbm90aGVyRmllbGRUb0NoZWNrIDogZ3JvdXAuZ2V0KGFub3RoZXJGaWVsZFRvQ2hlY2spO1xuICAgICAgaWYgKCFhbm90aGVyQ29udHJvbCkgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gZmluZCBjb250cm9sICR7dHlwZW9mIGFub3RoZXJGaWVsZFRvQ2hlY2sgPT09ICdzdHJpbmcnID8gYW5vdGhlckZpZWxkVG9DaGVjayAgKyAnICcgOiAnJ311c2VkIGJ5IFNoYXJlRm9ybUdyb3VwVmFsaWRhdG9ycy5yZXF1aXJlZElmIHZhbGlkYXRvciFgKTtcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wpICYmIHByZWRpY2F0ZShhbm90aGVyQ29udHJvbCkpIHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSB7IHJlcXVpcmVkOiB0cnVlIH07XG4gICAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKGVycm9yKTtcbiAgICAgICAgY29udHJvbC5tYXJrQXNUb3VjaGVkKHsgb25seVNlbGY6IHRydWUgfSk7XG4gICAgICAgIHJldHVybiBvcHRzPy5maWVsZE9ubHkgPyBudWxsIDogZXJyb3I7XG4gICAgICB9XG4gICAgICBTaGFyZWRWYWxpZGF0b3JzLmNsZWFyRXJyb3IoY29udHJvbCwgJ3JlcXVpcmVkJyk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIHJlcXVpcmVkSWZUcnVlKFxuICAgIGZpZWxkTmFtZTogc3RyaW5nLFxuICAgIGFub3RoZXJGaWVsZFRvQ2hlY2s6IHN0cmluZyB8IEFic3RyYWN0Q29udHJvbCxcbiAgICBvcHRzPzoge1xuICAgICAgZmllbGRPbmx5PzogYm9vbGVhbjtcbiAgICAgIGlzRW1wdHk/OiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiBib29sZWFuO1xuICAgIH1cbiAgKTogVmFsaWRhdG9yRm4ge1xuICAgIGNvbnN0IGlzRW1wdHkgPSBvcHRzPy5pc0VtcHR5IHx8ICgoY29udHJvbCkgPT4gaXNOaWxPckJsYW5rKGNvbnRyb2wudmFsdWUpKTtcbiAgICByZXR1cm4gKGdyb3VwOiBVbnR5cGVkRm9ybUdyb3VwKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgY29uc3QgY29udHJvbCA9IGdyb3VwLmdldChmaWVsZE5hbWUpO1xuICAgICAgY29uc3QgYW5vdGhlckNvbnRyb2wgPSBhbm90aGVyRmllbGRUb0NoZWNrIGluc3RhbmNlb2YgQWJzdHJhY3RDb250cm9sID8gYW5vdGhlckZpZWxkVG9DaGVjayA6IGdyb3VwLmdldChhbm90aGVyRmllbGRUb0NoZWNrKTtcbiAgICAgIGlmICghYW5vdGhlckNvbnRyb2wpIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGZpbmQgZmllbGQgdG8gY2hlY2shJyk7XG4gICAgICBpZiAoaXNFbXB0eShjb250cm9sKSAmJiB0b0Jvb2xlYW4oYW5vdGhlckNvbnRyb2wudmFsdWUsIGZhbHNlKSkge1xuICAgICAgICBjb25zdCBlcnJvciA9IHsgcmVxdWlyZWQ6IHRydWUgfTtcbiAgICAgICAgY29udHJvbC5zZXRFcnJvcnMoZXJyb3IpO1xuICAgICAgICBjb250cm9sLm1hcmtBc1RvdWNoZWQoeyBvbmx5U2VsZjogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuIG9wdHM/LmZpZWxkT25seSA/IG51bGwgOiBlcnJvcjtcbiAgICAgIH1cbiAgICAgIFNoYXJlZFZhbGlkYXRvcnMuY2xlYXJFcnJvcihjb250cm9sLCAncmVxdWlyZWQnKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICBzdGF0aWMgcmVxdWlyZWRJZkVtcHR5KFxuICAgIGZpZWxkTmFtZTogc3RyaW5nLFxuICAgIGFub3RoZXJGaWVsZFRvQ2hlY2s6IHN0cmluZyxcbiAgICBvcHRzPzoge1xuICAgICAgZmllbGRPbmx5PzogYm9vbGVhbjtcbiAgICAgIGlzRW1wdHk/OiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiBib29sZWFuO1xuICAgIH1cbiAgKTogVmFsaWRhdG9yRm4ge1xuICAgIGNvbnN0IGlzRW1wdHkgPSBvcHRzPy5pc0VtcHR5IHx8ICgoY29udHJvbCkgPT4gaXNOaWxPckJsYW5rKGNvbnRyb2wudmFsdWUpKTtcbiAgICByZXR1cm4gKGdyb3VwOiBVbnR5cGVkRm9ybUdyb3VwKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgY29uc3QgY29udHJvbCA9IGdyb3VwLmdldChmaWVsZE5hbWUpO1xuICAgICAgaWYgKGlzRW1wdHkoY29udHJvbCkgJiYgaXNOaWxPckJsYW5rKGdyb3VwLmdldChhbm90aGVyRmllbGRUb0NoZWNrKS52YWx1ZSkpIHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSB7IHJlcXVpcmVkOiB0cnVlIH07XG4gICAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKGVycm9yKTtcbiAgICAgICAgY29udHJvbC5tYXJrQXNUb3VjaGVkKHsgb25seVNlbGY6IHRydWUgfSk7XG4gICAgICAgIHJldHVybiBvcHRzPy5maWVsZE9ubHkgPyBudWxsIDogZXJyb3I7XG4gICAgICB9XG4gICAgICBTaGFyZWRWYWxpZGF0b3JzLmNsZWFyRXJyb3IoY29udHJvbCwgJ3JlcXVpcmVkJyk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIHByb3BhZ2F0ZUlmRGlydHkoZmllbGROYW1lOiBzdHJpbmcsIGZpZWxkTmFtZVRvUHJvcGFnYXRlOiBzdHJpbmcsIHZhbHVlVG9Qcm9wYWdhdGU6IGFueSk6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKGdyb3VwOiBVbnR5cGVkRm9ybUdyb3VwKTogbnVsbCA9PiB7XG4gICAgICBjb25zdCBjb250cm9sID0gZ3JvdXAuZ2V0KGZpZWxkTmFtZSk7XG4gICAgICBjb25zdCBjb250cm9sVG9Qcm9wYWdhdGUgPSBncm91cC5nZXQoZmllbGROYW1lVG9Qcm9wYWdhdGUpO1xuICAgICAgaWYgKGNvbnRyb2wuZGlydHkgJiYgY29udHJvbFRvUHJvcGFnYXRlLnZhbHVlICE9PSB2YWx1ZVRvUHJvcGFnYXRlKSB7XG4gICAgICAgIGNvbnRyb2xUb1Byb3BhZ2F0ZS5zZXRWYWx1ZSh2YWx1ZVRvUHJvcGFnYXRlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogU2FtZSBhcyBjb21wb3NlLCBidXQga2VlcCBvbmx5IHRoZSBmaXJzdCBlcnJvcnMgKGluc3RlYWQgb2YgdGhlIHVuaW9uKVxuICAgKlxuICAgKiBAcGFyYW0gdmFsaWRhdG9yc1xuICAgKi9cbiAgZmlyc3QodmFsaWRhdG9yczogKFZhbGlkYXRvckZuIHwgbnVsbCB8IHVuZGVmaW5lZClbXSk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcbiAgICByZXR1cm4gKGNvbnRyb2wpID0+XG4gICAgICB2YWxpZGF0b3JzXG4gICAgICAgIC5maWx0ZXIoaXNOb3ROaWwpXG4gICAgICAgIC5tYXAoKHZhbGlkYXRvcikgPT4gdmFsaWRhdG9yKGNvbnRyb2wpKVxuICAgICAgICAuZmluZChpc05vdE5pbCkgfHwgbnVsbDtcbiAgfVxufVxuXG4vLyBAZHluYW1pY1xuZXhwb3J0IGNsYXNzIFNoYXJlZEZvcm1BcnJheVZhbGlkYXRvcnMge1xuICAvKipcbiAgICogVmFsaWRhdGUgdW5pcXVlbmVzcyBvZiBhbiBlbnRpdHkgaW4gYSBGb3JtQXJyYXlcbiAgICpcbiAgICogQHBhcmFtIGNvbnRyb2xOYW1lIHRoZSBuYW1lIG9mIHRoZSBjb250cm9sIGluIEZvcm1BcnJheVxuICAgKi9cbiAgc3RhdGljIHVuaXF1ZUVudGl0eShjb250cm9sTmFtZTogc3RyaW5nKTogVmFsaWRhdG9yRm4ge1xuICAgIHJldHVybiAoYXJyYXk6IFVudHlwZWRGb3JtQXJyYXkpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCBjb250cm9sczogQWJzdHJhY3RDb250cm9sW10gPSBbXTtcbiAgICAgIGlmIChhcnJheS5sZW5ndGgpIHtcbiAgICAgICAgLy8gZ2F0aGVyIGNvbnRyb2xzIGluIGFycmF5IHdpdGggdmFsaWQgZW50aXR5XG4gICAgICAgIGZvciAoY29uc3QgY29udHJvbCBvZiBhcnJheS5jb250cm9scykge1xuICAgICAgICAgIGNvbnN0IGZyb21Hcm91cCA9IGNvbnRyb2wgYXMgVW50eXBlZEZvcm1Hcm91cDtcbiAgICAgICAgICBpZiAoZnJvbUdyb3VwLmNvbnRyb2xzW2NvbnRyb2xOYW1lXSkge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBmcm9tR3JvdXAuY29udHJvbHNbY29udHJvbE5hbWVdLnZhbHVlO1xuICAgICAgICAgICAgaWYgKCEhdmFsdWUgJiYgISF2YWx1ZS5pZCkgY29udHJvbHMucHVzaChmcm9tR3JvdXAuY29udHJvbHNbY29udHJvbE5hbWVdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gZ2V0IG9jY3VycmVuY2VzIG9mIGVudGl0eSBieSBpZFxuICAgICAgICBjb25zdCBvY2N1cnJlbmNlcyA9IGNvbnRyb2xzLnJlZHVjZSgoYWNjLCBjb250cm9sKSA9PiB7XG4gICAgICAgICAgY29uc3QgaWQgPSBjb250cm9sLnZhbHVlLmlkO1xuICAgICAgICAgIGlmIChhY2NbaWRdKSBhY2NbaWRdKys7XG4gICAgICAgICAgZWxzZSBhY2NbaWRdID0gMTtcbiAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9LCB7fSk7XG4gICAgICAgIC8vIGdldCBjb250cm9scyB3aXRoIHZhbHVlIG9jY3VycmVuY2VzID4gMVxuICAgICAgICBjb25zdCBlcnJvciA9IHsgdW5pcXVlRW50aXR5OiB0cnVlIH07XG4gICAgICAgIGxldCByZXR1cm5FcnJvciA9IGZhbHNlO1xuICAgICAgICBjb250cm9sc1xuICAgICAgICAgIC5maWx0ZXIoKGNvbnRyb2wpID0+IG9jY3VycmVuY2VzW2NvbnRyb2wudmFsdWUuaWRdID4gMSlcbiAgICAgICAgICAuZm9yRWFjaCgoY29udHJvbCkgPT4ge1xuICAgICAgICAgICAgbGV0IGVycm9yczogVmFsaWRhdGlvbkVycm9ycyA9IGNvbnRyb2wuZXJyb3JzIHx8IHt9O1xuICAgICAgICAgICAgZXJyb3JzID0geyAuLi5lcnJvcnMsIC4uLmVycm9yIH07XG4gICAgICAgICAgICBjb250cm9sLnNldEVycm9ycyhlcnJvcnMpO1xuICAgICAgICAgICAgY29udHJvbC5tYXJrQXNUb3VjaGVkKHsgb25seVNlbGY6IHRydWUgfSk7XG4gICAgICAgICAgICByZXR1cm5FcnJvciA9IHRydWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXR1cm5FcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgfVxuICAgICAgY29udHJvbHMuZm9yRWFjaCgoY29udHJvbCkgPT4gU2hhcmVkVmFsaWRhdG9ycy5jbGVhckVycm9yKGNvbnRyb2wsICd1bmlxdWVFbnRpdHknKSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIHJlcXVpcmVkQXJyYXlNaW5MZW5ndGgobWluTGVuZ3RoPzogbnVtYmVyKTogVmFsaWRhdG9yRm4ge1xuICAgIG1pbkxlbmd0aCA9IG1pbkxlbmd0aCB8fCAxO1xuICAgIHJldHVybiAoYXJyYXk6IFVudHlwZWRGb3JtQXJyYXkpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICBpZiAoIWFycmF5IHx8IGFycmF5Lmxlbmd0aCA8IG1pbkxlbmd0aCkge1xuICAgICAgICByZXR1cm4geyByZXF1aXJlZDogdHJ1ZSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBhcnJheU1heExlbmd0aChtYXhMZW5ndGg/OiBudW1iZXIpOiBWYWxpZGF0b3JGbiB7XG4gICAgbWF4TGVuZ3RoID0gbWF4TGVuZ3RoIHx8IDE7XG4gICAgcmV0dXJuIChhcnJheTogVW50eXBlZEZvcm1BcnJheSk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgIGlmIChhcnJheSAmJiBhcnJheS5sZW5ndGggPiBtYXhMZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHsgbWF4TGVuZ3RoOiBtYXhMZW5ndGggfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhlIHN1bSBvZiBjb250cm9sIHZhbHVlcyBpbiBhbiBGb3JtQXJyYXkgbm90IG92ZXJmbG93IHRoZSBtYXggdmFsdWVcbiAgICpcbiAgICogQHBhcmFtIGNvbnRyb2xOYW1lIHRoZSBuYW1lIG9mIHRoZSBjb250cm9sIGluIEZvcm1BcnJheVxuICAgKiBAcGFyYW0gbWF4IHRoZSBtYXhpbXVtIHZhbHVlXG4gICAqL1xuICBzdGF0aWMgdmFsaWRTdW1NYXhWYWx1ZShjb250cm9sTmFtZTogc3RyaW5nLCBtYXg6IG51bWJlcik6IFZhbGlkYXRvckZuIHtcbiAgICByZXR1cm4gKGFycmF5OiBVbnR5cGVkRm9ybUFycmF5KTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgY29uc3QgY29udHJvbHM6IEFic3RyYWN0Q29udHJvbFtdID0gW107XG4gICAgICBpZiAoYXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIGZvciAoY29uc3QgY29udHJvbCBvZiBhcnJheS5jb250cm9scykge1xuICAgICAgICAgIGNvbnN0IGZyb21Hcm91cCA9IGNvbnRyb2wgYXMgVW50eXBlZEZvcm1Hcm91cDtcbiAgICAgICAgICBpZiAoZnJvbUdyb3VwLmNvbnRyb2xzW2NvbnRyb2xOYW1lXSAmJiBpc05vdE5pbE9yTmFOKGZyb21Hcm91cC5jb250cm9sc1tjb250cm9sTmFtZV0udmFsdWUpKSB7XG4gICAgICAgICAgICBjb250cm9scy5wdXNoKGZyb21Hcm91cC5jb250cm9sc1tjb250cm9sTmFtZV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udHJvbHMucmVkdWNlKChzdW0sIGNvbnRyb2wpID0+IHN1bSArIGNvbnRyb2wudmFsdWUsIDApID4gbWF4KSB7XG4gICAgICAgICAgY29uc3QgZXJyb3IgPSB7IHN1bU1heFZhbHVlOiB0cnVlIH07XG4gICAgICAgICAgY29udHJvbHMuZm9yRWFjaCgoY29udHJvbCkgPT4ge1xuICAgICAgICAgICAgbGV0IGVycm9yczogVmFsaWRhdGlvbkVycm9ycyA9IGNvbnRyb2wuZXJyb3JzIHx8IHt9O1xuICAgICAgICAgICAgZXJyb3JzID0geyAuLi5lcnJvcnMsIC4uLmVycm9yIH07XG4gICAgICAgICAgICBjb250cm9sLnNldEVycm9ycyhlcnJvcnMpO1xuICAgICAgICAgICAgY29udHJvbC5tYXJrQXNUb3VjaGVkKHsgb25seVNlbGY6IHRydWUgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb250cm9scy5mb3JFYWNoKChjb250cm9sKSA9PiBTaGFyZWRWYWxpZGF0b3JzLmNsZWFyRXJyb3IoY29udHJvbCwgJ3N1bU1heFZhbHVlJykpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBPYnNlcnZhYmxlVmFsaWRhdG9yRm4gPSAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiBPYnNlcnZhYmxlPFZhbGlkYXRpb25FcnJvcnMgfCBudWxsPjtcbmV4cG9ydCB0eXBlIFByb21pc2VWYWxpZGF0b3JGbiA9IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IFByb21pc2U8VmFsaWRhdGlvbkVycm9ycyB8IG51bGw+O1xuXG4vLyBAZHluYW1pY1xuZXhwb3J0IGNsYXNzIFNoYXJlZEFzeW5jVmFsaWRhdG9ycyB7XG4gIHByaXZhdGUgc3RhdGljIERFQk9VTkNFX1RJTUVfVkFMSURBVE9SX0lEID0gMDtcblxuICAvKipcbiAgICogQWRkIGEgZGVib3VuY2UgdGltZSB0byBhIHZhbGlkYXRvci5cbiAgICpcbiAgICogQHBhcmFtIGZvcm1cbiAgICogQHBhcmFtIHZhbGlkYXRvckZuXG4gICAqIEBwYXJhbSBvcHRzIFVzZSBvcHRzLnN0b3BTdWJqZWN0IHRvIHN0b3AgdGhlIHZhbGlkYXRvciwgYmVmb3JlIGVuZFxuICAgKi9cbiAgc3RhdGljIGRlYm91bmNlVGltZShcbiAgICB2YWxpZGF0b3JGbjogVmFsaWRhdG9yRm4gfCBBc3luY1ZhbGlkYXRvckZuLFxuICAgIG9wdHM/OiB7XG4gICAgICBkaXNwb3NlPzogT2JzZXJ2YWJsZTxhbnk+O1xuICAgICAgZGVib3VuY2VUaW1lPzogbnVtYmVyO1xuICAgICAgbWFya0ZvckNoZWNrPzogKCkgPT4gdm9pZDtcbiAgICAgIGRlYnVnPzogYm9vbGVhbjtcbiAgICB9XG4gICk6IE9ic2VydmFibGVWYWxpZGF0b3JGbiB7XG4gICAgLy8gREVCVUcgb25seVxuICAgIGNvbnN0IGRlYnVnID0gb3B0cz8uZGVidWcgfHwgZmFsc2U7XG4gICAgY29uc3QgbG9nUHJlZml4ID0gZGVidWcgJiYgYFtkZWJvdW5jZVRpbWUtdmFsaWRhdG9yXSAjJHtTaGFyZWRBc3luY1ZhbGlkYXRvcnMuREVCT1VOQ0VfVElNRV9WQUxJREFUT1JfSUQrK30gLSBgO1xuICAgIGNvbnN0IGRlYm91bmNlVGltZSA9IHRvTnVtYmVyKG9wdHM/LmRlYm91bmNlVGltZSwgMjUwKTtcblxuICAgIC8vIERFQlVHXG4gICAgaWYgKGRlYnVnKSBjb25zb2xlLmRlYnVnKGxvZ1ByZWZpeCArIGBOZXcgdmFsaWRhdG9yIHdpdGggYSBkZWJvdW5jZVRpbWUgYXQgJHtkZWJvdW5jZVRpbWV9bXNgKTtcblxuICAgIGNvbnN0ICRkaXNwb3NlU3ViamVjdCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gICAgY29uc3QgZGlzcG9zZUV2ZW50JCA9IG9wdHM/LmRpc3Bvc2UgPyBtZXJnZSgkZGlzcG9zZVN1YmplY3QsIG9wdHM/LmRpc3Bvc2UpIDogJGRpc3Bvc2VTdWJqZWN0O1xuXG4gICAgLy8gREVCVUdcbiAgICBpZiAoZGVidWcgJiYgb3B0cz8uZGlzcG9zZSkge1xuICAgICAgb3B0cz8uZGlzcG9zZS5waXBlKGZpcnN0KCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcobG9nUHJlZml4ICsgJ1N0b3BwaW5nJyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gKGNvbnRyb2wpID0+IHtcbiAgICAgIGlmIChkZWJ1ZykgY29uc29sZS5kZWJ1Zyhsb2dQcmVmaXggKyAnRm9ybSBhc2sgdmFsaWRhdGlvbi4uLicpO1xuXG4gICAgICAvLyBTdG9wIHByZXZpb3VzIG9ic2VydmFibGVzXG4gICAgICAkZGlzcG9zZVN1YmplY3QubmV4dCgpO1xuICAgICAgbGV0IG5vdzogbnVtYmVyO1xuXG4gICAgICByZXR1cm4gb2YobnVsbCkucGlwZShcbiAgICAgICAgLy8gQWRkIGEgZGVsYXkgYmVmb3JlIGV4ZWN1dGlvblxuICAgICAgICBkZWxheShkZWJvdW5jZVRpbWUpLFxuICAgICAgICAvLyBERUJVR1xuICAgICAgICB0YXAoKF8pID0+IHtcbiAgICAgICAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZGVidWcobG9nUHJlZml4ICsgJ0V4ZWN1dGluZy4uLicpO1xuICAgICAgICAgICAgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgICBzd2l0Y2hNYXAoKF8pID0+IHtcbiAgICAgICAgICAvLyBDYWxsIHRoZSB2YWxpZGF0b3JcbiAgICAgICAgICBjb25zdCByZXMgPSB2YWxpZGF0b3JGbihjb250cm9sKTtcbiAgICAgICAgICAvLyBNYWtlIHN1cmUgdG8gcmV0dXJuIGFuIE9ic2VydmFibGVcbiAgICAgICAgICBpZiAoaXNPYnNlcnZhYmxlKHJlcykpIHJldHVybiByZXM7XG4gICAgICAgICAgaWYgKHJlcyBpbnN0YW5jZW9mIFByb21pc2UpIHJldHVybiBmcm9tKHJlcyk7XG4gICAgICAgICAgcmV0dXJuIG9mKHJlcyk7XG4gICAgICAgIH0pLFxuICAgICAgICAvLyBERUJVR1xuICAgICAgICB0YXAoKHJlcykgPT4gZGVidWcgJiYgY29uc29sZS5kZWJ1Zyhsb2dQcmVmaXggKyBgRmluaXNoZWQgaW4gJHtEYXRlLm5vdygpIC0gbm93fW1zICgke3JlcyA/ICd3aXRoIGVycm9ycycgOiAnbm8gZXJyb3InfSlgLCByZXMpKSxcbiAgICAgICAgLy8gUmVmcmVzaCBVSSwgYWZ0ZXIgYSBzdWNjZXNzZnVsIGV4ZWN1dGlvblxuICAgICAgICB0YXAoKCkgPT4gb3B0cz8ubWFya0ZvckNoZWNrICYmIG9wdHM/Lm1hcmtGb3JDaGVjaygpKSxcbiAgICAgICAgLy8gQ2F0Y2ggZXJyb3JcbiAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGxvZ1ByZWZpeCArICdFcnJvciB3aGlsZSBleGVjdXRpbmcgdmFsaWRhdG9yLiBTdG9wcGluZyBqb2InLCBlcnJvcik7XG4gICAgICAgICAgJGRpc3Bvc2VTdWJqZWN0Lm5leHQoKTtcbiAgICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICAgIH0pLFxuICAgICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgICAgaWYgKGRlYnVnKSBjb25zb2xlLmRlYnVnKGxvZ1ByZWZpeCArICdWYWxpZGF0b3IgZGlzcG9zZWQuJyk7XG4gICAgICAgICAgJGRpc3Bvc2VTdWJqZWN0LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIH0pLFxuICAgICAgICAvLyBNYWtlIHN1cmUgdG8gc3RvcFxuICAgICAgICB0YWtlVW50aWwoZGlzcG9zZUV2ZW50JCksXG4gICAgICApO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQWRkIGFuIGFzeW5jIHZhbGlkYXRvciwgdGhhdCBjYW4gYmUgZGlzcG9zZWQgYnkgdGhlIHJldHVybmVkIHN1YnNjcmlwdGlvblxuICAgKlxuICAgKiBAcGFyYW0gZm9ybVxuICAgKiBAcGFyYW0gdmFsaWRhdG9yRm4gdGhlIHZhbGlkYXRvciBvciBqb2IgdG8gZXhlY3V0ZVxuICAgKiBAcGFyYW0gb3B0c1xuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyQXN5bmNWYWxpZGF0b3IoXG4gICAgZm9ybTogQWJzdHJhY3RDb250cm9sLFxuICAgIHZhbGlkYXRvckZuOiBWYWxpZGF0b3JGbiB8IEFzeW5jVmFsaWRhdG9yRm4sXG4gICAgb3B0cz86IHtcbiAgICAgIGRlYm91bmNlVGltZT86IG51bWJlcjtcbiAgICAgIG1hcmtGb3JDaGVjaz86ICgpID0+IHZvaWQ7XG4gICAgICBkZWJ1Zz86IGJvb2xlYW47XG4gICAgfVxuICApOiBTdWJzY3JpcHRpb24ge1xuICAgIGlmICghZm9ybSkgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgcmVnaXN0ZXIgYXN5bmMgdmFsaWRhdG9yOiBmb3JtIGNvbnRyb2wgaXMgbnVsbCBvciB1bmRlZmluZWQuJyk7XG4gICAgaWYgKGZvcm0uYXN5bmNWYWxpZGF0b3IpIHRocm93IG5ldyBFcnJvcihgRm9ybSBjb250cm9sIGFscmVhZHkgaGFzIGFuIGFzeW5jIHZhbGlkYXRvci4gQ2xlYXIgaXQgZmlyc3Qgb3IgdXNlIGEgZGlmZmVyZW50IGNvbnRyb2wuYCk7XG5cbiAgICBjb25zdCBkZWJvdW5jZVRpbWUgPSB0b051bWJlcihvcHRzPy5kZWJvdW5jZVRpbWUsIDI1MCk7XG4gICAgY29uc3QgJGRpc3Bvc2UgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgY29uc3QgYXN5bmNWYWxpZGF0b3JGbiA9IFNoYXJlZEFzeW5jVmFsaWRhdG9ycy5kZWJvdW5jZVRpbWUodmFsaWRhdG9yRm4sIHsgLi4ub3B0cywgZGVib3VuY2VUaW1lLCBkaXNwb3NlOiAkZGlzcG9zZSB9KTtcbiAgICBmb3JtLnNldEFzeW5jVmFsaWRhdG9ycyhhc3luY1ZhbGlkYXRvckZuKTtcblxuICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICAgIC8vIFdoZW4gdW5zdWJzY3JpYmluZywgcmVtb3ZlIGFzeW5jIHZhbGlkYXRvclxuICAgIHN1YnNjcmlwdGlvbi5hZGQoKCkgPT4ge1xuICAgICAgLy8gQ2xlYXIgYWRkZWQgdmFsaWRhdG9yLiBNdXN0IGJlIGRvbmUgTk9XICh3aXRob3V0IGRlbGF5KSBiZWNhdXNlIGdlbmVyYWxseSBhIG5ldyBKb2IgaXMgZ2l2ZW4ganVzdCBhZnRlclxuICAgICAgZm9ybS5jbGVhckFzeW5jVmFsaWRhdG9ycygpO1xuXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgJGRpc3Bvc2UubmV4dCgpO1xuICAgICAgICAkZGlzcG9zZS51bnN1YnNjcmliZSgpO1xuICAgICAgfSwgZGVib3VuY2VUaW1lKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBzdWJzY3JpcHRpb247XG4gIH1cbn1cbiJdfQ==
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, Directive, Pipe, Injectable, EventEmitter, Output, Optional, Inject, inject, NgModule, forwardRef, booleanAttribute, Component, ChangeDetectionStrategy, Input, ViewChildren, HostBinding, HostListener, ElementRef, numberAttribute, ViewChild, ANIMATION_MODULE_TYPE, RendererStyleFlags2, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectorRef, Self, ViewEncapsulation, APP_INITIALIZER, SecurityContext, viewChild, signal, input, model, computed, effect, untracked } from '@angular/core';
3
3
  import { firstValueFrom, shareReplay, tap, of, timer, Subject, merge, delay, isObservable, from, Subscription, BehaviorSubject, fromEvent, noop as noop$9, Observable, forkJoin, timeout, defer, combineLatest, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1, interval, mergeMap as mergeMap$1, switchMap as switchMap$1, EMPTY } from 'rxjs';
4
- import { catchError, map, filter, takeUntil, first, switchMap, tap as tap$1, throttleTime, debounceTime, startWith, distinctUntilChanged, mergeMap, skip, finalize, distinctUntilKeyChanged, bufferWhen, take } from 'rxjs/operators';
4
+ import { catchError, map, filter, takeUntil, first, switchMap, tap as tap$1, finalize, throttleTime, debounceTime, startWith, distinctUntilChanged, mergeMap, skip, distinctUntilKeyChanged, bufferWhen, take } from 'rxjs/operators';
5
5
  import * as cloneImported from 'clone';
6
6
  import * as i3$1 from '@angular/common';
7
7
  import { CommonModule, DOCUMENT, LocationStrategy, APP_BASE_HREF, Location, NgIf, AsyncPipe, JsonPipe } from '@angular/common';
@@ -3544,14 +3544,20 @@ class SharedAsyncValidators {
3544
3544
  return of(res);
3545
3545
  }),
3546
3546
  // DEBUG
3547
- tap$1((res) => debug && console.debug(logPrefix + `Finished in ${Date.now() - now}ms (${res ? 'with errors' : 'no error'})`, res)), catchError((error) => {
3548
- console.error('[debounceTime-validator] Error while executing validator. Stopping job', error);
3549
- $disposeSubject.next();
3550
- throw error;
3551
- }),
3547
+ tap$1((res) => debug && console.debug(logPrefix + `Finished in ${Date.now() - now}ms (${res ? 'with errors' : 'no error'})`, res)),
3552
3548
  // Refresh UI, after a successful execution
3553
3549
  tap$1(() => opts?.markForCheck && opts?.markForCheck()),
3554
- // Make sure to stop, because of the switchMap
3550
+ // Catch error
3551
+ catchError((error) => {
3552
+ console.error(logPrefix + 'Error while executing validator. Stopping job', error);
3553
+ $disposeSubject.next();
3554
+ return of(null);
3555
+ }), finalize(() => {
3556
+ if (debug)
3557
+ console.debug(logPrefix + 'Validator disposed.');
3558
+ $disposeSubject.unsubscribe();
3559
+ }),
3560
+ // Make sure to stop
3555
3561
  takeUntil(disposeEvent$));
3556
3562
  };
3557
3563
  }
@@ -3563,8 +3569,10 @@ class SharedAsyncValidators {
3563
3569
  * @param opts
3564
3570
  */
3565
3571
  static registerAsyncValidator(form, validatorFn, opts) {
3572
+ if (!form)
3573
+ throw new Error('Cannot register async validator: form control is null or undefined.');
3566
3574
  if (form.asyncValidator)
3567
- throw Error('Form already have an async validator. Cannot configure job');
3575
+ throw new Error(`Form control already has an async validator. Clear it first or use a different control.`);
3568
3576
  const debounceTime = toNumber(opts?.debounceTime, 250);
3569
3577
  const $dispose = new Subject();
3570
3578
  const asyncValidatorFn = SharedAsyncValidators.debounceTime(validatorFn, { ...opts, debounceTime, dispose: $dispose });
@@ -3574,7 +3582,6 @@ class SharedAsyncValidators {
3574
3582
  subscription.add(() => {
3575
3583
  // Clear added validator. Must be done NOW (without delay) because generally a new Job is given just after
3576
3584
  form.clearAsyncValidators();
3577
- // Stop the job, with a delay to let the last execution finished
3578
3585
  setTimeout(() => {
3579
3586
  $dispose.next();
3580
3587
  $dispose.unsubscribe();
@@ -47179,7 +47186,6 @@ class UsersPage extends AppTable {
47179
47186
  dataService;
47180
47187
  messageService;
47181
47188
  menuService;
47182
- modalCtrl;
47183
47189
  canDebug;
47184
47190
  filterForm;
47185
47191
  profiles = [...PRIORITIZED_AUTHORITIES].reverse();
@@ -47244,7 +47250,7 @@ class UsersPage extends AppTable {
47244
47250
  showFooter = true;
47245
47251
  showToolbar = true;
47246
47252
  showPaginator = true;
47247
- constructor(injector, formBuilder, accountService, validatorService, configService, dataService, messageService, menuService, modalCtrl, environment) {
47253
+ constructor(injector, formBuilder, accountService, validatorService, configService, dataService, messageService, menuService, environment) {
47248
47254
  super(injector, RESERVED_START_COLUMNS.concat(['avatar', 'lastName', 'firstName', 'email', 'profile', 'status', 'username', 'usernameExtranet', 'pubkey'])
47249
47255
  .concat(accountService.additionalFields.filter((field) => AccountUtils.isFieldVisibleFor(field, 'users')).map((field) => field.key))
47250
47256
  .concat(['creationDate', 'updateDate'])
@@ -47259,7 +47265,6 @@ class UsersPage extends AppTable {
47259
47265
  this.dataService = dataService;
47260
47266
  this.messageService = messageService;
47261
47267
  this.menuService = menuService;
47262
- this.modalCtrl = modalCtrl;
47263
47268
  this.canDebug = !environment.production;
47264
47269
  this.canEdit = accountService.isAdmin();
47265
47270
  this.canSendMessage = this.canEdit;
@@ -47545,7 +47550,7 @@ class UsersPage extends AppTable {
47545
47550
  await this.savePageSettings(this.debug, 'debug');
47546
47551
  }
47547
47552
  getDisplayValueFn = FormFieldDefinitionUtils.getDisplayValueFn;
47548
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UsersPage, deps: [{ token: i0.Injector }, { token: i1$3.UntypedFormBuilder }, { token: AccountService }, { token: i1$8.ValidatorService }, { token: ConfigService }, { token: APP_PERSON_SERVICE }, { token: MessageService }, { token: MenuService }, { token: i2$1.ModalController }, { token: ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Component });
47553
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UsersPage, deps: [{ token: i0.Injector }, { token: i1$3.UntypedFormBuilder }, { token: AccountService }, { token: i1$8.ValidatorService }, { token: ConfigService }, { token: APP_PERSON_SERVICE }, { token: MessageService }, { token: MenuService }, { token: ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Component });
47549
47554
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: UsersPage, selector: "app-users-table", inputs: { showUsernameColumn: "showUsernameColumn", showUsernameExtranetColumn: "showUsernameExtranetColumn", showEmailColumn: "showEmailColumn", showPubkeyColumn: "showPubkeyColumn", showCreationDateColumn: "showCreationDateColumn", showUpdateDateColumn: "showUpdateDateColumn", title: "title", canSendMessage: ["canSendMessage", "canSendMessage", booleanAttribute], canEdit: ["canEdit", "canEdit", booleanAttribute], compact: ["compact", "compact", booleanAttribute], usePageSettings: ["usePageSettings", "usePageSettings", booleanAttribute], sticky: ["sticky", "sticky", booleanAttribute], stickyEnd: ["stickyEnd", "stickyEnd", booleanAttribute], canDownload: ["canDownload", "canDownload", booleanAttribute], inModal: ["inModal", "inModal", booleanAttribute], showFooter: ["showFooter", "showFooter", booleanAttribute], showToolbar: ["showToolbar", "showToolbar", booleanAttribute], showPaginator: ["showPaginator", "showPaginator", booleanAttribute] }, providers: [{ provide: ValidatorService, useExisting: PersonValidatorService }], viewQueries: [{ propertyName: "filterExpansionPanel", first: true, predicate: MatExpansionPanel, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n [title]=\"(title || 'USER.LIST.TITLE') | translate\"\n color=\"primary\"\n [canGoBack]=\"false\"\n [class.cdk-visible-hidden]=\"!showToolbar\"\n [hasValidate]=\"(loadingSubject | async) !== true && (dirtySubject | async) === true\"\n (onValidate)=\"save()\"\n>\n <ion-buttons slot=\"end\">\n <!-- Compose message -->\n <button\n mat-icon-button\n *ngIf=\"canSendMessage\"\n [title]=\"'USER.LIST.BTN_SEND_MESSAGE' | translate\"\n (click)=\"openComposeMessageModal($event)\"\n >\n <ion-icon name=\"mail\" slot=\"icon-only\"></ion-icon>\n </button>\n\n @if (selection | isEmptySelection) {\n <!-- Add -->\n <button mat-icon-button *ngIf=\"canEdit && !mobile\" [title]=\"'COMMON.BTN_ADD' | translate\" (click)=\"addRow()\">\n <mat-icon>add</mat-icon>\n </button>\n\n <!-- Refresh -->\n <button mat-icon-button *ngIf=\"!mobile\" [title]=\"'COMMON.BTN_REFRESH' | translate\" (click)=\"emitRefresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n <!-- reset filter -->\n <button mat-icon-button (click)=\"resetFilter()\" *ngIf=\"filterCriteriaCount\">\n <mat-icon color=\"accent\">filter_list_alt</mat-icon>\n <mat-icon class=\"icon-secondary\" style=\"left: 16px; top: 5px; font-weight: bold\">close</mat-icon>\n </button>\n\n <!-- show filter -->\n <button mat-icon-button (click)=\"filterExpansionPanel.toggle()\">\n <mat-icon\n *ngIf=\"filterCriteriaCount; else emptyFilter\"\n [matBadge]=\"filterCriteriaCount\"\n matBadgeColor=\"accent\"\n matBadgeSize=\"small\"\n matBadgePosition=\"above after\"\n aria-hidden=\"false\"\n >\n filter_list_alt\n </mat-icon>\n <ng-template #emptyFilter>\n <mat-icon>filter_list_alt</mat-icon>\n </ng-template>\n </button>\n } @else {\n <!-- delete -->\n <button\n mat-icon-button\n class=\"hidden-xs hidden-sm\"\n [title]=\"'COMMON.BTN_DELETE' | translate\"\n (click)=\"deleteSelection($event)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n }\n\n @if (!mobile && (canDownload || canDebug)) {\n <button mat-icon-button [title]=\"'COMMON.BTN_OPTIONS' | translate\" [matMenuTriggerFor]=\"toolbarOptionsMenu\">\n <mat-icon>more_vert</mat-icon>\n </button>\n }\n </ion-buttons>\n</app-toolbar>\n\n<!-- Toolbar option menu -->\n<mat-menu #toolbarOptionsMenu=\"matMenu\" xPosition=\"after\">\n <ng-template matMenuContent>\n <!-- export button -->\n @if (canDownload) {\n <button mat-menu-item (click)=\"exportToCsv($event)\">\n <mat-icon>download</mat-icon>\n <ion-label translate>FILE.CSV.BTN_DOWNLOAD_HELP</ion-label>\n </button>\n }\n\n <!-- Debug only: Test select users modal -->\n @if (canDebug) {\n <mat-divider></mat-divider>\n\n <button mat-menu-item #menuTrigger=\"matMenuTrigger\" (mouseenter)=\"menuTrigger.openMenu()\" [matMenuTriggerFor]=\"debugMenu\">\n <mat-icon>\n <ion-icon name=\"bug\"></ion-icon>\n </mat-icon>\n <ion-label translate>COMMON.DEBUG.BTN_DEBUG_DOTS</ion-label>\n </button>\n }\n </ng-template>\n</mat-menu>\n\n<!-- debug menu -->\n<mat-menu #debugMenu=\"matMenu\">\n <ng-template matMenuContent>\n\n <button mat-menu-item (click)=\"devToggleDebug()\">\n <mat-icon>{{ debug ? 'check_box' : 'check_box_outline_blank' }}</mat-icon>\n <ion-label translate>COMMON.DEBUG.BTN_ENABLE_DEBUG</ion-label>\n </button>\n </ng-template>\n</mat-menu>\n\n<ion-content class=\"ion-no-padding\">\n <!-- error -->\n <ion-item\n *ngIf=\"mobile && (errorSubject | async); let error\"\n lines=\"none\"\n class=\"hidden-sm hidden-xs hidden-mobile\"\n @slideUpDownAnimation\n >\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <!-- debug -->\n <app-debug *ngIf=\"debug\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n focusColumn: {{ focusColumn }}\n <br/>\n loadingSubject: {{ loading }}\n <br/>\n </ion-col>\n </ion-row>\n </ion-grid>\n </app-debug>\n\n <!-- search -->\n <mat-expansion-panel #filterExpansionPanel class=\"ion-no-padding filter-panel filter-panel-floating\">\n <form class=\"form-container ion-padding\" [formGroup]=\"filterForm\" (ngSubmit)=\"emitRefresh()\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <!-- search -->\n <mat-form-field>\n <mat-label>{{ 'USER.LIST.FILTER.SEARCH' | translate }}</mat-label>\n <input matInput formControlName=\"searchText\"/>\n <button\n mat-icon-button\n matSuffix\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.searchText)\"\n [hidden]=\"filterForm.controls.searchText.disabled || !filterForm.controls.searchText.value\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n\n <ion-col>\n <!-- status -->\n <mat-form-field>\n <mat-label>{{ 'USER.STATUS' | translate }}</mat-label>\n <mat-select formControlName=\"statusId\">\n <mat-option [value]=\"null\">\n <i><span translate>COMMON.EMPTY_OPTION</span></i>\n </mat-option>\n <mat-option *ngFor=\"let item of statusList\" [value]=\"item.id\">\n <ion-icon [name]=\"item.icon\"></ion-icon>\n {{ item.label | translate }}\n </mat-option>\n </mat-select>\n\n <button\n mat-icon-button\n matSuffix\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearControlValue($event, filterForm.controls.statusId)\"\n [hidden]=\"filterForm.controls.statusId.disabled || filterForm.controls.statusId.value == null\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </ion-col>\n\n <ion-col>\n <!-- user profiles -->\n <mat-chips-field\n formControlName=\"userProfiles\"\n [placeholder]=\"'USER.PROFILES' | translate\"\n chipColor=\"accent\"\n [items]=\"userProfileList\"\n [displayAttributes]=\"['name']\"\n [clearable]=\"true\">\n </mat-chips-field>\n </ion-col>\n </ion-row>\n\n <!-- Additional fields filters -->\n @if (additionalFilterFields | isNotEmptyArray) {\n <ion-row>\n @for (field of additionalFilterFields; track field.key) {\n <ion-col size=\"12\" size-md=\"6\" size-lg=\"4\">\n <app-form-field\n [definition]=\"field\"\n [formControlName]=\"field.key\"\n [clearable]=\"true\"\n floatLabel=\"auto\">\n </app-form-field>\n </ion-col>\n }\n </ion-row>\n }\n </ion-grid>\n </form>\n\n <mat-action-row>\n <!-- Counter -->\n <ion-label\n [hidden]=\"(loadingSubject | async) === true || filterForm.dirty\"\n [color]=\"empty && 'danger'\"\n class=\"ion-padding\"\n >\n {{\n (totalRowCount ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT')\n | translate\n : {\n count: (totalRowCount | numberFormat),\n }\n }}\n </ion-label>\n\n <div class=\"toolbar-spacer\"></div>\n\n <!-- Close panel -->\n <ion-button\n mat-button\n fill=\"clear\"\n color=\"dark\"\n (click)=\"filterExpansionPanel.close()\"\n [disabled]=\"loadingSubject | async\"\n >\n <ion-text translate>COMMON.BTN_CLOSE</ion-text>\n </ion-button>\n\n <!-- Search button -->\n <ion-button\n mat-button\n [color]=\"filterForm.dirty ? 'tertiary' : 'dark'\"\n [fill]=\"filterForm.dirty ? 'solid' : 'clear'\"\n (click)=\"applyFilterAndClosePanel($event)\"\n [disabled]=\"loadingSubject | async\"\n >\n <ion-text translate>COMMON.BTN_APPLY</ion-text>\n </ion-button>\n </mat-action-row>\n </mat-expansion-panel>\n\n <!-- error -->\n @if (mobile && (errorSubject | async); as error) {\n <ion-item lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n }\n\n <div class=\"table-container\" [class.has-toolbar]=\"showToolbar\"\n [class.has-paginator]=\"showPaginator\" [class.has-form-buttons]=\"showFormButtons\">\n <table\n #table\n mat-table\n matSort\n [class.compact]=\"compact\"\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n matSortDisableClear\n [trackBy]=\"trackByFn\"\n >\n <ng-container matColumnDef=\"select\" [sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!inlineEdition\">\n <mat-checkbox\n (change)=\"$event ? masterToggle() : null\"\n [checked]=\"this | isAllSelected\"\n [indeterminate]=\"this | isNotAllSelected\"\n ></mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!inlineEdition\">\n <mat-checkbox (click)=\"toggleSelectRow($event, row)\" [checked]=\"selection | isSelected: row\"></mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id Column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <ion-label>{{ row.currentData.id }}</ion-label>\n </td>\n </ng-container>\n\n <!-- avatar Column -->\n <ng-container matColumnDef=\"avatar\" [sticky]=\"sticky\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let row\">\n <ion-avatar [style.background-color]=\"'white'\">\n @if (row.currentData.avatar; as avatarUrl) {\n <ion-img [src]=\"avatarUrl\"></ion-img>\n } @else {\n <svg width=\"39\" height=\"39\" [data-jdenticon-value]=\"row.currentData.id\"></svg>\n }\n </ion-avatar>\n </td>\n </ng-container>\n\n <!-- lastName -->\n <ng-container matColumnDef=\"lastName\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.LAST_NAME</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'lastName'\">\n @if (row.editing) {\n <mat-form-field>\n <input\n matInput\n [formControl]=\"row.validator.controls['lastName']\"\n [placeholder]=\"'USER.LAST_NAME' | translate\"\n [readonly]=\"!row.editing\"\n [appAutofocus]=\"row.editing && focusColumn === 'lastName'\"\n />\n <mat-error *ngIf=\"row.validator.controls['lastName'].hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"row.validator.controls['lastName'].hasError('minlength')\">\n <span>{{ 'ERROR.FIELD_MIN_LENGTH' | translate: {requiredLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'lastName' }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- firstname -->\n <ng-container matColumnDef=\"firstName\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.FIRST_NAME</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'firstName'\">\n @if (row.editing) {\n <mat-form-field>\n <input\n matInput\n [formControl]=\"row.validator.controls['firstName']\"\n [placeholder]=\"'USER.FIRST_NAME' | translate\"\n [readonly]=\"!row.editing\"\n [appAutofocus]=\"row.editing && focusColumn === 'firstName'\"\n />\n <mat-error *ngIf=\"row.validator.controls['firstName'].hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"row.validator.controls['firstName'].hasError('minlength')\">\n <span>{{ 'ERROR.FIELD_MIN_LENGTH' | translate: {requiredLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'firstName' }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- email -->\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.EMAIL</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'email'\">\n @if (row.editing) {\n <mat-form-field>\n <input\n matInput\n [formControl]=\"row.validator.controls['email']\"\n [placeholder]=\"'USER.EMAIL' | translate\"\n [readonly]=\"!row.editing\"\n [appAutofocus]=\"row.editing && focusColumn === 'email'\"\n />\n <mat-error *ngIf=\"row.validator.controls['email'].hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"row.validator.controls['email'].hasError('email')\">\n <span translate>ERROR.FIELD_NOT_VALID_EMAIL</span>\n </mat-error>\n </mat-form-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'email' }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- additional fields -->\n @for (definition of additionalFields; track definition.key) {\n <ng-container [matColumnDef]=\"definition.key\">\n <th mat-header-cell *matHeaderCellDef>\n <span>{{ definition.label | translate }}</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = definition.key\">\n @if (row.editing) {\n <app-form-field\n floatLabel=\"never\"\n [definition]=\"definition\"\n [formControl]=\"row.validator.controls[definition.key]\"\n [required]=\"definition.extra?.users?.required\"\n [autofocus]=\"row.editing && focusColumn === definition.key\"\n ></app-form-field>\n } @else {\n <ion-label appAutoTitle>{{ row.validator | formGetValue: definition.key | displayWith: getDisplayValueFn(definition) }}</ion-label>\n }\n </td>\n </ng-container>\n }\n\n <!-- profile column -->\n <ng-container matColumnDef=\"profile\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.PROFILE</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'profile'\">\n @if (row.editing) {\n <mat-form-field>\n <mat-select\n [formControl]=\"row.validator | formGetControl: 'mainProfile'\"\n [placeholder]=\"'USER.PROFILE' | translate\"\n >\n <mat-option *ngFor=\"let item of profiles\" [value]=\"item\">\n {{ 'USER.PROFILE_ENUM.' + item | uppercase | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"row.validator.controls['mainProfile'].hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n @let profile = row.validator | formGetValue: 'mainProfile';\n @if (profile) {\n <ion-label appAutoTitle>{{ 'USER.PROFILE_ENUM.' + profile | uppercase | translate }}</ion-label>\n }\n }\n\n </td>\n </ng-container>\n\n <!-- Status column -->\n <ng-container matColumnDef=\"status\">\n <th mat-header-cell *matHeaderCellDef>\n <span translate>USER.STATUS</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'status'\">\n @if (row.editing) {\n @let control = row.validator | formGetControl: 'statusId';\n <mat-form-field>\n <mat-select\n [formControl]=\"control\"\n [placeholder]=\"'REFERENTIAL.STATUS' | translate\"\n >\n <mat-select-trigger>\n <span *ngIf=\"control.value >= 0\">\n {{ statusById[control.value]?.label | translate }}\n </span>\n </mat-select-trigger>\n @for (item of statusList; track item.id) {\n <mat-option [value]=\"item.id\">\n <mat-icon>\n <ion-icon [name]=\"item.icon\"></ion-icon>\n </mat-icon>\n {{ item.label | translate }}\n </mat-option>\n }\n </mat-select>\n <mat-error *ngIf=\"control.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n @let statusId = row.validator | formGetValue: 'statusId';\n @if (statusId >= 0) {\n <ion-label appAutoTitle>\n {{ (statusById | mapGet: statusId)?.label | translate }}\n </ion-label>\n }\n }\n </td>\n </ng-container>\n\n <!-- username -->\n <ng-container matColumnDef=\"username\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.USERNAME</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'username'\">\n @if (row.editing) {\n <mat-form-field>\n <input\n matInput\n [formControl]=\"row.validator.controls.username\"\n [placeholder]=\"'USER.USERNAME' | translate\"\n [readonly]=\"!row.editing\"\n [appAutofocus]=\"row.editing && focusColumn === 'username'\"\n />\n <mat-error *ngIf=\"row.validator.controls.username.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'username' }}\n </ion-label>\n }\n </td>\n </ng-container>\n\n <!-- username extranet -->\n <ng-container matColumnDef=\"usernameExtranet\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.USERNAME_EXTRANET</span>\n </th>\n <td mat-cell *matCellDef=\"let row\" (click)=\"focusColumn = 'usernameExtranet'\">\n <mat-form-field *ngIf=\"row.editing; else readonlyCell\">\n <input\n matInput\n [formControl]=\"row.validator.controls.usernameExtranet\"\n [placeholder]=\"'USER.USERNAME_EXTRANET' | translate\"\n [readonly]=\"!row.editing\"\n [appAutofocus]=\"row.editing && focusColumn === 'usernameExtranet'\"\n />\n <mat-error *ngIf=\"row.validator.controls.usernameExtranet.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'usernameExtranet' }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- pubkey -->\n <ng-container matColumnDef=\"pubkey\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <span translate>USER.PUBKEY</span>\n </th>\n <td\n mat-cell\n *matCellDef=\"let row\"\n [title]=\"row.validator.controls.pubkey.valueChanges | async\"\n (click)=\"focusColumn = 'pubkey'\"\n >\n <mat-form-field *ngIf=\"row.editing; else readonlyCell\">\n <input\n matInput\n [formControl]=\"row.validator.controls['pubkey']\"\n [placeholder]=\"'USER.PUBKEY' | translate\"\n [readonly]=\"!row.editing\"\n autocomplete=\"off\"\n />\n <mat-error *ngIf=\"row.validator.controls.pubkey.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"row.validator.controls.pubkey.hasError('pubkey')\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n <ng-template #readonlyCell>\n <ion-label appAutoTitle>\n {{ row.validator | formGetValue: 'pubkey' }}\n </ion-label>\n </ng-template>\n </td>\n </ng-container>\n\n <!-- Creation date column -->\n <ng-container matColumnDef=\"creationDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>USER.CREATION_DATE</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-form-field-disabled\">\n <ion-text class=\"ion-text-end\" color=\"medium\" *ngIf=\"row.id !== -1\">\n {{ row.currentData.creationDate | dateFormat: {time: true} }}\n </ion-text>\n </td>\n </ng-container>\n\n <!-- Update date column -->\n <ng-container matColumnDef=\"updateDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label translate>USER.UPDATE_DATE</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-form-field-disabled\">\n <ion-text class=\"ion-text-end\" color=\"medium\" *ngIf=\"row.id !== -1\">\n {{ row.currentData.updateDate | dateFormat: {time: true} }}\n </ion-text>\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column\n [stickyEnd]=\"stickyEnd\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmEditCreateClick)=\"confirmEditCreate($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [canCancel]=\"false\"\n >\n <!-- table options menu -->\n <button\n matHeader\n mat-icon-button\n [title]=\"'COMMON.BTN_OPTIONS' | translate\"\n [matMenuTriggerFor]=\"tableOptionsMenu\"\n >\n <mat-icon>more_vert</mat-icon>\n </button>\n </app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-row-error]=\"row.validator.invalid\"\n [class.mat-row-dirty]=\"row.currentData.dirty\"\n [class.mat-row-disabled]=\"!row.editing\"\n [class.mat-mdc-row-selected]=\"row.editing || (!canEdit && selection | isSelected: row)\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"!row.validator?.valid\"\n ></tr>\n </table>\n\n <!-- D\u00E9clencheur invisible pour le mat-menu -->\n\n @if (loadingSubject | async) {\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n } @else if (totalRowCount === 0) {\n <ion-item>\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n }\n </div>\n</ion-content>\n\n<!-- Table options menu -->\n<mat-menu #tableOptionsMenu=\"matMenu\" xPosition=\"after\">\n <!-- display columns -->\n <button mat-menu-item (click)=\"openSelectColumnsModal($event)\">\n <mat-icon>view_column</mat-icon>\n <ion-label translate>COMMON.DISPLAYED_COLUMNS_DOTS</ion-label>\n </button>\n\n @if (usePageSettings) {\n <mat-divider></mat-divider>\n\n <!-- Compact mode -->\n <button mat-menu-item (click)=\"toggleCompactMode()\">\n <mat-icon>{{ compact ? 'check_box' : 'check_box_outline_blank' }}</mat-icon>\n <ion-label translate>COMMON.BTN_COMPACT_ROWS</ion-label>\n </button>\n }\n</mat-menu>\n\n<ion-footer>\n <mat-paginator *ngIf=\"showPaginator\"\n [length]=\"totalRowCount\"\n [pageSize]=\"defaultPageSize\"\n [pageSizeOptions]=\"defaultPageSizeOptions\"\n showFirstLastButtons\n ></mat-paginator>\n\n @if (showFormButtons) {\n <app-form-buttons-bar\n (onCancel)=\"cancel($event)\"\n (onSave)=\"save()\"\n [disabled]=\"(loadingSubject | async) === true || (dirtySubject | async) !== true\"\n >\n <!-- error -->\n <ion-item *ngIf=\"errorSubject | async; let error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n }\n</ion-footer>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addRow()\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".mat-expansion-panel{margin-bottom:5px}.mat-expansion-panel .form-container mat-form-field{width:100%}.mat-expansion-panel mat-action-row ion-label{line-height:36px}ion-content{height:calc(100% - var(--table-offset, 0px))}.table-container{height:100%}.table-container.has-toolbar{--table-toolbar-height: var(--mat-toolbar-height, 64px)}.table-container.has-paginator{--table-paginator-height: var(--app-paginator-height, 34px)}.table-container.has-form-buttons{--form-buttons-height: var(--ion-toolbar-height, 56px)}.mat-mdc-table .mat-column-avatar{--avatar-width: 40px;--avatar-height: 40px;width:calc(var(--avatar-width) + 10px)}.mat-mdc-table .mat-column-avatar ion-avatar{--border-radius: 5px !important;--border-width: 1px !important;--border-color: rgba(var(--ion-color-secondary-rgb), .5) !important;height:var(--avatar-height);max-height:var(--avatar-height);width:var(--avatar-width);max-width:var(--avatar-width);border:solid var(--border-width) var(--border-color);margin:0 2px}.mat-mdc-table .mat-column-avatar ion-avatar svg{max-height:calc(var(--avatar-height) - 1px);max-width:calc(var(--avatar-width) - 1px)}.mat-mdc-table.compact{--mat-row-height: 33px}.mat-mdc-table.compact .mat-column-avatar{--avatar-width: calc(var(--mat-row-height, 33px) - 4px);--avatar-height: calc(var(--mat-row-height, 33px) - 4px)}.mat-mdc-table .mat-column-id{min-width:50px;max-width:120px;padding-right:var(--mat-cell-horizontal-padding, 4px)}.mat-mdc-table .mat-column-lastName,.mat-mdc-table .mat-column-firstName{min-width:80px}.mat-mdc-table .mat-column-email,.mat-mdc-table .mat-column-pubkey,.mat-mdc-table .mat-column-department{min-width:180px}.mat-mdc-table .mat-column-profile{min-width:110px}.mat-mdc-table .mat-column-status,.mat-mdc-table .mat-column-creationDate,.mat-mdc-table .mat-column-updateDate{min-width:130px}\n"], dependencies: [{ kind: "directive", type: i4$3.SvgJdenticonDirective, selector: "svg[data-jdenticon-hash],svg[data-jdenticon-value]", inputs: ["data-jdenticon-hash", "data-jdenticon-value", "width", "height"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonAvatar, selector: "ion-avatar" }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFab, selector: "ion-fab", inputs: ["activated", "edge", "horizontal", "vertical"] }, { kind: "component", type: i2$1.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonImg, selector: "ion-img", inputs: ["alt", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.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$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i1$7.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$7.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$7.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$7.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$7.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$7.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$7.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$7.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$7.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$7.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i8$2.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8$2.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i9$3.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i13$2.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i13$2.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i6$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i12.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i12.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i12.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i12.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i6$3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i6$3.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i9.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "directive", type: i1$5.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: MatChipsField, selector: "mat-chips-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "placeholder", "suggestFn", "required", "mobile", "readonly", "clearable", "debounceTime", "displaySeparator", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "autofocus", "config", "i18nPrefix", "noResultMessage", "panelClass", "panelWidth", "disableRipple", "matAutocompletePosition", "itemSize", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "chipColor", "debug", "applyImplicitValue", "dropButtonTitle", "clearButtonTitle", "trimSearchText", "hideRequiredMarker", "colSizes", "separatorKeysCodes", "appearance", "subscriptSizing", "class", "filter", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keyup.enter"] }, { kind: "directive", type: AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "directive", type: AutoTitleDirective, selector: "ion-label[appAutoTitle], mat-label[appAutoTitle]", inputs: ["appAutoTitle"] }, { kind: "component", type: ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "id", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: AppFormField, selector: "app-form-field", inputs: ["definition", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "required", "hideRequiredMarker", "floatLabel", "label", "appearance", "subscriptSizing", "tabindex", "autofocus", "clearable", "chipColor", "class", "debug", "panelClass", "panelWidth"], outputs: ["keyup.enter"] }, { kind: "component", type: FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "disabledEscape", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: ActionsColumnComponent, selector: "app-actions-column", inputs: ["matColumnDef", "style", "showPendingSpinner", "stickyEnd", "canCancel", "canConfirm", "canDelete", "canBackward", "canForward", "canConfirmAndAdd", "dirtyIcon", "optionsTitle", "class", "cellTemplateStart", "cellTemplate"], outputs: ["optionsClick", "cancelOrDeleteClick", "confirmEditCreateClick", "confirmAndAddClick", "backward", "forward"] }, { kind: "component", type: DebugComponent, selector: "app-debug", inputs: ["titlePrefix", "title", "enable", "expanded"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "pipe", type: i3$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: DateFormatPipe, name: "dateFormat" }, { kind: "pipe", type: NumberFormatPipe, name: "numberFormat" }, { kind: "pipe", type: NotEmptyArrayPipe, name: "isNotEmptyArray" }, { kind: "pipe", type: MapGetPipe, name: "mapGet" }, { kind: "pipe", type: FormGetControlPipe, name: "formGetControl" }, { kind: "pipe", type: FormGetValuePipe, name: "formGetValue" }, { kind: "pipe", type: IsSelectedPipe, name: "isSelected" }, { kind: "pipe", type: IsEmptySelectionPipe, name: "isEmptySelection" }, { kind: "pipe", type: DisplayWithPipe, name: "displayWith" }, { kind: "pipe", type: IsAllSelectedPipe, name: "isAllSelected" }, { kind: "pipe", type: IsNotAllSelectedPipe, name: "isNotAllSelected" }], animations: [slideUpDownAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush });
47550
47555
  }
47551
47556
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UsersPage, decorators: [{
@@ -47554,7 +47559,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
47554
47559
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i1$3.UntypedFormBuilder }, { type: AccountService }, { type: i1$8.ValidatorService }, { type: ConfigService }, { type: undefined, decorators: [{
47555
47560
  type: Inject,
47556
47561
  args: [APP_PERSON_SERVICE]
47557
- }] }, { type: MessageService }, { type: MenuService }, { type: i2$1.ModalController }, { type: undefined, decorators: [{
47562
+ }] }, { type: MessageService }, { type: MenuService }, { type: Environment, decorators: [{
47558
47563
  type: Inject,
47559
47564
  args: [ENVIRONMENT]
47560
47565
  }] }], propDecorators: { showUsernameColumn: [{