@ragemp-mango/core 2.0.6-beta.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/LICENSE +21 -0
- package/README.md +20 -0
- package/dist/app/constants/index.d.ts +26 -0
- package/dist/app/constants/index.js +49 -0
- package/dist/app/controller/index.d.ts +70 -0
- package/dist/app/controller/index.js +24 -0
- package/dist/app/enums/index.d.ts +27 -0
- package/dist/app/enums/index.js +16 -0
- package/dist/app/index.d.ts +138 -0
- package/dist/app/index.js +132 -0
- package/dist/app/interfaces/index.d.ts +157 -0
- package/dist/app/interfaces/index.js +2 -0
- package/dist/app/module/index.d.ts +27 -0
- package/dist/app/module/index.js +16 -0
- package/dist/app/module-tree/index.d.ts +56 -0
- package/dist/app/module-tree/index.js +25 -0
- package/dist/app/pipeline/index.d.ts +5 -0
- package/dist/app/pipeline/index.js +14 -0
- package/dist/app/services/index.d.ts +37 -0
- package/dist/app/services/index.js +14 -0
- package/dist/app/utils/index.d.ts +16 -0
- package/dist/app/utils/index.js +10 -0
- package/dist/call-handler.interface-DVdaknsB.d.ts +52 -0
- package/dist/chunk-2ADQZWQE.js +170 -0
- package/dist/chunk-6YEWPMZJ.js +69 -0
- package/dist/chunk-73LIJA6X.js +176 -0
- package/dist/chunk-7QVYU63E.js +7 -0
- package/dist/chunk-AO6BXG54.js +139 -0
- package/dist/chunk-CFHBJ5MV.js +1906 -0
- package/dist/chunk-CW7WAA3P.js +1906 -0
- package/dist/chunk-DEPJRTVT.js +1 -0
- package/dist/chunk-DJZCOYB3.js +17 -0
- package/dist/chunk-DXPVUDXD.js +81 -0
- package/dist/chunk-E6IQL4S6.js +40 -0
- package/dist/chunk-HK7QTFPA.js +81 -0
- package/dist/chunk-ITEHLEIP.js +29 -0
- package/dist/chunk-M55YEQ7J.js +1 -0
- package/dist/chunk-PGWRESZG.js +790 -0
- package/dist/chunk-PQK4E654.js +1 -0
- package/dist/chunk-RYOUF322.js +68 -0
- package/dist/chunk-SKPH3K2M.js +570 -0
- package/dist/chunk-TBWHLT75.js +61 -0
- package/dist/constants/index.d.ts +8 -0
- package/dist/constants/index.js +18 -0
- package/dist/controller-Ss0TVrxQ.d.ts +30 -0
- package/dist/custom-decorator.type-BHRvXIGz.d.ts +5 -0
- package/dist/decorators/index.d.ts +90 -0
- package/dist/decorators/index.js +91 -0
- package/dist/enums/index.d.ts +66 -0
- package/dist/enums/index.js +12 -0
- package/dist/errors/index.d.ts +23 -0
- package/dist/errors/index.js +17 -0
- package/dist/event-destination.enum-DT8jJFwR.d.ts +7 -0
- package/dist/event-emmiter.interface-7Ne9W8SM.d.ts +10 -0
- package/dist/event-metadata.interface-CREizDNq.d.ts +89 -0
- package/dist/execution-context-type.enum-fwYPtPvp.d.ts +6 -0
- package/dist/execution-context.interface-DpRN4oVj.d.ts +56 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +190 -0
- package/dist/injectable-options.interface-8Gp9oRY6.d.ts +10 -0
- package/dist/injectable-scope.enum-CjyQMpW2.d.ts +7 -0
- package/dist/injection-token.type-dQTkkP6p.d.ts +5 -0
- package/dist/interfaces/index.d.ts +38 -0
- package/dist/interfaces/index.js +2 -0
- package/dist/logger-service.interface-BGV-o_Fx.d.ts +8 -0
- package/dist/method-param-type.enum-BfrJ8zqa.d.ts +11 -0
- package/dist/module-metadata.interface-B3bn1vqq.d.ts +59 -0
- package/dist/multiplayer-timers.interface-CFDTWwAT.d.ts +22 -0
- package/dist/newable.type-BdhG3MZC.d.ts +5 -0
- package/dist/nullable.type-C-lE7JU4.d.ts +3 -0
- package/dist/pipe-transform.interface-BlzOrUy3.d.ts +14 -0
- package/dist/pipes/index.d.ts +12 -0
- package/dist/pipes/index.js +9 -0
- package/dist/reflectable-decorator.interface-CLOGdtEQ.d.ts +14 -0
- package/dist/rpc-call-options.interface-BJ5mHrvT.d.ts +5 -0
- package/dist/rpc-error.interface-CeaZLqzE.d.ts +6 -0
- package/dist/rpc-metadata.interface-DS-GqgqA.d.ts +11 -0
- package/dist/rpc-result.interface-C758heM0.d.ts +10 -0
- package/dist/schemas/index.d.ts +189 -0
- package/dist/schemas/index.js +39 -0
- package/dist/script-event-handler.interface-B-Th4Ssg.d.ts +24 -0
- package/dist/script-event-handler.interface-vUr_v6tV.d.ts +5 -0
- package/dist/script-rpc-handler.interface-DBpD9-yk.d.ts +8 -0
- package/dist/services/index.d.ts +45 -0
- package/dist/services/index.js +23 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/index.d.ts +16 -0
- package/dist/utils/index.js +32 -0
- package/package.json +133 -0
|
@@ -0,0 +1,1906 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Module,
|
|
3
|
+
ModuleContainer,
|
|
4
|
+
ModuleMetadataReader
|
|
5
|
+
} from "./chunk-73LIJA6X.js";
|
|
6
|
+
import {
|
|
7
|
+
ExecutionContextBase,
|
|
8
|
+
MangoRequestBase,
|
|
9
|
+
MangoResponseBase
|
|
10
|
+
} from "./chunk-AO6BXG54.js";
|
|
11
|
+
import {
|
|
12
|
+
Tree,
|
|
13
|
+
TreeNode
|
|
14
|
+
} from "./chunk-RYOUF322.js";
|
|
15
|
+
import {
|
|
16
|
+
validateControllerOptions,
|
|
17
|
+
validateErrorFilter,
|
|
18
|
+
validateGuard,
|
|
19
|
+
validateInjectableMetadata,
|
|
20
|
+
validateInjectionToken,
|
|
21
|
+
validateInterceptor,
|
|
22
|
+
validateModuleOptions,
|
|
23
|
+
validatePipe
|
|
24
|
+
} from "./chunk-PGWRESZG.js";
|
|
25
|
+
import {
|
|
26
|
+
Controller,
|
|
27
|
+
ControllerEventHandler,
|
|
28
|
+
ControllerFlowHandler,
|
|
29
|
+
ControllerMetadataReader,
|
|
30
|
+
ControllerRPCHandler,
|
|
31
|
+
PipelineHandler
|
|
32
|
+
} from "./chunk-SKPH3K2M.js";
|
|
33
|
+
import {
|
|
34
|
+
APP_ENVIROMENT,
|
|
35
|
+
CONTAINER_OPTIONS,
|
|
36
|
+
ENABLE_SHUTDOWN_HOOKS,
|
|
37
|
+
EXECUTION_CONTEXT_FACTORY,
|
|
38
|
+
GLOBAL_APP_CONTAINER,
|
|
39
|
+
GLOBAL_ERROR_FILTERS,
|
|
40
|
+
GLOBAL_GUARDS,
|
|
41
|
+
GLOBAL_INTERCEPTORS,
|
|
42
|
+
GLOBAL_PIPES,
|
|
43
|
+
INTERNAL_APP_CONTAINER,
|
|
44
|
+
MANGO_REQUEST_FACTORY,
|
|
45
|
+
MANGO_RESPONSE_FACTORY,
|
|
46
|
+
MULTIPLAYER_SERVICE,
|
|
47
|
+
PLUGINS
|
|
48
|
+
} from "./chunk-HK7QTFPA.js";
|
|
49
|
+
import {
|
|
50
|
+
CoreMetadataKey,
|
|
51
|
+
MethodParamType
|
|
52
|
+
} from "./chunk-TBWHLT75.js";
|
|
53
|
+
import {
|
|
54
|
+
LOGGER_SERVICE,
|
|
55
|
+
MODULE_CONTAINER,
|
|
56
|
+
REFLECTOR_SERVICE,
|
|
57
|
+
TIMER_SERVICE
|
|
58
|
+
} from "./chunk-DJZCOYB3.js";
|
|
59
|
+
import {
|
|
60
|
+
ErrorMessage
|
|
61
|
+
} from "./chunk-DXPVUDXD.js";
|
|
62
|
+
import {
|
|
63
|
+
generateRandomId,
|
|
64
|
+
isEmpty,
|
|
65
|
+
isNil,
|
|
66
|
+
isNumber,
|
|
67
|
+
isObject,
|
|
68
|
+
isString
|
|
69
|
+
} from "./chunk-E6IQL4S6.js";
|
|
70
|
+
import {
|
|
71
|
+
__name
|
|
72
|
+
} from "./chunk-7QVYU63E.js";
|
|
73
|
+
|
|
74
|
+
// src/services/reflector.service.ts
|
|
75
|
+
import { injectable as injectable9 } from "inversify";
|
|
76
|
+
|
|
77
|
+
// src/decorators/core/controller.decorator.ts
|
|
78
|
+
import { injectable } from "inversify";
|
|
79
|
+
function Controller2(options) {
|
|
80
|
+
return (target) => {
|
|
81
|
+
if (Reflect.hasMetadata(CoreMetadataKey.Controller, target)) {
|
|
82
|
+
throw new Error(ErrorMessage.DuplicateDecoratorUsage);
|
|
83
|
+
}
|
|
84
|
+
const { valid, value, error } = validateControllerOptions(options);
|
|
85
|
+
if (!valid) throw new Error(error);
|
|
86
|
+
Reflect.defineMetadata(CoreMetadataKey.Controller, value, target);
|
|
87
|
+
return injectable()(target);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
__name(Controller2, "Controller");
|
|
91
|
+
|
|
92
|
+
// src/decorators/core/global.decorator.ts
|
|
93
|
+
function Global() {
|
|
94
|
+
return (target) => {
|
|
95
|
+
Reflect.defineMetadata(CoreMetadataKey.GlobalModule, true, target);
|
|
96
|
+
return target;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
__name(Global, "Global");
|
|
100
|
+
|
|
101
|
+
// src/decorators/core/inject.decorator.ts
|
|
102
|
+
import { inject } from "inversify";
|
|
103
|
+
function Inject(key) {
|
|
104
|
+
return (target, propertyKey, paramIndex) => {
|
|
105
|
+
if (!isNil(key) && !validateInjectionToken(key).valid) {
|
|
106
|
+
throw new Error(ErrorMessage.InvalidInjectionTokenSpecified);
|
|
107
|
+
}
|
|
108
|
+
const token = key ?? Reflect.getMetadata("design:type", target, propertyKey);
|
|
109
|
+
if (!token) {
|
|
110
|
+
throw new Error(ErrorMessage.InjectionTokenNotFound);
|
|
111
|
+
}
|
|
112
|
+
inject(token)(target, propertyKey, paramIndex);
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
__name(Inject, "Inject");
|
|
116
|
+
|
|
117
|
+
// src/decorators/core/injectable.decorator.ts
|
|
118
|
+
import { injectable as injectable2 } from "inversify";
|
|
119
|
+
function Injectable(options) {
|
|
120
|
+
return (target) => {
|
|
121
|
+
if (Reflect.hasMetadata(CoreMetadataKey.Injectable, target)) {
|
|
122
|
+
throw new Error(ErrorMessage.DuplicateDecoratorUsage);
|
|
123
|
+
}
|
|
124
|
+
const { valid, value, error } = validateInjectableMetadata(options);
|
|
125
|
+
if (!valid) throw new Error(error);
|
|
126
|
+
Reflect.defineMetadata(CoreMetadataKey.Injectable, value, target);
|
|
127
|
+
return injectable2()(target);
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
__name(Injectable, "Injectable");
|
|
131
|
+
|
|
132
|
+
// src/decorators/core/module.decorator.ts
|
|
133
|
+
import { injectable as injectable3 } from "inversify";
|
|
134
|
+
function Module2(options) {
|
|
135
|
+
return (target) => {
|
|
136
|
+
if (Reflect.hasMetadata(CoreMetadataKey.Module, target)) {
|
|
137
|
+
throw new Error(ErrorMessage.DuplicateDecoratorUsage);
|
|
138
|
+
}
|
|
139
|
+
const { valid, value, error } = validateModuleOptions(options);
|
|
140
|
+
if (!valid) throw new Error(error);
|
|
141
|
+
Reflect.defineMetadata(CoreMetadataKey.Module, value, target);
|
|
142
|
+
return injectable3()(target);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
__name(Module2, "Module");
|
|
146
|
+
|
|
147
|
+
// src/decorators/core/optional.decorator.ts
|
|
148
|
+
import { optional } from "inversify";
|
|
149
|
+
function Optional() {
|
|
150
|
+
return (target, propertyKey, paramIndex) => {
|
|
151
|
+
return optional()(target, propertyKey, paramIndex);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
__name(Optional, "Optional");
|
|
155
|
+
|
|
156
|
+
// src/decorators/core/set-metadata.decorator.ts
|
|
157
|
+
function SetMetadata(key, value) {
|
|
158
|
+
const decoratorFactory = /* @__PURE__ */ __name((target, _method, descriptor) => {
|
|
159
|
+
if (descriptor) {
|
|
160
|
+
Reflect.defineMetadata(key, value, descriptor.value);
|
|
161
|
+
return descriptor;
|
|
162
|
+
}
|
|
163
|
+
Reflect.defineMetadata(key, value, target);
|
|
164
|
+
return target;
|
|
165
|
+
}, "decoratorFactory");
|
|
166
|
+
decoratorFactory.KEY = key;
|
|
167
|
+
return decoratorFactory;
|
|
168
|
+
}
|
|
169
|
+
__name(SetMetadata, "SetMetadata");
|
|
170
|
+
|
|
171
|
+
// src/decorators/errors/catch.decorator.ts
|
|
172
|
+
function Catch(...exceptions) {
|
|
173
|
+
return (target) => {
|
|
174
|
+
if (Reflect.hasMetadata(CoreMetadataKey.Catch, target)) {
|
|
175
|
+
throw new Error(ErrorMessage.DuplicateDecoratorUsage);
|
|
176
|
+
}
|
|
177
|
+
const duplicates = exceptions.filter((exception, index) => exceptions.indexOf(exception) !== index);
|
|
178
|
+
if (duplicates.length) {
|
|
179
|
+
throw new Error(ErrorMessage.ExceptionHandlingConflict);
|
|
180
|
+
}
|
|
181
|
+
Reflect.defineMetadata(CoreMetadataKey.Catch, exceptions, target);
|
|
182
|
+
return target;
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
__name(Catch, "Catch");
|
|
186
|
+
|
|
187
|
+
// src/decorators/errors/use-filters.decorator.ts
|
|
188
|
+
function UseFilters(...filters) {
|
|
189
|
+
return (target, method, descriptor) => {
|
|
190
|
+
const validatedFilters = [];
|
|
191
|
+
for (const filter of filters) {
|
|
192
|
+
const { valid, value, error } = validateErrorFilter(filter);
|
|
193
|
+
if (!valid) throw new Error(error);
|
|
194
|
+
validatedFilters.push(value);
|
|
195
|
+
}
|
|
196
|
+
if (!isNil(descriptor) && !isNil(descriptor.value)) {
|
|
197
|
+
if (filters.length === 0) {
|
|
198
|
+
throw new Error(ErrorMessage.AtLeastOneFilterRequired);
|
|
199
|
+
}
|
|
200
|
+
const methodFilters = Reflect.getMetadata(CoreMetadataKey.ErrorFilters, target.constructor, method) || [];
|
|
201
|
+
if (!isNil(methodFilters.find((filter) => filters.includes(filter)))) {
|
|
202
|
+
throw new Error(ErrorMessage.DuplicateErrorFilterDetected);
|
|
203
|
+
}
|
|
204
|
+
Reflect.defineMetadata(CoreMetadataKey.ErrorFilters, [
|
|
205
|
+
...validatedFilters,
|
|
206
|
+
...methodFilters
|
|
207
|
+
], target.constructor, method);
|
|
208
|
+
return descriptor;
|
|
209
|
+
}
|
|
210
|
+
if (filters.length === 0) {
|
|
211
|
+
throw new Error(ErrorMessage.AtLeastOneFilterRequired);
|
|
212
|
+
}
|
|
213
|
+
const classFilters = Reflect.getMetadata(CoreMetadataKey.ErrorFilters, target) || [];
|
|
214
|
+
if (!isNil(classFilters.find((filter) => filters.includes(filter)))) {
|
|
215
|
+
throw new Error(ErrorMessage.DuplicateErrorFilterDetected);
|
|
216
|
+
}
|
|
217
|
+
Reflect.defineMetadata(CoreMetadataKey.ErrorFilters, [
|
|
218
|
+
...validatedFilters,
|
|
219
|
+
...classFilters
|
|
220
|
+
], target);
|
|
221
|
+
return target;
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
__name(UseFilters, "UseFilters");
|
|
225
|
+
|
|
226
|
+
// src/app/module-tree/app-runtime.ts
|
|
227
|
+
import { inject as inject2, injectable as injectable4, optional as optional2 } from "inversify";
|
|
228
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
229
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
230
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
231
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
232
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
233
|
+
}
|
|
234
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
235
|
+
function _ts_metadata(k, v) {
|
|
236
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
237
|
+
}
|
|
238
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
239
|
+
var AppRuntime = class {
|
|
240
|
+
static {
|
|
241
|
+
__name(this, "AppRuntime");
|
|
242
|
+
}
|
|
243
|
+
eventHandler;
|
|
244
|
+
rpcHandler;
|
|
245
|
+
globalGuards;
|
|
246
|
+
globalInterceptors;
|
|
247
|
+
globalPipes;
|
|
248
|
+
globalErrorFilters;
|
|
249
|
+
loggerService;
|
|
250
|
+
enableShutdownHooks;
|
|
251
|
+
async boot(resolvedTree) {
|
|
252
|
+
await resolvedTree.asyncTraverse(async (node) => {
|
|
253
|
+
const startTime = Date.now();
|
|
254
|
+
const module = node.value;
|
|
255
|
+
module.instance = module.container.get(module.metadata.classRef);
|
|
256
|
+
module.controllers.forEach((controller) => controller.instance = module.container.get(controller.metadata.classRef));
|
|
257
|
+
[
|
|
258
|
+
...module.metadata.internalProviders,
|
|
259
|
+
...module.metadata.externalProviders
|
|
260
|
+
].forEach(([token]) => module.container.get(token));
|
|
261
|
+
this.loggerService.log(`~lw~Module ~lb~${module.metadata.classRef.name} ~lw~loaded ~lk~(${Date.now() - startTime}ms)`);
|
|
262
|
+
await this.runLifecycleMethod(module, "onModuleInit");
|
|
263
|
+
});
|
|
264
|
+
await this.runLifecycleMethods(resolvedTree, "onAppBootstrap");
|
|
265
|
+
resolvedTree.traverse((node) => {
|
|
266
|
+
const module = node.value;
|
|
267
|
+
module.controllers.forEach((controller) => {
|
|
268
|
+
const time = Date.now();
|
|
269
|
+
this.registerTimers(controller);
|
|
270
|
+
this.registerListeners(controller);
|
|
271
|
+
this.loggerService.log(`~lw~Controller ~lc~${controller.metadata.classRef.name} ~lw~timers and listeners registered ~lk~(${Date.now() - time}ms)`);
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
async shutdown(resolvedTree) {
|
|
276
|
+
if (this.enableShutdownHooks) {
|
|
277
|
+
await this.runLifecycleMethods(resolvedTree, "onModuleDestroy");
|
|
278
|
+
await this.runLifecycleMethods(resolvedTree, "beforeAppShutdown");
|
|
279
|
+
}
|
|
280
|
+
await resolvedTree.asyncTraverse(async (node) => {
|
|
281
|
+
const module = node.value;
|
|
282
|
+
module.controllers.forEach((controller) => {
|
|
283
|
+
const timerService = controller.owner.container.get(TIMER_SERVICE);
|
|
284
|
+
timerService.everyticks.forEach((timer) => timer.destroy());
|
|
285
|
+
timerService.intervals.forEach((timer) => timer.destroy());
|
|
286
|
+
timerService.timeouts.forEach((timer) => timer.destroy());
|
|
287
|
+
timerService.crons.forEach((cron) => cron.stop());
|
|
288
|
+
controller.eventHandlers.forEach((handler) => handler.destroy());
|
|
289
|
+
controller.rpcHandlers.forEach((handler) => handler.destroy());
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
if (this.enableShutdownHooks) {
|
|
293
|
+
await this.runLifecycleMethods(resolvedTree, "onAppShutdown");
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
registerListeners(controller) {
|
|
297
|
+
const module = controller.owner;
|
|
298
|
+
controller.metadata.events.forEach((event) => {
|
|
299
|
+
const guards = [
|
|
300
|
+
...this.globalGuards,
|
|
301
|
+
...module.metadata.guards,
|
|
302
|
+
...controller.metadata.guards,
|
|
303
|
+
...event.guards
|
|
304
|
+
];
|
|
305
|
+
const interceptors = [
|
|
306
|
+
...this.globalInterceptors,
|
|
307
|
+
...module.metadata.interceptors,
|
|
308
|
+
...controller.metadata.interceptors,
|
|
309
|
+
...event.interceptors
|
|
310
|
+
];
|
|
311
|
+
const pipes = [
|
|
312
|
+
...this.globalPipes,
|
|
313
|
+
...module.metadata.pipes,
|
|
314
|
+
...controller.metadata.pipes,
|
|
315
|
+
...event.pipes
|
|
316
|
+
];
|
|
317
|
+
const mappedErrorFilters = this.mapErrorFilters([
|
|
318
|
+
...this.globalErrorFilters,
|
|
319
|
+
...module.metadata.errorFilters,
|
|
320
|
+
...controller.metadata.errorFilters,
|
|
321
|
+
...event.errorFilters
|
|
322
|
+
]);
|
|
323
|
+
const handler = this.eventHandler.registerEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event);
|
|
324
|
+
controller.eventHandlers.push(handler);
|
|
325
|
+
});
|
|
326
|
+
controller.metadata.rpcs.forEach(async (rpc) => {
|
|
327
|
+
const guards = [
|
|
328
|
+
...this.globalGuards,
|
|
329
|
+
...module.metadata.guards,
|
|
330
|
+
...controller.metadata.guards,
|
|
331
|
+
...rpc.guards
|
|
332
|
+
];
|
|
333
|
+
const interceptors = [
|
|
334
|
+
...this.globalInterceptors,
|
|
335
|
+
...module.metadata.interceptors,
|
|
336
|
+
...controller.metadata.interceptors,
|
|
337
|
+
...rpc.interceptors
|
|
338
|
+
];
|
|
339
|
+
const pipes = [
|
|
340
|
+
...this.globalPipes,
|
|
341
|
+
...module.metadata.pipes,
|
|
342
|
+
...controller.metadata.pipes,
|
|
343
|
+
...rpc.pipes
|
|
344
|
+
];
|
|
345
|
+
const mappedErrorFilters = this.mapErrorFilters([
|
|
346
|
+
...this.globalErrorFilters,
|
|
347
|
+
...module.metadata.errorFilters,
|
|
348
|
+
...controller.metadata.errorFilters,
|
|
349
|
+
...rpc.errorFilters
|
|
350
|
+
]);
|
|
351
|
+
const handler = await this.rpcHandler.registerRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc);
|
|
352
|
+
controller.rpcHandlers.push(handler);
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
registerTimers(controller) {
|
|
356
|
+
const timerService = controller.owner.container.get(TIMER_SERVICE);
|
|
357
|
+
controller.metadata.timers.forEach((timer) => {
|
|
358
|
+
if (timer.type === "cron") {
|
|
359
|
+
timerService.createCronJob(controller.instance[timer.method].bind(controller.instance), timer.options);
|
|
360
|
+
} else if (timer.type === "everytick") {
|
|
361
|
+
timerService.createEveryTick(controller.instance[timer.method].bind(controller.instance), timer.name);
|
|
362
|
+
} else if (timer.type === "interval") {
|
|
363
|
+
timerService.createInterval(controller.instance[timer.method].bind(controller.instance), timer.options.timeout, timer.name);
|
|
364
|
+
} else if (timer.type === "timeout") {
|
|
365
|
+
timerService.createTimeout(controller.instance[timer.method].bind(controller.instance), timer.options.timeout, timer.name);
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
mapErrorFilters(errorFilters) {
|
|
370
|
+
const filterMap = [];
|
|
371
|
+
for (const filter of errorFilters) {
|
|
372
|
+
const errors = Reflect.getMetadata(CoreMetadataKey.Catch, filter) ?? [];
|
|
373
|
+
if (errors.length === 0) {
|
|
374
|
+
errors.push("MANGO_ANY_ERROR");
|
|
375
|
+
}
|
|
376
|
+
for (const error of errors) {
|
|
377
|
+
if (!isNil(filterMap.find((filterError) => filterError[0] === error))) {
|
|
378
|
+
this.loggerService.error("An error occurred while trying to map error filters.");
|
|
379
|
+
throw new Error(ErrorMessage.ErrorAlreadyHandledByFilter);
|
|
380
|
+
}
|
|
381
|
+
filterMap.push([
|
|
382
|
+
error,
|
|
383
|
+
filter
|
|
384
|
+
]);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return filterMap;
|
|
388
|
+
}
|
|
389
|
+
async runLifecycleMethods(resolvedTree, method) {
|
|
390
|
+
return resolvedTree.asyncTraverse(async (node) => await this.runLifecycleMethod(node.value, method));
|
|
391
|
+
}
|
|
392
|
+
async runLifecycleMethod(module, method) {
|
|
393
|
+
await Promise.all(module.controllers.map(async (controller) => {
|
|
394
|
+
if (!isObject(controller.instance) || isNil(controller.instance[method])) return;
|
|
395
|
+
await controller.instance[method]();
|
|
396
|
+
}));
|
|
397
|
+
await Promise.all([
|
|
398
|
+
...module.metadata.internalProviders,
|
|
399
|
+
...module.metadata.externalProviders
|
|
400
|
+
].map(async ([token]) => {
|
|
401
|
+
const providerInstance = module.container.get(token);
|
|
402
|
+
if (!isObject(providerInstance) || isNil(providerInstance[method])) return;
|
|
403
|
+
await providerInstance[method]();
|
|
404
|
+
}));
|
|
405
|
+
if (!isObject(module.instance) || isNil(module.instance[method])) return;
|
|
406
|
+
await module.instance[method]();
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
_ts_decorate([
|
|
410
|
+
inject2(ControllerEventHandler),
|
|
411
|
+
_ts_metadata("design:type", typeof ControllerEventHandler === "undefined" ? Object : ControllerEventHandler)
|
|
412
|
+
], AppRuntime.prototype, "eventHandler", void 0);
|
|
413
|
+
_ts_decorate([
|
|
414
|
+
inject2(ControllerRPCHandler),
|
|
415
|
+
_ts_metadata("design:type", typeof ControllerRPCHandler === "undefined" ? Object : ControllerRPCHandler)
|
|
416
|
+
], AppRuntime.prototype, "rpcHandler", void 0);
|
|
417
|
+
_ts_decorate([
|
|
418
|
+
inject2(GLOBAL_GUARDS),
|
|
419
|
+
_ts_metadata("design:type", Array)
|
|
420
|
+
], AppRuntime.prototype, "globalGuards", void 0);
|
|
421
|
+
_ts_decorate([
|
|
422
|
+
inject2(GLOBAL_INTERCEPTORS),
|
|
423
|
+
_ts_metadata("design:type", Array)
|
|
424
|
+
], AppRuntime.prototype, "globalInterceptors", void 0);
|
|
425
|
+
_ts_decorate([
|
|
426
|
+
inject2(GLOBAL_PIPES),
|
|
427
|
+
_ts_metadata("design:type", Array)
|
|
428
|
+
], AppRuntime.prototype, "globalPipes", void 0);
|
|
429
|
+
_ts_decorate([
|
|
430
|
+
inject2(GLOBAL_ERROR_FILTERS),
|
|
431
|
+
_ts_metadata("design:type", Array)
|
|
432
|
+
], AppRuntime.prototype, "globalErrorFilters", void 0);
|
|
433
|
+
_ts_decorate([
|
|
434
|
+
inject2(LOGGER_SERVICE),
|
|
435
|
+
_ts_metadata("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
|
|
436
|
+
], AppRuntime.prototype, "loggerService", void 0);
|
|
437
|
+
_ts_decorate([
|
|
438
|
+
inject2(ENABLE_SHUTDOWN_HOOKS),
|
|
439
|
+
optional2(),
|
|
440
|
+
_ts_metadata("design:type", Boolean)
|
|
441
|
+
], AppRuntime.prototype, "enableShutdownHooks", void 0);
|
|
442
|
+
AppRuntime = _ts_decorate([
|
|
443
|
+
injectable4()
|
|
444
|
+
], AppRuntime);
|
|
445
|
+
|
|
446
|
+
// src/app/module-tree/dependency-binder.ts
|
|
447
|
+
import { Container, inject as inject3, injectable as injectable5, optional as optional3 } from "inversify";
|
|
448
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
449
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
450
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
451
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
452
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
453
|
+
}
|
|
454
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
455
|
+
function _ts_metadata2(k, v) {
|
|
456
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
457
|
+
}
|
|
458
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
459
|
+
var ModuleDependencyBinder = class {
|
|
460
|
+
static {
|
|
461
|
+
__name(this, "ModuleDependencyBinder");
|
|
462
|
+
}
|
|
463
|
+
globalAppContainer;
|
|
464
|
+
loggerService;
|
|
465
|
+
containerOptions;
|
|
466
|
+
async bind(resolvedTree) {
|
|
467
|
+
await resolvedTree.asyncTraverse(async (node) => {
|
|
468
|
+
const startTime = Date.now();
|
|
469
|
+
const module = node.value;
|
|
470
|
+
module.container = new ModuleContainer(module.metadata.container ?? this.containerOptions);
|
|
471
|
+
module.container.parent = this.globalAppContainer;
|
|
472
|
+
this.globalAppContainer.bind(module.metadata.classRef).toSelf().inSingletonScope();
|
|
473
|
+
if (module.metadata.global) {
|
|
474
|
+
for (const [_, provider] of module.metadata.externalProviders) {
|
|
475
|
+
this.bindProvider(provider, this.globalAppContainer);
|
|
476
|
+
}
|
|
477
|
+
} else {
|
|
478
|
+
for (const [token, provider] of module.metadata.externalProviders) {
|
|
479
|
+
this.bindProvider(provider, module.container);
|
|
480
|
+
module.parent?.container.bind(token).toDynamicValue(() => module.container.get(token));
|
|
481
|
+
}
|
|
482
|
+
for (const importModule of module.repetitiveImports) {
|
|
483
|
+
for (const [token] of importModule.metadata.externalProviders) {
|
|
484
|
+
module.container.bind(token).toDynamicValue(() => importModule.container.get(token));
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
for (const [_, provider] of module.metadata.internalProviders) {
|
|
489
|
+
this.bindProvider(provider, module.container);
|
|
490
|
+
}
|
|
491
|
+
module.container.bind(MODULE_CONTAINER).toConstantValue(module.container);
|
|
492
|
+
for (const classRef of module.metadata.controllers) {
|
|
493
|
+
module.container.bind(classRef).toSelf().inSingletonScope();
|
|
494
|
+
}
|
|
495
|
+
module.container.bind(TIMER_SERVICE).to(TimerService).inSingletonScope();
|
|
496
|
+
this.loggerService.log(`~lw~Module ~lb~${module.metadata.classRef.name} ~lw~dependencies binded ~lk~(${Date.now() - startTime}ms)`);
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
bindProvider(provider, container) {
|
|
500
|
+
if ("useValue" in provider) {
|
|
501
|
+
container.bind(provider.provide).toConstantValue(provider.useValue);
|
|
502
|
+
} else if ("useFactory" in provider) {
|
|
503
|
+
const binding = container.bind(provider.provide).toDynamicValue((ctx) => {
|
|
504
|
+
const deps = provider.inject?.map((dep) => {
|
|
505
|
+
if (isObject(dep) && "token" in dep && "optional" in dep) {
|
|
506
|
+
try {
|
|
507
|
+
return ctx.container.get(dep.token);
|
|
508
|
+
} catch (err) {
|
|
509
|
+
if (dep.optional) return void 0;
|
|
510
|
+
this.loggerService.error("An error occurred while trying to resolve a dependency.");
|
|
511
|
+
throw err;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return ctx.container.get(dep);
|
|
515
|
+
}) ?? [];
|
|
516
|
+
return provider.useFactory(...deps);
|
|
517
|
+
});
|
|
518
|
+
if (provider.scope === "transient") binding.inTransientScope();
|
|
519
|
+
else if (provider.scope === "request") binding.inRequestScope();
|
|
520
|
+
else binding.inSingletonScope();
|
|
521
|
+
} else if ("useClass" in provider) {
|
|
522
|
+
const binding = container.bind(provider.provide).to(provider.useClass);
|
|
523
|
+
if (provider.scope === "transient") binding.inTransientScope();
|
|
524
|
+
else if (provider.scope === "request") binding.inRequestScope();
|
|
525
|
+
else binding.inSingletonScope();
|
|
526
|
+
} else if ("useExisting" in provider) {
|
|
527
|
+
container.bind(provider.provide).toService(provider.useExisting);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
_ts_decorate2([
|
|
532
|
+
inject3(GLOBAL_APP_CONTAINER),
|
|
533
|
+
_ts_metadata2("design:type", typeof Container === "undefined" ? Object : Container)
|
|
534
|
+
], ModuleDependencyBinder.prototype, "globalAppContainer", void 0);
|
|
535
|
+
_ts_decorate2([
|
|
536
|
+
inject3(LOGGER_SERVICE),
|
|
537
|
+
_ts_metadata2("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
|
|
538
|
+
], ModuleDependencyBinder.prototype, "loggerService", void 0);
|
|
539
|
+
_ts_decorate2([
|
|
540
|
+
optional3(),
|
|
541
|
+
inject3(CONTAINER_OPTIONS),
|
|
542
|
+
_ts_metadata2("design:type", typeof interfaces === "undefined" || typeof interfaces.ContainerOptions === "undefined" ? Object : interfaces.ContainerOptions)
|
|
543
|
+
], ModuleDependencyBinder.prototype, "containerOptions", void 0);
|
|
544
|
+
ModuleDependencyBinder = _ts_decorate2([
|
|
545
|
+
injectable5()
|
|
546
|
+
], ModuleDependencyBinder);
|
|
547
|
+
|
|
548
|
+
// src/app/module-tree/module-tree-scanner.ts
|
|
549
|
+
import { inject as inject4, injectable as injectable6 } from "inversify";
|
|
550
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
551
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
552
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
553
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
554
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
555
|
+
}
|
|
556
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
557
|
+
function _ts_metadata3(k, v) {
|
|
558
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
559
|
+
}
|
|
560
|
+
__name(_ts_metadata3, "_ts_metadata");
|
|
561
|
+
var ModuleTreeScanner = class {
|
|
562
|
+
static {
|
|
563
|
+
__name(this, "ModuleTreeScanner");
|
|
564
|
+
}
|
|
565
|
+
moduleMetadataReader;
|
|
566
|
+
controllerMetadataReader;
|
|
567
|
+
loggerService;
|
|
568
|
+
async scan(classRef) {
|
|
569
|
+
const startTime = Date.now();
|
|
570
|
+
const moduleMetadata = await this.moduleMetadataReader.read(classRef);
|
|
571
|
+
const module = new Module();
|
|
572
|
+
module.metadata = moduleMetadata;
|
|
573
|
+
this.loggerService.log(`~lw~Module ~lb~${module.metadata.classRef.name} ~lw~scanned ~lk~(${Date.now() - startTime}ms)`);
|
|
574
|
+
await this.scanControllers(module);
|
|
575
|
+
const moduleTree = new Tree(module);
|
|
576
|
+
const scannedModules = /* @__PURE__ */ new Map();
|
|
577
|
+
scannedModules.set(classRef, module);
|
|
578
|
+
for (const importedModule of moduleMetadata.imports) {
|
|
579
|
+
await this.scanModules(moduleTree.root, importedModule, scannedModules);
|
|
580
|
+
}
|
|
581
|
+
return moduleTree;
|
|
582
|
+
}
|
|
583
|
+
async scanModules(parentNode, classRef, scannedModules = /* @__PURE__ */ new Map()) {
|
|
584
|
+
const scannedModule = scannedModules.get(classRef);
|
|
585
|
+
if (!isNil(scannedModule)) {
|
|
586
|
+
parentNode.value.repetitiveImports.add(scannedModule);
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
const startTime = Date.now();
|
|
590
|
+
const moduleMetadata = await this.moduleMetadataReader.read(classRef);
|
|
591
|
+
this.checkCircularDependency(parentNode.value.metadata, moduleMetadata);
|
|
592
|
+
const module = new Module();
|
|
593
|
+
module.metadata = moduleMetadata;
|
|
594
|
+
module.parent = parentNode.value;
|
|
595
|
+
this.loggerService.log(`~lw~Module ~lb~${module.metadata.classRef.name} ~lw~scanned ~lk~(${Date.now() - startTime}ms)`);
|
|
596
|
+
await this.scanControllers(module);
|
|
597
|
+
const treeNode = new TreeNode(module);
|
|
598
|
+
parentNode.addChild(treeNode);
|
|
599
|
+
scannedModules.set(classRef, module);
|
|
600
|
+
for (const importModule of moduleMetadata.imports) {
|
|
601
|
+
await this.scanModules(treeNode, importModule, scannedModules);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
async scanControllers(module) {
|
|
605
|
+
for (const classRef of module.metadata.controllers) {
|
|
606
|
+
const startTime = Date.now();
|
|
607
|
+
const controllerMetadata = await this.controllerMetadataReader.read(classRef);
|
|
608
|
+
const controller = new Controller();
|
|
609
|
+
controller.metadata = controllerMetadata;
|
|
610
|
+
controller.owner = module;
|
|
611
|
+
module.controllers.push(controller);
|
|
612
|
+
this.loggerService.log(`~lw~Controller ~lc~${classRef.name} ~lw~scanned ~lk~(${Date.now() - startTime}ms)`);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
async checkCircularDependency(parentMetadata, moduleMetadata) {
|
|
616
|
+
if (moduleMetadata.imports.includes(parentMetadata.classRef)) {
|
|
617
|
+
throw new Error(ErrorMessage.CircularDependencyDetected);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
_ts_decorate3([
|
|
622
|
+
inject4(ModuleMetadataReader),
|
|
623
|
+
_ts_metadata3("design:type", typeof ModuleMetadataReader === "undefined" ? Object : ModuleMetadataReader)
|
|
624
|
+
], ModuleTreeScanner.prototype, "moduleMetadataReader", void 0);
|
|
625
|
+
_ts_decorate3([
|
|
626
|
+
inject4(ControllerMetadataReader),
|
|
627
|
+
_ts_metadata3("design:type", typeof ControllerMetadataReader === "undefined" ? Object : ControllerMetadataReader)
|
|
628
|
+
], ModuleTreeScanner.prototype, "controllerMetadataReader", void 0);
|
|
629
|
+
_ts_decorate3([
|
|
630
|
+
inject4(LOGGER_SERVICE),
|
|
631
|
+
_ts_metadata3("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
|
|
632
|
+
], ModuleTreeScanner.prototype, "loggerService", void 0);
|
|
633
|
+
ModuleTreeScanner = _ts_decorate3([
|
|
634
|
+
injectable6()
|
|
635
|
+
], ModuleTreeScanner);
|
|
636
|
+
|
|
637
|
+
// src/app/multiplayer/ragemp/ragemp-script-event-handler.ts
|
|
638
|
+
var RageMPScriptEvent = class {
|
|
639
|
+
static {
|
|
640
|
+
__name(this, "RageMPScriptEvent");
|
|
641
|
+
}
|
|
642
|
+
eventName;
|
|
643
|
+
listener;
|
|
644
|
+
constructor(eventName, listener) {
|
|
645
|
+
this.eventName = eventName;
|
|
646
|
+
this.listener = listener;
|
|
647
|
+
}
|
|
648
|
+
destroy() {
|
|
649
|
+
mp.events.remove(this.eventName, this.listener);
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
// src/app/multiplayer/ragemp/ragemp-event-emmiter.ts
|
|
654
|
+
var RageMPEventEmmiter = class {
|
|
655
|
+
static {
|
|
656
|
+
__name(this, "RageMPEventEmmiter");
|
|
657
|
+
}
|
|
658
|
+
mapEvents;
|
|
659
|
+
mapEventsShared = {
|
|
660
|
+
// Map alt:V event names to RageMP equivalents
|
|
661
|
+
"entityColShapeEnter": "playerEnterColshape",
|
|
662
|
+
"entityColShapeLeave": "playerExitColshape"
|
|
663
|
+
};
|
|
664
|
+
constructor(mapEvents = {}) {
|
|
665
|
+
this.mapEvents = mapEvents;
|
|
666
|
+
}
|
|
667
|
+
getEventName(eventName) {
|
|
668
|
+
return this.mapEventsShared[eventName] || this.mapEvents[eventName] || eventName;
|
|
669
|
+
}
|
|
670
|
+
emit(eventName, ...args) {
|
|
671
|
+
mp.events.call(eventName, ...args);
|
|
672
|
+
}
|
|
673
|
+
on(eventName, listener) {
|
|
674
|
+
const mappedEventName = this.getEventName(eventName);
|
|
675
|
+
mp.events.add(mappedEventName, listener);
|
|
676
|
+
return new RageMPScriptEvent(mappedEventName, listener);
|
|
677
|
+
}
|
|
678
|
+
once(eventName, listener) {
|
|
679
|
+
const mappedEventName = this.getEventName(eventName);
|
|
680
|
+
const onceWrapper = /* @__PURE__ */ __name((...args) => {
|
|
681
|
+
mp.events.remove(mappedEventName, onceWrapper);
|
|
682
|
+
listener(...args);
|
|
683
|
+
}, "onceWrapper");
|
|
684
|
+
mp.events.add(mappedEventName, onceWrapper);
|
|
685
|
+
return new RageMPScriptEvent(mappedEventName, onceWrapper);
|
|
686
|
+
}
|
|
687
|
+
off(eventName, listener) {
|
|
688
|
+
mp.events.remove(eventName, listener);
|
|
689
|
+
}
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
// src/app/multiplayer/ragemp/ragemp-timer.ts
|
|
693
|
+
var RageMPTimer = class {
|
|
694
|
+
static {
|
|
695
|
+
__name(this, "RageMPTimer");
|
|
696
|
+
}
|
|
697
|
+
id;
|
|
698
|
+
interval;
|
|
699
|
+
once;
|
|
700
|
+
callback;
|
|
701
|
+
clearTimer;
|
|
702
|
+
lastTick = Date.now();
|
|
703
|
+
constructor(id, interval = 0, once, callback, clearTimer) {
|
|
704
|
+
this.id = id;
|
|
705
|
+
this.interval = interval;
|
|
706
|
+
this.once = once;
|
|
707
|
+
this.callback = callback;
|
|
708
|
+
this.clearTimer = clearTimer;
|
|
709
|
+
}
|
|
710
|
+
destroy() {
|
|
711
|
+
this.clearTimer();
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
// src/app/multiplayer/ragemp/ragemp-timers.ts
|
|
716
|
+
var RageMPTimers = class {
|
|
717
|
+
static {
|
|
718
|
+
__name(this, "RageMPTimers");
|
|
719
|
+
}
|
|
720
|
+
timerIncrementer = 0;
|
|
721
|
+
timers = /* @__PURE__ */ new Map();
|
|
722
|
+
everyTickHandlers = /* @__PURE__ */ new Map();
|
|
723
|
+
isEveryTickRunning = false;
|
|
724
|
+
everyTickMainHandler = null;
|
|
725
|
+
get all() {
|
|
726
|
+
return [
|
|
727
|
+
...this.timers.values()
|
|
728
|
+
];
|
|
729
|
+
}
|
|
730
|
+
get warningThreshold() {
|
|
731
|
+
return 0;
|
|
732
|
+
}
|
|
733
|
+
set warningThreshold(_value) {
|
|
734
|
+
}
|
|
735
|
+
get sourceLocationFrameSkipCount() {
|
|
736
|
+
return 0;
|
|
737
|
+
}
|
|
738
|
+
set sourceLocationFrameSkipCount(_value) {
|
|
739
|
+
}
|
|
740
|
+
getByID(id) {
|
|
741
|
+
const timer = this.timers.get(id);
|
|
742
|
+
return timer ?? null;
|
|
743
|
+
}
|
|
744
|
+
createTimer(createTimer, clear, callback, interval, once, ...args) {
|
|
745
|
+
const callbackBind = callback.bind(this, ...Array.isArray(args) ? args : []);
|
|
746
|
+
const timerId = typeof interval === "number" ? createTimer(callbackBind, interval) : createTimer(callbackBind);
|
|
747
|
+
const id = this.timerIncrementer++;
|
|
748
|
+
const rageMPTimer = new RageMPTimer(id, interval ?? 0, once, callbackBind, () => {
|
|
749
|
+
clear(timerId);
|
|
750
|
+
this.timers.delete(id);
|
|
751
|
+
});
|
|
752
|
+
this.timers.set(id, rageMPTimer);
|
|
753
|
+
return rageMPTimer;
|
|
754
|
+
}
|
|
755
|
+
setInterval(callback, time, ...args) {
|
|
756
|
+
return this.createTimer((cb, interval) => setInterval(cb, interval), (id) => clearInterval(id), callback, time, false, ...args);
|
|
757
|
+
}
|
|
758
|
+
setTimeout(callback, time, ...args) {
|
|
759
|
+
const id = this.timerIncrementer++;
|
|
760
|
+
const callbackBind = callback.bind(this, ...Array.isArray(args) ? args : []);
|
|
761
|
+
const timerId = setTimeout(() => {
|
|
762
|
+
callbackBind();
|
|
763
|
+
this.timers.delete(id);
|
|
764
|
+
}, time);
|
|
765
|
+
const rageMPTimer = new RageMPTimer(id, time, true, callbackBind, () => {
|
|
766
|
+
clearTimeout(timerId);
|
|
767
|
+
this.timers.delete(id);
|
|
768
|
+
});
|
|
769
|
+
this.timers.set(id, rageMPTimer);
|
|
770
|
+
return rageMPTimer;
|
|
771
|
+
}
|
|
772
|
+
everyTick(callback, ...args) {
|
|
773
|
+
const id = this.timerIncrementer++;
|
|
774
|
+
const callbackBind = callback.bind(this, ...Array.isArray(args) ? args : []);
|
|
775
|
+
this.everyTickHandlers.set(id, {
|
|
776
|
+
callback,
|
|
777
|
+
bound: callbackBind
|
|
778
|
+
});
|
|
779
|
+
const isClientSide = typeof mp !== "undefined" && typeof mp.browsers !== "undefined";
|
|
780
|
+
if (!this.isEveryTickRunning) {
|
|
781
|
+
this.isEveryTickRunning = true;
|
|
782
|
+
if (isClientSide) {
|
|
783
|
+
this.everyTickMainHandler = () => {
|
|
784
|
+
for (const [, handler] of this.everyTickHandlers) {
|
|
785
|
+
try {
|
|
786
|
+
handler.bound();
|
|
787
|
+
} catch (e) {
|
|
788
|
+
mp.console.logError(`Error in everyTick handler: ${e}`);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
mp.events.add("render", this.everyTickMainHandler);
|
|
793
|
+
} else {
|
|
794
|
+
const intervalHandler = /* @__PURE__ */ __name(() => {
|
|
795
|
+
for (const [, handler] of this.everyTickHandlers) {
|
|
796
|
+
try {
|
|
797
|
+
handler.bound();
|
|
798
|
+
} catch (e) {
|
|
799
|
+
mp.console.logError(`Error in everyTick handler: ${e}`);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
}, "intervalHandler");
|
|
803
|
+
this._everyTickInterval = setInterval(intervalHandler, 0);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
const rageMPTimer = new RageMPTimer(id, 0, false, callbackBind, () => {
|
|
807
|
+
this.everyTickHandlers.delete(id);
|
|
808
|
+
this.timers.delete(id);
|
|
809
|
+
if (this.everyTickHandlers.size === 0) {
|
|
810
|
+
if (isClientSide && this.everyTickMainHandler) {
|
|
811
|
+
mp.events.remove("render", this.everyTickMainHandler);
|
|
812
|
+
this.everyTickMainHandler = null;
|
|
813
|
+
} else if (this._everyTickInterval) {
|
|
814
|
+
clearInterval(this._everyTickInterval);
|
|
815
|
+
this._everyTickInterval = null;
|
|
816
|
+
}
|
|
817
|
+
this.isEveryTickRunning = false;
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
this.timers.set(id, rageMPTimer);
|
|
821
|
+
return rageMPTimer;
|
|
822
|
+
}
|
|
823
|
+
nextTick(callback, ...args) {
|
|
824
|
+
const id = this.timerIncrementer++;
|
|
825
|
+
const callbackBind = callback.bind(this, ...Array.isArray(args) ? args : []);
|
|
826
|
+
const isClientSide = typeof mp !== "undefined" && typeof mp.browsers !== "undefined";
|
|
827
|
+
let timerId;
|
|
828
|
+
if (isClientSide) {
|
|
829
|
+
const handler = /* @__PURE__ */ __name(() => {
|
|
830
|
+
try {
|
|
831
|
+
callbackBind();
|
|
832
|
+
} finally {
|
|
833
|
+
mp.events.remove("render", handler);
|
|
834
|
+
this.timers.delete(id);
|
|
835
|
+
}
|
|
836
|
+
}, "handler");
|
|
837
|
+
mp.events.add("render", handler);
|
|
838
|
+
const rageMPTimer = new RageMPTimer(id, 0, true, callbackBind, () => {
|
|
839
|
+
mp.events.remove("render", handler);
|
|
840
|
+
this.timers.delete(id);
|
|
841
|
+
});
|
|
842
|
+
this.timers.set(id, rageMPTimer);
|
|
843
|
+
return rageMPTimer;
|
|
844
|
+
} else {
|
|
845
|
+
timerId = setTimeout(() => {
|
|
846
|
+
try {
|
|
847
|
+
callbackBind();
|
|
848
|
+
} finally {
|
|
849
|
+
this.timers.delete(id);
|
|
850
|
+
}
|
|
851
|
+
}, 0);
|
|
852
|
+
const rageMPTimer = new RageMPTimer(id, 0, true, callbackBind, () => {
|
|
853
|
+
clearTimeout(timerId);
|
|
854
|
+
this.timers.delete(id);
|
|
855
|
+
});
|
|
856
|
+
this.timers.set(id, rageMPTimer);
|
|
857
|
+
return rageMPTimer;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
time(_name) {
|
|
861
|
+
}
|
|
862
|
+
timeEnd(_name) {
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
|
|
866
|
+
// src/app/multiplayer/ragemp/ragemp-multiplayer.service.ts
|
|
867
|
+
var RageMPMultiplayerService = class {
|
|
868
|
+
static {
|
|
869
|
+
__name(this, "RageMPMultiplayerService");
|
|
870
|
+
}
|
|
871
|
+
Timers;
|
|
872
|
+
Events;
|
|
873
|
+
constructor() {
|
|
874
|
+
this.Events = new RageMPEventEmmiter();
|
|
875
|
+
this.Timers = new RageMPTimers();
|
|
876
|
+
}
|
|
877
|
+
parseInternalArgs(...args) {
|
|
878
|
+
const player = isObject(args[0]) ? args[0] : void 0;
|
|
879
|
+
return {
|
|
880
|
+
player,
|
|
881
|
+
body: args
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
log(arg, ...args) {
|
|
885
|
+
const message = [
|
|
886
|
+
arg,
|
|
887
|
+
...args
|
|
888
|
+
].map((a) => typeof a === "object" ? JSON.stringify(a) : String(a)).join(" ");
|
|
889
|
+
mp.console.logInfo(message);
|
|
890
|
+
}
|
|
891
|
+
logError(arg, ...args) {
|
|
892
|
+
const message = [
|
|
893
|
+
arg,
|
|
894
|
+
...args
|
|
895
|
+
].map((a) => typeof a === "object" ? JSON.stringify(a) : String(a)).join(" ");
|
|
896
|
+
mp.console.logError(message);
|
|
897
|
+
}
|
|
898
|
+
logWarning(arg, ...args) {
|
|
899
|
+
const message = [
|
|
900
|
+
arg,
|
|
901
|
+
...args
|
|
902
|
+
].map((a) => typeof a === "object" ? JSON.stringify(a) : String(a)).join(" ");
|
|
903
|
+
mp.console.logWarning(message);
|
|
904
|
+
}
|
|
905
|
+
logDebug(arg, ...args) {
|
|
906
|
+
const message = [
|
|
907
|
+
arg,
|
|
908
|
+
...args
|
|
909
|
+
].map((a) => typeof a === "object" ? JSON.stringify(a) : String(a)).join(" ");
|
|
910
|
+
mp.console.logInfo(`[DEBUG] ${message}`);
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
|
|
914
|
+
// src/app/app-builder.ts
|
|
915
|
+
import { inject as inject6, Container as Container3, injectable as injectable8 } from "inversify";
|
|
916
|
+
|
|
917
|
+
// src/app/app.ts
|
|
918
|
+
import { Container as Container2, inject as inject5, injectable as injectable7 } from "inversify";
|
|
919
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
920
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
921
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
922
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
923
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
924
|
+
}
|
|
925
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
926
|
+
function _ts_metadata4(k, v) {
|
|
927
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
928
|
+
}
|
|
929
|
+
__name(_ts_metadata4, "_ts_metadata");
|
|
930
|
+
var App = class {
|
|
931
|
+
static {
|
|
932
|
+
__name(this, "App");
|
|
933
|
+
}
|
|
934
|
+
moduleTreeScanner;
|
|
935
|
+
moduleDependencyBinder;
|
|
936
|
+
appRuntime;
|
|
937
|
+
internalAppContainer;
|
|
938
|
+
plugins;
|
|
939
|
+
loggerService;
|
|
940
|
+
moduleTree;
|
|
941
|
+
loaded = false;
|
|
942
|
+
async start(rootModule) {
|
|
943
|
+
if (this.loaded) {
|
|
944
|
+
this.loggerService.error("Error occurred while starting the app.");
|
|
945
|
+
throw new Error(ErrorMessage.AppAlreadyLoaded);
|
|
946
|
+
}
|
|
947
|
+
this.loggerService.log("~lw~Starting app...");
|
|
948
|
+
await this.runPluginMethods("beforeStart");
|
|
949
|
+
this.loggerService.log("~lw~Scanning module tree...");
|
|
950
|
+
await this.runPluginMethods("beforeScan");
|
|
951
|
+
this.moduleTree = await this.moduleTreeScanner.scan(rootModule);
|
|
952
|
+
await this.runPluginMethods("afterScan");
|
|
953
|
+
this.loggerService.log("~lw~Binding module dependencies...");
|
|
954
|
+
await this.runPluginMethods("beforeBind");
|
|
955
|
+
await this.moduleDependencyBinder.bind(this.moduleTree);
|
|
956
|
+
await this.runPluginMethods("afterBind");
|
|
957
|
+
this.loggerService.log("~lw~Loading app...");
|
|
958
|
+
await this.runPluginMethods("beforeLoad");
|
|
959
|
+
await this.appRuntime.boot(this.moduleTree);
|
|
960
|
+
this.loaded = true;
|
|
961
|
+
await this.runPluginMethods("afterLoad");
|
|
962
|
+
this.loggerService.log("~lw~App loaded");
|
|
963
|
+
await this.runPluginMethods("afterStart");
|
|
964
|
+
}
|
|
965
|
+
async stop() {
|
|
966
|
+
if (!this.loaded) {
|
|
967
|
+
this.loggerService.error("Error occurred while stopping the app.");
|
|
968
|
+
throw new Error(ErrorMessage.AppNotLoaded);
|
|
969
|
+
}
|
|
970
|
+
await this.runPluginMethods("beforeStop");
|
|
971
|
+
this.loggerService.log("~lw~Stopping app...");
|
|
972
|
+
await this.appRuntime.shutdown(this.moduleTree);
|
|
973
|
+
this.loaded = false;
|
|
974
|
+
this.loggerService.log("~lw~App stopped");
|
|
975
|
+
await this.runPluginMethods("afterStop");
|
|
976
|
+
}
|
|
977
|
+
async runPluginMethods(method) {
|
|
978
|
+
await Promise.all(this.plugins.map(async (p) => {
|
|
979
|
+
const plugin = this.internalAppContainer.get(p);
|
|
980
|
+
if (!plugin[method]) return Promise.resolve();
|
|
981
|
+
return Promise.resolve(plugin[method]());
|
|
982
|
+
}));
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
_ts_decorate4([
|
|
986
|
+
inject5(ModuleTreeScanner),
|
|
987
|
+
_ts_metadata4("design:type", typeof ModuleTreeScanner === "undefined" ? Object : ModuleTreeScanner)
|
|
988
|
+
], App.prototype, "moduleTreeScanner", void 0);
|
|
989
|
+
_ts_decorate4([
|
|
990
|
+
inject5(ModuleDependencyBinder),
|
|
991
|
+
_ts_metadata4("design:type", typeof ModuleDependencyBinder === "undefined" ? Object : ModuleDependencyBinder)
|
|
992
|
+
], App.prototype, "moduleDependencyBinder", void 0);
|
|
993
|
+
_ts_decorate4([
|
|
994
|
+
inject5(AppRuntime),
|
|
995
|
+
_ts_metadata4("design:type", typeof AppRuntime === "undefined" ? Object : AppRuntime)
|
|
996
|
+
], App.prototype, "appRuntime", void 0);
|
|
997
|
+
_ts_decorate4([
|
|
998
|
+
inject5(INTERNAL_APP_CONTAINER),
|
|
999
|
+
_ts_metadata4("design:type", typeof Container2 === "undefined" ? Object : Container2)
|
|
1000
|
+
], App.prototype, "internalAppContainer", void 0);
|
|
1001
|
+
_ts_decorate4([
|
|
1002
|
+
inject5(PLUGINS),
|
|
1003
|
+
_ts_metadata4("design:type", Array)
|
|
1004
|
+
], App.prototype, "plugins", void 0);
|
|
1005
|
+
_ts_decorate4([
|
|
1006
|
+
inject5(LOGGER_SERVICE),
|
|
1007
|
+
_ts_metadata4("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
|
|
1008
|
+
], App.prototype, "loggerService", void 0);
|
|
1009
|
+
App = _ts_decorate4([
|
|
1010
|
+
injectable7()
|
|
1011
|
+
], App);
|
|
1012
|
+
|
|
1013
|
+
// src/app/app-builder.ts
|
|
1014
|
+
function _ts_decorate5(decorators, target, key, desc) {
|
|
1015
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1016
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1017
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1018
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1019
|
+
}
|
|
1020
|
+
__name(_ts_decorate5, "_ts_decorate");
|
|
1021
|
+
function _ts_metadata5(k, v) {
|
|
1022
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1023
|
+
}
|
|
1024
|
+
__name(_ts_metadata5, "_ts_metadata");
|
|
1025
|
+
var AppBuilder = class {
|
|
1026
|
+
static {
|
|
1027
|
+
__name(this, "AppBuilder");
|
|
1028
|
+
}
|
|
1029
|
+
enviroment;
|
|
1030
|
+
internalAppContainer;
|
|
1031
|
+
multiplayerService;
|
|
1032
|
+
plugins;
|
|
1033
|
+
globalContainerOptions = {};
|
|
1034
|
+
useGlobalGuards(...guards) {
|
|
1035
|
+
const validatedGuards = [];
|
|
1036
|
+
for (const guard of guards) {
|
|
1037
|
+
const { valid, value, error } = validateGuard(guard);
|
|
1038
|
+
if (!valid) throw new Error(error);
|
|
1039
|
+
validatedGuards.push(value);
|
|
1040
|
+
}
|
|
1041
|
+
this.internalAppContainer.bind(GLOBAL_GUARDS).toConstantValue(validatedGuards);
|
|
1042
|
+
return this;
|
|
1043
|
+
}
|
|
1044
|
+
useGlobalInterceptors(...interceptors) {
|
|
1045
|
+
const validatedInterceptors = [];
|
|
1046
|
+
for (const interceptor of interceptors) {
|
|
1047
|
+
const { valid, value, error } = validateInterceptor(interceptor);
|
|
1048
|
+
if (!valid) throw new Error(error);
|
|
1049
|
+
validatedInterceptors.push(value);
|
|
1050
|
+
}
|
|
1051
|
+
this.internalAppContainer.bind(GLOBAL_INTERCEPTORS).toConstantValue(validatedInterceptors);
|
|
1052
|
+
return this;
|
|
1053
|
+
}
|
|
1054
|
+
useGlobalPipes(...pipes) {
|
|
1055
|
+
const validatedPipes = [];
|
|
1056
|
+
for (const pipe of pipes) {
|
|
1057
|
+
const { valid, value, error } = validatePipe(pipe);
|
|
1058
|
+
if (!valid) throw new Error(error);
|
|
1059
|
+
validatedPipes.push(value);
|
|
1060
|
+
}
|
|
1061
|
+
this.internalAppContainer.bind(GLOBAL_PIPES).toConstantValue(validatedPipes);
|
|
1062
|
+
return this;
|
|
1063
|
+
}
|
|
1064
|
+
useGlobalFilters(...filters) {
|
|
1065
|
+
const validatedFIlters = [];
|
|
1066
|
+
for (const filter of filters) {
|
|
1067
|
+
const { valid, value, error } = validateErrorFilter(filter);
|
|
1068
|
+
if (!valid) throw new Error(error);
|
|
1069
|
+
validatedFIlters.push(value);
|
|
1070
|
+
}
|
|
1071
|
+
this.internalAppContainer.bind(GLOBAL_ERROR_FILTERS).toConstantValue(validatedFIlters);
|
|
1072
|
+
return this;
|
|
1073
|
+
}
|
|
1074
|
+
usePlugins(...plugins) {
|
|
1075
|
+
plugins.forEach((p) => this.internalAppContainer.bind(p).toSelf().inSingletonScope());
|
|
1076
|
+
const internalPlugins = this.internalAppContainer.get(PLUGINS);
|
|
1077
|
+
this.internalAppContainer.rebind(PLUGINS).toConstantValue([
|
|
1078
|
+
...internalPlugins,
|
|
1079
|
+
...plugins
|
|
1080
|
+
]);
|
|
1081
|
+
return this;
|
|
1082
|
+
}
|
|
1083
|
+
enableShutdownHooks() {
|
|
1084
|
+
this.internalAppContainer.bind(ENABLE_SHUTDOWN_HOOKS).toConstantValue(true);
|
|
1085
|
+
return this;
|
|
1086
|
+
}
|
|
1087
|
+
setContainerOptions(options, onlyGlobal = false) {
|
|
1088
|
+
this.globalContainerOptions = options;
|
|
1089
|
+
if (onlyGlobal) return this;
|
|
1090
|
+
this.internalAppContainer.bind(CONTAINER_OPTIONS).toConstantValue(options);
|
|
1091
|
+
return this;
|
|
1092
|
+
}
|
|
1093
|
+
async build() {
|
|
1094
|
+
const globalAppContainer = new Container3(this.globalContainerOptions);
|
|
1095
|
+
globalAppContainer.bind(REFLECTOR_SERVICE).toConstantValue(ReflectorService);
|
|
1096
|
+
globalAppContainer.bind(ReflectorService).toService(REFLECTOR_SERVICE);
|
|
1097
|
+
globalAppContainer.bind(MULTIPLAYER_SERVICE).toConstantValue(this.multiplayerService);
|
|
1098
|
+
this.internalAppContainer.bind(App).toSelf().inSingletonScope();
|
|
1099
|
+
this.internalAppContainer.bind(GLOBAL_APP_CONTAINER).toConstantValue(globalAppContainer);
|
|
1100
|
+
this.internalAppContainer.bind(ModuleTreeScanner).toSelf().inSingletonScope();
|
|
1101
|
+
this.internalAppContainer.bind(ModuleDependencyBinder).toSelf().inSingletonScope();
|
|
1102
|
+
this.internalAppContainer.bind(AppRuntime).toSelf().inSingletonScope();
|
|
1103
|
+
this.internalAppContainer.bind(PipelineHandler).toSelf().inSingletonScope();
|
|
1104
|
+
this.internalAppContainer.bind(Module).toSelf().inTransientScope();
|
|
1105
|
+
this.internalAppContainer.bind(ModuleMetadataReader).toSelf().inSingletonScope();
|
|
1106
|
+
this.internalAppContainer.bind(Controller).toSelf().inTransientScope();
|
|
1107
|
+
this.internalAppContainer.bind(ControllerMetadataReader).toSelf().inSingletonScope();
|
|
1108
|
+
this.internalAppContainer.bind(ControllerFlowHandler).toSelf().inSingletonScope();
|
|
1109
|
+
this.internalAppContainer.bind(ControllerEventHandler).toSelf().inSingletonScope();
|
|
1110
|
+
this.internalAppContainer.bind(ControllerRPCHandler).toSelf().inSingletonScope();
|
|
1111
|
+
this.internalAppContainer.bind(MangoRequestBase).toSelf().inTransientScope();
|
|
1112
|
+
this.internalAppContainer.bind(MANGO_REQUEST_FACTORY).toFactory((context) => {
|
|
1113
|
+
return (body, player) => {
|
|
1114
|
+
const request = context.container.get(MangoRequestBase);
|
|
1115
|
+
request.$body = body;
|
|
1116
|
+
request.$player = player;
|
|
1117
|
+
return request;
|
|
1118
|
+
};
|
|
1119
|
+
});
|
|
1120
|
+
this.internalAppContainer.bind(MangoResponseBase).toSelf().inTransientScope();
|
|
1121
|
+
this.internalAppContainer.bind(MANGO_RESPONSE_FACTORY).toFactory((context) => {
|
|
1122
|
+
return () => {
|
|
1123
|
+
return context.container.get(MangoResponseBase);
|
|
1124
|
+
};
|
|
1125
|
+
});
|
|
1126
|
+
this.internalAppContainer.bind(ExecutionContextBase).toSelf().inTransientScope();
|
|
1127
|
+
this.internalAppContainer.bind(EXECUTION_CONTEXT_FACTORY).toFactory((context) => {
|
|
1128
|
+
return (type, classRef, handler, request, response, name) => {
|
|
1129
|
+
const executionContext = context.container.get(ExecutionContextBase);
|
|
1130
|
+
executionContext.$type = type;
|
|
1131
|
+
executionContext.$request = request;
|
|
1132
|
+
executionContext.$response = response;
|
|
1133
|
+
executionContext.$handler = handler;
|
|
1134
|
+
executionContext.$classRef = classRef;
|
|
1135
|
+
executionContext.$name = name;
|
|
1136
|
+
return executionContext;
|
|
1137
|
+
};
|
|
1138
|
+
});
|
|
1139
|
+
for (const plugin of this.plugins) {
|
|
1140
|
+
this.internalAppContainer.bind(plugin).toSelf().inSingletonScope();
|
|
1141
|
+
const pluginInstance = this.internalAppContainer.get(plugin);
|
|
1142
|
+
if (!pluginInstance.onBuild) continue;
|
|
1143
|
+
await pluginInstance.onBuild();
|
|
1144
|
+
}
|
|
1145
|
+
if (!this.internalAppContainer.isBound(GLOBAL_GUARDS)) this.internalAppContainer.bind(GLOBAL_GUARDS).toConstantValue([]);
|
|
1146
|
+
if (!this.internalAppContainer.isBound(GLOBAL_INTERCEPTORS)) this.internalAppContainer.bind(GLOBAL_INTERCEPTORS).toConstantValue([]);
|
|
1147
|
+
if (!this.internalAppContainer.isBound(GLOBAL_PIPES)) this.internalAppContainer.bind(GLOBAL_PIPES).toConstantValue([]);
|
|
1148
|
+
if (!this.internalAppContainer.isBound(GLOBAL_ERROR_FILTERS)) this.internalAppContainer.bind(GLOBAL_ERROR_FILTERS).toConstantValue([]);
|
|
1149
|
+
return this.internalAppContainer.get(App);
|
|
1150
|
+
}
|
|
1151
|
+
};
|
|
1152
|
+
_ts_decorate5([
|
|
1153
|
+
inject6(APP_ENVIROMENT),
|
|
1154
|
+
_ts_metadata5("design:type", String)
|
|
1155
|
+
], AppBuilder.prototype, "enviroment", void 0);
|
|
1156
|
+
_ts_decorate5([
|
|
1157
|
+
inject6(INTERNAL_APP_CONTAINER),
|
|
1158
|
+
_ts_metadata5("design:type", typeof Container3 === "undefined" ? Object : Container3)
|
|
1159
|
+
], AppBuilder.prototype, "internalAppContainer", void 0);
|
|
1160
|
+
_ts_decorate5([
|
|
1161
|
+
inject6(MULTIPLAYER_SERVICE),
|
|
1162
|
+
_ts_metadata5("design:type", typeof MultiplayerService === "undefined" ? Object : MultiplayerService)
|
|
1163
|
+
], AppBuilder.prototype, "multiplayerService", void 0);
|
|
1164
|
+
_ts_decorate5([
|
|
1165
|
+
inject6(PLUGINS),
|
|
1166
|
+
_ts_metadata5("design:type", Array)
|
|
1167
|
+
], AppBuilder.prototype, "plugins", void 0);
|
|
1168
|
+
AppBuilder = _ts_decorate5([
|
|
1169
|
+
injectable8()
|
|
1170
|
+
], AppBuilder);
|
|
1171
|
+
|
|
1172
|
+
// src/app/create-app.ts
|
|
1173
|
+
import { Container as Container4 } from "inversify";
|
|
1174
|
+
async function createAppBuilder({ enviroment, plugins, appBuilderInherit, multiplayerService }) {
|
|
1175
|
+
const internalAppContainer = new Container4();
|
|
1176
|
+
if (multiplayerService) internalAppContainer.bind(MULTIPLAYER_SERVICE).toConstantValue(multiplayerService);
|
|
1177
|
+
internalAppContainer.bind(INTERNAL_APP_CONTAINER).toConstantValue(internalAppContainer);
|
|
1178
|
+
internalAppContainer.bind(APP_ENVIROMENT).toConstantValue(enviroment);
|
|
1179
|
+
internalAppContainer.bind(PLUGINS).toConstantValue(plugins);
|
|
1180
|
+
internalAppContainer.bind(appBuilderInherit).toSelf().inSingletonScope();
|
|
1181
|
+
return internalAppContainer.get(appBuilderInherit);
|
|
1182
|
+
}
|
|
1183
|
+
__name(createAppBuilder, "createAppBuilder");
|
|
1184
|
+
|
|
1185
|
+
// src/decorators/create-event-decorator.ts
|
|
1186
|
+
function createEventDecorator(type, name, webViewId) {
|
|
1187
|
+
return (target, method) => {
|
|
1188
|
+
if (!isNil(name) && !isString(name)) {
|
|
1189
|
+
throw new Error(ErrorMessage.EventNameMustBeString);
|
|
1190
|
+
}
|
|
1191
|
+
name = name ?? method;
|
|
1192
|
+
const events = Reflect.getMetadata(CoreMetadataKey.ControllerEvents, target) ?? [];
|
|
1193
|
+
if (events.some((event) => event.method === method && event.name === name && event.type === type)) {
|
|
1194
|
+
throw new Error(ErrorMessage.EventNameMustBeUnique);
|
|
1195
|
+
}
|
|
1196
|
+
Reflect.defineMetadata(CoreMetadataKey.ControllerEvents, [
|
|
1197
|
+
...events,
|
|
1198
|
+
{
|
|
1199
|
+
method,
|
|
1200
|
+
name,
|
|
1201
|
+
type,
|
|
1202
|
+
webViewId
|
|
1203
|
+
}
|
|
1204
|
+
], target);
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
__name(createEventDecorator, "createEventDecorator");
|
|
1208
|
+
|
|
1209
|
+
// src/decorators/events/on-internal.decorator.ts
|
|
1210
|
+
function OnInternal(eventName) {
|
|
1211
|
+
return createEventDecorator("onInternal", eventName);
|
|
1212
|
+
}
|
|
1213
|
+
__name(OnInternal, "OnInternal");
|
|
1214
|
+
|
|
1215
|
+
// src/decorators/events/on-webview.decorator.ts
|
|
1216
|
+
function OnWebView(id, eventName) {
|
|
1217
|
+
return createEventDecorator("onWebView", eventName, id);
|
|
1218
|
+
}
|
|
1219
|
+
__name(OnWebView, "OnWebView");
|
|
1220
|
+
|
|
1221
|
+
// src/decorators/events/on.decorator.ts
|
|
1222
|
+
function On(eventName) {
|
|
1223
|
+
return createEventDecorator("on", eventName);
|
|
1224
|
+
}
|
|
1225
|
+
__name(On, "On");
|
|
1226
|
+
|
|
1227
|
+
// src/decorators/events/once-internal.decorator.ts
|
|
1228
|
+
function OnceInternal(eventName) {
|
|
1229
|
+
return createEventDecorator("onceInternal", eventName);
|
|
1230
|
+
}
|
|
1231
|
+
__name(OnceInternal, "OnceInternal");
|
|
1232
|
+
|
|
1233
|
+
// src/decorators/events/once.decorator.ts
|
|
1234
|
+
function Once(eventName) {
|
|
1235
|
+
return createEventDecorator("once", eventName);
|
|
1236
|
+
}
|
|
1237
|
+
__name(Once, "Once");
|
|
1238
|
+
|
|
1239
|
+
// src/decorators/events/once-webview.decorator.ts
|
|
1240
|
+
function OnceWebView(id, eventName) {
|
|
1241
|
+
return createEventDecorator("onceWebView", eventName, id);
|
|
1242
|
+
}
|
|
1243
|
+
__name(OnceWebView, "OnceWebView");
|
|
1244
|
+
|
|
1245
|
+
// src/decorators/params/body.decorator.ts
|
|
1246
|
+
function Body(...pipes) {
|
|
1247
|
+
return (target, method, index) => {
|
|
1248
|
+
const validatedPipes = [];
|
|
1249
|
+
for (const pipe of pipes) {
|
|
1250
|
+
const { valid, value, error } = validatePipe(pipe);
|
|
1251
|
+
if (!valid) throw new Error(error);
|
|
1252
|
+
validatedPipes.push(value);
|
|
1253
|
+
}
|
|
1254
|
+
const params = Reflect.getMetadata(CoreMetadataKey.ControllerParams, target, method) ?? [];
|
|
1255
|
+
if (params.some((param) => param.index === index)) {
|
|
1256
|
+
throw new Error(ErrorMessage.MultipleDecoratorsOnSingleParameterNotAllowed);
|
|
1257
|
+
}
|
|
1258
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target, method);
|
|
1259
|
+
const metatype = Array.isArray(paramTypes) ? paramTypes[index] : void 0;
|
|
1260
|
+
Reflect.defineMetadata(CoreMetadataKey.ControllerParams, [
|
|
1261
|
+
...params,
|
|
1262
|
+
{
|
|
1263
|
+
index,
|
|
1264
|
+
method,
|
|
1265
|
+
pipes: validatedPipes,
|
|
1266
|
+
type: MethodParamType.Body,
|
|
1267
|
+
data: void 0,
|
|
1268
|
+
metatype
|
|
1269
|
+
}
|
|
1270
|
+
], target, method);
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
__name(Body, "Body");
|
|
1274
|
+
|
|
1275
|
+
// src/decorators/params/index.decorator.ts
|
|
1276
|
+
function Index(key, ...pipes) {
|
|
1277
|
+
return (target, method, index) => {
|
|
1278
|
+
if (!isNumber(key)) {
|
|
1279
|
+
throw new Error(ErrorMessage.IndexKeyMustBeNumber);
|
|
1280
|
+
}
|
|
1281
|
+
const validatedPipes = [];
|
|
1282
|
+
for (const pipe of pipes) {
|
|
1283
|
+
const { valid, value, error } = validatePipe(pipe);
|
|
1284
|
+
if (!valid) throw new Error(error);
|
|
1285
|
+
validatedPipes.push(value);
|
|
1286
|
+
}
|
|
1287
|
+
const params = Reflect.getMetadata(CoreMetadataKey.ControllerParams, target, method) ?? [];
|
|
1288
|
+
if (params.some((param) => param.index === index)) {
|
|
1289
|
+
throw new Error(ErrorMessage.MultipleDecoratorsOnSingleParameterNotAllowed);
|
|
1290
|
+
}
|
|
1291
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target, method);
|
|
1292
|
+
const metatype = Array.isArray(paramTypes) ? paramTypes[index] : void 0;
|
|
1293
|
+
Reflect.defineMetadata(CoreMetadataKey.ControllerParams, [
|
|
1294
|
+
...params,
|
|
1295
|
+
{
|
|
1296
|
+
index,
|
|
1297
|
+
method,
|
|
1298
|
+
pipes: validatedPipes,
|
|
1299
|
+
type: MethodParamType.Index,
|
|
1300
|
+
data: key,
|
|
1301
|
+
metatype
|
|
1302
|
+
}
|
|
1303
|
+
], target, method);
|
|
1304
|
+
};
|
|
1305
|
+
}
|
|
1306
|
+
__name(Index, "Index");
|
|
1307
|
+
|
|
1308
|
+
// src/decorators/params/request.decorator.ts
|
|
1309
|
+
function Request() {
|
|
1310
|
+
return (target, method, index) => {
|
|
1311
|
+
const params = Reflect.getMetadata(CoreMetadataKey.ControllerParams, target, method) ?? [];
|
|
1312
|
+
if (params.some((param) => param.index === index)) {
|
|
1313
|
+
throw new Error(ErrorMessage.MultipleDecoratorsOnSingleParameterNotAllowed);
|
|
1314
|
+
}
|
|
1315
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target, method);
|
|
1316
|
+
const metatype = Array.isArray(paramTypes) ? paramTypes[index] : void 0;
|
|
1317
|
+
Reflect.defineMetadata(CoreMetadataKey.ControllerParams, [
|
|
1318
|
+
...params,
|
|
1319
|
+
{
|
|
1320
|
+
index,
|
|
1321
|
+
method,
|
|
1322
|
+
type: MethodParamType.Request,
|
|
1323
|
+
data: void 0,
|
|
1324
|
+
metatype
|
|
1325
|
+
}
|
|
1326
|
+
], target, method);
|
|
1327
|
+
};
|
|
1328
|
+
}
|
|
1329
|
+
__name(Request, "Request");
|
|
1330
|
+
function Req() {
|
|
1331
|
+
return Request();
|
|
1332
|
+
}
|
|
1333
|
+
__name(Req, "Req");
|
|
1334
|
+
|
|
1335
|
+
// src/decorators/params/param.decorator.ts
|
|
1336
|
+
function Param(key, ...pipes) {
|
|
1337
|
+
return (target, method, index) => {
|
|
1338
|
+
if (!isString(key)) {
|
|
1339
|
+
throw new Error(ErrorMessage.ParamKeyMustBeString);
|
|
1340
|
+
}
|
|
1341
|
+
const validatedPipes = [];
|
|
1342
|
+
for (const pipe of pipes) {
|
|
1343
|
+
const { valid, value, error } = validatePipe(pipe);
|
|
1344
|
+
if (!valid) throw new Error(error);
|
|
1345
|
+
validatedPipes.push(value);
|
|
1346
|
+
}
|
|
1347
|
+
const params = Reflect.getMetadata(CoreMetadataKey.ControllerParams, target, method) ?? [];
|
|
1348
|
+
if (params.some((param) => param.index === index)) {
|
|
1349
|
+
throw new Error(ErrorMessage.MultipleDecoratorsOnSingleParameterNotAllowed);
|
|
1350
|
+
}
|
|
1351
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target, method);
|
|
1352
|
+
const metatype = Array.isArray(paramTypes) ? paramTypes[index] : void 0;
|
|
1353
|
+
Reflect.defineMetadata(CoreMetadataKey.ControllerParams, [
|
|
1354
|
+
...params,
|
|
1355
|
+
{
|
|
1356
|
+
index,
|
|
1357
|
+
method,
|
|
1358
|
+
data: key,
|
|
1359
|
+
pipes: validatedPipes,
|
|
1360
|
+
type: MethodParamType.Param,
|
|
1361
|
+
metatype
|
|
1362
|
+
}
|
|
1363
|
+
], target, method);
|
|
1364
|
+
};
|
|
1365
|
+
}
|
|
1366
|
+
__name(Param, "Param");
|
|
1367
|
+
|
|
1368
|
+
// src/decorators/params/response.deorator.ts
|
|
1369
|
+
function Response() {
|
|
1370
|
+
return (target, method, index) => {
|
|
1371
|
+
const params = Reflect.getMetadata(CoreMetadataKey.ControllerParams, target, method) ?? [];
|
|
1372
|
+
if (params.some((param) => param.index === index)) {
|
|
1373
|
+
throw new Error(ErrorMessage.MultipleDecoratorsOnSingleParameterNotAllowed);
|
|
1374
|
+
}
|
|
1375
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target, method);
|
|
1376
|
+
const metatype = Array.isArray(paramTypes) ? paramTypes[index] : void 0;
|
|
1377
|
+
Reflect.defineMetadata(CoreMetadataKey.ControllerParams, [
|
|
1378
|
+
...params,
|
|
1379
|
+
{
|
|
1380
|
+
index,
|
|
1381
|
+
method,
|
|
1382
|
+
type: MethodParamType.Response,
|
|
1383
|
+
data: void 0,
|
|
1384
|
+
metatype
|
|
1385
|
+
}
|
|
1386
|
+
], target, method);
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
__name(Response, "Response");
|
|
1390
|
+
function Res() {
|
|
1391
|
+
return Response();
|
|
1392
|
+
}
|
|
1393
|
+
__name(Res, "Res");
|
|
1394
|
+
|
|
1395
|
+
// src/decorators/pipeline/use-guards.decorator.ts
|
|
1396
|
+
function UseGuards(...guards) {
|
|
1397
|
+
return (target, method, descriptor) => {
|
|
1398
|
+
const validatedGuards = [];
|
|
1399
|
+
for (const guard of guards) {
|
|
1400
|
+
const { valid, value, error } = validateGuard(guard);
|
|
1401
|
+
if (!valid) throw new Error(error);
|
|
1402
|
+
validatedGuards.push(value);
|
|
1403
|
+
}
|
|
1404
|
+
if (!isNil(descriptor) && !isNil(descriptor.value)) {
|
|
1405
|
+
if (guards.length === 0) {
|
|
1406
|
+
throw new Error(ErrorMessage.AtLeastOneGuardRequired);
|
|
1407
|
+
}
|
|
1408
|
+
const methodGuards = Reflect.getMetadata(CoreMetadataKey.Guards, target.constructor, method) || [];
|
|
1409
|
+
Reflect.defineMetadata(CoreMetadataKey.Guards, [
|
|
1410
|
+
...validatedGuards,
|
|
1411
|
+
...methodGuards
|
|
1412
|
+
], target.constructor, method);
|
|
1413
|
+
return descriptor;
|
|
1414
|
+
}
|
|
1415
|
+
if (guards.length === 0) {
|
|
1416
|
+
throw new Error(ErrorMessage.AtLeastOneGuardRequired);
|
|
1417
|
+
}
|
|
1418
|
+
const classGuards = Reflect.getMetadata(CoreMetadataKey.Guards, target) || [];
|
|
1419
|
+
Reflect.defineMetadata(CoreMetadataKey.Guards, [
|
|
1420
|
+
...validatedGuards,
|
|
1421
|
+
...classGuards
|
|
1422
|
+
], target);
|
|
1423
|
+
return target;
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
__name(UseGuards, "UseGuards");
|
|
1427
|
+
|
|
1428
|
+
// src/decorators/pipeline/use-interceptors.decorator.ts
|
|
1429
|
+
function UseInterceptors(...interceptors) {
|
|
1430
|
+
return (target, method, descriptor) => {
|
|
1431
|
+
const validatedInterceptors = [];
|
|
1432
|
+
for (const interceptor of interceptors) {
|
|
1433
|
+
const { valid, value, error } = validateInterceptor(interceptor);
|
|
1434
|
+
if (!valid) throw new Error(error);
|
|
1435
|
+
validatedInterceptors.push(value);
|
|
1436
|
+
}
|
|
1437
|
+
if (!isNil(descriptor) && !isNil(descriptor.value)) {
|
|
1438
|
+
if (interceptors.length === 0) {
|
|
1439
|
+
throw new Error(ErrorMessage.AtLeastOneInterceptorRequired);
|
|
1440
|
+
}
|
|
1441
|
+
const methodInterceptors = Reflect.getMetadata(CoreMetadataKey.Interceptors, target.constructor, method) || [];
|
|
1442
|
+
Reflect.defineMetadata(CoreMetadataKey.Interceptors, [
|
|
1443
|
+
...validatedInterceptors,
|
|
1444
|
+
...methodInterceptors
|
|
1445
|
+
], target.constructor, method);
|
|
1446
|
+
return descriptor;
|
|
1447
|
+
}
|
|
1448
|
+
if (interceptors.length === 0) {
|
|
1449
|
+
throw new Error(ErrorMessage.AtLeastOneInterceptorRequired);
|
|
1450
|
+
}
|
|
1451
|
+
const classInterceptors = Reflect.getMetadata(CoreMetadataKey.Interceptors, target) || [];
|
|
1452
|
+
Reflect.defineMetadata(CoreMetadataKey.Interceptors, [
|
|
1453
|
+
...validatedInterceptors,
|
|
1454
|
+
...classInterceptors
|
|
1455
|
+
], target);
|
|
1456
|
+
return target;
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1459
|
+
__name(UseInterceptors, "UseInterceptors");
|
|
1460
|
+
|
|
1461
|
+
// src/decorators/pipeline/use-pipes.decorator.ts
|
|
1462
|
+
function UsePipes(...pipes) {
|
|
1463
|
+
return (target, method, descriptor) => {
|
|
1464
|
+
const validatedPipes = [];
|
|
1465
|
+
for (const pipe of pipes) {
|
|
1466
|
+
const { valid, value, error } = validatePipe(pipe);
|
|
1467
|
+
if (!valid) throw new Error(error);
|
|
1468
|
+
validatedPipes.push(value);
|
|
1469
|
+
}
|
|
1470
|
+
if (!isNil(descriptor) && !isNil(descriptor.value)) {
|
|
1471
|
+
if (pipes.length === 0) {
|
|
1472
|
+
throw new Error(ErrorMessage.AtLeastOnePipeRequired);
|
|
1473
|
+
}
|
|
1474
|
+
const methodPipes = Reflect.getMetadata(CoreMetadataKey.Pipes, target.constructor, method) || [];
|
|
1475
|
+
Reflect.defineMetadata(CoreMetadataKey.Pipes, [
|
|
1476
|
+
...validatedPipes,
|
|
1477
|
+
...methodPipes
|
|
1478
|
+
], target.constructor, method);
|
|
1479
|
+
return descriptor;
|
|
1480
|
+
}
|
|
1481
|
+
if (pipes.length === 0) {
|
|
1482
|
+
throw new Error(ErrorMessage.AtLeastOnePipeRequired);
|
|
1483
|
+
}
|
|
1484
|
+
const classPipes = Reflect.getMetadata(CoreMetadataKey.Pipes, target) || [];
|
|
1485
|
+
Reflect.defineMetadata(CoreMetadataKey.Pipes, [
|
|
1486
|
+
...validatedPipes,
|
|
1487
|
+
...classPipes
|
|
1488
|
+
], target);
|
|
1489
|
+
return target;
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
__name(UsePipes, "UsePipes");
|
|
1493
|
+
|
|
1494
|
+
// src/decorators/create-rpc-decorator.ts
|
|
1495
|
+
function createRPCDecorator(type, name, webViewId) {
|
|
1496
|
+
return (target, method) => {
|
|
1497
|
+
if (!isNil(webViewId) && !isString(webViewId) && !isNumber(webViewId)) {
|
|
1498
|
+
throw new Error(ErrorMessage.WebViewIdMustBeStringOrNumber);
|
|
1499
|
+
}
|
|
1500
|
+
if (!isNil(name) && !isString(name)) {
|
|
1501
|
+
throw new Error(ErrorMessage.RPCNameMustBeString);
|
|
1502
|
+
}
|
|
1503
|
+
name = name ?? method;
|
|
1504
|
+
const rpcs = Reflect.getMetadata(CoreMetadataKey.ControllerRPCs, target) ?? [];
|
|
1505
|
+
if (rpcs.some((rpc) => rpc.method === method && rpc.name === name && rpc.type === type)) {
|
|
1506
|
+
throw new Error(ErrorMessage.RPCNameMustBeUnique);
|
|
1507
|
+
}
|
|
1508
|
+
Reflect.defineMetadata(CoreMetadataKey.ControllerRPCs, [
|
|
1509
|
+
...rpcs,
|
|
1510
|
+
{
|
|
1511
|
+
method,
|
|
1512
|
+
name,
|
|
1513
|
+
type,
|
|
1514
|
+
webViewId
|
|
1515
|
+
}
|
|
1516
|
+
], target);
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
__name(createRPCDecorator, "createRPCDecorator");
|
|
1520
|
+
|
|
1521
|
+
// src/decorators/rpc/on-request.decorator.ts
|
|
1522
|
+
function OnRequest(rpcName) {
|
|
1523
|
+
return createRPCDecorator("onRequest", rpcName);
|
|
1524
|
+
}
|
|
1525
|
+
__name(OnRequest, "OnRequest");
|
|
1526
|
+
|
|
1527
|
+
// src/decorators/rpc/on-webview-request.decorator.ts
|
|
1528
|
+
function OnWebViewRequest(id, rpcName) {
|
|
1529
|
+
return createRPCDecorator("onWebViewRequest", rpcName, id);
|
|
1530
|
+
}
|
|
1531
|
+
__name(OnWebViewRequest, "OnWebViewRequest");
|
|
1532
|
+
|
|
1533
|
+
// src/decorators/create-timer.decorator.ts
|
|
1534
|
+
function createTimerDecorator(type, name, options) {
|
|
1535
|
+
return (target, method) => {
|
|
1536
|
+
if (!isNil(name) && !isString(name)) {
|
|
1537
|
+
throw new Error(ErrorMessage.TimerNameMustBeString);
|
|
1538
|
+
}
|
|
1539
|
+
name = name ?? method;
|
|
1540
|
+
const timers = Reflect.getMetadata(CoreMetadataKey.Timers, target) ?? [];
|
|
1541
|
+
if (timers.some((timer) => timer.method === method && timer.name === name && timer.type === type)) {
|
|
1542
|
+
throw new Error(ErrorMessage.EventNameMustBeUnique);
|
|
1543
|
+
}
|
|
1544
|
+
Reflect.defineMetadata(CoreMetadataKey.Timers, [
|
|
1545
|
+
...timers,
|
|
1546
|
+
{
|
|
1547
|
+
method,
|
|
1548
|
+
name,
|
|
1549
|
+
type,
|
|
1550
|
+
options
|
|
1551
|
+
}
|
|
1552
|
+
], target);
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
__name(createTimerDecorator, "createTimerDecorator");
|
|
1556
|
+
|
|
1557
|
+
// src/decorators/timers/cron.decorator.ts
|
|
1558
|
+
function Cron(pattern, options = {}) {
|
|
1559
|
+
return createTimerDecorator("cron", options.name, {
|
|
1560
|
+
pattern,
|
|
1561
|
+
...options
|
|
1562
|
+
});
|
|
1563
|
+
}
|
|
1564
|
+
__name(Cron, "Cron");
|
|
1565
|
+
|
|
1566
|
+
// src/decorators/timers/every-tick.decorator.ts
|
|
1567
|
+
function EveryTick(name) {
|
|
1568
|
+
return createTimerDecorator("everytick", name);
|
|
1569
|
+
}
|
|
1570
|
+
__name(EveryTick, "EveryTick");
|
|
1571
|
+
|
|
1572
|
+
// src/decorators/timers/interval.decorator.ts
|
|
1573
|
+
function Interval(nameOrTimeout, timeout) {
|
|
1574
|
+
const [name, intervalTimeout] = isString(nameOrTimeout) ? [
|
|
1575
|
+
nameOrTimeout,
|
|
1576
|
+
timeout
|
|
1577
|
+
] : [
|
|
1578
|
+
void 0,
|
|
1579
|
+
nameOrTimeout
|
|
1580
|
+
];
|
|
1581
|
+
return createTimerDecorator("interval", name, {
|
|
1582
|
+
timeout: intervalTimeout
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1585
|
+
__name(Interval, "Interval");
|
|
1586
|
+
|
|
1587
|
+
// src/decorators/timers/timeout.decorator.ts
|
|
1588
|
+
function Timeout(nameOrTimeout, timeout) {
|
|
1589
|
+
const [name, intervalTimeout] = isString(nameOrTimeout) ? [
|
|
1590
|
+
nameOrTimeout,
|
|
1591
|
+
timeout
|
|
1592
|
+
] : [
|
|
1593
|
+
void 0,
|
|
1594
|
+
nameOrTimeout
|
|
1595
|
+
];
|
|
1596
|
+
return createTimerDecorator("timeout", name, {
|
|
1597
|
+
timeout: intervalTimeout
|
|
1598
|
+
});
|
|
1599
|
+
}
|
|
1600
|
+
__name(Timeout, "Timeout");
|
|
1601
|
+
|
|
1602
|
+
// src/decorators/apply-decorator.util.ts
|
|
1603
|
+
function applyDecorators(...decorators) {
|
|
1604
|
+
return (target, propertyKey, descriptor) => {
|
|
1605
|
+
for (const decorator of decorators) {
|
|
1606
|
+
if (target instanceof Function && !descriptor) {
|
|
1607
|
+
decorator(target);
|
|
1608
|
+
continue;
|
|
1609
|
+
}
|
|
1610
|
+
decorator(target, propertyKey, descriptor);
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
1613
|
+
}
|
|
1614
|
+
__name(applyDecorators, "applyDecorators");
|
|
1615
|
+
|
|
1616
|
+
// src/decorators/create-param.util.ts
|
|
1617
|
+
function createParamDecorator(factory) {
|
|
1618
|
+
return (data, ...pipes) => {
|
|
1619
|
+
return (target, method, index) => {
|
|
1620
|
+
const validatedPipes = [];
|
|
1621
|
+
for (const pipe of pipes) {
|
|
1622
|
+
const { valid, value, error } = validatePipe(pipe);
|
|
1623
|
+
if (!valid) throw new Error(error);
|
|
1624
|
+
validatedPipes.push(value);
|
|
1625
|
+
}
|
|
1626
|
+
const params = Reflect.getMetadata(CoreMetadataKey.ControllerParams, target, method) ?? [];
|
|
1627
|
+
if (params.some((param) => param.index === index)) {
|
|
1628
|
+
throw new Error(ErrorMessage.MultipleDecoratorsOnSingleParameterNotAllowed);
|
|
1629
|
+
}
|
|
1630
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", target, method);
|
|
1631
|
+
const metatype = Array.isArray(paramTypes) ? paramTypes[index] : void 0;
|
|
1632
|
+
Reflect.defineMetadata(CoreMetadataKey.ControllerParams, [
|
|
1633
|
+
...params,
|
|
1634
|
+
{
|
|
1635
|
+
index,
|
|
1636
|
+
method,
|
|
1637
|
+
pipes: validatedPipes,
|
|
1638
|
+
type: MethodParamType.Custom,
|
|
1639
|
+
factory,
|
|
1640
|
+
data,
|
|
1641
|
+
metatype
|
|
1642
|
+
}
|
|
1643
|
+
], target, method);
|
|
1644
|
+
};
|
|
1645
|
+
};
|
|
1646
|
+
}
|
|
1647
|
+
__name(createParamDecorator, "createParamDecorator");
|
|
1648
|
+
|
|
1649
|
+
// src/decorators/forward-ref.util.ts
|
|
1650
|
+
import { LazyServiceIdentifer } from "inversify";
|
|
1651
|
+
function forwardRef(fn) {
|
|
1652
|
+
return new LazyServiceIdentifer(fn);
|
|
1653
|
+
}
|
|
1654
|
+
__name(forwardRef, "forwardRef");
|
|
1655
|
+
|
|
1656
|
+
// src/services/reflector.service.ts
|
|
1657
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
1658
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1659
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1660
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1661
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1662
|
+
}
|
|
1663
|
+
__name(_ts_decorate6, "_ts_decorate");
|
|
1664
|
+
var ReflectorService = class {
|
|
1665
|
+
static {
|
|
1666
|
+
__name(this, "ReflectorService");
|
|
1667
|
+
}
|
|
1668
|
+
get(metadataKey, target) {
|
|
1669
|
+
return Reflect.getMetadata(metadataKey, target);
|
|
1670
|
+
}
|
|
1671
|
+
getAll(metadataKey, targets) {
|
|
1672
|
+
return (targets || []).map((target) => this.get(metadataKey, target));
|
|
1673
|
+
}
|
|
1674
|
+
getAllAndMerge(metadataKey, targets) {
|
|
1675
|
+
const metadataCollection = this.getAll(metadataKey, targets).filter((item) => item !== void 0);
|
|
1676
|
+
if (isEmpty(metadataCollection)) return metadataCollection;
|
|
1677
|
+
return metadataCollection.reduce((a, b) => {
|
|
1678
|
+
if (Array.isArray(a)) {
|
|
1679
|
+
return a.concat(b);
|
|
1680
|
+
}
|
|
1681
|
+
if (isObject(a) && isObject(b)) {
|
|
1682
|
+
return {
|
|
1683
|
+
...a,
|
|
1684
|
+
...b
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
return [
|
|
1688
|
+
a,
|
|
1689
|
+
b
|
|
1690
|
+
];
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
getAllAndOverride(metadataKey, targets) {
|
|
1694
|
+
for (const target of targets) {
|
|
1695
|
+
const result = this.get(metadataKey, target);
|
|
1696
|
+
if (result !== void 0) return result;
|
|
1697
|
+
}
|
|
1698
|
+
return void 0;
|
|
1699
|
+
}
|
|
1700
|
+
static createDecorator(options = {}) {
|
|
1701
|
+
const metadataKey = options.key ?? generateRandomId();
|
|
1702
|
+
const decoratorFn = /* @__PURE__ */ __name((metadataValue) => (target, key, descriptor) => {
|
|
1703
|
+
const value = options.transform ? options.transform(metadataValue) : metadataValue;
|
|
1704
|
+
SetMetadata(metadataKey, value ?? {})(target, key, descriptor);
|
|
1705
|
+
}, "decoratorFn");
|
|
1706
|
+
decoratorFn.KEY = metadataKey;
|
|
1707
|
+
return decoratorFn;
|
|
1708
|
+
}
|
|
1709
|
+
};
|
|
1710
|
+
ReflectorService = _ts_decorate6([
|
|
1711
|
+
injectable9()
|
|
1712
|
+
], ReflectorService);
|
|
1713
|
+
|
|
1714
|
+
// src/services/timer.service.ts
|
|
1715
|
+
import { inject as inject7, injectable as injectable10 } from "inversify";
|
|
1716
|
+
import { Cron as Cron2 } from "croner";
|
|
1717
|
+
function _ts_decorate7(decorators, target, key, desc) {
|
|
1718
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1719
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1720
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1721
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1722
|
+
}
|
|
1723
|
+
__name(_ts_decorate7, "_ts_decorate");
|
|
1724
|
+
function _ts_metadata6(k, v) {
|
|
1725
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1726
|
+
}
|
|
1727
|
+
__name(_ts_metadata6, "_ts_metadata");
|
|
1728
|
+
var TimerService = class {
|
|
1729
|
+
static {
|
|
1730
|
+
__name(this, "TimerService");
|
|
1731
|
+
}
|
|
1732
|
+
multiplayerService;
|
|
1733
|
+
$everyticks = /* @__PURE__ */ new Map();
|
|
1734
|
+
$intervals = /* @__PURE__ */ new Map();
|
|
1735
|
+
$timeouts = /* @__PURE__ */ new Map();
|
|
1736
|
+
$crons = /* @__PURE__ */ new Map();
|
|
1737
|
+
get all() {
|
|
1738
|
+
return this.multiplayerService.Timers.all;
|
|
1739
|
+
}
|
|
1740
|
+
get everyticks() {
|
|
1741
|
+
return [
|
|
1742
|
+
...this.$everyticks.values()
|
|
1743
|
+
];
|
|
1744
|
+
}
|
|
1745
|
+
get intervals() {
|
|
1746
|
+
return [
|
|
1747
|
+
...this.$intervals.values()
|
|
1748
|
+
];
|
|
1749
|
+
}
|
|
1750
|
+
get timeouts() {
|
|
1751
|
+
return [
|
|
1752
|
+
...this.$timeouts.values()
|
|
1753
|
+
];
|
|
1754
|
+
}
|
|
1755
|
+
get crons() {
|
|
1756
|
+
return [
|
|
1757
|
+
...this.$crons.values()
|
|
1758
|
+
];
|
|
1759
|
+
}
|
|
1760
|
+
set warningThreshold(value) {
|
|
1761
|
+
this.multiplayerService.Timers.warningThreshold = value;
|
|
1762
|
+
}
|
|
1763
|
+
get warningThreshold() {
|
|
1764
|
+
return this.multiplayerService.Timers.warningThreshold;
|
|
1765
|
+
}
|
|
1766
|
+
set sourceLocationFrameSkipCount(value) {
|
|
1767
|
+
this.multiplayerService.Timers.sourceLocationFrameSkipCount = value;
|
|
1768
|
+
}
|
|
1769
|
+
get sourceLocationFrameSkipCount() {
|
|
1770
|
+
return this.multiplayerService.Timers.sourceLocationFrameSkipCount;
|
|
1771
|
+
}
|
|
1772
|
+
createCronJob(callback, options) {
|
|
1773
|
+
const { pattern, ...cronOptions } = options;
|
|
1774
|
+
const cron = Cron2(pattern, cronOptions, callback);
|
|
1775
|
+
if (isString(options.name)) this.$crons.set(options.name, cron);
|
|
1776
|
+
return cron;
|
|
1777
|
+
}
|
|
1778
|
+
createInterval(callback, interval, name) {
|
|
1779
|
+
const timer = this.multiplayerService.Timers.setInterval(callback, interval);
|
|
1780
|
+
if (isString(name)) this.$intervals.set(name, timer);
|
|
1781
|
+
return timer;
|
|
1782
|
+
}
|
|
1783
|
+
createTimeout(callback, timeout, name) {
|
|
1784
|
+
const timer = this.multiplayerService.Timers.setTimeout(callback, timeout);
|
|
1785
|
+
if (isString(name)) this.$timeouts.set(name, timer);
|
|
1786
|
+
return timer;
|
|
1787
|
+
}
|
|
1788
|
+
createEveryTick(callback, name) {
|
|
1789
|
+
const timer = this.multiplayerService.Timers.everyTick(callback);
|
|
1790
|
+
if (isString(name)) this.$everyticks.set(name, timer);
|
|
1791
|
+
return timer;
|
|
1792
|
+
}
|
|
1793
|
+
delete(type, name) {
|
|
1794
|
+
switch (type) {
|
|
1795
|
+
case "cron":
|
|
1796
|
+
const cronJob = this.$crons.get(name);
|
|
1797
|
+
if (cronJob) {
|
|
1798
|
+
cronJob.stop();
|
|
1799
|
+
this.$crons.delete(name);
|
|
1800
|
+
}
|
|
1801
|
+
break;
|
|
1802
|
+
case "everytick":
|
|
1803
|
+
const everytick = this.$everyticks.get(name);
|
|
1804
|
+
if (everytick) {
|
|
1805
|
+
everytick.destroy();
|
|
1806
|
+
this.$everyticks.delete(name);
|
|
1807
|
+
}
|
|
1808
|
+
break;
|
|
1809
|
+
case "interval":
|
|
1810
|
+
const interval = this.$intervals.get(name);
|
|
1811
|
+
if (interval) {
|
|
1812
|
+
interval.destroy();
|
|
1813
|
+
this.$intervals.delete(name);
|
|
1814
|
+
}
|
|
1815
|
+
break;
|
|
1816
|
+
case "timeout":
|
|
1817
|
+
const timeout = this.$timeouts.get(name);
|
|
1818
|
+
if (timeout) {
|
|
1819
|
+
timeout.destroy();
|
|
1820
|
+
this.$timeouts.delete(name);
|
|
1821
|
+
}
|
|
1822
|
+
break;
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
getByName(type, name) {
|
|
1826
|
+
switch (type) {
|
|
1827
|
+
case "cron":
|
|
1828
|
+
return this.$crons.get(name);
|
|
1829
|
+
case "everytick":
|
|
1830
|
+
return this.$everyticks.get(name);
|
|
1831
|
+
case "interval":
|
|
1832
|
+
return this.$intervals.get(name);
|
|
1833
|
+
case "timeout":
|
|
1834
|
+
return this.$timeouts.get(name);
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
getById(id) {
|
|
1838
|
+
return this.multiplayerService.Timers.getByID(id);
|
|
1839
|
+
}
|
|
1840
|
+
time(name) {
|
|
1841
|
+
return this.multiplayerService.Timers.time(name);
|
|
1842
|
+
}
|
|
1843
|
+
timeEnd(name) {
|
|
1844
|
+
return this.multiplayerService.Timers.timeEnd(name);
|
|
1845
|
+
}
|
|
1846
|
+
};
|
|
1847
|
+
_ts_decorate7([
|
|
1848
|
+
inject7(MULTIPLAYER_SERVICE),
|
|
1849
|
+
_ts_metadata6("design:type", typeof MultiplayerService === "undefined" ? Object : MultiplayerService)
|
|
1850
|
+
], TimerService.prototype, "multiplayerService", void 0);
|
|
1851
|
+
TimerService = _ts_decorate7([
|
|
1852
|
+
injectable10()
|
|
1853
|
+
], TimerService);
|
|
1854
|
+
|
|
1855
|
+
export {
|
|
1856
|
+
Controller2 as Controller,
|
|
1857
|
+
Global,
|
|
1858
|
+
Inject,
|
|
1859
|
+
Injectable,
|
|
1860
|
+
Module2 as Module,
|
|
1861
|
+
Optional,
|
|
1862
|
+
SetMetadata,
|
|
1863
|
+
Catch,
|
|
1864
|
+
UseFilters,
|
|
1865
|
+
AppRuntime,
|
|
1866
|
+
ReflectorService,
|
|
1867
|
+
TimerService,
|
|
1868
|
+
ModuleDependencyBinder,
|
|
1869
|
+
ModuleTreeScanner,
|
|
1870
|
+
RageMPScriptEvent,
|
|
1871
|
+
RageMPEventEmmiter,
|
|
1872
|
+
RageMPTimer,
|
|
1873
|
+
RageMPTimers,
|
|
1874
|
+
RageMPMultiplayerService,
|
|
1875
|
+
App,
|
|
1876
|
+
AppBuilder,
|
|
1877
|
+
createAppBuilder,
|
|
1878
|
+
createEventDecorator,
|
|
1879
|
+
OnInternal,
|
|
1880
|
+
OnWebView,
|
|
1881
|
+
On,
|
|
1882
|
+
OnceInternal,
|
|
1883
|
+
Once,
|
|
1884
|
+
OnceWebView,
|
|
1885
|
+
Body,
|
|
1886
|
+
Index,
|
|
1887
|
+
Request,
|
|
1888
|
+
Req,
|
|
1889
|
+
Param,
|
|
1890
|
+
Response,
|
|
1891
|
+
Res,
|
|
1892
|
+
UseGuards,
|
|
1893
|
+
UseInterceptors,
|
|
1894
|
+
UsePipes,
|
|
1895
|
+
createRPCDecorator,
|
|
1896
|
+
OnRequest,
|
|
1897
|
+
OnWebViewRequest,
|
|
1898
|
+
Cron,
|
|
1899
|
+
EveryTick,
|
|
1900
|
+
Interval,
|
|
1901
|
+
Timeout,
|
|
1902
|
+
applyDecorators,
|
|
1903
|
+
createParamDecorator,
|
|
1904
|
+
forwardRef
|
|
1905
|
+
};
|
|
1906
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NlcnZpY2VzL3JlZmxlY3Rvci5zZXJ2aWNlLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL2NvcmUvY29udHJvbGxlci5kZWNvcmF0b3IudHMiLCAiLi4vc3JjL2RlY29yYXRvcnMvY29yZS9nbG9iYWwuZGVjb3JhdG9yLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL2NvcmUvaW5qZWN0LmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9jb3JlL2luamVjdGFibGUuZGVjb3JhdG9yLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL2NvcmUvbW9kdWxlLmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9jb3JlL29wdGlvbmFsLmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9jb3JlL3NldC1tZXRhZGF0YS5kZWNvcmF0b3IudHMiLCAiLi4vc3JjL2RlY29yYXRvcnMvZXJyb3JzL2NhdGNoLmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9lcnJvcnMvdXNlLWZpbHRlcnMuZGVjb3JhdG9yLnRzIiwgIi4uL3NyYy9hcHAvbW9kdWxlLXRyZWUvYXBwLXJ1bnRpbWUudHMiLCAiLi4vc3JjL2FwcC9tb2R1bGUtdHJlZS9kZXBlbmRlbmN5LWJpbmRlci50cyIsICIuLi9zcmMvYXBwL21vZHVsZS10cmVlL21vZHVsZS10cmVlLXNjYW5uZXIudHMiLCAiLi4vc3JjL2FwcC9tdWx0aXBsYXllci9yYWdlbXAvcmFnZW1wLXNjcmlwdC1ldmVudC1oYW5kbGVyLnRzIiwgIi4uL3NyYy9hcHAvbXVsdGlwbGF5ZXIvcmFnZW1wL3JhZ2VtcC1ldmVudC1lbW1pdGVyLnRzIiwgIi4uL3NyYy9hcHAvbXVsdGlwbGF5ZXIvcmFnZW1wL3JhZ2VtcC10aW1lci50cyIsICIuLi9zcmMvYXBwL211bHRpcGxheWVyL3JhZ2VtcC9yYWdlbXAtdGltZXJzLnRzIiwgIi4uL3NyYy9hcHAvbXVsdGlwbGF5ZXIvcmFnZW1wL3JhZ2VtcC1tdWx0aXBsYXllci5zZXJ2aWNlLnRzIiwgIi4uL3NyYy9hcHAvYXBwLWJ1aWxkZXIudHMiLCAiLi4vc3JjL2FwcC9hcHAudHMiLCAiLi4vc3JjL2FwcC9jcmVhdGUtYXBwLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL2NyZWF0ZS1ldmVudC1kZWNvcmF0b3IudHMiLCAiLi4vc3JjL2RlY29yYXRvcnMvZXZlbnRzL29uLWludGVybmFsLmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9ldmVudHMvb24td2Vidmlldy5kZWNvcmF0b3IudHMiLCAiLi4vc3JjL2RlY29yYXRvcnMvZXZlbnRzL29uLmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9ldmVudHMvb25jZS1pbnRlcm5hbC5kZWNvcmF0b3IudHMiLCAiLi4vc3JjL2RlY29yYXRvcnMvZXZlbnRzL29uY2UuZGVjb3JhdG9yLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL2V2ZW50cy9vbmNlLXdlYnZpZXcuZGVjb3JhdG9yLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL3BhcmFtcy9ib2R5LmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9wYXJhbXMvaW5kZXguZGVjb3JhdG9yLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL3BhcmFtcy9yZXF1ZXN0LmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9wYXJhbXMvcGFyYW0uZGVjb3JhdG9yLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL3BhcmFtcy9yZXNwb25zZS5kZW9yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9waXBlbGluZS91c2UtZ3VhcmRzLmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9waXBlbGluZS91c2UtaW50ZXJjZXB0b3JzLmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9waXBlbGluZS91c2UtcGlwZXMuZGVjb3JhdG9yLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL2NyZWF0ZS1ycGMtZGVjb3JhdG9yLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL3JwYy9vbi1yZXF1ZXN0LmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9ycGMvb24td2Vidmlldy1yZXF1ZXN0LmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy9jcmVhdGUtdGltZXIuZGVjb3JhdG9yLnRzIiwgIi4uL3NyYy9kZWNvcmF0b3JzL3RpbWVycy9jcm9uLmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy90aW1lcnMvZXZlcnktdGljay5kZWNvcmF0b3IudHMiLCAiLi4vc3JjL2RlY29yYXRvcnMvdGltZXJzL2ludGVydmFsLmRlY29yYXRvci50cyIsICIuLi9zcmMvZGVjb3JhdG9ycy90aW1lcnMvdGltZW91dC5kZWNvcmF0b3IudHMiLCAiLi4vc3JjL2RlY29yYXRvcnMvYXBwbHktZGVjb3JhdG9yLnV0aWwudHMiLCAiLi4vc3JjL2RlY29yYXRvcnMvY3JlYXRlLXBhcmFtLnV0aWwudHMiLCAiLi4vc3JjL2RlY29yYXRvcnMvZm9yd2FyZC1yZWYudXRpbC50cyIsICIuLi9zcmMvc2VydmljZXMvdGltZXIuc2VydmljZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgaW5qZWN0YWJsZSB9IGZyb20gJ2ludmVyc2lmeSc7XG5pbXBvcnQgeyBTZXRNZXRhZGF0YSB9IGZyb20gJy4uL2RlY29yYXRvcnMnO1xuaW1wb3J0IHR5cGUgeyBDcmVhdGVEZWNvcmF0b3JPcHRpb25zLCBDcmVhdGVEZWNvcmF0b3JXaXRoVHJhbnNmb3JtT3B0aW9ucywgUmVmbGVjdGFibGVEZWNvcmF0b3IgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB0eXBlIHsgTmV3YWJsZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IGdlbmVyYXRlUmFuZG9tSWQsIGlzRW1wdHksIGlzT2JqZWN0IH0gZnJvbSAnLi4vdXRpbHMnO1xuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVmbGVjdG9yU2VydmljZSB7XG4gICAgcHVibGljIGdldDxUUmVzdWx0ID0gdW5rbm93biwgVEtleSBleHRlbmRzIHN0cmluZyB8IHN5bWJvbCA9IHN0cmluZz4obWV0YWRhdGFLZXk6IFRLZXksIHRhcmdldDogTmV3YWJsZSB8IEZ1bmN0aW9uKSB7XG4gICAgICAgIHJldHVybiBSZWZsZWN0LmdldE1ldGFkYXRhPFRSZXN1bHQ+KG1ldGFkYXRhS2V5LCB0YXJnZXQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRBbGw8VFJlc3VsdCBleHRlbmRzIHVua25vd25bXSA9IHVua25vd25bXSwgVEtleSBleHRlbmRzIHN0cmluZyB8IHN5bWJvbCA9IHN0cmluZz4oXG4gICAgICAgIG1ldGFkYXRhS2V5OiBUS2V5LFxuICAgICAgICB0YXJnZXRzOiAoTmV3YWJsZSB8IEZ1bmN0aW9uKVtdLFxuICAgICkge1xuICAgICAgICByZXR1cm4gPFRSZXN1bHQ+KHRhcmdldHMgfHwgW10pLm1hcCgodGFyZ2V0KSA9PiB0aGlzLmdldChtZXRhZGF0YUtleSwgdGFyZ2V0KSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldEFsbEFuZE1lcmdlPFRSZXN1bHQgZXh0ZW5kcyB1bmtub3duW10gPSB1bmtub3duW10sIFRLZXkgZXh0ZW5kcyBzdHJpbmcgfCBzeW1ib2wgPSBzdHJpbmc+KFxuICAgICAgICBtZXRhZGF0YUtleTogVEtleSxcbiAgICAgICAgdGFyZ2V0czogKE5ld2FibGUgfCBGdW5jdGlvbilbXSxcbiAgICApIHtcbiAgICAgICAgY29uc3QgbWV0YWRhdGFDb2xsZWN0aW9uID0gdGhpcy5nZXRBbGw8VFJlc3VsdCwgVEtleT4obWV0YWRhdGFLZXksIHRhcmdldHMpLmZpbHRlcigoaXRlbSkgPT4gaXRlbSAhPT0gdW5kZWZpbmVkKTtcblxuICAgICAgICBpZiAoaXNFbXB0eShtZXRhZGF0YUNvbGxlY3Rpb24pKSByZXR1cm4gPFRSZXN1bHQ+bWV0YWRhdGFDb2xsZWN0aW9uO1xuXG4gICAgICAgIHJldHVybiA8VFJlc3VsdD5tZXRhZGF0YUNvbGxlY3Rpb24ucmVkdWNlKChhLCBiKSA9PiB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhLmNvbmNhdChiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc09iamVjdChhKSAmJiBpc09iamVjdChiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmEsXG4gICAgICAgICAgICAgICAgICAgIC4uLmIsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBbYSwgYl07XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRBbGxBbmRPdmVycmlkZTxUUmVzdWx0ID0gdW5rbm93biwgVEtleSBleHRlbmRzIHN0cmluZyB8IHN5bWJvbCA9IHN0cmluZz4obWV0YWRhdGFLZXk6IFRLZXksIHRhcmdldHM6IChOZXdhYmxlIHwgRnVuY3Rpb24pW10pIHtcbiAgICAgICAgZm9yIChjb25zdCB0YXJnZXQgb2YgdGFyZ2V0cykge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5nZXQobWV0YWRhdGFLZXksIHRhcmdldCk7XG4gICAgICAgICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHJldHVybiA8VFJlc3VsdD5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGNyZWF0ZURlY29yYXRvcjxUUGFyYW0+KG9wdGlvbnM/OiBDcmVhdGVEZWNvcmF0b3JPcHRpb25zPFRQYXJhbT4pOiBSZWZsZWN0YWJsZURlY29yYXRvcjxUUGFyYW0+O1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlRGVjb3JhdG9yPFRQYXJhbSwgVFRyYW5zZm9ybWVkPihcbiAgICAgICAgb3B0aW9uczogQ3JlYXRlRGVjb3JhdG9yV2l0aFRyYW5zZm9ybU9wdGlvbnM8VFBhcmFtLCBUVHJhbnNmb3JtZWQ+LFxuICAgICk6IFJlZmxlY3RhYmxlRGVjb3JhdG9yPFRQYXJhbSwgVFRyYW5zZm9ybWVkPjtcbiAgICBwdWJsaWMgc3RhdGljIGNyZWF0ZURlY29yYXRvcjxUUGFyYW0sIFRUcmFuc2Zvcm1lZCA9IFRQYXJhbT4oXG4gICAgICAgIG9wdGlvbnM6IENyZWF0ZURlY29yYXRvck9wdGlvbnM8VFBhcmFtLCBUVHJhbnNmb3JtZWQ+ID0ge30sXG4gICAgKTogUmVmbGVjdGFibGVEZWNvcmF0b3I8VFBhcmFtLCBUVHJhbnNmb3JtZWQ+IHtcbiAgICAgICAgY29uc3QgbWV0YWRhdGFLZXkgPSBvcHRpb25zLmtleSA/PyBnZW5lcmF0ZVJhbmRvbUlkKCk7XG4gICAgICAgIGNvbnN0IGRlY29yYXRvckZuID0gKG1ldGFkYXRhVmFsdWU6IFRQYXJhbSkgPT4gKHRhcmdldDogb2JqZWN0IHwgRnVuY3Rpb24sIGtleT86IHN0cmluZyB8IHN5bWJvbCwgZGVzY3JpcHRvcj86IGFueSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBvcHRpb25zLnRyYW5zZm9ybSA/IG9wdGlvbnMudHJhbnNmb3JtKG1ldGFkYXRhVmFsdWUpIDogbWV0YWRhdGFWYWx1ZTtcbiAgICAgICAgICAgIFNldE1ldGFkYXRhKG1ldGFkYXRhS2V5LCB2YWx1ZSA/PyB7fSkodGFyZ2V0LCBrZXkhLCBkZXNjcmlwdG9yKTtcbiAgICAgICAgfTtcblxuICAgICAgICBkZWNvcmF0b3JGbi5LRVkgPSBtZXRhZGF0YUtleTtcbiAgICAgICAgcmV0dXJuIGRlY29yYXRvckZuIGFzIFJlZmxlY3RhYmxlRGVjb3JhdG9yPFRQYXJhbSwgVFRyYW5zZm9ybWVkPjtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQ29yZU1ldGFkYXRhS2V5IH0gZnJvbSAnLi4vLi4vYXBwL2VudW1zJztcbmltcG9ydCB0eXBlIHsgQ29udHJvbGxlck9wdGlvbnMgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IHZhbGlkYXRlQ29udHJvbGxlck9wdGlvbnMgfSBmcm9tICcuLi8uLi9zY2hlbWFzJztcbmltcG9ydCB0eXBlIHsgTmV3YWJsZSB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7IGluamVjdGFibGUgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gQ29udHJvbGxlcjxUIGV4dGVuZHMgTmV3YWJsZT4ob3B0aW9ucz86IENvbnRyb2xsZXJPcHRpb25zKSB7XG4gICAgcmV0dXJuICh0YXJnZXQ6IFQpID0+IHtcbiAgICAgICAgaWYgKFJlZmxlY3QuaGFzTWV0YWRhdGEoQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXIsIHRhcmdldCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuRHVwbGljYXRlRGVjb3JhdG9yVXNhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeyB2YWxpZCwgdmFsdWUsIGVycm9yIH0gPSB2YWxpZGF0ZUNvbnRyb2xsZXJPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICBpZiAoIXZhbGlkKSB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKENvcmVNZXRhZGF0YUtleS5Db250cm9sbGVyLCB2YWx1ZSwgdGFyZ2V0KTtcblxuICAgICAgICByZXR1cm4gaW5qZWN0YWJsZSgpKHRhcmdldCk7XG4gICAgfTtcbn1cbiIsICJpbXBvcnQgeyBDb3JlTWV0YWRhdGFLZXkgfSBmcm9tICcuLi8uLi9hcHAvZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gR2xvYmFsPFQgZXh0ZW5kcyBOZXdhYmxlPigpIHtcbiAgICByZXR1cm4gKHRhcmdldDogVCkgPT4ge1xuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKENvcmVNZXRhZGF0YUtleS5HbG9iYWxNb2R1bGUsIHRydWUsIHRhcmdldCk7XG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfTtcbn1cbiIsICJpbXBvcnQgeyBpbmplY3QgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHR5cGUgeyBJbmplY3Rpb25Ub2tlbiB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7IEVycm9yTWVzc2FnZSB9IGZyb20gJy4uLy4uL2VudW1zJztcbmltcG9ydCB7IHZhbGlkYXRlSW5qZWN0aW9uVG9rZW4gfSBmcm9tICcuLi8uLi9zY2hlbWFzJztcbmltcG9ydCB7IGlzTmlsIH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuXG5leHBvcnQgZnVuY3Rpb24gSW5qZWN0PFQgPSB1bmtub3duPihrZXk/OiBJbmplY3Rpb25Ub2tlbjxUPikge1xuICAgIHJldHVybiA8UHJvcGVydHlEZWNvcmF0b3IgJiBQYXJhbWV0ZXJEZWNvcmF0b3I+KCh0YXJnZXQ6IE9iamVjdCwgcHJvcGVydHlLZXk6IHN0cmluZywgcGFyYW1JbmRleD86IG51bWJlcikgPT4ge1xuICAgICAgICBpZiAoIWlzTmlsKGtleSkgJiYgIXZhbGlkYXRlSW5qZWN0aW9uVG9rZW4oa2V5KS52YWxpZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5JbnZhbGlkSW5qZWN0aW9uVG9rZW5TcGVjaWZpZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdG9rZW4gPSBrZXkgPz8gUmVmbGVjdC5nZXRNZXRhZGF0YTxJbmplY3Rpb25Ub2tlbj4oJ2Rlc2lnbjp0eXBlJywgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgIGlmICghdG9rZW4pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuSW5qZWN0aW9uVG9rZW5Ob3RGb3VuZCk7XG4gICAgICAgIH1cblxuICAgICAgICBpbmplY3QodG9rZW4pKHRhcmdldCwgcHJvcGVydHlLZXksIHBhcmFtSW5kZXgpO1xuICAgIH0pO1xufVxuIiwgImltcG9ydCB7IGluamVjdGFibGUgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgQ29yZU1ldGFkYXRhS2V5IH0gZnJvbSAnLi4vLi4vYXBwL2VudW1zJztcbmltcG9ydCB0eXBlIHsgSW5qZWN0YWJsZU9wdGlvbnMgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEVycm9yTWVzc2FnZSB9IGZyb20gJy4uLy4uL2VudW1zJztcbmltcG9ydCB7IHZhbGlkYXRlSW5qZWN0YWJsZU1ldGFkYXRhIH0gZnJvbSAnLi4vLi4vc2NoZW1hcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBJbmplY3RhYmxlPFQgZXh0ZW5kcyBOZXdhYmxlPihvcHRpb25zPzogSW5qZWN0YWJsZU9wdGlvbnMpIHtcbiAgICByZXR1cm4gKHRhcmdldDogVCkgPT4ge1xuICAgICAgICBpZiAoUmVmbGVjdC5oYXNNZXRhZGF0YShDb3JlTWV0YWRhdGFLZXkuSW5qZWN0YWJsZSwgdGFyZ2V0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5EdXBsaWNhdGVEZWNvcmF0b3JVc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IHZhbGlkLCB2YWx1ZSwgZXJyb3IgfSA9IHZhbGlkYXRlSW5qZWN0YWJsZU1ldGFkYXRhKG9wdGlvbnMpO1xuICAgICAgICBpZiAoIXZhbGlkKSB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKENvcmVNZXRhZGF0YUtleS5JbmplY3RhYmxlLCB2YWx1ZSwgdGFyZ2V0KTtcblxuICAgICAgICByZXR1cm4gaW5qZWN0YWJsZSgpKHRhcmdldCk7XG4gICAgfTtcbn1cbiIsICJpbXBvcnQgeyBDb3JlTWV0YWRhdGFLZXkgfSBmcm9tICcuLi8uLi9hcHAvZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBNb2R1bGVPcHRpb25zIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBpbmplY3RhYmxlIH0gZnJvbSAnaW52ZXJzaWZ5JztcbmltcG9ydCB7IEVycm9yTWVzc2FnZSB9IGZyb20gJy4uLy4uL2VudW1zJztcbmltcG9ydCB7IHZhbGlkYXRlTW9kdWxlT3B0aW9ucyB9IGZyb20gJy4uLy4uL3NjaGVtYXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gTW9kdWxlPFQgZXh0ZW5kcyBOZXdhYmxlPihvcHRpb25zPzogTW9kdWxlT3B0aW9ucykge1xuICAgIHJldHVybiAodGFyZ2V0OiBUKSA9PiB7XG4gICAgICAgIGlmIChSZWZsZWN0Lmhhc01ldGFkYXRhKENvcmVNZXRhZGF0YUtleS5Nb2R1bGUsIHRhcmdldCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuRHVwbGljYXRlRGVjb3JhdG9yVXNhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeyB2YWxpZCwgdmFsdWUsIGVycm9yIH0gPSB2YWxpZGF0ZU1vZHVsZU9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIGlmICghdmFsaWQpIHRocm93IG5ldyBFcnJvcihlcnJvciEpO1xuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKENvcmVNZXRhZGF0YUtleS5Nb2R1bGUsIHZhbHVlLCB0YXJnZXQpO1xuXG4gICAgICAgIHJldHVybiBpbmplY3RhYmxlKCkodGFyZ2V0KTtcbiAgICB9O1xufVxuIiwgImltcG9ydCB7IG9wdGlvbmFsIH0gZnJvbSAnaW52ZXJzaWZ5JztcblxuZXhwb3J0IGZ1bmN0aW9uIE9wdGlvbmFsKCkge1xuICAgIHJldHVybiA8UHJvcGVydHlEZWNvcmF0b3IgJiBQYXJhbWV0ZXJEZWNvcmF0b3I+KCh0YXJnZXQ6IE9iamVjdCwgcHJvcGVydHlLZXk6IHN0cmluZywgcGFyYW1JbmRleD86IG51bWJlcikgPT4ge1xuICAgICAgICByZXR1cm4gb3B0aW9uYWwoKSh0YXJnZXQsIHByb3BlcnR5S2V5LCBwYXJhbUluZGV4KTtcbiAgICB9KTtcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEN1c3RvbURlY29yYXRvciB9IGZyb20gJy4uLy4uL3R5cGVzJztcblxuZXhwb3J0IGZ1bmN0aW9uIFNldE1ldGFkYXRhPEsgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmcsIFYgPSB1bmtub3duPihrZXk6IEssIHZhbHVlOiBWKSB7XG4gICAgY29uc3QgZGVjb3JhdG9yRmFjdG9yeSA9IDxDdXN0b21EZWNvcmF0b3I+KCh0YXJnZXQ6IG9iamVjdCwgX21ldGhvZD86IHN0cmluZywgZGVzY3JpcHRvcj86IFByb3BlcnR5RGVzY3JpcHRvcikgPT4ge1xuICAgICAgICBpZiAoZGVzY3JpcHRvcikge1xuICAgICAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShrZXksIHZhbHVlLCBkZXNjcmlwdG9yLnZhbHVlKTtcbiAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICAgICAgICB9XG4gICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoa2V5LCB2YWx1ZSwgdGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9KTtcbiAgICBkZWNvcmF0b3JGYWN0b3J5LktFWSA9IGtleTtcbiAgICByZXR1cm4gZGVjb3JhdG9yRmFjdG9yeTtcbn1cbiIsICJpbXBvcnQgeyBDb3JlTWV0YWRhdGFLZXkgfSBmcm9tICcuLi8uLi9hcHAvZW51bXMnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gQ2F0Y2g8VCBleHRlbmRzIE5ld2FibGU+KC4uLmV4Y2VwdGlvbnM6IHVua25vd25bXSkge1xuICAgIHJldHVybiAodGFyZ2V0OiBUKSA9PiB7XG4gICAgICAgIGlmIChSZWZsZWN0Lmhhc01ldGFkYXRhKENvcmVNZXRhZGF0YUtleS5DYXRjaCwgdGFyZ2V0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5EdXBsaWNhdGVEZWNvcmF0b3JVc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkdXBsaWNhdGVzID0gZXhjZXB0aW9ucy5maWx0ZXIoKGV4Y2VwdGlvbiwgaW5kZXgpID0+IGV4Y2VwdGlvbnMuaW5kZXhPZihleGNlcHRpb24pICE9PSBpbmRleCk7XG4gICAgICAgIGlmIChkdXBsaWNhdGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5FeGNlcHRpb25IYW5kbGluZ0NvbmZsaWN0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoQ29yZU1ldGFkYXRhS2V5LkNhdGNoLCBleGNlcHRpb25zLCB0YXJnZXQpO1xuXG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfTtcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgdHlwZSB7IEVycm9yRmlsdGVyIH0gZnJvbSAnLi4vLi4vYXBwL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgQ29yZU1ldGFkYXRhS2V5IH0gZnJvbSAnLi4vLi4vYXBwL2VudW1zJztcbmltcG9ydCB7IGlzTmlsIH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHsgdmFsaWRhdGVFcnJvckZpbHRlciB9IGZyb20gJy4uLy4uL3NjaGVtYXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gVXNlRmlsdGVycyguLi5maWx0ZXJzOiAoTmV3YWJsZTxFcnJvckZpbHRlcj4gfCBFcnJvckZpbHRlcilbXSkge1xuICAgIHJldHVybiA8Q2xhc3NEZWNvcmF0b3IgJiBNZXRob2REZWNvcmF0b3I+KCh0YXJnZXQ6IE9iamVjdCwgbWV0aG9kPzogc3RyaW5nLCBkZXNjcmlwdG9yPzogUHJvcGVydHlEZXNjcmlwdG9yKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbGlkYXRlZEZpbHRlcnM6IChOZXdhYmxlPEVycm9yRmlsdGVyPiB8IEVycm9yRmlsdGVyKVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgZmlsdGVyIG9mIGZpbHRlcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgdmFsaWQsIHZhbHVlLCBlcnJvciB9ID0gdmFsaWRhdGVFcnJvckZpbHRlcihmaWx0ZXIpO1xuICAgICAgICAgICAgaWYgKCF2YWxpZCkgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIHZhbGlkYXRlZEZpbHRlcnMucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzTmlsKGRlc2NyaXB0b3IpICYmICFpc05pbChkZXNjcmlwdG9yLnZhbHVlKSkge1xuICAgICAgICAgICAgaWYgKGZpbHRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5BdExlYXN0T25lRmlsdGVyUmVxdWlyZWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBtZXRob2RGaWx0ZXJzID1cbiAgICAgICAgICAgICAgICBSZWZsZWN0LmdldE1ldGFkYXRhPE5ld2FibGU8RXJyb3JGaWx0ZXI+W10+KENvcmVNZXRhZGF0YUtleS5FcnJvckZpbHRlcnMsIHRhcmdldC5jb25zdHJ1Y3RvciwgbWV0aG9kKSB8fCBbXTtcbiAgICAgICAgICAgIGlmICghaXNOaWwobWV0aG9kRmlsdGVycy5maW5kKChmaWx0ZXIpID0+IGZpbHRlcnMuaW5jbHVkZXMoZmlsdGVyKSkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5EdXBsaWNhdGVFcnJvckZpbHRlckRldGVjdGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoQ29yZU1ldGFkYXRhS2V5LkVycm9yRmlsdGVycywgWy4uLnZhbGlkYXRlZEZpbHRlcnMsIC4uLm1ldGhvZEZpbHRlcnNdLCB0YXJnZXQuY29uc3RydWN0b3IsIG1ldGhvZCk7XG4gICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWx0ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5BdExlYXN0T25lRmlsdGVyUmVxdWlyZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2xhc3NGaWx0ZXJzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxOZXdhYmxlPEVycm9yRmlsdGVyPltdPihDb3JlTWV0YWRhdGFLZXkuRXJyb3JGaWx0ZXJzLCB0YXJnZXQpIHx8IFtdO1xuICAgICAgICBpZiAoIWlzTmlsKGNsYXNzRmlsdGVycy5maW5kKChmaWx0ZXIpID0+IGZpbHRlcnMuaW5jbHVkZXMoZmlsdGVyKSkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkR1cGxpY2F0ZUVycm9yRmlsdGVyRGV0ZWN0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoQ29yZU1ldGFkYXRhS2V5LkVycm9yRmlsdGVycywgWy4uLnZhbGlkYXRlZEZpbHRlcnMsIC4uLmNsYXNzRmlsdGVyc10sIHRhcmdldCk7XG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfSk7XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgaXNOaWwsIGlzT2JqZWN0IH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgRU5BQkxFX1NIVVRET1dOX0hPT0tTLCBHTE9CQUxfRVJST1JfRklMVEVSUywgR0xPQkFMX0dVQVJEUywgR0xPQkFMX0lOVEVSQ0VQVE9SUywgR0xPQkFMX1BJUEVTIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB0eXBlIHsgRXJyb3JGaWx0ZXIsIEd1YXJkLCBJbnRlcmNlcHRvciB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTW9kdWxlIH0gZnJvbSAnLi4vbW9kdWxlJztcbmltcG9ydCB7IGluamVjdCwgaW5qZWN0YWJsZSwgb3B0aW9uYWwgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHsgQ29udHJvbGxlciwgQ29udHJvbGxlckV2ZW50SGFuZGxlciwgQ29udHJvbGxlclJQQ0hhbmRsZXIgfSBmcm9tICcuLi9jb250cm9sbGVyJztcbmltcG9ydCB7IExPR0dFUl9TRVJWSUNFLCBUSU1FUl9TRVJWSUNFIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IENvcmVNZXRhZGF0YUtleSB9IGZyb20gJy4uL2VudW1zJztcbmltcG9ydCB7IEVycm9yTWVzc2FnZSB9IGZyb20gJy4uLy4uL2VudW1zJztcbmltcG9ydCB0eXBlIHsgTG9nZ2VyU2VydmljZSwgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHR5cGUgeyBUcmVlIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHR5cGUgeyBUaW1lclNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcyc7XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBcHBSdW50aW1lIHtcbiAgICBAaW5qZWN0KENvbnRyb2xsZXJFdmVudEhhbmRsZXIpIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRIYW5kbGVyOiBDb250cm9sbGVyRXZlbnRIYW5kbGVyO1xuICAgIEBpbmplY3QoQ29udHJvbGxlclJQQ0hhbmRsZXIpIHByaXZhdGUgcmVhZG9ubHkgcnBjSGFuZGxlcjogQ29udHJvbGxlclJQQ0hhbmRsZXI7XG4gICAgQGluamVjdChHTE9CQUxfR1VBUkRTKSBwcml2YXRlIHJlYWRvbmx5IGdsb2JhbEd1YXJkczogKE5ld2FibGU8R3VhcmQ+IHwgR3VhcmQpW107XG4gICAgQGluamVjdChHTE9CQUxfSU5URVJDRVBUT1JTKSBwcml2YXRlIHJlYWRvbmx5IGdsb2JhbEludGVyY2VwdG9yczogKE5ld2FibGU8SW50ZXJjZXB0b3I+IHwgSW50ZXJjZXB0b3IpW107XG4gICAgQGluamVjdChHTE9CQUxfUElQRVMpIHByaXZhdGUgcmVhZG9ubHkgZ2xvYmFsUGlwZXM6IChOZXdhYmxlPFBpcGU+IHwgUGlwZSlbXTtcbiAgICBAaW5qZWN0KEdMT0JBTF9FUlJPUl9GSUxURVJTKSBwcml2YXRlIHJlYWRvbmx5IGdsb2JhbEVycm9yRmlsdGVyczogKE5ld2FibGU8RXJyb3JGaWx0ZXI+IHwgRXJyb3JGaWx0ZXIpW107XG4gICAgQGluamVjdChMT0dHRVJfU0VSVklDRSkgcHJpdmF0ZSByZWFkb25seSBsb2dnZXJTZXJ2aWNlOiBMb2dnZXJTZXJ2aWNlO1xuICAgIEBpbmplY3QoRU5BQkxFX1NIVVRET1dOX0hPT0tTKSBAb3B0aW9uYWwoKSBwcml2YXRlIHJlYWRvbmx5IGVuYWJsZVNodXRkb3duSG9va3M6IGJvb2xlYW47XG5cbiAgICBwdWJsaWMgYXN5bmMgYm9vdChyZXNvbHZlZFRyZWU6IFRyZWU8TW9kdWxlPikge1xuICAgICAgICBhd2FpdCByZXNvbHZlZFRyZWUuYXN5bmNUcmF2ZXJzZShhc3luYyAobm9kZSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgIC8vIEluaXRpYWxpemUgbW9kdWxlLCBjb250cm9sbGVycyBhbmQgcHJvdmlkZXJzLlxuICAgICAgICAgICAgY29uc3QgbW9kdWxlID0gbm9kZS52YWx1ZTtcbiAgICAgICAgICAgIG1vZHVsZS5pbnN0YW5jZSA9IG1vZHVsZS5jb250YWluZXIuZ2V0PHsgW2tleTogc3RyaW5nXTogRnVuY3Rpb24gfT4obW9kdWxlLm1ldGFkYXRhLmNsYXNzUmVmKTtcbiAgICAgICAgICAgIG1vZHVsZS5jb250cm9sbGVycy5mb3JFYWNoKFxuICAgICAgICAgICAgICAgIChjb250cm9sbGVyKSA9PiAoY29udHJvbGxlci5pbnN0YW5jZSA9IG1vZHVsZS5jb250YWluZXIuZ2V0PHsgW2tleTogc3RyaW5nXTogRnVuY3Rpb24gfT4oY29udHJvbGxlci5tZXRhZGF0YS5jbGFzc1JlZikpLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIFsuLi5tb2R1bGUubWV0YWRhdGEuaW50ZXJuYWxQcm92aWRlcnMsIC4uLm1vZHVsZS5tZXRhZGF0YS5leHRlcm5hbFByb3ZpZGVyc10uZm9yRWFjaCgoW3Rva2VuXSkgPT5cbiAgICAgICAgICAgICAgICBtb2R1bGUuY29udGFpbmVyLmdldDxhbnk+KHRva2VuIGFzIGFueSksXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyBMb2cgbW9kdWxlIGxvYWRlZC5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2coYH5sd35Nb2R1bGUgfmxifiR7bW9kdWxlLm1ldGFkYXRhLmNsYXNzUmVmLm5hbWV9IH5sd35sb2FkZWQgfmxrfigke0RhdGUubm93KCkgLSBzdGFydFRpbWV9bXMpYCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJ1bkxpZmVjeWNsZU1ldGhvZChtb2R1bGUsICdvbk1vZHVsZUluaXQnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGF3YWl0IHRoaXMucnVuTGlmZWN5Y2xlTWV0aG9kcyhyZXNvbHZlZFRyZWUsICdvbk1vZHVsZUluaXQnKTtcbiAgICAgICAgYXdhaXQgdGhpcy5ydW5MaWZlY3ljbGVNZXRob2RzKHJlc29sdmVkVHJlZSwgJ29uQXBwQm9vdHN0cmFwJyk7XG5cbiAgICAgICAgLy8gUmVnaXN0ZXIgZXZlbnQgYW5kIHJwYyBsaXN0ZW5lcnMuXG4gICAgICAgIHJlc29sdmVkVHJlZS50cmF2ZXJzZSgobm9kZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbW9kdWxlID0gbm9kZS52YWx1ZTtcbiAgICAgICAgICAgIG1vZHVsZS5jb250cm9sbGVycy5mb3JFYWNoKChjb250cm9sbGVyKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWdpc3RlclRpbWVycyhjb250cm9sbGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlZ2lzdGVyTGlzdGVuZXJzKGNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2coXG4gICAgICAgICAgICAgICAgICAgIGB+bHd+Q29udHJvbGxlciB+bGN+JHtjb250cm9sbGVyLm1ldGFkYXRhLmNsYXNzUmVmLm5hbWV9IH5sd350aW1lcnMgYW5kIGxpc3RlbmVycyByZWdpc3RlcmVkIH5sa34oJHtEYXRlLm5vdygpIC0gdGltZX1tcylgLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNodXRkb3duKHJlc29sdmVkVHJlZTogVHJlZTxNb2R1bGU+KSB7XG4gICAgICAgIGlmICh0aGlzLmVuYWJsZVNodXRkb3duSG9va3MpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucnVuTGlmZWN5Y2xlTWV0aG9kcyhyZXNvbHZlZFRyZWUsICdvbk1vZHVsZURlc3Ryb3knKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucnVuTGlmZWN5Y2xlTWV0aG9kcyhyZXNvbHZlZFRyZWUsICdiZWZvcmVBcHBTaHV0ZG93bicpO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgcmVzb2x2ZWRUcmVlLmFzeW5jVHJhdmVyc2UoYXN5bmMgKG5vZGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IG5vZGUudmFsdWU7XG4gICAgICAgICAgICBtb2R1bGUuY29udHJvbGxlcnMuZm9yRWFjaCgoY29udHJvbGxlcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRpbWVyU2VydmljZSA9IGNvbnRyb2xsZXIub3duZXIuY29udGFpbmVyLmdldDxUaW1lclNlcnZpY2U+KFRJTUVSX1NFUlZJQ0UpO1xuXG4gICAgICAgICAgICAgICAgLy8gRGVzdHJveSBhbGwgdGltZXJzLlxuICAgICAgICAgICAgICAgIHRpbWVyU2VydmljZS5ldmVyeXRpY2tzLmZvckVhY2goKHRpbWVyKSA9PiB0aW1lci5kZXN0cm95KCkpO1xuICAgICAgICAgICAgICAgIHRpbWVyU2VydmljZS5pbnRlcnZhbHMuZm9yRWFjaCgodGltZXIpID0+IHRpbWVyLmRlc3Ryb3koKSk7XG4gICAgICAgICAgICAgICAgdGltZXJTZXJ2aWNlLnRpbWVvdXRzLmZvckVhY2goKHRpbWVyKSA9PiB0aW1lci5kZXN0cm95KCkpO1xuICAgICAgICAgICAgICAgIHRpbWVyU2VydmljZS5jcm9ucy5mb3JFYWNoKChjcm9uKSA9PiBjcm9uLnN0b3AoKSk7XG5cbiAgICAgICAgICAgICAgICAvLyBEZXN0cm95IGFsbCBzY3JpcHQgZXZlbnQgaGFuZGxlcnMuXG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5ldmVudEhhbmRsZXJzLmZvckVhY2goKGhhbmRsZXIpID0+IGhhbmRsZXIuZGVzdHJveSgpKTtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLnJwY0hhbmRsZXJzLmZvckVhY2goKGhhbmRsZXIpID0+IGhhbmRsZXIuZGVzdHJveSgpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyAvLyBEZXN0cm95IGFsbCB0aW1lcnMuXG4gICAgICAgIC8vIHRoaXMudGltZXJTZXJ2aWNlLmV2ZXJ5dGlja3MuZm9yRWFjaCgodGltZXIpID0+IHRpbWVyLmRlc3Ryb3koKSk7XG4gICAgICAgIC8vIHRoaXMudGltZXJTZXJ2aWNlLmludGVydmFscy5mb3JFYWNoKCh0aW1lcikgPT4gdGltZXIuZGVzdHJveSgpKTtcbiAgICAgICAgLy8gdGhpcy50aW1lclNlcnZpY2UudGltZW91dHMuZm9yRWFjaCgodGltZXIpID0+IHRpbWVyLmRlc3Ryb3koKSk7XG4gICAgICAgIC8vIHRoaXMudGltZXJTZXJ2aWNlLmNyb25Kb2JzLmZvckVhY2goKGNyb25Kb2IpID0+IGNyb25Kb2Iuc3RvcCgpKTtcblxuICAgICAgICAvLyAvLyBEZXN0cm95IGFsbCBzY3JpcHQgZXZlbnQgaGFuZGxlcnMuXG4gICAgICAgIC8vIHRoaXMuZXZlbnRTZXJ2aWNlLiRsb2NhbEhhbmRsZXJzLmZvckVhY2goKGhhbmRsZXIpID0+IGhhbmRsZXIuZGVzdHJveSgpKTtcbiAgICAgICAgLy8gdGhpcy5ldmVudFNlcnZpY2UuJGludGVybmFsSGFuZGxlcnMuZm9yRWFjaCgoaGFuZGxlcikgPT4gaGFuZGxlci5kZXN0cm95KCkpO1xuICAgICAgICAvLyB0aGlzLmV2ZW50U2VydmljZS4kcmVtb3RlSGFuZGxlcnMuZm9yRWFjaCgoaGFuZGxlcikgPT4gaGFuZGxlci5kZXN0cm95KCkpO1xuXG4gICAgICAgIGlmICh0aGlzLmVuYWJsZVNodXRkb3duSG9va3MpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucnVuTGlmZWN5Y2xlTWV0aG9kcyhyZXNvbHZlZFRyZWUsICdvbkFwcFNodXRkb3duJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlZ2lzdGVyTGlzdGVuZXJzKGNvbnRyb2xsZXI6IENvbnRyb2xsZXIpIHtcbiAgICAgICAgY29uc3QgbW9kdWxlID0gY29udHJvbGxlci5vd25lcjtcbiAgICAgICAgY29udHJvbGxlci5tZXRhZGF0YS5ldmVudHMuZm9yRWFjaCgoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGd1YXJkcyA9IFsuLi50aGlzLmdsb2JhbEd1YXJkcywgLi4ubW9kdWxlLm1ldGFkYXRhLmd1YXJkcywgLi4uY29udHJvbGxlci5tZXRhZGF0YS5ndWFyZHMsIC4uLmV2ZW50Lmd1YXJkc107XG4gICAgICAgICAgICBjb25zdCBpbnRlcmNlcHRvcnMgPSBbXG4gICAgICAgICAgICAgICAgLi4udGhpcy5nbG9iYWxJbnRlcmNlcHRvcnMsXG4gICAgICAgICAgICAgICAgLi4ubW9kdWxlLm1ldGFkYXRhLmludGVyY2VwdG9ycyxcbiAgICAgICAgICAgICAgICAuLi5jb250cm9sbGVyLm1ldGFkYXRhLmludGVyY2VwdG9ycyxcbiAgICAgICAgICAgICAgICAuLi5ldmVudC5pbnRlcmNlcHRvcnMsXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgY29uc3QgcGlwZXMgPSBbLi4udGhpcy5nbG9iYWxQaXBlcywgLi4ubW9kdWxlLm1ldGFkYXRhLnBpcGVzLCAuLi5jb250cm9sbGVyLm1ldGFkYXRhLnBpcGVzLCAuLi5ldmVudC5waXBlc107XG4gICAgICAgICAgICBjb25zdCBtYXBwZWRFcnJvckZpbHRlcnMgPSB0aGlzLm1hcEVycm9yRmlsdGVycyhbXG4gICAgICAgICAgICAgICAgLi4udGhpcy5nbG9iYWxFcnJvckZpbHRlcnMsXG4gICAgICAgICAgICAgICAgLi4ubW9kdWxlLm1ldGFkYXRhLmVycm9yRmlsdGVycyxcbiAgICAgICAgICAgICAgICAuLi5jb250cm9sbGVyLm1ldGFkYXRhLmVycm9yRmlsdGVycyxcbiAgICAgICAgICAgICAgICAuLi5ldmVudC5lcnJvckZpbHRlcnMsXG4gICAgICAgICAgICBdKTtcblxuICAgICAgICAgICAgY29uc3QgaGFuZGxlciA9IHRoaXMuZXZlbnRIYW5kbGVyLnJlZ2lzdGVyRXZlbnQoZ3VhcmRzLCBpbnRlcmNlcHRvcnMsIHBpcGVzLCBtYXBwZWRFcnJvckZpbHRlcnMsIGNvbnRyb2xsZXIsIGV2ZW50KTtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuZXZlbnRIYW5kbGVycy5wdXNoKGhhbmRsZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb250cm9sbGVyLm1ldGFkYXRhLnJwY3MuZm9yRWFjaChhc3luYyAocnBjKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBndWFyZHMgPSBbLi4udGhpcy5nbG9iYWxHdWFyZHMsIC4uLm1vZHVsZS5tZXRhZGF0YS5ndWFyZHMsIC4uLmNvbnRyb2xsZXIubWV0YWRhdGEuZ3VhcmRzLCAuLi5ycGMuZ3VhcmRzXTtcbiAgICAgICAgICAgIGNvbnN0IGludGVyY2VwdG9ycyA9IFtcbiAgICAgICAgICAgICAgICAuLi50aGlzLmdsb2JhbEludGVyY2VwdG9ycyxcbiAgICAgICAgICAgICAgICAuLi5tb2R1bGUubWV0YWRhdGEuaW50ZXJjZXB0b3JzLFxuICAgICAgICAgICAgICAgIC4uLmNvbnRyb2xsZXIubWV0YWRhdGEuaW50ZXJjZXB0b3JzLFxuICAgICAgICAgICAgICAgIC4uLnJwYy5pbnRlcmNlcHRvcnMsXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgY29uc3QgcGlwZXMgPSBbLi4udGhpcy5nbG9iYWxQaXBlcywgLi4ubW9kdWxlLm1ldGFkYXRhLnBpcGVzLCAuLi5jb250cm9sbGVyLm1ldGFkYXRhLnBpcGVzLCAuLi5ycGMucGlwZXNdO1xuICAgICAgICAgICAgY29uc3QgbWFwcGVkRXJyb3JGaWx0ZXJzID0gdGhpcy5tYXBFcnJvckZpbHRlcnMoW1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuZ2xvYmFsRXJyb3JGaWx0ZXJzLFxuICAgICAgICAgICAgICAgIC4uLm1vZHVsZS5tZXRhZGF0YS5lcnJvckZpbHRlcnMsXG4gICAgICAgICAgICAgICAgLi4uY29udHJvbGxlci5tZXRhZGF0YS5lcnJvckZpbHRlcnMsXG4gICAgICAgICAgICAgICAgLi4ucnBjLmVycm9yRmlsdGVycyxcbiAgICAgICAgICAgIF0pO1xuXG4gICAgICAgICAgICBjb25zdCBoYW5kbGVyID0gYXdhaXQgdGhpcy5ycGNIYW5kbGVyLnJlZ2lzdGVyUlBDKGd1YXJkcywgaW50ZXJjZXB0b3JzLCBwaXBlcywgbWFwcGVkRXJyb3JGaWx0ZXJzLCBjb250cm9sbGVyLCBycGMpO1xuICAgICAgICAgICAgY29udHJvbGxlci5ycGNIYW5kbGVycy5wdXNoKGhhbmRsZXIpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVnaXN0ZXJUaW1lcnMoY29udHJvbGxlcjogQ29udHJvbGxlcikge1xuICAgICAgICBjb25zdCB0aW1lclNlcnZpY2UgPSBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lci5nZXQ8VGltZXJTZXJ2aWNlPihUSU1FUl9TRVJWSUNFKTtcblxuICAgICAgICBjb250cm9sbGVyLm1ldGFkYXRhLnRpbWVycy5mb3JFYWNoKCh0aW1lcikgPT4ge1xuICAgICAgICAgICAgaWYgKHRpbWVyLnR5cGUgPT09ICdjcm9uJykge1xuICAgICAgICAgICAgICAgIHRpbWVyU2VydmljZS5jcmVhdGVDcm9uSm9iKGNvbnRyb2xsZXIuaW5zdGFuY2VbdGltZXIubWV0aG9kXSEuYmluZChjb250cm9sbGVyLmluc3RhbmNlKSwgdGltZXIub3B0aW9ucyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRpbWVyLnR5cGUgPT09ICdldmVyeXRpY2snKSB7XG4gICAgICAgICAgICAgICAgdGltZXJTZXJ2aWNlLmNyZWF0ZUV2ZXJ5VGljayhjb250cm9sbGVyLmluc3RhbmNlW3RpbWVyLm1ldGhvZF0hLmJpbmQoY29udHJvbGxlci5pbnN0YW5jZSksIHRpbWVyLm5hbWUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aW1lci50eXBlID09PSAnaW50ZXJ2YWwnKSB7XG4gICAgICAgICAgICAgICAgdGltZXJTZXJ2aWNlLmNyZWF0ZUludGVydmFsKFxuICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmluc3RhbmNlW3RpbWVyLm1ldGhvZF0hLmJpbmQoY29udHJvbGxlci5pbnN0YW5jZSksXG4gICAgICAgICAgICAgICAgICAgIHRpbWVyLm9wdGlvbnMudGltZW91dCxcbiAgICAgICAgICAgICAgICAgICAgdGltZXIubmFtZSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aW1lci50eXBlID09PSAndGltZW91dCcpIHtcbiAgICAgICAgICAgICAgICB0aW1lclNlcnZpY2UuY3JlYXRlVGltZW91dChjb250cm9sbGVyLmluc3RhbmNlW3RpbWVyLm1ldGhvZF0hLmJpbmQoY29udHJvbGxlci5pbnN0YW5jZSksIHRpbWVyLm9wdGlvbnMudGltZW91dCwgdGltZXIubmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgbWFwRXJyb3JGaWx0ZXJzKGVycm9yRmlsdGVyczogKE5ld2FibGU8RXJyb3JGaWx0ZXI+IHwgRXJyb3JGaWx0ZXIpW10pIHtcbiAgICAgICAgY29uc3QgZmlsdGVyTWFwOiBbdW5rbm93biB8ICdNQU5HT19BTllfRVJST1InLCBOZXdhYmxlPEVycm9yRmlsdGVyPiB8IEVycm9yRmlsdGVyXVtdID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBmaWx0ZXIgb2YgZXJyb3JGaWx0ZXJzKSB7XG4gICAgICAgICAgICBjb25zdCBlcnJvcnMgPSBSZWZsZWN0LmdldE1ldGFkYXRhPGFueVtdPihDb3JlTWV0YWRhdGFLZXkuQ2F0Y2gsIGZpbHRlcikgPz8gW107XG4gICAgICAgICAgICBpZiAoZXJyb3JzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKCdNQU5HT19BTllfRVJST1InKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoY29uc3QgZXJyb3Igb2YgZXJyb3JzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpc05pbChmaWx0ZXJNYXAuZmluZCgoZmlsdGVyRXJyb3IpID0+IGZpbHRlckVycm9yWzBdID09PSBlcnJvcikpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIG1hcCBlcnJvciBmaWx0ZXJzLicpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkVycm9yQWxyZWFkeUhhbmRsZWRCeUZpbHRlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZpbHRlck1hcC5wdXNoKFtlcnJvciwgZmlsdGVyXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmlsdGVyTWFwO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcnVuTGlmZWN5Y2xlTWV0aG9kcyhcbiAgICAgICAgcmVzb2x2ZWRUcmVlOiBUcmVlPE1vZHVsZT4sXG4gICAgICAgIG1ldGhvZDogJ29uTW9kdWxlSW5pdCcgfCAnb25Nb2R1bGVEZXN0cm95JyB8ICdvbkFwcEJvb3RzdHJhcCcgfCAnYmVmb3JlQXBwU2h1dGRvd24nIHwgJ29uQXBwU2h1dGRvd24nLFxuICAgICkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZWRUcmVlLmFzeW5jVHJhdmVyc2UoYXN5bmMgKG5vZGUpID0+IGF3YWl0IHRoaXMucnVuTGlmZWN5Y2xlTWV0aG9kKG5vZGUudmFsdWUsIG1ldGhvZCkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcnVuTGlmZWN5Y2xlTWV0aG9kKFxuICAgICAgICBtb2R1bGU6IE1vZHVsZSxcbiAgICAgICAgbWV0aG9kOiAnb25Nb2R1bGVJbml0JyB8ICdvbk1vZHVsZURlc3Ryb3knIHwgJ29uQXBwQm9vdHN0cmFwJyB8ICdiZWZvcmVBcHBTaHV0ZG93bicgfCAnb25BcHBTaHV0ZG93bicsXG4gICAgKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgbW9kdWxlLmNvbnRyb2xsZXJzLm1hcChhc3luYyAoY29udHJvbGxlcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghaXNPYmplY3QoY29udHJvbGxlci5pbnN0YW5jZSkgfHwgaXNOaWwoY29udHJvbGxlci5pbnN0YW5jZVttZXRob2RdKSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbnRyb2xsZXIuaW5zdGFuY2VbbWV0aG9kXSEoKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICAgIFsuLi5tb2R1bGUubWV0YWRhdGEuaW50ZXJuYWxQcm92aWRlcnMsIC4uLm1vZHVsZS5tZXRhZGF0YS5leHRlcm5hbFByb3ZpZGVyc10ubWFwKGFzeW5jIChbdG9rZW5dKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvdmlkZXJJbnN0YW5jZSA9IDx7IFtrZXk6IHN0cmluZ106IEZ1bmN0aW9uIH0+bW9kdWxlLmNvbnRhaW5lci5nZXQodG9rZW4gYXMgYW55KTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzT2JqZWN0KHByb3ZpZGVySW5zdGFuY2UpIHx8IGlzTmlsKHByb3ZpZGVySW5zdGFuY2VbbWV0aG9kXSkpIHJldHVybjtcbiAgICAgICAgICAgICAgICBhd2FpdCBwcm92aWRlckluc3RhbmNlW21ldGhvZF0hKCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFpc09iamVjdChtb2R1bGUuaW5zdGFuY2UpIHx8IGlzTmlsKG1vZHVsZS5pbnN0YW5jZVttZXRob2RdKSkgcmV0dXJuO1xuICAgICAgICBhd2FpdCBtb2R1bGUuaW5zdGFuY2VbbWV0aG9kXSEoKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBMb2dnZXJTZXJ2aWNlLCBQcm92aWRlciB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgaXNPYmplY3QgfSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgeyBDT05UQUlORVJfT1BUSU9OUywgR0xPQkFMX0FQUF9DT05UQUlORVIgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgTW9kdWxlLCBNb2R1bGVDb250YWluZXIgfSBmcm9tICcuLi9tb2R1bGUnO1xuaW1wb3J0IHsgQ29udGFpbmVyLCBpbmplY3QsIGluamVjdGFibGUsIG9wdGlvbmFsLCB0eXBlIGludGVyZmFjZXMgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHsgTE9HR0VSX1NFUlZJQ0UsIE1PRFVMRV9DT05UQUlORVIsIFRJTUVSX1NFUlZJQ0UgfSBmcm9tICcuLi8uLi9jb25zdGFudHMnO1xuaW1wb3J0IHR5cGUgeyBUcmVlIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHsgVGltZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMnO1xuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTW9kdWxlRGVwZW5kZW5jeUJpbmRlciB7XG4gICAgQGluamVjdChHTE9CQUxfQVBQX0NPTlRBSU5FUikgcHJpdmF0ZSByZWFkb25seSBnbG9iYWxBcHBDb250YWluZXI6IENvbnRhaW5lcjtcbiAgICBAaW5qZWN0KExPR0dFUl9TRVJWSUNFKSBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlclNlcnZpY2U6IExvZ2dlclNlcnZpY2U7XG4gICAgQG9wdGlvbmFsKCkgQGluamVjdChDT05UQUlORVJfT1BUSU9OUykgcHJpdmF0ZSByZWFkb25seSBjb250YWluZXJPcHRpb25zPzogaW50ZXJmYWNlcy5Db250YWluZXJPcHRpb25zO1xuXG4gICAgcHVibGljIGFzeW5jIGJpbmQocmVzb2x2ZWRUcmVlOiBUcmVlPE1vZHVsZT4pIHtcbiAgICAgICAgYXdhaXQgcmVzb2x2ZWRUcmVlLmFzeW5jVHJhdmVyc2UoYXN5bmMgKG5vZGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IG5vZGUudmFsdWU7XG4gICAgICAgICAgICBtb2R1bGUuY29udGFpbmVyID0gbmV3IE1vZHVsZUNvbnRhaW5lcihtb2R1bGUubWV0YWRhdGEuY29udGFpbmVyID8/IHRoaXMuY29udGFpbmVyT3B0aW9ucyk7XG4gICAgICAgICAgICAvLyBBdHRhY2ggdGhlIGdsb2JhbCBjb250YWluZXIgdG8gdGhlIG1vZHVsZSBjb250YWluZXIsIHNvIGl0IGNhbiBiZSB1c2VkIHRvIHJlc29sdmUgZGVwZW5kZW5jaWVzLlxuICAgICAgICAgICAgbW9kdWxlLmNvbnRhaW5lci5wYXJlbnQgPSB0aGlzLmdsb2JhbEFwcENvbnRhaW5lcjtcbiAgICAgICAgICAgIHRoaXMuZ2xvYmFsQXBwQ29udGFpbmVyLmJpbmQobW9kdWxlLm1ldGFkYXRhLmNsYXNzUmVmKS50b1NlbGYoKS5pblNpbmdsZXRvblNjb3BlKCk7XG5cbiAgICAgICAgICAgIC8vIElmIHRoZSBtb2R1bGUgaXMgZ2xvYmFsLCB3ZSB3YW50IHRvIGJpbmQgaXQgdG8gdGhlIGdsb2JhbCBjb250YWluZXIuXG4gICAgICAgICAgICBpZiAobW9kdWxlLm1ldGFkYXRhLmdsb2JhbCkge1xuICAgICAgICAgICAgICAgIC8vIEJpbmQgZXh0ZXJuYWwgcHJvdmlkZXJzIHRvIHRoZSBnbG9iYWwgY29udGFpbmVyLCBzbyB0aGV5IGNhbiBiZSBpbmplY3RlZCBpbiBvdGhlciBtb2R1bGVzLlxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW18sIHByb3ZpZGVyXSBvZiBtb2R1bGUubWV0YWRhdGEuZXh0ZXJuYWxQcm92aWRlcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5iaW5kUHJvdmlkZXIocHJvdmlkZXIsIHRoaXMuZ2xvYmFsQXBwQ29udGFpbmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBtb2R1bGUgaXMgbm90IGdsb2JhbCwgd2Ugd2FudCB0byBiaW5kIGl0IHRvIGl0cyBvd24gY29udGFpbmVyLlxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW3Rva2VuLCBwcm92aWRlcl0gb2YgbW9kdWxlLm1ldGFkYXRhLmV4dGVybmFsUHJvdmlkZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYmluZFByb3ZpZGVyKHByb3ZpZGVyLCBtb2R1bGUuY29udGFpbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgbW9kdWxlLnBhcmVudD8uY29udGFpbmVyLmJpbmQodG9rZW4pLnRvRHluYW1pY1ZhbHVlKCgpID0+IG1vZHVsZS5jb250YWluZXIuZ2V0KHRva2VuKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaW1wb3J0TW9kdWxlIG9mIG1vZHVsZS5yZXBldGl0aXZlSW1wb3J0cykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFt0b2tlbl0gb2YgaW1wb3J0TW9kdWxlLm1ldGFkYXRhLmV4dGVybmFsUHJvdmlkZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGUuY29udGFpbmVyLmJpbmQodG9rZW4pLnRvRHluYW1pY1ZhbHVlKCgpID0+IGltcG9ydE1vZHVsZS5jb250YWluZXIuZ2V0KHRva2VuKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEJpbmQgaW50ZXJuYWwgcHJvdmlkZXJzLlxuICAgICAgICAgICAgZm9yIChjb25zdCBbXywgcHJvdmlkZXJdIG9mIG1vZHVsZS5tZXRhZGF0YS5pbnRlcm5hbFByb3ZpZGVycykge1xuICAgICAgICAgICAgICAgIHRoaXMuYmluZFByb3ZpZGVyKHByb3ZpZGVyLCBtb2R1bGUuY29udGFpbmVyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQmluZCBjb250YWluZXIgdG8gaXRzZWxmIHNvIGl0IGNhbiBiZSBpbmplY3RlZC5cbiAgICAgICAgICAgIG1vZHVsZS5jb250YWluZXIuYmluZChNT0RVTEVfQ09OVEFJTkVSKS50b0NvbnN0YW50VmFsdWUobW9kdWxlLmNvbnRhaW5lcik7XG5cbiAgICAgICAgICAgIC8vIEJpbmQgY29udHJvbGxlcnMgdG8gdGhlIGNvbnRhaW5lci5cbiAgICAgICAgICAgIGZvciAoY29uc3QgY2xhc3NSZWYgb2YgbW9kdWxlLm1ldGFkYXRhLmNvbnRyb2xsZXJzKSB7XG4gICAgICAgICAgICAgICAgbW9kdWxlLmNvbnRhaW5lci5iaW5kKGNsYXNzUmVmKS50b1NlbGYoKS5pblNpbmdsZXRvblNjb3BlKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEJpbmQgc2VydmljZXMgdG8gdGhlIGNvbnRhaW5lci5cbiAgICAgICAgICAgIG1vZHVsZS5jb250YWluZXIuYmluZChUSU1FUl9TRVJWSUNFKS50byhUaW1lclNlcnZpY2UpLmluU2luZ2xldG9uU2NvcGUoKTtcblxuICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZyhcbiAgICAgICAgICAgICAgICBgfmx3fk1vZHVsZSB+bGJ+JHttb2R1bGUubWV0YWRhdGEuY2xhc3NSZWYubmFtZX0gfmx3fmRlcGVuZGVuY2llcyBiaW5kZWQgfmxrfigke0RhdGUubm93KCkgLSBzdGFydFRpbWV9bXMpYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYmluZFByb3ZpZGVyKHByb3ZpZGVyOiBFeGNsdWRlPFByb3ZpZGVyLCBOZXdhYmxlPiwgY29udGFpbmVyOiBDb250YWluZXIpIHtcbiAgICAgICAgaWYgKCd1c2VWYWx1ZScgaW4gcHJvdmlkZXIpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5iaW5kKHByb3ZpZGVyLnByb3ZpZGUpLnRvQ29uc3RhbnRWYWx1ZShwcm92aWRlci51c2VWYWx1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoJ3VzZUZhY3RvcnknIGluIHByb3ZpZGVyKSB7XG4gICAgICAgICAgICBjb25zdCBiaW5kaW5nID0gY29udGFpbmVyLmJpbmQocHJvdmlkZXIucHJvdmlkZSkudG9EeW5hbWljVmFsdWUoKGN0eCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRlcHMgPVxuICAgICAgICAgICAgICAgICAgICBwcm92aWRlci5pbmplY3Q/Lm1hcCgoZGVwKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNPYmplY3QoZGVwKSAmJiAndG9rZW4nIGluIGRlcCAmJiAnb3B0aW9uYWwnIGluIGRlcCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdHguY29udGFpbmVyLmdldChkZXAudG9rZW4pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVwLm9wdGlvbmFsKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHRyeWluZyB0byByZXNvbHZlIGEgZGVwZW5kZW5jeS4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdHguY29udGFpbmVyLmdldChkZXApO1xuICAgICAgICAgICAgICAgICAgICB9KSA/PyBbXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvdmlkZXIudXNlRmFjdG9yeSguLi5kZXBzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHByb3ZpZGVyLnNjb3BlID09PSAndHJhbnNpZW50JykgYmluZGluZy5pblRyYW5zaWVudFNjb3BlKCk7XG4gICAgICAgICAgICBlbHNlIGlmIChwcm92aWRlci5zY29wZSA9PT0gJ3JlcXVlc3QnKSBiaW5kaW5nLmluUmVxdWVzdFNjb3BlKCk7XG4gICAgICAgICAgICBlbHNlIGJpbmRpbmcuaW5TaW5nbGV0b25TY29wZSgpO1xuICAgICAgICB9IGVsc2UgaWYgKCd1c2VDbGFzcycgaW4gcHJvdmlkZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGJpbmRpbmcgPSBjb250YWluZXIuYmluZChwcm92aWRlci5wcm92aWRlKS50byhwcm92aWRlci51c2VDbGFzcyk7XG4gICAgICAgICAgICBpZiAocHJvdmlkZXIuc2NvcGUgPT09ICd0cmFuc2llbnQnKSBiaW5kaW5nLmluVHJhbnNpZW50U2NvcGUoKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHByb3ZpZGVyLnNjb3BlID09PSAncmVxdWVzdCcpIGJpbmRpbmcuaW5SZXF1ZXN0U2NvcGUoKTtcbiAgICAgICAgICAgIGVsc2UgYmluZGluZy5pblNpbmdsZXRvblNjb3BlKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoJ3VzZUV4aXN0aW5nJyBpbiBwcm92aWRlcikge1xuICAgICAgICAgICAgY29udGFpbmVyLmJpbmQocHJvdmlkZXIucHJvdmlkZSkudG9TZXJ2aWNlKHByb3ZpZGVyLnVzZUV4aXN0aW5nKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IER5bmFtaWNNb2R1bGUsIExvZ2dlclNlcnZpY2UgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcbmltcG9ydCB0eXBlIHsgTmV3YWJsZSB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7IENvbnRyb2xsZXIsIENvbnRyb2xsZXJNZXRhZGF0YVJlYWRlciB9IGZyb20gJy4uL2NvbnRyb2xsZXInO1xuaW1wb3J0IHsgTW9kdWxlLCBNb2R1bGVNZXRhZGF0YVJlYWRlciB9IGZyb20gJy4uL21vZHVsZSc7XG5pbXBvcnQgeyBpbmplY3QsIGluamVjdGFibGUgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHsgVHJlZSwgVHJlZU5vZGUgfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQgeyBMT0dHRVJfU0VSVklDRSB9IGZyb20gJy4uLy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgdHlwZSB7IE1vZHVsZU1ldGFkYXRhIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBpc05pbCB9IGZyb20gJy4uLy4uL3V0aWxzJztcblxuQGluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE1vZHVsZVRyZWVTY2FubmVyIHtcbiAgICBAaW5qZWN0KE1vZHVsZU1ldGFkYXRhUmVhZGVyKSBwcml2YXRlIHJlYWRvbmx5IG1vZHVsZU1ldGFkYXRhUmVhZGVyOiBNb2R1bGVNZXRhZGF0YVJlYWRlcjtcbiAgICBAaW5qZWN0KENvbnRyb2xsZXJNZXRhZGF0YVJlYWRlcikgcHJpdmF0ZSByZWFkb25seSBjb250cm9sbGVyTWV0YWRhdGFSZWFkZXI6IENvbnRyb2xsZXJNZXRhZGF0YVJlYWRlcjtcbiAgICBAaW5qZWN0KExPR0dFUl9TRVJWSUNFKSBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlclNlcnZpY2U6IExvZ2dlclNlcnZpY2U7XG5cbiAgICBwdWJsaWMgYXN5bmMgc2NhbihjbGFzc1JlZjogTmV3YWJsZSB8IER5bmFtaWNNb2R1bGUgfCBQcm9taXNlPER5bmFtaWNNb2R1bGU+KSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgIC8vIFJlYWQgbW9kdWxlIG1ldGFkYXRhXG4gICAgICAgIGNvbnN0IG1vZHVsZU1ldGFkYXRhID0gYXdhaXQgdGhpcy5tb2R1bGVNZXRhZGF0YVJlYWRlci5yZWFkKGNsYXNzUmVmKTtcbiAgICAgICAgLy8gQ3JlYXRlIG1vZHVsZSBpbnN0YW5jZSBhbmQgc2V0IG1ldGFkYXRhIHRvIGl0XG4gICAgICAgIGNvbnN0IG1vZHVsZSA9IG5ldyBNb2R1bGUoKTtcbiAgICAgICAgbW9kdWxlLm1ldGFkYXRhID0gbW9kdWxlTWV0YWRhdGE7XG4gICAgICAgIC8vIExvZyBtb2R1bGUgaW5mb1xuICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UubG9nKGB+bHd+TW9kdWxlIH5sYn4ke21vZHVsZS5tZXRhZGF0YS5jbGFzc1JlZi5uYW1lfSB+bHd+c2Nhbm5lZCB+bGt+KCR7RGF0ZS5ub3coKSAtIHN0YXJ0VGltZX1tcylgKTtcbiAgICAgICAgLy8gU2NhbiBjb250cm9sbGVycyBpbiBtb2R1bGVcbiAgICAgICAgYXdhaXQgdGhpcy5zY2FuQ29udHJvbGxlcnMobW9kdWxlKTtcbiAgICAgICAgLy8gU2NhbiBjb250cm9sbGVycyBpbiBtb2R1bGVcbiAgICAgICAgY29uc3QgbW9kdWxlVHJlZSA9IG5ldyBUcmVlKG1vZHVsZSk7XG4gICAgICAgIGNvbnN0IHNjYW5uZWRNb2R1bGVzID0gbmV3IE1hcDxOZXdhYmxlIHwgRHluYW1pY01vZHVsZSB8IFByb21pc2U8RHluYW1pY01vZHVsZT4sIE1vZHVsZT4oKTtcbiAgICAgICAgc2Nhbm5lZE1vZHVsZXMuc2V0KGNsYXNzUmVmLCBtb2R1bGUpO1xuICAgICAgICAvLyBTY2FuIGltcG9ydGVkIG1vZHVsZXNcbiAgICAgICAgZm9yIChjb25zdCBpbXBvcnRlZE1vZHVsZSBvZiBtb2R1bGVNZXRhZGF0YS5pbXBvcnRzKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNjYW5Nb2R1bGVzKG1vZHVsZVRyZWUucm9vdCwgaW1wb3J0ZWRNb2R1bGUsIHNjYW5uZWRNb2R1bGVzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbW9kdWxlVHJlZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHNjYW5Nb2R1bGVzKFxuICAgICAgICBwYXJlbnROb2RlOiBUcmVlTm9kZTxNb2R1bGU+LFxuICAgICAgICBjbGFzc1JlZjogTmV3YWJsZSB8IER5bmFtaWNNb2R1bGUgfCBQcm9taXNlPER5bmFtaWNNb2R1bGU+LFxuICAgICAgICBzY2FubmVkTW9kdWxlcyA9IG5ldyBNYXA8TmV3YWJsZSB8IER5bmFtaWNNb2R1bGUgfCBQcm9taXNlPER5bmFtaWNNb2R1bGU+LCBNb2R1bGU+KCksXG4gICAgKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIG1vZHVsZSBpcyBhbHJlYWR5IGltcG9ydGVkXG4gICAgICAgIGNvbnN0IHNjYW5uZWRNb2R1bGUgPSBzY2FubmVkTW9kdWxlcy5nZXQoY2xhc3NSZWYpO1xuICAgICAgICBpZiAoIWlzTmlsKHNjYW5uZWRNb2R1bGUpKSB7XG4gICAgICAgICAgICBwYXJlbnROb2RlLnZhbHVlLnJlcGV0aXRpdmVJbXBvcnRzLmFkZChzY2FubmVkTW9kdWxlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgICAgLy8gUmVhZCBtb2R1bGUgbWV0YWRhdGFcbiAgICAgICAgY29uc3QgbW9kdWxlTWV0YWRhdGEgPSBhd2FpdCB0aGlzLm1vZHVsZU1ldGFkYXRhUmVhZGVyLnJlYWQoY2xhc3NSZWYpO1xuICAgICAgICAvLyBDaGVjayBpZiB0aGVyZSBpcyBhIGNpcmN1bGFyIGRlcGVuZGVuY3lcbiAgICAgICAgdGhpcy5jaGVja0NpcmN1bGFyRGVwZW5kZW5jeShwYXJlbnROb2RlLnZhbHVlLm1ldGFkYXRhLCBtb2R1bGVNZXRhZGF0YSk7XG4gICAgICAgIC8vIENyZWF0ZSBtb2R1bGUgaW5zdGFuY2VcbiAgICAgICAgY29uc3QgbW9kdWxlID0gbmV3IE1vZHVsZSgpO1xuICAgICAgICBtb2R1bGUubWV0YWRhdGEgPSBtb2R1bGVNZXRhZGF0YTtcbiAgICAgICAgbW9kdWxlLnBhcmVudCA9IHBhcmVudE5vZGUudmFsdWU7XG4gICAgICAgIC8vIExvZyBtb2R1bGUgaW5mb1xuICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UubG9nKGB+bHd+TW9kdWxlIH5sYn4ke21vZHVsZS5tZXRhZGF0YS5jbGFzc1JlZi5uYW1lfSB+bHd+c2Nhbm5lZCB+bGt+KCR7RGF0ZS5ub3coKSAtIHN0YXJ0VGltZX1tcylgKTtcbiAgICAgICAgLy8gU2NhbiBjb250cm9sbGVycyBpbiBtb2R1bGVcbiAgICAgICAgYXdhaXQgdGhpcy5zY2FuQ29udHJvbGxlcnMobW9kdWxlKTtcbiAgICAgICAgLy8gQWRkIG1vZHVsZSB0byB0cmVlXG4gICAgICAgIGNvbnN0IHRyZWVOb2RlID0gbmV3IFRyZWVOb2RlKG1vZHVsZSk7XG4gICAgICAgIHBhcmVudE5vZGUuYWRkQ2hpbGQodHJlZU5vZGUpO1xuICAgICAgICAvLyBBZGQgbW9kdWxlIHRvIGltcG9ydGVkIG1vZHVsZXMgc2V0IHRvIHByZXZlbnQgdW5uZWNlc3Nhcnkgc2Nhbm5pbmdcbiAgICAgICAgc2Nhbm5lZE1vZHVsZXMuc2V0KGNsYXNzUmVmLCBtb2R1bGUpO1xuICAgICAgICAvLyBTY2FuIGltcG9ydGVkIG1vZHVsZXMgcmVjdXJzaXZlbHlcbiAgICAgICAgZm9yIChjb25zdCBpbXBvcnRNb2R1bGUgb2YgbW9kdWxlTWV0YWRhdGEuaW1wb3J0cykge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5zY2FuTW9kdWxlcyh0cmVlTm9kZSwgaW1wb3J0TW9kdWxlLCBzY2FubmVkTW9kdWxlcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHNjYW5Db250cm9sbGVycyhtb2R1bGU6IE1vZHVsZSkge1xuICAgICAgICAvLyBTY2FuIGNvbnRyb2xsZXJzXG4gICAgICAgIGZvciAoY29uc3QgY2xhc3NSZWYgb2YgbW9kdWxlLm1ldGFkYXRhLmNvbnRyb2xsZXJzKSB7XG4gICAgICAgICAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgY29uc3QgY29udHJvbGxlck1ldGFkYXRhID0gYXdhaXQgdGhpcy5jb250cm9sbGVyTWV0YWRhdGFSZWFkZXIucmVhZChjbGFzc1JlZik7XG4gICAgICAgICAgICBjb25zdCBjb250cm9sbGVyID0gbmV3IENvbnRyb2xsZXIoKTtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIubWV0YWRhdGEgPSBjb250cm9sbGVyTWV0YWRhdGE7XG4gICAgICAgICAgICBjb250cm9sbGVyLm93bmVyID0gbW9kdWxlO1xuICAgICAgICAgICAgbW9kdWxlLmNvbnRyb2xsZXJzLnB1c2goY29udHJvbGxlcik7XG5cbiAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2coYH5sd35Db250cm9sbGVyIH5sY34ke2NsYXNzUmVmLm5hbWV9IH5sd35zY2FubmVkIH5sa34oJHtEYXRlLm5vdygpIC0gc3RhcnRUaW1lfW1zKWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBjaGVja0NpcmN1bGFyRGVwZW5kZW5jeShwYXJlbnRNZXRhZGF0YTogTW9kdWxlTWV0YWRhdGEsIG1vZHVsZU1ldGFkYXRhOiBNb2R1bGVNZXRhZGF0YSkge1xuICAgICAgICAvLyBDaGVjayBpZiBwYXJlbnQgbW9kdWxlIGlzIGltcG9ydGVkIGluIG1vZHVsZVxuICAgICAgICBpZiAobW9kdWxlTWV0YWRhdGEuaW1wb3J0cy5pbmNsdWRlcyhwYXJlbnRNZXRhZGF0YS5jbGFzc1JlZikpIHtcbiAgICAgICAgICAgIC8vIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgc2Nhbm5pbmcgdGhlIG1vZHVsZSB0cmVlLicpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5DaXJjdWxhckRlcGVuZGVuY3lEZXRlY3RlZCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBTY3JpcHRFdmVudEhhbmRsZXIgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcblxuZXhwb3J0IGNsYXNzIFJhZ2VNUFNjcmlwdEV2ZW50IGltcGxlbWVudHMgU2NyaXB0RXZlbnRIYW5kbGVyIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBldmVudE5hbWU6IHN0cmluZyxcbiAgICAgICAgcHJpdmF0ZSBsaXN0ZW5lcjogKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkLFxuICAgICkge31cblxuICAgIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIG1wLmV2ZW50cy5yZW1vdmUodGhpcy5ldmVudE5hbWUsIHRoaXMubGlzdGVuZXIpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IEV2ZW50RW1taXRlciwgU2NyaXB0RXZlbnRIYW5kbGVyIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBSYWdlTVBTY3JpcHRFdmVudCB9IGZyb20gJy4vcmFnZW1wLXNjcmlwdC1ldmVudC1oYW5kbGVyJztcblxuZXhwb3J0IGNsYXNzIFJhZ2VNUEV2ZW50RW1taXRlciBpbXBsZW1lbnRzIEV2ZW50RW1taXRlciB7XG4gICAgcHJpdmF0ZSBtYXBFdmVudHNTaGFyZWQ6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAgIC8vIE1hcCBhbHQ6ViBldmVudCBuYW1lcyB0byBSYWdlTVAgZXF1aXZhbGVudHNcbiAgICAgICAgJ2VudGl0eUNvbFNoYXBlRW50ZXInOiAncGxheWVyRW50ZXJDb2xzaGFwZScsXG4gICAgICAgICdlbnRpdHlDb2xTaGFwZUxlYXZlJzogJ3BsYXllckV4aXRDb2xzaGFwZScsXG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgbWFwRXZlbnRzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge30pIHt9XG5cbiAgICBwcml2YXRlIGdldEV2ZW50TmFtZShldmVudE5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcEV2ZW50c1NoYXJlZFtldmVudE5hbWVdIHx8IHRoaXMubWFwRXZlbnRzW2V2ZW50TmFtZV0gfHwgZXZlbnROYW1lO1xuICAgIH1cblxuICAgIGVtaXQoZXZlbnROYW1lOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIG1wLmV2ZW50cy5jYWxsKGV2ZW50TmFtZSwgLi4uYXJncyk7XG4gICAgfVxuXG4gICAgb24oZXZlbnROYW1lOiBzdHJpbmcsIGxpc3RlbmVyOiAoLi4uYXJnczogYW55W10pID0+IHZvaWQpOiBTY3JpcHRFdmVudEhhbmRsZXIge1xuICAgICAgICBjb25zdCBtYXBwZWRFdmVudE5hbWUgPSB0aGlzLmdldEV2ZW50TmFtZShldmVudE5hbWUpO1xuICAgICAgICBtcC5ldmVudHMuYWRkKG1hcHBlZEV2ZW50TmFtZSwgbGlzdGVuZXIpO1xuICAgICAgICByZXR1cm4gbmV3IFJhZ2VNUFNjcmlwdEV2ZW50KG1hcHBlZEV2ZW50TmFtZSwgbGlzdGVuZXIpO1xuICAgIH1cblxuICAgIG9uY2UoZXZlbnROYW1lOiBzdHJpbmcsIGxpc3RlbmVyOiAoLi4uYXJnczogYW55W10pID0+IHZvaWQpOiBTY3JpcHRFdmVudEhhbmRsZXIge1xuICAgICAgICBjb25zdCBtYXBwZWRFdmVudE5hbWUgPSB0aGlzLmdldEV2ZW50TmFtZShldmVudE5hbWUpO1xuICAgICAgICBjb25zdCBvbmNlV3JhcHBlciA9ICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgICAgICAgICAgbXAuZXZlbnRzLnJlbW92ZShtYXBwZWRFdmVudE5hbWUsIG9uY2VXcmFwcGVyKTtcbiAgICAgICAgICAgIGxpc3RlbmVyKC4uLmFyZ3MpO1xuICAgICAgICB9O1xuICAgICAgICBtcC5ldmVudHMuYWRkKG1hcHBlZEV2ZW50TmFtZSwgb25jZVdyYXBwZXIpO1xuICAgICAgICByZXR1cm4gbmV3IFJhZ2VNUFNjcmlwdEV2ZW50KG1hcHBlZEV2ZW50TmFtZSwgb25jZVdyYXBwZXIpO1xuICAgIH1cblxuICAgIG9mZihldmVudE5hbWU6IHN0cmluZywgbGlzdGVuZXI6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCk6IHZvaWQge1xuICAgICAgICBtcC5ldmVudHMucmVtb3ZlKGV2ZW50TmFtZSwgbGlzdGVuZXIpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IE11bHRpcGxheWVyVGltZXIgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcblxuZXhwb3J0IGNsYXNzIFJhZ2VNUFRpbWVyIGltcGxlbWVudHMgTXVsdGlwbGF5ZXJUaW1lciB7XG4gICAgcHVibGljIGxhc3RUaWNrID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHVibGljIGlkOiBudW1iZXIsXG4gICAgICAgIHB1YmxpYyBpbnRlcnZhbDogbnVtYmVyID0gMCxcbiAgICAgICAgcHVibGljIG9uY2U6IGJvb2xlYW4sXG4gICAgICAgIHB1YmxpYyBjYWxsYmFjazogRnVuY3Rpb24sXG4gICAgICAgIHByaXZhdGUgY2xlYXJUaW1lcjogRnVuY3Rpb24sXG4gICAgKSB7fVxuXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5jbGVhclRpbWVyKCk7XG4gICAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgTXVsdGlwbGF5ZXJUaW1lciwgTXVsdGlwbGF5ZXJUaW1lcnMgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IFJhZ2VNUFRpbWVyIH0gZnJvbSAnLi9yYWdlbXAtdGltZXInO1xuXG5leHBvcnQgY2xhc3MgUmFnZU1QVGltZXJzIGltcGxlbWVudHMgTXVsdGlwbGF5ZXJUaW1lcnMge1xuICAgIHByaXZhdGUgdGltZXJJbmNyZW1lbnRlcjogbnVtYmVyID0gMDtcbiAgICBwcml2YXRlIHRpbWVycyA9IG5ldyBNYXA8bnVtYmVyLCBNdWx0aXBsYXllclRpbWVyPigpO1xuICAgIHByaXZhdGUgZXZlcnlUaWNrSGFuZGxlcnMgPSBuZXcgTWFwPG51bWJlciwgeyBjYWxsYmFjazogRnVuY3Rpb247IGJvdW5kOiBGdW5jdGlvbiB9PigpO1xuICAgIHByaXZhdGUgaXNFdmVyeVRpY2tSdW5uaW5nID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBldmVyeVRpY2tNYWluSGFuZGxlcjogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5cbiAgICBwdWJsaWMgZ2V0IGFsbCgpOiBNdWx0aXBsYXllclRpbWVyW10ge1xuICAgICAgICByZXR1cm4gWy4uLnRoaXMudGltZXJzLnZhbHVlcygpXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHdhcm5pbmdUaHJlc2hvbGQoKTogbnVtYmVyIHtcbiAgICAgICAgLy8gUmFnZU1QIGRvZXNuJ3QgaGF2ZSB0aGlzIGZlYXR1cmVcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgcHVibGljIHNldCB3YXJuaW5nVGhyZXNob2xkKF92YWx1ZTogbnVtYmVyKSB7XG4gICAgICAgIC8vIFJhZ2VNUCBkb2Vzbid0IGhhdmUgdGhpcyBmZWF0dXJlXG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzb3VyY2VMb2NhdGlvbkZyYW1lU2tpcENvdW50KCk6IG51bWJlciB7XG4gICAgICAgIC8vIFJhZ2VNUCBkb2Vzbid0IGhhdmUgdGhpcyBmZWF0dXJlXG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXQgc291cmNlTG9jYXRpb25GcmFtZVNraXBDb3VudChfdmFsdWU6IG51bWJlcikge1xuICAgICAgICAvLyBSYWdlTVAgZG9lc24ndCBoYXZlIHRoaXMgZmVhdHVyZVxuICAgIH1cblxuICAgIGdldEJ5SUQoaWQ6IG51bWJlcik6IE11bHRpcGxheWVyVGltZXIgfCBudWxsIHtcbiAgICAgICAgY29uc3QgdGltZXIgPSB0aGlzLnRpbWVycy5nZXQoaWQpO1xuICAgICAgICByZXR1cm4gdGltZXIgPz8gbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVRpbWVyKFxuICAgICAgICBjcmVhdGVUaW1lcjogKC4uLmFyZ3M6IGFueVtdKSA9PiBudW1iZXIsXG4gICAgICAgIGNsZWFyOiAoaWQ6IG51bWJlcikgPT4gdm9pZCxcbiAgICAgICAgY2FsbGJhY2s6IEZ1bmN0aW9uLFxuICAgICAgICBpbnRlcnZhbDogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgICAgICBvbmNlOiBib29sZWFuLFxuICAgICAgICAuLi5hcmdzOiB1bmtub3duW11cbiAgICApIHtcbiAgICAgICAgY29uc3QgY2FsbGJhY2tCaW5kID0gY2FsbGJhY2suYmluZCh0aGlzLCAuLi4oQXJyYXkuaXNBcnJheShhcmdzKSA/IGFyZ3MgOiBbXSkpO1xuICAgICAgICBjb25zdCB0aW1lcklkID0gdHlwZW9mIGludGVydmFsID09PSAnbnVtYmVyJyA/IGNyZWF0ZVRpbWVyKGNhbGxiYWNrQmluZCwgaW50ZXJ2YWwpIDogY3JlYXRlVGltZXIoY2FsbGJhY2tCaW5kKTtcbiAgICAgICAgY29uc3QgaWQgPSB0aGlzLnRpbWVySW5jcmVtZW50ZXIrKztcblxuICAgICAgICBjb25zdCByYWdlTVBUaW1lciA9IG5ldyBSYWdlTVBUaW1lcihpZCwgaW50ZXJ2YWwgPz8gMCwgb25jZSwgY2FsbGJhY2tCaW5kLCAoKSA9PiB7XG4gICAgICAgICAgICBjbGVhcih0aW1lcklkKTtcbiAgICAgICAgICAgIHRoaXMudGltZXJzLmRlbGV0ZShpZCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnRpbWVycy5zZXQoaWQsIHJhZ2VNUFRpbWVyKTtcbiAgICAgICAgcmV0dXJuIHJhZ2VNUFRpbWVyO1xuICAgIH1cblxuICAgIHNldEludGVydmFsKGNhbGxiYWNrOiBGdW5jdGlvbiwgdGltZTogbnVtYmVyLCAuLi5hcmdzOiB1bmtub3duW10pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlVGltZXIoXG4gICAgICAgICAgICAoY2I6IEZ1bmN0aW9uLCBpbnRlcnZhbDogbnVtYmVyKSA9PiBzZXRJbnRlcnZhbChjYiBhcyAoKSA9PiB2b2lkLCBpbnRlcnZhbCkgYXMgdW5rbm93biBhcyBudW1iZXIsXG4gICAgICAgICAgICAoaWQ6IG51bWJlcikgPT4gY2xlYXJJbnRlcnZhbChpZCksXG4gICAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICAgIHRpbWUsXG4gICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgIC4uLmFyZ3NcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KGNhbGxiYWNrOiBGdW5jdGlvbiwgdGltZTogbnVtYmVyLCAuLi5hcmdzOiB1bmtub3duW10pIHtcbiAgICAgICAgY29uc3QgaWQgPSB0aGlzLnRpbWVySW5jcmVtZW50ZXIrKztcbiAgICAgICAgY29uc3QgY2FsbGJhY2tCaW5kID0gY2FsbGJhY2suYmluZCh0aGlzLCAuLi4oQXJyYXkuaXNBcnJheShhcmdzKSA/IGFyZ3MgOiBbXSkpO1xuXG4gICAgICAgIGNvbnN0IHRpbWVySWQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrQmluZCgpO1xuICAgICAgICAgICAgdGhpcy50aW1lcnMuZGVsZXRlKGlkKTtcbiAgICAgICAgfSwgdGltZSkgYXMgdW5rbm93biBhcyBudW1iZXI7XG5cbiAgICAgICAgY29uc3QgcmFnZU1QVGltZXIgPSBuZXcgUmFnZU1QVGltZXIoaWQsIHRpbWUsIHRydWUsIGNhbGxiYWNrQmluZCwgKCkgPT4ge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgICAgICAgICAgdGhpcy50aW1lcnMuZGVsZXRlKGlkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudGltZXJzLnNldChpZCwgcmFnZU1QVGltZXIpO1xuICAgICAgICByZXR1cm4gcmFnZU1QVGltZXI7XG4gICAgfVxuXG4gICAgZXZlcnlUaWNrKGNhbGxiYWNrOiBGdW5jdGlvbiwgLi4uYXJnczogdW5rbm93bltdKSB7XG4gICAgICAgIGNvbnN0IGlkID0gdGhpcy50aW1lckluY3JlbWVudGVyKys7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrQmluZCA9IGNhbGxiYWNrLmJpbmQodGhpcywgLi4uKEFycmF5LmlzQXJyYXkoYXJncykgPyBhcmdzIDogW10pKTtcblxuICAgICAgICB0aGlzLmV2ZXJ5VGlja0hhbmRsZXJzLnNldChpZCwgeyBjYWxsYmFjaywgYm91bmQ6IGNhbGxiYWNrQmluZCB9KTtcblxuICAgICAgICAvLyBDaGVjayBpZiB3ZSdyZSBvbiBjbGllbnQtc2lkZSAocmVuZGVyIGV2ZW50IGV4aXN0cykgb3Igc2VydmVyLXNpZGVcbiAgICAgICAgY29uc3QgaXNDbGllbnRTaWRlID0gdHlwZW9mIG1wICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgKG1wIGFzIGFueSkuYnJvd3NlcnMgIT09ICd1bmRlZmluZWQnO1xuXG4gICAgICAgIC8vIFN0YXJ0IHRoZSB0aWNrIGxvb3AgaWYgbm90IGFscmVhZHkgcnVubmluZ1xuICAgICAgICBpZiAoIXRoaXMuaXNFdmVyeVRpY2tSdW5uaW5nKSB7XG4gICAgICAgICAgICB0aGlzLmlzRXZlcnlUaWNrUnVubmluZyA9IHRydWU7XG5cbiAgICAgICAgICAgIGlmIChpc0NsaWVudFNpZGUpIHtcbiAgICAgICAgICAgICAgICAvLyBDbGllbnQtc2lkZTogdXNlIHJlbmRlciBldmVudCBmb3IgZnJhbWUtYWNjdXJhdGUgdGlja2luZ1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlcnlUaWNrTWFpbkhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgWywgaGFuZGxlcl0gb2YgdGhpcy5ldmVyeVRpY2tIYW5kbGVycykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLmJvdW5kKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXAuY29uc29sZS5sb2dFcnJvcihgRXJyb3IgaW4gZXZlcnlUaWNrIGhhbmRsZXI6ICR7ZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbXAuZXZlbnRzLmFkZCgncmVuZGVyJywgdGhpcy5ldmVyeVRpY2tNYWluSGFuZGxlcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFNlcnZlci1zaWRlOiB1c2Ugc2V0SW50ZXJ2YWwgd2l0aCBtaW5pbWFsIGRlbGF5IGFzIGFwcHJveGltYXRpb25cbiAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnZhbEhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgWywgaGFuZGxlcl0gb2YgdGhpcy5ldmVyeVRpY2tIYW5kbGVycykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLmJvdW5kKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXAuY29uc29sZS5sb2dFcnJvcihgRXJyb3IgaW4gZXZlcnlUaWNrIGhhbmRsZXI6ICR7ZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgKHRoaXMgYXMgYW55KS5fZXZlcnlUaWNrSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChpbnRlcnZhbEhhbmRsZXIsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmFnZU1QVGltZXIgPSBuZXcgUmFnZU1QVGltZXIoaWQsIDAsIGZhbHNlLCBjYWxsYmFja0JpbmQsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZXZlcnlUaWNrSGFuZGxlcnMuZGVsZXRlKGlkKTtcbiAgICAgICAgICAgIHRoaXMudGltZXJzLmRlbGV0ZShpZCk7XG5cbiAgICAgICAgICAgIC8vIFN0b3AgdGhlIHRpY2sgbG9vcCBpZiBubyBtb3JlIGhhbmRsZXJzXG4gICAgICAgICAgICBpZiAodGhpcy5ldmVyeVRpY2tIYW5kbGVycy5zaXplID09PSAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzQ2xpZW50U2lkZSAmJiB0aGlzLmV2ZXJ5VGlja01haW5IYW5kbGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIG1wLmV2ZW50cy5yZW1vdmUoJ3JlbmRlcicsIHRoaXMuZXZlcnlUaWNrTWFpbkhhbmRsZXIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV2ZXJ5VGlja01haW5IYW5kbGVyID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCh0aGlzIGFzIGFueSkuX2V2ZXJ5VGlja0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoKHRoaXMgYXMgYW55KS5fZXZlcnlUaWNrSW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAodGhpcyBhcyBhbnkpLl9ldmVyeVRpY2tJbnRlcnZhbCA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuaXNFdmVyeVRpY2tSdW5uaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnRpbWVycy5zZXQoaWQsIHJhZ2VNUFRpbWVyKTtcbiAgICAgICAgcmV0dXJuIHJhZ2VNUFRpbWVyO1xuICAgIH1cblxuICAgIG5leHRUaWNrKGNhbGxiYWNrOiBGdW5jdGlvbiwgLi4uYXJnczogdW5rbm93bltdKSB7XG4gICAgICAgIGNvbnN0IGlkID0gdGhpcy50aW1lckluY3JlbWVudGVyKys7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrQmluZCA9IGNhbGxiYWNrLmJpbmQodGhpcywgLi4uKEFycmF5LmlzQXJyYXkoYXJncykgPyBhcmdzIDogW10pKTtcblxuICAgICAgICAvLyBDaGVjayBpZiB3ZSdyZSBvbiBjbGllbnQtc2lkZSAocmVuZGVyIGV2ZW50IGV4aXN0cykgb3Igc2VydmVyLXNpZGVcbiAgICAgICAgY29uc3QgaXNDbGllbnRTaWRlID0gdHlwZW9mIG1wICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgKG1wIGFzIGFueSkuYnJvd3NlcnMgIT09ICd1bmRlZmluZWQnO1xuXG4gICAgICAgIGxldCB0aW1lcklkOiBhbnk7XG5cbiAgICAgICAgaWYgKGlzQ2xpZW50U2lkZSkge1xuICAgICAgICAgICAgLy8gQ2xpZW50LXNpZGU6IHVzZSByZW5kZXIgZXZlbnQgZm9yIG5leHQgZnJhbWVcbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tCaW5kKCk7XG4gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgbXAuZXZlbnRzLnJlbW92ZSgncmVuZGVyJywgaGFuZGxlcik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGltZXJzLmRlbGV0ZShpZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIG1wLmV2ZW50cy5hZGQoJ3JlbmRlcicsIGhhbmRsZXIpO1xuXG4gICAgICAgICAgICBjb25zdCByYWdlTVBUaW1lciA9IG5ldyBSYWdlTVBUaW1lcihpZCwgMCwgdHJ1ZSwgY2FsbGJhY2tCaW5kLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgbXAuZXZlbnRzLnJlbW92ZSgncmVuZGVyJywgaGFuZGxlcik7XG4gICAgICAgICAgICAgICAgdGhpcy50aW1lcnMuZGVsZXRlKGlkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy50aW1lcnMuc2V0KGlkLCByYWdlTVBUaW1lcik7XG4gICAgICAgICAgICByZXR1cm4gcmFnZU1QVGltZXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXJ2ZXItc2lkZTogdXNlIHNldEltbWVkaWF0ZSBvciBzZXRUaW1lb3V0KDApIGZvciBuZXh0IHRpY2tcbiAgICAgICAgICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja0JpbmQoKTtcbiAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRpbWVycy5kZWxldGUoaWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIDApO1xuXG4gICAgICAgICAgICBjb25zdCByYWdlTVBUaW1lciA9IG5ldyBSYWdlTVBUaW1lcihpZCwgMCwgdHJ1ZSwgY2FsbGJhY2tCaW5kLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgICAgICAgICAgICAgIHRoaXMudGltZXJzLmRlbGV0ZShpZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMudGltZXJzLnNldChpZCwgcmFnZU1QVGltZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHJhZ2VNUFRpbWVyO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGltZShfbmFtZT86IHN0cmluZykge1xuICAgICAgICAvLyBSYWdlTVAgZG9lc24ndCBoYXZlIGNvbnNvbGUudGltZSBlcXVpdmFsZW50XG4gICAgICAgIC8vIENvdWxkIGltcGxlbWVudCBjdXN0b20gdGltaW5nIGlmIG5lZWRlZFxuICAgIH1cblxuICAgIHRpbWVFbmQoX25hbWU/OiBzdHJpbmcpIHtcbiAgICAgICAgLy8gUmFnZU1QIGRvZXNuJ3QgaGF2ZSBjb25zb2xlLnRpbWVFbmQgZXF1aXZhbGVudFxuICAgIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IEV2ZW50RW1taXRlciwgTXVsdGlwbGF5ZXJTZXJ2aWNlLCBNdWx0aXBsYXllclRpbWVycyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgUmFnZU1QRXZlbnRFbW1pdGVyIH0gZnJvbSAnLi9yYWdlbXAtZXZlbnQtZW1taXRlcic7XG5pbXBvcnQgeyBSYWdlTVBUaW1lcnMgfSBmcm9tICcuL3JhZ2VtcC10aW1lcnMnO1xuaW1wb3J0IHsgaXNPYmplY3QgfSBmcm9tICcuLi8uLi8uLi91dGlscyc7XG5cbmV4cG9ydCBjbGFzcyBSYWdlTVBNdWx0aXBsYXllclNlcnZpY2UgaW1wbGVtZW50cyBNdWx0aXBsYXllclNlcnZpY2Uge1xuICAgIHJlYWRvbmx5IFRpbWVyczogTXVsdGlwbGF5ZXJUaW1lcnM7XG4gICAgcmVhZG9ubHkgRXZlbnRzOiBFdmVudEVtbWl0ZXI7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5FdmVudHMgPSBuZXcgUmFnZU1QRXZlbnRFbW1pdGVyKCk7XG4gICAgICAgIHRoaXMuVGltZXJzID0gbmV3IFJhZ2VNUFRpbWVycygpO1xuICAgIH1cblxuICAgIHBhcnNlSW50ZXJuYWxBcmdzPFUgPSB1bmtub3duLCBUID0gdW5rbm93bj4oXG4gICAgICAgIC4uLmFyZ3M6IGFueVxuICAgICk6IHtcbiAgICAgICAgcGxheWVyPzogVTtcbiAgICAgICAgYm9keT86IFQ7XG4gICAgfSB7XG4gICAgICAgIGNvbnN0IHBsYXllciA9IChpc09iamVjdChhcmdzWzBdKSA/IGFyZ3NbMF0gOiB1bmRlZmluZWQpIGFzIFU7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHBsYXllcixcbiAgICAgICAgICAgIGJvZHk6IGFyZ3MsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgbG9nKGFyZzogYW55LCAuLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gW2FyZywgLi4uYXJnc10ubWFwKGEgPT5cbiAgICAgICAgICAgIHR5cGVvZiBhID09PSAnb2JqZWN0JyA/IEpTT04uc3RyaW5naWZ5KGEpIDogU3RyaW5nKGEpXG4gICAgICAgICkuam9pbignICcpO1xuICAgICAgICBtcC5jb25zb2xlLmxvZ0luZm8obWVzc2FnZSk7XG4gICAgfVxuXG4gICAgbG9nRXJyb3IoYXJnOiBhbnksIC4uLmFyZ3M6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBbYXJnLCAuLi5hcmdzXS5tYXAoYSA9PlxuICAgICAgICAgICAgdHlwZW9mIGEgPT09ICdvYmplY3QnID8gSlNPTi5zdHJpbmdpZnkoYSkgOiBTdHJpbmcoYSlcbiAgICAgICAgKS5qb2luKCcgJyk7XG4gICAgICAgIG1wLmNvbnNvbGUubG9nRXJyb3IobWVzc2FnZSk7XG4gICAgfVxuXG4gICAgbG9nV2FybmluZyhhcmc6IGFueSwgLi4uYXJnczogYW55W10pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IFthcmcsIC4uLmFyZ3NdLm1hcChhID0+XG4gICAgICAgICAgICB0eXBlb2YgYSA9PT0gJ29iamVjdCcgPyBKU09OLnN0cmluZ2lmeShhKSA6IFN0cmluZyhhKVxuICAgICAgICApLmpvaW4oJyAnKTtcbiAgICAgICAgbXAuY29uc29sZS5sb2dXYXJuaW5nKG1lc3NhZ2UpO1xuICAgIH1cblxuICAgIGxvZ0RlYnVnKGFyZzogYW55LCAuLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgICAgICAvLyBSYWdlTVAgZG9lc24ndCBoYXZlIGEgZGVkaWNhdGVkIGRlYnVnIGxvZywgdXNlIGluZm9cbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IFthcmcsIC4uLmFyZ3NdLm1hcChhID0+XG4gICAgICAgICAgICB0eXBlb2YgYSA9PT0gJ29iamVjdCcgPyBKU09OLnN0cmluZ2lmeShhKSA6IFN0cmluZyhhKVxuICAgICAgICApLmpvaW4oJyAnKTtcbiAgICAgICAgbXAuY29uc29sZS5sb2dJbmZvKGBbREVCVUddICR7bWVzc2FnZX1gKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgdmFsaWRhdGVFcnJvckZpbHRlciwgdmFsaWRhdGVHdWFyZCwgdmFsaWRhdGVJbnRlcmNlcHRvciwgdmFsaWRhdGVQaXBlIH0gZnJvbSAnLi4vc2NoZW1hcy9ldmVudHMnO1xuaW1wb3J0IHtcbiAgICBJTlRFUk5BTF9BUFBfQ09OVEFJTkVSLFxuICAgIEdMT0JBTF9FUlJPUl9GSUxURVJTLFxuICAgIEdMT0JBTF9HVUFSRFMsXG4gICAgR0xPQkFMX0lOVEVSQ0VQVE9SUyxcbiAgICBHTE9CQUxfUElQRVMsXG4gICAgRU5BQkxFX1NIVVRET1dOX0hPT0tTLFxuICAgIFBMVUdJTlMsXG4gICAgR0xPQkFMX0FQUF9DT05UQUlORVIsXG4gICAgQVBQX0VOVklST01FTlQsXG4gICAgTUFOR09fUkVRVUVTVF9GQUNUT1JZLFxuICAgIE1BTkdPX1JFU1BPTlNFX0ZBQ1RPUlksXG4gICAgRVhFQ1VUSU9OX0NPTlRFWFRfRkFDVE9SWSxcbiAgICBDT05UQUlORVJfT1BUSU9OUyxcbiAgICBNVUxUSVBMQVlFUl9TRVJWSUNFLFxufSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBpbmplY3QsIENvbnRhaW5lciwgaW5qZWN0YWJsZSwgdHlwZSBpbnRlcmZhY2VzIH0gZnJvbSAnaW52ZXJzaWZ5JztcbmltcG9ydCB7IEFwcCB9IGZyb20gJy4vYXBwJztcbmltcG9ydCB0eXBlIHsgRXJyb3JGaWx0ZXIsIEd1YXJkLCBJbnRlcmNlcHRvciwgTWFuZ29QbHVnaW4sIE11bHRpcGxheWVyU2VydmljZSB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgdHlwZSB7IFBpcGUgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7XG4gICAgQ29udHJvbGxlckV2ZW50SGFuZGxlcixcbiAgICBDb250cm9sbGVyRmxvd0hhbmRsZXIsXG4gICAgQ29udHJvbGxlck1ldGFkYXRhUmVhZGVyLFxuICAgIENvbnRyb2xsZXJSUENIYW5kbGVyLFxuICAgIFBpcGVsaW5lSGFuZGxlcixcbn0gZnJvbSAnLi9jb250cm9sbGVyJztcbmltcG9ydCB7IE1vZHVsZSwgTW9kdWxlTWV0YWRhdGFSZWFkZXIgfSBmcm9tICcuL21vZHVsZSc7XG5pbXBvcnQgeyBBcHBSdW50aW1lLCBNb2R1bGVEZXBlbmRlbmN5QmluZGVyLCBNb2R1bGVUcmVlU2Nhbm5lciB9IGZyb20gJy4vbW9kdWxlLXRyZWUnO1xuaW1wb3J0IHsgQ29udHJvbGxlciB9IGZyb20gJy4vY29udHJvbGxlcic7XG5pbXBvcnQgeyBFeGVjdXRpb25Db250ZXh0QmFzZSwgTWFuZ29SZXF1ZXN0QmFzZSwgTWFuZ29SZXNwb25zZUJhc2UgfSBmcm9tICcuL3BpcGVsaW5lJztcbmltcG9ydCB0eXBlIHsgRXhlY3V0aW9uQ29udGV4dFR5cGUgfSBmcm9tICcuL2VudW1zJztcbmltcG9ydCB7IFJFRkxFQ1RPUl9TRVJWSUNFIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IFJlZmxlY3RvclNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcyc7XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBcHBCdWlsZGVyPEcgZXh0ZW5kcyBHdWFyZCA9IEd1YXJkLCBJIGV4dGVuZHMgSW50ZXJjZXB0b3IgPSBJbnRlcmNlcHRvciwgRUYgZXh0ZW5kcyBFcnJvckZpbHRlciA9IEVycm9yRmlsdGVyPiB7XG4gICAgQGluamVjdChBUFBfRU5WSVJPTUVOVCkgcHJvdGVjdGVkIHJlYWRvbmx5IGVudmlyb21lbnQ6IHN0cmluZztcbiAgICBAaW5qZWN0KElOVEVSTkFMX0FQUF9DT05UQUlORVIpIHByb3RlY3RlZCByZWFkb25seSBpbnRlcm5hbEFwcENvbnRhaW5lcjogQ29udGFpbmVyO1xuICAgIEBpbmplY3QoTVVMVElQTEFZRVJfU0VSVklDRSkgcHJvdGVjdGVkIHJlYWRvbmx5IG11bHRpcGxheWVyU2VydmljZTogTXVsdGlwbGF5ZXJTZXJ2aWNlO1xuICAgIEBpbmplY3QoUExVR0lOUykgcHJvdGVjdGVkIHJlYWRvbmx5IHBsdWdpbnM6IE5ld2FibGU8TWFuZ29QbHVnaW4+W107XG5cbiAgICBwcml2YXRlIGdsb2JhbENvbnRhaW5lck9wdGlvbnM6IGludGVyZmFjZXMuQ29udGFpbmVyT3B0aW9ucyA9IHt9O1xuXG4gICAgcHVibGljIHVzZUdsb2JhbEd1YXJkcyguLi5ndWFyZHM6IChOZXdhYmxlPEc+IHwgRylbXSkge1xuICAgICAgICBjb25zdCB2YWxpZGF0ZWRHdWFyZHM6IChOZXdhYmxlPEc+IHwgRylbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGd1YXJkIG9mIGd1YXJkcykge1xuICAgICAgICAgICAgY29uc3QgeyB2YWxpZCwgdmFsdWUsIGVycm9yIH0gPSB2YWxpZGF0ZUd1YXJkKGd1YXJkKTtcbiAgICAgICAgICAgIGlmICghdmFsaWQpIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgICAgICAgICB2YWxpZGF0ZWRHdWFyZHMucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmludGVybmFsQXBwQ29udGFpbmVyLmJpbmQoR0xPQkFMX0dVQVJEUykudG9Db25zdGFudFZhbHVlKHZhbGlkYXRlZEd1YXJkcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHB1YmxpYyB1c2VHbG9iYWxJbnRlcmNlcHRvcnMoLi4uaW50ZXJjZXB0b3JzOiAoTmV3YWJsZTxJPiB8IEkpW10pIHtcbiAgICAgICAgY29uc3QgdmFsaWRhdGVkSW50ZXJjZXB0b3JzOiAoTmV3YWJsZTxJPiB8IEkpW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBpbnRlcmNlcHRvciBvZiBpbnRlcmNlcHRvcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgdmFsaWQsIHZhbHVlLCBlcnJvciB9ID0gdmFsaWRhdGVJbnRlcmNlcHRvcihpbnRlcmNlcHRvcik7XG4gICAgICAgICAgICBpZiAoIXZhbGlkKSB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgdmFsaWRhdGVkSW50ZXJjZXB0b3JzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKEdMT0JBTF9JTlRFUkNFUFRPUlMpLnRvQ29uc3RhbnRWYWx1ZSh2YWxpZGF0ZWRJbnRlcmNlcHRvcnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBwdWJsaWMgdXNlR2xvYmFsUGlwZXMoLi4ucGlwZXM6IChOZXdhYmxlPFBpcGU+IHwgUGlwZSlbXSkge1xuICAgICAgICBjb25zdCB2YWxpZGF0ZWRQaXBlczogKE5ld2FibGU8UGlwZT4gfCBQaXBlKVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcGlwZSBvZiBwaXBlcykge1xuICAgICAgICAgICAgY29uc3QgeyB2YWxpZCwgdmFsdWUsIGVycm9yIH0gPSB2YWxpZGF0ZVBpcGUocGlwZSk7XG4gICAgICAgICAgICBpZiAoIXZhbGlkKSB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgdmFsaWRhdGVkUGlwZXMucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmludGVybmFsQXBwQ29udGFpbmVyLmJpbmQoR0xPQkFMX1BJUEVTKS50b0NvbnN0YW50VmFsdWUodmFsaWRhdGVkUGlwZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBwdWJsaWMgdXNlR2xvYmFsRmlsdGVycyguLi5maWx0ZXJzOiAoTmV3YWJsZTxFRj4gfCBFRilbXSkge1xuICAgICAgICBjb25zdCB2YWxpZGF0ZWRGSWx0ZXJzOiAoTmV3YWJsZTxFRj4gfCBFRilbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGZpbHRlciBvZiBmaWx0ZXJzKSB7XG4gICAgICAgICAgICBjb25zdCB7IHZhbGlkLCB2YWx1ZSwgZXJyb3IgfSA9IHZhbGlkYXRlRXJyb3JGaWx0ZXIoZmlsdGVyKTtcbiAgICAgICAgICAgIGlmICghdmFsaWQpIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgICAgICAgICB2YWxpZGF0ZWRGSWx0ZXJzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKEdMT0JBTF9FUlJPUl9GSUxURVJTKS50b0NvbnN0YW50VmFsdWUodmFsaWRhdGVkRklsdGVycyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHB1YmxpYyB1c2VQbHVnaW5zKC4uLnBsdWdpbnM6IE5ld2FibGU8TWFuZ29QbHVnaW4+W10pIHtcbiAgICAgICAgcGx1Z2lucy5mb3JFYWNoKChwKSA9PiB0aGlzLmludGVybmFsQXBwQ29udGFpbmVyLmJpbmQocCkudG9TZWxmKCkuaW5TaW5nbGV0b25TY29wZSgpKTtcbiAgICAgICAgY29uc3QgaW50ZXJuYWxQbHVnaW5zID0gdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5nZXQ8TmV3YWJsZTxNYW5nb1BsdWdpbj5bXT4oUExVR0lOUyk7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIucmViaW5kKFBMVUdJTlMpLnRvQ29uc3RhbnRWYWx1ZShbLi4uaW50ZXJuYWxQbHVnaW5zLCAuLi5wbHVnaW5zXSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHB1YmxpYyBlbmFibGVTaHV0ZG93bkhvb2tzKCkge1xuICAgICAgICB0aGlzLmludGVybmFsQXBwQ29udGFpbmVyLmJpbmQoRU5BQkxFX1NIVVRET1dOX0hPT0tTKS50b0NvbnN0YW50VmFsdWUodHJ1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRDb250YWluZXJPcHRpb25zKG9wdGlvbnM6IGludGVyZmFjZXMuQ29udGFpbmVyT3B0aW9ucywgb25seUdsb2JhbCA9IGZhbHNlKSB7XG4gICAgICAgIHRoaXMuZ2xvYmFsQ29udGFpbmVyT3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIGlmIChvbmx5R2xvYmFsKSByZXR1cm4gdGhpcztcbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKENPTlRBSU5FUl9PUFRJT05TKS50b0NvbnN0YW50VmFsdWUob3B0aW9ucyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBidWlsZCgpIHtcbiAgICAgICAgY29uc3QgZ2xvYmFsQXBwQ29udGFpbmVyID0gbmV3IENvbnRhaW5lcih0aGlzLmdsb2JhbENvbnRhaW5lck9wdGlvbnMpO1xuICAgICAgICAvLyBHTG9iYWwgc2VydmljZSBiaW5kaW5nc1xuICAgICAgICBnbG9iYWxBcHBDb250YWluZXIuYmluZChSRUZMRUNUT1JfU0VSVklDRSkudG9Db25zdGFudFZhbHVlKFJlZmxlY3RvclNlcnZpY2UpO1xuICAgICAgICBnbG9iYWxBcHBDb250YWluZXIuYmluZChSZWZsZWN0b3JTZXJ2aWNlKS50b1NlcnZpY2UoUkVGTEVDVE9SX1NFUlZJQ0UpO1xuXG4gICAgICAgIC8vIE11bHRpcGxheWVyIHNlcnZpY2UgYmluZGluZ3NcbiAgICAgICAgZ2xvYmFsQXBwQ29udGFpbmVyLmJpbmQoTVVMVElQTEFZRVJfU0VSVklDRSkudG9Db25zdGFudFZhbHVlKHRoaXMubXVsdGlwbGF5ZXJTZXJ2aWNlKTtcbiBcbiAgICAgICAgLy8gQXBwIGJpbmRpbmdzXG4gICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChBcHApLnRvU2VsZigpLmluU2luZ2xldG9uU2NvcGUoKTtcbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKEdMT0JBTF9BUFBfQ09OVEFJTkVSKS50b0NvbnN0YW50VmFsdWUoZ2xvYmFsQXBwQ29udGFpbmVyKTtcblxuICAgICAgICAvLyBNb2R1bGUgdHJlZSBiaW5kaW5nc1xuICAgICAgICB0aGlzLmludGVybmFsQXBwQ29udGFpbmVyLmJpbmQoTW9kdWxlVHJlZVNjYW5uZXIpLnRvU2VsZigpLmluU2luZ2xldG9uU2NvcGUoKTtcbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKE1vZHVsZURlcGVuZGVuY3lCaW5kZXIpLnRvU2VsZigpLmluU2luZ2xldG9uU2NvcGUoKTtcbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKEFwcFJ1bnRpbWUpLnRvU2VsZigpLmluU2luZ2xldG9uU2NvcGUoKTtcblxuICAgICAgICAvLyBBcHAgYmluZGluZ3NcbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKFBpcGVsaW5lSGFuZGxlcikudG9TZWxmKCkuaW5TaW5nbGV0b25TY29wZSgpO1xuXG4gICAgICAgIC8vIE1vZHVsZSBiaW5kaW5nc1xuICAgICAgICB0aGlzLmludGVybmFsQXBwQ29udGFpbmVyLmJpbmQoTW9kdWxlKS50b1NlbGYoKS5pblRyYW5zaWVudFNjb3BlKCk7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChNb2R1bGVNZXRhZGF0YVJlYWRlcikudG9TZWxmKCkuaW5TaW5nbGV0b25TY29wZSgpO1xuXG4gICAgICAgIC8vIENvbnRyb2xsZXIgYmluZGluZ3NcbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKENvbnRyb2xsZXIpLnRvU2VsZigpLmluVHJhbnNpZW50U2NvcGUoKTtcbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKENvbnRyb2xsZXJNZXRhZGF0YVJlYWRlcikudG9TZWxmKCkuaW5TaW5nbGV0b25TY29wZSgpO1xuICAgICAgICB0aGlzLmludGVybmFsQXBwQ29udGFpbmVyLmJpbmQoQ29udHJvbGxlckZsb3dIYW5kbGVyKS50b1NlbGYoKS5pblNpbmdsZXRvblNjb3BlKCk7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChDb250cm9sbGVyRXZlbnRIYW5kbGVyKS50b1NlbGYoKS5pblNpbmdsZXRvblNjb3BlKCk7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChDb250cm9sbGVyUlBDSGFuZGxlcikudG9TZWxmKCkuaW5TaW5nbGV0b25TY29wZSgpO1xuXG4gICAgICAgIC8vIE1hbmdvIFJlcXVlc3QgYW5kIFJlc3BvbnNlIGJpbmRpbmdzXG4gICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChNYW5nb1JlcXVlc3RCYXNlKS50b1NlbGYoKS5pblRyYW5zaWVudFNjb3BlKCk7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChNQU5HT19SRVFVRVNUX0ZBQ1RPUlkpLnRvRmFjdG9yeSgoY29udGV4dCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChib2R5OiB1bmtub3duLCBwbGF5ZXI6IFBsYXllck1wKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IGNvbnRleHQuY29udGFpbmVyLmdldChNYW5nb1JlcXVlc3RCYXNlKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0LiRib2R5ID0gYm9keTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0LiRwbGF5ZXIgPSBwbGF5ZXI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKE1hbmdvUmVzcG9uc2VCYXNlKS50b1NlbGYoKS5pblRyYW5zaWVudFNjb3BlKCk7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChNQU5HT19SRVNQT05TRV9GQUNUT1JZKS50b0ZhY3RvcnkoKGNvbnRleHQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuY29udGFpbmVyLmdldChNYW5nb1Jlc3BvbnNlQmFzZSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKEV4ZWN1dGlvbkNvbnRleHRCYXNlKS50b1NlbGYoKS5pblRyYW5zaWVudFNjb3BlKCk7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChFWEVDVVRJT05fQ09OVEVYVF9GQUNUT1JZKS50b0ZhY3RvcnkoKGNvbnRleHQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgdHlwZTogRXhlY3V0aW9uQ29udGV4dFR5cGUsXG4gICAgICAgICAgICAgICAgY2xhc3NSZWY6IE5ld2FibGUsXG4gICAgICAgICAgICAgICAgaGFuZGxlcjogRnVuY3Rpb24sXG4gICAgICAgICAgICAgICAgcmVxdWVzdDogTWFuZ29SZXF1ZXN0QmFzZSxcbiAgICAgICAgICAgICAgICByZXNwb25zZTogTWFuZ29SZXNwb25zZUJhc2UsXG4gICAgICAgICAgICAgICAgbmFtZTogc3RyaW5nLFxuICAgICAgICAgICAgKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXhlY3V0aW9uQ29udGV4dCA9IGNvbnRleHQuY29udGFpbmVyLmdldChFeGVjdXRpb25Db250ZXh0QmFzZSk7XG4gICAgICAgICAgICAgICAgZXhlY3V0aW9uQ29udGV4dC4kdHlwZSA9IHR5cGU7XG4gICAgICAgICAgICAgICAgZXhlY3V0aW9uQ29udGV4dC4kcmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgICAgICAgICAgICAgZXhlY3V0aW9uQ29udGV4dC4kcmVzcG9uc2UgPSByZXNwb25zZTtcbiAgICAgICAgICAgICAgICBleGVjdXRpb25Db250ZXh0LiRoYW5kbGVyID0gaGFuZGxlcjtcbiAgICAgICAgICAgICAgICBleGVjdXRpb25Db250ZXh0LiRjbGFzc1JlZiA9IGNsYXNzUmVmO1xuICAgICAgICAgICAgICAgIGV4ZWN1dGlvbkNvbnRleHQuJG5hbWUgPSBuYW1lO1xuICAgICAgICAgICAgICAgIHJldHVybiBleGVjdXRpb25Db250ZXh0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUGx1Z2lucyBiaW5kaW5nc1xuICAgICAgICBmb3IgKGNvbnN0IHBsdWdpbiBvZiB0aGlzLnBsdWdpbnMpIHtcbiAgICAgICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChwbHVnaW4pLnRvU2VsZigpLmluU2luZ2xldG9uU2NvcGUoKTtcbiAgICAgICAgICAgIGNvbnN0IHBsdWdpbkluc3RhbmNlID0gdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5nZXQocGx1Z2luKTtcbiAgICAgICAgICAgIGlmICghcGx1Z2luSW5zdGFuY2Uub25CdWlsZCkgY29udGludWU7XG4gICAgICAgICAgICBhd2FpdCBwbHVnaW5JbnN0YW5jZS5vbkJ1aWxkKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuaXNCb3VuZChHTE9CQUxfR1VBUkRTKSkgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKEdMT0JBTF9HVUFSRFMpLnRvQ29uc3RhbnRWYWx1ZShbXSk7XG4gICAgICAgIGlmICghdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5pc0JvdW5kKEdMT0JBTF9JTlRFUkNFUFRPUlMpKVxuICAgICAgICAgICAgdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKEdMT0JBTF9JTlRFUkNFUFRPUlMpLnRvQ29uc3RhbnRWYWx1ZShbXSk7XG4gICAgICAgIGlmICghdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5pc0JvdW5kKEdMT0JBTF9QSVBFUykpIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChHTE9CQUxfUElQRVMpLnRvQ29uc3RhbnRWYWx1ZShbXSk7XG4gICAgICAgIGlmICghdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5pc0JvdW5kKEdMT0JBTF9FUlJPUl9GSUxURVJTKSlcbiAgICAgICAgICAgIHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChHTE9CQUxfRVJST1JfRklMVEVSUykudG9Db25zdGFudFZhbHVlKFtdKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5pbnRlcm5hbEFwcENvbnRhaW5lci5nZXQoQXBwKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgQ29udGFpbmVyLCBpbmplY3QsIGluamVjdGFibGUgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHsgTW9kdWxlRGVwZW5kZW5jeUJpbmRlciwgTW9kdWxlVHJlZVNjYW5uZXIgfSBmcm9tICcuL21vZHVsZS10cmVlJztcbmltcG9ydCB7IE1vZHVsZSB9IGZyb20gJy4vbW9kdWxlL21vZHVsZSc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBJTlRFUk5BTF9BUFBfQ09OVEFJTkVSLCBQTFVHSU5TIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgQXBwUnVudGltZSB9IGZyb20gJy4vbW9kdWxlLXRyZWUnO1xuaW1wb3J0IHR5cGUgeyBNYW5nb1BsdWdpbiB9IGZyb20gJy4vaW50ZXJmYWNlcy9jb3JlL21hbmdvLXBsdWdpbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBUcmVlIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyB0eXBlIExvZ2dlclNlcnZpY2UgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IExPR0dFUl9TRVJWSUNFIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuQGluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEFwcCB7XG4gICAgQGluamVjdChNb2R1bGVUcmVlU2Nhbm5lcikgcHJpdmF0ZSByZWFkb25seSBtb2R1bGVUcmVlU2Nhbm5lcjogTW9kdWxlVHJlZVNjYW5uZXI7XG4gICAgQGluamVjdChNb2R1bGVEZXBlbmRlbmN5QmluZGVyKSBwcml2YXRlIHJlYWRvbmx5IG1vZHVsZURlcGVuZGVuY3lCaW5kZXI6IE1vZHVsZURlcGVuZGVuY3lCaW5kZXI7XG4gICAgQGluamVjdChBcHBSdW50aW1lKSBwcml2YXRlIHJlYWRvbmx5IGFwcFJ1bnRpbWU6IEFwcFJ1bnRpbWU7XG4gICAgQGluamVjdChJTlRFUk5BTF9BUFBfQ09OVEFJTkVSKSBwcml2YXRlIHJlYWRvbmx5IGludGVybmFsQXBwQ29udGFpbmVyOiBDb250YWluZXI7XG4gICAgQGluamVjdChQTFVHSU5TKSBwcml2YXRlIHJlYWRvbmx5IHBsdWdpbnM6IE5ld2FibGU8TWFuZ29QbHVnaW4+W107XG4gICAgQGluamVjdChMT0dHRVJfU0VSVklDRSkgcHJpdmF0ZSByZWFkb25seSBsb2dnZXJTZXJ2aWNlOiBMb2dnZXJTZXJ2aWNlO1xuICAgIHByaXZhdGUgbW9kdWxlVHJlZTogVHJlZTxNb2R1bGU+O1xuICAgIHByaXZhdGUgbG9hZGVkID0gZmFsc2U7XG5cbiAgICBwdWJsaWMgYXN5bmMgc3RhcnQ8VD4ocm9vdE1vZHVsZTogTmV3YWJsZTxUPikge1xuICAgICAgICBpZiAodGhpcy5sb2FkZWQpIHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignRXJyb3Igb2NjdXJyZWQgd2hpbGUgc3RhcnRpbmcgdGhlIGFwcC4nKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuQXBwQWxyZWFkeUxvYWRlZCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZygnfmx3flN0YXJ0aW5nIGFwcC4uLicpO1xuICAgICAgICBhd2FpdCB0aGlzLnJ1blBsdWdpbk1ldGhvZHMoJ2JlZm9yZVN0YXJ0Jyk7XG5cbiAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZygnfmx3flNjYW5uaW5nIG1vZHVsZSB0cmVlLi4uJyk7XG4gICAgICAgIGF3YWl0IHRoaXMucnVuUGx1Z2luTWV0aG9kcygnYmVmb3JlU2NhbicpO1xuICAgICAgICB0aGlzLm1vZHVsZVRyZWUgPSBhd2FpdCB0aGlzLm1vZHVsZVRyZWVTY2FubmVyLnNjYW4ocm9vdE1vZHVsZSk7XG4gICAgICAgIGF3YWl0IHRoaXMucnVuUGx1Z2luTWV0aG9kcygnYWZ0ZXJTY2FuJyk7XG5cbiAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmxvZygnfmx3fkJpbmRpbmcgbW9kdWxlIGRlcGVuZGVuY2llcy4uLicpO1xuICAgICAgICBhd2FpdCB0aGlzLnJ1blBsdWdpbk1ldGhvZHMoJ2JlZm9yZUJpbmQnKTtcbiAgICAgICAgYXdhaXQgdGhpcy5tb2R1bGVEZXBlbmRlbmN5QmluZGVyLmJpbmQodGhpcy5tb2R1bGVUcmVlKTtcbiAgICAgICAgYXdhaXQgdGhpcy5ydW5QbHVnaW5NZXRob2RzKCdhZnRlckJpbmQnKTtcblxuICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UubG9nKCd+bHd+TG9hZGluZyBhcHAuLi4nKTtcbiAgICAgICAgYXdhaXQgdGhpcy5ydW5QbHVnaW5NZXRob2RzKCdiZWZvcmVMb2FkJyk7XG4gICAgICAgIGF3YWl0IHRoaXMuYXBwUnVudGltZS5ib290KHRoaXMubW9kdWxlVHJlZSk7XG4gICAgICAgIHRoaXMubG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgYXdhaXQgdGhpcy5ydW5QbHVnaW5NZXRob2RzKCdhZnRlckxvYWQnKTtcblxuICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UubG9nKCd+bHd+QXBwIGxvYWRlZCcpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMucnVuUGx1Z2luTWV0aG9kcygnYWZ0ZXJTdGFydCcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzdG9wKCkge1xuICAgICAgICBpZiAoIXRoaXMubG9hZGVkKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UuZXJyb3IoJ0Vycm9yIG9jY3VycmVkIHdoaWxlIHN0b3BwaW5nIHRoZSBhcHAuJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkFwcE5vdExvYWRlZCk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5ydW5QbHVnaW5NZXRob2RzKCdiZWZvcmVTdG9wJyk7XG4gICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2coJ35sd35TdG9wcGluZyBhcHAuLi4nKTtcbiAgICAgICAgYXdhaXQgdGhpcy5hcHBSdW50aW1lLnNodXRkb3duKHRoaXMubW9kdWxlVHJlZSk7XG4gICAgICAgIHRoaXMubG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5sb2coJ35sd35BcHAgc3RvcHBlZCcpO1xuICAgICAgICBhd2FpdCB0aGlzLnJ1blBsdWdpbk1ldGhvZHMoJ2FmdGVyU3RvcCcpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcnVuUGx1Z2luTWV0aG9kcyhtZXRob2Q6IGtleW9mIE1hbmdvUGx1Z2luKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLm1hcChhc3luYyAocCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBsdWdpbiA9IHRoaXMuaW50ZXJuYWxBcHBDb250YWluZXIuZ2V0KHApO1xuICAgICAgICAgICAgICAgIGlmICghcGx1Z2luW21ldGhvZF0pIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBsdWdpblttZXRob2RdISgpKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBDb250YWluZXIgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHsgQVBQX0VOVklST01FTlQsIElOVEVSTkFMX0FQUF9DT05UQUlORVIsIE1VTFRJUExBWUVSX1NFUlZJQ0UsIFBMVUdJTlMgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgdHlwZSB7IE1hbmdvUGx1Z2luLCBNdWx0aXBsYXllclNlcnZpY2UgfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuaW1wb3J0IHR5cGUgeyBBcHBFbnZpcm9tZW50IH0gZnJvbSAnLi9lbnVtcyc7XG5pbXBvcnQgdHlwZSB7IEFwcEJ1aWxkZXIgfSBmcm9tICcuL2FwcC1idWlsZGVyJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUFwcEJ1aWxkZXI8VCBleHRlbmRzIEFwcEJ1aWxkZXI+KHtcbiAgICBlbnZpcm9tZW50LFxuICAgIHBsdWdpbnMsXG4gICAgYXBwQnVpbGRlckluaGVyaXQsXG4gICAgbXVsdGlwbGF5ZXJTZXJ2aWNlLFxufToge1xuICAgIGVudmlyb21lbnQ6IEFwcEVudmlyb21lbnQ7XG4gICAgcGx1Z2luczogTmV3YWJsZTxNYW5nb1BsdWdpbj5bXTtcbiAgICBhcHBCdWlsZGVySW5oZXJpdDogTmV3YWJsZTxUPjtcbiAgICBtdWx0aXBsYXllclNlcnZpY2U/OiBNdWx0aXBsYXllclNlcnZpY2U7XG59KSB7XG4gICAgY29uc3QgaW50ZXJuYWxBcHBDb250YWluZXIgPSBuZXcgQ29udGFpbmVyKCk7XG5cbiAgICBpZiAobXVsdGlwbGF5ZXJTZXJ2aWNlKSBpbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKE1VTFRJUExBWUVSX1NFUlZJQ0UpLnRvQ29uc3RhbnRWYWx1ZShtdWx0aXBsYXllclNlcnZpY2UpO1xuICAgIGludGVybmFsQXBwQ29udGFpbmVyLmJpbmQoSU5URVJOQUxfQVBQX0NPTlRBSU5FUikudG9Db25zdGFudFZhbHVlKGludGVybmFsQXBwQ29udGFpbmVyKTtcbiAgICBpbnRlcm5hbEFwcENvbnRhaW5lci5iaW5kKEFQUF9FTlZJUk9NRU5UKS50b0NvbnN0YW50VmFsdWUoZW52aXJvbWVudCk7XG4gICAgaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChQTFVHSU5TKS50b0NvbnN0YW50VmFsdWUocGx1Z2lucyk7XG4gICAgaW50ZXJuYWxBcHBDb250YWluZXIuYmluZChhcHBCdWlsZGVySW5oZXJpdCkudG9TZWxmKCkuaW5TaW5nbGV0b25TY29wZSgpO1xuXG4gICAgcmV0dXJuIGludGVybmFsQXBwQ29udGFpbmVyLmdldChhcHBCdWlsZGVySW5oZXJpdCk7XG59XG4iLCAiaW1wb3J0IHsgaXNOaWwsIGlzU3RyaW5nIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHsgQ29yZU1ldGFkYXRhS2V5LCB0eXBlIEV2ZW50TWV0YWRhdGEsIHR5cGUgUGlwZWxpbmVNZXRhZGF0YSB9IGZyb20gJy4uL2FwcCc7XG5pbXBvcnQgeyBFcnJvck1lc3NhZ2UgfSBmcm9tICcuLi9lbnVtcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFdmVudERlY29yYXRvcih0eXBlOiBFdmVudE1ldGFkYXRhWyd0eXBlJ10sIG5hbWU/OiBzdHJpbmcsIHdlYlZpZXdJZD86IHN0cmluZyB8IG51bWJlcikge1xuICAgIHJldHVybiA8TWV0aG9kRGVjb3JhdG9yPigodGFyZ2V0OiBPYmplY3QsIG1ldGhvZDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGlmICghaXNOaWwobmFtZSkgJiYgIWlzU3RyaW5nKG5hbWUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkV2ZW50TmFtZU11c3RCZVN0cmluZyk7XG4gICAgICAgIH1cblxuICAgICAgICBuYW1lID0gbmFtZSA/PyBtZXRob2Q7XG5cbiAgICAgICAgY29uc3QgZXZlbnRzID1cbiAgICAgICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGE8T21pdDxFdmVudE1ldGFkYXRhLCAncGFyYW1zJyB8IGtleW9mIFBpcGVsaW5lTWV0YWRhdGE+W10+KENvcmVNZXRhZGF0YUtleS5Db250cm9sbGVyRXZlbnRzLCB0YXJnZXQpID8/IFtdO1xuXG4gICAgICAgIGlmIChldmVudHMuc29tZSgoZXZlbnQpID0+IGV2ZW50Lm1ldGhvZCA9PT0gbWV0aG9kICYmIGV2ZW50Lm5hbWUgPT09IG5hbWUgJiYgZXZlbnQudHlwZSA9PT0gdHlwZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuRXZlbnROYW1lTXVzdEJlVW5pcXVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGE8T21pdDxFdmVudE1ldGFkYXRhLCAncGFyYW1zJyB8IGtleW9mIFBpcGVsaW5lTWV0YWRhdGE+W10+KFxuICAgICAgICAgICAgQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXJFdmVudHMsXG4gICAgICAgICAgICBbLi4uZXZlbnRzLCB7IG1ldGhvZCwgbmFtZSwgdHlwZSwgd2ViVmlld0lkIH1dLFxuICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICApO1xuICAgIH0pO1xufVxuIiwgImltcG9ydCB7IGNyZWF0ZUV2ZW50RGVjb3JhdG9yIH0gZnJvbSAnLi4vY3JlYXRlLWV2ZW50LWRlY29yYXRvcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBPbkludGVybmFsKGV2ZW50TmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUV2ZW50RGVjb3JhdG9yKCdvbkludGVybmFsJywgZXZlbnROYW1lKTtcbn1cbiIsICJpbXBvcnQgeyBjcmVhdGVFdmVudERlY29yYXRvciB9IGZyb20gJy4uL2NyZWF0ZS1ldmVudC1kZWNvcmF0b3InO1xuXG5leHBvcnQgZnVuY3Rpb24gT25XZWJWaWV3KGlkOiBzdHJpbmcgfCBudW1iZXIsIGV2ZW50TmFtZT86IHN0cmluZykge1xuICAgIHJldHVybiBjcmVhdGVFdmVudERlY29yYXRvcignb25XZWJWaWV3JywgZXZlbnROYW1lLCBpZCk7XG59XG4iLCAiaW1wb3J0IHsgY3JlYXRlRXZlbnREZWNvcmF0b3IgfSBmcm9tICcuLi9jcmVhdGUtZXZlbnQtZGVjb3JhdG9yJztcblxuZXhwb3J0IGZ1bmN0aW9uIE9uKGV2ZW50TmFtZT86IHN0cmluZykge1xuICAgIHJldHVybiBjcmVhdGVFdmVudERlY29yYXRvcignb24nLCBldmVudE5hbWUpO1xufVxuIiwgImltcG9ydCB7IGNyZWF0ZUV2ZW50RGVjb3JhdG9yIH0gZnJvbSAnLi4vY3JlYXRlLWV2ZW50LWRlY29yYXRvcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBPbmNlSW50ZXJuYWwoZXZlbnROYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gY3JlYXRlRXZlbnREZWNvcmF0b3IoJ29uY2VJbnRlcm5hbCcsIGV2ZW50TmFtZSk7XG59XG4iLCAiaW1wb3J0IHsgY3JlYXRlRXZlbnREZWNvcmF0b3IgfSBmcm9tICcuLi9jcmVhdGUtZXZlbnQtZGVjb3JhdG9yJztcblxuZXhwb3J0IGZ1bmN0aW9uIE9uY2UoZXZlbnROYW1lPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUV2ZW50RGVjb3JhdG9yKCdvbmNlJywgZXZlbnROYW1lKTtcbn1cbiIsICJpbXBvcnQgeyBjcmVhdGVFdmVudERlY29yYXRvciB9IGZyb20gJy4uL2NyZWF0ZS1ldmVudC1kZWNvcmF0b3InO1xuXG5leHBvcnQgZnVuY3Rpb24gT25jZVdlYlZpZXcoaWQ6IHN0cmluZyB8IG51bWJlciwgZXZlbnROYW1lPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUV2ZW50RGVjb3JhdG9yKCdvbmNlV2ViVmlldycsIGV2ZW50TmFtZSwgaWQpO1xufVxuIiwgImltcG9ydCB7IENvcmVNZXRhZGF0YUtleSB9IGZyb20gJy4uLy4uL2FwcC9lbnVtcyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgdHlwZSB7IE1ldGhvZFBhcmFtZXRlciB9IGZyb20gJy4uLy4uL2FwcC9pbnRlcmZhY2VzJztcbmltcG9ydCB7IE1ldGhvZFBhcmFtVHlwZSB9IGZyb20gJy4uLy4uL2FwcC9lbnVtcyc7XG5pbXBvcnQgeyBFcnJvck1lc3NhZ2UgfSBmcm9tICcuLi8uLi9lbnVtcyc7XG5pbXBvcnQgdHlwZSB7IFBpcGUgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IHZhbGlkYXRlUGlwZSB9IGZyb20gJy4uLy4uL3NjaGVtYXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gQm9keSguLi5waXBlczogKE5ld2FibGU8UGlwZT4gfCBQaXBlKVtdKSB7XG4gICAgcmV0dXJuIDxQYXJhbWV0ZXJEZWNvcmF0b3I+KCh0YXJnZXQ6IE9iamVjdCwgbWV0aG9kOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgY29uc3QgdmFsaWRhdGVkUGlwZXM6IChOZXdhYmxlPFBpcGU+IHwgUGlwZSlbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHBpcGUgb2YgcGlwZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgdmFsaWQsIHZhbHVlLCBlcnJvciB9ID0gdmFsaWRhdGVQaXBlKHBpcGUpO1xuICAgICAgICAgICAgaWYgKCF2YWxpZCkgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIHZhbGlkYXRlZFBpcGVzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxNZXRob2RQYXJhbWV0ZXJbXT4oQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXJQYXJhbXMsIHRhcmdldCwgbWV0aG9kKSA/PyBbXTtcblxuICAgICAgICBpZiAocGFyYW1zLnNvbWUoKHBhcmFtKSA9PiBwYXJhbS5pbmRleCA9PT0gaW5kZXgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLk11bHRpcGxlRGVjb3JhdG9yc09uU2luZ2xlUGFyYW1ldGVyTm90QWxsb3dlZCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXJhbVR5cGVzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxOZXdhYmxlW10+KCdkZXNpZ246cGFyYW10eXBlcycsIHRhcmdldCwgbWV0aG9kKTtcbiAgICAgICAgY29uc3QgbWV0YXR5cGUgPSBBcnJheS5pc0FycmF5KHBhcmFtVHlwZXMpID8gcGFyYW1UeXBlc1tpbmRleF0gOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YTxNZXRob2RQYXJhbWV0ZXJbXT4oXG4gICAgICAgICAgICBDb3JlTWV0YWRhdGFLZXkuQ29udHJvbGxlclBhcmFtcyxcbiAgICAgICAgICAgIFsuLi5wYXJhbXMsIHsgaW5kZXgsIG1ldGhvZCwgcGlwZXM6IHZhbGlkYXRlZFBpcGVzLCB0eXBlOiBNZXRob2RQYXJhbVR5cGUuQm9keSwgZGF0YTogdW5kZWZpbmVkLCBtZXRhdHlwZSB9XSxcbiAgICAgICAgICAgIHRhcmdldCxcbiAgICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgKTtcbiAgICB9KTtcbn1cbiIsICJpbXBvcnQgeyBDb3JlTWV0YWRhdGFLZXkgfSBmcm9tICcuLi8uLi9hcHAvZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBNZXRob2RQYXJhbWV0ZXIgfSBmcm9tICcuLi8uLi9hcHAvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBNZXRob2RQYXJhbVR5cGUgfSBmcm9tICcuLi8uLi9hcHAvZW51bXMnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBQaXBlIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBpc051bWJlciB9IGZyb20gJy4uLy4uL3V0aWxzJztcbmltcG9ydCB7IHZhbGlkYXRlUGlwZSB9IGZyb20gJy4uLy4uL3NjaGVtYXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gSW5kZXgoa2V5OiBudW1iZXIsIC4uLnBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10pIHtcbiAgICByZXR1cm4gPFBhcmFtZXRlckRlY29yYXRvcj4oKHRhcmdldDogT2JqZWN0LCBtZXRob2Q6IHN0cmluZywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICBpZiAoIWlzTnVtYmVyKGtleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuSW5kZXhLZXlNdXN0QmVOdW1iZXIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbGlkYXRlZFBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBwaXBlIG9mIHBpcGVzKSB7XG4gICAgICAgICAgICBjb25zdCB7IHZhbGlkLCB2YWx1ZSwgZXJyb3IgfSA9IHZhbGlkYXRlUGlwZShwaXBlKTtcbiAgICAgICAgICAgIGlmICghdmFsaWQpIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgICAgICAgICB2YWxpZGF0ZWRQaXBlcy5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGE8TWV0aG9kUGFyYW1ldGVyW10+KENvcmVNZXRhZGF0YUtleS5Db250cm9sbGVyUGFyYW1zLCB0YXJnZXQsIG1ldGhvZCkgPz8gW107XG5cbiAgICAgICAgaWYgKHBhcmFtcy5zb21lKChwYXJhbSkgPT4gcGFyYW0uaW5kZXggPT09IGluZGV4KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5NdWx0aXBsZURlY29yYXRvcnNPblNpbmdsZVBhcmFtZXRlck5vdEFsbG93ZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGFyYW1UeXBlcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGE8TmV3YWJsZVtdPignZGVzaWduOnBhcmFtdHlwZXMnLCB0YXJnZXQsIG1ldGhvZCk7XG4gICAgICAgIGNvbnN0IG1ldGF0eXBlID0gQXJyYXkuaXNBcnJheShwYXJhbVR5cGVzKSA/IHBhcmFtVHlwZXNbaW5kZXhdIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGE8TWV0aG9kUGFyYW1ldGVyW10+KFxuICAgICAgICAgICAgQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXJQYXJhbXMsXG4gICAgICAgICAgICBbLi4ucGFyYW1zLCB7IGluZGV4LCBtZXRob2QsIHBpcGVzOiB2YWxpZGF0ZWRQaXBlcywgdHlwZTogTWV0aG9kUGFyYW1UeXBlLkluZGV4LCBkYXRhOiBrZXksIG1ldGF0eXBlIH1dLFxuICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgbWV0aG9kLFxuICAgICAgICApO1xuICAgIH0pO1xufVxuIiwgImltcG9ydCB7IENvcmVNZXRhZGF0YUtleSB9IGZyb20gJy4uLy4uL2FwcC9lbnVtcyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgdHlwZSB7IE1ldGhvZFBhcmFtZXRlciB9IGZyb20gJy4uLy4uL2FwcC9pbnRlcmZhY2VzJztcbmltcG9ydCB7IE1ldGhvZFBhcmFtVHlwZSB9IGZyb20gJy4uLy4uL2FwcC9lbnVtcyc7XG5pbXBvcnQgeyBFcnJvck1lc3NhZ2UgfSBmcm9tICcuLi8uLi9lbnVtcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBSZXF1ZXN0KCkge1xuICAgIHJldHVybiA8UGFyYW1ldGVyRGVjb3JhdG9yPigodGFyZ2V0OiBPYmplY3QsIG1ldGhvZDogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGE8TWV0aG9kUGFyYW1ldGVyW10+KENvcmVNZXRhZGF0YUtleS5Db250cm9sbGVyUGFyYW1zLCB0YXJnZXQsIG1ldGhvZCkgPz8gW107XG5cbiAgICAgICAgaWYgKHBhcmFtcy5zb21lKChwYXJhbSkgPT4gcGFyYW0uaW5kZXggPT09IGluZGV4KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5NdWx0aXBsZURlY29yYXRvcnNPblNpbmdsZVBhcmFtZXRlck5vdEFsbG93ZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGFyYW1UeXBlcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGE8TmV3YWJsZVtdPignZGVzaWduOnBhcmFtdHlwZXMnLCB0YXJnZXQsIG1ldGhvZCk7XG4gICAgICAgIGNvbnN0IG1ldGF0eXBlID0gQXJyYXkuaXNBcnJheShwYXJhbVR5cGVzKSA/IHBhcmFtVHlwZXNbaW5kZXhdIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGE8TWV0aG9kUGFyYW1ldGVyW10+KFxuICAgICAgICAgICAgQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXJQYXJhbXMsXG4gICAgICAgICAgICBbLi4ucGFyYW1zLCB7IGluZGV4LCBtZXRob2QsIHR5cGU6IE1ldGhvZFBhcmFtVHlwZS5SZXF1ZXN0LCBkYXRhOiB1bmRlZmluZWQsIG1ldGF0eXBlIH1dLFxuICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgbWV0aG9kLFxuICAgICAgICApO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gUmVxKCkge1xuICAgIHJldHVybiBSZXF1ZXN0KCk7XG59XG4iLCAiaW1wb3J0IHsgQ29yZU1ldGFkYXRhS2V5IH0gZnJvbSAnLi4vLi4vYXBwL2VudW1zJztcbmltcG9ydCB0eXBlIHsgTmV3YWJsZSB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgTWV0aG9kUGFyYW1ldGVyIH0gZnJvbSAnLi4vLi4vYXBwL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTWV0aG9kUGFyYW1UeXBlIH0gZnJvbSAnLi4vLi4vYXBwL2VudW1zJztcbmltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBQaXBlIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyB2YWxpZGF0ZVBpcGUgfSBmcm9tICcuLi8uLi9zY2hlbWFzJztcblxuZXhwb3J0IGZ1bmN0aW9uIFBhcmFtKGtleTogc3RyaW5nLCAuLi5waXBlczogKE5ld2FibGU8UGlwZT4gfCBQaXBlKVtdKSB7XG4gICAgcmV0dXJuIDxQYXJhbWV0ZXJEZWNvcmF0b3I+KCh0YXJnZXQ6IE9iamVjdCwgbWV0aG9kOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgaWYgKCFpc1N0cmluZyhrZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLlBhcmFtS2V5TXVzdEJlU3RyaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2YWxpZGF0ZWRQaXBlczogKE5ld2FibGU8UGlwZT4gfCBQaXBlKVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgcGlwZSBvZiBwaXBlcykge1xuICAgICAgICAgICAgY29uc3QgeyB2YWxpZCwgdmFsdWUsIGVycm9yIH0gPSB2YWxpZGF0ZVBpcGUocGlwZSk7XG4gICAgICAgICAgICBpZiAoIXZhbGlkKSB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgdmFsaWRhdGVkUGlwZXMucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBSZWZsZWN0LmdldE1ldGFkYXRhPE1ldGhvZFBhcmFtZXRlcltdPihDb3JlTWV0YWRhdGFLZXkuQ29udHJvbGxlclBhcmFtcywgdGFyZ2V0LCBtZXRob2QpID8/IFtdO1xuXG4gICAgICAgIGlmIChwYXJhbXMuc29tZSgocGFyYW0pID0+IHBhcmFtLmluZGV4ID09PSBpbmRleCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuTXVsdGlwbGVEZWNvcmF0b3JzT25TaW5nbGVQYXJhbWV0ZXJOb3RBbGxvd2VkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhcmFtVHlwZXMgPSBSZWZsZWN0LmdldE1ldGFkYXRhPE5ld2FibGVbXT4oJ2Rlc2lnbjpwYXJhbXR5cGVzJywgdGFyZ2V0LCBtZXRob2QpO1xuICAgICAgICBjb25zdCBtZXRhdHlwZSA9IEFycmF5LmlzQXJyYXkocGFyYW1UeXBlcykgPyBwYXJhbVR5cGVzW2luZGV4XSA6IHVuZGVmaW5lZDtcblxuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhPE1ldGhvZFBhcmFtZXRlcltdPihcbiAgICAgICAgICAgIENvcmVNZXRhZGF0YUtleS5Db250cm9sbGVyUGFyYW1zLFxuICAgICAgICAgICAgWy4uLnBhcmFtcywgeyBpbmRleCwgbWV0aG9kLCBkYXRhOiBrZXksIHBpcGVzOiB2YWxpZGF0ZWRQaXBlcywgdHlwZTogTWV0aG9kUGFyYW1UeXBlLlBhcmFtLCBtZXRhdHlwZSB9XSxcbiAgICAgICAgICAgIHRhcmdldCxcbiAgICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgKTtcbiAgICB9KTtcbn1cbiIsICJpbXBvcnQgeyBDb3JlTWV0YWRhdGFLZXkgfSBmcm9tICcuLi8uLi9hcHAvZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBNZXRob2RQYXJhbWV0ZXIgfSBmcm9tICcuLi8uLi9hcHAvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBNZXRob2RQYXJhbVR5cGUgfSBmcm9tICcuLi8uLi9hcHAvZW51bXMnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gUmVzcG9uc2UoKSB7XG4gICAgcmV0dXJuIDxQYXJhbWV0ZXJEZWNvcmF0b3I+KCh0YXJnZXQ6IE9iamVjdCwgbWV0aG9kOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxNZXRob2RQYXJhbWV0ZXJbXT4oQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXJQYXJhbXMsIHRhcmdldCwgbWV0aG9kKSA/PyBbXTtcblxuICAgICAgICBpZiAocGFyYW1zLnNvbWUoKHBhcmFtKSA9PiBwYXJhbS5pbmRleCA9PT0gaW5kZXgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLk11bHRpcGxlRGVjb3JhdG9yc09uU2luZ2xlUGFyYW1ldGVyTm90QWxsb3dlZCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXJhbVR5cGVzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxOZXdhYmxlW10+KCdkZXNpZ246cGFyYW10eXBlcycsIHRhcmdldCwgbWV0aG9kKTtcbiAgICAgICAgY29uc3QgbWV0YXR5cGUgPSBBcnJheS5pc0FycmF5KHBhcmFtVHlwZXMpID8gcGFyYW1UeXBlc1tpbmRleF0gOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YTxNZXRob2RQYXJhbWV0ZXJbXT4oXG4gICAgICAgICAgICBDb3JlTWV0YWRhdGFLZXkuQ29udHJvbGxlclBhcmFtcyxcbiAgICAgICAgICAgIFsuLi5wYXJhbXMsIHsgaW5kZXgsIG1ldGhvZCwgdHlwZTogTWV0aG9kUGFyYW1UeXBlLlJlc3BvbnNlLCBkYXRhOiB1bmRlZmluZWQsIG1ldGF0eXBlIH1dLFxuICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgbWV0aG9kLFxuICAgICAgICApO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gUmVzKCkge1xuICAgIHJldHVybiBSZXNwb25zZSgpO1xufVxuIiwgImltcG9ydCB0eXBlIHsgR3VhcmQgfSBmcm9tICcuLi8uLi9hcHAvaW50ZXJmYWNlcyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBpc05pbCB9IGZyb20gJy4uLy4uL3V0aWxzJztcbmltcG9ydCB7IENvcmVNZXRhZGF0YUtleSB9IGZyb20gJy4uLy4uL2FwcC9lbnVtcyc7XG5pbXBvcnQgeyBFcnJvck1lc3NhZ2UgfSBmcm9tICcuLi8uLi9lbnVtcyc7XG5pbXBvcnQgeyB2YWxpZGF0ZUd1YXJkIH0gZnJvbSAnLi4vLi4vc2NoZW1hcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBVc2VHdWFyZHMoLi4uZ3VhcmRzOiAoTmV3YWJsZTxHdWFyZD4gfCBHdWFyZClbXSkge1xuICAgIHJldHVybiA8Q2xhc3NEZWNvcmF0b3IgJiBNZXRob2REZWNvcmF0b3I+KCh0YXJnZXQ6IE9iamVjdCwgbWV0aG9kPzogc3RyaW5nLCBkZXNjcmlwdG9yPzogUHJvcGVydHlEZXNjcmlwdG9yKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbGlkYXRlZEd1YXJkczogKE5ld2FibGU8R3VhcmQ+IHwgR3VhcmQpW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBndWFyZCBvZiBndWFyZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgdmFsaWQsIHZhbHVlLCBlcnJvciB9ID0gdmFsaWRhdGVHdWFyZChndWFyZCk7XG4gICAgICAgICAgICBpZiAoIXZhbGlkKSB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgdmFsaWRhdGVkR3VhcmRzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc05pbChkZXNjcmlwdG9yKSAmJiAhaXNOaWwoZGVzY3JpcHRvci52YWx1ZSkpIHtcbiAgICAgICAgICAgIGlmIChndWFyZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5BdExlYXN0T25lR3VhcmRSZXF1aXJlZCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IG1ldGhvZEd1YXJkcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGE8TmV3YWJsZTxHdWFyZD5bXT4oQ29yZU1ldGFkYXRhS2V5Lkd1YXJkcywgdGFyZ2V0LmNvbnN0cnVjdG9yLCBtZXRob2QpIHx8IFtdO1xuICAgICAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShDb3JlTWV0YWRhdGFLZXkuR3VhcmRzLCBbLi4udmFsaWRhdGVkR3VhcmRzLCAuLi5tZXRob2RHdWFyZHNdLCB0YXJnZXQuY29uc3RydWN0b3IsIG1ldGhvZCk7XG4gICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChndWFyZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkF0TGVhc3RPbmVHdWFyZFJlcXVpcmVkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsYXNzR3VhcmRzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxOZXdhYmxlPEd1YXJkPltdPihDb3JlTWV0YWRhdGFLZXkuR3VhcmRzLCB0YXJnZXQpIHx8IFtdO1xuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKENvcmVNZXRhZGF0YUtleS5HdWFyZHMsIFsuLi52YWxpZGF0ZWRHdWFyZHMsIC4uLmNsYXNzR3VhcmRzXSwgdGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9KTtcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgdHlwZSB7IEludGVyY2VwdG9yIH0gZnJvbSAnLi4vLi4vYXBwL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgaXNOaWwgfSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgeyBDb3JlTWV0YWRhdGFLZXkgfSBmcm9tICcuLi8uLi9hcHAvZW51bXMnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHsgdmFsaWRhdGVJbnRlcmNlcHRvciB9IGZyb20gJy4uLy4uL3NjaGVtYXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gVXNlSW50ZXJjZXB0b3JzKC4uLmludGVyY2VwdG9yczogKE5ld2FibGU8SW50ZXJjZXB0b3I+IHwgSW50ZXJjZXB0b3IpW10pIHtcbiAgICByZXR1cm4gPENsYXNzRGVjb3JhdG9yICYgTWV0aG9kRGVjb3JhdG9yPigodGFyZ2V0OiBPYmplY3QsIG1ldGhvZD86IHN0cmluZywgZGVzY3JpcHRvcj86IFByb3BlcnR5RGVzY3JpcHRvcikgPT4ge1xuICAgICAgICBjb25zdCB2YWxpZGF0ZWRJbnRlcmNlcHRvcnM6IChOZXdhYmxlPEludGVyY2VwdG9yPiB8IEludGVyY2VwdG9yKVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgaW50ZXJjZXB0b3Igb2YgaW50ZXJjZXB0b3JzKSB7XG4gICAgICAgICAgICBjb25zdCB7IHZhbGlkLCB2YWx1ZSwgZXJyb3IgfSA9IHZhbGlkYXRlSW50ZXJjZXB0b3IoaW50ZXJjZXB0b3IpO1xuICAgICAgICAgICAgaWYgKCF2YWxpZCkgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIHZhbGlkYXRlZEludGVyY2VwdG9ycy5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNOaWwoZGVzY3JpcHRvcikgJiYgIWlzTmlsKGRlc2NyaXB0b3IudmFsdWUpKSB7XG4gICAgICAgICAgICBpZiAoaW50ZXJjZXB0b3JzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuQXRMZWFzdE9uZUludGVyY2VwdG9yUmVxdWlyZWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBtZXRob2RJbnRlcmNlcHRvcnMgPVxuICAgICAgICAgICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGE8TmV3YWJsZTxJbnRlcmNlcHRvcj5bXT4oQ29yZU1ldGFkYXRhS2V5LkludGVyY2VwdG9ycywgdGFyZ2V0LmNvbnN0cnVjdG9yLCBtZXRob2QpIHx8IFtdO1xuICAgICAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbiAgICAgICAgICAgICAgICBDb3JlTWV0YWRhdGFLZXkuSW50ZXJjZXB0b3JzLFxuICAgICAgICAgICAgICAgIFsuLi52YWxpZGF0ZWRJbnRlcmNlcHRvcnMsIC4uLm1ldGhvZEludGVyY2VwdG9yc10sXG4gICAgICAgICAgICAgICAgdGFyZ2V0LmNvbnN0cnVjdG9yLFxuICAgICAgICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbnRlcmNlcHRvcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkF0TGVhc3RPbmVJbnRlcmNlcHRvclJlcXVpcmVkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsYXNzSW50ZXJjZXB0b3JzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxOZXdhYmxlPEludGVyY2VwdG9yPltdPihDb3JlTWV0YWRhdGFLZXkuSW50ZXJjZXB0b3JzLCB0YXJnZXQpIHx8IFtdO1xuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKENvcmVNZXRhZGF0YUtleS5JbnRlcmNlcHRvcnMsIFsuLi52YWxpZGF0ZWRJbnRlcmNlcHRvcnMsIC4uLmNsYXNzSW50ZXJjZXB0b3JzXSwgdGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9KTtcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBpc05pbCB9IGZyb20gJy4uLy4uL3V0aWxzJztcbmltcG9ydCB7IENvcmVNZXRhZGF0YUtleSB9IGZyb20gJy4uLy4uL2FwcC9lbnVtcyc7XG5pbXBvcnQgeyBFcnJvck1lc3NhZ2UgfSBmcm9tICcuLi8uLi9lbnVtcyc7XG5pbXBvcnQgdHlwZSB7IFBpcGUgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IHZhbGlkYXRlUGlwZSB9IGZyb20gJy4uLy4uL3NjaGVtYXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gVXNlUGlwZXMoLi4ucGlwZXM6IChOZXdhYmxlPFBpcGU+IHwgUGlwZSlbXSkge1xuICAgIHJldHVybiA8Q2xhc3NEZWNvcmF0b3IgJiBNZXRob2REZWNvcmF0b3I+KCh0YXJnZXQ6IE9iamVjdCwgbWV0aG9kPzogc3RyaW5nLCBkZXNjcmlwdG9yPzogUHJvcGVydHlEZXNjcmlwdG9yKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbGlkYXRlZFBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBwaXBlIG9mIHBpcGVzKSB7XG4gICAgICAgICAgICBjb25zdCB7IHZhbGlkLCB2YWx1ZSwgZXJyb3IgfSA9IHZhbGlkYXRlUGlwZShwaXBlKTtcbiAgICAgICAgICAgIGlmICghdmFsaWQpIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgICAgICAgICB2YWxpZGF0ZWRQaXBlcy5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNOaWwoZGVzY3JpcHRvcikgJiYgIWlzTmlsKGRlc2NyaXB0b3IudmFsdWUpKSB7XG4gICAgICAgICAgICBpZiAocGlwZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5BdExlYXN0T25lUGlwZVJlcXVpcmVkKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbWV0aG9kUGlwZXMgPSBSZWZsZWN0LmdldE1ldGFkYXRhPE5ld2FibGU8UGlwZT5bXT4oQ29yZU1ldGFkYXRhS2V5LlBpcGVzLCB0YXJnZXQuY29uc3RydWN0b3IsIG1ldGhvZCkgfHwgW107XG4gICAgICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKENvcmVNZXRhZGF0YUtleS5QaXBlcywgWy4uLnZhbGlkYXRlZFBpcGVzLCAuLi5tZXRob2RQaXBlc10sIHRhcmdldC5jb25zdHJ1Y3RvciwgbWV0aG9kKTtcbiAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBpcGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5BdExlYXN0T25lUGlwZVJlcXVpcmVkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsYXNzUGlwZXMgPSBSZWZsZWN0LmdldE1ldGFkYXRhPE5ld2FibGU8UGlwZT5bXT4oQ29yZU1ldGFkYXRhS2V5LlBpcGVzLCB0YXJnZXQpIHx8IFtdO1xuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKENvcmVNZXRhZGF0YUtleS5QaXBlcywgWy4uLnZhbGlkYXRlZFBpcGVzLCAuLi5jbGFzc1BpcGVzXSwgdGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9KTtcbn1cbiIsICJpbXBvcnQgeyBpc05pbCwgaXNOdW1iZXIsIGlzU3RyaW5nIH0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHsgQ29yZU1ldGFkYXRhS2V5LCB0eXBlIFBpcGVsaW5lTWV0YWRhdGEsIHR5cGUgUlBDTWV0YWRhdGEgfSBmcm9tICcuLi9hcHAnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vZW51bXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUlBDRGVjb3JhdG9yKHR5cGU6IFJQQ01ldGFkYXRhWyd0eXBlJ10sIG5hbWU/OiBzdHJpbmcsIHdlYlZpZXdJZD86IHN0cmluZyB8IG51bWJlcikge1xuICAgIHJldHVybiA8TWV0aG9kRGVjb3JhdG9yPigodGFyZ2V0OiBPYmplY3QsIG1ldGhvZDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGlmICghaXNOaWwod2ViVmlld0lkKSAmJiAhaXNTdHJpbmcod2ViVmlld0lkKSAmJiAhaXNOdW1iZXIod2ViVmlld0lkKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5XZWJWaWV3SWRNdXN0QmVTdHJpbmdPck51bWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzTmlsKG5hbWUpICYmICFpc1N0cmluZyhuYW1lKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5SUENOYW1lTXVzdEJlU3RyaW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5hbWUgPSBuYW1lID8/IG1ldGhvZDtcblxuICAgICAgICBjb25zdCBycGNzID1cbiAgICAgICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGE8T21pdDxSUENNZXRhZGF0YSwgJ3BhcmFtcycgfCBrZXlvZiBQaXBlbGluZU1ldGFkYXRhPltdPihDb3JlTWV0YWRhdGFLZXkuQ29udHJvbGxlclJQQ3MsIHRhcmdldCkgPz8gW107XG5cbiAgICAgICAgaWYgKHJwY3Muc29tZSgocnBjKSA9PiBycGMubWV0aG9kID09PSBtZXRob2QgJiYgcnBjLm5hbWUgPT09IG5hbWUgJiYgcnBjLnR5cGUgPT09IHR5cGUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLlJQQ05hbWVNdXN0QmVVbmlxdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YTxPbWl0PFJQQ01ldGFkYXRhLCAncGFyYW1zJyB8IGtleW9mIFBpcGVsaW5lTWV0YWRhdGE+W10+KFxuICAgICAgICAgICAgQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXJSUENzLFxuICAgICAgICAgICAgWy4uLnJwY3MsIHsgbWV0aG9kLCBuYW1lLCB0eXBlLCB3ZWJWaWV3SWQgfV0sXG4gICAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICk7XG4gICAgfSk7XG59XG4iLCAiaW1wb3J0IHsgY3JlYXRlUlBDRGVjb3JhdG9yIH0gZnJvbSAnLi4vY3JlYXRlLXJwYy1kZWNvcmF0b3InO1xuXG5leHBvcnQgZnVuY3Rpb24gT25SZXF1ZXN0KHJwY05hbWU/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gY3JlYXRlUlBDRGVjb3JhdG9yKCdvblJlcXVlc3QnLCBycGNOYW1lKTtcbn1cbiIsICJpbXBvcnQgeyBjcmVhdGVSUENEZWNvcmF0b3IgfSBmcm9tICcuLi9jcmVhdGUtcnBjLWRlY29yYXRvcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBPbldlYlZpZXdSZXF1ZXN0KGlkOiBzdHJpbmcgfCBudW1iZXIsIHJwY05hbWU/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gY3JlYXRlUlBDRGVjb3JhdG9yKCdvbldlYlZpZXdSZXF1ZXN0JywgcnBjTmFtZSwgaWQpO1xufVxuIiwgImltcG9ydCB7IENvcmVNZXRhZGF0YUtleSwgdHlwZSBUaW1lck1ldGFkYXRhIH0gZnJvbSAnLi4vYXBwJztcbmltcG9ydCB7IEVycm9yTWVzc2FnZSB9IGZyb20gJy4uL2VudW1zJztcbmltcG9ydCB7IGlzTmlsLCBpc1N0cmluZyB9IGZyb20gJy4uL3V0aWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRpbWVyRGVjb3JhdG9yKHR5cGU6IFRpbWVyTWV0YWRhdGFbJ3R5cGUnXSwgbmFtZT86IHN0cmluZywgb3B0aW9ucz86IFRpbWVyTWV0YWRhdGFbJ29wdGlvbnMnXSkge1xuICAgIHJldHVybiA8TWV0aG9kRGVjb3JhdG9yPigodGFyZ2V0OiBPYmplY3QsIG1ldGhvZDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGlmICghaXNOaWwobmFtZSkgJiYgIWlzU3RyaW5nKG5hbWUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLlRpbWVyTmFtZU11c3RCZVN0cmluZyk7XG4gICAgICAgIH1cblxuICAgICAgICBuYW1lID0gbmFtZSA/PyBtZXRob2Q7XG5cbiAgICAgICAgY29uc3QgdGltZXJzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxUaW1lck1ldGFkYXRhW10+KENvcmVNZXRhZGF0YUtleS5UaW1lcnMsIHRhcmdldCkgPz8gW107XG5cbiAgICAgICAgaWYgKHRpbWVycy5zb21lKCh0aW1lcikgPT4gdGltZXIubWV0aG9kID09PSBtZXRob2QgJiYgdGltZXIubmFtZSA9PT0gbmFtZSAmJiB0aW1lci50eXBlID09PSB0eXBlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5FdmVudE5hbWVNdXN0QmVVbmlxdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YTxUaW1lck1ldGFkYXRhW10+KFxuICAgICAgICAgICAgQ29yZU1ldGFkYXRhS2V5LlRpbWVycyxcbiAgICAgICAgICAgIFsuLi50aW1lcnMsIDxUaW1lck1ldGFkYXRhPnsgbWV0aG9kLCBuYW1lLCB0eXBlLCBvcHRpb25zIH1dLFxuICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICApO1xuICAgIH0pO1xufVxuIiwgImltcG9ydCB0eXBlIHsgQ3Jvbk9wdGlvbnMgfSBmcm9tICdjcm9uZXInO1xuaW1wb3J0IHsgY3JlYXRlVGltZXJEZWNvcmF0b3IgfSBmcm9tICcuLi9jcmVhdGUtdGltZXIuZGVjb3JhdG9yJztcblxuZXhwb3J0IGZ1bmN0aW9uIENyb24ocGF0dGVybjogc3RyaW5nIHwgRGF0ZSwgb3B0aW9uczogQ3Jvbk9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiBjcmVhdGVUaW1lckRlY29yYXRvcignY3JvbicsIG9wdGlvbnMubmFtZSwgeyBwYXR0ZXJuLCAuLi5vcHRpb25zIH0pO1xufVxuIiwgImltcG9ydCB7IGNyZWF0ZVRpbWVyRGVjb3JhdG9yIH0gZnJvbSAnLi4vY3JlYXRlLXRpbWVyLmRlY29yYXRvcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBFdmVyeVRpY2sobmFtZT86IHN0cmluZykge1xuICAgIHJldHVybiBjcmVhdGVUaW1lckRlY29yYXRvcignZXZlcnl0aWNrJywgbmFtZSk7XG59XG4iLCAiaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgeyBjcmVhdGVUaW1lckRlY29yYXRvciB9IGZyb20gJy4uL2NyZWF0ZS10aW1lci5kZWNvcmF0b3InO1xuXG5leHBvcnQgZnVuY3Rpb24gSW50ZXJ2YWwodGltZW91dDogbnVtYmVyKTogTWV0aG9kRGVjb3JhdG9yO1xuZXhwb3J0IGZ1bmN0aW9uIEludGVydmFsKG5hbWU6IHN0cmluZywgdGltZW91dDogbnVtYmVyKTogTWV0aG9kRGVjb3JhdG9yO1xuZXhwb3J0IGZ1bmN0aW9uIEludGVydmFsKG5hbWVPclRpbWVvdXQ6IHN0cmluZyB8IG51bWJlciwgdGltZW91dD86IG51bWJlcik6IE1ldGhvZERlY29yYXRvciB7XG4gICAgY29uc3QgW25hbWUsIGludGVydmFsVGltZW91dF0gPSBpc1N0cmluZyhuYW1lT3JUaW1lb3V0KSA/IFtuYW1lT3JUaW1lb3V0LCB0aW1lb3V0XSA6IFt1bmRlZmluZWQsIG5hbWVPclRpbWVvdXRdO1xuICAgIHJldHVybiBjcmVhdGVUaW1lckRlY29yYXRvcignaW50ZXJ2YWwnLCBuYW1lLCB7IHRpbWVvdXQ6IGludGVydmFsVGltZW91dCEgfSk7XG59XG4iLCAiaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgeyBjcmVhdGVUaW1lckRlY29yYXRvciB9IGZyb20gJy4uL2NyZWF0ZS10aW1lci5kZWNvcmF0b3InO1xuXG5leHBvcnQgZnVuY3Rpb24gVGltZW91dCh0aW1lb3V0OiBudW1iZXIpOiBNZXRob2REZWNvcmF0b3I7XG5leHBvcnQgZnVuY3Rpb24gVGltZW91dChuYW1lOiBzdHJpbmcsIHZhbHVlOiBudW1iZXIpOiBNZXRob2REZWNvcmF0b3I7XG5leHBvcnQgZnVuY3Rpb24gVGltZW91dChuYW1lT3JUaW1lb3V0OiBzdHJpbmcgfCBudW1iZXIsIHRpbWVvdXQ/OiBudW1iZXIpOiBNZXRob2REZWNvcmF0b3Ige1xuICAgIGNvbnN0IFtuYW1lLCBpbnRlcnZhbFRpbWVvdXRdID0gaXNTdHJpbmcobmFtZU9yVGltZW91dCkgPyBbbmFtZU9yVGltZW91dCwgdGltZW91dF0gOiBbdW5kZWZpbmVkLCBuYW1lT3JUaW1lb3V0XTtcbiAgICByZXR1cm4gY3JlYXRlVGltZXJEZWNvcmF0b3IoJ3RpbWVvdXQnLCBuYW1lLCB7IHRpbWVvdXQ6IGludGVydmFsVGltZW91dCEgfSk7XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGFwcGx5RGVjb3JhdG9ycyguLi5kZWNvcmF0b3JzOiAoQ2xhc3NEZWNvcmF0b3IgfCBNZXRob2REZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvcilbXSkge1xuICAgIHJldHVybiA8VEZ1bmN0aW9uIGV4dGVuZHMgRnVuY3Rpb24sIFk+KFxuICAgICAgICB0YXJnZXQ6IFRGdW5jdGlvbiB8IE9iamVjdCxcbiAgICAgICAgcHJvcGVydHlLZXk6IHN0cmluZyB8IHN5bWJvbCxcbiAgICAgICAgZGVzY3JpcHRvcjogVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I8WT4sXG4gICAgKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIGRlY29yYXRvcnMpIHtcbiAgICAgICAgICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBGdW5jdGlvbiAmJiAhZGVzY3JpcHRvcikge1xuICAgICAgICAgICAgICAgICg8Q2xhc3NEZWNvcmF0b3I+ZGVjb3JhdG9yKSh0YXJnZXQpO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgKDxNZXRob2REZWNvcmF0b3IgfCBQcm9wZXJ0eURlY29yYXRvcj5kZWNvcmF0b3IpKHRhcmdldCwgcHJvcGVydHlLZXksIGRlc2NyaXB0b3IpO1xuICAgICAgICB9XG4gICAgfTtcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEV4ZWN1dGlvbkNvbnRleHQsIE1ldGhvZFBhcmFtZXRlciB9IGZyb20gJy4uL2FwcC9pbnRlcmZhY2VzJztcbmltcG9ydCB7IENvcmVNZXRhZGF0YUtleSB9IGZyb20gJy4uL2FwcC9lbnVtcyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBNZXRob2RQYXJhbVR5cGUgfSBmcm9tICcuLi9hcHAvZW51bXMnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBQaXBlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyB2YWxpZGF0ZVBpcGUgfSBmcm9tICcuLi9zY2hlbWFzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBhcmFtRGVjb3JhdG9yPFRJbnB1dCA9IHVua25vd24sIFRPdXRwdXQgPSB1bmtub3duPihmYWN0b3J5OiAoZGF0YTogVElucHV0LCBjdHg6IEV4ZWN1dGlvbkNvbnRleHQpID0+IFRPdXRwdXQpIHtcbiAgICByZXR1cm4gPFRJbnB1dCA9IHVua25vd24+KGRhdGE/OiBUSW5wdXQsIC4uLnBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10pID0+IHtcbiAgICAgICAgcmV0dXJuIDxQYXJhbWV0ZXJEZWNvcmF0b3I+KCh0YXJnZXQ6IE9iamVjdCwgbWV0aG9kOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRlZFBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10gPSBbXTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcGlwZSBvZiBwaXBlcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgdmFsaWQsIHZhbHVlLCBlcnJvciB9ID0gdmFsaWRhdGVQaXBlKHBpcGUpO1xuICAgICAgICAgICAgICAgIGlmICghdmFsaWQpIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdmFsaWRhdGVkUGlwZXMucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGE8TWV0aG9kUGFyYW1ldGVyW10+KENvcmVNZXRhZGF0YUtleS5Db250cm9sbGVyUGFyYW1zLCB0YXJnZXQsIG1ldGhvZCkgPz8gW107XG5cbiAgICAgICAgICAgIGlmIChwYXJhbXMuc29tZSgocGFyYW0pID0+IHBhcmFtLmluZGV4ID09PSBpbmRleCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLk11bHRpcGxlRGVjb3JhdG9yc09uU2luZ2xlUGFyYW1ldGVyTm90QWxsb3dlZCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcmFtVHlwZXMgPSBSZWZsZWN0LmdldE1ldGFkYXRhPE5ld2FibGVbXT4oJ2Rlc2lnbjpwYXJhbXR5cGVzJywgdGFyZ2V0LCBtZXRob2QpO1xuICAgICAgICAgICAgY29uc3QgbWV0YXR5cGUgPSBBcnJheS5pc0FycmF5KHBhcmFtVHlwZXMpID8gcGFyYW1UeXBlc1tpbmRleF0gOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGE8TWV0aG9kUGFyYW1ldGVyW10+KFxuICAgICAgICAgICAgICAgIENvcmVNZXRhZGF0YUtleS5Db250cm9sbGVyUGFyYW1zLFxuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVzOiB2YWxpZGF0ZWRQaXBlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IE1ldGhvZFBhcmFtVHlwZS5DdXN0b20sXG4gICAgICAgICAgICAgICAgICAgICAgICBmYWN0b3J5OiA8KGRhdGE6IHVua25vd24sIGNvbnRleHQ6IEV4ZWN1dGlvbkNvbnRleHQpID0+IHVua25vd24+ZmFjdG9yeSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXRhdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIHRhcmdldCxcbiAgICAgICAgICAgICAgICBtZXRob2QsXG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuIiwgImltcG9ydCB7IExhenlTZXJ2aWNlSWRlbnRpZmVyLCB0eXBlIGludGVyZmFjZXMgfSBmcm9tICdpbnZlcnNpZnknO1xuXG5leHBvcnQgZnVuY3Rpb24gZm9yd2FyZFJlZjxUID0gdW5rbm93bj4oZm46ICgpID0+IGludGVyZmFjZXMuU2VydmljZUlkZW50aWZpZXI8VD4pIHtcbiAgICByZXR1cm4gbmV3IExhenlTZXJ2aWNlSWRlbnRpZmVyPFQ+KGZuKTtcbn1cbiIsICJpbXBvcnQgeyBpbmplY3QsIGluamVjdGFibGUgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQgeyBDcm9uLCB0eXBlIENyb25PcHRpb25zIH0gZnJvbSAnY3JvbmVyJztcbmltcG9ydCB7IE1VTFRJUExBWUVSX1NFUlZJQ0UsIHR5cGUgTXVsdGlwbGF5ZXJTZXJ2aWNlLCB0eXBlIE11bHRpcGxheWVyVGltZXIgfSBmcm9tICcuLi9hcHAnO1xuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgVGltZXJTZXJ2aWNlIHtcbiAgICBAaW5qZWN0KE1VTFRJUExBWUVSX1NFUlZJQ0UpIHByaXZhdGUgcmVhZG9ubHkgbXVsdGlwbGF5ZXJTZXJ2aWNlOiBNdWx0aXBsYXllclNlcnZpY2U7XG4gICAgcHJpdmF0ZSByZWFkb25seSAkZXZlcnl0aWNrcyA9IG5ldyBNYXA8c3RyaW5nLCBNdWx0aXBsYXllclRpbWVyPigpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgJGludGVydmFscyA9IG5ldyBNYXA8c3RyaW5nLCBNdWx0aXBsYXllclRpbWVyPigpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgJHRpbWVvdXRzID0gbmV3IE1hcDxzdHJpbmcsIE11bHRpcGxheWVyVGltZXI+KCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSAkY3JvbnMgPSBuZXcgTWFwPHN0cmluZywgQ3Jvbj4oKTtcblxuICAgIHB1YmxpYyBnZXQgYWxsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tdWx0aXBsYXllclNlcnZpY2UuVGltZXJzLmFsbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGV2ZXJ5dGlja3MoKSB7XG4gICAgICAgIHJldHVybiBbLi4udGhpcy4kZXZlcnl0aWNrcy52YWx1ZXMoKV07XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBpbnRlcnZhbHMoKSB7XG4gICAgICAgIHJldHVybiBbLi4udGhpcy4kaW50ZXJ2YWxzLnZhbHVlcygpXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHRpbWVvdXRzKCkge1xuICAgICAgICByZXR1cm4gWy4uLnRoaXMuJHRpbWVvdXRzLnZhbHVlcygpXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGNyb25zKCkge1xuICAgICAgICByZXR1cm4gWy4uLnRoaXMuJGNyb25zLnZhbHVlcygpXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IHdhcm5pbmdUaHJlc2hvbGQodmFsdWU6IG51bWJlcikge1xuICAgICAgICB0aGlzLm11bHRpcGxheWVyU2VydmljZS5UaW1lcnMud2FybmluZ1RocmVzaG9sZCA9IHZhbHVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgd2FybmluZ1RocmVzaG9sZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubXVsdGlwbGF5ZXJTZXJ2aWNlLlRpbWVycy53YXJuaW5nVGhyZXNob2xkO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXQgc291cmNlTG9jYXRpb25GcmFtZVNraXBDb3VudCh2YWx1ZTogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMubXVsdGlwbGF5ZXJTZXJ2aWNlLlRpbWVycy5zb3VyY2VMb2NhdGlvbkZyYW1lU2tpcENvdW50ID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzb3VyY2VMb2NhdGlvbkZyYW1lU2tpcENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tdWx0aXBsYXllclNlcnZpY2UuVGltZXJzLnNvdXJjZUxvY2F0aW9uRnJhbWVTa2lwQ291bnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGNyZWF0ZUNyb25Kb2IoY2FsbGJhY2s6IEZ1bmN0aW9uLCBvcHRpb25zOiBDcm9uT3B0aW9ucyAmIHsgcGF0dGVybjogc3RyaW5nIHwgRGF0ZSB9KSB7XG4gICAgICAgIGNvbnN0IHsgcGF0dGVybiwgLi4uY3Jvbk9wdGlvbnMgfSA9IG9wdGlvbnM7XG5cbiAgICAgICAgY29uc3QgY3JvbiA9IENyb24ocGF0dGVybiwgY3Jvbk9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgICAgaWYgKGlzU3RyaW5nKG9wdGlvbnMubmFtZSkpIHRoaXMuJGNyb25zLnNldChvcHRpb25zLm5hbWUsIGNyb24pO1xuXG4gICAgICAgIHJldHVybiBjcm9uO1xuICAgIH1cblxuICAgIHB1YmxpYyBjcmVhdGVJbnRlcnZhbChjYWxsYmFjazogRnVuY3Rpb24sIGludGVydmFsOiBudW1iZXIsIG5hbWU/OiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgdGltZXIgPSB0aGlzLm11bHRpcGxheWVyU2VydmljZS5UaW1lcnMuc2V0SW50ZXJ2YWwoY2FsbGJhY2ssIGludGVydmFsKTtcbiAgICAgICAgaWYgKGlzU3RyaW5nKG5hbWUpKSB0aGlzLiRpbnRlcnZhbHMuc2V0KG5hbWUsIHRpbWVyKTtcbiAgICAgICAgcmV0dXJuIHRpbWVyO1xuICAgIH1cblxuICAgIHB1YmxpYyBjcmVhdGVUaW1lb3V0KGNhbGxiYWNrOiBGdW5jdGlvbiwgdGltZW91dDogbnVtYmVyLCBuYW1lPzogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IHRpbWVyID0gdGhpcy5tdWx0aXBsYXllclNlcnZpY2UuVGltZXJzLnNldFRpbWVvdXQoY2FsbGJhY2ssIHRpbWVvdXQpO1xuICAgICAgICBpZiAoaXNTdHJpbmcobmFtZSkpIHRoaXMuJHRpbWVvdXRzLnNldChuYW1lLCB0aW1lcik7XG4gICAgICAgIHJldHVybiB0aW1lcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgY3JlYXRlRXZlcnlUaWNrKGNhbGxiYWNrOiBGdW5jdGlvbiwgbmFtZT86IHN0cmluZykge1xuICAgICAgICBjb25zdCB0aW1lciA9IHRoaXMubXVsdGlwbGF5ZXJTZXJ2aWNlLlRpbWVycy5ldmVyeVRpY2soY2FsbGJhY2spO1xuICAgICAgICBpZiAoaXNTdHJpbmcobmFtZSkpIHRoaXMuJGV2ZXJ5dGlja3Muc2V0KG5hbWUsIHRpbWVyKTtcbiAgICAgICAgcmV0dXJuIHRpbWVyO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWxldGUodHlwZTogJ2Nyb24nIHwgJ2V2ZXJ5dGljaycgfCAndGltZW91dCcgfCAnaW50ZXJ2YWwnLCBuYW1lOiBzdHJpbmcpIHtcbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICBjYXNlICdjcm9uJzpcbiAgICAgICAgICAgICAgICBjb25zdCBjcm9uSm9iID0gdGhpcy4kY3JvbnMuZ2V0KG5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChjcm9uSm9iKSB7XG4gICAgICAgICAgICAgICAgICAgIGNyb25Kb2Iuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRjcm9ucy5kZWxldGUobmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZXZlcnl0aWNrJzpcbiAgICAgICAgICAgICAgICBjb25zdCBldmVyeXRpY2sgPSB0aGlzLiRldmVyeXRpY2tzLmdldChuYW1lKTtcbiAgICAgICAgICAgICAgICBpZiAoZXZlcnl0aWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZXJ5dGljay5kZXN0cm95KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGV2ZXJ5dGlja3MuZGVsZXRlKG5hbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2ludGVydmFsJzpcbiAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnZhbCA9IHRoaXMuJGludGVydmFscy5nZXQobmFtZSk7XG4gICAgICAgICAgICAgICAgaWYgKGludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsLmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kaW50ZXJ2YWxzLmRlbGV0ZShuYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0aW1lb3V0JzpcbiAgICAgICAgICAgICAgICBjb25zdCB0aW1lb3V0ID0gdGhpcy4kdGltZW91dHMuZ2V0KG5hbWUpO1xuICAgICAgICAgICAgICAgIGlmICh0aW1lb3V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRpbWVvdXQuZGVzdHJveSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiR0aW1lb3V0cy5kZWxldGUobmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldEJ5TmFtZSh0eXBlOiAnY3JvbicgfCAnZXZlcnl0aWNrJyB8ICd0aW1lb3V0JyB8ICdpbnRlcnZhbCcsIG5hbWU6IHN0cmluZykge1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2Nyb24nOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLiRjcm9ucy5nZXQobmFtZSk7XG4gICAgICAgICAgICBjYXNlICdldmVyeXRpY2snOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLiRldmVyeXRpY2tzLmdldChuYW1lKTtcbiAgICAgICAgICAgIGNhc2UgJ2ludGVydmFsJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy4kaW50ZXJ2YWxzLmdldChuYW1lKTtcbiAgICAgICAgICAgIGNhc2UgJ3RpbWVvdXQnOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLiR0aW1lb3V0cy5nZXQobmFtZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0QnlJZChpZDogbnVtYmVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm11bHRpcGxheWVyU2VydmljZS5UaW1lcnMuZ2V0QnlJRChpZCk7XG4gICAgfVxuXG4gICAgcHVibGljIHRpbWUobmFtZT86IHN0cmluZykge1xuICAgICAgICByZXR1cm4gdGhpcy5tdWx0aXBsYXllclNlcnZpY2UuVGltZXJzLnRpbWUobmFtZSk7XG4gICAgfVxuXG4gICAgcHVibGljIHRpbWVFbmQobmFtZT86IHN0cmluZykge1xuICAgICAgICByZXR1cm4gdGhpcy5tdWx0aXBsYXllclNlcnZpY2UuVGltZXJzLnRpbWVFbmQobmFtZSk7XG4gICAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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LGVBQU8sS0FBSy9CLE9BQU9pQyxJQUFJZCxJQUFBQTtNQUMzQixLQUFLO0FBQ0QsZUFBTyxLQUFLdkIsWUFBWXFDLElBQUlkLElBQUFBO01BQ2hDLEtBQUs7QUFDRCxlQUFPLEtBQUtyQixXQUFXbUMsSUFBSWQsSUFBQUE7TUFDL0IsS0FBSztBQUNELGVBQU8sS0FBS3BCLFVBQVVrQyxJQUFJZCxJQUFBQTtJQUNsQztFQUNKO0VBRU9tQixRQUFRQyxJQUFZO0FBQ3ZCLFdBQU8sS0FBSzVDLG1CQUFtQk8sT0FBT3NDLFFBQVFELEVBQUFBO0VBQ2xEO0VBRU9FLEtBQUt0QixNQUFlO0FBQ3ZCLFdBQU8sS0FBS3hCLG1CQUFtQk8sT0FBT3VDLEtBQUt0QixJQUFBQTtFQUMvQztFQUVPdUIsUUFBUXZCLE1BQWU7QUFDMUIsV0FBTyxLQUFLeEIsbUJBQW1CTyxPQUFPd0MsUUFBUXZCLElBQUFBO0VBQ2xEO0FBQ0o7Ozs7Ozs7OyIsCiAgIm5hbWVzIjogWyJpbmplY3RhYmxlIiwgImluamVjdGFibGUiLCAiQ29udHJvbGxlciIsICJvcHRpb25zIiwgInRhcmdldCIsICJSZWZsZWN0IiwgImhhc01ldGFkYXRhIiwgIkNvcmVNZXRhZGF0YUtleSIsICJFcnJvciIsICJFcnJvck1lc3NhZ2UiLCAiRHVwbGljYXRlRGVjb3JhdG9yVXNhZ2UiLCAidmFsaWQiLCAidmFsdWUiLCAiZXJyb3IiLCAidmFsaWRhdGVDb250cm9sbGVyT3B0aW9ucyIsICJkZWZpbmVNZXRhZGF0YSIsICJpbmplY3RhYmxlIiwgIkdsb2JhbCIsICJ0YXJnZXQiLCAiUmVmbGVjdCIsICJkZWZpbmVNZXRhZGF0YSIsICJDb3JlTWV0YWRhdGFLZXkiLCAiR2xvYmFsTW9kdWxlIiwgImluamVjdCIsICJJbmplY3QiLCAia2V5IiwgInRhcmdldCIsICJwcm9wZXJ0eUtleSIsICJwYXJhbUluZGV4IiwgImlzTmlsIiwgInZhbGlkYXRlSW5qZWN0aW9uVG9rZW4iLCAidmFsaWQiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkludmFsaWRJbmplY3Rpb25Ub2tlblNwZWNpZmllZCIsICJ0b2tlbiIsICJSZWZsZWN0IiwgImdldE1ldGFkYXRhIiwgIkluamVjdGlvblRva2VuTm90Rm91bmQiLCAiaW5qZWN0IiwgImluamVjdGFibGUiLCAiSW5qZWN0YWJsZSIsICJvcHRpb25zIiwgInRhcmdldCIsICJSZWZsZWN0IiwgImhhc01ldGFkYXRhIiwgIkNvcmVNZXRhZGF0YUtleSIsICJFcnJvciIsICJFcnJvck1lc3NhZ2UiLCAiRHVwbGljYXRlRGVjb3JhdG9yVXNhZ2UiLCAidmFsaWQiLCAidmFsdWUiLCAiZXJyb3IiLCAidmFsaWRhdGVJbmplY3RhYmxlTWV0YWRhdGEiLCAiZGVmaW5lTWV0YWRhdGEiLCAiaW5qZWN0YWJsZSIsICJpbmplY3RhYmxlIiwgIk1vZHVsZSIsICJvcHRpb25zIiwgInRhcmdldCIsICJSZWZsZWN0IiwgImhhc01ldGFkYXRhIiwgIkNvcmVNZXRhZGF0YUtleSIsICJFcnJvciIsICJFcnJvck1lc3NhZ2UiLCAiRHVwbGljYXRlRGVjb3JhdG9yVXNhZ2UiLCAidmFsaWQiLCAidmFsdWUiLCAiZXJyb3IiLCAidmFsaWRhdGVNb2R1bGVPcHRpb25zIiwgImRlZmluZU1ldGFkYXRhIiwgImluamVjdGFibGUiLCAib3B0aW9uYWwiLCAiT3B0aW9uYWwiLCAidGFyZ2V0IiwgInByb3BlcnR5S2V5IiwgInBhcmFtSW5kZXgiLCAib3B0aW9uYWwiLCAiU2V0TWV0YWRhdGEiLCAia2V5IiwgInZhbHVlIiwgImRlY29yYXRvckZhY3RvcnkiLCAidGFyZ2V0IiwgIl9tZXRob2QiLCAiZGVzY3JpcHRvciIsICJSZWZsZWN0IiwgImRlZmluZU1ldGFkYXRhIiwgIktFWSIsICJDYXRjaCIsICJleGNlcHRpb25zIiwgInRhcmdldCIsICJSZWZsZWN0IiwgImhhc01ldGFkYXRhIiwgIkNvcmVNZXRhZGF0YUtleSIsICJFcnJvciIsICJFcnJvck1lc3NhZ2UiLCAiRHVwbGljYXRlRGVjb3JhdG9yVXNhZ2UiLCAiZHVwbGljYXRlcyIsICJmaWx0ZXIiLCAiZXhjZXB0aW9uIiwgImluZGV4IiwgImluZGV4T2YiLCAibGVuZ3RoIiwgIkV4Y2VwdGlvbkhhbmRsaW5nQ29uZmxpY3QiLCAiZGVmaW5lTWV0YWRhdGEiLCAiVXNlRmlsdGVycyIsICJmaWx0ZXJzIiwgInRhcmdldCIsICJtZXRob2QiLCAiZGVzY3JpcHRvciIsICJ2YWxpZGF0ZWRGaWx0ZXJzIiwgImZpbHRlciIsICJ2YWxpZCIsICJ2YWx1ZSIsICJlcnJvciIsICJ2YWxpZGF0ZUVycm9yRmlsdGVyIiwgIkVycm9yIiwgInB1c2giLCAiaXNOaWwiLCAibGVuZ3RoIiwgIkVycm9yTWVzc2FnZSIsICJBdExlYXN0T25lRmlsdGVyUmVxdWlyZWQiLCAibWV0aG9kRmlsdGVycyIsICJSZWZsZWN0IiwgImdldE1ldGFkYXRhIiwgIkNvcmVNZXRhZGF0YUtleSIsICJFcnJvckZpbHRlcnMiLCAiZmluZCIsICJpbmNsdWRlcyIsICJEdXBsaWNhdGVFcnJvckZpbHRlckRldGVjdGVkIiwgImRlZmluZU1ldGFkYXRhIiwgImNsYXNzRmlsdGVycyIsICJpbmplY3QiLCAiaW5qZWN0YWJsZSIsICJvcHRpb25hbCIsICJBcHBSdW50aW1lIiwgImV2ZW50SGFuZGxlciIsICJycGNIYW5kbGVyIiwgImdsb2JhbEd1YXJkcyIsICJnbG9iYWxJbnRlcmNlcHRvcnMiLCAiZ2xvYmFsUGlwZXMiLCAiZ2xvYmFsRXJyb3JGaWx0ZXJzIiwgImxvZ2dlclNlcnZpY2UiLCAiZW5hYmxlU2h1dGRvd25Ib29rcyIsICJib290IiwgInJlc29sdmVkVHJlZSIsICJhc3luY1RyYXZlcnNlIiwgIm5vZGUiLCAic3RhcnRUaW1lIiwgIkRhdGUiLCAibm93IiwgIm1vZHVsZSIsICJ2YWx1ZSIsICJpbnN0YW5jZSIsICJjb250YWluZXIiLCAiZ2V0IiwgIm1ldGFkYXRhIiwgImNsYXNzUmVmIiwgImNvbnRyb2xsZXJzIiwgImZvckVhY2giLCAiY29udHJvbGxlciIsICJpbnRlcm5hbFByb3ZpZGVycyIsICJleHRlcm5hbFByb3ZpZGVycyIsICJ0b2tlbiIsICJsb2ciLCAibmFtZSIsICJydW5MaWZlY3ljbGVNZXRob2QiLCAicnVuTGlmZWN5Y2xlTWV0aG9kcyIsICJ0cmF2ZXJzZSIsICJ0aW1lIiwgInJlZ2lzdGVyVGltZXJzIiwgInJlZ2lzdGVyTGlzdGVuZXJzIiwgInNodXRkb3duIiwgInRpbWVyU2VydmljZSIsICJvd25lciIsICJUSU1FUl9TRVJWSUNFIiwgImV2ZXJ5dGlja3MiLCAidGltZXIiLCAiZGVzdHJveSIsICJpbnRlcnZhbHMiLCAidGltZW91dHMiLCAiY3JvbnMiLCAiY3JvbiIsICJzdG9wIiwgImV2ZW50SGFuZGxlcnMiLCAiaGFuZGxlciIsICJycGNIYW5kbGVycyIsICJldmVudHMiLCAiZXZlbnQiLCAiZ3VhcmRzIiwgImludGVyY2VwdG9ycyIsICJwaXBlcyIsICJtYXBwZWRFcnJvckZpbHRlcnMiLCAibWFwRXJyb3JGaWx0ZXJzIiwgImVycm9yRmlsdGVycyIsICJyZWdpc3RlckV2ZW50IiwgInB1c2giLCAicnBjcyIsICJycGMiLCAicmVnaXN0ZXJSUEMiLCAidGltZXJzIiwgInR5cGUiLCAiY3JlYXRlQ3JvbkpvYiIsICJtZXRob2QiLCAiYmluZCIsICJvcHRpb25zIiwgImNyZWF0ZUV2ZXJ5VGljayIsICJjcmVhdGVJbnRlcnZhbCIsICJ0aW1lb3V0IiwgImNyZWF0ZVRpbWVvdXQiLCAiZmlsdGVyTWFwIiwgImZpbHRlciIsICJlcnJvcnMiLCAiUmVmbGVjdCIsICJnZXRNZXRhZGF0YSIsICJDb3JlTWV0YWRhdGFLZXkiLCAiQ2F0Y2giLCAibGVuZ3RoIiwgImVycm9yIiwgImlzTmlsIiwgImZpbmQiLCAiZmlsdGVyRXJyb3IiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkVycm9yQWxyZWFkeUhhbmRsZWRCeUZpbHRlciIsICJQcm9taXNlIiwgImFsbCIsICJtYXAiLCAiaXNPYmplY3QiLCAicHJvdmlkZXJJbnN0YW5jZSIsICJDb250YWluZXIiLCAiaW5qZWN0IiwgImluamVjdGFibGUiLCAib3B0aW9uYWwiLCAiTW9kdWxlRGVwZW5kZW5jeUJpbmRlciIsICJnbG9iYWxBcHBDb250YWluZXIiLCAibG9nZ2VyU2VydmljZSIsICJjb250YWluZXJPcHRpb25zIiwgImJpbmQiLCAicmVzb2x2ZWRUcmVlIiwgImFzeW5jVHJhdmVyc2UiLCAibm9kZSIsICJzdGFydFRpbWUiLCAiRGF0ZSIsICJub3ciLCAibW9kdWxlIiwgInZhbHVlIiwgImNvbnRhaW5lciIsICJNb2R1bGVDb250YWluZXIiLCAibWV0YWRhdGEiLCAicGFyZW50IiwgImNsYXNzUmVmIiwgInRvU2VsZiIsICJpblNpbmdsZXRvblNjb3BlIiwgImdsb2JhbCIsICJfIiwgInByb3ZpZGVyIiwgImV4dGVybmFsUHJvdmlkZXJzIiwgImJpbmRQcm92aWRlciIsICJ0b2tlbiIsICJ0b0R5bmFtaWNWYWx1ZSIsICJnZXQiLCAiaW1wb3J0TW9kdWxlIiwgInJlcGV0aXRpdmVJbXBvcnRzIiwgImludGVybmFsUHJvdmlkZXJzIiwgIk1PRFVMRV9DT05UQUlORVIiLCAidG9Db25zdGFudFZhbHVlIiwgImNvbnRyb2xsZXJzIiwgIlRJTUVSX1NFUlZJQ0UiLCAidG8iLCAiVGltZXJTZXJ2aWNlIiwgImxvZyIsICJuYW1lIiwgInByb3ZpZGUiLCAidXNlVmFsdWUiLCAiYmluZGluZyIsICJjdHgiLCAiZGVwcyIsICJpbmplY3QiLCAibWFwIiwgImRlcCIsICJpc09iamVjdCIsICJlcnIiLCAib3B0aW9uYWwiLCAidW5kZWZpbmVkIiwgImVycm9yIiwgInVzZUZhY3RvcnkiLCAic2NvcGUiLCAiaW5UcmFuc2llbnRTY29wZSIsICJpblJlcXVlc3RTY29wZSIsICJ1c2VDbGFzcyIsICJ0b1NlcnZpY2UiLCAidXNlRXhpc3RpbmciLCAiaW5qZWN0IiwgImluamVjdGFibGUiLCAiTW9kdWxlVHJlZVNjYW5uZXIiLCAibW9kdWxlTWV0YWRhdGFSZWFkZXIiLCAiY29udHJvbGxlck1ldGFkYXRhUmVhZGVyIiwgImxvZ2dlclNlcnZpY2UiLCAic2NhbiIsICJjbGFzc1JlZiIsICJzdGFydFRpbWUiLCAiRGF0ZSIsICJub3ciLCAibW9kdWxlTWV0YWRhdGEiLCAicmVhZCIsICJtb2R1bGUiLCAiTW9kdWxlIiwgIm1ldGFkYXRhIiwgImxvZyIsICJuYW1lIiwgInNjYW5Db250cm9sbGVycyIsICJtb2R1bGVUcmVlIiwgIlRyZWUiLCAic2Nhbm5lZE1vZHVsZXMiLCAiTWFwIiwgInNldCIsICJpbXBvcnRlZE1vZHVsZSIsICJpbXBvcnRzIiwgInNjYW5Nb2R1bGVzIiwgInJvb3QiLCAicGFyZW50Tm9kZSIsICJzY2FubmVkTW9kdWxlIiwgImdldCIsICJpc05pbCIsICJ2YWx1ZSIsICJyZXBldGl0aXZlSW1wb3J0cyIsICJhZGQiLCAiY2hlY2tDaXJjdWxhckRlcGVuZGVuY3kiLCAicGFyZW50IiwgInRyZWVOb2RlIiwgIlRyZWVOb2RlIiwgImFkZENoaWxkIiwgImltcG9ydE1vZHVsZSIsICJjb250cm9sbGVycyIsICJjb250cm9sbGVyTWV0YWRhdGEiLCAiY29udHJvbGxlciIsICJDb250cm9sbGVyIiwgIm93bmVyIiwgInB1c2giLCAicGFyZW50TWV0YWRhdGEiLCAiaW5jbHVkZXMiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkNpcmN1bGFyRGVwZW5kZW5jeURldGVjdGVkIiwgIlJhZ2VNUFNjcmlwdEV2ZW50IiwgImV2ZW50TmFtZSIsICJsaXN0ZW5lciIsICJkZXN0cm95IiwgIm1wIiwgImV2ZW50cyIsICJyZW1vdmUiLCAiUmFnZU1QRXZlbnRFbW1pdGVyIiwgIm1hcEV2ZW50c1NoYXJlZCIsICJtYXBFdmVudHMiLCAiZ2V0RXZlbnROYW1lIiwgImV2ZW50TmFtZSIsICJlbWl0IiwgImFyZ3MiLCAibXAiLCAiZXZlbnRzIiwgImNhbGwiLCAib24iLCAibGlzdGVuZXIiLCAibWFwcGVkRXZlbnROYW1lIiwgImFkZCIsICJSYWdlTVBTY3JpcHRFdmVudCIsICJvbmNlIiwgIm9uY2VXcmFwcGVyIiwgInJlbW92ZSIsICJvZmYiLCAiUmFnZU1QVGltZXIiLCAibGFzdFRpY2siLCAiRGF0ZSIsICJub3ciLCAiaWQiLCAiaW50ZXJ2YWwiLCAib25jZSIsICJjYWxsYmFjayIsICJjbGVhclRpbWVyIiwgImRlc3Ryb3kiLCAiUmFnZU1QVGltZXJzIiwgInRpbWVySW5jcmVtZW50ZXIiLCAidGltZXJzIiwgIk1hcCIsICJldmVyeVRpY2tIYW5kbGVycyIsICJpc0V2ZXJ5VGlja1J1bm5pbmciLCAiZXZlcnlUaWNrTWFpbkhhbmRsZXIiLCAiYWxsIiwgInZhbHVlcyIsICJ3YXJuaW5nVGhyZXNob2xkIiwgIl92YWx1ZSIsICJzb3VyY2VMb2NhdGlvbkZyYW1lU2tpcENvdW50IiwgImdldEJ5SUQiLCAiaWQiLCAidGltZXIiLCAiZ2V0IiwgImNyZWF0ZVRpbWVyIiwgImNsZWFyIiwgImNhbGxiYWNrIiwgImludGVydmFsIiwgIm9uY2UiLCAiYXJncyIsICJjYWxsYmFja0JpbmQiLCAiYmluZCIsICJBcnJheSIsICJpc0FycmF5IiwgInRpbWVySWQiLCAicmFnZU1QVGltZXIiLCAiUmFnZU1QVGltZXIiLCAiZGVsZXRlIiwgInNldCIsICJzZXRJbnRlcnZhbCIsICJ0aW1lIiwgImNiIiwgImNsZWFySW50ZXJ2YWwiLCAic2V0VGltZW91dCIsICJjbGVhclRpbWVvdXQiLCAiZXZlcnlUaWNrIiwgImJvdW5kIiwgImlzQ2xpZW50U2lkZSIsICJtcCIsICJicm93c2VycyIsICJoYW5kbGVyIiwgImUiLCAiY29uc29sZSIsICJsb2dFcnJvciIsICJldmVudHMiLCAiYWRkIiwgImludGVydmFsSGFuZGxlciIsICJfZXZlcnlUaWNrSW50ZXJ2YWwiLCAic2l6ZSIsICJyZW1vdmUiLCAibmV4dFRpY2siLCAiX25hbWUiLCAidGltZUVuZCIsICJSYWdlTVBNdWx0aXBsYXllclNlcnZpY2UiLCAiVGltZXJzIiwgIkV2ZW50cyIsICJSYWdlTVBFdmVudEVtbWl0ZXIiLCAiUmFnZU1QVGltZXJzIiwgInBhcnNlSW50ZXJuYWxBcmdzIiwgImFyZ3MiLCAicGxheWVyIiwgImlzT2JqZWN0IiwgInVuZGVmaW5lZCIsICJib2R5IiwgImxvZyIsICJhcmciLCAibWVzc2FnZSIsICJtYXAiLCAiYSIsICJKU09OIiwgInN0cmluZ2lmeSIsICJTdHJpbmciLCAiam9pbiIsICJtcCIsICJjb25zb2xlIiwgImxvZ0luZm8iLCAibG9nRXJyb3IiLCAibG9nV2FybmluZyIsICJsb2dEZWJ1ZyIsICJpbmplY3QiLCAiQ29udGFpbmVyIiwgImluamVjdGFibGUiLCAiQ29udGFpbmVyIiwgImluamVjdCIsICJpbmplY3RhYmxlIiwgIkFwcCIsICJtb2R1bGVUcmVlU2Nhbm5lciIsICJtb2R1bGVEZXBlbmRlbmN5QmluZGVyIiwgImFwcFJ1bnRpbWUiLCAiaW50ZXJuYWxBcHBDb250YWluZXIiLCAicGx1Z2lucyIsICJsb2dnZXJTZXJ2aWNlIiwgIm1vZHVsZVRyZWUiLCAibG9hZGVkIiwgInN0YXJ0IiwgInJvb3RNb2R1bGUiLCAiZXJyb3IiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkFwcEFscmVhZHlMb2FkZWQiLCAibG9nIiwgInJ1blBsdWdpbk1ldGhvZHMiLCAic2NhbiIsICJiaW5kIiwgImJvb3QiLCAic3RvcCIsICJBcHBOb3RMb2FkZWQiLCAic2h1dGRvd24iLCAibWV0aG9kIiwgIlByb21pc2UiLCAiYWxsIiwgIm1hcCIsICJwIiwgInBsdWdpbiIsICJnZXQiLCAicmVzb2x2ZSIsICJBcHBCdWlsZGVyIiwgImVudmlyb21lbnQiLCAiaW50ZXJuYWxBcHBDb250YWluZXIiLCAibXVsdGlwbGF5ZXJTZXJ2aWNlIiwgInBsdWdpbnMiLCAiZ2xvYmFsQ29udGFpbmVyT3B0aW9ucyIsICJ1c2VHbG9iYWxHdWFyZHMiLCAiZ3VhcmRzIiwgInZhbGlkYXRlZEd1YXJkcyIsICJndWFyZCIsICJ2YWxpZCIsICJ2YWx1ZSIsICJlcnJvciIsICJ2YWxpZGF0ZUd1YXJkIiwgIkVycm9yIiwgInB1c2giLCAiYmluZCIsICJHTE9CQUxfR1VBUkRTIiwgInRvQ29uc3RhbnRWYWx1ZSIsICJ1c2VHbG9iYWxJbnRlcmNlcHRvcnMiLCAiaW50ZXJjZXB0b3JzIiwgInZhbGlkYXRlZEludGVyY2VwdG9ycyIsICJpbnRlcmNlcHRvciIsICJ2YWxpZGF0ZUludGVyY2VwdG9yIiwgIkdMT0JBTF9JTlRFUkNFUFRPUlMiLCAidXNlR2xvYmFsUGlwZXMiLCAicGlwZXMiLCAidmFsaWRhdGVkUGlwZXMiLCAicGlwZSIsICJ2YWxpZGF0ZVBpcGUiLCAiR0xPQkFMX1BJUEVTIiwgInVzZUdsb2JhbEZpbHRlcnMiLCAiZmlsdGVycyIsICJ2YWxpZGF0ZWRGSWx0ZXJzIiwgImZpbHRlciIsICJ2YWxpZGF0ZUVycm9yRmlsdGVyIiwgIkdMT0JBTF9FUlJPUl9GSUxURVJTIiwgInVzZVBsdWdpbnMiLCAiZm9yRWFjaCIsICJwIiwgInRvU2VsZiIsICJpblNpbmdsZXRvblNjb3BlIiwgImludGVybmFsUGx1Z2lucyIsICJnZXQiLCAiUExVR0lOUyIsICJyZWJpbmQiLCAiZW5hYmxlU2h1dGRvd25Ib29rcyIsICJFTkFCTEVfU0hVVERPV05fSE9PS1MiLCAic2V0Q29udGFpbmVyT3B0aW9ucyIsICJvcHRpb25zIiwgIm9ubHlHbG9iYWwiLCAiQ09OVEFJTkVSX09QVElPTlMiLCAiYnVpbGQiLCAiZ2xvYmFsQXBwQ29udGFpbmVyIiwgIkNvbnRhaW5lciIsICJSRUZMRUNUT1JfU0VSVklDRSIsICJSZWZsZWN0b3JTZXJ2aWNlIiwgInRvU2VydmljZSIsICJNVUxUSVBMQVlFUl9TRVJWSUNFIiwgIkFwcCIsICJHTE9CQUxfQVBQX0NPTlRBSU5FUiIsICJNb2R1bGVUcmVlU2Nhbm5lciIsICJNb2R1bGVEZXBlbmRlbmN5QmluZGVyIiwgIkFwcFJ1bnRpbWUiLCAiUGlwZWxpbmVIYW5kbGVyIiwgIk1vZHVsZSIsICJpblRyYW5zaWVudFNjb3BlIiwgIk1vZHVsZU1ldGFkYXRhUmVhZGVyIiwgIkNvbnRyb2xsZXIiLCAiQ29udHJvbGxlck1ldGFkYXRhUmVhZGVyIiwgIkNvbnRyb2xsZXJGbG93SGFuZGxlciIsICJDb250cm9sbGVyRXZlbnRIYW5kbGVyIiwgIkNvbnRyb2xsZXJSUENIYW5kbGVyIiwgIk1hbmdvUmVxdWVzdEJhc2UiLCAiTUFOR09fUkVRVUVTVF9GQUNUT1JZIiwgInRvRmFjdG9yeSIsICJjb250ZXh0IiwgImJvZHkiLCAicGxheWVyIiwgInJlcXVlc3QiLCAiY29udGFpbmVyIiwgIiRib2R5IiwgIiRwbGF5ZXIiLCAiTWFuZ29SZXNwb25zZUJhc2UiLCAiTUFOR09fUkVTUE9OU0VfRkFDVE9SWSIsICJFeGVjdXRpb25Db250ZXh0QmFzZSIsICJFWEVDVVRJT05fQ09OVEVYVF9GQUNUT1JZIiwgInR5cGUiLCAiY2xhc3NSZWYiLCAiaGFuZGxlciIsICJyZXNwb25zZSIsICJuYW1lIiwgImV4ZWN1dGlvbkNvbnRleHQiLCAiJHR5cGUiLCAiJHJlcXVlc3QiLCAiJHJlc3BvbnNlIiwgIiRoYW5kbGVyIiwgIiRjbGFzc1JlZiIsICIkbmFtZSIsICJwbHVnaW4iLCAicGx1Z2luSW5zdGFuY2UiLCAib25CdWlsZCIsICJpc0JvdW5kIiwgIkNvbnRhaW5lciIsICJjcmVhdGVBcHBCdWlsZGVyIiwgImVudmlyb21lbnQiLCAicGx1Z2lucyIsICJhcHBCdWlsZGVySW5oZXJpdCIsICJtdWx0aXBsYXllclNlcnZpY2UiLCAiaW50ZXJuYWxBcHBDb250YWluZXIiLCAiQ29udGFpbmVyIiwgImJpbmQiLCAiTVVMVElQTEFZRVJfU0VSVklDRSIsICJ0b0NvbnN0YW50VmFsdWUiLCAiSU5URVJOQUxfQVBQX0NPTlRBSU5FUiIsICJBUFBfRU5WSVJPTUVOVCIsICJQTFVHSU5TIiwgInRvU2VsZiIsICJpblNpbmdsZXRvblNjb3BlIiwgImdldCIsICJjcmVhdGVFdmVudERlY29yYXRvciIsICJ0eXBlIiwgIm5hbWUiLCAid2ViVmlld0lkIiwgInRhcmdldCIsICJtZXRob2QiLCAiaXNOaWwiLCAiaXNTdHJpbmciLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkV2ZW50TmFtZU11c3RCZVN0cmluZyIsICJldmVudHMiLCAiUmVmbGVjdCIsICJnZXRNZXRhZGF0YSIsICJDb3JlTWV0YWRhdGFLZXkiLCAiQ29udHJvbGxlckV2ZW50cyIsICJzb21lIiwgImV2ZW50IiwgIkV2ZW50TmFtZU11c3RCZVVuaXF1ZSIsICJkZWZpbmVNZXRhZGF0YSIsICJPbkludGVybmFsIiwgImV2ZW50TmFtZSIsICJjcmVhdGVFdmVudERlY29yYXRvciIsICJPbldlYlZpZXciLCAiaWQiLCAiZXZlbnROYW1lIiwgImNyZWF0ZUV2ZW50RGVjb3JhdG9yIiwgIk9uIiwgImV2ZW50TmFtZSIsICJjcmVhdGVFdmVudERlY29yYXRvciIsICJPbmNlSW50ZXJuYWwiLCAiZXZlbnROYW1lIiwgImNyZWF0ZUV2ZW50RGVjb3JhdG9yIiwgIk9uY2UiLCAiZXZlbnROYW1lIiwgImNyZWF0ZUV2ZW50RGVjb3JhdG9yIiwgIk9uY2VXZWJWaWV3IiwgImlkIiwgImV2ZW50TmFtZSIsICJjcmVhdGVFdmVudERlY29yYXRvciIsICJCb2R5IiwgInBpcGVzIiwgInRhcmdldCIsICJtZXRob2QiLCAiaW5kZXgiLCAidmFsaWRhdGVkUGlwZXMiLCAicGlwZSIsICJ2YWxpZCIsICJ2YWx1ZSIsICJlcnJvciIsICJ2YWxpZGF0ZVBpcGUiLCAiRXJyb3IiLCAicHVzaCIsICJwYXJhbXMiLCAiUmVmbGVjdCIsICJnZXRNZXRhZGF0YSIsICJDb3JlTWV0YWRhdGFLZXkiLCAiQ29udHJvbGxlclBhcmFtcyIsICJzb21lIiwgInBhcmFtIiwgIkVycm9yTWVzc2FnZSIsICJNdWx0aXBsZURlY29yYXRvcnNPblNpbmdsZVBhcmFtZXRlck5vdEFsbG93ZWQiLCAicGFyYW1UeXBlcyIsICJtZXRhdHlwZSIsICJBcnJheSIsICJpc0FycmF5IiwgInVuZGVmaW5lZCIsICJkZWZpbmVNZXRhZGF0YSIsICJ0eXBlIiwgIk1ldGhvZFBhcmFtVHlwZSIsICJkYXRhIiwgIkluZGV4IiwgImtleSIsICJwaXBlcyIsICJ0YXJnZXQiLCAibWV0aG9kIiwgImluZGV4IiwgImlzTnVtYmVyIiwgIkVycm9yIiwgIkVycm9yTWVzc2FnZSIsICJJbmRleEtleU11c3RCZU51bWJlciIsICJ2YWxpZGF0ZWRQaXBlcyIsICJwaXBlIiwgInZhbGlkIiwgInZhbHVlIiwgImVycm9yIiwgInZhbGlkYXRlUGlwZSIsICJwdXNoIiwgInBhcmFtcyIsICJSZWZsZWN0IiwgImdldE1ldGFkYXRhIiwgIkNvcmVNZXRhZGF0YUtleSIsICJDb250cm9sbGVyUGFyYW1zIiwgInNvbWUiLCAicGFyYW0iLCAiTXVsdGlwbGVEZWNvcmF0b3JzT25TaW5nbGVQYXJhbWV0ZXJOb3RBbGxvd2VkIiwgInBhcmFtVHlwZXMiLCAibWV0YXR5cGUiLCAiQXJyYXkiLCAiaXNBcnJheSIsICJ1bmRlZmluZWQiLCAiZGVmaW5lTWV0YWRhdGEiLCAidHlwZSIsICJNZXRob2RQYXJhbVR5cGUiLCAiZGF0YSIsICJSZXF1ZXN0IiwgInRhcmdldCIsICJtZXRob2QiLCAiaW5kZXgiLCAicGFyYW1zIiwgIlJlZmxlY3QiLCAiZ2V0TWV0YWRhdGEiLCAiQ29yZU1ldGFkYXRhS2V5IiwgIkNvbnRyb2xsZXJQYXJhbXMiLCAic29tZSIsICJwYXJhbSIsICJFcnJvciIsICJFcnJvck1lc3NhZ2UiLCAiTXVsdGlwbGVEZWNvcmF0b3JzT25TaW5nbGVQYXJhbWV0ZXJOb3RBbGxvd2VkIiwgInBhcmFtVHlwZXMiLCAibWV0YXR5cGUiLCAiQXJyYXkiLCAiaXNBcnJheSIsICJ1bmRlZmluZWQiLCAiZGVmaW5lTWV0YWRhdGEiLCAidHlwZSIsICJNZXRob2RQYXJhbVR5cGUiLCAiZGF0YSIsICJSZXEiLCAiUGFyYW0iLCAia2V5IiwgInBpcGVzIiwgInRhcmdldCIsICJtZXRob2QiLCAiaW5kZXgiLCAiaXNTdHJpbmciLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIlBhcmFtS2V5TXVzdEJlU3RyaW5nIiwgInZhbGlkYXRlZFBpcGVzIiwgInBpcGUiLCAidmFsaWQiLCAidmFsdWUiLCAiZXJyb3IiLCAidmFsaWRhdGVQaXBlIiwgInB1c2giLCAicGFyYW1zIiwgIlJlZmxlY3QiLCAiZ2V0TWV0YWRhdGEiLCAiQ29yZU1ldGFkYXRhS2V5IiwgIkNvbnRyb2xsZXJQYXJhbXMiLCAic29tZSIsICJwYXJhbSIsICJNdWx0aXBsZURlY29yYXRvcnNPblNpbmdsZVBhcmFtZXRlck5vdEFsbG93ZWQiLCAicGFyYW1UeXBlcyIsICJtZXRhdHlwZSIsICJBcnJheSIsICJpc0FycmF5IiwgInVuZGVmaW5lZCIsICJkZWZpbmVNZXRhZGF0YSIsICJkYXRhIiwgInR5cGUiLCAiTWV0aG9kUGFyYW1UeXBlIiwgIlJlc3BvbnNlIiwgInRhcmdldCIsICJtZXRob2QiLCAiaW5kZXgiLCAicGFyYW1zIiwgIlJlZmxlY3QiLCAiZ2V0TWV0YWRhdGEiLCAiQ29yZU1ldGFkYXRhS2V5IiwgIkNvbnRyb2xsZXJQYXJhbXMiLCAic29tZSIsICJwYXJhbSIsICJFcnJvciIsICJFcnJvck1lc3NhZ2UiLCAiTXVsdGlwbGVEZWNvcmF0b3JzT25TaW5nbGVQYXJhbWV0ZXJOb3RBbGxvd2VkIiwgInBhcmFtVHlwZXMiLCAibWV0YXR5cGUiLCAiQXJyYXkiLCAiaXNBcnJheSIsICJ1bmRlZmluZWQiLCAiZGVmaW5lTWV0YWRhdGEiLCAidHlwZSIsICJNZXRob2RQYXJhbVR5cGUiLCAiZGF0YSIsICJSZXMiLCAiVXNlR3VhcmRzIiwgImd1YXJkcyIsICJ0YXJnZXQiLCAibWV0aG9kIiwgImRlc2NyaXB0b3IiLCAidmFsaWRhdGVkR3VhcmRzIiwgImd1YXJkIiwgInZhbGlkIiwgInZhbHVlIiwgImVycm9yIiwgInZhbGlkYXRlR3VhcmQiLCAiRXJyb3IiLCAicHVzaCIsICJpc05pbCIsICJsZW5ndGgiLCAiRXJyb3JNZXNzYWdlIiwgIkF0TGVhc3RPbmVHdWFyZFJlcXVpcmVkIiwgIm1ldGhvZEd1YXJkcyIsICJSZWZsZWN0IiwgImdldE1ldGFkYXRhIiwgIkNvcmVNZXRhZGF0YUtleSIsICJHdWFyZHMiLCAiZGVmaW5lTWV0YWRhdGEiLCAiY2xhc3NHdWFyZHMiLCAiVXNlSW50ZXJjZXB0b3JzIiwgImludGVyY2VwdG9ycyIsICJ0YXJnZXQiLCAibWV0aG9kIiwgImRlc2NyaXB0b3IiLCAidmFsaWRhdGVkSW50ZXJjZXB0b3JzIiwgImludGVyY2VwdG9yIiwgInZhbGlkIiwgInZhbHVlIiwgImVycm9yIiwgInZhbGlkYXRlSW50ZXJjZXB0b3IiLCAiRXJyb3IiLCAicHVzaCIsICJpc05pbCIsICJsZW5ndGgiLCAiRXJyb3JNZXNzYWdlIiwgIkF0TGVhc3RPbmVJbnRlcmNlcHRvclJlcXVpcmVkIiwgIm1ldGhvZEludGVyY2VwdG9ycyIsICJSZWZsZWN0IiwgImdldE1ldGFkYXRhIiwgIkNvcmVNZXRhZGF0YUtleSIsICJJbnRlcmNlcHRvcnMiLCAiZGVmaW5lTWV0YWRhdGEiLCAiY2xhc3NJbnRlcmNlcHRvcnMiLCAiVXNlUGlwZXMiLCAicGlwZXMiLCAidGFyZ2V0IiwgIm1ldGhvZCIsICJkZXNjcmlwdG9yIiwgInZhbGlkYXRlZFBpcGVzIiwgInBpcGUiLCAidmFsaWQiLCAidmFsdWUiLCAiZXJyb3IiLCAidmFsaWRhdGVQaXBlIiwgIkVycm9yIiwgInB1c2giLCAiaXNOaWwiLCAibGVuZ3RoIiwgIkVycm9yTWVzc2FnZSIsICJBdExlYXN0T25lUGlwZVJlcXVpcmVkIiwgIm1ldGhvZFBpcGVzIiwgIlJlZmxlY3QiLCAiZ2V0TWV0YWRhdGEiLCAiQ29yZU1ldGFkYXRhS2V5IiwgIlBpcGVzIiwgImRlZmluZU1ldGFkYXRhIiwgImNsYXNzUGlwZXMiLCAiY3JlYXRlUlBDRGVjb3JhdG9yIiwgInR5cGUiLCAibmFtZSIsICJ3ZWJWaWV3SWQiLCAidGFyZ2V0IiwgIm1ldGhvZCIsICJpc05pbCIsICJpc1N0cmluZyIsICJpc051bWJlciIsICJFcnJvciIsICJFcnJvck1lc3NhZ2UiLCAiV2ViVmlld0lkTXVzdEJlU3RyaW5nT3JOdW1iZXIiLCAiUlBDTmFtZU11c3RCZVN0cmluZyIsICJycGNzIiwgIlJlZmxlY3QiLCAiZ2V0TWV0YWRhdGEiLCAiQ29yZU1ldGFkYXRhS2V5IiwgIkNvbnRyb2xsZXJSUENzIiwgInNvbWUiLCAicnBjIiwgIlJQQ05hbWVNdXN0QmVVbmlxdWUiLCAiZGVmaW5lTWV0YWRhdGEiLCAiT25SZXF1ZXN0IiwgInJwY05hbWUiLCAiY3JlYXRlUlBDRGVjb3JhdG9yIiwgIk9uV2ViVmlld1JlcXVlc3QiLCAiaWQiLCAicnBjTmFtZSIsICJjcmVhdGVSUENEZWNvcmF0b3IiLCAiY3JlYXRlVGltZXJEZWNvcmF0b3IiLCAidHlwZSIsICJuYW1lIiwgIm9wdGlvbnMiLCAidGFyZ2V0IiwgIm1ldGhvZCIsICJpc05pbCIsICJpc1N0cmluZyIsICJFcnJvciIsICJFcnJvck1lc3NhZ2UiLCAiVGltZXJOYW1lTXVzdEJlU3RyaW5nIiwgInRpbWVycyIsICJSZWZsZWN0IiwgImdldE1ldGFkYXRhIiwgIkNvcmVNZXRhZGF0YUtleSIsICJUaW1lcnMiLCAic29tZSIsICJ0aW1lciIsICJFdmVudE5hbWVNdXN0QmVVbmlxdWUiLCAiZGVmaW5lTWV0YWRhdGEiLCAiQ3JvbiIsICJwYXR0ZXJuIiwgIm9wdGlvbnMiLCAiY3JlYXRlVGltZXJEZWNvcmF0b3IiLCAibmFtZSIsICJFdmVyeVRpY2siLCAibmFtZSIsICJjcmVhdGVUaW1lckRlY29yYXRvciIsICJJbnRlcnZhbCIsICJuYW1lT3JUaW1lb3V0IiwgInRpbWVvdXQiLCAibmFtZSIsICJpbnRlcnZhbFRpbWVvdXQiLCAiaXNTdHJpbmciLCAidW5kZWZpbmVkIiwgImNyZWF0ZVRpbWVyRGVjb3JhdG9yIiwgIlRpbWVvdXQiLCAibmFtZU9yVGltZW91dCIsICJ0aW1lb3V0IiwgIm5hbWUiLCAiaW50ZXJ2YWxUaW1lb3V0IiwgImlzU3RyaW5nIiwgInVuZGVmaW5lZCIsICJjcmVhdGVUaW1lckRlY29yYXRvciIsICJhcHBseURlY29yYXRvcnMiLCAiZGVjb3JhdG9ycyIsICJ0YXJnZXQiLCAicHJvcGVydHlLZXkiLCAiZGVzY3JpcHRvciIsICJkZWNvcmF0b3IiLCAiRnVuY3Rpb24iLCAiY3JlYXRlUGFyYW1EZWNvcmF0b3IiLCAiZmFjdG9yeSIsICJkYXRhIiwgInBpcGVzIiwgInRhcmdldCIsICJtZXRob2QiLCAiaW5kZXgiLCAidmFsaWRhdGVkUGlwZXMiLCAicGlwZSIsICJ2YWxpZCIsICJ2YWx1ZSIsICJlcnJvciIsICJ2YWxpZGF0ZVBpcGUiLCAiRXJyb3IiLCAicHVzaCIsICJwYXJhbXMiLCAiUmVmbGVjdCIsICJnZXRNZXRhZGF0YSIsICJDb3JlTWV0YWRhdGFLZXkiLCAiQ29udHJvbGxlclBhcmFtcyIsICJzb21lIiwgInBhcmFtIiwgIkVycm9yTWVzc2FnZSIsICJNdWx0aXBsZURlY29yYXRvcnNPblNpbmdsZVBhcmFtZXRlck5vdEFsbG93ZWQiLCAicGFyYW1UeXBlcyIsICJtZXRhdHlwZSIsICJBcnJheSIsICJpc0FycmF5IiwgInVuZGVmaW5lZCIsICJkZWZpbmVNZXRhZGF0YSIsICJ0eXBlIiwgIk1ldGhvZFBhcmFtVHlwZSIsICJDdXN0b20iLCAiTGF6eVNlcnZpY2VJZGVudGlmZXIiLCAiZm9yd2FyZFJlZiIsICJmbiIsICJMYXp5U2VydmljZUlkZW50aWZlciIsICJSZWZsZWN0b3JTZXJ2aWNlIiwgImdldCIsICJtZXRhZGF0YUtleSIsICJ0YXJnZXQiLCAiUmVmbGVjdCIsICJnZXRNZXRhZGF0YSIsICJnZXRBbGwiLCAidGFyZ2V0cyIsICJtYXAiLCAiZ2V0QWxsQW5kTWVyZ2UiLCAibWV0YWRhdGFDb2xsZWN0aW9uIiwgImZpbHRlciIsICJpdGVtIiwgInVuZGVmaW5lZCIsICJpc0VtcHR5IiwgInJlZHVjZSIsICJhIiwgImIiLCAiQXJyYXkiLCAiaXNBcnJheSIsICJjb25jYXQiLCAiaXNPYmplY3QiLCAiZ2V0QWxsQW5kT3ZlcnJpZGUiLCAicmVzdWx0IiwgImNyZWF0ZURlY29yYXRvciIsICJvcHRpb25zIiwgImtleSIsICJnZW5lcmF0ZVJhbmRvbUlkIiwgImRlY29yYXRvckZuIiwgIm1ldGFkYXRhVmFsdWUiLCAiZGVzY3JpcHRvciIsICJ2YWx1ZSIsICJ0cmFuc2Zvcm0iLCAiU2V0TWV0YWRhdGEiLCAiS0VZIiwgImluamVjdCIsICJpbmplY3RhYmxlIiwgIkNyb24iLCAiVGltZXJTZXJ2aWNlIiwgIm11bHRpcGxheWVyU2VydmljZSIsICIkZXZlcnl0aWNrcyIsICJNYXAiLCAiJGludGVydmFscyIsICIkdGltZW91dHMiLCAiJGNyb25zIiwgImFsbCIsICJUaW1lcnMiLCAiZXZlcnl0aWNrcyIsICJ2YWx1ZXMiLCAiaW50ZXJ2YWxzIiwgInRpbWVvdXRzIiwgImNyb25zIiwgIndhcm5pbmdUaHJlc2hvbGQiLCAidmFsdWUiLCAic291cmNlTG9jYXRpb25GcmFtZVNraXBDb3VudCIsICJjcmVhdGVDcm9uSm9iIiwgImNhbGxiYWNrIiwgIm9wdGlvbnMiLCAicGF0dGVybiIsICJjcm9uT3B0aW9ucyIsICJjcm9uIiwgIkNyb24iLCAiaXNTdHJpbmciLCAibmFtZSIsICJzZXQiLCAiY3JlYXRlSW50ZXJ2YWwiLCAiaW50ZXJ2YWwiLCAidGltZXIiLCAic2V0SW50ZXJ2YWwiLCAiY3JlYXRlVGltZW91dCIsICJ0aW1lb3V0IiwgInNldFRpbWVvdXQiLCAiY3JlYXRlRXZlcnlUaWNrIiwgImV2ZXJ5VGljayIsICJkZWxldGUiLCAidHlwZSIsICJjcm9uSm9iIiwgImdldCIsICJzdG9wIiwgImV2ZXJ5dGljayIsICJkZXN0cm95IiwgImdldEJ5TmFtZSIsICJnZXRCeUlkIiwgImlkIiwgImdldEJ5SUQiLCAidGltZSIsICJ0aW1lRW5kIl0KfQo=
|