@decaf-ts/for-angular 0.0.25 → 0.0.27

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.
Files changed (78) hide show
  1. package/fesm2022/decaf-ts-for-angular.mjs +1486 -1505
  2. package/fesm2022/decaf-ts-for-angular.mjs.map +1 -1
  3. package/index.d.ts +7482 -3
  4. package/package.json +15 -18
  5. package/components/component-renderer/component-renderer.component.d.ts +0 -278
  6. package/components/crud-field/crud-field.component.d.ts +0 -611
  7. package/components/crud-form/constants.d.ts +0 -5
  8. package/components/crud-form/crud-form.component.d.ts +0 -288
  9. package/components/crud-form/types.d.ts +0 -17
  10. package/components/empty-state/empty-state.component.d.ts +0 -300
  11. package/components/fieldset/fieldset.component.d.ts +0 -555
  12. package/components/filter/filter.component.d.ts +0 -514
  13. package/components/for-angular-components.module.d.ts +0 -20
  14. package/components/index.d.ts +0 -16
  15. package/components/layout/layout.component.d.ts +0 -110
  16. package/components/list/list.component.d.ts +0 -848
  17. package/components/list-item/list-item.component.d.ts +0 -390
  18. package/components/model-renderer/model-renderer.component.d.ts +0 -97
  19. package/components/pagination/constants.d.ts +0 -7
  20. package/components/pagination/pagination.component.d.ts +0 -264
  21. package/components/searchbar/searchbar.component.d.ts +0 -407
  22. package/components/stepped-form/stepped-form.component.d.ts +0 -255
  23. package/directives/collapsable.directive.d.ts +0 -9
  24. package/directives/index.d.ts +0 -1
  25. package/engine/DynamicModule.d.ts +0 -17
  26. package/engine/NgxBaseComponent.d.ts +0 -541
  27. package/engine/NgxCrudFormField.d.ts +0 -123
  28. package/engine/NgxFormService.d.ts +0 -601
  29. package/engine/NgxRenderingEngine.d.ts +0 -282
  30. package/engine/ValidatorFactory.d.ts +0 -15
  31. package/engine/constants.d.ts +0 -168
  32. package/engine/decorators.d.ts +0 -25
  33. package/engine/index.d.ts +0 -18
  34. package/engine/interfaces.d.ts +0 -271
  35. package/engine/types.d.ts +0 -200
  36. package/esm2022/components/component-renderer/component-renderer.component.mjs +0 -321
  37. package/esm2022/components/crud-field/crud-field.component.mjs +0 -518
  38. package/esm2022/components/crud-form/constants.mjs +0 -14
  39. package/esm2022/components/crud-form/crud-form.component.mjs +0 -259
  40. package/esm2022/components/crud-form/types.mjs +0 -2
  41. package/esm2022/components/empty-state/empty-state.component.mjs +0 -345
  42. package/esm2022/components/fieldset/fieldset.component.mjs +0 -677
  43. package/esm2022/components/filter/filter.component.mjs +0 -700
  44. package/esm2022/components/for-angular-components.module.mjs +0 -84
  45. package/esm2022/components/index.mjs +0 -20
  46. package/esm2022/components/layout/layout.component.mjs +0 -150
  47. package/esm2022/components/list/list.component.mjs +0 -1238
  48. package/esm2022/components/list-item/list-item.component.mjs +0 -405
  49. package/esm2022/components/model-renderer/model-renderer.component.mjs +0 -144
  50. package/esm2022/components/pagination/constants.mjs +0 -2
  51. package/esm2022/components/pagination/pagination.component.mjs +0 -321
  52. package/esm2022/components/searchbar/searchbar.component.mjs +0 -491
  53. package/esm2022/components/stepped-form/stepped-form.component.mjs +0 -306
  54. package/esm2022/decaf-ts-for-angular.mjs +0 -5
  55. package/esm2022/directives/collapsable.directive.mjs +0 -29
  56. package/esm2022/directives/index.mjs +0 -2
  57. package/esm2022/engine/DynamicModule.mjs +0 -18
  58. package/esm2022/engine/NgxBaseComponent.mjs +0 -541
  59. package/esm2022/engine/NgxCrudFormField.mjs +0 -137
  60. package/esm2022/engine/NgxFormService.mjs +0 -917
  61. package/esm2022/engine/NgxRenderingEngine.mjs +0 -376
  62. package/esm2022/engine/ValidatorFactory.mjs +0 -106
  63. package/esm2022/engine/constants.mjs +0 -170
  64. package/esm2022/engine/decorators.mjs +0 -38
  65. package/esm2022/engine/index.mjs +0 -19
  66. package/esm2022/engine/interfaces.mjs +0 -4
  67. package/esm2022/engine/types.mjs +0 -2
  68. package/esm2022/for-angular-common.module.mjs +0 -84
  69. package/esm2022/helpers/index.mjs +0 -13
  70. package/esm2022/helpers/utils.mjs +0 -436
  71. package/esm2022/i18n/Loader.mjs +0 -86
  72. package/esm2022/i18n/data/en.json +0 -85
  73. package/esm2022/public-apis.mjs +0 -15
  74. package/for-angular-common.module.d.ts +0 -50
  75. package/helpers/index.d.ts +0 -12
  76. package/helpers/utils.d.ts +0 -279
  77. package/i18n/Loader.d.ts +0 -43
  78. package/public-apis.d.ts +0 -14
