@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
package/lib/models/Model.js
DELETED
|
@@ -1,953 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.Model = 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.reduce.js");
|
|
13
|
-
|
|
14
|
-
require("core-js/modules/esnext.iterator.reduce.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.weak-map.delete-all.js");
|
|
21
|
-
|
|
22
|
-
require("core-js/modules/esnext.weak-map.emplace.js");
|
|
23
|
-
|
|
24
|
-
var _objection = _interopRequireDefault(require("objection"));
|
|
25
|
-
|
|
26
|
-
var _query = require("../query");
|
|
27
|
-
|
|
28
|
-
var _lib = require("../lib");
|
|
29
|
-
|
|
30
|
-
var _schema = require("../schema");
|
|
31
|
-
|
|
32
|
-
var _graph = require("../graph");
|
|
33
|
-
|
|
34
|
-
var _utils = require("../utils");
|
|
35
|
-
|
|
36
|
-
var _errors = require("../errors");
|
|
37
|
-
|
|
38
|
-
var _utils2 = require("@ditojs/utils");
|
|
39
|
-
|
|
40
|
-
var _RelationAccessor = _interopRequireDefault(require("./RelationAccessor"));
|
|
41
|
-
|
|
42
|
-
var _definitions = _interopRequireDefault(require("./definitions"));
|
|
43
|
-
|
|
44
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
45
|
-
|
|
46
|
-
class Model extends _objection.default.Model {
|
|
47
|
-
constructor(json) {
|
|
48
|
-
super();
|
|
49
|
-
|
|
50
|
-
if (json) {
|
|
51
|
-
this.$setJson(json);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
static setup(knex) {
|
|
56
|
-
this.knex(knex);
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
for (const relation of Object.values(this.getRelations())) {
|
|
60
|
-
this.setupRelation(relation);
|
|
61
|
-
}
|
|
62
|
-
} catch (error) {
|
|
63
|
-
throw error instanceof _errors.RelationError ? error : new _errors.RelationError(error);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
this.referenceValidator = null;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
static setupRelation(relation) {
|
|
70
|
-
relation.relatedModelClass.getRelatedRelations().push(relation);
|
|
71
|
-
const accessor = `$${relation.name}`;
|
|
72
|
-
|
|
73
|
-
if (accessor in this.prototype) {
|
|
74
|
-
throw new _errors.RelationError(`Model '${this.name}' already defines a property with name ` + `'${accessor}' that clashes with the relation accessor.`);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const defineAccessor = (target, isClass) => {
|
|
78
|
-
Object.defineProperty(target, accessor, {
|
|
79
|
-
get() {
|
|
80
|
-
const value = new _RelationAccessor.default(relation, isClass ? this : null, isClass ? null : this);
|
|
81
|
-
Object.defineProperty(this, accessor, {
|
|
82
|
-
value,
|
|
83
|
-
configurable: true,
|
|
84
|
-
enumerable: false
|
|
85
|
-
});
|
|
86
|
-
return value;
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
configurable: true,
|
|
90
|
-
enumerable: false
|
|
91
|
-
});
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
defineAccessor(this, true);
|
|
95
|
-
defineAccessor(this.prototype, false);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
static initialize() {
|
|
99
|
-
const {
|
|
100
|
-
hooks,
|
|
101
|
-
assets
|
|
102
|
-
} = this.definition;
|
|
103
|
-
|
|
104
|
-
this._setupEmitter(hooks);
|
|
105
|
-
|
|
106
|
-
if (assets) {
|
|
107
|
-
this._setupAssetsEvents(assets);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
$initialize() {}
|
|
112
|
-
|
|
113
|
-
get $app() {
|
|
114
|
-
return this.constructor.app;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
$is(model) {
|
|
118
|
-
return (model == null ? void 0 : model.constructor) === this.constructor && (model == null ? void 0 : model.id) === this.id;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
$has(...properties) {
|
|
122
|
-
for (const property of properties) {
|
|
123
|
-
if (!(property in this)) return false;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
$update(properties, trx) {
|
|
130
|
-
return this.$query(trx).update(properties).runAfter((result, query) => query.has('update') ? this.$set(result) : result);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
$patch(properties, trx) {
|
|
134
|
-
return this.$query(trx).patch(properties).runAfter((result, query) => query.has('patch') ? this.$set(result) : result);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
$transaction(trx, handler) {
|
|
138
|
-
return this.constructor.transaction(trx, handler);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
static transaction(trx, handler) {
|
|
142
|
-
if (!handler) {
|
|
143
|
-
handler = trx;
|
|
144
|
-
trx = null;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (handler) {
|
|
148
|
-
return trx ? handler(trx) : this.knex().transaction(handler);
|
|
149
|
-
} else {
|
|
150
|
-
return super.transaction();
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
$validate(json, options = {}) {
|
|
155
|
-
if (options.skipValidation) {
|
|
156
|
-
return json;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (!options.graph && !options.async) {
|
|
160
|
-
return super.$validate(json, options);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
json = json || this;
|
|
164
|
-
const inputJson = json;
|
|
165
|
-
const shallow = json.$isObjectionModel && !options.graph;
|
|
166
|
-
|
|
167
|
-
if (shallow) {
|
|
168
|
-
json = json.clone({
|
|
169
|
-
shallow: true
|
|
170
|
-
});
|
|
171
|
-
options = { ...options,
|
|
172
|
-
mutable: true
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const validator = this.constructor.getValidator();
|
|
177
|
-
const args = {
|
|
178
|
-
options,
|
|
179
|
-
model: this,
|
|
180
|
-
json,
|
|
181
|
-
ctx: Object.create(null)
|
|
182
|
-
};
|
|
183
|
-
validator.beforeValidate(args);
|
|
184
|
-
const result = validator.validate(args);
|
|
185
|
-
|
|
186
|
-
const handleResult = result => {
|
|
187
|
-
validator.afterValidate(args);
|
|
188
|
-
return shallow ? inputJson.$set(result) : result;
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
return (0, _utils2.isPromise)(result) ? result.then(handleResult) : handleResult(result);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
async $validateGraph(options = {}) {
|
|
195
|
-
await this.$validate(null, { ...options,
|
|
196
|
-
graph: true,
|
|
197
|
-
async: true
|
|
198
|
-
});
|
|
199
|
-
return this;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
static fromJson(json, options = {}) {
|
|
203
|
-
if (options.async && !options.skipValidation) {
|
|
204
|
-
const model = new this();
|
|
205
|
-
return model.$validate(json, options).then(json => model.$setJson(json, { ...options,
|
|
206
|
-
skipValidation: true
|
|
207
|
-
}));
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return super.fromJson(json, options);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
static query(trx) {
|
|
214
|
-
return super.query(trx).onError(err => {
|
|
215
|
-
err = err instanceof _errors.ResponseError ? err : err instanceof _objection.default.DBError ? this.app.createDatabaseError(err) : new _errors.WrappedError(err);
|
|
216
|
-
return Promise.reject(err);
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
static async count(...args) {
|
|
221
|
-
const {
|
|
222
|
-
count
|
|
223
|
-
} = (await this.query().count(...args).first()) || {};
|
|
224
|
-
return +count || 0;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
static get tableName() {
|
|
228
|
-
return this.name.match(/^(.*?)(?:Model|)$/)[1];
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
static get idColumn() {
|
|
232
|
-
const {
|
|
233
|
-
properties
|
|
234
|
-
} = this;
|
|
235
|
-
const ids = [];
|
|
236
|
-
|
|
237
|
-
for (const [name, property] of Object.entries(properties || {})) {
|
|
238
|
-
if (property != null && property.primary) {
|
|
239
|
-
ids.push(name);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const {
|
|
244
|
-
length
|
|
245
|
-
} = ids;
|
|
246
|
-
return length > 1 ? ids : length > 0 ? ids[0] : super.idColumn;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
static getReference(modelOrId, includeProperties) {
|
|
250
|
-
const ref = new this();
|
|
251
|
-
const idProperties = this.getIdPropertyArray();
|
|
252
|
-
|
|
253
|
-
if ((0, _utils2.isObject)(modelOrId)) {
|
|
254
|
-
const addProperty = key => {
|
|
255
|
-
const value = modelOrId[key];
|
|
256
|
-
|
|
257
|
-
if (value !== undefined) {
|
|
258
|
-
ref[key] = value;
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
addProperty(this.uidRefProp);
|
|
263
|
-
idProperties.forEach(addProperty);
|
|
264
|
-
includeProperties == null ? void 0 : includeProperties.forEach(addProperty);
|
|
265
|
-
} else {
|
|
266
|
-
const ids = (0, _utils2.asArray)(modelOrId);
|
|
267
|
-
|
|
268
|
-
if (ids.length !== idProperties.length) {
|
|
269
|
-
throw new _errors.ModelError(this, `Invalid amount of id values provided for reference: Unable to map ${(0, _utils.formatJson)(modelOrId, false)} to ${(0, _utils.formatJson)(idProperties, false)}.`);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
idProperties.forEach((key, index) => {
|
|
273
|
-
ref[key] = ids[index];
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
return ref;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
static isReference(obj) {
|
|
281
|
-
let validator = this.referenceValidator;
|
|
282
|
-
|
|
283
|
-
if (!validator) {
|
|
284
|
-
validator = this.referenceValidator = this.app.compileValidator({
|
|
285
|
-
oneOf: [{
|
|
286
|
-
type: 'object',
|
|
287
|
-
properties: this.getIdPropertyArray().reduce((idProperties, idProperty) => {
|
|
288
|
-
idProperties[idProperty] = {
|
|
289
|
-
type: this.definition.properties[idProperty].type
|
|
290
|
-
};
|
|
291
|
-
return idProperties;
|
|
292
|
-
}, {}),
|
|
293
|
-
additionalProperties: false
|
|
294
|
-
}, {
|
|
295
|
-
type: 'object',
|
|
296
|
-
properties: {
|
|
297
|
-
[this.uidRefProp]: {
|
|
298
|
-
type: 'string'
|
|
299
|
-
}
|
|
300
|
-
},
|
|
301
|
-
additionalProperties: false
|
|
302
|
-
}]
|
|
303
|
-
}, {
|
|
304
|
-
throw: false
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return validator(obj);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
static getScope(name) {
|
|
312
|
-
return this.definition.scopes[name];
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
static hasScope(name) {
|
|
316
|
-
return !!this.getScope(name);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
static getModifiers() {
|
|
320
|
-
return this.definition.modifiers;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
static get relationMappings() {
|
|
324
|
-
return this._getCached('relationMappings', () => (0, _schema.convertRelations)(this, this.definition.relations, this.app.models), {});
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
static get jsonSchema() {
|
|
328
|
-
return this._getCached('jsonSchema', () => {
|
|
329
|
-
const schema = (0, _schema.convertSchema)(this.definition.properties);
|
|
330
|
-
(0, _schema.addRelationSchemas)(this, schema.properties);
|
|
331
|
-
(0, _utils2.merge)(schema, this.definition.schema);
|
|
332
|
-
return {
|
|
333
|
-
$id: this.name,
|
|
334
|
-
$schema: 'http://json-schema.org/draft-07/schema',
|
|
335
|
-
...schema
|
|
336
|
-
};
|
|
337
|
-
}, {});
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
static get virtualAttributes() {
|
|
341
|
-
return this.computedAttributes;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
static get jsonAttributes() {
|
|
345
|
-
return this._getCached('jsonSchema:jsonAttributes', () => this.getAttributes(({
|
|
346
|
-
type,
|
|
347
|
-
specificType,
|
|
348
|
-
computed
|
|
349
|
-
}) => !computed && !specificType && (type === 'object' || type === 'array')), []);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
static get booleanAttributes() {
|
|
353
|
-
return this._getCached('jsonSchema:booleanAttributes', () => this.getAttributes(({
|
|
354
|
-
type,
|
|
355
|
-
computed
|
|
356
|
-
}) => !computed && type === 'boolean'), []);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
static get dateAttributes() {
|
|
360
|
-
return this._getCached('jsonSchema:dateAttributes', () => this.getAttributes(({
|
|
361
|
-
type,
|
|
362
|
-
computed
|
|
363
|
-
}) => !computed && ['date', 'datetime', 'timestamp'].includes(type)), []);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
static get computedAttributes() {
|
|
367
|
-
return this._getCached('jsonSchema:computedAttributes', () => this.getAttributes(({
|
|
368
|
-
computed
|
|
369
|
-
}) => computed), []);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
static get hiddenAttributes() {
|
|
373
|
-
return this._getCached('jsonSchema:hiddenAttributes', () => this.getAttributes(({
|
|
374
|
-
hidden
|
|
375
|
-
}) => hidden), []);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
static getAttributes(filter) {
|
|
379
|
-
const attributes = [];
|
|
380
|
-
const {
|
|
381
|
-
properties
|
|
382
|
-
} = this.definition;
|
|
383
|
-
|
|
384
|
-
for (const [name, property] of Object.entries(properties)) {
|
|
385
|
-
if (filter(property)) {
|
|
386
|
-
attributes.push(name);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
return attributes;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
static _getCached(identifier, calculate, empty = {}) {
|
|
394
|
-
var _entry, _entry2;
|
|
395
|
-
|
|
396
|
-
let cache = getMeta(this, 'cache', {});
|
|
397
|
-
let entry;
|
|
398
|
-
|
|
399
|
-
for (const part of identifier.split(':')) {
|
|
400
|
-
entry = cache[part] = cache[part] || {
|
|
401
|
-
cache: {},
|
|
402
|
-
value: undefined
|
|
403
|
-
};
|
|
404
|
-
cache = entry.cache;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
if (((_entry = entry) == null ? void 0 : _entry.value) === undefined) {
|
|
408
|
-
entry.value = empty;
|
|
409
|
-
entry.value = calculate();
|
|
410
|
-
entry.cache = {};
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
return (_entry2 = entry) == null ? void 0 : _entry2.value;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
static getRelatedRelations() {
|
|
417
|
-
return getMeta(this, 'relatedRelations', []);
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
static propertyNameToColumnName(propertyName) {
|
|
421
|
-
return propertyName;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
static columnNameToPropertyName(columnName) {
|
|
425
|
-
return columnName;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
$setJson(json, options) {
|
|
429
|
-
options = options || {};
|
|
430
|
-
const callInitialize = !options.patch && this.$initialize !== Model.prototype.$initialize && !this.constructor.isReference(json);
|
|
431
|
-
|
|
432
|
-
if (!callInitialize || options.skipValidation) {
|
|
433
|
-
super.$setJson(json, options);
|
|
434
|
-
|
|
435
|
-
if (callInitialize) {
|
|
436
|
-
this.$initialize();
|
|
437
|
-
}
|
|
438
|
-
} else {
|
|
439
|
-
super.$setJson(json, { ...options,
|
|
440
|
-
patch: true
|
|
441
|
-
});
|
|
442
|
-
this.$initialize();
|
|
443
|
-
this.$validate(this, options);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
return this;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
$formatDatabaseJson(json) {
|
|
450
|
-
const {
|
|
451
|
-
constructor
|
|
452
|
-
} = this;
|
|
453
|
-
|
|
454
|
-
for (const key of constructor.dateAttributes) {
|
|
455
|
-
const date = json[key];
|
|
456
|
-
|
|
457
|
-
if (date != null && date.toISOString) {
|
|
458
|
-
json[key] = date.toISOString();
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
if (constructor.isSQLite()) {
|
|
463
|
-
for (const key of constructor.booleanAttributes) {
|
|
464
|
-
const bool = json[key];
|
|
465
|
-
|
|
466
|
-
if (bool !== undefined) {
|
|
467
|
-
json[key] = bool ? 1 : 0;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
for (const key of constructor.computedAttributes) {
|
|
473
|
-
delete json[key];
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
return super.$formatDatabaseJson(json);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
$parseDatabaseJson(json) {
|
|
480
|
-
const {
|
|
481
|
-
constructor
|
|
482
|
-
} = this;
|
|
483
|
-
json = super.$parseDatabaseJson(json);
|
|
484
|
-
|
|
485
|
-
if (constructor.isSQLite()) {
|
|
486
|
-
for (const key of constructor.booleanAttributes) {
|
|
487
|
-
const bool = json[key];
|
|
488
|
-
|
|
489
|
-
if (bool !== undefined) {
|
|
490
|
-
json[key] = !!bool;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
return this.$parseJson(json);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
$parseJson(json) {
|
|
499
|
-
const {
|
|
500
|
-
constructor
|
|
501
|
-
} = this;
|
|
502
|
-
|
|
503
|
-
for (const key of constructor.dateAttributes) {
|
|
504
|
-
const date = json[key];
|
|
505
|
-
|
|
506
|
-
if (date !== undefined) {
|
|
507
|
-
json[key] = (0, _utils2.isString)(date) ? new Date(date) : date;
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
const {
|
|
512
|
-
assets
|
|
513
|
-
} = constructor.definition;
|
|
514
|
-
|
|
515
|
-
if (assets) {
|
|
516
|
-
for (const dataPath in assets) {
|
|
517
|
-
const storage = constructor.app.getStorage(assets[dataPath].storage);
|
|
518
|
-
const data = (0, _utils2.getValueAtDataPath)(json, dataPath, () => null);
|
|
519
|
-
|
|
520
|
-
if (data) {
|
|
521
|
-
const convertToAssetFiles = data => {
|
|
522
|
-
if (data) {
|
|
523
|
-
if ((0, _utils2.isArray)(data)) {
|
|
524
|
-
data.forEach(convertToAssetFiles);
|
|
525
|
-
} else {
|
|
526
|
-
storage.convertAssetFile(data);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
};
|
|
530
|
-
|
|
531
|
-
convertToAssetFiles(data);
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
return json;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
$formatJson(json) {
|
|
540
|
-
const {
|
|
541
|
-
constructor
|
|
542
|
-
} = this;
|
|
543
|
-
|
|
544
|
-
for (const key of constructor.computedAttributes) {
|
|
545
|
-
if (!(key in json)) {
|
|
546
|
-
const value = this[key];
|
|
547
|
-
|
|
548
|
-
if (value !== undefined) {
|
|
549
|
-
json[key] = value;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
for (const key of constructor.hiddenAttributes) {
|
|
555
|
-
delete json[key];
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
return json;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
$filterGraph(modelGraph, expr) {
|
|
562
|
-
return (0, _graph.filterGraph)(this.constructor, modelGraph, expr);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
async $populateGraph(modelGraph, expr, trx) {
|
|
566
|
-
return (0, _graph.populateGraph)(this.constructor, modelGraph, expr, trx);
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
static filterGraph(modelGraph, expr) {
|
|
570
|
-
return (0, _graph.filterGraph)(this, modelGraph, expr);
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
static async populateGraph(modelGraph, expr, trx) {
|
|
574
|
-
return (0, _graph.populateGraph)(this, modelGraph, expr, trx);
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
static getPropertyOrRelationAtDataPath(dataPath) {
|
|
578
|
-
const parsedDataPath = (0, _utils2.parseDataPath)(dataPath);
|
|
579
|
-
let index = 0;
|
|
580
|
-
|
|
581
|
-
const getResult = (property = null, relation = null) => {
|
|
582
|
-
const found = property || relation;
|
|
583
|
-
const name = parsedDataPath[index];
|
|
584
|
-
const next = index + 1;
|
|
585
|
-
const dataPath = found ? (0, _utils2.normalizeDataPath)(parsedDataPath.slice(0, next)) : null;
|
|
586
|
-
const nestedDataPath = found ? (0, _utils2.normalizeDataPath)(parsedDataPath.slice(next)) : null;
|
|
587
|
-
const expression = found ? parsedDataPath.slice(0, relation ? next : index).join('.') + (property ? `(#${name})` : '') : null;
|
|
588
|
-
return {
|
|
589
|
-
property,
|
|
590
|
-
relation,
|
|
591
|
-
dataPath,
|
|
592
|
-
nestedDataPath,
|
|
593
|
-
name,
|
|
594
|
-
expression,
|
|
595
|
-
index
|
|
596
|
-
};
|
|
597
|
-
};
|
|
598
|
-
|
|
599
|
-
const [firstToken, ...otherTokens] = parsedDataPath;
|
|
600
|
-
const property = this.definition.properties[firstToken];
|
|
601
|
-
|
|
602
|
-
if (property) {
|
|
603
|
-
return getResult(property);
|
|
604
|
-
} else {
|
|
605
|
-
let relation = this.getRelations()[firstToken];
|
|
606
|
-
|
|
607
|
-
if (relation) {
|
|
608
|
-
let {
|
|
609
|
-
relatedModelClass
|
|
610
|
-
} = relation;
|
|
611
|
-
|
|
612
|
-
for (const token of otherTokens) {
|
|
613
|
-
index++;
|
|
614
|
-
const property = relatedModelClass.definition.properties[token];
|
|
615
|
-
|
|
616
|
-
if (property) {
|
|
617
|
-
return getResult(property);
|
|
618
|
-
} else if (token === '*') {
|
|
619
|
-
if (relation.isOneToOne()) {
|
|
620
|
-
return getResult();
|
|
621
|
-
} else {
|
|
622
|
-
continue;
|
|
623
|
-
}
|
|
624
|
-
} else {
|
|
625
|
-
relation = relatedModelClass.getRelations()[token];
|
|
626
|
-
|
|
627
|
-
if (relation) {
|
|
628
|
-
relatedModelClass = relation.relatedModelClass;
|
|
629
|
-
} else {
|
|
630
|
-
return getResult();
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
if (relation) {
|
|
636
|
-
return getResult(null, relation);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
return getResult();
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
static relatedQuery(relationName, trx) {
|
|
645
|
-
return super.relatedQuery(relationName, trx).alias(relationName);
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
static modifierNotFound(query, modifier) {
|
|
649
|
-
if ((0, _utils2.isString)(modifier)) {
|
|
650
|
-
if (query.modelClass().hasScope(modifier)) {
|
|
651
|
-
return query.applyScope(modifier);
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
switch (modifier[0]) {
|
|
655
|
-
case '^':
|
|
656
|
-
return query.applyScope(modifier);
|
|
657
|
-
|
|
658
|
-
case '-':
|
|
659
|
-
return query.ignoreScope(modifier.slice(1));
|
|
660
|
-
|
|
661
|
-
case '#':
|
|
662
|
-
return query.select(modifier.slice(1));
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
super.modifierNotFound(query, modifier);
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
static createNotFoundError(ctx, error) {
|
|
670
|
-
return new _errors.NotFoundError(error || (ctx.byId ? `'${this.name}' model with id ${ctx.byId} not found` : `'${this.name}' model not found`));
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
static createValidator() {
|
|
674
|
-
return this.app.validator;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
static createValidationError({
|
|
678
|
-
type,
|
|
679
|
-
message,
|
|
680
|
-
errors,
|
|
681
|
-
options,
|
|
682
|
-
json
|
|
683
|
-
}) {
|
|
684
|
-
switch (type) {
|
|
685
|
-
case 'ModelValidation':
|
|
686
|
-
return this.app.createValidationError({
|
|
687
|
-
type,
|
|
688
|
-
message: message || `The provided data for the ${this.name} model is not valid`,
|
|
689
|
-
errors,
|
|
690
|
-
options,
|
|
691
|
-
json
|
|
692
|
-
});
|
|
693
|
-
|
|
694
|
-
case 'RelationExpression':
|
|
695
|
-
case 'UnallowedRelation':
|
|
696
|
-
return new _errors.RelationError({
|
|
697
|
-
type,
|
|
698
|
-
message,
|
|
699
|
-
errors
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
case 'InvalidGraph':
|
|
703
|
-
return new _errors.GraphError({
|
|
704
|
-
type,
|
|
705
|
-
message,
|
|
706
|
-
errors
|
|
707
|
-
});
|
|
708
|
-
|
|
709
|
-
default:
|
|
710
|
-
return new _errors.ResponseError({
|
|
711
|
-
type,
|
|
712
|
-
message,
|
|
713
|
-
errors
|
|
714
|
-
});
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
static get definition() {
|
|
719
|
-
return getMeta(this, 'definition', () => {
|
|
720
|
-
const definition = {};
|
|
721
|
-
|
|
722
|
-
const setDefinition = (name, property) => {
|
|
723
|
-
Object.defineProperty(definition, name, { ...property,
|
|
724
|
-
enumerable: true
|
|
725
|
-
});
|
|
726
|
-
};
|
|
727
|
-
|
|
728
|
-
const getDefinition = name => {
|
|
729
|
-
let modelClass = this;
|
|
730
|
-
const values = [];
|
|
731
|
-
|
|
732
|
-
while (modelClass !== _objection.default.Model) {
|
|
733
|
-
if (name in modelClass) {
|
|
734
|
-
const desc = Object.getOwnPropertyDescriptor(modelClass, name);
|
|
735
|
-
|
|
736
|
-
if (desc) {
|
|
737
|
-
var _desc$get;
|
|
738
|
-
|
|
739
|
-
const value = ((_desc$get = desc.get) == null ? void 0 : _desc$get.call(this)) || desc.value;
|
|
740
|
-
|
|
741
|
-
if (value) {
|
|
742
|
-
values.push(value);
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
modelClass = Object.getPrototypeOf(modelClass);
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
setDefinition(name, {
|
|
751
|
-
configurable: true,
|
|
752
|
-
value: {}
|
|
753
|
-
});
|
|
754
|
-
|
|
755
|
-
try {
|
|
756
|
-
const merged = _definitions.default[name].call(this, values);
|
|
757
|
-
|
|
758
|
-
setDefinition(name, {
|
|
759
|
-
configurable: false,
|
|
760
|
-
value: merged
|
|
761
|
-
});
|
|
762
|
-
return merged;
|
|
763
|
-
} catch (error) {
|
|
764
|
-
throw new _errors.ModelError(this, error.message);
|
|
765
|
-
}
|
|
766
|
-
};
|
|
767
|
-
|
|
768
|
-
for (const name in _definitions.default) {
|
|
769
|
-
setDefinition(name, {
|
|
770
|
-
configurable: true,
|
|
771
|
-
get: () => getDefinition(name)
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
return definition;
|
|
776
|
-
});
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
$emit(event, ...args) {
|
|
780
|
-
return this.constructor.emit(event, this, ...args);
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
static beforeFind(args) {
|
|
784
|
-
return this._emitStaticHook('before:find', args);
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
static afterFind(args) {
|
|
788
|
-
return this._emitStaticHook('after:find', args);
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
static beforeInsert(args) {
|
|
792
|
-
return this._emitStaticHook('before:insert', args);
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
static afterInsert(args) {
|
|
796
|
-
return this._emitStaticHook('after:insert', args);
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
static beforeUpdate(args) {
|
|
800
|
-
return this._emitStaticHook('before:update', args);
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
static afterUpdate(args) {
|
|
804
|
-
return this._emitStaticHook('after:update', args);
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
static beforeDelete(args) {
|
|
808
|
-
return this._emitStaticHook('before:delete', args);
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
static afterDelete(args) {
|
|
812
|
-
return this._emitStaticHook('after:delete', args);
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
static async _emitStaticHook(event, originalArgs) {
|
|
816
|
-
const listeners = this.listeners(event);
|
|
817
|
-
|
|
818
|
-
if (listeners.length > 0) {
|
|
819
|
-
let {
|
|
820
|
-
result
|
|
821
|
-
} = originalArgs;
|
|
822
|
-
const args = Object.create(originalArgs, {
|
|
823
|
-
type: {
|
|
824
|
-
value: event
|
|
825
|
-
},
|
|
826
|
-
result: {
|
|
827
|
-
get() {
|
|
828
|
-
return result;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
}
|
|
832
|
-
});
|
|
833
|
-
|
|
834
|
-
for (const listener of listeners) {
|
|
835
|
-
const res = await listener.call(this, args);
|
|
836
|
-
|
|
837
|
-
if (res !== undefined) {
|
|
838
|
-
result = res;
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
if (result !== originalArgs.result) {
|
|
843
|
-
return result;
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
static _setupAssetsEvents(assets) {
|
|
849
|
-
const assetDataPaths = Object.keys(assets);
|
|
850
|
-
this.on(['before:insert', 'before:update', 'before:delete'], async ({
|
|
851
|
-
type,
|
|
852
|
-
transaction,
|
|
853
|
-
inputItems,
|
|
854
|
-
asFindQuery
|
|
855
|
-
}) => {
|
|
856
|
-
const afterItems = type === 'before:delete' ? [] : inputItems;
|
|
857
|
-
const dataPaths = afterItems.length > 0 ? assetDataPaths.filter(path => getValueAtAssetDataPath(afterItems[0], path) !== undefined) : assetDataPaths;
|
|
858
|
-
|
|
859
|
-
if (dataPaths.length === 0) {
|
|
860
|
-
return;
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
const beforeItems = type === 'before:insert' ? [] : await loadAssetDataPaths(asFindQuery(), dataPaths);
|
|
864
|
-
const beforeFilesPerDataPath = getFilesPerAssetDataPath(beforeItems, dataPaths);
|
|
865
|
-
const afterFilesPerDataPath = getFilesPerAssetDataPath(afterItems, dataPaths);
|
|
866
|
-
const importedFiles = [];
|
|
867
|
-
const modifiedFiles = [];
|
|
868
|
-
|
|
869
|
-
if (transaction.rollback) {
|
|
870
|
-
transaction.setMaxListeners(0);
|
|
871
|
-
transaction.on('rollback', async error => {
|
|
872
|
-
if (importedFiles.length > 0) {
|
|
873
|
-
console.info(`Received '${error}', removing imported files again: ${importedFiles.map(file => `'${file.name}'`)}`);
|
|
874
|
-
await Promise.all(importedFiles.map(file => file.storage.removeFile(file)));
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
if (modifiedFiles.length > 0) {
|
|
878
|
-
console.info(`Unable to restore these already modified files: ${modifiedFiles.map(file => `'${file.name}'`)}`);
|
|
879
|
-
}
|
|
880
|
-
});
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
for (const dataPath of dataPaths) {
|
|
884
|
-
const storage = this.app.getStorage(assets[dataPath].storage);
|
|
885
|
-
const beforeFiles = beforeFilesPerDataPath[dataPath] || [];
|
|
886
|
-
const afterFiles = afterFilesPerDataPath[dataPath] || [];
|
|
887
|
-
const beforeByKey = mapFilesByKey(beforeFiles);
|
|
888
|
-
const afterByKey = mapFilesByKey(afterFiles);
|
|
889
|
-
const removedFiles = beforeFiles.filter(file => !afterByKey[file.key]);
|
|
890
|
-
const addedFiles = afterFiles.filter(file => !beforeByKey[file.key]);
|
|
891
|
-
const modifiedFiles = afterFiles.filter(file => file.data && beforeByKey[file.key]);
|
|
892
|
-
importedFiles.push(...(await this.app.handleAdddedAndRemovedAssets(storage, addedFiles, removedFiles, transaction)));
|
|
893
|
-
modifiedFiles.push(...(await this.app.handleModifiedAssets(storage, modifiedFiles, transaction)));
|
|
894
|
-
}
|
|
895
|
-
});
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
exports.Model = Model;
|
|
901
|
-
Model.QueryBuilder = _query.QueryBuilder;
|
|
902
|
-
Model.cloneObjectAttributes = false;
|
|
903
|
-
Model.pickJsonSchemaProperties = true;
|
|
904
|
-
Model.useLimitInFirst = true;
|
|
905
|
-
|
|
906
|
-
_lib.EventEmitter.mixin(Model);
|
|
907
|
-
|
|
908
|
-
_lib.KnexHelper.mixin(Model);
|
|
909
|
-
|
|
910
|
-
_query.QueryBuilder.mixin(Model);
|
|
911
|
-
|
|
912
|
-
const metaMap = new WeakMap();
|
|
913
|
-
|
|
914
|
-
function getMeta(modelClass, key, value) {
|
|
915
|
-
let meta = metaMap.get(modelClass);
|
|
916
|
-
|
|
917
|
-
if (!meta) {
|
|
918
|
-
metaMap.set(modelClass, meta = {});
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
if (!(key in meta)) {
|
|
922
|
-
meta[key] = (0, _utils2.isFunction)(value) ? value() : value;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
return meta[key];
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
function loadAssetDataPaths(query, dataPaths) {
|
|
929
|
-
return dataPaths.reduce((query, dataPath) => query.loadDataPath(dataPath), query);
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
function getValueAtAssetDataPath(item, path) {
|
|
933
|
-
return (0, _utils2.getValueAtDataPath)(item, path, () => undefined);
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
function getFilesPerAssetDataPath(items, dataPaths) {
|
|
937
|
-
return dataPaths.reduce((allFiles, dataPath) => {
|
|
938
|
-
allFiles[dataPath] = (0, _utils2.asArray)(items).reduce((files, item) => {
|
|
939
|
-
const data = (0, _utils2.asArray)(getValueAtAssetDataPath(item, dataPath));
|
|
940
|
-
files.push(...(0, _utils2.flatten)(data).filter(file => !!file));
|
|
941
|
-
return files;
|
|
942
|
-
}, []);
|
|
943
|
-
return allFiles;
|
|
944
|
-
}, {});
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
function mapFilesByKey(files) {
|
|
948
|
-
return files.reduce((map, file) => {
|
|
949
|
-
map[file.key] = file;
|
|
950
|
-
return map;
|
|
951
|
-
}, {});
|
|
952
|
-
}
|
|
953
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2RlbHMvTW9kZWwuanMiXSwibmFtZXMiOlsiTW9kZWwiLCJvYmplY3Rpb24iLCJjb25zdHJ1Y3RvciIsImpzb24iLCIkc2V0SnNvbiIsInNldHVwIiwia25leCIsInJlbGF0aW9uIiwiT2JqZWN0IiwidmFsdWVzIiwiZ2V0UmVsYXRpb25zIiwic2V0dXBSZWxhdGlvbiIsImVycm9yIiwiUmVsYXRpb25FcnJvciIsInJlZmVyZW5jZVZhbGlkYXRvciIsInJlbGF0ZWRNb2RlbENsYXNzIiwiZ2V0UmVsYXRlZFJlbGF0aW9ucyIsInB1c2giLCJhY2Nlc3NvciIsIm5hbWUiLCJwcm90b3R5cGUiLCJkZWZpbmVBY2Nlc3NvciIsInRhcmdldCIsImlzQ2xhc3MiLCJkZWZpbmVQcm9wZXJ0eSIsImdldCIsInZhbHVlIiwiUmVsYXRpb25BY2Nlc3NvciIsImNvbmZpZ3VyYWJsZSIsImVudW1lcmFibGUiLCJpbml0aWFsaXplIiwiaG9va3MiLCJhc3NldHMiLCJkZWZpbml0aW9uIiwiX3NldHVwRW1pdHRlciIsIl9zZXR1cEFzc2V0c0V2ZW50cyIsIiRpbml0aWFsaXplIiwiJGFwcCIsImFwcCIsIiRpcyIsIm1vZGVsIiwiaWQiLCIkaGFzIiwicHJvcGVydGllcyIsInByb3BlcnR5IiwiJHVwZGF0ZSIsInRyeCIsIiRxdWVyeSIsInVwZGF0ZSIsInJ1bkFmdGVyIiwicmVzdWx0IiwicXVlcnkiLCJoYXMiLCIkc2V0IiwiJHBhdGNoIiwicGF0Y2giLCIkdHJhbnNhY3Rpb24iLCJoYW5kbGVyIiwidHJhbnNhY3Rpb24iLCIkdmFsaWRhdGUiLCJvcHRpb25zIiwic2tpcFZhbGlkYXRpb24iLCJncmFwaCIsImFzeW5jIiwiaW5wdXRKc29uIiwic2hhbGxvdyIsIiRpc09iamVjdGlvbk1vZGVsIiwiY2xvbmUiLCJtdXRhYmxlIiwidmFsaWRhdG9yIiwiZ2V0VmFsaWRhdG9yIiwiYXJncyIsImN0eCIsImNyZWF0ZSIsImJlZm9yZVZhbGlkYXRlIiwidmFsaWRhdGUiLCJoYW5kbGVSZXN1bHQiLCJhZnRlclZhbGlkYXRlIiwidGhlbiIsIiR2YWxpZGF0ZUdyYXBoIiwiZnJvbUpzb24iLCJvbkVycm9yIiwiZXJyIiwiUmVzcG9uc2VFcnJvciIsIkRCRXJyb3IiLCJjcmVhdGVEYXRhYmFzZUVycm9yIiwiV3JhcHBlZEVycm9yIiwiUHJvbWlzZSIsInJlamVjdCIsImNvdW50IiwiZmlyc3QiLCJ0YWJsZU5hbWUiLCJtYXRjaCIsImlkQ29sdW1uIiwiaWRzIiwiZW50cmllcyIsInByaW1hcnkiLCJsZW5ndGgiLCJnZXRSZWZlcmVuY2UiLCJtb2RlbE9ySWQiLCJpbmNsdWRlUHJvcGVydGllcyIsInJlZiIsImlkUHJvcGVydGllcyIsImdldElkUHJvcGVydHlBcnJheSIsImFkZFByb3BlcnR5Iiwia2V5IiwidW5kZWZpbmVkIiwidWlkUmVmUHJvcCIsImZvckVhY2giLCJNb2RlbEVycm9yIiwiaW5kZXgiLCJpc1JlZmVyZW5jZSIsIm9iaiIsImNvbXBpbGVWYWxpZGF0b3IiLCJvbmVPZiIsInR5cGUiLCJyZWR1Y2UiLCJpZFByb3BlcnR5IiwiYWRkaXRpb25hbFByb3BlcnRpZXMiLCJ0aHJvdyIsImdldFNjb3BlIiwic2NvcGVzIiwiaGFzU2NvcGUiLCJnZXRNb2RpZmllcnMiLCJtb2RpZmllcnMiLCJyZWxhdGlvbk1hcHBpbmdzIiwiX2dldENhY2hlZCIsInJlbGF0aW9ucyIsIm1vZGVscyIsImpzb25TY2hlbWEiLCJzY2hlbWEiLCIkaWQiLCIkc2NoZW1hIiwidmlydHVhbEF0dHJpYnV0ZXMiLCJjb21wdXRlZEF0dHJpYnV0ZXMiLCJqc29uQXR0cmlidXRlcyIsImdldEF0dHJpYnV0ZXMiLCJzcGVjaWZpY1R5cGUiLCJjb21wdXRlZCIsImJvb2xlYW5BdHRyaWJ1dGVzIiwiZGF0ZUF0dHJpYnV0ZXMiLCJpbmNsdWRlcyIsImhpZGRlbkF0dHJpYnV0ZXMiLCJoaWRkZW4iLCJmaWx0ZXIiLCJhdHRyaWJ1dGVzIiwiaWRlbnRpZmllciIsImNhbGN1bGF0ZSIsImVtcHR5IiwiY2FjaGUiLCJnZXRNZXRhIiwiZW50cnkiLCJwYXJ0Iiwic3BsaXQiLCJwcm9wZXJ0eU5hbWVUb0NvbHVtbk5hbWUiLCJwcm9wZXJ0eU5hbWUiLCJjb2x1bW5OYW1lVG9Qcm9wZXJ0eU5hbWUiLCJjb2x1bW5OYW1lIiwiY2FsbEluaXRpYWxpemUiLCIkZm9ybWF0RGF0YWJhc2VKc29uIiwiZGF0ZSIsInRvSVNPU3RyaW5nIiwiaXNTUUxpdGUiLCJib29sIiwiJHBhcnNlRGF0YWJhc2VKc29uIiwiJHBhcnNlSnNvbiIsIkRhdGUiLCJkYXRhUGF0aCIsInN0b3JhZ2UiLCJnZXRTdG9yYWdlIiwiZGF0YSIsImNvbnZlcnRUb0Fzc2V0RmlsZXMiLCJjb252ZXJ0QXNzZXRGaWxlIiwiJGZvcm1hdEpzb24iLCIkZmlsdGVyR3JhcGgiLCJtb2RlbEdyYXBoIiwiZXhwciIsIiRwb3B1bGF0ZUdyYXBoIiwiZmlsdGVyR3JhcGgiLCJwb3B1bGF0ZUdyYXBoIiwiZ2V0UHJvcGVydHlPclJlbGF0aW9uQXREYXRhUGF0aCIsInBhcnNlZERhdGFQYXRoIiwiZ2V0UmVzdWx0IiwiZm91bmQiLCJuZXh0Iiwic2xpY2UiLCJuZXN0ZWREYXRhUGF0aCIsImV4cHJlc3Npb24iLCJqb2luIiwiZmlyc3RUb2tlbiIsIm90aGVyVG9rZW5zIiwidG9rZW4iLCJpc09uZVRvT25lIiwicmVsYXRlZFF1ZXJ5IiwicmVsYXRpb25OYW1lIiwiYWxpYXMiLCJtb2RpZmllck5vdEZvdW5kIiwibW9kaWZpZXIiLCJtb2RlbENsYXNzIiwiYXBwbHlTY29wZSIsImlnbm9yZVNjb3BlIiwic2VsZWN0IiwiY3JlYXRlTm90Rm91bmRFcnJvciIsIk5vdEZvdW5kRXJyb3IiLCJieUlkIiwiY3JlYXRlVmFsaWRhdG9yIiwiY3JlYXRlVmFsaWRhdGlvbkVycm9yIiwibWVzc2FnZSIsImVycm9ycyIsIkdyYXBoRXJyb3IiLCJzZXREZWZpbml0aW9uIiwiZ2V0RGVmaW5pdGlvbiIsImRlc2MiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJjYWxsIiwiZ2V0UHJvdG90eXBlT2YiLCJtZXJnZWQiLCJkZWZpbml0aW9ucyIsIiRlbWl0IiwiZXZlbnQiLCJlbWl0IiwiYmVmb3JlRmluZCIsIl9lbWl0U3RhdGljSG9vayIsImFmdGVyRmluZCIsImJlZm9yZUluc2VydCIsImFmdGVySW5zZXJ0IiwiYmVmb3JlVXBkYXRlIiwiYWZ0ZXJVcGRhdGUiLCJiZWZvcmVEZWxldGUiLCJhZnRlckRlbGV0ZSIsIm9yaWdpbmFsQXJncyIsImxpc3RlbmVycyIsImxpc3RlbmVyIiwicmVzIiwiYXNzZXREYXRhUGF0aHMiLCJrZXlzIiwib24iLCJpbnB1dEl0ZW1zIiwiYXNGaW5kUXVlcnkiLCJhZnRlckl0ZW1zIiwiZGF0YVBhdGhzIiwicGF0aCIsImdldFZhbHVlQXRBc3NldERhdGFQYXRoIiwiYmVmb3JlSXRlbXMiLCJsb2FkQXNzZXREYXRhUGF0aHMiLCJiZWZvcmVGaWxlc1BlckRhdGFQYXRoIiwiZ2V0RmlsZXNQZXJBc3NldERhdGFQYXRoIiwiYWZ0ZXJGaWxlc1BlckRhdGFQYXRoIiwiaW1wb3J0ZWRGaWxlcyIsIm1vZGlmaWVkRmlsZXMiLCJyb2xsYmFjayIsInNldE1heExpc3RlbmVycyIsImNvbnNvbGUiLCJpbmZvIiwibWFwIiwiZmlsZSIsImFsbCIsInJlbW92ZUZpbGUiLCJiZWZvcmVGaWxlcyIsImFmdGVyRmlsZXMiLCJiZWZvcmVCeUtleSIsIm1hcEZpbGVzQnlLZXkiLCJhZnRlckJ5S2V5IiwicmVtb3ZlZEZpbGVzIiwiYWRkZWRGaWxlcyIsImhhbmRsZUFkZGRlZEFuZFJlbW92ZWRBc3NldHMiLCJoYW5kbGVNb2RpZmllZEFzc2V0cyIsIlF1ZXJ5QnVpbGRlciIsImNsb25lT2JqZWN0QXR0cmlidXRlcyIsInBpY2tKc29uU2NoZW1hUHJvcGVydGllcyIsInVzZUxpbWl0SW5GaXJzdCIsIkV2ZW50RW1pdHRlciIsIm1peGluIiwiS25leEhlbHBlciIsIm1ldGFNYXAiLCJXZWFrTWFwIiwibWV0YSIsInNldCIsImxvYWREYXRhUGF0aCIsIml0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QVNwQixhQUFULENBQXVCcUIsS0FBdkIsRUFBOEI7QUFDNUIsU0FBT0EsS0FBSyxDQUFDdEssTUFBTixDQUNMLENBQUMwSSxHQUFELEVBQU1DLElBQU4sS0FBZTtBQUNiRCxJQUFBQSxHQUFHLENBQUNDLElBQUksQ0FBQ3RKLEdBQU4sQ0FBSCxHQUFnQnNKLElBQWhCO0FBQ0EsV0FBT0QsR0FBUDtBQUNELEdBSkksRUFLTCxFQUxLLENBQVA7QUFPRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBvYmplY3Rpb24gZnJvbSAnb2JqZWN0aW9uJ1xuaW1wb3J0IHsgUXVlcnlCdWlsZGVyIH0gZnJvbSAnQC9xdWVyeSdcbmltcG9ydCB7IEV2ZW50RW1pdHRlciwgS25leEhlbHBlciB9IGZyb20gJ0AvbGliJ1xuaW1wb3J0IHsgY29udmVydFNjaGVtYSwgYWRkUmVsYXRpb25TY2hlbWFzLCBjb252ZXJ0UmVsYXRpb25zIH0gZnJvbSAnQC9zY2hlbWEnXG5pbXBvcnQgeyBwb3B1bGF0ZUdyYXBoLCBmaWx0ZXJHcmFwaCB9IGZyb20gJ0AvZ3JhcGgnXG5pbXBvcnQgeyBmb3JtYXRKc29uIH0gZnJvbSAnQC91dGlscydcbmltcG9ydCB7XG4gIFJlc3BvbnNlRXJyb3IsXG4gIEdyYXBoRXJyb3IsIE1vZGVsRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIFJlbGF0aW9uRXJyb3IsXG4gIFdyYXBwZWRFcnJvclxufSBmcm9tICdAL2Vycm9ycydcbmltcG9ydCB7XG4gIGlzU3RyaW5nLCBpc09iamVjdCwgaXNBcnJheSwgaXNGdW5jdGlvbiwgaXNQcm9taXNlLCBhc0FycmF5LCBtZXJnZSwgZmxhdHRlbixcbiAgcGFyc2VEYXRhUGF0aCwgbm9ybWFsaXplRGF0YVBhdGgsIGdldFZhbHVlQXREYXRhUGF0aFxufSBmcm9tICdAZGl0b2pzL3V0aWxzJ1xuaW1wb3J0IFJlbGF0aW9uQWNjZXNzb3IgZnJvbSAnLi9SZWxhdGlvbkFjY2Vzc29yJ1xuaW1wb3J0IGRlZmluaXRpb25zIGZyb20gJy4vZGVmaW5pdGlvbnMnXG5cbmV4cG9ydCBjbGFzcyBNb2RlbCBleHRlbmRzIG9iamVjdGlvbi5Nb2RlbCB7XG4gIC8vIERlZmluZSBhIGRlZmF1bHQgY29uc3RydWN0b3IgdG8gYWxsb3cgbmV3IE1vZGVsKGpzb24pIGFzIGEgc2hvcnQtY3V0IHRvXG4gIC8vIGBNb2RlbC5mcm9tSnNvbihqc29uLCB7IHNraXBWYWxpZGF0aW9uOiB0cnVlIH0pYFxuICBjb25zdHJ1Y3Rvcihqc29uKSB7XG4gICAgc3VwZXIoKVxuICAgIGlmIChqc29uKSB7XG4gICAgICB0aGlzLiRzZXRKc29uKGpzb24pXG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHNldHVwKGtuZXgpIHtcbiAgICB0aGlzLmtuZXgoa25leClcbiAgICB0cnkge1xuICAgICAgZm9yIChjb25zdCByZWxhdGlvbiBvZiBPYmplY3QudmFsdWVzKHRoaXMuZ2V0UmVsYXRpb25zKCkpKSB7XG4gICAgICAgIHRoaXMuc2V0dXBSZWxhdGlvbihyZWxhdGlvbilcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgZXJyb3IgaW5zdGFuY2VvZiBSZWxhdGlvbkVycm9yID8gZXJyb3IgOiBuZXcgUmVsYXRpb25FcnJvcihlcnJvcilcbiAgICB9XG4gICAgdGhpcy5yZWZlcmVuY2VWYWxpZGF0b3IgPSBudWxsXG4gIH1cblxuICBzdGF0aWMgc2V0dXBSZWxhdGlvbihyZWxhdGlvbikge1xuICAgIC8vIEFkZCB0aGlzIHJlbGF0aW9uIHRvIHRoZSByZWxhdGVkIG1vZGVsJ3MgcmVsYXRlZFJlbGF0aW9ucywgc28gaXQgY2FuXG4gICAgLy8gcmVnaXN0ZXIgYWxsIHJlcXVpcmVkIGZvcmVpZ24ga2V5cyBpbiBpdHMgcHJvcGVydGllcy5cbiAgICByZWxhdGlvbi5yZWxhdGVkTW9kZWxDbGFzcy5nZXRSZWxhdGVkUmVsYXRpb25zKCkucHVzaChyZWxhdGlvbilcbiAgICAvLyBUT0RPOiBDaGVjayBgdGhyb3VnaGAgc2V0dGluZ3MgdG8gbWFrZSBzdXJlIHRoZXkncmUgY29ycmVjdD9cblxuICAgIC8vIEV4cG9zZSBSZWxhdGlvbkFjY2Vzc29yIGluc3RhbmNlcyBmb3IgZWFjaCByZWxhdGlvbiB1bmRlciBzaG9ydC1jdXQgJG5hbWVcbiAgICAvLyBmb3IgYWNjZXNzIHRvIHJlbGF0aW9ucyBhbmQgaW1wbGljaXQgY2FsbHMgdG8gJHJlbGF0ZWRRdWVyeShuYW1lKS5cbiAgICBjb25zdCBhY2Nlc3NvciA9IGAkJHtyZWxhdGlvbi5uYW1lfWBcbiAgICBpZiAoYWNjZXNzb3IgaW4gdGhpcy5wcm90b3R5cGUpIHtcbiAgICAgIHRocm93IG5ldyBSZWxhdGlvbkVycm9yKFxuICAgICAgICBgTW9kZWwgJyR7dGhpcy5uYW1lfScgYWxyZWFkeSBkZWZpbmVzIGEgcHJvcGVydHkgd2l0aCBuYW1lIGAgK1xuICAgICAgICBgJyR7YWNjZXNzb3J9JyB0aGF0IGNsYXNoZXMgd2l0aCB0aGUgcmVsYXRpb24gYWNjZXNzb3IuYClcbiAgICB9XG5cbiAgICAvLyBEZWZpbmUgYW4gYWNjZXNzb3Igb24gdGhlIGNsYXNzIGFzIHdlbGwgYXMgb24gdGhlIHByb3RvdHlwZSB0aGF0IHdoZW5cbiAgICAvLyBmaXJzdCBjYWxsZWQgY3JlYXRlcyBhIFJlbGF0aW9uQWNjZXNzb3IgaW5zdGFuY2UgYW5kIHRoZW4gb3ZlcnJpZGVzIHRoZVxuICAgIC8vIGFjY2Vzc29yIHdpdGggb25lIHRoYXQgdGhlbiBqdXN0IHJldHVybnMgdGhlIHNhbWUgdmFsdWUgYWZ0ZXJ3YXJkcy5cbiAgICBjb25zdCBkZWZpbmVBY2Nlc3NvciA9ICh0YXJnZXQsIGlzQ2xhc3MpID0+IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGFjY2Vzc29yLCB7XG4gICAgICAgIGdldCgpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyBSZWxhdGlvbkFjY2Vzc29yKFxuICAgICAgICAgICAgcmVsYXRpb24sXG4gICAgICAgICAgICBpc0NsYXNzID8gdGhpcyA6IG51bGwsIC8vIG1vZGVsQ2xhc3NcbiAgICAgICAgICAgIGlzQ2xhc3MgPyBudWxsIDogdGhpcyAvLyBtb2RlbFxuICAgICAgICAgIClcbiAgICAgICAgICAvLyBPdmVycmlkZSBhY2Nlc3NvciB3aXRoIHZhbHVlIG9uIGZpcnN0IGNhbGwgZm9yIGNhY2hpbmcuXG4gICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGFjY2Vzc29yLCB7XG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlXG4gICAgICAgICAgfSlcbiAgICAgICAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZVxuICAgICAgfSlcbiAgICB9XG5cbiAgICBkZWZpbmVBY2Nlc3Nvcih0aGlzLCB0cnVlKVxuICAgIGRlZmluZUFjY2Vzc29yKHRoaXMucHJvdG90eXBlLCBmYWxzZSlcbiAgfVxuXG4gIC8vIEBvdmVycmlkYWJsZVxuICBzdGF0aWMgaW5pdGlhbGl6ZSgpIHtcbiAgICBjb25zdCB7IGhvb2tzLCBhc3NldHMgfSA9IHRoaXMuZGVmaW5pdGlvblxuICAgIHRoaXMuX3NldHVwRW1pdHRlcihob29rcylcbiAgICBpZiAoYXNzZXRzKSB7XG4gICAgICB0aGlzLl9zZXR1cEFzc2V0c0V2ZW50cyhhc3NldHMpXG4gICAgfVxuICB9XG5cbiAgLy8gQG92ZXJyaWRhYmxlXG4gICRpbml0aWFsaXplKCkge1xuICB9XG5cbiAgZ2V0ICRhcHAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IuYXBwXG4gIH1cblxuICAkaXMobW9kZWwpIHtcbiAgICByZXR1cm4gbW9kZWw/LmNvbnN0cnVjdG9yID09PSB0aGlzLmNvbnN0cnVjdG9yICYmIG1vZGVsPy5pZCA9PT0gdGhpcy5pZFxuICB9XG5cbiAgJGhhcyguLi5wcm9wZXJ0aWVzKSB7XG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBwcm9wZXJ0aWVzKSB7XG4gICAgICBpZiAoIShwcm9wZXJ0eSBpbiB0aGlzKSkgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAkdXBkYXRlKHByb3BlcnRpZXMsIHRyeCkge1xuICAgIHJldHVybiB0aGlzLiRxdWVyeSh0cngpXG4gICAgICAudXBkYXRlKHByb3BlcnRpZXMpXG4gICAgICAucnVuQWZ0ZXIoKHJlc3VsdCwgcXVlcnkpID0+XG4gICAgICAgIC8vIE9ubHkgcGVyZm9ybSBgJHNldCgpYCBhbmQgcmV0dXJuIGB0aGlzYCBpZiB0aGUgcXVlcnkgd2Fzbid0IG1vZGlmaWVkXG4gICAgICAgIC8vIGluIGEgd2F5IHRoYXQgd291bGQgcmVtb3ZlIHRoZSBgdXBkYXRlKClgIGNvbW1hbmQsIGUuZy4gdG9GaW5kUXVlcnkoKVxuICAgICAgICBxdWVyeS5oYXMoJ3VwZGF0ZScpID8gdGhpcy4kc2V0KHJlc3VsdCkgOiByZXN1bHRcbiAgICAgIClcbiAgfVxuXG4gICRwYXRjaChwcm9wZXJ0aWVzLCB0cngpIHtcbiAgICByZXR1cm4gdGhpcy4kcXVlcnkodHJ4KVxuICAgICAgLnBhdGNoKHByb3BlcnRpZXMpXG4gICAgICAucnVuQWZ0ZXIoKHJlc3VsdCwgcXVlcnkpID0+XG4gICAgICAgIC8vIE9ubHkgcGVyZm9ybSBgJHNldCgpYCBhbmQgcmV0dXJuIGB0aGlzYCBpZiB0aGUgcXVlcnkgd2Fzbid0IG1vZGlmaWVkXG4gICAgICAgIC8vIGluIGEgd2F5IHRoYXQgd291bGQgcmVtb3ZlIHRoZSBgcGF0Y2goKWAgY29tbWFuZCwgZS5nLiB0b0ZpbmRRdWVyeSgpXG4gICAgICAgIHF1ZXJ5LmhhcygncGF0Y2gnKSA/IHRoaXMuJHNldChyZXN1bHQpIDogcmVzdWx0XG4gICAgICApXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgJHRyYW5zYWN0aW9uKHRyeCwgaGFuZGxlcikge1xuICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRyYW5zYWN0aW9uKHRyeCwgaGFuZGxlcilcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgdHJhbnNhY3Rpb24odHJ4LCBoYW5kbGVyKSB7XG4gICAgLy8gU3VwcG9ydCBib3RoIGB0cmFuc2FjdGlvbih0cngsIGhhbmRsZXIpYCAmIGB0cmFuc2FjdGlvbihoYW5kbGVyKWBcbiAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgIGhhbmRsZXIgPSB0cnhcbiAgICAgIHRyeCA9IG51bGxcbiAgICB9XG4gICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgIC8vIFVzZSBleGlzdGluZyB0cmFuc2FjdGlvbiwgb3IgY3JlYXRlIG5ldyBvbmUsIHRvIGV4ZWN1dGUgaGFuZGxlciB3aXRoOlxuICAgICAgcmV0dXJuIHRyeFxuICAgICAgICA/IGhhbmRsZXIodHJ4KVxuICAgICAgICA6IHRoaXMua25leCgpLnRyYW5zYWN0aW9uKGhhbmRsZXIpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIGFyZ3VtZW50cywgc2ltcGx5IGRlbGVnYXRlIHRvIG9iamVjdGlvbidzIHRyYW5zYWN0aW9uKClcbiAgICAgIHJldHVybiBzdXBlci50cmFuc2FjdGlvbigpXG4gICAgfVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gICR2YWxpZGF0ZShqc29uLCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAob3B0aW9ucy5za2lwVmFsaWRhdGlvbikge1xuICAgICAgcmV0dXJuIGpzb25cbiAgICB9XG4gICAgaWYgKCFvcHRpb25zLmdyYXBoICYmICFvcHRpb25zLmFzeW5jKSB7XG4gICAgICAvLyBGYWxsIGJhY2sgdG8gT2JqZWN0aW9uJ3MgJHZhbGlkYXRlKCkgaWYgd2UgZG9uJ3QgbmVlZCBhbnkgb2Ygb3VyXG4gICAgICAvLyBleHRlbnNpb25zIChhc3luYyBhbmQgZ3JhcGggZm9yIG5vdyk6XG4gICAgICByZXR1cm4gc3VwZXIuJHZhbGlkYXRlKGpzb24sIG9wdGlvbnMpXG4gICAgfVxuICAgIGpzb24gPSBqc29uIHx8IHRoaXNcbiAgICBjb25zdCBpbnB1dEpzb24gPSBqc29uXG4gICAgY29uc3Qgc2hhbGxvdyA9IGpzb24uJGlzT2JqZWN0aW9uTW9kZWwgJiYgIW9wdGlvbnMuZ3JhcGhcbiAgICBpZiAoc2hhbGxvdykge1xuICAgICAgLy8gU3RyaXAgYXdheSByZWxhdGlvbnMgYW5kIG90aGVyIGludGVybmFsIHN0dWZmLlxuICAgICAganNvbiA9IGpzb24uY2xvbmUoeyBzaGFsbG93OiB0cnVlIH0pXG4gICAgICAvLyBXZSBjYW4gbXV0YXRlIGBqc29uYCBub3cgdGhhdCB3ZSB0b29rIGEgY29weSBvZiBpdC5cbiAgICAgIG9wdGlvbnMgPSB7IC4uLm9wdGlvbnMsIG11dGFibGU6IHRydWUgfVxuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkYXRvciA9IHRoaXMuY29uc3RydWN0b3IuZ2V0VmFsaWRhdG9yKClcbiAgICBjb25zdCBhcmdzID0ge1xuICAgICAgb3B0aW9ucyxcbiAgICAgIG1vZGVsOiB0aGlzLFxuICAgICAganNvbixcbiAgICAgIGN0eDogT2JqZWN0LmNyZWF0ZShudWxsKVxuICAgIH1cblxuICAgIHZhbGlkYXRvci5iZWZvcmVWYWxpZGF0ZShhcmdzKVxuICAgIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRvci52YWxpZGF0ZShhcmdzKVxuICAgIGNvbnN0IGhhbmRsZVJlc3VsdCA9IHJlc3VsdCA9PiB7XG4gICAgICB2YWxpZGF0b3IuYWZ0ZXJWYWxpZGF0ZShhcmdzKVxuICAgICAgLy8gSWYgYGpzb25gIHdhcyBzaGFsbG93LWNsb25lZCwgY29weSBvdmVyIHRoZSBwb3NzaWJsZSBkZWZhdWx0IHZhbHVlcy5cbiAgICAgIHJldHVybiBzaGFsbG93ID8gaW5wdXRKc29uLiRzZXQocmVzdWx0KSA6IHJlc3VsdFxuICAgIH1cbiAgICAvLyBIYW5kbGUgYm90aCBhc3luYyBhbmQgc3luYyB2YWxpZGF0aW9uIGhlcmU6XG4gICAgcmV0dXJuIGlzUHJvbWlzZShyZXN1bHQpXG4gICAgICA/IHJlc3VsdC50aGVuKGhhbmRsZVJlc3VsdClcbiAgICAgIDogaGFuZGxlUmVzdWx0KHJlc3VsdClcbiAgfVxuXG4gIGFzeW5jICR2YWxpZGF0ZUdyYXBoKG9wdGlvbnMgPSB7fSkge1xuICAgIGF3YWl0IHRoaXMuJHZhbGlkYXRlKG51bGwsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBncmFwaDogdHJ1ZSxcbiAgICAgIC8vIEFsd2F5cyB1c2UgYGFzeW5jOiB0cnVlYCBvcHRpb24gaGVyZSBmb3Igc2ltcGxpY2l0eTpcbiAgICAgIGFzeW5jOiB0cnVlXG4gICAgfSlcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIHN0YXRpYyBmcm9tSnNvbihqc29uLCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAob3B0aW9ucy5hc3luYyAmJiAhb3B0aW9ucy5za2lwVmFsaWRhdGlvbikge1xuICAgICAgLy8gSGFuZGxlIGFzeW5jIHZhbGlkYXRpb24sIGFzIHN1cHBvcnRlZCBieSBEaXRvOlxuICAgICAgY29uc3QgbW9kZWwgPSBuZXcgdGhpcygpXG4gICAgICByZXR1cm4gbW9kZWwuJHZhbGlkYXRlKGpzb24sIG9wdGlvbnMpLnRoZW4oXG4gICAgICAgIGpzb24gPT4gbW9kZWwuJHNldEpzb24oanNvbiwge1xuICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgc2tpcFZhbGlkYXRpb246IHRydWVcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICB9XG4gICAgLy8gRmFsbCBiYWNrIHRvIE9iamVjdGlvbidzIGZyb21Kc29uKCkgaWYgd2UgZG9uJ3QgbmVlZCBhc3luYyBoYW5kbGluZzpcbiAgICByZXR1cm4gc3VwZXIuZnJvbUpzb24oanNvbiwgb3B0aW9ucylcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgcXVlcnkodHJ4KSB7XG4gICAgcmV0dXJuIHN1cGVyLnF1ZXJ5KHRyeCkub25FcnJvcihlcnIgPT4ge1xuICAgICAgLy8gVE9ETzogU2hvdWxkbid0IHRoaXMgd3JhcHBpbmcgaGFwcGVuIG9uIHRoZSBDb250cm9sbGVyIGxldmVsP1xuICAgICAgZXJyID0gZXJyIGluc3RhbmNlb2YgUmVzcG9uc2VFcnJvciA/IGVyclxuICAgICAgICA6IGVyciBpbnN0YW5jZW9mIG9iamVjdGlvbi5EQkVycm9yID8gdGhpcy5hcHAuY3JlYXRlRGF0YWJhc2VFcnJvcihlcnIpXG4gICAgICAgIDogbmV3IFdyYXBwZWRFcnJvcihlcnIpXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKVxuICAgIH0pXG4gIH1cblxuICBzdGF0aWMgYXN5bmMgY291bnQoLi4uYXJncykge1xuICAgIGNvbnN0IHsgY291bnQgfSA9IGF3YWl0IHRoaXMucXVlcnkoKS5jb3VudCguLi5hcmdzKS5maXJzdCgpIHx8IHt9XG4gICAgcmV0dXJuICtjb3VudCB8fCAwXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgLy8gSWYgdGhlIGNsYXNzIG5hbWUgZW5kcyBpbiAnTW9kZWwnLCByZW1vdmUgdGhhdCBmcm9tIHRoZSB0YWJsZSBuYW1lLlxuICAgIHJldHVybiB0aGlzLm5hbWUubWF0Y2goL14oLio/KSg/Ok1vZGVsfCkkLylbMV1cbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgZ2V0IGlkQ29sdW1uKCkge1xuICAgIC8vIFRyeSBleHRyYWN0aW5nIHRoZSBpZCBjb2x1bW4gbmFtZSBmcm9tIHRoZSByYXcgcHJvcGVydGllcyBkZWZpbml0aW9ucyxcbiAgICAvLyBub3QgdGhlIHJlc29sdmVkIGBkZWZpbml0aW9uLnByb3BlcnRpZXNgIHdoaWNoIGFyZW4ndCByZWFkeSBhdCB0aGlzIHBvaW50XG4gICAgLy8gd2l0aCBmYWxsLWJhY2sgb250byBkZWZhdWx0IE9iamVjdGlvbi5qcyBiZWhhdmlvci5cbiAgICBjb25zdCB7IHByb3BlcnRpZXMgfSA9IHRoaXNcbiAgICBjb25zdCBpZHMgPSBbXVxuICAgIGZvciAoY29uc3QgW25hbWUsIHByb3BlcnR5XSBvZiBPYmplY3QuZW50cmllcyhwcm9wZXJ0aWVzIHx8IHt9KSkge1xuICAgICAgaWYgKHByb3BlcnR5Py5wcmltYXJ5KSB7XG4gICAgICAgIGlkcy5wdXNoKG5hbWUpXG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHsgbGVuZ3RoIH0gPSBpZHNcbiAgICByZXR1cm4gbGVuZ3RoID4gMSA/IGlkcyA6IGxlbmd0aCA+IDAgPyBpZHNbMF0gOiBzdXBlci5pZENvbHVtblxuICB9XG5cbiAgc3RhdGljIGdldFJlZmVyZW5jZShtb2RlbE9ySWQsIGluY2x1ZGVQcm9wZXJ0aWVzKSB7XG4gICAgLy8gQ3JlYXRlcyBhIHJlZmVyZW5jZSBtb2RlbCB0aGF0IHRha2VzIG92ZXIgdGhlIGlkIC8gI3JlZiBwcm9wZXJ0aWVzIGZyb21cbiAgICAvLyB0aGUgcGFzc2VkIG1vZGVsIG9yIGlkIHZhbHVlL2FycmF5LCBvbWl0dGluZyBhbnkgb3RoZXIgcHJvcGVydGllcyBpbiBpdCxcbiAgICAvLyBleGNlcHQgZm9yIGFueXRoaW5nIG1lbnRpb25lZCBpbiB0aGUgb3B0aW9uYWwgYGluY2x1ZGVQcm9wZXJ0aWVzYCBhcmcuXG4gICAgY29uc3QgcmVmID0gbmV3IHRoaXMoKVxuICAgIGNvbnN0IGlkUHJvcGVydGllcyA9IHRoaXMuZ2V0SWRQcm9wZXJ0eUFycmF5KClcbiAgICBpZiAoaXNPYmplY3QobW9kZWxPcklkKSkge1xuICAgICAgY29uc3QgYWRkUHJvcGVydHkgPSBrZXkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG1vZGVsT3JJZFtrZXldXG4gICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmVmW2tleV0gPSB2YWx1ZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBBbHNvIHN1cHBvcnQgT2JqZWN0aW9uJ3MgI3JlZiB0eXBlIHJlZmVyZW5jZXMgbmV4dCB0byBpZCBwcm9wZXJ0aWVzLlxuICAgICAgYWRkUHJvcGVydHkodGhpcy51aWRSZWZQcm9wKVxuICAgICAgaWRQcm9wZXJ0aWVzLmZvckVhY2goYWRkUHJvcGVydHkpXG4gICAgICBpbmNsdWRlUHJvcGVydGllcz8uZm9yRWFjaChhZGRQcm9wZXJ0eSlcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQW4gaWQgdmFsdWUvYXJyYXk6IE1hcCBpdCB0byB0aGUgcHJvcGVydGllcyBpbiBgZ2V0SWRQcm9wZXJ0eUFycmF5KClgOlxuICAgICAgY29uc3QgaWRzID0gYXNBcnJheShtb2RlbE9ySWQpXG4gICAgICBpZiAoaWRzLmxlbmd0aCAhPT0gaWRQcm9wZXJ0aWVzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgTW9kZWxFcnJvcihcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGBJbnZhbGlkIGFtb3VudCBvZiBpZCB2YWx1ZXMgcHJvdmlkZWQgZm9yIHJlZmVyZW5jZTogVW5hYmxlIHRvIG1hcCAke1xuICAgICAgICAgICAgZm9ybWF0SnNvbihtb2RlbE9ySWQsIGZhbHNlKVxuICAgICAgICAgIH0gdG8gJHtcbiAgICAgICAgICAgIGZvcm1hdEpzb24oaWRQcm9wZXJ0aWVzLCBmYWxzZSlcbiAgICAgICAgICB9LmBcbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgaWRQcm9wZXJ0aWVzLmZvckVhY2goKGtleSwgaW5kZXgpID0+IHtcbiAgICAgICAgcmVmW2tleV0gPSBpZHNbaW5kZXhdXG4gICAgICB9KVxuICAgIH1cbiAgICByZXR1cm4gcmVmXG4gIH1cblxuICBzdGF0aWMgaXNSZWZlcmVuY2Uob2JqKSB7XG4gICAgbGV0IHZhbGlkYXRvciA9IHRoaXMucmVmZXJlbmNlVmFsaWRhdG9yXG4gICAgaWYgKCF2YWxpZGF0b3IpIHtcbiAgICAgIC8vIEZvciBgZGF0YWAgdG8gYmUgY29uc2lkZXJlZCBhIHJlZmVyZW5jZSwgaXQgbmVlZHMgdG8gaG9sZCBvbmx5IG9uZVxuICAgICAgLy8gdmFsdWUgdGhhdCBpcyBlaXRoZXIgdGhlIHRhcmdldCdzIGlkLCBvciBhbiBPYmplY3Rpb24uanMgI3JlZiB2YWx1ZTpcbiAgICAgIHZhbGlkYXRvciA9IHRoaXMucmVmZXJlbmNlVmFsaWRhdG9yID0gdGhpcy5hcHAuY29tcGlsZVZhbGlkYXRvcihcbiAgICAgICAge1xuICAgICAgICAgIG9uZU9mOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICAvLyBTdXBwb3J0IGNvbXBvc2l0ZSBrZXlzIGFuZCBhZGQgYSBwcm9wZXJ0eSBmb3IgZWFjaCBrZXk6XG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHRoaXMuZ2V0SWRQcm9wZXJ0eUFycmF5KCkucmVkdWNlKFxuICAgICAgICAgICAgICAgIChpZFByb3BlcnRpZXMsIGlkUHJvcGVydHkpID0+IHtcbiAgICAgICAgICAgICAgICAgIGlkUHJvcGVydGllc1tpZFByb3BlcnR5XSA9IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogdGhpcy5kZWZpbml0aW9uLnByb3BlcnRpZXNbaWRQcm9wZXJ0eV0udHlwZVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGlkUHJvcGVydGllc1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge31cbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIFt0aGlzLnVpZFJlZlByb3BdOiB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXVxuICAgICAgICB9LFxuICAgICAgICAvLyBSZWNlaXZlIGBmYWxzZWAgaW5zdGVhZCBvZiB0aHJvd24gZXhjZXB0aW9ucyB3aGVuIHZhbGlkYXRpb24gZmFpbHM6XG4gICAgICAgIHsgdGhyb3c6IGZhbHNlIH1cbiAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIHZhbGlkYXRvcihvYmopXG4gIH1cblxuICBzdGF0aWMgZ2V0U2NvcGUobmFtZSkge1xuICAgIHJldHVybiB0aGlzLmRlZmluaXRpb24uc2NvcGVzW25hbWVdXG4gIH1cblxuICBzdGF0aWMgaGFzU2NvcGUobmFtZSkge1xuICAgIHJldHVybiAhIXRoaXMuZ2V0U2NvcGUobmFtZSlcbiAgfVxuXG4gIHN0YXRpYyBnZXRNb2RpZmllcnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVmaW5pdGlvbi5tb2RpZmllcnNcbiAgfVxuXG4gIHN0YXRpYyBnZXQgcmVsYXRpb25NYXBwaW5ncygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0Q2FjaGVkKCdyZWxhdGlvbk1hcHBpbmdzJywgKCkgPT4gKFxuICAgICAgY29udmVydFJlbGF0aW9ucyh0aGlzLCB0aGlzLmRlZmluaXRpb24ucmVsYXRpb25zLCB0aGlzLmFwcC5tb2RlbHMpXG4gICAgKSwge30pXG4gIH1cblxuICBzdGF0aWMgZ2V0IGpzb25TY2hlbWEoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldENhY2hlZCgnanNvblNjaGVtYScsICgpID0+IHtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IGNvbnZlcnRTY2hlbWEodGhpcy5kZWZpbml0aW9uLnByb3BlcnRpZXMpXG4gICAgICBhZGRSZWxhdGlvblNjaGVtYXModGhpcywgc2NoZW1hLnByb3BlcnRpZXMpXG4gICAgICAvLyBNZXJnZSBpbiByb290LWxldmVsIHNjaGVtYSBhZGRpdGlvbnNcbiAgICAgIG1lcmdlKHNjaGVtYSwgdGhpcy5kZWZpbml0aW9uLnNjaGVtYSlcbiAgICAgIHJldHVybiB7XG4gICAgICAgICRpZDogdGhpcy5uYW1lLFxuICAgICAgICAkc2NoZW1hOiAnaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEnLFxuICAgICAgICAuLi5zY2hlbWFcbiAgICAgIH1cbiAgICB9LCB7fSlcbiAgfVxuXG4gIHN0YXRpYyBnZXQgdmlydHVhbEF0dHJpYnV0ZXMoKSB7XG4gICAgLy8gTGV2ZXJhZ2UgT2JqZWN0aW9uJ3Mgb3duIG1lY2hhbmlzbSBjYWxsZWQgYHZpcnR1YWxBdHRyaWJ1dGVzYCB0byBoYW5kbGVcbiAgICAvLyBgY29tcHV0ZWRBdHRyaWJ1dGVzYCB3aGVuIHNldHRpbmcgSlNPTiBkYXRhLlxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVkQXR0cmlidXRlc1xuICB9XG5cbiAgc3RhdGljIGdldCBqc29uQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0Q2FjaGVkKCdqc29uU2NoZW1hOmpzb25BdHRyaWJ1dGVzJywgKCkgPT4gKFxuICAgICAgdGhpcy5nZXRBdHRyaWJ1dGVzKCh7IHR5cGUsIHNwZWNpZmljVHlwZSwgY29tcHV0ZWQgfSkgPT5cbiAgICAgICAgIWNvbXB1dGVkICYmICFzcGVjaWZpY1R5cGUgJiYgKHR5cGUgPT09ICdvYmplY3QnIHx8IHR5cGUgPT09ICdhcnJheScpKVxuICAgICksIFtdKVxuICB9XG5cbiAgc3RhdGljIGdldCBib29sZWFuQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0Q2FjaGVkKCdqc29uU2NoZW1hOmJvb2xlYW5BdHRyaWJ1dGVzJywgKCkgPT4gKFxuICAgICAgdGhpcy5nZXRBdHRyaWJ1dGVzKCh7IHR5cGUsIGNvbXB1dGVkIH0pID0+XG4gICAgICAgICFjb21wdXRlZCAmJiB0eXBlID09PSAnYm9vbGVhbicpXG4gICAgKSwgW10pXG4gIH1cblxuICBzdGF0aWMgZ2V0IGRhdGVBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRDYWNoZWQoJ2pzb25TY2hlbWE6ZGF0ZUF0dHJpYnV0ZXMnLCAoKSA9PiAoXG4gICAgICB0aGlzLmdldEF0dHJpYnV0ZXMoKHsgdHlwZSwgY29tcHV0ZWQgfSkgPT5cbiAgICAgICAgIWNvbXB1dGVkICYmIFsnZGF0ZScsICdkYXRldGltZScsICd0aW1lc3RhbXAnXS5pbmNsdWRlcyh0eXBlKSlcbiAgICApLCBbXSlcbiAgfVxuXG4gIHN0YXRpYyBnZXQgY29tcHV0ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRDYWNoZWQoJ2pzb25TY2hlbWE6Y29tcHV0ZWRBdHRyaWJ1dGVzJywgKCkgPT4gKFxuICAgICAgdGhpcy5nZXRBdHRyaWJ1dGVzKCh7IGNvbXB1dGVkIH0pID0+IGNvbXB1dGVkKVxuICAgICksIFtdKVxuICB9XG5cbiAgc3RhdGljIGdldCBoaWRkZW5BdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRDYWNoZWQoJ2pzb25TY2hlbWE6aGlkZGVuQXR0cmlidXRlcycsICgpID0+IChcbiAgICAgIHRoaXMuZ2V0QXR0cmlidXRlcygoeyBoaWRkZW4gfSkgPT4gaGlkZGVuKVxuICAgICksIFtdKVxuICB9XG5cbiAgc3RhdGljIGdldEF0dHJpYnV0ZXMoZmlsdGVyKSB7XG4gICAgY29uc3QgYXR0cmlidXRlcyA9IFtdXG4gICAgY29uc3QgeyBwcm9wZXJ0aWVzIH0gPSB0aGlzLmRlZmluaXRpb25cbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBwcm9wZXJ0eV0gb2YgT2JqZWN0LmVudHJpZXMocHJvcGVydGllcykpIHtcbiAgICAgIGlmIChmaWx0ZXIocHJvcGVydHkpKSB7XG4gICAgICAgIGF0dHJpYnV0ZXMucHVzaChuYW1lKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXR0cmlidXRlc1xuICB9XG5cbiAgc3RhdGljIF9nZXRDYWNoZWQoaWRlbnRpZmllciwgY2FsY3VsYXRlLCBlbXB0eSA9IHt9KSB7XG4gICAgbGV0IGNhY2hlID0gZ2V0TWV0YSh0aGlzLCAnY2FjaGUnLCB7fSlcbiAgICAvLyBVc2UgYSBzaW1wbGUgZGVwZW5kZW5jeSB0cmFja2luZyBtZWNoYW5pc20gd2l0aCBjYWNoZSBpZGVudGlmaWVycyB0aGF0XG4gICAgLy8gY2FuIGJlIGNoaWxkcmVuIG9mIG90aGVyIGNhY2hlZCB2YWx1ZXMsIGUuZy46XG4gICAgLy8gJ2pzb25TY2hlbWE6anNvbkF0dHJpYnV0ZXMnIGFzIGEgY2hpbGQgb2YgJ2pzb25TY2hlbWEnLCBzbyB0aGF0IHdoZW5ldmVyXG4gICAgLy8gJ2pzb25TY2hlbWEnIGNoYW5nZXMsIGFsbCBjYWNoZWQgY2hpbGQgdmFsdWVzICBhcmUgaW52YWxpZGF0ZWQuXG4gICAgbGV0IGVudHJ5XG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIGlkZW50aWZpZXIuc3BsaXQoJzonKSkge1xuICAgICAgZW50cnkgPSBjYWNoZVtwYXJ0XSA9IGNhY2hlW3BhcnRdIHx8IHtcbiAgICAgICAgY2FjaGU6IHt9LFxuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkXG4gICAgICB9XG4gICAgICBjYWNoZSA9IGVudHJ5LmNhY2hlXG4gICAgfVxuICAgIGlmIChlbnRyeT8udmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gVGVtcG9yYXJpbHkgc2V0IGNhY2hlIHRvIGFuIGVtcHR5IG9iamVjdCB0byBwcmV2ZW50IGVuZGxlc3NcbiAgICAgIC8vIHJlY3Vyc2lvbiB3aXRoIGludGVyZGVwZW5kZW50IGpzb25TY2hlbWEgcmVsYXRlZCBjYWxscy4uLlxuICAgICAgZW50cnkudmFsdWUgPSBlbXB0eVxuICAgICAgZW50cnkudmFsdWUgPSBjYWxjdWxhdGUoKVxuICAgICAgLy8gQ2xlYXIgY2hpbGQgZGVwZW5kZW5jaWVzIG9uY2UgcGFyZW50IHZhbHVlIGhhcyBjaGFuZ2VkOlxuICAgICAgZW50cnkuY2FjaGUgPSB7fVxuICAgIH1cbiAgICByZXR1cm4gZW50cnk/LnZhbHVlXG4gIH1cblxuICBzdGF0aWMgZ2V0UmVsYXRlZFJlbGF0aW9ucygpIHtcbiAgICByZXR1cm4gZ2V0TWV0YSh0aGlzLCAncmVsYXRlZFJlbGF0aW9ucycsIFtdKVxuICB9XG5cbiAgLy8gT3ZlcnJpZGUgcHJvcGVydHlOYW1lVG9Db2x1bW5OYW1lKCkgLyBjb2x1bW5OYW1lVG9Qcm9wZXJ0eU5hbWUoKSB0byBub3RcbiAgLy8gcmVseSBvbiAkZm9ybWF0RGF0YWJhc2VKc29uKCkgLyAgJHBhcnNlRGF0YWJhc2VKc29uKCkgZG8gZGV0ZWN0IG5hbWluZ1xuICAvLyBjb252ZW50aW9ucyBidXQgYXNzdW1lIHNpbXBseSB0aGF0IHRoZXkncmUgYWx3YXlzIHRoZSBzYW1lLlxuICAvLyBUaGlzIGlzIGZpbmUgc2luY2Ugd2UgY2FuIG5vdyBjaGFuZ2UgbmFtaW5nIGF0IEtuZXggbGV2ZWwuXG4gIC8vIFNlZSBrbmV4U25ha2VDYXNlTWFwcGVycygpXG5cbiAgLy8gQG92ZXJyaWRlXG4gIHN0YXRpYyBwcm9wZXJ0eU5hbWVUb0NvbHVtbk5hbWUocHJvcGVydHlOYW1lKSB7XG4gICAgcmV0dXJuIHByb3BlcnR5TmFtZVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIHN0YXRpYyBjb2x1bW5OYW1lVG9Qcm9wZXJ0eU5hbWUoY29sdW1uTmFtZSkge1xuICAgIHJldHVybiBjb2x1bW5OYW1lXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgJHNldEpzb24oanNvbiwgb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG4gICAgY29uc3QgY2FsbEluaXRpYWxpemUgPSAoXG4gICAgICAvLyBPbmx5IGNhbGwgaW5pdGlhbGl6ZSB3aGVuOlxuICAgICAgLy8gMS4gd2UncmUgbm90IHBhcnRpYWxseSBwYXRjaGluZzpcbiAgICAgICFvcHRpb25zLnBhdGNoICYmXG4gICAgICAvLyAyLiAkaW5pdGlhbGl6ZSgpIGlzIGFjdHVhbGx5IGRvaW5nIHNvbWV0aGluZzpcbiAgICAgIHRoaXMuJGluaXRpYWxpemUgIT09IE1vZGVsLnByb3RvdHlwZS4kaW5pdGlhbGl6ZSAmJlxuICAgICAgLy8gMy4gdGhlIGRhdGEgaXMgbm90IGp1c3QgYSByZWZlcmVuY2U6XG4gICAgICAhdGhpcy5jb25zdHJ1Y3Rvci5pc1JlZmVyZW5jZShqc29uKVxuICAgIClcbiAgICBpZiAoIWNhbGxJbml0aWFsaXplIHx8IG9wdGlvbnMuc2tpcFZhbGlkYXRpb24pIHtcbiAgICAgIHN1cGVyLiRzZXRKc29uKGpzb24sIG9wdGlvbnMpXG4gICAgICBpZiAoY2FsbEluaXRpYWxpemUpIHtcbiAgICAgICAgdGhpcy4kaW5pdGlhbGl6ZSgpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHZhbGlkYXRpb24gaXNuJ3Qgc2tpcHBlZCBvciB0aGUgbW9kZWwgcHJvdmlkZXMgaXRzIG93biAkaW5pdGlhbGl6ZSgpXG4gICAgICAvLyBtZXRob2QsIGNhbGwgJHNldEpzb24oKSB3aXRoIHBhdGNoIHZhbGlkYXRpb24gZmlyc3QgdG8gbm90IGNvbXBsYWluXG4gICAgICAvLyBhYm91dCBtaXNzaW5nIGZpZWxkcywgdGhlbiBwZXJmb3JtIGEgZnVsbCB2YWxpZGF0aW9uIGFmdGVyIGNhbGxpbmdcbiAgICAgIC8vICRpbml0aWFsaXplKCksIHRvIGdpdmUgdGhlIG1vZGVsIGEgY2hhbmNlIHRvIGNvbmZpZ3VyZSBpdHNlbGYuXG4gICAgICBzdXBlci4kc2V0SnNvbihqc29uLCB7IC4uLm9wdGlvbnMsIHBhdGNoOiB0cnVlIH0pXG4gICAgICB0aGlzLiRpbml0aWFsaXplKClcbiAgICAgIHRoaXMuJHZhbGlkYXRlKHRoaXMsIG9wdGlvbnMpXG4gICAgfVxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgJGZvcm1hdERhdGFiYXNlSnNvbihqc29uKSB7XG4gICAgY29uc3QgeyBjb25zdHJ1Y3RvciB9ID0gdGhpc1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGNvbnN0cnVjdG9yLmRhdGVBdHRyaWJ1dGVzKSB7XG4gICAgICBjb25zdCBkYXRlID0ganNvbltrZXldXG4gICAgICBpZiAoZGF0ZT8udG9JU09TdHJpbmcpIHtcbiAgICAgICAganNvbltrZXldID0gZGF0ZS50b0lTT1N0cmluZygpXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChjb25zdHJ1Y3Rvci5pc1NRTGl0ZSgpKSB7XG4gICAgICAvLyBTUUxpdGUgZG9lcyBub3Qgc3VwcG9ydCBib29sZWFuIG5hdGl2ZWx5IGFuZCBuZWVkcyBjb252ZXJzaW9uLi4uXG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBjb25zdHJ1Y3Rvci5ib29sZWFuQXR0cmlidXRlcykge1xuICAgICAgICBjb25zdCBib29sID0ganNvbltrZXldXG4gICAgICAgIGlmIChib29sICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBqc29uW2tleV0gPSBib29sID8gMSA6IDBcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBSZW1vdmUgdGhlIGNvbXB1dGVkIHByb3BlcnRpZXMgc28gdGhleSBkb24ndCBhdHRlbXB0IHRvIGdldCBzZXQuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgY29uc3RydWN0b3IuY29tcHV0ZWRBdHRyaWJ1dGVzKSB7XG4gICAgICBkZWxldGUganNvbltrZXldXG4gICAgfVxuICAgIC8vIE5PVEU6IE5vIG5lZWQgdG8gbm9ybWFsaXplIHRoZSBpZGVudGlmaWVycyBpbiB0aGUgSlNPTiBpbiBjYXNlIG9mXG4gICAgLy8gbm9ybWFsaXplRGJOYW1lcywgYXMgdGhpcyBhbHJlYWR5IGhhcHBlbnMgdGhyb3VnaFxuICAgIC8vIGtuZXguY29uZmlnLndyYXBJZGVudGlmaWVyKCksIHNlZSBBcHBsaWNhdGlvbi5qc1xuICAgIHJldHVybiBzdXBlci4kZm9ybWF0RGF0YWJhc2VKc29uKGpzb24pXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgJHBhcnNlRGF0YWJhc2VKc29uKGpzb24pIHtcbiAgICBjb25zdCB7IGNvbnN0cnVjdG9yIH0gPSB0aGlzXG4gICAganNvbiA9IHN1cGVyLiRwYXJzZURhdGFiYXNlSnNvbihqc29uKVxuICAgIGlmIChjb25zdHJ1Y3Rvci5pc1NRTGl0ZSgpKSB7XG4gICAgICAvLyBTUUxpdGUgZG9lcyBub3Qgc3VwcG9ydCBib29sZWFuIG5hdGl2ZWx5IGFuZCBuZWVkcyBjb252ZXJzaW9uLi4uXG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBjb25zdHJ1Y3Rvci5ib29sZWFuQXR0cmlidXRlcykge1xuICAgICAgICBjb25zdCBib29sID0ganNvbltrZXldXG4gICAgICAgIGlmIChib29sICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBqc29uW2tleV0gPSAhIWJvb2xcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBBbHNvIHJ1biB0aHJvdWdoIG5vcm1hbCAkcGFyc2VKc29uKCksIGZvciBoYW5kbGluZyBvZiBgRGF0ZWAgYW5kXG4gICAgLy8gYEFzc2V0RmlsZWAuXG4gICAgcmV0dXJuIHRoaXMuJHBhcnNlSnNvbihqc29uKVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gICRwYXJzZUpzb24oanNvbikge1xuICAgIGNvbnN0IHsgY29uc3RydWN0b3IgfSA9IHRoaXNcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBjb25zdHJ1Y3Rvci5kYXRlQXR0cmlidXRlcykge1xuICAgICAgY29uc3QgZGF0ZSA9IGpzb25ba2V5XVxuICAgICAgaWYgKGRhdGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBqc29uW2tleV0gPSBpc1N0cmluZyhkYXRlKSA/IG5ldyBEYXRlKGRhdGUpIDogZGF0ZVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBDb252ZXJ0IHBsYWluIGFzc2V0IGZpbGVzIG9iamVjdHMgdG8gQXNzZXRGaWxlIGluc3RhbmNlcyB3aXRoIHJlZmVyZW5jZXNcbiAgICAvLyB0byB0aGUgbGlua2VkIHN0b3JhZ2UuXG4gICAgY29uc3QgeyBhc3NldHMgfSA9IGNvbnN0cnVjdG9yLmRlZmluaXRpb25cbiAgICBpZiAoYXNzZXRzKSB7XG4gICAgICBmb3IgKGNvbnN0IGRhdGFQYXRoIGluIGFzc2V0cykge1xuICAgICAgICBjb25zdCBzdG9yYWdlID0gY29uc3RydWN0b3IuYXBwLmdldFN0b3JhZ2UoYXNzZXRzW2RhdGFQYXRoXS5zdG9yYWdlKVxuICAgICAgICBjb25zdCBkYXRhID0gZ2V0VmFsdWVBdERhdGFQYXRoKGpzb24sIGRhdGFQYXRoLCAoKSA9PiBudWxsKVxuICAgICAgICBpZiAoZGF0YSkge1xuICAgICAgICAgIGNvbnN0IGNvbnZlcnRUb0Fzc2V0RmlsZXMgPSBkYXRhID0+IHtcbiAgICAgICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgICAgIGlmIChpc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgZGF0YS5mb3JFYWNoKGNvbnZlcnRUb0Fzc2V0RmlsZXMpXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RvcmFnZS5jb252ZXJ0QXNzZXRGaWxlKGRhdGEpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgY29udmVydFRvQXNzZXRGaWxlcyhkYXRhKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBqc29uXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgJGZvcm1hdEpzb24oanNvbikge1xuICAgIGNvbnN0IHsgY29uc3RydWN0b3IgfSA9IHRoaXNcbiAgICAvLyBDYWxjdWxhdGUgYW5kIHNldCB0aGUgY29tcHV0ZWQgcHJvcGVydGllcy5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBjb25zdHJ1Y3Rvci5jb21wdXRlZEF0dHJpYnV0ZXMpIHtcbiAgICAgIC8vIFBlcmhhcHMgdGhlIGNvbXB1dGVkIHByb3BlcnR5IGlzIHByb2R1Y2VkIGluIHRoZSBTUUwgc3RhdGVtZW50LFxuICAgICAgLy8gaW4gd2hpY2ggY2FzZSB3ZSBkb24ndCBoYXZlIHRvIGRvIGFueXRoaW5nIGFueW1vcmUgaGVyZS5cbiAgICAgIGlmICghKGtleSBpbiBqc29uKSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXNba2V5XVxuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGpzb25ba2V5XSA9IHZhbHVlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gUmVtb3ZlIGhpZGRlbiBhdHRyaWJ1dGVzLlxuICAgIGZvciAoY29uc3Qga2V5IG9mIGNvbnN0cnVjdG9yLmhpZGRlbkF0dHJpYnV0ZXMpIHtcbiAgICAgIGRlbGV0ZSBqc29uW2tleV1cbiAgICB9XG4gICAgcmV0dXJuIGpzb25cbiAgfVxuXG4gIC8vIEdyYXBoIGhhbmRsaW5nXG5cbiAgJGZpbHRlckdyYXBoKG1vZGVsR3JhcGgsIGV4cHIpIHtcbiAgICByZXR1cm4gZmlsdGVyR3JhcGgodGhpcy5jb25zdHJ1Y3RvciwgbW9kZWxHcmFwaCwgZXhwcilcbiAgfVxuXG4gIGFzeW5jICRwb3B1bGF0ZUdyYXBoKG1vZGVsR3JhcGgsIGV4cHIsIHRyeCkge1xuICAgIHJldHVybiBwb3B1bGF0ZUdyYXBoKHRoaXMuY29uc3RydWN0b3IsIG1vZGVsR3JhcGgsIGV4cHIsIHRyeClcbiAgfVxuXG4gIHN0YXRpYyBmaWx0ZXJHcmFwaChtb2RlbEdyYXBoLCBleHByKSB7XG4gICAgcmV0dXJuIGZpbHRlckdyYXBoKHRoaXMsIG1vZGVsR3JhcGgsIGV4cHIpXG4gIH1cblxuICBzdGF0aWMgYXN5bmMgcG9wdWxhdGVHcmFwaChtb2RlbEdyYXBoLCBleHByLCB0cngpIHtcbiAgICByZXR1cm4gcG9wdWxhdGVHcmFwaCh0aGlzLCBtb2RlbEdyYXBoLCBleHByLCB0cngpXG4gIH1cblxuICBzdGF0aWMgZ2V0UHJvcGVydHlPclJlbGF0aW9uQXREYXRhUGF0aChkYXRhUGF0aCkge1xuICAgIC8vIEZpbmRzIHRoZSBwcm9wZXJ0eSBvciByZWxhdGlvbiBhdCB0aGUgZ2l2ZW4gdGhlIGRhdGFQYXRoIG9mIHRoZSBtb2RlbCBieVxuICAgIC8vIHBhcnNpbmcgdGhlIGRhdGFQYXRoIGFuZCBtYXRjaGluZyBpdCB0byBpdHMgcmVsYXRpb25zIGFuZCBwcm9wZXJ0aWVzLlxuICAgIGNvbnN0IHBhcnNlZERhdGFQYXRoID0gcGFyc2VEYXRhUGF0aChkYXRhUGF0aClcbiAgICBsZXQgaW5kZXggPSAwXG5cbiAgICBjb25zdCBnZXRSZXN1bHQgPSAocHJvcGVydHkgPSBudWxsLCByZWxhdGlvbiA9IG51bGwpID0+IHtcbiAgICAgIGNvbnN0IGZvdW5kID0gcHJvcGVydHkgfHwgcmVsYXRpb25cbiAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZWREYXRhUGF0aFtpbmRleF1cbiAgICAgIGNvbnN0IG5leHQgPSBpbmRleCArIDFcbiAgICAgIGNvbnN0IGRhdGFQYXRoID0gZm91bmRcbiAgICAgICAgPyBub3JtYWxpemVEYXRhUGF0aChwYXJzZWREYXRhUGF0aC5zbGljZSgwLCBuZXh0KSlcbiAgICAgICAgOiBudWxsXG4gICAgICBjb25zdCBuZXN0ZWREYXRhUGF0aCA9IGZvdW5kXG4gICAgICAgID8gbm9ybWFsaXplRGF0YVBhdGgocGFyc2VkRGF0YVBhdGguc2xpY2UobmV4dCkpXG4gICAgICAgIDogbnVsbFxuICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IGZvdW5kXG4gICAgICAgID8gcGFyc2VkRGF0YVBhdGguc2xpY2UoMCwgcmVsYXRpb24gPyBuZXh0IDogaW5kZXgpLmpvaW4oJy4nKSArXG4gICAgICAgICAgKHByb3BlcnR5ID8gYCgjJHtuYW1lfSlgIDogJycpXG4gICAgICAgIDogbnVsbFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcHJvcGVydHksXG4gICAgICAgIHJlbGF0aW9uLFxuICAgICAgICBkYXRhUGF0aCxcbiAgICAgICAgbmVzdGVkRGF0YVBhdGgsXG4gICAgICAgIG5hbWUsXG4gICAgICAgIGV4cHJlc3Npb24sXG4gICAgICAgIGluZGV4XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgW2ZpcnN0VG9rZW4sIC4uLm90aGVyVG9rZW5zXSA9IHBhcnNlZERhdGFQYXRoXG4gICAgY29uc3QgcHJvcGVydHkgPSB0aGlzLmRlZmluaXRpb24ucHJvcGVydGllc1tmaXJzdFRva2VuXVxuICAgIGlmIChwcm9wZXJ0eSkge1xuICAgICAgcmV0dXJuIGdldFJlc3VsdChwcm9wZXJ0eSlcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHJlbGF0aW9uID0gdGhpcy5nZXRSZWxhdGlvbnMoKVtmaXJzdFRva2VuXVxuICAgICAgaWYgKHJlbGF0aW9uKSB7XG4gICAgICAgIGxldCB7IHJlbGF0ZWRNb2RlbENsYXNzIH0gPSByZWxhdGlvblxuICAgICAgICBmb3IgKGNvbnN0IHRva2VuIG9mIG90aGVyVG9rZW5zKSB7XG4gICAgICAgICAgaW5kZXgrK1xuICAgICAgICAgIGNvbnN0IHByb3BlcnR5ID0gcmVsYXRlZE1vZGVsQ2xhc3MuZGVmaW5pdGlvbi5wcm9wZXJ0aWVzW3Rva2VuXVxuICAgICAgICAgIGlmIChwcm9wZXJ0eSkge1xuICAgICAgICAgICAgcmV0dXJuIGdldFJlc3VsdChwcm9wZXJ0eSlcbiAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuID09PSAnKicpIHtcbiAgICAgICAgICAgIGlmIChyZWxhdGlvbi5pc09uZVRvT25lKCkpIHtcbiAgICAgICAgICAgICAgLy8gRG8gbm90IHN1cHBvcnQgd2lsZGNhcmRzIG9uIG9uZS10by1vbmUgcmVsYXRpb25zOlxuICAgICAgICAgICAgICByZXR1cm4gZ2V0UmVzdWx0KClcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEZvdW5kIGEgcmVsYXRpb24/IEtlZXAgaXRlcmF0aW5nLlxuICAgICAgICAgICAgcmVsYXRpb24gPSByZWxhdGVkTW9kZWxDbGFzcy5nZXRSZWxhdGlvbnMoKVt0b2tlbl1cbiAgICAgICAgICAgIGlmIChyZWxhdGlvbikge1xuICAgICAgICAgICAgICByZWxhdGVkTW9kZWxDbGFzcyA9IHJlbGF0aW9uLnJlbGF0ZWRNb2RlbENsYXNzXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0UmVzdWx0KClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlbGF0aW9uKSB7XG4gICAgICAgICAgLy8gU3RpbGwgaGVyZT8gRm91bmQgYSByZWxhdGlvbiBhdCB0aGUgZW5kIG9mIHRoZSBkYXRhLXBhdGguXG4gICAgICAgICAgcmV0dXJuIGdldFJlc3VsdChudWxsLCByZWxhdGlvbilcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZ2V0UmVzdWx0KClcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgcmVsYXRlZFF1ZXJ5KHJlbGF0aW9uTmFtZSwgdHJ4KSB7XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL1ZpbmNpdC9vYmplY3Rpb24uanMvaXNzdWVzLzE3MjBcbiAgICByZXR1cm4gc3VwZXIucmVsYXRlZFF1ZXJ5KHJlbGF0aW9uTmFtZSwgdHJ4KS5hbGlhcyhyZWxhdGlvbk5hbWUpXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc3RhdGljIG1vZGlmaWVyTm90Rm91bmQocXVlcnksIG1vZGlmaWVyKSB7XG4gICAgaWYgKGlzU3RyaW5nKG1vZGlmaWVyKSkge1xuICAgICAgaWYgKHF1ZXJ5Lm1vZGVsQ2xhc3MoKS5oYXNTY29wZShtb2RpZmllcikpIHtcbiAgICAgICAgcmV0dXJuIHF1ZXJ5LmFwcGx5U2NvcGUobW9kaWZpZXIpXG4gICAgICB9XG4gICAgICAvLyBOb3cgY2hlY2sgcG9zc2libGUgc2NvcGUgcHJlZml4ZXMgYW5kIGhhbmRsZSB0aGVtOlxuICAgICAgc3dpdGNoIChtb2RpZmllclswXSkge1xuICAgICAgY2FzZSAnXic6IC8vIEVhZ2VyLWFwcGxpZWQgc2NvcGU6XG4gICAgICAgIC8vIEFsd2F5cyBhcHBseSBlYWdlci1zY29wZXMsIGV2ZW4gaWYgdGhlIG1vZGVsIGl0c2VsZiBkb2Vzbid0IGtub3cgaXQuXG4gICAgICAgIC8vIFRoZSBzY29wZSBtYXkgc3RpbGwgYmUga25vd24gaW4gZWFnZXItbG9hZGVkIHJlbGF0aW9ucy5cbiAgICAgICAgLy8gTm90ZTogYGFwcGx5U2NvcGUoKWAgd2lsbCBoYW5kbGUgdGhlICdeJyBzaWduLlxuICAgICAgICByZXR1cm4gcXVlcnkuYXBwbHlTY29wZShtb2RpZmllcilcbiAgICAgIGNhc2UgJy0nOiAvLyBJZ25vcmUgc2NvcGU6XG4gICAgICAgIHJldHVybiBxdWVyeS5pZ25vcmVTY29wZShtb2RpZmllci5zbGljZSgxKSlcbiAgICAgIGNhc2UgJyMnOiAvLyBTZWxlY3QgY29sdW1uOlxuICAgICAgICByZXR1cm4gcXVlcnkuc2VsZWN0KG1vZGlmaWVyLnNsaWNlKDEpKVxuICAgICAgfVxuICAgIH1cbiAgICBzdXBlci5tb2RpZmllck5vdEZvdW5kKHF1ZXJ5LCBtb2RpZmllcilcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgY3JlYXRlTm90Rm91bmRFcnJvcihjdHgsIGVycm9yKSB7XG4gICAgcmV0dXJuIG5ldyBOb3RGb3VuZEVycm9yKFxuICAgICAgZXJyb3IgfHwgKFxuICAgICAgICBjdHguYnlJZFxuICAgICAgICAgID8gYCcke3RoaXMubmFtZX0nIG1vZGVsIHdpdGggaWQgJHtjdHguYnlJZH0gbm90IGZvdW5kYFxuICAgICAgICAgIDogYCcke3RoaXMubmFtZX0nIG1vZGVsIG5vdCBmb3VuZGBcbiAgICAgIClcbiAgICApXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc3RhdGljIGNyZWF0ZVZhbGlkYXRvcigpIHtcbiAgICAvLyBVc2UgYSBzaGFyZWQgdmFsaWRhdG9yIHBlciBhcHAsIHNvIG1vZGVsIHNjaGVtYSBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIuXG4gICAgLy8gTk9URTogVGhlIERpdG8gVmFsaWRhdG9yIGNsYXNzIGNyZWF0ZXMgYW5kIG1hbmFnZXMgdGhpcyBzaGFyZWQgT2JqZWN0aW9uXG4gICAgLy8gVmFsaWRhdG9yIGluc3RhbmNlIGZvciB1cywgd2UganVzdCBuZWVkIHRvIHJldHVybiBpdCBoZXJlOlxuICAgIHJldHVybiB0aGlzLmFwcC52YWxpZGF0b3JcbiAgfVxuXG4gIC8vIEBvdmVycmlkZVxuICBzdGF0aWMgY3JlYXRlVmFsaWRhdGlvbkVycm9yKHsgdHlwZSwgbWVzc2FnZSwgZXJyb3JzLCBvcHRpb25zLCBqc29uIH0pIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdNb2RlbFZhbGlkYXRpb24nOlxuICAgICAgcmV0dXJuIHRoaXMuYXBwLmNyZWF0ZVZhbGlkYXRpb25FcnJvcih7XG4gICAgICAgIHR5cGUsXG4gICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgbWVzc2FnZSB8fCBgVGhlIHByb3ZpZGVkIGRhdGEgZm9yIHRoZSAke3RoaXMubmFtZX0gbW9kZWwgaXMgbm90IHZhbGlkYCxcbiAgICAgICAgZXJyb3JzLFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICBqc29uXG4gICAgICB9KVxuICAgIGNhc2UgJ1JlbGF0aW9uRXhwcmVzc2lvbic6XG4gICAgY2FzZSAnVW5hbGxvd2VkUmVsYXRpb24nOlxuICAgICAgcmV0dXJuIG5ldyBSZWxhdGlvbkVycm9yKHsgdHlwZSwgbWVzc2FnZSwgZXJyb3JzIH0pXG4gICAgY2FzZSAnSW52YWxpZEdyYXBoJzpcbiAgICAgIHJldHVybiBuZXcgR3JhcGhFcnJvcih7IHR5cGUsIG1lc3NhZ2UsIGVycm9ycyB9KVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbmV3IFJlc3BvbnNlRXJyb3IoeyB0eXBlLCBtZXNzYWdlLCBlcnJvcnMgfSlcbiAgICB9XG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc3RhdGljIFF1ZXJ5QnVpbGRlciA9IFF1ZXJ5QnVpbGRlclxuXG4gIC8vIGh0dHBzOi8vdmluY2l0LmdpdGh1Yi5pby9vYmplY3Rpb24uanMvYXBpL21vZGVsL3N0YXRpYy1wcm9wZXJ0aWVzLmh0bWwjc3RhdGljLWNsb25lb2JqZWN0YXR0cmlidXRlc1xuICBzdGF0aWMgY2xvbmVPYmplY3RBdHRyaWJ1dGVzID0gZmFsc2VcblxuICAvLyBPbmx5IHBpY2sgcHJvcGVydGllcyBmb3IgZGF0YWJhc2UgSlNPTiB0aGF0IGlzIG1lbnRpb25lZCBpbiB0aGUgc2NoZW1hLlxuICBzdGF0aWMgcGlja0pzb25TY2hlbWFQcm9wZXJ0aWVzID0gdHJ1ZVxuXG4gIC8vIFNlZSBodHRwczovL2dpdHRlci5pbS9WaW5jaXQvb2JqZWN0aW9uLmpzP2F0PTVhODFmODU5Y2U2OGMzYmM3NDc5ZDY1YVxuICBzdGF0aWMgdXNlTGltaXRJbkZpcnN0ID0gdHJ1ZVxuXG4gIHN0YXRpYyBnZXQgZGVmaW5pdGlvbigpIHtcbiAgICAvLyBDaGVjayBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBkZWZpbml0aW9uIG9iamVjdCBmb3IgdGhpcyBjbGFzcyBhbmQgcmV0dXJuIGl0XG4gICAgcmV0dXJuIGdldE1ldGEodGhpcywgJ2RlZmluaXRpb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCBkZWZpbml0aW9uID0ge31cblxuICAgICAgY29uc3Qgc2V0RGVmaW5pdGlvbiA9IChuYW1lLCBwcm9wZXJ0eSkgPT4ge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGVmaW5pdGlvbiwgbmFtZSwge1xuICAgICAgICAgIC4uLnByb3BlcnR5LFxuICAgICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgY29uc3QgZ2V0RGVmaW5pdGlvbiA9IG5hbWUgPT4ge1xuICAgICAgICBsZXQgbW9kZWxDbGFzcyA9IHRoaXNcbiAgICAgICAgLy8gQ29sbGVjdCBhbmNlc3RvciB2YWx1ZXMgZm9yIHByb3BlciBpbmhlcml0YW5jZS5cbiAgICAgICAgLy8gTk9URTogdmFsdWVzIGFyZSBjb2xsZWN0ZWQgaW4gc2VxdWVuY2Ugb2YgaW5oZXJpdGFuY2UsIGZyb20gc3ViLWNsYXNzXG4gICAgICAgIC8vIHRvIHN1cGVyLWNsYXNzLiBUbyBnbyBmcm9tIHN1cGVyLWNsYXNzIHRvIHN1Yi1jbGFzcyB3aGVuIG1lcmdpbmcsXG4gICAgICAgIC8vIGBtZXJnZVJldmVyc2VkKClgIGlzIHVzZWQgdG8gcHJldmVudCB3cm9uZyBvdmVycmlkZXMuXG4gICAgICAgIC8vIGBtZXJnZUFzUmV2ZXJzZWRBcnJheXMoKWAgY2FuIGJlIHVzZWQgdG8ga2VlcCBhcnJheXMgb2YgaW5oZXJpdGVkXG4gICAgICAgIC8vIHZhbHVlcyBwZXIga2V5LCBzZWUgYGRlZmluaXRpb25zLmhvb2tzYC5cbiAgICAgICAgY29uc3QgdmFsdWVzID0gW11cbiAgICAgICAgd2hpbGUgKG1vZGVsQ2xhc3MgIT09IG9iamVjdGlvbi5Nb2RlbCkge1xuICAgICAgICAgIC8vIE9ubHkgY29uc2lkZXIgbW9kZWwgY2xhc3NlcyB0aGF0IGFjdHVhbGx5IGRlZmluZSBgbmFtZWAgcHJvcGVydHkuXG4gICAgICAgICAgaWYgKG5hbWUgaW4gbW9kZWxDbGFzcykge1xuICAgICAgICAgICAgLy8gVXNlIHJlZmxlY3Rpb24gdGhyb3VnaCBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoKSB0byBiZSBhYmxlIHRvXG4gICAgICAgICAgICAvLyBjYWxsIHRoZSBnZXR0ZXIgb24gYHRoaXNgIHJhdGhlciB0aGFuIG9uIGBtb2RlbENsYXNzYC4gVGhpcyBjYW5cbiAgICAgICAgICAgIC8vIGJlIHVzZWQgdG8gcHJvdmlkZSBhYnN0cmFjdCBiYXNlLWNsYXNzZXMgYW5kIGhhdmUgdGhlbSBjcmVhdGVcbiAgICAgICAgICAgIC8vIHRoZWlyIHJlbGF0aW9ucyBmb3IgYHRoaXNgIGluc2lkZSBgZ2V0IHJlbGF0aW9ucygpYCBhY2Nlc3NvcnMuXG4gICAgICAgICAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtb2RlbENsYXNzLCBuYW1lKVxuICAgICAgICAgICAgaWYgKGRlc2MpIHtcbiAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBkZXNjLmdldD8uY2FsbCh0aGlzKSB8fCBkZXNjLnZhbHVlXG4gICAgICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHZhbHVlKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG1vZGVsQ2xhc3MgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YobW9kZWxDbGFzcylcbiAgICAgICAgfVxuICAgICAgICAvLyBUbyBwcmV2ZW50IGVuZGxlc3MgcmVjdXJzaW9uIHdpdGggaW50ZXJkZXBlbmRlbnQgY2FsbHMgcmVsYXRlZCB0b1xuICAgICAgICAvLyBwcm9wZXJ0aWVzLCBvdmVycmlkZSBkZWZpbml0aW9uIGJlZm9yZSBjYWxsaW5nIGhhbmRsZXIoKTpcbiAgICAgICAgc2V0RGVmaW5pdGlvbihuYW1lLCB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHZhbHVlOiB7fVxuICAgICAgICB9KVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IG1lcmdlZCA9IGRlZmluaXRpb25zW25hbWVdLmNhbGwodGhpcywgdmFsdWVzKVxuICAgICAgICAgIC8vIE9uY2UgY2FsY3VsYXRlZCwgb3ZlcnJpZGUgZ2V0dGVyIHdpdGggZmluYWwgbWVyZ2VkIHZhbHVlLlxuICAgICAgICAgIHNldERlZmluaXRpb24obmFtZSwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBtZXJnZWRcbiAgICAgICAgICB9KVxuICAgICAgICAgIHJldHVybiBtZXJnZWRcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTW9kZWxFcnJvcih0aGlzLCBlcnJvci5tZXNzYWdlKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIElmIG5vIGRlZmluaXRpb24gb2JqZWN0IHdhcyBkZWZpbmVkIHlldCwgY3JlYXRlIG9uZSB3aXRoIGFjY2Vzc29ycyBmb3JcbiAgICAgIC8vIGVhY2ggZW50cnkgaW4gYGRlZmluaXRpb25zYC4gRWFjaCBvZiB0aGVzZSBnZXR0ZXJzIHdoZW4gY2FsbGVkIG1lcmdlXG4gICAgICAvLyBkZWZpbml0aW9ucyB1cCB0aGUgaW5oZXJpdGFuY2UgY2hhaW4gYW5kIHN0b3JlIHRoZSBtZXJnZWQgcmVzdWx0IGluXG4gICAgICAvLyBgbW9kZWxDbGFzcy5kZWZpbml0aW9uW25hbWVdYCBmb3IgZnVydGhlciBjYWNoaW5nLlxuICAgICAgZm9yIChjb25zdCBuYW1lIGluIGRlZmluaXRpb25zKSB7XG4gICAgICAgIHNldERlZmluaXRpb24obmFtZSwge1xuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICBnZXQ6ICgpID0+IGdldERlZmluaXRpb24obmFtZSlcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWZpbml0aW9uXG4gICAgfSlcbiAgfVxuXG4gIC8vIEhvb2tzXG5cbiAgJGVtaXQoZXZlbnQsIC4uLmFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5lbWl0KGV2ZW50LCB0aGlzLCAuLi5hcmdzKVxuICB9XG5cbiAgc3RhdGljIGJlZm9yZUZpbmQoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYmVmb3JlOmZpbmQnLCBhcmdzKVxuICB9XG5cbiAgc3RhdGljIGFmdGVyRmluZChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VtaXRTdGF0aWNIb29rKCdhZnRlcjpmaW5kJywgYXJncylcbiAgfVxuXG4gIHN0YXRpYyBiZWZvcmVJbnNlcnQoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYmVmb3JlOmluc2VydCcsIGFyZ3MpXG4gIH1cblxuICBzdGF0aWMgYWZ0ZXJJbnNlcnQoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYWZ0ZXI6aW5zZXJ0JywgYXJncylcbiAgfVxuXG4gIHN0YXRpYyBiZWZvcmVVcGRhdGUoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYmVmb3JlOnVwZGF0ZScsIGFyZ3MpXG4gIH1cblxuICBzdGF0aWMgYWZ0ZXJVcGRhdGUoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYWZ0ZXI6dXBkYXRlJywgYXJncylcbiAgfVxuXG4gIHN0YXRpYyBiZWZvcmVEZWxldGUoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYmVmb3JlOmRlbGV0ZScsIGFyZ3MpXG4gIH1cblxuICBzdGF0aWMgYWZ0ZXJEZWxldGUoYXJncykge1xuICAgIHJldHVybiB0aGlzLl9lbWl0U3RhdGljSG9vaygnYWZ0ZXI6ZGVsZXRlJywgYXJncylcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBfZW1pdFN0YXRpY0hvb2soZXZlbnQsIG9yaWdpbmFsQXJncykge1xuICAgIGNvbnN0IGxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzKGV2ZW50KVxuICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gU3RhdGljIGhvb2tzIGFyZSBlbWl0dGVkIGluIHNlcXVlbmNlIChidXQgZWFjaCBldmVudCBjYW4gYmUgYXN5bmMpLCBhbmRcbiAgICAgIC8vIHJlc3VsdHMgYXJlIHBhc3NlZCB0aHJvdWdoIGFuZCByZXR1cm5lZCBpbiB0aGUgZW5kLlxuICAgICAgbGV0IHsgcmVzdWx0IH0gPSBvcmlnaW5hbEFyZ3NcbiAgICAgIC8vIFRoZSByZXN1bHQgb2YgYW55IGV2ZW50IGhhbmRsZXIgd2lsbCBvdmVycmlkZSBgYXJncy5yZXN1bHRgIGluIHRoZSBjYWxsXG4gICAgICAvLyBvZiB0aGUgbmV4dCBoYW5kbGVyIGluIHNlcXVlbmNlLiBBcyBgU3RhdGljSG9va0FyZ3VtZW50c2AgaW4gT2JqZWN0aW9uXG4gICAgICAvLyBpcyBwcml2YXRlLCB1c2UgYSBKUyBpbmhlcml0YW5jZSB0cmljayBoZXJlIHRvIG92ZXJyaWRlIGBhcmdzLnJlc3VsdGA6XG4gICAgICBjb25zdCBhcmdzID0gT2JqZWN0LmNyZWF0ZShvcmlnaW5hbEFyZ3MsIHtcbiAgICAgICAgdHlwZToge1xuICAgICAgICAgIHZhbHVlOiBldmVudFxuICAgICAgICB9LFxuICAgICAgICByZXN1bHQ6IHtcbiAgICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgbGlzdGVuZXIuY2FsbCh0aGlzLCBhcmdzKVxuICAgICAgICBpZiAocmVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXN1bHQgPSByZXNcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gVW5mb3J0dW5hdGVseSBgcmVzdWx0YCBpcyBhbHdheXMgYW4gYXJyYXksIGV2ZW4gd2hlbiB0aGUgYWN0dWFsIHJlc3VsdFxuICAgICAgLy8gaXMgYSBtb2RlbCBvYmplY3QuIEF2b2lkIHJldHVybmluZyBpdCB3aGVuIGl0J3Mgbm90IGFjdHVhbGx5IGNoYW5nZWQuXG4gICAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9WaW5jaXQvb2JqZWN0aW9uLmpzL2lzc3Vlcy8xODQyXG4gICAgICBpZiAocmVzdWx0ICE9PSBvcmlnaW5hbEFyZ3MucmVzdWx0KSB7XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBBc3NldHMgaGFuZGxpbmdcblxuICBzdGF0aWMgX3NldHVwQXNzZXRzRXZlbnRzKGFzc2V0cykge1xuICAgIGNvbnN0IGFzc2V0RGF0YVBhdGhzID0gT2JqZWN0LmtleXMoYXNzZXRzKVxuXG4gICAgdGhpcy5vbihbXG4gICAgICAnYmVmb3JlOmluc2VydCcsXG4gICAgICAnYmVmb3JlOnVwZGF0ZScsXG4gICAgICAnYmVmb3JlOmRlbGV0ZSdcbiAgICBdLCBhc3luYyAoeyB0eXBlLCB0cmFuc2FjdGlvbiwgaW5wdXRJdGVtcywgYXNGaW5kUXVlcnkgfSkgPT4ge1xuICAgICAgY29uc3QgYWZ0ZXJJdGVtcyA9IHR5cGUgPT09ICdiZWZvcmU6ZGVsZXRlJ1xuICAgICAgICA/IFtdXG4gICAgICAgIDogaW5wdXRJdGVtc1xuICAgICAgLy8gRmlndXJlIG91dCB3aGljaCBhc3NldCBkYXRhIHBhdGhzIHdoZXJlIGFjdHVhbGx5IHByZXNlbnQgaW4gdGhlXG4gICAgICAvLyBzdWJtaXR0ZWQgZGF0YSwgYW5kIG9ubHkgY29tcGFyZSB0aGVzZS4gQnV0IHdoZW4gZGVsZXRpbmcsIHVzZSBhbGwuXG4gICAgICBjb25zdCBkYXRhUGF0aHMgPSBhZnRlckl0ZW1zLmxlbmd0aCA+IDBcbiAgICAgICAgPyBhc3NldERhdGFQYXRocy5maWx0ZXIoXG4gICAgICAgICAgcGF0aCA9PiBnZXRWYWx1ZUF0QXNzZXREYXRhUGF0aChhZnRlckl0ZW1zWzBdLCBwYXRoKSAhPT0gdW5kZWZpbmVkXG4gICAgICAgIClcbiAgICAgICAgOiBhc3NldERhdGFQYXRoc1xuXG4gICAgICAvLyBgZGF0YVBhdGhzYCB3aWxsIGJlIGVtcHR5IGluIHRoZSBjYXNlIG9mIGFuIHVwZGF0ZS9pbnNlcnQgdGhhdCBkbyBub3RcbiAgICAgIC8vIGFmZmVjdCB0aGUgYXNzZXRzLlxuICAgICAgaWYgKGRhdGFQYXRocy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIC8vIExvYWQgdGhlIG1vZGVsJ3MgYXNzZXQgZmlsZXMgaW4gdGhlaXIgY3VycmVudCBzdGF0ZSBiZWZvcmUgdGhlIHF1ZXJ5IGlzXG4gICAgICAvLyBleGVjdXRlZC5cbiAgICAgIGNvbnN0IGJlZm9yZUl0ZW1zID0gdHlwZSA9PT0gJ2JlZm9yZTppbnNlcnQnXG4gICAgICAgID8gW11cbiAgICAgICAgOiBhd2FpdCBsb2FkQXNzZXREYXRhUGF0aHMoYXNGaW5kUXVlcnkoKSwgZGF0YVBhdGhzKVxuICAgICAgY29uc3QgYmVmb3JlRmlsZXNQZXJEYXRhUGF0aCA9IGdldEZpbGVzUGVyQXNzZXREYXRhUGF0aChcbiAgICAgICAgYmVmb3JlSXRlbXMsXG4gICAgICAgIGRhdGFQYXRoc1xuICAgICAgKVxuICAgICAgY29uc3QgYWZ0ZXJGaWxlc1BlckRhdGFQYXRoID0gZ2V0RmlsZXNQZXJBc3NldERhdGFQYXRoKFxuICAgICAgICBhZnRlckl0ZW1zLFxuICAgICAgICBkYXRhUGF0aHNcbiAgICAgIClcblxuICAgICAgY29uc3QgaW1wb3J0ZWRGaWxlcyA9IFtdXG4gICAgICBjb25zdCBtb2RpZmllZEZpbGVzID0gW11cblxuICAgICAgaWYgKHRyYW5zYWN0aW9uLnJvbGxiYWNrKSB7XG4gICAgICAgIC8vIFByZXZlbnQgd3JvbmcgbWVtb3J5IGxlYWsgZXJyb3IgbWVzc2FnZXMgd2hlbiBpbnN0YWxsaW5nIG1vcmUgdGhhbiAxMFxuICAgICAgICAvLyAncm9sbGJhY2snIGhhbmRsZXJzLCB3aGljaCBjYW4gaGFwcGVuIHdpdGggbW9yZSBjb21wbGV4IHF1ZXJpZXMuXG4gICAgICAgIHRyYW5zYWN0aW9uLnNldE1heExpc3RlbmVycygwKVxuICAgICAgICB0cmFuc2FjdGlvbi5vbigncm9sbGJhY2snLCBhc3luYyBlcnJvciA9PiB7XG4gICAgICAgICAgaWYgKGltcG9ydGVkRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc29sZS5pbmZvKFxuICAgICAgICAgICAgICBgUmVjZWl2ZWQgJyR7ZXJyb3J9JywgcmVtb3ZpbmcgaW1wb3J0ZWQgZmlsZXMgYWdhaW46ICR7XG4gICAgICAgICAgICAgICAgaW1wb3J0ZWRGaWxlcy5tYXAoZmlsZSA9PiBgJyR7ZmlsZS5uYW1lfSdgKVxuICAgICAgICAgICAgICB9YFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICAgIGltcG9ydGVkRmlsZXMubWFwKFxuICAgICAgICAgICAgICAgIGZpbGUgPT4gZmlsZS5zdG9yYWdlLnJlbW92ZUZpbGUoZmlsZSlcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobW9kaWZpZWRGaWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBgbW9kaWZpZWRGaWxlc2Agc2hvdWxkIGJlIHJlc3RvcmVkIGFzIHdlbGwsIGJ1dCB0aGF0J3MgZmFyXG4gICAgICAgICAgICAvLyBmcm9tIHRyaXZpYWwgc2luY2Ugbm8gYmFja3VwIGlzIGtlcHQgaW4gYGhhbmRsZU1vZGlmaWVkQXNzZXRzYFxuICAgICAgICAgICAgY29uc29sZS5pbmZvKFxuICAgICAgICAgICAgICBgVW5hYmxlIHRvIHJlc3RvcmUgdGhlc2UgYWxyZWFkeSBtb2RpZmllZCBmaWxlczogJHtcbiAgICAgICAgICAgICAgICBtb2RpZmllZEZpbGVzLm1hcChmaWxlID0+IGAnJHtmaWxlLm5hbWV9J2ApXG4gICAgICAgICAgICAgIH1gXG4gICAgICAgICAgICApXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGRhdGFQYXRoIG9mIGRhdGFQYXRocykge1xuICAgICAgICBjb25zdCBzdG9yYWdlID0gdGhpcy5hcHAuZ2V0U3RvcmFnZShhc3NldHNbZGF0YVBhdGhdLnN0b3JhZ2UpXG4gICAgICAgIGNvbnN0IGJlZm9yZUZpbGVzID0gYmVmb3JlRmlsZXNQZXJEYXRhUGF0aFtkYXRhUGF0aF0gfHwgW11cbiAgICAgICAgY29uc3QgYWZ0ZXJGaWxlcyA9IGFmdGVyRmlsZXNQZXJEYXRhUGF0aFtkYXRhUGF0aF0gfHwgW11cbiAgICAgICAgY29uc3QgYmVmb3JlQnlLZXkgPSBtYXBGaWxlc0J5S2V5KGJlZm9yZUZpbGVzKVxuICAgICAgICBjb25zdCBhZnRlckJ5S2V5ID0gbWFwRmlsZXNCeUtleShhZnRlckZpbGVzKVxuICAgICAgICBjb25zdCByZW1vdmVkRmlsZXMgPSBiZWZvcmVGaWxlcy5maWx0ZXIoZmlsZSA9PiAhYWZ0ZXJCeUtleVtmaWxlLmtleV0pXG4gICAgICAgIGNvbnN0IGFkZGVkRmlsZXMgPSBhZnRlckZpbGVzLmZpbHRlcihmaWxlID0+ICFiZWZvcmVCeUtleVtmaWxlLmtleV0pXG4gICAgICAgIC8vIEFsc28gaGFuZGxlIG1vZGlmaWVkIGZpbGVzLCB3aGljaCBhcmUgZmlsZXMgd2hlcmUgdGhlIGRhdGEgcHJvcGVydHlcbiAgICAgICAgLy8gaXMgY2hhbmdlZCBiZWZvcmUgdXBkYXRlIC8gcGF0Y2gsIG1lYW50aW5nIHRoZSBmaWxlIGlzIGNoYW5nZWQuXG4gICAgICAgIC8vIE5PVEU6IFRoaXMgd2lsbCBjaGFuZ2UgdGhlIGNvbnRlbnQgZm9yIGFsbCB0aGUgcmVmZXJlbmNlcyB0byBpdCxcbiAgICAgICAgLy8gYW5kIHRodXMgc2hvdWxkIG9ubHkgcmVhbGx5IGJlIHVzZWQgd2hlbiB0aGVyZSdzIG9ubHkgb25lIHJlZmVyZW5jZS5cbiAgICAgICAgY29uc3QgbW9kaWZpZWRGaWxlcyA9IGFmdGVyRmlsZXMuZmlsdGVyKFxuICAgICAgICAgIGZpbGUgPT4gZmlsZS5kYXRhICYmIGJlZm9yZUJ5S2V5W2ZpbGUua2V5XVxuICAgICAgICApXG4gICAgICAgIGltcG9ydGVkRmlsZXMucHVzaChcbiAgICAgICAgICAuLi5hd2FpdCB0aGlzLmFwcC5oYW5kbGVBZGRkZWRBbmRSZW1vdmVkQXNzZXRzKFxuICAgICAgICAgICAgc3RvcmFnZSxcbiAgICAgICAgICAgIGFkZGVkRmlsZXMsXG4gICAgICAgICAgICByZW1vdmVkRmlsZXMsXG4gICAgICAgICAgICB0cmFuc2FjdGlvblxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgICBtb2RpZmllZEZpbGVzLnB1c2goXG4gICAgICAgICAgLi4uYXdhaXQgdGhpcy5hcHAuaGFuZGxlTW9kaWZpZWRBc3NldHMoXG4gICAgICAgICAgICBzdG9yYWdlLFxuICAgICAgICAgICAgbW9kaWZpZWRGaWxlcyxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICB9XG4gICAgfSlcbiAgfVxufVxuXG5FdmVudEVtaXR0ZXIubWl4aW4oTW9kZWwpXG5LbmV4SGVscGVyLm1peGluKE1vZGVsKVxuLy8gRXhwb3NlIGEgc2VsZWN0aW9uIG9mIFF1ZXJ5QnVpbGRlciBtZXRob2RzIGFzIHN0YXRpYyBtZXRob2RzIG9uIG1vZGVsIGNsYXNzZXNcblF1ZXJ5QnVpbGRlci5taXhpbihNb2RlbClcblxuY29uc3QgbWV0YU1hcCA9IG5ldyBXZWFrTWFwKClcblxuZnVuY3Rpb24gZ2V0TWV0YShtb2RlbENsYXNzLCBrZXksIHZhbHVlKSB7XG4gIGxldCBtZXRhID0gbWV0YU1hcC5nZXQobW9kZWxDbGFzcylcbiAgaWYgKCFtZXRhKSB7XG4gICAgbWV0YU1hcC5zZXQobW9kZWxDbGFzcywgbWV0YSA9IHt9KVxuICB9XG4gIGlmICghKGtleSBpbiBtZXRhKSkge1xuICAgIG1ldGFba2V5XSA9IGlzRnVuY3Rpb24odmFsdWUpID8gdmFsdWUoKSA6IHZhbHVlXG4gIH1cbiAgcmV0dXJuIG1ldGFba2V5XVxufVxuXG5mdW5jdGlvbiBsb2FkQXNzZXREYXRhUGF0aHMocXVlcnksIGRhdGFQYXRocykge1xuICByZXR1cm4gZGF0YVBhdGhzLnJlZHVjZShcbiAgICAocXVlcnksIGRhdGFQYXRoKSA9PiBxdWVyeS5sb2FkRGF0YVBhdGgoZGF0YVBhdGgpLFxuICAgIHF1ZXJ5XG4gIClcbn1cblxuZnVuY3Rpb24gZ2V0VmFsdWVBdEFzc2V0RGF0YVBhdGgoaXRlbSwgcGF0aCkge1xuICByZXR1cm4gZ2V0VmFsdWVBdERhdGFQYXRoKGl0ZW0sIHBhdGgsICgpID0+IHVuZGVmaW5lZClcbn1cblxuZnVuY3Rpb24gZ2V0RmlsZXNQZXJBc3NldERhdGFQYXRoKGl0ZW1zLCBkYXRhUGF0aHMpIHtcbiAgcmV0dXJuIGRhdGFQYXRocy5yZWR1Y2UoXG4gICAgKGFsbEZpbGVzLCBkYXRhUGF0aCkgPT4ge1xuICAgICAgYWxsRmlsZXNbZGF0YVBhdGhdID0gYXNBcnJheShpdGVtcykucmVkdWNlKFxuICAgICAgICAoZmlsZXMsIGl0ZW0pID0+IHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gYXNBcnJheShnZXRWYWx1ZUF0QXNzZXREYXRhUGF0aChpdGVtLCBkYXRhUGF0aCkpXG4gICAgICAgICAgLy8gVXNlIGZsYXR0ZW4oKSBhcyBkYXRhUGF0aCBtYXkgY29udGFpbiB3aWxkY2FyZHMsIHJlc3VsdGluZyBpblxuICAgICAgICAgIC8vIG5lc3RlZCBmaWxlcyBhcnJheXMuXG4gICAgICAgICAgZmlsZXMucHVzaCguLi5mbGF0dGVuKGRhdGEpLmZpbHRlcihmaWxlID0+ICEhZmlsZSkpXG4gICAgICAgICAgcmV0dXJuIGZpbGVzXG4gICAgICAgIH0sXG4gICAgICAgIFtdXG4gICAgICApXG4gICAgICByZXR1cm4gYWxsRmlsZXNcbiAgICB9LFxuICAgIHt9XG4gIClcbn1cblxuZnVuY3Rpb24gbWFwRmlsZXNCeUtleShmaWxlcykge1xuICByZXR1cm4gZmlsZXMucmVkdWNlKFxuICAgIChtYXAsIGZpbGUpID0+IHtcbiAgICAgIG1hcFtmaWxlLmtleV0gPSBmaWxlXG4gICAgICByZXR1cm4gbWFwXG4gICAgfSxcbiAgICB7fVxuICApXG59XG4iXX0=
|