@decohere/flux 0.0.1-dev.68 → 0.0.1-dev.7

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.
Files changed (36) hide show
  1. package/commonjs/src/ember.command.js +27 -0
  2. package/commonjs/src/ember.module.js +37 -0
  3. package/commonjs/src/hot-module-hooks.js +47 -0
  4. package/commonjs/src/hot-reload-server.js +121 -316
  5. package/commonjs/src/index.js +35 -9
  6. package/commonjs/src/serve.action.js +11 -23
  7. package/commonjs/src/serve.command.js +4 -8
  8. package/commonjs/src/serve.js +36 -0
  9. package/commonjs/src/workspace-serve.action.js +59 -0
  10. package/es6/src/ember.command.js +17 -0
  11. package/es6/src/ember.module.js +19 -0
  12. package/es6/src/hot-module-hooks.js +26 -0
  13. package/es6/src/hot-reload-server.js +119 -303
  14. package/es6/src/index.js +7 -3
  15. package/es6/src/serve.action.js +11 -25
  16. package/es6/src/serve.command.js +5 -9
  17. package/es6/src/serve.js +32 -0
  18. package/es6/src/workspace-serve.action.js +45 -0
  19. package/package.json +12 -7
  20. package/types/src/{flux.command.d.ts → ember.command.d.ts} +1 -1
  21. package/types/src/ember.module.d.ts +22 -0
  22. package/types/src/hot-module-hooks.d.ts +5 -0
  23. package/types/src/hot-reload-server.d.ts +22 -61
  24. package/types/src/index.d.ts +8 -3
  25. package/types/src/serve.action.d.ts +2 -8
  26. package/types/src/serve.command.d.ts +2 -2
  27. package/types/src/serve.d.ts +1 -0
  28. package/types/src/workspace-serve.action.d.ts +11 -0
  29. package/commonjs/src/flux.command.js +0 -27
  30. package/commonjs/src/flux.module.js +0 -32
  31. package/commonjs/src/rewrite-serve-specifier.js +0 -46
  32. package/es6/src/flux.command.js +0 -17
  33. package/es6/src/flux.module.js +0 -22
  34. package/es6/src/rewrite-serve-specifier.js +0 -40
  35. package/types/src/flux.module.d.ts +0 -14
  36. package/types/src/rewrite-serve-specifier.d.ts +0 -13
