ngx-techlify-core 18.79.0 → 18.80.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/esm2022/lib/audit-log/audit-log-view/audit-log-view.component.mjs +12 -10
- package/esm2022/lib/base-model/techlify-list/techlify-list.component.mjs +3 -3
- package/esm2022/lib/core/form-validator.service.mjs +2 -2
- package/esm2022/lib/core/index.mjs +1 -2
- package/esm2022/lib/request-helper/request-helper.service.mjs +14 -4
- package/esm2022/lib/user/app-admin-user-list/app-admin-user-list.component.mjs +32 -56
- package/esm2022/lib/user/app-admin-user-view/app-admin-user-view.component.mjs +17 -31
- package/esm2022/lib/user/app-admin-user-view/app-admin-user-view.module.mjs +5 -16
- package/esm2022/lib/user/index.mjs +3 -3
- package/esm2022/lib/user/user-form/user-form.component.mjs +204 -0
- package/esm2022/lib/user/user-list/user-list.component.mjs +156 -0
- package/esm2022/lib/user/user-view.component.mjs +17 -31
- package/esm2022/lib/user/user.module.mjs +12 -64
- package/esm2022/lib/user/user.routes.mjs +3 -3
- package/fesm2022/ngx-techlify-core.mjs +268 -494
- package/fesm2022/ngx-techlify-core.mjs.map +1 -1
- package/lib/audit-log/audit-log-view/audit-log-view.component.d.ts +3 -3
- package/lib/core/index.d.ts +0 -1
- package/lib/request-helper/request-helper.service.d.ts +9 -0
- package/lib/user/app-admin-user-list/app-admin-user-list.component.d.ts +3 -4
- package/lib/user/app-admin-user-view/app-admin-user-view.component.d.ts +3 -4
- package/lib/user/app-admin-user-view/app-admin-user-view.module.d.ts +8 -10
- package/lib/user/index.d.ts +2 -2
- package/lib/user/user-form/user-form.component.d.ts +43 -0
- package/lib/user/user-list/user-list.component.d.ts +38 -0
- package/lib/user/user-view.component.d.ts +3 -4
- package/lib/user/user.module.d.ts +13 -26
- package/package.json +1 -1
- package/esm2022/lib/core/dataManager.service.mjs +0 -119
- package/esm2022/lib/user/user-form.component.mjs +0 -225
- package/esm2022/lib/user/users-view-all.component.mjs +0 -153
- package/lib/core/dataManager.service.d.ts +0 -73
- package/lib/user/user-form.component.d.ts +0 -53
- package/lib/user/users-view-all.component.d.ts +0 -39
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { CommonModule } from '@angular/common';
|
|
2
1
|
import { NgModule } from '@angular/core';
|
|
3
|
-
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
4
2
|
import { FlexLayoutModule } from '@angular/flex-layout';
|
|
5
3
|
import { AppAdminUserViewComponent, } from './app-admin-user-view.component';
|
|
6
|
-
import {
|
|
4
|
+
import { SharedModule } from '../../shared.module';
|
|
7
5
|
import { LoginHistoryForUserModule } from '../../login-history-for-user/login-history-for-user.module';
|
|
8
6
|
import { AuditLogListModule } from '../../audit-log/audit-log-list/audit-log-list.module';
|
|
9
7
|
import { AppAdminUserViewRoutingProvider } from './app-admin-user-view.routes';
|
|
@@ -12,21 +10,15 @@ import { UserSessionsModule } from '../user-sessions/user-sessions/user-sessions
|
|
|
12
10
|
import * as i0 from "@angular/core";
|
|
13
11
|
export class AppAdminUserViewModule {
|
|
14
12
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AppAdminUserViewModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
15
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: AppAdminUserViewModule, declarations: [AppAdminUserViewComponent], imports: [
|
|
16
|
-
MaterialModule,
|
|
13
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: AppAdminUserViewModule, declarations: [AppAdminUserViewComponent], imports: [SharedModule,
|
|
17
14
|
FlexLayoutModule,
|
|
18
|
-
FormsModule,
|
|
19
|
-
ReactiveFormsModule,
|
|
20
15
|
LoginHistoryForUserModule,
|
|
21
16
|
AuditLogListModule,
|
|
22
17
|
AppAdminUserViewRoutingProvider,
|
|
23
18
|
UserClientsListModule,
|
|
24
19
|
UserSessionsModule], exports: [AppAdminUserViewComponent] }); }
|
|
25
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AppAdminUserViewModule, imports: [
|
|
26
|
-
MaterialModule,
|
|
20
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AppAdminUserViewModule, imports: [SharedModule,
|
|
27
21
|
FlexLayoutModule,
|
|
28
|
-
FormsModule,
|
|
29
|
-
ReactiveFormsModule,
|
|
30
22
|
LoginHistoryForUserModule,
|
|
31
23
|
AuditLogListModule,
|
|
32
24
|
AppAdminUserViewRoutingProvider,
|
|
@@ -37,11 +29,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
37
29
|
type: NgModule,
|
|
38
30
|
args: [{
|
|
39
31
|
imports: [
|
|
40
|
-
|
|
41
|
-
MaterialModule,
|
|
32
|
+
SharedModule,
|
|
42
33
|
FlexLayoutModule,
|
|
43
|
-
FormsModule,
|
|
44
|
-
ReactiveFormsModule,
|
|
45
34
|
LoginHistoryForUserModule,
|
|
46
35
|
AuditLogListModule,
|
|
47
36
|
AppAdminUserViewRoutingProvider,
|
|
@@ -56,4 +45,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
56
45
|
]
|
|
57
46
|
}]
|
|
58
47
|
}] });
|
|
59
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
48
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLWFkbWluLXVzZXItdmlldy5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdGVjaGxpZnktY29yZS9zcmMvbGliL3VzZXIvYXBwLWFkbWluLXVzZXItdmlldy9hcHAtYWRtaW4tdXNlci12aWV3Lm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3hELE9BQU8sRUFBRSx5QkFBeUIsR0FBRyxNQUFNLGlDQUFpQyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw0REFBNEQsQ0FBQztBQUN2RyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxzREFBc0QsQ0FBQztBQUMxRixPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMvRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUN6RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQzs7QUFtQnpGLE1BQU0sT0FBTyxzQkFBc0I7K0dBQXRCLHNCQUFzQjtnSEFBdEIsc0JBQXNCLGlCQU4vQix5QkFBeUIsYUFUekIsWUFBWTtZQUNaLGdCQUFnQjtZQUNoQix5QkFBeUI7WUFDekIsa0JBQWtCO1lBQ2xCLCtCQUErQjtZQUMvQixxQkFBcUI7WUFDckIsa0JBQWtCLGFBTWxCLHlCQUF5QjtnSEFHaEIsc0JBQXNCLFlBZi9CLFlBQVk7WUFDWixnQkFBZ0I7WUFDaEIseUJBQXlCO1lBQ3pCLGtCQUFrQjtZQUNsQiwrQkFBK0I7WUFDL0IscUJBQXFCO1lBQ3JCLGtCQUFrQjs7NEZBU1Qsc0JBQXNCO2tCQWpCbEMsUUFBUTttQkFBQztvQkFDUixPQUFPLEVBQUU7d0JBQ1AsWUFBWTt3QkFDWixnQkFBZ0I7d0JBQ2hCLHlCQUF5Qjt3QkFDekIsa0JBQWtCO3dCQUNsQiwrQkFBK0I7d0JBQy9CLHFCQUFxQjt3QkFDckIsa0JBQWtCO3FCQUNuQjtvQkFDRCxZQUFZLEVBQUU7d0JBQ1oseUJBQXlCO3FCQUMxQjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1AseUJBQXlCO3FCQUMxQjtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbIlxuaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZsZXhMYXlvdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mbGV4LWxheW91dCc7XG5pbXBvcnQgeyBBcHBBZG1pblVzZXJWaWV3Q29tcG9uZW50LCB9IGZyb20gJy4vYXBwLWFkbWluLXVzZXItdmlldy5jb21wb25lbnQnO1xuaW1wb3J0IHsgU2hhcmVkTW9kdWxlIH0gZnJvbSAnLi4vLi4vc2hhcmVkLm1vZHVsZSc7XG5pbXBvcnQgeyBMb2dpbkhpc3RvcnlGb3JVc2VyTW9kdWxlIH0gZnJvbSAnLi4vLi4vbG9naW4taGlzdG9yeS1mb3ItdXNlci9sb2dpbi1oaXN0b3J5LWZvci11c2VyLm1vZHVsZSc7XG5pbXBvcnQgeyBBdWRpdExvZ0xpc3RNb2R1bGUgfSBmcm9tICcuLi8uLi9hdWRpdC1sb2cvYXVkaXQtbG9nLWxpc3QvYXVkaXQtbG9nLWxpc3QubW9kdWxlJztcbmltcG9ydCB7IEFwcEFkbWluVXNlclZpZXdSb3V0aW5nUHJvdmlkZXIgfSBmcm9tICcuL2FwcC1hZG1pbi11c2VyLXZpZXcucm91dGVzJztcbmltcG9ydCB7IFVzZXJDbGllbnRzTGlzdE1vZHVsZSB9IGZyb20gJy4uLy4uL3VzZXItY2xpZW50cy1saXN0L3VzZXItY2xpZW50cy1saXN0Lm1vZHVsZSc7XG5pbXBvcnQgeyBVc2VyU2Vzc2lvbnNNb2R1bGUgfSBmcm9tICcuLi91c2VyLXNlc3Npb25zL3VzZXItc2Vzc2lvbnMvdXNlci1zZXNzaW9ucy5tb2R1bGUnO1xuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbXG4gICAgU2hhcmVkTW9kdWxlLFxuICAgIEZsZXhMYXlvdXRNb2R1bGUsXG4gICAgTG9naW5IaXN0b3J5Rm9yVXNlck1vZHVsZSxcbiAgICBBdWRpdExvZ0xpc3RNb2R1bGUsXG4gICAgQXBwQWRtaW5Vc2VyVmlld1JvdXRpbmdQcm92aWRlcixcbiAgICBVc2VyQ2xpZW50c0xpc3RNb2R1bGUsXG4gICAgVXNlclNlc3Npb25zTW9kdWxlXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW1xuICAgIEFwcEFkbWluVXNlclZpZXdDb21wb25lbnRcbiAgXSxcbiAgZXhwb3J0czogW1xuICAgIEFwcEFkbWluVXNlclZpZXdDb21wb25lbnRcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBBcHBBZG1pblVzZXJWaWV3TW9kdWxlIHsgfVxuIl19
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export * from './current-user.service';
|
|
2
2
|
export * from './user-explore.component';
|
|
3
|
-
export * from './user-form.component';
|
|
3
|
+
export * from './user-form/user-form.component';
|
|
4
4
|
export * from './user.model';
|
|
5
5
|
export * from './user.service';
|
|
6
|
-
export * from './
|
|
6
|
+
export * from './user-list/user-list.component';
|
|
7
7
|
export * from './user.routes';
|
|
8
8
|
export * from '../user-clients-list/user-clients-list.component';
|
|
9
9
|
export * from '../user-clients-list/user-clients-list.module';
|
|
@@ -11,4 +11,4 @@ export * from '../user-client-enable-disable-button/user-client-enable-disable-b
|
|
|
11
11
|
export * from '../user-client-enable-disable-button/user-client-enable-disable-button.module';
|
|
12
12
|
export * from './user-sessions/user-sessions/user-sessions.component';
|
|
13
13
|
export * from './user-sessions/user-sessions/user-sessions.module';
|
|
14
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdGVjaGxpZnktY29yZS9zcmMvbGliL3VzZXIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsaUNBQWlDLENBQUM7QUFDaEQsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLGlDQUFpQyxDQUFDO0FBQ2hELGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsa0RBQWtELENBQUM7QUFDakUsY0FBYywrQ0FBK0MsQ0FBQztBQUM5RCxjQUFjLGtGQUFrRixDQUFDO0FBQ2pHLGNBQWMsK0VBQStFLENBQUM7QUFDOUYsY0FBYyx1REFBdUQsQ0FBQztBQUN0RSxjQUFjLG9EQUFvRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9jdXJyZW50LXVzZXIuc2VydmljZSc7XG5leHBvcnQgKiBmcm9tICcuL3VzZXItZXhwbG9yZS5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi91c2VyLWZvcm0vdXNlci1mb3JtLmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL3VzZXIubW9kZWwnO1xuZXhwb3J0ICogZnJvbSAnLi91c2VyLnNlcnZpY2UnO1xuZXhwb3J0ICogZnJvbSAnLi91c2VyLWxpc3QvdXNlci1saXN0LmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuL3VzZXIucm91dGVzJztcbmV4cG9ydCAqIGZyb20gJy4uL3VzZXItY2xpZW50cy1saXN0L3VzZXItY2xpZW50cy1saXN0LmNvbXBvbmVudCc7XG5leHBvcnQgKiBmcm9tICcuLi91c2VyLWNsaWVudHMtbGlzdC91c2VyLWNsaWVudHMtbGlzdC5tb2R1bGUnO1xuZXhwb3J0ICogZnJvbSAnLi4vdXNlci1jbGllbnQtZW5hYmxlLWRpc2FibGUtYnV0dG9uL3VzZXItY2xpZW50LWVuYWJsZS1kaXNhYmxlLWJ1dHRvbi5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi4vdXNlci1jbGllbnQtZW5hYmxlLWRpc2FibGUtYnV0dG9uL3VzZXItY2xpZW50LWVuYWJsZS1kaXNhYmxlLWJ1dHRvbi5tb2R1bGUnO1xuZXhwb3J0ICogZnJvbSAnLi91c2VyLXNlc3Npb25zL3VzZXItc2Vzc2lvbnMvdXNlci1zZXNzaW9ucy5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi91c2VyLXNlc3Npb25zL3VzZXItc2Vzc2lvbnMvdXNlci1zZXNzaW9ucy5tb2R1bGUnO1xuIl19
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { Component, Inject } from '@angular/core';
|
|
2
|
+
import { Validators, UntypedFormControl } from '@angular/forms';
|
|
3
|
+
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
|
|
4
|
+
import { FileDropperModule } from "../../file-dropper/file-dropper.module";
|
|
5
|
+
import { DocumentViewerModule } from "../../document-viewer/document-viewer.module";
|
|
6
|
+
import { UserTypeEnum } from '../user-type.enum';
|
|
7
|
+
import { TechlifyFormComponent } from '../../base-model';
|
|
8
|
+
import { SharedModule } from '../../shared.module';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
import * as i1 from "@angular/material/dialog";
|
|
11
|
+
import * as i2 from "../../core";
|
|
12
|
+
import * as i3 from "@angular/forms";
|
|
13
|
+
import * as i4 from "../../core/form-validator.service";
|
|
14
|
+
import * as i5 from "../user.service";
|
|
15
|
+
import * as i6 from "../current-user.service";
|
|
16
|
+
import * as i7 from "../../user-config/user-config.service";
|
|
17
|
+
import * as i8 from "@angular/common";
|
|
18
|
+
import * as i9 from "@angular/material/button";
|
|
19
|
+
import * as i10 from "@angular/material/checkbox";
|
|
20
|
+
import * as i11 from "@angular/material/form-field";
|
|
21
|
+
import * as i12 from "@angular/material/input";
|
|
22
|
+
import * as i13 from "@angular/material/core";
|
|
23
|
+
import * as i14 from "@angular/material/select";
|
|
24
|
+
import * as i15 from "../../file-dropper/file-dropper.component";
|
|
25
|
+
import * as i16 from "../../document-viewer/document-viewer.component";
|
|
26
|
+
export class UserFormComponent extends TechlifyFormComponent {
|
|
27
|
+
constructor(dialogRef, data, http, fb, formValidatorService, userService, currentUserService, userConfigService) {
|
|
28
|
+
super(formValidatorService, userService);
|
|
29
|
+
this.dialogRef = dialogRef;
|
|
30
|
+
this.data = data;
|
|
31
|
+
this.http = http;
|
|
32
|
+
this.fb = fb;
|
|
33
|
+
this.formValidatorService = formValidatorService;
|
|
34
|
+
this.userService = userService;
|
|
35
|
+
this.currentUserService = currentUserService;
|
|
36
|
+
this.userConfigService = userConfigService;
|
|
37
|
+
this.isPasswordRequired = false;
|
|
38
|
+
this.userTypes = [
|
|
39
|
+
{ title: 'Admin', value: 2 },
|
|
40
|
+
{ title: 'Normal User', value: 3 },
|
|
41
|
+
];
|
|
42
|
+
this.roles = [];
|
|
43
|
+
this.fileList = [];
|
|
44
|
+
this.errorMessages = {
|
|
45
|
+
name: {
|
|
46
|
+
required: 'Name is required'
|
|
47
|
+
},
|
|
48
|
+
email: {
|
|
49
|
+
required: 'Email is required',
|
|
50
|
+
email: 'Invalid email',
|
|
51
|
+
},
|
|
52
|
+
password: {
|
|
53
|
+
required: 'Password is required'
|
|
54
|
+
},
|
|
55
|
+
user_type_id: {
|
|
56
|
+
required: 'User Type is required'
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
this.config = this.userConfigService.getConfig();
|
|
60
|
+
}
|
|
61
|
+
get roleForms() {
|
|
62
|
+
return this.form.get('roles');
|
|
63
|
+
}
|
|
64
|
+
get canUpdateUserCredential() {
|
|
65
|
+
return this.currentUserService.getUser().user_type_id == UserTypeEnum.ADMIN
|
|
66
|
+
|| (this.data?.model?.user_clients || [])?.length <= 1;
|
|
67
|
+
}
|
|
68
|
+
ngOnInit() {
|
|
69
|
+
this.userTypes = this.config.userConfig.showUserTypes
|
|
70
|
+
? this.config.userConfig.userTypes
|
|
71
|
+
: this.userTypes;
|
|
72
|
+
this.form = this.fb.group({
|
|
73
|
+
id: [''],
|
|
74
|
+
name: new UntypedFormControl('', Validators.compose([Validators.required])),
|
|
75
|
+
email: new UntypedFormControl('', Validators.compose([Validators.required, Validators.email])),
|
|
76
|
+
password: new UntypedFormControl(''),
|
|
77
|
+
phone: new UntypedFormControl(''),
|
|
78
|
+
user_type_id: new UntypedFormControl('', Validators.required),
|
|
79
|
+
roles: this.fb.array([]),
|
|
80
|
+
roles_exists: [[]],
|
|
81
|
+
client_id: [this.data?.client_id ?? ''],
|
|
82
|
+
signature_url: [''],
|
|
83
|
+
signature: [''],
|
|
84
|
+
is_temporary_password: [true],
|
|
85
|
+
});
|
|
86
|
+
const user = this.data?.model;
|
|
87
|
+
if (user) {
|
|
88
|
+
this.isUpdate = true;
|
|
89
|
+
this.form.patchValue(user);
|
|
90
|
+
this.form.controls.user_type_id.setValue(user.user_type_id);
|
|
91
|
+
this.form.controls.roles_exists.setValue(user.roles || []);
|
|
92
|
+
}
|
|
93
|
+
// The calling context's client_id always wins, even in edit mode (e.g. an app-admin
|
|
94
|
+
// managing a specific tenant's users should save against that tenant, not the user's own).
|
|
95
|
+
if (this.data?.client_id != null) {
|
|
96
|
+
this.form.controls.client_id.setValue(this.data.client_id);
|
|
97
|
+
}
|
|
98
|
+
if (this.config.userConfig.showRoles || this.config.userConfig.showFormRoles) {
|
|
99
|
+
this.loadRoles();
|
|
100
|
+
}
|
|
101
|
+
this.fileConfig = {
|
|
102
|
+
fileId: 'subjectFile',
|
|
103
|
+
containerId: 'subjectFileContainer',
|
|
104
|
+
styles: {
|
|
105
|
+
height: '200px'
|
|
106
|
+
},
|
|
107
|
+
multiple: false,
|
|
108
|
+
acceptFile: '*',
|
|
109
|
+
maxSize: 10,
|
|
110
|
+
acceptFileText: 'PNG and JPEG only'
|
|
111
|
+
};
|
|
112
|
+
this.viewerConfig = {
|
|
113
|
+
imageStyle: {
|
|
114
|
+
height: '200px',
|
|
115
|
+
width: '400px'
|
|
116
|
+
},
|
|
117
|
+
viewerStyle: {
|
|
118
|
+
height: '200px',
|
|
119
|
+
width: '100%'
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
if (!this.canUpdateUserCredential) {
|
|
123
|
+
this.form.get('email').disable();
|
|
124
|
+
this.form.get('password').disable();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
loadRoles() {
|
|
128
|
+
this.isWorking = true;
|
|
129
|
+
const filter = {
|
|
130
|
+
client_id: this.data?.client_id || this.data?.model?.client_id || '',
|
|
131
|
+
is_subscribed: true,
|
|
132
|
+
sort_by: 'label|asc'
|
|
133
|
+
};
|
|
134
|
+
this.http.get('api/roles', { params: filter }).toPromise().then((res) => {
|
|
135
|
+
let roles = res.data;
|
|
136
|
+
/* Lets set the roles this user has */
|
|
137
|
+
for (let role of roles) {
|
|
138
|
+
role.selected = this.form.value.roles_exists.find(roleData => roleData.id == role.id) ? true : false;
|
|
139
|
+
}
|
|
140
|
+
this.roles = roles;
|
|
141
|
+
this.isWorking = false;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
save() {
|
|
145
|
+
const data = this.form.getRawValue();
|
|
146
|
+
let roles = [];
|
|
147
|
+
this.roles.forEach((role) => {
|
|
148
|
+
if (role.selected) {
|
|
149
|
+
roles[role.id] = role;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
data.roles = roles;
|
|
153
|
+
super.submit(data);
|
|
154
|
+
}
|
|
155
|
+
roleSelected(event, roleId) {
|
|
156
|
+
this.roles.forEach((role) => {
|
|
157
|
+
if (role.id == roleId) {
|
|
158
|
+
role.selected = event.checked;
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async fileChanged(event) {
|
|
163
|
+
this.fileList = event;
|
|
164
|
+
if (this.fileList.length > 0) {
|
|
165
|
+
const result = await this.uploadEntityFile(this.fileList[0]);
|
|
166
|
+
this.form
|
|
167
|
+
.get('signature')
|
|
168
|
+
.setValue(result.item.file);
|
|
169
|
+
this.form
|
|
170
|
+
.get('signature_url')
|
|
171
|
+
.setValue(result.item.url);
|
|
172
|
+
this.fileList = [];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async removeFile() {
|
|
176
|
+
if (this.form.value.signature) {
|
|
177
|
+
this.form.patchValue({
|
|
178
|
+
signature: '',
|
|
179
|
+
signature_url: ''
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
uploadEntityFile(file) {
|
|
184
|
+
const formData = new FormData();
|
|
185
|
+
formData.append('fileData', file, file.name);
|
|
186
|
+
return this.http
|
|
187
|
+
.skipHeader()
|
|
188
|
+
.post('api/entity-files-upload', formData).toPromise();
|
|
189
|
+
}
|
|
190
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserFormComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: i2.HttpService }, { token: i3.UntypedFormBuilder }, { token: i4.FormValidatorService }, { token: i5.UserService }, { token: i6.CurrentUserService }, { token: i7.UserConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
191
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: UserFormComponent, isStandalone: true, selector: "app-user-form", usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"form\" (ngSubmit)=\"save()\">\n <div class=\"d-flex flex-column justify-content-start align-items center gap-1\" mat-dialog-content>\n <h5 class=\"fw-bold text-center\">{{ isUpdate ? 'Edit' : 'Create ' }} User</h5>\n <div class=\"d-flex\">\n <div class=\"d-flex flex-column flex-fill gap-1\">\n <mat-form-field>\n <mat-label>Full name</mat-label>\n <input [required]=\"!!form.get('name').validator\" autocomplete=\"off\" formControlName=\"name\" matInput\n placeholder=\"Full Name\" type=\"text\" />\n <mat-error *ngIf=\"isFieldValid('name') && !!form.get('name').validator\">{{ getErrorMessage('name') }}\n </mat-error>\n </mat-form-field>\n <mat-form-field>\n <mat-label>Email</mat-label>\n <input [required]=\"!!form.get('email').validator\" formControlName=\"email\" matInput placeholder=\"Email\"\n type=\"email\" />\n <mat-error *ngIf=\"isFieldValid('email') && !!form.get('email').validator\">\n {{ getErrorMessage('email') }}\n </mat-error>\n </mat-form-field>\n <mat-form-field *ngIf=\"this.config.userConfig.showPhone\">\n <mat-label>Phone</mat-label>\n <input autocomplete=\"off\" formControlName=\"phone\" matInput placeholder=\"Phone\" type=\"text\" />\n </mat-form-field>\n <mat-form-field>\n <mat-label>Password</mat-label>\n <input [required]=\"isPasswordRequired && !!form.get('password').validator\" autocomplete=\"off\"\n formControlName=\"password\" matInput placeholder=\"Password\" type=\"password\" />\n <mat-error *ngIf=\"isFieldValid('password') && !!form.get('password').validator\">\n {{ getErrorMessage('password') }}\n </mat-error>\n </mat-form-field>\n\n <div class=\"d-flex flex-column justify-content-start gap-1\">\n <mat-checkbox formControlName=\"is_temporary_password\">Is Temporary Password?</mat-checkbox>\n <small class=\"text-secondary\">Should this user to update password on first login?</small>\n </div>\n\n <div *ngIf=\"this.config.userConfig.showSignature\">\n <ng-template #fileUpload>\n <section class=\"col-12\">\n <div>User Signature</div>\n <app-file-dropper (fileChanged)=\"fileChanged($event)\" [config]=\"fileConfig\" [fileArray]=\"fileList\">\n </app-file-dropper>\n </section>\n </ng-template>\n <div *ngIf=\"form.get('signature').value;else fileUpload;\" class=\"col-12\">\n <app-document-viewer (remove)=\"removeFile()\" [config]=\"this.viewerConfig\"\n [fileUrl]=\"form.get('signature_url').value\" [file]=\"form.get('signature').value\">\n </app-document-viewer>\n </div>\n </div>\n <mat-form-field *ngIf=\"this.config.userConfig.showUserTypes\" class=\"mt-3\">\n <mat-label>User Type</mat-label>\n <mat-select autocomplete=\"off\" formControlName=\"user_type_id\" required>\n <mat-option *ngFor=\"let userType of userTypes\" [value]=\"userType.value\">\n {{ userType.title }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"isFieldValid('user_type_id')\">{{ getErrorMessage('user_type_id') }}</mat-error>\n </mat-form-field>\n </div>\n\n <div\n *ngIf=\"(this.config.userConfig.showRoles || this.config.userConfig.showFormRoles) && this.form.get('user_type_id').value == 3\"\n class=\"flex-fill ml-4\">\n <p class=\"mb-0 fw-bold\">\n Roles\n </p>\n <div *ngFor=\"let role of roles\" class=\"d-flex flex-column\">\n <mat-checkbox (change)=\"roleSelected($event, role.id)\" [checked]=\"role.selected\">\n {{ role.label }}\n </mat-checkbox>\n </div>\n </div>\n\n </div>\n <div class=\"d-flex justify-content-end align-items-center gap-3\">\n <button [disabled]=\"isWorking\" color=\"primary\" mat-raised-button type=\"submit\">\n Save\n </button>\n <button (click)=\"closeDialog()\" [disabled]=\"isWorking\" mat-flat-button type=\"button\">\n Cancel\n </button>\n </div>\n </div>\n</form>", dependencies: [{ kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "component", type: i9.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i10.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i11.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i11.MatLabel, selector: "mat-label" }, { kind: "directive", type: i11.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i12.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: i13.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i14.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FileDropperModule }, { kind: "component", type: i15.FileDropperComponent, selector: "app-file-dropper", inputs: ["fileArray", "config", "styles"], outputs: ["fileChanged"] }, { kind: "ngmodule", type: DocumentViewerModule }, { kind: "component", type: i16.DocumentViewerComponent, selector: "app-document-viewer", inputs: ["config", "file", "fileUrl", "disableEdit"], outputs: ["remove"] }] }); }
|
|
192
|
+
}
|
|
193
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserFormComponent, decorators: [{
|
|
194
|
+
type: Component,
|
|
195
|
+
args: [{ selector: 'app-user-form', standalone: true, imports: [
|
|
196
|
+
SharedModule,
|
|
197
|
+
FileDropperModule,
|
|
198
|
+
DocumentViewerModule
|
|
199
|
+
], template: "<form [formGroup]=\"form\" (ngSubmit)=\"save()\">\n <div class=\"d-flex flex-column justify-content-start align-items center gap-1\" mat-dialog-content>\n <h5 class=\"fw-bold text-center\">{{ isUpdate ? 'Edit' : 'Create ' }} User</h5>\n <div class=\"d-flex\">\n <div class=\"d-flex flex-column flex-fill gap-1\">\n <mat-form-field>\n <mat-label>Full name</mat-label>\n <input [required]=\"!!form.get('name').validator\" autocomplete=\"off\" formControlName=\"name\" matInput\n placeholder=\"Full Name\" type=\"text\" />\n <mat-error *ngIf=\"isFieldValid('name') && !!form.get('name').validator\">{{ getErrorMessage('name') }}\n </mat-error>\n </mat-form-field>\n <mat-form-field>\n <mat-label>Email</mat-label>\n <input [required]=\"!!form.get('email').validator\" formControlName=\"email\" matInput placeholder=\"Email\"\n type=\"email\" />\n <mat-error *ngIf=\"isFieldValid('email') && !!form.get('email').validator\">\n {{ getErrorMessage('email') }}\n </mat-error>\n </mat-form-field>\n <mat-form-field *ngIf=\"this.config.userConfig.showPhone\">\n <mat-label>Phone</mat-label>\n <input autocomplete=\"off\" formControlName=\"phone\" matInput placeholder=\"Phone\" type=\"text\" />\n </mat-form-field>\n <mat-form-field>\n <mat-label>Password</mat-label>\n <input [required]=\"isPasswordRequired && !!form.get('password').validator\" autocomplete=\"off\"\n formControlName=\"password\" matInput placeholder=\"Password\" type=\"password\" />\n <mat-error *ngIf=\"isFieldValid('password') && !!form.get('password').validator\">\n {{ getErrorMessage('password') }}\n </mat-error>\n </mat-form-field>\n\n <div class=\"d-flex flex-column justify-content-start gap-1\">\n <mat-checkbox formControlName=\"is_temporary_password\">Is Temporary Password?</mat-checkbox>\n <small class=\"text-secondary\">Should this user to update password on first login?</small>\n </div>\n\n <div *ngIf=\"this.config.userConfig.showSignature\">\n <ng-template #fileUpload>\n <section class=\"col-12\">\n <div>User Signature</div>\n <app-file-dropper (fileChanged)=\"fileChanged($event)\" [config]=\"fileConfig\" [fileArray]=\"fileList\">\n </app-file-dropper>\n </section>\n </ng-template>\n <div *ngIf=\"form.get('signature').value;else fileUpload;\" class=\"col-12\">\n <app-document-viewer (remove)=\"removeFile()\" [config]=\"this.viewerConfig\"\n [fileUrl]=\"form.get('signature_url').value\" [file]=\"form.get('signature').value\">\n </app-document-viewer>\n </div>\n </div>\n <mat-form-field *ngIf=\"this.config.userConfig.showUserTypes\" class=\"mt-3\">\n <mat-label>User Type</mat-label>\n <mat-select autocomplete=\"off\" formControlName=\"user_type_id\" required>\n <mat-option *ngFor=\"let userType of userTypes\" [value]=\"userType.value\">\n {{ userType.title }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"isFieldValid('user_type_id')\">{{ getErrorMessage('user_type_id') }}</mat-error>\n </mat-form-field>\n </div>\n\n <div\n *ngIf=\"(this.config.userConfig.showRoles || this.config.userConfig.showFormRoles) && this.form.get('user_type_id').value == 3\"\n class=\"flex-fill ml-4\">\n <p class=\"mb-0 fw-bold\">\n Roles\n </p>\n <div *ngFor=\"let role of roles\" class=\"d-flex flex-column\">\n <mat-checkbox (change)=\"roleSelected($event, role.id)\" [checked]=\"role.selected\">\n {{ role.label }}\n </mat-checkbox>\n </div>\n </div>\n\n </div>\n <div class=\"d-flex justify-content-end align-items-center gap-3\">\n <button [disabled]=\"isWorking\" color=\"primary\" mat-raised-button type=\"submit\">\n Save\n </button>\n <button (click)=\"closeDialog()\" [disabled]=\"isWorking\" mat-flat-button type=\"button\">\n Cancel\n </button>\n </div>\n </div>\n</form>" }]
|
|
200
|
+
}], ctorParameters: () => [{ type: i1.MatDialogRef }, { type: undefined, decorators: [{
|
|
201
|
+
type: Inject,
|
|
202
|
+
args: [MAT_DIALOG_DATA]
|
|
203
|
+
}] }, { type: i2.HttpService }, { type: i3.UntypedFormBuilder }, { type: i4.FormValidatorService }, { type: i5.UserService }, { type: i6.CurrentUserService }, { type: i7.UserConfigService }] });
|
|
204
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC10ZWNobGlmeS1jb3JlL3NyYy9saWIvdXNlci91c2VyLWZvcm0vdXNlci1mb3JtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC10ZWNobGlmeS1jb3JlL3NyYy9saWIvdXNlci91c2VyLWZvcm0vdXNlci1mb3JtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sRUFBc0IsVUFBVSxFQUFFLGtCQUFrQixFQUFvQixNQUFNLGdCQUFnQixDQUFDO0FBSXRHLE9BQU8sRUFBZ0IsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFLekUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFFM0UsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFFcEYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXpELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBY25ELE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxxQkFBcUI7SUE0QjFELFlBQ1MsU0FBMEMsRUFDakIsSUFBUyxFQUNqQyxJQUFpQixFQUNqQixFQUFzQixFQUNwQixvQkFBMEMsRUFDMUMsV0FBd0IsRUFDMUIsa0JBQXNDLEVBQ3ZDLGlCQUFvQztRQUUzQyxLQUFLLENBQUMsb0JBQW9CLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFUbEMsY0FBUyxHQUFULFNBQVMsQ0FBaUM7UUFDakIsU0FBSSxHQUFKLElB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O3dCQUNQLFlBQVk7d0JBQ1osaUJBQWlCO3dCQUNqQixvQkFBb0I7cUJBQ3JCOzswQkFnQ0UsTUFBTTsyQkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbmplY3QsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVW50eXBlZEZvcm1CdWlsZGVyLCBWYWxpZGF0b3JzLCBVbnR5cGVkRm9ybUNvbnRyb2wsIFVudHlwZWRGb3JtQXJyYXkgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IEh0dHBTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZSc7XG5cbmltcG9ydCB7IE1hdERpYWxvZ1JlZiwgTUFUX0RJQUxPR19EQVRBIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IFVzZXJTZXJ2aWNlIH0gZnJvbSAnLi4vdXNlci5zZXJ2aWNlJztcbmltcG9ydCB7IE11bHRpVXNlckNvbmZpZyB9IGZyb20gJy4uLy4uL3VzZXItY29uZmlnL3VzZXItY29uZmlnLm1vZGVsJztcbmltcG9ydCB7IFVzZXJDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vdXNlci1jb25maWcvdXNlci1jb25maWcuc2VydmljZSc7XG5pbXBvcnQgeyBGaWxlRHJvcHBlckNvbmZpZyB9IGZyb20gXCIuLi8uLi9maWxlLWRyb3BwZXJcIjtcbmltcG9ydCB7IEZpbGVEcm9wcGVyTW9kdWxlIH0gZnJvbSBcIi4uLy4uL2ZpbGUtZHJvcHBlci9maWxlLWRyb3BwZXIubW9kdWxlXCI7XG5pbXBvcnQgeyBWaWV3ZXJDb25maWcgfSBmcm9tIFwiLi4vLi4vZG9jdW1lbnQtdmlld2VyXCI7XG5pbXBvcnQgeyBEb2N1bWVudFZpZXdlck1vZHVsZSB9IGZyb20gXCIuLi8uLi9kb2N1bWVudC12aWV3ZXIvZG9jdW1lbnQtdmlld2VyLm1vZHVsZVwiO1xuaW1wb3J0IHsgQ3VycmVudFVzZXJTZXJ2aWNlIH0gZnJvbSAnLi4vY3VycmVudC11c2VyLnNlcnZpY2UnO1xuaW1wb3J0IHsgVXNlclR5cGVFbnVtIH0gZnJvbSAnLi4vdXNlci10eXBlLmVudW0nO1xuaW1wb3J0IHsgVGVjaGxpZnlGb3JtQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vYmFzZS1tb2RlbCc7XG5pbXBvcnQgeyBGb3JtVmFsaWRhdG9yU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvZm9ybS12YWxpZGF0b3Iuc2VydmljZSc7XG5pbXBvcnQgeyBTaGFyZWRNb2R1bGUgfSBmcm9tICcuLi8uLi9zaGFyZWQubW9kdWxlJztcblxuXG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC11c2VyLWZvcm0nLFxuICB0ZW1wbGF0ZVVybDogJy4vdXNlci1mb3JtLmNvbXBvbmVudC5odG1sJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIFNoYXJlZE1vZHVsZSxcbiAgICBGaWxlRHJvcHBlck1vZHVsZSxcbiAgICBEb2N1bWVudFZpZXdlck1vZHVsZVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIFVzZXJGb3JtQ29tcG9uZW50IGV4dGVuZHMgVGVjaGxpZnlGb3JtQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgaXNQYXNzd29yZFJlcXVpcmVkID0gZmFsc2U7XG4gIGNvbmZpZzogTXVsdGlVc2VyQ29uZmlnO1xuICB1c2VyVHlwZXM6IGFueSA9IFtcbiAgICB7IHRpdGxlOiAnQWRtaW4nLCB2YWx1ZTogMiB9LFxuICAgIHsgdGl0bGU6ICdOb3JtYWwgVXNlcicsIHZhbHVlOiAzIH0sXG4gIF07XG4gIHJvbGVzOiBhbnlbXSA9IFtdO1xuICBmaWxlQ29uZmlnOiBGaWxlRHJvcHBlckNvbmZpZztcbiAgdmlld2VyQ29uZmlnOiBWaWV3ZXJDb25maWc7XG4gIGZpbGVMaXN0OiBhbnlbXSA9IFtdO1xuXG4gIGVycm9yTWVzc2FnZXM6IGFueSA9IHtcbiAgICBuYW1lOiB7XG4gICAgICByZXF1aXJlZDogJ05hbWUgaXMgcmVxdWlyZWQnXG4gICAgfSxcbiAgICBlbWFpbDoge1xuICAgICAgcmVxdWlyZWQ6ICdFbWFpbCBpcyByZXF1aXJlZCcsXG4gICAgICBlbWFpbDogJ0ludmFsaWQgZW1haWwnLFxuICAgIH0sXG4gICAgcGFzc3dvcmQ6IHtcbiAgICAgIHJlcXVpcmVkOiAnUGFzc3dvcmQgaXMgcmVxdWlyZWQnXG4gICAgfSxcbiAgICB1c2VyX3R5cGVfaWQ6IHtcbiAgICAgIHJlcXVpcmVkOiAnVXNlciBUeXBlIGlzIHJlcXVpcmVkJ1xuICAgIH1cbiAgfTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8VXNlckZvcm1Db21wb25lbnQ+LFxuICAgIEBJbmplY3QoTUFUX0RJQUxPR19EQVRBKSBwdWJsaWMgZGF0YTogYW55LFxuICAgIHByaXZhdGUgaHR0cDogSHR0cFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBmYjogVW50eXBlZEZvcm1CdWlsZGVyLFxuICAgIHByb3RlY3RlZCBmb3JtVmFsaWRhdG9yU2VydmljZTogRm9ybVZhbGlkYXRvclNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHVzZXJTZXJ2aWNlOiBVc2VyU2VydmljZSxcbiAgICBwcml2YXRlIGN1cnJlbnRVc2VyU2VydmljZTogQ3VycmVudFVzZXJTZXJ2aWNlLFxuICAgIHB1YmxpYyB1c2VyQ29uZmlnU2VydmljZTogVXNlckNvbmZpZ1NlcnZpY2UsXG4gICkge1xuICAgIHN1cGVyKGZvcm1WYWxpZGF0b3JTZXJ2aWNlLCB1c2VyU2VydmljZSk7XG4gICAgdGhpcy5jb25maWcgPSB0aGlzLnVzZXJDb25maWdTZXJ2aWNlLmdldENvbmZpZygpO1xuICB9XG5cbiAgZ2V0IHJvbGVGb3JtcygpIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtLmdldCgncm9sZXMnKSBhcyBVbnR5cGVkRm9ybUFycmF5O1xuICB9XG5cbiAgZ2V0IGNhblVwZGF0ZVVzZXJDcmVkZW50aWFsKCkge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnRVc2VyU2VydmljZS5nZXRVc2VyKCkudXNlcl90eXBlX2lkID09IFVzZXJUeXBlRW51bS5BRE1JTlxuICAgICAgfHwgKHRoaXMuZGF0YT8ubW9kZWw/LnVzZXJfY2xpZW50cyB8fCBbXSk/Lmxlbmd0aCA8PSAxO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy51c2VyVHlwZXMgPSB0aGlzLmNvbmZpZy51c2VyQ29uZmlnLnNob3dVc2VyVHlwZXNcbiAgICAgID8gdGhpcy5jb25maWcudXNlckNvbmZpZy51c2VyVHlwZXNcbiAgICAgIDogdGhpcy51c2VyVHlwZXM7XG4gICAgdGhpcy5mb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBpZDogWycnXSxcbiAgICAgIG5hbWU6IG5ldyBVbnR5cGVkRm9ybUNvbnRyb2woJycsIFZhbGlkYXRvcnMuY29tcG9zZShbVmFsaWRhdG9ycy5yZXF1aXJlZF0pKSxcbiAgICAgIGVtYWlsOiBuZXcgVW50eXBlZEZvcm1Db250cm9sKCcnLCBWYWxpZGF0b3JzLmNvbXBvc2UoW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMuZW1haWxdKSksXG4gICAgICBwYXNzd29yZDogbmV3IFVudHlwZWRGb3JtQ29udHJvbCgnJyksXG4gICAgICBwaG9uZTogbmV3IFVudHlwZWRGb3JtQ29udHJvbCgnJyksXG4gICAgICB1c2VyX3R5cGVfaWQ6IG5ldyBVbnR5cGVkRm9ybUNvbnRyb2woJycsIFZhbGlkYXRvcnMucmVxdWlyZWQpLFxuICAgICAgcm9sZXM6IHRoaXMuZmIuYXJyYXkoW10pLFxuICAgICAgcm9sZXNfZXhpc3RzOiBbW11dLFxuICAgICAgY2xpZW50X2lkOiBbdGhpcy5kYXRhPy5jbGllbnRfaWQgPz8gJyddLFxuICAgICAgc2lnbmF0dXJlX3VybDogWycnXSxcbiAgICAgIHNpZ25hdHVyZTogWycnXSxcbiAgICAgIGlzX3RlbXBvcmFyeV9wYXNzd29yZDogW3RydWVdLFxuICAgIH0pO1xuXG4gICAgY29uc3QgdXNlciA9IHRoaXMuZGF0YT8ubW9kZWw7XG4gICAgaWYgKHVzZXIpIHtcbiAgICAgIHRoaXMuaXNVcGRhdGUgPSB0cnVlO1xuICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUodXNlcik7XG4gICAgICB0aGlzLmZvcm0uY29udHJvbHMudXNlcl90eXBlX2lkLnNldFZhbHVlKHVzZXIudXNlcl90eXBlX2lkKTtcbiAgICAgIHRoaXMuZm9ybS5jb250cm9scy5yb2xlc19leGlzdHMuc2V0VmFsdWUodXNlci5yb2xlcyB8fCBbXSk7XG4gICAgfVxuICAgIC8vIFRoZSBjYWxsaW5nIGNvbnRleHQncyBjbGllbnRfaWQgYWx3YXlzIHdpbnMsIGV2ZW4gaW4gZWRpdCBtb2RlIChlLmcuIGFuIGFwcC1hZG1pblxuICAgIC8vIG1hbmFnaW5nIGEgc3BlY2lmaWMgdGVuYW50J3MgdXNlcnMgc2hvdWxkIHNhdmUgYWdhaW5zdCB0aGF0IHRlbmFudCwgbm90IHRoZSB1c2VyJ3Mgb3duKS5cbiAgICBpZiAodGhpcy5kYXRhPy5jbGllbnRfaWQgIT0gbnVsbCkge1xuICAgICAgdGhpcy5mb3JtLmNvbnRyb2xzLmNsaWVudF9pZC5zZXRWYWx1ZSh0aGlzLmRhdGEuY2xpZW50X2lkKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY29uZmlnLnVzZXJDb25maWcuc2hvd1JvbGVzIHx8IHRoaXMuY29uZmlnLnVzZXJDb25maWcuc2hvd0Zvcm1Sb2xlcykge1xuICAgICAgdGhpcy5sb2FkUm9sZXMoKTtcbiAgICB9XG4gICAgdGhpcy5maWxlQ29uZmlnID0ge1xuICAgICAgZmlsZUlkOiAnc3ViamVjdEZpbGUnLFxuICAgICAgY29udGFpbmVySWQ6ICdzdWJqZWN0RmlsZUNvbnRhaW5lcicsXG4gICAgICBzdHlsZXM6IHtcbiAgICAgICAgaGVpZ2h0OiAnMjAwcHgnXG4gICAgICB9LFxuICAgICAgbXVsdGlwbGU6IGZhbHNlLFxuICAgICAgYWNjZXB0RmlsZTogJyonLFxuICAgICAgbWF4U2l6ZTogMTAsXG4gICAgICBhY2NlcHRGaWxlVGV4dDogJ1BORyBhbmQgSlBFRyBvbmx5J1xuICAgIH07XG5cbiAgICB0aGlzLnZpZXdlckNvbmZpZyA9IHtcbiAgICAgIGltYWdlU3R5bGU6IHtcbiAgICAgICAgaGVpZ2h0OiAnMjAwcHgnLFxuICAgICAgICB3aWR0aDogJzQwMHB4J1xuICAgICAgfSxcbiAgICAgIHZpZXdlclN0eWxlOiB7XG4gICAgICAgIGhlaWdodDogJzIwMHB4JyxcbiAgICAgICAgd2lkdGg6ICcxMDAlJ1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoIXRoaXMuY2FuVXBkYXRlVXNlckNyZWRlbnRpYWwpIHtcbiAgICAgIHRoaXMuZm9ybS5nZXQoJ2VtYWlsJykuZGlzYWJsZSgpO1xuICAgICAgdGhpcy5mb3JtLmdldCgncGFzc3dvcmQnKS5kaXNhYmxlKCk7XG4gICAgfVxuICB9XG5cbiAgbG9hZFJvbGVzKCkge1xuICAgIHRoaXMuaXNXb3JraW5nID0gdHJ1ZTtcbiAgICBjb25zdCBmaWx0ZXIgPSB7XG4gICAgICBjbGllbnRfaWQ6IHRoaXMuZGF0YT8uY2xpZW50X2lkIHx8IHRoaXMuZGF0YT8ubW9kZWw/LmNsaWVudF9pZCB8fCAnJyxcbiAgICAgIGlzX3N1YnNjcmliZWQ6IHRydWUsXG4gICAgICBzb3J0X2J5OiAnbGFiZWx8YXNjJ1xuICAgIH07XG4gICAgdGhpcy5odHRwLmdldCgnYXBpL3JvbGVzJywgeyBwYXJhbXM6IGZpbHRlciB9KS50b1Byb21pc2UoKS50aGVuKFxuICAgICAgKHJlczogYW55KSA9PiB7XG4gICAgICAgIGxldCByb2xlcyA9IHJlcy5kYXRhO1xuICAgICAgICAvKiBMZXRzIHNldCB0aGUgcm9sZXMgdGhpcyB1c2VyIGhhcyAqL1xuICAgICAgICBmb3IgKGxldCByb2xlIG9mIHJvbGVzKSB7XG4gICAgICAgICAgcm9sZS5zZWxlY3RlZCA9IHRoaXMuZm9ybS52YWx1ZS5yb2xlc19leGlzdHMuZmluZChyb2xlRGF0YSA9PiByb2xlRGF0YS5pZCA9PSByb2xlLmlkKSA/IHRydWUgOiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJvbGVzID0gcm9sZXM7XG4gICAgICAgIHRoaXMuaXNXb3JraW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHNhdmUoKSB7XG4gICAgY29uc3QgZGF0YTogYW55ID0gdGhpcy5mb3JtLmdldFJhd1ZhbHVlKCk7XG4gICAgbGV0IHJvbGVzID0gW107XG5cbiAgICB0aGlzLnJvbGVzLmZvckVhY2goKHJvbGU6IGFueSkgPT4ge1xuICAgICAgaWYgKHJvbGUuc2VsZWN0ZWQpIHtcbiAgICAgICAgcm9sZXNbcm9sZS5pZF0gPSByb2xlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGRhdGEucm9sZXMgPSByb2xlcztcblxuICAgIHN1cGVyLnN1Ym1pdChkYXRhKTtcbiAgfVxuXG4gIHJvbGVTZWxlY3RlZChldmVudDogYW55LCByb2xlSWQ6IG51bWJlcikge1xuICAgIHRoaXMucm9sZXMuZm9yRWFjaCgocm9sZTogYW55KSA9PiB7XG4gICAgICBpZiAocm9sZS5pZCA9PSByb2xlSWQpIHtcbiAgICAgICAgcm9sZS5zZWxlY3RlZCA9IGV2ZW50LmNoZWNrZWQ7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBmaWxlQ2hhbmdlZChldmVudDogYW55KSB7XG4gICAgdGhpcy5maWxlTGlzdCA9IGV2ZW50O1xuXG4gICAgaWYgKHRoaXMuZmlsZUxpc3QubGVuZ3RoID4gMCkge1xuXG4gICAgICBjb25zdCByZXN1bHQ6IGFueSA9IGF3YWl0IHRoaXMudXBsb2FkRW50aXR5RmlsZShcbiAgICAgICAgdGhpcy5maWxlTGlzdFswXVxuICAgICAgKTtcbiAgICAgIHRoaXMuZm9ybVxuICAgICAgICAuZ2V0KCdzaWduYXR1cmUnKVxuICAgICAgICAuc2V0VmFsdWUocmVzdWx0Lml0ZW0uZmlsZSk7XG4gICAgICB0aGlzLmZvcm1cbiAgICAgICAgLmdldCgnc2lnbmF0dXJlX3VybCcpXG4gICAgICAgIC5zZXRWYWx1ZShyZXN1bHQuaXRlbS51cmwpO1xuICAgICAgdGhpcy5maWxlTGlzdCA9IFtdO1xuICAgIH1cbiAgfVxuXG5cbiAgYXN5bmMgcmVtb3ZlRmlsZSgpIHtcbiAgICBpZiAodGhpcy5mb3JtLnZhbHVlLnNpZ25hdHVyZSkge1xuICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgICBzaWduYXR1cmU6ICcnLFxuICAgICAgICBzaWduYXR1cmVfdXJsOiAnJ1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHVwbG9hZEVudGl0eUZpbGUoZmlsZTogRmlsZSkge1xuICAgIGNvbnN0IGZvcm1EYXRhOiBGb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZURhdGEnLCBmaWxlLCBmaWxlLm5hbWUpO1xuICAgIHJldHVybiB0aGlzLmh0dHBcbiAgICAgIC5za2lwSGVhZGVyKClcbiAgICAgIC5wb3N0KFxuICAgICAgICAnYXBpL2VudGl0eS1maWxlcy11cGxvYWQnLFxuICAgICAgICBmb3JtRGF0YSxcbiAgICAgICkudG9Qcm9taXNlKCk7XG4gIH1cbn1cbiIsIjxmb3JtIFtmb3JtR3JvdXBdPVwiZm9ybVwiIChuZ1N1Ym1pdCk9XCJzYXZlKClcIj5cbiAgPGRpdiBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtbiBqdXN0aWZ5LWNvbnRlbnQtc3RhcnQgYWxpZ24taXRlbXMgY2VudGVyIGdhcC0xXCIgbWF0LWRpYWxvZy1jb250ZW50PlxuICAgIDxoNSBjbGFzcz1cImZ3LWJvbGQgdGV4dC1jZW50ZXJcIj57eyBpc1VwZGF0ZSA/ICdFZGl0JyA6ICdDcmVhdGUgJyB9fSBVc2VyPC9oNT5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uIGZsZXgtZmlsbCBnYXAtMVwiPlxuICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgPG1hdC1sYWJlbD5GdWxsIG5hbWU8L21hdC1sYWJlbD5cbiAgICAgICAgICA8aW5wdXQgW3JlcXVpcmVkXT1cIiEhZm9ybS5nZXQoJ25hbWUnKS52YWxpZGF0b3JcIiBhdXRvY29tcGxldGU9XCJvZmZcIiBmb3JtQ29udHJvbE5hbWU9XCJuYW1lXCIgbWF0SW5wdXRcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiRnVsbCBOYW1lXCIgdHlwZT1cInRleHRcIiAvPlxuICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJpc0ZpZWxkVmFsaWQoJ25hbWUnKSAmJiAhIWZvcm0uZ2V0KCduYW1lJykudmFsaWRhdG9yXCI+e3sgZ2V0RXJyb3JNZXNzYWdlKCduYW1lJykgfX1cbiAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDxtYXQtbGFiZWw+RW1haWw8L21hdC1sYWJlbD5cbiAgICAgICAgICA8aW5wdXQgW3JlcXVpcmVkXT1cIiEhZm9ybS5nZXQoJ2VtYWlsJykudmFsaWRhdG9yXCIgZm9ybUNvbnRyb2xOYW1lPVwiZW1haWxcIiBtYXRJbnB1dCBwbGFjZWhvbGRlcj1cIkVtYWlsXCJcbiAgICAgICAgICAgIHR5cGU9XCJlbWFpbFwiIC8+XG4gICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImlzRmllbGRWYWxpZCgnZW1haWwnKSAmJiAhIWZvcm0uZ2V0KCdlbWFpbCcpLnZhbGlkYXRvclwiPlxuICAgICAgICAgICAge3sgZ2V0RXJyb3JNZXNzYWdlKCdlbWFpbCcpIH19XG4gICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDxtYXQtZm9ybS1maWVsZCAqbmdJZj1cInRoaXMuY29uZmlnLnVzZXJDb25maWcuc2hvd1Bob25lXCI+XG4gICAgICAgICAgPG1hdC1sYWJlbD5QaG9uZTwvbWF0LWxhYmVsPlxuICAgICAgICAgIDxpbnB1dCBhdXRvY29tcGxldGU9XCJvZmZcIiBmb3JtQ29udHJvbE5hbWU9XCJwaG9uZVwiIG1hdElucHV0IHBsYWNlaG9sZGVyPVwiUGhvbmVcIiB0eXBlPVwidGV4dFwiIC8+XG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICA8bWF0LWxhYmVsPlBhc3N3b3JkPC9tYXQtbGFiZWw+XG4gICAgICAgICAgPGlucHV0IFtyZXF1aXJlZF09XCJpc1Bhc3N3b3JkUmVxdWlyZWQgJiYgISFmb3JtLmdldCgncGFzc3dvcmQnKS52YWxpZGF0b3JcIiBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwicGFzc3dvcmRcIiBtYXRJbnB1dCBwbGFjZWhvbGRlcj1cIlBhc3N3b3JkXCIgdHlwZT1cInBhc3N3b3JkXCIgLz5cbiAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiaXNGaWVsZFZhbGlkKCdwYXNzd29yZCcpICYmICEhZm9ybS5nZXQoJ3Bhc3N3b3JkJykudmFsaWRhdG9yXCI+XG4gICAgICAgICAgICB7eyBnZXRFcnJvck1lc3NhZ2UoJ3Bhc3N3b3JkJykgfX1cbiAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uIGp1c3RpZnktY29udGVudC1zdGFydCBnYXAtMVwiPlxuICAgICAgICAgIDxtYXQtY2hlY2tib3ggZm9ybUNvbnRyb2xOYW1lPVwiaXNfdGVtcG9yYXJ5X3Bhc3N3b3JkXCI+SXMgVGVtcG9yYXJ5IFBhc3N3b3JkPzwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCI+U2hvdWxkIHRoaXMgdXNlciB0byB1cGRhdGUgcGFzc3dvcmQgb24gZmlyc3QgbG9naW4/PC9zbWFsbD5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiAqbmdJZj1cInRoaXMuY29uZmlnLnVzZXJDb25maWcuc2hvd1NpZ25hdHVyZVwiPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZmlsZVVwbG9hZD5cbiAgICAgICAgICAgIDxzZWN0aW9uIGNsYXNzPVwiY29sLTEyXCI+XG4gICAgICAgICAgICAgIDxkaXY+VXNlciBTaWduYXR1cmU8L2Rpdj5cbiAgICAgICAgICAgICAgPGFwcC1maWxlLWRyb3BwZXIgKGZpbGVDaGFuZ2VkKT1cImZpbGVDaGFuZ2VkKCRldmVudClcIiBbY29uZmlnXT1cImZpbGVDb25maWdcIiBbZmlsZUFycmF5XT1cImZpbGVMaXN0XCI+XG4gICAgICAgICAgICAgIDwvYXBwLWZpbGUtZHJvcHBlcj5cbiAgICAgICAgICAgIDwvc2VjdGlvbj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJmb3JtLmdldCgnc2lnbmF0dXJlJykudmFsdWU7ZWxzZSBmaWxlVXBsb2FkO1wiIGNsYXNzPVwiY29sLTEyXCI+XG4gICAgICAgICAgICA8YXBwLWRvY3VtZW50LXZpZXdlciAocmVtb3ZlKT1cInJlbW92ZUZpbGUoKVwiIFtjb25maWddPVwidGhpcy52aWV3ZXJDb25maWdcIlxuICAgICAgICAgICAgICBbZmlsZVVybF09XCJmb3JtLmdldCgnc2lnbmF0dXJlX3VybCcpLnZhbHVlXCIgW2ZpbGVdPVwiZm9ybS5nZXQoJ3NpZ25hdHVyZScpLnZhbHVlXCI+XG4gICAgICAgICAgICA8L2FwcC1kb2N1bWVudC12aWV3ZXI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCJ0aGlzLmNvbmZpZy51c2VyQ29uZmlnLnNob3dVc2VyVHlwZXNcIiBjbGFzcz1cIm10LTNcIj5cbiAgICAgICAgICA8bWF0LWxhYmVsPlVzZXIgVHlwZTwvbWF0LWxhYmVsPlxuICAgICAgICAgIDxtYXQtc2VsZWN0IGF1dG9jb21wbGV0ZT1cIm9mZlwiIGZvcm1Db250cm9sTmFtZT1cInVzZXJfdHlwZV9pZFwiIHJlcXVpcmVkPlxuICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IHVzZXJUeXBlIG9mIHVzZXJUeXBlc1wiIFt2YWx1ZV09XCJ1c2VyVHlwZS52YWx1ZVwiPlxuICAgICAgICAgICAgICB7eyB1c2VyVHlwZS50aXRsZSB9fVxuICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiaXNGaWVsZFZhbGlkKCd1c2VyX3R5cGVfaWQnKVwiPnt7IGdldEVycm9yTWVzc2FnZSgndXNlcl90eXBlX2lkJykgfX08L21hdC1lcnJvcj5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2XG4gICAgICAgICpuZ0lmPVwiKHRoaXMuY29uZmlnLnVzZXJDb25maWcuc2hvd1JvbGVzIHx8IHRoaXMuY29uZmlnLnVzZXJDb25maWcuc2hvd0Zvcm1Sb2xlcykgJiYgdGhpcy5mb3JtLmdldCgndXNlcl90eXBlX2lkJykudmFsdWUgPT0gM1wiXG4gICAgICAgIGNsYXNzPVwiZmxleC1maWxsIG1sLTRcIj5cbiAgICAgICAgPHAgY2xhc3M9XCJtYi0wIGZ3LWJvbGRcIj5cbiAgICAgICAgICBSb2xlc1xuICAgICAgICA8L3A+XG4gICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHJvbGUgb2Ygcm9sZXNcIiBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtblwiPlxuICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNoYW5nZSk9XCJyb2xlU2VsZWN0ZWQoJGV2ZW50LCByb2xlLmlkKVwiIFtjaGVja2VkXT1cInJvbGUuc2VsZWN0ZWRcIj5cbiAgICAgICAgICAgIHt7IHJvbGUubGFiZWwgfX1cbiAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWVuZCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTNcIj5cbiAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cImlzV29ya2luZ1wiIGNvbG9yPVwicHJpbWFyeVwiIG1hdC1yYWlzZWQtYnV0dG9uIHR5cGU9XCJzdWJtaXRcIj5cbiAgICAgICAgU2F2ZVxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uIChjbGljayk9XCJjbG9zZURpYWxvZygpXCIgW2Rpc2FibGVkXT1cImlzV29ya2luZ1wiIG1hdC1mbGF0LWJ1dHRvbiB0eXBlPVwiYnV0dG9uXCI+XG4gICAgICAgIENhbmNlbFxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9mb3JtPiJdfQ==
|