@libs-ui/interfaces-types 0.2.356-8 → 0.2.357-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/README.md
CHANGED
|
@@ -1,3 +1,618 @@
|
|
|
1
|
-
# interfaces-types
|
|
1
|
+
# @libs-ui/interfaces-types
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Bộ sưu tập tập trung các Interface và Type TypeScript dùng chung toàn hệ thống libs-ui.
|
|
4
|
+
|
|
5
|
+
## Giới thiệu
|
|
6
|
+
|
|
7
|
+
`@libs-ui/interfaces-types` là thư viện thuần TypeScript cung cấp các interface và type được tái sử dụng xuyên suốt hệ sinh thái `@libs-ui`. Lib bao gồm các định nghĩa cho HTTP response/upload, phân trang, file, sự kiện trình duyệt, ngày tháng (dayjs), cũng như các utility type nâng cao phục vụ Angular Signals như `ExtractInputs`, `PathOf`, `GetValueAtPath`, và `SignalOf`.
|
|
8
|
+
|
|
9
|
+
## Tính năng
|
|
10
|
+
|
|
11
|
+
- ✅ Định nghĩa chuẩn cho HTTP Response và phân trang (`IHttpResponse`, `IPaging`)
|
|
12
|
+
- ✅ Utility type trích xuất Input Signal từ Angular component (`ExtractInputs`)
|
|
13
|
+
- ✅ Type-safe path navigation cho object/signal lồng nhau (`PathOf`, `GetValueAtPath`)
|
|
14
|
+
- ✅ Chuyển đổi kiểu dữ liệu sang dạng Signal và ngược lại (`SignalOf`, `NonSignalOf`)
|
|
15
|
+
- ✅ Định nghĩa cho sự kiện trình duyệt mở rộng (`IEvent`, `IEventTarget`)
|
|
16
|
+
- ✅ Interface quản lý file upload và tiến trình (`IFile`, `IHttpProcessUpload`)
|
|
17
|
+
- ✅ Type ngày tháng với dayjs tích hợp (`GetDayjsConfig`, `GetDayjsReturn`)
|
|
18
|
+
- ✅ Interface validator và định dạng chuỗi (`IIsValidRequired`, `ITextFormatOptions`)
|
|
19
|
+
- ✅ Type tỉ lệ khung hình và toạ độ DOM (`TYPE_ASPECT_RATIO`, `IBoundingClientRect`)
|
|
20
|
+
|
|
21
|
+
## Khi nào sử dụng
|
|
22
|
+
|
|
23
|
+
- Khi cần định nghĩa kiểu cho response API trả về từ backend
|
|
24
|
+
- Khi truyền data vào Modal V2 qua `of<ExtractInputs<...>>()` để đảm bảo type-safe
|
|
25
|
+
- Khi xây dựng hàm generic truy cập giá trị theo đường dẫn chuỗi trên object/signal lồng nhau
|
|
26
|
+
- Khi cần chuyển đổi một interface sang dạng Signal-wrapped để dùng với Angular Signals
|
|
27
|
+
- Khi xây dựng form validator và cần type chuẩn cho message lỗi
|
|
28
|
+
- Khi xử lý file upload và cần theo dõi tiến trình phần trăm
|
|
29
|
+
|
|
30
|
+
## Cài đặt
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @libs-ui/interfaces-types
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Import
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// HTTP & Paging
|
|
40
|
+
import { IHttpResponse, IHttpResponseError, IPaging } from '@libs-ui/interfaces-types';
|
|
41
|
+
|
|
42
|
+
// File & Upload
|
|
43
|
+
import { IFile, TYPE_FILE, IHttpProcessUpload } from '@libs-ui/interfaces-types';
|
|
44
|
+
|
|
45
|
+
// Angular Signal Utilities
|
|
46
|
+
import { ExtractInputs } from '@libs-ui/interfaces-types';
|
|
47
|
+
import { PathOf, GetValueAtPath, GetReturnType, SignalOf, NonSignalOf } from '@libs-ui/interfaces-types';
|
|
48
|
+
|
|
49
|
+
// Event browser
|
|
50
|
+
import { IEvent, IEventTarget, IEventCustom } from '@libs-ui/interfaces-types';
|
|
51
|
+
|
|
52
|
+
// Date (dayjs)
|
|
53
|
+
import { GetDayjsConfig, GetDayjsReturn, NonNullableDate } from '@libs-ui/interfaces-types';
|
|
54
|
+
|
|
55
|
+
// DOM
|
|
56
|
+
import { IBoundingClientRect } from '@libs-ui/interfaces-types';
|
|
57
|
+
import { TYPE_ASPECT_RATIO, IAspectRatio } from '@libs-ui/interfaces-types';
|
|
58
|
+
|
|
59
|
+
// Validator
|
|
60
|
+
import { IIsValidRequired, IIsValidPattern, IIsValidLength, IMessageTranslate } from '@libs-ui/interfaces-types';
|
|
61
|
+
|
|
62
|
+
// String
|
|
63
|
+
import { IString, IStringCustom, ITextFormatOptions } from '@libs-ui/interfaces-types';
|
|
64
|
+
|
|
65
|
+
// Others
|
|
66
|
+
import { TYPE_OBJECT } from '@libs-ui/interfaces-types';
|
|
67
|
+
import { TYPE_LANGUAGE_SUPPORT } from '@libs-ui/interfaces-types';
|
|
68
|
+
import { TYPE_FUNCTION } from '@libs-ui/interfaces-types';
|
|
69
|
+
import { TYPE_IFRAME_MESSAGE } from '@libs-ui/interfaces-types';
|
|
70
|
+
import { TYPE_TEMPLATE_REF } from '@libs-ui/interfaces-types';
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Ví dụ sử dụng
|
|
74
|
+
|
|
75
|
+
### 1. IHttpResponse — Định nghĩa kiểu trả về từ API
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { IHttpResponse, IPaging } from '@libs-ui/interfaces-types';
|
|
79
|
+
import { HttpClient } from '@angular/common/http';
|
|
80
|
+
import { inject } from '@angular/core';
|
|
81
|
+
import { Observable } from 'rxjs';
|
|
82
|
+
|
|
83
|
+
interface IUser {
|
|
84
|
+
id: string;
|
|
85
|
+
name: string;
|
|
86
|
+
email: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Service gọi API danh sách user có phân trang
|
|
90
|
+
export class UserApiService {
|
|
91
|
+
private readonly http = inject(HttpClient);
|
|
92
|
+
|
|
93
|
+
getList(params: { page: number; per_page: number }): Observable<IHttpResponse<IUser[]>> {
|
|
94
|
+
return this.http.get<IHttpResponse<IUser[]>>('/api/users', { params });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Component nhận response
|
|
99
|
+
// component.ts
|
|
100
|
+
protected handlerLoadData(): void {
|
|
101
|
+
this.userApiService.getList({ page: 1, per_page: 20 })
|
|
102
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
103
|
+
.subscribe((res: IHttpResponse<IUser[]>) => {
|
|
104
|
+
if (res.code !== 200) return;
|
|
105
|
+
this.users.set(res.data ?? []);
|
|
106
|
+
this.paging.set(res.paging ?? {});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 2. ExtractInputs — Truyền data type-safe vào Modal V2
|
|
112
|
+
|
|
113
|
+
`ExtractInputs<T>` trích xuất tất cả `InputSignal` từ một component thành một plain object type, dùng khi gọi `of<ExtractInputs<...>>()` để truyền data vào `getDataComponentOutlet`.
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { ExtractInputs } from '@libs-ui/interfaces-types';
|
|
117
|
+
import { InputSignal, input } from '@angular/core';
|
|
118
|
+
import { of } from 'rxjs';
|
|
119
|
+
import { from } from 'rxjs';
|
|
120
|
+
import { LibsUiComponentsModalV2Component } from '@libs-ui/components-modal-v2';
|
|
121
|
+
|
|
122
|
+
// Định nghĩa interface khớp với component con
|
|
123
|
+
interface I_DataInComponentUserDetail {
|
|
124
|
+
userId: InputSignal<string>; // required
|
|
125
|
+
mode: InputSignal<'view' | 'edit'>; // required
|
|
126
|
+
title?: InputSignal<string>; // optional
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Component con implements interface
|
|
130
|
+
export class UserDetailModalComponent implements I_DataInComponentUserDetail {
|
|
131
|
+
readonly userId = input.required<string>();
|
|
132
|
+
readonly mode = input.required<'view' | 'edit'>();
|
|
133
|
+
readonly title = input<string>();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Component cha truyền data qua getDataComponentOutlet
|
|
137
|
+
this.libsUiDynamicComponentService.setInputs(this.modalComponentRef, {
|
|
138
|
+
bodyConfig: {
|
|
139
|
+
component: () => from(
|
|
140
|
+
import('./user-detail-modal/user-detail-modal.component')
|
|
141
|
+
.then(m => m.UserDetailModalComponent)
|
|
142
|
+
),
|
|
143
|
+
getDataComponentOutlet: () => of<ExtractInputs<I_DataInComponentUserDetail>>({
|
|
144
|
+
userId: 'user-123', // required — bắt buộc truyền
|
|
145
|
+
mode: 'view', // required — bắt buộc truyền
|
|
146
|
+
// title: 'Chi tiết', // optional — có thể bỏ qua
|
|
147
|
+
}),
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 3. PathOf & GetValueAtPath — Truy cập an toàn theo đường dẫn chuỗi
|
|
153
|
+
|
|
154
|
+
`PathOf<T>` sinh ra union type của tất cả đường dẫn hợp lệ trong object `T`. `GetValueAtPath<T, P>` trả về type của giá trị tại đường dẫn `P`.
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { PathOf, GetValueAtPath } from '@libs-ui/interfaces-types';
|
|
158
|
+
import { WritableSignal, signal } from '@angular/core';
|
|
159
|
+
|
|
160
|
+
interface IOrder {
|
|
161
|
+
id: string;
|
|
162
|
+
customer: {
|
|
163
|
+
name: string;
|
|
164
|
+
address: {
|
|
165
|
+
city: string;
|
|
166
|
+
zip: string;
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
items: Array<{
|
|
170
|
+
productId: string;
|
|
171
|
+
quantity: number;
|
|
172
|
+
}>;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// PathOf<IOrder> tự động sinh ra:
|
|
176
|
+
// 'id' | 'customer' | 'customer.name' | 'customer.address' |
|
|
177
|
+
// 'customer.address.city' | 'customer.address.zip' |
|
|
178
|
+
// 'items' | 'items[0]' | 'items[0].productId' | 'items[0].quantity' | ...
|
|
179
|
+
type OrderPaths = PathOf<IOrder>;
|
|
180
|
+
|
|
181
|
+
// GetValueAtPath trả về type chính xác tại path
|
|
182
|
+
type CityType = GetValueAtPath<IOrder, 'customer.address.city'>; // string
|
|
183
|
+
type ItemQty = GetValueAtPath<IOrder, 'items[0].quantity'>; // number
|
|
184
|
+
|
|
185
|
+
// Dùng trong hàm generic type-safe
|
|
186
|
+
function getField<T, P extends PathOf<T>>(
|
|
187
|
+
obj: T,
|
|
188
|
+
path: P
|
|
189
|
+
): GetValueAtPath<T, P> {
|
|
190
|
+
// implementation dùng get() từ @libs-ui/utils
|
|
191
|
+
return (obj as any)[path as string];
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### 4. SignalOf — Chuyển đổi interface sang Signal-wrapped
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { SignalOf, NonSignalOf } from '@libs-ui/interfaces-types';
|
|
199
|
+
import { signal, WritableSignal } from '@angular/core';
|
|
200
|
+
import { convertObjectToSignal, convertSignalToObject } from '@libs-ui/utils';
|
|
201
|
+
|
|
202
|
+
interface IUserProfile {
|
|
203
|
+
name: string;
|
|
204
|
+
age: number;
|
|
205
|
+
address: {
|
|
206
|
+
city: string;
|
|
207
|
+
country: string;
|
|
208
|
+
};
|
|
209
|
+
tags: string[];
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// SignalOf<IUserProfile> sẽ sinh ra:
|
|
213
|
+
// {
|
|
214
|
+
// name: WritableSignal<string>;
|
|
215
|
+
// age: WritableSignal<number>;
|
|
216
|
+
// address: WritableSignal<{ city: WritableSignal<string>; country: WritableSignal<string>; }>;
|
|
217
|
+
// tags: WritableSignal<WritableSignal<string>[]>;
|
|
218
|
+
// }
|
|
219
|
+
type SignaledProfile = SignalOf<IUserProfile>;
|
|
220
|
+
|
|
221
|
+
// Sử dụng với convertObjectToSignal từ @libs-ui/utils
|
|
222
|
+
const profileSignal = convertObjectToSignal<IUserProfile>({
|
|
223
|
+
name: 'Nguyễn Văn A',
|
|
224
|
+
age: 30,
|
|
225
|
+
address: { city: 'Hà Nội', country: 'Việt Nam' },
|
|
226
|
+
tags: ['admin', 'dev'],
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Chuyển ngược lại về plain object để gửi API
|
|
230
|
+
const payload = convertSignalToObject(profileSignal);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 5. IFile & IHttpProcessUpload — Quản lý file upload
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { IFile, TYPE_FILE, IHttpProcessUpload } from '@libs-ui/interfaces-types';
|
|
237
|
+
import { signal } from '@angular/core';
|
|
238
|
+
|
|
239
|
+
// component.ts
|
|
240
|
+
protected uploadingFiles = signal<IFile[]>([]);
|
|
241
|
+
protected uploadProgress = signal<IHttpProcessUpload>({ loaded: 0, total: 0, percent: 0 });
|
|
242
|
+
|
|
243
|
+
protected handlerFileSelect(event: Event): void {
|
|
244
|
+
event.stopPropagation();
|
|
245
|
+
const input = event.target as HTMLInputElement;
|
|
246
|
+
if (!input.files?.length) return;
|
|
247
|
+
|
|
248
|
+
const newFiles: IFile[] = Array.from(input.files).map(file => ({
|
|
249
|
+
name: file.name,
|
|
250
|
+
file: file,
|
|
251
|
+
size: `${(file.size / 1024).toFixed(1)} KB`,
|
|
252
|
+
type: this.detectFileType(file.type),
|
|
253
|
+
isUploading: true,
|
|
254
|
+
percentUploading: 0,
|
|
255
|
+
}));
|
|
256
|
+
|
|
257
|
+
this.uploadingFiles.set(newFiles);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
private detectFileType(mimeType: string): TYPE_FILE {
|
|
261
|
+
if (mimeType.startsWith('image/')) return 'image';
|
|
262
|
+
if (mimeType.startsWith('video/')) return 'video';
|
|
263
|
+
if (mimeType.startsWith('audio/')) return 'audio';
|
|
264
|
+
return 'document';
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### 6. IEvent & IEventTarget — Xử lý sự kiện DOM mở rộng
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
import { IEvent } from '@libs-ui/interfaces-types';
|
|
272
|
+
|
|
273
|
+
// component.ts
|
|
274
|
+
protected handlerInputChange(event: IEvent): void {
|
|
275
|
+
event.stopPropagation();
|
|
276
|
+
const value = event.target.value as string;
|
|
277
|
+
this.searchTerm.set(value.trim());
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
protected handlerFileDrop(event: IEvent): void {
|
|
281
|
+
event.stopPropagation();
|
|
282
|
+
const files = event.dataTransfer?.files;
|
|
283
|
+
if (!files?.length) return;
|
|
284
|
+
this.processFiles(files);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
protected handlerKeyDown(event: IEvent): void {
|
|
288
|
+
event.stopPropagation();
|
|
289
|
+
if (event.keyCode === 13) {
|
|
290
|
+
this.handlerSubmit();
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (event.keyCode === 27) {
|
|
294
|
+
this.handlerClose();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### 7. GetDayjsConfig & GetDayjsReturn — Type cho hàm getDayjs
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
import { GetDayjsConfig, GetDayjsReturn, NonNullableDate } from '@libs-ui/interfaces-types';
|
|
303
|
+
import { getDayjs } from '@libs-ui/utils';
|
|
304
|
+
|
|
305
|
+
// Định nghĩa hàm format ngày với type rõ ràng
|
|
306
|
+
function formatDateSafe(config: GetDayjsConfig): string {
|
|
307
|
+
const result = getDayjs(config);
|
|
308
|
+
if (!result) return '';
|
|
309
|
+
return result.format('DD/MM/YYYY HH:mm');
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Ví dụ sử dụng
|
|
313
|
+
const formatted1 = formatDateSafe({ date: '2024-06-15', formatOfDate: 'YYYY-MM-DD' });
|
|
314
|
+
// => '15/06/2024 00:00'
|
|
315
|
+
|
|
316
|
+
const formatted2 = formatDateSafe({
|
|
317
|
+
date: 1718409600000,
|
|
318
|
+
utc: false,
|
|
319
|
+
returnDayjsIfConfigDateNotExist: true,
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### 8. IPaging — Phân trang
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
import { IPaging, IHttpResponse } from '@libs-ui/interfaces-types';
|
|
327
|
+
import { signal, computed } from '@angular/core';
|
|
328
|
+
|
|
329
|
+
// component.ts
|
|
330
|
+
protected paging = signal<IPaging>({});
|
|
331
|
+
|
|
332
|
+
protected totalPages = computed(() => this.paging().total_pages ?? 0);
|
|
333
|
+
protected currentPage = computed(() => this.paging().page ?? 1);
|
|
334
|
+
protected hasNextPage = computed(() => !!this.paging().next);
|
|
335
|
+
|
|
336
|
+
protected handlerPageChange(page: number): void {
|
|
337
|
+
this.loadData({ page, per_page: 20 });
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
private loadData(params: { page: number; per_page: number }): void {
|
|
341
|
+
this.apiService.getList(params)
|
|
342
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
343
|
+
.subscribe((res: IHttpResponse<unknown[], IPaging>) => {
|
|
344
|
+
if (res.code !== 200) return;
|
|
345
|
+
this.paging.set(res.paging ?? {});
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### 9. Validator interfaces — Cấu hình rule validate
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import {
|
|
354
|
+
IIsValidRequired,
|
|
355
|
+
IIsValidPattern,
|
|
356
|
+
IIsValidLength,
|
|
357
|
+
IMessageTranslate,
|
|
358
|
+
} from '@libs-ui/interfaces-types';
|
|
359
|
+
|
|
360
|
+
// Cấu hình validator cho input email
|
|
361
|
+
const emailValidators = {
|
|
362
|
+
required: {
|
|
363
|
+
isRequired: true,
|
|
364
|
+
message: 'i18n_email_required',
|
|
365
|
+
} satisfies IIsValidRequired,
|
|
366
|
+
|
|
367
|
+
pattern: {
|
|
368
|
+
pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
|
369
|
+
message: 'i18n_email_invalid',
|
|
370
|
+
valuePatternShowError: true,
|
|
371
|
+
} satisfies IIsValidPattern,
|
|
372
|
+
|
|
373
|
+
maxLength: {
|
|
374
|
+
length: 100,
|
|
375
|
+
message: 'i18n_email_too_long',
|
|
376
|
+
interpolateParams: { max: 100 },
|
|
377
|
+
} satisfies IIsValidLength,
|
|
378
|
+
};
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### 10. TYPE_LANGUAGE_SUPPORT — Kiểu ngôn ngữ được hỗ trợ
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
import { TYPE_LANGUAGE_SUPPORT } from '@libs-ui/interfaces-types';
|
|
385
|
+
import { signal } from '@angular/core';
|
|
386
|
+
|
|
387
|
+
// component.ts
|
|
388
|
+
protected currentLang = signal<TYPE_LANGUAGE_SUPPORT>('vi');
|
|
389
|
+
|
|
390
|
+
protected handlerSwitchLang(lang: TYPE_LANGUAGE_SUPPORT): void {
|
|
391
|
+
this.currentLang.set(lang);
|
|
392
|
+
this.translateService.use(lang);
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### 11. IAspectRatio & TYPE_ASPECT_RATIO — Tỉ lệ khung hình
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
import { IAspectRatio, TYPE_ASPECT_RATIO } from '@libs-ui/interfaces-types';
|
|
400
|
+
import { signal } from '@angular/core';
|
|
401
|
+
|
|
402
|
+
const aspectRatioOptions: IAspectRatio[] = [
|
|
403
|
+
{ key: 'Tự do', value: 0 },
|
|
404
|
+
{ key: '1:1', value: 1 },
|
|
405
|
+
{ key: '16:9', value: 16 / 9 },
|
|
406
|
+
{ key: '4:3', value: 4 / 3 },
|
|
407
|
+
];
|
|
408
|
+
|
|
409
|
+
// component.ts
|
|
410
|
+
protected selectedRatio = signal<TYPE_ASPECT_RATIO>('16:9');
|
|
411
|
+
|
|
412
|
+
protected handlerSelectRatio(ratio: TYPE_ASPECT_RATIO): void {
|
|
413
|
+
this.selectedRatio.set(ratio);
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### 12. IBoundingClientRect — Toạ độ và kích thước DOM
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
import { IBoundingClientRect } from '@libs-ui/interfaces-types';
|
|
421
|
+
import { ElementRef, inject } from '@angular/core';
|
|
422
|
+
import { signal } from '@angular/core';
|
|
423
|
+
|
|
424
|
+
// component.ts (dùng trong directive hoặc component tính toán vị trí)
|
|
425
|
+
private readonly elementRef = inject(ElementRef);
|
|
426
|
+
|
|
427
|
+
protected boundingRect = signal<IBoundingClientRect>({
|
|
428
|
+
top: 0, left: 0, width: 0, height: 0,
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
ngAfterViewInit(): void {
|
|
432
|
+
const rect = this.elementRef.nativeElement.getBoundingClientRect();
|
|
433
|
+
this.boundingRect.set({
|
|
434
|
+
top: rect.top,
|
|
435
|
+
left: rect.left,
|
|
436
|
+
width: rect.width,
|
|
437
|
+
height: rect.height,
|
|
438
|
+
right: rect.right,
|
|
439
|
+
bottom: rect.bottom,
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### 13. TYPE_IFRAME_MESSAGE — Giao tiếp giữa các micro-frontend
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
import { TYPE_IFRAME_MESSAGE } from '@libs-ui/interfaces-types';
|
|
448
|
+
|
|
449
|
+
type MessageType = 'AUTH_TOKEN' | 'PAGE_READY' | 'CLOSE_MODAL';
|
|
450
|
+
type MessagePayload = { token: string } | { route: string } | null;
|
|
451
|
+
|
|
452
|
+
type AppMessage = TYPE_IFRAME_MESSAGE<MessageType, MessagePayload>;
|
|
453
|
+
|
|
454
|
+
// Gửi message
|
|
455
|
+
const msg: AppMessage = { type: 'AUTH_TOKEN', response: { token: 'demo-token' } };
|
|
456
|
+
window.parent.postMessage(msg, '*');
|
|
457
|
+
|
|
458
|
+
// Nhận message
|
|
459
|
+
window.addEventListener('message', (event) => {
|
|
460
|
+
const data = event.data as AppMessage;
|
|
461
|
+
if (data.type === 'AUTH_TOKEN') {
|
|
462
|
+
// xử lý token
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Types & Interfaces
|
|
468
|
+
|
|
469
|
+
### HTTP
|
|
470
|
+
|
|
471
|
+
| Export | Loại | Mô tả |
|
|
472
|
+
|---|---|---|
|
|
473
|
+
| `IHttpResponse<T, P>` | type | Kiểu chuẩn cho HTTP response từ backend. `T` = data type, `P` = paging type |
|
|
474
|
+
| `IHttpResponseError` | interface | Lỗi HTTP mở rộng từ `Error`, có thêm `code` |
|
|
475
|
+
| `IPaging` | interface | Phân trang hỗ trợ cả cursor-based và offset-based |
|
|
476
|
+
| `IHttpProcessUpload` | interface | Tiến trình upload: `loaded`, `total`, `percent` |
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
// IHttpResponse chi tiết
|
|
480
|
+
type IHttpResponse<T = any, P = IPaging> = {
|
|
481
|
+
code?: number; // HTTP status code
|
|
482
|
+
feCloneCode?: any; // Code override khi server trả 200 nhưng logic khác
|
|
483
|
+
message?: string; // Thông báo từ server
|
|
484
|
+
data?: T; // Dữ liệu chính
|
|
485
|
+
paging?: P; // Thông tin phân trang
|
|
486
|
+
[key: string]: unknown; // Các field mở rộng
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
// IPaging chi tiết
|
|
490
|
+
interface IPaging {
|
|
491
|
+
page?: number; // Trang hiện tại (offset-based)
|
|
492
|
+
per_page?: number; // Số item mỗi trang
|
|
493
|
+
total_items?: number; // Tổng số item
|
|
494
|
+
total_pages?: number; // Tổng số trang
|
|
495
|
+
before?: string; // Cursor trước (cursor-based)
|
|
496
|
+
after?: string; // Cursor sau (cursor-based)
|
|
497
|
+
previous?: string; // URL trang trước
|
|
498
|
+
next?: string; // URL trang sau
|
|
499
|
+
fake?: boolean; // Dữ liệu giả (dùng trong loading state)
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### File
|
|
504
|
+
|
|
505
|
+
| Export | Loại | Mô tả |
|
|
506
|
+
|---|---|---|
|
|
507
|
+
| `IFile` | interface | Đối tượng file đầy đủ: id, name, url, type, upload progress |
|
|
508
|
+
| `TYPE_FILE` | type | `'document' \| 'image' \| 'video' \| 'audio'` |
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
interface IFile {
|
|
512
|
+
id?: string;
|
|
513
|
+
name?: string;
|
|
514
|
+
file?: File; // File object gốc từ input[type=file]
|
|
515
|
+
size?: string; // Chuỗi kích thước (vd: '2.5 MB')
|
|
516
|
+
isUploading?: boolean;
|
|
517
|
+
percentUploading?: number; // 0-100
|
|
518
|
+
isUpdate?: boolean; // Đang cập nhật file cũ
|
|
519
|
+
url?: string; // URL sau khi upload xong
|
|
520
|
+
origin_url?: string; // URL gốc
|
|
521
|
+
mimetype?: string; // MIME type (vd: 'image/png')
|
|
522
|
+
type?: TYPE_FILE;
|
|
523
|
+
error?: string;
|
|
524
|
+
isAvatar?: boolean;
|
|
525
|
+
}
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Angular Signal Utilities
|
|
529
|
+
|
|
530
|
+
| Export | Loại | Mô tả |
|
|
531
|
+
|---|---|---|
|
|
532
|
+
| `ExtractInputs<T, R>` | type | Trích xuất `InputSignal` / `ModelSignal` từ component thành plain object type. `R=true` (mặc định) giữ nguyên required/optional |
|
|
533
|
+
| `PathOf<T, Depth>` | type | Sinh union type tất cả đường dẫn hợp lệ trong object `T`, hỗ trợ signal lồng nhau, depth mặc định 6 |
|
|
534
|
+
| `GetValueAtPath<T, P, R>` | type | Resolve type giá trị tại path `P`. `R=false` (mặc định) unwrap signal, `R=true` giữ nguyên signal |
|
|
535
|
+
| `GetReturnType<O, P, KS, D>` | type | Kiểu trả về của `get()` dựa trên `defaultValue D` — loại `null \| undefined` nếu `D` có giá trị |
|
|
536
|
+
| `SignalOf<T, P, F>` | type | Chuyển toàn bộ object sang dạng Signal-wrapped. `P=true` (mặc định) wrap cả primitive |
|
|
537
|
+
| `NonSignalOf<T>` | type | Unwrap toàn bộ Signal về plain type |
|
|
538
|
+
|
|
539
|
+
```typescript
|
|
540
|
+
// Ví dụ ExtractInputs
|
|
541
|
+
interface I_DataInComponentBadge {
|
|
542
|
+
label: InputSignal<string>; // required
|
|
543
|
+
variant: InputSignal<'primary' | 'secondary'>; // required
|
|
544
|
+
count?: InputSignal<number>; // optional (có ? vì InputSignal<number | undefined>)
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
type BadgeData = ExtractInputs<I_DataInComponentBadge>;
|
|
548
|
+
// => { label: string; variant: 'primary' | 'secondary'; count?: number }
|
|
549
|
+
|
|
550
|
+
// R=false: optional field có thể bỏ qua
|
|
551
|
+
type BadgeDataPartial = ExtractInputs<I_DataInComponentBadge, false>;
|
|
552
|
+
// => { label?: string; variant?: string; count?: number }
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### Event Browser
|
|
556
|
+
|
|
557
|
+
| Export | Loại | Mô tả |
|
|
558
|
+
|---|---|---|
|
|
559
|
+
| `IEvent` | interface | Kết hợp `Event`, `MouseEvent`, `KeyboardEvent`, `ErrorEvent` và custom |
|
|
560
|
+
| `IEventTarget` | interface | `EventTarget` mở rộng với `value`, `files`, `style`, `innerHTML`,... |
|
|
561
|
+
| `IEventCustom` | interface | Event tuỳ chỉnh với `data`, `fakeEvent`, `inputType` |
|
|
562
|
+
|
|
563
|
+
### Date
|
|
564
|
+
|
|
565
|
+
| Export | Loại | Mô tả |
|
|
566
|
+
|---|---|---|
|
|
567
|
+
| `GetDayjsConfig` | type | Config truyền vào `getDayjs()`: `date`, `utc`, `formatOfDate`, `returnDayjsIfConfigDateNotExist`, `localeZone` |
|
|
568
|
+
| `GetDayjsReturn<C>` | type | Kiểu trả về điều kiện của `getDayjs()`: `dayjs.Dayjs` hoặc `undefined` tùy config |
|
|
569
|
+
| `NonNullableDate` | type | `dayjs.ConfigType` loại bỏ `null \| undefined` |
|
|
570
|
+
|
|
571
|
+
### DOM & Layout
|
|
572
|
+
|
|
573
|
+
| Export | Loại | Mô tả |
|
|
574
|
+
|---|---|---|
|
|
575
|
+
| `IBoundingClientRect` | interface | `top`, `left`, `width`, `height`, `right?`, `bottom?` |
|
|
576
|
+
| `IAspectRatio` | interface | `key: string`, `value: number` |
|
|
577
|
+
| `TYPE_ASPECT_RATIO` | type | `'free' \| '1:1' \| '2:3' \| '3:2' \| '3:4' \| '4:3' \| '9:16' \| '16:9'` |
|
|
578
|
+
|
|
579
|
+
### Validator
|
|
580
|
+
|
|
581
|
+
| Export | Loại | Mô tả |
|
|
582
|
+
|---|---|---|
|
|
583
|
+
| `IIsValidRequired` | interface | Validator required: `isRequired`, `message`, `interpolateParams` |
|
|
584
|
+
| `IIsValidPattern` | interface | Validator regex: `pattern`, `valuePatternShowError`, `message` |
|
|
585
|
+
| `IIsValidLength` | interface | Validator độ dài: `length`, `message`, `interpolateParams` |
|
|
586
|
+
| `IMessageTranslate` | interface | Base interface cho message lỗi: `message?`, `interpolateParams?` |
|
|
587
|
+
|
|
588
|
+
### String
|
|
589
|
+
|
|
590
|
+
| Export | Loại | Mô tả |
|
|
591
|
+
|---|---|---|
|
|
592
|
+
| `IString` | type | `String & string & IStringCustom` — chuỗi mở rộng |
|
|
593
|
+
| `IStringCustom` | interface | Thêm `replaceAt`, `replaceAll`, `occurrencesByCharacter`, `indexesOfCharacter`, `indexesByString` |
|
|
594
|
+
| `ITextFormatOptions` | interface | Options format text: `uppercaseOtherCharacter`, `lowercaseOtherCharacter`, `trim`, `removeMultipleSpace`, `removeEmoji`, `removeUnicode` |
|
|
595
|
+
|
|
596
|
+
### Khác
|
|
597
|
+
|
|
598
|
+
| Export | Loại | Mô tả |
|
|
599
|
+
|---|---|---|
|
|
600
|
+
| `TYPE_OBJECT` | type | `Record<any, any>` — object không định kiểu. Chỉ dùng khi có lý do, phải kèm comment `// CONVENTION-EXCEPT: TYPE_OBJECT — [lý do]` |
|
|
601
|
+
| `TYPE_LANGUAGE_SUPPORT` | type | `'vi' \| 'en'` — ngôn ngữ được hỗ trợ hiện tại |
|
|
602
|
+
| `TYPE_FUNCTION<T>` | type | `(data: { value: any; item?: any; otherData?: any }) => Observable<T>` |
|
|
603
|
+
| `TYPE_IFRAME_MESSAGE<T, U>` | type | `{ type: T; response: U }` — message giao tiếp giữa micro-frontend qua iframe |
|
|
604
|
+
| `TYPE_TEMPLATE_REF` | type | `any` — placeholder type cho `TemplateRef` chưa xác định |
|
|
605
|
+
|
|
606
|
+
## Lưu ý quan trọng
|
|
607
|
+
|
|
608
|
+
⚠️ **ExtractInputs yêu cầu Generic Type tường minh**: Khi truyền data qua `of()` vào `getDataComponentOutlet`, BẮT BUỘC khai báo `of<ExtractInputs<I_DataInComponent...>>({...})`. Dùng `of({...})` không có generic sẽ mất type-safety và TypeScript không báo lỗi thiếu field.
|
|
609
|
+
|
|
610
|
+
⚠️ **PathOf có Depth giới hạn mặc định là 6**: Với object lồng nhau sâu hơn 6 cấp, các path vượt quá sẽ trả về `never`. Có thể tăng `Depth` khi cần: `PathOf<T, 8>`.
|
|
611
|
+
|
|
612
|
+
⚠️ **SignalOf không wrap các kiểu đặc biệt thêm lần nữa**: `Dayjs`, `Date`, `File`, `Blob`, `HttpParams`, `FormData`, `Event`, `Node`, `Map`, `Set`, `RegExp` và các Promise/Function sẽ chỉ được wrap 1 cấp signal — không đệ quy vào bên trong.
|
|
613
|
+
|
|
614
|
+
⚠️ **TYPE_OBJECT cần comment lý do**: Theo coding convention, mọi nơi sử dụng `TYPE_OBJECT` phải kèm comment `// CONVENTION-EXCEPT: TYPE_OBJECT — [lý do cụ thể]`. Không dùng tuỳ tiện.
|
|
615
|
+
|
|
616
|
+
⚠️ **IHttpResponse.feCloneCode là trường đặc biệt**: Trường này chỉ được gán từ phía frontend khi muốn override logic sau khi server trả về HTTP 200 nhưng business code lại là giá trị khác. Không phải field từ backend.
|
|
617
|
+
|
|
618
|
+
⚠️ **GetValueAtPath với R=false/true khác nhau**: Tham số `R=false` (mặc định) sẽ unwrap toàn bộ `WritableSignal` về giá trị thuần. `R=true` giữ nguyên cấu trúc signal. Lựa chọn `R` phải nhất quán với mục đích sử dụng.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export {};
|
|
2
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy11dGlsaXRpZXMtZm9yLXBhdGgtdmFsdWUudHlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYnMtdWkvaW50ZXJmYWNlcy10eXBlcy9zcmMvZ2VuZXJpYy11dGlsaXRpZXMtZm9yLXBhdGgtdmFsdWUudHlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqL1xuaW1wb3J0IHsgSHR0cFBhcmFtcyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IFNpZ25hbCwgV3JpdGFibGVTaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERheWpzIH0gZnJvbSAnZGF5anMnO1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSBIZWxwZXJzOiB1bndyYXAgJiBzaGFwZSA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG50eXBlIElzRW1wdHlPYmplY3Q8T2JqPiA9IFtrZXlvZiBPYmpdIGV4dGVuZHMgW25ldmVyXSA/IHRydWUgOiBmYWxzZTtcblxuLy8gVW53cmFwIHRvw6BuIGLhu5kgU2lnbmFsXG50eXBlIFVud3JhcEFsbFNpZ25hbHM8VD4gPSBUIGV4dGVuZHMgU2lnbmFsPGluZmVyIFU+ID8gVW53cmFwQWxsU2lnbmFsczxVPiA6IFQ7XG5cbi8vIExv4bqhaSBi4buPIHVuZGVmaW5lZCB8IG51bGwgc2F1IGtoaSB1bndyYXAgMSBs4bubcCBTaWduYWwgxJHhu4Mgc29pIHNoYXBlXG50eXBlIENsZWFuPFQ+ID0gRXhjbHVkZTxVbndyYXBBbGxTaWduYWxzPFQ+LCB1bmRlZmluZWQgfCBudWxsPjtcblxuLy8gS2V5IGThuqFuZyBzdHJpbmdcbnR5cGUgU3RyS2V5czxUPiA9IEV4dHJhY3Q8a2V5b2YgVCwgc3RyaW5nPjtcblxuLyoqID09PT09PT09PT09PT09PT09PT09PT0gQXJyYXkgaGVscGVycyA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG4vLyBM4bqleSBlbGVtZW50IHR5cGUgY+G7p2EgbeG6o25nLCB04buxIGzDoG0gc+G6oWNoIChi4buPIHVuZGVmaW5lZC9udWxsLCB1bndyYXAgU2lnbmFsIHRyxrDhu5tjIGtoaSBraeG7g20gdHJhKVxudHlwZSBBcnJheUVsZW1lbnRSYXc8VD4gPSBVbndyYXBBbGxTaWduYWxzPENsZWFuPFQ+PiBleHRlbmRzIFJlYWRvbmx5QXJyYXk8aW5mZXIgVT4gPyBVIDogVW53cmFwQWxsU2lnbmFsczxDbGVhbjxUPj4gZXh0ZW5kcyAoaW5mZXIgVSlbXSA/IFUgOiBuZXZlcjtcblxuLy8gS2nhu4NtIHRyYSBhcnJheS1saWtlIHNhdSBraGkgdW53cmFwIHRvw6BuIGLhu5kgU2lnbmFsIHbDoCBsw6BtIHPhuqFjaCBvcHRpb25hbFxudHlwZSBJc0FycmF5TGlrZTxUPiA9IFVud3JhcEFsbFNpZ25hbHM8Q2xlYW48VD4+IGV4dGVuZHMgcmVhZG9ubHkgdW5rbm93bltdID8gdHJ1ZSA6IFVud3JhcEFsbFNpZ25hbHM8Q2xlYW48VD4+IGV4dGVuZHMgdW5rbm93bltdID8gdHJ1ZSA6IGZhbHNlO1xuXG4vLyBLaeG7g20gdHJhIG9iamVjdCBraMO0bmcgcGjhuqNpIGFycmF5IHNhdSBraGkgdW53cmFwIHRvw6BuIGLhu5kgU2lnbmFsIHbDoCBsw6BtIHPhuqFjaCBvcHRpb25hbFxudHlwZSBJc05vbkFycmF5T2JqZWN0PFQ+ID0gVW53cmFwQWxsU2lnbmFsczxDbGVhbjxUPj4gZXh0ZW5kcyBvYmplY3QgPyAoVW53cmFwQWxsU2lnbmFsczxDbGVhbjxUPj4gZXh0ZW5kcyByZWFkb25seSB1bmtub3duW10gPyBmYWxzZSA6IFVud3JhcEFsbFNpZ25hbHM8Q2xlYW48VD4+IGV4dGVuZHMgdW5rbm93bltdID8gZmFsc2UgOiB0cnVlKSA6IGZhbHNlO1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSBET00vRXZ0IGd1YXJkID09PT09PT09PT09PT09PT09PT09PT0gKiovXG5cbnR5cGUgSXNET01UeXBlPFQ+ID0gVW53cmFwQWxsU2lnbmFsczxUPiBleHRlbmRzIEV2ZW50IHwgTm9kZSB8IERvY3VtZW50IHwgRWxlbWVudCB8IFdpbmRvdyB8IENTU1N0eWxlRGVjbGFyYXRpb24gfCBDU1NSdWxlIHwgQ1NTU3R5bGVTaGVldCA/IHRydWUgOiBmYWxzZTtcblxuLyoqID09PT09PT09PT09PT09PT09PT09PT0gRmluYWxpemUgKGdp4buvIFNpZ25hbCBu4bq/dSBj4bqnbikgPT09PT09PT09PT09PT09PT09PT09PSAqKi9cblxudHlwZSBGaW5hbGl6ZTxULCBSIGV4dGVuZHMgYm9vbGVhbj4gPSBSIGV4dGVuZHMgdHJ1ZSA/IFQgOiBVbndyYXBBbGxTaWduYWxzPFQ+O1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSBEZXB0aCBsaW1pdGVyIChoeWJyaWQsIG3hurdjIMSR4buLbmggNikgPT09PT09PT09PT09PT09PT09PT09PSAqKi9cblxudHlwZSBEZWM8TiBleHRlbmRzIG51bWJlcj4gPSBOIGV4dGVuZHMgNiA/IDUgOiBOIGV4dGVuZHMgNSA/IDQgOiBOIGV4dGVuZHMgNCA/IDMgOiBOIGV4dGVuZHMgMyA/IDIgOiBOIGV4dGVuZHMgMiA/IDEgOiBOIGV4dGVuZHMgMSA/IDAgOiAwO1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSBQYXRoIGJ1aWxkZXJzIChEZXB0aC1saW1pdGVkKSA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG4vLyBQYXRoIGNobyBhcnJheSDhu58gcm9vdC9maWVsZFxudHlwZSBQYXRoRm9yQXJyYXk8VCwgRGVwdGggZXh0ZW5kcyBudW1iZXI+ID0gW0RlcHRoXSBleHRlbmRzIFswXSA/IG5ldmVyIDogYFske251bWJlcn1dYCB8IChQYXRoT2Y8QXJyYXlFbGVtZW50UmF3PFQ+LCBEZWM8RGVwdGg+PiBleHRlbmRzIG5ldmVyID8gbmV2ZXIgOiBgWyR7bnVtYmVyfV0uJHtQYXRoT2Y8QXJyYXlFbGVtZW50UmF3PFQ+LCBEZWM8RGVwdGg+Pn1gKTtcblxuLy8gUGF0aCBjaG8gdOG7q25nIHByb3AgSyB0w7l5IGtp4buDdSBnacOhIHRy4buLXG50eXBlIFBhdGhGb3JQcm9wPFRQcm9wLCBLIGV4dGVuZHMgc3RyaW5nLCBEZXB0aCBleHRlbmRzIG51bWJlcj4gPSBbRGVwdGhdIGV4dGVuZHMgWzBdXG4gID8gS1xuICA6IElzQXJyYXlMaWtlPFRQcm9wPiBleHRlbmRzIHRydWVcbiAgICA/IGAke0t9YCB8IGAke0t9WyR7bnVtYmVyfV1gIHwgKFBhdGhPZjxBcnJheUVsZW1lbnRSYXc8VFByb3A+LCBEZWM8RGVwdGg+PiBleHRlbmRzIG5ldmVyID8gbmV2ZXIgOiBgJHtLfVske251bWJlcn1dLiR7UGF0aE9mPEFycmF5RWxlbWVudFJhdzxUUHJvcD4sIERlYzxEZXB0aD4+fWApXG4gICAgOiBJc05vbkFycmF5T2JqZWN0PFRQcm9wPiBleHRlbmRzIHRydWVcbiAgICAgID8gYCR7S31gIHwgKFBhdGhPZjxDbGVhbjxUUHJvcD4sIERlYzxEZXB0aD4+IGV4dGVuZHMgbmV2ZXIgPyBuZXZlciA6IGAke0t9LiR7UGF0aE9mPENsZWFuPFRQcm9wPiwgRGVjPERlcHRoPj59YClcbiAgICAgIDogYCR7S31gO1xuXG4vLyBQYXRoIGNobyBvYmplY3QgKG1hcCB04burbmcga2V5KVxudHlwZSBQYXRoRm9yT2JqZWN0PFQsIERlcHRoIGV4dGVuZHMgbnVtYmVyPiA9IHtcbiAgW0sgaW4gU3RyS2V5czxUPl06IFBhdGhGb3JQcm9wPFRbS10sIEssIERlcHRoPjtcbn1bU3RyS2V5czxUPl07XG5cbi8qKiA9PT09PT09PT09PT09PT09PT09PT09IFB1YmxpYzogUGF0aE9mIChoeWJyaWQsIERlcHRoIG3hurdjIMSR4buLbmggNikgPT09PT09PT09PT09PT09PT09PT09PSAqKi9cblxuZXhwb3J0IHR5cGUgUGF0aE9mPFRSYXcsIERlcHRoIGV4dGVuZHMgbnVtYmVyID0gNj4gPVxuICBJc0VtcHR5T2JqZWN0PENsZWFuPFRSYXc+PiBleHRlbmRzIHRydWVcbiAgICA/IGFueVxuICAgIDogSXNET01UeXBlPENsZWFuPFRSYXc+PiBleHRlbmRzIHRydWVcbiAgICAgID8gYW55XG4gICAgICA6IFtEZXB0aF0gZXh0ZW5kcyBbMF1cbiAgICAgICAgPyBuZXZlclxuICAgICAgICA6IFVud3JhcEFsbFNpZ25hbHM8Q2xlYW48VFJhdz4+IGV4dGVuZHMgcmVhZG9ubHkgdW5rbm93bltdIHwgdW5rbm93bltdXG4gICAgICAgICAgPyBQYXRoRm9yQXJyYXk8Q2xlYW48VFJhdz4sIERlcHRoPlxuICAgICAgICAgIDogVW53cmFwQWxsU2lnbmFsczxDbGVhbjxUUmF3Pj4gZXh0ZW5kcyBvYmplY3RcbiAgICAgICAgICAgID8gUGF0aEZvck9iamVjdDxVbndyYXBBbGxTaWduYWxzPENsZWFuPFRSYXc+PiwgRGVwdGg+XG4gICAgICAgICAgICA6IHN0cmluZztcblxuLyoqID09PT09PT09PT09PT09PT09PT09PT0gUmVzb2x2ZSBnacOhIHRy4buLIHRoZW8gcGF0aCA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG4vLyBHZXRJbnRlcm5hbDogxJFpIHRoZW8gc3RyaW5nIHBhdGggxJHhu4MgcmVzb2x2ZSB0eXBlIGdpw6EgdHLhu4sgY3Xhu5FpIGPDuW5nXG4vLyBT4butIGThu6VuZyBkaXN0cmlidXRpdmUgY29uZGl0aW9uYWwgdHlwZSAoVFJhdyBleHRlbmRzIG51bGwgfCB1bmRlZmluZWQpIMSR4buDIHThu7EgxJHhu5luZyBoYW5kbGUgdW5pb24gY8OzIHVuZGVmaW5lZC9udWxsICh2w60gZOG7pSBvcHRpb25hbCBwcm9wcykuXG50eXBlIEdldEludGVybmFsPFRSYXcsIFAgZXh0ZW5kcyBzdHJpbmcsIFIgZXh0ZW5kcyBib29sZWFuPiA9IFRSYXcgZXh0ZW5kcyBudWxsIHwgdW5kZWZpbmVkXG4gID8gVFJhd1xuICA6IC8vIFt4XS5SZXN0ICjEkcOhbmggaW5kZXggdsOgbyByb290IGFycmF5KVxuICAgIFAgZXh0ZW5kcyBgWyR7aW5mZXIgSX1dLiR7aW5mZXIgUmVzdH1gXG4gICAgPyBJIGV4dGVuZHMgYCR7bnVtYmVyfWBcbiAgICAgID8gR2V0SW50ZXJuYWw8QXJyYXlFbGVtZW50UmF3PFRSYXc+LCBSZXN0LCBSPlxuICAgICAgOiBhbnlcbiAgICA6IC8vIFt4XSAoY2jhu4kgaW5kZXgpXG4gICAgICBQIGV4dGVuZHMgYFske2luZmVyIEl9XWBcbiAgICAgID8gSSBleHRlbmRzIGAke251bWJlcn1gXG4gICAgICAgID8gRmluYWxpemU8QXJyYXlFbGVtZW50UmF3PFRSYXc+LCBSPlxuICAgICAgICA6IGFueVxuICAgICAgOiAvLyBLW3hdLlJlc3QgKMSRw6FuaCBpbmRleCB2w6BvIGZpZWxkIG3huqNuZylcbiAgICAgICAgUCBleHRlbmRzIGAke2luZmVyIEt9WyR7aW5mZXIgSX1dLiR7aW5mZXIgUmVzdH1gXG4gICAgICAgID8gSyBleHRlbmRzIFN0cktleXM8Q2xlYW48VW53cmFwQWxsU2lnbmFsczxUUmF3Pj4+XG4gICAgICAgICAgPyBJIGV4dGVuZHMgYCR7bnVtYmVyfWBcbiAgICAgICAgICAgID8gR2V0SW50ZXJuYWw8QXJyYXlFbGVtZW50UmF3PENsZWFuPFVud3JhcEFsbFNpZ25hbHM8VFJhdz4+W0tdPiwgUmVzdCwgUj5cbiAgICAgICAgICAgIDogYW55XG4gICAgICAgICAgOiBhbnlcbiAgICAgICAgOiAvLyBLLlJlc3QgKMSRaSBzw6J1IHbDoG8gb2JqZWN0KVxuICAgICAgICAgIFAgZXh0ZW5kcyBgJHtpbmZlciBLfS4ke2luZmVyIFJlc3R9YFxuICAgICAgICAgID8gSyBleHRlbmRzIFN0cktleXM8Q2xlYW48VW53cmFwQWxsU2lnbmFsczxUUmF3Pj4+XG4gICAgICAgICAgICA/IElzQXJyYXlMaWtlPENsZWFuPFVud3JhcEFsbFNpZ25hbHM8VFJhdz4+W0tdPiBleHRlbmRzIHRydWVcbiAgICAgICAgICAgICAgPyBhbnkgLy8ga2jDtG5nIGjhu5cgdHLhu6MgZG90IHbDoG8gcGjhuqduIHThu60gbeG6o25nIGtoaSB0aGnhur91IGluZGV4XG4gICAgICAgICAgICAgIDogR2V0SW50ZXJuYWw8Q2xlYW48VW53cmFwQWxsU2lnbmFsczxUUmF3Pj5bS10sIFJlc3QsIFI+XG4gICAgICAgICAgICA6IGFueVxuICAgICAgICAgIDogLy8gS1s8bnVtYmVyPl0gKGvhur90IHRow7pjIOG7nyBpbmRleClcbiAgICAgICAgICAgIFAgZXh0ZW5kcyBgJHtpbmZlciBLfVske2luZmVyIEl9XWBcbiAgICAgICAgICAgID8gSyBleHRlbmRzIFN0cktleXM8Q2xlYW48VW53cmFwQWxsU2lnbmFsczxUUmF3Pj4+XG4gICAgICAgICAgICAgID8gSSBleHRlbmRzIGAke251bWJlcn1gXG4gICAgICAgICAgICAgICAgPyBGaW5hbGl6ZTxBcnJheUVsZW1lbnRSYXc8Q2xlYW48VW53cmFwQWxsU2lnbmFsczxUUmF3Pj5bS10+LCBSPlxuICAgICAgICAgICAgICAgIDogYW55XG4gICAgICAgICAgICAgIDogYW55XG4gICAgICAgICAgICA6IC8vIEsgKGvhur90IHRow7pjIOG7nyBrZXkpXG4gICAgICAgICAgICAgIFAgZXh0ZW5kcyBgJHtpbmZlciBLfWBcbiAgICAgICAgICAgICAgPyBLIGV4dGVuZHMgU3RyS2V5czxDbGVhbjxVbndyYXBBbGxTaWduYWxzPFRSYXc+Pj5cbiAgICAgICAgICAgICAgICA/IEZpbmFsaXplPENsZWFuPFVud3JhcEFsbFNpZ25hbHM8VFJhdz4+W0tdLCBSPlxuICAgICAgICAgICAgICAgIDogYW55XG4gICAgICAgICAgICAgIDogYW55O1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSBQdWJsaWM6IEdldFZhbHVlQXRQYXRoICYgR2V0UmV0dXJuVHlwZSA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG4vLyBSZXNvbHZlIGtp4buDdSBnacOhIHRy4buLIHThuqFpIHBhdGggUC4gTuG6v3UgUj10cnVlLCBnaeG7ryBuZ3V5w6puIFNpZ25hbDsgbeG6t2MgxJHhu4tuaCBSPWZhbHNlIHPhur0gdW53cmFwIHRvw6BuIGLhu5kgU2lnbmFsLlxuZXhwb3J0IHR5cGUgR2V0VmFsdWVBdFBhdGg8VFJhdywgUCBleHRlbmRzIFBhdGhPZjxUUmF3PiwgUiBleHRlbmRzIGJvb2xlYW4gPSBmYWxzZT4gPSBUUmF3IGV4dGVuZHMgbnVsbCB8IHVuZGVmaW5lZCA/IFRSYXcgOiBHZXRJbnRlcm5hbDxUUmF3LCBQLCBSPjtcblxuLy8gS2nhu4N1IHRy4bqjIHbhu4EgY+G7p2EgZ2V0KCkgZOG7sWEgdHLDqm4gZGVmYXVsdFZhbHVlIERcbmV4cG9ydCB0eXBlIEdldFJldHVyblR5cGU8TywgUCBleHRlbmRzIFBhdGhPZjxPPiwgS1MgZXh0ZW5kcyBib29sZWFuLCBEIGV4dGVuZHMgR2V0VmFsdWVBdFBhdGg8TywgUCwgS1M+IHwgdW5kZWZpbmVkPiA9IEQgZXh0ZW5kcyB1bmRlZmluZWQgPyBHZXRWYWx1ZUF0UGF0aDxPLCBQLCBLUz4gOiBFeGNsdWRlPEdldFZhbHVlQXRQYXRoPE8sIFAsIEtTPiwgbnVsbCB8IHVuZGVmaW5lZD47XG5cbi8vIEtp4buDbSB0cmEgY8OhYyBraeG7g3UgZOG7ryBsaeG7h3UgxJHhurdjIGJp4buHdCDEkeG7gyBjaOG7iSB3cmFwIHNpZ25hbCAxIGPhuqVwXG50eXBlIElzU3BlY2lmaWNUeXBlPFQ+ID0gW1RdIGV4dGVuZHMgW1xuICB8IEV2ZW50XG4gIHwgTm9kZVxuICB8IERvY3VtZW50XG4gIHwgRWxlbWVudFxuICB8IFdpbmRvd1xuICB8IENTU1N0eWxlRGVjbGFyYXRpb25cbiAgfCBDU1NSdWxlXG4gIHwgQ1NTU3R5bGVTaGVldFxuICB8IEh0dHBQYXJhbXNcbiAgfCBEYXlqc1xuICB8IERhdGVcbiAgfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpXG4gIHwgUHJvbWlzZTxhbnk+XG4gIHwgTWFwPGFueSwgYW55PlxuICB8IFNldDxhbnk+XG4gIHwgV2Vha01hcDxhbnksIGFueT5cbiAgfCBXZWFrU2V0PGFueT5cbiAgfCBSZWdFeHBcbiAgfCBGaWxlXG4gIHwgQmxvYlxuICB8IEZpbGVMaXN0XG4gIHwgRm9ybURhdGEsXG5dXG4gID8gdHJ1ZVxuICA6IGZhbHNlO1xuXG4vLyBIZWxwZXIgdHlwZTogeOG7rSBsw70gbG9naWMgY2jDrW5oIG3DoCBLSMOUTkcgZGlzdHJpYnV0ZSAobm9uLWRpc3RyaWJ1dGl2ZSlcbnR5cGUgU2lnbmFsT2ZOb25OdWxsYWJsZTxULCBQIGV4dGVuZHMgYm9vbGVhbiwgRiBleHRlbmRzIGJvb2xlYW4+ID1cbiAgLy8gTuG6v3UgVCDEkcOjIGzDoCBXcml0YWJsZVNpZ25hbCwgZ2nhu68gbmd1ecOqbiAodHLDoW5oIHdyYXAgMiBs4bqnbilcbiAgW1RdIGV4dGVuZHMgW1dyaXRhYmxlU2lnbmFsPGFueT5dXG4gICAgPyBUXG4gICAgOiBbSXNTcGVjaWZpY1R5cGU8VD5dIGV4dGVuZHMgW3RydWVdXG4gICAgICA/IEYgZXh0ZW5kcyB0cnVlXG4gICAgICAgID8gV3JpdGFibGVTaWduYWw8VD5cbiAgICAgICAgOiBUXG4gICAgICA6IFtUXSBleHRlbmRzIFtSZWFkb25seUFycmF5PGFueT5dXG4gICAgICAgID8gRiBleHRlbmRzIHRydWVcbiAgICAgICAgICA/IFdyaXRhYmxlU2lnbmFsPEFycmF5PFNpZ25hbE9mSW1wbDxBcnJheUVsZW1lbnRSYXc8VD4sIFAsIHRydWU+Pj5cbiAgICAgICAgICA6IEFycmF5PFNpZ25hbE9mSW1wbDxBcnJheUVsZW1lbnRSYXc8VD4sIFAsIHRydWU+PlxuICAgICAgICA6IFtUXSBleHRlbmRzIFtvYmplY3RdXG4gICAgICAgICAgPyBGIGV4dGVuZHMgdHJ1ZVxuICAgICAgICAgICAgPyBXcml0YWJsZVNpZ25hbDx7IFtLIGluIGtleW9mIFRdOiBTaWduYWxPZkltcGw8VFtLXSwgUCwgdHJ1ZT4gfT5cbiAgICAgICAgICAgIDogeyBbSyBpbiBrZXlvZiBUXTogU2lnbmFsT2ZJbXBsPFRbS10sIFAsIHRydWU+IH1cbiAgICAgICAgICA6IFtUXSBleHRlbmRzIFtzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuXVxuICAgICAgICAgICAgPyBQIGV4dGVuZHMgdHJ1ZVxuICAgICAgICAgICAgICA/IFdyaXRhYmxlU2lnbmFsPFQ+XG4gICAgICAgICAgICAgIDogVFxuICAgICAgICAgICAgOiBXcml0YWJsZVNpZ25hbDxUPjtcblxuLy8gSW1wbGVtZW50YXRpb24gaGVscGVyOiB0w6FjaCBudWxsL3VuZGVmaW5lZCBtw6AgS0jDlE5HIGTDuW5nIGRpc3RyaWJ1dGl2ZSBjb25kaXRpb25hbFxudHlwZSBTaWduYWxPZkltcGw8VCwgUCBleHRlbmRzIGJvb2xlYW4sIEYgZXh0ZW5kcyBib29sZWFuPiA9IEV4dHJhY3Q8VCwgbnVsbCB8IHVuZGVmaW5lZD4gZXh0ZW5kcyBuZXZlciA/IFNpZ25hbE9mTm9uTnVsbGFibGU8VCwgUCwgRj4gOiBTaWduYWxPZk5vbk51bGxhYmxlPEV4Y2x1ZGU8VCwgbnVsbCB8IHVuZGVmaW5lZD4sIFAsIEY+IHwgRXh0cmFjdDxULCBudWxsIHwgdW5kZWZpbmVkPjtcblxuLy8gxJDGsGEga2nhu4N1IGThu68gbGnhu4d1IGLhuqV0IGvhu7MgduG7gSBk4bqhbmcgc2lnbmFsLCBO4bq/dSBQID0gdHJ1ZSDEkcawYSBj4bqjIGThu68gbGnhu4d1IHByZW1ldGl2ZV90eXBlIHbhu4EgZOG6oW5nIHNpZ25hbFxuZXhwb3J0IHR5cGUgU2lnbmFsT2Y8VCwgUCBleHRlbmRzIGJvb2xlYW4gPSB0cnVlLCBGIGV4dGVuZHMgYm9vbGVhbiA9IGZhbHNlPiA9IFNpZ25hbE9mSW1wbDxULCBQLCBGPjtcblxuZXhwb3J0IHR5cGUgTm9uU2lnbmFsT2Y8VD4gPSBUIGV4dGVuZHMgbnVsbCB8IHVuZGVmaW5lZCA/IFQgOiBDbGVhbjxUPiBleHRlbmRzIEFycmF5PGluZmVyIFU+ID8gQXJyYXk8Tm9uU2lnbmFsT2Y8Q2xlYW48VT4+PiA6IENsZWFuPFQ+IGV4dGVuZHMgb2JqZWN0ID8geyBbSyBpbiBrZXlvZiBDbGVhbjxUPl06IE5vblNpZ25hbE9mPENsZWFuPENsZWFuPFQ+W0tdPj4gfSA6IENsZWFuPFQ+O1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSAoVHXhu7MgY2jhu41uKSBWw60gZOG7pSBuaGFuaCA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG5leHBvcnQgdHlwZSBUX1BhZ2VCb3RDb25maWcgPSB7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIG1vZGU/OiAnQVVUTycgfCAnUkVWSUVXJztcbn07XG5cbmV4cG9ydCB0eXBlIFRfU2lnbmFsX1BhZ2VCb3RDb25maWcgPSBTaWduYWxPZjxUX1BhZ2VCb3RDb25maWc+O1xuZXhwb3J0IGludGVyZmFjZSBJQ29tbWVudCB7XG4gIGNvbW1lbnRzPzogV3JpdGFibGVTaWduYWw8SVN1YkNvbW1lbnQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElTdWJDb21tZW50IHtcbiAgc3RvcmU/OiBXcml0YWJsZVNpZ25hbDxBcnJheTxXcml0YWJsZVNpZ25hbDxJQ29tbWVudD4+PjtcbiAgZGF0YT86IFdyaXRhYmxlU2lnbmFsPEFycmF5PFdyaXRhYmxlU2lnbmFsPElDb21tZW50Pj4+O1xuICBzcGVjaWZpY190ZW1wX2RhdGE/OiBXcml0YWJsZVNpZ25hbDxBcnJheTxXcml0YWJsZVNpZ25hbDxJQ29tbWVudD4+PjtcbiAgcGFnaW5nPzogV3JpdGFibGVTaWduYWw8e1xuICAgIGN1cnNvcnM/OiBXcml0YWJsZVNpZ25hbDx7XG4gICAgICBhZnRlcj86IFdyaXRhYmxlU2lnbmFsPHN0cmluZz47XG4gICAgICBiZWZvcmU/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgIH0+O1xuICAgIGJlZm9yZT86IFdyaXRhYmxlU2lnbmFsPHN0cmluZz47XG4gICAgYWZ0ZXI/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgIG5leHQ/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgIHByZXZpb3VzPzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgfT47XG4gIHN1bW1hcnk/OiBXcml0YWJsZVNpZ25hbDx7XG4gICAgY2FuX2NvbW1lbnQ/OiBXcml0YWJsZVNpZ25hbDxib29sZWFuPjtcbiAgICBjYW5vcmRlcl9jb21tZW50PzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgICB0b3RhbF9jb3VudD86IFdyaXRhYmxlU2lnbmFsPG51bWJlcj47XG4gIH0+O1xufVxuXG50eXBlIFZfY29tbWVudHNfRiA9IEdldFZhbHVlQXRQYXRoPElDb21tZW50LCAnY29tbWVudHMnLCBmYWxzZT47IC8vIElTdWJDb21tZW50XG50eXBlIFZfY29tbWVudHNfVCA9IEdldFZhbHVlQXRQYXRoPElDb21tZW50LCAnY29tbWVudHMnLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8SVN1YkNvbW1lbnQ+XG5cbnR5cGUgVl9jb21tZW50c19zdG9yZV9GID0gR2V0VmFsdWVBdFBhdGg8SUNvbW1lbnQsICdjb21tZW50cy5kYXRhJywgZmFsc2U+OyAvLyBBcnJheTxXcml0YWJsZVNpZ25hbDxJQ29tbWVudD4+XG50eXBlIFZfY29tbWVudHNfc3RvcmVfVCA9IEdldFZhbHVlQXRQYXRoPElDb21tZW50LCAnY29tbWVudHMuZGF0YScsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDxBcnJheTxXcml0YWJsZVNpZ25hbDxJQ29tbWVudD4+PlxuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3Qge1xuICBzcGVjaWZpY19xdWVyeT86IFdyaXRhYmxlU2lnbmFsPElBc3NpZ25tZW50SXRlbVF1ZXJ5PjtcblxuICBkYXRhOiBXcml0YWJsZVNpZ25hbDxBcnJheTxXcml0YWJsZVNpZ25hbDxJQXNzaWdubWVudEl0ZW0+Pj47XG5cbiAgaW5kZXg6IG51bWJlcjtcbiAgaW5mbzoge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBhZ2U6IG51bWJlcjtcbiAgICBhbmltYWw6IGJvb2xlYW47XG4gICAgY2F0ZTogJ2FsbycgfCAnYWxvMic7XG4gIH07XG4gIGNpdHk6IFdyaXRhYmxlU2lnbmFsPHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgY291bnRyeTogc3RyaW5nO1xuICB9PjtcbiAgYWRkcmVzczogV3JpdGFibGVTaWduYWw8e1xuICAgIGlwOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgIHBvcnQ6IFdyaXRhYmxlU2lnbmFsPG51bWJlcj47XG4gIH0+O1xuICBvd25lcjogQXJyYXk8c3RyaW5nPjtcbiAgc3VwcG9ydDogQXJyYXk8V3JpdGFibGVTaWduYWw8c3RyaW5nPj47XG4gIGhvc3Q6IEFycmF5PHtcbiAgICBpcDogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgICBwb3J0OiBudW1iZXI7XG4gIH0+O1xuXG4gIGNvdW50cnk6IFdyaXRhYmxlU2lnbmFsPFxuICAgIEFycmF5PFxuICAgICAgV3JpdGFibGVTaWduYWw8e1xuICAgICAgICBuYW1lOiBXcml0YWJsZVNpZ25hbDx7XG4gICAgICAgICAgdmk6IHN0cmluZztcbiAgICAgICAgICBlbjogc3RyaW5nO1xuICAgICAgICB9PjtcbiAgICAgICAgY29kZTogV3JpdGFibGVTaWduYWw8e1xuICAgICAgICAgIHZpOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgICAgICAgIGVuOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgICAgICB9PjtcbiAgICAgICAgZmxhZzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgICAgICAgcGhvbmVfY29kZTogc3RyaW5nO1xuICAgICAgICBjdXJyZW5jeToge1xuICAgICAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgICAgICBjb2RlOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgICAgICAgIHN5bWJvbDogV3JpdGFibGVTaWduYWw8e1xuICAgICAgICAgICAgdmk6IHN0cmluZztcbiAgICAgICAgICAgIGVuOiBzdHJpbmc7XG4gICAgICAgICAgICBjbjogV3JpdGFibGVTaWduYWw8QXJyYXk8c3RyaW5nPj47XG4gICAgICAgICAgICBqcDogV3JpdGFibGVTaWduYWw8XG4gICAgICAgICAgICAgIEFycmF5PFxuICAgICAgICAgICAgICAgIFdyaXRhYmxlU2lnbmFsPHtcbiAgICAgICAgICAgICAgICAgIHZpOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgICBlbjogc3RyaW5nO1xuICAgICAgICAgICAgICAgIH0+XG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgID47XG4gICAgICAgICAgfT47XG4gICAgICAgIH07XG4gICAgICB9PlxuICAgID5cbiAgPjtcbn1cblxudHlwZSBUZXN0MSA9IEdldFJldHVyblR5cGU8SUFzc2lnbm1lbnRJdGVtLCAnY2hhdGJvdF9jb25maWcubW9kZScsIHRydWUsICdSRVZJRVcnPjtcbnR5cGUgVGVzdDIgPSBTaWduYWxPZjxUZXN0PjtcbnR5cGUgVGVzdDMgPSBHZXRSZXR1cm5UeXBlPFRlc3QyLCAnaW5mby5jYXRlJywgdHJ1ZSwgV3JpdGFibGVTaWduYWw8J2Fsbyc+PjtcblxuaW50ZXJmYWNlIElBc3NpZ25tZW50SXRlbSB7XG4gIGlkOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBuYW1lOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBkZXNjcmlwdGlvbjogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgY3JlYXRlZF9hdDogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgdXBkYXRlZF9hdDogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgYXNzaWduZWVzPzogV3JpdGFibGVTaWduYWw8QXJyYXk8V3JpdGFibGVTaWduYWw8SUFzc2lnbmVlPj4+O1xuICBjaGF0Ym90X2NvbmZpZz86IFdyaXRhYmxlU2lnbmFsPFRfUGFnZUJvdENvbmZpZz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUFzc2lnbmVlIHtcbiAgYXNzaWduZWVfaWQ/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBjb252ZXJzYXRpb25faWQ/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBjcmVhdGVkX3RpbWU/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBjcmVhdGVkX3VzZXI/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBpZD86IFdyaXRhYmxlU2lnbmFsPHN0cmluZz47XG4gIG5vdGU/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBzdGF0dXM/OiBXcml0YWJsZVNpZ25hbDxudW1iZXI+O1xuICBhc3NpZ25fdGFnX2FjdGl2aXR5X3N0YXR1cz86IFdyaXRhYmxlU2lnbmFsPG51bWJlcj47XG4gIGNvbW1lbnRfaWQ/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICByYXRpbmdfaWQ/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElBc3NpZ25tZW50SXRlbVF1ZXJ5IHtcbiAgcGVyX3BhZ2U6IFdyaXRhYmxlU2lnbmFsPG51bWJlcj47XG4gIGFmdGVyX3Rva2VuPzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgYmVmb3JlX3Rva2VuPzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgc2VhcmNoPzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgc2VhcmNoX2luZGV4PzogV3JpdGFibGVTaWduYWw8bnVtYmVyPjtcbn1cblxudHlwZSBWX2luZGV4X0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5kZXgnLCBmYWxzZT47IC8vIG51bWJlclxudHlwZSBWX2luZGV4X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5kZXgnLCB0cnVlPjsgLy8gbnVtYmVyXG5cbnR5cGUgVl9pbmZvX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5mbycsIGZhbHNlPjsgLy8geyBuYW1lOiBzdHJpbmc7IGFnZTogbnVtYmVyIH1cbnR5cGUgVl9pbmZvX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5mbycsIHRydWU+OyAvLyB7IG5hbWU6IHN0cmluZzsgYWdlOiBudW1iZXIgfVxudHlwZSBWX2luZm9fbmFtZV9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2luZm8ubmFtZScsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfaW5mb19uYW1lX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5mby5uYW1lJywgdHJ1ZT47IC8vIHN0cmluZ1xudHlwZSBWX2luZm9fYWdlX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5mby5hZ2UnLCBmYWxzZT47IC8vIG51bWJlclxudHlwZSBWX2luZm9fYWdlX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5mby5hZ2UnLCB0cnVlPjsgLy8gbnVtYmVyXG5cbi8vIENpdHkgKHNpZ25hbC13cmFwcGVkIG9iamVjdCB3aXRoIHBsYWluIGZpZWxkcylcbnR5cGUgVl9jaXR5X0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY2l0eScsIGZhbHNlPjsgLy8geyBuYW1lOiBzdHJpbmc7IGNvdW50cnk6IHN0cmluZyB9XG50eXBlIFZfY2l0eV9UID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NpdHknLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8eyBuYW1lOiBzdHJpbmc7IGNvdW50cnk6IHN0cmluZyB9PlxudHlwZSBWX2NpdHlfbmFtZV9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NpdHkubmFtZScsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfY2l0eV9uYW1lX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY2l0eS5uYW1lJywgdHJ1ZT47IC8vIHN0cmluZ1xudHlwZSBWX2NpdHlfY291bnRyeV9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NpdHkuY291bnRyeScsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfY2l0eV9jb3VudHJ5X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY2l0eS5jb3VudHJ5JywgdHJ1ZT47IC8vIHN0cmluZ1xuXG4vLyBBZGRyZXNzIChzaWduYWwtd3JhcHBlZCBvYmplY3Qgd2l0aCBzaWduYWwgbGVhdmVzKVxudHlwZSBWX2FkZHJlc3NfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdhZGRyZXNzJywgZmFsc2U+OyAvLyB7IGlwOiBzdHJpbmc7IHBvcnQ6IG51bWJlciB9XG50eXBlIFZfYWRkcmVzc19UID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2FkZHJlc3MnLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8eyBpcDogV3JpdGFibGVTaWduYWw8c3RyaW5nPjsgcG9ydDogV3JpdGFibGVTaWduYWw8bnVtYmVyPiB9PlxudHlwZSBWX2FkZHJlc3NfaXBfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdhZGRyZXNzLmlwJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9hZGRyZXNzX2lwX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnYWRkcmVzcy5pcCcsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDxzdHJpbmc+XG50eXBlIFZfYWRkcmVzc19wb3J0X0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnYWRkcmVzcy5wb3J0JywgZmFsc2U+OyAvLyBudW1iZXJcbnR5cGUgVl9hZGRyZXNzX3BvcnRfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdhZGRyZXNzLnBvcnQnLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8bnVtYmVyPlxuXG4vLyBPd25lciAoYXJyYXkgb2YgcHJpbWl0aXZlcylcbnR5cGUgVl9vd25lcl9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ293bmVyJywgZmFsc2U+OyAvLyBzdHJpbmdbXVxudHlwZSBWX293bmVyX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnb3duZXInLCB0cnVlPjsgLy8gc3RyaW5nW11cbnR5cGUgVl9vd25lcl9pZHhfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdvd25lclswXScsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfb3duZXJfaWR4X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnb3duZXJbMF0nLCB0cnVlPjsgLy8gc3RyaW5nXG5cbi8vIFN1cHBvcnQgKGFycmF5IG9mIHNpZ25hbHMpXG50eXBlIFZfc3VwcG9ydF9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ3N1cHBvcnQnLCBmYWxzZT47IC8vIHN0cmluZ1tdXG50eXBlIFZfc3VwcG9ydF9UID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ3N1cHBvcnQnLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8c3RyaW5nPltdXG50eXBlIFZfc3VwcG9ydF9pZHhfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdzdXBwb3J0WzBdJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9zdXBwb3J0X2lkeF9UID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ3N1cHBvcnRbMF0nLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8c3RyaW5nPlxuXG4vLyBIb3N0IChhcnJheSBvZiBvYmplY3RzIHdpdGggbWl4ZWQgbGVhdmVzKVxudHlwZSBWX2hvc3RfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdob3N0JywgZmFsc2U+OyAvLyB7IGlwOiBzdHJpbmc7IHBvcnQ6IG51bWJlciB9W11cbnR5cGUgVl9ob3N0X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaG9zdCcsIHRydWU+OyAvLyB7IGlwOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+OyBwb3J0OiBudW1iZXIgfVtdXG50eXBlIFZfaG9zdF9pZHhfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdob3N0WzBdJywgZmFsc2U+OyAvLyB7IGlwOiBzdHJpbmc7IHBvcnQ6IG51bWJlciB9XG50eXBlIFZfaG9zdF9pZHhfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdob3N0WzBdJywgdHJ1ZT47IC8vIHsgaXA6IFdyaXRhYmxlU2lnbmFsPHN0cmluZz47IHBvcnQ6IG51bWJlciB9XG50eXBlIFZfaG9zdF9pcF9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2hvc3RbMF0uaXAnLCBmYWxzZT47IC8vIHN0cmluZ1xudHlwZSBWX2hvc3RfaXBfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdob3N0WzBdLmlwJywgdHJ1ZT47IC8vIFdyaXRhYmxlU2lnbmFsPHN0cmluZz5cbnR5cGUgVl9ob3N0X3BvcnRfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdob3N0WzBdLnBvcnQnLCBmYWxzZT47IC8vIG51bWJlclxudHlwZSBWX2hvc3RfcG9ydF9UID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2hvc3RbMF0ucG9ydCcsIHRydWU+OyAvLyBudW1iZXJcblxuLy8gY3VycmVuY3lcbnR5cGUgVl9jdXJyZW5jeV9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NvdW50cnlbMF0uY3VycmVuY3knLCBmYWxzZT47IC8vIHsgbmFtZTogc3RyaW5nOyBjb2RlOiBzdHJpbmc7IHN5bWJvbDogeyAuLi4gfSB9XG50eXBlIFZfY3VycmVuY3lfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5JywgdHJ1ZT47IC8vIHsgbmFtZTogc3RyaW5nOyBjb2RlOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+OyBzeW1ib2w6IFdyaXRhYmxlU2lnbmFsPHsgLi4uIH0+IH1cbnR5cGUgVl9jdXJyZW5jeV9uYW1lX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5uYW1lJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9jdXJyZW5jeV9uYW1lX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5uYW1lJywgdHJ1ZT47IC8vIHN0cmluZ1xudHlwZSBWX2N1cnJlbmN5X2NvZGVfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LmNvZGUnLCBmYWxzZT47IC8vIHN0cmluZ1xudHlwZSBWX2N1cnJlbmN5X2NvZGVfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LmNvZGUnLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8c3RyaW5nPlxuXG4vLyBjdXJyZW5jeS5zeW1ib2xcbnR5cGUgVl9zeW1ib2xfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbCcsIGZhbHNlPjsgLy8geyB2aTogc3RyaW5nOyBlbjogc3RyaW5nOyBjbjogc3RyaW5nW107IGpwOiB7IHZpOiBzdHJpbmc7IGVuOiBzdHJpbmcgfVtdIH1cbnR5cGUgVl9zeW1ib2xfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbCcsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDx7IHZpOiBzdHJpbmc7IGVuOiBzdHJpbmc7IGNuOiBXcml0YWJsZVNpZ25hbDxzdHJpbmdbXT47IGpwOiBXcml0YWJsZVNpZ25hbDx7IHZpOiBzdHJpbmc7IGVuOiBzdHJpbmcgfVtdPiB9PlxudHlwZSBWX3N5bWJvbF92aV9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NvdW50cnlbMF0uY3VycmVuY3kuc3ltYm9sLnZpJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9zeW1ib2xfdmlfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC52aScsIHRydWU+OyAvLyBzdHJpbmdcbnR5cGUgVl9zeW1ib2xfZW5fRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5lbicsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfc3ltYm9sX2VuX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuZW4nLCB0cnVlPjsgLy8gc3RyaW5nXG50eXBlIFZfc3ltYm9sX2NuX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuY24nLCBmYWxzZT47IC8vIHN0cmluZ1tdXG50eXBlIFZfc3ltYm9sX2NuX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuY24nLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8c3RyaW5nW10+XG50eXBlIFZfc3ltYm9sX2NuX2lkeF9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NvdW50cnlbMF0uY3VycmVuY3kuc3ltYm9sLmNuWzBdJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9zeW1ib2xfY25faWR4X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuY25bMF0nLCB0cnVlPjsgLy8gc3RyaW5nXG50eXBlIFZfc3ltYm9sX2pwX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuanAnLCBmYWxzZT47IC8vIHsgdmk6IHN0cmluZzsgZW46IHN0cmluZyB9W11cbnR5cGUgVl9zeW1ib2xfanBfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5qcCcsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDx7IHZpOiBzdHJpbmc7IGVuOiBzdHJpbmcgfVtdPlxudHlwZSBWX3N5bWJvbF9qcF9pZHhfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5qcFswXScsIGZhbHNlPjsgLy8geyB2aTogc3RyaW5nOyBlbjogc3RyaW5nIH1cbnR5cGUgVl9zeW1ib2xfanBfaWR4X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuanBbMF0nLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8eyB2aTogc3RyaW5nOyBlbjogc3RyaW5nIH0+XG50eXBlIFZfc3ltYm9sX2pwX3ZpX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuanBbMF0udmknLCBmYWxzZT47IC8vIHN0cmluZ1xudHlwZSBWX3N5bWJvbF9qcF92aV9UID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NvdW50cnlbMF0uY3VycmVuY3kuc3ltYm9sLmpwWzBdLnZpJywgdHJ1ZT47IC8vIHN0cmluZ1xudHlwZSBWX3N5bWJvbF9qcF9lbl9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NvdW50cnlbMF0uY3VycmVuY3kuc3ltYm9sLmpwWzBdLmVuJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9zeW1ib2xfanBfZW5fVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5qcFswXS5lbicsIHRydWU+OyAvLyBzdHJpbmdcblxudHlwZSBWX0FycmF5X3N5bWJvbF9jbl9GID0gR2V0VmFsdWVBdFBhdGg8QXJyYXk8VGVzdD4sICdbMF0uY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuY24nLCBmYWxzZT47IC8vIHN0cmluZ1tdXG50eXBlIFZfQXJyYXlfc3ltYm9sX2NuX1QgPSBHZXRWYWx1ZUF0UGF0aDxBcnJheTxUZXN0PiwgJ1swXS5jb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5jbicsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDxzdHJpbmdbXT5cbnR5cGUgVl9BcnJheV9zeW1ib2xfY25faWR4X0YgPSBHZXRWYWx1ZUF0UGF0aDxBcnJheTxUZXN0PiwgJ1swXS5jb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5jblswXScsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfQXJyYXlfc3ltYm9sX2NuX2lkeF9UID0gR2V0VmFsdWVBdFBhdGg8QXJyYXk8VGVzdD4sICdbMF0uY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuY25bMF0nLCB0cnVlPjsgLy8gc3RyaW5nXG5cbnR5cGUgcGF0aElBc3NpZ25tZW50SXRlbSA9IFBhdGhPZjxJQXNzaWdubWVudEl0ZW0+O1xudHlwZSBwYXRoSUFzc2lnbm1lbnRJdGVtMSA9IFBhdGhPZjx1bmtub3duPjsgLy8gc3RyaW5nXG5cbnR5cGUgVl9hc3NpZ25lZXNfRiA9IEdldFZhbHVlQXRQYXRoPElBc3NpZ25tZW50SXRlbSwgJ2Fzc2lnbmVlc1swXScsIGZhbHNlPjsgLy8gSUFzc2lnbmVlXG4iXX0=
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy11dGlsaXRpZXMtZm9yLXBhdGgtdmFsdWUudHlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYnMtdWkvaW50ZXJmYWNlcy10eXBlcy9zcmMvZ2VuZXJpYy11dGlsaXRpZXMtZm9yLXBhdGgtdmFsdWUudHlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqL1xuaW1wb3J0IHsgSHR0cFBhcmFtcyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IFNpZ25hbCwgV3JpdGFibGVTaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERheWpzIH0gZnJvbSAnZGF5anMnO1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSBIZWxwZXJzOiB1bndyYXAgJiBzaGFwZSA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG50eXBlIElzRW1wdHlPYmplY3Q8T2JqPiA9IFtrZXlvZiBPYmpdIGV4dGVuZHMgW25ldmVyXSA/IHRydWUgOiBmYWxzZTtcblxuLy8gVW53cmFwIHRvw6BuIGLhu5kgU2lnbmFsXG50eXBlIFVud3JhcEFsbFNpZ25hbHM8VD4gPSBUIGV4dGVuZHMgU2lnbmFsPGluZmVyIFU+ID8gVW53cmFwQWxsU2lnbmFsczxVPiA6IFQ7XG5cbi8vIExv4bqhaSBi4buPIHVuZGVmaW5lZCB8IG51bGwgc2F1IGtoaSB1bndyYXAgMSBs4bubcCBTaWduYWwgxJHhu4Mgc29pIHNoYXBlXG50eXBlIENsZWFuPFQ+ID0gRXhjbHVkZTxVbndyYXBBbGxTaWduYWxzPFQ+LCB1bmRlZmluZWQgfCBudWxsPjtcblxuLy8gS2V5IGThuqFuZyBzdHJpbmdcbnR5cGUgU3RyS2V5czxUPiA9IEV4dHJhY3Q8a2V5b2YgVCwgc3RyaW5nPjtcblxuLyoqID09PT09PT09PT09PT09PT09PT09PT0gQXJyYXkgaGVscGVycyA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG4vLyBM4bqleSBlbGVtZW50IHR5cGUgY+G7p2EgbeG6o25nLCB04buxIGzDoG0gc+G6oWNoIChi4buPIHVuZGVmaW5lZC9udWxsLCB1bndyYXAgU2lnbmFsIHRyxrDhu5tjIGtoaSBraeG7g20gdHJhKVxudHlwZSBBcnJheUVsZW1lbnRSYXc8VD4gPSBVbndyYXBBbGxTaWduYWxzPENsZWFuPFQ+PiBleHRlbmRzIFJlYWRvbmx5QXJyYXk8aW5mZXIgVT4gPyBVIDogVW53cmFwQWxsU2lnbmFsczxDbGVhbjxUPj4gZXh0ZW5kcyAoaW5mZXIgVSlbXSA/IFUgOiBuZXZlcjtcblxuLy8gS2nhu4NtIHRyYSBhcnJheS1saWtlIHNhdSBraGkgdW53cmFwIHRvw6BuIGLhu5kgU2lnbmFsIHbDoCBsw6BtIHPhuqFjaCBvcHRpb25hbFxudHlwZSBJc0FycmF5TGlrZTxUPiA9IFVud3JhcEFsbFNpZ25hbHM8Q2xlYW48VD4+IGV4dGVuZHMgcmVhZG9ubHkgdW5rbm93bltdID8gdHJ1ZSA6IFVud3JhcEFsbFNpZ25hbHM8Q2xlYW48VD4+IGV4dGVuZHMgdW5rbm93bltdID8gdHJ1ZSA6IGZhbHNlO1xuXG4vLyBLaeG7g20gdHJhIG9iamVjdCBraMO0bmcgcGjhuqNpIGFycmF5IHNhdSBraGkgdW53cmFwIHRvw6BuIGLhu5kgU2lnbmFsIHbDoCBsw6BtIHPhuqFjaCBvcHRpb25hbFxudHlwZSBJc05vbkFycmF5T2JqZWN0PFQ+ID0gVW53cmFwQWxsU2lnbmFsczxDbGVhbjxUPj4gZXh0ZW5kcyBvYmplY3QgPyAoVW53cmFwQWxsU2lnbmFsczxDbGVhbjxUPj4gZXh0ZW5kcyByZWFkb25seSB1bmtub3duW10gPyBmYWxzZSA6IFVud3JhcEFsbFNpZ25hbHM8Q2xlYW48VD4+IGV4dGVuZHMgdW5rbm93bltdID8gZmFsc2UgOiB0cnVlKSA6IGZhbHNlO1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSBET00vRXZ0IGd1YXJkID09PT09PT09PT09PT09PT09PT09PT0gKiovXG5cbnR5cGUgSXNET01UeXBlPFQ+ID0gVW53cmFwQWxsU2lnbmFsczxUPiBleHRlbmRzIEV2ZW50IHwgTm9kZSB8IERvY3VtZW50IHwgRWxlbWVudCB8IFdpbmRvdyB8IENTU1N0eWxlRGVjbGFyYXRpb24gfCBDU1NSdWxlIHwgQ1NTU3R5bGVTaGVldCA/IHRydWUgOiBmYWxzZTtcblxuLyoqID09PT09PT09PT09PT09PT09PT09PT0gRmluYWxpemUgKGdp4buvIFNpZ25hbCBu4bq/dSBj4bqnbikgPT09PT09PT09PT09PT09PT09PT09PSAqKi9cblxudHlwZSBGaW5hbGl6ZTxULCBSIGV4dGVuZHMgYm9vbGVhbj4gPSBSIGV4dGVuZHMgdHJ1ZSA/IFQgOiBVbndyYXBBbGxTaWduYWxzPFQ+O1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSBEZXB0aCBsaW1pdGVyIChoeWJyaWQsIG3hurdjIMSR4buLbmggNikgPT09PT09PT09PT09PT09PT09PT09PSAqKi9cblxudHlwZSBEZWM8TiBleHRlbmRzIG51bWJlcj4gPSBOIGV4dGVuZHMgNiA/IDUgOiBOIGV4dGVuZHMgNSA/IDQgOiBOIGV4dGVuZHMgNCA/IDMgOiBOIGV4dGVuZHMgMyA/IDIgOiBOIGV4dGVuZHMgMiA/IDEgOiBOIGV4dGVuZHMgMSA/IDAgOiAwO1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSBQYXRoIGJ1aWxkZXJzIChEZXB0aC1saW1pdGVkKSA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG4vLyBQYXRoIGNobyBhcnJheSDhu58gcm9vdC9maWVsZFxudHlwZSBQYXRoRm9yQXJyYXk8VCwgRGVwdGggZXh0ZW5kcyBudW1iZXI+ID0gW0RlcHRoXSBleHRlbmRzIFswXSA/IG5ldmVyIDogYFske251bWJlcn1dYCB8IChQYXRoT2Y8QXJyYXlFbGVtZW50UmF3PFQ+LCBEZWM8RGVwdGg+PiBleHRlbmRzIG5ldmVyID8gbmV2ZXIgOiBgWyR7bnVtYmVyfV0uJHtQYXRoT2Y8QXJyYXlFbGVtZW50UmF3PFQ+LCBEZWM8RGVwdGg+Pn1gKTtcblxuLy8gUGF0aCBjaG8gdOG7q25nIHByb3AgSyB0w7l5IGtp4buDdSBnacOhIHRy4buLXG50eXBlIFBhdGhGb3JQcm9wPFRQcm9wLCBLIGV4dGVuZHMgc3RyaW5nLCBEZXB0aCBleHRlbmRzIG51bWJlcj4gPSBbRGVwdGhdIGV4dGVuZHMgWzBdXG4gID8gS1xuICA6IElzQXJyYXlMaWtlPFRQcm9wPiBleHRlbmRzIHRydWVcbiAgICA/IGAke0t9YCB8IGAke0t9WyR7bnVtYmVyfV1gIHwgKFBhdGhPZjxBcnJheUVsZW1lbnRSYXc8VFByb3A+LCBEZWM8RGVwdGg+PiBleHRlbmRzIG5ldmVyID8gbmV2ZXIgOiBgJHtLfVske251bWJlcn1dLiR7UGF0aE9mPEFycmF5RWxlbWVudFJhdzxUUHJvcD4sIERlYzxEZXB0aD4+fWApXG4gICAgOiBJc05vbkFycmF5T2JqZWN0PFRQcm9wPiBleHRlbmRzIHRydWVcbiAgICAgID8gYCR7S31gIHwgKFBhdGhPZjxDbGVhbjxUUHJvcD4sIERlYzxEZXB0aD4+IGV4dGVuZHMgbmV2ZXIgPyBuZXZlciA6IGAke0t9LiR7UGF0aE9mPENsZWFuPFRQcm9wPiwgRGVjPERlcHRoPj59YClcbiAgICAgIDogYCR7S31gO1xuXG4vLyBQYXRoIGNobyBvYmplY3QgKG1hcCB04burbmcga2V5KVxudHlwZSBQYXRoRm9yT2JqZWN0PFQsIERlcHRoIGV4dGVuZHMgbnVtYmVyPiA9IHtcbiAgW0sgaW4gU3RyS2V5czxUPl06IFBhdGhGb3JQcm9wPFRbS10sIEssIERlcHRoPjtcbn1bU3RyS2V5czxUPl07XG5cbi8qKiA9PT09PT09PT09PT09PT09PT09PT09IFB1YmxpYzogUGF0aE9mIChoeWJyaWQsIERlcHRoIG3hurdjIMSR4buLbmggNikgPT09PT09PT09PT09PT09PT09PT09PSAqKi9cblxuZXhwb3J0IHR5cGUgUGF0aE9mPFRSYXcsIERlcHRoIGV4dGVuZHMgbnVtYmVyID0gNj4gPVxuICBJc0VtcHR5T2JqZWN0PENsZWFuPFRSYXc+PiBleHRlbmRzIHRydWVcbiAgICA/IGFueVxuICAgIDogSXNET01UeXBlPENsZWFuPFRSYXc+PiBleHRlbmRzIHRydWVcbiAgICAgID8gYW55XG4gICAgICA6IFtEZXB0aF0gZXh0ZW5kcyBbMF1cbiAgICAgICAgPyBuZXZlclxuICAgICAgICA6IFVud3JhcEFsbFNpZ25hbHM8Q2xlYW48VFJhdz4+IGV4dGVuZHMgcmVhZG9ubHkgdW5rbm93bltdIHwgdW5rbm93bltdXG4gICAgICAgICAgPyBQYXRoRm9yQXJyYXk8Q2xlYW48VFJhdz4sIERlcHRoPlxuICAgICAgICAgIDogVW53cmFwQWxsU2lnbmFsczxDbGVhbjxUUmF3Pj4gZXh0ZW5kcyBvYmplY3RcbiAgICAgICAgICAgID8gUGF0aEZvck9iamVjdDxVbndyYXBBbGxTaWduYWxzPENsZWFuPFRSYXc+PiwgRGVwdGg+XG4gICAgICAgICAgICA6IHN0cmluZztcblxuLyoqID09PT09PT09PT09PT09PT09PT09PT0gUmVzb2x2ZSBnacOhIHRy4buLIHRoZW8gcGF0aCA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG4vLyBHZXRJbnRlcm5hbDogxJFpIHRoZW8gc3RyaW5nIHBhdGggxJHhu4MgcmVzb2x2ZSB0eXBlIGdpw6EgdHLhu4sgY3Xhu5FpIGPDuW5nXG4vLyBT4butIGThu6VuZyBkaXN0cmlidXRpdmUgY29uZGl0aW9uYWwgdHlwZSAoVFJhdyBleHRlbmRzIG51bGwgfCB1bmRlZmluZWQpIMSR4buDIHThu7EgxJHhu5luZyBoYW5kbGUgdW5pb24gY8OzIHVuZGVmaW5lZC9udWxsICh2w60gZOG7pSBvcHRpb25hbCBwcm9wcykuXG50eXBlIEdldEludGVybmFsPFRSYXcsIFAgZXh0ZW5kcyBzdHJpbmcsIFIgZXh0ZW5kcyBib29sZWFuPiA9IFRSYXcgZXh0ZW5kcyBudWxsIHwgdW5kZWZpbmVkXG4gID8gVFJhd1xuICA6IC8vIFt4XS5SZXN0ICjEkcOhbmggaW5kZXggdsOgbyByb290IGFycmF5KVxuICAgIFAgZXh0ZW5kcyBgWyR7aW5mZXIgSX1dLiR7aW5mZXIgUmVzdH1gXG4gICAgPyBJIGV4dGVuZHMgYCR7bnVtYmVyfWBcbiAgICAgID8gR2V0SW50ZXJuYWw8QXJyYXlFbGVtZW50UmF3PFRSYXc+LCBSZXN0LCBSPlxuICAgICAgOiBhbnlcbiAgICA6IC8vIFt4XSAoY2jhu4kgaW5kZXgpXG4gICAgICBQIGV4dGVuZHMgYFske2luZmVyIEl9XWBcbiAgICAgID8gSSBleHRlbmRzIGAke251bWJlcn1gXG4gICAgICAgID8gRmluYWxpemU8QXJyYXlFbGVtZW50UmF3PFRSYXc+LCBSPlxuICAgICAgICA6IGFueVxuICAgICAgOiAvLyBLW3hdLlJlc3QgKMSRw6FuaCBpbmRleCB2w6BvIGZpZWxkIG3huqNuZylcbiAgICAgICAgUCBleHRlbmRzIGAke2luZmVyIEt9WyR7aW5mZXIgSX1dLiR7aW5mZXIgUmVzdH1gXG4gICAgICAgID8gSyBleHRlbmRzIFN0cktleXM8Q2xlYW48VW53cmFwQWxsU2lnbmFsczxUUmF3Pj4+XG4gICAgICAgICAgPyBJIGV4dGVuZHMgYCR7bnVtYmVyfWBcbiAgICAgICAgICAgID8gR2V0SW50ZXJuYWw8QXJyYXlFbGVtZW50UmF3PENsZWFuPFVud3JhcEFsbFNpZ25hbHM8VFJhdz4+W0tdPiwgUmVzdCwgUj5cbiAgICAgICAgICAgIDogYW55XG4gICAgICAgICAgOiBhbnlcbiAgICAgICAgOiAvLyBLLlJlc3QgKMSRaSBzw6J1IHbDoG8gb2JqZWN0KVxuICAgICAgICAgIFAgZXh0ZW5kcyBgJHtpbmZlciBLfS4ke2luZmVyIFJlc3R9YFxuICAgICAgICAgID8gSyBleHRlbmRzIFN0cktleXM8Q2xlYW48VW53cmFwQWxsU2lnbmFsczxUUmF3Pj4+XG4gICAgICAgICAgICA/IElzQXJyYXlMaWtlPENsZWFuPFVud3JhcEFsbFNpZ25hbHM8VFJhdz4+W0tdPiBleHRlbmRzIHRydWVcbiAgICAgICAgICAgICAgPyBhbnkgLy8ga2jDtG5nIGjhu5cgdHLhu6MgZG90IHbDoG8gcGjhuqduIHThu60gbeG6o25nIGtoaSB0aGnhur91IGluZGV4XG4gICAgICAgICAgICAgIDogR2V0SW50ZXJuYWw8Q2xlYW48VW53cmFwQWxsU2lnbmFsczxUUmF3Pj5bS10sIFJlc3QsIFI+XG4gICAgICAgICAgICA6IGFueVxuICAgICAgICAgIDogLy8gS1s8bnVtYmVyPl0gKGvhur90IHRow7pjIOG7nyBpbmRleClcbiAgICAgICAgICAgIFAgZXh0ZW5kcyBgJHtpbmZlciBLfVske2luZmVyIEl9XWBcbiAgICAgICAgICAgID8gSyBleHRlbmRzIFN0cktleXM8Q2xlYW48VW53cmFwQWxsU2lnbmFsczxUUmF3Pj4+XG4gICAgICAgICAgICAgID8gSSBleHRlbmRzIGAke251bWJlcn1gXG4gICAgICAgICAgICAgICAgPyBGaW5hbGl6ZTxBcnJheUVsZW1lbnRSYXc8Q2xlYW48VW53cmFwQWxsU2lnbmFsczxUUmF3Pj5bS10+LCBSPlxuICAgICAgICAgICAgICAgIDogYW55XG4gICAgICAgICAgICAgIDogYW55XG4gICAgICAgICAgICA6IC8vIEsgKGvhur90IHRow7pjIOG7nyBrZXkpXG4gICAgICAgICAgICAgIFAgZXh0ZW5kcyBgJHtpbmZlciBLfWBcbiAgICAgICAgICAgICAgPyBLIGV4dGVuZHMgU3RyS2V5czxDbGVhbjxVbndyYXBBbGxTaWduYWxzPFRSYXc+Pj5cbiAgICAgICAgICAgICAgICA/IEZpbmFsaXplPENsZWFuPFVud3JhcEFsbFNpZ25hbHM8VFJhdz4+W0tdLCBSPlxuICAgICAgICAgICAgICAgIDogYW55XG4gICAgICAgICAgICAgIDogYW55O1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSBQdWJsaWM6IEdldFZhbHVlQXRQYXRoICYgR2V0UmV0dXJuVHlwZSA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG4vLyBSZXNvbHZlIGtp4buDdSBnacOhIHRy4buLIHThuqFpIHBhdGggUC4gTuG6v3UgUj10cnVlLCBnaeG7ryBuZ3V5w6puIFNpZ25hbDsgbeG6t2MgxJHhu4tuaCBSPWZhbHNlIHPhur0gdW53cmFwIHRvw6BuIGLhu5kgU2lnbmFsLlxuZXhwb3J0IHR5cGUgR2V0VmFsdWVBdFBhdGg8VFJhdywgUCBleHRlbmRzIFBhdGhPZjxUUmF3PiwgUiBleHRlbmRzIGJvb2xlYW4gPSBmYWxzZT4gPSBUUmF3IGV4dGVuZHMgbnVsbCB8IHVuZGVmaW5lZCA/IFRSYXcgOiBHZXRJbnRlcm5hbDxUUmF3LCBQLCBSPjtcblxuLy8gS2nhu4N1IHRy4bqjIHbhu4EgY+G7p2EgZ2V0KCkgZOG7sWEgdHLDqm4gZGVmYXVsdFZhbHVlIERcbmV4cG9ydCB0eXBlIEdldFJldHVyblR5cGU8TywgUCBleHRlbmRzIFBhdGhPZjxPPiwgS1MgZXh0ZW5kcyBib29sZWFuLCBEIGV4dGVuZHMgR2V0VmFsdWVBdFBhdGg8TywgUCwgS1M+IHwgdW5kZWZpbmVkPiA9IEQgZXh0ZW5kcyB1bmRlZmluZWQgPyBHZXRWYWx1ZUF0UGF0aDxPLCBQLCBLUz4gOiBFeGNsdWRlPEdldFZhbHVlQXRQYXRoPE8sIFAsIEtTPiwgbnVsbCB8IHVuZGVmaW5lZD47XG5cbi8vIEtp4buDbSB0cmEgY8OhYyBraeG7g3UgZOG7ryBsaeG7h3UgxJHhurdjIGJp4buHdCDEkeG7gyBjaOG7iSB3cmFwIHNpZ25hbCAxIGPhuqVwXG50eXBlIElzU3BlY2lmaWNUeXBlPFQ+ID0gW1RdIGV4dGVuZHMgW1xuICB8IEV2ZW50XG4gIHwgTm9kZVxuICB8IERvY3VtZW50XG4gIHwgRWxlbWVudFxuICB8IFdpbmRvd1xuICB8IENTU1N0eWxlRGVjbGFyYXRpb25cbiAgfCBDU1NSdWxlXG4gIHwgQ1NTU3R5bGVTaGVldFxuICB8IEh0dHBQYXJhbXNcbiAgfCBEYXlqc1xuICB8IERhdGVcbiAgfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpXG4gIHwgUHJvbWlzZTxhbnk+XG4gIHwgTWFwPGFueSwgYW55PlxuICB8IFNldDxhbnk+XG4gIHwgV2Vha01hcDxhbnksIGFueT5cbiAgfCBXZWFrU2V0PGFueT5cbiAgfCBSZWdFeHBcbiAgfCBGaWxlXG4gIHwgQmxvYlxuICB8IEZpbGVMaXN0XG4gIHwgRm9ybURhdGEsXG5dXG4gID8gdHJ1ZVxuICA6IGZhbHNlO1xuXG4vLyBIZWxwZXIgdHlwZTogeOG7rSBsw70gbG9naWMgY2jDrW5oIG3DoCBLSMOUTkcgZGlzdHJpYnV0ZSAobm9uLWRpc3RyaWJ1dGl2ZSlcbnR5cGUgU2lnbmFsT2ZOb25OdWxsYWJsZTxULCBQIGV4dGVuZHMgYm9vbGVhbiwgRiBleHRlbmRzIGJvb2xlYW4+ID1cbiAgLy8gTuG6v3UgVCDEkcOjIGzDoCBXcml0YWJsZVNpZ25hbCwgZ2nhu68gbmd1ecOqbiAodHLDoW5oIHdyYXAgMiBs4bqnbilcbiAgW1RdIGV4dGVuZHMgW1dyaXRhYmxlU2lnbmFsPGFueT5dXG4gICAgPyBUXG4gICAgOiBbSXNTcGVjaWZpY1R5cGU8VD5dIGV4dGVuZHMgW3RydWVdXG4gICAgICA/IEYgZXh0ZW5kcyB0cnVlXG4gICAgICAgID8gV3JpdGFibGVTaWduYWw8VD5cbiAgICAgICAgOiBUXG4gICAgICA6IFtUXSBleHRlbmRzIFtSZWFkb25seUFycmF5PGFueT5dXG4gICAgICAgID8gRiBleHRlbmRzIHRydWVcbiAgICAgICAgICA/IFdyaXRhYmxlU2lnbmFsPEFycmF5PFNpZ25hbE9mSW1wbDxBcnJheUVsZW1lbnRSYXc8VD4sIFAsIHRydWU+Pj5cbiAgICAgICAgICA6IEFycmF5PFNpZ25hbE9mSW1wbDxBcnJheUVsZW1lbnRSYXc8VD4sIFAsIHRydWU+PlxuICAgICAgICA6IFtUXSBleHRlbmRzIFtvYmplY3RdXG4gICAgICAgICAgPyBGIGV4dGVuZHMgdHJ1ZVxuICAgICAgICAgICAgPyBXcml0YWJsZVNpZ25hbDx7IFtLIGluIGtleW9mIFRdOiBTaWduYWxPZkltcGw8VFtLXSwgUCwgdHJ1ZT4gfT5cbiAgICAgICAgICAgIDogeyBbSyBpbiBrZXlvZiBUXTogU2lnbmFsT2ZJbXBsPFRbS10sIFAsIHRydWU+IH1cbiAgICAgICAgICA6IFtUXSBleHRlbmRzIFtzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuXVxuICAgICAgICAgICAgPyBQIGV4dGVuZHMgdHJ1ZVxuICAgICAgICAgICAgICA/IFdyaXRhYmxlU2lnbmFsPFQ+XG4gICAgICAgICAgICAgIDogVFxuICAgICAgICAgICAgOiBXcml0YWJsZVNpZ25hbDxUPjtcblxuLy8gSW1wbGVtZW50YXRpb24gaGVscGVyOiB0w6FjaCBudWxsL3VuZGVmaW5lZCBtw6AgS0jDlE5HIGTDuW5nIGRpc3RyaWJ1dGl2ZSBjb25kaXRpb25hbFxudHlwZSBTaWduYWxPZkltcGw8VCwgUCBleHRlbmRzIGJvb2xlYW4sIEYgZXh0ZW5kcyBib29sZWFuPiA9IEV4dHJhY3Q8VCwgbnVsbCB8IHVuZGVmaW5lZD4gZXh0ZW5kcyBuZXZlciA/IFNpZ25hbE9mTm9uTnVsbGFibGU8VCwgUCwgRj4gOiBTaWduYWxPZk5vbk51bGxhYmxlPEV4Y2x1ZGU8VCwgbnVsbCB8IHVuZGVmaW5lZD4sIFAsIEY+IHwgRXh0cmFjdDxULCBudWxsIHwgdW5kZWZpbmVkPjtcblxuLy8gxJDGsGEga2nhu4N1IGThu68gbGnhu4d1IGLhuqV0IGvhu7MgduG7gSBk4bqhbmcgc2lnbmFsLCBO4bq/dSBQID0gdHJ1ZSDEkcawYSBj4bqjIGThu68gbGnhu4d1IHByZW1ldGl2ZV90eXBlIHbhu4EgZOG6oW5nIHNpZ25hbFxuZXhwb3J0IHR5cGUgU2lnbmFsT2Y8VCwgUCBleHRlbmRzIGJvb2xlYW4gPSB0cnVlLCBGIGV4dGVuZHMgYm9vbGVhbiA9IGZhbHNlPiA9IFNpZ25hbE9mSW1wbDxULCBQLCBGPjtcblxuZXhwb3J0IHR5cGUgTm9uU2lnbmFsT2Y8VD4gPSBUIGV4dGVuZHMgbnVsbCB8IHVuZGVmaW5lZCA/IFQgOiBDbGVhbjxUPiBleHRlbmRzIEFycmF5PGluZmVyIFU+ID8gQXJyYXk8Tm9uU2lnbmFsT2Y8Q2xlYW48VT4+PiA6IENsZWFuPFQ+IGV4dGVuZHMgb2JqZWN0ID8geyBbSyBpbiBrZXlvZiBDbGVhbjxUPl06IE5vblNpZ25hbE9mPENsZWFuPENsZWFuPFQ+W0tdPj4gfSA6IENsZWFuPFQ+O1xuXG4vKiogPT09PT09PT09PT09PT09PT09PT09PSAoVHXhu7MgY2jhu41uKSBWw60gZOG7pSBuaGFuaCA9PT09PT09PT09PT09PT09PT09PT09ICoqL1xuXG5leHBvcnQgdHlwZSBUX1BhZ2VCb3RDb25maWcgPSB7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIG1vZGU/OiAnQVVUTycgfCAnUkVWSUVXJztcbn07XG5cbmV4cG9ydCB0eXBlIFRfU2lnbmFsX1BhZ2VCb3RDb25maWcgPSBTaWduYWxPZjxUX1BhZ2VCb3RDb25maWc+O1xuZXhwb3J0IGludGVyZmFjZSBJQ29tbWVudCB7XG4gIGNvbW1lbnRzPzogV3JpdGFibGVTaWduYWw8SVN1YkNvbW1lbnQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElTdWJDb21tZW50IHtcbiAgc3RvcmU/OiBXcml0YWJsZVNpZ25hbDxBcnJheTxXcml0YWJsZVNpZ25hbDxJQ29tbWVudD4+PjtcbiAgZGF0YT86IFdyaXRhYmxlU2lnbmFsPEFycmF5PFdyaXRhYmxlU2lnbmFsPElDb21tZW50Pj4+O1xuICBzcGVjaWZpY190ZW1wX2RhdGE/OiBXcml0YWJsZVNpZ25hbDxBcnJheTxXcml0YWJsZVNpZ25hbDxJQ29tbWVudD4+PjtcbiAgcGFnaW5nPzogV3JpdGFibGVTaWduYWw8e1xuICAgIGN1cnNvcnM/OiBXcml0YWJsZVNpZ25hbDx7XG4gICAgICBhZnRlcj86IFdyaXRhYmxlU2lnbmFsPHN0cmluZz47XG4gICAgICBiZWZvcmU/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgIH0+O1xuICAgIGJlZm9yZT86IFdyaXRhYmxlU2lnbmFsPHN0cmluZz47XG4gICAgYWZ0ZXI/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgIG5leHQ/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgIHByZXZpb3VzPzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgfT47XG4gIHN1bW1hcnk/OiBXcml0YWJsZVNpZ25hbDx7XG4gICAgY2FuX2NvbW1lbnQ/OiBXcml0YWJsZVNpZ25hbDxib29sZWFuPjtcbiAgICBjYW5vcmRlcl9jb21tZW50PzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgICB0b3RhbF9jb3VudD86IFdyaXRhYmxlU2lnbmFsPG51bWJlcj47XG4gIH0+O1xufVxuXG50eXBlIFZfY29tbWVudHNfRiA9IEdldFZhbHVlQXRQYXRoPElDb21tZW50LCAnY29tbWVudHMnLCBmYWxzZT47IC8vIElTdWJDb21tZW50XG50eXBlIFZfY29tbWVudHNfVCA9IEdldFZhbHVlQXRQYXRoPElDb21tZW50LCAnY29tbWVudHMnLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8SVN1YkNvbW1lbnQ+XG5cbnR5cGUgVl9jb21tZW50c19zdG9yZV9GID0gR2V0VmFsdWVBdFBhdGg8SUNvbW1lbnQsICdjb21tZW50cy5kYXRhJywgZmFsc2U+OyAvLyBBcnJheTxXcml0YWJsZVNpZ25hbDxJQ29tbWVudD4+XG50eXBlIFZfY29tbWVudHNfc3RvcmVfVCA9IEdldFZhbHVlQXRQYXRoPElDb21tZW50LCAnY29tbWVudHMuZGF0YScsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDxBcnJheTxXcml0YWJsZVNpZ25hbDxJQ29tbWVudD4+PlxuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3Qge1xuICBzcGVjaWZpY19xdWVyeT86IFdyaXRhYmxlU2lnbmFsPElBc3NpZ25tZW50SXRlbVF1ZXJ5PjtcblxuICBkYXRhOiBXcml0YWJsZVNpZ25hbDxBcnJheTxXcml0YWJsZVNpZ25hbDxJQXNzaWdubWVudEl0ZW0+Pj47XG5cbiAgaW5kZXg6IG51bWJlcjtcbiAgaW5mbzoge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBhZ2U6IG51bWJlcjtcbiAgICBhbmltYWw6IGJvb2xlYW47XG4gICAgY2F0ZTogJ2FsbycgfCAnYWxvMic7XG4gIH07XG4gIGNpdHk6IFdyaXRhYmxlU2lnbmFsPHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgY291bnRyeTogc3RyaW5nO1xuICB9PjtcbiAgYWRkcmVzczogV3JpdGFibGVTaWduYWw8e1xuICAgIGlwOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgIHBvcnQ6IFdyaXRhYmxlU2lnbmFsPG51bWJlcj47XG4gIH0+O1xuICBvd25lcjogQXJyYXk8c3RyaW5nPjtcbiAgc3VwcG9ydDogQXJyYXk8V3JpdGFibGVTaWduYWw8c3RyaW5nPj47XG4gIGhvc3Q6IEFycmF5PHtcbiAgICBpcDogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgICBwb3J0OiBudW1iZXI7XG4gIH0+O1xuXG4gIGNvdW50cnk6IFdyaXRhYmxlU2lnbmFsPFxuICAgIEFycmF5PFxuICAgICAgV3JpdGFibGVTaWduYWw8e1xuICAgICAgICBuYW1lOiBXcml0YWJsZVNpZ25hbDx7XG4gICAgICAgICAgdmk6IHN0cmluZztcbiAgICAgICAgICBlbjogc3RyaW5nO1xuICAgICAgICB9PjtcbiAgICAgICAgY29kZTogV3JpdGFibGVTaWduYWw8e1xuICAgICAgICAgIHZpOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgICAgICAgIGVuOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgICAgICB9PjtcbiAgICAgICAgZmxhZzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgICAgICAgcGhvbmVfY29kZTogc3RyaW5nO1xuICAgICAgICBjdXJyZW5jeToge1xuICAgICAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgICAgICBjb2RlOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICAgICAgICAgIHN5bWJvbDogV3JpdGFibGVTaWduYWw8e1xuICAgICAgICAgICAgdmk6IHN0cmluZztcbiAgICAgICAgICAgIGVuOiBzdHJpbmc7XG4gICAgICAgICAgICBjbjogV3JpdGFibGVTaWduYWw8QXJyYXk8c3RyaW5nPj47XG4gICAgICAgICAgICBqcDogV3JpdGFibGVTaWduYWw8XG4gICAgICAgICAgICAgIEFycmF5PFxuICAgICAgICAgICAgICAgIFdyaXRhYmxlU2lnbmFsPHtcbiAgICAgICAgICAgICAgICAgIHZpOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgICBlbjogc3RyaW5nO1xuICAgICAgICAgICAgICAgIH0+XG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgID47XG4gICAgICAgICAgfT47XG4gICAgICAgIH07XG4gICAgICB9PlxuICAgID5cbiAgPjtcbn1cblxudHlwZSBUZXN0MSA9IEdldFJldHVyblR5cGU8SUFzc2lnbm1lbnRJdGVtLCAnY2hhdGJvdF9jb25maWcubW9kZScsIHRydWUsICdSRVZJRVcnPjtcbnR5cGUgVGVzdDIgPSBTaWduYWxPZjxUZXN0PjtcbnR5cGUgVGVzdDMgPSBHZXRSZXR1cm5UeXBlPFRlc3QyLCAnaW5mby5jYXRlJywgdHJ1ZSwgV3JpdGFibGVTaWduYWw8J2Fsbyc+PjtcblxuaW50ZXJmYWNlIElBc3NpZ25tZW50SXRlbSB7XG4gIGlkOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBuYW1lOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBkZXNjcmlwdGlvbjogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgY3JlYXRlZF9hdDogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgdXBkYXRlZF9hdDogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgYXNzaWduZWVzPzogV3JpdGFibGVTaWduYWw8QXJyYXk8V3JpdGFibGVTaWduYWw8SUFzc2lnbmVlPj4+O1xuICBjaGF0Ym90X2NvbmZpZz86IFdyaXRhYmxlU2lnbmFsPFRfUGFnZUJvdENvbmZpZz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUFzc2lnbmVlIHtcbiAgYXNzaWduZWVfaWQ/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBjb252ZXJzYXRpb25faWQ/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBjcmVhdGVkX3RpbWU/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBjcmVhdGVkX3VzZXI/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBpZD86IFdyaXRhYmxlU2lnbmFsPHN0cmluZz47XG4gIG5vdGU/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICBzdGF0dXM/OiBXcml0YWJsZVNpZ25hbDxudW1iZXI+O1xuICBhc3NpZ25fdGFnX2FjdGl2aXR5X3N0YXR1cz86IFdyaXRhYmxlU2lnbmFsPG51bWJlcj47XG4gIGNvbW1lbnRfaWQ/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xuICByYXRpbmdfaWQ/OiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElBc3NpZ25tZW50SXRlbVF1ZXJ5IHtcbiAgcGVyX3BhZ2U6IFdyaXRhYmxlU2lnbmFsPG51bWJlcj47XG4gIGFmdGVyX3Rva2VuPzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgYmVmb3JlX3Rva2VuPzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgc2VhcmNoPzogV3JpdGFibGVTaWduYWw8c3RyaW5nPjtcbiAgc2VhcmNoX2luZGV4PzogV3JpdGFibGVTaWduYWw8bnVtYmVyPjtcbn1cblxudHlwZSBWX2luZGV4X0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5kZXgnLCBmYWxzZT47IC8vIG51bWJlclxudHlwZSBWX2luZGV4X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5kZXgnLCB0cnVlPjsgLy8gbnVtYmVyXG5cbnR5cGUgVl9pbmZvX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5mbycsIGZhbHNlPjtcbnR5cGUgVl9pbmZvX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5mbycsIHRydWU+O1xudHlwZSBWX2luZm9fbmFtZV9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2luZm8ubmFtZScsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfaW5mb19uYW1lX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5mby5uYW1lJywgdHJ1ZT47IC8vIHN0cmluZ1xudHlwZSBWX2luZm9fYWdlX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5mby5hZ2UnLCBmYWxzZT47IC8vIG51bWJlclxudHlwZSBWX2luZm9fYWdlX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnaW5mby5hZ2UnLCB0cnVlPjsgLy8gbnVtYmVyXG5cbi8vIENpdHkgKHNpZ25hbC13cmFwcGVkIG9iamVjdCB3aXRoIHBsYWluIGZpZWxkcylcbnR5cGUgVl9jaXR5X0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY2l0eScsIGZhbHNlPjtcbnR5cGUgVl9jaXR5X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY2l0eScsIHRydWU+O1xudHlwZSBWX2NpdHlfbmFtZV9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NpdHkubmFtZScsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfY2l0eV9uYW1lX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY2l0eS5uYW1lJywgdHJ1ZT47IC8vIHN0cmluZ1xudHlwZSBWX2NpdHlfY291bnRyeV9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NpdHkuY291bnRyeScsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfY2l0eV9jb3VudHJ5X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY2l0eS5jb3VudHJ5JywgdHJ1ZT47IC8vIHN0cmluZ1xuXG4vLyBBZGRyZXNzIChzaWduYWwtd3JhcHBlZCBvYmplY3Qgd2l0aCBzaWduYWwgbGVhdmVzKVxudHlwZSBWX2FkZHJlc3NfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdhZGRyZXNzJywgZmFsc2U+O1xudHlwZSBWX2FkZHJlc3NfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdhZGRyZXNzJywgdHJ1ZT47XG50eXBlIFZfYWRkcmVzc19pcF9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2FkZHJlc3MuaXAnLCBmYWxzZT47IC8vIHN0cmluZ1xudHlwZSBWX2FkZHJlc3NfaXBfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdhZGRyZXNzLmlwJywgdHJ1ZT47IC8vIFdyaXRhYmxlU2lnbmFsPHN0cmluZz5cbnR5cGUgVl9hZGRyZXNzX3BvcnRfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdhZGRyZXNzLnBvcnQnLCBmYWxzZT47IC8vIG51bWJlclxudHlwZSBWX2FkZHJlc3NfcG9ydF9UID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2FkZHJlc3MucG9ydCcsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDxudW1iZXI+XG5cbi8vIE93bmVyIChhcnJheSBvZiBwcmltaXRpdmVzKVxudHlwZSBWX293bmVyX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnb3duZXInLCBmYWxzZT47IC8vIHN0cmluZ1tdXG50eXBlIFZfb3duZXJfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdvd25lcicsIHRydWU+OyAvLyBzdHJpbmdbXVxudHlwZSBWX293bmVyX2lkeF9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ293bmVyWzBdJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9vd25lcl9pZHhfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdvd25lclswXScsIHRydWU+OyAvLyBzdHJpbmdcblxuLy8gU3VwcG9ydCAoYXJyYXkgb2Ygc2lnbmFscylcbnR5cGUgVl9zdXBwb3J0X0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnc3VwcG9ydCcsIGZhbHNlPjsgLy8gc3RyaW5nW11cbnR5cGUgVl9zdXBwb3J0X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnc3VwcG9ydCcsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDxzdHJpbmc+W11cbnR5cGUgVl9zdXBwb3J0X2lkeF9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ3N1cHBvcnRbMF0nLCBmYWxzZT47IC8vIHN0cmluZ1xudHlwZSBWX3N1cHBvcnRfaWR4X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnc3VwcG9ydFswXScsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDxzdHJpbmc+XG5cbi8vIEhvc3QgKGFycmF5IG9mIG9iamVjdHMgd2l0aCBtaXhlZCBsZWF2ZXMpXG50eXBlIFZfaG9zdF9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2hvc3QnLCBmYWxzZT47IC8vIHsgaXA6IHN0cmluZzsgcG9ydDogbnVtYmVyIH1bXVxudHlwZSBWX2hvc3RfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdob3N0JywgdHJ1ZT47IC8vIHsgaXA6IFdyaXRhYmxlU2lnbmFsPHN0cmluZz47IHBvcnQ6IG51bWJlciB9W11cbnR5cGUgVl9ob3N0X2lkeF9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2hvc3RbMF0nLCBmYWxzZT47XG50eXBlIFZfaG9zdF9pZHhfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdob3N0WzBdJywgdHJ1ZT47XG50eXBlIFZfaG9zdF9pcF9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2hvc3RbMF0uaXAnLCBmYWxzZT47IC8vIHN0cmluZ1xudHlwZSBWX2hvc3RfaXBfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdob3N0WzBdLmlwJywgdHJ1ZT47IC8vIFdyaXRhYmxlU2lnbmFsPHN0cmluZz5cbnR5cGUgVl9ob3N0X3BvcnRfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdob3N0WzBdLnBvcnQnLCBmYWxzZT47IC8vIG51bWJlclxudHlwZSBWX2hvc3RfcG9ydF9UID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2hvc3RbMF0ucG9ydCcsIHRydWU+OyAvLyBudW1iZXJcblxuLy8gY3VycmVuY3lcbnR5cGUgVl9jdXJyZW5jeV9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NvdW50cnlbMF0uY3VycmVuY3knLCBmYWxzZT47IC8vIHsgbmFtZTogc3RyaW5nOyBjb2RlOiBzdHJpbmc7IHN5bWJvbDogeyAuLi4gfSB9XG50eXBlIFZfY3VycmVuY3lfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5JywgdHJ1ZT47IC8vIHsgbmFtZTogc3RyaW5nOyBjb2RlOiBXcml0YWJsZVNpZ25hbDxzdHJpbmc+OyBzeW1ib2w6IFdyaXRhYmxlU2lnbmFsPHsgLi4uIH0+IH1cbnR5cGUgVl9jdXJyZW5jeV9uYW1lX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5uYW1lJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9jdXJyZW5jeV9uYW1lX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5uYW1lJywgdHJ1ZT47IC8vIHN0cmluZ1xudHlwZSBWX2N1cnJlbmN5X2NvZGVfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LmNvZGUnLCBmYWxzZT47IC8vIHN0cmluZ1xudHlwZSBWX2N1cnJlbmN5X2NvZGVfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LmNvZGUnLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8c3RyaW5nPlxuXG4vLyBjdXJyZW5jeS5zeW1ib2xcbnR5cGUgVl9zeW1ib2xfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbCcsIGZhbHNlPjsgLy8geyB2aTogc3RyaW5nOyBlbjogc3RyaW5nOyBjbjogc3RyaW5nW107IGpwOiB7IHZpOiBzdHJpbmc7IGVuOiBzdHJpbmcgfVtdIH1cbnR5cGUgVl9zeW1ib2xfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbCcsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDx7IHZpOiBzdHJpbmc7IGVuOiBzdHJpbmc7IGNuOiBXcml0YWJsZVNpZ25hbDxzdHJpbmdbXT47IGpwOiBXcml0YWJsZVNpZ25hbDx7IHZpOiBzdHJpbmc7IGVuOiBzdHJpbmcgfVtdPiB9PlxudHlwZSBWX3N5bWJvbF92aV9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NvdW50cnlbMF0uY3VycmVuY3kuc3ltYm9sLnZpJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9zeW1ib2xfdmlfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC52aScsIHRydWU+OyAvLyBzdHJpbmdcbnR5cGUgVl9zeW1ib2xfZW5fRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5lbicsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfc3ltYm9sX2VuX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuZW4nLCB0cnVlPjsgLy8gc3RyaW5nXG50eXBlIFZfc3ltYm9sX2NuX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuY24nLCBmYWxzZT47IC8vIHN0cmluZ1tdXG50eXBlIFZfc3ltYm9sX2NuX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuY24nLCB0cnVlPjsgLy8gV3JpdGFibGVTaWduYWw8c3RyaW5nW10+XG50eXBlIFZfc3ltYm9sX2NuX2lkeF9GID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NvdW50cnlbMF0uY3VycmVuY3kuc3ltYm9sLmNuWzBdJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9zeW1ib2xfY25faWR4X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuY25bMF0nLCB0cnVlPjsgLy8gc3RyaW5nXG50eXBlIFZfc3ltYm9sX2pwX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuanAnLCBmYWxzZT47IC8vIHsgdmk6IHN0cmluZzsgZW46IHN0cmluZyB9W11cbnR5cGUgVl9zeW1ib2xfanBfVCA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5qcCcsIHRydWU+OyAvLyBXcml0YWJsZVNpZ25hbDx7IHZpOiBzdHJpbmc7IGVuOiBzdHJpbmcgfVtdPlxudHlwZSBWX3N5bWJvbF9qcF9pZHhfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5qcFswXScsIGZhbHNlPjtcbnR5cGUgVl9zeW1ib2xfanBfaWR4X1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuanBbMF0nLCB0cnVlPjtcbnR5cGUgVl9zeW1ib2xfanBfdmlfRiA9IEdldFZhbHVlQXRQYXRoPFRlc3QsICdjb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5qcFswXS52aScsIGZhbHNlPjsgLy8gc3RyaW5nXG50eXBlIFZfc3ltYm9sX2pwX3ZpX1QgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuanBbMF0udmknLCB0cnVlPjsgLy8gc3RyaW5nXG50eXBlIFZfc3ltYm9sX2pwX2VuX0YgPSBHZXRWYWx1ZUF0UGF0aDxUZXN0LCAnY291bnRyeVswXS5jdXJyZW5jeS5zeW1ib2wuanBbMF0uZW4nLCBmYWxzZT47IC8vIHN0cmluZ1xudHlwZSBWX3N5bWJvbF9qcF9lbl9UID0gR2V0VmFsdWVBdFBhdGg8VGVzdCwgJ2NvdW50cnlbMF0uY3VycmVuY3kuc3ltYm9sLmpwWzBdLmVuJywgdHJ1ZT47IC8vIHN0cmluZ1xuXG50eXBlIFZfQXJyYXlfc3ltYm9sX2NuX0YgPSBHZXRWYWx1ZUF0UGF0aDxBcnJheTxUZXN0PiwgJ1swXS5jb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5jbicsIGZhbHNlPjsgLy8gc3RyaW5nW11cbnR5cGUgVl9BcnJheV9zeW1ib2xfY25fVCA9IEdldFZhbHVlQXRQYXRoPEFycmF5PFRlc3Q+LCAnWzBdLmNvdW50cnlbMF0uY3VycmVuY3kuc3ltYm9sLmNuJywgdHJ1ZT47IC8vIFdyaXRhYmxlU2lnbmFsPHN0cmluZ1tdPlxudHlwZSBWX0FycmF5X3N5bWJvbF9jbl9pZHhfRiA9IEdldFZhbHVlQXRQYXRoPEFycmF5PFRlc3Q+LCAnWzBdLmNvdW50cnlbMF0uY3VycmVuY3kuc3ltYm9sLmNuWzBdJywgZmFsc2U+OyAvLyBzdHJpbmdcbnR5cGUgVl9BcnJheV9zeW1ib2xfY25faWR4X1QgPSBHZXRWYWx1ZUF0UGF0aDxBcnJheTxUZXN0PiwgJ1swXS5jb3VudHJ5WzBdLmN1cnJlbmN5LnN5bWJvbC5jblswXScsIHRydWU+OyAvLyBzdHJpbmdcblxudHlwZSBwYXRoSUFzc2lnbm1lbnRJdGVtID0gUGF0aE9mPElBc3NpZ25tZW50SXRlbT47XG50eXBlIHBhdGhJQXNzaWdubWVudEl0ZW0xID0gUGF0aE9mPHVua25vd24+OyAvLyBzdHJpbmdcblxudHlwZSBWX2Fzc2lnbmVlc19GID0gR2V0VmFsdWVBdFBhdGg8SUFzc2lnbm1lbnRJdGVtLCAnYXNzaWduZWVzWzBdJywgZmFsc2U+OyAvLyBJQXNzaWduZWVcbiJdfQ==
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libs-ui/interfaces-types",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.357-0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"rxjs": "~7.8.0"
|
|
5
|
+
"rxjs": "~7.8.0",
|
|
6
|
+
"dayjs": "1.11.5",
|
|
7
|
+
"@angular/core": "~18.2.0",
|
|
8
|
+
"@angular/common": "~18.2.0"
|
|
6
9
|
},
|
|
7
10
|
"sideEffects": false,
|
|
8
11
|
"module": "fesm2022/libs-ui-interfaces-types.mjs",
|