@@ -2,32 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get DEFAULT_REBOOT_DEBOUNCE_MS () {
13
- return DEFAULT_REBOOT_DEBOUNCE_MS;
14
- },
15
- get HotReloadServer () {
5
+ Object.defineProperty(exports, "HotReloadServer", {
6
+ enumerable: true,
7
+ get: function() {
16
8
  return HotReloadServer;
17
- },
18
- get resolveRebootDebounceMs () {
19
- return resolveRebootDebounceMs;
20
9
  }
21
10
  });
22
11
  const _nodeevents = require("node:events");
23
- const _nodemodule = require("node:module");
24
12
  const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
25
- const _forge = require("@decohere/forge");
26
- const _mesh = require("@decohere/mesh");
27
13
  const _io = require("@decohere/nexus/io");
28
14
  const _system = require("@decohere/nexus/system");
29
- const _scribe = require("@decohere/scribe");
30
- const _rewriteservespecifier = require("./rewrite-serve-specifier.js");
15
+ const _hotmodulehooks = require("./hot-module-hooks.js");
31
16
  function _interop_require_default(obj) {
32
17
  return obj && obj.__esModule ? obj : {
33
18
  default: obj
@@ -75,314 +60,79 @@ function _interop_require_wildcard(obj, nodeInterop) {
75
60
  return newObj;
76
61
  }
77
62
  const currentFilePath = _io.io.fileUrlToPath(require("url").pathToFileURL(__filename).toString());
78
- const VERSION_URL_PARAM = "version";
79
- const DEFAULT_REBOOT_DEBOUNCE_MS = 250;
80
- function resolveRebootDebounceMs(value) {
81
- const delay = value ?? DEFAULT_REBOOT_DEBOUNCE_MS;
82
- if (!Number.isFinite(delay) || delay < 0) {
83
- throw new Error(`rebootDebounceMs must be a non-negative number, got ${String(value)}`);
84
- }
85
- return delay;
86
- }
87
- /** Process-wide: Node's ESM cache is process-global, including across HotReloadServer instances. */ let moduleVersionSeq = 0;
88
63
  class HotReloadServer extends _nodeevents.EventEmitter {
89
- // ── State ────────────────────────────────────────────────────────────────
90
- logger = _scribe.scribe.logger(HotReloadServer.name);
64
+ logger;
91
65
  disposed = false;
92
- hooksRegistered = false;
93
- entryModulePath;
94
66
  entryModule;
95
- workspace;
96
- buildConfig = "debug";
97
- watchSubscription;
98
- /** Map from absolute .ts source file path to project info */ fileInfoMap = new Map();
67
+ entry;
68
+ sourceFiles = [];
99
69
  moduleCache = new Map();
100
70
  dependencies = new Map();
101
- transpileCache = new Map();
102
- transpiler = new _forge.SwcTranspiler();
103
- aliasPaths = {};
104
- aliasBaseUrl = _nodepath.default.resolve(".");
105
- rebootTail = Promise.resolve();
106
- rebootDebounceGen = 0;
107
- rebootInFlight = false;
108
- rebootFollowUp = false;
109
- rebootQueued = false;
110
- scheduleReboot = ()=>{};
111
- // ── Public API ───────────────────────────────────────────────────────────
112
- async start(options) {
113
- this.disposed = false;
114
- this.dependencies.clear();
115
- this.moduleCache.clear();
116
- this.transpileCache.clear();
117
- this.rebootTail = Promise.resolve();
118
- this.rebootInFlight = false;
119
- this.rebootFollowUp = false;
120
- this.rebootQueued = false;
121
- this.bindScheduleReboot(resolveRebootDebounceMs(options.rebootDebounceMs));
122
- const { buildConfig } = options;
123
- this.buildConfig = buildConfig;
124
- this.workspace = await this.resolveWorkspace(options);
125
- const project = this.resolveProject(buildConfig, options.project);
126
- this.entryModulePath = _nodepath.default.resolve(project.getSourceEntryPath());
127
- this.fileInfoMap = await this.buildFileInfoMap(buildConfig);
128
- this.aliasPaths = await this.buildAliasPaths();
129
- this.registerHooks();
71
+ watchers = [];
72
+ constructor(logger){
73
+ super();
74
+ this.logger = logger;
75
+ }
76
+ async start(entry, ...watchDirs) {
77
+ this.entryModule = entry;
78
+ this.sourceFiles = await this.getSourceFiles(watchDirs);
79
+ this.configureModuleHooks();
130
80
  this.invalidateAllSourceFiles();
131
- await this.workspace.watch(buildConfig);
132
- this.watchSubscription = this.workspace.projectFileChanged$.subscribe(this.onFileChange);
133
- this.logger.trace(`Serving ${this.entryModulePath}`);
81
+ await this.watch(watchDirs);
82
+ this.logger.trace("Serving", entry);
83
+ this.logger.trace("Hot reload watching", watchDirs);
134
84
  await this.bootEntry();
135
- this.emit("start");
136
85
  }
137
86
  async dispose() {
138
87
  if (this.disposed) return;
139
88
  this.disposed = true;
140
- this.rebootDebounceGen += 1;
141
- this.watchSubscription?.unsubscribe();
142
- this.workspace?.[Symbol.dispose]();
143
- await this.rebootTail;
144
- await this.disposeEntry();
145
- }
146
- async [Symbol.asyncDispose]() {
147
- await this.dispose();
148
- }
149
- // ── Lifecycle ────────────────────────────────────────────────────────────
150
- async bootEntry() {
151
- try {
152
- const url = this.versionModule(_io.io.pathToFileUrl(this.entryModulePath));
153
- this.entryModule = (await Promise.resolve(url).then((p)=>/*#__PURE__*/ _interop_require_wildcard(require(p))))?.default;
154
- } catch (error) {
155
- this.entryModule = undefined;
156
- this.logger.error("There was an error booting the entry point. Your application may not function as expected", error);
157
- }
158
- }
159
- bindScheduleReboot(delayMs) {
160
- const gen = ++this.rebootDebounceGen;
161
- this.scheduleReboot = (0, _system.debounce)(async ()=>{
162
- if (this.disposed || gen !== this.rebootDebounceGen) return;
163
- this.requestReboot();
164
- }, delayMs);
165
- }
166
- requestReboot() {
167
- if (this.disposed) return;
168
- if (this.rebootInFlight) {
169
- this.rebootFollowUp = true;
170
- return;
171
- }
172
- if (this.rebootQueued) return;
173
- this.rebootQueued = true;
174
- this.rebootTail = this.rebootTail.then(()=>this.runReboot(), ()=>this.runReboot());
175
- }
176
- async runReboot() {
177
- this.rebootQueued = false;
178
- if (this.disposed) return;
179
- this.rebootInFlight = true;
180
- try {
181
- do {
182
- this.rebootFollowUp = false;
183
- if (this.disposed) return;
184
- this.logger.trace("Rebooting entry module");
185
- await this.disposeEntry();
186
- await this.bootEntry();
187
- this.emit("reboot");
188
- }while (this.rebootFollowUp && !this.disposed)
189
- } finally{
190
- const needsFollowUp = this.rebootFollowUp && !this.disposed;
191
- this.rebootFollowUp = false;
192
- this.rebootInFlight = false;
193
- if (needsFollowUp) this.requestReboot();
194
- }
195
- }
196
- async disposeEntry() {
197
- const entry = this.entryModule;
198
- this.entryModule = undefined;
199
- try {
200
- await entry?.[Symbol.asyncDispose]();
201
- } catch (error) {
202
- this.logger.error("Entry asyncDispose failed", error);
89
+ (0, _hotmodulehooks.removeResolverHook)(this.onResolve);
90
+ for (const watcher of this.watchers){
91
+ watcher.close();
203
92
  }
93
+ await this.disposeEntry();
204
94
  }
205
- // ── Setup ────────────────────────────────────────────────────────────────
206
- async resolveWorkspace(options) {
207
- return options.workspace ?? _mesh.WorkspaceFactory.create({
208
- ..._forge.WorkspaceDefaults,
209
- rootDir: process.cwd()
210
- });
211
- }
212
- resolveProject(buildConfig, name) {
213
- const projects = this.workspace?.getProjects(buildConfig) ?? [];
214
- const found = name == null ? projects.at(0) : projects.find((p)=>p.name === name);
215
- if (found == null) {
216
- throw new Error(name == null ? `No projects found for configuration: ${buildConfig}` : `Project "${name}" not found in workspace`);
217
- }
218
- return found;
95
+ removeSourceFiles(...sourceFiles) {
96
+ this.sourceFiles = this.sourceFiles.filter((sourceFile)=>!sourceFiles.includes(sourceFile));
219
97
  }
220
- async buildFileInfoMap(buildConfig) {
221
- const projects = this.workspace?.getProjects(buildConfig) ?? [];
222
- const entries = await Promise.all(projects.map(async (project)=>{
223
- const files = await project.getAllFiles();
224
- return files.map((file)=>[
225
- file.fullPath,
226
- {
227
- project
228
- }
229
- ]);
230
- }));
231
- return new Map(entries.flat());
98
+ async getSourceFiles(dirs) {
99
+ const patterns = dirs.map((dir)=>`${dir}/**/*.js`);
100
+ const files = await _io.io.findFiles(patterns);
101
+ return files.map((f)=>f.fullPath);
232
102
  }
233
- registerHooks() {
234
- if (this.hooksRegistered) return;
235
- this.hooksRegistered = true;
236
- (0, _nodemodule.registerHooks)({
237
- resolve: (specifier, context, next)=>{
238
- if (this.disposed) return next(specifier, context);
239
- const parentUrl = context.parentURL ?? "";
240
- const rewritten = (0, _rewriteservespecifier.rewriteServeSpecifier)({
241
- specifier,
242
- parentUrl,
243
- isWatchedTs: (filePath)=>this.fileInfoMap.has(filePath),
244
- resolveBare: (bare)=>_mesh.packageAliases.resolvePath(bare, this.aliasPaths, this.aliasBaseUrl),
245
- versionFileUrl: (fileUrl)=>this.getCachedOrNew(fileUrl)
246
- }) ?? specifier;
247
- const result = next(rewritten, context);
248
- this.onPostResolve(result, parentUrl);
249
- return result;
250
- },
251
- load: (url, context, next)=>{
252
- if (this.disposed) return next(url, context);
253
- const result = this.loadTs(url);
254
- if (result != null) return {
255
- format: "module",
256
- source: result.source,
257
- shortCircuit: true
258
- };
259
- return next(url, context);
260
- }
261
- });
103
+ configureModuleHooks() {
104
+ (0, _hotmodulehooks.initModuleHooks)();
105
+ (0, _hotmodulehooks.addResolverHook)(this.onResolve);
262
106
  }
263
- // ── Module hooks ─────────────────────────────────────────────────────────
264
- async buildAliasPaths() {
265
- const workspace = this.workspace;
266
- if (workspace == null) return {};
267
- const packageAliases = workspace.getPackageAliases(this.buildConfig);
268
- this.aliasBaseUrl = packageAliases.baseUrl;
269
- return packageAliases.paths;
270
- }
271
- /**
272
- * Post-next dependency tracker: records which source files import which
273
- * other source files so that reloadIfAffected can traverse the graph.
274
- */ onPostResolve = (result, parentUrl)=>{
107
+ onResolve = (result, parentUrl)=>{
275
108
  const { url } = result;
276
109
  const parentUrlClean = parentUrl.split("?")[0];
277
- let filePath;
278
- let parentPath;
279
- try {
280
- const urlObj = new URL(url);
281
- urlObj.search = "";
282
- filePath = _io.io.fileUrlToPath(urlObj.toString());
283
- } catch {
284
- return;
285
- }
286
- try {
287
- parentPath = _io.io.fileUrlToPath(parentUrlClean);
288
- } catch {
289
- parentPath = "";
290
- }
291
- const isSource = this.fileInfoMap.has(filePath);
292
- const parentIsSource = this.fileInfoMap.has(parentPath);
110
+ const isSource = this.isSourceModule(url);
111
+ const parentIsSource = this.isSourceModule(parentUrlClean);
293
112
  if (isSource || parentIsSource) {
294
- this.trackDependency(filePath, parentPath);
295
- }
296
- };
297
- loadTs = (url)=>{
298
- if (!url.startsWith("file:")) return null;
299
- const cleanPath = new URL(url).pathname;
300
- const fileInfo = this.fileInfoMap.get(cleanPath);
301
- if (fileInfo == null) return null;
302
- const cached = this.transpileCache.get(cleanPath);
303
- if (cached != null) return {
304
- source: cached
305
- };
306
- const { project } = fileInfo;
307
- const tsConfig = project.getTsConfigSync();
308
- const userConfig = project.getSwcConfigSync();
309
- const file = new _io.FileEx({
310
- fullPath: cleanPath
311
- });
312
- const response = this.transpiler.transformFileSync(file, _forge.BuildTargets.es6, {
313
- tsConfig,
314
- aliasPaths: true,
315
- userConfig,
316
- workspace: this.workspace,
317
- projects: this.workspace?.getProjects(this.buildConfig)
318
- });
319
- if (response.outcome !== "success") {
320
- this.logger.error(`Failed to transpile ${cleanPath}`, response);
321
- // Do not fall through to next(): Vitest/Node loaders can deadlock on a
322
- // versioned .ts URL. Fail the import so bootEntry can catch and continue.
323
- throw new Error(`Failed to transpile ${cleanPath}`);
113
+ this.trackDependency(url, parentUrl);
324
114
  }
325
- this.transpileCache.set(cleanPath, response.code);
326
- return {
327
- source: response.code
328
- };
329
- };
330
- // ── File watching ────────────────────────────────────────────────────────
331
- onFileChange = (evt)=>{
332
- const { file, eventName, project } = evt;
333
- const fullPath = file.fullPath;
334
- this.logger.trace(`File ${eventName}: ${fullPath}`);
335
- if (eventName === _io.io.WatchEvents.unlink) {
336
- this.transpileCache.delete(fullPath);
337
- this.moduleCache.set(fullPath, null);
115
+ if (!isSource) {
338
116
  return;
339
117
  }
340
- if (eventName === _io.io.WatchEvents.add) {
341
- if (project.isSourceFile(file)) {
342
- this.fileInfoMap.set(fullPath, {
343
- project
344
- });
345
- this.moduleCache.set(fullPath, null);
346
- this.reloadIfAffected(fullPath);
347
- }
348
- return;
349
- }
350
- // change
351
- if (!project.isSourceFile(file)) return;
352
- this.transpileCache.delete(fullPath);
353
- this.transpiler.invalidateContentCache(new _io.FileEx({
354
- fullPath
355
- }));
356
- this.reloadIfAffected(fullPath);
118
+ result.url = this.getCachedOrNew(url);
357
119
  };
358
- reloadIfAffected(fullPath) {
359
- const deps = this.getDependencyGraph(fullPath);
360
- const modules = [
361
- ...new Set([
362
- ...deps,
363
- fullPath
364
- ])
365
- ];
366
- if (!modules.includes(this.entryModulePath)) {
367
- this.logger.trace(`Change in ${fullPath} does not affect entry — skipping reload`);
368
- return false;
369
- }
370
- this.logger.trace(`Change in ${fullPath} affects ${modules.length} module(s) — scheduling reload`);
371
- this.invalidateModule(...modules);
372
- this.scheduleReboot();
373
- return true;
120
+ isSourceModule(url) {
121
+ const path = _io.io.fileUrlToPath(url);
122
+ return this.sourceFiles.includes(path);
374
123
  }
375
- // ── Dependency graph ─────────────────────────────────────────────────────
376
124
  getDependencyGraph(moduleId, parentModules = []) {
377
- if (this.isSelf(moduleId)) return [];
125
+ if (this.isSelf(moduleId)) {
126
+ return [];
127
+ }
378
128
  const moduleDeps = this.dependencies.get(moduleId) ?? [];
379
129
  if (parentModules.includes(moduleId)) {
380
130
  this.logger.error(`Circular reference detected: ${moduleId}`);
381
131
  return [];
382
132
  }
383
- let subDeps = [];
133
+ let subDeps = Array.of();
384
134
  for (const dep of moduleDeps){
385
- if (!this.fileInfoMap.has(dep)) continue;
135
+ if (!this.sourceFiles.includes(dep)) continue;
386
136
  const subs = this.getDependencyGraph(dep, [
387
137
  moduleId,
388
138
  ...parentModules
@@ -399,8 +149,9 @@ class HotReloadServer extends _nodeevents.EventEmitter {
399
149
  ])
400
150
  ];
401
151
  }
402
- trackDependency(filePath, parentPath) {
403
- if (!parentPath) return;
152
+ trackDependency(url, parentUrl) {
153
+ const filePath = _io.io.fileUrlToPath(url);
154
+ const parentPath = _io.io.fileUrlToPath(parentUrl.split("?")[0]);
404
155
  const deps = this.dependencies.get(filePath) ?? [];
405
156
  const updatedDeps = new Set([
406
157
  ...deps,
@@ -410,7 +161,6 @@ class HotReloadServer extends _nodeevents.EventEmitter {
410
161
  ...updatedDeps
411
162
  ]);
412
163
  }
413
- // ── Module cache ─────────────────────────────────────────────────────────
414
164
  getCachedOrNew(moduleUrl) {
415
165
  const filePath = _io.io.fileUrlToPath(moduleUrl);
416
166
  const cached = this.moduleCache.get(filePath);
@@ -420,33 +170,88 @@ class HotReloadServer extends _nodeevents.EventEmitter {
420
170
  }
421
171
  versionModule(moduleUrl) {
422
172
  const versionedUrl = new URL(moduleUrl);
423
- versionedUrl.searchParams.set(VERSION_URL_PARAM, String(++moduleVersionSeq));
173
+ versionedUrl.searchParams.set("version", Date.now().toString());
424
174
  return versionedUrl.toString();
425
175
  }
426
- invalidateModule(...modules) {
176
+ watch = async (dirs)=>{
177
+ for (const dir of dirs){
178
+ const watcher = _io.io.watch(dir, {
179
+ include: [
180
+ "**/*.js"
181
+ ],
182
+ ignoreInitial: true
183
+ });
184
+ watcher.on("add", this.onFileAdded).on("change", this.onSourceFileChanged).on("unlink", this.onFileDeleted);
185
+ this.watchers.push(watcher);
186
+ }
187
+ };
188
+ onFileAdded = async ({ fullPath })=>{
189
+ this.sourceFiles.push(fullPath);
190
+ this.moduleCache.set(fullPath, null);
191
+ this.reloadIfAffected(fullPath);
192
+ };
193
+ onSourceFileChanged = async ({ fullPath })=>{
194
+ if (!this.reloadIfAffected(fullPath)) {
195
+ this.logger.trace(`${fullPath} is not part of the current dependency graph. Not reloading entry.`);
196
+ }
197
+ };
198
+ onFileDeleted = async ({ fullPath })=>{
199
+ this.removeSourceFiles(fullPath);
200
+ };
201
+ reloadIfAffected(fullPath) {
202
+ const deps = this.getDependencyGraph(fullPath);
203
+ const modules = [
204
+ ...new Set([
205
+ ...deps,
206
+ fullPath
207
+ ])
208
+ ];
209
+ if (!modules.includes(this.entryModule)) {
210
+ return false;
211
+ }
212
+ this.invlidateModule(...modules);
213
+ this.disposeAndBoot();
214
+ return true;
215
+ }
216
+ isSelf(urlLike) {
217
+ return currentFilePath === _nodepath.default.resolve(_io.io.fileUrlToPath(urlLike));
218
+ }
219
+ invlidateModule(...modules) {
427
220
  for (const module of modules){
428
221
  this.moduleCache.set(module, null);
429
- this.transpileCache.delete(module);
430
- // Prune stale outgoing edges: remove this module as a parent from all dependency lists
431
- for (const [key, parents] of this.dependencies){
432
- const filtered = parents.filter((p)=>p !== module);
433
- if (filtered.length === 0) {
434
- this.dependencies.delete(key);
435
- } else {
436
- this.dependencies.set(key, filtered);
437
- }
222
+ }
223
+ // Prune invalidated modules from all parent lists so stale relationships
224
+ // are cleared. The fresh boot rebuilds only what is actually imported.
225
+ for (const [child, parents] of this.dependencies){
226
+ const pruned = parents.filter((p)=>!modules.includes(p));
227
+ if (pruned.length === 0) {
228
+ this.dependencies.delete(child);
229
+ } else {
230
+ this.dependencies.set(child, pruned);
438
231
  }
439
232
  }
440
233
  }
441
234
  invalidateAllSourceFiles() {
442
- for (const filePath of this.fileInfoMap.keys()){
443
- this.moduleCache.set(filePath, null);
235
+ for (const file of this.sourceFiles){
236
+ this.moduleCache.set(file, null);
444
237
  }
445
238
  }
446
- // ── Utilities ────────────────────────────────────────────────────────────
447
- isSelf(filePath) {
448
- return currentFilePath === _nodepath.default.resolve(filePath);
239
+ disposeAndBoot = (0, _system.debounce)(async ()=>{
240
+ await this.disposeEntry();
241
+ await this.bootEntry();
242
+ }, 250);
243
+ async disposeEntry() {
244
+ await this.entry?.[Symbol.asyncDispose]();
245
+ }
246
+ async bootEntry() {
247
+ try {
248
+ const version = this.versionModule(_io.io.pathToFileUrl(this.entryModule));
249
+ this.entry = (await Promise.resolve(version).then((p)=>/*#__PURE__*/ _interop_require_wildcard(require(p))))?.default;
250
+ this.emit("reboot");
251
+ } catch (error) {
252
+ this.logger.error(`There was an error booting the entry point. Your application may not function as expected`, error);
253
+ }
449
254
  }
450
255
  }
451
256
 
452
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZsdXgvc3JjL2hvdC1yZWxvYWQtc2VydmVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gXCJub2RlOmV2ZW50c1wiO1xuaW1wb3J0IHR5cGUge1xuXHRMb2FkRm5PdXRwdXQsXG5cdExvYWRIb29rQ29udGV4dCxcblx0UmVzb2x2ZUZuT3V0cHV0LFxuXHRSZXNvbHZlSG9va0NvbnRleHQsXG59IGZyb20gXCJub2RlOm1vZHVsZVwiO1xuaW1wb3J0IHsgcmVnaXN0ZXJIb29rcyB9IGZyb20gXCJub2RlOm1vZHVsZVwiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgQnVpbGRUYXJnZXRzLCBTd2NUcmFuc3BpbGVyLCBXb3Jrc3BhY2VEZWZhdWx0cyB9IGZyb20gXCJAZGVjb2hlcmUvZm9yZ2VcIjtcbmltcG9ydCB0eXBlIHsgUHJvamVjdCwgUHJvamVjdEZpbGVFdmVudCwgV29ya3NwYWNlIH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG5pbXBvcnQgeyBwYWNrYWdlQWxpYXNlcywgV29ya3NwYWNlRmFjdG9yeSB9IGZyb20gXCJAZGVjb2hlcmUvbWVzaFwiO1xuaW1wb3J0IHsgRmlsZUV4LCBpbyB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvaW9cIjtcbmltcG9ydCB7IGRlYm91bmNlIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9zeXN0ZW1cIjtcbmltcG9ydCB7IHR5cGUgTG9nZ2VyLCBzY3JpYmUgfSBmcm9tIFwiQGRlY29oZXJlL3NjcmliZVwiO1xuaW1wb3J0IHR5cGUgeyBTdWJzY3JpcHRpb24gfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgcmV3cml0ZVNlcnZlU3BlY2lmaWVyIH0gZnJvbSBcIi4vcmV3cml0ZS1zZXJ2ZS1zcGVjaWZpZXIuanNcIjtcblxudHlwZSBMb2FkRGVsZWdhdGUgPSAodXJsOiBzdHJpbmcpID0+IHsgc291cmNlOiBzdHJpbmcgfSB8IG51bGw7XG5cbmNvbnN0IGN1cnJlbnRGaWxlUGF0aCA9IGlvLmZpbGVVcmxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKTtcbmNvbnN0IFZFUlNJT05fVVJMX1BBUkFNID0gXCJ2ZXJzaW9uXCI7XG4vKiogRGVmYXVsdCBxdWlldCB3aW5kb3cgYmVmb3JlIGEgZmlsZS1jaGFuZ2UgcmVib290LiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfUkVCT09UX0RFQk9VTkNFX01TID0gMjUwO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVJlYm9vdERlYm91bmNlTXModmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCk6IG51bWJlciB7XG5cdGNvbnN0IGRlbGF5ID0gdmFsdWUgPz8gREVGQVVMVF9SRUJPT1RfREVCT1VOQ0VfTVM7XG5cdGlmICghTnVtYmVyLmlzRmluaXRlKGRlbGF5KSB8fCBkZWxheSA8IDApIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoYHJlYm9vdERlYm91bmNlTXMgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIsIGdvdCAke1N0cmluZyh2YWx1ZSl9YCk7XG5cdH1cblx0cmV0dXJuIGRlbGF5O1xufVxuXG4vKiogUHJvY2Vzcy13aWRlOiBOb2RlJ3MgRVNNIGNhY2hlIGlzIHByb2Nlc3MtZ2xvYmFsLCBpbmNsdWRpbmcgYWNyb3NzIEhvdFJlbG9hZFNlcnZlciBpbnN0YW5jZXMuICovXG5sZXQgbW9kdWxlVmVyc2lvblNlcSA9IDA7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSG90UmVsb2FkU2VydmVyRXZlbnRzIHtcblx0c3RhcnQ6IFtdO1xuXHRyZWJvb3Q6IFtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEhvdFJlbG9hZFNlcnZlck9wdGlvbnMge1xuXHQvKiogQnVpbGQgY29uZmlndXJhdGlvbiBuYW1lLiAqL1xuXHRidWlsZENvbmZpZzogc3RyaW5nO1xuXHQvKiogTmFtZSBvZiB0aGUgcHJvamVjdCB0byBzZXJ2ZS4gRGVmYXVsdHMgdG8gdGhlIGZpcnN0IHByb2plY3QgaW4gdGhlIHdvcmtzcGFjZS4gKi9cblx0cHJvamVjdD86IHN0cmluZztcblx0LyoqXG5cdCAqIFByZS1idWlsdCBXb3Jrc3BhY2UgaW5zdGFuY2UgdG8gdXNlIGluc3RlYWQgb2YgcnVubmluZyBXb3Jrc3BhY2VGYWN0b3J5LlxuXHQgKiBVc2VmdWwgaW4gdGVzdHMgdG8gYnlwYXNzIGZpbGVzeXN0ZW0tYmFzZWQgd29ya3NwYWNlIGRpc2NvdmVyeS5cblx0ICovXG5cdHdvcmtzcGFjZT86IFdvcmtzcGFjZTtcblx0LyoqXG5cdCAqIFF1aWV0IHdpbmRvdyBpbiBtaWxsaXNlY29uZHMgYWZ0ZXIgdGhlIGxhc3QgYWZmZWN0aW5nIHNhdmUgYmVmb3JlIGEgcmVib290LlxuXHQgKiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9SRUJPT1RfREVCT1VOQ0VfTVN9LiBSYWlzZSB0aGlzIGZvciBhZ2VudCBzYXZlIHRyYWlucy5cblx0ICovXG5cdHJlYm9vdERlYm91bmNlTXM/OiBudW1iZXI7XG59XG5cbnR5cGUgRmlsZUluZm8gPSB7IHByb2plY3Q6IFByb2plY3QgfTtcblxuZXhwb3J0IGNsYXNzIEhvdFJlbG9hZFNlcnZlciBleHRlbmRzIEV2ZW50RW1pdHRlcjxIb3RSZWxvYWRTZXJ2ZXJFdmVudHM+IHtcblx0Ly8g4pSA4pSAIFN0YXRlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXHRwcml2YXRlIHJlYWRvbmx5IGxvZ2dlcjogTG9nZ2VyID0gc2NyaWJlLmxvZ2dlcihIb3RSZWxvYWRTZXJ2ZXIubmFtZSk7XG5cdHByaXZhdGUgZGlzcG9zZWQgPSBmYWxzZTtcblx0cHJpdmF0ZSBob29rc1JlZ2lzdGVyZWQgPSBmYWxzZTtcblx0cHJpdmF0ZSBlbnRyeU1vZHVsZVBhdGghOiBzdHJpbmc7XG5cdHByaXZhdGUgZW50cnlNb2R1bGU/OiBBc3luY0Rpc3Bvc2FibGU7XG5cdHByaXZhdGUgd29ya3NwYWNlPzogV29ya3NwYWNlO1xuXHRwcml2YXRlIGJ1aWxkQ29uZmlnID0gXCJkZWJ1Z1wiO1xuXHRwcml2YXRlIHdhdGNoU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXHQvKiogTWFwIGZyb20gYWJzb2x1dGUgLnRzIHNvdXJjZSBmaWxlIHBhdGggdG8gcHJvamVjdCBpbmZvICovXG5cdHByaXZhdGUgZmlsZUluZm9NYXAgPSBuZXcgTWFwPHN0cmluZywgRmlsZUluZm8+KCk7XG5cdHByaXZhdGUgbW9kdWxlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nIHwgbnVsbD4oKTtcblx0cHJpdmF0ZSBkZXBlbmRlbmNpZXMgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KCk7XG5cdHByaXZhdGUgdHJhbnNwaWxlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuXHRwcml2YXRlIHRyYW5zcGlsZXIgPSBuZXcgU3djVHJhbnNwaWxlcigpO1xuXHRwcml2YXRlIGFsaWFzUGF0aHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHt9O1xuXHRwcml2YXRlIGFsaWFzQmFzZVVybCA9IHBhdGgucmVzb2x2ZShcIi5cIik7XG5cdHByaXZhdGUgcmVib290VGFpbDogUHJvbWlzZTx2b2lkPiA9IFByb21pc2UucmVzb2x2ZSgpO1xuXHRwcml2YXRlIHJlYm9vdERlYm91bmNlR2VuID0gMDtcblx0cHJpdmF0ZSByZWJvb3RJbkZsaWdodCA9IGZhbHNlO1xuXHRwcml2YXRlIHJlYm9vdEZvbGxvd1VwID0gZmFsc2U7XG5cdHByaXZhdGUgcmVib290UXVldWVkID0gZmFsc2U7XG5cdHByaXZhdGUgc2NoZWR1bGVSZWJvb3Q6ICgpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuXHQvLyDilIDilIAgUHVibGljIEFQSSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuXHRwdWJsaWMgYXN5bmMgc3RhcnQob3B0aW9uczogSG90UmVsb2FkU2VydmVyT3B0aW9ucykge1xuXHRcdHRoaXMuZGlzcG9zZWQgPSBmYWxzZTtcblx0XHR0aGlzLmRlcGVuZGVuY2llcy5jbGVhcigpO1xuXHRcdHRoaXMubW9kdWxlQ2FjaGUuY2xlYXIoKTtcblx0XHR0aGlzLnRyYW5zcGlsZUNhY2hlLmNsZWFyKCk7XG5cdFx0dGhpcy5yZWJvb3RUYWlsID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cdFx0dGhpcy5yZWJvb3RJbkZsaWdodCA9IGZhbHNlO1xuXHRcdHRoaXMucmVib290Rm9sbG93VXAgPSBmYWxzZTtcblx0XHR0aGlzLnJlYm9vdFF1ZXVlZCA9IGZhbHNlO1xuXHRcdHRoaXMuYmluZFNjaGVkdWxlUmVib290KHJlc29sdmVSZWJvb3REZWJvdW5jZU1zKG9wdGlvbnMucmVib290RGVib3VuY2VNcykpO1xuXG5cdFx0Y29uc3QgeyBidWlsZENvbmZpZyB9ID0gb3B0aW9ucztcblx0XHR0aGlzLmJ1aWxkQ29uZmlnID0gYnVpbGRDb25maWc7XG5cdFx0dGhpcy53b3Jrc3BhY2UgPSBhd2FpdCB0aGlzLnJlc29sdmVXb3Jrc3BhY2Uob3B0aW9ucyk7XG5cdFx0Y29uc3QgcHJvamVjdCA9IHRoaXMucmVzb2x2ZVByb2plY3QoYnVpbGRDb25maWcsIG9wdGlvbnMucHJvamVjdCk7XG5cblx0XHR0aGlzLmVudHJ5TW9kdWxlUGF0aCA9IHBhdGgucmVzb2x2ZShwcm9qZWN0LmdldFNvdXJjZUVudHJ5UGF0aCgpKTtcblx0XHR0aGlzLmZpbGVJbmZvTWFwID0gYXdhaXQgdGhpcy5idWlsZEZpbGVJbmZvTWFwKGJ1aWxkQ29uZmlnKTtcblx0XHR0aGlzLmFsaWFzUGF0aHMgPSBhd2FpdCB0aGlzLmJ1aWxkQWxpYXNQYXRocygpO1xuXG5cdFx0dGhpcy5yZWdpc3Rlckhvb2tzKCk7XG5cdFx0dGhpcy5pbnZhbGlkYXRlQWxsU291cmNlRmlsZXMoKTtcblxuXHRcdGF3YWl0IHRoaXMud29ya3NwYWNlLndhdGNoKGJ1aWxkQ29uZmlnKTtcblx0XHR0aGlzLndhdGNoU3Vic2NyaXB0aW9uID0gdGhpcy53b3Jrc3BhY2UucHJvamVjdEZpbGVDaGFuZ2VkJC5zdWJzY3JpYmUodGhpcy5vbkZpbGVDaGFuZ2UpO1xuXG5cdFx0dGhpcy5sb2dnZXIudHJhY2UoYFNlcnZpbmcgJHt0aGlzLmVudHJ5TW9kdWxlUGF0aH1gKTtcblx0XHRhd2FpdCB0aGlzLmJvb3RFbnRyeSgpO1xuXHRcdHRoaXMuZW1pdChcInN0YXJ0XCIpO1xuXHR9XG5cblx0cHVibGljIGFzeW5jIGRpc3Bvc2UoKSB7XG5cdFx0aWYgKHRoaXMuZGlzcG9zZWQpIHJldHVybjtcblx0XHR0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcblx0XHR0aGlzLnJlYm9vdERlYm91bmNlR2VuICs9IDE7XG5cdFx0dGhpcy53YXRjaFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcblx0XHR0aGlzLndvcmtzcGFjZT8uW1N5bWJvbC5kaXNwb3NlXSgpO1xuXHRcdGF3YWl0IHRoaXMucmVib290VGFpbDtcblx0XHRhd2FpdCB0aGlzLmRpc3Bvc2VFbnRyeSgpO1xuXHR9XG5cblx0cHVibGljIGFzeW5jIFtTeW1ib2wuYXN5bmNEaXNwb3NlXSgpIHtcblx0XHRhd2FpdCB0aGlzLmRpc3Bvc2UoKTtcblx0fVxuXG5cdC8vIOKUgOKUgCBMaWZlY3ljbGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cblx0cHJpdmF0ZSBhc3luYyBib290RW50cnkoKSB7XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHVybCA9IHRoaXMudmVyc2lvbk1vZHVsZShpby5wYXRoVG9GaWxlVXJsKHRoaXMuZW50cnlNb2R1bGVQYXRoKSk7XG5cdFx0XHR0aGlzLmVudHJ5TW9kdWxlID0gKGF3YWl0IGltcG9ydCh1cmwpKT8uZGVmYXVsdDtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0dGhpcy5lbnRyeU1vZHVsZSA9IHVuZGVmaW5lZDtcblx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKFxuXHRcdFx0XHRcIlRoZXJlIHdhcyBhbiBlcnJvciBib290aW5nIHRoZSBlbnRyeSBwb2ludC4gWW91ciBhcHBsaWNhdGlvbiBtYXkgbm90IGZ1bmN0aW9uIGFzIGV4cGVjdGVkXCIsXG5cdFx0XHRcdGVycm9yLFxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGJpbmRTY2hlZHVsZVJlYm9vdChkZWxheU1zOiBudW1iZXIpIHtcblx0XHRjb25zdCBnZW4gPSArK3RoaXMucmVib290RGVib3VuY2VHZW47XG5cdFx0dGhpcy5zY2hlZHVsZVJlYm9vdCA9IGRlYm91bmNlKGFzeW5jICgpID0+IHtcblx0XHRcdGlmICh0aGlzLmRpc3Bvc2VkIHx8IGdlbiAhPT0gdGhpcy5yZWJvb3REZWJvdW5jZUdlbikgcmV0dXJuO1xuXHRcdFx0dGhpcy5yZXF1ZXN0UmVib290KCk7XG5cdFx0fSwgZGVsYXlNcyk7XG5cdH1cblxuXHRwcml2YXRlIHJlcXVlc3RSZWJvb3QoKSB7XG5cdFx0aWYgKHRoaXMuZGlzcG9zZWQpIHJldHVybjtcblx0XHRpZiAodGhpcy5yZWJvb3RJbkZsaWdodCkge1xuXHRcdFx0dGhpcy5yZWJvb3RGb2xsb3dVcCA9IHRydWU7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGlmICh0aGlzLnJlYm9vdFF1ZXVlZCkgcmV0dXJuO1xuXHRcdHRoaXMucmVib290UXVldWVkID0gdHJ1ZTtcblx0XHR0aGlzLnJlYm9vdFRhaWwgPSB0aGlzLnJlYm9vdFRhaWwudGhlbihcblx0XHRcdCgpID0+IHRoaXMucnVuUmVib290KCksXG5cdFx0XHQoKSA9PiB0aGlzLnJ1blJlYm9vdCgpLFxuXHRcdCk7XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIHJ1blJlYm9vdCgpIHtcblx0XHR0aGlzLnJlYm9vdFF1ZXVlZCA9IGZhbHNlO1xuXHRcdGlmICh0aGlzLmRpc3Bvc2VkKSByZXR1cm47XG5cdFx0dGhpcy5yZWJvb3RJbkZsaWdodCA9IHRydWU7XG5cdFx0dHJ5IHtcblx0XHRcdGRvIHtcblx0XHRcdFx0dGhpcy5yZWJvb3RGb2xsb3dVcCA9IGZhbHNlO1xuXHRcdFx0XHRpZiAodGhpcy5kaXNwb3NlZCkgcmV0dXJuO1xuXHRcdFx0XHR0aGlzLmxvZ2dlci50cmFjZShcIlJlYm9vdGluZyBlbnRyeSBtb2R1bGVcIik7XG5cdFx0XHRcdGF3YWl0IHRoaXMuZGlzcG9zZUVudHJ5KCk7XG5cdFx0XHRcdGF3YWl0IHRoaXMuYm9vdEVudHJ5KCk7XG5cdFx0XHRcdHRoaXMuZW1pdChcInJlYm9vdFwiKTtcblx0XHRcdH0gd2hpbGUgKHRoaXMucmVib290Rm9sbG93VXAgJiYgIXRoaXMuZGlzcG9zZWQpO1xuXHRcdH0gZmluYWxseSB7XG5cdFx0XHRjb25zdCBuZWVkc0ZvbGxvd1VwID0gdGhpcy5yZWJvb3RGb2xsb3dVcCAmJiAhdGhpcy5kaXNwb3NlZDtcblx0XHRcdHRoaXMucmVib290Rm9sbG93VXAgPSBmYWxzZTtcblx0XHRcdHRoaXMucmVib290SW5GbGlnaHQgPSBmYWxzZTtcblx0XHRcdGlmIChuZWVkc0ZvbGxvd1VwKSB0aGlzLnJlcXVlc3RSZWJvb3QoKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIGRpc3Bvc2VFbnRyeSgpIHtcblx0XHRjb25zdCBlbnRyeSA9IHRoaXMuZW50cnlNb2R1bGU7XG5cdFx0dGhpcy5lbnRyeU1vZHVsZSA9IHVuZGVmaW5lZDtcblx0XHR0cnkge1xuXHRcdFx0YXdhaXQgZW50cnk/LltTeW1ib2wuYXN5bmNEaXNwb3NlXSgpO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihcIkVudHJ5IGFzeW5jRGlzcG9zZSBmYWlsZWRcIiwgZXJyb3IpO1xuXHRcdH1cblx0fVxuXG5cdC8vIOKUgOKUgCBTZXR1cCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuXHRwcml2YXRlIGFzeW5jIHJlc29sdmVXb3Jrc3BhY2Uob3B0aW9uczogSG90UmVsb2FkU2VydmVyT3B0aW9ucyk6IFByb21pc2U8V29ya3NwYWNlPiB7XG5cdFx0cmV0dXJuIChcblx0XHRcdG9wdGlvbnMud29ya3NwYWNlID8/XG5cdFx0XHRXb3Jrc3BhY2VGYWN0b3J5LmNyZWF0ZSh7IC4uLldvcmtzcGFjZURlZmF1bHRzLCByb290RGlyOiBwcm9jZXNzLmN3ZCgpIH0pXG5cdFx0KTtcblx0fVxuXG5cdHByaXZhdGUgcmVzb2x2ZVByb2plY3QoYnVpbGRDb25maWc6IHN0cmluZywgbmFtZT86IHN0cmluZyk6IFByb2plY3Qge1xuXHRcdGNvbnN0IHByb2plY3RzID0gdGhpcy53b3Jrc3BhY2U/LmdldFByb2plY3RzKGJ1aWxkQ29uZmlnKSA/PyBbXTtcblx0XHRjb25zdCBmb3VuZCA9IG5hbWUgPT0gbnVsbCA/IHByb2plY3RzLmF0KDApIDogcHJvamVjdHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBuYW1lKTtcblx0XHRpZiAoZm91bmQgPT0gbnVsbCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRuYW1lID09IG51bGxcblx0XHRcdFx0XHQ/IGBObyBwcm9qZWN0cyBmb3VuZCBmb3IgY29uZmlndXJhdGlvbjogJHtidWlsZENvbmZpZ31gXG5cdFx0XHRcdFx0OiBgUHJvamVjdCBcIiR7bmFtZX1cIiBub3QgZm91bmQgaW4gd29ya3NwYWNlYCxcblx0XHRcdCk7XG5cdFx0fVxuXHRcdHJldHVybiBmb3VuZDtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgYnVpbGRGaWxlSW5mb01hcChidWlsZENvbmZpZzogc3RyaW5nKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBGaWxlSW5mbz4+IHtcblx0XHRjb25zdCBwcm9qZWN0cyA9IHRoaXMud29ya3NwYWNlPy5nZXRQcm9qZWN0cyhidWlsZENvbmZpZykgPz8gW107XG5cdFx0Y29uc3QgZW50cmllcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuXHRcdFx0cHJvamVjdHMubWFwKGFzeW5jIChwcm9qZWN0KSA9PiB7XG5cdFx0XHRcdGNvbnN0IGZpbGVzID0gYXdhaXQgcHJvamVjdC5nZXRBbGxGaWxlcygpO1xuXHRcdFx0XHRyZXR1cm4gZmlsZXMubWFwKChmaWxlKTogW3N0cmluZywgRmlsZUluZm9dID0+IFtmaWxlLmZ1bGxQYXRoLCB7IHByb2plY3QgfV0pO1xuXHRcdFx0fSksXG5cdFx0KTtcblx0XHRyZXR1cm4gbmV3IE1hcChlbnRyaWVzLmZsYXQoKSk7XG5cdH1cblxuXHRwcml2YXRlIHJlZ2lzdGVySG9va3MoKSB7XG5cdFx0aWYgKHRoaXMuaG9va3NSZWdpc3RlcmVkKSByZXR1cm47XG5cdFx0dGhpcy5ob29rc1JlZ2lzdGVyZWQgPSB0cnVlO1xuXHRcdHJlZ2lzdGVySG9va3Moe1xuXHRcdFx0cmVzb2x2ZTogKFxuXHRcdFx0XHRzcGVjaWZpZXI6IHN0cmluZyxcblx0XHRcdFx0Y29udGV4dDogUmVzb2x2ZUhvb2tDb250ZXh0LFxuXHRcdFx0XHRuZXh0OiAoc3BlY2lmaWVyOiBzdHJpbmcsIGNvbnRleHQ/OiBQYXJ0aWFsPFJlc29sdmVIb29rQ29udGV4dD4pID0+IFJlc29sdmVGbk91dHB1dCxcblx0XHRcdCkgPT4ge1xuXHRcdFx0XHRpZiAodGhpcy5kaXNwb3NlZCkgcmV0dXJuIG5leHQoc3BlY2lmaWVyLCBjb250ZXh0KTtcblx0XHRcdFx0Y29uc3QgcGFyZW50VXJsID0gY29udGV4dC5wYXJlbnRVUkwgPz8gXCJcIjtcblx0XHRcdFx0Y29uc3QgcmV3cml0dGVuID1cblx0XHRcdFx0XHRyZXdyaXRlU2VydmVTcGVjaWZpZXIoe1xuXHRcdFx0XHRcdFx0c3BlY2lmaWVyLFxuXHRcdFx0XHRcdFx0cGFyZW50VXJsLFxuXHRcdFx0XHRcdFx0aXNXYXRjaGVkVHM6IChmaWxlUGF0aCkgPT4gdGhpcy5maWxlSW5mb01hcC5oYXMoZmlsZVBhdGgpLFxuXHRcdFx0XHRcdFx0cmVzb2x2ZUJhcmU6IChiYXJlKSA9PlxuXHRcdFx0XHRcdFx0XHRwYWNrYWdlQWxpYXNlcy5yZXNvbHZlUGF0aChiYXJlLCB0aGlzLmFsaWFzUGF0aHMsIHRoaXMuYWxpYXNCYXNlVXJsKSxcblx0XHRcdFx0XHRcdHZlcnNpb25GaWxlVXJsOiAoZmlsZVVybCkgPT4gdGhpcy5nZXRDYWNoZWRPck5ldyhmaWxlVXJsKSxcblx0XHRcdFx0XHR9KSA/PyBzcGVjaWZpZXI7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdCA9IG5leHQocmV3cml0dGVuLCBjb250ZXh0KSBhcyBSZXNvbHZlRm5PdXRwdXQ7XG5cdFx0XHRcdHRoaXMub25Qb3N0UmVzb2x2ZShyZXN1bHQsIHBhcmVudFVybCk7XG5cdFx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0XHR9LFxuXHRcdFx0bG9hZDogKFxuXHRcdFx0XHR1cmw6IHN0cmluZyxcblx0XHRcdFx0Y29udGV4dDogTG9hZEhvb2tDb250ZXh0LFxuXHRcdFx0XHRuZXh0OiAodXJsOiBzdHJpbmcsIGNvbnRleHQ/OiBQYXJ0aWFsPExvYWRIb29rQ29udGV4dD4pID0+IExvYWRGbk91dHB1dCxcblx0XHRcdCk6IExvYWRGbk91dHB1dCA9PiB7XG5cdFx0XHRcdGlmICh0aGlzLmRpc3Bvc2VkKSByZXR1cm4gbmV4dCh1cmwsIGNvbnRleHQpO1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSB0aGlzLmxvYWRUcyh1cmwpO1xuXHRcdFx0XHRpZiAocmVzdWx0ICE9IG51bGwpXG5cdFx0XHRcdFx0cmV0dXJuIHsgZm9ybWF0OiBcIm1vZHVsZVwiLCBzb3VyY2U6IHJlc3VsdC5zb3VyY2UsIHNob3J0Q2lyY3VpdDogdHJ1ZSB9O1xuXHRcdFx0XHRyZXR1cm4gbmV4dCh1cmwsIGNvbnRleHQpO1xuXHRcdFx0fSxcblx0XHR9KTtcblx0fVxuXG5cdC8vIOKUgOKUgCBNb2R1bGUgaG9va3Mg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cblx0cHJpdmF0ZSBhc3luYyBidWlsZEFsaWFzUGF0aHMoKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4+IHtcblx0XHRjb25zdCB3b3Jrc3BhY2UgPSB0aGlzLndvcmtzcGFjZTtcblx0XHRpZiAod29ya3NwYWNlID09IG51bGwpIHJldHVybiB7fTtcblxuXHRcdGNvbnN0IHBhY2thZ2VBbGlhc2VzID0gd29ya3NwYWNlLmdldFBhY2thZ2VBbGlhc2VzKHRoaXMuYnVpbGRDb25maWcpO1xuXHRcdHRoaXMuYWxpYXNCYXNlVXJsID0gcGFja2FnZUFsaWFzZXMuYmFzZVVybDtcblx0XHRyZXR1cm4gcGFja2FnZUFsaWFzZXMucGF0aHM7XG5cdH1cblxuXHQvKipcblx0ICogUG9zdC1uZXh0IGRlcGVuZGVuY3kgdHJhY2tlcjogcmVjb3JkcyB3aGljaCBzb3VyY2UgZmlsZXMgaW1wb3J0IHdoaWNoXG5cdCAqIG90aGVyIHNvdXJjZSBmaWxlcyBzbyB0aGF0IHJlbG9hZElmQWZmZWN0ZWQgY2FuIHRyYXZlcnNlIHRoZSBncmFwaC5cblx0ICovXG5cdHByaXZhdGUgb25Qb3N0UmVzb2x2ZSA9IChyZXN1bHQ6IFJlc29sdmVGbk91dHB1dCwgcGFyZW50VXJsOiBzdHJpbmcpID0+IHtcblx0XHRjb25zdCB7IHVybCB9ID0gcmVzdWx0O1xuXHRcdGNvbnN0IHBhcmVudFVybENsZWFuID0gcGFyZW50VXJsLnNwbGl0KFwiP1wiKVswXTtcblxuXHRcdGxldCBmaWxlUGF0aDogc3RyaW5nO1xuXHRcdGxldCBwYXJlbnRQYXRoOiBzdHJpbmc7XG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgdXJsT2JqID0gbmV3IFVSTCh1cmwpO1xuXHRcdFx0dXJsT2JqLnNlYXJjaCA9IFwiXCI7XG5cdFx0XHRmaWxlUGF0aCA9IGlvLmZpbGVVcmxUb1BhdGgodXJsT2JqLnRvU3RyaW5nKCkpO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRyeSB7XG5cdFx0XHRwYXJlbnRQYXRoID0gaW8uZmlsZVVybFRvUGF0aChwYXJlbnRVcmxDbGVhbik7XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHRwYXJlbnRQYXRoID0gXCJcIjtcblx0XHR9XG5cblx0XHRjb25zdCBpc1NvdXJjZSA9IHRoaXMuZmlsZUluZm9NYXAuaGFzKGZpbGVQYXRoKTtcblx0XHRjb25zdCBwYXJlbnRJc1NvdXJjZSA9IHRoaXMuZmlsZUluZm9NYXAuaGFzKHBhcmVudFBhdGgpO1xuXG5cdFx0aWYgKGlzU291cmNlIHx8IHBhcmVudElzU291cmNlKSB7XG5cdFx0XHR0aGlzLnRyYWNrRGVwZW5kZW5jeShmaWxlUGF0aCwgcGFyZW50UGF0aCk7XG5cdFx0fVxuXHR9O1xuXG5cdHByaXZhdGUgbG9hZFRzOiBMb2FkRGVsZWdhdGUgPSAodXJsOiBzdHJpbmcpID0+IHtcblx0XHRpZiAoIXVybC5zdGFydHNXaXRoKFwiZmlsZTpcIikpIHJldHVybiBudWxsO1xuXG5cdFx0Y29uc3QgY2xlYW5QYXRoID0gbmV3IFVSTCh1cmwpLnBhdGhuYW1lO1xuXHRcdGNvbnN0IGZpbGVJbmZvID0gdGhpcy5maWxlSW5mb01hcC5nZXQoY2xlYW5QYXRoKTtcblx0XHRpZiAoZmlsZUluZm8gPT0gbnVsbCkgcmV0dXJuIG51bGw7XG5cblx0XHRjb25zdCBjYWNoZWQgPSB0aGlzLnRyYW5zcGlsZUNhY2hlLmdldChjbGVhblBhdGgpO1xuXHRcdGlmIChjYWNoZWQgIT0gbnVsbCkgcmV0dXJuIHsgc291cmNlOiBjYWNoZWQgfTtcblxuXHRcdGNvbnN0IHsgcHJvamVjdCB9ID0gZmlsZUluZm87XG5cdFx0Y29uc3QgdHNDb25maWcgPSBwcm9qZWN0LmdldFRzQ29uZmlnU3luYygpO1xuXHRcdGNvbnN0IHVzZXJDb25maWcgPSBwcm9qZWN0LmdldFN3Y0NvbmZpZ1N5bmMoKTtcblxuXHRcdGNvbnN0IGZpbGUgPSBuZXcgRmlsZUV4KHsgZnVsbFBhdGg6IGNsZWFuUGF0aCB9KTtcblx0XHRjb25zdCByZXNwb25zZSA9IHRoaXMudHJhbnNwaWxlci50cmFuc2Zvcm1GaWxlU3luYyhmaWxlLCBCdWlsZFRhcmdldHMuZXM2LCB7XG5cdFx0XHR0c0NvbmZpZyxcblx0XHRcdGFsaWFzUGF0aHM6IHRydWUsXG5cdFx0XHR1c2VyQ29uZmlnLFxuXHRcdFx0d29ya3NwYWNlOiB0aGlzLndvcmtzcGFjZSxcblx0XHRcdHByb2plY3RzOiB0aGlzLndvcmtzcGFjZT8uZ2V0UHJvamVjdHModGhpcy5idWlsZENvbmZpZyksXG5cdFx0fSk7XG5cblx0XHRpZiAocmVzcG9uc2Uub3V0Y29tZSAhPT0gXCJzdWNjZXNzXCIpIHtcblx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gdHJhbnNwaWxlICR7Y2xlYW5QYXRofWAsIHJlc3BvbnNlKTtcblx0XHRcdC8vIERvIG5vdCBmYWxsIHRocm91Z2ggdG8gbmV4dCgpOiBWaXRlc3QvTm9kZSBsb2FkZXJzIGNhbiBkZWFkbG9jayBvbiBhXG5cdFx0XHQvLyB2ZXJzaW9uZWQgLnRzIFVSTC4gRmFpbCB0aGUgaW1wb3J0IHNvIGJvb3RFbnRyeSBjYW4gY2F0Y2ggYW5kIGNvbnRpbnVlLlxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gdHJhbnNwaWxlICR7Y2xlYW5QYXRofWApO1xuXHRcdH1cblxuXHRcdHRoaXMudHJhbnNwaWxlQ2FjaGUuc2V0KGNsZWFuUGF0aCwgcmVzcG9uc2UuY29kZSk7XG5cdFx0cmV0dXJuIHsgc291cmNlOiByZXNwb25zZS5jb2RlIH07XG5cdH07XG5cblx0Ly8g4pSA4pSAIEZpbGUgd2F0Y2hpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cblx0cHJpdmF0ZSBvbkZpbGVDaGFuZ2UgPSAoZXZ0OiBQcm9qZWN0RmlsZUV2ZW50KSA9PiB7XG5cdFx0Y29uc3QgeyBmaWxlLCBldmVudE5hbWUsIHByb2plY3QgfSA9IGV2dDtcblx0XHRjb25zdCBmdWxsUGF0aCA9IGZpbGUuZnVsbFBhdGg7XG5cblx0XHR0aGlzLmxvZ2dlci50cmFjZShgRmlsZSAke2V2ZW50TmFtZX06ICR7ZnVsbFBhdGh9YCk7XG5cblx0XHRpZiAoZXZlbnROYW1lID09PSBpby5XYXRjaEV2ZW50cy51bmxpbmspIHtcblx0XHRcdHRoaXMudHJhbnNwaWxlQ2FjaGUuZGVsZXRlKGZ1bGxQYXRoKTtcblx0XHRcdHRoaXMubW9kdWxlQ2FjaGUuc2V0KGZ1bGxQYXRoLCBudWxsKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoZXZlbnROYW1lID09PSBpby5XYXRjaEV2ZW50cy5hZGQpIHtcblx0XHRcdGlmIChwcm9qZWN0LmlzU291cmNlRmlsZShmaWxlKSkge1xuXHRcdFx0XHR0aGlzLmZpbGVJbmZvTWFwLnNldChmdWxsUGF0aCwgeyBwcm9qZWN0IH0pO1xuXHRcdFx0XHR0aGlzLm1vZHVsZUNhY2hlLnNldChmdWxsUGF0aCwgbnVsbCk7XG5cdFx0XHRcdHRoaXMucmVsb2FkSWZBZmZlY3RlZChmdWxsUGF0aCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gY2hhbmdlXG5cdFx0aWYgKCFwcm9qZWN0LmlzU291cmNlRmlsZShmaWxlKSkgcmV0dXJuO1xuXHRcdHRoaXMudHJhbnNwaWxlQ2FjaGUuZGVsZXRlKGZ1bGxQYXRoKTtcblx0XHR0aGlzLnRyYW5zcGlsZXIuaW52YWxpZGF0ZUNvbnRlbnRDYWNoZShuZXcgRmlsZUV4KHsgZnVsbFBhdGggfSkpO1xuXHRcdHRoaXMucmVsb2FkSWZBZmZlY3RlZChmdWxsUGF0aCk7XG5cdH07XG5cblx0cHJpdmF0ZSByZWxvYWRJZkFmZmVjdGVkKGZ1bGxQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcblx0XHRjb25zdCBkZXBzID0gdGhpcy5nZXREZXBlbmRlbmN5R3JhcGgoZnVsbFBhdGgpO1xuXHRcdGNvbnN0IG1vZHVsZXMgPSBbLi4ubmV3IFNldChbLi4uZGVwcywgZnVsbFBhdGhdKV07XG5cblx0XHRpZiAoIW1vZHVsZXMuaW5jbHVkZXModGhpcy5lbnRyeU1vZHVsZVBhdGgpKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci50cmFjZShgQ2hhbmdlIGluICR7ZnVsbFBhdGh9IGRvZXMgbm90IGFmZmVjdCBlbnRyeSDigJQgc2tpcHBpbmcgcmVsb2FkYCk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dGhpcy5sb2dnZXIudHJhY2UoXG5cdFx0XHRgQ2hhbmdlIGluICR7ZnVsbFBhdGh9IGFmZmVjdHMgJHttb2R1bGVzLmxlbmd0aH0gbW9kdWxlKHMpIOKAlCBzY2hlZHVsaW5nIHJlbG9hZGAsXG5cdFx0KTtcblx0XHR0aGlzLmludmFsaWRhdGVNb2R1bGUoLi4ubW9kdWxlcyk7XG5cdFx0dGhpcy5zY2hlZHVsZVJlYm9vdCgpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0Ly8g4pSA4pSAIERlcGVuZGVuY3kgZ3JhcGgg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cblx0cHJpdmF0ZSBnZXREZXBlbmRlbmN5R3JhcGgobW9kdWxlSWQ6IHN0cmluZywgcGFyZW50TW9kdWxlczogc3RyaW5nW10gPSBbXSk6IHN0cmluZ1tdIHtcblx0XHRpZiAodGhpcy5pc1NlbGYobW9kdWxlSWQpKSByZXR1cm4gW107XG5cblx0XHRjb25zdCBtb2R1bGVEZXBzID0gdGhpcy5kZXBlbmRlbmNpZXMuZ2V0KG1vZHVsZUlkKSA/PyBbXTtcblx0XHRpZiAocGFyZW50TW9kdWxlcy5pbmNsdWRlcyhtb2R1bGVJZCkpIHtcblx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBDaXJjdWxhciByZWZlcmVuY2UgZGV0ZWN0ZWQ6ICR7bW9kdWxlSWR9YCk7XG5cdFx0XHRyZXR1cm4gW107XG5cdFx0fVxuXG5cdFx0bGV0IHN1YkRlcHM6IHN0cmluZ1tdID0gW107XG5cdFx0Zm9yIChjb25zdCBkZXAgb2YgbW9kdWxlRGVwcykge1xuXHRcdFx0aWYgKCF0aGlzLmZpbGVJbmZvTWFwLmhhcyhkZXApKSBjb250aW51ZTtcblx0XHRcdGNvbnN0IHN1YnMgPSB0aGlzLmdldERlcGVuZGVuY3lHcmFwaChkZXAsIFttb2R1bGVJZCwgLi4ucGFyZW50TW9kdWxlc10pO1xuXHRcdFx0c3ViRGVwcyA9IFsuLi5zdWJEZXBzLCAuLi5zdWJzXTtcblx0XHR9XG5cblx0XHRyZXR1cm4gWy4uLm5ldyBTZXQoWy4uLm1vZHVsZURlcHMsIC4uLnN1YkRlcHNdKV07XG5cdH1cblxuXHRwcml2YXRlIHRyYWNrRGVwZW5kZW5jeShmaWxlUGF0aDogc3RyaW5nLCBwYXJlbnRQYXRoOiBzdHJpbmcpIHtcblx0XHRpZiAoIXBhcmVudFBhdGgpIHJldHVybjtcblx0XHRjb25zdCBkZXBzID0gdGhpcy5kZXBlbmRlbmNpZXMuZ2V0KGZpbGVQYXRoKSA/PyBbXTtcblx0XHRjb25zdCB1cGRhdGVkRGVwcyA9IG5ldyBTZXQoWy4uLmRlcHMsIHBhcmVudFBhdGhdKTtcblx0XHR0aGlzLmRlcGVuZGVuY2llcy5zZXQoZmlsZVBhdGgsIFsuLi51cGRhdGVkRGVwc10pO1xuXHR9XG5cblx0Ly8g4pSA4pSAIE1vZHVsZSBjYWNoZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuXHRwcml2YXRlIGdldENhY2hlZE9yTmV3KG1vZHVsZVVybDogc3RyaW5nKSB7XG5cdFx0Y29uc3QgZmlsZVBhdGggPSBpby5maWxlVXJsVG9QYXRoKG1vZHVsZVVybCk7XG5cdFx0Y29uc3QgY2FjaGVkID0gdGhpcy5tb2R1bGVDYWNoZS5nZXQoZmlsZVBhdGgpO1xuXHRcdGNvbnN0IHZlcnNpb25lZCA9IGNhY2hlZCA/PyB0aGlzLnZlcnNpb25Nb2R1bGUobW9kdWxlVXJsKTtcblx0XHR0aGlzLm1vZHVsZUNhY2hlLnNldChmaWxlUGF0aCwgdmVyc2lvbmVkKTtcblx0XHRyZXR1cm4gdmVyc2lvbmVkO1xuXHR9XG5cblx0cHJpdmF0ZSB2ZXJzaW9uTW9kdWxlKG1vZHVsZVVybDogc3RyaW5nKSB7XG5cdFx0Y29uc3QgdmVyc2lvbmVkVXJsID0gbmV3IFVSTChtb2R1bGVVcmwpO1xuXHRcdHZlcnNpb25lZFVybC5zZWFyY2hQYXJhbXMuc2V0KFZFUlNJT05fVVJMX1BBUkFNLCBTdHJpbmcoKyttb2R1bGVWZXJzaW9uU2VxKSk7XG5cdFx0cmV0dXJuIHZlcnNpb25lZFVybC50b1N0cmluZygpO1xuXHR9XG5cblx0cHJpdmF0ZSBpbnZhbGlkYXRlTW9kdWxlKC4uLm1vZHVsZXM6IHN0cmluZ1tdKSB7XG5cdFx0Zm9yIChjb25zdCBtb2R1bGUgb2YgbW9kdWxlcykge1xuXHRcdFx0dGhpcy5tb2R1bGVDYWNoZS5zZXQobW9kdWxlLCBudWxsKTtcblx0XHRcdHRoaXMudHJhbnNwaWxlQ2FjaGUuZGVsZXRlKG1vZHVsZSk7XG5cdFx0XHQvLyBQcnVuZSBzdGFsZSBvdXRnb2luZyBlZGdlczogcmVtb3ZlIHRoaXMgbW9kdWxlIGFzIGEgcGFyZW50IGZyb20gYWxsIGRlcGVuZGVuY3kgbGlzdHNcblx0XHRcdGZvciAoY29uc3QgW2tleSwgcGFyZW50c10gb2YgdGhpcy5kZXBlbmRlbmNpZXMpIHtcblx0XHRcdFx0Y29uc3QgZmlsdGVyZWQgPSBwYXJlbnRzLmZpbHRlcigocCkgPT4gcCAhPT0gbW9kdWxlKTtcblx0XHRcdFx0aWYgKGZpbHRlcmVkLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRcdHRoaXMuZGVwZW5kZW5jaWVzLmRlbGV0ZShrZXkpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMuZGVwZW5kZW5jaWVzLnNldChrZXksIGZpbHRlcmVkKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgaW52YWxpZGF0ZUFsbFNvdXJjZUZpbGVzKCkge1xuXHRcdGZvciAoY29uc3QgZmlsZVBhdGggb2YgdGhpcy5maWxlSW5mb01hcC5rZXlzKCkpIHtcblx0XHRcdHRoaXMubW9kdWxlQ2FjaGUuc2V0KGZpbGVQYXRoLCBudWxsKTtcblx0XHR9XG5cdH1cblxuXHQvLyDilIDilIAgVXRpbGl0aWVzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5cdHByaXZhdGUgaXNTZWxmKGZpbGVQYXRoOiBzdHJpbmcpIHtcblx0XHRyZXR1cm4gY3VycmVudEZpbGVQYXRoID09PSBwYXRoLnJlc29sdmUoZmlsZVBhdGgpO1xuXHR9XG59XG4iXSwibmFtZXMiOlsiREVGQVVMVF9SRUJPT1RfREVCT1VOQ0VfTVMiLCJIb3RSZWxvYWRTZXJ2ZXIiLCJyZXNvbHZlUmVib290RGVib3VuY2VNcyIsImN1cnJlbnRGaWxlUGF0aCIsImlvIiwiZmlsZVVybFRvUGF0aCIsIlZFUlNJT05fVVJMX1BBUkFNIiwidmFsdWUiLCJkZWxheSIsIk51bWJlciIsImlzRmluaXRlIiwiRXJyb3IiLCJTdHJpbmciLCJtb2R1bGVWZXJzaW9uU2VxIiwiRXZlbnRFbWl0dGVyIiwibG9nZ2VyIiwic2NyaWJlIiwibmFtZSIsImRpc3Bvc2VkIiwiaG9va3NSZWdpc3RlcmVkIiwiZW50cnlNb2R1bGVQYXRoIiwiZW50cnlNb2R1bGUiLCJ3b3Jrc3BhY2UiLCJidWlsZENvbmZpZyIsIndhdGNoU3Vic2NyaXB0aW9uIiwiZmlsZUluZm9NYXAiLCJNYXAiLCJtb2R1bGVDYWNoZSIsImRlcGVuZGVuY2llcyIsInRyYW5zcGlsZUNhY2hlIiwidHJhbnNwaWxlciIsIlN3Y1RyYW5zcGlsZXIiLCJhbGlhc1BhdGhzIiwiYWxpYXNCYXNlVXJsIiwicGF0aCIsInJlc29sdmUiLCJyZWJvb3RUYWlsIiwiUHJvbWlzZSIsInJlYm9vdERlYm91bmNlR2VuIiwicmVib290SW5GbGlnaHQiLCJyZWJvb3RGb2xsb3dVcCIsInJlYm9vdFF1ZXVlZCIsInNjaGVkdWxlUmVib290Iiwic3RhcnQiLCJvcHRpb25zIiwiY2xlYXIiLCJiaW5kU2NoZWR1bGVSZWJvb3QiLCJyZWJvb3REZWJvdW5jZU1zIiwicmVzb2x2ZVdvcmtzcGFjZSIsInByb2plY3QiLCJyZXNvbHZlUHJvamVjdCIsImdldFNvdXJjZUVudHJ5UGF0aCIsImJ1aWxkRmlsZUluZm9NYXAiLCJidWlsZEFsaWFzUGF0aHMiLCJyZWdpc3Rlckhvb2tzIiwiaW52YWxpZGF0ZUFsbFNvdXJjZUZpbGVzIiwid2F0Y2giLCJwcm9qZWN0RmlsZUNoYW5nZWQkIiwic3Vic2NyaWJlIiwib25GaWxlQ2hhbmdlIiwidHJhY2UiLCJib290RW50cnkiLCJlbWl0IiwiZGlzcG9zZSIsInVuc3Vic2NyaWJlIiwiU3ltYm9sIiwiZGlzcG9zZUVudHJ5IiwiYXN5bmNEaXNwb3NlIiwidXJsIiwidmVyc2lvbk1vZHVsZSIsInBhdGhUb0ZpbGVVcmwiLCJkZWZhdWx0IiwiZXJyb3IiLCJ1bmRlZmluZWQiLCJkZWxheU1zIiwiZ2VuIiwiZGVib3VuY2UiLCJyZXF1ZXN0UmVib290IiwidGhlbiIsInJ1blJlYm9vdCIsIm5lZWRzRm9sbG93VXAiLCJlbnRyeSIsIldvcmtzcGFjZUZhY3RvcnkiLCJjcmVhdGUiLCJXb3Jrc3BhY2VEZWZhdWx0cyIsInJvb3REaXIiLCJwcm9jZXNzIiwiY3dkIiwicHJvamVjdHMiLCJnZXRQcm9qZWN0cyIsImZvdW5kIiwiYXQiLCJmaW5kIiwicCIsImVudHJpZXMiLCJhbGwiLCJtYXAiLCJmaWxlcyIsImdldEFsbEZpbGVzIiwiZmlsZSIsImZ1bGxQYXRoIiwiZmxhdCIsInNwZWNpZmllciIsImNvbnRleHQiLCJuZXh0IiwicGFyZW50VXJsIiwicGFyZW50VVJMIiwicmV3cml0dGVuIiwicmV3cml0ZVNlcnZlU3BlY2lmaWVyIiwiaXNXYXRjaGVkVHMiLCJmaWxlUGF0aCIsImhhcyIsInJlc29sdmVCYXJlIiwiYmFyZSIsInBhY2thZ2VBbGlhc2VzIiwicmVzb2x2ZVBhdGgiLCJ2ZXJzaW9uRmlsZVVybCIsImZpbGVVcmwiLCJnZXRDYWNoZWRPck5ldyIsInJlc3VsdCIsIm9uUG9zdFJlc29sdmUiLCJsb2FkIiwibG9hZFRzIiwiZm9ybWF0Iiwic291cmNlIiwic2hvcnRDaXJjdWl0IiwiZ2V0UGFja2FnZUFsaWFzZXMiLCJiYXNlVXJsIiwicGF0aHMiLCJwYXJlbnRVcmxDbGVhbiIsInNwbGl0IiwicGFyZW50UGF0aCIsInVybE9iaiIsIlVSTCIsInNlYXJjaCIsInRvU3RyaW5nIiwiaXNTb3VyY2UiLCJwYXJlbnRJc1NvdXJjZSIsInRyYWNrRGVwZW5kZW5jeSIsInN0YXJ0c1dpdGgiLCJjbGVhblBhdGgiLCJwYXRobmFtZSIsImZpbGVJbmZvIiwiZ2V0IiwiY2FjaGVkIiwidHNDb25maWciLCJnZXRUc0NvbmZpZ1N5bmMiLCJ1c2VyQ29uZmlnIiwiZ2V0U3djQ29uZmlnU3luYyIsIkZpbGVFeCIsInJlc3BvbnNlIiwidHJhbnNmb3JtRmlsZVN5bmMiLCJCdWlsZFRhcmdldHMiLCJlczYiLCJvdXRjb21lIiwic2V0IiwiY29kZSIsImV2dCIsImV2ZW50TmFtZSIsIldhdGNoRXZlbnRzIiwidW5saW5rIiwiZGVsZXRlIiwiYWRkIiwiaXNTb3VyY2VGaWxlIiwicmVsb2FkSWZBZmZlY3RlZCIsImludmFsaWRhdGVDb250ZW50Q2FjaGUiLCJkZXBzIiwiZ2V0RGVwZW5kZW5jeUdyYXBoIiwibW9kdWxlcyIsIlNldCIsImluY2x1ZGVzIiwibGVuZ3RoIiwiaW52YWxpZGF0ZU1vZHVsZSIsIm1vZHVsZUlkIiwicGFyZW50TW9kdWxlcyIsImlzU2VsZiIsIm1vZHVsZURlcHMiLCJzdWJEZXBzIiwiZGVwIiwic3VicyIsInVwZGF0ZWREZXBzIiwibW9kdWxlVXJsIiwidmVyc2lvbmVkIiwidmVyc2lvbmVkVXJsIiwic2VhcmNoUGFyYW1zIiwibW9kdWxlIiwia2V5IiwicGFyZW50cyIsImZpbHRlcmVkIiwiZmlsdGVyIiwia2V5cyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7UUF1QmFBO2VBQUFBOztRQXFDQUM7ZUFBQUE7O1FB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
257
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZsdXgvc3JjL2hvdC1yZWxvYWQtc2VydmVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gXCJub2RlOmV2ZW50c1wiO1xuaW1wb3J0IHR5cGUgeyBSZXNvbHZlRm5PdXRwdXQgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IHR5cGUgRmlsZSwgaW8gfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2lvXCI7XG5pbXBvcnQgeyBkZWJvdW5jZSB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvc3lzdGVtXCI7XG5pbXBvcnQgdHlwZSB7IExvZ2dlciB9IGZyb20gXCJAZGVjb2hlcmUvc2NyaWJlXCI7XG5pbXBvcnQgeyBhZGRSZXNvbHZlckhvb2ssIGluaXRNb2R1bGVIb29rcywgcmVtb3ZlUmVzb2x2ZXJIb29rIH0gZnJvbSBcIi4vaG90LW1vZHVsZS1ob29rcy5qc1wiO1xuXG5jb25zdCBjdXJyZW50RmlsZVBhdGggPSBpby5maWxlVXJsVG9QYXRoKGltcG9ydC5tZXRhLnVybCk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSG90UmVsb2FkU2VydmVyRXZlbnRzIHtcblx0cmVib290OiBbXTtcbn1cblxuZXhwb3J0IGNsYXNzIEhvdFJlbG9hZFNlcnZlciBleHRlbmRzIEV2ZW50RW1pdHRlcjxIb3RSZWxvYWRTZXJ2ZXJFdmVudHM+IHtcblx0cHJpdmF0ZSByZWFkb25seSBsb2dnZXI6IExvZ2dlcjtcblx0cHJpdmF0ZSBkaXNwb3NlZCA9IGZhbHNlO1xuXHRwcml2YXRlIGVudHJ5TW9kdWxlOiBzdHJpbmc7XG5cdHByaXZhdGUgZW50cnk6IEFzeW5jRGlzcG9zYWJsZTtcblx0cHJpdmF0ZSBzb3VyY2VGaWxlczogc3RyaW5nW10gPSBbXTtcblx0cHJpdmF0ZSBtb2R1bGVDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmcgfCBudWxsPigpO1xuXHRwcml2YXRlIGRlcGVuZGVuY2llcyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmdbXT4oKTtcblx0cHJpdmF0ZSB3YXRjaGVyczogUmV0dXJuVHlwZTx0eXBlb2YgaW8ud2F0Y2g+W10gPSBbXTtcblxuXHRwdWJsaWMgY29uc3RydWN0b3IobG9nZ2VyOiBMb2dnZXIpIHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMubG9nZ2VyID0gbG9nZ2VyO1xuXHR9XG5cblx0cHVibGljIGFzeW5jIHN0YXJ0KGVudHJ5OiBzdHJpbmcsIC4uLndhdGNoRGlyczogc3RyaW5nW10pIHtcblx0XHR0aGlzLmVudHJ5TW9kdWxlID0gZW50cnk7XG5cdFx0dGhpcy5zb3VyY2VGaWxlcyA9IGF3YWl0IHRoaXMuZ2V0U291cmNlRmlsZXMod2F0Y2hEaXJzKTtcblx0XHR0aGlzLmNvbmZpZ3VyZU1vZHVsZUhvb2tzKCk7XG5cdFx0dGhpcy5pbnZhbGlkYXRlQWxsU291cmNlRmlsZXMoKTtcblx0XHRhd2FpdCB0aGlzLndhdGNoKHdhdGNoRGlycyk7XG5cdFx0dGhpcy5sb2dnZXIudHJhY2UoXCJTZXJ2aW5nXCIsIGVudHJ5KTtcblx0XHR0aGlzLmxvZ2dlci50cmFjZShcIkhvdCByZWxvYWQgd2F0Y2hpbmdcIiwgd2F0Y2hEaXJzKTtcblx0XHRhd2FpdCB0aGlzLmJvb3RFbnRyeSgpO1xuXHR9XG5cblx0cHVibGljIGFzeW5jIGRpc3Bvc2UoKSB7XG5cdFx0aWYgKHRoaXMuZGlzcG9zZWQpIHJldHVybjtcblx0XHR0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcblx0XHRyZW1vdmVSZXNvbHZlckhvb2sodGhpcy5vblJlc29sdmUpO1xuXHRcdGZvciAoY29uc3Qgd2F0Y2hlciBvZiB0aGlzLndhdGNoZXJzKSB7XG5cdFx0XHR3YXRjaGVyLmNsb3NlKCk7XG5cdFx0fVxuXHRcdGF3YWl0IHRoaXMuZGlzcG9zZUVudHJ5KCk7XG5cdH1cblxuXHRwcml2YXRlIHJlbW92ZVNvdXJjZUZpbGVzKC4uLnNvdXJjZUZpbGVzOiBzdHJpbmdbXSkge1xuXHRcdHRoaXMuc291cmNlRmlsZXMgPSB0aGlzLnNvdXJjZUZpbGVzLmZpbHRlcihcblx0XHRcdChzb3VyY2VGaWxlKSA9PiAhc291cmNlRmlsZXMuaW5jbHVkZXMoc291cmNlRmlsZSksXG5cdFx0KTtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgZ2V0U291cmNlRmlsZXMoZGlyczogc3RyaW5nW10pIHtcblx0XHRjb25zdCBwYXR0ZXJucyA9IGRpcnMubWFwKChkaXIpID0+IGAke2Rpcn0vKiovKi5qc2ApO1xuXHRcdGNvbnN0IGZpbGVzID0gYXdhaXQgaW8uZmluZEZpbGVzKHBhdHRlcm5zKTtcblx0XHRyZXR1cm4gZmlsZXMubWFwKChmKSA9PiBmLmZ1bGxQYXRoKTtcblx0fVxuXG5cdHByaXZhdGUgY29uZmlndXJlTW9kdWxlSG9va3MoKSB7XG5cdFx0aW5pdE1vZHVsZUhvb2tzKCk7XG5cdFx0YWRkUmVzb2x2ZXJIb29rKHRoaXMub25SZXNvbHZlKTtcblx0fVxuXG5cdHByaXZhdGUgb25SZXNvbHZlID0gKHJlc3VsdDogUmVzb2x2ZUZuT3V0cHV0LCBwYXJlbnRVcmw6IHN0cmluZykgPT4ge1xuXHRcdGNvbnN0IHsgdXJsIH0gPSByZXN1bHQ7XG5cdFx0Y29uc3QgcGFyZW50VXJsQ2xlYW4gPSBwYXJlbnRVcmwuc3BsaXQoXCI/XCIpWzBdO1xuXHRcdGNvbnN0IGlzU291cmNlID0gdGhpcy5pc1NvdXJjZU1vZHVsZSh1cmwpO1xuXHRcdGNvbnN0IHBhcmVudElzU291cmNlID0gdGhpcy5pc1NvdXJjZU1vZHVsZShwYXJlbnRVcmxDbGVhbik7XG5cblx0XHRpZiAoaXNTb3VyY2UgfHwgcGFyZW50SXNTb3VyY2UpIHtcblx0XHRcdHRoaXMudHJhY2tEZXBlbmRlbmN5KHVybCwgcGFyZW50VXJsKTtcblx0XHR9XG5cblx0XHRpZiAoIWlzU291cmNlKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0cmVzdWx0LnVybCA9IHRoaXMuZ2V0Q2FjaGVkT3JOZXcodXJsKTtcblx0fTtcblxuXHRwcml2YXRlIGlzU291cmNlTW9kdWxlKHVybDogc3RyaW5nKSB7XG5cdFx0Y29uc3QgcGF0aCA9IGlvLmZpbGVVcmxUb1BhdGgodXJsKTtcblx0XHRyZXR1cm4gdGhpcy5zb3VyY2VGaWxlcy5pbmNsdWRlcyhwYXRoKTtcblx0fVxuXG5cdHByaXZhdGUgZ2V0RGVwZW5kZW5jeUdyYXBoKG1vZHVsZUlkOiBzdHJpbmcsIHBhcmVudE1vZHVsZXM6IHN0cmluZ1tdID0gW10pIHtcblx0XHRpZiAodGhpcy5pc1NlbGYobW9kdWxlSWQpKSB7XG5cdFx0XHRyZXR1cm4gW107XG5cdFx0fVxuXG5cdFx0Y29uc3QgbW9kdWxlRGVwcyA9IHRoaXMuZGVwZW5kZW5jaWVzLmdldChtb2R1bGVJZCkgPz8gW107XG5cdFx0aWYgKHBhcmVudE1vZHVsZXMuaW5jbHVkZXMobW9kdWxlSWQpKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihgQ2lyY3VsYXIgcmVmZXJlbmNlIGRldGVjdGVkOiAke21vZHVsZUlkfWApO1xuXHRcdFx0cmV0dXJuIFtdO1xuXHRcdH1cblxuXHRcdGxldCBzdWJEZXBzID0gQXJyYXkub2Y8c3RyaW5nPigpO1xuXHRcdGZvciAoY29uc3QgZGVwIG9mIG1vZHVsZURlcHMpIHtcblx0XHRcdGlmICghdGhpcy5zb3VyY2VGaWxlcy5pbmNsdWRlcyhkZXApKSBjb250aW51ZTtcblx0XHRcdGNvbnN0IHN1YnMgPSB0aGlzLmdldERlcGVuZGVuY3lHcmFwaChkZXAsIFttb2R1bGVJZCwgLi4ucGFyZW50TW9kdWxlc10pO1xuXHRcdFx0c3ViRGVwcyA9IFsuLi5zdWJEZXBzLCAuLi5zdWJzXTtcblx0XHR9XG5cblx0XHRyZXR1cm4gWy4uLm5ldyBTZXQoWy4uLm1vZHVsZURlcHMsIC4uLnN1YkRlcHNdKV07XG5cdH1cblxuXHRwcml2YXRlIHRyYWNrRGVwZW5kZW5jeSh1cmw6IHN0cmluZywgcGFyZW50VXJsOiBzdHJpbmcpIHtcblx0XHRjb25zdCBmaWxlUGF0aCA9IGlvLmZpbGVVcmxUb1BhdGgodXJsKTtcblx0XHRjb25zdCBwYXJlbnRQYXRoID0gaW8uZmlsZVVybFRvUGF0aChwYXJlbnRVcmwuc3BsaXQoXCI/XCIpWzBdKTtcblx0XHRjb25zdCBkZXBzID0gdGhpcy5kZXBlbmRlbmNpZXMuZ2V0KGZpbGVQYXRoKSA/PyBbXTtcblx0XHRjb25zdCB1cGRhdGVkRGVwcyA9IG5ldyBTZXQoWy4uLmRlcHMsIHBhcmVudFBhdGhdKTtcblx0XHR0aGlzLmRlcGVuZGVuY2llcy5zZXQoZmlsZVBhdGgsIFsuLi51cGRhdGVkRGVwc10pO1xuXHR9XG5cblx0cHJpdmF0ZSBnZXRDYWNoZWRPck5ldyhtb2R1bGVVcmw6IHN0cmluZykge1xuXHRcdGNvbnN0IGZpbGVQYXRoID0gaW8uZmlsZVVybFRvUGF0aChtb2R1bGVVcmwpO1xuXHRcdGNvbnN0IGNhY2hlZCA9IHRoaXMubW9kdWxlQ2FjaGUuZ2V0KGZpbGVQYXRoKTtcblx0XHRjb25zdCB2ZXJzaW9uZWQgPSBjYWNoZWQgPz8gdGhpcy52ZXJzaW9uTW9kdWxlKG1vZHVsZVVybCk7XG5cdFx0dGhpcy5tb2R1bGVDYWNoZS5zZXQoZmlsZVBhdGgsIHZlcnNpb25lZCk7XG5cdFx0cmV0dXJuIHZlcnNpb25lZDtcblx0fVxuXG5cdHByaXZhdGUgdmVyc2lvbk1vZHVsZShtb2R1bGVVcmw6IHN0cmluZykge1xuXHRcdGNvbnN0IHZlcnNpb25lZFVybCA9IG5ldyBVUkwobW9kdWxlVXJsKTtcblx0XHR2ZXJzaW9uZWRVcmwuc2VhcmNoUGFyYW1zLnNldChcInZlcnNpb25cIiwgRGF0ZS5ub3coKS50b1N0cmluZygpKTtcblx0XHRyZXR1cm4gdmVyc2lvbmVkVXJsLnRvU3RyaW5nKCk7XG5cdH1cblxuXHRwcml2YXRlIHdhdGNoID0gYXN5bmMgKGRpcnM6IHN0cmluZ1tdKSA9PiB7XG5cdFx0Zm9yIChjb25zdCBkaXIgb2YgZGlycykge1xuXHRcdFx0Y29uc3Qgd2F0Y2hlciA9IGlvLndhdGNoKGRpciwgeyBpbmNsdWRlOiBbXCIqKi8qLmpzXCJdLCBpZ25vcmVJbml0aWFsOiB0cnVlIH0pO1xuXHRcdFx0d2F0Y2hlclxuXHRcdFx0XHQub24oXCJhZGRcIiwgdGhpcy5vbkZpbGVBZGRlZClcblx0XHRcdFx0Lm9uKFwiY2hhbmdlXCIsIHRoaXMub25Tb3VyY2VGaWxlQ2hhbmdlZClcblx0XHRcdFx0Lm9uKFwidW5saW5rXCIsIHRoaXMub25GaWxlRGVsZXRlZCk7XG5cdFx0XHR0aGlzLndhdGNoZXJzLnB1c2god2F0Y2hlcik7XG5cdFx0fVxuXHR9O1xuXG5cdHByaXZhdGUgb25GaWxlQWRkZWQgPSBhc3luYyAoeyBmdWxsUGF0aCB9OiBGaWxlKSA9PiB7XG5cdFx0dGhpcy5zb3VyY2VGaWxlcy5wdXNoKGZ1bGxQYXRoKTtcblx0XHR0aGlzLm1vZHVsZUNhY2hlLnNldChmdWxsUGF0aCwgbnVsbCk7XG5cdFx0dGhpcy5yZWxvYWRJZkFmZmVjdGVkKGZ1bGxQYXRoKTtcblx0fTtcblxuXHRwcml2YXRlIG9uU291cmNlRmlsZUNoYW5nZWQgPSBhc3luYyAoeyBmdWxsUGF0aCB9OiBGaWxlKSA9PiB7XG5cdFx0aWYgKCF0aGlzLnJlbG9hZElmQWZmZWN0ZWQoZnVsbFBhdGgpKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci50cmFjZShcblx0XHRcdFx0YCR7ZnVsbFBhdGh9IGlzIG5vdCBwYXJ0IG9mIHRoZSBjdXJyZW50IGRlcGVuZGVuY3kgZ3JhcGguIE5vdCByZWxvYWRpbmcgZW50cnkuYCxcblx0XHRcdCk7XG5cdFx0fVxuXHR9O1xuXG5cdHByaXZhdGUgb25GaWxlRGVsZXRlZCA9IGFzeW5jICh7IGZ1bGxQYXRoIH06IEZpbGUpID0+IHtcblx0XHR0aGlzLnJlbW92ZVNvdXJjZUZpbGVzKGZ1bGxQYXRoKTtcblx0fTtcblxuXHRwcml2YXRlIHJlbG9hZElmQWZmZWN0ZWQoZnVsbFBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRcdGNvbnN0IGRlcHMgPSB0aGlzLmdldERlcGVuZGVuY3lHcmFwaChmdWxsUGF0aCk7XG5cdFx0Y29uc3QgbW9kdWxlcyA9IFsuLi5uZXcgU2V0KFsuLi5kZXBzLCBmdWxsUGF0aF0pXTtcblxuXHRcdGlmICghbW9kdWxlcy5pbmNsdWRlcyh0aGlzLmVudHJ5TW9kdWxlKSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHRoaXMuaW52bGlkYXRlTW9kdWxlKC4uLm1vZHVsZXMpO1xuXHRcdHRoaXMuZGlzcG9zZUFuZEJvb3QoKTtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdHByaXZhdGUgaXNTZWxmKHVybExpa2U6IHN0cmluZykge1xuXHRcdHJldHVybiBjdXJyZW50RmlsZVBhdGggPT09IHBhdGgucmVzb2x2ZShpby5maWxlVXJsVG9QYXRoKHVybExpa2UpKTtcblx0fVxuXG5cdHByaXZhdGUgaW52bGlkYXRlTW9kdWxlKC4uLm1vZHVsZXM6IHN0cmluZ1tdKSB7XG5cdFx0Zm9yIChjb25zdCBtb2R1bGUgb2YgbW9kdWxlcykge1xuXHRcdFx0dGhpcy5tb2R1bGVDYWNoZS5zZXQobW9kdWxlLCBudWxsKTtcblx0XHR9XG5cdFx0Ly8gUHJ1bmUgaW52YWxpZGF0ZWQgbW9kdWxlcyBmcm9tIGFsbCBwYXJlbnQgbGlzdHMgc28gc3RhbGUgcmVsYXRpb25zaGlwc1xuXHRcdC8vIGFyZSBjbGVhcmVkLiBUaGUgZnJlc2ggYm9vdCByZWJ1aWxkcyBvbmx5IHdoYXQgaXMgYWN0dWFsbHkgaW1wb3J0ZWQuXG5cdFx0Zm9yIChjb25zdCBbY2hpbGQsIHBhcmVudHNdIG9mIHRoaXMuZGVwZW5kZW5jaWVzKSB7XG5cdFx0XHRjb25zdCBwcnVuZWQgPSBwYXJlbnRzLmZpbHRlcigocCkgPT4gIW1vZHVsZXMuaW5jbHVkZXMocCkpO1xuXHRcdFx0aWYgKHBydW5lZC5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0dGhpcy5kZXBlbmRlbmNpZXMuZGVsZXRlKGNoaWxkKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuZGVwZW5kZW5jaWVzLnNldChjaGlsZCwgcHJ1bmVkKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGludmFsaWRhdGVBbGxTb3VyY2VGaWxlcygpIHtcblx0XHRmb3IgKGNvbnN0IGZpbGUgb2YgdGhpcy5zb3VyY2VGaWxlcykge1xuXHRcdFx0dGhpcy5tb2R1bGVDYWNoZS5zZXQoZmlsZSwgbnVsbCk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBkaXNwb3NlQW5kQm9vdCA9IGRlYm91bmNlKGFzeW5jICgpID0+IHtcblx0XHRhd2FpdCB0aGlzLmRpc3Bvc2VFbnRyeSgpO1xuXHRcdGF3YWl0IHRoaXMuYm9vdEVudHJ5KCk7XG5cdH0sIDI1MCk7XG5cblx0cHJpdmF0ZSBhc3luYyBkaXNwb3NlRW50cnkoKSB7XG5cdFx0YXdhaXQgdGhpcy5lbnRyeT8uW1N5bWJvbC5hc3luY0Rpc3Bvc2VdKCk7XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIGJvb3RFbnRyeSgpIHtcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgdmVyc2lvbiA9IHRoaXMudmVyc2lvbk1vZHVsZShpby5wYXRoVG9GaWxlVXJsKHRoaXMuZW50cnlNb2R1bGUpKTtcblx0XHRcdHRoaXMuZW50cnkgPSAoYXdhaXQgaW1wb3J0KHZlcnNpb24pKT8uZGVmYXVsdDtcblx0XHRcdHRoaXMuZW1pdChcInJlYm9vdFwiKTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoXG5cdFx0XHRcdGBUaGVyZSB3YXMgYW4gZXJyb3IgYm9vdGluZyB0aGUgZW50cnkgcG9pbnQuIFlvdXIgYXBwbGljYXRpb24gbWF5IG5vdCBmdW5jdGlvbiBhcyBleHBlY3RlZGAsXG5cdFx0XHRcdGVycm9yLFxuXHRcdFx0KTtcblx0XHR9XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJIb3RSZWxvYWRTZXJ2ZXIiLCJjdXJyZW50RmlsZVBhdGgiLCJpbyIsImZpbGVVcmxUb1BhdGgiLCJFdmVudEVtaXR0ZXIiLCJsb2dnZXIiLCJkaXNwb3NlZCIsImVudHJ5TW9kdWxlIiwiZW50cnkiLCJzb3VyY2VGaWxlcyIsIm1vZHVsZUNhY2hlIiwiTWFwIiwiZGVwZW5kZW5jaWVzIiwid2F0Y2hlcnMiLCJzdGFydCIsIndhdGNoRGlycyIsImdldFNvdXJjZUZpbGVzIiwiY29uZmlndXJlTW9kdWxlSG9va3MiLCJpbnZhbGlkYXRlQWxsU291cmNlRmlsZXMiLCJ3YXRjaCIsInRyYWNlIiwiYm9vdEVudHJ5IiwiZGlzcG9zZSIsInJlbW92ZVJlc29sdmVySG9vayIsIm9uUmVzb2x2ZSIsIndhdGNoZXIiLCJjbG9zZSIsImRpc3Bvc2VFbnRyeSIsInJlbW92ZVNvdXJjZUZpbGVzIiwiZmlsdGVyIiwic291cmNlRmlsZSIsImluY2x1ZGVzIiwiZGlycyIsInBhdHRlcm5zIiwibWFwIiwiZGlyIiwiZmlsZXMiLCJmaW5kRmlsZXMiLCJmIiwiZnVsbFBhdGgiLCJpbml0TW9kdWxlSG9va3MiLCJhZGRSZXNvbHZlckhvb2siLCJyZXN1bHQiLCJwYXJlbnRVcmwiLCJ1cmwiLCJwYXJlbnRVcmxDbGVhbiIsInNwbGl0IiwiaXNTb3VyY2UiLCJpc1NvdXJjZU1vZHVsZSIsInBhcmVudElzU291cmNlIiwidHJhY2tEZXBlbmRlbmN5IiwiZ2V0Q2FjaGVkT3JOZXciLCJwYXRoIiwiZ2V0RGVwZW5kZW5jeUdyYXBoIiwibW9kdWxlSWQiLCJwYXJlbnRNb2R1bGVzIiwiaXNTZWxmIiwibW9kdWxlRGVwcyIsImdldCIsImVycm9yIiwic3ViRGVwcyIsIkFycmF5Iiwib2YiLCJkZXAiLCJzdWJzIiwiU2V0IiwiZmlsZVBhdGgiLCJwYXJlbnRQYXRoIiwiZGVwcyIsInVwZGF0ZWREZXBzIiwic2V0IiwibW9kdWxlVXJsIiwiY2FjaGVkIiwidmVyc2lvbmVkIiwidmVyc2lvbk1vZHVsZSIsInZlcnNpb25lZFVybCIsIlVSTCIsInNlYXJjaFBhcmFtcyIsIkRhdGUiLCJub3ciLCJ0b1N0cmluZyIsImluY2x1ZGUiLCJpZ25vcmVJbml0aWFsIiwib24iLCJvbkZpbGVBZGRlZCIsIm9uU291cmNlRmlsZUNoYW5nZWQiLCJvbkZpbGVEZWxldGVkIiwicHVzaCIsInJlbG9hZElmQWZmZWN0ZWQiLCJtb2R1bGVzIiwiaW52bGlkYXRlTW9kdWxlIiwiZGlzcG9zZUFuZEJvb3QiLCJ1cmxMaWtlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImNoaWxkIiwicGFyZW50cyIsInBydW5lZCIsInAiLCJsZW5ndGgiLCJkZWxldGUiLCJmaWxlIiwiZGVib3VuY2UiLCJTeW1ib2wiLCJhc3luY0Rpc3Bvc2UiLCJ2ZXJzaW9uIiwicGF0aFRvRmlsZVVybCIsImRlZmF1bHQiLCJlbWl0Il0sIm1hcHBpbmdzIjoiOzs7OytCQWNhQTs7O2VBQUFBOzs7NEJBZGdCO2lFQUVaO29CQUNhO3dCQUNMO2dDQUU0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFckUsTUFBTUMsa0JBQWtCQyxNQUFFLENBQUNDLGFBQWEsQ0FBQztBQU1sQyxNQUFNSCx3QkFBd0JJLHdCQUFZO0lBQy9CQyxPQUFlO0lBQ3hCQyxXQUFXLE1BQU07SUFDakJDLFlBQW9CO0lBQ3BCQyxNQUF1QjtJQUN2QkMsY0FBd0IsRUFBRSxDQUFDO0lBQzNCQyxjQUFjLElBQUlDLE1BQTZCO0lBQy9DQyxlQUFlLElBQUlELE1BQXdCO0lBQzNDRSxXQUEwQyxFQUFFLENBQUM7SUFFckQsWUFBbUJSLE1BQWMsQ0FBRTtRQUNsQyxLQUFLO1FBQ0wsSUFBSSxDQUFDQSxNQUFNLEdBQUdBO0lBQ2Y7SUFFQSxNQUFhUyxNQUFNTixLQUFhLEVBQUUsR0FBR08sU0FBbUIsRUFBRTtRQUN6RCxJQUFJLENBQUNSLFdBQVcsR0FBR0M7UUFDbkIsSUFBSSxDQUFDQyxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUNPLGNBQWMsQ0FBQ0Q7UUFDN0MsSUFBSSxDQUFDRSxvQkFBb0I7UUFDekIsSUFBSSxDQUFDQyx3QkFBd0I7UUFDN0IsTUFBTSxJQUFJLENBQUNDLEtBQUssQ0FBQ0o7UUFDakIsSUFBSSxDQUFDVixNQUFNLENBQUNlLEtBQUss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