@ditojs/server 0.275.0 → 1.0.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/package.json +25 -43
- package/src/app/Application.js +105 -111
- package/src/app/Validator.js +6 -3
- package/src/app/index.js +2 -2
- package/src/cli/db/createMigration.js +1 -1
- package/src/cli/db/index.js +7 -7
- package/src/cli/db/listAssetConfig.js +1 -1
- package/src/cli/db/reset.js +1 -1
- package/src/cli/index.js +14 -5
- package/src/controllers/AdminController.js +181 -158
- package/src/controllers/CollectionController.js +8 -29
- package/src/controllers/Controller.js +71 -76
- package/src/controllers/ControllerAction.js +39 -17
- package/src/controllers/MemberAction.js +2 -2
- package/src/controllers/ModelController.js +4 -4
- package/src/controllers/RelationController.js +3 -3
- package/src/controllers/{UserController.js → UsersController.js} +8 -13
- package/src/controllers/index.js +5 -5
- package/src/decorators/action.js +3 -3
- package/src/decorators/authorize.js +1 -1
- package/src/decorators/index.js +6 -6
- package/src/decorators/parameters.js +1 -1
- package/src/decorators/returns.js +1 -1
- package/src/decorators/scope.js +1 -1
- package/src/decorators/transacted.js +1 -1
- package/src/errors/AssetError.js +1 -1
- package/src/errors/AuthenticationError.js +1 -1
- package/src/errors/AuthorizationError.js +1 -1
- package/src/errors/ControllerError.js +1 -1
- package/src/errors/DatabaseError.js +12 -3
- package/src/errors/GraphError.js +1 -1
- package/src/errors/ModelError.js +1 -1
- package/src/errors/NotFoundError.js +1 -1
- package/src/errors/NotImplementedError.js +1 -1
- package/src/errors/QueryBuilderError.js +1 -1
- package/src/errors/RelationError.js +1 -1
- package/src/errors/ValidationError.js +1 -1
- package/src/errors/WrappedError.js +1 -1
- package/src/errors/index.js +14 -14
- package/src/graph/DitoGraphProcessor.js +2 -1
- package/src/graph/graph.js +1 -1
- package/src/graph/index.js +3 -3
- package/src/index.js +11 -9
- package/src/lib/index.js +2 -2
- package/src/middleware/createTransaction.js +1 -1
- package/src/middleware/findRoute.js +3 -2
- package/src/middleware/handleConnectMiddleware.js +88 -0
- package/src/middleware/handleError.js +1 -1
- package/src/middleware/handleRoute.js +3 -3
- package/src/middleware/index.js +8 -7
- package/src/mixins/AssetMixin.js +1 -1
- package/src/mixins/UserMixin.js +1 -1
- package/src/mixins/index.js +4 -4
- package/src/models/AssetModel.js +2 -2
- package/src/models/Model.js +16 -12
- package/src/models/RelationAccessor.js +1 -1
- package/src/models/SessionModel.js +2 -2
- package/src/models/TimeStampedModel.js +2 -2
- package/src/models/UserModel.js +2 -2
- package/src/models/definitions/assets.js +1 -1
- package/src/models/definitions/filters.js +57 -44
- package/src/models/definitions/hooks.js +1 -1
- package/src/models/definitions/index.js +9 -9
- package/src/models/definitions/modifiers.js +1 -1
- package/src/models/definitions/options.js +1 -1
- package/src/models/definitions/properties.js +2 -2
- package/src/models/definitions/relations.js +1 -1
- package/src/models/definitions/schema.js +1 -1
- package/src/models/definitions/scopes.js +2 -2
- package/src/models/index.js +5 -5
- package/src/query/QueryBuilder.js +5 -5
- package/src/query/QueryFilters.js +50 -50
- package/src/query/QueryParameters.js +2 -2
- package/src/query/index.js +3 -3
- package/src/schema/formats/index.js +2 -2
- package/src/schema/index.js +4 -4
- package/src/schema/keywords/_relate.js +1 -1
- package/src/schema/keywords/index.js +12 -12
- package/src/schema/properties.test.js +1 -1
- package/src/schema/relations.js +1 -1
- package/src/schema/relations.test.js +2 -2
- package/src/services/index.js +1 -1
- package/src/storage/DiskStorage.js +1 -1
- package/src/storage/S3Storage.js +4 -4
- package/src/storage/Storage.js +1 -1
- package/src/storage/index.js +4 -4
- package/src/utils/function.test.js +1 -1
- package/src/utils/handler.js +17 -0
- package/src/utils/index.js +8 -7
- package/src/utils/object.test.js +1 -1
- package/lib/app/Application.js +0 -961
- package/lib/app/SessionStore.js +0 -40
- package/lib/app/Validator.js +0 -355
- package/lib/app/index.js +0 -26
- package/lib/cli/console.js +0 -175
- package/lib/cli/db/createMigration.js +0 -237
- package/lib/cli/db/index.js +0 -66
- package/lib/cli/db/listAssetConfig.js +0 -16
- package/lib/cli/db/migrate.js +0 -15
- package/lib/cli/db/reset.js +0 -27
- package/lib/cli/db/rollback.js +0 -15
- package/lib/cli/db/seed.js +0 -104
- package/lib/cli/db/unlock.js +0 -15
- package/lib/cli/index.js +0 -90
- package/lib/controllers/AdminController.js +0 -258
- package/lib/controllers/CollectionController.js +0 -263
- package/lib/controllers/Controller.js +0 -462
- package/lib/controllers/ControllerAction.js +0 -276
- package/lib/controllers/MemberAction.js +0 -22
- package/lib/controllers/ModelController.js +0 -64
- package/lib/controllers/RelationController.js +0 -82
- package/lib/controllers/UserController.js +0 -98
- package/lib/controllers/index.js +0 -50
- package/lib/decorators/action.js +0 -14
- package/lib/decorators/authorize.js +0 -13
- package/lib/decorators/index.js +0 -58
- package/lib/decorators/parameters.js +0 -35
- package/lib/decorators/returns.js +0 -26
- package/lib/decorators/scope.js +0 -14
- package/lib/decorators/transacted.js +0 -12
- package/lib/errors/AssetError.js +0 -19
- package/lib/errors/AuthenticationError.js +0 -19
- package/lib/errors/AuthorizationError.js +0 -19
- package/lib/errors/ControllerError.js +0 -24
- package/lib/errors/DatabaseError.js +0 -27
- package/lib/errors/GraphError.js +0 -19
- package/lib/errors/ModelError.js +0 -24
- package/lib/errors/NotFoundError.js +0 -19
- package/lib/errors/NotImplementedError.js +0 -19
- package/lib/errors/QueryBuilderError.js +0 -19
- package/lib/errors/RelationError.js +0 -36
- package/lib/errors/ResponseError.js +0 -46
- package/lib/errors/ValidationError.js +0 -19
- package/lib/errors/WrappedError.js +0 -24
- package/lib/errors/index.js +0 -122
- package/lib/graph/DitoGraphProcessor.js +0 -185
- package/lib/graph/expression.js +0 -76
- package/lib/graph/graph.js +0 -300
- package/lib/graph/index.js +0 -34
- package/lib/index.js +0 -82
- package/lib/lib/EventEmitter.js +0 -76
- package/lib/lib/KnexHelper.js +0 -40
- package/lib/lib/index.js +0 -26
- package/lib/middleware/attachLogger.js +0 -16
- package/lib/middleware/createTransaction.js +0 -36
- package/lib/middleware/findRoute.js +0 -35
- package/lib/middleware/handleError.js +0 -26
- package/lib/middleware/handleRoute.js +0 -29
- package/lib/middleware/handleUser.js +0 -36
- package/lib/middleware/index.js +0 -66
- package/lib/middleware/logRequests.js +0 -122
- package/lib/mixins/AssetMixin.js +0 -81
- package/lib/mixins/SessionMixin.js +0 -22
- package/lib/mixins/TimeStampedMixin.js +0 -47
- package/lib/mixins/UserMixin.js +0 -151
- package/lib/mixins/index.js +0 -42
- package/lib/models/AssetModel.js +0 -12
- package/lib/models/Model.js +0 -953
- package/lib/models/RelationAccessor.js +0 -41
- package/lib/models/SessionModel.js +0 -12
- package/lib/models/TimeStampedModel.js +0 -12
- package/lib/models/UserModel.js +0 -12
- package/lib/models/definitions/assets.js +0 -11
- package/lib/models/definitions/filters.js +0 -101
- package/lib/models/definitions/hooks.js +0 -11
- package/lib/models/definitions/index.js +0 -38
- package/lib/models/definitions/modifiers.js +0 -11
- package/lib/models/definitions/options.js +0 -11
- package/lib/models/definitions/properties.js +0 -87
- package/lib/models/definitions/relations.js +0 -11
- package/lib/models/definitions/schema.js +0 -11
- package/lib/models/definitions/scopes.js +0 -51
- package/lib/models/index.js +0 -50
- package/lib/query/QueryBuilder.js +0 -745
- package/lib/query/QueryFilters.js +0 -82
- package/lib/query/QueryParameters.js +0 -77
- package/lib/query/Registry.js +0 -40
- package/lib/query/index.js +0 -34
- package/lib/schema/formats/_empty.js +0 -10
- package/lib/schema/formats/_required.js +0 -10
- package/lib/schema/formats/index.js +0 -26
- package/lib/schema/index.js +0 -49
- package/lib/schema/keywords/_computed.js +0 -11
- package/lib/schema/keywords/_foreign.js +0 -11
- package/lib/schema/keywords/_hidden.js +0 -11
- package/lib/schema/keywords/_index.js +0 -11
- package/lib/schema/keywords/_instanceof.js +0 -49
- package/lib/schema/keywords/_primary.js +0 -11
- package/lib/schema/keywords/_range.js +0 -26
- package/lib/schema/keywords/_relate.js +0 -19
- package/lib/schema/keywords/_specificType.js +0 -11
- package/lib/schema/keywords/_unique.js +0 -11
- package/lib/schema/keywords/_unsigned.js +0 -11
- package/lib/schema/keywords/_validate.js +0 -80
- package/lib/schema/keywords/index.js +0 -106
- package/lib/schema/properties.js +0 -227
- package/lib/schema/properties.test.js +0 -573
- package/lib/schema/relations.js +0 -274
- package/lib/schema/relations.test.js +0 -155
- package/lib/services/Service.js +0 -34
- package/lib/services/index.js +0 -18
- package/lib/storage/AssetFile.js +0 -97
- package/lib/storage/DiskStorage.js +0 -125
- package/lib/storage/S3Storage.js +0 -171
- package/lib/storage/Storage.js +0 -209
- package/lib/storage/index.js +0 -34
- package/lib/utils/decorator.js +0 -16
- package/lib/utils/deprecate.js +0 -46
- package/lib/utils/emitter.js +0 -13
- package/lib/utils/function.js +0 -14
- package/lib/utils/function.test.js +0 -49
- package/lib/utils/index.js +0 -66
- package/lib/utils/json.js +0 -9
- package/lib/utils/object.js +0 -92
- package/lib/utils/object.test.js +0 -65
- package/lib/utils/scope.js +0 -14
|
@@ -1,462 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.Controller = void 0;
|
|
5
|
-
|
|
6
|
-
require("core-js/modules/esnext.async-iterator.for-each.js");
|
|
7
|
-
|
|
8
|
-
require("core-js/modules/esnext.iterator.constructor.js");
|
|
9
|
-
|
|
10
|
-
require("core-js/modules/esnext.iterator.for-each.js");
|
|
11
|
-
|
|
12
|
-
require("core-js/modules/esnext.async-iterator.map.js");
|
|
13
|
-
|
|
14
|
-
require("core-js/modules/esnext.iterator.map.js");
|
|
15
|
-
|
|
16
|
-
require("core-js/modules/esnext.async-iterator.filter.js");
|
|
17
|
-
|
|
18
|
-
require("core-js/modules/esnext.iterator.filter.js");
|
|
19
|
-
|
|
20
|
-
require("core-js/modules/esnext.async-iterator.reduce.js");
|
|
21
|
-
|
|
22
|
-
require("core-js/modules/esnext.iterator.reduce.js");
|
|
23
|
-
|
|
24
|
-
require("core-js/modules/esnext.async-iterator.find.js");
|
|
25
|
-
|
|
26
|
-
require("core-js/modules/esnext.iterator.find.js");
|
|
27
|
-
|
|
28
|
-
require("core-js/modules/esnext.weak-map.delete-all.js");
|
|
29
|
-
|
|
30
|
-
require("core-js/modules/esnext.weak-map.emplace.js");
|
|
31
|
-
|
|
32
|
-
var _picocolors = _interopRequireDefault(require("picocolors"));
|
|
33
|
-
|
|
34
|
-
var _utils = require("../utils");
|
|
35
|
-
|
|
36
|
-
var _lib = require("../lib");
|
|
37
|
-
|
|
38
|
-
var _ControllerAction = _interopRequireDefault(require("./ControllerAction"));
|
|
39
|
-
|
|
40
|
-
var _MemberAction = _interopRequireDefault(require("./MemberAction"));
|
|
41
|
-
|
|
42
|
-
var _errors = require("../errors");
|
|
43
|
-
|
|
44
|
-
var _utils2 = require("@ditojs/utils");
|
|
45
|
-
|
|
46
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
47
|
-
|
|
48
|
-
class Controller {
|
|
49
|
-
constructor(app, namespace) {
|
|
50
|
-
this.app = app;
|
|
51
|
-
this.namespace = this.namespace || namespace;
|
|
52
|
-
this.logging = this.app.config.log.routes;
|
|
53
|
-
this.level = 0;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
initialize() {}
|
|
57
|
-
|
|
58
|
-
setup(isRoot = true, setupActionsObject = true) {
|
|
59
|
-
this._setupEmitter(this.hooks, {
|
|
60
|
-
wildcard: true
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
this.name = this.name || this.constructor.name.match(/^(.*?)(?:Controller|)$/)[1];
|
|
64
|
-
|
|
65
|
-
if (this.path === undefined) {
|
|
66
|
-
this.path = this.app.normalizePath(this.name);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
this.transacted = !!this.transacted;
|
|
70
|
-
|
|
71
|
-
if (isRoot) {
|
|
72
|
-
const {
|
|
73
|
-
path,
|
|
74
|
-
namespace
|
|
75
|
-
} = this;
|
|
76
|
-
const url = path ? `/${path}` : '';
|
|
77
|
-
this.url = namespace ? `/${namespace}${url}` : url;
|
|
78
|
-
this.log(`${namespace ? _picocolors.default.green(`/${namespace}/`) : ''}${_picocolors.default.cyan(path)}${_picocolors.default.white(':')}`, this.level);
|
|
79
|
-
|
|
80
|
-
if (setupActionsObject) {
|
|
81
|
-
this.actions = this.actions || this.reflectActionsObject();
|
|
82
|
-
this.actions = this.setupActions('actions');
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
this.assets = this.setupAssets();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
reflectActionsObject() {
|
|
90
|
-
const {
|
|
91
|
-
allow
|
|
92
|
-
} = this;
|
|
93
|
-
const controller = allow ? {
|
|
94
|
-
allow
|
|
95
|
-
} : {};
|
|
96
|
-
|
|
97
|
-
const addAction = key => {
|
|
98
|
-
const value = this[key];
|
|
99
|
-
|
|
100
|
-
if (value != null && value.verb) {
|
|
101
|
-
controller[key] = value;
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const proto = Object.getPrototypeOf(this);
|
|
106
|
-
Object.getOwnPropertyNames(proto).forEach(addAction);
|
|
107
|
-
Object.getOwnPropertyNames(this).forEach(addAction);
|
|
108
|
-
return controller;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
setupRoute(verb, url, transacted, authorize, action, handlers) {
|
|
112
|
-
this.log(`${_picocolors.default.magenta(verb.toUpperCase())} ${_picocolors.default.green(this.url)}${_picocolors.default.cyan(url.slice(this.url.length))} ${_picocolors.default.white(this.describeAuthorize(authorize))}`, this.level + 1);
|
|
113
|
-
this.app.addRoute(verb, url, transacted, handlers, this, action);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
setupActions(type) {
|
|
117
|
-
const {
|
|
118
|
-
values: actions,
|
|
119
|
-
authorize
|
|
120
|
-
} = this.processValues(this.inheritValues(type));
|
|
121
|
-
|
|
122
|
-
for (const [name, handler] of Object.entries(actions)) {
|
|
123
|
-
this.setupAction(type, actions, name, handler, authorize[name]);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return actions;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
setupAction(type, actions, name, handler, authorize, verb = 'get', path = this.app.normalizePath(name)) {
|
|
130
|
-
if (!(0, _utils2.isFunction)(handler)) {
|
|
131
|
-
handler = setupHandlerFromObject(handler, actions);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const actionClass = type === 'member' ? _MemberAction.default : _ControllerAction.default;
|
|
135
|
-
this.setupActionRoute(type, new actionClass(this, handler, type, name, verb, path, authorize));
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
setupActionRoute(type, action) {
|
|
139
|
-
const url = this.getUrl(type, action.path);
|
|
140
|
-
const {
|
|
141
|
-
verb,
|
|
142
|
-
transacted,
|
|
143
|
-
authorize
|
|
144
|
-
} = action;
|
|
145
|
-
this.setupRoute(verb, url, transacted, authorize, action, [async ctx => {
|
|
146
|
-
try {
|
|
147
|
-
const res = await action.callAction(ctx);
|
|
148
|
-
|
|
149
|
-
if (res !== undefined) {
|
|
150
|
-
ctx.body = res;
|
|
151
|
-
}
|
|
152
|
-
} catch (err) {
|
|
153
|
-
throw err instanceof _errors.ResponseError ? err : new _errors.WrappedError(err);
|
|
154
|
-
}
|
|
155
|
-
}]);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
setupAssets() {
|
|
159
|
-
const {
|
|
160
|
-
values: assets,
|
|
161
|
-
authorize
|
|
162
|
-
} = this.processValues(this.inheritValues('assets'));
|
|
163
|
-
|
|
164
|
-
for (const [dataPath, config] of Object.entries(assets || {})) {
|
|
165
|
-
this.setupAssetRoute(dataPath, config, authorize[dataPath]);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return assets;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
setupAssetRoute(dataPath, config, authorize) {
|
|
172
|
-
const {
|
|
173
|
-
storage: storageName,
|
|
174
|
-
transacted,
|
|
175
|
-
...settings
|
|
176
|
-
} = config;
|
|
177
|
-
const storage = this.app.getStorage(storageName);
|
|
178
|
-
|
|
179
|
-
if (!storage) {
|
|
180
|
-
throw new _errors.ControllerError(this, `Unknown storage configuration: '${storageName}'`);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const tokens = (0, _utils2.parseDataPath)(dataPath);
|
|
184
|
-
|
|
185
|
-
const getDataPath = callback => (0, _utils2.normalizeDataPath)(tokens.map(callback));
|
|
186
|
-
|
|
187
|
-
let index = 0;
|
|
188
|
-
const multipleWildcards = tokens.filter(token => token === '*').length > 1;
|
|
189
|
-
const normalizedPath = getDataPath(token => token === '*' ? multipleWildcards ? `:index${++index}` : ':index' : this.app.normalizePath(token));
|
|
190
|
-
const matchDataPath = new RegExp(`^${getDataPath(token => token === '*' ? '\\w+' : token)}$`);
|
|
191
|
-
const url = this.getUrl('controller', `upload/${normalizedPath}`);
|
|
192
|
-
const upload = storage.getUploadHandler({ ...settings,
|
|
193
|
-
fileFilter: (req, file, cb) => {
|
|
194
|
-
cb(null, matchDataPath.test(file.fieldname));
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
const authorization = this.processAuthorize(authorize);
|
|
198
|
-
this.setupRoute('post', url, transacted, authorize, null, [async (ctx, next) => {
|
|
199
|
-
await this.handleAuthorization(authorization, ctx);
|
|
200
|
-
return next();
|
|
201
|
-
}, upload, async (ctx, next) => {
|
|
202
|
-
const files = storage.convertStorageFiles(ctx.request.files);
|
|
203
|
-
await this.app.createAssets(storage, files, 0, ctx.transaction);
|
|
204
|
-
ctx.body = files;
|
|
205
|
-
return next();
|
|
206
|
-
}]);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
compose() {}
|
|
210
|
-
|
|
211
|
-
getPath(type, path) {
|
|
212
|
-
return path;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
getUrl(type, path) {
|
|
216
|
-
path = this.getPath(type, path);
|
|
217
|
-
return path && path !== '.' ? `${this.url}/${path}` : this.url;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
inheritValues(type) {
|
|
221
|
-
const parentClass = Object.getPrototypeOf(this.constructor);
|
|
222
|
-
|
|
223
|
-
if (!inheritanceMap.has(parentClass)) {
|
|
224
|
-
inheritanceMap.set(parentClass, {
|
|
225
|
-
instance: new parentClass(this.app, this.namespace)
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const entry = inheritanceMap.get(parentClass);
|
|
230
|
-
|
|
231
|
-
if (!entry[type]) {
|
|
232
|
-
const parent = entry.instance;
|
|
233
|
-
let values = parent[type];
|
|
234
|
-
|
|
235
|
-
if (parentClass !== Controller) {
|
|
236
|
-
values = parent.inheritValues(type);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
entry[type] = values;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const parentValues = entry[type];
|
|
243
|
-
let currentValues = this[type];
|
|
244
|
-
|
|
245
|
-
if (currentValues && currentValues === parentValues) {
|
|
246
|
-
currentValues = this[type] = {};
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return (0, _utils2.isObject)(parentValues) && (0, _utils2.isObject)(currentValues) ? Object.setPrototypeOf(currentValues, parentValues) : currentValues;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
processValues(values) {
|
|
253
|
-
if (!values) return {};
|
|
254
|
-
const mergedAllow = {};
|
|
255
|
-
const mergedAuthorize = {};
|
|
256
|
-
let hasOwnAllow = false;
|
|
257
|
-
|
|
258
|
-
const excludeKey = key => ['allow', 'authorize'].includes(key);
|
|
259
|
-
|
|
260
|
-
const handleAllow = (allow, current) => {
|
|
261
|
-
if (allow) {
|
|
262
|
-
allow = (0, _utils2.asArray)(allow);
|
|
263
|
-
hasOwnAllow = true;
|
|
264
|
-
} else if (!hasOwnAllow) {
|
|
265
|
-
allow = Object.keys(current);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (allow) {
|
|
269
|
-
if (allow.includes('*')) {
|
|
270
|
-
allow = (0, _utils.getAllKeys)(current);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
for (const key of allow) {
|
|
274
|
-
if (!excludeKey(key)) {
|
|
275
|
-
mergedAllow[key] = true;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
const handleAuthorize = authorize => {
|
|
282
|
-
const add = (key, value) => {
|
|
283
|
-
if (key in values && !(key in mergedAuthorize) && !excludeKey(key)) {
|
|
284
|
-
mergedAuthorize[key] = value;
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
if ((0, _utils2.isObject)(authorize)) {
|
|
289
|
-
for (const key in authorize) {
|
|
290
|
-
add(key, authorize[key]);
|
|
291
|
-
}
|
|
292
|
-
} else if (authorize != null) {
|
|
293
|
-
for (const key in values) {
|
|
294
|
-
add(key, authorize);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
let current = values;
|
|
300
|
-
|
|
301
|
-
while (current !== Object.prototype && !current.hasOwnProperty('$core')) {
|
|
302
|
-
handleAllow((0, _utils.getOwnProperty)(current, 'allow'), current);
|
|
303
|
-
handleAuthorize((0, _utils.getOwnProperty)(current, 'authorize'));
|
|
304
|
-
current = Object.getPrototypeOf(current);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (this.allow) {
|
|
308
|
-
handleAllow(this.allow, values);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
if (this.authorize) {
|
|
312
|
-
handleAuthorize(this.authorize);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return {
|
|
316
|
-
values: (0, _utils.getAllKeys)(values).reduce((result, key) => {
|
|
317
|
-
if (mergedAllow[key]) {
|
|
318
|
-
result[key] = values[key];
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
return result;
|
|
322
|
-
}, Object.create(Object.getPrototypeOf(values))),
|
|
323
|
-
allow: Object.keys(mergedAllow),
|
|
324
|
-
authorize: mergedAuthorize
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
async emitHook(type, handleResult, ctx, ...args) {
|
|
329
|
-
let result = handleResult ? args.shift() : undefined;
|
|
330
|
-
|
|
331
|
-
for (const handler of this.listeners(type)) {
|
|
332
|
-
if (handleResult) {
|
|
333
|
-
const res = await handler.call(this, ctx, result, ...args);
|
|
334
|
-
|
|
335
|
-
if (res !== undefined) {
|
|
336
|
-
result = res;
|
|
337
|
-
}
|
|
338
|
-
} else {
|
|
339
|
-
await handler.call(this, ctx, ...args);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
return result;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
async getMember() {
|
|
347
|
-
return null;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
processAuthorize(authorize) {
|
|
351
|
-
if (authorize == null) {
|
|
352
|
-
return () => true;
|
|
353
|
-
} else if ((0, _utils2.isBoolean)(authorize)) {
|
|
354
|
-
return () => authorize;
|
|
355
|
-
} else if ((0, _utils2.isFunction)(authorize)) {
|
|
356
|
-
return async (ctx, member) => {
|
|
357
|
-
const res = await authorize(ctx, member);
|
|
358
|
-
return this.processAuthorize(res)(ctx, member);
|
|
359
|
-
};
|
|
360
|
-
} else if ((0, _utils2.isString)(authorize) || (0, _utils2.isArray)(authorize)) {
|
|
361
|
-
return async (ctx, member) => {
|
|
362
|
-
const {
|
|
363
|
-
user
|
|
364
|
-
} = ctx.state;
|
|
365
|
-
|
|
366
|
-
if (!user) {
|
|
367
|
-
return false;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
const values = (0, _utils2.asArray)(authorize);
|
|
371
|
-
|
|
372
|
-
if (!member && values.includes('$owner')) {
|
|
373
|
-
member = await this.getMember(ctx);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
return !!values.find(value => {
|
|
377
|
-
var _member;
|
|
378
|
-
|
|
379
|
-
return value === '$self' ? user.constructor === this.modelClass && (0, _utils2.equals)(user.$id(), ctx.memberId) : value === '$owner' ? (_member = member) == null ? void 0 : _member.$hasOwner == null ? void 0 : _member.$hasOwner(user) : user.$hasRole(value);
|
|
380
|
-
});
|
|
381
|
-
};
|
|
382
|
-
} else {
|
|
383
|
-
throw new _errors.ControllerError(this, `Unsupported authorize setting: '${authorize}'`);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
describeAuthorize(authorize) {
|
|
388
|
-
return (0, _utils2.isFunction)(authorize) ? (0, _utils.describeFunction)(authorize) : (0, _utils2.isString)(authorize) ? `'${authorize}'` : (0, _utils2.isArray)(authorize) ? `[${authorize.map(value => `'${value}'`).join(', ')}]` : '';
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
async handleAuthorization(authorization, ctx, member) {
|
|
392
|
-
const ok = await authorization(ctx, member);
|
|
393
|
-
|
|
394
|
-
if (ok !== true) {
|
|
395
|
-
throw new _errors.AuthorizationError();
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
log(str, indent = 0) {
|
|
400
|
-
if (this.logging) {
|
|
401
|
-
console.info(`${' '.repeat(indent)}${str}`);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
exports.Controller = Controller;
|
|
408
|
-
|
|
409
|
-
_lib.EventEmitter.mixin(Controller.prototype);
|
|
410
|
-
|
|
411
|
-
const inheritanceMap = new WeakMap();
|
|
412
|
-
|
|
413
|
-
function setupHandlerFromObject(object, actions) {
|
|
414
|
-
const {
|
|
415
|
-
handler,
|
|
416
|
-
action,
|
|
417
|
-
authorize,
|
|
418
|
-
parameters,
|
|
419
|
-
returns,
|
|
420
|
-
scope,
|
|
421
|
-
transacted
|
|
422
|
-
} = object;
|
|
423
|
-
Object.setPrototypeOf(object, Object.getPrototypeOf(actions));
|
|
424
|
-
handler.authorize = authorize;
|
|
425
|
-
handler.transacted = transacted;
|
|
426
|
-
|
|
427
|
-
if (action) {
|
|
428
|
-
const [verb, path] = (0, _utils2.asArray)(action);
|
|
429
|
-
handler.verb = verb;
|
|
430
|
-
handler.path = path;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
if (parameters) {
|
|
434
|
-
const [_parameters, options] = parameters;
|
|
435
|
-
const hasOptions = (0, _utils2.isArray)(_parameters);
|
|
436
|
-
handler.parameters = hasOptions ? _parameters : parameters;
|
|
437
|
-
|
|
438
|
-
if (hasOptions) {
|
|
439
|
-
handler.options = { ...handler.options,
|
|
440
|
-
parameters: options
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
if (returns) {
|
|
446
|
-
const [_returns, options] = (0, _utils2.asArray)(returns);
|
|
447
|
-
handler.returns = _returns;
|
|
448
|
-
|
|
449
|
-
if (options) {
|
|
450
|
-
handler.options = { ...handler.options,
|
|
451
|
-
parameters: options
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
if (scope) {
|
|
457
|
-
handler.scope = (0, _utils2.asArray)(scope);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
return handler;
|
|
461
|
-
}
|
|
462
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb250cm9sbGVycy9Db250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFwcCIsIm5hbWVzcGFjZSIsImxvZ2dpbmciLCJjb25maWciLCJsb2ciLCJyb3V0ZXMiLCJsZXZlbCIsImluaXRpYWxpemUiLCJzZXR1cCIsImlzUm9vdCIsInNldHVwQWN0aW9uc09iamVjdCIsIl9zZXR1cEVtaXR0ZXIiLCJob29rcyIsIndpbGRjYXJkIiwibmFtZSIsIm1hdGNoIiwicGF0aCIsInVuZGVmaW5lZCIsIm5vcm1hbGl6ZVBhdGgiLCJ0cmFuc2FjdGVkIiwidXJsIiwicGljbyIsImdyZWVuIiwiY3lhbiIsIndoaXRlIiwiYWN0aW9ucyIsInJlZmxlY3RBY3Rpb25zT2JqZWN0Iiwic2V0dXBBY3Rpb25zIiwiYXNzZXRzIiwic2V0dXBBc3NldHMiLCJhbGxvdyIsImNvbnRyb2xsZXIiLCJhZGRBY3Rpb24iLCJrZXkiLCJ2YWx1ZSIsInZlcmIiLCJwcm90byIsIk9iamVjdCIsImdldFByb3RvdHlwZU9mIiwiZ2V0T3duUHJvcGVydHlOYW1lcyIsImZvckVhY2giLCJzZXR1cFJvdXRlIiwiYXV0aG9yaXplIiwiYWN0aW9uIiwiaGFuZGxlcnMiLCJtYWdlbnRhIiwidG9VcHBlckNhc2UiLCJzbGljZSIsImxlbmd0aCIsImRlc2NyaWJlQXV0aG9yaXplIiwiYWRkUm91dGUiLCJ0eXBlIiwidmFsdWVzIiwicHJvY2Vzc1ZhbHVlcyIsImluaGVyaXRWYWx1ZXMiLCJoYW5kbGVyIiwiZW50cmllcyIsInNldHVwQWN0aW9uIiwic2V0dXBIYW5kbGVyRnJvbU9iamVjdCIsImFjdGlvbkNsYXNzIiwiTWVtYmVyQWN0aW9uIiwiQ29udHJvbGxlckFjdGlvbiIsInNldHVwQWN0aW9uUm91dGUiLCJnZXRVcmwiLCJjdHgiLCJyZXMiLCJjYWxsQWN0aW9uIiwiYm9keSIsImVyciIsIlJlc3BvbnNlRXJyb3IiLCJXcmFwcGVkRXJyb3IiLCJkYXRhUGF0aCIsInNldHVwQXNzZXRSb3V0ZSIsInN0b3JhZ2UiLCJzdG9yYWdlTmFtZSIsInNldHRpbmdzIiwiZ2V0U3RvcmFnZSIsIkNvbnRyb2xsZXJFcnJvciIsInRva2VucyIsImdldERhdGFQYXRoIiwiY2FsbGJhY2siLCJtYXAiLCJpbmRleCIsIm11bHRpcGxlV2lsZGNhcmRzIiwiZmlsdGVyIiwidG9rZW4iLCJub3JtYWxpemVkUGF0aCIsIm1hdGNoRGF0YVBhdGgiLCJSZWdFeHAiLCJ1cGxvYWQiLCJnZXRVcGxvYWRIYW5kbGVyIiwiZmlsZUZpbHRlciIsInJlcSIsImZpbGUiLCJjYiIsInRlc3QiLCJmaWVsZG5hbWUiLCJhdXRob3JpemF0aW9uIiwicHJvY2Vzc0F1dGhvcml6ZSIsIm5leHQiLCJoYW5kbGVBdXRob3JpemF0aW9uIiwiZmlsZXMiLCJjb252ZXJ0U3RvcmFnZUZpbGVzIiwicmVxdWVzdCIsImNyZWF0ZUFzc2V0cyIsInRyYW5zYWN0aW9uIiwiY29tcG9zZSIsImdldFBhdGgiLCJwYXJlbnRDbGFzcyIsImluaGVyaXRhbmNlTWFwIiwiaGFzIiwic2V0IiwiaW5zdGFuY2UiLCJlbnRyeSIsImdldCIsInBhcmVudCIsInBhcmVudFZhbHVlcyIsImN1cnJlbnRWYWx1ZXMiLCJzZXRQcm90b3R5cGVPZiIsIm1lcmdlZEFsbG93IiwibWVyZ2VkQXV0aG9yaXplIiwiaGFzT3duQWxsb3ciLCJleGNsdWRlS2V5IiwiaW5jbHVkZXMiLCJoYW5kbGVBbGxvdyIsImN1cnJlbnQiLCJrZXlzIiwiaGFuZGxlQXV0aG9yaXplIiwiYWRkIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJyZWR1Y2UiLCJyZXN1bHQiLCJjcmVhdGUiLCJlbWl0SG9vayIsImhhbmRsZVJlc3VsdCIsImFyZ3MiLCJzaGlmdCIsImxpc3RlbmVycyIsImNhbGwiLCJnZXRNZW1iZXIiLCJtZW1iZXIiLCJ1c2VyIiwic3RhdGUiLCJmaW5kIiwibW9kZWxDbGFzcyIsIiRpZCIsIm1lbWJlcklkIiwiJGhhc093bmVyIiwiJGhhc1JvbGUiLCJqb2luIiwib2siLCJBdXRob3JpemF0aW9uRXJyb3IiLCJzdHIiLCJpbmRlbnQiLCJjb25zb2xlIiwiaW5mbyIsInJlcGVhdCIsIkV2ZW50RW1pdHRlciIsIm1peGluIiwiV2Vha01hcCIsIm9iamVjdCIsInBhcmFtZXRlcnMiLCJyZXR1cm5zIiwic2NvcGUiLCJfcGFyYW1ldGVycyIsIm9wdGlvbnMiLCJoYXNPcHRpb25zIiwiX3JldHVybnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFHQTs7OztBQUtPLE1BQU1BLFVBQU4sQ0FBaUI7QUFDdEJDLEVBQUFBLFdBQVcsQ0FBQ0MsR0FBRCxFQUFNQyxTQUFOLEVBQWlCO0FBQzFCLFNBQUtELEdBQUwsR0FBV0EsR0FBWDtBQUNBLFNBQUtDLFNBQUwsR0FBaUIsS0FBS0EsU0FBTCxJQUFrQkEsU0FBbkM7QUFDQSxTQUFLQyxPQUFMLEdBQWUsS0FBS0YsR0FBTCxDQUFTRyxNQUFULENBQWdCQyxHQUFoQixDQUFvQkMsTUFBbkM7QUFDQSxTQUFLQyxLQUFMLEdBQWEsQ0FBYjtBQUNEOztBQUdEQyxFQUFBQSxVQUFVLEdBQUcsQ0FDWjs7QUFFREMsRUFBQUEsS0FBSyxDQUFDQyxNQUFNLEdBQUcsSUFBVixFQUFnQkMsa0JBQWtCLEdBQUcsSUFBckMsRUFBMkM7QUFDOUMsU0FBS0MsYUFBTCxDQUFtQixLQUFLQyxLQUF4QixFQUErQjtBQUU3QkMsTUFBQUEsUUFBUSxFQUFFO0FBRm1CLEtBQS9COztBQUtBLFNBQUtDLElBQUwsR0FBWSxLQUFLQSxJQUFMLElBQ1YsS0FBS2YsV0FBTCxDQUFpQmUsSUFBakIsQ0FBc0JDLEtBQXRCLENBQTRCLHdCQUE1QixFQUFzRCxDQUF0RCxDQURGOztBQUVBLFFBQUksS0FBS0MsSUFBTCxLQUFjQyxTQUFsQixFQUE2QjtBQUMzQixXQUFLRCxJQUFMLEdBQVksS0FBS2hCLEdBQUwsQ0FB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Q0FBQ3ZDLElBQVIsR0FBZUEsSUFBZjtBQUNEOztBQUVELE1BQUlrSixVQUFKLEVBQWdCO0FBQ2QsVUFBTSxDQUFDRyxXQUFELEVBQWNDLE9BQWQsSUFBeUJKLFVBQS9CO0FBQ0EsVUFBTUssVUFBVSxHQUFHLHFCQUFRRixXQUFSLENBQW5CO0FBQ0E5RyxJQUFBQSxPQUFPLENBQUMyRyxVQUFSLEdBQXFCSyxVQUFVLEdBQUdGLFdBQUgsR0FBaUJILFVBQWhEOztBQUlBLFFBQUlLLFVBQUosRUFBZ0I7QUFDZGhILE1BQUFBLE9BQU8sQ0FBQytHLE9BQVIsR0FBa0IsRUFDaEIsR0FBRy9HLE9BQU8sQ0FBQytHLE9BREs7QUFFaEJKLFFBQUFBLFVBQVUsRUFBRUk7QUFGSSxPQUFsQjtBQUlEO0FBQ0Y7O0FBRUQsTUFBSUgsT0FBSixFQUFhO0FBQ1gsVUFBTSxDQUFDSyxRQUFELEVBQVdGLE9BQVgsSUFBc0IscUJBQVFILE9BQVIsQ0FBNUI7QUFDQTVHLElBQUFBLE9BQU8sQ0FBQzRHLE9BQVIsR0FBa0JLLFFBQWxCOztBQUlBLFFBQUlGLE9BQUosRUFBYTtBQUNYL0csTUFBQUEsT0FBTyxDQUFDK0csT0FBUixHQUFrQixFQUNoQixHQUFHL0csT0FBTyxDQUFDK0csT0FESztBQUVoQkosUUFBQUEsVUFBVSxFQUFFSTtBQUZJLE9BQWxCO0FBSUQ7QUFDRjs7QUFFRCxNQUFJRixLQUFKLEVBQVc7QUFDVDdHLElBQUFBLE9BQU8sQ0FBQzZHLEtBQVIsR0FBZ0IscUJBQVFBLEtBQVIsQ0FBaEI7QUFDRDs7QUFFRCxTQUFPN0csT0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHBpY28gZnJvbSAncGljb2NvbG9ycydcbmltcG9ydCB7IGdldE93blByb3BlcnR5LCBnZXRBbGxLZXlzLCBkZXNjcmliZUZ1bmN0aW9uIH0gZnJvbSAnQC91dGlscydcbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ0AvbGliJ1xuaW1wb3J0IENvbnRyb2xsZXJBY3Rpb24gZnJvbSAnLi9Db250cm9sbGVyQWN0aW9uJ1xuaW1wb3J0IE1lbWJlckFjdGlvbiBmcm9tICcuL01lbWJlckFjdGlvbidcbmltcG9ydCB7XG4gIFJlc3BvbnNlRXJyb3IsIFdyYXBwZWRFcnJvciwgQ29udHJvbGxlckVycm9yLCBBdXRob3JpemF0aW9uRXJyb3Jcbn0gZnJvbSAnQC9lcnJvcnMnXG5pbXBvcnQge1xuICBpc09iamVjdCwgaXNTdHJpbmcsIGlzQXJyYXksIGlzQm9vbGVhbiwgaXNGdW5jdGlvbiwgYXNBcnJheSwgZXF1YWxzLFxuICBwYXJzZURhdGFQYXRoLCBub3JtYWxpemVEYXRhUGF0aFxufSBmcm9tICdAZGl0b2pzL3V0aWxzJ1xuXG5leHBvcnQgY2xhc3MgQ29udHJvbGxlciB7XG4gIGNvbnN0cnVjdG9yKGFwcCwgbmFtZXNwYWNlKSB7XG4gICAgdGhpcy5hcHAgPSBhcHBcbiAgICB0aGlzLm5hbWVzcGFjZSA9IHRoaXMubmFtZXNwYWNlIHx8IG5hbWVzcGFjZVxuICAgIHRoaXMubG9nZ2luZyA9IHRoaXMuYXBwLmNvbmZpZy5sb2cucm91dGVzXG4gICAgdGhpcy5sZXZlbCA9IDBcbiAgfVxuXG4gIC8vIEBvdmVycmlkYWJsZVxuICBpbml0aWFsaXplKCkge1xuICB9XG5cbiAgc2V0dXAoaXNSb290ID0gdHJ1ZSwgc2V0dXBBY3Rpb25zT2JqZWN0ID0gdHJ1ZSkge1xuICAgIHRoaXMuX3NldHVwRW1pdHRlcih0aGlzLmhvb2tzLCB7XG4gICAgICAvLyBTdXBwb3J0IHdpbGRjYXJkIGhvb2tzIG9ubHkgb24gY29udHJvbGxlcnM6XG4gICAgICB3aWxkY2FyZDogdHJ1ZVxuICAgIH0pXG4gICAgLy8gSWYgdGhlIGNsYXNzIG5hbWUgZW5kcyBpbiAnQ29udHJvbGxlcicsIHJlbW92ZSBpdCBmcm9tIGNvbnRyb2xsZXIgbmFtZS5cbiAgICB0aGlzLm5hbWUgPSB0aGlzLm5hbWUgfHxcbiAgICAgIHRoaXMuY29uc3RydWN0b3IubmFtZS5tYXRjaCgvXiguKj8pKD86Q29udHJvbGxlcnwpJC8pWzFdXG4gICAgaWYgKHRoaXMucGF0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnBhdGggPSB0aGlzLmFwcC5ub3JtYWxpemVQYXRoKHRoaXMubmFtZSlcbiAgICB9XG4gICAgdGhpcy50cmFuc2FjdGVkID0gISF0aGlzLnRyYW5zYWN0ZWRcbiAgICBpZiAoaXNSb290KSB7XG4gICAgICBjb25zdCB7IHBhdGgsIG5hbWVzcGFjZSB9ID0gdGhpc1xuICAgICAgLy8gVE9ETzogVGhlIGRpc3RpbmN0aW9uIGJldHdlZW4gIGB1cmxgIGFuZCBgcGF0aGAgaXMgYSBiaXQgdHJpY2t5LCBzaW5jZVxuICAgICAgLy8gd2hhdCB3ZSBjYWxsIGB1cmxgIGhlcmUgaXMgY2FsbGVkIGBwYXRoYCBpbiBSb3V0ZXIsIGFuZCBtYXkgY29udGFpblxuICAgICAgLy8gbWFwcGVkIHBhcmFtZXRlcnMgb3Igd2lsZGNhcmRzLiBDb25zaWRlciBgcGF0aGAgLyBgcm91dGVgIGluc3RlYWQ/XG4gICAgICBjb25zdCB1cmwgPSBwYXRoID8gYC8ke3BhdGh9YCA6ICcnXG4gICAgICB0aGlzLnVybCA9IG5hbWVzcGFjZSA/IGAvJHtuYW1lc3BhY2V9JHt1cmx9YCA6IHVybFxuICAgICAgdGhpcy5sb2coXG4gICAgICAgIGAke1xuICAgICAgICAgIG5hbWVzcGFjZSA/IHBpY28uZ3JlZW4oYC8ke25hbWVzcGFjZX0vYCkgOiAnJ1xuICAgICAgICB9JHtcbiAgICAgICAgICBwaWNvLmN5YW4ocGF0aClcbiAgICAgICAgfSR7XG4gICAgICAgICAgcGljby53aGl0ZSgnOicpXG4gICAgICAgIH1gLFxuICAgICAgICB0aGlzLmxldmVsXG4gICAgICApXG4gICAgICBpZiAoc2V0dXBBY3Rpb25zT2JqZWN0KSB7XG4gICAgICAgIHRoaXMuYWN0aW9ucyA9IHRoaXMuYWN0aW9ucyB8fCB0aGlzLnJlZmxlY3RBY3Rpb25zT2JqZWN0KClcbiAgICAgICAgLy8gTm93IHRoYXQgdGhlIGluc3RhbmNlIGZpZWxkcyBhcmUgcmVmbGVjdGVkIGluIHRoZSBgY29udHJvbGxlcmAgb2JqZWN0XG4gICAgICAgIC8vIHdlIGNhbiB1c2UgdGhlIG5vcm1hbCBpbmhlcml0YW5jZSBtZWNoYW5pc20gdGhyb3VnaCBgc2V0dXBBY3Rpb25zKClgOlxuICAgICAgICB0aGlzLmFjdGlvbnMgPSB0aGlzLnNldHVwQWN0aW9ucygnYWN0aW9ucycpXG4gICAgICB9XG4gICAgICB0aGlzLmFzc2V0cyA9IHRoaXMuc2V0dXBBc3NldHMoKVxuICAgIH1cbiAgfVxuXG4gIHJlZmxlY3RBY3Rpb25zT2JqZWN0KCkge1xuICAgIC8vIE9uIGJhc2UgY29udHJvbGxlcnMsIHRoZSBhY3Rpb25zIGNhbiBiZSBkZWZpbmVkIGRpcmVjdGx5IGluIHRoZSBjbGFzc1xuICAgIC8vIGluc3RlYWQgb2YgaW5zaWRlIGFuIGFjdGlvbnMgb2JqZWN0LCBhcyBpcyBkb25lIHdpdGggbW9kZWwgYW5kIHJlbGF0aW9uXG4gICAgLy8gY29udHJvbGxlcnMuIEJ1dCBpbiBvcmRlciB0byB1c2UgdGhlIHNhbWUgc3RydWN0dXJlIGZvciBpbmhlcml0YW5jZSBhc1xuICAgIC8vIHRoZXNlIG90aGVyIGNvbnRyb2xsZXJzLCB3ZSByZWZsZWN0IHRoZXNlIGluc3RhbmNlIGZpZWxkcyBpbiBhIHNlcGFyYXRlXG4gICAgLy8gYGFjdGlvbnNgIG9iamVjdC5cbiAgICBjb25zdCB7IGFsbG93IH0gPSB0aGlzXG4gICAgY29uc3QgY29udHJvbGxlciA9IGFsbG93ID8geyBhbGxvdyB9IDoge31cblxuICAgIGNvbnN0IGFkZEFjdGlvbiA9IGtleSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXNba2V5XVxuICAgICAgLy8gTk9URTogT25seSBhZGQgaW5zdGFuY2UgbWV0aG9kcyB0aGF0IGhhdmUgYSBAYWN0aW9uKCkgZGVjb3JhdG9yLFxuICAgICAgLy8gd2hpY2ggaW4gdHVybiBzZXRzIHRoZSBgdmVyYmAgcHJvcGVydHkgb24gdGhlIG1ldGhvZCwgb3IgYWN0aW9uIG9iamVjdHNcbiAgICAgIC8vIHdoaWNoIGhhdmUgdGhlIGB2ZXJiYCBwcm9wZXJ0eTpcbiAgICAgIGlmICh2YWx1ZT8udmVyYikge1xuICAgICAgICBjb250cm9sbGVyW2tleV0gPSB2YWx1ZVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBVc2UgYE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKClgIHRvIGdldCB0aGUgZmllbGRzLCBpbiBvcmRlciB0b1xuICAgIC8vIG5vdCBhbHNvIHJlY2VpdmUgdmFsdWVzIGZyb20gcGFyZW50cyAodGhvc2UgYXJlIGZldGNoZWQgbGF0ZXIgaW5cbiAgICAvLyBgaW5oZXJpdFZhbHVlcygpYCwgc2VlIGBnZXRQYXJlbnRWYWx1ZXMoKWApLlxuICAgIGNvbnN0IHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpXG4gICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocHJvdG8pLmZvckVhY2goYWRkQWN0aW9uKVxuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMpLmZvckVhY2goYWRkQWN0aW9uKVxuICAgIHJldHVybiBjb250cm9sbGVyXG4gIH1cblxuICBzZXR1cFJvdXRlKHZlcmIsIHVybCwgdHJhbnNhY3RlZCwgYXV0aG9yaXplLCBhY3Rpb24sIGhhbmRsZXJzKSB7XG4gICAgdGhpcy5sb2coXG4gICAgICBgJHtcbiAgICAgICAgcGljby5tYWdlbnRhKHZlcmIudG9VcHBlckNhc2UoKSlcbiAgICAgIH0gJHtcbiAgICAgICAgcGljby5ncmVlbih0aGlzLnVybClcbiAgICAgIH0ke1xuICAgICAgICBwaWNvLmN5YW4odXJsLnNsaWNlKHRoaXMudXJsLmxlbmd0aCkpXG4gICAgICB9ICR7XG4gICAgICAgIHBpY28ud2hpdGUodGhpcy5kZXNjcmliZUF1dGhvcml6ZShhdXRob3JpemUpKVxuICAgICAgfWAsXG4gICAgICB0aGlzLmxldmVsICsgMVxuICAgIClcbiAgICB0aGlzLmFwcC5hZGRSb3V0ZSh2ZXJiLCB1cmwsIHRyYW5zYWN0ZWQsIGhhbmRsZXJzLCB0aGlzLCBhY3Rpb24pXG4gIH1cblxuICBzZXR1cEFjdGlvbnModHlwZSkge1xuICAgIGNvbnN0IHtcbiAgICAgIHZhbHVlczogYWN0aW9ucyxcbiAgICAgIGF1dGhvcml6ZVxuICAgIH0gPSB0aGlzLnByb2Nlc3NWYWx1ZXModGhpcy5pbmhlcml0VmFsdWVzKHR5cGUpKVxuICAgIGZvciAoY29uc3QgW25hbWUsIGhhbmRsZXJdIG9mIE9iamVjdC5lbnRyaWVzKGFjdGlvbnMpKSB7XG4gICAgICB0aGlzLnNldHVwQWN0aW9uKHR5cGUsIGFjdGlvbnMsIG5hbWUsIGhhbmRsZXIsIGF1dGhvcml6ZVtuYW1lXSlcbiAgICB9XG4gICAgcmV0dXJuIGFjdGlvbnNcbiAgfVxuXG4gIHNldHVwQWN0aW9uKFxuICAgIHR5cGUsXG4gICAgYWN0aW9ucyxcbiAgICBuYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgYXV0aG9yaXplLFxuICAgIC8vIFRoZXNlIHZhbHVlcyBhcmUgb25seSBjaGFuZ2VkIHdoZW4gY2FsbGVkIGZyb21cbiAgICAvLyBgQ29sbGVjdGlvbkNvbnRyb2xsZXIuc2V0dXBBY3Rpb24oKWA6XG4gICAgdmVyYiA9ICdnZXQnLFxuICAgIC8vIFRoZSBkZWZhdWx0IHBhdGggZm9yIGFjdGlvbnMgaXMgdGhlIG5vcm1hbGl6ZWQgbmFtZS5cbiAgICBwYXRoID0gdGhpcy5hcHAubm9ybWFsaXplUGF0aChuYW1lKVxuICApIHtcbiAgICBpZiAoIWlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICAgIGhhbmRsZXIgPSBzZXR1cEhhbmRsZXJGcm9tT2JqZWN0KGhhbmRsZXIsIGFjdGlvbnMpXG4gICAgfVxuICAgIC8vIEN1c3RvbSBtZW1iZXIgYWN0aW9ucyBoYXZlIHRoZWlyIG93biBjbGFzcyBzbyB0aGV5IGNhbiBmZXRjaCB0aGUgbWVtYmVyc1xuICAgIC8vIGFoZWFkIG9mIHRoZWlyIGNhbGwuXG4gICAgY29uc3QgYWN0aW9uQ2xhc3MgPSB0eXBlID09PSAnbWVtYmVyJyA/IE1lbWJlckFjdGlvbiA6IENvbnRyb2xsZXJBY3Rpb25cbiAgICB0aGlzLnNldHVwQWN0aW9uUm91dGUoXG4gICAgICB0eXBlLFxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5ldy1jYXBcbiAgICAgIG5ldyBhY3Rpb25DbGFzcyh0aGlzLCBoYW5kbGVyLCB0eXBlLCBuYW1lLCB2ZXJiLCBwYXRoLCBhdXRob3JpemUpXG4gICAgKVxuICB9XG5cbiAgc2V0dXBBY3Rpb25Sb3V0ZSh0eXBlLCBhY3Rpb24pIHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmdldFVybCh0eXBlLCBhY3Rpb24ucGF0aClcbiAgICBjb25zdCB7IHZlcmIsIHRyYW5zYWN0ZWQsIGF1dGhvcml6ZSB9ID0gYWN0aW9uXG4gICAgdGhpcy5zZXR1cFJvdXRlKHZlcmIsIHVybCwgdHJhbnNhY3RlZCwgYXV0aG9yaXplLCBhY3Rpb24sIFtcbiAgICAgIGFzeW5jIGN0eCA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgYWN0aW9uLmNhbGxBY3Rpb24oY3R4KVxuICAgICAgICAgIGlmIChyZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY3R4LmJvZHkgPSByZXNcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIHRocm93IGVyciBpbnN0YW5jZW9mIFJlc3BvbnNlRXJyb3IgPyBlcnIgOiBuZXcgV3JhcHBlZEVycm9yKGVycilcbiAgICAgICAgfVxuICAgICAgfVxuICAgIF0pXG4gIH1cblxuICBzZXR1cEFzc2V0cygpIHtcbiAgICBjb25zdCB7XG4gICAgICB2YWx1ZXM6IGFzc2V0cyxcbiAgICAgIGF1dGhvcml6ZVxuICAgIH0gPSB0aGlzLnByb2Nlc3NWYWx1ZXModGhpcy5pbmhlcml0VmFsdWVzKCdhc3NldHMnKSlcbiAgICBmb3IgKGNvbnN0IFtkYXRhUGF0aCwgY29uZmlnXSBvZiBPYmplY3QuZW50cmllcyhhc3NldHMgfHwge30pKSB7XG4gICAgICB0aGlzLnNldHVwQXNzZXRSb3V0ZShkYXRhUGF0aCwgY29uZmlnLCBhdXRob3JpemVbZGF0YVBhdGhdKVxuICAgIH1cbiAgICByZXR1cm4gYXNzZXRzXG4gIH1cblxuICBzZXR1cEFzc2V0Um91dGUoZGF0YVBhdGgsIGNvbmZpZywgYXV0aG9yaXplKSB7XG4gICAgY29uc3Qge1xuICAgICAgc3RvcmFnZTogc3RvcmFnZU5hbWUsXG4gICAgICAvLyBUT0RPOiBXaGF0IGV4YWN0bHkgc2hvdWxkIGNvbnRyb2wgdGhlIHVzZSBvZiBgdHJhbnNhY3RlZGA/XG4gICAgICB0cmFuc2FjdGVkLFxuICAgICAgLi4uc2V0dGluZ3NcbiAgICB9ID0gY29uZmlnXG4gICAgY29uc3Qgc3RvcmFnZSA9IHRoaXMuYXBwLmdldFN0b3JhZ2Uoc3RvcmFnZU5hbWUpXG4gICAgaWYgKCFzdG9yYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgQ29udHJvbGxlckVycm9yKHRoaXMsXG4gICAgICAgIGBVbmtub3duIHN0b3JhZ2UgY29uZmlndXJhdGlvbjogJyR7c3RvcmFnZU5hbWV9J2BcbiAgICAgIClcbiAgICB9XG4gICAgY29uc3QgdG9rZW5zID0gcGFyc2VEYXRhUGF0aChkYXRhUGF0aClcbiAgICBjb25zdCBnZXREYXRhUGF0aCA9IGNhbGxiYWNrID0+IG5vcm1hbGl6ZURhdGFQYXRoKHRva2Vucy5tYXAoY2FsbGJhY2spKVxuXG4gICAgLy8gUmVwbGFjZSB3aWxkY2FyZHMgd2l0aCBudW1iZXJlZCBpbmRpY2VzIGFuZCBjb252ZXJ0IHRvICcvJy1ub3RhdGlvbjpcbiAgICBsZXQgaW5kZXggPSAwXG4gICAgY29uc3QgbXVsdGlwbGVXaWxkY2FyZHMgPSB0b2tlbnMuZmlsdGVyKHRva2VuID0+IHRva2VuID09PSAnKicpLmxlbmd0aCA+IDFcbiAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IGdldERhdGFQYXRoKFxuICAgICAgdG9rZW4gPT4gdG9rZW4gPT09ICcqJ1xuICAgICAgICA/IG11bHRpcGxlV2lsZGNhcmRzXG4gICAgICAgICAgPyBgOmluZGV4JHsrK2luZGV4fWBcbiAgICAgICAgICA6ICc6aW5kZXgnXG4gICAgICAgIDogdGhpcy5hcHAubm9ybWFsaXplUGF0aCh0b2tlbilcbiAgICApXG5cbiAgICAvLyBDb252ZXJ0IGBkYXRhUGF0aGAgdG8gYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWF0Y2ggZmllbGQgbmFtZXNcbiAgICAvLyBhZ2FpbnN0LCBidXQgY29udmVydCB3aWxkY2FyZHMgKCopIHRvIG1hdGNoIGJvdGggbnVtZXJpYyBpZHMgYW5kIHdvcmRzLFxuICAgIC8vIGUuZy4gJ2NyZWF0ZSc6XG4gICAgY29uc3QgbWF0Y2hEYXRhUGF0aCA9IG5ldyBSZWdFeHAoXG4gICAgICBgXiR7Z2V0RGF0YVBhdGgodG9rZW4gPT4gdG9rZW4gPT09ICcqJyA/ICdcXFxcdysnIDogdG9rZW4pfSRgXG4gICAgKVxuXG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRVcmwoJ2NvbnRyb2xsZXInLCBgdXBsb2FkLyR7bm9ybWFsaXplZFBhdGh9YClcbiAgICBjb25zdCB1cGxvYWQgPSBzdG9yYWdlLmdldFVwbG9hZEhhbmRsZXIoe1xuICAgICAgLi4uc2V0dGluZ3MsXG4gICAgICAvLyBPbmx5IGxldCB1cGxvYWRzIHBhc3MgdGhhdCBtYXRjaCB0aGUgbm9ybWFsaXplUGF0aCArIHdpbGRjYXJkczpcbiAgICAgIGZpbGVGaWx0ZXI6IChyZXEsIGZpbGUsIGNiKSA9PiB7XG4gICAgICAgIGNiKG51bGwsIG1hdGNoRGF0YVBhdGgudGVzdChmaWxlLmZpZWxkbmFtZSkpXG4gICAgICB9XG4gICAgfSlcblxuICAgIGNvbnN0IGF1dGhvcml6YXRpb24gPSB0aGlzLnByb2Nlc3NBdXRob3JpemUoYXV0aG9yaXplKVxuICAgIHRoaXMuc2V0dXBSb3V0ZSgncG9zdCcsIHVybCwgdHJhbnNhY3RlZCwgYXV0aG9yaXplLCBudWxsLCBbXG4gICAgICBhc3luYyAoY3R4LCBuZXh0KSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQXV0aG9yaXphdGlvbihhdXRob3JpemF0aW9uLCBjdHgpXG4gICAgICAgIHJldHVybiBuZXh0KClcbiAgICAgIH0sXG5cbiAgICAgIHVwbG9hZCxcblxuICAgICAgYXN5bmMgKGN0eCwgbmV4dCkgPT4ge1xuICAgICAgICBjb25zdCBmaWxlcyA9IHN0b3JhZ2UuY29udmVydFN0b3JhZ2VGaWxlcyhjdHgucmVxdWVzdC5maWxlcylcbiAgICAgICAgYXdhaXQgdGhpcy5hcHAuY3JlYXRlQXNzZXRzKHN0b3JhZ2UsIGZpbGVzLCAwLCBjdHgudHJhbnNhY3Rpb24pXG4gICAgICAgIC8vIFNlbmQgdGhlIGZpbGUgb2JqZWN0cyBiYWNrIGZvciB0aGUgdXBsb2FkIGNvbXBvbmVudCB0byBzdG9yZSBpbiB0aGVcbiAgICAgICAgLy8gZGF0YS5cbiAgICAgICAgY3R4LmJvZHkgPSBmaWxlc1xuICAgICAgICByZXR1cm4gbmV4dCgpXG4gICAgICB9XG4gICAgXSlcbiAgfVxuXG4gIGNvbXBvc2UoKSB7XG4gICAgLy8gVG8gYmUgb3ZlcnJpZGRlbiBpbiBzdWItY2xhc3NlcywgaWYgdGhlIGNvbnRyb2xsZXIgbmVlZHMgdG8gaW5zdGFsbFxuICAgIC8vIG1pZGRsZXdhcmUuIEZvciBub3JtYWwgcm91dGVzLCB1c2UgYHRoaXMuYXBwLmFkZFJvdXRlKClgIGluc3RlYWQuXG4gIH1cblxuICBnZXRQYXRoKHR5cGUsIHBhdGgpIHtcbiAgICAvLyBUbyBiZSBvdmVycmlkZGVuIGJ5IHN1Yi1jbGFzc2VzLlxuICAgIHJldHVybiBwYXRoXG4gIH1cblxuICBnZXRVcmwodHlwZSwgcGF0aCkge1xuICAgIHBhdGggPSB0aGlzLmdldFBhdGgodHlwZSwgcGF0aClcbiAgICAvLyBVc2UgJy4nIGFzIHRoZSBwYXRoIGZvciB0aGUgY29udHJvbGxlcidzIFwiaW5kZXhcIiBhY3Rpb24uXG4gICAgcmV0dXJuIHBhdGggJiYgcGF0aCAhPT0gJy4nID8gYCR7dGhpcy51cmx9LyR7cGF0aH1gIDogdGhpcy51cmxcbiAgfVxuXG4gIGluaGVyaXRWYWx1ZXModHlwZSkge1xuICAgIC8vIEdldHMgdGhlIGNvbnRyb2xsZXIgY2xhc3MncyBpbnN0YW5jZSBmaWVsZCBmb3IgYSBnaXZlbiBhY3Rpb24gdHlwZSwgZS5nLlxuICAgIC8vIGBjb250cm9sbGVyYCAoQ29udHJvbGxlciksIGBjb2xsZWN0aW9uYCwgYG1lbWJlcmAgKE1vZGVsQ29udHJvbGxlcixcbiAgICAvLyBSZWxhdGlvbkNvbnRyb2xsZXIpLCBgcmVsYXRpb25gIChSZWxhdGlvbkNvbnRyb2xsZXIpLCBhbmQgc2V0cyB1cCBhblxuICAgIC8vIGluaGVyaXRhbmNlIGNoYWluIGZvciBpdCB0aGF0IGdvZXMgYWxsIHRoZSB3YXkgdXAgdG8gaXQgYmFzZSBjbGFzcyAoZS5nLlxuICAgIC8vIENvbGxlY3Rpb25Db250cm9sbGVyKSwgc28gdGhhdCB0aGUgZGVmYXVsdCBkZWZpbml0aW9ucyBmb3IgYWxsIGh0dHAgdmVyYnNcbiAgICAvLyBjYW4gYmUgY29ycmVjdGx5IGluaGVyaXRlZCBhbmQgb3ZlcnJpZGRlbiB3aGlsZSB1c2luZyBgc3VwZXIuPGFjdGlvbj4oKWAuXG4gICAgY29uc3QgcGFyZW50Q2xhc3MgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcy5jb25zdHJ1Y3RvcilcbiAgICAvLyBDcmVhdGUgb25lIGluc3RhbmNlIG9mIGVhY2ggY29udHJvbGxlciBjbGFzcyB1cCB0aGUgY2hhaW4gaW4gb3JkZXIgdG9cbiAgICAvLyBnZXQgdG8gdGhlaXIgZGVmaW5pdGlvbnMgb2YgdGhlIGluaGVyaXRhYmxlIHZhbHVlcy4gQ2FjaGUgYm90aCBpbnN0YW5jZVxuICAgIC8vIGFuZCByZXNvbHZlZCB2YWx1ZXMgcGVyIHBhcmVudENsYXNzIGluIGFuIGluaGVyaXRhbmNlTWFwLlxuICAgIGlmICghaW5oZXJpdGFuY2VNYXAuaGFzKHBhcmVudENsYXNzKSkge1xuICAgICAgaW5oZXJpdGFuY2VNYXAuc2V0KHBhcmVudENsYXNzLCB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuZXctY2FwXG4gICAgICAgIGluc3RhbmNlOiBuZXcgcGFyZW50Q2xhc3ModGhpcy5hcHAsIHRoaXMubmFtZXNwYWNlKVxuICAgICAgfSlcbiAgICB9XG4gICAgY29uc3QgZW50cnkgPSBpbmhlcml0YW5jZU1hcC5nZXQocGFyZW50Q2xhc3MpXG4gICAgaWYgKCFlbnRyeVt0eXBlXSkge1xuICAgICAgY29uc3QgcGFyZW50ID0gZW50cnkuaW5zdGFuY2VcbiAgICAgIGxldCB2YWx1ZXMgPSBwYXJlbnRbdHlwZV1cbiAgICAgIGlmIChwYXJlbnRDbGFzcyAhPT0gQ29udHJvbGxlcikge1xuICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXQgdXAgaW5oZXJpdGFuY2UgY2hhaW5zLlxuICAgICAgICB2YWx1ZXMgPSBwYXJlbnQuaW5oZXJpdFZhbHVlcyh0eXBlKVxuICAgICAgfVxuICAgICAgZW50cnlbdHlwZV0gPSB2YWx1ZXNcbiAgICB9XG4gICAgLy8gSWYgdGhlcmUgYXJlIG5vIHZhbHVlcyBkZWZpbmVkIG9uIGB0aGlzYCB0aGF0IGRpZmZlciBmcm9tIHRoZSBwYXJlbnQsXG4gICAgLy8gc2V0IHRvIGFuIGVtcHR5IG9iamVjdCBzbyBpbmhlcml0YW5jZSBjYW4gYmUgc2V0IHVwIGFuZCBgcHJvY2Vzc1ZhbHVlcygpYFxuICAgIC8vIGNhbiBzdGlsbCBiZSBjYWxsZWQuXG4gICAgLy8gTk9URTogV2UgY2FuJ3QgY2hlY2sgd2l0aCBgdGhpcy5oYXNPd25Qcm9wZXJ0eSh0eXBlKWAgYmVjYXVzZSB0aGVcbiAgICAvLyBmaWVsZCBjYW4gYmUgb24gdGhlIGNsYXNzIHByb3RvdHlwZSBhcyB3ZWxsLCBpbiBjYXNlIG9mIGFjY2Vzc29ycy5cbiAgICBjb25zdCBwYXJlbnRWYWx1ZXMgPSBlbnRyeVt0eXBlXVxuICAgIGxldCBjdXJyZW50VmFsdWVzID0gdGhpc1t0eXBlXVxuICAgIGlmIChjdXJyZW50VmFsdWVzICYmIGN1cnJlbnRWYWx1ZXMgPT09IHBhcmVudFZhbHVlcykge1xuICAgICAgY3VycmVudFZhbHVlcyA9IHRoaXNbdHlwZV0gPSB7fVxuICAgIH1cbiAgICAvLyBDb21iaW5lIHBhcmVudFZhbHVlcyBhbmQgY3VycmVudFZhbHVlcyB3aXRoIGNvcnJlY3QgaW5oZXJpdGFuY2UuXG4gICAgcmV0dXJuIGlzT2JqZWN0KHBhcmVudFZhbHVlcykgJiYgaXNPYmplY3QoY3VycmVudFZhbHVlcylcbiAgICAgID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKGN1cnJlbnRWYWx1ZXMsIHBhcmVudFZhbHVlcylcbiAgICAgIDogY3VycmVudFZhbHVlc1xuICB9XG5cbiAgcHJvY2Vzc1ZhbHVlcyh2YWx1ZXMpIHtcbiAgICBpZiAoIXZhbHVlcykgcmV0dXJuIHt9XG4gICAgLy8gUmVzcGVjdCBgYWxsb3dgIHNldHRpbmdzIGFuZCBjbGVhciBlbnRyaWVzIHRoYXQgYXJlbid0IGFsbG93ZWQuXG4gICAgLy8gQWxzbyBjb2xsZWN0IGFuZCBleHBhbmQgYGF1dGhvcml6ZWAgc2V0dGluZ3Mgc28gdGhhdCBpbiB0aGUgZW5kLCBhblxuICAgIC8vIGBhdXRob3JpemVgIG9iamVjdCBjYW4gYmUgcmV0dXJuZWQgd2l0aCB2YWxpZCBzZXR0aW5ncyBmb3IgYWxsIHZhbHVlcy5cbiAgICAvL1xuICAgIC8vIFJ1bGVzOlxuICAgIC8vIC0gT3duIHZhbHVlcyBvbiBvYmplY3RzIHRoYXQgZG9uJ3QgZGVmaW5lIGFuIGBhbGxvd2AgYXJyYXkgYXJlXG4gICAgLy8gICBhdXRvbWF0aWNhbGx5IGFsbG93ZWQuIElmIGFuIGBhbGxvd2AgYXJyYXkgaXMgZGVmaW5lZCBhcyB3ZWxsLCB0aGVuXG4gICAgLy8gICB0aGVzZSBvd24gdmFsdWVzIG5lZWQgdG8gYmUgZXhwbGljaXRseSBsaXN0ZWQuXG4gICAgLy8gLSBJZiBubyBgYWxsb3dgIGFycmF5cyBhcmUgZGVmaW5lZCBpbiB0aGUgcHJvdG90eXBhbCBoaWVyYXJjaHksIGVhY2hcbiAgICAvLyAgIGxldmVsIGFsbG93cyBpdHMgb3duIHZhbHVlcywgYW5kIHRoZXNlIGFyZSBtZXJnZWQsIGV4Y2VwdCBmb3IgdGhvc2VcbiAgICAvLyAgIG1hcmtlZCBhcyBgJGNvcmVgLCB3aGljaCBuZWVkIHRvIGJlIGV4cGxpY2l0bHkgbGlzdGVkIGluIGBhbGxvd2AuXG5cbiAgICAvLyBOT1RFOiBgaGFuZGxlQWxsb3coKWAgYW5kIGBoYW5kbGVBdXRob3JpemUoKWAgYXJlIGFwcGxpZWQgaW4gc2VxdWVuY2Ugb2ZcbiAgICAvLyB0aGUgYHZhbHVlc2AgaW5oZXJpdGFuY2UsIGZyb20gc3ViLWNsYXNzIHRvIGJhc2UtY2xhc3MuXG5cbiAgICBjb25zdCBtZXJnZWRBbGxvdyA9IHt9XG4gICAgY29uc3QgbWVyZ2VkQXV0aG9yaXplID0ge31cbiAgICBsZXQgaGFzT3duQWxsb3cgPSBmYWxzZVxuXG4gICAgY29uc3QgZXhjbHVkZUtleSA9IGtleSA9PiBbJ2FsbG93JywgJ2F1dGhvcml6ZSddLmluY2x1ZGVzKGtleSlcblxuICAgIGNvbnN0IGhhbmRsZUFsbG93ID0gKGFsbG93LCBjdXJyZW50KSA9PiB7XG4gICAgICBpZiAoYWxsb3cpIHtcbiAgICAgICAgYWxsb3cgPSBhc0FycmF5KGFsbG93KVxuICAgICAgICBoYXNPd25BbGxvdyA9IHRydWVcbiAgICAgIH0gZWxzZSBpZiAoIWhhc093bkFsbG93KSB7XG4gICAgICAgIC8vIE9ubHkga2VlcCBhZGRpbmcgdG8gdGhlIG1lcmdlZCBgYWxsb3dgIGlmIHdlIGRpZG4ndCBhbHJlYWR5IGVuY291bnRlclxuICAgICAgICAvLyBhbiBvd24gYGFsbG93YCBvYmplY3QgZnVydGhlciB1cCB0aGUgY2hhaW4uXG4gICAgICAgIGFsbG93ID0gT2JqZWN0LmtleXMoY3VycmVudClcbiAgICAgIH1cbiAgICAgIGlmIChhbGxvdykge1xuICAgICAgICBpZiAoYWxsb3cuaW5jbHVkZXMoJyonKSkge1xuICAgICAgICAgIGFsbG93ID0gZ2V0QWxsS2V5cyhjdXJyZW50KVxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGFsbG93KSB7XG4gICAgICAgICAgaWYgKCFleGNsdWRlS2V5KGtleSkpIHtcbiAgICAgICAgICAgIG1lcmdlZEFsbG93W2tleV0gPSB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaGFuZGxlQXV0aG9yaXplID0gYXV0aG9yaXplID0+IHtcbiAgICAgIGNvbnN0IGFkZCA9IChrZXksIHZhbHVlKSA9PiB7XG4gICAgICAgIC8vIFNpbmNlIHdlJ3JlIHdhbGtpbmcgdXAgaW4gdGhlIGluaGVyaXRhbmNlIGNoYWluLCBvbmx5IHRha2Ugb24gYW5cbiAgICAgICAgLy8gYXV0aG9yaXplIHNldHRpbmcgZm9yIGEgZ2l2ZW4ga2V5IGlmIGl0IHdhc24ndCBhbHJlYWR5IGRlZmluZWQgYmVmb3JlXG4gICAgICAgIGlmIChcbiAgICAgICAgICBrZXkgaW4gdmFsdWVzICYmXG4gICAgICAgICAgIShrZXkgaW4gbWVyZ2VkQXV0aG9yaXplKSAmJlxuICAgICAgICAgICFleGNsdWRlS2V5KGtleSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgbWVyZ2VkQXV0aG9yaXplW2tleV0gPSB2YWx1ZVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChpc09iamVjdChhdXRob3JpemUpKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGF1dGhvcml6ZSkge1xuICAgICAgICAgIGFkZChrZXksIGF1dGhvcml6ZVtrZXldKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGF1dGhvcml6ZSAhPSBudWxsKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgYSB2YWx1ZXMtd2lkZSBzZXR0aW5nLiBMb29wIHRocm91Z2ggYWxsIHZhbHVlcywgbm90IGp1c3RcbiAgICAgICAgLy8gY3VycmVudCBvbmVzLCBhbmQgYXBwbHkgdG8gYW55IGFjdGlvbiB0aGF0IGRvZXNuJ3QgYWxyZWFkeSBoYXZlIG9uZTpcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdmFsdWVzKSB7XG4gICAgICAgICAgYWRkKGtleSwgYXV0aG9yaXplKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUHJvY2VzcyB0aGUgYGFsbG93YCBhbmQgYGF1dGhvcml6ZWAgc2V0dGluZ3MgaW4gc2VxdWVuY2Ugb2YgdGhlIGB2YWx1ZXNgXG4gICAgLy8gaW5oZXJpdGFuY2UsIGZyb20gc3ViLWNsYXNzIHRvIGJhc2UtY2xhc3MuXG4gICAgbGV0IGN1cnJlbnQgPSB2YWx1ZXNcbiAgICB3aGlsZSAoY3VycmVudCAhPT0gT2JqZWN0LnByb3RvdHlwZSAmJiAhY3VycmVudC5oYXNPd25Qcm9wZXJ0eSgnJGNvcmUnKSkge1xuICAgICAgaGFuZGxlQWxsb3coZ2V0T3duUHJvcGVydHkoY3VycmVudCwgJ2FsbG93JyksIGN1cnJlbnQpXG4gICAgICBoYW5kbGVBdXRob3JpemUoZ2V0T3duUHJvcGVydHkoY3VycmVudCwgJ2F1dGhvcml6ZScpKVxuICAgICAgY3VycmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihjdXJyZW50KVxuICAgIH1cblxuICAgIC8vIEF0IHRoZSBlbmQgb2YgdGhlIGNoYWluLCBhbHNvIHN1cHBvcnQgYm90aCBzZXR0aW5ncyBvbiB0aGUgY29udHJvbGxlci1cbiAgICAvLyBsZXZlbCwgYW5kIHRodXMgYXBwbGllZCB0byBhbGwgYWN0aW9uIG9iamVjdHMgaW4gdGhlIGNvbnRyb2xsZXIuXG4gICAgaWYgKHRoaXMuYWxsb3cpIHtcbiAgICAgIGhhbmRsZUFsbG93KHRoaXMuYWxsb3csIHZhbHVlcylcbiAgICB9XG4gICAgaWYgKHRoaXMuYXV0aG9yaXplKSB7XG4gICAgICBoYW5kbGVBdXRob3JpemUodGhpcy5hdXRob3JpemUpXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIENyZWF0ZSBhIGZpbHRlcmVkIGB2YWx1ZXNgIG9iamVjdCB0aGF0IG9ubHkgY29udGFpbnMgdGhlIGFsbG93ZWQgZmllbGRzXG4gICAgICB2YWx1ZXM6IGdldEFsbEtleXModmFsdWVzKS5yZWR1Y2UoXG4gICAgICAgIChyZXN1bHQsIGtleSkgPT4ge1xuICAgICAgICAgIGlmIChtZXJnZWRBbGxvd1trZXldKSB7XG4gICAgICAgICAgICByZXN1bHRba2V5XSA9IHZhbHVlc1trZXldXG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgICAgfSxcbiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IG9iamVjdCBmb3IgdGhlIGZpbHRlcmVkIGB2YWx1ZXNgIHRoYXQga2VlcHMgaW5oZXJpdGFuY2VcbiAgICAgICAgLy8gaW50YWN0LiBUaGlzIGlzIHJlcXVpcmVkIGJ5IGBzZXR1cEhhbmRsZXJGcm9tT2JqZWN0KClgLCB0byBzdXBwb3J0XG4gICAgICAgIC8vIGBzdXBlcmAgaW4gaGFuZGxlciBmdW5jdGlvbnMuXG4gICAgICAgIE9iamVjdC5jcmVhdGUoT2JqZWN0LmdldFByb3RvdHlwZU9mKHZhbHVlcykpXG4gICAgICApLFxuICAgICAgYWxsb3c6IE9iamVjdC5rZXlzKG1lcmdlZEFsbG93KSxcbiAgICAgIGF1dGhvcml6ZTogbWVyZ2VkQXV0aG9yaXplXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZW1pdEhvb2sodHlwZSwgaGFuZGxlUmVzdWx0LCBjdHgsIC4uLmFyZ3MpIHtcbiAgICBsZXQgcmVzdWx0ID0gaGFuZGxlUmVzdWx0ID8gYXJncy5zaGlmdCgpIDogdW5kZWZpbmVkXG4gICAgZm9yIChjb25zdCBoYW5kbGVyIG9mIHRoaXMubGlzdGVuZXJzKHR5cGUpKSB7XG4gICAgICBpZiAoaGFuZGxlUmVzdWx0KSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGhhbmRsZXIuY2FsbCh0aGlzLCBjdHgsIHJlc3VsdCwgLi4uYXJncylcbiAgICAgICAgaWYgKHJlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmVzdWx0ID0gcmVzXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IGhhbmRsZXIuY2FsbCh0aGlzLCBjdHgsIC4uLmFyZ3MpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRcbiAgfVxuXG4gIGFzeW5jIGdldE1lbWJlcigvKiBjdHgsIGJhc2UgPSB0aGlzLCBwYXJhbSA9IHsgLi4uIH0gKi8pIHtcbiAgICAvLyBUaGlzIGlzIG9ubHkgZGVmaW5lZCBpbiBgQ29sbGVjdGlvbkNvbnRyb2xsZXJgLCB3aGVyZSBpdCByZXNvbHZlcyB0byB0aGVcbiAgICAvLyBtZW1iZXIgcmVwcmVzZW50ZWQgYnkgdGhlIGdpdmVuIHJvdXRlLlxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIGF1dGhvcml6ZSBjb25maWcgc2V0dGluZ3MgaW50byBhbiBhdXRob3JpemF0aW9uIGZ1bmN0aW9uIHRoYXRcbiAgICogY2FuIGJlIHBhc3NlZCB0byBgaGFuZGxlQXV0aG9yaXphdGlvbigpYC5cbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFufGZ1bmN0aW9ufHN0cmluZ3xzdHJpbmdbXX0gYXV0aG9yaXplIHRoZSBhdXRob3JpemUgY29uZmlnXG4gICAqIHNldHRpbmdzXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9ufSB0aGUgYXV0aG9yaXphdGlvbiBmdW5jdGlvblxuICAgKi9cbiAgcHJvY2Vzc0F1dGhvcml6ZShhdXRob3JpemUpIHtcbiAgICBpZiAoYXV0aG9yaXplID09IG51bGwpIHtcbiAgICAgIHJldHVybiAoKSA9PiB0cnVlXG4gICAgfSBlbHNlIGlmIChpc0Jvb2xlYW4oYXV0aG9yaXplKSkge1xuICAgICAgcmV0dXJuICgpID0+IGF1dGhvcml6ZVxuICAgIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihhdXRob3JpemUpKSB7XG4gICAgICByZXR1cm4gYXN5bmMgKGN0eCwgbWVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGF1dGhvcml6ZShjdHgsIG1lbWJlcilcbiAgICAgICAgLy8gUGFzcyByZXMgdGhyb3VnaCBgcHJvY2Vzc0F1dGhvcml6ZSgpYCB0byBzdXBwb3J0IHN0cmluZ3MgJiBhcnJheXMuXG4gICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NBdXRob3JpemUocmVzKShjdHgsIG1lbWJlcilcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzU3RyaW5nKGF1dGhvcml6ZSkgfHwgaXNBcnJheShhdXRob3JpemUpKSB7XG4gICAgICByZXR1cm4gYXN5bmMgKGN0eCwgbWVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgdXNlciB9ID0gY3R4LnN0YXRlXG4gICAgICAgIGlmICghdXNlcikge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IGFzQXJyYXkoYXV0aG9yaXplKVxuICAgICAgICAvLyBGb3IgJyRvd25lcicsIGZldGNoIGBtZW1iZXJgIG5vdyBpbiBjYXNlIHRoZSBhY3Rpb24gcGFyYW1ldGVyc1xuICAgICAgICAvLyBkaWRuJ3QgYWxyZWFkeSByZXF1ZXN0IGl0OlxuICAgICAgICBpZiAoIW1lbWJlciAmJiB2YWx1ZXMuaW5jbHVkZXMoJyRvd25lcicpKSB7XG4gICAgICAgICAgbWVtYmVyID0gYXdhaXQgdGhpcy5nZXRNZW1iZXIoY3R4KVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXZhbHVlcy5maW5kKFxuICAgICAgICAvLyBTdXBwb3J0IDMgc2NlbmFyaW9zOlxuICAgICAgICAvLyAtICckc2VsZic6IFRoZSByZXF1ZXN0ZWQgbWVtYmVyIGlzIGNoZWNrZWQgYWdhaW5zdCBgY3R4LnN0YXRlLnVzZXJgXG4gICAgICAgIC8vICAgYW5kIHRoZSBhY3Rpb24gaXMgb25seSBhdXRob3JpemVkIGlmIGl0IG1hdGNoZXMgdGhlIG1lbWJlci5cbiAgICAgICAgLy8gLSAnJG93bmVyJzogVGhlIG1lbWJlciBpcyBhc2tlZCBpZiBpdCBpcyBvd25lZCBieSBgY3R4LnN0YXRlLnVzZXJgXG4gICAgICAgIC8vICAgdGhyb3VnaCB0aGUgb3B0aW9uYWwgYE1vZGVsLiRoYXNPd25lcigpYCBtZXRob2QuXG4gICAgICAgIC8vIC0gYW55IHN0cmluZzogIGBjdHguc3RhdGUudXNlcmAgaXMgY2hlY2tlZCBmb3IgdGhpcyByb2xlIHRocm91Z2hcbiAgICAgICAgLy8gICB0aGUgb3ZlcnJpZGFibGUgYFVzZXJNb2RlbC5oYXNSb2xlKClgIG1ldGhvZC5cbiAgICAgICAgICB2YWx1ZSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgPT09ICckc2VsZidcbiAgICAgICAgICAgICAgPyB1c2VyLmNvbnN0cnVjdG9yID09PSB0aGlzLm1vZGVsQ2xhc3MgJiZcbiAgICAgICAgICAgICAgZXF1YWxzKHVzZXIuJGlkKCksIGN0eC5tZW1iZXJJZClcbiAgICAgICAgICAgICAgOiB2YWx1ZSA9PT0gJyRvd25lcidcbiAgICAgICAgICAgICAgICA/IG1lbWJlcj8uJGhhc093bmVyPy4odXNlcilcbiAgICAgICAgICAgICAgICA6IHVzZXIuJGhhc1JvbGUodmFsdWUpXG4gICAgICAgICAgfVxuICAgICAgICApXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBDb250cm9sbGVyRXJyb3IodGhpcyxcbiAgICAgICAgYFVuc3VwcG9ydGVkIGF1dGhvcml6ZSBzZXR0aW5nOiAnJHthdXRob3JpemV9J2BcbiAgICAgIClcbiAgICB9XG4gIH1cblxuICBkZXNjcmliZUF1dGhvcml6ZShhdXRob3JpemUpIHtcbiAgICByZXR1cm4gaXNGdW5jdGlvbihhdXRob3JpemUpXG4gICAgICA/IGRlc2NyaWJlRnVuY3Rpb24oYXV0aG9yaXplKVxuICAgICAgOiBpc1N0cmluZyhhdXRob3JpemUpXG4gICAgICAgID8gYCcke2F1dGhvcml6ZX0nYFxuICAgICAgICA6IGlzQXJyYXkoYXV0aG9yaXplKVxuICAgICAgICAgID8gYFske2F1dGhvcml6ZS5tYXAodmFsdWUgPT4gYCcke3ZhbHVlfSdgKS5qb2luKCcsICcpfV1gXG4gICAgICAgICAgOiAnJ1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlQXV0aG9yaXphdGlvbihhdXRob3JpemF0aW9uLCBjdHgsIG1lbWJlcikge1xuICAgIGNvbnN0IG9rID0gYXdhaXQgYXV0aG9yaXphdGlvbihjdHgsIG1lbWJlcilcbiAgICBpZiAob2sgIT09IHRydWUpIHtcbiAgICAgIHRocm93IG5ldyBBdXRob3JpemF0aW9uRXJyb3IoKVxuICAgIH1cbiAgfVxuXG4gIGxvZyhzdHIsIGluZGVudCA9IDApIHtcbiAgICBpZiAodGhpcy5sb2dnaW5nKSB7XG4gICAgICBjb25zb2xlLmluZm8oYCR7JyAgJy5yZXBlYXQoaW5kZW50KX0ke3N0cn1gKVxuICAgIH1cbiAgfVxufVxuXG5FdmVudEVtaXR0ZXIubWl4aW4oQ29udHJvbGxlci5wcm90b3R5cGUpXG5cbmNvbnN0IGluaGVyaXRhbmNlTWFwID0gbmV3IFdlYWtNYXAoKVxuXG5mdW5jdGlvbiBzZXR1cEhhbmRsZXJGcm9tT2JqZWN0KG9iamVjdCwgYWN0aW9ucykge1xuICBjb25zdCB7XG4gICAgaGFuZGxlcixcbiAgICBhY3Rpb24sXG4gICAgYXV0aG9yaXplLFxuICAgIHBhcmFtZXRlcnMsXG4gICAgcmV0dXJucyxcbiAgICBzY29wZSxcbiAgICB0cmFuc2FjdGVkXG4gIH0gPSBvYmplY3RcblxuICAvLyBJbiBvcmRlciB0byBzdXBvcnQgYHN1cGVyYCBjYWxscyBpbiB0aGUgYGhhbmRsZXJgIGZ1bmN0aW9uIGluIG9iamVjdFxuICAvLyBub3RhdGlvbiwgZGVwbG95IHRoaXMgY3JhenkgSlMgc29yY2VyeTpcbiAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG9iamVjdCwgT2JqZWN0LmdldFByb3RvdHlwZU9mKGFjdGlvbnMpKVxuXG4gIGhhbmRsZXIuYXV0aG9yaXplID0gYXV0aG9yaXplXG4gIGhhbmRsZXIudHJhbnNhY3RlZCA9IHRyYW5zYWN0ZWRcblxuICBpZiAoYWN0aW9uKSB7XG4gICAgY29uc3QgW3ZlcmIsIHBhdGhdID0gYXNBcnJheShhY3Rpb24pXG4gICAgaGFuZGxlci52ZXJiID0gdmVyYlxuICAgIGhhbmRsZXIucGF0aCA9IHBhdGhcbiAgfVxuXG4gIGlmIChwYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgW19wYXJhbWV0ZXJzLCBvcHRpb25zXSA9IHBhcmFtZXRlcnNcbiAgICBjb25zdCBoYXNPcHRpb25zID0gaXNBcnJheShfcGFyYW1ldGVycylcbiAgICBoYW5kbGVyLnBhcmFtZXRlcnMgPSBoYXNPcHRpb25zID8gX3BhcmFtZXRlcnMgOiBwYXJhbWV0ZXJzXG5cbiAgICAvLyBJZiB2YWxpZGF0aW9uIG9wdGlvbnMgYXJlIHByb3ZpZGVkLCBleHBvc2UgdGhlbSB0aHJvdWdoXG4gICAgLy8gYGhhbmRsZXIub3B0aW9ucy5wYXJhbWV0ZXJzYCwgc2VlIENvbnRyb2xsZXJBY3Rpb25cbiAgICBpZiAoaGFzT3B0aW9ucykge1xuICAgICAgaGFuZGxlci5vcHRpb25zID0ge1xuICAgICAgICAuLi5oYW5kbGVyLm9wdGlvbnMsXG4gICAgICAgIHBhcmFtZXRlcnM6IG9wdGlvbnNcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAocmV0dXJucykge1xuICAgIGNvbnN0IFtfcmV0dXJucywgb3B0aW9uc10gPSBhc0FycmF5KHJldHVybnMpXG4gICAgaGFuZGxlci5yZXR1cm5zID0gX3JldHVybnNcblxuICAgIC8vIElmIHZhbGlkYXRpb24gb3B0aW9ucyBhcmUgcHJvdmlkZWQsIGV4cG9zZSB0aGVtIHRocm91Z2hcbiAgICAvLyBgaGFuZGxlci5vcHRpb25zLnJldHVybnNgLCBzZWUgQ29udHJvbGxlckFjdGlvblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBoYW5kbGVyLm9wdGlvbnMgPSB7XG4gICAgICAgIC4uLmhhbmRsZXIub3B0aW9ucyxcbiAgICAgICAgcGFyYW1ldGVyczogb3B0aW9uc1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChzY29wZSkge1xuICAgIGhhbmRsZXIuc2NvcGUgPSBhc0FycmF5KHNjb3BlKVxuICB9XG5cbiAgcmV0dXJuIGhhbmRsZXJcbn1cbiJdfQ==
|