@glimmer/compiler
Version:
733 lines (640 loc) • 63.1 kB
JavaScript
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