@decaf-ts/core 0.3.38 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/core.cjs +2361 -0
- package/dist/core.esm.cjs +2307 -0
- package/lib/esm/identity/decorators.js +1 -2
- package/lib/esm/identity/index.js +1 -2
- package/lib/esm/identity/utils.js +1 -2
- package/{dist/types → lib/esm}/index.d.ts +1 -1
- package/lib/esm/index.js +2 -3
- package/lib/esm/interfaces/Builder.js +1 -2
- package/lib/esm/interfaces/Executor.js +1 -2
- package/lib/esm/interfaces/Observable.js +1 -2
- package/lib/esm/interfaces/Observer.js +1 -2
- package/lib/esm/interfaces/Paginatable.js +1 -2
- package/lib/esm/interfaces/Queriable.js +1 -2
- package/lib/esm/interfaces/RawExecutor.js +1 -2
- package/lib/esm/interfaces/SequenceOptions.js +1 -2
- package/lib/esm/interfaces/index.js +1 -2
- package/lib/esm/model/BaseModel.js +1 -2
- package/lib/esm/model/IdentifiedBaseModel.js +1 -2
- package/{dist/types → lib/esm}/model/User.d.ts +2 -1
- package/lib/esm/model/User.js +1 -2
- package/lib/esm/model/construction.js +2 -3
- package/lib/esm/model/decorators.js +1 -2
- package/lib/esm/model/index.js +1 -2
- package/lib/esm/model/types.js +1 -2
- package/lib/esm/persistence/Adapter.js +1 -2
- package/lib/esm/persistence/Sequence.js +1 -2
- package/lib/esm/persistence/constants.js +1 -2
- package/lib/esm/persistence/decorators.js +1 -2
- package/lib/esm/persistence/errors.js +1 -2
- package/lib/esm/persistence/index.js +1 -2
- package/lib/esm/query/Clause.js +1 -2
- package/lib/esm/query/ClauseFactory.js +1 -2
- package/lib/esm/query/Condition.js +1 -2
- package/lib/esm/query/Paginator.js +1 -2
- package/lib/esm/query/Query.js +1 -2
- package/{dist/types → lib/esm}/query/Statement.d.ts +2 -1
- package/lib/esm/query/Statement.js +1 -2
- package/lib/esm/query/clauses/FromClause.js +1 -2
- package/lib/esm/query/clauses/GroupByClause.js +1 -2
- package/lib/esm/query/clauses/InsertClause.js +1 -2
- package/lib/esm/query/clauses/LimitClause.js +1 -2
- package/lib/esm/query/clauses/OffsetClause.js +1 -2
- package/lib/esm/query/clauses/OrderByClause.js +1 -2
- package/lib/esm/query/clauses/SelectClause.js +1 -2
- package/lib/esm/query/clauses/SelectorBasedClause.js +1 -2
- package/lib/esm/query/clauses/ValuesClause.js +1 -2
- package/lib/esm/query/clauses/WhereClause.js +1 -2
- package/lib/esm/query/clauses/index.js +1 -2
- package/lib/esm/query/constants.js +1 -2
- package/lib/esm/query/errors.js +1 -2
- package/lib/esm/query/index.js +1 -2
- package/lib/esm/query/options.js +1 -2
- package/lib/esm/query/selectors.js +1 -2
- package/lib/esm/query/types.js +1 -2
- package/lib/esm/repository/Context.js +1 -2
- package/lib/esm/repository/Repository.js +1 -2
- package/lib/esm/repository/constants.js +1 -2
- package/lib/esm/repository/decorators.js +1 -2
- package/lib/esm/repository/errors.js +1 -2
- package/lib/esm/repository/index.js +1 -2
- package/lib/esm/repository/injectables.js +1 -2
- package/lib/esm/repository/types.js +1 -2
- package/lib/esm/repository/utils.js +1 -2
- package/lib/esm/validators/ClauseSequenceValidator.js +1 -2
- package/lib/esm/validators/decorators.js +1 -2
- package/lib/esm/validators/index.js +1 -2
- package/lib/identity/decorators.cjs +1 -2
- package/lib/identity/decorators.d.ts +24 -0
- package/lib/identity/index.cjs +1 -2
- package/lib/identity/index.d.ts +2 -0
- package/lib/identity/utils.cjs +1 -2
- package/lib/identity/utils.d.ts +3 -0
- package/lib/index.cjs +2 -3
- package/lib/index.d.ts +25 -0
- package/lib/interfaces/Builder.cjs +1 -2
- package/lib/interfaces/Builder.d.ts +16 -0
- package/lib/interfaces/Executor.cjs +1 -2
- package/lib/interfaces/Executor.d.ts +19 -0
- package/lib/interfaces/Observable.cjs +1 -2
- package/lib/interfaces/Observable.d.ts +31 -0
- package/lib/interfaces/Observer.cjs +1 -2
- package/lib/interfaces/Observer.d.ts +16 -0
- package/lib/interfaces/Paginatable.cjs +1 -2
- package/lib/interfaces/Paginatable.d.ts +4 -0
- package/lib/interfaces/Queriable.cjs +1 -2
- package/lib/interfaces/Queriable.d.ts +6 -0
- package/lib/interfaces/RawExecutor.cjs +1 -2
- package/lib/interfaces/RawExecutor.d.ts +20 -0
- package/lib/interfaces/SequenceOptions.cjs +1 -2
- package/lib/interfaces/SequenceOptions.d.ts +19 -0
- package/lib/interfaces/index.cjs +1 -2
- package/lib/interfaces/index.d.ts +7 -0
- package/lib/model/BaseModel.cjs +1 -2
- package/lib/model/BaseModel.d.ts +6 -0
- package/lib/model/IdentifiedBaseModel.cjs +1 -2
- package/lib/model/IdentifiedBaseModel.d.ts +7 -0
- package/lib/model/User.cjs +1 -2
- package/lib/model/User.d.ts +9 -0
- package/lib/model/construction.cjs +2 -3
- package/lib/model/construction.d.ts +15 -0
- package/lib/model/decorators.cjs +1 -2
- package/lib/model/decorators.d.ts +75 -0
- package/lib/model/index.cjs +1 -2
- package/lib/model/index.d.ts +4 -0
- package/lib/model/types.cjs +1 -2
- package/lib/model/types.d.ts +6 -0
- package/lib/persistence/Adapter.cjs +1 -2
- package/lib/persistence/Adapter.d.ts +86 -0
- package/lib/persistence/Sequence.cjs +1 -2
- package/lib/persistence/Sequence.d.ts +22 -0
- package/lib/persistence/constants.cjs +1 -2
- package/lib/persistence/constants.d.ts +22 -0
- package/lib/persistence/decorators.cjs +1 -2
- package/lib/persistence/decorators.d.ts +1 -0
- package/lib/persistence/errors.cjs +1 -2
- package/lib/persistence/errors.d.ts +7 -0
- package/lib/persistence/index.cjs +1 -2
- package/lib/persistence/index.d.ts +5 -0
- package/lib/query/Clause.cjs +1 -2
- package/lib/query/Clause.d.ts +50 -0
- package/lib/query/ClauseFactory.cjs +1 -2
- package/lib/query/ClauseFactory.d.ts +71 -0
- package/lib/query/Condition.cjs +1 -2
- package/lib/query/Condition.d.ts +75 -0
- package/lib/query/Paginator.cjs +1 -2
- package/lib/query/Paginator.d.ts +22 -0
- package/lib/query/Query.cjs +1 -2
- package/lib/query/Query.d.ts +43 -0
- package/lib/query/Statement.cjs +1 -2
- package/lib/query/Statement.d.ts +56 -0
- package/lib/query/clauses/FromClause.cjs +1 -2
- package/lib/query/clauses/FromClause.d.ts +45 -0
- package/lib/query/clauses/GroupByClause.cjs +1 -2
- package/lib/query/clauses/GroupByClause.d.ts +21 -0
- package/lib/query/clauses/InsertClause.cjs +1 -2
- package/lib/query/clauses/InsertClause.d.ts +37 -0
- package/lib/query/clauses/LimitClause.cjs +1 -2
- package/lib/query/clauses/LimitClause.d.ts +29 -0
- package/lib/query/clauses/OffsetClause.cjs +1 -2
- package/lib/query/clauses/OffsetClause.d.ts +21 -0
- package/lib/query/clauses/OrderByClause.cjs +1 -2
- package/lib/query/clauses/OrderByClause.d.ts +37 -0
- package/lib/query/clauses/SelectClause.cjs +1 -2
- package/lib/query/clauses/SelectClause.d.ts +47 -0
- package/lib/query/clauses/SelectorBasedClause.cjs +1 -2
- package/lib/query/clauses/SelectorBasedClause.d.ts +25 -0
- package/lib/query/clauses/ValuesClause.cjs +1 -2
- package/lib/query/clauses/ValuesClause.d.ts +21 -0
- package/lib/query/clauses/WhereClause.cjs +1 -2
- package/lib/query/clauses/WhereClause.d.ts +46 -0
- package/lib/query/clauses/index.cjs +1 -2
- package/lib/query/clauses/index.d.ts +10 -0
- package/lib/query/constants.cjs +1 -2
- package/lib/query/constants.d.ts +79 -0
- package/lib/query/errors.cjs +1 -2
- package/lib/query/errors.d.ts +7 -0
- package/lib/query/index.cjs +1 -2
- package/lib/query/index.d.ts +12 -0
- package/lib/query/options.cjs +1 -2
- package/lib/query/options.d.ts +372 -0
- package/lib/query/selectors.cjs +1 -2
- package/lib/query/selectors.d.ts +38 -0
- package/lib/query/types.cjs +1 -2
- package/lib/query/types.d.ts +2 -0
- package/lib/repository/Context.cjs +1 -2
- package/lib/repository/Context.d.ts +10 -0
- package/lib/repository/Repository.cjs +1 -2
- package/lib/repository/Repository.d.ts +70 -0
- package/lib/repository/constants.cjs +1 -2
- package/lib/repository/constants.d.ts +25 -0
- package/lib/repository/decorators.cjs +1 -2
- package/lib/repository/decorators.d.ts +2 -0
- package/lib/repository/errors.cjs +1 -2
- package/lib/repository/errors.d.ts +12 -0
- package/lib/repository/index.cjs +1 -2
- package/lib/repository/index.d.ts +8 -0
- package/lib/repository/injectables.cjs +1 -2
- package/lib/repository/injectables.d.ts +5 -0
- package/lib/repository/types.cjs +1 -2
- package/lib/repository/types.d.ts +15 -0
- package/lib/repository/utils.cjs +1 -2
- package/lib/repository/utils.d.ts +3 -0
- package/lib/validators/ClauseSequenceValidator.cjs +1 -2
- package/lib/validators/ClauseSequenceValidator.d.ts +28 -0
- package/lib/validators/decorators.cjs +1 -2
- package/lib/validators/decorators.d.ts +10 -0
- package/lib/validators/index.cjs +1 -2
- package/lib/validators/index.d.ts +2 -0
- package/package.json +24 -37
- package/dist/core.js +0 -2
- package/dist/core.js.LICENSE.txt +0 -14
- package/dist/esm/core.js +0 -2
- package/dist/esm/core.js.LICENSE.txt +0 -14
- /package/{dist/types → lib/esm}/identity/decorators.d.ts +0 -0
- /package/{dist/types → lib/esm}/identity/index.d.ts +0 -0
- /package/{dist/types → lib/esm}/identity/utils.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/Builder.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/Executor.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/Observable.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/Observer.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/Paginatable.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/Queriable.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/RawExecutor.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/SequenceOptions.d.ts +0 -0
- /package/{dist/types → lib/esm}/interfaces/index.d.ts +0 -0
- /package/{dist/types → lib/esm}/model/BaseModel.d.ts +0 -0
- /package/{dist/types → lib/esm}/model/IdentifiedBaseModel.d.ts +0 -0
- /package/{dist/types → lib/esm}/model/construction.d.ts +0 -0
- /package/{dist/types → lib/esm}/model/decorators.d.ts +0 -0
- /package/{dist/types → lib/esm}/model/index.d.ts +0 -0
- /package/{dist/types → lib/esm}/model/types.d.ts +0 -0
- /package/{dist/types → lib/esm}/persistence/Adapter.d.ts +0 -0
- /package/{dist/types → lib/esm}/persistence/Sequence.d.ts +0 -0
- /package/{dist/types → lib/esm}/persistence/constants.d.ts +0 -0
- /package/{dist/types → lib/esm}/persistence/decorators.d.ts +0 -0
- /package/{dist/types → lib/esm}/persistence/errors.d.ts +0 -0
- /package/{dist/types → lib/esm}/persistence/index.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/Clause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/ClauseFactory.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/Condition.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/Paginator.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/Query.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/FromClause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/GroupByClause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/InsertClause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/LimitClause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/OffsetClause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/OrderByClause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/SelectClause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/SelectorBasedClause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/ValuesClause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/WhereClause.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/clauses/index.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/constants.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/errors.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/index.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/options.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/selectors.d.ts +0 -0
- /package/{dist/types → lib/esm}/query/types.d.ts +0 -0
- /package/{dist/types → lib/esm}/repository/Context.d.ts +0 -0
- /package/{dist/types → lib/esm}/repository/Repository.d.ts +0 -0
- /package/{dist/types → lib/esm}/repository/constants.d.ts +0 -0
- /package/{dist/types → lib/esm}/repository/decorators.d.ts +0 -0
- /package/{dist/types → lib/esm}/repository/errors.d.ts +0 -0
- /package/{dist/types → lib/esm}/repository/index.d.ts +0 -0
- /package/{dist/types → lib/esm}/repository/injectables.d.ts +0 -0
- /package/{dist/types → lib/esm}/repository/types.d.ts +0 -0
- /package/{dist/types → lib/esm}/repository/utils.d.ts +0 -0
- /package/{dist/types → lib/esm}/validators/ClauseSequenceValidator.d.ts +0 -0
- /package/{dist/types → lib/esm}/validators/decorators.d.ts +0 -0
- /package/{dist/types → lib/esm}/validators/index.d.ts +0 -0
package/dist/core.cjs
ADDED
@@ -0,0 +1,2361 @@
|
|
1
|
+
(function (global, factory) {
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@decaf-ts/db-decorators'), require('@decaf-ts/injectable-decorators'), require('@decaf-ts/reflection'), require('@decaf-ts/decorator-validation')) :
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', '@decaf-ts/db-decorators', '@decaf-ts/injectable-decorators', '@decaf-ts/reflection', '@decaf-ts/decorator-validation'], factory) :
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.core = {}, global.dbDecorators, global.injectableDecorators, global.reflection, global.decoratorValidation));
|
5
|
+
})(this, (function (exports, dbDecorators, injectableDecorators, reflection, decoratorValidation) { 'use strict';
|
6
|
+
|
7
|
+
/**
|
8
|
+
* @summary defines order directions when sorting
|
9
|
+
*
|
10
|
+
* @constant OrderDirection
|
11
|
+
*
|
12
|
+
* @category Query
|
13
|
+
*/
|
14
|
+
exports.OrderDirection = void 0;
|
15
|
+
(function (OrderDirection) {
|
16
|
+
/**
|
17
|
+
* @summary Defines the sort order as ascending
|
18
|
+
* @prop ASC
|
19
|
+
*/
|
20
|
+
OrderDirection["ASC"] = "asc";
|
21
|
+
/**
|
22
|
+
* @summary Defines the sort order as descending
|
23
|
+
* @property {string} DSC
|
24
|
+
*/
|
25
|
+
OrderDirection["DSC"] = "desc";
|
26
|
+
})(exports.OrderDirection || (exports.OrderDirection = {}));
|
27
|
+
exports.Cascade = void 0;
|
28
|
+
(function (Cascade) {
|
29
|
+
Cascade["CASCADE"] = "cascade";
|
30
|
+
Cascade["NONE"] = "none";
|
31
|
+
})(exports.Cascade || (exports.Cascade = {}));
|
32
|
+
const DefaultCascade = {
|
33
|
+
update: exports.Cascade.CASCADE,
|
34
|
+
delete: exports.Cascade.NONE,
|
35
|
+
};
|
36
|
+
|
37
|
+
class Context extends dbDecorators.Context {
|
38
|
+
constructor(operation, model, parent) {
|
39
|
+
super(operation, model, parent);
|
40
|
+
}
|
41
|
+
get timestamp() {
|
42
|
+
if (!this._timestamp)
|
43
|
+
this._timestamp = new Date();
|
44
|
+
return this._timestamp;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
exports.PersistenceKeys = void 0;
|
49
|
+
(function (PersistenceKeys) {
|
50
|
+
PersistenceKeys["INDEX"] = "index";
|
51
|
+
PersistenceKeys["UNIQUE"] = "unique";
|
52
|
+
PersistenceKeys["ADAPTER"] = "adapter";
|
53
|
+
PersistenceKeys["INJECTABLE"] = "decaf_{0}_adapter_for_{1}";
|
54
|
+
PersistenceKeys["TABLE"] = "table";
|
55
|
+
PersistenceKeys["COLUMN"] = "column";
|
56
|
+
PersistenceKeys["METADATA"] = "__metadata";
|
57
|
+
PersistenceKeys["RELATIONS"] = "__relations";
|
58
|
+
PersistenceKeys["CLAUSE_SEQUENCE"] = "clause-sequence";
|
59
|
+
// Ownership
|
60
|
+
PersistenceKeys["CREATED_BY"] = "ownership.created-by";
|
61
|
+
PersistenceKeys["UPDATED_BY"] = "ownership.updated-by";
|
62
|
+
// Relations
|
63
|
+
PersistenceKeys["ONE_TO_ONE"] = "relations.one-to-one";
|
64
|
+
PersistenceKeys["ONE_TO_MANY"] = "relations.one-to-many";
|
65
|
+
PersistenceKeys["MANY_TO_ONE"] = "relations.many-to-one";
|
66
|
+
PersistenceKeys["POPULATE"] = "populate";
|
67
|
+
})(exports.PersistenceKeys || (exports.PersistenceKeys = {}));
|
68
|
+
exports.Roles = void 0;
|
69
|
+
(function (Roles) {
|
70
|
+
Roles["ADMIN"] = "admin";
|
71
|
+
Roles["WRITER"] = "writer";
|
72
|
+
Roles["READER"] = "reader";
|
73
|
+
})(exports.Roles || (exports.Roles = {}));
|
74
|
+
|
75
|
+
exports.Operator = void 0;
|
76
|
+
(function (Operator) {
|
77
|
+
Operator["EQUAL"] = "EQUAL";
|
78
|
+
Operator["DIFFERENT"] = "DIFFERENT";
|
79
|
+
Operator["BIGGER"] = "BIGGER";
|
80
|
+
Operator["BIGGER_EQ"] = "BIGGER_EQ";
|
81
|
+
Operator["SMALLER"] = "SMALLER";
|
82
|
+
Operator["SMALLER_EQ"] = "SMALLER_EQ";
|
83
|
+
// BETWEEN = "BETWEEN",
|
84
|
+
Operator["NOT"] = "NOT";
|
85
|
+
Operator["IN"] = "IN";
|
86
|
+
// IS = "IS",
|
87
|
+
Operator["REGEXP"] = "REGEXP";
|
88
|
+
})(exports.Operator || (exports.Operator = {}));
|
89
|
+
exports.GroupOperator = void 0;
|
90
|
+
(function (GroupOperator) {
|
91
|
+
GroupOperator["AND"] = "AND";
|
92
|
+
GroupOperator["OR"] = "OR";
|
93
|
+
})(exports.GroupOperator || (exports.GroupOperator = {}));
|
94
|
+
exports.Const = void 0;
|
95
|
+
(function (Const) {
|
96
|
+
Const["NULL"] = "NULL";
|
97
|
+
Const["FULL_RECORD"] = "*";
|
98
|
+
})(exports.Const || (exports.Const = {}));
|
99
|
+
/**
|
100
|
+
* @summary Defines execution order of Clauses in statements as defined in SQL.
|
101
|
+
*
|
102
|
+
* @description sub priorities where defined to better organize clauses within statements, eg From and Join Clauses
|
103
|
+
*
|
104
|
+
* @const Priority
|
105
|
+
*
|
106
|
+
* @category Clauses
|
107
|
+
* @subcategory Constants
|
108
|
+
*/
|
109
|
+
exports.Priority = void 0;
|
110
|
+
(function (Priority) {
|
111
|
+
/**
|
112
|
+
* @summary Defines the priority for the FROM Clause
|
113
|
+
* @description From Clause in SELECT Statements.
|
114
|
+
* Values Clause in INSERT Statements
|
115
|
+
*
|
116
|
+
* @prop FROM
|
117
|
+
*/
|
118
|
+
Priority[Priority["FROM"] = 1] = "FROM";
|
119
|
+
/**
|
120
|
+
* @summary Defines the priority for the JOIN Clause
|
121
|
+
*
|
122
|
+
* @property {number} JOIN
|
123
|
+
*/
|
124
|
+
Priority[Priority["JOIN"] = 1.1] = "JOIN";
|
125
|
+
/**
|
126
|
+
* Where Clause
|
127
|
+
*/
|
128
|
+
Priority[Priority["WHERE"] = 2] = "WHERE";
|
129
|
+
/**
|
130
|
+
* Group By Clause
|
131
|
+
*/
|
132
|
+
Priority[Priority["GROUP_BY"] = 3] = "GROUP_BY";
|
133
|
+
/**
|
134
|
+
* Having Clause
|
135
|
+
*/
|
136
|
+
Priority[Priority["HAVING"] = 4] = "HAVING";
|
137
|
+
/**
|
138
|
+
* Select Clause in SELECT Statements
|
139
|
+
* Insert Clause in INSERT Statements
|
140
|
+
*/
|
141
|
+
Priority[Priority["SELECT"] = 5] = "SELECT";
|
142
|
+
/**
|
143
|
+
* Order By Clause
|
144
|
+
*/
|
145
|
+
Priority[Priority["ORDER_BY"] = 6] = "ORDER_BY";
|
146
|
+
/**
|
147
|
+
* Limit Clause
|
148
|
+
*/
|
149
|
+
Priority[Priority["LIMIT"] = 7] = "LIMIT";
|
150
|
+
/**
|
151
|
+
* Offset Clause
|
152
|
+
*/
|
153
|
+
Priority[Priority["OFFSET"] = 7.1] = "OFFSET";
|
154
|
+
})(exports.Priority || (exports.Priority = {}));
|
155
|
+
const MandatoryPriorities = [exports.Priority.FROM, exports.Priority.SELECT];
|
156
|
+
exports.StatementType = void 0;
|
157
|
+
(function (StatementType) {
|
158
|
+
StatementType["QUERY"] = "query";
|
159
|
+
StatementType["TRANSACTION"] = "transaction";
|
160
|
+
})(exports.StatementType || (exports.StatementType = {}));
|
161
|
+
|
162
|
+
/**
|
163
|
+
* @summary Helper Class to build queries
|
164
|
+
*
|
165
|
+
* @param {Database} db
|
166
|
+
*
|
167
|
+
* @class Query
|
168
|
+
*
|
169
|
+
* @category Query
|
170
|
+
*/
|
171
|
+
class Query {
|
172
|
+
constructor(adapter) {
|
173
|
+
this.adapter = adapter;
|
174
|
+
}
|
175
|
+
/**
|
176
|
+
* @summary Creates a Select Clause
|
177
|
+
* @param {SelectSelector} [selector]
|
178
|
+
*/
|
179
|
+
select(selector = exports.Const.FULL_RECORD) {
|
180
|
+
return this.adapter.Clauses.select(selector);
|
181
|
+
}
|
182
|
+
/**
|
183
|
+
* @summary Creates a Min Clause
|
184
|
+
* @param {SelectSelector} selector
|
185
|
+
*/
|
186
|
+
min(selector) {
|
187
|
+
return this.select().min(selector);
|
188
|
+
}
|
189
|
+
/**
|
190
|
+
* @summary Creates a Max Clause
|
191
|
+
* @param {SelectSelector} selector
|
192
|
+
*/
|
193
|
+
max(selector) {
|
194
|
+
return this.select().max(selector);
|
195
|
+
}
|
196
|
+
/**
|
197
|
+
* @summary Creates a Distinct Clause
|
198
|
+
* @param {SelectSelector} selector
|
199
|
+
*/
|
200
|
+
distinct(selector) {
|
201
|
+
return this.select().distinct(selector);
|
202
|
+
}
|
203
|
+
/**
|
204
|
+
* @summary Creates a Count Clause
|
205
|
+
* @param {SelectSelector} selector
|
206
|
+
*/
|
207
|
+
count(selector) {
|
208
|
+
return this.select().count(selector);
|
209
|
+
}
|
210
|
+
insert() {
|
211
|
+
return this.adapter.Clauses.insert();
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
class ConnectionError extends dbDecorators.BaseError {
|
216
|
+
constructor(msg) {
|
217
|
+
super(ConnectionError.name, msg);
|
218
|
+
}
|
219
|
+
}
|
220
|
+
class UnsupportedError extends dbDecorators.BaseError {
|
221
|
+
constructor(msg) {
|
222
|
+
super(UnsupportedError.name, msg);
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
/**
|
227
|
+
* @summary Abstract Decaf-ts Persistence Adapter Class
|
228
|
+
* @description Offers the base implementation for all Adapter Classes
|
229
|
+
* and manages them various registered {@link Adapter}s
|
230
|
+
*
|
231
|
+
* @typedef Y the underlying persistence object type
|
232
|
+
* @typedef Q The query object the adapter uses
|
233
|
+
*
|
234
|
+
* @param {Y} native the underlying persistence object
|
235
|
+
* @param {string} flavour the under witch the persistence adapter should be stored
|
236
|
+
*
|
237
|
+
* @class Adapter
|
238
|
+
* @implements RawExecutor
|
239
|
+
* @implements Observable
|
240
|
+
*/
|
241
|
+
class Adapter {
|
242
|
+
static { this._cache = {}; }
|
243
|
+
get native() {
|
244
|
+
return this._native;
|
245
|
+
}
|
246
|
+
repository() {
|
247
|
+
return Repository;
|
248
|
+
}
|
249
|
+
constructor(native, flavour) {
|
250
|
+
this.flavour = flavour;
|
251
|
+
this._observers = [];
|
252
|
+
if (this.flavour in Adapter._cache)
|
253
|
+
throw new dbDecorators.InternalError(`Persistence adapter flavour ${this.flavour} already registered`);
|
254
|
+
this._native = native;
|
255
|
+
Adapter._cache[this.flavour] = this;
|
256
|
+
}
|
257
|
+
Query() {
|
258
|
+
return new Query(this);
|
259
|
+
}
|
260
|
+
isReserved(attr) {
|
261
|
+
return !attr;
|
262
|
+
}
|
263
|
+
async context(operation, model) {
|
264
|
+
let user;
|
265
|
+
try {
|
266
|
+
user = await this.user();
|
267
|
+
}
|
268
|
+
catch (e) {
|
269
|
+
if (!(e instanceof UnsupportedError))
|
270
|
+
throw e;
|
271
|
+
}
|
272
|
+
const c = new (class extends Context {
|
273
|
+
constructor(operation, model, parent) {
|
274
|
+
super(operation, model, parent);
|
275
|
+
}
|
276
|
+
get user() {
|
277
|
+
if (!user)
|
278
|
+
throw new UnsupportedError("Adapter does not support user identification");
|
279
|
+
return user;
|
280
|
+
}
|
281
|
+
})(operation, model);
|
282
|
+
return c;
|
283
|
+
}
|
284
|
+
prepare(model, pk) {
|
285
|
+
const result = Object.entries(model).reduce((accum, [key, val]) => {
|
286
|
+
// if (key === pk) return accum;
|
287
|
+
const mappedProp = Repository.column(model, key);
|
288
|
+
if (this.isReserved(mappedProp))
|
289
|
+
throw new dbDecorators.InternalError(`Property name ${mappedProp} is reserved`);
|
290
|
+
accum[mappedProp] = val;
|
291
|
+
return accum;
|
292
|
+
}, {});
|
293
|
+
if (model[exports.PersistenceKeys.METADATA])
|
294
|
+
Object.defineProperty(result, exports.PersistenceKeys.METADATA, {
|
295
|
+
enumerable: false,
|
296
|
+
writable: false,
|
297
|
+
configurable: true,
|
298
|
+
value: model[exports.PersistenceKeys.METADATA],
|
299
|
+
});
|
300
|
+
return {
|
301
|
+
record: result,
|
302
|
+
id: model[pk],
|
303
|
+
};
|
304
|
+
}
|
305
|
+
revert(obj, clazz, pk, id) {
|
306
|
+
const ob = {};
|
307
|
+
ob[pk] = id;
|
308
|
+
const m = (typeof clazz === "string" ? decoratorValidation.Model.build(ob, clazz) : new clazz(ob));
|
309
|
+
const metadata = obj[exports.PersistenceKeys.METADATA];
|
310
|
+
const result = Object.keys(m).reduce((accum, key) => {
|
311
|
+
if (key === pk)
|
312
|
+
return accum;
|
313
|
+
accum[key] = obj[Repository.column(accum, key)];
|
314
|
+
return accum;
|
315
|
+
}, m);
|
316
|
+
if (metadata)
|
317
|
+
Object.defineProperty(result, exports.PersistenceKeys.METADATA, {
|
318
|
+
enumerable: false,
|
319
|
+
configurable: false,
|
320
|
+
writable: false,
|
321
|
+
value: metadata,
|
322
|
+
});
|
323
|
+
return result;
|
324
|
+
}
|
325
|
+
async createAll(tableName, id, model, ...args) {
|
326
|
+
if (id.length !== model.length)
|
327
|
+
throw new dbDecorators.InternalError("Ids and models must have the same length");
|
328
|
+
return Promise.all(id.map((i, count) => this.create(tableName, i, model[count], ...args)));
|
329
|
+
}
|
330
|
+
async readAll(tableName, id, ...args) {
|
331
|
+
return Promise.all(id.map((i) => this.read(tableName, i, ...args)));
|
332
|
+
}
|
333
|
+
async updateAll(tableName, id, model, ...args) {
|
334
|
+
if (id.length !== model.length)
|
335
|
+
throw new dbDecorators.InternalError("Ids and models must have the same length");
|
336
|
+
return Promise.all(id.map((i, count) => this.update(tableName, i, model[count], ...args)));
|
337
|
+
}
|
338
|
+
async deleteAll(tableName, id, ...args) {
|
339
|
+
return Promise.all(id.map((i) => this.delete(tableName, i, ...args)));
|
340
|
+
}
|
341
|
+
/**
|
342
|
+
* @summary Registers an {@link Observer}
|
343
|
+
* @param {Observer} observer
|
344
|
+
*
|
345
|
+
* @see {Observable#observe}
|
346
|
+
*/
|
347
|
+
observe(observer) {
|
348
|
+
const index = this._observers.indexOf(observer);
|
349
|
+
if (index !== -1)
|
350
|
+
throw new dbDecorators.InternalError("Observer already registered");
|
351
|
+
this._observers.push(observer);
|
352
|
+
}
|
353
|
+
/**
|
354
|
+
* @summary Unregisters an {@link Observer}
|
355
|
+
* @param {Observer} observer
|
356
|
+
*
|
357
|
+
* @see {Observable#unObserve}
|
358
|
+
*/
|
359
|
+
unObserve(observer) {
|
360
|
+
const index = this._observers.indexOf(observer);
|
361
|
+
if (index === -1)
|
362
|
+
throw new dbDecorators.InternalError("Failed to find Observer");
|
363
|
+
this._observers.splice(index, 1);
|
364
|
+
}
|
365
|
+
/**
|
366
|
+
* @summary calls all registered {@link Observer}s to update themselves
|
367
|
+
* @param {any[]} [args] optional arguments to be passed to the {@link Observer#refresh} method
|
368
|
+
*/
|
369
|
+
async updateObservers(...args) {
|
370
|
+
const results = await Promise.allSettled(this._observers.map((o) => o.refresh(...args)));
|
371
|
+
results.forEach((result, i) => {
|
372
|
+
if (result.status === "rejected")
|
373
|
+
console.warn(`Failed to update observable ${this._observers[i]}: ${result.reason}`);
|
374
|
+
});
|
375
|
+
}
|
376
|
+
static get current() {
|
377
|
+
return this._current;
|
378
|
+
}
|
379
|
+
static get(flavour) {
|
380
|
+
if (flavour in this._cache)
|
381
|
+
return this._cache[flavour];
|
382
|
+
throw new dbDecorators.InternalError(`No Adapter registered under ${flavour}.`);
|
383
|
+
}
|
384
|
+
static setCurrent(flavour) {
|
385
|
+
const adapter = Adapter.get(flavour);
|
386
|
+
if (!adapter)
|
387
|
+
throw new dbDecorators.NotFoundError(`No persistence flavour ${flavour} registered`);
|
388
|
+
this._current = adapter;
|
389
|
+
}
|
390
|
+
static key(key) {
|
391
|
+
return Repository.key(key);
|
392
|
+
}
|
393
|
+
static models(flavour) {
|
394
|
+
try {
|
395
|
+
const registry = decoratorValidation.Model.getRegistry();
|
396
|
+
const cache = registry.cache;
|
397
|
+
const managedModels = Object.values(cache)
|
398
|
+
.map((m) => {
|
399
|
+
let f = Reflect.getMetadata(Adapter.key(exports.PersistenceKeys.ADAPTER), m);
|
400
|
+
if (f && f === flavour)
|
401
|
+
return m;
|
402
|
+
if (!f) {
|
403
|
+
const repo = Reflect.getMetadata(Repository.key(dbDecorators.DBKeys.REPOSITORY), m);
|
404
|
+
if (!repo)
|
405
|
+
return;
|
406
|
+
const repository = Repository.forModel(m);
|
407
|
+
f = Reflect.getMetadata(Adapter.key(exports.PersistenceKeys.ADAPTER), repository);
|
408
|
+
return f;
|
409
|
+
}
|
410
|
+
})
|
411
|
+
.filter((m) => !!m);
|
412
|
+
return managedModels;
|
413
|
+
}
|
414
|
+
catch (e) {
|
415
|
+
throw new dbDecorators.InternalError(e);
|
416
|
+
}
|
417
|
+
}
|
418
|
+
}
|
419
|
+
|
420
|
+
function getTableName(model) {
|
421
|
+
const metadata = Reflect.getMetadata(Adapter.key(exports.PersistenceKeys.TABLE), model instanceof decoratorValidation.Model ? model.constructor : model);
|
422
|
+
if (metadata) {
|
423
|
+
return metadata;
|
424
|
+
}
|
425
|
+
if (model instanceof decoratorValidation.Model) {
|
426
|
+
return model.constructor.name;
|
427
|
+
}
|
428
|
+
return model.name;
|
429
|
+
}
|
430
|
+
function sequenceNameForModel(model, ...args) {
|
431
|
+
return [getTableName(model), ...args].join("_");
|
432
|
+
}
|
433
|
+
|
434
|
+
class Sequence {
|
435
|
+
constructor(options) {
|
436
|
+
this.options = options;
|
437
|
+
}
|
438
|
+
static pk(model) {
|
439
|
+
return sequenceNameForModel(model, "pk");
|
440
|
+
}
|
441
|
+
}
|
442
|
+
|
443
|
+
function uses(flavour) {
|
444
|
+
return reflection.apply(reflection.metadata(Adapter.key(exports.PersistenceKeys.ADAPTER), flavour));
|
445
|
+
}
|
446
|
+
|
447
|
+
class Repository extends dbDecorators.Repository {
|
448
|
+
static { this._cache = {}; }
|
449
|
+
get adapter() {
|
450
|
+
if (!this._adapter)
|
451
|
+
throw new dbDecorators.InternalError(`No adapter found for this repository. did you use the @uses decorator or pass it in the constructor?`);
|
452
|
+
return this._adapter;
|
453
|
+
}
|
454
|
+
get tableName() {
|
455
|
+
if (!this._tableName)
|
456
|
+
this._tableName = Repository.table(this.class);
|
457
|
+
return this._tableName;
|
458
|
+
}
|
459
|
+
constructor(adapter, clazz) {
|
460
|
+
super(clazz);
|
461
|
+
this.observers = [];
|
462
|
+
if (adapter)
|
463
|
+
this._adapter = adapter;
|
464
|
+
if (clazz) {
|
465
|
+
Repository.register(clazz, this);
|
466
|
+
if (adapter) {
|
467
|
+
const flavour = Reflect.getMetadata(Adapter.key(exports.PersistenceKeys.ADAPTER), clazz);
|
468
|
+
if (flavour && flavour !== adapter.flavour)
|
469
|
+
throw new dbDecorators.InternalError("Incompatible flavours");
|
470
|
+
uses(adapter.flavour)(clazz);
|
471
|
+
}
|
472
|
+
}
|
473
|
+
[this.createAll, this.readAll, this.updateAll, this.deleteAll].forEach((m) => {
|
474
|
+
const name = m.name;
|
475
|
+
dbDecorators.wrapMethodWithContext(this, this[name + "Prefix"], m, this[name + "Suffix"]);
|
476
|
+
});
|
477
|
+
}
|
478
|
+
async createPrefix(model, ...args) {
|
479
|
+
const contextArgs = await Context.args(dbDecorators.OperationKeys.CREATE, this.class, args, this.adapter);
|
480
|
+
model = new this.class(model);
|
481
|
+
await dbDecorators.enforceDBDecorators(this, contextArgs.context, model, dbDecorators.OperationKeys.CREATE, dbDecorators.OperationKeys.ON);
|
482
|
+
const errors = model.hasErrors();
|
483
|
+
if (errors)
|
484
|
+
throw new dbDecorators.ValidationError(errors.toString());
|
485
|
+
return [model, ...contextArgs.args];
|
486
|
+
}
|
487
|
+
async create(model, ...args) {
|
488
|
+
// eslint-disable-next-line prefer-const
|
489
|
+
let { record, id } = this.adapter.prepare(model, this.pk);
|
490
|
+
record = await this.adapter.create(this.tableName, id, record, ...args);
|
491
|
+
return this.adapter.revert(record, this.class, this.pk, id);
|
492
|
+
}
|
493
|
+
async createAll(models, ...args) {
|
494
|
+
if (!models.length)
|
495
|
+
return models;
|
496
|
+
const prepared = models.map((m) => this.adapter.prepare(m, this.pk));
|
497
|
+
const ids = prepared.map((p) => p.id);
|
498
|
+
let records = prepared.map((p) => p.record);
|
499
|
+
records = await this.adapter.createAll(this.tableName, ids, records, ...args);
|
500
|
+
return records.map((r, i) => this.adapter.revert(r, this.class, this.pk, ids[i]));
|
501
|
+
}
|
502
|
+
async createAllPrefix(models, ...args) {
|
503
|
+
const contextArgs = await Context.args(dbDecorators.OperationKeys.CREATE, this.class, args, this.adapter);
|
504
|
+
if (!models.length)
|
505
|
+
return [models, ...contextArgs.args];
|
506
|
+
const opts = Repository.getSequenceOptions(models[0]);
|
507
|
+
let ids = [];
|
508
|
+
if (opts.type) {
|
509
|
+
if (!opts.name)
|
510
|
+
opts.name = Sequence.pk(models[0]);
|
511
|
+
ids = await (await this.adapter.Sequence(opts)).range(models.length);
|
512
|
+
}
|
513
|
+
models = await Promise.all(models.map(async (m, i) => {
|
514
|
+
m = new this.class(m);
|
515
|
+
m[this.pk] = ids[i];
|
516
|
+
await dbDecorators.enforceDBDecorators(this, contextArgs.context, m, dbDecorators.OperationKeys.CREATE, dbDecorators.OperationKeys.ON);
|
517
|
+
return m;
|
518
|
+
}));
|
519
|
+
const errors = models
|
520
|
+
.map((m) => m.hasErrors())
|
521
|
+
.reduce((accum, e, i) => {
|
522
|
+
if (e)
|
523
|
+
accum =
|
524
|
+
typeof accum === "string"
|
525
|
+
? accum + `\n - ${i}: ${e.toString()}`
|
526
|
+
: ` - ${i}: ${e.toString()}`;
|
527
|
+
return accum;
|
528
|
+
}, undefined);
|
529
|
+
if (errors)
|
530
|
+
throw new dbDecorators.ValidationError(errors);
|
531
|
+
return [models, ...contextArgs.args];
|
532
|
+
}
|
533
|
+
async readPrefix(key, ...args) {
|
534
|
+
const contextArgs = await Context.args(dbDecorators.OperationKeys.READ, this.class, args, this.adapter);
|
535
|
+
const model = new this.class();
|
536
|
+
model[this.pk] = key;
|
537
|
+
await dbDecorators.enforceDBDecorators(this, contextArgs.context, model, dbDecorators.OperationKeys.READ, dbDecorators.OperationKeys.ON);
|
538
|
+
return [key, ...contextArgs.args];
|
539
|
+
}
|
540
|
+
async read(id, ...args) {
|
541
|
+
const m = await this.adapter.read(this.tableName, id, ...args);
|
542
|
+
return this.adapter.revert(m, this.class, this.pk, id);
|
543
|
+
}
|
544
|
+
async readAllPrefix(keys, ...args) {
|
545
|
+
const contextArgs = await Context.args(dbDecorators.OperationKeys.READ, this.class, args, this.adapter);
|
546
|
+
await Promise.all(keys.map(async (k) => {
|
547
|
+
const m = new this.class();
|
548
|
+
m[this.pk] = k;
|
549
|
+
return dbDecorators.enforceDBDecorators(this, contextArgs.context, m, dbDecorators.OperationKeys.READ, dbDecorators.OperationKeys.ON);
|
550
|
+
}));
|
551
|
+
return [keys, ...contextArgs.args];
|
552
|
+
}
|
553
|
+
async readAll(keys, ...args) {
|
554
|
+
const records = await this.adapter.readAll(this.tableName, keys, ...args);
|
555
|
+
return records.map((r, i) => this.adapter.revert(r, this.class, this.pk, keys[i]));
|
556
|
+
}
|
557
|
+
async update(model, ...args) {
|
558
|
+
// eslint-disable-next-line prefer-const
|
559
|
+
let { record, id } = this.adapter.prepare(model, this.pk);
|
560
|
+
record = await this.adapter.update(this.tableName, id, record, ...args);
|
561
|
+
return this.adapter.revert(record, this.class, this.pk, id);
|
562
|
+
}
|
563
|
+
async updatePrefix(model, ...args) {
|
564
|
+
const contextArgs = await Context.args(dbDecorators.OperationKeys.UPDATE, this.class, args, this.adapter);
|
565
|
+
const pk = model[this.pk];
|
566
|
+
if (!pk)
|
567
|
+
throw new dbDecorators.InternalError(`No value for the Id is defined under the property ${this.pk}`);
|
568
|
+
const oldModel = await this.read(pk, ...contextArgs.args);
|
569
|
+
model = this.merge(oldModel, model);
|
570
|
+
await dbDecorators.enforceDBDecorators(this, contextArgs.context, model, dbDecorators.OperationKeys.UPDATE, dbDecorators.OperationKeys.ON, oldModel);
|
571
|
+
const errors = model.hasErrors(oldModel, ...Repository.relations(this.class));
|
572
|
+
if (errors)
|
573
|
+
throw new dbDecorators.ValidationError(errors.toString());
|
574
|
+
if (Repository.getMetadata(oldModel)) {
|
575
|
+
if (!Repository.getMetadata(model))
|
576
|
+
Repository.setMetadata(model, Repository.getMetadata(oldModel));
|
577
|
+
}
|
578
|
+
return [model, ...contextArgs.args];
|
579
|
+
}
|
580
|
+
async updateAll(models, ...args) {
|
581
|
+
const records = models.map((m) => this.adapter.prepare(m, this.pk));
|
582
|
+
const updated = await this.adapter.updateAll(this.tableName, records.map((r) => r.id), records.map((r) => r.record), ...args);
|
583
|
+
return updated.map((u, i) => this.adapter.revert(u, this.class, this.pk, records[i].id));
|
584
|
+
}
|
585
|
+
async updateAllPrefix(models, ...args) {
|
586
|
+
const contextArgs = await Context.args(dbDecorators.OperationKeys.UPDATE, this.class, args, this.adapter);
|
587
|
+
const ids = models.map((m) => {
|
588
|
+
const id = m[this.pk];
|
589
|
+
if (!id)
|
590
|
+
throw new dbDecorators.InternalError("missing id on update operation");
|
591
|
+
return id;
|
592
|
+
});
|
593
|
+
const oldModels = await this.readAll(ids, ...contextArgs.args);
|
594
|
+
models = models.map((m, i) => {
|
595
|
+
m = this.merge(oldModels[i], m);
|
596
|
+
if (Repository.getMetadata(oldModels[i])) {
|
597
|
+
if (!Repository.getMetadata(m))
|
598
|
+
Repository.setMetadata(m, Repository.getMetadata(oldModels[i]));
|
599
|
+
}
|
600
|
+
return m;
|
601
|
+
});
|
602
|
+
await Promise.all(models.map((m, i) => dbDecorators.enforceDBDecorators(this, contextArgs.context, m, dbDecorators.OperationKeys.UPDATE, dbDecorators.OperationKeys.ON, oldModels[i])));
|
603
|
+
const errors = models
|
604
|
+
.map((m, i) => m.hasErrors(oldModels[i], m))
|
605
|
+
.reduce((accum, e, i) => {
|
606
|
+
if (e)
|
607
|
+
accum =
|
608
|
+
typeof accum === "string"
|
609
|
+
? accum + `\n - ${i}: ${e.toString()}`
|
610
|
+
: ` - ${i}: ${e.toString()}`;
|
611
|
+
return accum;
|
612
|
+
}, undefined);
|
613
|
+
if (errors)
|
614
|
+
throw new dbDecorators.ValidationError(errors);
|
615
|
+
models.forEach((m, i) => {
|
616
|
+
if (Repository.getMetadata(oldModels[i])) {
|
617
|
+
if (!Repository.getMetadata(m))
|
618
|
+
Repository.setMetadata(m, Repository.getMetadata(oldModels[i]));
|
619
|
+
}
|
620
|
+
});
|
621
|
+
return [models, ...contextArgs.args];
|
622
|
+
}
|
623
|
+
async deletePrefix(key, ...args) {
|
624
|
+
const contextArgs = await Context.args(dbDecorators.OperationKeys.DELETE, this.class, args, this.adapter);
|
625
|
+
const model = await this.read(key, ...contextArgs.args);
|
626
|
+
await dbDecorators.enforceDBDecorators(this, contextArgs.context, model, dbDecorators.OperationKeys.DELETE, dbDecorators.OperationKeys.ON);
|
627
|
+
return [key, ...contextArgs.args];
|
628
|
+
}
|
629
|
+
async delete(id, ...args) {
|
630
|
+
const m = await this.adapter.delete(this.tableName, id, ...args);
|
631
|
+
return this.adapter.revert(m, this.class, this.pk, id);
|
632
|
+
}
|
633
|
+
async deleteAllPrefix(keys, ...args) {
|
634
|
+
const contextArgs = await Context.args(dbDecorators.OperationKeys.DELETE, this.class, args, this.adapter);
|
635
|
+
const models = await this.readAll(keys, ...contextArgs.args);
|
636
|
+
await Promise.all(models.map(async (m) => {
|
637
|
+
return dbDecorators.enforceDBDecorators(this, contextArgs.context, m, dbDecorators.OperationKeys.DELETE, dbDecorators.OperationKeys.ON);
|
638
|
+
}));
|
639
|
+
return [keys, ...contextArgs.args];
|
640
|
+
}
|
641
|
+
async deleteAll(keys, ...args) {
|
642
|
+
const results = await this.adapter.deleteAll(this.tableName, keys, ...args);
|
643
|
+
return results.map((r, i) => this.adapter.revert(r, this.class, this.pk, keys[i]));
|
644
|
+
}
|
645
|
+
select(selector) {
|
646
|
+
return new Query(this.adapter).select(selector).from(this.class);
|
647
|
+
}
|
648
|
+
async query(condition, orderBy, order = exports.OrderDirection.ASC, limit, skip) {
|
649
|
+
const sort = [orderBy, order];
|
650
|
+
const query = this.select().where(condition).orderBy(sort);
|
651
|
+
if (limit)
|
652
|
+
query.limit(limit);
|
653
|
+
if (skip)
|
654
|
+
query.offset(skip);
|
655
|
+
return query.execute();
|
656
|
+
}
|
657
|
+
/**
|
658
|
+
* @summary Registers an {@link Observer}
|
659
|
+
* @param {Observer} observer
|
660
|
+
*
|
661
|
+
* @see {Observable#observe}
|
662
|
+
*/
|
663
|
+
observe(observer) {
|
664
|
+
const index = this.observers.indexOf(observer);
|
665
|
+
if (index !== -1)
|
666
|
+
throw new dbDecorators.InternalError("Observer already registered");
|
667
|
+
this.observers.push(observer);
|
668
|
+
}
|
669
|
+
/**
|
670
|
+
* @summary Unregisters an {@link Observer}
|
671
|
+
* @param {Observer} observer
|
672
|
+
*
|
673
|
+
* @see {Observable#unObserve}
|
674
|
+
*/
|
675
|
+
unObserve(observer) {
|
676
|
+
const index = this.observers.indexOf(observer);
|
677
|
+
if (index === -1)
|
678
|
+
throw new dbDecorators.InternalError("Failed to find Observer");
|
679
|
+
this.observers.splice(index, 1);
|
680
|
+
}
|
681
|
+
/**
|
682
|
+
* @summary calls all registered {@link Observer}s to update themselves
|
683
|
+
* @param {any[]} [args] optional arguments to be passed to the {@link Observer#refresh} method
|
684
|
+
*/
|
685
|
+
async updateObservers(...args) {
|
686
|
+
const results = await Promise.allSettled(this.observers.map((o) => o.refresh(...args)));
|
687
|
+
results.forEach((result, i) => {
|
688
|
+
if (result.status === "rejected")
|
689
|
+
console.warn(`Failed to update observable ${this.observers[i]}: ${result.reason}`);
|
690
|
+
});
|
691
|
+
}
|
692
|
+
static forModel(model, defaultFlavour) {
|
693
|
+
let repo;
|
694
|
+
try {
|
695
|
+
repo = this.get(model);
|
696
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
697
|
+
}
|
698
|
+
catch (e) {
|
699
|
+
repo = undefined;
|
700
|
+
}
|
701
|
+
if (repo instanceof Repository)
|
702
|
+
return repo;
|
703
|
+
const flavour = Reflect.getMetadata(Adapter.key(exports.PersistenceKeys.ADAPTER), model) ||
|
704
|
+
(repo &&
|
705
|
+
Reflect.getMetadata(Adapter.key(exports.PersistenceKeys.ADAPTER), repo)) ||
|
706
|
+
defaultFlavour;
|
707
|
+
const adapter = flavour
|
708
|
+
? Adapter.get(flavour)
|
709
|
+
: undefined;
|
710
|
+
if (!adapter)
|
711
|
+
throw new dbDecorators.InternalError(`No registered persistence adapter found flavour ${flavour}`);
|
712
|
+
repo = repo || adapter.repository();
|
713
|
+
return new repo(adapter, model);
|
714
|
+
}
|
715
|
+
static get(model) {
|
716
|
+
const name = Repository.table(model);
|
717
|
+
if (name in this._cache)
|
718
|
+
return this._cache[name];
|
719
|
+
throw new dbDecorators.InternalError(`Could not find repository registered under ${name}`);
|
720
|
+
}
|
721
|
+
static register(model, repo) {
|
722
|
+
const name = Repository.table(model);
|
723
|
+
if (name in this._cache)
|
724
|
+
throw new dbDecorators.InternalError(`${name} already registered as a repository`);
|
725
|
+
this._cache[name] = repo;
|
726
|
+
}
|
727
|
+
static setMetadata(model, metadata) {
|
728
|
+
Object.defineProperty(model, exports.PersistenceKeys.METADATA, {
|
729
|
+
enumerable: false,
|
730
|
+
configurable: true,
|
731
|
+
writable: false,
|
732
|
+
value: metadata,
|
733
|
+
});
|
734
|
+
}
|
735
|
+
static getMetadata(model) {
|
736
|
+
const descriptor = Object.getOwnPropertyDescriptor(model, exports.PersistenceKeys.METADATA);
|
737
|
+
return descriptor ? descriptor.value : undefined;
|
738
|
+
}
|
739
|
+
static removeMetadata(model) {
|
740
|
+
const descriptor = Object.getOwnPropertyDescriptor(model, exports.PersistenceKeys.METADATA);
|
741
|
+
if (descriptor)
|
742
|
+
delete model[exports.PersistenceKeys.METADATA];
|
743
|
+
}
|
744
|
+
static getSequenceOptions(model) {
|
745
|
+
const pk = dbDecorators.findPrimaryKey(model).id;
|
746
|
+
const metadata = Reflect.getMetadata(Repository.key(dbDecorators.DBKeys.ID), model, pk);
|
747
|
+
if (!metadata)
|
748
|
+
throw new dbDecorators.InternalError("No sequence options defined for model. did you use the @pk decorator?");
|
749
|
+
return metadata;
|
750
|
+
}
|
751
|
+
static indexes(model) {
|
752
|
+
const indexDecorators = reflection.Reflection.getAllPropertyDecorators(model instanceof decoratorValidation.Model ? model : new model(), dbDecorators.DBKeys.REFLECT);
|
753
|
+
return Object.entries(indexDecorators || {}).reduce((accum, [k, val]) => {
|
754
|
+
const decs = val.filter((v) => v.key.startsWith(exports.PersistenceKeys.INDEX));
|
755
|
+
if (decs && decs.length) {
|
756
|
+
for (const dec of decs) {
|
757
|
+
const { key, props } = dec;
|
758
|
+
accum[k] = accum[k] || {};
|
759
|
+
accum[k][key] = props;
|
760
|
+
}
|
761
|
+
}
|
762
|
+
return accum;
|
763
|
+
}, {});
|
764
|
+
}
|
765
|
+
static relations(model) {
|
766
|
+
const result = [];
|
767
|
+
let prototype = model instanceof decoratorValidation.Model
|
768
|
+
? Object.getPrototypeOf(model)
|
769
|
+
: model.prototype;
|
770
|
+
while (prototype != null) {
|
771
|
+
const props = prototype[exports.PersistenceKeys.RELATIONS];
|
772
|
+
if (props) {
|
773
|
+
result.push(...props);
|
774
|
+
}
|
775
|
+
prototype = Object.getPrototypeOf(prototype);
|
776
|
+
}
|
777
|
+
return result;
|
778
|
+
}
|
779
|
+
static table(model) {
|
780
|
+
return getTableName(model);
|
781
|
+
}
|
782
|
+
static column(model, attribute) {
|
783
|
+
const metadata = Reflect.getMetadata(Adapter.key(exports.PersistenceKeys.COLUMN), model, attribute);
|
784
|
+
return metadata ? metadata : attribute;
|
785
|
+
}
|
786
|
+
}
|
787
|
+
|
788
|
+
function repository(model, nameOverride) {
|
789
|
+
return ((original, propertyKey) => {
|
790
|
+
if (propertyKey) {
|
791
|
+
return injectableDecorators.inject(nameOverride || model.name)(original, propertyKey);
|
792
|
+
}
|
793
|
+
reflection.metadata(Repository.key(dbDecorators.DBKeys.REPOSITORY), nameOverride || original.name)(model);
|
794
|
+
Repository.register(model, original);
|
795
|
+
return injectableDecorators.injectable(nameOverride || original.name, true, (instance) => {
|
796
|
+
Object.defineProperty(instance, dbDecorators.DBKeys.CLASS, {
|
797
|
+
enumerable: false,
|
798
|
+
configurable: false,
|
799
|
+
writable: false,
|
800
|
+
value: model,
|
801
|
+
});
|
802
|
+
})(original);
|
803
|
+
});
|
804
|
+
}
|
805
|
+
|
806
|
+
/**
|
807
|
+
* @summary Represents a failure in observer communication
|
808
|
+
*
|
809
|
+
* @param {string} msg the error message
|
810
|
+
*
|
811
|
+
* @class ObserverError
|
812
|
+
* @extends BaseError
|
813
|
+
*/
|
814
|
+
class ObserverError extends dbDecorators.BaseError {
|
815
|
+
constructor(msg) {
|
816
|
+
super(ObserverError.name, msg);
|
817
|
+
}
|
818
|
+
}
|
819
|
+
|
820
|
+
function generateInjectableNameForRepository(model, flavour) {
|
821
|
+
if (!flavour) {
|
822
|
+
const key = Adapter.key(exports.PersistenceKeys.ADAPTER);
|
823
|
+
flavour = Reflect.getMetadata(key, model instanceof decoratorValidation.Model ? model.constructor : model);
|
824
|
+
if (!flavour)
|
825
|
+
throw new dbDecorators.InternalError(`Could not retrieve flavour from model ${model instanceof decoratorValidation.Model ? model.constructor.name : model.name}`);
|
826
|
+
}
|
827
|
+
return decoratorValidation.sf(exports.PersistenceKeys.INJECTABLE, flavour, Repository.table(model));
|
828
|
+
}
|
829
|
+
|
830
|
+
class InjectablesRegistry extends injectableDecorators.InjectableRegistryImp {
|
831
|
+
constructor() {
|
832
|
+
super();
|
833
|
+
}
|
834
|
+
get(name) {
|
835
|
+
let injectable = super.get(name);
|
836
|
+
if (!injectable)
|
837
|
+
try {
|
838
|
+
const m = decoratorValidation.Model.get(name);
|
839
|
+
if (m)
|
840
|
+
injectable = Repository.forModel(m);
|
841
|
+
if (injectable) {
|
842
|
+
if (injectable instanceof Repository)
|
843
|
+
return injectable;
|
844
|
+
const flavour = Reflect.getMetadata(Adapter.key(exports.PersistenceKeys.ADAPTER), injectable.constructor) ||
|
845
|
+
Reflect.getMetadata(Adapter.key(exports.PersistenceKeys.ADAPTER), m);
|
846
|
+
injectableDecorators.Injectables.register(injectable, generateInjectableNameForRepository(m, flavour));
|
847
|
+
}
|
848
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
849
|
+
}
|
850
|
+
catch (e) {
|
851
|
+
return undefined;
|
852
|
+
}
|
853
|
+
return injectable;
|
854
|
+
}
|
855
|
+
}
|
856
|
+
|
857
|
+
const DefaultSequenceOptions = {
|
858
|
+
type: "Number",
|
859
|
+
startWith: 0,
|
860
|
+
incrementBy: 1,
|
861
|
+
cycle: false,
|
862
|
+
};
|
863
|
+
const NumericSequence = {
|
864
|
+
type: "Number",
|
865
|
+
startWith: 0,
|
866
|
+
incrementBy: 1,
|
867
|
+
cycle: false,
|
868
|
+
};
|
869
|
+
const BigIntSequence = {
|
870
|
+
type: "BigInt",
|
871
|
+
startWith: 0,
|
872
|
+
incrementBy: 1,
|
873
|
+
cycle: false,
|
874
|
+
};
|
875
|
+
|
876
|
+
/******************************************************************************
|
877
|
+
Copyright (c) Microsoft Corporation.
|
878
|
+
|
879
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
880
|
+
purpose with or without fee is hereby granted.
|
881
|
+
|
882
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
883
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
884
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
885
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
886
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
887
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
888
|
+
PERFORMANCE OF THIS SOFTWARE.
|
889
|
+
***************************************************************************** */
|
890
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
891
|
+
|
892
|
+
|
893
|
+
function __decorate(decorators, target, key, desc) {
|
894
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
895
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
896
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
897
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
898
|
+
}
|
899
|
+
|
900
|
+
function __metadata(metadataKey, metadataValue) {
|
901
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
902
|
+
}
|
903
|
+
|
904
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
905
|
+
var e = new Error(message);
|
906
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
907
|
+
};
|
908
|
+
|
909
|
+
class QueryError extends dbDecorators.BaseError {
|
910
|
+
constructor(msg) {
|
911
|
+
super(QueryError.name, msg);
|
912
|
+
}
|
913
|
+
}
|
914
|
+
class PagingError extends dbDecorators.BaseError {
|
915
|
+
constructor(msg) {
|
916
|
+
super(PagingError.name, msg);
|
917
|
+
}
|
918
|
+
}
|
919
|
+
|
920
|
+
/**
|
921
|
+
* @summary Condition Class
|
922
|
+
* @description Represents a logical condition
|
923
|
+
*
|
924
|
+
* @param {string | Condition} attr1
|
925
|
+
* @param {Operator | GroupOperator} operator
|
926
|
+
* @param {string | Condition} comparison
|
927
|
+
*
|
928
|
+
* @class Condition
|
929
|
+
* @implements Executor
|
930
|
+
*
|
931
|
+
* @category Query
|
932
|
+
* @subcategory Conditions
|
933
|
+
*/
|
934
|
+
class Condition extends decoratorValidation.Model {
|
935
|
+
constructor(attr1, operator, comparison) {
|
936
|
+
super();
|
937
|
+
this.attr1 = undefined;
|
938
|
+
this.operator = undefined;
|
939
|
+
this.comparison = undefined;
|
940
|
+
this.attr1 = attr1;
|
941
|
+
this.operator = operator;
|
942
|
+
this.comparison = comparison;
|
943
|
+
}
|
944
|
+
/**
|
945
|
+
* @summary Joins 2 {@link Condition}s on an {@link Operator#AND} operation
|
946
|
+
* @param {Condition} condition
|
947
|
+
*/
|
948
|
+
and(condition) {
|
949
|
+
return Condition.and(this, condition);
|
950
|
+
}
|
951
|
+
/**
|
952
|
+
* @summary Joins 2 {@link Condition}s on an {@link Operator#OR} operation
|
953
|
+
* @param {Condition} condition
|
954
|
+
*/
|
955
|
+
or(condition) {
|
956
|
+
return Condition.or(this, condition);
|
957
|
+
}
|
958
|
+
/**
|
959
|
+
* @summary excludes a valut from the result
|
960
|
+
* @param val
|
961
|
+
*/
|
962
|
+
not(val) {
|
963
|
+
return new Condition(this, exports.Operator.NOT, val);
|
964
|
+
}
|
965
|
+
/**
|
966
|
+
* @inheritDoc
|
967
|
+
*/
|
968
|
+
hasErrors(...exceptions) {
|
969
|
+
const errors = super.hasErrors(...exceptions);
|
970
|
+
if (errors)
|
971
|
+
return errors;
|
972
|
+
if (typeof this.attr1 === "string") {
|
973
|
+
if (this.comparison instanceof Condition)
|
974
|
+
return {
|
975
|
+
comparison: {
|
976
|
+
condition: "Both sides of the comparison must be of the same type",
|
977
|
+
},
|
978
|
+
};
|
979
|
+
if (Object.values(exports.Operator).indexOf(this.operator) === -1)
|
980
|
+
return {
|
981
|
+
operator: {
|
982
|
+
condition: decoratorValidation.sf("Invalid operator {0}", this.operator),
|
983
|
+
},
|
984
|
+
};
|
985
|
+
}
|
986
|
+
if (this.attr1 instanceof Condition) {
|
987
|
+
if (!(this.comparison instanceof Condition) &&
|
988
|
+
this.operator !== exports.Operator.NOT)
|
989
|
+
return {
|
990
|
+
comparison: {
|
991
|
+
condition: decoratorValidation.sf("Invalid operator {0}", this.operator),
|
992
|
+
},
|
993
|
+
};
|
994
|
+
if (Object.values(exports.GroupOperator).indexOf(this.operator) ===
|
995
|
+
-1 &&
|
996
|
+
this.operator !== exports.Operator.NOT)
|
997
|
+
return {
|
998
|
+
operator: {
|
999
|
+
condition: decoratorValidation.sf("Invalid operator {0}", this.operator),
|
1000
|
+
},
|
1001
|
+
};
|
1002
|
+
// if (this.operator !== Operator.NOT && typeof this.attr1.attr1 !== "string")
|
1003
|
+
// return {
|
1004
|
+
// attr1: {
|
1005
|
+
// condition: stringFormat("Parent condition attribute must be a string")
|
1006
|
+
// }
|
1007
|
+
// } as ModelErrorDefinition
|
1008
|
+
}
|
1009
|
+
}
|
1010
|
+
/**
|
1011
|
+
* @summary Joins 2 {@link Condition}s on an {@link Operator#AND} operation
|
1012
|
+
* @param {Condition} condition1
|
1013
|
+
* @param {Condition} condition2
|
1014
|
+
*/
|
1015
|
+
static and(condition1, condition2) {
|
1016
|
+
return Condition.group(condition1, exports.GroupOperator.AND, condition2);
|
1017
|
+
}
|
1018
|
+
/**
|
1019
|
+
* @summary Joins 2 {@link Condition}s on an {@link Operator#OR} operation
|
1020
|
+
* @param {Condition} condition1
|
1021
|
+
* @param {Condition} condition2
|
1022
|
+
*/
|
1023
|
+
static or(condition1, condition2) {
|
1024
|
+
return Condition.group(condition1, exports.GroupOperator.OR, condition2);
|
1025
|
+
}
|
1026
|
+
/**
|
1027
|
+
* @summary Groups 2 {@link Condition}s by the specified {@link GroupOperator}
|
1028
|
+
* @param {Condition} condition1
|
1029
|
+
* @param {GroupOperator} operator
|
1030
|
+
* @param {Condition} condition2
|
1031
|
+
*/
|
1032
|
+
static group(condition1, operator, condition2) {
|
1033
|
+
return new Condition(condition1, operator, condition2);
|
1034
|
+
}
|
1035
|
+
static attribute(attr) {
|
1036
|
+
return new Condition.Builder().attribute(attr);
|
1037
|
+
}
|
1038
|
+
/**
|
1039
|
+
* @summary Condition Builder Class
|
1040
|
+
* @description provides a simple API to build {@link Condition}s
|
1041
|
+
*
|
1042
|
+
* @class ConditionBuilder
|
1043
|
+
* @implements Builder
|
1044
|
+
* @implements AttributeOption
|
1045
|
+
*
|
1046
|
+
* @category Query
|
1047
|
+
* @subcategory Conditions
|
1048
|
+
*/
|
1049
|
+
static { this.Builder = class ConditionBuilder {
|
1050
|
+
constructor() {
|
1051
|
+
this.attr1 = undefined;
|
1052
|
+
this.operator = undefined;
|
1053
|
+
this.comparison = undefined;
|
1054
|
+
}
|
1055
|
+
/**
|
1056
|
+
* @inheritDoc
|
1057
|
+
*/
|
1058
|
+
attribute(attr) {
|
1059
|
+
this.attr1 = attr;
|
1060
|
+
return this;
|
1061
|
+
}
|
1062
|
+
/**
|
1063
|
+
* @summary Creates an Equality Comparison
|
1064
|
+
* @param {any} val
|
1065
|
+
*/
|
1066
|
+
eq(val) {
|
1067
|
+
return this.setOp(exports.Operator.EQUAL, val);
|
1068
|
+
}
|
1069
|
+
/**
|
1070
|
+
* @summary Creates a Different Comparison
|
1071
|
+
* @param {any} val
|
1072
|
+
*/
|
1073
|
+
dif(val) {
|
1074
|
+
return this.setOp(exports.Operator.DIFFERENT, val);
|
1075
|
+
}
|
1076
|
+
/**
|
1077
|
+
* @summary Creates a Greater Than Comparison
|
1078
|
+
* @param {any} val
|
1079
|
+
*/
|
1080
|
+
gt(val) {
|
1081
|
+
return this.setOp(exports.Operator.BIGGER, val);
|
1082
|
+
}
|
1083
|
+
/**
|
1084
|
+
* @summary Creates a Lower Than Comparison
|
1085
|
+
* @param {any} val
|
1086
|
+
*/
|
1087
|
+
lt(val) {
|
1088
|
+
return this.setOp(exports.Operator.SMALLER, val);
|
1089
|
+
}
|
1090
|
+
/**
|
1091
|
+
* @summary Creates a Greater or Equal to Comparison
|
1092
|
+
* @param {any} val
|
1093
|
+
*/
|
1094
|
+
gte(val) {
|
1095
|
+
return this.setOp(exports.Operator.BIGGER_EQ, val);
|
1096
|
+
}
|
1097
|
+
/**
|
1098
|
+
* @summary Creates a Lower or Equal to Comparison
|
1099
|
+
* @param {any} val
|
1100
|
+
*/
|
1101
|
+
lte(val) {
|
1102
|
+
return this.setOp(exports.Operator.SMALLER_EQ, val);
|
1103
|
+
}
|
1104
|
+
in(arr) {
|
1105
|
+
return this.setOp(exports.Operator.IN, arr);
|
1106
|
+
}
|
1107
|
+
/**
|
1108
|
+
* @summary Creates a Regexpo Comparison
|
1109
|
+
* @param {any} val
|
1110
|
+
*/
|
1111
|
+
regexp(val) {
|
1112
|
+
return this.setOp(exports.Operator.REGEXP, new RegExp(val).source);
|
1113
|
+
}
|
1114
|
+
/**
|
1115
|
+
* @summary Creates an {@link Operator} based Comparison
|
1116
|
+
* @param {Operator} op
|
1117
|
+
* @param {any} val
|
1118
|
+
*/
|
1119
|
+
setOp(op, val) {
|
1120
|
+
this.operator = op;
|
1121
|
+
this.comparison = val;
|
1122
|
+
return this.build();
|
1123
|
+
}
|
1124
|
+
/**
|
1125
|
+
* @summary Builds the Database Object
|
1126
|
+
* @throws {QueryError} if it fails to build the {@link Condition}
|
1127
|
+
* @private
|
1128
|
+
*/
|
1129
|
+
build() {
|
1130
|
+
try {
|
1131
|
+
return new Condition(this.attr1, this.operator, this.comparison);
|
1132
|
+
}
|
1133
|
+
catch (e) {
|
1134
|
+
throw new QueryError(e);
|
1135
|
+
}
|
1136
|
+
}
|
1137
|
+
}; }
|
1138
|
+
static get builder() {
|
1139
|
+
return new Condition.Builder();
|
1140
|
+
}
|
1141
|
+
}
|
1142
|
+
__decorate([
|
1143
|
+
decoratorValidation.required(),
|
1144
|
+
__metadata("design:type", Object)
|
1145
|
+
], Condition.prototype, "attr1", void 0);
|
1146
|
+
__decorate([
|
1147
|
+
decoratorValidation.required(),
|
1148
|
+
__metadata("design:type", String)
|
1149
|
+
], Condition.prototype, "operator", void 0);
|
1150
|
+
__decorate([
|
1151
|
+
decoratorValidation.required(),
|
1152
|
+
__metadata("design:type", Object)
|
1153
|
+
], Condition.prototype, "comparison", void 0);
|
1154
|
+
|
1155
|
+
async function createOrUpdate(model, context, repository) {
|
1156
|
+
if (!repository) {
|
1157
|
+
const constructor = decoratorValidation.Model.get(model.constructor.name);
|
1158
|
+
if (!constructor)
|
1159
|
+
throw new dbDecorators.InternalError(`Could not find model ${model.constructor.name}`);
|
1160
|
+
repository = Repository.forModel(constructor);
|
1161
|
+
}
|
1162
|
+
if (typeof model[repository.pk] === "undefined")
|
1163
|
+
return repository.create(model, context);
|
1164
|
+
else {
|
1165
|
+
try {
|
1166
|
+
return repository.update(model, context);
|
1167
|
+
}
|
1168
|
+
catch (e) {
|
1169
|
+
if (!(e instanceof dbDecorators.NotFoundError))
|
1170
|
+
throw e;
|
1171
|
+
return repository.create(model, context);
|
1172
|
+
}
|
1173
|
+
}
|
1174
|
+
}
|
1175
|
+
async function oneToOneOnCreate(context, data, key, model) {
|
1176
|
+
const propertyValue = model[key];
|
1177
|
+
if (!propertyValue)
|
1178
|
+
return;
|
1179
|
+
if (typeof propertyValue !== "object") {
|
1180
|
+
const innerRepo = repositoryFromTypeMetadata(model, key);
|
1181
|
+
const read = await innerRepo.read(propertyValue);
|
1182
|
+
await cacheModelForPopulate(context, model, key, propertyValue, read);
|
1183
|
+
model[key] = propertyValue;
|
1184
|
+
return;
|
1185
|
+
}
|
1186
|
+
const constructor = decoratorValidation.Model.get(data.class);
|
1187
|
+
if (!constructor)
|
1188
|
+
throw new dbDecorators.InternalError(`Could not find model ${data.class}`);
|
1189
|
+
const repo = Repository.forModel(constructor);
|
1190
|
+
const created = await repo.create(propertyValue);
|
1191
|
+
const pk = dbDecorators.findPrimaryKey(created).id;
|
1192
|
+
await cacheModelForPopulate(context, model, key, created[pk], created);
|
1193
|
+
model[key] = created[pk];
|
1194
|
+
}
|
1195
|
+
async function oneToOneOnUpdate(context, data, key, model) {
|
1196
|
+
const propertyValue = model[key];
|
1197
|
+
if (!propertyValue)
|
1198
|
+
return;
|
1199
|
+
if (data.cascade.update !== exports.Cascade.CASCADE)
|
1200
|
+
return;
|
1201
|
+
if (typeof propertyValue !== "object") {
|
1202
|
+
const innerRepo = repositoryFromTypeMetadata(model, key);
|
1203
|
+
const read = await innerRepo.read(propertyValue);
|
1204
|
+
await cacheModelForPopulate(context, model, key, propertyValue, read);
|
1205
|
+
model[key] = propertyValue;
|
1206
|
+
return;
|
1207
|
+
}
|
1208
|
+
const updated = await createOrUpdate(model[key], context);
|
1209
|
+
const pk = dbDecorators.findPrimaryKey(updated).id;
|
1210
|
+
await cacheModelForPopulate(context, model, key, updated[pk], updated);
|
1211
|
+
model[key] = updated[pk];
|
1212
|
+
}
|
1213
|
+
async function oneToOneOnDelete(context, data, key, model) {
|
1214
|
+
const propertyValue = model[key];
|
1215
|
+
if (!propertyValue)
|
1216
|
+
return;
|
1217
|
+
if (data.cascade.update !== exports.Cascade.CASCADE)
|
1218
|
+
return;
|
1219
|
+
const innerRepo = repositoryFromTypeMetadata(model, key);
|
1220
|
+
let deleted;
|
1221
|
+
if (!(propertyValue instanceof decoratorValidation.Model))
|
1222
|
+
deleted = await innerRepo.delete(model[key], context);
|
1223
|
+
else
|
1224
|
+
deleted = await innerRepo.delete(model[key][innerRepo.pk], context);
|
1225
|
+
await cacheModelForPopulate(context, model, key, deleted[innerRepo.pk], deleted);
|
1226
|
+
}
|
1227
|
+
async function oneToManyOnCreate(context, data, key, model) {
|
1228
|
+
const propertyValues = model[key];
|
1229
|
+
if (!propertyValues || !propertyValues.length)
|
1230
|
+
return;
|
1231
|
+
const arrayType = typeof propertyValues[0];
|
1232
|
+
if (!propertyValues.every((item) => typeof item === arrayType))
|
1233
|
+
throw new dbDecorators.InternalError(`Invalid operation. All elements of property ${key} must match the same type.`);
|
1234
|
+
const uniqueValues = new Set([...propertyValues]);
|
1235
|
+
if (arrayType !== "object") {
|
1236
|
+
const repo = repositoryFromTypeMetadata(model, key);
|
1237
|
+
for (const id of uniqueValues) {
|
1238
|
+
const read = await repo.read(id);
|
1239
|
+
await cacheModelForPopulate(context, model, key, id, read);
|
1240
|
+
}
|
1241
|
+
model[key] = [...uniqueValues];
|
1242
|
+
return;
|
1243
|
+
}
|
1244
|
+
const pkName = dbDecorators.findPrimaryKey(propertyValues[0]).id;
|
1245
|
+
const result = new Set();
|
1246
|
+
for (const m of propertyValues) {
|
1247
|
+
const record = await createOrUpdate(m, context);
|
1248
|
+
await cacheModelForPopulate(context, model, key, record[pkName], record);
|
1249
|
+
result.add(record[pkName]);
|
1250
|
+
}
|
1251
|
+
model[key] = [...result];
|
1252
|
+
}
|
1253
|
+
async function oneToManyOnUpdate(context, data, key, model) {
|
1254
|
+
const { cascade } = data;
|
1255
|
+
if (cascade.update !== exports.Cascade.CASCADE)
|
1256
|
+
return;
|
1257
|
+
return oneToManyOnCreate.call(this, context, data, key, model);
|
1258
|
+
}
|
1259
|
+
async function oneToManyOnDelete(context, data, key, model) {
|
1260
|
+
if (data.cascade.delete !== exports.Cascade.CASCADE)
|
1261
|
+
return;
|
1262
|
+
const values = model[key];
|
1263
|
+
if (!values || !values.length)
|
1264
|
+
return;
|
1265
|
+
const arrayType = typeof values[0];
|
1266
|
+
const areAllSameType = values.every((item) => typeof item === arrayType);
|
1267
|
+
if (!areAllSameType)
|
1268
|
+
throw new dbDecorators.InternalError(`Invalid operation. All elements of property ${key} must match the same type.`);
|
1269
|
+
const isInstantiated = arrayType === "object";
|
1270
|
+
const repo = isInstantiated
|
1271
|
+
? Repository.forModel(values[0])
|
1272
|
+
: repositoryFromTypeMetadata(model, key);
|
1273
|
+
const uniqueValues = new Set([
|
1274
|
+
...(isInstantiated
|
1275
|
+
? values.map((v) => v[repo.pk])
|
1276
|
+
: values),
|
1277
|
+
]);
|
1278
|
+
for (const id of uniqueValues.values()) {
|
1279
|
+
const deleted = await repo.delete(id, context);
|
1280
|
+
await cacheModelForPopulate(context, model, key, id, deleted);
|
1281
|
+
}
|
1282
|
+
model[key] = [...uniqueValues];
|
1283
|
+
}
|
1284
|
+
function getPopulateKey(tableName, fieldName, id) {
|
1285
|
+
return [exports.PersistenceKeys.POPULATE, tableName, fieldName, id].join(".");
|
1286
|
+
}
|
1287
|
+
async function cacheModelForPopulate(context, parentModel, propertyKey, pkValue, cacheValue) {
|
1288
|
+
const cacheKey = getPopulateKey(parentModel.constructor.name, propertyKey, pkValue);
|
1289
|
+
return context.put(cacheKey, cacheValue);
|
1290
|
+
}
|
1291
|
+
async function populate(context, data, key, model) {
|
1292
|
+
if (!data.populate)
|
1293
|
+
return;
|
1294
|
+
const nested = model[key];
|
1295
|
+
const isArr = Array.isArray(nested);
|
1296
|
+
if (typeof nested === "undefined" || (isArr && nested.length === 0))
|
1297
|
+
return;
|
1298
|
+
async function fetchPopulateValues(c, model, propName, propKeyValues) {
|
1299
|
+
let cacheKey;
|
1300
|
+
let val;
|
1301
|
+
const results = [];
|
1302
|
+
for (const proKeyValue of propKeyValues) {
|
1303
|
+
cacheKey = getPopulateKey(model.constructor.name, propName, proKeyValue);
|
1304
|
+
try {
|
1305
|
+
val = await c.get(cacheKey);
|
1306
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
1307
|
+
}
|
1308
|
+
catch (e) {
|
1309
|
+
const repo = repositoryFromTypeMetadata(model, propName);
|
1310
|
+
if (!repo)
|
1311
|
+
throw new dbDecorators.InternalError("Could not find repo");
|
1312
|
+
val = await repo.read(proKeyValue);
|
1313
|
+
}
|
1314
|
+
results.push(val);
|
1315
|
+
}
|
1316
|
+
return results;
|
1317
|
+
}
|
1318
|
+
const res = await fetchPopulateValues(context, model, key, isArr ? nested : [nested]);
|
1319
|
+
model[key] = isArr ? res : res[0];
|
1320
|
+
}
|
1321
|
+
const commomTypes = [
|
1322
|
+
"array",
|
1323
|
+
"string",
|
1324
|
+
"number",
|
1325
|
+
"boolean",
|
1326
|
+
"symbol",
|
1327
|
+
"function",
|
1328
|
+
"object",
|
1329
|
+
"undefined",
|
1330
|
+
"null",
|
1331
|
+
"bigint",
|
1332
|
+
];
|
1333
|
+
function repositoryFromTypeMetadata(model, propertyKey) {
|
1334
|
+
const types = Reflect.getMetadata(decoratorValidation.Validation.key(Array.isArray(model[propertyKey])
|
1335
|
+
? decoratorValidation.ValidationKeys.LIST
|
1336
|
+
: decoratorValidation.ValidationKeys.TYPE), model, propertyKey);
|
1337
|
+
const customTypes = Array.isArray(model[propertyKey])
|
1338
|
+
? types.clazz
|
1339
|
+
: types.customTypes;
|
1340
|
+
if (!types || !customTypes)
|
1341
|
+
throw new dbDecorators.InternalError(`Failed to find types decorators for property ${propertyKey}`);
|
1342
|
+
const allowedTypes = Array.isArray(customTypes)
|
1343
|
+
? [...customTypes]
|
1344
|
+
: [customTypes];
|
1345
|
+
const constructorName = allowedTypes.find((t) => !commomTypes.includes(`${t}`.toLowerCase()));
|
1346
|
+
if (!constructorName)
|
1347
|
+
throw new dbDecorators.InternalError(`Property key ${propertyKey} does not have a valid constructor type`);
|
1348
|
+
const constructor = decoratorValidation.Model.get(constructorName);
|
1349
|
+
if (!constructor)
|
1350
|
+
throw new dbDecorators.InternalError(`No registered model found for ${constructorName}`);
|
1351
|
+
return Repository.forModel(constructor);
|
1352
|
+
}
|
1353
|
+
|
1354
|
+
function table(tableName) {
|
1355
|
+
return reflection.metadata(Adapter.key(exports.PersistenceKeys.TABLE), tableName);
|
1356
|
+
}
|
1357
|
+
function column(columnName) {
|
1358
|
+
return decoratorValidation.propMetadata(Adapter.key(exports.PersistenceKeys.COLUMN), columnName);
|
1359
|
+
}
|
1360
|
+
/**
|
1361
|
+
* @summary Index Decorator
|
1362
|
+
* @description properties decorated will the index in the
|
1363
|
+
* DB for performance in queries
|
1364
|
+
*
|
1365
|
+
* @param {OrderDirection[]} [directions]
|
1366
|
+
* @param {string[]} [compositions]
|
1367
|
+
*
|
1368
|
+
* @function index
|
1369
|
+
*/
|
1370
|
+
function index(directions, compositions) {
|
1371
|
+
return decoratorValidation.propMetadata(Repository.key(`${exports.PersistenceKeys.INDEX}${compositions && compositions.length ? `.${compositions.join(".")}` : ""}`), {
|
1372
|
+
directions: directions,
|
1373
|
+
compositions: compositions,
|
1374
|
+
});
|
1375
|
+
}
|
1376
|
+
async function uniqueOnCreateUpdate(context, data, key, model) {
|
1377
|
+
if (!model[key])
|
1378
|
+
return;
|
1379
|
+
const existing = await this.select()
|
1380
|
+
.where(Condition.attribute(key).eq(model[key]))
|
1381
|
+
.execute();
|
1382
|
+
if (existing.length)
|
1383
|
+
throw new dbDecorators.ConflictError(`model already exists with property ${key} equal to ${JSON.stringify(model[key], undefined, 2)}`);
|
1384
|
+
}
|
1385
|
+
/**
|
1386
|
+
* @summary Unique Decorator
|
1387
|
+
* @description Tags a property as unique.
|
1388
|
+
* No other elements in that table can have the same property value
|
1389
|
+
*
|
1390
|
+
* @function unique
|
1391
|
+
*
|
1392
|
+
* @memberOf module:wallet-db.Decorators
|
1393
|
+
*/
|
1394
|
+
function unique() {
|
1395
|
+
return reflection.apply(dbDecorators.onCreateUpdate(uniqueOnCreateUpdate), decoratorValidation.propMetadata(Repository.key(exports.PersistenceKeys.UNIQUE), {}));
|
1396
|
+
}
|
1397
|
+
async function createdByOnCreateUpdate(context, data, key, model) {
|
1398
|
+
const user = context.user;
|
1399
|
+
if (!user)
|
1400
|
+
throw new UnsupportedError("This adapter does not support user identification");
|
1401
|
+
model[key] = user.id;
|
1402
|
+
}
|
1403
|
+
function createdBy() {
|
1404
|
+
return reflection.apply(dbDecorators.onCreate(createdByOnCreateUpdate), decoratorValidation.propMetadata(Repository.key(exports.PersistenceKeys.CREATED_BY), {}));
|
1405
|
+
}
|
1406
|
+
function updatedBy() {
|
1407
|
+
return reflection.apply(dbDecorators.onCreateUpdate(createdByOnCreateUpdate), decoratorValidation.propMetadata(Repository.key(exports.PersistenceKeys.CREATED_BY), {}));
|
1408
|
+
}
|
1409
|
+
/**
|
1410
|
+
* @summary One To One relation Decorators
|
1411
|
+
*
|
1412
|
+
* @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence}
|
1413
|
+
* @param {CascadeMetadata} [cascadeOptions]
|
1414
|
+
* @param {boolean} populate If true, replaces the specified key in the document with the corresponding record from the database
|
1415
|
+
*
|
1416
|
+
* @function onToOne
|
1417
|
+
*
|
1418
|
+
* @memberOf module:wallet-db.Decorators
|
1419
|
+
*
|
1420
|
+
* @see oneToMany
|
1421
|
+
* @see manyToOne
|
1422
|
+
*/
|
1423
|
+
function oneToOne(clazz, cascadeOptions = DefaultCascade, populate$1 = true) {
|
1424
|
+
decoratorValidation.Model.register(clazz);
|
1425
|
+
const metadata = {
|
1426
|
+
class: clazz.name,
|
1427
|
+
cascade: cascadeOptions,
|
1428
|
+
populate: populate$1,
|
1429
|
+
};
|
1430
|
+
return reflection.apply(decoratorValidation.prop(exports.PersistenceKeys.RELATIONS), decoratorValidation.type([clazz.name, String.name, Number.name, BigInt.name]), dbDecorators.onCreate(oneToOneOnCreate, metadata), dbDecorators.onUpdate(oneToOneOnUpdate, metadata), dbDecorators.onDelete(oneToOneOnDelete, metadata), dbDecorators.afterAny(populate, metadata), decoratorValidation.propMetadata(Repository.key(exports.PersistenceKeys.ONE_TO_ONE), metadata));
|
1431
|
+
}
|
1432
|
+
/**
|
1433
|
+
* @summary One To Many relation Decorators
|
1434
|
+
*
|
1435
|
+
* @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence}
|
1436
|
+
* @param {CascadeMetadata} [cascadeOptions]
|
1437
|
+
*
|
1438
|
+
* @function oneToMany
|
1439
|
+
*
|
1440
|
+
* @memberOf module:wallet-db.Decorators
|
1441
|
+
*
|
1442
|
+
* @see oneToOne
|
1443
|
+
* @see manyToOne
|
1444
|
+
*/
|
1445
|
+
function oneToMany(clazz, cascadeOptions = DefaultCascade, populate$1 = true) {
|
1446
|
+
decoratorValidation.Model.register(clazz);
|
1447
|
+
const metadata = {
|
1448
|
+
class: clazz.name,
|
1449
|
+
cascade: cascadeOptions,
|
1450
|
+
populate: populate$1,
|
1451
|
+
};
|
1452
|
+
return reflection.apply(decoratorValidation.prop(exports.PersistenceKeys.RELATIONS),
|
1453
|
+
// @ts-expect-error purposeful override
|
1454
|
+
decoratorValidation.list([clazz, String, Number, BigInt]), dbDecorators.onCreate(oneToManyOnCreate, metadata), dbDecorators.onUpdate(oneToManyOnUpdate, metadata), dbDecorators.onDelete(oneToManyOnDelete, metadata), dbDecorators.afterAny(populate, metadata), decoratorValidation.propMetadata(Repository.key(exports.PersistenceKeys.ONE_TO_MANY), metadata));
|
1455
|
+
}
|
1456
|
+
/**
|
1457
|
+
* @summary Many To One relation Decorators
|
1458
|
+
*
|
1459
|
+
* @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence}
|
1460
|
+
* @param {CascadeMetadata} [cascadeOptions]
|
1461
|
+
*
|
1462
|
+
* @function manyToOne
|
1463
|
+
*
|
1464
|
+
* @memberOf module:wallet-db.Decorators
|
1465
|
+
*
|
1466
|
+
* @see oneToMany
|
1467
|
+
* @see oneToOne
|
1468
|
+
*/
|
1469
|
+
function manyToOne(clazz, cascadeOptions = DefaultCascade, populate = true) {
|
1470
|
+
decoratorValidation.Model.register(clazz);
|
1471
|
+
const metadata = {
|
1472
|
+
class: clazz.name,
|
1473
|
+
cascade: cascadeOptions,
|
1474
|
+
populate: populate,
|
1475
|
+
};
|
1476
|
+
return reflection.apply(decoratorValidation.prop(exports.PersistenceKeys.RELATIONS), decoratorValidation.type([clazz.name, String.name, Number.name, BigInt.name]),
|
1477
|
+
// onCreate(oneToManyOnCreate, metadata),
|
1478
|
+
// onUpdate(oneToManyOnUpdate, metadata),
|
1479
|
+
// onDelete(oneToManyOnDelete, metadata),
|
1480
|
+
// afterAll(populate, metadata),
|
1481
|
+
decoratorValidation.propMetadata(Repository.key(exports.PersistenceKeys.MANY_TO_ONE), metadata));
|
1482
|
+
}
|
1483
|
+
|
1484
|
+
/**
|
1485
|
+
* @summary Primary Key Decorator
|
1486
|
+
* @description Marks the property as the {@link Model}s primary key.
|
1487
|
+
* Also marks the property as {@link unique} as {@required} and ensures the index is created properly according to the provided {@link Sequence}
|
1488
|
+
*
|
1489
|
+
*
|
1490
|
+
*
|
1491
|
+
* @function pk
|
1492
|
+
*
|
1493
|
+
* @memberOf module:wallet-db.Decorators
|
1494
|
+
*
|
1495
|
+
* @see unique
|
1496
|
+
* @see required
|
1497
|
+
* @see on
|
1498
|
+
* @param data
|
1499
|
+
* @param key
|
1500
|
+
* @param model
|
1501
|
+
*/
|
1502
|
+
async function pkOnCreate(context, data, key, model) {
|
1503
|
+
if (!data.type || model[key]) {
|
1504
|
+
return;
|
1505
|
+
}
|
1506
|
+
const setPrimaryKeyValue = function (target, propertyKey, value) {
|
1507
|
+
Object.defineProperty(target, propertyKey, {
|
1508
|
+
enumerable: true,
|
1509
|
+
writable: false,
|
1510
|
+
configurable: true,
|
1511
|
+
value: value,
|
1512
|
+
});
|
1513
|
+
};
|
1514
|
+
if (!data.name)
|
1515
|
+
data.name = sequenceNameForModel(model, "pk");
|
1516
|
+
let sequence;
|
1517
|
+
try {
|
1518
|
+
sequence = await this.adapter.Sequence(data);
|
1519
|
+
}
|
1520
|
+
catch (e) {
|
1521
|
+
throw new dbDecorators.InternalError(`Failed to instantiate Sequence ${data.name}: ${e}`);
|
1522
|
+
}
|
1523
|
+
const next = await sequence.next();
|
1524
|
+
setPrimaryKeyValue(model, key, next);
|
1525
|
+
}
|
1526
|
+
function pk(opts = DefaultSequenceOptions) {
|
1527
|
+
opts = Object.assign({}, DefaultSequenceOptions, opts);
|
1528
|
+
return reflection.apply(index([exports.OrderDirection.ASC, exports.OrderDirection.DSC]), decoratorValidation.required(), dbDecorators.readonly(),
|
1529
|
+
// type([String.name, Number.name, BigInt.name]),
|
1530
|
+
decoratorValidation.propMetadata(Repository.key(dbDecorators.DBKeys.ID), opts), dbDecorators.onCreate(pkOnCreate, opts));
|
1531
|
+
}
|
1532
|
+
|
1533
|
+
class BaseModel extends decoratorValidation.Model {
|
1534
|
+
constructor(arg) {
|
1535
|
+
super(arg);
|
1536
|
+
}
|
1537
|
+
}
|
1538
|
+
__decorate([
|
1539
|
+
dbDecorators.timestamp(dbDecorators.DBOperations.CREATE),
|
1540
|
+
__metadata("design:type", Date)
|
1541
|
+
], BaseModel.prototype, "createdOn", void 0);
|
1542
|
+
__decorate([
|
1543
|
+
dbDecorators.timestamp(),
|
1544
|
+
__metadata("design:type", Date)
|
1545
|
+
], BaseModel.prototype, "updatedOn", void 0);
|
1546
|
+
|
1547
|
+
exports.User = class User extends decoratorValidation.Model {
|
1548
|
+
constructor(arg) {
|
1549
|
+
super(arg);
|
1550
|
+
}
|
1551
|
+
};
|
1552
|
+
__decorate([
|
1553
|
+
pk(),
|
1554
|
+
__metadata("design:type", String)
|
1555
|
+
], exports.User.prototype, "id", void 0);
|
1556
|
+
__decorate([
|
1557
|
+
decoratorValidation.list([String]),
|
1558
|
+
__metadata("design:type", Array)
|
1559
|
+
], exports.User.prototype, "roles", void 0);
|
1560
|
+
__decorate([
|
1561
|
+
decoratorValidation.list([String]),
|
1562
|
+
__metadata("design:type", Array)
|
1563
|
+
], exports.User.prototype, "affiliations", void 0);
|
1564
|
+
exports.User = __decorate([
|
1565
|
+
decoratorValidation.model(),
|
1566
|
+
__metadata("design:paramtypes", [Object])
|
1567
|
+
], exports.User);
|
1568
|
+
|
1569
|
+
Object.defineProperty(decoratorValidation.DEFAULT_ERROR_MESSAGES, exports.PersistenceKeys.CLAUSE_SEQUENCE, {
|
1570
|
+
value: "Invalid clause sequence: {0}",
|
1571
|
+
});
|
1572
|
+
Object.defineProperty(decoratorValidation.ValidationKeys, "CLAUSE_SEQUENCE", {
|
1573
|
+
value: exports.PersistenceKeys.CLAUSE_SEQUENCE,
|
1574
|
+
});
|
1575
|
+
/**
|
1576
|
+
*
|
1577
|
+
* @param {string} [message]
|
1578
|
+
*
|
1579
|
+
* @function clauseSequence
|
1580
|
+
*
|
1581
|
+
* @category Decorators
|
1582
|
+
* @subcategory Validation
|
1583
|
+
*/
|
1584
|
+
function clauseSequence(message) {
|
1585
|
+
return decoratorValidation.propMetadata(decoratorValidation.Validation.key(decoratorValidation.ValidationKeys.REQUIRED), {
|
1586
|
+
message: message ||
|
1587
|
+
decoratorValidation.DEFAULT_ERROR_MESSAGES[exports.PersistenceKeys.CLAUSE_SEQUENCE],
|
1588
|
+
});
|
1589
|
+
}
|
1590
|
+
|
1591
|
+
/**
|
1592
|
+
* @summary Validates a {@link Sequence}'s {@link Clause}s
|
1593
|
+
*
|
1594
|
+
* @param {string} [message]
|
1595
|
+
*
|
1596
|
+
* @class ClauseSequenceValidator
|
1597
|
+
* @extends Validator
|
1598
|
+
*
|
1599
|
+
* @category Validation
|
1600
|
+
* @subcategory Validators
|
1601
|
+
*/
|
1602
|
+
exports.ClauseSequenceValidator = class ClauseSequenceValidator extends decoratorValidation.Validator {
|
1603
|
+
constructor(message = decoratorValidation.DEFAULT_ERROR_MESSAGES[exports.PersistenceKeys.CLAUSE_SEQUENCE]) {
|
1604
|
+
super(message);
|
1605
|
+
}
|
1606
|
+
validateSequence(clauses, message) {
|
1607
|
+
return MandatoryPriorities.every((p) => !!clauses.find((c) => c.getPriority() === p))
|
1608
|
+
? undefined
|
1609
|
+
: this.getMessage(decoratorValidation.sf(message || this.message, "Missing required Clause Priorities"));
|
1610
|
+
}
|
1611
|
+
/**
|
1612
|
+
* @summary Verifies the model for errors
|
1613
|
+
* @param {string} value
|
1614
|
+
* @param {ValidatorOptions} [options]
|
1615
|
+
*
|
1616
|
+
* @return Errors
|
1617
|
+
*
|
1618
|
+
* @override
|
1619
|
+
*
|
1620
|
+
* @see Validator
|
1621
|
+
*/
|
1622
|
+
hasErrors(value, options) {
|
1623
|
+
try {
|
1624
|
+
if (!value ||
|
1625
|
+
!Array.isArray(value) ||
|
1626
|
+
!value.length ||
|
1627
|
+
!value.every((e) => e instanceof Clause))
|
1628
|
+
return this.getMessage(decoratorValidation.sf((options || {}).message || this.message, "No or invalid Clauses found"));
|
1629
|
+
const clauses = value;
|
1630
|
+
const clauseErrors = clauses.reduce((accum, c) => {
|
1631
|
+
const errs = c.hasErrors();
|
1632
|
+
if (errs)
|
1633
|
+
if (accum)
|
1634
|
+
accum += decoratorValidation.sf("\nClause {0}: {1}", c.constructor.name, errs.toString());
|
1635
|
+
else
|
1636
|
+
accum = decoratorValidation.sf("Clause {0}: {1}", c.constructor.name, errs.toString());
|
1637
|
+
return accum;
|
1638
|
+
}, undefined);
|
1639
|
+
if (clauseErrors)
|
1640
|
+
return this.getMessage(decoratorValidation.sf((options || {}).message || this.message, clauseErrors.toString()));
|
1641
|
+
const verifyPriority = () => {
|
1642
|
+
const priorities = clauses.map((c) => c.getPriority());
|
1643
|
+
const allUnique = new Set(priorities).size === priorities.length;
|
1644
|
+
if (!allUnique)
|
1645
|
+
return "Not all clauses have unique priorities";
|
1646
|
+
const sorted = priorities.sort((a, b) => {
|
1647
|
+
return b - a;
|
1648
|
+
});
|
1649
|
+
return reflection.isEqual(priorities, sorted)
|
1650
|
+
? true
|
1651
|
+
: "Clauses are not properly sorted";
|
1652
|
+
};
|
1653
|
+
const priorityCheck = verifyPriority();
|
1654
|
+
if (priorityCheck !== true)
|
1655
|
+
return this.getMessage(decoratorValidation.sf((options || {}).message || this.message, "Invalid prioritization"));
|
1656
|
+
const sequenceCheck = this.validateSequence(clauses, (options || {}).message);
|
1657
|
+
if (sequenceCheck)
|
1658
|
+
return this.getMessage(decoratorValidation.sf((options || {}).message || this.message, "Invalid sequence"));
|
1659
|
+
}
|
1660
|
+
catch (e) {
|
1661
|
+
throw new QueryError(decoratorValidation.sf("Failed to verify clause sequence {0}: {1}", value, e));
|
1662
|
+
}
|
1663
|
+
}
|
1664
|
+
};
|
1665
|
+
exports.ClauseSequenceValidator = __decorate([
|
1666
|
+
decoratorValidation.validator(exports.PersistenceKeys.CLAUSE_SEQUENCE),
|
1667
|
+
__metadata("design:paramtypes", [String])
|
1668
|
+
], exports.ClauseSequenceValidator);
|
1669
|
+
|
1670
|
+
/**
|
1671
|
+
* @summary Statement Class
|
1672
|
+
* @description holds all the clauses until they can be processed
|
1673
|
+
*
|
1674
|
+
* @param {ModelArg} [statement]
|
1675
|
+
*
|
1676
|
+
* @class Statement
|
1677
|
+
* @extends Model
|
1678
|
+
* @implements Executor
|
1679
|
+
* @implements RawExecutor
|
1680
|
+
*
|
1681
|
+
* @category Query
|
1682
|
+
*/
|
1683
|
+
class Statement extends decoratorValidation.Model {
|
1684
|
+
constructor(db) {
|
1685
|
+
super();
|
1686
|
+
this.clauses = undefined;
|
1687
|
+
this.target = undefined;
|
1688
|
+
this.fullRecord = false;
|
1689
|
+
this.type = undefined;
|
1690
|
+
this.adapter = db;
|
1691
|
+
}
|
1692
|
+
build() {
|
1693
|
+
if (!this.clauses)
|
1694
|
+
throw new QueryError(decoratorValidation.sf("Failed to build Statement:\n{0}", "No Clauses"));
|
1695
|
+
this.clauses.sort((c1, c2) => {
|
1696
|
+
return c1.getPriority() - c2.getPriority();
|
1697
|
+
});
|
1698
|
+
const errors = this.hasErrors();
|
1699
|
+
if (errors)
|
1700
|
+
throw new QueryError(decoratorValidation.sf("Poorly built statement: {0}", errors.toString()));
|
1701
|
+
let query;
|
1702
|
+
try {
|
1703
|
+
const iterator = function (clauses, previous = {}) {
|
1704
|
+
const c = clauses.shift();
|
1705
|
+
if (!c)
|
1706
|
+
return previous;
|
1707
|
+
const results = c.build(previous);
|
1708
|
+
return iterator(clauses, results);
|
1709
|
+
};
|
1710
|
+
query = iterator(new Array(...this.clauses));
|
1711
|
+
}
|
1712
|
+
catch (e) {
|
1713
|
+
throw new QueryError(e);
|
1714
|
+
}
|
1715
|
+
return query;
|
1716
|
+
}
|
1717
|
+
/**
|
1718
|
+
* @inheritDoc
|
1719
|
+
*/
|
1720
|
+
async execute() {
|
1721
|
+
try {
|
1722
|
+
const query = this.build();
|
1723
|
+
return this.raw(query);
|
1724
|
+
}
|
1725
|
+
catch (e) {
|
1726
|
+
throw new dbDecorators.InternalError(e);
|
1727
|
+
}
|
1728
|
+
}
|
1729
|
+
async raw(rawInput, ...args) {
|
1730
|
+
const results = await this.adapter.raw(rawInput, true, ...args);
|
1731
|
+
if (!this.fullRecord)
|
1732
|
+
return results;
|
1733
|
+
if (!this.target)
|
1734
|
+
throw new dbDecorators.InternalError("No target defined in statement. should never happen");
|
1735
|
+
const pkAttr = dbDecorators.findPrimaryKey(new this.target()).id;
|
1736
|
+
const processor = function recordProcessor(r) {
|
1737
|
+
const id = r[pkAttr];
|
1738
|
+
return this.adapter.revert(r, this.target, pkAttr, id);
|
1739
|
+
}.bind(this);
|
1740
|
+
if (Array.isArray(results))
|
1741
|
+
return results.map(processor);
|
1742
|
+
return processor(results);
|
1743
|
+
}
|
1744
|
+
/**
|
1745
|
+
* @inheritDoc
|
1746
|
+
*/
|
1747
|
+
hasErrors(...exceptions) {
|
1748
|
+
const errors = super.hasErrors(...exceptions);
|
1749
|
+
if (errors)
|
1750
|
+
return errors;
|
1751
|
+
for (const i in this.clauses) {
|
1752
|
+
const err = this.clauses[i].hasErrors();
|
1753
|
+
if (err)
|
1754
|
+
return err;
|
1755
|
+
}
|
1756
|
+
}
|
1757
|
+
/**
|
1758
|
+
* @summary Adds a clause to the Statement
|
1759
|
+
* @param {Clause} clause
|
1760
|
+
*/
|
1761
|
+
addClause(clause) {
|
1762
|
+
if (!this.clauses)
|
1763
|
+
this.clauses = [];
|
1764
|
+
const priority = clause.getPriority();
|
1765
|
+
const currentPriority = this.clauses
|
1766
|
+
.map((c, i) => ({ index: i, clause: c }))
|
1767
|
+
.find((c) => c.clause.getPriority() === priority);
|
1768
|
+
if (currentPriority) {
|
1769
|
+
this.clauses[currentPriority.index] = clause;
|
1770
|
+
}
|
1771
|
+
this.clauses.push(clause);
|
1772
|
+
}
|
1773
|
+
getAdapter() {
|
1774
|
+
return this.adapter;
|
1775
|
+
}
|
1776
|
+
/**
|
1777
|
+
* @summary Defines the output class (when existing)
|
1778
|
+
* @param {Constructor} clazz
|
1779
|
+
*/
|
1780
|
+
setTarget(clazz) {
|
1781
|
+
if (this.target)
|
1782
|
+
throw new QueryError(decoratorValidation.sf("Output class already defined to {0}", this.target.name));
|
1783
|
+
this.target = clazz;
|
1784
|
+
}
|
1785
|
+
getTarget() {
|
1786
|
+
if (!this.target)
|
1787
|
+
throw new dbDecorators.InternalError("No target defined for statement");
|
1788
|
+
return this.target;
|
1789
|
+
}
|
1790
|
+
setFullRecord() {
|
1791
|
+
this.fullRecord = true;
|
1792
|
+
}
|
1793
|
+
setMode(type) {
|
1794
|
+
this.type = type;
|
1795
|
+
}
|
1796
|
+
}
|
1797
|
+
__decorate([
|
1798
|
+
decoratorValidation.required(),
|
1799
|
+
decoratorValidation.minlength(MandatoryPriorities.length),
|
1800
|
+
clauseSequence(),
|
1801
|
+
__metadata("design:type", Array)
|
1802
|
+
], Statement.prototype, "clauses", void 0);
|
1803
|
+
__decorate([
|
1804
|
+
decoratorValidation.required(),
|
1805
|
+
decoratorValidation.type(["object"]),
|
1806
|
+
__metadata("design:type", Adapter)
|
1807
|
+
], Statement.prototype, "adapter", void 0);
|
1808
|
+
__decorate([
|
1809
|
+
decoratorValidation.required(),
|
1810
|
+
__metadata("design:type", Object)
|
1811
|
+
], Statement.prototype, "target", void 0);
|
1812
|
+
__decorate([
|
1813
|
+
decoratorValidation.required(),
|
1814
|
+
__metadata("design:type", String)
|
1815
|
+
], Statement.prototype, "type", void 0);
|
1816
|
+
|
1817
|
+
/**
|
1818
|
+
*/
|
1819
|
+
/**
|
1820
|
+
* @summary Clause Class
|
1821
|
+
* @description Represents a Clause in a {@link Statement}
|
1822
|
+
*
|
1823
|
+
* @typedef Q Represents que query object the persistence adapter uses
|
1824
|
+
*
|
1825
|
+
* @param {ModelArg<Clause<Q>>} [clause]
|
1826
|
+
*
|
1827
|
+
* @class Clause
|
1828
|
+
* @extends Model
|
1829
|
+
* @implements Executor
|
1830
|
+
* @implements QueryBuilder
|
1831
|
+
* @abstract
|
1832
|
+
*
|
1833
|
+
* @category Query
|
1834
|
+
* @subcategory Clauses
|
1835
|
+
*/
|
1836
|
+
class Clause extends decoratorValidation.Model {
|
1837
|
+
constructor(clause) {
|
1838
|
+
super();
|
1839
|
+
this.priority = clause?.priority;
|
1840
|
+
this.statement = clause?.statement;
|
1841
|
+
if (!this.statement || !this.priority)
|
1842
|
+
throw new QueryError("Missing statement or priority. Should be impossible");
|
1843
|
+
this.statement.addClause(this);
|
1844
|
+
}
|
1845
|
+
get adapter() {
|
1846
|
+
return this.statement.getAdapter();
|
1847
|
+
}
|
1848
|
+
get Clauses() {
|
1849
|
+
return this.statement.getAdapter().Clauses;
|
1850
|
+
}
|
1851
|
+
/**
|
1852
|
+
* @summary return the priority of the clause
|
1853
|
+
* @see Priority
|
1854
|
+
*/
|
1855
|
+
getPriority() {
|
1856
|
+
return this.priority;
|
1857
|
+
}
|
1858
|
+
/**
|
1859
|
+
* @inheritDoc
|
1860
|
+
* @abstract
|
1861
|
+
*/
|
1862
|
+
async execute() {
|
1863
|
+
return this.statement.execute();
|
1864
|
+
}
|
1865
|
+
/**
|
1866
|
+
* @inheritDoc
|
1867
|
+
* @abstract
|
1868
|
+
*/
|
1869
|
+
async paginate(size) {
|
1870
|
+
return this.statement.paginate(size);
|
1871
|
+
}
|
1872
|
+
toString() {
|
1873
|
+
return this.constructor.name;
|
1874
|
+
}
|
1875
|
+
}
|
1876
|
+
__decorate([
|
1877
|
+
decoratorValidation.required(),
|
1878
|
+
__metadata("design:type", Number)
|
1879
|
+
], Clause.prototype, "priority", void 0);
|
1880
|
+
__decorate([
|
1881
|
+
decoratorValidation.required(),
|
1882
|
+
decoratorValidation.type("object"),
|
1883
|
+
__metadata("design:type", Statement)
|
1884
|
+
], Clause.prototype, "statement", void 0);
|
1885
|
+
|
1886
|
+
/**
|
1887
|
+
* @summary The base Selector based clause
|
1888
|
+
*
|
1889
|
+
* @param {ClauseArg} [clause]
|
1890
|
+
*
|
1891
|
+
* @class SelectorBasedClause
|
1892
|
+
* @extends Clause
|
1893
|
+
* @abstract
|
1894
|
+
*
|
1895
|
+
* @category Query
|
1896
|
+
* @subcategory Clauses
|
1897
|
+
*/
|
1898
|
+
class SelectorBasedClause extends Clause {
|
1899
|
+
constructor(clause) {
|
1900
|
+
super(clause);
|
1901
|
+
/**
|
1902
|
+
* @summary Stores the selector
|
1903
|
+
*
|
1904
|
+
* @prop selector
|
1905
|
+
* @protected
|
1906
|
+
*/
|
1907
|
+
this.selector = undefined;
|
1908
|
+
this.selector = clause.selector;
|
1909
|
+
}
|
1910
|
+
toString() {
|
1911
|
+
return this.constructor.name + `[${this.selector}]`;
|
1912
|
+
}
|
1913
|
+
}
|
1914
|
+
__decorate([
|
1915
|
+
decoratorValidation.required(),
|
1916
|
+
__metadata("design:type", Object)
|
1917
|
+
], SelectorBasedClause.prototype, "selector", void 0);
|
1918
|
+
|
1919
|
+
/**
|
1920
|
+
* @summary The FROM clause
|
1921
|
+
*
|
1922
|
+
* @param {ModelArg} [clause]
|
1923
|
+
*
|
1924
|
+
* @class FromClause
|
1925
|
+
* @extends SelectorBasedClause
|
1926
|
+
* @implements WhereOption
|
1927
|
+
*
|
1928
|
+
* @category Query
|
1929
|
+
* @subcategory Clauses
|
1930
|
+
*/
|
1931
|
+
class FromClause extends SelectorBasedClause {
|
1932
|
+
constructor(clause) {
|
1933
|
+
super(Object.assign({}, clause, { priority: exports.Priority.FROM }));
|
1934
|
+
this.selector =
|
1935
|
+
typeof this.selector === "string"
|
1936
|
+
? decoratorValidation.Model.get(this.selector)
|
1937
|
+
: this.selector;
|
1938
|
+
if (!this.selector)
|
1939
|
+
throw new QueryError(decoratorValidation.stringFormat("Could not find selector model: {0}"));
|
1940
|
+
this.statement.setTarget(this.selector);
|
1941
|
+
}
|
1942
|
+
/**
|
1943
|
+
* @inheritDoc
|
1944
|
+
*/
|
1945
|
+
where(condition) {
|
1946
|
+
return this.Clauses.where(this.statement, condition);
|
1947
|
+
}
|
1948
|
+
/**
|
1949
|
+
* @inheritDoc
|
1950
|
+
*/
|
1951
|
+
orderBy(...selector) {
|
1952
|
+
return this.Clauses.orderBy(this.statement, selector);
|
1953
|
+
}
|
1954
|
+
/**
|
1955
|
+
* @inheritDoc
|
1956
|
+
*/
|
1957
|
+
groupBy(selector) {
|
1958
|
+
return this.Clauses.groupBy(this.statement, selector);
|
1959
|
+
}
|
1960
|
+
/**
|
1961
|
+
* @inheritDoc
|
1962
|
+
*/
|
1963
|
+
limit(selector) {
|
1964
|
+
return this.Clauses.limit(this.statement, selector);
|
1965
|
+
}
|
1966
|
+
/**
|
1967
|
+
* @inheritDoc
|
1968
|
+
*/
|
1969
|
+
offset(selector) {
|
1970
|
+
return this.Clauses.offset(this.statement, selector);
|
1971
|
+
}
|
1972
|
+
}
|
1973
|
+
|
1974
|
+
/**
|
1975
|
+
* @summary The GROUP BY clause
|
1976
|
+
*
|
1977
|
+
* @param {ClauseArg} [clause]
|
1978
|
+
*
|
1979
|
+
* @class GroupByClause
|
1980
|
+
* @extends SelectorBasedClause
|
1981
|
+
*
|
1982
|
+
* @category Query
|
1983
|
+
* @subcategory Clauses
|
1984
|
+
*/
|
1985
|
+
class GroupByClause extends SelectorBasedClause {
|
1986
|
+
constructor(clause) {
|
1987
|
+
super(Object.assign({}, clause, { priority: exports.Priority.GROUP_BY }));
|
1988
|
+
}
|
1989
|
+
}
|
1990
|
+
|
1991
|
+
/**
|
1992
|
+
* @summary The INSERT/INTO clause
|
1993
|
+
*
|
1994
|
+
* @param {ClauseArg} [clause]
|
1995
|
+
*
|
1996
|
+
* @class FromClause
|
1997
|
+
* @extends Clause
|
1998
|
+
* @implements IntoOption
|
1999
|
+
*
|
2000
|
+
* @category Query
|
2001
|
+
* @subcategory Clauses
|
2002
|
+
*/
|
2003
|
+
class InsertClause extends Clause {
|
2004
|
+
constructor(clause) {
|
2005
|
+
super(Object.assign({}, clause, { priority: exports.Priority.SELECT }));
|
2006
|
+
this.table = undefined;
|
2007
|
+
}
|
2008
|
+
/**
|
2009
|
+
* @inheritDoc
|
2010
|
+
*/
|
2011
|
+
into(table) {
|
2012
|
+
this.table = table.name; // TODO get mapped name
|
2013
|
+
this.statement.setTarget(table);
|
2014
|
+
return this;
|
2015
|
+
}
|
2016
|
+
/**
|
2017
|
+
* @inheritDoc
|
2018
|
+
*/
|
2019
|
+
values(...models) {
|
2020
|
+
return this.Clauses.values(this.statement, models);
|
2021
|
+
}
|
2022
|
+
/**
|
2023
|
+
* @inheritDoc
|
2024
|
+
*/
|
2025
|
+
where(condition) {
|
2026
|
+
return this.Clauses.where(this.statement, condition);
|
2027
|
+
}
|
2028
|
+
}
|
2029
|
+
__decorate([
|
2030
|
+
decoratorValidation.required(),
|
2031
|
+
__metadata("design:type", String)
|
2032
|
+
], InsertClause.prototype, "table", void 0);
|
2033
|
+
|
2034
|
+
/**
|
2035
|
+
* @summary Limit Clause
|
2036
|
+
* @description Limits the results
|
2037
|
+
*
|
2038
|
+
* @param {ClauseArg} [clause]
|
2039
|
+
*
|
2040
|
+
* @class LimitClause
|
2041
|
+
* @extends SelectorBasedClause<T>
|
2042
|
+
* @implements OffsetOption<T>
|
2043
|
+
*
|
2044
|
+
* @category Query
|
2045
|
+
* @subcategory Clauses
|
2046
|
+
*/
|
2047
|
+
class LimitClause extends SelectorBasedClause {
|
2048
|
+
constructor(clause) {
|
2049
|
+
super(Object.assign({}, clause, { priority: exports.Priority.GROUP_BY }));
|
2050
|
+
}
|
2051
|
+
/**
|
2052
|
+
* @inheritDoc
|
2053
|
+
*/
|
2054
|
+
offset(selector) {
|
2055
|
+
return this.Clauses.offset(this.statement, selector);
|
2056
|
+
}
|
2057
|
+
}
|
2058
|
+
|
2059
|
+
/**
|
2060
|
+
* @summary The OFFSET clause
|
2061
|
+
*
|
2062
|
+
* @param {ClauseArg} [clause]
|
2063
|
+
*
|
2064
|
+
* @class FromClause
|
2065
|
+
* @extends SelectorBasedClause
|
2066
|
+
*
|
2067
|
+
* @category Query
|
2068
|
+
* @subcategory Clauses
|
2069
|
+
*/
|
2070
|
+
class OffsetClause extends SelectorBasedClause {
|
2071
|
+
constructor(clause) {
|
2072
|
+
super(Object.assign({}, clause, { priority: exports.Priority.GROUP_BY }));
|
2073
|
+
}
|
2074
|
+
}
|
2075
|
+
|
2076
|
+
/**
|
2077
|
+
* @summary The ORDER BY clause
|
2078
|
+
*
|
2079
|
+
* @param {ClauseArg} [clause]
|
2080
|
+
*
|
2081
|
+
* @class OrderByClause
|
2082
|
+
* @extends SelectorBasedClause
|
2083
|
+
* @implements LimitOption
|
2084
|
+
* @implements OffsetOption
|
2085
|
+
*
|
2086
|
+
* @category Query
|
2087
|
+
* @subcategory Clauses
|
2088
|
+
*/
|
2089
|
+
class OrderByClause extends SelectorBasedClause {
|
2090
|
+
constructor(clause) {
|
2091
|
+
super(Object.assign({}, clause, { priority: exports.Priority.ORDER_BY }));
|
2092
|
+
}
|
2093
|
+
/**
|
2094
|
+
* @inheritDoc
|
2095
|
+
*/
|
2096
|
+
groupBy(selector) {
|
2097
|
+
return this.Clauses.groupBy(this.statement, selector);
|
2098
|
+
}
|
2099
|
+
/**
|
2100
|
+
* @inheritDoc
|
2101
|
+
*/
|
2102
|
+
limit(selector) {
|
2103
|
+
return this.Clauses.limit(this.statement, selector);
|
2104
|
+
}
|
2105
|
+
/**
|
2106
|
+
* @inheritDoc
|
2107
|
+
*/
|
2108
|
+
offset(selector) {
|
2109
|
+
return this.Clauses.offset(this.statement, selector);
|
2110
|
+
}
|
2111
|
+
}
|
2112
|
+
|
2113
|
+
/**
|
2114
|
+
* @summary The SELECT clause
|
2115
|
+
*
|
2116
|
+
* @param {ClauseArg} [clause]
|
2117
|
+
*
|
2118
|
+
* @class SelectClause
|
2119
|
+
* @extends SelectorBasedClause
|
2120
|
+
* @implements SelectOption
|
2121
|
+
*
|
2122
|
+
* @category Query
|
2123
|
+
* @subcategory Clauses
|
2124
|
+
*/
|
2125
|
+
class SelectClause extends SelectorBasedClause {
|
2126
|
+
constructor(clause) {
|
2127
|
+
super(Object.assign({}, clause, { priority: exports.Priority.SELECT }));
|
2128
|
+
this.isDistinct = false;
|
2129
|
+
this.isCount = false;
|
2130
|
+
this.isMax = false;
|
2131
|
+
this.isMin = false;
|
2132
|
+
if (this.selector === exports.Const.FULL_RECORD)
|
2133
|
+
this.statement.setFullRecord();
|
2134
|
+
this.statement.setMode(exports.StatementType.QUERY);
|
2135
|
+
}
|
2136
|
+
/**
|
2137
|
+
* @inheritDoc
|
2138
|
+
*/
|
2139
|
+
distinct(selector) {
|
2140
|
+
this.isDistinct = true;
|
2141
|
+
this.selector = selector;
|
2142
|
+
return this;
|
2143
|
+
}
|
2144
|
+
/**
|
2145
|
+
* @inheritDoc
|
2146
|
+
*/
|
2147
|
+
count(selector) {
|
2148
|
+
this.selector = selector;
|
2149
|
+
return this;
|
2150
|
+
}
|
2151
|
+
/**
|
2152
|
+
* @inheritDoc
|
2153
|
+
*/
|
2154
|
+
min(selector) {
|
2155
|
+
this.selector = selector;
|
2156
|
+
return this;
|
2157
|
+
}
|
2158
|
+
/**
|
2159
|
+
* @inheritDoc
|
2160
|
+
*/
|
2161
|
+
max(selector) {
|
2162
|
+
this.selector = selector;
|
2163
|
+
return this;
|
2164
|
+
}
|
2165
|
+
/**
|
2166
|
+
* @inheritDoc
|
2167
|
+
*/
|
2168
|
+
from(tableName) {
|
2169
|
+
return this.Clauses.from(this.statement, tableName);
|
2170
|
+
}
|
2171
|
+
}
|
2172
|
+
|
2173
|
+
/**
|
2174
|
+
* @summary The VALUES clause
|
2175
|
+
*
|
2176
|
+
* @param {ClauseArg} [clause]
|
2177
|
+
*
|
2178
|
+
* @class ValuesClause
|
2179
|
+
* @extends Clause
|
2180
|
+
*
|
2181
|
+
* @category Query
|
2182
|
+
* @subcategory Clauses
|
2183
|
+
*/
|
2184
|
+
class ValuesClause extends Clause {
|
2185
|
+
constructor(clause) {
|
2186
|
+
super(Object.assign({}, clause, { priority: exports.Priority.FROM }));
|
2187
|
+
this.models = undefined;
|
2188
|
+
this.models = clause?.models;
|
2189
|
+
}
|
2190
|
+
}
|
2191
|
+
__decorate([
|
2192
|
+
decoratorValidation.required(),
|
2193
|
+
decoratorValidation.type(Array.name),
|
2194
|
+
__metadata("design:type", Array)
|
2195
|
+
], ValuesClause.prototype, "models", void 0);
|
2196
|
+
|
2197
|
+
/**
|
2198
|
+
* @summary The WHERE clause
|
2199
|
+
*
|
2200
|
+
* @param {ClauseArg} [clause]
|
2201
|
+
*
|
2202
|
+
* @class WhereClause
|
2203
|
+
* @extends Clause
|
2204
|
+
* @implements OrderAndGroupOption
|
2205
|
+
*
|
2206
|
+
* @category Query
|
2207
|
+
* @subcategory Clauses
|
2208
|
+
*/
|
2209
|
+
class WhereClause extends Clause {
|
2210
|
+
constructor(clause) {
|
2211
|
+
super(Object.assign({}, clause, { priority: exports.Priority.WHERE }));
|
2212
|
+
this.condition = undefined;
|
2213
|
+
this.condition = clause?.condition;
|
2214
|
+
}
|
2215
|
+
/**
|
2216
|
+
* @inheritDoc
|
2217
|
+
*/
|
2218
|
+
orderBy(...selector) {
|
2219
|
+
return this.Clauses.orderBy(this.statement, selector);
|
2220
|
+
}
|
2221
|
+
/**
|
2222
|
+
* @inheritDoc
|
2223
|
+
*/
|
2224
|
+
groupBy(selector) {
|
2225
|
+
return this.Clauses.groupBy(this.statement, selector);
|
2226
|
+
}
|
2227
|
+
/**
|
2228
|
+
* @inheritDoc
|
2229
|
+
*/
|
2230
|
+
limit(selector) {
|
2231
|
+
return this.Clauses.limit(this.statement, selector);
|
2232
|
+
}
|
2233
|
+
/**
|
2234
|
+
* @inheritDoc
|
2235
|
+
*/
|
2236
|
+
offset(selector) {
|
2237
|
+
return this.Clauses.offset(this.statement, selector);
|
2238
|
+
}
|
2239
|
+
/**
|
2240
|
+
* @inheritDoc
|
2241
|
+
*/
|
2242
|
+
hasErrors(...exceptions) {
|
2243
|
+
const errors = super.hasErrors(...exceptions);
|
2244
|
+
if (errors)
|
2245
|
+
return errors;
|
2246
|
+
return this.condition.hasErrors();
|
2247
|
+
}
|
2248
|
+
}
|
2249
|
+
__decorate([
|
2250
|
+
decoratorValidation.required(),
|
2251
|
+
decoratorValidation.type("Condition"),
|
2252
|
+
__metadata("design:type", Condition)
|
2253
|
+
], WhereClause.prototype, "condition", void 0);
|
2254
|
+
|
2255
|
+
class ClauseFactory {
|
2256
|
+
constructor(adapter) {
|
2257
|
+
this.adapter = adapter;
|
2258
|
+
}
|
2259
|
+
}
|
2260
|
+
|
2261
|
+
class Paginator {
|
2262
|
+
get current() {
|
2263
|
+
return this._currentPage;
|
2264
|
+
}
|
2265
|
+
get total() {
|
2266
|
+
return this._totalPages;
|
2267
|
+
}
|
2268
|
+
get count() {
|
2269
|
+
return this._recordCount;
|
2270
|
+
}
|
2271
|
+
get statement() {
|
2272
|
+
if (!this._statement)
|
2273
|
+
this._statement = this.prepare(this._rawStatement);
|
2274
|
+
return this._statement;
|
2275
|
+
}
|
2276
|
+
get adapter() {
|
2277
|
+
return this.stat.getAdapter();
|
2278
|
+
}
|
2279
|
+
constructor(stat, size, _rawStatement) {
|
2280
|
+
this.stat = stat;
|
2281
|
+
this.size = size;
|
2282
|
+
this._rawStatement = _rawStatement;
|
2283
|
+
}
|
2284
|
+
async next() {
|
2285
|
+
return this.page(this.current + 1);
|
2286
|
+
}
|
2287
|
+
async previous() {
|
2288
|
+
return this.page(this.current - 1);
|
2289
|
+
}
|
2290
|
+
validatePage(page) {
|
2291
|
+
if (page < 1 || !Number.isInteger(page))
|
2292
|
+
throw new PagingError("page number cannot be under 1 and must be an integer");
|
2293
|
+
if (page > this._totalPages)
|
2294
|
+
throw new PagingError("page number cannot be under 1 and must be an integer");
|
2295
|
+
}
|
2296
|
+
}
|
2297
|
+
|
2298
|
+
injectableDecorators.Injectables.setRegistry(new InjectablesRegistry());
|
2299
|
+
/**
|
2300
|
+
* @summary stores the current package version
|
2301
|
+
* @description this is how you should document a constant
|
2302
|
+
* @const VERSION
|
2303
|
+
* @memberOf module:ts-workspace
|
2304
|
+
*/
|
2305
|
+
const VERSION = "0.4.1";
|
2306
|
+
|
2307
|
+
exports.Adapter = Adapter;
|
2308
|
+
exports.BaseModel = BaseModel;
|
2309
|
+
exports.BigIntSequence = BigIntSequence;
|
2310
|
+
exports.Clause = Clause;
|
2311
|
+
exports.ClauseFactory = ClauseFactory;
|
2312
|
+
exports.Condition = Condition;
|
2313
|
+
exports.ConnectionError = ConnectionError;
|
2314
|
+
exports.Context = Context;
|
2315
|
+
exports.DefaultCascade = DefaultCascade;
|
2316
|
+
exports.DefaultSequenceOptions = DefaultSequenceOptions;
|
2317
|
+
exports.FromClause = FromClause;
|
2318
|
+
exports.GroupByClause = GroupByClause;
|
2319
|
+
exports.InjectablesRegistry = InjectablesRegistry;
|
2320
|
+
exports.InsertClause = InsertClause;
|
2321
|
+
exports.LimitClause = LimitClause;
|
2322
|
+
exports.MandatoryPriorities = MandatoryPriorities;
|
2323
|
+
exports.NumericSequence = NumericSequence;
|
2324
|
+
exports.ObserverError = ObserverError;
|
2325
|
+
exports.OffsetClause = OffsetClause;
|
2326
|
+
exports.OrderByClause = OrderByClause;
|
2327
|
+
exports.Paginator = Paginator;
|
2328
|
+
exports.PagingError = PagingError;
|
2329
|
+
exports.Query = Query;
|
2330
|
+
exports.QueryError = QueryError;
|
2331
|
+
exports.Repository = Repository;
|
2332
|
+
exports.SelectClause = SelectClause;
|
2333
|
+
exports.SelectorBasedClause = SelectorBasedClause;
|
2334
|
+
exports.Sequence = Sequence;
|
2335
|
+
exports.Statement = Statement;
|
2336
|
+
exports.UnsupportedError = UnsupportedError;
|
2337
|
+
exports.VERSION = VERSION;
|
2338
|
+
exports.ValuesClause = ValuesClause;
|
2339
|
+
exports.WhereClause = WhereClause;
|
2340
|
+
exports.clauseSequence = clauseSequence;
|
2341
|
+
exports.column = column;
|
2342
|
+
exports.createdBy = createdBy;
|
2343
|
+
exports.createdByOnCreateUpdate = createdByOnCreateUpdate;
|
2344
|
+
exports.generateInjectableNameForRepository = generateInjectableNameForRepository;
|
2345
|
+
exports.getTableName = getTableName;
|
2346
|
+
exports.index = index;
|
2347
|
+
exports.manyToOne = manyToOne;
|
2348
|
+
exports.oneToMany = oneToMany;
|
2349
|
+
exports.oneToOne = oneToOne;
|
2350
|
+
exports.pk = pk;
|
2351
|
+
exports.pkOnCreate = pkOnCreate;
|
2352
|
+
exports.repository = repository;
|
2353
|
+
exports.sequenceNameForModel = sequenceNameForModel;
|
2354
|
+
exports.table = table;
|
2355
|
+
exports.unique = unique;
|
2356
|
+
exports.uniqueOnCreateUpdate = uniqueOnCreateUpdate;
|
2357
|
+
exports.updatedBy = updatedBy;
|
2358
|
+
exports.uses = uses;
|
2359
|
+
|
2360
|
+
}));
|
2361
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXBvc2l0b3J5L2NvbnN0YW50cy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L0NvbnRleHQudHMiLCIuLi9zcmMvcGVyc2lzdGVuY2UvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3F1ZXJ5L2NvbnN0YW50cy50cyIsIi4uL3NyYy9xdWVyeS9RdWVyeS50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9lcnJvcnMudHMiLCIuLi9zcmMvcGVyc2lzdGVuY2UvQWRhcHRlci50cyIsIi4uL3NyYy9pZGVudGl0eS91dGlscy50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9TZXF1ZW5jZS50cyIsIi4uL3NyYy9wZXJzaXN0ZW5jZS9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvUmVwb3NpdG9yeS50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L2RlY29yYXRvcnMudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS9lcnJvcnMudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS91dGlscy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L2luamVjdGFibGVzLnRzIiwiLi4vc3JjL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zLnRzIiwiLi4vbm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIi4uL3NyYy9xdWVyeS9lcnJvcnMudHMiLCIuLi9zcmMvcXVlcnkvQ29uZGl0aW9uLnRzIiwiLi4vc3JjL21vZGVsL2NvbnN0cnVjdGlvbi50cyIsIi4uL3NyYy9tb2RlbC9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2lkZW50aXR5L2RlY29yYXRvcnMudHMiLCIuLi9zcmMvbW9kZWwvQmFzZU1vZGVsLnRzIiwiLi4vc3JjL21vZGVsL1VzZXIudHMiLCIuLi9zcmMvdmFsaWRhdG9ycy9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL3ZhbGlkYXRvcnMvQ2xhdXNlU2VxdWVuY2VWYWxpZGF0b3IudHMiLCIuLi9zcmMvcXVlcnkvU3RhdGVtZW50LnRzIiwiLi4vc3JjL3F1ZXJ5L0NsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9jbGF1c2VzL1NlbGVjdG9yQmFzZWRDbGF1c2UudHMiLCIuLi9zcmMvcXVlcnkvY2xhdXNlcy9Gcm9tQ2xhdXNlLnRzIiwiLi4vc3JjL3F1ZXJ5L2NsYXVzZXMvR3JvdXBCeUNsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9jbGF1c2VzL0luc2VydENsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9jbGF1c2VzL0xpbWl0Q2xhdXNlLnRzIiwiLi4vc3JjL3F1ZXJ5L2NsYXVzZXMvT2Zmc2V0Q2xhdXNlLnRzIiwiLi4vc3JjL3F1ZXJ5L2NsYXVzZXMvT3JkZXJCeUNsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9jbGF1c2VzL1NlbGVjdENsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9jbGF1c2VzL1ZhbHVlc0NsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9jbGF1c2VzL1doZXJlQ2xhdXNlLnRzIiwiLi4vc3JjL3F1ZXJ5L0NsYXVzZUZhY3RvcnkudHMiLCIuLi9zcmMvcXVlcnkvUGFnaW5hdG9yLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENhc2NhZGVNZXRhZGF0YSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgZGVmaW5lcyBvcmRlciBkaXJlY3Rpb25zIHdoZW4gc29ydGluZ1xuICpcbiAqIEBjb25zdGFudCBPcmRlckRpcmVjdGlvblxuICpcbiAqIEBjYXRlZ29yeSBRdWVyeVxuICovXG5leHBvcnQgZW51bSBPcmRlckRpcmVjdGlvbiB7XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBzb3J0IG9yZGVyIGFzIGFzY2VuZGluZ1xuICAgKiBAcHJvcCBBU0NcbiAgICovXG4gIEFTQyA9IFwiYXNjXCIsXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBzb3J0IG9yZGVyIGFzIGRlc2NlbmRpbmdcbiAgICogQHByb3BlcnR5IHtzdHJpbmd9IERTQ1xuICAgKi9cbiAgRFNDID0gXCJkZXNjXCIsXG59XG5cbmV4cG9ydCBlbnVtIENhc2NhZGUge1xuICBDQVNDQURFID0gXCJjYXNjYWRlXCIsXG4gIE5PTkUgPSBcIm5vbmVcIixcbn1cblxuZXhwb3J0IGNvbnN0IERlZmF1bHRDYXNjYWRlOiBDYXNjYWRlTWV0YWRhdGEgPSB7XG4gIHVwZGF0ZTogQ2FzY2FkZS5DQVNDQURFLFxuICBkZWxldGU6IENhc2NhZGUuTk9ORSxcbn07XG4iLCJpbXBvcnQgeyBDb250ZXh0IGFzIEN0eCB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gXCIuLi9tb2RlbFwiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ29udGV4dDxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBVIGV4dGVuZHMgVXNlciA9IFVzZXIsXG4+IGV4dGVuZHMgQ3R4PE0+IHtcbiAgcHJvdGVjdGVkIF90aW1lc3RhbXAhOiBEYXRlO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihcbiAgICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMsXG4gICAgbW9kZWw/OiBDb25zdHJ1Y3RvcjxNPixcbiAgICBwYXJlbnQ/OiBDb250ZXh0PGFueSwgYW55PlxuICApIHtcbiAgICBzdXBlcihvcGVyYXRpb24sIG1vZGVsLCBwYXJlbnQpO1xuICB9XG5cbiAgb3ZlcnJpZGUgZ2V0IHRpbWVzdGFtcCgpIHtcbiAgICBpZiAoIXRoaXMuX3RpbWVzdGFtcCkgdGhpcy5fdGltZXN0YW1wID0gbmV3IERhdGUoKTtcbiAgICByZXR1cm4gdGhpcy5fdGltZXN0YW1wO1xuICB9XG5cbiAgYWJzdHJhY3QgZ2V0IHVzZXIoKTogVSB8IHVuZGVmaW5lZDtcbn1cbiIsImV4cG9ydCBlbnVtIFBlcnNpc3RlbmNlS2V5cyB7XG4gIElOREVYID0gXCJpbmRleFwiLFxuICBVTklRVUUgPSBcInVuaXF1ZVwiLFxuICBBREFQVEVSID0gXCJhZGFwdGVyXCIsXG4gIElOSkVDVEFCTEUgPSBcImRlY2FmX3swfV9hZGFwdGVyX2Zvcl97MX1cIixcbiAgVEFCTEUgPSBcInRhYmxlXCIsXG4gIENPTFVNTiA9IFwiY29sdW1uXCIsXG4gIE1FVEFEQVRBID0gXCJfX21ldGFkYXRhXCIsXG4gIFJFTEFUSU9OUyA9IFwiX19yZWxhdGlvbnNcIixcbiAgQ0xBVVNFX1NFUVVFTkNFID0gXCJjbGF1c2Utc2VxdWVuY2VcIixcbiAgLy8gT3duZXJzaGlwXG4gIENSRUFURURfQlkgPSBcIm93bmVyc2hpcC5jcmVhdGVkLWJ5XCIsXG4gIFVQREFURURfQlkgPSBcIm93bmVyc2hpcC51cGRhdGVkLWJ5XCIsXG4gIC8vIFJlbGF0aW9uc1xuICBPTkVfVE9fT05FID0gXCJyZWxhdGlvbnMub25lLXRvLW9uZVwiLFxuICBPTkVfVE9fTUFOWSA9IFwicmVsYXRpb25zLm9uZS10by1tYW55XCIsXG4gIE1BTllfVE9fT05FID0gXCJyZWxhdGlvbnMubWFueS10by1vbmVcIixcbiAgUE9QVUxBVEUgPSBcInBvcHVsYXRlXCIsXG59XG5cbmV4cG9ydCBlbnVtIFJvbGVzIHtcbiAgQURNSU4gPSBcImFkbWluXCIsXG4gIFdSSVRFUiA9IFwid3JpdGVyXCIsXG4gIFJFQURFUiA9IFwicmVhZGVyXCIsXG59XG4iLCJleHBvcnQgZW51bSBPcGVyYXRvciB7XG4gIEVRVUFMID0gXCJFUVVBTFwiLFxuICBESUZGRVJFTlQgPSBcIkRJRkZFUkVOVFwiLFxuICBCSUdHRVIgPSBcIkJJR0dFUlwiLFxuICBCSUdHRVJfRVEgPSBcIkJJR0dFUl9FUVwiLFxuICBTTUFMTEVSID0gXCJTTUFMTEVSXCIsXG4gIFNNQUxMRVJfRVEgPSBcIlNNQUxMRVJfRVFcIixcbiAgLy8gQkVUV0VFTiA9IFwiQkVUV0VFTlwiLFxuICBOT1QgPSBcIk5PVFwiLFxuICBJTiA9IFwiSU5cIixcbiAgLy8gSVMgPSBcIklTXCIsXG4gIFJFR0VYUCA9IFwiUkVHRVhQXCIsXG59XG5cbmV4cG9ydCBlbnVtIEdyb3VwT3BlcmF0b3Ige1xuICBBTkQgPSBcIkFORFwiLFxuICBPUiA9IFwiT1JcIixcbn1cblxuZXhwb3J0IGVudW0gQ29uc3Qge1xuICBOVUxMID0gXCJOVUxMXCIsXG4gIEZVTExfUkVDT1JEID0gXCIqXCIsXG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBleGVjdXRpb24gb3JkZXIgb2YgQ2xhdXNlcyBpbiBzdGF0ZW1lbnRzIGFzIGRlZmluZWQgaW4gU1FMLlxuICpcbiAqIEBkZXNjcmlwdGlvbiBzdWIgcHJpb3JpdGllcyB3aGVyZSBkZWZpbmVkIHRvIGJldHRlciBvcmdhbml6ZSBjbGF1c2VzIHdpdGhpbiBzdGF0ZW1lbnRzLCBlZyBGcm9tIGFuZCBKb2luIENsYXVzZXNcbiAqXG4gKiBAY29uc3QgUHJpb3JpdHlcbiAqXG4gKiBAY2F0ZWdvcnkgQ2xhdXNlc1xuICogQHN1YmNhdGVnb3J5IENvbnN0YW50c1xuICovXG5leHBvcnQgZW51bSBQcmlvcml0eSB7XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBwcmlvcml0eSBmb3IgdGhlIEZST00gQ2xhdXNlXG4gICAqIEBkZXNjcmlwdGlvbiBGcm9tIENsYXVzZSBpbiBTRUxFQ1QgU3RhdGVtZW50cy5cbiAgICogVmFsdWVzIENsYXVzZSBpbiBJTlNFUlQgU3RhdGVtZW50c1xuICAgKlxuICAgKiBAcHJvcCBGUk9NXG4gICAqL1xuICBGUk9NID0gMSxcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIHByaW9yaXR5IGZvciB0aGUgSk9JTiBDbGF1c2VcbiAgICpcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IEpPSU5cbiAgICovXG4gIEpPSU4gPSAxLjEsXG4gIC8qKlxuICAgKiBXaGVyZSBDbGF1c2VcbiAgICovXG4gIFdIRVJFID0gMixcbiAgLyoqXG4gICAqIEdyb3VwIEJ5IENsYXVzZVxuICAgKi9cbiAgR1JPVVBfQlkgPSAzLFxuICAvKipcbiAgICogSGF2aW5nIENsYXVzZVxuICAgKi9cbiAgSEFWSU5HID0gNCxcbiAgLyoqXG4gICAqIFNlbGVjdCBDbGF1c2UgaW4gU0VMRUNUIFN0YXRlbWVudHNcbiAgICogSW5zZXJ0IENsYXVzZSBpbiBJTlNFUlQgU3RhdGVtZW50c1xuICAgKi9cbiAgU0VMRUNUID0gNSxcbiAgLyoqXG4gICAqIE9yZGVyIEJ5IENsYXVzZVxuICAgKi9cbiAgT1JERVJfQlkgPSA2LFxuICAvKipcbiAgICogTGltaXQgQ2xhdXNlXG4gICAqL1xuICBMSU1JVCA9IDcsXG4gIC8qKlxuICAgKiBPZmZzZXQgQ2xhdXNlXG4gICAqL1xuICBPRkZTRVQgPSA3LjEsXG59XG5cbmV4cG9ydCBjb25zdCBNYW5kYXRvcnlQcmlvcml0aWVzID0gW1ByaW9yaXR5LkZST00sIFByaW9yaXR5LlNFTEVDVF07XG5cbmV4cG9ydCBlbnVtIFN0YXRlbWVudFR5cGUge1xuICBRVUVSWSA9IFwicXVlcnlcIixcbiAgVFJBTlNBQ1RJT04gPSBcInRyYW5zYWN0aW9uXCIsXG59XG4iLCJpbXBvcnQge1xuICBDb3VudE9wdGlvbixcbiAgRGlzdGluY3RPcHRpb24sXG4gIEluc2VydE9wdGlvbixcbiAgTWF4T3B0aW9uLFxuICBNaW5PcHRpb24sXG4gIFNlbGVjdE9wdGlvbixcbn0gZnJvbSBcIi4vb3B0aW9uc1wiO1xuaW1wb3J0IHsgU2VsZWN0U2VsZWN0b3IgfSBmcm9tIFwiLi9zZWxlY3RvcnNcIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2VcIjtcbmltcG9ydCB7IENvbnN0IH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBIZWxwZXIgQ2xhc3MgdG8gYnVpbGQgcXVlcmllc1xuICpcbiAqIEBwYXJhbSB7RGF0YWJhc2V9IGRiXG4gKlxuICogQGNsYXNzIFF1ZXJ5XG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKi9cbmV4cG9ydCBjbGFzcyBRdWVyeTxRLCBNIGV4dGVuZHMgTW9kZWw+IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBhZGFwdGVyOiBBZGFwdGVyPGFueSwgUT4pIHt9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBTZWxlY3QgQ2xhdXNlXG4gICAqIEBwYXJhbSB7U2VsZWN0U2VsZWN0b3J9IFtzZWxlY3Rvcl1cbiAgICovXG4gIHNlbGVjdChzZWxlY3RvcjogU2VsZWN0U2VsZWN0b3IgPSBDb25zdC5GVUxMX1JFQ09SRCk6IFNlbGVjdE9wdGlvbjxNPiB7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5DbGF1c2VzLnNlbGVjdDxNPihzZWxlY3Rvcik7XG4gIH1cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBNaW4gQ2xhdXNlXG4gICAqIEBwYXJhbSB7U2VsZWN0U2VsZWN0b3J9IHNlbGVjdG9yXG4gICAqL1xuICBtaW4oc2VsZWN0b3I6IFNlbGVjdFNlbGVjdG9yKTogTWluT3B0aW9uPE0+IHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3QoKS5taW4oc2VsZWN0b3IpO1xuICB9XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgTWF4IENsYXVzZVxuICAgKiBAcGFyYW0ge1NlbGVjdFNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgbWF4KHNlbGVjdG9yOiBTZWxlY3RTZWxlY3Rvcik6IE1heE9wdGlvbjxNPiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0KCkubWF4KHNlbGVjdG9yKTtcbiAgfVxuICAvKipcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIERpc3RpbmN0IENsYXVzZVxuICAgKiBAcGFyYW0ge1NlbGVjdFNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgZGlzdGluY3Qoc2VsZWN0b3I6IFNlbGVjdFNlbGVjdG9yKTogRGlzdGluY3RPcHRpb248TT4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdCgpLmRpc3RpbmN0KHNlbGVjdG9yKTtcbiAgfVxuICAvKipcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIENvdW50IENsYXVzZVxuICAgKiBAcGFyYW0ge1NlbGVjdFNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgY291bnQoc2VsZWN0b3I/OiBTZWxlY3RTZWxlY3Rvcik6IENvdW50T3B0aW9uPE0+IHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3QoKS5jb3VudChzZWxlY3Rvcik7XG4gIH1cblxuICBpbnNlcnQoKTogSW5zZXJ0T3B0aW9uPE0+IHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLkNsYXVzZXMuaW5zZXJ0PE0+KCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2VFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbkVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKENvbm5lY3Rpb25FcnJvci5uYW1lLCBtc2cpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBVbnN1cHBvcnRlZEVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKFVuc3VwcG9ydGVkRXJyb3IubmFtZSwgbXNnKTtcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgQmFzZUVycm9yLFxuICBEQktleXMsXG4gIEludGVybmFsRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIENvbnRleHQsXG4gIE9wZXJhdGlvbktleXMsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9PYnNlcnZlclwiO1xuaW1wb3J0IHtcbiAgQ29uc3RydWN0b3IsXG4gIE1vZGVsLFxuICBNb2RlbENvbnN0cnVjdG9yLFxuICBNb2RlbFJlZ2lzdHJ5LFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBTZXF1ZW5jZU9wdGlvbnMgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9TZXF1ZW5jZU9wdGlvbnNcIjtcbmltcG9ydCB7IFJhd0V4ZWN1dG9yIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvUmF3RXhlY3V0b3JcIjtcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9PYnNlcnZhYmxlXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFF1ZXJ5IH0gZnJvbSBcIi4uL3F1ZXJ5L1F1ZXJ5XCI7XG5pbXBvcnQgeyBTdGF0ZW1lbnQgfSBmcm9tIFwiLi4vcXVlcnkvU3RhdGVtZW50XCI7XG5pbXBvcnQgeyBDbGF1c2VGYWN0b3J5IH0gZnJvbSBcIi4uL3F1ZXJ5L0NsYXVzZUZhY3RvcnlcIjtcbmltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuLi9xdWVyeS9Db25kaXRpb25cIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBTZXF1ZW5jZSB9IGZyb20gXCIuL1NlcXVlbmNlXCI7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSBcIi4uL21vZGVsL1VzZXJcIjtcbmltcG9ydCB7IENvbnRleHQgYXMgQ3R4IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvQ29udGV4dFwiO1xuaW1wb3J0IHsgVW5zdXBwb3J0ZWRFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IEFic3RyYWN0IERlY2FmLXRzIFBlcnNpc3RlbmNlIEFkYXB0ZXIgQ2xhc3NcbiAqIEBkZXNjcmlwdGlvbiBPZmZlcnMgdGhlIGJhc2UgaW1wbGVtZW50YXRpb24gZm9yIGFsbCBBZGFwdGVyIENsYXNzZXNcbiAqIGFuZCBtYW5hZ2VzIHRoZW0gdmFyaW91cyByZWdpc3RlcmVkIHtAbGluayBBZGFwdGVyfXNcbiAqXG4gKiBAdHlwZWRlZiBZIHRoZSB1bmRlcmx5aW5nIHBlcnNpc3RlbmNlIG9iamVjdCB0eXBlXG4gKiBAdHlwZWRlZiBRIFRoZSBxdWVyeSBvYmplY3QgdGhlIGFkYXB0ZXIgdXNlc1xuICpcbiAqIEBwYXJhbSB7WX0gbmF0aXZlIHRoZSB1bmRlcmx5aW5nIHBlcnNpc3RlbmNlIG9iamVjdFxuICogQHBhcmFtIHtzdHJpbmd9IGZsYXZvdXIgdGhlIHVuZGVyIHdpdGNoIHRoZSBwZXJzaXN0ZW5jZSBhZGFwdGVyIHNob3VsZCBiZSBzdG9yZWRcbiAqXG4gKiBAY2xhc3MgQWRhcHRlclxuICogQGltcGxlbWVudHMgUmF3RXhlY3V0b3JcbiAqIEBpbXBsZW1lbnRzIE9ic2VydmFibGVcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFkYXB0ZXI8WSwgUT4gaW1wbGVtZW50cyBSYXdFeGVjdXRvcjxRPiwgT2JzZXJ2YWJsZSB7XG4gIHByaXZhdGUgc3RhdGljIF9jdXJyZW50OiBBZGFwdGVyPGFueSwgYW55PjtcbiAgcHJpdmF0ZSBzdGF0aWMgX2NhY2hlOiBSZWNvcmQ8c3RyaW5nLCBBZGFwdGVyPGFueSwgYW55Pj4gPSB7fTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX29ic2VydmVyczogT2JzZXJ2ZXJbXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IF9uYXRpdmU6IFk7XG5cbiAgZ2V0IG5hdGl2ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbmF0aXZlO1xuICB9XG5cbiAgcmVwb3NpdG9yeTxNIGV4dGVuZHMgTW9kZWw+KCk6IENvbnN0cnVjdG9yPFJlcG9zaXRvcnk8TSwgUSwgQWRhcHRlcjxZLCBRPj4+IHtcbiAgICByZXR1cm4gUmVwb3NpdG9yeTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihcbiAgICBuYXRpdmU6IFksXG4gICAgcmVhZG9ubHkgZmxhdm91cjogc3RyaW5nXG4gICkge1xuICAgIGlmICh0aGlzLmZsYXZvdXIgaW4gQWRhcHRlci5fY2FjaGUpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYFBlcnNpc3RlbmNlIGFkYXB0ZXIgZmxhdm91ciAke3RoaXMuZmxhdm91cn0gYWxyZWFkeSByZWdpc3RlcmVkYFxuICAgICAgKTtcbiAgICB0aGlzLl9uYXRpdmUgPSBuYXRpdmU7XG4gICAgQWRhcHRlci5fY2FjaGVbdGhpcy5mbGF2b3VyXSA9IHRoaXM7XG4gIH1cblxuICBRdWVyeTxNIGV4dGVuZHMgTW9kZWw+KCk6IFF1ZXJ5PFEsIE0+IHtcbiAgICByZXR1cm4gbmV3IFF1ZXJ5KHRoaXMpO1xuICB9XG5cbiAgYWJzdHJhY3QgcGFyc2VDb25kaXRpb24oY29uZGl0aW9uOiBDb25kaXRpb24pOiBRO1xuXG4gIGFic3RyYWN0IGdldCBTdGF0ZW1lbnQoKTogU3RhdGVtZW50PFE+O1xuXG4gIGFic3RyYWN0IGdldCBDbGF1c2VzKCk6IENsYXVzZUZhY3Rvcnk8WSwgUT47XG5cbiAgcHJvdGVjdGVkIGlzUmVzZXJ2ZWQoYXR0cjogc3RyaW5nKSB7XG4gICAgcmV0dXJuICFhdHRyO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFic3RyYWN0IHBhcnNlRXJyb3IoZXJyOiBFcnJvcik6IEJhc2VFcnJvcjtcblxuICBhYnN0cmFjdCBpbml0aWFsaXplKC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPjtcblxuICBhYnN0cmFjdCBTZXF1ZW5jZShvcHRpb25zOiBTZXF1ZW5jZU9wdGlvbnMpOiBQcm9taXNlPFNlcXVlbmNlPjtcblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgdXNlcigpOiBQcm9taXNlPFVzZXIgfCB1bmRlZmluZWQ+O1xuXG4gIGFzeW5jIGNvbnRleHQ8TSBleHRlbmRzIE1vZGVsLCBDIGV4dGVuZHMgQ29udGV4dDxNPj4oXG4gICAgb3BlcmF0aW9uOlxuICAgICAgfCBPcGVyYXRpb25LZXlzLkNSRUFURVxuICAgICAgfCBPcGVyYXRpb25LZXlzLlJFQURcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5VUERBVEVcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+XG4gICk6IFByb21pc2U8Qz4ge1xuICAgIGxldCB1c2VyOiBVc2VyIHwgdW5kZWZpbmVkO1xuICAgIHRyeSB7XG4gICAgICB1c2VyID0gYXdhaXQgdGhpcy51c2VyKCk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoIShlIGluc3RhbmNlb2YgVW5zdXBwb3J0ZWRFcnJvcikpIHRocm93IGU7XG4gICAgfVxuXG4gICAgY29uc3QgYzogQyA9IG5ldyAoY2xhc3MgZXh0ZW5kcyBDdHg8TT4ge1xuICAgICAgY29uc3RydWN0b3IoXG4gICAgICAgIG9wZXJhdGlvbjogT3BlcmF0aW9uS2V5cyxcbiAgICAgICAgbW9kZWw/OiBDb25zdHJ1Y3RvcjxNPixcbiAgICAgICAgcGFyZW50PzogQ3R4PGFueSwgYW55PlxuICAgICAgKSB7XG4gICAgICAgIHN1cGVyKG9wZXJhdGlvbiwgbW9kZWwsIHBhcmVudCk7XG4gICAgICB9XG5cbiAgICAgIGdldCB1c2VyKCk6IFVzZXIgfCB1bmRlZmluZWQge1xuICAgICAgICBpZiAoIXVzZXIpXG4gICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRXJyb3IoXG4gICAgICAgICAgICBcIkFkYXB0ZXIgZG9lcyBub3Qgc3VwcG9ydCB1c2VyIGlkZW50aWZpY2F0aW9uXCJcbiAgICAgICAgICApO1xuICAgICAgICByZXR1cm4gdXNlcjtcbiAgICAgIH1cbiAgICB9KShvcGVyYXRpb24sIG1vZGVsKSBhcyB1bmtub3duIGFzIEM7XG5cbiAgICByZXR1cm4gYztcbiAgfVxuXG4gIHByZXBhcmU8TSBleHRlbmRzIE1vZGVsPihcbiAgICBtb2RlbDogTSxcbiAgICBwazogc3RyaW5nIHwgbnVtYmVyXG4gICk6IHtcbiAgICByZWNvcmQ6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgaWQ6IHN0cmluZztcbiAgfSB7XG4gICAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmVudHJpZXMobW9kZWwpLnJlZHVjZShcbiAgICAgIChhY2N1bTogUmVjb3JkPHN0cmluZywgYW55PiwgW2tleSwgdmFsXSkgPT4ge1xuICAgICAgICAvLyBpZiAoa2V5ID09PSBwaykgcmV0dXJuIGFjY3VtO1xuICAgICAgICBjb25zdCBtYXBwZWRQcm9wID0gUmVwb3NpdG9yeS5jb2x1bW4obW9kZWwsIGtleSk7XG4gICAgICAgIGlmICh0aGlzLmlzUmVzZXJ2ZWQobWFwcGVkUHJvcCkpXG4gICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYFByb3BlcnR5IG5hbWUgJHttYXBwZWRQcm9wfSBpcyByZXNlcnZlZGApO1xuICAgICAgICBhY2N1bVttYXBwZWRQcm9wXSA9IHZhbDtcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSxcbiAgICAgIHt9XG4gICAgKTtcbiAgICBpZiAoKG1vZGVsIGFzIGFueSlbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXSlcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXN1bHQsIFBlcnNpc3RlbmNlS2V5cy5NRVRBREFUQSwge1xuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIHZhbHVlOiAobW9kZWwgYXMgYW55KVtQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEFdLFxuICAgICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHJlY29yZDogcmVzdWx0LFxuICAgICAgaWQ6IChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwa10sXG4gICAgfTtcbiAgfVxuXG4gIHJldmVydDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG9iajogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICBjbGF6ejogc3RyaW5nIHwgQ29uc3RydWN0b3I8TT4sXG4gICAgcGs6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50XG4gICk6IE0ge1xuICAgIGNvbnN0IG9iOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgb2JbcGtdID0gaWQ7XG4gICAgY29uc3QgbSA9IChcbiAgICAgIHR5cGVvZiBjbGF6eiA9PT0gXCJzdHJpbmdcIiA/IE1vZGVsLmJ1aWxkKG9iLCBjbGF6eikgOiBuZXcgY2xhenoob2IpXG4gICAgKSBhcyBNO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gb2JqW1BlcnNpc3RlbmNlS2V5cy5NRVRBREFUQV07XG4gICAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmtleXMobSkucmVkdWNlKChhY2N1bTogTSwga2V5KSA9PiB7XG4gICAgICBpZiAoa2V5ID09PSBwaykgcmV0dXJuIGFjY3VtO1xuICAgICAgKGFjY3VtIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV0gPSBvYmpbUmVwb3NpdG9yeS5jb2x1bW4oYWNjdW0sIGtleSldO1xuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sIG0pO1xuICAgIGlmIChtZXRhZGF0YSlcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXN1bHQsIFBlcnNpc3RlbmNlS2V5cy5NRVRBREFUQSwge1xuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogbWV0YWRhdGEsXG4gICAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgYWJzdHJhY3QgY3JlYXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcblxuICBhc3luYyBjcmVhdGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IChzdHJpbmcgfCBudW1iZXIpW10sXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT5bXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT5bXT4ge1xuICAgIGlmIChpZC5sZW5ndGggIT09IG1vZGVsLmxlbmd0aClcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiSWRzIGFuZCBtb2RlbHMgbXVzdCBoYXZlIHRoZSBzYW1lIGxlbmd0aFwiKTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICBpZC5tYXAoKGksIGNvdW50KSA9PiB0aGlzLmNyZWF0ZSh0YWJsZU5hbWUsIGksIG1vZGVsW2NvdW50XSwgLi4uYXJncykpXG4gICAgKTtcbiAgfVxuXG4gIGFic3RyYWN0IHJlYWQoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG4gIGFzeW5jIHJlYWRBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IChzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQpW10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoaWQubWFwKChpKSA9PiB0aGlzLnJlYWQodGFibGVOYW1lLCBpLCAuLi5hcmdzKSkpO1xuICB9XG5cbiAgYWJzdHJhY3QgdXBkYXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcblxuICBhc3luYyB1cGRhdGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZ1tdIHwgbnVtYmVyW10sXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT5bXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT5bXT4ge1xuICAgIGlmIChpZC5sZW5ndGggIT09IG1vZGVsLmxlbmd0aClcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiSWRzIGFuZCBtb2RlbHMgbXVzdCBoYXZlIHRoZSBzYW1lIGxlbmd0aFwiKTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICBpZC5tYXAoKGksIGNvdW50KSA9PiB0aGlzLnVwZGF0ZSh0YWJsZU5hbWUsIGksIG1vZGVsW2NvdW50XSwgLi4uYXJncykpXG4gICAgKTtcbiAgfVxuXG4gIGFic3RyYWN0IGRlbGV0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj47XG5cbiAgYXN5bmMgZGVsZXRlQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KVtdLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGlkLm1hcCgoaSkgPT4gdGhpcy5kZWxldGUodGFibGVOYW1lLCBpLCAuLi5hcmdzKSkpO1xuICB9XG5cbiAgYWJzdHJhY3QgcmF3PFI+KHJhd0lucHV0OiBRLCBwcm9jZXNzOiBib29sZWFuLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8Uj47XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFJlZ2lzdGVycyBhbiB7QGxpbmsgT2JzZXJ2ZXJ9XG4gICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAqXG4gICAqIEBzZWUge09ic2VydmFibGUjb2JzZXJ2ZX1cbiAgICovXG4gIG9ic2VydmUob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl9vYnNlcnZlcnMuaW5kZXhPZihvYnNlcnZlcik7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJPYnNlcnZlciBhbHJlYWR5IHJlZ2lzdGVyZWRcIik7XG4gICAgdGhpcy5fb2JzZXJ2ZXJzLnB1c2gob2JzZXJ2ZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFVucmVnaXN0ZXJzIGFuIHtAbGluayBPYnNlcnZlcn1cbiAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICpcbiAgICogQHNlZSB7T2JzZXJ2YWJsZSN1bk9ic2VydmV9XG4gICAqL1xuICB1bk9ic2VydmUob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl9vYnNlcnZlcnMuaW5kZXhPZihvYnNlcnZlcik7XG4gICAgaWYgKGluZGV4ID09PSAtMSkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJGYWlsZWQgdG8gZmluZCBPYnNlcnZlclwiKTtcbiAgICB0aGlzLl9vYnNlcnZlcnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBjYWxscyBhbGwgcmVnaXN0ZXJlZCB7QGxpbmsgT2JzZXJ2ZXJ9cyB0byB1cGRhdGUgdGhlbXNlbHZlc1xuICAgKiBAcGFyYW0ge2FueVtdfSBbYXJnc10gb3B0aW9uYWwgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byB0aGUge0BsaW5rIE9ic2VydmVyI3JlZnJlc2h9IG1ldGhvZFxuICAgKi9cbiAgYXN5bmMgdXBkYXRlT2JzZXJ2ZXJzKC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChcbiAgICAgIHRoaXMuX29ic2VydmVycy5tYXAoKG8pID0+IG8ucmVmcmVzaCguLi5hcmdzKSlcbiAgICApO1xuICAgIHJlc3VsdHMuZm9yRWFjaCgocmVzdWx0LCBpKSA9PiB7XG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKVxuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYEZhaWxlZCB0byB1cGRhdGUgb2JzZXJ2YWJsZSAke3RoaXMuX29ic2VydmVyc1tpXX06ICR7cmVzdWx0LnJlYXNvbn1gXG4gICAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IGN1cnJlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2N1cnJlbnQ7XG4gIH1cblxuICBzdGF0aWMgZ2V0PFksIFE+KGZsYXZvdXI6IGFueSk6IEFkYXB0ZXI8WSwgUT4gfCB1bmRlZmluZWQge1xuICAgIGlmIChmbGF2b3VyIGluIHRoaXMuX2NhY2hlKSByZXR1cm4gdGhpcy5fY2FjaGVbZmxhdm91cl07XG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYE5vIEFkYXB0ZXIgcmVnaXN0ZXJlZCB1bmRlciAke2ZsYXZvdXJ9LmApO1xuICB9XG5cbiAgc3RhdGljIHNldEN1cnJlbnQoZmxhdm91cjogc3RyaW5nKSB7XG4gICAgY29uc3QgYWRhcHRlciA9IEFkYXB0ZXIuZ2V0KGZsYXZvdXIpO1xuICAgIGlmICghYWRhcHRlcilcbiAgICAgIHRocm93IG5ldyBOb3RGb3VuZEVycm9yKGBObyBwZXJzaXN0ZW5jZSBmbGF2b3VyICR7Zmxhdm91cn0gcmVnaXN0ZXJlZGApO1xuICAgIHRoaXMuX2N1cnJlbnQgPSBhZGFwdGVyO1xuICB9XG5cbiAgc3RhdGljIGtleShrZXk6IHN0cmluZykge1xuICAgIHJldHVybiBSZXBvc2l0b3J5LmtleShrZXkpO1xuICB9XG5cbiAgc3RhdGljIG1vZGVsczxNIGV4dGVuZHMgTW9kZWw+KGZsYXZvdXI6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZWdpc3RyeSA9IChNb2RlbCBhcyBhbnkpLmdldFJlZ2lzdHJ5KCkgYXMgTW9kZWxSZWdpc3RyeTxhbnk+O1xuICAgICAgY29uc3QgY2FjaGUgPSAoXG4gICAgICAgIHJlZ2lzdHJ5IGFzIHVua25vd24gYXMgeyBjYWNoZTogUmVjb3JkPHN0cmluZywgTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+PiB9XG4gICAgICApLmNhY2hlO1xuICAgICAgY29uc3QgbWFuYWdlZE1vZGVsczogTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+W10gPSBPYmplY3QudmFsdWVzKGNhY2hlKVxuICAgICAgICAubWFwKChtOiBNb2RlbENvbnN0cnVjdG9yPE0+KSA9PiB7XG4gICAgICAgICAgbGV0IGYgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgICAgQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLFxuICAgICAgICAgICAgbSBhcyBNb2RlbENvbnN0cnVjdG9yPGFueT5cbiAgICAgICAgICApO1xuICAgICAgICAgIGlmIChmICYmIGYgPT09IGZsYXZvdXIpIHJldHVybiBtO1xuICAgICAgICAgIGlmICghZikge1xuICAgICAgICAgICAgY29uc3QgcmVwbyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgICAgIFJlcG9zaXRvcnkua2V5KERCS2V5cy5SRVBPU0lUT1JZKSxcbiAgICAgICAgICAgICAgbSBhcyBNb2RlbENvbnN0cnVjdG9yPGFueT5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoIXJlcG8pIHJldHVybjtcbiAgICAgICAgICAgIGNvbnN0IHJlcG9zaXRvcnkgPSBSZXBvc2l0b3J5LmZvck1vZGVsKG0pO1xuXG4gICAgICAgICAgICBmID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgICAgICAgQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLFxuICAgICAgICAgICAgICByZXBvc2l0b3J5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIGY7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuZmlsdGVyKChtKSA9PiAhIW0pO1xuICAgICAgcmV0dXJuIG1hbmFnZWRNb2RlbHM7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihlKTtcbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvQWRhcHRlclwiO1xuaW1wb3J0IHsgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL2NvbnN0YW50c1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGFibGVOYW1lPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0gfCBDb25zdHJ1Y3RvcjxNPikge1xuICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLlRBQkxFKSxcbiAgICBtb2RlbCBpbnN0YW5jZW9mIE1vZGVsID8gbW9kZWwuY29uc3RydWN0b3IgOiBtb2RlbFxuICApO1xuICBpZiAobWV0YWRhdGEpIHtcbiAgICByZXR1cm4gbWV0YWRhdGE7XG4gIH1cbiAgaWYgKG1vZGVsIGluc3RhbmNlb2YgTW9kZWwpIHtcbiAgICByZXR1cm4gbW9kZWwuY29uc3RydWN0b3IubmFtZTtcbiAgfVxuICByZXR1cm4gbW9kZWwubmFtZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlcXVlbmNlTmFtZUZvck1vZGVsPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBNIHwgQ29uc3RydWN0b3I8TT4sXG4gIC4uLmFyZ3M6IHN0cmluZ1tdXG4pIHtcbiAgcmV0dXJuIFtnZXRUYWJsZU5hbWUobW9kZWwpLCAuLi5hcmdzXS5qb2luKFwiX1wiKTtcbn1cbiIsIi8qKlxuICogQHN1bW1hcnkgU2VxdWVuY2VcbiAqXG4gKiBAaW50ZXJmYWNlIFNlcXVlbmNlXG4gKlxuICogQGNhdGVnb3J5IFNlcXVlbmNlc1xuICovXG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBzZXF1ZW5jZU5hbWVGb3JNb2RlbCB9IGZyb20gXCIuLi9pZGVudGl0eS91dGlsc1wiO1xuaW1wb3J0IHsgU2VxdWVuY2VPcHRpb25zIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zXCI7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBTZXF1ZW5jZSB7XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgcmVhZG9ubHkgb3B0aW9uczogU2VxdWVuY2VPcHRpb25zKSB7fVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBnZW5lcmF0ZXMgdGhlIG5leHQgdmFsdWUgaW4gdGhlIHNlcXVlbmNlXG4gICAqXG4gICAqIEBtZXRob2RcbiAgICovXG4gIGFic3RyYWN0IG5leHQoKTogUHJvbWlzZTxzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ+O1xuICBhYnN0cmFjdCBjdXJyZW50KCk6IFByb21pc2U8c3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50PjtcbiAgYWJzdHJhY3QgcmFuZ2UoY291bnQ6IG51bWJlcik6IFByb21pc2U8KG51bWJlciB8IHN0cmluZyB8IGJpZ2ludClbXT47XG5cbiAgc3RhdGljIHBrPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0gfCBDb25zdHJ1Y3RvcjxNPikge1xuICAgIHJldHVybiBzZXF1ZW5jZU5hbWVGb3JNb2RlbChtb2RlbCwgXCJwa1wiKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgYXBwbHksIG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi9BZGFwdGVyXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiB1c2VzKGZsYXZvdXI6IHN0cmluZykge1xuICByZXR1cm4gYXBwbHkobWV0YWRhdGEoQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLCBmbGF2b3VyKSk7XG59XG4iLCJpbXBvcnQge1xuICBEQktleXMsXG4gIGVuZm9yY2VEQkRlY29yYXRvcnMsXG4gIGZpbmRQcmltYXJ5S2V5LFxuICBJbnRlcm5hbEVycm9yLFxuICBJUmVwb3NpdG9yeSxcbiAgT3BlcmF0aW9uS2V5cyxcbiAgUmVwb3NpdG9yeSBhcyBSZXAsXG4gIFZhbGlkYXRpb25FcnJvcixcbiAgd3JhcE1ldGhvZFdpdGhDb250ZXh0LFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9PYnNlcnZhYmxlXCI7XG5pbXBvcnQgeyBPYnNlcnZlciB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL09ic2VydmVyXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL0FkYXB0ZXJcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcbmltcG9ydCB7IFF1ZXJ5IH0gZnJvbSBcIi4uL3F1ZXJ5L1F1ZXJ5XCI7XG5pbXBvcnQgeyBPcmRlckRpcmVjdGlvbiB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgU2VxdWVuY2VPcHRpb25zIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zXCI7XG5pbXBvcnQgeyBRdWVyaWFibGUgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9RdWVyaWFibGVcIjtcbmltcG9ydCB7IFJlZmxlY3Rpb24gfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IEluZGV4TWV0YWRhdGEgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgU2VxdWVuY2UgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvU2VxdWVuY2VcIjtcbmltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuLi9xdWVyeS9Db25kaXRpb25cIjtcbmltcG9ydCB7IFdoZXJlT3B0aW9uIH0gZnJvbSBcIi4uL3F1ZXJ5L29wdGlvbnNcIjtcbmltcG9ydCB7IE9yZGVyQnlTZWxlY3RvciwgU2VsZWN0U2VsZWN0b3IgfSBmcm9tIFwiLi4vcXVlcnkvc2VsZWN0b3JzXCI7XG5pbXBvcnQgeyBnZXRUYWJsZU5hbWUgfSBmcm9tIFwiLi4vaWRlbnRpdHkvdXRpbHNcIjtcbmltcG9ydCB7IHVzZXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuL0NvbnRleHRcIjtcblxuZXhwb3J0IHR5cGUgUmVwbzxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBRID0gYW55LFxuICBBIGV4dGVuZHMgQWRhcHRlcjxhbnksIFE+ID0gQWRhcHRlcjxhbnksIFE+LFxuPiA9IFJlcG9zaXRvcnk8TSwgUSwgQT47XG5cbmV4cG9ydCBjbGFzcyBSZXBvc2l0b3J5PE0gZXh0ZW5kcyBNb2RlbCwgUSwgQSBleHRlbmRzIEFkYXB0ZXI8YW55LCBRPj5cbiAgZXh0ZW5kcyBSZXA8TT5cbiAgaW1wbGVtZW50cyBPYnNlcnZhYmxlLCBRdWVyaWFibGUsIElSZXBvc2l0b3J5PE0+XG57XG4gIHByaXZhdGUgc3RhdGljIF9jYWNoZTogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBDb25zdHJ1Y3RvcjxSZXBvPE1vZGVsPj4gfCBSZXBvPE1vZGVsPlxuICA+ID0ge307XG5cbiAgcHJvdGVjdGVkIG9ic2VydmVyczogT2JzZXJ2ZXJbXSA9IFtdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2FkYXB0ZXIhOiBBO1xuICBwcml2YXRlIF90YWJsZU5hbWUhOiBzdHJpbmc7XG5cbiAgcHJvdGVjdGVkIGdldCBhZGFwdGVyKCk6IEEge1xuICAgIGlmICghdGhpcy5fYWRhcHRlcilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgTm8gYWRhcHRlciBmb3VuZCBmb3IgdGhpcyByZXBvc2l0b3J5LiBkaWQgeW91IHVzZSB0aGUgQHVzZXMgZGVjb3JhdG9yIG9yIHBhc3MgaXQgaW4gdGhlIGNvbnN0cnVjdG9yP2BcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0ZXI7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICBpZiAoIXRoaXMuX3RhYmxlTmFtZSkgdGhpcy5fdGFibGVOYW1lID0gUmVwb3NpdG9yeS50YWJsZSh0aGlzLmNsYXNzKTtcbiAgICByZXR1cm4gdGhpcy5fdGFibGVOYW1lO1xuICB9XG5cbiAgY29uc3RydWN0b3IoYWRhcHRlcj86IEEsIGNsYXp6PzogQ29uc3RydWN0b3I8TT4pIHtcbiAgICBzdXBlcihjbGF6eik7XG4gICAgaWYgKGFkYXB0ZXIpIHRoaXMuX2FkYXB0ZXIgPSBhZGFwdGVyO1xuICAgIGlmIChjbGF6eikge1xuICAgICAgUmVwb3NpdG9yeS5yZWdpc3RlcihjbGF6eiwgdGhpcyk7XG4gICAgICBpZiAoYWRhcHRlcikge1xuICAgICAgICBjb25zdCBmbGF2b3VyID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgICBBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuQURBUFRFUiksXG4gICAgICAgICAgY2xhenpcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZsYXZvdXIgJiYgZmxhdm91ciAhPT0gYWRhcHRlci5mbGF2b3VyKVxuICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiSW5jb21wYXRpYmxlIGZsYXZvdXJzXCIpO1xuICAgICAgICB1c2VzKGFkYXB0ZXIuZmxhdm91cikoY2xhenopO1xuICAgICAgfVxuICAgIH1cbiAgICBbdGhpcy5jcmVhdGVBbGwsIHRoaXMucmVhZEFsbCwgdGhpcy51cGRhdGVBbGwsIHRoaXMuZGVsZXRlQWxsXS5mb3JFYWNoKFxuICAgICAgKG0pID0+IHtcbiAgICAgICAgY29uc3QgbmFtZSA9IG0ubmFtZTtcbiAgICAgICAgd3JhcE1ldGhvZFdpdGhDb250ZXh0KFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgKHRoaXMgYXMgYW55KVtuYW1lICsgXCJQcmVmaXhcIl0sXG4gICAgICAgICAgbSxcbiAgICAgICAgICAodGhpcyBhcyBhbnkpW25hbWUgKyBcIlN1ZmZpeFwiXVxuICAgICAgICApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgYXN5bmMgY3JlYXRlUHJlZml4KFxuICAgIG1vZGVsOiBNLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8W00sIC4uLmFueVtdXT4ge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJncyxcbiAgICAgIHRoaXMuYWRhcHRlclxuICAgICk7XG4gICAgbW9kZWwgPSBuZXcgdGhpcy5jbGFzcyhtb2RlbCk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICApO1xuXG4gICAgY29uc3QgZXJyb3JzID0gbW9kZWwuaGFzRXJyb3JzKCk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMudG9TdHJpbmcoKSk7XG5cbiAgICByZXR1cm4gW21vZGVsLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZShtb2RlbDogTSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gICAgbGV0IHsgcmVjb3JkLCBpZCB9ID0gdGhpcy5hZGFwdGVyLnByZXBhcmUobW9kZWwsIHRoaXMucGspO1xuICAgIHJlY29yZCA9IGF3YWl0IHRoaXMuYWRhcHRlci5jcmVhdGUodGhpcy50YWJsZU5hbWUsIGlkLCByZWNvcmQsIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIucmV2ZXJ0PE0+KHJlY29yZCwgdGhpcy5jbGFzcywgdGhpcy5waywgaWQpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlQWxsKG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TVtdPiB7XG4gICAgaWYgKCFtb2RlbHMubGVuZ3RoKSByZXR1cm4gbW9kZWxzO1xuICAgIGNvbnN0IHByZXBhcmVkID0gbW9kZWxzLm1hcCgobSkgPT4gdGhpcy5hZGFwdGVyLnByZXBhcmUobSwgdGhpcy5waykpO1xuICAgIGNvbnN0IGlkcyA9IHByZXBhcmVkLm1hcCgocCkgPT4gcC5pZCk7XG4gICAgbGV0IHJlY29yZHMgPSBwcmVwYXJlZC5tYXAoKHApID0+IHAucmVjb3JkKTtcbiAgICByZWNvcmRzID0gYXdhaXQgdGhpcy5hZGFwdGVyLmNyZWF0ZUFsbChcbiAgICAgIHRoaXMudGFibGVOYW1lLFxuICAgICAgaWRzIGFzIChzdHJpbmcgfCBudW1iZXIpW10sXG4gICAgICByZWNvcmRzLFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gICAgcmV0dXJuIHJlY29yZHMubWFwKChyLCBpKSA9PlxuICAgICAgdGhpcy5hZGFwdGVyLnJldmVydChyLCB0aGlzLmNsYXNzLCB0aGlzLnBrLCBpZHNbaV0gYXMgc3RyaW5nIHwgbnVtYmVyKVxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgY3JlYXRlQWxsUHJlZml4KG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJncyxcbiAgICAgIHRoaXMuYWRhcHRlclxuICAgICk7XG4gICAgaWYgKCFtb2RlbHMubGVuZ3RoKSByZXR1cm4gW21vZGVscywgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gICAgY29uc3Qgb3B0cyA9IFJlcG9zaXRvcnkuZ2V0U2VxdWVuY2VPcHRpb25zKG1vZGVsc1swXSk7XG4gICAgbGV0IGlkczogKHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCB8IHVuZGVmaW5lZClbXSA9IFtdO1xuICAgIGlmIChvcHRzLnR5cGUpIHtcbiAgICAgIGlmICghb3B0cy5uYW1lKSBvcHRzLm5hbWUgPSBTZXF1ZW5jZS5wayhtb2RlbHNbMF0pO1xuICAgICAgaWRzID0gYXdhaXQgKGF3YWl0IHRoaXMuYWRhcHRlci5TZXF1ZW5jZShvcHRzKSkucmFuZ2UobW9kZWxzLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgbW9kZWxzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKGFzeW5jIChtLCBpKSA9PiB7XG4gICAgICAgIG0gPSBuZXcgdGhpcy5jbGFzcyhtKTtcbiAgICAgICAgKG0gYXMgUmVjb3JkPHN0cmluZywgYW55PilbdGhpcy5wa10gPSBpZHNbaV07XG4gICAgICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gbTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICBjb25zdCBlcnJvcnMgPSBtb2RlbHNcbiAgICAgIC5tYXAoKG0pID0+IG0uaGFzRXJyb3JzKCkpXG4gICAgICAucmVkdWNlKChhY2N1bTogc3RyaW5nIHwgdW5kZWZpbmVkLCBlLCBpKSA9PiB7XG4gICAgICAgIGlmIChlKVxuICAgICAgICAgIGFjY3VtID1cbiAgICAgICAgICAgIHR5cGVvZiBhY2N1bSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgICAgICA/IGFjY3VtICsgYFxcbiAtICR7aX06ICR7ZS50b1N0cmluZygpfWBcbiAgICAgICAgICAgICAgOiBgIC0gJHtpfTogJHtlLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSwgdW5kZWZpbmVkKTtcbiAgICBpZiAoZXJyb3JzKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGVycm9ycyk7XG4gICAgcmV0dXJuIFttb2RlbHMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHJlYWRQcmVmaXgoa2V5OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJncyxcbiAgICAgIHRoaXMuYWRhcHRlclxuICAgICk7XG4gICAgY29uc3QgbW9kZWw6IE0gPSBuZXcgdGhpcy5jbGFzcygpO1xuICAgIChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVt0aGlzLnBrXSA9IGtleTtcbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICApO1xuICAgIHJldHVybiBba2V5LCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIGFzeW5jIHJlYWQoaWQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+IHtcbiAgICBjb25zdCBtID0gYXdhaXQgdGhpcy5hZGFwdGVyLnJlYWQodGhpcy50YWJsZU5hbWUsIGlkLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydDxNPihtLCB0aGlzLmNsYXNzLCB0aGlzLnBrLCBpZCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgcmVhZEFsbFByZWZpeChrZXlzOiBzdHJpbmdbXSB8IG51bWJlcltdLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXJcbiAgICApO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAga2V5cy5tYXAoYXN5bmMgKGspID0+IHtcbiAgICAgICAgY29uc3QgbSA9IG5ldyB0aGlzLmNsYXNzKCk7XG4gICAgICAgIChtIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3RoaXMucGtdID0gaztcbiAgICAgICAgcmV0dXJuIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gW2tleXMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgYXN5bmMgcmVhZEFsbChrZXlzOiBzdHJpbmdbXSB8IG51bWJlcltdLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TVtdPiB7XG4gICAgY29uc3QgcmVjb3JkcyA9IGF3YWl0IHRoaXMuYWRhcHRlci5yZWFkQWxsKHRoaXMudGFibGVOYW1lLCBrZXlzLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gcmVjb3Jkcy5tYXAoKHIsIGkpID0+XG4gICAgICB0aGlzLmFkYXB0ZXIucmV2ZXJ0KHIsIHRoaXMuY2xhc3MsIHRoaXMucGssIGtleXNbaV0pXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZShtb2RlbDogTSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLWNvbnN0XG4gICAgbGV0IHsgcmVjb3JkLCBpZCB9ID0gdGhpcy5hZGFwdGVyLnByZXBhcmUobW9kZWwsIHRoaXMucGspO1xuICAgIHJlY29yZCA9IGF3YWl0IHRoaXMuYWRhcHRlci51cGRhdGUodGhpcy50YWJsZU5hbWUsIGlkLCByZWNvcmQsIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIucmV2ZXJ0PE0+KHJlY29yZCwgdGhpcy5jbGFzcywgdGhpcy5waywgaWQpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHVwZGF0ZVByZWZpeChcbiAgICBtb2RlbDogTSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFtNLCAuLi5hcmdzOiBhbnlbXV0+IHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXJcbiAgICApO1xuICAgIGNvbnN0IHBrID0gKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3RoaXMucGtdO1xuICAgIGlmICghcGspXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYE5vIHZhbHVlIGZvciB0aGUgSWQgaXMgZGVmaW5lZCB1bmRlciB0aGUgcHJvcGVydHkgJHt0aGlzLnBrfWBcbiAgICAgICk7XG4gICAgY29uc3Qgb2xkTW9kZWwgPSBhd2FpdCB0aGlzLnJlYWQocGssIC4uLmNvbnRleHRBcmdzLmFyZ3MpO1xuICAgIG1vZGVsID0gdGhpcy5tZXJnZShvbGRNb2RlbCwgbW9kZWwpO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OLFxuICAgICAgb2xkTW9kZWxcbiAgICApO1xuXG4gICAgY29uc3QgZXJyb3JzID0gbW9kZWwuaGFzRXJyb3JzKFxuICAgICAgb2xkTW9kZWwsXG4gICAgICAuLi5SZXBvc2l0b3J5LnJlbGF0aW9ucyh0aGlzLmNsYXNzKVxuICAgICk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMudG9TdHJpbmcoKSk7XG4gICAgaWYgKFJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEob2xkTW9kZWwpKSB7XG4gICAgICBpZiAoIVJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEobW9kZWwpKVxuICAgICAgICBSZXBvc2l0b3J5LnNldE1ldGFkYXRhKG1vZGVsLCBSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG9sZE1vZGVsKSk7XG4gICAgfVxuICAgIHJldHVybiBbbW9kZWwsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlQWxsKG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TVtdPiB7XG4gICAgY29uc3QgcmVjb3JkcyA9IG1vZGVscy5tYXAoKG0pID0+IHRoaXMuYWRhcHRlci5wcmVwYXJlKG0sIHRoaXMucGspKTtcbiAgICBjb25zdCB1cGRhdGVkID0gYXdhaXQgdGhpcy5hZGFwdGVyLnVwZGF0ZUFsbChcbiAgICAgIHRoaXMudGFibGVOYW1lLFxuICAgICAgcmVjb3Jkcy5tYXAoKHIpID0+IHIuaWQpLFxuICAgICAgcmVjb3Jkcy5tYXAoKHIpID0+IHIucmVjb3JkKSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICAgIHJldHVybiB1cGRhdGVkLm1hcCgodSwgaSkgPT5cbiAgICAgIHRoaXMuYWRhcHRlci5yZXZlcnQodSwgdGhpcy5jbGFzcywgdGhpcy5waywgcmVjb3Jkc1tpXS5pZClcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHVwZGF0ZUFsbFByZWZpeChtb2RlbHM6IE1bXSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPGFueVtdPiB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzLFxuICAgICAgdGhpcy5hZGFwdGVyXG4gICAgKTtcbiAgICBjb25zdCBpZHMgPSBtb2RlbHMubWFwKChtKSA9PiB7XG4gICAgICBjb25zdCBpZCA9IChtIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3RoaXMucGtdO1xuICAgICAgaWYgKCFpZCkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJtaXNzaW5nIGlkIG9uIHVwZGF0ZSBvcGVyYXRpb25cIik7XG4gICAgICByZXR1cm4gaWQ7XG4gICAgfSk7XG4gICAgY29uc3Qgb2xkTW9kZWxzID0gYXdhaXQgdGhpcy5yZWFkQWxsKGlkcywgLi4uY29udGV4dEFyZ3MuYXJncyk7XG4gICAgbW9kZWxzID0gbW9kZWxzLm1hcCgobSwgaSkgPT4ge1xuICAgICAgbSA9IHRoaXMubWVyZ2Uob2xkTW9kZWxzW2ldLCBtKTtcbiAgICAgIGlmIChSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG9sZE1vZGVsc1tpXSkpIHtcbiAgICAgICAgaWYgKCFSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG0pKVxuICAgICAgICAgIFJlcG9zaXRvcnkuc2V0TWV0YWRhdGEobSwgUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShvbGRNb2RlbHNbaV0pKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBtO1xuICAgIH0pO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgbW9kZWxzLm1hcCgobSwgaSkgPT5cbiAgICAgICAgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OLFxuICAgICAgICAgIG9sZE1vZGVsc1tpXVxuICAgICAgICApXG4gICAgICApXG4gICAgKTtcblxuICAgIGNvbnN0IGVycm9ycyA9IG1vZGVsc1xuICAgICAgLm1hcCgobSwgaSkgPT4gbS5oYXNFcnJvcnMob2xkTW9kZWxzW2ldLCBtKSlcbiAgICAgIC5yZWR1Y2UoKGFjY3VtOiBzdHJpbmcgfCB1bmRlZmluZWQsIGUsIGkpID0+IHtcbiAgICAgICAgaWYgKGUpXG4gICAgICAgICAgYWNjdW0gPVxuICAgICAgICAgICAgdHlwZW9mIGFjY3VtID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgID8gYWNjdW0gKyBgXFxuIC0gJHtpfTogJHtlLnRvU3RyaW5nKCl9YFxuICAgICAgICAgICAgICA6IGAgLSAke2l9OiAke2UudG9TdHJpbmcoKX1gO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCB1bmRlZmluZWQpO1xuICAgIGlmIChlcnJvcnMpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzKTtcblxuICAgIG1vZGVscy5mb3JFYWNoKChtLCBpKSA9PiB7XG4gICAgICBpZiAoUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShvbGRNb2RlbHNbaV0pKSB7XG4gICAgICAgIGlmICghUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShtKSlcbiAgICAgICAgICBSZXBvc2l0b3J5LnNldE1ldGFkYXRhKG0sIFJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEob2xkTW9kZWxzW2ldKSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIFttb2RlbHMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGRlbGV0ZVByZWZpeChrZXk6IGFueSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXJcbiAgICApO1xuICAgIGNvbnN0IG1vZGVsID0gYXdhaXQgdGhpcy5yZWFkKGtleSwgLi4uY29udGV4dEFyZ3MuYXJncyk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICApO1xuICAgIHJldHVybiBba2V5LCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZShpZDogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50LCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT4ge1xuICAgIGNvbnN0IG0gPSBhd2FpdCB0aGlzLmFkYXB0ZXIuZGVsZXRlKHRoaXMudGFibGVOYW1lLCBpZCwgLi4uYXJncyk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZXZlcnQ8TT4obSwgdGhpcy5jbGFzcywgdGhpcy5waywgaWQpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGRlbGV0ZUFsbFByZWZpeChrZXlzOiBzdHJpbmdbXSB8IG51bWJlcltdLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJncyxcbiAgICAgIHRoaXMuYWRhcHRlclxuICAgICk7XG4gICAgY29uc3QgbW9kZWxzID0gYXdhaXQgdGhpcy5yZWFkQWxsKGtleXMsIC4uLmNvbnRleHRBcmdzLmFyZ3MpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgbW9kZWxzLm1hcChhc3luYyAobSkgPT4ge1xuICAgICAgICByZXR1cm4gZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgICAgICk7XG4gICAgICB9KVxuICAgICk7XG4gICAgcmV0dXJuIFtrZXlzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZUFsbChrZXlzOiBzdHJpbmdbXSB8IG51bWJlcltdLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TVtdPiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuYWRhcHRlci5kZWxldGVBbGwodGhpcy50YWJsZU5hbWUsIGtleXMsIC4uLmFyZ3MpO1xuICAgIHJldHVybiByZXN1bHRzLm1hcCgociwgaSkgPT5cbiAgICAgIHRoaXMuYWRhcHRlci5yZXZlcnQociwgdGhpcy5jbGFzcywgdGhpcy5waywga2V5c1tpXSlcbiAgICApO1xuICB9XG5cbiAgc2VsZWN0KHNlbGVjdG9yPzogU2VsZWN0U2VsZWN0b3IpOiBXaGVyZU9wdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBRdWVyeTxRLCBNPih0aGlzLmFkYXB0ZXIpLnNlbGVjdChzZWxlY3RvcikuZnJvbSh0aGlzLmNsYXNzKTtcbiAgfVxuXG4gIGFzeW5jIHF1ZXJ5PFY+KFxuICAgIGNvbmRpdGlvbjogQ29uZGl0aW9uLFxuICAgIG9yZGVyQnk6IHN0cmluZyxcbiAgICBvcmRlcjogT3JkZXJEaXJlY3Rpb24gPSBPcmRlckRpcmVjdGlvbi5BU0MsXG4gICAgbGltaXQ/OiBudW1iZXIsXG4gICAgc2tpcD86IG51bWJlclxuICApOiBQcm9taXNlPFY+IHtcbiAgICBjb25zdCBzb3J0OiBPcmRlckJ5U2VsZWN0b3IgPSBbb3JkZXJCeSBhcyBzdHJpbmcsIG9yZGVyIGFzIE9yZGVyRGlyZWN0aW9uXTtcbiAgICBjb25zdCBxdWVyeSA9IHRoaXMuc2VsZWN0KCkud2hlcmUoY29uZGl0aW9uKS5vcmRlckJ5KHNvcnQpO1xuICAgIGlmIChsaW1pdCkgcXVlcnkubGltaXQobGltaXQpO1xuICAgIGlmIChza2lwKSBxdWVyeS5vZmZzZXQoc2tpcCk7XG4gICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGU8Vj4oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZWdpc3RlcnMgYW4ge0BsaW5rIE9ic2VydmVyfVxuICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgKlxuICAgKiBAc2VlIHtPYnNlcnZhYmxlI29ic2VydmV9XG4gICAqL1xuICBvYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5vYnNlcnZlcnMuaW5kZXhPZihvYnNlcnZlcik7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJPYnNlcnZlciBhbHJlYWR5IHJlZ2lzdGVyZWRcIik7XG4gICAgdGhpcy5vYnNlcnZlcnMucHVzaChvYnNlcnZlcik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgVW5yZWdpc3RlcnMgYW4ge0BsaW5rIE9ic2VydmVyfVxuICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgKlxuICAgKiBAc2VlIHtPYnNlcnZhYmxlI3VuT2JzZXJ2ZX1cbiAgICovXG4gIHVuT2JzZXJ2ZShvYnNlcnZlcjogT2JzZXJ2ZXIpOiB2b2lkIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMub2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiRmFpbGVkIHRvIGZpbmQgT2JzZXJ2ZXJcIik7XG4gICAgdGhpcy5vYnNlcnZlcnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBjYWxscyBhbGwgcmVnaXN0ZXJlZCB7QGxpbmsgT2JzZXJ2ZXJ9cyB0byB1cGRhdGUgdGhlbXNlbHZlc1xuICAgKiBAcGFyYW0ge2FueVtdfSBbYXJnc10gb3B0aW9uYWwgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byB0aGUge0BsaW5rIE9ic2VydmVyI3JlZnJlc2h9IG1ldGhvZFxuICAgKi9cbiAgYXN5bmMgdXBkYXRlT2JzZXJ2ZXJzKC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChcbiAgICAgIHRoaXMub2JzZXJ2ZXJzLm1hcCgobykgPT4gby5yZWZyZXNoKC4uLmFyZ3MpKVxuICAgICk7XG4gICAgcmVzdWx0cy5mb3JFYWNoKChyZXN1bHQsIGkpID0+IHtcbiAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSBcInJlamVjdGVkXCIpXG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICBgRmFpbGVkIHRvIHVwZGF0ZSBvYnNlcnZhYmxlICR7dGhpcy5vYnNlcnZlcnNbaV19OiAke3Jlc3VsdC5yZWFzb259YFxuICAgICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGZvck1vZGVsPE0gZXh0ZW5kcyBNb2RlbCwgUiBleHRlbmRzIFJlcG88TT4+KFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBkZWZhdWx0Rmxhdm91cj86IHN0cmluZ1xuICApOiBSIHtcbiAgICBsZXQgcmVwbzogUiB8IENvbnN0cnVjdG9yPFI+IHwgdW5kZWZpbmVkO1xuICAgIHRyeSB7XG4gICAgICByZXBvID0gdGhpcy5nZXQobW9kZWwpIGFzIENvbnN0cnVjdG9yPFI+IHwgUjtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJlcG8gPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKHJlcG8gaW5zdGFuY2VvZiBSZXBvc2l0b3J5KSByZXR1cm4gcmVwbyBhcyBSO1xuXG4gICAgY29uc3QgZmxhdm91cjogc3RyaW5nIHwgdW5kZWZpbmVkID1cbiAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLCBtb2RlbCkgfHxcbiAgICAgIChyZXBvICYmXG4gICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLCByZXBvKSkgfHxcbiAgICAgIGRlZmF1bHRGbGF2b3VyO1xuICAgIGNvbnN0IGFkYXB0ZXI6IEFkYXB0ZXI8YW55LCBhbnk+IHwgdW5kZWZpbmVkID0gZmxhdm91clxuICAgICAgPyBBZGFwdGVyLmdldChmbGF2b3VyKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoIWFkYXB0ZXIpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYE5vIHJlZ2lzdGVyZWQgcGVyc2lzdGVuY2UgYWRhcHRlciBmb3VuZCBmbGF2b3VyICR7Zmxhdm91cn1gXG4gICAgICApO1xuXG4gICAgcmVwbyA9IHJlcG8gfHwgKGFkYXB0ZXIucmVwb3NpdG9yeSgpIGFzIENvbnN0cnVjdG9yPFI+KTtcbiAgICByZXR1cm4gbmV3IHJlcG8oYWRhcHRlciwgbW9kZWwpIGFzIFI7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXQ8TSBleHRlbmRzIE1vZGVsPihcbiAgICBtb2RlbDogQ29uc3RydWN0b3I8TT5cbiAgKTogQ29uc3RydWN0b3I8UmVwbzxNPj4gfCBSZXBvPE0+IHtcbiAgICBjb25zdCBuYW1lID0gUmVwb3NpdG9yeS50YWJsZShtb2RlbCk7XG4gICAgaWYgKG5hbWUgaW4gdGhpcy5fY2FjaGUpXG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVbbmFtZV0gYXMgQ29uc3RydWN0b3I8UmVwbzxNPj4gfCBSZXBvPE0+O1xuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYENvdWxkIG5vdCBmaW5kIHJlcG9zaXRvcnkgcmVnaXN0ZXJlZCB1bmRlciAke25hbWV9YFxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgcmVnaXN0ZXI8TSBleHRlbmRzIE1vZGVsPihcbiAgICBtb2RlbDogQ29uc3RydWN0b3I8TT4sXG4gICAgcmVwbzogQ29uc3RydWN0b3I8UmVwbzxNPj4gfCBSZXBvPE0+XG4gICkge1xuICAgIGNvbnN0IG5hbWUgPSBSZXBvc2l0b3J5LnRhYmxlKG1vZGVsKTtcbiAgICBpZiAobmFtZSBpbiB0aGlzLl9jYWNoZSlcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGAke25hbWV9IGFscmVhZHkgcmVnaXN0ZXJlZCBhcyBhIHJlcG9zaXRvcnlgKTtcbiAgICB0aGlzLl9jYWNoZVtuYW1lXSA9IHJlcG87XG4gIH1cblxuICBzdGF0aWMgc2V0TWV0YWRhdGE8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSwgbWV0YWRhdGE6IGFueSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtb2RlbCwgUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBLCB7XG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIHZhbHVlOiBtZXRhZGF0YSxcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRNZXRhZGF0YTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gICAgY29uc3QgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoXG4gICAgICBtb2RlbCxcbiAgICAgIFBlcnNpc3RlbmNlS2V5cy5NRVRBREFUQVxuICAgICk7XG4gICAgcmV0dXJuIGRlc2NyaXB0b3IgPyBkZXNjcmlwdG9yLnZhbHVlIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgc3RhdGljIHJlbW92ZU1ldGFkYXRhPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0pIHtcbiAgICBjb25zdCBkZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcbiAgICAgIG1vZGVsLFxuICAgICAgUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXG4gICAgKTtcbiAgICBpZiAoZGVzY3JpcHRvcikgZGVsZXRlIChtb2RlbCBhcyBhbnkpW1BlcnNpc3RlbmNlS2V5cy5NRVRBREFUQV07XG4gIH1cblxuICBzdGF0aWMgZ2V0U2VxdWVuY2VPcHRpb25zPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0pIHtcbiAgICBjb25zdCBwayA9IGZpbmRQcmltYXJ5S2V5KG1vZGVsKS5pZDtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoREJLZXlzLklEKSwgbW9kZWwsIHBrKTtcbiAgICBpZiAoIW1ldGFkYXRhKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIFwiTm8gc2VxdWVuY2Ugb3B0aW9ucyBkZWZpbmVkIGZvciBtb2RlbC4gZGlkIHlvdSB1c2UgdGhlIEBwayBkZWNvcmF0b3I/XCJcbiAgICAgICk7XG4gICAgcmV0dXJuIG1ldGFkYXRhIGFzIFNlcXVlbmNlT3B0aW9ucztcbiAgfVxuXG4gIHN0YXRpYyBpbmRleGVzPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0gfCBDb25zdHJ1Y3RvcjxNPikge1xuICAgIGNvbnN0IGluZGV4RGVjb3JhdG9ycyA9IFJlZmxlY3Rpb24uZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgbW9kZWwgaW5zdGFuY2VvZiBNb2RlbCA/IG1vZGVsIDogbmV3IG1vZGVsKCksXG4gICAgICBEQktleXMuUkVGTEVDVFxuICAgICk7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGluZGV4RGVjb3JhdG9ycyB8fCB7fSkucmVkdWNlKFxuICAgICAgKGFjY3VtOiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBJbmRleE1ldGFkYXRhPj4sIFtrLCB2YWxdKSA9PiB7XG4gICAgICAgIGNvbnN0IGRlY3MgPSB2YWwuZmlsdGVyKCh2KSA9PiB2LmtleS5zdGFydHNXaXRoKFBlcnNpc3RlbmNlS2V5cy5JTkRFWCkpO1xuICAgICAgICBpZiAoZGVjcyAmJiBkZWNzLmxlbmd0aCkge1xuICAgICAgICAgIGZvciAoY29uc3QgZGVjIG9mIGRlY3MpIHtcbiAgICAgICAgICAgIGNvbnN0IHsga2V5LCBwcm9wcyB9ID0gZGVjO1xuICAgICAgICAgICAgYWNjdW1ba10gPSBhY2N1bVtrXSB8fCB7fTtcbiAgICAgICAgICAgIGFjY3VtW2tdW2tleV0gPSBwcm9wcyBhcyBJbmRleE1ldGFkYXRhO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LFxuICAgICAge31cbiAgICApO1xuICB9XG5cbiAgc3RhdGljIHJlbGF0aW9uczxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNIHwgQ29uc3RydWN0b3I8TT4pIHtcbiAgICBjb25zdCByZXN1bHQ6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IHByb3RvdHlwZSA9XG4gICAgICBtb2RlbCBpbnN0YW5jZW9mIE1vZGVsXG4gICAgICAgID8gT2JqZWN0LmdldFByb3RvdHlwZU9mKG1vZGVsKVxuICAgICAgICA6IChtb2RlbCBhcyBhbnkpLnByb3RvdHlwZTtcbiAgICB3aGlsZSAocHJvdG90eXBlICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IHByb3BzOiBzdHJpbmdbXSA9IHByb3RvdHlwZVtQZXJzaXN0ZW5jZUtleXMuUkVMQVRJT05TXTtcbiAgICAgIGlmIChwcm9wcykge1xuICAgICAgICByZXN1bHQucHVzaCguLi5wcm9wcyk7XG4gICAgICB9XG4gICAgICBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHN0YXRpYyB0YWJsZTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNIHwgQ29uc3RydWN0b3I8TT4pIHtcbiAgICByZXR1cm4gZ2V0VGFibGVOYW1lKG1vZGVsKTtcbiAgfVxuXG4gIHN0YXRpYyBjb2x1bW48TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSwgYXR0cmlidXRlOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuQ09MVU1OKSxcbiAgICAgIG1vZGVsLFxuICAgICAgYXR0cmlidXRlXG4gICAgKTtcbiAgICByZXR1cm4gbWV0YWRhdGEgPyBtZXRhZGF0YSA6IGF0dHJpYnV0ZTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgaW5qZWN0LCBpbmplY3RhYmxlIH0gZnJvbSBcIkBkZWNhZi10cy9pbmplY3RhYmxlLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IERCS2V5cywgSVJlcG9zaXRvcnkgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5IH0gZnJvbSBcIi4vUmVwb3NpdG9yeVwiO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVwb3NpdG9yeTxUIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogQ29uc3RydWN0b3I8VD4sXG4gIG5hbWVPdmVycmlkZT86IHN0cmluZ1xuKTogYW55IHtcbiAgcmV0dXJuICgob3JpZ2luYWw6IGFueSwgcHJvcGVydHlLZXk/OiBhbnkpID0+IHtcbiAgICBpZiAocHJvcGVydHlLZXkpIHtcbiAgICAgIHJldHVybiBpbmplY3QobmFtZU92ZXJyaWRlIHx8IG1vZGVsLm5hbWUpKG9yaWdpbmFsLCBwcm9wZXJ0eUtleSk7XG4gICAgfVxuXG4gICAgbWV0YWRhdGEoXG4gICAgICBSZXBvc2l0b3J5LmtleShEQktleXMuUkVQT1NJVE9SWSksXG4gICAgICBuYW1lT3ZlcnJpZGUgfHwgb3JpZ2luYWwubmFtZVxuICAgICkobW9kZWwpO1xuICAgIFJlcG9zaXRvcnkucmVnaXN0ZXIobW9kZWwsIG9yaWdpbmFsKTtcbiAgICByZXR1cm4gaW5qZWN0YWJsZShcbiAgICAgIG5hbWVPdmVycmlkZSB8fCBvcmlnaW5hbC5uYW1lLFxuICAgICAgdHJ1ZSxcbiAgICAgIChpbnN0YW5jZTogSVJlcG9zaXRvcnk8VD4pID0+IHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGluc3RhbmNlLCBEQktleXMuQ0xBU1MsIHtcbiAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICB2YWx1ZTogbW9kZWwsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICkob3JpZ2luYWwpO1xuICB9KSBhcyBhbnk7XG59XG4iLCJpbXBvcnQgeyBCYXNlRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGEgZmFpbHVyZSBpbiBvYnNlcnZlciBjb21tdW5pY2F0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1zZyB0aGUgZXJyb3IgbWVzc2FnZVxuICpcbiAqIEBjbGFzcyBPYnNlcnZlckVycm9yXG4gKiBAZXh0ZW5kcyBCYXNlRXJyb3JcbiAqL1xuZXhwb3J0IGNsYXNzIE9ic2VydmVyRXJyb3IgZXh0ZW5kcyBCYXNlRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoT2JzZXJ2ZXJFcnJvci5uYW1lLCBtc2cpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3Rvciwgc2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL0FkYXB0ZXJcIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSB9IGZyb20gXCIuL1JlcG9zaXRvcnlcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlSW5qZWN0YWJsZU5hbWVGb3JSZXBvc2l0b3J5PFQgZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBDb25zdHJ1Y3RvcjxUPiB8IFQsXG4gIGZsYXZvdXI/OiBzdHJpbmdcbikge1xuICBpZiAoIWZsYXZvdXIpIHtcbiAgICBjb25zdCBrZXkgPSBBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuQURBUFRFUik7XG4gICAgZmxhdm91ciA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBrZXksXG4gICAgICBtb2RlbCBpbnN0YW5jZW9mIE1vZGVsID8gbW9kZWwuY29uc3RydWN0b3IgOiBtb2RlbFxuICAgICk7XG4gICAgaWYgKCFmbGF2b3VyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgcmV0cmlldmUgZmxhdm91ciBmcm9tIG1vZGVsICR7bW9kZWwgaW5zdGFuY2VvZiBNb2RlbCA/IG1vZGVsLmNvbnN0cnVjdG9yLm5hbWUgOiBtb2RlbC5uYW1lfWBcbiAgICAgICk7XG4gIH1cbiAgcmV0dXJuIHNmKFBlcnNpc3RlbmNlS2V5cy5JTkpFQ1RBQkxFLCBmbGF2b3VyLCBSZXBvc2l0b3J5LnRhYmxlKG1vZGVsKSk7XG59XG4iLCJpbXBvcnQge1xuICBJbmplY3RhYmxlUmVnaXN0cnlJbXAsXG4gIEluamVjdGFibGVzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2luamVjdGFibGUtZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSB9IGZyb20gXCIuL1JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IE1vZGVsLCBNb2RlbENvbnN0cnVjdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVJbmplY3RhYmxlTmFtZUZvclJlcG9zaXRvcnkgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9BZGFwdGVyXCI7XG5cbmV4cG9ydCBjbGFzcyBJbmplY3RhYmxlc1JlZ2lzdHJ5IGV4dGVuZHMgSW5qZWN0YWJsZVJlZ2lzdHJ5SW1wIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIGdldDxUPihuYW1lOiBzdHJpbmcpOiBUIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgaW5qZWN0YWJsZSA9IHN1cGVyLmdldChuYW1lKTtcbiAgICBpZiAoIWluamVjdGFibGUpXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBtID0gTW9kZWwuZ2V0KG5hbWUpO1xuICAgICAgICBpZiAobSkgaW5qZWN0YWJsZSA9IFJlcG9zaXRvcnkuZm9yTW9kZWwobSk7XG4gICAgICAgIGlmIChpbmplY3RhYmxlKSB7XG4gICAgICAgICAgaWYgKGluamVjdGFibGUgaW5zdGFuY2VvZiBSZXBvc2l0b3J5KSByZXR1cm4gaW5qZWN0YWJsZSBhcyBUO1xuICAgICAgICAgIGNvbnN0IGZsYXZvdXIgPVxuICAgICAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgICAgICAgQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLFxuICAgICAgICAgICAgICBpbmplY3RhYmxlLmNvbnN0cnVjdG9yXG4gICAgICAgICAgICApIHx8XG4gICAgICAgICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgICAgICBBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuQURBUFRFUiksXG4gICAgICAgICAgICAgIG0gYXMgTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+XG4gICAgICAgICAgICApO1xuICAgICAgICAgIEluamVjdGFibGVzLnJlZ2lzdGVyKFxuICAgICAgICAgICAgaW5qZWN0YWJsZSxcbiAgICAgICAgICAgIGdlbmVyYXRlSW5qZWN0YWJsZU5hbWVGb3JSZXBvc2l0b3J5KFxuICAgICAgICAgICAgICBtIGFzIE1vZGVsQ29uc3RydWN0b3I8YW55PixcbiAgICAgICAgICAgICAgZmxhdm91clxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgcmV0dXJuIGluamVjdGFibGUgYXMgVCB8IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiLyoqXG4gKiBAdHlwZWRlZiBTZXF1ZW5jZU9wdGlvbnNcbiAqXG4gKiBAcHJvcCB7c3RyaW5nIHwgbnVtYmVyfSBbc3RhcnRpbmdWYWx1ZV0gZGVmaW5lcyB0aGUgc3RhcnRpbmcgdmFsdWUgd2hlbiBzZXF1ZW5jZSBkb2VzdCBub3QgZXhpc3RcbiAqXG4gKiBAY2F0ZWdvcnkgU2VxdWVuY2VzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VxdWVuY2VPcHRpb25zIHtcbiAgbmFtZT86IHN0cmluZztcbiAgdHlwZTogXCJOdW1iZXJcIiB8IFwiQmlnSW50XCIgfCB1bmRlZmluZWQ7XG4gIHN0YXJ0V2l0aDogbnVtYmVyO1xuICBpbmNyZW1lbnRCeTogbnVtYmVyO1xuICBtaW5WYWx1ZT86IG51bWJlcjtcbiAgbWF4VmFsdWU/OiBudW1iZXI7XG4gIGN5Y2xlOiBib29sZWFuO1xufVxuXG5leHBvcnQgY29uc3QgRGVmYXVsdFNlcXVlbmNlT3B0aW9uczogU2VxdWVuY2VPcHRpb25zID0ge1xuICB0eXBlOiBcIk51bWJlclwiLFxuICBzdGFydFdpdGg6IDAsXG4gIGluY3JlbWVudEJ5OiAxLFxuICBjeWNsZTogZmFsc2UsXG59O1xuXG5leHBvcnQgY29uc3QgTnVtZXJpY1NlcXVlbmNlOiBTZXF1ZW5jZU9wdGlvbnMgPSB7XG4gIHR5cGU6IFwiTnVtYmVyXCIsXG4gIHN0YXJ0V2l0aDogMCxcbiAgaW5jcmVtZW50Qnk6IDEsXG4gIGN5Y2xlOiBmYWxzZSxcbn07XG5cbmV4cG9ydCBjb25zdCBCaWdJbnRTZXF1ZW5jZTogU2VxdWVuY2VPcHRpb25zID0ge1xuICB0eXBlOiBcIkJpZ0ludFwiLFxuICBzdGFydFdpdGg6IDAsXG4gIGluY3JlbWVudEJ5OiAxLFxuICBjeWNsZTogZmFsc2UsXG59O1xuIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlLCBTdXBwcmVzc2VkRXJyb3IsIFN5bWJvbCwgSXRlcmF0b3IgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXNEZWNvcmF0ZShjdG9yLCBkZXNjcmlwdG9ySW4sIGRlY29yYXRvcnMsIGNvbnRleHRJbiwgaW5pdGlhbGl6ZXJzLCBleHRyYUluaXRpYWxpemVycykge1xyXG4gICAgZnVuY3Rpb24gYWNjZXB0KGYpIHsgaWYgKGYgIT09IHZvaWQgMCAmJiB0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRnVuY3Rpb24gZXhwZWN0ZWRcIik7IHJldHVybiBmOyB9XHJcbiAgICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xyXG4gICAgdmFyIHRhcmdldCA9ICFkZXNjcmlwdG9ySW4gJiYgY3RvciA/IGNvbnRleHRJbltcInN0YXRpY1wiXSA/IGN0b3IgOiBjdG9yLnByb3RvdHlwZSA6IG51bGw7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JJbiB8fCAodGFyZ2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGNvbnRleHRJbi5uYW1lKSA6IHt9KTtcclxuICAgIHZhciBfLCBkb25lID0gZmFsc2U7XHJcbiAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHZhciBjb250ZXh0ID0ge307XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4uYWNjZXNzKSBjb250ZXh0LmFjY2Vzc1twXSA9IGNvbnRleHRJbi5hY2Nlc3NbcF07XHJcbiAgICAgICAgY29udGV4dC5hZGRJbml0aWFsaXplciA9IGZ1bmN0aW9uIChmKSB7IGlmIChkb25lKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGFkZCBpbml0aWFsaXplcnMgYWZ0ZXIgZGVjb3JhdGlvbiBoYXMgY29tcGxldGVkXCIpOyBleHRyYUluaXRpYWxpemVycy5wdXNoKGFjY2VwdChmIHx8IG51bGwpKTsgfTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcclxuICAgICAgICBpZiAoa2luZCA9PT0gXCJhY2Nlc3NvclwiKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmdldCkpIGRlc2NyaXB0b3IuZ2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LnNldCkpIGRlc2NyaXB0b3Iuc2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoXyA9IGFjY2VwdChyZXN1bHQpKSB7XHJcbiAgICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xyXG4gICAgICAgICAgICBlbHNlIGRlc2NyaXB0b3Jba2V5XSA9IF87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRhcmdldCkgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgY29udGV4dEluLm5hbWUsIGRlc2NyaXB0b3IpO1xyXG4gICAgZG9uZSA9IHRydWU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19ydW5Jbml0aWFsaXplcnModGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xyXG4gICAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRpYWxpemVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB1c2VWYWx1ZSA/IHZhbHVlIDogdm9pZCAwO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcHJvcEtleSh4KSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCIgPyB4IDogXCJcIi5jb25jYXQoeCk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zZXRGdW5jdGlvbk5hbWUoZiwgbmFtZSwgcHJlZml4KSB7XHJcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XHJcbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGYsIFwibmFtZVwiLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHByZWZpeCA/IFwiXCIuY29uY2F0KHByZWZpeCwgXCIgXCIsIG5hbWUpIDogbmFtZSB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGcgPSBPYmplY3QuY3JlYXRlKCh0eXBlb2YgSXRlcmF0b3IgPT09IFwiZnVuY3Rpb25cIiA/IEl0ZXJhdG9yIDogT2JqZWN0KS5wcm90b3R5cGUpO1xyXG4gICAgcmV0dXJuIGcubmV4dCA9IHZlcmIoMCksIGdbXCJ0aHJvd1wiXSA9IHZlcmIoMSksIGdbXCJyZXR1cm5cIl0gPSB2ZXJiKDIpLCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XHJcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xyXG4gICAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XHJcbiAgICB9XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xyXG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIG9bazJdID0gbVtrXTtcclxufSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xyXG4gICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBpZiAoYXIgfHwgIShpIGluIGZyb20pKSB7XHJcbiAgICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XHJcbiAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IE9iamVjdC5jcmVhdGUoKHR5cGVvZiBBc3luY0l0ZXJhdG9yID09PSBcImZ1bmN0aW9uXCIgPyBBc3luY0l0ZXJhdG9yIDogT2JqZWN0KS5wcm90b3R5cGUpLCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIsIGF3YWl0UmV0dXJuKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gYXdhaXRSZXR1cm4oZikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGYsIHJlamVjdCk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpZiAoZ1tuXSkgeyBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyBpZiAoZikgaVtuXSA9IGYoaVtuXSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbnZhciBvd25LZXlzID0gZnVuY3Rpb24obykge1xyXG4gICAgb3duS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIHx8IGZ1bmN0aW9uIChvKSB7XHJcbiAgICAgICAgdmFyIGFyID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgayBpbiBvKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIGspKSBhclthci5sZW5ndGhdID0gaztcclxuICAgICAgICByZXR1cm4gYXI7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIG93bktleXMobyk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayA9IG93bktleXMobW9kKSwgaSA9IDA7IGkgPCBrLmxlbmd0aDsgaSsrKSBpZiAoa1tpXSAhPT0gXCJkZWZhdWx0XCIpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwga1tpXSk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4oc3RhdGUsIHJlY2VpdmVyKSB7XHJcbiAgICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcclxuICAgIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZShlbnYsIHZhbHVlLCBhc3luYykge1xyXG4gICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB2b2lkIDApIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkLlwiKTtcclxuICAgICAgICB2YXIgZGlzcG9zZSwgaW5uZXI7XHJcbiAgICAgICAgaWYgKGFzeW5jKSB7XHJcbiAgICAgICAgICAgIGlmICghU3ltYm9sLmFzeW5jRGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0Rpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgICAgICBkaXNwb3NlID0gdmFsdWVbU3ltYm9sLmFzeW5jRGlzcG9zZV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkaXNwb3NlID09PSB2b2lkIDApIHtcclxuICAgICAgICAgICAgaWYgKCFTeW1ib2wuZGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5kaXNwb3NlIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5kaXNwb3NlXTtcclxuICAgICAgICAgICAgaWYgKGFzeW5jKSBpbm5lciA9IGRpc3Bvc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0eXBlb2YgZGlzcG9zZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IG5vdCBkaXNwb3NhYmxlLlwiKTtcclxuICAgICAgICBpZiAoaW5uZXIpIGRpc3Bvc2UgPSBmdW5jdGlvbigpIHsgdHJ5IHsgaW5uZXIuY2FsbCh0aGlzKTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7IH0gfTtcclxuICAgICAgICBlbnYuc3RhY2sucHVzaCh7IHZhbHVlOiB2YWx1ZSwgZGlzcG9zZTogZGlzcG9zZSwgYXN5bmM6IGFzeW5jIH0pO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoYXN5bmMpIHtcclxuICAgICAgICBlbnYuc3RhY2sucHVzaCh7IGFzeW5jOiB0cnVlIH0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG5cclxufVxyXG5cclxudmFyIF9TdXBwcmVzc2VkRXJyb3IgPSB0eXBlb2YgU3VwcHJlc3NlZEVycm9yID09PSBcImZ1bmN0aW9uXCIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbiAoZXJyb3IsIHN1cHByZXNzZWQsIG1lc3NhZ2UpIHtcclxuICAgIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG4gICAgcmV0dXJuIGUubmFtZSA9IFwiU3VwcHJlc3NlZEVycm9yXCIsIGUuZXJyb3IgPSBlcnJvciwgZS5zdXBwcmVzc2VkID0gc3VwcHJlc3NlZCwgZTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2Rpc3Bvc2VSZXNvdXJjZXMoZW52KSB7XHJcbiAgICBmdW5jdGlvbiBmYWlsKGUpIHtcclxuICAgICAgICBlbnYuZXJyb3IgPSBlbnYuaGFzRXJyb3IgPyBuZXcgX1N1cHByZXNzZWRFcnJvcihlLCBlbnYuZXJyb3IsIFwiQW4gZXJyb3Igd2FzIHN1cHByZXNzZWQgZHVyaW5nIGRpc3Bvc2FsLlwiKSA6IGU7XHJcbiAgICAgICAgZW52Lmhhc0Vycm9yID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHZhciByLCBzID0gMDtcclxuICAgIGZ1bmN0aW9uIG5leHQoKSB7XHJcbiAgICAgICAgd2hpbGUgKHIgPSBlbnYuc3RhY2sucG9wKCkpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmICghci5hc3luYyAmJiBzID09PSAxKSByZXR1cm4gcyA9IDAsIGVudi5zdGFjay5wdXNoKHIpLCBQcm9taXNlLnJlc29sdmUoKS50aGVuKG5leHQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHIuZGlzcG9zZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSByLmRpc3Bvc2UuY2FsbChyLnZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoci5hc3luYykgcmV0dXJuIHMgfD0gMiwgUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCkudGhlbihuZXh0LCBmdW5jdGlvbihlKSB7IGZhaWwoZSk7IHJldHVybiBuZXh0KCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBzIHw9IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGZhaWwoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHMgPT09IDEpIHJldHVybiBlbnYuaGFzRXJyb3IgPyBQcm9taXNlLnJlamVjdChlbnYuZXJyb3IpIDogUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgaWYgKGVudi5oYXNFcnJvcikgdGhyb3cgZW52LmVycm9yO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5leHQoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uKHBhdGgsIHByZXNlcnZlSnN4KSB7XHJcbiAgICBpZiAodHlwZW9mIHBhdGggPT09IFwic3RyaW5nXCIgJiYgL15cXC5cXC4/XFwvLy50ZXN0KHBhdGgpKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhdGgucmVwbGFjZSgvXFwuKHRzeCkkfCgoPzpcXC5kKT8pKCg/OlxcLlteLi9dKz8pPylcXC4oW2NtXT8pdHMkL2ksIGZ1bmN0aW9uIChtLCB0c3gsIGQsIGV4dCwgY20pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRzeCA/IHByZXNlcnZlSnN4ID8gXCIuanN4XCIgOiBcIi5qc1wiIDogZCAmJiAoIWV4dCB8fCAhY20pID8gbSA6IChkICsgZXh0ICsgXCIuXCIgKyBjbS50b0xvd2VyQ2FzZSgpICsgXCJqc1wiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBwYXRoO1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcbiAgICBfX2V4dGVuZHM6IF9fZXh0ZW5kcyxcclxuICAgIF9fYXNzaWduOiBfX2Fzc2lnbixcclxuICAgIF9fcmVzdDogX19yZXN0LFxyXG4gICAgX19kZWNvcmF0ZTogX19kZWNvcmF0ZSxcclxuICAgIF9fcGFyYW06IF9fcGFyYW0sXHJcbiAgICBfX2VzRGVjb3JhdGU6IF9fZXNEZWNvcmF0ZSxcclxuICAgIF9fcnVuSW5pdGlhbGl6ZXJzOiBfX3J1bkluaXRpYWxpemVycyxcclxuICAgIF9fcHJvcEtleTogX19wcm9wS2V5LFxyXG4gICAgX19zZXRGdW5jdGlvbk5hbWU6IF9fc2V0RnVuY3Rpb25OYW1lLFxyXG4gICAgX19tZXRhZGF0YTogX19tZXRhZGF0YSxcclxuICAgIF9fYXdhaXRlcjogX19hd2FpdGVyLFxyXG4gICAgX19nZW5lcmF0b3I6IF9fZ2VuZXJhdG9yLFxyXG4gICAgX19jcmVhdGVCaW5kaW5nOiBfX2NyZWF0ZUJpbmRpbmcsXHJcbiAgICBfX2V4cG9ydFN0YXI6IF9fZXhwb3J0U3RhcixcclxuICAgIF9fdmFsdWVzOiBfX3ZhbHVlcyxcclxuICAgIF9fcmVhZDogX19yZWFkLFxyXG4gICAgX19zcHJlYWQ6IF9fc3ByZWFkLFxyXG4gICAgX19zcHJlYWRBcnJheXM6IF9fc3ByZWFkQXJyYXlzLFxyXG4gICAgX19zcHJlYWRBcnJheTogX19zcHJlYWRBcnJheSxcclxuICAgIF9fYXdhaXQ6IF9fYXdhaXQsXHJcbiAgICBfX2FzeW5jR2VuZXJhdG9yOiBfX2FzeW5jR2VuZXJhdG9yLFxyXG4gICAgX19hc3luY0RlbGVnYXRvcjogX19hc3luY0RlbGVnYXRvcixcclxuICAgIF9fYXN5bmNWYWx1ZXM6IF9fYXN5bmNWYWx1ZXMsXHJcbiAgICBfX21ha2VUZW1wbGF0ZU9iamVjdDogX19tYWtlVGVtcGxhdGVPYmplY3QsXHJcbiAgICBfX2ltcG9ydFN0YXI6IF9faW1wb3J0U3RhcixcclxuICAgIF9faW1wb3J0RGVmYXVsdDogX19pbXBvcnREZWZhdWx0LFxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldDogX19jbGFzc1ByaXZhdGVGaWVsZEdldCxcclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQ6IF9fY2xhc3NQcml2YXRlRmllbGRTZXQsXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkSW46IF9fY2xhc3NQcml2YXRlRmllbGRJbixcclxuICAgIF9fYWRkRGlzcG9zYWJsZVJlc291cmNlOiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZSxcclxuICAgIF9fZGlzcG9zZVJlc291cmNlczogX19kaXNwb3NlUmVzb3VyY2VzLFxyXG4gICAgX19yZXdyaXRlUmVsYXRpdmVJbXBvcnRFeHRlbnNpb246IF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uLFxyXG59O1xyXG4iLCJpbXBvcnQgeyBCYXNlRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGNsYXNzIFF1ZXJ5RXJyb3IgZXh0ZW5kcyBCYXNlRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoUXVlcnlFcnJvci5uYW1lLCBtc2cpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQYWdpbmdFcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihQYWdpbmdFcnJvci5uYW1lLCBtc2cpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBBdHRyaWJ1dGVPcHRpb24sIENvbmRpdGlvbkJ1aWxkZXJPcHRpb24gfSBmcm9tIFwiLi9vcHRpb25zXCI7XG5pbXBvcnQge1xuICBNb2RlbCxcbiAgTW9kZWxFcnJvckRlZmluaXRpb24sXG4gIHJlcXVpcmVkLFxuICBzZixcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgR3JvdXBPcGVyYXRvciwgT3BlcmF0b3IgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFF1ZXJ5RXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBDb25kaXRpb24gQ2xhc3NcbiAqIEBkZXNjcmlwdGlvbiBSZXByZXNlbnRzIGEgbG9naWNhbCBjb25kaXRpb25cbiAqXG4gKiBAcGFyYW0ge3N0cmluZyB8IENvbmRpdGlvbn0gYXR0cjFcbiAqIEBwYXJhbSB7T3BlcmF0b3IgfCBHcm91cE9wZXJhdG9yfSBvcGVyYXRvclxuICogQHBhcmFtIHtzdHJpbmcgfCBDb25kaXRpb259IGNvbXBhcmlzb25cbiAqXG4gKiBAY2xhc3MgQ29uZGl0aW9uXG4gKiBAaW1wbGVtZW50cyBFeGVjdXRvclxuICpcbiAqIEBjYXRlZ29yeSBRdWVyeVxuICogQHN1YmNhdGVnb3J5IENvbmRpdGlvbnNcbiAqL1xuXG5leHBvcnQgY2xhc3MgQ29uZGl0aW9uIGV4dGVuZHMgTW9kZWwge1xuICBAcmVxdWlyZWQoKVxuICBwcm90ZWN0ZWQgYXR0cjE/OiBzdHJpbmcgfCBDb25kaXRpb24gPSB1bmRlZmluZWQ7XG4gIEByZXF1aXJlZCgpXG4gIHByb3RlY3RlZCBvcGVyYXRvcj86IE9wZXJhdG9yIHwgR3JvdXBPcGVyYXRvciA9IHVuZGVmaW5lZDtcbiAgQHJlcXVpcmVkKClcbiAgcHJvdGVjdGVkIGNvbXBhcmlzb24/OiBhbnkgPSB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihcbiAgICBhdHRyMTogc3RyaW5nIHwgQ29uZGl0aW9uLFxuICAgIG9wZXJhdG9yOiBPcGVyYXRvciB8IEdyb3VwT3BlcmF0b3IsXG4gICAgY29tcGFyaXNvbjogYW55XG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5hdHRyMSA9IGF0dHIxO1xuICAgIHRoaXMub3BlcmF0b3IgPSBvcGVyYXRvcjtcbiAgICB0aGlzLmNvbXBhcmlzb24gPSBjb21wYXJpc29uO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEpvaW5zIDIge0BsaW5rIENvbmRpdGlvbn1zIG9uIGFuIHtAbGluayBPcGVyYXRvciNBTkR9IG9wZXJhdGlvblxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbn0gY29uZGl0aW9uXG4gICAqL1xuICBhbmQoY29uZGl0aW9uOiBDb25kaXRpb24pOiBDb25kaXRpb24ge1xuICAgIHJldHVybiBDb25kaXRpb24uYW5kKHRoaXMsIGNvbmRpdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgSm9pbnMgMiB7QGxpbmsgQ29uZGl0aW9ufXMgb24gYW4ge0BsaW5rIE9wZXJhdG9yI09SfSBvcGVyYXRpb25cbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvblxuICAgKi9cbiAgb3IoY29uZGl0aW9uOiBDb25kaXRpb24pOiBDb25kaXRpb24ge1xuICAgIHJldHVybiBDb25kaXRpb24ub3IodGhpcywgY29uZGl0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBleGNsdWRlcyBhIHZhbHV0IGZyb20gdGhlIHJlc3VsdFxuICAgKiBAcGFyYW0gdmFsXG4gICAqL1xuICBub3QodmFsOiBhbnkpOiBDb25kaXRpb24ge1xuICAgIHJldHVybiBuZXcgQ29uZGl0aW9uKHRoaXMsIE9wZXJhdG9yLk5PVCwgdmFsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgaGFzRXJyb3JzKC4uLmV4Y2VwdGlvbnM6IHN0cmluZ1tdKTogTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGVycm9ycyA9IHN1cGVyLmhhc0Vycm9ycyguLi5leGNlcHRpb25zKTtcbiAgICBpZiAoZXJyb3JzKSByZXR1cm4gZXJyb3JzO1xuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmF0dHIxID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBpZiAodGhpcy5jb21wYXJpc29uIGluc3RhbmNlb2YgQ29uZGl0aW9uKVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbXBhcmlzb246IHtcbiAgICAgICAgICAgIGNvbmRpdGlvbjogXCJCb3RoIHNpZGVzIG9mIHRoZSBjb21wYXJpc29uIG11c3QgYmUgb2YgdGhlIHNhbWUgdHlwZVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgTW9kZWxFcnJvckRlZmluaXRpb247XG4gICAgICBpZiAoT2JqZWN0LnZhbHVlcyhPcGVyYXRvcikuaW5kZXhPZih0aGlzLm9wZXJhdG9yIGFzIE9wZXJhdG9yKSA9PT0gLTEpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgb3BlcmF0b3I6IHtcbiAgICAgICAgICAgIGNvbmRpdGlvbjogc2YoXCJJbnZhbGlkIG9wZXJhdG9yIHswfVwiLCB0aGlzLm9wZXJhdG9yIGFzIHN0cmluZyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBNb2RlbEVycm9yRGVmaW5pdGlvbjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hdHRyMSBpbnN0YW5jZW9mIENvbmRpdGlvbikge1xuICAgICAgaWYgKFxuICAgICAgICAhKHRoaXMuY29tcGFyaXNvbiBpbnN0YW5jZW9mIENvbmRpdGlvbikgJiZcbiAgICAgICAgdGhpcy5vcGVyYXRvciAhPT0gT3BlcmF0b3IuTk9UXG4gICAgICApXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29tcGFyaXNvbjoge1xuICAgICAgICAgICAgY29uZGl0aW9uOiBzZihcIkludmFsaWQgb3BlcmF0b3IgezB9XCIsIHRoaXMub3BlcmF0b3IgYXMgc3RyaW5nKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIE1vZGVsRXJyb3JEZWZpbml0aW9uO1xuICAgICAgaWYgKFxuICAgICAgICBPYmplY3QudmFsdWVzKEdyb3VwT3BlcmF0b3IpLmluZGV4T2YodGhpcy5vcGVyYXRvciBhcyBHcm91cE9wZXJhdG9yKSA9PT1cbiAgICAgICAgICAtMSAmJlxuICAgICAgICB0aGlzLm9wZXJhdG9yICE9PSBPcGVyYXRvci5OT1RcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvcGVyYXRvcjoge1xuICAgICAgICAgICAgY29uZGl0aW9uOiBzZihcIkludmFsaWQgb3BlcmF0b3IgezB9XCIsIHRoaXMub3BlcmF0b3IgYXMgc3RyaW5nKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIE1vZGVsRXJyb3JEZWZpbml0aW9uO1xuICAgICAgLy8gaWYgKHRoaXMub3BlcmF0b3IgIT09IE9wZXJhdG9yLk5PVCAmJiB0eXBlb2YgdGhpcy5hdHRyMS5hdHRyMSAhPT0gXCJzdHJpbmdcIilcbiAgICAgIC8vICAgICByZXR1cm4ge1xuICAgICAgLy8gICAgICAgICBhdHRyMToge1xuICAgICAgLy8gICAgICAgICAgICAgY29uZGl0aW9uOiBzdHJpbmdGb3JtYXQoXCJQYXJlbnQgY29uZGl0aW9uIGF0dHJpYnV0ZSBtdXN0IGJlIGEgc3RyaW5nXCIpXG4gICAgICAvLyAgICAgICAgIH1cbiAgICAgIC8vICAgICB9IGFzIE1vZGVsRXJyb3JEZWZpbml0aW9uXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEpvaW5zIDIge0BsaW5rIENvbmRpdGlvbn1zIG9uIGFuIHtAbGluayBPcGVyYXRvciNBTkR9IG9wZXJhdGlvblxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbn0gY29uZGl0aW9uMVxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbn0gY29uZGl0aW9uMlxuICAgKi9cbiAgc3RhdGljIGFuZChjb25kaXRpb24xOiBDb25kaXRpb24sIGNvbmRpdGlvbjI6IENvbmRpdGlvbik6IENvbmRpdGlvbiB7XG4gICAgcmV0dXJuIENvbmRpdGlvbi5ncm91cChjb25kaXRpb24xLCBHcm91cE9wZXJhdG9yLkFORCwgY29uZGl0aW9uMik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgSm9pbnMgMiB7QGxpbmsgQ29uZGl0aW9ufXMgb24gYW4ge0BsaW5rIE9wZXJhdG9yI09SfSBvcGVyYXRpb25cbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvbjFcbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvbjJcbiAgICovXG4gIHN0YXRpYyBvcihjb25kaXRpb24xOiBDb25kaXRpb24sIGNvbmRpdGlvbjI6IENvbmRpdGlvbik6IENvbmRpdGlvbiB7XG4gICAgcmV0dXJuIENvbmRpdGlvbi5ncm91cChjb25kaXRpb24xLCBHcm91cE9wZXJhdG9yLk9SLCBjb25kaXRpb24yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBHcm91cHMgMiB7QGxpbmsgQ29uZGl0aW9ufXMgYnkgdGhlIHNwZWNpZmllZCB7QGxpbmsgR3JvdXBPcGVyYXRvcn1cbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvbjFcbiAgICogQHBhcmFtIHtHcm91cE9wZXJhdG9yfSBvcGVyYXRvclxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbn0gY29uZGl0aW9uMlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ3JvdXAoXG4gICAgY29uZGl0aW9uMTogQ29uZGl0aW9uLFxuICAgIG9wZXJhdG9yOiBHcm91cE9wZXJhdG9yLFxuICAgIGNvbmRpdGlvbjI6IENvbmRpdGlvblxuICApOiBDb25kaXRpb24ge1xuICAgIHJldHVybiBuZXcgQ29uZGl0aW9uKGNvbmRpdGlvbjEsIG9wZXJhdG9yLCBjb25kaXRpb24yKTtcbiAgfVxuXG4gIHN0YXRpYyBhdHRyaWJ1dGUoYXR0cjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBDb25kaXRpb24uQnVpbGRlcigpLmF0dHJpYnV0ZShhdHRyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBDb25kaXRpb24gQnVpbGRlciBDbGFzc1xuICAgKiBAZGVzY3JpcHRpb24gcHJvdmlkZXMgYSBzaW1wbGUgQVBJIHRvIGJ1aWxkIHtAbGluayBDb25kaXRpb259c1xuICAgKlxuICAgKiBAY2xhc3MgQ29uZGl0aW9uQnVpbGRlclxuICAgKiBAaW1wbGVtZW50cyBCdWlsZGVyXG4gICAqIEBpbXBsZW1lbnRzIEF0dHJpYnV0ZU9wdGlvblxuICAgKlxuICAgKiBAY2F0ZWdvcnkgUXVlcnlcbiAgICogQHN1YmNhdGVnb3J5IENvbmRpdGlvbnNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIEJ1aWxkZXIgPSBjbGFzcyBDb25kaXRpb25CdWlsZGVyXG4gICAgaW1wbGVtZW50cyBDb25kaXRpb25CdWlsZGVyT3B0aW9uLCBBdHRyaWJ1dGVPcHRpb25cbiAge1xuICAgIGF0dHIxPzogc3RyaW5nIHwgQ29uZGl0aW9uID0gdW5kZWZpbmVkO1xuICAgIG9wZXJhdG9yPzogT3BlcmF0b3IgfCBHcm91cE9wZXJhdG9yID0gdW5kZWZpbmVkO1xuICAgIGNvbXBhcmlzb24/OiBhbnkgPSB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaW5oZXJpdERvY1xuICAgICAqL1xuICAgIGF0dHJpYnV0ZShhdHRyOiBzdHJpbmcpOiBBdHRyaWJ1dGVPcHRpb24ge1xuICAgICAgdGhpcy5hdHRyMSA9IGF0dHI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGFuIEVxdWFsaXR5IENvbXBhcmlzb25cbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsXG4gICAgICovXG4gICAgZXEodmFsOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldE9wKE9wZXJhdG9yLkVRVUFMLCB2YWwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBEaWZmZXJlbnQgQ29tcGFyaXNvblxuICAgICAqIEBwYXJhbSB7YW55fSB2YWxcbiAgICAgKi9cbiAgICBkaWYodmFsOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldE9wKE9wZXJhdG9yLkRJRkZFUkVOVCwgdmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgR3JlYXRlciBUaGFuIENvbXBhcmlzb25cbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsXG4gICAgICovXG4gICAgZ3QodmFsOiBhbnkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldE9wKE9wZXJhdG9yLkJJR0dFUiwgdmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgTG93ZXIgVGhhbiBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIGx0KHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5TTUFMTEVSLCB2YWwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBHcmVhdGVyIG9yIEVxdWFsIHRvIENvbXBhcmlzb25cbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsXG4gICAgICovXG4gICAgZ3RlKHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5CSUdHRVJfRVEsIHZhbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIExvd2VyIG9yIEVxdWFsIHRvIENvbXBhcmlzb25cbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsXG4gICAgICovXG4gICAgbHRlKHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5TTUFMTEVSX0VRLCB2YWwpO1xuICAgIH1cblxuICAgIGluKGFycjogYW55W10pIHtcbiAgICAgIHJldHVybiB0aGlzLnNldE9wKE9wZXJhdG9yLklOLCBhcnIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBSZWdleHBvIENvbXBhcmlzb25cbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsXG4gICAgICovXG4gICAgcmVnZXhwKHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5SRUdFWFAsIG5ldyBSZWdFeHAodmFsKS5zb3VyY2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IENyZWF0ZXMgYW4ge0BsaW5rIE9wZXJhdG9yfSBiYXNlZCBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHtPcGVyYXRvcn0gb3BcbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsXG4gICAgICovXG4gICAgcHJpdmF0ZSBzZXRPcChvcDogT3BlcmF0b3IsIHZhbDogYW55KSB7XG4gICAgICB0aGlzLm9wZXJhdG9yID0gb3A7XG4gICAgICB0aGlzLmNvbXBhcmlzb24gPSB2YWw7XG4gICAgICByZXR1cm4gdGhpcy5idWlsZCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IEJ1aWxkcyB0aGUgRGF0YWJhc2UgT2JqZWN0XG4gICAgICogQHRocm93cyB7UXVlcnlFcnJvcn0gaWYgaXQgZmFpbHMgdG8gYnVpbGQgdGhlIHtAbGluayBDb25kaXRpb259XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGJ1aWxkKCk6IENvbmRpdGlvbiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbmV3IENvbmRpdGlvbihcbiAgICAgICAgICB0aGlzLmF0dHIxIGFzIHN0cmluZyB8IENvbmRpdGlvbixcbiAgICAgICAgICB0aGlzLm9wZXJhdG9yIGFzIE9wZXJhdG9yLFxuICAgICAgICAgIHRoaXMuY29tcGFyaXNvbiBhcyBhbnlcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICB0aHJvdyBuZXcgUXVlcnlFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgc3RhdGljIGdldCBidWlsZGVyKCk6IENvbmRpdGlvbkJ1aWxkZXJPcHRpb24ge1xuICAgIHJldHVybiBuZXcgQ29uZGl0aW9uLkJ1aWxkZXIoKTtcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgQ29uc3RydWN0b3IsXG4gIE1vZGVsLFxuICBWYWxpZGF0aW9uLFxuICBWYWxpZGF0aW9uS2V5cyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUmVwbywgUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L1JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IFJlbGF0aW9uc01ldGFkYXRhIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIGZpbmRQcmltYXJ5S2V5LFxuICBJbnRlcm5hbEVycm9yLFxuICBOb3RGb3VuZEVycm9yLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcbmltcG9ydCB7IENhc2NhZGUgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9jb25zdGFudHNcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBNLFxuICBjb250ZXh0OiBDb250ZXh0PE0+LFxuICByZXBvc2l0b3J5PzogUmVwbzxNPlxuKTogUHJvbWlzZTxNPiB7XG4gIGlmICghcmVwb3NpdG9yeSkge1xuICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gTW9kZWwuZ2V0KG1vZGVsLmNvbnN0cnVjdG9yLm5hbWUpO1xuICAgIGlmICghY29uc3RydWN0b3IpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgQ291bGQgbm90IGZpbmQgbW9kZWwgJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfWApO1xuICAgIHJlcG9zaXRvcnkgPSBSZXBvc2l0b3J5LmZvck1vZGVsKGNvbnN0cnVjdG9yKSBhcyBSZXBvPE0+O1xuICB9XG4gIGlmICh0eXBlb2YgKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3JlcG9zaXRvcnkucGtdID09PSBcInVuZGVmaW5lZFwiKVxuICAgIHJldHVybiByZXBvc2l0b3J5LmNyZWF0ZShtb2RlbCwgY29udGV4dCk7XG4gIGVsc2Uge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcmVwb3NpdG9yeS51cGRhdGUobW9kZWwsIGNvbnRleHQpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIE5vdEZvdW5kRXJyb3IpKSB0aHJvdyBlO1xuICAgICAgcmV0dXJuIHJlcG9zaXRvcnkuY3JlYXRlKG1vZGVsLCBjb250ZXh0KTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvT25lT25DcmVhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TT4sXG4gIFkgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbj4odGhpczogUiwgY29udGV4dDogQ29udGV4dDxNPiwgZGF0YTogWSwga2V5OiBzdHJpbmcsIG1vZGVsOiBNKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb3BlcnR5VmFsdWU6IGFueSA9IChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrZXldO1xuICBpZiAoIXByb3BlcnR5VmFsdWUpIHJldHVybjtcblxuICBpZiAodHlwZW9mIHByb3BlcnR5VmFsdWUgIT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCBpbm5lclJlcG8gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcbiAgICBjb25zdCByZWFkID0gYXdhaXQgaW5uZXJSZXBvLnJlYWQocHJvcGVydHlWYWx1ZSk7XG4gICAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIHByb3BlcnR5VmFsdWUsIHJlYWQpO1xuICAgIChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrZXldID0gcHJvcGVydHlWYWx1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBjb25zdHJ1Y3RvciA9IE1vZGVsLmdldChkYXRhLmNsYXNzKTtcbiAgaWYgKCFjb25zdHJ1Y3RvcilcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgQ291bGQgbm90IGZpbmQgbW9kZWwgJHtkYXRhLmNsYXNzfWApO1xuICBjb25zdCByZXBvOiBSZXBvPGFueT4gPSBSZXBvc2l0b3J5LmZvck1vZGVsKGNvbnN0cnVjdG9yKTtcbiAgY29uc3QgY3JlYXRlZCA9IGF3YWl0IHJlcG8uY3JlYXRlKHByb3BlcnR5VmFsdWUpO1xuICBjb25zdCBwayA9IGZpbmRQcmltYXJ5S2V5KGNyZWF0ZWQpLmlkO1xuICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgY3JlYXRlZFtwa10sIGNyZWF0ZWQpO1xuICAobW9kZWwgYXMgYW55KVtrZXldID0gY3JlYXRlZFtwa107XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb09uZU9uVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0+LFxuICBZIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4+KHRoaXM6IFIsIGNvbnRleHQ6IENvbnRleHQ8TT4sIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9wZXJ0eVZhbHVlOiBhbnkgPSAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XTtcbiAgaWYgKCFwcm9wZXJ0eVZhbHVlKSByZXR1cm47XG4gIGlmIChkYXRhLmNhc2NhZGUudXBkYXRlICE9PSBDYXNjYWRlLkNBU0NBREUpIHJldHVybjtcblxuICBpZiAodHlwZW9mIHByb3BlcnR5VmFsdWUgIT09IFwib2JqZWN0XCIpIHtcbiAgICBjb25zdCBpbm5lclJlcG8gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcbiAgICBjb25zdCByZWFkID0gYXdhaXQgaW5uZXJSZXBvLnJlYWQocHJvcGVydHlWYWx1ZSk7XG4gICAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIHByb3BlcnR5VmFsdWUsIHJlYWQpO1xuICAgIChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrZXldID0gcHJvcGVydHlWYWx1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB1cGRhdGVkID0gYXdhaXQgY3JlYXRlT3JVcGRhdGUoXG4gICAgKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV0sXG4gICAgY29udGV4dFxuICApO1xuICBjb25zdCBwayA9IGZpbmRQcmltYXJ5S2V5KHVwZGF0ZWQpLmlkO1xuICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoXG4gICAgY29udGV4dCxcbiAgICBtb2RlbCxcbiAgICBrZXksXG4gICAgKHVwZGF0ZWQgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcGtdLFxuICAgIHVwZGF0ZWRcbiAgKTtcbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9ICh1cGRhdGVkIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3BrXTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvT25lT25EZWxldGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TT4sXG4gIFkgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbj4odGhpczogUiwgY29udGV4dDogQ29udGV4dDxNPiwgZGF0YTogWSwga2V5OiBzdHJpbmcsIG1vZGVsOiBNKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb3BlcnR5VmFsdWU6IGFueSA9IChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrZXldO1xuICBpZiAoIXByb3BlcnR5VmFsdWUpIHJldHVybjtcbiAgaWYgKGRhdGEuY2FzY2FkZS51cGRhdGUgIT09IENhc2NhZGUuQ0FTQ0FERSkgcmV0dXJuO1xuICBjb25zdCBpbm5lclJlcG86IFJlcG88TT4gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcbiAgbGV0IGRlbGV0ZWQ6IE07XG4gIGlmICghKHByb3BlcnR5VmFsdWUgaW5zdGFuY2VvZiBNb2RlbCkpXG4gICAgZGVsZXRlZCA9IGF3YWl0IGlubmVyUmVwby5kZWxldGUoXG4gICAgICAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSxcbiAgICAgIGNvbnRleHRcbiAgICApO1xuICBlbHNlXG4gICAgZGVsZXRlZCA9IGF3YWl0IGlubmVyUmVwby5kZWxldGUoXG4gICAgICAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XVtpbm5lclJlcG8ucGtdLFxuICAgICAgY29udGV4dFxuICAgICk7XG4gIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShcbiAgICBjb250ZXh0LFxuICAgIG1vZGVsLFxuICAgIGtleSxcbiAgICAoZGVsZXRlZCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtpbm5lclJlcG8ucGtdLFxuICAgIGRlbGV0ZWRcbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvTWFueU9uQ3JlYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0+LFxuICBZIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4+KHRoaXM6IFIsIGNvbnRleHQ6IENvbnRleHQ8TT4sIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9wZXJ0eVZhbHVlczogYW55ID0gKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV07XG4gIGlmICghcHJvcGVydHlWYWx1ZXMgfHwgIXByb3BlcnR5VmFsdWVzLmxlbmd0aCkgcmV0dXJuO1xuICBjb25zdCBhcnJheVR5cGUgPSB0eXBlb2YgcHJvcGVydHlWYWx1ZXNbMF07XG4gIGlmICghcHJvcGVydHlWYWx1ZXMuZXZlcnkoKGl0ZW06IGFueSkgPT4gdHlwZW9mIGl0ZW0gPT09IGFycmF5VHlwZSkpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgSW52YWxpZCBvcGVyYXRpb24uIEFsbCBlbGVtZW50cyBvZiBwcm9wZXJ0eSAke2tleX0gbXVzdCBtYXRjaCB0aGUgc2FtZSB0eXBlLmBcbiAgICApO1xuICBjb25zdCB1bmlxdWVWYWx1ZXMgPSBuZXcgU2V0KFsuLi5wcm9wZXJ0eVZhbHVlc10pO1xuICBpZiAoYXJyYXlUeXBlICE9PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgcmVwbyA9IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhKG1vZGVsLCBrZXkpO1xuICAgIGZvciAoY29uc3QgaWQgb2YgdW5pcXVlVmFsdWVzKSB7XG4gICAgICBjb25zdCByZWFkID0gYXdhaXQgcmVwby5yZWFkKGlkKTtcbiAgICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBpZCwgcmVhZCk7XG4gICAgfVxuICAgIChtb2RlbCBhcyBhbnkpW2tleV0gPSBbLi4udW5pcXVlVmFsdWVzXTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBwa05hbWUgPSBmaW5kUHJpbWFyeUtleShwcm9wZXJ0eVZhbHVlc1swXSkuaWQ7XG5cbiAgY29uc3QgcmVzdWx0OiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcblxuICBmb3IgKGNvbnN0IG0gb2YgcHJvcGVydHlWYWx1ZXMpIHtcbiAgICBjb25zdCByZWNvcmQgPSBhd2FpdCBjcmVhdGVPclVwZGF0ZShtLCBjb250ZXh0KTtcbiAgICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgcmVjb3JkW3BrTmFtZV0sIHJlY29yZCk7XG4gICAgcmVzdWx0LmFkZChyZWNvcmRbcGtOYW1lXSk7XG4gIH1cblxuICAobW9kZWwgYXMgYW55KVtrZXldID0gWy4uLnJlc3VsdF07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb01hbnlPblVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNPixcbiAgWSBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuPih0aGlzOiBSLCBjb250ZXh0OiBDb250ZXh0PE0+LCBkYXRhOiBZLCBrZXk6IHN0cmluZywgbW9kZWw6IE0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBjYXNjYWRlIH0gPSBkYXRhO1xuICBpZiAoY2FzY2FkZS51cGRhdGUgIT09IENhc2NhZGUuQ0FTQ0FERSkgcmV0dXJuO1xuICByZXR1cm4gb25lVG9NYW55T25DcmVhdGUuY2FsbCh0aGlzLCBjb250ZXh0LCBkYXRhLCBrZXksIG1vZGVsKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uZVRvTWFueU9uRGVsZXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0+LFxuICBZIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4+KHRoaXM6IFIsIGNvbnRleHQ6IENvbnRleHQ8TT4sIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoZGF0YS5jYXNjYWRlLmRlbGV0ZSAhPT0gQ2FzY2FkZS5DQVNDQURFKSByZXR1cm47XG4gIGNvbnN0IHZhbHVlcyA9IChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrZXldO1xuICBpZiAoIXZhbHVlcyB8fCAhdmFsdWVzLmxlbmd0aCkgcmV0dXJuO1xuICBjb25zdCBhcnJheVR5cGUgPSB0eXBlb2YgdmFsdWVzWzBdO1xuICBjb25zdCBhcmVBbGxTYW1lVHlwZSA9IHZhbHVlcy5ldmVyeSgoaXRlbTogYW55KSA9PiB0eXBlb2YgaXRlbSA9PT0gYXJyYXlUeXBlKTtcbiAgaWYgKCFhcmVBbGxTYW1lVHlwZSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBJbnZhbGlkIG9wZXJhdGlvbi4gQWxsIGVsZW1lbnRzIG9mIHByb3BlcnR5ICR7a2V5fSBtdXN0IG1hdGNoIHRoZSBzYW1lIHR5cGUuYFxuICAgICk7XG4gIGNvbnN0IGlzSW5zdGFudGlhdGVkID0gYXJyYXlUeXBlID09PSBcIm9iamVjdFwiO1xuICBjb25zdCByZXBvID0gaXNJbnN0YW50aWF0ZWRcbiAgICA/IFJlcG9zaXRvcnkuZm9yTW9kZWwodmFsdWVzWzBdKVxuICAgIDogcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG5cbiAgY29uc3QgdW5pcXVlVmFsdWVzID0gbmV3IFNldChbXG4gICAgLi4uKGlzSW5zdGFudGlhdGVkXG4gICAgICA/IHZhbHVlcy5tYXAoKHY6IFJlY29yZDxzdHJpbmcsIGFueT4pID0+IHZbcmVwby5wa10pXG4gICAgICA6IHZhbHVlcyksXG4gIF0pO1xuXG4gIGZvciAoY29uc3QgaWQgb2YgdW5pcXVlVmFsdWVzLnZhbHVlcygpKSB7XG4gICAgY29uc3QgZGVsZXRlZCA9IGF3YWl0IHJlcG8uZGVsZXRlKGlkLCBjb250ZXh0KTtcbiAgICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgaWQsIGRlbGV0ZWQpO1xuICB9XG4gIChtb2RlbCBhcyBhbnkpW2tleV0gPSBbLi4udW5pcXVlVmFsdWVzXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBvcHVsYXRlS2V5KFxuICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgZmllbGROYW1lOiBzdHJpbmcsXG4gIGlkOiBzdHJpbmcgfCBudW1iZXJcbikge1xuICByZXR1cm4gW1BlcnNpc3RlbmNlS2V5cy5QT1BVTEFURSwgdGFibGVOYW1lLCBmaWVsZE5hbWUsIGlkXS5qb2luKFwiLlwiKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNhY2hlTW9kZWxGb3JQb3B1bGF0ZTxNIGV4dGVuZHMgTW9kZWw+KFxuICBjb250ZXh0OiBDb250ZXh0PE0+LFxuICBwYXJlbnRNb2RlbDogTSxcbiAgcHJvcGVydHlLZXk6IHN0cmluZyxcbiAgcGtWYWx1ZTogc3RyaW5nIHwgbnVtYmVyLFxuICBjYWNoZVZhbHVlOiBhbnlcbikge1xuICBjb25zdCBjYWNoZUtleSA9IGdldFBvcHVsYXRlS2V5KFxuICAgIHBhcmVudE1vZGVsLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgcHJvcGVydHlLZXksXG4gICAgcGtWYWx1ZVxuICApO1xuICByZXR1cm4gY29udGV4dC5wdXQoY2FjaGVLZXksIGNhY2hlVmFsdWUpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcG9wdWxhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TT4sXG4gIFkgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbj4odGhpczogUiwgY29udGV4dDogQ29udGV4dDxNPiwgZGF0YTogWSwga2V5OiBzdHJpbmcsIG1vZGVsOiBNKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICghZGF0YS5wb3B1bGF0ZSkgcmV0dXJuO1xuICBjb25zdCBuZXN0ZWQ6IGFueSA9IChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrZXldO1xuICBjb25zdCBpc0FyciA9IEFycmF5LmlzQXJyYXkobmVzdGVkKTtcbiAgaWYgKHR5cGVvZiBuZXN0ZWQgPT09IFwidW5kZWZpbmVkXCIgfHwgKGlzQXJyICYmIG5lc3RlZC5sZW5ndGggPT09IDApKSByZXR1cm47XG5cbiAgYXN5bmMgZnVuY3Rpb24gZmV0Y2hQb3B1bGF0ZVZhbHVlcyhcbiAgICBjOiBDb250ZXh0PE0+LFxuICAgIG1vZGVsOiBNLFxuICAgIHByb3BOYW1lOiBzdHJpbmcsXG4gICAgcHJvcEtleVZhbHVlczogYW55W11cbiAgKSB7XG4gICAgbGV0IGNhY2hlS2V5OiBzdHJpbmc7XG4gICAgbGV0IHZhbDogYW55O1xuICAgIGNvbnN0IHJlc3VsdHM6IE1bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgcHJvS2V5VmFsdWUgb2YgcHJvcEtleVZhbHVlcykge1xuICAgICAgY2FjaGVLZXkgPSBnZXRQb3B1bGF0ZUtleShtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lLCBwcm9wTmFtZSwgcHJvS2V5VmFsdWUpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsID0gYXdhaXQgYy5nZXQoY2FjaGVLZXkpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgY29uc3QgcmVwbyA9IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhKG1vZGVsLCBwcm9wTmFtZSk7XG4gICAgICAgIGlmICghcmVwbykgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJDb3VsZCBub3QgZmluZCByZXBvXCIpO1xuICAgICAgICB2YWwgPSBhd2FpdCByZXBvLnJlYWQocHJvS2V5VmFsdWUpO1xuICAgICAgfVxuICAgICAgcmVzdWx0cy5wdXNoKHZhbCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG4gIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoUG9wdWxhdGVWYWx1ZXMoXG4gICAgY29udGV4dCxcbiAgICBtb2RlbCxcbiAgICBrZXksXG4gICAgaXNBcnIgPyBuZXN0ZWQgOiBbbmVzdGVkXVxuICApO1xuICAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSA9IGlzQXJyID8gcmVzIDogcmVzWzBdO1xufVxuXG5jb25zdCBjb21tb21UeXBlcyA9IFtcbiAgXCJhcnJheVwiLFxuICBcInN0cmluZ1wiLFxuICBcIm51bWJlclwiLFxuICBcImJvb2xlYW5cIixcbiAgXCJzeW1ib2xcIixcbiAgXCJmdW5jdGlvblwiLFxuICBcIm9iamVjdFwiLFxuICBcInVuZGVmaW5lZFwiLFxuICBcIm51bGxcIixcbiAgXCJiaWdpbnRcIixcbl07XG5cbmV4cG9ydCBmdW5jdGlvbiByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YTxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogYW55LFxuICBwcm9wZXJ0eUtleTogc3RyaW5nXG4pOiBSZXBvPE0+IHtcbiAgY29uc3QgdHlwZXMgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgIFZhbGlkYXRpb24ua2V5KFxuICAgICAgQXJyYXkuaXNBcnJheShtb2RlbFtwcm9wZXJ0eUtleV0pXG4gICAgICAgID8gVmFsaWRhdGlvbktleXMuTElTVFxuICAgICAgICA6IFZhbGlkYXRpb25LZXlzLlRZUEVcbiAgICApLFxuICAgIG1vZGVsLFxuICAgIHByb3BlcnR5S2V5XG4gICk7XG4gIGNvbnN0IGN1c3RvbVR5cGVzOiBhbnkgPSBBcnJheS5pc0FycmF5KG1vZGVsW3Byb3BlcnR5S2V5XSlcbiAgICA/IHR5cGVzLmNsYXp6XG4gICAgOiB0eXBlcy5jdXN0b21UeXBlcztcbiAgaWYgKCF0eXBlcyB8fCAhY3VzdG9tVHlwZXMpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgRmFpbGVkIHRvIGZpbmQgdHlwZXMgZGVjb3JhdG9ycyBmb3IgcHJvcGVydHkgJHtwcm9wZXJ0eUtleX1gXG4gICAgKTtcblxuICBjb25zdCBhbGxvd2VkVHlwZXM6IHN0cmluZ1tdID0gQXJyYXkuaXNBcnJheShjdXN0b21UeXBlcylcbiAgICA/IFsuLi5jdXN0b21UeXBlc11cbiAgICA6IFtjdXN0b21UeXBlc107XG4gIGNvbnN0IGNvbnN0cnVjdG9yTmFtZSA9IGFsbG93ZWRUeXBlcy5maW5kKFxuICAgICh0KSA9PiAhY29tbW9tVHlwZXMuaW5jbHVkZXMoYCR7dH1gLnRvTG93ZXJDYXNlKCkpXG4gICk7XG4gIGlmICghY29uc3RydWN0b3JOYW1lKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYFByb3BlcnR5IGtleSAke3Byb3BlcnR5S2V5fSBkb2VzIG5vdCBoYXZlIGEgdmFsaWQgY29uc3RydWN0b3IgdHlwZWBcbiAgICApO1xuICBjb25zdCBjb25zdHJ1Y3RvcjogQ29uc3RydWN0b3I8TT4gfCB1bmRlZmluZWQgPSBNb2RlbC5nZXQoY29uc3RydWN0b3JOYW1lKTtcbiAgaWYgKCFjb25zdHJ1Y3RvcilcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgTm8gcmVnaXN0ZXJlZCBtb2RlbCBmb3VuZCBmb3IgJHtjb25zdHJ1Y3Rvck5hbWV9YCk7XG5cbiAgcmV0dXJuIFJlcG9zaXRvcnkuZm9yTW9kZWwoY29uc3RydWN0b3IpO1xufVxuIiwiaW1wb3J0IHtcbiAgQ29uZmxpY3RFcnJvcixcbiAgb25DcmVhdGUsXG4gIG9uQ3JlYXRlVXBkYXRlLFxuICBvbkRlbGV0ZSxcbiAgb25VcGRhdGUsXG4gIGFmdGVyQW55LFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IGFwcGx5LCBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ2FzY2FkZU1ldGFkYXRhLCBJbmRleE1ldGFkYXRhIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvdHlwZXNcIjtcbmltcG9ydCB7IERlZmF1bHRDYXNjYWRlLCBPcmRlckRpcmVjdGlvbiB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L2NvbnN0YW50c1wiO1xuaW1wb3J0IHtcbiAgQ29uc3RydWN0b3IsXG4gIGxpc3QsXG4gIE1vZGVsLFxuICBwcm9wLFxuICBwcm9wTWV0YWRhdGEsXG4gIHR5cGUsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvQWRhcHRlclwiO1xuaW1wb3J0IHsgUmVwbywgUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L1JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuLi9xdWVyeS9Db25kaXRpb25cIjtcbmltcG9ydCB7IFJlbGF0aW9uc01ldGFkYXRhIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7XG4gIG9uZVRvTWFueU9uQ3JlYXRlLFxuICBvbmVUb01hbnlPbkRlbGV0ZSxcbiAgb25lVG9NYW55T25VcGRhdGUsXG4gIG9uZVRvT25lT25DcmVhdGUsXG4gIG9uZVRvT25lT25EZWxldGUsXG4gIG9uZVRvT25lT25VcGRhdGUsXG4gIHBvcHVsYXRlIGFzIHBvcCxcbn0gZnJvbSBcIi4vY29uc3RydWN0aW9uXCI7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSBcIi4vVXNlclwiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L0NvbnRleHRcIjtcbmltcG9ydCB7IFVuc3VwcG9ydGVkRXJyb3IgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvZXJyb3JzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiB0YWJsZSh0YWJsZU5hbWU6IHN0cmluZykge1xuICByZXR1cm4gbWV0YWRhdGEoQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLlRBQkxFKSwgdGFibGVOYW1lKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbHVtbihjb2x1bW5OYW1lOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YShBZGFwdGVyLmtleShQZXJzaXN0ZW5jZUtleXMuQ09MVU1OKSwgY29sdW1uTmFtZSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgSW5kZXggRGVjb3JhdG9yXG4gKiBAZGVzY3JpcHRpb24gcHJvcGVydGllcyBkZWNvcmF0ZWQgd2lsbCB0aGUgaW5kZXggaW4gdGhlXG4gKiBEQiBmb3IgcGVyZm9ybWFuY2UgaW4gcXVlcmllc1xuICpcbiAqIEBwYXJhbSB7T3JkZXJEaXJlY3Rpb25bXX0gW2RpcmVjdGlvbnNdXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbY29tcG9zaXRpb25zXVxuICpcbiAqIEBmdW5jdGlvbiBpbmRleFxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5kZXgoZGlyZWN0aW9ucz86IE9yZGVyRGlyZWN0aW9uW10sIGNvbXBvc2l0aW9ucz86IHN0cmluZ1tdKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGEoXG4gICAgUmVwb3NpdG9yeS5rZXkoXG4gICAgICBgJHtQZXJzaXN0ZW5jZUtleXMuSU5ERVh9JHtjb21wb3NpdGlvbnMgJiYgY29tcG9zaXRpb25zLmxlbmd0aCA/IGAuJHtjb21wb3NpdGlvbnMuam9pbihcIi5cIil9YCA6IFwiXCJ9YFxuICAgICksXG4gICAge1xuICAgICAgZGlyZWN0aW9uczogZGlyZWN0aW9ucyxcbiAgICAgIGNvbXBvc2l0aW9uczogY29tcG9zaXRpb25zLFxuICAgIH0gYXMgSW5kZXhNZXRhZGF0YVxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdW5pcXVlT25DcmVhdGVVcGRhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TT4sXG4gIFkgPSBhbnksXG4+KHRoaXM6IFIsIGNvbnRleHQ6IENvbnRleHQ8TT4sIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIShtb2RlbCBhcyBhbnkpW2tleV0pIHJldHVybjtcbiAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCB0aGlzLnNlbGVjdCgpXG4gICAgLndoZXJlKENvbmRpdGlvbi5hdHRyaWJ1dGUoa2V5KS5lcSgobW9kZWwgYXMgYW55KVtrZXldKSlcbiAgICAuZXhlY3V0ZTxNW10+KCk7XG4gIGlmIChleGlzdGluZy5sZW5ndGgpXG4gICAgdGhyb3cgbmV3IENvbmZsaWN0RXJyb3IoXG4gICAgICBgbW9kZWwgYWxyZWFkeSBleGlzdHMgd2l0aCBwcm9wZXJ0eSAke2tleX0gZXF1YWwgdG8gJHtKU09OLnN0cmluZ2lmeSgobW9kZWwgYXMgYW55KVtrZXldLCB1bmRlZmluZWQsIDIpfWBcbiAgICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFVuaXF1ZSBEZWNvcmF0b3JcbiAqIEBkZXNjcmlwdGlvbiBUYWdzIGEgcHJvcGVydHkgYXMgdW5pcXVlLlxuICogIE5vIG90aGVyIGVsZW1lbnRzIGluIHRoYXQgdGFibGUgY2FuIGhhdmUgdGhlIHNhbWUgcHJvcGVydHkgdmFsdWVcbiAqXG4gKiBAZnVuY3Rpb24gdW5pcXVlXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp3YWxsZXQtZGIuRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdW5pcXVlKCkge1xuICByZXR1cm4gYXBwbHkoXG4gICAgb25DcmVhdGVVcGRhdGUodW5pcXVlT25DcmVhdGVVcGRhdGUpLFxuICAgIHByb3BNZXRhZGF0YShSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuVU5JUVVFKSwge30pXG4gICk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVkQnlPbkNyZWF0ZVVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNPixcbiAgWSA9IGFueSxcbj4odGhpczogUiwgY29udGV4dDogQ29udGV4dDxNPiwgZGF0YTogWSwga2V5OiBzdHJpbmcsIG1vZGVsOiBNKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHVzZXI6IFVzZXIgfCB1bmRlZmluZWQgPSBjb250ZXh0LnVzZXI7XG4gIGlmICghdXNlcilcbiAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRFcnJvcihcbiAgICAgIFwiVGhpcyBhZGFwdGVyIGRvZXMgbm90IHN1cHBvcnQgdXNlciBpZGVudGlmaWNhdGlvblwiXG4gICAgKTtcbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9IHVzZXIuaWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVkQnkoKSB7XG4gIHJldHVybiBhcHBseShcbiAgICBvbkNyZWF0ZShjcmVhdGVkQnlPbkNyZWF0ZVVwZGF0ZSksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KFBlcnNpc3RlbmNlS2V5cy5DUkVBVEVEX0JZKSwge30pXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVkQnkoKSB7XG4gIHJldHVybiBhcHBseShcbiAgICBvbkNyZWF0ZVVwZGF0ZShjcmVhdGVkQnlPbkNyZWF0ZVVwZGF0ZSksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KFBlcnNpc3RlbmNlS2V5cy5DUkVBVEVEX0JZKSwge30pXG4gICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgT25lIFRvIE9uZSByZWxhdGlvbiBEZWNvcmF0b3JzXG4gKlxuICogQHBhcmFtIHtDb25zdHJ1Y3Rvcjxhbnk+fSBjbGF6eiB0aGUge0BsaW5rIFNlcXVlbmNlfSB0byB1c2UuIERlZmF1bHRzIHRvIHtAbGluayBOb25lU2VxdWVuY2V9XG4gKiBAcGFyYW0ge0Nhc2NhZGVNZXRhZGF0YX0gW2Nhc2NhZGVPcHRpb25zXVxuICogQHBhcmFtIHtib29sZWFufSBwb3B1bGF0ZSBJZiB0cnVlLCByZXBsYWNlcyB0aGUgc3BlY2lmaWVkIGtleSBpbiB0aGUgZG9jdW1lbnQgd2l0aCB0aGUgY29ycmVzcG9uZGluZyByZWNvcmQgZnJvbSB0aGUgZGF0YWJhc2VcbiAqXG4gKiBAZnVuY3Rpb24gb25Ub09uZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6d2FsbGV0LWRiLkRlY29yYXRvcnNcbiAqXG4gKiBAc2VlIG9uZVRvTWFueVxuICogQHNlZSBtYW55VG9PbmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uZVRvT25lPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIGNsYXp6OiBDb25zdHJ1Y3RvcjxNPixcbiAgY2FzY2FkZU9wdGlvbnM6IENhc2NhZGVNZXRhZGF0YSA9IERlZmF1bHRDYXNjYWRlLFxuICBwb3B1bGF0ZTogYm9vbGVhbiA9IHRydWVcbikge1xuICBNb2RlbC5yZWdpc3RlcihjbGF6eik7XG4gIGNvbnN0IG1ldGFkYXRhOiBSZWxhdGlvbnNNZXRhZGF0YSA9IHtcbiAgICBjbGFzczogY2xhenoubmFtZSxcbiAgICBjYXNjYWRlOiBjYXNjYWRlT3B0aW9ucyxcbiAgICBwb3B1bGF0ZTogcG9wdWxhdGUsXG4gIH07XG4gIHJldHVybiBhcHBseShcbiAgICBwcm9wKFBlcnNpc3RlbmNlS2V5cy5SRUxBVElPTlMpLFxuICAgIHR5cGUoW2NsYXp6Lm5hbWUsIFN0cmluZy5uYW1lLCBOdW1iZXIubmFtZSwgQmlnSW50Lm5hbWVdKSxcbiAgICBvbkNyZWF0ZShvbmVUb09uZU9uQ3JlYXRlLCBtZXRhZGF0YSksXG4gICAgb25VcGRhdGUob25lVG9PbmVPblVwZGF0ZSwgbWV0YWRhdGEpLFxuICAgIG9uRGVsZXRlKG9uZVRvT25lT25EZWxldGUsIG1ldGFkYXRhKSxcbiAgICBhZnRlckFueShwb3AsIG1ldGFkYXRhKSxcbiAgICBwcm9wTWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLk9ORV9UT19PTkUpLCBtZXRhZGF0YSlcbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBPbmUgVG8gTWFueSByZWxhdGlvbiBEZWNvcmF0b3JzXG4gKlxuICogQHBhcmFtIHtDb25zdHJ1Y3Rvcjxhbnk+fSBjbGF6eiB0aGUge0BsaW5rIFNlcXVlbmNlfSB0byB1c2UuIERlZmF1bHRzIHRvIHtAbGluayBOb25lU2VxdWVuY2V9XG4gKiBAcGFyYW0ge0Nhc2NhZGVNZXRhZGF0YX0gW2Nhc2NhZGVPcHRpb25zXVxuICpcbiAqIEBmdW5jdGlvbiBvbmVUb01hbnlcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOndhbGxldC1kYi5EZWNvcmF0b3JzXG4gKlxuICogQHNlZSBvbmVUb09uZVxuICogQHNlZSBtYW55VG9PbmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uZVRvTWFueTxNIGV4dGVuZHMgTW9kZWw+KFxuICBjbGF6ejogQ29uc3RydWN0b3I8TT4sXG4gIGNhc2NhZGVPcHRpb25zOiBDYXNjYWRlTWV0YWRhdGEgPSBEZWZhdWx0Q2FzY2FkZSxcbiAgcG9wdWxhdGU6IGJvb2xlYW4gPSB0cnVlXG4pIHtcbiAgTW9kZWwucmVnaXN0ZXIoY2xhenopO1xuICBjb25zdCBtZXRhZGF0YTogUmVsYXRpb25zTWV0YWRhdGEgPSB7XG4gICAgY2xhc3M6IGNsYXp6Lm5hbWUsXG4gICAgY2FzY2FkZTogY2FzY2FkZU9wdGlvbnMsXG4gICAgcG9wdWxhdGU6IHBvcHVsYXRlLFxuICB9O1xuICByZXR1cm4gYXBwbHkoXG4gICAgcHJvcChQZXJzaXN0ZW5jZUtleXMuUkVMQVRJT05TKSxcbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yIHB1cnBvc2VmdWwgb3ZlcnJpZGVcbiAgICBsaXN0KFtjbGF6eiwgU3RyaW5nLCBOdW1iZXIsIEJpZ0ludF0pLFxuICAgIG9uQ3JlYXRlKG9uZVRvTWFueU9uQ3JlYXRlLCBtZXRhZGF0YSksXG4gICAgb25VcGRhdGUob25lVG9NYW55T25VcGRhdGUsIG1ldGFkYXRhKSxcbiAgICBvbkRlbGV0ZShvbmVUb01hbnlPbkRlbGV0ZSwgbWV0YWRhdGEpLFxuICAgIGFmdGVyQW55KHBvcCwgbWV0YWRhdGEpLFxuICAgIHByb3BNZXRhZGF0YShSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuT05FX1RPX01BTlkpLCBtZXRhZGF0YSlcbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBNYW55IFRvIE9uZSByZWxhdGlvbiBEZWNvcmF0b3JzXG4gKlxuICogQHBhcmFtIHtDb25zdHJ1Y3Rvcjxhbnk+fSBjbGF6eiB0aGUge0BsaW5rIFNlcXVlbmNlfSB0byB1c2UuIERlZmF1bHRzIHRvIHtAbGluayBOb25lU2VxdWVuY2V9XG4gKiBAcGFyYW0ge0Nhc2NhZGVNZXRhZGF0YX0gW2Nhc2NhZGVPcHRpb25zXVxuICpcbiAqIEBmdW5jdGlvbiBtYW55VG9PbmVcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOndhbGxldC1kYi5EZWNvcmF0b3JzXG4gKlxuICogQHNlZSBvbmVUb01hbnlcbiAqIEBzZWUgb25lVG9PbmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hbnlUb09uZShcbiAgY2xheno6IENvbnN0cnVjdG9yPGFueT4sXG4gIGNhc2NhZGVPcHRpb25zOiBDYXNjYWRlTWV0YWRhdGEgPSBEZWZhdWx0Q2FzY2FkZSxcbiAgcG9wdWxhdGUgPSB0cnVlXG4pIHtcbiAgTW9kZWwucmVnaXN0ZXIoY2xhenopO1xuICBjb25zdCBtZXRhZGF0YTogUmVsYXRpb25zTWV0YWRhdGEgPSB7XG4gICAgY2xhc3M6IGNsYXp6Lm5hbWUsXG4gICAgY2FzY2FkZTogY2FzY2FkZU9wdGlvbnMsXG4gICAgcG9wdWxhdGU6IHBvcHVsYXRlLFxuICB9O1xuICByZXR1cm4gYXBwbHkoXG4gICAgcHJvcChQZXJzaXN0ZW5jZUtleXMuUkVMQVRJT05TKSxcbiAgICB0eXBlKFtjbGF6ei5uYW1lLCBTdHJpbmcubmFtZSwgTnVtYmVyLm5hbWUsIEJpZ0ludC5uYW1lXSksXG4gICAgLy8gb25DcmVhdGUob25lVG9NYW55T25DcmVhdGUsIG1ldGFkYXRhKSxcbiAgICAvLyBvblVwZGF0ZShvbmVUb01hbnlPblVwZGF0ZSwgbWV0YWRhdGEpLFxuICAgIC8vIG9uRGVsZXRlKG9uZVRvTWFueU9uRGVsZXRlLCBtZXRhZGF0YSksXG4gICAgLy8gYWZ0ZXJBbGwocG9wdWxhdGUsIG1ldGFkYXRhKSxcbiAgICBwcm9wTWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLk1BTllfVE9fT05FKSwgbWV0YWRhdGEpXG4gICk7XG59XG4iLCJpbXBvcnQgeyBNb2RlbCwgcHJvcE1ldGFkYXRhLCByZXF1aXJlZCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7XG4gIERlZmF1bHRTZXF1ZW5jZU9wdGlvbnMsXG4gIFNlcXVlbmNlT3B0aW9ucyxcbn0gZnJvbSBcIi4uL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zXCI7XG5pbXBvcnQge1xuICBEQktleXMsXG4gIEludGVybmFsRXJyb3IsXG4gIG9uQ3JlYXRlLFxuICByZWFkb25seSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBhcHBseSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgUmVwbywgUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L1JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IGluZGV4IH0gZnJvbSBcIi4uL21vZGVsL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IHNlcXVlbmNlTmFtZUZvck1vZGVsIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IFNlcXVlbmNlIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL1NlcXVlbmNlXCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBPcmRlckRpcmVjdGlvbiB9IGZyb20gXCIuLi9yZXBvc2l0b3J5XCI7XG5cbi8qKlxuICogQHN1bW1hcnkgUHJpbWFyeSBLZXkgRGVjb3JhdG9yXG4gKiBAZGVzY3JpcHRpb24gTWFya3MgdGhlIHByb3BlcnR5IGFzIHRoZSB7QGxpbmsgTW9kZWx9cyBwcmltYXJ5IGtleS5cbiAqICBBbHNvIG1hcmtzIHRoZSBwcm9wZXJ0eSBhcyB7QGxpbmsgdW5pcXVlfSBhcyB7QHJlcXVpcmVkfSBhbmQgZW5zdXJlcyB0aGUgaW5kZXggaXMgY3JlYXRlZCBwcm9wZXJseSBhY2NvcmRpbmcgdG8gdGhlIHByb3ZpZGVkIHtAbGluayBTZXF1ZW5jZX1cbiAqXG4gKlxuICpcbiAqIEBmdW5jdGlvbiBwa1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6d2FsbGV0LWRiLkRlY29yYXRvcnNcbiAqXG4gKiBAc2VlIHVuaXF1ZVxuICogQHNlZSByZXF1aXJlZFxuICogQHNlZSBvblxuICogQHBhcmFtIGRhdGFcbiAqIEBwYXJhbSBrZXlcbiAqIEBwYXJhbSBtb2RlbFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGtPbkNyZWF0ZTxNIGV4dGVuZHMgTW9kZWwsIFYgZXh0ZW5kcyBSZXBvPE0+PihcbiAgdGhpczogVixcbiAgY29udGV4dDogQ29udGV4dDxNPixcbiAgZGF0YTogU2VxdWVuY2VPcHRpb25zLFxuICBrZXk6IHN0cmluZyxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIWRhdGEudHlwZSB8fCAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHNldFByaW1hcnlLZXlWYWx1ZSA9IGZ1bmN0aW9uIDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIHRhcmdldDogTSxcbiAgICBwcm9wZXJ0eUtleTogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnRcbiAgKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIHtcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgfSk7XG4gIH07XG4gIGlmICghZGF0YS5uYW1lKSBkYXRhLm5hbWUgPSBzZXF1ZW5jZU5hbWVGb3JNb2RlbChtb2RlbCwgXCJwa1wiKTtcbiAgbGV0IHNlcXVlbmNlOiBTZXF1ZW5jZTtcbiAgdHJ5IHtcbiAgICBzZXF1ZW5jZSA9IGF3YWl0IHRoaXMuYWRhcHRlci5TZXF1ZW5jZShkYXRhKTtcbiAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgRmFpbGVkIHRvIGluc3RhbnRpYXRlIFNlcXVlbmNlICR7ZGF0YS5uYW1lfTogJHtlfWBcbiAgICApO1xuICB9XG5cbiAgY29uc3QgbmV4dCA9IGF3YWl0IHNlcXVlbmNlLm5leHQoKTtcbiAgc2V0UHJpbWFyeUtleVZhbHVlKG1vZGVsLCBrZXksIG5leHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGsoXG4gIG9wdHM6IE9taXQ8XG4gICAgU2VxdWVuY2VPcHRpb25zLFxuICAgIFwiY3ljbGVcIiB8IFwic3RhcnRXaXRoXCIgfCBcImluY3JlbWVudEJ5XCJcbiAgPiA9IERlZmF1bHRTZXF1ZW5jZU9wdGlvbnNcbikge1xuICBvcHRzID0gT2JqZWN0LmFzc2lnbih7fSwgRGVmYXVsdFNlcXVlbmNlT3B0aW9ucywgb3B0cykgYXMgU2VxdWVuY2VPcHRpb25zO1xuICByZXR1cm4gYXBwbHkoXG4gICAgaW5kZXgoW09yZGVyRGlyZWN0aW9uLkFTQywgT3JkZXJEaXJlY3Rpb24uRFNDXSksXG4gICAgcmVxdWlyZWQoKSxcbiAgICByZWFkb25seSgpLFxuICAgIC8vIHR5cGUoW1N0cmluZy5uYW1lLCBOdW1iZXIubmFtZSwgQmlnSW50Lm5hbWVdKSxcbiAgICBwcm9wTWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoREJLZXlzLklEKSwgb3B0cyBhcyBTZXF1ZW5jZU9wdGlvbnMpLFxuICAgIG9uQ3JlYXRlKHBrT25DcmVhdGUsIG9wdHMgYXMgU2VxdWVuY2VPcHRpb25zKVxuICApO1xufVxuIiwiaW1wb3J0IHsgREJPcGVyYXRpb25zLCB0aW1lc3RhbXAgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IE1vZGVsQXJnLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VNb2RlbCBleHRlbmRzIE1vZGVsIHtcbiAgQHRpbWVzdGFtcChEQk9wZXJhdGlvbnMuQ1JFQVRFKVxuICBjcmVhdGVkT24hOiBEYXRlO1xuICBAdGltZXN0YW1wKClcbiAgdXBkYXRlZE9uITogRGF0ZTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoYXJnPzogTW9kZWxBcmc8QmFzZU1vZGVsPikge1xuICAgIHN1cGVyKGFyZyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IGxpc3QsIG1vZGVsLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB0eXBlIHsgTW9kZWxBcmcgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSb2xlcyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcbmltcG9ydCB7IHBrIH0gZnJvbSBcIi4uL2lkZW50aXR5L2RlY29yYXRvcnNcIjtcblxuQG1vZGVsKClcbmV4cG9ydCBjbGFzcyBVc2VyIGV4dGVuZHMgTW9kZWwge1xuICBAcGsoKVxuICBpZCE6IHN0cmluZztcblxuICBAbGlzdChbU3RyaW5nXSlcbiAgcm9sZXM/OiAoc3RyaW5nIHwgUm9sZXMpW107XG5cbiAgQGxpc3QoW1N0cmluZ10pXG4gIGFmZmlsaWF0aW9ucz86IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKGFyZz86IE1vZGVsQXJnPFVzZXI+KSB7XG4gICAgc3VwZXIoYXJnKTtcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyxcbiAgcHJvcE1ldGFkYXRhLFxuICBWYWxpZGF0aW9uLFxuICBWYWxpZGF0aW9uS2V5cyxcbiAgVmFsaWRhdGlvbk1ldGFkYXRhLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2VcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFBlcnNpc3RlbmNlS2V5cy5DTEFVU0VfU0VRVUVOQ0UsIHtcbiAgdmFsdWU6IFwiSW52YWxpZCBjbGF1c2Ugc2VxdWVuY2U6IHswfVwiLFxufSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShWYWxpZGF0aW9uS2V5cywgXCJDTEFVU0VfU0VRVUVOQ0VcIiwge1xuICB2YWx1ZTogUGVyc2lzdGVuY2VLZXlzLkNMQVVTRV9TRVFVRU5DRSxcbn0pO1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdXG4gKlxuICogQGZ1bmN0aW9uIGNsYXVzZVNlcXVlbmNlXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqIEBzdWJjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGF1c2VTZXF1ZW5jZShtZXNzYWdlPzogc3RyaW5nKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPihcbiAgICBWYWxpZGF0aW9uLmtleShWYWxpZGF0aW9uS2V5cy5SRVFVSVJFRCksXG4gICAge1xuICAgICAgbWVzc2FnZTpcbiAgICAgICAgbWVzc2FnZSB8fFxuICAgICAgICAoKERFRkFVTFRfRVJST1JfTUVTU0FHRVMgYXMgYW55KVtcbiAgICAgICAgICBQZXJzaXN0ZW5jZUtleXMuQ0xBVVNFX1NFUVVFTkNFIGFzIGFueVxuICAgICAgICBdIGFzIHN0cmluZyksXG4gICAgfVxuICApO1xufVxuIiwiaW1wb3J0IHtcbiAgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyxcbiAgc2YsXG4gIHZhbGlkYXRvcixcbiAgVmFsaWRhdG9yLFxuICBWYWxpZGF0b3JPcHRpb25zLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBpc0VxdWFsIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBDbGF1c2UgfSBmcm9tIFwiLi4vcXVlcnkvQ2xhdXNlXCI7XG5pbXBvcnQgeyBNYW5kYXRvcnlQcmlvcml0aWVzIH0gZnJvbSBcIi4uL3F1ZXJ5L2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgUXVlcnlFcnJvciB9IGZyb20gXCIuLi9xdWVyeS9lcnJvcnNcIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSB7QGxpbmsgU2VxdWVuY2V9J3Mge0BsaW5rIENsYXVzZX1zXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXVxuICpcbiAqIEBjbGFzcyBDbGF1c2VTZXF1ZW5jZVZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRpb25cbiAqIEBzdWJjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoUGVyc2lzdGVuY2VLZXlzLkNMQVVTRV9TRVFVRU5DRSlcbmV4cG9ydCBjbGFzcyBDbGF1c2VTZXF1ZW5jZVZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVNbUGVyc2lzdGVuY2VLZXlzLkNMQVVTRV9TRVFVRU5DRV1cbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlU2VxdWVuY2UoXG4gICAgY2xhdXNlczogQ2xhdXNlPGFueT5bXSxcbiAgICBtZXNzYWdlPzogc3RyaW5nXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIE1hbmRhdG9yeVByaW9yaXRpZXMuZXZlcnkoXG4gICAgICAocCkgPT4gISFjbGF1c2VzLmZpbmQoKGMpID0+IGMuZ2V0UHJpb3JpdHkoKSA9PT0gcClcbiAgICApXG4gICAgICA/IHVuZGVmaW5lZFxuICAgICAgOiB0aGlzLmdldE1lc3NhZ2UoXG4gICAgICAgICAgc2YobWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIFwiTWlzc2luZyByZXF1aXJlZCBDbGF1c2UgUHJpb3JpdGllc1wiKVxuICAgICAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFZlcmlmaWVzIHRoZSBtb2RlbCBmb3IgZXJyb3JzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1ZhbGlkYXRvck9wdGlvbnN9IFtvcHRpb25zXVxuICAgKlxuICAgKiBAcmV0dXJuIEVycm9yc1xuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICpcbiAgICogQHNlZSBWYWxpZGF0b3JcbiAgICovXG4gIHB1YmxpYyBoYXNFcnJvcnModmFsdWU6IGFueSwgb3B0aW9ucz86IFZhbGlkYXRvck9wdGlvbnMpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHRyeSB7XG4gICAgICBpZiAoXG4gICAgICAgICF2YWx1ZSB8fFxuICAgICAgICAhQXJyYXkuaXNBcnJheSh2YWx1ZSkgfHxcbiAgICAgICAgIXZhbHVlLmxlbmd0aCB8fFxuICAgICAgICAhdmFsdWUuZXZlcnkoKGUpID0+IGUgaW5zdGFuY2VvZiBDbGF1c2UpXG4gICAgICApXG4gICAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoXG4gICAgICAgICAgc2YoXG4gICAgICAgICAgICAob3B0aW9ucyB8fCB7fSkubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsXG4gICAgICAgICAgICBcIk5vIG9yIGludmFsaWQgQ2xhdXNlcyBmb3VuZFwiXG4gICAgICAgICAgKVxuICAgICAgICApO1xuXG4gICAgICBjb25zdCBjbGF1c2VzOiBDbGF1c2U8YW55PltdID0gdmFsdWUgYXMgQ2xhdXNlPGFueT5bXTtcblxuICAgICAgY29uc3QgY2xhdXNlRXJyb3JzID0gY2xhdXNlcy5yZWR1Y2UoXG4gICAgICAgIChhY2N1bTogc3RyaW5nIHwgdW5kZWZpbmVkLCBjOiBDbGF1c2U8YW55PikgPT4ge1xuICAgICAgICAgIGNvbnN0IGVycnMgPSBjLmhhc0Vycm9ycygpO1xuICAgICAgICAgIGlmIChlcnJzKVxuICAgICAgICAgICAgaWYgKGFjY3VtKVxuICAgICAgICAgICAgICBhY2N1bSArPSBzZihcbiAgICAgICAgICAgICAgICBcIlxcbkNsYXVzZSB7MH06IHsxfVwiLFxuICAgICAgICAgICAgICAgIGMuY29uc3RydWN0b3IubmFtZSxcbiAgICAgICAgICAgICAgICBlcnJzLnRvU3RyaW5nKClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgYWNjdW0gPSBzZihcbiAgICAgICAgICAgICAgICBcIkNsYXVzZSB7MH06IHsxfVwiLFxuICAgICAgICAgICAgICAgIGMuY29uc3RydWN0b3IubmFtZSxcbiAgICAgICAgICAgICAgICBlcnJzLnRvU3RyaW5nKClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICAgIH0sXG4gICAgICAgIHVuZGVmaW5lZFxuICAgICAgKTtcblxuICAgICAgaWYgKGNsYXVzZUVycm9ycylcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShcbiAgICAgICAgICBzZigob3B0aW9ucyB8fCB7fSkubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIGNsYXVzZUVycm9ycy50b1N0cmluZygpKVxuICAgICAgICApO1xuXG4gICAgICBjb25zdCB2ZXJpZnlQcmlvcml0eSA9ICgpID0+IHtcbiAgICAgICAgY29uc3QgcHJpb3JpdGllcyA9IGNsYXVzZXMubWFwKChjKSA9PiBjLmdldFByaW9yaXR5KCkpO1xuICAgICAgICBjb25zdCBhbGxVbmlxdWUgPSBuZXcgU2V0KHByaW9yaXRpZXMpLnNpemUgPT09IHByaW9yaXRpZXMubGVuZ3RoO1xuICAgICAgICBpZiAoIWFsbFVuaXF1ZSkgcmV0dXJuIFwiTm90IGFsbCBjbGF1c2VzICBoYXZlIHVuaXF1ZSBwcmlvcml0aWVzXCI7XG4gICAgICAgIGNvbnN0IHNvcnRlZCA9IHByaW9yaXRpZXMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgIHJldHVybiBiIC0gYTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGlzRXF1YWwocHJpb3JpdGllcywgc29ydGVkKVxuICAgICAgICAgID8gdHJ1ZVxuICAgICAgICAgIDogXCJDbGF1c2VzICBhcmUgbm90IHByb3Blcmx5IHNvcnRlZFwiO1xuICAgICAgfTtcblxuICAgICAgY29uc3QgcHJpb3JpdHlDaGVjayA9IHZlcmlmeVByaW9yaXR5KCk7XG4gICAgICBpZiAocHJpb3JpdHlDaGVjayAhPT0gdHJ1ZSlcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShcbiAgICAgICAgICBzZigob3B0aW9ucyB8fCB7fSkubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIFwiSW52YWxpZCBwcmlvcml0aXphdGlvblwiKVxuICAgICAgICApO1xuXG4gICAgICBjb25zdCBzZXF1ZW5jZUNoZWNrID0gdGhpcy52YWxpZGF0ZVNlcXVlbmNlKFxuICAgICAgICBjbGF1c2VzLFxuICAgICAgICAob3B0aW9ucyB8fCB7fSkubWVzc2FnZVxuICAgICAgKTtcbiAgICAgIGlmIChzZXF1ZW5jZUNoZWNrKVxuICAgICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKFxuICAgICAgICAgIHNmKChvcHRpb25zIHx8IHt9KS5tZXNzYWdlIHx8IHRoaXMubWVzc2FnZSwgXCJJbnZhbGlkIHNlcXVlbmNlXCIpXG4gICAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgUXVlcnlFcnJvcihcbiAgICAgICAgc2YoXCJGYWlsZWQgdG8gdmVyaWZ5IGNsYXVzZSBzZXF1ZW5jZSB7MH06IHsxfVwiLCB2YWx1ZSwgZSlcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgdHlwZSB7IENvbnN0cnVjdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHtcbiAgbWlubGVuZ3RoLFxuICBNb2RlbCxcbiAgTW9kZWxFcnJvckRlZmluaXRpb24sXG4gIHJlcXVpcmVkLFxuICB0eXBlLFxuICBzZixcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgRXhlY3V0b3IsIFJhd0V4ZWN1dG9yIH0gZnJvbSBcIi4uL2ludGVyZmFjZXNcIjtcbmltcG9ydCB7IE1hbmRhdG9yeVByaW9yaXRpZXMsIFN0YXRlbWVudFR5cGUgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFF1ZXJ5RXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IENsYXVzZSB9IGZyb20gXCIuL0NsYXVzZVwiO1xuaW1wb3J0IHsgY2xhdXNlU2VxdWVuY2UgfSBmcm9tIFwiLi4vdmFsaWRhdG9yc1wiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZVwiO1xuaW1wb3J0IHsgZmluZFByaW1hcnlLZXksIEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IFBhZ2luYXRvciB9IGZyb20gXCIuL1BhZ2luYXRvclwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFN0YXRlbWVudCBDbGFzc1xuICogQGRlc2NyaXB0aW9uIGhvbGRzIGFsbCB0aGUgY2xhdXNlcyB1bnRpbCB0aGV5IGNhbiBiZSBwcm9jZXNzZWRcbiAqXG4gKiBAcGFyYW0ge01vZGVsQXJnfSBbc3RhdGVtZW50XVxuICpcbiAqIEBjbGFzcyBTdGF0ZW1lbnRcbiAqIEBleHRlbmRzIE1vZGVsXG4gKiBAaW1wbGVtZW50cyBFeGVjdXRvclxuICogQGltcGxlbWVudHMgUmF3RXhlY3V0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgUXVlcnlcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFN0YXRlbWVudDxRPlxuICBleHRlbmRzIE1vZGVsXG4gIGltcGxlbWVudHMgRXhlY3V0b3IsIFJhd0V4ZWN1dG9yPFE+XG57XG4gIEByZXF1aXJlZCgpXG4gIEBtaW5sZW5ndGgoTWFuZGF0b3J5UHJpb3JpdGllcy5sZW5ndGgpXG4gIEBjbGF1c2VTZXF1ZW5jZSgpXG4gIHByb3RlY3RlZCBjbGF1c2VzPzogQ2xhdXNlPGFueT5bXSA9IHVuZGVmaW5lZDtcbiAgQHJlcXVpcmVkKClcbiAgQHR5cGUoW1wib2JqZWN0XCJdKVxuICBwcm90ZWN0ZWQgYWRhcHRlcjogQWRhcHRlcjxhbnksIFE+O1xuICBAcmVxdWlyZWQoKVxuICBwcm90ZWN0ZWQgdGFyZ2V0PzogQ29uc3RydWN0b3I8YW55PiA9IHVuZGVmaW5lZDtcblxuICBwcm90ZWN0ZWQgZnVsbFJlY29yZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIEByZXF1aXJlZCgpXG4gIHByb3RlY3RlZCB0eXBlPzogc3RyaW5nID0gdW5kZWZpbmVkO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihkYjogQWRhcHRlcjxhbnksIFE+KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSBkYjtcbiAgfVxuXG4gIHByb3RlY3RlZCBidWlsZCgpOiBRIHtcbiAgICBpZiAoIXRoaXMuY2xhdXNlcylcbiAgICAgIHRocm93IG5ldyBRdWVyeUVycm9yKHNmKFwiRmFpbGVkIHRvIGJ1aWxkIFN0YXRlbWVudDpcXG57MH1cIiwgXCJObyBDbGF1c2VzXCIpKTtcbiAgICB0aGlzLmNsYXVzZXMuc29ydCgoYzEsIGMyKSA9PiB7XG4gICAgICByZXR1cm4gYzEuZ2V0UHJpb3JpdHkoKSAtIGMyLmdldFByaW9yaXR5KCk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBlcnJvcnMgPSB0aGlzLmhhc0Vycm9ycygpO1xuICAgIGlmIChlcnJvcnMpXG4gICAgICB0aHJvdyBuZXcgUXVlcnlFcnJvcihcbiAgICAgICAgc2YoXCJQb29ybHkgYnVpbHQgc3RhdGVtZW50OiB7MH1cIiwgZXJyb3JzLnRvU3RyaW5nKCkpXG4gICAgICApO1xuXG4gICAgbGV0IHF1ZXJ5OiBRO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBpdGVyYXRvciA9IGZ1bmN0aW9uIChcbiAgICAgICAgY2xhdXNlczogQ2xhdXNlPGFueT5bXSxcbiAgICAgICAgcHJldmlvdXM6IGFueSA9IHt9XG4gICAgICApOiBRIHtcbiAgICAgICAgY29uc3QgYyA9IGNsYXVzZXMuc2hpZnQoKTtcbiAgICAgICAgaWYgKCFjKSByZXR1cm4gcHJldmlvdXMgYXMgUTtcbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IGMuYnVpbGQocHJldmlvdXMpO1xuICAgICAgICByZXR1cm4gaXRlcmF0b3IoY2xhdXNlcywgcmVzdWx0cyBhcyBhbnkpO1xuICAgICAgfTtcblxuICAgICAgcXVlcnkgPSBpdGVyYXRvcihuZXcgQXJyYXkoLi4uKHRoaXMuY2xhdXNlcyBhcyBDbGF1c2U8UT5bXSkpKSBhcyBRO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IFF1ZXJ5RXJyb3IoZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHF1ZXJ5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBhc3luYyBleGVjdXRlPFk+KCk6IFByb21pc2U8WT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBxdWVyeTogUSA9IHRoaXMuYnVpbGQoKTtcbiAgICAgIHJldHVybiB0aGlzLnJhdyhxdWVyeSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGFic3RyYWN0IHBhZ2luYXRlPFk+KHNpemU6IG51bWJlcik6IFByb21pc2U8UGFnaW5hdG9yPFksIFE+PjtcblxuICBhc3luYyByYXc8Uj4ocmF3SW5wdXQ6IFEsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSPiB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuYWRhcHRlci5yYXc8Uj4ocmF3SW5wdXQsIHRydWUsIC4uLmFyZ3MpO1xuICAgIGlmICghdGhpcy5mdWxsUmVjb3JkKSByZXR1cm4gcmVzdWx0cztcbiAgICBpZiAoIXRoaXMudGFyZ2V0KVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIFwiTm8gdGFyZ2V0IGRlZmluZWQgaW4gc3RhdGVtZW50LiBzaG91bGQgbmV2ZXIgaGFwcGVuXCJcbiAgICAgICk7XG5cbiAgICBjb25zdCBwa0F0dHIgPSBmaW5kUHJpbWFyeUtleShuZXcgdGhpcy50YXJnZXQoKSBhcyBhbnkpLmlkO1xuXG4gICAgY29uc3QgcHJvY2Vzc29yID0gZnVuY3Rpb24gcmVjb3JkUHJvY2Vzc29yKHRoaXM6IFN0YXRlbWVudDxRPiwgcjogYW55KSB7XG4gICAgICBjb25zdCBpZCA9IHJbcGtBdHRyXTtcbiAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIucmV2ZXJ0KFxuICAgICAgICByLFxuICAgICAgICB0aGlzLnRhcmdldCBhcyBDb25zdHJ1Y3Rvcjxhbnk+LFxuICAgICAgICBwa0F0dHIsXG4gICAgICAgIGlkXG4gICAgICApIGFzIGFueTtcbiAgICB9LmJpbmQodGhpcyk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRzKSkgcmV0dXJuIHJlc3VsdHMubWFwKHByb2Nlc3NvcikgYXMgUjtcbiAgICByZXR1cm4gcHJvY2Vzc29yKHJlc3VsdHMpIGFzIFI7XG4gIH1cblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGhhc0Vycm9ycyguLi5leGNlcHRpb25zOiBzdHJpbmdbXSk6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBlcnJvcnMgPSBzdXBlci5oYXNFcnJvcnMoLi4uZXhjZXB0aW9ucyk7XG4gICAgaWYgKGVycm9ycykgcmV0dXJuIGVycm9ycztcblxuICAgIGZvciAoY29uc3QgaSBpbiB0aGlzLmNsYXVzZXMpIHtcbiAgICAgIGNvbnN0IGVyciA9IHRoaXMuY2xhdXNlc1tpIGFzIGFueV0uaGFzRXJyb3JzKCk7XG4gICAgICBpZiAoZXJyKSByZXR1cm4gZXJyO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBBZGRzIGEgY2xhdXNlIHRvIHRoZSBTdGF0ZW1lbnRcbiAgICogQHBhcmFtIHtDbGF1c2V9IGNsYXVzZVxuICAgKi9cbiAgYWRkQ2xhdXNlKGNsYXVzZTogQ2xhdXNlPFE+KSB7XG4gICAgaWYgKCF0aGlzLmNsYXVzZXMpIHRoaXMuY2xhdXNlcyA9IFtdO1xuXG4gICAgY29uc3QgcHJpb3JpdHkgPSBjbGF1c2UuZ2V0UHJpb3JpdHkoKTtcbiAgICBjb25zdCBjdXJyZW50UHJpb3JpdHkgPSB0aGlzLmNsYXVzZXNcbiAgICAgIC5tYXAoKGMsIGkpID0+ICh7IGluZGV4OiBpLCBjbGF1c2U6IGMgfSkpXG4gICAgICAuZmluZCgoYykgPT4gYy5jbGF1c2UuZ2V0UHJpb3JpdHkoKSA9PT0gcHJpb3JpdHkpO1xuICAgIGlmIChjdXJyZW50UHJpb3JpdHkpIHtcbiAgICAgIHRoaXMuY2xhdXNlc1tjdXJyZW50UHJpb3JpdHkuaW5kZXhdID0gY2xhdXNlO1xuICAgIH1cbiAgICB0aGlzLmNsYXVzZXMucHVzaChjbGF1c2UpO1xuICB9XG5cbiAgZ2V0QWRhcHRlcigpOiBBZGFwdGVyPGFueSwgUT4ge1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXI7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgb3V0cHV0IGNsYXNzICh3aGVuIGV4aXN0aW5nKVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yfSBjbGF6elxuICAgKi9cbiAgc2V0VGFyZ2V0KGNsYXp6OiBDb25zdHJ1Y3Rvcjxhbnk+KSB7XG4gICAgaWYgKHRoaXMudGFyZ2V0KVxuICAgICAgdGhyb3cgbmV3IFF1ZXJ5RXJyb3IoXG4gICAgICAgIHNmKFwiT3V0cHV0IGNsYXNzIGFscmVhZHkgZGVmaW5lZCB0byB7MH1cIiwgdGhpcy50YXJnZXQhLm5hbWUpXG4gICAgICApO1xuICAgIHRoaXMudGFyZ2V0ID0gY2xheno7XG4gIH1cblxuICBnZXRUYXJnZXQoKSB7XG4gICAgaWYgKCF0aGlzLnRhcmdldClcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTm8gdGFyZ2V0IGRlZmluZWQgZm9yIHN0YXRlbWVudFwiKTtcbiAgICByZXR1cm4gdGhpcy50YXJnZXQ7XG4gIH1cblxuICBzZXRGdWxsUmVjb3JkKCkge1xuICAgIHRoaXMuZnVsbFJlY29yZCA9IHRydWU7XG4gIH1cblxuICBzZXRNb2RlKHR5cGU6IFN0YXRlbWVudFR5cGUpIHtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICB9XG59XG4iLCJpbXBvcnQgeyBFeGVjdXRvciB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQge1xuICBNb2RlbCxcbiAgTW9kZWxBcmcsXG4gIHJlcXVpcmVkLFxuICB0eXBlLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBRdWVyeUJ1aWxkZXIgfSBmcm9tIFwiLi9vcHRpb25zXCI7XG5pbXBvcnQgeyBRdWVyeUVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBQcmlvcml0eSB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgU3RhdGVtZW50IH0gZnJvbSBcIi4vU3RhdGVtZW50XCI7XG5pbXBvcnQgeyBQYWdpbmF0YWJsZSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL1BhZ2luYXRhYmxlXCI7XG5pbXBvcnQgeyBQYWdpbmF0b3IgfSBmcm9tIFwiLi9QYWdpbmF0b3JcIjtcblxuLyoqXG4gKi9cblxuLyoqXG4gKiBAc3VtbWFyeSBDbGF1c2UgQ2xhc3NcbiAqIEBkZXNjcmlwdGlvbiBSZXByZXNlbnRzIGEgQ2xhdXNlIGluIGEge0BsaW5rIFN0YXRlbWVudH1cbiAqXG4gKiBAdHlwZWRlZiBRIFJlcHJlc2VudHMgcXVlIHF1ZXJ5IG9iamVjdCB0aGUgcGVyc2lzdGVuY2UgYWRhcHRlciB1c2VzXG4gKlxuICogQHBhcmFtIHtNb2RlbEFyZzxDbGF1c2U8UT4+fSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBDbGF1c2VcbiAqIEBleHRlbmRzIE1vZGVsXG4gKiBAaW1wbGVtZW50cyBFeGVjdXRvclxuICogQGltcGxlbWVudHMgUXVlcnlCdWlsZGVyXG4gKiBAYWJzdHJhY3RcbiAqXG4gKiBAY2F0ZWdvcnkgUXVlcnlcbiAqIEBzdWJjYXRlZ29yeSBDbGF1c2VzXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDbGF1c2U8UT5cbiAgZXh0ZW5kcyBNb2RlbFxuICBpbXBsZW1lbnRzIEV4ZWN1dG9yLCBQYWdpbmF0YWJsZSwgUXVlcnlCdWlsZGVyPFE+XG57XG4gIEByZXF1aXJlZCgpXG4gIHJlYWRvbmx5IHByaW9yaXR5ITogUHJpb3JpdHk7XG5cbiAgQHJlcXVpcmVkKClcbiAgQHR5cGUoXCJvYmplY3RcIilcbiAgcmVhZG9ubHkgc3RhdGVtZW50ITogU3RhdGVtZW50PFE+O1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihjbGF1c2U/OiBNb2RlbEFyZzxDbGF1c2U8UT4+KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnByaW9yaXR5ID0gY2xhdXNlPy5wcmlvcml0eTtcbiAgICB0aGlzLnN0YXRlbWVudCA9IGNsYXVzZT8uc3RhdGVtZW50O1xuICAgIGlmICghdGhpcy5zdGF0ZW1lbnQgfHwgIXRoaXMucHJpb3JpdHkpXG4gICAgICB0aHJvdyBuZXcgUXVlcnlFcnJvcihcbiAgICAgICAgXCJNaXNzaW5nIHN0YXRlbWVudCBvciBwcmlvcml0eS4gU2hvdWxkIGJlIGltcG9zc2libGVcIlxuICAgICAgKTtcbiAgICB0aGlzLnN0YXRlbWVudC5hZGRDbGF1c2UodGhpcyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGFkYXB0ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGVtZW50LmdldEFkYXB0ZXIoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgQ2xhdXNlcygpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZW1lbnQuZ2V0QWRhcHRlcigpLkNsYXVzZXM7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgcmV0dXJuIHRoZSBwcmlvcml0eSBvZiB0aGUgY2xhdXNlXG4gICAqIEBzZWUgUHJpb3JpdHlcbiAgICovXG4gIGdldFByaW9yaXR5KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucHJpb3JpdHkgYXMgbnVtYmVyO1xuICB9XG5cbiAgYWJzdHJhY3QgYnVpbGQocHJldmlvdXM6IFEpOiBRO1xuXG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKiBAYWJzdHJhY3RcbiAgICovXG4gIGFzeW5jIGV4ZWN1dGU8Uj4oKTogUHJvbWlzZTxSPiB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGVtZW50LmV4ZWN1dGUoKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICogQGFic3RyYWN0XG4gICAqL1xuICBhc3luYyBwYWdpbmF0ZTxSPihzaXplOiBudW1iZXIpOiBQcm9taXNlPFBhZ2luYXRvcjxSLCBRPj4ge1xuICAgIHJldHVybiB0aGlzLnN0YXRlbWVudC5wYWdpbmF0ZShzaXplKTtcbiAgfVxuXG4gIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG4gIH1cblxuICAvLyAvKipcbiAgLy8gICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgZm9yIHtAbGluayBGcm9tQ2xhdXNlfVxuICAvLyAgKiBAcGFyYW0ge3twcmlvcml0eTogbnVtYmVyLCBzdGF0ZW1lbnQ6IFN0YXRlbWVudCwgZ2V0UHJpb3JpdHk6IEZ1bmN0aW9uLCBidWlsZDogRnVuY3Rpb24sIHByb2Nlc3M6IEZ1bmN0aW9ufX0gY2xhdXNlXG4gIC8vICAqL1xuICAvLyBzdGF0aWMgaXNDbGF1c2UoY2xhdXNlOiBQYXJ0aWFsPENsYXVzZTxhbnk+Pikge1xuICAvLyAgIHJldHVybiBjbGF1c2UgaW5zdGFuY2VvZiBDbGF1c2U7XG4gIC8vICAgcmV0dXJuIChcbiAgLy8gICAgIGNsYXVzZS5jb25zdHJ1Y3RvciAmJlxuICAvLyAgICAgY2xhdXNlLmNvbnN0cnVjdG9yLm5hbWUgJiZcbiAgLy8gICAgIGNsYXVzZS5wcmlvcml0eSAmJlxuICAvLyAgICAgY2xhdXNlLnN0YXRlbWVudCAmJlxuICAvLyAgICAgY2xhdXNlLmdldFByaW9yaXR5ICYmXG4gIC8vICAgICBjbGF1c2UuYnVpbGQgJiZcbiAgLy8gICAgIGNsYXVzZS5leGVjdXRlXG4gIC8vICAgKTtcbiAgLy8gfVxufVxuIiwiaW1wb3J0IHsgQ2xhdXNlIH0gZnJvbSBcIi4uL0NsYXVzZVwiO1xuaW1wb3J0IHsgTW9kZWxBcmcsIHJlcXVpcmVkIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFRoZSBiYXNlIFNlbGVjdG9yIGJhc2VkIGNsYXVzZVxuICpcbiAqIEBwYXJhbSB7Q2xhdXNlQXJnfSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBTZWxlY3RvckJhc2VkQ2xhdXNlXG4gKiBAZXh0ZW5kcyBDbGF1c2VcbiAqIEBhYnN0cmFjdFxuICpcbiAqIEBjYXRlZ29yeSBRdWVyeVxuICogQHN1YmNhdGVnb3J5IENsYXVzZXNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFNlbGVjdG9yQmFzZWRDbGF1c2U8USwgUz4gZXh0ZW5kcyBDbGF1c2U8UT4ge1xuICAvKipcbiAgICogQHN1bW1hcnkgU3RvcmVzIHRoZSBzZWxlY3RvclxuICAgKlxuICAgKiBAcHJvcCBzZWxlY3RvclxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBAcmVxdWlyZWQoKVxuICBwcm90ZWN0ZWQgc2VsZWN0b3I/OiBTID0gdW5kZWZpbmVkO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihjbGF1c2U/OiBNb2RlbEFyZzxTZWxlY3RvckJhc2VkQ2xhdXNlPFEsIFM+Pikge1xuICAgIHN1cGVyKGNsYXVzZSk7XG4gICAgdGhpcy5zZWxlY3RvciA9IChjbGF1c2UgYXMgeyBzZWxlY3RvcjogUyB9KS5zZWxlY3RvcjtcbiAgfVxuXG4gIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLm5hbWUgKyBgWyR7dGhpcy5zZWxlY3Rvcn1dYDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgUHJpb3JpdHkgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBGcm9tU2VsZWN0b3IsXG4gIEdyb3VwQnlTZWxlY3RvcixcbiAgTGltaXRTZWxlY3RvcixcbiAgT2Zmc2V0U2VsZWN0b3IsXG4gIE9yZGVyQnlTZWxlY3Rvcixcbn0gZnJvbSBcIi4uL3NlbGVjdG9yc1wiO1xuaW1wb3J0IHtcbiAgTGltaXRPcHRpb24sXG4gIE9mZnNldE9wdGlvbixcbiAgT3JkZXJBbmRHcm91cE9wdGlvbixcbiAgV2hlcmVPcHRpb24sXG59IGZyb20gXCIuLi9vcHRpb25zXCI7XG5pbXBvcnQgeyBTZWxlY3RvckJhc2VkQ2xhdXNlIH0gZnJvbSBcIi4vU2VsZWN0b3JCYXNlZENsYXVzZVwiO1xuaW1wb3J0IHsgRXhlY3V0b3IgfSBmcm9tIFwiLi4vLi4vaW50ZXJmYWNlc1wiO1xuaW1wb3J0IHsgUXVlcnlFcnJvciB9IGZyb20gXCIuLi9lcnJvcnNcIjtcbmltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuLi9Db25kaXRpb25cIjtcbmltcG9ydCB7XG4gIENvbnN0cnVjdG9yLFxuICBNb2RlbCxcbiAgTW9kZWxBcmcsXG4gIHN0cmluZ0Zvcm1hdCxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFRoZSBGUk9NIGNsYXVzZVxuICpcbiAqIEBwYXJhbSB7TW9kZWxBcmd9IFtjbGF1c2VdXG4gKlxuICogQGNsYXNzIEZyb21DbGF1c2VcbiAqIEBleHRlbmRzIFNlbGVjdG9yQmFzZWRDbGF1c2VcbiAqIEBpbXBsZW1lbnRzIFdoZXJlT3B0aW9uXG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKiBAc3ViY2F0ZWdvcnkgQ2xhdXNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRnJvbUNsYXVzZTxRLCBNIGV4dGVuZHMgTW9kZWw+XG4gIGV4dGVuZHMgU2VsZWN0b3JCYXNlZENsYXVzZTxRLCBGcm9tU2VsZWN0b3I8TT4+XG4gIGltcGxlbWVudHMgV2hlcmVPcHRpb25cbntcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGNsYXVzZT86IE1vZGVsQXJnPEZyb21DbGF1c2U8USwgTT4+KSB7XG4gICAgc3VwZXIoT2JqZWN0LmFzc2lnbih7fSwgY2xhdXNlLCB7IHByaW9yaXR5OiBQcmlvcml0eS5GUk9NIH0pKTtcbiAgICB0aGlzLnNlbGVjdG9yID1cbiAgICAgIHR5cGVvZiB0aGlzLnNlbGVjdG9yID09PSBcInN0cmluZ1wiXG4gICAgICAgID8gTW9kZWwuZ2V0KHRoaXMuc2VsZWN0b3IpXG4gICAgICAgIDogdGhpcy5zZWxlY3RvcjtcbiAgICBpZiAoIXRoaXMuc2VsZWN0b3IpXG4gICAgICB0aHJvdyBuZXcgUXVlcnlFcnJvcihzdHJpbmdGb3JtYXQoXCJDb3VsZCBub3QgZmluZCBzZWxlY3RvciBtb2RlbDogezB9XCIpKTtcbiAgICB0aGlzLnN0YXRlbWVudC5zZXRUYXJnZXQodGhpcy5zZWxlY3RvciBhcyBDb25zdHJ1Y3RvcjxNPik7XG4gIH1cblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGFic3RyYWN0IGJ1aWxkKHF1ZXJ5OiBRKTogUTtcblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIHdoZXJlKGNvbmRpdGlvbjogQ29uZGl0aW9uKTogT3JkZXJBbmRHcm91cE9wdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuQ2xhdXNlcy53aGVyZSh0aGlzLnN0YXRlbWVudCwgY29uZGl0aW9uKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIG9yZGVyQnkoLi4uc2VsZWN0b3I6IE9yZGVyQnlTZWxlY3RvcltdKTogTGltaXRPcHRpb24gJiBPZmZzZXRPcHRpb24ge1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMub3JkZXJCeSh0aGlzLnN0YXRlbWVudCwgc2VsZWN0b3IpO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgZ3JvdXBCeShzZWxlY3RvcjogR3JvdXBCeVNlbGVjdG9yKTogRXhlY3V0b3Ige1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMuZ3JvdXBCeSh0aGlzLnN0YXRlbWVudCwgc2VsZWN0b3IpO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgbGltaXQoc2VsZWN0b3I6IExpbWl0U2VsZWN0b3IpOiBPZmZzZXRPcHRpb24ge1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMubGltaXQodGhpcy5zdGF0ZW1lbnQsIHNlbGVjdG9yKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIG9mZnNldChzZWxlY3RvcjogT2Zmc2V0U2VsZWN0b3IpOiBFeGVjdXRvciB7XG4gICAgcmV0dXJuIHRoaXMuQ2xhdXNlcy5vZmZzZXQodGhpcy5zdGF0ZW1lbnQsIHNlbGVjdG9yKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWxBcmcgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBHcm91cEJ5U2VsZWN0b3IgfSBmcm9tIFwiLi4vc2VsZWN0b3JzXCI7XG5pbXBvcnQgeyBQcmlvcml0eSB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFNlbGVjdG9yQmFzZWRDbGF1c2UgfSBmcm9tIFwiLi9TZWxlY3RvckJhc2VkQ2xhdXNlXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgVGhlIEdST1VQIEJZIGNsYXVzZVxuICpcbiAqIEBwYXJhbSB7Q2xhdXNlQXJnfSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBHcm91cEJ5Q2xhdXNlXG4gKiBAZXh0ZW5kcyBTZWxlY3RvckJhc2VkQ2xhdXNlXG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKiBAc3ViY2F0ZWdvcnkgQ2xhdXNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgR3JvdXBCeUNsYXVzZTxRPiBleHRlbmRzIFNlbGVjdG9yQmFzZWRDbGF1c2U8XG4gIFEsXG4gIEdyb3VwQnlTZWxlY3RvclxuPiB7XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihjbGF1c2U/OiBNb2RlbEFyZzxHcm91cEJ5Q2xhdXNlPFE+Pikge1xuICAgIHN1cGVyKE9iamVjdC5hc3NpZ24oe30sIGNsYXVzZSwgeyBwcmlvcml0eTogUHJpb3JpdHkuR1JPVVBfQlkgfSkpO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgYWJzdHJhY3QgYnVpbGQocXVlcnk6IFEpOiBRO1xufVxuIiwiaW1wb3J0IHsgQ29uZGl0aW9uIH0gZnJvbSBcIi4uL0NvbmRpdGlvblwiO1xuaW1wb3J0IHsgSW5zZXJ0T3B0aW9uLCBJbnRvT3B0aW9uLCBPcmRlckFuZEdyb3VwT3B0aW9uIH0gZnJvbSBcIi4uL29wdGlvbnNcIjtcbmltcG9ydCB7IFByaW9yaXR5IH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ2xhdXNlIH0gZnJvbSBcIi4uL0NsYXVzZVwiO1xuaW1wb3J0IHtcbiAgQ29uc3RydWN0b3IsXG4gIE1vZGVsLFxuICBNb2RlbEFyZyxcbiAgcmVxdWlyZWQsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEV4ZWN1dG9yIH0gZnJvbSBcIi4uLy4uL2ludGVyZmFjZXNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBUaGUgSU5TRVJUL0lOVE8gY2xhdXNlXG4gKlxuICogQHBhcmFtIHtDbGF1c2VBcmd9IFtjbGF1c2VdXG4gKlxuICogQGNsYXNzIEZyb21DbGF1c2VcbiAqIEBleHRlbmRzIENsYXVzZVxuICogQGltcGxlbWVudHMgSW50b09wdGlvblxuICpcbiAqIEBjYXRlZ29yeSBRdWVyeVxuICogQHN1YmNhdGVnb3J5IENsYXVzZXNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEluc2VydENsYXVzZTxRLCBNIGV4dGVuZHMgTW9kZWw+XG4gIGV4dGVuZHMgQ2xhdXNlPFE+XG4gIGltcGxlbWVudHMgSW5zZXJ0T3B0aW9uPE0+LCBJbnRvT3B0aW9uPE0+XG57XG4gIEByZXF1aXJlZCgpXG4gIHByb3RlY3RlZCB0YWJsZT86IHN0cmluZyA9IHVuZGVmaW5lZDtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xhdXNlPzogTW9kZWxBcmc8SW5zZXJ0Q2xhdXNlPFEsIE0+Pikge1xuICAgIHN1cGVyKE9iamVjdC5hc3NpZ24oe30sIGNsYXVzZSwgeyBwcmlvcml0eTogUHJpb3JpdHkuU0VMRUNUIH0pKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGFic3RyYWN0IGJ1aWxkKHF1ZXJ5OiBRKTogUTtcblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGludG8odGFibGU6IENvbnN0cnVjdG9yPE0+KTogSW50b09wdGlvbjxNPiB7XG4gICAgdGhpcy50YWJsZSA9IHRhYmxlLm5hbWU7IC8vIFRPRE8gZ2V0IG1hcHBlZCBuYW1lXG4gICAgdGhpcy5zdGF0ZW1lbnQuc2V0VGFyZ2V0KHRhYmxlKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIHZhbHVlcyguLi5tb2RlbHM6IE1bXSk6IEV4ZWN1dG9yIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLnZhbHVlcyh0aGlzLnN0YXRlbWVudCwgbW9kZWxzKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIHdoZXJlKGNvbmRpdGlvbjogQ29uZGl0aW9uKTogT3JkZXJBbmRHcm91cE9wdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuQ2xhdXNlcy53aGVyZSh0aGlzLnN0YXRlbWVudCwgY29uZGl0aW9uKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgU2VsZWN0b3JCYXNlZENsYXVzZSB9IGZyb20gXCIuL1NlbGVjdG9yQmFzZWRDbGF1c2VcIjtcbmltcG9ydCB7IE9mZnNldE9wdGlvbiB9IGZyb20gXCIuLi9vcHRpb25zXCI7XG5pbXBvcnQgeyBFeGVjdXRvciB9IGZyb20gXCIuLi8uLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBMaW1pdFNlbGVjdG9yLCBPZmZzZXRTZWxlY3RvciB9IGZyb20gXCIuLi9zZWxlY3RvcnNcIjtcbmltcG9ydCB7IFByaW9yaXR5IH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgTW9kZWxBcmcgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgTGltaXQgQ2xhdXNlXG4gKiBAZGVzY3JpcHRpb24gTGltaXRzIHRoZSByZXN1bHRzXG4gKlxuICogQHBhcmFtIHtDbGF1c2VBcmd9IFtjbGF1c2VdXG4gKlxuICogQGNsYXNzIExpbWl0Q2xhdXNlXG4gKiBAZXh0ZW5kcyBTZWxlY3RvckJhc2VkQ2xhdXNlPFQ+XG4gKiBAaW1wbGVtZW50cyBPZmZzZXRPcHRpb248VD5cbiAqXG4gKiBAY2F0ZWdvcnkgUXVlcnlcbiAqIEBzdWJjYXRlZ29yeSBDbGF1c2VzXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBMaW1pdENsYXVzZTxRPlxuICBleHRlbmRzIFNlbGVjdG9yQmFzZWRDbGF1c2U8USwgTGltaXRTZWxlY3Rvcj5cbiAgaW1wbGVtZW50cyBPZmZzZXRPcHRpb25cbntcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGNsYXVzZT86IE1vZGVsQXJnPExpbWl0Q2xhdXNlPFE+Pikge1xuICAgIHN1cGVyKE9iamVjdC5hc3NpZ24oe30sIGNsYXVzZSwgeyBwcmlvcml0eTogUHJpb3JpdHkuR1JPVVBfQlkgfSkpO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgYWJzdHJhY3QgYnVpbGQocXVlcnk6IFEpOiBRO1xuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIG9mZnNldChzZWxlY3RvcjogT2Zmc2V0U2VsZWN0b3IpOiBFeGVjdXRvciB7XG4gICAgcmV0dXJuIHRoaXMuQ2xhdXNlcy5vZmZzZXQodGhpcy5zdGF0ZW1lbnQsIHNlbGVjdG9yKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgU2VsZWN0b3JCYXNlZENsYXVzZSB9IGZyb20gXCIuL1NlbGVjdG9yQmFzZWRDbGF1c2VcIjtcbmltcG9ydCB7IE9mZnNldFNlbGVjdG9yIH0gZnJvbSBcIi4uL3NlbGVjdG9yc1wiO1xuaW1wb3J0IHsgUHJpb3JpdHkgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNb2RlbEFyZyB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBUaGUgT0ZGU0VUIGNsYXVzZVxuICpcbiAqIEBwYXJhbSB7Q2xhdXNlQXJnfSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBGcm9tQ2xhdXNlXG4gKiBAZXh0ZW5kcyBTZWxlY3RvckJhc2VkQ2xhdXNlXG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKiBAc3ViY2F0ZWdvcnkgQ2xhdXNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgT2Zmc2V0Q2xhdXNlPFE+IGV4dGVuZHMgU2VsZWN0b3JCYXNlZENsYXVzZTxcbiAgUSxcbiAgT2Zmc2V0U2VsZWN0b3Jcbj4ge1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xhdXNlPzogTW9kZWxBcmc8T2Zmc2V0Q2xhdXNlPFE+Pikge1xuICAgIHN1cGVyKE9iamVjdC5hc3NpZ24oe30sIGNsYXVzZSwgeyBwcmlvcml0eTogUHJpb3JpdHkuR1JPVVBfQlkgfSkpO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgYWJzdHJhY3QgYnVpbGQocXVlcnk6IFEpOiBRO1xufVxuIiwiaW1wb3J0IHsgU2VsZWN0b3JCYXNlZENsYXVzZSB9IGZyb20gXCIuL1NlbGVjdG9yQmFzZWRDbGF1c2VcIjtcbmltcG9ydCB7IFByaW9yaXR5IH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHtcbiAgR3JvdXBCeVNlbGVjdG9yLFxuICBMaW1pdFNlbGVjdG9yLFxuICBPZmZzZXRTZWxlY3RvcixcbiAgT3JkZXJCeVNlbGVjdG9yLFxufSBmcm9tIFwiLi4vc2VsZWN0b3JzXCI7XG5pbXBvcnQgeyBMaW1pdE9wdGlvbiwgT2Zmc2V0T3B0aW9uIH0gZnJvbSBcIi4uL29wdGlvbnNcIjtcbmltcG9ydCB7IEV4ZWN1dG9yIH0gZnJvbSBcIi4uLy4uL2ludGVyZmFjZXNcIjtcbmltcG9ydCB7IE1vZGVsQXJnIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuLyoqXG4gKiBAc3VtbWFyeSBUaGUgT1JERVIgQlkgY2xhdXNlXG4gKlxuICogQHBhcmFtIHtDbGF1c2VBcmd9IFtjbGF1c2VdXG4gKlxuICogQGNsYXNzIE9yZGVyQnlDbGF1c2VcbiAqIEBleHRlbmRzIFNlbGVjdG9yQmFzZWRDbGF1c2VcbiAqIEBpbXBsZW1lbnRzIExpbWl0T3B0aW9uXG4gKiBAaW1wbGVtZW50cyBPZmZzZXRPcHRpb25cbiAqXG4gKiBAY2F0ZWdvcnkgUXVlcnlcbiAqIEBzdWJjYXRlZ29yeSBDbGF1c2VzXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBPcmRlckJ5Q2xhdXNlPFE+XG4gIGV4dGVuZHMgU2VsZWN0b3JCYXNlZENsYXVzZTxRLCBPcmRlckJ5U2VsZWN0b3JbXT5cbiAgaW1wbGVtZW50cyBMaW1pdE9wdGlvbiwgT2Zmc2V0T3B0aW9uXG57XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihjbGF1c2U/OiBNb2RlbEFyZzxPcmRlckJ5Q2xhdXNlPFE+Pikge1xuICAgIHN1cGVyKE9iamVjdC5hc3NpZ24oe30sIGNsYXVzZSwgeyBwcmlvcml0eTogUHJpb3JpdHkuT1JERVJfQlkgfSkpO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgYWJzdHJhY3QgYnVpbGQocXVlcnk6IFEpOiBRO1xuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGdyb3VwQnkoc2VsZWN0b3I6IEdyb3VwQnlTZWxlY3Rvcik6IEV4ZWN1dG9yIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLmdyb3VwQnkodGhpcy5zdGF0ZW1lbnQsIHNlbGVjdG9yKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGxpbWl0KHNlbGVjdG9yOiBMaW1pdFNlbGVjdG9yKTogT2Zmc2V0T3B0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLmxpbWl0KHRoaXMuc3RhdGVtZW50LCBzZWxlY3Rvcik7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBvZmZzZXQoc2VsZWN0b3I6IE9mZnNldFNlbGVjdG9yKTogRXhlY3V0b3Ige1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMub2Zmc2V0KHRoaXMuc3RhdGVtZW50LCBzZWxlY3Rvcik7XG4gIH1cbn1cbiIsImltcG9ydCB7IFNlbGVjdG9yQmFzZWRDbGF1c2UgfSBmcm9tIFwiLi9TZWxlY3RvckJhc2VkQ2xhdXNlXCI7XG5pbXBvcnQge1xuICBDb3VudE9wdGlvbixcbiAgRGlzdGluY3RPcHRpb24sXG4gIE1heE9wdGlvbixcbiAgTWluT3B0aW9uLFxuICBTZWxlY3RPcHRpb24sXG4gIFdoZXJlT3B0aW9uLFxufSBmcm9tIFwiLi4vb3B0aW9uc1wiO1xuaW1wb3J0IHsgQ29uc3QsIFByaW9yaXR5LCBTdGF0ZW1lbnRUeXBlIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsQXJnLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFNlbGVjdFNlbGVjdG9yIH0gZnJvbSBcIi4uL3NlbGVjdG9yc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFRoZSBTRUxFQ1QgY2xhdXNlXG4gKlxuICogQHBhcmFtIHtDbGF1c2VBcmd9IFtjbGF1c2VdXG4gKlxuICogQGNsYXNzIFNlbGVjdENsYXVzZVxuICogQGV4dGVuZHMgU2VsZWN0b3JCYXNlZENsYXVzZVxuICogQGltcGxlbWVudHMgU2VsZWN0T3B0aW9uXG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKiBAc3ViY2F0ZWdvcnkgQ2xhdXNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgU2VsZWN0Q2xhdXNlPFEsIE0gZXh0ZW5kcyBNb2RlbD5cbiAgZXh0ZW5kcyBTZWxlY3RvckJhc2VkQ2xhdXNlPFEsIFNlbGVjdFNlbGVjdG9yPlxuICBpbXBsZW1lbnRzIFNlbGVjdE9wdGlvbjxNPlxue1xuICBwcml2YXRlIGlzRGlzdGluY3Q6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBpc0NvdW50ID0gZmFsc2U7XG4gIHByaXZhdGUgaXNNYXggPSBmYWxzZTtcbiAgcHJpdmF0ZSBpc01pbiA9IGZhbHNlO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihjbGF1c2U/OiBNb2RlbEFyZzxTZWxlY3RDbGF1c2U8USwgTT4+KSB7XG4gICAgc3VwZXIoT2JqZWN0LmFzc2lnbih7fSwgY2xhdXNlLCB7IHByaW9yaXR5OiBQcmlvcml0eS5TRUxFQ1QgfSkpO1xuICAgIGlmICh0aGlzLnNlbGVjdG9yID09PSBDb25zdC5GVUxMX1JFQ09SRCkgdGhpcy5zdGF0ZW1lbnQuc2V0RnVsbFJlY29yZCgpO1xuICAgIHRoaXMuc3RhdGVtZW50LnNldE1vZGUoU3RhdGVtZW50VHlwZS5RVUVSWSk7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBhYnN0cmFjdCBidWlsZChxdWVyeTogUSk6IFE7XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgZGlzdGluY3Qoc2VsZWN0b3I6IFNlbGVjdFNlbGVjdG9yKTogRGlzdGluY3RPcHRpb248TT4ge1xuICAgIHRoaXMuaXNEaXN0aW5jdCA9IHRydWU7XG4gICAgdGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgY291bnQoc2VsZWN0b3I6IFNlbGVjdFNlbGVjdG9yKTogQ291bnRPcHRpb248TT4ge1xuICAgIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIG1pbihzZWxlY3RvcjogU2VsZWN0U2VsZWN0b3IpOiBNaW5PcHRpb248TT4ge1xuICAgIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIG1heChzZWxlY3RvcjogU2VsZWN0U2VsZWN0b3IpOiBNYXhPcHRpb248TT4ge1xuICAgIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGZyb20odGFibGVOYW1lOiBDb25zdHJ1Y3RvcjxNPik6IFdoZXJlT3B0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLmZyb20odGhpcy5zdGF0ZW1lbnQsIHRhYmxlTmFtZSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IENsYXVzZSB9IGZyb20gXCIuLi9DbGF1c2VcIjtcbmltcG9ydCB7IFByaW9yaXR5IH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgTW9kZWxBcmcsIHJlcXVpcmVkLCB0eXBlIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFRoZSBWQUxVRVMgY2xhdXNlXG4gKlxuICogQHBhcmFtIHtDbGF1c2VBcmd9IFtjbGF1c2VdXG4gKlxuICogQGNsYXNzIFZhbHVlc0NsYXVzZVxuICogQGV4dGVuZHMgQ2xhdXNlXG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKiBAc3ViY2F0ZWdvcnkgQ2xhdXNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVmFsdWVzQ2xhdXNlPFEsIE0+IGV4dGVuZHMgQ2xhdXNlPFE+IHtcbiAgQHJlcXVpcmVkKClcbiAgQHR5cGUoQXJyYXkubmFtZSlcbiAgbW9kZWxzPzogTVtdID0gdW5kZWZpbmVkO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihjbGF1c2U/OiBNb2RlbEFyZzxWYWx1ZXNDbGF1c2U8USwgTT4+KSB7XG4gICAgc3VwZXIoT2JqZWN0LmFzc2lnbih7fSwgY2xhdXNlLCB7IHByaW9yaXR5OiBQcmlvcml0eS5GUk9NIH0pKTtcbiAgICB0aGlzLm1vZGVscyA9IGNsYXVzZT8ubW9kZWxzO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgYWJzdHJhY3QgYnVpbGQocXVlcnk6IFEpOiBRO1xufVxuIiwiaW1wb3J0IHsgQ2xhdXNlIH0gZnJvbSBcIi4uL0NsYXVzZVwiO1xuaW1wb3J0IHsgQ29uZGl0aW9uIH0gZnJvbSBcIi4uL0NvbmRpdGlvblwiO1xuaW1wb3J0IHtcbiAgTW9kZWxBcmcsXG4gIE1vZGVsRXJyb3JEZWZpbml0aW9uLFxuICByZXF1aXJlZCxcbiAgdHlwZSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgTGltaXRPcHRpb24sIE9mZnNldE9wdGlvbiwgT3JkZXJBbmRHcm91cE9wdGlvbiB9IGZyb20gXCIuLi9vcHRpb25zXCI7XG5pbXBvcnQgeyBQcmlvcml0eSB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIEdyb3VwQnlTZWxlY3RvcixcbiAgTGltaXRTZWxlY3RvcixcbiAgT2Zmc2V0U2VsZWN0b3IsXG4gIE9yZGVyQnlTZWxlY3Rvcixcbn0gZnJvbSBcIi4uL3NlbGVjdG9yc1wiO1xuaW1wb3J0IHsgRXhlY3V0b3IgfSBmcm9tIFwiLi4vLi4vaW50ZXJmYWNlc1wiO1xuLyoqXG4gKiBAc3VtbWFyeSBUaGUgV0hFUkUgY2xhdXNlXG4gKlxuICogQHBhcmFtIHtDbGF1c2VBcmd9IFtjbGF1c2VdXG4gKlxuICogQGNsYXNzIFdoZXJlQ2xhdXNlXG4gKiBAZXh0ZW5kcyBDbGF1c2VcbiAqIEBpbXBsZW1lbnRzIE9yZGVyQW5kR3JvdXBPcHRpb25cbiAqXG4gKiBAY2F0ZWdvcnkgUXVlcnlcbiAqIEBzdWJjYXRlZ29yeSBDbGF1c2VzXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBXaGVyZUNsYXVzZTxRPlxuICBleHRlbmRzIENsYXVzZTxRPlxuICBpbXBsZW1lbnRzIE9yZGVyQW5kR3JvdXBPcHRpb25cbntcbiAgQHJlcXVpcmVkKClcbiAgQHR5cGUoXCJDb25kaXRpb25cIilcbiAgY29uZGl0aW9uPzogQ29uZGl0aW9uID0gdW5kZWZpbmVkO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihjbGF1c2U/OiBNb2RlbEFyZzxXaGVyZUNsYXVzZTxRPj4pIHtcbiAgICBzdXBlcihPYmplY3QuYXNzaWduKHt9LCBjbGF1c2UsIHsgcHJpb3JpdHk6IFByaW9yaXR5LldIRVJFIH0pKTtcbiAgICB0aGlzLmNvbmRpdGlvbiA9IGNsYXVzZT8uY29uZGl0aW9uO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgYWJzdHJhY3QgYnVpbGQocXVlcnk6IFEpOiBRO1xuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIG9yZGVyQnkoLi4uc2VsZWN0b3I6IE9yZGVyQnlTZWxlY3RvcltdKTogTGltaXRPcHRpb24gJiBPZmZzZXRPcHRpb24ge1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMub3JkZXJCeSh0aGlzLnN0YXRlbWVudCwgc2VsZWN0b3IpO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgZ3JvdXBCeShzZWxlY3RvcjogR3JvdXBCeVNlbGVjdG9yKTogRXhlY3V0b3Ige1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMuZ3JvdXBCeSh0aGlzLnN0YXRlbWVudCwgc2VsZWN0b3IpO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgbGltaXQoc2VsZWN0b3I6IExpbWl0U2VsZWN0b3IpOiBPZmZzZXRPcHRpb24ge1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMubGltaXQodGhpcy5zdGF0ZW1lbnQsIHNlbGVjdG9yKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIG9mZnNldChzZWxlY3RvcjogT2Zmc2V0U2VsZWN0b3IpOiBFeGVjdXRvciB7XG4gICAgcmV0dXJuIHRoaXMuQ2xhdXNlcy5vZmZzZXQodGhpcy5zdGF0ZW1lbnQsIHNlbGVjdG9yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgaGFzRXJyb3JzKC4uLmV4Y2VwdGlvbnM6IHN0cmluZ1tdKTogTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGVycm9ycyA9IHN1cGVyLmhhc0Vycm9ycyguLi5leGNlcHRpb25zKTtcbiAgICBpZiAoZXJyb3JzKSByZXR1cm4gZXJyb3JzO1xuICAgIHJldHVybiB0aGlzLmNvbmRpdGlvbiEuaGFzRXJyb3JzKCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IEZyb21DbGF1c2UgfSBmcm9tIFwiLi9jbGF1c2VzXCI7XG5pbXBvcnQgeyBHcm91cEJ5Q2xhdXNlIH0gZnJvbSBcIi4vY2xhdXNlcy9Hcm91cEJ5Q2xhdXNlXCI7XG5pbXBvcnQgeyBJbnNlcnRDbGF1c2UgfSBmcm9tIFwiLi9jbGF1c2VzL0luc2VydENsYXVzZVwiO1xuaW1wb3J0IHsgTGltaXRDbGF1c2UgfSBmcm9tIFwiLi9jbGF1c2VzL0xpbWl0Q2xhdXNlXCI7XG5pbXBvcnQgeyBPZmZzZXRDbGF1c2UgfSBmcm9tIFwiLi9jbGF1c2VzL09mZnNldENsYXVzZVwiO1xuaW1wb3J0IHsgT3JkZXJCeUNsYXVzZSB9IGZyb20gXCIuL2NsYXVzZXMvT3JkZXJCeUNsYXVzZVwiO1xuaW1wb3J0IHsgU2VsZWN0Q2xhdXNlIH0gZnJvbSBcIi4vY2xhdXNlcy9TZWxlY3RDbGF1c2VcIjtcbmltcG9ydCB7IFZhbHVlc0NsYXVzZSB9IGZyb20gXCIuL2NsYXVzZXMvVmFsdWVzQ2xhdXNlXCI7XG5pbXBvcnQgeyBXaGVyZUNsYXVzZSB9IGZyb20gXCIuL2NsYXVzZXMvV2hlcmVDbGF1c2VcIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2VcIjtcbmltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuL0NvbmRpdGlvblwiO1xuaW1wb3J0IHtcbiAgRnJvbVNlbGVjdG9yLFxuICBHcm91cEJ5U2VsZWN0b3IsXG4gIExpbWl0U2VsZWN0b3IsXG4gIE9mZnNldFNlbGVjdG9yLFxuICBPcmRlckJ5U2VsZWN0b3IsXG4gIFNlbGVjdFNlbGVjdG9yLFxufSBmcm9tIFwiLi9zZWxlY3RvcnNcIjtcbmltcG9ydCB7IFN0YXRlbWVudCB9IGZyb20gXCIuL1N0YXRlbWVudFwiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDbGF1c2VGYWN0b3J5PFksIFE+IHtcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIGZvciB7QGxpbmsgRnJvbUNsYXVzZX1cbiAgICogQHBhcmFtIHtTdGF0ZW1lbnR9IHN0YXRlbWVudFxuICAgKiBAcGFyYW0ge0Zyb21TZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIGFic3RyYWN0IGZyb208TSBleHRlbmRzIE1vZGVsPihcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxRPixcbiAgICBzZWxlY3RvcjogRnJvbVNlbGVjdG9yPE0+XG4gICk6IEZyb21DbGF1c2U8USwgTT47XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBGYWN0b3J5IG1ldGhvZCBmb3Ige0BsaW5rIEdyb3VwQnlDbGF1c2V9XG4gICAqIEBwYXJhbSB7U3RhdGVtZW50fSBzdGF0ZW1lbnRcbiAgICogQHBhcmFtIHtHcm91cEJ5U2VsZWN0b3J9IHNlbGVjdG9yXG4gICAqL1xuICBhYnN0cmFjdCBncm91cEJ5KFxuICAgIHN0YXRlbWVudDogU3RhdGVtZW50PFE+LFxuICAgIHNlbGVjdG9yOiBHcm91cEJ5U2VsZWN0b3JcbiAgKTogR3JvdXBCeUNsYXVzZTxRPjtcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIGZvciB7QGxpbmsgSW5zZXJ0Q2xhdXNlfVxuICAgKiBAcGFyYW0ge1N0YXRlbWVudH0gc3RhdGVtZW50XG4gICAqL1xuICBhYnN0cmFjdCBpbnNlcnQ8TSBleHRlbmRzIE1vZGVsPigpOiBJbnNlcnRDbGF1c2U8USwgTT47XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBGYWN0b3J5IG1ldGhvZCBmb3Ige0BsaW5rIExpbWl0Q2xhdXNlfVxuICAgKiBAcGFyYW0ge1N0YXRlbWVudH0gc3RhdGVtZW50XG4gICAqIEBwYXJhbSB7TGltaXRTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIGFic3RyYWN0IGxpbWl0KFxuICAgIHN0YXRlbWVudDogU3RhdGVtZW50PFE+LFxuICAgIHNlbGVjdG9yOiBMaW1pdFNlbGVjdG9yXG4gICk6IExpbWl0Q2xhdXNlPFE+O1xuICAvKipcbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgZm9yIHtAbGluayBPZmZzZXRDbGF1c2V9XG4gICAqIEBwYXJhbSB7U3RhdGVtZW50fSBzdGF0ZW1lbnRcbiAgICogQHBhcmFtIHtPZmZzZXRTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIGFic3RyYWN0IG9mZnNldChcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxRPixcbiAgICBzZWxlY3RvcjogT2Zmc2V0U2VsZWN0b3JcbiAgKTogT2Zmc2V0Q2xhdXNlPFE+O1xuICAvKipcbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgZm9yIHtAbGluayBPcmRlckJ5Q2xhdXNlfVxuICAgKiBAcGFyYW0ge1N0YXRlbWVudH0gc3RhdGVtZW50XG4gICAqIEBwYXJhbSB7T3JkZXJCeVNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgYWJzdHJhY3Qgb3JkZXJCeShcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxRPixcbiAgICBzZWxlY3RvcjogT3JkZXJCeVNlbGVjdG9yW11cbiAgKTogT3JkZXJCeUNsYXVzZTxRPjtcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIGZvciB7QGxpbmsgU2VsZWN0Q2xhdXNlfVxuICAgKiBAcGFyYW0ge1N0YXRlbWVudH0gc3RhdGVtZW50XG4gICAqIEBwYXJhbSB7U2VsZWN0U2VsZWN0b3J9IFtzZWxlY3Rvcl1cbiAgICovXG4gIGFic3RyYWN0IHNlbGVjdDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIHNlbGVjdG9yPzogU2VsZWN0U2VsZWN0b3JcbiAgKTogU2VsZWN0Q2xhdXNlPFEsIE0+O1xuICAvKipcbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgZm9yIHtAbGluayBWYWx1ZXNDbGF1c2V9XG4gICAqIEBwYXJhbSB7U3RhdGVtZW50fSBzdGF0ZW1lbnRcbiAgICogQHBhcmFtIHtNW119IHZhbHVlc1xuICAgKi9cbiAgYWJzdHJhY3QgdmFsdWVzPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgc3RhdGVtZW50OiBTdGF0ZW1lbnQ8UT4sXG4gICAgdmFsdWVzOiBNW11cbiAgKTogVmFsdWVzQ2xhdXNlPFEsIE0+O1xuICAvKipcbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgZm9yIHtAbGluayBXaGVyZUNsYXVzZX1cbiAgICogQHBhcmFtIHtTdGF0ZW1lbnR9IHN0YXRlbWVudFxuICAgKiBAcGFyYW0ge0NvbmRpdGlvbn0gY29uZGl0aW9uXG4gICAqL1xuICBhYnN0cmFjdCB3aGVyZShzdGF0ZW1lbnQ6IFN0YXRlbWVudDxRPiwgY29uZGl0aW9uOiBDb25kaXRpb24pOiBXaGVyZUNsYXVzZTxRPjtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IocHJvdGVjdGVkIGFkYXB0ZXI6IEFkYXB0ZXI8WSwgUT4pIHt9XG59XG4iLCJpbXBvcnQgeyBQYWdpbmdFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuaW1wb3J0IHsgU3RhdGVtZW50IH0gZnJvbSBcIi4vU3RhdGVtZW50XCI7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBQYWdpbmF0b3I8ViwgUT4ge1xuICBwcm90ZWN0ZWQgX2N1cnJlbnRQYWdlITogbnVtYmVyO1xuICBwcm90ZWN0ZWQgX3RvdGFsUGFnZXMhOiBudW1iZXI7XG4gIHByb3RlY3RlZCBfcmVjb3JkQ291bnQhOiBudW1iZXI7XG4gIHByb3RlY3RlZCBsaW1pdCE6IG51bWJlcjtcblxuICBwcml2YXRlIF9zdGF0ZW1lbnQ/OiBRO1xuXG4gIGdldCBjdXJyZW50KCkge1xuICAgIHJldHVybiB0aGlzLl9jdXJyZW50UGFnZTtcbiAgfVxuXG4gIGdldCB0b3RhbCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdG90YWxQYWdlcztcbiAgfVxuXG4gIGdldCBjb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9yZWNvcmRDb3VudDtcbiAgfVxuXG4gIGdldCBzdGF0ZW1lbnQoKSB7XG4gICAgaWYgKCF0aGlzLl9zdGF0ZW1lbnQpIHRoaXMuX3N0YXRlbWVudCA9IHRoaXMucHJlcGFyZSh0aGlzLl9yYXdTdGF0ZW1lbnQpO1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZW1lbnQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGFkYXB0ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdC5nZXRBZGFwdGVyKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHN0YXQ6IFN0YXRlbWVudDxRPixcbiAgICByZWFkb25seSBzaXplOiBudW1iZXIsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IF9yYXdTdGF0ZW1lbnQ6IFFcbiAgKSB7fVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwcmVwYXJlKHJhd1N0YXRlbWVudDogUSk6IFE7XG5cbiAgYXN5bmMgbmV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy5wYWdlKHRoaXMuY3VycmVudCArIDEpO1xuICB9XG5cbiAgYXN5bmMgcHJldmlvdXMoKSB7XG4gICAgcmV0dXJuIHRoaXMucGFnZSh0aGlzLmN1cnJlbnQgLSAxKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB2YWxpZGF0ZVBhZ2UocGFnZTogbnVtYmVyKSB7XG4gICAgaWYgKHBhZ2UgPCAxIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHBhZ2UpKVxuICAgICAgdGhyb3cgbmV3IFBhZ2luZ0Vycm9yKFxuICAgICAgICBcInBhZ2UgbnVtYmVyIGNhbm5vdCBiZSB1bmRlciAxIGFuZCBtdXN0IGJlIGFuIGludGVnZXJcIlxuICAgICAgKTtcbiAgICBpZiAocGFnZSA+IHRoaXMuX3RvdGFsUGFnZXMpXG4gICAgICB0aHJvdyBuZXcgUGFnaW5nRXJyb3IoXG4gICAgICAgIFwicGFnZSBudW1iZXIgY2Fubm90IGJlIHVuZGVyIDEgYW5kIG11c3QgYmUgYW4gaW50ZWdlclwiXG4gICAgICApO1xuICB9XG5cbiAgYWJzdHJhY3QgcGFnZShwYWdlPzogbnVtYmVyLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8VltdPjtcbn1cbiIsImltcG9ydCB7IEluamVjdGFibGVzUmVnaXN0cnkgfSBmcm9tIFwiLi9yZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBJbmplY3RhYmxlcyB9IGZyb20gXCJAZGVjYWYtdHMvaW5qZWN0YWJsZS1kZWNvcmF0b3JzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgTW9kdWxlIHN1bW1hcnlcbiAqIEBkZXNjcmlwdGlvbiBNb2R1bGUgZGVzY3JpcHRpb25cbiAqIEBtb2R1bGUgdHMtd29ya3NwYWNlXG4gKi9cblxuLyoqXG4gKiBAc3VtbWFyeSBOYW1lc3BhY2Ugc3VtbWFyeVxuICogQGRlc2NyaXB0aW9uIE5hbWVzcGFjZSBkZXNjcmlwdGlvblxuICogQG5hbWVzcGFjZSBOYW1lc3BhY2VcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dHMtd29ya3NwYWNlXG4gKi9cblxuZXhwb3J0ICogZnJvbSBcIi4vaWRlbnRpdHlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ludGVyZmFjZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL21vZGVsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9wZXJzaXN0ZW5jZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vcXVlcnlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3JlcG9zaXRvcnlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3ZhbGlkYXRvcnNcIjtcblxuSW5qZWN0YWJsZXMuc2V0UmVnaXN0cnkobmV3IEluamVjdGFibGVzUmVnaXN0cnkoKSk7XG5cbi8qKlxuICogQHN1bW1hcnkgc3RvcmVzIHRoZSBjdXJyZW50IHBhY2thZ2UgdmVyc2lvblxuICogQGRlc2NyaXB0aW9uIHRoaXMgaXMgaG93IHlvdSBzaG91bGQgZG9jdW1lbnQgYSBjb25zdGFudFxuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dHMtd29ya3NwYWNlXG4gKi9cbmV4cG9ydCBjb25zdCBWRVJTSU9OID0gXCIjI1ZFUlNJT04jI1wiO1xuIl0sIm5hbWVzIjpbIk9yZGVyRGlyZWN0aW9uIiwiQ2FzY2FkZSIsIkN0eCIsIlBlcnNpc3RlbmNlS2V5cyIsIlJvbGVzIiwiT3BlcmF0b3IiLCJHcm91cE9wZXJhdG9yIiwiQ29uc3QiLCJQcmlvcml0eSIsIlN0YXRlbWVudFR5cGUiLCJCYXNlRXJyb3IiLCJJbnRlcm5hbEVycm9yIiwiTW9kZWwiLCJOb3RGb3VuZEVycm9yIiwiREJLZXlzIiwiYXBwbHkiLCJtZXRhZGF0YSIsIlJlcCIsIndyYXBNZXRob2RXaXRoQ29udGV4dCIsIk9wZXJhdGlvbktleXMiLCJlbmZvcmNlREJEZWNvcmF0b3JzIiwiVmFsaWRhdGlvbkVycm9yIiwiZmluZFByaW1hcnlLZXkiLCJSZWZsZWN0aW9uIiwiaW5qZWN0IiwiaW5qZWN0YWJsZSIsInNmIiwiSW5qZWN0YWJsZVJlZ2lzdHJ5SW1wIiwiSW5qZWN0YWJsZXMiLCJyZXF1aXJlZCIsIlZhbGlkYXRpb24iLCJWYWxpZGF0aW9uS2V5cyIsInByb3BNZXRhZGF0YSIsIkNvbmZsaWN0RXJyb3IiLCJvbkNyZWF0ZVVwZGF0ZSIsIm9uQ3JlYXRlIiwicG9wdWxhdGUiLCJwcm9wIiwidHlwZSIsIm9uVXBkYXRlIiwib25EZWxldGUiLCJhZnRlckFueSIsInBvcCIsImxpc3QiLCJyZWFkb25seSIsInRpbWVzdGFtcCIsIkRCT3BlcmF0aW9ucyIsIlVzZXIiLCJtb2RlbCIsIkRFRkFVTFRfRVJST1JfTUVTU0FHRVMiLCJDbGF1c2VTZXF1ZW5jZVZhbGlkYXRvciIsIlZhbGlkYXRvciIsImlzRXF1YWwiLCJ2YWxpZGF0b3IiLCJtaW5sZW5ndGgiLCJzdHJpbmdGb3JtYXQiXSwibWFwcGluZ3MiOiI7Ozs7OztJQUVBOzs7Ozs7SUFNRztBQUNTQTtJQUFaLENBQUEsVUFBWSxjQUFjLEVBQUE7SUFDeEI7OztJQUdHO0lBQ0gsSUFBQSxjQUFBLENBQUEsS0FBQSxDQUFBLEdBQUEsS0FBVztJQUNY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
|