/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import * as html from '../ml_parser/ast'; import { ParseError } from '../parse_util'; import * as t from './r3_ast'; import { getTriggerParametersStart, parseDeferredTime, parseOnTrigger, parseWhenTrigger } from './r3_deferred_triggers'; /** Pattern to identify a `prefetch when` trigger. */ const PREFETCH_WHEN_PATTERN = /^prefetch\s+when\s/; /** Pattern to identify a `prefetch on` trigger. */ const PREFETCH_ON_PATTERN = /^prefetch\s+on\s/; /** Pattern to identify a `minimum` parameter in a block. */ const MINIMUM_PARAMETER_PATTERN = /^minimum\s/; /** Pattern to identify a `after` parameter in a block. */ const AFTER_PARAMETER_PATTERN = /^after\s/; /** Pattern to identify a `when` parameter in a block. */ const WHEN_PARAMETER_PATTERN = /^when\s/; /** Pattern to identify a `on` parameter in a block. */ const ON_PARAMETER_PATTERN = /^on\s/; /** Possible types of secondary deferred blocks. */ export var SecondaryDeferredBlockType; (function (SecondaryDeferredBlockType) { SecondaryDeferredBlockType["PLACEHOLDER"] = "placeholder"; SecondaryDeferredBlockType["LOADING"] = "loading"; SecondaryDeferredBlockType["ERROR"] = "error"; })(SecondaryDeferredBlockType || (SecondaryDeferredBlockType = {})); /** Creates a deferred block from an HTML AST node. */ export function createDeferredBlock(ast, visitor, bindingParser) { const errors = []; const [primaryBlock, ...secondaryBlocks] = ast.blocks; const { triggers, prefetchTriggers } = parsePrimaryTriggers(primaryBlock.parameters, bindingParser, errors); const { placeholder, loading, error } = parseSecondaryBlocks(secondaryBlocks, errors, visitor); return { node: new t.DeferredBlock(html.visitAll(visitor, primaryBlock.children), triggers, prefetchTriggers, placeholder, loading, error, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan), errors, }; } function parseSecondaryBlocks(blocks, errors, visitor) { let placeholder = null; let loading = null; let error = null; for (const block of blocks) { try { switch (block.name) { case SecondaryDeferredBlockType.PLACEHOLDER: if (placeholder !== null) { errors.push(new ParseError(block.startSourceSpan, `"defer" block can only have one "${SecondaryDeferredBlockType.PLACEHOLDER}" block`)); } else { placeholder = parsePlaceholderBlock(block, visitor); } break; case SecondaryDeferredBlockType.LOADING: if (loading !== null) { errors.push(new ParseError(block.startSourceSpan, `"defer" block can only have one "${SecondaryDeferredBlockType.LOADING}" block`)); } else { loading = parseLoadingBlock(block, visitor); } break; case SecondaryDeferredBlockType.ERROR: if (error !== null) { errors.push(new ParseError(block.startSourceSpan, `"defer" block can only have one "${SecondaryDeferredBlockType.ERROR}" block`)); } else { error = parseErrorBlock(block, visitor); } break; default: errors.push(new ParseError(block.startSourceSpan, `Unrecognized block "${block.name}"`)); break; } } catch (e) { errors.push(new ParseError(block.startSourceSpan, e.message)); } } return { placeholder, loading, error }; } function parsePlaceholderBlock(ast, visitor) { let minimumTime = null; for (const param of ast.parameters) { if (MINIMUM_PARAMETER_PATTERN.test(param.expression)) { const parsedTime = parseDeferredTime(param.expression.slice(getTriggerParametersStart(param.expression))); if (parsedTime === null) { throw new Error(`Could not parse time value of parameter "minimum"`); } minimumTime = parsedTime; } else { throw new Error(`Unrecognized parameter in "${SecondaryDeferredBlockType.PLACEHOLDER}" block: "${param.expression}"`); } } return new t.DeferredBlockPlaceholder(html.visitAll(visitor, ast.children), minimumTime, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan); } function parseLoadingBlock(ast, visitor) { let afterTime = null; let minimumTime = null; for (const param of ast.parameters) { if (AFTER_PARAMETER_PATTERN.test(param.expression)) { const parsedTime = parseDeferredTime(param.expression.slice(getTriggerParametersStart(param.expression))); if (parsedTime === null) { throw new Error(`Could not parse time value of parameter "after"`); } afterTime = parsedTime; } else if (MINIMUM_PARAMETER_PATTERN.test(param.expression)) { const parsedTime = parseDeferredTime(param.expression.slice(getTriggerParametersStart(param.expression))); if (parsedTime === null) { throw new Error(`Could not parse time value of parameter "minimum"`); } minimumTime = parsedTime; } else { throw new Error(`Unrecognized parameter in "${SecondaryDeferredBlockType.LOADING}" block: "${param.expression}"`); } } return new t.DeferredBlockLoading(html.visitAll(visitor, ast.children), afterTime, minimumTime, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan); } function parseErrorBlock(ast, visitor) { if (ast.parameters.length > 0) { throw new Error(`"${SecondaryDeferredBlockType.ERROR}" block cannot have parameters`); } return new t.DeferredBlockError(html.visitAll(visitor, ast.children), ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan); } function parsePrimaryTriggers(params, bindingParser, errors) { const triggers = []; const prefetchTriggers = []; for (const param of params) { // The lexer ignores the leading spaces so we can assume // that the expression starts with a keyword. if (WHEN_PARAMETER_PATTERN.test(param.expression)) { const result = parseWhenTrigger(param, bindingParser, errors); result !== null && triggers.push(result); } else if (ON_PARAMETER_PATTERN.test(param.expression)) { triggers.push(...parseOnTrigger(param, errors)); } else if (PREFETCH_WHEN_PATTERN.test(param.expression)) { const result = parseWhenTrigger(param, bindingParser, errors); result !== null && prefetchTriggers.push(result); } else if (PREFETCH_ON_PATTERN.test(param.expression)) { prefetchTriggers.push(...parseOnTrigger(param, errors)); } else { errors.push(new ParseError(param.sourceSpan, 'Unrecognized trigger')); } } return { triggers, prefetchTriggers }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicjNfZGVmZXJyZWRfYmxvY2tzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3JlbmRlcjMvcjNfZGVmZXJyZWRfYmxvY2tzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sS0FBSyxJQUFJLE1BQU0sa0JBQWtCLENBQUM7QUFDekMsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUd6QyxPQUFPLEtBQUssQ0FBQyxNQUFNLFVBQVUsQ0FBQztBQUM5QixPQUFPLEVBQUMseUJBQXlCLEVBQUUsaUJBQWlCLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFFdEgscURBQXFEO0FBQ3JELE1BQU0scUJBQXFCLEdBQUcsb0JBQW9CLENBQUM7QUFFbkQsbURBQW1EO0FBQ25ELE1BQU0sbUJBQW1CLEdBQUcsa0JBQWtCLENBQUM7QUFFL0MsNERBQTREO0FBQzVELE1BQU0seUJBQXlCLEdBQUcsWUFBWSxDQUFDO0FBRS9DLDBEQUEwRDtBQUMxRCxNQUFNLHVCQUF1QixHQUFHLFVBQVUsQ0FBQztBQUUzQyx5REFBeUQ7QUFDekQsTUFBTSxzQkFBc0IsR0FBRyxTQUFTLENBQUM7QUFFekMsdURBQXVEO0FBQ3ZELE1BQU0sb0JBQW9CLEdBQUcsT0FBTyxDQUFDO0FBRXJDLG1EQUFtRDtBQUNuRCxNQUFNLENBQU4sSUFBWSwwQkFJWDtBQUpELFdBQVksMEJBQTBCO0lBQ3BDLHlEQUEyQixDQUFBO0lBQzNCLGlEQUFtQixDQUFBO0lBQ25CLDZDQUFlLENBQUE7QUFDakIsQ0FBQyxFQUpXLDBCQUEwQixLQUExQiwwQkFBMEIsUUFJckM7QUFFRCxzREFBc0Q7QUFDdEQsTUFBTSxVQUFVLG1CQUFtQixDQUMvQixHQUFvQixFQUFFLE9BQXFCLEVBQzNDLGFBQTRCO0lBQzlCLE1BQU0sTUFBTSxHQUFp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TSxDQUFDLENBQUM7U0FDbEQ7YUFBTSxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDckQsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEdBQUcsY0FBYyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQ3pEO2FBQU07WUFDTCxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO1NBQ3ZFO0tBQ0Y7SUFFRCxPQUFPLEVBQUMsUUFBUSxFQUFFLGdCQUFnQixFQUFDLENBQUM7QUFDdEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgKiBhcyBodG1sIGZyb20gJy4uL21sX3BhcnNlci9hc3QnO1xuaW1wb3J0IHtQYXJzZUVycm9yfSBmcm9tICcuLi9wYXJzZV91dGlsJztcbmltcG9ydCB7QmluZGluZ1BhcnNlcn0gZnJvbSAnLi4vdGVtcGxhdGVfcGFyc2VyL2JpbmRpbmdfcGFyc2VyJztcblxuaW1wb3J0ICogYXMgdCBmcm9tICcuL3IzX2FzdCc7XG5pbXBvcnQge2dldFRyaWdnZXJQYXJhbWV0ZXJzU3RhcnQsIHBhcnNlRGVmZXJyZWRUaW1lLCBwYXJzZU9uVHJpZ2dlciwgcGFyc2VXaGVuVHJpZ2dlcn0gZnJvbSAnLi9yM19kZWZlcnJlZF90cmlnZ2Vycyc7XG5cbi8qKiBQYXR0ZXJuIHRvIGlkZW50aWZ5IGEgYHByZWZldGNoIHdoZW5gIHRyaWdnZXIuICovXG5jb25zdCBQUkVGRVRDSF9XSEVOX1BBVFRFUk4gPSAvXnByZWZldGNoXFxzK3doZW5cXHMvO1xuXG4vKiogUGF0dGVybiB0byBpZGVudGlmeSBhIGBwcmVmZXRjaCBvbmAgdHJpZ2dlci4gKi9cbmNvbnN0IFBSRUZFVENIX09OX1BBVFRFUk4gPSAvXnByZWZldGNoXFxzK29uXFxzLztcblxuLyoqIFBhdHRlcm4gdG8gaWRlbnRpZnkgYSBgbWluaW11bWAgcGFyYW1ldGVyIGluIGEgYmxvY2suICovXG5jb25zdCBNSU5JTVVNX1BBUkFNRVRFUl9QQVRURVJOID0gL15taW5pbXVtXFxzLztcblxuLyoqIFBhdHRlcm4gdG8gaWRlbnRpZnkgYSBgYWZ0ZXJgIHBhcmFtZXRlciBpbiBhIGJsb2NrLiAqL1xuY29uc3QgQUZURVJfUEFSQU1FVEVSX1BBVFRFUk4gPSAvXmFmdGVyXFxzLztcblxuLyoqIFBhdHRlcm4gdG8gaWRlbnRpZnkgYSBgd2hlbmAgcGFyYW1ldGVyIGluIGEgYmxvY2suICovXG5jb25zdCBXSEVOX1BBUkFNRVRFUl9QQVRURVJOID0gL153aGVuXFxzLztcblxuLyoqIFBhdHRlcm4gdG8gaWRlbnRpZnkgYSBgb25gIHBhcmFtZXRlciBpbiBhIGJsb2NrLiAqL1xuY29uc3QgT05fUEFSQU1FVEVSX1BBVFRFUk4gPSAvXm9uXFxzLztcblxuLyoqIFBvc3NpYmxlIHR5cGVzIG9mIHNlY29uZGFyeSBkZWZlcnJlZCBibG9ja3MuICovXG5leHBvcnQgZW51bSBTZWNvbmRhcnlEZWZlcnJlZEJsb2NrVHlwZSB7XG4gIFBMQUNFSE9MREVSID0gJ3BsYWNlaG9sZGVyJyxcbiAgTE9BRElORyA9ICdsb2FkaW5nJyxcbiAgRVJST1IgPSAnZXJyb3InLFxufVxuXG4vKiogQ3JlYXRlcyBhIGRlZmVycmVkIGJsb2NrIGZyb20gYW4gSFRNTCBBU1Qgbm9kZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEZWZlcnJlZEJsb2NrKFxuICAgIGFzdDogaHRtbC5CbG9ja0dyb3VwLCB2aXNpdG9yOiBodG1sLlZpc2l0b3IsXG4gICAgYmluZGluZ1BhcnNlcjogQmluZGluZ1BhcnNlcik6IHtub2RlOiB0LkRlZmVycmVkQmxvY2ssIGVycm9yczogUGFyc2VFcnJvcltdfSB7XG4gIGNvbnN0IGVycm9yczogUGFyc2VFcnJvcltdID0gW107XG4gIGNvbnN0IFtwcmltYXJ5QmxvY2ssIC4uLnNlY29uZGFyeUJsb2Nrc10gPSBhc3QuYmxvY2tzO1xuICBjb25zdCB7dHJpZ2dlcnMsIHByZWZldGNoVHJpZ2dlcnN9ID1cbiAgICAgIHBhcnNlUHJpbWFyeVRyaWdnZXJzKHByaW1hcnlCbG9jay5wYXJhbWV0ZXJzLCBiaW5kaW5nUGFyc2VyLCBlcnJvcnMpO1xuICBjb25zdCB7cGxhY2Vob2xkZXIsIGxvYWRpbmcsIGVycm9yfSA9IHBhcnNlU2Vjb25kYXJ5QmxvY2tzKHNlY29uZGFyeUJsb2NrcywgZXJyb3JzLCB2aXNpdG9yKTtcblxuICByZXR1cm4ge1xuICAgIG5vZGU6IG5ldyB0LkRlZmVycmVkQmxvY2soXG4gICAgICAgIGh0bWwudmlzaXRBbGwodmlzaXRvciwgcHJpbWFyeUJsb2NrLmNoaWxkcmVuKSwgdHJpZ2dlcnMsIHByZWZldGNoVHJpZ2dlcnMsIHBsYWNlaG9sZGVyLFxuICAgICAgICBsb2FkaW5nLCBlcnJvciwgYXN0LnNvdXJjZVNwYW4sIGFzdC5zdGFydFNvdXJjZVNwYW4sIGFzdC5lbmRTb3VyY2VTcGFuKSxcbiAgICBlcnJvcnMsXG4gIH07XG59XG5cbmZ1bmN0aW9uIHBhcnNlU2Vjb25kYXJ5QmxvY2tzKGJsb2NrczogaHRtbC5CbG9ja1tdLCBlcnJvcnM6IFBhcnNlRXJyb3JbXSwgdmlzaXRvcjogaHRtbC5WaXNpdG9yKSB7XG4gIGxldCBwbGFjZWhvbGRlcjogdC5EZWZlcnJlZEJsb2NrUGxhY2Vob2xkZXJ8bnVsbCA9IG51bGw7XG4gIGxldCBsb2FkaW5nOiB0LkRlZmVycmVkQmxvY2tMb2FkaW5nfG51bGwgPSBudWxsO1xuICBsZXQgZXJyb3I6IHQuRGVmZXJyZWRCbG9ja0Vycm9yfG51bGwgPSBudWxsO1xuXG4gIGZvciAoY29uc3QgYmxvY2sgb2YgYmxvY2tzKSB7XG4gICAgdHJ5IHtcbiAgICAgIHN3aXRjaCAoYmxvY2submFtZSkge1xuICAgICAgICBjYXNlIFNlY29uZGFyeURlZmVycmVkQmxvY2tUeXBlLlBMQUNFSE9MREVSOlxuICAgICAgICAgIGlmIChwbGFjZWhvbGRlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IoXG4gICAgICAgICAgICAgICAgYmxvY2suc3RhcnRTb3VyY2VTcGFuLFxuICAgICAgICAgICAgICAgIGBcImRlZmVyXCIgYmxvY2sgY2FuIG9ubHkgaGF2ZSBvbmUgXCIke1xuICAgICAgICAgICAgICAgICAgICBTZWNvbmRhcnlEZWZlcnJlZEJsb2NrVHlwZS5QTEFDRUhPTERFUn1cIiBibG9ja2ApKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGxhY2Vob2xkZXIgPSBwYXJzZVBsYWNlaG9sZGVyQmxvY2soYmxvY2ssIHZpc2l0b3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFNlY29uZGFyeURlZmVycmVkQmxvY2tUeXBlLkxPQURJTkc6XG4gICAgICAgICAgaWYgKGxvYWRpbmcgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKFxuICAgICAgICAgICAgICAgIGJsb2NrLnN0YXJ0U291cmNlU3BhbixcbiAgICAgICAgICAgICAgICBgXCJkZWZlclwiIGJsb2NrIGNhbiBvbmx5IGhhdmUgb25lIFwiJHtTZWNvbmRhcnlEZWZlcnJlZEJsb2NrVHlwZS5MT0FESU5HfVwiIGJsb2NrYCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2FkaW5nID0gcGFyc2VMb2FkaW5nQmxvY2soYmxvY2ssIHZpc2l0b3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFNlY29uZGFyeURlZmVycmVkQmxvY2tUeXBlLkVSUk9SOlxuICAgICAgICAgIGlmIChlcnJvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IoXG4gICAgICAgICAgICAgICAgYmxvY2suc3RhcnRTb3VyY2VTcGFuLFxuICAgICAgICAgICAgICAgIGBcImRlZmVyXCIgYmxvY2sgY2FuIG9ubHkgaGF2ZSBvbmUgXCIke1NlY29uZGFyeURlZmVycmVkQmxvY2tUeXBlLkVSUk9SfVwiIGJsb2NrYCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlcnJvciA9IHBhcnNlRXJyb3JCbG9jayhibG9jaywgdmlzaXRvcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IoYmxvY2suc3RhcnRTb3VyY2VTcGFuLCBgVW5yZWNvZ25pemVkIGJsb2NrIFwiJHtibG9jay5uYW1lfVwiYCkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKGJsb2NrLnN0YXJ0U291cmNlU3BhbiwgKGUgYXMgRXJyb3IpLm1lc3NhZ2UpKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge3BsYWNlaG9sZGVyLCBsb2FkaW5nLCBlcnJvcn07XG59XG5cbmZ1bmN0aW9uIHBhcnNlUGxhY2Vob2xkZXJCbG9jayhhc3Q6IGh0bWwuQmxvY2ssIHZpc2l0b3I6IGh0bWwuVmlzaXRvcik6IHQuRGVmZXJyZWRCbG9ja1BsYWNlaG9sZGVyIHtcbiAgbGV0IG1pbmltdW1UaW1lOiBudW1iZXJ8bnVsbCA9IG51bGw7XG5cbiAgZm9yIChjb25zdCBwYXJhbSBvZiBhc3QucGFyYW1ldGVycykge1xuICAgIGlmIChNSU5JTVVNX1BBUkFNRVRFUl9QQVRURVJOLnRlc3QocGFyYW0uZXhwcmVzc2lvbikpIHtcbiAgICAgIGNvbnN0IHBhcnNlZFRpbWUgPVxuICAgICAgICAgIHBhcnNlRGVmZXJyZWRUaW1lKHBhcmFtLmV4cHJlc3Npb24uc2xpY2UoZ2V0VHJpZ2dlclBhcmFtZXRlcnNTdGFydChwYXJhbS5leHByZXNzaW9uKSkpO1xuXG4gICAgICBpZiAocGFyc2VkVGltZSA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBwYXJzZSB0aW1lIHZhbHVlIG9mIHBhcmFtZXRlciBcIm1pbmltdW1cImApO1xuICAgICAgfVxuXG4gICAgICBtaW5pbXVtVGltZSA9IHBhcnNlZFRpbWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5yZWNvZ25pemVkIHBhcmFtZXRlciBpbiBcIiR7XG4gICAgICAgICAgU2Vjb25kYXJ5RGVmZXJyZWRCbG9ja1R5cGUuUExBQ0VIT0xERVJ9XCIgYmxvY2s6IFwiJHtwYXJhbS5leHByZXNzaW9ufVwiYCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyB0LkRlZmVycmVkQmxvY2tQbGFjZWhvbGRlcihcbiAgICAgIGh0bWwudmlzaXRBbGwodmlzaXRvciwgYXN0LmNoaWxkcmVuKSwgbWluaW11bVRpbWUsIGFzdC5zb3VyY2VTcGFuLCBhc3Quc3RhcnRTb3VyY2VTcGFuLFxuICAgICAgYXN0LmVuZFNvdXJjZVNwYW4pO1xufVxuXG5mdW5jdGlvbiBwYXJzZUxvYWRpbmdCbG9jayhhc3Q6IGh0bWwuQmxvY2ssIHZpc2l0b3I6IGh0bWwuVmlzaXRvcik6IHQuRGVmZXJyZWRCbG9ja0xvYWRpbmcge1xuICBsZXQgYWZ0ZXJUaW1lOiBudW1iZXJ8bnVsbCA9IG51bGw7XG4gIGxldCBtaW5pbXVtVGltZTogbnVtYmVyfG51bGwgPSBudWxsO1xuXG4gIGZvciAoY29uc3QgcGFyYW0gb2YgYXN0LnBhcmFtZXRlcnMpIHtcbiAgICBpZiAoQUZURVJfUEFSQU1FVEVSX1BBVFRFUk4udGVzdChwYXJhbS5leHByZXNzaW9uKSkge1xuICAgICAgY29uc3QgcGFyc2VkVGltZSA9XG4gICAgICAgICAgcGFyc2VEZWZlcnJlZFRpbWUocGFyYW0uZXhwcmVzc2lvbi5zbGljZShnZXRUcmlnZ2VyUGFyYW1ldGVyc1N0YXJ0KHBhcmFtLmV4cHJlc3Npb24pKSk7XG5cbiAgICAgIGlmIChwYXJzZWRUaW1lID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IHBhcnNlIHRpbWUgdmFsdWUgb2YgcGFyYW1ldGVyIFwiYWZ0ZXJcImApO1xuICAgICAgfVxuXG4gICAgICBhZnRlclRpbWUgPSBwYXJzZWRUaW1lO1xuICAgIH0gZWxzZSBpZiAoTUlOSU1VTV9QQVJBTUVURVJfUEFUVEVSTi50ZXN0KHBhcmFtLmV4cHJlc3Npb24pKSB7XG4gICAgICBjb25zdCBwYXJzZWRUaW1lID1cbiAgICAgICAgICBwYXJzZURlZmVycmVkVGltZShwYXJhbS5leHByZXNzaW9uLnNsaWNlKGdldFRyaWdnZXJQYXJhbWV0ZXJzU3RhcnQocGFyYW0uZXhwcmVzc2lvbikpKTtcblxuICAgICAgaWYgKHBhcnNlZFRpbWUgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgcGFyc2UgdGltZSB2YWx1ZSBvZiBwYXJhbWV0ZXIgXCJtaW5pbXVtXCJgKTtcbiAgICAgIH1cblxuICAgICAgbWluaW11bVRpbWUgPSBwYXJzZWRUaW1lO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBwYXJhbWV0ZXIgaW4gXCIke1NlY29uZGFyeURlZmVycmVkQmxvY2tUeXBlLkxPQURJTkd9XCIgYmxvY2s6IFwiJHtcbiAgICAgICAgICBwYXJhbS5leHByZXNzaW9ufVwiYCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyB0LkRlZmVycmVkQmxvY2tMb2FkaW5nKFxuICAgICAgaHRtbC52aXNpdEFsbCh2aXNpdG9yLCBhc3QuY2hpbGRyZW4pLCBhZnRlclRpbWUsIG1pbmltdW1UaW1lLCBhc3Quc291cmNlU3BhbixcbiAgICAgIGFzdC5zdGFydFNvdXJjZVNwYW4sIGFzdC5lbmRTb3VyY2VTcGFuKTtcbn1cblxuXG5mdW5jdGlvbiBwYXJzZUVycm9yQmxvY2soYXN0OiBodG1sLkJsb2NrLCB2aXNpdG9yOiBodG1sLlZpc2l0b3IpOiB0LkRlZmVycmVkQmxvY2tFcnJvciB7XG4gIGlmIChhc3QucGFyYW1ldGVycy5sZW5ndGggPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBcIiR7U2Vjb25kYXJ5RGVmZXJyZWRCbG9ja1R5cGUuRVJST1J9XCIgYmxvY2sgY2Fubm90IGhhdmUgcGFyYW1ldGVyc2ApO1xuICB9XG5cbiAgcmV0dXJuIG5ldyB0LkRlZmVycmVkQmxvY2tFcnJvcihcbiAgICAgIGh0bWwudmlzaXRBbGwodmlzaXRvciwgYXN0LmNoaWxkcmVuKSwgYXN0LnNvdXJjZVNwYW4sIGFzdC5zdGFydFNvdXJjZVNwYW4sIGFzdC5lbmRTb3VyY2VTcGFuKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VQcmltYXJ5VHJpZ2dlcnMoXG4gICAgcGFyYW1zOiBodG1sLkJsb2NrUGFyYW1ldGVyW10sIGJpbmRpbmdQYXJzZXI6IEJpbmRpbmdQYXJzZXIsIGVycm9yczogUGFyc2VFcnJvcltdKSB7XG4gIGNvbnN0IHRyaWdnZXJzOiB0LkRlZmVycmVkVHJpZ2dlcltdID0gW107XG4gIGNvbnN0IHByZWZldGNoVHJpZ2dlcnM6IHQuRGVmZXJyZWRUcmlnZ2VyW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IHBhcmFtIG9mIHBhcmFtcykge1xuICAgIC8vIFRoZSBsZXhlciBpZ25vcmVzIHRoZSBsZWFkaW5nIHNwYWNlcyBzbyB3ZSBjYW4gYXNzdW1lXG4gICAgLy8gdGhhdCB0aGUgZXhwcmVzc2lvbiBzdGFydHMgd2l0aCBhIGtleXdvcmQuXG4gICAgaWYgKFdIRU5fUEFSQU1FVEVSX1BBVFRFUk4udGVzdChwYXJhbS5leHByZXNzaW9uKSkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VXaGVuVHJpZ2dlcihwYXJhbSwgYmluZGluZ1BhcnNlciwgZXJyb3JzKTtcbiAgICAgIHJlc3VsdCAhPT0gbnVsbCAmJiB0cmlnZ2Vycy5wdXNoKHJlc3VsdCk7XG4gICAgfSBlbHNlIGlmIChPTl9QQVJBTUVURVJfUEFUVEVSTi50ZXN0KHBhcmFtLmV4cHJlc3Npb24pKSB7XG4gICAgICB0cmlnZ2Vycy5wdXNoKC4uLnBhcnNlT25UcmlnZ2VyKHBhcmFtLCBlcnJvcnMpKTtcbiAgICB9IGVsc2UgaWYgKFBSRUZFVENIX1dIRU5fUEFUVEVSTi50ZXN0KHBhcmFtLmV4cHJlc3Npb24pKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBwYXJzZVdoZW5UcmlnZ2VyKHBhcmFtLCBiaW5kaW5nUGFyc2VyLCBlcnJvcnMpO1xuICAgICAgcmVzdWx0ICE9PSBudWxsICYmIHByZWZldGNoVHJpZ2dlcnMucHVzaChyZXN1bHQpO1xuICAgIH0gZWxzZSBpZiAoUFJFRkVUQ0hfT05fUEFUVEVSTi50ZXN0KHBhcmFtLmV4cHJlc3Npb24pKSB7XG4gICAgICBwcmVmZXRjaFRyaWdnZXJzLnB1c2goLi4ucGFyc2VPblRyaWdnZXIocGFyYW0sIGVycm9ycykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihwYXJhbS5zb3VyY2VTcGFuLCAnVW5yZWNvZ25pemVkIHRyaWdnZXInKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHt0cmlnZ2VycywgcHJlZmV0Y2hUcmlnZ2Vyc307XG59XG4iXX0=