UNPKG

@glimmer/compiler

Version:
733 lines (640 loc) 63.1 kB
import { assert, assertNever, dict, exhausted, isPresent, values } from '@glimmer/util'; import { normalizeStatement, VariableKind } from './builder-interface'; export class ProgramSymbols { constructor() { this._freeVariables = []; this._symbols = ['this']; this.top = this; } toSymbols() { return this._symbols.slice(1); } toUpvars() { return this._freeVariables; } freeVar(name) { return addString(this._freeVariables, name); } block(name) { return this.symbol(name); } arg(name) { return addString(this._symbols, name); } local(name) { throw new Error(`No local ${name} was found. Maybe you meant ^${name} for upvar, or !${name} for keyword?`); } this() { return 0; } hasLocal(_name) { return false; } // any symbol symbol(name) { return addString(this._symbols, name); } child(locals) { return new LocalSymbols(this, locals); } } class LocalSymbols { constructor(parent, locals) { this.parent = parent; this.locals = dict(); for (let local of locals) { this.locals[local] = parent.top.symbol(local); } } get paramSymbols() { return values(this.locals); } get top() { return this.parent.top; } freeVar(name) { return this.parent.freeVar(name); } arg(name) { return this.parent.arg(name); } block(name) { return this.parent.block(name); } local(name) { if (name in this.locals) { return this.locals[name]; } else { return this.parent.local(name); } } this() { return this.parent.this(); } hasLocal(name) { if (name in this.locals) { return true; } else { return this.parent.hasLocal(name); } } child(locals) { return new LocalSymbols(this, locals); } } function addString(array, item) { let index = array.indexOf(item); if (index === -1) { index = array.length; array.push(item); return index; } else { return index; } } function unimpl(message) { return new Error(`unimplemented ${message}`); } export function buildStatements(statements, symbols) { let out = []; statements.forEach(s => out.push(...buildStatement(normalizeStatement(s), symbols))); return out; } export function buildNormalizedStatements(statements, symbols) { let out = []; statements.forEach(s => out.push(...buildStatement(s, symbols))); return out; } export function buildStatement(normalized, symbols = new ProgramSymbols()) { switch (normalized.kind) { case "AppendPath" /* AppendPath */ : { return [[normalized.trusted ? 2 /* TrustingAppend */ : 1 /* Append */ , buildGetPath(normalized.path, symbols)]]; } case "AppendExpr" /* AppendExpr */ : { return [[normalized.trusted ? 2 /* TrustingAppend */ : 1 /* Append */ , buildExpression(normalized.expr, normalized.trusted ? 'TrustedAppend' : 'Append', symbols)]]; } case "Call" /* Call */ : { let { head: path, params, hash, trusted } = normalized; let builtParams = params ? buildParams(params, symbols) : null; let builtHash = hash ? buildHash(hash, symbols) : null; let builtExpr = buildCallHead(path, trusted ? 3 /* AmbiguousInvoke */ : 2 /* AmbiguousAppendInvoke */ , symbols); return [[trusted ? 2 /* TrustingAppend */ : 1 /* Append */ , [28 /* Call */ , builtExpr, builtParams, builtHash]]]; } case "Literal" /* Literal */ : { return [[1 /* Append */ , normalized.value]]; } case "Comment" /* Comment */ : { return [[3 /* Comment */ , normalized.value]]; } case "Block" /* Block */ : { let blocks = buildBlocks(normalized.blocks, normalized.blockParams, symbols); let hash = buildHash(normalized.hash, symbols); let params = buildParams(normalized.params, symbols); let path = buildCallHead(normalized.head, 7 /* ResolveAsComponentHead */ , symbols); return [[6 /* Block */ , path, params, hash, blocks]]; } case "Keyword" /* Keyword */ : { return [buildKeyword(normalized, symbols)]; } case "Element" /* Element */ : return buildElement(normalized, symbols); case "Modifier" /* Modifier */ : throw unimpl('modifier'); case "DynamicComponent" /* DynamicComponent */ : throw unimpl('dynamic component'); default: throw assertNever(normalized); } } export function s(arr, ...interpolated) { let result = arr.reduce((result, string, i) => result + `${string}${interpolated[i] ? String(interpolated[i]) : ''}`, ''); return [0 /* Literal */ , result]; } export function c(arr, ...interpolated) { let result = arr.reduce((result, string, i) => result + `${string}${interpolated[i] ? String(interpolated[i]) : ''}`, ''); return [1 /* Comment */ , result]; } export function unicode(charCode) { return String.fromCharCode(parseInt(charCode, 16)); } export const NEWLINE = '\n'; function buildKeyword(normalized, symbols) { let { name } = normalized; let params = buildParams(normalized.params, symbols); let childSymbols = symbols.child(normalized.blockParams || []); let block = buildBlock(normalized.blocks.default, childSymbols, childSymbols.paramSymbols); let inverse = normalized.blocks.else ? buildBlock(normalized.blocks.else, symbols, []) : null; switch (name) { case 'with': return [43 /* With */ , params[0], block, inverse]; case 'if': return [41 /* If */ , params[0], block, inverse]; case 'each': let keyExpr = normalized.hash ? normalized.hash['key'] : null; let key = keyExpr ? buildExpression(keyExpr, 'Strict', symbols) : null; return [42 /* Each */ , params[0], key, block, inverse]; default: throw new Error('unimplemented keyword'); } } function buildElement({ name, attrs, block }, symbols) { let out = [hasSplat(attrs) ? [11 /* OpenElementWithSplat */ , name] : [10 /* OpenElement */ , name]]; if (attrs) { let { params, args } = buildElementParams(attrs, symbols); out.push(...params); (false && assert(args === null, `Can't pass args to a simple element`)); } out.push([12 /* FlushElement */ ]); if (Array.isArray(block)) { block.forEach(s => out.push(...buildStatement(s, symbols))); } else if (block === null) {// do nothing } else { throw assertNever(block); } out.push([13 /* CloseElement */ ]); return out; } function hasSplat(attrs) { if (attrs === null) return false; return Object.keys(attrs).some(a => attrs[a] === "Splat" /* Splat */ ); } export function buildAngleInvocation({ attrs, block, head }, symbols) { let paramList = []; let args = null; let blockList = []; if (attrs) { let built = buildElementParams(attrs, symbols); paramList = built.params; args = built.args; } if (block) blockList = buildNormalizedStatements(block, symbols); return [8 /* Component */ , buildExpression(head, 7 /* ResolveAsComponentHead */ , symbols), isPresent(paramList) ? paramList : null, args, [['default'], [[blockList, []]]]]; } export function buildElementParams(attrs, symbols) { let params = []; let keys = []; let values = []; Object.keys(attrs).forEach(key => { let value = attrs[key]; if (value === "Splat" /* Splat */ ) { params.push([17 /* AttrSplat */ , symbols.block('&attrs')]); } else if (key[0] === '@') { keys.push(key); values.push(buildExpression(value, 'Strict', symbols)); } else { params.push(...buildAttributeValue(key, value, // TODO: extract namespace from key extractNamespace(key), symbols)); } }); return { params, args: isPresent(keys) && isPresent(values) ? [keys, values] : null }; } export function extractNamespace(name) { if (name === 'xmlns') { return "http://www.w3.org/2000/xmlns/" /* XMLNS */ ; } let match = /^([^:]*):([^:]*)$/.exec(name); if (match === null) { return null; } let namespace = match[1]; switch (namespace) { case 'xlink': return "http://www.w3.org/1999/xlink" /* XLink */ ; case 'xml': return "http://www.w3.org/XML/1998/namespace" /* XML */ ; case 'xmlns': return "http://www.w3.org/2000/xmlns/" /* XMLNS */ ; } return null; } export function buildAttributeValue(name, value, namespace, symbols) { switch (value.type) { case "Literal" /* Literal */ : { let val = value.value; if (val === false) { return []; } else if (val === true) { return [[14 /* StaticAttr */ , name, '', namespace !== null && namespace !== void 0 ? namespace : undefined]]; } else if (typeof val === 'string') { return [[14 /* StaticAttr */ , name, val, namespace !== null && namespace !== void 0 ? namespace : undefined]]; } else { throw new Error(`Unexpected/unimplemented literal attribute ${JSON.stringify(val)}`); } } default: return [[15 /* DynamicAttr */ , name, buildExpression(value, 'AttrValue', symbols), namespace !== null && namespace !== void 0 ? namespace : undefined]]; } } function varContext(context, bare) { switch (context) { case 'Append': return bare ? 'AppendBare' : 'AppendInvoke'; case 'TrustedAppend': return bare ? 'TrustedAppendBare' : 'TrustedAppendInvoke'; case 'AttrValue': return bare ? 'AttrValueBare' : 'AttrValueInvoke'; default: return context; } } export function buildExpression(expr, context, symbols) { switch (expr.type) { case "GetPath" /* GetPath */ : { return buildGetPath(expr, symbols); } case "GetVar" /* GetVar */ : { return buildVar(expr.variable, varContext(context, true), symbols); } case "Concat" /* Concat */ : { return [29 /* Concat */ , buildConcat(expr.params, symbols)]; } case "Call" /* Call */ : { let builtParams = buildParams(expr.params, symbols); let builtHash = buildHash(expr.hash, symbols); let builtExpr = buildCallHead(expr.head, context === 'Strict' ? 'SubExpression' : varContext(context, false), symbols); return [28 /* Call */ , builtExpr, builtParams, builtHash]; } case "HasBlock" /* HasBlock */ : { return [48 /* HasBlock */ , buildVar({ kind: VariableKind.Block, name: expr.name, mode: 'loose' }, 0 /* Strict */ , symbols)]; } case "HasBlockParams" /* HasBlockParams */ : { return [49 /* HasBlockParams */ , buildVar({ kind: VariableKind.Block, name: expr.name, mode: 'loose' }, 0 /* Strict */ , symbols)]; } case "Literal" /* Literal */ : { if (expr.value === undefined) { return [27 /* Undefined */ ]; } else { return expr.value; } } default: assertNever(expr); } } export function buildCallHead(callHead, context, symbols) { if (callHead.type === "GetVar" /* GetVar */ ) { return buildVar(callHead.variable, context, symbols); } else { return buildGetPath(callHead, symbols); } } export function buildGetPath(head, symbols) { return buildVar(head.path.head, 0 /* Strict */ , symbols, head.path.tail); } export function buildVar(head, context, symbols, path) { let op = 30 /* GetSymbol */ ; let sym; switch (head.kind) { case VariableKind.Free: if (context === 'Strict') { op = 31 /* GetStrictFree */ ; } else if (context === 'AppendBare') { op = 34 /* GetFreeAsComponentOrHelperHeadOrThisFallback */ ; } else if (context === 'AppendInvoke') { op = 35 /* GetFreeAsComponentOrHelperHead */ ; } else if (context === 'TrustedAppendBare') { op = 36 /* GetFreeAsHelperHeadOrThisFallback */ ; } else if (context === 'TrustedAppendInvoke') { op = 37 /* GetFreeAsHelperHead */ ; } else if (context === 'AttrValueBare') { op = 36 /* GetFreeAsHelperHeadOrThisFallback */ ; } else if (context === 'AttrValueInvoke') { op = 37 /* GetFreeAsHelperHead */ ; } else if (context === 'SubExpression') { op = 37 /* GetFreeAsHelperHead */ ; } else { op = expressionContextOp(context); } sym = symbols.freeVar(head.name); break; default: op = 30 /* GetSymbol */ ; sym = getSymbolForVar(head.kind, symbols, head.name); } if (path === undefined || path.length === 0) { return [op, sym]; } else { return [op, sym, path]; } } function getSymbolForVar(kind, symbols, name) { switch (kind) { case VariableKind.Arg: return symbols.arg(name); case VariableKind.Block: return symbols.block(name); case VariableKind.Local: return symbols.local(name); case VariableKind.This: return symbols.this(); default: return exhausted(kind); } } export function expressionContextOp(context) { switch (context) { case 0 /* Strict */ : return 31 /* GetStrictFree */ ; case 1 /* AmbiguousAppend */ : return 34 /* GetFreeAsComponentOrHelperHeadOrThisFallback */ ; case 2 /* AmbiguousAppendInvoke */ : return 35 /* GetFreeAsComponentOrHelperHead */ ; case 3 /* AmbiguousInvoke */ : return 36 /* GetFreeAsHelperHeadOrThisFallback */ ; case 5 /* ResolveAsCallHead */ : return 37 /* GetFreeAsHelperHead */ ; case 6 /* ResolveAsModifierHead */ : return 38 /* GetFreeAsModifierHead */ ; case 7 /* ResolveAsComponentHead */ : return 39 /* GetFreeAsComponentHead */ ; default: return exhausted(context); } } export function buildParams(exprs, symbols) { if (exprs === null || !isPresent(exprs)) return null; return exprs.map(e => buildExpression(e, 'Strict', symbols)); } export function buildConcat(exprs, symbols) { return exprs.map(e => buildExpression(e, 'AttrValue', symbols)); } export function buildHash(exprs, symbols) { if (exprs === null) return null; let out = [[], []]; Object.keys(exprs).forEach(key => { out[0].push(key); out[1].push(buildExpression(exprs[key], 'Strict', symbols)); }); return out; } export function buildBlocks(blocks, blockParams, parent) { let keys = []; let values = []; Object.keys(blocks).forEach(name => { keys.push(name); if (name === 'default') { let symbols = parent.child(blockParams || []); values.push(buildBlock(blocks[name], symbols, symbols.paramSymbols)); } else { values.push(buildBlock(blocks[name], parent, [])); } }); return [keys, values]; } function buildBlock(block, symbols, locals = []) { return [buildNormalizedStatements(block, symbols), locals]; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL2NvbXBpbGVyL2xpYi9idWlsZGVyL2J1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBVUEsU0FBUyxNQUFULEVBQWlCLFdBQWpCLEVBQThCLElBQTlCLEVBQW9DLFNBQXBDLEVBQXVELFNBQXZELEVBQWtFLE1BQWxFLFFBQWdGLGVBQWhGO0FBR0EsU0FrQkUsa0JBbEJGLEVBb0JFLFlBcEJGLFFBcUJPLHFCQXJCUDtBQXNDQSxPQUFNLE1BQU8sY0FBUCxDQUFxQjtBQUEzQixFQUFBLFdBQUEsR0FBQTtBQUNFLFNBQUEsY0FBQSxHQUEyQixFQUEzQjtBQUNBLFNBQUEsUUFBQSxHQUFxQixDQUFDLE1BQUQsQ0FBckI7QUFFQSxTQUFBLEdBQUEsR0FBTSxJQUFOO0FBNENEOztBQTFDQyxFQUFBLFNBQVMsR0FBQTtBQUNQLFdBQU8sS0FBSyxRQUFMLENBQWMsS0FBZCxDQUFvQixDQUFwQixDQUFQO0FBQ0Q7O0FBRUQsRUFBQSxRQUFRLEdBQUE7QUFDTixXQUFPLEtBQUssY0FBWjtBQUNEOztBQUVELEVBQUEsT0FBTyxDQUFDLElBQUQsRUFBYTtBQUNsQixXQUFPLFNBQVMsQ0FBQyxLQUFLLGNBQU4sRUFBc0IsSUFBdEIsQ0FBaEI7QUFDRDs7QUFFRCxFQUFBLEtBQUssQ0FBQyxJQUFELEVBQWE7QUFDaEIsV0FBTyxLQUFLLE1BQUwsQ0FBWSxJQUFaLENBQVA7QUFDRDs7QUFFRCxFQUFBLEdBQUcsQ0FBQyxJQUFELEVBQWE7QUFDZCxXQUFPLFNBQVMsQ0FBQyxLQUFLLFFBQU4sRUFBZ0IsSUFBaEIsQ0FBaEI7QUFDRDs7QUFFRCxFQUFBLEtBQUssQ0FBQyxJQUFELEVBQWE7QUFDaEIsVUFBTSxJQUFJLEtBQUosQ0FDSixZQUFZLElBQUksZ0NBQWdDLElBQUksbUJBQW1CLElBQUksZUFEdkUsQ0FBTjtBQUdEOztBQUVELEVBQUEsSUFBSSxHQUFBO0FBQ0YsV0FBTyxDQUFQO0FBQ0Q7O0FB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QUNMLE1BQUEsTUFBTSxDQUFDLElBQVAsQ0FBWSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUQsQ0FBUCxFQUFlLE1BQWYsRUFBdUIsRUFBdkIsQ0FBdEI7QUFDRDtBQUNGLEdBVkQ7QUFZQSxTQUFPLENBQUMsSUFBRCxFQUFPLE1BQVAsQ0FBUDtBQUNEOztBQUVELFNBQVMsVUFBVCxDQUNFLEtBREYsRUFFRSxPQUZGLEVBR0UsTUFBQSxHQUFtQixFQUhyQixFQUd1QjtBQUVyQixTQUFPLENBQUMseUJBQXlCLENBQUMsS0FBRCxFQUFRLE9BQVIsQ0FBMUIsRUFBNEMsTUFBNUMsQ0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRGljdCxcbiAgRXhwcmVzc2lvbnMsXG4gIEdldENvbnRleHR1YWxGcmVlT3AsXG4gIE9wdGlvbixcbiAgUHJlc2VudEFycmF5LFxuICBTZXhwT3Bjb2RlcyxcbiAgVmFyaWFibGVSZXNvbHV0aW9uQ29udGV4dCxcbiAgV2lyZUZvcm1hdCxcbn0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBhc3NlcnQsIGFzc2VydE5ldmVyLCBkaWN0LCBleGhhdXN0ZWQsIGV4cGVjdCwgaXNQcmVzZW50LCB2YWx1ZXMgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcbmltcG9ydCB7IEF0dHJOYW1lc3BhY2UsIE5hbWVzcGFjZSB9IGZyb20gJ0BzaW1wbGUtZG9tL2ludGVyZmFjZSc7XG5cbmltcG9ydCB7XG4gIEJ1aWxkZXIsXG4gIEJ1aWxkZXJDb21tZW50LFxuICBCdWlsZGVyU3RhdGVtZW50LFxuICBFeHByZXNzaW9uS2luZCxcbiAgSGVhZEtpbmQsXG4gIE5vcm1hbGl6ZWRBbmdsZUludm9jYXRpb24sXG4gIE5vcm1hbGl6ZWRBdHRycyxcbiAgTm9ybWFsaXplZEJsb2NrLFxuICBOb3JtYWxpemVkQmxvY2tzLFxuICBOb3JtYWxpemVkRWxlbWVudCxcbiAgTm9ybWFsaXplZEV4cHJlc3Npb24sXG4gIE5vcm1hbGl6ZWRIYXNoLFxuICBOb3JtYWxpemVkSGVhZCxcbiAgTm9ybWFsaXplZEtleXdvcmRTdGF0ZW1lbnQsXG4gIE5vcm1hbGl6ZWRQYXJhbXMsXG4gIE5vcm1hbGl6ZWRQYXRoLFxuICBOb3JtYWxpemVkU3RhdGVtZW50LFxuICBub3JtYWxpemVTdGF0ZW1lbnQsXG4gIFZhcmlhYmxlLFxuICBWYXJpYWJsZUtpbmQsXG59IGZyb20gJy4vYnVpbGRlci1pbnRlcmZhY2UnO1xuXG5pbXBvcnQgT3AgPSBXaXJlRm9ybWF0LlNleHBPcGNvZGVzO1xuXG5pbnRlcmZhY2UgU3ltYm9scyB7XG4gIHRvcDogUHJvZ3JhbVN5bWJvbHM7XG4gIGZyZWVWYXIobmFtZTogc3RyaW5nKTogbnVtYmVyO1xuICBhcmcobmFtZTogc3RyaW5nKTogbnVtYmVyO1xuICBibG9jayhuYW1lOiBzdHJpbmcpOiBudW1iZXI7XG4gIGxvY2FsKG5hbWU6IHN0cmluZyk6IG51bWJlcjtcbiAgdGhpcygpOiBudW1iZXI7XG5cbiAgaGFzTG9jYWwobmFtZTogc3RyaW5nKTogYm9vbGVhbjtcblxuICBjaGlsZChwYXJhbXM6IHN0cmluZ1tdKTogTG9jYWxTeW1ib2xzO1xufVxuXG5leHBvcnQgY2xhc3MgUHJvZ3JhbVN5bWJvbHMgaW1wbGVtZW50cyBTeW1ib2xzIHtcbiAgX2ZyZWVWYXJpYWJsZXM6IHN0cmluZ1tdID0gW107XG4gIF9zeW1ib2xzOiBzdHJpbmdbXSA9IFsndGhpcyddO1xuXG4gIHRvcCA9IHRoaXM7XG5cbiAgdG9TeW1ib2xzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fc3ltYm9scy5zbGljZSgxKTtcbiAgfVxuXG4gIHRvVXB2YXJzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fZnJlZVZhcmlhYmxlcztcbiAgfVxuXG4gIGZyZWVWYXIobmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gYWRkU3RyaW5nKHRoaXMuX2ZyZWVWYXJpYWJsZXMsIG5hbWUpO1xuICB9XG5cbiAgYmxvY2sobmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zeW1ib2wobmFtZSk7XG4gIH1cblxuICBhcmcobmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gYWRkU3RyaW5nKHRoaXMuX3N5bWJvbHMsIG5hbWUpO1xuICB9XG5cbiAgbG9jYWwobmFtZTogc3RyaW5nKTogbmV2ZXIge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBObyBsb2NhbCAke25hbWV9IHdhcyBmb3VuZC4gTWF5YmUgeW91IG1lYW50IF4ke25hbWV9IGZvciB1cHZhciwgb3IgISR7bmFtZX0gZm9yIGtleXdvcmQ/YFxuICAgICk7XG4gIH1cblxuICB0aGlzKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBoYXNMb2NhbChfbmFtZTogc3RyaW5nKTogZmFsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGFueSBzeW1ib2xcbiAgc3ltYm9sKG5hbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIGFkZFN0cmluZyh0aGlzLl9zeW1ib2xzLCBuYW1lKTtcbiAgfVxuXG4gIGNoaWxkKGxvY2Fsczogc3RyaW5nW10pOiBMb2NhbFN5bWJvbHMge1xuICAgIHJldHVybiBuZXcgTG9jYWxTeW1ib2xzKHRoaXMsIGxvY2Fscyk7XG4gIH1cbn1cblxuY2xhc3MgTG9jYWxTeW1ib2xzIGltcGxlbWVudHMgU3ltYm9scyB7XG4gIHByaXZhdGUgbG9jYWxzOiBEaWN0PG51bWJlcj4gPSBkaWN0KCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBwYXJlbnQ6IFN5bWJvbHMsIGxvY2Fsczogc3RyaW5nW10pIHtcbiAgICBmb3IgKGxldCBsb2NhbCBvZiBsb2NhbHMpIHtcbiAgICAgIHRoaXMubG9jYWxzW2xvY2FsXSA9IHBhcmVudC50b3Auc3ltYm9sKGxvY2FsKTtcbiAgICB9XG4gIH1cblxuICBnZXQgcGFyYW1TeW1ib2xzKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gdmFsdWVzKHRoaXMubG9jYWxzKTtcbiAgfVxuXG4gIGdldCB0b3AoKTogUHJvZ3JhbVN5bWJvbHMge1xuICAgIHJldHVybiB0aGlzLnBhcmVudC50b3A7XG4gIH1cblxuICBmcmVlVmFyKG5hbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50LmZyZWVWYXIobmFtZSk7XG4gIH1cblxuICBhcmcobmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQuYXJnKG5hbWUpO1xuICB9XG5cbiAgYmxvY2sobmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQuYmxvY2sobmFtZSk7XG4gIH1cblxuICBsb2NhbChuYW1lOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGlmIChuYW1lIGluIHRoaXMubG9jYWxzKSB7XG4gICAgICByZXR1cm4gdGhpcy5sb2NhbHNbbmFtZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnBhcmVudC5sb2NhbChuYW1lKTtcbiAgICB9XG4gIH1cblxuICB0aGlzKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50LnRoaXMoKTtcbiAgfVxuXG4gIGhhc0xvY2FsKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmIChuYW1lIGluIHRoaXMubG9jYWxzKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMucGFyZW50Lmhhc0xvY2FsKG5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIGNoaWxkKGxvY2Fsczogc3RyaW5nW10pOiBMb2NhbFN5bWJvbHMge1xuICAgIHJldHVybiBuZXcgTG9jYWxTeW1ib2xzKHRoaXMsIGxvY2Fscyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkU3RyaW5nKGFycmF5OiBzdHJpbmdbXSwgaXRlbTogc3RyaW5nKTogbnVtYmVyIHtcbiAgbGV0IGluZGV4ID0gYXJyYXkuaW5kZXhPZihpdGVtKTtcblxuICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgaW5kZXggPSBhcnJheS5sZW5ndGg7XG4gICAgYXJyYXkucHVzaChpdGVtKTtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbGRlckdldEZyZWUge1xuICB0eXBlOiAnR2V0RnJlZSc7XG4gIGhlYWQ6IHN0cmluZztcbiAgdGFpbDogc3RyaW5nW107XG59XG5cbmZ1bmN0aW9uIHVuaW1wbChtZXNzYWdlOiBzdHJpbmcpOiBFcnJvciB7XG4gIHJldHVybiBuZXcgRXJyb3IoYHVuaW1wbGVtZW50ZWQgJHttZXNzYWdlfWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRTdGF0ZW1lbnRzKFxuICBzdGF0ZW1lbnRzOiBCdWlsZGVyU3RhdGVtZW50W10sXG4gIHN5bWJvbHM6IFN5bWJvbHNcbik6IFdpcmVGb3JtYXQuU3RhdGVtZW50W10ge1xuICBsZXQgb3V0OiBXaXJlRm9ybWF0LlN0YXRlbWVudFtdID0gW107XG5cbiAgc3RhdGVtZW50cy5mb3JFYWNoKChzKSA9PiBvdXQucHVzaCguLi5idWlsZFN0YXRlbWVudChub3JtYWxpemVTdGF0ZW1lbnQocyksIHN5bWJvbHMpKSk7XG5cbiAgcmV0dXJuIG91dDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkTm9ybWFsaXplZFN0YXRlbWVudHMoXG4gIHN0YXRlbWVudHM6IE5vcm1hbGl6ZWRTdGF0ZW1lbnRbXSxcbiAgc3ltYm9sczogU3ltYm9sc1xuKTogV2lyZUZvcm1hdC5TdGF0ZW1lbnRbXSB7XG4gIGxldCBvdXQ6IFdpcmVGb3JtYXQuU3RhdGVtZW50W10gPSBbXTtcblxuICBzdGF0ZW1lbnRzLmZvckVhY2goKHMpID0+IG91dC5wdXNoKC4uLmJ1aWxkU3RhdGVtZW50KHMsIHN5bWJvbHMpKSk7XG5cbiAgcmV0dXJuIG91dDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkU3RhdGVtZW50KFxuICBub3JtYWxpemVkOiBOb3JtYWxpemVkU3RhdGVtZW50LFxuICBzeW1ib2xzOiBTeW1ib2xzID0gbmV3IFByb2dyYW1TeW1ib2xzKClcbik6IFdpcmVGb3JtYXQuU3RhdGVtZW50W10ge1xuICBzd2l0Y2ggKG5vcm1hbGl6ZWQua2luZCkge1xuICAgIGNhc2UgSGVhZEtpbmQuQXBwZW5kUGF0aDoge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAgW1xuICAgICAgICAgIG5vcm1hbGl6ZWQudHJ1c3RlZCA/IE9wLlRydXN0aW5nQXBwZW5kIDogT3AuQXBwZW5kLFxuICAgICAgICAgIGJ1aWxkR2V0UGF0aChub3JtYWxpemVkLnBhdGgsIHN5bWJvbHMpLFxuICAgICAgICBdLFxuICAgICAgXTtcbiAgICB9XG5cbiAgICBjYXNlIEhlYWRLaW5kLkFwcGVuZEV4cHI6IHtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIFtcbiAgICAgICAgICBub3JtYWxpemVkLnRydXN0ZWQgPyBPcC5UcnVzdGluZ0FwcGVuZCA6IE9wLkFwcGVuZCxcbiAgICAgICAgICBidWlsZEV4cHJlc3Npb24oXG4gICAgICAgICAgICBub3JtYWxpemVkLmV4cHIsXG4gICAgICAgICAgICBub3JtYWxpemVkLnRydXN0ZWQgPyAnVHJ1c3RlZEFwcGVuZCcgOiAnQXBwZW5kJyxcbiAgICAgICAgICAgIHN5bWJvbHNcbiAgICAgICAgICApLFxuICAgICAgICBdLFxuICAgICAgXTtcbiAgICB9XG5cbiAgICBjYXNlIEhlYWRLaW5kLkNhbGw6IHtcbiAgICAgIGxldCB7IGhlYWQ6IHBhdGgsIHBhcmFtcywgaGFzaCwgdHJ1c3RlZCB9ID0gbm9ybWFsaXplZDtcbiAgICAgIGxldCBidWlsdFBhcmFtczogT3B0aW9uPFdpcmVGb3JtYXQuQ29yZS5QYXJhbXM+ID0gcGFyYW1zXG4gICAgICAgID8gYnVpbGRQYXJhbXMocGFyYW1zLCBzeW1ib2xzKVxuICAgICAgICA6IG51bGw7XG4gICAgICBsZXQgYnVpbHRIYXNoOiBXaXJlRm9ybWF0LkNvcmUuSGFzaCA9IGhhc2ggPyBidWlsZEhhc2goaGFzaCwgc3ltYm9scykgOiBudWxsO1xuICAgICAgbGV0IGJ1aWx0RXhwcjogV2lyZUZvcm1hdC5FeHByZXNzaW9uID0gYnVpbGRDYWxsSGVhZChcbiAgICAgICAgcGF0aCxcbiAgICAgICAgdHJ1c3RlZFxuICAgICAgICAgID8gVmFyaWFibGVSZXNvbHV0aW9uQ29udGV4dC5BbWJpZ3VvdXNJbnZva2VcbiAgICAgICAgICA6IFZhcmlhYmxlUmVzb2x1dGlvbkNvbnRleHQuQW1iaWd1b3VzQXBwZW5kSW52b2tlLFxuICAgICAgICBzeW1ib2xzXG4gICAgICApO1xuXG4gICAgICByZXR1cm4gW1xuICAgICAgICBbdHJ1c3RlZCA/IE9wLlRydXN0aW5nQXBwZW5kIDogT3AuQXBwZW5kLCBbT3AuQ2FsbCwgYnVpbHRFeHByLCBidWlsdFBhcmFtcywgYnVpbHRIYXNoXV0sXG4gICAgICBdO1xuICAgIH1cblxuICAgIGNhc2UgSGVhZEtpbmQuTGl0ZXJhbDoge1xuICAgICAgcmV0dXJuIFtbT3AuQXBwZW5kLCBub3JtYWxpemVkLnZhbHVlXV07XG4gICAgfVxuXG4gICAgY2FzZSBIZWFkS2luZC5Db21tZW50OiB7XG4gICAgICByZXR1cm4gW1tPcC5Db21tZW50LCBub3JtYWxpemVkLnZhbHVlXV07XG4gICAgfVxuXG4gICAgY2FzZSBIZWFkS2luZC5CbG9jazoge1xuICAgICAgbGV0IGJsb2NrcyA9IGJ1aWxkQmxvY2tzKG5vcm1hbGl6ZWQuYmxvY2tzLCBub3JtYWxpemVkLmJsb2NrUGFyYW1zLCBzeW1ib2xzKTtcbiAgICAgIGxldCBoYXNoID0gYnVpbGRIYXNoKG5vcm1hbGl6ZWQuaGFzaCwgc3ltYm9scyk7XG4gICAgICBsZXQgcGFyYW1zID0gYnVpbGRQYXJhbXMobm9ybWFsaXplZC5wYXJhbXMsIHN5bWJvbHMpO1xuICAgICAgbGV0IHBhdGggPSBidWlsZENhbGxIZWFkKFxuICAgICAgICBub3JtYWxpemVkLmhlYWQsXG4gICAgICAgIFZhcmlhYmxlUmVzb2x1dGlvbkNvbnRleHQuUmVzb2x2ZUFzQ29tcG9uZW50SGVhZCxcbiAgICAgICAgc3ltYm9sc1xuICAgICAgKTtcblxuICAgICAgcmV0dXJuIFtbT3AuQmxvY2ssIHBhdGgsIHBhcmFtcywgaGFzaCwgYmxvY2tzXV07XG4gICAgfVxuXG4gICAgY2FzZSBIZWFkS2luZC5LZXl3b3JkOiB7XG4gICAgICByZXR1cm4gW2J1aWxkS2V5d29yZChub3JtYWxpemVkLCBzeW1ib2xzKV07XG4gICAgfVxuXG4gICAgY2FzZSBIZWFkS2luZC5FbGVtZW50OlxuICAgICAgcmV0dXJuIGJ1aWxkRWxlbWVudChub3JtYWxpemVkLCBzeW1ib2xzKTtcblxuICAgIGNhc2UgSGVhZEtpbmQuTW9kaWZpZXI6XG4gICAgICB0aHJvdyB1bmltcGwoJ21vZGlmaWVyJyk7XG5cbiAgICBjYXNlIEhlYWRLaW5kLkR5bmFtaWNDb21wb25lbnQ6XG4gICAgICB0aHJvdyB1bmltcGwoJ2R5bmFtaWMgY29tcG9uZW50Jyk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgYXNzZXJ0TmV2ZXIobm9ybWFsaXplZCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHMoXG4gIGFycjogVGVtcGxhdGVTdHJpbmdzQXJyYXksXG4gIC4uLmludGVycG9sYXRlZDogdW5rbm93bltdXG4pOiBbQnVpbGRlci5MaXRlcmFsLCBzdHJpbmddIHtcbiAgbGV0IHJlc3VsdCA9IGFyci5yZWR1Y2UoXG4gICAgKHJlc3VsdCwgc3RyaW5nLCBpKSA9PiByZXN1bHQgKyBgJHtzdHJpbmd9JHtpbnRlcnBvbGF0ZWRbaV0gPyBTdHJpbmcoaW50ZXJwb2xhdGVkW2ldKSA6ICcnfWAsXG4gICAgJydcbiAgKTtcblxuICByZXR1cm4gW0J1aWxkZXIuTGl0ZXJhbCwgcmVzdWx0XTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGMoYXJyOiBUZW1wbGF0ZVN0cmluZ3NBcnJheSwgLi4uaW50ZXJwb2xhdGVkOiB1bmtub3duW10pOiBCdWlsZGVyQ29tbWVudCB7XG4gIGxldCByZXN1bHQgPSBhcnIucmVkdWNlKFxuICAgIChyZXN1bHQsIHN0cmluZywgaSkgPT4gcmVzdWx0ICsgYCR7c3RyaW5nfSR7aW50ZXJwb2xhdGVkW2ldID8gU3RyaW5nKGludGVycG9sYXRlZFtpXSkgOiAnJ31gLFxuICAgICcnXG4gICk7XG5cbiAgcmV0dXJuIFtCdWlsZGVyLkNvbW1lbnQsIHJlc3VsdF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bmljb2RlKGNoYXJDb2RlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChjaGFyQ29kZSwgMTYpKTtcbn1cblxuZXhwb3J0IGNvbnN0IE5FV0xJTkUgPSAnXFxuJztcblxuZnVuY3Rpb24gYnVpbGRLZXl3b3JkKFxuICBub3JtYWxpemVkOiBOb3JtYWxpemVkS2V5d29yZFN0YXRlbWVudCxcbiAgc3ltYm9sczogU3ltYm9sc1xuKTogV2lyZUZvcm1hdC5TdGF0ZW1lbnQge1xuICBsZXQgeyBuYW1lIH0gPSBub3JtYWxpemVkO1xuICBsZXQgcGFyYW1zID0gYnVpbGRQYXJhbXMobm9ybWFsaXplZC5wYXJhbXMsIHN5bWJvbHMpO1xuICBsZXQgY2hpbGRTeW1ib2xzID0gc3ltYm9scy5jaGlsZChub3JtYWxpemVkLmJsb2NrUGFyYW1zIHx8IFtdKTtcblxuICBsZXQgYmxvY2sgPSBidWlsZEJsb2NrKG5vcm1hbGl6ZWQuYmxvY2tzLmRlZmF1bHQsIGNoaWxkU3ltYm9scywgY2hpbGRTeW1ib2xzLnBhcmFtU3ltYm9scyk7XG4gIGxldCBpbnZlcnNlID0gbm9ybWFsaXplZC5ibG9ja3MuZWxzZSA/IGJ1aWxkQmxvY2sobm9ybWFsaXplZC5ibG9ja3MuZWxzZSwgc3ltYm9scywgW10pIDogbnVsbDtcblxuICBzd2l0Y2ggKG5hbWUpIHtcbiAgICBjYXNlICd3aXRoJzpcbiAgICAgIHJldHVybiBbT3AuV2l0aCwgZXhwZWN0KHBhcmFtcywgJ3dpdGggcmVxdWlyZXMgcGFyYW1zJylbMF0sIGJsb2NrLCBpbnZlcnNlXTtcbiAgICBjYXNlICdpZic6XG4gICAgICByZXR1cm4gW09wLklmLCBleHBlY3QocGFyYW1zLCAnaWYgcmVxdWlyZXMgcGFyYW1zJylbMF0sIGJsb2NrLCBpbnZlcnNlXTtcbiAgICBjYXNlICdlYWNoJzpcbiAgICAgIGxldCBrZXlFeHByID0gbm9ybWFsaXplZC5oYXNoID8gbm9ybWFsaXplZC5oYXNoWydrZXknXSA6IG51bGw7XG4gICAgICBsZXQga2V5ID0ga2V5RXhwciA/IGJ1aWxkRXhwcmVzc2lvbihrZXlFeHByLCAnU3RyaWN0Jywgc3ltYm9scykgOiBudWxsO1xuXG4gICAgICByZXR1cm4gW09wLkVhY2gsIGV4cGVjdChwYXJhbXMsICdpZiByZXF1aXJlcyBwYXJhbXMnKVswXSwga2V5LCBibG9jaywgaW52ZXJzZV07XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5pbXBsZW1lbnRlZCBrZXl3b3JkJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYnVpbGRFbGVtZW50KFxuICB7IG5hbWUsIGF0dHJzLCBibG9jayB9OiBOb3JtYWxpemVkRWxlbWVudCxcbiAgc3ltYm9sczogU3ltYm9sc1xuKTogV2lyZUZvcm1hdC5TdGF0ZW1lbnRbXSB7XG4gIGxldCBvdXQ6IFdpcmVGb3JtYXQuU3RhdGVtZW50W10gPSBbXG4gICAgaGFzU3BsYXQoYXR0cnMpID8gW09wLk9wZW5FbGVtZW50V2l0aFNwbGF0LCBuYW1lXSA6IFtPcC5PcGVuRWxlbWVudCwgbmFtZV0sXG4gIF07XG4gIGlmIChhdHRycykge1xuICAgIGxldCB7IHBhcmFtcywgYXJncyB9ID0gYnVpbGRFbGVtZW50UGFyYW1zKGF0dHJzLCBzeW1ib2xzKTtcbiAgICBvdXQucHVzaCguLi5wYXJhbXMpO1xuICAgIGFzc2VydChhcmdzID09PSBudWxsLCBgQ2FuJ3QgcGFzcyBhcmdzIHRvIGEgc2ltcGxlIGVsZW1lbnRgKTtcbiAgfVxuICBvdXQucHVzaChbT3AuRmx1c2hFbGVtZW50XSk7XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoYmxvY2spKSB7XG4gICAgYmxvY2suZm9yRWFjaCgocykgPT4gb3V0LnB1c2goLi4uYnVpbGRTdGF0ZW1lbnQocywgc3ltYm9scykpKTtcbiAgfSBlbHNlIGlmIChibG9jayA9PT0gbnVsbCkge1xuICAgIC8vIGRvIG5vdGhpbmdcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBhc3NlcnROZXZlcihibG9jayk7XG4gIH1cblxuICBvdXQucHVzaChbT3AuQ2xvc2VFbGVtZW50XSk7XG5cbiAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gaGFzU3BsYXQoYXR0cnM6IE9wdGlvbjxOb3JtYWxpemVkQXR0cnM+KTogYm9vbGVhbiB7XG4gIGlmIChhdHRycyA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuXG4gIHJldHVybiBPYmplY3Qua2V5cyhhdHRycykuc29tZSgoYSkgPT4gYXR0cnNbYV0gPT09IEhlYWRLaW5kLlNwbGF0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQW5nbGVJbnZvY2F0aW9uKFxuICB7IGF0dHJzLCBibG9jaywgaGVhZCB9OiBOb3JtYWxpemVkQW5nbGVJbnZvY2F0aW9uLFxuICBzeW1ib2xzOiBTeW1ib2xzXG4pOiBXaXJlRm9ybWF0LlN0YXRlbWVudHMuQ29tcG9uZW50IHtcbiAgbGV0IHBhcmFtTGlzdDogV2lyZUZvcm1hdC5FbGVtZW50UGFyYW1ldGVyW10gPSBbXTtcbiAgbGV0IGFyZ3M6IFdpcmVGb3JtYXQuQ29yZS5IYXNoID0gbnVsbDtcbiAgbGV0IGJsb2NrTGlzdDogV2lyZUZvcm1hdC5TdGF0ZW1lbnRbXSA9IFtdO1xuXG4gIGlmIChhdHRycykge1xuICAgIGxldCBidWlsdCA9IGJ1aWxkRWxlbWVudFBhcmFtcyhhdHRycywgc3ltYm9scyk7XG4gICAgcGFyYW1MaXN0ID0gYnVpbHQucGFyYW1zO1xuICAgIGFyZ3MgPSBidWlsdC5hcmdzO1xuICB9XG5cbiAgaWYgKGJsb2NrKSBibG9ja0xpc3QgPSBidWlsZE5vcm1hbGl6ZWRTdGF0ZW1lbnRzKGJsb2NrLCBzeW1ib2xzKTtcblxuICByZXR1cm4gW1xuICAgIE9wLkNvbXBvbmVudCxcbiAgICBidWlsZEV4cHJlc3Npb24oaGVhZCwgVmFyaWFibGVSZXNvbHV0aW9uQ29udGV4dC5SZXNvbHZlQXNDb21wb25lbnRIZWFkLCBzeW1ib2xzKSxcbiAgICBpc1ByZXNlbnQocGFyYW1MaXN0KSA/IHBhcmFtTGlzdCA6IG51bGwsXG4gICAgYXJncyxcbiAgICBbWydkZWZhdWx0J10sIFtbYmxvY2tMaXN0LCBbXV1dXSxcbiAgXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkRWxlbWVudFBhcmFtcyhcbiAgYXR0cnM6IE5vcm1hbGl6ZWRBdHRycyxcbiAgc3ltYm9sczogU3ltYm9sc1xuKTogeyBwYXJhbXM6IFdpcmVGb3JtYXQuRWxlb