@ragemp-mango/webview 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/index.d.ts +72 -0
- package/dist/index.js +535 -0
- package/package.json +40 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Aurėjus Remeika
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## Mango Framework
|
|
2
|
+
|
|
3
|
+
A simple, lightweight, and powerful TypeScript framework for building RageMP servers.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Mango Framework is built with TypeScript and provides a powerful type system for your application.
|
|
8
|
+
- Mango Framework has a wide range of decorators that allow you to easily create and manage your resource flow.
|
|
9
|
+
- Mango Framework is built with modularity in mind, allowing you to organize your application into small, reusable pieces.
|
|
10
|
+
- Mango Framework uses InversifyJS under the hood to provide a powerful dependency injection for your application.
|
|
11
|
+
- Mango Framework uses controllers to group and listen to events/rpcs together under a single class.
|
|
12
|
+
- Mango Framework uses Guards, Interceptors, and Error Filters to create a powerful pipeline that allows you to easily manage every incoming event/rpc.
|
|
13
|
+
|
|
14
|
+
## Documentation
|
|
15
|
+
|
|
16
|
+
[Documentation](https://ragemp-mango.vercel.app)
|
|
17
|
+
|
|
18
|
+
## License
|
|
19
|
+
|
|
20
|
+
[MIT](https://choosealicense.com/licenses/mit/)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { RPCCallOptions, RPCResult, ScriptRPCHandler, LoggerService } from '@ragemp-mango/core/interfaces';
|
|
2
|
+
|
|
3
|
+
interface ScriptEventHandler {
|
|
4
|
+
destroy(): void;
|
|
5
|
+
valid?: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface EventService {
|
|
9
|
+
on<E extends keyof MangoEvents.CustomWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
|
|
10
|
+
on<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
|
|
11
|
+
once<E extends keyof MangoEvents.CustomWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
|
|
12
|
+
once<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
|
|
13
|
+
emit<E extends keyof MangoEvents.CustomWebViewEvent>(eventName: E, body?: Parameters<MangoEvents.CustomWebViewEvent[E]>[0]): void;
|
|
14
|
+
emit<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomWebViewEvent>, body?: unknown): void;
|
|
15
|
+
onPlayer<E extends keyof MangoEvents.CustomClientToWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomClientToWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
|
|
16
|
+
onPlayer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomClientToWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
|
|
17
|
+
oncePlayer<E extends keyof MangoEvents.CustomClientToWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomClientToWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
|
|
18
|
+
oncePlayer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomClientToWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
|
|
19
|
+
emitPlayer<E extends keyof MangoEvents.CustomWebViewToClientEvent>(eventName: E, body?: Parameters<MangoEvents.CustomWebViewToClientEvent[E]>[0]): void;
|
|
20
|
+
emitPlayer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomWebViewToClientEvent>, body?: unknown): void;
|
|
21
|
+
onServer<E extends keyof MangoEvents.CustomServerToWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomServerToWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
|
|
22
|
+
onServer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomServerToWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
|
|
23
|
+
onceServer<E extends keyof MangoEvents.CustomServerToWebViewEvent>(eventName: E, callback: (body: Parameters<MangoEvents.CustomServerToWebViewEvent[E]>[0]) => void | Promise<void>): ScriptEventHandler;
|
|
24
|
+
onceServer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomServerToWebViewEvent>, callback: (body: unknown) => void | Promise<void>): ScriptEventHandler;
|
|
25
|
+
emitServer<E extends keyof MangoEvents.CustomWebViewToServerEvent>(eventName: E, body?: Parameters<MangoEvents.CustomWebViewToServerEvent[E]>[0]): void;
|
|
26
|
+
emitServer<E extends string>(eventName: Exclude<E, keyof MangoEvents.CustomWebViewToServerEvent>, body?: unknown): void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface RPCService {
|
|
30
|
+
call<E extends keyof MangoRPC.CustomWebViewRPC>(rpcName: E, body?: Parameters<MangoRPC.CustomWebViewRPC[E]>[0], options?: RPCCallOptions): Promise<RPCResult<ReturnType<MangoRPC.CustomWebViewRPC[E]>>>;
|
|
31
|
+
call<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomWebViewRPC>, body?: unknown, options?: RPCCallOptions): Promise<RPCResult>;
|
|
32
|
+
onRequest<E extends keyof MangoRPC.CustomWebViewRPC>(rpcName: E, handler: (body: Parameters<MangoRPC.CustomWebViewRPC[E]>[0]) => ReturnType<MangoRPC.CustomWebViewRPC[E]>): ScriptRPCHandler;
|
|
33
|
+
onRequest<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomWebViewRPC>, handler: (body: unknown) => unknown | Promise<unknown>): ScriptRPCHandler;
|
|
34
|
+
callServer<E extends keyof MangoRPC.CustomWebViewToServerRPC>(rpcName: E, body?: Parameters<MangoRPC.CustomWebViewToServerRPC[E]>[0], options?: RPCCallOptions): Promise<RPCResult<ReturnType<MangoRPC.CustomWebViewToServerRPC[E]>>>;
|
|
35
|
+
callServer<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomWebViewToServerRPC>, body?: unknown, options?: RPCCallOptions): Promise<RPCResult>;
|
|
36
|
+
onServerRequest<E extends keyof MangoRPC.CustomServerToWebViewRPC>(rpcName: E, handler: (body: Parameters<MangoRPC.CustomServerToWebViewRPC[E]>[0]) => ReturnType<MangoRPC.CustomServerToWebViewRPC[E]>): ScriptRPCHandler;
|
|
37
|
+
onServerRequest<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomServerToWebViewRPC>, handler: (body: unknown) => unknown | Promise<unknown>): ScriptRPCHandler;
|
|
38
|
+
callPlayer<E extends keyof MangoRPC.CustomWebViewToClientRPC>(rpcName: E, body?: Parameters<MangoRPC.CustomWebViewToClientRPC[E]>[0], options?: RPCCallOptions): Promise<RPCResult<ReturnType<MangoRPC.CustomWebViewToClientRPC[E]>>>;
|
|
39
|
+
callPlayer<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomWebViewToClientRPC>, body?: unknown, options?: RPCCallOptions): Promise<RPCResult>;
|
|
40
|
+
onPlayerRequest<E extends keyof MangoRPC.CustomClientToWebviewRPC>(rpcName: E, handler: (body: Parameters<MangoRPC.CustomClientToWebviewRPC[E]>[0]) => ReturnType<MangoRPC.CustomClientToWebviewRPC[E]>): ScriptRPCHandler;
|
|
41
|
+
onPlayerRequest<E extends string>(rpcName: Exclude<E, keyof MangoRPC.CustomClientToWebviewRPC>, handler: (body: unknown) => unknown | Promise<unknown>): ScriptRPCHandler;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// RageMP WebView type extensions
|
|
45
|
+
// These are empty placeholders - extend MangoEvents and MangoRPC namespaces in your project
|
|
46
|
+
|
|
47
|
+
declare global {
|
|
48
|
+
namespace MangoEvents {
|
|
49
|
+
// Extend these in your project
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
namespace MangoRPC {
|
|
53
|
+
// Extend these in your project
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
declare function initMango(): {
|
|
58
|
+
event: EventService;
|
|
59
|
+
rpc: RPCService;
|
|
60
|
+
logger: LoggerService;
|
|
61
|
+
};
|
|
62
|
+
declare global {
|
|
63
|
+
export interface Window {
|
|
64
|
+
mango: {
|
|
65
|
+
event: EventService;
|
|
66
|
+
rpc: RPCService;
|
|
67
|
+
logger: LoggerService;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { initMango };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/services/webview-logger.service.ts
|
|
5
|
+
var WebViewLoggerService = class {
|
|
6
|
+
static {
|
|
7
|
+
__name(this, "WebViewLoggerService");
|
|
8
|
+
}
|
|
9
|
+
log(...args) {
|
|
10
|
+
console.log(`[\u{1F96D}WebView][Log]`, ...args);
|
|
11
|
+
}
|
|
12
|
+
error(...args) {
|
|
13
|
+
console.error(`[\u{1F96D}WebView][Error]`, ...args);
|
|
14
|
+
}
|
|
15
|
+
warn(...args) {
|
|
16
|
+
console.warn(`[\u{1F96D}WebView][Warn]`, ...args);
|
|
17
|
+
}
|
|
18
|
+
debug(...args) {
|
|
19
|
+
console.debug(`[\u{1F96D}WebView][Debug]`, ...args);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// src/services/webview-event.service.ts
|
|
24
|
+
var WebViewEventService = class {
|
|
25
|
+
static {
|
|
26
|
+
__name(this, "WebViewEventService");
|
|
27
|
+
}
|
|
28
|
+
$localHandlers = /* @__PURE__ */ new Map();
|
|
29
|
+
$remoteHandlers = /* @__PURE__ */ new Map();
|
|
30
|
+
on(eventName, callback) {
|
|
31
|
+
const eventHandler = {
|
|
32
|
+
destroy: /* @__PURE__ */ __name(() => {
|
|
33
|
+
eventHandler.valid = false;
|
|
34
|
+
const handlers = this.$localHandlers.get(eventName);
|
|
35
|
+
handlers?.delete(eventHandler);
|
|
36
|
+
}, "destroy"),
|
|
37
|
+
eventName,
|
|
38
|
+
handler: callback,
|
|
39
|
+
local: true,
|
|
40
|
+
onlyOnce: false,
|
|
41
|
+
remote: false,
|
|
42
|
+
valid: true
|
|
43
|
+
};
|
|
44
|
+
if (!this.$localHandlers.has(eventName)) {
|
|
45
|
+
this.$localHandlers.set(eventName, /* @__PURE__ */ new Set());
|
|
46
|
+
}
|
|
47
|
+
this.$localHandlers.get(eventName).add(eventHandler);
|
|
48
|
+
return eventHandler;
|
|
49
|
+
}
|
|
50
|
+
once(eventName, callback) {
|
|
51
|
+
const eventHandler = {
|
|
52
|
+
destroy: /* @__PURE__ */ __name(() => {
|
|
53
|
+
eventHandler.valid = false;
|
|
54
|
+
const handlers = this.$localHandlers.get(eventName);
|
|
55
|
+
handlers?.delete(eventHandler);
|
|
56
|
+
}, "destroy"),
|
|
57
|
+
eventName,
|
|
58
|
+
handler: callback,
|
|
59
|
+
local: true,
|
|
60
|
+
onlyOnce: true,
|
|
61
|
+
remote: false,
|
|
62
|
+
valid: true
|
|
63
|
+
};
|
|
64
|
+
if (!this.$localHandlers.has(eventName)) {
|
|
65
|
+
this.$localHandlers.set(eventName, /* @__PURE__ */ new Set());
|
|
66
|
+
}
|
|
67
|
+
this.$localHandlers.get(eventName).add(eventHandler);
|
|
68
|
+
return eventHandler;
|
|
69
|
+
}
|
|
70
|
+
emit(eventName, body) {
|
|
71
|
+
const listeners = this.$localHandlers.get(eventName);
|
|
72
|
+
listeners?.forEach((scriptEventHandler) => {
|
|
73
|
+
scriptEventHandler.handler(body);
|
|
74
|
+
if (!scriptEventHandler.onlyOnce) return;
|
|
75
|
+
scriptEventHandler.destroy();
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
onPlayer(eventName, callback) {
|
|
79
|
+
const wrapper = /* @__PURE__ */ __name((...args) => callback(args[0]), "wrapper");
|
|
80
|
+
const eventHandler = {
|
|
81
|
+
destroy: /* @__PURE__ */ __name(() => {
|
|
82
|
+
eventHandler.valid = false;
|
|
83
|
+
const handlers = this.$remoteHandlers.get(eventName);
|
|
84
|
+
handlers?.delete(eventHandler);
|
|
85
|
+
}, "destroy"),
|
|
86
|
+
eventName,
|
|
87
|
+
handler: wrapper,
|
|
88
|
+
local: false,
|
|
89
|
+
onlyOnce: false,
|
|
90
|
+
remote: true,
|
|
91
|
+
valid: true
|
|
92
|
+
};
|
|
93
|
+
if (typeof window.mp !== "undefined") {
|
|
94
|
+
window.mp.events.add(eventName, wrapper);
|
|
95
|
+
}
|
|
96
|
+
if (!this.$remoteHandlers.has(eventName)) {
|
|
97
|
+
this.$remoteHandlers.set(eventName, /* @__PURE__ */ new Set());
|
|
98
|
+
}
|
|
99
|
+
this.$remoteHandlers.get(eventName).add(eventHandler);
|
|
100
|
+
return eventHandler;
|
|
101
|
+
}
|
|
102
|
+
oncePlayer(eventName, callback) {
|
|
103
|
+
const wrapper = /* @__PURE__ */ __name((...args) => {
|
|
104
|
+
callback(args[0]);
|
|
105
|
+
eventHandler.destroy();
|
|
106
|
+
}, "wrapper");
|
|
107
|
+
const eventHandler = {
|
|
108
|
+
destroy: /* @__PURE__ */ __name(() => {
|
|
109
|
+
eventHandler.valid = false;
|
|
110
|
+
const handlers = this.$remoteHandlers.get(eventName);
|
|
111
|
+
handlers?.delete(eventHandler);
|
|
112
|
+
}, "destroy"),
|
|
113
|
+
eventName,
|
|
114
|
+
handler: wrapper,
|
|
115
|
+
local: false,
|
|
116
|
+
onlyOnce: true,
|
|
117
|
+
remote: true,
|
|
118
|
+
valid: true
|
|
119
|
+
};
|
|
120
|
+
if (typeof window.mp !== "undefined") {
|
|
121
|
+
window.mp.events.add(eventName, wrapper);
|
|
122
|
+
}
|
|
123
|
+
if (!this.$remoteHandlers.has(eventName)) {
|
|
124
|
+
this.$remoteHandlers.set(eventName, /* @__PURE__ */ new Set());
|
|
125
|
+
}
|
|
126
|
+
this.$remoteHandlers.get(eventName).add(eventHandler);
|
|
127
|
+
return eventHandler;
|
|
128
|
+
}
|
|
129
|
+
emitPlayer(eventName, body) {
|
|
130
|
+
if (typeof window.mp !== "undefined") {
|
|
131
|
+
window.mp.trigger(eventName, body);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
onServer(eventName, callback) {
|
|
135
|
+
return this.onPlayer(`WEBVIEW::ON_SERVER_${eventName}`, callback);
|
|
136
|
+
}
|
|
137
|
+
onceServer(eventName, callback) {
|
|
138
|
+
return this.oncePlayer(`WEBVIEW::ON_SERVER_${eventName}`, callback);
|
|
139
|
+
}
|
|
140
|
+
emitServer(eventName, body) {
|
|
141
|
+
if (typeof window.mp !== "undefined") {
|
|
142
|
+
window.mp.trigger("WEBVIEW::EMIT_SERVER", {
|
|
143
|
+
eventName,
|
|
144
|
+
payload: body
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// ../core/dist/chunk-DXPVUDXD.js
|
|
151
|
+
var ErrorMessage = /* @__PURE__ */ (function(ErrorMessage2) {
|
|
152
|
+
ErrorMessage2["TooManyRequests"] = "Too many requests.";
|
|
153
|
+
ErrorMessage2["EventNameMustBeString"] = "The event name must be a string.";
|
|
154
|
+
ErrorMessage2["EventNameMustBeUnique"] = "The event name must be unique.";
|
|
155
|
+
ErrorMessage2["EventNotAllowedInClient"] = "The event is not allowed in the client environment.";
|
|
156
|
+
ErrorMessage2["EventNotAllowedInServer"] = "The event is not allowed in the server environment.";
|
|
157
|
+
ErrorMessage2["InvalidEventType"] = "Invalid event type.";
|
|
158
|
+
ErrorMessage2["InvalidInternalEventName"] = "The name of the internal event is invalid.";
|
|
159
|
+
ErrorMessage2["InvalidReturnInEvent"] = "Cannot return a value from an event.";
|
|
160
|
+
ErrorMessage2["RPCNameMustBeString"] = "The RPC name must be a string.";
|
|
161
|
+
ErrorMessage2["RPCNameMustBeUnique"] = "The RPC name must be unique.";
|
|
162
|
+
ErrorMessage2["RPCNotAllowedInClient"] = "The RPC is not allowed in the client environment.";
|
|
163
|
+
ErrorMessage2["RPCNotAllowedInServer"] = "The RPC is not allowed in the server environment.";
|
|
164
|
+
ErrorMessage2["InvalidRPCType"] = "Invalid RPC type.";
|
|
165
|
+
ErrorMessage2["RPCHandlerAlreadyExists"] = "The RPC handler already exists. Please provide a unique name for the RPC.";
|
|
166
|
+
ErrorMessage2["RPCResponseAlreadySent"] = "The RPC response has already been sent.";
|
|
167
|
+
ErrorMessage2["InvalidErrorFilterDefinition"] = "Invalid error filter. Error filters must be a class reference or an object with a catch method.";
|
|
168
|
+
ErrorMessage2["ErrorAlreadyHandledByFilter"] = "The error already points to a filter.";
|
|
169
|
+
ErrorMessage2["ExceptionHandlingConflict"] = "The same exception can only be caught once.";
|
|
170
|
+
ErrorMessage2["AtLeastOneFilterRequired"] = "At least one error filter must be provided.";
|
|
171
|
+
ErrorMessage2["DuplicateErrorFilterDetected"] = "Duplicate error filter found. Ensure that the same filter is not applied more than once.";
|
|
172
|
+
ErrorMessage2["WebViewNotFound"] = "The WebView with the specified id does not exist.";
|
|
173
|
+
ErrorMessage2["WebViewIdMustBeStringOrNumber"] = "The WebView id must be a string or number.";
|
|
174
|
+
ErrorMessage2["InvalidGuardDefinition"] = "Invalid guard. Guards must be a class reference or an object with a canActivate method.";
|
|
175
|
+
ErrorMessage2["AtLeastOneGuardRequired"] = "At least one guard must be provided.";
|
|
176
|
+
ErrorMessage2["InvalidInterceptorDefinition"] = "Invalid interceptor. Interceptors must be a class reference or an object with an intercept method.";
|
|
177
|
+
ErrorMessage2["AtLeastOneInterceptorRequired"] = "At least one interceptor must be provided.";
|
|
178
|
+
ErrorMessage2["InvalidInterceptorReturnValue"] = "The interceptor must return a function.";
|
|
179
|
+
ErrorMessage2["InvalidPipeDefinition"] = "Invalid pipe. Pipes must be a class reference or an object with a transform method.";
|
|
180
|
+
ErrorMessage2["AtLeastOnePipeRequired"] = "At least one pipe must be provided.";
|
|
181
|
+
ErrorMessage2["AppAlreadyLoaded"] = "App is already loaded. Please call the stop method before calling the start method.";
|
|
182
|
+
ErrorMessage2["AppNotLoaded"] = "App is not loaded. Please call the start method before calling the stop method.";
|
|
183
|
+
ErrorMessage2["InvalidInjectionTokenSpecified"] = "The specified injection token is invalid.";
|
|
184
|
+
ErrorMessage2["InjectionTokenNotFound"] = "The injection token could not be found.";
|
|
185
|
+
ErrorMessage2["ParamKeyMustBeString"] = "The param key must be a string.";
|
|
186
|
+
ErrorMessage2["IndexKeyMustBeNumber"] = "The index key must be a number.";
|
|
187
|
+
ErrorMessage2["DuplicateDecoratorUsage"] = "The same decorator can only be used once in the same class.";
|
|
188
|
+
ErrorMessage2["InvalidControllerOptions"] = "Invalid controller options found.";
|
|
189
|
+
ErrorMessage2["InvalidInjectableOptions"] = "Invalid injectable options found.";
|
|
190
|
+
ErrorMessage2["InvalidModuleOptions"] = "Invalid module options found.";
|
|
191
|
+
ErrorMessage2["MultipleDecoratorsOnSingleParameterNotAllowed"] = "Cannot apply multiple decorators to the same parameter.";
|
|
192
|
+
ErrorMessage2["CircularDependencyDetected"] = "Circular dependency detected.";
|
|
193
|
+
ErrorMessage2["InvalidModuleDefinition"] = "The module is invalid.";
|
|
194
|
+
ErrorMessage2["InvalidExportDefinition"] = "The export is invalid.";
|
|
195
|
+
ErrorMessage2["InvalidProviderDefinition"] = "The provider is invalid.";
|
|
196
|
+
ErrorMessage2["InvalidParameterDecoratorUsage"] = "Each parameter must have their its own decorator.";
|
|
197
|
+
ErrorMessage2["ResponseDecoratorNotAllowedOnEvents"] = "The @Response() decorator is not allowed on events.";
|
|
198
|
+
ErrorMessage2["PlayerDecoratorNotAllowedOnClientEvents"] = "The @Player() decorator is not allowed on client events.";
|
|
199
|
+
ErrorMessage2["TimerNameMustBeString"] = "The timer name must be a string.";
|
|
200
|
+
return ErrorMessage2;
|
|
201
|
+
})({});
|
|
202
|
+
var RPCResultStatus = /* @__PURE__ */ (function(RPCResultStatus2) {
|
|
203
|
+
RPCResultStatus2[RPCResultStatus2["Success"] = 1] = "Success";
|
|
204
|
+
RPCResultStatus2[RPCResultStatus2["Timeout"] = 2] = "Timeout";
|
|
205
|
+
RPCResultStatus2[RPCResultStatus2["HandlerNotFound"] = 3] = "HandlerNotFound";
|
|
206
|
+
RPCResultStatus2[RPCResultStatus2["Unknown"] = 4] = "Unknown";
|
|
207
|
+
RPCResultStatus2[RPCResultStatus2["CancelledByGuard"] = 5] = "CancelledByGuard";
|
|
208
|
+
RPCResultStatus2[RPCResultStatus2["InvalidGuardReturn"] = 6] = "InvalidGuardReturn";
|
|
209
|
+
RPCResultStatus2[RPCResultStatus2["TooManyRequests"] = 7] = "TooManyRequests";
|
|
210
|
+
RPCResultStatus2[RPCResultStatus2["PlayerDisconnected"] = 8] = "PlayerDisconnected";
|
|
211
|
+
RPCResultStatus2[RPCResultStatus2["PlayerNotFound"] = 9] = "PlayerNotFound";
|
|
212
|
+
return RPCResultStatus2;
|
|
213
|
+
})({});
|
|
214
|
+
|
|
215
|
+
// ../core/dist/chunk-HK7QTFPA.js
|
|
216
|
+
var RPC_RESULT_TIMEOUT = {
|
|
217
|
+
success: false,
|
|
218
|
+
error: {
|
|
219
|
+
message: "RPC call timed out."
|
|
220
|
+
},
|
|
221
|
+
status: RPCResultStatus.Timeout
|
|
222
|
+
};
|
|
223
|
+
var RPC_RESULT_HANDLER_NOT_FOUND = {
|
|
224
|
+
success: false,
|
|
225
|
+
error: {
|
|
226
|
+
message: "RPC handler not found."
|
|
227
|
+
},
|
|
228
|
+
status: RPCResultStatus.HandlerNotFound
|
|
229
|
+
};
|
|
230
|
+
var RPC_RESULT_UNKNOWN = {
|
|
231
|
+
success: false,
|
|
232
|
+
error: {
|
|
233
|
+
message: "Unknown error."
|
|
234
|
+
},
|
|
235
|
+
status: RPCResultStatus.Unknown
|
|
236
|
+
};
|
|
237
|
+
var RPC_RESULT_PLAYER_DISCONNECTED = {
|
|
238
|
+
success: false,
|
|
239
|
+
error: {
|
|
240
|
+
message: "Player disconnected."
|
|
241
|
+
},
|
|
242
|
+
status: RPCResultStatus.PlayerDisconnected
|
|
243
|
+
};
|
|
244
|
+
var RPC_RESULT_PLAYER_NOT_FOUND = {
|
|
245
|
+
success: false,
|
|
246
|
+
error: {
|
|
247
|
+
message: "Player not found."
|
|
248
|
+
},
|
|
249
|
+
status: RPCResultStatus.PlayerNotFound
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// ../core/dist/chunk-7QVYU63E.js
|
|
253
|
+
var __defProp2 = Object.defineProperty;
|
|
254
|
+
var __name2 = /* @__PURE__ */ __name((target, value) => __defProp2(target, "name", {
|
|
255
|
+
value,
|
|
256
|
+
configurable: true
|
|
257
|
+
}), "__name");
|
|
258
|
+
|
|
259
|
+
// ../core/dist/chunk-E6IQL4S6.js
|
|
260
|
+
function generateRandomId() {
|
|
261
|
+
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
262
|
+
}
|
|
263
|
+
__name(generateRandomId, "generateRandomId");
|
|
264
|
+
__name2(generateRandomId, "generateRandomId");
|
|
265
|
+
var isUndefined = /* @__PURE__ */ __name2((obj) => typeof obj === "undefined", "isUndefined");
|
|
266
|
+
var isNil = /* @__PURE__ */ __name2((val) => isUndefined(val) || val === null, "isNil");
|
|
267
|
+
|
|
268
|
+
// ../core/dist/chunk-TBWHLT75.js
|
|
269
|
+
var EventDestination = /* @__PURE__ */ (function(EventDestination2) {
|
|
270
|
+
EventDestination2["Server"] = "server";
|
|
271
|
+
EventDestination2["Client"] = "client";
|
|
272
|
+
EventDestination2["WebView"] = "webview";
|
|
273
|
+
return EventDestination2;
|
|
274
|
+
})({});
|
|
275
|
+
|
|
276
|
+
// src/services/webview-rpc.service.ts
|
|
277
|
+
var WebViewRPCService = class {
|
|
278
|
+
static {
|
|
279
|
+
__name(this, "WebViewRPCService");
|
|
280
|
+
}
|
|
281
|
+
$eventService;
|
|
282
|
+
$loggerService;
|
|
283
|
+
$TIMEOUT = 2e3;
|
|
284
|
+
$localHandlers = /* @__PURE__ */ new Map();
|
|
285
|
+
$clientHandlers = /* @__PURE__ */ new Map();
|
|
286
|
+
$serverHandlers = /* @__PURE__ */ new Map();
|
|
287
|
+
constructor($eventService, $loggerService) {
|
|
288
|
+
this.$eventService = $eventService;
|
|
289
|
+
this.$loggerService = $loggerService;
|
|
290
|
+
}
|
|
291
|
+
async call(rpcName, body, options = {
|
|
292
|
+
timeout: this.$TIMEOUT
|
|
293
|
+
}) {
|
|
294
|
+
return new Promise(async (resolve) => {
|
|
295
|
+
const rpcHandler = this.$localHandlers.get(rpcName);
|
|
296
|
+
if (isNil(rpcHandler)) {
|
|
297
|
+
resolve(RPC_RESULT_HANDLER_NOT_FOUND);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const timeoutId = setTimeout(() => {
|
|
301
|
+
resolve(RPC_RESULT_TIMEOUT);
|
|
302
|
+
}, options.timeout);
|
|
303
|
+
const result = await rpcHandler.handler(body);
|
|
304
|
+
clearTimeout(timeoutId);
|
|
305
|
+
resolve({
|
|
306
|
+
success: true,
|
|
307
|
+
status: RPCResultStatus.Success,
|
|
308
|
+
body: result,
|
|
309
|
+
error: void 0
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
onRequest(rpcName, handler) {
|
|
314
|
+
if (this.$localHandlers.has(rpcName)) {
|
|
315
|
+
this.$loggerService.error("An error occurred while registering a RPC handler.");
|
|
316
|
+
throw new Error(ErrorMessage.RPCHandlerAlreadyExists);
|
|
317
|
+
}
|
|
318
|
+
const rpcHandler = {
|
|
319
|
+
destroy: /* @__PURE__ */ __name(() => {
|
|
320
|
+
rpcHandler.valid = false;
|
|
321
|
+
this.$localHandlers.delete(rpcName);
|
|
322
|
+
}, "destroy"),
|
|
323
|
+
rpcName,
|
|
324
|
+
handler,
|
|
325
|
+
valid: true
|
|
326
|
+
};
|
|
327
|
+
this.$localHandlers.set(rpcName, rpcHandler);
|
|
328
|
+
return rpcHandler;
|
|
329
|
+
}
|
|
330
|
+
callServer(rpcName, body, options = {
|
|
331
|
+
timeout: this.$TIMEOUT
|
|
332
|
+
}) {
|
|
333
|
+
return this.$handleCall(rpcName, EventDestination.Server, options, body);
|
|
334
|
+
}
|
|
335
|
+
onServerRequest(rpcName, handler) {
|
|
336
|
+
if (this.$serverHandlers.has(rpcName)) {
|
|
337
|
+
this.$loggerService.error("An error occurred while registering a RPC handler.");
|
|
338
|
+
throw new Error(ErrorMessage.RPCHandlerAlreadyExists);
|
|
339
|
+
}
|
|
340
|
+
const rpcHandler = {
|
|
341
|
+
destroy: /* @__PURE__ */ __name(() => {
|
|
342
|
+
rpcHandler.valid = false;
|
|
343
|
+
this.$serverHandlers.delete(rpcName);
|
|
344
|
+
}, "destroy"),
|
|
345
|
+
rpcName,
|
|
346
|
+
handler,
|
|
347
|
+
valid: true
|
|
348
|
+
};
|
|
349
|
+
this.$serverHandlers.set(rpcName, rpcHandler);
|
|
350
|
+
return rpcHandler;
|
|
351
|
+
}
|
|
352
|
+
callPlayer(rpcName, body, options = {
|
|
353
|
+
timeout: this.$TIMEOUT
|
|
354
|
+
}) {
|
|
355
|
+
return this.$handleCall(rpcName, EventDestination.Client, options, body);
|
|
356
|
+
}
|
|
357
|
+
onPlayerRequest(rpcName, handler) {
|
|
358
|
+
if (this.$clientHandlers.has(rpcName)) {
|
|
359
|
+
this.$loggerService.error("An error occurred while registering a RPC listener.");
|
|
360
|
+
throw new Error(ErrorMessage.RPCHandlerAlreadyExists);
|
|
361
|
+
}
|
|
362
|
+
const rpcHandler = {
|
|
363
|
+
destroy: /* @__PURE__ */ __name(() => {
|
|
364
|
+
rpcHandler.valid = false;
|
|
365
|
+
this.$clientHandlers.delete(rpcName);
|
|
366
|
+
}, "destroy"),
|
|
367
|
+
rpcName,
|
|
368
|
+
handler,
|
|
369
|
+
valid: true
|
|
370
|
+
};
|
|
371
|
+
this.$clientHandlers.set(rpcName, rpcHandler);
|
|
372
|
+
return rpcHandler;
|
|
373
|
+
}
|
|
374
|
+
async $handleCall(rpcName, destination, options, body) {
|
|
375
|
+
return new Promise((resolve) => {
|
|
376
|
+
const callId = generateRandomId();
|
|
377
|
+
let timeoutId;
|
|
378
|
+
const onceHandle = /* @__PURE__ */ __name((body2) => {
|
|
379
|
+
clearTimeout(timeoutId);
|
|
380
|
+
resolve(body2);
|
|
381
|
+
}, "onceHandle");
|
|
382
|
+
const scriptEventHandler = destination === EventDestination.Server ? this.$eventService.onceServer(`RPC::RETURN_FROM_SERVER_${callId}`, onceHandle) : this.$eventService.oncePlayer(`RPC::RETURN_FROM_CLIENT_${callId}`, onceHandle);
|
|
383
|
+
const payload = {
|
|
384
|
+
source: EventDestination.WebView,
|
|
385
|
+
destination,
|
|
386
|
+
id: callId,
|
|
387
|
+
rpcName,
|
|
388
|
+
body
|
|
389
|
+
};
|
|
390
|
+
destination === EventDestination.Server ? this.$eventService.emitPlayer("RPC::CALL_SERVER", payload) : this.$eventService.emitPlayer("RPC::CALL_CLIENT", payload);
|
|
391
|
+
timeoutId = setTimeout(() => {
|
|
392
|
+
scriptEventHandler.destroy();
|
|
393
|
+
resolve(RPC_RESULT_TIMEOUT);
|
|
394
|
+
}, options?.timeout ?? this.$TIMEOUT);
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
// ../core/dist/chunk-6YEWPMZJ.js
|
|
400
|
+
var MangoError = class extends Error {
|
|
401
|
+
static {
|
|
402
|
+
__name(this, "MangoError");
|
|
403
|
+
}
|
|
404
|
+
static {
|
|
405
|
+
__name2(this, "MangoError");
|
|
406
|
+
}
|
|
407
|
+
status = RPCResultStatus.Unknown;
|
|
408
|
+
details;
|
|
409
|
+
constructor(message, status, details) {
|
|
410
|
+
super(message);
|
|
411
|
+
this.status = status ?? RPCResultStatus.Unknown;
|
|
412
|
+
this.details = details;
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
var GuardCancelError = class extends MangoError {
|
|
416
|
+
static {
|
|
417
|
+
__name(this, "GuardCancelError");
|
|
418
|
+
}
|
|
419
|
+
static {
|
|
420
|
+
__name2(this, "GuardCancelError");
|
|
421
|
+
}
|
|
422
|
+
constructor() {
|
|
423
|
+
super("Process cancelled by the guard.", RPCResultStatus.CancelledByGuard);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
var GuardInvalidReturnError = class extends MangoError {
|
|
427
|
+
static {
|
|
428
|
+
__name(this, "GuardInvalidReturnError");
|
|
429
|
+
}
|
|
430
|
+
static {
|
|
431
|
+
__name2(this, "GuardInvalidReturnError");
|
|
432
|
+
}
|
|
433
|
+
constructor() {
|
|
434
|
+
super("Guard returned an invalid value. Expected boolean.", RPCResultStatus.InvalidGuardReturn);
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
var TooManyRequests = class extends MangoError {
|
|
438
|
+
static {
|
|
439
|
+
__name(this, "TooManyRequests");
|
|
440
|
+
}
|
|
441
|
+
static {
|
|
442
|
+
__name2(this, "TooManyRequests");
|
|
443
|
+
}
|
|
444
|
+
constructor(message = "Too many requests.") {
|
|
445
|
+
super(message, RPCResultStatus.TooManyRequests);
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
var UnknownError = class extends MangoError {
|
|
449
|
+
static {
|
|
450
|
+
__name(this, "UnknownError");
|
|
451
|
+
}
|
|
452
|
+
static {
|
|
453
|
+
__name2(this, "UnknownError");
|
|
454
|
+
}
|
|
455
|
+
constructor() {
|
|
456
|
+
super("Unknown error.", RPCResultStatus.Unknown);
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
// src/index.ts
|
|
461
|
+
function initMango() {
|
|
462
|
+
if (!isNil(window.mango)) {
|
|
463
|
+
return window.mango;
|
|
464
|
+
}
|
|
465
|
+
const event = new WebViewEventService();
|
|
466
|
+
const logger = new WebViewLoggerService();
|
|
467
|
+
const rpc = new WebViewRPCService(event, logger);
|
|
468
|
+
event.onServer("RPC::CALL_WEBVIEW", async (body) => {
|
|
469
|
+
const id = body.id;
|
|
470
|
+
const name = body.rpcName;
|
|
471
|
+
const payload = body.body;
|
|
472
|
+
const rpcHandler = rpc.$serverHandlers.get(name);
|
|
473
|
+
if (!rpcHandler) {
|
|
474
|
+
event.emitServer(`RPC::RETURN_FROM_WEBVIEW_${id}`, RPC_RESULT_HANDLER_NOT_FOUND);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
try {
|
|
478
|
+
const result = await rpcHandler.handler(payload);
|
|
479
|
+
const rpcResult = {
|
|
480
|
+
success: true,
|
|
481
|
+
status: RPCResultStatus.Success,
|
|
482
|
+
body: result
|
|
483
|
+
};
|
|
484
|
+
event.emitServer(`RPC::RETURN_FROM_WEBVIEW_${id}`, rpcResult);
|
|
485
|
+
} catch (error) {
|
|
486
|
+
if (error instanceof MangoError) {
|
|
487
|
+
const rpcResult = {
|
|
488
|
+
success: false,
|
|
489
|
+
status: error.status,
|
|
490
|
+
error: {
|
|
491
|
+
message: error.message,
|
|
492
|
+
details: error.details
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
event.emitServer(`RPC::RETURN_FROM_WEBVIEW_${id}`, rpcResult);
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
event.emitServer(`RPC::RETURN_FROM_WEBVIEW_${id}`, RPC_RESULT_UNKNOWN);
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
event.onPlayer("RPC::CALL_WEBVIEW", async (body) => {
|
|
502
|
+
const id = body.id;
|
|
503
|
+
const name = body.rpcName;
|
|
504
|
+
const payload = body.body;
|
|
505
|
+
const rpcHandler = rpc.$clientHandlers.get(name);
|
|
506
|
+
if (isNil(rpcHandler)) {
|
|
507
|
+
event.emitPlayer(`RPC::RETURN_FROM_WEBVIEW_${id}`, RPC_RESULT_HANDLER_NOT_FOUND);
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
try {
|
|
511
|
+
const result = await rpcHandler.handler(payload);
|
|
512
|
+
const rpcResult = {
|
|
513
|
+
success: true,
|
|
514
|
+
status: RPCResultStatus.Success,
|
|
515
|
+
body: result
|
|
516
|
+
};
|
|
517
|
+
event.emitPlayer(`RPC::RETURN_FROM_WEBVIEW_${id}`, rpcResult);
|
|
518
|
+
} catch (error) {
|
|
519
|
+
event.emitPlayer(`RPC::RETURN_FROM_WEBVIEW_${id}`, RPC_RESULT_UNKNOWN);
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
const mango = {
|
|
523
|
+
event,
|
|
524
|
+
rpc,
|
|
525
|
+
logger
|
|
526
|
+
};
|
|
527
|
+
window.mango = mango;
|
|
528
|
+
logger.log("WebView initialized");
|
|
529
|
+
return mango;
|
|
530
|
+
}
|
|
531
|
+
__name(initMango, "initMango");
|
|
532
|
+
export {
|
|
533
|
+
initMango
|
|
534
|
+
};
|
|
535
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NlcnZpY2VzL3dlYnZpZXctbG9nZ2VyLnNlcnZpY2UudHMiLCAiLi4vc3JjL3NlcnZpY2VzL3dlYnZpZXctZXZlbnQuc2VydmljZS50cyIsICIuLi8uLi9jb3JlL3NyYy9lbnVtcy9lcnJvci1tZXNzYWdlLmVudW0udHMiLCAiLi4vLi4vY29yZS9zcmMvZW51bXMvaW5qZWN0YWJsZS1zY29wZS5lbnVtLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2VudW1zL3JwYy1yZXN1bHQtc3RhdHVzLmVudW0udHMiLCAiLi4vLi4vY29yZS9zcmMvYXBwL2NvbnN0YW50cy9pbmRleC50cyIsICIuLi8uLi9jb3JlL2Rpc3QvY2h1bmstN1FWWVU2M0UuanMiLCAiLi4vLi4vY29yZS9zcmMvdXRpbHMvZ2VuZXJhdGUtcmFuZG9tLWlkLnV0aWwudHMiLCAiLi4vLi4vY29yZS9zcmMvdXRpbHMvdHlwZS1jaGVjay51dGlsLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2FwcC9lbnVtcy9hcHAtZW52aXJvbWVudC5lbnVtLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2FwcC9lbnVtcy9jb3JlLW1ldGFkYXRhLWtleS5lbnVtLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2FwcC9lbnVtcy9ldmVudC1kZXN0aW5hdGlvbi5lbnVtLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2FwcC9lbnVtcy9leGVjdXRpb24tY29udGV4dC10eXBlLmVudW0udHMiLCAiLi4vLi4vY29yZS9zcmMvYXBwL2VudW1zL21ldGhvZC1wYXJhbS10eXBlLmVudW0udHMiLCAiLi4vc3JjL3NlcnZpY2VzL3dlYnZpZXctcnBjLnNlcnZpY2UudHMiLCAiLi4vLi4vY29yZS9zcmMvZXJyb3JzL21hbmdvLmVycm9yLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2Vycm9ycy9ndWFyZC1jYW5jZWwuZXJyb3IudHMiLCAiLi4vLi4vY29yZS9zcmMvZXJyb3JzL2d1YXJkLWludmFsaWQtcmV0dXJuLmVycm9yLnRzIiwgIi4uLy4uL2NvcmUvc3JjL2Vycm9ycy90b28tbWFueS1yZXF1ZXN0cy5lcnJvci50cyIsICIuLi8uLi9jb3JlL3NyYy9lcnJvcnMvdW5rbm93bi5lcnJvci50cyIsICIuLi9zcmMvaW5kZXgudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB0eXBlIHsgTG9nZ2VyU2VydmljZSB9IGZyb20gJ0ByYWdlbXAtbWFuZ28vY29yZS9pbnRlcmZhY2VzJztcblxuZXhwb3J0IGNsYXNzIFdlYlZpZXdMb2dnZXJTZXJ2aWNlIGltcGxlbWVudHMgTG9nZ2VyU2VydmljZSB7XG4gICAgcHVibGljIGxvZyguLi5hcmdzOiB1bmtub3duW10pIHtcbiAgICAgICAgY29uc29sZS5sb2coYFvwn6WtV2ViVmlld11bTG9nXWAsIC4uLmFyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBlcnJvciguLi5hcmdzOiB1bmtub3duW10pIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgW/Cfpa1XZWJWaWV3XVtFcnJvcl1gLCAuLi5hcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgd2FybiguLi5hcmdzOiB1bmtub3duW10pIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBb8J+lrVdlYlZpZXddW1dhcm5dYCwgLi4uYXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIGRlYnVnKC4uLmFyZ3M6IHVua25vd25bXSkge1xuICAgICAgICBjb25zb2xlLmRlYnVnKGBb8J+lrVdlYlZpZXddW0RlYnVnXWAsIC4uLmFyZ3MpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IEV2ZW50U2VydmljZSwgU2NyaXB0RXZlbnRIYW5kbGVyIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBjbGFzcyBXZWJWaWV3RXZlbnRTZXJ2aWNlIGltcGxlbWVudHMgRXZlbnRTZXJ2aWNlIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5ICRsb2NhbEhhbmRsZXJzOiBNYXA8c3RyaW5nLCBTZXQ8U2NyaXB0RXZlbnRIYW5kbGVyPj4gPSBuZXcgTWFwKCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSAkcmVtb3RlSGFuZGxlcnM6IE1hcDxzdHJpbmcsIFNldDxTY3JpcHRFdmVudEhhbmRsZXI+PiA9IG5ldyBNYXAoKTtcblxuICAgIHB1YmxpYyBvbjxFIGV4dGVuZHMgc3RyaW5nPihcbiAgICAgICAgZXZlbnROYW1lOiBFLFxuICAgICAgICBjYWxsYmFjazogKGJvZHk6IHVua25vd24pID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+LFxuICAgICkge1xuICAgICAgICBjb25zdCBldmVudEhhbmRsZXI6IFNjcmlwdEV2ZW50SGFuZGxlciA9IHtcbiAgICAgICAgICAgIGRlc3Ryb3k6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgZXZlbnRIYW5kbGVyLnZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlcnMgPSB0aGlzLiRsb2NhbEhhbmRsZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzPy5kZWxldGUoZXZlbnRIYW5kbGVyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWUsXG4gICAgICAgICAgICBoYW5kbGVyOiBjYWxsYmFjayxcbiAgICAgICAgICAgIGxvY2FsOiB0cnVlLFxuICAgICAgICAgICAgb25seU9uY2U6IGZhbHNlLFxuICAgICAgICAgICAgcmVtb3RlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghdGhpcy4kbG9jYWxIYW5kbGVycy5oYXMoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgdGhpcy4kbG9jYWxIYW5kbGVycy5zZXQoZXZlbnROYW1lLCBuZXcgU2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuJGxvY2FsSGFuZGxlcnMuZ2V0KGV2ZW50TmFtZSkhLmFkZChldmVudEhhbmRsZXIpO1xuXG4gICAgICAgIHJldHVybiBldmVudEhhbmRsZXI7XG4gICAgfVxuXG4gICAgcHVibGljIG9uY2U8RSBleHRlbmRzIHN0cmluZz4oXG4gICAgICAgIGV2ZW50TmFtZTogRSxcbiAgICAgICAgY2FsbGJhY2s6IChib2R5OiB1bmtub3duKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPixcbiAgICApIHtcbiAgICAgICAgY29uc3QgZXZlbnRIYW5kbGVyID0ge1xuICAgICAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50SGFuZGxlci52YWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJzID0gdGhpcy4kbG9jYWxIYW5kbGVycy5nZXQoZXZlbnROYW1lKTtcbiAgICAgICAgICAgICAgICBoYW5kbGVycz8uZGVsZXRlKGV2ZW50SGFuZGxlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnROYW1lLFxuICAgICAgICAgICAgaGFuZGxlcjogY2FsbGJhY2ssXG4gICAgICAgICAgICBsb2NhbDogdHJ1ZSxcbiAgICAgICAgICAgIG9ubHlPbmNlOiB0cnVlLFxuICAgICAgICAgICAgcmVtb3RlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghdGhpcy4kbG9jYWxIYW5kbGVycy5oYXMoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgdGhpcy4kbG9jYWxIYW5kbGVycy5zZXQoZXZlbnROYW1lLCBuZXcgU2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuJGxvY2FsSGFuZGxlcnMuZ2V0KGV2ZW50TmFtZSkhLmFkZChldmVudEhhbmRsZXIpO1xuXG4gICAgICAgIHJldHVybiA8U2NyaXB0RXZlbnRIYW5kbGVyPmV2ZW50SGFuZGxlcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZW1pdDxFIGV4dGVuZHMgc3RyaW5nPihldmVudE5hbWU6IEUsIGJvZHk/OiB1bmtub3duKSB7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuJGxvY2FsSGFuZGxlcnMuZ2V0KGV2ZW50TmFtZSk7XG4gICAgICAgIGxpc3RlbmVycz8uZm9yRWFjaCgoc2NyaXB0RXZlbnRIYW5kbGVyKSA9PiB7XG4gICAgICAgICAgICBzY3JpcHRFdmVudEhhbmRsZXIuaGFuZGxlcihib2R5KTtcbiAgICAgICAgICAgIGlmICghc2NyaXB0RXZlbnRIYW5kbGVyLm9ubHlPbmNlKSByZXR1cm47XG4gICAgICAgICAgICBzY3JpcHRFdmVudEhhbmRsZXIuZGVzdHJveSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25QbGF5ZXI8RSBleHRlbmRzIHN0cmluZz4oXG4gICAgICAgIGV2ZW50TmFtZTogRSxcbiAgICAgICAgY2FsbGJhY2s6IChib2R5OiB1bmtub3duKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPixcbiAgICApIHtcbiAgICAgICAgY29uc3Qgd3JhcHBlciA9ICguLi5hcmdzOiBhbnlbXSkgPT4gY2FsbGJhY2soYXJnc1swXSk7XG4gICAgICAgIGNvbnN0IGV2ZW50SGFuZGxlcjogU2NyaXB0RXZlbnRIYW5kbGVyID0ge1xuICAgICAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBldmVudEhhbmRsZXIudmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGVycyA9IHRoaXMuJHJlbW90ZUhhbmRsZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzPy5kZWxldGUoZXZlbnRIYW5kbGVyKTtcbiAgICAgICAgICAgICAgICAvLyBJbiBSYWdlTVAgQ0VGLCB3ZSB1c2UgbXAudHJpZ2dlciB0byBjb21tdW5pY2F0ZVxuICAgICAgICAgICAgICAgIC8vIEV2ZW50cyBhcmUgcmVnaXN0ZXJlZCB2aWEgd2luZG93IGV2ZW50IGxpc3RlbmVycyBvciBtcC5ldmVudHNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWUsXG4gICAgICAgICAgICBoYW5kbGVyOiB3cmFwcGVyLFxuICAgICAgICAgICAgbG9jYWw6IGZhbHNlLFxuICAgICAgICAgICAgb25seU9uY2U6IGZhbHNlLFxuICAgICAgICAgICAgcmVtb3RlOiB0cnVlLFxuICAgICAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmFnZU1QIENFRiB1c2VzIHdpbmRvdy1sZXZlbCBldmVudCByZWdpc3RyYXRpb25cbiAgICAgICAgaWYgKHR5cGVvZiAod2luZG93IGFzIGFueSkubXAgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAod2luZG93IGFzIGFueSkubXAuZXZlbnRzLmFkZChldmVudE5hbWUsIHdyYXBwZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLiRyZW1vdGVIYW5kbGVycy5oYXMoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgdGhpcy4kcmVtb3RlSGFuZGxlcnMuc2V0KGV2ZW50TmFtZSwgbmV3IFNldCgpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLiRyZW1vdGVIYW5kbGVycy5nZXQoZXZlbnROYW1lKSEuYWRkKGV2ZW50SGFuZGxlcik7XG5cbiAgICAgICAgcmV0dXJuIGV2ZW50SGFuZGxlcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25jZVBsYXllcjxFIGV4dGVuZHMgc3RyaW5nPihcbiAgICAgICAgZXZlbnROYW1lOiBFLFxuICAgICAgICBjYWxsYmFjazogKGJvZHk6IHVua25vd24pID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+LFxuICAgICkge1xuICAgICAgICBjb25zdCB3cmFwcGVyID0gKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayhhcmdzWzBdKTtcbiAgICAgICAgICAgIGV2ZW50SGFuZGxlci5kZXN0cm95KCk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV2ZW50SGFuZGxlcjogU2NyaXB0RXZlbnRIYW5kbGVyID0ge1xuICAgICAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBldmVudEhhbmRsZXIudmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGVycyA9IHRoaXMuJHJlbW90ZUhhbmRsZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzPy5kZWxldGUoZXZlbnRIYW5kbGVyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWUsXG4gICAgICAgICAgICBoYW5kbGVyOiB3cmFwcGVyLFxuICAgICAgICAgICAgbG9jYWw6IGZhbHNlLFxuICAgICAgICAgICAgb25seU9uY2U6IHRydWUsXG4gICAgICAgICAgICByZW1vdGU6IHRydWUsXG4gICAgICAgICAgICB2YWxpZDogdHJ1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodHlwZW9mICh3aW5kb3cgYXMgYW55KS5tcCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICh3aW5kb3cgYXMgYW55KS5tcC5ldmVudHMuYWRkKGV2ZW50TmFtZSwgd3JhcHBlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuJHJlbW90ZUhhbmRsZXJzLmhhcyhldmVudE5hbWUpKSB7XG4gICAgICAgICAgICB0aGlzLiRyZW1vdGVIYW5kbGVycy5zZXQoZXZlbnROYW1lLCBuZXcgU2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuJHJlbW90ZUhhbmRsZXJzLmdldChldmVudE5hbWUpIS5hZGQoZXZlbnRIYW5kbGVyKTtcblxuICAgICAgICByZXR1cm4gZXZlbnRIYW5kbGVyO1xuICAgIH1cblxuICAgIHB1YmxpYyBlbWl0UGxheWVyPEUgZXh0ZW5kcyBzdHJpbmc+KGV2ZW50TmFtZTogRSwgYm9keT86IHVua25vd24pIHtcbiAgICAgICAgLy8gUmFnZU1QIENFRiB1c2VzIG1wLnRyaWdnZXIgdG8gc2VuZCBldmVudHMgdG8gY2xpZW50XG4gICAgICAgIGlmICh0eXBlb2YgKHdpbmRvdyBhcyBhbnkpLm1wICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgKHdpbmRvdyBhcyBhbnkpLm1wLnRyaWdnZXIoZXZlbnROYW1lLCBib2R5KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBvblNlcnZlcjxFIGV4dGVuZHMgc3RyaW5nPihcbiAgICAgICAgZXZlbnROYW1lOiBFLFxuICAgICAgICBjYWxsYmFjazogKGJvZHk6IHVua25vd24pID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+LFxuICAgICkge1xuICAgICAgICByZXR1cm4gdGhpcy5vblBsYXllcig8c3RyaW5nPmBXRUJWSUVXOjpPTl9TRVJWRVJfJHtldmVudE5hbWV9YCwgPGFueT5jYWxsYmFjayk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uY2VTZXJ2ZXI8RSBleHRlbmRzIHN0cmluZz4oXG4gICAgICAgIGV2ZW50TmFtZTogRSxcbiAgICAgICAgY2FsbGJhY2s6IChib2R5OiB1bmtub3duKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPixcbiAgICApOiBTY3JpcHRFdmVudEhhbmRsZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5vbmNlUGxheWVyKDxzdHJpbmc+YFdFQlZJRVc6Ok9OX1NFUlZFUl8ke2V2ZW50TmFtZX1gLCA8YW55PmNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZW1pdFNlcnZlcjxFIGV4dGVuZHMgc3RyaW5nPihldmVudE5hbWU6IEUsIGJvZHk/OiB1bmtub3duKSB7XG4gICAgICAgIC8vIEluIFJhZ2VNUCwgd2UgZW1pdCB0byBjbGllbnQgd2hpY2ggdGhlbiBmb3J3YXJkcyB0byBzZXJ2ZXJcbiAgICAgICAgaWYgKHR5cGVvZiAod2luZG93IGFzIGFueSkubXAgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAod2luZG93IGFzIGFueSkubXAudHJpZ2dlcignV0VCVklFVzo6RU1JVF9TRVJWRVInLCB7XG4gICAgICAgICAgICAgICAgZXZlbnROYW1lLFxuICAgICAgICAgICAgICAgIHBheWxvYWQ6IGJvZHksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsICJleHBvcnQgZW51bSBFcnJvck1lc3NhZ2Uge1xuICAgIFRvb01hbnlSZXF1ZXN0cyA9ICdUb28gbWFueSByZXF1ZXN0cy4nLFxuXG4gICAgLy8gRXZlbnRzXG4gICAgRXZlbnROYW1lTXVzdEJlU3RyaW5nID0gJ1RoZSBldmVudCBuYW1lIG11c3QgYmUgYSBzdHJpbmcuJyxcbiAgICBFdmVudE5hbWVNdXN0QmVVbmlxdWUgPSAnVGhlIGV2ZW50IG5hbWUgbXVzdCBiZSB1bmlxdWUuJyxcbiAgICBFdmVudE5vdEFsbG93ZWRJbkNsaWVudCA9ICdUaGUgZXZlbnQgaXMgbm90IGFsbG93ZWQgaW4gdGhlIGNsaWVudCBlbnZpcm9ubWVudC4nLFxuICAgIEV2ZW50Tm90QWxsb3dlZEluU2VydmVyID0gJ1RoZSBldmVudCBpcyBub3QgYWxsb3dlZCBpbiB0aGUgc2VydmVyIGVudmlyb25tZW50LicsXG4gICAgSW52YWxpZEV2ZW50VHlwZSA9ICdJbnZhbGlkIGV2ZW50IHR5cGUuJyxcbiAgICBJbnZhbGlkSW50ZXJuYWxFdmVudE5hbWUgPSAnVGhlIG5hbWUgb2YgdGhlIGludGVybmFsIGV2ZW50IGlzIGludmFsaWQuJyxcbiAgICBJbnZhbGlkUmV0dXJuSW5FdmVudCA9ICdDYW5ub3QgcmV0dXJuIGEgdmFsdWUgZnJvbSBhbiBldmVudC4nLFxuXG4gICAgLy8gUlBDXG4gICAgUlBDTmFtZU11c3RCZVN0cmluZyA9ICdUaGUgUlBDIG5hbWUgbXVzdCBiZSBhIHN0cmluZy4nLFxuICAgIFJQQ05hbWVNdXN0QmVVbmlxdWUgPSAnVGhlIFJQQyBuYW1lIG11c3QgYmUgdW5pcXVlLicsXG4gICAgUlBDTm90QWxsb3dlZEluQ2xpZW50ID0gJ1RoZSBSUEMgaXMgbm90IGFsbG93ZWQgaW4gdGhlIGNsaWVudCBlbnZpcm9ubWVudC4nLFxuICAgIFJQQ05vdEFsbG93ZWRJblNlcnZlciA9ICdUaGUgUlBDIGlzIG5vdCBhbGxvd2VkIGluIHRoZSBzZXJ2ZXIgZW52aXJvbm1lbnQuJyxcbiAgICBJbnZhbGlkUlBDVHlwZSA9ICdJbnZhbGlkIFJQQyB0eXBlLicsXG4gICAgUlBDSGFuZGxlckFscmVhZHlFeGlzdHMgPSAnVGhlIFJQQyBoYW5kbGVyIGFscmVhZHkgZXhpc3RzLiBQbGVhc2UgcHJvdmlkZSBhIHVuaXF1ZSBuYW1lIGZvciB0aGUgUlBDLicsXG4gICAgUlBDUmVzcG9uc2VBbHJlYWR5U2VudCA9ICdUaGUgUlBDIHJlc3BvbnNlIGhhcyBhbHJlYWR5IGJlZW4gc2VudC4nLFxuXG4gICAgLy8gRXJyb3IgZmlsdGVyc1xuICAgIEludmFsaWRFcnJvckZpbHRlckRlZmluaXRpb24gPSAnSW52YWxpZCBlcnJvciBmaWx0ZXIuIEVycm9yIGZpbHRlcnMgbXVzdCBiZSBhIGNsYXNzIHJlZmVyZW5jZSBvciBhbiBvYmplY3Qgd2l0aCBhIGNhdGNoIG1ldGhvZC4nLFxuICAgIEVycm9yQWxyZWFkeUhhbmRsZWRCeUZpbHRlciA9ICdUaGUgZXJyb3IgYWxyZWFkeSBwb2ludHMgdG8gYSBmaWx0ZXIuJyxcbiAgICBFeGNlcHRpb25IYW5kbGluZ0NvbmZsaWN0ID0gJ1RoZSBzYW1lIGV4Y2VwdGlvbiBjYW4gb25seSBiZSBjYXVnaHQgb25jZS4nLFxuICAgIEF0TGVhc3RPbmVGaWx0ZXJSZXF1aXJlZCA9ICdBdCBsZWFzdCBvbmUgZXJyb3IgZmlsdGVyIG11c3QgYmUgcHJvdmlkZWQuJyxcbiAgICBEdXBsaWNhdGVFcnJvckZpbHRlckRldGVjdGVkID0gJ0R1cGxpY2F0ZSBlcnJvciBmaWx0ZXIgZm91bmQuIEVuc3VyZSB0aGF0IHRoZSBzYW1lIGZpbHRlciBpcyBub3QgYXBwbGllZCBtb3JlIHRoYW4gb25jZS4nLFxuXG4gICAgLy8gV2ViVmlld1xuICAgIFdlYlZpZXdOb3RGb3VuZCA9ICdUaGUgV2ViVmlldyB3aXRoIHRoZSBzcGVjaWZpZWQgaWQgZG9lcyBub3QgZXhpc3QuJyxcbiAgICBXZWJWaWV3SWRNdXN0QmVTdHJpbmdPck51bWJlciA9ICdUaGUgV2ViVmlldyBpZCBtdXN0IGJlIGEgc3RyaW5nIG9yIG51bWJlci4nLFxuXG4gICAgLy8gR3VhcmRcbiAgICBJbnZhbGlkR3VhcmREZWZpbml0aW9uID0gJ0ludmFsaWQgZ3VhcmQuIEd1YXJkcyBtdXN0IGJlIGEgY2xhc3MgcmVmZXJlbmNlIG9yIGFuIG9iamVjdCB3aXRoIGEgY2FuQWN0aXZhdGUgbWV0aG9kLicsXG4gICAgQXRMZWFzdE9uZUd1YXJkUmVxdWlyZWQgPSAnQXQgbGVhc3Qgb25lIGd1YXJkIG11c3QgYmUgcHJvdmlkZWQuJyxcblxuICAgIC8vIEludGVyY2VwdG9yXG4gICAgSW52YWxpZEludGVyY2VwdG9yRGVmaW5pdGlvbiA9ICdJbnZhbGlkIGludGVyY2VwdG9yLiBJbnRlcmNlcHRvcnMgbXVzdCBiZSBhIGNsYXNzIHJlZmVyZW5jZSBvciBhbiBvYmplY3Qgd2l0aCBhbiBpbnRlcmNlcHQgbWV0aG9kLicsXG4gICAgQXRMZWFzdE9uZUludGVyY2VwdG9yUmVxdWlyZWQgPSAnQXQgbGVhc3Qgb25lIGludGVyY2VwdG9yIG11c3QgYmUgcHJvdmlkZWQuJyxcbiAgICBJbnZhbGlkSW50ZXJjZXB0b3JSZXR1cm5WYWx1ZSA9ICdUaGUgaW50ZXJjZXB0b3IgbXVzdCByZXR1cm4gYSBmdW5jdGlvbi4nLFxuXG4gICAgLy8gUGlwZVxuICAgIEludmFsaWRQaXBlRGVmaW5pdGlvbiA9ICdJbnZhbGlkIHBpcGUuIFBpcGVzIG11c3QgYmUgYSBjbGFzcyByZWZlcmVuY2Ugb3IgYW4gb2JqZWN0IHdpdGggYSB0cmFuc2Zvcm0gbWV0aG9kLicsXG4gICAgQXRMZWFzdE9uZVBpcGVSZXF1aXJlZCA9ICdBdCBsZWFzdCBvbmUgcGlwZSBtdXN0IGJlIHByb3ZpZGVkLicsXG5cbiAgICAvLyBBcHAgbG9hZGluZ1xuICAgIEFwcEFscmVhZHlMb2FkZWQgPSAnQXBwIGlzIGFscmVhZHkgbG9hZGVkLiBQbGVhc2UgY2FsbCB0aGUgc3RvcCBtZXRob2QgYmVmb3JlIGNhbGxpbmcgdGhlIHN0YXJ0IG1ldGhvZC4nLFxuICAgIEFwcE5vdExvYWRlZCA9ICdBcHAgaXMgbm90IGxvYWRlZC4gUGxlYXNlIGNhbGwgdGhlIHN0YXJ0IG1ldGhvZCBiZWZvcmUgY2FsbGluZyB0aGUgc3RvcCBtZXRob2QuJyxcblxuICAgIC8vIERlY29yYXRvcnNcbiAgICBJbnZhbGlkSW5qZWN0aW9uVG9rZW5TcGVjaWZpZWQgPSAnVGhlIHNwZWNpZmllZCBpbmplY3Rpb24gdG9rZW4gaXMgaW52YWxpZC4nLFxuICAgIEluamVjdGlvblRva2VuTm90Rm91bmQgPSAnVGhlIGluamVjdGlvbiB0b2tlbiBjb3VsZCBub3QgYmUgZm91bmQuJyxcbiAgICBQYXJhbUtleU11c3RCZVN0cmluZyA9ICdUaGUgcGFyYW0ga2V5IG11c3QgYmUgYSBzdHJpbmcuJyxcbiAgICBJbmRleEtleU11c3RCZU51bWJlciA9ICdUaGUgaW5kZXgga2V5IG11c3QgYmUgYSBudW1iZXIuJyxcbiAgICBEdXBsaWNhdGVEZWNvcmF0b3JVc2FnZSA9ICdUaGUgc2FtZSBkZWNvcmF0b3IgY2FuIG9ubHkgYmUgdXNlZCBvbmNlIGluIHRoZSBzYW1lIGNsYXNzLicsXG4gICAgSW52YWxpZENvbnRyb2xsZXJPcHRpb25zID0gJ0ludmFsaWQgY29udHJvbGxlciBvcHRpb25zIGZvdW5kLicsXG4gICAgSW52YWxpZEluamVjdGFibGVPcHRpb25zID0gJ0ludmFsaWQgaW5qZWN0YWJsZSBvcHRpb25zIGZvdW5kLicsXG4gICAgSW52YWxpZE1vZHVsZU9wdGlvbnMgPSAnSW52YWxpZCBtb2R1bGUgb3B0aW9ucyBmb3VuZC4nLFxuICAgIE11bHRpcGxlRGVjb3JhdG9yc09uU2luZ2xlUGFyYW1ldGVyTm90QWxsb3dlZCA9ICdDYW5ub3QgYXBwbHkgbXVsdGlwbGUgZGVjb3JhdG9ycyB0byB0aGUgc2FtZSBwYXJhbWV0ZXIuJyxcblxuICAgIC8vIEludGVybmFsIEFwcFxuICAgIENpcmN1bGFyRGVwZW5kZW5jeURldGVjdGVkID0gJ0NpcmN1bGFyIGRlcGVuZGVuY3kgZGV0ZWN0ZWQuJyxcbiAgICBJbnZhbGlkTW9kdWxlRGVmaW5pdGlvbiA9ICdUaGUgbW9kdWxlIGlzIGludmFsaWQuJyxcbiAgICBJbnZhbGlkRXhwb3J0RGVmaW5pdGlvbiA9ICdUaGUgZXhwb3J0IGlzIGludmFsaWQuJyxcbiAgICBJbnZhbGlkUHJvdmlkZXJEZWZpbml0aW9uID0gJ1RoZSBwcm92aWRlciBpcyBpbnZhbGlkLicsXG4gICAgSW52YWxpZFBhcmFtZXRlckRlY29yYXRvclVzYWdlID0gJ0VhY2ggcGFyYW1ldGVyIG11c3QgaGF2ZSB0aGVpciBpdHMgb3duIGRlY29yYXRvci4nLFxuICAgIFJlc3BvbnNlRGVjb3JhdG9yTm90QWxsb3dlZE9uRXZlbnRzID0gJ1RoZSBAUmVzcG9uc2UoKSBkZWNvcmF0b3IgaXMgbm90IGFsbG93ZWQgb24gZXZlbnRzLicsXG4gICAgUGxheWVyRGVjb3JhdG9yTm90QWxsb3dlZE9uQ2xpZW50RXZlbnRzID0gJ1RoZSBAUGxheWVyKCkgZGVjb3JhdG9yIGlzIG5vdCBhbGxvd2VkIG9uIGNsaWVudCBldmVudHMuJyxcblxuICAgIC8vIFRpbWVyc1xuICAgIFRpbWVyTmFtZU11c3RCZVN0cmluZyA9ICdUaGUgdGltZXIgbmFtZSBtdXN0IGJlIGEgc3RyaW5nLicsXG59XG4iLCAiZXhwb3J0IGVudW0gSW5qZWN0YWJsZVNjb3BlIHtcbiAgICBSZXF1ZXN0ID0gJ3JlcXVlc3QnLFxuICAgIFRyYW5zaWVudCA9ICd0cmFuc2llbnQnLFxuICAgIFNpbmdsZXRvbiA9ICdzaW5nbGV0b24nLFxufVxuIiwgImV4cG9ydCBlbnVtIFJQQ1Jlc3VsdFN0YXR1cyB7XG4gICAgU3VjY2VzcyA9IDEsXG4gICAgVGltZW91dCA9IDIsXG4gICAgSGFuZGxlck5vdEZvdW5kID0gMyxcbiAgICBVbmtub3duID0gNCxcbiAgICBDYW5jZWxsZWRCeUd1YXJkID0gNSxcbiAgICBJbnZhbGlkR3VhcmRSZXR1cm4gPSA2LFxuICAgIFRvb01hbnlSZXF1ZXN0cyA9IDcsXG4gICAgUGxheWVyRGlzY29ubmVjdGVkID0gOCxcbiAgICBQbGF5ZXJOb3RGb3VuZCA9IDksXG59XG4iLCAiaW1wb3J0IHsgUlBDUmVzdWx0U3RhdHVzIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBSUENSZXN1bHQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzJztcblxuZXhwb3J0IGNvbnN0IElOVEVSTkFMX0FQUF9DT05UQUlORVIgPSAnSU5URVJOQUxfQVBQX0NPTlRBSU5FUic7XG5leHBvcnQgY29uc3QgR0xPQkFMX0FQUF9DT05UQUlORVIgPSAnR0xPQkFMX0FQUF9DT05UQUlORVInO1xuZXhwb3J0IGNvbnN0IEFQUF9FTlZJUk9NRU5UID0gJ0FQUF9FTlZJUk9NRU5UJztcblxuZXhwb3J0IGNvbnN0IEdMT0JBTF9HVUFSRFMgPSAnR0xPQkFMX0dVQVJEUyc7XG5leHBvcnQgY29uc3QgR0xPQkFMX0lOVEVSQ0VQVE9SUyA9ICdHTE9CQUxfSU5URVJDRVBUT1JTJztcbmV4cG9ydCBjb25zdCBHTE9CQUxfUElQRVMgPSAnR0xPQkFMX1BJUEVTJztcbmV4cG9ydCBjb25zdCBHTE9CQUxfRVJST1JfRklMVEVSUyA9ICdHTE9CQUxfRVJST1JfRklMVEVSUyc7XG5cbmV4cG9ydCBjb25zdCBQTFVHSU5TID0gJ1BMVUdJTlMnO1xuXG5leHBvcnQgY29uc3QgRU5BQkxFX1NIVVRET1dOX0hPT0tTID0gJ0VOQUJMRV9TSFVURE9XTl9IT09LUyc7XG5leHBvcnQgY29uc3QgQ09OVEFJTkVSX09QVElPTlMgPSAnQ09OVEFJTkVSX09QVElPTlMnO1xuZXhwb3J0IGNvbnN0IExPR19FUlJPUl9TVEFDS1RSQUNFID0gJ0xPR19FUlJPUl9TVEFDS1RSQUNFJztcblxuZXhwb3J0IGNvbnN0IE1BTkdPX0xPR19QUkVGSVggPSAn8J+lrSc7XG5cbmV4cG9ydCBjb25zdCBNQU5HT19SRVFVRVNUX0ZBQ1RPUlkgPSAnTUFOR09fUkVRVUVTVF9GQUNUT1JZJztcbmV4cG9ydCBjb25zdCBNQU5HT19SRVNQT05TRV9GQUNUT1JZID0gJ01BTkdPX1JFU1BPTlNFX0ZBQ1RPUlknO1xuZXhwb3J0IGNvbnN0IEVYRUNVVElPTl9DT05URVhUX0ZBQ1RPUlkgPSAnRVhFQ1VUSU9OX0NPTlRFWFRfRkFDVE9SWSc7XG5cbmV4cG9ydCBjb25zdCBNVUxUSVBMQVlFUl9TRVJWSUNFID0gJ01VTFRJUExBWUVSX1NFUlZJQ0UnO1xuXG5leHBvcnQgY29uc3QgUlBDX1JFU1VMVF9USU1FT1VUOiBSUENSZXN1bHQgPSB7XG4gICAgc3VjY2VzczogZmFsc2UsXG4gICAgZXJyb3I6IHsgbWVzc2FnZTogJ1JQQyBjYWxsIHRpbWVkIG91dC4nIH0sXG4gICAgc3RhdHVzOiBSUENSZXN1bHRTdGF0dXMuVGltZW91dCxcbn07XG5cbmV4cG9ydCBjb25zdCBSUENfUkVTVUxUX0hBTkRMRVJfTk9UX0ZPVU5EOiBSUENSZXN1bHQgPSB7XG4gICAgc3VjY2VzczogZmFsc2UsXG4gICAgZXJyb3I6IHsgbWVzc2FnZTogJ1JQQyBoYW5kbGVyIG5vdCBmb3VuZC4nIH0sXG4gICAgc3RhdHVzOiBSUENSZXN1bHRTdGF0dXMuSGFuZGxlck5vdEZvdW5kLFxufTtcblxuZXhwb3J0IGNvbnN0IFJQQ19SRVNVTFRfVU5LTk9XTjogUlBDUmVzdWx0ID0ge1xuICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgIGVycm9yOiB7IG1lc3NhZ2U6ICdVbmtub3duIGVycm9yLicgfSxcbiAgICBzdGF0dXM6IFJQQ1Jlc3VsdFN0YXR1cy5Vbmtub3duLFxufTtcblxuZXhwb3J0IGNvbnN0IFJQQ19SRVNVTFRfUExBWUVSX0RJU0NPTk5FQ1RFRDogUlBDUmVzdWx0ID0ge1xuICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgIGVycm9yOiB7IG1lc3NhZ2U6ICdQbGF5ZXIgZGlzY29ubmVjdGVkLicgfSxcbiAgICBzdGF0dXM6IFJQQ1Jlc3VsdFN0YXR1cy5QbGF5ZXJEaXNjb25uZWN0ZWQsXG59O1xuXG5leHBvcnQgY29uc3QgUlBDX1JFU1VMVF9QTEFZRVJfTk9UX0ZPVU5EOiBSUENSZXN1bHQgPSB7XG4gICAgc3VjY2VzczogZmFsc2UsXG4gICAgZXJyb3I6IHsgbWVzc2FnZTogJ1BsYXllciBub3QgZm91bmQuJyB9LFxuICAgIHN0YXR1czogUlBDUmVzdWx0U3RhdHVzLlBsYXllck5vdEZvdW5kLFxufTtcbiIsICJ2YXIgX19kZWZQcm9wID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIF9fbmFtZSA9ICh0YXJnZXQsIHZhbHVlKT0+X19kZWZQcm9wKHRhcmdldCwgXCJuYW1lXCIsIHtcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xuZXhwb3J0IHsgX19uYW1lIH07IC8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsZXdvZ0lDSjJaWEp6YVc5dUlqb2dNeXdLSUNBaWMyOTFjbU5sY3lJNklGdGRMQW9nSUNKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2SUZ0ZExBb2dJQ0p0WVhCd2FXNW5jeUk2SUNJaUxBb2dJQ0p1WVcxbGN5STZJRnRkQ24wS1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYlhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWlKOSIsICJleHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVSYW5kb21JZCgpIHtcbiAgICByZXR1cm4gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyaW5nKDIsIDE1KSArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZygyLCAxNSk7XG59XG4iLCAiZXhwb3J0IGNvbnN0IGlzVW5kZWZpbmVkID0gKG9iajogYW55KTogb2JqIGlzIHVuZGVmaW5lZCA9PiB0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJztcbmV4cG9ydCBjb25zdCBpc09iamVjdCA9IChmbjogYW55KTogZm4gaXMgb2JqZWN0ID0+ICFpc05pbChmbikgJiYgdHlwZW9mIGZuID09PSAnb2JqZWN0JztcbmV4cG9ydCBjb25zdCBpc0Z1bmN0aW9uID0gKHZhbDogYW55KTogdmFsIGlzIEZ1bmN0aW9uID0+IHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbic7XG5leHBvcnQgY29uc3QgaXNTdHJpbmcgPSAodmFsOiBhbnkpOiB2YWwgaXMgc3RyaW5nID0+IHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnO1xuZXhwb3J0IGNvbnN0IGlzTnVtYmVyID0gKHZhbDogYW55KTogdmFsIGlzIG51bWJlciA9PiB0eXBlb2YgdmFsID09PSAnbnVtYmVyJztcbmV4cG9ydCBjb25zdCBpc0NvbnN0cnVjdG9yID0gKHZhbDogYW55KTogYm9vbGVhbiA9PiB2YWwgPT09ICdjb25zdHJ1Y3Rvcic7XG5leHBvcnQgY29uc3QgaXNOaWwgPSAodmFsOiBhbnkpOiB2YWwgaXMgbnVsbCB8IHVuZGVmaW5lZCA9PiBpc1VuZGVmaW5lZCh2YWwpIHx8IHZhbCA9PT0gbnVsbDtcbmV4cG9ydCBjb25zdCBpc0VtcHR5ID0gKGFycmF5OiBhbnkpOiBib29sZWFuID0+ICEoYXJyYXkgJiYgYXJyYXkubGVuZ3RoID4gMCk7XG5leHBvcnQgY29uc3QgaXNTeW1ib2wgPSAodmFsOiBhbnkpOiB2YWwgaXMgc3ltYm9sID0+IHR5cGVvZiB2YWwgPT09ICdzeW1ib2wnO1xuZXhwb3J0IGNvbnN0IGlzQXN5bmNGdW5jdGlvbiA9ICh2YWw6IGFueSk6IGJvb2xlYW4gPT4gaXNGdW5jdGlvbih2YWwpICYmIHZhbC5jb25zdHJ1Y3Rvci5uYW1lID09PSAnQXN5bmNGdW5jdGlvbic7XG5leHBvcnQgY29uc3QgaXNCb29sZWFuID0gKHZhbDogYW55KTogdmFsIGlzIGJvb2xlYW4gPT4gdHlwZW9mIHZhbCA9PT0gJ2Jvb2xlYW4nO1xuZXhwb3J0IGNvbnN0IGlzUHJvbWlzZSA9IDxUID0gYW55Pih2YWw6IGFueSk6IHZhbCBpcyBQcm9taXNlPFQ+ID0+IHZhbCBpbnN0YW5jZW9mIFByb21pc2U7XG4iLCAiZXhwb3J0IGVudW0gQXBwRW52aXJvbWVudCB7XG4gICAgQ2xpZW50LFxuICAgIFNlcnZlcixcbn1cbiIsICJleHBvcnQgZW51bSBDb3JlTWV0YWRhdGFLZXkge1xuICAgIC8vIEdlbmVyYWxcbiAgICBJbmplY3RhYmxlID0gJ21hbmdvOmluamVjdGFibGUnLFxuICAgIEluamVjdCA9ICdtYW5nbzppbmplY3QnLFxuICAgIE1vZHVsZSA9ICdtYW5nbzptb2R1bGUnLFxuICAgIEdsb2JhbE1vZHVsZSA9ICdtYW5nbzpnbG9iYWwtbW9kdWxlJyxcbiAgICBDb250cm9sbGVyID0gJ21hbmdvOmNvbnRyb2xsZXItb3B0aW9ucycsXG4gICAgLy8gRXZlbnRzICYgUlBDXG4gICAgQ29udHJvbGxlckV2ZW50cyA9ICdtYW5nbzpjb250cm9sbGVyLWV2ZW50cycsXG4gICAgQ29udHJvbGxlclJQQ3MgPSAnbWFuZ286Y29udHJvbGxlci1ycGNzJyxcbiAgICBDb250cm9sbGVyUGFyYW1zID0gJ21hbmdvOmNvbnRyb2xsZXItcnBjLXBhcmFtcycsXG4gICAgLy8gUGlwZWxpbmVcbiAgICBHdWFyZHMgPSAnbWFuZ286Z3VhcmRzJyxcbiAgICBJbnRlcmNlcHRvcnMgPSAnbWFuZ286aW50ZXJjZXB0b3JzJyxcbiAgICBQaXBlcyA9ICdtYW5nbzpwaXBlcycsXG4gICAgLy8gRXJyb3JcbiAgICBDYXRjaCA9ICdtYW5nbzpjYXRjaCcsXG4gICAgRXJyb3JGaWx0ZXJzID0gJ21hbmdvOmVycm9yLWZpbHRlcnMnLFxuICAgIC8vXG4gICAgVGltZXJzID0gJ21hbmdvOnRpbWVycycsXG59XG4iLCAiZXhwb3J0IGVudW0gRXZlbnREZXN0aW5hdGlvbiB7XG4gICAgU2VydmVyID0gJ3NlcnZlcicsXG4gICAgQ2xpZW50ID0gJ2NsaWVudCcsXG4gICAgV2ViVmlldyA9ICd3ZWJ2aWV3Jyxcbn1cbiIsICJleHBvcnQgZW51bSBFeGVjdXRpb25Db250ZXh0VHlwZSB7XG4gICAgRXZlbnQgPSAnZXZlbnQnLFxuICAgIFJQQyA9ICdycGMnLFxufVxuIiwgImV4cG9ydCBlbnVtIE1ldGhvZFBhcmFtVHlwZSB7XG4gICAgQm9keSA9ICdib2R5JyxcbiAgICBDdXN0b20gPSAnY3VzdG9tJyxcbiAgICBQYXJhbSA9ICdwYXJhbScsXG4gICAgUGxheWVyID0gJ3BsYXllcicsXG4gICAgUmVxdWVzdCA9ICdyZXF1ZXN0JyxcbiAgICBSZXNwb25zZSA9ICdyZXNwb25zZScsXG4gICAgSW5kZXggPSAnaW5kZXgnLFxufVxuIiwgImltcG9ydCB7IHR5cGUgUlBDQ2FsbE9wdGlvbnMsIHR5cGUgUlBDUmVzdWx0LCB0eXBlIFNjcmlwdFJQQ0hhbmRsZXIgfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBSUENfUkVTVUxUX0hBTkRMRVJfTk9UX0ZPVU5ELCBSUENfUkVTVUxUX1RJTUVPVVQgfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvYXBwL2NvbnN0YW50cyc7XG5pbXBvcnQgdHlwZSB7IEV2ZW50U2VydmljZSwgUlBDU2VydmljZSB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHR5cGUgeyBXZWJWaWV3RXZlbnRTZXJ2aWNlIH0gZnJvbSAnLi93ZWJ2aWV3LWV2ZW50LnNlcnZpY2UnO1xuaW1wb3J0IHR5cGUgeyBXZWJWaWV3TG9nZ2VyU2VydmljZSB9IGZyb20gJy4vd2Vidmlldy1sb2dnZXIuc2VydmljZSc7XG5pbXBvcnQgeyBnZW5lcmF0ZVJhbmRvbUlkLCBpc05pbCB9IGZyb20gJ0ByYWdlbXAtbWFuZ28vY29yZS91dGlscyc7XG5pbXBvcnQgeyBFcnJvck1lc3NhZ2UsIFJQQ1Jlc3VsdFN0YXR1cyB9IGZyb20gJ0ByYWdlbXAtbWFuZ28vY29yZS9lbnVtcyc7XG5pbXBvcnQgeyBFdmVudERlc3RpbmF0aW9uIH0gZnJvbSAnQHJhZ2VtcC1tYW5nby9jb3JlL2FwcC9lbnVtcyc7XG5pbXBvcnQgdHlwZSB7IFJQQ1BheWxvYWQgfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvYXBwL2ludGVyZmFjZXMnO1xuXG5leHBvcnQgY2xhc3MgV2ViVmlld1JQQ1NlcnZpY2UgaW1wbGVtZW50cyBSUENTZXJ2aWNlIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5ICRUSU1FT1VUID0gMjAwMDtcbiAgICBwdWJsaWMgcmVhZG9ubHkgJGxvY2FsSGFuZGxlcnMgPSBuZXcgTWFwPHN0cmluZywgU2NyaXB0UlBDSGFuZGxlcj4oKTtcbiAgICBwdWJsaWMgcmVhZG9ubHkgJGNsaWVudEhhbmRsZXJzID0gbmV3IE1hcDxzdHJpbmcsIFNjcmlwdFJQQ0hhbmRsZXI+KCk7XG4gICAgcHVibGljIHJlYWRvbmx5ICRzZXJ2ZXJIYW5kbGVycyA9IG5ldyBNYXA8c3RyaW5nLCBTY3JpcHRSUENIYW5kbGVyPigpO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgJGV2ZW50U2VydmljZTogV2ViVmlld0V2ZW50U2VydmljZSwgcHJpdmF0ZSByZWFkb25seSAkbG9nZ2VyU2VydmljZTogV2ViVmlld0xvZ2dlclNlcnZpY2UpIHt9XG5cbiAgICBwdWJsaWMgYXN5bmMgY2FsbDxFIGV4dGVuZHMgc3RyaW5nPihcbiAgICAgICAgcnBjTmFtZTogRSxcbiAgICAgICAgYm9keT86IHVua25vd24sXG4gICAgICAgIG9wdGlvbnM6IFJQQ0NhbGxPcHRpb25zID0geyB0aW1lb3V0OiB0aGlzLiRUSU1FT1VUIH0sXG4gICAgKTogUHJvbWlzZTxSUENSZXN1bHQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBycGNIYW5kbGVyID0gdGhpcy4kbG9jYWxIYW5kbGVycy5nZXQocnBjTmFtZSk7XG4gICAgICAgICAgICBpZiAoaXNOaWwocnBjSGFuZGxlcikpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKFJQQ19SRVNVTFRfSEFORExFUl9OT1RfRk9VTkQpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShSUENfUkVTVUxUX1RJTUVPVVQpO1xuICAgICAgICAgICAgfSwgb3B0aW9ucy50aW1lb3V0KTtcblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnBjSGFuZGxlci5oYW5kbGVyKGJvZHkpO1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gICAgICAgICAgICByZXNvbHZlKHsgc3VjY2VzczogdHJ1ZSwgc3RhdHVzOiBSUENSZXN1bHRTdGF0dXMuU3VjY2VzcywgYm9keTogcmVzdWx0LCBlcnJvcjogdW5kZWZpbmVkIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25SZXF1ZXN0PEUgZXh0ZW5kcyBzdHJpbmc+KFxuICAgICAgICBycGNOYW1lOiBFLFxuICAgICAgICBoYW5kbGVyOiAoYm9keTogdW5rbm93bikgPT4gdW5rbm93biB8IFByb21pc2U8dW5rbm93bj4sXG4gICAgKTogU2NyaXB0UlBDSGFuZGxlciB7XG4gICAgICAgIGlmICh0aGlzLiRsb2NhbEhhbmRsZXJzLmhhcyhycGNOYW1lKSkge1xuICAgICAgICAgICAgdGhpcy4kbG9nZ2VyU2VydmljZS5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgcmVnaXN0ZXJpbmcgYSBSUEMgaGFuZGxlci4nKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihFcnJvck1lc3NhZ2UuUlBDSGFuZGxlckFscmVhZHlFeGlzdHMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJwY0hhbmRsZXI6IFNjcmlwdFJQQ0hhbmRsZXIgPSB7XG4gICAgICAgICAgICBkZXN0cm95OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIHJwY0hhbmRsZXIudmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLiRsb2NhbEhhbmRsZXJzLmRlbGV0ZShycGNOYW1lKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBycGNOYW1lLFxuICAgICAgICAgICAgaGFuZGxlcixcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLiRsb2NhbEhhbmRsZXJzLnNldChycGNOYW1lLCBycGNIYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIHJwY0hhbmRsZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGNhbGxTZXJ2ZXI8RSBleHRlbmRzIHN0cmluZz4oXG4gICAgICAgIHJwY05hbWU6IEUsXG4gICAgICAgIGJvZHk/OiB1bmtub3duLFxuICAgICAgICBvcHRpb25zOiBSUENDYWxsT3B0aW9ucyA9IHsgdGltZW91dDogdGhpcy4kVElNRU9VVCB9LFxuICAgICk6IFByb21pc2U8UlBDUmVzdWx0PiB7XG4gICAgICAgIHJldHVybiB0aGlzLiRoYW5kbGVDYWxsKHJwY05hbWUsIEV2ZW50RGVzdGluYXRpb24uU2VydmVyLCBvcHRpb25zLCBib2R5KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25TZXJ2ZXJSZXF1ZXN0PEUgZXh0ZW5kcyBzdHJpbmc+KFxuICAgICAgICBycGNOYW1lOiBFLFxuICAgICAgICBoYW5kbGVyOiAoYm9keTogdW5rbm93bikgPT4gdW5rbm93biB8IFByb21pc2U8dW5rbm93bj4sXG4gICAgKTogU2NyaXB0UlBDSGFuZGxlciB7XG4gICAgICAgIGlmICh0aGlzLiRzZXJ2ZXJIYW5kbGVycy5oYXMocnBjTmFtZSkpIHtcbiAgICAgICAgICAgIHRoaXMuJGxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHJlZ2lzdGVyaW5nIGEgUlBDIGhhbmRsZXIuJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRXJyb3JNZXNzYWdlLlJQQ0hhbmRsZXJBbHJlYWR5RXhpc3RzKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBycGNIYW5kbGVyOiBTY3JpcHRSUENIYW5kbGVyID0ge1xuICAgICAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBycGNIYW5kbGVyLnZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy4kc2VydmVySGFuZGxlcnMuZGVsZXRlKHJwY05hbWUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJwY05hbWUsXG4gICAgICAgICAgICBoYW5kbGVyLFxuICAgICAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuJHNlcnZlckhhbmRsZXJzLnNldChycGNOYW1lLCBycGNIYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIHJwY0hhbmRsZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGNhbGxQbGF5ZXI8RSBleHRlbmRzIHN0cmluZz4oXG4gICAgICAgIHJwY05hbWU6IEUsXG4gICAgICAgIGJvZHk/OiB1bmtub3duLFxuICAgICAgICBvcHRpb25zOiBSUENDYWxsT3B0aW9ucyA9IHsgdGltZW91dDogdGhpcy4kVElNRU9VVCB9LFxuICAgICk6IFByb21pc2U8UlBDUmVzdWx0PiB7XG4gICAgICAgIHJldHVybiB0aGlzLiRoYW5kbGVDYWxsKHJwY05hbWUsIEV2ZW50RGVzdGluYXRpb24uQ2xpZW50LCBvcHRpb25zLCBib2R5KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25QbGF5ZXJSZXF1ZXN0PEUgZXh0ZW5kcyBzdHJpbmc+KFxuICAgICAgICBycGNOYW1lOiBFLFxuICAgICAgICBoYW5kbGVyOiAoYm9keTogdW5rbm93bikgPT4gdW5rbm93biB8IFByb21pc2U8dW5rbm93bj4sXG4gICAgKTogU2NyaXB0UlBDSGFuZGxlciB7XG4gICAgICAgIGlmICh0aGlzLiRjbGllbnRIYW5kbGVycy5oYXMocnBjTmFtZSkpIHtcbiAgICAgICAgICAgIHRoaXMuJGxvZ2dlclNlcnZpY2UuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHJlZ2lzdGVyaW5nIGEgUlBDIGxpc3RlbmVyLicpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVycm9yTWVzc2FnZS5SUENIYW5kbGVyQWxyZWFkeUV4aXN0cyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcnBjSGFuZGxlcjogU2NyaXB0UlBDSGFuZGxlciA9IHtcbiAgICAgICAgICAgIGRlc3Ryb3k6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgcnBjSGFuZGxlci52YWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuJGNsaWVudEhhbmRsZXJzLmRlbGV0ZShycGNOYW1lKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBycGNOYW1lLFxuICAgICAgICAgICAgaGFuZGxlcixcbiAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLiRjbGllbnRIYW5kbGVycy5zZXQocnBjTmFtZSwgcnBjSGFuZGxlcik7XG4gICAgICAgIHJldHVybiBycGNIYW5kbGVyO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgJGhhbmRsZUNhbGw8VFJlc3VsdD4oXG4gICAgICAgIHJwY05hbWU6IHN0cmluZyxcbiAgICAgICAgZGVzdGluYXRpb246IEV2ZW50RGVzdGluYXRpb24sIC8vICdjbGllbnQnIHwgJ3NlcnZlcicsXG4gICAgICAgIG9wdGlvbnM/OiBQYXJ0aWFsPFJQQ0NhbGxPcHRpb25zPixcbiAgICAgICAgYm9keT86IHVua25vd24sXG4gICAgKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxSUENSZXN1bHQ8VFJlc3VsdD4+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjYWxsSWQgPSBnZW5lcmF0ZVJhbmRvbUlkKCk7XG4gICAgICAgICAgICBsZXQgdGltZW91dElkOiBudW1iZXI7XG5cbiAgICAgICAgICAgIGNvbnN0IG9uY2VIYW5kbGUgPSAoYm9keTogdW5rbm93bikgPT4ge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoPFJQQ1Jlc3VsdDxUUmVzdWx0Pj5ib2R5KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBzY3JpcHRFdmVudEhhbmRsZXIgPVxuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uID09PSBFdmVudERlc3RpbmF0aW9uLlNlcnZlclxuICAgICAgICAgICAgICAgICAgICA/IHRoaXMuJGV2ZW50U2VydmljZS5vbmNlU2VydmVyKGBSUEM6OlJFVFVSTl9GUk9NX1NFUlZFUl8ke2NhbGxJZH1gLCBvbmNlSGFuZGxlKVxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMuJGV2ZW50U2VydmljZS5vbmNlUGxheWVyKGBSUEM6OlJFVFVSTl9GUk9NX0NMSUVOVF8ke2NhbGxJZH1gLCBvbmNlSGFuZGxlKTtcblxuICAgICAgICAgICAgY29uc3QgcGF5bG9hZDogUlBDUGF5bG9hZCA9IHtcbiAgICAgICAgICAgICAgICBzb3VyY2U6IEV2ZW50RGVzdGluYXRpb24uV2ViVmlldyxcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbixcbiAgICAgICAgICAgICAgICBpZDogY2FsbElkLFxuICAgICAgICAgICAgICAgIHJwY05hbWUsXG4gICAgICAgICAgICAgICAgYm9keSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkZXN0aW5hdGlvbiA9PT0gRXZlbnREZXN0aW5hdGlvbi5TZXJ2ZXJcbiAgICAgICAgICAgICAgICA/ICg8RXZlbnRTZXJ2aWNlPnRoaXMuJGV2ZW50U2VydmljZSkuZW1pdFBsYXllcignUlBDOjpDQUxMX1NFUlZFUicsIHBheWxvYWQpXG4gICAgICAgICAgICAgICAgOiAoPEV2ZW50U2VydmljZT50aGlzLiRldmVudFNlcnZpY2UpLmVtaXRQbGF5ZXIoJ1JQQzo6Q0FMTF9DTElFTlQnLCBwYXlsb2FkKTtcblxuICAgICAgICAgICAgdGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgc2NyaXB0RXZlbnRIYW5kbGVyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKDxSUENSZXN1bHQ8VFJlc3VsdD4+UlBDX1JFU1VMVF9USU1FT1VUKTtcbiAgICAgICAgICAgIH0sIG9wdGlvbnM/LnRpbWVvdXQgPz8gdGhpcy4kVElNRU9VVCk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBSUENSZXN1bHRTdGF0dXMgfSBmcm9tICcuLi9lbnVtcyc7XG5cbmV4cG9ydCBjbGFzcyBNYW5nb0Vycm9yPFREZXRhaWxzID0gdW5rbm93bj4gZXh0ZW5kcyBFcnJvciB7XG4gICAgcHVibGljIHN0YXR1czogbnVtYmVyID0gUlBDUmVzdWx0U3RhdHVzLlVua25vd247XG4gICAgcHVibGljIGRldGFpbHM6IFREZXRhaWxzIHwgdW5kZWZpbmVkO1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgc3RhdHVzPzogbnVtYmVyLCBkZXRhaWxzPzogVERldGFpbHMpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzID8/IFJQQ1Jlc3VsdFN0YXR1cy5Vbmtub3duO1xuICAgICAgICB0aGlzLmRldGFpbHMgPSBkZXRhaWxzO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBSUENSZXN1bHRTdGF0dXMgfSBmcm9tICcuLi9lbnVtcyc7XG5pbXBvcnQgeyBNYW5nb0Vycm9yIH0gZnJvbSAnLi9tYW5nby5lcnJvcic7XG5cbmV4cG9ydCBjbGFzcyBHdWFyZENhbmNlbEVycm9yIGV4dGVuZHMgTWFuZ29FcnJvciB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcignUHJvY2VzcyBjYW5jZWxsZWQgYnkgdGhlIGd1YXJkLicsIFJQQ1Jlc3VsdFN0YXR1cy5DYW5jZWxsZWRCeUd1YXJkKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgUlBDUmVzdWx0U3RhdHVzIH0gZnJvbSAnLi4vZW51bXMnO1xuaW1wb3J0IHsgTWFuZ29FcnJvciB9IGZyb20gJy4vbWFuZ28uZXJyb3InO1xuXG5leHBvcnQgY2xhc3MgR3VhcmRJbnZhbGlkUmV0dXJuRXJyb3IgZXh0ZW5kcyBNYW5nb0Vycm9yIHtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCdHdWFyZCByZXR1cm5lZCBhbiBpbnZhbGlkIHZhbHVlLiBFeHBlY3RlZCBib29sZWFuLicsIFJQQ1Jlc3VsdFN0YXR1cy5JbnZhbGlkR3VhcmRSZXR1cm4pO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBSUENSZXN1bHRTdGF0dXMgfSBmcm9tICcuLi9lbnVtcyc7XG5pbXBvcnQgeyBNYW5nb0Vycm9yIH0gZnJvbSAnLi9tYW5nby5lcnJvcic7XG5cbmV4cG9ydCBjbGFzcyBUb29NYW55UmVxdWVzdHMgZXh0ZW5kcyBNYW5nb0Vycm9yIHtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZSA9ICdUb28gbWFueSByZXF1ZXN0cy4nKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UsIFJQQ1Jlc3VsdFN0YXR1cy5Ub29NYW55UmVxdWVzdHMpO1xuICAgIH1cbn1cbiIsICJpbXBvcnQgeyBSUENSZXN1bHRTdGF0dXMgfSBmcm9tICcuLi9lbnVtcyc7XG5pbXBvcnQgeyBNYW5nb0Vycm9yIH0gZnJvbSAnLi9tYW5nby5lcnJvcic7XG5cbmV4cG9ydCBjbGFzcyBVbmtub3duRXJyb3IgZXh0ZW5kcyBNYW5nb0Vycm9yIHtcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCdVbmtub3duIGVycm9yLicsIFJQQ1Jlc3VsdFN0YXR1cy5Vbmtub3duKTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgV2ViVmlld0V2ZW50U2VydmljZSwgV2ViVmlld0xvZ2dlclNlcnZpY2UsIFdlYlZpZXdSUENTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBpc05pbCB9IGZyb20gJ0ByYWdlbXAtbWFuZ28vY29yZS91dGlscyc7XG5pbXBvcnQgeyBSUENfUkVTVUxUX0hBTkRMRVJfTk9UX0ZPVU5ELCBSUENfUkVTVUxUX1VOS05PV04gfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvYXBwL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBSUENSZXN1bHRTdGF0dXMgfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvZW51bXMnO1xuaW1wb3J0IHR5cGUgeyBMb2dnZXJTZXJ2aWNlLCBSUENSZXN1bHQgfSBmcm9tICdAcmFnZW1wLW1hbmdvL2NvcmUvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBNYW5nb0Vycm9yIH0gZnJvbSAnQHJhZ2VtcC1tYW5nby9jb3JlL2Vycm9ycyc7XG5pbXBvcnQgdHlwZSB7IEV2ZW50U2VydmljZSwgUlBDU2VydmljZSB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0TWFuZ28oKSB7XG4gICAgaWYgKCFpc05pbCh3aW5kb3cubWFuZ28pKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cubWFuZ287XG4gICAgfVxuXG4gICAgY29uc3QgZXZlbnQgPSBuZXcgV2ViVmlld0V2ZW50U2VydmljZSgpO1xuICAgIGNvbnN0IGxvZ2dlciA9IG5ldyBXZWJWaWV3TG9nZ2VyU2VydmljZSgpO1xuICAgIGNvbnN0IHJwYyA9IG5ldyBXZWJWaWV3UlBDU2VydmljZShldmVudCwgbG9nZ2VyKTtcblxuICAgICg8RXZlbnRTZXJ2aWNlPmV2ZW50KS5vblNlcnZlcignUlBDOjpDQUxMX1dFQlZJRVcnLCBhc3luYyAoYm9keSkgPT4ge1xuICAgICAgICBjb25zdCBpZCA9IGJvZHkuaWQ7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBib2R5LnJwY05hbWU7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBib2R5LmJvZHk7XG5cbiAgICAgICAgY29uc3QgcnBjSGFuZGxlciA9IHJwYy4kc2VydmVySGFuZGxlcnMuZ2V0KG5hbWUpO1xuICAgICAgICBpZiAoIXJwY0hhbmRsZXIpIHtcbiAgICAgICAgICAgIGV2ZW50LmVtaXRTZXJ2ZXIoYFJQQzo6UkVUVVJOX0ZST01fV0VCVklFV18ke2lkfWAsIFJQQ19SRVNVTFRfSEFORExFUl9OT1RfRk9VTkQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJwY0hhbmRsZXIuaGFuZGxlcihwYXlsb2FkKTtcbiAgICAgICAgICAgIGNvbnN0IHJwY1Jlc3VsdDogUlBDUmVzdWx0ID0ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiBSUENSZXN1bHRTdGF0dXMuU3VjY2VzcyxcbiAgICAgICAgICAgICAgICBib2R5OiByZXN1bHQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZXZlbnQuZW1pdFNlcnZlcihgUlBDOjpSRVRVUk5fRlJPTV9XRUJWSUVXXyR7aWR9YCwgcnBjUmVzdWx0KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE1hbmdvRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBycGNSZXN1bHQ6IFJQQ1Jlc3VsdCA9IHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogZXJyb3Iuc3RhdHVzLFxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogeyBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLCBkZXRhaWxzOiBlcnJvci5kZXRhaWxzIH0sXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBldmVudC5lbWl0U2VydmVyKGBSUEM6OlJFVFVSTl9GUk9NX1dFQlZJRVdfJHtpZH1gLCBycGNSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZXZlbnQuZW1pdFNlcnZlcihgUlBDOjpSRVRVUk5fRlJPTV9XRUJWSUVXXyR7aWR9YCwgUlBDX1JFU1VMVF9VTktOT1dOKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgICg8RXZlbnRTZXJ2aWNlPmV2ZW50KS5vblBsYXllcignUlBDOjpDQUxMX1dFQlZJRVcnLCBhc3luYyAoYm9keSkgPT4ge1xuICAgICAgICBjb25zdCBpZCA9IGJvZHkuaWQ7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBib2R5LnJwY05hbWU7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBib2R5LmJvZHk7XG5cbiAgICAgICAgY29uc3QgcnBjSGFuZGxlciA9IHJwYy4kY2xpZW50SGFuZGxlcnMuZ2V0KG5hbWUpO1xuICAgICAgICBpZiAoaXNOaWwocnBjSGFuZGxlcikpIHtcbiAgICAgICAgICAgIGV2ZW50LmVtaXRQbGF5ZXIoYFJQQzo6UkVUVVJOX0ZST01fV0VCVklFV18ke2lkfWAsIFJQQ19SRVNVTFRfSEFORExFUl9OT1RfRk9VTkQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJwY0hhbmRsZXIuaGFuZGxlcihwYXlsb2FkKTtcbiAgICAgICAgICAgIGNvbnN0IHJwY1Jlc3VsdDogUlBDUmVzdWx0ID0ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiBSUENSZXN1bHRTdGF0dXMuU3VjY2VzcyxcbiAgICAgICAgICAgICAgICBib2R5OiByZXN1bHQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZXZlbnQuZW1pdFBsYXllcihgUlBDOjpSRVRVUk5fRlJPTV9XRUJWSUVXXyR7aWR9YCwgcnBjUmVzdWx0KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGV2ZW50LmVtaXRQbGF5ZXIoYFJQQzo6UkVUVVJOX0ZST01fV0VCVklFV18ke2lkfWAsIFJQQ19SRVNVTFRfVU5LTk9XTik7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IG1hbmdvID0geyBldmVudCwgcnBjLCBsb2dnZXIgfTtcblxuICAgIHdpbmRvdy5tYW5nbyA9IG1hbmdvO1xuXG4gICAgbG9nZ2VyLmxvZygnV2ViVmlldyBpbml0aWFsaXplZCcpO1xuXG4gICAgcmV0dXJuIG1hbmdvO1xufVxuXG5kZWNsYXJlIGdsb2JhbCB7XG4gICAgZXhwb3J0IGludGVyZmFjZSBXaW5kb3cge1xuICAgICAgICBtYW5nbzoge1xuICAgICAgICAgICAgZXZlbnQ6IEV2ZW50U2VydmljZTtcbiAgICAgICAgICAgIHJwYzogUlBDU2VydmljZTtcbiAgICAgICAgICAgIGxvZ2dlcjogTG9nZ2VyU2VydmljZTtcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmltcG9ydCAnLi9leHRlbnNpb24uZC50cyc7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7O0FBRU8sSUFBTUEsdUJBQU4sTUFBTUE7RUFBYixPQUFhQTs7O0VBQ0ZDLE9BQU9DLE1BQWlCO0FBQzNCQyxZQUFRRixJQUFJLDJCQUFrQixHQUFLQyxJQUFBQTtFQUN2QztFQUVPRSxTQUFTRixNQUFpQjtBQUM3QkMsWUFBUUMsTUFBTSw2QkFBb0IsR0FBS0YsSUFBQUE7RUFDM0M7RUFFT0csUUFBUUgsTUFBaUI7QUFDNUJDLFlBQVFFLEtBQUssNEJBQW1CLEdBQUtILElBQUFBO0VBQ3pDO0VBRU9JLFNBQVNKLE1BQWlCO0FBQzdCQyxZQUFRRyxNQUFNLDZCQUFvQixHQUFLSixJQUFBQTtFQUMzQztBQUNKOzs7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SUFBRUM7SUFBT0k7SUFBS0Y7RUFBTztBQUVuQ0osU0FBT0MsUUFBUUE7QUFFZkcsU0FBTzhCLElBQUkscUJBQUE7QUFFWCxTQUFPakM7QUFDWDtBQXpFZ0JIOyIsCiAgIm5hbWVzIjogWyJXZWJWaWV3TG9nZ2VyU2VydmljZSIsICJsb2ciLCAiYXJncyIsICJjb25zb2xlIiwgImVycm9yIiwgIndhcm4iLCAiZGVidWciLCAiV2ViVmlld0V2ZW50U2VydmljZSIsICIkbG9jYWxIYW5kbGVycyIsICJNYXAiLCAiJHJlbW90ZUhhbmRsZXJzIiwgIm9uIiwgImV2ZW50TmFtZSIsICJjYWxsYmFjayIsICJldmVudEhhbmRsZXIiLCAiZGVzdHJveSIsICJ2YWxpZCIsICJoYW5kbGVycyIsICJnZXQiLCAiZGVsZXRlIiwgImhhbmRsZXIiLCAibG9jYWwiLCAib25seU9uY2UiLCAicmVtb3RlIiwgImhhcyIsICJzZXQiLCAiU2V0IiwgImFkZCIsICJvbmNlIiwgImVtaXQiLCAiYm9keSIsICJsaXN0ZW5lcnMiLCAiZm9yRWFjaCIsICJzY3JpcHRFdmVudEhhbmRsZXIiLCAib25QbGF5ZXIiLCAid3JhcHBlciIsICJhcmdzIiwgIndpbmRvdyIsICJtcCIsICJldmVudHMiLCAib25jZVBsYXllciIsICJlbWl0UGxheWVyIiwgInRyaWdnZXIiLCAib25TZXJ2ZXIiLCAib25jZVNlcnZlciIsICJlbWl0U2VydmVyIiwgInBheWxvYWQiLCAiRXJyb3JNZXNzYWdlIiwgIlJQQ1Jlc3VsdFN0YXR1cyIsICJSUENfUkVTVUxUX1RJTUVPVVQiLCAic3VjY2VzcyIsICJlcnJvciIsICJtZXNzYWdlIiwgInN0YXR1cyIsICJSUENSZXN1bHRTdGF0dXMiLCAiVGltZW91dCIsICJSUENfUkVTVUxUX0hBTkRMRVJfTk9UX0ZPVU5EIiwgIkhhbmRsZXJOb3RGb3VuZCIsICJSUENfUkVTVUxUX1VOS05PV04iLCAiVW5rbm93biIsICJSUENfUkVTVUxUX1BMQVlFUl9ESVNDT05ORUNURUQiLCAiUGxheWVyRGlzY29ubmVjdGVkIiwgIlJQQ19SRVNVTFRfUExBWUVSX05PVF9GT1VORCIsICJQbGF5ZXJOb3RGb3VuZCIsICJfX2RlZlByb3AiLCAiX19uYW1lIiwgImdlbmVyYXRlUmFuZG9tSWQiLCAiTWF0aCIsICJyYW5kb20iLCAidG9TdHJpbmciLCAic3Vic3RyaW5nIiwgImlzVW5kZWZpbmVkIiwgIl9fbmFtZSIsICJvYmoiLCAiaXNOaWwiLCAiX19uYW1lIiwgInZhbCIsICJpc1VuZGVmaW5lZCIsICJFdmVudERlc3RpbmF0aW9uIiwgIldlYlZpZXdSUENTZXJ2aWNlIiwgIiRUSU1FT1VUIiwgIiRsb2NhbEhhbmRsZXJzIiwgIk1hcCIsICIkY2xpZW50SGFuZGxlcnMiLCAiJHNlcnZlckhhbmRsZXJzIiwgIiRldmVudFNlcnZpY2UiLCAiJGxvZ2dlclNlcnZpY2UiLCAiY2FsbCIsICJycGNOYW1lIiwgImJvZHkiLCAib3B0aW9ucyIsICJ0aW1lb3V0IiwgIlByb21pc2UiLCAicmVzb2x2ZSIsICJycGNIYW5kbGVyIiwgImdldCIsICJpc05pbCIsICJSUENfUkVTVUxUX0hBTkRMRVJfTk9UX0ZPVU5EIiwgInRpbWVvdXRJZCIsICJzZXRUaW1lb3V0IiwgIlJQQ19SRVNVTFRfVElNRU9VVCIsICJyZXN1bHQiLCAiaGFuZGxlciIsICJjbGVhclRpbWVvdXQiLCAic3VjY2VzcyIsICJzdGF0dXMiLCAiUlBDUmVzdWx0U3RhdHVzIiwgIlN1Y2Nlc3MiLCAiZXJyb3IiLCAidW5kZWZpbmVkIiwgIm9uUmVxdWVzdCIsICJoYXMiLCAiRXJyb3IiLCAiRXJyb3JNZXNzYWdlIiwgIlJQQ0hhbmRsZXJBbHJlYWR5RXhpc3RzIiwgImRlc3Ryb3kiLCAidmFsaWQiLCAiZGVsZXRlIiwgInNldCIsICJjYWxsU2VydmVyIiwgIiRoYW5kbGVDYWxsIiwgIkV2ZW50RGVzdGluYXRpb24iLCAiU2VydmVyIiwgIm9uU2VydmVyUmVxdWVzdCIsICJjYWxsUGxheWVyIiwgIkNsaWVudCIsICJvblBsYXllclJlcXVlc3QiLCAiZGVzdGluYXRpb24iLCAiY2FsbElkIiwgImdlbmVyYXRlUmFuZG9tSWQiLCAib25jZUhhbmRsZSIsICJzY3JpcHRFdmVudEhhbmRsZXIiLCAib25jZVNlcnZlciIsICJvbmNlUGxheWVyIiwgInBheWxvYWQiLCAic291cmNlIiwgIldlYlZpZXciLCAiaWQiLCAiZW1pdFBsYXllciIsICJNYW5nb0Vycm9yIiwgIkVycm9yIiwgInN0YXR1cyIsICJSUENSZXN1bHRTdGF0dXMiLCAiVW5rbm93biIsICJkZXRhaWxzIiwgIm1lc3NhZ2UiLCAiR3VhcmRDYW5jZWxFcnJvciIsICJDYW5jZWxsZWRCeUd1YXJkIiwgIkd1YXJkSW52YWxpZFJldHVybkVycm9yIiwgIkludmFsaWRHdWFyZFJldHVybiIsICJUb29NYW55UmVxdWVzdHMiLCAiVW5rbm93bkVycm9yIiwgImluaXRNYW5nbyIsICJpc05pbCIsICJ3aW5kb3ciLCAibWFuZ28iLCAiZXZlbnQiLCAiV2ViVmlld0V2ZW50U2VydmljZSIsICJsb2dnZXIiLCAiV2ViVmlld0xvZ2dlclNlcnZpY2UiLCAicnBjIiwgIldlYlZpZXdSUENTZXJ2aWNlIiwgIm9uU2VydmVyIiwgImJvZHkiLCAiaWQiLCAibmFtZSIsICJycGNOYW1lIiwgInBheWxvYWQiLCAicnBjSGFuZGxlciIsICIkc2VydmVySGFuZGxlcnMiLCAiZ2V0IiwgImVtaXRTZXJ2ZXIiLCAiUlBDX1JFU1VMVF9IQU5ETEVSX05PVF9GT1VORCIsICJyZXN1bHQiLCAiaGFuZGxlciIsICJycGNSZXN1bHQiLCAic3VjY2VzcyIsICJzdGF0dXMiLCAiUlBDUmVzdWx0U3RhdHVzIiwgIlN1Y2Nlc3MiLCAiZXJyb3IiLCAiTWFuZ29FcnJvciIsICJtZXNzYWdlIiwgImRldGFpbHMiLCAiUlBDX1JFU1VMVF9VTktOT1dOIiwgIm9uUGxheWVyIiwgIiRjbGllbnRIYW5kbGVycyIsICJlbWl0UGxheWVyIiwgImxvZyJdCn0K
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ragemp-mango/webview",
|
|
3
|
+
"version": "2.0.6-beta.0",
|
|
4
|
+
"homepage": "https://github.com/kkwlkk/ragemp-mango",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/kkwlkk/ragemp-mango",
|
|
8
|
+
"directory": "packages/webview"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"author": "5exyGuy (Aurėjus Remeika), wlk (https://github.com/kkwlkk)",
|
|
12
|
+
"description": "Webview/CEF package for the RageMP Mango Framework - a decorator-driven TypeScript framework for RageMP servers.",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "dist/index.js",
|
|
15
|
+
"types": "dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"dependencies": {},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"tsup": "^8.0.2",
|
|
22
|
+
"typescript": "^5.4.5",
|
|
23
|
+
"@abraham/reflection": "^0.12.0",
|
|
24
|
+
"@ragemp-mango/core": "^2.0.6-beta.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"@ragempcommunity/types-cef": "^2.1.8",
|
|
28
|
+
"@ragemp-mango/core": "^2.0.6-beta.0"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public",
|
|
32
|
+
"registry": "https://registry.npmjs.org/"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsup",
|
|
36
|
+
"dev": "tsup --watch",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"types": "tsup --dts-only"
|
|
39
|
+
}
|
|
40
|
+
}
|