@@ -1,405 +0,0 @@
1
- import { __decorate, __metadata } from "tslib";
2
- import { Component, EventEmitter, HostListener, inject, Input, Output, ViewChild } from '@angular/core';
3
- import { OperationKeys } from '@decaf-ts/db-decorators';
4
- import { NgxBaseComponent } from '../../engine/NgxBaseComponent';
5
- import { removeFocusTrap, stringToBoolean } from '../../helpers/utils';
6
- import { getWindowWidth, windowEventEmitter } from '../../helpers/utils';
7
- import { Dynamic, EventConstants } from '../../engine';
8
- import { NavController } from '@ionic/angular';
9
- import { IonButton, IonItem, IonLabel, IonList, IonContent, IonIcon, IonListHeader, IonPopover, IonItemSliding, IonItemOptions, IonItemOption } from '@ionic/angular/standalone';
10
- import * as AllIcons from 'ionicons/icons';
11
- import { addIcons } from 'ionicons';
12
- import { TranslatePipe } from '@ngx-translate/core';
13
- import * as i0 from "@angular/core";
14
- /**
15
- * @description A component for displaying a list item with various customization options.
16
- * @summary The ListItemComponent is an Angular component that extends NgxBaseComponent. It provides a flexible and customizable list item interface with support for icons, buttons, and various text elements. The component also handles actions and navigation based on user interactions.
17
- *
18
- * @class
19
- * @extends NgxBaseComponent
20
- *
21
- * @param {string} [lines='none'] - Determines the line style of the item. Can be 'inset', 'inseet', or 'none'.
22
- * @param {Record<string, any>} item - The data item to be displayed in the list item.
23
- * @param {string} icon - The name of the icon to be displayed.
24
- * @param {'start' | 'end'} [iconSlot='start'] - The position of the icon within the item.
25
- * @param {StringOrBoolean} [button=true] - Determines if the item should behave as a button.
26
- * @param {string} [title] - The main title of the list item.
27
- * @param {string} [description] - A description for the list item.
28
- * @param {string} [info] - Additional information for the list item.
29
- * @param {string} [subinfo] - Sub-information for the list item.
30
- *
31
- * @example
32
- * <ngx-decaf-list-item
33
- * [item]="dataItem"
34
- * icon="star"
35
- * title="Item Title"
36
- * description="Item Description"
37
- * (clickEvent)="handleItemClick($event)">
38
- * </ngx-decaf-list-item>
39
- *
40
- * @mermaid
41
- * sequenceDiagram
42
- * participant C as Component
43
- * participant V as View
44
- * participant U as User
45
- * C->>V: Initialize component
46
- * V->>U: Display list item
47
- * U->>V: Click on item or action
48
- * V->>C: Trigger handleAction()
49
- * C->>C: Process action
50
- * C->>V: Update view or navigate
51
- */
52
- let ListItemComponent = class ListItemComponent extends NgxBaseComponent {
53
- /**
54
- * @description Creates an instance of ListItemComponent.
55
- * @summary Initializes a new ListItemComponent by calling the parent class constructor
56
- * with the component name for logging and identification purposes. Also registers
57
- * all available Ionic icons to ensure they can be displayed in the component.
58
- *
59
- * @memberOf ListItemComponent
60
- */
61
- constructor() {
62
- super("ListItemComponent");
63
- /**
64
- * @description Controls the display of lines around the list item.
65
- * @summary Determines how lines are displayed around the list item borders.
66
- * 'inset' shows lines with padding, 'full' shows full-width lines, and 'none'
67
- * removes all lines. This affects the visual separation between list items.
68
- *
69
- * @type {'inset' | 'full' | 'none'}
70
- * @default 'inset'
71
- * @memberOf ListItemComponent
72
- */
73
- this.lines = 'full';
74
- /**
75
- * @description Position of the icon within the list item.
76
- * @summary Determines whether the icon appears at the start (left in LTR languages)
77
- * or end (right in LTR languages) of the list item. This affects the overall
78
- * layout and visual hierarchy of the item content.
79
- *
80
- * @type {'start' | 'end'}
81
- * @default 'start'
82
- * @memberOf ListItemComponent
83
- */
84
- this.iconSlot = 'start';
85
- /**
86
- * @description Controls whether the list item behaves as a clickable button.
87
- * @summary When set to true, the list item will have button-like behavior including
88
- * hover effects, click handling, and appropriate accessibility attributes.
89
- * When false, the item is displayed as static content without interactive behavior.
90
- *
91
- * @type {StringOrBoolean}
92
- * @default true
93
- * @memberOf ListItemComponent
94
- */
95
- this.button = true;
96
- /**
97
- * @description Event emitter for list item click interactions.
98
- * @summary Emits custom events when the list item is clicked or when actions
99
- * are performed on it. The emitted event contains information about the action,
100
- * the item data, and other relevant context for parent components to handle.
101
- *
102
- * @type {EventEmitter<ListItemCustomEvent>}
103
- * @memberOf ListItemComponent
104
- */
105
- this.clickEvent = new EventEmitter();
106
- /**
107
- * @description Flag indicating whether slide items are currently enabled.
108
- * @summary Controls the visibility of slide actions based on screen size and
109
- * available operations. When true, users can swipe on the item to reveal
110
- * action buttons for operations like edit and delete.
111
- *
112
- * @type {boolean}
113
- * @default false
114
- * @memberOf ListItemComponent
115
- */
116
- this.showSlideItems = false;
117
- /**
118
- * @description Flag indicating whether the action menu popover is currently open.
119
- * @summary Tracks the state of the action menu to prevent multiple instances
120
- * from being opened simultaneously and to ensure proper cleanup when actions
121
- * are performed. Used for managing the popover lifecycle.
122
- *
123
- * @type {boolean}
124
- * @default false
125
- * @memberOf ListItemComponent
126
- */
127
- this.actionMenuOpen = false;
128
- /**
129
- * @description Angular NavController service for handling navigation.
130
- * @summary Injected service that provides methods for programmatic navigation
131
- * within the Ionic application. Used for navigating to different routes when
132
- * list item actions are performed or when the item itself is clicked.
133
- *
134
- * @private
135
- * @type {NavController}
136
- * @memberOf ListItemComponent
137
- */
138
- this.navController = inject(NavController);
139
- addIcons(AllIcons);
140
- }
141
- /**
142
- * @description Initializes the component after Angular first displays the data-bound properties.
143
- * @summary Sets up the component by determining slide item visibility, processing boolean inputs,
144
- * building CSS class names based on properties, and capturing the current window width.
145
- * This method prepares the component for user interaction by ensuring all properties are
146
- * properly initialized and responsive behavior is configured.
147
- *
148
- * @mermaid
149
- * sequenceDiagram
150
- * participant A as Angular Lifecycle
151
- * participant L as ListItemComponent
152
- * participant W as Window
153
- *
154
- * A->>L: ngOnInit()
155
- * L->>L: enableSlideItems()
156
- * L->>L: Process button boolean
157
- * L->>L: Build className with flex classes
158
- * alt operations exist
159
- * L->>L: Add 'action' class
160
- * end
161
- * L->>W: getWindowWidth()
162
- * W-->>L: Return current width
163
- * L->>L: Store windowWidth
164
- *
165
- * @return {Promise<void>}
166
- * @memberOf ListItemComponent
167
- */
168
- async ngOnInit() {
169
- this.showSlideItems = this.enableSlideItems();
170
- this.button = stringToBoolean(this.button);
171
- this.className = `${this.className} dcf-flex dcf-flex-middle grid-item`;
172
- if (this.operations?.length)
173
- this.className += ` action`;
174
- this.windowWidth = getWindowWidth();
175
- }
176
- /**
177
- * @description Handles user interactions and actions performed on the list item.
178
- * @summary This method is the central action handler for list item interactions. It manages
179
- * event propagation, dismisses open action menus, removes focus traps, and either emits
180
- * events for parent components to handle or performs navigation based on the component's
181
- * route configuration. This method supports both event-driven and navigation-driven architectures.
182
- *
183
- * @param {CrudOperations} action - The type of CRUD operation being performed
184
- * @param {Event} event - The browser event that triggered the action
185
- * @param {HTMLElement} [target] - Optional target element for the event
186
- * @return {Promise<boolean|void>} A promise that resolves to navigation success or void for events
187
- *
188
- * @mermaid
189
- * sequenceDiagram
190
- * participant U as User
191
- * participant L as ListItemComponent
192
- * participant P as Parent Component
193
- * participant N as NavController
194
- * participant E as Event System
195
- *
196
- * U->>L: Perform action (click/swipe)
197
- * L->>L: stopImmediatePropagation()
198
- * alt actionMenuOpen
199
- * L->>L: Dismiss action menu
200
- * end
201
- * L->>L: removeFocusTrap()
202
- * alt No route configured
203
- * L->>E: windowEventEmitter()
204
- * L->>P: clickEvent.emit()
205
- * else Route configured
206
- * L->>N: redirect(action, uid)
207
- * N-->>L: Return navigation result
208
- * end
209
- *
210
- * @memberOf ListItemComponent
211
- */
212
- async handleAction(action, event, target) {
213
- event.stopImmediatePropagation();
214
- if (this.actionMenuOpen)
215
- await this.actionMenuComponent.dismiss();
216
- // forcing trap focus
217
- removeFocusTrap();
218
- if (!this.route) {
219
- const event = { target: target, action, pk: this.pk, data: this.uid, name: EventConstants.CLICK, component: this.componentName };
220
- windowEventEmitter(`ListItem${EventConstants.CLICK}`, event);
221
- return this.clickEvent.emit(event);
222
- }
223
- return await this.redirect(action, (typeof this.uid === 'number' ? `${this.uid}` : this.uid));
224
- }
225
- /**
226
- * @description Responsive handler that enables or disables slide items based on screen size and operations.
227
- * @summary This method is automatically called when the window is resized and also during component
228
- * initialization. It determines whether slide actions should be available based on the current
229
- * window width and the presence of UPDATE or DELETE operations. Slide items are typically hidden
230
- * on larger screens where there's space for dedicated action buttons.
231
- *
232
- * @return {boolean} True if slide items should be shown, false otherwise
233
- *
234
- * @mermaid
235
- * sequenceDiagram
236
- * participant W as Window
237
- * participant L as ListItemComponent
238
- * participant U as UI
239
- *
240
- * W->>L: resize event
241
- * L->>W: getWindowWidth()
242
- * W-->>L: Return current width
243
- * L->>L: Store windowWidth
244
- * alt No operations OR width > 639px
245
- * L->>U: showSlideItems = false
246
- * else Operations include UPDATE/DELETE
247
- * L->>U: showSlideItems = true
248
- * end
249
- * L-->>U: Return showSlideItems value
250
- *
251
- * @memberOf ListItemComponent
252
- */
253
- enableSlideItems() {
254
- this.windowWidth = getWindowWidth();
255
- if (!this.operations?.length || this.windowWidth > 639)
256
- return this.showSlideItems = false;
257
- this.showSlideItems = this.operations.includes(OperationKeys.UPDATE) || this.operations.includes(OperationKeys.DELETE);
258
- return this.showSlideItems;
259
- }
260
- /**
261
- * @description Animates and removes an element from the DOM.
262
- * @summary This method applies CSS animation classes to create a smooth fade-out effect
263
- * before removing the element from the DOM. The animation enhances user experience by
264
- * providing visual feedback when items are deleted or removed from lists. The timing
265
- * is coordinated with the CSS animation duration to ensure the element is removed
266
- * after the animation completes.
267
- *
268
- * @param {HTMLElement} element - The DOM element to animate and remove
269
- * @return {void}
270
- *
271
- * @mermaid
272
- * sequenceDiagram
273
- * participant L as ListItemComponent
274
- * participant E as HTMLElement
275
- * participant D as DOM
276
- *
277
- * L->>E: Add animation classes
278
- * Note over E: uk-animation-fade, uk-animation-medium, uk-animation-reverse
279
- * E->>E: Start fade animation
280
- * L->>L: setTimeout(600ms)
281
- * Note over L: Wait for animation to complete
282
- * L->>D: element.remove()
283
- * D->>D: Remove element from DOM
284
- *
285
- * @memberOf ListItemComponent
286
- */
287
- removeElement(element) {
288
- element.classList.add('uk-animation-fade', 'uk-animation-medium', 'uk-animation-reverse');
289
- setTimeout(() => { element.remove(); }, 600);
290
- }
291
- /**
292
- * @description Navigates to a new route based on the specified action and item ID.
293
- * @summary This method constructs a navigation URL using the component's route configuration,
294
- * the specified action, and an item identifier. It uses Ionic's NavController to perform
295
- * forward navigation with appropriate animations. This method is typically used for
296
- * CRUD operations where each action (create, read, update, delete) has its own route.
297
- *
298
- * @param {string} action - The action to be performed (e.g., 'edit', 'view', 'delete')
299
- * @param {string} [id] - The unique identifier of the item to be acted upon
300
- * @return {Promise<boolean>} A promise that resolves to true if navigation was successful
301
- *
302
- * @mermaid
303
- * sequenceDiagram
304
- * participant L as ListItemComponent
305
- * participant N as NavController
306
- * participant R as Router
307
- *
308
- * L->>L: redirect(action, id)
309
- * L->>L: Construct URL: /{route}/{action}/{id}
310
- * L->>N: navigateForward(url)
311
- * N->>R: Navigate to constructed URL
312
- * R-->>N: Return navigation result
313
- * N-->>L: Return boolean success
314
- *
315
- * @memberOf ListItemComponent
316
- */
317
- async redirect(action, id) {
318
- return await this.navController.navigateForward(`/${this.route}/${action}/${id || this.uid}`);
319
- }
320
- /**
321
- * @description Presents the actions menu popover for the list item.
322
- * @summary This method handles the display of a contextual action menu when triggered by user
323
- * interaction (typically a long press or right-click). It stops event propagation to prevent
324
- * unwanted side effects, removes any existing focus traps for accessibility, configures the
325
- * popover with the triggering event, and opens the action menu. The menu typically contains
326
- * available CRUD operations for the item.
327
- *
328
- * @param {Event} event - The event that triggered the action menu request
329
- * @return {void}
330
- *
331
- * @mermaid
332
- * sequenceDiagram
333
- * participant U as User
334
- * participant L as ListItemComponent
335
- * participant P as Popover
336
- * participant A as Accessibility
337
- *
338
- * U->>L: Trigger action menu (long press/right-click)
339
- * L->>L: stopImmediatePropagation()
340
- * L->>A: removeFocusTrap()
341
- * L->>P: Set event reference
342
- * L->>L: actionMenuOpen = true
343
- * L->>P: Display popover with actions
344
- *
345
- * @memberOf ListItemComponent
346
- */
347
- presentActionsMenu(event) {
348
- event.stopImmediatePropagation();
349
- // forcing trap focus
350
- removeFocusTrap();
351
- this.actionMenuComponent.event = event;
352
- this.actionMenuOpen = true;
353
- }
354
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
355
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ListItemComponent, isStandalone: true, selector: "ngx-decaf-list-item", inputs: { lines: "lines", item: "item", icon: "icon", iconSlot: "iconSlot", button: "button", title: "title", description: "description", info: "info", subinfo: "subinfo" }, outputs: { clickEvent: "clickEvent" }, host: { listeners: { "window:resize": "enableSlideItems($event)" } }, viewQueries: [{ propertyName: "actionMenuComponent", first: true, predicate: ["actionMenuComponent"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n@if(title || description) {\n <ion-item-sliding #component>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"button\"\n [class]=\"className\"\n (click)=\"operations?.includes('read') ? handleAction('read', $event, component) : ''\n \">\n @if(icon && lines !== 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\"></ion-icon>\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if(icon && lines === 'inset') {\n <div class=\"dcf-icon dcf-grid-icon\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\"></ion-icon>\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n <ion-label class=\"dcf-item-title\" [innerHTML]=\"uid + ' - ' + title\" ></ion-label>\n @if(description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if(info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if(info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if(subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if((operations.includes('delete') || operations.includes('update')) && uid) {\n <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n <ion-button class=\"dcf-hidden@m\" shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\"></ion-icon>\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\">\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4 class=\"dcf-text-capitalize\" [innerHTML]=\"'actions' | translate\"></h4>\n </ion-list-header>\n @for (operation of ['update', 'delete']; track operation) {\n @if(operations.includes(operation)) {\n <ion-item [button]=\"true\" (click)=\"handleAction(operation, $event, component)\">\n <ion-avatar class=\"dcf-flex dcf-flex-middle\" aria-hidden=\"true\" slot=\"start\">\n @if(operation === 'update') {\n <ion-icon color=\"primary\" aria-hidden=\"true\" name=\"create-outline\"></ion-icon>\n } @else {\n <ion-icon color=\"danger\" aria-hidden=\"true\" name=\"trash\"></ion-icon>\n }\n </ion-avatar>\n <ion-label class=\"dcf-text-capitalize\">{{ operation | translate }}</ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n </div>\n }\n <!-- @if(operations?.length && uid) {\n <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n @if(operations?.includes('update')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"primary\" (click)=\"handleAction('update', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-button>\n }\n @if(operations?.includes('delete')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleAction('delete', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-button>\n }\n </div>\n } -->\n @if(windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if(showSlideItems && uid) {\n <ion-item-options side=\"end\" (ionSwipe)=\"operations.length === 1 ? handleAction(operations[0], $event, component) : ''\">\n @if(operations?.includes('update')) {\n <ion-item-option class=\"dcf-update\" (click)=\"handleAction('update', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-item-option>\n }\n @if(operations?.includes('delete')) {\n <ion-item-option class=\"dcf- delete\" (click)=\"handleAction('delete', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n", styles: ["ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8)}@media (prefers-color-scheme: dark){ion-item{--background-hover-opacity: .25;--background-focused-opacity: .25}}@media (prefers-color-scheme: light){ion-item{--background-hover-opacity: .1;--background-focused-opacity: .1}}ion-item.item-lines-full{--padding-top: .5rem;--padding-bottom: .5rem;--padding-start: .25rem;-padding-end:.25rem;padding:0 .65rem}ion-item.item-lines-inset{--padding-top: 0rem !important;--padding-bottom: 0rem !important;--inner-padding-top: .5rem !important;--inner-padding-bottom: .65rem !important}@media (prefers-color-scheme: light){ion-item{--border-color: var(--dcf-color-gray-2)}ion-item .dcf-info{color:var(--dcf-color-gray-6)}ion-item .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item .dcf-description{color:var(--dcf-color-gray-6)}}@media (prefers-color-scheme: dark){ion-item{--border-color: var(--dcf-color-gray-6)}ion-item .dcf-description{color:var(--dcf-color-gray-4)}}ion-item .dcf-info{min-width:10vw;background:transparent!important}ion-item .dcf-grid{padding:0!important;margin:0!important;min-width:100%!important}ion-item .dcf-item-title{font-style:normal;font-weight:700}ion-item .dcf-description{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-weight:400;font-size:.925rem}ion-item::part(native){min-width:100%}ion-item [slot=start]{margin-right:.5rem!important}ion-item [slot=end]{margin-left:.5rem!important}ion-item .dcf-info{font-size:.9rem}ion-item .dcf-info .dcf-subinfo.dcf-line{margin-left:.5rem}@media (min-width: var(--dcf-width-sm)){ion-item .dcf-info .dcf-subinfo.dcf-line{display:block;margin-left:0}}ion-item #dcf-actions{padding:5px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-actions{display:none;pointer-events:none!important;cursor:text!important}ion-item #dcf-actions *{display:none;pointer-events:none!important;cursor:text!important}}ion-item #dcf-actions ion-button{--padding-start: 1rem;--padding-end: .75rem;--padding-top: .85rem !important;--padding-bottom: .85rem !important;color:#ccc;margin-right:.5rem!important;--background: var(--dcf-color-gray-2) !important}ion-item #dcf-actions ion-button ion-icon{position:relative;left:-1px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-end,ion-item [slot=end]{display:none!important}}ion-item #dcf-end{padding-top:5px;display:flex;align-items:flex-end}ion-item .dcf-icon{display:flex;justify-content:center;align-items:center;text-align:center;margin-right:.5rem!important}ion-item .dcf-icon.dcf-grid-icon{min-width:50px;text-align:left;display:flex;justify-content:flex-start}@media (max-width: var(--dcf-width-s)){ion-item .dcf-icon{align-items:flex-start!important}}@media (prefers-color-scheme: light){ion-item .dcf-icon ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}}@media (prefers-color-scheme: dark){ion-item .dcf-icon ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}}ion-item .dcf-icon ion-button ion-icon{font-size:20px}ion-item .dcf-icon ion-avatar{width:48px;height:48px;display:flex;justify-content:center;align-items:center;text-align:center}@media (prefers-color-scheme: light){ion-item .dcf-icon ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}}@media (prefers-color-scheme: dark){ion-item .dcf-icon ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}}ion-item .dcf-icon ion-avatar ion-icon{font-size:20px}ion-item .dcf-icon ion-avatar .dcf-icon-large{transform:translateY(5px)}ion-item-sliding{box-sizing:border-box}@media (prefers-color-scheme: light){ion-item-sliding ion-item-option:not(.dcf-delete),ion-item-sliding ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item-sliding ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-delete) ion-icon,ion-item-sliding ion-item-option:not(.dcf-update) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item-sliding ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-delete .dcf-ti,ion-item-sliding ion-item-option.dcf-delete *,ion-item-sliding ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-sliding ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-update .dcf-ti,ion-item-sliding ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}}@media (prefers-color-scheme: dark){ion-item-sliding ion-item-option:not(.dcf-delete),ion-item-sliding ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item-sliding ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-delete) ion-icon,ion-item-sliding ion-item-option:not(.dcf-update) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-delete .dcf-ti,ion-item-sliding ion-item-option.dcf-delete *,ion-item-sliding ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-sliding ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-update .dcf-ti,ion-item-sliding ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}}ion-item-sliding[class*=active-slide]{border-color:var(--dcf-color-gray-3)}ion-item-sliding ion-item-option{color:var(--dcf-color-gray-5);box-shadow:inset 0 0 5px rgba(var(--dcf-color-dark-rgb),.15)!important;background:var(--dcf-color-gray-3)}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonItemSliding, selector: "ion-item-sliding", inputs: ["disabled"] }, { kind: "component", type: IonItemOptions, selector: "ion-item-options", inputs: ["side"] }, { kind: "component", type: IonItemOption, selector: "ion-item-option", inputs: ["color", "disabled", "download", "expandable", "href", "mode", "rel", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonPopover, selector: "ion-popover" }] }); }
356
- };
357
- ListItemComponent = __decorate([
358
- Dynamic(),
359
- __metadata("design:paramtypes", [])
360
- ], ListItemComponent);
361
- export { ListItemComponent };
362
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListItemComponent, decorators: [{
363
- type: Component,
364
- args: [{ selector: 'ngx-decaf-list-item', standalone: true, imports: [
365
- TranslatePipe,
366
- IonList,
367
- IonListHeader,
368
- IonItem,
369
- IonItemSliding,
370
- IonItemOptions,
371
- IonItemOption,
372
- IonIcon,
373
- IonLabel,
374
- IonButton,
375
- IonContent,
376
- IonPopover
377
- ], template: "\n@if(title || description) {\n <ion-item-sliding #component>\n <ion-item\n [id]=\"uid\"\n [lines]=\"lines\"\n [button]=\"button\"\n [class]=\"className\"\n (click)=\"operations?.includes('read') ? handleAction('read', $event, component) : ''\n \">\n @if(icon && lines !== 'inset') {\n <div class=\"dcf-icon\" [slot]=\"iconSlot\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\"></ion-icon>\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand\">\n <div class=\"dcf-flex dcf-flex-middle dcf-grid-collapse\" dcf-grid>\n @if(icon && lines === 'inset') {\n <div class=\"dcf-icon dcf-grid-icon\">\n <ion-avatar>\n <ion-icon aria-hidden=\"true\" name=\"reader-outline\" size=\"default\"></ion-icon>\n </ion-avatar>\n </div>\n }\n <div class=\"dcf-width-expand@s dcf-width-1-1 dcf-label\">\n <ion-label class=\"dcf-item-title\" [innerHTML]=\"uid + ' - ' + title\" ></ion-label>\n @if(description) {\n <div class=\"dcf-description\" [innerHTML]=\"description\"></div>\n }\n </div>\n @if(info || subinfo) {\n <div class=\"dcf-width-auto@s dcf-width-expand dcf-info dcf-flex dcf-flex-right@s\">\n <div>\n @if(info) {\n <span [innerHTML]=\"info\"></span>\n }\n @if(subinfo) {\n <div class=\"dcf-subinfo dcf-text-truncate\" [innerHTML]=\"subinfo\" ></div>\n }\n </div>\n </div>\n }\n\n <div class=\"dcf-width-auto dcf-flex dcf-flex-middle dcf-flex-right\">\n @if((operations.includes('delete') || operations.includes('update')) && uid) {\n <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n <ion-button class=\"dcf-hidden@m\" shape=\"round\" fill=\"clear\" color=\"primary\" (click)=\"presentActionsMenu($event)\">\n <ion-icon slot=\"icon-only\" aria-hidden=\"true\" name=\"ellipsis-vertical-outline\"></ion-icon>\n </ion-button>\n <ion-popover\n #actionMenuComponent\n side=\"bottom\"\n alignment=\"left\"\n\n [isOpen]=\"actionMenuOpen\"\n (didDismiss)=\"actionMenuOpen = false\">\n <ng-template>\n <ion-content class=\"ion-padding\">\n <ion-list lines=\"none\">\n <ion-list-header>\n <h4 class=\"dcf-text-capitalize\" [innerHTML]=\"'actions' | translate\"></h4>\n </ion-list-header>\n @for (operation of ['update', 'delete']; track operation) {\n @if(operations.includes(operation)) {\n <ion-item [button]=\"true\" (click)=\"handleAction(operation, $event, component)\">\n <ion-avatar class=\"dcf-flex dcf-flex-middle\" aria-hidden=\"true\" slot=\"start\">\n @if(operation === 'update') {\n <ion-icon color=\"primary\" aria-hidden=\"true\" name=\"create-outline\"></ion-icon>\n } @else {\n <ion-icon color=\"danger\" aria-hidden=\"true\" name=\"trash\"></ion-icon>\n }\n </ion-avatar>\n <ion-label class=\"dcf-text-capitalize\">{{ operation | translate }}</ion-label>\n </ion-item>\n }\n }\n </ion-list>\n </ion-content>\n </ng-template>\n </ion-popover>\n </div>\n }\n <!-- @if(operations?.length && uid) {\n <div class=\"dcf-visible@m\" id=\"dcf-actions\">\n @if(operations?.includes('update')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"primary\" (click)=\"handleAction('update', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-button>\n }\n @if(operations?.includes('delete')) {\n <ion-button fill=\"clear\" size=\"small\" color=\"danger\" (click)=\"handleAction('delete', component)\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-button>\n }\n </div>\n } -->\n @if(windowWidth > 639) {\n <div id=\"end\">\n <ng-content select=\"[slot='end']\"></ng-content>\n </div>\n }\n </div>\n </div>\n </div>\n </ion-item>\n @if(showSlideItems && uid) {\n <ion-item-options side=\"end\" (ionSwipe)=\"operations.length === 1 ? handleAction(operations[0], $event, component) : ''\">\n @if(operations?.includes('update')) {\n <ion-item-option class=\"dcf-update\" (click)=\"handleAction('update', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"create-outline\"></ion-icon>\n </ion-item-option>\n }\n @if(operations?.includes('delete')) {\n <ion-item-option class=\"dcf- delete\" (click)=\"handleAction('delete', $event, component)\" [expandable]=\"operations.length === 1\">\n <ion-icon aria-hidden=\"true\" slot=\"icon-only\" name=\"trash\"></ion-icon>\n </ion-item-option>\n }\n </ion-item-options>\n }\n </ion-item-sliding>\n}\n", styles: ["ion-item{--min-height: 50px;--padding-top: .25rem;--padding-bottom: .25rem;--padding-start: .75rem;--padding-end: .75rem;--inner-padding-start: 0px !important;--inner-padding-end: 0px !important;--background-hover: var(--dcf-color-gray-8);--background-focused: var(--dcf-color-gray-8)}@media (prefers-color-scheme: dark){ion-item{--background-hover-opacity: .25;--background-focused-opacity: .25}}@media (prefers-color-scheme: light){ion-item{--background-hover-opacity: .1;--background-focused-opacity: .1}}ion-item.item-lines-full{--padding-top: .5rem;--padding-bottom: .5rem;--padding-start: .25rem;-padding-end:.25rem;padding:0 .65rem}ion-item.item-lines-inset{--padding-top: 0rem !important;--padding-bottom: 0rem !important;--inner-padding-top: .5rem !important;--inner-padding-bottom: .65rem !important}@media (prefers-color-scheme: light){ion-item{--border-color: var(--dcf-color-gray-2)}ion-item .dcf-info{color:var(--dcf-color-gray-6)}ion-item .dcf-item-title{color:var(--dcf-color-gray-8)}ion-item .dcf-description{color:var(--dcf-color-gray-6)}}@media (prefers-color-scheme: dark){ion-item{--border-color: var(--dcf-color-gray-6)}ion-item .dcf-description{color:var(--dcf-color-gray-4)}}ion-item .dcf-info{min-width:10vw;background:transparent!important}ion-item .dcf-grid{padding:0!important;margin:0!important;min-width:100%!important}ion-item .dcf-item-title{font-style:normal;font-weight:700}ion-item .dcf-description{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-weight:400;font-size:.925rem}ion-item::part(native){min-width:100%}ion-item [slot=start]{margin-right:.5rem!important}ion-item [slot=end]{margin-left:.5rem!important}ion-item .dcf-info{font-size:.9rem}ion-item .dcf-info .dcf-subinfo.dcf-line{margin-left:.5rem}@media (min-width: var(--dcf-width-sm)){ion-item .dcf-info .dcf-subinfo.dcf-line{display:block;margin-left:0}}ion-item #dcf-actions{padding:5px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-actions{display:none;pointer-events:none!important;cursor:text!important}ion-item #dcf-actions *{display:none;pointer-events:none!important;cursor:text!important}}ion-item #dcf-actions ion-button{--padding-start: 1rem;--padding-end: .75rem;--padding-top: .85rem !important;--padding-bottom: .85rem !important;color:#ccc;margin-right:.5rem!important;--background: var(--dcf-color-gray-2) !important}ion-item #dcf-actions ion-button ion-icon{position:relative;left:-1px}@media (max-width: var(--dcf-width-m)){ion-item #dcf-end,ion-item [slot=end]{display:none!important}}ion-item #dcf-end{padding-top:5px;display:flex;align-items:flex-end}ion-item .dcf-icon{display:flex;justify-content:center;align-items:center;text-align:center;margin-right:.5rem!important}ion-item .dcf-icon.dcf-grid-icon{min-width:50px;text-align:left;display:flex;justify-content:flex-start}@media (max-width: var(--dcf-width-s)){ion-item .dcf-icon{align-items:flex-start!important}}@media (prefers-color-scheme: light){ion-item .dcf-icon ion-button{color:var(--dcf-color-gray-7);--background: var(--dcf-color-gray-1) !important}}@media (prefers-color-scheme: dark){ion-item .dcf-icon ion-button{color:var(--dcf-color-gray-1)!important;--background: var(--dcf-color-gray-7) !important}}ion-item .dcf-icon ion-button ion-icon{font-size:20px}ion-item .dcf-icon ion-avatar{width:48px;height:48px;display:flex;justify-content:center;align-items:center;text-align:center}@media (prefers-color-scheme: light){ion-item .dcf-icon ion-avatar{color:var(--dcf-color-gray-7);background:var(--dcf-color-gray-1)!important}}@media (prefers-color-scheme: dark){ion-item .dcf-icon ion-avatar{color:var(--dcf-color-gray-1)!important;background:var(--dcf-background-color)!important}}ion-item .dcf-icon ion-avatar ion-icon{font-size:20px}ion-item .dcf-icon ion-avatar .dcf-icon-large{transform:translateY(5px)}ion-item-sliding{box-sizing:border-box}@media (prefers-color-scheme: light){ion-item-sliding ion-item-option:not(.dcf-delete),ion-item-sliding ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),.25)!important}ion-item-sliding ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-delete) ion-icon,ion-item-sliding ion-item-option:not(.dcf-update) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-7)!important}ion-item-sliding ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-delete .dcf-ti,ion-item-sliding ion-item-option.dcf-delete *,ion-item-sliding ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-sliding ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-update .dcf-ti,ion-item-sliding ion-item-option.dcf-update ion-icon{color:var(--dcf-color-primary)!important}}@media (prefers-color-scheme: dark){ion-item-sliding ion-item-option:not(.dcf-delete),ion-item-sliding ion-item-option:not(.dcf-update){background:rgba(var(--dcf-color-dark-rgb),1)!important}ion-item-sliding ion-item-option:not(.dcf-delete) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-delete) ion-icon,ion-item-sliding ion-item-option:not(.dcf-update) .dcf-ti,ion-item-sliding ion-item-option:not(.dcf-update) ion-icon{color:var(--dcf-color-gray-2)!important}ion-item-sliding ion-item-option.dcf-delete{background:rgba(var(--dcf-color-danger-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-delete .dcf-ti,ion-item-sliding ion-item-option.dcf-delete *,ion-item-sliding ion-item-option.dcf-delete ion-icon{color:var(--dcf-color-danger)!important}ion-item-sliding ion-item-option.dcf-update{background:rgba(var(--dcf-color-primary-rgb),.05)!important}ion-item-sliding ion-item-option.dcf-update .dcf-ti,ion-item-sliding ion-item-option.dcf-update ion-icon{color:var(--dcf-color-gray-2)!important}}ion-item-sliding[class*=active-slide]{border-color:var(--dcf-color-gray-3)}ion-item-sliding ion-item-option{color:var(--dcf-color-gray-5);box-shadow:inset 0 0 5px rgba(var(--dcf-color-dark-rgb),.15)!important;background:var(--dcf-color-gray-3)}\n"] }]
378
- }], ctorParameters: () => [], propDecorators: { actionMenuComponent: [{
379
- type: ViewChild,
380
- args: ['actionMenuComponent']
381
- }], lines: [{
382
- type: Input
383
- }], item: [{
384
- type: Input
385
- }], icon: [{
386
- type: Input
387
- }], iconSlot: [{
388
- type: Input
389
- }], button: [{
390
- type: Input
391
- }], title: [{
392
- type: Input
393
- }], description: [{
394
- type: Input
395
- }], info: [{
396
- type: Input
397
- }], subinfo: [{
398
- type: Input
399
- }], clickEvent: [{
400
- type: Output
401
- }], enableSlideItems: [{
402
- type: HostListener,
403
- args: ['window:resize', ['$event']]
404
- }] } });
405
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1pdGVtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9saXN0LWl0ZW0vbGlzdC1pdGVtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9saXN0LWl0ZW0vbGlzdC1pdGVtLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsU0FBUyxFQUFHLE1BQU0sZUFBZSxDQUFDO0FBQ2pILE9BQU8sRUFBa0IsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFeEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RSxPQUFPLEVBQUUsY0FBYyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDekUsT0FBTyxFQUFFLE9BQU8sRUFBRSxjQUFjLEVBQXVCLE1BQU0sY0FBYyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsU0FBUyxFQUNULE9BQU8sRUFDUCxRQUFRLEVBQ1IsT0FBTyxFQUNQLFVBQVUsRUFDVixPQUFPLEVBQ1AsYUFBYSxFQUNiLFVBQVUsRUFDVixjQUFjLEVBQ2QsY0FBYyxFQUNkLGFBQWEsRUFDZCxNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sS0FBSyxRQUFRLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNwQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7O0FBR3BEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUNHO0FBdUJJLElBQU0saUJBQWlCLEdBQXZCLE1BQU0saUJBQWtCLFNBQVEsZ0JBQWdCO0lBd0xyRDs7Ozs7OztPQU9HO0lBQ0g7UUFDRSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQW5MN0I7Ozs7Ozs7OztXQVNHO1FBRUgsVUFBSyxHQUE4QixNQUFNLENBQUM7UUEwQjFDOzs7Ozs7Ozs7V0FTRztRQUVILGFBQVEsR0FBbUIsT0FBTyxDQUFDO1FBRW5DOzs7Ozs7Ozs7V0FTRztRQUVILFdBQU0sR0FBb0IsSUFBSSxDQUFDO1FBa0QvQjs7Ozs7Ozs7V0FRRztRQUVILGVBQVUsR0FBdUMsSUFBSSxZQUFZLEVBQXVCLENBQUM7UUFFekY7Ozs7Ozs7OztXQVNHO1FBQ0gsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFhaEM7Ozs7Ozs7OztXQVNHO1FBQ0gsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFFaEM7Ozs7Ozs7OztXQVNHO1FBQ0ssa0JBQWEsR0FBa0IsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBWTNELFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUNwQixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BMEJHO0lBQ0gsS0FBSyxDQUFDLFFBQVE7UUFDWixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQzlDLElBQUksQ0FBQyxNQUFNLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUUzQyxJQUFJLENBQUMsU0FBUyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsc0NBQXNDLENBQUM7UUFDekUsSUFBRyxJQUFJLENBQUMsVUFBVSxFQUFFLE1BQU07WUFDeEIsSUFBSSxDQUFDLFNBQVMsSUFBSSxTQUFTLENBQUM7UUFDOUIsSUFBSSxDQUFDLFdBQVcsR0FBRyxjQUFjLEVBQVksQ0FBQztJQUNoRCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BbUNHO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFzQixFQUFFLEtBQVksRUFBRSxNQUFvQjtRQUMzRSxLQUFLLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztRQUNqQyxJQUFHLElBQUksQ0FBQyxjQUFjO1lBQ3BCLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzNDLHFCQUFxQjtRQUNyQixlQUFlLEVBQUUsQ0FBQztRQUNsQixJQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxLQUFLLEdBQUcsRUFBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBeUIsQ0FBQztZQUN2SixrQkFBa0IsQ0FBQyxXQUFXLGNBQWMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM3RCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLENBQUM7UUFDRCxPQUFPLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxPQUFPLElBQUksQ0FBQyxHQUFHLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDL0YsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0EyQkc7SUFFSCxnQkFBZ0I7UUFDZCxJQUFJLENBQUMsV0FBVyxHQUFHLGNBQWMsRUFBWSxDQUFDO1FBQzlDLElBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLE1BQU0sSUFBSSxJQUFJLENBQUMsV0FBVyxHQUFHLEdBQUc7WUFDbkQsT0FBTyxJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztRQUNyQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkgsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDO0lBQzdCLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0EwQkc7SUFDSCxhQUFhLENBQUMsT0FBb0I7UUFDaEMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUscUJBQXFCLEVBQUUsc0JBQXNCLENBQUMsQ0FBQztRQUMxRixVQUFVLENBQUMsR0FBRyxFQUFFLEdBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFBLENBQUEsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQzNDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXlCRztJQUNILEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBYyxFQUFFLEVBQVc7UUFDeEMsT0FBTyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxNQUFNLElBQUksRUFBRSxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQ2hHLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0EwQkc7SUFDSCxrQkFBa0IsQ0FBQyxLQUFZO1FBQzdCLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQ2pDLHFCQUFxQjtRQUNyQixlQUFlLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUN2QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztJQUM3QixDQUFDOytHQWhhVSxpQkFBaUI7bUdBQWpCLGlCQUFpQiw2ZkN0RjlCLGkxTEEySEEsaWtNRHBESSxhQUFhLGtEQUNiLE9BQU8seUZBQ1AsYUFBYSxnR0FDYixPQUFPLDBOQUNQLGNBQWMsbUZBQ2QsY0FBYywrRUFDZCxhQUFhLDhKQUNiLE9BQU8sMkpBQ1AsUUFBUSw2RkFDUixTQUFTLG9QQUNULFVBQVUsd0tBQ1YsVUFBVTs7QUFJRCxpQkFBaUI7SUF0QjdCLE9BQU8sRUFBRTs7R0FzQkcsaUJBQWlCLENBaWE3Qjs7NEZBamFZLGlCQUFpQjtrQkFyQjdCLFNBQVM7K0JBQ0UscUJBQXFCLGNBR25CLElBQUksV0FDUDt3QkFDUCxhQUFhO3dCQUNiLE9BQU87d0JBQ1AsYUFBYTt3QkFDYixPQUFPO3dCQUNQLGNBQWM7d0JBQ2QsY0FBYzt3QkFDZCxhQUFhO3dCQUNiLE9BQU87d0JBQ1AsUUFBUTt3QkFDUixTQUFTO3dCQUNULFVBQVU7d0JBQ1YsVUFBVTtxQkFDWDt3REFlRCxtQkFBbUI7c0JBRGxCLFNBQVM7dUJBQUMscUJBQXFCO2dCQWNoQyxLQUFLO3NCQURKLEtBQUs7Z0JBYUcsSUFBSTtzQkFEWixLQUFLO2dCQWFOLElBQUk7c0JBREgsS0FBSztnQkFjTixRQUFRO3NCQURQLEtBQUs7Z0JBY04sTUFBTTtzQkFETCxLQUFLO2dCQWFOLEtBQUs7c0JBREosS0FBSztnQkFhTixXQUFXO3NCQURWLEtBQUs7Z0JBYU4sSUFBSTtzQkFESCxLQUFLO2dCQWFOLE9BQU87c0JBRE4sS0FBSztnQkFhTixVQUFVO3NCQURULE1BQU07Z0JBbUxQLGdCQUFnQjtzQkFEZixZQUFZO3VCQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIGluamVjdCwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBWaWV3Q2hpbGQgIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDcnVkT3BlcmF0aW9ucywgT3BlcmF0aW9uS2V5cyB9IGZyb20gJ0BkZWNhZi10cy9kYi1kZWNvcmF0b3JzJztcbmltcG9ydCB7IFN0cmluZ09yQm9vbGVhbiB9IGZyb20gJy4uLy4uL2VuZ2luZS90eXBlcyc7XG5pbXBvcnQgeyBOZ3hCYXNlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vZW5naW5lL05neEJhc2VDb21wb25lbnQnO1xuaW1wb3J0IHsgcmVtb3ZlRm9jdXNUcmFwLCBzdHJpbmdUb0Jvb2xlYW4gfSBmcm9tICcuLi8uLi9oZWxwZXJzL3V0aWxzJztcbmltcG9ydCB7IGdldFdpbmRvd1dpZHRoLCB3aW5kb3dFdmVudEVtaXR0ZXIgfSBmcm9tICcuLi8uLi9oZWxwZXJzL3V0aWxzJztcbmltcG9ydCB7IER5bmFtaWMsIEV2ZW50Q29uc3RhbnRzLCBMaXN0SXRlbUN1c3RvbUV2ZW50IH0gZnJvbSAnLi4vLi4vZW5naW5lJztcbmltcG9ydCB7IE5hdkNvbnRyb2xsZXIgfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XG5pbXBvcnQge1xuICBJb25CdXR0b24sXG4gIElvbkl0ZW0sXG4gIElvbkxhYmVsLFxuICBJb25MaXN0LFxuICBJb25Db250ZW50LFxuICBJb25JY29uLFxuICBJb25MaXN0SGVhZGVyLFxuICBJb25Qb3BvdmVyLFxuICBJb25JdGVtU2xpZGluZyxcbiAgSW9uSXRlbU9wdGlvbnMsXG4gIElvbkl0ZW1PcHRpb25cbn0gZnJvbSAnQGlvbmljL2FuZ3VsYXIvc3RhbmRhbG9uZSc7XG5pbXBvcnQgKiBhcyBBbGxJY29ucyBmcm9tICdpb25pY29ucy9pY29ucyc7XG5pbXBvcnQgeyBhZGRJY29ucyB9IGZyb20gJ2lvbmljb25zJztcbmltcG9ydCB7IFRyYW5zbGF0ZVBpcGUgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcblxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBIGNvbXBvbmVudCBmb3IgZGlzcGxheWluZyBhIGxpc3QgaXRlbSB3aXRoIHZhcmlvdXMgY3VzdG9taXphdGlvbiBvcHRpb25zLlxuICogQHN1bW1hcnkgVGhlIExpc3RJdGVtQ29tcG9uZW50IGlzIGFuIEFuZ3VsYXIgY29tcG9uZW50IHRoYXQgZXh0ZW5kcyBOZ3hCYXNlQ29tcG9uZW50LiBJdCBwcm92aWRlcyBhIGZsZXhpYmxlIGFuZCBjdXN0b21pemFibGUgbGlzdCBpdGVtIGludGVyZmFjZSB3aXRoIHN1cHBvcnQgZm9yIGljb25zLCBidXR0b25zLCBhbmQgdmFyaW91cyB0ZXh0IGVsZW1lbnRzLiBUaGUgY29tcG9uZW50IGFsc28gaGFuZGxlcyBhY3Rpb25zIGFuZCBuYXZpZ2F0aW9uIGJhc2VkIG9uIHVzZXIgaW50ZXJhY3Rpb25zLlxuICpcbiAqIEBjbGFzc1xuICogQGV4dGVuZHMgTmd4QmFzZUNvbXBvbmVudFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbGluZXM9J25vbmUnXSAtIERldGVybWluZXMgdGhlIGxpbmUgc3R5bGUgb2YgdGhlIGl0ZW0uIENhbiBiZSAnaW5zZXQnLCAnaW5zZWV0Jywgb3IgJ25vbmUnLlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBpdGVtIC0gVGhlIGRhdGEgaXRlbSB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIGxpc3QgaXRlbS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpY29uIC0gVGhlIG5hbWUgb2YgdGhlIGljb24gdG8gYmUgZGlzcGxheWVkLlxuICogQHBhcmFtIHsnc3RhcnQnIHwgJ2VuZCd9IFtpY29uU2xvdD0nc3RhcnQnXSAtIFRoZSBwb3NpdGlvbiBvZiB0aGUgaWNvbiB3aXRoaW4gdGhlIGl0ZW0uXG4gKiBAcGFyYW0ge1N0cmluZ09yQm9vbGVhbn0gW2J1dHRvbj10cnVlXSAtIERldGVybWluZXMgaWYgdGhlIGl0ZW0gc2hvdWxkIGJlaGF2ZSBhcyBhIGJ1dHRvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbdGl0bGVdIC0gVGhlIG1haW4gdGl0bGUgb2YgdGhlIGxpc3QgaXRlbS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZGVzY3JpcHRpb25dIC0gQSBkZXNjcmlwdGlvbiBmb3IgdGhlIGxpc3QgaXRlbS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbaW5mb10gLSBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIGZvciB0aGUgbGlzdCBpdGVtLlxuICogQHBhcmFtIHtzdHJpbmd9IFtzdWJpbmZvXSAtIFN1Yi1pbmZvcm1hdGlvbiBmb3IgdGhlIGxpc3QgaXRlbS5cbiAqXG4gKiBAZXhhbXBsZVxuICogPG5neC1kZWNhZi1saXN0LWl0ZW1cbiAqICAgW2l0ZW1dPVwiZGF0YUl0ZW1cIlxuICogICBpY29uPVwic3RhclwiXG4gKiAgIHRpdGxlPVwiSXRlbSBUaXRsZVwiXG4gKiAgIGRlc2NyaXB0aW9uPVwiSXRlbSBEZXNjcmlwdGlvblwiXG4gKiAgIChjbGlja0V2ZW50KT1cImhhbmRsZUl0ZW1DbGljaygkZXZlbnQpXCI+XG4gKiA8L25neC1kZWNhZi1saXN0LWl0ZW0+XG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFxuICogICBwYXJ0aWNpcGFudCBWIGFzIFZpZXdcbiAqICAgcGFydGljaXBhbnQgVSBhcyBVc2VyXG4gKiAgIEMtPj5WOiBJbml0aWFsaXplIGNvbXBvbmVudFxuICogICBWLT4+VTogRGlzcGxheSBsaXN0IGl0ZW1cbiAqICAgVS0+PlY6IENsaWNrIG9uIGl0ZW0gb3IgYWN0aW9uXG4gKiAgIFYtPj5DOiBUcmlnZ2VyIGhhbmRsZUFjdGlvbigpXG4gKiAgIEMtPj5DOiBQcm9jZXNzIGFjdGlvblxuICogICBDLT4+VjogVXBkYXRlIHZpZXcgb3IgbmF2aWdhdGVcbiAqL1xuQER5bmFtaWMoKVxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWRlY2FmLWxpc3QtaXRlbScsXG4gIHRlbXBsYXRlVXJsOiAnLi9saXN0LWl0ZW0uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9saXN0LWl0ZW0uY29tcG9uZW50LnNjc3MnXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIFRyYW5zbGF0ZVBpcGUsXG4gICAgSW9uTGlzdCxcbiAgICBJb25MaXN0SGVhZGVyLFxuICAgIElvbkl0ZW0sXG4gICAgSW9uSXRlbVNsaWRpbmcsXG4gICAgSW9uSXRlbU9wdGlvbnMsXG4gICAgSW9uSXRlbU9wdGlvbixcbiAgICBJb25JY29uLFxuICAgIElvbkxhYmVsLFxuICAgIElvbkJ1dHRvbixcbiAgICBJb25Db250ZW50LFxuICAgIElvblBvcG92ZXJcbiAgXVxuXG59KVxuZXhwb3J0IGNsYXNzIExpc3RJdGVtQ29tcG9uZW50IGV4dGVuZHMgTmd4QmFzZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWZlcmVuY2UgdG8gdGhlIGFjdGlvbiBtZW51IHBvcG92ZXIgY29tcG9uZW50LlxuICAgKiBAc3VtbWFyeSBWaWV3Q2hpbGQgcmVmZXJlbmNlIHRoYXQgcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBIVE1MSW9uUG9wb3ZlckVsZW1lbnRcbiAgICogdXNlZCBmb3IgZGlzcGxheWluZyBhY3Rpb24gbWVudXMuIFRoaXMgcmVmZXJlbmNlIGlzIHVzZWQgdG8gcHJvZ3JhbW1hdGljYWxseVxuICAgKiBjb250cm9sIHRoZSBwb3BvdmVyLCBzdWNoIGFzIGRpc21pc3NpbmcgaXQgd2hlbiBuZWNlc3NhcnkuXG4gICAqXG4gICAqIEB0eXBlIHtIVE1MSW9uUG9wb3ZlckVsZW1lbnR9XG4gICAqIEBtZW1iZXJPZiBMaXN0SXRlbUNvbXBvbmVudFxuICAgKi9cbiAgQFZpZXdDaGlsZCgnYWN0aW9uTWVudUNvbXBvbmVudCcpXG4gIGFjdGlvbk1lbnVDb21wb25lbnQhOiBIVE1MSW9uUG9wb3ZlckVsZW1lbnQ7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb250cm9scyB0aGUgZGlzcGxheSBvZiBsaW5lcyBhcm91bmQgdGhlIGxpc3QgaXRlbS5cbiAgICogQHN1bW1hcnkgRGV0ZXJtaW5lcyBob3cgbGluZXMgYXJlIGRpc3BsYXllZCBhcm91bmQgdGhlIGxpc3QgaXRlbSBib3JkZXJzLlxuICAgKiAnaW5zZXQnIHNob3dzIGxpbmVzIHdpdGggcGFkZGluZywgJ2Z1bGwnIHNob3dzIGZ1bGwtd2lkdGggbGluZXMsIGFuZCAnbm9uZSdcbiAgICogcmVtb3ZlcyBhbGwgbGluZXMuIFRoaXMgYWZmZWN0cyB0aGUgdmlzdWFsIHNlcGFyYXRpb24gYmV0d2VlbiBsaXN0IGl0ZW1zLlxuICAgKlxuICAgKiBAdHlwZSB7J2luc2V0JyB8ICdmdWxsJyB8ICdub25lJ31cbiAgICogQGRlZmF1bHQgJ2luc2V0J1xuICAgKiBAbWVtYmVyT2YgTGlzdEl0ZW1Db21wb25lbnRcbiAgICovXG4gIEBJbnB1dCgpXG4gIGxpbmVzOiAnaW5zZXQnIHwgJ2Z1bGwnIHwgJ25vbmUnID0gJ2Z1bGwnO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGRhdGEgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGxpc3QgaXRlbS5cbiAgICogQHN1bW1hcnkgQ29udGFpbnMgdGhlIHJhdyBkYXRhIHRoYXQgdGhpcyBsaXN0IGl0ZW0gcmVwcmVzZW50cy4gVGhpcyBvYmplY3RcbiAgICogaXMgdXNlZCB0byBleHRyYWN0IGRpc3BsYXkgaW5mb3JtYXRpb24gYW5kIGZvciBwYXNzaW5nIHRvIGV2ZW50IGhhbmRsZXJzXG4gICAqIHdoZW4gdGhlIGl0ZW0gaXMgaW50ZXJhY3RlZCB3aXRoLiBJdCBvdmVycmlkZXMgdGhlIGJhc2UgaXRlbSBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fVxuICAgKiBAbWVtYmVyT2YgTGlzdEl0ZW1Db21wb25lbnRcbiAgICovXG4gIEBJbnB1dCgpXG4gIG92ZXJyaWRlIGl0ZW0hOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBuYW1lIG9mIHRoZSBpY29uIHRvIGRpc3BsYXkgaW4gdGhlIGxpc3QgaXRlbS5cbiAgICogQHN1bW1hcnkgU3BlY2lmaWVzIHdoaWNoIGljb24gdG8gZGlzcGxheSB1c2luZyBJb25pYydzIGljb24gc3lzdGVtLlxuICAgKiBUaGUgaWNvbiBuYW1lIHNob3VsZCBjb3JyZXNwb25kIHRvIGFuIGF2YWlsYWJsZSBJb25pYyBpY29uIG9yIGEgY3VzdG9tXG4gICAqIGljb24gdGhhdCBoYXMgYmVlbiByZWdpc3RlcmVkIHdpdGggdGhlIGljb24gcmVnaXN0cnkuXG4gICAqXG4gICAqIEB0eXBlIHtzdHJpbmd9XG4gICAqIEBtZW1iZXJPZiBMaXN0SXRlbUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgaWNvbiE6IHN0cmluZztcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBvc2l0aW9uIG9mIHRoZSBpY29uIHdpdGhpbiB0aGUgbGlzdCBpdGVtLlxuICAgKiBAc3VtbWFyeSBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGljb24gYXBwZWFycyBhdCB0aGUgc3RhcnQgKGxlZnQgaW4gTFRSIGxhbmd1YWdlcylcbiAgICogb3IgZW5kIChyaWdodCBpbiBMVFIgbGFuZ3VhZ2VzKSBvZiB0aGUgbGlzdCBpdGVtLiBUaGlzIGFmZmVjdHMgdGhlIG92ZXJhbGxcbiAgICogbGF5b3V0IGFuZCB2aXN1YWwgaGllcmFyY2h5IG9mIHRoZSBpdGVtIGNvbnRlbnQuXG4gICAqXG4gICAqIEB0eXBlIHsnc3RhcnQnIHwgJ2VuZCd9XG4gICAqIEBkZWZhdWx0ICdzdGFydCdcbiAgICogQG1lbWJlck9mIExpc3RJdGVtQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKVxuICBpY29uU2xvdDogJ3N0YXJ0JyB8ICdlbmQnID0nc3RhcnQnO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ29udHJvbHMgd2hldGhlciB0aGUgbGlzdCBpdGVtIGJlaGF2ZXMgYXMgYSBjbGlja2FibGUgYnV0dG9uLlxuICAgKiBAc3VtbWFyeSBXaGVuIHNldCB0byB0cnVlLCB0aGUgbGlzdCBpdGVtIHdpbGwgaGF2ZSBidXR0b24tbGlrZSBiZWhhdmlvciBpbmNsdWRpbmdcbiAgICogaG92ZXIgZWZmZWN0cywgY2xpY2sgaGFuZGxpbmcsIGFuZCBhcHByb3ByaWF0ZSBhY2Nlc3NpYmlsaXR5IGF0dHJpYnV0ZXMuXG4gICAqIFdoZW4gZmFsc2UsIHRoZSBpdGVtIGlzIGRpc3BsYXllZCBhcyBzdGF0aWMgY29udGVudCB3aXRob3V0IGludGVyYWN0aXZlIGJlaGF2aW9yLlxuICAgKlxuICAgKiBAdHlwZSB7U3RyaW5nT3JCb29sZWFufVxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqIEBtZW1iZXJPZiBMaXN0SXRlbUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgYnV0dG9uOiBTdHJpbmdPckJvb2xlYW4gPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIG1haW4gdGl0bGUgdGV4dCBkaXNwbGF5ZWQgaW4gdGhlIGxpc3QgaXRlbS5cbiAgICogQHN1bW1hcnkgU2V0cyB0aGUgcHJpbWFyeSB0ZXh0IGNvbnRlbnQgdGhhdCBhcHBlYXJzIHByb21pbmVudGx5IGluIHRoZSBsaXN0IGl0ZW0uXG4gICAqIFRoaXMgaXMgdHlwaWNhbGx5IHRoZSBtb3N0IGltcG9ydGFudCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgaXRlbSBhbmQgaXMgZGlzcGxheWVkXG4gICAqIHdpdGggZW1waGFzaXMgaW4gdGhlIGNvbXBvbmVudCdzIHZpc3VhbCBoaWVyYXJjaHkuXG4gICAqXG4gICAqIEB0eXBlIHtzdHJpbmd9XG4gICAqIEBtZW1iZXJPZiBMaXN0SXRlbUNvbXBvbmVudFxuICAgKi9cbiAgQElucHV0KClcbiAgdGl0bGU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZWNvbmRhcnkgZGVzY3JpcHRpdmUgdGV4dCBmb3IgdGhlIGxpc3QgaXRlbS5cbiAgICogQHN1bW1hcnkgUHJvdmlkZXMgYWRkaXRpb25hbCBjb250ZXh0IG9yIGRldGFpbHMgYWJvdXQgdGhlIGl0ZW0uIFRoaXMgdGV4dFxuICAgKiBpcyB0eXBpY2FsbHkgZGlzcGxheWVkIGJlbG93IHRoZSB0aXRsZSB3aXRoIGxlc3MgdmlzdWFsIGVtcGhhc2lzLlxuICAgKiBVc2VmdWwgZm9yIHByb3ZpZGluZyBjb250ZXh0IHdpdGhvdXQgY2x1dHRlcmluZyB0aGUgbWFpbiB0aXRsZS5cbiAgICpcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICogQG1lbWJlck9mIExpc3RJdGVtQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKVxuICBkZXNjcmlwdGlvbj86IHN0cmluZztcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdGV4dCBmb3IgdGhlIGxpc3QgaXRlbS5cbiAgICogQHN1bW1hcnkgRGlzcGxheXMgc3VwcGxlbWVudGFyeSBpbmZvcm1hdGlvbiB0aGF0IHByb3ZpZGVzIGV4dHJhIGNvbnRleHRcbiAgICogYWJvdXQgdGhlIGl0ZW0uIFRoaXMgY291bGQgaW5jbHVkZSBtZXRhZGF0YSwgc3RhdHVzIGluZm9ybWF0aW9uLCBvclxuICAgKiBvdGhlciByZWxldmFudCBkZXRhaWxzIHRoYXQgZG9uJ3QgZml0IGluIHRoZSB0aXRsZSBvciBkZXNjcmlwdGlvbi5cbiAgICpcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICogQG1lbWJlck9mIExpc3RJdGVtQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKVxuICBpbmZvPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3ViLWluZm9ybWF0aW9uIHRleHQgZGlzcGxheWVkIGluIHRoZSBsaXN0IGl0ZW0uXG4gICAqIEBzdW1tYXJ5IFByb3ZpZGVzIHRlcnRpYXJ5IGxldmVsIGluZm9ybWF0aW9uIHRoYXQgY29tcGxlbWVudHMgdGhlIGluZm8gZmllbGQuXG4gICAqIFRoaXMgaXMgdHlwaWNhbGx5IHVzZWQgZm9yIGFkZGl0aW9uYWwgbWV0YWRhdGEgb3IgY29udGV4dHVhbCBkZXRhaWxzXG4gICAqIHRoYXQgYXJlIHVzZWZ1bCBidXQgbm90IGNyaXRpY2FsIGZvciB1bmRlcnN0YW5kaW5nIHRoZSBpdGVtLlxuICAgKlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKiBAbWVtYmVyT2YgTGlzdEl0ZW1Db21wb25lbnRcbiAgICovXG4gIEBJbnB1dCgpXG4gIHN1YmluZm8/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFdmVudCBlbWl0dGVyIGZvciBsaXN0IGl0ZW0gY2xpY2sgaW50ZXJhY3Rpb25zLlxuICAgKiBAc3VtbWFyeSBFbWl0cyBjdXN0b20gZXZlbnRzIHdoZW4gdGhlIGxpc3QgaXRlbSBpcyBjbGlja2VkIG9yIHdoZW4gYWN0aW9uc1xuICAgKiBhcmUgcGVyZm9ybWVkIG9uIGl0LiBUaGUgZW1pdHRlZCBldmVudCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgYWN0aW9uLFxuICAgKiB0aGUgaXRlbSBkYXRhLCBhbmQgb3RoZXIgcmVsZXZhbnQgY29udGV4dCBmb3IgcGFyZW50IGNvbXBvbmVudHMgdG8gaGFuZGxlLlxuICAgKlxuICAgKiBAdHlwZSB7RXZlbnRFbWl0dGVyPExpc3RJdGVtQ3VzdG9tRXZlbnQ+fVxuICAgKiBAbWVtYmVyT2YgTGlzdEl0ZW1Db21wb25lbnRcbiAgICovXG4gIEBPdXRwdXQoKVxuICBjbGlja0V2ZW50OiAgRXZlbnRFbWl0dGVyPExpc3RJdGVtQ3VzdG9tRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxMaXN0SXRlbUN1c3RvbUV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgc2xpZGUgaXRlbXMgYXJlIGN1cnJlbnRseSBlbmFibGVkLlxuICAgKiBAc3VtbWFyeSBDb250cm9scyB0aGUgdmlzaWJpbGl0eSBvZiBzbGlkZSBhY3Rpb25zIGJhc2VkIG9uIHNjcmVlbiBzaXplIGFuZFxuICAgKiBhdmFpbGFibGUgb3BlcmF0aW9ucy4gV2hlbiB0cnVlLCB1c2VycyBjYW4gc3dpcGUgb24gdGhlIGl0ZW0gdG8gcmV2ZWFsXG4gICAqIGFjdGlvbiBidXR0b25zIGZvciBvcGVyYXRpb25zIGxpa2UgZWRpdCBhbmQgZGVsZXRlLlxuICAgKlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQG1lbWJlck9mIExpc3RJdGVtQ29tcG9uZW50XG4gICAqL1xuICBzaG93U2xpZGVJdGVtczogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3VycmVudCB3aW5kb3cgd2lkdGggaW4gcGl4ZWxzLlxuICAgKiBAc3VtbWFyeSBTdG9yZXMgdGhlIGN1cnJlbnQgYnJvd3NlciB3aW5kb3cgd2lkdGggd2hpY2ggaXMgdXNlZCB0byBkZXRlcm1pbmVcbiAgICogcmVzcG9uc2l2ZSBiZWhhdmlvciwgc3VjaCBhcyB3aGVuIHRvIHNob3cgb3IgaGlkZSBzbGlkZSBpdGVtcyBiYXNlZCBvblxuICAgKiBzY3JlZW4gc2l6ZS4gVXBkYXRlZCBhdXRvbWF0aWNhbGx5IG9uIHdpbmRvdyByZXNpemUgZXZlbnRzLlxuICAgKlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKiBAbWVtYmVyT2YgTGlzdEl0ZW1Db21wb25lbnRcbiAgICovXG4gIHdpbmRvd1dpZHRoITogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGFjdGlvbiBtZW51IHBvcG92ZXIgaXMgY3VycmVudGx5IG9wZW4uXG4gICAqIEBzdW1tYXJ5IFRyYWNrcyB0aGUgc3RhdGUgb2YgdGhlIGFjdGlvbiBtZW51IHRvIHByZXZlbnQgbXVsdGlwbGUgaW5zdGFuY2VzXG4gICAqIGZyb20gYmVpbmcgb3BlbmVkIHNpbXVsdGFuZW91c2x5IGFuZCB0byBlbnN1cmUgcHJvcGVyIGNsZWFudXAgd2hlbiBhY3Rpb25zXG4gICAqIGFyZSBwZXJmb3JtZWQuIFVzZWQgZm9yIG1hbmFnaW5nIHRoZSBwb3BvdmVyIGxpZmVjeWNsZS5cbiAgICpcbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqIEBtZW1iZXJPZiBMaXN0SXRlbUNvbXBvbmVudFxuICAgKi9cbiAgYWN0aW9uTWVudU9wZW46IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFuZ3VsYXIgTmF2Q29udHJvbGxlciBzZXJ2aWNlIGZvciBoYW5kbGluZyBuYXZpZ2F0aW9uLlxuICAgKiBAc3VtbWFyeSBJbmplY3RlZCBzZXJ2aWNlIHRoYXQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgcHJvZ3JhbW1hdGljIG5hdmlnYXRpb25cbiAgICogd2l0aGluIHRoZSBJb25pYyBhcHBsaWNhdGlvbi4gVXNlZCBmb3IgbmF2aWdhdGluZyB0byBkaWZmZXJlbnQgcm91dGVzIHdoZW5cbiAgICogbGlzdCBpdGVtIGFjdGlvbnMgYXJlIHBlcmZvcm1lZCBvciB3aGVuIHRoZSBpdGVtIGl0c2VsZiBpcyBjbGlja2VkLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAdHlwZSB7TmF2Q29udHJvbGxlcn1cbiAgICogQG1lbWJlck9mIExpc3RJdGVtQ29tcG9uZW50XG4gICAqL1xuICBwcml2YXRlIG5hdkNvbnRyb2xsZXI6IE5hdkNvbnRyb2xsZXIgPSBpbmplY3QoTmF2Q29udHJvbGxlcik7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIExpc3RJdGVtQ29tcG9uZW50LlxuICAgKiBAc3VtbWFyeSBJbml0aWFsaXplcyBhIG5ldyBMaXN0SXRlbUNvbXBvbmVudCBieSBjYWxsaW5nIHRoZSBwYXJlbnQgY2xhc3MgY29uc3RydWN0b3JcbiAgICogd2l0aCB0aGUgY29tcG9uZW50IG5hbWUgZm9yIGxvZ2dpbmcgYW5kIGlkZW50aWZpY2F0aW9uIHB1cnBvc2VzLiBBbHNvIHJlZ2lzdGVyc1xuICAgKiBhbGwgYXZhaWxhYmxlIElvbmljIGljb25zIHRvIGVuc3VyZSB0aGV5IGNhbiBiZSBkaXNwbGF5ZWQgaW4gdGhlIGNvbXBvbmVudC5cbiAgICpcbiAgICogQG1lbWJlck9mIExpc3RJdGVtQ29tcG9uZW50XG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihcIkxpc3RJdGVtQ29tcG9uZW50XCIpO1xuICAgIGFkZEljb25zKEFsbEljb25zKVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXplcyB0aGUgY29tcG9uZW50IGFmdGVyIEFuZ3VsYXIgZmlyc3QgZGlzcGxheXMgdGhlIGRhdGEtYm91bmQgcHJvcGVydGllcy5cbiAgICogQHN1bW1hcnkgU2V0cyB1cCB0aGUgY29tcG9uZW50IGJ5IGRldGVybWluaW5nIHNsaWRlIGl0ZW0gdmlzaWJpbGl0eSwgcHJvY2Vzc2luZyBib29sZWFuIGlucHV0cyxcbiAgICogYnVpbGRpbmcgQ1NTIGNsYXNzIG5hbWVzIGJhc2VkIG9uIHByb3BlcnRpZXMsIGFuZCBjYXB0dXJpbmcgdGhlIGN1cnJlbnQgd2luZG93IHdpZHRoLlxuICAgKiBUaGlzIG1ldGhvZCBwcmVwYXJlcyB0aGUgY29tcG9uZW50IGZvciB1c2VyIGludGVyYWN0aW9uIGJ5IGVuc3VyaW5nIGFsbCBwcm9wZXJ0aWVzIGFyZVxuICAgKiBwcm9wZXJseSBpbml0aWFsaXplZCBhbmQgcmVzcG9uc2l2ZSBiZWhhdmlvciBpcyBjb25maWd1cmVkLlxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBBIGFzIEFuZ3VsYXIgTGlmZWN5Y2xlXG4gICAqICAgcGFydGljaXBhbnQgTCBhcyBMaXN0SXRlbUNvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IFcgYXMgV2luZG93XG4gICAqXG4gICAqICAgQS0+Pkw6IG5nT25Jbml0KClcbiAgICogICBMLT4+TDogZW5hYmxlU2xpZGVJdGVtcygpXG4gICAqICAgTC0+Pkw6IFByb2Nlc3MgYnV0dG9uIGJvb2xlYW5cbiAgICogICBMLT4+TDogQnVpbGQgY2xhc3NOYW1lIHdpdGggZmxleCBjbGFzc2VzXG4gICAqICAgYWx0IG9wZXJhdGlvbnMgZXhpc3RcbiAgICogICAgIEwtPj5MOiBBZGQgJ2FjdGlvbicgY2xhc3NcbiAgICogICBlbmRcbiAgICogICBMLT4+VzogZ2V0V2luZG93V2lkdGgoKVxuICAgKiAgIFctLT4+TDogUmV0dXJuIGN1cnJlbnQgd2lkdGhcbiAgICogICBMLT4+TDogU3RvcmUgd2luZG93V2lkdGhcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn1cbiAgICogQG1lbWJlck9mIExpc3RJdGVtQ29tcG9uZW50XG4gICAqL1xuICBhc3luYyBuZ09uSW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnNob3dTbGlkZUl0ZW1zID0gdGhpcy5lbmFibGVTbGlkZUl0ZW1zKCk7XG4gICAgdGhpcy5idXR0b24gPSBzdHJpbmdUb0Jvb2xlYW4odGhpcy5idXR0b24pO1xuXG4gICAgdGhpcy5jbGFzc05hbWUgPSBgJHt0aGlzLmNsYXNzTmFtZX0gIGRjZi1mbGV4IGRjZi1mbGV4LW1pZGRsZSBncmlkLWl0ZW1gO1xuICAgIGlmKHRoaXMub3BlcmF0aW9ucz8ubGVuZ3RoKVxuICAgICAgdGhpcy5jbGFzc05hbWUgKz0gYCBhY3Rpb25gO1xuICAgIHRoaXMud2luZG93V2lkdGggPSBnZXRXaW5kb3dXaWR0aCgpIGFzIG51bWJlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSGFuZGxlcyB1c2VyIGludGVyYWN0aW9ucyBhbmQgYWN0aW9ucyBwZXJmb3JtZWQgb24gdGhlIGxpc3QgaXRlbS5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2QgaXMgdGhlIGNlbnRyYWwgYWN0aW9uIGhhbmRsZXIgZm9yIGxpc3QgaXRlbSBpbnRlcmFjdGlvbnMuIEl0IG1hbmFnZXNcbiAgICogZXZlbnQgcHJvcGFnYXRpb24sIGRpc21pc3NlcyBvcGVuIGFjdGlvbiBtZW51cywgcmVtb3ZlcyBmb2N1cyB0cmFwcywgYW5kIGVpdGhlciBlbWl0c1xuICAgKiBldmVudHMgZm9yIHBhcmVudCBjb21wb25lbnRzIHRvIGhhbmRsZSBvciBwZXJmb3JtcyBuYXZpZ2F0aW9uIGJhc2VkIG9uIHRoZSBjb21wb25lbnQnc1xuICAgKiByb3V0ZSBjb25maWd1cmF0aW9uLiBUaGlzIG1ldGhvZCBzdXBwb3J0cyBib3RoIGV2ZW50LWRyaXZlbiBhbmQgbmF2aWdhdGlvbi1kcml2ZW4gYXJjaGl0ZWN0dXJlcy5cbiAgICpcbiAgICogQHBhcmFtIHtDcnVkT3BlcmF0aW9uc30gYWN0aW9uIC0gVGhlIHR5cGUgb2YgQ1JVRCBvcGVyYXRpb24gYmVpbmcgcGVyZm9ybWVkXG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IC0gVGhlIGJyb3dzZXIgZXZlbnQgdGhhdCB0cmlnZ2VyZWQgdGhlIGFjdGlvblxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBbdGFyZ2V0XSAtIE9wdGlvbmFsIHRhcmdldCBlbGVtZW50IGZvciB0aGUgZXZlbnRcbiAgICogQHJldHVybiB7UHJvbWlzZTxib29sZWFufHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBuYXZpZ2F0aW9uIHN1Y2Nlc3Mgb3Igdm9pZCBmb3IgZXZlbnRzXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IFUgYXMgVXNlclxuICAgKiAgIHBhcnRpY2lwYW50IEwgYXMgTGlzdEl0ZW1Db21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBQIGFzIFBhcmVudCBDb21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBOIGFzIE5hdkNvbnRyb2xsZXJcbiAgICogICBwYXJ0aWNpcGFudCBFIGFzIEV2ZW50IFN5c3RlbVxuICAgKlxuICAgKiAgIFUtPj5MOiBQZXJmb3JtIGFjdGlvbiAoY2xpY2svc3dpcGUpXG4gICAqICAgTC0+Pkw6IHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpXG4gICAqICAgYWx0IGFjdGlvbk1lbnVPcGVuXG4gICAqICAgICBMLT4+TDogRGlzbWlzcyBhY3Rpb24gbWVudVxuICAgKiAgIGVuZFxuICAgKiAgIEwtPj5MOiByZW1vdmVGb2N1c1RyYXAoKVxuICAgKiAgIGFsdCBObyByb3V0ZSBjb25maWd1cmVkXG4gICAqICAgICBMLT4+RTogd2luZG93RXZlbnRFbWl0dGVyKClcbiAgICogICAgIEwtPj5QOiBjbGlja0V2ZW50LmVtaXQoKVxuICAgKiAgIGVsc2UgUm91dGUgY29uZmlndXJlZFxuICAgKiAgICAgTC0+Pk46IHJlZGlyZWN0KGFjdGlvbiwgdWlkKVxuICAgKiAgICAgTi0tPj5MOiBSZXR1cm4gbmF2aWdhdGlvbiByZXN1bHRcbiAgICogICBlbmRcbiAgICpcbiAgICogQG1lbWJlck9mIExpc3RJdGVtQ29tcG9uZW50XG4gICAqL1xuICBhc3luYyBoYW5kbGVBY3Rpb24oYWN0aW9uOiBDcnVkT3BlcmF0aW9ucywgZXZlbnQ6IEV2ZW50LCB0YXJnZXQ/OiBIVE1MRWxlbWVudCk6IFByb21pc2U8Ym9vbGVhbnx2b2lkPiB7XG4gICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgaWYodGhpcy5hY3Rpb25NZW51T3BlbilcbiAgICAgIGF3YWl0IHRoaXMuYWN0aW9uTWVudUNvbXBvbmVudC5kaXNtaXNzKCk7XG4gICAgLy8gZm9yY2luZyB0cmFwIGZvY3VzXG4gICAgcmVtb3ZlRm9jdXNUcmFwKCk7XG4gICAgaWYoIXRoaXMucm91dGUpIHtcbiAgICAgIGNvbnN0IGV2ZW50ID0ge3RhcmdldDogdGFyZ2V0LCBhY3Rpb24sIHBrOiB0aGlzLnBrLCBkYXRhOiB0aGlzLnVpZCwgbmFtZTogRXZlbnRDb25zdGFudHMuQ0xJQ0ssIGNvbXBvbmVudDogdGhpcy5jb21wb25lbnROYW1lIH0gYXMgTGlzdEl0ZW1DdXN0b21FdmVudDtcbiAgICAgIHdpbmRvd0V2ZW50RW1pdHRlcihgTGlzdEl0ZW0ke0V2ZW50Q29uc3RhbnRzLkNMSUNLfWAsIGV2ZW50KTtcbiAgICAgIHJldHVybiB0aGlzLmNsaWNrRXZlbnQuZW1pdChldmVudCk7XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJlZGlyZWN0KGFjdGlvbiwgKHR5cGVvZiB0aGlzLnVpZCA9PT0gJ251bWJlcicgPyBgJHt0aGlzLnVpZH1gOiB0aGlzLnVpZCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXNwb25zaXZlIGhhbmRsZXIgdGhhdCBlbmFibGVzIG9yIGRpc2FibGVzIHNsaWRlIGl0ZW1zIGJhc2VkIG9uIHNjcmVlbiBzaXplIGFuZCBvcGVyYXRpb25zLlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBpcyBhdXRvbWF0aWNhbGx5IGNhbGxlZCB3aGVuIHRoZSB3aW5kb3cgaXMgcmVzaXplZCBhbmQgYWxzbyBkdXJpbmcgY29tcG9uZW50XG4gICAqIGluaXRpYWxpemF0aW9uLiBJdCBkZXRlcm1pbmVzIHdoZXRoZXIgc2xpZGUgYWN0aW9ucyBzaG91bGQgYmUgYXZhaWxhYmxlIGJhc2VkIG9uIHRoZSBjdXJyZW50XG4gICAqIHdpbmRvdyB3aWR0aCBhbmQgdGhlIHByZXNlbmNlIG9mIFVQREFURSBvciBERUxFVEUgb3BlcmF0aW9ucy4gU2xpZGUgaXRlbXMgYXJlIHR5cGljYWxseSBoaWRkZW5cbiAgICogb24gbGFyZ2VyIHNjcmVlbnMgd2hlcmUgdGhlcmUncyBzcGFjZSBmb3IgZGVkaWNhdGVkIGFjdGlvbiBidXR0b25zLlxuICAgKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHNsaWRlIGl0ZW1zIHNob3VsZCBiZSBzaG93biwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IFcgYXMgV2luZG93XG4gICAqICAgcGFydGljaXBhbnQgTCBhcyBMaXN0SXRlbUNvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IFUgYXMgVUlcbiAgICpcbiAgICogICBXLT4+TDogcmVzaXplIGV2ZW50XG4gICAqICAgTC0+Plc6IGdldFdpbmRvd1dpZHRoKClcbiAgICogICBXLS0+Pkw6IFJldHVybiBjdXJyZW50IHdpZHRoXG4gICAqICAgTC0+Pkw6IFN0b3JlIHdpbmRvd1dpZHRoXG4gICAqICAgYWx0IE5vIG9wZXJhdGlvbnMgT1Igd2lkdGggPiA2MzlweFxuICAgKiAgICAgTC0+PlU6IHNob3dTbGlkZUl0ZW1zID0gZmFsc2VcbiAgICogICBlbHNlIE9wZXJhdGlvbnMgaW5jbHVkZSBVUERBVEUvREVMRVRFXG4gICAqICAgICBMLT4+VTogc2hvd1NsaWRlSXRlbXMgPSB0cnVlXG4gICAqICAgZW5kXG4gICAqICAgTC0tPj5VOiBSZXR1cm4gc2hvd1NsaWRlSXRlbXMgdmFsdWVcbiAgICpcbiAgICogQG1lbWJlck9mIExpc3RJdGVtQ29tcG9uZW50XG4gICAqL1xuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgWyckZXZlbnQnXSlcbiAgZW5hYmxlU2xpZGVJdGVtcygpOiBib29sZWFuIHtcbiAgICB0aGlzLndpbmRvd1dpZHRoID0gZ2V0V2luZG93V2lkdGgoKSBhcyBudW1iZXI7XG4gICAgaWYoIXRoaXMub3BlcmF0aW9ucz8ubGVuZ3RoIHx8IHRoaXMud2luZG93V2lkdGggPiA2MzkpXG4gICAgICByZXR1cm4gdGhpcy5zaG93U2xpZGVJdGVtcyA9IGZhbHNlO1xuICAgIHRoaXMuc2hvd1NsaWRlSXRlbXMgPSB0aGlzLm9wZXJhdGlvbnMuaW5jbHVkZXMoT3BlcmF0aW9uS2V5cy5VUERBVEUpIHx8IHRoaXMub3BlcmF0aW9ucy5pbmNsdWRlcyhPcGVyYXRpb25LZXlzLkRFTEVURSk7XG4gICAgcmV0dXJuIHRoaXMuc2hvd1NsaWRlSXRlbXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFuaW1hdGVzIGFuZCByZW1vdmVzIGFuIGVsZW1lbnQgZnJvbSB0aGUgRE9NLlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBhcHBsaWVzIENTUyBhbmltYXRpb24gY2xhc3NlcyB0byBjcmVhdGUgYSBzbW9vdGggZmFkZS1vdXQgZWZmZWN0XG4gICAqIGJlZm9yZSByZW1vdmluZyB0aGUgZWxlbWVudCBmcm9tIHRoZSBET00uIFRoZSBhbmltYXRpb24gZW5oYW5jZXMgdXNlciBleHBlcmllbmNlIGJ5XG4gICAqIHByb3ZpZGluZyB2aXN1YWwgZmVlZGJhY2sgd2hlbiBpdGVtcyBhcmUgZGVsZXRlZCBvciByZW1vdmVkIGZyb20gbGlzdHMuIFRoZSB0aW1pbmdcbiAgICogaXMgY29vcmRpbmF0ZWQgd2l0aCB0aGUgQ1NTIGFuaW1hdGlvbiBkdXJhdGlvbiB0byBlbnN1cmUgdGhlIGVsZW1lbnQgaXMgcmVtb3ZlZFxuICAgKiBhZnRlciB0aGUgYW5pbWF0aW9uIGNvbXBsZXRlcy5cbiAgICpcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudCAtIFRoZSBET00gZWxlbWVudCB0byBhbmltYXRlIGFuZCByZW1vdmVcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgTCBhcyBMaXN0SXRlbUNvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IEUgYXMgSFRNTEVsZW1lbnRcbiAgICogICBwYXJ0aWNpcGFudCBEIGFzIERPTVxuICAgKlxuICAgKiAgIEwtPj5FOiBBZGQgYW5pbWF0aW9uIGNsYXNzZXNcbiAgICogICBOb3RlIG92ZXIgRTogdWstYW5pbWF0aW9uLWZhZGUsIHVrLWFuaW1hdGlvbi1tZWRpdW0sIHVrLWFuaW1hdGlvbi1yZXZlcnNlXG4gICAqICAgRS0+PkU6IFN0YXJ0IGZhZGUgYW5pbWF0aW9uXG4gICAqICAgTC0+Pkw6IHNldFRpbWVvdXQoNjAwbXMpXG4gICAqICAgTm90ZSBvdmVyIEw6IFdhaXQgZm9yIGFuaW1hdGlvbiB0byBjb21wbGV0ZVxuICAgKiAgIEwtPj5EOiBlbGVtZW50LnJlbW92ZSgpXG4gICAqICAgRC0+PkQ6IFJlbW92ZSBlbGVtZW50IGZyb20gRE9NXG4gICAqXG4gICAqIEBtZW1iZXJPZiBMaXN0SXRlbUNvbXBvbmVudFxuICAgKi9cbiAgcmVtb3ZlRWxlbWVudChlbGVtZW50OiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgndWstYW5pbWF0aW9uLWZhZGUnLCAndWstYW5pbWF0aW9uLW1lZGl1bScsICd1ay1hbmltYXRpb24tcmV2ZXJzZScpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge2VsZW1lbnQucmVtb3ZlKCl9LCA2MDApXG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIE5hdmlnYXRlcyB0byBhIG5ldyByb3V0ZSBiYXNlZCBvbiB0aGUgc3BlY2lmaWVkIGFjdGlvbiBhbmQgaXRlbSBJRC5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2QgY29uc3RydWN0cyBhIG5hdmlnYXRpb24gVVJMIHVzaW5nIHRoZSBjb21wb25lbnQncyByb3V0ZSBjb25maWd1cmF0aW9uLFxuICAgKiB0aGUgc3BlY2lmaWVkIGFjdGlvbiwgYW5kIGFuIGl0ZW0gaWRlbnRpZmllci4gSXQgdXNlcyBJb25pYydzIE5hdkNvbnRyb2xsZXIgdG8gcGVyZm9ybVxuICAgKiBmb3J3YXJkIG5hdmlnYXRpb24gd2l0aCBhcHByb3ByaWF0ZSBhbmltYXRpb25zLiBUaGlzIG1ldGhvZCBpcyB0eXBpY2FsbHkgdXNlZCBmb3JcbiAgICogQ1JVRCBvcGVyYXRpb25zIHdoZXJlIGVhY2ggYWN0aW9uIChjcmVhdGUsIHJlYWQsIHVwZGF0ZSwgZGVsZXRlKSBoYXMgaXRzIG93biByb3V0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbiAtIFRoZSBhY3Rpb24gdG8gYmUgcGVyZm9ybWVkIChlLmcuLCAnZWRpdCcsICd2aWV3JywgJ2RlbGV0ZScpXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbaWRdIC0gVGhlIHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBpdGVtIHRvIGJlIGFjdGVkIHVwb25cbiAgICogQHJldHVybiB7UHJvbWlzZTxib29sZWFuPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdHJ1ZSBpZiBuYXZpZ2F0aW9uIHdhcyBzdWNjZXNzZnVsXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEwgYXMgTGlzdEl0ZW1Db21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBOIGFzIE5hdkNvbnRyb2xsZXJcbiAgICogICBwYXJ0aWNpcGFudCBSIGFzIFJvdXRlclxuICAgKlxuICAgKiAgIEwtPj5MOiByZWRpcmVjdChhY3Rpb24sIGlkKVxuICAgKiAgIEwtPj5MOiBDb25zdHJ1Y3QgVVJMOiAve3JvdXRlfS97YWN0aW9ufS97aWR9XG4gICAqICAgTC0+Pk46IG5hdmlnYXRlRm9yd2FyZCh1cmwpXG4gICAqICAgTi0+PlI6IE5hdmlnYXRlIHRvIGNvbnN0cnVjdGVkIFVSTFxuICAgKiAgIFItLT4+TjogUmV0dXJuIG5hdmlnYXRpb24gcmVzdWx0XG4gICAqICAgTi0tPj5MOiBSZXR1cm4gYm9vbGVhbiBzdWNjZXNzXG4gICAqXG4gICAqIEBtZW1iZXJPZiBMaXN0SXRlbUNvbXBvbmVudFxuICAgKi9cbiAgYXN5bmMgcmVkaXJlY3QoYWN0aW9uOiBzdHJpbmcsIGlkPzogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMubmF2Q29udHJvbGxlci5uYXZpZ2F0ZUZvcndhcmQoYC8ke3RoaXMucm91dGV9LyR7YWN0aW9ufS8ke2lkIHx8IHRoaXMudWlkfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcmVzZW50cyB0aGUgYWN0aW9ucyBtZW51IHBvcG92ZXIgZm9yIHRoZSBsaXN0IGl0ZW0uXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIGhhbmRsZXMgdGhlIGRpc3BsYXkgb2YgYSBjb250ZXh0dWFsIGFjdGlvbiBtZW51IHdoZW4gdHJpZ2dlcmVkIGJ5IHVzZXJcbiAgICogaW50ZXJhY3Rpb24gKHR5cGljYWxseSBhIGxvbmcgcHJlc3Mgb3IgcmlnaHQtY2xpY2spLiBJdCBzdG9wcyBldmVudCBwcm9wYWdhdGlvbiB0byBwcmV2ZW50XG4gICAqIHVud2FudGVkIHNpZGUgZWZmZWN0cywgcmVtb3ZlcyBhbnkgZXhpc3RpbmcgZm9jdXMgdHJhcHMgZm9yIGFjY2Vzc2liaWxpdHksIGNvbmZpZ3VyZXMgdGhlXG4gICAqIHBvcG92ZXIgd2l0aCB0aGUgdHJpZ2dlcmluZyBldmVudCwgYW5kIG9wZW5zIHRoZSBhY3Rpb24gbWVudS4gVGhlIG1lbnUgdHlwaWNhbGx5IGNvbnRhaW5zXG4gICAqIGF2YWlsYWJsZSBDUlVEIG9wZXJhdGlvbnMgZm9yIHRoZSBpdGVtLlxuICAgKlxuICAgKiBAcGFyYW0ge0V2ZW50fSBldmVudCAtIFRoZSBldmVudCB0aGF0IHRyaWdnZXJlZCB0aGUgYWN0aW9uIG1lbnUgcmVxdWVzdFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBVIGFzIFVzZXJcbiAgICogICBwYXJ0aWNpcGFudCBMIGFzIExpc3RJdGVtQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgUCBhcyBQb3BvdmVyXG4gICAqICAgcGFydGljaXBhbnQgQSBhcyBBY2Nlc3NpYmlsaXR5XG4gICAqXG4gICAqICAgVS0+Pkw6IFRyaWdnZXIgYWN0aW9uIG1lbnUgKGxvbmcgcHJlc3MvcmlnaHQtY2xpY2spXG4gICAqICAgTC0+Pkw6IHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpXG4gICAqICAgTC0+PkE6IHJlbW92ZUZvY3VzVHJhcCgpXG4gICAqICAgTC0+PlA6IFNldCBldmVudCByZWZlcmVuY2VcbiAgICogICBMLT4+TDogYWN0aW9uTWVudU9wZW4gPSB0cnVlXG4gICAqICAgTC0+PlA6IERpc3BsYXkgcG9wb3ZlciB3aXRoIGFjdGlvbnNcbiAgICpcbiAgICogQG1lbWJlck9mIExpc3RJdGVtQ29tcG9uZW50XG4gICAqL1xuICBwcmVzZW50QWN0aW9uc01lbnUoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgLy8gZm9yY2luZyB0cmFwIGZvY3VzXG4gICAgcmVtb3ZlRm9jdXNUcmFwKCk7XG4gICAgdGhpcy5hY3Rpb25NZW51Q29tcG9uZW50LmV2ZW50ID0gZXZlbnQ7XG4gICAgdGhpcy5hY3Rpb25NZW51T3BlbiA9IHRydWU7XG4gIH1cbn1cbiIsIlxuQGlmKHRpdGxlIHx8IGRlc2NyaXB0aW9uKSB7XG4gIDxpb24taXRlbS1zbGlkaW5nICNjb21wb25lbnQ+XG4gICAgPGlvbi1pdGVtXG4gICAgICBbaWRdPVwidWlkXCJcbiAgICAgIFtsaW5lc109XCJsaW5lc1wiXG4gICAgICBbYnV0dG9uXT1cImJ1dHRvblwiXG4gICAgICBbY2xhc3NdPVwiY2xhc3NOYW1lXCJcbiAgICAgIChjbGljayk9XCJvcGVyYXRpb25zPy5pbmNsdWRlcygncmVhZCcpID8gaGFuZGxlQWN0aW9uKCdyZWFkJywgJGV2ZW50LCBjb21wb25lbnQpIDogJydcbiAgICBcIj5cbiAgICAgIEBpZihpY29uICYmIGxpbmVzICE9PSAnaW5zZXQnKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkY2YtaWNvblwiIFtzbG90XT1cImljb25TbG90XCI+XG4gICAgICAgICAgPGlvbi1hdmF0YXI+XG4gICAgICAgICAgICA8aW9uLWljb24gYXJpYS1oaWRkZW49XCJ0cnVlXCIgbmFtZT1cInJlYWRlci1vdXRsaW5lXCIgc2l6ZT1cImRlZmF1bHRcIj48L2lvbi1pY29uPlxuICAgICAgICAgIDwvaW9uLWF2YXRhcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgICA8ZGl2IGNsYXNzPVwiZGNmLXdpZHRoLWV4cGFuZFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZGNmLWZsZXggZGNmLWZsZXgtbWlkZGxlIGRjZi1ncmlkLWNvbGxhcHNlXCIgZGNmLWdyaWQ+XG4gICAgICAgICAgQGlmKGljb24gJiYgbGluZXMgPT09ICdpbnNldCcpIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkY2YtaWNvbiBkY2YtZ3JpZC1pY29uXCI+XG4gICAgICAgICAgICAgIDxpb24tYXZhdGFyPlxuICAgICAgICAgICAgICAgIDxpb24taWNvbiBhcmlhLWhpZGRlbj1cInRydWVcIiBuYW1lPVwicmVhZGVyLW91dGxpbmVcIiAgc2l6ZT1cImRlZmF1bHRcIj48L2lvbi1pY29uPlxuICAgICAgICAgICAgICA8L2lvbi1hdmF0YXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImRjZi13aWR0aC1leHBhbmRAcyBkY2Ytd2lkdGgtMS0xIGRjZi1sYWJlbFwiPlxuICAgICAgICAgICAgPGlvbi1sYWJlbCBjbGFzcz1cImRjZi1pdGVtLXRpdGxlXCIgW2lubmVySFRNTF09XCJ1aWQgKyAnIC0gJyArIHRpdGxlXCIgPjwvaW9uLWxhYmVsPlxuICAgICAgICAgICAgQGlmKGRlc2NyaXB0aW9uKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkY2YtZGVzY3JpcHRpb25cIiBbaW5uZXJIVE1MXT1cImRlc2NyaXB0aW9uXCI+PC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgQGlmKGluZm8gfHwgc3ViaW5mbykge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRjZi13aWR0aC1hdXRvQHMgZGNmLXdpZHRoLWV4cGFuZCBkY2YtaW5mbyBkY2YtZmxleCBkY2YtZmxleC1yaWdodEBzXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgQGlmKGluZm8pIHtcbiAgICAgICAgICAgICAgICA8c3BhbiAgW2lubmVySFRNTF09XCJpbmZvXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBAaWYoc3ViaW5mbykge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRjZi1zdWJpbmZvIGRjZi10ZXh0LXRydW5jYXRlXCIgW2lubmVySFRNTF09XCJzdWJpbmZvXCIgPjwvZGl2PlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGNmLXdpZHRoLWF1dG8gZGNmLWZsZXggZGNmLWZsZXgtbWlkZGxlIGRjZi1mbGV4LXJpZ2h0XCI+XG4gICAgICAgICAgICBAaWYoKG9wZXJhdGlvbnMuaW5jbHVkZXMoJ2RlbGV0ZScpIHx8IG9wZXJhdGlvbnMuaW5jbHVkZXMoJ3VwZGF0ZScpKSAmJiB1aWQpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRjZi12aXNpYmxlQG1cIiBpZD1cImRjZi1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgPGlvbi1idXR0b24gY2xhc3M9XCJkY2YtaGlkZGVuQG1cIiBzaGFwZT1cInJvdW5kXCIgZmlsbD1cImNsZWFyXCIgY29sb3I9XCJwcmltYXJ5XCIgKGNsaWNrKT1cInByZXNlbnRBY3Rpb25zTWVudSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICA8aW9uLWljb24gc2xvdD1cImljb24tb25seVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiIG5hbWU9XCJlbGxpcHNpcy12ZXJ0aWNhbC1vdXRsaW5lXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgICAgICAgICAgPGlvbi1wb3BvdmVyXG4gICAgICAgICAgICAgICAgICAjYWN0aW9uTWVudUNvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgc2lkZT1cImJvdHRvbVwiXG4gICAgICAgICAgICAgICAgICBhbGlnbm1lbnQ9XCJsZWZ0XCJcblxuICAgICAgICAgICAgICAgICAgW2lzT3Blbl09XCJhY3Rpb25NZW51T3BlblwiXG4gICAgICAgICAgICAgICAgICAoZGlkRGlzbWlzcyk9XCJhY3Rpb25NZW51T3BlbiA9IGZhbHNlXCI+XG4gICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDxpb24tY29udGVudCBjbGFzcz1cImlvbi1wYWRkaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGlvbi1saXN0IGxpbmVzPVwibm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1saXN0LWhlYWRlcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGg0IGNsYXNzPVwiZGNmLXRleHQtY2FwaXRhbGl6ZVwiIFtpbm5lckhUTUxdPVwiJ2FjdGlvbnMnIHwgdHJhbnNsYXRlXCI+PC9oND5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvaW9uLWxpc3QtaGVhZGVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAob3BlcmF0aW9uIG9mIFsndXBkYXRlJywgJ2RlbGV0ZSddOyB0cmFjayBvcGVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmKG9wZXJhdGlvbnMuaW5jbHVkZXMob3BlcmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWl0ZW0gW2J1dHRvbl09XCJ0cnVlXCIgKGNsaWNrKT1cImhhbmRsZUFjdGlvbihvcGVyYXRpb24sICRldmVudCwgY29tcG9uZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1hdmF0YXIgY2xhc3M9XCJkY2YtZmxleCBkY2YtZmxleC1taWRkbGVcIiBhcmlhLWhpZGRlbj1cInRydWVcIiBzbG90PVwic3RhcnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmKG9wZXJhdGlvbiA9PT0gJ3VwZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW9uLWljb24gY29sb3I9XCJwcmltYXJ5XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCIgbmFtZT1cImNyZWF0ZS1vdXRsaW5lXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1pY29uIGNvbG9yPVwiZGFuZ2VyXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCIgbmFtZT1cInRyYXNoXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9pb24tYXZhdGFyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlvbi1sYWJlbCBjbGFzcz1cImRjZi10ZXh0LWNhcGl0YWxpemVcIj57eyBvcGVyYXRpb24gfCB0cmFuc2xhdGUgfX08L2lvbi1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2lvbi1pdGVtPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9pb24tbGlzdD5cbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29udGVudD5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9pb24tcG9wb3Zlcj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8IS0tIEBpZihvcGVyYXRpb25zPy5sZW5ndGggJiYgdWlkKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkY2YtdmlzaWJsZUBtXCIgaWQ9XCJkY2YtYWN0aW9uc1wiPlxuICAgICAgICAgICAgICAgIEBpZihvcGVyYXRpb25zPy5pbmNsdWRlcygndXBkYXRlJykpIHtcbiAgICAgICAgICAgICAgICAgIDxpb24tYnV0dG9uIGZpbGw9XCJjbGVhclwiIHNpemU9XCJzbWFsbFwiIGNvbG9yPVwicHJpbWFyeVwiIChjbGljayk9XCJoYW5kbGVBY3Rpb24oJ3VwZGF0ZScsICBjb21wb25lbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpb24taWNvbiBhcmlhLWhpZGRlbj1cInRydWVcIiBzbG90PVwiaWNvbi1vbmx5XCIgbmFtZT1cImNyZWF0ZS1vdXRsaW5lXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgQGlmKG9wZXJhdGlvbnM/LmluY2x1ZGVzKCdkZWxldGUnKSkge1xuICAgICAgICAgICAgICAgICAgPGlvbi1idXR0b24gZmlsbD1cImNsZWFyXCIgc2l6ZT1cInNtYWxsXCIgY29sb3I9XCJkYW5nZXJcIiAoY2xpY2spPVwiaGFuZGxlQWN0aW9uKCdkZWxldGUnLCAgY29tcG9uZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWljb24gYXJpYS1oaWRkZW49XCJ0cnVlXCIgc2xvdD1cImljb24tb25seVwiIG5hbWU9XCJ0cmFzaFwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH0gLS0+XG4gICAgICAgICAgICBAaWYod2luZG93V2lkdGggPiA2MzkpIHtcbiAgICAgICAgICAgICAgPGRpdiBpZD1cImVuZFwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltzbG90PSdlbmQnXVwiPjwvbmctY29udGVudD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9pb24taXRlbT5cbiAgICBAaWYoc2hvd1NsaWRlSXRlbXMgJiYgdWlkKSB7XG4gICAgICA8aW9uLWl0ZW0tb3B0aW9ucyBzaWRlPVwiZW5kXCIgKGlvblN3aXBlKT1cIm9wZXJhdGlvbnMubGVuZ3RoID09PSAxID8gaGFuZGxlQWN0aW9uKG9wZXJhdGlvbnNbMF0sICAkZXZlbnQsIGNvbXBvbmVudCkgOiAnJ1wiPlxuICAgICAgICBAaWYob3BlcmF0aW9ucz8uaW5jbHVkZXMoJ3VwZGF0ZScpKSB7XG4gICAgICAgICAgPGlvbi1pdGVtLW9wdGlvbiBjbGFzcz1cImRjZi11cGRhdGVcIiAoY2xpY2spPVwiaGFuZGxlQWN0aW9uKCd1cGRhdGUnLCAkZXZlbnQsIGNvbXBvbmVudClcIiBbZXhwYW5kYWJsZV09XCJvcGVyYXRpb25zLmxlbmd0aCA9PT0gMVwiPlxuICAgICAgICAgICAgPGlvbi1pY29uIGFyaWEtaGlkZGVuPVwidHJ1ZVwiIHNsb3Q9XCJpY29uLW9ubHlcIiBuYW1lPVwiY3JlYXRlLW91dGxpbmVcIj48L2lvbi1pY29uPlxuICAgICAgICAgIDwvaW9uLWl0ZW0tb3B0aW9uPlxuICAgICAgICB9XG4gICAgICAgIEBpZihvcGVyYXRpb25zPy5pbmNsdWRlcygnZGVsZXRlJykpIHtcbiAgICAgICAgPGlvbi1pdGVtLW9wdGlvbiBjbGFzcz1cImRjZi0gICAgICAgICAgZGVsZXRlXCIgKGNsaWNrKT1cImhhbmRsZUFjdGlvbignZGVsZXRlJywgICRldmVudCwgY29tcG9uZW50KVwiIFtleHBhbmRhYmxlXT1cIm9wZXJhdGlvbnMubGVuZ3RoID09PSAxXCI+XG4gICAgICAgICAgICA8aW9uLWljb24gYXJpYS1oaWRkZW49XCJ0cnVlXCIgc2xvdD1cImljb24tb25seVwiIG5hbWU9XCJ0cmFzaFwiPjwvaW9uLWljb24+XG4gICAgICAgICAgPC9pb24taXRlbS1vcHRpb24+XG4gICAgICAgIH1cbiAgICAgIDwvaW9uLWl0ZW0tb3B0aW9ucz5cbiAgICB9XG4gIDwvaW9uLWl0ZW0tc2xpZGluZz5cbn1cbiJdfQ==