auto-complete2.js
30.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { NgModule, Component, Input, Output, EventEmitter, forwardRef } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { SharedModule } from 'primeng/primeng';
import { Request } from '../_services/request.service';
import * as _ from 'lodash';
import { DxSelectBoxModule } from 'devextreme-angular';
import DataSource from 'devextreme/data/data_source';
import CustomStore from 'devextreme/data/custom_store';
import ArrayStore from 'devextreme/data/array_store';
export class SocAutoComplete2Component {
/**
* @param {?} request
*/
constructor(request) {
this.request = request;
this.filteredOptions = [];
/**
* local, remote
*/
this.mode = 'local';
/**
* API ที่ต้องการเรียกใช้เมื่อพิมพ์ auto complete
*/
this.api = '';
/**
* field ที่ต้องการ query เมื่อยิง API
*/
this.field = '';
this.fieldApi = '';
this.id = '';
this.placeholder = '';
this.disabled = false;
this.orderBy = '';
this.filter = '';
this.ex_type_view = '';
this.limit = 1000;
this.onLoad = new EventEmitter();
this.valueChange = new EventEmitter();
this.valueSelete = new EventEmitter();
this.storeOnLoaded = new EventEmitter();
this.acceptCustomValue = true;
this.resData = [];
this.loadOptionData = [];
this.openOnFieldClick = false;
this.showDropDownButton = false;
// acceptCustomValue = true;
this.searchEnabled = true;
this.inputValue = '';
this.fnCustomStoreOnLoaded = (result) => {
this.storeOnLoaded.emit(result);
return result;
};
/**
* START Bind Value
*/
this.onModelChange = () => { };
this.onModelTouched = () => { };
}
/**
* @return {?}
*/
ngOnInit() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (this.mode === 'dropdown') {
this.acceptCustomValue = false;
this.searchEnabled = false;
}
/** ถ้าเป็น โหมด local จะแสดง list ให้เลือกเลย แตถ้่เป็น remote จะต้องขึ้นเมื่อพิมพ์เท่านั้น */
if (this.mode === 'local' || this.mode === 'dropdown') {
this.openOnFieldClick = true;
this.showDropDownButton = true;
this.fnStartDataSourceLocal();
}
else {
this.fnStartDataSourceRemote();
}
});
}
/**
* @return {?}
*/
ngAfterViewInit() {
}
/**
* @return {?}
*/
fnStartDataSourceLocal() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
/** @type {?} */
let params = `?_fields=${this.fieldApi ? this.fieldApi : this.field}`;
if (this.filter) {
params += this.filter; //`&_where=(${this.filter})`
}
if (this.orderBy && this.orderBy !== '') {
params += `&_sort=${this.orderBy}`;
}
params += `&_limit=${this.limit}`;
/** @type {?} */
let resData = yield this.fnPreResponse(params);
this.ds = new DataSource({
store: new ArrayStore({
data: resData,
onLoaded: this.fnCustomStoreOnLoaded
})
});
});
}
/**
* @return {?}
*/
fnStartDataSourceRemote() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
this.ds = new DataSource({
store: new CustomStore({
byKey: (key) => tslib_1.__awaiter(this, void 0, void 0, function* () {
this.onLoad.emit(key);
return this.fnGetCustomStore(key);
}),
load: (loadOptions) => tslib_1.__awaiter(this, void 0, void 0, function* () {
this.onLoad.emit(loadOptions.searchValue);
return this.fnGetCustomStore(loadOptions.searchValue);
;
}),
onLoaded: this.fnCustomStoreOnLoaded
})
});
});
}
/**
* @param {?} key
* @return {?}
*/
fnGetCustomStore(key) {
/** @type {?} */
let params = `?_fields=${this.fieldApi ? this.fieldApi : this.field}&_where=(${this.field},like,$${key}$)`;
if (this.filter) {
params = `?_fields=${this.fieldApi ? this.fieldApi : this.field}&_where=((${this.field},like,$${key}$)$and(${this.filter}))`;
}
if (this.orderBy && this.orderBy !== '') {
params += `&_sort=${this.orderBy}`;
}
params += `&_limit=${this.limit}`;
return this.fnPreResponse(params);
;
}
/**
* @param {?} e
* @return {?}
*/
onValueChanged(e) {
this.onValueSelete(e);
console.log("SocAutoCompleteComponent -> onValueChanged -> e", e);
this.valueChange.emit(e.value);
}
/**
* @param {?} e
* @return {?}
*/
onValueSelete(e) {
/** @type {?} */
let temp = _.find(this.loadOptionData, r => {
if (this.ex_type_view === "ct_dropdown") {
return `${r.code} - ${r.name}` === e.value;
}
else if (this.ex_type_view === "ct_ext_departmen") {
return `${r.short_name} - ${r.name}` === e.value;
}
return r[this.field] === e.value;
});
console.log("SocAutoCompleteComponent -> onValueSelete -> e", e, temp);
this.valueSelete.emit(temp);
}
/**
* @param {?} params
* @return {?}
*/
fnPreResponse(params) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
/** @type {?} */
let resData = yield this.request.get(this.api + params);
resData = _.map(resData, (obj) => {
return obj; //[this.field]
});
/** @type {?} */
let _resData = [];
for (let i in resData) {
/** @type {?} */
let temp = _.find(_resData, r => r[this.field] === resData[i][this.field]);
if (!temp) {
_resData.push(resData[i]);
}
}
this.loadOptionData = _resData;
return _.map(_resData, (obj) => {
if (this.ex_type_view === "ct_dropdown") {
return `${obj.code} - ${obj.name}`;
}
else if (this.ex_type_view === "ct_ext_departmen") {
return `${obj.short_name} - ${obj.name}`;
}
return obj[this.field];
});
});
}
/**
* @param {?} e
* @return {?}
*/
onOpened(e) {
/** @type {?} */
const element = document.querySelector('.dx-overlay-wrapper.dx-dropdowneditor-overlay.dx-popup-wrapper.dx-dropdownlist-popup-wrapper.dx-selectbox-popup-wrapper');
element.setAttribute('style', 'z-index:9999;');
}
/**
* @param {?} value
* @return {?}
*/
writeValue(value) { }
/**
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) { }
/**
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) { }
}
SocAutoComplete2Component.decorators = [
{ type: Component, args: [{
selector: 'soc-auto-complete-2',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SocAutoComplete2Component),
multi: true
}],
template: `
<dx-select-box [dataSource]="ds"
[searchEnabled]="searchEnabled"
[openOnFieldClick]="openOnFieldClick"
[showClearButton]="true"
[showDropDownButton]="showDropDownButton"
[inputAttr]="{ id: id }"
[acceptCustomValue]="acceptCustomValue"
[placeholder]="placeholder"
[(value)]="value"
(onValueChanged)="onValueChanged($event)"
(onOpened)="onOpened($event)"
[disabled]="disabled"
noDataText="ไม่พบข้อมูล"
placeholder="กรุณาเลือกรายการ"
></dx-select-box>
`
}] }
];
/** @nocollapse */
SocAutoComplete2Component.ctorParameters = () => [
{ type: Request }
];
SocAutoComplete2Component.propDecorators = {
mode: [{ type: Input }],
api: [{ type: Input }],
field: [{ type: Input }],
fieldApi: [{ type: Input }],
id: [{ type: Input }],
placeholder: [{ type: Input }],
value: [{ type: Input }],
disabled: [{ type: Input }],
orderBy: [{ type: Input }],
filter: [{ type: Input }],
ex_type_view: [{ type: Input }],
limit: [{ type: Input }],
onLoad: [{ type: Output }],
valueChange: [{ type: Output }],
valueSelete: [{ type: Output }],
storeOnLoaded: [{ type: Output }],
acceptCustomValue: [{ type: Input }]
};
if (false) {
/** @type {?} */
SocAutoComplete2Component.prototype.filteredOptions;
/**
* local, remote
* @type {?}
*/
SocAutoComplete2Component.prototype.mode;
/**
* API ที่ต้องการเรียกใช้เมื่อพิมพ์ auto complete
* @type {?}
*/
SocAutoComplete2Component.prototype.api;
/**
* field ที่ต้องการ query เมื่อยิง API
* @type {?}
*/
SocAutoComplete2Component.prototype.field;
/** @type {?} */
SocAutoComplete2Component.prototype.fieldApi;
/** @type {?} */
SocAutoComplete2Component.prototype.id;
/** @type {?} */
SocAutoComplete2Component.prototype.placeholder;
/** @type {?} */
SocAutoComplete2Component.prototype.value;
/** @type {?} */
SocAutoComplete2Component.prototype.disabled;
/** @type {?} */
SocAutoComplete2Component.prototype.orderBy;
/** @type {?} */
SocAutoComplete2Component.prototype.filter;
/** @type {?} */
SocAutoComplete2Component.prototype.ex_type_view;
/** @type {?} */
SocAutoComplete2Component.prototype.limit;
/** @type {?} */
SocAutoComplete2Component.prototype.onLoad;
/** @type {?} */
SocAutoComplete2Component.prototype.valueChange;
/** @type {?} */
SocAutoComplete2Component.prototype.valueSelete;
/** @type {?} */
SocAutoComplete2Component.prototype.storeOnLoaded;
/** @type {?} */
SocAutoComplete2Component.prototype.acceptCustomValue;
/** @type {?} */
SocAutoComplete2Component.prototype.resData;
/** @type {?} */
SocAutoComplete2Component.prototype.loadOptionData;
/** @type {?} */
SocAutoComplete2Component.prototype.openOnFieldClick;
/** @type {?} */
SocAutoComplete2Component.prototype.showDropDownButton;
/** @type {?} */
SocAutoComplete2Component.prototype.searchEnabled;
/** @type {?} */
SocAutoComplete2Component.prototype.inputValue;
/**
* ds
* @type {?}
*/
SocAutoComplete2Component.prototype.ds;
/** @type {?} */
SocAutoComplete2Component.prototype.fnCustomStoreOnLoaded;
/**
* START Bind Value
* @type {?}
*/
SocAutoComplete2Component.prototype.onModelChange;
/** @type {?} */
SocAutoComplete2Component.prototype.onModelTouched;
/** @type {?} */
SocAutoComplete2Component.prototype.request;
}
export class SharedAutoComplete2Module {
}
SharedAutoComplete2Module.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule, FormsModule, SharedModule, DxSelectBoxModule],
exports: [SocAutoComplete2Component, SharedModule],
declarations: [SocAutoComplete2Component],
},] }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0by1jb21wbGV0ZTIuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9zb2MtYXBwLWxpYnJhcnkvIiwic291cmNlcyI6WyJsaWIvX3RlbXBsYXRlL2F1dG8tY29tcGxldGUyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNILFFBQVEsRUFBRSxTQUFTLEVBQVUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUN2RSxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUF3QixNQUFNLGdCQUFnQixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3ZELE9BQU8sVUFBVSxNQUFNLDZCQUE2QixDQUFDO0FBQ3JELE9BQU8sV0FBVyxNQUFNLDhCQUE4QixDQUFDO0FBQ3ZELE9BQU8sVUFBVSxNQUFNLDZCQUE2QixDQUFDO0FBMkJyRCxNQUFNOzs7O0lBa0NGLFlBQW9CLE9BQWdCO1FBQWhCLFlBQU8sR0FBUCxPQUFPLENBQVM7K0JBakNsQixFQUFFOzs7O29CQUU2QixPQUFPOzs7O21CQUV6QyxFQUFFOzs7O3FCQUVBLEVBQUU7d0JBQ0MsRUFBRTtrQkFFUixFQUFFOzJCQUNPLEVBQUU7d0JBRUwsS0FBSzt1QkFDTixFQUFFO3NCQUNILEVBQUU7NEJBQ0ksRUFBRTtxQkFFVCxJQUFJO3NCQUNpQixJQUFJLFlBQVksRUFBTzsyQkFDZixJQUFJLFlBQVksRUFBVTsyQkFDMUIsSUFBSSxZQUFZLEVBQVU7NkJBQ3hCLElBQUksWUFBWSxFQUFVO2lD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QkFDTCxLQUFLO3FCQUNMLEtBQUs7MkJBQ0wsS0FBSztvQkFFTCxLQUFLO3FCQUNMLE1BQU07MEJBQ04sTUFBTTswQkFDTixNQUFNOzRCQUNOLE1BQU07Z0NBRU4sS0FBSzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE4SVYsTUFBTTs7O1lBTEwsUUFBUSxTQUFDO2dCQUNOLE9BQU8sRUFBRSxDQUFDLFlBQVksRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixDQUFDO2dCQUNyRSxPQUFPLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRSxZQUFZLENBQUM7Z0JBQ2xELFlBQVksRUFBRSxDQUFDLHlCQUF5QixDQUFDO2FBQzVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBOZ01vZHVsZSwgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgZm9yd2FyZFJlZiwgQWZ0ZXJWaWV3SW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlLCBOR19WQUxVRV9BQ0NFU1NPUiwgQ29udHJvbFZhbHVlQWNjZXNzb3IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgU2hhcmVkTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9wcmltZW5nJztcbmltcG9ydCB7IFJlcXVlc3QgfSBmcm9tICcuLi9fc2VydmljZXMvcmVxdWVzdC5zZXJ2aWNlJztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IER4U2VsZWN0Qm94TW9kdWxlIH0gZnJvbSAnZGV2ZXh0cmVtZS1hbmd1bGFyJztcbmltcG9ydCBEYXRhU291cmNlIGZyb20gJ2RldmV4dHJlbWUvZGF0YS9kYXRhX3NvdXJjZSc7XG5pbXBvcnQgQ3VzdG9tU3RvcmUgZnJvbSAnZGV2ZXh0cmVtZS9kYXRhL2N1c3RvbV9zdG9yZSc7XG5pbXBvcnQgQXJyYXlTdG9yZSBmcm9tICdkZXZleHRyZW1lL2RhdGEvYXJyYXlfc3RvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ3NvYy1hdXRvLWNvbXBsZXRlLTInLFxuICAgIHByb3ZpZGVyczogW3tcbiAgICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFNvY0F1dG9Db21wbGV0ZTJDb21wb25lbnQpLFxuICAgICAgICBtdWx0aTogdHJ1ZVxuICAgIH1dLFxuICAgIHRlbXBsYXRlOiBgXG4gICAgICA8ZHgtc2VsZWN0LWJveCBbZGF0YVNvdXJjZV09XCJkc1wiXG4gICAgICAgICAgICAgICAgW3NlYXJjaEVuYWJsZWRdPVwic2VhcmNoRW5hYmxlZFwiXG4gICAgICAgICAgICAgICAgW29wZW5PbkZpZWxkQ2xpY2tdPVwib3Blbk9uRmllbGRDbGlja1wiXG4gICAgICAgICAgICAgICAgW3Nob3dDbGVhckJ1dHRvbl09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICBbc2hvd0Ryb3BEb3duQnV0dG9uXT1cInNob3dEcm9wRG93bkJ1dHRvblwiXG4gICAgICAgICAgICAgICAgW2lucHV0QXR0cl09XCJ7IGlkOiBpZCB9XCJcbiAgICAgICAgICAgICAgICBbYWNjZXB0Q3VzdG9tVmFsdWVdPVwiYWNjZXB0Q3VzdG9tVmFsdWVcIlxuICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgICAgWyh2YWx1ZSldPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgIChvblZhbHVlQ2hhbmdlZCk9XCJvblZhbHVlQ2hhbmdlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAob25PcGVuZWQpPVwib25PcGVuZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICBub0RhdGFUZXh0PVwi4LmE4Lih4LmI4Lie4Lia4LiC4LmJ4Lit4Lih4Li54LilXCJcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIuC4geC4o+C4uOC4k+C4suC5gOC4peC4t+C4reC4geC4o+C4suC4ouC4geC4suC4o1wiXG4gICAgICAgICAgICA+PC9keC1zZWxlY3QtYm94PlxuYFxufSlcbmV4cG9ydCBjbGFzcyBTb2NBdXRvQ29tcGxldGUyQ29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCB7XG4gICAgZmlsdGVyZWRPcHRpb25zID0gW107XG4gICAgLyoqIGxvY2FsLCByZW1vdGUgKi9cbiAgICBASW5wdXQoKSBtb2RlOiAnbG9jYWwnIHwgJ3JlbW90ZScgfCAnZHJvcGRvd24nID0gJ2xvY2FsJztcbiAgICAvKiogQVBJIOC4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4o+C5gOC4o+C4teC4ouC4geC5g+C4iuC5ieC5gOC4oeC4t+C5iOC4reC4nuC4tOC4oeC4nuC5jCBhdXRvIGNvbXBsZXRlICovXG4gICAgQElucHV0KCkgYXBpID0gJyc7XG4gICAgLyoqIGZpZWxkIOC4l+C4teC5iOC4leC5ieC4reC4h+C4geC4suC4oyBxdWVyeSDguYDguKHguLfguYjguK3guKLguLTguIcgQVBJICovXG4gICAgQElucHV0KCkgZmllbGQgPSAnJztcbiAgICBASW5wdXQoKSBmaWVsZEFwaSA9ICcnO1xuXG4gICAgQElucHV0KCkgaWQgPSAnJztcbiAgICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICcnO1xuICAgIEBJbnB1dCgpIHZhbHVlOiBTdHJpbmc7XG4gICAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgICBASW5wdXQoKSBvcmRlckJ5ID0gJyc7XG4gICAgQElucHV0KCkgZmlsdGVyID0gJyc7XG4gICAgQElucHV0KCkgZXhfdHlwZV92aWV3ID0gJyc7XG5cbiAgICBASW5wdXQoKSBsaW1pdCA9IDEwMDA7XG4gICAgQE91dHB1dCgpIG9uTG9hZDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gICAgQE91dHB1dCgpIHZhbHVlU2VsZXRlOiBFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAgIEBPdXRwdXQoKSBzdG9yZU9uTG9hZGVkOiBFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gICAgQElucHV0KCkgYWNjZXB0Q3VzdG9tVmFsdWUgPSB0cnVlO1xuICAgIHJlc0RhdGEgPSBbXTtcbiAgICBsb2FkT3B0aW9uRGF0YSA9IFtdO1xuICAgIG9wZW5PbkZpZWxkQ2xpY2sgPSBmYWxzZTtcbiAgICBzaG93RHJvcERvd25CdXR0b24gPSBmYWxzZTtcbiAgICAvLyBhY2NlcHRDdXN0b21WYWx1ZSA9IHRydWU7XG4gICAgc2VhcmNoRW5hYmxlZCA9IHRydWU7XG4gICAgaW5wdXRWYWx1ZSA9ICcnO1xuICAgIC8qKiBkcyAqL1xuICAgIGRzOiBEYXRhU291cmNlO1xuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVxdWVzdDogUmVxdWVzdCkgeyB9XG4gICAgYXN5bmMgbmdPbkluaXQoKSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGUgPT09ICdkcm9wZG93bicpIHtcbiAgICAgICAgICAgIHRoaXMuYWNjZXB0Q3VzdG9tVmFsdWUgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2VhcmNoRW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8qKiDguJbguYnguLLguYDguJvguYfguJkg4LmC4Lir4Lih4LiUIGxvY2FsIOC4iOC4sOC5geC4quC4lOC4hyBsaXN0IOC5g+C4q+C5ieC5gOC4peC4t+C4reC4geC5gOC4peC4oiDguYHguJXguJbguYnguYjguYDguJvguYfguJkgcmVtb3RlIOC4iOC4sOC4leC5ieC4reC4h+C4guC4tuC5ieC4meC5gOC4oeC4t+C5iOC4reC4nuC4tOC4oeC4nuC5jOC5gOC4l+C5iOC4suC4meC4seC5ieC4mSAqL1xuICAgICAgICBpZiAodGhpcy5tb2RlID09PSAnbG9jYWwnIHx8IHRoaXMubW9kZSA9PT0gJ2Ryb3Bkb3duJykge1xuICAgICAgICAgICAgdGhpcy5vcGVuT25GaWVsZENsaWNrID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc2hvd0Ryb3BEb3duQnV0dG9uID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuZm5TdGFydERhdGFTb3VyY2VMb2NhbCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5mblN0YXJ0RGF0YVNvdXJjZVJlbW90ZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB9XG5cbiAgICBhc3luYyBmblN0YXJ0RGF0YVNvdXJjZUxvY2FsKCkge1xuICAgICAgICBsZXQgcGFyYW1zID0gYD9fZmllbGRzPSR7dGhpcy5maWVsZEFwaT90aGlzLmZpZWxkQXBpOnRoaXMuZmllbGR9YFxuICAgICAgICBpZih0aGlzLmZpbHRlcikge1xuICAgICAgICAgICAgcGFyYW1zICs9IHRoaXMuZmlsdGVyLy9gJl93aGVyZT0oJHt0aGlzLmZpbHRlcn0pYFxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm9yZGVyQnkgJiYgdGhpcy5vcmRlckJ5ICE9PSAnJykge1xuICAgICAgICAgICAgcGFyYW1zICs9IGAmX3NvcnQ9JHt0aGlzLm9yZGVyQnl9YDtcbiAgICAgICAgfVxuICAgICAgICBwYXJhbXMgKz0gYCZfbGltaXQ9JHt0aGlzLmxpbWl0fWA7XG4gICAgICAgIGxldCByZXNEYXRhID0gYXdhaXQgdGhpcy5mblByZVJlc3BvbnNlKHBhcmFtcyk7XG4gICAgICAgIHRoaXMuZHMgPSBuZXcgRGF0YVNvdXJjZSh7XG4gICAgICAgICAgICBzdG9yZTogbmV3IEFycmF5U3RvcmUoe1xuICAgICAgICAgICAgICAgIGRhdGE6IHJlc0RhdGEsXG4gICAgICAgICAgICAgICAgb25Mb2FkZWQ6IHRoaXMuZm5DdXN0b21TdG9yZU9uTG9hZGVkXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgYXN5bmMgZm5TdGFydERhdGFTb3VyY2VSZW1vdGUoKSB7XG4gICAgICAgIHRoaXMuZHMgPSBuZXcgRGF0YVNvdXJjZSh7XG4gICAgICAgICAgICBzdG9yZTogbmV3IEN1c3RvbVN0b3JlKHtcbiAgICAgICAgICAgICAgICBieUtleTogYXN5bmMgKGtleSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTG9hZC5lbWl0KGtleSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZuR2V0Q3VzdG9tU3RvcmUoa2V5KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxvYWQ6IGFzeW5jIChsb2FkT3B0aW9uczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25Mb2FkLmVtaXQobG9hZE9wdGlvbnMuc2VhcmNoVmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbkdldEN1c3RvbVN0b3JlKGxvYWRPcHRpb25zLnNlYXJjaFZhbHVlKTs7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBvbkxvYWRlZDogdGhpcy5mbkN1c3RvbVN0b3JlT25Mb2FkZWRcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBmbkdldEN1c3RvbVN0b3JlKGtleTogYW55KSB7XG4gICAgICAgIGxldCBwYXJhbXMgPSBgP19maWVsZHM9JHt0aGlzLmZpZWxkQXBpP3RoaXMuZmllbGRBcGk6dGhpcy5maWVsZH0mX3doZXJlPSgke3RoaXMuZmllbGR9LGxpa2UsJCR7a2V5fSQpYDtcbiAgICAgICAgaWYgKHRoaXMuZmlsdGVyKSB7XG4gICAgICAgICAgICBwYXJhbXMgPSBgP19maWVsZHM9JHt0aGlzLmZpZWxkQXBpP3RoaXMuZmllbGRBcGk6dGhpcy5maWVsZH0mX3doZXJlPSgoJHt0aGlzLmZpZWxkfSxsaWtlLCQke2tleX0kKSRhbmQoJHt0aGlzLmZpbHRlcn0pKWA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub3JkZXJCeSAmJiB0aGlzLm9yZGVyQnkgIT09ICcnKSB7XG4gICAgICAgICAgICBwYXJhbXMgKz0gYCZfc29ydD0ke3RoaXMub3JkZXJCeX1gO1xuICAgICAgICB9XG4gICAgICAgIHBhcmFtcyArPSBgJl9saW1pdD0ke3RoaXMubGltaXR9YDtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm5QcmVSZXNwb25zZShwYXJhbXMpOztcbiAgICB9XG4gICAgZm5DdXN0b21TdG9yZU9uTG9hZGVkID0gKHJlc3VsdCkgPT4ge1xuICAgICAgICB0aGlzLnN0b3JlT25Mb2FkZWQuZW1pdChyZXN1bHQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBvblZhbHVlQ2hhbmdlZChlOiBhbnkpIHtcbiAgICAgICAgdGhpcy5vblZhbHVlU2VsZXRlKGUpXG4gICAgICAgIGNvbnNvbGUubG9nKFwi4oCLU29jQXV0b0NvbXBsZXRlQ29tcG9uZW50IC0+IG9uVmFsdWVDaGFuZ2VkIC0+IGVcIiwgZSlcbiAgICAgICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KGUudmFsdWUpO1xuXG4gICAgfVxuICAgIG9uVmFsdWVTZWxldGUoZTogYW55KSB7XG4gICAgICAgIGxldCB0ZW1wID0gXy5maW5kKHRoaXMubG9hZE9wdGlvbkRhdGEgLHI9PntcbiAgICAgICAgICBpZih0aGlzLmV4X3R5cGVfdmlldz09PVwiY3RfZHJvcGRvd25cIil7XG4gICAgICAgICAgICByZXR1cm4gYCR7ci5jb2RlfSAtICR7ci5uYW1lfWAgPT09ICBlLnZhbHVlXG4gICAgICAgICAgfWVsc2UgaWYodGhpcy5leF90eXBlX3ZpZXc9PT1cImN0X2V4dF9kZXBhcnRtZW5cIil7XG4gICAgICAgICAgICByZXR1cm4gYCR7ci5zaG9ydF9uYW1lfSAtICR7ci5uYW1lfWAgPT09ICBlLnZhbHVlXG4gICAgICAgICAgfVxuXG5cblxuICAgICAgICAgIHJldHVybiByW3RoaXMuZmllbGRdICA9PT0gZS52YWx1ZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5sb2coXCLigItTb2NBdXRvQ29tcGxldGVDb21wb25lbnQgLT4gb25WYWx1ZVNlbGV0ZSAtPiBlXCIsIGUsdGVtcClcbiAgICAgICAgdGhpcy52YWx1ZVNlbGV0ZS5lbWl0KHRlbXApO1xuXG4gICAgfVxuXG4gICAgYXN5bmMgZm5QcmVSZXNwb25zZShwYXJhbXMpIHtcbiAgICAgICAgbGV0IHJlc0RhdGEgPSBhd2FpdCB0aGlzLnJlcXVlc3QuZ2V0KHRoaXMuYXBpICsgcGFyYW1zKTtcbiAgICAgICAgcmVzRGF0YSA9IF8ubWFwKHJlc0RhdGEsIChvYmo6IGFueSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG9iaiAvL1t0aGlzLmZpZWxkXVxuICAgICAgICB9KTtcbiAgICAgICAgbGV0IF9yZXNEYXRhID0gW107XG4gICAgICAgIGZvcihsZXQgaSBpbiByZXNEYXRhKXtcbiAgICAgICAgICBsZXQgdGVtcCA9IF8uZmluZChfcmVzRGF0YSAsIHI9PnJbdGhpcy5maWVsZF0gPT09IHJlc0RhdGFbaV1bdGhpcy5maWVsZF0pO1xuICAgICAgICAgIGlmKCF0ZW1wKXtcbiAgICAgICAgICAgIF9yZXNEYXRhLnB1c2gocmVzRGF0YVtpXSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sb2FkT3B0aW9uRGF0YSA9IF9yZXNEYXRhO1xuICAgICAgICByZXR1cm4gXy5tYXAoX3Jlc0RhdGEsIChvYmo6IGFueSkgPT4ge1xuICAgICAgICAgIGlmKHRoaXMuZXhfdHlwZV92aWV3PT09XCJjdF9kcm9wZG93blwiKXtcbiAgICAgICAgICAgIHJldHVybiBgJHtvYmouY29kZX0gLSAke29iai5uYW1lfWBcbiAgICAgICAgICB9ZWxzZSBpZih0aGlzLmV4X3R5cGVfdmlldz09PVwiY3RfZXh0X2RlcGFydG1lblwiKXtcbiAgICAgICAgICAgIHJldHVybiBgJHtvYmouc2hvcnRfbmFtZX0gLSAke29iai5uYW1lfWBcbiAgICAgICAgICB9XG5cblxuXG4gICAgICAgICAgICByZXR1cm4gb2JqW3RoaXMuZmllbGRdXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBvbk9wZW5lZChlKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZHgtb3ZlcmxheS13cmFwcGVyLmR4LWRyb3Bkb3duZWRpdG9yLW92ZXJsYXkuZHgtcG9wdXAtd3JhcHBlci5keC1kcm9wZG93bmxpc3QtcG9wdXAtd3JhcHBlci5keC1zZWxlY3Rib3gtcG9wdXAtd3JhcHBlcicpO1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnei1pbmRleDo5OTk5OycpO1xuICAgIH1cbiAgICAvKiogU1RBUlQgQmluZCBWYWx1ZSAqL1xuICAgIG9uTW9kZWxDaGFuZ2U6IEZ1bmN0aW9uID0gKCkgPT4geyB9O1xuICAgIG9uTW9kZWxUb3VjaGVkOiBGdW5jdGlvbiA9ICgpID0+IHsgfTtcbiAgICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHsgfVxuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IEZ1bmN0aW9uKTogdm9pZCB7IH1cbiAgICByZWdpc3Rlck9uVG91Y2hlZChmbjogRnVuY3Rpb24pOiB2b2lkIHsgfVxuICAgIC8qKiBFTkQgQmluZCBWYWx1ZSAqL1xuXG59XG5cbkBOZ01vZHVsZSh7XG4gICAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGUsIFNoYXJlZE1vZHVsZSwgRHhTZWxlY3RCb3hNb2R1bGVdLFxuICAgIGV4cG9ydHM6IFtTb2NBdXRvQ29tcGxldGUyQ29tcG9uZW50LCBTaGFyZWRNb2R1bGVdLFxuICAgIGRlY2xhcmF0aW9uczogW1NvY0F1dG9Db21wbGV0ZTJDb21wb25lbnRdLFxufSlcbmV4cG9ydCBjbGFzcyBTaGFyZWRBdXRvQ29tcGxldGUyTW9kdWxlIHsgfVxuIl19