@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
- This library was generated with [Nx](https://nx.dev).
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.356-8",
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",