@ditojs/server 0.275.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +25 -43
- package/src/app/Application.js +105 -111
- package/src/app/Validator.js +6 -3
- package/src/app/index.js +2 -2
- package/src/cli/db/createMigration.js +1 -1
- package/src/cli/db/index.js +7 -7
- package/src/cli/db/listAssetConfig.js +1 -1
- package/src/cli/db/reset.js +1 -1
- package/src/cli/index.js +14 -5
- package/src/controllers/AdminController.js +181 -158
- package/src/controllers/CollectionController.js +8 -29
- package/src/controllers/Controller.js +71 -76
- package/src/controllers/ControllerAction.js +39 -17
- package/src/controllers/MemberAction.js +2 -2
- package/src/controllers/ModelController.js +4 -4
- package/src/controllers/RelationController.js +3 -3
- package/src/controllers/{UserController.js → UsersController.js} +8 -13
- package/src/controllers/index.js +5 -5
- package/src/decorators/action.js +3 -3
- package/src/decorators/authorize.js +1 -1
- package/src/decorators/index.js +6 -6
- package/src/decorators/parameters.js +1 -1
- package/src/decorators/returns.js +1 -1
- package/src/decorators/scope.js +1 -1
- package/src/decorators/transacted.js +1 -1
- package/src/errors/AssetError.js +1 -1
- package/src/errors/AuthenticationError.js +1 -1
- package/src/errors/AuthorizationError.js +1 -1
- package/src/errors/ControllerError.js +1 -1
- package/src/errors/DatabaseError.js +12 -3
- package/src/errors/GraphError.js +1 -1
- package/src/errors/ModelError.js +1 -1
- package/src/errors/NotFoundError.js +1 -1
- package/src/errors/NotImplementedError.js +1 -1
- package/src/errors/QueryBuilderError.js +1 -1
- package/src/errors/RelationError.js +1 -1
- package/src/errors/ValidationError.js +1 -1
- package/src/errors/WrappedError.js +1 -1
- package/src/errors/index.js +14 -14
- package/src/graph/DitoGraphProcessor.js +2 -1
- package/src/graph/graph.js +1 -1
- package/src/graph/index.js +3 -3
- package/src/index.js +11 -9
- package/src/lib/index.js +2 -2
- package/src/middleware/createTransaction.js +1 -1
- package/src/middleware/findRoute.js +3 -2
- package/src/middleware/handleConnectMiddleware.js +88 -0
- package/src/middleware/handleError.js +1 -1
- package/src/middleware/handleRoute.js +3 -3
- package/src/middleware/index.js +8 -7
- package/src/mixins/AssetMixin.js +1 -1
- package/src/mixins/UserMixin.js +1 -1
- package/src/mixins/index.js +4 -4
- package/src/models/AssetModel.js +2 -2
- package/src/models/Model.js +16 -12
- package/src/models/RelationAccessor.js +1 -1
- package/src/models/SessionModel.js +2 -2
- package/src/models/TimeStampedModel.js +2 -2
- package/src/models/UserModel.js +2 -2
- package/src/models/definitions/assets.js +1 -1
- package/src/models/definitions/filters.js +57 -44
- package/src/models/definitions/hooks.js +1 -1
- package/src/models/definitions/index.js +9 -9
- package/src/models/definitions/modifiers.js +1 -1
- package/src/models/definitions/options.js +1 -1
- package/src/models/definitions/properties.js +2 -2
- package/src/models/definitions/relations.js +1 -1
- package/src/models/definitions/schema.js +1 -1
- package/src/models/definitions/scopes.js +2 -2
- package/src/models/index.js +5 -5
- package/src/query/QueryBuilder.js +5 -5
- package/src/query/QueryFilters.js +50 -50
- package/src/query/QueryParameters.js +2 -2
- package/src/query/index.js +3 -3
- package/src/schema/formats/index.js +2 -2
- package/src/schema/index.js +4 -4
- package/src/schema/keywords/_relate.js +1 -1
- package/src/schema/keywords/index.js +12 -12
- package/src/schema/properties.test.js +1 -1
- package/src/schema/relations.js +1 -1
- package/src/schema/relations.test.js +2 -2
- package/src/services/index.js +1 -1
- package/src/storage/DiskStorage.js +1 -1
- package/src/storage/S3Storage.js +4 -4
- package/src/storage/Storage.js +1 -1
- package/src/storage/index.js +4 -4
- package/src/utils/function.test.js +1 -1
- package/src/utils/handler.js +17 -0
- package/src/utils/index.js +8 -7
- package/src/utils/object.test.js +1 -1
- package/lib/app/Application.js +0 -961
- package/lib/app/SessionStore.js +0 -40
- package/lib/app/Validator.js +0 -355
- package/lib/app/index.js +0 -26
- package/lib/cli/console.js +0 -175
- package/lib/cli/db/createMigration.js +0 -237
- package/lib/cli/db/index.js +0 -66
- package/lib/cli/db/listAssetConfig.js +0 -16
- package/lib/cli/db/migrate.js +0 -15
- package/lib/cli/db/reset.js +0 -27
- package/lib/cli/db/rollback.js +0 -15
- package/lib/cli/db/seed.js +0 -104
- package/lib/cli/db/unlock.js +0 -15
- package/lib/cli/index.js +0 -90
- package/lib/controllers/AdminController.js +0 -258
- package/lib/controllers/CollectionController.js +0 -263
- package/lib/controllers/Controller.js +0 -462
- package/lib/controllers/ControllerAction.js +0 -276
- package/lib/controllers/MemberAction.js +0 -22
- package/lib/controllers/ModelController.js +0 -64
- package/lib/controllers/RelationController.js +0 -82
- package/lib/controllers/UserController.js +0 -98
- package/lib/controllers/index.js +0 -50
- package/lib/decorators/action.js +0 -14
- package/lib/decorators/authorize.js +0 -13
- package/lib/decorators/index.js +0 -58
- package/lib/decorators/parameters.js +0 -35
- package/lib/decorators/returns.js +0 -26
- package/lib/decorators/scope.js +0 -14
- package/lib/decorators/transacted.js +0 -12
- package/lib/errors/AssetError.js +0 -19
- package/lib/errors/AuthenticationError.js +0 -19
- package/lib/errors/AuthorizationError.js +0 -19
- package/lib/errors/ControllerError.js +0 -24
- package/lib/errors/DatabaseError.js +0 -27
- package/lib/errors/GraphError.js +0 -19
- package/lib/errors/ModelError.js +0 -24
- package/lib/errors/NotFoundError.js +0 -19
- package/lib/errors/NotImplementedError.js +0 -19
- package/lib/errors/QueryBuilderError.js +0 -19
- package/lib/errors/RelationError.js +0 -36
- package/lib/errors/ResponseError.js +0 -46
- package/lib/errors/ValidationError.js +0 -19
- package/lib/errors/WrappedError.js +0 -24
- package/lib/errors/index.js +0 -122
- package/lib/graph/DitoGraphProcessor.js +0 -185
- package/lib/graph/expression.js +0 -76
- package/lib/graph/graph.js +0 -300
- package/lib/graph/index.js +0 -34
- package/lib/index.js +0 -82
- package/lib/lib/EventEmitter.js +0 -76
- package/lib/lib/KnexHelper.js +0 -40
- package/lib/lib/index.js +0 -26
- package/lib/middleware/attachLogger.js +0 -16
- package/lib/middleware/createTransaction.js +0 -36
- package/lib/middleware/findRoute.js +0 -35
- package/lib/middleware/handleError.js +0 -26
- package/lib/middleware/handleRoute.js +0 -29
- package/lib/middleware/handleUser.js +0 -36
- package/lib/middleware/index.js +0 -66
- package/lib/middleware/logRequests.js +0 -122
- package/lib/mixins/AssetMixin.js +0 -81
- package/lib/mixins/SessionMixin.js +0 -22
- package/lib/mixins/TimeStampedMixin.js +0 -47
- package/lib/mixins/UserMixin.js +0 -151
- package/lib/mixins/index.js +0 -42
- package/lib/models/AssetModel.js +0 -12
- package/lib/models/Model.js +0 -953
- package/lib/models/RelationAccessor.js +0 -41
- package/lib/models/SessionModel.js +0 -12
- package/lib/models/TimeStampedModel.js +0 -12
- package/lib/models/UserModel.js +0 -12
- package/lib/models/definitions/assets.js +0 -11
- package/lib/models/definitions/filters.js +0 -101
- package/lib/models/definitions/hooks.js +0 -11
- package/lib/models/definitions/index.js +0 -38
- package/lib/models/definitions/modifiers.js +0 -11
- package/lib/models/definitions/options.js +0 -11
- package/lib/models/definitions/properties.js +0 -87
- package/lib/models/definitions/relations.js +0 -11
- package/lib/models/definitions/schema.js +0 -11
- package/lib/models/definitions/scopes.js +0 -51
- package/lib/models/index.js +0 -50
- package/lib/query/QueryBuilder.js +0 -745
- package/lib/query/QueryFilters.js +0 -82
- package/lib/query/QueryParameters.js +0 -77
- package/lib/query/Registry.js +0 -40
- package/lib/query/index.js +0 -34
- package/lib/schema/formats/_empty.js +0 -10
- package/lib/schema/formats/_required.js +0 -10
- package/lib/schema/formats/index.js +0 -26
- package/lib/schema/index.js +0 -49
- package/lib/schema/keywords/_computed.js +0 -11
- package/lib/schema/keywords/_foreign.js +0 -11
- package/lib/schema/keywords/_hidden.js +0 -11
- package/lib/schema/keywords/_index.js +0 -11
- package/lib/schema/keywords/_instanceof.js +0 -49
- package/lib/schema/keywords/_primary.js +0 -11
- package/lib/schema/keywords/_range.js +0 -26
- package/lib/schema/keywords/_relate.js +0 -19
- package/lib/schema/keywords/_specificType.js +0 -11
- package/lib/schema/keywords/_unique.js +0 -11
- package/lib/schema/keywords/_unsigned.js +0 -11
- package/lib/schema/keywords/_validate.js +0 -80
- package/lib/schema/keywords/index.js +0 -106
- package/lib/schema/properties.js +0 -227
- package/lib/schema/properties.test.js +0 -573
- package/lib/schema/relations.js +0 -274
- package/lib/schema/relations.test.js +0 -155
- package/lib/services/Service.js +0 -34
- package/lib/services/index.js +0 -18
- package/lib/storage/AssetFile.js +0 -97
- package/lib/storage/DiskStorage.js +0 -125
- package/lib/storage/S3Storage.js +0 -171
- package/lib/storage/Storage.js +0 -209
- package/lib/storage/index.js +0 -34
- package/lib/utils/decorator.js +0 -16
- package/lib/utils/deprecate.js +0 -46
- package/lib/utils/emitter.js +0 -13
- package/lib/utils/function.js +0 -14
- package/lib/utils/function.test.js +0 -49
- package/lib/utils/index.js +0 -66
- package/lib/utils/json.js +0 -9
- package/lib/utils/object.js +0 -92
- package/lib/utils/object.test.js +0 -65
- package/lib/utils/scope.js +0 -14
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.CollectionController = void 0;
|
|
5
|
-
|
|
6
|
-
require("core-js/modules/esnext.async-iterator.find.js");
|
|
7
|
-
|
|
8
|
-
require("core-js/modules/esnext.iterator.constructor.js");
|
|
9
|
-
|
|
10
|
-
require("core-js/modules/esnext.iterator.find.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.map.js");
|
|
17
|
-
|
|
18
|
-
require("core-js/modules/esnext.iterator.map.js");
|
|
19
|
-
|
|
20
|
-
var _Controller = require("./Controller");
|
|
21
|
-
|
|
22
|
-
var _errors = require("../errors");
|
|
23
|
-
|
|
24
|
-
var _utils = require("@ditojs/utils");
|
|
25
|
-
|
|
26
|
-
class CollectionController extends _Controller.Controller {
|
|
27
|
-
constructor(app, namespace) {
|
|
28
|
-
super(app, namespace);
|
|
29
|
-
this.collection = this.toCoreActions({
|
|
30
|
-
async find(ctx, modify) {
|
|
31
|
-
const result = await this.execute(ctx, (query, trx) => {
|
|
32
|
-
query.find(ctx.query, this.allowParam).modify(getModify(modify, trx));
|
|
33
|
-
return this.isOneToOne ? query.first() : query;
|
|
34
|
-
});
|
|
35
|
-
return result || null;
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
async delete(ctx, modify) {
|
|
39
|
-
const count = await this.execute(ctx, (query, trx) => query.ignoreScope().find(ctx.query, this.allowParam).modify(query => this.isOneToOne && query.throwIfNotFound()).modify(getModify(modify, trx)).modify(query => this.unrelate ? query.unrelate() : query.delete()));
|
|
40
|
-
return {
|
|
41
|
-
count
|
|
42
|
-
};
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
async insert(ctx, modify) {
|
|
46
|
-
const result = this.relate ? await this.execute(ctx, (query, trx) => query.patchDitoGraphAndFetch(ctx.request.body, {
|
|
47
|
-
relate: true
|
|
48
|
-
}).modify(getModify(modify, trx))) : await this.executeAndFetch('insert', ctx, modify);
|
|
49
|
-
ctx.status = 201;
|
|
50
|
-
|
|
51
|
-
if ((0, _utils.isObject)(result)) {
|
|
52
|
-
ctx.set('Location', this.getUrl('collection', result.id));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return result;
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
async update(ctx, modify) {
|
|
59
|
-
return this.executeAndFetch('update', ctx, modify);
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
async patch(ctx, modify) {
|
|
63
|
-
return this.executeAndFetch('patch', ctx, modify);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
});
|
|
67
|
-
this.member = this.toCoreActions({
|
|
68
|
-
async find(ctx, modify) {
|
|
69
|
-
return this.execute(ctx, (query, trx) => query.findById(ctx.memberId).find(ctx.query, this.allowParam).throwIfNotFound().modify(getModify(modify, trx)));
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
async delete(ctx, modify) {
|
|
73
|
-
const count = await this.execute(ctx, (query, trx) => query.ignoreScope().findById(ctx.memberId).find(ctx.query, this.allowParam).throwIfNotFound().modify(getModify(modify, trx)).modify(query => this.unrelate ? query.unrelate() : query.delete()));
|
|
74
|
-
return {
|
|
75
|
-
count
|
|
76
|
-
};
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
async update(ctx, modify) {
|
|
80
|
-
return this.executeAndFetchById('update', ctx, modify);
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
async patch(ctx, modify) {
|
|
84
|
-
return this.executeAndFetchById('patch', ctx, modify);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
});
|
|
88
|
-
this.modelClass = null;
|
|
89
|
-
this.isOneToOne = false;
|
|
90
|
-
this.relate = false;
|
|
91
|
-
this.unrelate = false;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
setup(isRoot) {
|
|
95
|
-
super.setup(isRoot, false);
|
|
96
|
-
this.idParam = this.level ? `id${this.level}` : 'id';
|
|
97
|
-
this.graph = !!this.graph;
|
|
98
|
-
this.transacted = !!this.transacted;
|
|
99
|
-
this.scope = this.scope || null;
|
|
100
|
-
this.collection = this.setupActions('collection');
|
|
101
|
-
this.member = this.isOneToOne ? {} : this.setupActions('member');
|
|
102
|
-
this.idValidator = new this.modelClass();
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
setupAction(type, actions, name, handler, authorize, verb, path) {
|
|
106
|
-
if (name in actionToVerb) {
|
|
107
|
-
verb = actionToVerb[name];
|
|
108
|
-
path = '';
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return super.setupAction(type, actions, name, handler, authorize, verb, path);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
setupAssets() {
|
|
115
|
-
const {
|
|
116
|
-
modelClass
|
|
117
|
-
} = this;
|
|
118
|
-
|
|
119
|
-
if (this.assets === true) {
|
|
120
|
-
this.assets = modelClass.definition.assets || null;
|
|
121
|
-
} else if ((0, _utils.isObject)(this.assets)) {
|
|
122
|
-
this.assets = { ...modelClass.definition.assets,
|
|
123
|
-
...this.assets
|
|
124
|
-
};
|
|
125
|
-
} else {
|
|
126
|
-
this.assets = null;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return super.setupAssets();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
getPath(type, path) {
|
|
133
|
-
return type === 'member' ? path ? `:${this.idParam}/${path}` : `:${this.idParam}` : path;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
extendContext(ctx, object) {
|
|
137
|
-
return Object.setPrototypeOf(object, ctx);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
getMemberId(ctx) {
|
|
141
|
-
return this.validateId(ctx.params[this.idParam]);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
getContextWithMemberId(ctx, memberId = this.getMemberId(ctx)) {
|
|
145
|
-
return this.extendContext(ctx, {
|
|
146
|
-
memberId
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
getCollectionIds(ctx) {
|
|
151
|
-
const idProperty = this.modelClass.getIdProperty();
|
|
152
|
-
const getId = (0, _utils.isArray)(idProperty) ? model => idProperty.reduce((id, key) => {
|
|
153
|
-
id.push(model[key]);
|
|
154
|
-
return id;
|
|
155
|
-
}, []) : model => model[idProperty];
|
|
156
|
-
return (0, _utils.asArray)(ctx.request.body).map(model => this.validateId(getId(model)));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
getIds(ctx) {
|
|
160
|
-
const {
|
|
161
|
-
type
|
|
162
|
-
} = ctx.action;
|
|
163
|
-
return type === 'member' ? [this.getMemberId(ctx)] : type === 'collection' ? this.getCollectionIds(ctx) : [];
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
validateId(id) {
|
|
167
|
-
const reference = this.modelClass.getReference(id);
|
|
168
|
-
this.idValidator.$validate(reference, {
|
|
169
|
-
coerceTypes: true,
|
|
170
|
-
patch: true
|
|
171
|
-
});
|
|
172
|
-
const values = Object.values(reference);
|
|
173
|
-
return values.length > 1 ? values : values[0];
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async getMember(ctx, base = this, {
|
|
177
|
-
query = {},
|
|
178
|
-
modify = null,
|
|
179
|
-
forUpdate = false
|
|
180
|
-
} = {}) {
|
|
181
|
-
return this.member.find.call(this, this.extendContext(ctx, {
|
|
182
|
-
query
|
|
183
|
-
}), (query, trx) => {
|
|
184
|
-
this.setupQuery(query, base);
|
|
185
|
-
query.modify(modify);
|
|
186
|
-
|
|
187
|
-
if (forUpdate) {
|
|
188
|
-
if (!trx) {
|
|
189
|
-
throw new _errors.ControllerError(this, 'Using `forUpdate()` without a transaction is invalid');
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
query.forUpdate();
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
query(trx) {
|
|
198
|
-
return this.setupQuery(this.modelClass.query(trx));
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
setupQuery(query, base = this) {
|
|
202
|
-
const {
|
|
203
|
-
scope
|
|
204
|
-
} = base;
|
|
205
|
-
const {
|
|
206
|
-
allowScope,
|
|
207
|
-
allowFilter
|
|
208
|
-
} = this;
|
|
209
|
-
|
|
210
|
-
const asAllowArray = value => value === false ? [] : (0, _utils.asArray)(value);
|
|
211
|
-
|
|
212
|
-
if (allowScope !== undefined && allowScope !== true) {
|
|
213
|
-
query.allowScope(...asAllowArray(allowScope), ...(0, _utils.asArray)(scope));
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (allowFilter !== undefined && allowFilter !== true) {
|
|
217
|
-
query.allowFilter(...asAllowArray(allowFilter));
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (scope) {
|
|
221
|
-
query.withScope(...(0, _utils.asArray)(scope));
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return query;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
async execute() {}
|
|
228
|
-
|
|
229
|
-
async executeAndFetch(action, ctx, modify, body = ctx.request.body) {
|
|
230
|
-
const name = `${action}${this.graph ? 'DitoGraph' : ''}AndFetch`;
|
|
231
|
-
return this.execute(ctx, (query, trx) => query[name](body).modify(getModify(modify, trx)));
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
async executeAndFetchById(action, ctx, modify, body = ctx.request.body) {
|
|
235
|
-
const name = `${action}${this.graph ? 'DitoGraph' : ''}AndFetchById`;
|
|
236
|
-
return this.execute(ctx, (query, trx) => query[name](ctx.memberId, body).throwIfNotFound().modify(getModify(modify, trx)));
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
toCoreActions(actions) {
|
|
240
|
-
for (const action of Object.values(actions)) {
|
|
241
|
-
action.core = true;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
actions.$core = true;
|
|
245
|
-
return actions;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
exports.CollectionController = CollectionController;
|
|
251
|
-
|
|
252
|
-
function getModify(modify, trx) {
|
|
253
|
-
return modify ? query => modify(query, trx) : null;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const actionToVerb = {
|
|
257
|
-
find: 'get',
|
|
258
|
-
delete: 'delete',
|
|
259
|
-
insert: 'post',
|
|
260
|
-
update: 'put',
|
|
261
|
-
patch: 'patch'
|
|
262
|
-
};
|
|
263
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb250cm9sbGVycy9Db2xsZWN0aW9uQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJDb2xsZWN0aW9uQ29udHJvbGxlciIsIkNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFwcCIsIm5hbWVzcGFjZSIsImNvbGxlY3Rpb24iLCJ0b0NvcmVBY3Rpb25zIiwiZmluZCIsImN0eCIsIm1vZGlmeSIsInJlc3VsdCIsImV4ZWN1dGUiLCJxdWVyeSIsInRyeCIsImFsbG93UGFyYW0iLCJnZXRNb2RpZnkiLCJpc09uZVRvT25lIiwiZmlyc3QiLCJkZWxldGUiLCJjb3VudCIsImlnbm9yZVNjb3BlIiwidGhyb3dJZk5vdEZvdW5kIiwidW5yZWxhdGUiLCJpbnNlcnQiLCJyZWxhdGUiLCJwYXRjaERpdG9HcmFwaEFuZEZldGNoIiwicmVxdWVzdCIsImJvZHkiLCJleGVjdXRlQW5kRmV0Y2giLCJzdGF0dXMiLCJzZXQiLCJnZXRVcmwiLCJpZCIsInVwZGF0ZSIsInBhdGNoIiwibWVtYmVyIiwiZmluZEJ5SWQiLCJtZW1iZXJJZCIsImV4ZWN1dGVBbmRGZXRjaEJ5SWQiLCJtb2RlbENsYXNzIiwic2V0dXAiLCJpc1Jvb3QiLCJpZFBhcmFtIiwibGV2ZWwiLCJncmFwaCIsInRyYW5zYWN0ZWQiLCJzY29wZSIsInNldHVwQWN0aW9ucyIsImlkVmFsaWRhdG9yIiwic2V0dXBBY3Rpb24iLCJ0eXBlIiwiYWN0aW9ucyIsIm5hbWUiLCJoYW5kbGVyIiwiYXV0aG9yaXplIiwidmVyYiIsInBhdGgiLCJhY3Rpb25Ub1ZlcmIiLCJzZXR1cEFzc2V0cyIsImFzc2V0cyIsImRlZmluaXRpb24iLCJnZXRQYXRoIiwiZXh0ZW5kQ29udGV4dCIsIm9iamVjdCIsIk9iamVjdCIsInNldFByb3RvdHlwZU9mIiwiZ2V0TWVtYmVySWQiLCJ2YWxpZGF0ZUlkIiwicGFyYW1zIiwiZ2V0Q29udGV4dFdpdGhNZW1iZXJJZCIsImdldENvbGxlY3Rpb25JZHMiLCJpZFByb3BlcnR5IiwiZ2V0SWRQcm9wZXJ0eSIsImdldElkIiwibW9kZWwiLCJyZWR1Y2UiLCJrZXkiLCJwdXNoIiwibWFwIiwiZ2V0SWRzIiwiYWN0aW9uIiwicmVmZXJlbmNlIiwiZ2V0UmVmZXJlbmNlIiwiJHZhbGlkYXRlIiwiY29lcmNlVHlwZXMiLCJ2YWx1ZXMiLCJsZW5ndGgiLCJnZXRNZW1iZXIiLCJiYXNlIiwiZm9yVXBkYXRlIiwiY2FsbCIsInNldHVwUXVlcnkiLCJDb250cm9sbGVyRXJyb3IiLCJhbGxvd1Njb3BlIiwiYWxsb3dGaWx0ZXIiLCJhc0FsbG93QXJyYXkiLCJ2YWx1ZSIsInVuZGVmaW5lZCIsIndpdGhTY29wZSIsImNvcmUiLCIkY29yZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUdPLE1BQU1BLG9CQUFOLFNBQW1DQyxzQkFBbkMsQ0FBOEM7QUFDbkRDLEVBQUFBLFdBQVcsQ0FBQ0MsR0FBRCxFQUFNQyxTQUFOLEVBQWlCO0FBQzFCLFVBQU1ELEdBQU4sRUFBV0MsU0FBWDtBQUQwQixTQXFNNUJDLFVBck00QixHQXFNZixLQUFLQyxhQUFMLENBQW1CO0FBQzlCLFlBQU1DLElBQU4sQ0FBV0MsR0FBWCxFQUFnQkMsTUFBaEIsRUFBd0I7QUFDdEIsY0FBTUMsTUFBTSxHQUFHLE1BQU0sS0FBS0MsT0FBTCxDQUFhSCxHQUFiLEVBQWtCLENBQUNJLEtBQUQsRUFBUUMsR0FBUixLQUFnQjtBQUNyREQsVUFBQUEsS0FBSyxDQUFDTCxJQUFOLENBQVdDLEdBQUcsQ0FBQ0ksS0FBZixFQUFzQixLQUFLRSxVQUEzQixFQUF1Q0wsTUFBdkMsQ0FBOENNLFNBQVMsQ0FBQ04sTUFBRCxFQUFTSSxHQUFULENBQXZEO0FBQ0EsaUJBQU8sS0FBS0csVUFBTCxHQUFrQkosS0FBSyxDQUFDSyxLQUFOLEVBQWxCLEdBQWtDTCxLQUF6QztBQUNELFNBSG9CLENBQXJCO0FBT0EsZUFBT0YsTUFBTSxJQUFJLElBQWpCO0FBQ0QsT0FWNkI7O0FBWTlCLFlBQU1RLE1B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LEdBQWEsV0FBYixHQUEyQixFQUFHLGNBQXZEO0FBQ0EsV0FBTyxLQUFLakMsT0FBTCxDQUFhSCxHQUFiLEVBQWtCLENBQUNJLEtBQUQsRUFBUUMsR0FBUixLQUN2QkQsS0FBSyxDQUFDd0MsSUFBRCxDQUFMLENBQVk1QyxHQUFHLENBQUM2QixRQUFoQixFQUEwQlYsSUFBMUIsRUFDR04sZUFESCxHQUVHWixNQUZILENBRVVNLFNBQVMsQ0FBQ04sTUFBRCxFQUFTSSxHQUFULENBRm5CLENBREssQ0FBUDtBQUtEOztBQUVEUCxFQUFBQSxhQUFhLENBQUM2QyxPQUFELEVBQVU7QUFHckIsU0FBSyxNQUFNNkIsTUFBWCxJQUFxQmhCLE1BQU0sQ0FBQ3FCLE1BQVAsQ0FBY2xDLE9BQWQsQ0FBckIsRUFBNkM7QUFHM0M2QixNQUFBQSxNQUFNLENBQUNtQixJQUFQLEdBQWMsSUFBZDtBQUNEOztBQUNEaEQsSUFBQUEsT0FBTyxDQUFDaUQsS0FBUixHQUFnQixJQUFoQjtBQUNBLFdBQU9qRCxPQUFQO0FBQ0Q7O0FBcE1rRDs7OztBQXFSckQsU0FBU3BDLFNBQVQsQ0FBbUJOLE1BQW5CLEVBQTJCSSxHQUEzQixFQUFnQztBQUM5QixTQUFPSixNQUFNLEdBQ1RHLEtBQUssSUFBSUgsTUFBTSxDQUFDRyxLQUFELEVBQVFDLEdBQVIsQ0FETixHQUVULElBRko7QUFHRDs7QUFFRCxNQUFNNEMsWUFBWSxHQUFHO0FBQ25CbEQsRUFBQUEsSUFBSSxFQUFFLEtBRGE7QUFFbkJXLEVBQUFBLE1BQU0sRUFBRSxRQUZXO0FBR25CSyxFQUFBQSxNQUFNLEVBQUUsTUFIVztBQUluQlUsRUFBQUEsTUFBTSxFQUFFLEtBSlc7QUFLbkJDLEVBQUFBLEtBQUssRUFBRTtBQUxZLENBQXJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29udHJvbGxlciB9IGZyb20gJy4vQ29udHJvbGxlcidcbmltcG9ydCB7IENvbnRyb2xsZXJFcnJvciB9IGZyb20gJ0AvZXJyb3JzJ1xuaW1wb3J0IHsgaXNPYmplY3QsIGlzQXJyYXksIGFzQXJyYXkgfSBmcm9tICdAZGl0b2pzL3V0aWxzJ1xuXG4vLyBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBNb2RlbENvbnRyb2xsZXIgYW5kIFJlbGF0aW9uQ29udHJvbGxlclxuZXhwb3J0IGNsYXNzIENvbGxlY3Rpb25Db250cm9sbGVyIGV4dGVuZHMgQ29udHJvbGxlciB7XG4gIGNvbnN0cnVjdG9yKGFwcCwgbmFtZXNwYWNlKSB7XG4gICAgc3VwZXIoYXBwLCBuYW1lc3BhY2UpXG4gICAgdGhpcy5tb2RlbENsYXNzID0gbnVsbCAvLyBUbyBiZSBkZWZpbmVkIGJ5IHN1Yi1jbGFzc2VzXG4gICAgdGhpcy5pc09uZVRvT25lID0gZmFsc2VcbiAgICB0aGlzLnJlbGF0ZSA9IGZhbHNlXG4gICAgdGhpcy51bnJlbGF0ZSA9IGZhbHNlXG4gIH1cblxuICBzZXR1cChpc1Jvb3QpIHtcbiAgICBzdXBlci5zZXR1cChpc1Jvb3QsIGZhbHNlKVxuICAgIHRoaXMuaWRQYXJhbSA9IHRoaXMubGV2ZWwgPyBgaWQke3RoaXMubGV2ZWx9YCA6ICdpZCdcbiAgICB0aGlzLmdyYXBoID0gISF0aGlzLmdyYXBoXG4gICAgdGhpcy50cmFuc2FjdGVkID0gISF0aGlzLnRyYW5zYWN0ZWRcbiAgICB0aGlzLnNjb3BlID0gdGhpcy5zY29wZSB8fCBudWxsXG4gICAgdGhpcy5jb2xsZWN0aW9uID0gdGhpcy5zZXR1cEFjdGlvbnMoJ2NvbGxlY3Rpb24nKVxuICAgIHRoaXMubWVtYmVyID0gdGhpcy5pc09uZVRvT25lID8ge30gOiB0aGlzLnNldHVwQWN0aW9ucygnbWVtYmVyJylcbiAgICAvLyBDcmVhdGUgYSBkdW1teSBtb2RlbCBpbnN0YW5jZSB0byB2YWxpZGF0ZSB0aGUgcmVxdWVzdGVkIGlkIGFnYWluc3QuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5ldy1jYXBcbiAgICB0aGlzLmlkVmFsaWRhdG9yID0gbmV3IHRoaXMubW9kZWxDbGFzcygpXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc2V0dXBBY3Rpb24odHlwZSwgYWN0aW9ucywgbmFtZSwgaGFuZGxlciwgYXV0aG9yaXplLCB2ZXJiLCBwYXRoKSB7XG4gICAgLy8gVGhlc2UgZGVmYXVsdCBhY3Rpb25zIGhhcHBlbiBkaXJlY3RseSBvbiB0aGUgY29sbGVjdGlvbiAvIG1lbWJlciByb3V0ZVxuICAgIC8vIGFuZCBhcmUgZGlzdGluZ3Vpc2hlZCBieSB0aGVpciB2ZXJicywgbm90IGJ5IG5lc3RlZCBwYXRocy5cbiAgICBpZiAobmFtZSBpbiBhY3Rpb25Ub1ZlcmIpIHtcbiAgICAgIHZlcmIgPSBhY3Rpb25Ub1ZlcmJbbmFtZV1cbiAgICAgIHBhdGggPSAnJ1xuICAgIH1cbiAgICByZXR1cm4gc3VwZXIuc2V0dXBBY3Rpb24oXG4gICAgICB0eXBlLCBhY3Rpb25zLCBuYW1lLCBoYW5kbGVyLCBhdXRob3JpemUsIHZlcmIsIHBhdGhcbiAgICApXG4gIH1cblxuICAvLyBAb3ZlcnJpZGVcbiAgc2V0dXBBc3NldHMoKSB7XG4gICAgY29uc3QgeyBtb2RlbENsYXNzIH0gPSB0aGlzXG4gICAgaWYgKHRoaXMuYXNzZXRzID09PSB0cnVlKSB7XG4gICAgICB0aGlzLmFzc2V0cyA9IG1vZGVsQ2xhc3MuZGVmaW5pdGlvbi5hc3NldHMgfHwgbnVsbFxuICAgIH0gZWxzZSBpZiAoaXNPYmplY3QodGhpcy5hc3NldHMpKSB7XG4gICAgICAvLyBNZXJnZSBpbiB0aGUgYXNzZXRzIGRlZmluaXRpb24gZnJvbSB0aGUgbW9kZWwgaW50byB0aGUgYXNzZXRzIGNvbmZpZy5cbiAgICAgIC8vIFRoYXQgd2F5LCB3ZSBjYW4gc3RpbGwgdXNlIGBhbGxvd2AgYW5kIGBhdXRob3JpemVgIHRvIGNvbnRyb2xsIHRoZVxuICAgICAgLy8gdXBsb2FkIGFjY2Vzcywgd2hpbGUga2VlcGluZyB0aGUgYXNzZXRzIGRlZmluaXRpb25zIGluIG9uZSBjZW50cmFsXG4gICAgICAvLyBsb2NhdGlvbiBvbiB0aGUgbW9kZWwuXG4gICAgICB0aGlzLmFzc2V0cyA9IHtcbiAgICAgICAgLi4ubW9kZWxDbGFzcy5kZWZpbml0aW9uLmFzc2V0cyxcbiAgICAgICAgLi4udGhpcy5hc3NldHNcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hc3NldHMgPSBudWxsXG4gICAgfVxuICAgIC8vIE5vdyBjYWxsIGBzdXBlci5zZXR1cEFzc2V0cygpYCB3aGljaCBwZXJmb3JtcyB0aGUgdXN1YWwgaW5oZXJpdGFuY2UgL1xuICAgIC8vIGFsbG93IC8gYXV0aG9yaXplIHRyaWNrczpcbiAgICByZXR1cm4gc3VwZXIuc2V0dXBBc3NldHMoKVxuICB9XG5cbiAgLy8gQG92ZXJyaWRlXG4gIGdldFBhdGgodHlwZSwgcGF0aCkge1xuICAgIHJldHVybiB0eXBlID09PSAnbWVtYmVyJ1xuICAgICAgPyBwYXRoID8gYDoke3RoaXMuaWRQYXJhbX0vJHtwYXRofWAgOiBgOiR7dGhpcy5pZFBhcmFtfWBcbiAgICAgIDogcGF0aFxuICB9XG5cbiAgZXh0ZW5kQ29udGV4dChjdHgsIG9iamVjdCkge1xuICAgIC8vIENyZWF0ZSBhIGNvcHkgb2YgYGN0eGAgdGhhdCBpbmhlcml0cyBmcm9tIHRoZSByZWFsIG9uZSwgYnV0IG92ZXJyaWRlc1xuICAgIC8vIHNvbWUgcHJvcGVydGllcyB3aXRoIHRoZSBvbmVzIGZyb20gdGhlIHBhc3NlZCBgb2JqZWN0YC5cbiAgICByZXR1cm4gT2JqZWN0LnNldFByb3RvdHlwZU9mKG9iamVjdCwgY3R4KVxuICB9XG5cbiAgZ2V0TWVtYmVySWQoY3R4KSB7XG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdGVJZChjdHgucGFyYW1zW3RoaXMuaWRQYXJhbV0pXG4gIH1cblxuICBnZXRDb250ZXh0V2l0aE1lbWJlcklkKGN0eCwgbWVtYmVySWQgPSB0aGlzLmdldE1lbWJlcklkKGN0eCkpIHtcbiAgICByZXR1cm4gdGhpcy5leHRlbmRDb250ZXh0KGN0eCwgeyBtZW1iZXJJZCB9KVxuICB9XG5cbiAgZ2V0Q29sbGVjdGlvbklkcyhjdHgpIHtcbiAgICBjb25zdCBpZFByb3BlcnR5ID0gdGhpcy5tb2RlbENsYXNzLmdldElkUHJvcGVydHkoKVxuICAgIC8vIEhhbmRsZSBib3RoIGNvbXBvc2l0ZSBrZXlzIGFuZCBub3JtYWwgb25lcy5cbiAgICBjb25zdCBnZXRJZCA9IGlzQXJyYXkoaWRQcm9wZXJ0eSlcbiAgICAgID8gbW9kZWwgPT4gaWRQcm9wZXJ0eS5yZWR1Y2UoXG4gICAgICAgIChpZCwga2V5KSA9PiB7XG4gICAgICAgICAgaWQucHVzaChtb2RlbFtrZXldKVxuICAgICAgICAgIHJldHVybiBpZFxuICAgICAgICB9LCBbXSlcbiAgICAgIDogbW9kZWwgPT4gbW9kZWxbaWRQcm9wZXJ0eV1cbiAgICByZXR1cm4gYXNBcnJheShjdHgucmVxdWVzdC5ib2R5KS5tYXAobW9kZWwgPT4gdGhpcy52YWxpZGF0ZUlkKGdldElkKG1vZGVsKSkpXG4gIH1cblxuICBnZXRJZHMoY3R4KSB7XG4gICAgLy8gUmV0dXJucyB0aGUgbW9kZWwgaWRzIHRoYXQgdGhpcyByZXF1ZXN0IGNvbmNlcm5zLCByZWFkIGZyb20gdGhlIHBhcmFtXG4gICAgLy8gZm9yIG1lbWJlciBpZHMsIGFuZCBmcm9tIHRoZSBwYXlsb2FkIGZvciBjb2xsZWN0aW9uIGlkczpcbiAgICBjb25zdCB7IHR5cGUgfSA9IGN0eC5hY3Rpb25cbiAgICByZXR1cm4gdHlwZSA9PT0gJ21lbWJlcicgPyBbdGhpcy5nZXRNZW1iZXJJZChjdHgpXVxuICAgICAgOiB0eXBlID09PSAnY29sbGVjdGlvbicgPyB0aGlzLmdldENvbGxlY3Rpb25JZHMoY3R4KVxuICAgICAgOiBbXVxuICB9XG5cbiAgdmFsaWRhdGVJZChpZCkge1xuICAgIGNvbnN0IHJlZmVyZW5jZSA9IHRoaXMubW9kZWxDbGFzcy5nZXRSZWZlcmVuY2UoaWQpXG4gICAgLy8gVGhpcyB2YWxpZGF0ZXMgYW5kIGNvZXJjZXMgYXQgdGhlIHNhbWUgdGltZSwgc28gZXh0cmFjdCB0aGUgY29lcmNlZCBpZFxuICAgIC8vIGZyb20gYHJlZmVyZW5jZWAgYWdhaW4gYWZ0ZXJ3YXJkcy5cbiAgICB0aGlzLmlkVmFsaWRhdG9yLiR2YWxpZGF0ZShyZWZlcmVuY2UsIHtcbiAgICAgIGNvZXJjZVR5cGVzOiB0cnVlLFxuICAgICAgcGF0Y2g6IHRydWVcbiAgICB9KVxuICAgIGNvbnN0IHZhbHVlcyA9IE9iamVjdC52YWx1ZXMocmVmZXJlbmNlKVxuICAgIHJldHVybiB2YWx1ZXMubGVuZ3RoID4gMSA/IHZhbHVlcyA6IHZhbHVlc1swXVxuICB9XG5cbiAgYXN5bmMgZ2V0TWVtYmVyKFxuICAgIGN0eCxcbiAgICBiYXNlID0gdGhpcyxcbiAgICB7IHF1ZXJ5ID0ge30sIG1vZGlmeSA9IG51bGwsIGZvclVwZGF0ZSA9IGZhbHNlIH0gPSB7fVxuICApIHtcbiAgICByZXR1cm4gdGhpcy5tZW1iZXIuZmluZC5jYWxsKFxuICAgICAgdGhpcyxcbiAgICAgIC8vIEV4dGVuZCBgY3R4YCB3aXRoIGEgbmV3IGBxdWVyeWAgb2JqZWN0LCB3aGlsZSBpbmhlcml0aW5nIHRoZSByb3V0ZVxuICAgICAgLy8gcGFyYW1zIGluIGBjdHgucGFyYW1zYCwgc28gZmluaW5nIHRoZSBtZW1iZXIgYnkgaWQgc3RpbGwgd29ya3MuXG4gICAgICB0aGlzLmV4dGVuZENvbnRleHQoY3R4LCB7IHF1ZXJ5IH0pLFxuICAgICAgKHF1ZXJ5LCB0cngpID0+IHtcbiAgICAgICAgdGhpcy5zZXR1cFF1ZXJ5KHF1ZXJ5LCBiYXNlKVxuICAgICAgICBxdWVyeS5tb2RpZnkobW9kaWZ5KVxuICAgICAgICBpZiAoZm9yVXBkYXRlKSB7XG4gICAgICAgICAgaWYgKCF0cngpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBDb250cm9sbGVyRXJyb3IoXG4gICAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICAgICdVc2luZyBgZm9yVXBkYXRlKClgIHdpdGhvdXQgYSB0cmFuc2FjdGlvbiBpcyBpbnZhbGlkJ1xuICAgICAgICAgICAgKVxuICAgICAgICAgIH1cbiAgICAgICAgICBxdWVyeS5mb3JVcGRhdGUoKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgKVxuICB9XG5cbiAgcXVlcnkodHJ4KSB7XG4gICAgcmV0dXJuIHRoaXMuc2V0dXBRdWVyeSh0aGlzLm1vZGVsQ2xhc3MucXVlcnkodHJ4KSlcbiAgfVxuXG4gIHNldHVwUXVlcnkocXVlcnksIGJhc2UgPSB0aGlzKSB7XG4gICAgY29uc3QgeyBzY29wZSB9ID0gYmFzZVxuICAgIGNvbnN0IHsgYWxsb3dTY29wZSwgYWxsb3dGaWx0ZXIgfSA9IHRoaXNcblxuICAgIGNvbnN0IGFzQWxsb3dBcnJheSA9IHZhbHVlID0+IHZhbHVlID09PSBmYWxzZSA/IFtdIDogYXNBcnJheSh2YWx1ZSlcblxuICAgIGlmIChhbGxvd1Njb3BlICE9PSB1bmRlZmluZWQgJiYgYWxsb3dTY29wZSAhPT0gdHJ1ZSkge1xuICAgICAgcXVlcnkuYWxsb3dTY29wZShcbiAgICAgICAgLi4uYXNBbGxvd0FycmF5KGFsbG93U2NvcGUpLFxuICAgICAgICAvLyBBbHNvIGluY2x1ZGUgdGhlIHNjb3BlcyBkZWZpbmVkIGJ5IHNjb3BlIHNvIHRoZXNlIGNhbiBwYXNzIHRocm91Z2guXG4gICAgICAgIC4uLmFzQXJyYXkoc2NvcGUpXG4gICAgICApXG4gICAgfVxuICAgIGlmIChhbGxvd0ZpbHRlciAhPT0gdW5kZWZpbmVkICYmIGFsbG93RmlsdGVyICE9PSB0cnVlKSB7XG4gICAgICBxdWVyeS5hbGxvd0ZpbHRlciguLi5hc0FsbG93QXJyYXkoYWxsb3dGaWx0ZXIpKVxuICAgIH1cbiAgICBpZiAoc2NvcGUpIHtcbiAgICAgIHF1ZXJ5LndpdGhTY29wZSguLi5hc0FycmF5KHNjb3BlKSlcbiAgICB9XG4gICAgcmV0dXJuIHF1ZXJ5XG4gIH1cblxuICBhc3luYyBleGVjdXRlKC8qIGN0eCwgZXhlY3V0ZShxdWVyeSwgdHJ4KSB7fSAqLykge1xuICAgIC8vIERvZXMgbm90aGluZyBpbiBiYXNlIGNsYXNzLlxuICAgIC8vIE92ZXJyaWRlcyBhcmUgaW4gTW9kZWxDb250cm9sbGVyIGFuZCBSZWxhdGlvbkNvbnRyb2xsZXIuXG4gIH1cblxuICBhc3luYyBleGVjdXRlQW5kRmV0Y2goYWN0aW9uLCBjdHgsIG1vZGlmeSwgYm9keSA9IGN0eC5yZXF1ZXN0LmJvZHkpIHtcbiAgICBjb25zdCBuYW1lID0gYCR7YWN0aW9ufSR7dGhpcy5ncmFwaCA/ICdEaXRvR3JhcGgnIDogJyd9QW5kRmV0Y2hgXG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZShjdHgsIChxdWVyeSwgdHJ4KSA9PlxuICAgICAgcXVlcnlbbmFtZV0oYm9keSlcbiAgICAgICAgLm1vZGlmeShnZXRNb2RpZnkobW9kaWZ5LCB0cngpKVxuICAgIClcbiAgfVxuXG4gIGFzeW5jIGV4ZWN1dGVBbmRGZXRjaEJ5SWQoYWN0aW9uLCBjdHgsIG1vZGlmeSwgYm9keSA9IGN0eC5yZXF1ZXN0LmJvZHkpIHtcbiAgICBjb25zdCBuYW1lID0gYCR7YWN0aW9ufSR7dGhpcy5ncmFwaCA/ICdEaXRvR3JhcGgnIDogJyd9QW5kRmV0Y2hCeUlkYFxuICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoY3R4LCAocXVlcnksIHRyeCkgPT5cbiAgICAgIHF1ZXJ5W25hbWVdKGN0eC5tZW1iZXJJZCwgYm9keSlcbiAgICAgICAgLnRocm93SWZOb3RGb3VuZCgpXG4gICAgICAgIC5tb2RpZnkoZ2V0TW9kaWZ5KG1vZGlmeSwgdHJ4KSlcbiAgICApXG4gIH1cblxuICB0b0NvcmVBY3Rpb25zKGFjdGlvbnMpIHtcbiAgICAvLyBNYXJrIGFjdGlvbiBvYmplY3QgYW5kIG1ldGhvZHMgYXMgY29yZSwgc28gYENvbnRyb2xsZXIucHJvY2Vzc1ZhbHVlcygpYFxuICAgIC8vIGNhbiBmaWx0ZXIgY29ycmVjdGx5LlxuICAgIGZvciAoY29uc3QgYWN0aW9uIG9mIE9iamVjdC52YWx1ZXMoYWN0aW9ucykpIHtcbiAgICAgIC8vIE1hcmsgYWN0aW9uIGZ1bmN0aW9ucyBhbHNvLCBzbyBDb250cm9sbGVyQWN0aW9uIGNhbiB1c2UgaXQgdG8gZGV0ZXJtaW5lXG4gICAgICAvLyB2YWx1ZSBmb3IgYHRyYW5zYWN0ZWRgLlxuICAgICAgYWN0aW9uLmNvcmUgPSB0cnVlXG4gICAgfVxuICAgIGFjdGlvbnMuJGNvcmUgPSB0cnVlXG4gICAgcmV0dXJuIGFjdGlvbnNcbiAgfVxuXG4gIGNvbGxlY3Rpb24gPSB0aGlzLnRvQ29yZUFjdGlvbnMoe1xuICAgIGFzeW5jIGZpbmQoY3R4LCBtb2RpZnkpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY3V0ZShjdHgsIChxdWVyeSwgdHJ4KSA9PiB7XG4gICAgICAgIHF1ZXJ5LmZpbmQoY3R4LnF1ZXJ5LCB0aGlzLmFsbG93UGFyYW0pLm1vZGlmeShnZXRNb2RpZnkobW9kaWZ5LCB0cngpKVxuICAgICAgICByZXR1cm4gdGhpcy5pc09uZVRvT25lID8gcXVlcnkuZmlyc3QoKSA6IHF1ZXJ5XG4gICAgICB9KVxuICAgICAgLy8gVGhpcyBtZXRob2QgZG9lc24ndCBhbHdheXMgcmV0dXJuIGFuIGFycmF5OlxuICAgICAgLy8gRm9yIFJlbGF0aW9uQ29udHJvbGxlcnMgd2hlcmUgYGlzT25lVG9PbmVgIGlzIHRydWUsIGl0IGNhbiByZXR1cm5cbiAgICAgIC8vIGB1bmRlZmluZWRgLiBDYXN0IHRvIGBudWxsYCBmb3Igc3VjaCBjYXNlczpcbiAgICAgIHJldHVybiByZXN1bHQgfHwgbnVsbFxuICAgIH0sXG5cbiAgICBhc3luYyBkZWxldGUoY3R4LCBtb2RpZnkpIHtcbiAgICAgIGNvbnN0IGNvdW50ID0gYXdhaXQgdGhpcy5leGVjdXRlKGN0eCwgKHF1ZXJ5LCB0cngpID0+IHF1ZXJ5XG4gICAgICAgIC5pZ25vcmVTY29wZSgpXG4gICAgICAgIC5maW5kKGN0eC5xdWVyeSwgdGhpcy5hbGxvd1BhcmFtKVxuICAgICAgICAubW9kaWZ5KHF1ZXJ5ID0+IHRoaXMuaXNPbmVUb09uZSAmJiBxdWVyeS50aHJvd0lmTm90Rm91bmQoKSlcbiAgICAgICAgLm1vZGlmeShnZXRNb2RpZnkobW9kaWZ5LCB0cngpKVxuICAgICAgICAubW9kaWZ5KHF1ZXJ5ID0+IHRoaXMudW5yZWxhdGUgPyBxdWVyeS51bnJlbGF0ZSgpIDogcXVlcnkuZGVsZXRlKCkpXG4gICAgICApXG4gICAgICByZXR1cm4geyBjb3VudCB9XG4gICAgfSxcblxuICAgIGFzeW5jIGluc2VydChjdHgsIG1vZGlmeSkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5yZWxhdGVcbiAgICAgICAgLy8gVXNlIHBhdGNoRGl0b0dyYXBoQW5kRmV0Y2goKSB0byBoYW5kbGUgcmVsYXRlcyBmb3IgdXMuXG4gICAgICAgID8gYXdhaXQgdGhpcy5leGVjdXRlKGN0eCwgKHF1ZXJ5LCB0cngpID0+IHF1ZXJ5XG4gICAgICAgICAgLnBhdGNoRGl0b0dyYXBoQW5kRmV0Y2goY3R4LnJlcXVlc3QuYm9keSwgeyByZWxhdGU6IHRydWUgfSlcbiAgICAgICAgICAubW9kaWZ5KGdldE1vZGlmeShtb2RpZnksIHRyeCkpXG4gICAgICAgIClcbiAgICAgICAgOiBhd2FpdCB0aGlzLmV4ZWN1dGVBbmRGZXRjaCgnaW5zZXJ0JywgY3R4LCBtb2RpZnkpXG4gICAgICBjdHguc3RhdHVzID0gMjAxXG4gICAgICBpZiAoaXNPYmplY3QocmVzdWx0KSkge1xuICAgICAgICBjdHguc2V0KCdMb2NhdGlvbicsIHRoaXMuZ2V0VXJsKCdjb2xsZWN0aW9uJywgcmVzdWx0LmlkKSlcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHRcbiAgICB9LFxuXG4gICAgYXN5bmMgdXBkYXRlKGN0eCwgbW9kaWZ5KSB7XG4gICAgICByZXR1cm4gdGhpcy5leGVjdXRlQW5kRmV0Y2goJ3VwZGF0ZScsIGN0eCwgbW9kaWZ5KVxuICAgIH0sXG5cbiAgICBhc3luYyBwYXRjaChjdHgsIG1vZGlmeSkge1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZUFuZEZldGNoKCdwYXRjaCcsIGN0eCwgbW9kaWZ5KVxuICAgIH1cbiAgfSlcblxuICBtZW1iZXIgPSB0aGlzLnRvQ29yZUFjdGlvbnMoe1xuICAgIGFzeW5jIGZpbmQoY3R4LCBtb2RpZnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoY3R4LCAocXVlcnksIHRyeCkgPT4gcXVlcnlcbiAgICAgICAgLmZpbmRCeUlkKGN0eC5tZW1iZXJJZClcbiAgICAgICAgLmZpbmQoY3R4LnF1ZXJ5LCB0aGlzLmFsbG93UGFyYW0pXG4gICAgICAgIC50aHJvd0lmTm90Rm91bmQoKVxuICAgICAgICAubW9kaWZ5KGdldE1vZGlmeShtb2RpZnksIHRyeCkpXG4gICAgICApXG4gICAgfSxcblxuICAgIGFzeW5jIGRlbGV0ZShjdHgsIG1vZGlmeSkge1xuICAgICAgY29uc3QgY291bnQgPSBhd2FpdCB0aGlzLmV4ZWN1dGUoY3R4LCAocXVlcnksIHRyeCkgPT4gcXVlcnlcbiAgICAgICAgLmlnbm9yZVNjb3BlKClcbiAgICAgICAgLmZpbmRCeUlkKGN0eC5tZW1iZXJJZClcbiAgICAgICAgLmZpbmQoY3R4LnF1ZXJ5LCB0aGlzLmFsbG93UGFyYW0pXG4gICAgICAgIC50aHJvd0lmTm90Rm91bmQoKVxuICAgICAgICAubW9kaWZ5KGdldE1vZGlmeShtb2RpZnksIHRyeCkpXG4gICAgICAgIC5tb2RpZnkocXVlcnkgPT4gdGhpcy51bnJlbGF0ZSA/IHF1ZXJ5LnVucmVsYXRlKCkgOiBxdWVyeS5kZWxldGUoKSlcbiAgICAgIClcbiAgICAgIHJldHVybiB7IGNvdW50IH1cbiAgICB9LFxuXG4gICAgYXN5bmMgdXBkYXRlKGN0eCwgbW9kaWZ5KSB7XG4gICAgICByZXR1cm4gdGhpcy5leGVjdXRlQW5kRmV0Y2hCeUlkKCd1cGRhdGUnLCBjdHgsIG1vZGlmeSlcbiAgICB9LFxuXG4gICAgYXN5bmMgcGF0Y2goY3R4LCBtb2RpZnkpIHtcbiAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGVBbmRGZXRjaEJ5SWQoJ3BhdGNoJywgY3R4LCBtb2RpZnkpXG4gICAgfVxuICB9KVxufVxuXG5mdW5jdGlvbiBnZXRNb2RpZnkobW9kaWZ5LCB0cngpIHtcbiAgcmV0dXJuIG1vZGlmeVxuICAgID8gcXVlcnkgPT4gbW9kaWZ5KHF1ZXJ5LCB0cngpXG4gICAgOiBudWxsXG59XG5cbmNvbnN0IGFjdGlvblRvVmVyYiA9IHtcbiAgZmluZDogJ2dldCcsXG4gIGRlbGV0ZTogJ2RlbGV0ZScsXG4gIGluc2VydDogJ3Bvc3QnLFxuICB1cGRhdGU6ICdwdXQnLFxuICBwYXRjaDogJ3BhdGNoJ1xufVxuIl19
|