@plumile/router 0.1.52 → 0.1.54
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/lib/ResourcePage.d.ts +12 -0
- package/lib/ResourcePage.d.ts.map +1 -0
- package/lib/ResourcePage.js +38 -0
- package/lib/asyncResource.d.ts +8 -0
- package/lib/asyncResource.d.ts.map +1 -0
- package/lib/asyncResource.js +101 -0
- package/lib/builder.d.ts +13 -0
- package/lib/builder.d.ts.map +1 -0
- package/lib/builder.js +72 -0
- package/lib/errors/HttpRedirect.d.ts +6 -0
- package/lib/errors/HttpRedirect.d.ts.map +1 -0
- package/lib/errors/HttpRedirect.js +11 -0
- package/lib/errors/index.d.ts +2 -0
- package/lib/errors/index.d.ts.map +1 -0
- package/lib/errors/index.js +2 -0
- package/lib/eslint-rules/index.d.ts +2 -0
- package/lib/eslint-rules/index.d.ts.map +1 -0
- package/lib/eslint-rules/index.js +2 -0
- package/lib/eslint-rules/no-direct-window-location-search.d.ts +4 -0
- package/lib/eslint-rules/no-direct-window-location-search.d.ts.map +1 -0
- package/lib/eslint-rules/no-direct-window-location-search.js +48 -0
- package/lib/history/BrowserHistory.d.ts +21 -0
- package/lib/history/BrowserHistory.d.ts.map +1 -0
- package/lib/history/BrowserHistory.js +139 -0
- package/lib/history/index.d.ts +3 -0
- package/lib/history/index.d.ts.map +1 -0
- package/lib/history/index.js +2 -0
- package/lib/history/types.d.ts +19 -0
- package/lib/history/types.d.ts.map +1 -0
- package/lib/history/types.js +2 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +9 -0
- package/lib/instrumentation/Instrumentation.d.ts +90 -0
- package/lib/instrumentation/Instrumentation.d.ts.map +1 -0
- package/lib/instrumentation/Instrumentation.js +59 -0
- package/lib/instrumentation/adapters/devtoolsBridge.d.ts +14 -0
- package/lib/instrumentation/adapters/devtoolsBridge.d.ts.map +1 -0
- package/lib/instrumentation/adapters/devtoolsBridge.js +133 -0
- package/lib/instrumentation/adapters/logger.d.ts +10 -0
- package/lib/instrumentation/adapters/logger.d.ts.map +1 -0
- package/lib/instrumentation/adapters/logger.js +19 -0
- package/lib/instrumentation/index.d.ts +4 -0
- package/lib/instrumentation/index.d.ts.map +1 -0
- package/lib/instrumentation/index.js +4 -0
- package/lib/prepareResource.d.ts +4 -0
- package/lib/prepareResource.d.ts.map +1 -0
- package/lib/prepareResource.js +11 -0
- package/lib/routing/Link.d.ts +23 -0
- package/lib/routing/Link.d.ts.map +1 -0
- package/lib/routing/Link.js +158 -0
- package/lib/routing/RouteComponent.d.ts +8 -0
- package/lib/routing/RouteComponent.d.ts.map +1 -0
- package/lib/routing/RouteComponent.js +20 -0
- package/lib/routing/RouteComponentWrapper.d.ts +11 -0
- package/lib/routing/RouteComponentWrapper.d.ts.map +1 -0
- package/lib/routing/RouteComponentWrapper.js +101 -0
- package/lib/routing/RouterRenderer.d.ts +10 -0
- package/lib/routing/RouterRenderer.d.ts.map +1 -0
- package/lib/routing/RouterRenderer.js +67 -0
- package/lib/routing/RoutingContext.d.ts +5 -0
- package/lib/routing/RoutingContext.d.ts.map +1 -0
- package/lib/routing/RoutingContext.js +4 -0
- package/lib/routing/createRouter.d.ts +19 -0
- package/lib/routing/createRouter.d.ts.map +1 -0
- package/lib/routing/createRouter.js +604 -0
- package/lib/routing/index.d.ts +16 -0
- package/lib/routing/index.d.ts.map +1 -0
- package/lib/routing/index.js +16 -0
- package/lib/routing/useAllQuery.d.ts +7 -0
- package/lib/routing/useAllQuery.d.ts.map +1 -0
- package/lib/routing/useAllQuery.js +31 -0
- package/lib/routing/useFilterDiagnostics.d.ts +2 -0
- package/lib/routing/useFilterDiagnostics.d.ts.map +1 -0
- package/lib/routing/useFilterDiagnostics.js +11 -0
- package/lib/routing/useFilters.d.ts +8 -0
- package/lib/routing/useFilters.d.ts.map +1 -0
- package/lib/routing/useFilters.js +65 -0
- package/lib/routing/useLocation.d.ts +2 -0
- package/lib/routing/useLocation.d.ts.map +1 -0
- package/lib/routing/useLocation.js +24 -0
- package/lib/routing/useNavigate.d.ts +7 -0
- package/lib/routing/useNavigate.d.ts.map +1 -0
- package/lib/routing/useNavigate.js +11 -0
- package/lib/routing/usePathname.d.ts +2 -0
- package/lib/routing/usePathname.d.ts.map +1 -0
- package/lib/routing/usePathname.js +9 -0
- package/lib/routing/useQuery.d.ts +2 -0
- package/lib/routing/useQuery.d.ts.map +1 -0
- package/lib/routing/useQuery.js +9 -0
- package/lib/routing/useQueryState.d.ts +13 -0
- package/lib/routing/useQueryState.d.ts.map +1 -0
- package/lib/routing/useQueryState.js +45 -0
- package/lib/routing/useSearchParams.d.ts +11 -0
- package/lib/routing/useSearchParams.d.ts.map +1 -0
- package/lib/routing/useSearchParams.js +67 -0
- package/lib/tools/buildCombinedSearch.d.ts +8 -0
- package/lib/tools/buildCombinedSearch.d.ts.map +1 -0
- package/lib/tools/buildCombinedSearch.js +76 -0
- package/lib/tools/index.d.ts +3 -0
- package/lib/tools/index.d.ts.map +1 -0
- package/lib/tools/index.js +13 -0
- package/lib/tools/query.d.ts +2 -0
- package/lib/tools/query.d.ts.map +1 -0
- package/lib/tools/query.js +43 -0
- package/lib/tools.d.ts +15 -0
- package/lib/tools.d.ts.map +1 -0
- package/lib/tools.js +179 -0
- package/lib/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/types.d.ts +245 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +2 -0
- package/lib/values.d.ts +19 -0
- package/lib/values.d.ts.map +1 -0
- package/lib/values.js +53 -0
- package/package.json +2 -2
|
@@ -0,0 +1,604 @@
|
|
|
1
|
+
import { buildRoutes } from '../builder.js';
|
|
2
|
+
import { BrowserHistory } from '../history/index.js';
|
|
3
|
+
import { getMatchedRoute, prepareMatch } from '../tools.js';
|
|
4
|
+
import { parseRawQuery } from '../tools/query.js';
|
|
5
|
+
import buildCombinedSearch from '../tools/buildCombinedSearch.js';
|
|
6
|
+
import { FILTER_OPERATORS, parse as parseFilters, } from '@plumile/filter-query';
|
|
7
|
+
import { createInstrumentationRegistry, } from '../instrumentation/Instrumentation.js';
|
|
8
|
+
import { isRouterNavigationSource, } from '../values.js';
|
|
9
|
+
export default function createRouter(routes, options = {}) {
|
|
10
|
+
const history = new BrowserHistory();
|
|
11
|
+
const registry = createInstrumentationRegistry(options.instrumentations ?? []);
|
|
12
|
+
let staticContext;
|
|
13
|
+
if (options.getContext == null) {
|
|
14
|
+
if (typeof options.context === 'function') {
|
|
15
|
+
staticContext = options.context();
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
staticContext = options.context;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function resolveContext() {
|
|
22
|
+
if (options.getContext != null) {
|
|
23
|
+
return options.getContext();
|
|
24
|
+
}
|
|
25
|
+
return staticContext;
|
|
26
|
+
}
|
|
27
|
+
let pendingNavigationOrigin;
|
|
28
|
+
let lastNavigationOrigin = 'external';
|
|
29
|
+
let lastPreloadSignature = null;
|
|
30
|
+
function normalizeLocation(location) {
|
|
31
|
+
let pathnameValue = '';
|
|
32
|
+
if (typeof location.pathname === 'string') {
|
|
33
|
+
pathnameValue = location.pathname;
|
|
34
|
+
}
|
|
35
|
+
let searchValue = '';
|
|
36
|
+
if (typeof location.search === 'string') {
|
|
37
|
+
searchValue = location.search;
|
|
38
|
+
}
|
|
39
|
+
let hashValue = '';
|
|
40
|
+
if (typeof location.hash === 'string') {
|
|
41
|
+
hashValue = location.hash;
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
pathname: pathnameValue,
|
|
45
|
+
search: searchValue,
|
|
46
|
+
hash: hashValue,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function emitEvent(event) {
|
|
50
|
+
registry.emitEvent(event);
|
|
51
|
+
}
|
|
52
|
+
function mapOrigin(raw) {
|
|
53
|
+
if (isRouterNavigationSource(raw)) {
|
|
54
|
+
return raw;
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const filterOperators = new Set(FILTER_OPERATORS);
|
|
59
|
+
function looksLikeFilters(value) {
|
|
60
|
+
if (value == null || typeof value !== 'object' || Array.isArray(value)) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const record = value;
|
|
64
|
+
for (const fieldValue of Object.values(record)) {
|
|
65
|
+
if (fieldValue != null &&
|
|
66
|
+
typeof fieldValue === 'object' &&
|
|
67
|
+
!Array.isArray(fieldValue)) {
|
|
68
|
+
for (const key of Object.keys(fieldValue)) {
|
|
69
|
+
if (filterOperators.has(key)) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
function resolveNavigationOrigin(context) {
|
|
78
|
+
const fallbackOrigin = pendingNavigationOrigin;
|
|
79
|
+
let origin;
|
|
80
|
+
const contextOrigin = context?.origin;
|
|
81
|
+
if (contextOrigin !== undefined) {
|
|
82
|
+
origin = mapOrigin(contextOrigin);
|
|
83
|
+
}
|
|
84
|
+
origin ??= fallbackOrigin;
|
|
85
|
+
origin ??= 'external';
|
|
86
|
+
pendingNavigationOrigin = undefined;
|
|
87
|
+
return origin;
|
|
88
|
+
}
|
|
89
|
+
function readMatchedRoutePath(entry) {
|
|
90
|
+
if (entry === undefined) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const matchedRoute = entry.route;
|
|
94
|
+
if (matchedRoute === null) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
const childRoutes = matchedRoute.route.routes;
|
|
98
|
+
if (Array.isArray(childRoutes)) {
|
|
99
|
+
const lastChild = childRoutes.at(-1);
|
|
100
|
+
if (lastChild !== undefined) {
|
|
101
|
+
const lastChildRecord = lastChild;
|
|
102
|
+
const childPath = lastChildRecord.path;
|
|
103
|
+
if (typeof childPath === 'string') {
|
|
104
|
+
return childPath;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const rootPath = matchedRoute.route.path;
|
|
109
|
+
if (typeof rootPath === 'string') {
|
|
110
|
+
return rootPath;
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
function readActiveQuerySchema(route) {
|
|
115
|
+
return route?.route.routes.at(-1)?.querySchema;
|
|
116
|
+
}
|
|
117
|
+
function parseSearchState(search, querySchema) {
|
|
118
|
+
const query = parseRawQuery(search);
|
|
119
|
+
if (querySchema == null) {
|
|
120
|
+
return { query };
|
|
121
|
+
}
|
|
122
|
+
const parsed = parseFilters(search, querySchema);
|
|
123
|
+
return {
|
|
124
|
+
query,
|
|
125
|
+
filters: parsed.filters,
|
|
126
|
+
filterDiagnostics: parsed.diagnostics,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function readPageValue(filters) {
|
|
130
|
+
if (filters == null) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
const rawPage = filters.page;
|
|
134
|
+
if (typeof rawPage === 'number') {
|
|
135
|
+
return rawPage;
|
|
136
|
+
}
|
|
137
|
+
if (rawPage != null &&
|
|
138
|
+
typeof rawPage === 'object' &&
|
|
139
|
+
!Array.isArray(rawPage) &&
|
|
140
|
+
typeof rawPage.eq === 'number') {
|
|
141
|
+
return rawPage.eq;
|
|
142
|
+
}
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
function normalizePageFilters(filters) {
|
|
146
|
+
const pageValue = readPageValue(filters);
|
|
147
|
+
if (pageValue == null || pageValue >= 1 || filters == null) {
|
|
148
|
+
return {
|
|
149
|
+
filters,
|
|
150
|
+
normalized: false,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
filters: {
|
|
155
|
+
...filters,
|
|
156
|
+
page: { eq: 1 },
|
|
157
|
+
},
|
|
158
|
+
normalized: true,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function buildPrepareQueryInput(state, querySchema) {
|
|
162
|
+
if (querySchema != null) {
|
|
163
|
+
return state.filters ?? {};
|
|
164
|
+
}
|
|
165
|
+
return state.query;
|
|
166
|
+
}
|
|
167
|
+
function buildEntrySnapshot(entry) {
|
|
168
|
+
const preparedSegments = entry.preparedMatch.segments.map((segment) => {
|
|
169
|
+
return {
|
|
170
|
+
path: segment.path,
|
|
171
|
+
fullPath: segment.fullPath,
|
|
172
|
+
segmentIndex: segment.segmentIndex,
|
|
173
|
+
preparedResource: segment.preparedResource,
|
|
174
|
+
redirectTo: segment.redirectTo,
|
|
175
|
+
highlightId: segment.highlightId,
|
|
176
|
+
querySchema: segment.querySchema,
|
|
177
|
+
preparedStatus: segment.preparedResource?.getStatus(),
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
return {
|
|
181
|
+
location: normalizeLocation(entry.location),
|
|
182
|
+
routePath: readMatchedRoutePath(entry),
|
|
183
|
+
preparedMatch: {
|
|
184
|
+
segments: preparedSegments,
|
|
185
|
+
routes: preparedSegments,
|
|
186
|
+
},
|
|
187
|
+
filters: entry.filters,
|
|
188
|
+
filterDiagnostics: entry.filterDiagnostics,
|
|
189
|
+
activeQuerySchema: entry.activeQuerySchema,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function notifyEntry(entry) {
|
|
193
|
+
registry.notifyEntryChange(buildEntrySnapshot(entry));
|
|
194
|
+
}
|
|
195
|
+
function buildPreloadKey(mode, pathname) {
|
|
196
|
+
return `${mode}:${pathname}`;
|
|
197
|
+
}
|
|
198
|
+
function emitPreloadEvent(mode, pathname, source) {
|
|
199
|
+
const now = Date.now();
|
|
200
|
+
const key = buildPreloadKey(mode, pathname);
|
|
201
|
+
const recentlyRecorded = lastPreloadSignature !== null &&
|
|
202
|
+
lastPreloadSignature.key === key &&
|
|
203
|
+
now - lastPreloadSignature.timestamp < 50;
|
|
204
|
+
if (!recentlyRecorded) {
|
|
205
|
+
emitEvent({
|
|
206
|
+
kind: 'preload',
|
|
207
|
+
source,
|
|
208
|
+
timestamp: now,
|
|
209
|
+
location: normalizeLocation(history.location),
|
|
210
|
+
targetPathname: pathname,
|
|
211
|
+
mode,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
lastPreloadSignature = { key, timestamp: now };
|
|
215
|
+
}
|
|
216
|
+
function emitHistoryEvent(action, source, location, details) {
|
|
217
|
+
pendingNavigationOrigin = source;
|
|
218
|
+
emitEvent({
|
|
219
|
+
kind: 'history',
|
|
220
|
+
source,
|
|
221
|
+
action,
|
|
222
|
+
timestamp: Date.now(),
|
|
223
|
+
location: normalizeLocation(location),
|
|
224
|
+
details,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
const flatRoutes = buildRoutes(routes);
|
|
228
|
+
const route = getMatchedRoute(flatRoutes, history.location);
|
|
229
|
+
const initialUnifiedSchema = readActiveQuerySchema(route);
|
|
230
|
+
const initialSearchState = parseSearchState(history.location.search, initialUnifiedSchema);
|
|
231
|
+
const normalizedInitialFilters = normalizePageFilters(initialSearchState.filters);
|
|
232
|
+
const initialLocationSnapshot = normalizeLocation(history.location);
|
|
233
|
+
let initialInstrumentation;
|
|
234
|
+
if (route != null) {
|
|
235
|
+
initialInstrumentation = {
|
|
236
|
+
emit: (event) => {
|
|
237
|
+
emitEvent(event);
|
|
238
|
+
},
|
|
239
|
+
source: lastNavigationOrigin,
|
|
240
|
+
location: initialLocationSnapshot,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
const initialContext = resolveContext();
|
|
244
|
+
const preparedMatch = prepareMatch(route, buildPrepareQueryInput({
|
|
245
|
+
...initialSearchState,
|
|
246
|
+
filters: normalizedInitialFilters.filters,
|
|
247
|
+
}, initialUnifiedSchema), initialInstrumentation, initialContext);
|
|
248
|
+
let currentEntry = {
|
|
249
|
+
forceRerender: false,
|
|
250
|
+
location: history.location,
|
|
251
|
+
route,
|
|
252
|
+
preparedMatch,
|
|
253
|
+
context: initialContext,
|
|
254
|
+
rawSearch: history.location.search,
|
|
255
|
+
query: initialSearchState.query,
|
|
256
|
+
filters: normalizedInitialFilters.filters,
|
|
257
|
+
filterDiagnostics: initialSearchState.filterDiagnostics,
|
|
258
|
+
activeQuerySchema: initialUnifiedSchema,
|
|
259
|
+
};
|
|
260
|
+
if (normalizedInitialFilters.normalized &&
|
|
261
|
+
initialUnifiedSchema != null &&
|
|
262
|
+
normalizedInitialFilters.filters != null) {
|
|
263
|
+
currentEntry.filters = normalizedInitialFilters.filters;
|
|
264
|
+
const normalizedSearch = buildCombinedSearch({
|
|
265
|
+
filters: normalizedInitialFilters.filters,
|
|
266
|
+
query: initialSearchState.query,
|
|
267
|
+
querySchema: initialUnifiedSchema,
|
|
268
|
+
});
|
|
269
|
+
if (normalizedSearch !== history.location.search) {
|
|
270
|
+
emitHistoryEvent('normalize', 'normalize', {
|
|
271
|
+
pathname: history.location.pathname,
|
|
272
|
+
search: normalizedSearch,
|
|
273
|
+
hash: '',
|
|
274
|
+
}, { reason: 'initial-page-clamp' });
|
|
275
|
+
const normalizeDebugContext = {
|
|
276
|
+
origin: 'normalize',
|
|
277
|
+
trigger: 'normalize',
|
|
278
|
+
};
|
|
279
|
+
history.set({
|
|
280
|
+
pathname: history.location.pathname,
|
|
281
|
+
search: normalizedSearch,
|
|
282
|
+
hash: '',
|
|
283
|
+
debugContext: normalizeDebugContext,
|
|
284
|
+
});
|
|
285
|
+
currentEntry = {
|
|
286
|
+
...currentEntry,
|
|
287
|
+
location: { ...currentEntry.location, search: normalizedSearch },
|
|
288
|
+
rawSearch: normalizedSearch,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
notifyEntry(currentEntry);
|
|
293
|
+
emitEvent({
|
|
294
|
+
kind: 'snapshot',
|
|
295
|
+
source: lastNavigationOrigin,
|
|
296
|
+
timestamp: Date.now(),
|
|
297
|
+
location: normalizeLocation(currentEntry.location),
|
|
298
|
+
routePath: readMatchedRoutePath(currentEntry),
|
|
299
|
+
});
|
|
300
|
+
let nextId = 0;
|
|
301
|
+
const subscribers = new Map();
|
|
302
|
+
const disposeHistory = history.subscribe((location, forceRerender, debugContext) => {
|
|
303
|
+
const origin = resolveNavigationOrigin(debugContext);
|
|
304
|
+
lastNavigationOrigin = origin;
|
|
305
|
+
const locationPayload = normalizeLocation(location);
|
|
306
|
+
const debugContextOrigin = debugContext?.origin;
|
|
307
|
+
if (debugContextOrigin !== undefined) {
|
|
308
|
+
let historyDetails;
|
|
309
|
+
if (typeof debugContext?.historyIndex === 'number') {
|
|
310
|
+
historyDetails = { historyIndex: debugContext.historyIndex };
|
|
311
|
+
}
|
|
312
|
+
if (debugContextOrigin === 'popstate-back' ||
|
|
313
|
+
debugContextOrigin === 'popstate-forward' ||
|
|
314
|
+
debugContextOrigin === 'popstate-unknown' ||
|
|
315
|
+
debugContextOrigin === 'external') {
|
|
316
|
+
let direction = 'unknown';
|
|
317
|
+
if (debugContextOrigin === 'popstate-back') {
|
|
318
|
+
direction = 'back';
|
|
319
|
+
}
|
|
320
|
+
else if (debugContextOrigin === 'popstate-forward') {
|
|
321
|
+
direction = 'forward';
|
|
322
|
+
}
|
|
323
|
+
emitEvent({
|
|
324
|
+
kind: 'popstate',
|
|
325
|
+
source: origin,
|
|
326
|
+
timestamp: Date.now(),
|
|
327
|
+
location: locationPayload,
|
|
328
|
+
direction,
|
|
329
|
+
details: historyDetails,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
const samePathname = location.pathname === currentEntry.location.pathname;
|
|
334
|
+
const sameSearch = location.search === currentEntry.rawSearch;
|
|
335
|
+
if (!forceRerender && samePathname && sameSearch) {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
const nextContext = resolveContext();
|
|
339
|
+
let nextPreparedMatch = currentEntry.preparedMatch;
|
|
340
|
+
let nextRoute = currentEntry.route;
|
|
341
|
+
if (!samePathname) {
|
|
342
|
+
nextRoute = getMatchedRoute(flatRoutes, location);
|
|
343
|
+
}
|
|
344
|
+
const querySchema = readActiveQuerySchema(nextRoute);
|
|
345
|
+
const parsedSearchState = parseSearchState(location.search, querySchema);
|
|
346
|
+
const normalizedFilters = normalizePageFilters(parsedSearchState.filters);
|
|
347
|
+
if (!samePathname || !sameSearch) {
|
|
348
|
+
let updateInstrumentation;
|
|
349
|
+
if (nextRoute != null) {
|
|
350
|
+
updateInstrumentation = {
|
|
351
|
+
emit: (event) => {
|
|
352
|
+
emitEvent(event);
|
|
353
|
+
},
|
|
354
|
+
source: origin,
|
|
355
|
+
location: locationPayload,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
nextPreparedMatch = prepareMatch(nextRoute, buildPrepareQueryInput({
|
|
359
|
+
...parsedSearchState,
|
|
360
|
+
filters: normalizedFilters.filters,
|
|
361
|
+
}, querySchema), updateInstrumentation, nextContext);
|
|
362
|
+
}
|
|
363
|
+
const nextEntry = {
|
|
364
|
+
forceRerender: forceRerender || (samePathname && !sameSearch),
|
|
365
|
+
location,
|
|
366
|
+
route: nextRoute,
|
|
367
|
+
preparedMatch: nextPreparedMatch,
|
|
368
|
+
context: nextContext,
|
|
369
|
+
rawSearch: location.search,
|
|
370
|
+
query: parsedSearchState.query,
|
|
371
|
+
filters: normalizedFilters.filters,
|
|
372
|
+
filterDiagnostics: parsedSearchState.filterDiagnostics,
|
|
373
|
+
activeQuerySchema: querySchema,
|
|
374
|
+
};
|
|
375
|
+
if (normalizedFilters.normalized && querySchema != null) {
|
|
376
|
+
const normalizedSearch = buildCombinedSearch({
|
|
377
|
+
filters: normalizedFilters.filters,
|
|
378
|
+
query: parsedSearchState.query,
|
|
379
|
+
querySchema,
|
|
380
|
+
});
|
|
381
|
+
if (normalizedSearch !== location.search) {
|
|
382
|
+
let nextSearchStr = normalizedSearch;
|
|
383
|
+
if (!nextSearchStr.startsWith('?') && nextSearchStr.length > 0) {
|
|
384
|
+
nextSearchStr = `?${nextSearchStr}`;
|
|
385
|
+
}
|
|
386
|
+
emitHistoryEvent('normalize', 'normalize', {
|
|
387
|
+
pathname: location.pathname,
|
|
388
|
+
search: nextSearchStr,
|
|
389
|
+
hash: '',
|
|
390
|
+
}, { reason: 'runtime-page-clamp' });
|
|
391
|
+
const runtimeNormalizeContext = {
|
|
392
|
+
origin: 'normalize',
|
|
393
|
+
trigger: 'normalize',
|
|
394
|
+
};
|
|
395
|
+
history.set({
|
|
396
|
+
pathname: location.pathname,
|
|
397
|
+
search: nextSearchStr,
|
|
398
|
+
hash: '',
|
|
399
|
+
debugContext: runtimeNormalizeContext,
|
|
400
|
+
});
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
currentEntry = nextEntry;
|
|
405
|
+
subscribers.forEach((callback) => {
|
|
406
|
+
callback(nextEntry);
|
|
407
|
+
});
|
|
408
|
+
notifyEntry(nextEntry);
|
|
409
|
+
emitEvent({
|
|
410
|
+
kind: 'snapshot',
|
|
411
|
+
source: origin,
|
|
412
|
+
timestamp: Date.now(),
|
|
413
|
+
location: locationPayload,
|
|
414
|
+
routePath: readMatchedRoutePath(nextEntry),
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
function normalizePreloadTarget(target) {
|
|
418
|
+
let normalizedPathname = history.location.pathname;
|
|
419
|
+
if (typeof target.pathname === 'string' && target.pathname.length > 0) {
|
|
420
|
+
normalizedPathname = target.pathname;
|
|
421
|
+
}
|
|
422
|
+
let normalizedSearch = '';
|
|
423
|
+
if (typeof target.search === 'string') {
|
|
424
|
+
normalizedSearch = target.search;
|
|
425
|
+
}
|
|
426
|
+
let normalizedSource = 'programmatic';
|
|
427
|
+
const mappedSource = mapOrigin(target.source);
|
|
428
|
+
if (mappedSource !== undefined) {
|
|
429
|
+
normalizedSource = mappedSource;
|
|
430
|
+
}
|
|
431
|
+
return {
|
|
432
|
+
pathname: normalizedPathname,
|
|
433
|
+
search: normalizedSearch,
|
|
434
|
+
source: normalizedSource,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
function getPrepared(path) {
|
|
438
|
+
try {
|
|
439
|
+
const entry = currentEntry;
|
|
440
|
+
for (const preparedRoute of entry.preparedMatch.segments) {
|
|
441
|
+
if (preparedRoute.path === path || preparedRoute.fullPath === path) {
|
|
442
|
+
const preparedValue = preparedRoute.preparedResource?.get();
|
|
443
|
+
return preparedValue;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return undefined;
|
|
447
|
+
}
|
|
448
|
+
catch {
|
|
449
|
+
return undefined;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
function getPreparedSegments(path) {
|
|
453
|
+
return currentEntry.preparedMatch.segments
|
|
454
|
+
.filter((preparedRoute) => {
|
|
455
|
+
return preparedRoute.path === path || preparedRoute.fullPath === path;
|
|
456
|
+
})
|
|
457
|
+
.map((preparedRoute) => {
|
|
458
|
+
return {
|
|
459
|
+
path: preparedRoute.path,
|
|
460
|
+
fullPath: preparedRoute.fullPath,
|
|
461
|
+
segmentIndex: preparedRoute.segmentIndex,
|
|
462
|
+
preparedResource: preparedRoute.preparedResource,
|
|
463
|
+
redirectTo: preparedRoute.redirectTo,
|
|
464
|
+
resourcePage: preparedRoute.resourcePage,
|
|
465
|
+
highlightId: preparedRoute.highlightId,
|
|
466
|
+
querySchema: preparedRoute.querySchema,
|
|
467
|
+
};
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
const context = {
|
|
471
|
+
history,
|
|
472
|
+
get() {
|
|
473
|
+
return currentEntry;
|
|
474
|
+
},
|
|
475
|
+
preloadCode(target) {
|
|
476
|
+
const normalized = normalizePreloadTarget(target);
|
|
477
|
+
emitPreloadEvent('code', normalized.pathname, normalized.source);
|
|
478
|
+
const matches = getMatchedRoute(flatRoutes, {
|
|
479
|
+
...history.location,
|
|
480
|
+
pathname: normalized.pathname,
|
|
481
|
+
});
|
|
482
|
+
if (matches == null) {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
matches.route.routes.forEach(({ resourcePage }) => {
|
|
486
|
+
if (resourcePage == null) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
resourcePage.load();
|
|
490
|
+
});
|
|
491
|
+
},
|
|
492
|
+
preload(target) {
|
|
493
|
+
const normalized = normalizePreloadTarget(target);
|
|
494
|
+
emitPreloadEvent('full', normalized.pathname, normalized.source);
|
|
495
|
+
const matches = getMatchedRoute(flatRoutes, {
|
|
496
|
+
...history.location,
|
|
497
|
+
pathname: normalized.pathname,
|
|
498
|
+
});
|
|
499
|
+
const locationSnapshot = {
|
|
500
|
+
pathname: normalized.pathname,
|
|
501
|
+
search: normalized.search,
|
|
502
|
+
hash: '',
|
|
503
|
+
};
|
|
504
|
+
let instrumentation;
|
|
505
|
+
if (matches != null) {
|
|
506
|
+
instrumentation = {
|
|
507
|
+
emit: (event) => {
|
|
508
|
+
emitEvent(event);
|
|
509
|
+
},
|
|
510
|
+
source: normalized.source,
|
|
511
|
+
location: locationSnapshot,
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
const preloadContext = resolveContext();
|
|
515
|
+
const preloadQuerySchema = readActiveQuerySchema(matches);
|
|
516
|
+
const preloadSearchState = parseSearchState(normalized.search, preloadQuerySchema);
|
|
517
|
+
const preparedMatch = prepareMatch(matches, buildPrepareQueryInput(preloadSearchState, preloadQuerySchema), instrumentation, preloadContext);
|
|
518
|
+
preparedMatch.segments.forEach((route) => {
|
|
519
|
+
if (route.preparedResource != null) {
|
|
520
|
+
route.preparedResource.load();
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
},
|
|
524
|
+
subscribe(callback) {
|
|
525
|
+
nextId += 1;
|
|
526
|
+
const id = nextId;
|
|
527
|
+
function disposeCallback() {
|
|
528
|
+
subscribers.delete(id);
|
|
529
|
+
}
|
|
530
|
+
subscribers.set(id, callback);
|
|
531
|
+
return disposeCallback;
|
|
532
|
+
},
|
|
533
|
+
navigate({ pathname, query, filters: navFilters, replace, }) {
|
|
534
|
+
const current = currentEntry;
|
|
535
|
+
let targetPathname = pathname;
|
|
536
|
+
targetPathname ??= current.location.pathname;
|
|
537
|
+
const destinationRoute = getMatchedRoute(flatRoutes, {
|
|
538
|
+
...history.location,
|
|
539
|
+
pathname: targetPathname,
|
|
540
|
+
});
|
|
541
|
+
let destSchema = readActiveQuerySchema(destinationRoute);
|
|
542
|
+
destSchema = destSchema ?? current.activeQuerySchema;
|
|
543
|
+
const hasSchema = destSchema != null;
|
|
544
|
+
const useQueryAsFilters = navFilters == null &&
|
|
545
|
+
hasSchema &&
|
|
546
|
+
query != null &&
|
|
547
|
+
looksLikeFilters(query);
|
|
548
|
+
let filtersInput = navFilters;
|
|
549
|
+
if (filtersInput == null) {
|
|
550
|
+
if (useQueryAsFilters) {
|
|
551
|
+
filtersInput = query;
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
filtersInput = current.filters;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
let rawQueryInput;
|
|
558
|
+
if (useQueryAsFilters) {
|
|
559
|
+
rawQueryInput = current.query;
|
|
560
|
+
}
|
|
561
|
+
else {
|
|
562
|
+
rawQueryInput = query ?? current.query;
|
|
563
|
+
}
|
|
564
|
+
const search = buildCombinedSearch({
|
|
565
|
+
filters: filtersInput,
|
|
566
|
+
query: rawQueryInput,
|
|
567
|
+
querySchema: destSchema,
|
|
568
|
+
});
|
|
569
|
+
const locationObj = { pathname: targetPathname, search, hash: '' };
|
|
570
|
+
const origin = 'programmatic';
|
|
571
|
+
const debugContext = {
|
|
572
|
+
origin,
|
|
573
|
+
trigger: 'programmatic',
|
|
574
|
+
};
|
|
575
|
+
if (replace === true) {
|
|
576
|
+
emitHistoryEvent('replace', origin, locationObj, {
|
|
577
|
+
trigger: 'programmatic',
|
|
578
|
+
});
|
|
579
|
+
history.set({
|
|
580
|
+
...locationObj,
|
|
581
|
+
debugContext,
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
emitHistoryEvent('push', origin, locationObj, {
|
|
586
|
+
trigger: 'programmatic',
|
|
587
|
+
});
|
|
588
|
+
history.push({
|
|
589
|
+
...locationObj,
|
|
590
|
+
debugContext,
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
getPrepared,
|
|
595
|
+
getPreparedSegments,
|
|
596
|
+
};
|
|
597
|
+
function cleanup() {
|
|
598
|
+
disposeHistory();
|
|
599
|
+
subscribers.clear();
|
|
600
|
+
registry.dispose();
|
|
601
|
+
}
|
|
602
|
+
return { context, cleanup };
|
|
603
|
+
}
|
|
604
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlUm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JvdXRpbmcvY3JlYXRlUm91dGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNsRCxPQUFPLG1CQUFtQixNQUFNLGlDQUFpQyxDQUFDO0FBQ2xFLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsS0FBSyxJQUFJLFlBQVksR0FHdEIsTUFBTSx1QkFBdUIsQ0FBQztBQWlCL0IsT0FBTyxFQUNMLDZCQUE2QixHQU05QixNQUFNLHVDQUF1QyxDQUFDO0FBRS9DLE9BQU8sRUFDTCx3QkFBd0IsR0FHekIsTUFBTSxjQUFjLENBQUM7QUF1RnRCLE1BQU0sQ0FBQyxPQUFPLFVBQVUsWUFBWSxDQUlsQyxNQUEyQixFQUMzQixVQUF5QyxFQUFFO0lBRzNDLE1BQU0sT0FBTyxHQUFHLElBQUksY0FBYyxFQUFFLENBQUM7SUFFckMsTUFBTSxRQUFRLEdBQUcsNkJBQTZCLENBQzVDLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxFQUFFLENBQy9CLENBQUM7SUFFRixJQUFJLGFBQW1DLENBQUM7SUFDeEMsSUFBSSxPQUFPLENBQUMsVUFBVSxJQUFJLElBQUksRUFBRSxDQUFDO1FBQy9CLElBQUksT0FBTyxPQUFPLENBQUMsT0FBTyxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQzFDLGFBQWEsR0FBSSxPQUFPLENBQUMsT0FBMEIsRUFBRSxDQUFDO1FBQ3hELENBQUM7YUFBTSxDQUFDO1lBQ04sYUFBYSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFDbEMsQ0FBQztJQUNI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aUJBQ2IsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFO29CQUM1QyxPQUFPLEVBQUUsY0FBYztpQkFDeEIsQ0FBQyxDQUFDO2dCQUNILE9BQU8sQ0FBQyxJQUFJLENBQUM7b0JBQ1gsR0FBRyxXQUFXO29CQUNkLFlBQVk7aUJBQ2IsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7UUFDRCxXQUFXO1FBQ1gsbUJBQW1CO0tBQzBCLENBQUM7SUFHaEQsU0FBUyxPQUFPO1FBQ2QsY0FBYyxFQUFFLENBQUM7UUFDakIsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3BCLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBR0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQztBQUM5QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYnVpbGRSb3V0ZXMgfSBmcm9tICcuLi9idWlsZGVyLmpzJztcbmltcG9ydCB7IEJyb3dzZXJIaXN0b3J5IH0gZnJvbSAnLi4vaGlzdG9yeS9pbmRleC5qcyc7XG5pbXBvcnQgeyBnZXRNYXRjaGVkUm91dGUsIHByZXBhcmVNYXRjaCB9IGZyb20gJy4uL3Rvb2xzLmpzJztcbmltcG9ydCB7IHBhcnNlUmF3UXVlcnkgfSBmcm9tICcuLi90b29scy9xdWVyeS5qcyc7XG5pbXBvcnQgYnVpbGRDb21iaW5lZFNlYXJjaCBmcm9tICcuLi90b29scy9idWlsZENvbWJpbmVkU2VhcmNoLmpzJztcbmltcG9ydCB7XG4gIEZJTFRFUl9PUEVSQVRPUlMsXG4gIHBhcnNlIGFzIHBhcnNlRmlsdGVycyxcbiAgdHlwZSBEaWFnbm9zdGljIGFzIEZpbHRlckRpYWdub3N0aWMsXG4gIHR5cGUgU2NoZW1hIGFzIEZpbHRlclNjaGVtYSxcbn0gZnJvbSAnQHBsdW1pbGUvZmlsdGVyLXF1ZXJ5JztcbmltcG9ydCB0eXBlIHsgUGFyYW1EYXRhIH0gZnJvbSAncGF0aC10by1yZWdleHAnO1xuaW1wb3J0IHtcbiAgdHlwZSBSb3V0ZUVudHJ5LFxuICB0eXBlIFJvdXRpbmdDb250ZXh0VHlwZSxcbiAgdHlwZSBTdWJzY3JpYmVDYWxsYmFjayxcbiAgdHlwZSBBbnlSb3V0ZSxcbiAgdHlwZSBQcmVwYXJlZEFjY2VzcyxcbiAgdHlwZSBOYXZpZ2F0ZU92ZXJsb2FkcyxcbiAgdHlwZSBQcmVsb2FkVGFyZ2V0LFxuICB0eXBlIFByZXBhcmVkT2YsXG4gIHR5cGUgUHJlcGFyZWRSb3V0ZVNlZ21lbnRTbmFwc2hvdCxcbiAgdHlwZSBSb3V0ZVVuaW9uLFxuICB0eXBlIFJhd1F1ZXJ5LFxuICB0eXBlIFVua25vd25GaWx0ZXJzLFxuICB0eXBlIFVua25vd25RdWVyeVNoYXBlLFxufSBmcm9tICcuLi90eXBlcy5qcyc7XG5pbXBvcnQge1xuICBjcmVhdGVJbnN0cnVtZW50YXRpb25SZWdpc3RyeSxcbiAgdHlwZSBJbnN0cnVtZW50YXRpb25BUEksXG4gIHR5cGUgUm91dGVyRW50cnlTbmFwc2hvdCxcbiAgdHlwZSBSb3V0ZXJMb2NhdGlvblNuYXBzaG90LFxuICB0eXBlIFJvdXRlck5hdmlnYXRpb25Tb3VyY2UsXG4gIHR5cGUgUm91dGVyRXZlbnQsXG59IGZyb20gJy4uL2luc3RydW1lbnRhdGlvbi9JbnN0cnVtZW50YXRpb24uanMnO1xuaW1wb3J0IHR5cGUgeyBIaXN0b3J5RGVidWdDb250ZXh0IH0gZnJvbSAnLi4vaGlzdG9yeS90eXBlcy5qcyc7XG5pbXBvcnQge1xuICBpc1JvdXRlck5hdmlnYXRpb25Tb3VyY2UsXG4gIHR5cGUgUm91dGVySGlzdG9yeUFjdGlvblZhbHVlLFxuICB0eXBlIFJvdXRlclByZWxvYWRNb2RlVmFsdWUsXG59IGZyb20gJy4uL3ZhbHVlcy5qcyc7XG5cbnR5cGUgUm91dGVyUXVlcnlTY2hlbWEgPSBGaWx0ZXJTY2hlbWEgfCB1bmRlZmluZWQ7XG50eXBlIFJvdXRlckVudHJ5U3RhdGU8VENvbnRleHQ+ID0gUm91dGVFbnRyeTxcbiAgUGFyYW1EYXRhLFxuICBSb3V0ZXJRdWVyeVNjaGVtYSxcbiAgVENvbnRleHRcbj47XG50eXBlIFBhcnNlZFNlYXJjaFN0YXRlID0ge1xuICBxdWVyeTogUmF3UXVlcnk7XG4gIGZpbHRlcnM/OiBVbmtub3duRmlsdGVycztcbiAgZmlsdGVyRGlhZ25vc3RpY3M/OiBGaWx0ZXJEaWFnbm9zdGljW107XG59O1xudHlwZSBQcmVwYXJlUXVlcnlJbnB1dCA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXG4vKipcbiAqIFJldHVybiB0eXBlIGZvciB0aGUgY3JlYXRlUm91dGVyIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgdHlwZSBDcmVhdGVSb3V0ZXJSZXR1cm48VENvbnRleHQsIFIgZXh0ZW5kcyBBbnlSb3V0ZVtdPiA9IHtcbiAgLyoqIEZ1bmN0aW9uIHRvIGNsZWFuIHVwIHJvdXRlciBsaXN0ZW5lcnMgYW5kIHJlc291cmNlcyAqL1xuICBjbGVhbnVwOiAoKSA9PiB2b2lkO1xuICAvKiogUm91dGVyIGNvbnRleHQgb2JqZWN0IGZvciB0aGUgUmVhY3QgQ29udGV4dCBQcm92aWRlciAqL1xuICBjb250ZXh0OiBSb3V0aW5nQ29udGV4dFR5cGU8XG4gICAgUGFyYW1EYXRhLFxuICAgIFJvdXRlclF1ZXJ5U2NoZW1hLFxuICAgIFVua25vd25RdWVyeVNoYXBlLFxuICAgIFRDb250ZXh0XG4gID4gJlxuICAgIFByZXBhcmVkQWNjZXNzPFI+ICYge1xuICAgICAgbmF2aWdhdGU6IE5hdmlnYXRlT3ZlcmxvYWRzPFI+O1xuICAgIH07XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjb21wbGV0ZSByb3V0ZXIgc3lzdGVtIGZyb20gcm91dGUgY29uZmlndXJhdGlvbnMuXG4gKlxuICogVGhpcyByb3V0ZXIgaXMgYnVpbHQgZnJvbSB0aGUgc2FtZSBwcmltaXRpdmVzIGFzIHJlYWN0LXJvdXRlciBidXQgd2l0aCBhZGRpdGlvbmFsXG4gKiBmZWF0dXJlcyBmb3IgZGF0YSBwcmVsb2FkaW5nIGFuZCBjb2RlIHNwbGl0dGluZy4gRWFjaCByb3V0ZSBjYW4gY29udGFpbiBib3RoIGFcbiAqIENvbXBvbmVudCBhbmQgYSBwcmVwYXJlKCkgZnVuY3Rpb24gdGhhdCBjYW4gcHJlbG9hZCBkYXRhIGZvciB0aGUgY29tcG9uZW50LlxuICpcbiAqIFRoZSByb3V0ZXIgd2F0Y2hlcyBmb3IgY2hhbmdlcyB0byB0aGUgY3VycmVudCBsb2NhdGlvbiB2aWEgdGhlIEhUTUw1IEhpc3RvcnkgQVBJLFxuICogbWFwcyB0aGUgbG9jYXRpb24gdG8gdGhlIGNvcnJlc3BvbmRpbmcgcm91dGUgZW50cnksIGFuZCB0aGVuIHByZWxvYWRzIHRoZSBjb2RlXG4gKiBhbmQgZGF0YSBmb3IgdGhlIHJvdXRlIGJlZm9yZSByZW5kZXJpbmcuXG4gKlxuICogQHBhcmFtIHJvdXRlcyAtIEFycmF5IG9mIHJvdXRlIGNvbmZpZ3VyYXRpb25zXG4gKiBAcmV0dXJucyBPYmplY3QgY29udGFpbmluZyB0aGUgcm91dGVyIGNvbnRleHQgYW5kIGNsZWFudXAgZnVuY3Rpb25cbiAqXG4gIHByZXBhcmVkTWF0Y2g6IHByZXBhcmVNYXRjaChyb3V0ZSwgcGFyc2VSYXdRdWVyeShoaXN0b3J5LmxvY2F0aW9uLnNlYXJjaCkpLFxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgcm91dGVzID0gW1xuICogICB7XG4gKiAgICAgcGF0aDogJy91c2Vycy86aWQnLFxuICogICAgIHJlc291cmNlUGFnZTogZ2V0UmVzb3VyY2VQYWdlKCdVc2VyUHJvZmlsZScsICgpID0+IGltcG9ydCgnLi9Vc2VyUHJvZmlsZScpKSxcbiAqICAgICBwcmVwYXJlOiAoeyB2YXJpYWJsZXMgfSkgPT4gKHsgdXNlcklkOiB2YXJpYWJsZXMuaWQgfSlcbiAqICAgfVxuICogXTtcbiAqXG4gKiBjb25zdCB7IGNvbnRleHQsIGNsZWFudXAgfSA9IGNyZWF0ZVJvdXRlcihyb3V0ZXMpO1xuICpcbiAqIC8vIFVzZSBpbiBSZWFjdCBhcHBcbiAqIDxSb3V0aW5nQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17Y29udGV4dH0+XG4gKiAgIDxSb3V0ZXJSZW5kZXJlciAvPlxuICogPC9Sb3V0aW5nQ29udGV4dC5Qcm92aWRlcj5cbiAqIGBgYFxuICovXG4vKipcbiAqIENyZWF0ZSBhIHJvdXRlciAodHlwZWQgb3ZlcmxvYWQpLiBXaGVuIGNhbGxlZCB3aXRoIGEgY29uc3QgdHVwbGUgb2Ygcm91dGVzLCBnZW5lcmljcyBhcmUgcHJlc2VydmVkLlxuICovXG4vKipcbiAqIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIGBjcmVhdGVSb3V0ZXJgLlxuICovXG5leHBvcnQgdHlwZSBDcmVhdGVSb3V0ZXJPcHRpb25zPFRDb250ZXh0PiA9IHtcbiAgLyoqIEluc3RydW1lbnRhdGlvbnMgdG8gYXR0YWNoIHRvIHRoZSByb3V0ZXIgKERldlRvb2xzIGJyaWRnZSwgbG9nZ2VyLCAuLi4pLiAqL1xuICBpbnN0cnVtZW50YXRpb25zPzogSW5zdHJ1bWVudGF0aW9uQVBJW107XG4gIC8qKiBTdGF0aWMgY29udGV4dCB2YWx1ZSBvciBsYXp5IGluaXRpYWxpemVyIGZvciB0aGUgcm91dGVyLiAqL1xuICBjb250ZXh0PzogVENvbnRleHQgfCAoKCkgPT4gVENvbnRleHQpO1xuICAvKiogUmVzb2x2ZSBhIGZyZXNoIGNvbnRleHQgdmFsdWUgcGVyIG5hdmlnYXRpb24uICovXG4gIGdldENvbnRleHQ/OiAoKSA9PiBUQ29udGV4dDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIHJvdXRlciBpbnN0YW5jZSBmcm9tIGEgcm91dGUgY29uZmlndXJhdGlvbi5cbiAqXG4gKiBAcGFyYW0gcm91dGVzIC0gUm91dGUgZGVmaW5pdGlvbnMgdG8gcmVnaXN0ZXIuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbmFsIGluc3RydW1lbnRhdGlvbiBzZXR0aW5ncyB1c2VkIGZvciBleHBvc2luZyBkZXZlbG9wbWVudCB0b29saW5nLlxuICogQHBhcmFtIG9wdGlvbnMuaW5zdHJ1bWVudGF0aW9ucyAtIEluc3RydW1lbnRhdGlvbnMgaW52b2tlZCBvbiByb3V0ZXIgZXZlbnRzIChkZXZlbG9wbWVudCBvbmx5KS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY3JlYXRlUm91dGVyPFxuICBUQ29udGV4dCA9IHVua25vd24sXG4gIFIgZXh0ZW5kcyBBbnlSb3V0ZVtdID0gQW55Um91dGVbXSxcbj4oXG4gIHJvdXRlczogWy4uLlJdIHwgQW55Um91dGVbXSxcbiAgb3B0aW9uczogQ3JlYXRlUm91dGVyT3B0aW9uczxUQ29udGV4dD4gPSB7fSxcbik6IENyZWF0ZVJvdXRlclJldHVybjxUQ29udGV4dCwgUj4ge1xuICAvLyBJbml0aWFsaXplIGJyb3dzZXIgaGlzdG9yeSBtYW5hZ2VyXG4gIGNvbnN0IGhpc3RvcnkgPSBuZXcgQnJvd3Nlckhpc3RvcnkoKTtcblxuICBjb25zdCByZWdpc3RyeSA9IGNyZWF0ZUluc3RydW1lbnRhdGlvblJlZ2lzdHJ5KFxuICAgIG9wdGlvbnMuaW5zdHJ1bWVudGF0aW9ucyA/PyBbXSxcbiAgKTtcblxuICBsZXQgc3RhdGljQ29udGV4dDogVENvbnRleHQgfCB1bmRlZmluZWQ7XG4gIGlmIChvcHRpb25zLmdldENvbnRleHQgPT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5jb250ZXh0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBzdGF0aWNDb250ZXh0ID0gKG9wdGlvbnMuY29udGV4dCBhcyAoKSA9PiBUQ29udGV4dCkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGljQ29udGV4dCA9IG9wdGlvbnMuY29udGV4dDtcbiAgICB9XG4gIH1cblxuICAvKiogUmVzb2x2ZSB0aGUgY29udGV4dCBmb3IgdGhlIGN1cnJlbnQgbmF2aWdhdGlvbi4gKi9cbiAgZnVuY3Rpb24gcmVzb2x2ZUNvbnRleHQoKTogVENvbnRleHQge1xuICAgIGlmIChvcHRpb25zLmdldENvbnRleHQgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuZ2V0Q29udGV4dCgpO1xuICAgIH1cbiAgICByZXR1cm4gc3RhdGljQ29udGV4dCBhcyBUQ29udGV4dDtcbiAgfVxuXG4gIGxldCBwZW5kaW5nTmF2aWdhdGlvbk9yaWdpbjogUm91dGVyTmF2aWdhdGlvblNvdXJjZSB8IHVuZGVmaW5lZDtcbiAgbGV0IGxhc3ROYXZpZ2F0aW9uT3JpZ2luOiBSb3V0ZXJOYXZpZ2F0aW9uU291cmNlID0gJ2V4dGVybmFsJztcbiAgbGV0IGxhc3RQcmVsb2FkU2lnbmF0dXJlOiB7XG4gICAga2V5OiBzdHJpbmc7XG4gICAgdGltZXN0YW1wOiBudW1iZXI7XG4gIH0gfCBudWxsID0gbnVsbDtcblxuICAvKipcbiAgICogQ29udmVydHMgYSBwYXJ0aWFsIGxvY2F0aW9uIG9iamVjdCBpbnRvIGEgZnVsbCBsb2NhdGlvbiBzdHJ1Y3R1cmUgd2l0aCBzdHJpbmcgZmllbGRzLlxuICAgKi9cbiAgZnVuY3Rpb24gbm9ybWFsaXplTG9jYXRpb24obG9jYXRpb246IHtcbiAgICBwYXRobmFtZTogc3RyaW5nO1xuICAgIHNlYXJjaD86IHN0cmluZztcbiAgICBoYXNoPzogc3RyaW5nO1xuICB9KTogeyBwYXRobmFtZTogc3RyaW5nOyBzZWFyY2g6IHN0cmluZzsgaGFzaDogc3RyaW5nIH0ge1xuICAgIGxldCBwYXRobmFtZVZhbHVlID0gJyc7XG4gICAgaWYgKHR5cGVvZiBsb2NhdGlvbi5wYXRobmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHBhdGhuYW1lVmFsdWUgPSBsb2NhdGlvbi5wYXRobmFtZTtcbiAgICB9XG4gICAgbGV0IHNlYXJjaFZhbHVlID0gJyc7XG4gICAgaWYgKHR5cGVvZiBsb2NhdGlvbi5zZWFyY2ggPT09ICdzdHJpbmcnKSB7XG4gICAgICBzZWFyY2hWYWx1ZSA9IGxvY2F0aW9uLnNlYXJjaDtcbiAgICB9XG4gICAgbGV0IGhhc2hWYWx1ZSA9ICcnO1xuICAgIGlmICh0eXBlb2YgbG9jYXRpb24uaGFzaCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGhhc2hWYWx1ZSA9IGxvY2F0aW9uLmhhc2g7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBwYXRobmFtZTogcGF0aG5hbWVWYWx1ZSxcbiAgICAgIHNlYXJjaDogc2VhcmNoVmFsdWUsXG4gICAgICBoYXNoOiBoYXNoVmFsdWUsXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBFbWl0cyBhIHJvdXRlciBldmVudCB0byBldmVyeSByZWdpc3RlcmVkIGluc3RydW1lbnRhdGlvbi4gKi9cbiAgZnVuY3Rpb24gZW1pdEV2ZW50KGV2ZW50OiBSb3V0ZXJFdmVudCk6IHZvaWQge1xuICAgIHJlZ2lzdHJ5LmVtaXRFdmVudChldmVudCk7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdHMgdG8gY29lcmNlIGFuIGFyYml0cmFyeSBzdHJpbmcgaW50byBhIGtub3duIG5hdmlnYXRpb24gc291cmNlLlxuICAgKi9cbiAgZnVuY3Rpb24gbWFwT3JpZ2luKHJhdz86IHN0cmluZyk6IFJvdXRlck5hdmlnYXRpb25Tb3VyY2UgfCB1bmRlZmluZWQge1xuICAgIGlmIChpc1JvdXRlck5hdmlnYXRpb25Tb3VyY2UocmF3KSkge1xuICAgICAgcmV0dXJuIHJhdztcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGZpbHRlck9wZXJhdG9ycyA9IG5ldyBTZXQ8c3RyaW5nPihGSUxURVJfT1BFUkFUT1JTKTtcblxuICAvKiogSGV1cmlzdGljOiBkZXRlY3QgZmlsdGVyLWxpa2Ugb2JqZWN0cyB0byBwcmVzZXJ2ZSBsZWdhY3kgbmF2aWdhdGUocXVlcnkpIGJlaGF2aW9yLiAqL1xuICBmdW5jdGlvbiBsb29rc0xpa2VGaWx0ZXJzKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gICAgaWYgKHZhbHVlID09IG51bGwgfHwgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyB8fCBBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCByZWNvcmQgPSB2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBmb3IgKGNvbnN0IGZpZWxkVmFsdWUgb2YgT2JqZWN0LnZhbHVlcyhyZWNvcmQpKSB7XG4gICAgICBpZiAoXG4gICAgICAgIGZpZWxkVmFsdWUgIT0gbnVsbCAmJlxuICAgICAgICB0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgIUFycmF5LmlzQXJyYXkoZmllbGRWYWx1ZSlcbiAgICAgICkge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhmaWVsZFZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSkge1xuICAgICAgICAgIGlmIChmaWx0ZXJPcGVyYXRvcnMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyB0aGUgbW9zdCBhcHByb3ByaWF0ZSBvcmlnaW4gZm9yIHRoZSBjdXJyZW50IG5hdmlnYXRpb24gZXZlbnQuXG4gICAqL1xuICAvKiogUmVzb2x2ZXMgdGhlIG5hdmlnYXRpb24gc291cmNlIGNvbWJpbmluZyBoaXN0b3J5IGNvbnRleHQgYW5kIHBlbmRpbmcgaW50ZW50LiAqL1xuICBmdW5jdGlvbiByZXNvbHZlTmF2aWdhdGlvbk9yaWdpbihcbiAgICBjb250ZXh0PzogSGlzdG9yeURlYnVnQ29udGV4dCB8IG51bGwsXG4gICk6IFJvdXRlck5hdmlnYXRpb25Tb3VyY2Uge1xuICAgIGNvbnN0IGZhbGxiYWNrT3JpZ2luID0gcGVuZGluZ05hdmlnYXRpb25PcmlnaW47XG4gICAgbGV0IG9yaWdpbjogUm91dGVyTmF2aWdhdGlvblNvdXJjZSB8IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGNvbnRleHRPcmlnaW4gPSBjb250ZXh0Py5vcmlnaW47XG4gICAgaWYgKGNvbnRleHRPcmlnaW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgb3JpZ2luID0gbWFwT3JpZ2luKGNvbnRleHRPcmlnaW4pO1xuICAgIH1cblxuICAgIG9yaWdpbiA/Pz0gZmFsbGJhY2tPcmlnaW47XG4gICAgb3JpZ2luID8/PSAnZXh0ZXJuYWwnO1xuICAgIHBlbmRpbmdOYXZpZ2F0aW9uT3JpZ2luID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiBvcmlnaW47XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdHMgdGhlIGlubmVyLW1vc3QgbWF0Y2hlZCByb3V0ZSBwYXRoIGZyb20gYSByb3V0ZSBlbnRyeSB3aGVuIGF2YWlsYWJsZS5cbiAgICovXG4gIC8qKiBSZXR1cm5zIHRoZSBkZWVwZXN0IG1hdGNoZWQgcm91dGUgcGF0aCBmcm9tIGEgcm91dGUgZW50cnkgaWYgYXZhaWxhYmxlLiAqL1xuICBmdW5jdGlvbiByZWFkTWF0Y2hlZFJvdXRlUGF0aChcbiAgICBlbnRyeTogUm91dGVyRW50cnlTdGF0ZTxUQ29udGV4dD4gfCB1bmRlZmluZWQsXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGVudHJ5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IG1hdGNoZWRSb3V0ZSA9IGVudHJ5LnJvdXRlO1xuICAgIGlmIChtYXRjaGVkUm91dGUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IGNoaWxkUm91dGVzID0gbWF0Y2hlZFJvdXRlLnJvdXRlLnJvdXRlcztcbiAgICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZFJvdXRlcykpIHtcbiAgICAgIGNvbnN0IGxhc3RDaGlsZCA9IGNoaWxkUm91dGVzLmF0KC0xKTtcbiAgICAgIGlmIChsYXN0Q2hpbGQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBsYXN0Q2hpbGRSZWNvcmQgPSBsYXN0Q2hpbGQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgIGNvbnN0IGNoaWxkUGF0aCA9IGxhc3RDaGlsZFJlY29yZC5wYXRoO1xuICAgICAgICBpZiAodHlwZW9mIGNoaWxkUGF0aCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICByZXR1cm4gY2hpbGRQYXRoO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHJvb3RQYXRoID0gbWF0Y2hlZFJvdXRlLnJvdXRlLnBhdGg7XG4gICAgaWYgKHR5cGVvZiByb290UGF0aCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiByb290UGF0aDtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRoZSBkZWVwZXN0IGFjdGl2ZSBxdWVyeSBzY2hlbWEgZm9yIGEgbWF0Y2hlZCByb3V0ZS4gKi9cbiAgZnVuY3Rpb24gcmVhZEFjdGl2ZVF1ZXJ5U2NoZW1hKFxuICAgIHJvdXRlOiBSb3V0ZXJFbnRyeVN0YXRlPFRDb250ZXh0Plsncm91dGUnXSxcbiAgKTogUm91dGVyUXVlcnlTY2hlbWEge1xuICAgIHJldHVybiByb3V0ZT8ucm91dGUucm91dGVzLmF0KC0xKT8ucXVlcnlTY2hlbWE7XG4gIH1cblxuICAvKiogUGFyc2VzIHJhdyBxdWVyeSBhbmQgdHlwZWQgZmlsdGVycyBmb3IgdGhlIHByb3ZpZGVkIHNlYXJjaCBzdHJpbmcuICovXG4gIGZ1bmN0aW9uIHBhcnNlU2VhcmNoU3RhdGUoXG4gICAgc2VhcmNoOiBzdHJpbmcsXG4gICAgcXVlcnlTY2hlbWE6IFJvdXRlclF1ZXJ5U2NoZW1hLFxuICApOiBQYXJzZWRTZWFyY2hTdGF0ZSB7XG4gICAgY29uc3QgcXVlcnkgPSBwYXJzZVJhd1F1ZXJ5KHNlYXJjaCk7XG4gICAgaWYgKHF1ZXJ5U2NoZW1hID09IG51bGwpIHtcbiAgICAgIHJldHVybiB7IHF1ZXJ5IH07XG4gICAgfVxuXG4gICAgY29uc3QgcGFyc2VkID0gcGFyc2VGaWx0ZXJzKHNlYXJjaCwgcXVlcnlTY2hlbWEpO1xuICAgIHJldHVybiB7XG4gICAgICBxdWVyeSxcbiAgICAgIGZpbHRlcnM6IHBhcnNlZC5maWx0ZXJzIGFzIFVua25vd25GaWx0ZXJzLFxuICAgICAgZmlsdGVyRGlhZ25vc3RpY3M6IHBhcnNlZC5kaWFnbm9zdGljcyxcbiAgICB9O1xuICB9XG5cbiAgLyoqIFJlYWRzIGEgcGFnZSBudW1iZXIgZnJvbSBlaXRoZXIgYHBhZ2VgIG9yIGBwYWdlLmVxYCBmaWx0ZXIgc2hhcGVzLiAqL1xuICBmdW5jdGlvbiByZWFkUGFnZVZhbHVlKGZpbHRlcnM/OiBVbmtub3duRmlsdGVycyk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGZpbHRlcnMgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCByYXdQYWdlID0gZmlsdGVycy5wYWdlO1xuICAgIGlmICh0eXBlb2YgcmF3UGFnZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiByYXdQYWdlO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICByYXdQYWdlICE9IG51bGwgJiZcbiAgICAgIHR5cGVvZiByYXdQYWdlID09PSAnb2JqZWN0JyAmJlxuICAgICAgIUFycmF5LmlzQXJyYXkocmF3UGFnZSkgJiZcbiAgICAgIHR5cGVvZiAocmF3UGFnZSBhcyB7IGVxPzogdW5rbm93biB9KS5lcSA9PT0gJ251bWJlcidcbiAgICApIHtcbiAgICAgIHJldHVybiAocmF3UGFnZSBhcyB7IGVxOiBudW1iZXIgfSkuZXE7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKiogTm9ybWFsaXplcyB0aGUgcGFnZSBmaWx0ZXIgdG8gYSBtaW5pbXVtIHZhbHVlIG9mIDEgd2hlbiBwcmVzZW50LiAqL1xuICBmdW5jdGlvbiBub3JtYWxpemVQYWdlRmlsdGVycyhmaWx0ZXJzPzogVW5rbm93bkZpbHRlcnMpOiB7XG4gICAgZmlsdGVycz86IFVua25vd25GaWx0ZXJzO1xuICAgIG5vcm1hbGl6ZWQ6IGJvb2xlYW47XG4gIH0ge1xuICAgIGNvbnN0IHBhZ2VWYWx1ZSA9IHJlYWRQYWdlVmFsdWUoZmlsdGVycyk7XG4gICAgaWYgKHBhZ2VWYWx1ZSA9PSBudWxsIHx8IHBhZ2VWYWx1ZSA+PSAxIHx8IGZpbHRlcnMgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZmlsdGVycyxcbiAgICAgICAgbm9ybWFsaXplZDogZmFsc2UsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBmaWx0ZXJzOiB7XG4gICAgICAgIC4uLmZpbHRlcnMsXG4gICAgICAgIHBhZ2U6IHsgZXE6IDEgfSxcbiAgICAgIH0sXG4gICAgICBub3JtYWxpemVkOiB0cnVlLFxuICAgIH07XG4gIH1cblxuICAvKiogQ29udmVydHMgcm91dGVyIHNlYXJjaCBzdGF0ZSBpbnRvIHRoZSBvYmplY3QgZm9yd2FyZGVkIHRvIGBwcmVwYXJlYC4gKi9cbiAgZnVuY3Rpb24gYnVpbGRQcmVwYXJlUXVlcnlJbnB1dChcbiAgICBzdGF0ZTogUGFyc2VkU2VhcmNoU3RhdGUsXG4gICAgcXVlcnlTY2hlbWE6IFJvdXRlclF1ZXJ5U2NoZW1hLFxuICApOiBQcmVwYXJlUXVlcnlJbnB1dCB7XG4gICAgaWYgKHF1ZXJ5U2NoZW1hICE9IG51bGwpIHtcbiAgICAgIHJldHVybiBzdGF0ZS5maWx0ZXJzID8/IHt9O1xuICAgIH1cbiAgICByZXR1cm4gc3RhdGUucXVlcnk7XG4gIH1cblxuICAvKiogQnVpbGRzIGEgc25hcHNob3QgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnJlbnQgcm91dGVyIGVudHJ5LiAqL1xuICBmdW5jdGlvbiBidWlsZEVudHJ5U25hcHNob3QoXG4gICAgZW50cnk6IFJvdXRlckVudHJ5U3RhdGU8VENvbnRleHQ+LFxuICApOiBSb3V0ZXJFbnRyeVNuYXBzaG90IHtcbiAgICBjb25zdCBwcmVwYXJlZFNlZ21lbnRzID0gZW50cnkucHJlcGFyZWRNYXRjaC5zZWdtZW50cy5tYXAoKHNlZ21lbnQpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhdGg6IHNlZ21lbnQucGF0aCxcbiAgICAgICAgZnVsbFBhdGg6IHNlZ21lbnQuZnVsbFBhdGgsXG4gICAgICAgIHNlZ21lbnRJbmRleDogc2VnbWVudC5zZWdtZW50SW5kZXgsXG4gICAgICAgIHByZXBhcmVkUmVzb3VyY2U6IHNlZ21lbnQucHJlcGFyZWRSZXNvdXJjZSxcbiAgICAgICAgcmVkaXJlY3RUbzogc2VnbWVudC5yZWRpcmVjdFRvLFxuICAgICAgICBoaWdobGlnaHRJZDogc2VnbWVudC5oaWdobGlnaHRJZCxcbiAgICAgICAgcXVlcnlTY2hlbWE6IHNlZ21lbnQucXVlcnlTY2hlbWEsXG4gICAgICAgIHByZXBhcmVkU3RhdHVzOiBzZWdtZW50LnByZXBhcmVkUmVzb3VyY2U/LmdldFN0YXR1cygpLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBsb2NhdGlvbjogbm9ybWFsaXplTG9jYXRpb24oZW50cnkubG9jYXRpb24pLFxuICAgICAgcm91dGVQYXRoOiByZWFkTWF0Y2hlZFJvdXRlUGF0aChlbnRyeSksXG4gICAgICBwcmVwYXJlZE1hdGNoOiB7XG4gICAgICAgIHNlZ21lbnRzOiBwcmVwYXJlZFNlZ21lbnRzLFxuICAgICAgICByb3V0ZXM6IHByZXBhcmVkU2VnbWVudHMsXG4gICAgICB9LFxuICAgICAgZmlsdGVyczogZW50cnkuZmlsdGVycyxcbiAgICAgIGZpbHRlckRpYWdub3N0aWNzOiBlbnRyeS5maWx0ZXJEaWFnbm9zdGljcyxcbiAgICAgIGFjdGl2ZVF1ZXJ5U2NoZW1hOiBlbnRyeS5hY3RpdmVRdWVyeVNjaGVtYSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIE5vdGlmaWVzIGluc3RydW1lbnRhdGlvbnMgb2YgYSBuZXcgYWN0aXZlIGVudHJ5LiAqL1xuICBmdW5jdGlvbiBub3RpZnlFbnRyeShlbnRyeTogUm91dGVyRW50cnlTdGF0ZTxUQ29udGV4dD4pOiB2b2lkIHtcbiAgICByZWdpc3RyeS5ub3RpZnlFbnRyeUNoYW5nZShidWlsZEVudHJ5U25hcHNob3QoZW50cnkpKTtcbiAgfVxuXG4gIC8qKiBDcmVhdGVzIGEgZGVkdXBsaWNhdGlvbiBrZXkgZm9yIHByZWxvYWQgZXZlbnRzLiAqL1xuICBmdW5jdGlvbiBidWlsZFByZWxvYWRLZXkoXG4gICAgbW9kZTogUm91dGVyUHJlbG9hZE1vZGVWYWx1ZSxcbiAgICBwYXRobmFtZTogc3RyaW5nLFxuICApOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHttb2RlfToke3BhdGhuYW1lfWA7XG4gIH1cblxuICAvKiogRW1pdHMgYSBwcmVsb2FkIG9yIHByZWxvYWQtY29kZSBpbnN0cnVtZW50YXRpb24gZXZlbnQuICovXG4gIGZ1bmN0aW9uIGVtaXRQcmVsb2FkRXZlbnQoXG4gICAgbW9kZTogJ2NvZGUnIHwgJ2Z1bGwnLFxuICAgIHBhdGhuYW1lOiBzdHJpbmcsXG4gICAgc291cmNlOiBSb3V0ZXJOYXZpZ2F0aW9uU291cmNlLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGtleSA9IGJ1aWxkUHJlbG9hZEtleShtb2RlLCBwYXRobmFtZSk7XG4gICAgY29uc3QgcmVjZW50bHlSZWNvcmRlZCA9XG4gICAgICBsYXN0UHJlbG9hZFNpZ25hdHVyZSAhPT0gbnVsbCAmJlxuICAgICAgbGFzdFByZWxvYWRTaWduYXR1cmUua2V5ID09PSBrZXkgJiZcbiAgICAgIG5vdyAtIGxhc3RQcmVsb2FkU2lnbmF0dXJlLnRpbWVzdGFtcCA8IDUwO1xuXG4gICAgaWYgKCFyZWNlbnRseVJlY29yZGVkKSB7XG4gICAgICBlbWl0RXZlbnQoe1xuICAgICAgICBraW5kOiAncHJlbG9hZCcsXG4gICAgICAgIHNvdXJjZSxcbiAgICAgICAgdGltZXN0YW1wOiBub3csXG4gICAgICAgIGxvY2F0aW9uOiBub3JtYWxpemVMb2NhdGlvbihoaXN0b3J5LmxvY2F0aW9uKSxcbiAgICAgICAgdGFyZ2V0UGF0aG5hbWU6IHBhdGhuYW1lLFxuICAgICAgICBtb2RlLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGFzdFByZWxvYWRTaWduYXR1cmUgPSB7IGtleSwgdGltZXN0YW1wOiBub3cgfTtcbiAgfVxuXG4gIC8qKiBFbWl0cyBhIGhpc3RvcnkgbXV0YXRpb24gZXZlbnQgKHB1c2gvcmVwbGFjZS9ub3JtYWxpemUpLiAqL1xuICBmdW5jdGlvbiBlbWl0SGlzdG9yeUV2ZW50KFxuICAgIGFjdGlvbjogUm91dGVySGlzdG9yeUFjdGlvblZhbHVlLFxuICAgIHNvdXJjZTogUm91dGVyTmF2aWdhdGlvblNvdXJjZSxcbiAgICBsb2NhdGlvbjogeyBwYXRobmFtZTogc3RyaW5nOyBzZWFyY2g/OiBzdHJpbmc7IGhhc2g/OiBzdHJpbmcgfSxcbiAgICBkZXRhaWxzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICk6IHZvaWQge1xuICAgIHBlbmRpbmdOYXZpZ2F0aW9uT3JpZ2luID0gc291cmNlO1xuICAgIGVtaXRFdmVudCh7XG4gICAgICBraW5kOiAnaGlzdG9yeScsXG4gICAgICBzb3VyY2UsXG4gICAgICBhY3Rpb24sXG4gICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICBsb2NhdGlvbjogbm9ybWFsaXplTG9jYXRpb24obG9jYXRpb24pLFxuICAgICAgZGV0YWlscyxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEJ1aWxkIGEgZmxhdCBsaXN0IG9mIHJvdXRlcyBmb3IgZWZmaWNpZW50IG1hdGNoaW5nXG4gIGNvbnN0IGZsYXRSb3V0ZXMgPSBidWlsZFJvdXRlcyhyb3V0ZXMpO1xuXG4gIC8vIEZpbmQgdGhlIGluaXRpYWwgcm91dGUgbWF0Y2ggYW5kIHByZXBhcmUgaXQgZm9yIHJlbmRlcmluZ1xuICBjb25zdCByb3V0ZSA9IGdldE1hdGNoZWRSb3V0ZShmbGF0Um91dGVzLCBoaXN0b3J5LmxvY2F0aW9uKTtcbiAgY29uc3QgaW5pdGlhbFVuaWZpZWRTY2hlbWEgPSByZWFkQWN0aXZlUXVlcnlTY2hlbWEocm91dGUpO1xuICBjb25zdCBpbml0aWFsU2VhcmNoU3RhdGUgPSBwYXJzZVNlYXJjaFN0YXRlKFxuICAgIGhpc3RvcnkubG9jYXRpb24uc2VhcmNoLFxuICAgIGluaXRpYWxVbmlmaWVkU2NoZW1hLFxuICApO1xuICBjb25zdCBub3JtYWxpemVkSW5pdGlhbEZpbHRlcnMgPSBub3JtYWxpemVQYWdlRmlsdGVycyhcbiAgICBpbml0aWFsU2VhcmNoU3RhdGUuZmlsdGVycyxcbiAgKTtcbiAgY29uc3QgaW5pdGlhbExvY2F0aW9uU25hcHNob3QgPSBub3JtYWxpemVMb2NhdGlvbihoaXN0b3J5LmxvY2F0aW9uKTtcbiAgbGV0IGluaXRpYWxJbnN0cnVtZW50YXRpb246XG4gICAgfCB7XG4gICAgICAgIGVtaXQ6IChldmVudDogUm91dGVyRXZlbnQpID0+IHZvaWQ7XG4gICAgICAgIHNvdXJjZTogUm91dGVyTmF2aWdhdGlvblNvdXJjZTtcbiAgICAgICAgbG9jYXRpb246IFJvdXRlckxvY2F0aW9uU25hcHNob3Q7XG4gICAgICB9XG4gICAgfCB1bmRlZmluZWQ7XG4gIGlmIChyb3V0ZSAhPSBudWxsKSB7XG4gICAgaW5pdGlhbEluc3RydW1lbnRhdGlvbiA9IHtcbiAgICAgIGVtaXQ6IChldmVudDogUm91dGVyRXZlbnQpID0+IHtcbiAgICAgICAgZW1pdEV2ZW50KGV2ZW50KTtcbiAgICAgIH0sXG4gICAgICBzb3VyY2U6IGxhc3ROYXZpZ2F0aW9uT3JpZ2luLFxuICAgICAgbG9jYXRpb246IGluaXRpYWxMb2NhdGlvblNuYXBzaG90LFxuICAgIH07XG4gIH1cbiAgY29uc3QgaW5pdGlhbENvbnRleHQgPSByZXNvbHZlQ29udGV4dCgpO1xuICBjb25zdCBwcmVwYXJlZE1hdGNoID0gcHJlcGFyZU1hdGNoKFxuICAgIHJvdXRlLFxuICAgIGJ1aWxkUHJlcGFyZVF1ZXJ5SW5wdXQoXG4gICAgICB7XG4gICAgICAgIC4uLmluaXRpYWxTZWFyY2hTdGF0ZSxcbiAgICAgICAgZmlsdGVyczogbm9ybWFsaXplZEluaXRpYWxGaWx0ZXJzLmZpbHRlcnMsXG4gICAgICB9LFxuICAgICAgaW5pdGlhbFVuaWZpZWRTY2hlbWEsXG4gICAgKSxcbiAgICBpbml0aWFsSW5zdHJ1bWVudGF0aW9uLFxuICAgIGluaXRpYWxDb250ZXh0LFxuICApO1xuICAvLyBIZWxwZXIgdG8gYnVpbGQgdGhlIHJhdyBxdWVyeSBvYmplY3QgZnJvbSBhIHNlYXJjaCBzdHJpbmdcbiAgbGV0IGN1cnJlbnRFbnRyeTogUm91dGVyRW50cnlTdGF0ZTxUQ29udGV4dD4gPSB7XG4gICAgZm9yY2VSZXJlbmRlcjogZmFsc2UsXG4gICAgbG9jYXRpb246IGhpc3RvcnkubG9jYXRpb24sXG4gICAgcm91dGUsXG4gICAgcHJlcGFyZWRNYXRjaCxcbiAgICBjb250ZXh0OiBpbml0aWFsQ29udGV4dCxcbiAgICByYXdTZWFyY2g6IGhpc3RvcnkubG9jYXRpb24uc2VhcmNoLFxuICAgIHF1ZXJ5OiBpbml0aWFsU2VhcmNoU3RhdGUucXVlcnksXG4gICAgLy8gdHlwZWRRdWVyeSByZW1vdmVkICh1bmlmaWVkIGludG8gZmlsdGVycy9xdWVyeSlcbiAgICBmaWx0ZXJzOiBub3JtYWxpemVkSW5pdGlhbEZpbHRlcnMuZmlsdGVycyxcbiAgICBmaWx0ZXJEaWFnbm9zdGljczogaW5pdGlhbFNlYXJjaFN0YXRlLmZpbHRlckRpYWdub3N0aWNzLFxuICAgIGFjdGl2ZVF1ZXJ5U2NoZW1hOiBpbml0aWFsVW5pZmllZFNjaGVtYSxcbiAgfTtcblxuICAvLyBJbml0aWFsIG5vcm1hbGl6YXRpb24gcGFzcyAoZS5nLiwgY2xhbXAgcGFnZSlcbiAgaWYgKFxuICAgIG5vcm1hbGl6ZWRJbml0aWFsRmlsdGVycy5ub3JtYWxpemVkICYmXG4gICAgaW5pdGlhbFVuaWZpZWRTY2hlbWEgIT0gbnVsbCAmJlxuICAgIG5vcm1hbGl6ZWRJbml0aWFsRmlsdGVycy5maWx0ZXJzICE9IG51bGxcbiAgKSB7XG4gICAgY3VycmVudEVudHJ5LmZpbHRlcnMgPSBub3JtYWxpemVkSW5pdGlhbEZpbHRlcnMuZmlsdGVycztcbiAgICBjb25zdCBub3JtYWxpemVkU2VhcmNoID0gYnVpbGRDb21iaW5lZFNlYXJjaCh7XG4gICAgICBmaWx0ZXJzOiBub3JtYWxpemVkSW5pdGlhbEZpbHRlcnMuZmlsdGVycyxcbiAgICAgIHF1ZXJ5OiBpbml0aWFsU2VhcmNoU3RhdGUucXVlcnksXG4gICAgICBxdWVyeVNjaGVtYTogaW5pdGlhbFVuaWZpZWRTY2hlbWEsXG4gICAgfSk7IC8vIHJldHVybnMgJycgb3Igc3RyaW5nIHN0YXJ0aW5nIHdpdGggJz8nXG4gICAgaWYgKG5vcm1hbGl6ZWRTZWFyY2ggIT09IGhpc3RvcnkubG9jYXRpb24uc2VhcmNoKSB7XG4gICAgICBlbWl0SGlzdG9yeUV2ZW50KFxuICAgICAgICAnbm9ybWFsaXplJyxcbiAgICAgICAgJ25vcm1hbGl6ZScsXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRobmFtZTogaGlzdG9yeS5sb2NhdGlvbi5wYXRobmFtZSxcbiAgICAgICAgICBzZWFyY2g6IG5vcm1hbGl6ZWRTZWFyY2gsXG4gICAgICAgICAgaGFzaDogJycsXG4gICAgICAgIH0sXG4gICAgICAgIHsgcmVhc29uOiAnaW5pdGlhbC1wYWdlLWNsYW1wJyB9LFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZURlYnVnQ29udGV4dDogSGlzdG9yeURlYnVnQ29udGV4dCA9IHtcbiAgICAgICAgb3JpZ2luOiAnbm9ybWFsaXplJyxcbiAgICAgICAgdHJpZ2dlcjogJ25vcm1hbGl6ZScsXG4gICAgICB9O1xuICAgICAgaGlzdG9yeS5zZXQoe1xuICAgICAgICBwYXRobmFtZTogaGlzdG9yeS5sb2NhdGlvbi5wYXRobmFtZSxcbiAgICAgICAgc2VhcmNoOiBub3JtYWxpemVkU2VhcmNoLFxuICAgICAgICBoYXNoOiAnJyxcbiAgICAgICAgZGVidWdDb250ZXh0OiBub3JtYWxpemVEZWJ1Z0NvbnRleHQsXG4gICAgICB9KTtcbiAgICAgIC8vIFVwZGF0ZSBjdXJyZW50RW50cnkubG9jYXRpb24gdG8gcmVmbGVjdCBuZXcgc2VhcmNoIGRpcmVjdGx5IChoaXN0b3J5LnNldCB0cmlnZ2VycyBhc3luYyBzdWJzY3JpYmVyKVxuICAgICAgY3VycmVudEVudHJ5ID0ge1xuICAgICAgICAuLi5jdXJyZW50RW50cnksXG4gICAgICAgIGxvY2F0aW9uOiB7IC4uLmN1cnJlbnRFbnRyeS5sb2NhdGlvbiwgc2VhcmNoOiBub3JtYWxpemVkU2VhcmNoIH0sXG4gICAgICAgIHJhd1NlYXJjaDogbm9ybWFsaXplZFNlYXJjaCxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgbm90aWZ5RW50cnkoY3VycmVudEVudHJ5KTtcbiAgZW1pdEV2ZW50KHtcbiAgICBraW5kOiAnc25hcHNob3QnLFxuICAgIHNvdXJjZTogbGFzdE5hdmlnYXRpb25PcmlnaW4sXG4gICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgIGxvY2F0aW9uOiBub3JtYWxpemVMb2NhdGlvbihjdXJyZW50RW50cnkubG9jYXRpb24pLFxuICAgIHJvdXRlUGF0aDogcmVhZE1hdGNoZWRSb3V0ZVBhdGgoY3VycmVudEVudHJ5KSxcbiAgfSk7XG5cbiAgLy8gTWFpbnRhaW4gYSBzZXQgb2Ygc3Vic2NyaWJlcnMgdG8gdGhlIGFjdGl2ZSByb3V0ZSBlbnRyeVxuICBsZXQgbmV4dElkID0gMDtcbiAgY29uc3Qgc3Vic2NyaWJlcnMgPSBuZXcgTWFwPFxuICAgIG51bWJlcixcbiAgICBTdWJzY3JpYmVDYWxsYmFjazxQYXJhbURhdGEsIFJvdXRlclF1ZXJ5U2NoZW1hLCBUQ29udGV4dD5cbiAgPigpO1xuXG4gIC8vIExpc3RlbiBmb3IgbG9jYXRpb24gY2hhbmdlcywgbWF0Y2ggdG8gdGhlIHJvdXRlIGVudHJ5LCBwcmVwYXJlIHRoZSBlbnRyeSxcbiAgLy8gYW5kIG5vdGlmeSBzdWJzY3JpYmVycy4gVGhpcyBwYXR0ZXJuIGVuc3VyZXMgdGhhdCBkYXRhLWxvYWRpbmdcbiAgLy8gb2NjdXJzICpvdXRzaWRlKiBvZiAtIGFuZCAqYmVmb3JlKiAtIHJlbmRlcmluZy5cbiAgY29uc3QgZGlzcG9zZUhpc3RvcnkgPSBoaXN0b3J5LnN1YnNjcmliZShcbiAgICAobG9jYXRpb24sIGZvcmNlUmVyZW5kZXIsIGRlYnVnQ29udGV4dCkgPT4ge1xuICAgICAgY29uc3Qgb3JpZ2luID0gcmVzb2x2ZU5hdmlnYXRpb25PcmlnaW4oZGVidWdDb250ZXh0KTtcbiAgICAgIGxhc3ROYXZpZ2F0aW9uT3JpZ2luID0gb3JpZ2luO1xuICAgICAgY29uc3QgbG9jYXRpb25QYXlsb2FkID0gbm9ybWFsaXplTG9jYXRpb24obG9jYXRpb24pO1xuXG4gICAgICBjb25zdCBkZWJ1Z0NvbnRleHRPcmlnaW4gPSBkZWJ1Z0NvbnRleHQ/Lm9yaWdpbjtcbiAgICAgIGlmIChkZWJ1Z0NvbnRleHRPcmlnaW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsZXQgaGlzdG9yeURldGFpbHM6IHsgaGlzdG9yeUluZGV4OiBudW1iZXIgfSB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHR5cGVvZiBkZWJ1Z0NvbnRleHQ/Lmhpc3RvcnlJbmRleCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBoaXN0b3J5RGV0YWlscyA9IHsgaGlzdG9yeUluZGV4OiBkZWJ1Z0NvbnRleHQuaGlzdG9yeUluZGV4IH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgZGVidWdDb250ZXh0T3JpZ2luID09PSAncG9wc3RhdGUtYmFjaycgfHxcbiAgICAgICAgICBkZWJ1Z0NvbnRleHRPcmlnaW4gPT09ICdwb3BzdGF0ZS1mb3J3YXJkJyB8fFxuICAgICAgICAgIGRlYnVnQ29udGV4dE9yaWdpbiA9PT0gJ3BvcHN0YXRlLXVua25vd24nIHx8XG4gICAgICAgICAgZGVidWdDb250ZXh0T3JpZ2luID09PSAnZXh0ZXJuYWwnXG4gICAgICAgICkge1xuICAgICAgICAgIGxldCBkaXJlY3Rpb246ICdiYWNrJyB8ICdmb3J3YXJkJyB8ICd1bmtub3duJyA9ICd1bmtub3duJztcbiAgICAgICAgICBpZiAoZGVidWdDb250ZXh0T3JpZ2luID09PSAncG9wc3RhdGUtYmFjaycpIHtcbiAgICAgICAgICAgIGRpcmVjdGlvbiA9ICdiYWNrJztcbiAgICAgICAgICB9IGVsc2UgaWYgKGRlYnVnQ29udGV4dE9yaWdpbiA9PT0gJ3BvcHN0YXRlLWZvcndhcmQnKSB7XG4gICAgICAgICAgICBkaXJlY3Rpb24gPSAnZm9yd2FyZCc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVtaXRFdmVudCh7XG4gICAgICAgICAgICBraW5kOiAncG9wc3RhdGUnLFxuICAgICAgICAgICAgc291cmNlOiBvcmlnaW4sXG4gICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICBsb2NhdGlvbjogbG9jYXRpb25QYXlsb2FkLFxuICAgICAgICAgICAgZGlyZWN0aW9uLFxuICAgICAgICAgICAgZGV0YWlsczogaGlzdG9yeURldGFpbHMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2FtZVBhdGhuYW1lID0gbG9jYXRpb24ucGF0aG5hbWUgPT09IGN1cnJlbnRFbnRyeS5sb2NhdGlvbi5wYXRobmFtZTtcbiAgICAgIGNvbnN0IHNhbWVTZWFyY2ggPSBsb2NhdGlvbi5zZWFyY2ggPT09IGN1cnJlbnRFbnRyeS5yYXdTZWFyY2g7XG5cbiAgICAgIGlmICghZm9yY2VSZXJlbmRlciAmJiBzYW1lUGF0aG5hbWUgJiYgc2FtZVNlYXJjaCkge1xuICAgICAgICAvLyBOb3RoaW5nIGNoYW5nZWQgdGhhdCB3ZSBjYXJlIGFib3V0XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbmV4dENvbnRleHQgPSByZXNvbHZlQ29udGV4dCgpO1xuXG4gICAgICAvLyBJZiBvbmx5IHRoZSBzZWFyY2ggY2hhbmdlZCB3ZSBzdGlsbCB3YW50IHRvIHByb3BhZ2F0ZSB0aGUgY2hhbmdlLlxuICAgICAgLy8gS2VlcCB0aGUgZXhpc3RpbmcgcHJlcGFyZWRNYXRjaCB3aGVuIHBhdGhuYW1lIGlzIGlkZW50aWNhbCB0byBhdm9pZCByZWR1bmRhbnQgd29yay5cbiAgICAgIGxldCBuZXh0UHJlcGFyZWRNYXRjaCA9IGN1cnJlbnRFbnRyeS5wcmVwYXJlZE1hdGNoO1xuICAgICAgbGV0IG5leHRSb3V0ZSA9IGN1cnJlbnRFbnRyeS5yb3V0ZTtcblxuICAgICAgaWYgKCFzYW1lUGF0aG5hbWUpIHtcbiAgICAgICAgbmV4dFJvdXRlID0gZ2V0TWF0Y2hlZFJvdXRlKGZsYXRSb3V0ZXMsIGxvY2F0aW9uKTtcbiAgICAgIH1cblxuICAgICAgLy8gQnVpbGQgcmF3IHF1ZXJ5IG9iamVjdCAoYmFzaWMgYWdncmVnYXRpb24pIGZyb20gbG9jYXRpb24uc2VhcmNoXG4gICAgICBjb25zdCBxdWVyeVNjaGVtYSA9IHJlYWRBY3RpdmVRdWVyeVNjaGVtYShuZXh0Um91dGUpO1xuICAgICAgY29uc3QgcGFyc2VkU2VhcmNoU3RhdGUgPSBwYXJzZVNlYXJjaFN0YXRlKGxvY2F0aW9uLnNlYXJjaCwgcXVlcnlTY2hlbWEpO1xuICAgICAgY29uc3Qgbm9ybWFsaXplZEZpbHRlcnMgPSBub3JtYWxpemVQYWdlRmlsdGVycyhwYXJzZWRTZWFyY2hTdGF0ZS5maWx0ZXJzKTtcblxuICAgICAgLy8gSWYgb25seSB0aGUgc2VhcmNoIGNoYW5nZWQgKHNhbWUgcGF0aG5hbWUpIHdlIHN0aWxsIG5lZWQgdG8gcmUtcnVuIHByZXBhcmVcbiAgICAgIGlmICghc2FtZVBhdGhuYW1lIHx8ICFzYW1lU2VhcmNoKSB7XG4gICAgICAgIGxldCB1cGRhdGVJbnN0cnVtZW50YXRpb246XG4gICAgICAgICAgfCB7XG4gICAgICAgICAgICAgIGVtaXQ6IChldmVudDogUm91dGVyRXZlbnQpID0+IHZvaWQ7XG4gICAgICAgICAgICAgIHNvdXJjZTogUm91dGVyTmF2aWdhdGlvblNvdXJjZTtcbiAgICAgICAgICAgICAgbG9jYXRpb246IFJvdXRlckxvY2F0aW9uU25hcHNob3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChuZXh0Um91dGUgIT0gbnVsbCkge1xuICAgICAgICAgIHVwZGF0ZUluc3RydW1lbnRhdGlvbiA9IHtcbiAgICAgICAgICAgIGVtaXQ6IChldmVudDogUm91dGVyRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgZW1pdEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzb3VyY2U6IG9yaWdpbixcbiAgICAgICAgICAgIGxvY2F0aW9uOiBsb2NhdGlvblBheWxvYWQsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBuZXh0UHJlcGFyZWRNYXRjaCA9IHByZXBhcmVNYXRjaChcbiAgICAgICAgICBuZXh0Um91dGUsXG4gICAgICAgICAgYnVpbGRQcmVwYXJlUXVlcnlJbnB1dChcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgLi4ucGFyc2VkU2VhcmNoU3RhdGUsXG4gICAgICAgICAgICAgIGZpbHRlcnM6IG5vcm1hbGl6ZWRGaWx0ZXJzLmZpbHRlcnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcXVlcnlTY2hlbWEsXG4gICAgICAgICAgKSxcbiAgICAgICAgICB1cGRhdGVJbnN0cnVtZW50YXRpb24sXG4gICAgICAgICAgbmV4dENvbnRleHQsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5leHRFbnRyeTogUm91dGVyRW50cnlTdGF0ZTxUQ29udGV4dD4gPSB7XG4gICAgICAgIGZvcmNlUmVyZW5kZXI6IGZvcmNlUmVyZW5kZXIgfHwgKHNhbWVQYXRobmFtZSAmJiAhc2FtZVNlYXJjaCksXG4gICAgICAgIGxvY2F0aW9uLFxuICAgICAgICByb3V0ZTogbmV4dFJvdXRlLFxuICAgICAgICBwcmVwYXJlZE1hdGNoOiBuZXh0UHJlcGFyZWRNYXRjaCxcbiAgICAgICAgY29udGV4dDogbmV4dENvbnRleHQsXG4gICAgICAgIHJhd1NlYXJjaDogbG9jYXRpb24uc2VhcmNoLFxuICAgICAgICBxdWVyeTogcGFyc2VkU2VhcmNoU3RhdGUucXVlcnksXG4gICAgICAgIGZpbHRlcnM6IG5vcm1hbGl6ZWRGaWx0ZXJzLmZpbHRlcnMsXG4gICAgICAgIGZpbHRlckRpYWdub3N0aWNzOiBwYXJzZWRTZWFyY2hTdGF0ZS5maWx0ZXJEaWFnbm9zdGljcyxcbiAgICAgICAgYWN0aXZlUXVlcnlTY2hlbWE6IHF1ZXJ5U2NoZW1hLFxuICAgICAgfTtcblxuICAgICAgLy8gSWYgbm9ybWFsaXphdGlvbiBjaGFuZ2VkIHRoZSB0eXBlZCBxdWVyeSB3ZSB0cmlnZ2VyIGEgcmVwbGFjZSB3aXRoIG5vcm1hbGl6ZWQgc2VhcmNoXG4gICAgICBpZiAobm9ybWFsaXplZEZpbHRlcnMubm9ybWFsaXplZCAmJiBxdWVyeVNjaGVtYSAhPSBudWxsKSB7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTZWFyY2ggPSBidWlsZENvbWJpbmVkU2VhcmNoKHtcbiAgICAgICAgICBmaWx0ZXJzOiBub3JtYWxpemVkRmlsdGVycy5maWx0ZXJzLFxuICAgICAgICAgIHF1ZXJ5OiBwYXJzZWRTZWFyY2hTdGF0ZS5xdWVyeSxcbiAgICAgICAgICBxdWVyeVNjaGVtYSxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChub3JtYWxpemVkU2VhcmNoICE9PSBsb2NhdGlvbi5zZWFyY2gpIHtcbiAgICAgICAgICBsZXQgbmV4dFNlYXJjaFN0ciA9IG5vcm1hbGl6ZWRTZWFyY2g7XG4gICAgICAgICAgaWYgKCFuZXh0U2VhcmNoU3RyLnN0YXJ0c1dpdGgoJz8nKSAmJiBuZXh0U2VhcmNoU3RyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIG5leHRTZWFyY2hTdHIgPSBgPyR7bmV4dFNlYXJjaFN0cn1gO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbWl0SGlzdG9yeUV2ZW50KFxuICAgICAgICAgICAgJ25vcm1hbGl6ZScsXG4gICAgICAgICAgICAnbm9ybWFsaXplJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcGF0aG5hbWU6IGxvY2F0aW9uLnBhdGhuYW1lLFxuICAgICAgICAgICAgICBzZWFyY2g6IG5leHRTZWFyY2hTdHIsXG4gICAgICAgICAgICAgIGhhc2g6ICcnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgcmVhc29uOiAncnVudGltZS1wYWdlLWNsYW1wJyB9LFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgcnVudGltZU5vcm1hbGl6ZUNvbnRleHQ6IEhpc3RvcnlEZWJ1Z0NvbnRleHQgPSB7XG4gICAgICAgICAgICBvcmlnaW46ICdub3JtYWxpemUnLFxuICAgICAgICAgICAgdHJpZ2dlcjogJ25vcm1hbGl6ZScsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBoaXN0b3J5LnNldCh7XG4gICAgICAgICAgICBwYXRobmFtZTogbG9jYXRpb24ucGF0aG5hbWUsXG4gICAgICAgICAgICBzZWFyY2g6IG5leHRTZWFyY2hTdHIsXG4gICAgICAgICAgICBoYXNoOiAnJyxcbiAgICAgICAgICAgIGRlYnVnQ29udGV4dDogcnVudGltZU5vcm1hbGl6ZUNvbnRleHQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuOyAvLyBlYXJseTogc3Vic2VxdWVudCBzZXQgd2lsbCB0cmlnZ2VyIHJlcnVuXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVXBkYXRlIGN1cnJlbnQgZW50cnkgYW5kIG5vdGlmeSBhbGwgc3Vic2NyaWJlcnNcbiAgICAgIGN1cnJlbnRFbnRyeSA9IG5leHRFbnRyeTtcbiAgICAgIHN1YnNjcmliZXJzLmZvckVhY2goKGNhbGxiYWNrKSA9PiB7XG4gICAgICAgIGNhbGxiYWNrKG5leHRFbnRyeSk7XG4gICAgICB9KTtcbiAgICAgIG5vdGlmeUVudHJ5KG5leHRFbnRyeSk7XG4gICAgICBlbWl0RXZlbnQoe1xuICAgICAgICBraW5kOiAnc25hcHNob3QnLFxuICAgICAgICBzb3VyY2U6IG9yaWdpbixcbiAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICBsb2NhdGlvbjogbG9jYXRpb25QYXlsb2FkLFxuICAgICAgICByb3V0ZVBhdGg6IHJlYWRNYXRjaGVkUm91dGVQYXRoKG5leHRFbnRyeSksXG4gICAgICB9KTtcbiAgICB9LFxuICApO1xuXG4gIC8qKiBOb3JtYWxpemVzIHVzZXItcHJvdmlkZWQgcHJlbG9hZCB0YXJnZXRzIGludG8gY29uc2lzdGVudCBzdHJ1Y3R1cmVzLiAqL1xuICBmdW5jdGlvbiBub3JtYWxpemVQcmVsb2FkVGFyZ2V0KHRhcmdldDogUHJlbG9hZFRhcmdldCk6IHtcbiAgICBwYXRobmFtZTogc3RyaW5nO1xuICAgIHNlYXJjaDogc3RyaW5nO1xuICAgIHNvdXJjZTogUm91dGVyTmF2aWdhdGlvblNvdXJjZTtcbiAgfSB7XG4gICAgbGV0IG5vcm1hbGl6ZWRQYXRobmFtZSA9IGhpc3RvcnkubG9jYXRpb24ucGF0aG5hbWU7XG4gICAgaWYgKHR5cGVvZiB0YXJnZXQucGF0aG5hbWUgPT09ICdzdHJpbmcnICYmIHRhcmdldC5wYXRobmFtZS5sZW5ndGggPiAwKSB7XG4gICAgICBub3JtYWxpemVkUGF0aG5hbWUgPSB0YXJnZXQucGF0aG5hbWU7XG4gICAgfVxuXG4gICAgbGV0IG5vcm1hbGl6ZWRTZWFyY2ggPSAnJztcbiAgICBpZiAodHlwZW9mIHRhcmdldC5zZWFyY2ggPT09ICdzdHJpbmcnKSB7XG4gICAgICBub3JtYWxpemVkU2VhcmNoID0gdGFyZ2V0LnNlYXJjaDtcbiAgICB9XG5cbiAgICBsZXQgbm9ybWFsaXplZFNvdXJjZTogUm91dGVyTmF2aWdhdGlvblNvdXJjZSA9ICdwcm9ncmFtbWF0aWMnO1xuICAgIGNvbnN0IG1hcHBlZFNvdXJjZSA9IG1hcE9yaWdpbih0YXJnZXQuc291cmNlKTtcbiAgICBpZiAobWFwcGVkU291cmNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG5vcm1hbGl6ZWRTb3VyY2UgPSBtYXBwZWRTb3VyY2U7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBwYXRobmFtZTogbm9ybWFsaXplZFBhdGhuYW1lLFxuICAgICAgc2VhcmNoOiBub3JtYWxpemVkU2VhcmNoLFxuICAgICAgc291cmNlOiBub3JtYWxpemVkU291cmNlLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgcHJlcGFyZWQgdmFsdWUgZm9yIHRoZSBmaXJzdCBhY3RpdmUgc2VnbWVudCBtYXRjaGluZyB0aGUgcHJvdmlkZWQgcGF0aC5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggLSBSb3V0ZSBzZWdtZW50IHBhdGggb3IgZnVsbCBwYXRoIHRvIGluc3BlY3QuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRQcmVwYXJlZChwYXRoOiBzdHJpbmcpOiBQcmVwYXJlZE9mPFJvdXRlVW5pb248Uj4+IHwgdW5kZWZpbmVkIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZW50cnkgPSBjdXJyZW50RW50cnk7XG4gICAgICBmb3IgKGNvbnN0IHByZXBhcmVkUm91dGUgb2YgZW50cnkucHJlcGFyZWRNYXRjaC5zZWdtZW50cykge1xuICAgICAgICBpZiAocHJlcGFyZWRSb3V0ZS5wYXRoID09PSBwYXRoIHx8IHByZXBhcmVkUm91dGUuZnVsbFBhdGggPT09IHBhdGgpIHtcbiAgICAgICAgICBjb25zdCBwcmVwYXJlZFZhbHVlID0gcHJlcGFyZWRSb3V0ZS5wcmVwYXJlZFJlc291cmNlPy5nZXQoKTtcbiAgICAgICAgICByZXR1cm4gcHJlcGFyZWRWYWx1ZSBhcyBQcmVwYXJlZE9mPFJvdXRlVW5pb248Uj4+IHwgdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBldmVyeSBhY3RpdmUgcHJlcGFyZWQgc2VnbWVudCBtYXRjaGluZyB0aGUgcHJvdmlkZWQgcGF0aC5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggLSBSb3V0ZSBzZWdtZW50IHBhdGggb3IgZnVsbCBwYXRoIHRvIGluc3BlY3QuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRQcmVwYXJlZFNlZ21lbnRzKHBhdGg6IHN0cmluZyk6IFByZXBhcmVkUm91dGVTZWdtZW50U25hcHNob3RbXSB7XG4gICAgcmV0dXJuIGN1cnJlbnRFbnRyeS5wcmVwYXJlZE1hdGNoLnNlZ21lbnRzXG4gICAgICAuZmlsdGVyKChwcmVwYXJlZFJvdXRlKSA9PiB7XG4gICAgICAgIHJldHVybiBwcmVwYXJlZFJvdXRlLnBhdGggPT09IHBhdGggfHwgcHJlcGFyZWRSb3V0ZS5mdWxsUGF0aCA9PT0gcGF0aDtcbiAgICAgIH0pXG4gICAgICAubWFwKChwcmVwYXJlZFJvdXRlKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcGF0aDogcHJlcGFyZWRSb3V0ZS5wYXRoLFxuICAgICAgICAgIGZ1bGxQYXRoOiBwcmVwYXJlZFJvdXRlLmZ1bGxQYXRoLFxuICAgICAgICAgIHNlZ21lbnRJbmRleDogcHJlcGFyZWRSb3V0ZS5zZWdtZW50SW5kZXgsXG4gICAgICAgICAgcHJlcGFyZWRSZXNvdXJjZTogcHJlcGFyZWRSb3V0ZS5wcmVwYXJlZFJlc291cmNlLFxuICAgICAgICAgIHJlZGlyZWN0VG86IHByZXBhcmVkUm91dGUucmVkaXJlY3RUbyxcbiAgICAgICAgICByZXNvdXJjZVBhZ2U6IHByZXBhcmVkUm91dGUucmVzb3VyY2VQYWdlLFxuICAgICAgICAgIGhpZ2hsaWdodElkOiBwcmVwYXJlZFJvdXRlLmhpZ2hsaWdodElkLFxuICAgICAgICAgIHF1ZXJ5U2NoZW1hOiBwcmVwYXJlZFJvdXRlLnF1ZXJ5U2NoZW1hLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBUaGUgcm91dGVyIGNvbnRleHQgb2JqZWN0IHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gUmVhY3QgQ29udGV4dFxuICBjb25zdCBjb250ZXh0ID0ge1xuICAgIGhpc3RvcnksXG4gICAgZ2V0KCkge1xuICAgICAgcmV0dXJuIGN1cnJlbnRFbnRyeTtcbiAgICB9LFxuICAgIHByZWxvYWRDb2RlKHRhcmdldCkge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZVByZWxvYWRUYXJnZXQodGFyZ2V0KTtcbiAgICAgIGVtaXRQcmVsb2FkRXZlbnQoJ2NvZGUnLCBub3JtYWxpemVkLnBhdGhuYW1lLCBub3JtYWxpemVkLnNvdXJjZSk7XG4gICAgICBjb25zdCBtYXRjaGVzID0gZ2V0TWF0Y2hlZFJvdXRlKGZsYXRSb3V0ZXMsIHtcbiAgICAgICAgLi4uaGlzdG9yeS5sb2NhdGlvbixcbiAgICAgICAgcGF0aG5hbWU6IG5vcm1hbGl6ZWQucGF0aG5hbWUsXG4gICAgICB9KTtcblxuICAgICAgaWYgKG1hdGNoZXMgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIG1hdGNoZXMucm91dGUucm91dGVzLmZvckVhY2goKHsgcmVzb3VyY2VQYWdlIH0pID0+IHtcbiAgICAgICAgaWYgKHJlc291cmNlUGFnZSA9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZmxvYXRpbmctcHJvbWlzZXNcbiAgICAgICAgcmVzb3VyY2VQYWdlLmxvYWQoKTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgcHJlbG9hZCh0YXJnZXQpIHtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVQcmVsb2FkVGFyZ2V0KHRhcmdldCk7XG4gICAgICBlbWl0UHJlbG9hZEV2ZW50KCdmdWxsJywgbm9ybWFsaXplZC5wYXRobmFtZSwgbm9ybWFsaXplZC5zb3VyY2UpO1xuICAgICAgY29uc3QgbWF0Y2hlcyA9IGdldE1hdGNoZWRSb3V0ZShmbGF0Um91dGVzLCB7XG4gICAgICAgIC4uLmhpc3RvcnkubG9jYXRpb24sXG4gICAgICAgIHBhdGhuYW1lOiBub3JtYWxpemVkLnBhdGhuYW1lLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBsb2NhdGlvblNuYXBzaG90OiBSb3V0ZXJMb2NhdGlvblNuYXBzaG90ID0ge1xuICAgICAgICBwYXRobmFtZTogbm9ybWFsaXplZC5wYXRobmFtZSxcbiAgICAgICAgc2VhcmNoOiBub3JtYWxpemVkLnNlYXJjaCxcbiAgICAgICAgaGFzaDogJycsXG4gICAgICB9O1xuICAgICAgbGV0IGluc3RydW1lbnRhdGlvbjpcbiAgICAgICAgfCB7XG4gICAgICAgICAgICBlbWl0OiAoZXZlbnQ6IFJvdXRlckV2ZW50KSA9PiB2b2lkO1xuICAgICAgICAgICAgc291cmNlOiBSb3V0ZXJOYXZpZ2F0aW9uU291cmNlO1xuICAgICAgICAgICAgbG9jYXRpb246IFJvdXRlckxvY2F0aW9uU25hcHNob3Q7XG4gICAgICAgICAgfVxuICAgICAgICB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChtYXRjaGVzICE9IG51bGwpIHtcbiAgICAgICAgaW5zdHJ1bWVudGF0aW9uID0ge1xuICAgICAgICAgIGVtaXQ6IChldmVudDogUm91dGVyRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGVtaXRFdmVudChldmVudCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzb3VyY2U6IG5vcm1hbGl6ZWQuc291cmNlLFxuICAgICAgICAgIGxvY2F0aW9uOiBsb2NhdGlvblNuYXBzaG90LFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgY29uc3QgcHJlbG9hZENvbnRleHQgPSByZXNvbHZlQ29udGV4dCgpO1xuICAgICAgY29uc3QgcHJlbG9hZFF1ZXJ5U2NoZW1hID0gcmVhZEFjdGl2ZVF1ZXJ5U2NoZW1hKG1hdGNoZXMpO1xuICAgICAgY29uc3QgcHJlbG9hZFNlYXJjaFN0YXRlID0gcGFyc2VTZWFyY2hTdGF0ZShcbiAgICAgICAgbm9ybWFsaXplZC5zZWFyY2gsXG4gICAgICAgIHByZWxvYWRRdWVyeVNjaGVtYSxcbiAgICAgICk7XG4gICAgICBjb25zdCBwcmVwYXJlZE1hdGNoID0gcHJlcGFyZU1hdGNoKFxuICAgICAgICBtYXRjaGVzLFxuICAgICAgICBidWlsZFByZXBhcmVRdWVyeUlucHV0KHByZWxvYWRTZWFyY2hTdGF0ZSwgcHJlbG9hZFF1ZXJ5U2NoZW1hKSxcbiAgICAgICAgaW5zdHJ1bWVudGF0aW9uLFxuICAgICAgICBwcmVsb2FkQ29udGV4dCxcbiAgICAgICk7XG4gICAgICBwcmVwYXJlZE1hdGNoLnNlZ21lbnRzLmZvckVhY2goKHJvdXRlKSA9PiB7XG4gICAgICAgIGlmIChyb3V0ZS5wcmVwYXJlZFJlc291cmNlICE9IG51bGwpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWZsb2F0aW5nLXByb21pc2VzXG4gICAgICAgICAgcm91dGUucHJlcGFyZWRSZXNvdXJjZS5sb2FkKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0sXG4gICAgc3Vic2NyaWJlKGNhbGxiYWNrKSB7XG4gICAgICBuZXh0SWQgKz0gMTtcbiAgICAgIGNvbnN0IGlkID0gbmV4dElkO1xuICAgICAgLyoqIFJlbW92ZXMgdGhlIHN1YnNjcmliZXIgcHJldmlvdXNseSByZWdpc3RlcmVkIHZpYSBzdWJzY3JpYmUuICovXG4gICAgICBmdW5jdGlvbiBkaXNwb3NlQ2FsbGJhY2soKSB7XG4gICAgICAgIHN1YnNjcmliZXJzLmRlbGV0ZShpZCk7XG4gICAgICB9XG4gICAgICBzdWJzY3JpYmVycy5zZXQoaWQsIGNhbGxiYWNrKTtcbiAgICAgIHJldHVybiBkaXNwb3NlQ2FsbGJhY2s7XG4gICAgfSxcbiAgICBuYXZpZ2F0ZSh7XG4gICAgICBwYXRobmFtZSxcbiAgICAgIHF1ZXJ5LFxuICAgICAgZmlsdGVyczogbmF2RmlsdGVycyxcbiAgICAgIHJlcGxhY2UsXG4gICAgfToge1xuICAgICAgcGF0aG5hbWU/OiBzdHJpbmc7XG4gICAgICBxdWVyeT86IFVua25vd25RdWVyeVNoYXBlO1xuICAgICAgZmlsdGVycz86IFVua25vd25GaWx0ZXJzO1xuICAgICAgcmVwbGFjZT86IGJvb2xlYW47XG4gICAgfSkge1xuICAgICAgY29uc3QgY3VycmVudCA9IGN1cnJlbnRFbnRyeTtcbiAgICAgIGxldCB0YXJnZXRQYXRobmFtZSA9IHBhdGhuYW1lO1xuICAgICAgdGFyZ2V0UGF0aG5hbWUgPz89IGN1cnJlbnQubG9jYXRpb24ucGF0aG5hbWU7XG5cbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uUm91dGUgPSBnZXRNYXRjaGVkUm91dGUoZmxhdFJvdXRlcywge1xuICAgICAgICAuLi5oaXN0b3J5LmxvY2F0aW9uLFxuICAgICAgICBwYXRobmFtZTogdGFyZ2V0UGF0aG5hbWUsXG4gICAgICB9KTtcbiAgICAgIGxldCBkZXN0U2NoZW1hID0gcmVhZEFjdGl2ZVF1ZXJ5U2NoZW1hKGRlc3RpbmF0aW9uUm91dGUpO1xuICAgICAgZGVzdFNjaGVtYSA9IGRlc3RTY2hlbWEgPz8gY3VycmVudC5hY3RpdmVRdWVyeVNjaGVtYTtcblxuICAgICAgY29uc3QgaGFzU2NoZW1hID0gZGVzdFNjaGVtYSAhPSBudWxsO1xuICAgICAgY29uc3QgdXNlUXVlcnlBc0ZpbHRlcnMgPVxuICAgICAgICBuYXZGaWx0ZXJzID09IG51bGwgJiZcbiAgICAgICAgaGFzU2NoZW1hICYmXG4gICAgICAgIHF1ZXJ5ICE9IG51bGwgJiZcbiAgICAgICAgbG9va3NMaWtlRmlsdGVycyhxdWVyeSk7XG4gICAgICBsZXQgZmlsdGVyc0lucHV0ID0gbmF2RmlsdGVycztcbiAgICAgIGlmIChmaWx0ZXJzSW5wdXQgPT0gbnVsbCkge1xuICAgICAgICBpZiAodXNlUXVlcnlBc0ZpbHRlcnMpIHtcbiAgICAgICAgICBmaWx0ZXJzSW5wdXQgPSBxdWVyeTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaWx0ZXJzSW5wdXQgPSBjdXJyZW50LmZpbHRlcnMgYXMgVW5rbm93bkZpbHRlcnMgfCB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxldCByYXdRdWVyeUlucHV0OiBVbmtub3duUXVlcnlTaGFwZSB8IFJhd1F1ZXJ5IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKHVzZVF1ZXJ5QXNGaWx0ZXJzKSB7XG4gICAgICAgIHJhd1F1ZXJ5SW5wdXQgPSBjdXJyZW50LnF1ZXJ5O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmF3UXVlcnlJbnB1dCA9IHF1ZXJ5ID8/IGN1cnJlbnQucXVlcnk7XG4gICAgICB9XG4gICAgICBjb25zdCBzZWFyY2ggPSBidWlsZENvbWJpbmVkU2VhcmNoKHtcbiAgICAgICAgZmlsdGVyczogZmlsdGVyc0lucHV0LFxuICAgICAgICBxdWVyeTogcmF3UXVlcnlJbnB1dCxcbiAgICAgICAgcXVlcnlTY2hlbWE6IGRlc3RTY2hlbWEsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGxvY2F0aW9uT2JqID0geyBwYXRobmFtZTogdGFyZ2V0UGF0aG5hbWUsIHNlYXJjaCwgaGFzaDogJycgfTtcbiAgICAgIGNvbnN0IG9yaWdpbjogUm91dGVyTmF2aWdhdGlvblNvdXJjZSA9ICdwcm9ncmFtbWF0aWMnO1xuICAgICAgY29uc3QgZGVidWdDb250ZXh0OiBIaXN0b3J5RGVidWdDb250ZXh0ID0ge1xuICAgICAgICBvcmlnaW4sXG4gICAgICAgIHRyaWdnZXI6ICdwcm9ncmFtbWF0aWMnLFxuICAgICAgfTtcblxuICAgICAgaWYgKHJlcGxhY2UgPT09IHRydWUpIHtcbiAgICAgICAgZW1pdEhpc3RvcnlFdmVudCgncmVwbGFjZScsIG9yaWdpbiwgbG9jYXRpb25PYmosIHtcbiAgICAgICAgICB0cmlnZ2VyOiAncHJvZ3JhbW1hdGljJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGhpc3Rvcnkuc2V0KHtcbiAgICAgICAgICAuLi5sb2NhdGlvbk9iaixcbiAgICAgICAgICBkZWJ1Z0NvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZW1pdEhpc3RvcnlFdmVudCgncHVzaCcsIG9yaWdpbiwgbG9jYXRpb25PYmosIHtcbiAgICAgICAgICB0cmlnZ2VyOiAncHJvZ3JhbW1hdGljJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGhpc3RvcnkucHVzaCh7XG4gICAgICAgICAgLi4ubG9jYXRpb25PYmosXG4gICAgICAgICAgZGVidWdDb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGdldFByZXBhcmVkLFxuICAgIGdldFByZXBhcmVkU2VnbWVudHMsXG4gIH0gYXMgQ3JlYXRlUm91dGVyUmV0dXJuPFRDb250ZXh0LCBSPlsnY29udGV4dCddO1xuXG4gIC8qKiBSZWxlYXNlcyByb3V0ZXIgcmVzb3VyY2VzIGFuZCBkZXRhY2hlcyBhbGwgaW5zdHJ1bWVudGF0aW9ucy4gKi9cbiAgZnVuY3Rpb24gY2xlYW51cCgpOiB2b2lkIHtcbiAgICBkaXNwb3NlSGlzdG9yeSgpO1xuICAgIHN1YnNjcmliZXJzLmNsZWFyKCk7XG4gICAgcmVnaXN0cnkuZGlzcG9zZSgpO1xuICB9XG5cbiAgLy8gUmV0dXJuIGJvdGggdGhlIGNvbnRleHQgb2JqZWN0IGFuZCBhIGNsZWFudXAgZnVuY3Rpb25cbiAgcmV0dXJuIHsgY29udGV4dCwgY2xlYW51cCB9O1xufVxuIl19
|