source: trip-planner-front/node_modules/@angular/compiler/esm2015/src/jit/compiler.js@ 1ad8e64

Last change on this file since 1ad8e64 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 52.4 KB
Line 
1/**
2 * @license
3 * Copyright Google LLC All Rights Reserved.
4 *
5 * Use of this source code is governed by an MIT-style license that can be
6 * found in the LICENSE file at https://angular.io/license
7 */
8import { ngModuleJitUrl, sharedStylesheetJitUrl, templateJitUrl, templateSourceUrl } from '../compile_metadata';
9import { ConstantPool } from '../constant_pool';
10import * as ir from '../output/output_ast';
11import { interpretStatements } from '../output/output_interpreter';
12import { identifierName } from '../parse_util';
13import { stringify, SyncAsync } from '../util';
14/**
15 * An internal module of the Angular compiler that begins with component types,
16 * extracts templates, and eventually produces a compiled version of the component
17 * ready for linking into an application.
18 *
19 * @security When compiling templates at runtime, you must ensure that the entire template comes
20 * from a trusted source. Attacker-controlled data introduced by a template could expose your
21 * application to XSS risks. For more detail, see the [Security Guide](https://g.co/ng/security).
22 */
23export class JitCompiler {
24 constructor(_metadataResolver, _templateParser, _styleCompiler, _viewCompiler, _ngModuleCompiler, _summaryResolver, _reflector, _jitEvaluator, _compilerConfig, _console, getExtraNgModuleProviders) {
25 this._metadataResolver = _metadataResolver;
26 this._templateParser = _templateParser;
27 this._styleCompiler = _styleCompiler;
28 this._viewCompiler = _viewCompiler;
29 this._ngModuleCompiler = _ngModuleCompiler;
30 this._summaryResolver = _summaryResolver;
31 this._reflector = _reflector;
32 this._jitEvaluator = _jitEvaluator;
33 this._compilerConfig = _compilerConfig;
34 this._console = _console;
35 this.getExtraNgModuleProviders = getExtraNgModuleProviders;
36 this._compiledTemplateCache = new Map();
37 this._compiledHostTemplateCache = new Map();
38 this._compiledDirectiveWrapperCache = new Map();
39 this._compiledNgModuleCache = new Map();
40 this._sharedStylesheetCount = 0;
41 this._addedAotSummaries = new Set();
42 }
43 compileModuleSync(moduleType) {
44 return SyncAsync.assertSync(this._compileModuleAndComponents(moduleType, true));
45 }
46 compileModuleAsync(moduleType) {
47 return Promise.resolve(this._compileModuleAndComponents(moduleType, false));
48 }
49 compileModuleAndAllComponentsSync(moduleType) {
50 return SyncAsync.assertSync(this._compileModuleAndAllComponents(moduleType, true));
51 }
52 compileModuleAndAllComponentsAsync(moduleType) {
53 return Promise.resolve(this._compileModuleAndAllComponents(moduleType, false));
54 }
55 getComponentFactory(component) {
56 const summary = this._metadataResolver.getDirectiveSummary(component);
57 return summary.componentFactory;
58 }
59 loadAotSummaries(summaries) {
60 this.clearCache();
61 this._addAotSummaries(summaries);
62 }
63 _addAotSummaries(fn) {
64 if (this._addedAotSummaries.has(fn)) {
65 return;
66 }
67 this._addedAotSummaries.add(fn);
68 const summaries = fn();
69 for (let i = 0; i < summaries.length; i++) {
70 const entry = summaries[i];
71 if (typeof entry === 'function') {
72 this._addAotSummaries(entry);
73 }
74 else {
75 const summary = entry;
76 this._summaryResolver.addSummary({ symbol: summary.type.reference, metadata: null, type: summary });
77 }
78 }
79 }
80 hasAotSummary(ref) {
81 return !!this._summaryResolver.resolveSummary(ref);
82 }
83 _filterJitIdentifiers(ids) {
84 return ids.map(mod => mod.reference).filter((ref) => !this.hasAotSummary(ref));
85 }
86 _compileModuleAndComponents(moduleType, isSync) {
87 return SyncAsync.then(this._loadModules(moduleType, isSync), () => {
88 this._compileComponents(moduleType, null);
89 return this._compileModule(moduleType);
90 });
91 }
92 _compileModuleAndAllComponents(moduleType, isSync) {
93 return SyncAsync.then(this._loadModules(moduleType, isSync), () => {
94 const componentFactories = [];
95 this._compileComponents(moduleType, componentFactories);
96 return {
97 ngModuleFactory: this._compileModule(moduleType),
98 componentFactories: componentFactories
99 };
100 });
101 }
102 _loadModules(mainModule, isSync) {
103 const loading = [];
104 const mainNgModule = this._metadataResolver.getNgModuleMetadata(mainModule);
105 // Note: for runtime compilation, we want to transitively compile all modules,
106 // so we also need to load the declared directives / pipes for all nested modules.
107 this._filterJitIdentifiers(mainNgModule.transitiveModule.modules).forEach((nestedNgModule) => {
108 // getNgModuleMetadata only returns null if the value passed in is not an NgModule
109 const moduleMeta = this._metadataResolver.getNgModuleMetadata(nestedNgModule);
110 this._filterJitIdentifiers(moduleMeta.declaredDirectives).forEach((ref) => {
111 const promise = this._metadataResolver.loadDirectiveMetadata(moduleMeta.type.reference, ref, isSync);
112 if (promise) {
113 loading.push(promise);
114 }
115 });
116 this._filterJitIdentifiers(moduleMeta.declaredPipes)
117 .forEach((ref) => this._metadataResolver.getOrLoadPipeMetadata(ref));
118 });
119 return SyncAsync.all(loading);
120 }
121 _compileModule(moduleType) {
122 let ngModuleFactory = this._compiledNgModuleCache.get(moduleType);
123 if (!ngModuleFactory) {
124 const moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType);
125 // Always provide a bound Compiler
126 const extraProviders = this.getExtraNgModuleProviders(moduleMeta.type.reference);
127 const outputCtx = createOutputContext();
128 const compileResult = this._ngModuleCompiler.compile(outputCtx, moduleMeta, extraProviders);
129 ngModuleFactory = this._interpretOrJit(ngModuleJitUrl(moduleMeta), outputCtx.statements)[compileResult.ngModuleFactoryVar];
130 this._compiledNgModuleCache.set(moduleMeta.type.reference, ngModuleFactory);
131 }
132 return ngModuleFactory;
133 }
134 /**
135 * @internal
136 */
137 _compileComponents(mainModule, allComponentFactories) {
138 const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule);
139 const moduleByJitDirective = new Map();
140 const templates = new Set();
141 const transJitModules = this._filterJitIdentifiers(ngModule.transitiveModule.modules);
142 transJitModules.forEach((localMod) => {
143 const localModuleMeta = this._metadataResolver.getNgModuleMetadata(localMod);
144 this._filterJitIdentifiers(localModuleMeta.declaredDirectives).forEach((dirRef) => {
145 moduleByJitDirective.set(dirRef, localModuleMeta);
146 const dirMeta = this._metadataResolver.getDirectiveMetadata(dirRef);
147 if (dirMeta.isComponent) {
148 templates.add(this._createCompiledTemplate(dirMeta, localModuleMeta));
149 if (allComponentFactories) {
150 const template = this._createCompiledHostTemplate(dirMeta.type.reference, localModuleMeta);
151 templates.add(template);
152 allComponentFactories.push(dirMeta.componentFactory);
153 }
154 }
155 });
156 });
157 transJitModules.forEach((localMod) => {
158 const localModuleMeta = this._metadataResolver.getNgModuleMetadata(localMod);
159 this._filterJitIdentifiers(localModuleMeta.declaredDirectives).forEach((dirRef) => {
160 const dirMeta = this._metadataResolver.getDirectiveMetadata(dirRef);
161 if (dirMeta.isComponent) {
162 dirMeta.entryComponents.forEach((entryComponentType) => {
163 const moduleMeta = moduleByJitDirective.get(entryComponentType.componentType);
164 templates.add(this._createCompiledHostTemplate(entryComponentType.componentType, moduleMeta));
165 });
166 }
167 });
168 localModuleMeta.entryComponents.forEach((entryComponentType) => {
169 if (!this.hasAotSummary(entryComponentType.componentType)) {
170 const moduleMeta = moduleByJitDirective.get(entryComponentType.componentType);
171 templates.add(this._createCompiledHostTemplate(entryComponentType.componentType, moduleMeta));
172 }
173 });
174 });
175 templates.forEach((template) => this._compileTemplate(template));
176 }
177 clearCacheFor(type) {
178 this._compiledNgModuleCache.delete(type);
179 this._metadataResolver.clearCacheFor(type);
180 this._compiledHostTemplateCache.delete(type);
181 const compiledTemplate = this._compiledTemplateCache.get(type);
182 if (compiledTemplate) {
183 this._compiledTemplateCache.delete(type);
184 }
185 }
186 clearCache() {
187 // Note: don't clear the _addedAotSummaries, as they don't change!
188 this._metadataResolver.clearCache();
189 this._compiledTemplateCache.clear();
190 this._compiledHostTemplateCache.clear();
191 this._compiledNgModuleCache.clear();
192 }
193 _createCompiledHostTemplate(compType, ngModule) {
194 if (!ngModule) {
195 throw new Error(`Component ${stringify(compType)} is not part of any NgModule or the module has not been imported into your module.`);
196 }
197 let compiledTemplate = this._compiledHostTemplateCache.get(compType);
198 if (!compiledTemplate) {
199 const compMeta = this._metadataResolver.getDirectiveMetadata(compType);
200 assertComponent(compMeta);
201 const hostMeta = this._metadataResolver.getHostComponentMetadata(compMeta, compMeta.componentFactory.viewDefFactory);
202 compiledTemplate =
203 new CompiledTemplate(true, compMeta.type, hostMeta, ngModule, [compMeta.type]);
204 this._compiledHostTemplateCache.set(compType, compiledTemplate);
205 }
206 return compiledTemplate;
207 }
208 _createCompiledTemplate(compMeta, ngModule) {
209 let compiledTemplate = this._compiledTemplateCache.get(compMeta.type.reference);
210 if (!compiledTemplate) {
211 assertComponent(compMeta);
212 compiledTemplate = new CompiledTemplate(false, compMeta.type, compMeta, ngModule, ngModule.transitiveModule.directives);
213 this._compiledTemplateCache.set(compMeta.type.reference, compiledTemplate);
214 }
215 return compiledTemplate;
216 }
217 _compileTemplate(template) {
218 if (template.isCompiled) {
219 return;
220 }
221 const compMeta = template.compMeta;
222 const externalStylesheetsByModuleUrl = new Map();
223 const outputContext = createOutputContext();
224 const componentStylesheet = this._styleCompiler.compileComponent(outputContext, compMeta);
225 compMeta.template.externalStylesheets.forEach((stylesheetMeta) => {
226 const compiledStylesheet = this._styleCompiler.compileStyles(createOutputContext(), compMeta, stylesheetMeta);
227 externalStylesheetsByModuleUrl.set(stylesheetMeta.moduleUrl, compiledStylesheet);
228 });
229 this._resolveStylesCompileResult(componentStylesheet, externalStylesheetsByModuleUrl);
230 const pipes = template.ngModule.transitiveModule.pipes.map(pipe => this._metadataResolver.getPipeSummary(pipe.reference));
231 const { template: parsedTemplate, pipes: usedPipes } = this._parseTemplate(compMeta, template.ngModule, template.directives);
232 const compileResult = this._viewCompiler.compileComponent(outputContext, compMeta, parsedTemplate, ir.variable(componentStylesheet.stylesVar), usedPipes);
233 const evalResult = this._interpretOrJit(templateJitUrl(template.ngModule.type, template.compMeta), outputContext.statements);
234 const viewClass = evalResult[compileResult.viewClassVar];
235 const rendererType = evalResult[compileResult.rendererTypeVar];
236 template.compiled(viewClass, rendererType);
237 }
238 _parseTemplate(compMeta, ngModule, directiveIdentifiers) {
239 // Note: ! is ok here as components always have a template.
240 const preserveWhitespaces = compMeta.template.preserveWhitespaces;
241 const directives = directiveIdentifiers.map(dir => this._metadataResolver.getDirectiveSummary(dir.reference));
242 const pipes = ngModule.transitiveModule.pipes.map(pipe => this._metadataResolver.getPipeSummary(pipe.reference));
243 return this._templateParser.parse(compMeta, compMeta.template.htmlAst, directives, pipes, ngModule.schemas, templateSourceUrl(ngModule.type, compMeta, compMeta.template), preserveWhitespaces);
244 }
245 _resolveStylesCompileResult(result, externalStylesheetsByModuleUrl) {
246 result.dependencies.forEach((dep, i) => {
247 const nestedCompileResult = externalStylesheetsByModuleUrl.get(dep.moduleUrl);
248 const nestedStylesArr = this._resolveAndEvalStylesCompileResult(nestedCompileResult, externalStylesheetsByModuleUrl);
249 dep.setValue(nestedStylesArr);
250 });
251 }
252 _resolveAndEvalStylesCompileResult(result, externalStylesheetsByModuleUrl) {
253 this._resolveStylesCompileResult(result, externalStylesheetsByModuleUrl);
254 return this._interpretOrJit(sharedStylesheetJitUrl(result.meta, this._sharedStylesheetCount++), result.outputCtx.statements)[result.stylesVar];
255 }
256 _interpretOrJit(sourceUrl, statements) {
257 if (!this._compilerConfig.useJit) {
258 return interpretStatements(statements, this._reflector);
259 }
260 else {
261 return this._jitEvaluator.evaluateStatements(sourceUrl, statements, this._reflector, this._compilerConfig.jitDevMode);
262 }
263 }
264}
265class CompiledTemplate {
266 constructor(isHost, compType, compMeta, ngModule, directives) {
267 this.isHost = isHost;
268 this.compType = compType;
269 this.compMeta = compMeta;
270 this.ngModule = ngModule;
271 this.directives = directives;
272 this._viewClass = null;
273 this.isCompiled = false;
274 }
275 compiled(viewClass, rendererType) {
276 this._viewClass = viewClass;
277 this.compMeta.componentViewType.setDelegate(viewClass);
278 for (let prop in rendererType) {
279 this.compMeta.rendererType[prop] = rendererType[prop];
280 }
281 this.isCompiled = true;
282 }
283}
284function assertComponent(meta) {
285 if (!meta.isComponent) {
286 throw new Error(`Could not compile '${identifierName(meta.type)}' because it is not a component.`);
287 }
288}
289function createOutputContext() {
290 const importExpr = (symbol) => ir.importExpr({ name: identifierName(symbol), moduleName: null, runtime: symbol });
291 return { statements: [], genFilePath: '', importExpr, constantPool: new ConstantPool() };
292}
293//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21waWxlci9zcmMvaml0L2NvbXBpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBcUgsY0FBYyxFQUFjLHNCQUFzQixFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRzlPLE9BQU8sRUFBQyxZQUFZLEVBQWdCLE1BQU0sa0JBQWtCLENBQUM7QUFJN0QsT0FBTyxLQUFLLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMzQyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUVqRSxPQUFPLEVBQTRCLGNBQWMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUt4RSxPQUFPLEVBQVUsU0FBUyxFQUFFLFNBQVMsRUFBQyxNQUFNLFNBQVMsQ0FBQztBQVF0RDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sT0FBTyxXQUFXO0lBUXRCLFlBQ1ksaUJBQTBDLEVBQVUsZUFBK0IsRUFDbkYsY0FBNkIsRUFBVSxhQUEyQixFQUNsRSxpQkFBbUMsRUFBVSxnQkFBdUMsRUFDcEYsVUFBNEIsRUFBVSxhQUEyQixFQUNqRSxlQUErQixFQUFVLFFBQWlCLEVBQzFELHlCQUF1RTtRQUx2RSxzQkFBaUIsR0FBakIsaUJBQWlCLENBQXlCO1FBQVUsb0JBQWUsR0FBZixlQUFlLENBQWdCO1FBQ25GLG1CQUFjLEdBQWQsY0FBYyxDQUFlO1FBQVUsa0JBQWEsR0FBYixhQUFhLENBQWM7UUFDbEUsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFrQjtRQUFVLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBdUI7UUFDcEYsZUFBVSxHQUFWLFVBQVUsQ0FBa0I7UUFBVSxrQkFBYSxHQUFiLGFBQWEsQ0FBYztRQUNqRSxvQkFBZSxHQUFmLGVBQWUsQ0FBZ0I7UUFBVSxhQUFRLEdB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QUFRLENBQUMsWUFBYSxDQUFDLElBQUksQ0FBQyxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUM5RDtRQUNELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO0lBQ3pCLENBQUM7Q0FDRjtBQUVELFNBQVMsZUFBZSxDQUFDLElBQThCO0lBQ3JELElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1FBQ3JCLE1BQU0sSUFBSSxLQUFLLENBQ1gsc0JBQXNCLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7S0FDeEY7QUFDSCxDQUFDO0FBRUQsU0FBUyxtQkFBbUI7SUFDMUIsTUFBTSxVQUFVLEdBQUcsQ0FBQyxNQUFXLEVBQUUsRUFBRSxDQUMvQixFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxNQUFNLENBQUMsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUMsQ0FBQyxDQUFDO0lBQ3JGLE9BQU8sRUFBQyxVQUFVLEVBQUUsRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxJQUFJLFlBQVksRUFBRSxFQUFDLENBQUM7QUFDekYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0NvbXBpbGVEaXJlY3RpdmVNZXRhZGF0YSwgQ29tcGlsZU5nTW9kdWxlTWV0YWRhdGEsIENvbXBpbGVQaXBlU3VtbWFyeSwgQ29tcGlsZVByb3ZpZGVyTWV0YWRhdGEsIENvbXBpbGVUeXBlU3VtbWFyeSwgbmdNb2R1bGVKaXRVcmwsIFByb3h5Q2xhc3MsIHNoYXJlZFN0eWxlc2hlZXRKaXRVcmwsIHRlbXBsYXRlSml0VXJsLCB0ZW1wbGF0ZVNvdXJjZVVybH0gZnJvbSAnLi4vY29tcGlsZV9tZXRhZGF0YSc7XG5pbXBvcnQge0NvbXBpbGVSZWZsZWN0b3J9IGZyb20gJy4uL2NvbXBpbGVfcmVmbGVjdG9yJztcbmltcG9ydCB7Q29tcGlsZXJDb25maWd9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQge0NvbnN0YW50UG9vbCwgT3V0cHV0Q29udGV4dH0gZnJvbSAnLi4vY29uc3RhbnRfcG9vbCc7XG5pbXBvcnQge1R5cGV9IGZyb20gJy4uL2NvcmUnO1xuaW1wb3J0IHtDb21waWxlTWV0YWRhdGFSZXNvbHZlcn0gZnJvbSAnLi4vbWV0YWRhdGFfcmVzb2x2ZXInO1xuaW1wb3J0IHtOZ01vZHVsZUNvbXBpbGVyfSBmcm9tICcuLi9uZ19tb2R1bGVfY29tcGlsZXInO1xuaW1wb3J0ICogYXMgaXIgZnJvbSAnLi4vb3V0cHV0L291dHB1dF9hc3QnO1xuaW1wb3J0IHtpbnRlcnByZXRTdGF0ZW1lbnRzfSBmcm9tICcuLi9vdXRwdXQvb3V0cHV0X2ludGVycHJldGVyJztcbmltcG9ydCB7Sml0RXZhbHVhdG9yfSBmcm9tICcuLi9vdXRwdXQvb3V0cHV0X2ppdCc7XG5pbXBvcnQge0NvbXBpbGVJZGVudGlmaWVyTWV0YWRhdGEsIGlkZW50aWZpZXJOYW1lfSBmcm9tICcuLi9wYXJzZV91dGlsJztcbmltcG9ydCB7Q29tcGlsZWRTdHlsZXNoZWV0LCBTdHlsZUNvbXBpbGVyfSBmcm9tICcuLi9zdHlsZV9jb21waWxlcic7XG5pbXBvcnQge1N1bW1hcnlSZXNvbHZlcn0gZnJvbSAnLi4vc3VtbWFyeV9yZXNvbHZlcic7XG5pbXBvcnQge1RlbXBsYXRlQXN0fSBmcm9tICcuLi90ZW1wbGF0ZV9wYXJzZXIvdGVtcGxhdGVfYXN0JztcbmltcG9ydCB7VGVtcGxhdGVQYXJzZXJ9IGZyb20gJy4uL3RlbXBsYXRlX3BhcnNlci90ZW1wbGF0ZV9wYXJzZXInO1xuaW1wb3J0IHtDb25zb2xlLCBzdHJpbmdpZnksIFN5bmNBc3luY30gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQge1ZpZXdDb21waWxlcn0gZnJvbSAnLi4vdmlld19jb21waWxlci92aWV3X2NvbXBpbGVyJztcblxuZXhwb3J0IGludGVyZmFjZSBNb2R1bGVXaXRoQ29tcG9uZW50RmFjdG9yaWVzIHtcbiAgbmdNb2R1bGVGYWN0b3J5OiBvYmplY3Q7XG4gIGNvbXBvbmVudEZhY3Rvcmllczogb2JqZWN0W107XG59XG5cbi8qKlxuICogQW4gaW50ZXJuYWwgbW9kdWxlIG9mIHRoZSBBbmd1bGFyIGNvbXBpbGVyIHRoYXQgYmVnaW5zIHdpdGggY29tcG9uZW50IHR5cGVzLFxuICogZXh0cmFjdHMgdGVtcGxhdGVzLCBhbmQgZXZlbnR1YWxseSBwcm9kdWNlcyBhIGNvbXBpbGVkIHZlcnNpb24gb2YgdGhlIGNvbXBvbmVudFxuICogcmVhZHkgZm9yIGxpbmtpbmcgaW50byBhbiBhcHBsaWNhdGlvbi5cbiAqXG4gKiBAc2VjdXJpdHkgIFdoZW4gY29tcGlsaW5nIHRlbXBsYXRlcyBhdCBydW50aW1lLCB5b3UgbXVzdCBlbnN1cmUgdGhhdCB0aGUgZW50aXJlIHRlbXBsYXRlIGNvbWVzXG4gKiBmcm9tIGEgdHJ1c3RlZCBzb3VyY2UuIEF0dGFja2VyLWNvbnRyb2xsZWQgZGF0YSBpbnRyb2R1Y2VkIGJ5IGEgdGVtcGxhdGUgY291bGQgZXhwb3NlIHlvdXJcbiAqIGFwcGxpY2F0aW9uIHRvIFhTUyByaXNrcy4gIEZvciBtb3JlIGRldGFpbCwgc2VlIHRoZSBbU2VjdXJpdHkgR3VpZGVdKGh0dHBzOi8vZy5jby9uZy9zZWN1cml0eSkuXG4gKi9cbmV4cG9ydCBjbGFzcyBKaXRDb21waWxlciB7XG4gIHByaXZhdGUgX2NvbXBpbGVkVGVtcGxhdGVDYWNoZSA9IG5ldyBNYXA8VHlwZSwgQ29tcGlsZWRUZW1wbGF0ZT4oKTtcbiAgcHJpdmF0ZSBfY29tcGlsZWRIb3N0VGVtcGxhdGVDYWNoZSA9IG5ldyBNYXA8VHlwZSwgQ29tcGlsZWRUZW1wbGF0ZT4oKTtcbiAgcHJpdmF0ZSBfY29tcGlsZWREaXJlY3RpdmVXcmFwcGVyQ2FjaGUgPSBuZXcgTWFwPFR5cGUsIFR5cGU+KCk7XG4gIHByaXZhdGUgX2NvbXBpbGVkTmdNb2R1bGVDYWNoZSA9IG5ldyBNYXA8VHlwZSwgb2JqZWN0PigpO1xuICBwcml2YXRlIF9zaGFyZWRTdHlsZXNoZWV0Q291bnQgPSAwO1xuICBwcml2YXRlIF9hZGRlZEFvdFN1bW1hcmllcyA9IG5ldyBTZXQ8KCkgPT4gYW55W10+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIF9tZXRhZGF0YVJlc29sdmVyOiBDb21waWxlTWV0YWRhdGFSZXNvbHZlciwgcHJpdmF0ZSBfdGVtcGxhdGVQYXJzZXI6IFRlbXBsYXRlUGFyc2VyLFxuICAgICAgcHJpdmF0ZSBfc3R5bGVDb21waWxlcjogU3R5bGVDb21waWxlciwgcHJpdmF0ZSBfdmlld0NvbXBpbGVyOiBWaWV3Q29tcGlsZXIsXG4gICAgICBwcml2YXRlIF9uZ01vZHVsZUNvbXBpbGVyOiBOZ01vZHVsZUNvbXBpbGVyLCBwcml2YXRlIF9zdW1tYXJ5UmVzb2x2ZXI6IFN1bW1hcnlSZXNvbHZlcjxUeXBlPixcbiAgICAgIHByaXZhdGUgX3JlZmxlY3RvcjogQ29tcGlsZVJlZmxlY3RvciwgcHJpdmF0ZSBfaml0RXZhbHVhdG9yOiBKaXRFdmFsdWF0b3IsXG4gICAgICBwcml2YXRlIF9jb21waWxlckNvbmZpZzogQ29tcGlsZXJDb25maWcsIHByaXZhdGUgX2NvbnNvbGU6IENvbnNvbGUsXG4gICAgICBwcml2YXRlIGdldEV4dHJhTmdNb2R1bGVQcm92aWRlcnM6IChuZ01vZHVsZTogYW55KSA9PiBDb21waWxlUHJvdmlkZXJNZXRhZGF0YVtdKSB7fVxuXG4gIGNvbXBpbGVNb2R1bGVTeW5jKG1vZHVsZVR5cGU6IFR5cGUpOiBvYmplY3Qge1xuICAgIHJldHVybiBTeW5jQXN5bmMuYXNzZXJ0U3luYyh0aGlzLl9jb21waWxlTW9kdWxlQW5kQ29tcG9uZW50cyhtb2R1bGVUeXBlLCB0cnVlKSk7XG4gIH1cblxuICBjb21waWxlTW9kdWxlQXN5bmMobW9kdWxlVHlwZTogVHlwZSk6IFByb21pc2U8b2JqZWN0PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLl9jb21waWxlTW9kdWxlQW5kQ29tcG9uZW50cyhtb2R1bGVUeXBlLCBmYWxzZSkpO1xuICB9XG5cbiAgY29tcGlsZU1vZHVsZUFuZEFsbENvbXBvbmVudHNTeW5jKG1vZHVsZVR5cGU6IFR5cGUpOiBNb2R1bGVXaXRoQ29tcG9uZW50RmFjdG9yaWVzIHtcbiAgICByZXR1cm4gU3luY0FzeW5jLmFzc2VydFN5bmModGhpcy5fY29tcGlsZU1vZHVsZUFuZEFsbENvbXBvbmVudHMobW9kdWxlVHlwZSwgdHJ1ZSkpO1xuICB9XG5cbiAgY29tcGlsZU1vZHVsZUFuZEFsbENvbXBvbmVudHNBc3luYyhtb2R1bGVUeXBlOiBUeXBlKTogUHJvbWlzZTxNb2R1bGVXaXRoQ29tcG9uZW50RmFjdG9yaWVzPiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLl9jb21waWxlTW9kdWxlQW5kQWxsQ29tcG9uZW50cyhtb2R1bGVUeXBlLCBmYWxzZSkpO1xuICB9XG5cbiAgZ2V0Q29tcG9uZW50RmFjdG9yeShjb21wb25lbnQ6IFR5cGUpOiBvYmplY3Qge1xuICAgIGNvbnN0IHN1bW1hcnkgPSB0aGlzLl9tZXRhZGF0YVJlc29sdmVyLmdldERpcmVjdGl2ZVN1bW1hcnkoY29tcG9uZW50KTtcbiAgICByZXR1cm4gc3VtbWFyeS5jb21wb25lbnRGYWN0b3J5IGFzIG9iamVjdDtcbiAgfVxuXG4gIGxvYWRBb3RTdW1tYXJpZXMoc3VtbWFyaWVzOiAoKSA9PiBhbnlbXSkge1xuICAgIHRoaXMuY2xlYXJDYWNoZSgpO1xuICAgIHRoaXMuX2FkZEFvdFN1bW1hcmllcyhzdW1tYXJpZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBfYWRkQW90U3VtbWFyaWVzKGZuOiAoKSA9PiBhbnlbXSkge1xuICAgIGlmICh0aGlzLl9hZGRlZEFvdFN1bW1hcmllcy5oYXMoZm4pKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2FkZGVkQW90U3VtbWFyaWVzLmFkZChmbik7XG4gICAgY29uc3Qgc3VtbWFyaWVzID0gZm4oKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN1bW1hcmllcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZW50cnkgPSBzdW1tYXJpZXNbaV07XG4gICAgICBpZiAodHlwZW9mIGVudHJ5ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRoaXMuX2FkZEFvdFN1bW1hcmllcyhlbnRyeSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzdW1tYXJ5ID0gZW50cnkgYXMgQ29tcGlsZVR5cGVTdW1tYXJ5O1xuICAgICAgICB0aGlzLl9zdW1tYXJ5UmVzb2x2ZXIuYWRkU3VtbWFyeShcbiAgICAgICAgICAgIHtzeW1ib2w6IHN1bW1hcnkudHlwZS5yZWZlcmVuY2UsIG1ldGFkYXRhOiBudWxsLCB0eXBlOiBzdW1tYXJ5fSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFzQW90U3VtbWFyeShyZWY6IFR5cGUpIHtcbiAgICByZXR1cm4gISF0aGlzLl9zdW1tYXJ5UmVzb2x2ZXIucmVzb2x2ZVN1bW1hcnkocmVmKTtcbiAgfVxuXG4gIHByaXZhdGUgX2ZpbHRlckppdElkZW50aWZpZXJzKGlkczogQ29tcGlsZUlkZW50aWZpZXJNZXRhZGF0YVtdKTogYW55W10ge1xuICAgIHJldHVybiBpZHMubWFwKG1vZCA9PiBtb2QucmVmZXJlbmNlKS5maWx0ZXIoKHJlZikgPT4gIXRoaXMuaGFzQW90U3VtbWFyeShyZWYpKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbXBpbGVNb2R1bGVBbmRDb21wb25lbnRzKG1vZHVsZVR5cGU6IFR5cGUsIGlzU3luYzogYm9vbGVhbik6IFN5bmNBc3luYzxvYmplY3Q+IHtcbiAgICByZXR1cm4gU3luY0FzeW5jLnRoZW4odGhpcy5fbG9hZE1vZHVsZXMobW9kdWxlVHlwZSwgaXNTeW5jKSwgKCkgPT4ge1xuICAgICAgdGhpcy5fY29tcGlsZUNvbXBvbmVudHMobW9kdWxlVHlwZSwgbnVsbCk7XG4gICAgICByZXR1cm4gdGhpcy5fY29tcGlsZU1vZHVsZShtb2R1bGVUeXBlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbXBpbGVNb2R1bGVBbmRBbGxDb21wb25lbnRzKG1vZHVsZVR5cGU6IFR5cGUsIGlzU3luYzogYm9vbGVhbik6XG4gICAgICBTeW5jQXN5bmM8TW9kdWxlV2l0aENvbXBvbmVudEZhY3Rvcmllcz4ge1xuICAgIHJldHVybiBTeW5jQXN5bmMudGhlbih0aGlzLl9sb2FkTW9kdWxlcyhtb2R1bGVUeXBlLCBpc1N5bmMpLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb21wb25lbnRGYWN0b3JpZXM6IG9iamVjdFtdID0gW107XG4gICAgICB0aGlzLl9jb21waWxlQ29tcG9uZW50cyhtb2R1bGVUeXBlLCBjb21wb25lbnRGYWN0b3JpZXMpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmdNb2R1bGVGYWN0b3J5OiB0aGlzLl9jb21waWxlTW9kdWxlKG1vZHVsZVR5cGUpLFxuICAgICAgICBjb21wb25lbnRGYWN0b3JpZXM6IGNvbXBvbmVudEZhY3Rvcmllc1xuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2xvYWRNb2R1bGVzKG1haW5Nb2R1bGU6IGFueSwgaXNTeW5jOiBib29sZWFuKTogU3luY0FzeW5jPGFueT4ge1xuICAgIGNvbnN0IGxvYWRpbmc6IFByb21pc2U8YW55PltdID0gW107XG4gICAgY29uc3QgbWFpbk5nTW9kdWxlID0gdGhpcy5fbWV0YWRhdGFSZXNvbHZlci5nZXROZ01vZHVsZU1ldGFkYXRhKG1haW5Nb2R1bGUpITtcbiAgICAvLyBOb3RlOiBmb3IgcnVudGltZSBjb21waWxhdGlvbiwgd2Ugd2FudCB0byB0cmFuc2l0aXZlbHkgY29tcGlsZSBhbGwgbW9kdWxlcyxcbiAgICAvLyBzbyB3ZSBhbHNvIG5lZWQgdG8gbG9hZCB0aGUgZGVjbGFyZWQgZGlyZWN0aXZlcyAvIHBpcGVzIGZvciBhbGwgbmVzdGVkIG1vZHVsZXMuXG4gICAgdGhpcy5fZmlsdGVySml0SWRlbnRpZmllcnMobWFpbk5nTW9kdWxlLnRyYW5zaXRpdmVNb2R1bGUubW9kdWxlcykuZm9yRWFjaCgobmVzdGVkTmdNb2R1bGUpID0+IHtcbiAgICAgIC8vIGdldE5nTW9kdWxlTWV0YWRhdGEgb25seSByZXR1cm5zIG51bGwgaWYgdGhlIHZhbHVlIHBhc3NlZCBpbiBpcyBub3QgYW4gTmdNb2R1bGVcbiAgICAgIGNvbnN0IG1vZHVsZU1ldGEgPSB0aGlzLl9tZXRhZGF0YVJlc29sdmVyLmdldE5nTW9kdWxlTWV0YWRhdGEobmVzdGVkTmdNb2R1bGUpITtcbiAgICAgIHRoaXMuX2ZpbHRlckppdElkZW50aWZpZXJzKG1vZHVsZU1ldGEuZGVjbGFyZWREaXJlY3RpdmVzKS5mb3JFYWNoKChyZWYpID0+IHtcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9XG4gICAgICAgICAgICB0aGlzLl9tZXRhZGF0YVJlc29sdmVyLmxvYWREaXJlY3RpdmVNZXRhZGF0YShtb2R1bGVNZXRhLnR5cGUucmVmZXJlbmNlLCByZWYsIGlzU3luYyk7XG4gICAgICAgIGlmIChwcm9taXNlKSB7XG4gICAgICAgICAgbG9hZGluZy5wdXNoKHByb21pc2UpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuX2ZpbHRlckppdElkZW50aWZpZXJzKG1vZHVsZU1ldGEuZGVjbGFyZWRQaXBlcylcbiAgICAgICAgICAuZm9yRWFjaCgocmVmKSA9PiB0aGlzLl9tZXRhZGF0YVJlc29sdmVyLmdldE9yTG9hZFBpcGVNZXRhZGF0YShyZWYpKTtcbiAgICB9KTtcbiAgICByZXR1cm4gU3luY0FzeW5jLmFsbChsb2FkaW5nKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbXBpbGVNb2R1bGUobW9kdWxlVHlwZTogVHlwZSk6IG9iamVjdCB7XG4gICAgbGV0IG5nTW9kdWxlRmFjdG9yeSA9IHRoaXMuX2NvbXBpbGVkTmdNb2R1bGVDYWNoZS5nZXQobW9kdWxlVHlwZSkhO1xuICAgIGlmICghbmdNb2R1bGVGYWN0b3J5KSB7XG4gICAgICBjb25zdCBtb2R1bGVNZXRhID0gdGhpcy5fbWV0YWRhdGFSZXNvbHZlci5nZXROZ01vZHVsZU1ldGFkYXRhKG1vZHVsZVR5cGUpITtcbiAgICAgIC8vIEFsd2F5cyBwcm92aWRlIGEgYm91bmQgQ29tcGlsZXJcbiAgICAgIGNvbnN0IGV4dHJhUHJvdmlkZXJzID0gdGhpcy5nZXRFeHRyYU5nTW9kdWxlUHJvdmlkZXJzKG1vZHVsZU1ldGEudHlwZS5yZWZlcmVuY2UpO1xuICAgICAgY29uc3Qgb3V0cHV0Q3R4ID0gY3JlYXRlT3V0cHV0Q29udGV4dCgpO1xuICAgICAgY29uc3QgY29tcGlsZVJlc3VsdCA9IHRoaXMuX25nTW9kdWxlQ29tcGlsZXIuY29tcGlsZShvdXRwdXRDdHgsIG1vZHVsZU1ldGEsIGV4dHJhUHJvdmlkZXJzKTtcbiAgICAgIG5nTW9kdWxlRmFjdG9yeSA9IHRoaXMuX2ludGVycHJldE9ySml0KFxuICAgICAgICAgIG5nTW9kdWxlSml0VXJsKG1vZHVsZU1ldGEpLCBvdXRwdXRDdHguc3RhdGVtZW50cylbY29tcGlsZVJlc3VsdC5uZ01vZHVsZUZhY3RvcnlWYXJdO1xuICAgICAgdGhpcy5fY29tcGlsZWROZ01vZHVsZUNhY2hlLnNldChtb2R1bGVNZXRhLnR5cGUucmVmZXJlbmNlLCBuZ01vZHVsZUZhY3RvcnkpO1xuICAgIH1cbiAgICByZXR1cm4gbmdNb2R1bGVGYWN0b3J5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgX2NvbXBpbGVDb21wb25lbnRzKG1haW5Nb2R1bGU6IFR5cGUsIGFsbENvbXBvbmVudEZhY3Rvcmllczogb2JqZWN0W118bnVsbCkge1xuICAgIGNvbnN0IG5nTW9kdWxlID0gdGhpcy5fbWV0YWRhdGFSZXNvbHZlci5nZXROZ01vZHVsZU1ldGFkYXRhKG1haW5Nb2R1bGUpITtcbiAgICBjb25zdCBtb2R1bGVCeUppdERpcmVjdGl2ZSA9IG5ldyBNYXA8YW55LCBDb21waWxlTmdNb2R1bGVNZXRhZGF0YT4oKTtcbiAgICBjb25zdCB0ZW1wbGF0ZXMgPSBuZXcgU2V0PENvbXBpbGVkVGVtcGxhdGU+KCk7XG5cbiAgICBjb25zdCB0cmFuc0ppdE1vZHVsZXMgPSB0aGlzLl9maWx0ZXJKaXRJZGVudGlmaWVycyhuZ01vZHVsZS50cmFuc2l0aXZlTW9kdWxlLm1vZHVsZXMpO1xuICAgIHRyYW5zSml0TW9kdWxlcy5mb3JFYWNoKChsb2NhbE1vZCkgPT4ge1xuICAgICAgY29uc3QgbG9jYWxNb2R1bGVNZXRhID0gdGhpcy5fbWV0YWRhdGFSZXNvbHZlci5nZXROZ01vZHVsZU1ldGFkYXRhKGxvY2FsTW9kKSE7XG4gICAgICB0aGlzLl9maWx0ZXJKaXRJZGVudGlmaWVycyhsb2NhbE1vZHVsZU1ldGEuZGVjbGFyZWREaXJlY3RpdmVzKS5mb3JFYWNoKChkaXJSZWYpID0+IHtcbiAgICAgICAgbW9kdWxlQnlKaXREaXJlY3RpdmUuc2V0KGRpclJlZiwgbG9jYWxNb2R1bGVNZXRhKTtcbiAgICAgICAgY29uc3QgZGlyTWV0YSA9IHRoaXMuX21ldGFkYXRhUmVzb2x2ZXIuZ2V0RGlyZWN0aXZlTWV0YWRhdGEoZGlyUmVmKTtcbiAgICAgICAgaWYgKGRpck1ldGEuaXNDb21wb25lbnQpIHtcbiAgICAgICAgICB0ZW1wbGF0ZXMuYWRkKHRoaXMuX2NyZWF0ZUNvbXBpbGVkVGVtcGxhdGUoZGlyTWV0YSwgbG9jYWxNb2R1bGVNZXRhKSk7XG4gICAgICAgICAgaWYgKGFsbENvbXBvbmVudEZhY3Rvcmllcykge1xuICAgICAgICAgICAgY29uc3QgdGVtcGxhdGUgPVxuICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUNvbXBpbGVkSG9zdFRlbXBsYXRlKGRpck1ldGEudHlwZS5yZWZlcmVuY2UsIGxvY2FsTW9kdWxlTWV0YSk7XG4gICAgICAgICAgICB0ZW1wbGF0ZXMuYWRkKHRlbXBsYXRlKTtcbiAgICAgICAgICAgIGFsbENvbXBvbmVudEZhY3Rvcmllcy5wdXNoKGRpck1ldGEuY29tcG9uZW50RmFjdG9yeSBhcyBvYmplY3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgdHJhbnNKaXRNb2R1bGVzLmZvckVhY2goKGxvY2FsTW9kKSA9PiB7XG4gICAgICBjb25zdCBsb2NhbE1vZHVsZU1ldGEgPSB0aGlzLl9tZXRhZGF0YVJlc29sdmVyLmdldE5nTW9kdWxlTWV0YWRhdGEobG9jYWxNb2QpITtcbiAgICAgIHRoaXMuX2ZpbHRlckppdElkZW50aWZpZXJzKGxvY2FsTW9kdWxlTWV0YS5kZWNsYXJlZERpcmVjdGl2ZXMpLmZvckVhY2goKGRpclJlZikgPT4ge1xuICAgICAgICBjb25zdCBkaXJNZXRhID0gdGhpcy5fbWV0YWRhdGFSZXNvbHZlci5nZXREaXJlY3RpdmVNZXRhZGF0YShkaXJSZWYpO1xuICAgICAgICBpZiAoZGlyTWV0YS5pc0NvbXBvbmVudCkge1xuICAgICAgICAgIGRpck1ldGEuZW50cnlDb21wb25lbnRzLmZvckVhY2goKGVudHJ5Q29tcG9uZW50VHlwZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbW9kdWxlTWV0YSA9IG1vZHVsZUJ5Sml0RGlyZWN0aXZlLmdldChlbnRyeUNvbXBvbmVudFR5cGUuY29tcG9uZW50VHlwZSkhO1xuICAgICAgICAgICAgdGVtcGxhdGVzLmFkZChcbiAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVDb21waWxlZEhvc3RUZW1wbGF0ZShlbnRyeUNvbXBvbmVudFR5cGUuY29tcG9uZW50VHlwZSwgbW9kdWxlTWV0YSkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGxvY2FsTW9kdWxlTWV0YS5lbnRyeUNvbXBvbmVudHMuZm9yRWFjaCgoZW50cnlDb21wb25lbnRUeXBlKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5oYXNBb3RTdW1tYXJ5KGVudHJ5Q29tcG9uZW50VHlwZS5jb21wb25lbnRUeXBlKSkge1xuICAgICAgICAgIGNvbnN0IG1vZHVsZU1ldGEgPSBtb2R1bGVCeUppdERpcmVjdGl2ZS5nZXQoZW50cnlDb21wb25lbnRUeXBlLmNvbXBvbmVudFR5cGUpITtcbiAgICAgICAgICB0ZW1wbGF0ZXMuYWRkKFxuICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVDb21waWxlZEhvc3RUZW1wbGF0ZShlbnRyeUNvbXBvbmVudFR5cGUuY29tcG9uZW50VHlwZSwgbW9kdWxlTWV0YSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICB0ZW1wbGF0ZXMuZm9yRWFjaCgodGVtcGxhdGUpID0+IHRoaXMuX2NvbXBpbGVUZW1wbGF0ZSh0ZW1wbGF0ZSkpO1xuICB9XG5cbiAgY2xlYXJDYWNoZUZvcih0eXBlOiBUeXBlKSB7XG4gICAgdGhpcy5fY29tcGlsZWROZ01vZHVsZUNhY2hlLmRlbGV0ZSh0eXBlKTtcbiAgICB0aGlzLl9tZXRhZGF0YVJlc29sdmVyLmNsZWFyQ2FjaGVGb3IodHlwZSk7XG4gICAgdGhpcy5fY29tcGlsZWRIb3N0VGVtcGxhdGVDYWNoZS5kZWxldGUodHlwZSk7XG4gICAgY29uc3QgY29tcGlsZWRUZW1wbGF0ZSA9IHRoaXMuX2NvbXBpbGVkVGVtcGxhdGVDYWNoZS5nZXQodHlwZSk7XG4gICAgaWYgKGNvbXBpbGVkVGVtcGxhdGUpIHtcbiAgICAgIHRoaXMuX2NvbXBpbGVkVGVtcGxhdGVDYWNoZS5kZWxldGUodHlwZSk7XG4gICAgfVxuICB9XG5cbiAgY2xlYXJDYWNoZSgpOiB2b2lkIHtcbiAgICAvLyBOb3RlOiBkb24ndCBjbGVhciB0aGUgX2FkZGVkQW90U3VtbWFyaWVzLCBhcyB0aGV5IGRvbid0IGNoYW5nZSFcbiAgICB0aGlzLl9tZXRhZGF0YVJlc29sdmVyLmNsZWFyQ2FjaGUoKTtcbiAgICB0aGlzLl9jb21waWxlZFRlbXBsYXRlQ2FjaGUuY2xlYXIoKTtcbiAgICB0aGlzLl9jb21waWxlZEhvc3RUZW1wbGF0ZUNhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy5fY29tcGlsZWROZ01vZHVsZUNhY2hlLmNsZWFyKCk7XG4gIH1cblxuICBwcml2YXRlIF9jcmVhdGVDb21waWxlZEhvc3RUZW1wbGF0ZShjb21wVHlwZTogVHlwZSwgbmdNb2R1bGU6IENvbXBpbGVOZ01vZHVsZU1ldGFkYXRhKTpcbiAgICAgIENvbXBpbGVkVGVtcGxhdGUge1xuICAgIGlmICghbmdNb2R1bGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ29tcG9uZW50ICR7XG4gICAgICAgICAgc3RyaW5naWZ5KFxuICAgICAgICAgICAgICBjb21wVHlwZSl9IGlzIG5vdCBwYXJ0IG9mIGFueSBOZ01vZHVsZSBvciB0aGUgbW9kdWxlIGhhcyBub3QgYmVlbiBpbXBvcnRlZCBpbnRvIHlvdXIgbW9kdWxlLmApO1xuICAgIH1cbiAgICBsZXQgY29tcGlsZWRUZW1wbGF0ZSA9IHRoaXMuX2NvbXBpbGVkSG9zdFRlbXBsYXRlQ2FjaGUuZ2V0KGNvbXBUeXBlKTtcbiAgICBpZiAoIWNvbXBpbGVkVGVtcGxhdGUpIHtcbiAgICAgIGNvbnN0IGNvbXBNZXRhID0gdGhpcy5fbWV0YWRhdGFSZXNvbHZlci5nZXREaXJlY3RpdmVNZXRhZGF0YShjb21wVHlwZSk7XG4gICAgICBhc3NlcnRDb21wb25lbnQoY29tcE1ldGEpO1xuXG4gICAgICBjb25zdCBob3N0TWV0YSA9IHRoaXMuX21ldGFkYXRhUmVzb2x2ZXIuZ2V0SG9zdENvbXBvbmVudE1ldGFkYXRhKFxuICAgICAgICAgIGNvbXBNZXRhLCAoY29tcE1ldGEuY29tcG9uZW50RmFjdG9yeSBhcyBhbnkpLnZpZXdEZWZGYWN0b3J5KTtcbiAgICAgIGNvbXBpbGVkVGVtcGxhdGUgPVxuICAgICAgICAgIG5ldyBDb21waWxlZFRlbXBsYXRlKHRydWUsIGNvbXBNZXRhLnR5cGUsIGhvc3RNZXRhLCBuZ01vZHVsZSwgW2NvbXBNZXRhLnR5cGVdKTtcbiAgICAgIHRoaXMuX2NvbXBpbGVkSG9zdFRlbXBsYXRlQ2FjaGUuc2V0KGNvbXBUeXBlLCBjb21waWxlZFRlbXBsYXRlKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbXBpbGVkVGVtcGxhdGU7XG4gIH1cblxuICBwcml2YXRlIF9jcmVhdGVDb21waWxlZFRlbXBsYXRlKFxuICAgICAgY29tcE1ldGE6IENvbXBpbGVEaXJlY3RpdmVNZXRhZGF0YSwgbmdNb2R1bGU6IENvbXBpbGVOZ01vZHVsZU1ldGFkYXRhKTogQ29tcGlsZWRUZW1wbGF0ZSB7XG4gICAgbGV0IGNvbXBpbGVkVGVtcGxhdGUgPSB0aGlzLl9jb21waWxlZFRlbXBsYXRlQ2FjaGUuZ2V0KGNvbXBNZXRhLnR5cGUucmVmZXJlbmNlKTtcbiAgICBpZiAoIWNvbXBpbGVkVGVtcGxhdGUpIHtcbiAgICAgIGFzc2VydENvbXBvbmVudChjb21wTWV0YSk7XG4gICAgICBjb21waWxlZFRlbXBsYXRlID0gbmV3IENvbXBpbGVkVGVtcGxhdGUoXG4gICAgICAgICAgZmFsc2UsIGNvbXBNZXRhLnR5cGUsIGNvbXBNZXRhLCBuZ01vZHVsZSwgbmdNb2R1bGUudHJhbnNpdGl2ZU1vZHVsZS5kaXJlY3RpdmVzKTtcbiAgICAgIHRoaXMuX2NvbXBpbGVkVGVtcGxhdGVDYWNoZS5zZXQoY29tcE1ldGEudHlwZS5yZWZlcmVuY2UsIGNvbXBpbGVkVGVtcGxhdGUpO1xuICAgIH1cbiAgICByZXR1cm4gY29tcGlsZWRUZW1wbGF0ZTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbXBpbGVUZW1wbGF0ZSh0ZW1wbGF0ZTogQ29tcGlsZWRUZW1wbGF0ZSkge1xuICAgIGlmICh0ZW1wbGF0ZS5pc0NvbXBpbGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNvbXBNZXRhID0gdGVtcGxhdGUuY29tcE1ldGE7XG4gICAgY29uc3QgZXh0ZXJuYWxTdHlsZXNoZWV0c0J5TW9kdWxlVXJsID0gbmV3IE1hcDxzdHJpbmcsIENvbXBpbGVkU3R5bGVzaGVldD4oKTtcbiAgICBjb25zdCBvdXRwdXRDb250ZXh0ID0gY3JlYXRlT3V0cHV0Q29udGV4dCgpO1xuICAgIGNvbnN0IGNvbXBvbmVudFN0eWxlc2hlZXQgPSB0aGlzLl9zdHlsZUNvbXBpbGVyLmNvbXBpbGVDb21wb25lbnQob3V0cHV0Q29udGV4dCwgY29tcE1ldGEpO1xuICAgIGNvbXBNZXRhLnRlbXBsYXRlICEuZXh0ZXJuYWxTdHlsZXNoZWV0cy5mb3JFYWNoKChzdHlsZXNoZWV0TWV0YSkgPT4ge1xuICAgICAgY29uc3QgY29tcGlsZWRTdHlsZXNoZWV0ID1cbiAgICAgICAgICB0aGlzLl9zdHlsZUNvbXBpbGVyLmNvbXBpbGVTdHlsZXMoY3JlYXRlT3V0cHV0Q29udGV4dCgpLCBjb21wTWV0YSwgc3R5bGVzaGVldE1ldGEpO1xuICAgICAgZXh0ZXJuYWxTdHlsZXNoZWV0c0J5TW9kdWxlVXJsLnNldChzdHlsZXNoZWV0TWV0YS5tb2R1bGVVcmwhLCBjb21waWxlZFN0eWxlc2hlZXQpO1xuICAgIH0pO1xuICAgIHRoaXMuX3Jlc29sdmVTdHlsZXNDb21waWxlUmVzdWx0KGNvbXBvbmVudFN0eWxlc2hlZXQsIGV4dGVybmFsU3R5bGVzaGVldHNCeU1vZHVsZVVybCk7XG4gICAgY29uc3QgcGlwZXMgPSB0ZW1wbGF0ZS5uZ01vZHVsZS50cmFuc2l0aXZlTW9kdWxlLnBpcGVzLm1hcChcbiAgICAgICAgcGlwZSA9PiB0aGlzLl9tZXRhZGF0YVJlc29sdmVyLmdldFBpcGVTdW1tYXJ5KHBpcGUucmVmZXJlbmNlKSk7XG4gICAgY29uc3Qge3RlbXBsYXRlOiBwYXJzZWRUZW1wbGF0ZSwgcGlwZXM6IHVzZWRQaXBlc30gPVxuICAgICAgICB0aGlzLl9wYXJzZVRlbXBsYXRlKGNvbXBNZXRhLCB0ZW1wbGF0ZS5uZ01vZHVsZSwgdGVtcGxhdGUuZGlyZWN0aXZlcyk7XG4gICAgY29uc3QgY29tcGlsZVJlc3VsdCA9IHRoaXMuX3ZpZXdDb21waWxlci5jb21waWxlQ29tcG9uZW50KFxuICAgICAgICBvdXRwdXRDb250ZXh0LCBjb21wTWV0YSwgcGFyc2VkVGVtcGxhdGUsIGlyLnZhcmlhYmxlKGNvbXBvbmVudFN0eWxlc2hlZXQuc3R5bGVzVmFyKSxcbiAgICAgICAgdXNlZFBpcGVzKTtcbiAgICBjb25zdCBldmFsUmVzdWx0ID0gdGhpcy5faW50ZXJwcmV0T3JKaXQoXG4gICAgICAgIHRlbXBsYXRlSml0VXJsKHRlbXBsYXRlLm5nTW9kdWxlLnR5cGUsIHRlbXBsYXRlLmNvbXBNZXRhKSwgb3V0cHV0Q29udGV4dC5zdGF0ZW1lbnRzKTtcbiAgICBjb25zdCB2aWV3Q2xhc3MgPSBldmFsUmVzdWx0W2NvbXBpbGVSZXN1bHQudmlld0NsYXNzVmFyXTtcbiAgICBjb25zdCByZW5kZXJlclR5cGUgPSBldmFsUmVzdWx0W2NvbXBpbGVSZXN1bHQucmVuZGVyZXJUeXBlVmFyXTtcbiAgICB0ZW1wbGF0ZS5jb21waWxlZCh2aWV3Q2xhc3MsIHJlbmRlcmVyVHlwZSk7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZVRlbXBsYXRlKFxuICAgICAgY29tcE1ldGE6IENvbXBpbGVEaXJlY3RpdmVNZXRhZGF0YSwgbmdNb2R1bGU6IENvbXBpbGVOZ01vZHVsZU1ldGFkYXRhLFxuICAgICAgZGlyZWN0aXZlSWRlbnRpZmllcnM6IENvbXBpbGVJZGVudGlmaWVyTWV0YWRhdGFbXSk6XG4gICAgICB7dGVtcGxhdGU6IFRlbXBsYXRlQXN0W10sIHBpcGVzOiBDb21waWxlUGlwZVN1bW1hcnlbXX0ge1xuICAgIC8vIE5vdGU6ICEgaXMgb2sgaGVyZSBhcyBjb21wb25lbnRzIGFsd2F5cyBoYXZlIGEgdGVtcGxhdGUuXG4gICAgY29uc3QgcHJlc2VydmVXaGl0ZXNwYWNlcyA9IGNvbXBNZXRhLnRlbXBsYXRlICEucHJlc2VydmVXaGl0ZXNwYWNlcztcbiAgICBjb25zdCBkaXJlY3RpdmVzID1cbiAgICAgICAgZGlyZWN0aXZlSWRlbnRpZmllcnMubWFwKGRpciA9PiB0aGlzLl9tZXRhZGF0YVJlc29sdmVyLmdldERpcmVjdGl2ZVN1bW1hcnkoZGlyLnJlZmVyZW5jZSkpO1xuICAgIGNvbnN0IHBpcGVzID0gbmdNb2R1bGUudHJhbnNpdGl2ZU1vZHVsZS5waXBlcy5tYXAoXG4gICAgICAgIHBpcGUgPT4gdGhpcy5fbWV0YWRhdGFSZXNvbHZlci5nZXRQaXBlU3VtbWFyeShwaXBlLnJlZmVyZW5jZSkpO1xuICAgIHJldHVybiB0aGlzLl90ZW1wbGF0ZVBhcnNlci5wYXJzZShcbiAgICAgICAgY29tcE1ldGEsIGNvbXBNZXRhLnRlbXBsYXRlICEuaHRtbEFzdCEsIGRpcmVjdGl2ZXMsIHBpcGVzLCBuZ01vZHVsZS5zY2hlbWFzLFxuICAgICAgICB0ZW1wbGF0ZVNvdXJjZVVybChuZ01vZHVsZS50eXBlLCBjb21wTWV0YSwgY29tcE1ldGEudGVtcGxhdGUgISksIHByZXNlcnZlV2hpdGVzcGFjZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVzb2x2ZVN0eWxlc0NvbXBpbGVSZXN1bHQoXG4gICAgICByZXN1bHQ6IENvbXBpbGVkU3R5bGVzaGVldCwgZXh0ZXJuYWxTdHlsZXNoZWV0c0J5TW9kdWxlVXJsOiBNYXA8c3RyaW5nLCBDb21waWxlZFN0eWxlc2hlZXQ+KSB7XG4gICAgcmVzdWx0LmRlcGVuZGVuY2llcy5mb3JFYWNoKChkZXAsIGkpID0+IHtcbiAgICAgIGNvbnN0IG5lc3RlZENvbXBpbGVSZXN1bHQgPSBleHRlcm5hbFN0eWxlc2hlZXRzQnlNb2R1bGVVcmwuZ2V0KGRlcC5tb2R1bGVVcmwpITtcbiAgICAgIGNvbnN0IG5lc3RlZFN0eWxlc0FyciA9IHRoaXMuX3Jlc29sdmVBbmRFdmFsU3R5bGVzQ29tcGlsZVJlc3VsdChcbiAgICAgICAgICBuZXN0ZWRDb21waWxlUmVzdWx0LCBleHRlcm5hbFN0eWxlc2hlZXRzQnlNb2R1bGVVcmwpO1xuICAgICAgZGVwLnNldFZhbHVlKG5lc3RlZFN0eWxlc0Fycik7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZXNvbHZlQW5kRXZhbFN0eWxlc0NvbXBpbGVSZXN1bHQoXG4gICAgICByZXN1bHQ6IENvbXBpbGVkU3R5bGVzaGVldCxcbiAgICAgIGV4dGVybmFsU3R5bGVzaGVldHNCeU1vZHVsZVVybDogTWFwPHN0cmluZywgQ29tcGlsZWRTdHlsZXNoZWV0Pik6IHN0cmluZ1tdIHtcbiAgICB0aGlzLl9yZXNvbHZlU3R5bGVzQ29tcGlsZVJlc3VsdChyZXN1bHQsIGV4dGVybmFsU3R5bGVzaGVldHNCeU1vZHVsZVVybCk7XG4gICAgcmV0dXJuIHRoaXMuX2ludGVycHJldE9ySml0KFxuICAgICAgICBzaGFyZWRTdHlsZXNoZWV0Sml0VXJsKHJlc3VsdC5tZXRhLCB0aGlzLl9zaGFyZWRTdHlsZXNoZWV0Q291bnQrKyksXG4gICAgICAgIHJlc3VsdC5vdXRwdXRDdHguc3RhdGVtZW50cylbcmVzdWx0LnN0eWxlc1Zhcl07XG4gIH1cblxuICBwcml2YXRlIF9pbnRlcnByZXRPckppdChzb3VyY2VVcmw6IHN0cmluZywgc3RhdGVtZW50czogaXIuU3RhdGVtZW50W10pOiBhbnkge1xuICAgIGlmICghdGhpcy5fY29tcGlsZXJDb25maWcudXNlSml0KSB7XG4gICAgICByZXR1cm4gaW50ZXJwcmV0U3RhdGVtZW50cyhzdGF0ZW1lbnRzLCB0aGlzLl9yZWZsZWN0b3IpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5faml0RXZhbHVhdG9yLmV2YWx1YXRlU3RhdGVtZW50cyhcbiAgICAgICAgICBzb3VyY2VVcmwsIHN0YXRlbWVudHMsIHRoaXMuX3JlZmxlY3RvciwgdGhpcy5fY29tcGlsZXJDb25maWcuaml0RGV2TW9kZSk7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIENvbXBpbGVkVGVtcGxhdGUge1xuICBwcml2YXRlIF92aWV3Q2xhc3M6IEZ1bmN0aW9uID0gbnVsbCE7XG4gIGlzQ29tcGlsZWQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICAgIHB1YmxpYyBpc0hvc3Q6IGJvb2xlYW4sIHB1YmxpYyBjb21wVHlwZTogQ29tcGlsZUlkZW50aWZpZXJNZXRhZGF0YSxcbiAgICAgIHB1YmxpYyBjb21wTWV0YTogQ29tcGlsZURpcmVjdGl2ZU1ldGFkYXRhLCBwdWJsaWMgbmdNb2R1bGU6IENvbXBpbGVOZ01vZHVsZU1ldGFkYXRhLFxuICAgICAgcHVibGljIGRpcmVjdGl2ZXM6IENvbXBpbGVJZGVudGlmaWVyTWV0YWRhdGFbXSkge31cblxuICBjb21waWxlZCh2aWV3Q2xhc3M6IEZ1bmN0aW9uLCByZW5kZXJlclR5cGU6IGFueSkge1xuICAgIHRoaXMuX3ZpZXdDbGFzcyA9IHZpZXdDbGFzcztcbiAgICAoPFByb3h5Q2xhc3M+dGhpcy5jb21wTWV0YS5jb21wb25lbnRWaWV3VHlwZSkuc2V0RGVsZWdhdGUodmlld0NsYXNzKTtcbiAgICBmb3IgKGxldCBwcm9wIGluIHJlbmRlcmVyVHlwZSkge1xuICAgICAgKDxhbnk+dGhpcy5jb21wTWV0YS5yZW5kZXJlclR5cGUpW3Byb3BdID0gcmVuZGVyZXJUeXBlW3Byb3BdO1xuICAgIH1cbiAgICB0aGlzLmlzQ29tcGlsZWQgPSB0cnVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydENvbXBvbmVudChtZXRhOiBDb21waWxlRGlyZWN0aXZlTWV0YWRhdGEpIHtcbiAgaWYgKCFtZXRhLmlzQ29tcG9uZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ291bGQgbm90IGNvbXBpbGUgJyR7aWRlbnRpZmllck5hbWUobWV0YS50eXBlKX0nIGJlY2F1c2UgaXQgaXMgbm90IGEgY29tcG9uZW50LmApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU91dHB1dENvbnRleHQoKTogT3V0cHV0Q29udGV4dCB7XG4gIGNvbnN0IGltcG9ydEV4cHIgPSAoc3ltYm9sOiBhbnkpID0+XG4gICAgICBpci5pbXBvcnRFeHByKHtuYW1lOiBpZGVudGlmaWVyTmFtZShzeW1ib2wpLCBtb2R1bGVOYW1lOiBudWxsLCBydW50aW1lOiBzeW1ib2x9KTtcbiAgcmV0dXJuIHtzdGF0ZW1lbnRzOiBbXSwgZ2VuRmlsZVBhdGg6ICcnLCBpbXBvcnRFeHByLCBjb25zdGFudFBvb2w6IG5ldyBDb25zdGFudFBvb2woKX07XG59XG4iXX0=
Note: See TracBrowser for help on using the repository browser.