angular-odata 0.122.0 → 0.124.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/api.mjs +373 -0
- package/esm2022/lib/cache/cache.mjs +175 -0
- package/{esm2020 → esm2022}/lib/cache/storage.mjs +1 -1
- package/esm2022/lib/client.mjs +252 -0
- package/{esm2020 → esm2022}/lib/helper.mjs +1 -1
- package/{esm2020 → esm2022}/lib/loaders.mjs +1 -1
- package/esm2022/lib/models/collection.mjs +865 -0
- package/esm2022/lib/models/model.mjs +535 -0
- package/esm2022/lib/models/options.mjs +1117 -0
- package/{esm2020 → esm2022}/lib/module.mjs +5 -5
- package/esm2022/lib/resources/path/segments.mjs +124 -0
- package/esm2022/lib/resources/query/builder.mjs +624 -0
- package/esm2022/lib/resources/query/expressions/base.mjs +20 -0
- package/esm2022/lib/resources/query/expressions/compute.mjs +39 -0
- package/esm2022/lib/resources/query/expressions/count.mjs +99 -0
- package/esm2022/lib/resources/query/expressions/expand.mjs +125 -0
- package/esm2022/lib/resources/query/expressions/filter.mjs +161 -0
- package/esm2022/lib/resources/query/expressions/orderby.mjs +56 -0
- package/esm2022/lib/resources/query/expressions/search.mjs +122 -0
- package/esm2022/lib/resources/query/expressions/select.mjs +31 -0
- package/esm2022/lib/resources/query/expressions/syntax.mjs +444 -0
- package/{esm2020 → esm2022}/lib/resources/query/handlers.mjs +1 -1
- package/esm2022/lib/resources/query/options.mjs +115 -0
- package/{esm2020 → esm2022}/lib/resources/request.mjs +1 -1
- package/esm2022/lib/resources/resource.mjs +257 -0
- package/{esm2020 → esm2022}/lib/resources/responses/annotations.mjs +1 -1
- package/esm2022/lib/resources/responses/csdl/csdl-annotation.mjs +33 -0
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-entity-container.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-entity-set.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-enum-type.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-function-action.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-navigation-property-binding.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-reference.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-schema.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-singleton.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-structural-property.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-structured-type.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/responses/csdl/csdl-type-definition.mjs +1 -1
- package/esm2022/lib/resources/responses/metadata.mjs +547 -0
- package/{esm2020 → esm2022}/lib/resources/responses/response.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/action.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/batch.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/count.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/entity-set.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/entity.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/function.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/media.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/navigation-property.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/property.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/reference.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/singleton.mjs +1 -1
- package/{esm2020 → esm2022}/lib/resources/types/value.mjs +1 -1
- package/{esm2020 → esm2022}/lib/schema/annotation.mjs +1 -1
- package/{esm2020 → esm2022}/lib/schema/callable.mjs +1 -1
- package/{esm2020 → esm2022}/lib/schema/element.mjs +1 -1
- package/{esm2020 → esm2022}/lib/schema/entity-container.mjs +1 -1
- package/{esm2020 → esm2022}/lib/schema/enum-type.mjs +1 -1
- package/{esm2020 → esm2022}/lib/schema/parsers/callable.mjs +1 -1
- package/esm2022/lib/schema/parsers/edm.mjs +99 -0
- package/{esm2020 → esm2022}/lib/schema/parsers/enum-type.mjs +2 -2
- package/esm2022/lib/schema/parsers/structured-type.mjs +502 -0
- package/{esm2020 → esm2022}/lib/schema/schema.mjs +1 -1
- package/esm2022/lib/schema/structured-type.mjs +207 -0
- package/esm2022/lib/services/base.mjs +29 -0
- package/{esm2020 → esm2022}/lib/services/entity-set.mjs +1 -1
- package/{esm2020 → esm2022}/lib/services/factory.mjs +4 -4
- package/{esm2020 → esm2022}/lib/services/singleton.mjs +1 -1
- package/{esm2020 → esm2022}/lib/settings.mjs +1 -1
- package/{esm2020 → esm2022}/lib/types.mjs +1 -1
- package/{esm2020 → esm2022}/lib/utils/arrays.mjs +1 -1
- package/{esm2020 → esm2022}/lib/utils/durations.mjs +1 -1
- package/esm2022/lib/utils/enums.mjs +61 -0
- package/{esm2020 → esm2022}/lib/utils/http.mjs +1 -1
- package/{esm2020 → esm2022}/lib/utils/objects.mjs +1 -1
- package/{esm2020 → esm2022}/lib/utils/odata.mjs +1 -1
- package/esm2022/lib/utils/types.mjs +136 -0
- package/{fesm2020 → fesm2022}/angular-odata.mjs +544 -373
- package/fesm2022/angular-odata.mjs.map +1 -0
- package/lib/helper.d.ts +1 -1
- package/lib/models/model.d.ts +4 -2
- package/lib/models/options.d.ts +7 -8
- package/lib/resources/path/segments.d.ts +15 -6
- package/lib/resources/query/builder.d.ts +21 -20
- package/lib/resources/query/expressions/base.d.ts +6 -4
- package/lib/resources/query/expressions/compute.d.ts +10 -8
- package/lib/resources/query/expressions/count.d.ts +14 -11
- package/lib/resources/query/expressions/expand.d.ts +23 -19
- package/lib/resources/query/expressions/filter.d.ts +22 -20
- package/lib/resources/query/expressions/orderby.d.ts +12 -9
- package/lib/resources/query/expressions/search.d.ts +12 -9
- package/lib/resources/query/expressions/select.d.ts +9 -7
- package/lib/resources/query/expressions/syntax.d.ts +75 -71
- package/lib/resources/query/handlers.d.ts +2 -2
- package/lib/resources/query/options.d.ts +15 -6
- package/lib/resources/resource.d.ts +2 -2
- package/lib/resources/responses/types.d.ts +3 -3
- package/lib/resources/types/options.d.ts +7 -7
- package/lib/schema/parsers/structured-type.d.ts +8 -5
- package/lib/schema/structured-type.d.ts +2 -1
- package/lib/types.d.ts +15 -15
- package/lib/utils/durations.d.ts +1 -1
- package/lib/utils/enums.d.ts +3 -0
- package/lib/utils/types.d.ts +1 -0
- package/package.json +9 -15
- package/esm2020/lib/api.mjs +0 -373
- package/esm2020/lib/cache/cache.mjs +0 -173
- package/esm2020/lib/client.mjs +0 -252
- package/esm2020/lib/models/collection.mjs +0 -861
- package/esm2020/lib/models/model.mjs +0 -507
- package/esm2020/lib/models/options.mjs +0 -1110
- package/esm2020/lib/resources/path/segments.mjs +0 -124
- package/esm2020/lib/resources/query/builder.mjs +0 -588
- package/esm2020/lib/resources/query/expressions/base.mjs +0 -20
- package/esm2020/lib/resources/query/expressions/compute.mjs +0 -39
- package/esm2020/lib/resources/query/expressions/count.mjs +0 -89
- package/esm2020/lib/resources/query/expressions/expand.mjs +0 -115
- package/esm2020/lib/resources/query/expressions/filter.mjs +0 -161
- package/esm2020/lib/resources/query/expressions/orderby.mjs +0 -56
- package/esm2020/lib/resources/query/expressions/search.mjs +0 -122
- package/esm2020/lib/resources/query/expressions/select.mjs +0 -31
- package/esm2020/lib/resources/query/expressions/syntax.mjs +0 -409
- package/esm2020/lib/resources/query/options.mjs +0 -115
- package/esm2020/lib/resources/resource.mjs +0 -251
- package/esm2020/lib/resources/responses/csdl/csdl-annotation.mjs +0 -33
- package/esm2020/lib/resources/responses/metadata.mjs +0 -547
- package/esm2020/lib/schema/parsers/edm.mjs +0 -104
- package/esm2020/lib/schema/parsers/structured-type.mjs +0 -490
- package/esm2020/lib/schema/structured-type.mjs +0 -202
- package/esm2020/lib/services/base.mjs +0 -29
- package/esm2020/lib/utils/enums.mjs +0 -45
- package/esm2020/lib/utils/types.mjs +0 -133
- package/fesm2015/angular-odata.mjs +0 -11811
- package/fesm2015/angular-odata.mjs.map +0 -1
- package/fesm2020/angular-odata.mjs.map +0 -1
- /package/{esm2020 → esm2022}/angular-odata.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/cache/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/cache/memory.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/constants.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/models/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/options.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/path/handlers.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/path/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/query/expressions/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/query/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/responses/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/responses/options.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/responses/types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/types/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/types/metadata.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/resources/types/options.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/schema/entity-set.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/schema/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/schema/parsers/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/services/entity.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/services/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/arraybuffers.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/dates.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/strings.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/urls.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
|
@@ -1,588 +0,0 @@
|
|
|
1
|
-
const COMPARISON_OPERATORS = ['eq', 'ne', 'gt', 'ge', 'lt', 'le'];
|
|
2
|
-
const LOGICAL_OPERATORS = ['and', 'or', 'not'];
|
|
3
|
-
const COLLECTION_OPERATORS = ['any', 'all'];
|
|
4
|
-
const BOOLEAN_FUNCTIONS = ['startswith', 'endswith', 'contains'];
|
|
5
|
-
const SUPPORTED_EXPAND_PROPERTIES = [
|
|
6
|
-
'expand',
|
|
7
|
-
'levels',
|
|
8
|
-
'select',
|
|
9
|
-
'top',
|
|
10
|
-
'count',
|
|
11
|
-
'orderby',
|
|
12
|
-
'filter',
|
|
13
|
-
];
|
|
14
|
-
const FUNCTION_REGEX = /\((.*)\)/;
|
|
15
|
-
const INDEXOF_REGEX = /(?!indexof)\((\w+)\)/;
|
|
16
|
-
export var StandardAggregateMethods;
|
|
17
|
-
(function (StandardAggregateMethods) {
|
|
18
|
-
StandardAggregateMethods["sum"] = "sum";
|
|
19
|
-
StandardAggregateMethods["min"] = "min";
|
|
20
|
-
StandardAggregateMethods["max"] = "max";
|
|
21
|
-
StandardAggregateMethods["average"] = "average";
|
|
22
|
-
StandardAggregateMethods["countdistinct"] = "countdistinct";
|
|
23
|
-
})(StandardAggregateMethods || (StandardAggregateMethods = {}));
|
|
24
|
-
export var QueryCustomTypes;
|
|
25
|
-
(function (QueryCustomTypes) {
|
|
26
|
-
QueryCustomTypes[QueryCustomTypes["Raw"] = 0] = "Raw";
|
|
27
|
-
QueryCustomTypes[QueryCustomTypes["Alias"] = 1] = "Alias";
|
|
28
|
-
QueryCustomTypes[QueryCustomTypes["Duration"] = 2] = "Duration";
|
|
29
|
-
QueryCustomTypes[QueryCustomTypes["Binary"] = 3] = "Binary";
|
|
30
|
-
})(QueryCustomTypes || (QueryCustomTypes = {}));
|
|
31
|
-
//https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_QueryOptions
|
|
32
|
-
export const raw = (value) => ({
|
|
33
|
-
type: QueryCustomTypes.Raw,
|
|
34
|
-
value,
|
|
35
|
-
});
|
|
36
|
-
export const alias = (value, name) => ({
|
|
37
|
-
type: QueryCustomTypes.Alias,
|
|
38
|
-
value,
|
|
39
|
-
name,
|
|
40
|
-
});
|
|
41
|
-
export const duration = (value) => ({
|
|
42
|
-
type: QueryCustomTypes.Duration,
|
|
43
|
-
value,
|
|
44
|
-
});
|
|
45
|
-
export const binary = (value) => ({
|
|
46
|
-
type: QueryCustomTypes.Binary,
|
|
47
|
-
value,
|
|
48
|
-
});
|
|
49
|
-
export const isQueryCustomType = (value) => typeof value === 'object' &&
|
|
50
|
-
'type' in value &&
|
|
51
|
-
value.type in QueryCustomTypes;
|
|
52
|
-
export const ITEM_ROOT = '';
|
|
53
|
-
export default function ({ select, search, skiptoken, format, top, skip, filter, transform, orderBy, key, count, expand, action, func, aliases, escape, } = {}) {
|
|
54
|
-
const [path, params] = buildPathAndQuery({
|
|
55
|
-
select,
|
|
56
|
-
search,
|
|
57
|
-
skiptoken,
|
|
58
|
-
format,
|
|
59
|
-
top,
|
|
60
|
-
skip,
|
|
61
|
-
filter,
|
|
62
|
-
transform,
|
|
63
|
-
orderBy,
|
|
64
|
-
key,
|
|
65
|
-
count,
|
|
66
|
-
expand,
|
|
67
|
-
action,
|
|
68
|
-
func,
|
|
69
|
-
aliases,
|
|
70
|
-
escape,
|
|
71
|
-
});
|
|
72
|
-
return buildUrl(path, params);
|
|
73
|
-
}
|
|
74
|
-
export function buildPathAndQuery({ select, search, skiptoken, format, top, skip, filter, transform, orderBy, key, count, expand, action, func, aliases, escape, } = {}) {
|
|
75
|
-
let path = '';
|
|
76
|
-
aliases = aliases || [];
|
|
77
|
-
const query = {};
|
|
78
|
-
// key is not (null, undefined)
|
|
79
|
-
if (key != undefined) {
|
|
80
|
-
path += `(${normalizeValue(key, { aliases, escape })})`;
|
|
81
|
-
}
|
|
82
|
-
if (select) {
|
|
83
|
-
query.$select = Array.isArray(select) ? select.join(',') : select;
|
|
84
|
-
}
|
|
85
|
-
if (search) {
|
|
86
|
-
query.$search = search;
|
|
87
|
-
}
|
|
88
|
-
if (skiptoken) {
|
|
89
|
-
query.$skiptoken = skiptoken;
|
|
90
|
-
}
|
|
91
|
-
if (format) {
|
|
92
|
-
query.$format = format;
|
|
93
|
-
}
|
|
94
|
-
if (filter || typeof count === 'object') {
|
|
95
|
-
query.$filter = buildFilter(typeof count === 'object' ? count : filter, {
|
|
96
|
-
aliases,
|
|
97
|
-
escape,
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
if (transform) {
|
|
101
|
-
query.$apply = buildTransforms(transform, { aliases, escape });
|
|
102
|
-
}
|
|
103
|
-
if (expand) {
|
|
104
|
-
query.$expand = buildExpand(expand, { aliases, escape });
|
|
105
|
-
}
|
|
106
|
-
if (orderBy) {
|
|
107
|
-
query.$orderby = buildOrderBy(orderBy);
|
|
108
|
-
}
|
|
109
|
-
if (count) {
|
|
110
|
-
if (typeof count === 'boolean') {
|
|
111
|
-
query.$count = true;
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
path += '/$count';
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (typeof top === 'number') {
|
|
118
|
-
query.$top = top;
|
|
119
|
-
}
|
|
120
|
-
if (typeof skip === 'number') {
|
|
121
|
-
query.$skip = skip;
|
|
122
|
-
}
|
|
123
|
-
if (action) {
|
|
124
|
-
path += `/${action}`;
|
|
125
|
-
}
|
|
126
|
-
if (func) {
|
|
127
|
-
if (typeof func === 'string') {
|
|
128
|
-
path += `/${func}()`;
|
|
129
|
-
}
|
|
130
|
-
else if (typeof func === 'object') {
|
|
131
|
-
const [funcName] = Object.keys(func);
|
|
132
|
-
const funcArgs = normalizeValue(func[funcName], {
|
|
133
|
-
aliases,
|
|
134
|
-
escape,
|
|
135
|
-
});
|
|
136
|
-
path += `/${funcName}(${funcArgs})`;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
if (aliases.length > 0) {
|
|
140
|
-
Object.assign(query, aliases.reduce((acc, alias) => Object.assign(acc, {
|
|
141
|
-
[`@${alias.name}`]: normalizeValue(alias.value, {
|
|
142
|
-
escape,
|
|
143
|
-
}),
|
|
144
|
-
}), {}));
|
|
145
|
-
}
|
|
146
|
-
// Filter empty values
|
|
147
|
-
const params = Object.entries(query)
|
|
148
|
-
.filter(([, value]) => value !== undefined && value !== '')
|
|
149
|
-
.reduce((acc, [key, value]) => Object.assign(acc, { [key]: value }), {});
|
|
150
|
-
return [path, params];
|
|
151
|
-
}
|
|
152
|
-
function renderPrimitiveValue(key, val, { aliases, escape, }) {
|
|
153
|
-
return `${key} eq ${normalizeValue(val, { aliases, escape })}`;
|
|
154
|
-
}
|
|
155
|
-
function buildFilter(filters = {}, { aliases, propPrefix, escape, }) {
|
|
156
|
-
return (Array.isArray(filters) ? filters : [filters]).reduce((acc, filter) => {
|
|
157
|
-
if (filter) {
|
|
158
|
-
const builtFilter = buildFilterCore(filter, {
|
|
159
|
-
aliases,
|
|
160
|
-
propPrefix,
|
|
161
|
-
escape,
|
|
162
|
-
});
|
|
163
|
-
if (builtFilter) {
|
|
164
|
-
acc.push(builtFilter);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return acc;
|
|
168
|
-
}, []).join(' and ');
|
|
169
|
-
function buildFilterCore(filter = {}, { aliases, propPrefix, escape, }) {
|
|
170
|
-
let filterExpr = '';
|
|
171
|
-
if (typeof filter === 'string') {
|
|
172
|
-
// Use raw filter string
|
|
173
|
-
filterExpr = filter;
|
|
174
|
-
}
|
|
175
|
-
else if (filter && typeof filter === 'object') {
|
|
176
|
-
const filtersArray = Object.keys(filter).reduce((result, filterKey) => {
|
|
177
|
-
const value = filter[filterKey];
|
|
178
|
-
let propName = '';
|
|
179
|
-
if (propPrefix) {
|
|
180
|
-
if (filterKey === ITEM_ROOT) {
|
|
181
|
-
propName = propPrefix;
|
|
182
|
-
}
|
|
183
|
-
else if (INDEXOF_REGEX.test(filterKey)) {
|
|
184
|
-
propName = filterKey.replace(INDEXOF_REGEX, (_, $1) => $1.trim() === ITEM_ROOT
|
|
185
|
-
? `(${propPrefix})`
|
|
186
|
-
: `(${propPrefix}/${$1.trim()})`);
|
|
187
|
-
}
|
|
188
|
-
else if (FUNCTION_REGEX.test(filterKey)) {
|
|
189
|
-
propName = filterKey.replace(FUNCTION_REGEX, (_, $1) => $1.trim() === ITEM_ROOT
|
|
190
|
-
? `(${propPrefix})`
|
|
191
|
-
: `(${propPrefix}/${$1.trim()})`);
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
propName = `${propPrefix}/${filterKey}`;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
propName = filterKey;
|
|
199
|
-
}
|
|
200
|
-
if (filterKey === ITEM_ROOT && Array.isArray(value)) {
|
|
201
|
-
return result.concat(value.map((arrayValue) => renderPrimitiveValue(propName, arrayValue, { escape, aliases })));
|
|
202
|
-
}
|
|
203
|
-
if (['number', 'string', 'boolean'].indexOf(typeof value) !== -1 ||
|
|
204
|
-
value instanceof Date ||
|
|
205
|
-
value === null) {
|
|
206
|
-
// Simple key/value handled as equals operator
|
|
207
|
-
result.push(renderPrimitiveValue(propName, value, { aliases, escape }));
|
|
208
|
-
}
|
|
209
|
-
else if (Array.isArray(value)) {
|
|
210
|
-
const op = filterKey;
|
|
211
|
-
const builtFilters = value
|
|
212
|
-
.map((v) => buildFilter(v, { aliases, propPrefix, escape }))
|
|
213
|
-
.filter((f) => f)
|
|
214
|
-
.map((f) => LOGICAL_OPERATORS.indexOf(op) !== -1 ? `(${f})` : f);
|
|
215
|
-
if (builtFilters.length) {
|
|
216
|
-
if (LOGICAL_OPERATORS.indexOf(op) !== -1) {
|
|
217
|
-
if (builtFilters.length) {
|
|
218
|
-
if (op === 'not') {
|
|
219
|
-
result.push(parseNot(builtFilters));
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
result.push(`(${builtFilters.join(` ${op} `)})`);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
result.push(builtFilters.join(` ${op} `));
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
else if (LOGICAL_OPERATORS.indexOf(propName) !== -1) {
|
|
232
|
-
const op = propName;
|
|
233
|
-
const builtFilters = Object.keys(value).map((valueKey) => buildFilterCore({ [valueKey]: value[valueKey] }, { aliases, escape }));
|
|
234
|
-
if (builtFilters.length) {
|
|
235
|
-
if (op === 'not') {
|
|
236
|
-
result.push(parseNot(builtFilters));
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
result.push(`${builtFilters.join(` ${op} `)}`);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
else if (typeof value === 'object') {
|
|
244
|
-
if ('type' in value) {
|
|
245
|
-
result.push(renderPrimitiveValue(propName, value, { aliases, escape }));
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
const operators = Object.keys(value);
|
|
249
|
-
operators.forEach((op) => {
|
|
250
|
-
if (COMPARISON_OPERATORS.indexOf(op) !== -1) {
|
|
251
|
-
result.push(`${propName} ${op} ${normalizeValue(value[op], {
|
|
252
|
-
aliases,
|
|
253
|
-
escape,
|
|
254
|
-
})}`);
|
|
255
|
-
}
|
|
256
|
-
else if (LOGICAL_OPERATORS.indexOf(op) !== -1) {
|
|
257
|
-
if (Array.isArray(value[op])) {
|
|
258
|
-
result.push(value[op]
|
|
259
|
-
.map((v) => '(' +
|
|
260
|
-
buildFilterCore(v, {
|
|
261
|
-
aliases,
|
|
262
|
-
propPrefix: propName,
|
|
263
|
-
escape,
|
|
264
|
-
}) +
|
|
265
|
-
')')
|
|
266
|
-
.join(` ${op} `));
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
result.push('(' +
|
|
270
|
-
buildFilterCore(value[op], {
|
|
271
|
-
aliases,
|
|
272
|
-
propPrefix: propName,
|
|
273
|
-
escape,
|
|
274
|
-
}) +
|
|
275
|
-
')');
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
else if (COLLECTION_OPERATORS.indexOf(op) !== -1) {
|
|
279
|
-
const collectionClause = buildCollectionClause(filterKey.toLowerCase(), value[op], op, propName);
|
|
280
|
-
if (collectionClause) {
|
|
281
|
-
result.push(collectionClause);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
else if (op === 'has') {
|
|
285
|
-
result.push(`${propName} ${op} ${normalizeValue(value[op], {
|
|
286
|
-
aliases,
|
|
287
|
-
escape,
|
|
288
|
-
})}`);
|
|
289
|
-
}
|
|
290
|
-
else if (op === 'in') {
|
|
291
|
-
const resultingValues = Array.isArray(value[op])
|
|
292
|
-
? value[op]
|
|
293
|
-
: value[op].value.map((typedValue) => ({
|
|
294
|
-
type: value[op].type,
|
|
295
|
-
value: typedValue,
|
|
296
|
-
}));
|
|
297
|
-
result.push(propName +
|
|
298
|
-
' in (' +
|
|
299
|
-
resultingValues
|
|
300
|
-
.map((v) => normalizeValue(v, { aliases, escape }))
|
|
301
|
-
.join(',') +
|
|
302
|
-
')');
|
|
303
|
-
}
|
|
304
|
-
else if (BOOLEAN_FUNCTIONS.indexOf(op) !== -1) {
|
|
305
|
-
// Simple boolean functions (startswith, endswith, contains)
|
|
306
|
-
result.push(`${op}(${propName},${normalizeValue(value[op], {
|
|
307
|
-
aliases,
|
|
308
|
-
escape,
|
|
309
|
-
})})`);
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
// Nested property
|
|
313
|
-
const filter = buildFilterCore(value, {
|
|
314
|
-
aliases,
|
|
315
|
-
propPrefix: propName,
|
|
316
|
-
escape,
|
|
317
|
-
});
|
|
318
|
-
if (filter) {
|
|
319
|
-
result.push(filter);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
else if (value === undefined) {
|
|
326
|
-
// Ignore/omit filter if value is `undefined`
|
|
327
|
-
}
|
|
328
|
-
else {
|
|
329
|
-
throw new Error(`Unexpected value type: ${value}`);
|
|
330
|
-
}
|
|
331
|
-
return result;
|
|
332
|
-
}, []);
|
|
333
|
-
filterExpr = filtersArray.join(' and ');
|
|
334
|
-
} /* else {
|
|
335
|
-
throw new Error(`Unexpected filters type: ${filter}`);
|
|
336
|
-
} */
|
|
337
|
-
return filterExpr;
|
|
338
|
-
}
|
|
339
|
-
function buildCollectionClause(lambdaParameter, value, op, propName) {
|
|
340
|
-
let clause = '';
|
|
341
|
-
if (typeof value === 'string' || value instanceof String) {
|
|
342
|
-
clause = getStringCollectionClause(lambdaParameter, value, op, propName);
|
|
343
|
-
}
|
|
344
|
-
else if (value) {
|
|
345
|
-
// normalize {any:[{prop1: 1}, {prop2: 1}]} --> {any:{prop1: 1, prop2: 1}}; same for 'all',
|
|
346
|
-
// simple values collection: {any:[{'': 'simpleVal1'}, {'': 'simpleVal2'}]} --> {any:{'': ['simpleVal1', 'simpleVal2']}}; same for 'all',
|
|
347
|
-
const filterValue = Array.isArray(value)
|
|
348
|
-
? value.reduce((acc, item) => {
|
|
349
|
-
if (item.hasOwnProperty(ITEM_ROOT)) {
|
|
350
|
-
if (!acc.hasOwnProperty(ITEM_ROOT)) {
|
|
351
|
-
acc[ITEM_ROOT] = [];
|
|
352
|
-
}
|
|
353
|
-
acc[ITEM_ROOT].push(item[ITEM_ROOT]);
|
|
354
|
-
return acc;
|
|
355
|
-
}
|
|
356
|
-
return { ...acc, ...item };
|
|
357
|
-
}, {})
|
|
358
|
-
: value;
|
|
359
|
-
const filter = buildFilterCore(filterValue, {
|
|
360
|
-
aliases,
|
|
361
|
-
propPrefix: lambdaParameter,
|
|
362
|
-
escape,
|
|
363
|
-
});
|
|
364
|
-
clause = `${propName}/${op}(${filter ? `${lambdaParameter}:${filter}` : ''})`;
|
|
365
|
-
}
|
|
366
|
-
return clause;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
function getStringCollectionClause(lambdaParameter, value, collectionOperator, propName) {
|
|
370
|
-
let clause = '';
|
|
371
|
-
const conditionOperator = collectionOperator == 'all' ? 'ne' : 'eq';
|
|
372
|
-
clause = `${propName}/${collectionOperator}(${lambdaParameter}: ${lambdaParameter} ${conditionOperator} '${value}')`;
|
|
373
|
-
return clause;
|
|
374
|
-
}
|
|
375
|
-
function escapeIllegalChars(string) {
|
|
376
|
-
string = string.replace(/%/g, '%25');
|
|
377
|
-
string = string.replace(/\+/g, '%2B');
|
|
378
|
-
string = string.replace(/\//g, '%2F');
|
|
379
|
-
string = string.replace(/\?/g, '%3F');
|
|
380
|
-
string = string.replace(/#/g, '%23');
|
|
381
|
-
string = string.replace(/&/g, '%26');
|
|
382
|
-
string = string.replace(/'/g, "''");
|
|
383
|
-
return string;
|
|
384
|
-
}
|
|
385
|
-
export function normalizeValue(value, { aliases, escape = false, } = {}) {
|
|
386
|
-
if (typeof value === 'string') {
|
|
387
|
-
return escape ? `'${escapeIllegalChars(value)}'` : `'${value}'`;
|
|
388
|
-
}
|
|
389
|
-
else if (value instanceof Date) {
|
|
390
|
-
return value.toISOString();
|
|
391
|
-
}
|
|
392
|
-
else if (typeof value === 'number') {
|
|
393
|
-
return value;
|
|
394
|
-
}
|
|
395
|
-
else if (Array.isArray(value)) {
|
|
396
|
-
return `[${value
|
|
397
|
-
.map((d) => normalizeValue(d, { aliases, escape }))
|
|
398
|
-
.join(',')}]`;
|
|
399
|
-
}
|
|
400
|
-
else if (value === null) {
|
|
401
|
-
return value;
|
|
402
|
-
}
|
|
403
|
-
else if (typeof value === 'object') {
|
|
404
|
-
switch (value.type) {
|
|
405
|
-
case QueryCustomTypes.Raw:
|
|
406
|
-
return value.value;
|
|
407
|
-
case QueryCustomTypes.Duration:
|
|
408
|
-
return `duration'${value.value}'`;
|
|
409
|
-
case QueryCustomTypes.Binary:
|
|
410
|
-
return `binary'${value.value}'`;
|
|
411
|
-
case QueryCustomTypes.Alias:
|
|
412
|
-
// Store
|
|
413
|
-
if (Array.isArray(aliases)) {
|
|
414
|
-
if (value.name === undefined) {
|
|
415
|
-
value.name = `a${aliases.length + 1}`;
|
|
416
|
-
}
|
|
417
|
-
aliases.push(value);
|
|
418
|
-
}
|
|
419
|
-
return `@${value.name}`;
|
|
420
|
-
default:
|
|
421
|
-
return Object.entries(value)
|
|
422
|
-
.filter(([, v]) => v !== undefined)
|
|
423
|
-
.map(([k, v]) => `${k}=${normalizeValue(v, { aliases, escape })}`)
|
|
424
|
-
.join(',');
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
return value;
|
|
428
|
-
}
|
|
429
|
-
function buildExpand(expands, { aliases, escape = false }) {
|
|
430
|
-
if (typeof expands === 'number') {
|
|
431
|
-
return expands;
|
|
432
|
-
}
|
|
433
|
-
else if (typeof expands === 'string') {
|
|
434
|
-
if (expands.indexOf('/') === -1) {
|
|
435
|
-
return expands;
|
|
436
|
-
}
|
|
437
|
-
// Change `Foo/Bar/Baz` to `Foo($expand=Bar($expand=Baz))`
|
|
438
|
-
return expands
|
|
439
|
-
.split('/')
|
|
440
|
-
.reverse()
|
|
441
|
-
.reduce((results, item, index, arr) => {
|
|
442
|
-
if (index === 0) {
|
|
443
|
-
// Inner-most item
|
|
444
|
-
return `$expand=${item}`;
|
|
445
|
-
}
|
|
446
|
-
else if (index === arr.length - 1) {
|
|
447
|
-
// Outer-most item, don't add `$expand=` prefix (added above)
|
|
448
|
-
return `${item}(${results})`;
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
451
|
-
// Other items
|
|
452
|
-
return `$expand=${item}(${results})`;
|
|
453
|
-
}
|
|
454
|
-
}, '');
|
|
455
|
-
}
|
|
456
|
-
else if (Array.isArray(expands)) {
|
|
457
|
-
return `${expands
|
|
458
|
-
.map((e) => buildExpand(e, { aliases, escape }))
|
|
459
|
-
.join(',')}`;
|
|
460
|
-
}
|
|
461
|
-
else if (typeof expands === 'object') {
|
|
462
|
-
const expandKeys = Object.keys(expands);
|
|
463
|
-
if (expandKeys.some((key) => SUPPORTED_EXPAND_PROPERTIES.indexOf(key.toLowerCase()) !== -1)) {
|
|
464
|
-
return expandKeys
|
|
465
|
-
.map((key) => {
|
|
466
|
-
let value;
|
|
467
|
-
switch (key) {
|
|
468
|
-
case 'filter':
|
|
469
|
-
value = buildFilter(expands[key], {
|
|
470
|
-
aliases,
|
|
471
|
-
escape,
|
|
472
|
-
});
|
|
473
|
-
break;
|
|
474
|
-
case 'orderBy':
|
|
475
|
-
value = buildOrderBy(expands[key]);
|
|
476
|
-
break;
|
|
477
|
-
case 'levels':
|
|
478
|
-
case 'count':
|
|
479
|
-
case 'top':
|
|
480
|
-
case 'skip':
|
|
481
|
-
value = `${expands[key]}`;
|
|
482
|
-
break;
|
|
483
|
-
default:
|
|
484
|
-
value = buildExpand(expands[key], { aliases, escape });
|
|
485
|
-
}
|
|
486
|
-
return `$${key.toLowerCase()}=${value}`;
|
|
487
|
-
})
|
|
488
|
-
.join(';');
|
|
489
|
-
}
|
|
490
|
-
else {
|
|
491
|
-
return expandKeys
|
|
492
|
-
.map((key) => {
|
|
493
|
-
const builtExpand = buildExpand(expands[key], { aliases, escape });
|
|
494
|
-
return builtExpand ? `${key}(${builtExpand})` : key;
|
|
495
|
-
})
|
|
496
|
-
.join(',');
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
return '';
|
|
500
|
-
}
|
|
501
|
-
function buildTransforms(transforms, { aliases, escape = false }) {
|
|
502
|
-
// Wrap single object an array for simplified processing
|
|
503
|
-
const transformsArray = Array.isArray(transforms) ? transforms : [transforms];
|
|
504
|
-
const transformsResult = transformsArray.reduce((result, transform) => {
|
|
505
|
-
const { aggregate, filter, groupBy, ...rest } = transform;
|
|
506
|
-
// TODO: support as many of the following:
|
|
507
|
-
// topcount, topsum, toppercent,
|
|
508
|
-
// bottomsum, bottomcount, bottompercent,
|
|
509
|
-
// identity, concat, expand, search, compute, isdefined
|
|
510
|
-
const unsupportedKeys = Object.keys(rest);
|
|
511
|
-
if (unsupportedKeys.length) {
|
|
512
|
-
throw new Error(`Unsupported transform(s): ${unsupportedKeys}`);
|
|
513
|
-
}
|
|
514
|
-
if (aggregate) {
|
|
515
|
-
result.push(`aggregate(${buildAggregate(aggregate)})`);
|
|
516
|
-
}
|
|
517
|
-
if (filter) {
|
|
518
|
-
const builtFilter = buildFilter(filter, { aliases, escape });
|
|
519
|
-
if (builtFilter) {
|
|
520
|
-
result.push(`filter(${buildFilter(builtFilter, { aliases, escape })})`);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
if (groupBy) {
|
|
524
|
-
result.push(`groupby(${buildGroupBy(groupBy, { aliases, escape })})`);
|
|
525
|
-
}
|
|
526
|
-
return result;
|
|
527
|
-
}, []);
|
|
528
|
-
return transformsResult.join('/') || undefined;
|
|
529
|
-
}
|
|
530
|
-
function buildAggregate(aggregate) {
|
|
531
|
-
// Wrap single object in an array for simplified processing
|
|
532
|
-
const aggregateArray = Array.isArray(aggregate) ? aggregate : [aggregate];
|
|
533
|
-
return aggregateArray
|
|
534
|
-
.map((aggregateItem) => {
|
|
535
|
-
return typeof aggregateItem === 'string'
|
|
536
|
-
? aggregateItem
|
|
537
|
-
: Object.keys(aggregateItem).map((aggregateKey) => {
|
|
538
|
-
const aggregateValue = aggregateItem[aggregateKey];
|
|
539
|
-
// TODO: Are these always required? Can/should we default them if so?
|
|
540
|
-
if (!aggregateValue.with) {
|
|
541
|
-
throw new Error(`'with' property required for '${aggregateKey}'`);
|
|
542
|
-
}
|
|
543
|
-
if (!aggregateValue.as) {
|
|
544
|
-
throw new Error(`'as' property required for '${aggregateKey}'`);
|
|
545
|
-
}
|
|
546
|
-
return `${aggregateKey} with ${aggregateValue.with} as ${aggregateValue.as}`;
|
|
547
|
-
});
|
|
548
|
-
})
|
|
549
|
-
.join(',');
|
|
550
|
-
}
|
|
551
|
-
function buildGroupBy(groupBy, { aliases, escape = false }) {
|
|
552
|
-
if (!groupBy.properties) {
|
|
553
|
-
throw new Error(`'properties' property required for groupBy`);
|
|
554
|
-
}
|
|
555
|
-
let result = `(${groupBy.properties.join(',')})`;
|
|
556
|
-
if (groupBy.transform) {
|
|
557
|
-
result += `,${buildTransforms(groupBy.transform, { aliases, escape })}`;
|
|
558
|
-
}
|
|
559
|
-
return result;
|
|
560
|
-
}
|
|
561
|
-
function buildOrderBy(orderBy, prefix = '') {
|
|
562
|
-
if (Array.isArray(orderBy)) {
|
|
563
|
-
return orderBy
|
|
564
|
-
.map((value) => Array.isArray(value) &&
|
|
565
|
-
value.length === 2 &&
|
|
566
|
-
['asc', 'desc'].indexOf(value[1]) !== -1
|
|
567
|
-
? value.join(' ')
|
|
568
|
-
: value)
|
|
569
|
-
.map((v) => `${prefix}${v}`)
|
|
570
|
-
.join(',');
|
|
571
|
-
}
|
|
572
|
-
else if (typeof orderBy === 'object') {
|
|
573
|
-
return Object.entries(orderBy)
|
|
574
|
-
.map(([k, v]) => buildOrderBy(v, `${k}/`))
|
|
575
|
-
.map((v) => `${prefix}${v}`)
|
|
576
|
-
.join(',');
|
|
577
|
-
}
|
|
578
|
-
return `${prefix}${orderBy}`;
|
|
579
|
-
}
|
|
580
|
-
function buildUrl(path, params) {
|
|
581
|
-
// This can be refactored using URL API. But IE does not support it.
|
|
582
|
-
const queries = Object.entries(params).map(([key, value]) => `${key}=${value}`);
|
|
583
|
-
return queries.length ? `${path}?${queries.join('&')}` : path;
|
|
584
|
-
}
|
|
585
|
-
function parseNot(builtFilters) {
|
|
586
|
-
return `not(${builtFilters.join(' and ')})`;
|
|
587
|
-
}
|
|
588
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItb2RhdGEvc3JjL2xpYi9yZXNvdXJjZXMvcXVlcnkvYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLG9CQUFvQixHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNsRSxNQUFNLGlCQUFpQixHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztBQUMvQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzVDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ2pFLE1BQU0sMkJBQTJCLEdBQUc7SUFDbEMsUUFBUTtJQUNSLFFBQVE7SUFDUixRQUFRO0lBQ1IsS0FBSztJQUNMLE9BQU87SUFDUCxTQUFTO0lBQ1QsUUFBUTtDQUNULENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRyxVQUFVLENBQUM7QUFDbEMsTUFBTSxhQUFhLEdBQUcsc0JBQXNCLENBQUM7QUFRN0MsTUFBTSxDQUFOLElBQVksd0JBTVg7QUFORCxXQUFZLHdCQUF3QjtJQUNsQyx1Q0FBVyxDQUFBO0lBQ1gsdUNBQVcsQ0FBQTtJQUNYLHVDQUFXLENBQUE7SUFDWCwrQ0FBbUIsQ0FBQTtJQUNuQiwyREFBK0IsQ0FBQTtBQUNqQyxDQUFDLEVBTlcsd0JBQXdCLEtBQXhCLHdCQUF3QixRQU1uQztBQTZDRCxNQUFNLENBQU4sSUFBWSxnQkFLWDtBQUxELFdBQVksZ0JBQWdCO0lBQzFCLHFEQUFHLENBQUE7SUFDSCx5REFBSyxDQUFBO0lBQ0wsK0RBQVEsQ0FBQTtJQUNSLDJEQUFNLENBQUE7QUFDUixDQUFDLEVBTFcsZ0JBQWdC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LENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7QUFDOUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IENPTVBBUklTT05fT1BFUkFUT1JTID0gWydlcScsICduZScsICdndCcsICdnZScsICdsdCcsICdsZSddO1xuY29uc3QgTE9HSUNBTF9PUEVSQVRPUlMgPSBbJ2FuZCcsICdvcicsICdub3QnXTtcbmNvbnN0IENPTExFQ1RJT05fT1BFUkFUT1JTID0gWydhbnknLCAnYWxsJ107XG5jb25zdCBCT09MRUFOX0ZVTkNUSU9OUyA9IFsnc3RhcnRzd2l0aCcsICdlbmRzd2l0aCcsICdjb250YWlucyddO1xuY29uc3QgU1VQUE9SVEVEX0VYUEFORF9QUk9QRVJUSUVTID0gW1xuICAnZXhwYW5kJyxcbiAgJ2xldmVscycsXG4gICdzZWxlY3QnLFxuICAndG9wJyxcbiAgJ2NvdW50JyxcbiAgJ29yZGVyYnknLFxuICAnZmlsdGVyJyxcbl07XG5cbmNvbnN0IEZVTkNUSU9OX1JFR0VYID0gL1xcKCguKilcXCkvO1xuY29uc3QgSU5ERVhPRl9SRUdFWCA9IC8oPyFpbmRleG9mKVxcKChcXHcrKVxcKS87XG5cbmV4cG9ydCB0eXBlIFVucGFja2VkPFQ+ID0gVCBleHRlbmRzIChpbmZlciBVKVtdID8gVSA6IFQ7XG5leHBvcnQgdHlwZSBTZWxlY3Q8VD4gPSBTZWxlY3RUeXBlPFQ+IHwgU2VsZWN0VHlwZTxUPltdO1xuZXhwb3J0IHR5cGUgU2VsZWN0VHlwZTxUPiA9IHN0cmluZyB8IGtleW9mIFQ7XG5leHBvcnQgdHlwZSBGaWx0ZXI8VD4gPSBGaWx0ZXJUeXBlIHwgRmlsdGVyVHlwZVtdO1xuZXhwb3J0IHR5cGUgRmlsdGVyVHlwZSA9IHN0cmluZyB8IHsgW25hbWU6IHN0cmluZ106IGFueSB9O1xuXG5leHBvcnQgZW51bSBTdGFuZGFyZEFnZ3JlZ2F0ZU1ldGhvZHMge1xuICBzdW0gPSAnc3VtJyxcbiAgbWluID0gJ21pbicsXG4gIG1heCA9ICdtYXgnLFxuICBhdmVyYWdlID0gJ2F2ZXJhZ2UnLFxuICBjb3VudGRpc3RpbmN0ID0gJ2NvdW50ZGlzdGluY3QnLFxufVxuZXhwb3J0IHR5cGUgQWdncmVnYXRlID1cbiAgfCBzdHJpbmdcbiAgfCB7IFtwcm9wZXJ0eU5hbWU6IHN0cmluZ106IHsgd2l0aDogU3RhbmRhcmRBZ2dyZWdhdGVNZXRob2RzOyBhczogc3RyaW5nIH0gfTtcblxuLy8gT3JkZXJCeVxuXG5leHBvcnQgdHlwZSBPcmRlckJ5PFQ+ID0gT3JkZXJCeVR5cGU8VD4gfCBPcmRlckJ5VHlwZTxUPltdO1xuZXhwb3J0IHR5cGUgT3JkZXJCeVR5cGU8VD4gPSBzdHJpbmcgfCBPcmRlckJ5T2JqZWN0PFQ+O1xuZXhwb3J0IHR5cGUgT3JkZXJCeU9iamVjdDxUPiA9XG4gIHwga2V5b2YgVFxuICB8IFtrZXlvZiBUIHwgc3RyaW5nLCAnYXNjJyB8ICdkZXNjJ11cbiAgfCBOZXN0ZWRPcmRlckJ5PFQ+O1xuZXhwb3J0IHR5cGUgTmVzdGVkT3JkZXJCeTxUPiA9IHtcbiAgW1AgaW4ga2V5b2YgVF0/OiBUW1BdIGV4dGVuZHMgQXJyYXk8aW5mZXIgRT4gPyBPcmRlckJ5PEU+IDogT3JkZXJCeTxUW1BdPjtcbn07XG5cbi8vIEV4cGFuZFxuZXhwb3J0IHR5cGUgRXhwYW5kPFQ+ID0gRXhwYW5kVHlwZTxUPiB8IEV4cGFuZFR5cGU8VD5bXTtcbmV4cG9ydCB0eXBlIEV4cGFuZFR5cGU8VD4gPSBzdHJpbmcgfCBFeHBhbmRPYmplY3Q8VD47XG5leHBvcnQgdHlwZSBFeHBhbmRPYmplY3Q8VD4gPSBrZXlvZiBUIHwgTmVzdGVkRXhwYW5kT3B0aW9uczxUPjtcbmV4cG9ydCB0eXBlIE5lc3RlZEV4cGFuZE9wdGlvbnM8VD4gPSB7XG4gIFtQIGluIGtleW9mIFRdPzogRXhwYW5kT3B0aW9uczxVbnBhY2tlZDxUW1BdPj47XG59O1xuZXhwb3J0IHR5cGUgRXhwYW5kT3B0aW9uczxUPiA9IHtcbiAgc2VsZWN0PzogU2VsZWN0PFQ+O1xuICBmaWx0ZXI/OiBGaWx0ZXI8VD47XG4gIG9yZGVyQnk/OiBPcmRlckJ5PFQ+O1xuICB0b3A/OiBudW1iZXI7XG4gIHNraXA/OiBudW1iZXI7XG4gIGxldmVscz86IG51bWJlciB8ICdtYXgnO1xuICBjb3VudD86IGJvb2xlYW4gfCBGaWx0ZXI8VD47XG4gIGV4cGFuZD86IEV4cGFuZDxUPjtcbn07XG5cbmV4cG9ydCB0eXBlIFRyYW5zZm9ybTxUPiA9IHtcbiAgYWdncmVnYXRlPzogQWdncmVnYXRlIHwgQXJyYXk8QWdncmVnYXRlPjtcbiAgZmlsdGVyPzogRmlsdGVyPFQ+O1xuICBncm91cEJ5PzogR3JvdXBCeTxUPjtcbn07XG5leHBvcnQgdHlwZSBHcm91cEJ5PFQ+ID0ge1xuICBwcm9wZXJ0aWVzOiBBcnJheTxrZXlvZiBUPjtcbiAgdHJhbnNmb3JtPzogVHJhbnNmb3JtPFQ+O1xufTtcblxuZXhwb3J0IGVudW0gUXVlcnlDdXN0b21UeXBlcyB7XG4gIFJhdyxcbiAgQWxpYXMsXG4gIER1cmF0aW9uLFxuICBCaW5hcnksXG59XG5cbmV4cG9ydCB0eXBlIFF1ZXJ5Q3VzdG9tVHlwZSA9IHtcbiAgdHlwZTogUXVlcnlDdXN0b21UeXBlcztcbiAgdmFsdWU6IGFueTtcbiAgbmFtZT86IHN0cmluZztcbn07XG5leHBvcnQgdHlwZSBWYWx1ZSA9IHN0cmluZyB8IERhdGUgfCBudW1iZXIgfCBib29sZWFuIHwgUXVlcnlDdXN0b21UeXBlO1xuXG4vL2h0dHBzOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy9vZGF0YS9vZGF0YS92NC4wMS9vZGF0YS12NC4wMS1wYXJ0Mi11cmwtY29udmVudGlvbnMuaHRtbCNzZWNfUXVlcnlPcHRpb25zXG5leHBvcnQgY29uc3QgcmF3ID0gKHZhbHVlOiBzdHJpbmcpOiBRdWVyeUN1c3RvbVR5cGUgPT4gKHtcbiAgdHlwZTogUXVlcnlDdXN0b21UeXBlcy5SYXcsXG4gIHZhbHVlLFxufSk7XG5leHBvcnQgY29uc3QgYWxpYXMgPSAodmFsdWU6IGFueSwgbmFtZT86IHN0cmluZyk6IFF1ZXJ5Q3VzdG9tVHlwZSA9PiAoe1xuICB0eXBlOiBRdWVyeUN1c3RvbVR5cGVzLkFsaWFzLFxuICB2YWx1ZSxcbiAgbmFtZSxcbn0pO1xuZXhwb3J0IGNvbnN0IGR1cmF0aW9uID0gKHZhbHVlOiBzdHJpbmcpOiBRdWVyeUN1c3RvbVR5cGUgPT4gKHtcbiAgdHlwZTogUXVlcnlDdXN0b21UeXBlcy5EdXJhdGlvbixcbiAgdmFsdWUsXG59KTtcbmV4cG9ydCBjb25zdCBiaW5hcnkgPSAodmFsdWU6IHN0cmluZyk6IFF1ZXJ5Q3VzdG9tVHlwZSA9PiAoe1xuICB0eXBlOiBRdWVyeUN1c3RvbVR5cGVzLkJpbmFyeSxcbiAgdmFsdWUsXG59KTtcbmV4cG9ydCBjb25zdCBpc1F1ZXJ5Q3VzdG9tVHlwZSA9ICh2YWx1ZTogYW55KSA9PlxuICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICd0eXBlJyBpbiB2YWx1ZSAmJlxuICB2YWx1ZS50eXBlIGluIFF1ZXJ5Q3VzdG9tVHlwZXM7XG5leHBvcnQgdHlwZSBRdWVyeU9wdGlvbnM8VD4gPSBFeHBhbmRPcHRpb25zPFQ+ICYge1xuICBzZWFyY2g6IHN0cmluZztcbiAgdHJhbnNmb3JtOiB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfSB8IHsgW25hbWU6IHN0cmluZ106IGFueSB9W107XG4gIHNraXA6IG51bWJlcjtcbiAgc2tpcHRva2VuOiBzdHJpbmc7XG4gIGtleTogc3RyaW5nIHwgbnVtYmVyIHwgeyBbbmFtZTogc3RyaW5nXTogYW55IH07XG4gIGNvdW50OiBib29sZWFuIHwgRmlsdGVyPFQ+O1xuICBhY3Rpb246IHN0cmluZztcbiAgZnVuYzogc3RyaW5nIHwgeyBbZnVuY3Rpb25OYW1lOiBzdHJpbmddOiB7IFtwYXJhbWV0ZXJOYW1lOiBzdHJpbmddOiBhbnkgfSB9O1xuICBmb3JtYXQ6IHN0cmluZztcbiAgYWxpYXNlczogUXVlcnlDdXN0b21UeXBlW107XG4gIGVzY2FwZTogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBjb25zdCBJVEVNX1JPT1QgPSAnJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gPFQ+KHtcbiAgc2VsZWN0LFxuICBzZWFyY2gsXG4gIHNraXB0b2tlbixcbiAgZm9ybWF0LFxuICB0b3AsXG4gIHNraXAsXG4gIGZpbHRlcixcbiAgdHJhbnNmb3JtLFxuICBvcmRlckJ5LFxuICBrZXksXG4gIGNvdW50LFxuICBleHBhbmQsXG4gIGFjdGlvbixcbiAgZnVuYyxcbiAgYWxpYXNlcyxcbiAgZXNjYXBlLFxufTogUGFydGlhbDxRdWVyeU9wdGlvbnM8VD4+ID0ge30pIHtcbiAgY29uc3QgW3BhdGgsIHBhcmFtc10gPSBidWlsZFBhdGhBbmRRdWVyeSh7XG4gICAgc2VsZWN0LFxuICAgIHNlYXJjaCxcbiAgICBza2lwdG9rZW4sXG4gICAgZm9ybWF0LFxuICAgIHRvcCxcbiAgICBza2lwLFxuICAgIGZpbHRlcixcbiAgICB0cmFuc2Zvcm0sXG4gICAgb3JkZXJCeSxcbiAgICBrZXksXG4gICAgY291bnQsXG4gICAgZXhwYW5kLFxuICAgIGFjdGlvbixcbiAgICBmdW5jLFxuICAgIGFsaWFzZXMsXG4gICAgZXNjYXBlLFxuICB9KTtcblxuICByZXR1cm4gYnVpbGRVcmwocGF0aCwgcGFyYW1zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGF0aEFuZFF1ZXJ5PFQ+KHtcbiAgc2VsZWN0LFxuICBzZWFyY2gsXG4gIHNraXB0b2tlbixcbiAgZm9ybWF0LFxuICB0b3AsXG4gIHNraXAsXG4gIGZpbHRlcixcbiAgdHJhbnNmb3JtLFxuICBvcmRlckJ5LFxuICBrZXksXG4gIGNvdW50LFxuICBleHBhbmQsXG4gIGFjdGlvbixcbiAgZnVuYyxcbiAgYWxpYXNlcyxcbiAgZXNjYXBlLFxufTogUGFydGlhbDxRdWVyeU9wdGlvbnM8VD4+ID0ge30pOiBbc3RyaW5nLCB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfV0ge1xuICBsZXQgcGF0aDogc3RyaW5nID0gJyc7XG4gIGFsaWFzZXMgPSBhbGlhc2VzIHx8IFtdO1xuXG4gIGNvbnN0IHF1ZXJ5OiBhbnkgPSB7fTtcblxuICAvLyBrZXkgaXMgbm90IChudWxsLCB1bmRlZmluZWQpXG4gIGlmIChrZXkgIT0gdW5kZWZpbmVkKSB7XG4gICAgcGF0aCArPSBgKCR7bm9ybWFsaXplVmFsdWUoa2V5IGFzIFZhbHVlLCB7IGFsaWFzZXMsIGVzY2FwZSB9KX0pYDtcbiAgfVxuXG4gIGlmIChzZWxlY3QpIHtcbiAgICBxdWVyeS4kc2VsZWN0ID0gQXJyYXkuaXNBcnJheShzZWxlY3QpID8gc2VsZWN0LmpvaW4oJywnKSA6IHNlbGVjdDtcbiAgfVxuXG4gIGlmIChzZWFyY2gpIHtcbiAgICBxdWVyeS4kc2VhcmNoID0gc2VhcmNoO1xuICB9XG5cbiAgaWYgKHNraXB0b2tlbikge1xuICAgIHF1ZXJ5LiRza2lwdG9rZW4gPSBza2lwdG9rZW47XG4gIH1cblxuICBpZiAoZm9ybWF0KSB7XG4gICAgcXVlcnkuJGZvcm1hdCA9IGZvcm1hdDtcbiAgfVxuXG4gIGlmIChmaWx0ZXIgfHwgdHlwZW9mIGNvdW50ID09PSAnb2JqZWN0Jykge1xuICAgIHF1ZXJ5LiRmaWx0ZXIgPSBidWlsZEZpbHRlcih0eXBlb2YgY291bnQgPT09ICdvYmplY3QnID8gY291bnQgOiBmaWx0ZXIsIHtcbiAgICAgIGFsaWFzZXMsXG4gICAgICBlc2NhcGUsXG4gICAgfSk7XG4gIH1cblxuICBpZiAodHJhbnNmb3JtKSB7XG4gICAgcXVlcnkuJGFwcGx5ID0gYnVpbGRUcmFuc2Zvcm1zKHRyYW5zZm9ybSwgeyBhbGlhc2VzLCBlc2NhcGUgfSk7XG4gIH1cblxuICBpZiAoZXhwYW5kKSB7XG4gICAgcXVlcnkuJGV4cGFuZCA9IGJ1aWxkRXhwYW5kKGV4cGFuZCwgeyBhbGlhc2VzLCBlc2NhcGUgfSk7XG4gIH1cblxuICBpZiAob3JkZXJCeSkge1xuICAgIHF1ZXJ5LiRvcmRlcmJ5ID0gYnVpbGRPcmRlckJ5KG9yZGVyQnkpO1xuICB9XG5cbiAgaWYgKGNvdW50KSB7XG4gICAgaWYgKHR5cGVvZiBjb3VudCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBxdWVyeS4kY291bnQgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXRoICs9ICcvJGNvdW50JztcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIHRvcCA9PT0gJ251bWJlcicpIHtcbiAgICBxdWVyeS4kdG9wID0gdG9wO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBza2lwID09PSAnbnVtYmVyJykge1xuICAgIHF1ZXJ5LiRza2lwID0gc2tpcDtcbiAgfVxuXG4gIGlmIChhY3Rpb24pIHtcbiAgICBwYXRoICs9IGAvJHthY3Rpb259YDtcbiAgfVxuXG4gIGlmIChmdW5jKSB7XG4gICAgaWYgKHR5cGVvZiBmdW5jID09PSAnc3RyaW5nJykge1xuICAgICAgcGF0aCArPSBgLyR7ZnVuY30oKWA7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZnVuYyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGNvbnN0IFtmdW5jTmFtZV0gPSBPYmplY3Qua2V5cyhmdW5jKTtcbiAgICAgIGNvbnN0IGZ1bmNBcmdzID0gbm9ybWFsaXplVmFsdWUoZnVuY1tmdW5jTmFtZV0gYXMgVmFsdWUsIHtcbiAgICAgICAgYWxpYXNlcyxcbiAgICAgICAgZXNjYXBlLFxuICAgICAgfSk7XG5cbiAgICAgIHBhdGggKz0gYC8ke2Z1bmNOYW1lfSgke2Z1bmNBcmdzfSlgO1xuICAgIH1cbiAgfVxuXG4gIGlmIChhbGlhc2VzLmxlbmd0aCA+IDApIHtcbiAgICBPYmplY3QuYXNzaWduKFxuICAgICAgcXVlcnksXG4gICAgICBhbGlhc2VzLnJlZHVjZShcbiAgICAgICAgKGFjYywgYWxpYXMpID0+XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihhY2MsIHtcbiAgICAgICAgICAgIFtgQCR7YWxpYXMubmFtZX1gXTogbm9ybWFsaXplVmFsdWUoYWxpYXMudmFsdWUsIHtcbiAgICAgICAgICAgICAgZXNjYXBlLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSksXG4gICAgICAgIHt9XG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8vIEZpbHRlciBlbXB0eSB2YWx1ZXNcbiAgY29uc3QgcGFyYW1zID0gT2JqZWN0LmVudHJpZXMocXVlcnkpXG4gICAgLmZpbHRlcigoWywgdmFsdWVdKSA9PiB2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSAnJylcbiAgICAucmVkdWNlKChhY2MsIFtrZXksIHZhbHVlXSkgPT4gT2JqZWN0LmFzc2lnbihhY2MsIHsgW2tleV06IHZhbHVlIH0pLCB7fSk7XG5cbiAgcmV0dXJuIFtwYXRoLCBwYXJhbXNdO1xufVxuXG5mdW5jdGlvbiByZW5kZXJQcmltaXRpdmVWYWx1ZShcbiAga2V5OiBzdHJpbmcsXG4gIHZhbDogYW55LFxuICB7XG4gICAgYWxpYXNlcyxcbiAgICBlc2NhcGUsXG4gIH06IHtcbiAgICBhbGlhc2VzPzogUXVlcnlDdXN0b21UeXBlW107XG4gICAgZXNjYXBlPzogYm9vbGVhbjtcbiAgfVxuKSB7XG4gIHJldHVybiBgJHtrZXl9IGVxICR7bm9ybWFsaXplVmFsdWUodmFsLCB7IGFsaWFzZXMsIGVzY2FwZSB9KX1gO1xufVxuXG5mdW5jdGlvbiBidWlsZEZpbHRlcihcbiAgZmlsdGVyczogRmlsdGVyPGFueT4gPSB7fSxcbiAge1xuICAgIGFsaWFzZXMsXG4gICAgcHJvcFByZWZpeCxcbiAgICBlc2NhcGUsXG4gIH06IHsgYWxpYXNlcz86IFF1ZXJ5Q3VzdG9tVHlwZVtdOyBwcm9wUHJlZml4Pzogc3RyaW5nOyBlc2NhcGU/OiBib29sZWFuIH1cbik6IHN0cmluZyB7XG4gIHJldHVybiAoXG4gICAgKEFycmF5LmlzQXJyYXkoZmlsdGVycykgPyBmaWx0ZXJzIDogW2ZpbHRlcnNdKS5yZWR1Y2UoXG4gICAgICAoYWNjOiBzdHJpbmdbXSwgZmlsdGVyKSA9PiB7XG4gICAgICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgICAgICBjb25zdCBidWlsdEZpbHRlciA9IGJ1aWxkRmlsdGVyQ29yZShmaWx0ZXIsIHtcbiAgICAgICAgICAgIGFsaWFzZXMsXG4gICAgICAgICAgICBwcm9wUHJlZml4LFxuICAgICAgICAgICAgZXNjYXBlLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChidWlsdEZpbHRlcikge1xuICAgICAgICAgICAgYWNjLnB1c2goYnVpbHRGaWx0ZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIFtdXG4gICAgKSBhcyBzdHJpbmdbXVxuICApLmpvaW4oJyBhbmQgJyk7XG5cbiAgZnVuY3Rpb24gYnVpbGRGaWx0ZXJDb3JlKFxuICAgIGZpbHRlcjogRmlsdGVyPGFueT4gPSB7fSxcbiAgICB7XG4gICAgICBhbGlhc2VzLFxuICAgICAgcHJvcFByZWZpeCxcbiAgICAgIGVzY2FwZSxcbiAgICB9OiB7IGFsaWFzZXM/OiBRdWVyeUN1c3RvbVR5cGVbXTsgcHJvcFByZWZpeD86IHN0cmluZzsgZXNjYXBlPzogYm9vbGVhbiB9XG4gICkge1xuICAgIGxldCBmaWx0ZXJFeHByID0gJyc7XG4gICAgaWYgKHR5cGVvZiBmaWx0ZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBVc2UgcmF3IGZpbHRlciBzdHJpbmdcbiAgICAgIGZpbHRlckV4cHIgPSBmaWx0ZXI7XG4gICAgfSBlbHNlIGlmIChmaWx0ZXIgJiYgdHlwZW9mIGZpbHRlciA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGNvbnN0IGZpbHRlcnNBcnJheSA9IE9iamVjdC5rZXlzKGZpbHRlcikucmVkdWNlKFxuICAgICAgICAocmVzdWx0OiBhbnlbXSwgZmlsdGVyS2V5KSA9PiB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSAoZmlsdGVyIGFzIGFueSlbZmlsdGVyS2V5XTtcbiAgICAgICAgICBsZXQgcHJvcE5hbWUgPSAnJztcbiAgICAgICAgICBpZiAocHJvcFByZWZpeCkge1xuICAgICAgICAgICAgaWYgKGZpbHRlcktleSA9PT0gSVRFTV9ST09UKSB7XG4gICAgICAgICAgICAgIHByb3BOYW1lID0gcHJvcFByZWZpeDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoSU5ERVhPRl9SRUdFWC50ZXN0KGZpbHRlcktleSkpIHtcbiAgICAgICAgICAgICAgcHJvcE5hbWUgPSBmaWx0ZXJLZXkucmVwbGFjZShJTkRFWE9GX1JFR0VYLCAoXywgJDEpID0+XG4gICAgICAgICAgICAgICAgJDEudHJpbSgpID09PSBJVEVNX1JPT1RcbiAgICAgICAgICAgICAgICAgID8gYCgke3Byb3BQcmVmaXh9KWBcbiAgICAgICAgICAgICAgICAgIDogYCgke3Byb3BQcmVmaXh9LyR7JDEudHJpbSgpfSlgXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKEZVTkNUSU9OX1JFR0VYLnRlc3QoZmlsdGVyS2V5KSkge1xuICAgICAgICAgICAgICBwcm9wTmFtZSA9IGZpbHRlcktleS5yZXBsYWNlKEZVTkNUSU9OX1JFR0VYLCAoXywgJDEpID0+XG4gICAgICAgICAgICAgICAgJDEudHJpbSgpID09PSBJVEVNX1JPT1RcbiAgICAgICAgICAgICAgICAgID8gYCgke3Byb3BQcmVmaXh9KWBcbiAgICAgICAgICAgICAgICAgIDogYCgke3Byb3BQcmVmaXh9LyR7JDEudHJpbSgpfSlgXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwcm9wTmFtZSA9IGAke3Byb3BQcmVmaXh9LyR7ZmlsdGVyS2V5fWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByb3BOYW1lID0gZmlsdGVyS2V5O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChmaWx0ZXJLZXkgPT09IElURU1fUk9PVCAmJiBBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5jb25jYXQoXG4gICAgICAgICAgICAgIHZhbHVlLm1hcCgoYXJyYXlWYWx1ZTogYW55KSA9PlxuICAgICAgICAgICAgICAgIHJlbmRlclByaW1pdGl2ZVZhbHVlKHByb3BOYW1lLCBhcnJheVZhbHVlLCB7IGVzY2FwZSwgYWxpYXNlcyB9KVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIFsnbnVtYmVyJywgJ3N0cmluZycsICdib29sZWFuJ10uaW5kZXhPZih0eXBlb2YgdmFsdWUpICE9PSAtMSB8fFxuICAgICAgICAgICAgdmFsdWUgaW5zdGFuY2VvZiBEYXRlIHx8XG4gICAgICAgICAgICB2YWx1ZSA9PT0gbnVsbFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gU2ltcGxlIGtleS92YWx1ZSBoYW5kbGVkIGFzIGVxdWFscyBvcGVyYXRvclxuICAgICAgICAgICAgcmVzdWx0LnB1c2goXG4gICAgICAgICAgICAgIHJlbmRlclByaW1pdGl2ZVZhbHVlKHByb3BOYW1lLCB2YWx1ZSwgeyBhbGlhc2VzLCBlc2NhcGUgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgY29uc3Qgb3AgPSBmaWx0ZXJLZXk7XG4gICAgICAgICAgICBjb25zdCBidWlsdEZpbHRlcnMgPSB2YWx1ZVxuICAgICAgICAgICAgICAubWFwKCh2KSA9PiBidWlsZEZpbHRlcih2LCB7IGFsaWFzZXMsIHByb3BQcmVmaXgsIGVzY2FwZSB9KSlcbiAgICAgICAgICAgICAgLmZpbHRlcigoZikgPT4gZilcbiAgICAgICAgICAgICAgLm1hcCgoZikgPT5cbiAgICAgICAgICAgICAgICBMT0dJQ0FMX09QRVJBVE9SUy5pbmRleE9mKG9wKSAhPT0gLTEgPyBgKCR7Zn0pYCA6IGZcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChidWlsdEZpbHRlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGlmIChMT0dJQ0FMX09QRVJBVE9SUy5pbmRleE9mKG9wKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBpZiAoYnVpbHRGaWx0ZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgaWYgKG9wID09PSAnbm90Jykge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChwYXJzZU5vdChidWlsdEZpbHRlcnMgYXMgc3RyaW5nW10pKTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGAoJHtidWlsdEZpbHRlcnMuam9pbihgICR7b3B9IGApfSlgKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goYnVpbHRGaWx0ZXJzLmpvaW4oYCAke29wfSBgKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKExPR0lDQUxfT1BFUkFUT1JTLmluZGV4T2YocHJvcE5hbWUpICE9PSAtMSkge1xuICAgICAgICAgICAgY29uc3Qgb3AgPSBwcm9wTmFtZTtcbiAgICAgICAgICAgIGNvbnN0IGJ1aWx0RmlsdGVycyA9IE9iamVjdC5rZXlzKHZhbHVlKS5tYXAoKHZhbHVlS2V5KSA9PlxuICAgICAgICAgICAgICBidWlsZEZpbHRlckNvcmUoXG4gICAgICAgICAgICAgICAgeyBbdmFsdWVLZXldOiB2YWx1ZVt2YWx1ZUtleV0gfSxcbiAgICAgICAgICAgICAgICB7IGFsaWFzZXMsIGVzY2FwZSB9XG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoYnVpbHRGaWx0ZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBpZiAob3AgPT09ICdub3QnKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gocGFyc2VOb3QoYnVpbHRGaWx0ZXJzIGFzIHN0cmluZ1tdKSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goYCR7YnVpbHRGaWx0ZXJzLmpvaW4oYCAke29wfSBgKX1gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgaWYgKCd0eXBlJyBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICByZXN1bHQucHVzaChcbiAgICAgICAgICAgICAgICByZW5kZXJQcmltaXRpdmVWYWx1ZShwcm9wTmFtZSwgdmFsdWUsIHsgYWxpYXNlcywgZXNjYXBlIH0pXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdCBvcGVyYXRvcnMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7XG4gICAgICAgICAgICAgIG9wZXJhdG9ycy5mb3JFYWNoKChvcCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChDT01QQVJJU09OX09QRVJBVE9SUy5pbmRleE9mKG9wKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICBgJHtwcm9wTmFtZX0gJHtvcH0gJHtub3JtYWxpemVWYWx1ZSh2YWx1ZVtvcF0sIHtcbiAgICAgICAgICAgICAgICAgICAgICBhbGlhc2VzLFxuICAgICAgICAgICAgICAgICAgICAgIGVzY2FwZSxcbiAgICAgICAgICAgICAgICAgICAgfSl9YFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKExPR0lDQUxfT1BFUkFUT1JTLmluZGV4T2Yob3ApICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWVbb3BdKSkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVtvcF1cbiAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICh2OiBhbnkpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJygnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWlsZEZpbHRlckNvcmUodiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpYXNlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BQcmVmaXg6IHByb3BOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjYXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnKSdcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgIC5qb2luKGAgJHtvcH0gYClcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICcoJyArXG4gICAgICAgICAgICAgICAgICAgICAgICBidWlsZEZpbHRlckNvcmUodmFsdWVbb3BdLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWFzZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BQcmVmaXg6IHByb3BOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBlc2NhcGUsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSdcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKENPTExFQ1RJT05fT1BFUkFUT1JTLmluZGV4T2Yob3ApICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgY29sbGVjdGlvbkNsYXVzZSA9IGJ1aWxkQ29sbGVjdGlvbkNsYXVzZShcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyS2V5LnRvTG93ZXJDYXNlKCksXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlW29wXSxcbiAgICAgICAgICAgICAgICAgICAgb3AsXG4gICAgICAgICAgICAgICAgICAgIHByb3BOYW1lXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgaWYgKGNvbGxlY3Rpb25DbGF1c2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goY29sbGVjdGlvbkNsYXVzZSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvcCA9PT0gJ2hhcycpIHtcbiAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICBgJHtwcm9wTmFtZX0gJHtvcH0gJHtub3JtYWxpemVWYWx1ZSh2YWx1ZVtvcF0sIHtcbiAgICAgICAgICAgICAgICAgICAgICBhbGlhc2VzLFxuICAgICAgICAgICAgICAgICAgICAgIGVzY2FwZSxcbiAgICAgICAgICAgICAgICAgICAgfSl9YFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9wID09PSAnaW4nKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHRpbmdWYWx1ZXMgPSBBcnJheS5pc0FycmF5KHZhbHVlW29wXSlcbiAgICAgICAgICAgICAgICAgICAgPyB2YWx1ZVtvcF1cbiAgICAgICAgICAgICAgICAgICAgOiB2YWx1ZVtvcF0udmFsdWUubWFwKCh0eXBlZFZhbHVlOiBhbnkpID0+ICh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiB2YWx1ZVtvcF0udHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0eXBlZFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goXG4gICAgICAgICAgICAgICAgICAgIHByb3BOYW1lICtcbiAgICAgICAgICAgICAgICAgICAgICAnIGluICgnICtcbiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRpbmdWYWx1ZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoKHY6IGFueSkgPT4gbm9ybWFsaXplVmFsdWUodiwgeyBhbGlhc2VzLCBlc2NhcGUgfSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAuam9pbignLCcpICtcbiAgICAgICAgICAgICAgICAgICAgICAnKSdcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChCT09MRUFOX0ZVTkNUSU9OUy5pbmRleE9mKG9wKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgIC8vIFNpbXBsZSBib29sZWFuIGZ1bmN0aW9ucyAoc3RhcnRzd2l0aCwgZW5kc3dpdGgsIGNvbnRhaW5zKVxuICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goXG4gICAgICAgICAgICAgICAgICAgIGAke29wfSgke3Byb3BOYW1lfSwke25vcm1hbGl6ZVZhbHVlKHZhbHVlW29wXSwge1xuICAgICAgICAgICAgICAgICAgICAgIGFsaWFzZXMsXG4gICAgICAgICAgICAgICAgICAgICAgZXNjYXBlLFxuICAgICAgICAgICAgICAgICAgICB9KX0pYFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gTmVzdGVkIHByb3BlcnR5XG4gICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSBidWlsZEZpbHRlckNvcmUodmFsdWUsIHtcbiAgICAgICAgICAgICAgICAgICAgYWxpYXNlcyxcbiAgICAgICAgICAgICAgICAgICAgcHJvcFByZWZpeDogcHJvcE5hbWUsXG4gICAgICAgICAgICAgICAgICAgIGVzY2FwZSxcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlcikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChmaWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAvLyBJZ25vcmUvb21pdCBmaWx0ZXIgaWYgdmFsdWUgaXMgYHVuZGVmaW5lZGBcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIHZhbHVlIHR5cGU6ICR7dmFsdWV9YCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSxcbiAgICAgICAgW11cbiAgICAgICk7XG5cbiAgICAgIGZpbHRlckV4cHIgPSBmaWx0ZXJzQXJyYXkuam9pbignIGFuZCAnKTtcbiAgICB9IC8qIGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgZmlsdGVycyB0eXBlOiAke2ZpbHRlcn1gKTtcbiAgICAgIH0gKi9cbiAgICByZXR1cm4gZmlsdGVyRXhwcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkQ29sbGVjdGlvbkNsYXVzZShcbiAgICBsYW1iZGFQYXJhbWV0ZXI6IHN0cmluZyxcbiAgICB2YWx1ZTogYW55LFxuICAgIG9wOiBzdHJpbmcsXG4gICAgcHJvcE5hbWU6IHN0cmluZ1xuICApIHtcbiAgICBsZXQgY2xhdXNlID0gJyc7XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fCB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykge1xuICAgICAgY2xhdXNlID0gZ2V0U3RyaW5nQ29sbGVjdGlvbkNsYXVzZShsYW1iZGFQYXJhbWV0ZXIsIHZhbHVlLCBvcCwgcHJvcE5hbWUpO1xuICAgIH0gZWxzZSBpZiAodmFsdWUpIHtcbiAgICAgIC8vIG5vcm1hbGl6ZSB7YW55Olt7cHJvcDE6IDF9LCB7cHJvcDI6IDF9XX0gLS0+IHthbnk6e3Byb3AxOiAxLCBwcm9wMjogMX19OyBzYW1lIGZvciAnYWxsJyxcbiAgICAgIC8vIHNpbXBsZSB2YWx1ZXMgY29sbGVjdGlvbjoge2FueTpbeycnOiAnc2ltcGxlVmFsMSd9LCB7Jyc6ICdzaW1wbGVWYWwyJ31dfSAtLT4ge2FueTp7Jyc6IFsnc2ltcGxlVmFsMScsICdzaW1wbGVWYWwyJ119fTsgc2FtZSBmb3IgJ2FsbCcsXG4gICAgICBjb25zdCBmaWx0ZXJWYWx1ZSA9IEFycmF5LmlzQXJyYXkodmFsdWUpXG4gICAgICAgID8gdmFsdWUucmVkdWNlKChhY2MsIGl0ZW0pID0+IHtcbiAgICAgICAgICAgIGlmIChpdGVtLmhhc093blByb3BlcnR5KElURU1fUk9PVCkpIHtcbiAgICAgICAgICAgICAgaWYgKCFhY2MuaGFzT3duUHJvcGVydHkoSVRFTV9ST09UKSkge1xuICAgICAgICAgICAgICAgIGFjY1tJVEVNX1JPT1RdID0gW107XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYWNjW0lURU1fUk9PVF0ucHVzaChpdGVtW0lURU1fUk9PVF0pO1xuICAgICAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHsgLi4uYWNjLCAuLi5pdGVtIH07XG4gICAgICAgICAgfSwge30pXG4gICAgICAgIDogdmFsdWU7XG5cbiAgICAgIGNvbnN0IGZpbHRlciA9IGJ1aWxkRmlsdGVyQ29yZShmaWx0ZXJWYWx1ZSwge1xuICAgICAgICBhbGlhc2VzLFxuICAgICAgICBwcm9wUHJlZml4OiBsYW1iZGFQYXJhbWV0ZXIsXG4gICAgICAgIGVzY2FwZSxcbiAgICAgIH0pO1xuICAgICAgY2xhdXNlID0gYCR7cHJvcE5hbWV9LyR7b3B9KCR7XG4gICAgICAgIGZpbHRlciA/IGAke2xhbWJkYVBhcmFtZXRlcn06JHtmaWx0ZXJ9YCA6ICcnXG4gICAgICB9KWA7XG4gICAgfVxuICAgIHJldHVybiBjbGF1c2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0U3RyaW5nQ29sbGVjdGlvbkNsYXVzZShcbiAgbGFtYmRhUGFyYW1ldGVyOiBzdHJpbmcsXG4gIHZhbHVlOiBhbnksXG4gIGNvbGxlY3Rpb25PcGVyYXRvcjogc3RyaW5nLFxuICBwcm9wTmFtZTogc3RyaW5nXG4pIHtcbiAgbGV0IGNsYXVzZSA9ICcnO1xuICBjb25zdCBjb25kaXRpb25PcGVyYXRvciA9IGNvbGxlY3Rpb25PcGVyYXRvciA9PSAnYWxsJyA/ICduZScgOiAnZXEnO1xuICBjbGF1c2UgPSBgJHtwcm9wTmFtZX0vJHtjb2xsZWN0aW9uT3BlcmF0b3J9KCR7bGFtYmRhUGFyYW1ldGVyfTogJHtsYW1iZGFQYXJhbWV0ZXJ9ICR7Y29uZGl0aW9uT3BlcmF0b3J9ICcke3ZhbHVlfScpYDtcblxuICByZXR1cm4gY2xhdXNlO1xufVxuXG5mdW5jdGlvbiBlc2NhcGVJbGxlZ2FsQ2hhcnMoc3RyaW5nOiBzdHJpbmcpIHtcbiAgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UoLyUvZywgJyUyNScpO1xuICBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZSgvXFwrL2csICclMkInKTtcbiAgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UoL1xcLy9nLCAnJTJGJyk7XG4gIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKC9cXD8vZywgJyUzRicpO1xuICBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZSgvIy9nLCAnJTIzJyk7XG4gIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKC8mL2csICclMjYnKTtcbiAgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UoLycvZywgXCInJ1wiKTtcbiAgcmV0dXJuIHN0cmluZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVZhbHVlKFxuICB2YWx1ZTogVmFsdWUsXG4gIHtcbiAgICBhbGlhc2VzLFxuICAgIGVzY2FwZSA9IGZhbHNlLFxuICB9OiB7IGFsaWFzZXM/OiBRdWVyeUN1c3RvbVR5cGVbXTsgZXNjYXBlPzogYm9vbGVhbiB9ID0ge31cbik6IGFueSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGVzY2FwZSA/IGAnJHtlc2NhcGVJbGxlZ2FsQ2hhcnModmFsdWUpfSdgIDogYCcke3ZhbHVlfSdgO1xuICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gYFske3ZhbHVlXG4gICAgICAubWFwKChkKSA9PiBub3JtYWxpemVWYWx1ZShkLCB7IGFsaWFzZXMsIGVzY2FwZSB9KSlcbiAgICAgIC5qb2luKCcsJyl9XWA7XG4gIH0gZWxzZSBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgIHN3aXRjaCAodmFsdWUudHlwZSkge1xuICAgICAgY2FzZSBRdWVyeUN1c3RvbVR5cGVzLlJhdzpcbiAgICAgICAgcmV0dXJuIHZhbHVlLnZhbHVlO1xuICAgICAgY2FzZSBRdWVyeUN1c3RvbVR5cGVzLkR1cmF0aW9uOlxuICAgICAgICByZXR1cm4gYGR1cmF0aW9uJyR7dmFsdWUudmFsdWV9J2A7XG4gICAgICBjYXNlIFF1ZXJ5Q3VzdG9tVHlwZXMuQmluYXJ5OlxuICAgICAgICByZXR1cm4gYGJpbmFyeScke3ZhbHVlLnZhbHVlfSdgO1xuICAgICAgY2FzZSBRdWVyeUN1c3RvbVR5cGVzLkFsaWFzOlxuICAgICAgICAvLyBTdG9yZVxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhbGlhc2VzKSkge1xuICAgICAgICAgIGlmICh2YWx1ZS5uYW1lID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHZhbHVlLm5hbWUgPSBgYSR7YWxpYXNlcy5sZW5ndGggKyAxfWA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFsaWFzZXMucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGBAJHt2YWx1ZS5uYW1lfWA7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gT2JqZWN0LmVudHJpZXModmFsdWUpXG4gICAgICAgICAgLmZpbHRlcigoWywgdl0pID0+IHYgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICAubWFwKFxuICAgICAgICAgICAgKFtrLCB2XSkgPT5cbiAgICAgICAgICAgICAgYCR7a309JHtub3JtYWxpemVWYWx1ZSh2IGFzIFZhbHVlLCB7IGFsaWFzZXMsIGVzY2FwZSB9KX1gXG4gICAgICAgICAgKVxuICAgICAgICAgIC5qb2luKCcsJyk7XG4gICAgfVxuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gYnVpbGRFeHBhbmQ8VD4oXG4gIGV4cGFuZHM6IEV4cGFuZDxUPixcbiAgeyBhbGlhc2VzLCBlc2NhcGUgPSBmYWxzZSB9OiB7IGFsaWFzZXM/OiBRdWVyeUN1c3RvbVR5cGVbXTsgZXNjYXBlPzogYm9vbGVhbiB9XG4pOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIGV4cGFuZHMgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIGV4cGFuZHMgYXMgYW55O1xuICB9IGVsc2UgaWYgKHR5cGVvZiBleHBhbmRzID09PSAnc3RyaW5nJykge1xuICAgIGlmIChleHBhbmRzLmluZGV4T2YoJy8nKSA9PT0gLTEpIHtcbiAgICAgIHJldHVybiBleHBhbmRzO1xuICAgIH1cblxuICAgIC8vIENoYW5nZSBgRm9vL0Jhci9CYXpgIHRvIGBGb28oJGV4cGFuZD1CYXIoJGV4cGFuZD1CYXopKWBcbiAgICByZXR1cm4gZXhwYW5kc1xuICAgICAgLnNwbGl0KCcvJylcbiAgICAgIC5yZXZlcnNlKClcbiAgICAgIC5yZWR1Y2UoKHJlc3VsdHMsIGl0ZW0sIGluZGV4LCBhcnIpID0+IHtcbiAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgLy8gSW5uZXItbW9zdCBpdGVtXG4gICAgICAgICAgcmV0dXJuIGAkZXhwYW5kPSR7aXRlbX1gO1xuICAgICAgICB9IGVsc2UgaWYgKGluZGV4ID09PSBhcnIubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIC8vIE91dGVyLW1vc3QgaXRlbSwgZG9uJ3QgYWRkIGAkZXhwYW5kPWAgcHJlZml4IChhZGRlZCBhYm92ZSlcbiAgICAgICAgICByZXR1cm4gYCR7aXRlbX0oJHtyZXN1bHRzfSlgO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE90aGVyIGl0ZW1zXG4gICAgICAgICAgcmV0dXJuIGAkZXhwYW5kPSR7aXRlbX0oJHtyZXN1bHRzfSlgO1xuICAgICAgICB9XG4gICAgICB9LCAnJyk7XG4gIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShleHBhbmRzKSkge1xuICAgIHJldHVybiBgJHsoZXhwYW5kcyBhcyBBcnJheTxOZXN0ZWRFeHBhbmRPcHRpb25zPGFueT4+KVxuICAgICAgLm1hcCgoZSkgPT4gYnVpbGRFeHBhbmQoZSwgeyBhbGlhc2VzLCBlc2NhcGUgfSkpXG4gICAgICAuam9pbignLCcpfWA7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGV4cGFuZHMgPT09ICdvYmplY3QnKSB7XG4gICAgY29uc3QgZXhwYW5kS2V5cyA9IE9iamVjdC5rZXlzKGV4cGFuZHMpO1xuXG4gICAgaWYgKFxuICAgICAgZXhwYW5kS2V5cy5zb21lKFxuICAgICAgICAoa2V5KSA9PiBTVVBQT1JURURfRVhQQU5EX1BST1BFUlRJRVMuaW5kZXhPZihrZXkudG9Mb3dlckNhc2UoKSkgIT09IC0xXG4gICAgICApXG4gICAgKSB7XG4gICAgICByZXR1cm4gZXhwYW5kS2V5c1xuICAgICAgICAubWFwKChrZXkpID0+IHtcbiAgICAgICAgICBsZXQgdmFsdWU7XG4gICAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgIHZhbHVlID0gYnVpbGRGaWx0ZXIoKGV4cGFuZHMgYXMgTmVzdGVkRXhwYW5kT3B0aW9uczxhbnk+KVtrZXldLCB7XG4gICAgICAgICAgICAgICAgYWxpYXNlcyxcbiAgICAgICAgICAgICAgICBlc2NhcGUsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ29yZGVyQnknOlxuICAgICAgICAgICAgICB2YWx1ZSA9IGJ1aWxkT3JkZXJCeShcbiAgICAgICAgICAgICAgICAoZXhwYW5kcyBhcyBOZXN0ZWRFeHBhbmRPcHRpb25zPGFueT4pW2tleV0gYXMgT3JkZXJCeTxUPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2xldmVscyc6XG4gICAgICAgICAgICBjYXNlICdjb3VudCc6XG4gICAgICAgICAgICBjYXNlICd0b3AnOlxuICAgICAgICAgICAgY2FzZSAnc2tpcCc6XG4gICAgICAgICAgICAgIHZhbHVlID0gYCR7KGV4cGFuZHMgYXMgTmVzdGVkRXhwYW5kT3B0aW9uczxhbnk+KVtrZXldfWA7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdmFsdWUgPSBidWlsZEV4cGFuZChcbiAgICAgICAgICAgICAgICAoZXhwYW5kcyBhcyBOZXN0ZWRFeHBhbmRPcHRpb25zPGFueT4pW2tleV0gYXMgRXhwYW5kPFQ+LFxuICAgICAgICAgICAgICAgIHsgYWxpYXNlcywgZXNjYXBlIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGAkJHtrZXkudG9Mb3dlckNhc2UoKX09JHt2YWx1ZX1gO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbignOycpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZXhwYW5kS2V5c1xuICAgICAgICAubWFwKChrZXkpID0+IHtcbiAgICAgICAgICBjb25zdCBidWlsdEV4cGFuZCA9IGJ1aWxkRXhwYW5kKFxuICAgICAgICAgICAgKGV4cGFuZHMgYXMgTmVzdGVkRXhwYW5kT3B0aW9uczxhbnk+KVtcbiAgICAgICAgICAgICAga2V5XG4gICAgICAgICAgICBdIGFzIE5lc3RlZEV4cGFuZE9wdGlvbnM8YW55PixcbiAgICAgICAgICAgIHsgYWxpYXNlcywgZXNjYXBlIH1cbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiBidWlsdEV4cGFuZCA/IGAke2tleX0oJHtidWlsdEV4cGFuZH0pYCA6IGtleTtcbiAgICAgICAgfSlcbiAgICAgICAgLmpvaW4oJywnKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBidWlsZFRyYW5zZm9ybXM8VD4oXG4gIHRyYW5zZm9ybXM6IFRyYW5zZm9ybTxUPiB8IFRyYW5zZm9ybTxUPltdLFxuICB7IGFsaWFzZXMsIGVzY2FwZSA9IGZhbHNlIH06IHsgYWxpYXNlcz86IFF1ZXJ5Q3VzdG9tVHlwZVtdOyBlc2NhcGU/OiBib29sZWFuIH1cbikge1xuICAvLyBXcmFwIHNpbmdsZSBvYmplY3QgYW4gYXJyYXkgZm9yIHNpbXBsaWZpZWQgcHJvY2Vzc2luZ1xuICBjb25zdCB0cmFuc2Zvcm1zQXJyYXkgPSBBcnJheS5pc0FycmF5KHRyYW5zZm9ybXMpID8gdHJhbnNmb3JtcyA6IFt0cmFuc2Zvcm1zXTtcblxuICBjb25zdCB0cmFuc2Zvcm1zUmVzdWx0ID0gdHJhbnNmb3Jtc0FycmF5LnJlZHVjZShcbiAgICAocmVzdWx0OiBzdHJpbmdbXSwgdHJhbnNmb3JtKSA9PiB7XG4gICAgICBjb25zdCB7IGFnZ3JlZ2F0ZSwgZmlsdGVyLCBncm91cEJ5LCAuLi5yZXN0IH0gPSB0cmFuc2Zvcm07XG5cbiAgICAgIC8vIFRPRE86IHN1cHBvcnQgYXMgbWFueSBvZiB0aGUgZm9sbG93aW5nOlxuICAgICAgLy8gICB0b3Bjb3VudCwgdG9wc3VtLCB0b3BwZXJjZW50LFxuICAgICAgLy8gICBib3R0b21zdW0sIGJvdHRvbWNvdW50LCBib3R0b21wZXJjZW50LFxuICAgICAgLy8gICBpZGVudGl0eSwgY29uY2F0LCBleHBhbmQsIHNlYXJjaCwgY29tcHV0ZSwgaXNkZWZpbmVkXG4gICAgICBjb25zdCB1bnN1cHBvcnRlZEtleXMgPSBPYmplY3Qua2V5cyhyZXN0KTtcbiAgICAgIGlmICh1bnN1cHBvcnRlZEtleXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdHJhbnNmb3JtKHMpOiAke3Vuc3VwcG9ydGVkS2V5c31gKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFnZ3JlZ2F0ZSkge1xuICAgICAgICByZXN1bHQucHVzaChgYWdncmVnYXRlKCR7YnVpbGRBZ2dyZWdhdGUoYWdncmVnYXRlKX0pYCk7XG4gICAgICB9XG4gICAgICBpZiAoZmlsdGVyKSB7XG4gICAgICAgIGNvbnN0IGJ1aWx0RmlsdGVyID0gYnVpbGRGaWx0ZXIoZmlsdGVyLCB7IGFsaWFzZXMsIGVzY2FwZSB9KTtcbiAgICAgICAgaWYgKGJ1aWx0RmlsdGVyKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goXG4gICAgICAgICAgICBgZmlsdGVyKCR7YnVpbGRGaWx0ZXIoYnVpbHRGaWx0ZXIsIHsgYWxpYXNlcywgZXNjYXBlIH0pfSlgXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGdyb3VwQnkpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goYGdyb3VwYnkoJHtidWlsZEdyb3VwQnkoZ3JvdXBCeSwgeyBhbGlhc2VzLCBlc2NhcGUgfSl9KWApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG4gICAgW11cbiAgKTtcblxuICByZXR1cm4gdHJhbnNmb3Jtc1Jlc3VsdC5qb2luKCcvJykgfHwgdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBidWlsZEFnZ3JlZ2F0ZShhZ2dyZWdhdGU6IEFnZ3JlZ2F0ZSB8IEFnZ3JlZ2F0ZVtdKSB7XG4gIC8vIFdyYXAgc2luZ2xlIG9iamVjdCBpbiBhbiBhcnJheSBmb3Igc2ltcGxpZmllZCBwcm9jZXNzaW5nXG4gIGNvbnN0IGFnZ3JlZ2F0ZUFycmF5ID0gQXJyYXkuaXNBcnJheShhZ2dyZWdhdGUpID8gYWdncmVnYXRlIDogW2FnZ3JlZ2F0ZV07XG5cbiAgcmV0dXJuIGFnZ3JlZ2F0ZUFycmF5XG4gICAgLm1hcCgoYWdncmVnYXRlSXRlbSkgPT4ge1xuICAgICAgcmV0dXJuIHR5cGVvZiBhZ2dyZWdhdGVJdGVtID09PSAnc3RyaW5nJ1xuICAgICAgICA/IGFnZ3JlZ2F0ZUl0ZW1cbiAgICAgICAgOiBPYmplY3Qua2V5cyhhZ2dyZWdhdGVJdGVtKS5tYXAoKGFnZ3JlZ2F0ZUtleSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWdncmVnYXRlVmFsdWUgPSBhZ2dyZWdhdGVJdGVtW2FnZ3JlZ2F0ZUtleV07XG5cbiAgICAgICAgICAgIC8vIFRPRE86IEFyZSB0aGVzZSBhbHdheXMgcmVxdWlyZWQ/ICBDYW4vc2hvdWxkIHdlIGRlZmF1bHQgdGhlbSBpZiBzbz9cbiAgICAgICAgICAgIGlmICghYWdncmVnYXRlVmFsdWUud2l0aCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCd3aXRoJyBwcm9wZXJ0eSByZXF1aXJlZCBmb3IgJyR7YWdncmVnYXRlS2V5fSdgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghYWdncmVnYXRlVmFsdWUuYXMpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAnYXMnIHByb3BlcnR5IHJlcXVpcmVkIGZvciAnJHthZ2dyZWdhdGVLZXl9J2ApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gYCR7YWdncmVnYXRlS2V5fSB3aXRoICR7YWdncmVnYXRlVmFsdWUud2l0aH0gYXMgJHthZ2dyZWdhdGVWYWx1ZS5hc31gO1xuICAgICAgICAgIH0pO1xuICAgIH0pXG4gICAgLmpvaW4oJywnKTtcbn1cblxuZnVuY3Rpb24gYnVpbGRHcm91cEJ5PFQ+KFxuICBncm91cEJ5OiBHcm91cEJ5PFQ+LFxuICB7IGFsaWFzZXMsIGVzY2FwZSA9IGZhbHNlIH06IHsgYWxpYXNlcz86IFF1ZXJ5Q3VzdG9tVHlwZVtdOyBlc2NhcGU/OiBib29sZWFuIH1cbikge1xuICBpZiAoIWdyb3VwQnkucHJvcGVydGllcykge1xuICAgIHRocm93IG5ldyBFcnJvcihgJ3Byb3BlcnRpZXMnIHByb3BlcnR5IHJlcXVpcmVkIGZvciBncm91cEJ5YCk7XG4gIH1cblxuICBsZXQgcmVzdWx0ID0gYCgke2dyb3VwQnkucHJvcGVydGllcy5qb2luKCcsJyl9KWA7XG5cbiAgaWYgKGdyb3VwQnkudHJhbnNmb3JtKSB7XG4gICAgcmVzdWx0ICs9IGAsJHtidWlsZFRyYW5zZm9ybXMoZ3JvdXBCeS50cmFuc2Zvcm0sIHsgYWxpYXNlcywgZXNjYXBlIH0pfWA7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBidWlsZE9yZGVyQnk8VD4ob3JkZXJCeTogT3JkZXJCeTxUPiwgcHJlZml4OiBzdHJpbmcgPSAnJyk6IHN0cmluZyB7XG4gIGlmIChBcnJheS5pc0FycmF5KG9yZGVyQnkpKSB7XG4gICAgcmV0dXJuIChvcmRlckJ5IGFzIE9yZGVyQnlPYmplY3Q8VD5bXSlcbiAgICAgIC5tYXAoKHZhbHVlKSA9PlxuICAgICAgICBBcnJheS5pc0FycmF5KHZhbHVlKSAmJlxuICAgICAgICB2YWx1ZS5sZW5ndGggPT09IDIgJiZcbiAgICAgICAgWydhc2MnLCAnZGVzYyddLmluZGV4T2YodmFsdWVbMV0pICE9PSAtMVxuICAgICAgICAgID8gdmFsdWUuam9pbignICcpXG4gICAgICAgICAgOiB2YWx1ZVxuICAgICAgKVxuICAgICAgLm1hcCgodikgPT4gYCR7cHJlZml4fSR7diBhcyBzdHJpbmd9YClcbiAgICAgIC5qb2luKCcsJyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9yZGVyQnkgPT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKG9yZGVyQnkpXG4gICAgICAubWFwKChbaywgdl0pID0+IGJ1aWxkT3JkZXJCeSh2IGFzIE9yZGVyQnk8YW55PiwgYCR7a30vYCkpXG4gICAgICAubWFwKCh2KSA9PiBgJHtwcmVmaXh9JHt2fWApXG4gICAgICAuam9pbignLCcpO1xuICB9XG4gIHJldHVybiBgJHtwcmVmaXh9JHtvcmRlckJ5IGFzIHN0cmluZ31gO1xufVxuXG5mdW5jdGlvbiBidWlsZFVybChwYXRoOiBzdHJpbmcsIHBhcmFtczogeyBbbmFtZTogc3RyaW5nXTogYW55IH0pOiBzdHJpbmcge1xuICAvLyBUaGlzIGNhbiBiZSByZWZhY3RvcmVkIHVzaW5nIFVSTCBBUEkuIEJ1dCBJRSBkb2VzIG5vdCBzdXBwb3J0IGl0LlxuICBjb25zdCBxdWVyaWVzOiBzdHJpbmdbXSA9IE9iamVjdC5lbnRyaWVzKHBhcmFtcykubWFwKFxuICAgIChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gXG4gICk7XG4gIHJldHVybiBxdWVyaWVzLmxlbmd0aCA/IGAke3BhdGh9PyR7cXVlcmllcy5qb2luKCcmJyl9YCA6IHBhdGg7XG59XG5cbmZ1bmN0aW9uIHBhcnNlTm90KGJ1aWx0RmlsdGVyczogc3RyaW5nW10pOiBzdHJpbmcge1xuICByZXR1cm4gYG5vdCgke2J1aWx0RmlsdGVycy5qb2luKCcgYW5kICcpfSlgO1xufVxuIl19
|