@decaf-ts/ui-decorators 0.5.25 → 0.5.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.
- package/LICENSE.md +173 -17
- package/README.md +20 -2
- package/dist/ui-decorators.cjs +2 -1550
- package/dist/ui-decorators.cjs.map +1 -0
- package/dist/ui-decorators.js +2 -0
- package/dist/ui-decorators.js.map +1 -0
- package/lib/esm/index.d.ts +1 -1
- package/lib/esm/index.js +2 -2
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/model/Renderable.js +1 -1
- package/lib/esm/model/Renderable.js.map +1 -0
- package/lib/esm/model/decorators.js +1 -1
- package/lib/esm/model/decorators.js.map +1 -0
- package/lib/esm/model/index.js +1 -1
- package/lib/esm/model/index.js.map +1 -0
- package/lib/esm/model/model.js +1 -1
- package/lib/esm/model/model.js.map +1 -0
- package/lib/esm/model/overrides.js +1 -1
- package/lib/esm/model/overrides.js.map +1 -0
- package/lib/esm/ui/Rendering.js +1 -1
- package/lib/esm/ui/Rendering.js.map +1 -0
- package/lib/esm/ui/constants.js +1 -1
- package/lib/esm/ui/constants.js.map +1 -0
- package/lib/esm/ui/decorators.js +1 -1
- package/lib/esm/ui/decorators.js.map +1 -0
- package/lib/esm/ui/errors.js +1 -1
- package/lib/esm/ui/errors.js.map +1 -0
- package/lib/esm/ui/handlers.js +1 -1
- package/lib/esm/ui/handlers.js.map +1 -0
- package/lib/esm/ui/index.js +1 -1
- package/lib/esm/ui/index.js.map +1 -0
- package/lib/esm/ui/interfaces.js +1 -1
- package/lib/esm/ui/interfaces.js.map +1 -0
- package/lib/esm/ui/types.d.ts +0 -1
- package/lib/esm/ui/types.js +1 -1
- package/lib/esm/ui/types.js.map +1 -0
- package/lib/esm/ui/utils.js +1 -1
- package/lib/esm/ui/utils.js.map +1 -0
- package/lib/index.cjs +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js.map +1 -0
- package/lib/model/Renderable.cjs +1 -1
- package/lib/model/Renderable.js.map +1 -0
- package/lib/model/decorators.cjs +1 -1
- package/lib/model/decorators.js.map +1 -0
- package/lib/model/index.cjs +1 -1
- package/lib/model/index.js.map +1 -0
- package/lib/model/model.cjs +1 -1
- package/lib/model/model.js.map +1 -0
- package/lib/model/overrides.cjs +1 -1
- package/lib/model/overrides.js.map +1 -0
- package/lib/ui/Rendering.cjs +1 -1
- package/lib/ui/Rendering.js.map +1 -0
- package/lib/ui/constants.cjs +1 -1
- package/lib/ui/constants.js.map +1 -0
- package/lib/ui/decorators.cjs +1 -1
- package/lib/ui/decorators.js.map +1 -0
- package/lib/ui/errors.cjs +1 -1
- package/lib/ui/errors.js.map +1 -0
- package/lib/ui/handlers.cjs +1 -1
- package/lib/ui/handlers.js.map +1 -0
- package/lib/ui/index.cjs +1 -1
- package/lib/ui/index.js.map +1 -0
- package/lib/ui/interfaces.cjs +1 -1
- package/lib/ui/interfaces.js.map +1 -0
- package/lib/ui/types.cjs +1 -1
- package/lib/ui/types.d.ts +0 -1
- package/lib/ui/types.js.map +1 -0
- package/lib/ui/utils.cjs +1 -1
- package/lib/ui/utils.js.map +1 -0
- package/package.json +14 -22
- package/dist/ui-decorators.esm.cjs +0 -1519
package/dist/ui-decorators.cjs
CHANGED
|
@@ -1,1550 +1,2 @@
|
|
|
1
|
-
(function (global, factory) {
|
|
2
|
-
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', '@decaf-ts/decorator-validation', '@decaf-ts/reflection', '@decaf-ts/db-decorators', 'reflect-metadata'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["ui-decorators"] = {}, global.decoratorValidation, global.reflection, global.dbDecorators));
|
|
5
|
-
})(this, (function (exports, decoratorValidation, reflection, dbDecorators) { 'use strict';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @description Constants and enums for UI rendering and validation
|
|
9
|
-
* @summary Defines keys, mappings, and HTML5 input types for UI components
|
|
10
|
-
* This module provides constants used throughout the UI decorators library for
|
|
11
|
-
* rendering, validation, and HTML element generation.
|
|
12
|
-
* @module ui/constants
|
|
13
|
-
* @memberOf module:ui-decorators
|
|
14
|
-
*/
|
|
15
|
-
exports.UIMediaBreakPoints = void 0;
|
|
16
|
-
(function (UIMediaBreakPoints) {
|
|
17
|
-
UIMediaBreakPoints["SMALL"] = "s";
|
|
18
|
-
UIMediaBreakPoints["MEDIUM"] = "m";
|
|
19
|
-
UIMediaBreakPoints["LARGE"] = "l";
|
|
20
|
-
UIMediaBreakPoints["XLARGE"] = "xl";
|
|
21
|
-
})(exports.UIMediaBreakPoints || (exports.UIMediaBreakPoints = {}));
|
|
22
|
-
/**
|
|
23
|
-
* @description Key constants used for UI metadata and rendering
|
|
24
|
-
* @summary Collection of string constants used as keys for UI-related metadata
|
|
25
|
-
* These keys are used throughout the library to store and retrieve metadata related to
|
|
26
|
-
* UI models, elements, properties, and validation rules.
|
|
27
|
-
*
|
|
28
|
-
* @typedef {Object} UIKeysType
|
|
29
|
-
* @property {string} REFLECT - Base reflection key for UI metadata
|
|
30
|
-
* @property {string} UIMODEL - Key for UI model metadata
|
|
31
|
-
* @property {string} RENDERED_BY - Key for specifying rendering engine
|
|
32
|
-
* @property {string} ELEMENT - Key for element metadata
|
|
33
|
-
* @property {string} PROP - Key for property metadata
|
|
34
|
-
* @property {string} NAME - Key for name attribute
|
|
35
|
-
* @property {string} NAME_PREFIX - Prefix for input names
|
|
36
|
-
* @property {string} CUSTOM_PROPS - Key for custom validation properties
|
|
37
|
-
* @property {string} UILISTITEM - Key for list item metadata
|
|
38
|
-
* @property {string} UILISTPROP - Key for list property metadata
|
|
39
|
-
* @property {string} TYPE - Key for type metadata
|
|
40
|
-
* @property {string} SUB_TYPE - Key for subtype metadata
|
|
41
|
-
* @property {string} HIDDEN - Key for hidden attribute
|
|
42
|
-
* @property {string} FORMAT - Key for format metadata
|
|
43
|
-
* @property {string} READ_ONLY - Key for readonly attribute
|
|
44
|
-
* @property {string} REQUIRED - Key for required validation
|
|
45
|
-
* @property {string} MIN - Key for minimum value validation
|
|
46
|
-
* @property {string} MIN_LENGTH - Key for minimum length validation
|
|
47
|
-
* @property {string} MAX - Key for maximum value validation
|
|
48
|
-
* @property {string} MAX_LENGTH - Key for maximum length validation
|
|
49
|
-
* @property {string} PATTERN - Key for pattern validation
|
|
50
|
-
* @property {string} URL - Key for URL validation
|
|
51
|
-
* @property {string} STEP - Key for step validation
|
|
52
|
-
* @property {string} DATE - Key for date validation
|
|
53
|
-
* @property {string} EMAIL - Key for email validation
|
|
54
|
-
* @property {string} PASSWORD - Key for password validation
|
|
55
|
-
* @property {string} EQUALS - Key for equality validation
|
|
56
|
-
* @property {string} DIFF - Key for difference validation
|
|
57
|
-
* @property {string} LESS_THAN - Key for less than validation
|
|
58
|
-
* @property {string} LESS_THAN_OR_EQUAL - Key for less than or equal validation
|
|
59
|
-
* @property {string} GREATER_THAN - Key for greater than validation
|
|
60
|
-
* @property {string} GREATER_THAN_OR_EQUAL - Key for greater than or equal validation
|
|
61
|
-
*
|
|
62
|
-
* @const UIKeys
|
|
63
|
-
* @type {UIKeysType}
|
|
64
|
-
* @readonly
|
|
65
|
-
* @memberOf module:ui-decorators
|
|
66
|
-
*/
|
|
67
|
-
const UIKeys = {
|
|
68
|
-
REFLECT: `${decoratorValidation.ModelKeys.REFLECT}.ui.`,
|
|
69
|
-
UIMODEL: "uimodel",
|
|
70
|
-
RENDERED_BY: "rendered-by",
|
|
71
|
-
ELEMENT: "element",
|
|
72
|
-
PROP: "prop",
|
|
73
|
-
CHILD: "child",
|
|
74
|
-
NAME: "name",
|
|
75
|
-
NAME_PREFIX: "input-",
|
|
76
|
-
CUSTOM_PROPS: "customValidationProps",
|
|
77
|
-
UILISTITEM: "uilistitem",
|
|
78
|
-
UILISTPROP: "listprop",
|
|
79
|
-
UILAYOUT: "uilayout",
|
|
80
|
-
UILAYOUTITEM: "uilayoutitem",
|
|
81
|
-
HANDLERS: "handlers",
|
|
82
|
-
TYPE: "type",
|
|
83
|
-
SUB_TYPE: "subtype",
|
|
84
|
-
HIDDEN: "hidden",
|
|
85
|
-
FORMAT: "format",
|
|
86
|
-
ORDER: "order",
|
|
87
|
-
READ_ONLY: "readonly",
|
|
88
|
-
REQUIRED: decoratorValidation.ValidationKeys.REQUIRED,
|
|
89
|
-
MIN: decoratorValidation.ValidationKeys.MIN,
|
|
90
|
-
MIN_LENGTH: decoratorValidation.ValidationKeys.MIN_LENGTH,
|
|
91
|
-
MAX: decoratorValidation.ValidationKeys.MAX,
|
|
92
|
-
MAX_LENGTH: decoratorValidation.ValidationKeys.MAX_LENGTH,
|
|
93
|
-
PATTERN: decoratorValidation.ValidationKeys.PATTERN,
|
|
94
|
-
URL: decoratorValidation.ValidationKeys.URL,
|
|
95
|
-
STEP: decoratorValidation.ValidationKeys.STEP,
|
|
96
|
-
DATE: decoratorValidation.ValidationKeys.DATE,
|
|
97
|
-
EMAIL: decoratorValidation.ValidationKeys.EMAIL,
|
|
98
|
-
PASSWORD: decoratorValidation.ValidationKeys.PASSWORD,
|
|
99
|
-
EQUALS: decoratorValidation.ValidationKeys.EQUALS,
|
|
100
|
-
DIFF: decoratorValidation.ValidationKeys.DIFF,
|
|
101
|
-
LESS_THAN: decoratorValidation.ValidationKeys.LESS_THAN,
|
|
102
|
-
LESS_THAN_OR_EQUAL: decoratorValidation.ValidationKeys.LESS_THAN_OR_EQUAL,
|
|
103
|
-
GREATER_THAN: decoratorValidation.ValidationKeys.GREATER_THAN,
|
|
104
|
-
GREATER_THAN_OR_EQUAL: decoratorValidation.ValidationKeys.GREATER_THAN_OR_EQUAL,
|
|
105
|
-
};
|
|
106
|
-
/**
|
|
107
|
-
* @description Mapping of input types to their corresponding validators
|
|
108
|
-
* @summary Maps special input types to their validator classes
|
|
109
|
-
* This constant maps input types like email, URL, date, and password to their
|
|
110
|
-
* corresponding validator classes from the decorator-validation library.
|
|
111
|
-
*
|
|
112
|
-
* @typedef {Object.<string, Constructor<Validator>>} ValidatableByTypeMap
|
|
113
|
-
* @property {Constructor<EmailValidator>} email - Validator for email inputs
|
|
114
|
-
* @property {Constructor<URLValidator>} url - Validator for URL inputs
|
|
115
|
-
* @property {Constructor<DateValidator>} date - Validator for date inputs
|
|
116
|
-
* @property {Constructor<PasswordValidator>} password - Validator for password inputs
|
|
117
|
-
*
|
|
118
|
-
* @const ValidatableByType
|
|
119
|
-
* @type {ValidatableByTypeMap}
|
|
120
|
-
* @readonly
|
|
121
|
-
* @memberOf module:ui-decorators
|
|
122
|
-
*/
|
|
123
|
-
const ValidatableByType = {
|
|
124
|
-
[UIKeys.EMAIL]: decoratorValidation.EmailValidator,
|
|
125
|
-
[UIKeys.URL]: decoratorValidation.URLValidator,
|
|
126
|
-
[UIKeys.DATE]: decoratorValidation.DateValidator,
|
|
127
|
-
[UIKeys.PASSWORD]: decoratorValidation.PasswordValidator,
|
|
128
|
-
};
|
|
129
|
-
/**
|
|
130
|
-
* @description Mapping of validation attributes to their corresponding validators
|
|
131
|
-
* @summary Maps HTML validation attributes to their validator classes
|
|
132
|
-
* This constant maps HTML validation attributes like required, min, max, pattern, etc.
|
|
133
|
-
* to their corresponding validator classes from the decorator-validation library.
|
|
134
|
-
*
|
|
135
|
-
* @typedef {Object.<string, Constructor<Validator>>} ValidatableByAttributeMap
|
|
136
|
-
* @property {Constructor<RequiredValidator>} required - Validator for required fields
|
|
137
|
-
* @property {Constructor<MinValidator>} min - Validator for minimum value
|
|
138
|
-
* @property {Constructor<MaxValidator>} max - Validator for maximum value
|
|
139
|
-
* @property {Constructor<StepValidator>} step - Validator for step value
|
|
140
|
-
* @property {Constructor<MinLengthValidator>} minlength - Validator for minimum length
|
|
141
|
-
* @property {Constructor<MaxLengthValidator>} maxlength - Validator for maximum length
|
|
142
|
-
* @property {Constructor<PatternValidator>} pattern - Validator for regex pattern
|
|
143
|
-
* @property {Constructor<EqualsValidator>} equals - Validator for equality
|
|
144
|
-
* @property {Constructor<DiffValidator>} diff - Validator for difference
|
|
145
|
-
* @property {Constructor<LessThanValidator>} lessthan - Validator for less than comparison
|
|
146
|
-
* @property {Constructor<LessThanOrEqualValidator>} lessthanorequal - Validator for less than or equal comparison
|
|
147
|
-
* @property {Constructor<GreaterThanValidator>} greaterthan - Validator for greater than comparison
|
|
148
|
-
* @property {Constructor<GreaterThanOrEqualValidator>} greaterthanorequal - Validator for greater than or equal comparison
|
|
149
|
-
*
|
|
150
|
-
* @const ValidatableByAttribute
|
|
151
|
-
* @type {ValidatableByAttributeMap}
|
|
152
|
-
* @readonly
|
|
153
|
-
* @memberOf module:ui-decorators
|
|
154
|
-
*/
|
|
155
|
-
const ValidatableByAttribute = {
|
|
156
|
-
[UIKeys.REQUIRED]: decoratorValidation.RequiredValidator,
|
|
157
|
-
[UIKeys.MIN]: decoratorValidation.MinValidator,
|
|
158
|
-
[UIKeys.MAX]: decoratorValidation.MaxValidator,
|
|
159
|
-
[UIKeys.STEP]: decoratorValidation.StepValidator,
|
|
160
|
-
[UIKeys.MIN_LENGTH]: decoratorValidation.MinLengthValidator,
|
|
161
|
-
[UIKeys.MAX_LENGTH]: decoratorValidation.MaxLengthValidator,
|
|
162
|
-
[UIKeys.PATTERN]: decoratorValidation.PatternValidator,
|
|
163
|
-
[UIKeys.EQUALS]: decoratorValidation.EqualsValidator,
|
|
164
|
-
[UIKeys.DIFF]: decoratorValidation.DiffValidator,
|
|
165
|
-
[UIKeys.LESS_THAN]: decoratorValidation.LessThanValidator,
|
|
166
|
-
[UIKeys.LESS_THAN_OR_EQUAL]: decoratorValidation.LessThanOrEqualValidator,
|
|
167
|
-
[UIKeys.GREATER_THAN]: decoratorValidation.GreaterThanValidator,
|
|
168
|
-
[UIKeys.GREATER_THAN_OR_EQUAL]: decoratorValidation.GreaterThanOrEqualValidator,
|
|
169
|
-
};
|
|
170
|
-
/**
|
|
171
|
-
* @description Standard date format string for HTML5 date inputs
|
|
172
|
-
* @summary Format string for HTML5 date inputs (yyyy-MM-dd)
|
|
173
|
-
* This constant defines the standard date format string used for HTML5 date inputs.
|
|
174
|
-
*
|
|
175
|
-
* @const HTML5DateFormat
|
|
176
|
-
* @type {string}
|
|
177
|
-
* @readonly
|
|
178
|
-
* @memberOf module:ui-decorators
|
|
179
|
-
*/
|
|
180
|
-
const HTML5DateFormat = "yyyy-MM-dd";
|
|
181
|
-
/**
|
|
182
|
-
* @description Collection of HTML5 input type values
|
|
183
|
-
* @summary Maps input type constants to their HTML attribute values
|
|
184
|
-
* This constant provides a mapping of input type constants to their corresponding
|
|
185
|
-
* HTML attribute values for use in form elements.
|
|
186
|
-
*
|
|
187
|
-
* @typedef {Object} HTML5InputTypesMap
|
|
188
|
-
* @property {string} BUTTON - Button input type
|
|
189
|
-
* @property {string} CHECKBOX - Checkbox input type
|
|
190
|
-
* @property {string} COLOR - Color picker input type
|
|
191
|
-
* @property {string} DATE - Date picker input type
|
|
192
|
-
* @property {string} DATETIME_LOCAL - Local datetime picker input type
|
|
193
|
-
* @property {string} EMAIL - Email input type with validation
|
|
194
|
-
* @property {string} FILE - File upload input type
|
|
195
|
-
* @property {string} HIDDEN - Hidden input type
|
|
196
|
-
* @property {string} IMAGE - Image input type
|
|
197
|
-
* @property {string} MONTH - Month picker input type
|
|
198
|
-
* @property {string} NUMBER - Numeric input type
|
|
199
|
-
* @property {string} PASSWORD - Password input type with masked text
|
|
200
|
-
* @property {string} RADIO - Radio button input type
|
|
201
|
-
* @property {string} RANGE - Range slider input type
|
|
202
|
-
* @property {string} RESET - Form reset button input type
|
|
203
|
-
* @property {string} SEARCH - Search input type
|
|
204
|
-
* @property {string} SUBMIT - Form submit button input type
|
|
205
|
-
* @property {string} TEL - Telephone number input type
|
|
206
|
-
* @property {string} TEXT - Basic text input type
|
|
207
|
-
* @property {string} TIME - Time picker input type
|
|
208
|
-
* @property {string} URL - URL input type with validation
|
|
209
|
-
* @property {string} WEEK - Week picker input type
|
|
210
|
-
*
|
|
211
|
-
* @const HTML5InputTypes
|
|
212
|
-
* @type {HTML5InputTypesMap}
|
|
213
|
-
* @readonly
|
|
214
|
-
* @memberOf module:ui-decorators
|
|
215
|
-
*/
|
|
216
|
-
const HTML5InputTypes = {
|
|
217
|
-
BUTTON: "button",
|
|
218
|
-
CHECKBOX: "checkbox",
|
|
219
|
-
COLOR: "color",
|
|
220
|
-
DATE: UIKeys.DATE,
|
|
221
|
-
DATETIME_LOCAL: "datetime-local",
|
|
222
|
-
EMAIL: UIKeys.EMAIL,
|
|
223
|
-
FILE: "file",
|
|
224
|
-
HIDDEN: "hidden",
|
|
225
|
-
IMAGE: "image",
|
|
226
|
-
MONTH: "month",
|
|
227
|
-
NUMBER: "number",
|
|
228
|
-
PASSWORD: UIKeys.PASSWORD,
|
|
229
|
-
RADIO: "radio",
|
|
230
|
-
RANGE: "range",
|
|
231
|
-
RESET: "reset",
|
|
232
|
-
SEARCH: "search",
|
|
233
|
-
SUBMIT: "submit",
|
|
234
|
-
TEL: "tel",
|
|
235
|
-
TEXT: "text",
|
|
236
|
-
TEXTAREA: 'textarea',
|
|
237
|
-
SELECT: 'select',
|
|
238
|
-
TIME: "time",
|
|
239
|
-
URL: UIKeys.URL,
|
|
240
|
-
WEEK: "week",
|
|
241
|
-
};
|
|
242
|
-
/**
|
|
243
|
-
* @description Array of HTML5 input types that use checkboxes
|
|
244
|
-
* @summary List of input types that represent checkable controls
|
|
245
|
-
* This constant defines an array of HTML5 input types that represent
|
|
246
|
-
* checkable controls (checkbox and radio).
|
|
247
|
-
*
|
|
248
|
-
* @const HTML5CheckTypes
|
|
249
|
-
* @type {string[]}
|
|
250
|
-
* @readonly
|
|
251
|
-
* @memberOf module:ui-decorators
|
|
252
|
-
*/
|
|
253
|
-
const HTML5CheckTypes = [
|
|
254
|
-
HTML5InputTypes.CHECKBOX,
|
|
255
|
-
HTML5InputTypes.RADIO,
|
|
256
|
-
];
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* @description Error thrown when a rendering operation fails
|
|
260
|
-
* @summary Specialized error for rendering failures in UI components
|
|
261
|
-
* This error is thrown when the rendering engine encounters an error while
|
|
262
|
-
* attempting to render a UI component or model.
|
|
263
|
-
*
|
|
264
|
-
* @param {string|Error} msg The error message or original error
|
|
265
|
-
*
|
|
266
|
-
* @class RenderingError
|
|
267
|
-
* @extends BaseError
|
|
268
|
-
* @category Errors
|
|
269
|
-
*
|
|
270
|
-
* @example
|
|
271
|
-
* // Throwing a rendering error
|
|
272
|
-
* try {
|
|
273
|
-
* // Rendering code that might fail
|
|
274
|
-
* if (!component.canRender()) {
|
|
275
|
-
* throw new RenderingError('Component cannot be rendered');
|
|
276
|
-
* }
|
|
277
|
-
* } catch (error) {
|
|
278
|
-
* console.error('Rendering failed:', error.message);
|
|
279
|
-
* }
|
|
280
|
-
*/
|
|
281
|
-
class RenderingError extends dbDecorators.InternalError {
|
|
282
|
-
/**
|
|
283
|
-
* @description Creates a new RenderingError instance
|
|
284
|
-
* @summary Initializes the error with a message or original error
|
|
285
|
-
* @param {string|Error} msg The error message or original error
|
|
286
|
-
*/
|
|
287
|
-
constructor(msg) {
|
|
288
|
-
super(msg, RenderingError.name);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* @function formatByType
|
|
294
|
-
*
|
|
295
|
-
* @memberOf module:ui-decorators
|
|
296
|
-
*/
|
|
297
|
-
function formatByType(type, value, ...args) {
|
|
298
|
-
if (type === UIKeys.DATE) {
|
|
299
|
-
if (!value)
|
|
300
|
-
return "";
|
|
301
|
-
const format = args.shift() || HTML5DateFormat;
|
|
302
|
-
return decoratorValidation.formatDate(new Date(value), format);
|
|
303
|
-
}
|
|
304
|
-
return value;
|
|
305
|
-
}
|
|
306
|
-
function parseValueByType(type, value, fieldProps) {
|
|
307
|
-
let result = undefined;
|
|
308
|
-
switch (type) {
|
|
309
|
-
case Array.name: {
|
|
310
|
-
const parsed = Array.isArray(value) ? value.map(v => parseValueByType(decoratorValidation.ReservedModels.STRING, v, fieldProps)) : [value];
|
|
311
|
-
result = parsed.join(",");
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
314
|
-
case HTML5InputTypes.NUMBER:
|
|
315
|
-
result = parseToNumber(value);
|
|
316
|
-
break;
|
|
317
|
-
case HTML5InputTypes.DATE: {
|
|
318
|
-
const format = fieldProps.format;
|
|
319
|
-
if (value && `${value}`.trim().length) {
|
|
320
|
-
result =
|
|
321
|
-
typeof value === decoratorValidation.ReservedModels.NUMBER
|
|
322
|
-
? new Date(value)
|
|
323
|
-
: value
|
|
324
|
-
? format
|
|
325
|
-
? decoratorValidation.parseDate(format, value)
|
|
326
|
-
: new Date(value)
|
|
327
|
-
: undefined;
|
|
328
|
-
}
|
|
329
|
-
break;
|
|
330
|
-
}
|
|
331
|
-
default:
|
|
332
|
-
result =
|
|
333
|
-
typeof value === decoratorValidation.ReservedModels.OBJECT ?
|
|
334
|
-
(Array.isArray(value) ? value.join(",") : JSON.stringify(value)) :
|
|
335
|
-
typeof value === decoratorValidation.ReservedModels.BOOLEAN ?
|
|
336
|
-
value : typeof value === decoratorValidation.ReservedModels.STRING ?
|
|
337
|
-
escapeHtml(value) : result;
|
|
338
|
-
}
|
|
339
|
-
if (typeof result === "undefined") {
|
|
340
|
-
throw new dbDecorators.InternalError(`Failed to parse value of type ${type} from ${typeof value} - ${value}`);
|
|
341
|
-
}
|
|
342
|
-
return result;
|
|
343
|
-
}
|
|
344
|
-
function parseToNumber(value) {
|
|
345
|
-
if (typeof value === "number" && !isNaN(value))
|
|
346
|
-
return value;
|
|
347
|
-
const parsed = Number(value);
|
|
348
|
-
if (!isNaN(parsed))
|
|
349
|
-
return parsed;
|
|
350
|
-
return undefined;
|
|
351
|
-
}
|
|
352
|
-
function escapeHtml(value) {
|
|
353
|
-
if (!value)
|
|
354
|
-
return value;
|
|
355
|
-
const tagsToReplace = {
|
|
356
|
-
"&": "&",
|
|
357
|
-
"<": "<",
|
|
358
|
-
">": ">",
|
|
359
|
-
};
|
|
360
|
-
return `${value}`.replace(/[&<>]/g, (tag) => {
|
|
361
|
-
return tagsToReplace[tag] || tag;
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
function revertHtml(value) {
|
|
365
|
-
const tagsToReplace = {
|
|
366
|
-
"&": "&",
|
|
367
|
-
"<": "<",
|
|
368
|
-
">": ">",
|
|
369
|
-
};
|
|
370
|
-
return `${value}`.replace(/<|>|&/g, (tag) => {
|
|
371
|
-
return tagsToReplace[tag] || tag;
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
function generateUIModelID(model) {
|
|
375
|
-
let id;
|
|
376
|
-
try {
|
|
377
|
-
id = dbDecorators.findModelId(model);
|
|
378
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
379
|
-
}
|
|
380
|
-
catch (e) {
|
|
381
|
-
id = Date.now();
|
|
382
|
-
}
|
|
383
|
-
const name = model.constructor.name;
|
|
384
|
-
return `${name}-${id}`;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* @description Abstract class for rendering UI components based on model metadata.
|
|
389
|
-
* @summary The RenderingEngine class provides a framework for converting model metadata into UI field definitions.
|
|
390
|
-
* It handles the translation of model properties to UI elements, applies validation rules, and manages different rendering flavors.
|
|
391
|
-
* This class is designed to be extended by specific rendering implementations.
|
|
392
|
-
*
|
|
393
|
-
* @template T The type of the rendering result, defaults to void
|
|
394
|
-
* @template R The type of the field definition, defaults to FieldDefinition<T>
|
|
395
|
-
*
|
|
396
|
-
* @param {string} flavour - The flavor of the rendering engine.
|
|
397
|
-
*
|
|
398
|
-
* @class RenderingEngine
|
|
399
|
-
*/
|
|
400
|
-
class RenderingEngine {
|
|
401
|
-
/**
|
|
402
|
-
* @description Cache for storing rendering engine instances or constructors.
|
|
403
|
-
* @private
|
|
404
|
-
* @static
|
|
405
|
-
*/
|
|
406
|
-
static { this.cache = {}; }
|
|
407
|
-
constructor(flavour) {
|
|
408
|
-
this.flavour = flavour;
|
|
409
|
-
/**
|
|
410
|
-
* Flag indicating whether the rendering engine has been initialized.
|
|
411
|
-
*/
|
|
412
|
-
this.initialized = false;
|
|
413
|
-
RenderingEngine.register(this);
|
|
414
|
-
console.log(`decaf's ${flavour} rendering engine loaded`);
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* @description Translates between model types and HTML input types.
|
|
418
|
-
* @summary Converts model data types to appropriate HTML input types and vice versa.
|
|
419
|
-
*
|
|
420
|
-
* @param {string} key - The key to translate.
|
|
421
|
-
* @param {boolean} [toView=true] - Direction of translation (true for model to view, false for view to model).
|
|
422
|
-
* @returns {string} The translated type.
|
|
423
|
-
*/
|
|
424
|
-
translate(key, toView = true) {
|
|
425
|
-
if (toView) {
|
|
426
|
-
switch (key) {
|
|
427
|
-
case decoratorValidation.ReservedModels.STRING:
|
|
428
|
-
return HTML5InputTypes.TEXT;
|
|
429
|
-
case decoratorValidation.ReservedModels.NUMBER:
|
|
430
|
-
case decoratorValidation.ReservedModels.BIGINT:
|
|
431
|
-
return HTML5InputTypes.NUMBER;
|
|
432
|
-
case decoratorValidation.ReservedModels.BOOLEAN:
|
|
433
|
-
return HTML5InputTypes.CHECKBOX;
|
|
434
|
-
case decoratorValidation.ReservedModels.DATE:
|
|
435
|
-
return HTML5InputTypes.DATE;
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
else {
|
|
439
|
-
switch (key) {
|
|
440
|
-
case HTML5InputTypes.SELECT:
|
|
441
|
-
case HTML5InputTypes.TEXT:
|
|
442
|
-
case HTML5InputTypes.EMAIL:
|
|
443
|
-
case HTML5InputTypes.COLOR:
|
|
444
|
-
case HTML5InputTypes.PASSWORD:
|
|
445
|
-
case HTML5InputTypes.TEL:
|
|
446
|
-
case HTML5InputTypes.URL:
|
|
447
|
-
case HTML5InputTypes.SEARCH:
|
|
448
|
-
case HTML5InputTypes.HIDDEN:
|
|
449
|
-
case HTML5InputTypes.TEXTAREA:
|
|
450
|
-
case HTML5InputTypes.RADIO:
|
|
451
|
-
return decoratorValidation.ReservedModels.STRING;
|
|
452
|
-
case HTML5InputTypes.NUMBER:
|
|
453
|
-
return decoratorValidation.ReservedModels.NUMBER;
|
|
454
|
-
case HTML5InputTypes.CHECKBOX:
|
|
455
|
-
return decoratorValidation.ReservedModels.BOOLEAN;
|
|
456
|
-
case HTML5InputTypes.DATE:
|
|
457
|
-
case HTML5InputTypes.DATETIME_LOCAL:
|
|
458
|
-
case HTML5InputTypes.TIME:
|
|
459
|
-
return decoratorValidation.ReservedModels.DATE;
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
return key;
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* @description Retrieves class decorator metadata for a model instance
|
|
466
|
-
* @summary Extracts UI-related class decorators from a model and returns them as an array
|
|
467
|
-
* This method collects metadata from various UI class decorators including @uimodel,
|
|
468
|
-
* @uilistitem, @uihandlers, and @uilayout applied to the model class.
|
|
469
|
-
*
|
|
470
|
-
* @template M Type extending Model
|
|
471
|
-
* @param {M} model - The model instance to extract metadata from
|
|
472
|
-
* @returns {UIClassMetadata[]} Array of UI class metadata objects
|
|
473
|
-
*
|
|
474
|
-
* @private
|
|
475
|
-
*/
|
|
476
|
-
getClassDecoratorsMetadata(model) {
|
|
477
|
-
return [
|
|
478
|
-
Reflect.getMetadata(RenderingEngine.key(UIKeys.UIMODEL), model.constructor) ||
|
|
479
|
-
Reflect.getMetadata(RenderingEngine.key(UIKeys.UIMODEL), decoratorValidation.Model.get(model.constructor.name)),
|
|
480
|
-
Reflect.getMetadata(RenderingEngine.key(UIKeys.UILISTITEM), model.constructor) ||
|
|
481
|
-
Reflect.getMetadata(RenderingEngine.key(UIKeys.UILISTITEM), decoratorValidation.Model.get(model.constructor.name)),
|
|
482
|
-
Reflect.getMetadata(RenderingEngine.key(UIKeys.HANDLERS), model.constructor) ||
|
|
483
|
-
Reflect.getMetadata(RenderingEngine.key(UIKeys.HANDLERS), decoratorValidation.Model.get(model.constructor.name)),
|
|
484
|
-
Reflect.getMetadata(RenderingEngine.key(UIKeys.UILAYOUT), model.constructor) ||
|
|
485
|
-
Reflect.getMetadata(RenderingEngine.key(UIKeys.UILAYOUT), decoratorValidation.Model.get(model.constructor.name)),
|
|
486
|
-
].filter(Boolean);
|
|
487
|
-
}
|
|
488
|
-
/**
|
|
489
|
-
* @description Checks if a type is validatable by its nature.
|
|
490
|
-
* @summary Determines if a given UI key represents a type that is inherently validatable.
|
|
491
|
-
*
|
|
492
|
-
* @param {string} key - The UI key to check.
|
|
493
|
-
* @returns {boolean} True if the type is validatable, false otherwise.
|
|
494
|
-
*/
|
|
495
|
-
isValidatableByType(key) {
|
|
496
|
-
return Object.keys(ValidatableByType).includes(key);
|
|
497
|
-
}
|
|
498
|
-
/**
|
|
499
|
-
* @description Checks if a type is validatable by attribute.
|
|
500
|
-
* @summary Determines if a given UI key represents a validation that can be applied as an attribute.
|
|
501
|
-
*
|
|
502
|
-
* @param {string} key - The UI key to check.
|
|
503
|
-
* @returns {boolean} True if the type is validatable by attribute, false otherwise.
|
|
504
|
-
*/
|
|
505
|
-
isValidatableByAttribute(key) {
|
|
506
|
-
return Object.keys(ValidatableByAttribute).includes(key);
|
|
507
|
-
}
|
|
508
|
-
/**
|
|
509
|
-
* @description Converts validation metadata to an attribute value.
|
|
510
|
-
* @summary Transforms validation metadata into a value suitable for use as an HTML attribute.
|
|
511
|
-
*
|
|
512
|
-
* @param {string} key - The validation key.
|
|
513
|
-
* @param {ValidationMetadata} value - The validation metadata.
|
|
514
|
-
* @returns {string | number | boolean} The converted attribute value.
|
|
515
|
-
* @throws {Error} If the given key is not validatable by attribute.
|
|
516
|
-
*/
|
|
517
|
-
toAttributeValue(key, value) {
|
|
518
|
-
if (!Object.keys(ValidatableByAttribute).includes(key))
|
|
519
|
-
throw new Error(`Invalid attribute key "${key}". Expected one of: ${Object.keys(ValidatableByAttribute).join(", ")}.`);
|
|
520
|
-
return key === UIKeys.REQUIRED ? true : value[key];
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* @description Converts a model to a field definition.
|
|
524
|
-
* @summary Processes a model instance, extracting UI-related metadata and validation rules to create a field definition.
|
|
525
|
-
*
|
|
526
|
-
* @template M Type extending Model
|
|
527
|
-
* @template T Type referencing the specific Rendering engine field properties/inputs
|
|
528
|
-
* @param {M} model - The model instance to convert.
|
|
529
|
-
* @param {Record<string, unknown>} [globalProps={}] - Global properties to apply to all child elements.
|
|
530
|
-
* @param {boolean} [generateId=true] - Flag indicating whether to populate the rendererId property.
|
|
531
|
-
* @returns {FieldDefinition<T>} A field definition object representing the UI structure of the model.
|
|
532
|
-
* @throws {RenderingError} If no UI definitions are set for the model or if there are invalid decorators.
|
|
533
|
-
*
|
|
534
|
-
* @mermaid
|
|
535
|
-
* sequenceDiagram
|
|
536
|
-
* participant C as Client
|
|
537
|
-
* participant RE as RenderingEngine
|
|
538
|
-
* participant R as Reflection
|
|
539
|
-
* participant M as Model
|
|
540
|
-
* C->>RE: toFieldDefinition(model, globalProps)
|
|
541
|
-
* RE->>R: getMetadata(UIKeys.UIMODEL, model.constructor)
|
|
542
|
-
* R-->>RE: UIModelMetadata
|
|
543
|
-
* RE->>R: getAllPropertyDecorators(model, UIKeys.REFLECT)
|
|
544
|
-
* R-->>RE: Record<string, DecoratorMetadata[]>
|
|
545
|
-
* RE->>R: getAllPropertyDecorators(model, ValidationKeys.REFLECT)
|
|
546
|
-
* R-->>RE: Record<string, DecoratorMetadata<ValidationMetadata>[]>
|
|
547
|
-
* loop For each property
|
|
548
|
-
* RE->>RE: Process UI decorators
|
|
549
|
-
* RE->>RE: Apply validation rules
|
|
550
|
-
* end
|
|
551
|
-
* RE-->>C: FieldDefinition<T>
|
|
552
|
-
*/
|
|
553
|
-
toFieldDefinition(model, globalProps = {}, generateId = true) {
|
|
554
|
-
const { inheritProps, ...globalPropsWithoutInherits } = globalProps;
|
|
555
|
-
globalProps = globalPropsWithoutInherits;
|
|
556
|
-
const classDecorators = this.getClassDecoratorsMetadata(model);
|
|
557
|
-
if (!classDecorators.length)
|
|
558
|
-
throw new RenderingError(`No ui definitions set for model ${model.constructor.name}. Did you use @uimodel?`);
|
|
559
|
-
const classDecorator = Object.assign({}, ...classDecorators, inheritProps ? inheritProps : {} // override tag and properties when it is a component that should inherit properties from its parent.
|
|
560
|
-
);
|
|
561
|
-
const { tag, props, item, handlers } = classDecorator;
|
|
562
|
-
const uiDecorators = reflection.Reflection.getAllPropertyDecorators(model, UIKeys.REFLECT);
|
|
563
|
-
let children;
|
|
564
|
-
let childProps = item?.props || {};
|
|
565
|
-
let mapper = {};
|
|
566
|
-
const getPath = (parent, prop) => {
|
|
567
|
-
return parent ? [parent, prop].join(".") : prop;
|
|
568
|
-
};
|
|
569
|
-
if (uiDecorators) {
|
|
570
|
-
const validationDecorators = reflection.Reflection.getAllPropertyDecorators(model, decoratorValidation.ValidationKeys.REFLECT);
|
|
571
|
-
for (const key in uiDecorators) {
|
|
572
|
-
const decs = uiDecorators[key];
|
|
573
|
-
const types = Object.values(decs).filter(({ key }) => [UIKeys.PROP, UIKeys.ELEMENT, UIKeys.CHILD].includes(key));
|
|
574
|
-
if (types?.length > 1)
|
|
575
|
-
throw new RenderingError(`Only one type of decoration is allowed. Please choose between @uiprop, @uichild or @uielement`);
|
|
576
|
-
const hasHideOnDecorator = decs.find(({ key }) => key === UIKeys.HIDDEN);
|
|
577
|
-
if (hasHideOnDecorator) {
|
|
578
|
-
const hasUiElementDecorator = decs.find(({ key }) => key === UIKeys.ELEMENT);
|
|
579
|
-
if (!hasUiElementDecorator)
|
|
580
|
-
throw new RenderingError(`@uielement no found in "${key}". It is required to use hiddenOn decorator.`);
|
|
581
|
-
}
|
|
582
|
-
decs.shift();
|
|
583
|
-
const sorted = decs.sort((a) => {
|
|
584
|
-
return a.key === UIKeys.ELEMENT ? -1 : 1;
|
|
585
|
-
});
|
|
586
|
-
sorted.forEach((dec) => {
|
|
587
|
-
if (!dec)
|
|
588
|
-
throw new RenderingError(`No decorator found`);
|
|
589
|
-
switch (dec.key) {
|
|
590
|
-
case UIKeys.PROP: {
|
|
591
|
-
childProps[key] = dec.props;
|
|
592
|
-
break;
|
|
593
|
-
}
|
|
594
|
-
case UIKeys.CHILD: {
|
|
595
|
-
if (!decoratorValidation.Model.isPropertyModel(model, key))
|
|
596
|
-
throw new RenderingError(`Child "${key}" must be a model.`);
|
|
597
|
-
let Clazz;
|
|
598
|
-
const submodel = model[key];
|
|
599
|
-
const constructable = typeof submodel === "object" &&
|
|
600
|
-
submodel !== null &&
|
|
601
|
-
!Array.isArray(submodel);
|
|
602
|
-
// create instance if undefined
|
|
603
|
-
if (!constructable) {
|
|
604
|
-
const clazzName = dec.props.props
|
|
605
|
-
?.name;
|
|
606
|
-
Clazz = new (decoratorValidation.Model.get(clazzName))();
|
|
607
|
-
}
|
|
608
|
-
children = children || [];
|
|
609
|
-
const childrenGlobalProps = Object.assign({}, globalProps || {}, { "model": Clazz }, {
|
|
610
|
-
inheritProps: dec.props,
|
|
611
|
-
childOf: getPath(globalProps?.childOf, key),
|
|
612
|
-
});
|
|
613
|
-
const childDefinition = this.toFieldDefinition(submodel || Clazz, // Must avoid undefined values — an instance is required to retrieve properties.
|
|
614
|
-
childrenGlobalProps, false);
|
|
615
|
-
children.push(childDefinition);
|
|
616
|
-
break;
|
|
617
|
-
}
|
|
618
|
-
case UIKeys.UILISTPROP: {
|
|
619
|
-
mapper = mapper || {};
|
|
620
|
-
if (dec.props?.name)
|
|
621
|
-
mapper[dec.props?.name] = key;
|
|
622
|
-
const props = Object.assign({}, classDecorator.props?.item || {}, item?.props || {}, dec.props?.props || {}, globalProps);
|
|
623
|
-
childProps = {
|
|
624
|
-
tag: item?.tag || props.render || "",
|
|
625
|
-
props: Object.assign({}, childProps?.props, { mapper }, props),
|
|
626
|
-
};
|
|
627
|
-
break;
|
|
628
|
-
}
|
|
629
|
-
case UIKeys.HIDDEN:
|
|
630
|
-
case UIKeys.ORDER:
|
|
631
|
-
case UIKeys.UILAYOUTITEM:
|
|
632
|
-
case UIKeys.ELEMENT: {
|
|
633
|
-
children = children || [];
|
|
634
|
-
const uiProps = dec.props;
|
|
635
|
-
const props = Object.assign({}, childProps?.props, uiProps.props || {}, (uiProps?.props?.name ? {
|
|
636
|
-
path: getPath(globalProps?.childOf, uiProps.props.name),
|
|
637
|
-
childOf: undefined, // The childOf prop is passed by globalProps when it is a nested prop
|
|
638
|
-
} : {}), globalProps);
|
|
639
|
-
const childDefinition = {
|
|
640
|
-
tag: uiProps.tag || childProps?.tag || tag || "",
|
|
641
|
-
props,
|
|
642
|
-
};
|
|
643
|
-
if (dec.key === UIKeys.ELEMENT) {
|
|
644
|
-
const validationDecs = validationDecorators[key];
|
|
645
|
-
const typeDec = validationDecs.shift();
|
|
646
|
-
for (const dec of validationDecs) {
|
|
647
|
-
if (this.isValidatableByAttribute(dec.key)) {
|
|
648
|
-
childDefinition.props[this.translate(dec.key)] = this.toAttributeValue(dec.key, dec.props);
|
|
649
|
-
continue;
|
|
650
|
-
}
|
|
651
|
-
if (this.isValidatableByType(dec.key)) {
|
|
652
|
-
if (dec.key === HTML5InputTypes.DATE) {
|
|
653
|
-
childDefinition.props[UIKeys.FORMAT] = dec.props.format || HTML5DateFormat;
|
|
654
|
-
}
|
|
655
|
-
childDefinition.props[UIKeys.TYPE] = dec.key;
|
|
656
|
-
continue;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
if (!childDefinition.props[UIKeys.TYPE]) {
|
|
660
|
-
const basicType = typeDec.props.name;
|
|
661
|
-
childDefinition.props[UIKeys.TYPE] = this.translate(basicType.toLowerCase(), true);
|
|
662
|
-
}
|
|
663
|
-
childDefinition.props.value = formatByType(childDefinition.props[UIKeys.TYPE], model[key], childDefinition.props[UIKeys.FORMAT]);
|
|
664
|
-
children.push(childDefinition);
|
|
665
|
-
}
|
|
666
|
-
else {
|
|
667
|
-
const child = children.find(c => c.props?.name === key || dec.key === UIKeys.UILAYOUTITEM && c?.props?.childOf === key);
|
|
668
|
-
if (child) {
|
|
669
|
-
if (dec.key !== UIKeys.UILAYOUTITEM) {
|
|
670
|
-
child.props = Object.assign({}, child.props, { [dec.key]: uiProps });
|
|
671
|
-
}
|
|
672
|
-
else {
|
|
673
|
-
const { row, col, props } = dec.props;
|
|
674
|
-
child.props = Object.assign({}, props || {}, child.props, row, col);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
else {
|
|
678
|
-
children.push(childDefinition);
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
break;
|
|
682
|
-
}
|
|
683
|
-
default:
|
|
684
|
-
throw new RenderingError(`Invalid key: ${dec.key}`);
|
|
685
|
-
}
|
|
686
|
-
});
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
globalProps = Object.assign({}, props, globalProps, {
|
|
690
|
-
handlers: handlers || {},
|
|
691
|
-
});
|
|
692
|
-
const operation = globalProps?.operation;
|
|
693
|
-
children = children?.sort((a, b) => ((a?.props?.order ?? 0) - (b?.props?.order ?? 0)))
|
|
694
|
-
.filter((item) => {
|
|
695
|
-
const hiddenOn = (item?.props?.hidden || []);
|
|
696
|
-
if (!hiddenOn?.length)
|
|
697
|
-
return item;
|
|
698
|
-
if (!hiddenOn.includes(operation))
|
|
699
|
-
return item;
|
|
700
|
-
});
|
|
701
|
-
const result = {
|
|
702
|
-
tag: tag,
|
|
703
|
-
item: childProps,
|
|
704
|
-
props: globalProps,
|
|
705
|
-
children: children,
|
|
706
|
-
};
|
|
707
|
-
if (generateId)
|
|
708
|
-
result.rendererId = generateUIModelID(model);
|
|
709
|
-
return result;
|
|
710
|
-
}
|
|
711
|
-
/**
|
|
712
|
-
* @description Registers a rendering engine instance.
|
|
713
|
-
* @summary Adds a rendering engine to the static cache and sets it as the current engine.
|
|
714
|
-
*
|
|
715
|
-
* @param {RenderingEngine<unknown, unknown>} engine - The rendering engine to register.
|
|
716
|
-
* @throws {InternalError} If an engine with the same flavor already exists.
|
|
717
|
-
*
|
|
718
|
-
* @static
|
|
719
|
-
*/
|
|
720
|
-
static register(engine) {
|
|
721
|
-
if (engine.flavour in this.cache)
|
|
722
|
-
throw new dbDecorators.InternalError(`Rendering engine under ${engine.flavour} already exists`);
|
|
723
|
-
this.cache[engine.flavour] = engine;
|
|
724
|
-
this.current = engine;
|
|
725
|
-
}
|
|
726
|
-
/**
|
|
727
|
-
* @description Retrieves or initializes a rendering engine.
|
|
728
|
-
* @summary Gets an existing engine instance or creates and initializes a new one if given a constructor.
|
|
729
|
-
*
|
|
730
|
-
* @template O The type of the rendering engine output
|
|
731
|
-
* @param {Constructor<RenderingEngine<O>> | RenderingEngine<O>} obj - The engine instance or constructor.
|
|
732
|
-
* @returns {RenderingEngine<O>} The initialized rendering engine.
|
|
733
|
-
*
|
|
734
|
-
* @private
|
|
735
|
-
* @static
|
|
736
|
-
*/
|
|
737
|
-
static getOrBoot(obj) {
|
|
738
|
-
if (obj instanceof RenderingEngine)
|
|
739
|
-
return obj;
|
|
740
|
-
const engine = new obj();
|
|
741
|
-
engine.initialize(); // make the booting async. use the initialized flag to control it
|
|
742
|
-
return engine;
|
|
743
|
-
}
|
|
744
|
-
/**
|
|
745
|
-
* @description Retrieves a rendering engine by flavor.
|
|
746
|
-
* @summary Gets the current rendering engine or a specific one by flavor.
|
|
747
|
-
*
|
|
748
|
-
* @template O The type of the rendering engine output
|
|
749
|
-
* @param {string} [flavour] - The flavor of the rendering engine to retrieve.
|
|
750
|
-
* @returns {RenderingEngine<O>} The requested rendering engine.
|
|
751
|
-
* @throws {InternalError} If the requested flavor does not exist.
|
|
752
|
-
*
|
|
753
|
-
* @static
|
|
754
|
-
*/
|
|
755
|
-
static get(flavour) {
|
|
756
|
-
if (!flavour)
|
|
757
|
-
return this.getOrBoot(this.current);
|
|
758
|
-
if (!(flavour in this.cache))
|
|
759
|
-
throw new dbDecorators.InternalError(`Rendering engine under ${flavour} does not exist`);
|
|
760
|
-
return this.getOrBoot(this.cache[flavour]);
|
|
761
|
-
}
|
|
762
|
-
/**
|
|
763
|
-
* @description Renders a model using the appropriate rendering engine.
|
|
764
|
-
* @summary Determines the correct rendering engine for a model and invokes its render method.
|
|
765
|
-
*
|
|
766
|
-
* @template M Type extending Model
|
|
767
|
-
* @param {M} model - The model to render.
|
|
768
|
-
* @param {...any[]} args - Additional arguments to pass to the render method.
|
|
769
|
-
* @returns {any} The result of the rendering process.
|
|
770
|
-
* @throws {InternalError} If no registered model is found.
|
|
771
|
-
*
|
|
772
|
-
* @static
|
|
773
|
-
*/
|
|
774
|
-
static render(model, ...args) {
|
|
775
|
-
const constructor = decoratorValidation.Model.get(model.constructor.name) || decoratorValidation.Model.fromObject(model);
|
|
776
|
-
if (!constructor)
|
|
777
|
-
throw new dbDecorators.InternalError("No model registered found");
|
|
778
|
-
const flavour = Reflect.getMetadata(RenderingEngine.key(UIKeys.RENDERED_BY), constructor);
|
|
779
|
-
// @ts-expect-error for the var args type check
|
|
780
|
-
return RenderingEngine.get(flavour).render(model, ...args);
|
|
781
|
-
}
|
|
782
|
-
/**
|
|
783
|
-
* @description Generates a metadata key for UI-related properties.
|
|
784
|
-
* @summary Prefixes a given key with the UI reflection prefix.
|
|
785
|
-
*
|
|
786
|
-
* @param {string} key - The key to prefix.
|
|
787
|
-
* @returns {string} The prefixed key.
|
|
788
|
-
*
|
|
789
|
-
* @static
|
|
790
|
-
*/
|
|
791
|
-
static key(key) {
|
|
792
|
-
return `${UIKeys.REFLECT}${key}`;
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
/**
|
|
797
|
-
* @description Decorator that tags a class as a UI model
|
|
798
|
-
* @summary Adds rendering capabilities to a model class by providing a render method
|
|
799
|
-
* This decorator applies metadata to the class that enables it to be rendered by the UI rendering engine.
|
|
800
|
-
* The model will be rendered with the specified tag and properties.
|
|
801
|
-
*
|
|
802
|
-
* @param {string} [tag] The HTML tag to use when rendering this model (defaults to class name)
|
|
803
|
-
* @param {Record<string, any>} [props] Additional properties to pass to the rendered element
|
|
804
|
-
* @return {Function} A class decorator function
|
|
805
|
-
*
|
|
806
|
-
* @function uimodel
|
|
807
|
-
* @category Class Decorators
|
|
808
|
-
*
|
|
809
|
-
* @example
|
|
810
|
-
* // Basic usage with default tag (class name)
|
|
811
|
-
* @uimodel()
|
|
812
|
-
* class UserProfile extends Model {
|
|
813
|
-
* @attribute()
|
|
814
|
-
* name: string;
|
|
815
|
-
*
|
|
816
|
-
* @attribute()
|
|
817
|
-
* email: string;
|
|
818
|
-
* }
|
|
819
|
-
*
|
|
820
|
-
* // Usage with custom tag and properties
|
|
821
|
-
* @uimodel('div', { class: 'user-card' })
|
|
822
|
-
* class UserCard extends Model {
|
|
823
|
-
* @attribute()
|
|
824
|
-
* username: string;
|
|
825
|
-
* }
|
|
826
|
-
*
|
|
827
|
-
* @mermaid
|
|
828
|
-
* sequenceDiagram
|
|
829
|
-
* participant System
|
|
830
|
-
* participant uimodel
|
|
831
|
-
* participant constructor
|
|
832
|
-
* participant instance
|
|
833
|
-
* System->>uimodel:do(constructor)
|
|
834
|
-
* uimodel->>constructor: Executes the constructor
|
|
835
|
-
* constructor->>uimodel: returns instance
|
|
836
|
-
* uimodel->>instance: adds the render method
|
|
837
|
-
* uimodel->>System: returns UIModel instance
|
|
838
|
-
*/
|
|
839
|
-
function uimodel(tag, props) {
|
|
840
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
841
|
-
return (original, propertyKey) => {
|
|
842
|
-
const meta = {
|
|
843
|
-
tag: tag || original.name,
|
|
844
|
-
props: props,
|
|
845
|
-
};
|
|
846
|
-
return reflection.metadata(RenderingEngine.key(UIKeys.UIMODEL), meta)(original);
|
|
847
|
-
};
|
|
848
|
-
}
|
|
849
|
-
/**
|
|
850
|
-
* @description Decorator that specifies which rendering engine to use for a model
|
|
851
|
-
* @summary Associates a model with a specific rendering engine implementation
|
|
852
|
-
* This decorator allows you to override the default rendering engine for a specific model class,
|
|
853
|
-
* enabling different rendering strategies for different models.
|
|
854
|
-
*
|
|
855
|
-
* @param {string} engine The name of the rendering engine to use
|
|
856
|
-
* @return {Function} A class decorator function
|
|
857
|
-
*
|
|
858
|
-
* @function renderedBy
|
|
859
|
-
* @category Class Decorators
|
|
860
|
-
*
|
|
861
|
-
* @example
|
|
862
|
-
* // Specify a custom rendering engine for a model
|
|
863
|
-
* @uimodel()
|
|
864
|
-
* @renderedBy('react')
|
|
865
|
-
* class ReactComponent extends Model {
|
|
866
|
-
* @attribute()
|
|
867
|
-
* title: string;
|
|
868
|
-
* }
|
|
869
|
-
*
|
|
870
|
-
* @mermaid
|
|
871
|
-
* sequenceDiagram
|
|
872
|
-
* participant System
|
|
873
|
-
* participant renderedBy
|
|
874
|
-
* participant Model
|
|
875
|
-
* participant RenderingEngine
|
|
876
|
-
* System->>renderedBy: apply to Model
|
|
877
|
-
* renderedBy->>Model: adds engine metadata
|
|
878
|
-
* Model->>RenderingEngine: uses specified engine
|
|
879
|
-
* RenderingEngine->>System: renders with custom engine
|
|
880
|
-
*/
|
|
881
|
-
function renderedBy(engine) {
|
|
882
|
-
return reflection.apply(reflection.metadata(RenderingEngine.key(UIKeys.RENDERED_BY), engine));
|
|
883
|
-
}
|
|
884
|
-
/**
|
|
885
|
-
* @description Decorator that tags a model as a list item for UI rendering
|
|
886
|
-
* @summary Specifies how a model should be rendered when displayed in a list context
|
|
887
|
-
* This decorator applies metadata to the class that enables it to be rendered as a list item
|
|
888
|
-
* by the UI rendering engine. The model will be rendered with the specified tag and properties
|
|
889
|
-
* when it appears in a list.
|
|
890
|
-
*
|
|
891
|
-
* @param {string} [tag] The HTML tag to use when rendering this model as a list item (defaults to class name)
|
|
892
|
-
* @param {Record<string, any>} [props] Additional properties to pass to the rendered list item element
|
|
893
|
-
* @return {Function} A class decorator function
|
|
894
|
-
*
|
|
895
|
-
* @function uilistitem
|
|
896
|
-
* @category Class Decorators
|
|
897
|
-
*
|
|
898
|
-
* @example
|
|
899
|
-
* // Basic usage with default tag (class name)
|
|
900
|
-
* @uimodel()
|
|
901
|
-
* @uilistitem()
|
|
902
|
-
* class TodoItem extends Model {
|
|
903
|
-
* @attribute()
|
|
904
|
-
* title: string;
|
|
905
|
-
*
|
|
906
|
-
* @attribute()
|
|
907
|
-
* completed: boolean;
|
|
908
|
-
* }
|
|
909
|
-
*
|
|
910
|
-
* // Usage with custom tag and properties
|
|
911
|
-
* @uimodel()
|
|
912
|
-
* @uilistitem('li', { class: 'list-group-item' })
|
|
913
|
-
* class ListItem extends Model {
|
|
914
|
-
* @attribute()
|
|
915
|
-
* text: string;
|
|
916
|
-
* }
|
|
917
|
-
*
|
|
918
|
-
* @mermaid
|
|
919
|
-
* sequenceDiagram
|
|
920
|
-
* participant System
|
|
921
|
-
* participant uilistitem
|
|
922
|
-
* participant Model
|
|
923
|
-
* participant RenderingEngine
|
|
924
|
-
* System->>uilistitem: apply to Model
|
|
925
|
-
* uilistitem->>Model: adds list item metadata
|
|
926
|
-
* Model->>RenderingEngine: uses list item metadata when in list context
|
|
927
|
-
* RenderingEngine->>System: renders with list item styling
|
|
928
|
-
*/
|
|
929
|
-
function uilistitem(tag, props) {
|
|
930
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
931
|
-
return (original, propertyKey) => {
|
|
932
|
-
const meta = {
|
|
933
|
-
item: {
|
|
934
|
-
tag: tag || original.name,
|
|
935
|
-
props: props,
|
|
936
|
-
},
|
|
937
|
-
};
|
|
938
|
-
return reflection.metadata(RenderingEngine.key(UIKeys.UILISTITEM), meta)(original);
|
|
939
|
-
};
|
|
940
|
-
}
|
|
941
|
-
/**
|
|
942
|
-
* @description Decorator that adds event handlers to a UI model
|
|
943
|
-
* @summary Specifies event handlers that should be attached to the rendered model
|
|
944
|
-
* This decorator allows you to define event handlers that will be automatically
|
|
945
|
-
* attached to the rendered UI element. The handlers are passed as properties
|
|
946
|
-
* to the rendering engine.
|
|
947
|
-
*
|
|
948
|
-
* @param {Record<string, any>} [props] Object containing event handler functions and other properties
|
|
949
|
-
* @return {Function} A class decorator function
|
|
950
|
-
*
|
|
951
|
-
* @function uihandlers
|
|
952
|
-
* @category Class Decorators
|
|
953
|
-
*
|
|
954
|
-
* @example
|
|
955
|
-
* // Add event handlers to a model
|
|
956
|
-
* @uimodel('button')
|
|
957
|
-
* @uihandlers({
|
|
958
|
-
* onClick: (event) => console.log('Button clicked'),
|
|
959
|
-
* onMouseOver: (event) => console.log('Mouse over button'),
|
|
960
|
-
* disabled: false
|
|
961
|
-
* })
|
|
962
|
-
* class ClickableButton extends Model {
|
|
963
|
-
* @attribute()
|
|
964
|
-
* label: string;
|
|
965
|
-
* }
|
|
966
|
-
*
|
|
967
|
-
* // Add form submission handlers
|
|
968
|
-
* @uimodel('form')
|
|
969
|
-
* @uihandlers({
|
|
970
|
-
* onSubmit: (event) => {
|
|
971
|
-
* event.preventDefault();
|
|
972
|
-
* console.log('Form submitted');
|
|
973
|
-
* },
|
|
974
|
-
* onReset: (event) => console.log('Form reset')
|
|
975
|
-
* })
|
|
976
|
-
* class ContactForm extends Model {
|
|
977
|
-
* @attribute()
|
|
978
|
-
* email: string;
|
|
979
|
-
* }
|
|
980
|
-
*
|
|
981
|
-
* @mermaid
|
|
982
|
-
* sequenceDiagram
|
|
983
|
-
* participant System
|
|
984
|
-
* participant uihandlers
|
|
985
|
-
* participant Model
|
|
986
|
-
* participant RenderingEngine
|
|
987
|
-
* participant UI
|
|
988
|
-
* System->>uihandlers: apply to Model
|
|
989
|
-
* uihandlers->>Model: adds handler metadata
|
|
990
|
-
* Model->>RenderingEngine: requests rendering with handlers
|
|
991
|
-
* RenderingEngine->>UI: renders element with event handlers attached
|
|
992
|
-
* UI->>Model: triggers handlers on events
|
|
993
|
-
*/
|
|
994
|
-
function uihandlers(props) {
|
|
995
|
-
return (original) => {
|
|
996
|
-
const meta = {
|
|
997
|
-
handlers: props
|
|
998
|
-
};
|
|
999
|
-
return reflection.metadata(RenderingEngine.key(UIKeys.HANDLERS), meta)(original);
|
|
1000
|
-
};
|
|
1001
|
-
}
|
|
1002
|
-
/**
|
|
1003
|
-
* @description Decorator that creates a layout container with grid specifications
|
|
1004
|
-
* @summary Combines UI model functionality with layout grid configuration
|
|
1005
|
-
* This decorator creates a UI model that acts as a layout container with specified
|
|
1006
|
-
* column and row configurations. It's a convenience decorator that combines
|
|
1007
|
-
* @uimodel with layout-specific properties for responsive grid layouts.
|
|
1008
|
-
*
|
|
1009
|
-
* @param {string} tag The HTML tag to use for the layout container
|
|
1010
|
-
* @param {number} [cols=1] Number of columns in the grid layout
|
|
1011
|
-
* @param {number|string[]} [rows=1] Number of rows or array of row definitions
|
|
1012
|
-
* @param {UIMediaBreakPoints} [breakpoint='m'] Media breakpoint for responsive behavior
|
|
1013
|
-
* @return {Function} A class decorator function
|
|
1014
|
-
*
|
|
1015
|
-
* @function uilayout
|
|
1016
|
-
* @category Class Decorators
|
|
1017
|
-
*
|
|
1018
|
-
* @example
|
|
1019
|
-
* // Create a simple 2-column layout
|
|
1020
|
-
* @uilayout('div', 2, 3)
|
|
1021
|
-
* class TwoColumnLayout extends Model {
|
|
1022
|
-
* @attribute()
|
|
1023
|
-
* @uilayoutitem(1, 1)
|
|
1024
|
-
* header: string;
|
|
1025
|
-
*
|
|
1026
|
-
* @attribute()
|
|
1027
|
-
* @uilayoutitem(1, 2)
|
|
1028
|
-
* leftContent: string;
|
|
1029
|
-
*
|
|
1030
|
-
* @attribute()
|
|
1031
|
-
* @uilayoutitem(2, 2)
|
|
1032
|
-
* rightContent: string;
|
|
1033
|
-
* }
|
|
1034
|
-
*
|
|
1035
|
-
* // Create a responsive layout with custom breakpoint
|
|
1036
|
-
* @uilayout('section', 3, 2, 'l')
|
|
1037
|
-
* class ResponsiveLayout extends Model {
|
|
1038
|
-
* @attribute()
|
|
1039
|
-
* @uilayoutitem(1, 1)
|
|
1040
|
-
* title: string;
|
|
1041
|
-
*
|
|
1042
|
-
* @attribute()
|
|
1043
|
-
* @uilayoutitem(2, 1)
|
|
1044
|
-
* subtitle: string;
|
|
1045
|
-
* }
|
|
1046
|
-
*
|
|
1047
|
-
* @mermaid
|
|
1048
|
-
* sequenceDiagram
|
|
1049
|
-
* participant System
|
|
1050
|
-
* participant uilayout
|
|
1051
|
-
* participant uimodel
|
|
1052
|
-
* participant Model
|
|
1053
|
-
* participant RenderingEngine
|
|
1054
|
-
* System->>uilayout: apply to Model
|
|
1055
|
-
* uilayout->>uimodel: call with layout props
|
|
1056
|
-
* uimodel->>Model: adds model metadata with layout config
|
|
1057
|
-
* Model->>RenderingEngine: requests rendering as layout container
|
|
1058
|
-
* RenderingEngine->>System: renders grid layout with specified dimensions
|
|
1059
|
-
*/
|
|
1060
|
-
function uilayout(tag, cols = 1, rows = 1, breakpoint = exports.UIMediaBreakPoints.MEDIUM) {
|
|
1061
|
-
return (original, propertyKey) => {
|
|
1062
|
-
return uimodel(tag, { cols, rows, breakpoint })(original, propertyKey);
|
|
1063
|
-
};
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
/**
|
|
1067
|
-
* @description Module that extends the Model prototype with rendering capabilities
|
|
1068
|
-
* @summary Adds the render method to all Model instances from decorator-validation
|
|
1069
|
-
* This module implements the Renderable interface for the Model class by adding a render method
|
|
1070
|
-
* to its prototype. This allows any Model instance to be rendered using the RenderingEngine.
|
|
1071
|
-
* @module model/overrides
|
|
1072
|
-
* @memberOf module:ui-decorators/model
|
|
1073
|
-
*/
|
|
1074
|
-
/**
|
|
1075
|
-
* @description Renders the model using the appropriate rendering engine
|
|
1076
|
-
* @summary Delegates rendering to the RenderingEngine based on model metadata
|
|
1077
|
-
* This method implements the render method from the Renderable interface for all Model instances.
|
|
1078
|
-
* It uses the RenderingEngine to determine how to render the model based on its metadata.
|
|
1079
|
-
*
|
|
1080
|
-
* @template M Type of the model being rendered
|
|
1081
|
-
* @param {any[]} args Additional arguments to pass to the rendering engine
|
|
1082
|
-
* @return {any} The rendered output in the format determined by the rendering engine
|
|
1083
|
-
*/
|
|
1084
|
-
decoratorValidation.Model.prototype.render = function (...args) {
|
|
1085
|
-
return RenderingEngine.render(this, ...args);
|
|
1086
|
-
};
|
|
1087
|
-
|
|
1088
|
-
/**
|
|
1089
|
-
* @description Decorator that hides a property during specific CRUD operations
|
|
1090
|
-
* @summary Controls property visibility based on operation type
|
|
1091
|
-
* This decorator allows you to specify which CRUD operations should hide a property
|
|
1092
|
-
* in the UI. The property will only be visible during operations not specified.
|
|
1093
|
-
*
|
|
1094
|
-
* @param operations - The CRUD operations during which the property should be hidden
|
|
1095
|
-
* @return {Function} A property decorator function
|
|
1096
|
-
*
|
|
1097
|
-
* @function hideOn
|
|
1098
|
-
* @category Property Decorators
|
|
1099
|
-
*
|
|
1100
|
-
* @example
|
|
1101
|
-
* // Hide the password field during READ operations
|
|
1102
|
-
* class User {
|
|
1103
|
-
* @attribute()
|
|
1104
|
-
* username: string;
|
|
1105
|
-
*
|
|
1106
|
-
* @attribute()
|
|
1107
|
-
* @hideOn(OperationKeys.READ)
|
|
1108
|
-
* password: string;
|
|
1109
|
-
* }
|
|
1110
|
-
*
|
|
1111
|
-
* @mermaid
|
|
1112
|
-
* sequenceDiagram
|
|
1113
|
-
* participant Model
|
|
1114
|
-
* participant hideOn
|
|
1115
|
-
* participant RenderingEngine
|
|
1116
|
-
* participant UI
|
|
1117
|
-
* Model->>hideOn: Apply to property
|
|
1118
|
-
* hideOn->>Model: Add hidden metadata
|
|
1119
|
-
* RenderingEngine->>Model: Check if property should be hidden
|
|
1120
|
-
* Model->>RenderingEngine: Return hidden operations
|
|
1121
|
-
* RenderingEngine->>UI: Render or hide based on current operation
|
|
1122
|
-
*/
|
|
1123
|
-
function hideOn(...operations) {
|
|
1124
|
-
return decoratorValidation.propMetadata(RenderingEngine.key(UIKeys.HIDDEN), operations);
|
|
1125
|
-
}
|
|
1126
|
-
/**
|
|
1127
|
-
* @description Decorator that sets the order of a UI element
|
|
1128
|
-
* @summary Specifies the rendering order for UI components
|
|
1129
|
-
* This decorator applies metadata to the property or class, indicating its order in the UI rendering sequence.
|
|
1130
|
-
*
|
|
1131
|
-
* @param {number} [order=1] The order value for the UI element (default is 1)
|
|
1132
|
-
* @return {Function} A property or class decorator function
|
|
1133
|
-
*
|
|
1134
|
-
* @function uiorder
|
|
1135
|
-
* @category Property Decorators
|
|
1136
|
-
*
|
|
1137
|
-
* @example
|
|
1138
|
-
* // Set order for a field
|
|
1139
|
-
* @uiorder(2)
|
|
1140
|
-
* fieldName: string;
|
|
1141
|
-
*
|
|
1142
|
-
* // Set order for a class
|
|
1143
|
-
* @uiorder(1)
|
|
1144
|
-
* class UserProfile { ... }
|
|
1145
|
-
*
|
|
1146
|
-
* @mermaid
|
|
1147
|
-
* sequenceDiagram
|
|
1148
|
-
* participant System
|
|
1149
|
-
* participant uiorder
|
|
1150
|
-
* participant property
|
|
1151
|
-
* System->>uiorder:do(property)
|
|
1152
|
-
* uiorder->>property: sets order metadata
|
|
1153
|
-
* uiorder->>System: returns decorated property
|
|
1154
|
-
*/
|
|
1155
|
-
function uiorder(order = 1) {
|
|
1156
|
-
return decoratorValidation.propMetadata(RenderingEngine.key(UIKeys.ORDER), order);
|
|
1157
|
-
}
|
|
1158
|
-
/**
|
|
1159
|
-
* @description Decorator that completely hides a property in all UI operations
|
|
1160
|
-
* @summary Makes a property invisible in all CRUD operations
|
|
1161
|
-
* This decorator is a convenience wrapper around hideOn that hides a property
|
|
1162
|
-
* during all CRUD operations (CREATE, READ, UPDATE, DELETE).
|
|
1163
|
-
*
|
|
1164
|
-
* @return {Function} A property decorator function
|
|
1165
|
-
*
|
|
1166
|
-
* @function hidden
|
|
1167
|
-
* @category Property Decorators
|
|
1168
|
-
*
|
|
1169
|
-
* @example
|
|
1170
|
-
* // Completely hide the internalId field in the UI
|
|
1171
|
-
* class Product {
|
|
1172
|
-
* @attribute()
|
|
1173
|
-
* name: string;
|
|
1174
|
-
*
|
|
1175
|
-
* @attribute()
|
|
1176
|
-
* @hidden()
|
|
1177
|
-
* internalId: string;
|
|
1178
|
-
* }
|
|
1179
|
-
*
|
|
1180
|
-
* @mermaid
|
|
1181
|
-
* sequenceDiagram
|
|
1182
|
-
* participant Model
|
|
1183
|
-
* participant hidden
|
|
1184
|
-
* participant hideOn
|
|
1185
|
-
* participant RenderingEngine
|
|
1186
|
-
* Model->>hidden: Apply to property
|
|
1187
|
-
* hidden->>hideOn: Call with all operations
|
|
1188
|
-
* hideOn->>Model: Add hidden metadata
|
|
1189
|
-
* RenderingEngine->>Model: Check if property should be hidden
|
|
1190
|
-
* Model->>RenderingEngine: Return all operations
|
|
1191
|
-
* RenderingEngine->>UI: Always hide property
|
|
1192
|
-
*/
|
|
1193
|
-
function hidden() {
|
|
1194
|
-
return hideOn(dbDecorators.OperationKeys.CREATE, dbDecorators.OperationKeys.READ, dbDecorators.OperationKeys.UPDATE, dbDecorators.OperationKeys.DELETE);
|
|
1195
|
-
}
|
|
1196
|
-
/**
|
|
1197
|
-
* @description Decorator that specifies how a property should be rendered as a UI element
|
|
1198
|
-
* @summary Maps a model property to a specific UI element with custom properties
|
|
1199
|
-
* This decorator allows you to define which HTML element or component should be used
|
|
1200
|
-
* to render a specific property, along with any additional properties to pass to that element.
|
|
1201
|
-
*
|
|
1202
|
-
* @param {string} tag The HTML element or component tag name to use for rendering
|
|
1203
|
-
* @param {Record<string, any>} [props] Additional properties to pass to the element
|
|
1204
|
-
* @param {boolean} [serialize=false] Whether the property should be serialized
|
|
1205
|
-
* @return {Function} A property decorator function
|
|
1206
|
-
*
|
|
1207
|
-
* @function uielement
|
|
1208
|
-
* @category Property Decorators
|
|
1209
|
-
*
|
|
1210
|
-
* @example
|
|
1211
|
-
* // Render a property as a text input
|
|
1212
|
-
* class LoginForm {
|
|
1213
|
-
* @attribute()
|
|
1214
|
-
* @uielement('input', { type: 'text', placeholder: 'Enter username' })
|
|
1215
|
-
* username: string;
|
|
1216
|
-
*
|
|
1217
|
-
* @attribute()
|
|
1218
|
-
* @uielement('input', { type: 'password', placeholder: 'Enter password' })
|
|
1219
|
-
* password: string;
|
|
1220
|
-
*
|
|
1221
|
-
* @attribute()
|
|
1222
|
-
* @uielement('button', { class: 'btn-primary' })
|
|
1223
|
-
* submit: string = 'Login';
|
|
1224
|
-
* }
|
|
1225
|
-
*
|
|
1226
|
-
* @mermaid
|
|
1227
|
-
* sequenceDiagram
|
|
1228
|
-
* participant Model
|
|
1229
|
-
* participant uielement
|
|
1230
|
-
* participant RenderingEngine
|
|
1231
|
-
* participant UI
|
|
1232
|
-
* Model->>uielement: Apply to property
|
|
1233
|
-
* uielement->>Model: Add element metadata
|
|
1234
|
-
* RenderingEngine->>Model: Get element metadata
|
|
1235
|
-
* Model->>RenderingEngine: Return tag and props
|
|
1236
|
-
* RenderingEngine->>UI: Render with specified element
|
|
1237
|
-
*/
|
|
1238
|
-
function uielement(tag, props, serialize = false) {
|
|
1239
|
-
return (original, propertyKey) => {
|
|
1240
|
-
const metadata = {
|
|
1241
|
-
tag: tag,
|
|
1242
|
-
serialize: serialize,
|
|
1243
|
-
props: Object.assign({}, props || {}, {
|
|
1244
|
-
name: propertyKey,
|
|
1245
|
-
}),
|
|
1246
|
-
};
|
|
1247
|
-
return decoratorValidation.propMetadata(RenderingEngine.key(UIKeys.ELEMENT), metadata)(original, propertyKey);
|
|
1248
|
-
};
|
|
1249
|
-
}
|
|
1250
|
-
/**
|
|
1251
|
-
* @description Decorator that maps a model property to a UI component property
|
|
1252
|
-
* @summary Specifies how a property should be passed to a UI component
|
|
1253
|
-
* This decorator allows you to define how a model property should be mapped to
|
|
1254
|
-
* a property of the UI component when rendering. It requires the class to be
|
|
1255
|
-
* decorated with @uimodel.
|
|
1256
|
-
*
|
|
1257
|
-
* @param {string} [propName] The name of the property to pass to the component (defaults to the property key)
|
|
1258
|
-
* @param {boolean} [stringify=false] Whether to stringify the property value
|
|
1259
|
-
* @return {Function} A property decorator function
|
|
1260
|
-
*
|
|
1261
|
-
* @function uiprop
|
|
1262
|
-
* @category Property Decorators
|
|
1263
|
-
*
|
|
1264
|
-
* @example
|
|
1265
|
-
* // Map model properties to component properties
|
|
1266
|
-
* @uimodel('user-profile')
|
|
1267
|
-
* class UserProfile {
|
|
1268
|
-
* @attribute()
|
|
1269
|
-
* @uiprop() // Will be passed as 'fullName' to the component
|
|
1270
|
-
* fullName: string;
|
|
1271
|
-
*
|
|
1272
|
-
* @attribute()
|
|
1273
|
-
* @uiprop('userEmail') // Will be passed as 'userEmail' to the component
|
|
1274
|
-
* email: string;
|
|
1275
|
-
*
|
|
1276
|
-
* @attribute()
|
|
1277
|
-
* @uiprop('userData', true) // Will be passed as stringified JSON
|
|
1278
|
-
* userData: Record<string, any>;
|
|
1279
|
-
* }
|
|
1280
|
-
*
|
|
1281
|
-
* @mermaid
|
|
1282
|
-
* sequenceDiagram
|
|
1283
|
-
* participant Model
|
|
1284
|
-
* participant uiprop
|
|
1285
|
-
* participant RenderingEngine
|
|
1286
|
-
* participant Component
|
|
1287
|
-
* Model->>uiprop: Apply to property
|
|
1288
|
-
* uiprop->>Model: Add prop metadata
|
|
1289
|
-
* RenderingEngine->>Model: Get prop metadata
|
|
1290
|
-
* Model->>RenderingEngine: Return prop name and stringify flag
|
|
1291
|
-
* RenderingEngine->>Component: Pass property with specified name
|
|
1292
|
-
*/
|
|
1293
|
-
function uiprop(propName = undefined, stringify = false) {
|
|
1294
|
-
return (target, propertyKey) => {
|
|
1295
|
-
const metadata = {
|
|
1296
|
-
name: propName || propertyKey,
|
|
1297
|
-
stringify: stringify,
|
|
1298
|
-
};
|
|
1299
|
-
decoratorValidation.propMetadata(RenderingEngine.key(UIKeys.PROP), metadata)(target, propertyKey);
|
|
1300
|
-
};
|
|
1301
|
-
}
|
|
1302
|
-
/**
|
|
1303
|
-
* @description Decorator that maps a nested model property to a UI component property.
|
|
1304
|
-
* @summary Defines how a parent component should render the child model when nested.
|
|
1305
|
-
*
|
|
1306
|
-
* This decorator is used to decorate properties that are nested models.
|
|
1307
|
-
* When applied, it allows overriding the default tag of the child model with the provided one,
|
|
1308
|
-
* enabling different rendering behavior when the model acts as a child (nested)
|
|
1309
|
-
* compared to when it is rendered as the parent model.
|
|
1310
|
-
*
|
|
1311
|
-
* It requires the class to be decorated with `@uimodel`.
|
|
1312
|
-
*
|
|
1313
|
-
* @param {string} clazz The model class name to pass to the component (defaults to the property key).
|
|
1314
|
-
* @param {string} tag The HTML element or component tag name to override the UI tag of the nested model
|
|
1315
|
-
* @param {Record<string, any>} [props] Additional properties to pass to the element
|
|
1316
|
-
* @param {boolean} [serialize=false] Whether the property should be serialized
|
|
1317
|
-
* @return {Function} A property decorator function.
|
|
1318
|
-
*
|
|
1319
|
-
* @function uichild
|
|
1320
|
-
* @category Property Decorators
|
|
1321
|
-
*
|
|
1322
|
-
* @example
|
|
1323
|
-
* // Map a nested model to a component property with a different tag when nested
|
|
1324
|
-
* @uimodel('address-component')
|
|
1325
|
-
* class Address {
|
|
1326
|
-
* @attribute()
|
|
1327
|
-
* street: string;
|
|
1328
|
-
*
|
|
1329
|
-
* @attribute()
|
|
1330
|
-
* city: string;
|
|
1331
|
-
* }
|
|
1332
|
-
*
|
|
1333
|
-
* @uimodel('user-profile')
|
|
1334
|
-
* class UserProfile {
|
|
1335
|
-
* @attribute()
|
|
1336
|
-
* @uichild(Address.name, 'address-child-component')
|
|
1337
|
-
* address: Address;
|
|
1338
|
-
* }
|
|
1339
|
-
*
|
|
1340
|
-
* // In this example, the Address model has the default tag 'address-component' when rendered as a root component,
|
|
1341
|
-
* // but when used inside UserProfile, it is rendered with the overridden tag 'address-child-component'
|
|
1342
|
-
*
|
|
1343
|
-
* @mermaid
|
|
1344
|
-
* sequenceDiagram
|
|
1345
|
-
* participant Model
|
|
1346
|
-
* participant uichild
|
|
1347
|
-
* participant RenderingEngine
|
|
1348
|
-
* participant Component
|
|
1349
|
-
* Model->>uichild: Apply to property
|
|
1350
|
-
* uichild->>Model: Add child metadata
|
|
1351
|
-
* RenderingEngine->>Model: Get child metadata
|
|
1352
|
-
* Model->>RenderingEngine: Return prop name, stringify flag, and child tag override
|
|
1353
|
-
* RenderingEngine->>Component: Pass property with specified name and render with overridden tag if nested
|
|
1354
|
-
*/
|
|
1355
|
-
function uichild(clazz, tag, props = {}, isArray = false, serialize = false) {
|
|
1356
|
-
return (target, propertyKey) => {
|
|
1357
|
-
const metadata = {
|
|
1358
|
-
tag: tag,
|
|
1359
|
-
serialize: serialize,
|
|
1360
|
-
props: Object.assign({}, props || {}, {
|
|
1361
|
-
name: clazz || propertyKey,
|
|
1362
|
-
}, isArray ? { customTypes: [Array.name], multiple: true } : { multiple: props?.multiple || false }),
|
|
1363
|
-
};
|
|
1364
|
-
decoratorValidation.propMetadata(RenderingEngine.key(UIKeys.CHILD), metadata)(target, propertyKey);
|
|
1365
|
-
};
|
|
1366
|
-
}
|
|
1367
|
-
/**
|
|
1368
|
-
* @description Decorator that maps a model property to a list item component
|
|
1369
|
-
* @summary Specifies how a property should be rendered in a list context
|
|
1370
|
-
* This decorator allows you to define how a model property containing a list
|
|
1371
|
-
* should be rendered. It requires the class to be decorated with @uilistitem.
|
|
1372
|
-
*
|
|
1373
|
-
* @param {string} [propName] The name of the property to pass to the list component (defaults to the property key)
|
|
1374
|
-
* @param {Record<string, any>} [props] Additional properties to pass to the list container
|
|
1375
|
-
* @return {Function} A property decorator function
|
|
1376
|
-
*
|
|
1377
|
-
* @function uilistprop
|
|
1378
|
-
* @category Property Decorators
|
|
1379
|
-
*
|
|
1380
|
-
* @example
|
|
1381
|
-
* // Define a list property with custom rendering
|
|
1382
|
-
* @uimodel('todo-list')
|
|
1383
|
-
* class TodoList {
|
|
1384
|
-
* @attribute()
|
|
1385
|
-
* title: string;
|
|
1386
|
-
*
|
|
1387
|
-
* @attribute()
|
|
1388
|
-
* @uilistprop('items', { class: 'todo-items-container' })
|
|
1389
|
-
* items: TodoItem[];
|
|
1390
|
-
* }
|
|
1391
|
-
*
|
|
1392
|
-
* @uilistitem('li', { class: 'todo-item' })
|
|
1393
|
-
* class TodoItem extends Model {
|
|
1394
|
-
* @attribute()
|
|
1395
|
-
* text: string;
|
|
1396
|
-
*
|
|
1397
|
-
* @attribute()
|
|
1398
|
-
* completed: boolean;
|
|
1399
|
-
* }
|
|
1400
|
-
*
|
|
1401
|
-
* @mermaid
|
|
1402
|
-
* sequenceDiagram
|
|
1403
|
-
* participant Model
|
|
1404
|
-
* participant uilistprop
|
|
1405
|
-
* participant RenderingEngine
|
|
1406
|
-
* participant ListContainer
|
|
1407
|
-
* participant ListItems
|
|
1408
|
-
* Model->>uilistprop: Apply to property
|
|
1409
|
-
* uilistprop->>Model: Add list prop metadata
|
|
1410
|
-
* RenderingEngine->>Model: Get list prop metadata
|
|
1411
|
-
* Model->>RenderingEngine: Return prop name and container props
|
|
1412
|
-
* RenderingEngine->>ListContainer: Create container with props
|
|
1413
|
-
* RenderingEngine->>ListItems: Render each item using @uilistitem
|
|
1414
|
-
* ListContainer->>RenderingEngine: Return rendered list
|
|
1415
|
-
*/
|
|
1416
|
-
function uilistprop(propName = undefined, props) {
|
|
1417
|
-
return (target, propertyKey) => {
|
|
1418
|
-
const metadata = {
|
|
1419
|
-
name: propName || propertyKey,
|
|
1420
|
-
props: props || {},
|
|
1421
|
-
};
|
|
1422
|
-
decoratorValidation.propMetadata(RenderingEngine.key(UIKeys.UILISTPROP), metadata)(target, propertyKey);
|
|
1423
|
-
};
|
|
1424
|
-
}
|
|
1425
|
-
/**
|
|
1426
|
-
* @description Decorator that positions a property in a specific grid layout position
|
|
1427
|
-
* @summary Specifies the column and row position for a property in a UI layout grid
|
|
1428
|
-
* This decorator allows you to define the specific position of a property within
|
|
1429
|
-
* a grid-based layout system. It specifies which column and row the property
|
|
1430
|
-
* should occupy when rendered in the UI.
|
|
1431
|
-
*
|
|
1432
|
-
* @param {number} col The column position in the grid layout
|
|
1433
|
-
* @param {number} [row=1] The row position in the grid layout (defaults to 1)
|
|
1434
|
-
* @param {Record<string, any>} [props={}] Additional properties to pass to the layout item
|
|
1435
|
-
* @return {Function} A property decorator function
|
|
1436
|
-
*
|
|
1437
|
-
* @function uilayoutitem
|
|
1438
|
-
* @category Property Decorators
|
|
1439
|
-
*
|
|
1440
|
-
* @example
|
|
1441
|
-
* // Position properties in a grid layout
|
|
1442
|
-
* @uimodel('user-form')
|
|
1443
|
-
* class UserForm {
|
|
1444
|
-
* @attribute()
|
|
1445
|
-
* @uilayoutitem(1, 1) // First column, first row
|
|
1446
|
-
* firstName: string;
|
|
1447
|
-
*
|
|
1448
|
-
* @attribute()
|
|
1449
|
-
* @uilayoutitem(2, 1) // Second column, first row
|
|
1450
|
-
* lastName: string;
|
|
1451
|
-
*
|
|
1452
|
-
* @attribute()
|
|
1453
|
-
* @uilayoutitem(1, 2, { colspan: 2 }) // First column, second row, spans 2 columns
|
|
1454
|
-
* email: string;
|
|
1455
|
-
*
|
|
1456
|
-
* @attribute()
|
|
1457
|
-
* @uilayoutitem(1, 3, { class: 'full-width' }) // First column, third row with custom class
|
|
1458
|
-
* bio: string;
|
|
1459
|
-
* }
|
|
1460
|
-
*
|
|
1461
|
-
* @mermaid
|
|
1462
|
-
* sequenceDiagram
|
|
1463
|
-
* participant Model
|
|
1464
|
-
* participant uilayoutitem
|
|
1465
|
-
* participant RenderingEngine
|
|
1466
|
-
* participant LayoutContainer
|
|
1467
|
-
* Model->>uilayoutitem: Apply to property
|
|
1468
|
-
* uilayoutitem->>Model: Add layout item metadata
|
|
1469
|
-
* RenderingEngine->>Model: Get layout item metadata
|
|
1470
|
-
* Model->>RenderingEngine: Return column, row, and props
|
|
1471
|
-
* RenderingEngine->>LayoutContainer: Position element at grid coordinates
|
|
1472
|
-
* LayoutContainer->>RenderingEngine: Return positioned element
|
|
1473
|
-
*/
|
|
1474
|
-
function uilayoutitem(col, row = 1, props = {}) {
|
|
1475
|
-
return (target, propertyKey) => {
|
|
1476
|
-
const metadata = {
|
|
1477
|
-
name: propertyKey,
|
|
1478
|
-
col,
|
|
1479
|
-
row,
|
|
1480
|
-
props: Object.assign({}, props, { row: row ?? 1, col: col ?? 1 }),
|
|
1481
|
-
};
|
|
1482
|
-
decoratorValidation.propMetadata(RenderingEngine.key(UIKeys.UILAYOUTITEM), metadata)(target, propertyKey);
|
|
1483
|
-
};
|
|
1484
|
-
}
|
|
1485
|
-
|
|
1486
|
-
/**
|
|
1487
|
-
* @description Class representing an event handler
|
|
1488
|
-
* @summary Defines the structure for handling events in the UI decorators system
|
|
1489
|
-
* This class provides a foundation for managing and processing events that occur
|
|
1490
|
-
* within the UI components generated by the decorators.
|
|
1491
|
-
* @class EventHandler
|
|
1492
|
-
* @memberOf module:ui-decorators/ui
|
|
1493
|
-
*/
|
|
1494
|
-
class EventHandler {
|
|
1495
|
-
/**
|
|
1496
|
-
* @description Creates an instance of EventHandler
|
|
1497
|
-
* @summary Initializes a new EventHandler object
|
|
1498
|
-
* This constructor currently doesn't take any parameters, but it can be
|
|
1499
|
-
* extended in the future to accept configuration options if needed.
|
|
1500
|
-
*/
|
|
1501
|
-
constructor() { }
|
|
1502
|
-
}
|
|
1503
|
-
|
|
1504
|
-
/**
|
|
1505
|
-
* @description UI decorators module for TypeScript applications
|
|
1506
|
-
* @summary A collection of decorators and utilities for building UI components in TypeScript applications.
|
|
1507
|
-
* This module exports functionality from both the model and UI submodules, providing decorators for
|
|
1508
|
-
* rendering, component definition, and UI state management.
|
|
1509
|
-
* @module ui-decorators
|
|
1510
|
-
*/
|
|
1511
|
-
/**
|
|
1512
|
-
* @description Current package version string
|
|
1513
|
-
* @summary Stores the current package version for reference
|
|
1514
|
-
* @const VERSION
|
|
1515
|
-
* @memberOf module:ui-decorators
|
|
1516
|
-
*/
|
|
1517
|
-
const VERSION = "0.5.25";
|
|
1518
|
-
|
|
1519
|
-
exports.EventHandler = EventHandler;
|
|
1520
|
-
exports.HTML5CheckTypes = HTML5CheckTypes;
|
|
1521
|
-
exports.HTML5DateFormat = HTML5DateFormat;
|
|
1522
|
-
exports.HTML5InputTypes = HTML5InputTypes;
|
|
1523
|
-
exports.RenderingEngine = RenderingEngine;
|
|
1524
|
-
exports.RenderingError = RenderingError;
|
|
1525
|
-
exports.UIKeys = UIKeys;
|
|
1526
|
-
exports.VERSION = VERSION;
|
|
1527
|
-
exports.ValidatableByAttribute = ValidatableByAttribute;
|
|
1528
|
-
exports.ValidatableByType = ValidatableByType;
|
|
1529
|
-
exports.escapeHtml = escapeHtml;
|
|
1530
|
-
exports.formatByType = formatByType;
|
|
1531
|
-
exports.generateUIModelID = generateUIModelID;
|
|
1532
|
-
exports.hidden = hidden;
|
|
1533
|
-
exports.hideOn = hideOn;
|
|
1534
|
-
exports.parseToNumber = parseToNumber;
|
|
1535
|
-
exports.parseValueByType = parseValueByType;
|
|
1536
|
-
exports.renderedBy = renderedBy;
|
|
1537
|
-
exports.revertHtml = revertHtml;
|
|
1538
|
-
exports.uichild = uichild;
|
|
1539
|
-
exports.uielement = uielement;
|
|
1540
|
-
exports.uihandlers = uihandlers;
|
|
1541
|
-
exports.uilayout = uilayout;
|
|
1542
|
-
exports.uilayoutitem = uilayoutitem;
|
|
1543
|
-
exports.uilistitem = uilistitem;
|
|
1544
|
-
exports.uilistprop = uilistprop;
|
|
1545
|
-
exports.uimodel = uimodel;
|
|
1546
|
-
exports.uiorder = uiorder;
|
|
1547
|
-
exports.uiprop = uiprop;
|
|
1548
|
-
|
|
1549
|
-
}));
|
|
1550
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWktZGVjb3JhdG9ycy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy91aS9jb25zdGFudHMudHMiLCIuLi9zcmMvdWkvZXJyb3JzLnRzIiwiLi4vc3JjL3VpL3V0aWxzLnRzIiwiLi4vc3JjL3VpL1JlbmRlcmluZy50cyIsIi4uL3NyYy9tb2RlbC9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL21vZGVsL292ZXJyaWRlcy50cyIsIi4uL3NyYy91aS9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL3VpL2hhbmRsZXJzLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnN0YW50cyBhbmQgZW51bXMgZm9yIFVJIHJlbmRlcmluZyBhbmQgdmFsaWRhdGlvblxuICogQHN1bW1hcnkgRGVmaW5lcyBrZXlzLCBtYXBwaW5ncywgYW5kIEhUTUw1IGlucHV0IHR5cGVzIGZvciBVSSBjb21wb25lbnRzXG4gKiBUaGlzIG1vZHVsZSBwcm92aWRlcyBjb25zdGFudHMgdXNlZCB0aHJvdWdob3V0IHRoZSBVSSBkZWNvcmF0b3JzIGxpYnJhcnkgZm9yXG4gKiByZW5kZXJpbmcsIHZhbGlkYXRpb24sIGFuZCBIVE1MIGVsZW1lbnQgZ2VuZXJhdGlvbi5cbiAqIEBtb2R1bGUgdWkvY29uc3RhbnRzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnVpLWRlY29yYXRvcnNcbiAqL1xuXG5pbXBvcnQge1xuICBDb25zdHJ1Y3RvcixcbiAgRGF0ZVZhbGlkYXRvcixcbiAgRGlmZlZhbGlkYXRvcixcbiAgRW1haWxWYWxpZGF0b3IsXG4gIEVxdWFsc1ZhbGlkYXRvcixcbiAgR3JlYXRlclRoYW5PckVxdWFsVmFsaWRhdG9yLFxuICBHcmVhdGVyVGhhblZhbGlkYXRvcixcbiAgTGVzc1RoYW5PckVxdWFsVmFsaWRhdG9yLFxuICBMZXNzVGhhblZhbGlkYXRvcixcbiAgTWF4TGVuZ3RoVmFsaWRhdG9yLFxuICBNYXhWYWxpZGF0b3IsXG4gIE1pbkxlbmd0aFZhbGlkYXRvcixcbiAgTWluVmFsaWRhdG9yLFxuICBNb2RlbEtleXMsXG4gIFBhc3N3b3JkVmFsaWRhdG9yLFxuICBQYXR0ZXJuVmFsaWRhdG9yLFxuICBSZXF1aXJlZFZhbGlkYXRvcixcbiAgU3RlcFZhbGlkYXRvcixcbiAgVVJMVmFsaWRhdG9yLFxuICBWYWxpZGF0aW9uS2V5cyxcbiAgVmFsaWRhdG9yLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cblxuXG5leHBvcnQgZW51bSBVSU1lZGlhQnJlYWtQb2ludHMgIHtcbiAgU01BTEwgPSAncycsXG4gIE1FRElVTSA9ICdtJyxcbiAgTEFSR0UgPSAnbCcsXG4gIFhMQVJHRSA9ICd4bCcsXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBLZXkgY29uc3RhbnRzIHVzZWQgZm9yIFVJIG1ldGFkYXRhIGFuZCByZW5kZXJpbmdcbiAqIEBzdW1tYXJ5IENvbGxlY3Rpb24gb2Ygc3RyaW5nIGNvbnN0YW50cyB1c2VkIGFzIGtleXMgZm9yIFVJLXJlbGF0ZWQgbWV0YWRhdGFcbiAqIFRoZXNlIGtleXMgYXJlIHVzZWQgdGhyb3VnaG91dCB0aGUgbGlicmFyeSB0byBzdG9yZSBhbmQgcmV0cmlldmUgbWV0YWRhdGEgcmVsYXRlZCB0b1xuICogVUkgbW9kZWxzLCBlbGVtZW50cywgcHJvcGVydGllcywgYW5kIHZhbGlkYXRpb24gcnVsZXMuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gVUlLZXlzVHlwZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFRkxFQ1QgLSBCYXNlIHJlZmxlY3Rpb24ga2V5IGZvciBVSSBtZXRhZGF0YVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFVJTU9ERUwgLSBLZXkgZm9yIFVJIG1vZGVsIG1ldGFkYXRhXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVOREVSRURfQlkgLSBLZXkgZm9yIHNwZWNpZnlpbmcgcmVuZGVyaW5nIGVuZ2luZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEVMRU1FTlQgLSBLZXkgZm9yIGVsZW1lbnQgbWV0YWRhdGFcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBQUk9QIC0gS2V5IGZvciBwcm9wZXJ0eSBtZXRhZGF0YVxuICogQHByb3BlcnR5IHtzdHJpbmd9IE5BTUUgLSBLZXkgZm9yIG5hbWUgYXR0cmlidXRlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTkFNRV9QUkVGSVggLSBQcmVmaXggZm9yIGlucHV0IG5hbWVzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQ1VTVE9NX1BST1BTIC0gS2V5IGZvciBjdXN0b20gdmFsaWRhdGlvbiBwcm9wZXJ0aWVzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVUlMSVNUSVRFTSAtIEtleSBmb3IgbGlzdCBpdGVtIG1ldGFkYXRhXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVUlMSVNUUFJPUCAtIEtleSBmb3IgbGlzdCBwcm9wZXJ0eSBtZXRhZGF0YVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFRZUEUgLSBLZXkgZm9yIHR5cGUgbWV0YWRhdGFcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBTVUJfVFlQRSAtIEtleSBmb3Igc3VidHlwZSBtZXRhZGF0YVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEhJRERFTiAtIEtleSBmb3IgaGlkZGVuIGF0dHJpYnV0ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IEZPUk1BVCAtIEtleSBmb3IgZm9ybWF0IG1ldGFkYXRhXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVBRF9PTkxZIC0gS2V5IGZvciByZWFkb25seSBhdHRyaWJ1dGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRVFVSVJFRCAtIEtleSBmb3IgcmVxdWlyZWQgdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1JTiAtIEtleSBmb3IgbWluaW11bSB2YWx1ZSB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUlOX0xFTkdUSCAtIEtleSBmb3IgbWluaW11bSBsZW5ndGggdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IE1BWCAtIEtleSBmb3IgbWF4aW11bSB2YWx1ZSB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUFYX0xFTkdUSCAtIEtleSBmb3IgbWF4aW11bSBsZW5ndGggdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBBVFRFUk4gLSBLZXkgZm9yIHBhdHRlcm4gdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IFVSTCAtIEtleSBmb3IgVVJMIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBTVEVQIC0gS2V5IGZvciBzdGVwIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEQVRFIC0gS2V5IGZvciBkYXRlIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBFTUFJTCAtIEtleSBmb3IgZW1haWwgdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBBU1NXT1JEIC0gS2V5IGZvciBwYXNzd29yZCB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRVFVQUxTIC0gS2V5IGZvciBlcXVhbGl0eSB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRElGRiAtIEtleSBmb3IgZGlmZmVyZW5jZSB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTEVTU19USEFOIC0gS2V5IGZvciBsZXNzIHRoYW4gdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IExFU1NfVEhBTl9PUl9FUVVBTCAtIEtleSBmb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBHUkVBVEVSX1RIQU4gLSBLZXkgZm9yIGdyZWF0ZXIgdGhhbiB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gR1JFQVRFUl9USEFOX09SX0VRVUFMIC0gS2V5IGZvciBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdmFsaWRhdGlvblxuICpcbiAqIEBjb25zdCBVSUtleXNcbiAqIEB0eXBlIHtVSUtleXNUeXBlfVxuICogQHJlYWRvbmx5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOnVpLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGNvbnN0IFVJS2V5cyA9IHtcbiAgUkVGTEVDVDogYCR7TW9kZWxLZXlzLlJFRkxFQ1R9LnVpLmAsXG4gIFVJTU9ERUw6IFwidWltb2RlbFwiLFxuICBSRU5ERVJFRF9CWTogXCJyZW5kZXJlZC1ieVwiLFxuICBFTEVNRU5UOiBcImVsZW1lbnRcIixcbiAgUFJPUDogXCJwcm9wXCIsXG4gIENISUxEOiBcImNoaWxkXCIsXG4gIE5BTUU6IFwibmFtZVwiLFxuICBOQU1FX1BSRUZJWDogXCJpbnB1dC1cIixcbiAgQ1VTVE9NX1BST1BTOiBcImN1c3RvbVZhbGlkYXRpb25Qcm9wc1wiLFxuXG4gIFVJTElTVElURU06IFwidWlsaXN0aXRlbVwiLFxuICBVSUxJU1RQUk9QOiBcImxpc3Rwcm9wXCIsXG4gIFVJTEFZT1VUOiBcInVpbGF5b3V0XCIsXG4gIFVJTEFZT1VUSVRFTTogXCJ1aWxheW91dGl0ZW1cIixcbiAgSEFORExFUlM6IFwiaGFuZGxlcnNcIixcblxuICBUWVBFOiBcInR5cGVcIixcbiAgU1VCX1RZUEU6IFwic3VidHlwZVwiLFxuXG4gIEhJRERFTjogXCJoaWRkZW5cIixcbiAgRk9STUFUOiBcImZvcm1hdFwiLFxuICBPUkRFUjogXCJvcmRlclwiLFxuXG4gIFJFQURfT05MWTogXCJyZWFkb25seVwiLFxuICBSRVFVSVJFRDogVmFsaWRhdGlvbktleXMuUkVRVUlSRUQsXG4gIE1JTjogVmFsaWRhdGlvbktleXMuTUlOLFxuICBNSU5fTEVOR1RIOiBWYWxpZGF0aW9uS2V5cy5NSU5fTEVOR1RILFxuICBNQVg6IFZhbGlkYXRpb25LZXlzLk1BWCxcbiAgTUFYX0xFTkdUSDogVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSCxcbiAgUEFUVEVSTjogVmFsaWRhdGlvbktleXMuUEFUVEVSTixcbiAgVVJMOiBWYWxpZGF0aW9uS2V5cy5VUkwsXG4gIFNURVA6IFZhbGlkYXRpb25LZXlzLlNURVAsXG4gIERBVEU6IFZhbGlkYXRpb25LZXlzLkRBVEUsXG4gIEVNQUlMOiBWYWxpZGF0aW9uS2V5cy5FTUFJTCxcbiAgUEFTU1dPUkQ6IFZhbGlkYXRpb25LZXlzLlBBU1NXT1JELFxuICBFUVVBTFM6IFZhbGlkYXRpb25LZXlzLkVRVUFMUyxcbiAgRElGRjogVmFsaWRhdGlvbktleXMuRElGRixcbiAgTEVTU19USEFOOiBWYWxpZGF0aW9uS2V5cy5MRVNTX1RIQU4sXG4gIExFU1NfVEhBTl9PUl9FUVVBTDogVmFsaWRhdGlvbktleXMuTEVTU19USEFOX09SX0VRVUFMLFxuICBHUkVBVEVSX1RIQU46IFZhbGlkYXRpb25LZXlzLkdSRUFURVJfVEhBTixcbiAgR1JFQVRFUl9USEFOX09SX0VRVUFMOiBWYWxpZGF0aW9uS2V5cy5HUkVBVEVSX1RIQU5fT1JfRVFVQUwsXG59O1xuXG5cblxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNYXBwaW5nIG9mIGlucHV0IHR5cGVzIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgdmFsaWRhdG9yc1xuICogQHN1bW1hcnkgTWFwcyBzcGVjaWFsIGlucHV0IHR5cGVzIHRvIHRoZWlyIHZhbGlkYXRvciBjbGFzc2VzXG4gKiBUaGlzIGNvbnN0YW50IG1hcHMgaW5wdXQgdHlwZXMgbGlrZSBlbWFpbCwgVVJMLCBkYXRlLCBhbmQgcGFzc3dvcmQgdG8gdGhlaXJcbiAqIGNvcnJlc3BvbmRpbmcgdmFsaWRhdG9yIGNsYXNzZXMgZnJvbSB0aGUgZGVjb3JhdG9yLXZhbGlkYXRpb24gbGlicmFyeS5cbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0LjxzdHJpbmcsIENvbnN0cnVjdG9yPFZhbGlkYXRvcj4+fSBWYWxpZGF0YWJsZUJ5VHlwZU1hcFxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxFbWFpbFZhbGlkYXRvcj59IGVtYWlsIC0gVmFsaWRhdG9yIGZvciBlbWFpbCBpbnB1dHNcbiAqIEBwcm9wZXJ0eSB7Q29uc3RydWN0b3I8VVJMVmFsaWRhdG9yPn0gdXJsIC0gVmFsaWRhdG9yIGZvciBVUkwgaW5wdXRzXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yPERhdGVWYWxpZGF0b3I+fSBkYXRlIC0gVmFsaWRhdG9yIGZvciBkYXRlIGlucHV0c1xuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxQYXNzd29yZFZhbGlkYXRvcj59IHBhc3N3b3JkIC0gVmFsaWRhdG9yIGZvciBwYXNzd29yZCBpbnB1dHNcbiAqXG4gKiBAY29uc3QgVmFsaWRhdGFibGVCeVR5cGVcbiAqIEB0eXBlIHtWYWxpZGF0YWJsZUJ5VHlwZU1hcH1cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTp1aS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBjb25zdCBWYWxpZGF0YWJsZUJ5VHlwZTogUmVjb3JkPHN0cmluZywgQ29uc3RydWN0b3I8VmFsaWRhdG9yPj4gPSB7XG4gIFtVSUtleXMuRU1BSUxdOiBFbWFpbFZhbGlkYXRvcixcbiAgW1VJS2V5cy5VUkxdOiBVUkxWYWxpZGF0b3IsXG4gIFtVSUtleXMuREFURV06IERhdGVWYWxpZGF0b3IsXG4gIFtVSUtleXMuUEFTU1dPUkRdOiBQYXNzd29yZFZhbGlkYXRvcixcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1hcHBpbmcgb2YgdmFsaWRhdGlvbiBhdHRyaWJ1dGVzIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgdmFsaWRhdG9yc1xuICogQHN1bW1hcnkgTWFwcyBIVE1MIHZhbGlkYXRpb24gYXR0cmlidXRlcyB0byB0aGVpciB2YWxpZGF0b3IgY2xhc3Nlc1xuICogVGhpcyBjb25zdGFudCBtYXBzIEhUTUwgdmFsaWRhdGlvbiBhdHRyaWJ1dGVzIGxpa2UgcmVxdWlyZWQsIG1pbiwgbWF4LCBwYXR0ZXJuLCBldGMuXG4gKiB0byB0aGVpciBjb3JyZXNwb25kaW5nIHZhbGlkYXRvciBjbGFzc2VzIGZyb20gdGhlIGRlY29yYXRvci12YWxpZGF0aW9uIGxpYnJhcnkuXG4gKlxuICogQHR5cGVkZWYge09iamVjdC48c3RyaW5nLCBDb25zdHJ1Y3RvcjxWYWxpZGF0b3I+Pn0gVmFsaWRhdGFibGVCeUF0dHJpYnV0ZU1hcFxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxSZXF1aXJlZFZhbGlkYXRvcj59IHJlcXVpcmVkIC0gVmFsaWRhdG9yIGZvciByZXF1aXJlZCBmaWVsZHNcbiAqIEBwcm9wZXJ0eSB7Q29uc3RydWN0b3I8TWluVmFsaWRhdG9yPn0gbWluIC0gVmFsaWRhdG9yIGZvciBtaW5pbXVtIHZhbHVlXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yPE1heFZhbGlkYXRvcj59IG1heCAtIFZhbGlkYXRvciBmb3IgbWF4aW11bSB2YWx1ZVxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxTdGVwVmFsaWRhdG9yPn0gc3RlcCAtIFZhbGlkYXRvciBmb3Igc3RlcCB2YWx1ZVxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxNaW5MZW5ndGhWYWxpZGF0b3I+fSBtaW5sZW5ndGggLSBWYWxpZGF0b3IgZm9yIG1pbmltdW0gbGVuZ3RoXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yPE1heExlbmd0aFZhbGlkYXRvcj59IG1heGxlbmd0aCAtIFZhbGlkYXRvciBmb3IgbWF4aW11bSBsZW5ndGhcbiAqIEBwcm9wZXJ0eSB7Q29uc3RydWN0b3I8UGF0dGVyblZhbGlkYXRvcj59IHBhdHRlcm4gLSBWYWxpZGF0b3IgZm9yIHJlZ2V4IHBhdHRlcm5cbiAqIEBwcm9wZXJ0eSB7Q29uc3RydWN0b3I8RXF1YWxzVmFsaWRhdG9yPn0gZXF1YWxzIC0gVmFsaWRhdG9yIGZvciBlcXVhbGl0eVxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxEaWZmVmFsaWRhdG9yPn0gZGlmZiAtIFZhbGlkYXRvciBmb3IgZGlmZmVyZW5jZVxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxMZXNzVGhhblZhbGlkYXRvcj59IGxlc3N0aGFuIC0gVmFsaWRhdG9yIGZvciBsZXNzIHRoYW4gY29tcGFyaXNvblxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxMZXNzVGhhbk9yRXF1YWxWYWxpZGF0b3I+fSBsZXNzdGhhbm9yZXF1YWwgLSBWYWxpZGF0b3IgZm9yIGxlc3MgdGhhbiBvciBlcXVhbCBjb21wYXJpc29uXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yPEdyZWF0ZXJUaGFuVmFsaWRhdG9yPn0gZ3JlYXRlcnRoYW4gLSBWYWxpZGF0b3IgZm9yIGdyZWF0ZXIgdGhhbiBjb21wYXJpc29uXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yPEdyZWF0ZXJUaGFuT3JFcXVhbFZhbGlkYXRvcj59IGdyZWF0ZXJ0aGFub3JlcXVhbCAtIFZhbGlkYXRvciBmb3IgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIGNvbXBhcmlzb25cbiAqXG4gKiBAY29uc3QgVmFsaWRhdGFibGVCeUF0dHJpYnV0ZVxuICogQHR5cGUge1ZhbGlkYXRhYmxlQnlBdHRyaWJ1dGVNYXB9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dWktZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgVmFsaWRhdGFibGVCeUF0dHJpYnV0ZTogUmVjb3JkPHN0cmluZywgQ29uc3RydWN0b3I8VmFsaWRhdG9yPj4gPSB7XG4gIFtVSUtleXMuUkVRVUlSRURdOiBSZXF1aXJlZFZhbGlkYXRvcixcbiAgW1VJS2V5cy5NSU5dOiBNaW5WYWxpZGF0b3IsXG4gIFtVSUtleXMuTUFYXTogTWF4VmFsaWRhdG9yLFxuICBbVUlLZXlzLlNURVBdOiBTdGVwVmFsaWRhdG9yLFxuICBbVUlLZXlzLk1JTl9MRU5HVEhdOiBNaW5MZW5ndGhWYWxpZGF0b3IsXG4gIFtVSUtleXMuTUFYX0xFTkdUSF06IE1heExlbmd0aFZhbGlkYXRvcixcbiAgW1VJS2V5cy5QQVRURVJOXTogUGF0dGVyblZhbGlkYXRvcixcbiAgW1VJS2V5cy5FUVVBTFNdOiBFcXVhbHNWYWxpZGF0b3IsXG4gIFtVSUtleXMuRElGRl06IERpZmZWYWxpZGF0b3IsXG4gIFtVSUtleXMuTEVTU19USEFOXTogTGVzc1RoYW5WYWxpZGF0b3IsXG4gIFtVSUtleXMuTEVTU19USEFOX09SX0VRVUFMXTogTGVzc1RoYW5PckVxdWFsVmFsaWRhdG9yLFxuICBbVUlLZXlzLkdSRUFURVJfVEhBTl06IEdyZWF0ZXJUaGFuVmFsaWRhdG9yLFxuICBbVUlLZXlzLkdSRUFURVJfVEhBTl9PUl9FUVVBTF06IEdyZWF0ZXJUaGFuT3JFcXVhbFZhbGlkYXRvcixcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFN0YW5kYXJkIGRhdGUgZm9ybWF0IHN0cmluZyBmb3IgSFRNTDUgZGF0ZSBpbnB1dHNcbiAqIEBzdW1tYXJ5IEZvcm1hdCBzdHJpbmcgZm9yIEhUTUw1IGRhdGUgaW5wdXRzICh5eXl5LU1NLWRkKVxuICogVGhpcyBjb25zdGFudCBkZWZpbmVzIHRoZSBzdGFuZGFyZCBkYXRlIGZvcm1hdCBzdHJpbmcgdXNlZCBmb3IgSFRNTDUgZGF0ZSBpbnB1dHMuXG4gKlxuICogQGNvbnN0IEhUTUw1RGF0ZUZvcm1hdFxuICogQHR5cGUge3N0cmluZ31cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTp1aS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBjb25zdCBIVE1MNURhdGVGb3JtYXQgPSBcInl5eXktTU0tZGRcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29sbGVjdGlvbiBvZiBIVE1MNSBpbnB1dCB0eXBlIHZhbHVlc1xuICogQHN1bW1hcnkgTWFwcyBpbnB1dCB0eXBlIGNvbnN0YW50cyB0byB0aGVpciBIVE1MIGF0dHJpYnV0ZSB2YWx1ZXNcbiAqIFRoaXMgY29uc3RhbnQgcHJvdmlkZXMgYSBtYXBwaW5nIG9mIGlucHV0IHR5cGUgY29uc3RhbnRzIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmdcbiAqIEhUTUwgYXR0cmlidXRlIHZhbHVlcyBmb3IgdXNlIGluIGZvcm0gZWxlbWVudHMuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gSFRNTDVJbnB1dFR5cGVzTWFwXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQlVUVE9OIC0gQnV0dG9uIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBDSEVDS0JPWCAtIENoZWNrYm94IGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBDT0xPUiAtIENvbG9yIHBpY2tlciBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gREFURSAtIERhdGUgcGlja2VyIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEQVRFVElNRV9MT0NBTCAtIExvY2FsIGRhdGV0aW1lIHBpY2tlciBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRU1BSUwgLSBFbWFpbCBpbnB1dCB0eXBlIHdpdGggdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IEZJTEUgLSBGaWxlIHVwbG9hZCBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gSElEREVOIC0gSGlkZGVuIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBJTUFHRSAtIEltYWdlIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNT05USCAtIE1vbnRoIHBpY2tlciBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTlVNQkVSIC0gTnVtZXJpYyBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUEFTU1dPUkQgLSBQYXNzd29yZCBpbnB1dCB0eXBlIHdpdGggbWFza2VkIHRleHRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSQURJTyAtIFJhZGlvIGJ1dHRvbiBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkFOR0UgLSBSYW5nZSBzbGlkZXIgaW5wdXQgdHlwZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFU0VUIC0gRm9ybSByZXNldCBidXR0b24gaW5wdXQgdHlwZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNFQVJDSCAtIFNlYXJjaCBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gU1VCTUlUIC0gRm9ybSBzdWJtaXQgYnV0dG9uIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBURUwgLSBUZWxlcGhvbmUgbnVtYmVyIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBURVhUIC0gQmFzaWMgdGV4dCBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVElNRSAtIFRpbWUgcGlja2VyIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBVUkwgLSBVUkwgaW5wdXQgdHlwZSB3aXRoIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBXRUVLIC0gV2VlayBwaWNrZXIgaW5wdXQgdHlwZVxuICpcbiAqIEBjb25zdCBIVE1MNUlucHV0VHlwZXNcbiAqIEB0eXBlIHtIVE1MNUlucHV0VHlwZXNNYXB9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dWktZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgSFRNTDVJbnB1dFR5cGVzID0ge1xuICBCVVRUT046IFwiYnV0dG9uXCIsXG4gIENIRUNLQk9YOiBcImNoZWNrYm94XCIsXG4gIENPTE9SOiBcImNvbG9yXCIsXG4gIERBVEU6IFVJS2V5cy5EQVRFLFxuICBEQVRFVElNRV9MT0NBTDogXCJkYXRldGltZS1sb2NhbFwiLFxuICBFTUFJTDogVUlLZXlzLkVNQUlMLFxuICBGSUxFOiBcImZpbGVcIixcbiAgSElEREVOOiBcImhpZGRlblwiLFxuICBJTUFHRTogXCJpbWFnZVwiLFxuICBNT05USDogXCJtb250aFwiLFxuICBOVU1CRVI6IFwibnVtYmVyXCIsXG4gIFBBU1NXT1JEOiBVSUtleXMuUEFTU1dPUkQsXG4gIFJBRElPOiBcInJhZGlvXCIsXG4gIFJBTkdFOiBcInJhbmdlXCIsXG4gIFJFU0VUOiBcInJlc2V0XCIsXG4gIFNFQVJDSDogXCJzZWFyY2hcIixcbiAgU1VCTUlUOiBcInN1Ym1pdFwiLFxuICBURUw6IFwidGVsXCIsXG4gIFRFWFQ6IFwidGV4dFwiLFxuICBURVhUQVJFQTogJ3RleHRhcmVhJyxcbiAgU0VMRUNUOiAnc2VsZWN0JyxcbiAgVElNRTogXCJ0aW1lXCIsXG4gIFVSTDogVUlLZXlzLlVSTCxcbiAgV0VFSzogXCJ3ZWVrXCIsXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBcnJheSBvZiBIVE1MNSBpbnB1dCB0eXBlcyB0aGF0IHVzZSBjaGVja2JveGVzXG4gKiBAc3VtbWFyeSBMaXN0IG9mIGlucHV0IHR5cGVzIHRoYXQgcmVwcmVzZW50IGNoZWNrYWJsZSBjb250cm9sc1xuICogVGhpcyBjb25zdGFudCBkZWZpbmVzIGFuIGFycmF5IG9mIEhUTUw1IGlucHV0IHR5cGVzIHRoYXQgcmVwcmVzZW50XG4gKiBjaGVja2FibGUgY29udHJvbHMgKGNoZWNrYm94IGFuZCByYWRpbykuXG4gKlxuICogQGNvbnN0IEhUTUw1Q2hlY2tUeXBlc1xuICogQHR5cGUge3N0cmluZ1tdfVxuICogQHJlYWRvbmx5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOnVpLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGNvbnN0IEhUTUw1Q2hlY2tUeXBlcyA9IFtcbiAgSFRNTDVJbnB1dFR5cGVzLkNIRUNLQk9YLFxuICBIVE1MNUlucHV0VHlwZXMuUkFESU8sXG5dO1xuIiwiaW1wb3J0IHsgSW50ZXJuYWxFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFcnJvciB0aHJvd24gd2hlbiBhIHJlbmRlcmluZyBvcGVyYXRpb24gZmFpbHNcbiAqIEBzdW1tYXJ5IFNwZWNpYWxpemVkIGVycm9yIGZvciByZW5kZXJpbmcgZmFpbHVyZXMgaW4gVUkgY29tcG9uZW50c1xuICogVGhpcyBlcnJvciBpcyB0aHJvd24gd2hlbiB0aGUgcmVuZGVyaW5nIGVuZ2luZSBlbmNvdW50ZXJzIGFuIGVycm9yIHdoaWxlXG4gKiBhdHRlbXB0aW5nIHRvIHJlbmRlciBhIFVJIGNvbXBvbmVudCBvciBtb2RlbC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xFcnJvcn0gbXNnIFRoZSBlcnJvciBtZXNzYWdlIG9yIG9yaWdpbmFsIGVycm9yXG4gKlxuICogQGNsYXNzIFJlbmRlcmluZ0Vycm9yXG4gKiBAZXh0ZW5kcyBCYXNlRXJyb3JcbiAqIEBjYXRlZ29yeSBFcnJvcnNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gVGhyb3dpbmcgYSByZW5kZXJpbmcgZXJyb3JcbiAqIHRyeSB7XG4gKiAgIC8vIFJlbmRlcmluZyBjb2RlIHRoYXQgbWlnaHQgZmFpbFxuICogICBpZiAoIWNvbXBvbmVudC5jYW5SZW5kZXIoKSkge1xuICogICAgIHRocm93IG5ldyBSZW5kZXJpbmdFcnJvcignQ29tcG9uZW50IGNhbm5vdCBiZSByZW5kZXJlZCcpO1xuICogICB9XG4gKiB9IGNhdGNoIChlcnJvcikge1xuICogICBjb25zb2xlLmVycm9yKCdSZW5kZXJpbmcgZmFpbGVkOicsIGVycm9yLm1lc3NhZ2UpO1xuICogfVxuICovXG5leHBvcnQgY2xhc3MgUmVuZGVyaW5nRXJyb3IgZXh0ZW5kcyBJbnRlcm5hbEVycm9yIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IFJlbmRlcmluZ0Vycm9yIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IEluaXRpYWxpemVzIHRoZSBlcnJvciB3aXRoIGEgbWVzc2FnZSBvciBvcmlnaW5hbCBlcnJvclxuICAgKiBAcGFyYW0ge3N0cmluZ3xFcnJvcn0gbXNnIFRoZSBlcnJvciBtZXNzYWdlIG9yIG9yaWdpbmFsIGVycm9yXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIobXNnLCBSZW5kZXJpbmdFcnJvci5uYW1lKTtcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgZm9ybWF0RGF0ZSxcbiAgTW9kZWwsXG4gIHBhcnNlRGF0ZSxcbiAgUmVzZXJ2ZWRNb2RlbHMsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEhUTUw1RGF0ZUZvcm1hdCwgSFRNTDVJbnB1dFR5cGVzLCBVSUtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IGZpbmRNb2RlbElkLCBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBGaWVsZFByb3BlcnRpZXMgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBmdW5jdGlvbiBmb3JtYXRCeVR5cGVcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnVpLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEJ5VHlwZShcbiAgdHlwZTogYW55LFxuICB2YWx1ZTogYW55LFxuICAuLi5hcmdzOiB1bmtub3duW11cbik6IHN0cmluZyB8IG51bWJlciB7XG4gIGlmICh0eXBlID09PSBVSUtleXMuREFURSkge1xuICAgIGlmKCF2YWx1ZSlcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgY29uc3QgZm9ybWF0OiBzdHJpbmcgPSAoYXJncy5zaGlmdCgpIGFzIHN0cmluZykgfHwgSFRNTDVEYXRlRm9ybWF0O1xuICAgIHJldHVybiBmb3JtYXREYXRlKG5ldyBEYXRlKHZhbHVlKSwgZm9ybWF0KTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVZhbHVlQnlUeXBlKFxuICB0eXBlOiBzdHJpbmcsXG4gIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIsXG4gIGZpZWxkUHJvcHM6IEZpZWxkUHJvcGVydGllc1xuKTogc3RyaW5nIHwgbnVtYmVyIHwgRGF0ZSB7XG4gIGxldCByZXN1bHQ6IHN0cmluZyB8IG51bWJlciB8IERhdGUgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgQXJyYXkubmFtZToge1xuICAgICAgY29uc3QgcGFyc2VkID0gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyAgdmFsdWUubWFwKHYgPT4gcGFyc2VWYWx1ZUJ5VHlwZShcbiAgICAgICAgUmVzZXJ2ZWRNb2RlbHMuU1RSSU5HLCB2LCBmaWVsZFByb3BzXG4gICAgICApKSA6IFt2YWx1ZV07XG4gICAgICByZXN1bHQgPSBwYXJzZWQuam9pbihcIixcIik7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuTlVNQkVSOlxuICAgICAgcmVzdWx0ID0gcGFyc2VUb051bWJlcih2YWx1ZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5EQVRFOiB7XG4gICAgICBjb25zdCBmb3JtYXQ6IHN0cmluZyB8IHVuZGVmaW5lZCA9IGZpZWxkUHJvcHMuZm9ybWF0O1xuICAgICAgaWYodmFsdWUgJiYgYCR7dmFsdWV9YC50cmltKCkubGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdCA9XG4gICAgICAgICAgdHlwZW9mIHZhbHVlID09PSBSZXNlcnZlZE1vZGVscy5OVU1CRVJcbiAgICAgICAgICAgID8gbmV3IERhdGUodmFsdWUpXG4gICAgICAgICAgICA6IHZhbHVlXG4gICAgICAgICAgICAgID8gZm9ybWF0XG4gICAgICAgICAgICAgICAgPyBwYXJzZURhdGUoZm9ybWF0LCB2YWx1ZSlcbiAgICAgICAgICAgICAgICA6IG5ldyBEYXRlKHZhbHVlKVxuICAgICAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgcmVzdWx0ID0gXG4gICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gUmVzZXJ2ZWRNb2RlbHMuT0JKRUNUID8gXG4gICAgICAgICAgKEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUuam9pbihcIixcIikgOiBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpIDpcbiAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gUmVzZXJ2ZWRNb2RlbHMuQk9PTEVBTiA/XG4gICAgICAgICAgICAgIHZhbHVlIDogdHlwZW9mIHZhbHVlID09PSBSZXNlcnZlZE1vZGVscy5TVFJJTkcgPyBcbiAgICAgICAgICAgICAgICBlc2NhcGVIdG1sKHZhbHVlIGFzIHN0cmluZykgOiByZXN1bHQ7XG4gIH1cbiAgaWYgKHR5cGVvZiByZXN1bHQgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBGYWlsZWQgdG8gcGFyc2UgdmFsdWUgb2YgdHlwZSAke3R5cGV9IGZyb20gJHt0eXBlb2YgdmFsdWV9IC0gJHt2YWx1ZX1gXG4gICAgKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUb051bWJlcih2YWx1ZTogc3RyaW5nIHwgbnVtYmVyKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgIWlzTmFOKHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xuXG4gIGNvbnN0IHBhcnNlZCA9IE51bWJlcih2YWx1ZSk7XG4gIGlmICghaXNOYU4ocGFyc2VkKSkgcmV0dXJuIHBhcnNlZDtcblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlSHRtbCh2YWx1ZTogc3RyaW5nKSB7XG4gIGlmICghdmFsdWUpIHJldHVybiB2YWx1ZTtcblxuICBjb25zdCB0YWdzVG9SZXBsYWNlOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIFwiJlwiOiBcIiZhbXA7XCIsXG4gICAgXCI8XCI6IFwiJmx0O1wiLFxuICAgIFwiPlwiOiBcIiZndDtcIixcbiAgfTtcbiAgcmV0dXJuIGAke3ZhbHVlfWAucmVwbGFjZSgvWyY8Pl0vZywgKHRhZykgPT4ge1xuICAgIHJldHVybiB0YWdzVG9SZXBsYWNlW3RhZ10gfHwgdGFnO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJldmVydEh0bWwodmFsdWU6IHN0cmluZykge1xuICBjb25zdCB0YWdzVG9SZXBsYWNlOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIFwiJmFtcDtcIjogXCImXCIsXG4gICAgXCImbHQ7XCI6IFwiPFwiLFxuICAgIFwiJmd0O1wiOiBcIj5cIixcbiAgfTtcblxuICByZXR1cm4gYCR7dmFsdWV9YC5yZXBsYWNlKC8mbHQ7fCZndDt8JmFtcDsvZywgKHRhZykgPT4ge1xuICAgIHJldHVybiB0YWdzVG9SZXBsYWNlW3RhZ10gfHwgdGFnO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlVUlNb2RlbElEPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0pIHtcbiAgbGV0IGlkOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ7XG4gIHRyeSB7XG4gICAgaWQgPSBmaW5kTW9kZWxJZChtb2RlbCkgYXMgc3RyaW5nIHwgbnVtYmVyO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgIGlkID0gRGF0ZS5ub3coKTtcbiAgfVxuICBjb25zdCBuYW1lID0gbW9kZWwuY29uc3RydWN0b3IubmFtZTtcbiAgcmV0dXJuIGAke25hbWV9LSR7aWR9YDtcbn1cbiIsImltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7XG4gIENvbnN0cnVjdG9yLFxuICBNb2RlbCxcbiAgTW9kZWxDb25zdHJ1Y3RvcixcbiAgUmVzZXJ2ZWRNb2RlbHMsXG4gIFZhbGlkYXRpb25LZXlzLFxuICBWYWxpZGF0aW9uTWV0YWRhdGEsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7XG4gIEhUTUw1RGF0ZUZvcm1hdCxcbiAgSFRNTDVJbnB1dFR5cGVzLFxuICBVSUtleXMsXG4gIFZhbGlkYXRhYmxlQnlBdHRyaWJ1dGUsXG4gIFZhbGlkYXRhYmxlQnlUeXBlLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIENydWRPcGVyYXRpb25LZXlzLFxuICBGaWVsZERlZmluaXRpb24sXG4gIEZpZWxkUHJvcGVydGllcyxcbiAgVUlDbGFzc01ldGFkYXRhLFxuICBVSUVsZW1lbnRNZXRhZGF0YSxcbiAgVUlMaXN0SXRlbUVsZW1lbnRNZXRhZGF0YSxcbiAgVUlNb2RlbE1ldGFkYXRhLFxuICBVSVByb3BNZXRhZGF0YSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IFJlbmRlcmluZ0Vycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBEZWNvcmF0b3JNZXRhZGF0YSwgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgZm9ybWF0QnlUeXBlLCBnZW5lcmF0ZVVJTW9kZWxJRCB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEFic3RyYWN0IGNsYXNzIGZvciByZW5kZXJpbmcgVUkgY29tcG9uZW50cyBiYXNlZCBvbiBtb2RlbCBtZXRhZGF0YS5cbiAqIEBzdW1tYXJ5IFRoZSBSZW5kZXJpbmdFbmdpbmUgY2xhc3MgcHJvdmlkZXMgYSBmcmFtZXdvcmsgZm9yIGNvbnZlcnRpbmcgbW9kZWwgbWV0YWRhdGEgaW50byBVSSBmaWVsZCBkZWZpbml0aW9ucy5cbiAqIEl0IGhhbmRsZXMgdGhlIHRyYW5zbGF0aW9uIG9mIG1vZGVsIHByb3BlcnRpZXMgdG8gVUkgZWxlbWVudHMsIGFwcGxpZXMgdmFsaWRhdGlvbiBydWxlcywgYW5kIG1hbmFnZXMgZGlmZmVyZW50IHJlbmRlcmluZyBmbGF2b3JzLlxuICogVGhpcyBjbGFzcyBpcyBkZXNpZ25lZCB0byBiZSBleHRlbmRlZCBieSBzcGVjaWZpYyByZW5kZXJpbmcgaW1wbGVtZW50YXRpb25zLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0eXBlIG9mIHRoZSByZW5kZXJpbmcgcmVzdWx0LCBkZWZhdWx0cyB0byB2b2lkXG4gKiBAdGVtcGxhdGUgUiBUaGUgdHlwZSBvZiB0aGUgZmllbGQgZGVmaW5pdGlvbiwgZGVmYXVsdHMgdG8gRmllbGREZWZpbml0aW9uPFQ+XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZsYXZvdXIgLSBUaGUgZmxhdm9yIG9mIHRoZSByZW5kZXJpbmcgZW5naW5lLlxuICpcbiAqIEBjbGFzcyBSZW5kZXJpbmdFbmdpbmVcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFJlbmRlcmluZ0VuZ2luZTxUID0gdm9pZCwgUiA9IEZpZWxkRGVmaW5pdGlvbjxUPj4ge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENhY2hlIGZvciBzdG9yaW5nIHJlbmRlcmluZyBlbmdpbmUgaW5zdGFuY2VzIG9yIGNvbnN0cnVjdG9ycy5cbiAgICogQHByaXZhdGVcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgY2FjaGU6IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgfCBDb25zdHJ1Y3RvcjxSZW5kZXJpbmdFbmdpbmU8dW5rbm93biwgdW5rbm93bj4+XG4gICAgfCBSZW5kZXJpbmdFbmdpbmU8dW5rbm93biwgdW5rbm93bj5cbiAgPiA9IHt9O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGhlIGN1cnJlbnRseSBhY3RpdmUgcmVuZGVyaW5nIGVuZ2luZS5cbiAgICogQHByaXZhdGVcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgY3VycmVudDpcbiAgICB8IENvbnN0cnVjdG9yPFJlbmRlcmluZ0VuZ2luZTx1bmtub3duLCB1bmtub3duPj5cbiAgICB8IFJlbmRlcmluZ0VuZ2luZTx1bmtub3duLCB1bmtub3duPjtcblxuICAvKipcbiAgICogRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHJlbmRlcmluZyBlbmdpbmUgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuXG4gICAqL1xuICBwcm90ZWN0ZWQgaW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IocmVhZG9ubHkgZmxhdm91cjogc3RyaW5nKSB7XG4gICAgUmVuZGVyaW5nRW5naW5lLnJlZ2lzdGVyKHRoaXMpO1xuICAgIGNvbnNvbGUubG9nKGBkZWNhZidzICR7Zmxhdm91cn0gcmVuZGVyaW5nIGVuZ2luZSBsb2FkZWRgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSW5pdGlhbGl6ZXMgdGhlIHJlbmRlcmluZyBlbmdpbmUuXG4gICAqIEBzdW1tYXJ5IEFic3RyYWN0IG1ldGhvZCB0byBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzc2VzIGZvciBzcGVjaWZpYyBpbml0aWFsaXphdGlvbiBsb2dpYy5cbiAgICpcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyBuZWVkZWQgZm9yIGluaXRpYWxpemF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBpbml0aWFsaXphdGlvbiBpcyBjb21wbGV0ZS5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqL1xuICBhYnN0cmFjdCBpbml0aWFsaXplKC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRyYW5zbGF0ZXMgYmV0d2VlbiBtb2RlbCB0eXBlcyBhbmQgSFRNTCBpbnB1dCB0eXBlcy5cbiAgICogQHN1bW1hcnkgQ29udmVydHMgbW9kZWwgZGF0YSB0eXBlcyB0byBhcHByb3ByaWF0ZSBIVE1MIGlucHV0IHR5cGVzIGFuZCB2aWNlIHZlcnNhLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIGtleSB0byB0cmFuc2xhdGUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3RvVmlldz10cnVlXSAtIERpcmVjdGlvbiBvZiB0cmFuc2xhdGlvbiAodHJ1ZSBmb3IgbW9kZWwgdG8gdmlldywgZmFsc2UgZm9yIHZpZXcgdG8gbW9kZWwpLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgdHJhbnNsYXRlZCB0eXBlLlxuICAgKi9cbiAgdHJhbnNsYXRlKGtleTogc3RyaW5nLCB0b1ZpZXc6IGJvb2xlYW4gPSB0cnVlKTogc3RyaW5nIHtcbiAgICBpZiAodG9WaWV3KSB7XG4gICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICBjYXNlIFJlc2VydmVkTW9kZWxzLlNUUklORzpcbiAgICAgICAgICByZXR1cm4gSFRNTDVJbnB1dFR5cGVzLlRFWFQ7XG4gICAgICAgIGNhc2UgUmVzZXJ2ZWRNb2RlbHMuTlVNQkVSOlxuICAgICAgICBjYXNlIFJlc2VydmVkTW9kZWxzLkJJR0lOVDpcbiAgICAgICAgICByZXR1cm4gSFRNTDVJbnB1dFR5cGVzLk5VTUJFUjtcbiAgICAgICAgY2FzZSBSZXNlcnZlZE1vZGVscy5CT09MRUFOOlxuICAgICAgICAgIHJldHVybiBIVE1MNUlucHV0VHlwZXMuQ0hFQ0tCT1g7XG4gICAgICAgIGNhc2UgUmVzZXJ2ZWRNb2RlbHMuREFURTpcbiAgICAgICAgICByZXR1cm4gSFRNTDVJbnB1dFR5cGVzLkRBVEU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLlNFTEVDVDpcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuVEVYVDpcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuRU1BSUw6XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLkNPTE9SOlxuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5QQVNTV09SRDpcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuVEVMOlxuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5VUkw6XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLlNFQVJDSDpcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuSElEREVOOlxuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5URVhUQVJFQTpcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuUkFESU86XG4gICAgICAgICAgcmV0dXJuIFJlc2VydmVkTW9kZWxzLlNUUklORztcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuTlVNQkVSOlxuICAgICAgICAgIHJldHVybiBSZXNlcnZlZE1vZGVscy5OVU1CRVI7XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLkNIRUNLQk9YOiBcbiAgICAgICAgICByZXR1cm4gUmVzZXJ2ZWRNb2RlbHMuQk9PTEVBTjtcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuREFURTpcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuREFURVRJTUVfTE9DQUw6XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLlRJTUU6XG4gICAgICAgICAgcmV0dXJuIFJlc2VydmVkTW9kZWxzLkRBVEU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBrZXk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBjbGFzcyBkZWNvcmF0b3IgbWV0YWRhdGEgZm9yIGEgbW9kZWwgaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgRXh0cmFjdHMgVUktcmVsYXRlZCBjbGFzcyBkZWNvcmF0b3JzIGZyb20gYSBtb2RlbCBhbmQgcmV0dXJucyB0aGVtIGFzIGFuIGFycmF5XG4gICAqIFRoaXMgbWV0aG9kIGNvbGxlY3RzIG1ldGFkYXRhIGZyb20gdmFyaW91cyBVSSBjbGFzcyBkZWNvcmF0b3JzIGluY2x1ZGluZyBAdWltb2RlbCxcbiAgICogQHVpbGlzdGl0ZW0sIEB1aWhhbmRsZXJzLCBhbmQgQHVpbGF5b3V0IGFwcGxpZWQgdG8gdGhlIG1vZGVsIGNsYXNzLlxuICAgKlxuICAgKiBAdGVtcGxhdGUgTSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIGV4dHJhY3QgbWV0YWRhdGEgZnJvbVxuICAgKiBAcmV0dXJucyB7VUlDbGFzc01ldGFkYXRhW119IEFycmF5IG9mIFVJIGNsYXNzIG1ldGFkYXRhIG9iamVjdHNcbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZ2V0Q2xhc3NEZWNvcmF0b3JzTWV0YWRhdGE8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSk6IFVJQ2xhc3NNZXRhZGF0YVtdICB7XG4gICAgcmV0dXJuIFtcbiAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgIFJlbmRlcmluZ0VuZ2luZS5rZXkoVUlLZXlzLlVJTU9ERUwpLFxuICAgICAgICBtb2RlbC5jb25zdHJ1Y3RvclxuICAgICAgKSB8fFxuICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuVUlNT0RFTCksXG4gICAgICAgIE1vZGVsLmdldChtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lKSBhcyBhbnlcbiAgICAgICksXG4gICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICBSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5VSUxJU1RJVEVNKSxcbiAgICAgICAgbW9kZWwuY29uc3RydWN0b3JcbiAgICAgICkgfHxcbiAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgIFJlbmRlcmluZ0VuZ2luZS5rZXkoVUlLZXlzLlVJTElTVElURU0pLFxuICAgICAgICBNb2RlbC5nZXQobW9kZWwuY29uc3RydWN0b3IubmFtZSkgYXMgYW55XG4gICAgICApLFxuICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuSEFORExFUlMpLFxuICAgICAgICBtb2RlbC5jb25zdHJ1Y3RvclxuICAgICAgKSB8fFxuICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuSEFORExFUlMpLFxuICAgICAgICBNb2RlbC5nZXQobW9kZWwuY29uc3RydWN0b3IubmFtZSkgYXMgYW55XG4gICAgICApLFxuICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuVUlMQVlPVVQpLFxuICAgICAgICBtb2RlbC5jb25zdHJ1Y3RvclxuICAgICAgKSB8fFxuICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuVUlMQVlPVVQpLFxuICAgICAgICBNb2RlbC5nZXQobW9kZWwuY29uc3RydWN0b3IubmFtZSkgYXMgYW55XG4gICAgICApLFxuICAgIF0uZmlsdGVyKEJvb2xlYW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSB0eXBlIGlzIHZhbGlkYXRhYmxlIGJ5IGl0cyBuYXR1cmUuXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgaWYgYSBnaXZlbiBVSSBrZXkgcmVwcmVzZW50cyBhIHR5cGUgdGhhdCBpcyBpbmhlcmVudGx5IHZhbGlkYXRhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIFVJIGtleSB0byBjaGVjay5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHR5cGUgaXMgdmFsaWRhdGFibGUsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIHByb3RlY3RlZCBpc1ZhbGlkYXRhYmxlQnlUeXBlKGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKFZhbGlkYXRhYmxlQnlUeXBlKS5pbmNsdWRlcyhrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSB0eXBlIGlzIHZhbGlkYXRhYmxlIGJ5IGF0dHJpYnV0ZS5cbiAgICogQHN1bW1hcnkgRGV0ZXJtaW5lcyBpZiBhIGdpdmVuIFVJIGtleSByZXByZXNlbnRzIGEgdmFsaWRhdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIGFzIGFuIGF0dHJpYnV0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBVSSBrZXkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB0eXBlIGlzIHZhbGlkYXRhYmxlIGJ5IGF0dHJpYnV0ZSwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGlzVmFsaWRhdGFibGVCeUF0dHJpYnV0ZShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhWYWxpZGF0YWJsZUJ5QXR0cmlidXRlKS5pbmNsdWRlcyhrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyB2YWxpZGF0aW9uIG1ldGFkYXRhIHRvIGFuIGF0dHJpYnV0ZSB2YWx1ZS5cbiAgICogQHN1bW1hcnkgVHJhbnNmb3JtcyB2YWxpZGF0aW9uIG1ldGFkYXRhIGludG8gYSB2YWx1ZSBzdWl0YWJsZSBmb3IgdXNlIGFzIGFuIEhUTUwgYXR0cmlidXRlLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIHZhbGlkYXRpb24ga2V5LlxuICAgKiBAcGFyYW0ge1ZhbGlkYXRpb25NZXRhZGF0YX0gdmFsdWUgLSBUaGUgdmFsaWRhdGlvbiBtZXRhZGF0YS5cbiAgICogQHJldHVybnMge3N0cmluZyB8IG51bWJlciB8IGJvb2xlYW59IFRoZSBjb252ZXJ0ZWQgYXR0cmlidXRlIHZhbHVlLlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGdpdmVuIGtleSBpcyBub3QgdmFsaWRhdGFibGUgYnkgYXR0cmlidXRlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHRvQXR0cmlidXRlVmFsdWUoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgdmFsdWU6IFZhbGlkYXRpb25NZXRhZGF0YVxuICApOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHtcbiAgICBpZiAoIU9iamVjdC5rZXlzKFZhbGlkYXRhYmxlQnlBdHRyaWJ1dGUpLmluY2x1ZGVzKGtleSkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIGF0dHJpYnV0ZSBrZXkgXCIke2tleX1cIi4gRXhwZWN0ZWQgb25lIG9mOiAke09iamVjdC5rZXlzKFZhbGlkYXRhYmxlQnlBdHRyaWJ1dGUpLmpvaW4oXCIsIFwiKX0uYFxuICAgICAgKTtcblxuICAgIHJldHVybiBrZXkgPT09IFVJS2V5cy5SRVFVSVJFRCA/IHRydWUgOiB2YWx1ZVtrZXldO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIG1vZGVsIHRvIGEgZmllbGQgZGVmaW5pdGlvbi5cbiAgICogQHN1bW1hcnkgUHJvY2Vzc2VzIGEgbW9kZWwgaW5zdGFuY2UsIGV4dHJhY3RpbmcgVUktcmVsYXRlZCBtZXRhZGF0YSBhbmQgdmFsaWRhdGlvbiBydWxlcyB0byBjcmVhdGUgYSBmaWVsZCBkZWZpbml0aW9uLlxuICAgKlxuICAgKiBAdGVtcGxhdGUgTSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICAgKiBAdGVtcGxhdGUgVCBUeXBlIHJlZmVyZW5jaW5nIHRoZSBzcGVjaWZpYyBSZW5kZXJpbmcgZW5naW5lIGZpZWxkIHByb3BlcnRpZXMvaW5wdXRzXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdG8gY29udmVydC5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gW2dsb2JhbFByb3BzPXt9XSAtIEdsb2JhbCBwcm9wZXJ0aWVzIHRvIGFwcGx5IHRvIGFsbCBjaGlsZCBlbGVtZW50cy5cbiAgICogQHBhcmFtIHtib29sZWFufSBbZ2VuZXJhdGVJZD10cnVlXSAtIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHBvcHVsYXRlIHRoZSByZW5kZXJlcklkIHByb3BlcnR5LlxuICAgKiBAcmV0dXJucyB7RmllbGREZWZpbml0aW9uPFQ+fSBBIGZpZWxkIGRlZmluaXRpb24gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgVUkgc3RydWN0dXJlIG9mIHRoZSBtb2RlbC5cbiAgICogQHRocm93cyB7UmVuZGVyaW5nRXJyb3J9IElmIG5vIFVJIGRlZmluaXRpb25zIGFyZSBzZXQgZm9yIHRoZSBtb2RlbCBvciBpZiB0aGVyZSBhcmUgaW52YWxpZCBkZWNvcmF0b3JzLlxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gICAqICBwYXJ0aWNpcGFudCBSRSBhcyBSZW5kZXJpbmdFbmdpbmVcbiAgICogIHBhcnRpY2lwYW50IFIgYXMgUmVmbGVjdGlvblxuICAgKiAgcGFydGljaXBhbnQgTSBhcyBNb2RlbFxuICAgKiAgQy0+PlJFOiB0b0ZpZWxkRGVmaW5pdGlvbihtb2RlbCwgZ2xvYmFsUHJvcHMpXG4gICAqICBSRS0+PlI6IGdldE1ldGFkYXRhKFVJS2V5cy5VSU1PREVMLCBtb2RlbC5jb25zdHJ1Y3RvcilcbiAgICogIFItLT4+UkU6IFVJTW9kZWxNZXRhZGF0YVxuICAgKiAgUkUtPj5SOiBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnMobW9kZWwsIFVJS2V5cy5SRUZMRUNUKVxuICAgKiAgUi0tPj5SRTogUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGFbXT5cbiAgICogIFJFLT4+UjogZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzKG1vZGVsLCBWYWxpZGF0aW9uS2V5cy5SRUZMRUNUKVxuICAgKiAgUi0tPj5SRTogUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPltdPlxuICAgKiAgbG9vcCBGb3IgZWFjaCBwcm9wZXJ0eVxuICAgKiAgICBSRS0+PlJFOiBQcm9jZXNzIFVJIGRlY29yYXRvcnNcbiAgICogICAgUkUtPj5SRTogQXBwbHkgdmFsaWRhdGlvbiBydWxlc1xuICAgKiAgZW5kXG4gICAqICBSRS0tPj5DOiBGaWVsZERlZmluaXRpb248VD5cbiAgICovXG4gIHByb3RlY3RlZCB0b0ZpZWxkRGVmaW5pdGlvbjxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG1vZGVsOiBNLFxuICAgIGdsb2JhbFByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9LFxuICAgIGdlbmVyYXRlSWQ6IGJvb2xlYW4gPSB0cnVlXG4gICk6IEZpZWxkRGVmaW5pdGlvbjxUPiB7XG4gICAgXG4gICAgY29uc3QgeyBpbmhlcml0UHJvcHMsIC4uLmdsb2JhbFByb3BzV2l0aG91dEluaGVyaXRzIH0gPSBnbG9iYWxQcm9wcztcbiAgICBnbG9iYWxQcm9wcyA9IGdsb2JhbFByb3BzV2l0aG91dEluaGVyaXRzO1xuXG4gICAgY29uc3QgY2xhc3NEZWNvcmF0b3JzID0gdGhpcy5nZXRDbGFzc0RlY29yYXRvcnNNZXRhZGF0YTxNPihtb2RlbCk7XG5cbiAgICBpZiAoIWNsYXNzRGVjb3JhdG9ycy5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgUmVuZGVyaW5nRXJyb3IoXG4gICAgICAgIGBObyB1aSBkZWZpbml0aW9ucyBzZXQgZm9yIG1vZGVsICR7bW9kZWwuY29uc3RydWN0b3IubmFtZX0uIERpZCB5b3UgdXNlIEB1aW1vZGVsP2BcbiAgICAgICk7XG5cbiAgICBjb25zdCBjbGFzc0RlY29yYXRvciA9IE9iamVjdC5hc3NpZ24oXG4gICAgICB7fSxcbiAgICAgIC4uLmNsYXNzRGVjb3JhdG9ycyxcbiAgICAgIGluaGVyaXRQcm9wcyA/IGluaGVyaXRQcm9wcyA6IHt9IC8vIG92ZXJyaWRlIHRhZyBhbmQgcHJvcGVydGllcyB3aGVuIGl0IGlzIGEgY29tcG9uZW50IHRoYXQgc2hvdWxkIGluaGVyaXQgcHJvcGVydGllcyBmcm9tIGl0cyBwYXJlbnQuXG4gICAgKTtcbiAgICBjb25zdCB7IHRhZywgcHJvcHMsIGl0ZW0sIGhhbmRsZXJzIH0gPSBjbGFzc0RlY29yYXRvcjtcblxuICAgIGNvbnN0IHVpRGVjb3JhdG9yczogUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGFbXT4gPVxuICAgICAgUmVmbGVjdGlvbi5nZXRBbGxQcm9wZXJ0eURlY29yYXRvcnMobW9kZWwsIFVJS2V5cy5SRUZMRUNUKSBhcyBSZWNvcmQ8XG4gICAgICAgIHN0cmluZyxcbiAgICAgICAgRGVjb3JhdG9yTWV0YWRhdGFbXVxuICAgICAgPjtcbiAgICBsZXQgY2hpbGRyZW46IEZpZWxkRGVmaW5pdGlvbjxSZWNvcmQ8c3RyaW5nLCBhbnk+PltdIHwgdW5kZWZpbmVkO1xuICAgIGxldCBjaGlsZFByb3BzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gaXRlbT8ucHJvcHMgfHwge307XG4gICAgbGV0IG1hcHBlcjogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgIGNvbnN0IGdldFBhdGggPSAocGFyZW50OiBzdHJpbmcgfCB1bmRlZmluZWQsIHByb3A6IHN0cmluZykgPT4ge1xuICAgICAgcmV0dXJuIHBhcmVudCA/IFtwYXJlbnQsIHByb3BdLmpvaW4oXCIuXCIpIDogcHJvcDtcbiAgICB9O1xuXG4gICAgaWYgKHVpRGVjb3JhdG9ycykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkRlY29yYXRvcnM6IFJlY29yZDxcbiAgICAgICAgc3RyaW5nLFxuICAgICAgICBEZWNvcmF0b3JNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+W11cbiAgICAgID4gPSBSZWZsZWN0aW9uLmdldEFsbFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgICAgbW9kZWwsXG4gICAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1RcbiAgICAgICkgYXMgUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPltdPjtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHVpRGVjb3JhdG9ycykge1xuICAgICAgICBjb25zdCBkZWNzID0gdWlEZWNvcmF0b3JzW2tleV07XG4gICAgICAgIGNvbnN0IHR5cGVzID0gT2JqZWN0LnZhbHVlcyhkZWNzKS5maWx0ZXIoKHtrZXl9KSA9PiBbVUlLZXlzLlBST1AsIFVJS2V5cy5FTEVNRU5ULCBVSUtleXMuQ0hJTERdLmluY2x1ZGVzKGtleSkpO1xuICAgICAgICBpZiAodHlwZXM/Lmxlbmd0aCA+IDEpXG4gICAgICAgICAgdGhyb3cgbmV3IFJlbmRlcmluZ0Vycm9yKFxuICAgICAgICAgICAgYE9ubHkgb25lIHR5cGUgb2YgZGVjb3JhdGlvbiBpcyBhbGxvd2VkLiBQbGVhc2UgY2hvb3NlIGJldHdlZW4gQHVpcHJvcCwgQHVpY2hpbGQgb3IgQHVpZWxlbWVudGBcbiAgICAgICAgICApO1xuICAgICAgICBjb25zdCBoYXNIaWRlT25EZWNvcmF0b3IgPSBkZWNzLmZpbmQoKHsga2V5IH0pID0+IGtleSA9PT0gVUlLZXlzLkhJRERFTik7XG4gICAgICAgIGlmKGhhc0hpZGVPbkRlY29yYXRvcikge1xuICAgICAgICAgIGNvbnN0IGhhc1VpRWxlbWVudERlY29yYXRvciA9IGRlY3MuZmluZCgoeyBrZXkgfSkgPT4ga2V5ID09PSBVSUtleXMuRUxFTUVOVCk7XG4gICAgICAgICAgaWYoIWhhc1VpRWxlbWVudERlY29yYXRvcilcbiAgICAgICAgICAgIHRocm93IG5ldyBSZW5kZXJpbmdFcnJvcihgQHVpZWxlbWVudCBubyBmb3VuZCBpbiBcIiR7a2V5fVwiLiBJdCBpcyByZXF1aXJlZCB0byB1c2UgaGlkZGVuT24gZGVjb3JhdG9yLmApO1xuXG4gICAgICAgIH1cbiAgICAgICAgZGVjcy5zaGlmdCgpO1xuICAgICAgICBjb25zdCBzb3J0ZWQgPSBkZWNzLnNvcnQoKGEpID0+IHtcbiAgICAgICAgICByZXR1cm4gYS5rZXkgPT09IFVJS2V5cy5FTEVNRU5UID8gLTEgOiAxO1xuICAgICAgICB9KTtcbiAgICAgICAgc29ydGVkLmZvckVhY2goKGRlYykgPT4ge1xuICAgICAgICAgIGlmICghZGVjKSB0aHJvdyBuZXcgUmVuZGVyaW5nRXJyb3IoYE5vIGRlY29yYXRvciBmb3VuZGApO1xuXG4gICAgICAgICAgc3dpdGNoIChkZWMua2V5KSB7XG4gICAgICAgICAgICBjYXNlIFVJS2V5cy5QUk9QOiB7XG4gICAgICAgICAgICAgIGNoaWxkUHJvcHNba2V5XSA9IGRlYy5wcm9wcyBhcyBVSVByb3BNZXRhZGF0YTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFVJS2V5cy5DSElMRDoge1xuICAgICAgICAgICAgICBpZiAoIU1vZGVsLmlzUHJvcGVydHlNb2RlbChtb2RlbCwga2V5KSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmVuZGVyaW5nRXJyb3IoYENoaWxkIFwiJHtrZXl9XCIgbXVzdCBiZSBhIG1vZGVsLmApO1xuXG4gICAgICAgICAgICAgIGxldCBDbGF6ejtcbiAgICAgICAgICAgICAgY29uc3Qgc3VibW9kZWwgPSAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSBhcyBNb2RlbDtcbiAgICAgICAgICAgICAgY29uc3QgY29uc3RydWN0YWJsZSA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIHN1Ym1vZGVsID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICAgICAgc3VibW9kZWwgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAhQXJyYXkuaXNBcnJheShzdWJtb2RlbCk7XG4gICAgICAgICAgICAgIC8vIGNyZWF0ZSBpbnN0YW5jZSBpZiB1bmRlZmluZWRcbiAgICAgICAgICAgICAgaWYgKCFjb25zdHJ1Y3RhYmxlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2xhenpOYW1lID0gKGRlYy5wcm9wcy5wcm9wcyBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVxuICAgICAgICAgICAgICAgICAgPy5uYW1lIGFzIHN0cmluZztcbiAgICAgICAgICAgICAgICBDbGF6eiA9IG5ldyAoTW9kZWwuZ2V0KGNsYXp6TmFtZSkgYXMgTW9kZWxDb25zdHJ1Y3RvcjxNb2RlbD4pKCk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuIHx8IFtdO1xuICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbkdsb2JhbFByb3BzID0gT2JqZWN0LmFzc2lnbih7fSwgZ2xvYmFsUHJvcHMgfHwge30sIHtcIm1vZGVsXCI6IENsYXp6fSAse1xuICAgICAgICAgICAgICAgIGluaGVyaXRQcm9wczogZGVjLnByb3BzIGFzIFVJTW9kZWxNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICBjaGlsZE9mOiBnZXRQYXRoKGdsb2JhbFByb3BzPy5jaGlsZE9mIGFzIHN0cmluZywga2V5KSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGNvbnN0IGNoaWxkRGVmaW5pdGlvbiA9IHRoaXMudG9GaWVsZERlZmluaXRpb24oXG4gICAgICAgICAgICAgICAgc3VibW9kZWwgfHwgQ2xhenosIC8vIE11c3QgYXZvaWQgdW5kZWZpbmVkIHZhbHVlcyDigJQgYW4gaW5zdGFuY2UgaXMgcmVxdWlyZWQgdG8gcmV0cmlldmUgcHJvcGVydGllcy5cbiAgICAgICAgICAgICAgICBjaGlsZHJlbkdsb2JhbFByb3BzLFxuICAgICAgICAgICAgICAgIGZhbHNlXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goXG4gICAgICAgICAgICAgICAgY2hpbGREZWZpbml0aW9uIGFzIEZpZWxkRGVmaW5pdGlvbjxSZWNvcmQ8c3RyaW5nLCBhbnk+PlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgVUlLZXlzLlVJTElTVFBST1A6IHtcbiAgICAgICAgICAgICAgbWFwcGVyID0gbWFwcGVyIHx8IHt9O1xuICAgICAgICAgICAgICBpZihkZWMucHJvcHM/Lm5hbWUpXG4gICAgICAgICAgICAgICAgbWFwcGVyW2RlYy5wcm9wcz8ubmFtZSBhcyBzdHJpbmddID0ga2V5O1xuICAgICAgICAgICAgICBjb25zdCBwcm9wcyA9IE9iamVjdC5hc3NpZ24oXG4gICAgICAgICAgICAgICAge30sXG4gICAgICAgICAgICAgICAgY2xhc3NEZWNvcmF0b3IucHJvcHM/Lml0ZW0gfHwge30sXG4gICAgICAgICAgICAgICAgaXRlbT8ucHJvcHMgfHwge30sXG4gICAgICAgICAgICAgICAgZGVjLnByb3BzPy5wcm9wcyB8fCB7fSxcbiAgICAgICAgICAgICAgICBnbG9iYWxQcm9wc1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBjaGlsZFByb3BzID0ge1xuICAgICAgICAgICAgICAgIHRhZzogaXRlbT8udGFnIHx8IHByb3BzLnJlbmRlciB8fCBcIlwiLFxuICAgICAgICAgICAgICAgIHByb3BzOiBPYmplY3QuYXNzaWduKFxuICAgICAgICAgICAgICAgICAge30sIFxuICAgICAgICAgICAgICAgICAgY2hpbGRQcm9wcz8ucHJvcHMsIFxuICAgICAgICAgICAgICAgICAgeyBtYXBwZXIgfSwgXG4gICAgICAgICAgICAgICAgICBwcm9wcyksXG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFVJS2V5cy5ISURERU46IFxuICAgICAgICAgICAgY2FzZSBVSUtleXMuT1JERVI6IFxuICAgICAgICAgICAgY2FzZSBVSUtleXMuVUlMQVlPVVRJVEVNOiBcbiAgICAgICAgICAgIGNhc2UgVUlLZXlzLkVMRU1FTlQ6IHtcbiAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiB8fCBbXTtcbiAgICAgICAgICAgICAgY29uc3QgdWlQcm9wczogVUlFbGVtZW50TWV0YWRhdGEgPSBkZWMucHJvcHMgYXMgVUlFbGVtZW50TWV0YWRhdGE7XG4gICAgICAgICAgICAgIGNvbnN0IHByb3BzID0gT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAgICAgICAgY2hpbGRQcm9wcz8ucHJvcHMsXG4gICAgICAgICAgICAgICAgICB1aVByb3BzLnByb3BzIHx8IHt9LFxuICAgICAgICAgICAgICAgICAgKHVpUHJvcHM/LnByb3BzPy5uYW1lID8ge1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiBnZXRQYXRoKFxuICAgICAgICAgICAgICAgICAgICAgIGdsb2JhbFByb3BzPy5jaGlsZE9mIGFzIHN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICB1aVByb3BzLnByb3BzIS5uYW1lXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkT2Y6IHVuZGVmaW5lZCwgLy8gVGhlIGNoaWxkT2YgcHJvcCBpcyBwYXNzZWQgYnkgZ2xvYmFsUHJvcHMgd2hlbiBpdCBpcyBhIG5lc3RlZCBwcm9wXG4gICAgICAgICAgICAgICAgICB9IDoge30pLFxuICAgICAgICAgICAgICAgICAgZ2xvYmFsUHJvcHNcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkRGVmaW5pdGlvbjogRmllbGREZWZpbml0aW9uPFJlY29yZDxzdHJpbmcsIGFueT4+ID0ge1xuICAgICAgICAgICAgICAgICAgdGFnOiAgdWlQcm9wcy50YWcgfHwgY2hpbGRQcm9wcz8udGFnIHx8IHRhZyB8fCBcIlwiLFxuICAgICAgICAgICAgICAgICAgcHJvcHMsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgaWYoZGVjLmtleSA9PT0gVUlLZXlzLkVMRU1FTlQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZGF0aW9uRGVjcyA9IHZhbGlkYXRpb25EZWNvcmF0b3JzW2tleV0gYXMgRGVjb3JhdG9yTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPltdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVEZWMgPSB2YWxpZGF0aW9uRGVjcy5zaGlmdCgpIGFzIERlY29yYXRvck1ldGFkYXRhO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZGVjIG9mIHZhbGlkYXRpb25EZWNzKSB7XG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1ZhbGlkYXRhYmxlQnlBdHRyaWJ1dGUoZGVjLmtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGREZWZpbml0aW9uLnByb3BzW3RoaXMudHJhbnNsYXRlKGRlYy5rZXkpXSA9IHRoaXMudG9BdHRyaWJ1dGVWYWx1ZShkZWMua2V5LCBkZWMucHJvcHMpO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzVmFsaWRhdGFibGVCeVR5cGUoZGVjLmtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlYy5rZXkgPT09IEhUTUw1SW5wdXRUeXBlcy5EQVRFKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY2hpbGREZWZpbml0aW9uLnByb3BzW1VJS2V5cy5GT1JNQVRdID0gZGVjLnByb3BzLmZvcm1hdCB8fCBIVE1MNURhdGVGb3JtYXQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2hpbGREZWZpbml0aW9uLnByb3BzW1VJS2V5cy5UWVBFXSA9IGRlYy5rZXk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghY2hpbGREZWZpbml0aW9uLnByb3BzW1VJS2V5cy5UWVBFXSkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgYmFzaWNUeXBlID0gKHR5cGVEZWMucHJvcHMgYXMgeyBuYW1lOiBzdHJpbmcgfSkubmFtZTtcbiAgICAgICAgICAgICAgICAgIGNoaWxkRGVmaW5pdGlvbi5wcm9wc1tVSUtleXMuVFlQRV0gPSB0aGlzLnRyYW5zbGF0ZShcbiAgICAgICAgICAgICAgICAgICAgYmFzaWNUeXBlLnRvTG93ZXJDYXNlKCksXG4gICAgICAgICAgICAgICAgICAgIHRydWVcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY2hpbGREZWZpbml0aW9uLnByb3BzLnZhbHVlID0gZm9ybWF0QnlUeXBlKFxuICAgICAgICAgICAgICAgICAgY2hpbGREZWZpbml0aW9uLnByb3BzW1VJS2V5cy5UWVBFXSxcbiAgICAgICAgICAgICAgICAgIG1vZGVsW2tleSBhcyBrZXlvZiBNXSxcbiAgICAgICAgICAgICAgICAgIGNoaWxkRGVmaW5pdGlvbi5wcm9wc1tVSUtleXMuRk9STUFUXVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW4ucHVzaChjaGlsZERlZmluaXRpb24pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkID0gY2hpbGRyZW4uZmluZChjID0+IGMucHJvcHM/Lm5hbWUgPT09IGtleSB8fCBkZWMua2V5ID09PSBVSUtleXMuVUlMQVlPVVRJVEVNICYmIGM/LnByb3BzPy5jaGlsZE9mID09PSBrZXkpO1xuICAgICAgICAgICAgICAgIGlmIChjaGlsZCkge1xuICAgICAgICAgICAgICAgICAgaWYoZGVjLmtleSAhPT0gVUlLZXlzLlVJTEFZT1VUSVRFTSkge1xuICAgICAgICAgICAgICAgICAgICBjaGlsZC5wcm9wcyA9IE9iamVjdC5hc3NpZ24oe30sIGNoaWxkLnByb3BzLCB7IFtkZWMua2V5XTogdWlQcm9wcyB9KTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHtyb3csIGNvbCwgcHJvcHN9ID0gZGVjLnByb3BzO1xuICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnByb3BzID0gT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgICAgICAgICAgICB7fSwgXG4gICAgICAgICAgICAgICAgICAgICAgcHJvcHMgfHwge30sXG4gICAgICAgICAgICAgICAgICAgICAgY2hpbGQucHJvcHMsXG4gICAgICAgICAgICAgICAgICAgICAgcm93LFxuICAgICAgICAgICAgICAgICAgICAgIGNvbFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGNoaWxkRGVmaW5pdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlbmRlcmluZ0Vycm9yKGBJbnZhbGlkIGtleTogJHtkZWMua2V5fWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZ2xvYmFsUHJvcHMgPSBPYmplY3QuYXNzaWduKHt9LCBwcm9wcywgZ2xvYmFsUHJvcHMsIHtcbiAgICAgIGhhbmRsZXJzOiBoYW5kbGVycyB8fCB7fSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG9wZXJhdGlvbiA9IGdsb2JhbFByb3BzPy5vcGVyYXRpb247XG4gICAgY2hpbGRyZW4gPSBjaGlsZHJlbj8uc29ydCgoYSwgYikgPT4gKChhPy5wcm9wcz8ub3JkZXIgPz8gMCkgLSAoYj8ucHJvcHM/Lm9yZGVyID8/IDApKSlcbiAgICAgIC5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgICAgY29uc3QgaGlkZGVuT24gPSAoaXRlbT8ucHJvcHM/LmhpZGRlbiBhcyBDcnVkT3BlcmF0aW9uS2V5c1tdIHx8IFtdKTtcbiAgICAgICAgaWYoIWhpZGRlbk9uPy5sZW5ndGgpXG4gICAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgICAgIGlmKCFoaWRkZW5Pbi5pbmNsdWRlcyhvcGVyYXRpb24gYXMgQ3J1ZE9wZXJhdGlvbktleXMpKVxuICAgICAgICAgIHJldHVybiBpdGVtO1xuICAgICAgfSk7XG4gICAgY29uc3QgcmVzdWx0OiBGaWVsZERlZmluaXRpb248VD4gPSB7XG4gICAgICB0YWc6IHRhZyxcbiAgICAgIGl0ZW06IGNoaWxkUHJvcHMgYXMgVUlMaXN0SXRlbUVsZW1lbnRNZXRhZGF0YSxcbiAgICAgIHByb3BzOiBnbG9iYWxQcm9wcyBhcyBUICYgRmllbGRQcm9wZXJ0aWVzLFxuICAgICAgY2hpbGRyZW46IGNoaWxkcmVuIGFzIEZpZWxkRGVmaW5pdGlvbjxhbnk+W10sXG4gICAgXG4gICAgfTtcblxuICAgIGlmIChnZW5lcmF0ZUlkKSByZXN1bHQucmVuZGVyZXJJZCA9IGdlbmVyYXRlVUlNb2RlbElEKG1vZGVsKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlbmRlcnMgYSBtb2RlbCB3aXRoIGdsb2JhbCBwcm9wZXJ0aWVzIGFuZCBhZGRpdGlvbmFsIGFyZ3VtZW50cy5cbiAgICogQHN1bW1hcnkgQWJzdHJhY3QgbWV0aG9kIHRvIGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzZXMgdG8gZGVmaW5lIHNwZWNpZmljIHJlbmRlcmluZyBiZWhhdmlvci5cbiAgICpcbiAgICogQHRlbXBsYXRlIE0gVHlwZSBleHRlbmRpbmcgTW9kZWxcbiAgICogQHRlbXBsYXRlIFIgUmVuZGVyaW5nIGVuZ2luZSBpbXBsZW1lbnRhdGlvbiBzcGVjaWZpYyBvdXRwdXQgdHlwZVxuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIHRvIGJlIHJlbmRlcmVkLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSBnbG9iYWxQcm9wcyAtIEdsb2JhbCBwcm9wZXJ0aWVzIHRvIGJlIGFwcGxpZWQgdG8gYWxsIGVsZW1lbnRzIGR1cmluZyByZW5kZXJpbmcuXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0aGF0IG1heSBiZSByZXF1aXJlZCBmb3Igc3BlY2lmaWMgcmVuZGVyaW5nIGltcGxlbWVudGF0aW9ucy5cbiAgICogQHJldHVybnMge1J9IFRoZSByZW5kZXJlZCByZXN1bHQsIHR5cGUgZGVwZW5kcyBvbiB0aGUgc3BlY2lmaWMgaW1wbGVtZW50YXRpb24uXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKi9cbiAgYWJzdHJhY3QgcmVuZGVyPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgbW9kZWw6IE0sXG4gICAgZ2xvYmFsUHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFI7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWdpc3RlcnMgYSByZW5kZXJpbmcgZW5naW5lIGluc3RhbmNlLlxuICAgKiBAc3VtbWFyeSBBZGRzIGEgcmVuZGVyaW5nIGVuZ2luZSB0byB0aGUgc3RhdGljIGNhY2hlIGFuZCBzZXRzIGl0IGFzIHRoZSBjdXJyZW50IGVuZ2luZS5cbiAgICpcbiAgICogQHBhcmFtIHtSZW5kZXJpbmdFbmdpbmU8dW5rbm93biwgdW5rbm93bj59IGVuZ2luZSAtIFRoZSByZW5kZXJpbmcgZW5naW5lIHRvIHJlZ2lzdGVyLlxuICAgKiBAdGhyb3dzIHtJbnRlcm5hbEVycm9yfSBJZiBhbiBlbmdpbmUgd2l0aCB0aGUgc2FtZSBmbGF2b3IgYWxyZWFkeSBleGlzdHMuXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICovXG4gIHN0YXRpYyByZWdpc3RlcihlbmdpbmU6IFJlbmRlcmluZ0VuZ2luZTx1bmtub3duLCB1bmtub3duPikge1xuICAgIGlmIChlbmdpbmUuZmxhdm91ciBpbiB0aGlzLmNhY2hlKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBSZW5kZXJpbmcgZW5naW5lIHVuZGVyICR7ZW5naW5lLmZsYXZvdXJ9IGFscmVhZHkgZXhpc3RzYFxuICAgICAgKTtcbiAgICB0aGlzLmNhY2hlW2VuZ2luZS5mbGF2b3VyXSA9IGVuZ2luZTtcbiAgICB0aGlzLmN1cnJlbnQgPSBlbmdpbmU7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBvciBpbml0aWFsaXplcyBhIHJlbmRlcmluZyBlbmdpbmUuXG4gICAqIEBzdW1tYXJ5IEdldHMgYW4gZXhpc3RpbmcgZW5naW5lIGluc3RhbmNlIG9yIGNyZWF0ZXMgYW5kIGluaXRpYWxpemVzIGEgbmV3IG9uZSBpZiBnaXZlbiBhIGNvbnN0cnVjdG9yLlxuICAgKlxuICAgKiBAdGVtcGxhdGUgTyBUaGUgdHlwZSBvZiB0aGUgcmVuZGVyaW5nIGVuZ2luZSBvdXRwdXRcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxSZW5kZXJpbmdFbmdpbmU8Tz4+IHwgUmVuZGVyaW5nRW5naW5lPE8+fSBvYmogLSBUaGUgZW5naW5lIGluc3RhbmNlIG9yIGNvbnN0cnVjdG9yLlxuICAgKiBAcmV0dXJucyB7UmVuZGVyaW5nRW5naW5lPE8+fSBUaGUgaW5pdGlhbGl6ZWQgcmVuZGVyaW5nIGVuZ2luZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0T3JCb290PE8+KFxuICAgIG9iajogQ29uc3RydWN0b3I8UmVuZGVyaW5nRW5naW5lPE8+PiB8IFJlbmRlcmluZ0VuZ2luZTxPPlxuICApOiBSZW5kZXJpbmdFbmdpbmU8Tz4ge1xuICAgIGlmIChvYmogaW5zdGFuY2VvZiBSZW5kZXJpbmdFbmdpbmUpIHJldHVybiBvYmogYXMgUmVuZGVyaW5nRW5naW5lPE8+O1xuICAgIGNvbnN0IGVuZ2luZTogUmVuZGVyaW5nRW5naW5lPE8+ID0gbmV3IG9iaigpO1xuICAgIGVuZ2luZS5pbml0aWFsaXplKCk7IC8vIG1ha2UgdGhlIGJvb3RpbmcgYXN5bmMuIHVzZSB0aGUgaW5pdGlhbGl6ZWQgZmxhZyB0byBjb250cm9sIGl0XG4gICAgcmV0dXJuIGVuZ2luZSBhcyBSZW5kZXJpbmdFbmdpbmU8Tz47XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhIHJlbmRlcmluZyBlbmdpbmUgYnkgZmxhdm9yLlxuICAgKiBAc3VtbWFyeSBHZXRzIHRoZSBjdXJyZW50IHJlbmRlcmluZyBlbmdpbmUgb3IgYSBzcGVjaWZpYyBvbmUgYnkgZmxhdm9yLlxuICAgKlxuICAgKiBAdGVtcGxhdGUgTyBUaGUgdHlwZSBvZiB0aGUgcmVuZGVyaW5nIGVuZ2luZSBvdXRwdXRcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtmbGF2b3VyXSAtIFRoZSBmbGF2b3Igb2YgdGhlIHJlbmRlcmluZyBlbmdpbmUgdG8gcmV0cmlldmUuXG4gICAqIEByZXR1cm5zIHtSZW5kZXJpbmdFbmdpbmU8Tz59IFRoZSByZXF1ZXN0ZWQgcmVuZGVyaW5nIGVuZ2luZS5cbiAgICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gSWYgdGhlIHJlcXVlc3RlZCBmbGF2b3IgZG9lcyBub3QgZXhpc3QuXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICovXG4gIHN0YXRpYyBnZXQ8Tz4oZmxhdm91cj86IHN0cmluZyk6IFJlbmRlcmluZ0VuZ2luZTxPPiB7XG4gICAgaWYgKCFmbGF2b3VyKVxuICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JCb290PE8+KFxuICAgICAgICB0aGlzLmN1cnJlbnQgYXMgQ29uc3RydWN0b3I8UmVuZGVyaW5nRW5naW5lPE8+PiB8IFJlbmRlcmluZ0VuZ2luZTxPPlxuICAgICAgKTtcbiAgICBpZiAoIShmbGF2b3VyIGluIHRoaXMuY2FjaGUpKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBSZW5kZXJpbmcgZW5naW5lIHVuZGVyICR7Zmxhdm91cn0gZG9lcyBub3QgZXhpc3RgXG4gICAgICApO1xuICAgIHJldHVybiB0aGlzLmdldE9yQm9vdDxPPihcbiAgICAgIHRoaXMuY2FjaGVbZmxhdm91cl0gYXNcbiAgICAgICAgfCBDb25zdHJ1Y3RvcjxSZW5kZXJpbmdFbmdpbmU8Tz4+XG4gICAgICAgIHwgUmVuZGVyaW5nRW5naW5lPE8+XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVuZGVycyBhIG1vZGVsIHVzaW5nIHRoZSBhcHByb3ByaWF0ZSByZW5kZXJpbmcgZW5naW5lLlxuICAgKiBAc3VtbWFyeSBEZXRlcm1pbmVzIHRoZSBjb3JyZWN0IHJlbmRlcmluZyBlbmdpbmUgZm9yIGEgbW9kZWwgYW5kIGludm9rZXMgaXRzIHJlbmRlciBtZXRob2QuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBNIFR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgdG8gcmVuZGVyLlxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgcmVuZGVyIG1ldGhvZC5cbiAgICogQHJldHVybnMge2FueX0gVGhlIHJlc3VsdCBvZiB0aGUgcmVuZGVyaW5nIHByb2Nlc3MuXG4gICAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IElmIG5vIHJlZ2lzdGVyZWQgbW9kZWwgaXMgZm91bmQuXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICovXG4gIHN0YXRpYyByZW5kZXI8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSwgLi4uYXJnczogYW55W10pOiBhbnkge1xuICAgIGNvbnN0IGNvbnN0cnVjdG9yID1cbiAgICAgIE1vZGVsLmdldChtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lKSB8fCBNb2RlbC5mcm9tT2JqZWN0KG1vZGVsKTtcbiAgICBpZiAoIWNvbnN0cnVjdG9yKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIk5vIG1vZGVsIHJlZ2lzdGVyZWQgZm91bmRcIik7XG4gICAgY29uc3QgZmxhdm91ciA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5SRU5ERVJFRF9CWSksXG4gICAgICBjb25zdHJ1Y3RvciBhcyBNb2RlbENvbnN0cnVjdG9yPE1vZGVsPlxuICAgICk7XG5cbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGZvciB0aGUgdmFyIGFyZ3MgdHlwZSBjaGVja1xuICAgIHJldHVybiBSZW5kZXJpbmdFbmdpbmUuZ2V0KGZsYXZvdXIpLnJlbmRlcihtb2RlbCwgLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdlbmVyYXRlcyBhIG1ldGFkYXRhIGtleSBmb3IgVUktcmVsYXRlZCBwcm9wZXJ0aWVzLlxuICAgKiBAc3VtbWFyeSBQcmVmaXhlcyBhIGdpdmVuIGtleSB3aXRoIHRoZSBVSSByZWZsZWN0aW9uIHByZWZpeC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBrZXkgdG8gcHJlZml4LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgcHJlZml4ZWQga2V5LlxuICAgKlxuICAgKiBAc3RhdGljXG4gICAqL1xuICBzdGF0aWMga2V5KGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7VUlLZXlzLlJFRkxFQ1R9JHtrZXl9YDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgVUlLZXlzIH0gZnJvbSBcIi4uL3VpL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgYXBwbHksIG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBSZW5kZXJpbmdFbmdpbmUgfSBmcm9tIFwiLi4vdWkvUmVuZGVyaW5nXCI7XG5pbXBvcnQgeyBVSUxpc3RJdGVtTW9kZWxNZXRhZGF0YSwgVUlNZWRpYUJyZWFrUG9pbnRzVHlwZSwgVUlNb2RlbE1ldGFkYXRhIH0gZnJvbSBcIi4uL3VpL3R5cGVzXCI7XG5pbXBvcnQgeyBVSU1lZGlhQnJlYWtQb2ludHMgfSBmcm9tIFwiLi4vdWkvY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciB0aGF0IHRhZ3MgYSBjbGFzcyBhcyBhIFVJIG1vZGVsXG4gKiBAc3VtbWFyeSBBZGRzIHJlbmRlcmluZyBjYXBhYmlsaXRpZXMgdG8gYSBtb2RlbCBjbGFzcyBieSBwcm92aWRpbmcgYSByZW5kZXIgbWV0aG9kXG4gKiBUaGlzIGRlY29yYXRvciBhcHBsaWVzIG1ldGFkYXRhIHRvIHRoZSBjbGFzcyB0aGF0IGVuYWJsZXMgaXQgdG8gYmUgcmVuZGVyZWQgYnkgdGhlIFVJIHJlbmRlcmluZyBlbmdpbmUuXG4gKiBUaGUgbW9kZWwgd2lsbCBiZSByZW5kZXJlZCB3aXRoIHRoZSBzcGVjaWZpZWQgdGFnIGFuZCBwcm9wZXJ0aWVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbdGFnXSBUaGUgSFRNTCB0YWcgdG8gdXNlIHdoZW4gcmVuZGVyaW5nIHRoaXMgbW9kZWwgKGRlZmF1bHRzIHRvIGNsYXNzIG5hbWUpXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IFtwcm9wc10gQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIHBhc3MgdG8gdGhlIHJlbmRlcmVkIGVsZW1lbnRcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGNsYXNzIGRlY29yYXRvciBmdW5jdGlvblxuICpcbiAqIEBmdW5jdGlvbiB1aW1vZGVsXG4gKiBAY2F0ZWdvcnkgQ2xhc3MgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBCYXNpYyB1c2FnZSB3aXRoIGRlZmF1bHQgdGFnIChjbGFzcyBuYW1lKVxuICogQHVpbW9kZWwoKVxuICogY2xhc3MgVXNlclByb2ZpbGUgZXh0ZW5kcyBNb2RlbCB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBuYW1lOiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgZW1haWw6IHN0cmluZztcbiAqIH1cbiAqXG4gKiAvLyBVc2FnZSB3aXRoIGN1c3RvbSB0YWcgYW5kIHByb3BlcnRpZXNcbiAqIEB1aW1vZGVsKCdkaXYnLCB7IGNsYXNzOiAndXNlci1jYXJkJyB9KVxuICogY2xhc3MgVXNlckNhcmQgZXh0ZW5kcyBNb2RlbCB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICB1c2VybmFtZTogc3RyaW5nO1xuICogfVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgU3lzdGVtXG4gKiAgIHBhcnRpY2lwYW50IHVpbW9kZWxcbiAqICAgcGFydGljaXBhbnQgY29uc3RydWN0b3JcbiAqICAgcGFydGljaXBhbnQgaW5zdGFuY2VcbiAqICAgU3lzdGVtLT4+dWltb2RlbDpkbyhjb25zdHJ1Y3RvcilcbiAqICAgdWltb2RlbC0+PmNvbnN0cnVjdG9yOiBFeGVjdXRlcyB0aGUgY29uc3RydWN0b3JcbiAqICAgY29uc3RydWN0b3ItPj51aW1vZGVsOiByZXR1cm5zIGluc3RhbmNlXG4gKiAgIHVpbW9kZWwtPj5pbnN0YW5jZTogYWRkcyB0aGUgcmVuZGVyIG1ldGhvZFxuICogICB1aW1vZGVsLT4+U3lzdGVtOiByZXR1cm5zIFVJTW9kZWwgaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVpbW9kZWwodGFnPzogc3RyaW5nLCBwcm9wcz86IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICByZXR1cm4gKG9yaWdpbmFsOiBhbnksIHByb3BlcnR5S2V5PzogYW55KSA9PiB7XG4gICAgY29uc3QgbWV0YTogVUlNb2RlbE1ldGFkYXRhID0ge1xuICAgICAgdGFnOiB0YWcgfHwgb3JpZ2luYWwubmFtZSxcbiAgICAgIHByb3BzOiBwcm9wcyxcbiAgICB9O1xuICAgIHJldHVybiBtZXRhZGF0YShSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5VSU1PREVMKSwgbWV0YSkob3JpZ2luYWwpO1xuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCBzcGVjaWZpZXMgd2hpY2ggcmVuZGVyaW5nIGVuZ2luZSB0byB1c2UgZm9yIGEgbW9kZWxcbiAqIEBzdW1tYXJ5IEFzc29jaWF0ZXMgYSBtb2RlbCB3aXRoIGEgc3BlY2lmaWMgcmVuZGVyaW5nIGVuZ2luZSBpbXBsZW1lbnRhdGlvblxuICogVGhpcyBkZWNvcmF0b3IgYWxsb3dzIHlvdSB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCByZW5kZXJpbmcgZW5naW5lIGZvciBhIHNwZWNpZmljIG1vZGVsIGNsYXNzLFxuICogZW5hYmxpbmcgZGlmZmVyZW50IHJlbmRlcmluZyBzdHJhdGVnaWVzIGZvciBkaWZmZXJlbnQgbW9kZWxzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBlbmdpbmUgVGhlIG5hbWUgb2YgdGhlIHJlbmRlcmluZyBlbmdpbmUgdG8gdXNlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBjbGFzcyBkZWNvcmF0b3IgZnVuY3Rpb25cbiAqXG4gKiBAZnVuY3Rpb24gcmVuZGVyZWRCeVxuICogQGNhdGVnb3J5IENsYXNzIERlY29yYXRvcnNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU3BlY2lmeSBhIGN1c3RvbSByZW5kZXJpbmcgZW5naW5lIGZvciBhIG1vZGVsXG4gKiBAdWltb2RlbCgpXG4gKiBAcmVuZGVyZWRCeSgncmVhY3QnKVxuICogY2xhc3MgUmVhY3RDb21wb25lbnQgZXh0ZW5kcyBNb2RlbCB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICB0aXRsZTogc3RyaW5nO1xuICogfVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgU3lzdGVtXG4gKiAgIHBhcnRpY2lwYW50IHJlbmRlcmVkQnlcbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgcGFydGljaXBhbnQgUmVuZGVyaW5nRW5naW5lXG4gKiAgIFN5c3RlbS0+PnJlbmRlcmVkQnk6IGFwcGx5IHRvIE1vZGVsXG4gKiAgIHJlbmRlcmVkQnktPj5Nb2RlbDogYWRkcyBlbmdpbmUgbWV0YWRhdGFcbiAqICAgTW9kZWwtPj5SZW5kZXJpbmdFbmdpbmU6IHVzZXMgc3BlY2lmaWVkIGVuZ2luZVxuICogICBSZW5kZXJpbmdFbmdpbmUtPj5TeXN0ZW06IHJlbmRlcnMgd2l0aCBjdXN0b20gZW5naW5lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJlZEJ5KGVuZ2luZTogc3RyaW5nKSB7XG4gIHJldHVybiBhcHBseShtZXRhZGF0YShSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5SRU5ERVJFRF9CWSksIGVuZ2luZSkpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCB0YWdzIGEgbW9kZWwgYXMgYSBsaXN0IGl0ZW0gZm9yIFVJIHJlbmRlcmluZ1xuICogQHN1bW1hcnkgU3BlY2lmaWVzIGhvdyBhIG1vZGVsIHNob3VsZCBiZSByZW5kZXJlZCB3aGVuIGRpc3BsYXllZCBpbiBhIGxpc3QgY29udGV4dFxuICogVGhpcyBkZWNvcmF0b3IgYXBwbGllcyBtZXRhZGF0YSB0byB0aGUgY2xhc3MgdGhhdCBlbmFibGVzIGl0IHRvIGJlIHJlbmRlcmVkIGFzIGEgbGlzdCBpdGVtXG4gKiBieSB0aGUgVUkgcmVuZGVyaW5nIGVuZ2luZS4gVGhlIG1vZGVsIHdpbGwgYmUgcmVuZGVyZWQgd2l0aCB0aGUgc3BlY2lmaWVkIHRhZyBhbmQgcHJvcGVydGllc1xuICogd2hlbiBpdCBhcHBlYXJzIGluIGEgbGlzdC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW3RhZ10gVGhlIEhUTUwgdGFnIHRvIHVzZSB3aGVuIHJlbmRlcmluZyB0aGlzIG1vZGVsIGFzIGEgbGlzdCBpdGVtIChkZWZhdWx0cyB0byBjbGFzcyBuYW1lKVxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbcHJvcHNdIEFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBwYXNzIHRvIHRoZSByZW5kZXJlZCBsaXN0IGl0ZW0gZWxlbWVudFxuICogQHJldHVybiB7RnVuY3Rpb259IEEgY2xhc3MgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gKlxuICogQGZ1bmN0aW9uIHVpbGlzdGl0ZW1cbiAqIEBjYXRlZ29yeSBDbGFzcyBEZWNvcmF0b3JzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEJhc2ljIHVzYWdlIHdpdGggZGVmYXVsdCB0YWcgKGNsYXNzIG5hbWUpXG4gKiBAdWltb2RlbCgpXG4gKiBAdWlsaXN0aXRlbSgpXG4gKiBjbGFzcyBUb2RvSXRlbSBleHRlbmRzIE1vZGVsIHtcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIHRpdGxlOiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgY29tcGxldGVkOiBib29sZWFuO1xuICogfVxuICpcbiAqIC8vIFVzYWdlIHdpdGggY3VzdG9tIHRhZyBhbmQgcHJvcGVydGllc1xuICogQHVpbW9kZWwoKVxuICogQHVpbGlzdGl0ZW0oJ2xpJywgeyBjbGFzczogJ2xpc3QtZ3JvdXAtaXRlbScgfSlcbiAqIGNsYXNzIExpc3RJdGVtIGV4dGVuZHMgTW9kZWwge1xuICogICBAYXR0cmlidXRlKClcbiAqICAgdGV4dDogc3RyaW5nO1xuICogfVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgU3lzdGVtXG4gKiAgIHBhcnRpY2lwYW50IHVpbGlzdGl0ZW1cbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgcGFydGljaXBhbnQgUmVuZGVyaW5nRW5naW5lXG4gKiAgIFN5c3RlbS0+PnVpbGlzdGl0ZW06IGFwcGx5IHRvIE1vZGVsXG4gKiAgIHVpbGlzdGl0ZW0tPj5Nb2RlbDogYWRkcyBsaXN0IGl0ZW0gbWV0YWRhdGFcbiAqICAgTW9kZWwtPj5SZW5kZXJpbmdFbmdpbmU6IHVzZXMgbGlzdCBpdGVtIG1ldGFkYXRhIHdoZW4gaW4gbGlzdCBjb250ZXh0XG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+PlN5c3RlbTogcmVuZGVycyB3aXRoIGxpc3QgaXRlbSBzdHlsaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1aWxpc3RpdGVtKHRhZz86IHN0cmluZywgcHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgcmV0dXJuIChvcmlnaW5hbDogYW55LCBwcm9wZXJ0eUtleT86IGFueSkgPT4ge1xuICAgIGNvbnN0IG1ldGE6IFVJTGlzdEl0ZW1Nb2RlbE1ldGFkYXRhID0ge1xuICAgICAgaXRlbToge1xuICAgICAgICB0YWc6IHRhZyB8fCBvcmlnaW5hbC5uYW1lLFxuICAgICAgICBwcm9wczogcHJvcHMsXG4gICAgICB9LFxuICAgIH07XG4gICAgcmV0dXJuIG1ldGFkYXRhKFJlbmRlcmluZ0VuZ2luZS5rZXkoVUlLZXlzLlVJTElTVElURU0pLCBtZXRhKShvcmlnaW5hbCk7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciB0aGF0IGFkZHMgZXZlbnQgaGFuZGxlcnMgdG8gYSBVSSBtb2RlbFxuICogQHN1bW1hcnkgU3BlY2lmaWVzIGV2ZW50IGhhbmRsZXJzIHRoYXQgc2hvdWxkIGJlIGF0dGFjaGVkIHRvIHRoZSByZW5kZXJlZCBtb2RlbFxuICogVGhpcyBkZWNvcmF0b3IgYWxsb3dzIHlvdSB0byBkZWZpbmUgZXZlbnQgaGFuZGxlcnMgdGhhdCB3aWxsIGJlIGF1dG9tYXRpY2FsbHlcbiAqIGF0dGFjaGVkIHRvIHRoZSByZW5kZXJlZCBVSSBlbGVtZW50LiBUaGUgaGFuZGxlcnMgYXJlIHBhc3NlZCBhcyBwcm9wZXJ0aWVzXG4gKiB0byB0aGUgcmVuZGVyaW5nIGVuZ2luZS5cbiAqXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IFtwcm9wc10gT2JqZWN0IGNvbnRhaW5pbmcgZXZlbnQgaGFuZGxlciBmdW5jdGlvbnMgYW5kIG90aGVyIHByb3BlcnRpZXNcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGNsYXNzIGRlY29yYXRvciBmdW5jdGlvblxuICpcbiAqIEBmdW5jdGlvbiB1aWhhbmRsZXJzXG4gKiBAY2F0ZWdvcnkgQ2xhc3MgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBBZGQgZXZlbnQgaGFuZGxlcnMgdG8gYSBtb2RlbFxuICogQHVpbW9kZWwoJ2J1dHRvbicpXG4gKiBAdWloYW5kbGVycyh7XG4gKiAgIG9uQ2xpY2s6IChldmVudCkgPT4gY29uc29sZS5sb2coJ0J1dHRvbiBjbGlja2VkJyksXG4gKiAgIG9uTW91c2VPdmVyOiAoZXZlbnQpID0+IGNvbnNvbGUubG9nKCdNb3VzZSBvdmVyIGJ1dHRvbicpLFxuICogICBkaXNhYmxlZDogZmFsc2VcbiAqIH0pXG4gKiBjbGFzcyBDbGlja2FibGVCdXR0b24gZXh0ZW5kcyBNb2RlbCB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBsYWJlbDogc3RyaW5nO1xuICogfVxuICpcbiAqIC8vIEFkZCBmb3JtIHN1Ym1pc3Npb24gaGFuZGxlcnNcbiAqIEB1aW1vZGVsKCdmb3JtJylcbiAqIEB1aWhhbmRsZXJzKHtcbiAqICAgb25TdWJtaXQ6IChldmVudCkgPT4ge1xuICogICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gKiAgICAgY29uc29sZS5sb2coJ0Zvcm0gc3VibWl0dGVkJyk7XG4gKiAgIH0sXG4gKiAgIG9uUmVzZXQ6IChldmVudCkgPT4gY29uc29sZS5sb2coJ0Zvcm0gcmVzZXQnKVxuICogfSlcbiAqIGNsYXNzIENvbnRhY3RGb3JtIGV4dGVuZHMgTW9kZWwge1xuICogICBAYXR0cmlidXRlKClcbiAqICAgZW1haWw6IHN0cmluZztcbiAqIH1cbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IFN5c3RlbVxuICogICBwYXJ0aWNpcGFudCB1aWhhbmRsZXJzXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IFJlbmRlcmluZ0VuZ2luZVxuICogICBwYXJ0aWNpcGFudCBVSVxuICogICBTeXN0ZW0tPj51aWhhbmRsZXJzOiBhcHBseSB0byBNb2RlbFxuICogICB1aWhhbmRsZXJzLT4+TW9kZWw6IGFkZHMgaGFuZGxlciBtZXRhZGF0YVxuICogICBNb2RlbC0+PlJlbmRlcmluZ0VuZ2luZTogcmVxdWVzdHMgcmVuZGVyaW5nIHdpdGggaGFuZGxlcnNcbiAqICAgUmVuZGVyaW5nRW5naW5lLT4+VUk6IHJlbmRlcnMgZWxlbWVudCB3aXRoIGV2ZW50IGhhbmRsZXJzIGF0dGFjaGVkXG4gKiAgIFVJLT4+TW9kZWw6IHRyaWdnZXJzIGhhbmRsZXJzIG9uIGV2ZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gdWloYW5kbGVycyhwcm9wcz86IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgcmV0dXJuIChvcmlnaW5hbDogYW55KSA9PiB7XG4gICAgY29uc3QgbWV0YSA9IHtcbiAgICAgIGhhbmRsZXJzOiBwcm9wc1xuICAgIH07XG4gICAgcmV0dXJuIG1ldGFkYXRhKFJlbmRlcmluZ0VuZ2luZS5rZXkoVUlLZXlzLkhBTkRMRVJTKSwgbWV0YSkob3JpZ2luYWwpO1xuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCBjcmVhdGVzIGEgbGF5b3V0IGNvbnRhaW5lciB3aXRoIGdyaWQgc3BlY2lmaWNhdGlvbnNcbiAqIEBzdW1tYXJ5IENvbWJpbmVzIFVJIG1vZGVsIGZ1bmN0aW9uYWxpdHkgd2l0aCBsYXlvdXQgZ3JpZCBjb25maWd1cmF0aW9uXG4gKiBUaGlzIGRlY29yYXRvciBjcmVhdGVzIGEgVUkgbW9kZWwgdGhhdCBhY3RzIGFzIGEgbGF5b3V0IGNvbnRhaW5lciB3aXRoIHNwZWNpZmllZFxuICogY29sdW1uIGFuZCByb3cgY29uZmlndXJhdGlvbnMuIEl0J3MgYSBjb252ZW5pZW5jZSBkZWNvcmF0b3IgdGhhdCBjb21iaW5lc1xuICogQHVpbW9kZWwgd2l0aCBsYXlvdXQtc3BlY2lmaWMgcHJvcGVydGllcyBmb3IgcmVzcG9uc2l2ZSBncmlkIGxheW91dHMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgSFRNTCB0YWcgdG8gdXNlIGZvciB0aGUgbGF5b3V0IGNvbnRhaW5lclxuICogQHBhcmFtIHtudW1iZXJ9IFtjb2xzPTFdIE51bWJlciBvZiBjb2x1bW5zIGluIHRoZSBncmlkIGxheW91dFxuICogQHBhcmFtIHtudW1iZXJ8c3RyaW5nW119IFtyb3dzPTFdIE51bWJlciBvZiByb3dzIG9yIGFycmF5IG9mIHJvdyBkZWZpbml0aW9uc1xuICogQHBhcmFtIHtVSU1lZGlhQnJlYWtQb2ludHN9IFticmVha3BvaW50PSdtJ10gTWVkaWEgYnJlYWtwb2ludCBmb3IgcmVzcG9uc2l2ZSBiZWhhdmlvclxuICogQHJldHVybiB7RnVuY3Rpb259IEEgY2xhc3MgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gKlxuICogQGZ1bmN0aW9uIHVpbGF5b3V0XG4gKiBAY2F0ZWdvcnkgQ2xhc3MgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDcmVhdGUgYSBzaW1wbGUgMi1jb2x1bW4gbGF5b3V0XG4gKiBAdWlsYXlvdXQoJ2RpdicsIDIsIDMpXG4gKiBjbGFzcyBUd29Db2x1bW5MYXlvdXQgZXh0ZW5kcyBNb2RlbCB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWlsYXlvdXRpdGVtKDEsIDEpXG4gKiAgIGhlYWRlcjogc3RyaW5nO1xuICpcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIEB1aWxheW91dGl0ZW0oMSwgMilcbiAqICAgbGVmdENvbnRlbnQ6IHN0cmluZztcbiAqXG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWlsYXlvdXRpdGVtKDIsIDIpXG4gKiAgIHJpZ2h0Q29udGVudDogc3RyaW5nO1xuICogfVxuICpcbiAqIC8vIENyZWF0ZSBhIHJlc3BvbnNpdmUgbGF5b3V0IHdpdGggY3VzdG9tIGJyZWFrcG9pbnRcbiAqIEB1aWxheW91dCgnc2VjdGlvbicsIDMsIDIsICdsJylcbiAqIGNsYXNzIFJlc3BvbnNpdmVMYXlvdXQgZXh0ZW5kcyBNb2RlbCB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWlsYXlvdXRpdGVtKDEsIDEpXG4gKiAgIHRpdGxlOiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgQHVpbGF5b3V0aXRlbSgyLCAxKVxuICogICBzdWJ0aXRsZTogc3RyaW5nO1xuICogfVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgU3lzdGVtXG4gKiAgIHBhcnRpY2lwYW50IHVpbGF5b3V0XG4gKiAgIHBhcnRpY2lwYW50IHVpbW9kZWxcbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgcGFydGljaXBhbnQgUmVuZGVyaW5nRW5naW5lXG4gKiAgIFN5c3RlbS0+PnVpbGF5b3V0OiBhcHBseSB0byBNb2RlbFxuICogICB1aWxheW91dC0+PnVpbW9kZWw6IGNhbGwgd2l0aCBsYXlvdXQgcHJvcHNcbiAqICAgdWltb2RlbC0+Pk1vZGVsOiBhZGRzIG1vZGVsIG1ldGFkYXRhIHdpdGggbGF5b3V0IGNvbmZpZ1xuICogICBNb2RlbC0+PlJlbmRlcmluZ0VuZ2luZTogcmVxdWVzdHMgcmVuZGVyaW5nIGFzIGxheW91dCBjb250YWluZXJcbiAqICAgUmVuZGVyaW5nRW5naW5lLT4+U3lzdGVtOiByZW5kZXJzIGdyaWQgbGF5b3V0IHdpdGggc3BlY2lmaWVkIGRpbWVuc2lvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVpbGF5b3V0KHRhZzogc3RyaW5nLCBjb2xzOiBudW1iZXIgPSAxLCByb3dzOiBudW1iZXIgfCBzdHJpbmdbXSA9IDEsIGJyZWFrcG9pbnQ6IFVJTWVkaWFCcmVha1BvaW50c1R5cGUgPSBVSU1lZGlhQnJlYWtQb2ludHMuTUVESVVNKSB7XG4gIHJldHVybiAob3JpZ2luYWw6IGFueSwgcHJvcGVydHlLZXk/OiBhbnkpID0+IHtcbiAgICByZXR1cm4gdWltb2RlbCh0YWcsIHtjb2xzLCByb3dzLCBicmVha3BvaW50fSkob3JpZ2luYWwsIHByb3BlcnR5S2V5KTtcbiAgfTtcbn0iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBNb2R1bGUgdGhhdCBleHRlbmRzIHRoZSBNb2RlbCBwcm90b3R5cGUgd2l0aCByZW5kZXJpbmcgY2FwYWJpbGl0aWVzXG4gKiBAc3VtbWFyeSBBZGRzIHRoZSByZW5kZXIgbWV0aG9kIHRvIGFsbCBNb2RlbCBpbnN0YW5jZXMgZnJvbSBkZWNvcmF0b3ItdmFsaWRhdGlvblxuICogVGhpcyBtb2R1bGUgaW1wbGVtZW50cyB0aGUgUmVuZGVyYWJsZSBpbnRlcmZhY2UgZm9yIHRoZSBNb2RlbCBjbGFzcyBieSBhZGRpbmcgYSByZW5kZXIgbWV0aG9kXG4gKiB0byBpdHMgcHJvdG90eXBlLiBUaGlzIGFsbG93cyBhbnkgTW9kZWwgaW5zdGFuY2UgdG8gYmUgcmVuZGVyZWQgdXNpbmcgdGhlIFJlbmRlcmluZ0VuZ2luZS5cbiAqIEBtb2R1bGUgbW9kZWwvb3ZlcnJpZGVzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnVpLWRlY29yYXRvcnMvbW9kZWxcbiAqL1xuXG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFJlbmRlcmluZ0VuZ2luZSB9IGZyb20gXCIuLi91aS9SZW5kZXJpbmdcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmVuZGVycyB0aGUgbW9kZWwgdXNpbmcgdGhlIGFwcHJvcHJpYXRlIHJlbmRlcmluZyBlbmdpbmVcbiAqIEBzdW1tYXJ5IERlbGVnYXRlcyByZW5kZXJpbmcgdG8gdGhlIFJlbmRlcmluZ0VuZ2luZSBiYXNlZCBvbiBtb2RlbCBtZXRhZGF0YVxuICogVGhpcyBtZXRob2QgaW1wbGVtZW50cyB0aGUgcmVuZGVyIG1ldGhvZCBmcm9tIHRoZSBSZW5kZXJhYmxlIGludGVyZmFjZSBmb3IgYWxsIE1vZGVsIGluc3RhbmNlcy5cbiAqIEl0IHVzZXMgdGhlIFJlbmRlcmluZ0VuZ2luZSB0byBkZXRlcm1pbmUgaG93IHRvIHJlbmRlciB0aGUgbW9kZWwgYmFzZWQgb24gaXRzIG1ldGFkYXRhLlxuICpcbiAqIEB0ZW1wbGF0ZSBNIFR5cGUgb2YgdGhlIG1vZGVsIGJlaW5nIHJlbmRlcmVkXG4gKiBAcGFyYW0ge2FueVtdfSBhcmdzIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIHJlbmRlcmluZyBlbmdpbmVcbiAqIEByZXR1cm4ge2FueX0gVGhlIHJlbmRlcmVkIG91dHB1dCBpbiB0aGUgZm9ybWF0IGRldGVybWluZWQgYnkgdGhlIHJlbmRlcmluZyBlbmdpbmVcbiAqL1xuTW9kZWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIDxNIGV4dGVuZHMgTW9kZWw+KHRoaXM6IE0sIC4uLmFyZ3M6IGFueVtdKSB7XG4gIHJldHVybiBSZW5kZXJpbmdFbmdpbmUucmVuZGVyKHRoaXMsIC4uLmFyZ3MpO1xufTtcbiIsImltcG9ydCBcInJlZmxlY3QtbWV0YWRhdGFcIjtcbmltcG9ydCB7IFVJS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgcHJvcE1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHtcbiAgQ3J1ZE9wZXJhdGlvbktleXMsXG4gIFVJRWxlbWVudE1ldGFkYXRhLFxuICBVSUxheW91dEl0ZW1NZXRhZGF0YSxcbiAgVUlMaXN0UHJvcE1ldGFkYXRhLFxuICBVSVByb3BNZXRhZGF0YSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IFJlbmRlcmluZ0VuZ2luZSB9IGZyb20gXCIuL1JlbmRlcmluZ1wiO1xuaW1wb3J0IHsgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCBoaWRlcyBhIHByb3BlcnR5IGR1cmluZyBzcGVjaWZpYyBDUlVEIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IENvbnRyb2xzIHByb3BlcnR5IHZpc2liaWxpdHkgYmFzZWQgb24gb3BlcmF0aW9uIHR5cGVcbiAqIFRoaXMgZGVjb3JhdG9yIGFsbG93cyB5b3UgdG8gc3BlY2lmeSB3aGljaCBDUlVEIG9wZXJhdGlvbnMgc2hvdWxkIGhpZGUgYSBwcm9wZXJ0eVxuICogaW4gdGhlIFVJLiBUaGUgcHJvcGVydHkgd2lsbCBvbmx5IGJlIHZpc2libGUgZHVyaW5nIG9wZXJhdGlvbnMgbm90IHNwZWNpZmllZC5cbiAqXG4gKiBAcGFyYW0gb3BlcmF0aW9ucyAtIFRoZSBDUlVEIG9wZXJhdGlvbnMgZHVyaW5nIHdoaWNoIHRoZSBwcm9wZXJ0eSBzaG91bGQgYmUgaGlkZGVuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBwcm9wZXJ0eSBkZWNvcmF0b3IgZnVuY3Rpb25cbiAqXG4gKiBAZnVuY3Rpb24gaGlkZU9uXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBIaWRlIHRoZSBwYXNzd29yZCBmaWVsZCBkdXJpbmcgUkVBRCBvcGVyYXRpb25zXG4gKiBjbGFzcyBVc2VyIHtcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIHVzZXJuYW1lOiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgQGhpZGVPbihPcGVyYXRpb25LZXlzLlJFQUQpXG4gKiAgIHBhc3N3b3JkOiBzdHJpbmc7XG4gKiB9XG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBNb2RlbFxuICogICBwYXJ0aWNpcGFudCBoaWRlT25cbiAqICAgcGFydGljaXBhbnQgUmVuZGVyaW5nRW5naW5lXG4gKiAgIHBhcnRpY2lwYW50IFVJXG4gKiAgIE1vZGVsLT4+aGlkZU9uOiBBcHBseSB0byBwcm9wZXJ0eVxuICogICBoaWRlT24tPj5Nb2RlbDogQWRkIGhpZGRlbiBtZXRhZGF0YVxuICogICBSZW5kZXJpbmdFbmdpbmUtPj5Nb2RlbDogQ2hlY2sgaWYgcHJvcGVydHkgc2hvdWxkIGJlIGhpZGRlblxuICogICBNb2RlbC0+PlJlbmRlcmluZ0VuZ2luZTogUmV0dXJuIGhpZGRlbiBvcGVyYXRpb25zXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+PlVJOiBSZW5kZXIgb3IgaGlkZSBiYXNlZCBvbiBjdXJyZW50IG9wZXJhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaGlkZU9uKC4uLm9wZXJhdGlvbnM6IENydWRPcGVyYXRpb25LZXlzW10pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxDcnVkT3BlcmF0aW9uS2V5c1tdPihcbiAgICBSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5ISURERU4pLFxuICAgIG9wZXJhdGlvbnNcbiAgKTtcbn1cblxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCBzZXRzIHRoZSBvcmRlciBvZiBhIFVJIGVsZW1lbnRcbiAqIEBzdW1tYXJ5IFNwZWNpZmllcyB0aGUgcmVuZGVyaW5nIG9yZGVyIGZvciBVSSBjb21wb25lbnRzXG4gKiBUaGlzIGRlY29yYXRvciBhcHBsaWVzIG1ldGFkYXRhIHRvIHRoZSBwcm9wZXJ0eSBvciBjbGFzcywgaW5kaWNhdGluZyBpdHMgb3JkZXIgaW4gdGhlIFVJIHJlbmRlcmluZyBzZXF1ZW5jZS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gW29yZGVyPTFdIFRoZSBvcmRlciB2YWx1ZSBmb3IgdGhlIFVJIGVsZW1lbnQgKGRlZmF1bHQgaXMgMSlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIHByb3BlcnR5IG9yIGNsYXNzIGRlY29yYXRvciBmdW5jdGlvblxuICpcbiAqIEBmdW5jdGlvbiB1aW9yZGVyXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTZXQgb3JkZXIgZm9yIGEgZmllbGRcbiAqIEB1aW9yZGVyKDIpXG4gKiBmaWVsZE5hbWU6IHN0cmluZztcbiAqXG4gKiAvLyBTZXQgb3JkZXIgZm9yIGEgY2xhc3NcbiAqIEB1aW9yZGVyKDEpXG4gKiBjbGFzcyBVc2VyUHJvZmlsZSB7IC4uLiB9XG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBTeXN0ZW1cbiAqICAgcGFydGljaXBhbnQgdWlvcmRlclxuICogICBwYXJ0aWNpcGFudCBwcm9wZXJ0eVxuICogICBTeXN0ZW0tPj51aW9yZGVyOmRvKHByb3BlcnR5KVxuICogICB1aW9yZGVyLT4+cHJvcGVydHk6IHNldHMgb3JkZXIgbWV0YWRhdGFcbiAqICAgdWlvcmRlci0+PlN5c3RlbTogcmV0dXJucyBkZWNvcmF0ZWQgcHJvcGVydHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVpb3JkZXIob3JkZXI6IG51bWJlciA9IDEpIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxudW1iZXI+KFxuICAgIFJlbmRlcmluZ0VuZ2luZS5rZXkoVUlLZXlzLk9SREVSKSxcbiAgICBvcmRlclxuICApO1xufVxuXG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciB0aGF0IGNvbXBsZXRlbHkgaGlkZXMgYSBwcm9wZXJ0eSBpbiBhbGwgVUkgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgTWFrZXMgYSBwcm9wZXJ0eSBpbnZpc2libGUgaW4gYWxsIENSVUQgb3BlcmF0aW9uc1xuICogVGhpcyBkZWNvcmF0b3IgaXMgYSBjb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCBoaWRlT24gdGhhdCBoaWRlcyBhIHByb3BlcnR5XG4gKiBkdXJpbmcgYWxsIENSVUQgb3BlcmF0aW9ucyAoQ1JFQVRFLCBSRUFELCBVUERBVEUsIERFTEVURSkuXG4gKlxuICogQHJldHVybiB7RnVuY3Rpb259IEEgcHJvcGVydHkgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gKlxuICogQGZ1bmN0aW9uIGhpZGRlblxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQ29tcGxldGVseSBoaWRlIHRoZSBpbnRlcm5hbElkIGZpZWxkIGluIHRoZSBVSVxuICogY2xhc3MgUHJvZHVjdCB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBuYW1lOiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgQGhpZGRlbigpXG4gKiAgIGludGVybmFsSWQ6IHN0cmluZztcbiAqIH1cbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IGhpZGRlblxuICogICBwYXJ0aWNpcGFudCBoaWRlT25cbiAqICAgcGFydGljaXBhbnQgUmVuZGVyaW5nRW5naW5lXG4gKiAgIE1vZGVsLT4+aGlkZGVuOiBBcHBseSB0byBwcm9wZXJ0eVxuICogICBoaWRkZW4tPj5oaWRlT246IENhbGwgd2l0aCBhbGwgb3BlcmF0aW9uc1xuICogICBoaWRlT24tPj5Nb2RlbDogQWRkIGhpZGRlbiBtZXRhZGF0YVxuICogICBSZW5kZXJpbmdFbmdpbmUtPj5Nb2RlbDogQ2hlY2sgaWYgcHJvcGVydHkgc2hvdWxkIGJlIGhpZGRlblxuICogICBNb2RlbC0+PlJlbmRlcmluZ0VuZ2luZTogUmV0dXJuIGFsbCBvcGVyYXRpb25zXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+PlVJOiBBbHdheXMgaGlkZSBwcm9wZXJ0eVxuICovXG5leHBvcnQgZnVuY3Rpb24gaGlkZGVuKCkge1xuICByZXR1cm4gaGlkZU9uKFxuICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICBPcGVyYXRpb25LZXlzLkRFTEVURVxuICApO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCBzcGVjaWZpZXMgaG93IGEgcHJvcGVydHkgc2hvdWxkIGJlIHJlbmRlcmVkIGFzIGEgVUkgZWxlbWVudFxuICogQHN1bW1hcnkgTWFwcyBhIG1vZGVsIHByb3BlcnR5IHRvIGEgc3BlY2lmaWMgVUkgZWxlbWVudCB3aXRoIGN1c3RvbSBwcm9wZXJ0aWVzXG4gKiBUaGlzIGRlY29yYXRvciBhbGxvd3MgeW91IHRvIGRlZmluZSB3aGljaCBIVE1MIGVsZW1lbnQgb3IgY29tcG9uZW50IHNob3VsZCBiZSB1c2VkXG4gKiB0byByZW5kZXIgYSBzcGVjaWZpYyBwcm9wZXJ0eSwgYWxvbmcgd2l0aCBhbnkgYWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIHBhc3MgdG8gdGhhdCBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIEhUTUwgZWxlbWVudCBvciBjb21wb25lbnQgdGFnIG5hbWUgdG8gdXNlIGZvciByZW5kZXJpbmdcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gW3Byb3BzXSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gcGFzcyB0byB0aGUgZWxlbWVudFxuICogQHBhcmFtIHtib29sZWFufSBbc2VyaWFsaXplPWZhbHNlXSBXaGV0aGVyIHRoZSBwcm9wZXJ0eSBzaG91bGQgYmUgc2VyaWFsaXplZFxuICogQHJldHVybiB7RnVuY3Rpb259IEEgcHJvcGVydHkgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gKlxuICogQGZ1bmN0aW9uIHVpZWxlbWVudFxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gUmVuZGVyIGEgcHJvcGVydHkgYXMgYSB0ZXh0IGlucHV0XG4gKiBjbGFzcyBMb2dpbkZvcm0ge1xuICogICBAYXR0cmlidXRlKClcbiAqICAgQHVpZWxlbWVudCgnaW5wdXQnLCB7IHR5cGU6ICd0ZXh0JywgcGxhY2Vob2xkZXI6ICdFbnRlciB1c2VybmFtZScgfSlcbiAqICAgdXNlcm5hbWU6IHN0cmluZztcbiAqXG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWllbGVtZW50KCdpbnB1dCcsIHsgdHlwZTogJ3Bhc3N3b3JkJywgcGxhY2Vob2xkZXI6ICdFbnRlciBwYXNzd29yZCcgfSlcbiAqICAgcGFzc3dvcmQ6IHN0cmluZztcbiAqXG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWllbGVtZW50KCdidXR0b24nLCB7IGNsYXNzOiAnYnRuLXByaW1hcnknIH0pXG4gKiAgIHN1Ym1pdDogc3RyaW5nID0gJ0xvZ2luJztcbiAqIH1cbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IHVpZWxlbWVudFxuICogICBwYXJ0aWNpcGFudCBSZW5kZXJpbmdFbmdpbmVcbiAqICAgcGFydGljaXBhbnQgVUlcbiAqICAgTW9kZWwtPj51aWVsZW1lbnQ6IEFwcGx5IHRvIHByb3BlcnR5XG4gKiAgIHVpZWxlbWVudC0+Pk1vZGVsOiBBZGQgZWxlbWVudCBtZXRhZGF0YVxuICogICBSZW5kZXJpbmdFbmdpbmUtPj5Nb2RlbDogR2V0IGVsZW1lbnQgbWV0YWRhdGFcbiAqICAgTW9kZWwtPj5SZW5kZXJpbmdFbmdpbmU6IFJldHVybiB0YWcgYW5kIHByb3BzXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+PlVJOiBSZW5kZXIgd2l0aCBzcGVjaWZpZWQgZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gdWllbGVtZW50KFxuICB0YWc6IHN0cmluZyxcbiAgcHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBzZXJpYWxpemU6IGJvb2xlYW4gPSBmYWxzZVxuKSB7XG4gIHJldHVybiAob3JpZ2luYWw6IGFueSwgcHJvcGVydHlLZXk/OiBhbnkpID0+IHtcbiAgICBjb25zdCBtZXRhZGF0YTogVUlFbGVtZW50TWV0YWRhdGEgPSB7XG4gICAgICB0YWc6IHRhZyxcbiAgICAgIHNlcmlhbGl6ZTogc2VyaWFsaXplLFxuICAgICAgcHJvcHM6IE9iamVjdC5hc3NpZ24oe30sIHByb3BzIHx8IHt9LCB7XG4gICAgICAgIG5hbWU6IHByb3BlcnR5S2V5LFxuICAgICAgfSksXG4gICAgfTtcblxuICAgIHJldHVybiBwcm9wTWV0YWRhdGEoUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuRUxFTUVOVCksIG1ldGFkYXRhKShcbiAgICAgIG9yaWdpbmFsLFxuICAgICAgcHJvcGVydHlLZXlcbiAgICApO1xuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCBtYXBzIGEgbW9kZWwgcHJvcGVydHkgdG8gYSBVSSBjb21wb25lbnQgcHJvcGVydHlcbiAqIEBzdW1tYXJ5IFNwZWNpZmllcyBob3cgYSBwcm9wZXJ0eSBzaG91bGQgYmUgcGFzc2VkIHRvIGEgVUkgY29tcG9uZW50XG4gKiBUaGlzIGRlY29yYXRvciBhbGxvd3MgeW91IHRvIGRlZmluZSBob3cgYSBtb2RlbCBwcm9wZXJ0eSBzaG91bGQgYmUgbWFwcGVkIHRvXG4gKiBhIHByb3BlcnR5IG9mIHRoZSBVSSBjb21wb25lbnQgd2hlbiByZW5kZXJpbmcuIEl0IHJlcXVpcmVzIHRoZSBjbGFzcyB0byBiZVxuICogZGVjb3JhdGVkIHdpdGggQHVpbW9kZWwuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtwcm9wTmFtZV0gVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIHBhc3MgdG8gdGhlIGNvbXBvbmVudCAoZGVmYXVsdHMgdG8gdGhlIHByb3BlcnR5IGtleSlcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3N0cmluZ2lmeT1mYWxzZV0gV2hldGhlciB0byBzdHJpbmdpZnkgdGhlIHByb3BlcnR5IHZhbHVlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBwcm9wZXJ0eSBkZWNvcmF0b3IgZnVuY3Rpb25cbiAqXG4gKiBAZnVuY3Rpb24gdWlwcm9wXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBNYXAgbW9kZWwgcHJvcGVydGllcyB0byBjb21wb25lbnQgcHJvcGVydGllc1xuICogQHVpbW9kZWwoJ3VzZXItcHJvZmlsZScpXG4gKiBjbGFzcyBVc2VyUHJvZmlsZSB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWlwcm9wKCkgLy8gV2lsbCBiZSBwYXNzZWQgYXMgJ2Z1bGxOYW1lJyB0byB0aGUgY29tcG9uZW50XG4gKiAgIGZ1bGxOYW1lOiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgQHVpcHJvcCgndXNlckVtYWlsJykgLy8gV2lsbCBiZSBwYXNzZWQgYXMgJ3VzZXJFbWFpbCcgdG8gdGhlIGNvbXBvbmVudFxuICogICBlbWFpbDogc3RyaW5nO1xuICpcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIEB1aXByb3AoJ3VzZXJEYXRhJywgdHJ1ZSkgLy8gV2lsbCBiZSBwYXNzZWQgYXMgc3RyaW5naWZpZWQgSlNPTlxuICogICB1c2VyRGF0YTogUmVjb3JkPHN0cmluZywgYW55PjtcbiAqIH1cbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IHVpcHJvcFxuICogICBwYXJ0aWNpcGFudCBSZW5kZXJpbmdFbmdpbmVcbiAqICAgcGFydGljaXBhbnQgQ29tcG9uZW50XG4gKiAgIE1vZGVsLT4+dWlwcm9wOiBBcHBseSB0byBwcm9wZXJ0eVxuICogICB1aXByb3AtPj5Nb2RlbDogQWRkIHByb3AgbWV0YWRhdGFcbiAqICAgUmVuZGVyaW5nRW5naW5lLT4+TW9kZWw6IEdldCBwcm9wIG1ldGFkYXRhXG4gKiAgIE1vZGVsLT4+UmVuZGVyaW5nRW5naW5lOiBSZXR1cm4gcHJvcCBuYW1lIGFuZCBzdHJpbmdpZnkgZmxhZ1xuICogICBSZW5kZXJpbmdFbmdpbmUtPj5Db21wb25lbnQ6IFBhc3MgcHJvcGVydHkgd2l0aCBzcGVjaWZpZWQgbmFtZVxuICovXG5leHBvcnQgZnVuY3Rpb24gdWlwcm9wKFxuICBwcm9wTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLFxuICBzdHJpbmdpZnk6IGJvb2xlYW4gPSBmYWxzZVxuKSB7XG4gIHJldHVybiAodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5OiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBtZXRhZGF0YTogVUlQcm9wTWV0YWRhdGEgPSB7XG4gICAgICBuYW1lOiBwcm9wTmFtZSB8fCBwcm9wZXJ0eUtleSxcbiAgICAgIHN0cmluZ2lmeTogc3RyaW5naWZ5LFxuICAgIH07XG4gICAgcHJvcE1ldGFkYXRhKFJlbmRlcmluZ0VuZ2luZS5rZXkoVUlLZXlzLlBST1ApLCBtZXRhZGF0YSkoXG4gICAgICB0YXJnZXQsXG4gICAgICBwcm9wZXJ0eUtleVxuICAgICk7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciB0aGF0IG1hcHMgYSBuZXN0ZWQgbW9kZWwgcHJvcGVydHkgdG8gYSBVSSBjb21wb25lbnQgcHJvcGVydHkuXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGhvdyBhIHBhcmVudCBjb21wb25lbnQgc2hvdWxkIHJlbmRlciB0aGUgY2hpbGQgbW9kZWwgd2hlbiBuZXN0ZWQuXG4gKlxuICogVGhpcyBkZWNvcmF0b3IgaXMgdXNlZCB0byBkZWNvcmF0ZSBwcm9wZXJ0aWVzIHRoYXQgYXJlIG5lc3RlZCBtb2RlbHMuXG4gKiBXaGVuIGFwcGxpZWQsIGl0IGFsbG93cyBvdmVycmlkaW5nIHRoZSBkZWZhdWx0IHRhZyBvZiB0aGUgY2hpbGQgbW9kZWwgd2l0aCB0aGUgcHJvdmlkZWQgb25lLFxuICogZW5hYmxpbmcgZGlmZmVyZW50IHJlbmRlcmluZyBiZWhhdmlvciB3aGVuIHRoZSBtb2RlbCBhY3RzIGFzIGEgY2hpbGQgKG5lc3RlZClcbiAqIGNvbXBhcmVkIHRvIHdoZW4gaXQgaXMgcmVuZGVyZWQgYXMgdGhlIHBhcmVudCBtb2RlbC5cbiAqXG4gKiBJdCByZXF1aXJlcyB0aGUgY2xhc3MgdG8gYmUgZGVjb3JhdGVkIHdpdGggYEB1aW1vZGVsYC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhenogVGhlIG1vZGVsIGNsYXNzIG5hbWUgdG8gcGFzcyB0byB0aGUgY29tcG9uZW50IChkZWZhdWx0cyB0byB0aGUgcHJvcGVydHkga2V5KS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIEhUTUwgZWxlbWVudCBvciBjb21wb25lbnQgdGFnIG5hbWUgdG8gb3ZlcnJpZGUgdGhlIFVJIHRhZyBvZiB0aGUgbmVzdGVkIG1vZGVsXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IFtwcm9wc10gQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIHBhc3MgdG8gdGhlIGVsZW1lbnRcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3NlcmlhbGl6ZT1mYWxzZV0gV2hldGhlciB0aGUgcHJvcGVydHkgc2hvdWxkIGJlIHNlcmlhbGl6ZWRcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIHByb3BlcnR5IGRlY29yYXRvciBmdW5jdGlvbi5cbiAqXG4gKiBAZnVuY3Rpb24gdWljaGlsZFxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gTWFwIGEgbmVzdGVkIG1vZGVsIHRvIGEgY29tcG9uZW50IHByb3BlcnR5IHdpdGggYSBkaWZmZXJlbnQgdGFnIHdoZW4gbmVzdGVkXG4gKiBAdWltb2RlbCgnYWRkcmVzcy1jb21wb25lbnQnKVxuICogY2xhc3MgQWRkcmVzcyB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBzdHJlZXQ6IHN0cmluZztcbiAqXG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBjaXR5OiBzdHJpbmc7XG4gKiB9XG4gKlxuICogQHVpbW9kZWwoJ3VzZXItcHJvZmlsZScpXG4gKiBjbGFzcyBVc2VyUHJvZmlsZSB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWljaGlsZChBZGRyZXNzLm5hbWUsICdhZGRyZXNzLWNoaWxkLWNvbXBvbmVudCcpXG4gKiAgIGFkZHJlc3M6IEFkZHJlc3M7XG4gKiB9XG4gKlxuICogLy8gSW4gdGhpcyBleGFtcGxlLCB0aGUgQWRkcmVzcyBtb2RlbCBoYXMgdGhlIGRlZmF1bHQgdGFnICdhZGRyZXNzLWNvbXBvbmVudCcgd2hlbiByZW5kZXJlZCBhcyBhIHJvb3QgY29tcG9uZW50LFxuICogLy8gYnV0IHdoZW4gdXNlZCBpbnNpZGUgVXNlclByb2ZpbGUsIGl0IGlzIHJlbmRlcmVkIHdpdGggdGhlIG92ZXJyaWRkZW4gdGFnICdhZGRyZXNzLWNoaWxkLWNvbXBvbmVudCdcbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IHVpY2hpbGRcbiAqICAgcGFydGljaXBhbnQgUmVuZGVyaW5nRW5naW5lXG4gKiAgIHBhcnRpY2lwYW50IENvbXBvbmVudFxuICogICBNb2RlbC0+PnVpY2hpbGQ6IEFwcGx5IHRvIHByb3BlcnR5XG4gKiAgIHVpY2hpbGQtPj5Nb2RlbDogQWRkIGNoaWxkIG1ldGFkYXRhXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+Pk1vZGVsOiBHZXQgY2hpbGQgbWV0YWRhdGFcbiAqICAgTW9kZWwtPj5SZW5kZXJpbmdFbmdpbmU6IFJldHVybiBwcm9wIG5hbWUsIHN0cmluZ2lmeSBmbGFnLCBhbmQgY2hpbGQgdGFnIG92ZXJyaWRlXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+PkNvbXBvbmVudDogUGFzcyBwcm9wZXJ0eSB3aXRoIHNwZWNpZmllZCBuYW1lIGFuZCByZW5kZXIgd2l0aCBvdmVycmlkZGVuIHRhZyBpZiBuZXN0ZWRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdWljaGlsZChcbiAgY2xheno6IHN0cmluZyxcbiAgdGFnOiBzdHJpbmcsXG4gIHByb3BzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge30sXG4gIGlzQXJyYXk6IGJvb2xlYW4gPSBmYWxzZSxcbiAgc2VyaWFsaXplOiBib29sZWFuID0gZmFsc2Vcbikge1xuICByZXR1cm4gKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleTogc3RyaW5nKSA9PiB7XG4gICAgY29uc3QgbWV0YWRhdGE6IFVJRWxlbWVudE1ldGFkYXRhID0ge1xuICAgICAgdGFnOiB0YWcsXG4gICAgICBzZXJpYWxpemU6IHNlcmlhbGl6ZSxcbiAgICAgIHByb3BzOiBPYmplY3QuYXNzaWduKHt9LCBwcm9wcyB8fCB7fSwge1xuICAgICAgICBuYW1lOiBjbGF6eiB8fCBwcm9wZXJ0eUtleSxcbiAgICAgIH0sIGlzQXJyYXkgPyB7Y3VzdG9tVHlwZXM6IFtBcnJheS5uYW1lXSwgbXVsdGlwbGU6IHRydWV9IDoge211bHRpcGxlOiBwcm9wcz8ubXVsdGlwbGUgfHwgZmFsc2V9KSxcbiAgICB9O1xuXG4gICAgcHJvcE1ldGFkYXRhKFJlbmRlcmluZ0VuZ2luZS5rZXkoVUlLZXlzLkNISUxEKSwgbWV0YWRhdGEpKFxuICAgICAgdGFyZ2V0LFxuICAgICAgcHJvcGVydHlLZXlcbiAgICApO1xuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCBtYXBzIGEgbW9kZWwgcHJvcGVydHkgdG8gYSBsaXN0IGl0ZW0gY29tcG9uZW50XG4gKiBAc3VtbWFyeSBTcGVjaWZpZXMgaG93IGEgcHJvcGVydHkgc2hvdWxkIGJlIHJlbmRlcmVkIGluIGEgbGlzdCBjb250ZXh0XG4gKiBUaGlzIGRlY29yYXRvciBhbGxvd3MgeW91IHRvIGRlZmluZSBob3cgYSBtb2RlbCBwcm9wZXJ0eSBjb250YWluaW5nIGEgbGlzdFxuICogc2hvdWxkIGJlIHJlbmRlcmVkLiBJdCByZXF1aXJlcyB0aGUgY2xhc3MgdG8gYmUgZGVjb3JhdGVkIHdpdGggQHVpbGlzdGl0ZW0uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtwcm9wTmFtZV0gVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIHBhc3MgdG8gdGhlIGxpc3QgY29tcG9uZW50IChkZWZhdWx0cyB0byB0aGUgcHJvcGVydHkga2V5KVxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbcHJvcHNdIEFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBwYXNzIHRvIHRoZSBsaXN0IGNvbnRhaW5lclxuICogQHJldHVybiB7RnVuY3Rpb259IEEgcHJvcGVydHkgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gKlxuICogQGZ1bmN0aW9uIHVpbGlzdHByb3BcbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eSBEZWNvcmF0b3JzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIERlZmluZSBhIGxpc3QgcHJvcGVydHkgd2l0aCBjdXN0b20gcmVuZGVyaW5nXG4gKiBAdWltb2RlbCgndG9kby1saXN0JylcbiAqIGNsYXNzIFRvZG9MaXN0IHtcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIHRpdGxlOiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgQHVpbGlzdHByb3AoJ2l0ZW1zJywgeyBjbGFzczogJ3RvZG8taXRlbXMtY29udGFpbmVyJyB9KVxuICogICBpdGVtczogVG9kb0l0ZW1bXTtcbiAqIH1cbiAqXG4gKiBAdWlsaXN0aXRlbSgnbGknLCB7IGNsYXNzOiAndG9kby1pdGVtJyB9KVxuICogY2xhc3MgVG9kb0l0ZW0gZXh0ZW5kcyBNb2RlbCB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICB0ZXh0OiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgY29tcGxldGVkOiBib29sZWFuO1xuICogfVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgcGFydGljaXBhbnQgdWlsaXN0cHJvcFxuICogICBwYXJ0aWNpcGFudCBSZW5kZXJpbmdFbmdpbmVcbiAqICAgcGFydGljaXBhbnQgTGlzdENvbnRhaW5lclxuICogICBwYXJ0aWNpcGFudCBMaXN0SXRlbXNcbiAqICAgTW9kZWwtPj51aWxpc3Rwcm9wOiBBcHBseSB0byBwcm9wZXJ0eVxuICogICB1aWxpc3Rwcm9wLT4+TW9kZWw6IEFkZCBsaXN0IHByb3AgbWV0YWRhdGFcbiAqICAgUmVuZGVyaW5nRW5naW5lLT4+TW9kZWw6IEdldCBsaXN0IHByb3AgbWV0YWRhdGFcbiAqICAgTW9kZWwtPj5SZW5kZXJpbmdFbmdpbmU6IFJldHVybiBwcm9wIG5hbWUgYW5kIGNvbnRhaW5lciBwcm9wc1xuICogICBSZW5kZXJpbmdFbmdpbmUtPj5MaXN0Q29udGFpbmVyOiBDcmVhdGUgY29udGFpbmVyIHdpdGggcHJvcHNcbiAqICAgUmVuZGVyaW5nRW5naW5lLT4+TGlzdEl0ZW1zOiBSZW5kZXIgZWFjaCBpdGVtIHVzaW5nIEB1aWxpc3RpdGVtXG4gKiAgIExpc3RDb250YWluZXItPj5SZW5kZXJpbmdFbmdpbmU6IFJldHVybiByZW5kZXJlZCBsaXN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1aWxpc3Rwcm9wKFxuICBwcm9wTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLFxuICBwcm9wcz86IFJlY29yZDxzdHJpbmcsIGFueT5cbikge1xuICByZXR1cm4gKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleTogc3RyaW5nKSA9PiB7XG4gICAgY29uc3QgbWV0YWRhdGE6IFBhcnRpYWw8VUlMaXN0UHJvcE1ldGFkYXRhPiA9IHtcbiAgICAgIG5hbWU6IHByb3BOYW1lIHx8IHByb3BlcnR5S2V5LFxuICAgICAgcHJvcHM6IHByb3BzIHx8IHt9LFxuICAgIH07XG4gICAgcHJvcE1ldGFkYXRhKFJlbmRlcmluZ0VuZ2luZS5rZXkoVUlLZXlzLlVJTElTVFBST1ApLCBtZXRhZGF0YSkoXG4gICAgICB0YXJnZXQsXG4gICAgICBwcm9wZXJ0eUtleVxuICAgICk7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciB0aGF0IHBvc2l0aW9ucyBhIHByb3BlcnR5IGluIGEgc3BlY2lmaWMgZ3JpZCBsYXlvdXQgcG9zaXRpb25cbiAqIEBzdW1tYXJ5IFNwZWNpZmllcyB0aGUgY29sdW1uIGFuZCByb3cgcG9zaXRpb24gZm9yIGEgcHJvcGVydHkgaW4gYSBVSSBsYXlvdXQgZ3JpZFxuICogVGhpcyBkZWNvcmF0b3IgYWxsb3dzIHlvdSB0byBkZWZpbmUgdGhlIHNwZWNpZmljIHBvc2l0aW9uIG9mIGEgcHJvcGVydHkgd2l0aGluXG4gKiBhIGdyaWQtYmFzZWQgbGF5b3V0IHN5c3RlbS4gSXQgc3BlY2lmaWVzIHdoaWNoIGNvbHVtbiBhbmQgcm93IHRoZSBwcm9wZXJ0eVxuICogc2hvdWxkIG9jY3VweSB3aGVuIHJlbmRlcmVkIGluIHRoZSBVSS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gY29sIFRoZSBjb2x1bW4gcG9zaXRpb24gaW4gdGhlIGdyaWQgbGF5b3V0XG4gKiBAcGFyYW0ge251bWJlcn0gW3Jvdz0xXSBUaGUgcm93IHBvc2l0aW9uIGluIHRoZSBncmlkIGxheW91dCAoZGVmYXVsdHMgdG8gMSlcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gW3Byb3BzPXt9XSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gcGFzcyB0byB0aGUgbGF5b3V0IGl0ZW1cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIHByb3BlcnR5IGRlY29yYXRvciBmdW5jdGlvblxuICpcbiAqIEBmdW5jdGlvbiB1aWxheW91dGl0ZW1cbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eSBEZWNvcmF0b3JzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFBvc2l0aW9uIHByb3BlcnRpZXMgaW4gYSBncmlkIGxheW91dFxuICogQHVpbW9kZWwoJ3VzZXItZm9ybScpXG4gKiBjbGFzcyBVc2VyRm9ybSB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWlsYXlvdXRpdGVtKDEsIDEpIC8vIEZpcnN0IGNvbHVtbiwgZmlyc3Qgcm93XG4gKiAgIGZpcnN0TmFtZTogc3RyaW5nO1xuICpcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIEB1aWxheW91dGl0ZW0oMiwgMSkgLy8gU2Vjb25kIGNvbHVtbiwgZmlyc3Qgcm93XG4gKiAgIGxhc3ROYW1lOiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgQHVpbGF5b3V0aXRlbSgxLCAyLCB7IGNvbHNwYW46IDIgfSkgLy8gRmlyc3QgY29sdW1uLCBzZWNvbmQgcm93LCBzcGFucyAyIGNvbHVtbnNcbiAqICAgZW1haWw6IHN0cmluZztcbiAqXG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWlsYXlvdXRpdGVtKDEsIDMsIHsgY2xhc3M6ICdmdWxsLXdpZHRoJyB9KSAvLyBGaXJzdCBjb2x1bW4sIHRoaXJkIHJvdyB3aXRoIGN1c3RvbSBjbGFzc1xuICogICBiaW86IHN0cmluZztcbiAqIH1cbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IHVpbGF5b3V0aXRlbVxuICogICBwYXJ0aWNpcGFudCBSZW5kZXJpbmdFbmdpbmVcbiAqICAgcGFydGljaXBhbnQgTGF5b3V0Q29udGFpbmVyXG4gKiAgIE1vZGVsLT4+dWlsYXlvdXRpdGVtOiBBcHBseSB0byBwcm9wZXJ0eVxuICogICB1aWxheW91dGl0ZW0tPj5Nb2RlbDogQWRkIGxheW91dCBpdGVtIG1ldGFkYXRhXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+Pk1vZGVsOiBHZXQgbGF5b3V0IGl0ZW0gbWV0YWRhdGFcbiAqICAgTW9kZWwtPj5SZW5kZXJpbmdFbmdpbmU6IFJldHVybiBjb2x1bW4sIHJvdywgYW5kIHByb3BzXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+PkxheW91dENvbnRhaW5lcjogUG9zaXRpb24gZWxlbWVudCBhdCBncmlkIGNvb3JkaW5hdGVzXG4gKiAgIExheW91dENvbnRhaW5lci0+PlJlbmRlcmluZ0VuZ2luZTogUmV0dXJuIHBvc2l0aW9uZWQgZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gdWlsYXlvdXRpdGVtKFxuICBjb2w6IG51bWJlcixcbiAgcm93OiBudW1iZXIgPSAxLFxuICBwcm9wczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9LFxuKSB7XG4gIHJldHVybiAodGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5OiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBtZXRhZGF0YTogVUlMYXlvdXRJdGVtTWV0YWRhdGEgPSB7XG4gICAgICBuYW1lOiAgcHJvcGVydHlLZXksXG4gICAgICBjb2wsXG4gICAgICByb3csXG4gICAgICBwcm9wczogT2JqZWN0LmFzc2lnbih7fSwgcHJvcHMsIHtyb3c6IHJvdyA/PyAxLCBjb2w6IGNvbCA/PyAxfSksXG4gICAgfTsgIFxuICAgIHByb3BNZXRhZGF0YShSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5VSUxBWU9VVElURU0pLCBtZXRhZGF0YSkoXG4gICAgICB0YXJnZXQsXG4gICAgICBwcm9wZXJ0eUtleVxuICAgICk7XG4gIH07XG59XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBDbGFzcyByZXByZXNlbnRpbmcgYW4gZXZlbnQgaGFuZGxlclxuICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgc3RydWN0dXJlIGZvciBoYW5kbGluZyBldmVudHMgaW4gdGhlIFVJIGRlY29yYXRvcnMgc3lzdGVtXG4gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGEgZm91bmRhdGlvbiBmb3IgbWFuYWdpbmcgYW5kIHByb2Nlc3NpbmcgZXZlbnRzIHRoYXQgb2NjdXJcbiAqIHdpdGhpbiB0aGUgVUkgY29tcG9uZW50cyBnZW5lcmF0ZWQgYnkgdGhlIGRlY29yYXRvcnMuXG4gKiBAY2xhc3MgRXZlbnRIYW5kbGVyXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnVpLWRlY29yYXRvcnMvdWlcbiAqL1xuZXhwb3J0IGNsYXNzIEV2ZW50SGFuZGxlciB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBFdmVudEhhbmRsZXJcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBuZXcgRXZlbnRIYW5kbGVyIG9iamVjdFxuICAgKiBUaGlzIGNvbnN0cnVjdG9yIGN1cnJlbnRseSBkb2Vzbid0IHRha2UgYW55IHBhcmFtZXRlcnMsIGJ1dCBpdCBjYW4gYmVcbiAgICogZXh0ZW5kZWQgaW4gdGhlIGZ1dHVyZSB0byBhY2NlcHQgY29uZmlndXJhdGlvbiBvcHRpb25zIGlmIG5lZWRlZC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKCkge31cbn0iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBVSSBkZWNvcmF0b3JzIG1vZHVsZSBmb3IgVHlwZVNjcmlwdCBhcHBsaWNhdGlvbnNcbiAqIEBzdW1tYXJ5IEEgY29sbGVjdGlvbiBvZiBkZWNvcmF0b3JzIGFuZCB1dGlsaXRpZXMgZm9yIGJ1aWxkaW5nIFVJIGNvbXBvbmVudHMgaW4gVHlwZVNjcmlwdCBhcHBsaWNhdGlvbnMuXG4gKiBUaGlzIG1vZHVsZSBleHBvcnRzIGZ1bmN0aW9uYWxpdHkgZnJvbSBib3RoIHRoZSBtb2RlbCBhbmQgVUkgc3VibW9kdWxlcywgcHJvdmlkaW5nIGRlY29yYXRvcnMgZm9yXG4gKiByZW5kZXJpbmcsIGNvbXBvbmVudCBkZWZpbml0aW9uLCBhbmQgVUkgc3RhdGUgbWFuYWdlbWVudC5cbiAqIEBtb2R1bGUgdWktZGVjb3JhdG9yc1xuICovXG5cbmV4cG9ydCAqIGZyb20gXCIuL21vZGVsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi91aVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDdXJyZW50IHBhY2thZ2UgdmVyc2lvbiBzdHJpbmdcbiAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgY3VycmVudCBwYWNrYWdlIHZlcnNpb24gZm9yIHJlZmVyZW5jZVxuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dWktZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6WyJVSU1lZGlhQnJlYWtQb2ludHMiLCJNb2RlbEtleXMiLCJWYWxpZGF0aW9uS2V5cyIsIkVtYWlsVmFsaWRhdG9yIiwiVVJMVmFsaWRhdG9yIiwiRGF0ZVZhbGlkYXRvciIsIlBhc3N3b3JkVmFsaWRhdG9yIiwiUmVxdWlyZWRWYWxpZGF0b3IiLCJNaW5WYWxpZGF0b3IiLCJNYXhWYWxpZGF0b3IiLCJTdGVwVmFsaWRhdG9yIiwiTWluTGVuZ3RoVmFsaWRhdG9yIiwiTWF4TGVuZ3RoVmFsaWRhdG9yIiwiUGF0dGVyblZhbGlkYXRvciIsIkVxdWFsc1ZhbGlkYXRvciIsIkRpZmZWYWxpZGF0b3IiLCJMZXNzVGhhblZhbGlkYXRvciIsIkxlc3NUaGFuT3JFcXVhbFZhbGlkYXRvciIsIkdyZWF0ZXJUaGFuVmFsaWRhdG9yIiwiR3JlYXRlclRoYW5PckVxdWFsVmFsaWRhdG9yIiwiSW50ZXJuYWxFcnJvciIsImZvcm1hdERhdGUiLCJSZXNlcnZlZE1vZGVscyIsInBhcnNlRGF0ZSIsImZpbmRNb2RlbElkIiwiTW9kZWwiLCJSZWZsZWN0aW9uIiwibWV0YWRhdGEiLCJhcHBseSIsInByb3BNZXRhZGF0YSIsIk9wZXJhdGlvbktleXMiXSwibWFwcGluZ3MiOiI7Ozs7OztJQUFBOzs7Ozs7O0lBT0c7QUE0QlNBO0lBQVosQ0FBQSxVQUFZLGtCQUFrQixFQUFBO0lBQzVCLElBQUEsa0JBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxHQUFXO0lBQ1gsSUFBQSxrQkFBQSxDQUFBLFFBQUEsQ0FBQSxHQUFBLEdBQVk7SUFDWixJQUFBLGtCQUFBLENBQUEsT0FBQSxDQUFBLEdBQUEsR0FBVztJQUNYLElBQUEsa0JBQUEsQ0FBQSxRQUFBLENBQUEsR0FBQSxJQUFhO0lBQ2YsQ0FBQyxFQUxXQSwwQkFBa0IsS0FBbEJBLDBCQUFrQixHQUs3QixFQUFBLENBQUEsQ0FBQTtJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQTRDRztBQUNVLFVBQUEsTUFBTSxHQUFHO0lBQ3BCLElBQUEsT0FBTyxFQUFFLENBQUEsRUFBR0MsNkJBQVMsQ0FBQyxPQUFPLENBQU0sSUFBQSxDQUFBO0lBQ25DLElBQUEsT0FBTyxFQUFFLFNBQVM7SUFDbEIsSUFBQSxXQUFXLEVBQUUsYUFBYTtJQUMxQixJQUFBLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLElBQUEsSUFBSSxFQUFFLE1BQU07SUFDWixJQUFBLEtBQUssRUFBRSxPQUFPO0lBQ2QsSUFBQSxJQUFJLEVBQUUsTUFBTTtJQUNaLElBQUEsV0FBVyxFQUFFLFFBQVE7SUFDckIsSUFBQSxZQUFZLEVBQUUsdUJBQXVCO0lBRXJDLElBQUEsVUFBVSxFQUFFLFlBQVk7SUFDeEIsSUFBQSxVQUFVLEVBQUUsVUFBVTtJQUN0QixJ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
|
|
1
|
+
var e,t;e=this,t=function(e,t,r,a){"use strict";var o;e.UIMediaBreakPoints=void 0,(o=e.UIMediaBreakPoints||(e.UIMediaBreakPoints={})).SMALL="s",o.MEDIUM="m",o.LARGE="l",o.XLARGE="xl";const s={REFLECT:t.ModelKeys.REFLECT+".ui.",UIMODEL:"uimodel",RENDERED_BY:"rendered-by",ELEMENT:"element",PROP:"prop",CHILD:"child",NAME:"name",NAME_PREFIX:"input-",CUSTOM_PROPS:"customValidationProps",UILISTITEM:"uilistitem",UILISTPROP:"listprop",UILAYOUT:"uilayout",UILAYOUTITEM:"uilayoutitem",HANDLERS:"handlers",TYPE:"type",SUB_TYPE:"subtype",HIDDEN:"hidden",FORMAT:"format",ORDER:"order",READ_ONLY:"readonly",REQUIRED:t.ValidationKeys.REQUIRED,MIN:t.ValidationKeys.MIN,MIN_LENGTH:t.ValidationKeys.MIN_LENGTH,MAX:t.ValidationKeys.MAX,MAX_LENGTH:t.ValidationKeys.MAX_LENGTH,PATTERN:t.ValidationKeys.PATTERN,URL:t.ValidationKeys.URL,STEP:t.ValidationKeys.STEP,DATE:t.ValidationKeys.DATE,EMAIL:t.ValidationKeys.EMAIL,PASSWORD:t.ValidationKeys.PASSWORD,EQUALS:t.ValidationKeys.EQUALS,DIFF:t.ValidationKeys.DIFF,LESS_THAN:t.ValidationKeys.LESS_THAN,LESS_THAN_OR_EQUAL:t.ValidationKeys.LESS_THAN_OR_EQUAL,GREATER_THAN:t.ValidationKeys.GREATER_THAN,GREATER_THAN_OR_EQUAL:t.ValidationKeys.GREATER_THAN_OR_EQUAL},i={[s.EMAIL]:t.EmailValidator,[s.URL]:t.URLValidator,[s.DATE]:t.DateValidator,[s.PASSWORD]:t.PasswordValidator},n={[s.REQUIRED]:t.RequiredValidator,[s.MIN]:t.MinValidator,[s.MAX]:t.MaxValidator,[s.STEP]:t.StepValidator,[s.MIN_LENGTH]:t.MinLengthValidator,[s.MAX_LENGTH]:t.MaxLengthValidator,[s.PATTERN]:t.PatternValidator,[s.EQUALS]:t.EqualsValidator,[s.DIFF]:t.DiffValidator,[s.LESS_THAN]:t.LessThanValidator,[s.LESS_THAN_OR_EQUAL]:t.LessThanOrEqualValidator,[s.GREATER_THAN]:t.GreaterThanValidator,[s.GREATER_THAN_OR_EQUAL]:t.GreaterThanOrEqualValidator},d="yyyy-MM-dd",l={BUTTON:"button",CHECKBOX:"checkbox",COLOR:"color",DATE:s.DATE,DATETIME_LOCAL:"datetime-local",EMAIL:s.EMAIL,FILE:"file",HIDDEN:"hidden",IMAGE:"image",MONTH:"month",NUMBER:"number",PASSWORD:s.PASSWORD,RADIO:"radio",RANGE:"range",RESET:"reset",SEARCH:"search",SUBMIT:"submit",TEL:"tel",TEXT:"text",TEXTAREA:"textarea",SELECT:"select",TIME:"time",URL:s.URL,WEEK:"week"},c=[l.CHECKBOX,l.RADIO];class E extends a.InternalError{constructor(e){super(e,E.name)}}function p(e,r,...a){if(e===s.DATE){if(!r)return"";const e=a.shift()||d;return t.formatDate(new Date(r),e)}return r}function u(e){if("number"==typeof e&&!isNaN(e))return e;const t=Number(e);return isNaN(t)?void 0:t}function T(e){if(!e)return e;const t={"&":"&","<":"<",">":">"};return(""+e).replace(/[&<>]/g,e=>t[e]||e)}function R(e){let t;try{t=a.findModelId(e)}catch(e){t=Date.now()}return`${e.constructor.name}-${t}`}class y{static{this.cache={}}constructor(e){this.flavour=e,this.initialized=!1,y.register(this)}translate(e,r=!0){if(r)switch(e){case t.ReservedModels.STRING:return l.TEXT;case t.ReservedModels.NUMBER:case t.ReservedModels.BIGINT:return l.NUMBER;case t.ReservedModels.BOOLEAN:return l.CHECKBOX;case t.ReservedModels.DATE:return l.DATE}else switch(e){case l.SELECT:case l.TEXT:case l.EMAIL:case l.COLOR:case l.PASSWORD:case l.TEL:case l.URL:case l.SEARCH:case l.HIDDEN:case l.TEXTAREA:case l.RADIO:return t.ReservedModels.STRING;case l.NUMBER:return t.ReservedModels.NUMBER;case l.CHECKBOX:return t.ReservedModels.BOOLEAN;case l.DATE:case l.DATETIME_LOCAL:case l.TIME:return t.ReservedModels.DATE}return e}getClassDecoratorsMetadata(e){return[Reflect.getMetadata(y.key(s.UIMODEL),e.constructor)||Reflect.getMetadata(y.key(s.UIMODEL),t.Model.get(e.constructor.name)),Reflect.getMetadata(y.key(s.UILISTITEM),e.constructor)||Reflect.getMetadata(y.key(s.UILISTITEM),t.Model.get(e.constructor.name)),Reflect.getMetadata(y.key(s.HANDLERS),e.constructor)||Reflect.getMetadata(y.key(s.HANDLERS),t.Model.get(e.constructor.name)),Reflect.getMetadata(y.key(s.UILAYOUT),e.constructor)||Reflect.getMetadata(y.key(s.UILAYOUT),t.Model.get(e.constructor.name))].filter(Boolean)}isValidatableByType(e){return Object.keys(i).includes(e)}isValidatableByAttribute(e){return Object.keys(n).includes(e)}toAttributeValue(e,t){if(!Object.keys(n).includes(e))throw Error(`Invalid attribute key "${e}". Expected one of: ${Object.keys(n).join(", ")}.`);return e===s.REQUIRED||t[e]}toFieldDefinition(e,a={},o=!0){const{inheritProps:i,...n}=a;a=n;const c=this.getClassDecoratorsMetadata(e);if(!c.length)throw new E(`No ui definitions set for model ${e.constructor.name}. Did you use @uimodel?`);const u=Object.assign({},...c,i||{}),{tag:T,props:y,item:f,handlers:M}=u,A=r.Reflection.getAllPropertyDecorators(e,s.REFLECT);let I,L=f?.props||{},O={};const h=(e,t)=>e?[e,t].join("."):t;if(A){const o=r.Reflection.getAllPropertyDecorators(e,t.ValidationKeys.REFLECT);for(const r in A){const i=A[r],n=Object.values(i).filter(({key:e})=>[s.PROP,s.ELEMENT,s.CHILD].includes(e));if(n?.length>1)throw new E("Only one type of decoration is allowed. Please choose between @uiprop, @uichild or @uielement");const c=i.find(({key:e})=>e===s.HIDDEN);if(c){const e=i.find(({key:e})=>e===s.ELEMENT);if(!e)throw new E(`@uielement no found in "${r}". It is required to use hiddenOn decorator.`)}i.shift(),i.sort(e=>e.key===s.ELEMENT?-1:1).forEach(i=>{if(!i)throw new E("No decorator found");switch(i.key){case s.PROP:L[r]=i.props;break;case s.CHILD:{if(!t.Model.isPropertyModel(e,r))throw new E(`Child "${r}" must be a model.`);let o;const s=e[r];if("object"!=typeof s||null===s||Array.isArray(s)){const e=i.props.props?.name;o=new(t.Model.get(e))}I=I||[];const n=Object.assign({},a||{},{model:o},{inheritProps:i.props,childOf:h(a?.childOf,r)}),d=this.toFieldDefinition(s||o,n,!1);I.push(d);break}case s.UILISTPROP:{O=O||{},i.props?.name&&(O[i.props?.name]=r);const e=Object.assign({},u.props?.item||{},f?.props||{},i.props?.props||{},a);L={tag:f?.tag||e.render||"",props:Object.assign({},L?.props,{mapper:O},e)};break}case s.HIDDEN:case s.ORDER:case s.UILAYOUTITEM:case s.ELEMENT:{I=I||[];const t=i.props,n=Object.assign({},L?.props,t.props||{},t?.props?.name?{path:h(a?.childOf,t.props.name),childOf:void 0}:{},a),c={tag:t.tag||L?.tag||T||"",props:n};if(i.key===s.ELEMENT){const t=o[r],a=t.shift();for(const e of t)this.isValidatableByAttribute(e.key)?c.props[this.translate(e.key)]=this.toAttributeValue(e.key,e.props):this.isValidatableByType(e.key)&&(e.key===l.DATE&&(c.props[s.FORMAT]=e.props.format||d),c.props[s.TYPE]=e.key);if(!c.props[s.TYPE]){const e=a.props.name;c.props[s.TYPE]=this.translate(e.toLowerCase(),!0)}c.props.value=p(c.props[s.TYPE],e[r],c.props[s.FORMAT]),I.push(c)}else{const e=I.find(e=>e.props?.name===r||i.key===s.UILAYOUTITEM&&e?.props?.childOf===r);if(e)if(i.key!==s.UILAYOUTITEM)e.props=Object.assign({},e.props,{[i.key]:t});else{const{row:t,col:r,props:a}=i.props;e.props=Object.assign({},a||{},e.props,t,r)}else I.push(c)}break}default:throw new E("Invalid key: "+i.key)}})}}a=Object.assign({},y,a,{handlers:M||{}});const D=a?.operation;I=I?.sort((e,t)=>(e?.props?.order??0)-(t?.props?.order??0)).filter(e=>{const t=e?.props?.hidden||[];return t?.length&&t.includes(D)?void 0:e});const m={tag:T,item:L,props:a,children:I};return o&&(m.rendererId=R(e)),m}static register(e){if(e.flavour in this.cache)throw new a.InternalError(`Rendering engine under ${e.flavour} already exists`);this.cache[e.flavour]=e,this.current=e}static getOrBoot(e){if(e instanceof y)return e;const t=new e;return t.initialize(),t}static get(e){if(!e)return this.getOrBoot(this.current);if(!(e in this.cache))throw new a.InternalError(`Rendering engine under ${e} does not exist`);return this.getOrBoot(this.cache[e])}static render(e,...r){const o=t.Model.get(e.constructor.name)||t.Model.fromObject(e);if(!o)throw new a.InternalError("No model registered found");const i=Reflect.getMetadata(y.key(s.RENDERED_BY),o);return y.get(i).render(e,...r)}static key(e){return`${s.REFLECT}${e}`}}function f(e,t){return(a,o)=>{const i={tag:e||a.name,props:t};return r.metadata(y.key(s.UIMODEL),i)(a)}}function M(...e){return t.propMetadata(y.key(s.HIDDEN),e)}t.Model.prototype.render=function(...e){return y.render(this,...e)},e.EventHandler=class{constructor(){}},e.HTML5CheckTypes=c,e.HTML5DateFormat=d,e.HTML5InputTypes=l,e.RenderingEngine=y,e.RenderingError=E,e.UIKeys=s,e.VERSION="##VERSION##",e.ValidatableByAttribute=n,e.ValidatableByType=i,e.escapeHtml=T,e.formatByType=p,e.generateUIModelID=R,e.hidden=()=>M(a.OperationKeys.CREATE,a.OperationKeys.READ,a.OperationKeys.UPDATE,a.OperationKeys.DELETE),e.hideOn=M,e.parseToNumber=u,e.parseValueByType=function e(r,o,s){let i;switch(r){case Array.name:i=(Array.isArray(o)?o.map(r=>e(t.ReservedModels.STRING,r,s)):[o]).join(",");break;case l.NUMBER:i=u(o);break;case l.DATE:{const e=s.format;o&&(""+o).trim().length&&(i=typeof o===t.ReservedModels.NUMBER?new Date(o):o?e?t.parseDate(e,o):new Date(o):void 0);break}default:i=typeof o===t.ReservedModels.OBJECT?Array.isArray(o)?o.join(","):JSON.stringify(o):typeof o===t.ReservedModels.BOOLEAN?o:typeof o===t.ReservedModels.STRING?T(o):i}if(void 0===i)throw new a.InternalError(`Failed to parse value of type ${r} from ${typeof o} - ${o}`);return i},e.renderedBy=e=>r.apply(r.metadata(y.key(s.RENDERED_BY),e)),e.revertHtml=e=>{const t={"&":"&","<":"<",">":">"};return(""+e).replace(/<|>|&/g,e=>t[e]||e)},e.uichild=(e,r,a={},o=!1,i=!1)=>(n,d)=>{const l={tag:r,serialize:i,props:Object.assign({},a||{},{name:e||d},o?{customTypes:[Array.name],multiple:!0}:{multiple:a?.multiple||!1})};t.propMetadata(y.key(s.CHILD),l)(n,d)},e.uielement=(e,r,a=!1)=>(o,i)=>{const n={tag:e,serialize:a,props:Object.assign({},r||{},{name:i})};return t.propMetadata(y.key(s.ELEMENT),n)(o,i)},e.uihandlers=e=>t=>{const a={handlers:e};return r.metadata(y.key(s.HANDLERS),a)(t)},e.uilayout=(t,r=1,a=1,o=e.UIMediaBreakPoints.MEDIUM)=>(e,s)=>f(t,{cols:r,rows:a,breakpoint:o})(e,s),e.uilayoutitem=(e,r=1,a={})=>(o,i)=>{const n={name:i,col:e,row:r,props:Object.assign({},a,{row:r??1,col:e??1})};t.propMetadata(y.key(s.UILAYOUTITEM),n)(o,i)},e.uilistitem=(e,t)=>(a,o)=>{const i={item:{tag:e||a.name,props:t}};return r.metadata(y.key(s.UILISTITEM),i)(a)},e.uilistprop=(e=void 0,r)=>(a,o)=>{const i={name:e||o,props:r||{}};t.propMetadata(y.key(s.UILISTPROP),i)(a,o)},e.uimodel=f,e.uiorder=(e=1)=>t.propMetadata(y.key(s.ORDER),e),e.uiprop=(e=void 0,r=!1)=>(a,o)=>{const i={name:e||o,stringify:r};t.propMetadata(y.key(s.PROP),i)(a,o)}},"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@decaf-ts/decorator-validation"),require("@decaf-ts/reflection"),require("@decaf-ts/db-decorators"),require("reflect-metadata")):"function"==typeof define&&define.amd?define(["exports","@decaf-ts/decorator-validation","@decaf-ts/reflection","@decaf-ts/db-decorators","reflect-metadata"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["ui-decorators"]={},e.decafTsDecoratorValidation,e.decafTsReflection,e.decafTsDbDecorators);
|
|
2
|
+
//# sourceMappingURL=ui-decorators.cjs.map
|