@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,570 @@
|
|
|
1
|
+
import {
|
|
2
|
+
APP_ENVIROMENT,
|
|
3
|
+
EXECUTION_CONTEXT_FACTORY,
|
|
4
|
+
MANGO_REQUEST_FACTORY,
|
|
5
|
+
MANGO_RESPONSE_FACTORY,
|
|
6
|
+
MULTIPLAYER_SERVICE
|
|
7
|
+
} from "./chunk-HK7QTFPA.js";
|
|
8
|
+
import {
|
|
9
|
+
AppEnviroment,
|
|
10
|
+
CoreMetadataKey,
|
|
11
|
+
ExecutionContextType
|
|
12
|
+
} from "./chunk-TBWHLT75.js";
|
|
13
|
+
import {
|
|
14
|
+
EVENT_SERVICE,
|
|
15
|
+
LOGGER_SERVICE,
|
|
16
|
+
RPC_SERVICE
|
|
17
|
+
} from "./chunk-DJZCOYB3.js";
|
|
18
|
+
import {
|
|
19
|
+
GuardCancelError,
|
|
20
|
+
GuardInvalidReturnError
|
|
21
|
+
} from "./chunk-6YEWPMZJ.js";
|
|
22
|
+
import {
|
|
23
|
+
ErrorMessage
|
|
24
|
+
} from "./chunk-DXPVUDXD.js";
|
|
25
|
+
import {
|
|
26
|
+
isAsyncFunction,
|
|
27
|
+
isFunction,
|
|
28
|
+
isNil,
|
|
29
|
+
isObject
|
|
30
|
+
} from "./chunk-E6IQL4S6.js";
|
|
31
|
+
import {
|
|
32
|
+
__name
|
|
33
|
+
} from "./chunk-7QVYU63E.js";
|
|
34
|
+
|
|
35
|
+
// src/app/controller/controller-event.handler.ts
|
|
36
|
+
import { inject as inject3, injectable as injectable3 } from "inversify";
|
|
37
|
+
|
|
38
|
+
// src/app/controller/pipeline.handler.ts
|
|
39
|
+
import { inject, injectable } from "inversify";
|
|
40
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
41
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
42
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
43
|
+
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;
|
|
44
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
45
|
+
}
|
|
46
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
47
|
+
function _ts_metadata(k, v) {
|
|
48
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
49
|
+
}
|
|
50
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
51
|
+
var PipelineHandler = class {
|
|
52
|
+
static {
|
|
53
|
+
__name(this, "PipelineHandler");
|
|
54
|
+
}
|
|
55
|
+
loggerService;
|
|
56
|
+
// @inject(GLOBAL_APP_CONTAINER) private readonly globalContainer: Container;
|
|
57
|
+
async goTroughGuards(executionContext, guards, container) {
|
|
58
|
+
for (const guard of guards) {
|
|
59
|
+
const instance = isFunction(guard) ? container.get(guard) : isObject(guard) && isFunction(guard["canActivate"]) ? guard : null;
|
|
60
|
+
if (isNil(instance)) {
|
|
61
|
+
this.loggerService.error("An error occurred while trying to go through guards.");
|
|
62
|
+
throw new Error(ErrorMessage.InvalidGuardDefinition);
|
|
63
|
+
}
|
|
64
|
+
const canActivate = await instance.canActivate.call(instance, executionContext);
|
|
65
|
+
if (typeof canActivate !== "boolean") {
|
|
66
|
+
this.loggerService.error("An error occurred while trying to go through guards.");
|
|
67
|
+
throw new GuardInvalidReturnError();
|
|
68
|
+
}
|
|
69
|
+
if (!canActivate) {
|
|
70
|
+
throw new GuardCancelError();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async goThroughInterceptors(executionContext, interceptors, container, callHandler) {
|
|
75
|
+
for (const interceptor of interceptors) {
|
|
76
|
+
const instance = isFunction(interceptor) ? container.get(interceptor) : isObject(interceptor) && isFunction(interceptor["intercept"]) ? interceptor : null;
|
|
77
|
+
if (isNil(instance)) {
|
|
78
|
+
this.loggerService.error("An error occurred while trying to go through interceptors.");
|
|
79
|
+
throw new Error(ErrorMessage.InvalidInterceptorDefinition);
|
|
80
|
+
}
|
|
81
|
+
await instance.intercept.call(instance, executionContext, callHandler);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async goTroughPipes(value, pipes, argumentMetadata, container) {
|
|
85
|
+
for (const pipe of pipes) {
|
|
86
|
+
const instance = isFunction(pipe) ? container.get(pipe) : isObject(pipe) ? pipe : null;
|
|
87
|
+
if (isNil(instance)) {
|
|
88
|
+
this.loggerService.error("An error occurred while trying to go through pipes.");
|
|
89
|
+
throw new Error(ErrorMessage.InvalidPipeDefinition);
|
|
90
|
+
}
|
|
91
|
+
value = await Promise.resolve(instance.transform.call(instance, value, argumentMetadata));
|
|
92
|
+
}
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
_ts_decorate([
|
|
97
|
+
inject(LOGGER_SERVICE),
|
|
98
|
+
_ts_metadata("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
|
|
99
|
+
], PipelineHandler.prototype, "loggerService", void 0);
|
|
100
|
+
PipelineHandler = _ts_decorate([
|
|
101
|
+
injectable()
|
|
102
|
+
], PipelineHandler);
|
|
103
|
+
|
|
104
|
+
// src/app/controller/controller-flow.handler.ts
|
|
105
|
+
import { inject as inject2, injectable as injectable2 } from "inversify";
|
|
106
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
107
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
108
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
109
|
+
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;
|
|
110
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
111
|
+
}
|
|
112
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
113
|
+
function _ts_metadata2(k, v) {
|
|
114
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
115
|
+
}
|
|
116
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
117
|
+
var ControllerFlowHandler = class {
|
|
118
|
+
static {
|
|
119
|
+
__name(this, "ControllerFlowHandler");
|
|
120
|
+
}
|
|
121
|
+
appEnv;
|
|
122
|
+
pipelineHandler;
|
|
123
|
+
async createArgs(controller, executionContext, metadata, pipes, player) {
|
|
124
|
+
return Promise.all(metadata.params.map(async (param) => {
|
|
125
|
+
const argumentMetadata = {
|
|
126
|
+
type: param.type,
|
|
127
|
+
data: param.data,
|
|
128
|
+
metatype: param.metatype
|
|
129
|
+
};
|
|
130
|
+
if (param.type === "body") {
|
|
131
|
+
return this.pipelineHandler.goTroughPipes(executionContext.request.body, [
|
|
132
|
+
...pipes,
|
|
133
|
+
...param?.pipes ?? []
|
|
134
|
+
], argumentMetadata, controller.owner.container);
|
|
135
|
+
} else if (param.type === "param") {
|
|
136
|
+
if (!isObject(executionContext.request.body)) return void 0;
|
|
137
|
+
return this.pipelineHandler.goTroughPipes(executionContext.request.body[param.data], [
|
|
138
|
+
...pipes,
|
|
139
|
+
...param?.pipes ?? []
|
|
140
|
+
], argumentMetadata, controller.owner.container);
|
|
141
|
+
} else if (param.type === "index") {
|
|
142
|
+
if (!Array.isArray(executionContext.request.body)) return void 0;
|
|
143
|
+
return this.pipelineHandler.goTroughPipes(executionContext.request.body[param.data], [
|
|
144
|
+
...pipes,
|
|
145
|
+
...param?.pipes ?? []
|
|
146
|
+
], argumentMetadata, controller.owner.container);
|
|
147
|
+
} else if (param.type === "request") {
|
|
148
|
+
return executionContext.request;
|
|
149
|
+
} else if (param.type === "custom") {
|
|
150
|
+
return this.pipelineHandler.goTroughPipes(param.factory(param.data, executionContext), [
|
|
151
|
+
...pipes,
|
|
152
|
+
...param?.pipes ?? []
|
|
153
|
+
], argumentMetadata, controller.owner.container);
|
|
154
|
+
} else if (param.type === "player" && this.appEnv === AppEnviroment.Server) {
|
|
155
|
+
return this.pipelineHandler.goTroughPipes(param.data ? player[param.data] : player, [
|
|
156
|
+
...pipes,
|
|
157
|
+
...param?.pipes ?? []
|
|
158
|
+
], argumentMetadata, controller.owner.container);
|
|
159
|
+
}
|
|
160
|
+
return void 0;
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
_ts_decorate2([
|
|
165
|
+
inject2(APP_ENVIROMENT),
|
|
166
|
+
_ts_metadata2("design:type", typeof AppEnviroment === "undefined" ? Object : AppEnviroment)
|
|
167
|
+
], ControllerFlowHandler.prototype, "appEnv", void 0);
|
|
168
|
+
_ts_decorate2([
|
|
169
|
+
inject2(PipelineHandler),
|
|
170
|
+
_ts_metadata2("design:type", typeof PipelineHandler === "undefined" ? Object : PipelineHandler)
|
|
171
|
+
], ControllerFlowHandler.prototype, "pipelineHandler", void 0);
|
|
172
|
+
ControllerFlowHandler = _ts_decorate2([
|
|
173
|
+
injectable2()
|
|
174
|
+
], ControllerFlowHandler);
|
|
175
|
+
|
|
176
|
+
// src/app/controller/controller-event.handler.ts
|
|
177
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
178
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
179
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
180
|
+
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;
|
|
181
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
182
|
+
}
|
|
183
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
184
|
+
function _ts_metadata3(k, v) {
|
|
185
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
186
|
+
}
|
|
187
|
+
__name(_ts_metadata3, "_ts_metadata");
|
|
188
|
+
var ControllerEventHandler = class {
|
|
189
|
+
static {
|
|
190
|
+
__name(this, "ControllerEventHandler");
|
|
191
|
+
}
|
|
192
|
+
appEnv;
|
|
193
|
+
multiplayerService;
|
|
194
|
+
eventService;
|
|
195
|
+
controllerFlowHandler;
|
|
196
|
+
pipelineHandler;
|
|
197
|
+
loggerService;
|
|
198
|
+
createMangoRequest;
|
|
199
|
+
createExecutionContext;
|
|
200
|
+
registerEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event) {
|
|
201
|
+
if (event.type === "on" || event.type === "once") {
|
|
202
|
+
return this.eventService[event.type](event.name, async (body) => {
|
|
203
|
+
await this.handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body);
|
|
204
|
+
});
|
|
205
|
+
} else if (event.type === "onInternal" || event.type === "onceInternal") {
|
|
206
|
+
return this.eventService[`$${event.type}`](event.name, async (...args) => {
|
|
207
|
+
const { player, body } = this.multiplayerService.parseInternalArgs(...args);
|
|
208
|
+
await this.handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body, player);
|
|
209
|
+
});
|
|
210
|
+
} else if (event.type === "onPlayer" || event.type === "oncePlayer") {
|
|
211
|
+
return this.eventService[event.type](event.name, async (player, body) => {
|
|
212
|
+
await this.handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body, player);
|
|
213
|
+
});
|
|
214
|
+
} else if (event.type === "onServer" || event.type === "onceServer") {
|
|
215
|
+
return this.eventService[event.type](event.name, async (body) => {
|
|
216
|
+
await this.handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body);
|
|
217
|
+
});
|
|
218
|
+
} else if (event.type === "onWebView" || event.type === "onceWebView") {
|
|
219
|
+
return this.eventService[event.type](event.webViewId, event.name, async (...args) => {
|
|
220
|
+
const body = this.appEnv === AppEnviroment.Server ? args[1] : args[0];
|
|
221
|
+
const player = this.appEnv === AppEnviroment.Server ? args[0] : void 0;
|
|
222
|
+
await this.handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body, player);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
this.loggerService.error("An error occurred while trying to register event.");
|
|
226
|
+
throw new Error(ErrorMessage.InvalidEventType);
|
|
227
|
+
}
|
|
228
|
+
async handleEvent(guards, interceptors, pipes, mappedErrorFilters, controller, event, body, player) {
|
|
229
|
+
const request = this.createMangoRequest(body, player);
|
|
230
|
+
const executionContext = this.createExecutionContext(ExecutionContextType.Event, controller.metadata.classRef, controller.metadata.classRef.prototype[event.method], request, void 0, event.name);
|
|
231
|
+
try {
|
|
232
|
+
await this.pipelineHandler.goTroughGuards(executionContext, guards, controller.owner.container);
|
|
233
|
+
const args = await this.controllerFlowHandler.createArgs(controller, executionContext, event, pipes, player);
|
|
234
|
+
const controllerMethod = controller.instance[event.method];
|
|
235
|
+
const handle = isAsyncFunction(controllerMethod) ? () => controller.instance[event.method].apply(controller.instance, args) : () => controller.instance[event.method].apply(controller.instance, args);
|
|
236
|
+
const callHandler = {
|
|
237
|
+
handle,
|
|
238
|
+
return: /* @__PURE__ */ __name(() => {
|
|
239
|
+
this.loggerService.error("An error occurred while trying to return a value from an event.");
|
|
240
|
+
throw new Error(ErrorMessage.InvalidReturnInEvent);
|
|
241
|
+
}, "return")
|
|
242
|
+
};
|
|
243
|
+
if (interceptors.length > 0) {
|
|
244
|
+
await this.pipelineHandler.goThroughInterceptors(executionContext, interceptors, controller.owner.container, callHandler);
|
|
245
|
+
} else {
|
|
246
|
+
await callHandler.handle();
|
|
247
|
+
}
|
|
248
|
+
} catch (error) {
|
|
249
|
+
const errorGroup = mappedErrorFilters.find(([errorType]) => isFunction(errorType) && error instanceof errorType || errorType === "MANGO_ANY_ERROR" || error === errorType);
|
|
250
|
+
if (isNil(errorGroup)) return;
|
|
251
|
+
const instance = isFunction(errorGroup[1]) ? controller.owner.container.get(errorGroup[1]) : isObject(errorGroup[1]) && isFunction(errorGroup[1]["catch"]) ? errorGroup[1] : null;
|
|
252
|
+
if (isNil(instance)) {
|
|
253
|
+
this.loggerService.error("An error occurred while trying to go through error filters.");
|
|
254
|
+
throw new Error(ErrorMessage.InvalidErrorFilterDefinition);
|
|
255
|
+
}
|
|
256
|
+
await Promise.resolve(instance.catch.call(instance, error, executionContext));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
_ts_decorate3([
|
|
261
|
+
inject3(APP_ENVIROMENT),
|
|
262
|
+
_ts_metadata3("design:type", typeof AppEnviroment === "undefined" ? Object : AppEnviroment)
|
|
263
|
+
], ControllerEventHandler.prototype, "appEnv", void 0);
|
|
264
|
+
_ts_decorate3([
|
|
265
|
+
inject3(MULTIPLAYER_SERVICE),
|
|
266
|
+
_ts_metadata3("design:type", typeof MultiplayerService === "undefined" ? Object : MultiplayerService)
|
|
267
|
+
], ControllerEventHandler.prototype, "multiplayerService", void 0);
|
|
268
|
+
_ts_decorate3([
|
|
269
|
+
inject3(EVENT_SERVICE),
|
|
270
|
+
_ts_metadata3("design:type", typeof InternalEventService === "undefined" ? Object : InternalEventService)
|
|
271
|
+
], ControllerEventHandler.prototype, "eventService", void 0);
|
|
272
|
+
_ts_decorate3([
|
|
273
|
+
inject3(ControllerFlowHandler),
|
|
274
|
+
_ts_metadata3("design:type", typeof ControllerFlowHandler === "undefined" ? Object : ControllerFlowHandler)
|
|
275
|
+
], ControllerEventHandler.prototype, "controllerFlowHandler", void 0);
|
|
276
|
+
_ts_decorate3([
|
|
277
|
+
inject3(PipelineHandler),
|
|
278
|
+
_ts_metadata3("design:type", typeof PipelineHandler === "undefined" ? Object : PipelineHandler)
|
|
279
|
+
], ControllerEventHandler.prototype, "pipelineHandler", void 0);
|
|
280
|
+
_ts_decorate3([
|
|
281
|
+
inject3(LOGGER_SERVICE),
|
|
282
|
+
_ts_metadata3("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
|
|
283
|
+
], ControllerEventHandler.prototype, "loggerService", void 0);
|
|
284
|
+
_ts_decorate3([
|
|
285
|
+
inject3(MANGO_REQUEST_FACTORY),
|
|
286
|
+
_ts_metadata3("design:type", Function)
|
|
287
|
+
], ControllerEventHandler.prototype, "createMangoRequest", void 0);
|
|
288
|
+
_ts_decorate3([
|
|
289
|
+
inject3(EXECUTION_CONTEXT_FACTORY),
|
|
290
|
+
_ts_metadata3("design:type", Function)
|
|
291
|
+
], ControllerEventHandler.prototype, "createExecutionContext", void 0);
|
|
292
|
+
ControllerEventHandler = _ts_decorate3([
|
|
293
|
+
injectable3()
|
|
294
|
+
], ControllerEventHandler);
|
|
295
|
+
|
|
296
|
+
// src/app/controller/controller-metadata.reader.ts
|
|
297
|
+
import { inject as inject4, injectable as injectable4 } from "inversify";
|
|
298
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
299
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
300
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
301
|
+
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;
|
|
302
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
303
|
+
}
|
|
304
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
305
|
+
function _ts_metadata4(k, v) {
|
|
306
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
307
|
+
}
|
|
308
|
+
__name(_ts_metadata4, "_ts_metadata");
|
|
309
|
+
var ControllerMetadataReader = class {
|
|
310
|
+
static {
|
|
311
|
+
__name(this, "ControllerMetadataReader");
|
|
312
|
+
}
|
|
313
|
+
appEnv;
|
|
314
|
+
loggerService;
|
|
315
|
+
async read(classRef) {
|
|
316
|
+
const options = Reflect.getMetadata(CoreMetadataKey.Controller, classRef) ?? {};
|
|
317
|
+
const events = this.getEvents(classRef);
|
|
318
|
+
const rpcs = this.getRPCs(classRef);
|
|
319
|
+
const timers = this.getTimers(classRef);
|
|
320
|
+
return {
|
|
321
|
+
...options,
|
|
322
|
+
classRef,
|
|
323
|
+
events,
|
|
324
|
+
rpcs,
|
|
325
|
+
...this.getPipeline(classRef),
|
|
326
|
+
timers
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
getEvents(classRef) {
|
|
330
|
+
const events = Reflect.getMetadata(CoreMetadataKey.ControllerEvents, classRef.prototype) ?? [];
|
|
331
|
+
return events.map((event) => {
|
|
332
|
+
return {
|
|
333
|
+
...event,
|
|
334
|
+
params: this.getMethodParams(classRef, event),
|
|
335
|
+
...this.getPipeline(classRef, event.method)
|
|
336
|
+
};
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
getRPCs(classRef) {
|
|
340
|
+
const rpcs = Reflect.getMetadata(CoreMetadataKey.ControllerRPCs, classRef.prototype) ?? [];
|
|
341
|
+
return rpcs.map((rpc) => {
|
|
342
|
+
return {
|
|
343
|
+
...rpc,
|
|
344
|
+
params: this.getMethodParams(classRef, rpc),
|
|
345
|
+
...this.getPipeline(classRef, rpc.method)
|
|
346
|
+
};
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
getMethodParams(classRef, metadata) {
|
|
350
|
+
const params = Reflect.getMetadata(CoreMetadataKey.ControllerParams, classRef.prototype, metadata.method) ?? [];
|
|
351
|
+
params.sort((a, b) => a.index - b.index);
|
|
352
|
+
params.forEach((param, index) => {
|
|
353
|
+
if (param.index !== index) {
|
|
354
|
+
this.loggerService.error("An error occurred while reading controller metadata.");
|
|
355
|
+
throw new Error(ErrorMessage.InvalidParameterDecoratorUsage);
|
|
356
|
+
} else if ((metadata.type === "on" || metadata.type === "onPlayer" || metadata.type === "onInternal" || metadata.type === "onServer" || metadata.type === "onWebView" || metadata.type === "once" || metadata.type === "oncePlayer" || metadata.type === "onceInternal" || metadata.type === "onceServer" || metadata.type === "onceWebView") && param.type === "response") {
|
|
357
|
+
this.loggerService.error("An error occurred while reading controller metadata.");
|
|
358
|
+
throw new Error(ErrorMessage.ResponseDecoratorNotAllowedOnEvents);
|
|
359
|
+
} else if (param.type === "player" && this.appEnv === AppEnviroment.Client) {
|
|
360
|
+
this.loggerService.error("An error occurred while reading controller metadata.");
|
|
361
|
+
throw new Error(ErrorMessage.PlayerDecoratorNotAllowedOnClientEvents);
|
|
362
|
+
} else if (metadata.type === "onPlayerRequest" && this.appEnv === AppEnviroment.Client) {
|
|
363
|
+
this.loggerService.error("An error occurred while reading controller metadata.");
|
|
364
|
+
throw new Error(ErrorMessage.RPCNotAllowedInClient);
|
|
365
|
+
} else if (metadata.type === "onServerRequest" && this.appEnv === AppEnviroment.Server) {
|
|
366
|
+
this.loggerService.error("An error occurred while reading controller metadata.");
|
|
367
|
+
throw new Error(ErrorMessage.RPCNotAllowedInServer);
|
|
368
|
+
} else if ((metadata.type === "onPlayer" || metadata.type === "oncePlayer") && this.appEnv === AppEnviroment.Client) {
|
|
369
|
+
this.loggerService.error("An error occurred while reading controller metadata.");
|
|
370
|
+
throw new Error(ErrorMessage.EventNotAllowedInClient);
|
|
371
|
+
} else if ((metadata.type === "onServer" || metadata.type === "onceServer") && this.appEnv === AppEnviroment.Server) {
|
|
372
|
+
this.loggerService.error("An error occurred while reading controller metadata.");
|
|
373
|
+
throw new Error(ErrorMessage.EventNotAllowedInServer);
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
return params;
|
|
377
|
+
}
|
|
378
|
+
getPipeline(target, method) {
|
|
379
|
+
const guards = Reflect.getMetadata(CoreMetadataKey.Guards, target, method) ?? [];
|
|
380
|
+
const interceptors = Reflect.getMetadata(CoreMetadataKey.Interceptors, target, method) ?? [];
|
|
381
|
+
const pipes = Reflect.getMetadata(CoreMetadataKey.Pipes, target, method) ?? [];
|
|
382
|
+
const errorFilters = Reflect.getMetadata(CoreMetadataKey.ErrorFilters, target, method) ?? [];
|
|
383
|
+
return {
|
|
384
|
+
guards,
|
|
385
|
+
interceptors,
|
|
386
|
+
pipes,
|
|
387
|
+
errorFilters
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
getTimers(classRef) {
|
|
391
|
+
return Reflect.getMetadata(CoreMetadataKey.Timers, classRef.prototype) ?? [];
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
_ts_decorate4([
|
|
395
|
+
inject4(APP_ENVIROMENT),
|
|
396
|
+
_ts_metadata4("design:type", typeof AppEnviroment === "undefined" ? Object : AppEnviroment)
|
|
397
|
+
], ControllerMetadataReader.prototype, "appEnv", void 0);
|
|
398
|
+
_ts_decorate4([
|
|
399
|
+
inject4(LOGGER_SERVICE),
|
|
400
|
+
_ts_metadata4("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
|
|
401
|
+
], ControllerMetadataReader.prototype, "loggerService", void 0);
|
|
402
|
+
ControllerMetadataReader = _ts_decorate4([
|
|
403
|
+
injectable4()
|
|
404
|
+
], ControllerMetadataReader);
|
|
405
|
+
|
|
406
|
+
// src/app/controller/controller-rpc.handler.ts
|
|
407
|
+
import { inject as inject5, injectable as injectable5 } from "inversify";
|
|
408
|
+
function _ts_decorate5(decorators, target, key, desc) {
|
|
409
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
410
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
411
|
+
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;
|
|
412
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
413
|
+
}
|
|
414
|
+
__name(_ts_decorate5, "_ts_decorate");
|
|
415
|
+
function _ts_metadata5(k, v) {
|
|
416
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
417
|
+
}
|
|
418
|
+
__name(_ts_metadata5, "_ts_metadata");
|
|
419
|
+
var ControllerRPCHandler = class {
|
|
420
|
+
static {
|
|
421
|
+
__name(this, "ControllerRPCHandler");
|
|
422
|
+
}
|
|
423
|
+
appEnv;
|
|
424
|
+
rpcService;
|
|
425
|
+
pipelineHandler;
|
|
426
|
+
controllerFlowHandler;
|
|
427
|
+
loggerService;
|
|
428
|
+
createMangoRequest;
|
|
429
|
+
createMangoResponse;
|
|
430
|
+
createExecutionContext;
|
|
431
|
+
async registerRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc) {
|
|
432
|
+
if (rpc.type === "onRequest") {
|
|
433
|
+
return this.rpcService[rpc.type](rpc.name, async (body) => {
|
|
434
|
+
return this.handleRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc, body);
|
|
435
|
+
});
|
|
436
|
+
} else if (rpc.type === "onPlayerRequest") {
|
|
437
|
+
return this.rpcService[rpc.type](rpc.name, async (player, body) => {
|
|
438
|
+
return this.handleRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc, body, player);
|
|
439
|
+
});
|
|
440
|
+
} else if (rpc.type === "onServerRequest") {
|
|
441
|
+
return this.rpcService[rpc.type](rpc.name, async (body) => {
|
|
442
|
+
return this.handleRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc, body);
|
|
443
|
+
});
|
|
444
|
+
} else if (rpc.type === "onWebViewRequest") {
|
|
445
|
+
return this.rpcService[rpc.type](rpc.webViewId, rpc.name, async (...args) => {
|
|
446
|
+
const body = this.appEnv === AppEnviroment.Server ? args[1] : args[0];
|
|
447
|
+
const player = this.appEnv === AppEnviroment.Server ? args[0] : void 0;
|
|
448
|
+
return this.handleRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc, body, player);
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
this.loggerService.error("An error occurred while trying to register RPC.");
|
|
452
|
+
throw new Error(ErrorMessage.InvalidRPCType);
|
|
453
|
+
}
|
|
454
|
+
async handleRPC(guards, interceptors, pipes, mappedErrorFilters, controller, rpc, body, player) {
|
|
455
|
+
return new Promise(async (resolve) => {
|
|
456
|
+
const request = this.createMangoRequest(body, this.appEnv === AppEnviroment.Server && (rpc.type === "onPlayerRequest" || rpc.type === "onWebViewRequest") ? player : void 0);
|
|
457
|
+
const response = this.createMangoResponse();
|
|
458
|
+
response.$onSend((data) => resolve(data));
|
|
459
|
+
response.$onError((error) => resolve(error));
|
|
460
|
+
const executionContext = this.createExecutionContext(ExecutionContextType.RPC, controller.metadata.classRef, controller.metadata.classRef.prototype[rpc.method], request, response, rpc.name);
|
|
461
|
+
try {
|
|
462
|
+
await this.pipelineHandler.goTroughGuards(executionContext, guards, controller.owner.container);
|
|
463
|
+
const args = await this.controllerFlowHandler.createArgs(controller, executionContext, rpc, pipes, player);
|
|
464
|
+
const controllerMethod = controller.instance[rpc.method];
|
|
465
|
+
const handle = isAsyncFunction(controllerMethod) ? (options = {
|
|
466
|
+
send: true
|
|
467
|
+
}) => {
|
|
468
|
+
const result = controller.instance[rpc.method].apply(controller.instance, args);
|
|
469
|
+
if (options.send) {
|
|
470
|
+
response.send(result);
|
|
471
|
+
}
|
|
472
|
+
return result;
|
|
473
|
+
} : async (options = {
|
|
474
|
+
send: true
|
|
475
|
+
}) => {
|
|
476
|
+
const result = await controller.instance[rpc.method].apply(controller.instance, args);
|
|
477
|
+
if (options.send) {
|
|
478
|
+
response.send(result);
|
|
479
|
+
}
|
|
480
|
+
return result;
|
|
481
|
+
};
|
|
482
|
+
const callHandler = {
|
|
483
|
+
handle,
|
|
484
|
+
return: /* @__PURE__ */ __name((value) => response.send(value), "return")
|
|
485
|
+
};
|
|
486
|
+
if (interceptors.length > 0) {
|
|
487
|
+
await this.pipelineHandler.goThroughInterceptors(executionContext, interceptors, controller.owner.container, callHandler);
|
|
488
|
+
} else {
|
|
489
|
+
await callHandler.handle();
|
|
490
|
+
}
|
|
491
|
+
} catch (error) {
|
|
492
|
+
const errorGroup = mappedErrorFilters.find(([errorType]) => isFunction(errorType) && error instanceof errorType || errorType === "MANGO_ANY_ERROR" || error === errorType);
|
|
493
|
+
if (isNil(errorGroup)) return;
|
|
494
|
+
const instance = isFunction(errorGroup[1]) ? controller.owner.container.get(errorGroup[1]) : isObject(errorGroup[1]) && isFunction(errorGroup[1]["catch"]) ? errorGroup[1] : null;
|
|
495
|
+
if (isNil(instance)) {
|
|
496
|
+
return this.loggerService.error(ErrorMessage.InvalidErrorFilterDefinition);
|
|
497
|
+
}
|
|
498
|
+
await Promise.resolve(instance.catch.call(instance, error, executionContext));
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
_ts_decorate5([
|
|
504
|
+
inject5(APP_ENVIROMENT),
|
|
505
|
+
_ts_metadata5("design:type", typeof AppEnviroment === "undefined" ? Object : AppEnviroment)
|
|
506
|
+
], ControllerRPCHandler.prototype, "appEnv", void 0);
|
|
507
|
+
_ts_decorate5([
|
|
508
|
+
inject5(RPC_SERVICE),
|
|
509
|
+
_ts_metadata5("design:type", typeof InternalRPCService === "undefined" ? Object : InternalRPCService)
|
|
510
|
+
], ControllerRPCHandler.prototype, "rpcService", void 0);
|
|
511
|
+
_ts_decorate5([
|
|
512
|
+
inject5(PipelineHandler),
|
|
513
|
+
_ts_metadata5("design:type", typeof PipelineHandler === "undefined" ? Object : PipelineHandler)
|
|
514
|
+
], ControllerRPCHandler.prototype, "pipelineHandler", void 0);
|
|
515
|
+
_ts_decorate5([
|
|
516
|
+
inject5(ControllerFlowHandler),
|
|
517
|
+
_ts_metadata5("design:type", typeof ControllerFlowHandler === "undefined" ? Object : ControllerFlowHandler)
|
|
518
|
+
], ControllerRPCHandler.prototype, "controllerFlowHandler", void 0);
|
|
519
|
+
_ts_decorate5([
|
|
520
|
+
inject5(LOGGER_SERVICE),
|
|
521
|
+
_ts_metadata5("design:type", typeof LoggerService === "undefined" ? Object : LoggerService)
|
|
522
|
+
], ControllerRPCHandler.prototype, "loggerService", void 0);
|
|
523
|
+
_ts_decorate5([
|
|
524
|
+
inject5(MANGO_REQUEST_FACTORY),
|
|
525
|
+
_ts_metadata5("design:type", Function)
|
|
526
|
+
], ControllerRPCHandler.prototype, "createMangoRequest", void 0);
|
|
527
|
+
_ts_decorate5([
|
|
528
|
+
inject5(MANGO_RESPONSE_FACTORY),
|
|
529
|
+
_ts_metadata5("design:type", Function)
|
|
530
|
+
], ControllerRPCHandler.prototype, "createMangoResponse", void 0);
|
|
531
|
+
_ts_decorate5([
|
|
532
|
+
inject5(EXECUTION_CONTEXT_FACTORY),
|
|
533
|
+
_ts_metadata5("design:type", Function)
|
|
534
|
+
], ControllerRPCHandler.prototype, "createExecutionContext", void 0);
|
|
535
|
+
ControllerRPCHandler = _ts_decorate5([
|
|
536
|
+
injectable5()
|
|
537
|
+
], ControllerRPCHandler);
|
|
538
|
+
|
|
539
|
+
// src/app/controller/controller.ts
|
|
540
|
+
import { injectable as injectable6 } from "inversify";
|
|
541
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
542
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
543
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
544
|
+
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;
|
|
545
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
546
|
+
}
|
|
547
|
+
__name(_ts_decorate6, "_ts_decorate");
|
|
548
|
+
var Controller = class {
|
|
549
|
+
static {
|
|
550
|
+
__name(this, "Controller");
|
|
551
|
+
}
|
|
552
|
+
metadata;
|
|
553
|
+
instance;
|
|
554
|
+
owner;
|
|
555
|
+
eventHandlers = [];
|
|
556
|
+
rpcHandlers = [];
|
|
557
|
+
};
|
|
558
|
+
Controller = _ts_decorate6([
|
|
559
|
+
injectable6()
|
|
560
|
+
], Controller);
|
|
561
|
+
|
|
562
|
+
export {
|
|
563
|
+
PipelineHandler,
|
|
564
|
+
ControllerFlowHandler,
|
|
565
|
+
ControllerEventHandler,
|
|
566
|
+
ControllerMetadataReader,
|
|
567
|
+
ControllerRPCHandler,
|
|
568
|
+
Controller
|
|
569
|
+
};
|
|
570
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2FwcC9jb250cm9sbGVyL2NvbnRyb2xsZXItZXZlbnQuaGFuZGxlci50cyIsICIuLi9zcmMvYXBwL2NvbnRyb2xsZXIvcGlwZWxpbmUuaGFuZGxlci50cyIsICIuLi9zcmMvYXBwL2NvbnRyb2xsZXIvY29udHJvbGxlci1mbG93LmhhbmRsZXIudHMiLCAiLi4vc3JjL2FwcC9jb250cm9sbGVyL2NvbnRyb2xsZXItbWV0YWRhdGEucmVhZGVyLnRzIiwgIi4uL3NyYy9hcHAvY29udHJvbGxlci9jb250cm9sbGVyLXJwYy5oYW5kbGVyLnRzIiwgIi4uL3NyYy9hcHAvY29udHJvbGxlci9jb250cm9sbGVyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBpbmplY3QsIGluamVjdGFibGUgfSBmcm9tICdpbnZlcnNpZnknO1xuaW1wb3J0IHR5cGUgeyBFcnJvckZpbHRlciwgR3VhcmQsIEludGVyY2VwdG9yLCBJbnRlcm5hbEV2ZW50U2VydmljZSwgTXVsdGlwbGF5ZXJTZXJ2aWNlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBBUFBfRU5WSVJPTUVOVCwgRVhFQ1VUSU9OX0NPTlRFWFRfRkFDVE9SWSwgTUFOR09fUkVRVUVTVF9GQUNUT1JZLCBNVUxUSVBMQVlFUl9TRVJWSUNFIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IGlzRnVuY3Rpb24sIGlzTmlsLCBpc09iamVjdCB9IGZyb20gJy4uLy4uL3V0aWxzJztcbmltcG9ydCB7IFBpcGVsaW5lSGFuZGxlciB9IGZyb20gJy4vcGlwZWxpbmUuaGFuZGxlcic7XG5pbXBvcnQgdHlwZSB7IEV2ZW50TWV0YWRhdGEgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEVWRU5UX1NFUlZJQ0UsIExPR0dFUl9TRVJWSUNFIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzJztcbmltcG9ydCB0eXBlIHsgQ29udHJvbGxlciB9IGZyb20gJy4vY29udHJvbGxlcic7XG5pbXBvcnQgeyBBcHBFbnZpcm9tZW50LCBFeGVjdXRpb25Db250ZXh0VHlwZSB9IGZyb20gJy4uL2VudW1zJztcbmltcG9ydCB7IEV4ZWN1dGlvbkNvbnRleHRCYXNlLCBNYW5nb1Jlc3BvbnNlQmFzZSwgdHlwZSBNYW5nb1JlcXVlc3RCYXNlIH0gZnJvbSAnLi4vcGlwZWxpbmUnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBDYWxsSGFuZGxlciwgTG9nZ2VyU2VydmljZSwgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgaXNBc3luY0Z1bmN0aW9uIH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgQ29udHJvbGxlckZsb3dIYW5kbGVyIH0gZnJvbSAnLi9jb250cm9sbGVyLWZsb3cuaGFuZGxlcic7XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBDb250cm9sbGVyRXZlbnRIYW5kbGVyIHtcbiAgICBAaW5qZWN0KEFQUF9FTlZJUk9NRU5UKSBwcml2YXRlIHJlYWRvbmx5IGFwcEVudjogQXBwRW52aXJvbWVudDtcbiAgICBAaW5qZWN0KE1VTFRJUExBWUVSX1NFUlZJQ0UpIHByaXZhdGUgcmVhZG9ubHkgbXVsdGlwbGF5ZXJTZXJ2aWNlOiBNdWx0aXBsYXllclNlcnZpY2U7XG4gICAgQGluamVjdChFVkVOVF9TRVJWSUNFKSBwcml2YXRlIHJlYWRvbmx5IGV2ZW50U2VydmljZTogSW50ZXJuYWxFdmVudFNlcnZpY2U7XG4gICAgQGluamVjdChDb250cm9sbGVyRmxvd0hhbmRsZXIpIHByaXZhdGUgcmVhZG9ubHkgY29udHJvbGxlckZsb3dIYW5kbGVyOiBDb250cm9sbGVyRmxvd0hhbmRsZXI7XG4gICAgQGluamVjdChQaXBlbGluZUhhbmRsZXIpIHByaXZhdGUgcmVhZG9ubHkgcGlwZWxpbmVIYW5kbGVyOiBQaXBlbGluZUhhbmRsZXI7XG4gICAgQGluamVjdChMT0dHRVJfU0VSVklDRSkgcHJpdmF0ZSByZWFkb25seSBsb2dnZXJTZXJ2aWNlOiBMb2dnZXJTZXJ2aWNlO1xuICAgIEBpbmplY3QoTUFOR09fUkVRVUVTVF9GQUNUT1JZKSBwcml2YXRlIHJlYWRvbmx5IGNyZWF0ZU1hbmdvUmVxdWVzdDogKGJvZHk6IHVua25vd24sIHBsYXllcj86IFBsYXllck1wKSA9PiBNYW5nb1JlcXVlc3RCYXNlO1xuICAgIEBpbmplY3QoRVhFQ1VUSU9OX0NPTlRFWFRfRkFDVE9SWSkgcHJpdmF0ZSByZWFkb25seSBjcmVhdGVFeGVjdXRpb25Db250ZXh0OiAoXG4gICAgICAgIHR5cGU6IEV4ZWN1dGlvbkNvbnRleHRUeXBlLFxuICAgICAgICBjbGFzc1JlZjogTmV3YWJsZSxcbiAgICAgICAgaGFuZGxlcjogRnVuY3Rpb24sXG4gICAgICAgIHJlcXVlc3Q6IE1hbmdvUmVxdWVzdEJhc2UsXG4gICAgICAgIHJlc3BvbnNlPzogTWFuZ29SZXNwb25zZUJhc2UsXG4gICAgICAgIG5hbWU/OiBzdHJpbmcsXG4gICAgKSA9PiBFeGVjdXRpb25Db250ZXh0QmFzZTtcblxuICAgIHB1YmxpYyByZWdpc3RlckV2ZW50KFxuICAgICAgICBndWFyZHM6IChOZXdhYmxlPEd1YXJkPiB8IEd1YXJkKVtdLFxuICAgICAgICBpbnRlcmNlcHRvcnM6IChOZXdhYmxlPEludGVyY2VwdG9yPiB8IEludGVyY2VwdG9yKVtdLFxuICAgICAgICBwaXBlczogKE5ld2FibGU8UGlwZT4gfCBQaXBlKVtdLFxuICAgICAgICBtYXBwZWRFcnJvckZpbHRlcnM6IFthbnkgfCAnTUFOR09fQU5ZX0VSUk9SJywgTmV3YWJsZTxFcnJvckZpbHRlcj4gfCBFcnJvckZpbHRlcl1bXSxcbiAgICAgICAgY29udHJvbGxlcjogQ29udHJvbGxlcixcbiAgICAgICAgZXZlbnQ6IEV2ZW50TWV0YWRhdGEsXG4gICAgKSB7XG4gICAgICAgIGlmIChldmVudC50eXBlID09PSAnb24nIHx8IGV2ZW50LnR5cGUgPT09ICdvbmNlJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRTZXJ2aWNlW2V2ZW50LnR5cGVdKGV2ZW50Lm5hbWUsIGFzeW5jIChib2R5KSA9PiB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVFdmVudChndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgZXZlbnQsIGJvZHkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gJ29uSW50ZXJuYWwnIHx8IGV2ZW50LnR5cGUgPT09ICdvbmNlSW50ZXJuYWwnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudFNlcnZpY2VbYCQke2V2ZW50LnR5cGV9YF0oZXZlbnQubmFtZSwgYXN5bmMgKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHBsYXllciwgYm9keSB9ID0gdGhpcy5tdWx0aXBsYXllclNlcnZpY2UucGFyc2VJbnRlcm5hbEFyZ3M8UGxheWVyTXA+KC4uLmFyZ3MpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlRXZlbnQoZ3VhcmRzLCBpbnRlcmNlcHRvcnMsIHBpcGVzLCBtYXBwZWRFcnJvckZpbHRlcnMsIGNvbnRyb2xsZXIsIGV2ZW50LCBib2R5LCBwbGF5ZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gJ29uUGxheWVyJyB8fCBldmVudC50eXBlID09PSAnb25jZVBsYXllcicpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50U2VydmljZVtldmVudC50eXBlXShldmVudC5uYW1lLCBhc3luYyAocGxheWVyLCBib2R5KSA9PiB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVFdmVudChndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgZXZlbnQsIGJvZHksIHBsYXllcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSAnb25TZXJ2ZXInIHx8IGV2ZW50LnR5cGUgPT09ICdvbmNlU2VydmVyJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRTZXJ2aWNlW2V2ZW50LnR5cGVdKGV2ZW50Lm5hbWUsIGFzeW5jIChib2R5KSA9PiB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVFdmVudChndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgZXZlbnQsIGJvZHkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gJ29uV2ViVmlldycgfHwgZXZlbnQudHlwZSA9PT0gJ29uY2VXZWJWaWV3Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRTZXJ2aWNlW2V2ZW50LnR5cGVdKGV2ZW50LndlYlZpZXdJZCEsIGV2ZW50Lm5hbWUsIGFzeW5jICguLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBib2R5ID0gdGhpcy5hcHBFbnYgPT09IEFwcEVudmlyb21lbnQuU2VydmVyID8gYXJnc1sxXSA6IGFyZ3NbMF07XG4gICAgICAgICAgICAgICAgY29uc3QgcGxheWVyID0gdGhpcy5hcHBFbnYgPT09IEFwcEVudmlyb21lbnQuU2VydmVyID8gPFBsYXllck1wPmFyZ3NbMF0gOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVFdmVudChndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgZXZlbnQsIGJvZHksIHBsYXllcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIHJlZ2lzdGVyIGV2ZW50LicpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkludmFsaWRFdmVudFR5cGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgaGFuZGxlRXZlbnQoXG4gICAgICAgIGd1YXJkczogKE5ld2FibGU8R3VhcmQ+IHwgR3VhcmQpW10sXG4gICAgICAgIGludGVyY2VwdG9yczogKE5ld2FibGU8SW50ZXJjZXB0b3I+IHwgSW50ZXJjZXB0b3IpW10sXG4gICAgICAgIHBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10sXG4gICAgICAgIG1hcHBlZEVycm9yRmlsdGVyczogW2FueSB8ICdNQU5HT19BTllfRVJST1InLCBOZXdhYmxlPEVycm9yRmlsdGVyPiB8IEVycm9yRmlsdGVyXVtdLFxuICAgICAgICBjb250cm9sbGVyOiBDb250cm9sbGVyLFxuICAgICAgICBldmVudDogRXZlbnRNZXRhZGF0YSxcbiAgICAgICAgYm9keTogdW5rbm93bixcbiAgICAgICAgcGxheWVyPzogUGxheWVyTXAsXG4gICAgKSB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLmNyZWF0ZU1hbmdvUmVxdWVzdChib2R5LCBwbGF5ZXIpO1xuICAgICAgICBjb25zdCBleGVjdXRpb25Db250ZXh0ID0gdGhpcy5jcmVhdGVFeGVjdXRpb25Db250ZXh0KFxuICAgICAgICAgICAgRXhlY3V0aW9uQ29udGV4dFR5cGUuRXZlbnQsXG4gICAgICAgICAgICBjb250cm9sbGVyLm1ldGFkYXRhLmNsYXNzUmVmLFxuICAgICAgICAgICAgY29udHJvbGxlci5tZXRhZGF0YS5jbGFzc1JlZi5wcm90b3R5cGVbZXZlbnQubWV0aG9kXSxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICBldmVudC5uYW1lLFxuICAgICAgICApO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBpcGVsaW5lSGFuZGxlci5nb1Ryb3VnaEd1YXJkcyhleGVjdXRpb25Db250ZXh0LCBndWFyZHMsIGNvbnRyb2xsZXIub3duZXIuY29udGFpbmVyKTtcbiAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBhd2FpdCB0aGlzLmNvbnRyb2xsZXJGbG93SGFuZGxlci5jcmVhdGVBcmdzKGNvbnRyb2xsZXIsIGV4ZWN1dGlvbkNvbnRleHQsIGV2ZW50LCBwaXBlcywgcGxheWVyKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRyb2xsZXJNZXRob2QgPSBjb250cm9sbGVyLmluc3RhbmNlW2V2ZW50Lm1ldGhvZF0hO1xuICAgICAgICAgICAgY29uc3QgaGFuZGxlID0gaXNBc3luY0Z1bmN0aW9uKGNvbnRyb2xsZXJNZXRob2QpXG4gICAgICAgICAgICAgICAgPyAoKTogdW5rbm93biA9PiBjb250cm9sbGVyLmluc3RhbmNlW2V2ZW50Lm1ldGhvZF0hLmFwcGx5KGNvbnRyb2xsZXIuaW5zdGFuY2UsIGFyZ3MpXG4gICAgICAgICAgICAgICAgOiAoKTogUHJvbWlzZTx1bmtub3duPiA9PiBjb250cm9sbGVyLmluc3RhbmNlW2V2ZW50Lm1ldGhvZF0hLmFwcGx5KGNvbnRyb2xsZXIuaW5zdGFuY2UsIGFyZ3MpO1xuICAgICAgICAgICAgY29uc3QgY2FsbEhhbmRsZXI6IENhbGxIYW5kbGVyID0ge1xuICAgICAgICAgICAgICAgIGhhbmRsZSxcbiAgICAgICAgICAgICAgICByZXR1cm46ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmVycm9yKCdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSB0cnlpbmcgdG8gcmV0dXJuIGEgdmFsdWUgZnJvbSBhbiBldmVudC4nKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5JbnZhbGlkUmV0dXJuSW5FdmVudCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmIChpbnRlcmNlcHRvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGlwZWxpbmVIYW5kbGVyLmdvVGhyb3VnaEludGVyY2VwdG9ycyhleGVjdXRpb25Db250ZXh0LCBpbnRlcmNlcHRvcnMsIGNvbnRyb2xsZXIub3duZXIuY29udGFpbmVyLCBjYWxsSGFuZGxlcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNhbGxIYW5kbGVyLmhhbmRsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc3QgZXJyb3JHcm91cCA9IG1hcHBlZEVycm9yRmlsdGVycy5maW5kKFxuICAgICAgICAgICAgICAgIChbZXJyb3JUeXBlXSkgPT5cbiAgICAgICAgICAgICAgICAgICAgKGlzRnVuY3Rpb24oZXJyb3JUeXBlKSAmJiBlcnJvciBpbnN0YW5jZW9mIGVycm9yVHlwZSkgfHwgZXJyb3JUeXBlID09PSAnTUFOR09fQU5ZX0VSUk9SJyB8fCBlcnJvciA9PT0gZXJyb3JUeXBlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChpc05pbChlcnJvckdyb3VwKSkgcmV0dXJuO1xuICAgICAgICAgICAgY29uc3QgaW5zdGFuY2UgPSBpc0Z1bmN0aW9uKGVycm9yR3JvdXBbMV0pXG4gICAgICAgICAgICAgICAgPyBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lci5nZXQoZXJyb3JHcm91cFsxXSlcbiAgICAgICAgICAgICAgICA6IGlzT2JqZWN0KGVycm9yR3JvdXBbMV0pICYmIGlzRnVuY3Rpb24oZXJyb3JHcm91cFsxXVsnY2F0Y2gnXSlcbiAgICAgICAgICAgICAgICAgID8gZXJyb3JHcm91cFsxXVxuICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgaWYgKGlzTmlsKGluc3RhbmNlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIGdvIHRocm91Z2ggZXJyb3IgZmlsdGVycy4nKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkludmFsaWRFcnJvckZpbHRlckRlZmluaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5yZXNvbHZlKGluc3RhbmNlLmNhdGNoLmNhbGwoaW5zdGFuY2UsIGVycm9yLCBleGVjdXRpb25Db250ZXh0KSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgaW5qZWN0LCBpbmplY3RhYmxlIH0gZnJvbSAnaW52ZXJzaWZ5JztcbmltcG9ydCB0eXBlIHsgR3VhcmQsIEludGVyY2VwdG9yIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgdHlwZSB7IE5ld2FibGUgfSBmcm9tICcuLi8uLi90eXBlcyc7XG5pbXBvcnQgeyBHdWFyZENhbmNlbEVycm9yLCBHdWFyZEludmFsaWRSZXR1cm5FcnJvciB9IGZyb20gJy4uLy4uL2Vycm9ycyc7XG5pbXBvcnQgeyBpc0Z1bmN0aW9uLCBpc05pbCwgaXNPYmplY3QgfSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgdHlwZSB7IEV4ZWN1dGlvbkNvbnRleHRCYXNlIH0gZnJvbSAnLi4vcGlwZWxpbmUnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBBcmd1bWVudE1ldGFkYXRhLCBDYWxsSGFuZGxlciwgTG9nZ2VyU2VydmljZSwgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTE9HR0VSX1NFUlZJQ0UgfSBmcm9tICcuLi8uLi9jb25zdGFudHMnO1xuaW1wb3J0IHR5cGUgeyBNb2R1bGVDb250YWluZXIgfSBmcm9tICcuLi9tb2R1bGUnO1xuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUGlwZWxpbmVIYW5kbGVyIHtcbiAgICBAaW5qZWN0KExPR0dFUl9TRVJWSUNFKSBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlclNlcnZpY2U6IExvZ2dlclNlcnZpY2U7XG4gICAgLy8gQGluamVjdChHTE9CQUxfQVBQX0NPTlRBSU5FUikgcHJpdmF0ZSByZWFkb25seSBnbG9iYWxDb250YWluZXI6IENvbnRhaW5lcjtcblxuICAgIHB1YmxpYyBhc3luYyBnb1Ryb3VnaEd1YXJkcyhleGVjdXRpb25Db250ZXh0OiBFeGVjdXRpb25Db250ZXh0QmFzZSwgZ3VhcmRzOiAoTmV3YWJsZTxHdWFyZD4gfCBHdWFyZClbXSwgY29udGFpbmVyOiBNb2R1bGVDb250YWluZXIpIHtcbiAgICAgICAgZm9yIChjb25zdCBndWFyZCBvZiBndWFyZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gaXNGdW5jdGlvbihndWFyZCkgPyBjb250YWluZXIuZ2V0KGd1YXJkKSA6IGlzT2JqZWN0KGd1YXJkKSAmJiBpc0Z1bmN0aW9uKGd1YXJkWydjYW5BY3RpdmF0ZSddKSA/IGd1YXJkIDogbnVsbDtcbiAgICAgICAgICAgIGlmIChpc05pbChpbnN0YW5jZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHRyeWluZyB0byBnbyB0aHJvdWdoIGd1YXJkcy4nKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLkludmFsaWRHdWFyZERlZmluaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY2FuQWN0aXZhdGUgPSBhd2FpdCBpbnN0YW5jZS5jYW5BY3RpdmF0ZS5jYWxsKGluc3RhbmNlLCBleGVjdXRpb25Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY2FuQWN0aXZhdGUgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIGdvIHRocm91Z2ggZ3VhcmRzLicpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBHdWFyZEludmFsaWRSZXR1cm5FcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFjYW5BY3RpdmF0ZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBHdWFyZENhbmNlbEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ29UaHJvdWdoSW50ZXJjZXB0b3JzKFxuICAgICAgICBleGVjdXRpb25Db250ZXh0OiBFeGVjdXRpb25Db250ZXh0QmFzZSxcbiAgICAgICAgaW50ZXJjZXB0b3JzOiAoTmV3YWJsZTxJbnRlcmNlcHRvcj4gfCBJbnRlcmNlcHRvcilbXSxcbiAgICAgICAgY29udGFpbmVyOiBNb2R1bGVDb250YWluZXIsXG4gICAgICAgIGNhbGxIYW5kbGVyOiBDYWxsSGFuZGxlcixcbiAgICApIHtcbiAgICAgICAgZm9yIChjb25zdCBpbnRlcmNlcHRvciBvZiBpbnRlcmNlcHRvcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gaXNGdW5jdGlvbihpbnRlcmNlcHRvcilcbiAgICAgICAgICAgICAgICA/IGNvbnRhaW5lci5nZXQoaW50ZXJjZXB0b3IpXG4gICAgICAgICAgICAgICAgOiBpc09iamVjdChpbnRlcmNlcHRvcikgJiYgaXNGdW5jdGlvbihpbnRlcmNlcHRvclsnaW50ZXJjZXB0J10pXG4gICAgICAgICAgICAgICAgICA/IGludGVyY2VwdG9yXG4gICAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICBpZiAoaXNOaWwoaW5zdGFuY2UpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmVycm9yKCdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSB0cnlpbmcgdG8gZ28gdGhyb3VnaCBpbnRlcmNlcHRvcnMuJyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5JbnZhbGlkSW50ZXJjZXB0b3JEZWZpbml0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IGluc3RhbmNlLmludGVyY2VwdC5jYWxsKGluc3RhbmNlLCBleGVjdXRpb25Db250ZXh0LCBjYWxsSGFuZGxlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ29Ucm91Z2hQaXBlcyhcbiAgICAgICAgdmFsdWU6IHVua25vd24sXG4gICAgICAgIHBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10sXG4gICAgICAgIGFyZ3VtZW50TWV0YWRhdGE6IEFyZ3VtZW50TWV0YWRhdGEsXG4gICAgICAgIGNvbnRhaW5lcjogTW9kdWxlQ29udGFpbmVyLFxuICAgICkge1xuICAgICAgICBmb3IgKGNvbnN0IHBpcGUgb2YgcGlwZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gaXNGdW5jdGlvbihwaXBlKSA/IGNvbnRhaW5lci5nZXQocGlwZSkgOiBpc09iamVjdChwaXBlKSA/IHBpcGUgOiBudWxsO1xuICAgICAgICAgICAgaWYgKGlzTmlsKGluc3RhbmNlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgdHJ5aW5nIHRvIGdvIHRocm91Z2ggcGlwZXMuJyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5JbnZhbGlkUGlwZURlZmluaXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFsdWUgPSBhd2FpdCBQcm9taXNlLnJlc29sdmUoaW5zdGFuY2UudHJhbnNmb3JtLmNhbGwoaW5zdGFuY2UsIHZhbHVlLCBhcmd1bWVudE1ldGFkYXRhKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxufVxuIiwgImltcG9ydCB7IGluamVjdCwgaW5qZWN0YWJsZSB9IGZyb20gJ2ludmVyc2lmeSc7XG5pbXBvcnQgdHlwZSB7IENvbnRyb2xsZXIgfSBmcm9tICcuL2NvbnRyb2xsZXInO1xuaW1wb3J0IHR5cGUgeyBFeGVjdXRpb25Db250ZXh0QmFzZSB9IGZyb20gJy4uL3BpcGVsaW5lJztcbmltcG9ydCB0eXBlIHsgRXZlbnRNZXRhZGF0YSwgUlBDTWV0YWRhdGEgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB0eXBlIHsgTmV3YWJsZSB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgUGlwZWxpbmVIYW5kbGVyIH0gZnJvbSAnLi9waXBlbGluZS5oYW5kbGVyJztcbmltcG9ydCB7IGlzT2JqZWN0IH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgQXBwRW52aXJvbWVudCB9IGZyb20gJy4uL2VudW1zJztcbmltcG9ydCB7IEFQUF9FTlZJUk9NRU5UIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuQGluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENvbnRyb2xsZXJGbG93SGFuZGxlciB7XG4gICAgQGluamVjdChBUFBfRU5WSVJPTUVOVCkgcHJpdmF0ZSByZWFkb25seSBhcHBFbnY6IEFwcEVudmlyb21lbnQ7XG4gICAgQGluamVjdChQaXBlbGluZUhhbmRsZXIpIHByaXZhdGUgcmVhZG9ubHkgcGlwZWxpbmVIYW5kbGVyOiBQaXBlbGluZUhhbmRsZXI7XG5cbiAgICBwdWJsaWMgYXN5bmMgY3JlYXRlQXJncyhcbiAgICAgICAgY29udHJvbGxlcjogQ29udHJvbGxlcixcbiAgICAgICAgZXhlY3V0aW9uQ29udGV4dDogRXhlY3V0aW9uQ29udGV4dEJhc2UsXG4gICAgICAgIG1ldGFkYXRhOiBSUENNZXRhZGF0YSB8IEV2ZW50TWV0YWRhdGEsXG4gICAgICAgIHBpcGVzOiAoTmV3YWJsZTxQaXBlPiB8IFBpcGUpW10sXG4gICAgICAgIHBsYXllcj86IFBsYXllck1wLFxuICAgICkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBtZXRhZGF0YS5wYXJhbXMubWFwKGFzeW5jIChwYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3VtZW50TWV0YWRhdGEgPSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IHBhcmFtLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHBhcmFtLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIG1ldGF0eXBlOiBwYXJhbS5tZXRhdHlwZSxcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKHBhcmFtLnR5cGUgPT09ICdib2R5Jykge1xuICAgICAgICAgICAgICAgICAgICAvLyBCb2R5XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBpcGVsaW5lSGFuZGxlci5nb1Ryb3VnaFBpcGVzKFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0aW9uQ29udGV4dC5yZXF1ZXN0LmJvZHksXG4gICAgICAgICAgICAgICAgICAgICAgICBbLi4ucGlwZXMsIC4uLihwYXJhbT8ucGlwZXMgPz8gW10pXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50TWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmFtLnR5cGUgPT09ICdwYXJhbScpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFyYW1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc09iamVjdChleGVjdXRpb25Db250ZXh0LnJlcXVlc3QuYm9keSkpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBpcGVsaW5lSGFuZGxlci5nb1Ryb3VnaFBpcGVzKFxuICAgICAgICAgICAgICAgICAgICAgICAgKDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj5leGVjdXRpb25Db250ZXh0LnJlcXVlc3QuYm9keSlbcGFyYW0uZGF0YV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbLi4ucGlwZXMsIC4uLihwYXJhbT8ucGlwZXMgPz8gW10pXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50TWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmFtLnR5cGUgPT09ICdpbmRleCcpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGV4ZWN1dGlvbkNvbnRleHQucmVxdWVzdC5ib2R5KSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGlwZWxpbmVIYW5kbGVyLmdvVHJvdWdoUGlwZXMoXG4gICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRpb25Db250ZXh0LnJlcXVlc3QuYm9keVtwYXJhbS5kYXRhXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFsuLi5waXBlcywgLi4uKHBhcmFtPy5waXBlcyA/PyBbXSldLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIub3duZXIuY29udGFpbmVyLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFyYW0udHlwZSA9PT0gJ3JlcXVlc3QnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBleGVjdXRpb25Db250ZXh0LnJlcXVlc3Q7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJhbS50eXBlID09PSAnY3VzdG9tJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBDdXN0b21cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucGlwZWxpbmVIYW5kbGVyLmdvVHJvdWdoUGlwZXMoXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbS5mYWN0b3J5KHBhcmFtLmRhdGEsIGV4ZWN1dGlvbkNvbnRleHQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgWy4uLnBpcGVzLCAuLi4ocGFyYW0/LnBpcGVzID8/IFtdKV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmd1bWVudE1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5vd25lci5jb250YWluZXIsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJhbS50eXBlID09PSAncGxheWVyJyAmJiB0aGlzLmFwcEVudiA9PT0gQXBwRW52aXJvbWVudC5TZXJ2ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGxheWVyIChTZXJ2ZXIpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBpcGVsaW5lSGFuZGxlci5nb1Ryb3VnaFBpcGVzKFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW0uZGF0YSA/IHBsYXllciFbPGtleW9mIFBsYXllck1wPnBhcmFtLmRhdGFdIDogcGxheWVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgWy4uLnBpcGVzLCAuLi4ocGFyYW0/LnBpcGVzID8/IFtdKV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmd1bWVudE1ldGFkYXRhLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5vd25lci5jb250YWluZXIsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgaW5qZWN0LCBpbmplY3RhYmxlIH0gZnJvbSAnaW52ZXJzaWZ5JztcbmltcG9ydCB0eXBlIHsgR3VhcmQsIEludGVyY2VwdG9yLCBFcnJvckZpbHRlciwgVGltZXJNZXRhZGF0YSB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBDb250cm9sbGVyTWV0YWRhdGEsIEV2ZW50TWV0YWRhdGEsIE1ldGhvZFBhcmFtZXRlciwgUlBDTWV0YWRhdGEgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEFwcEVudmlyb21lbnQsIENvcmVNZXRhZGF0YUtleSB9IGZyb20gJy4uL2VudW1zJztcbmltcG9ydCB7IEFQUF9FTlZJUk9NRU5UIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IEVycm9yTWVzc2FnZSB9IGZyb20gJy4uLy4uL2VudW1zJztcbmltcG9ydCB0eXBlIHsgTG9nZ2VyU2VydmljZSwgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTE9HR0VSX1NFUlZJQ0UgfSBmcm9tICcuLi8uLi9jb25zdGFudHMnO1xuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQ29udHJvbGxlck1ldGFkYXRhUmVhZGVyIHtcbiAgICBAaW5qZWN0KEFQUF9FTlZJUk9NRU5UKSBwcml2YXRlIHJlYWRvbmx5IGFwcEVudjogQXBwRW52aXJvbWVudDtcbiAgICBAaW5qZWN0KExPR0dFUl9TRVJWSUNFKSBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlclNlcnZpY2U6IExvZ2dlclNlcnZpY2U7XG5cbiAgICBwdWJsaWMgYXN5bmMgcmVhZChjbGFzc1JlZjogTmV3YWJsZSkge1xuICAgICAgICBjb25zdCBvcHRpb25zID1cbiAgICAgICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGE8UGljazxDb250cm9sbGVyTWV0YWRhdGEsICdwcmVmaXgnPj4oQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXIsIGNsYXNzUmVmKSA/P1xuICAgICAgICAgICAgPFBpY2s8Q29udHJvbGxlck1ldGFkYXRhLCAncHJlZml4Jz4+e307XG4gICAgICAgIGNvbnN0IGV2ZW50cyA9IHRoaXMuZ2V0RXZlbnRzKGNsYXNzUmVmKTtcbiAgICAgICAgY29uc3QgcnBjcyA9IHRoaXMuZ2V0UlBDcyhjbGFzc1JlZik7XG4gICAgICAgIGNvbnN0IHRpbWVycyA9IHRoaXMuZ2V0VGltZXJzKGNsYXNzUmVmKTtcblxuICAgICAgICByZXR1cm4gPENvbnRyb2xsZXJNZXRhZGF0YT57XG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgY2xhc3NSZWYsXG4gICAgICAgICAgICBldmVudHMsXG4gICAgICAgICAgICBycGNzLFxuICAgICAgICAgICAgLi4udGhpcy5nZXRQaXBlbGluZShjbGFzc1JlZiksXG4gICAgICAgICAgICB0aW1lcnMsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRFdmVudHMoY2xhc3NSZWY6IE5ld2FibGUpIHtcbiAgICAgICAgY29uc3QgZXZlbnRzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxFdmVudE1ldGFkYXRhW10+KENvcmVNZXRhZGF0YUtleS5Db250cm9sbGVyRXZlbnRzLCBjbGFzc1JlZi5wcm90b3R5cGUpID8/IFtdO1xuXG4gICAgICAgIHJldHVybiBldmVudHMubWFwKChldmVudCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIDxFdmVudE1ldGFkYXRhPntcbiAgICAgICAgICAgICAgICAuLi5ldmVudCxcbiAgICAgICAgICAgICAgICBwYXJhbXM6IHRoaXMuZ2V0TWV0aG9kUGFyYW1zKGNsYXNzUmVmLCBldmVudCksXG4gICAgICAgICAgICAgICAgLi4udGhpcy5nZXRQaXBlbGluZShjbGFzc1JlZiwgZXZlbnQubWV0aG9kKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UlBDcyhjbGFzc1JlZjogTmV3YWJsZSkge1xuICAgICAgICBjb25zdCBycGNzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxSUENNZXRhZGF0YVtdPihDb3JlTWV0YWRhdGFLZXkuQ29udHJvbGxlclJQQ3MsIGNsYXNzUmVmLnByb3RvdHlwZSkgPz8gW107XG5cbiAgICAgICAgcmV0dXJuIHJwY3MubWFwKChycGMpID0+IHtcbiAgICAgICAgICAgIHJldHVybiA8UlBDTWV0YWRhdGE+e1xuICAgICAgICAgICAgICAgIC4uLnJwYyxcbiAgICAgICAgICAgICAgICBwYXJhbXM6IHRoaXMuZ2V0TWV0aG9kUGFyYW1zKGNsYXNzUmVmLCBycGMpLFxuICAgICAgICAgICAgICAgIC4uLnRoaXMuZ2V0UGlwZWxpbmUoY2xhc3NSZWYsIHJwYy5tZXRob2QpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRNZXRob2RQYXJhbXMoY2xhc3NSZWY6IE5ld2FibGUsIG1ldGFkYXRhOiBFdmVudE1ldGFkYXRhIHwgUlBDTWV0YWRhdGEpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxNZXRob2RQYXJhbWV0ZXJbXT4oQ29yZU1ldGFkYXRhS2V5LkNvbnRyb2xsZXJQYXJhbXMsIGNsYXNzUmVmLnByb3RvdHlwZSwgbWV0YWRhdGEubWV0aG9kKSA/PyBbXTtcblxuICAgICAgICBwYXJhbXMuc29ydCgoYSwgYikgPT4gYS5pbmRleCAtIGIuaW5kZXgpO1xuICAgICAgICBwYXJhbXMuZm9yRWFjaCgocGFyYW0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBpZiAocGFyYW0uaW5kZXggIT09IGluZGV4KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmVycm9yKCdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSByZWFkaW5nIGNvbnRyb2xsZXIgbWV0YWRhdGEuJyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5JbnZhbGlkUGFyYW1ldGVyRGVjb3JhdG9yVXNhZ2UpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICAobWV0YWRhdGEudHlwZSA9PT0gJ29uJyB8fFxuICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YS50eXBlID09PSAnb25QbGF5ZXInIHx8XG4gICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhLnR5cGUgPT09ICdvbkludGVybmFsJyB8fFxuICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YS50eXBlID09PSAnb25TZXJ2ZXInIHx8XG4gICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhLnR5cGUgPT09ICdvbldlYlZpZXcnIHx8XG4gICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhLnR5cGUgPT09ICdvbmNlJyB8fFxuICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YS50eXBlID09PSAnb25jZVBsYXllcicgfHxcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEudHlwZSA9PT0gJ29uY2VJbnRlcm5hbCcgfHxcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEudHlwZSA9PT0gJ29uY2VTZXJ2ZXInIHx8XG4gICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhLnR5cGUgPT09ICdvbmNlV2ViVmlldycpICYmXG4gICAgICAgICAgICAgICAgcGFyYW0udHlwZSA9PT0gJ3Jlc3BvbnNlJ1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVzcG9uc2VcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHJlYWRpbmcgY29udHJvbGxlciBtZXRhZGF0YS4nKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLlJlc3BvbnNlRGVjb3JhdG9yTm90QWxsb3dlZE9uRXZlbnRzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocGFyYW0udHlwZSA9PT0gJ3BsYXllcicgJiYgdGhpcy5hcHBFbnYgPT09IEFwcEVudmlyb21lbnQuQ2xpZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gUGxheWVyIChDbGllbnQpIC0gTm90IGFsbG93ZWRcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHJlYWRpbmcgY29udHJvbGxlciBtZXRhZGF0YS4nKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLlBsYXllckRlY29yYXRvck5vdEFsbG93ZWRPbkNsaWVudEV2ZW50cyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1ldGFkYXRhLnR5cGUgPT09ICdvblBsYXllclJlcXVlc3QnICYmIHRoaXMuYXBwRW52ID09PSBBcHBFbnZpcm9tZW50LkNsaWVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVhZGluZyBjb250cm9sbGVyIG1ldGFkYXRhLicpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuUlBDTm90QWxsb3dlZEluQ2xpZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobWV0YWRhdGEudHlwZSA9PT0gJ29uU2VydmVyUmVxdWVzdCcgJiYgdGhpcy5hcHBFbnYgPT09IEFwcEVudmlyb21lbnQuU2VydmVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXJTZXJ2aWNlLmVycm9yKCdBbiBlcnJvciBvY2N1cnJlZCB3aGlsZSByZWFkaW5nIGNvbnRyb2xsZXIgbWV0YWRhdGEuJyk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5SUENOb3RBbGxvd2VkSW5TZXJ2ZXIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgobWV0YWRhdGEudHlwZSA9PT0gJ29uUGxheWVyJyB8fCBtZXRhZGF0YS50eXBlID09PSAnb25jZVBsYXllcicpICYmIHRoaXMuYXBwRW52ID09PSBBcHBFbnZpcm9tZW50LkNsaWVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVhZGluZyBjb250cm9sbGVyIG1ldGFkYXRhLicpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuRXZlbnROb3RBbGxvd2VkSW5DbGllbnQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgobWV0YWRhdGEudHlwZSA9PT0gJ29uU2VydmVyJyB8fCBtZXRhZGF0YS50eXBlID09PSAnb25jZVNlcnZlcicpICYmIHRoaXMuYXBwRW52ID09PSBBcHBFbnZpcm9tZW50LlNlcnZlcikge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVhZGluZyBjb250cm9sbGVyIG1ldGFkYXRhLicpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuRXZlbnROb3RBbGxvd2VkSW5TZXJ2ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcGFyYW1zO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UGlwZWxpbmUodGFyZ2V0OiBOZXdhYmxlIHwgb2JqZWN0LCBtZXRob2Q/OiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgZ3VhcmRzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxOZXdhYmxlPEd1YXJkPltdPihDb3JlTWV0YWRhdGFLZXkuR3VhcmRzLCB0YXJnZXQsIG1ldGhvZCkgPz8gW107XG4gICAgICAgIGNvbnN0IGludGVyY2VwdG9ycyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGE8TmV3YWJsZTxJbnRlcmNlcHRvcj5bXT4oQ29yZU1ldGFkYXRhS2V5LkludGVyY2VwdG9ycywgdGFyZ2V0LCBtZXRob2QpID8/IFtdO1xuICAgICAgICBjb25zdCBwaXBlcyA9IFJlZmxlY3QuZ2V0TWV0YWRhdGE8TmV3YWJsZTxQaXBlPltdPihDb3JlTWV0YWRhdGFLZXkuUGlwZXMsIHRhcmdldCwgbWV0aG9kKSA/PyBbXTtcbiAgICAgICAgY29uc3QgZXJyb3JGaWx0ZXJzID0gUmVmbGVjdC5nZXRNZXRhZGF0YTxOZXdhYmxlPEVycm9yRmlsdGVyPltdPihDb3JlTWV0YWRhdGFLZXkuRXJyb3JGaWx0ZXJzLCB0YXJnZXQsIG1ldGhvZCkgPz8gW107XG5cbiAgICAgICAgcmV0dXJuIHsgZ3VhcmRzLCBpbnRlcmNlcHRvcnMsIHBpcGVzLCBlcnJvckZpbHRlcnMgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFRpbWVycyhjbGFzc1JlZjogTmV3YWJsZSkge1xuICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXRNZXRhZGF0YTxUaW1lck1ldGFkYXRhW10+KENvcmVNZXRhZGF0YUtleS5UaW1lcnMsIGNsYXNzUmVmLnByb3RvdHlwZSkgPz8gW107XG4gICAgfVxufVxuIiwgImltcG9ydCB7IGluamVjdCwgaW5qZWN0YWJsZSB9IGZyb20gJ2ludmVyc2lmeSc7XG5pbXBvcnQgdHlwZSB7IEVycm9yRmlsdGVyLCBHdWFyZCwgSW50ZXJjZXB0b3IsIEludGVybmFsUlBDU2VydmljZSB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTE9HR0VSX1NFUlZJQ0UsIFJQQ19TRVJWSUNFIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IEFQUF9FTlZJUk9NRU5ULCBFWEVDVVRJT05fQ09OVEVYVF9GQUNUT1JZLCBNQU5HT19SRVFVRVNUX0ZBQ1RPUlksIE1BTkdPX1JFU1BPTlNFX0ZBQ1RPUlkgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHR5cGUgeyBOZXdhYmxlIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgaXNBc3luY0Z1bmN0aW9uLCBpc0Z1bmN0aW9uLCBpc05pbCwgaXNPYmplY3QgfSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgeyBQaXBlbGluZUhhbmRsZXIgfSBmcm9tICcuL3BpcGVsaW5lLmhhbmRsZXInO1xuaW1wb3J0IHR5cGUgeyBSUENNZXRhZGF0YSB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgQXBwRW52aXJvbWVudCwgRXhlY3V0aW9uQ29udGV4dFR5cGUgfSBmcm9tICcuLi9lbnVtcyc7XG5pbXBvcnQgeyBFeGVjdXRpb25Db250ZXh0QmFzZSwgdHlwZSBNYW5nb1JlcXVlc3RCYXNlLCB0eXBlIE1hbmdvUmVzcG9uc2VCYXNlIH0gZnJvbSAnLi4vcGlwZWxpbmUnO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBDYWxsSGFuZGxlciwgTG9nZ2VyU2VydmljZSwgUGlwZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHR5cGUgeyBDb250cm9sbGVyIH0gZnJvbSAnLi9jb250cm9sbGVyJztcbmltcG9ydCB7IENvbnRyb2xsZXJGbG93SGFuZGxlciB9IGZyb20gJy4vY29udHJvbGxlci1mbG93LmhhbmRsZXInO1xuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQ29udHJvbGxlclJQQ0hhbmRsZXIge1xuICAgIEBpbmplY3QoQVBQX0VOVklST01FTlQpIHByaXZhdGUgcmVhZG9ubHkgYXBwRW52OiBBcHBFbnZpcm9tZW50O1xuICAgIEBpbmplY3QoUlBDX1NFUlZJQ0UpIHByaXZhdGUgcmVhZG9ubHkgcnBjU2VydmljZTogSW50ZXJuYWxSUENTZXJ2aWNlO1xuICAgIEBpbmplY3QoUGlwZWxpbmVIYW5kbGVyKSBwcml2YXRlIHJlYWRvbmx5IHBpcGVsaW5lSGFuZGxlcjogUGlwZWxpbmVIYW5kbGVyO1xuICAgIEBpbmplY3QoQ29udHJvbGxlckZsb3dIYW5kbGVyKSBwcml2YXRlIHJlYWRvbmx5IGNvbnRyb2xsZXJGbG93SGFuZGxlcjogQ29udHJvbGxlckZsb3dIYW5kbGVyO1xuICAgIEBpbmplY3QoTE9HR0VSX1NFUlZJQ0UpIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyU2VydmljZTogTG9nZ2VyU2VydmljZTtcbiAgICBAaW5qZWN0KE1BTkdPX1JFUVVFU1RfRkFDVE9SWSkgcHJpdmF0ZSByZWFkb25seSBjcmVhdGVNYW5nb1JlcXVlc3Q6IChkYXRhOiB1bmtub3duLCBwbGF5ZXI/OiBQbGF5ZXJNcCkgPT4gTWFuZ29SZXF1ZXN0QmFzZTtcbiAgICBAaW5qZWN0KE1BTkdPX1JFU1BPTlNFX0ZBQ1RPUlkpIHByaXZhdGUgcmVhZG9ubHkgY3JlYXRlTWFuZ29SZXNwb25zZTogKCkgPT4gTWFuZ29SZXNwb25zZUJhc2U7XG4gICAgQGluamVjdChFWEVDVVRJT05fQ09OVEVYVF9GQUNUT1JZKSBwcml2YXRlIHJlYWRvbmx5IGNyZWF0ZUV4ZWN1dGlvbkNvbnRleHQ6IChcbiAgICAgICAgdHlwZTogRXhlY3V0aW9uQ29udGV4dFR5cGUsXG4gICAgICAgIGNsYXNzUmVmOiBOZXdhYmxlLFxuICAgICAgICBoYW5kbGVyOiBGdW5jdGlvbixcbiAgICAgICAgcmVxdWVzdDogTWFuZ29SZXF1ZXN0QmFzZSxcbiAgICAgICAgcmVzcG9uc2U6IE1hbmdvUmVzcG9uc2VCYXNlLFxuICAgICAgICBuYW1lOiBzdHJpbmcsXG4gICAgKSA9PiBFeGVjdXRpb25Db250ZXh0QmFzZTtcblxuICAgIHB1YmxpYyBhc3luYyByZWdpc3RlclJQQyhcbiAgICAgICAgZ3VhcmRzOiAoTmV3YWJsZTxHdWFyZD4gfCBHdWFyZClbXSxcbiAgICAgICAgaW50ZXJjZXB0b3JzOiAoTmV3YWJsZTxJbnRlcmNlcHRvcj4gfCBJbnRlcmNlcHRvcilbXSxcbiAgICAgICAgcGlwZXM6IChOZXdhYmxlPFBpcGU+IHwgUGlwZSlbXSxcbiAgICAgICAgbWFwcGVkRXJyb3JGaWx0ZXJzOiBbYW55IHwgJ01BTkdPX0FOWV9FUlJPUicsIE5ld2FibGU8RXJyb3JGaWx0ZXI+IHwgRXJyb3JGaWx0ZXJdW10sXG4gICAgICAgIGNvbnRyb2xsZXI6IENvbnRyb2xsZXIsXG4gICAgICAgIHJwYzogUlBDTWV0YWRhdGEsXG4gICAgKSB7XG4gICAgICAgIGlmIChycGMudHlwZSA9PT0gJ29uUmVxdWVzdCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJwY1NlcnZpY2VbcnBjLnR5cGVdKHJwYy5uYW1lLCBhc3luYyAoYm9keSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJQQyhndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgcnBjLCBib2R5KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHJwYy50eXBlID09PSAnb25QbGF5ZXJSZXF1ZXN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucnBjU2VydmljZVtycGMudHlwZV0ocnBjLm5hbWUsIGFzeW5jIChwbGF5ZXIsIGJvZHkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVSUEMoZ3VhcmRzLCBpbnRlcmNlcHRvcnMsIHBpcGVzLCBtYXBwZWRFcnJvckZpbHRlcnMsIGNvbnRyb2xsZXIsIHJwYywgYm9keSwgcGxheWVyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHJwYy50eXBlID09PSAnb25TZXJ2ZXJSZXF1ZXN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucnBjU2VydmljZVtycGMudHlwZV0ocnBjLm5hbWUsIGFzeW5jIChib2R5KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlUlBDKGd1YXJkcywgaW50ZXJjZXB0b3JzLCBwaXBlcywgbWFwcGVkRXJyb3JGaWx0ZXJzLCBjb250cm9sbGVyLCBycGMsIGJvZHkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocnBjLnR5cGUgPT09ICdvbldlYlZpZXdSZXF1ZXN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucnBjU2VydmljZVtycGMudHlwZV0ocnBjLndlYlZpZXdJZCEsIHJwYy5uYW1lLCBhc3luYyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYm9keSA9IHRoaXMuYXBwRW52ID09PSBBcHBFbnZpcm9tZW50LlNlcnZlciA/IGFyZ3NbMV0gOiBhcmdzWzBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBsYXllciA9IHRoaXMuYXBwRW52ID09PSBBcHBFbnZpcm9tZW50LlNlcnZlciA/IDxQbGF5ZXJNcD5hcmdzWzBdIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJQQyhndWFyZHMsIGludGVyY2VwdG9ycywgcGlwZXMsIG1hcHBlZEVycm9yRmlsdGVycywgY29udHJvbGxlciwgcnBjLCBib2R5LCBwbGF5ZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHRyeWluZyB0byByZWdpc3RlciBSUEMuJyk7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuSW52YWxpZFJQQ1R5cGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgaGFuZGxlUlBDKFxuICAgICAgICBndWFyZHM6IChOZXdhYmxlPEd1YXJkPiB8IEd1YXJkKVtdLFxuICAgICAgICBpbnRlcmNlcHRvcnM6IChOZXdhYmxlPEludGVyY2VwdG9yPiB8IEludGVyY2VwdG9yKVtdLFxuICAgICAgICBwaXBlczogKE5ld2FibGU8UGlwZT4gfCBQaXBlKVtdLFxuICAgICAgICBtYXBwZWRFcnJvckZpbHRlcnM6IFthbnkgfCAnTUFOR09fQU5ZX0VSUk9SJywgTmV3YWJsZTxFcnJvckZpbHRlcj4gfCBFcnJvckZpbHRlcl1bXSxcbiAgICAgICAgY29udHJvbGxlcjogQ29udHJvbGxlcixcbiAgICAgICAgcnBjOiBSUENNZXRhZGF0YSxcbiAgICAgICAgYm9keTogdW5rbm93bixcbiAgICAgICAgcGxheWVyPzogUGxheWVyTXAsXG4gICAgKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHRoaXMuY3JlYXRlTWFuZ29SZXF1ZXN0KFxuICAgICAgICAgICAgICAgIGJvZHksXG4gICAgICAgICAgICAgICAgdGhpcy5hcHBFbnYgPT09IEFwcEVudmlyb21lbnQuU2VydmVyICYmIChycGMudHlwZSA9PT0gJ29uUGxheWVyUmVxdWVzdCcgfHwgcnBjLnR5cGUgPT09ICdvbldlYlZpZXdSZXF1ZXN0JylcbiAgICAgICAgICAgICAgICAgICAgPyBwbGF5ZXJcbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLmNyZWF0ZU1hbmdvUmVzcG9uc2UoKTtcbiAgICAgICAgICAgIHJlc3BvbnNlLiRvblNlbmQoKGRhdGEpID0+IHJlc29sdmUoZGF0YSkpO1xuICAgICAgICAgICAgcmVzcG9uc2UuJG9uRXJyb3IoKGVycm9yKSA9PiByZXNvbHZlKGVycm9yKSk7XG4gICAgICAgICAgICBjb25zdCBleGVjdXRpb25Db250ZXh0ID0gdGhpcy5jcmVhdGVFeGVjdXRpb25Db250ZXh0KFxuICAgICAgICAgICAgICAgIEV4ZWN1dGlvbkNvbnRleHRUeXBlLlJQQyxcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLm1ldGFkYXRhLmNsYXNzUmVmLFxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIubWV0YWRhdGEuY2xhc3NSZWYucHJvdG90eXBlW3JwYy5tZXRob2RdLFxuICAgICAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgICAgICAgICAgcnBjLm5hbWUsXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGlwZWxpbmVIYW5kbGVyLmdvVHJvdWdoR3VhcmRzKGV4ZWN1dGlvbkNvbnRleHQsIGd1YXJkcywgY29udHJvbGxlci5vd25lci5jb250YWluZXIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBhd2FpdCB0aGlzLmNvbnRyb2xsZXJGbG93SGFuZGxlci5jcmVhdGVBcmdzKGNvbnRyb2xsZXIsIGV4ZWN1dGlvbkNvbnRleHQsIHJwYywgcGlwZXMsIHBsYXllcik7XG4gICAgICAgICAgICAgICAgY29uc3QgY29udHJvbGxlck1ldGhvZCA9IGNvbnRyb2xsZXIuaW5zdGFuY2VbcnBjLm1ldGhvZF0hO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZSA9IGlzQXN5bmNGdW5jdGlvbihjb250cm9sbGVyTWV0aG9kKVxuICAgICAgICAgICAgICAgICAgICA/IChvcHRpb25zOiB7IHNlbmQ6IGJvb2xlYW4gfSA9IHsgc2VuZDogdHJ1ZSB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnRyb2xsZXIuaW5zdGFuY2VbcnBjLm1ldGhvZF0hLmFwcGx5KGNvbnRyb2xsZXIuaW5zdGFuY2UsIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zZW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5zZW5kKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDogYXN5bmMgKG9wdGlvbnM6IHsgc2VuZDogYm9vbGVhbiB9ID0geyBzZW5kOiB0cnVlIH0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29udHJvbGxlci5pbnN0YW5jZVtycGMubWV0aG9kXSEuYXBwbHkoY29udHJvbGxlci5pbnN0YW5jZSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNlbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNlbmQocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY29uc3QgY2FsbEhhbmRsZXI6IENhbGxIYW5kbGVyID0ge1xuICAgICAgICAgICAgICAgICAgICBoYW5kbGUsXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjogKHZhbHVlOiB1bmtub3duKSA9PiByZXNwb25zZS5zZW5kKHZhbHVlKSxcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKGludGVyY2VwdG9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGlwZWxpbmVIYW5kbGVyLmdvVGhyb3VnaEludGVyY2VwdG9ycyhcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWN1dGlvbkNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmNlcHRvcnMsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxIYW5kbGVyLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGNhbGxIYW5kbGVyLmhhbmRsZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3JHcm91cCA9IG1hcHBlZEVycm9yRmlsdGVycy5maW5kKFxuICAgICAgICAgICAgICAgICAgICAoW2Vycm9yVHlwZV0pID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAoaXNGdW5jdGlvbihlcnJvclR5cGUpICYmIGVycm9yIGluc3RhbmNlb2YgZXJyb3JUeXBlKSB8fCBlcnJvclR5cGUgPT09ICdNQU5HT19BTllfRVJST1InIHx8IGVycm9yID09PSBlcnJvclR5cGUsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBpZiAoaXNOaWwoZXJyb3JHcm91cCkpIHJldHVybjtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGlzRnVuY3Rpb24oZXJyb3JHcm91cFsxXSlcbiAgICAgICAgICAgICAgICAgICAgPyBjb250cm9sbGVyLm93bmVyLmNvbnRhaW5lci5nZXQoZXJyb3JHcm91cFsxXSlcbiAgICAgICAgICAgICAgICAgICAgOiBpc09iamVjdChlcnJvckdyb3VwWzFdKSAmJiBpc0Z1bmN0aW9uKGVycm9yR3JvdXBbMV1bJ2NhdGNoJ10pXG4gICAgICAgICAgICAgICAgICAgICAgPyBlcnJvckdyb3VwWzFdXG4gICAgICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgICAgIGlmIChpc05pbChpbnN0YW5jZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9nZ2VyU2VydmljZS5lcnJvcihFcnJvck1lc3NhZ2UuSW52YWxpZEVycm9yRmlsdGVyRGVmaW5pdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UucmVzb2x2ZShpbnN0YW5jZS5jYXRjaC5jYWxsKGluc3RhbmNlLCBlcnJvciwgZXhlY3V0aW9uQ29udGV4dCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgaW5qZWN0YWJsZSB9IGZyb20gJ2ludmVyc2lmeSc7XG5pbXBvcnQgdHlwZSB7IENvbnRyb2xsZXJNZXRhZGF0YSwgU2NyaXB0RXZlbnRIYW5kbGVyIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgdHlwZSB7IE1vZHVsZSB9IGZyb20gJy4uL21vZHVsZSc7XG5pbXBvcnQgdHlwZSB7IFNjcmlwdFJQQ0hhbmRsZXIgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcblxuQGluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENvbnRyb2xsZXIge1xuICAgIHB1YmxpYyBtZXRhZGF0YTogQ29udHJvbGxlck1ldGFkYXRhO1xuICAgIHB1YmxpYyBpbnN0YW5jZTogeyBba2V5OiBzdHJpbmddOiBGdW5jdGlvbiB9O1xuICAgIHB1YmxpYyBvd25lcjogTW9kdWxlO1xuICAgIHB1YmxpYyBldmVudEhhbmRsZXJzOiBTY3JpcHRFdmVudEhhbmRsZXJbXSA9IFtdO1xuICAgIHB1YmxpYyBycGNIYW5kbGVyczogU2NyaXB0UlBDSGFuZGxlcltdID0gW107XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLFNBQVNBLFVBQUFBLFNBQVFDLGNBQUFBLG1CQUFrQjs7O0FDQW5DLFNBQVNDLFFBQVFDLGtCQUFrQjs7Ozs7Ozs7Ozs7O0FBWTVCLElBQU1DLGtCQUFOLE1BQU1BO1NBQUFBOzs7RUFDZ0NDOztFQUd6QyxNQUFhQyxlQUFlQyxrQkFBd0NDLFFBQW9DQyxXQUE0QjtBQUNoSSxlQUFXQyxTQUFTRixRQUFRO0FBQ3hCLFlBQU1HLFdBQVdDLFdBQVdGLEtBQUFBLElBQVNELFVBQVVJLElBQUlILEtBQUFBLElB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Ozs7Ozs7QUFNcEIsSUFBTUMsYUFBTixNQUFNQTtTQUFBQTs7O0VBQ0ZDO0VBQ0FDO0VBQ0FDO0VBQ0FDLGdCQUFzQyxDQUFBO0VBQ3RDQyxjQUFrQyxDQUFBO0FBQzdDOzs7OyIsCiAgIm5hbWVzIjogWyJpbmplY3QiLCAiaW5qZWN0YWJsZSIsICJpbmplY3QiLCAiaW5qZWN0YWJsZSIsICJQaXBlbGluZUhhbmRsZXIiLCAibG9nZ2VyU2VydmljZSIsICJnb1Ryb3VnaEd1YXJkcyIsICJleGVjdXRpb25Db250ZXh0IiwgImd1YXJkcyIsICJjb250YWluZXIiLCAiZ3VhcmQiLCAiaW5zdGFuY2UiLCAiaXNGdW5jdGlvbiIsICJnZXQiLCAiaXNPYmplY3QiLCAiaXNOaWwiLCAiZXJyb3IiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkludmFsaWRHdWFyZERlZmluaXRpb24iLCAiY2FuQWN0aXZhdGUiLCAiY2FsbCIsICJHdWFyZEludmFsaWRSZXR1cm5FcnJvciIsICJHdWFyZENhbmNlbEVycm9yIiwgImdvVGhyb3VnaEludGVyY2VwdG9ycyIsICJpbnRlcmNlcHRvcnMiLCAiY2FsbEhhbmRsZXIiLCAiaW50ZXJjZXB0b3IiLCAiSW52YWxpZEludGVyY2VwdG9yRGVmaW5pdGlvbiIsICJpbnRlcmNlcHQiLCAiZ29Ucm91Z2hQaXBlcyIsICJ2YWx1ZSIsICJwaXBlcyIsICJhcmd1bWVudE1ldGFkYXRhIiwgInBpcGUiLCAiSW52YWxpZFBpcGVEZWZpbml0aW9uIiwgIlByb21pc2UiLCAicmVzb2x2ZSIsICJ0cmFuc2Zvcm0iLCAiaW5qZWN0IiwgImluamVjdGFibGUiLCAiQ29udHJvbGxlckZsb3dIYW5kbGVyIiwgImFwcEVudiIsICJwaXBlbGluZUhhbmRsZXIiLCAiY3JlYXRlQXJncyIsICJjb250cm9sbGVyIiwgImV4ZWN1dGlvbkNvbnRleHQiLCAibWV0YWRhdGEiLCAicGlwZXMiLCAicGxheWVyIiwgIlByb21pc2UiLCAiYWxsIiwgInBhcmFtcyIsICJtYXAiLCAicGFyYW0iLCAiYXJndW1lbnRNZXRhZGF0YSIsICJ0eXBlIiwgImRhdGEiLCAibWV0YXR5cGUiLCAiZ29Ucm91Z2hQaXBlcyIsICJyZXF1ZXN0IiwgImJvZHkiLCAib3duZXIiLCAiY29udGFpbmVyIiwgImlzT2JqZWN0IiwgInVuZGVmaW5lZCIsICJBcnJheSIsICJpc0FycmF5IiwgImZhY3RvcnkiLCAiQXBwRW52aXJvbWVudCIsICJTZXJ2ZXIiLCAiQ29udHJvbGxlckV2ZW50SGFuZGxlciIsICJhcHBFbnYiLCAibXVsdGlwbGF5ZXJTZXJ2aWNlIiwgImV2ZW50U2VydmljZSIsICJjb250cm9sbGVyRmxvd0hhbmRsZXIiLCAicGlwZWxpbmVIYW5kbGVyIiwgImxvZ2dlclNlcnZpY2UiLCAiY3JlYXRlTWFuZ29SZXF1ZXN0IiwgImNyZWF0ZUV4ZWN1dGlvbkNvbnRleHQiLCAicmVnaXN0ZXJFdmVudCIsICJndWFyZHMiLCAiaW50ZXJjZXB0b3JzIiwgInBpcGVzIiwgIm1hcHBlZEVycm9yRmlsdGVycyIsICJjb250cm9sbGVyIiwgImV2ZW50IiwgInR5cGUiLCAibmFtZSIsICJib2R5IiwgImhhbmRsZUV2ZW50IiwgImFyZ3MiLCAicGxheWVyIiwgInBhcnNlSW50ZXJuYWxBcmdzIiwgIndlYlZpZXdJZCIsICJBcHBFbnZpcm9tZW50IiwgIlNlcnZlciIsICJ1bmRlZmluZWQiLCAiZXJyb3IiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkludmFsaWRFdmVudFR5cGUiLCAicmVxdWVzdCIsICJleGVjdXRpb25Db250ZXh0IiwgIkV4ZWN1dGlvbkNvbnRleHRUeXBlIiwgIkV2ZW50IiwgIm1ldGFkYXRhIiwgImNsYXNzUmVmIiwgInByb3RvdHlwZSIsICJtZXRob2QiLCAiZ29Ucm91Z2hHdWFyZHMiLCAib3duZXIiLCAiY29udGFpbmVyIiwgImNyZWF0ZUFyZ3MiLCAiY29udHJvbGxlck1ldGhvZCIsICJpbnN0YW5jZSIsICJoYW5kbGUiLCAiaXNBc3luY0Z1bmN0aW9uIiwgImFwcGx5IiwgImNhbGxIYW5kbGVyIiwgInJldHVybiIsICJJbnZhbGlkUmV0dXJuSW5FdmVudCIsICJsZW5ndGgiLCAiZ29UaHJvdWdoSW50ZXJjZXB0b3JzIiwgImVycm9yR3JvdXAiLCAiZmluZCIsICJlcnJvclR5cGUiLCAiaXNGdW5jdGlvbiIsICJpc05pbCIsICJnZXQiLCAiaXNPYmplY3QiLCAiSW52YWxpZEVycm9yRmlsdGVyRGVmaW5pdGlvbiIsICJQcm9taXNlIiwgInJlc29sdmUiLCAiY2F0Y2giLCAiY2FsbCIsICJpbmplY3QiLCAiaW5qZWN0YWJsZSIsICJDb250cm9sbGVyTWV0YWRhdGFSZWFkZXIiLCAiYXBwRW52IiwgImxvZ2dlclNlcnZpY2UiLCAicmVhZCIsICJjbGFzc1JlZiIsICJvcHRpb25zIiwgIlJlZmxlY3QiLCAiZ2V0TWV0YWRhdGEiLCAiQ29yZU1ldGFkYXRhS2V5IiwgIkNvbnRyb2xsZXIiLCAiZXZlbnRzIiwgImdldEV2ZW50cyIsICJycGNzIiwgImdldFJQQ3MiLCAidGltZXJzIiwgImdldFRpbWVycyIsICJnZXRQaXBlbGluZSIsICJDb250cm9sbGVyRXZlbnRzIiwgInByb3RvdHlwZSIsICJtYXAiLCAiZXZlbnQiLCAicGFyYW1zIiwgImdldE1ldGhvZFBhcmFtcyIsICJtZXRob2QiLCAiQ29udHJvbGxlclJQQ3MiLCAicnBjIiwgIm1ldGFkYXRhIiwgIkNvbnRyb2xsZXJQYXJhbXMiLCAic29ydCIsICJhIiwgImIiLCAiaW5kZXgiLCAiZm9yRWFjaCIsICJwYXJhbSIsICJlcnJvciIsICJFcnJvciIsICJFcnJvck1lc3NhZ2UiLCAiSW52YWxpZFBhcmFtZXRlckRlY29yYXRvclVzYWdlIiwgInR5cGUiLCAiUmVzcG9uc2VEZWNvcmF0b3JOb3RBbGxvd2VkT25FdmVudHMiLCAiQXBwRW52aXJvbWVudCIsICJDbGllbnQiLCAiUGxheWVyRGVjb3JhdG9yTm90QWxsb3dlZE9uQ2xpZW50RXZlbnRzIiwgIlJQQ05vdEFsbG93ZWRJbkNsaWVudCIsICJTZXJ2ZXIiLCAiUlBDTm90QWxsb3dlZEluU2VydmVyIiwgIkV2ZW50Tm90QWxsb3dlZEluQ2xpZW50IiwgIkV2ZW50Tm90QWxsb3dlZEluU2VydmVyIiwgInRhcmdldCIsICJndWFyZHMiLCAiR3VhcmRzIiwgImludGVyY2VwdG9ycyIsICJJbnRlcmNlcHRvcnMiLCAicGlwZXMiLCAiUGlwZXMiLCAiZXJyb3JGaWx0ZXJzIiwgIkVycm9yRmlsdGVycyIsICJUaW1lcnMiLCAiaW5qZWN0IiwgImluamVjdGFibGUiLCAiQ29udHJvbGxlclJQQ0hhbmRsZXIiLCAiYXBwRW52IiwgInJwY1NlcnZpY2UiLCAicGlwZWxpbmVIYW5kbGVyIiwgImNvbnRyb2xsZXJGbG93SGFuZGxlciIsICJsb2dnZXJTZXJ2aWNlIiwgImNyZWF0ZU1hbmdvUmVxdWVzdCIsICJjcmVhdGVNYW5nb1Jlc3BvbnNlIiwgImNyZWF0ZUV4ZWN1dGlvbkNvbnRleHQiLCAicmVnaXN0ZXJSUEMiLCAiZ3VhcmRzIiwgImludGVyY2VwdG9ycyIsICJwaXBlcyIsICJtYXBwZWRFcnJvckZpbHRlcnMiLCAiY29udHJvbGxlciIsICJycGMiLCAidHlwZSIsICJuYW1lIiwgImJvZHkiLCAiaGFuZGxlUlBDIiwgInBsYXllciIsICJ3ZWJWaWV3SWQiLCAiYXJncyIsICJBcHBFbnZpcm9tZW50IiwgIlNlcnZlciIsICJ1bmRlZmluZWQiLCAiZXJyb3IiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIkludmFsaWRSUENUeXBlIiwgIlByb21pc2UiLCAicmVzb2x2ZSIsICJyZXF1ZXN0IiwgInJlc3BvbnNlIiwgIiRvblNlbmQiLCAiZGF0YSIsICIkb25FcnJvciIsICJleGVjdXRpb25Db250ZXh0IiwgIkV4ZWN1dGlvbkNvbnRleHRUeXBlIiwgIlJQQyIsICJtZXRhZGF0YSIsICJjbGFzc1JlZiIsICJwcm90b3R5cGUiLCAibWV0aG9kIiwgImdvVHJvdWdoR3VhcmRzIiwgIm93bmVyIiwgImNvbnRhaW5lciIsICJjcmVhdGVBcmdzIiwgImNvbnRyb2xsZXJNZXRob2QiLCAiaW5zdGFuY2UiLCAiaGFuZGxlIiwgImlzQXN5bmNGdW5jdGlvbiIsICJvcHRpb25zIiwgInNlbmQiLCAicmVzdWx0IiwgImFwcGx5IiwgImNhbGxIYW5kbGVyIiwgInJldHVybiIsICJ2YWx1ZSIsICJsZW5ndGgiLCAiZ29UaHJvdWdoSW50ZXJjZXB0b3JzIiwgImVycm9yR3JvdXAiLCAiZmluZCIsICJlcnJvclR5cGUiLCAiaXNGdW5jdGlvbiIsICJpc05pbCIsICJnZXQiLCAiaXNPYmplY3QiLCAiSW52YWxpZEVycm9yRmlsdGVyRGVmaW5pdGlvbiIsICJjYXRjaCIsICJjYWxsIiwgImluamVjdGFibGUiLCAiQ29udHJvbGxlciIsICJtZXRhZGF0YSIsICJpbnN0YW5jZSIsICJvd25lciIsICJldmVudEhhbmRsZXJzIiwgInJwY0hhbmRsZXJzIl0KfQo=
|