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