@thinkhive/sdk 2.0.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +274 -0
- package/README.md +6 -22
- package/dist/api/calibration.d.ts +168 -0
- package/dist/api/calibration.js +176 -0
- package/dist/api/claims.d.ts +262 -0
- package/dist/api/claims.js +262 -0
- package/dist/api/runs.d.ts +200 -0
- package/dist/api/runs.js +262 -0
- package/dist/core/client.d.ts +29 -0
- package/dist/core/client.js +89 -0
- package/dist/core/config.d.ts +38 -0
- package/dist/core/config.js +76 -0
- package/dist/core/types.d.ts +354 -0
- package/dist/core/types.js +8 -0
- package/dist/index.d.ts +222 -512
- package/dist/index.js +169 -394
- package/dist/instrumentation/langchain.d.ts +194 -0
- package/dist/instrumentation/langchain.js +429 -0
- package/dist/instrumentation/openai.d.ts +141 -0
- package/dist/instrumentation/openai.js +279 -0
- package/dist/integrations/customer-context.d.ts +203 -0
- package/dist/integrations/customer-context.js +274 -0
- package/dist/integrations/ticket-linking.d.ts +217 -0
- package/dist/integrations/ticket-linking.js +259 -0
- package/package.json +61 -9
package/dist/index.js
CHANGED
|
@@ -1,64 +1,86 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* ThinkHive
|
|
4
|
-
* OpenTelemetry-based observability for AI agents with Explainer integration
|
|
3
|
+
* ThinkHive SDK v3.0.0
|
|
5
4
|
*
|
|
6
|
-
*
|
|
5
|
+
* Run-centric AI agent observability platform with:
|
|
6
|
+
* - Facts vs Inferences (claims API)
|
|
7
|
+
* - Deterministic ticket linking (7 methods)
|
|
8
|
+
* - Customer context snapshots (time-series)
|
|
9
|
+
* - Calibrated predictions (Brier scores)
|
|
10
|
+
*
|
|
11
|
+
* @version 3.0.0
|
|
12
|
+
* @license MIT
|
|
7
13
|
*/
|
|
8
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
15
|
+
exports.ThinkHiveValidationError = exports.ThinkHiveApiError = exports.calculateHealthTrend = exports.calculateArrChange = exports.toContextSnapshot = exports.getContextAsOf = exports.captureCustomerContext = exports.LINK_METHOD_CONFIDENCE = exports.getBestLinkMethod = exports.linkRunToZendeskTicket = exports.linkRunToTicket = exports.removeZendeskMarker = exports.hasZendeskMarker = exports.parseZendeskMarker = exports.generateZendeskMarker = exports.getCalibrationQuality = exports.isWellCalibrated = exports.calculateECE = exports.calculateBrierScore = exports.groupClaimsByCategory = exports.groupClaimsByType = exports.getHighConfidenceClaims = exports.isComputed = exports.isInference = exports.isFact = exports.fromOpenAIMessages = exports.toOpenAIMessages = exports.createRunWithContext = exports.customerContext = exports.linking = exports.calibration = exports.claims = exports.runs = exports.DEFAULT_ENDPOINT = exports.SDK_VERSION = exports.isInitialized = exports.explainer = void 0;
|
|
10
16
|
exports.init = init;
|
|
11
17
|
exports.getTracer = getTracer;
|
|
12
|
-
exports.
|
|
18
|
+
exports.shutdown = shutdown;
|
|
13
19
|
exports.traceLLM = traceLLM;
|
|
14
20
|
exports.traceRetrieval = traceRetrieval;
|
|
15
21
|
exports.traceTool = traceTool;
|
|
16
22
|
exports.traceChain = traceChain;
|
|
17
|
-
exports.createAndAnalyze = createAndAnalyze;
|
|
18
23
|
const api_1 = require("@opentelemetry/api");
|
|
19
24
|
const exporter_trace_otlp_proto_1 = require("@opentelemetry/exporter-trace-otlp-proto");
|
|
20
25
|
const resources_1 = require("@opentelemetry/resources");
|
|
21
26
|
const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
|
|
22
27
|
const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
|
|
28
|
+
// Core
|
|
29
|
+
const config_1 = require("./core/config");
|
|
30
|
+
Object.defineProperty(exports, "isInitialized", { enumerable: true, get: function () { return config_1.isInitialized; } });
|
|
31
|
+
Object.defineProperty(exports, "SDK_VERSION", { enumerable: true, get: function () { return config_1.SDK_VERSION; } });
|
|
32
|
+
Object.defineProperty(exports, "DEFAULT_ENDPOINT", { enumerable: true, get: function () { return config_1.DEFAULT_ENDPOINT; } });
|
|
33
|
+
const client_1 = require("./core/client");
|
|
34
|
+
Object.defineProperty(exports, "ThinkHiveApiError", { enumerable: true, get: function () { return client_1.ThinkHiveApiError; } });
|
|
35
|
+
Object.defineProperty(exports, "ThinkHiveValidationError", { enumerable: true, get: function () { return client_1.ThinkHiveValidationError; } });
|
|
36
|
+
// API clients
|
|
37
|
+
const runs_1 = require("./api/runs");
|
|
38
|
+
Object.defineProperty(exports, "runs", { enumerable: true, get: function () { return runs_1.runs; } });
|
|
39
|
+
Object.defineProperty(exports, "createRunWithContext", { enumerable: true, get: function () { return runs_1.createRunWithContext; } });
|
|
40
|
+
Object.defineProperty(exports, "toOpenAIMessages", { enumerable: true, get: function () { return runs_1.toOpenAIMessages; } });
|
|
41
|
+
Object.defineProperty(exports, "fromOpenAIMessages", { enumerable: true, get: function () { return runs_1.fromOpenAIMessages; } });
|
|
42
|
+
const claims_1 = require("./api/claims");
|
|
43
|
+
Object.defineProperty(exports, "claims", { enumerable: true, get: function () { return claims_1.claims; } });
|
|
44
|
+
Object.defineProperty(exports, "isFact", { enumerable: true, get: function () { return claims_1.isFact; } });
|
|
45
|
+
Object.defineProperty(exports, "isInference", { enumerable: true, get: function () { return claims_1.isInference; } });
|
|
46
|
+
Object.defineProperty(exports, "isComputed", { enumerable: true, get: function () { return claims_1.isComputed; } });
|
|
47
|
+
Object.defineProperty(exports, "getHighConfidenceClaims", { enumerable: true, get: function () { return claims_1.getHighConfidenceClaims; } });
|
|
48
|
+
Object.defineProperty(exports, "groupClaimsByType", { enumerable: true, get: function () { return claims_1.groupClaimsByType; } });
|
|
49
|
+
Object.defineProperty(exports, "groupClaimsByCategory", { enumerable: true, get: function () { return claims_1.groupClaimsByCategory; } });
|
|
50
|
+
const calibration_1 = require("./api/calibration");
|
|
51
|
+
Object.defineProperty(exports, "calibration", { enumerable: true, get: function () { return calibration_1.calibration; } });
|
|
52
|
+
Object.defineProperty(exports, "calculateBrierScore", { enumerable: true, get: function () { return calibration_1.calculateBrierScore; } });
|
|
53
|
+
Object.defineProperty(exports, "calculateECE", { enumerable: true, get: function () { return calibration_1.calculateECE; } });
|
|
54
|
+
Object.defineProperty(exports, "isWellCalibrated", { enumerable: true, get: function () { return calibration_1.isWellCalibrated; } });
|
|
55
|
+
Object.defineProperty(exports, "getCalibrationQuality", { enumerable: true, get: function () { return calibration_1.getCalibrationQuality; } });
|
|
56
|
+
// Integrations
|
|
57
|
+
const ticket_linking_1 = require("./integrations/ticket-linking");
|
|
58
|
+
Object.defineProperty(exports, "linking", { enumerable: true, get: function () { return ticket_linking_1.linking; } });
|
|
59
|
+
Object.defineProperty(exports, "generateZendeskMarker", { enumerable: true, get: function () { return ticket_linking_1.generateZendeskMarker; } });
|
|
60
|
+
Object.defineProperty(exports, "parseZendeskMarker", { enumerable: true, get: function () { return ticket_linking_1.parseZendeskMarker; } });
|
|
61
|
+
Object.defineProperty(exports, "hasZendeskMarker", { enumerable: true, get: function () { return ticket_linking_1.hasZendeskMarker; } });
|
|
62
|
+
Object.defineProperty(exports, "removeZendeskMarker", { enumerable: true, get: function () { return ticket_linking_1.removeZendeskMarker; } });
|
|
63
|
+
Object.defineProperty(exports, "linkRunToTicket", { enumerable: true, get: function () { return ticket_linking_1.linkRunToTicket; } });
|
|
64
|
+
Object.defineProperty(exports, "linkRunToZendeskTicket", { enumerable: true, get: function () { return ticket_linking_1.linkRunToZendeskTicket; } });
|
|
65
|
+
Object.defineProperty(exports, "getBestLinkMethod", { enumerable: true, get: function () { return ticket_linking_1.getBestLinkMethod; } });
|
|
66
|
+
Object.defineProperty(exports, "LINK_METHOD_CONFIDENCE", { enumerable: true, get: function () { return ticket_linking_1.LINK_METHOD_CONFIDENCE; } });
|
|
67
|
+
const customer_context_1 = require("./integrations/customer-context");
|
|
68
|
+
Object.defineProperty(exports, "customerContext", { enumerable: true, get: function () { return customer_context_1.customerContext; } });
|
|
69
|
+
Object.defineProperty(exports, "captureCustomerContext", { enumerable: true, get: function () { return customer_context_1.captureCustomerContext; } });
|
|
70
|
+
Object.defineProperty(exports, "getContextAsOf", { enumerable: true, get: function () { return customer_context_1.getContextAsOf; } });
|
|
71
|
+
Object.defineProperty(exports, "toContextSnapshot", { enumerable: true, get: function () { return customer_context_1.toContextSnapshot; } });
|
|
72
|
+
Object.defineProperty(exports, "calculateArrChange", { enumerable: true, get: function () { return customer_context_1.calculateArrChange; } });
|
|
73
|
+
Object.defineProperty(exports, "calculateHealthTrend", { enumerable: true, get: function () { return customer_context_1.calculateHealthTrend; } });
|
|
23
74
|
// ============================================================================
|
|
24
75
|
// GLOBAL STATE
|
|
25
76
|
// ============================================================================
|
|
26
77
|
let tracer = null;
|
|
27
|
-
let
|
|
28
|
-
let config;
|
|
29
|
-
const DEFAULT_ENDPOINT = "https://thinkhivemind-h25z7pvd3q-uc.a.run.app";
|
|
30
|
-
// ============================================================================
|
|
31
|
-
// HTTP CLIENT
|
|
32
|
-
// ============================================================================
|
|
33
|
-
async function apiRequest(path, options = {}) {
|
|
34
|
-
const { method = 'GET', body, headers = {} } = options;
|
|
35
|
-
const url = `${config.endpoint}/api/v1${path}`;
|
|
36
|
-
const requestHeaders = {
|
|
37
|
-
'Content-Type': 'application/json',
|
|
38
|
-
...headers,
|
|
39
|
-
};
|
|
40
|
-
if (config.apiKey) {
|
|
41
|
-
requestHeaders['Authorization'] = `Bearer ${config.apiKey}`;
|
|
42
|
-
}
|
|
43
|
-
else if (config.agentId) {
|
|
44
|
-
requestHeaders['X-Agent-ID'] = config.agentId;
|
|
45
|
-
}
|
|
46
|
-
const response = await fetch(url, {
|
|
47
|
-
method,
|
|
48
|
-
headers: requestHeaders,
|
|
49
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
50
|
-
});
|
|
51
|
-
if (!response.ok) {
|
|
52
|
-
const error = await response.text();
|
|
53
|
-
throw new Error(`ThinkHive API error: ${response.status} - ${error}`);
|
|
54
|
-
}
|
|
55
|
-
return response.json();
|
|
56
|
-
}
|
|
78
|
+
let provider = null;
|
|
57
79
|
// ============================================================================
|
|
58
80
|
// INITIALIZATION
|
|
59
81
|
// ============================================================================
|
|
60
82
|
/**
|
|
61
|
-
* Initialize ThinkHive SDK
|
|
83
|
+
* Initialize ThinkHive SDK v3
|
|
62
84
|
*
|
|
63
85
|
* @example
|
|
64
86
|
* ```typescript
|
|
@@ -73,33 +95,18 @@ async function apiRequest(path, options = {}) {
|
|
|
73
95
|
* ```
|
|
74
96
|
*/
|
|
75
97
|
function init(options = {}) {
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
console.log('ThinkHive SDK already initialized');
|
|
79
|
-
}
|
|
98
|
+
if ((0, config_1.isInitialized)()) {
|
|
99
|
+
(0, config_1.debugLog)('ThinkHive SDK already initialized');
|
|
80
100
|
return;
|
|
81
101
|
}
|
|
82
|
-
const
|
|
83
|
-
const agentId = options.agentId || process.env.THINKHIVE_AGENT_ID;
|
|
84
|
-
if (!apiKey && !agentId) {
|
|
85
|
-
throw new Error("Either apiKey or agentId must be provided (or set THINKHIVE_API_KEY env var)");
|
|
86
|
-
}
|
|
87
|
-
config = {
|
|
88
|
-
apiKey: apiKey || '',
|
|
89
|
-
agentId: agentId || '',
|
|
90
|
-
endpoint: options.endpoint || process.env.THINKHIVE_ENDPOINT || DEFAULT_ENDPOINT,
|
|
91
|
-
serviceName: options.serviceName || process.env.THINKHIVE_SERVICE_NAME || 'my-ai-agent',
|
|
92
|
-
autoInstrument: options.autoInstrument ?? false,
|
|
93
|
-
frameworks: options.frameworks || ['langchain', 'openai'],
|
|
94
|
-
debug: options.debug ?? false,
|
|
95
|
-
};
|
|
102
|
+
const config = (0, config_1.initConfig)(options);
|
|
96
103
|
// Configure OTLP exporter
|
|
97
104
|
const exporterHeaders = {};
|
|
98
105
|
if (config.apiKey) {
|
|
99
|
-
exporterHeaders[
|
|
106
|
+
exporterHeaders['Authorization'] = `Bearer ${config.apiKey}`;
|
|
100
107
|
}
|
|
101
108
|
else if (config.agentId) {
|
|
102
|
-
exporterHeaders[
|
|
109
|
+
exporterHeaders['X-Agent-ID'] = config.agentId;
|
|
103
110
|
}
|
|
104
111
|
const exporter = new exporter_trace_otlp_proto_1.OTLPTraceExporter({
|
|
105
112
|
url: `${config.endpoint}/v1/traces`,
|
|
@@ -107,24 +114,25 @@ function init(options = {}) {
|
|
|
107
114
|
});
|
|
108
115
|
// Create OpenTelemetry resource
|
|
109
116
|
const resource = resources_1.Resource.default().merge(new resources_1.Resource({
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
'service.name': config.serviceName,
|
|
118
|
+
'thinkhive.sdk.version': config_1.SDK_VERSION,
|
|
119
|
+
'thinkhive.sdk.language': 'typescript',
|
|
120
|
+
'thinkhive.api.version': config.apiVersion,
|
|
113
121
|
}));
|
|
114
122
|
// Create provider with span processor
|
|
115
|
-
|
|
123
|
+
provider = new sdk_trace_node_1.NodeTracerProvider({
|
|
116
124
|
resource,
|
|
117
125
|
spanProcessors: [new sdk_trace_base_1.BatchSpanProcessor(exporter)],
|
|
118
126
|
});
|
|
119
127
|
// Register provider
|
|
120
128
|
provider.register();
|
|
121
129
|
// Get tracer
|
|
122
|
-
tracer = api_1.trace.getTracer(
|
|
123
|
-
initialized = true;
|
|
130
|
+
tracer = api_1.trace.getTracer('thinkhive', config_1.SDK_VERSION);
|
|
124
131
|
if (config.debug) {
|
|
125
|
-
console.log(`✅ ThinkHive SDK initialized`);
|
|
132
|
+
console.log(`✅ ThinkHive SDK v${config_1.SDK_VERSION} initialized`);
|
|
126
133
|
console.log(` Endpoint: ${config.endpoint}`);
|
|
127
134
|
console.log(` Service: ${config.serviceName}`);
|
|
135
|
+
console.log(` API Version: ${config.apiVersion}`);
|
|
128
136
|
console.log(` Auto-instrument: ${config.autoInstrument}`);
|
|
129
137
|
}
|
|
130
138
|
// Setup auto-instrumentation if enabled
|
|
@@ -136,48 +144,43 @@ function init(options = {}) {
|
|
|
136
144
|
* Get the global tracer
|
|
137
145
|
*/
|
|
138
146
|
function getTracer() {
|
|
139
|
-
if (!
|
|
140
|
-
throw new Error(
|
|
147
|
+
if (!tracer) {
|
|
148
|
+
throw new Error('ThinkHive SDK not initialized. Call init() first.');
|
|
141
149
|
}
|
|
142
150
|
return tracer;
|
|
143
151
|
}
|
|
144
152
|
/**
|
|
145
|
-
*
|
|
153
|
+
* Shutdown the SDK and flush pending spans
|
|
146
154
|
*/
|
|
147
|
-
function
|
|
148
|
-
|
|
155
|
+
async function shutdown() {
|
|
156
|
+
if (provider) {
|
|
157
|
+
await provider.shutdown();
|
|
158
|
+
provider = null;
|
|
159
|
+
}
|
|
160
|
+
tracer = null;
|
|
161
|
+
(0, config_1.resetConfig)();
|
|
162
|
+
(0, config_1.debugLog)('ThinkHive SDK shutdown complete');
|
|
149
163
|
}
|
|
150
164
|
// ============================================================================
|
|
151
165
|
// TRACING FUNCTIONS
|
|
152
166
|
// ============================================================================
|
|
153
167
|
/**
|
|
154
168
|
* Trace an LLM call
|
|
155
|
-
*
|
|
156
|
-
* @example
|
|
157
|
-
* ```typescript
|
|
158
|
-
* const response = await traceLLM({
|
|
159
|
-
* name: 'chat_completion',
|
|
160
|
-
* modelName: 'gpt-4',
|
|
161
|
-
* provider: 'openai',
|
|
162
|
-
* }, async () => {
|
|
163
|
-
* return await openai.chat.completions.create({ ... });
|
|
164
|
-
* });
|
|
165
|
-
* ```
|
|
166
169
|
*/
|
|
167
170
|
function traceLLM(options, fn) {
|
|
168
171
|
const t = getTracer();
|
|
169
172
|
return t.startActiveSpan(options.name, {
|
|
170
173
|
attributes: {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
174
|
+
'openinference.span.kind': 'LLM',
|
|
175
|
+
'llm.model_name': options.modelName,
|
|
176
|
+
'llm.provider': options.provider,
|
|
177
|
+
'input.value': options.input ? JSON.stringify(options.input).substring(0, 10000) : undefined,
|
|
175
178
|
},
|
|
176
179
|
}, async (span) => {
|
|
177
180
|
const startTime = Date.now();
|
|
178
181
|
try {
|
|
179
182
|
const result = await fn();
|
|
180
|
-
span.setAttribute(
|
|
183
|
+
span.setAttribute('output.value', JSON.stringify(result).substring(0, 10000));
|
|
181
184
|
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
182
185
|
return result;
|
|
183
186
|
}
|
|
@@ -188,39 +191,28 @@ function traceLLM(options, fn) {
|
|
|
188
191
|
throw error;
|
|
189
192
|
}
|
|
190
193
|
finally {
|
|
191
|
-
span.setAttribute(
|
|
194
|
+
span.setAttribute('duration_ms', Date.now() - startTime);
|
|
192
195
|
span.end();
|
|
193
196
|
}
|
|
194
197
|
});
|
|
195
198
|
}
|
|
196
199
|
/**
|
|
197
200
|
* Trace a retrieval operation
|
|
198
|
-
*
|
|
199
|
-
* @example
|
|
200
|
-
* ```typescript
|
|
201
|
-
* const docs = await traceRetrieval({
|
|
202
|
-
* name: 'vector_search',
|
|
203
|
-
* query: 'What is the return policy?',
|
|
204
|
-
* }, async () => {
|
|
205
|
-
* return await vectorStore.similaritySearch(query, 5);
|
|
206
|
-
* });
|
|
207
|
-
* ```
|
|
208
201
|
*/
|
|
209
202
|
function traceRetrieval(options, fn) {
|
|
210
203
|
const t = getTracer();
|
|
211
204
|
return t.startActiveSpan(options.name, {
|
|
212
205
|
attributes: {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
206
|
+
'openinference.span.kind': 'RETRIEVER',
|
|
207
|
+
'retrieval.query': options.query,
|
|
208
|
+
'retrieval.top_k': options.topK,
|
|
216
209
|
},
|
|
217
210
|
}, async (span) => {
|
|
218
211
|
const startTime = Date.now();
|
|
219
212
|
try {
|
|
220
213
|
const result = await fn();
|
|
221
|
-
// Try to extract document count from result
|
|
222
214
|
if (Array.isArray(result)) {
|
|
223
|
-
span.setAttribute(
|
|
215
|
+
span.setAttribute('retrieval.document_count', result.length);
|
|
224
216
|
}
|
|
225
217
|
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
226
218
|
return result;
|
|
@@ -232,38 +224,27 @@ function traceRetrieval(options, fn) {
|
|
|
232
224
|
throw error;
|
|
233
225
|
}
|
|
234
226
|
finally {
|
|
235
|
-
span.setAttribute(
|
|
227
|
+
span.setAttribute('duration_ms', Date.now() - startTime);
|
|
236
228
|
span.end();
|
|
237
229
|
}
|
|
238
230
|
});
|
|
239
231
|
}
|
|
240
232
|
/**
|
|
241
233
|
* Trace a tool call
|
|
242
|
-
*
|
|
243
|
-
* @example
|
|
244
|
-
* ```typescript
|
|
245
|
-
* const result = await traceTool({
|
|
246
|
-
* name: 'search_orders',
|
|
247
|
-
* toolName: 'OrderLookup',
|
|
248
|
-
* parameters: { orderId: '12345' },
|
|
249
|
-
* }, async () => {
|
|
250
|
-
* return await orderService.lookup('12345');
|
|
251
|
-
* });
|
|
252
|
-
* ```
|
|
253
234
|
*/
|
|
254
235
|
function traceTool(options, fn) {
|
|
255
236
|
const t = getTracer();
|
|
256
237
|
return t.startActiveSpan(options.toolName || options.name, {
|
|
257
238
|
attributes: {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
239
|
+
'openinference.span.kind': 'TOOL',
|
|
240
|
+
'tool.name': options.toolName || options.name,
|
|
241
|
+
'tool.parameters': options.parameters ? JSON.stringify(options.parameters) : undefined,
|
|
261
242
|
},
|
|
262
243
|
}, async (span) => {
|
|
263
244
|
const startTime = Date.now();
|
|
264
245
|
try {
|
|
265
246
|
const result = await fn();
|
|
266
|
-
span.setAttribute(
|
|
247
|
+
span.setAttribute('tool.output', JSON.stringify(result).substring(0, 10000));
|
|
267
248
|
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
268
249
|
return result;
|
|
269
250
|
}
|
|
@@ -274,35 +255,26 @@ function traceTool(options, fn) {
|
|
|
274
255
|
throw error;
|
|
275
256
|
}
|
|
276
257
|
finally {
|
|
277
|
-
span.setAttribute(
|
|
258
|
+
span.setAttribute('duration_ms', Date.now() - startTime);
|
|
278
259
|
span.end();
|
|
279
260
|
}
|
|
280
261
|
});
|
|
281
262
|
}
|
|
282
263
|
/**
|
|
283
264
|
* Trace a chain/workflow
|
|
284
|
-
*
|
|
285
|
-
* @example
|
|
286
|
-
* ```typescript
|
|
287
|
-
* const result = await traceChain({
|
|
288
|
-
* name: 'customer_support_chain',
|
|
289
|
-
* }, async () => {
|
|
290
|
-
* // Multiple LLM calls, tools, etc.
|
|
291
|
-
* });
|
|
292
|
-
* ```
|
|
293
265
|
*/
|
|
294
266
|
function traceChain(options, fn) {
|
|
295
267
|
const t = getTracer();
|
|
296
268
|
return t.startActiveSpan(options.name, {
|
|
297
269
|
attributes: {
|
|
298
|
-
|
|
299
|
-
|
|
270
|
+
'openinference.span.kind': 'CHAIN',
|
|
271
|
+
'input.value': options.input ? JSON.stringify(options.input).substring(0, 10000) : undefined,
|
|
300
272
|
},
|
|
301
273
|
}, async (span) => {
|
|
302
274
|
const startTime = Date.now();
|
|
303
275
|
try {
|
|
304
276
|
const result = await fn();
|
|
305
|
-
span.setAttribute(
|
|
277
|
+
span.setAttribute('output.value', JSON.stringify(result).substring(0, 10000));
|
|
306
278
|
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
307
279
|
return result;
|
|
308
280
|
}
|
|
@@ -313,327 +285,130 @@ function traceChain(options, fn) {
|
|
|
313
285
|
throw error;
|
|
314
286
|
}
|
|
315
287
|
finally {
|
|
316
|
-
span.setAttribute(
|
|
288
|
+
span.setAttribute('duration_ms', Date.now() - startTime);
|
|
317
289
|
span.end();
|
|
318
290
|
}
|
|
319
291
|
});
|
|
320
292
|
}
|
|
321
293
|
// ============================================================================
|
|
322
|
-
// EXPLAINER CLIENT
|
|
294
|
+
// V2 COMPATIBILITY - EXPLAINER CLIENT
|
|
323
295
|
// ============================================================================
|
|
324
296
|
/**
|
|
325
|
-
* Explainer API client
|
|
297
|
+
* Explainer API client (v2 compatibility)
|
|
298
|
+
* @deprecated Use runs and claims APIs instead
|
|
326
299
|
*/
|
|
327
300
|
exports.explainer = {
|
|
328
301
|
/**
|
|
329
|
-
* Analyze a trace
|
|
330
|
-
*
|
|
331
|
-
* @example
|
|
332
|
-
* ```typescript
|
|
333
|
-
* const result = await explainer.analyze({
|
|
334
|
-
* userMessage: 'Help me with my order #12345',
|
|
335
|
-
* agentResponse: 'I found your order...',
|
|
336
|
-
* outcome: 'success',
|
|
337
|
-
* spans: [
|
|
338
|
-
* { name: 'order_lookup', type: 'tool', durationMs: 150 },
|
|
339
|
-
* { name: 'gpt-4', type: 'llm', durationMs: 2500, model: 'gpt-4' },
|
|
340
|
-
* ],
|
|
341
|
-
* });
|
|
342
|
-
* ```
|
|
343
|
-
*/
|
|
344
|
-
async analyze(trace, options = {}) {
|
|
345
|
-
if (!initialized) {
|
|
346
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
347
|
-
}
|
|
348
|
-
const payload = {
|
|
349
|
-
trace: {
|
|
350
|
-
userMessage: trace.userMessage,
|
|
351
|
-
agentResponse: trace.agentResponse,
|
|
352
|
-
userIntent: trace.userIntent,
|
|
353
|
-
outcome: trace.outcome || 'success',
|
|
354
|
-
duration: trace.duration,
|
|
355
|
-
sessionId: trace.sessionId,
|
|
356
|
-
conversationHistory: trace.conversationHistory,
|
|
357
|
-
metadata: trace.metadata,
|
|
358
|
-
},
|
|
359
|
-
spans: trace.spans,
|
|
360
|
-
businessContext: trace.businessContext,
|
|
361
|
-
options: {
|
|
362
|
-
tier: options.tier,
|
|
363
|
-
includeRagEvaluation: options.includeRagEvaluation ?? true,
|
|
364
|
-
includeHallucinationCheck: options.includeHallucinationCheck ?? true,
|
|
365
|
-
},
|
|
366
|
-
};
|
|
367
|
-
if (options.waitForResult === false && options.webhookUrl) {
|
|
368
|
-
// Async analysis with webhook
|
|
369
|
-
return apiRequest('/explainer/analyze-async', {
|
|
370
|
-
method: 'POST',
|
|
371
|
-
body: { ...payload, webhookUrl: options.webhookUrl },
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
return apiRequest('/explainer/analyze', {
|
|
375
|
-
method: 'POST',
|
|
376
|
-
body: payload,
|
|
377
|
-
});
|
|
378
|
-
},
|
|
379
|
-
/**
|
|
380
|
-
* Batch analyze multiple traces
|
|
381
|
-
*
|
|
382
|
-
* @example
|
|
383
|
-
* ```typescript
|
|
384
|
-
* const results = await explainer.analyzeBatch([
|
|
385
|
-
* { userMessage: 'Q1', agentResponse: 'A1' },
|
|
386
|
-
* { userMessage: 'Q2', agentResponse: 'A2' },
|
|
387
|
-
* ]);
|
|
388
|
-
* ```
|
|
302
|
+
* Analyze a trace (v2 format)
|
|
303
|
+
* @deprecated Use runs.create() + claims.getRunAnalysis() instead
|
|
389
304
|
*/
|
|
390
|
-
async
|
|
391
|
-
|
|
392
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
393
|
-
}
|
|
394
|
-
return apiRequest('/explainer/analyze-batch', {
|
|
305
|
+
async analyze(traceData, options = {}) {
|
|
306
|
+
return (0, client_1.apiRequestWithData)('/explainer/analyze', {
|
|
395
307
|
method: 'POST',
|
|
396
308
|
body: {
|
|
397
|
-
|
|
398
|
-
userMessage:
|
|
399
|
-
agentResponse:
|
|
400
|
-
userIntent:
|
|
401
|
-
outcome:
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
309
|
+
trace: {
|
|
310
|
+
userMessage: traceData.userMessage,
|
|
311
|
+
agentResponse: traceData.agentResponse,
|
|
312
|
+
userIntent: traceData.userIntent,
|
|
313
|
+
outcome: traceData.outcome || 'success',
|
|
314
|
+
duration: traceData.duration,
|
|
315
|
+
sessionId: traceData.sessionId,
|
|
316
|
+
conversationHistory: traceData.conversationHistory,
|
|
317
|
+
metadata: traceData.metadata,
|
|
318
|
+
},
|
|
319
|
+
spans: traceData.spans,
|
|
320
|
+
businessContext: traceData.businessContext,
|
|
321
|
+
options: {
|
|
322
|
+
tier: options.tier,
|
|
323
|
+
includeRagEvaluation: options.includeRagEvaluation ?? true,
|
|
324
|
+
includeHallucinationCheck: options.includeHallucinationCheck ?? true,
|
|
325
|
+
},
|
|
407
326
|
},
|
|
327
|
+
apiVersion: 'v1',
|
|
408
328
|
});
|
|
409
329
|
},
|
|
410
330
|
/**
|
|
411
331
|
* Get a previously analyzed trace
|
|
332
|
+
* @deprecated
|
|
412
333
|
*/
|
|
413
334
|
async get(traceId) {
|
|
414
|
-
|
|
415
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
416
|
-
}
|
|
417
|
-
return apiRequest(`/explainer/${traceId}`);
|
|
335
|
+
return (0, client_1.apiRequestWithData)(`/explainer/${traceId}`, { apiVersion: 'v1' });
|
|
418
336
|
},
|
|
419
337
|
/**
|
|
420
338
|
* Search traces semantically
|
|
421
|
-
*
|
|
422
|
-
* @example
|
|
423
|
-
* ```typescript
|
|
424
|
-
* const results = await explainer.search({
|
|
425
|
-
* query: 'order refund issues',
|
|
426
|
-
* filters: { outcome: 'failure' },
|
|
427
|
-
* limit: 10,
|
|
428
|
-
* });
|
|
429
|
-
* ```
|
|
339
|
+
* @deprecated
|
|
430
340
|
*/
|
|
431
341
|
async search(params) {
|
|
432
|
-
|
|
433
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
434
|
-
}
|
|
435
|
-
return apiRequest('/explainer/search', {
|
|
342
|
+
return (0, client_1.apiRequestWithData)('/explainer/search', {
|
|
436
343
|
method: 'POST',
|
|
437
344
|
body: params,
|
|
345
|
+
apiVersion: 'v1',
|
|
438
346
|
});
|
|
439
347
|
},
|
|
440
348
|
};
|
|
441
349
|
// ============================================================================
|
|
442
|
-
// FEEDBACK CLIENT
|
|
443
|
-
// ============================================================================
|
|
444
|
-
/**
|
|
445
|
-
* Feedback API for improving analysis quality
|
|
446
|
-
*/
|
|
447
|
-
exports.feedback = {
|
|
448
|
-
/**
|
|
449
|
-
* Submit feedback for a trace
|
|
450
|
-
*
|
|
451
|
-
* @example
|
|
452
|
-
* ```typescript
|
|
453
|
-
* await feedback.submit({
|
|
454
|
-
* traceId: 'trace_123',
|
|
455
|
-
* rating: 5,
|
|
456
|
-
* wasHelpful: true,
|
|
457
|
-
* });
|
|
458
|
-
* ```
|
|
459
|
-
*/
|
|
460
|
-
async submit(options) {
|
|
461
|
-
if (!initialized) {
|
|
462
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
463
|
-
}
|
|
464
|
-
return apiRequest('/feedback', {
|
|
465
|
-
method: 'POST',
|
|
466
|
-
body: options,
|
|
467
|
-
});
|
|
468
|
-
},
|
|
469
|
-
};
|
|
470
|
-
// ============================================================================
|
|
471
|
-
// QUALITY METRICS CLIENT
|
|
472
|
-
// ============================================================================
|
|
473
|
-
/**
|
|
474
|
-
* Quality metrics API for RAG evaluation and hallucination detection
|
|
475
|
-
*/
|
|
476
|
-
exports.quality = {
|
|
477
|
-
/**
|
|
478
|
-
* Get RAG evaluation scores for a trace
|
|
479
|
-
*/
|
|
480
|
-
async getRagScores(traceId) {
|
|
481
|
-
if (!initialized) {
|
|
482
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
483
|
-
}
|
|
484
|
-
return apiRequest(`/quality/rag-scores/${traceId}`);
|
|
485
|
-
},
|
|
486
|
-
/**
|
|
487
|
-
* Get hallucination report for a trace
|
|
488
|
-
*/
|
|
489
|
-
async getHallucinationReport(traceId) {
|
|
490
|
-
if (!initialized) {
|
|
491
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
492
|
-
}
|
|
493
|
-
return apiRequest(`/quality/hallucination-report/${traceId}`);
|
|
494
|
-
},
|
|
495
|
-
/**
|
|
496
|
-
* Evaluate RAG quality for custom input
|
|
497
|
-
*/
|
|
498
|
-
async evaluateRag(input) {
|
|
499
|
-
if (!initialized) {
|
|
500
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
501
|
-
}
|
|
502
|
-
return apiRequest('/quality/evaluate-rag', {
|
|
503
|
-
method: 'POST',
|
|
504
|
-
body: input,
|
|
505
|
-
});
|
|
506
|
-
},
|
|
507
|
-
};
|
|
508
|
-
// ============================================================================
|
|
509
|
-
// ROI ANALYTICS CLIENT
|
|
510
|
-
// ============================================================================
|
|
511
|
-
/**
|
|
512
|
-
* ROI analytics API for business impact tracking
|
|
513
|
-
*/
|
|
514
|
-
exports.analytics = {
|
|
515
|
-
/**
|
|
516
|
-
* Get ROI summary for the account
|
|
517
|
-
*/
|
|
518
|
-
async getRoiSummary() {
|
|
519
|
-
if (!initialized) {
|
|
520
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
521
|
-
}
|
|
522
|
-
return apiRequest('/analytics/roi/summary');
|
|
523
|
-
},
|
|
524
|
-
/**
|
|
525
|
-
* Get ROI by agent
|
|
526
|
-
*/
|
|
527
|
-
async getRoiByAgent(agentId) {
|
|
528
|
-
if (!initialized) {
|
|
529
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
530
|
-
}
|
|
531
|
-
return apiRequest(`/analytics/roi/by-agent/${agentId}`);
|
|
532
|
-
},
|
|
533
|
-
/**
|
|
534
|
-
* Get correlation analysis
|
|
535
|
-
*/
|
|
536
|
-
async getCorrelations() {
|
|
537
|
-
if (!initialized) {
|
|
538
|
-
throw new Error("ThinkHive SDK not initialized. Call init() first.");
|
|
539
|
-
}
|
|
540
|
-
return apiRequest('/analytics/correlations');
|
|
541
|
-
},
|
|
542
|
-
};
|
|
543
|
-
// ============================================================================
|
|
544
350
|
// AUTO-INSTRUMENTATION
|
|
545
351
|
// ============================================================================
|
|
546
|
-
/**
|
|
547
|
-
* Setup auto-instrumentation for AI frameworks
|
|
548
|
-
*/
|
|
549
352
|
function setupAutoInstrumentation(frameworks) {
|
|
550
|
-
|
|
551
|
-
console.log(`Setting up auto-instrumentation for: ${frameworks.join(', ')}`);
|
|
552
|
-
}
|
|
553
|
-
// Note: Full auto-instrumentation requires framework-specific patches
|
|
554
|
-
// This is a placeholder for the instrumentation setup
|
|
555
|
-
// In production, use @opentelemetry/instrumentation-* packages
|
|
353
|
+
(0, config_1.debugLog)(`Setting up auto-instrumentation for: ${frameworks.join(', ')}`);
|
|
556
354
|
for (const framework of frameworks) {
|
|
557
355
|
try {
|
|
558
356
|
switch (framework) {
|
|
559
357
|
case 'openai':
|
|
560
|
-
|
|
358
|
+
case 'openai-assistants':
|
|
359
|
+
(0, config_1.debugLog)('OpenAI instrumentation ready (use instrumentOpenAIClient)');
|
|
561
360
|
break;
|
|
562
361
|
case 'langchain':
|
|
563
|
-
|
|
362
|
+
case 'langgraph':
|
|
363
|
+
(0, config_1.debugLog)('LangChain/LangGraph instrumentation ready (use ThinkHiveCallbackHandler)');
|
|
564
364
|
break;
|
|
565
365
|
case 'anthropic':
|
|
566
|
-
|
|
366
|
+
(0, config_1.debugLog)('Anthropic instrumentation ready');
|
|
567
367
|
break;
|
|
568
368
|
case 'llamaindex':
|
|
569
|
-
|
|
369
|
+
(0, config_1.debugLog)('LlamaIndex instrumentation ready');
|
|
370
|
+
break;
|
|
371
|
+
case 'n8n':
|
|
372
|
+
(0, config_1.debugLog)('n8n instrumentation ready');
|
|
373
|
+
break;
|
|
374
|
+
case 'voiceflow':
|
|
375
|
+
(0, config_1.debugLog)('Voiceflow instrumentation ready');
|
|
570
376
|
break;
|
|
571
377
|
}
|
|
572
378
|
}
|
|
573
379
|
catch (error) {
|
|
574
|
-
|
|
575
|
-
console.warn(`Failed to instrument ${framework}:`, error);
|
|
576
|
-
}
|
|
380
|
+
(0, config_1.debugLog)(`Failed to setup ${framework} instrumentation:`, error);
|
|
577
381
|
}
|
|
578
382
|
}
|
|
579
383
|
}
|
|
580
|
-
|
|
581
|
-
// Placeholder - would patch OpenAI client
|
|
582
|
-
if (config.debug) {
|
|
583
|
-
console.log('OpenAI instrumentation ready');
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
function instrumentLangChain() {
|
|
587
|
-
// Placeholder - would use LangChain callbacks
|
|
588
|
-
if (config.debug) {
|
|
589
|
-
console.log('LangChain instrumentation ready');
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
function instrumentAnthropic() {
|
|
593
|
-
// Placeholder - would patch Anthropic client
|
|
594
|
-
if (config.debug) {
|
|
595
|
-
console.log('Anthropic instrumentation ready');
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
function instrumentLlamaIndex() {
|
|
599
|
-
// Placeholder - would use LlamaIndex callbacks
|
|
600
|
-
if (config.debug) {
|
|
601
|
-
console.log('LlamaIndex instrumentation ready');
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
// ============================================================================
|
|
605
|
-
// CONVENIENCE FUNCTIONS
|
|
606
|
-
// ============================================================================
|
|
607
|
-
/**
|
|
608
|
-
* Create a trace and analyze it in one call
|
|
609
|
-
*
|
|
610
|
-
* @example
|
|
611
|
-
* ```typescript
|
|
612
|
-
* const { trace, analysis } = await createAndAnalyze({
|
|
613
|
-
* userMessage: 'Help me track my order',
|
|
614
|
-
* agentResponse: 'Your order is on the way...',
|
|
615
|
-
* });
|
|
616
|
-
* ```
|
|
617
|
-
*/
|
|
618
|
-
async function createAndAnalyze(traceData, options = {}) {
|
|
619
|
-
const analysis = await exports.explainer.analyze(traceData, options);
|
|
620
|
-
return { trace: traceData, analysis };
|
|
621
|
-
}
|
|
622
|
-
// ============================================================================
|
|
623
|
-
// EXPORTS
|
|
624
|
-
// ============================================================================
|
|
384
|
+
// Default export for convenience
|
|
625
385
|
exports.default = {
|
|
626
386
|
init,
|
|
627
387
|
getTracer,
|
|
628
|
-
|
|
388
|
+
shutdown,
|
|
389
|
+
isInitialized: config_1.isInitialized,
|
|
390
|
+
// Tracing
|
|
629
391
|
traceLLM,
|
|
630
392
|
traceRetrieval,
|
|
631
393
|
traceTool,
|
|
632
394
|
traceChain,
|
|
395
|
+
// API clients
|
|
396
|
+
runs: runs_1.runs,
|
|
397
|
+
claims: claims_1.claims,
|
|
398
|
+
calibration: calibration_1.calibration,
|
|
399
|
+
linking: ticket_linking_1.linking,
|
|
400
|
+
customerContext: customer_context_1.customerContext,
|
|
401
|
+
// V2 compatibility
|
|
633
402
|
explainer: exports.explainer,
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
403
|
+
// Helpers
|
|
404
|
+
generateZendeskMarker: ticket_linking_1.generateZendeskMarker,
|
|
405
|
+
parseZendeskMarker: ticket_linking_1.parseZendeskMarker,
|
|
406
|
+
linkRunToTicket: ticket_linking_1.linkRunToTicket,
|
|
407
|
+
createRunWithContext: runs_1.createRunWithContext,
|
|
408
|
+
// Utilities
|
|
409
|
+
isFact: claims_1.isFact,
|
|
410
|
+
isInference: claims_1.isInference,
|
|
411
|
+
calculateBrierScore: calibration_1.calculateBrierScore,
|
|
412
|
+
isWellCalibrated: calibration_1.isWellCalibrated,
|
|
638
413
|
};
|
|
639
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7OztHQUtHOzs7QUFnT0gsb0JBdUVDO0FBS0QsOEJBS0M7QUFLRCxzQ0FFQztBQW9CRCw0QkF1Q0M7QUFlRCx3Q0EwQ0M7QUFnQkQsOEJBcUNDO0FBY0QsZ0NBbUNDO0FBOFpELDRDQVNDO0FBdjdCRCw0Q0FBc0Y7QUFDdEYsd0ZBQTZFO0FBQzdFLHdEQUFvRDtBQUNwRCxrRUFBbUU7QUFDbkUsa0VBQW1FO0FBb0puRSwrRUFBK0U7QUFDL0UsZUFBZTtBQUNmLCtFQUErRTtBQUUvRSxJQUFJLE1BQU0sR0FBOEMsSUFBSSxDQUFDO0FBQzdELElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQztBQUN4QixJQUFJLE1BQTZCLENBQUM7QUFFbEMsTUFBTSxnQkFBZ0IsR0FBRywrQ0FBK0MsQ0FBQztBQUV6RSwrRUFBK0U7QUFDL0UsY0FBYztBQUNkLCtFQUErRTtBQUUvRSxLQUFLLFVBQVUsVUFBVSxDQUN2QixJQUFZLEVBQ1osVUFJSSxFQUFFO0lBRU4sTUFBTSxFQUFFLE1BQU0sR0FBRyxLQUFLLEVBQUUsSUFBSSxFQUFFLE9BQU8sR0FBRyxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUM7SUFFdkQsTUFBTSxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUMsUUFBUSxVQUFVLElBQUksRUFBRSxDQUFDO0lBRS9DLE1BQU0sY0FBYyxHQUEyQjtRQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1FBQ2xDLEdBQUcsT0FBTztLQUNYLENBQUM7SUFFRixJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNsQixjQUFjLENBQUMsZUFBZSxDQUFDLEdBQUcsVUFBVSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDOUQsQ0FBQztTQUFNLElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzFCLGNBQWMsQ0FBQyxZQUFZLENBQUMs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LE9BQU8sRUFBUCxlQUFPO0lBQ1AsU0FBUyxFQUFULGlCQUFTO0lBQ1QsZ0JBQWdCO0NBQ2pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoaW5rSGl2ZSBUeXBlU2NyaXB0IFNES1xuICogT3BlblRlbGVtZXRyeS1iYXNlZCBvYnNlcnZhYmlsaXR5IGZvciBBSSBhZ2VudHMgd2l0aCBFeHBsYWluZXIgaW50ZWdyYXRpb25cbiAqXG4gKiBAdmVyc2lvbiAyLjAuMFxuICovXG5cbmltcG9ydCB7IHRyYWNlLCBjb250ZXh0LCBTcGFuU3RhdHVzQ29kZSwgU3BhbiBhcyBPVGVsU3BhbiB9IGZyb20gXCJAb3BlbnRlbGVtZXRyeS9hcGlcIjtcbmltcG9ydCB7IE9UTFBUcmFjZUV4cG9ydGVyIH0gZnJvbSBcIkBvcGVudGVsZW1ldHJ5L2V4cG9ydGVyLXRyYWNlLW90bHAtcHJvdG9cIjtcbmltcG9ydCB7IFJlc291cmNlIH0gZnJvbSBcIkBvcGVudGVsZW1ldHJ5L3Jlc291cmNlc1wiO1xuaW1wb3J0IHsgTm9kZVRyYWNlclByb3ZpZGVyIH0gZnJvbSBcIkBvcGVudGVsZW1ldHJ5L3Nkay10cmFjZS1ub2RlXCI7XG5pbXBvcnQgeyBCYXRjaFNwYW5Qcm9jZXNzb3IgfSBmcm9tIFwiQG9wZW50ZWxlbWV0cnkvc2RrLXRyYWNlLWJhc2VcIjtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVFlQRVNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGludGVyZmFjZSBJbml0T3B0aW9ucyB7XG4gIC8qKiBUaGlua0hpdmUgQVBJIGtleSAoc3RhcnRzIHdpdGggdGhfKSAqL1xuICBhcGlLZXk/OiBzdHJpbmc7XG4gIC8qKiBBZ2VudCBJRCBmb3IgbGVnYWN5IGF1dGhlbnRpY2F0aW9uICovXG4gIGFnZW50SWQ/OiBzdHJpbmc7XG4gIC8qKiBUaGlua0hpdmUgQVBJIGVuZHBvaW50ICovXG4gIGVuZHBvaW50Pzogc3RyaW5nO1xuICAvKiogU2VydmljZSBuYW1lIGZvciB0cmFjZXMgKi9cbiAgc2VydmljZU5hbWU/OiBzdHJpbmc7XG4gIC8qKiBFbmFibGUgYXV0by1pbnN0cnVtZW50YXRpb24gKi9cbiAgYXV0b0luc3RydW1lbnQ/OiBib29sZWFuO1xuICAvKiogRnJhbWV3b3JrcyB0byBhdXRvLWluc3RydW1lbnQgKi9cbiAgZnJhbWV3b3Jrcz86IEFycmF5PCdsYW5nY2hhaW4nIHwgJ29wZW5haScgfCAnYW50aHJvcGljJyB8ICdsbGFtYWluZGV4Jz47XG4gIC8qKiBFbmFibGUgZGVidWcgbG9nZ2luZyAqL1xuICBkZWJ1Zz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhY2VPcHRpb25zIHtcbiAgLyoqIFVzZXIncyBtZXNzYWdlL3F1ZXJ5ICovXG4gIHVzZXJNZXNzYWdlOiBzdHJpbmc7XG4gIC8qKiBBZ2VudCdzIHJlc3BvbnNlICovXG4gIGFnZW50UmVzcG9uc2U6IHN0cmluZztcbiAgLyoqIFVzZXIncyBkZXRlY3RlZCBpbnRlbnQgKi9cbiAgdXNlckludGVudD86IHN0cmluZztcbiAgLyoqIE91dGNvbWU6IHN1Y2Nlc3MsIGZhaWx1cmUsIHBhcnRpYWxfc3VjY2VzcyAqL1xuICBvdXRjb21lPzogJ3N1Y2Nlc3MnIHwgJ2ZhaWx1cmUnIHwgJ3BhcnRpYWxfc3VjY2Vzcyc7XG4gIC8qKiBEdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMgKi9cbiAgZHVyYXRpb24/OiBudW1iZXI7XG4gIC8qKiBTZXNzaW9uIElEIGZvciBjb252ZXJzYXRpb24gdHJhY2tpbmcgKi9cbiAgc2Vzc2lvbklkPzogc3RyaW5nO1xuICAvKiogQ29udmVyc2F0aW9uIGhpc3RvcnkgKi9cbiAgY29udmVyc2F0aW9uSGlzdG9yeT86IEFycmF5PHsgcm9sZTogc3RyaW5nOyBjb250ZW50OiBzdHJpbmcgfT47XG4gIC8qKiBTcGFuIGRhdGEgZm9yIGRldGFpbGVkIGFuYWx5c2lzICovXG4gIHNwYW5zPzogU3BhbkRhdGFbXTtcbiAgLyoqIEJ1c2luZXNzIGNvbnRleHQgZm9yIFJPSSBjYWxjdWxhdGlvbiAqL1xuICBidXNpbmVzc0NvbnRleHQ/OiBCdXNpbmVzc0NvbnRleHQ7XG4gIC8qKiBDdXN0b20gbWV0YWRhdGEgKi9cbiAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTcGFuRGF0YSB7XG4gIGlkPzogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIHR5cGU6ICdsbG0nIHwgJ3Rvb2wnIHwgJ3JldHJpZXZhbCcgfCAnZW1iZWRkaW5nJyB8ICdjaGFpbicgfCAnY3VzdG9tJztcbiAgc3RhcnRUaW1lPzogRGF0ZTtcbiAgZW5kVGltZT86IERhdGU7XG4gIGR1cmF0aW9uTXM/OiBudW1iZXI7XG4gIHN0YXR1cz86ICdvaycgfCAnZXJyb3InIHwgJ3RpbWVvdXQnO1xuICBlcnJvcj86IHN0cmluZztcbiAgaW5wdXQ/OiB1bmtub3duO1xuICBvdXRwdXQ/OiB1bmtub3duO1xuICAvLyBMTE0tc3BlY2lmaWNcbiAgbW9kZWw/OiBzdHJpbmc7XG4gIHByb3ZpZGVyPzogc3RyaW5nO1xuICBwcm9tcHRUb2tlbnM/OiBudW1iZXI7XG4gIGNvbXBsZXRpb25Ub2tlbnM/OiBudW1iZXI7XG4gIC8vIFRvb2wtc3BlY2lmaWNcbiAgdG9vbE5hbWU/OiBzdHJpbmc7XG4gIHRvb2xQYXJhbWV0ZXJzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIC8vIFJldHJpZXZhbC1zcGVjaWZpY1xuICBxdWVyeT86IHN0cmluZztcbiAgZG9jdW1lbnRDb3VudD86IG51bWJlcjtcbiAgdG9wU2NvcmU/OiBudW1iZXI7XG4gIHNvdXJjZXM/OiBzdHJpbmdbXTtcbiAgLy8gQ2hpbGRyZW5cbiAgY2hpbGRyZW4/OiBTcGFuRGF0YVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1c2luZXNzQ29udGV4dCB7XG4gIC8qKiBDdXN0b21lciBJRCAqL1xuICBjdXN0b21lcklkPzogc3RyaW5nO1xuICAvKiogVHJhbnNhY3Rpb24gdmFsdWUgaW4gZG9sbGFycyAqL1xuICB0cmFuc2FjdGlvblZhbHVlPzogbnVtYmVyO1xuICAvKiogUHJpb3JpdHkgbGV2ZWwgKi9cbiAgcHJpb3JpdHk/OiAnbG93JyB8ICdtZWRpdW0nIHwgJ2hpZ2gnIHwgJ2NyaXRpY2FsJztcbiAgLyoqIERlcGFydG1lbnQgKi9cbiAgZGVwYXJ0bWVudD86IHN0cmluZztcbiAgLyoqIEluZHVzdHJ5IHZlcnRpY2FsICovXG4gIGluZHVzdHJ5Pzogc3RyaW5nO1xuICAvKiogQ3VzdG9tIGZpZWxkcyAqL1xuICBjdXN0b20/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFeHBsYWluYWJpbGl0eVJlc3VsdCB7XG4gIHRyYWNlSWQ6IHN0cmluZztcbiAgZXhwbGFpbmFiaWxpdHlJZDogc3RyaW5nO1xuICBzdW1tYXJ5OiBzdHJpbmc7XG4gIG91dGNvbWU6IHtcbiAgICB2ZXJkaWN0OiAnc3VjY2VzcycgfCAncGFydGlhbF9zdWNjZXNzJyB8ICdmYWlsdXJlJztcbiAgICBjb25maWRlbmNlOiBudW1iZXI7XG4gICAgcmVhc29uaW5nOiBzdHJpbmc7XG4gIH07XG4gIGJ1c2luZXNzSW1wYWN0OiB7XG4gICAgaW1wYWN0U2NvcmU6IG51bWJlcjtcbiAgICBjdXN0b21lclNhdGlzZmFjdGlvbjogbnVtYmVyO1xuICAgIHJldmVudWVSaXNrOiBzdHJpbmc7XG4gIH07XG4gIHJlY29tbWVuZGF0aW9uczogQXJyYXk8e1xuICAgIHByaW9yaXR5OiBzdHJpbmc7XG4gICAgY2F0ZWdvcnk6IHN0cmluZztcbiAgICBhY3Rpb246IHN0cmluZztcbiAgICBleHBlY3RlZEltcGFjdDogc3RyaW5nO1xuICB9PjtcbiAgcmFnRXZhbHVhdGlvbj86IHtcbiAgICBncm91bmRlZG5lc3M6IG51bWJlcjtcbiAgICBmYWl0aGZ1bG5lc3M6IG51bWJlcjtcbiAgICBhbnN3ZXJSZWxldmFuY2U6IG51bWJlcjtcbiAgfTtcbiAgaGFsbHVjaW5hdGlvblJlcG9ydD86IHtcbiAgICBkZXRlY3RlZDogYm9vbGVhbjtcbiAgICB0eXBlczogc3RyaW5nW107XG4gICAgc2V2ZXJpdHk6IHN0cmluZztcbiAgfTtcbiAgcHJvY2Vzc2luZ1RpbWVNczogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFuYWx5emVPcHRpb25zIHtcbiAgLyoqIEZvcmNlIGEgc3BlY2lmaWMgYW5hbHlzaXMgdGllciAqL1xuICB0aWVyPzogJ3J1bGVfYmFzZWQnIHwgJ2Zhc3RfbGxtJyB8ICdmdWxsX2xsbScgfCAnZGVlcCc7XG4gIC8qKiBJbmNsdWRlIFJBRyBldmFsdWF0aW9uICovXG4gIGluY2x1ZGVSYWdFdmFsdWF0aW9uPzogYm9vbGVhbjtcbiAgLyoqIEluY2x1ZGUgaGFsbHVjaW5hdGlvbiBkZXRlY3Rpb24gKi9cbiAgaW5jbHVkZUhhbGx1Y2luYXRpb25DaGVjaz86IGJvb2xlYW47XG4gIC8qKiBXYWl0IGZvciBhbmFseXNpcyB0byBjb21wbGV0ZSAoc3luYyBtb2RlKSAqL1xuICB3YWl0Rm9yUmVzdWx0PzogYm9vbGVhbjtcbiAgLyoqIFdlYmhvb2sgVVJMIGZvciBhc3luYyBub3RpZmljYXRpb24gKi9cbiAgd2ViaG9va1VybD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGZWVkYmFja09wdGlvbnMge1xuICAvKiogVHJhY2UgSUQgdG8gcHJvdmlkZSBmZWVkYmFjayBmb3IgKi9cbiAgdHJhY2VJZDogc3RyaW5nO1xuICAvKiogVXNlciByYXRpbmcgKDEtNSkgKi9cbiAgcmF0aW5nPzogbnVtYmVyO1xuICAvKiogV2FzIHRoZSByZXNwb25zZSBoZWxwZnVsICovXG4gIHdhc0hlbHBmdWw/OiBib29sZWFuO1xuICAvKiogU3BlY2lmaWMgaXNzdWVzIGVuY291bnRlcmVkICovXG4gIGlzc3Vlcz86IEFycmF5PCdzbG93X3Jlc3BvbnNlJyB8ICdpbmNvcnJlY3QnIHwgJ3VuaGVscGZ1bCcgfCAnaGFsbHVjaW5hdGlvbicgfCAnb2ZmX3RvcGljJyB8ICdvdGhlcic+O1xuICAvKiogRnJlZS1mb3JtIGNvbW1lbnQgKi9cbiAgY29tbWVudD86IHN0cmluZztcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gR0xPQkFMIFNUQVRFXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmxldCB0cmFjZXI6IFJldHVyblR5cGU8dHlwZW9mIHRyYWNlLmdldFRyYWNlcj4gfCBudWxsID0gbnVsbDtcbmxldCBpbml0aWFsaXplZCA9IGZhbHNlO1xubGV0IGNvbmZpZzogUmVxdWlyZWQ8SW5pdE9wdGlvbnM+O1xuXG5jb25zdCBERUZBVUxUX0VORFBPSU5UID0gXCJodHRwczovL3RoaW5raGl2ZW1pbmQtaDI1ejdwdmQzcS11Yy5hLnJ1bi5hcHBcIjtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gSFRUUCBDTElFTlRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuYXN5bmMgZnVuY3Rpb24gYXBpUmVxdWVzdDxUPihcbiAgcGF0aDogc3RyaW5nLFxuICBvcHRpb25zOiB7XG4gICAgbWV0aG9kPzogJ0dFVCcgfCAnUE9TVCcgfCAnUFVUJyB8ICdERUxFVEUnO1xuICAgIGJvZHk/OiB1bmtub3duO1xuICAgIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICB9ID0ge31cbik6IFByb21pc2U8VD4ge1xuICBjb25zdCB7IG1ldGhvZCA9ICdHRVQnLCBib2R5LCBoZWFkZXJzID0ge30gfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgdXJsID0gYCR7Y29uZmlnLmVuZHBvaW50fS9hcGkvdjEke3BhdGh9YDtcblxuICBjb25zdCByZXF1ZXN0SGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgIC4uLmhlYWRlcnMsXG4gIH07XG5cbiAgaWYgKGNvbmZpZy5hcGlLZXkpIHtcbiAgICByZXF1ZXN0SGVhZGVyc1snQXV0aG9yaXphdGlvbiddID0gYEJlYXJlciAke2NvbmZpZy5hcGlLZXl9YDtcbiAgfSBlbHNlIGlmIChjb25maWcuYWdlbnRJZCkge1xuICAgIHJlcXVlc3RIZWFkZXJzWydYLUFnZW50LUlEJ10gPSBjb25maWcuYWdlbnRJZDtcbiAgfVxuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsLCB7XG4gICAgbWV0aG9kLFxuICAgIGhlYWRlcnM6IHJlcXVlc3RIZWFkZXJzLFxuICAgIGJvZHk6IGJvZHkgPyBKU09OLnN0cmluZ2lmeShib2R5KSA6IHVuZGVmaW5lZCxcbiAgfSk7XG5cbiAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgIGNvbnN0IGVycm9yID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhpbmtIaXZlIEFQSSBlcnJvcjogJHtyZXNwb25zZS5zdGF0dXN9IC0gJHtlcnJvcn1gKTtcbiAgfVxuXG4gIHJldHVybiByZXNwb25zZS5qc29uKCkgYXMgUHJvbWlzZTxUPjtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gSU5JVElBTElaQVRJT05cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBJbml0aWFsaXplIFRoaW5rSGl2ZSBTREtcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgaW5pdCB9IGZyb20gJ0B0aGlua2hpdmUvc2RrJztcbiAqXG4gKiBpbml0KHtcbiAqICAgYXBpS2V5OiAndGhfeW91cl9hcGlfa2V5JyxcbiAqICAgc2VydmljZU5hbWU6ICdteS1haS1hZ2VudCcsXG4gKiAgIGF1dG9JbnN0cnVtZW50OiB0cnVlLFxuICogICBmcmFtZXdvcmtzOiBbJ2xhbmdjaGFpbicsICdvcGVuYWknXSxcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0KG9wdGlvbnM6IEluaXRPcHRpb25zID0ge30pOiB2b2lkIHtcbiAgaWYgKGluaXRpYWxpemVkKSB7XG4gICAgaWYgKG9wdGlvbnMuZGVidWcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdUaGlua0hpdmUgU0RLIGFscmVhZHkgaW5pdGlhbGl6ZWQnKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgYXBpS2V5ID0gb3B0aW9ucy5hcGlLZXkgfHwgcHJvY2Vzcy5lbnYuVEhJTktISVZFX0FQSV9LRVk7XG4gIGNvbnN0IGFnZW50SWQgPSBvcHRpb25zLmFnZW50SWQgfHwgcHJvY2Vzcy5lbnYuVEhJTktISVZFX0FHRU5UX0lEO1xuXG4gIGlmICghYXBpS2V5ICYmICFhZ2VudElkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiRWl0aGVyIGFwaUtleSBvciBhZ2VudElkIG11c3QgYmUgcHJvdmlkZWQgKG9yIHNldCBUSElOS0hJVkVfQVBJX0tFWSBlbnYgdmFyKVwiKTtcbiAgfVxuXG4gIGNvbmZpZyA9IHtcbiAgICBhcGlLZXk6IGFwaUtleSB8fCAnJyxcbiAgICBhZ2VudElkOiBhZ2VudElkIHx8ICcnLFxuICAgIGVuZHBvaW50OiBvcHRpb25zLmVuZHBvaW50IHx8IHByb2Nlc3MuZW52LlRISU5LSElWRV9FTkRQT0lOVCB8fCBERUZBVUxUX0VORFBPSU5ULFxuICAgIHNlcnZpY2VOYW1lOiBvcHRpb25zLnNlcnZpY2VOYW1lIHx8IHByb2Nlc3MuZW52LlRISU5LSElWRV9TRVJWSUNFX05BTUUgfHwgJ215LWFpLWFnZW50JyxcbiAgICBhdXRvSW5zdHJ1bWVudDogb3B0aW9ucy5hdXRvSW5zdHJ1bWVudCA/PyBmYWxzZSxcbiAgICBmcmFtZXdvcmtzOiBvcHRpb25zLmZyYW1ld29ya3MgfHwgWydsYW5nY2hhaW4nLCAnb3BlbmFpJ10sXG4gICAgZGVidWc6IG9wdGlvbnMuZGVidWcgPz8gZmFsc2UsXG4gIH07XG5cbiAgLy8gQ29uZmlndXJlIE9UTFAgZXhwb3J0ZXJcbiAgY29uc3QgZXhwb3J0ZXJIZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIGlmIChjb25maWcuYXBpS2V5KSB7XG4gICAgZXhwb3J0ZXJIZWFkZXJzW1wiQXV0aG9yaXphdGlvblwiXSA9IGBCZWFyZXIgJHtjb25maWcuYXBpS2V5fWA7XG4gIH0gZWxzZSBpZiAoY29uZmlnLmFnZW50SWQpIHtcbiAgICBleHBvcnRlckhlYWRlcnNbXCJYLUFnZW50LUlEXCJdID0gY29uZmlnLmFnZW50SWQ7XG4gIH1cblxuICBjb25zdCBleHBvcnRlciA9IG5ldyBPVExQVHJhY2VFeHBvcnRlcih7XG4gICAgdXJsOiBgJHtjb25maWcuZW5kcG9pbnR9L3YxL3RyYWNlc2AsXG4gICAgaGVhZGVyczogZXhwb3J0ZXJIZWFkZXJzLFxuICB9KTtcblxuICAvLyBDcmVhdGUgT3BlblRlbGVtZXRyeSByZXNvdXJjZVxuICBjb25zdCByZXNvdXJjZSA9IFJlc291cmNlLmRlZmF1bHQoKS5tZXJnZShcbiAgICBuZXcgUmVzb3VyY2Uoe1xuICAgICAgXCJzZXJ2aWNlLm5hbWVcIjogY29uZmlnLnNlcnZpY2VOYW1lLFxuICAgICAgXCJ0aGlua2hpdmUuc2RrLnZlcnNpb25cIjogXCIyLjAuMFwiLFxuICAgICAgXCJ0aGlua2hpdmUuc2RrLmxhbmd1YWdlXCI6IFwidHlwZXNjcmlwdFwiLFxuICAgIH0pXG4gICk7XG5cbiAgLy8gQ3JlYXRlIHByb3ZpZGVyIHdpdGggc3BhbiBwcm9jZXNzb3JcbiAgY29uc3QgcHJvdmlkZXIgPSBuZXcgTm9kZVRyYWNlclByb3ZpZGVyKHtcbiAgICByZXNvdXJjZSxcbiAgICBzcGFuUHJvY2Vzc29yczogW25ldyBCYXRjaFNwYW5Qcm9jZXNzb3IoZXhwb3J0ZXIpXSxcbiAgfSk7XG5cbiAgLy8gUmVnaXN0ZXIgcHJvdmlkZXJcbiAgcHJvdmlkZXIucmVnaXN0ZXIoKTtcblxuICAvLyBHZXQgdHJhY2VyXG4gIHRyYWNlciA9IHRyYWNlLmdldFRyYWNlcihcInRoaW5raGl2ZVwiLCBcIjIuMC4wXCIpO1xuICBpbml0aWFsaXplZCA9IHRydWU7XG5cbiAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgIGNvbnNvbGUubG9nKGDinIUgVGhpbmtIaXZlIFNESyBpbml0aWFsaXplZGApO1xuICAgIGNvbnNvbGUubG9nKGAgICBFbmRwb2ludDogJHtjb25maWcuZW5kcG9pbnR9YCk7XG4gICAgY29uc29sZS5sb2coYCAgIFNlcnZpY2U6ICR7Y29uZmlnLnNlcnZpY2VOYW1lfWApO1xuICAgIGNvbnNvbGUubG9nKGAgICBBdXRvLWluc3RydW1lbnQ6ICR7Y29uZmlnLmF1dG9JbnN0cnVtZW50fWApO1xuICB9XG5cbiAgLy8gU2V0dXAgYXV0by1pbnN0cnVtZW50YXRpb24gaWYgZW5hYmxlZFxuICBpZiAoY29uZmlnLmF1dG9JbnN0cnVtZW50KSB7XG4gICAgc2V0dXBBdXRvSW5zdHJ1bWVudGF0aW9uKGNvbmZpZy5mcmFtZXdvcmtzKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgZ2xvYmFsIHRyYWNlclxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJhY2VyKCkge1xuICBpZiAoIWluaXRpYWxpemVkIHx8ICF0cmFjZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlua0hpdmUgU0RLIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0KCkgZmlyc3QuXCIpO1xuICB9XG4gIHJldHVybiB0cmFjZXI7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgU0RLIGlzIGluaXRpYWxpemVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0luaXRpYWxpemVkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gaW5pdGlhbGl6ZWQ7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRSQUNJTkcgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogVHJhY2UgYW4gTExNIGNhbGxcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0cmFjZUxMTSh7XG4gKiAgIG5hbWU6ICdjaGF0X2NvbXBsZXRpb24nLFxuICogICBtb2RlbE5hbWU6ICdncHQtNCcsXG4gKiAgIHByb3ZpZGVyOiAnb3BlbmFpJyxcbiAqIH0sIGFzeW5jICgpID0+IHtcbiAqICAgcmV0dXJuIGF3YWl0IG9wZW5haS5jaGF0LmNvbXBsZXRpb25zLmNyZWF0ZSh7IC4uLiB9KTtcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFjZUxMTTxUPihcbiAgb3B0aW9uczoge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBtb2RlbE5hbWU/OiBzdHJpbmc7XG4gICAgcHJvdmlkZXI/OiBzdHJpbmc7XG4gICAgaW5wdXQ/OiB1bmtub3duO1xuICB9LFxuICBmbjogKCkgPT4gUHJvbWlzZTxUPlxuKTogUHJvbWlzZTxUPiB7XG4gIGNvbnN0IHQgPSBnZXRUcmFjZXIoKTtcblxuICByZXR1cm4gdC5zdGFydEFjdGl2ZVNwYW4oXG4gICAgb3B0aW9ucy5uYW1lLFxuICAgIHtcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgXCJvcGVuaW5mZXJlbmNlLnNwYW4ua2luZFwiOiBcIkxMTVwiLFxuICAgICAgICBcImxsbS5tb2RlbF9uYW1lXCI6IG9wdGlvbnMubW9kZWxOYW1lLFxuICAgICAgICBcImxsbS5wcm92aWRlclwiOiBvcHRpb25zLnByb3ZpZGVyLFxuICAgICAgICBcImlucHV0LnZhbHVlXCI6IG9wdGlvbnMuaW5wdXQgPyBKU09OLnN0cmluZ2lmeShvcHRpb25zLmlucHV0KS5zdWJzdHJpbmcoMCwgMTAwMDApIDogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICB9LFxuICAgIGFzeW5jIChzcGFuKSA9PiB7XG4gICAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZm4oKTtcbiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoXCJvdXRwdXQudmFsdWVcIiwgSlNPTi5zdHJpbmdpZnkocmVzdWx0KS5zdWJzdHJpbmcoMCwgMTAwMDApKTtcbiAgICAgICAgc3Bhbi5zZXRTdGF0dXMoeyBjb2RlOiBTcGFuU3RhdHVzQ29kZS5PSyB9KTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgICAgIHNwYW4uc2V0U3RhdHVzKHsgY29kZTogU3BhblN0YXR1c0NvZGUuRVJST1IsIG1lc3NhZ2UgfSk7XG4gICAgICAgIHNwYW4ucmVjb3JkRXhjZXB0aW9uKGVycm9yIGFzIEVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZShcImR1cmF0aW9uX21zXCIsIERhdGUubm93KCkgLSBzdGFydFRpbWUpO1xuICAgICAgICBzcGFuLmVuZCgpO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBUcmFjZSBhIHJldHJpZXZhbCBvcGVyYXRpb25cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZG9jcyA9IGF3YWl0IHRyYWNlUmV0cmlldmFsKHtcbiAqICAgbmFtZTogJ3ZlY3Rvcl9zZWFyY2gnLFxuICogICBxdWVyeTogJ1doYXQgaXMgdGhlIHJldHVybiBwb2xpY3k/JyxcbiAqIH0sIGFzeW5jICgpID0+IHtcbiAqICAgcmV0dXJuIGF3YWl0IHZlY3RvclN0b3JlLnNpbWlsYXJpdHlTZWFyY2gocXVlcnksIDUpO1xuICogfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYWNlUmV0cmlldmFsPFQ+KFxuICBvcHRpb25zOiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHF1ZXJ5Pzogc3RyaW5nO1xuICAgIHRvcEs/OiBudW1iZXI7XG4gIH0sXG4gIGZuOiAoKSA9PiBQcm9taXNlPFQ+XG4pOiBQcm9taXNlPFQ+IHtcbiAgY29uc3QgdCA9IGdldFRyYWNlcigpO1xuXG4gIHJldHVybiB0LnN0YXJ0QWN0aXZlU3BhbihcbiAgICBvcHRpb25zLm5hbWUsXG4gICAge1xuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICBcIm9wZW5pbmZlcmVuY2Uuc3Bhbi5raW5kXCI6IFwiUkVUUklFVkVSXCIsXG4gICAgICAgIFwicmV0cmlldmFsLnF1ZXJ5XCI6IG9wdGlvbnMucXVlcnksXG4gICAgICAgIFwicmV0cmlldmFsLnRvcF9rXCI6IG9wdGlvbnMudG9wSyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBhc3luYyAoc3BhbikgPT4ge1xuICAgICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZuKCk7XG5cbiAgICAgICAgLy8gVHJ5IHRvIGV4dHJhY3QgZG9jdW1lbnQgY291bnQgZnJvbSByZXN1bHRcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVzdWx0KSkge1xuICAgICAgICAgIHNwYW4uc2V0QXR0cmlidXRlKFwicmV0cmlldmFsLmRvY3VtZW50X2NvdW50XCIsIHJlc3VsdC5sZW5ndGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3Bhbi5zZXRTdGF0dXMoeyBjb2RlOiBTcGFuU3RhdHVzQ29kZS5PSyB9KTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgICAgIHNwYW4uc2V0U3RhdHVzKHsgY29kZTogU3BhblN0YXR1c0NvZGUuRVJST1IsIG1lc3NhZ2UgfSk7XG4gICAgICAgIHNwYW4ucmVjb3JkRXhjZXB0aW9uKGVycm9yIGFzIEVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZShcImR1cmF0aW9uX21zXCIsIERhdGUubm93KCkgLSBzdGFydFRpbWUpO1xuICAgICAgICBzcGFuLmVuZCgpO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBUcmFjZSBhIHRvb2wgY2FsbFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXN1bHQgPSBhd2FpdCB0cmFjZVRvb2woe1xuICogICBuYW1lOiAnc2VhcmNoX29yZGVycycsXG4gKiAgIHRvb2xOYW1lOiAnT3JkZXJMb29rdXAnLFxuICogICBwYXJhbWV0ZXJzOiB7IG9yZGVySWQ6ICcxMjM0NScgfSxcbiAqIH0sIGFzeW5jICgpID0+IHtcbiAqICAgcmV0dXJuIGF3YWl0IG9yZGVyU2VydmljZS5sb29rdXAoJzEyMzQ1Jyk7XG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhY2VUb29sPFQ+KFxuICBvcHRpb25zOiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHRvb2xOYW1lPzogc3RyaW5nO1xuICAgIHBhcmFtZXRlcnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgfSxcbiAgZm46ICgpID0+IFByb21pc2U8VD5cbik6IFByb21pc2U8VD4ge1xuICBjb25zdCB0ID0gZ2V0VHJhY2VyKCk7XG5cbiAgcmV0dXJuIHQuc3RhcnRBY3RpdmVTcGFuKFxuICAgIG9wdGlvbnMudG9vbE5hbWUgfHwgb3B0aW9ucy5uYW1lLFxuICAgIHtcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgXCJvcGVuaW5mZXJlbmNlLnNwYW4ua2luZFwiOiBcIlRPT0xcIixcbiAgICAgICAgXCJ0b29sLm5hbWVcIjogb3B0aW9ucy50b29sTmFtZSB8fCBvcHRpb25zLm5hbWUsXG4gICAgICAgIFwidG9vbC5wYXJhbWV0ZXJzXCI6IG9wdGlvbnMucGFyYW1ldGVycyA/IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMucGFyYW1ldGVycykgOiB1bmRlZmluZWQsXG4gICAgICB9LFxuICAgIH0sXG4gICAgYXN5bmMgKHNwYW4pID0+IHtcbiAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmbigpO1xuICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZShcInRvb2wub3V0cHV0XCIsIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkuc3Vic3RyaW5nKDAsIDEwMDAwKSk7XG4gICAgICAgIHNwYW4uc2V0U3RhdHVzKHsgY29kZTogU3BhblN0YXR1c0NvZGUuT0sgfSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgICAgICBzcGFuLnNldFN0YXR1cyh7IGNvZGU6IFNwYW5TdGF0dXNDb2RlLkVSUk9SLCBtZXNzYWdlIH0pO1xuICAgICAgICBzcGFuLnJlY29yZEV4Y2VwdGlvbihlcnJvciBhcyBFcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoXCJkdXJhdGlvbl9tc1wiLCBEYXRlLm5vdygpIC0gc3RhcnRUaW1lKTtcbiAgICAgICAgc3Bhbi5lbmQoKTtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59XG5cbi8qKlxuICogVHJhY2UgYSBjaGFpbi93b3JrZmxvd1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXN1bHQgPSBhd2FpdCB0cmFjZUNoYWluKHtcbiAqICAgbmFtZTogJ2N1c3RvbWVyX3N1cHBvcnRfY2hhaW4nLFxuICogfSwgYXN5bmMgKCkgPT4ge1xuICogICAvLyBNdWx0aXBsZSBMTE0gY2FsbHMsIHRvb2xzLCBldGMuXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhY2VDaGFpbjxUPihcbiAgb3B0aW9uczoge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBpbnB1dD86IHVua25vd247XG4gIH0sXG4gIGZuOiAoKSA9PiBQcm9taXNlPFQ+XG4pOiBQcm9taXNlPFQ+IHtcbiAgY29uc3QgdCA9IGdldFRyYWNlcigpO1xuXG4gIHJldHVybiB0LnN0YXJ0QWN0aXZlU3BhbihcbiAgICBvcHRpb25zLm5hbWUsXG4gICAge1xuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICBcIm9wZW5pbmZlcmVuY2Uuc3Bhbi5raW5kXCI6IFwiQ0hBSU5cIixcbiAgICAgICAgXCJpbnB1dC52YWx1ZVwiOiBvcHRpb25zLmlucHV0ID8gSlNPTi5zdHJpbmdpZnkob3B0aW9ucy5pbnB1dCkuc3Vic3RyaW5nKDAsIDEwMDAwKSA6IHVuZGVmaW5lZCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBhc3luYyAoc3BhbikgPT4ge1xuICAgICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZuKCk7XG4gICAgICAgIHNwYW4uc2V0QXR0cmlidXRlKFwib3V0cHV0LnZhbHVlXCIsIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkuc3Vic3RyaW5nKDAsIDEwMDAwKSk7XG4gICAgICAgIHNwYW4uc2V0U3RhdHVzKHsgY29kZTogU3BhblN0YXR1c0NvZGUuT0sgfSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgICAgICBzcGFuLnNldFN0YXR1cyh7IGNvZGU6IFNwYW5TdGF0dXNDb2RlLkVSUk9SLCBtZXNzYWdlIH0pO1xuICAgICAgICBzcGFuLnJlY29yZEV4Y2VwdGlvbihlcnJvciBhcyBFcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoXCJkdXJhdGlvbl9tc1wiLCBEYXRlLm5vdygpIC0gc3RhcnRUaW1lKTtcbiAgICAgICAgc3Bhbi5lbmQoKTtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEVYUExBSU5FUiBDTElFTlRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBFeHBsYWluZXIgQVBJIGNsaWVudCBmb3IgdHJhY2UgYW5hbHlzaXNcbiAqL1xuZXhwb3J0IGNvbnN0IGV4cGxhaW5lciA9IHtcbiAgLyoqXG4gICAqIEFuYWx5emUgYSB0cmFjZSBhbmQgZ2V0IGV4cGxhaW5hYmlsaXR5IGluc2lnaHRzXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgZXhwbGFpbmVyLmFuYWx5emUoe1xuICAgKiAgIHVzZXJNZXNzYWdlOiAnSGVscCBtZSB3aXRoIG15IG9yZGVyICMxMjM0NScsXG4gICAqICAgYWdlbnRSZXNwb25zZTogJ0kgZm91bmQgeW91ciBvcmRlci4uLicsXG4gICAqICAgb3V0Y29tZTogJ3N1Y2Nlc3MnLFxuICAgKiAgIHNwYW5zOiBbXG4gICAqICAgICB7IG5hbWU6ICdvcmRlcl9sb29rdXAnLCB0eXBlOiAndG9vbCcsIGR1cmF0aW9uTXM6IDE1MCB9LFxuICAgKiAgICAgeyBuYW1lOiAnZ3B0LTQnLCB0eXBlOiAnbGxtJywgZHVyYXRpb25NczogMjUwMCwgbW9kZWw6ICdncHQtNCcgfSxcbiAgICogICBdLFxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBhbmFseXplKFxuICAgIHRyYWNlOiBUcmFjZU9wdGlvbnMsXG4gICAgb3B0aW9uczogQW5hbHl6ZU9wdGlvbnMgPSB7fVxuICApOiBQcm9taXNlPEV4cGxhaW5hYmlsaXR5UmVzdWx0PiB7XG4gICAgaWYgKCFpbml0aWFsaXplZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpbmtIaXZlIFNESyBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LlwiKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgdHJhY2U6IHtcbiAgICAgICAgdXNlck1lc3NhZ2U6IHRyYWNlLnVzZXJNZXNzYWdlLFxuICAgICAgICBhZ2VudFJlc3BvbnNlOiB0cmFjZS5hZ2VudFJlc3BvbnNlLFxuICAgICAgICB1c2VySW50ZW50OiB0cmFjZS51c2VySW50ZW50LFxuICAgICAgICBvdXRjb21lOiB0cmFjZS5vdXRjb21lIHx8ICdzdWNjZXNzJyxcbiAgICAgICAgZHVyYXRpb246IHRyYWNlLmR1cmF0aW9uLFxuICAgICAgICBzZXNzaW9uSWQ6IHRyYWNlLnNlc3Npb25JZCxcbiAgICAgICAgY29udmVyc2F0aW9uSGlzdG9yeTogdHJhY2UuY29udmVyc2F0aW9uSGlzdG9yeSxcbiAgICAgICAgbWV0YWRhdGE6IHRyYWNlLm1ldGFkYXRhLFxuICAgICAgfSxcbiAgICAgIHNwYW5zOiB0cmFjZS5zcGFucyxcbiAgICAgIGJ1c2luZXNzQ29udGV4dDogdHJhY2UuYnVzaW5lc3NDb250ZXh0LFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICB0aWVyOiBvcHRpb25zLnRpZXIsXG4gICAgICAgIGluY2x1ZGVSYWdFdmFsdWF0aW9uOiBvcHRpb25zLmluY2x1ZGVSYWdFdmFsdWF0aW9uID8/IHRydWUsXG4gICAgICAgIGluY2x1ZGVIYWxsdWNpbmF0aW9uQ2hlY2s6IG9wdGlvbnMuaW5jbHVkZUhhbGx1Y2luYXRpb25DaGVjayA/PyB0cnVlLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgaWYgKG9wdGlvbnMud2FpdEZvclJlc3VsdCA9PT0gZmFsc2UgJiYgb3B0aW9ucy53ZWJob29rVXJsKSB7XG4gICAgICAvLyBBc3luYyBhbmFseXNpcyB3aXRoIHdlYmhvb2tcbiAgICAgIHJldHVybiBhcGlSZXF1ZXN0PEV4cGxhaW5hYmlsaXR5UmVzdWx0PignL2V4cGxhaW5lci9hbmFseXplLWFzeW5jJywge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYm9keTogeyAuLi5wYXlsb2FkLCB3ZWJob29rVXJsOiBvcHRpb25zLndlYmhvb2tVcmwgfSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBhcGlSZXF1ZXN0PEV4cGxhaW5hYmlsaXR5UmVzdWx0PignL2V4cGxhaW5lci9hbmFseXplJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBwYXlsb2FkLFxuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiBCYXRjaCBhbmFseXplIG11bHRpcGxlIHRyYWNlc1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBleHBsYWluZXIuYW5hbHl6ZUJhdGNoKFtcbiAgICogICB7IHVzZXJNZXNzYWdlOiAnUTEnLCBhZ2VudFJlc3BvbnNlOiAnQTEnIH0sXG4gICAqICAgeyB1c2VyTWVzc2FnZTogJ1EyJywgYWdlbnRSZXNwb25zZTogJ0EyJyB9LFxuICAgKiBdKTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBhbmFseXplQmF0Y2goXG4gICAgdHJhY2VzOiBUcmFjZU9wdGlvbnNbXSxcbiAgICBvcHRpb25zOiBBbmFseXplT3B0aW9ucyA9IHt9XG4gICk6IFByb21pc2U8e1xuICAgIHJlc3VsdHM6IEV4cGxhaW5hYmlsaXR5UmVzdWx0W107XG4gICAgc3VtbWFyeToge1xuICAgICAgdG90YWw6IG51bWJlcjtcbiAgICAgIHN1Y2Nlc3NDb3VudDogbnVtYmVyO1xuICAgICAgZmFpbHVyZUNvdW50OiBudW1iZXI7XG4gICAgICBhdmVyYWdlUHJvY2Vzc2luZ1RpbWU6IG51bWJlcjtcbiAgICB9O1xuICB9PiB7XG4gICAgaWYgKCFpbml0aWFsaXplZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpbmtIaXZlIFNESyBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LlwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXBpUmVxdWVzdCgnL2V4cGxhaW5lci9hbmFseXplLWJhdGNoJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiB7XG4gICAgICAgIHRyYWNlczogdHJhY2VzLm1hcCh0ID0+ICh7XG4gICAgICAgICAgdXNlck1lc3NhZ2U6IHQudXNlck1lc3NhZ2UsXG4gICAgICAgICAgYWdlbnRSZXNwb25zZTogdC5hZ2VudFJlc3BvbnNlLFxuICAgICAgICAgIHVzZXJJbnRlbnQ6IHQudXNlckludGVudCxcbiAgICAgICAgICBvdXRjb21lOiB0Lm91dGNvbWUgfHwgJ3N1Y2Nlc3MnLFxuICAgICAgICAgIHNwYW5zOiB0LnNwYW5zLFxuICAgICAgICAgIGJ1c2luZXNzQ29udGV4dDogdC5idXNpbmVzc0NvbnRleHQsXG4gICAgICAgICAgbWV0YWRhdGE6IHQubWV0YWRhdGEsXG4gICAgICAgIH0pKSxcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhIHByZXZpb3VzbHkgYW5hbHl6ZWQgdHJhY2VcbiAgICovXG4gIGFzeW5jIGdldCh0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPEV4cGxhaW5hYmlsaXR5UmVzdWx0PiB7XG4gICAgaWYgKCFpbml0aWFsaXplZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpbmtIaXZlIFNESyBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LlwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXBpUmVxdWVzdDxFeHBsYWluYWJpbGl0eVJlc3VsdD4oYC9leHBsYWluZXIvJHt0cmFjZUlkfWApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBTZWFyY2ggdHJhY2VzIHNlbWFudGljYWxseVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBleHBsYWluZXIuc2VhcmNoKHtcbiAgICogICBxdWVyeTogJ29yZGVyIHJlZnVuZCBpc3N1ZXMnLFxuICAgKiAgIGZpbHRlcnM6IHsgb3V0Y29tZTogJ2ZhaWx1cmUnIH0sXG4gICAqICAgbGltaXQ6IDEwLFxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBzZWFyY2gocGFyYW1zOiB7XG4gICAgcXVlcnk6IHN0cmluZztcbiAgICBmaWx0ZXJzPzoge1xuICAgICAgb3V0Y29tZT86ICdzdWNjZXNzJyB8ICdmYWlsdXJlJyB8ICdwYXJ0aWFsX3N1Y2Nlc3MnO1xuICAgICAgbWluSW1wYWN0U2NvcmU/OiBudW1iZXI7XG4gICAgICBkYXRlUmFuZ2U/OiB7IGZyb206IERhdGU7IHRvOiBEYXRlIH07XG4gICAgfTtcbiAgICBsaW1pdD86IG51bWJlcjtcbiAgfSk6IFByb21pc2U8e1xuICAgIHJlc3VsdHM6IEFycmF5PEV4cGxhaW5hYmlsaXR5UmVzdWx0ICYgeyBzaW1pbGFyaXR5OiBudW1iZXIgfT47XG4gICAgdG90YWw6IG51bWJlcjtcbiAgfT4ge1xuICAgIGlmICghaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaW5rSGl2ZSBTREsgbm90IGluaXRpYWxpemVkLiBDYWxsIGluaXQoKSBmaXJzdC5cIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFwaVJlcXVlc3QoJy9leHBsYWluZXIvc2VhcmNoJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBwYXJhbXMsXG4gICAgfSk7XG4gIH0sXG59O1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBGRUVEQkFDSyBDTElFTlRcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBGZWVkYmFjayBBUEkgZm9yIGltcHJvdmluZyBhbmFseXNpcyBxdWFsaXR5XG4gKi9cbmV4cG9ydCBjb25zdCBmZWVkYmFjayA9IHtcbiAgLyoqXG4gICAqIFN1Ym1pdCBmZWVkYmFjayBmb3IgYSB0cmFjZVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGF3YWl0IGZlZWRiYWNrLnN1Ym1pdCh7XG4gICAqICAgdHJhY2VJZDogJ3RyYWNlXzEyMycsXG4gICAqICAgcmF0aW5nOiA1LFxuICAgKiAgIHdhc0hlbHBmdWw6IHRydWUsXG4gICAqIH0pO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIHN1Ym1pdChvcHRpb25zOiBGZWVkYmFja09wdGlvbnMpOiBQcm9taXNlPHsgc3VjY2VzczogYm9vbGVhbiB9PiB7XG4gICAgaWYgKCFpbml0aWFsaXplZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpbmtIaXZlIFNESyBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LlwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXBpUmVxdWVzdCgnL2ZlZWRiYWNrJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBvcHRpb25zLFxuICAgIH0pO1xuICB9LFxufTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gUVVBTElUWSBNRVRSSUNTIENMSUVOVFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFF1YWxpdHkgbWV0cmljcyBBUEkgZm9yIFJBRyBldmFsdWF0aW9uIGFuZCBoYWxsdWNpbmF0aW9uIGRldGVjdGlvblxuICovXG5leHBvcnQgY29uc3QgcXVhbGl0eSA9IHtcbiAgLyoqXG4gICAqIEdldCBSQUcgZXZhbHVhdGlvbiBzY29yZXMgZm9yIGEgdHJhY2VcbiAgICovXG4gIGFzeW5jIGdldFJhZ1Njb3Jlcyh0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPHtcbiAgICBjb250ZXh0UmVsZXZhbmNlOiBudW1iZXI7XG4gICAgY29udGV4dFByZWNpc2lvbjogbnVtYmVyO1xuICAgIGNvbnRleHRSZWNhbGw6IG51bWJlcjtcbiAgICBncm91bmRlZG5lc3M6IG51bWJlcjtcbiAgICBmYWl0aGZ1bG5lc3M6IG51bWJlcjtcbiAgICBhbnN3ZXJSZWxldmFuY2U6IG51bWJlcjtcbiAgICBjaXRhdGlvbkFjY3VyYWN5OiBudW1iZXI7XG4gICAgY2l0YXRpb25Db21wbGV0ZW5lc3M6IG51bWJlcjtcbiAgICBvdmVyYWxsR3JhZGU6IHN0cmluZztcbiAgfT4ge1xuICAgIGlmICghaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaW5rSGl2ZSBTREsgbm90IGluaXRpYWxpemVkLiBDYWxsIGluaXQoKSBmaXJzdC5cIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFwaVJlcXVlc3QoYC9xdWFsaXR5L3JhZy1zY29yZXMvJHt0cmFjZUlkfWApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZXQgaGFsbHVjaW5hdGlvbiByZXBvcnQgZm9yIGEgdHJhY2VcbiAgICovXG4gIGFzeW5jIGdldEhhbGx1Y2luYXRpb25SZXBvcnQodHJhY2VJZDogc3RyaW5nKTogUHJvbWlzZTx7XG4gICAgaGFzSGFsbHVjaW5hdGlvbnM6IGJvb2xlYW47XG4gICAgc2V2ZXJpdHk6ICdub25lJyB8ICdsb3cnIHwgJ21lZGl1bScgfCAnaGlnaCc7XG4gICAgY29uZmlkZW5jZTogbnVtYmVyO1xuICAgIGRldGVjdGVkVHlwZXM6IEFycmF5PHtcbiAgICAgIHR5cGU6IHN0cmluZztcbiAgICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgICBldmlkZW5jZTogc3RyaW5nO1xuICAgICAgc2V2ZXJpdHk6IHN0cmluZztcbiAgICB9PjtcbiAgfT4ge1xuICAgIGlmICghaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaW5rSGl2ZSBTREsgbm90IGluaXRpYWxpemVkLiBDYWxsIGluaXQoKSBmaXJzdC5cIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFwaVJlcXVlc3QoYC9xdWFsaXR5L2hhbGx1Y2luYXRpb24tcmVwb3J0LyR7dHJhY2VJZH1gKTtcbiAgfSxcblxuICAvKipcbiAgICogRXZhbHVhdGUgUkFHIHF1YWxpdHkgZm9yIGN1c3RvbSBpbnB1dFxuICAgKi9cbiAgYXN5bmMgZXZhbHVhdGVSYWcoaW5wdXQ6IHtcbiAgICBxdWVyeTogc3RyaW5nO1xuICAgIHJlc3BvbnNlOiBzdHJpbmc7XG4gICAgY29udGV4dHM6IEFycmF5PHsgY29udGVudDogc3RyaW5nOyBzb3VyY2U/OiBzdHJpbmc7IHNjb3JlPzogbnVtYmVyIH0+O1xuICB9KTogUHJvbWlzZTx7XG4gICAgc2NvcmVzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+O1xuICAgIGdyYWRlOiBzdHJpbmc7XG4gICAgZ3JvdW5kZWRTcGFuczogc3RyaW5nW107XG4gICAgdW5ncm91bmRlZFNwYW5zOiBzdHJpbmdbXTtcbiAgfT4ge1xuICAgIGlmICghaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaW5rSGl2ZSBTREsgbm90IGluaXRpYWxpemVkLiBDYWxsIGluaXQoKSBmaXJzdC5cIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFwaVJlcXVlc3QoJy9xdWFsaXR5L2V2YWx1YXRlLXJhZycsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgYm9keTogaW5wdXQsXG4gICAgfSk7XG4gIH0sXG59O1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBST0kgQU5BTFlUSUNTIENMSUVOVFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFJPSSBhbmFseXRpY3MgQVBJIGZvciBidXNpbmVzcyBpbXBhY3QgdHJhY2tpbmdcbiAqL1xuZXhwb3J0IGNvbnN0IGFuYWx5dGljcyA9IHtcbiAgLyoqXG4gICAqIEdldCBST0kgc3VtbWFyeSBmb3IgdGhlIGFjY291bnRcbiAgICovXG4gIGFzeW5jIGdldFJvaVN1bW1hcnkoKTogUHJvbWlzZTx7XG4gICAgdG90YWxSZXZlbnVlU2F2ZWQ6IG51bWJlcjtcbiAgICBzdXBwb3J0Q29zdFJlZHVjdGlvbjogbnVtYmVyO1xuICAgIGF2ZXJhZ2VSZXNvbHV0aW9uVGltZTogbnVtYmVyO1xuICAgIGN1c3RvbWVyU2F0aXNmYWN0aW9uOiBudW1iZXI7XG4gICAgdHJlbmRzOiBBcnJheTx7XG4gICAgICBkYXRlOiBzdHJpbmc7XG4gICAgICByZXZlbnVlU2F2ZWQ6IG51bWJlcjtcbiAgICAgIHRyYWNlc0FuYWx5emVkOiBudW1iZXI7XG4gICAgfT47XG4gIH0+IHtcbiAgICBpZiAoIWluaXRpYWxpemVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlua0hpdmUgU0RLIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0KCkgZmlyc3QuXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBhcGlSZXF1ZXN0KCcvYW5hbHl0aWNzL3JvaS9zdW1tYXJ5Jyk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBST0kgYnkgYWdlbnRcbiAgICovXG4gIGFzeW5jIGdldFJvaUJ5QWdlbnQoYWdlbnRJZDogc3RyaW5nKTogUHJvbWlzZTx7XG4gICAgYWdlbnRJZDogc3RyaW5nO1xuICAgIHJldmVudWVTYXZlZDogbnVtYmVyO1xuICAgIHRyYWNlc0FuYWx5emVkOiBudW1iZXI7XG4gICAgc3VjY2Vzc1JhdGU6IG51bWJlcjtcbiAgICB0b3BJc3N1ZXM6IEFycmF5PHsgaXNzdWU6IHN0cmluZzsgY291bnQ6IG51bWJlcjsgaW1wYWN0OiBudW1iZXIgfT47XG4gIH0+IHtcbiAgICBpZiAoIWluaXRpYWxpemVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlua0hpdmUgU0RLIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0KCkgZmlyc3QuXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBhcGlSZXF1ZXN0KGAvYW5hbHl0aWNzL3JvaS9ieS1hZ2VudC8ke2FnZW50SWR9YCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBjb3JyZWxhdGlvbiBhbmFseXNpc1xuICAgKi9cbiAgYXN5bmMgZ2V0Q29ycmVsYXRpb25zKCk6IFByb21pc2U8e1xuICAgIGNvcnJlbGF0aW9uczogQXJyYXk8e1xuICAgICAgdHlwZTogc3RyaW5nO1xuICAgICAgY29lZmZpY2llbnQ6IG51bWJlcjtcbiAgICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgICBhY3Rpb25hYmxlSW5zaWdodDogc3RyaW5nO1xuICAgIH0+O1xuICB9PiB7XG4gICAgaWYgKCFpbml0aWFsaXplZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpbmtIaXZlIFNESyBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LlwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXBpUmVxdWVzdCgnL2FuYWx5dGljcy9jb3JyZWxhdGlvbnMnKTtcbiAgfSxcbn07XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEFVVE8tSU5TVFJVTUVOVEFUSU9OXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogU2V0dXAgYXV0by1pbnN0cnVtZW50YXRpb24gZm9yIEFJIGZyYW1ld29ya3NcbiAqL1xuZnVuY3Rpb24gc2V0dXBBdXRvSW5zdHJ1bWVudGF0aW9uKFxuICBmcmFtZXdvcmtzOiBBcnJheTwnbGFuZ2NoYWluJyB8ICdvcGVuYWknIHwgJ2FudGhyb3BpYycgfCAnbGxhbWFpbmRleCc+XG4pOiB2b2lkIHtcbiAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgIGNvbnNvbGUubG9nKGBTZXR0aW5nIHVwIGF1dG8taW5zdHJ1bWVudGF0aW9uIGZvcjogJHtmcmFtZXdvcmtzLmpvaW4oJywgJyl9YCk7XG4gIH1cblxuICAvLyBOb3RlOiBGdWxsIGF1dG8taW5zdHJ1bWVudGF0aW9uIHJlcXVpcmVzIGZyYW1ld29yay1zcGVjaWZpYyBwYXRjaGVzXG4gIC8vIFRoaXMgaXMgYSBwbGFjZWhvbGRlciBmb3IgdGhlIGluc3RydW1lbnRhdGlvbiBzZXR1cFxuICAvLyBJbiBwcm9kdWN0aW9uLCB1c2UgQG9wZW50ZWxlbWV0cnkvaW5zdHJ1bWVudGF0aW9uLSogcGFja2FnZXNcblxuICBmb3IgKGNvbnN0IGZyYW1ld29yayBvZiBmcmFtZXdvcmtzKSB7XG4gICAgdHJ5IHtcbiAgICAgIHN3aXRjaCAoZnJhbWV3b3JrKSB7XG4gICAgICAgIGNhc2UgJ29wZW5haSc6XG4gICAgICAgICAgaW5zdHJ1bWVudE9wZW5BSSgpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdsYW5nY2hhaW4nOlxuICAgICAgICAgIGluc3RydW1lbnRMYW5nQ2hhaW4oKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnYW50aHJvcGljJzpcbiAgICAgICAgICBpbnN0cnVtZW50QW50aHJvcGljKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2xsYW1haW5kZXgnOlxuICAgICAgICAgIGluc3RydW1lbnRMbGFtYUluZGV4KCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBGYWlsZWQgdG8gaW5zdHJ1bWVudCAke2ZyYW1ld29ya306YCwgZXJyb3IpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBpbnN0cnVtZW50T3BlbkFJKCk6IHZvaWQge1xuICAvLyBQbGFjZWhvbGRlciAtIHdvdWxkIHBhdGNoIE9wZW5BSSBjbGllbnRcbiAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgIGNvbnNvbGUubG9nKCdPcGVuQUkgaW5zdHJ1bWVudGF0aW9uIHJlYWR5Jyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5zdHJ1bWVudExhbmdDaGFpbigpOiB2b2lkIHtcbiAgLy8gUGxhY2Vob2xkZXIgLSB3b3VsZCB1c2UgTGFuZ0NoYWluIGNhbGxiYWNrc1xuICBpZiAoY29uZmlnLmRlYnVnKSB7XG4gICAgY29uc29sZS5sb2coJ0xhbmdDaGFpbiBpbnN0cnVtZW50YXRpb24gcmVhZHknKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnN0cnVtZW50QW50aHJvcGljKCk6IHZvaWQge1xuICAvLyBQbGFjZWhvbGRlciAtIHdvdWxkIHBhdGNoIEFudGhyb3BpYyBjbGllbnRcbiAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgIGNvbnNvbGUubG9nKCdBbnRocm9waWMgaW5zdHJ1bWVudGF0aW9uIHJlYWR5Jyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5zdHJ1bWVudExsYW1hSW5kZXgoKTogdm9pZCB7XG4gIC8vIFBsYWNlaG9sZGVyIC0gd291bGQgdXNlIExsYW1hSW5kZXggY2FsbGJhY2tzXG4gIGlmIChjb25maWcuZGVidWcpIHtcbiAgICBjb25zb2xlLmxvZygnTGxhbWFJbmRleCBpbnN0cnVtZW50YXRpb24gcmVhZHknKTtcbiAgfVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBDT05WRU5JRU5DRSBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDcmVhdGUgYSB0cmFjZSBhbmQgYW5hbHl6ZSBpdCBpbiBvbmUgY2FsbFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB7IHRyYWNlLCBhbmFseXNpcyB9ID0gYXdhaXQgY3JlYXRlQW5kQW5hbHl6ZSh7XG4gKiAgIHVzZXJNZXNzYWdlOiAnSGVscCBtZSB0cmFjayBteSBvcmRlcicsXG4gKiAgIGFnZW50UmVzcG9uc2U6ICdZb3VyIG9yZGVyIGlzIG9uIHRoZSB3YXkuLi4nLFxuICogfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUFuZEFuYWx5emUoXG4gIHRyYWNlRGF0YTogVHJhY2VPcHRpb25zLFxuICBvcHRpb25zOiBBbmFseXplT3B0aW9ucyA9IHt9XG4pOiBQcm9taXNlPHtcbiAgdHJhY2U6IFRyYWNlT3B0aW9ucztcbiAgYW5hbHlzaXM6IEV4cGxhaW5hYmlsaXR5UmVzdWx0O1xufT4ge1xuICBjb25zdCBhbmFseXNpcyA9IGF3YWl0IGV4cGxhaW5lci5hbmFseXplKHRyYWNlRGF0YSwgb3B0aW9ucyk7XG4gIHJldHVybiB7IHRyYWNlOiB0cmFjZURhdGEsIGFuYWx5c2lzIH07XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEVYUE9SVFNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGRlZmF1bHQge1xuICBpbml0LFxuICBnZXRUcmFjZXIsXG4gIGlzSW5pdGlhbGl6ZWQsXG4gIHRyYWNlTExNLFxuICB0cmFjZVJldHJpZXZhbCxcbiAgdHJhY2VUb29sLFxuICB0cmFjZUNoYWluLFxuICBleHBsYWluZXIsXG4gIGZlZWRiYWNrLFxuICBxdWFsaXR5LFxuICBhbmFseXRpY3MsXG4gIGNyZWF0ZUFuZEFuYWx5emUsXG59O1xuIl19
|
|
414
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7OztHQVdHOzs7QUFvSEgsb0JBdURDO0FBS0QsOEJBS0M7QUFLRCw0QkFRQztBQVNELDRCQXVDQztBQUtELHdDQXVDQztBQUtELDhCQXFDQztBQUtELGdDQW1DQztBQTlXRCw0Q0FBb0U7QUFDcEUsd0ZBQTZFO0FBQzdFLHdEQUFvRDtBQUNwRCxrRUFBbUU7QUFDbkUsa0VBQW1FO0FBRW5FLE9BQU87QUFDUCwwQ0FRdUI7QUE2ZGQsOEZBbGVQLHNCQUFhLE9Ba2VPO0FBQUUsNEZBL2R0QixvQkFBVyxPQStkc0I7QUFBRSxpR0E5ZG5DLHlCQUFnQixPQThkbUM7QUE1ZHJELDBDQUE0RztBQTJnQm5HLGtHQTNnQmdDLDBCQUFpQixPQTJnQmhDO0FBQUUseUdBM2dCZ0MsaUNBQXdCLE9BMmdCaEM7QUF6Z0JwRCxjQUFjO0FBQ2QscUNBQThGO0FBNmQ1RixxRkE3ZE8sV0FBSSxPQTZkUDtBQVVKLHFHQXZlYSwyQkFBb0IsT0F1ZWI7QUFDcEIsaUdBeGVtQyx1QkFBZ0IsT0F3ZW5DO0FBQ2hCLG1HQXplcUQseUJBQWtCLE9BeWVyRDtBQXhlcEIseUNBUXNCO0FBcWRwQix1RkE1ZEEsZUFBTSxPQTRkQTtBQWFOLHVGQXhlQSxlQUFNLE9Bd2VBO0FBQ04sNEZBeGVBLG9CQUFXLE9Bd2VBO0FBQ1gsMkZBeGVBLG1CQUFVLE9Bd2VBO0FBQ1Ysd0dBeGVBLGdDQUF1QixPQXdlQTtBQUN2QixrR0F4ZUEsMEJBQWlCLE9Bd2VBO0FBQ2pCLHNHQXhlQSw4QkFBcUIsT0F3ZUE7QUF0ZXZCLG1EQU0yQjtBQStjekIsNEZBcGRBLHlCQUFXLE9Bb2RBO0FBbUJYLG9HQXRlQSxpQ0FBbUIsT0FzZUE7QUFDbkIsNkZBdGVBLDBCQUFZLE9Bc2VBO0FBQ1osaUdBdGVBLDhCQUFnQixPQXNlQTtBQUNoQixzR0F0ZUEsbUNBQXFC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V0FBSTtJQUNKLE1BQU0sRUFBTixlQUFNO0lBQ04sV0FBVyxFQUFYLHlCQUFXO0lBQ1gsT0FBTyxFQUFQLHdCQUFPO0lBQ1AsZUFBZSxFQUFmLGtDQUFlO0lBQ2YsbUJBQW1CO0lBQ25CLFNBQVMsRUFBVCxpQkFBUztJQUNULFVBQVU7SUFDVixxQkFBcUIsRUFBckIsc0NBQXFCO0lBQ3JCLGtCQUFrQixFQUFsQixtQ0FBa0I7SUFDbEIsZUFBZSxFQUFmLGdDQUFlO0lBQ2Ysb0JBQW9CLEVBQXBCLDJCQUFvQjtJQUNwQixZQUFZO0lBQ1osTUFBTSxFQUFOLGVBQU07SUFDTixXQUFXLEVBQVgsb0JBQVc7SUFDWCxtQkFBbUIsRUFBbkIsaUNBQW1CO0lBQ25CLGdCQUFnQixFQUFoQiw4QkFBZ0I7Q0FDakIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhpbmtIaXZlIFNESyB2My4wLjBcbiAqXG4gKiBSdW4tY2VudHJpYyBBSSBhZ2VudCBvYnNlcnZhYmlsaXR5IHBsYXRmb3JtIHdpdGg6XG4gKiAtIEZhY3RzIHZzIEluZmVyZW5jZXMgKGNsYWltcyBBUEkpXG4gKiAtIERldGVybWluaXN0aWMgdGlja2V0IGxpbmtpbmcgKDcgbWV0aG9kcylcbiAqIC0gQ3VzdG9tZXIgY29udGV4dCBzbmFwc2hvdHMgKHRpbWUtc2VyaWVzKVxuICogLSBDYWxpYnJhdGVkIHByZWRpY3Rpb25zIChCcmllciBzY29yZXMpXG4gKlxuICogQHZlcnNpb24gMy4wLjBcbiAqIEBsaWNlbnNlIE1JVFxuICovXG5cbmltcG9ydCB7IHRyYWNlLCBjb250ZXh0LCBTcGFuU3RhdHVzQ29kZSB9IGZyb20gJ0BvcGVudGVsZW1ldHJ5L2FwaSc7XG5pbXBvcnQgeyBPVExQVHJhY2VFeHBvcnRlciB9IGZyb20gJ0BvcGVudGVsZW1ldHJ5L2V4cG9ydGVyLXRyYWNlLW90bHAtcHJvdG8nO1xuaW1wb3J0IHsgUmVzb3VyY2UgfSBmcm9tICdAb3BlbnRlbGVtZXRyeS9yZXNvdXJjZXMnO1xuaW1wb3J0IHsgTm9kZVRyYWNlclByb3ZpZGVyIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvc2RrLXRyYWNlLW5vZGUnO1xuaW1wb3J0IHsgQmF0Y2hTcGFuUHJvY2Vzc29yIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvc2RrLXRyYWNlLWJhc2UnO1xuXG4vLyBDb3JlXG5pbXBvcnQge1xuICBpbml0Q29uZmlnLFxuICBnZXRDb25maWcsXG4gIGlzSW5pdGlhbGl6ZWQsXG4gIHJlc2V0Q29uZmlnLFxuICBkZWJ1Z0xvZyxcbiAgU0RLX1ZFUlNJT04sXG4gIERFRkFVTFRfRU5EUE9JTlQsXG59IGZyb20gJy4vY29yZS9jb25maWcnO1xuaW1wb3J0IHsgYXBpUmVxdWVzdCwgYXBpUmVxdWVzdFdpdGhEYXRhLCBUaGlua0hpdmVBcGlFcnJvciwgVGhpbmtIaXZlVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi9jb3JlL2NsaWVudCc7XG5cbi8vIEFQSSBjbGllbnRzXG5pbXBvcnQgeyBydW5zLCBjcmVhdGVSdW5XaXRoQ29udGV4dCwgdG9PcGVuQUlNZXNzYWdlcywgZnJvbU9wZW5BSU1lc3NhZ2VzIH0gZnJvbSAnLi9hcGkvcnVucyc7XG5pbXBvcnQge1xuICBjbGFpbXMsXG4gIGlzRmFjdCxcbiAgaXNJbmZlcmVuY2UsXG4gIGlzQ29tcHV0ZWQsXG4gIGdldEhpZ2hDb25maWRlbmNlQ2xhaW1zLFxuICBncm91cENsYWltc0J5VHlwZSxcbiAgZ3JvdXBDbGFpbXNCeUNhdGVnb3J5LFxufSBmcm9tICcuL2FwaS9jbGFpbXMnO1xuaW1wb3J0IHtcbiAgY2FsaWJyYXRpb24sXG4gIGNhbGN1bGF0ZUJyaWVyU2NvcmUsXG4gIGNhbGN1bGF0ZUVDRSxcbiAgaXNXZWxsQ2FsaWJyYXRlZCxcbiAgZ2V0Q2FsaWJyYXRpb25RdWFsaXR5LFxufSBmcm9tICcuL2FwaS9jYWxpYnJhdGlvbic7XG5cbi8vIEludGVncmF0aW9uc1xuaW1wb3J0IHtcbiAgbGlua2luZyxcbiAgZ2VuZXJhdGVaZW5kZXNrTWFya2VyLFxuICBwYXJzZVplbmRlc2tNYXJrZXIsXG4gIGhhc1plbmRlc2tNYXJrZXIsXG4gIHJlbW92ZVplbmRlc2tNYXJrZXIsXG4gIGxpbmtSdW5Ub1RpY2tldCxcbiAgbGlua1J1blRvWmVuZGVza1RpY2tldCxcbiAgZ2V0QmVzdExpbmtNZXRob2QsXG4gIExJTktfTUVUSE9EX0NPTkZJREVOQ0UsXG59IGZyb20gJy4vaW50ZWdyYXRpb25zL3RpY2tldC1saW5raW5nJztcbmltcG9ydCB7XG4gIGN1c3RvbWVyQ29udGV4dCxcbiAgY2FwdHVyZUN1c3RvbWVyQ29udGV4dCxcbiAgZ2V0Q29udGV4dEFzT2YsXG4gIHRvQ29udGV4dFNuYXBzaG90LFxuICBjYWxjdWxhdGVBcnJDaGFuZ2UsXG4gIGNhbGN1bGF0ZUhlYWx0aFRyZW5kLFxufSBmcm9tICcuL2ludGVncmF0aW9ucy9jdXN0b21lci1jb250ZXh0JztcblxuLy8gUmUtZXhwb3J0IHR5cGVzXG5leHBvcnQgdHlwZSB7XG4gIEluaXRPcHRpb25zLFxuICBGcmFtZXdvcmssXG4gIFJ1bk9wdGlvbnMsXG4gIFJ1bk91dGNvbWUsXG4gIENvbnZlcnNhdGlvbk1lc3NhZ2UsXG4gIEN1c3RvbWVyQ29udGV4dFNuYXBzaG90LFxuICBUaWNrZXRMaW5raW5nT3B0aW9ucyxcbiAgTGlua01ldGhvZCxcbiAgVHJhY2VPcHRpb25zLFxuICBTcGFuRGF0YSxcbiAgQnVzaW5lc3NDb250ZXh0LFxuICBDbGFpbSxcbiAgQ2xhaW1UeXBlLFxuICBDbGFpbUNhdGVnb3J5LFxuICBDb25maWRlbmNlQ2FsaWJyYXRpb24sXG4gIEV2aWRlbmNlUmVmZXJlbmNlLFxuICBBbmFseXNpc1Jlc3VsdCxcbiAgQ2FsaWJyYXRpb25TdGF0dXMsXG4gIENhbGlicmF0aW9uQnVja2V0LFxuICBQcmVkaWN0aW9uVHlwZSxcbiAgUm9pQ29uZmlnLFxuICBSb2lTdW1tYXJ5LFxuICBFeHBsYWluYWJpbGl0eVJlc3VsdCxcbiAgQXBpUmVzcG9uc2UsXG4gIFBhZ2luYXRlZFJlc3BvbnNlLFxuICBSdW5SZXNwb25zZSxcbn0gZnJvbSAnLi9jb3JlL3R5cGVzJztcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gR0xPQkFMIFNUQVRFXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmxldCB0cmFjZXI6IFJldHVyblR5cGU8dHlwZW9mIHRyYWNlLmdldFRyYWNlcj4gfCBudWxsID0gbnVsbDtcbmxldCBwcm92aWRlcjogTm9kZVRyYWNlclByb3ZpZGVyIHwgbnVsbCA9IG51bGw7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIElOSVRJQUxJWkFUSU9OXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBUaGlua0hpdmUgU0RLIHYzXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IGluaXQgfSBmcm9tICdAdGhpbmtoaXZlL3Nkayc7XG4gKlxuICogaW5pdCh7XG4gKiAgIGFwaUtleTogJ3RoX3lvdXJfYXBpX2tleScsXG4gKiAgIHNlcnZpY2VOYW1lOiAnbXktYWktYWdlbnQnLFxuICogICBhdXRvSW5zdHJ1bWVudDogdHJ1ZSxcbiAqICAgZnJhbWV3b3JrczogWydsYW5nY2hhaW4nLCAnb3BlbmFpJ10sXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdChvcHRpb25zOiBpbXBvcnQoJy4vY29yZS90eXBlcycpLkluaXRPcHRpb25zID0ge30pOiB2b2lkIHtcbiAgaWYgKGlzSW5pdGlhbGl6ZWQoKSkge1xuICAgIGRlYnVnTG9nKCdUaGlua0hpdmUgU0RLIGFscmVhZHkgaW5pdGlhbGl6ZWQnKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBjb25maWcgPSBpbml0Q29uZmlnKG9wdGlvbnMpO1xuXG4gIC8vIENvbmZpZ3VyZSBPVExQIGV4cG9ydGVyXG4gIGNvbnN0IGV4cG9ydGVySGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBpZiAoY29uZmlnLmFwaUtleSkge1xuICAgIGV4cG9ydGVySGVhZGVyc1snQXV0aG9yaXphdGlvbiddID0gYEJlYXJlciAke2NvbmZpZy5hcGlLZXl9YDtcbiAgfSBlbHNlIGlmIChjb25maWcuYWdlbnRJZCkge1xuICAgIGV4cG9ydGVySGVhZGVyc1snWC1BZ2VudC1JRCddID0gY29uZmlnLmFnZW50SWQ7XG4gIH1cblxuICBjb25zdCBleHBvcnRlciA9IG5ldyBPVExQVHJhY2VFeHBvcnRlcih7XG4gICAgdXJsOiBgJHtjb25maWcuZW5kcG9pbnR9L3YxL3RyYWNlc2AsXG4gICAgaGVhZGVyczogZXhwb3J0ZXJIZWFkZXJzLFxuICB9KTtcblxuICAvLyBDcmVhdGUgT3BlblRlbGVtZXRyeSByZXNvdXJjZVxuICBjb25zdCByZXNvdXJjZSA9IFJlc291cmNlLmRlZmF1bHQoKS5tZXJnZShcbiAgICBuZXcgUmVzb3VyY2Uoe1xuICAgICAgJ3NlcnZpY2UubmFtZSc6IGNvbmZpZy5zZXJ2aWNlTmFtZSxcbiAgICAgICd0aGlua2hpdmUuc2RrLnZlcnNpb24nOiBTREtfVkVSU0lPTixcbiAgICAgICd0aGlua2hpdmUuc2RrLmxhbmd1YWdlJzogJ3R5cGVzY3JpcHQnLFxuICAgICAgJ3RoaW5raGl2ZS5hcGkudmVyc2lvbic6IGNvbmZpZy5hcGlWZXJzaW9uLFxuICAgIH0pXG4gICk7XG5cbiAgLy8gQ3JlYXRlIHByb3ZpZGVyIHdpdGggc3BhbiBwcm9jZXNzb3JcbiAgcHJvdmlkZXIgPSBuZXcgTm9kZVRyYWNlclByb3ZpZGVyKHtcbiAgICByZXNvdXJjZSxcbiAgICBzcGFuUHJvY2Vzc29yczogW25ldyBCYXRjaFNwYW5Qcm9jZXNzb3IoZXhwb3J0ZXIpXSxcbiAgfSk7XG5cbiAgLy8gUmVnaXN0ZXIgcHJvdmlkZXJcbiAgcHJvdmlkZXIucmVnaXN0ZXIoKTtcblxuICAvLyBHZXQgdHJhY2VyXG4gIHRyYWNlciA9IHRyYWNlLmdldFRyYWNlcigndGhpbmtoaXZlJywgU0RLX1ZFUlNJT04pO1xuXG4gIGlmIChjb25maWcuZGVidWcpIHtcbiAgICBjb25zb2xlLmxvZyhg4pyFIFRoaW5rSGl2ZSBTREsgdiR7U0RLX1ZFUlNJT059IGluaXRpYWxpemVkYCk7XG4gICAgY29uc29sZS5sb2coYCAgIEVuZHBvaW50OiAke2NvbmZpZy5lbmRwb2ludH1gKTtcbiAgICBjb25zb2xlLmxvZyhgICAgU2VydmljZTogJHtjb25maWcuc2VydmljZU5hbWV9YCk7XG4gICAgY29uc29sZS5sb2coYCAgIEFQSSBWZXJzaW9uOiAke2NvbmZpZy5hcGlWZXJzaW9ufWApO1xuICAgIGNvbnNvbGUubG9nKGAgICBBdXRvLWluc3RydW1lbnQ6ICR7Y29uZmlnLmF1dG9JbnN0cnVtZW50fWApO1xuICB9XG5cbiAgLy8gU2V0dXAgYXV0by1pbnN0cnVtZW50YXRpb24gaWYgZW5hYmxlZFxuICBpZiAoY29uZmlnLmF1dG9JbnN0cnVtZW50KSB7XG4gICAgc2V0dXBBdXRvSW5zdHJ1bWVudGF0aW9uKGNvbmZpZy5mcmFtZXdvcmtzKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgZ2xvYmFsIHRyYWNlclxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJhY2VyKCkge1xuICBpZiAoIXRyYWNlcikge1xuICAgIHRocm93IG5ldyBFcnJvcignVGhpbmtIaXZlIFNESyBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LicpO1xuICB9XG4gIHJldHVybiB0cmFjZXI7XG59XG5cbi8qKlxuICogU2h1dGRvd24gdGhlIFNESyBhbmQgZmx1c2ggcGVuZGluZyBzcGFuc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2h1dGRvd24oKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChwcm92aWRlcikge1xuICAgIGF3YWl0IHByb3ZpZGVyLnNodXRkb3duKCk7XG4gICAgcHJvdmlkZXIgPSBudWxsO1xuICB9XG4gIHRyYWNlciA9IG51bGw7XG4gIHJlc2V0Q29uZmlnKCk7XG4gIGRlYnVnTG9nKCdUaGlua0hpdmUgU0RLIHNodXRkb3duIGNvbXBsZXRlJyk7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRSQUNJTkcgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogVHJhY2UgYW4gTExNIGNhbGxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYWNlTExNPFQ+KFxuICBvcHRpb25zOiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIG1vZGVsTmFtZT86IHN0cmluZztcbiAgICBwcm92aWRlcj86IHN0cmluZztcbiAgICBpbnB1dD86IHVua25vd247XG4gIH0sXG4gIGZuOiAoKSA9PiBQcm9taXNlPFQ+XG4pOiBQcm9taXNlPFQ+IHtcbiAgY29uc3QgdCA9IGdldFRyYWNlcigpO1xuXG4gIHJldHVybiB0LnN0YXJ0QWN0aXZlU3BhbihcbiAgICBvcHRpb25zLm5hbWUsXG4gICAge1xuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAnb3BlbmluZmVyZW5jZS5zcGFuLmtpbmQnOiAnTExNJyxcbiAgICAgICAgJ2xsbS5tb2RlbF9uYW1lJzogb3B0aW9ucy5tb2RlbE5hbWUsXG4gICAgICAgICdsbG0ucHJvdmlkZXInOiBvcHRpb25zLnByb3ZpZGVyLFxuICAgICAgICAnaW5wdXQudmFsdWUnOiBvcHRpb25zLmlucHV0ID8gSlNPTi5zdHJpbmdpZnkob3B0aW9ucy5pbnB1dCkuc3Vic3RyaW5nKDAsIDEwMDAwKSA6IHVuZGVmaW5lZCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBhc3luYyAoc3BhbikgPT4ge1xuICAgICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZuKCk7XG4gICAgICAgIHNwYW4uc2V0QXR0cmlidXRlKCdvdXRwdXQudmFsdWUnLCBKU09OLnN0cmluZ2lmeShyZXN1bHQpLnN1YnN0cmluZygwLCAxMDAwMCkpO1xuICAgICAgICBzcGFuLnNldFN0YXR1cyh7IGNvZGU6IFNwYW5TdGF0dXNDb2RlLk9LIH0pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcbiAgICAgICAgc3Bhbi5zZXRTdGF0dXMoeyBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUiwgbWVzc2FnZSB9KTtcbiAgICAgICAgc3Bhbi5yZWNvcmRFeGNlcHRpb24oZXJyb3IgYXMgRXJyb3IpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNwYW4uc2V0QXR0cmlidXRlKCdkdXJhdGlvbl9tcycsIERhdGUubm93KCkgLSBzdGFydFRpbWUpO1xuICAgICAgICBzcGFuLmVuZCgpO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBUcmFjZSBhIHJldHJpZXZhbCBvcGVyYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYWNlUmV0cmlldmFsPFQ+KFxuICBvcHRpb25zOiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHF1ZXJ5Pzogc3RyaW5nO1xuICAgIHRvcEs/OiBudW1iZXI7XG4gIH0sXG4gIGZuOiAoKSA9PiBQcm9taXNlPFQ+XG4pOiBQcm9taXNlPFQ+IHtcbiAgY29uc3QgdCA9IGdldFRyYWNlcigpO1xuXG4gIHJldHVybiB0LnN0YXJ0QWN0aXZlU3BhbihcbiAgICBvcHRpb25zLm5hbWUsXG4gICAge1xuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAnb3BlbmluZmVyZW5jZS5zcGFuLmtpbmQnOiAnUkVUUklFVkVSJyxcbiAgICAgICAgJ3JldHJpZXZhbC5xdWVyeSc6IG9wdGlvbnMucXVlcnksXG4gICAgICAgICdyZXRyaWV2YWwudG9wX2snOiBvcHRpb25zLnRvcEssXG4gICAgICB9LFxuICAgIH0sXG4gICAgYXN5bmMgKHNwYW4pID0+IHtcbiAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmbigpO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHQpKSB7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ3JldHJpZXZhbC5kb2N1bWVudF9jb3VudCcsIHJlc3VsdC5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICAgIHNwYW4uc2V0U3RhdHVzKHsgY29kZTogU3BhblN0YXR1c0NvZGUuT0sgfSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgICAgICBzcGFuLnNldFN0YXR1cyh7IGNvZGU6IFNwYW5TdGF0dXNDb2RlLkVSUk9SLCBtZXNzYWdlIH0pO1xuICAgICAgICBzcGFuLnJlY29yZEV4Y2VwdGlvbihlcnJvciBhcyBFcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2R1cmF0aW9uX21zJywgRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSk7XG4gICAgICAgIHNwYW4uZW5kKCk7XG4gICAgICB9XG4gICAgfVxuICApO1xufVxuXG4vKipcbiAqIFRyYWNlIGEgdG9vbCBjYWxsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFjZVRvb2w8VD4oXG4gIG9wdGlvbnM6IHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgdG9vbE5hbWU/OiBzdHJpbmc7XG4gICAgcGFyYW1ldGVycz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB9LFxuICBmbjogKCkgPT4gUHJvbWlzZTxUPlxuKTogUHJvbWlzZTxUPiB7XG4gIGNvbnN0IHQgPSBnZXRUcmFjZXIoKTtcblxuICByZXR1cm4gdC5zdGFydEFjdGl2ZVNwYW4oXG4gICAgb3B0aW9ucy50b29sTmFtZSB8fCBvcHRpb25zLm5hbWUsXG4gICAge1xuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAnb3BlbmluZmVyZW5jZS5zcGFuLmtpbmQnOiAnVE9PTCcsXG4gICAgICAgICd0b29sLm5hbWUnOiBvcHRpb25zLnRvb2xOYW1lIHx8IG9wdGlvbnMubmFtZSxcbiAgICAgICAgJ3Rvb2wucGFyYW1ldGVycyc6IG9wdGlvbnMucGFyYW1ldGVycyA/IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMucGFyYW1ldGVycykgOiB1bmRlZmluZWQsXG4gICAgICB9LFxuICAgIH0sXG4gICAgYXN5bmMgKHNwYW4pID0+IHtcbiAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmbigpO1xuICAgICAgICBzcGFuLnNldEF0dHJpYnV0ZSgndG9vbC5vdXRwdXQnLCBKU09OLnN0cmluZ2lmeShyZXN1bHQpLnN1YnN0cmluZygwLCAxMDAwMCkpO1xuICAgICAgICBzcGFuLnNldFN0YXR1cyh7IGNvZGU6IFNwYW5TdGF0dXNDb2RlLk9LIH0pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcbiAgICAgICAgc3Bhbi5zZXRTdGF0dXMoeyBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUiwgbWVzc2FnZSB9KTtcbiAgICAgICAgc3Bhbi5yZWNvcmRFeGNlcHRpb24oZXJyb3IgYXMgRXJyb3IpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNwYW4uc2V0QXR0cmlidXRlKCdkdXJhdGlvbl9tcycsIERhdGUubm93KCkgLSBzdGFydFRpbWUpO1xuICAgICAgICBzcGFuLmVuZCgpO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBUcmFjZSBhIGNoYWluL3dvcmtmbG93XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFjZUNoYWluPFQ+KFxuICBvcHRpb25zOiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIGlucHV0PzogdW5rbm93bjtcbiAgfSxcbiAgZm46ICgpID0+IFByb21pc2U8VD5cbik6IFByb21pc2U8VD4ge1xuICBjb25zdCB0ID0gZ2V0VHJhY2VyKCk7XG5cbiAgcmV0dXJuIHQuc3RhcnRBY3RpdmVTcGFuKFxuICAgIG9wdGlvbnMubmFtZSxcbiAgICB7XG4gICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICdvcGVuaW5mZXJlbmNlLnNwYW4ua2luZCc6ICdDSEFJTicsXG4gICAgICAgICdpbnB1dC52YWx1ZSc6IG9wdGlvbnMuaW5wdXQgPyBKU09OLnN0cmluZ2lmeShvcHRpb25zLmlucHV0KS5zdWJzdHJpbmcoMCwgMTAwMDApIDogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICB9LFxuICAgIGFzeW5jIChzcGFuKSA9PiB7XG4gICAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZm4oKTtcbiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ291dHB1dC52YWx1ZScsIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkuc3Vic3RyaW5nKDAsIDEwMDAwKSk7XG4gICAgICAgIHNwYW4uc2V0U3RhdHVzKHsgY29kZTogU3BhblN0YXR1c0NvZGUuT0sgfSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgICAgICBzcGFuLnNldFN0YXR1cyh7IGNvZGU6IFNwYW5TdGF0dXNDb2RlLkVSUk9SLCBtZXNzYWdlIH0pO1xuICAgICAgICBzcGFuLnJlY29yZEV4Y2VwdGlvbihlcnJvciBhcyBFcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2R1cmF0aW9uX21zJywgRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSk7XG4gICAgICAgIHNwYW4uZW5kKCk7XG4gICAgICB9XG4gICAgfVxuICApO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBWMiBDT01QQVRJQklMSVRZIC0gRVhQTEFJTkVSIENMSUVOVFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIEV4cGxhaW5lciBBUEkgY2xpZW50ICh2MiBjb21wYXRpYmlsaXR5KVxuICogQGRlcHJlY2F0ZWQgVXNlIHJ1bnMgYW5kIGNsYWltcyBBUElzIGluc3RlYWRcbiAqL1xuZXhwb3J0IGNvbnN0IGV4cGxhaW5lciA9IHtcbiAgLyoqXG4gICAqIEFuYWx5emUgYSB0cmFjZSAodjIgZm9ybWF0KVxuICAgKiBAZGVwcmVjYXRlZCBVc2UgcnVucy5jcmVhdGUoKSArIGNsYWltcy5nZXRSdW5BbmFseXNpcygpIGluc3RlYWRcbiAgICovXG4gIGFzeW5jIGFuYWx5emUoXG4gICAgdHJhY2VEYXRhOiBpbXBvcnQoJy4vY29yZS90eXBlcycpLlRyYWNlT3B0aW9ucyxcbiAgICBvcHRpb25zOiB7XG4gICAgICB0aWVyPzogc3RyaW5nO1xuICAgICAgaW5jbHVkZVJhZ0V2YWx1YXRpb24/OiBib29sZWFuO1xuICAgICAgaW5jbHVkZUhhbGx1Y2luYXRpb25DaGVjaz86IGJvb2xlYW47XG4gICAgICB3YWl0Rm9yUmVzdWx0PzogYm9vbGVhbjtcbiAgICAgIHdlYmhvb2tVcmw/OiBzdHJpbmc7XG4gICAgfSA9IHt9XG4gICk6IFByb21pc2U8aW1wb3J0KCcuL2NvcmUvdHlwZXMnKS5FeHBsYWluYWJpbGl0eVJlc3VsdD4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGEoJy9leHBsYWluZXIvYW5hbHl6ZScsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgYm9keToge1xuICAgICAgICB0cmFjZToge1xuICAgICAgICAgIHVzZXJNZXNzYWdlOiB0cmFjZURhdGEudXNlck1lc3NhZ2UsXG4gICAgICAgICAgYWdlbnRSZXNwb25zZTogdHJhY2VEYXRhLmFnZW50UmVzcG9uc2UsXG4gICAgICAgICAgdXNlckludGVudDogdHJhY2VEYXRhLnVzZXJJbnRlbnQsXG4gICAgICAgICAgb3V0Y29tZTogdHJhY2VEYXRhLm91dGNvbWUgfHwgJ3N1Y2Nlc3MnLFxuICAgICAgICAgIGR1cmF0aW9uOiB0cmFjZURhdGEuZHVyYXRpb24sXG4gICAgICAgICAgc2Vzc2lvbklkOiB0cmFjZURhdGEuc2Vzc2lvbklkLFxuICAgICAgICAgIGNvbnZlcnNhdGlvbkhpc3Rvcnk6IHRyYWNlRGF0YS5jb252ZXJzYXRpb25IaXN0b3J5LFxuICAgICAgICAgIG1ldGFkYXRhOiB0cmFjZURhdGEubWV0YWRhdGEsXG4gICAgICAgIH0sXG4gICAgICAgIHNwYW5zOiB0cmFjZURhdGEuc3BhbnMsXG4gICAgICAgIGJ1c2luZXNzQ29udGV4dDogdHJhY2VEYXRhLmJ1c2luZXNzQ29udGV4dCxcbiAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgIHRpZXI6IG9wdGlvbnMudGllcixcbiAgICAgICAgICBpbmNsdWRlUmFnRXZhbHVhdGlvbjogb3B0aW9ucy5pbmNsdWRlUmFnRXZhbHVhdGlvbiA/PyB0cnVlLFxuICAgICAgICAgIGluY2x1ZGVIYWxsdWNpbmF0aW9uQ2hlY2s6IG9wdGlvbnMuaW5jbHVkZUhhbGx1Y2luYXRpb25DaGVjayA/PyB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFwaVZlcnNpb246ICd2MScsXG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhIHByZXZpb3VzbHkgYW5hbHl6ZWQgdHJhY2VcbiAgICogQGRlcHJlY2F0ZWRcbiAgICovXG4gIGFzeW5jIGdldCh0cmFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPGltcG9ydCgnLi9jb3JlL3R5cGVzJykuRXhwbGFpbmFiaWxpdHlSZXN1bHQ+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhKGAvZXhwbGFpbmVyLyR7dHJhY2VJZH1gLCB7IGFwaVZlcnNpb246ICd2MScgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFNlYXJjaCB0cmFjZXMgc2VtYW50aWNhbGx5XG4gICAqIEBkZXByZWNhdGVkXG4gICAqL1xuICBhc3luYyBzZWFyY2gocGFyYW1zOiB7XG4gICAgcXVlcnk6IHN0cmluZztcbiAgICBmaWx0ZXJzPzoge1xuICAgICAgb3V0Y29tZT86IHN0cmluZztcbiAgICAgIG1pbkltcGFjdFNjb3JlPzogbnVtYmVyO1xuICAgICAgZGF0ZVJhbmdlPzogeyBmcm9tOiBEYXRlOyB0bzogRGF0ZSB9O1xuICAgIH07XG4gICAgbGltaXQ/OiBudW1iZXI7XG4gIH0pOiBQcm9taXNlPHtcbiAgICByZXN1bHRzOiBBcnJheTxpbXBvcnQoJy4vY29yZS90eXBlcycpLkV4cGxhaW5hYmlsaXR5UmVzdWx0ICYgeyBzaW1pbGFyaXR5OiBudW1iZXIgfT47XG4gICAgdG90YWw6IG51bWJlcjtcbiAgfT4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGEoJy9leHBsYWluZXIvc2VhcmNoJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBwYXJhbXMsXG4gICAgICBhcGlWZXJzaW9uOiAndjEnLFxuICAgIH0pO1xuICB9LFxufTtcblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQVVUTy1JTlNUUlVNRU5UQVRJT05cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gc2V0dXBBdXRvSW5zdHJ1bWVudGF0aW9uKFxuICBmcmFtZXdvcmtzOiBpbXBvcnQoJy4vY29yZS90eXBlcycpLkZyYW1ld29ya1tdXG4pOiB2b2lkIHtcbiAgZGVidWdMb2coYFNldHRpbmcgdXAgYXV0by1pbnN0cnVtZW50YXRpb24gZm9yOiAke2ZyYW1ld29ya3Muam9pbignLCAnKX1gKTtcblxuICBmb3IgKGNvbnN0IGZyYW1ld29yayBvZiBmcmFtZXdvcmtzKSB7XG4gICAgdHJ5IHtcbiAgICAgIHN3aXRjaCAoZnJhbWV3b3JrKSB7XG4gICAgICAgIGNhc2UgJ29wZW5haSc6XG4gICAgICAgIGNhc2UgJ29wZW5haS1hc3Npc3RhbnRzJzpcbiAgICAgICAgICBkZWJ1Z0xvZygnT3BlbkFJIGluc3RydW1lbnRhdGlvbiByZWFkeSAodXNlIGluc3RydW1lbnRPcGVuQUlDbGllbnQpJyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2xhbmdjaGFpbic6XG4gICAgICAgIGNhc2UgJ2xhbmdncmFwaCc6XG4gICAgICAgICAgZGVidWdMb2coJ0xhbmdDaGFpbi9MYW5nR3JhcGggaW5zdHJ1bWVudGF0aW9uIHJlYWR5ICh1c2UgVGhpbmtIaXZlQ2FsbGJhY2tIYW5kbGVyKScpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdhbnRocm9waWMnOlxuICAgICAgICAgIGRlYnVnTG9nKCdBbnRocm9waWMgaW5zdHJ1bWVudGF0aW9uIHJlYWR5Jyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2xsYW1haW5kZXgnOlxuICAgICAgICAgIGRlYnVnTG9nKCdMbGFtYUluZGV4IGluc3RydW1lbnRhdGlvbiByZWFkeScpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICduOG4nOlxuICAgICAgICAgIGRlYnVnTG9nKCduOG4gaW5zdHJ1bWVudGF0aW9uIHJlYWR5Jyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3ZvaWNlZmxvdyc6XG4gICAgICAgICAgZGVidWdMb2coJ1ZvaWNlZmxvdyBpbnN0cnVtZW50YXRpb24gcmVhZHknKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZGVidWdMb2coYEZhaWxlZCB0byBzZXR1cCAke2ZyYW1ld29ya30gaW5zdHJ1bWVudGF0aW9uOmAsIGVycm9yKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gUkUtRVhQT1JUUyAobm9uLWR1cGxpY2F0ZWQpXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8vIFJlLWV4cG9ydCBmcm9tIGNvbmZpZyAobm90IHlldCBleHBvcnRlZClcbmV4cG9ydCB7IGlzSW5pdGlhbGl6ZWQsIFNES19WRVJTSU9OLCBERUZBVUxUX0VORFBPSU5UIH07XG5cbi8vIFJlLWV4cG9ydCBBUEkgY2xpZW50cyAodjMpXG5leHBvcnQge1xuICBydW5zLFxuICBjbGFpbXMsXG4gIGNhbGlicmF0aW9uLFxuICBsaW5raW5nLFxuICBjdXN0b21lckNvbnRleHQsXG59O1xuXG4vLyBSZS1leHBvcnQgaGVscGVyIGZ1bmN0aW9uc1xuZXhwb3J0IHtcbiAgLy8gUnVucyBoZWxwZXJzXG4gIGNyZWF0ZVJ1bldpdGhDb250ZXh0LFxuICB0b09wZW5BSU1lc3NhZ2VzLFxuICBmcm9tT3BlbkFJTWVzc2FnZXMsXG4gIC8vIENsYWltcyBoZWxwZXJzXG4gIGlzRmFjdCxcbiAgaXNJbmZlcmVuY2UsXG4gIGlzQ29tcHV0ZWQsXG4gIGdldEhpZ2hDb25maWRlbmNlQ2xhaW1zLFxuICBncm91cENsYWltc0J5VHlwZSxcbiAgZ3JvdXBDbGFpbXNCeUNhdGVnb3J5LFxuICAvLyBDYWxpYnJhdGlvbiBoZWxwZXJzXG4gIGNhbGN1bGF0ZUJyaWVyU2NvcmUsXG4gIGNhbGN1bGF0ZUVDRSxcbiAgaXNXZWxsQ2FsaWJyYXRlZCxcbiAgZ2V0Q2FsaWJyYXRpb25RdWFsaXR5LFxuICAvLyBMaW5raW5nIGhlbHBlcnNcbiAgZ2VuZXJhdGVaZW5kZXNrTWFya2VyLFxuICBwYXJzZVplbmRlc2tNYXJrZXIsXG4gIGhhc1plbmRlc2tNYXJrZXIsXG4gIHJlbW92ZVplbmRlc2tNYXJrZXIsXG4gIGxpbmtSdW5Ub1RpY2tldCxcbiAgbGlua1J1blRvWmVuZGVza1RpY2tldCxcbiAgZ2V0QmVzdExpbmtNZXRob2QsXG4gIExJTktfTUVUSE9EX0NPTkZJREVOQ0UsXG4gIC8vIEN1c3RvbWVyIGNvbnRleHQgaGVscGVyc1xuICBjYXB0dXJlQ3VzdG9tZXJDb250ZXh0LFxuICBnZXRDb250ZXh0QXNPZixcbiAgdG9Db250ZXh0U25hcHNob3QsXG4gIGNhbGN1bGF0ZUFyckNoYW5nZSxcbiAgY2FsY3VsYXRlSGVhbHRoVHJlbmQsXG59O1xuXG4vLyBSZS1leHBvcnQgZXJyb3JzXG5leHBvcnQgeyBUaGlua0hpdmVBcGlFcnJvciwgVGhpbmtIaXZlVmFsaWRhdGlvbkVycm9yIH07XG5cbi8vIERlZmF1bHQgZXhwb3J0IGZvciBjb252ZW5pZW5jZVxuZXhwb3J0IGRlZmF1bHQge1xuICBpbml0LFxuICBnZXRUcmFjZXIsXG4gIHNodXRkb3duLFxuICBpc0luaXRpYWxpemVkLFxuICAvLyBUcmFjaW5nXG4gIHRyYWNlTExNLFxuICB0cmFjZVJldHJpZXZhbCxcbiAgdHJhY2VUb29sLFxuICB0cmFjZUNoYWluLFxuICAvLyBBUEkgY2xpZW50c1xuICBydW5zLFxuICBjbGFpbXMsXG4gIGNhbGlicmF0aW9uLFxuICBsaW5raW5nLFxuICBjdXN0b21lckNvbnRleHQsXG4gIC8vIFYyIGNvbXBhdGliaWxpdHlcbiAgZXhwbGFpbmVyLFxuICAvLyBIZWxwZXJzXG4gIGdlbmVyYXRlWmVuZGVza01hcmtlcixcbiAgcGFyc2VaZW5kZXNrTWFya2VyLFxuICBsaW5rUnVuVG9UaWNrZXQsXG4gIGNyZWF0ZVJ1bldpdGhDb250ZXh0LFxuICAvLyBVdGlsaXRpZXNcbiAgaXNGYWN0LFxuICBpc0luZmVyZW5jZSxcbiAgY2FsY3VsYXRlQnJpZXJTY29yZSxcbiAgaXNXZWxsQ2FsaWJyYXRlZCxcbn07XG4iXX0=
|