ngx-material-entity 15.3.1 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/classes/entity.model.d.ts +2 -2
- package/components/confirm-dialog/confirm-dialog-data.d.ts +1 -1
- package/components/edit-page/edit-page.component.d.ts +1 -1
- package/components/edit-page/page-edit-data.builder.d.ts +1 -1
- package/components/input/array/array-string-chips-input/array-string-chips-input.component.d.ts +1 -0
- package/components/input/array/array-table.class.d.ts +1 -1
- package/components/input/base-input.component.d.ts +5 -1
- package/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.d.ts +1 -1
- package/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.d.ts +1 -1
- package/components/input/file/file-input/file-input.component.d.ts +1 -1
- package/components/input/input.component.d.ts +2 -1
- package/components/table/display-column-value/base-display-column-value.component.d.ts +1 -1
- package/components/table/display-column-value/display-column-value.component.d.ts +1 -1
- package/components/table/table-data.builder.d.ts +1 -1
- package/components/table/table-data.d.ts +1 -1
- package/components/table/table.component.d.ts +1 -1
- package/decorators/base/decorator-types.enum.d.ts +1 -1
- package/decorators/base/property-decorator.data.d.ts +1 -1
- package/decorators/file/file-decorator.data.d.ts +1 -1
- package/decorators/number/number-decorator.data.d.ts +1 -1
- package/decorators/string/string-decorator.data.d.ts +1 -1
- package/encapsulation/jszip.utilities.d.ts +1 -1
- package/encapsulation/uuid.utilities.d.ts +11 -0
- package/esm2022/classes/base.builder.mjs +44 -0
- package/esm2022/classes/entity.model.mjs +26 -0
- package/esm2022/components/confirm-dialog/confirm-dialog-data.builder.mjs +58 -0
- package/esm2022/components/confirm-dialog/confirm-dialog.component.mjs +60 -0
- package/esm2022/components/edit-page/edit-page.component.mjs +291 -0
- package/esm2022/components/input/array/array-date-input/array-date-input.component.mjs +23 -0
- package/esm2022/components/input/array/array-date-range-input/array-date-range-input.component.mjs +49 -0
- package/esm2022/components/input/array/array-date-time-input/array-date-time-input.component.mjs +49 -0
- package/esm2022/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.mjs +50 -0
- package/esm2022/components/input/array/array-string-chips-input/array-string-chips-input.component.mjs +69 -0
- package/esm2022/components/input/array/array-table.class.mjs +100 -0
- package/esm2022/components/input/base-input.component.mjs +88 -0
- package/esm2022/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.mjs +21 -0
- package/esm2022/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.mjs +17 -0
- package/esm2022/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.mjs +21 -0
- package/esm2022/components/input/custom/custom.component.mjs +28 -0
- package/esm2022/components/input/date/date-input/date-input.component.mjs +19 -0
- package/esm2022/components/input/date/date-range-input/date-range-input.component.mjs +68 -0
- package/esm2022/components/input/date/date-time-input/date-time-input.component.mjs +69 -0
- package/{esm2020 → esm2022}/components/input/file/file-default-input/file-default-input.component.mjs +4 -4
- package/esm2022/components/input/file/file-image-input/file-image-input.component.mjs +101 -0
- package/esm2022/components/input/file/file-input/dragDrop.directive.mjs +62 -0
- package/esm2022/components/input/file/file-input/file-input.component.mjs +206 -0
- package/esm2022/components/input/input.component.mjs +849 -0
- package/esm2022/components/input/input.module.mjs +172 -0
- package/esm2022/components/input/number/number-dropdown-input/number-dropdown-input.component.mjs +23 -0
- package/esm2022/components/input/number/number-input/number-input.component.mjs +16 -0
- package/esm2022/components/input/number/number-slider-input/number-slider-input.component.mjs +17 -0
- package/esm2022/components/input/relations/references-many-input/references-many-input.component.mjs +102 -0
- package/esm2022/components/input/string/string-autocomplete-input/string-autocomplete-input.component.mjs +36 -0
- package/esm2022/components/input/string/string-dropdown-input/string-dropdown-input.component.mjs +23 -0
- package/esm2022/components/input/string/string-input/string-input.component.mjs +16 -0
- package/esm2022/components/input/string/string-password-input/string-password-input.component.mjs +39 -0
- package/esm2022/components/input/string/string-textbox-input/string-textbox-input.component.mjs +17 -0
- package/esm2022/components/table/create-dialog/create-dialog-data.builder.mjs +42 -0
- package/esm2022/components/table/create-dialog/create-entity-dialog-data.builder.mjs +32 -0
- package/esm2022/components/table/create-dialog/create-entity-dialog.component.mjs +107 -0
- package/esm2022/components/table/display-column-value/base-display-column-value.component.mjs +28 -0
- package/esm2022/components/table/display-column-value/display-column-value.component.mjs +37 -0
- package/esm2022/components/table/edit-dialog/edit-data.builder.mjs +106 -0
- package/esm2022/components/table/edit-dialog/edit-entity-dialog.component.mjs +209 -0
- package/esm2022/components/table/edit-dialog/edit-entity.builder.mjs +39 -0
- package/esm2022/components/table/table-data.builder.mjs +269 -0
- package/esm2022/components/table/table.component.mjs +348 -0
- package/esm2022/decorators/array/array-decorator-internal.data.mjs +286 -0
- package/esm2022/decorators/array/array-decorator.data.mjs +21 -0
- package/esm2022/decorators/base/property-decorator-internal.data.mjs +82 -0
- package/esm2022/decorators/base/property-decorator.data.mjs +56 -0
- package/esm2022/decorators/boolean/boolean-decorator-internal.data.mjs +43 -0
- package/esm2022/decorators/boolean/boolean-decorator.data.mjs +11 -0
- package/esm2022/decorators/custom/custom-decorator-internal.data.mjs +35 -0
- package/{esm2020 → esm2022}/decorators/date/date-decorator-internal.data.mjs +43 -1
- package/esm2022/decorators/date/date-decorator.data.mjs +11 -0
- package/esm2022/decorators/file/file-decorator-internal.data.mjs +143 -0
- package/esm2022/decorators/file/file-decorator.data.mjs +64 -0
- package/esm2022/decorators/has-many/has-many-decorator-internal.data.mjs +42 -0
- package/esm2022/decorators/number/number-decorator-internal.data.mjs +76 -0
- package/esm2022/decorators/number/number-decorator.data.mjs +11 -0
- package/esm2022/decorators/object/object-decorator-internal.data.mjs +20 -0
- package/esm2022/decorators/object/object-decorator.data.mjs +22 -0
- package/esm2022/decorators/references-many/references-many-decorator-internal.data.mjs +48 -0
- package/esm2022/decorators/references-one/references-one-decorator-internal.data.mjs +24 -0
- package/esm2022/decorators/string/string-decorator-internal.data.mjs +114 -0
- package/esm2022/decorators/string/string-decorator.data.mjs +11 -0
- package/esm2022/encapsulation/uuid.utilities.mjs +15 -0
- package/esm2022/services/entity.service.mjs +276 -0
- package/esm2022/utilities/date.utilities.mjs +159 -0
- package/esm2022/utilities/entity.utilities.mjs +905 -0
- package/{fesm2020 → fesm2022}/ngx-material-entity.mjs +1225 -376
- package/fesm2022/ngx-material-entity.mjs.map +1 -0
- package/package.json +11 -17
- package/utilities/date.utilities.d.ts +1 -1
- package/esm2020/classes/base.builder.mjs +0 -42
- package/esm2020/classes/entity.model.mjs +0 -22
- package/esm2020/components/confirm-dialog/confirm-dialog-data.builder.mjs +0 -44
- package/esm2020/components/confirm-dialog/confirm-dialog.component.mjs +0 -57
- package/esm2020/components/edit-page/edit-page.component.mjs +0 -277
- package/esm2020/components/input/array/array-date-input/array-date-input.component.mjs +0 -26
- package/esm2020/components/input/array/array-date-range-input/array-date-range-input.component.mjs +0 -50
- package/esm2020/components/input/array/array-date-time-input/array-date-time-input.component.mjs +0 -49
- package/esm2020/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.mjs +0 -49
- package/esm2020/components/input/array/array-string-chips-input/array-string-chips-input.component.mjs +0 -70
- package/esm2020/components/input/array/array-table.class.mjs +0 -96
- package/esm2020/components/input/base-input.component.mjs +0 -64
- package/esm2020/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.mjs +0 -21
- package/esm2020/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.mjs +0 -17
- package/esm2020/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.mjs +0 -21
- package/esm2020/components/input/custom/custom.component.mjs +0 -26
- package/esm2020/components/input/date/date-input/date-input.component.mjs +0 -22
- package/esm2020/components/input/date/date-range-input/date-range-input.component.mjs +0 -71
- package/esm2020/components/input/date/date-time-input/date-time-input.component.mjs +0 -71
- package/esm2020/components/input/file/file-image-input/file-image-input.component.mjs +0 -100
- package/esm2020/components/input/file/file-input/dragDrop.directive.mjs +0 -63
- package/esm2020/components/input/file/file-input/file-input.component.mjs +0 -198
- package/esm2020/components/input/input.component.mjs +0 -755
- package/esm2020/components/input/input.module.mjs +0 -173
- package/esm2020/components/input/number/number-dropdown-input/number-dropdown-input.component.mjs +0 -26
- package/esm2020/components/input/number/number-input/number-input.component.mjs +0 -16
- package/esm2020/components/input/number/number-slider-input/number-slider-input.component.mjs +0 -17
- package/esm2020/components/input/relations/references-many-input/references-many-input.component.mjs +0 -100
- package/esm2020/components/input/string/string-autocomplete-input/string-autocomplete-input.component.mjs +0 -34
- package/esm2020/components/input/string/string-dropdown-input/string-dropdown-input.component.mjs +0 -26
- package/esm2020/components/input/string/string-input/string-input.component.mjs +0 -16
- package/esm2020/components/input/string/string-password-input/string-password-input.component.mjs +0 -42
- package/esm2020/components/input/string/string-textbox-input/string-textbox-input.component.mjs +0 -17
- package/esm2020/components/table/create-dialog/create-dialog-data.builder.mjs +0 -32
- package/esm2020/components/table/create-dialog/create-entity-dialog-data.builder.mjs +0 -26
- package/esm2020/components/table/create-dialog/create-entity-dialog.component.mjs +0 -100
- package/esm2020/components/table/display-column-value/base-display-column-value.component.mjs +0 -27
- package/esm2020/components/table/display-column-value/display-column-value.component.mjs +0 -33
- package/esm2020/components/table/edit-dialog/edit-data.builder.mjs +0 -76
- package/esm2020/components/table/edit-dialog/edit-entity-dialog.component.mjs +0 -198
- package/esm2020/components/table/edit-dialog/edit-entity.builder.mjs +0 -29
- package/esm2020/components/table/table-data.builder.mjs +0 -205
- package/esm2020/components/table/table.component.mjs +0 -333
- package/esm2020/decorators/array/array-decorator-internal.data.mjs +0 -150
- package/esm2020/decorators/array/array-decorator.data.mjs +0 -7
- package/esm2020/decorators/base/property-decorator-internal.data.mjs +0 -58
- package/esm2020/decorators/base/property-decorator.data.mjs +0 -6
- package/esm2020/decorators/boolean/boolean-decorator-internal.data.mjs +0 -33
- package/esm2020/decorators/boolean/boolean-decorator.data.mjs +0 -7
- package/esm2020/decorators/custom/custom-decorator-internal.data.mjs +0 -27
- package/esm2020/decorators/date/date-decorator.data.mjs +0 -7
- package/esm2020/decorators/file/file-decorator-internal.data.mjs +0 -97
- package/esm2020/decorators/file/file-decorator.data.mjs +0 -7
- package/esm2020/decorators/has-many/has-many-decorator-internal.data.mjs +0 -32
- package/esm2020/decorators/number/number-decorator-internal.data.mjs +0 -54
- package/esm2020/decorators/number/number-decorator.data.mjs +0 -7
- package/esm2020/decorators/object/object-decorator-internal.data.mjs +0 -14
- package/esm2020/decorators/object/object-decorator.data.mjs +0 -7
- package/esm2020/decorators/references-many/references-many-decorator-internal.data.mjs +0 -30
- package/esm2020/decorators/references-one/references-one-decorator-internal.data.mjs +0 -16
- package/esm2020/decorators/string/string-decorator-internal.data.mjs +0 -72
- package/esm2020/decorators/string/string-decorator.data.mjs +0 -7
- package/esm2020/services/entity.service.mjs +0 -274
- package/esm2020/utilities/date.utilities.mjs +0 -159
- package/esm2020/utilities/entity.utilities.mjs +0 -905
- package/fesm2015/ngx-material-entity.mjs +0 -6322
- package/fesm2015/ngx-material-entity.mjs.map +0 -1
- package/fesm2020/ngx-material-entity.mjs.map +0 -1
- /package/{esm2020 → esm2022}/components/confirm-dialog/confirm-dialog-data.mjs +0 -0
- /package/{esm2020 → esm2022}/components/edit-page/edit-data.route.mjs +0 -0
- /package/{esm2020 → esm2022}/components/edit-page/page-edit-data.builder.mjs +0 -0
- /package/{esm2020 → esm2022}/components/get-validation-error-message.function.mjs +0 -0
- /package/{esm2020 → esm2022}/components/table/create-dialog/create-entity-dialog-data.mjs +0 -0
- /package/{esm2020 → esm2022}/components/table/default.actions.mjs +0 -0
- /package/{esm2020 → esm2022}/components/table/edit-dialog/edit-entity-data.mjs +0 -0
- /package/{esm2020 → esm2022}/components/table/table-data.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/array/array.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/base/base-property.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/base/decorator-types.enum.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/base/dropdown-value.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/boolean/boolean.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/custom/custom-decorator.data.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/custom/custom.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/date/date.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/file/file.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/has-many/has-many-decorator.data.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/has-many/has-many.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/number/number.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/object/object.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/references-many/references-many-decorator.data.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/references-many/references-many.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/references-one/references-one-decorator.data.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/references-one/references-one.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/string/string.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/encapsulation/js-2-xml.utilities.mjs +0 -0
- /package/{esm2020 → esm2022}/encapsulation/jszip.utilities.mjs +0 -0
- /package/{esm2020 → esm2022}/encapsulation/lodash.utilities.mjs +0 -0
- /package/{esm2020 → esm2022}/encapsulation/reflect.utilities.mjs +0 -0
- /package/{esm2020 → esm2022}/functions/default-false.function.mjs +0 -0
- /package/{esm2020 → esm2022}/functions/default-true.function.mjs +0 -0
- /package/{esm2020 → esm2022}/functions/is-async-function.function.mjs +0 -0
- /package/{esm2020 → esm2022}/mocks/placeholder-data.png.mjs +0 -0
- /package/{esm2020 → esm2022}/ngx-material-entity.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/services/unsaved-changes.guard.mjs +0 -0
- /package/{esm2020 → esm2022}/utilities/file.utilities.mjs +0 -0
- /package/{esm2020 → esm2022}/utilities/selection.utilities.mjs +0 -0
|
@@ -1,755 +0,0 @@
|
|
|
1
|
-
import { SelectionModel } from '@angular/cdk/collections';
|
|
2
|
-
import { HttpClient } from '@angular/common/http';
|
|
3
|
-
import { Component, EnvironmentInjector, EventEmitter, Inject, Input, Output, TemplateRef, ViewChild, inject } from '@angular/core';
|
|
4
|
-
import { MatDialog } from '@angular/material/dialog';
|
|
5
|
-
import { MatPaginator } from '@angular/material/paginator';
|
|
6
|
-
import { MatSort } from '@angular/material/sort';
|
|
7
|
-
import { MatTableDataSource } from '@angular/material/table';
|
|
8
|
-
import { Router } from '@angular/router';
|
|
9
|
-
import { firstValueFrom } from 'rxjs';
|
|
10
|
-
import { DecoratorTypes } from '../../decorators/base/decorator-types.enum';
|
|
11
|
-
import { LodashUtilities } from '../../encapsulation/lodash.utilities';
|
|
12
|
-
import { ReflectUtilities } from '../../encapsulation/reflect.utilities';
|
|
13
|
-
import { defaultFalse } from '../../functions/default-false.function';
|
|
14
|
-
import { DateUtilities } from '../../utilities/date.utilities';
|
|
15
|
-
import { EntityUtilities } from '../../utilities/entity.utilities';
|
|
16
|
-
import { SelectionUtilities } from '../../utilities/selection.utilities';
|
|
17
|
-
import { ConfirmDialogDataBuilder } from '../confirm-dialog/confirm-dialog-data.builder';
|
|
18
|
-
import { NgxMatEntityConfirmDialogComponent } from '../confirm-dialog/confirm-dialog.component';
|
|
19
|
-
import { NGX_GET_VALIDATION_ERROR_MESSAGE } from '../get-validation-error-message.function';
|
|
20
|
-
import { CreateDialogDataBuilder } from '../table/create-dialog/create-dialog-data.builder';
|
|
21
|
-
import { BaseTableActionInternal } from '../table/table-data.builder';
|
|
22
|
-
import * as i0 from "@angular/core";
|
|
23
|
-
import * as i1 from "@angular/material/dialog";
|
|
24
|
-
import * as i2 from "@angular/router";
|
|
25
|
-
import * as i3 from "@angular/common/http";
|
|
26
|
-
import * as i4 from "@angular/common";
|
|
27
|
-
import * as i5 from "@angular/material/input";
|
|
28
|
-
import * as i6 from "@angular/material/form-field";
|
|
29
|
-
import * as i7 from "@angular/forms";
|
|
30
|
-
import * as i8 from "@angular/material/select";
|
|
31
|
-
import * as i9 from "@angular/material/core";
|
|
32
|
-
import * as i10 from "@angular/material/checkbox";
|
|
33
|
-
import * as i11 from "@angular/material/table";
|
|
34
|
-
import * as i12 from "@angular/material/button";
|
|
35
|
-
import * as i13 from "@angular/material/tabs";
|
|
36
|
-
import * as i14 from "@angular/material/menu";
|
|
37
|
-
import * as i15 from "@angular/material/progress-spinner";
|
|
38
|
-
import * as i16 from "@angular/material/paginator";
|
|
39
|
-
import * as i17 from "../table/display-column-value/display-column-value.component";
|
|
40
|
-
import * as i18 from "./string/string-input/string-input.component";
|
|
41
|
-
import * as i19 from "./string/string-textbox-input/string-textbox-input.component";
|
|
42
|
-
import * as i20 from "./string/string-autocomplete-input/string-autocomplete-input.component";
|
|
43
|
-
import * as i21 from "./string/string-dropdown-input/string-dropdown-input.component";
|
|
44
|
-
import * as i22 from "./string/string-password-input/string-password-input.component";
|
|
45
|
-
import * as i23 from "./boolean/boolean-checkbox-input/boolean-checkbox-input.component";
|
|
46
|
-
import * as i24 from "./boolean/boolean-toggle-input/boolean-toggle-input.component";
|
|
47
|
-
import * as i25 from "./boolean/boolean-dropdown-input/boolean-dropdown-input.component";
|
|
48
|
-
import * as i26 from "./number/number-input/number-input.component";
|
|
49
|
-
import * as i27 from "./number/number-dropdown-input/number-dropdown-input.component";
|
|
50
|
-
import * as i28 from "./number/number-slider-input/number-slider-input.component";
|
|
51
|
-
import * as i29 from "./array/array-string-chips-input/array-string-chips-input.component";
|
|
52
|
-
import * as i30 from "./array/array-string-autocomplete-chips/array-string-autocomplete-chips.component";
|
|
53
|
-
import * as i31 from "./date/date-input/date-input.component";
|
|
54
|
-
import * as i32 from "./date/date-range-input/date-range-input.component";
|
|
55
|
-
import * as i33 from "./date/date-time-input/date-time-input.component";
|
|
56
|
-
import * as i34 from "./array/array-date-input/array-date-input.component";
|
|
57
|
-
import * as i35 from "./array/array-date-time-input/array-date-time-input.component";
|
|
58
|
-
import * as i36 from "./array/array-date-range-input/array-date-range-input.component";
|
|
59
|
-
import * as i37 from "./file/file-image-input/file-image-input.component";
|
|
60
|
-
import * as i38 from "./file/file-default-input/file-default-input.component";
|
|
61
|
-
import * as i39 from "./relations/references-many-input/references-many-input.component";
|
|
62
|
-
import * as i40 from "./custom/custom.component";
|
|
63
|
-
/**
|
|
64
|
-
* The default input component. It gets the metadata of the property from the given @Input "entity" and @Input "propertyKey"
|
|
65
|
-
* and displays the input field accordingly.
|
|
66
|
-
*
|
|
67
|
-
* You can also define a method that generates error-messages and if the input should be hidden when its metadata says
|
|
68
|
-
* that it should be omitted for creating or updating.
|
|
69
|
-
* The last part being mostly relevant if you want to use this component inside an ngFor.
|
|
70
|
-
*/
|
|
71
|
-
export class NgxMatEntityInputComponent {
|
|
72
|
-
constructor(dialog, injector, router, defaultGetValidationErrorMessage, http) {
|
|
73
|
-
this.dialog = dialog;
|
|
74
|
-
this.injector = injector;
|
|
75
|
-
this.router = router;
|
|
76
|
-
this.defaultGetValidationErrorMessage = defaultGetValidationErrorMessage;
|
|
77
|
-
this.http = http;
|
|
78
|
-
this.inputChangeEvent = new EventEmitter();
|
|
79
|
-
this.entityArraySelection = new SelectionModel(true, []);
|
|
80
|
-
this.isArrayItemValid = false;
|
|
81
|
-
this.isArrayItemDirty = false;
|
|
82
|
-
this.hasManyIsLoading = true;
|
|
83
|
-
this.hasManyDataSource = new MatTableDataSource();
|
|
84
|
-
this.hasManySelection = new SelectionModel(true, []);
|
|
85
|
-
this.isHasManyEntityValid = false;
|
|
86
|
-
this.isHasManyEntityDirty = false;
|
|
87
|
-
this.DecoratorTypes = DecoratorTypes;
|
|
88
|
-
this.EntityUtilities = EntityUtilities;
|
|
89
|
-
this.DateUtilities = DateUtilities;
|
|
90
|
-
this.SelectionUtilities = SelectionUtilities;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Checks if the input with the given key on the given property is readonly.
|
|
94
|
-
*
|
|
95
|
-
* @param property - The property on which to check the input.
|
|
96
|
-
* @param key - The key for the input to check.
|
|
97
|
-
* @returns Whether or not the input is readonly.
|
|
98
|
-
*/
|
|
99
|
-
isPropertyReadOnly(property, key) {
|
|
100
|
-
return this.injector.runInContext(() => {
|
|
101
|
-
if (this.internalIsReadOnly || this.metadataDefaultObject?.isReadOnly(property)) {
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
const metadata = EntityUtilities.getPropertyMetadata(property, key);
|
|
105
|
-
return metadata.isReadOnly(property);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* This is needed for the inputs to work inside an ngFor.
|
|
110
|
-
*
|
|
111
|
-
* @param index - The index of the element in the ngFor.
|
|
112
|
-
* @returns The index.
|
|
113
|
-
*/
|
|
114
|
-
trackByFn(index) {
|
|
115
|
-
return index;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Gets the value to display in the column.
|
|
119
|
-
* Runs in environment context to enable injection.
|
|
120
|
-
*
|
|
121
|
-
* @param entity - The entity to get the value from.
|
|
122
|
-
* @param displayColumn - The display column to get the value from.
|
|
123
|
-
* @returns The value of the display column.
|
|
124
|
-
*/
|
|
125
|
-
getDisplayColumnValue(entity, displayColumn) {
|
|
126
|
-
return this.injector.runInContext(() => {
|
|
127
|
-
return displayColumn.value(entity);
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
ngOnInit() {
|
|
131
|
-
if (!this.entity) {
|
|
132
|
-
throw new Error('Missing required Input data "entity"');
|
|
133
|
-
}
|
|
134
|
-
this.internalEntity = this.entity;
|
|
135
|
-
if (this.propertyKey == null) {
|
|
136
|
-
throw new Error('Missing required Input data "propertyKey"');
|
|
137
|
-
}
|
|
138
|
-
this.internalPropertyKey = this.propertyKey;
|
|
139
|
-
this.internalGetValidationErrorMessage = this.getValidationErrorMessage ?? this.defaultGetValidationErrorMessage;
|
|
140
|
-
this.internalIsReadOnly = this.isReadOnly ?? false;
|
|
141
|
-
this.type = EntityUtilities.getPropertyType(this.internalEntity, this.internalPropertyKey);
|
|
142
|
-
if (this.validEmpty === true) {
|
|
143
|
-
// eslint-disable-next-line max-len
|
|
144
|
-
const currentMetadata = ReflectUtilities.getMetadata('metadata', this.internalEntity, this.internalPropertyKey);
|
|
145
|
-
// eslint-disable-next-line max-len
|
|
146
|
-
ReflectUtilities.defineMetadata('metadata', { ...currentMetadata, required: defaultFalse }, this.internalEntity, this.internalPropertyKey);
|
|
147
|
-
}
|
|
148
|
-
this.metadata = EntityUtilities.getPropertyMetadata(this.internalEntity, this.internalPropertyKey, this.type);
|
|
149
|
-
switch (this.type) {
|
|
150
|
-
case DecoratorTypes.OBJECT:
|
|
151
|
-
this.initObjectInput();
|
|
152
|
-
break;
|
|
153
|
-
case DecoratorTypes.ARRAY:
|
|
154
|
-
this.initEntityArray();
|
|
155
|
-
break;
|
|
156
|
-
case DecoratorTypes.HAS_MANY:
|
|
157
|
-
this.initHasMany();
|
|
158
|
-
break;
|
|
159
|
-
case DecoratorTypes.REFERENCES_ONE:
|
|
160
|
-
this.initReferencesOne();
|
|
161
|
-
break;
|
|
162
|
-
default:
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
initReferencesOne() {
|
|
167
|
-
this.metadataReferencesOne = this.metadata;
|
|
168
|
-
void this.injector.runInContext(async () => {
|
|
169
|
-
this.referencesOneAllReferencedEntities = await this.metadataReferencesOne.getReferencedEntities();
|
|
170
|
-
// eslint-disable-next-line max-len
|
|
171
|
-
this.referencesOneDropdownValues = this.metadataReferencesOne.getDropdownValues(LodashUtilities.cloneDeep(this.referencesOneAllReferencedEntities));
|
|
172
|
-
this.setReferencesOneObject();
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
initHasMany() {
|
|
176
|
-
this.metadataHasMany = this.metadata;
|
|
177
|
-
this.hasManyImportAction = new BaseTableActionInternal({
|
|
178
|
-
...this.metadataHasMany.tableData.baseData.importActionData,
|
|
179
|
-
action: () => this.startImportJson()
|
|
180
|
-
});
|
|
181
|
-
this.injector.runInContext(() => {
|
|
182
|
-
this.hasManyAllowCreate = this.metadataHasMany.tableData.baseData.allowCreate();
|
|
183
|
-
this.hasManyEntityService = inject(this.metadataHasMany.tableData.baseData.EntityServiceClass);
|
|
184
|
-
this.hasManyCreateBaseUrl = this.metadataHasMany.createBaseUrl(this.internalEntity, this.metadataHasMany);
|
|
185
|
-
});
|
|
186
|
-
const givenDisplayColumns = this.metadataHasMany.tableData.baseData.displayColumns.map((v) => v.displayName);
|
|
187
|
-
if (this.metadataHasMany.tableData.baseData.tableActions.filter(tA => tA.type === 'multi-select').length) {
|
|
188
|
-
this.displayedHasManyColumns = ['select'].concat(givenDisplayColumns);
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
this.displayedHasManyColumns = givenDisplayColumns;
|
|
192
|
-
}
|
|
193
|
-
this.hasManyDataSource.sortingDataAccessor = (entity, header) => {
|
|
194
|
-
return this.injector.runInContext(() => {
|
|
195
|
-
// eslint-disable-next-line max-len
|
|
196
|
-
return this.metadataHasMany.tableData.baseData.displayColumns.find((dp) => dp.displayName === header)?.value(entity);
|
|
197
|
-
});
|
|
198
|
-
};
|
|
199
|
-
this.hasManyDataSource.sort = this.hasManySort;
|
|
200
|
-
this.hasManyDataSource.filterPredicate = (entity, filter) => {
|
|
201
|
-
const searchStr = this.metadataHasMany.tableData.baseData.searchString(entity);
|
|
202
|
-
const formattedSearchString = searchStr.toLowerCase();
|
|
203
|
-
const formattedFilterString = filter.toLowerCase();
|
|
204
|
-
return formattedSearchString.includes(formattedFilterString);
|
|
205
|
-
};
|
|
206
|
-
this.hasManyDataSource.filter = this.hasManyFilter;
|
|
207
|
-
this.hasManyDataSource.paginator = this.hasManyPaginator;
|
|
208
|
-
this.hasManyEntityService.entitiesSubject.subscribe((entities) => {
|
|
209
|
-
this.hasManyDataSource.data = entities;
|
|
210
|
-
this.hasManySelection.clear();
|
|
211
|
-
});
|
|
212
|
-
this.injector.runInContext(() => {
|
|
213
|
-
const readBaseUrl = this.metadataHasMany.readBaseUrl(this.internalEntity, this.metadataHasMany);
|
|
214
|
-
void this.hasManyEntityService.read(readBaseUrl).then(() => {
|
|
215
|
-
this.hasManyIsLoading = false;
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
initEntityArray() {
|
|
220
|
-
this.metadataEntityArray = this.metadata;
|
|
221
|
-
if (this.internalEntity[this.internalPropertyKey] == null) {
|
|
222
|
-
this.internalEntity[this.internalPropertyKey] = [];
|
|
223
|
-
}
|
|
224
|
-
this.entityArrayValues = this.internalEntity[this.internalPropertyKey];
|
|
225
|
-
if (!this.metadataEntityArray.createInline && !this.metadataEntityArray.createDialogData) {
|
|
226
|
-
this.metadataEntityArray.createDialogData = {
|
|
227
|
-
title: 'Add'
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
const givenDisplayColumns = this.metadataEntityArray.displayColumns.map((v) => v.displayName);
|
|
231
|
-
if (givenDisplayColumns.find(s => s === 'select')) {
|
|
232
|
-
throw new Error(`The name "select" for a display column is reserved.
|
|
233
|
-
Please choose a different name.`);
|
|
234
|
-
}
|
|
235
|
-
this.entityArrayDisplayedColumns = this.internalIsReadOnly ? givenDisplayColumns : ['select'].concat(givenDisplayColumns);
|
|
236
|
-
this.entityArrayDataSource = new MatTableDataSource();
|
|
237
|
-
this.entityArrayDataSource.data = this.entityArrayValues;
|
|
238
|
-
this.arrayItem = new this.metadataEntityArray.EntityClass();
|
|
239
|
-
this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
|
|
240
|
-
this.arrayItemInlineTabs = EntityUtilities.getEntityTabs(this.arrayItem, true);
|
|
241
|
-
this.addArrayItemDialogData = new CreateDialogDataBuilder(this.metadataEntityArray.createDialogData)
|
|
242
|
-
.withDefault('createButtonLabel', 'Add')
|
|
243
|
-
.withDefault('title', 'Add to array')
|
|
244
|
-
.getResult();
|
|
245
|
-
this.arrayItemDialogTabs = EntityUtilities.getEntityTabs(this.arrayItem, true);
|
|
246
|
-
this.editArrayItemDialogData = this.metadataEntityArray.editDialogData;
|
|
247
|
-
}
|
|
248
|
-
initObjectInput() {
|
|
249
|
-
this.metadataDefaultObject = this.metadata;
|
|
250
|
-
this.objectProperty = this.internalEntity[this.internalPropertyKey];
|
|
251
|
-
this.objectPropertyTabs = EntityUtilities.getEntityTabs(this.objectProperty, this.hideOmitForCreate, this.hideOmitForEdit, this.metadataDefaultObject.omit);
|
|
252
|
-
}
|
|
253
|
-
startImportJson() {
|
|
254
|
-
const input = document.createElement('input');
|
|
255
|
-
input.type = 'file';
|
|
256
|
-
input.accept = 'application/json';
|
|
257
|
-
input.onchange = async () => {
|
|
258
|
-
if (input.files) {
|
|
259
|
-
this.importJson(input.files[0]);
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
input.click();
|
|
263
|
-
}
|
|
264
|
-
importJson(file) {
|
|
265
|
-
const dialogData = new ConfirmDialogDataBuilder(this.hasManyImportAction.confirmDialogData)
|
|
266
|
-
.withDefault('text', this.metadataHasMany.tableData.baseData.importActionData.confirmDialogData?.text)
|
|
267
|
-
.withDefault('title', this.hasManyImportAction.displayName)
|
|
268
|
-
.getResult();
|
|
269
|
-
const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
270
|
-
data: dialogData,
|
|
271
|
-
autoFocus: false,
|
|
272
|
-
restoreFocus: false
|
|
273
|
-
});
|
|
274
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
275
|
-
if (res == true) {
|
|
276
|
-
void this.hasManyEntityService.import(file);
|
|
277
|
-
}
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Sets the references one object using the input id.
|
|
282
|
-
*/
|
|
283
|
-
setReferencesOneObject() {
|
|
284
|
-
// eslint-disable-next-line max-len
|
|
285
|
-
const foundEntity = this.metadataReferencesOne.getEntityForId(this.internalEntity[this.internalPropertyKey], this.referencesOneAllReferencedEntities);
|
|
286
|
-
this.referencesOneObject = new this.metadataReferencesOne.EntityClass(foundEntity);
|
|
287
|
-
this.referencesOnePropertyTabs = EntityUtilities.getEntityTabs(this.referencesOneObject);
|
|
288
|
-
this.emitChange();
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Edits an entity. This either calls the edit-Method provided by the user or uses a default edit-dialog.
|
|
292
|
-
*
|
|
293
|
-
* @param entity - The entity that should be updated.
|
|
294
|
-
* @param dCol - The display column that was clicked on.
|
|
295
|
-
* @throws When no EntityClass was provided, as a new call is needed to initialize metadata.
|
|
296
|
-
*/
|
|
297
|
-
editHasManyEntity(entity, dCol) {
|
|
298
|
-
if ((dCol.disableClick === true) || (!this.hasManyAllowUpdate(entity) && !this.hasManyAllowRead(entity))) {
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
if (!this.metadataHasMany.tableData.baseData.EntityClass) {
|
|
302
|
-
throw new Error('No "EntityClass" specified for this table');
|
|
303
|
-
}
|
|
304
|
-
if (this.metadataHasMany.tableData.baseData.edit) {
|
|
305
|
-
this.metadataHasMany.tableData.baseData.edit(new this.metadataHasMany.tableData.baseData.EntityClass(entity));
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
if (this.metadataHasMany.tableData.baseData.defaultEdit == 'page') {
|
|
309
|
-
this.editHasManyDefaultPage(new this.metadataHasMany.tableData.baseData.EntityClass(entity));
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
void this.editHasManyDefaultDialog(new this.metadataHasMany.tableData.baseData.EntityClass(entity));
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Whether updating the provided entity from the has many property is allowed.
|
|
316
|
-
*
|
|
317
|
-
* @param entity - A single value of the has many property that the user wants to edit.
|
|
318
|
-
* @returns True when the user can edit the provided entity and false otherwise.
|
|
319
|
-
*/
|
|
320
|
-
hasManyAllowUpdate(entity) {
|
|
321
|
-
return this.injector.runInContext(() => {
|
|
322
|
-
return this.metadataHasMany.tableData.baseData.allowUpdate(entity);
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Whether viewing the provided entity from the has many property is allowed.
|
|
327
|
-
*
|
|
328
|
-
* @param entity - A single value of the has many property that the user wants to view.
|
|
329
|
-
* @returns True when the user can view the provided entity and false otherwise.
|
|
330
|
-
*/
|
|
331
|
-
hasManyAllowRead(entity) {
|
|
332
|
-
return this.injector.runInContext(() => {
|
|
333
|
-
return this.metadataHasMany.tableData.baseData.allowRead(entity);
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Whether deleting the provided entity from the has many property is allowed.
|
|
338
|
-
*
|
|
339
|
-
* @param entity - A single value of the has many property that the user wants to delete.
|
|
340
|
-
* @returns True when the user can delete the provided entity and false otherwise.
|
|
341
|
-
*/
|
|
342
|
-
hasManyAllowDelete(entity) {
|
|
343
|
-
return this.injector.runInContext(() => {
|
|
344
|
-
return this.metadataHasMany.tableData.baseData.allowDelete(entity);
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
editHasManyDefaultPage(entity) {
|
|
348
|
-
void this.router.navigate(['', this.hasManyEntityService.editBaseRoute, entity[this.hasManyEntityService.idKey]]);
|
|
349
|
-
}
|
|
350
|
-
async editHasManyDefaultDialog(entity) {
|
|
351
|
-
this.hasManyEntity = LodashUtilities.cloneDeep(entity);
|
|
352
|
-
this.hasManyEntityPriorChanges = LodashUtilities.cloneDeep(this.hasManyEntity);
|
|
353
|
-
this.hasManyUpdateTabs = EntityUtilities.getEntityTabs(this.hasManyEntity, false, true);
|
|
354
|
-
await this.checkHasManyEntity();
|
|
355
|
-
this.editHasManyDialogRef = this.dialog.open(this.editHasManyDialog, {
|
|
356
|
-
minWidth: '60%',
|
|
357
|
-
autoFocus: false,
|
|
358
|
-
restoreFocus: false
|
|
359
|
-
});
|
|
360
|
-
const res = await firstValueFrom(this.editHasManyDialogRef.afterClosed());
|
|
361
|
-
if (res === 0) {
|
|
362
|
-
const data = this.hasManyDataSource.data;
|
|
363
|
-
// eslint-disable-next-line max-len
|
|
364
|
-
data[this.hasManyDataSource.data.findIndex((e) => e[this.hasManyEntityService.idKey] === entity[this.hasManyEntityService.idKey])] = entity;
|
|
365
|
-
this.hasManyDataSource.data = data;
|
|
366
|
-
this.hasManySelection.clear();
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Tries to save the changes and close the dialog afterwards.
|
|
371
|
-
* Also handles the confirmation if required.
|
|
372
|
-
*/
|
|
373
|
-
dialogEditHasMany() {
|
|
374
|
-
if (this.internalIsReadOnly || !this.isHasManyEntityValid || !this.isHasManyEntityDirty) {
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
if (!this.metadataHasMany.tableData.editData.editRequiresConfirmDialog) {
|
|
378
|
-
this.dialogConfirmEditHasMany();
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
// eslint-disable-next-line max-len
|
|
382
|
-
const dialogData = new ConfirmDialogDataBuilder(this.metadataHasMany.tableData.editData.confirmEditDialogData)
|
|
383
|
-
.withDefault('text', ['Do you really want to save all changes?'])
|
|
384
|
-
.withDefault('confirmButtonLabel', 'Save')
|
|
385
|
-
.withDefault('title', 'Edit')
|
|
386
|
-
.getResult();
|
|
387
|
-
const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
388
|
-
data: dialogData,
|
|
389
|
-
autoFocus: false,
|
|
390
|
-
restoreFocus: false
|
|
391
|
-
});
|
|
392
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
393
|
-
if (res == true) {
|
|
394
|
-
this.dialogConfirmEditHasMany();
|
|
395
|
-
}
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
dialogConfirmEditHasMany() {
|
|
399
|
-
void this.hasManyEntityService.update(this.hasManyEntity, this.hasManyEntityPriorChanges)
|
|
400
|
-
.then(() => {
|
|
401
|
-
this.editHasManyDialogRef.close(1);
|
|
402
|
-
this.emitChange();
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Tries to delete the entity and close the dialog afterwards.
|
|
407
|
-
* Also handles the confirmation if required.
|
|
408
|
-
*/
|
|
409
|
-
deleteHasManyEntity() {
|
|
410
|
-
if (!this.metadataHasMany.tableData.editData.deleteRequiresConfirmDialog) {
|
|
411
|
-
this.confirmDeleteHasManyEntity();
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
// eslint-disable-next-line max-len
|
|
415
|
-
const dialogData = new ConfirmDialogDataBuilder(this.metadataHasMany.tableData.editData.confirmDeleteDialogData)
|
|
416
|
-
.withDefault('text', ['Do you really want to delete this entity?'])
|
|
417
|
-
.withDefault('type', 'delete')
|
|
418
|
-
.withDefault('confirmButtonLabel', 'Delete')
|
|
419
|
-
.withDefault('title', 'Delete')
|
|
420
|
-
.getResult();
|
|
421
|
-
const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
422
|
-
data: dialogData,
|
|
423
|
-
autoFocus: false,
|
|
424
|
-
restoreFocus: false
|
|
425
|
-
});
|
|
426
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
427
|
-
if (res == true) {
|
|
428
|
-
this.confirmDeleteHasManyEntity();
|
|
429
|
-
}
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
confirmDeleteHasManyEntity() {
|
|
433
|
-
void this.hasManyEntityService.delete(this.hasManyEntityPriorChanges).then(() => {
|
|
434
|
-
this.editHasManyDialogRef.close(2);
|
|
435
|
-
this.emitChange();
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
/**
|
|
439
|
-
* Cancels the editing of the has many entity and closes the dialog.
|
|
440
|
-
*/
|
|
441
|
-
dialogCancelEditHasMany() {
|
|
442
|
-
EntityUtilities.resetChangesOnEntity(this.hasManyEntity, this.hasManyEntityPriorChanges);
|
|
443
|
-
this.editHasManyDialogRef.close(0);
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* Creates a new Entity. This either calls the create-Method provided by the user or uses a default create-dialog.
|
|
447
|
-
*
|
|
448
|
-
* @throws When no EntityClass was provided, as a new call is needed to initialize metadata.
|
|
449
|
-
*/
|
|
450
|
-
createHasManyEntity() {
|
|
451
|
-
this.injector.runInContext(() => {
|
|
452
|
-
if (this.metadataHasMany.tableData.baseData.allowCreate()) {
|
|
453
|
-
if (!this.metadataHasMany.tableData.baseData.EntityClass) {
|
|
454
|
-
throw new Error('No "EntityClass" specified for this table');
|
|
455
|
-
}
|
|
456
|
-
if (this.metadataHasMany.tableData.baseData.create) {
|
|
457
|
-
this.metadataHasMany.tableData.baseData.create(new this.metadataHasMany.tableData.baseData.EntityClass());
|
|
458
|
-
}
|
|
459
|
-
else {
|
|
460
|
-
this.createHasManyDefault(new this.metadataHasMany.tableData.baseData.EntityClass());
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
createHasManyDefault(entity) {
|
|
466
|
-
this.hasManyEntity = entity;
|
|
467
|
-
this.hasManyCreateTabs = EntityUtilities.getEntityTabs(this.hasManyEntity, true);
|
|
468
|
-
this.checkIsHasManyEntityValid('create');
|
|
469
|
-
this.createHasManyDialogRef = this.dialog.open(this.createHasManyDialog, {
|
|
470
|
-
minWidth: '60%',
|
|
471
|
-
autoFocus: false,
|
|
472
|
-
restoreFocus: false
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
/**
|
|
476
|
-
* Creates the has many entity over the dialog.
|
|
477
|
-
*/
|
|
478
|
-
dialogCreateHasMany() {
|
|
479
|
-
if (!this.isHasManyEntityValid) {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
if (!this.metadataHasMany.tableData.createDialogData.createRequiresConfirmDialog) {
|
|
483
|
-
this.dialogConfirmCreateHasMany();
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
// eslint-disable-next-line max-len
|
|
487
|
-
const dialogData = new ConfirmDialogDataBuilder(this.metadataHasMany.tableData.createDialogData.confirmCreateDialogData)
|
|
488
|
-
.withDefault('text', ['Do you really want to create this entity?'])
|
|
489
|
-
.withDefault('confirmButtonLabel', 'Create')
|
|
490
|
-
.withDefault('title', 'Create')
|
|
491
|
-
.getResult();
|
|
492
|
-
const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
493
|
-
data: dialogData,
|
|
494
|
-
autoFocus: false,
|
|
495
|
-
restoreFocus: false
|
|
496
|
-
});
|
|
497
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
498
|
-
if (res == true) {
|
|
499
|
-
this.dialogConfirmCreateHasMany();
|
|
500
|
-
}
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
dialogConfirmCreateHasMany() {
|
|
504
|
-
void this.hasManyEntityService.create(this.hasManyEntity, this.hasManyCreateBaseUrl).then(() => {
|
|
505
|
-
this.createHasManyDialogRef.close();
|
|
506
|
-
this.emitChange();
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* Cancels the creating of the has many entity and closes the dialog.
|
|
511
|
-
*/
|
|
512
|
-
dialogCancelCreateHasMany() {
|
|
513
|
-
this.createHasManyDialogRef.close();
|
|
514
|
-
}
|
|
515
|
-
/**
|
|
516
|
-
* Runs the TableAction for all selected entries.
|
|
517
|
-
* Also handles confirmation with an additional dialog if configured.
|
|
518
|
-
*
|
|
519
|
-
* @param action - The TableAction to run.
|
|
520
|
-
*/
|
|
521
|
-
runHasManyTableAction(action) {
|
|
522
|
-
const requireConfirmDialog = this.injector.runInContext(() => {
|
|
523
|
-
return action.requireConfirmDialog(this.hasManySelection.selected);
|
|
524
|
-
});
|
|
525
|
-
if (!requireConfirmDialog) {
|
|
526
|
-
this.confirmRunHasManyTableAction(action);
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
const dialogData = new ConfirmDialogDataBuilder(action.confirmDialogData)
|
|
530
|
-
.withDefault('text', [`Do you really want to run this action on ${this.hasManySelection.selected.length} entries?`])
|
|
531
|
-
.withDefault('title', action.displayName)
|
|
532
|
-
.getResult();
|
|
533
|
-
const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
534
|
-
data: dialogData,
|
|
535
|
-
autoFocus: false,
|
|
536
|
-
restoreFocus: false
|
|
537
|
-
});
|
|
538
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
539
|
-
if (res == true) {
|
|
540
|
-
this.confirmRunHasManyTableAction(action);
|
|
541
|
-
}
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
confirmRunHasManyTableAction(action) {
|
|
545
|
-
void this.injector.runInContext(async () => {
|
|
546
|
-
await action.action(this.hasManySelection.selected);
|
|
547
|
-
this.emitChange();
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
/**
|
|
551
|
-
* Checks if an TableAction is disabled (e.g. Because no entries have been selected).
|
|
552
|
-
*
|
|
553
|
-
* @param action - The TableAction to check.
|
|
554
|
-
* @returns Whether or not the Action can be used.
|
|
555
|
-
*/
|
|
556
|
-
hasManyTableActionDisabled(action) {
|
|
557
|
-
return this.injector.runInContext(() => {
|
|
558
|
-
return !action.enabled(this.hasManySelection.selected);
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
/**
|
|
562
|
-
* Applies the search input to filter the table entries.
|
|
563
|
-
*
|
|
564
|
-
* @param event - The keyup-event which contains the search-string of the user.
|
|
565
|
-
*/
|
|
566
|
-
applyHasManyFilter(event) {
|
|
567
|
-
const filterValue = event.target.value;
|
|
568
|
-
this.hasManyDataSource.filter = filterValue.trim().toLowerCase();
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* Checks if the entity is valid for updating and if it is dirty.
|
|
572
|
-
*/
|
|
573
|
-
async checkHasManyEntity() {
|
|
574
|
-
this.checkIsHasManyEntityValid('update');
|
|
575
|
-
this.isHasManyEntityDirty = await EntityUtilities.isDirty(this.hasManyEntity, this.hasManyEntityPriorChanges, this.http);
|
|
576
|
-
}
|
|
577
|
-
/**
|
|
578
|
-
* Checks if the entity is valid.
|
|
579
|
-
*
|
|
580
|
-
* @param omit - Whether values omitted for create or update should be left out.
|
|
581
|
-
*/
|
|
582
|
-
checkIsHasManyEntityValid(omit) {
|
|
583
|
-
this.isHasManyEntityValid = EntityUtilities.isEntityValid(this.hasManyEntity, omit);
|
|
584
|
-
}
|
|
585
|
-
/**
|
|
586
|
-
* Checks whether the array item is valid and if the array item is dirty.
|
|
587
|
-
*/
|
|
588
|
-
checkArrayItem() {
|
|
589
|
-
this.checkIsArrayItemValid();
|
|
590
|
-
void this.checkIsArrayItemDirty();
|
|
591
|
-
}
|
|
592
|
-
/**
|
|
593
|
-
* Checks if the array item is dirty.
|
|
594
|
-
*/
|
|
595
|
-
async checkIsArrayItemDirty() {
|
|
596
|
-
this.isArrayItemDirty = await EntityUtilities.isDirty(this.arrayItem, this.arrayItemPriorChanges, this.http);
|
|
597
|
-
}
|
|
598
|
-
/**
|
|
599
|
-
* Checks if the arrayItem is valid.
|
|
600
|
-
*/
|
|
601
|
-
checkIsArrayItemValid() {
|
|
602
|
-
this.isArrayItemValid = EntityUtilities.isEntityValid(this.arrayItem, 'create');
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* Emits that a the value has been changed.
|
|
606
|
-
*/
|
|
607
|
-
emitChange() {
|
|
608
|
-
this.inputChangeEvent.emit();
|
|
609
|
-
}
|
|
610
|
-
/**
|
|
611
|
-
* Tries to add an item to the entity array.
|
|
612
|
-
* Does this either inline if the "createInline"-metadata is set to true
|
|
613
|
-
* or in a separate dialog if it is set to false.
|
|
614
|
-
*/
|
|
615
|
-
async addEntity() {
|
|
616
|
-
if (this.metadataEntityArray.createInline) {
|
|
617
|
-
if (!this.metadataEntityArray.allowDuplicates) {
|
|
618
|
-
for (const v of this.entityArrayValues) {
|
|
619
|
-
if ((await EntityUtilities.isEqual(this.arrayItem, v, this.metadata, this.metadataEntityArray.itemType, this.http))) {
|
|
620
|
-
this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
621
|
-
data: this.metadataEntityArray.duplicatesErrorDialog,
|
|
622
|
-
autoFocus: false,
|
|
623
|
-
restoreFocus: false
|
|
624
|
-
});
|
|
625
|
-
return;
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
this.entityArrayValues.push(LodashUtilities.cloneDeep(this.arrayItem));
|
|
630
|
-
this.entityArrayDataSource.data = this.entityArrayValues;
|
|
631
|
-
EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
|
|
632
|
-
this.checkIsArrayItemValid();
|
|
633
|
-
this.emitChange();
|
|
634
|
-
}
|
|
635
|
-
else {
|
|
636
|
-
this.addArrayItemDialogRef = this.dialog.open(this.addArrayItemDialog, {
|
|
637
|
-
minWidth: '60%',
|
|
638
|
-
autoFocus: false,
|
|
639
|
-
restoreFocus: false
|
|
640
|
-
});
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
/**
|
|
644
|
-
* Adds the array item defined in the dialog.
|
|
645
|
-
*/
|
|
646
|
-
addArrayItem() {
|
|
647
|
-
if (!this.isArrayItemValid) {
|
|
648
|
-
return;
|
|
649
|
-
}
|
|
650
|
-
this.entityArrayValues.push(LodashUtilities.cloneDeep(this.arrayItem));
|
|
651
|
-
this.entityArrayDataSource.data = this.entityArrayValues;
|
|
652
|
-
this.closeAddArrayItemDialog();
|
|
653
|
-
}
|
|
654
|
-
/**
|
|
655
|
-
* Cancels adding the array item defined in the dialog.
|
|
656
|
-
*/
|
|
657
|
-
closeAddArrayItemDialog() {
|
|
658
|
-
this.addArrayItemDialogRef.close();
|
|
659
|
-
EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
|
|
660
|
-
this.checkIsArrayItemValid();
|
|
661
|
-
this.emitChange();
|
|
662
|
-
}
|
|
663
|
-
/**
|
|
664
|
-
* Edits an entity array item.
|
|
665
|
-
*
|
|
666
|
-
* @param entity - The entity that has been clicked.
|
|
667
|
-
* @param dCol - The display column that was clicked on.
|
|
668
|
-
*/
|
|
669
|
-
editArrayItem(entity, dCol) {
|
|
670
|
-
if (dCol.disableClick === true) {
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
this.indexOfEditedArrayItem = this.entityArrayValues.indexOf(entity);
|
|
674
|
-
this.arrayItem = new this.metadataEntityArray.EntityClass(entity);
|
|
675
|
-
this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
|
|
676
|
-
this.checkArrayItem();
|
|
677
|
-
this.editArrayItemDialogRef = this.dialog.open(this.editArrayItemDialog, {
|
|
678
|
-
minWidth: '60%',
|
|
679
|
-
autoFocus: false,
|
|
680
|
-
restoreFocus: false
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
/**
|
|
684
|
-
* Saves changes on the array item in the dialog.
|
|
685
|
-
*/
|
|
686
|
-
saveArrayItem() {
|
|
687
|
-
this.entityArrayValues[this.indexOfEditedArrayItem] = LodashUtilities.cloneDeep(this.arrayItem);
|
|
688
|
-
this.entityArrayDataSource.data = this.entityArrayValues;
|
|
689
|
-
this.closeEditArrayItemDialog();
|
|
690
|
-
}
|
|
691
|
-
/**
|
|
692
|
-
* Closes the edit array item dialog and resets changes.
|
|
693
|
-
*/
|
|
694
|
-
closeEditArrayItemDialog() {
|
|
695
|
-
this.editArrayItemDialogRef.close();
|
|
696
|
-
this.arrayItem = new this.metadataEntityArray.EntityClass();
|
|
697
|
-
this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
|
|
698
|
-
this.checkArrayItem();
|
|
699
|
-
this.emitChange();
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* Removes all selected entries from the entity array.
|
|
703
|
-
*/
|
|
704
|
-
removeFromEntityArray() {
|
|
705
|
-
SelectionUtilities.remove(this.entityArraySelection, this.entityArrayValues, this.entityArrayDataSource);
|
|
706
|
-
this.emitChange();
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
NgxMatEntityInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: NgxMatEntityInputComponent, deps: [{ token: i1.MatDialog }, { token: i0.EnvironmentInjector }, { token: i2.Router }, { token: NGX_GET_VALIDATION_ERROR_MESSAGE }, { token: i3.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
|
|
710
|
-
NgxMatEntityInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.3", type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: { entity: "entity", propertyKey: "propertyKey", getValidationErrorMessage: "getValidationErrorMessage", hideOmitForCreate: "hideOmitForCreate", hideOmitForEdit: "hideOmitForEdit", validEmpty: "validEmpty", isReadOnly: "isReadOnly" }, outputs: { inputChangeEvent: "inputChangeEvent" }, viewQueries: [{ propertyName: "addArrayItemDialog", first: true, predicate: ["addArrayItemDialog"], descendants: true }, { propertyName: "editArrayItemDialog", first: true, predicate: ["editArrayItemDialog"], descendants: true }, { propertyName: "hasManyPaginator", first: true, predicate: MatPaginator, descendants: true, static: true }, { propertyName: "hasManySort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "hasManyFilter", first: true, predicate: ["filter"], descendants: true, static: true }, { propertyName: "createHasManyDialog", first: true, predicate: ["createHasManyDialog"], descendants: true }, { propertyName: "editHasManyDialog", first: true, predicate: ["editHasManyDialog"], descendants: true }], ngImport: i0, template: "<div [ngSwitch]=\"type\" *ngIf=\"!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)\">\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.STRING\">\n <string-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_TEXTBOX\">\n <string-textbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-textbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_AUTOCOMPLETE\">\n <string-autocomplete-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-autocomplete-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_DROPDOWN\">\n <string-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_PASSWORD\">\n <string-password-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-password-input>\n </div>\n\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_CHECKBOX\">\n <boolean-checkbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-checkbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <boolean-toggle-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-toggle-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_DROPDOWN\">\n <boolean-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER\">\n <number-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_DROPDOWN\">\n <number-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_SLIDER\">\n <number-slider-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-slider-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE\">\n <array-date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_TIME\">\n <array-date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-time-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_RANGE\">\n <array-date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_CHIPS\">\n <array-string-chips-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-chips-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS\">\n <array-string-autocomplete-chips\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-autocomplete-chips>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.DATE\">\n <date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_RANGE\">\n <date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_TIME\">\n <date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-time-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Files-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.FILE_DEFAULT\">\n <file-default-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-default-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.FILE_IMAGE\">\n <file-image-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-image-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------- references many ------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.REFERENCES_MANY\">\n <references-many-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </references-many-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Custom------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.CUSTOM\">\n <custom-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </custom-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.OBJECT\">\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n <mat-tab-group *ngIf=\"objectPropertyTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of objectPropertyTabs; let tI = index; trackBy: trackByFn\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows;\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let rI = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"isPropertyReadOnly(objectProperty, key)\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"objectPropertyTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of objectPropertyTabs[0].rows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"isPropertyReadOnly(objectProperty, key)\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------- references one ------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.REFERENCES_ONE\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select [(ngModel)]=\"internalEntity[internalPropertyKey]\"\n [name]=\"internalPropertyKey.toString() + 'input'\"\n #inputModel=\"ngModel\"\n [disabled]=\"internalIsReadOnly\"\n [required]=\"metadata.required(entity)\"\n (ngModelChange)=\"setReferencesOneObject()\"\n >\n <mat-option *ngIf=\"!metadata.required(entity)\">-</mat-option>\n <mat-option *ngFor=\"let value of referencesOneDropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{internalGetValidationErrorMessage(inputModel)}}</mat-error>\n </mat-form-field>\n <!-- iterates over the references one properties -->\n <mat-tab-group *ngIf=\"referencesOnePropertyTabs && referencesOnePropertyTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of referencesOnePropertyTabs; let tI = index; trackBy: trackByFn\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows;\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let rI = index; trackBy: trackByFn\"\n [entity]=\"referencesOneObject\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(referencesOneObject, key, 'lg')}} col-md-{{EntityUtilities.getWidth(referencesOneObject, key, 'md')}} col-sm-{{EntityUtilities.getWidth(referencesOneObject, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"referencesOnePropertyTabs && referencesOnePropertyTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of referencesOnePropertyTabs[0].rows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"referencesOneObject\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(referencesOneObject, key, 'lg')}} col-md-{{EntityUtilities.getWidth(referencesOneObject, key, 'md')}} col-sm-{{EntityUtilities.getWidth(referencesOneObject, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div class=\"entityArray\" *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <div class=\"mat-elevation-z8 elevation-container\">\n <div class=\"array-headline\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n <div *ngIf=\"metadataEntityArray.createInline && !internalIsReadOnly\">\n <mat-tab-group *ngIf=\"arrayItemInlineTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemInlineTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"arrayItemInlineTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemInlineTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <div class=\"buttons\" *ngIf=\"!internalIsReadOnly\">\n <button type=\"button\" mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !isArrayItemValid\"\n (click)=\"addEntity()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button\n [disabled]=\"!entityArraySelection.selected.length\"\n (click)=\"removeFromEntityArray()\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n \n <mat-table [dataSource]=\"entityArrayDataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\" *ngIf=\"!internalIsReadOnly\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox\n [disabled]=\"!entityArrayDataSource.data.length\" (change)=\"$event ? SelectionUtilities.masterToggle(entityArraySelection, entityArrayDataSource) : null\"\n [checked]=\"entityArraySelection.hasValue() && SelectionUtilities.isAllSelected(entityArraySelection, entityArrayDataSource)\"\n [indeterminate]=\"entityArraySelection.hasValue() && !SelectionUtilities.isAllSelected(entityArraySelection, entityArrayDataSource)\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let entity\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? entityArraySelection.toggle(entity) : null\" [checked]=\"entityArraySelection.isSelected(entity)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadataEntityArray.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell [class.enabled]=\"!dCol.disableClick\" (click)=\"editArrayItem(entity, dCol)\" *matCellDef=\"let entity\">\n <ng-container *ngIf=\"dCol.Component\">\n <display-column-value [entity]=\"entity\" [ComponentClass]=\"dCol.Component\"></display-column-value>\n </ng-container>\n <ng-container *ngIf=\"!dCol.Component\">\n {{getDisplayColumnValue(entity, dCol)}}\n </ng-container>\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"entityArrayDisplayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: entityArrayDisplayedColumns\"></mat-row>\n </mat-table>\n \n <div class=\"array-error\" *ngIf=\"metadataEntityArray.required && !entityArrayDataSource.data.length\">\n {{metadataEntityArray.missingErrorMessage}}\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!------------------ has many ---------------->\n <!-------------------------------------------->\n <div class=\"hasMany\" *ngSwitchCase=\"DecoratorTypes.HAS_MANY\">\n <h2 class=\"title\">{{metadataHasMany.tableData.baseData.title}}</h2>\n\n <div class=\"row\">\n <mat-form-field class=\"col-lg-8 col-md-6 col-sm-12\">\n <mat-label>{{metadataHasMany.tableData.baseData.searchLabel}}</mat-label>\n <input matInput (keyup)=\"applyHasManyFilter($event)\">\n </mat-form-field>\n <div\n *ngIf=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-lg-2]=\"hasManyAllowCreate\"\n [class.col-lg-4]=\"!hasManyAllowCreate\"\n [class.col-md-3]=\"hasManyAllowCreate\"\n [class.col-md-6]=\"!hasManyAllowCreate\"\n [class.col-sm-6]=\"hasManyAllowCreate\"\n [class.col-sm-12]=\"!hasManyAllowCreate\"\n >\n <button type=\"button\" class=\"actions-button\" [matMenuTriggerFor]=\"menu\" mat-raised-button>\n {{metadataHasMany.tableData.baseData.tableActionsLabel}}\n </button>\n </div>\n <mat-menu #menu=\"matMenu\">\n <button *ngIf=\"metadataHasMany.tableData.baseData.allowJsonImport\" type=\"button\" [disabled]=\"hasManyTableActionDisabled(hasManyImportAction)\" (click)=\"runHasManyTableAction(hasManyImportAction)\" mat-menu-item>\n {{hasManyImportAction.displayName}}\n </button>\n <button type=\"button\" *ngFor=\"let action of metadataHasMany.tableData.baseData.tableActions\" [disabled]=\"hasManyTableActionDisabled(action)\" (click)=\"runHasManyTableAction(action)\" mat-menu-item>\n {{action.displayName}}\n </button>\n </mat-menu>\n\n <div\n *ngIf=\"hasManyAllowCreate\"\n [class.col-lg-2]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-lg-4]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-md-3]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-md-6]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-sm-6]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-sm-12]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n >\n <button type=\"button\" class=\"create-button\" (click)=\"createHasManyEntity()\" mat-raised-button>\n {{metadataHasMany.tableData.baseData.createButtonLabel}}\n </button>\n </div>\n </div>\n\n <div class=\"mat-elevation-z8 elevation-container\">\n <mat-table [dataSource]=\"hasManyDataSource\" matSort>\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? SelectionUtilities.masterToggle(hasManySelection, hasManyDataSource) : null\" [checked]=\"hasManySelection.hasValue() && SelectionUtilities.isAllSelected(hasManySelection, hasManyDataSource)\" [indeterminate]=\"hasManySelection.hasValue() && !SelectionUtilities.isAllSelected(hasManySelection, hasManyDataSource)\"> </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let entity\" class=\"enabled\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? hasManySelection.toggle(entity) : null\" [checked]=\"hasManySelection.isSelected(entity)\"> </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <ng-container *ngFor=\"let dCol of metadataHasMany.tableData.baseData.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell [class.enabled]=\"!dCol.disableClick && (hasManyAllowUpdate(entity) || hasManyAllowRead(entity))\" (click)=\"editHasManyEntity(entity, dCol)\" *matCellDef=\"let entity\">\n <ng-container *ngIf=\"dCol.Component\">\n <display-column-value [entity]=\"entity\" [ComponentClass]=\"dCol.Component\"></display-column-value>\n </ng-container>\n <ng-container *ngIf=\"!dCol.Component\">\n {{getDisplayColumnValue(entity, dCol)}}\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedHasManyColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedHasManyColumns\"></mat-row>\n </mat-table>\n\n <mat-spinner *ngIf=\"hasManyIsLoading && metadataHasMany.tableData.baseData.displayLoadingSpinner\">\n </mat-spinner>\n\n <mat-paginator [length]=\"hasManyDataSource.filteredData.length\" [pageIndex]=\"0\" [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\"></mat-paginator>\n </div>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}} is not known.</div>\n</div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{addArrayItemDialogData.title}}</div>\n </div>\n\n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"arrayItemDialogTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemDialogTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"arrayItemDialogTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" mat-raised-button (click)=\"addArrayItem()\" [disabled]=\"!isArrayItemValid\">\n {{addArrayItemDialogData.createButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"closeAddArrayItemDialog()\" class=\"cancel-button\">\n {{addArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Edit Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #editArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{editArrayItemDialogData.title(arrayItemPriorChanges)}}</div>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"arrayItemDialogTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemDialogTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkArrayItem()\"\n [isReadOnly]=\"isPropertyReadOnly(arrayItem, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"arrayItemDialogTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkArrayItem()\"\n [isReadOnly]=\"isPropertyReadOnly(arrayItem, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"saveArrayItem()\" mat-raised-button [disabled]=\"internalIsReadOnly || !isArrayItemValid || !isArrayItemDirty\">\n {{editArrayItemDialogData.confirmButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"closeEditArrayItemDialog()\" class=\"cancel-button\">\n {{editArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Create Has Many Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #createHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.createDialogData.title}}</div>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"hasManyCreateTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of hasManyCreateTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsHasManyEntityValid('create')\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"hasManyCreateTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of hasManyCreateTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsHasManyEntityValid('create')\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"dialogCreateHasMany()\" mat-raised-button [disabled]=\"!isHasManyEntityValid\">\n {{metadataHasMany.tableData.createDialogData.createButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"dialogCancelCreateHasMany()\" class=\"cancel-button\">\n {{metadataHasMany.tableData.createDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n \n</ng-template>\n\n<ng-template #editHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.editData.title(hasManyEntityPriorChanges)}}</div>\n <button type=\"button\" *ngIf=\"hasManyAllowDelete(hasManyEntity)\" mat-raised-button (click)=\"deleteHasManyEntity()\" color=\"warn\" class=\"delete-button\" tabindex=\"-1\">\n {{metadataHasMany.tableData.editData.deleteButtonLabel}}\n </button>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"hasManyUpdateTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of hasManyUpdateTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkHasManyEntity()\"\n [isReadOnly]=\"isPropertyReadOnly(hasManyEntity, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"hasManyUpdateTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of hasManyUpdateTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkHasManyEntity()\"\n [isReadOnly]=\"isPropertyReadOnly(hasManyEntity, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"dialogEditHasMany()\" mat-raised-button [disabled]=\"internalIsReadOnly || !isHasManyEntityValid || !isHasManyEntityDirty\">\n {{metadataHasMany.tableData.editData.confirmButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"dialogCancelEditHasMany()\" class=\"cancel-button\">\n {{metadataHasMany.tableData.editData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form> \n</ng-template>", styles: [".mdc-data-table__row:last-child .mdc-data-table__cell{border-bottom:1px solid rgba(0,0,0,.12)}.mat-dialog-title{padding:12px 20px;display:flex;justify-content:space-between;align-items:center}.mat-dialog-title div{font-size:var(--mdc-dialog-subhead-size, 14px);font-weight:var(--mdc-dialog-subhead-weight, 500)}::ng-deep .mdc-dialog .mdc-dialog__content{padding:6px 20px!important}mat-dialog-actions{justify-content:space-between;align-items:center;padding-left:20px;padding-right:20px}mat-spinner{margin:10px auto}::ng-deep .mat-mdc-tab-body-wrapper{margin-left:-12px;margin-right:-12px}::ng-deep mat-tab-body{padding-top:10px;padding-left:12px;padding-right:12px}::ng-deep mat-tab-body .mat-mdc-tab-body-content{overflow:initial}::ng-deep .mat-mdc-form-field.mat-form-field-disabled label{color:#0009}::ng-deep .mat-mdc-form-field.mat-form-field-disabled input,::ng-deep .mat-mdc-form-field.mat-form-field-disabled textarea,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-disabled,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-value{color:#000}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled{opacity:1}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled button{opacity:.2}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-date-range-input-inner:disabled{color:#000}::ng-deep .mat-mdc-form-field .mat-mdc-slide-toggle{opacity:1}.entityArray .elevation-container{border-radius:5px;padding:15px;margin-bottom:15px;margin-top:15px}.entityArray .array-headline{padding-bottom:10px}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}.entityArray mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.entityArray .mat-column-select{flex:0 0 75px}.entityArray .enabled:hover{cursor:pointer}.entityArray .array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}.hasMany button{width:100%;height:56px;line-height:24px;font-size:16px}.hasMany .title{text-align:center}.hasMany .elevation-container{border-radius:5px;padding:5px;margin-bottom:15px}.hasMany .mat-column-select{flex:0 0 75px}.hasMany .enabled:hover{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i4.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i7.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i8.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i9.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i10.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i11.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i11.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i11.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i11.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i11.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i11.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i11.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i11.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i11.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i11.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i12.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i13.MatTab, selector: "mat-tab", inputs: ["disabled"], exportAs: ["matTab"] }, { kind: "component", type: i13.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple", "fitInkBarToContent", "mat-stretch-tabs"], exportAs: ["matTabGroup"] }, { kind: "component", type: i14.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i14.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i14.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i15.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i16.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i17.DisplayColumnValueComponent, selector: "display-column-value", inputs: ["entity", "ComponentClass"] }, { kind: "component", type: i18.StringInputComponent, selector: "string-input" }, { kind: "component", type: i19.StringTextboxInputComponent, selector: "string-textbox-input" }, { kind: "component", type: i20.StringAutocompleteInputComponent, selector: "string-autocomplete-input" }, { kind: "component", type: i21.StringDropdownInputComponent, selector: "string-dropdown-input" }, { kind: "component", type: i22.StringPasswordInputComponent, selector: "string-password-input" }, { kind: "component", type: i23.BooleanCheckboxInputComponent, selector: "boolean-checkbox-input" }, { kind: "component", type: i24.BooleanToggleInputComponent, selector: "boolean-toggle-input" }, { kind: "component", type: i25.BooleanDropdownInputComponent, selector: "boolean-dropdown-input" }, { kind: "component", type: i26.NumberInputComponent, selector: "number-input" }, { kind: "component", type: i27.NumberDropdownInputComponent, selector: "number-dropdown-input" }, { kind: "component", type: i28.NumberSliderInputComponent, selector: "number-slider-input" }, { kind: "component", type: i29.ArrayStringChipsInputComponent, selector: "array-string-chips-input" }, { kind: "component", type: i30.ArrayStringAutocompleteChipsComponent, selector: "array-string-autocomplete-chips" }, { kind: "component", type: i31.DateInputComponent, selector: "date-input" }, { kind: "component", type: i32.DateRangeInputComponent, selector: "date-range-input" }, { kind: "component", type: i33.DateTimeInputComponent, selector: "date-time-input" }, { kind: "component", type: i34.ArrayDateInputComponent, selector: "array-date-input" }, { kind: "component", type: i35.ArrayDateTimeInputComponent, selector: "array-date-time-input" }, { kind: "component", type: i36.ArrayDateRangeInputComponent, selector: "array-date-range-input" }, { kind: "component", type: i37.FileImageInputComponent, selector: "file-image-input" }, { kind: "component", type: i38.FileDefaultInputComponent, selector: "file-default-input" }, { kind: "component", type: i39.ReferencesManyInputComponent, selector: "references-many-input" }, { kind: "component", type: i40.CustomInputComponent, selector: "custom-input" }, { kind: "component", type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit", "validEmpty", "isReadOnly"], outputs: ["inputChangeEvent"] }] });
|
|
711
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: NgxMatEntityInputComponent, decorators: [{
|
|
712
|
-
type: Component,
|
|
713
|
-
args: [{ selector: 'ngx-mat-entity-input', template: "<div [ngSwitch]=\"type\" *ngIf=\"!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)\">\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.STRING\">\n <string-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_TEXTBOX\">\n <string-textbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-textbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_AUTOCOMPLETE\">\n <string-autocomplete-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-autocomplete-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_DROPDOWN\">\n <string-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_PASSWORD\">\n <string-password-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-password-input>\n </div>\n\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_CHECKBOX\">\n <boolean-checkbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-checkbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <boolean-toggle-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-toggle-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_DROPDOWN\">\n <boolean-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER\">\n <number-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_DROPDOWN\">\n <number-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_SLIDER\">\n <number-slider-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-slider-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE\">\n <array-date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_TIME\">\n <array-date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-time-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_RANGE\">\n <array-date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_CHIPS\">\n <array-string-chips-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-chips-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS\">\n <array-string-autocomplete-chips\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-autocomplete-chips>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.DATE\">\n <date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_RANGE\">\n <date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_TIME\">\n <date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-time-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Files-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.FILE_DEFAULT\">\n <file-default-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-default-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.FILE_IMAGE\">\n <file-image-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-image-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------- references many ------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.REFERENCES_MANY\">\n <references-many-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </references-many-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Custom------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.CUSTOM\">\n <custom-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </custom-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.OBJECT\">\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n <mat-tab-group *ngIf=\"objectPropertyTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of objectPropertyTabs; let tI = index; trackBy: trackByFn\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows;\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let rI = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"isPropertyReadOnly(objectProperty, key)\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"objectPropertyTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of objectPropertyTabs[0].rows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"isPropertyReadOnly(objectProperty, key)\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------- references one ------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.REFERENCES_ONE\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select [(ngModel)]=\"internalEntity[internalPropertyKey]\"\n [name]=\"internalPropertyKey.toString() + 'input'\"\n #inputModel=\"ngModel\"\n [disabled]=\"internalIsReadOnly\"\n [required]=\"metadata.required(entity)\"\n (ngModelChange)=\"setReferencesOneObject()\"\n >\n <mat-option *ngIf=\"!metadata.required(entity)\">-</mat-option>\n <mat-option *ngFor=\"let value of referencesOneDropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{internalGetValidationErrorMessage(inputModel)}}</mat-error>\n </mat-form-field>\n <!-- iterates over the references one properties -->\n <mat-tab-group *ngIf=\"referencesOnePropertyTabs && referencesOnePropertyTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of referencesOnePropertyTabs; let tI = index; trackBy: trackByFn\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows;\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let rI = index; trackBy: trackByFn\"\n [entity]=\"referencesOneObject\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(referencesOneObject, key, 'lg')}} col-md-{{EntityUtilities.getWidth(referencesOneObject, key, 'md')}} col-sm-{{EntityUtilities.getWidth(referencesOneObject, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"referencesOnePropertyTabs && referencesOnePropertyTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of referencesOnePropertyTabs[0].rows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"referencesOneObject\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(referencesOneObject, key, 'lg')}} col-md-{{EntityUtilities.getWidth(referencesOneObject, key, 'md')}} col-sm-{{EntityUtilities.getWidth(referencesOneObject, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div class=\"entityArray\" *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <div class=\"mat-elevation-z8 elevation-container\">\n <div class=\"array-headline\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n <div *ngIf=\"metadataEntityArray.createInline && !internalIsReadOnly\">\n <mat-tab-group *ngIf=\"arrayItemInlineTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemInlineTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"arrayItemInlineTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemInlineTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <div class=\"buttons\" *ngIf=\"!internalIsReadOnly\">\n <button type=\"button\" mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !isArrayItemValid\"\n (click)=\"addEntity()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button\n [disabled]=\"!entityArraySelection.selected.length\"\n (click)=\"removeFromEntityArray()\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n \n <mat-table [dataSource]=\"entityArrayDataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\" *ngIf=\"!internalIsReadOnly\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox\n [disabled]=\"!entityArrayDataSource.data.length\" (change)=\"$event ? SelectionUtilities.masterToggle(entityArraySelection, entityArrayDataSource) : null\"\n [checked]=\"entityArraySelection.hasValue() && SelectionUtilities.isAllSelected(entityArraySelection, entityArrayDataSource)\"\n [indeterminate]=\"entityArraySelection.hasValue() && !SelectionUtilities.isAllSelected(entityArraySelection, entityArrayDataSource)\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let entity\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? entityArraySelection.toggle(entity) : null\" [checked]=\"entityArraySelection.isSelected(entity)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadataEntityArray.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell [class.enabled]=\"!dCol.disableClick\" (click)=\"editArrayItem(entity, dCol)\" *matCellDef=\"let entity\">\n <ng-container *ngIf=\"dCol.Component\">\n <display-column-value [entity]=\"entity\" [ComponentClass]=\"dCol.Component\"></display-column-value>\n </ng-container>\n <ng-container *ngIf=\"!dCol.Component\">\n {{getDisplayColumnValue(entity, dCol)}}\n </ng-container>\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"entityArrayDisplayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: entityArrayDisplayedColumns\"></mat-row>\n </mat-table>\n \n <div class=\"array-error\" *ngIf=\"metadataEntityArray.required && !entityArrayDataSource.data.length\">\n {{metadataEntityArray.missingErrorMessage}}\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!------------------ has many ---------------->\n <!-------------------------------------------->\n <div class=\"hasMany\" *ngSwitchCase=\"DecoratorTypes.HAS_MANY\">\n <h2 class=\"title\">{{metadataHasMany.tableData.baseData.title}}</h2>\n\n <div class=\"row\">\n <mat-form-field class=\"col-lg-8 col-md-6 col-sm-12\">\n <mat-label>{{metadataHasMany.tableData.baseData.searchLabel}}</mat-label>\n <input matInput (keyup)=\"applyHasManyFilter($event)\">\n </mat-form-field>\n <div\n *ngIf=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-lg-2]=\"hasManyAllowCreate\"\n [class.col-lg-4]=\"!hasManyAllowCreate\"\n [class.col-md-3]=\"hasManyAllowCreate\"\n [class.col-md-6]=\"!hasManyAllowCreate\"\n [class.col-sm-6]=\"hasManyAllowCreate\"\n [class.col-sm-12]=\"!hasManyAllowCreate\"\n >\n <button type=\"button\" class=\"actions-button\" [matMenuTriggerFor]=\"menu\" mat-raised-button>\n {{metadataHasMany.tableData.baseData.tableActionsLabel}}\n </button>\n </div>\n <mat-menu #menu=\"matMenu\">\n <button *ngIf=\"metadataHasMany.tableData.baseData.allowJsonImport\" type=\"button\" [disabled]=\"hasManyTableActionDisabled(hasManyImportAction)\" (click)=\"runHasManyTableAction(hasManyImportAction)\" mat-menu-item>\n {{hasManyImportAction.displayName}}\n </button>\n <button type=\"button\" *ngFor=\"let action of metadataHasMany.tableData.baseData.tableActions\" [disabled]=\"hasManyTableActionDisabled(action)\" (click)=\"runHasManyTableAction(action)\" mat-menu-item>\n {{action.displayName}}\n </button>\n </mat-menu>\n\n <div\n *ngIf=\"hasManyAllowCreate\"\n [class.col-lg-2]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-lg-4]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-md-3]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-md-6]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-sm-6]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-sm-12]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n >\n <button type=\"button\" class=\"create-button\" (click)=\"createHasManyEntity()\" mat-raised-button>\n {{metadataHasMany.tableData.baseData.createButtonLabel}}\n </button>\n </div>\n </div>\n\n <div class=\"mat-elevation-z8 elevation-container\">\n <mat-table [dataSource]=\"hasManyDataSource\" matSort>\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? SelectionUtilities.masterToggle(hasManySelection, hasManyDataSource) : null\" [checked]=\"hasManySelection.hasValue() && SelectionUtilities.isAllSelected(hasManySelection, hasManyDataSource)\" [indeterminate]=\"hasManySelection.hasValue() && !SelectionUtilities.isAllSelected(hasManySelection, hasManyDataSource)\"> </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let entity\" class=\"enabled\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? hasManySelection.toggle(entity) : null\" [checked]=\"hasManySelection.isSelected(entity)\"> </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <ng-container *ngFor=\"let dCol of metadataHasMany.tableData.baseData.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell [class.enabled]=\"!dCol.disableClick && (hasManyAllowUpdate(entity) || hasManyAllowRead(entity))\" (click)=\"editHasManyEntity(entity, dCol)\" *matCellDef=\"let entity\">\n <ng-container *ngIf=\"dCol.Component\">\n <display-column-value [entity]=\"entity\" [ComponentClass]=\"dCol.Component\"></display-column-value>\n </ng-container>\n <ng-container *ngIf=\"!dCol.Component\">\n {{getDisplayColumnValue(entity, dCol)}}\n </ng-container>\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedHasManyColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedHasManyColumns\"></mat-row>\n </mat-table>\n\n <mat-spinner *ngIf=\"hasManyIsLoading && metadataHasMany.tableData.baseData.displayLoadingSpinner\">\n </mat-spinner>\n\n <mat-paginator [length]=\"hasManyDataSource.filteredData.length\" [pageIndex]=\"0\" [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\"></mat-paginator>\n </div>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}} is not known.</div>\n</div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{addArrayItemDialogData.title}}</div>\n </div>\n\n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"arrayItemDialogTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemDialogTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"arrayItemDialogTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" mat-raised-button (click)=\"addArrayItem()\" [disabled]=\"!isArrayItemValid\">\n {{addArrayItemDialogData.createButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"closeAddArrayItemDialog()\" class=\"cancel-button\">\n {{addArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Edit Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #editArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{editArrayItemDialogData.title(arrayItemPriorChanges)}}</div>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"arrayItemDialogTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemDialogTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkArrayItem()\"\n [isReadOnly]=\"isPropertyReadOnly(arrayItem, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"arrayItemDialogTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkArrayItem()\"\n [isReadOnly]=\"isPropertyReadOnly(arrayItem, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"saveArrayItem()\" mat-raised-button [disabled]=\"internalIsReadOnly || !isArrayItemValid || !isArrayItemDirty\">\n {{editArrayItemDialogData.confirmButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"closeEditArrayItemDialog()\" class=\"cancel-button\">\n {{editArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Create Has Many Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #createHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.createDialogData.title}}</div>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"hasManyCreateTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of hasManyCreateTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsHasManyEntityValid('create')\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"hasManyCreateTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of hasManyCreateTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsHasManyEntityValid('create')\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"dialogCreateHasMany()\" mat-raised-button [disabled]=\"!isHasManyEntityValid\">\n {{metadataHasMany.tableData.createDialogData.createButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"dialogCancelCreateHasMany()\" class=\"cancel-button\">\n {{metadataHasMany.tableData.createDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n \n</ng-template>\n\n<ng-template #editHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.editData.title(hasManyEntityPriorChanges)}}</div>\n <button type=\"button\" *ngIf=\"hasManyAllowDelete(hasManyEntity)\" mat-raised-button (click)=\"deleteHasManyEntity()\" color=\"warn\" class=\"delete-button\" tabindex=\"-1\">\n {{metadataHasMany.tableData.editData.deleteButtonLabel}}\n </button>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"hasManyUpdateTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of hasManyUpdateTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkHasManyEntity()\"\n [isReadOnly]=\"isPropertyReadOnly(hasManyEntity, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"hasManyUpdateTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of hasManyUpdateTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkHasManyEntity()\"\n [isReadOnly]=\"isPropertyReadOnly(hasManyEntity, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"dialogEditHasMany()\" mat-raised-button [disabled]=\"internalIsReadOnly || !isHasManyEntityValid || !isHasManyEntityDirty\">\n {{metadataHasMany.tableData.editData.confirmButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"dialogCancelEditHasMany()\" class=\"cancel-button\">\n {{metadataHasMany.tableData.editData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form> \n</ng-template>", styles: [".mdc-data-table__row:last-child .mdc-data-table__cell{border-bottom:1px solid rgba(0,0,0,.12)}.mat-dialog-title{padding:12px 20px;display:flex;justify-content:space-between;align-items:center}.mat-dialog-title div{font-size:var(--mdc-dialog-subhead-size, 14px);font-weight:var(--mdc-dialog-subhead-weight, 500)}::ng-deep .mdc-dialog .mdc-dialog__content{padding:6px 20px!important}mat-dialog-actions{justify-content:space-between;align-items:center;padding-left:20px;padding-right:20px}mat-spinner{margin:10px auto}::ng-deep .mat-mdc-tab-body-wrapper{margin-left:-12px;margin-right:-12px}::ng-deep mat-tab-body{padding-top:10px;padding-left:12px;padding-right:12px}::ng-deep mat-tab-body .mat-mdc-tab-body-content{overflow:initial}::ng-deep .mat-mdc-form-field.mat-form-field-disabled label{color:#0009}::ng-deep .mat-mdc-form-field.mat-form-field-disabled input,::ng-deep .mat-mdc-form-field.mat-form-field-disabled textarea,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-disabled,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-value{color:#000}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled{opacity:1}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled button{opacity:.2}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-date-range-input-inner:disabled{color:#000}::ng-deep .mat-mdc-form-field .mat-mdc-slide-toggle{opacity:1}.entityArray .elevation-container{border-radius:5px;padding:15px;margin-bottom:15px;margin-top:15px}.entityArray .array-headline{padding-bottom:10px}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}.entityArray mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.entityArray .mat-column-select{flex:0 0 75px}.entityArray .enabled:hover{cursor:pointer}.entityArray .array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}.hasMany button{width:100%;height:56px;line-height:24px;font-size:16px}.hasMany .title{text-align:center}.hasMany .elevation-container{border-radius:5px;padding:5px;margin-bottom:15px}.hasMany .mat-column-select{flex:0 0 75px}.hasMany .enabled:hover{cursor:pointer}\n"] }]
|
|
714
|
-
}], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i0.EnvironmentInjector }, { type: i2.Router }, { type: undefined, decorators: [{
|
|
715
|
-
type: Inject,
|
|
716
|
-
args: [NGX_GET_VALIDATION_ERROR_MESSAGE]
|
|
717
|
-
}] }, { type: i3.HttpClient }]; }, propDecorators: { entity: [{
|
|
718
|
-
type: Input
|
|
719
|
-
}], propertyKey: [{
|
|
720
|
-
type: Input
|
|
721
|
-
}], getValidationErrorMessage: [{
|
|
722
|
-
type: Input
|
|
723
|
-
}], hideOmitForCreate: [{
|
|
724
|
-
type: Input
|
|
725
|
-
}], hideOmitForEdit: [{
|
|
726
|
-
type: Input
|
|
727
|
-
}], validEmpty: [{
|
|
728
|
-
type: Input
|
|
729
|
-
}], isReadOnly: [{
|
|
730
|
-
type: Input
|
|
731
|
-
}], inputChangeEvent: [{
|
|
732
|
-
type: Output
|
|
733
|
-
}], addArrayItemDialog: [{
|
|
734
|
-
type: ViewChild,
|
|
735
|
-
args: ['addArrayItemDialog']
|
|
736
|
-
}], editArrayItemDialog: [{
|
|
737
|
-
type: ViewChild,
|
|
738
|
-
args: ['editArrayItemDialog']
|
|
739
|
-
}], hasManyPaginator: [{
|
|
740
|
-
type: ViewChild,
|
|
741
|
-
args: [MatPaginator, { static: true }]
|
|
742
|
-
}], hasManySort: [{
|
|
743
|
-
type: ViewChild,
|
|
744
|
-
args: [MatSort, { static: true }]
|
|
745
|
-
}], hasManyFilter: [{
|
|
746
|
-
type: ViewChild,
|
|
747
|
-
args: ['filter', { static: true }]
|
|
748
|
-
}], createHasManyDialog: [{
|
|
749
|
-
type: ViewChild,
|
|
750
|
-
args: ['createHasManyDialog']
|
|
751
|
-
}], editHasManyDialog: [{
|
|
752
|
-
type: ViewChild,
|
|
753
|
-
args: ['editHasManyDialog']
|
|
754
|
-
}] } });
|
|
755
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW1hdGVyaWFsLWVudGl0eS9zcmMvY29tcG9uZW50cy9pbnB1dC9pbnB1dC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbWF0ZXJpYWwtZW50aXR5L3NyYy9jb21wb25lbnRzL2lucHV0L2lucHV0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxtQkFBbUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFNUksT0FBTyxFQUFFLFNBQVMsRUFBZ0IsTUFBTSwwQkFBMEIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDM0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzdELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3RDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQU01RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDdkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDekUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHdDQUF3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LEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFHcEMsYUFBYTtzQkFEWixTQUFTO3VCQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBUXJDLG1CQUFtQjtzQkFEbEIsU0FBUzt1QkFBQyxxQkFBcUI7Z0JBSWhDLGlCQUFpQjtzQkFEaEIsU0FBUzt1QkFBQyxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTZWxlY3Rpb25Nb2RlbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBFbnZpcm9ubWVudEluamVjdG9yLCBFdmVudEVtaXR0ZXIsIEluamVjdCwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBUZW1wbGF0ZVJlZiwgVmlld0NoaWxkLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5nTW9kZWwgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBNYXREaWFsb2csIE1hdERpYWxvZ1JlZiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBNYXRQYWdpbmF0b3IgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9wYWdpbmF0b3InO1xuaW1wb3J0IHsgTWF0U29ydCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NvcnQnO1xuaW1wb3J0IHsgTWF0VGFibGVEYXRhU291cmNlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFibGUnO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IGZpcnN0VmFsdWVGcm9tIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBCYXNlRW50aXR5VHlwZSB9IGZyb20gJy4uLy4uL2NsYXNzZXMvZW50aXR5Lm1vZGVsJztcbmltcG9ydCB7IEVkaXRBcnJheUl0ZW1EaWFsb2dEYXRhSW50ZXJuYWwsIEVudGl0eUFycmF5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgfSBmcm9tICcuLi8uLi9kZWNvcmF0b3JzL2FycmF5L2FycmF5LWRlY29yYXRvci1pbnRlcm5hbC5kYXRhJztcbmltcG9ydCB7IERlY29yYXRvclR5cGVzIH0gZnJvbSAnLi4vLi4vZGVjb3JhdG9ycy9iYXNlL2RlY29yYXRvci10eXBlcy5lbnVtJztcbmltcG9ydCB7IERyb3Bkb3duVmFsdWUgfSBmcm9tICcuLi8uLi9kZWNvcmF0b3JzL2Jhc2UvZHJvcGRvd24tdmFsdWUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFByb3BlcnR5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgfSBmcm9tICcuLi8uLi9kZWNvcmF0b3JzL2Jhc2UvcHJvcGVydHktZGVjb3JhdG9yLWludGVybmFsLmRhdGEnO1xuaW1wb3J0IHsgSGFzTWFueURlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vLi4vZGVjb3JhdG9ycy9oYXMtbWFueS9oYXMtbWFueS1kZWNvcmF0b3ItaW50ZXJuYWwuZGF0YSc7XG5pbXBvcnQgeyBEZWZhdWx0T2JqZWN0RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgfSBmcm9tICcuLi8uLi9kZWNvcmF0b3JzL29iamVjdC9vYmplY3QtZGVjb3JhdG9yLWludGVybmFsLmRhdGEnO1xuaW1wb3J0IHsgUmVmZXJlbmNlc09uZURlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vLi4vZGVjb3JhdG9ycy9yZWZlcmVuY2VzLW9uZS9yZWZlcmVuY2VzLW9uZS1kZWNvcmF0b3ItaW50ZXJuYWwuZGF0YSc7XG5pbXBvcnQgeyBMb2Rhc2hVdGlsaXRpZXMgfSBmcm9tICcuLi8uLi9lbmNhcHN1bGF0aW9uL2xvZGFzaC51dGlsaXRpZXMnO1xuaW1wb3J0IHsgUmVmbGVjdFV0aWxpdGllcyB9IGZyb20gJy4uLy4uL2VuY2Fwc3VsYXRpb24vcmVmbGVjdC51dGlsaXRpZXMnO1xuaW1wb3J0IHsgZGVmYXVsdEZhbHNlIH0gZnJvbSAnLi4vLi4vZnVuY3Rpb25zL2RlZmF1bHQtZmFsc2UuZnVuY3Rpb24nO1xuaW1wb3J0IHsgRW50aXR5U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2VudGl0eS5zZXJ2aWNlJztcbmltcG9ydCB7IERhdGVVdGlsaXRpZXMgfSBmcm9tICcuLi8uLi91dGlsaXRpZXMvZGF0ZS51dGlsaXRpZXMnO1xuaW1wb3J0IHsgRW50aXR5VGFiLCBFbnRpdHlVdGlsaXRpZXMgfSBmcm9tICcuLi8uLi91dGlsaXRpZXMvZW50aXR5LnV0aWxpdGllcyc7XG5pbXBvcnQgeyBTZWxlY3Rpb25VdGlsaXRpZXMgfSBmcm9tICcuLi8uLi91dGlsaXRpZXMvc2VsZWN0aW9uLnV0aWxpdGllcyc7XG5pbXBvcnQgeyBDb25maXJtRGlhbG9nRGF0YUJ1aWxkZXIsIENvbmZpcm1EaWFsb2dEYXRhSW50ZXJuYWwgfSBmcm9tICcuLi9jb25maXJtLWRpYWxvZy9jb25maXJtLWRpYWxvZy1kYXRhLmJ1aWxkZXInO1xuaW1wb3J0IHsgTmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCB9IGZyb20gJy4uL2NvbmZpcm0tZGlhbG9nL2NvbmZpcm0tZGlhbG9nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOR1hfR0VUX1ZBTElEQVRJT05fRVJST1JfTUVTU0FHRSB9IGZyb20gJy4uL2dldC12YWxpZGF0aW9uLWVycm9yLW1lc3NhZ2UuZnVuY3Rpb24nO1xuaW1wb3J0IHsgQ3JlYXRlRGlhbG9nRGF0YUJ1aWxkZXIsIENyZWF0ZURpYWxvZ0RhdGFJbnRlcm5hbCB9IGZyb20gJy4uL3RhYmxlL2NyZWF0ZS1kaWFsb2cvY3JlYXRlLWRpYWxvZy1kYXRhLmJ1aWxkZXInO1xuaW1wb3J0IHsgRGlzcGxheUNvbHVtbiB9IGZyb20gJy4uL3RhYmxlL3RhYmxlLWRhdGEnO1xuaW1wb3J0IHsgQmFzZVRhYmxlQWN0aW9uSW50ZXJuYWwsIFRhYmxlQWN0aW9uSW50ZXJuYWwgfSBmcm9tICcuLi90YWJsZS90YWJsZS1kYXRhLmJ1aWxkZXInO1xuXG4vKipcbiAqIFRoZSBkZWZhdWx0IGlucHV0IGNvbXBvbmVudC4gSXQgZ2V0cyB0aGUgbWV0YWRhdGEgb2YgdGhlIHByb3BlcnR5IGZyb20gdGhlIGdpdmVuIEBJbnB1dCBcImVudGl0eVwiIGFuZCBASW5wdXQgXCJwcm9wZXJ0eUtleVwiXG4gKiBhbmQgZGlzcGxheXMgdGhlIGlucHV0IGZpZWxkIGFjY29yZGluZ2x5LlxuICpcbiAqIFlvdSBjYW4gYWxzbyBkZWZpbmUgYSBtZXRob2QgdGhhdCBnZW5lcmF0ZXMgZXJyb3ItbWVzc2FnZXMgYW5kIGlmIHRoZSBpbnB1dCBzaG91bGQgYmUgaGlkZGVuIHdoZW4gaXRzIG1ldGFkYXRhIHNheXNcbiAqIHRoYXQgaXQgc2hvdWxkIGJlIG9taXR0ZWQgZm9yIGNyZWF0aW5nIG9yIHVwZGF0aW5nLlxuICogVGhlIGxhc3QgcGFydCBiZWluZyBtb3N0bHkgcmVsZXZhbnQgaWYgeW91IHdhbnQgdG8gdXNlIHRoaXMgY29tcG9uZW50IGluc2lkZSBhbiBuZ0Zvci5cbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICduZ3gtbWF0LWVudGl0eS1pbnB1dCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2lucHV0LmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9pbnB1dC5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIE5neE1hdEVudGl0eUlucHV0Q29tcG9uZW50PEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4gaW1wbGVtZW50cyBPbkluaXQge1xuICAgIC8qKlxuICAgICAqIFRoZSBlbnRpdHkgb24gd2hpY2ggdGhlIHByb3BlcnR5IGV4aXN0cy4gVXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSBcInByb3BlcnR5S2V5XCJcbiAgICAgKiB0byBkZXRlcm1pbmUgdGhlIHByb3BlcnR5IGZvciB3aGljaCB0aGUgaW5wdXQgc2hvdWxkIGJlIGdlbmVyYXRlZC5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGVudGl0eT86IEVudGl0eVR5cGU7XG4gICAgaW50ZXJuYWxFbnRpdHkhOiBFbnRpdHlUeXBlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGdlbmVyYXRlIHRoZSBpbnB1dCBmb3IuIFVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUgXCJlbnRpdHlcIi5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHByb3BlcnR5S2V5Pzoga2V5b2YgRW50aXR5VHlwZTtcbiAgICBpbnRlcm5hbFByb3BlcnR5S2V5IToga2V5b2YgRW50aXR5VHlwZTtcblxuICAgIC8qKlxuICAgICAqIChvcHRpb25hbCkgQSBjdXN0b20gZnVuY3Rpb24gdG8gZ2VuZXJhdGUgdGhlIGVycm9yLW1lc3NhZ2UgZm9yIGludmFsaWQgaW5wdXRzLlxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZT86IChtb2RlbDogTmdNb2RlbCkgPT4gc3RyaW5nO1xuICAgIGludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZSE6IChtb2RlbDogTmdNb2RlbCkgPT4gc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0byBoaWRlIGEgdmFsdWUgaWYgaXQgaXMgb21pdHRlZCBmb3IgY3JlYXRpb24uXG4gICAgICogSXMgdXNlZCBpbnRlcm5hbGx5IGZvciB0aGUgb2JqZWN0IHByb3BlcnR5LlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGhpZGVPbWl0Rm9yQ3JlYXRlPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdG8gaGlkZSBhIHZhbHVlIGlmIGl0IGlzIG9taXR0ZWQgZm9yIGVkaXRpbmcuXG4gICAgICogSXMgdXNlZCBpbnRlcm5hbGx5IGZvciB0aGUgb2JqZWN0IHByb3BlcnR5LlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGhpZGVPbWl0Rm9yRWRpdD86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIG9yIG5vdCBhbiBlbXB0eSB2YWx1ZSBzaG91bGQgYmUgdmFsaWQuXG4gICAgICogSXMgdXNlZCBpbnRlcm5hbGx5IGZvciB0aGUgb2JqZWN0IHByb3BlcnR5LlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgdW5kZWZpbmVkXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICB2YWxpZEVtcHR5PzogYm9vbGVhbjsgLy8gVE9ET1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBvciBub3QgdGhlIGlucHV0IHNob3VsZCBiZSByZWFkb25seS5cbiAgICAgKiBJbiB0aGF0IGNhc2UgaXQgaXMgZGlzYWJsZWQsIGJ1dCBtb3N0IG9mIHRoZSBkZWZhdWx0IHN0eWxpbmcgaXMgb3ZlcndyaXR0ZW4uXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgaXNSZWFkT25seT86IGJvb2xlYW47XG4gICAgaW50ZXJuYWxJc1JlYWRPbmx5ITogYm9vbGVhbjtcblxuICAgIEBPdXRwdXQoKVxuICAgIGlucHV0Q2hhbmdlRXZlbnQ6IEV2ZW50RW1pdHRlcjx2b2lkPiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAgIEBWaWV3Q2hpbGQoJ2FkZEFycmF5SXRlbURpYWxvZycpXG4gICAgYWRkQXJyYXlJdGVtRGlhbG9nITogVGVtcGxhdGVSZWY8dW5rbm93bj47XG4gICAgYWRkQXJyYXlJdGVtRGlhbG9nUmVmITogTWF0RGlhbG9nUmVmPHVua25vd24+O1xuXG4gICAgQFZpZXdDaGlsZCgnZWRpdEFycmF5SXRlbURpYWxvZycpXG4gICAgZWRpdEFycmF5SXRlbURpYWxvZyE6IFRlbXBsYXRlUmVmPHVua25vd24+O1xuICAgIGVkaXRBcnJheUl0ZW1EaWFsb2dSZWYhOiBNYXREaWFsb2dSZWY8dW5rbm93bj47XG5cbiAgICB0eXBlITogRGVjb3JhdG9yVHlwZXM7XG4gICAgbWV0YWRhdGEhOiBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsO1xuXG4gICAgbWV0YWRhdGFEZWZhdWx0T2JqZWN0ITogRGVmYXVsdE9iamVjdERlY29yYXRvckNvbmZpZ0ludGVybmFsPEVudGl0eVR5cGU+O1xuICAgIG9iamVjdFByb3BlcnR5ITogRW50aXR5VHlwZTtcbiAgICBvYmplY3RQcm9wZXJ0eVRhYnMhOiBFbnRpdHlUYWI8RW50aXR5VHlwZT5bXTtcblxuICAgIG1ldGFkYXRhRW50aXR5QXJyYXkhOiBFbnRpdHlBcnJheURlY29yYXRvckNvbmZpZ0ludGVybmFsPEVudGl0eVR5cGU+O1xuICAgIGVudGl0eUFycmF5VmFsdWVzITogRW50aXR5VHlwZVtdO1xuICAgIGFycmF5SXRlbSE6IEVudGl0eVR5cGU7XG4gICAgYXJyYXlJdGVtUHJpb3JDaGFuZ2VzITogRW50aXR5VHlwZTtcbiAgICBhcnJheUl0ZW1JbmxpbmVUYWJzITogRW50aXR5VGFiPEVudGl0eVR5cGU+W107XG4gICAgZW50aXR5QXJyYXlEYXRhU291cmNlITogTWF0VGFibGVEYXRhU291cmNlPEVudGl0eVR5cGU+O1xuICAgIGVudGl0eUFycmF5U2VsZWN0aW9uOiBTZWxlY3Rpb25Nb2RlbDxFbnRpdHlUeXBlPiA9IG5ldyBTZWxlY3Rpb25Nb2RlbDxFbnRpdHlUeXBlPih0cnVlLCBbXSk7XG4gICAgZW50aXR5QXJyYXlEaXNwbGF5ZWRDb2x1bW5zITogc3RyaW5nW107XG4gICAgaXNBcnJheUl0ZW1WYWxpZDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIGlzQXJyYXlJdGVtRGlydHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBpbmRleE9mRWRpdGVkQXJyYXlJdGVtITogbnVtYmVyO1xuICAgIGFkZEFycmF5SXRlbURpYWxvZ0RhdGEhOiBDcmVhdGVEaWFsb2dEYXRhSW50ZXJuYWw7XG4gICAgYXJyYXlJdGVtRGlhbG9nVGFicyE6IEVudGl0eVRhYjxFbnRpdHlUeXBlPltdO1xuICAgIGVkaXRBcnJheUl0ZW1EaWFsb2dEYXRhITogRWRpdEFycmF5SXRlbURpYWxvZ0RhdGFJbnRlcm5hbDxFbnRpdHlUeXBlPjtcblxuICAgIG1ldGFkYXRhSGFzTWFueSE6IEhhc01hbnlEZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlLCBFbnRpdHlUeXBlPjtcbiAgICBoYXNNYW55SXNMb2FkaW5nOiBib29sZWFuID0gdHJ1ZTtcbiAgICBAVmlld0NoaWxkKE1hdFBhZ2luYXRvciwgeyBzdGF0aWM6IHRydWUgfSlcbiAgICBoYXNNYW55UGFnaW5hdG9yITogTWF0UGFnaW5hdG9yO1xuICAgIEBWaWV3Q2hpbGQoTWF0U29ydCwgeyBzdGF0aWM6IHRydWUgfSlcbiAgICBoYXNNYW55U29ydCE6IE1hdFNvcnQ7XG4gICAgQFZpZXdDaGlsZCgnZmlsdGVyJywgeyBzdGF0aWM6IHRydWUgfSlcbiAgICBoYXNNYW55RmlsdGVyITogc3RyaW5nO1xuICAgIGRpc3BsYXllZEhhc01hbnlDb2x1bW5zITogc3RyaW5nW107XG4gICAgaGFzTWFueURhdGFTb3VyY2U6IE1hdFRhYmxlRGF0YVNvdXJjZTxFbnRpdHlUeXBlPiA9IG5ldyBNYXRUYWJsZURhdGFTb3VyY2UoKTtcbiAgICBoYXNNYW55U2VsZWN0aW9uOiBTZWxlY3Rpb25Nb2RlbDxFbnRpdHlUeXBlPiA9IG5ldyBTZWxlY3Rpb25Nb2RlbDxFbnRpdHlUeXBlPih0cnVlLCBbXSk7XG4gICAgaGFzTWFueUltcG9ydEFjdGlvbiE6IEJhc2VUYWJsZUFjdGlvbkludGVybmFsO1xuICAgIHByaXZhdGUgaGFzTWFueUVudGl0eVNlcnZpY2UhOiBFbnRpdHlTZXJ2aWNlPEVudGl0eVR5cGU+O1xuICAgIEBWaWV3Q2hpbGQoJ2NyZWF0ZUhhc01hbnlEaWFsb2cnKVxuICAgIGNyZWF0ZUhhc01hbnlEaWFsb2chOiBUZW1wbGF0ZVJlZjx1bmtub3duPjtcbiAgICBjcmVhdGVIYXNNYW55RGlhbG9nUmVmITogTWF0RGlhbG9nUmVmPHVua25vd24+O1xuICAgIEBWaWV3Q2hpbGQoJ2VkaXRIYXNNYW55RGlhbG9nJylcbiAgICBlZGl0SGFzTWFueURpYWxvZyE6IFRlbXBsYXRlUmVmPHVua25vd24+O1xuICAgIGVkaXRIYXNNYW55RGlhbG9nUmVmITogTWF0RGlhbG9nUmVmPHVua25vd24+O1xuICAgIGhhc01hbnlFbnRpdHkhOiBFbnRpdHlUeXBlO1xuICAgIGhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMhOiBFbnRpdHlUeXBlO1xuICAgIGlzSGFzTWFueUVudGl0eVZhbGlkOiBib29sZWFuID0gZmFsc2U7XG4gICAgaXNIYXNNYW55RW50aXR5RGlydHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBoYXNNYW55QWxsb3dDcmVhdGUhOiBib29sZWFuO1xuICAgIGhhc01hbnlDcmVhdGVUYWJzITogRW50aXR5VGFiPEVudGl0eVR5cGU+W107XG4gICAgaGFzTWFueVVwZGF0ZVRhYnMhOiBFbnRpdHlUYWI8RW50aXR5VHlwZT5bXTtcbiAgICBwcml2YXRlIGhhc01hbnlDcmVhdGVCYXNlVXJsITogc3RyaW5nO1xuXG4gICAgbWV0YWRhdGFSZWZlcmVuY2VzT25lITogUmVmZXJlbmNlc09uZURlY29yYXRvckNvbmZpZ0ludGVybmFsPEVudGl0eVR5cGU+O1xuICAgIHJlZmVyZW5jZXNPbmVPYmplY3QhOiBFbnRpdHlUeXBlO1xuICAgIHJlZmVyZW5jZXNPbmVQcm9wZXJ0eVRhYnMhOiBFbnRpdHlUYWI8RW50aXR5VHlwZT5bXTtcbiAgICByZWZlcmVuY2VzT25lQWxsUmVmZXJlbmNlZEVudGl0aWVzITogRW50aXR5VHlwZVtdO1xuICAgIHJlZmVyZW5jZXNPbmVEcm9wZG93blZhbHVlcyE6IERyb3Bkb3duVmFsdWU8c3RyaW5nPltdO1xuXG4gICAgcmVhZG9ubHkgRGVjb3JhdG9yVHlwZXM6IHR5cGVvZiBEZWNvcmF0b3JUeXBlcyA9IERlY29yYXRvclR5cGVzO1xuXG4gICAgRW50aXR5VXRpbGl0aWVzOiB0eXBlb2YgRW50aXR5VXRpbGl0aWVzID0gRW50aXR5VXRpbGl0aWVzO1xuICAgIERhdGVVdGlsaXRpZXM6IHR5cGVvZiBEYXRlVXRpbGl0aWVzID0gRGF0ZVV0aWxpdGllcztcbiAgICBTZWxlY3Rpb25VdGlsaXRpZXM6IHR5cGVvZiBTZWxlY3Rpb25VdGlsaXRpZXMgPSBTZWxlY3Rpb25VdGlsaXRpZXM7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBkaWFsb2c6IE1hdERpYWxvZyxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBpbmplY3RvcjogRW52aXJvbm1lbnRJbmplY3RvcixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZXI6IFJvdXRlcixcbiAgICAgICAgQEluamVjdChOR1hfR0VUX1ZBTElEQVRJT05fRVJST1JfTUVTU0FHRSlcbiAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IGRlZmF1bHRHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlOiAobW9kZWw6IE5nTW9kZWwpID0+IHN0cmluZyxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBodHRwOiBIdHRwQ2xpZW50XG4gICAgKSB7fVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBpbnB1dCB3aXRoIHRoZSBnaXZlbiBrZXkgb24gdGhlIGdpdmVuIHByb3BlcnR5IGlzIHJlYWRvbmx5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHByb3BlcnR5IC0gVGhlIHByb3BlcnR5IG9uIHdoaWNoIHRvIGNoZWNrIHRoZSBpbnB1dC5cbiAgICAgKiBAcGFyYW0ga2V5IC0gVGhlIGtleSBmb3IgdGhlIGlucHV0IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIFdoZXRoZXIgb3Igbm90IHRoZSBpbnB1dCBpcyByZWFkb25seS5cbiAgICAgKi9cbiAgICBpc1Byb3BlcnR5UmVhZE9ubHkocHJvcGVydHk6IEVudGl0eVR5cGUsIGtleToga2V5b2YgRW50aXR5VHlwZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbmplY3Rvci5ydW5JbkNvbnRleHQoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJuYWxJc1JlYWRPbmx5IHx8IHRoaXMubWV0YWRhdGFEZWZhdWx0T2JqZWN0Py5pc1JlYWRPbmx5KHByb3BlcnR5KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWV0YWRhdGE6IFByb3BlcnR5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YShwcm9wZXJ0eSwga2V5KTtcbiAgICAgICAgICAgIHJldHVybiBtZXRhZGF0YS5pc1JlYWRPbmx5KHByb3BlcnR5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBpcyBuZWVkZWQgZm9yIHRoZSBpbnB1dHMgdG8gd29yayBpbnNpZGUgYW4gbmdGb3IuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5kZXggLSBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgaW4gdGhlIG5nRm9yLlxuICAgICAqIEByZXR1cm5zIFRoZSBpbmRleC5cbiAgICAgKi9cbiAgICB0cmFja0J5Rm4oaW5kZXg6IHVua25vd24pOiB1bmtub3duIHtcbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHZhbHVlIHRvIGRpc3BsYXkgaW4gdGhlIGNvbHVtbi5cbiAgICAgKiBSdW5zIGluIGVudmlyb25tZW50IGNvbnRleHQgdG8gZW5hYmxlIGluamVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBUaGUgZW50aXR5IHRvIGdldCB0aGUgdmFsdWUgZnJvbS5cbiAgICAgKiBAcGFyYW0gZGlzcGxheUNvbHVtbiAtIFRoZSBkaXNwbGF5IGNvbHVtbiB0byBnZXQgdGhlIHZhbHVlIGZyb20uXG4gICAgICogQHJldHVybnMgVGhlIHZhbHVlIG9mIHRoZSBkaXNwbGF5IGNvbHVtbi5cbiAgICAgKi9cbiAgICBnZXREaXNwbGF5Q29sdW1uVmFsdWUoZW50aXR5OiBFbnRpdHlUeXBlLCBkaXNwbGF5Q29sdW1uOiBEaXNwbGF5Q29sdW1uPEVudGl0eVR5cGU+KTogdW5rbm93biB7XG4gICAgICAgIHJldHVybiB0aGlzLmluamVjdG9yLnJ1bkluQ29udGV4dCgoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZGlzcGxheUNvbHVtbi52YWx1ZShlbnRpdHkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmVudGl0eSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHJlcXVpcmVkIElucHV0IGRhdGEgXCJlbnRpdHlcIicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW50ZXJuYWxFbnRpdHkgPSB0aGlzLmVudGl0eTtcblxuICAgICAgICBpZiAodGhpcy5wcm9wZXJ0eUtleSA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgcmVxdWlyZWQgSW5wdXQgZGF0YSBcInByb3BlcnR5S2V5XCInKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmludGVybmFsUHJvcGVydHlLZXkgPSB0aGlzLnByb3BlcnR5S2V5O1xuXG4gICAgICAgIHRoaXMuaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlID0gdGhpcy5nZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlID8/IHRoaXMuZGVmYXVsdEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2U7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxJc1JlYWRPbmx5ID0gdGhpcy5pc1JlYWRPbmx5ID8/IGZhbHNlO1xuXG4gICAgICAgIHRoaXMudHlwZSA9IEVudGl0eVV0aWxpdGllcy5nZXRQcm9wZXJ0eVR5cGUodGhpcy5pbnRlcm5hbEVudGl0eSwgdGhpcy5pbnRlcm5hbFByb3BlcnR5S2V5KTtcbiAgICAgICAgaWYgKHRoaXMudmFsaWRFbXB0eSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRNZXRhZGF0YTogUHJvcGVydHlEZWNvcmF0b3JDb25maWdJbnRlcm5hbCA9IFJlZmxlY3RVdGlsaXRpZXMuZ2V0TWV0YWRhdGEoJ21ldGFkYXRhJywgdGhpcy5pbnRlcm5hbEVudGl0eSwgdGhpcy5pbnRlcm5hbFByb3BlcnR5S2V5KSBhcyBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgICAgICAgIFJlZmxlY3RVdGlsaXRpZXMuZGVmaW5lTWV0YWRhdGEoJ21ldGFkYXRhJywgeyAuLi5jdXJyZW50TWV0YWRhdGEsIHJlcXVpcmVkOiBkZWZhdWx0RmFsc2UgfSwgdGhpcy5pbnRlcm5hbEVudGl0eSwgdGhpcy5pbnRlcm5hbFByb3BlcnR5S2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1ldGFkYXRhID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5TWV0YWRhdGEodGhpcy5pbnRlcm5hbEVudGl0eSwgdGhpcy5pbnRlcm5hbFByb3BlcnR5S2V5LCB0aGlzLnR5cGUpO1xuXG4gICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLk9CSkVDVDpcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRPYmplY3RJbnB1dCgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5BUlJBWTpcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRFbnRpdHlBcnJheSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5IQVNfTUFOWTpcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRIYXNNYW55KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLlJFRkVSRU5DRVNfT05FOlxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdFJlZmVyZW5jZXNPbmUoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRSZWZlcmVuY2VzT25lKCk6IHZvaWQge1xuICAgICAgICB0aGlzLm1ldGFkYXRhUmVmZXJlbmNlc09uZSA9IHRoaXMubWV0YWRhdGEgYXMgUmVmZXJlbmNlc09uZURlY29yYXRvckNvbmZpZ0ludGVybmFsPEVudGl0eVR5cGU+O1xuXG4gICAgICAgIHZvaWQgdGhpcy5pbmplY3Rvci5ydW5JbkNvbnRleHQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VzT25lQWxsUmVmZXJlbmNlZEVudGl0aWVzID0gYXdhaXQgdGhpcy5tZXRhZGF0YVJlZmVyZW5jZXNPbmUuZ2V0UmVmZXJlbmNlZEVudGl0aWVzKCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VzT25lRHJvcGRvd25WYWx1ZXMgPSB0aGlzLm1ldGFkYXRhUmVmZXJlbmNlc09uZS5nZXREcm9wZG93blZhbHVlcyhMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHRoaXMucmVmZXJlbmNlc09uZUFsbFJlZmVyZW5jZWRFbnRpdGllcykpO1xuICAgICAgICAgICAgdGhpcy5zZXRSZWZlcmVuY2VzT25lT2JqZWN0KCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdEhhc01hbnkoKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWV0YWRhdGFIYXNNYW55ID0gdGhpcy5tZXRhZGF0YSBhcyBIYXNNYW55RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZSwgRW50aXR5VHlwZT47XG4gICAgICAgIHRoaXMuaGFzTWFueUltcG9ydEFjdGlvbiA9IG5ldyBCYXNlVGFibGVBY3Rpb25JbnRlcm5hbCh7XG4gICAgICAgICAgICAuLi50aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuaW1wb3J0QWN0aW9uRGF0YSxcbiAgICAgICAgICAgIGFjdGlvbjogKCkgPT4gdGhpcy5zdGFydEltcG9ydEpzb24oKVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmluamVjdG9yLnJ1bkluQ29udGV4dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmhhc01hbnlBbGxvd0NyZWF0ZSA9IHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5hbGxvd0NyZWF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5oYXNNYW55RW50aXR5U2VydmljZSA9IGluamVjdDxFbnRpdHlTZXJ2aWNlPEVudGl0eVR5cGU+Pih0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuRW50aXR5U2VydmljZUNsYXNzKTtcbiAgICAgICAgICAgIHRoaXMuaGFzTWFueUNyZWF0ZUJhc2VVcmwgPSB0aGlzLm1ldGFkYXRhSGFzTWFueS5jcmVhdGVCYXNlVXJsKHRoaXMuaW50ZXJuYWxFbnRpdHksIHRoaXMubWV0YWRhdGFIYXNNYW55KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZ2l2ZW5EaXNwbGF5Q29sdW1uczogc3RyaW5nW10gPSB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuZGlzcGxheUNvbHVtbnMubWFwKCh2KSA9PiB2LmRpc3BsYXlOYW1lKTtcbiAgICAgICAgaWYgKHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50YWJsZUFjdGlvbnMuZmlsdGVyKHRBID0+IHRBLnR5cGUgPT09ICdtdWx0aS1zZWxlY3QnKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheWVkSGFzTWFueUNvbHVtbnMgPSBbJ3NlbGVjdCddLmNvbmNhdChnaXZlbkRpc3BsYXlDb2x1bW5zKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheWVkSGFzTWFueUNvbHVtbnMgPSBnaXZlbkRpc3BsYXlDb2x1bW5zO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5oYXNNYW55RGF0YVNvdXJjZS5zb3J0aW5nRGF0YUFjY2Vzc29yID0gKGVudGl0eTogRW50aXR5VHlwZSwgaGVhZGVyOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmluamVjdG9yLnJ1bkluQ29udGV4dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmRpc3BsYXlDb2x1bW5zLmZpbmQoKGRwKSA9PiBkcC5kaXNwbGF5TmFtZSA9PT0gaGVhZGVyKT8udmFsdWUoZW50aXR5KSBhcyBzdHJpbmc7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYXNNYW55RGF0YVNvdXJjZS5zb3J0ID0gdGhpcy5oYXNNYW55U29ydDtcbiAgICAgICAgdGhpcy5oYXNNYW55RGF0YVNvdXJjZS5maWx0ZXJQcmVkaWNhdGUgPSAoZW50aXR5OiBFbnRpdHlUeXBlLCBmaWx0ZXI6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc2VhcmNoU3RyOiBzdHJpbmcgPSB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuc2VhcmNoU3RyaW5nKGVudGl0eSk7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRTZWFyY2hTdHJpbmc6IHN0cmluZyA9IHNlYXJjaFN0ci50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkRmlsdGVyU3RyaW5nOiBzdHJpbmcgPSBmaWx0ZXIudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXR0ZWRTZWFyY2hTdHJpbmcuaW5jbHVkZXMoZm9ybWF0dGVkRmlsdGVyU3RyaW5nKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYXNNYW55RGF0YVNvdXJjZS5maWx0ZXIgPSB0aGlzLmhhc01hbnlGaWx0ZXI7XG4gICAgICAgIHRoaXMuaGFzTWFueURhdGFTb3VyY2UucGFnaW5hdG9yID0gdGhpcy5oYXNNYW55UGFnaW5hdG9yO1xuXG4gICAgICAgIHRoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UuZW50aXRpZXNTdWJqZWN0LnN1YnNjcmliZSgoZW50aXRpZXMpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaGFzTWFueURhdGFTb3VyY2UuZGF0YSA9IGVudGl0aWVzO1xuICAgICAgICAgICAgdGhpcy5oYXNNYW55U2VsZWN0aW9uLmNsZWFyKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmluamVjdG9yLnJ1bkluQ29udGV4dCgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZWFkQmFzZVVybDogc3RyaW5nID0gdGhpcy5tZXRhZGF0YUhhc01hbnkucmVhZEJhc2VVcmwodGhpcy5pbnRlcm5hbEVudGl0eSwgdGhpcy5tZXRhZGF0YUhhc01hbnkpO1xuICAgICAgICAgICAgdm9pZCB0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLnJlYWQocmVhZEJhc2VVcmwpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFzTWFueUlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdEVudGl0eUFycmF5KCk6IHZvaWQge1xuICAgICAgICB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkgPSB0aGlzLm1ldGFkYXRhIGFzIEVudGl0eUFycmF5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZT47XG4gICAgICAgIGlmICh0aGlzLmludGVybmFsRW50aXR5W3RoaXMuaW50ZXJuYWxQcm9wZXJ0eUtleV0gPT0gbnVsbCkge1xuICAgICAgICAgICAgKHRoaXMuaW50ZXJuYWxFbnRpdHlbdGhpcy5pbnRlcm5hbFByb3BlcnR5S2V5XSBhcyBFbnRpdHlUeXBlW10pID0gW107XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbnRpdHlBcnJheVZhbHVlcyA9IHRoaXMuaW50ZXJuYWxFbnRpdHlbdGhpcy5pbnRlcm5hbFByb3BlcnR5S2V5XSBhcyBFbnRpdHlUeXBlW107XG4gICAgICAgIGlmICghdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LmNyZWF0ZUlubGluZSAmJiAhdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LmNyZWF0ZURpYWxvZ0RhdGEpIHtcbiAgICAgICAgICAgIHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5jcmVhdGVEaWFsb2dEYXRhID0ge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAnQWRkJ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBnaXZlbkRpc3BsYXlDb2x1bW5zOiBzdHJpbmdbXSA9IHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5kaXNwbGF5Q29sdW1ucy5tYXAoKHYpID0+IHYuZGlzcGxheU5hbWUpO1xuICAgICAgICBpZiAoZ2l2ZW5EaXNwbGF5Q29sdW1ucy5maW5kKHMgPT4gcyA9PT0gJ3NlbGVjdCcpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgYFRoZSBuYW1lIFwic2VsZWN0XCIgZm9yIGEgZGlzcGxheSBjb2x1bW4gaXMgcmVzZXJ2ZWQuXG4gICAgICAgICAgICAgICAgUGxlYXNlIGNob29zZSBhIGRpZmZlcmVudCBuYW1lLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbnRpdHlBcnJheURpc3BsYXllZENvbHVtbnMgPSB0aGlzLmludGVybmFsSXNSZWFkT25seSA/IGdpdmVuRGlzcGxheUNvbHVtbnMgOiBbJ3NlbGVjdCddLmNvbmNhdChnaXZlbkRpc3BsYXlDb2x1bW5zKTtcbiAgICAgICAgdGhpcy5lbnRpdHlBcnJheURhdGFTb3VyY2UgPSBuZXcgTWF0VGFibGVEYXRhU291cmNlKCk7XG4gICAgICAgIHRoaXMuZW50aXR5QXJyYXlEYXRhU291cmNlLmRhdGEgPSB0aGlzLmVudGl0eUFycmF5VmFsdWVzO1xuICAgICAgICB0aGlzLmFycmF5SXRlbSA9IG5ldyB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuRW50aXR5Q2xhc3MoKTtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW1QcmlvckNoYW5nZXMgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHRoaXMuYXJyYXlJdGVtKTtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW1JbmxpbmVUYWJzID0gRW50aXR5VXRpbGl0aWVzLmdldEVudGl0eVRhYnModGhpcy5hcnJheUl0ZW0sIHRydWUpO1xuXG4gICAgICAgIHRoaXMuYWRkQXJyYXlJdGVtRGlhbG9nRGF0YSA9IG5ldyBDcmVhdGVEaWFsb2dEYXRhQnVpbGRlcih0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuY3JlYXRlRGlhbG9nRGF0YSlcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgnY3JlYXRlQnV0dG9uTGFiZWwnLCAnQWRkJylcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgndGl0bGUnLCAnQWRkIHRvIGFycmF5JylcbiAgICAgICAgICAgIC5nZXRSZXN1bHQoKTtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW1EaWFsb2dUYWJzID0gRW50aXR5VXRpbGl0aWVzLmdldEVudGl0eVRhYnModGhpcy5hcnJheUl0ZW0sIHRydWUpO1xuXG4gICAgICAgIHRoaXMuZWRpdEFycmF5SXRlbURpYWxvZ0RhdGEgPSB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuZWRpdERpYWxvZ0RhdGE7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0T2JqZWN0SW5wdXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWV0YWRhdGFEZWZhdWx0T2JqZWN0ID0gdGhpcy5tZXRhZGF0YSBhcyBEZWZhdWx0T2JqZWN0RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZT47XG4gICAgICAgIHRoaXMub2JqZWN0UHJvcGVydHkgPSB0aGlzLmludGVybmFsRW50aXR5W3RoaXMuaW50ZXJuYWxQcm9wZXJ0eUtleV0gYXMgRW50aXR5VHlwZTtcbiAgICAgICAgdGhpcy5vYmplY3RQcm9wZXJ0eVRhYnMgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0RW50aXR5VGFicyhcbiAgICAgICAgICAgIHRoaXMub2JqZWN0UHJvcGVydHksXG4gICAgICAgICAgICB0aGlzLmhpZGVPbWl0Rm9yQ3JlYXRlLFxuICAgICAgICAgICAgdGhpcy5oaWRlT21pdEZvckVkaXQsXG4gICAgICAgICAgICB0aGlzLm1ldGFkYXRhRGVmYXVsdE9iamVjdC5vbWl0XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGFydEltcG9ydEpzb24oKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGlucHV0OiBIVE1MSW5wdXRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgaW5wdXQudHlwZSA9ICdmaWxlJztcbiAgICAgICAgaW5wdXQuYWNjZXB0ID0gJ2FwcGxpY2F0aW9uL2pzb24nO1xuICAgICAgICBpbnB1dC5vbmNoYW5nZSA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGlmIChpbnB1dC5maWxlcykge1xuICAgICAgICAgICAgICAgIHRoaXMuaW1wb3J0SnNvbihpbnB1dC5maWxlc1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGlucHV0LmNsaWNrKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbXBvcnRKc29uKGZpbGU6IEZpbGUpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGlhbG9nRGF0YTogQ29uZmlybURpYWxvZ0RhdGFJbnRlcm5hbCA9IG5ldyBDb25maXJtRGlhbG9nRGF0YUJ1aWxkZXIodGhpcy5oYXNNYW55SW1wb3J0QWN0aW9uLmNvbmZpcm1EaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmltcG9ydEFjdGlvbkRhdGEuY29uZmlybURpYWxvZ0RhdGE/LnRleHQgKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0aXRsZScsIHRoaXMuaGFzTWFueUltcG9ydEFjdGlvbi5kaXNwbGF5TmFtZSlcbiAgICAgICAgICAgIC5nZXRSZXN1bHQoKTtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8Tmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwgYm9vbGVhbj4gPSB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIGRhdGE6IGRpYWxvZ0RhdGEsXG4gICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgICAgICBpZiAocmVzID09IHRydWUpIHtcbiAgICAgICAgICAgICAgICB2b2lkIHRoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UuaW1wb3J0KGZpbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSByZWZlcmVuY2VzIG9uZSBvYmplY3QgdXNpbmcgdGhlIGlucHV0IGlkLlxuICAgICAqL1xuICAgIHNldFJlZmVyZW5jZXNPbmVPYmplY3QoKTogdm9pZCB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgIGNvbnN0IGZvdW5kRW50aXR5OiBFbnRpdHlUeXBlIHwgdW5kZWZpbmVkID0gdGhpcy5tZXRhZGF0YVJlZmVyZW5jZXNPbmUuZ2V0RW50aXR5Rm9ySWQodGhpcy5pbnRlcm5hbEVudGl0eVt0aGlzLmludGVybmFsUHJvcGVydHlLZXldIGFzIHN0cmluZywgdGhpcy5yZWZlcmVuY2VzT25lQWxsUmVmZXJlbmNlZEVudGl0aWVzKTtcbiAgICAgICAgdGhpcy5yZWZlcmVuY2VzT25lT2JqZWN0ID0gbmV3IHRoaXMubWV0YWRhdGFSZWZlcmVuY2VzT25lLkVudGl0eUNsYXNzKGZvdW5kRW50aXR5KTtcbiAgICAgICAgdGhpcy5yZWZlcmVuY2VzT25lUHJvcGVydHlUYWJzID0gRW50aXR5VXRpbGl0aWVzLmdldEVudGl0eVRhYnModGhpcy5yZWZlcmVuY2VzT25lT2JqZWN0KTtcbiAgICAgICAgdGhpcy5lbWl0Q2hhbmdlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRWRpdHMgYW4gZW50aXR5LiBUaGlzIGVpdGhlciBjYWxscyB0aGUgZWRpdC1NZXRob2QgcHJvdmlkZWQgYnkgdGhlIHVzZXIgb3IgdXNlcyBhIGRlZmF1bHQgZWRpdC1kaWFsb2cuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGVudGl0eSB0aGF0IHNob3VsZCBiZSB1cGRhdGVkLlxuICAgICAqIEBwYXJhbSBkQ29sIC0gVGhlIGRpc3BsYXkgY29sdW1uIHRoYXQgd2FzIGNsaWNrZWQgb24uXG4gICAgICogQHRocm93cyBXaGVuIG5vIEVudGl0eUNsYXNzIHdhcyBwcm92aWRlZCwgYXMgYSBuZXcgY2FsbCBpcyBuZWVkZWQgdG8gaW5pdGlhbGl6ZSBtZXRhZGF0YS5cbiAgICAgKi9cbiAgICBlZGl0SGFzTWFueUVudGl0eShlbnRpdHk6IEVudGl0eVR5cGUsIGRDb2w6IERpc3BsYXlDb2x1bW48RW50aXR5VHlwZT4pOiB2b2lkIHtcbiAgICAgICAgaWYgKChkQ29sLmRpc2FibGVDbGljayA9PT0gdHJ1ZSkgfHwgKCF0aGlzLmhhc01hbnlBbGxvd1VwZGF0ZShlbnRpdHkpICYmICF0aGlzLmhhc01hbnlBbGxvd1JlYWQoZW50aXR5KSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5FbnRpdHlDbGFzcykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBcIkVudGl0eUNsYXNzXCIgc3BlY2lmaWVkIGZvciB0aGlzIHRhYmxlJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5lZGl0KSB7XG4gICAgICAgICAgICB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuZWRpdChuZXcgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLkVudGl0eUNsYXNzKGVudGl0eSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuZGVmYXVsdEVkaXQgPT0gJ3BhZ2UnKSB7XG4gICAgICAgICAgICB0aGlzLmVkaXRIYXNNYW55RGVmYXVsdFBhZ2UobmV3IHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5FbnRpdHlDbGFzcyhlbnRpdHkpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2b2lkIHRoaXMuZWRpdEhhc01hbnlEZWZhdWx0RGlhbG9nKG5ldyB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuRW50aXR5Q2xhc3MoZW50aXR5KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB1cGRhdGluZyB0aGUgcHJvdmlkZWQgZW50aXR5IGZyb20gdGhlIGhhcyBtYW55IHByb3BlcnR5IGlzIGFsbG93ZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gQSBzaW5nbGUgdmFsdWUgb2YgdGhlIGhhcyBtYW55IHByb3BlcnR5IHRoYXQgdGhlIHVzZXIgd2FudHMgdG8gZWRpdC5cbiAgICAgKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHVzZXIgY2FuIGVkaXQgdGhlIHByb3ZpZGVkIGVudGl0eSBhbmQgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIGhhc01hbnlBbGxvd1VwZGF0ZShlbnRpdHk6IEVudGl0eVR5cGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5qZWN0b3IucnVuSW5Db250ZXh0KCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuYWxsb3dVcGRhdGUoZW50aXR5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB2aWV3aW5nIHRoZSBwcm92aWRlZCBlbnRpdHkgZnJvbSB0aGUgaGFzIG1hbnkgcHJvcGVydHkgaXMgYWxsb3dlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBBIHNpbmdsZSB2YWx1ZSBvZiB0aGUgaGFzIG1hbnkgcHJvcGVydHkgdGhhdCB0aGUgdXNlciB3YW50cyB0byB2aWV3LlxuICAgICAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgdXNlciBjYW4gdmlldyB0aGUgcHJvdmlkZWQgZW50aXR5IGFuZCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgaGFzTWFueUFsbG93UmVhZChlbnRpdHk6IEVudGl0eVR5cGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5qZWN0b3IucnVuSW5Db250ZXh0KCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuYWxsb3dSZWFkKGVudGl0eSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZGVsZXRpbmcgdGhlIHByb3ZpZGVkIGVudGl0eSBmcm9tIHRoZSBoYXMgbWFueSBwcm9wZXJ0eSBpcyBhbGxvd2VkLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIEEgc2luZ2xlIHZhbHVlIG9mIHRoZSBoYXMgbWFueSBwcm9wZXJ0eSB0aGF0IHRoZSB1c2VyIHdhbnRzIHRvIGRlbGV0ZS5cbiAgICAgKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHVzZXIgY2FuIGRlbGV0ZSB0aGUgcHJvdmlkZWQgZW50aXR5IGFuZCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgaGFzTWFueUFsbG93RGVsZXRlKGVudGl0eTogRW50aXR5VHlwZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbmplY3Rvci5ydW5JbkNvbnRleHQoKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5hbGxvd0RlbGV0ZShlbnRpdHkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGVkaXRIYXNNYW55RGVmYXVsdFBhZ2UoZW50aXR5OiBFbnRpdHlUeXBlKTogdm9pZCB7XG4gICAgICAgIHZvaWQgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycnLCB0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmVkaXRCYXNlUm91dGUsIGVudGl0eVt0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmlkS2V5XV0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZWRpdEhhc01hbnlEZWZhdWx0RGlhbG9nKGVudGl0eTogRW50aXR5VHlwZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmhhc01hbnlFbnRpdHkgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKGVudGl0eSk7XG4gICAgICAgIHRoaXMuaGFzTWFueUVudGl0eVByaW9yQ2hhbmdlcyA9IExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5oYXNNYW55RW50aXR5KTtcbiAgICAgICAgdGhpcy5oYXNNYW55VXBkYXRlVGFicyA9IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKHRoaXMuaGFzTWFueUVudGl0eSwgZmFsc2UsIHRydWUpO1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNrSGFzTWFueUVudGl0eSgpO1xuICAgICAgICB0aGlzLmVkaXRIYXNNYW55RGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihcbiAgICAgICAgICAgIHRoaXMuZWRpdEhhc01hbnlEaWFsb2csXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbWluV2lkdGg6ICc2MCUnLFxuICAgICAgICAgICAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICBjb25zdCByZXM6IG51bWJlciA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuZWRpdEhhc01hbnlEaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKSkgYXMgbnVtYmVyO1xuICAgICAgICBpZiAocmVzID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhOiBFbnRpdHlUeXBlW10gPSB0aGlzLmhhc01hbnlEYXRhU291cmNlLmRhdGE7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICAgICAgZGF0YVt0aGlzLmhhc01hbnlEYXRhU291cmNlLmRhdGEuZmluZEluZGV4KChlKSA9PiBlW3RoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UuaWRLZXldID09PSBlbnRpdHlbdGhpcy5oYXNNYW55RW50aXR5U2VydmljZS5pZEtleV0pXSA9IGVudGl0eTtcbiAgICAgICAgICAgIHRoaXMuaGFzTWFueURhdGFTb3VyY2UuZGF0YSA9IGRhdGE7XG4gICAgICAgICAgICB0aGlzLmhhc01hbnlTZWxlY3Rpb24uY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWVzIHRvIHNhdmUgdGhlIGNoYW5nZXMgYW5kIGNsb3NlIHRoZSBkaWFsb2cgYWZ0ZXJ3YXJkcy5cbiAgICAgKiBBbHNvIGhhbmRsZXMgdGhlIGNvbmZpcm1hdGlvbiBpZiByZXF1aXJlZC5cbiAgICAgKi9cbiAgICBkaWFsb2dFZGl0SGFzTWFueSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuaW50ZXJuYWxJc1JlYWRPbmx5IHx8ICF0aGlzLmlzSGFzTWFueUVudGl0eVZhbGlkIHx8ICF0aGlzLmlzSGFzTWFueUVudGl0eURpcnR5KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuZWRpdFJlcXVpcmVzQ29uZmlybURpYWxvZykge1xuICAgICAgICAgICAgdGhpcy5kaWFsb2dDb25maXJtRWRpdEhhc01hbnkoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICBjb25zdCBkaWFsb2dEYXRhOiBDb25maXJtRGlhbG9nRGF0YUludGVybmFsID0gbmV3IENvbmZpcm1EaWFsb2dEYXRhQnVpbGRlcih0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuY29uZmlybUVkaXREaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgWydEbyB5b3UgcmVhbGx5IHdhbnQgdG8gc2F2ZSBhbGwgY2hhbmdlcz8nXSlcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgnY29uZmlybUJ1dHRvbkxhYmVsJywgJ1NhdmUnKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0aXRsZScsICdFZGl0JylcbiAgICAgICAgICAgIC5nZXRSZXN1bHQoKTtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8Tmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwgYm9vbGVhbj4gPSB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIGRhdGE6IGRpYWxvZ0RhdGEsXG4gICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgICAgICBpZiAocmVzID09IHRydWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpYWxvZ0NvbmZpcm1FZGl0SGFzTWFueSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcHJpdmF0ZSBkaWFsb2dDb25maXJtRWRpdEhhc01hbnkoKTogdm9pZCB7XG4gICAgICAgIHZvaWQgdGhpcy5oYXNNYW55RW50aXR5U2VydmljZS51cGRhdGUodGhpcy5oYXNNYW55RW50aXR5LCB0aGlzLmhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0SGFzTWFueURpYWxvZ1JlZi5jbG9zZSgxKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWVzIHRvIGRlbGV0ZSB0aGUgZW50aXR5IGFuZCBjbG9zZSB0aGUgZGlhbG9nIGFmdGVyd2FyZHMuXG4gICAgICogQWxzbyBoYW5kbGVzIHRoZSBjb25maXJtYXRpb24gaWYgcmVxdWlyZWQuXG4gICAgICovXG4gICAgZGVsZXRlSGFzTWFueUVudGl0eSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuZGVsZXRlUmVxdWlyZXNDb25maXJtRGlhbG9nKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpcm1EZWxldGVIYXNNYW55RW50aXR5KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgICAgY29uc3QgZGlhbG9nRGF0YTogQ29uZmlybURpYWxvZ0RhdGFJbnRlcm5hbCA9IG5ldyBDb25maXJtRGlhbG9nRGF0YUJ1aWxkZXIodGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmVkaXREYXRhLmNvbmZpcm1EZWxldGVEaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgWydEbyB5b3UgcmVhbGx5IHdhbnQgdG8gZGVsZXRlIHRoaXMgZW50aXR5PyddKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0eXBlJywgJ2RlbGV0ZScpXG4gICAgICAgICAgICAud2l0aERlZmF1bHQoJ2NvbmZpcm1CdXR0b25MYWJlbCcsICdEZWxldGUnKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0aXRsZScsICdEZWxldGUnKVxuICAgICAgICAgICAgLmdldFJlc3VsdCgpO1xuICAgICAgICBjb25zdCBkaWFsb2dSZWY6IE1hdERpYWxvZ1JlZjxOZ3hNYXRFbnRpdHlDb25maXJtRGlhbG9nQ29tcG9uZW50LCBib29sZWFuPiA9IHRoaXMuZGlhbG9nLm9wZW4oTmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgICAgICAgZGF0YTogZGlhbG9nRGF0YSxcbiAgICAgICAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgICAgICAgICByZXN0b3JlRm9jdXM6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUocmVzID0+IHtcbiAgICAgICAgICAgIGlmIChyZXMgPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlybURlbGV0ZUhhc01hbnlFbnRpdHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb25maXJtRGVsZXRlSGFzTWFueUVudGl0eSgpOiB2b2lkIHtcbiAgICAgICAgdm9pZCB0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmRlbGV0ZSh0aGlzLmhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lZGl0SGFzTWFueURpYWxvZ1JlZi5jbG9zZSgyKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdENoYW5nZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYW5jZWxzIHRoZSBlZGl0aW5nIG9mIHRoZSBoYXMgbWFueSBlbnRpdHkgYW5kIGNsb3NlcyB0aGUgZGlhbG9nLlxuICAgICAqL1xuICAgIGRpYWxvZ0NhbmNlbEVkaXRIYXNNYW55KCk6IHZvaWQge1xuICAgICAgICBFbnRpdHlVdGlsaXRpZXMucmVzZXRDaGFuZ2VzT25FbnRpdHkodGhpcy5oYXNNYW55RW50aXR5LCB0aGlzLmhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMpO1xuICAgICAgICB0aGlzLmVkaXRIYXNNYW55RGlhbG9nUmVmLmNsb3NlKDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgRW50aXR5LiBUaGlzIGVpdGhlciBjYWxscyB0aGUgY3JlYXRlLU1ldGhvZCBwcm92aWRlZCBieSB0aGUgdXNlciBvciB1c2VzIGEgZGVmYXVsdCBjcmVhdGUtZGlhbG9nLlxuICAgICAqXG4gICAgICogQHRocm93cyBXaGVuIG5vIEVudGl0eUNsYXNzIHdhcyBwcm92aWRlZCwgYXMgYSBuZXcgY2FsbCBpcyBuZWVkZWQgdG8gaW5pdGlhbGl6ZSBtZXRhZGF0YS5cbiAgICAgKi9cbiAgICBjcmVhdGVIYXNNYW55RW50aXR5KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmluamVjdG9yLnJ1bkluQ29udGV4dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmFsbG93Q3JlYXRlKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5FbnRpdHlDbGFzcykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIFwiRW50aXR5Q2xhc3NcIiBzcGVjaWZpZWQgZm9yIHRoaXMgdGFibGUnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5jcmVhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmNyZWF0ZShuZXcgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLkVudGl0eUNsYXNzKCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVIYXNNYW55RGVmYXVsdChuZXcgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLkVudGl0eUNsYXNzKCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjcmVhdGVIYXNNYW55RGVmYXVsdChlbnRpdHk6IEVudGl0eVR5cGUpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5oYXNNYW55RW50aXR5ID0gZW50aXR5O1xuICAgICAgICB0aGlzLmhhc01hbnlDcmVhdGVUYWJzID0gRW50aXR5VXRpbGl0aWVzLmdldEVudGl0eVRhYnModGhpcy5oYXNNYW55RW50aXR5LCB0cnVlKTtcbiAgICAgICAgdGhpcy5jaGVja0lzSGFzTWFueUVudGl0eVZhbGlkKCdjcmVhdGUnKTtcbiAgICAgICAgdGhpcy5jcmVhdGVIYXNNYW55RGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlSGFzTWFueURpYWxvZyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBtaW5XaWR0aDogJzYwJScsXG4gICAgICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICByZXN0b3JlRm9jdXM6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgaGFzIG1hbnkgZW50aXR5IG92ZXIgdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBkaWFsb2dDcmVhdGVIYXNNYW55KCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuaXNIYXNNYW55RW50aXR5VmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5jcmVhdGVEaWFsb2dEYXRhLmNyZWF0ZVJlcXVpcmVzQ29uZmlybURpYWxvZykge1xuICAgICAgICAgICAgdGhpcy5kaWFsb2dDb25maXJtQ3JlYXRlSGFzTWFueSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgIGNvbnN0IGRpYWxvZ0RhdGE6IENvbmZpcm1EaWFsb2dEYXRhSW50ZXJuYWwgPSBuZXcgQ29uZmlybURpYWxvZ0RhdGFCdWlsZGVyKHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5jcmVhdGVEaWFsb2dEYXRhLmNvbmZpcm1DcmVhdGVEaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgWydEbyB5b3UgcmVhbGx5IHdhbnQgdG8gY3JlYXRlIHRoaXMgZW50aXR5PyddKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCdjb25maXJtQnV0dG9uTGFiZWwnLCAnQ3JlYXRlJylcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgndGl0bGUnLCAnQ3JlYXRlJylcbiAgICAgICAgICAgIC5nZXRSZXN1bHQoKTtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8Tmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwgYm9vbGVhbj4gPSB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIGRhdGE6IGRpYWxvZ0RhdGEsXG4gICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgICAgICBpZiAocmVzID09IHRydWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpYWxvZ0NvbmZpcm1DcmVhdGVIYXNNYW55KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBwcml2YXRlIGRpYWxvZ0NvbmZpcm1DcmVhdGVIYXNNYW55KCk6IHZvaWQge1xuICAgICAgICB2b2lkIHRoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UuY3JlYXRlKHRoaXMuaGFzTWFueUVudGl0eSwgdGhpcy5oYXNNYW55Q3JlYXRlQmFzZVVybCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUhhc01hbnlEaWFsb2dSZWYuY2xvc2UoKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdENoYW5nZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYW5jZWxzIHRoZSBjcmVhdGluZyBvZiB0aGUgaGFzIG1hbnkgZW50aXR5IGFuZCBjbG9zZXMgdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBkaWFsb2dDYW5jZWxDcmVhdGVIYXNNYW55KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNyZWF0ZUhhc01hbnlEaWFsb2dSZWYuY2xvc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSdW5zIHRoZSBUYWJsZUFjdGlvbiBmb3IgYWxsIHNlbGVjdGVkIGVudHJpZXMuXG4gICAgICogQWxzbyBoYW5kbGVzIGNvbmZpcm1hdGlvbiB3aXRoIGFuIGFkZGl0aW9uYWwgZGlhbG9nIGlmIGNvbmZpZ3VyZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIC0gVGhlIFRhYmxlQWN0aW9uIHRvIHJ1bi5cbiAgICAgKi9cbiAgICBydW5IYXNNYW55VGFibGVBY3Rpb24oYWN0aW9uOiBUYWJsZUFjdGlvbkludGVybmFsPEVudGl0eVR5cGU+KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHJlcXVpcmVDb25maXJtRGlhbG9nOiBib29sZWFuID0gdGhpcy5pbmplY3Rvci5ydW5JbkNvbnRleHQoKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGFjdGlvbi5yZXF1aXJlQ29uZmlybURpYWxvZyh0aGlzLmhhc01hbnlTZWxlY3Rpb24uc2VsZWN0ZWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFyZXF1aXJlQ29uZmlybURpYWxvZykge1xuICAgICAgICAgICAgdGhpcy5jb25maXJtUnVuSGFzTWFueVRhYmxlQWN0aW9uKGFjdGlvbik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGlhbG9nRGF0YTogQ29uZmlybURpYWxvZ0RhdGFJbnRlcm5hbCA9IG5ldyBDb25maXJtRGlhbG9nRGF0YUJ1aWxkZXIoYWN0aW9uLmNvbmZpcm1EaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgW2BEbyB5b3UgcmVhbGx5IHdhbnQgdG8gcnVuIHRoaXMgYWN0aW9uIG9uICR7dGhpcy5oYXNNYW55U2VsZWN0aW9uLnNlbGVjdGVkLmxlbmd0aH0gZW50cmllcz9gXSlcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgndGl0bGUnLCBhY3Rpb24uZGlzcGxheU5hbWUpXG4gICAgICAgICAgICAuZ2V0UmVzdWx0KCk7XG4gICAgICAgIGNvbnN0IGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIGJvb2xlYW4+ID0gdGhpcy5kaWFsb2cub3BlbihOZ3hNYXRFbnRpdHlDb25maXJtRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICAgICAgICBkYXRhOiBkaWFsb2dEYXRhLFxuICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICAgICAgICAgIHJlc3RvcmVGb2N1czogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShyZXMgPT4ge1xuICAgICAgICAgICAgaWYgKHJlcyA9PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maXJtUnVuSGFzTWFueVRhYmxlQWN0aW9uKGFjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgY29uZmlybVJ1bkhhc01hbnlUYWJsZUFjdGlvbihhY3Rpb246IFRhYmxlQWN0aW9uSW50ZXJuYWw8RW50aXR5VHlwZT4pOiB2b2lkIHtcbiAgICAgICAgdm9pZCB0aGlzLmluamVjdG9yLnJ1bkluQ29udGV4dChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBhY3Rpb24uYWN0aW9uKHRoaXMuaGFzTWFueVNlbGVjdGlvbi5zZWxlY3RlZCk7XG4gICAgICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGFuIFRhYmxlQWN0aW9uIGlzIGRpc2FibGVkIChlLmcuIEJlY2F1c2Ugbm8gZW50cmllcyBoYXZlIGJlZW4gc2VsZWN0ZWQpLlxuICAgICAqXG4gICAgICogQHBhcmFtIGFjdGlvbiAtIFRoZSBUYWJsZUFjdGlvbiB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCB0aGUgQWN0aW9uIGNhbiBiZSB1c2VkLlxuICAgICAqL1xuICAgIGhhc01hbnlUYWJsZUFjdGlvbkRpc2FibGVkKGFjdGlvbjogVGFibGVBY3Rpb25JbnRlcm5hbDxFbnRpdHlUeXBlPik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbmplY3Rvci5ydW5JbkNvbnRleHQoKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICFhY3Rpb24uZW5hYmxlZCh0aGlzLmhhc01hbnlTZWxlY3Rpb24uc2VsZWN0ZWQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIHRoZSBzZWFyY2ggaW5wdXQgdG8gZmlsdGVyIHRoZSB0YWJsZSBlbnRyaWVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50IC0gVGhlIGtleXVwLWV2ZW50IHdoaWNoIGNvbnRhaW5zIHRoZSBzZWFyY2gtc3RyaW5nIG9mIHRoZSB1c2VyLlxuICAgICAqL1xuICAgIGFwcGx5SGFzTWFueUZpbHRlcihldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZmlsdGVyVmFsdWU6IHN0cmluZyA9IChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkudmFsdWU7XG4gICAgICAgIHRoaXMuaGFzTWFueURhdGFTb3VyY2UuZmlsdGVyID0gZmlsdGVyVmFsdWUudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBlbnRpdHkgaXMgdmFsaWQgZm9yIHVwZGF0aW5nIGFuZCBpZiBpdCBpcyBkaXJ0eS5cbiAgICAgKi9cbiAgICBhc3luYyBjaGVja0hhc01hbnlFbnRpdHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuY2hlY2tJc0hhc01hbnlFbnRpdHlWYWxpZCgndXBkYXRlJyk7XG4gICAgICAgIHRoaXMuaXNIYXNNYW55RW50aXR5RGlydHkgPSBhd2FpdCBFbnRpdHlVdGlsaXRpZXMuaXNEaXJ0eSh0aGlzLmhhc01hbnlFbnRpdHksIHRoaXMuaGFzTWFueUVudGl0eVByaW9yQ2hhbmdlcywgdGhpcy5odHRwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIGVudGl0eSBpcyB2YWxpZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBvbWl0IC0gV2hldGhlciB2YWx1ZXMgb21pdHRlZCBmb3IgY3JlYXRlIG9yIHVwZGF0ZSBzaG91bGQgYmUgbGVmdCBvdXQuXG4gICAgICovXG4gICAgY2hlY2tJc0hhc01hbnlFbnRpdHlWYWxpZChvbWl0OiAnY3JlYXRlJyB8ICd1cGRhdGUnKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXNIYXNNYW55RW50aXR5VmFsaWQgPSBFbnRpdHlVdGlsaXRpZXMuaXNFbnRpdHlWYWxpZCh0aGlzLmhhc01hbnlFbnRpdHksIG9taXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBhcnJheSBpdGVtIGlzIHZhbGlkIGFuZCBpZiB0aGUgYXJyYXkgaXRlbSBpcyBkaXJ0eS5cbiAgICAgKi9cbiAgICBjaGVja0FycmF5SXRlbSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jaGVja0lzQXJyYXlJdGVtVmFsaWQoKTtcbiAgICAgICAgdm9pZCB0aGlzLmNoZWNrSXNBcnJheUl0ZW1EaXJ0eSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGUgYXJyYXkgaXRlbSBpcyBkaXJ0eS5cbiAgICAgKi9cbiAgICBhc3luYyBjaGVja0lzQXJyYXlJdGVtRGlydHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuaXNBcnJheUl0ZW1EaXJ0eSA9IGF3YWl0IEVudGl0eVV0aWxpdGllcy5pc0RpcnR5KHRoaXMuYXJyYXlJdGVtLCB0aGlzLmFycmF5SXRlbVByaW9yQ2hhbmdlcywgdGhpcy5odHRwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIGFycmF5SXRlbSBpcyB2YWxpZC5cbiAgICAgKi9cbiAgICBjaGVja0lzQXJyYXlJdGVtVmFsaWQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXNBcnJheUl0ZW1WYWxpZCA9IEVudGl0eVV0aWxpdGllcy5pc0VudGl0eVZhbGlkKHRoaXMuYXJyYXlJdGVtLCAnY3JlYXRlJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW1pdHMgdGhhdCBhIHRoZSB2YWx1ZSBoYXMgYmVlbiBjaGFuZ2VkLlxuICAgICAqL1xuICAgIGVtaXRDaGFuZ2UoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaW5wdXRDaGFuZ2VFdmVudC5lbWl0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJpZXMgdG8gYWRkIGFuIGl0ZW0gdG8gdGhlIGVudGl0eSBhcnJheS5cbiAgICAgKiBEb2VzIHRoaXMgZWl0aGVyIGlubGluZSBpZiB0aGUgXCJjcmVhdGVJbmxpbmVcIi1tZXRhZGF0YSBpcyBzZXQgdG8gdHJ1ZVxuICAgICAqIG9yIGluIGEgc2VwYXJhdGUgZGlhbG9nIGlmIGl0IGlzIHNldCB0byBmYWxzZS5cbiAgICAgKi9cbiAgICBhc3luYyBhZGRFbnRpdHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuY3JlYXRlSW5saW5lKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5hbGxvd0R1cGxpY2F0ZXMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHYgb2YgdGhpcy5lbnRpdHlBcnJheVZhbHVlcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoKGF3YWl0IEVudGl0eVV0aWxpdGllcy5pc0VxdWFsKHRoaXMuYXJyYXlJdGVtLCB2LCB0aGlzLm1ldGFkYXRhLCB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuaXRlbVR5cGUsIHRoaXMuaHR0cCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuZHVwbGljYXRlc0Vycm9yRGlhbG9nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVudGl0eUFycmF5VmFsdWVzLnB1c2goTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFycmF5SXRlbSkpO1xuICAgICAgICAgICAgdGhpcy5lbnRpdHlBcnJheURhdGFTb3VyY2UuZGF0YSA9IHRoaXMuZW50aXR5QXJyYXlWYWx1ZXM7XG4gICAgICAgICAgICBFbnRpdHlVdGlsaXRpZXMucmVzZXRDaGFuZ2VzT25FbnRpdHkodGhpcy5hcnJheUl0ZW0sIHRoaXMuYXJyYXlJdGVtUHJpb3JDaGFuZ2VzKTtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tJc0FycmF5SXRlbVZhbGlkKCk7XG4gICAgICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYWRkQXJyYXlJdGVtRGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEFycmF5SXRlbURpYWxvZyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1pbldpZHRoOiAnNjAlJyxcbiAgICAgICAgICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIHRoZSBhcnJheSBpdGVtIGRlZmluZWQgaW4gdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBhZGRBcnJheUl0ZW0oKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5pc0FycmF5SXRlbVZhbGlkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbnRpdHlBcnJheVZhbHVlcy5wdXNoKExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5hcnJheUl0ZW0pKTtcbiAgICAgICAgdGhpcy5lbnRpdHlBcnJheURhdGFTb3VyY2UuZGF0YSA9IHRoaXMuZW50aXR5QXJyYXlWYWx1ZXM7XG5cbiAgICAgICAgdGhpcy5jbG9zZUFkZEFycmF5SXRlbURpYWxvZygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbmNlbHMgYWRkaW5nIHRoZSBhcnJheSBpdGVtIGRlZmluZWQgaW4gdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBjbG9zZUFkZEFycmF5SXRlbURpYWxvZygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5hZGRBcnJheUl0ZW1EaWFsb2dSZWYuY2xvc2UoKTtcbiAgICAgICAgRW50aXR5VXRpbGl0aWVzLnJlc2V0Q2hhbmdlc09uRW50aXR5KHRoaXMuYXJyYXlJdGVtLCB0aGlzLmFycmF5SXRlbVByaW9yQ2hhbmdlcyk7XG4gICAgICAgIHRoaXMuY2hlY2tJc0FycmF5SXRlbVZhbGlkKCk7XG4gICAgICAgIHRoaXMuZW1pdENoYW5nZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVkaXRzIGFuIGVudGl0eSBhcnJheSBpdGVtLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIFRoZSBlbnRpdHkgdGhhdCBoYXMgYmVlbiBjbGlja2VkLlxuICAgICAqIEBwYXJhbSBkQ29sIC0gVGhlIGRpc3BsYXkgY29sdW1uIHRoYXQgd2FzIGNsaWNrZWQgb24uXG4gICAgICovXG4gICAgZWRpdEFycmF5SXRlbShlbnRpdHk6IEVudGl0eVR5cGUsIGRDb2w6IERpc3BsYXlDb2x1bW48RW50aXR5VHlwZT4pOiB2b2lkIHtcbiAgICAgICAgaWYgKGRDb2wuZGlzYWJsZUNsaWNrID09PSB0cnVlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbmRleE9mRWRpdGVkQXJyYXlJdGVtID0gdGhpcy5lbnRpdHlBcnJheVZhbHVlcy5pbmRleE9mKGVudGl0eSk7XG4gICAgICAgIHRoaXMuYXJyYXlJdGVtID0gbmV3IHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5FbnRpdHlDbGFzcyhlbnRpdHkpO1xuICAgICAgICB0aGlzLmFycmF5SXRlbVByaW9yQ2hhbmdlcyA9IExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5hcnJheUl0ZW0pO1xuXG4gICAgICAgIHRoaXMuY2hlY2tBcnJheUl0ZW0oKTtcblxuICAgICAgICB0aGlzLmVkaXRBcnJheUl0ZW1EaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKFxuICAgICAgICAgICAgdGhpcy5lZGl0QXJyYXlJdGVtRGlhbG9nLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG1pbldpZHRoOiAnNjAlJyxcbiAgICAgICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHJlc3RvcmVGb2N1czogZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTYXZlcyBjaGFuZ2VzIG9uIHRoZSBhcnJheSBpdGVtIGluIHRoZSBkaWFsb2cuXG4gICAgICovXG4gICAgc2F2ZUFycmF5SXRlbSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lbnRpdHlBcnJheVZhbHVlc1t0aGlzLmluZGV4T2ZFZGl0ZWRBcnJheUl0ZW1dID0gTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFycmF5SXRlbSk7XG4gICAgICAgIHRoaXMuZW50aXR5QXJyYXlEYXRhU291cmNlLmRhdGEgPSB0aGlzLmVudGl0eUFycmF5VmFsdWVzO1xuXG4gICAgICAgIHRoaXMuY2xvc2VFZGl0QXJyYXlJdGVtRGlhbG9nKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSBlZGl0IGFycmF5IGl0ZW0gZGlhbG9nIGFuZCByZXNldHMgY2hhbmdlcy5cbiAgICAgKi9cbiAgICBjbG9zZUVkaXRBcnJheUl0ZW1EaWFsb2coKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWRpdEFycmF5SXRlbURpYWxvZ1JlZi5jbG9zZSgpO1xuICAgICAgICB0aGlzLmFycmF5SXRlbSA9IG5ldyB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuRW50aXR5Q2xhc3MoKTtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW1QcmlvckNoYW5nZXMgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHRoaXMuYXJyYXlJdGVtKTtcbiAgICAgICAgdGhpcy5jaGVja0FycmF5SXRlbSgpO1xuICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBzZWxlY3RlZCBlbnRyaWVzIGZyb20gdGhlIGVudGl0eSBhcnJheS5cbiAgICAgKi9cbiAgICByZW1vdmVGcm9tRW50aXR5QXJyYXkoKTogdm9pZCB7XG4gICAgICAgIFNlbGVjdGlvblV0aWxpdGllcy5yZW1vdmUodGhpcy5lbnRpdHlBcnJheVNlbGVjdGlvbiwgdGhpcy5lbnRpdHlBcnJheVZhbHVlcywgdGhpcy5lbnRpdHlBcnJheURhdGFTb3VyY2UpO1xuICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICB9XG59IiwiPGRpdiBbbmdTd2l0Y2hdPVwidHlwZVwiICpuZ0lmPVwiIShoaWRlT21pdEZvckNyZWF0ZSAmJiBtZXRhZGF0YS5vbWl0Rm9yQ3JlYXRlKSAmJiAhKGhpZGVPbWl0Rm9yRWRpdCAmJiBtZXRhZGF0YS5vbWl0Rm9yVXBkYXRlKVwiPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLVN0cmluZ3MtLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLlNUUklOR1wiPlxuICAgICAgICA8c3RyaW5nLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9zdHJpbmctaW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuU1RSSU5HX1RFWFRCT1hcIj5cbiAgICAgICAgPHN0cmluZy10ZXh0Ym94LWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9zdHJpbmctdGV4dGJveC1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5TVFJJTkdfQVVUT0NPTVBMRVRFXCI+XG4gICAgICAgIDxzdHJpbmctYXV0b2NvbXBsZXRlLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9zdHJpbmctYXV0b2NvbXBsZXRlLWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLlNUUklOR19EUk9QRE9XTlwiPlxuICAgICAgICA8c3RyaW5nLWRyb3Bkb3duLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9zdHJpbmctZHJvcGRvd24taW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuU1RSSU5HX1BBU1NXT1JEXCI+XG4gICAgICAgIDxzdHJpbmctcGFzc3dvcmQtaW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L3N0cmluZy1wYXNzd29yZC1pbnB1dD5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLUJvb2xlYW5zLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLkJPT0xFQU5fQ0hFQ0tCT1hcIj5cbiAgICAgICAgPGJvb2xlYW4tY2hlY2tib3gtaW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L2Jvb2xlYW4tY2hlY2tib3gtaW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuQk9PTEVBTl9UT0dHTEVcIj5cbiAgICAgICAgPGJvb2xlYW4tdG9nZ2xlLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9ib29sZWFuLXRvZ2dsZS1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5CT09MRUFOX0RST1BET1dOXCI+XG4gICAgICAgIDxib29sZWFuLWRyb3Bkb3duLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9ib29sZWFuLWRyb3Bkb3duLWlucHV0PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLU51bWJlcnMtLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuTlVNQkVSXCI+XG4gICAgICAgIDxudW1iZXItaW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L251bWJlci1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5OVU1CRVJfRFJPUERPV05cIj5cbiAgICAgICAgPG51bWJlci1kcm9wZG93bi1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvbnVtYmVyLWRyb3Bkb3duLWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLk5VTUJFUl9TTElERVJcIj5cbiAgICAgICAgPG51bWJlci1zbGlkZXItaW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L251bWJlci1zbGlkZXItaW5wdXQ+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLUFycmF5LS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5BUlJBWV9EQVRFXCI+XG4gICAgICAgIDxhcnJheS1kYXRlLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9hcnJheS1kYXRlLWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLkFSUkFZX0RBVEVfVElNRVwiPlxuICAgICAgICA8YXJyYXktZGF0ZS10aW1lLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9hcnJheS1kYXRlLXRpbWUtaW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuQVJSQVlfREFURV9SQU5HRVwiPlxuICAgICAgICA8YXJyYXktZGF0ZS1yYW5nZS1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvYXJyYXktZGF0ZS1yYW5nZS1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5BUlJBWV9TVFJJTkdfQ0hJUFNcIj5cbiAgICAgICAgPGFycmF5LXN0cmluZy1jaGlwcy1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvYXJyYXktc3RyaW5nLWNoaXBzLWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLkFSUkFZX1NUUklOR19BVVRPQ09NUExFVEVfQ0hJUFNcIj5cbiAgICAgICAgPGFycmF5LXN0cmluZy1hdXRvY29tcGxldGUtY2hpcHNcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L2FycmF5LXN0cmluZy1hdXRvY29tcGxldGUtY2hpcHM+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLURhdGVzLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5EQVRFXCI+XG4gICAgICAgIDxkYXRlLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9kYXRlLWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLkRBVEVfUkFOR0VcIj5cbiAgICAgICAgPGRhdGUtcmFuZ2UtaW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L2RhdGUtcmFuZ2UtaW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuREFURV9USU1FXCI+XG4gICAgICAgIDxkYXRlLXRpbWUtaW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L2RhdGUtdGltZS1pbnB1dD5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tRmlsZXMtLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLkZJTEVfREVGQVVMVFwiPlxuICAgICAgICA8ZmlsZS1kZWZhdWx0LWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9maWxlLWRlZmF1bHQtaW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuRklMRV9JTUFHRVwiPlxuICAgICAgICA8ZmlsZS1pbWFnZS1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvZmlsZS1pbWFnZS1pbnB1dD5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLSByZWZlcmVuY2VzIG1hbnkgLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLlJFRkVSRU5DRVNfTUFOWVwiPlxuICAgICAgICA8cmVmZXJlbmNlcy1tYW55LWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9yZWZlcmVuY2VzLW1hbnktaW5wdXQ+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLUN1c3RvbS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5DVVNUT01cIj5cbiAgICAgICAgPGN1c3RvbS1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvY3VzdG9tLWlucHV0PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS1PYmplY3QtLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuT0JKRUNUXCI+XG4gICAgICAgIDxiPnt7bWV0YWRhdGFEZWZhdWx0T2JqZWN0LmRpc3BsYXlOYW1lfX08L2I+XG4gICAgICAgIDwhLS0gaXRlcmF0ZXMgb3ZlciB0aGUgb2JqZWN0IHByb3BlcnRpZXMgLS0+XG4gICAgICAgIDxtYXQtdGFiLWdyb3VwICpuZ0lmPVwib2JqZWN0UHJvcGVydHlUYWJzLmxlbmd0aCA+IDFcIiBwcmVzZXJ2ZUNvbnRlbnQ+XG4gICAgICAgICAgICA8bWF0LXRhYiAqbmdGb3I9XCJsZXQgdGFiIG9mIG9iamVjdFByb3BlcnR5VGFiczsgbGV0IHRJID0gaW5kZXg7IHRyYWNrQnk6IHRyYWNrQnlGblwiIFtsYWJlbF09XCJ0YWIudGFiTmFtZVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIHRhYi5yb3dzO1wiPlxuICAgICAgICAgICAgICAgICAgICA8bmd4LW1hdC1lbnRpdHktaW5wdXQgKm5nRm9yPVwibGV0IGtleSBvZiByb3cua2V5czsgbGV0IHJJID0gaW5kZXg7IHRyYWNrQnk6IHRyYWNrQnlGblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZW50aXR5XT1cIm9iamVjdFByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eUtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckNyZWF0ZV09XCJoaWRlT21pdEZvckNyZWF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JFZGl0XT1cImhpZGVPbWl0Rm9yRWRpdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdmFsaWRFbXB0eV09XCIhbWV0YWRhdGEucmVxdWlyZWQoZW50aXR5KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXNSZWFkT25seV09XCJpc1Byb3BlcnR5UmVhZE9ubHkob2JqZWN0UHJvcGVydHksIGtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtbGcte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgob2JqZWN0UHJvcGVydHksIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgob2JqZWN0UHJvcGVydHksIGtleSwgJ21kJyl9fSBjb2wtc20te3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgob2JqZWN0UHJvcGVydHksIGtleSwgJ3NtJyl9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDwvbmd4LW1hdC1lbnRpdHktaW5wdXQ+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIDwvbWF0LXRhYi1ncm91cD5cblxuICAgICAgICA8ZGl2ICpuZ0lmPVwib2JqZWN0UHJvcGVydHlUYWJzLmxlbmd0aCA8PSAxXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nRm9yPVwibGV0IHJvdyBvZiBvYmplY3RQcm9wZXJ0eVRhYnNbMF0ucm93c1wiPlxuICAgICAgICAgICAgICAgIDxuZ3gtbWF0LWVudGl0eS1pbnB1dCAqbmdGb3I9XCJsZXQga2V5IG9mIHJvdy5rZXlzOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5Rm5cIlxuICAgICAgICAgICAgICAgICAgICBbZW50aXR5XT1cIm9iamVjdFByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgW3Byb3BlcnR5S2V5XT1cImtleVwiXG4gICAgICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckNyZWF0ZV09XCJoaWRlT21pdEZvckNyZWF0ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckVkaXRdPVwiaGlkZU9taXRGb3JFZGl0XCJcbiAgICAgICAgICAgICAgICAgICAgW3ZhbGlkRW1wdHldPVwiIW1ldGFkYXRhLnJlcXVpcmVkKGVudGl0eSlcIlxuICAgICAgICAgICAgICAgICAgICBbaXNSZWFkT25seV09XCJpc1Byb3BlcnR5UmVhZE9ubHkob2JqZWN0UHJvcGVydHksIGtleSlcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChvYmplY3RQcm9wZXJ0eSwga2V5LCAnbGcnKX19IGNvbC1tZC17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChvYmplY3RQcm9wZXJ0eSwga2V5LCAnbWQnKX19IGNvbC1zbS17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChvYmplY3RQcm9wZXJ0eSwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLSByZWZlcmVuY2VzIG9uZSAtLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuUkVGRVJFTkNFU19PTkVcIj5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPG1hdC1sYWJlbD57e21ldGFkYXRhLmRpc3BsYXlOYW1lfX08L21hdC1sYWJlbD5cbiAgICAgICAgICAgIDxtYXQtc2VsZWN0IFsobmdNb2RlbCldPVwiaW50ZXJuYWxFbnRpdHlbaW50ZXJuYWxQcm9wZXJ0eUtleV1cIlxuICAgICAgICAgICAgICAgIFtuYW1lXT1cImludGVybmFsUHJvcGVydHlLZXkudG9TdHJpbmcoKSArICdpbnB1dCdcIlxuICAgICAgICAgICAgICAgICNpbnB1dE1vZGVsPVwibmdNb2RlbFwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cIm1ldGFkYXRhLnJlcXVpcmVkKGVudGl0eSlcIlxuICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldFJlZmVyZW5jZXNPbmVPYmplY3QoKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nSWY9XCIhbWV0YWRhdGEucmVxdWlyZWQoZW50aXR5KVwiPi08L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IHZhbHVlIG9mIHJlZmVyZW5jZXNPbmVEcm9wZG93blZhbHVlc1wiIFt2YWx1ZV09XCJ2YWx1ZS52YWx1ZVwiPnt7dmFsdWUuZGlzcGxheU5hbWV9fTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgIDxtYXQtZXJyb3I+e3tpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2UoaW5wdXRNb2RlbCl9fTwvbWF0LWVycm9yPlxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICA8IS0tIGl0ZXJhdGVzIG92ZXIgdGhlIHJlZmVyZW5jZXMgb25lIHByb3BlcnRpZXMgLS0+XG4gICAgICAgIDxtYXQtdGFiLWdyb3VwICpuZ0lmPVwicmVmZXJlbmNlc09uZVByb3BlcnR5VGFicyAmJiByZWZlcmVuY2VzT25lUHJvcGVydHlUYWJzLmxlbmd0aCA+IDFcIiBwcmVzZXJ2ZUNvbnRlbnQ+XG4gICAgICAgICAgICA8bWF0LXRhYiAqbmdGb3I9XCJsZXQgdGFiIG9mIHJlZmVyZW5jZXNPbmVQcm9wZXJ0eVRhYnM7IGxldCB0SSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5Rm5cIiBbbGFiZWxdPVwidGFiLnRhYk5hbWVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nRm9yPVwibGV0IHJvdyBvZiB0YWIucm93cztcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0ICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXM7IGxldCBySSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5Rm5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJyZWZlcmVuY2VzT25lT2JqZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eUtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckNyZWF0ZV09XCJoaWRlT21pdEZvckNyZWF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JFZGl0XT1cImhpZGVPbWl0Rm9yRWRpdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdmFsaWRFbXB0eV09XCIhbWV0YWRhdGEucmVxdWlyZWQoZW50aXR5KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXNSZWFkT25seV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLWxnLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKHJlZmVyZW5jZXNPbmVPYmplY3QsIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgocmVmZXJlbmNlc09uZU9iamVjdCwga2V5LCAnbWQnKX19IGNvbC1zbS17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChyZWZlcmVuY2VzT25lT2JqZWN0LCBrZXksICdzbScpfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8L25neC1tYXQtZW50aXR5LWlucHV0PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICA8L21hdC10YWItZ3JvdXA+XG5cbiAgICAgICAgPGRpdiAqbmdJZj1cInJlZmVyZW5jZXNPbmVQcm9wZXJ0eVRhYnMgJiYgcmVmZXJlbmNlc09uZVByb3BlcnR5VGFicy5sZW5ndGggPD0gMVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgcmVmZXJlbmNlc09uZVByb3BlcnR5VGFic1swXS5yb3dzXCI+XG4gICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0ICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXM7IGxldCBpID0gaW5kZXg7IHRyYWNrQnk6IHRyYWNrQnlGblwiXG4gICAgICAgICAgICAgICAgICAgIFtlbnRpdHldPVwicmVmZXJlbmNlc09uZU9iamVjdFwiXG4gICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eUtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JDcmVhdGVdPVwiaGlkZU9taXRGb3JDcmVhdGVcIlxuICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JFZGl0XT1cImhpZGVPbWl0Rm9yRWRpdFwiXG4gICAgICAgICAgICAgICAgICAgIFt2YWxpZEVtcHR5XT1cIiFtZXRhZGF0YS5yZXF1aXJlZChlbnRpdHkpXCJcbiAgICAgICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLWxnLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKHJlZmVyZW5jZXNPbmVPYmplY3QsIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgocmVmZXJlbmNlc09uZU9iamVjdCwga2V5LCAnbWQnKX19IGNvbC1zbS17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChyZWZlcmVuY2VzT25lT2JqZWN0LCBrZXksICdzbScpfX1cIlxuICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8L25neC1tYXQtZW50aXR5LWlucHV0PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS1BcnJheS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPGRpdiBjbGFzcz1cImVudGl0eUFycmF5XCIgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLkFSUkFZXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtYXQtZWxldmF0aW9uLXo4IGVsZXZhdGlvbi1jb250YWluZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhcnJheS1oZWFkbGluZVwiPlxuICAgICAgICAgICAgICAgIDxiPnt7bWV0YWRhdGFFbnRpdHlBcnJheS5kaXNwbGF5TmFtZX19PC9iPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwibWV0YWRhdGFFbnRpdHlBcnJheS5jcmVhdGVJbmxpbmUgJiYgIWludGVybmFsSXNSZWFkT25seVwiPlxuICAgICAgICAgICAgICAgIDxtYXQtdGFiLWdyb3VwICpuZ0lmPVwiYXJyYXlJdGVtSW5saW5lVGFicy5sZW5ndGggPiAxXCIgcHJlc2VydmVDb250ZW50PlxuICAgICAgICAgICAgICAgICAgICA8bWF0LXRhYiAqbmdGb3I9XCJsZXQgdGFiIG9mIGFycmF5SXRlbUlubGluZVRhYnNcIiBbbGFiZWxdPVwidGFiLnRhYk5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIHRhYi5yb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXM7IGxldCBpID0gaW5kZXg7IHRyYWNrQnk6IHRyYWNrQnlGblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiYXJyYXlJdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb3BlcnR5S2V5XT1cImtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckNyZWF0ZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtbGcte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdsZycpfX0gY29sLW1kLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnbWQnKX19IGNvbC1zbS17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ3NtJyl9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImNoZWNrSXNBcnJheUl0ZW1WYWxpZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuXG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImFycmF5SXRlbUlubGluZVRhYnMubGVuZ3RoIDw9IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgYXJyYXlJdGVtSW5saW5lVGFic1swXS5yb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmd4LW1hdC1lbnRpdHktaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQga2V5IG9mIHJvdy5rZXlzOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5Rm5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiYXJyYXlJdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JDcmVhdGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdtZCcpfX0gY29sLXNtLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjaGVja0lzQXJyYXlJdGVtVmFsaWQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25neC1tYXQtZW50aXR5LWlucHV0PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uc1wiICpuZ0lmPVwiIWludGVybmFsSXNSZWFkT25seVwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJtZXRhZGF0YUVudGl0eUFycmF5LmNyZWF0ZUlubGluZSAmJiAhaXNBcnJheUl0ZW1WYWxpZFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRFbnRpdHkoKVwiPlxuICAgICAgICAgICAgICAgICAgICB7e21ldGFkYXRhRW50aXR5QXJyYXkuYWRkQnV0dG9uTGFiZWx9fVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhZW50aXR5QXJyYXlTZWxlY3Rpb24uc2VsZWN0ZWQubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZUZyb21FbnRpdHlBcnJheSgpXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7bWV0YWRhdGFFbnRpdHlBcnJheS5yZW1vdmVCdXR0b25MYWJlbH19XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgXG4gICAgICAgICAgICA8bWF0LXRhYmxlIFtkYXRhU291cmNlXT1cImVudGl0eUFycmF5RGF0YVNvdXJjZVwiPlxuICAgICAgICAgICAgICAgIDwhLS0gc2VsZWN0IENvbHVtbiAtLT5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInNlbGVjdFwiICpuZ0lmPVwiIWludGVybmFsSXNSZWFkT25seVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhZW50aXR5QXJyYXlEYXRhU291cmNlLmRhdGEubGVuZ3RoXCIgKGNoYW5nZSk9XCIkZXZlbnQgPyBTZWxlY3Rpb25VdGlsaXRpZXMubWFzdGVyVG9nZ2xlKGVudGl0eUFycmF5U2VsZWN0aW9uLCBlbnRpdHlBcnJheURhdGFTb3VyY2UpIDogbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwiZW50aXR5QXJyYXlTZWxlY3Rpb24uaGFzVmFsdWUoKSAmJiBTZWxlY3Rpb25VdGlsaXRpZXMuaXNBbGxTZWxlY3RlZChlbnRpdHlBcnJheVNlbGVjdGlvbiwgZW50aXR5QXJyYXlEYXRhU291cmNlKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2luZGV0ZXJtaW5hdGVdPVwiZW50aXR5QXJyYXlTZWxlY3Rpb24uaGFzVmFsdWUoKSAmJiAhU2VsZWN0aW9uVXRpbGl0aWVzLmlzQWxsU2VsZWN0ZWQoZW50aXR5QXJyYXlTZWxlY3Rpb24sIGVudGl0eUFycmF5RGF0YVNvdXJjZSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgICAgICAgICAgICA8L21hdC1oZWFkZXItY2VsbD5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVudGl0eVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveCAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgKGNoYW5nZSk9XCIkZXZlbnQgPyBlbnRpdHlBcnJheVNlbGVjdGlvbi50b2dnbGUoZW50aXR5KSA6IG51bGxcIiBbY2hlY2tlZF09XCJlbnRpdHlBcnJheVNlbGVjdGlvbi5pc1NlbGVjdGVkKGVudGl0eSlcIj48L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2VsbD5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGRDb2wgb2YgbWV0YWRhdGFFbnRpdHlBcnJheS5kaXNwbGF5Q29sdW1uc1wiIFttYXRDb2x1bW5EZWZdPVwiZENvbC5kaXNwbGF5TmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPlxuICAgICAgICAgICAgICAgICAgICAgICAge3tkQ29sLmRpc3BsYXlOYW1lfX1cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtaGVhZGVyLWNlbGw+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtY2VsbCBbY2xhc3MuZW5hYmxlZF09XCIhZENvbC5kaXNhYmxlQ2xpY2tcIiAoY2xpY2spPVwiZWRpdEFycmF5SXRlbShlbnRpdHksIGRDb2wpXCIgKm1hdENlbGxEZWY9XCJsZXQgZW50aXR5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZENvbC5Db21wb25lbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGlzcGxheS1jb2x1bW4tdmFsdWUgW2VudGl0eV09XCJlbnRpdHlcIiBbQ29tcG9uZW50Q2xhc3NdPVwiZENvbC5Db21wb25lbnRcIj48L2Rpc3BsYXktY29sdW1uLXZhbHVlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWRDb2wuQ29tcG9uZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tnZXREaXNwbGF5Q29sdW1uVmFsdWUoZW50aXR5LCBkQ29sKX19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2VsbD5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIDxtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZW50aXR5QXJyYXlEaXNwbGF5ZWRDb2x1bW5zXCI+PC9tYXQtaGVhZGVyLXJvdz5cbiAgICAgICAgICAgICAgICA8bWF0LXJvdyAqbWF0Um93RGVmPVwibGV0IHJvdzsgY29sdW1uczogZW50aXR5QXJyYXlEaXNwbGF5ZWRDb2x1bW5zXCI+PC9tYXQtcm93PlxuICAgICAgICAgICAgPC9tYXQtdGFibGU+XG4gICAgICAgIFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFycmF5LWVycm9yXCIgKm5nSWY9XCJtZXRhZGF0YUVudGl0eUFycmF5LnJlcXVpcmVkICYmICFlbnRpdHlBcnJheURhdGFTb3VyY2UuZGF0YS5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICB7e21ldGFkYXRhRW50aXR5QXJyYXkubWlzc2luZ0Vycm9yTWVzc2FnZX19XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tIGhhcyBtYW55IC0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8ZGl2IGNsYXNzPVwiaGFzTWFueVwiICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5IQVNfTUFOWVwiPlxuICAgICAgICA8aDIgY2xhc3M9XCJ0aXRsZVwiPnt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50aXRsZX19PC9oMj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJjb2wtbGctOCBjb2wtbWQtNiBjb2wtc20tMTJcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5zZWFyY2hMYWJlbH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IChrZXl1cCk9XCJhcHBseUhhc01hbnlGaWx0ZXIoJGV2ZW50KVwiPlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAqbmdJZj1cIm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEudGFibGVBY3Rpb25zLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmNvbC1sZy0yXT1cImhhc01hbnlBbGxvd0NyZWF0ZVwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmNvbC1sZy00XT1cIiFoYXNNYW55QWxsb3dDcmVhdGVcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtbWQtM109XCJoYXNNYW55QWxsb3dDcmVhdGVcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtbWQtNl09XCIhaGFzTWFueUFsbG93Q3JlYXRlXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuY29sLXNtLTZdPVwiaGFzTWFueUFsbG93Q3JlYXRlXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuY29sLXNtLTEyXT1cIiFoYXNNYW55QWxsb3dDcmVhdGVcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYWN0aW9ucy1idXR0b25cIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwibWVudVwiIG1hdC1yYWlzZWQtYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICB7e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEudGFibGVBY3Rpb25zTGFiZWx9fVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8bWF0LW1lbnUgI21lbnU9XCJtYXRNZW51XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cIm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuYWxsb3dKc29uSW1wb3J0XCIgdHlwZT1cImJ1dHRvblwiIFtkaXNhYmxlZF09XCJoYXNNYW55VGFibGVBY3Rpb25EaXNhYmxlZChoYXNNYW55SW1wb3J0QWN0aW9uKVwiIChjbGljayk9XCJydW5IYXNNYW55VGFibGVBY3Rpb24oaGFzTWFueUltcG9ydEFjdGlvbilcIiBtYXQtbWVudS1pdGVtPlxuICAgICAgICAgICAgICAgICAgICB7e2hhc01hbnlJbXBvcnRBY3Rpb24uZGlzcGxheU5hbWV9fVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiICpuZ0Zvcj1cImxldCBhY3Rpb24gb2YgbWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50YWJsZUFjdGlvbnNcIiBbZGlzYWJsZWRdPVwiaGFzTWFueVRhYmxlQWN0aW9uRGlzYWJsZWQoYWN0aW9uKVwiIChjbGljayk9XCJydW5IYXNNYW55VGFibGVBY3Rpb24oYWN0aW9uKVwiIG1hdC1tZW51LWl0ZW0+XG4gICAgICAgICAgICAgICAgICAgIHt7YWN0aW9uLmRpc3BsYXlOYW1lfX1cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvbWF0LW1lbnU+XG5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAqbmdJZj1cImhhc01hbnlBbGxvd0NyZWF0ZVwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmNvbC1sZy0yXT1cIm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEudGFibGVBY3Rpb25zLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmNvbC1sZy00XT1cIiFtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtbWQtM109XCJtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtbWQtNl09XCIhbWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50YWJsZUFjdGlvbnMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuY29sLXNtLTZdPVwibWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50YWJsZUFjdGlvbnMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuY29sLXNtLTEyXT1cIiFtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5sZW5ndGhcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiY3JlYXRlLWJ1dHRvblwiIChjbGljayk9XCJjcmVhdGVIYXNNYW55RW50aXR5KClcIiBtYXQtcmFpc2VkLWJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAge3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmNyZWF0ZUJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwibWF0LWVsZXZhdGlvbi16OCBlbGV2YXRpb24tY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8bWF0LXRhYmxlIFtkYXRhU291cmNlXT1cImhhc01hbnlEYXRhU291cmNlXCIgbWF0U29ydD5cbiAgICAgICAgICAgICAgICA8IS0tIHNlbGVjdCBDb2x1bW4gLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzZWxlY3RcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNoYW5nZSk9XCIkZXZlbnQgPyBTZWxlY3Rpb25VdGlsaXRpZXMubWFzdGVyVG9nZ2xlKGhhc01hbnlTZWxlY3Rpb24sIGhhc01hbnlEYXRhU291cmNlKSA6IG51bGxcIiBbY2hlY2tlZF09XCJoYXNNYW55U2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgU2VsZWN0aW9uVXRpbGl0aWVzLmlzQWxsU2VsZWN0ZWQoaGFzTWFueVNlbGVjdGlvbiwgaGFzTWFueURhdGFTb3VyY2UpXCIgW2luZGV0ZXJtaW5hdGVdPVwiaGFzTWFueVNlbGVjdGlvbi5oYXNWYWx1ZSgpICYmICFTZWxlY3Rpb25VdGlsaXRpZXMuaXNBbGxTZWxlY3RlZChoYXNNYW55U2VsZWN0aW9uLCBoYXNNYW55RGF0YVNvdXJjZSlcIj4gPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWhlYWRlci1jZWxsPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZW50aXR5XCIgY2xhc3M9XCJlbmFibGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiAoY2hhbmdlKT1cIiRldmVudCA/IGhhc01hbnlTZWxlY3Rpb24udG9nZ2xlKGVudGl0eSkgOiBudWxsXCIgW2NoZWNrZWRdPVwiaGFzTWFueVNlbGVjdGlvbi5pc1NlbGVjdGVkKGVudGl0eSlcIj4gPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWNlbGw+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBkQ29sIG9mIG1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuZGlzcGxheUNvbHVtbnNcIiBbbWF0Q29sdW1uRGVmXT1cImRDb2wuZGlzcGxheU5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7e2RDb2wuZGlzcGxheU5hbWV9fVxuICAgICAgICAgICAgICAgICAgICA8L21hdC1oZWFkZXItY2VsbD5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1jZWxsIFtjbGFzcy5lbmFibGVkXT1cIiFkQ29sLmRpc2FibGVDbGljayAmJiAoaGFzTWFueUFsbG93VXBkYXRlKGVudGl0eSkgfHwgaGFzTWFueUFsbG93UmVhZChlbnRpdHkpKVwiIChjbGljayk9XCJlZGl0SGFzTWFueUVudGl0eShlbnRpdHksIGRDb2wpXCIgKm1hdENlbGxEZWY9XCJsZXQgZW50aXR5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZENvbC5Db21wb25lbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGlzcGxheS1jb2x1bW4tdmFsdWUgW2VudGl0eV09XCJlbnRpdHlcIiBbQ29tcG9uZW50Q2xhc3NdPVwiZENvbC5Db21wb25lbnRcIj48L2Rpc3BsYXktY29sdW1uLXZhbHVlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWRDb2wuQ29tcG9uZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tnZXREaXNwbGF5Q29sdW1uVmFsdWUoZW50aXR5LCBkQ29sKX19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2VsbD5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDxtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZGlzcGxheWVkSGFzTWFueUNvbHVtbnNcIj48L21hdC1oZWFkZXItcm93PlxuICAgICAgICAgICAgICAgIDxtYXQtcm93ICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOiBkaXNwbGF5ZWRIYXNNYW55Q29sdW1uc1wiPjwvbWF0LXJvdz5cbiAgICAgICAgICAgIDwvbWF0LXRhYmxlPlxuXG4gICAgICAgICAgICA8bWF0LXNwaW5uZXIgKm5nSWY9XCJoYXNNYW55SXNMb2FkaW5nICYmIG1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuZGlzcGxheUxvYWRpbmdTcGlubmVyXCI+XG4gICAgICAgICAgICA8L21hdC1zcGlubmVyPlxuXG4gICAgICAgICAgICA8bWF0LXBhZ2luYXRvciBbbGVuZ3RoXT1cImhhc01hbnlEYXRhU291cmNlLmZpbHRlcmVkRGF0YS5sZW5ndGhcIiBbcGFnZUluZGV4XT1cIjBcIiBbcGFnZVNpemVdPVwiMTBcIiBbcGFnZVNpemVPcHRpb25zXT1cIls1LCAxMCwgMjUsIDUwXVwiPjwvbWF0LXBhZ2luYXRvcj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2ICpuZ1N3aXRjaERlZmF1bHQ+RVJST1I6IFRoZSB0eXBlIHt7dHlwZX19IGlzIG5vdCBrbm93bi48L2Rpdj5cbjwvZGl2PlxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbjwhLS0tLS0tLS0tLS0tLS0tLS0tLS1BZGQgQXJyYXkgSXRlbSBEaWFsb2ctLS0tLS0tLS0tLS0tLS0tPlxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG48bmctdGVtcGxhdGUgI2FkZEFycmF5SXRlbURpYWxvZz5cbiAgICA8ZGl2IGNsYXNzPVwibWF0LWRpYWxvZy10aXRsZVwiPlxuICAgICAgICA8ZGl2Pnt7YWRkQXJyYXlJdGVtRGlhbG9nRGF0YS50aXRsZX19PC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8Zm9ybT5cbiAgICAgICAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICAgICAgICAgIDxtYXQtdGFiLWdyb3VwICpuZ0lmPVwiYXJyYXlJdGVtRGlhbG9nVGFicy5sZW5ndGggPiAxXCIgcHJlc2VydmVDb250ZW50PlxuICAgICAgICAgICAgICAgIDxtYXQtdGFiICpuZ0Zvcj1cImxldCB0YWIgb2YgYXJyYXlJdGVtRGlhbG9nVGFic1wiIFtsYWJlbF09XCJ0YWIudGFiTmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nRm9yPVwibGV0IHJvdyBvZiB0YWIucm93c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGtleSBvZiByb3cua2V5c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJhcnJheUl0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eUtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckNyZWF0ZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLWxnLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnbGcnKX19IGNvbC1tZC17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ21kJyl9fSBjb2wtc20te3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdzbScpfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImNoZWNrSXNBcnJheUl0ZW1WYWxpZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmd4LW1hdC1lbnRpdHktaW5wdXQ+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICAgIDwvbWF0LXRhYi1ncm91cD5cbiAgICBcbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJhcnJheUl0ZW1EaWFsb2dUYWJzLmxlbmd0aCA8PSAxXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgYXJyYXlJdGVtRGlhbG9nVGFic1swXS5yb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZ3gtbWF0LWVudGl0eS1pbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGtleSBvZiByb3cua2V5c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZW50aXR5XT1cImFycmF5SXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckNyZWF0ZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdtZCcpfX0gY29sLXNtLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImNoZWNrSXNBcnJheUl0ZW1WYWxpZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8L25neC1tYXQtZW50aXR5LWlucHV0PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LWRpYWxvZy1jb250ZW50PlxuICAgIFxuICAgICAgICA8bWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cImFkZEFycmF5SXRlbSgpXCIgW2Rpc2FibGVkXT1cIiFpc0FycmF5SXRlbVZhbGlkXCI+XG4gICAgICAgICAgICAgICAge3thZGRBcnJheUl0ZW1EaWFsb2dEYXRhLmNyZWF0ZUJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cImNsb3NlQWRkQXJyYXlJdGVtRGlhbG9nKClcIiBjbGFzcz1cImNhbmNlbC1idXR0b25cIj5cbiAgICAgICAgICAgICAgICB7e2FkZEFycmF5SXRlbURpYWxvZ0RhdGEuY2FuY2VsQnV0dG9uTGFiZWx9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgIDwvZm9ybT5cblxuPC9uZy10ZW1wbGF0ZT5cblxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tRWRpdCBBcnJheSBJdGVtIERpYWxvZy0tLS0tLS0tLS0tLS0tLS0+XG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbjxuZy10ZW1wbGF0ZSAjZWRpdEFycmF5SXRlbURpYWxvZz5cbiAgICA8ZGl2IGNsYXNzPVwibWF0LWRpYWxvZy10aXRsZVwiPlxuICAgICAgICA8ZGl2Pnt7ZWRpdEFycmF5SXRlbURpYWxvZ0RhdGEudGl0bGUoYXJyYXlJdGVtUHJpb3JDaGFuZ2VzKX19PC9kaXY+XG4gICAgPC9kaXY+XG4gICAgXG4gICAgPGZvcm0+XG4gICAgICAgIDxtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICAgICAgICA8bWF0LXRhYi1ncm91cCAqbmdJZj1cImFycmF5SXRlbURpYWxvZ1RhYnMubGVuZ3RoID4gMVwiIHByZXNlcnZlQ29udGVudD5cbiAgICAgICAgICAgICAgICA8bWF0LXRhYiAqbmdGb3I9XCJsZXQgdGFiIG9mIGFycmF5SXRlbURpYWxvZ1RhYnNcIiBbbGFiZWxdPVwidGFiLnRhYk5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgdGFiLnJvd3NcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZ3gtbWF0LWVudGl0eS1pbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiYXJyYXlJdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JFZGl0XT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLWxnLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnbGcnKX19IGNvbC1tZC17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ21kJyl9fSBjb2wtc20te3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdzbScpfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImNoZWNrQXJyYXlJdGVtKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImlzUHJvcGVydHlSZWFkT25seShhcnJheUl0ZW0sIGtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgICAgICBcbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJhcnJheUl0ZW1EaWFsb2dUYWJzLmxlbmd0aCA8PSAxXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgYXJyYXlJdGVtRGlhbG9nVGFic1swXS5yb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZ3gtbWF0LWVudGl0eS1pbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGtleSBvZiByb3cua2V5c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZW50aXR5XT1cImFycmF5SXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckVkaXRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdtZCcpfX0gY29sLXNtLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImNoZWNrQXJyYXlJdGVtKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaXNQcm9wZXJ0eVJlYWRPbmx5KGFycmF5SXRlbSwga2V5KVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC1kaWFsb2ctY29udGVudD5cbiAgICAgICAgXG4gICAgICAgIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiAoY2xpY2spPVwic2F2ZUFycmF5SXRlbSgpXCIgbWF0LXJhaXNlZC1idXR0b24gW2Rpc2FibGVkXT1cImludGVybmFsSXNSZWFkT25seSB8fCAhaXNBcnJheUl0ZW1WYWxpZCB8fCAhaXNBcnJheUl0ZW1EaXJ0eVwiPlxuICAgICAgICAgICAgICAgIHt7ZWRpdEFycmF5SXRlbURpYWxvZ0RhdGEuY29uZmlybUJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cImNsb3NlRWRpdEFycmF5SXRlbURpYWxvZygpXCIgY2xhc3M9XCJjYW5jZWwtYnV0dG9uXCI+XG4gICAgICAgICAgICAgICAge3tlZGl0QXJyYXlJdGVtRGlhbG9nRGF0YS5jYW5jZWxCdXR0b25MYWJlbH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgPC9mb3JtPlxuPC9uZy10ZW1wbGF0ZT5cblxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tQ3JlYXRlIEhhcyBNYW55IERpYWxvZy0tLS0tLS0tLS0tLS0tLS0+XG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbjxuZy10ZW1wbGF0ZSAjY3JlYXRlSGFzTWFueURpYWxvZz5cbiAgICA8ZGl2IGNsYXNzPVwibWF0LWRpYWxvZy10aXRsZVwiPlxuICAgICAgICA8ZGl2Pnt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5jcmVhdGVEaWFsb2dEYXRhLnRpdGxlfX08L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICBcbiAgICA8Zm9ybT5cbiAgICAgICAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICAgICAgICAgIDxtYXQtdGFiLWdyb3VwICpuZ0lmPVwiaGFzTWFueUNyZWF0ZVRhYnMubGVuZ3RoID4gMVwiIHByZXNlcnZlQ29udGVudD5cbiAgICAgICAgICAgICAgICA8bWF0LXRhYiAqbmdGb3I9XCJsZXQgdGFiIG9mIGhhc01hbnlDcmVhdGVUYWJzXCIgW2xhYmVsXT1cInRhYi50YWJOYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIHRhYi5yb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmd4LW1hdC1lbnRpdHktaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQga2V5IG9mIHJvdy5rZXlzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZW50aXR5XT1cImhhc01hbnlFbnRpdHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eUtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckNyZWF0ZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChoYXNNYW55RW50aXR5LCBrZXksICdsZycpfX0gY29sLW1kLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGhhc01hbnlFbnRpdHksIGtleSwgJ21kJyl9fSBjb2wtc20te3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoaGFzTWFueUVudGl0eSwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjaGVja0lzSGFzTWFueUVudGl0eVZhbGlkKCdjcmVhdGUnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25neC1tYXQtZW50aXR5LWlucHV0PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICA8L21hdC10YWItZ3JvdXA+XG4gICAgICAgIFxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImhhc01hbnlDcmVhdGVUYWJzLmxlbmd0aCA8PSAxXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgaGFzTWFueUNyZWF0ZVRhYnNbMF0ucm93c1wiPlxuICAgICAgICAgICAgICAgICAgICA8bmd4LW1hdC1lbnRpdHktaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJoYXNNYW55RW50aXR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eUtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2hpZGVPbWl0Rm9yQ3JlYXRlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtbGcte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoaGFzTWFueUVudGl0eSwga2V5LCAnbGcnKX19IGNvbC1tZC17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChoYXNNYW55RW50aXR5LCBrZXksICdtZCcpfX0gY29sLXNtLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGhhc01hbnlFbnRpdHksIGtleSwgJ3NtJyl9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjaGVja0lzSGFzTWFueUVudGl0eVZhbGlkKCdjcmVhdGUnKVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC1kaWFsb2ctY29udGVudD5cbiAgICAgICAgXG4gICAgICAgIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiAoY2xpY2spPVwiZGlhbG9nQ3JlYXRlSGFzTWFueSgpXCIgbWF0LXJhaXNlZC1idXR0b24gW2Rpc2FibGVkXT1cIiFpc0hhc01hbnlFbnRpdHlWYWxpZFwiPlxuICAgICAgICAgICAgICAgIHt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5jcmVhdGVEaWFsb2dEYXRhLmNyZWF0ZUJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cImRpYWxvZ0NhbmNlbENyZWF0ZUhhc01hbnkoKVwiIGNsYXNzPVwiY2FuY2VsLWJ1dHRvblwiPlxuICAgICAgICAgICAgICAgIHt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5jcmVhdGVEaWFsb2dEYXRhLmNhbmNlbEJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICA8L2Zvcm0+XG4gICAgXG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI2VkaXRIYXNNYW55RGlhbG9nPlxuICAgIDxkaXYgY2xhc3M9XCJtYXQtZGlhbG9nLXRpdGxlXCI+XG4gICAgICAgIDxkaXY+e3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmVkaXREYXRhLnRpdGxlKGhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMpfX08L2Rpdj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKm5nSWY9XCJoYXNNYW55QWxsb3dEZWxldGUoaGFzTWFueUVudGl0eSlcIiBtYXQtcmFpc2VkLWJ1dHRvbiAoY2xpY2spPVwiZGVsZXRlSGFzTWFueUVudGl0eSgpXCIgY29sb3I9XCJ3YXJuXCIgY2xhc3M9XCJkZWxldGUtYnV0dG9uXCIgdGFiaW5kZXg9XCItMVwiPlxuICAgICAgICAgICAge3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmVkaXREYXRhLmRlbGV0ZUJ1dHRvbkxhYmVsfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gICAgXG4gICAgPGZvcm0+XG4gICAgICAgIDxtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICAgICAgICA8bWF0LXRhYi1ncm91cCAqbmdJZj1cImhhc01hbnlVcGRhdGVUYWJzLmxlbmd0aCA+IDFcIiBwcmVzZXJ2ZUNvbnRlbnQ+XG4gICAgICAgICAgICAgICAgPG1hdC10YWIgKm5nRm9yPVwibGV0IHRhYiBvZiBoYXNNYW55VXBkYXRlVGFic1wiIFtsYWJlbF09XCJ0YWIudGFiTmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nRm9yPVwibGV0IHJvdyBvZiB0YWIucm93c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGtleSBvZiByb3cua2V5c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJoYXNNYW55RW50aXR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JFZGl0XT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLWxnLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGhhc01hbnlFbnRpdHksIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoaGFzTWFueUVudGl0eSwga2V5LCAnbWQnKX19IGNvbC1zbS17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChoYXNNYW55RW50aXR5LCBrZXksICdzbScpfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImNoZWNrSGFzTWFueUVudGl0eSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNSZWFkT25seV09XCJpc1Byb3BlcnR5UmVhZE9ubHkoaGFzTWFueUVudGl0eSwga2V5KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25neC1tYXQtZW50aXR5LWlucHV0PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICA8L21hdC10YWItZ3JvdXA+XG4gICAgICAgIFxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImhhc01hbnlVcGRhdGVUYWJzLmxlbmd0aCA8PSAxXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgaGFzTWFueVVwZGF0ZVRhYnNbMF0ucm93c1wiPlxuICAgICAgICAgICAgICAgICAgICA8bmd4LW1hdC1lbnRpdHktaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJoYXNNYW55RW50aXR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eUtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2hpZGVPbWl0Rm9yRWRpdF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLWxnLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGhhc01hbnlFbnRpdHksIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoaGFzTWFueUVudGl0eSwga2V5LCAnbWQnKX19IGNvbC1zbS17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChoYXNNYW55RW50aXR5LCBrZXksICdzbScpfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiY2hlY2tIYXNNYW55RW50aXR5KClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaXNQcm9wZXJ0eVJlYWRPbmx5KGhhc01hbnlFbnRpdHksIGtleSlcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDwvbmd4LW1hdC1lbnRpdHktaW5wdXQ+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICAgIFxuICAgICAgICA8bWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgKGNsaWNrKT1cImRpYWxvZ0VkaXRIYXNNYW55KClcIiBtYXQtcmFpc2VkLWJ1dHRvbiBbZGlzYWJsZWRdPVwiaW50ZXJuYWxJc1JlYWRPbmx5IHx8ICFpc0hhc01hbnlFbnRpdHlWYWxpZCB8fCAhaXNIYXNNYW55RW50aXR5RGlydHlcIj5cbiAgICAgICAgICAgICAgICB7e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuY29uZmlybUJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cImRpYWxvZ0NhbmNlbEVkaXRIYXNNYW55KClcIiBjbGFzcz1cImNhbmNlbC1idXR0b25cIj5cbiAgICAgICAgICAgICAgICB7e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuY2FuY2VsQnV0dG9uTGFiZWx9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgIDwvZm9ybT4gICAgXG48L25nLXRlbXBsYXRlPiJdfQ==
|