@wavemaker/app-ng-runtime 12.0.0-next.45031 → 12.0.0-next.45501

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. app-ng-runtime/build-task/bundles/index.umd.js +405 -451
  2. app-ng-runtime/build-task/esm2022/data/form/form-field/form-field.build.mjs +2 -3
  3. app-ng-runtime/build-task/esm2022/public_api.mjs +1 -3
  4. app-ng-runtime/build-task/fesm2022/index.mjs +406 -454
  5. app-ng-runtime/build-task/fesm2022/index.mjs.map +1 -1
  6. app-ng-runtime/build-task/public_api.d.ts +0 -2
  7. app-ng-runtime/components/base/bundles/index.umd.js +14 -62
  8. app-ng-runtime/components/base/components.module.d.ts +11 -12
  9. app-ng-runtime/components/base/esm2022/components.module.mjs +1 -5
  10. app-ng-runtime/components/base/esm2022/public_api.mjs +1 -2
  11. app-ng-runtime/components/base/esm2022/widgets/common/base/base.component.mjs +15 -25
  12. app-ng-runtime/components/base/fesm2022/index.mjs +15 -62
  13. app-ng-runtime/components/base/fesm2022/index.mjs.map +1 -1
  14. app-ng-runtime/components/base/public_api.d.ts +0 -1
  15. app-ng-runtime/components/base/widgets/common/base/base.component.d.ts +5 -10
  16. app-ng-runtime/components/containers/wizard/bundles/index.umd.js +17 -0
  17. app-ng-runtime/components/containers/wizard/esm2022/wizard.component.mjs +18 -1
  18. app-ng-runtime/components/containers/wizard/fesm2022/index.mjs +17 -0
  19. app-ng-runtime/components/containers/wizard/fesm2022/index.mjs.map +1 -1
  20. app-ng-runtime/components/containers/wizard/wizard.component.d.ts +1 -0
  21. app-ng-runtime/components/data/form/esm2022/form-field/form-field.directive.mjs +1 -3
  22. app-ng-runtime/components/data/form/fesm2022/index.mjs +0 -2
  23. app-ng-runtime/components/data/form/fesm2022/index.mjs.map +1 -1
  24. app-ng-runtime/components/dialogs/default/bundles/index.umd.js +11 -0
  25. app-ng-runtime/components/dialogs/default/esm2022/base-dialog.mjs +12 -1
  26. app-ng-runtime/components/dialogs/default/fesm2022/index.mjs +11 -0
  27. app-ng-runtime/components/dialogs/default/fesm2022/index.mjs.map +1 -1
  28. app-ng-runtime/components/input/default/bundles/index.umd.js +63 -39
  29. app-ng-runtime/components/input/default/checkboxset/checkboxset.component.d.ts +0 -1
  30. app-ng-runtime/components/input/default/esm2022/checkboxset/checkboxset.component.mjs +5 -8
  31. app-ng-runtime/components/input/default/esm2022/radioset/radioset.component.mjs +5 -8
  32. app-ng-runtime/components/input/default/esm2022/select/select.component.mjs +57 -29
  33. app-ng-runtime/components/input/default/esm2022/text/base/base-input.mjs +1 -4
  34. app-ng-runtime/components/input/default/esm2022/text/locale/number-locale.mjs +2 -2
  35. app-ng-runtime/components/input/default/esm2022/textarea/textarea.component.mjs +4 -1
  36. app-ng-runtime/components/input/default/fesm2022/index.mjs +63 -39
  37. app-ng-runtime/components/input/default/fesm2022/index.mjs.map +1 -1
  38. app-ng-runtime/components/input/default/radioset/radioset.component.d.ts +0 -1
  39. app-ng-runtime/components/input/default/select/select.component.d.ts +2 -4
  40. app-ng-runtime/components/input/default/textarea/textarea.component.d.ts +3 -2
  41. app-ng-runtime/components/input/epoch/bundles/index.umd.js +3 -0
  42. app-ng-runtime/components/input/epoch/esm2022/date-time/date-time.component.mjs +4 -1
  43. app-ng-runtime/components/input/epoch/fesm2022/index.mjs +3 -0
  44. app-ng-runtime/components/input/epoch/fesm2022/index.mjs.map +1 -1
  45. app-ng-runtime/components/input/file-upload/bundles/index.umd.js +31 -5
  46. app-ng-runtime/components/input/file-upload/esm2022/file-upload.component.mjs +34 -8
  47. app-ng-runtime/components/input/file-upload/fesm2022/index.mjs +32 -6
  48. app-ng-runtime/components/input/file-upload/fesm2022/index.mjs.map +1 -1
  49. app-ng-runtime/components/input/file-upload/file-upload.component.d.ts +6 -2
  50. app-ng-runtime/components/navigation/menu/bundles/index.umd.js +2 -2
  51. app-ng-runtime/components/navigation/menu/esm2022/menu.component.mjs +2 -2
  52. app-ng-runtime/components/navigation/menu/esm2022/nav/nav.component.mjs +2 -2
  53. app-ng-runtime/components/navigation/menu/fesm2022/index.mjs +2 -2
  54. app-ng-runtime/components/navigation/menu/fesm2022/index.mjs.map +1 -1
  55. app-ng-runtime/core/bundles/index.umd.js +6 -16
  56. app-ng-runtime/core/enums/enums.d.ts +1 -2
  57. app-ng-runtime/core/esm2022/enums/enums.mjs +1 -2
  58. app-ng-runtime/core/esm2022/types/types.mjs +1 -4
  59. app-ng-runtime/core/esm2022/utils/build-utils.mjs +1 -6
  60. app-ng-runtime/core/esm2022/utils/utils.mjs +4 -3
  61. app-ng-runtime/core/fesm2022/index.mjs +4 -12
  62. app-ng-runtime/core/fesm2022/index.mjs.map +1 -1
  63. app-ng-runtime/core/types/types.d.ts +1 -5
  64. app-ng-runtime/core/utils/utils.d.ts +1 -0
  65. app-ng-runtime/mobile/core/bundles/index.umd.js +18 -2
  66. app-ng-runtime/mobile/core/esm2022/native.xhr.mjs +19 -3
  67. app-ng-runtime/mobile/core/fesm2022/index.mjs +18 -2
  68. app-ng-runtime/mobile/core/fesm2022/index.mjs.map +1 -1
  69. app-ng-runtime/package.json +1 -1
  70. app-ng-runtime/runtime/base/bundles/index.umd.js +5 -288
  71. app-ng-runtime/runtime/base/esm2022/public_api.mjs +1 -2
  72. app-ng-runtime/runtime/base/esm2022/runtime-base.module.mjs +1 -6
  73. app-ng-runtime/runtime/base/esm2022/services/i18n.service.mjs +2 -2
  74. app-ng-runtime/runtime/base/esm2022/types/types.mjs +1 -2
  75. app-ng-runtime/runtime/base/fesm2022/index.mjs +4 -287
  76. app-ng-runtime/runtime/base/fesm2022/index.mjs.map +1 -1
  77. app-ng-runtime/runtime/base/public_api.d.ts +0 -1
  78. app-ng-runtime/runtime/base/runtime-base.module.d.ts +8 -9
  79. app-ng-runtime/runtime/base/types/types.d.ts +1 -2
  80. app-ng-runtime/runtime/dynamic/bundles/index.umd.js +9 -27
  81. app-ng-runtime/runtime/dynamic/esm2022/app/app.module.mjs +2 -5
  82. app-ng-runtime/runtime/dynamic/esm2022/app/services/component-ref-provider.service.mjs +7 -23
  83. app-ng-runtime/runtime/dynamic/fesm2022/index.mjs +7 -26
  84. app-ng-runtime/runtime/dynamic/fesm2022/index.mjs.map +1 -1
  85. app-ng-runtime/scripts/@wavemaker/nvd3/build/nv.d3.min.js +1 -1
  86. app-ng-runtime/scripts/datatable/datatable.js +6 -3
  87. app-ng-runtime/scripts/summernote/dist/summernote-lite.min.js +2 -3
  88. app-ng-runtime/transpiler/bundles/index.umd.js +0 -5
  89. app-ng-runtime/transpiler/esm2022/build.mjs +1 -4
  90. app-ng-runtime/transpiler/esm2022/imports.mjs +1 -3
  91. app-ng-runtime/transpiler/fesm2022/index.mjs +0 -5
  92. app-ng-runtime/transpiler/fesm2022/index.mjs.map +1 -1
  93. app-ng-runtime/build-task/advanced/custom-widget-container/custom-widget-container.build.d.ts +0 -2
  94. app-ng-runtime/build-task/advanced/custom-widget-wrapper/custom-widget-wrapper.build.d.ts +0 -2
  95. app-ng-runtime/build-task/esm2022/advanced/custom-widget-container/custom-widget-container.build.mjs +0 -15
  96. app-ng-runtime/build-task/esm2022/advanced/custom-widget-wrapper/custom-widget-wrapper.build.mjs +0 -26
  97. app-ng-runtime/components/advanced/custom/.npmignore +0 -2
  98. app-ng-runtime/components/advanced/custom/bundles/index.umd.js +0 -232
  99. app-ng-runtime/components/advanced/custom/custom-widget-container/custom-widget-container.directive.d.ts +0 -19
  100. app-ng-runtime/components/advanced/custom/custom-widget-container/custom-widget.props.d.ts +0 -2
  101. app-ng-runtime/components/advanced/custom/custom-widget-prop.d.ts +0 -1
  102. app-ng-runtime/components/advanced/custom/custom-widget.directive.d.ts +0 -19
  103. app-ng-runtime/components/advanced/custom/custom-widget.module.d.ts +0 -10
  104. app-ng-runtime/components/advanced/custom/esm2022/custom-widget-container/custom-widget-container.directive.mjs +0 -102
  105. app-ng-runtime/components/advanced/custom/esm2022/custom-widget-container/custom-widget.props.mjs +0 -12
  106. app-ng-runtime/components/advanced/custom/esm2022/custom-widget-prop.mjs +0 -8
  107. app-ng-runtime/components/advanced/custom/esm2022/custom-widget.directive.mjs +0 -68
  108. app-ng-runtime/components/advanced/custom/esm2022/custom-widget.module.mjs +0 -32
  109. app-ng-runtime/components/advanced/custom/esm2022/index.mjs +0 -5
  110. app-ng-runtime/components/advanced/custom/esm2022/public_api.mjs +0 -4
  111. app-ng-runtime/components/advanced/custom/fesm2022/index.mjs +0 -215
  112. app-ng-runtime/components/advanced/custom/fesm2022/index.mjs.map +0 -1
  113. app-ng-runtime/components/advanced/custom/index.d.ts +0 -5
  114. app-ng-runtime/components/advanced/custom/package.json +0 -23
  115. app-ng-runtime/components/advanced/custom/public_api.d.ts +0 -3
  116. app-ng-runtime/components/base/esm2022/widgets/common/base/custom-widget-container.directive.mjs +0 -39
  117. app-ng-runtime/components/base/widgets/common/base/custom-widget-container.directive.d.ts +0 -14
  118. app-ng-runtime/runtime/base/components/base-custom-widget.component.d.ts +0 -72
  119. app-ng-runtime/runtime/base/esm2022/components/base-custom-widget.component.mjs +0 -288
@@ -268,7 +268,7 @@
268
268
  const ctx_r1 = i0__namespace.ɵɵnextContext();
269
269
  i0__namespace.ɵɵproperty("ngStyle", i0__namespace.ɵɵpureFunction2(2, _c2, ctx_r1.filelistheight, ctx_r1.overflow));
270
270
  i0__namespace.ɵɵadvance();
271
- i0__namespace.ɵɵproperty("ngForOf", ctx_r1.selectedFiles);
271
+ i0__namespace.ɵɵproperty("ngForOf", ctx_r1.multiple ? ctx_r1.multipleSelectedFiles : ctx_r1.selectedFiles);
272
272
  } }
