printer.js 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. import { escapeAttrValue, escapeText, sortByLoc } from './util';
  2. export const voidMap = Object.create(null);
  3. let voidTagNames = 'area base br col command embed hr img input keygen link meta param source track wbr';
  4. voidTagNames.split(' ').forEach(tagName => {
  5. voidMap[tagName] = true;
  6. });
  7. const NON_WHITESPACE = /\S/;
  8. export default class Printer {
  9. constructor(options) {
  10. this.buffer = '';
  11. this.options = options;
  12. }
  13. /*
  14. This is used by _all_ methods on this Printer class that add to `this.buffer`,
  15. it allows consumers of the printer to use alternate string representations for
  16. a given node.
  17. The primary use case for this are things like source -> source codemod utilities.
  18. For example, ember-template-recast attempts to always preserve the original string
  19. formatting in each AST node if no modifications are made to it.
  20. */
  21. handledByOverride(node, ensureLeadingWhitespace = false) {
  22. if (this.options.override !== undefined) {
  23. let result = this.options.override(node, this.options);
  24. if (typeof result === 'string') {
  25. if (ensureLeadingWhitespace && result !== '' && NON_WHITESPACE.test(result[0])) {
  26. result = ` ${result}`;
  27. }
  28. this.buffer += result;
  29. return true;
  30. }
  31. }
  32. return false;
  33. }
  34. Node(node) {
  35. switch (node.type) {
  36. case 'MustacheStatement':
  37. case 'BlockStatement':
  38. case 'PartialStatement':
  39. case 'MustacheCommentStatement':
  40. case 'CommentStatement':
  41. case 'TextNode':
  42. case 'ElementNode':
  43. case 'AttrNode':
  44. case 'Block':
  45. case 'Template':
  46. return this.TopLevelStatement(node);
  47. case 'StringLiteral':
  48. case 'BooleanLiteral':
  49. case 'NumberLiteral':
  50. case 'UndefinedLiteral':
  51. case 'NullLiteral':
  52. case 'PathExpression':
  53. case 'SubExpression':
  54. return this.Expression(node);
  55. case 'Program':
  56. return this.Block(node);
  57. case 'ConcatStatement':
  58. // should have an AttrNode parent
  59. return this.ConcatStatement(node);
  60. case 'Hash':
  61. return this.Hash(node);
  62. case 'HashPair':
  63. return this.HashPair(node);
  64. case 'ElementModifierStatement':
  65. return this.ElementModifierStatement(node);
  66. }
  67. }
  68. Expression(expression) {
  69. switch (expression.type) {
  70. case 'StringLiteral':
  71. case 'BooleanLiteral':
  72. case 'NumberLiteral':
  73. case 'UndefinedLiteral':
  74. case 'NullLiteral':
  75. return this.Literal(expression);
  76. case 'PathExpression':
  77. return this.PathExpression(expression);
  78. case 'SubExpression':
  79. return this.SubExpression(expression);
  80. }
  81. }
  82. Literal(literal) {
  83. switch (literal.type) {
  84. case 'StringLiteral':
  85. return this.StringLiteral(literal);
  86. case 'BooleanLiteral':
  87. return this.BooleanLiteral(literal);
  88. case 'NumberLiteral':
  89. return this.NumberLiteral(literal);
  90. case 'UndefinedLiteral':
  91. return this.UndefinedLiteral(literal);
  92. case 'NullLiteral':
  93. return this.NullLiteral(literal);
  94. }
  95. }
  96. TopLevelStatement(statement) {
  97. switch (statement.type) {
  98. case 'MustacheStatement':
  99. return this.MustacheStatement(statement);
  100. case 'BlockStatement':
  101. return this.BlockStatement(statement);
  102. case 'PartialStatement':
  103. return this.PartialStatement(statement);
  104. case 'MustacheCommentStatement':
  105. return this.MustacheCommentStatement(statement);
  106. case 'CommentStatement':
  107. return this.CommentStatement(statement);
  108. case 'TextNode':
  109. return this.TextNode(statement);
  110. case 'ElementNode':
  111. return this.ElementNode(statement);
  112. case 'Block':
  113. case 'Template':
  114. return this.Block(statement);
  115. case 'AttrNode':
  116. // should have element
  117. return this.AttrNode(statement);
  118. }
  119. }
  120. Block(block) {
  121. /*
  122. When processing a template like:
  123. ```hbs
  124. {{#if whatever}}
  125. whatever
  126. {{else if somethingElse}}
  127. something else
  128. {{else}}
  129. fallback
  130. {{/if}}
  131. ```
  132. The AST still _effectively_ looks like:
  133. ```hbs
  134. {{#if whatever}}
  135. whatever
  136. {{else}}{{#if somethingElse}}
  137. something else
  138. {{else}}
  139. fallback
  140. {{/if}}{{/if}}
  141. ```
  142. The only way we can tell if that is the case is by checking for
  143. `block.chained`, but unfortunately when the actual statements are
  144. processed the `block.body[0]` node (which will always be a
  145. `BlockStatement`) has no clue that its ancestor `Block` node was
  146. chained.
  147. This "forwards" the `chained` setting so that we can check
  148. it later when processing the `BlockStatement`.
  149. */
  150. if (block.chained) {
  151. let firstChild = block.body[0];
  152. firstChild.chained = true;
  153. }
  154. if (this.handledByOverride(block)) {
  155. return;
  156. }
  157. this.TopLevelStatements(block.body);
  158. }
  159. TopLevelStatements(statements) {
  160. statements.forEach(statement => this.TopLevelStatement(statement));
  161. }
  162. ElementNode(el) {
  163. if (this.handledByOverride(el)) {
  164. return;
  165. }
  166. this.OpenElementNode(el);
  167. this.TopLevelStatements(el.children);
  168. this.CloseElementNode(el);
  169. }
  170. OpenElementNode(el) {
  171. this.buffer += `<${el.tag}`;
  172. const parts = [...el.attributes, ...el.modifiers, ...el.comments].sort(sortByLoc);
  173. for (const part of parts) {
  174. this.buffer += ' ';
  175. switch (part.type) {
  176. case 'AttrNode':
  177. this.AttrNode(part);
  178. break;
  179. case 'ElementModifierStatement':
  180. this.ElementModifierStatement(part);
  181. break;
  182. case 'MustacheCommentStatement':
  183. this.MustacheCommentStatement(part);
  184. break;
  185. }
  186. }
  187. if (el.blockParams.length) {
  188. this.BlockParams(el.blockParams);
  189. }
  190. if (el.selfClosing) {
  191. this.buffer += ' /';
  192. }
  193. this.buffer += '>';
  194. }
  195. CloseElementNode(el) {
  196. if (el.selfClosing || voidMap[el.tag.toLowerCase()]) {
  197. return;
  198. }
  199. this.buffer += `</${el.tag}>`;
  200. }
  201. AttrNode(attr) {
  202. if (this.handledByOverride(attr)) {
  203. return;
  204. }
  205. let {
  206. name,
  207. value
  208. } = attr;
  209. this.buffer += name;
  210. if (value.type !== 'TextNode' || value.chars.length > 0) {
  211. this.buffer += '=';
  212. this.AttrNodeValue(value);
  213. }
  214. }
  215. AttrNodeValue(value) {
  216. if (value.type === 'TextNode') {
  217. this.buffer += '"';
  218. this.TextNode(value, true);
  219. this.buffer += '"';
  220. } else {
  221. this.Node(value);
  222. }
  223. }
  224. TextNode(text, isAttr) {
  225. if (this.handledByOverride(text)) {
  226. return;
  227. }
  228. if (this.options.entityEncoding === 'raw') {
  229. this.buffer += text.chars;
  230. } else if (isAttr) {
  231. this.buffer += escapeAttrValue(text.chars);
  232. } else {
  233. this.buffer += escapeText(text.chars);
  234. }
  235. }
  236. MustacheStatement(mustache) {
  237. if (this.handledByOverride(mustache)) {
  238. return;
  239. }
  240. this.buffer += mustache.escaped ? '{{' : '{{{';
  241. if (mustache.strip.open) {
  242. this.buffer += '~';
  243. }
  244. this.Expression(mustache.path);
  245. this.Params(mustache.params);
  246. this.Hash(mustache.hash);
  247. if (mustache.strip.close) {
  248. this.buffer += '~';
  249. }
  250. this.buffer += mustache.escaped ? '}}' : '}}}';
  251. }
  252. BlockStatement(block) {
  253. if (this.handledByOverride(block)) {
  254. return;
  255. }
  256. if (block.chained) {
  257. this.buffer += block.inverseStrip.open ? '{{~' : '{{';
  258. this.buffer += 'else ';
  259. } else {
  260. this.buffer += block.openStrip.open ? '{{~#' : '{{#';
  261. }
  262. this.Expression(block.path);
  263. this.Params(block.params);
  264. this.Hash(block.hash);
  265. if (block.program.blockParams.length) {
  266. this.BlockParams(block.program.blockParams);
  267. }
  268. if (block.chained) {
  269. this.buffer += block.inverseStrip.close ? '~}}' : '}}';
  270. } else {
  271. this.buffer += block.openStrip.close ? '~}}' : '}}';
  272. }
  273. this.Block(block.program);
  274. if (block.inverse) {
  275. if (!block.inverse.chained) {
  276. this.buffer += block.inverseStrip.open ? '{{~' : '{{';
  277. this.buffer += 'else';
  278. this.buffer += block.inverseStrip.close ? '~}}' : '}}';
  279. }
  280. this.Block(block.inverse);
  281. }
  282. if (!block.chained) {
  283. this.buffer += block.closeStrip.open ? '{{~/' : '{{/';
  284. this.Expression(block.path);
  285. this.buffer += block.closeStrip.close ? '~}}' : '}}';
  286. }
  287. }
  288. BlockParams(blockParams) {
  289. this.buffer += ` as |${blockParams.join(' ')}|`;
  290. }
  291. PartialStatement(partial) {
  292. if (this.handledByOverride(partial)) {
  293. return;
  294. }
  295. this.buffer += '{{>';
  296. this.Expression(partial.name);
  297. this.Params(partial.params);
  298. this.Hash(partial.hash);
  299. this.buffer += '}}';
  300. }
  301. ConcatStatement(concat) {
  302. if (this.handledByOverride(concat)) {
  303. return;
  304. }
  305. this.buffer += '"';
  306. concat.parts.forEach(part => {
  307. if (part.type === 'TextNode') {
  308. this.TextNode(part, true);
  309. } else {
  310. this.Node(part);
  311. }
  312. });
  313. this.buffer += '"';
  314. }
  315. MustacheCommentStatement(comment) {
  316. if (this.handledByOverride(comment)) {
  317. return;
  318. }
  319. this.buffer += `{{!--${comment.value}--}}`;
  320. }
  321. ElementModifierStatement(mod) {
  322. if (this.handledByOverride(mod)) {
  323. return;
  324. }
  325. this.buffer += '{{';
  326. this.Expression(mod.path);
  327. this.Params(mod.params);
  328. this.Hash(mod.hash);
  329. this.buffer += '}}';
  330. }
  331. CommentStatement(comment) {
  332. if (this.handledByOverride(comment)) {
  333. return;
  334. }
  335. this.buffer += `<!--${comment.value}-->`;
  336. }
  337. PathExpression(path) {
  338. if (this.handledByOverride(path)) {
  339. return;
  340. }
  341. this.buffer += path.original;
  342. }
  343. SubExpression(sexp) {
  344. if (this.handledByOverride(sexp)) {
  345. return;
  346. }
  347. this.buffer += '(';
  348. this.Expression(sexp.path);
  349. this.Params(sexp.params);
  350. this.Hash(sexp.hash);
  351. this.buffer += ')';
  352. }
  353. Params(params) {
  354. // TODO: implement a top level Params AST node (just like the Hash object)
  355. // so that this can also be overridden
  356. if (params.length) {
  357. params.forEach(param => {
  358. this.buffer += ' ';
  359. this.Expression(param);
  360. });
  361. }
  362. }
  363. Hash(hash) {
  364. if (this.handledByOverride(hash, true)) {
  365. return;
  366. }
  367. hash.pairs.forEach(pair => {
  368. this.buffer += ' ';
  369. this.HashPair(pair);
  370. });
  371. }
  372. HashPair(pair) {
  373. if (this.handledByOverride(pair)) {
  374. return;
  375. }
  376. this.buffer += pair.key;
  377. this.buffer += '=';
  378. this.Node(pair.value);
  379. }
  380. StringLiteral(str) {
  381. if (this.handledByOverride(str)) {
  382. return;
  383. }
  384. this.buffer += JSON.stringify(str.value);
  385. }
  386. BooleanLiteral(bool) {
  387. if (this.handledByOverride(bool)) {
  388. return;
  389. }
  390. this.buffer += bool.value;
  391. }
  392. NumberLiteral(number) {
  393. if (this.handledByOverride(number)) {
  394. return;
  395. }
  396. this.buffer += number.value;
  397. }
  398. UndefinedLiteral(node) {
  399. if (this.handledByOverride(node)) {
  400. return;
  401. }
  402. this.buffer += 'undefined';
  403. }
  404. NullLiteral(node) {
  405. if (this.handledByOverride(node)) {
  406. return;
  407. }
  408. this.buffer += 'null';
  409. }
  410. print(node) {
  411. let {
  412. options
  413. } = this;
  414. if (options.override) {
  415. let result = options.override(node, options);
  416. if (result !== undefined) {
  417. return result;
  418. }
  419. }
  420. this.buffer = '';
  421. this.Node(node);
  422. return this.buffer;
  423. }
  424. }
  425. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3N5bnRheC9saWIvZ2VuZXJhdGlvbi9wcmludGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLFNBQVMsZUFBVCxFQUEwQixVQUExQixFQUFzQyxTQUF0QyxRQUF1RCxRQUF2RDtBQUVBLE9BQU8sTUFBTSxPQUFPLEdBRWhCLE1BQU0sQ0FBQyxNQUFQLENBQWMsSUFBZCxDQUZHO0FBSVAsSUFBSSxZQUFZLEdBQ2QscUZBREY7QUFFQSxZQUFZLENBQUMsS0FBYixDQUFtQixHQUFuQixFQUF3QixPQUF4QixDQUFpQyxPQUFELElBQVk7QUFDMUMsRUFBQSxPQUFPLENBQUMsT0FBRCxDQUFQLEdBQW1CLElBQW5CO0FBQ0QsQ0FGRDtBQUlBLE1BQU0sY0FBYyxHQUFHLElBQXZCO0FBc0JBLGVBQWMsTUFBTyxPQUFQLENBQWM7QUFJMUIsRUFBQSxXQUFBLENBQVksT0FBWixFQUFtQztBQUgzQixTQUFBLE1BQUEsR0FBUyxFQUFUO0FBSU4sU0FBSyxPQUFMLEdBQWUsT0FBZjtBQUNEO0FBRUQ7Ozs7Ozs7Ozs7QUFTQSxFQUFBLGlCQUFpQixDQUFDLElBQUQsRUFBbUIsdUJBQXVCLEdBQUcsS0FBN0MsRUFBa0Q7QUFDakUsUUFBSSxLQUFLLE9BQUwsQ0FBYSxRQUFiLEtBQTBCLFNBQTlCLEVBQXlDO0FBQ3ZDLFVBQUksTUFBTSxHQUFHLEtBQUssT0FBTCxDQUFhLFFBQWIsQ0FBc0IsSUFBdEIsRUFBNEIsS0FBSyxPQUFqQyxDQUFiOztBQUNBLFVBQUksT0FBTyxNQUFQLEtBQWtCLFFBQXRCLEVBQWdDO0FBQzlCLFlBQUksdUJBQXVCLElBQUksTUFBTSxLQUFLLEVBQXRDLElBQTRDLGNBQWMsQ0FBQyxJQUFmLENBQW9CLE1BQU0sQ0FBQyxDQUFELENBQTFCLENBQWhELEVBQWdGO0FBQzlFLFVBQUEsTUFBTSxHQUFHLElBQUksTUFBTSxFQUFuQjtBQUNEOztBQUVELGFBQUssTUFBTCxJQUFlLE1B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QUEwQjtBQUN4QixlQUFPLE1BQVA7QUFDRDtBQUNGOztBQUVELFNBQUssTUFBTCxHQUFjLEVBQWQ7QUFDQSxTQUFLLElBQUwsQ0FBVSxJQUFWO0FBQ0EsV0FBTyxLQUFLLE1BQVo7QUFDRDs7QUF4ZXlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgQVNUdjEgZnJvbSAnLi4vdjEvYXBpJztcbmltcG9ydCB7IGVzY2FwZUF0dHJWYWx1ZSwgZXNjYXBlVGV4dCwgc29ydEJ5TG9jIH0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IGNvbnN0IHZvaWRNYXA6IHtcbiAgW3RhZ05hbWU6IHN0cmluZ106IGJvb2xlYW47XG59ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxubGV0IHZvaWRUYWdOYW1lcyA9XG4gICdhcmVhIGJhc2UgYnIgY29sIGNvbW1hbmQgZW1iZWQgaHIgaW1nIGlucHV0IGtleWdlbiBsaW5rIG1ldGEgcGFyYW0gc291cmNlIHRyYWNrIHdicic7XG52b2lkVGFnTmFtZXMuc3BsaXQoJyAnKS5mb3JFYWNoKCh0YWdOYW1lKSA9PiB7XG4gIHZvaWRNYXBbdGFnTmFtZV0gPSB0cnVlO1xufSk7XG5cbmNvbnN0IE5PTl9XSElURVNQQUNFID0gL1xcUy87XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJpbnRlck9wdGlvbnMge1xuICBlbnRpdHlFbmNvZGluZzogJ3RyYW5zZm9ybWVkJyB8ICdyYXcnO1xuXG4gIC8qKlxuICAgKiBVc2VkIHRvIG92ZXJyaWRlIHRoZSBtZWNoYW5pc20gb2YgcHJpbnRpbmcgYSBnaXZlbiBBU1QuTm9kZS5cbiAgICpcbiAgICogVGhpcyB3aWxsIGdlbmVyYWxseSBvbmx5IGJlIHVzZWZ1bCB0byBzb3VyY2UgLT4gc291cmNlIGNvZGVtb2RzXG4gICAqIHdoZXJlIHlvdSB3b3VsZCBsaWtlIHRvIHNwZWNpYWxpemUvb3ZlcnJpZGUgdGhlIHdheSBhIGdpdmVuIG5vZGUgaXNcbiAgICogcHJpbnRlZCAoZS5nLiB5b3Ugd291bGQgbGlrZSB0byBwcmVzZXJ2ZSBhcyBtdWNoIG9mIHRoZSBvcmlnaW5hbFxuICAgKiBmb3JtYXR0aW5nIGFzIHBvc3NpYmxlKS5cbiAgICpcbiAgICogV2hlbiB0aGUgcHJvdmlkZWQgb3ZlcnJpZGUgcmV0dXJucyB1bmRlZmluZWQsIHRoZSBkZWZhdWx0IGJ1aWx0IGluIHByaW50aW5nXG4gICAqIHdpbGwgYmUgZG9uZSBmb3IgdGhlIEFTVC5Ob2RlLlxuICAgKlxuICAgKiBAcGFyYW0gYXN0IHRoZSBhc3Qgbm9kZSB0byBiZSBwcmludGVkXG4gICAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHNwZWNpZmllZCBkdXJpbmcgdGhlIHByaW50KCkgaW52b2NhdGlvblxuICAgKi9cbiAgb3ZlcnJpZGU/KGFzdDogQVNUdjEuTm9kZSwgb3B0aW9uczogUHJpbnRlck9wdGlvbnMpOiB2b2lkIHwgc3RyaW5nO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQcmludGVyIHtcbiAgcHJpdmF0ZSBidWZmZXIgPSAnJztcbiAgcHJpdmF0ZSBvcHRpb25zOiBQcmludGVyT3B0aW9ucztcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBQcmludGVyT3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICAvKlxuICAgIFRoaXMgaXMgdXNlZCBieSBfYWxsXyBtZXRob2RzIG9uIHRoaXMgUHJpbnRlciBjbGFzcyB0aGF0IGFkZCB0byBgdGhpcy5idWZmZXJgLFxuICAgIGl0IGFsbG93cyBjb25zdW1lcnMgb2YgdGhlIHByaW50ZXIgdG8gdXNlIGFsdGVybmF0ZSBzdHJpbmcgcmVwcmVzZW50YXRpb25zIGZvclxuICAgIGEgZ2l2ZW4gbm9kZS5cblxuICAgIFRoZSBwcmltYXJ5IHVzZSBjYXNlIGZvciB0aGlzIGFyZSB0aGluZ3MgbGlrZSBzb3VyY2UgLT4gc291cmNlIGNvZGVtb2QgdXRpbGl0aWVzLlxuICAgIEZvciBleGFtcGxlLCBlbWJlci10ZW1wbGF0ZS1yZWNhc3QgYXR0ZW1wdHMgdG8gYWx3YXlzIHByZXNlcnZlIHRoZSBvcmlnaW5hbCBzdHJpbmdcbiAgICBmb3JtYXR0aW5nIGluIGVhY2ggQVNUIG5vZGUgaWYgbm8gbW9kaWZpY2F0aW9ucyBhcmUgbWFkZSB0byBpdC5cbiAgKi9cbiAgaGFuZGxlZEJ5T3ZlcnJpZGUobm9kZTogQVNUdjEuTm9kZSwgZW5zdXJlTGVhZGluZ1doaXRlc3BhY2UgPSBmYWxzZSk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLm9wdGlvbnMub3ZlcnJpZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgbGV0IHJlc3VsdCA9IHRoaXMub3B0aW9ucy5vdmVycmlkZShub2RlLCB0aGlzLm9wdGlvbnMpO1xuICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmIChlbnN1cmVMZWFkaW5nV2hpdGVzcGFjZSAmJiByZXN1bHQgIT09ICcnICYmIE5PTl9XSElURVNQQUNFLnRlc3QocmVzdWx0WzBdKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGAgJHtyZXN1bHR9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYnVmZmVyICs9IHJlc3VsdDtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgTm9kZShub2RlOiBBU1R2MS5Ob2RlKTogdm9pZCB7XG4gICAgc3dpdGNoIChub2RlLnR5cGUpIHtcbiAgICAgIGNhc2UgJ011c3RhY2hlU3RhdGVtZW50JzpcbiAgICAgIGNhc2UgJ0Jsb2NrU3RhdGVtZW50JzpcbiAgICAgIGNhc2UgJ1BhcnRpYWxTdGF0ZW1lbnQnOlxuICAgICAgY2FzZSAnTXVzdGFjaGVDb21tZW50U3RhdGVtZW50JzpcbiAgICAgIGNhc2UgJ0NvbW1lbnRTdGF0ZW1lbnQnOlxuICAgICAgY2FzZSAnVGV4dE5vZGUnOlxuICAgICAgY2FzZSAnRWxlbWVudE5vZGUnOlxuICAgICAgY2FzZSAnQXR0ck5vZGUnOlxuICAgICAgY2FzZSAnQmxvY2snOlxuICAgICAgY2FzZSAnVGVtcGxhdGUnOlxuICAgICAgICByZXR1cm4gdGhpcy5Ub3BMZXZlbFN0YXRlbWVudChub2RlKTtcbiAgICAgIGNhc2UgJ1N0cmluZ0xpdGVyYWwnOlxuICAgICAgY2FzZSAnQm9vbGVhbkxpdGVyYWwnOlxuICAgICAgY2FzZSAnTnVtYmVyTGl0ZXJhbCc6XG4gICAgICBjYXNlICdVbmRlZmluZWRMaXRlcmFsJzpcbiAgICAgIGNhc2UgJ051bGxMaXRlcmFsJzpcbiAgICAgIGNhc2UgJ1BhdGhFeHByZXNzaW9uJzpcbiAgICAgIGNhc2UgJ1N1YkV4cHJlc3Npb24nOlxuICAgICAgICByZXR1cm4gdGhpcy5FeHByZXNzaW9uKG5vZGUpO1xuICAgICAgY2FzZSAnUHJvZ3JhbSc6XG4gICAgICAgIHJldHVybiB0aGlzLkJsb2NrKG5vZGUpO1xuICAgICAgY2FzZSAnQ29uY2F0U3RhdGVtZW50JzpcbiAgICAgICAgLy8gc2hvdWxkIGhhdmUgYW4gQXR0ck5vZGUgcGFyZW50XG4gICAgICAgIHJldHVybiB0aGlzLkNvbmNhdFN0YXRlbWVudChub2RlKTtcbiAgICAgIGNhc2UgJ0hhc2gnOlxuICAgICAgICByZXR1cm4gdGhpcy5IYXNoKG5vZGUpO1xuICAgICAgY2FzZSAnSGFzaFBhaXInOlxuICAgICAgICByZXR1cm4gdGhpcy5IYXNoUGFpcihub2RlKTtcbiAgICAgIGNhc2UgJ0VsZW1lbnRNb2RpZmllclN0YXRlbWVudCc6XG4gICAgICAgIHJldHVybiB0aGlzLkVsZW1lbnRNb2RpZmllclN0YXRlbWVudChub2RlKTtcbiAgICB9XG4gIH1cblxuICBFeHByZXNzaW9uKGV4cHJlc3Npb246IEFTVHYxLkV4cHJlc3Npb24pOiB2b2lkIHtcbiAgICBzd2l0Y2ggKGV4cHJlc3Npb24udHlwZSkge1xuICAgICAgY2FzZSAnU3RyaW5nTGl0ZXJhbCc6XG4gICAgICBjYXNlICdCb29sZWFuTGl0ZXJhbCc6XG4gICAgICBjYXNlICdOdW1iZXJMaXRlcmFsJzpcbiAgICAgIGNhc2UgJ1VuZGVmaW5lZExpdGVyYWwnOlxuICAgICAgY2FzZSAnTnVsbExpdGVyYWwnOlxuICAgICAgICByZXR1cm4gdGhpcy5MaXRlcmFsKGV4cHJlc3Npb24pO1xuICAgICAgY2FzZSAnUGF0aEV4cHJlc3Npb24nOlxuICAgICAgICByZXR1cm4gdGhpcy5QYXRoRXhwcmVzc2lvbihleHByZXNzaW9uKTtcbiAgICAgIGNhc2UgJ1N1YkV4cHJlc3Npb24nOlxuICAgICAgICByZXR1cm4gdGhpcy5TdWJFeHByZXNzaW9uKGV4cHJlc3Npb24pO1xuICAgIH1cbiAgfVxuXG4gIExpdGVyYWwobGl0ZXJhbDogQVNUdjEuTGl0ZXJhbCk6IHZvaWQge1xuICAgIHN3aXRjaCAobGl0ZXJhbC50eXBlKSB7XG4gICAgICBjYXNlICdTdHJpbmdMaXRlcmFsJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuU3RyaW5nTGl0ZXJhbChsaXRlcmFsKTtcbiAgICAgIGNhc2UgJ0Jvb2xlYW5MaXRlcmFsJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuQm9vbGVhbkxpdGVyYWwobGl0ZXJhbCk7XG4gICAgICBjYXNlICdOdW1iZXJMaXRlcmFsJzpcbiAgICAgICAgcmV0dXJuIHRoaXMuTnVtYmVyTGl0ZXJhbChsaXRlcmFsKTtcbiAgICAgIGNhc2UgJ1VuZGVmaW5lZExpdGVyYWwnOlxuICAgICAgICByZXR1cm4gdGhpcy5VbmRlZmluZWRMaXRlcmFsKGxpdGVyYWwpO1xuICAgICAgY2FzZSAnTnVsbExpdGVyYWwnOlxuICAgICAgICByZXR1cm4gdGhpcy5OdWxsTGl0ZXJhbChsaXRlcmFsKTtcbiAgICB9XG4gIH1cblxuICBUb3BMZXZlbFN0YXRlbWVudChzdGF0ZW1lbnQ6IEFTVHYxLlRvcExldmVsU3RhdGVtZW50IHwgQVNUdjEuVGVtcGxhdGUgfCBBU1R2MS5BdHRyTm9kZSk6IHZvaWQge1xuICAgIHN3aXRjaCAoc3RhdGVtZW50LnR5cGUpIHtcbiAgICAgIGNhc2UgJ011c3RhY2hlU3RhdGVtZW50JzpcbiAgICAgICAgcmV0dXJuIHRoaXMuTXVzdGFjaGVTdGF0ZW1lbnQoc3RhdGVtZW50KTtcbiAgICAgIGNhc2UgJ0Jsb2NrU3RhdGVtZW50JzpcbiAgICAgICAgcmV0dXJuIHRoaXMuQmxvY2tTdGF0ZW1lbnQoc3RhdGVtZW50KTtcbiAgICAgIGNhc2UgJ1BhcnRpYWxTdGF0ZW1lbnQnOlxuICAgICAgICByZXR1cm4gdGhpcy5QYXJ0aWFsU3RhdGVtZW50KHN0YXRlbWVudCk7XG4gICAgICBjYXNlICdNdXN0YWNoZUNvbW1lbnRTdGF0ZW1lbnQnOlxuICAgICAgICByZXR1cm4gdGhpcy5NdXN0YWNoZUNvbW1lbnRTdGF0ZW1lbnQoc3RhdGVtZW50KTtcbiAgICAgIGNhc2UgJ0NvbW1lbnRTdGF0ZW1lbnQnOlxuICAgICAgICByZXR1cm4gdGhpcy5Db21tZW50U3RhdGVtZW50KHN0YXRlbWVudCk7XG4gICAgICBjYXNlICdUZXh0Tm9kZSc6XG4gICAgICAgIHJldHVybiB0aGlzLlRleHROb2RlKHN0YXRlbWVudCk7XG4gICAgICBjYXNlICdFbGVtZW50Tm9kZSc6XG4gICAgICAgIHJldHVybiB0aGlzLkVsZW1lbnROb2RlKHN0YXRlbWVudCk7XG4gICAgICBjYXNlICdCbG9jayc6XG4gICAgICBjYXNlICdUZW1wbGF0ZSc6XG4gICAgICAgIHJldHVybiB0aGlzLkJsb2NrKHN0YXRlbWVudCk7XG4gICAgICBjYXNlICdBdHRyTm9kZSc6XG4gICAgICAgIC8vIHNob3VsZCBoYXZlIGVsZW1lbnRcbiAgICAgICAgcmV0dXJuIHRoaXMuQXR0ck5vZGUoc3RhdGVtZW50KTtcbiAgICB9XG4gIH1cblxuICBCbG9jayhibG9jazogQVNUdjEuQmxvY2sgfCBBU1R2MS5Qcm9ncmFtIHwgQVNUdjEuVGVtcGxhdGUpOiB2b2lkIHtcbiAgICAvKlxuICAgICAgV2hlbiBwcm9jZXNzaW5nIGEgdGVtcGxhdGUgbGlrZTpcblxuICAgICAgYGBgaGJzXG4gICAgICB7eyNpZiB3aGF0ZXZlcn19XG4gICAgICAgIHdoYXRldmVyXG4gICAgICB7e2Vsc2UgaWYgc29tZXRoaW5nRWxzZX19XG4gICAgICAgIHNvbWV0aGluZyBlbHNlXG4gICAgICB7e2Vsc2V9fVxuICAgICAgICBmYWxsYmFja1xuICAgICAge3svaWZ9fVxuICAgICAgYGBgXG5cbiAgICAgIFRoZSBBU1Qgc3RpbGwgX2VmZmVjdGl2ZWx5XyBsb29rcyBsaWtlOlxuXG4gICAgICBgYGBoYnNcbiAgICAgIHt7I2lmIHdoYXRldmVyfX1cbiAgICAgICAgd2hhdGV2ZXJcbiAgICAgIHt7ZWxzZX19e3sjaWYgc29tZXRoaW5nRWxzZX19XG4gICAgICAgIHNvbWV0aGluZyBlbHNlXG4gICAgICB7e2Vsc2V9fVxuICAgICAgICBmYWxsYmFja1xuICAgICAge3svaWZ9fXt7L2lmfX1cbiAgICAgIGBgYFxuXG4gICAgICBUaGUgb25seSB3YXkgd2UgY2FuIHRlbGwgaWYgdGhhdCBpcyB0aGUgY2FzZSBpcyBieSBjaGVja2luZyBmb3JcbiAgICAgIGBibG9jay5jaGFpbmVkYCwgYnV0IHVuZm9ydHVuYXRlbHkgd2hlbiB0aGUgYWN0dWFsIHN0YXRlbWVudHMgYXJlXG4gICAgICBwcm9jZXNzZWQgdGhlIGBibG9jay5ib2R5WzBdYCBub2RlICh3aGljaCB3aWxsIGFsd2F5cyBiZSBhXG4gICAgICBgQmxvY2tTdGF0ZW1lbnRgKSBoYXMgbm8gY2x1ZSB0aGF0IGl0cyBhbmNlc3RvciBgQmxvY2tgIG5vZGUgd2FzXG4gICAgICBjaGFpbmVkLlxuXG4gICAgICBUaGlzIFwiZm9yd2FyZHNcIiB0aGUgYGNoYWluZWRgIHNldHRpbmcgc28gdGhhdCB3ZSBjYW4gY2hlY2tcbiAgICAgIGl0IGxhdGVyIHdoZW4gcHJvY2Vzc2luZyB0aGUgYEJsb2NrU3RhdGVtZW50YC5cbiAgICAqL1xuICAgIGlmIChibG9jay5jaGFpbmVkKSB7XG4gICAgICBsZXQgZmlyc3RDaGlsZCA9IGJsb2NrLmJvZHlbMF0gYXMgQVNUdjEuQmxvY2tTdGF0ZW1lbnQ7XG4gICAgICBmaXJzdENoaWxkLmNoYWluZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmhhbmRsZWRCeU92ZXJyaWRlKGJsb2NrKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuVG9wTGV2ZWxTdGF0ZW1lbnRzKGJsb2NrLmJvZHkpO1xuICB9XG5cbiAgVG9wTGV2ZWxTdGF0ZW1lbnRzKHN0YXRlbWVudHM6IEFTVHYxLlRvcExldmVsU3RhdGVtZW50W10pOiB2b2lkIHtcbiAgICBzdGF0ZW1lbnRzLmZvckVhY2goKHN0YXRlbWVudCkgPT4gdGhpcy5Ub3BMZXZlbFN0YXRlbWVudChzdGF0ZW1lbnQpKTtcbiAgfVxuXG4gIEVsZW1lbnROb2RlKGVsOiBBU1R2MS5FbGVtZW50Tm9kZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhhbmRsZWRCeU92ZXJyaWRlKGVsKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuT3BlbkVsZW1lbnROb2RlKGVsKTtcbiAgICB0aGlzLlRvcExldmVsU3RhdGVtZW50cyhlbC5jaGlsZHJlbik7XG4gICAgdGhpcy5DbG9zZUVsZW1lbnROb2RlKGVsKTtcbiAgfVxuXG4gIE9wZW5FbGVtZW50Tm9kZShlbDogQVNUdjEuRWxlbWVudE5vZGUpOiB2b2lkIHtcbiAgICB0aGlzLmJ1ZmZlciArPSBgPCR7ZWwudGFnfWA7XG4gICAgY29uc3QgcGFydHMgPSBbLi4uZWwuYXR0cmlidXRlcywgLi4uZWwubW9kaWZpZXJzLCAuLi5lbC5jb21tZW50c10uc29ydChzb3J0QnlMb2MpO1xuXG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICB0aGlzLmJ1ZmZlciArPSAnICc7XG4gICAgICBzd2l0Y2ggKHBhcnQudHlwZSkge1xuICAgICAgICBjYXNlICdBdHRyTm9kZSc6XG4gICAgICAgICAgdGhpcy5BdHRyTm9kZShwYXJ0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnRWxlbWVudE1vZGlmaWVyU3RhdGVtZW50JzpcbiAgICAgICAgICB0aGlzLkVsZW1lbnRNb2RpZmllclN0YXRlbWVudChwYXJ0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnTXVzdGFjaGVDb21tZW50U3RhdGVtZW50JzpcbiAgICAgICAgICB0aGlzLk11c3RhY2hlQ29tbWVudFN0YXRlbWVudChwYXJ0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVsLmJsb2NrUGFyYW1zLmxlbmd0aCkge1xuICAgICAgdGhpcy5CbG9ja1BhcmFtcyhlbC5ibG9ja1BhcmFtcyk7XG4gICAgfVxuICAgIGlmIChlbC5zZWxmQ2xvc2luZykge1xuICAgICAgdGhpcy5idWZmZXIgKz0gJyAvJztcbiAgICB9XG4gICAgdGhpcy5idWZmZXIgKz0gJz4nO1xuICB9XG5cbiAgQ2xvc2VFbGVtZW50Tm9kZShlbDogQVNUdjEuRWxlbWVudE5vZGUpOiB2b2lkIHtcbiAgICBpZiAoZWwuc2VsZkNsb3NpbmcgfHwgdm9pZE1hcFtlbC50YWcudG9Mb3dlckNhc2UoKV0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5idWZmZXIgKz0gYDwvJHtlbC50YWd9PmA7XG4gIH1cblxuICBBdHRyTm9kZShhdHRyOiBBU1R2MS5BdHRyTm9kZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhhbmRsZWRCeU92ZXJyaWRlKGF0dHIpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHsgbmFtZSwgdmFsdWUgfSA9IGF0dHI7XG5cbiAgICB0aGlzLmJ1ZmZlciArPSBuYW1lO1xuICAgIGlmICh2YWx1ZS50eXBlICE9PSAnVGV4dE5vZGUnIHx8IHZhbHVlLmNoYXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYnVmZmVyICs9ICc9JztcbiAgICAgIHRoaXMuQXR0ck5vZGVWYWx1ZSh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgQXR0ck5vZGVWYWx1ZSh2YWx1ZTogQVNUdjEuQXR0ck5vZGVbJ3ZhbHVlJ10pOiB2b2lkIHtcbiAgICBpZiAodmFsdWUudHlwZSA9PT0gJ1RleHROb2RlJykge1xuICAgICAgdGhpcy5idWZmZXIgKz0gJ1wiJztcbiAgICAgIHRoaXMuVGV4dE5vZGUodmFsdWUsIHRydWUpO1xuICAgICAgdGhpcy5idWZmZXIgKz0gJ1wiJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5Ob2RlKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBUZXh0Tm9kZSh0ZXh0OiBBU1R2MS5UZXh0Tm9kZSwgaXNBdHRyPzogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh0aGlzLmhhbmRsZWRCeU92ZXJyaWRlKHRleHQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5lbnRpdHlFbmNvZGluZyA9PT0gJ3JhdycpIHtcbiAgICAgIHRoaXMuYnVmZmVyICs9IHRleHQuY2hhcnM7XG4gICAgfSBlbHNlIGlmIChpc0F0dHIpIHtcbiAgICAgIHRoaXMuYnVmZmVyICs9IGVzY2FwZUF0dHJWYWx1ZSh0ZXh0LmNoYXJzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5idWZmZXIgKz0gZXNjYXBlVGV4dCh0ZXh0LmNoYXJzKTtcbiAgICB9XG4gIH1cblxuICBNdXN0YWNoZVN0YXRlbWVudChtdXN0YWNoZTogQVNUdjEuTXVzdGFjaGVTdGF0ZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oYW5kbGVkQnlPdmVycmlkZShtdXN0YWNoZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmJ1ZmZlciArPSBtdXN0YWNoZS5lc2NhcGVkID8gJ3t7JyA6ICd7e3snO1xuXG4gICAgaWYgKG11c3RhY2hlLnN0cmlwLm9wZW4pIHtcbiAgICAgIHRoaXMuYnVmZmVyICs9ICd+JztcbiAgICB9XG5cbiAgICB0aGlzLkV4cHJlc3Npb24obXVzdGFjaGUucGF0aCk7XG4gICAgdGhpcy5QYXJhbXMobXVzdGFjaGUucGFyYW1zKTtcbiAgICB0aGlzLkhhc2gobXVzdGFjaGUuaGFzaCk7XG5cbiAgICBpZiAobXVzdGFjaGUuc3RyaXAuY2xvc2UpIHtcbiAgICAgIHRoaXMuYnVmZmVyICs9ICd+JztcbiAgICB9XG5cbiAgICB0aGlzLmJ1ZmZlciArPSBtdXN0YWNoZS5lc2NhcGVkID8gJ319JyA6ICd9fX0nO1xuICB9XG5cbiAgQmxvY2tTdGF0ZW1lbnQoYmxvY2s6IEFTVHYxLkJsb2NrU3RhdGVtZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaGFuZGxlZEJ5T3ZlcnJpZGUoYmxvY2spKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGJsb2NrLmNoYWluZWQpIHtcbiAgICAgIHRoaXMuYnVmZmVyICs9IGJsb2NrLmludmVyc2VTdHJpcC5vcGVuID8gJ3t7ficgOiAne3snO1xuICAgICAgdGhpcy5idWZmZXIgKz0gJ2Vsc2UgJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5idWZmZXIgKz0gYmxvY2sub3BlblN0cmlwLm9wZW4gPyAne3t+IycgOiAne3sjJztcbiAgICB9XG5cbiAgICB0aGlzLkV4cHJlc3Npb24oYmxvY2sucGF0aCk7XG4gICAgdGhpcy5QYXJhbXMoYmxvY2sucGFyYW1zKTtcbiAgICB0aGlzLkhhc2goYmxvY2suaGFzaCk7XG4gICAgaWYgKGJsb2NrLnByb2dyYW0uYmxvY2tQYXJhbXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLkJsb2NrUGFyYW1zKGJsb2NrLnByb2dyYW0uYmxvY2tQYXJhbXMpO1xuICAgIH1cblxuICAgIGlmIChibG9jay5jaGFpbmVkKSB7XG4gICAgICB0aGlzLmJ1ZmZlciArPSBibG9jay5pbnZlcnNlU3RyaXAuY2xvc2UgPyAnfn19JyA6ICd9fSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYnVmZmVyICs9IGJsb2NrLm9wZW5TdHJpcC5jbG9zZSA/ICd+fX0nIDogJ319JztcbiAgICB9XG5cbiAgICB0aGlzLkJsb2NrKGJsb2NrLnByb2dyYW0pO1xuXG4gICAgaWYgKGJsb2NrLmludmVyc2UpIHtcbiAgICAgIGlmICghYmxvY2suaW52ZXJzZS5jaGFpbmVkKSB7XG4gICAgICAgIHRoaXMuYnVmZmVyICs9IGJsb2NrLmludmVyc2VTdHJpcC5vcGVuID8gJ3t7ficgOiAne3snO1xuICAgICAgICB0aGlzLmJ1ZmZlciArPSAnZWxzZSc7XG4gICAgICAgIHRoaXMuYnVmZmVyICs9IGJsb2NrLmludmVyc2VTdHJpcC5jbG9zZSA/ICd+fX0nIDogJ319JztcbiAgICAgIH1cblxuICAgICAgdGhpcy5CbG9jayhibG9jay5pbnZlcnNlKTtcbiAgICB9XG5cbiAgICBpZiAoIWJsb2NrLmNoYWluZWQpIHtcbiAgICAgIHRoaXMuYnVmZmVyICs9IGJsb2NrLmNsb3NlU3RyaXAub3BlbiA/ICd7e34vJyA6ICd7ey8nO1xuICAgICAgdGhpcy5FeHByZXNzaW9uKGJsb2NrLnBhdGgpO1xuICAgICAgdGhpcy5idWZmZXIgKz0gYmxvY2suY2xvc2VTdHJpcC5jbG9zZSA/ICd+fX0nIDogJ319JztcbiAgICB9XG4gIH1cblxuICBCbG9ja1BhcmFtcyhibG9ja1BhcmFtczogc3RyaW5nW10pOiB2b2lkIHtcbiAgICB0aGlzLmJ1ZmZlciArPSBgIGFzIHwke2Jsb2NrUGFyYW1zLmpvaW4oJyAnKX18YDtcbiAgfVxuXG4gIFBhcnRpYWxTdGF0ZW1lbnQocGFydGlhbDogQVNUdjEuUGFydGlhbFN0YXRlbWVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhhbmRsZWRCeU92ZXJyaWRlKHBhcnRpYWwpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5idWZmZXIgKz0gJ3t7Pic7XG4gICAgdGhpcy5FeHByZXNzaW9uKHBhcnRpYWwubmFtZSk7XG4gICAgdGhpcy5QYXJhbXMocGFydGlhbC5wYXJhbXMpO1xuICAgIHRoaXMuSGFzaChwYXJ0aWFsLmhhc2gpO1xuICAgIHRoaXMuYnVmZmVyICs9ICd9fSc7XG4gIH1cblxuICBDb25jYXRTdGF0ZW1lbnQoY29uY2F0OiBBU1R2MS5Db25jYXRTdGF0ZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oYW5kbGVkQnlPdmVycmlkZShjb25jYXQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5idWZmZXIgKz0gJ1wiJztcbiAgICBjb25jYXQucGFydHMuZm9yRWFjaCgocGFydCkgPT4ge1xuICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ1RleHROb2RlJykge1xuICAgICAgICB0aGlzLlRleHROb2RlKHBhcnQsIHRydWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5Ob2RlKHBhcnQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMuYnVmZmVyICs9ICdcIic7XG4gIH1cblxuICBNdXN0YWNoZUNvbW1lbnRTdGF0ZW1lbnQoY29tbWVudDogQVNUdjEuTXVzdGFjaGVDb21tZW50U3RhdGVtZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaGFuZGxlZEJ5T3ZlcnJpZGUoY29tbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmJ1ZmZlciArPSBge3shLS0ke2NvbW1lbnQudmFsdWV9LS19fWA7XG4gIH1cblxuICBFbGVtZW50TW9kaWZpZXJTdGF0ZW1lbnQobW9kOiBBU1R2MS5FbGVtZW50TW9kaWZpZXJTdGF0ZW1lbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oYW5kbGVkQnlPdmVycmlkZShtb2QpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5idWZmZXIgKz0gJ3t7JztcbiAgICB0aGlzLkV4cHJlc3Npb24obW9kLnBhdGgpO1xuICAgIHRoaXMuUGFyYW1zKG1vZC5wYXJhbXMpO1xuICAgIHRoaXMuSGFzaChtb2QuaGFzaCk7XG4gICAgdGhpcy5idWZmZXIgKz0gJ319JztcbiAgfVxuXG4gIENvbW1lbnRTdGF0ZW1lbnQoY29tbWVudDogQVNUdjEuQ29tbWVudFN0YXRlbWVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhhbmRsZWRCeU92ZXJyaWRlKGNvbW1lbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5idWZmZXIgKz0gYDwhLS0ke2NvbW1lbnQudmFsdWV9LS0+YDtcbiAgfVxuXG4gIFBhdGhFeHByZXNzaW9uKHBhdGg6IEFTVHYxLlBhdGhFeHByZXNzaW9uKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaGFuZGxlZEJ5T3ZlcnJpZGUocGF0aCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmJ1ZmZlciArPSBwYXRoLm9yaWdpbmFsO1xuICB9XG5cbiAgU3ViRXhwcmVzc2lvbihzZXhwOiBBU1R2MS5TdWJFeHByZXNzaW9uKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaGFuZGxlZEJ5T3ZlcnJpZGUoc2V4cCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmJ1ZmZlciArPSAnKCc7XG4gICAgdGhpcy5FeHByZXNzaW9uKHNleHAucGF0aCk7XG4gICAgdGhpcy5QYXJhbXMoc2V4cC5wYXJhbXMpO1xuICAgIHRoaXMuSGFzaChzZXhwLmhhc2gpO1xuICAgIHRoaXMuYnVmZmVyICs9ICcpJztcbiAgfVxuXG4gIFBhcmFtcyhwYXJhbXM6IEFTVHYxLkV4cHJlc3Npb25bXSk6IHZvaWQge1xuICAgIC8vIFRPRE86IGltcGxlbWVudCBhIHRvcCBsZXZlbCBQYXJhbXMgQVNUIG5vZGUgKGp1c3QgbGlrZSB0aGUgSGFzaCBvYmplY3QpXG4gICAgLy8gc28gdGhhdCB0aGlzIGNhbiBhbHNvIGJlIG92ZXJyaWRkZW5cbiAgICBpZiAocGFyYW1zLmxlbmd0aCkge1xuICAgICAgcGFyYW1zLmZvckVhY2goKHBhcmFtKSA9PiB7XG4gICAgICAgIHRoaXMuYnVmZmVyICs9ICcgJztcbiAgICAgICAgdGhpcy5FeHByZXNzaW9uKHBhcmFtKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIEhhc2goaGFzaDogQVNUdjEuSGFzaCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhhbmRsZWRCeU92ZXJyaWRlKGhhc2gsIHRydWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaGFzaC5wYWlycy5mb3JFYWNoKChwYWlyKSA9PiB7XG4gICAgICB0aGlzLmJ1ZmZlciArPSAnICc7XG4gICAgICB0aGlzLkhhc2hQYWlyKHBhaXIpO1xuICAgIH0pO1xuICB9XG5cbiAgSGFzaFBhaXIocGFpcjogQVNUdjEuSGFzaFBhaXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oYW5kbGVkQnlPdmVycmlkZShwYWlyKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYnVmZmVyICs9IHBhaXIua2V5O1xuICAgIHRoaXMuYnVmZmVyICs9ICc9JztcbiAgICB0aGlzLk5vZGUocGFpci52YWx1ZSk7XG4gIH1cblxuICBTdHJpbmdMaXRlcmFsKHN0cjogQVNUdjEuU3RyaW5nTGl0ZXJhbCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhhbmRsZWRCeU92ZXJyaWRlKHN0cikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmJ1ZmZlciArPSBKU09OLnN0cmluZ2lmeShzdHIudmFsdWUpO1xuICB9XG5cbiAgQm9vbGVhbkxpdGVyYWwoYm9vbDogQVNUdjEuQm9vbGVhbkxpdGVyYWwpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oYW5kbGVkQnlPdmVycmlkZShib29sKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYnVmZmVyICs9IGJvb2wudmFsdWU7XG4gIH1cblxuICBOdW1iZXJMaXRlcmFsKG51bWJlcjogQVNUdjEuTnVtYmVyTGl0ZXJhbCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmhhbmRsZWRCeU92ZXJyaWRlKG51bWJlcikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmJ1ZmZlciArPSBudW1iZXIudmFsdWU7XG4gIH1cblxuICBVbmRlZmluZWRMaXRlcmFsKG5vZGU6IEFTVHYxLlVuZGVmaW5lZExpdGVyYWwpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oYW5kbGVkQnlPdmVycmlkZShub2RlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYnVmZmVyICs9ICd1bmRlZmluZWQnO1xuICB9XG5cbiAgTnVsbExpdGVyYWwobm9kZTogQVNUdjEuTnVsbExpdGVyYWwpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oYW5kbGVkQnlPdmVycmlkZShub2RlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYnVmZmVyICs9ICdudWxsJztcbiAgfVxuXG4gIHByaW50KG5vZGU6IEFTVHYxLk5vZGUpOiBzdHJpbmcge1xuICAgIGxldCB7IG9wdGlvbnMgfSA9IHRoaXM7XG5cbiAgICBpZiAob3B0aW9ucy5vdmVycmlkZSkge1xuICAgICAgbGV0IHJlc3VsdCA9IG9wdGlvbnMub3ZlcnJpZGUobm9kZSwgb3B0aW9ucyk7XG5cbiAgICAgIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuYnVmZmVyID0gJyc7XG4gICAgdGhpcy5Ob2RlKG5vZGUpO1xuICAgIHJldHVybiB0aGlzLmJ1ZmZlcjtcbiAgfVxufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==