273
273
  function FileUploadComponent_ul_5_li_1_Template(rf, ctx) { if (rf & 1) {
274
274
  i0__namespace.ɵɵelementStart(0, "li", 26)(1, "div", 27);
@@ -405,6 +405,7 @@
405
405
  * @param $files
406
406
  */
407
407
  onSelectEventCall($event, $files) {
408
+ this.multipleSelectedFiles = this.multiple ? [...this.multipleSelectedFiles, ...$files] : $files;
408
409
  this.selectedFiles = $files;
409
410
  setTimeout(() => {
410
411
  this.invokeEventCallback('select', {
@@ -427,7 +428,12 @@
427
428
  }
428
429
  /*this function to clear the specified file. if argument is not provided, it clears the complete list */
429
430
  clear(fileObj) {
430
- this.selectedFiles = (fileObj) ? this.selectedFiles.filter((file) => file !== fileObj) : [];
431
+ if (this.multiple) {
432
+ this.multipleSelectedFiles = (fileObj) ? this.multipleSelectedFiles.filter((file) => file !== fileObj) : [];
433
+ }
434
+ else {
435
+ this.selectedFiles = (fileObj) ? this.selectedFiles.filter((file) => file !== fileObj) : [];
436
+ }
431
437
  }
432
438
  /*this function to set the class names for clear icon */
433
439
  setClearIconClass(classValue) {
@@ -474,6 +480,10 @@
474
480
  file.status = progressObj.status;
475
481
  if (progressObj.errMsg) {
476
482
  file.errMsg = progressObj.errMsg;
483
+ this.invokeEventCallback('error', {
484
+ $event,
485
+ files: file
486
+ });
477
487
  }
478
488
  }
479
489
  }
@@ -533,6 +543,11 @@
533
543
  abortFileUpload($file) {
534
544
  this.datasource.execute(i1.DataSource.Operation.CANCEL, $file);
535
545
  }
546
+ isMimeType(file) {
547
+ return (this.defaultAllowedExtensions.includes('image/*') && i1.isImageFile(file))
548
+ || (this.defaultAllowedExtensions.includes('audio/*') && i1.isAudioFile(file))
549
+ || (this.defaultAllowedExtensions.includes('video/*') && i1.isVideoFile(file));
550
+ }
536
551
  /* Define the property change handler. This function will be triggered when there is a change in the widget property */
537
552
  onPropertyChange(key, nv, ov) {
538
553
  /*Monitoring changes for styles or properties and accordingly handling respective changes.*/
@@ -542,7 +557,15 @@
542
557
  this.changeServerUploadPath(nv);
543
558
  break;
544
559
  case 'contenttype':
545
- this.chooseFilter = nv.split(' ').join(',');
560
+ if (this.defaultAllowedExtensions.includes('*/*')) {
561
+ this.chooseFilter = nv.split(' ').join(',');
562
+ }
563
+ else {
564
+ this.chooseFilter = nv.split(' ').filter(item => this.defaultAllowedExtensions.includes(item) || this.isMimeType(item)).join(',');
565
+ if (lodashEs.isEmpty(this.chooseFilter)) {
566
+ this.chooseFilter = this.defaultAllowedExtensions;
567
+ }
568
+ }
546
569
  break;
547
570
  case 'multiple':
548
571
  this.formName = this.name + (this.multiple ? '-multiple-fileupload' : '-single-fileupload');
@@ -558,6 +581,7 @@
558
581
  this.app = app;
559
582
  this.onSelectEvt = onSelectEvt;
560
583
  this.selectedFiles = [];
584
+ this.multipleSelectedFiles = [];
561
585
  this.selectedFolders = [];
562
586
  this.fileTransfers = {};
563
587
  this.caption = 'Upload';
@@ -579,7 +603,9 @@
579
603
  file: undefined,
580
604
  uploadPath: undefined
581
605
  };
582
- this.chooseFilter = '';
606
+ this.allowedFileUploadExtensions = i1.getWmProjectProperties().allowedFileUploadExtensions;
607
+ this.defaultAllowedExtensions = this.allowedFileUploadExtensions.split(',').map(item => item.trim()).map(item => item.endsWith('/*') ? item : `.${item}`);
608
+ this.chooseFilter = this.defaultAllowedExtensions.includes('*/*') ? '' : this.defaultAllowedExtensions;
583
609
  this.fileUploadMessage = 'Drop your files here or click here to browse';
584
610
  this.uploadedFiles = {
585
611
  fileName: '',
@@ -631,7 +657,7 @@
631
657
  type: i0.Component,
632
658
  args: [{ selector: '[wmFileUpload]', providers: [
633
659
  i3.provideAsWidgetRef(FileUploadComponent)
634
- ], template: "<div class=\"app-fileupload\" init-widget>\n <!-- drag and drop files UI in web -->\n <div class=\"app-multi-file-upload\" *ngIf=\"!_isMobileType && multiple\">\n <div id=\"dropzone\" class=\"drop-box\" (click)=\"triggerFileSelect()\" [ngClass]=\"{'highlight-drop-box' : highlightDropArea}\" (dragover)=\"dragOverHandler($event);\" (drop)=\"onFileDrop($event);\">\n <i class=\"{{iconclass}}\"></i>\n <div class=\"message\">\n <label [innerHtml]=\"caption\" class=\"caption\"></label>\n <form class=\"form-horizontal\" name=\"{{formName}}\">\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" multiple >\n <a href=\"javascript:void(0);\" class=\"app-anchor\">{{fileUploadMessage}}</a>\n </form>\n </div>\n </div>\n </div>\n <!-- single file upload in web and single , multiple file upload UI in mobile runmode -->\n <div class=\"app-single-file-upload\" *ngIf=\"!_isCordova && (!multiple || _isMobileType)\">\n <div class=\"app-button-wrapper\">\n <form class=\"form-horizontal\" name=\"{{formName}}\">\n <!-- support for file upload in Mobileapp in its runmode (Web) -->\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" multiple>\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"!multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" >\n <button id=\"dropzone\" focus-target class=\"app-button btn btn-default\" [ngClass]=\"{'highlight-drop-box' : highlightDropArea}\">\n <i class=\"{{iconclass}}\" aria-hidden=\"true\"></i>\n <span class=\"caption\" [innerHTML]=\"caption\"></span>\n </button>\n </form>\n </div>\n <div class=\"app-files-upload-status single\"></div>\n </div>\n <!-- support for file upload in Mobile Application (device) -->\n <button *ngIf=\"_isCordova\" focus-target class=\"app-button btn btn-default\" (click)=\"openFileSelector()\" [disabled]=\"disabled\">\n <i class=\"{{iconclass}}\"></i>\n <span class=\"caption\" [innerHTML]=\"caption\"></span>\n </button>\n <!-- list of selectedfiles UI -->\n <ul class=\"list-group file-upload\" [ngStyle]=\"{height: filelistheight, overflow: overflow}\" *ngIf=\"selectedFiles.length > 0\" >\n <div *ngFor=\"let ft of selectedFiles\">\n <li class=\"list-group-item file-upload-status\" *ngIf=\"ft.status !== 'abort'\">\n <div class=\"media upload-file-list\">\n <div class=\"media-left media-middle file-icon {{getFileExtension(ft.name) | fileIconClass}}\" title=\"{{getFileExtension(ft.name)}}\"></div>\n <div class=\"media-body media-middle file-details\">\n <p class=\"uploaddetails\">\n <label class=\"upload-title\">{{ft.name}}</label><br/>\n <span class=\"filesize\" *ngIf=\"ft.fileLength !== 0\">{{ft.size | filesize:0}}</span>\n </p>\n <div class=\"progress\" *ngIf=\"ft.status === 'onProgress'\">\n <div class=\"progress-bar progress-bar-striped progress-bar-info\" [ngStyle]=\"{width: (ft.progress +'%')}\"></div>\n </div>\n </div>\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'onProgress' || ft.status === 'queued'\">\n <a class=\"btn btn-transparent file-upload-stop\" type=\"button\" (click)=\"abortFileUpload(ft)\">\n <i class=\"wi wi-close\"></i>\n </a>\n </div>\n\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'success'\">\n <span class=\"status-icon {{ft.status | stateClass }}\"></span>\n </div>\n <div *ngIf=\"cleariconclass !== '' && ft.status !== 'onProgress'\" class=\"media-right media-middle\">\n <a (click)=\"clear(ft)\" class=\"btn btn-transparent btn-default status-icon\" title=\"{{cleariconhint}}\" type=\"button\">\n <i class=\"{{cleariconclass}}\"></i>\n </a>\n </div>\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'error'\" title=\"{{ft.errMsg || this.appLocale.MESSAGE_FILE_UPLOAD_FAILED}}\">\n <span class=\"status-icon {{ft.status | stateClass }}\"></span>\n </div>\n </div>\n </li>\n </div>\n </ul>\n <!-- list of selectedfolders UI to show the error in title -->\n <ul class=\"list-group file-upload\" [ngStyle]=\"{height: filelistheight, overflow: overflow}\" title=\"{{this.appLocale.MESSAGE_FOLDER_UPLOADS_NOT_ALLOWED}}\" *ngIf=\"selectedFolders.length > 0\" >\n <li *ngFor=\"let ft of selectedFolders\" class=\"list-group-item file-upload-status\">\n <div class=\"media upload-file-list\">\n <div class=\"media-left media-middle file-icon fa fa-folder-o\"></div>\n <div class=\"media-body media-middle file-details\">\n <p class=\"uploaddetails\">\n <label class=\"upload-title\">{{ft.name}}</label><br/>\n </p>\n </div>\n <div class=\"media-right media-middle\" >\n <span class=\"status-icon wi wi-cancel text-danger\"></span>\n </div>\n </div>\n </li>\n </ul>\n</div>\n" }]
660
+ ], template: "<div class=\"app-fileupload\" init-widget>\n <!-- drag and drop files UI in web -->\n <div class=\"app-multi-file-upload\" *ngIf=\"!_isMobileType && multiple\">\n <div id=\"dropzone\" class=\"drop-box\" (click)=\"triggerFileSelect()\" [ngClass]=\"{'highlight-drop-box' : highlightDropArea}\" (dragover)=\"dragOverHandler($event);\" (drop)=\"onFileDrop($event);\">\n <i class=\"{{iconclass}}\"></i>\n <div class=\"message\">\n <label [innerHtml]=\"caption\" class=\"caption\"></label>\n <form class=\"form-horizontal\" name=\"{{formName}}\">\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" multiple >\n <a href=\"javascript:void(0);\" class=\"app-anchor\">{{fileUploadMessage}}</a>\n </form>\n </div>\n </div>\n </div>\n <!-- single file upload in web and single , multiple file upload UI in mobile runmode -->\n <div class=\"app-single-file-upload\" *ngIf=\"!_isCordova && (!multiple || _isMobileType)\">\n <div class=\"app-button-wrapper\">\n <form class=\"form-horizontal\" name=\"{{formName}}\">\n <!-- support for file upload in Mobileapp in its runmode (Web) -->\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" multiple>\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"!multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" >\n <button id=\"dropzone\" focus-target class=\"app-button btn btn-default\" [ngClass]=\"{'highlight-drop-box' : highlightDropArea}\">\n <i class=\"{{iconclass}}\" aria-hidden=\"true\"></i>\n <span class=\"caption\" [innerHTML]=\"caption\"></span>\n </button>\n </form>\n </div>\n <div class=\"app-files-upload-status single\"></div>\n </div>\n <!-- support for file upload in Mobile Application (device) -->\n <button *ngIf=\"_isCordova\" focus-target class=\"app-button btn btn-default\" (click)=\"openFileSelector()\" [disabled]=\"disabled\">\n <i class=\"{{iconclass}}\"></i>\n <span class=\"caption\" [innerHTML]=\"caption\"></span>\n </button>\n <!-- list of selectedfiles UI -->\n <ul class=\"list-group file-upload\" [ngStyle]=\"{height: filelistheight, overflow: overflow}\" *ngIf=\"selectedFiles.length > 0\" >\n <div *ngFor=\"let ft of (multiple ? multipleSelectedFiles : selectedFiles)\">\n <li class=\"list-group-item file-upload-status\" *ngIf=\"ft.status !== 'abort'\">\n <div class=\"media upload-file-list\">\n <div class=\"media-left media-middle file-icon {{getFileExtension(ft.name) | fileIconClass}}\" title=\"{{getFileExtension(ft.name)}}\"></div>\n <div class=\"media-body media-middle file-details\">\n <p class=\"uploaddetails\">\n <label class=\"upload-title\">{{ft.name}}</label><br/>\n <span class=\"filesize\" *ngIf=\"ft.fileLength !== 0\">{{ft.size | filesize:0}}</span>\n </p>\n <div class=\"progress\" *ngIf=\"ft.status === 'onProgress'\">\n <div class=\"progress-bar progress-bar-striped progress-bar-info\" [ngStyle]=\"{width: (ft.progress +'%')}\"></div>\n </div>\n </div>\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'onProgress' || ft.status === 'queued'\">\n <a class=\"btn btn-transparent file-upload-stop\" type=\"button\" (click)=\"abortFileUpload(ft)\">\n <i class=\"wi wi-close\"></i>\n </a>\n </div>\n\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'success'\">\n <span class=\"status-icon {{ft.status | stateClass }}\"></span>\n </div>\n <div *ngIf=\"cleariconclass !== '' && ft.status !== 'onProgress'\" class=\"media-right media-middle\">\n <a (click)=\"clear(ft)\" class=\"btn btn-transparent btn-default status-icon\" title=\"{{cleariconhint}}\" type=\"button\">\n <i class=\"{{cleariconclass}}\"></i>\n </a>\n </div>\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'error'\" title=\"{{ft.errMsg || this.appLocale.MESSAGE_FILE_UPLOAD_FAILED}}\">\n <span class=\"status-icon {{ft.status | stateClass }}\"></span>\n </div>\n </div>\n </li>\n </div>\n </ul>\n <!-- list of selectedfolders UI to show the error in title -->\n <ul class=\"list-group file-upload\" [ngStyle]=\"{height: filelistheight, overflow: overflow}\" title=\"{{this.appLocale.MESSAGE_FOLDER_UPLOADS_NOT_ALLOWED}}\" *ngIf=\"selectedFolders.length > 0\" >\n <li *ngFor=\"let ft of selectedFolders\" class=\"list-group-item file-upload-status\">\n <div class=\"media upload-file-list\">\n <div class=\"media-left media-middle file-icon fa fa-folder-o\"></div>\n <div class=\"media-body media-middle file-details\">\n <p class=\"uploaddetails\">\n <label class=\"upload-title\">{{ft.name}}</label><br/>\n </p>\n </div>\n <div class=\"media-right media-middle\" >\n <span class=\"status-icon wi wi-cancel text-danger\"></span>\n </div>\n </div>\n </li>\n </ul>\n</div>\n" }]
635
661
  }], () => [{ type: i0__namespace.Injector }, { type: i1__namespace.App }, { type: undefined, decorators: [{
636
662
  type: i0.Attribute,
637
663
  args: ['select.event']
@@ -1,6 +1,6 @@
1
- import { Attribute, Component, Injector, Optional, Inject } from '@angular/core';
1
+ import { Attribute, Component, Inject, Injector, Optional } from '@angular/core';
2
2
  import { Subject } from 'rxjs';
3
- import { App, DataSource, isAudioFile, isImageFile, isVideoFile } from '@wm/core';
3
+ import { App, DataSource, getWmProjectProperties, isAudioFile, isImageFile, isVideoFile } from '@wm/core';
4
4
  import { provideAsWidgetRef, StylableComponent, styler } from '@wm/components/base';
5
5
  import { registerProps } from './file-upload.props';
6
6
  import { forEach, includes, isEmpty, toLower } from "lodash-es";
@@ -219,7 +219,7 @@ function FileUploadComponent_ul_4_Template(rf, ctx) { if (rf & 1) {
219
219
  const ctx_r1 = i0.ɵɵnextContext();
220
220
  i0.ɵɵproperty("ngStyle", i0.ɵɵpureFunction2(2, _c2, ctx_r1.filelistheight, ctx_r1.overflow));
221
221
  i0.ɵɵadvance();
222
- i0.ɵɵproperty("ngForOf", ctx_r1.selectedFiles);
222
+ i0.ɵɵproperty("ngForOf", ctx_r1.multiple ? ctx_r1.multipleSelectedFiles : ctx_r1.selectedFiles);
223
223
  } }
224
224
  function FileUploadComponent_ul_5_li_1_Template(rf, ctx) { if (rf & 1) {
225
225
  i0.ɵɵelementStart(0, "li", 26)(1, "div", 27);
@@ -356,6 +356,7 @@ export class FileUploadComponent extends StylableComponent {
356
356
  * @param $files
357
357
  */
358
358
  onSelectEventCall($event, $files) {
359
+ this.multipleSelectedFiles = this.multiple ? [...this.multipleSelectedFiles, ...$files] : $files;
359
360
  this.selectedFiles = $files;
360
361
  setTimeout(() => {
361
362
  this.invokeEventCallback('select', {
@@ -378,7 +379,12 @@ export class FileUploadComponent extends StylableComponent {
378
379
  }
379
380
  /*this function to clear the specified file. if argument is not provided, it clears the complete list */
380
381
  clear(fileObj) {
381
- this.selectedFiles = (fileObj) ? this.selectedFiles.filter((file) => file !== fileObj) : [];
382
+ if (this.multiple) {
383
+ this.multipleSelectedFiles = (fileObj) ? this.multipleSelectedFiles.filter((file) => file !== fileObj) : [];
384
+ }
385
+ else {
386
+ this.selectedFiles = (fileObj) ? this.selectedFiles.filter((file) => file !== fileObj) : [];
387
+ }
382
388
  }
383
389
  /*this function to set the class names for clear icon */
384
390
  setClearIconClass(classValue) {
@@ -425,6 +431,10 @@ export class FileUploadComponent extends StylableComponent {
425
431
  file.status = progressObj.status;
426
432
  if (progressObj.errMsg) {
427
433
  file.errMsg = progressObj.errMsg;
434
+ this.invokeEventCallback('error', {
435
+ $event,
436
+ files: file
437
+ });
428
438
  }
429
439
  }
430
440
  }
@@ -484,6 +494,11 @@ export class FileUploadComponent extends StylableComponent {
484
494
  abortFileUpload($file) {
485
495
  this.datasource.execute(DataSource.Operation.CANCEL, $file);
486
496
  }
497
+ isMimeType(file) {
498
+ return (this.defaultAllowedExtensions.includes('image/*') && isImageFile(file))
499
+ || (this.defaultAllowedExtensions.includes('audio/*') && isAudioFile(file))
500
+ || (this.defaultAllowedExtensions.includes('video/*') && isVideoFile(file));
501
+ }
487
502
  /* Define the property change handler. This function will be triggered when there is a change in the widget property */
488
503
  onPropertyChange(key, nv, ov) {
489
504
  /*Monitoring changes for styles or properties and accordingly handling respective changes.*/
@@ -493,7 +508,15 @@ export class FileUploadComponent extends StylableComponent {
493
508
  this.changeServerUploadPath(nv);
494
509
  break;
495
510
  case 'contenttype':
496
- this.chooseFilter = nv.split(' ').join(',');
511
+ if (this.defaultAllowedExtensions.includes('*/*')) {
512
+ this.chooseFilter = nv.split(' ').join(',');
513
+ }
514
+ else {
515
+ this.chooseFilter = nv.split(' ').filter(item => this.defaultAllowedExtensions.includes(item) || this.isMimeType(item)).join(',');
516
+ if (isEmpty(this.chooseFilter)) {
517
+ this.chooseFilter = this.defaultAllowedExtensions;
518
+ }
519
+ }
497
520
  break;
498
521
  case 'multiple':
499
522
  this.formName = this.name + (this.multiple ? '-multiple-fileupload' : '-single-fileupload');
@@ -509,6 +532,7 @@ export class FileUploadComponent extends StylableComponent {
509
532
  this.app = app;
510
533
  this.onSelectEvt = onSelectEvt;
511
534
  this.selectedFiles = [];
535
+ this.multipleSelectedFiles = [];
512
536
  this.selectedFolders = [];
513
537
  this.fileTransfers = {};
514
538
  this.caption = 'Upload';
@@ -530,7 +554,9 @@ export class FileUploadComponent extends StylableComponent {
530
554
  file: undefined,
531
555
  uploadPath: undefined
532
556
  };
533
- this.chooseFilter = '';
557
+ this.allowedFileUploadExtensions = getWmProjectProperties().allowedFileUploadExtensions;
558
+ this.defaultAllowedExtensions = this.allowedFileUploadExtensions.split(',').map(item => item.trim()).map(item => item.endsWith('/*') ? item : `.${item}`);
559
+ this.chooseFilter = this.defaultAllowedExtensions.includes('*/*') ? '' : this.defaultAllowedExtensions;
534
560
  this.fileUploadMessage = 'Drop your files here or click here to browse';
535
561
  this.uploadedFiles = {
536
562
  fileName: '',
@@ -582,7 +608,7 @@ export class FileUploadComponent extends StylableComponent {
582
608
  type: Component,
583
609
  args: [{ selector: '[wmFileUpload]', providers: [
584
610
  provideAsWidgetRef(FileUploadComponent)
585
- ], template: "<div class=\"app-fileupload\" init-widget>\n <!-- drag and drop files UI in web -->\n <div class=\"app-multi-file-upload\" *ngIf=\"!_isMobileType && multiple\">\n <div id=\"dropzone\" class=\"drop-box\" (click)=\"triggerFileSelect()\" [ngClass]=\"{'highlight-drop-box' : highlightDropArea}\" (dragover)=\"dragOverHandler($event);\" (drop)=\"onFileDrop($event);\">\n <i class=\"{{iconclass}}\"></i>\n <div class=\"message\">\n <label [innerHtml]=\"caption\" class=\"caption\"></label>\n <form class=\"form-horizontal\" name=\"{{formName}}\">\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" multiple >\n <a href=\"javascript:void(0);\" class=\"app-anchor\">{{fileUploadMessage}}</a>\n </form>\n </div>\n </div>\n </div>\n <!-- single file upload in web and single , multiple file upload UI in mobile runmode -->\n <div class=\"app-single-file-upload\" *ngIf=\"!_isCordova && (!multiple || _isMobileType)\">\n <div class=\"app-button-wrapper\">\n <form class=\"form-horizontal\" name=\"{{formName}}\">\n <!-- support for file upload in Mobileapp in its runmode (Web) -->\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" multiple>\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"!multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" >\n <button id=\"dropzone\" focus-target class=\"app-button btn btn-default\" [ngClass]=\"{'highlight-drop-box' : highlightDropArea}\">\n <i class=\"{{iconclass}}\" aria-hidden=\"true\"></i>\n <span class=\"caption\" [innerHTML]=\"caption\"></span>\n </button>\n </form>\n </div>\n <div class=\"app-files-upload-status single\"></div>\n </div>\n <!-- support for file upload in Mobile Application (device) -->\n <button *ngIf=\"_isCordova\" focus-target class=\"app-button btn btn-default\" (click)=\"openFileSelector()\" [disabled]=\"disabled\">\n <i class=\"{{iconclass}}\"></i>\n <span class=\"caption\" [innerHTML]=\"caption\"></span>\n </button>\n <!-- list of selectedfiles UI -->\n <ul class=\"list-group file-upload\" [ngStyle]=\"{height: filelistheight, overflow: overflow}\" *ngIf=\"selectedFiles.length > 0\" >\n <div *ngFor=\"let ft of selectedFiles\">\n <li class=\"list-group-item file-upload-status\" *ngIf=\"ft.status !== 'abort'\">\n <div class=\"media upload-file-list\">\n <div class=\"media-left media-middle file-icon {{getFileExtension(ft.name) | fileIconClass}}\" title=\"{{getFileExtension(ft.name)}}\"></div>\n <div class=\"media-body media-middle file-details\">\n <p class=\"uploaddetails\">\n <label class=\"upload-title\">{{ft.name}}</label><br/>\n <span class=\"filesize\" *ngIf=\"ft.fileLength !== 0\">{{ft.size | filesize:0}}</span>\n </p>\n <div class=\"progress\" *ngIf=\"ft.status === 'onProgress'\">\n <div class=\"progress-bar progress-bar-striped progress-bar-info\" [ngStyle]=\"{width: (ft.progress +'%')}\"></div>\n </div>\n </div>\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'onProgress' || ft.status === 'queued'\">\n <a class=\"btn btn-transparent file-upload-stop\" type=\"button\" (click)=\"abortFileUpload(ft)\">\n <i class=\"wi wi-close\"></i>\n </a>\n </div>\n\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'success'\">\n <span class=\"status-icon {{ft.status | stateClass }}\"></span>\n </div>\n <div *ngIf=\"cleariconclass !== '' && ft.status !== 'onProgress'\" class=\"media-right media-middle\">\n <a (click)=\"clear(ft)\" class=\"btn btn-transparent btn-default status-icon\" title=\"{{cleariconhint}}\" type=\"button\">\n <i class=\"{{cleariconclass}}\"></i>\n </a>\n </div>\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'error'\" title=\"{{ft.errMsg || this.appLocale.MESSAGE_FILE_UPLOAD_FAILED}}\">\n <span class=\"status-icon {{ft.status | stateClass }}\"></span>\n </div>\n </div>\n </li>\n </div>\n </ul>\n <!-- list of selectedfolders UI to show the error in title -->\n <ul class=\"list-group file-upload\" [ngStyle]=\"{height: filelistheight, overflow: overflow}\" title=\"{{this.appLocale.MESSAGE_FOLDER_UPLOADS_NOT_ALLOWED}}\" *ngIf=\"selectedFolders.length > 0\" >\n <li *ngFor=\"let ft of selectedFolders\" class=\"list-group-item file-upload-status\">\n <div class=\"media upload-file-list\">\n <div class=\"media-left media-middle file-icon fa fa-folder-o\"></div>\n <div class=\"media-body media-middle file-details\">\n <p class=\"uploaddetails\">\n <label class=\"upload-title\">{{ft.name}}</label><br/>\n </p>\n </div>\n <div class=\"media-right media-middle\" >\n <span class=\"status-icon wi wi-cancel text-danger\"></span>\n </div>\n </div>\n </li>\n </ul>\n</div>\n" }]
611
+ ], template: "<div class=\"app-fileupload\" init-widget>\n <!-- drag and drop files UI in web -->\n <div class=\"app-multi-file-upload\" *ngIf=\"!_isMobileType && multiple\">\n <div id=\"dropzone\" class=\"drop-box\" (click)=\"triggerFileSelect()\" [ngClass]=\"{'highlight-drop-box' : highlightDropArea}\" (dragover)=\"dragOverHandler($event);\" (drop)=\"onFileDrop($event);\">\n <i class=\"{{iconclass}}\"></i>\n <div class=\"message\">\n <label [innerHtml]=\"caption\" class=\"caption\"></label>\n <form class=\"form-horizontal\" name=\"{{formName}}\">\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" multiple >\n <a href=\"javascript:void(0);\" class=\"app-anchor\">{{fileUploadMessage}}</a>\n </form>\n </div>\n </div>\n </div>\n <!-- single file upload in web and single , multiple file upload UI in mobile runmode -->\n <div class=\"app-single-file-upload\" *ngIf=\"!_isCordova && (!multiple || _isMobileType)\">\n <div class=\"app-button-wrapper\">\n <form class=\"form-horizontal\" name=\"{{formName}}\">\n <!-- support for file upload in Mobileapp in its runmode (Web) -->\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" multiple>\n <input class=\"file-input\" [attr.aria-label]=\"hint || 'File selection field'\" type=\"file\" name=\"files\" *ngIf=\"!multiple\" [disabled]=\"disabled\" [accept]=\"chooseFilter\" (click)=\"onFileElemClick($event)\" (change)=\"onFileSelect($event, $event.target.files)\" >\n <button id=\"dropzone\" focus-target class=\"app-button btn btn-default\" [ngClass]=\"{'highlight-drop-box' : highlightDropArea}\">\n <i class=\"{{iconclass}}\" aria-hidden=\"true\"></i>\n <span class=\"caption\" [innerHTML]=\"caption\"></span>\n </button>\n </form>\n </div>\n <div class=\"app-files-upload-status single\"></div>\n </div>\n <!-- support for file upload in Mobile Application (device) -->\n <button *ngIf=\"_isCordova\" focus-target class=\"app-button btn btn-default\" (click)=\"openFileSelector()\" [disabled]=\"disabled\">\n <i class=\"{{iconclass}}\"></i>\n <span class=\"caption\" [innerHTML]=\"caption\"></span>\n </button>\n <!-- list of selectedfiles UI -->\n <ul class=\"list-group file-upload\" [ngStyle]=\"{height: filelistheight, overflow: overflow}\" *ngIf=\"selectedFiles.length > 0\" >\n <div *ngFor=\"let ft of (multiple ? multipleSelectedFiles : selectedFiles)\">\n <li class=\"list-group-item file-upload-status\" *ngIf=\"ft.status !== 'abort'\">\n <div class=\"media upload-file-list\">\n <div class=\"media-left media-middle file-icon {{getFileExtension(ft.name) | fileIconClass}}\" title=\"{{getFileExtension(ft.name)}}\"></div>\n <div class=\"media-body media-middle file-details\">\n <p class=\"uploaddetails\">\n <label class=\"upload-title\">{{ft.name}}</label><br/>\n <span class=\"filesize\" *ngIf=\"ft.fileLength !== 0\">{{ft.size | filesize:0}}</span>\n </p>\n <div class=\"progress\" *ngIf=\"ft.status === 'onProgress'\">\n <div class=\"progress-bar progress-bar-striped progress-bar-info\" [ngStyle]=\"{width: (ft.progress +'%')}\"></div>\n </div>\n </div>\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'onProgress' || ft.status === 'queued'\">\n <a class=\"btn btn-transparent file-upload-stop\" type=\"button\" (click)=\"abortFileUpload(ft)\">\n <i class=\"wi wi-close\"></i>\n </a>\n </div>\n\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'success'\">\n <span class=\"status-icon {{ft.status | stateClass }}\"></span>\n </div>\n <div *ngIf=\"cleariconclass !== '' && ft.status !== 'onProgress'\" class=\"media-right media-middle\">\n <a (click)=\"clear(ft)\" class=\"btn btn-transparent btn-default status-icon\" title=\"{{cleariconhint}}\" type=\"button\">\n <i class=\"{{cleariconclass}}\"></i>\n </a>\n </div>\n <div class=\"media-right media-middle\" *ngIf=\"ft.status === 'error'\" title=\"{{ft.errMsg || this.appLocale.MESSAGE_FILE_UPLOAD_FAILED}}\">\n <span class=\"status-icon {{ft.status | stateClass }}\"></span>\n </div>\n </div>\n </li>\n </div>\n </ul>\n <!-- list of selectedfolders UI to show the error in title -->\n <ul class=\"list-group file-upload\" [ngStyle]=\"{height: filelistheight, overflow: overflow}\" title=\"{{this.appLocale.MESSAGE_FOLDER_UPLOADS_NOT_ALLOWED}}\" *ngIf=\"selectedFolders.length > 0\" >\n <li *ngFor=\"let ft of selectedFolders\" class=\"list-group-item file-upload-status\">\n <div class=\"media upload-file-list\">\n <div class=\"media-left media-middle file-icon fa fa-folder-o\"></div>\n <div class=\"media-body media-middle file-details\">\n <p class=\"uploaddetails\">\n <label class=\"upload-title\">{{ft.name}}</label><br/>\n </p>\n </div>\n <div class=\"media-right media-middle\" >\n <span class=\"status-icon wi wi-cancel text-danger\"></span>\n </div>\n </div>\n </li>\n </ul>\n</div>\n" }]
586
612
  }], () => [{ type: i0.Injector }, { type: i1.App }, { type: undefined, decorators: [{
587
613
  type: Attribute,
588
614
  args: ['select.event']
@@ -593,4 +619,4 @@ export class FileUploadComponent extends StylableComponent {
593
619
  type: Optional
594
620
  }] }], null); })();
595
621
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FileUploadComponent, { className: "FileUploadComponent", filePath: "file-upload.component.ts", lineNumber: 27 }); })();
596
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy93aWRnZXRzL2lucHV0L2ZpbGUtdXBsb2FkL3NyYy9maWxlLXVwbG9hZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3dpZGdldHMvaW5wdXQvZmlsZS11cGxvYWQvc3JjL2ZpbGUtdXBsb2FkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZ0IsU0FBUyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQXFCLFFBQVEsRUFBRSxNQUFNLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFakgsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUvQixPQUFPLEVBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUNoRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFcEYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3BELE9BQU8sRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUMsTUFBTSxXQUFXLENBQUM7Ozs7Ozs7Ozs7O0lDQTFDLGlDQUFzUTtJQUEvRCxBQUFsQyw2TEFBUyw4QkFBdUIsS0FBQyxrTEFBVyxnREFBeUMsS0FBQztJQUEzUCxpQkFBc1E7OztJQUF6SCxBQUF0QiwwQ0FBcUIsK0JBQXdCOzs7OztJQUxoTCxBQURKLDhCQUFzRSxhQUMwSDtJQUE3QixBQUF0QyxBQUFyRiw0S0FBUywwQkFBbUIsS0FBQywyS0FBb0UsOEJBQXVCLEtBQUUsbUtBQVMseUJBQWtCLEtBQUU7SUFDdkwsb0JBQTZCO0lBQzdC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QUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2xELFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hELEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN4QixDQUFDO29GQTdWUSxtQkFBbUIsd0ZBcVU0QixjQUFjLHdCQUE4QixrQkFBa0I7b0VBclU3RyxtQkFBbUIsMEVBTGpCO2dCQUNQLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDO2FBQzFDO1lDdkJMLDhCQUF3QztZQXVFcEMsQUFwQ0EsQUFMQSxBQWZBLEFBYkEscUVBQXNFLHdEQWFrQiw2REFlc0MscURBS0EscURBb0NnRTtZQWVsTSxpQkFBTTs7WUFwRmtDLGNBQWdDO1lBQWhDLHlEQUFnQztZQWEvQixjQUFpRDtZQUFqRCw4RUFBaUQ7WUFlN0UsY0FBZ0I7WUFBaEIscUNBQWdCO1lBS29FLGNBQThCO1lBQTlCLG1EQUE4QjtZQW9DZ0MsY0FBZ0M7WUFBaEMscURBQWdDOzs7aUZEN0NsTCxtQkFBbUI7Y0FSL0IsU0FBUzsyQkFDSSxnQkFBZ0IsYUFFZjtvQkFDUCxrQkFBa0IscUJBQXFCO2lCQUMxQzs7c0JBd1U2QyxTQUFTO3VCQUFDLGNBQWM7O3NCQUF1QixNQUFNO3VCQUFDLGtCQUFrQjs7c0JBQUcsUUFBUTs7a0ZBclV4SCxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FmdGVyVmlld0luaXQsIEF0dHJpYnV0ZSwgQ29tcG9uZW50LCBJbmplY3RvciwgT25Jbml0LCBPbkRlc3Ryb3ksIE9wdGlvbmFsLCBJbmplY3R9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7QXBwLCBEYXRhU291cmNlLCBpc0F1ZGlvRmlsZSwgaXNJbWFnZUZpbGUsIGlzVmlkZW9GaWxlfSBmcm9tICdAd20vY29yZSc7XG5pbXBvcnQgeyBwcm92aWRlQXNXaWRnZXRSZWYsIFN0eWxhYmxlQ29tcG9uZW50LCBzdHlsZXIgfSBmcm9tICdAd20vY29tcG9uZW50cy9iYXNlJztcblxuaW1wb3J0IHsgcmVnaXN0ZXJQcm9wcyB9IGZyb20gJy4vZmlsZS11cGxvYWQucHJvcHMnO1xuaW1wb3J0IHtmb3JFYWNoLCBpbmNsdWRlcywgaXNFbXB0eSwgdG9Mb3dlcn0gZnJvbSBcImxvZGFzaC1lc1wiO1xuXG5kZWNsYXJlIGNvbnN0ICQ7XG5cbmNvbnN0IERFRkFVTFRfQ0xTID0gJ2FwcC1maWxldXBsb2FkJztcbmNvbnN0IFdJREdFVF9DT05GSUcgPSB7XG4gICAgd2lkZ2V0VHlwZTogJ3dtLWZpbGV1cGxvYWQnLFxuICAgIGhvc3RDbGFzczogREVGQVVMVF9DTFNcbn07XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnW3dtRmlsZVVwbG9hZF0nLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9maWxlLXVwbG9hZC5jb21wb25lbnQuaHRtbCcsXG4gICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIHByb3ZpZGVBc1dpZGdldFJlZihGaWxlVXBsb2FkQ29tcG9uZW50KVxuICAgIF1cbn0pXG5cbmV4cG9ydCBjbGFzcyBGaWxlVXBsb2FkQ29tcG9uZW50IGV4dGVuZHMgU3R5bGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gICAgc3RhdGljIGluaXRpYWxpemVQcm9wcyA9IHJlZ2lzdGVyUHJvcHMoKTtcbiAgICBzZWxlY3RlZEZpbGVzOiBhbnkgPSBbXTtcbiAgICBzZWxlY3RlZEZvbGRlcnM6IGFueSA9IFtdO1xuICAgIHByb2dyZXNzT2JzZXJ2YWJsZTtcbiAgICBuYW1lO1xuICAgIGhpbnQ7XG4gICAgbXVsdGlwbGU7XG4gICAgZmlsZVRyYW5zZmVycyA9IHt9O1xuICAgIGNhcHRpb24gPSAnVXBsb2FkJztcbiAgICBmb3JtTmFtZSA9ICcnO1xuICAgIG1heGZpbGVzaXplO1xuICAgIGNsZWFyaWNvbmNsYXNzO1xuICAgIGNsZWFyaWNvbmhpbnQ7XG4gICAgc2VsZWN0ZWRVcGxvYWRUeXBlUGF0aDtcbiAgICBERUZBVUxUX0NBUFRJT05TID0ge1xuICAgICAgICBNVUxUSVBMRV9TRUxFQ1Q6ICdEcm9wIHlvdXIgZmlsZXMgaGVyZS4nLFxuICAgICAgICBTRUxFQ1Q6ICdTZWxlY3QnXG4gICAgfTtcbiAgICBERVZJQ0VfQ09OVEVOVFRZUEVTID0ge1xuICAgICAgICBJTUFHRTogJ2ltYWdlJyxcbiAgICAgICAgVklERU86ICd2aWRlbycsXG4gICAgICAgIEFVRElPOiAnYXVkaW8nLFxuICAgICAgICBGSUxFUzogJ2ZpbGVzJ1xuICAgIH07XG4gICAgRklMRVNJWkVfTUIgPSAxMDQ4NTc2O1xuICAgIHdpZGdldFByb3BzO1xuICAgIF9pc01vYmlsZVR5cGU7XG4gICAgX2lzQ29yZG92YTtcbiAgICAvLyBwYXJlbnRQcmVmYWJTY29wZSA9IGVsZW1lbnQuY2xvc2VzdCgnLmFwcC1wcmVmYWInKS5pc29sYXRlU2NvcGUoKSxcbiAgICBDT05TVEFOVF9GSUxFX1NFUlZJQ0UgPSAnRmlsZVNlcnZpY2UnO1xuICAgIHVwbG9hZERhdGEgPSB7XG4gICAgICAgIGZpbGU6IHVuZGVmaW5lZCxcbiAgICAgICAgdXBsb2FkUGF0aDogdW5kZWZpbmVkXG4gICAgfTtcbiAgICBjaG9vc2VGaWx0ZXIgPSAnJztcbiAgICBkYXRhc291cmNlO1xuICAgIGZpbGVVcGxvYWRNZXNzYWdlID0gJ0Ryb3AgeW91ciBmaWxlcyBoZXJlIG9yIGNsaWNrIGhlcmUgdG8gYnJvd3NlJztcbiAgICB1cGxvYWRlZEZpbGVzID0ge1xuICAgICAgICBmaWxlTmFtZTogJycsXG4gICAgICAgIHBhdGg6ICcnLFxuICAgICAgICBsZW5ndGg6ICcnLFxuICAgICAgICBzdGF0dXM6ICcnXG4gICAgfTtcbiAgICBoaWdobGlnaHREcm9wQXJlYTtcbiAgICAvKl9oYXNPblN1Y2Nlc3NFdnQgPSBXTS5pc0RlZmluZWQoYXR0cnMub25TdWNjZXNzKTtcbiAgICAgX2hhc09uRXJyb3JFdnQgPSBXTS5pc0RlZmluZWQoYXR0cnMub25FcnJvcik7Ki9cblxuICAgIC8vIENoZWNraW5nIGlmIHRoZSBzZWxlY3RlZCBmaWxlIGlzIHZhbGlkIGZvciB0aGUgY2hvb3NlbiBmaWx0ZXIgdHlwZVxuICAgIGlzVmFsaWRGaWxlKGZpbGVuYW1lLCBjb250ZW50dHlwZSwgZXh0ZW5zaW9uTmFtZSwgaXNNb2JpbGVUeXBlKSB7XG4gICAgICAgIGxldCBpc1ZhbGlkLCBjb250ZW50VHlwZXM7XG5cbiAgICAgICAgaWYgKCFjb250ZW50dHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY29udGVudFR5cGVzID0gdG9Mb3dlcihjb250ZW50dHlwZSkuc3BsaXQoJywnKTtcblxuICAgICAgICBpZiAoaW5jbHVkZXMoY29udGVudFR5cGVzLCAnaW1hZ2UvKicpIHx8IChpbmNsdWRlcyhjb250ZW50VHlwZXMsICdpbWFnZScpICYmIGlzTW9iaWxlVHlwZSkpIHtcbiAgICAgICAgICAgIGlzVmFsaWQgPSBpc0ltYWdlRmlsZShmaWxlbmFtZSk7XG4gICAgICAgICAgICAvLyBJZiBvbmUgb2YgdGhlIGNvbnRlbnQgdHlwZSBjaG9zZW4gaXMgaW1hZ2UgYW5kIHVzZXIgdXBsb2FkcyBpbWFnZSBpdCBpcyB2YWxpZCBmaWxlXG4gICAgICAgICAgICBpZiAoaXNWYWxpZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpbmNsdWRlcyhjb250ZW50VHlwZXMsICdhdWRpby8qJykgfHwgKGluY2x1ZGVzKGNvbnRlbnRUeXBlcywgJ2F1ZGlvJykgJiYgaXNNb2JpbGVUeXBlKSkge1xuICAgICAgICAgICAgaXNWYWxpZCA9IGlzQXVkaW9GaWxlKGZpbGVuYW1lKTtcbiAgICAgICAgICAgIC8vIElmIG9uZSBvZiB0aGUgY29udGVudCB0eXBlIGNob3NlbiBpcyBhdWRpby8qIGFuZCB1c2VyIHVwbG9hZHMgYXVkaW8gaXQgaXMgdmFsaWQgZmlsZVxuICAgICAgICAgICAgaWYgKGlzVmFsaWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNWYWxpZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5jbHVkZXMoY29udGVudFR5cGVzLCAndmlkZW8vKicpIHx8IChpbmNsdWRlcyhjb250ZW50VHlwZXMsICd2aWRlbycpICYmIGlzTW9iaWxlVHlwZSkpIHtcbiAgICAgICAgICAgIGlzVmFsaWQgPSBpc1ZpZGVvRmlsZShmaWxlbmFtZSk7XG4gICAgICAgICAgICAvLyBJZiBvbmUgb2YgdGhlIGNvbnRlbnQgdHlwZSBjaG9zZW4gaXMgdmlkZW8vKiBhbmQgdXNlciB1cGxvYWRzIHZpZGVvIGl0IGlzIHZhbGlkIGZpbGVcbiAgICAgICAgICAgIGlmIChpc1ZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLypjb250ZW50IHR5cGUgYW5kIHRoZSB1cGxvYWRlZCBmaWxlIGV4dGVuc2lvbiBzaG91bGQgYmUgc2FtZSovXG4gICAgICAgIGlmIChpbmNsdWRlcyhjb250ZW50VHlwZXMsICcuJyArIHRvTG93ZXIoZXh0ZW5zaW9uTmFtZSkpKSB7XG4gICAgICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNWYWxpZDtcbiAgICB9XG5cbiAgICAvKiB0aGlzIHJldHVybiB0aGUgYXJyYXkgb2YgZmlsZXMgd2hpY2ggYXJlIGhhdmluZyB0aGUgZmlsZSBzaXplIG5vdCBtb3JlIHRoYW4gbWF4ZmlsZXNpemUgYW5kIGZpbHRlcnMgYmFzZWQgb24gY29udGVudHR5cGUgKi9cbiAgICBnZXRWYWxpZEZpbGVzKCRmaWxlcykge1xuICAgICAgICBjb25zdCB2YWxpZEZpbGVzID0gW107XG4gICAgICAgIGNvbnN0IGVycm9yRmlsZXMgPSBbXTtcbiAgICAgICAgY29uc3QgTUFYRklMRVVQTE9BRF9TSVpFID0gcGFyc2VGbG9hdCh0aGlzLm1heGZpbGVzaXplKSAqIHRoaXMuRklMRVNJWkVfTUIgfHwgdGhpcy5GSUxFU0laRV9NQjtcbiAgICAgICAgY29uc3QgTUFYX0ZJTEVfVVBMT0FEX0ZPUk1BVFRFRF9TSVpFID0gKHRoaXMubWF4ZmlsZXNpemUgfHwgJzEnKSArICdNQic7XG5cbiAgICAgICAgLy8gaWYgY29udGVudHR5cGUgaXMgZmlsZXMgZm9yIG1vYmlsZSBwcm9qZWN0cy5cbiAgICAgICAgaWYgKHRoaXMuY2hvb3NlRmlsdGVyID09PSB0aGlzLkRFVklDRV9DT05URU5UVFlQRVMuRklMRVMpIHtcbiAgICAgICAgICAgIHRoaXMuY2hvb3NlRmlsdGVyID0gJyc7XG4gICAgICAgIH1cblxuICAgICAgICBmb3JFYWNoKCRmaWxlcywgKGZpbGUpID0+IHtcbiAgICAgICAgICAgIC8qIGNoZWNrIGZvciB0aGUgZmlsZSBjb250ZW50IHR5cGUgYmVmb3JlIHVwbG9hZGluZyAqL1xuICAgICAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWRGaWxlKGZpbGUubmFtZSwgdGhpcy5jaG9vc2VGaWx0ZXIsIHRoaXMuZ2V0RmlsZUV4dGVuc2lvbihmaWxlLm5hbWUpLCB0aGlzLl9pc01vYmlsZVR5cGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXNnID0gYCR7dGhpcy5hcHBMb2NhbGUuTEFCRUxfRklMRV9FWFRFTlRJT05fVkFMSURBVElPTl9NRVNTQUdFfSAke3RoaXMuY2hvb3NlRmlsdGVyfWA7XG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVFcnJvckZpbGVzKCdJTlZBTElEX0ZJTEVfRVhURU5TSU9OJywgbXNnLCBmaWxlLCBlcnJvckZpbGVzKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZmlsZS5zaXplID4gTUFYRklMRVVQTE9BRF9TSVpFKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXNnID0gYCR7dGhpcy5hcHBMb2NhbGUuTEFCRUxfRklMRV9FWENFRURfVkFMSURBVElPTl9NRVNTQUdFfSAke01BWF9GSUxFX1VQTE9BRF9GT1JNQVRURURfU0laRX1gO1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlRXJyb3JGaWxlcygnSU5WQUxJRF9GSUxFX1NJWkUnLCBtc2csIGZpbGUsIGVycm9yRmlsZXMpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbGlkRmlsZXMucHVzaChmaWxlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWxpZEZpbGVzOiB2YWxpZEZpbGVzLFxuICAgICAgICAgICAgZXJyb3JGaWxlczogZXJyb3JGaWxlc1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGhhbmRsZUVycm9yRmlsZXMoa2V5LCBtc2csIGZpbGUsIGVycm9yRmlsZXMpIHtcbiAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgZXJyb3IgY2FsbGJhY2sgZXhpc3Qgb3Igbm90LiBJZiBpdCBleGlzdHMgdGhlbiBkb250IHNob3cgdGFvc3RlciBtZXNzYWdlXG4gICAgICAgIGlmICghdGhpcy5oYXNFdmVudENhbGxiYWNrKCdlcnJvcicpKSB7XG4gICAgICAgICAgICB0aGlzLmFwcC5ub3RpZnlBcHAobXNnLCAnRXJyb3InKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBlcnJvciA9IHtcbiAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgbWVzc2FnZTogbXNnXG4gICAgICAgIH07XG4gICAgICAgIGZpbGUuZXJyb3IgPSBlcnJvcjtcbiAgICAgICAgZXJyb3JGaWxlcy5wdXNoKGZpbGUpO1xuICAgIH1cblxuICAgIC8qT3ZlcndyaXRlIHRoZSBjYXB0aW9uIG9ubHkgaWYgdGhleSBhcmUgZGVmYXVsdCovXG4gICAgZ2V0Q2FwdGlvbihjYXB0aW9uLCBpc011bHRpcGxlLCBpc01vYmlsZVR5cGUpIHtcbiAgICAgICAgaWYgKGluY2x1ZGVzKHRoaXMuREVGQVVMVF9DQVBUSU9OUywgY2FwdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiBpc011bHRpcGxlICYmICFpc01vYmlsZVR5cGUgPyB0aGlzLkRFRkFVTFRfQ0FQVElPTlMuTVVMVElQTEVfU0VMRUNUIDogdGhpcy5ERUZBVUxUX0NBUFRJT05TLlNFTEVDVDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FwdGlvbjtcbiAgICB9XG5cbiAgICB1cGxvYWRVcmwgPSAnc2VydmljZXMnO1xuXG4gICAgLyogY2hhbmdlIHNlcnZlciBwYXRoIGJhc2VkIG9uIHVzZXIgb3B0aW9uICovXG4gICAgY2hhbmdlU2VydmVyVXBsb2FkUGF0aChwYXRoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRVcGxvYWRUeXBlUGF0aCA9IHBhdGg7XG4gICAgfVxuXG4gICAgLyogdGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBmaWxlZXh0ZW5zaW9uICovXG4gICAgZ2V0RmlsZUV4dGVuc2lvbihmaWxlTmFtZSkge1xuICAgICAgICBpZiAoZmlsZU5hbWUgJiYgaW5jbHVkZXMoZmlsZU5hbWUsICcuJykpIHtcbiAgICAgICAgICAgIHJldHVybiBmaWxlTmFtZS5zdWJzdHJpbmcoZmlsZU5hbWUubGFzdEluZGV4T2YoJy4nKSArIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnZmlsZSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbHMgc2VsZWN0IEV2ZW50XG4gICAgICogQHBhcmFtICRldmVudFxuICAgICAqIEBwYXJhbSAkZmlsZXNcbiAgICAgKi9cbiAgICBvblNlbGVjdEV2ZW50Q2FsbCgkZXZlbnQsICRmaWxlcykge1xuICAgICAgICB0aGlzLnNlbGVjdGVkRmlsZXMgPSAkZmlsZXM7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbnZva2VFdmVudENhbGxiYWNrKCdzZWxlY3QnLCB7XG4gICAgICAgICAgICAgICAgJGV2ZW50OiAkLmV4dGVuZCgkZXZlbnQuJGZpbGVzIHx8IHt9LCAkZmlsZXMpLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkRmlsZXM6ICRmaWxlc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uRmlsZUVsZW1DbGljaygkZXZlbnQpIHtcbiAgICAgICAgdGhpcy5oaWdobGlnaHREcm9wQXJlYSA9IHRydWU7XG5cbiAgICAgICAgLy9UaGUgZmlsZSB1cGxvYWQgd2lkZ2V0IHZhbHVlIHNob3VsZCBiZSBzZXQgdG8gbnVsbCB0byByZXVwbG9hZCB0aGUgc2FtZSBmaWxlLlxuICAgICAgICB0aGlzLiRlbGVtZW50LmZpbmQoJy5maWxlLWlucHV0JylbMF0udmFsdWUgPSBudWxsO1xuICAgICAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgLy8gd2hlbiB0aGUgZmlsZXBpY2tlciBpcyBub3QgdGhlcmUgb24gdGhlIHdpbmRvdywgcmVtb3ZlIHRoZSBkcm9wem9uZSBoaWdobGlnaHRcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgdGhpcy5kaXNhYmxlRHJvcFpvbmUuYmluZCh0aGlzKSk7XG4gICAgfVxuXG4gICAgZGlzYWJsZURyb3Bab25lKCkge1xuICAgICAgICB0aGlzLmhpZ2hsaWdodERyb3BBcmVhID0gZmFsc2U7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1cycsIHRoaXMuZGlzYWJsZURyb3Bab25lKTtcbiAgICB9XG5cbiAgICAvKnRoaXMgZnVuY3Rpb24gdG8gY2xlYXIgdGhlIHNwZWNpZmllZCBmaWxlLiBpZiBhcmd1bWVudCBpcyBub3QgcHJvdmlkZWQsIGl0IGNsZWFycyB0aGUgY29tcGxldGUgbGlzdCAgKi9cbiAgICBjbGVhcihmaWxlT2JqKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRGaWxlcyA9IChmaWxlT2JqKSA/IHRoaXMuc2VsZWN0ZWRGaWxlcy5maWx0ZXIoKGZpbGUpID0+IGZpbGUgIT09IGZpbGVPYmopIDogW107XG4gICAgfVxuXG4gICAgLyp0aGlzIGZ1bmN0aW9uIHRvIHNldCB0aGUgY2xhc3MgbmFtZXMgZm9yIGNsZWFyIGljb24gKi9cbiAgICBzZXRDbGVhckljb25DbGFzcyhjbGFzc1ZhbHVlKSB7XG4gICAgICAgIHRoaXMuY2xlYXJpY29uY2xhc3MgPSBjbGFzc1ZhbHVlO1xuICAgIH1cbiAgICAvKnRoaXMgZnVuY3Rpb24gdG8gc2V0IHRoZSBoaW50IGZvciBjbGVhciBpY29uICovXG4gICAgc2V0Q2xlYXJJY29uSGludChoaW50KSB7XG4gICAgICAgIHRoaXMuY2xlYXJpY29uaGludCA9IGhpbnQ7XG4gICAgfVxuXG5cbiAgICAvKnRoaXMgZnVuY3Rpb24gdG8gYXBwZW5kIHVwbG9hZCBzdGF0dXMgZG9tIGVsZW1lbnRzIHRvIHdpZGdldCAqL1xuICAgIG9uRmlsZVNlbGVjdCgkZXZlbnQsICRmaWxlcykge1xuICAgICAgICBsZXQgYmVmb3JlU2VsZWN0VmFsO1xuICAgICAgICBjb25zdCBmaWxlcyA9IHRoaXMuZ2V0VmFsaWRGaWxlcygkZmlsZXMpO1xuICAgICAgICAkZmlsZXMgPSBmaWxlcy52YWxpZEZpbGVzO1xuXG4gICAgICAgIC8vIElmIHRoZSB1c2VyIGhhcyBwcmV2aW91c2x5IHRyaWVkIHVwbG9hZGluZyBmb2xkZXJzIHVzaW5nIGRyb3AsIGFuZCB0aGVuIHVwbG9hZGluZyB1c2luZyBjbGljayBtZXRob2Qgd2UgY2xlYXIgdGhlIGZvbGRlcnMgZG9tXG4gICAgICAgIGlmICgkZXZlbnQudHlwZSA9PT0gXCJjaGFuZ2VcIikge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEZvbGRlcnMgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyaWdnZXIgZXJyb3IgY2FsbGJhY2sgZXZlbnQgaWYgYW55IGludmFsaWQgZmlsZSBmb3VuZC5cbiAgICAgICAgaWYgKCFpc0VtcHR5KGZpbGVzLmVycm9yRmlsZXMpKSB7XG4gICAgICAgICAgICB0aGlzLmludm9rZUV2ZW50Q2FsbGJhY2soJ2Vycm9yJywge1xuICAgICAgICAgICAgICAgICRldmVudCxcbiAgICAgICAgICAgICAgICBmaWxlczogZmlsZXMuZXJyb3JGaWxlc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNYWtlIGNhbGwgaWYgdGhlcmUgYXJlIHZhbGlkIGZpbGVzIGVsc2Ugbm8gY2FsbCBpcyBtYWRlXG4gICAgICAgIGlmICgkZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnByb2dyZXNzT2JzZXJ2YWJsZSA9IG5ldyBTdWJqZWN0KCk7XG4gICAgICAgICAgICAvLyBFVkVOVDogT05fQkVGT1JFX1NFTEVDVFxuICAgICAgICAgICAgYmVmb3JlU2VsZWN0VmFsID0gdGhpcy5pbnZva2VFdmVudENhbGxiYWNrKCdiZWZvcmVzZWxlY3QnLCB7XG4gICAgICAgICAgICAgICAgJGV2ZW50OiAkLmV4dGVuZCgkZXZlbnQuJGZpbGVzIHx8IHt9LCAkZmlsZXMpLFxuICAgICAgICAgICAgICAgIGZpbGVzOiAkZmlsZXNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGF0YXNvdXJjZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZS5fcHJvZ3Jlc3NPYnNlcnZhYmxlID0gdGhpcy5wcm9ncmVzc09ic2VydmFibGU7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhc291cmNlLl9wcm9ncmVzc09ic2VydmFibGUuYXNPYnNlcnZhYmxlKCkuc3Vic2NyaWJlKChwcm9ncmVzc09iaikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBmb3JFYWNoKHRoaXMuc2VsZWN0ZWRGaWxlcywgKGZpbGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlLm5hbWUgPT09IHByb2dyZXNzT2JqLmZpbGVOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wcm9ncmVzcyA9IHByb2dyZXNzT2JqLnByb2dyZXNzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlLnByb2dyZXNzID09PSAxMDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5zdGF0dXMgPSAnc3VjY2Vzcyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5zdGF0dXMgPSBwcm9ncmVzc09iai5zdGF0dXM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9ncmVzc09iai5lcnJNc2cpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUuZXJyTXNnID0gcHJvZ3Jlc3NPYmouZXJyTXNnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEZpbGVzID0gJGZpbGVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGJlZm9yZVNlbGVjdFZhbCAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAvLyBFVkVOVDogT05fU0VMRUNUXG4gICAgICAgICAgICAgICAgdGhpcy5vblNlbGVjdEV2ZW50Q2FsbCgkZXZlbnQsICRmaWxlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBQcmV2ZW50IGRlZmF1bHQgYmVoYXZpb3IgKFByZXZlbnQgZmlsZSBmcm9tIGJlaW5nIG9wZW5lZClcbiAgICBkcmFnT3ZlckhhbmRsZXIoJGV2ZW50KSB7XG4gICAgICAgICRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuXG4gICAgLy8gR2V0IHRoZSBmaWxlIGRhdGEgaWYgaXQgZXhpc3RzIGFuZCBjYWxsIHRoZSBvbkZpbGVTZWxlY3QgZnVuY3Rpb25cbiAgICBvbkZpbGVEcm9wKCRldmVudCkge1xuICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgbGV0IGxpc3RPZkZpbGVzID0gW107XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRGb2xkZXJzID0gW107XG4gICAgICAgIGNvbnN0IGZpbGVzRGF0YSA9ICRldmVudC5kYXRhVHJhbnNmZXIuaXRlbXM7XG4gICAgICAgIGlmIChmaWxlc0RhdGEubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gVXNlIERhdGFUcmFuc2Zlckl0ZW1MaXN0IGludGVyZmFjZSB0byBhY2Nlc3MgdGhlIGZpbGUocylcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZmlsZXNEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgIC8vIEdldCBhbGwgdGhlIGZpbGVzIGFuZCBwdXNoIHRoZW0gaW50byBhbiBhcnJheVxuICAgICAgICAgICAgICAgIGlmIChmaWxlc0RhdGFbaV0ud2Via2l0R2V0QXNFbnRyeSgpLmlzRmlsZSkge1xuICAgICAgICAgICAgICAgICAgICBsaXN0T2ZGaWxlcy5wdXNoKGZpbGVzRGF0YVtpXS5nZXRBc0ZpbGUoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIElmIGEgc2VsZWN0ZWQgaXRlbSBpcyBkaXJlY3RvcnkgcHVzaCB0aGUgZm9sZGVyIGVsZW1lbnQgaW50byBhbiBhcnJheSBhbmQgZGlzcGxheSBlcnJvciBtZXNzYWdlIGJ5IGFkZGluZyB0byBkb21cbiAgICAgICAgICAgICAgICBlbHNlIGlmKGZpbGVzRGF0YVtpXS53ZWJraXRHZXRBc0VudHJ5KCkuaXNEaXJlY3RvcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEZvbGRlcnMucHVzaChmaWxlc0RhdGFbaV0uZ2V0QXNGaWxlKCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0KCRldmVudCwgbGlzdE9mRmlsZXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZHJhZ092ZXJDYihlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgJCh0aGlzLm5hdGl2ZUVsZW1lbnQpLmZpbmQoJyNkcm9wem9uZScpLmFkZENsYXNzKCdoaWdobGlnaHQtZHJvcC1ib3gnKTtcbiAgICB9XG5cbiAgICBkcm9wQ2IoKSB7XG4gICAgICAgICQodGhpcy5uYXRpdmVFbGVtZW50KS5maW5kKCcjZHJvcHpvbmUnKS5yZW1vdmVDbGFzcygnaGlnaGxpZ2h0LWRyb3AtYm94Jyk7XG4gICAgfVxuXG4gICAgLy8gdGhpcyBmdW5jdGlvbiB0cmlnZ2VycyBmaWxlIHNlbGVjdCB3aW5kb3csIHdoZW4gY2xpY2tlZCBhbnl3aGVyZSBvbiB0aGUgZmlsZSB1cGxvYWQgd2lkZ2V0IGluIGNhc2Ugb2YgbXVsdGkgc2VsZWN0XG4gICAgdHJpZ2dlckZpbGVTZWxlY3QoKSB7XG4gICAgICAgIHRoaXMuJGVsZW1lbnQuZmluZCgnLmZpbGUtaW5wdXQnKS50cmlnZ2VyKCdjbGljaycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFib3J0cyBhIGZpbGUgdXBsb2FkIHJlcXVlc3RcbiAgICAgKiBAcGFyYW0gJGZpbGUsIHRoZSBmaWxlIGZvciB3aGljaCB0aGUgcmVxdWVzdCBpcyB0byBiZSBhYm9ydGVkXG4gICAgICovXG4gICAgYWJvcnRGaWxlVXBsb2FkKCRmaWxlKSB7XG4gICAgICAgIHRoaXMuZGF0YXNvdXJjZS5leGVjdXRlKERhdGFTb3VyY2UuT3BlcmF0aW9uLkNBTkNFTCwgJGZpbGUpO1xuICAgIH1cblxuICAgIC8qIERlZmluZSB0aGUgcHJvcGVydHkgY2hhbmdlIGhhbmRsZXIuIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSB0cmlnZ2VyZWQgd2hlbiB0aGVyZSBpcyBhIGNoYW5nZSBpbiB0aGUgd2lkZ2V0IHByb3BlcnR5ICovXG4gICAgb25Qcm9wZXJ0eUNoYW5nZShrZXksIG52LCBvdikge1xuICAgICAgICAvKk1vbml0b3JpbmcgY2hhbmdlcyBmb3Igc3R5bGVzIG9yIHByb3BlcnRpZXMgYW5kIGFjY29yZGluZ2x5IGhhbmRsaW5nIHJlc3BlY3RpdmUgY2hhbmdlcy4qL1xuICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgY2FzZSAndXBsb2FkcGF0aCc6XG4gICAgICAgICAgICAgICAgLy8gVE9ETyBTcmluaXZhczogd2h5IGRvIHdlIG5lZWQgdXBsb2FkcGF0aFxuICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlU2VydmVyVXBsb2FkUGF0aChudik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdjb250ZW50dHlwZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5jaG9vc2VGaWx0ZXIgPSBudi5zcGxpdCgnICcpLmpvaW4oJywnKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ211bHRpcGxlJzpcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1OYW1lID0gdGhpcy5uYW1lICsgKHRoaXMubXVsdGlwbGUgPyAnLW11bHRpcGxlLWZpbGV1cGxvYWQnIDogJy1zaW5nbGUtZmlsZXVwbG9hZCcpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FwdGlvbiA9IHRoaXMuZ2V0Q2FwdGlvbih0aGlzLmNhcHRpb24sIHRoaXMubXVsdGlwbGUsIHRoaXMuX2lzTW9iaWxlVHlwZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdmaWxldXBsb2FkbWVzc2FnZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5maWxlVXBsb2FkTWVzc2FnZSA9IG52O1xuICAgICAgICB9XG5cbiAgICAgICAgc3VwZXIub25Qcm9wZXJ0eUNoYW5nZShrZXksIG52LCBvdik7XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IoaW5qOiBJbmplY3RvciwgcHJpdmF0ZSBhcHA6IEFwcCwgQEF0dHJpYnV0ZSgnc2VsZWN0LmV2ZW50JykgcHVibGljIG9uU2VsZWN0RXZ0LCBASW5qZWN0KCdFWFBMSUNJVF9DT05URVhUJykgQE9wdGlvbmFsKCkgZXhwbGljaXRDb250ZXh0OiBhbnkpIHtcbiAgICAgICAgc3VwZXIoaW5qLCBXSURHRVRfQ09ORklHLCBleHBsaWNpdENvbnRleHQpO1xuICAgICAgICAvLyBzdHlsZXIodGhpcy5uYXRpdmVFbGVtZW50LCB0aGlzKTtcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgc3VwZXIubmdPbkluaXQoKTtcbiAgICAgICAgLy8gYWRkaW5nLCBkcmFnb3ZlciBhbmQgZHJvcCBvbiB0aGUgZG9jdW1lbnQgYXMgd2hlbiBmaWxlIGlzIGRyYWdnZWQgb24gdG8gdGhlIHBhZ2UgaGlnaGxpZ2h0IHRoZSBkcm9wem9uZXMgYW5kIHJlbW92ZSBoaWdobGlnaHQgb24gZmlsZSBkcm9wXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdvdmVyJywgdGhpcy5kcmFnT3ZlckNiLmJpbmQodGhpcykpO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkcm9wJywgdGhpcy5kcm9wQ2IuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgLy8gYWRkaW5nIG1vdXNlbGVhdmUgZXZudCB0byByZW1vdmUgaGlnaGxpZ2h0IHdoZW4gZmlsZSBpcyBkcm9wcGVkIG91dHNpZGUgdGhlIHdpbmRvd1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgdGhpcy5kcm9wQ2IuYmluZCh0aGlzKSk7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgICAgICBzdHlsZXIoIHRoaXMubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuYXBwLWJ1dHRvbiwgLmRyb3AtYm94JyksIHRoaXMpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdkcmFnb3ZlcicsIHRoaXMuZHJhZ092ZXJDYik7XG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Ryb3AnLCB0aGlzLmRyb3BDYik7XG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCB0aGlzLmRyb3BDYik7XG4gICAgICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImFwcC1maWxldXBsb2FkXCIgaW5pdC13aWRnZXQ+XG4gICAgPCEtLSBkcmFnIGFuZCBkcm9wIGZpbGVzIFVJIGluIHdlYiAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiYXBwLW11bHRpLWZpbGUtdXBsb2FkXCIgKm5nSWY9XCIhX2lzTW9iaWxlVHlwZSAmJiBtdWx0aXBsZVwiPlxuICAgICAgICA8ZGl2IGlkPVwiZHJvcHpvbmVcIiBjbGFzcz1cImRyb3AtYm94XCIgKGNsaWNrKT1cInRyaWdnZXJGaWxlU2VsZWN0KClcIiBbbmdDbGFzc109XCJ7J2hpZ2hsaWdodC1kcm9wLWJveCcgOiBoaWdobGlnaHREcm9wQXJlYX1cIiAoZHJhZ292ZXIpPVwiZHJhZ092ZXJIYW5kbGVyKCRldmVudCk7XCIgKGRyb3ApPVwib25GaWxlRHJvcCgkZXZlbnQpO1wiPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJ7e2ljb25jbGFzc319XCI+PC9pPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2VcIj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgW2lubmVySHRtbF09XCJjYXB0aW9uXCIgY2xhc3M9XCJjYXB0aW9uXCI+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8Zm9ybSBjbGFzcz1cImZvcm0taG9yaXpvbnRhbFwiIG5hbWU9XCJ7e2Zvcm1OYW1lfX1cIj5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZmlsZS1pbnB1dFwiIFthdHRyLmFyaWEtbGFiZWxdPVwiaGludCB8fCAnRmlsZSBzZWxlY3Rpb24gZmllbGQnXCIgdHlwZT1cImZpbGVcIiBuYW1lPVwiZmlsZXNcIiAqbmdJZj1cIm11bHRpcGxlXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkXCIgW2FjY2VwdF09XCJjaG9vc2VGaWx0ZXJcIiAoY2xpY2spPVwib25GaWxlRWxlbUNsaWNrKCRldmVudClcIiAoY2hhbmdlKT1cIm9uRmlsZVNlbGVjdCgkZXZlbnQsICRldmVudC50YXJnZXQuZmlsZXMpXCIgbXVsdGlwbGUgPlxuICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApO1wiIGNsYXNzPVwiYXBwLWFuY2hvclwiPnt7ZmlsZVVwbG9hZE1lc3NhZ2V9fTwvYT5cbiAgICAgICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPCEtLSBzaW5nbGUgZmlsZSB1cGxvYWQgaW4gd2ViIGFuZCBzaW5nbGUgLCBtdWx0aXBsZSBmaWxlIHVwbG9hZCBVSSBpbiBtb2JpbGUgcnVubW9kZSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiYXBwLXNpbmdsZS1maWxlLXVwbG9hZFwiICpuZ0lmPVwiIV9pc0NvcmRvdmEgJiYgKCFtdWx0aXBsZSB8fCBfaXNNb2JpbGVUeXBlKVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYXBwLWJ1dHRvbi13cmFwcGVyXCI+XG4gICAgICAgICAgICA8Zm9ybSBjbGFzcz1cImZvcm0taG9yaXpvbnRhbFwiIG5hbWU9XCJ7e2Zvcm1OYW1lfX1cIj5cbiAgICAgICAgICAgICAgICA8IS0tIHN1cHBvcnQgZm9yIGZpbGUgdXBsb2FkIGluIE1vYmlsZWFwcCBpbiBpdHMgcnVubW9kZSAoV2ViKSAtLT5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmaWxlLWlucHV0XCIgW2F0dHIuYXJpYS1sYWJlbF09XCJoaW50IHx8ICdGaWxlIHNlbGVjdGlvbiBmaWVsZCdcIiB0eXBlPVwiZmlsZVwiIG5hbWU9XCJmaWxlc1wiICpuZ0lmPVwibXVsdGlwbGVcIiBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiBbYWNjZXB0XT1cImNob29zZUZpbHRlclwiIChjbGljayk9XCJvbkZpbGVFbGVtQ2xpY2soJGV2ZW50KVwiIChjaGFuZ2UpPVwib25GaWxlU2VsZWN0KCRldmVudCwgJGV2ZW50LnRhcmdldC5maWxlcylcIiBtdWx0aXBsZT5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmaWxlLWlucHV0XCIgW2F0dHIuYXJpYS1sYWJlbF09XCJoaW50IHx8ICdGaWxlIHNlbGVjdGlvbiBmaWVsZCdcIiB0eXBlPVwiZmlsZVwiIG5hbWU9XCJmaWxlc1wiICpuZ0lmPVwiIW11bHRpcGxlXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkXCIgW2FjY2VwdF09XCJjaG9vc2VGaWx0ZXJcIiAoY2xpY2spPVwib25GaWxlRWxlbUNsaWNrKCRldmVudClcIiAoY2hhbmdlKT1cIm9uRmlsZVNlbGVjdCgkZXZlbnQsICRldmVudC50YXJnZXQuZmlsZXMpXCIgPlxuICAgICAgICAgICAgICAgIDxidXR0b24gaWQ9XCJkcm9wem9uZVwiIGZvY3VzLXRhcmdldCBjbGFzcz1cImFwcC1idXR0b24gYnRuIGJ0bi1kZWZhdWx0XCIgW25nQ2xhc3NdPVwieydoaWdobGlnaHQtZHJvcC1ib3gnIDogaGlnaGxpZ2h0RHJvcEFyZWF9XCI+XG4gICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwie3tpY29uY2xhc3N9fVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjYXB0aW9uXCIgW2lubmVySFRNTF09XCJjYXB0aW9uXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFwcC1maWxlcy11cGxvYWQtc3RhdHVzIHNpbmdsZVwiPjwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDwhLS0gc3VwcG9ydCBmb3IgZmlsZSB1cGxvYWQgaW4gTW9iaWxlIEFwcGxpY2F0aW9uIChkZXZpY2UpIC0tPlxuICAgIDxidXR0b24gKm5nSWY9XCJfaXNDb3Jkb3ZhXCIgZm9jdXMtdGFyZ2V0IGNsYXNzPVwiYXBwLWJ1dHRvbiBidG4gYnRuLWRlZmF1bHRcIiAoY2xpY2spPVwib3BlbkZpbGVTZWxlY3RvcigpXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkXCI+XG4gICAgICAgIDxpIGNsYXNzPVwie3tpY29uY2xhc3N9fVwiPjwvaT5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJjYXB0aW9uXCIgW2lubmVySFRNTF09XCJjYXB0aW9uXCI+PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICAgIDwhLS0gbGlzdCBvZiBzZWxlY3RlZGZpbGVzIFVJIC0tPlxuICAgIDx1bCBjbGFzcz1cImxpc3QtZ3JvdXAgZmlsZS11cGxvYWRcIiBbbmdTdHlsZV09XCJ7aGVpZ2h0OiBmaWxlbGlzdGhlaWdodCwgb3ZlcmZsb3c6IG92ZXJmbG93fVwiICpuZ0lmPVwic2VsZWN0ZWRGaWxlcy5sZW5ndGggPiAwXCIgPlxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBmdCBvZiBzZWxlY3RlZEZpbGVzXCI+XG4gICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gZmlsZS11cGxvYWQtc3RhdHVzXCIgKm5nSWY9XCJmdC5zdGF0dXMgIT09ICdhYm9ydCdcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVkaWEgdXBsb2FkLWZpbGUtbGlzdFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVkaWEtbGVmdCBtZWRpYS1taWRkbGUgZmlsZS1pY29uIHt7Z2V0RmlsZUV4dGVuc2lvbihmdC5uYW1lKSB8IGZpbGVJY29uQ2xhc3N9fVwiIHRpdGxlPVwie3tnZXRGaWxlRXh0ZW5zaW9uKGZ0Lm5hbWUpfX1cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lZGlhLWJvZHkgbWVkaWEtbWlkZGxlIGZpbGUtZGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ1cGxvYWRkZXRhaWxzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidXBsb2FkLXRpdGxlXCI+e3tmdC5uYW1lfX08L2xhYmVsPjxici8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmaWxlc2l6ZVwiICpuZ0lmPVwiZnQuZmlsZUxlbmd0aCAgIT09IDBcIj57e2Z0LnNpemUgfCBmaWxlc2l6ZTowfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3NcIiAqbmdJZj1cImZ0LnN0YXR1cyA9PT0gJ29uUHJvZ3Jlc3MnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInByb2dyZXNzLWJhciBwcm9ncmVzcy1iYXItc3RyaXBlZCBwcm9ncmVzcy1iYXItaW5mb1wiIFtuZ1N0eWxlXT1cInt3aWR0aDogKGZ0LnByb2dyZXNzICsnJScpfVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVkaWEtcmlnaHQgbWVkaWEtbWlkZGxlXCIgKm5nSWY9XCJmdC5zdGF0dXMgPT09ICdvblByb2dyZXNzJyB8fCBmdC5zdGF0dXMgPT09ICdxdWV1ZWQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tdHJhbnNwYXJlbnQgZmlsZS11cGxvYWQtc3RvcFwiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiYWJvcnRGaWxlVXBsb2FkKGZ0KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwid2kgd2ktY2xvc2VcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZWRpYS1yaWdodCBtZWRpYS1taWRkbGVcIiAgKm5nSWY9XCJmdC5zdGF0dXMgPT09ICdzdWNjZXNzJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtaWNvbiB7e2Z0LnN0YXR1cyB8IHN0YXRlQ2xhc3MgfX1cIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY2xlYXJpY29uY2xhc3MgIT09ICcnICYmIGZ0LnN0YXR1cyAhPT0gJ29uUHJvZ3Jlc3MnXCIgY2xhc3M9XCJtZWRpYS1yaWdodCBtZWRpYS1taWRkbGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxhIChjbGljayk9XCJjbGVhcihmdClcIiBjbGFzcz1cImJ0biBidG4tdHJhbnNwYXJlbnQgYnRuLWRlZmF1bHQgc3RhdHVzLWljb25cIiB0aXRsZT1cInt7Y2xlYXJpY29uaGludH19XCIgdHlwZT1cImJ1dHRvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwie3tjbGVhcmljb25jbGFzc319XCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lZGlhLXJpZ2h0IG1lZGlhLW1pZGRsZVwiICAqbmdJZj1cImZ0LnN0YXR1cyA9PT0gJ2Vycm9yJ1wiIHRpdGxlPVwie3tmdC5lcnJNc2cgfHwgdGhpcy5hcHBMb2NhbGUuTUVTU0FHRV9GSUxFX1VQTE9BRF9GQUlMRUR9fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtaWNvbiB7e2Z0LnN0YXR1cyB8IHN0YXRlQ2xhc3MgfX1cIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgPC9kaXY+XG4gICAgPC91bD5cbiAgICA8IS0tIGxpc3Qgb2Ygc2VsZWN0ZWRmb2xkZXJzIFVJIHRvIHNob3cgdGhlIGVycm9yIGluIHRpdGxlIC0tPlxuICAgIDx1bCBjbGFzcz1cImxpc3QtZ3JvdXAgZmlsZS11cGxvYWRcIiBbbmdTdHlsZV09XCJ7aGVpZ2h0OiBmaWxlbGlzdGhlaWdodCwgb3ZlcmZsb3c6IG92ZXJmbG93fVwiIHRpdGxlPVwie3t0aGlzLmFwcExvY2FsZS5NRVNTQUdFX0ZPTERFUl9VUExPQURTX05PVF9BTExPV0VEfX1cIiAqbmdJZj1cInNlbGVjdGVkRm9sZGVycy5sZW5ndGggPiAwXCIgPlxuICAgICAgICA8bGkgKm5nRm9yPVwibGV0IGZ0IG9mIHNlbGVjdGVkRm9sZGVyc1wiIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGZpbGUtdXBsb2FkLXN0YXR1c1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lZGlhIHVwbG9hZC1maWxlLWxpc3RcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVkaWEtbGVmdCBtZWRpYS1taWRkbGUgZmlsZS1pY29uIGZhIGZhLWZvbGRlci1vXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lZGlhLWJvZHkgbWVkaWEtbWlkZGxlIGZpbGUtZGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInVwbG9hZGRldGFpbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInVwbG9hZC10aXRsZVwiPnt7ZnQubmFtZX19PC9sYWJlbD48YnIvPlxuICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lZGlhLXJpZ2h0IG1lZGlhLW1pZGRsZVwiID5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtaWNvbiAgd2kgd2ktY2FuY2VsIHRleHQtZGFuZ2VyXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbGk+XG4gICAgPC91bD5cbjwvZGl2PlxuIl19
622
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy93aWRnZXRzL2lucHV0L2ZpbGUtdXBsb2FkL3NyYy9maWxlLXVwbG9hZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3dpZGdldHMvaW5wdXQvZmlsZS11cGxvYWQvc3JjL2ZpbGUtdXBsb2FkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZ0IsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFxQixRQUFRLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFakgsT0FBTyxFQUFDLE9BQU8sRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUU3QixPQUFPLEVBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSxzQkFBc0IsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUN4RyxPQUFPLEVBQUMsa0JBQWtCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFFbEYsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUMsTUFBTSxXQUFXLENBQUM7Ozs7Ozs7Ozs7O0lDQTFDLGlDQUFzUTtJQUEvRCxBQUFsQyw2TEFBUyw4QkFBdUIsS0FBQyxrTEFBVyxnREFBeUMsS0FBQztJQUEzUCxpQkFBc1E7OztJQUF6SCxBQUF0QiwwQ0FBcUIsK0JBQXdCOzs7OztJQUxoTCxBQURKLDhCQUFzRSxhQUMwSDtJQUE3QixBQUF0QyxBQUFyRiw0S0FBUywwQkFBbUIsS0FBQywyS0FBb0UsOEJBQXVCLEtBQUUsbUtBQVMseUJBQWtCLEtBQUU7SUFDdkws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d0M7WUF1RXBDLEFBcENBLEFBTEEsQUFmQSxBQWJBLHFFQUFzRSx3REFha0IsNkRBZXNDLHFEQUtBLHFEQW9DZ0U7WUFlbE0saUJBQU07O1lBcEZrQyxjQUFnQztZQUFoQyx5REFBZ0M7WUFhL0IsY0FBaUQ7WUFBakQsOEVBQWlEO1lBZTdFLGNBQWdCO1lBQWhCLHFDQUFnQjtZQUtvRSxjQUE4QjtZQUE5QixtREFBOEI7WUFvQ2dDLGNBQWdDO1lBQWhDLHFEQUFnQzs7O2lGRDdDbEwsbUJBQW1CO2NBUi9CLFNBQVM7MkJBQ0ksZ0JBQWdCLGFBRWY7b0JBQ1Asa0JBQWtCLHFCQUFxQjtpQkFDMUM7O3NCQWtXNkMsU0FBUzt1QkFBQyxjQUFjOztzQkFBdUIsTUFBTTt1QkFBQyxrQkFBa0I7O3NCQUFHLFFBQVE7O2tGQS9WeEgsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtBZnRlclZpZXdJbml0LCBBdHRyaWJ1dGUsIENvbXBvbmVudCwgSW5qZWN0LCBJbmplY3RvciwgT25EZXN0cm95LCBPbkluaXQsIE9wdGlvbmFsfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtTdWJqZWN0fSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHtBcHAsIERhdGFTb3VyY2UsIGdldFdtUHJvamVjdFByb3BlcnRpZXMsIGlzQXVkaW9GaWxlLCBpc0ltYWdlRmlsZSwgaXNWaWRlb0ZpbGV9IGZyb20gJ0B3bS9jb3JlJztcbmltcG9ydCB7cHJvdmlkZUFzV2lkZ2V0UmVmLCBTdHlsYWJsZUNvbXBvbmVudCwgc3R5bGVyfSBmcm9tICdAd20vY29tcG9uZW50cy9iYXNlJztcblxuaW1wb3J0IHtyZWdpc3RlclByb3BzfSBmcm9tICcuL2ZpbGUtdXBsb2FkLnByb3BzJztcbmltcG9ydCB7Zm9yRWFjaCwgaW5jbHVkZXMsIGlzRW1wdHksIHRvTG93ZXJ9IGZyb20gXCJsb2Rhc2gtZXNcIjtcblxuZGVjbGFyZSBjb25zdCAkO1xuXG5jb25zdCBERUZBVUxUX0NMUyA9ICdhcHAtZmlsZXVwbG9hZCc7XG5jb25zdCBXSURHRVRfQ09ORklHID0ge1xuICAgIHdpZGdldFR5cGU6ICd3bS1maWxldXBsb2FkJyxcbiAgICBob3N0Q2xhc3M6IERFRkFVTFRfQ0xTXG59O1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ1t3bUZpbGVVcGxvYWRdJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vZmlsZS11cGxvYWQuY29tcG9uZW50Lmh0bWwnLFxuICAgIHByb3ZpZGVyczogW1xuICAgICAgICBwcm92aWRlQXNXaWRnZXRSZWYoRmlsZVVwbG9hZENvbXBvbmVudClcbiAgICBdXG59KVxuXG5leHBvcnQgY2xhc3MgRmlsZVVwbG9hZENvbXBvbmVudCBleHRlbmRzIFN0eWxhYmxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAgIHN0YXRpYyBpbml0aWFsaXplUHJvcHMgPSByZWdpc3RlclByb3BzKCk7XG4gICAgc2VsZWN0ZWRGaWxlczogYW55ID0gW107XG4gICAgbXVsdGlwbGVTZWxlY3RlZEZpbGVzOiBhbnkgPSBbXTtcbiAgICBzZWxlY3RlZEZvbGRlcnM6IGFueSA9IFtdO1xuICAgIHByb2dyZXNzT2JzZXJ2YWJsZTtcbiAgICBuYW1lO1xuICAgIGhpbnQ7XG4gICAgbXVsdGlwbGU7XG4gICAgZmlsZVRyYW5zZmVycyA9IHt9O1xuICAgIGNhcHRpb24gPSAnVXBsb2FkJztcbiAgICBmb3JtTmFtZSA9ICcnO1xuICAgIG1heGZpbGVzaXplO1xuICAgIGNsZWFyaWNvbmNsYXNzO1xuICAgIGNsZWFyaWNvbmhpbnQ7XG4gICAgc2VsZWN0ZWRVcGxvYWRUeXBlUGF0aDtcbiAgICBERUZBVUxUX0NBUFRJT05TID0ge1xuICAgICAgICBNVUxUSVBMRV9TRUxFQ1Q6ICdEcm9wIHlvdXIgZmlsZXMgaGVyZS4nLFxuICAgICAgICBTRUxFQ1Q6ICdTZWxlY3QnXG4gICAgfTtcbiAgICBERVZJQ0VfQ09OVEVOVFRZUEVTID0ge1xuICAgICAgICBJTUFHRTogJ2ltYWdlJyxcbiAgICAgICAgVklERU86ICd2aWRlbycsXG4gICAgICAgIEFVRElPOiAnYXVkaW8nLFxuICAgICAgICBGSUxFUzogJ2ZpbGVzJ1xuICAgIH07XG4gICAgRklMRVNJWkVfTUIgPSAxMDQ4NTc2O1xuICAgIHdpZGdldFByb3BzO1xuICAgIF9pc01vYmlsZVR5cGU7XG4gICAgX2lzQ29yZG92YTtcbiAgICAvLyBwYXJlbnRQcmVmYWJTY29wZSA9IGVsZW1lbnQuY2xvc2VzdCgnLmFwcC1wcmVmYWInKS5pc29sYXRlU2NvcGUoKSxcbiAgICBDT05TVEFOVF9GSUxFX1NFUlZJQ0UgPSAnRmlsZVNlcnZpY2UnO1xuICAgIHVwbG9hZERhdGEgPSB7XG4gICAgICAgIGZpbGU6IHVuZGVmaW5lZCxcbiAgICAgICAgdXBsb2FkUGF0aDogdW5kZWZpbmVkXG4gICAgfTtcbiAgICBhbGxvd2VkRmlsZVVwbG9hZEV4dGVuc2lvbnMgPSBnZXRXbVByb2plY3RQcm9wZXJ0aWVzKCkuYWxsb3dlZEZpbGVVcGxvYWRFeHRlbnNpb25zO1xuICAgIGRlZmF1bHRBbGxvd2VkRXh0ZW5zaW9ucyA9IHRoaXMuYWxsb3dlZEZpbGVVcGxvYWRFeHRlbnNpb25zLnNwbGl0KCcsJykubWFwKGl0ZW0gPT4gaXRlbS50cmltKCkpLm1hcChpdGVtID0+IGl0ZW0uZW5kc1dpdGgoJy8qJykgPyBpdGVtIDogYC4ke2l0ZW19YCk7XG4gICAgY2hvb3NlRmlsdGVyID0gdGhpcy5kZWZhdWx0QWxsb3dlZEV4dGVuc2lvbnMuaW5jbHVkZXMoJyovKicpID8gJycgOiB0aGlzLmRlZmF1bHRBbGxvd2VkRXh0ZW5zaW9ucztcbiAgICBkYXRhc291cmNlO1xuICAgIGZpbGVVcGxvYWRNZXNzYWdlID0gJ0Ryb3AgeW91ciBmaWxlcyBoZXJlIG9yIGNsaWNrIGhlcmUgdG8gYnJvd3NlJztcbiAgICB1cGxvYWRlZEZpbGVzID0ge1xuICAgICAgICBmaWxlTmFtZTogJycsXG4gICAgICAgIHBhdGg6ICcnLFxuICAgICAgICBsZW5ndGg6ICcnLFxuICAgICAgICBzdGF0dXM6ICcnXG4gICAgfTtcbiAgICBoaWdobGlnaHREcm9wQXJlYTtcbiAgICAvKl9oYXNPblN1Y2Nlc3NFdnQgPSBXTS5pc0RlZmluZWQoYXR0cnMub25TdWNjZXNzKTtcbiAgICAgX2hhc09uRXJyb3JFdnQgPSBXTS5pc0RlZmluZWQoYXR0cnMub25FcnJvcik7Ki9cblxuICAgIC8vIENoZWNraW5nIGlmIHRoZSBzZWxlY3RlZCBmaWxlIGlzIHZhbGlkIGZvciB0aGUgY2hvb3NlbiBmaWx0ZXIgdHlwZVxuICAgIGlzVmFsaWRGaWxlKGZpbGVuYW1lLCBjb250ZW50dHlwZSwgZXh0ZW5zaW9uTmFtZSwgaXNNb2JpbGVUeXBlKSB7XG4gICAgICAgIGxldCBpc1ZhbGlkLCBjb250ZW50VHlwZXM7XG5cbiAgICAgICAgaWYgKCFjb250ZW50dHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY29udGVudFR5cGVzID0gdG9Mb3dlcihjb250ZW50dHlwZSkuc3BsaXQoJywnKTtcblxuICAgICAgICBpZiAoaW5jbHVkZXMoY29udGVudFR5cGVzLCAnaW1hZ2UvKicpIHx8IChpbmNsdWRlcyhjb250ZW50VHlwZXMsICdpbWFnZScpICYmIGlzTW9iaWxlVHlwZSkpIHtcbiAgICAgICAgICAgIGlzVmFsaWQgPSBpc0ltYWdlRmlsZShmaWxlbmFtZSk7XG4gICAgICAgICAgICAvLyBJZiBvbmUgb2YgdGhlIGNvbnRlbnQgdHlwZSBjaG9zZW4gaXMgaW1hZ2UgYW5kIHVzZXIgdXBsb2FkcyBpbWFnZSBpdCBpcyB2YWxpZCBmaWxlXG4gICAgICAgICAgICBpZiAoaXNWYWxpZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpbmNsdWRlcyhjb250ZW50VHlwZXMsICdhdWRpby8qJykgfHwgKGluY2x1ZGVzKGNvbnRlbnRUeXBlcywgJ2F1ZGlvJykgJiYgaXNNb2JpbGVUeXBlKSkge1xuICAgICAgICAgICAgaXNWYWxpZCA9IGlzQXVkaW9GaWxlKGZpbGVuYW1lKTtcbiAgICAgICAgICAgIC8vIElmIG9uZSBvZiB0aGUgY29udGVudCB0eXBlIGNob3NlbiBpcyBhdWRpby8qIGFuZCB1c2VyIHVwbG9hZHMgYXVkaW8gaXQgaXMgdmFsaWQgZmlsZVxuICAgICAgICAgICAgaWYgKGlzVmFsaWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNWYWxpZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5jbHVkZXMoY29udGVudFR5cGVzLCAndmlkZW8vKicpIHx8IChpbmNsdWRlcyhjb250ZW50VHlwZXMsICd2aWRlbycpICYmIGlzTW9iaWxlVHlwZSkpIHtcbiAgICAgICAgICAgIGlzVmFsaWQgPSBpc1ZpZGVvRmlsZShmaWxlbmFtZSk7XG4gICAgICAgICAgICAvLyBJZiBvbmUgb2YgdGhlIGNvbnRlbnQgdHlwZSBjaG9zZW4gaXMgdmlkZW8vKiBhbmQgdXNlciB1cGxvYWRzIHZpZGVvIGl0IGlzIHZhbGlkIGZpbGVcbiAgICAgICAgICAgIGlmIChpc1ZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLypjb250ZW50IHR5cGUgYW5kIHRoZSB1cGxvYWRlZCBmaWxlIGV4dGVuc2lvbiBzaG91bGQgYmUgc2FtZSovXG4gICAgICAgIGlmIChpbmNsdWRlcyhjb250ZW50VHlwZXMsICcuJyArIHRvTG93ZXIoZXh0ZW5zaW9uTmFtZSkpKSB7XG4gICAgICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNWYWxpZDtcbiAgICB9XG5cbiAgICAvKiB0aGlzIHJldHVybiB0aGUgYXJyYXkgb2YgZmlsZXMgd2hpY2ggYXJlIGhhdmluZyB0aGUgZmlsZSBzaXplIG5vdCBtb3JlIHRoYW4gbWF4ZmlsZXNpemUgYW5kIGZpbHRlcnMgYmFzZWQgb24gY29udGVudHR5cGUgKi9cbiAgICBnZXRWYWxpZEZpbGVzKCRmaWxlcykge1xuICAgICAgICBjb25zdCB2YWxpZEZpbGVzID0gW107XG4gICAgICAgIGNvbnN0IGVycm9yRmlsZXMgPSBbXTtcbiAgICAgICAgY29uc3QgTUFYRklMRVVQTE9BRF9TSVpFID0gcGFyc2VGbG9hdCh0aGlzLm1heGZpbGVzaXplKSAqIHRoaXMuRklMRVNJWkVfTUIgfHwgdGhpcy5GSUxFU0laRV9NQjtcbiAgICAgICAgY29uc3QgTUFYX0ZJTEVfVVBMT0FEX0ZPUk1BVFRFRF9TSVpFID0gKHRoaXMubWF4ZmlsZXNpemUgfHwgJzEnKSArICdNQic7XG5cbiAgICAgICAgLy8gaWYgY29udGVudHR5cGUgaXMgZmlsZXMgZm9yIG1vYmlsZSBwcm9qZWN0cy5cbiAgICAgICAgaWYgKHRoaXMuY2hvb3NlRmlsdGVyID09PSB0aGlzLkRFVklDRV9DT05URU5UVFlQRVMuRklMRVMpIHtcbiAgICAgICAgICAgIHRoaXMuY2hvb3NlRmlsdGVyID0gJyc7XG4gICAgICAgIH1cblxuICAgICAgICBmb3JFYWNoKCRmaWxlcywgKGZpbGUpID0+IHtcbiAgICAgICAgICAgIC8qIGNoZWNrIGZvciB0aGUgZmlsZSBjb250ZW50IHR5cGUgYmVmb3JlIHVwbG9hZGluZyAqL1xuICAgICAgICAgICAgaWYgKCF0aGlzLmlzVmFsaWRGaWxlKGZpbGUubmFtZSwgdGhpcy5jaG9vc2VGaWx0ZXIsIHRoaXMuZ2V0RmlsZUV4dGVuc2lvbihmaWxlLm5hbWUpLCB0aGlzLl9pc01vYmlsZVR5cGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXNnID0gYCR7dGhpcy5hcHBMb2NhbGUuTEFCRUxfRklMRV9FWFRFTlRJT05fVkFMSURBVElPTl9NRVNTQUdFfSAke3RoaXMuY2hvb3NlRmlsdGVyfWA7XG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVFcnJvckZpbGVzKCdJTlZBTElEX0ZJTEVfRVhURU5TSU9OJywgbXNnLCBmaWxlLCBlcnJvckZpbGVzKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZmlsZS5zaXplID4gTUFYRklMRVVQTE9BRF9TSVpFKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXNnID0gYCR7dGhpcy5hcHBMb2NhbGUuTEFCRUxfRklMRV9FWENFRURfVkFMSURBVElPTl9NRVNTQUdFfSAke01BWF9GSUxFX1VQTE9BRF9GT1JNQVRURURfU0laRX1gO1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlRXJyb3JGaWxlcygnSU5WQUxJRF9GSUxFX1NJWkUnLCBtc2csIGZpbGUsIGVycm9yRmlsZXMpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbGlkRmlsZXMucHVzaChmaWxlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWxpZEZpbGVzOiB2YWxpZEZpbGVzLFxuICAgICAgICAgICAgZXJyb3JGaWxlczogZXJyb3JGaWxlc1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGhhbmRsZUVycm9yRmlsZXMoa2V5LCBtc2csIGZpbGUsIGVycm9yRmlsZXMpIHtcbiAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgZXJyb3IgY2FsbGJhY2sgZXhpc3Qgb3Igbm90LiBJZiBpdCBleGlzdHMgdGhlbiBkb250IHNob3cgdGFvc3RlciBtZXNzYWdlXG4gICAgICAgIGlmICghdGhpcy5oYXNFdmVudENhbGxiYWNrKCdlcnJvcicpKSB7XG4gICAgICAgICAgICB0aGlzLmFwcC5ub3RpZnlBcHAobXNnLCAnRXJyb3InKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBlcnJvciA9IHtcbiAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgbWVzc2FnZTogbXNnXG4gICAgICAgIH07XG4gICAgICAgIGZpbGUuZXJyb3IgPSBlcnJvcjtcbiAgICAgICAgZXJyb3JGaWxlcy5wdXNoKGZpbGUpO1xuICAgIH1cblxuICAgIC8qT3ZlcndyaXRlIHRoZSBjYXB0aW9uIG9ubHkgaWYgdGhleSBhcmUgZGVmYXVsdCovXG4gICAgZ2V0Q2FwdGlvbihjYXB0aW9uLCBpc011bHRpcGxlLCBpc01vYmlsZVR5cGUpIHtcbiAgICAgICAgaWYgKGluY2x1ZGVzKHRoaXMuREVGQVVMVF9DQVBUSU9OUywgY2FwdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiBpc011bHRpcGxlICYmICFpc01vYmlsZVR5cGUgPyB0aGlzLkRFRkFVTFRfQ0FQVElPTlMuTVVMVElQTEVfU0VMRUNUIDogdGhpcy5ERUZBVUxUX0NBUFRJT05TLlNFTEVDVDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FwdGlvbjtcbiAgICB9XG5cbiAgICB1cGxvYWRVcmwgPSAnc2VydmljZXMnO1xuXG4gICAgLyogY2hhbmdlIHNlcnZlciBwYXRoIGJhc2VkIG9uIHVzZXIgb3B0aW9uICovXG4gICAgY2hhbmdlU2VydmVyVXBsb2FkUGF0aChwYXRoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRVcGxvYWRUeXBlUGF0aCA9IHBhdGg7XG4gICAgfVxuXG4gICAgLyogdGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBmaWxlZXh0ZW5zaW9uICovXG4gICAgZ2V0RmlsZUV4dGVuc2lvbihmaWxlTmFtZSkge1xuICAgICAgICBpZiAoZmlsZU5hbWUgJiYgaW5jbHVkZXMoZmlsZU5hbWUsICcuJykpIHtcbiAgICAgICAgICAgIHJldHVybiBmaWxlTmFtZS5zdWJzdHJpbmcoZmlsZU5hbWUubGFzdEluZGV4T2YoJy4nKSArIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnZmlsZSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbHMgc2VsZWN0IEV2ZW50XG4gICAgICogQHBhcmFtICRldmVudFxuICAgICAqIEBwYXJhbSAkZmlsZXNcbiAgICAgKi9cbiAgICBvblNlbGVjdEV2ZW50Q2FsbCgkZXZlbnQsICRmaWxlcykge1xuICAgICAgICB0aGlzLm11bHRpcGxlU2VsZWN0ZWRGaWxlcyA9IHRoaXMubXVsdGlwbGUgPyBbLi4udGhpcy5tdWx0aXBsZVNlbGVjdGVkRmlsZXMsIC4uLiRmaWxlc10gOiAkZmlsZXM7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRGaWxlcyA9ICRmaWxlcztcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmludm9rZUV2ZW50Q2FsbGJhY2soJ3NlbGVjdCcsIHtcbiAgICAgICAgICAgICAgICAkZXZlbnQ6ICQuZXh0ZW5kKCRldmVudC4kZmlsZXMgfHwge30sICRmaWxlcyksXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRGaWxlczogJGZpbGVzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25GaWxlRWxlbUNsaWNrKCRldmVudCkge1xuICAgICAgICB0aGlzLmhpZ2hsaWdodERyb3BBcmVhID0gdHJ1ZTtcblxuICAgICAgICAvL1RoZSBmaWxlIHVwbG9hZCB3aWRnZXQgdmFsdWUgc2hvdWxkIGJlIHNldCB0byBudWxsIHRvIHJldXBsb2FkIHRoZSBzYW1lIGZpbGUuXG4gICAgICAgIHRoaXMuJGVsZW1lbnQuZmluZCgnLmZpbGUtaW5wdXQnKVswXS52YWx1ZSA9IG51bGw7XG4gICAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICAvLyB3aGVuIHRoZSBmaWxlcGlja2VyIGlzIG5vdCB0aGVyZSBvbiB0aGUgd2luZG93LCByZW1vdmUgdGhlIGRyb3B6b25lIGhpZ2hsaWdodFxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCB0aGlzLmRpc2FibGVEcm9wWm9uZS5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICBkaXNhYmxlRHJvcFpvbmUoKSB7XG4gICAgICAgIHRoaXMuaGlnaGxpZ2h0RHJvcEFyZWEgPSBmYWxzZTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgdGhpcy5kaXNhYmxlRHJvcFpvbmUpO1xuICAgIH1cblxuICAgIC8qdGhpcyBmdW5jdGlvbiB0byBjbGVhciB0aGUgc3BlY2lmaWVkIGZpbGUuIGlmIGFyZ3VtZW50IGlzIG5vdCBwcm92aWRlZCwgaXQgY2xlYXJzIHRoZSBjb21wbGV0ZSBsaXN0ICAqL1xuICAgIGNsZWFyKGZpbGVPYmopIHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcbiAgICAgICAgICAgIHRoaXMubXVsdGlwbGVTZWxlY3RlZEZpbGVzID0gKGZpbGVPYmopID8gdGhpcy5tdWx0aXBsZVNlbGVjdGVkRmlsZXMuZmlsdGVyKChmaWxlKSA9PiBmaWxlICE9PSBmaWxlT2JqKSA6IFtdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEZpbGVzID0gKGZpbGVPYmopID8gdGhpcy5zZWxlY3RlZEZpbGVzLmZpbHRlcigoZmlsZSkgPT4gZmlsZSAhPT0gZmlsZU9iaikgOiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qdGhpcyBmdW5jdGlvbiB0byBzZXQgdGhlIGNsYXNzIG5hbWVzIGZvciBjbGVhciBpY29uICovXG4gICAgc2V0Q2xlYXJJY29uQ2xhc3MoY2xhc3NWYWx1ZSkge1xuICAgICAgICB0aGlzLmNsZWFyaWNvbmNsYXNzID0gY2xhc3NWYWx1ZTtcbiAgICB9XG4gICAgLyp0aGlzIGZ1bmN0aW9uIHRvIHNldCB0aGUgaGludCBmb3IgY2xlYXIgaWNvbiAqL1xuICAgIHNldENsZWFySWNvbkhpbnQoaGludCkge1xuICAgICAgICB0aGlzLmNsZWFyaWNvbmhpbnQgPSBoaW50O1xuICAgIH1cblxuXG4gICAgLyp0aGlzIGZ1bmN0aW9uIHRvIGFwcGVuZCB1cGxvYWQgc3RhdHVzIGRvbSBlbGVtZW50cyB0byB3aWRnZXQgKi9cbiAgICBvbkZpbGVTZWxlY3QoJGV2ZW50LCAkZmlsZXMpIHtcbiAgICAgICAgbGV0IGJlZm9yZVNlbGVjdFZhbDtcbiAgICAgICAgY29uc3QgZmlsZXMgPSB0aGlzLmdldFZhbGlkRmlsZXMoJGZpbGVzKTtcbiAgICAgICAgJGZpbGVzID0gZmlsZXMudmFsaWRGaWxlcztcblxuICAgICAgICAvLyBJZiB0aGUgdXNlciBoYXMgcHJldmlvdXNseSB0cmllZCB1cGxvYWRpbmcgZm9sZGVycyB1c2luZyBkcm9wLCBhbmQgdGhlbiB1cGxvYWRpbmcgdXNpbmcgY2xpY2sgbWV0aG9kIHdlIGNsZWFyIHRoZSBmb2xkZXJzIGRvbVxuICAgICAgICBpZiAoJGV2ZW50LnR5cGUgPT09IFwiY2hhbmdlXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGb2xkZXJzID0gW107XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUcmlnZ2VyIGVycm9yIGNhbGxiYWNrIGV2ZW50IGlmIGFueSBpbnZhbGlkIGZpbGUgZm91bmQuXG4gICAgICAgIGlmICghaXNFbXB0eShmaWxlcy5lcnJvckZpbGVzKSkge1xuICAgICAgICAgICAgdGhpcy5pbnZva2VFdmVudENhbGxiYWNrKCdlcnJvcicsIHtcbiAgICAgICAgICAgICAgICAkZXZlbnQsXG4gICAgICAgICAgICAgICAgZmlsZXM6IGZpbGVzLmVycm9yRmlsZXNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTWFrZSBjYWxsIGlmIHRoZXJlIGFyZSB2YWxpZCBmaWxlcyBlbHNlIG5vIGNhbGwgaXMgbWFkZVxuICAgICAgICBpZiAoJGZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5wcm9ncmVzc09ic2VydmFibGUgPSBuZXcgU3ViamVjdCgpO1xuICAgICAgICAgICAgLy8gRVZFTlQ6IE9OX0JFRk9SRV9TRUxFQ1RcbiAgICAgICAgICAgIGJlZm9yZVNlbGVjdFZhbCA9IHRoaXMuaW52b2tlRXZlbnRDYWxsYmFjaygnYmVmb3Jlc2VsZWN0Jywge1xuICAgICAgICAgICAgICAgICRldmVudDogJC5leHRlbmQoJGV2ZW50LiRmaWxlcyB8fCB7fSwgJGZpbGVzKSxcbiAgICAgICAgICAgICAgICBmaWxlczogJGZpbGVzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGFzb3VyY2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGFzb3VyY2UuX3Byb2dyZXNzT2JzZXJ2YWJsZSA9IHRoaXMucHJvZ3Jlc3NPYnNlcnZhYmxlO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YXNvdXJjZS5fcHJvZ3Jlc3NPYnNlcnZhYmxlLmFzT2JzZXJ2YWJsZSgpLnN1YnNjcmliZSgocHJvZ3Jlc3NPYmopID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZm9yRWFjaCh0aGlzLnNlbGVjdGVkRmlsZXMsIChmaWxlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZS5uYW1lID09PSBwcm9ncmVzc09iai5maWxlTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucHJvZ3Jlc3MgPSBwcm9ncmVzc09iai5wcm9ncmVzcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZS5wcm9ncmVzcyA9PT0gMTAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUuc3RhdHVzID0gJ3N1Y2Nlc3MnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUuc3RhdHVzID0gcHJvZ3Jlc3NPYmouc3RhdHVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvZ3Jlc3NPYmouZXJyTXNnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLmVyck1zZyA9IHByb2dyZXNzT2JqLmVyck1zZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlRXZlbnRDYWxsYmFjaygnZXJyb3InLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGV2ZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzOiBmaWxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGaWxlcyA9ICRmaWxlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChiZWZvcmVTZWxlY3RWYWwgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgLy8gRVZFTlQ6IE9OX1NFTEVDVFxuICAgICAgICAgICAgICAgIHRoaXMub25TZWxlY3RFdmVudENhbGwoJGV2ZW50LCAkZmlsZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUHJldmVudCBkZWZhdWx0IGJlaGF2aW9yIChQcmV2ZW50IGZpbGUgZnJvbSBiZWluZyBvcGVuZWQpXG4gICAgZHJhZ092ZXJIYW5kbGVyKCRldmVudCkge1xuICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cblxuICAgIC8vIEdldCB0aGUgZmlsZSBkYXRhIGlmIGl0IGV4aXN0cyBhbmQgY2FsbCB0aGUgb25GaWxlU2VsZWN0IGZ1bmN0aW9uXG4gICAgb25GaWxlRHJvcCgkZXZlbnQpIHtcbiAgICAgICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGxldCBsaXN0T2ZGaWxlcyA9IFtdO1xuICAgICAgICB0aGlzLnNlbGVjdGVkRm9sZGVycyA9IFtdO1xuICAgICAgICBjb25zdCBmaWxlc0RhdGEgPSAkZXZlbnQuZGF0YVRyYW5zZmVyLml0ZW1zO1xuICAgICAgICBpZiAoZmlsZXNEYXRhLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIFVzZSBEYXRhVHJhbnNmZXJJdGVtTGlzdCBpbnRlcmZhY2UgdG8gYWNjZXNzIHRoZSBmaWxlKHMpXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpbGVzRGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAvLyBHZXQgYWxsIHRoZSBmaWxlcyBhbmQgcHVzaCB0aGVtIGludG8gYW4gYXJyYXlcbiAgICAgICAgICAgICAgICBpZiAoZmlsZXNEYXRhW2ldLndlYmtpdEdldEFzRW50cnkoKS5pc0ZpbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdE9mRmlsZXMucHVzaChmaWxlc0RhdGFbaV0uZ2V0QXNGaWxlKCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBJZiBhIHNlbGVjdGVkIGl0ZW0gaXMgZGlyZWN0b3J5IHB1c2ggdGhlIGZvbGRlciBlbGVtZW50IGludG8gYW4gYXJyYXkgYW5kIGRpc3BsYXkgZXJyb3IgbWVzc2FnZSBieSBhZGRpbmcgdG8gZG9tXG4gICAgICAgICAgICAgICAgZWxzZSBpZihmaWxlc0RhdGFbaV0ud2Via2l0R2V0QXNFbnRyeSgpLmlzRGlyZWN0b3J5KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGb2xkZXJzLnB1c2goZmlsZXNEYXRhW2ldLmdldEFzRmlsZSgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLm9uRmlsZVNlbGVjdCgkZXZlbnQsIGxpc3RPZkZpbGVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRyYWdPdmVyQ2IoZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICQodGhpcy5uYXRpdmVFbGVtZW50KS5maW5kKCcjZHJvcHpvbmUnKS5hZGRDbGFzcygnaGlnaGxpZ2h0LWRyb3AtYm94Jyk7XG4gICAgfVxuXG4gICAgZHJvcENiKCkge1xuICAgICAgICAkKHRoaXMubmF0aXZlRWxlbWVudCkuZmluZCgnI2Ryb3B6b25lJykucmVtb3ZlQ2xhc3MoJ2hpZ2hsaWdodC1kcm9wLWJveCcpO1xuICAgIH1cblxuICAgIC8vIHRoaXMgZnVuY3Rpb24gdHJpZ2dlcnMgZmlsZSBzZWxlY3Qgd2luZG93LCB3aGVuIGNsaWNrZWQgYW55d2hlcmUgb24gdGhlIGZpbGUgdXBsb2FkIHdpZGdldCBpbiBjYXNlIG9mIG11bHRpIHNlbGVjdFxuICAgIHRyaWdnZXJGaWxlU2VsZWN0KCkge1xuICAgICAgICB0aGlzLiRlbGVtZW50LmZpbmQoJy5maWxlLWlucHV0JykudHJpZ2dlcignY2xpY2snKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBYm9ydHMgYSBmaWxlIHVwbG9hZCByZXF1ZXN0XG4gICAgICogQHBhcmFtICRmaWxlLCB0aGUgZmlsZSBmb3Igd2hpY2ggdGhlIHJlcXVlc3QgaXMgdG8gYmUgYWJvcnRlZFxuICAgICAqL1xuICAgIGFib3J0RmlsZVVwbG9hZCgkZmlsZSkge1xuICAgICAgICB0aGlzLmRhdGFzb3VyY2UuZXhlY3V0ZShEYXRhU291cmNlLk9wZXJhdGlvbi5DQU5DRUwsICRmaWxlKTtcbiAgICB9XG5cbiAgICBpc01pbWVUeXBlKGZpbGU6IHN0cmluZykge1xuICAgICAgICByZXR1cm4gKHRoaXMuZGVmYXVsdEFsbG93ZWRFeHRlbnNpb25zLmluY2x1ZGVzKCdpbWFnZS8qJykgJiYgaXNJbWFnZUZpbGUoZmlsZSkpXG4gICAgICAgICAgICB8fCAodGhpcy5kZWZhdWx0QWxsb3dlZEV4dGVuc2lvbnMuaW5jbHVkZXMoJ2F1ZGlvLyonKSAmJiBpc0F1ZGlvRmlsZShmaWxlKSlcbiAgICAgICAgICAgIHx8ICh0aGlzLmRlZmF1bHRBbGxvd2VkRXh0ZW5zaW9ucy5pbmNsdWRlcygndmlkZW8vKicpICYmIGlzVmlkZW9GaWxlKGZpbGUpKTtcbiAgICB9XG5cbiAgICAvKiBEZWZpbmUgdGhlIHByb3BlcnR5IGNoYW5nZSBoYW5kbGVyLiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgdHJpZ2dlcmVkIHdoZW4gdGhlcmUgaXMgYSBjaGFuZ2UgaW4gdGhlIHdpZGdldCBwcm9wZXJ0eSAqL1xuICAgIG9uUHJvcGVydHlDaGFuZ2Uoa2V5LCBudiwgb3YpIHtcbiAgICAgICAgLypNb25pdG9yaW5nIGNoYW5nZXMgZm9yIHN0eWxlcyBvciBwcm9wZXJ0aWVzIGFuZCBhY2NvcmRpbmdseSBoYW5kbGluZyByZXNwZWN0aXZlIGNoYW5nZXMuKi9cbiAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgICAgIGNhc2UgJ3VwbG9hZHBhdGgnOlxuICAgICAgICAgICAgICAgIC8vIFRPRE8gU3Jpbml2YXM6IHdoeSBkbyB3ZSBuZWVkIHVwbG9hZHBhdGhcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZVNlcnZlclVwbG9hZFBhdGgobnYpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnY29udGVudHR5cGUnOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlZmF1bHRBbGxvd2VkRXh0ZW5zaW9ucy5pbmNsdWRlcygnKi8qJykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jaG9vc2VGaWx0ZXIgPSBudi5zcGxpdCgnICcpLmpvaW4oJywnKVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hvb3NlRmlsdGVyID0gbnYuc3BsaXQoJyAnKS5maWx0ZXIoaXRlbSA9PiB0aGlzLmRlZmF1bHRBbGxvd2VkRXh0ZW5zaW9ucy5pbmNsdWRlcyhpdGVtKSB8fCB0aGlzLmlzTWltZVR5cGUoaXRlbSkpLmpvaW4oJywnKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHkodGhpcy5jaG9vc2VGaWx0ZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNob29zZUZpbHRlciA9IHRoaXMuZGVmYXVsdEFsbG93ZWRFeHRlbnNpb25zO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtdWx0aXBsZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtTmFtZSA9IHRoaXMubmFtZSArICh0aGlzLm11bHRpcGxlID8gJy1tdWx0aXBsZS1maWxldXBsb2FkJyA6ICctc2luZ2xlLWZpbGV1cGxvYWQnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNhcHRpb24gPSB0aGlzLmdldENhcHRpb24odGhpcy5jYXB0aW9uLCB0aGlzLm11bHRpcGxlLCB0aGlzLl9pc01vYmlsZVR5cGUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZmlsZXVwbG9hZG1lc3NhZ2UnOlxuICAgICAgICAgICAgICAgIHRoaXMuZmlsZVVwbG9hZE1lc3NhZ2UgPSBudjtcbiAgICAgICAgfVxuXG4gICAgICAgIHN1cGVyLm9uUHJvcGVydHlDaGFuZ2Uoa2V5LCBudiwgb3YpO1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKGluajogSW5qZWN0b3IsIHByaXZhdGUgYXBwOiBBcHAsIEBBdHRyaWJ1dGUoJ3NlbGVjdC5ldmVudCcpIHB1YmxpYyBvblNlbGVjdEV2dCwgQEluamVjdCgnRVhQTElDSVRfQ09OVEVYVCcpIEBPcHRpb25hbCgpIGV4cGxpY2l0Q29udGV4dDogYW55KSB7XG4gICAgICAgIHN1cGVyKGluaiwgV0lER0VUX0NPTkZJRywgZXhwbGljaXRDb250ZXh0KTtcbiAgICAgICAgLy8gc3R5bGVyKHRoaXMubmF0aXZlRWxlbWVudCwgdGhpcyk7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHN1cGVyLm5nT25Jbml0KCk7XG4gICAgICAgIC8vIGFkZGluZywgZHJhZ292ZXIgYW5kIGRyb3Agb24gdGhlIGRvY3VtZW50IGFzIHdoZW4gZmlsZSBpcyBkcmFnZ2VkIG9uIHRvIHRoZSBwYWdlIGhpZ2hsaWdodCB0aGUgZHJvcHpvbmVzIGFuZCByZW1vdmUgaGlnaGxpZ2h0IG9uIGZpbGUgZHJvcFxuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkcmFnb3ZlcicsIHRoaXMuZHJhZ092ZXJDYi5iaW5kKHRoaXMpKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignZHJvcCcsIHRoaXMuZHJvcENiLmJpbmQodGhpcykpO1xuXG4gICAgICAgIC8vIGFkZGluZyBtb3VzZWxlYXZlIGV2bnQgdG8gcmVtb3ZlIGhpZ2hsaWdodCB3aGVuIGZpbGUgaXMgZHJvcHBlZCBvdXRzaWRlIHRoZSB3aW5kb3dcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIHRoaXMuZHJvcENiLmJpbmQodGhpcykpO1xuICAgIH1cblxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgc3R5bGVyKCB0aGlzLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmFwcC1idXR0b24sIC5kcm9wLWJveCcpLCB0aGlzKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCB0aGlzLmRyYWdPdmVyQ2IpO1xuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdkcm9wJywgdGhpcy5kcm9wQ2IpO1xuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgdGhpcy5kcm9wQ2IpO1xuICAgICAgICBzdXBlci5uZ09uRGVzdHJveSgpO1xuICAgIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJhcHAtZmlsZXVwbG9hZFwiIGluaXQtd2lkZ2V0PlxuICAgIDwhLS0gZHJhZyBhbmQgZHJvcCBmaWxlcyBVSSBpbiB3ZWIgLS0+XG4gICAgPGRpdiBjbGFzcz1cImFwcC1tdWx0aS1maWxlLXVwbG9hZFwiICpuZ0lmPVwiIV9pc01vYmlsZVR5cGUgJiYgbXVsdGlwbGVcIj5cbiAgICAgICAgPGRpdiBpZD1cImRyb3B6b25lXCIgY2xhc3M9XCJkcm9wLWJveFwiIChjbGljayk9XCJ0cmlnZ2VyRmlsZVNlbGVjdCgpXCIgW25nQ2xhc3NdPVwieydoaWdobGlnaHQtZHJvcC1ib3gnIDogaGlnaGxpZ2h0RHJvcEFyZWF9XCIgKGRyYWdvdmVyKT1cImRyYWdPdmVySGFuZGxlcigkZXZlbnQpO1wiIChkcm9wKT1cIm9uRmlsZURyb3AoJGV2ZW50KTtcIj5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwie3tpY29uY2xhc3N9fVwiPjwvaT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXNzYWdlXCI+XG4gICAgICAgICAgICAgICAgPGxhYmVsIFtpbm5lckh0bWxdPVwiY2FwdGlvblwiIGNsYXNzPVwiY2FwdGlvblwiPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGZvcm0gY2xhc3M9XCJmb3JtLWhvcml6b250YWxcIiBuYW1lPVwie3tmb3JtTmFtZX19XCI+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZpbGUtaW5wdXRcIiBbYXR0ci5hcmlhLWxhYmVsXT1cImhpbnQgfHwgJ0ZpbGUgc2VsZWN0aW9uIGZpZWxkJ1wiIHR5cGU9XCJmaWxlXCIgbmFtZT1cImZpbGVzXCIgKm5nSWY9XCJtdWx0aXBsZVwiIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiIFthY2NlcHRdPVwiY2hvb3NlRmlsdGVyXCIgKGNsaWNrKT1cIm9uRmlsZUVsZW1DbGljaygkZXZlbnQpXCIgKGNoYW5nZSk9XCJvbkZpbGVTZWxlY3QoJGV2ZW50LCAkZXZlbnQudGFyZ2V0LmZpbGVzKVwiIG11bHRpcGxlID5cbiAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKTtcIiBjbGFzcz1cImFwcC1hbmNob3JcIj57e2ZpbGVVcGxvYWRNZXNzYWdlfX08L2E+XG4gICAgICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDwhLS0gc2luZ2xlIGZpbGUgdXBsb2FkIGluIHdlYiBhbmQgc2luZ2xlICwgbXVsdGlwbGUgZmlsZSB1cGxvYWQgVUkgaW4gbW9iaWxlIHJ1bm1vZGUgLS0+XG4gICAgPGRpdiBjbGFzcz1cImFwcC1zaW5nbGUtZmlsZS11cGxvYWRcIiAqbmdJZj1cIiFfaXNDb3Jkb3ZhICYmICghbXVsdGlwbGUgfHwgX2lzTW9iaWxlVHlwZSlcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFwcC1idXR0b24td3JhcHBlclwiPlxuICAgICAgICAgICAgPGZvcm0gY2xhc3M9XCJmb3JtLWhvcml6b250YWxcIiBuYW1lPVwie3tmb3JtTmFtZX19XCI+XG4gICAgICAgICAgICAgICAgPCEtLSBzdXBwb3J0IGZvciBmaWxlIHVwbG9hZCBpbiBNb2JpbGVhcHAgaW4gaXRzIHJ1bm1vZGUgKFdlYikgLS0+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZmlsZS1pbnB1dFwiIFthdHRyLmFyaWEtbGFiZWxdPVwiaGludCB8fCAnRmlsZSBzZWxlY3Rpb24gZmllbGQnXCIgdHlwZT1cImZpbGVcIiBuYW1lPVwiZmlsZXNcIiAqbmdJZj1cIm11bHRpcGxlXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkXCIgW2FjY2VwdF09XCJjaG9vc2VGaWx0ZXJcIiAoY2xpY2spPVwib25GaWxlRWxlbUNsaWNrKCRldmVudClcIiAoY2hhbmdlKT1cIm9uRmlsZVNlbGVjdCgkZXZlbnQsICRldmVudC50YXJnZXQuZmlsZXMpXCIgbXVsdGlwbGU+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZmlsZS1pbnB1dFwiIFthdHRyLmFyaWEtbGFiZWxdPVwiaGludCB8fCAnRmlsZSBzZWxlY3Rpb24gZmllbGQnXCIgdHlwZT1cImZpbGVcIiBuYW1lPVwiZmlsZXNcIiAqbmdJZj1cIiFtdWx0aXBsZVwiIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiIFthY2NlcHRdPVwiY2hvb3NlRmlsdGVyXCIgKGNsaWNrKT1cIm9uRmlsZUVsZW1DbGljaygkZXZlbnQpXCIgKGNoYW5nZSk9XCJvbkZpbGVTZWxlY3QoJGV2ZW50LCAkZXZlbnQudGFyZ2V0LmZpbGVzKVwiID5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGlkPVwiZHJvcHpvbmVcIiBmb2N1cy10YXJnZXQgY2xhc3M9XCJhcHAtYnV0dG9uIGJ0biBidG4tZGVmYXVsdFwiIFtuZ0NsYXNzXT1cInsnaGlnaGxpZ2h0LWRyb3AtYm94JyA6IGhpZ2hsaWdodERyb3BBcmVhfVwiPlxuICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cInt7aWNvbmNsYXNzfX1cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY2FwdGlvblwiIFtpbm5lckhUTUxdPVwiY2FwdGlvblwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJhcHAtZmlsZXMtdXBsb2FkLXN0YXR1cyBzaW5nbGVcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8IS0tIHN1cHBvcnQgZm9yIGZpbGUgdXBsb2FkIGluIE1vYmlsZSBBcHBsaWNhdGlvbiAoZGV2aWNlKSAtLT5cbiAgICA8YnV0dG9uICpuZ0lmPVwiX2lzQ29yZG92YVwiIGZvY3VzLXRhcmdldCBjbGFzcz1cImFwcC1idXR0b24gYnRuIGJ0bi1kZWZhdWx0XCIgKGNsaWNrKT1cIm9wZW5GaWxlU2VsZWN0b3IoKVwiIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiPlxuICAgICAgICA8aSBjbGFzcz1cInt7aWNvbmNsYXNzfX1cIj48L2k+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiY2FwdGlvblwiIFtpbm5lckhUTUxdPVwiY2FwdGlvblwiPjwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbiAgICA8IS0tIGxpc3Qgb2Ygc2VsZWN0ZWRmaWxlcyBVSSAtLT5cbiAgICA8dWwgY2xhc3M9XCJsaXN0LWdyb3VwIGZpbGUtdXBsb2FkXCIgW25nU3R5bGVdPVwie2hlaWdodDogZmlsZWxpc3RoZWlnaHQsIG92ZXJmbG93OiBvdmVyZmxvd31cIiAqbmdJZj1cInNlbGVjdGVkRmlsZXMubGVuZ3RoID4gMFwiID5cbiAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgZnQgb2YgKG11bHRpcGxlID8gbXVsdGlwbGVTZWxlY3RlZEZpbGVzIDogc2VsZWN0ZWRGaWxlcylcIj5cbiAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBmaWxlLXVwbG9hZC1zdGF0dXNcIiAqbmdJZj1cImZ0LnN0YXR1cyAhPT0gJ2Fib3J0J1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZWRpYSB1cGxvYWQtZmlsZS1saXN0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZWRpYS1sZWZ0IG1lZGlhLW1pZGRsZSBmaWxlLWljb24ge3tnZXRGaWxlRXh0ZW5zaW9uKGZ0Lm5hbWUpIHwgZmlsZUljb25DbGFzc319XCIgdGl0bGU9XCJ7e2dldEZpbGVFeHRlbnNpb24oZnQubmFtZSl9fVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVkaWEtYm9keSBtZWRpYS1taWRkbGUgZmlsZS1kZXRhaWxzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInVwbG9hZGRldGFpbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ1cGxvYWQtdGl0bGVcIj57e2Z0Lm5hbWV9fTwvbGFiZWw+PGJyLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZpbGVzaXplXCIgKm5nSWY9XCJmdC5maWxlTGVuZ3RoICAhPT0gMFwiPnt7ZnQuc2l6ZSB8IGZpbGVzaXplOjB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzc1wiICpuZ0lmPVwiZnQuc3RhdHVzID09PSAnb25Qcm9ncmVzcydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtYmFyIHByb2dyZXNzLWJhci1zdHJpcGVkIHByb2dyZXNzLWJhci1pbmZvXCIgW25nU3R5bGVdPVwie3dpZHRoOiAoZnQucHJvZ3Jlc3MgKyclJyl9XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZWRpYS1yaWdodCBtZWRpYS1taWRkbGVcIiAqbmdJZj1cImZ0LnN0YXR1cyA9PT0gJ29uUHJvZ3Jlc3MnIHx8IGZ0LnN0YXR1cyA9PT0gJ3F1ZXVlZCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi10cmFuc3BhcmVudCBmaWxlLXVwbG9hZC1zdG9wXCIgdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJhYm9ydEZpbGVVcGxvYWQoZnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJ3aSB3aS1jbG9zZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lZGlhLXJpZ2h0IG1lZGlhLW1pZGRsZVwiICAqbmdJZj1cImZ0LnN0YXR1cyA9PT0gJ3N1Y2Nlc3MnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1pY29uIHt7ZnQuc3RhdHVzIHwgc3RhdGVDbGFzcyB9fVwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJjbGVhcmljb25jbGFzcyAhPT0gJycgJiYgZnQuc3RhdHVzICE9PSAnb25Qcm9ncmVzcydcIiBjbGFzcz1cIm1lZGlhLXJpZ2h0IG1lZGlhLW1pZGRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgKGNsaWNrKT1cImNsZWFyKGZ0KVwiIGNsYXNzPVwiYnRuIGJ0bi10cmFuc3BhcmVudCBidG4tZGVmYXVsdCBzdGF0dXMtaWNvblwiIHRpdGxlPVwie3tjbGVhcmljb25oaW50fX1cIiB0eXBlPVwiYnV0dG9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJ7e2NsZWFyaWNvbmNsYXNzfX1cIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVkaWEtcmlnaHQgbWVkaWEtbWlkZGxlXCIgICpuZ0lmPVwiZnQuc3RhdHVzID09PSAnZXJyb3InXCIgdGl0bGU9XCJ7e2Z0LmVyck1zZyB8fCB0aGlzLmFwcExvY2FsZS5NRVNTQUdFX0ZJTEVfVVBMT0FEX0ZBSUxFRH19XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1pY29uIHt7ZnQuc3RhdHVzIHwgc3RhdGVDbGFzcyB9fVwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L3VsPlxuICAgIDwhLS0gbGlzdCBvZiBzZWxlY3RlZGZvbGRlcnMgVUkgdG8gc2hvdyB0aGUgZXJyb3IgaW4gdGl0bGUgLS0+XG4gICAgPHVsIGNsYXNzPVwibGlzdC1ncm91cCBmaWxlLXVwbG9hZFwiIFtuZ1N0eWxlXT1cIntoZWlnaHQ6IGZpbGVsaXN0aGVpZ2h0LCBvdmVyZmxvdzogb3ZlcmZsb3d9XCIgdGl0bGU9XCJ7e3RoaXMuYXBwTG9jYWxlLk1FU1NBR0VfRk9MREVSX1VQTE9BRFNfTk9UX0FMTE9XRUR9fVwiICpuZ0lmPVwic2VsZWN0ZWRGb2xkZXJzLmxlbmd0aCA+IDBcIiA+XG4gICAgICAgIDxsaSAqbmdGb3I9XCJsZXQgZnQgb2Ygc2VsZWN0ZWRGb2xkZXJzXCIgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gZmlsZS11cGxvYWQtc3RhdHVzXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVkaWEgdXBsb2FkLWZpbGUtbGlzdFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZWRpYS1sZWZ0IG1lZGlhLW1pZGRsZSBmaWxlLWljb24gZmEgZmEtZm9sZGVyLW9cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVkaWEtYm9keSBtZWRpYS1taWRkbGUgZmlsZS1kZXRhaWxzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidXBsb2FkZGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidXBsb2FkLXRpdGxlXCI+e3tmdC5uYW1lfX08L2xhYmVsPjxici8+XG4gICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVkaWEtcmlnaHQgbWVkaWEtbWlkZGxlXCIgPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1pY29uICB3aSB3aS1jYW5jZWwgdGV4dC1kYW5nZXJcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9saT5cbiAgICA8L3VsPlxuPC9kaXY+XG4iXX0=