traverse.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import { deprecate } from '@glimmer/util';
  2. import visitorKeys from '../v1/visitor-keys';
  3. import { cannotRemoveNode, cannotReplaceNode, cannotReplaceOrRemoveInKeyHandlerYet } from './errors';
  4. import WalkerPath from './path';
  5. function getEnterFunction(handler) {
  6. if (typeof handler === 'function') {
  7. return handler;
  8. } else {
  9. return handler.enter;
  10. }
  11. }
  12. function getExitFunction(handler) {
  13. if (typeof handler === 'function') {
  14. return undefined;
  15. } else {
  16. return handler.exit;
  17. }
  18. }
  19. function getKeyHandler(handler, key) {
  20. var keyVisitor = typeof handler !== 'function' ? handler.keys : undefined;
  21. if (keyVisitor === undefined) return;
  22. var keyHandler = keyVisitor[key];
  23. if (keyHandler !== undefined) {
  24. return keyHandler;
  25. }
  26. return keyVisitor.All;
  27. }
  28. function getNodeHandler(visitor, nodeType) {
  29. if (nodeType === 'Template' || nodeType === 'Block') {
  30. if (visitor.Program) {
  31. if (false
  32. /* LOCAL_DEBUG */
  33. ) {
  34. false && !false && deprecate("The 'Program' visitor node is deprecated. Use 'Template' or 'Block' instead (node was '" + nodeType + "') ");
  35. }
  36. return visitor.Program;
  37. }
  38. }
  39. var handler = visitor[nodeType];
  40. if (handler !== undefined) {
  41. return handler;
  42. }
  43. return visitor.All;
  44. }
  45. function visitNode(visitor, path) {
  46. var node = path.node,
  47. parent = path.parent,
  48. parentKey = path.parentKey;
  49. var handler = getNodeHandler(visitor, node.type);
  50. var enter;
  51. var exit;
  52. if (handler !== undefined) {
  53. enter = getEnterFunction(handler);
  54. exit = getExitFunction(handler);
  55. }
  56. var result;
  57. if (enter !== undefined) {
  58. result = enter(node, path);
  59. }
  60. if (result !== undefined && result !== null) {
  61. if (JSON.stringify(node) === JSON.stringify(result)) {
  62. result = undefined;
  63. } else if (Array.isArray(result)) {
  64. visitArray(visitor, result, parent, parentKey);
  65. return result;
  66. } else {
  67. var _path = new WalkerPath(result, parent, parentKey);
  68. return visitNode(visitor, _path) || result;
  69. }
  70. }
  71. if (result === undefined) {
  72. var keys = visitorKeys[node.type];
  73. for (var i = 0; i < keys.length; i++) {
  74. var key = keys[i]; // we know if it has child keys we can widen to a ParentNode
  75. visitKey(visitor, handler, path, key);
  76. }
  77. if (exit !== undefined) {
  78. result = exit(node, path);
  79. }
  80. }
  81. return result;
  82. }
  83. function get(node, key) {
  84. return node[key];
  85. }
  86. function set(node, key, value) {
  87. node[key] = value;
  88. }
  89. function visitKey(visitor, handler, path, key) {
  90. var node = path.node;
  91. var value = get(node, key);
  92. if (!value) {
  93. return;
  94. }
  95. var keyEnter;
  96. var keyExit;
  97. if (handler !== undefined) {
  98. var keyHandler = getKeyHandler(handler, key);
  99. if (keyHandler !== undefined) {
  100. keyEnter = getEnterFunction(keyHandler);
  101. keyExit = getExitFunction(keyHandler);
  102. }
  103. }
  104. if (keyEnter !== undefined) {
  105. if (keyEnter(node, key) !== undefined) {
  106. throw cannotReplaceOrRemoveInKeyHandlerYet(node, key);
  107. }
  108. }
  109. if (Array.isArray(value)) {
  110. visitArray(visitor, value, path, key);
  111. } else {
  112. var keyPath = new WalkerPath(value, path, key);
  113. var result = visitNode(visitor, keyPath);
  114. if (result !== undefined) {
  115. // TODO: dynamically check the results by having a table of
  116. // expected node types in value space, not just type space
  117. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  118. assignKey(node, key, value, result);
  119. }
  120. }
  121. if (keyExit !== undefined) {
  122. if (keyExit(node, key) !== undefined) {
  123. throw cannotReplaceOrRemoveInKeyHandlerYet(node, key);
  124. }
  125. }
  126. }
  127. function visitArray(visitor, array, parent, parentKey) {
  128. for (var i = 0; i < array.length; i++) {
  129. var node = array[i];
  130. var path = new WalkerPath(node, parent, parentKey);
  131. var result = visitNode(visitor, path);
  132. if (result !== undefined) {
  133. i += spliceArray(array, i, result) - 1;
  134. }
  135. }
  136. }
  137. function assignKey(node, key, value, result) {
  138. if (result === null) {
  139. throw cannotRemoveNode(value, node, key);
  140. } else if (Array.isArray(result)) {
  141. if (result.length === 1) {
  142. set(node, key, result[0]);
  143. } else {
  144. if (result.length === 0) {
  145. throw cannotRemoveNode(value, node, key);
  146. } else {
  147. throw cannotReplaceNode(value, node, key);
  148. }
  149. }
  150. } else {
  151. set(node, key, result);
  152. }
  153. }
  154. function spliceArray(array, index, result) {
  155. if (result === null) {
  156. array.splice(index, 1);
  157. return 0;
  158. } else if (Array.isArray(result)) {
  159. array.splice.apply(array, [index, 1].concat(result));
  160. return result.length;
  161. } else {
  162. array.splice(index, 1, result);
  163. return 1;
  164. }
  165. }
  166. export default function traverse(node, visitor) {
  167. var path = new WalkerPath(node);
  168. visitNode(visitor, path);
  169. }
  170. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3N5bnRheC9saWIvdHJhdmVyc2FsL3RyYXZlcnNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLFNBQUEsU0FBQSxRQUFBLGVBQUE7QUFHQSxPQUFBLFdBQUEsTUFBQSxvQkFBQTtBQUNBLFNBQUEsZ0JBQUEsRUFBQSxpQkFBQSxFQUFBLG9DQUFBLFFBQUEsVUFBQTtBQUtBLE9BQUEsVUFBQSxNQUFBLFFBQUE7O0FBU0EsU0FBQSxnQkFBQSxDQUFBLE9BQUEsRUFDZ0Q7QUFFOUMsTUFBSSxPQUFBLE9BQUEsS0FBSixVQUFBLEVBQW1DO0FBQ2pDLFdBQUEsT0FBQTtBQURGLEdBQUEsTUFFTztBQUNMLFdBQU8sT0FBTyxDQUFkLEtBQUE7QUFDRDtBQUNGOztBQVFELFNBQUEsZUFBQSxDQUFBLE9BQUEsRUFDZ0Q7QUFFOUMsTUFBSSxPQUFBLE9BQUEsS0FBSixVQUFBLEVBQW1DO0FBQ2pDLFdBQUEsU0FBQTtBQURGLEdBQUEsTUFFTztBQUNMLFdBQU8sT0FBTyxDQUFkLElBQUE7QUFDRDtBQUNGOztBQUVELFNBQUEsYUFBQSxDQUFBLE9BQUEsRUFBQSxHQUFBLEVBRVE7QUFFTixNQUFJLFVBQVUsR0FBRyxPQUFBLE9BQUEsS0FBQSxVQUFBLEdBQWdDLE9BQU8sQ0FBdkMsSUFBQSxHQUFqQixTQUFBO0FBQ0EsTUFBSSxVQUFVLEtBQWQsU0FBQSxFQUE4QjtBQUU5QixNQUFJLFVBQVUsR0FBRyxVQUFVLENBQTNCLEdBQTJCLENBQTNCOztBQUNBLE1BQUksVUFBVSxLQUFkLFNBQUEsRUFBOEI7QUFDNUIsV0FBQSxVQUFBO0FBQ0Q7O0FBQ0QsU0FBTyxVQUFVLENBQWpCLEdBQUE7QUFDRDs7QUFPRCxTQUFBLGNBQUEsQ0FBQSxPQUFBLEVBQUEsUUFBQSxFQUVxQjtBQUVuQixNQUFJLFFBQVEsS0FBUixVQUFBLElBQTJCLFFBQVEsS0FBdkMsT0FBQSxFQUFxRDtBQUNuRCxRQUFJLE9BQU8sQ0FB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QUVPO0FBQ0wsVUFBSSxNQUFNLENBQU4sTUFBQSxLQUFKLENBQUEsRUFBeUI7QUFDdkIsY0FBTSxnQkFBZ0IsQ0FBQSxLQUFBLEVBQUEsSUFBQSxFQUF0QixHQUFzQixDQUF0QjtBQURGLE9BQUEsTUFFTztBQUNMLGNBQU0saUJBQWlCLENBQUEsS0FBQSxFQUFBLElBQUEsRUFBdkIsR0FBdUIsQ0FBdkI7QUFDRDtBQUNGO0FBVEksR0FBQSxNQVVBO0FBQ0wsSUFBQSxHQUFHLENBQUEsSUFBQSxFQUFBLEdBQUEsRUFBSCxNQUFHLENBQUg7QUFDRDtBQUNGOztBQUVELFNBQUEsV0FBQSxDQUFBLEtBQUEsRUFBQSxLQUFBLEVBQUEsTUFBQSxFQUFpRztBQUMvRixNQUFJLE1BQU0sS0FBVixJQUFBLEVBQXFCO0FBQ25CLElBQUEsS0FBSyxDQUFMLE1BQUEsQ0FBQSxLQUFBLEVBQUEsQ0FBQTtBQUNBLFdBQUEsQ0FBQTtBQUZGLEdBQUEsTUFHTyxJQUFJLEtBQUssQ0FBTCxPQUFBLENBQUosTUFBSSxDQUFKLEVBQTJCO0FBQ2hDLElBQUEsS0FBSyxDQUFMLE1BQUEsT0FBQSxLQUFLLEdBQUwsS0FBSyxFQUFMLENBQUssU0FBTCxNQUFLLEVBQUw7QUFDQSxXQUFPLE1BQU0sQ0FBYixNQUFBO0FBRkssR0FBQSxNQUdBO0FBQ0wsSUFBQSxLQUFLLENBQUwsTUFBQSxDQUFBLEtBQUEsRUFBQSxDQUFBLEVBQUEsTUFBQTtBQUNBLFdBQUEsQ0FBQTtBQUNEO0FBQ0Y7O0FBRUQsZUFBYyxTQUFBLFFBQUEsQ0FBQSxJQUFBLEVBQUEsT0FBQSxFQUF5RDtBQUNyRSxNQUFJLElBQUksR0FBRyxJQUFBLFVBQUEsQ0FBWCxJQUFXLENBQVg7QUFDQSxFQUFBLFNBQVMsQ0FBQSxPQUFBLEVBQVQsSUFBUyxDQUFUO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMT0NBTF9ERUJVRyB9IGZyb20gJ0BnbGltbWVyL2xvY2FsLWRlYnVnLWZsYWdzJztcbmltcG9ydCB7IGRlcHJlY2F0ZSB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuXG5pbXBvcnQgKiBhcyBBU1R2MSBmcm9tICcuLi92MS9hcGknO1xuaW1wb3J0IHZpc2l0b3JLZXlzLCB7IFZpc2l0b3JLZXksIFZpc2l0b3JLZXlzIH0gZnJvbSAnLi4vdjEvdmlzaXRvci1rZXlzJztcbmltcG9ydCB7XG4gIGNhbm5vdFJlbW92ZU5vZGUsXG4gIGNhbm5vdFJlcGxhY2VOb2RlLFxuICBjYW5ub3RSZXBsYWNlT3JSZW1vdmVJbktleUhhbmRsZXJZZXQsXG59IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCBXYWxrZXJQYXRoIGZyb20gJy4vcGF0aCc7XG5pbXBvcnQgeyBLZXlIYW5kbGVyLCBLZXlUcmF2ZXJzYWwsIE5vZGVIYW5kbGVyLCBOb2RlVHJhdmVyc2FsLCBOb2RlVmlzaXRvciB9IGZyb20gJy4vdmlzaXRvcic7XG5cbmZ1bmN0aW9uIGdldEVudGVyRnVuY3Rpb248TiBleHRlbmRzIEFTVHYxLk5vZGU+KFxuICBoYW5kbGVyOiBOb2RlVHJhdmVyc2FsPE4+XG4pOiBOb2RlSGFuZGxlcjxOPiB8IHVuZGVmaW5lZDtcbmZ1bmN0aW9uIGdldEVudGVyRnVuY3Rpb248TiBleHRlbmRzIEFTVHYxLk5vZGUsIEsgZXh0ZW5kcyBWaXNpdG9yS2V5PE4+PihcbiAgaGFuZGxlcjogS2V5VHJhdmVyc2FsPE4sIEs+XG4pOiBLZXlIYW5kbGVyPE4sIEs+IHwgdW5kZWZpbmVkO1xuZnVuY3Rpb24gZ2V0RW50ZXJGdW5jdGlvbjxOIGV4dGVuZHMgQVNUdjEuTm9kZSwgSyBleHRlbmRzIFZpc2l0b3JLZXk8Tj4+KFxuICBoYW5kbGVyOiBOb2RlVHJhdmVyc2FsPE4+IHwgS2V5VHJhdmVyc2FsPE4sIEs+XG4pOiBOb2RlSGFuZGxlcjxOPiB8IEtleUhhbmRsZXI8TiwgSz4gfCB1bmRlZmluZWQge1xuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gaGFuZGxlcjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gaGFuZGxlci5lbnRlciBhcyBOb2RlSGFuZGxlcjxOPiB8IEtleUhhbmRsZXI8TiwgSz47XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0RXhpdEZ1bmN0aW9uPE4gZXh0ZW5kcyBBU1R2MS5Ob2RlPihcbiAgaGFuZGxlcjogTm9kZVRyYXZlcnNhbDxOPlxuKTogTm9kZUhhbmRsZXI8Tj4gfCB1bmRlZmluZWQ7XG5mdW5jdGlvbiBnZXRFeGl0RnVuY3Rpb248TiBleHRlbmRzIEFTVHYxLk5vZGUsIEsgZXh0ZW5kcyBWaXNpdG9yS2V5PE4+PihcbiAgaGFuZGxlcjogS2V5VHJhdmVyc2FsPE4sIEs+XG4pOiBLZXlIYW5kbGVyPE4sIEs+IHwgdW5kZWZpbmVkO1xuZnVuY3Rpb24gZ2V0RXhpdEZ1bmN0aW9uPE4gZXh0ZW5kcyBBU1R2MS5Ob2RlLCBLIGV4dGVuZHMgVmlzaXRvcktleTxOPj4oXG4gIGhhbmRsZXI6IE5vZGVUcmF2ZXJzYWw8Tj4gfCBLZXlUcmF2ZXJzYWw8TiwgSz5cbik6IE5vZGVIYW5kbGVyPE4+IHwgS2V5SGFuZGxlcjxOLCBLPiB8IHVuZGVmaW5lZCB7XG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGhhbmRsZXIuZXhpdCBhcyBOb2RlSGFuZGxlcjxOPiB8IEtleUhhbmRsZXI8TiwgSz47XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0S2V5SGFuZGxlcjxOIGV4dGVuZHMgQVNUdjEuTm9kZSwgSyBleHRlbmRzIFZpc2l0b3JLZXk8Tj4+KFxuICBoYW5kbGVyOiBOb2RlVHJhdmVyc2FsPE4+LFxuICBrZXk6IEtcbik6IEtleVRyYXZlcnNhbDxOLCBLPiB8IEtleVRyYXZlcnNhbDxOLCBWaXNpdG9yS2V5PE4+PiB8IHVuZGVmaW5lZCB7XG4gIGxldCBrZXlWaXNpdG9yID0gdHlwZW9mIGhhbmRsZXIgIT09ICdmdW5jdGlvbicgPyBoYW5kbGVyLmtleXMgOiB1bmRlZmluZWQ7XG4gIGlmIChrZXlWaXNpdG9yID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICBsZXQga2V5SGFuZGxlciA9IGtleVZpc2l0b3Jba2V5XTtcbiAgaWYgKGtleUhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBrZXlIYW5kbGVyIGFzIEtleVRyYXZlcnNhbDxOLCBLPjtcbiAgfVxuICByZXR1cm4ga2V5VmlzaXRvci5BbGw7XG59XG5cbmZ1bmN0aW9uIGdldE5vZGVIYW5kbGVyPE4gZXh0ZW5kcyBBU1R2MS5Ob2RlPihcbiAgdmlzaXRvcjogTm9kZVZpc2l0b3IsXG4gIG5vZGVUeXBlOiBOWyd0eXBlJ11cbik6IE5vZGVUcmF2ZXJzYWw8Tj47XG5mdW5jdGlvbiBnZXROb2RlSGFuZGxlcih2aXNpdG9yOiBOb2RlVmlzaXRvciwgbm9kZVR5cGU6ICdBbGwnKTogTm9kZVRyYXZlcnNhbDxBU1R2MS5Ob2RlPjtcbmZ1bmN0aW9uIGdldE5vZGVIYW5kbGVyPE4gZXh0ZW5kcyBBU1R2MS5Ob2RlPihcbiAgdmlzaXRvcjogTm9kZVZpc2l0b3IsXG4gIG5vZGVUeXBlOiBOWyd0eXBlJ11cbik6IE5vZGVUcmF2ZXJzYWw8QVNUdjEuTm9kZT4gfCB1bmRlZmluZWQge1xuICBpZiAobm9kZVR5cGUgPT09ICdUZW1wbGF0ZScgfHwgbm9kZVR5cGUgPT09ICdCbG9jaycpIHtcbiAgICBpZiAodmlzaXRvci5Qcm9ncmFtKSB7XG4gICAgICBpZiAoTE9DQUxfREVCVUcpIHtcbiAgICAgICAgZGVwcmVjYXRlKFxuICAgICAgICAgIGBUaGUgJ1Byb2dyYW0nIHZpc2l0b3Igbm9kZSBpcyBkZXByZWNhdGVkLiBVc2UgJ1RlbXBsYXRlJyBvciAnQmxvY2snIGluc3RlYWQgKG5vZGUgd2FzICcke25vZGVUeXBlfScpIGBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHZpc2l0b3IuUHJvZ3JhbSBhcyBOb2RlVHJhdmVyc2FsPEFTVHYxLk5vZGU+O1xuICAgIH1cbiAgfVxuXG4gIGxldCBoYW5kbGVyID0gdmlzaXRvcltub2RlVHlwZV07XG4gIGlmIChoYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gKGhhbmRsZXIgYXMgdW5rbm93bikgYXMgTm9kZVRyYXZlcnNhbDxBU1R2MS5Ob2RlPjtcbiAgfVxuICByZXR1cm4gdmlzaXRvci5BbGw7XG59XG5cbmZ1bmN0aW9uIHZpc2l0Tm9kZTxOIGV4dGVuZHMgQVNUdjEuTm9kZT4oXG4gIHZpc2l0b3I6IE5vZGVWaXNpdG9yLFxuICBwYXRoOiBXYWxrZXJQYXRoPE4+XG4pOiBBU1R2MS5Ob2RlIHwgQVNUdjEuTm9kZVtdIHwgdW5kZWZpbmVkIHwgbnVsbCB8IHZvaWQge1xuICBsZXQgeyBub2RlLCBwYXJlbnQsIHBhcmVudEtleSB9ID0gcGF0aDtcblxuICBsZXQgaGFuZGxlcjogTm9kZVRyYXZlcnNhbDxOPiA9IGdldE5vZGVIYW5kbGVyKHZpc2l0b3IsIG5vZGUudHlwZSk7XG4gIGxldCBlbnRlcjtcbiAgbGV0IGV4aXQ7XG5cbiAgaWYgKGhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgIGVudGVyID0gZ2V0RW50ZXJGdW5jdGlvbihoYW5kbGVyKTtcbiAgICBleGl0ID0gZ2V0RXhpdEZ1bmN0aW9uKGhhbmRsZXIpO1xuICB9XG5cbiAgbGV0IHJlc3VsdDogQVNUdjEuTm9kZSB8IEFTVHYxLk5vZGVbXSB8IHVuZGVmaW5lZCB8IG51bGwgfCB2b2lkO1xuICBpZiAoZW50ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgIHJlc3VsdCA9IGVudGVyKG5vZGUsIHBhdGgpO1xuICB9XG5cbiAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkICYmIHJlc3VsdCAhPT0gbnVsbCkge1xuICAgIGlmIChKU09OLnN0cmluZ2lmeShub2RlKSA9PT0gSlNPTi5zdHJpbmdpZnkocmVzdWx0KSkge1xuICAgICAgcmVzdWx0ID0gdW5kZWZpbmVkO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHQpKSB7XG4gICAgICB2aXNpdEFycmF5KHZpc2l0b3IsIHJlc3VsdCwgcGFyZW50LCBwYXJlbnRLZXkpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHBhdGggPSBuZXcgV2Fsa2VyUGF0aChyZXN1bHQsIHBhcmVudCwgcGFyZW50S2V5KTtcbiAgICAgIHJldHVybiB2aXNpdE5vZGUodmlzaXRvciwgcGF0aCkgfHwgcmVzdWx0O1xuICAgIH1cbiAgfVxuXG4gIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgIGxldCBrZXlzID0gdmlzaXRvcktleXNbbm9kZS50eXBlXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IGtleSA9IGtleXNbaV0gYXMgVmlzaXRvcktleXNbTlsndHlwZSddXSAmIGtleW9mIE47XG4gICAgICAvLyB3ZSBrbm93IGlmIGl0IGhhcyBjaGlsZCBrZXlzIHdlIGNhbiB3aWRlbiB0byBhIFBhcmVudE5vZGVcbiAgICAgIHZpc2l0S2V5KHZpc2l0b3IsIGhhbmRsZXIsIHBhdGgsIGtleSk7XG4gICAgfVxuXG4gICAgaWYgKGV4aXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVzdWx0ID0gZXhpdChub2RlLCBwYXRoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBnZXQ8TiBleHRlbmRzIEFTVHYxLk5vZGU+KFxuICBub2RlOiBOLFxuICBrZXk6IFZpc2l0b3JLZXlzW05bJ3R5cGUnXV0gJiBrZXlvZiBOXG4pOiBBU1R2MS5Ob2RlIHwgQVNUdjEuTm9kZVtdIHtcbiAgcmV0dXJuIChub2RlW2tleV0gYXMgdW5rbm93bikgYXMgQVNUdjEuTm9kZSB8IEFTVHYxLk5vZGVbXTtcbn1cblxuZnVuY3Rpb24gc2V0PE4gZXh0ZW5kcyBBU1R2MS5Ob2RlLCBLIGV4dGVuZHMga2V5b2YgTj4obm9kZTogTiwga2V5OiBLLCB2YWx1ZTogTltLXSk6IHZvaWQge1xuICBub2RlW2tleV0gPSB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gdmlzaXRLZXk8TiBleHRlbmRzIEFTVHYxLk5vZGU+KFxuICB2aXNpdG9yOiBOb2RlVmlzaXRvcixcbiAgaGFuZGxlcjogTm9kZVRyYXZlcnNhbDxOPixcbiAgcGF0aDogV2Fsa2VyUGF0aDxOPixcbiAga2V5OiBWaXNpdG9yS2V5c1tOWyd0eXBlJ11dICYga2V5b2YgTlxuKSB7XG4gIGxldCB7IG5vZGUgfSA9IHBhdGg7XG5cbiAgbGV0IHZhbHVlID0gZ2V0KG5vZGUsIGtleSk7XG4gIGlmICghdmFsdWUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBsZXQga2V5RW50ZXI7XG4gIGxldCBrZXlFeGl0O1xuXG4gIGlmIChoYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICBsZXQga2V5SGFuZGxlciA9IGdldEtleUhhbmRsZXIoaGFuZGxlciwga2V5KTtcbiAgICBpZiAoa2V5SGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBrZXlFbnRlciA9IGdldEVudGVyRnVuY3Rpb24oa2V5SGFuZGxlcik7XG4gICAgICBrZXlFeGl0ID0gZ2V0RXhpdEZ1bmN0aW9uKGtleUhhbmRsZXIpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChrZXlFbnRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGtleUVudGVyKG5vZGUsIGtleSkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgY2Fubm90UmVwbGFjZU9yUmVtb3ZlSW5LZXlIYW5kbGVyWWV0KG5vZGUsIGtleSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgdmlzaXRBcnJheSh2aXNpdG9yLCB2YWx1ZSwgcGF0aCwga2V5KTtcbiAgfSBlbHNlIHtcbiAgICBsZXQga2V5UGF0aCA9IG5ldyBXYWxrZXJQYXRoKHZhbHVlLCBwYXRoLCBrZXkpO1xuICAgIGxldCByZXN1bHQgPSB2aXNpdE5vZGUodmlzaXRvciwga2V5UGF0aCk7XG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBUT0RPOiBkeW5hbWljYWxseSBjaGVjayB0aGUgcmVzdWx0cyBieSBoYXZpbmcgYSB0YWJsZSBvZlxuICAgICAgLy8gZXhwZWN0ZWQgbm9kZSB0eXBlcyBpbiB2YWx1ZSBzcGFjZSwgbm90IGp1c3QgdHlwZSBzcGFjZVxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIGFzc2lnbktleShub2RlLCBrZXksIHZhbHVlLCByZXN1bHQgYXMgYW55KTtcbiAgICB9XG4gIH1cblxuICBpZiAoa2V5RXhpdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGtleUV4aXQobm9kZSwga2V5KSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBjYW5ub3RSZXBsYWNlT3JSZW1vdmVJbktleUhhbmRsZXJZZXQobm9kZSwga2V5KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmlzaXRBcnJheShcbiAgdmlzaXRvcjogTm9kZVZpc2l0b3IsXG4gIGFycmF5OiBBU1R2MS5Ob2RlW10sXG4gIHBhcmVudDogV2Fsa2VyUGF0aDxBU1R2MS5Ob2RlPiB8IG51bGwsXG4gIHBhcmVudEtleTogc3RyaW5nIHwgbnVsbFxuKSB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgbm9kZSA9IGFycmF5W2ldO1xuICAgIGxldCBwYXRoID0gbmV3IFdhbGtlclBhdGgobm9kZSwgcGFyZW50LCBwYXJlbnRLZXkpO1xuICAgIGxldCByZXN1bHQgPSB2aXNpdE5vZGUodmlzaXRvciwgcGF0aCk7XG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpICs9IHNwbGljZUFycmF5KGFycmF5LCBpLCByZXN1bHQpIC0gMTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYXNzaWduS2V5PE4gZXh0ZW5kcyBBU1R2MS5Ob2RlLCBLIGV4dGVuZHMgVmlzaXRvcktleTxOPj4oXG4gIG5vZGU6IE4sXG4gIGtleTogSyxcbiAgdmFsdWU6IEFTVHYxLk5vZGUsXG4gIHJlc3VsdDogTltLXSB8IFtOW0tdXSB8IG51bGxcbikge1xuICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgdGhyb3cgY2Fubm90UmVtb3ZlTm9kZSh2YWx1ZSwgbm9kZSwga2V5KTtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICBpZiAocmVzdWx0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgc2V0KG5vZGUsIGtleSwgcmVzdWx0WzBdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHJlc3VsdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgY2Fubm90UmVtb3ZlTm9kZSh2YWx1ZSwgbm9kZSwga2V5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGNhbm5vdFJlcGxhY2VOb2RlKHZhbHVlLCBub2RlLCBrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzZXQobm9kZSwga2V5LCByZXN1bHQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNwbGljZUFycmF5KGFycmF5OiBBU1R2MS5Ob2RlW10sIGluZGV4OiBudW1iZXIsIHJlc3VsdDogQVNUdjEuTm9kZSB8IEFTVHYxLk5vZGVbXSB8IG51bGwpIHtcbiAgaWYgKHJlc3VsdCA9PT0gbnVsbCkge1xuICAgIGFycmF5LnNwbGljZShpbmRleCwgMSk7XG4gICAgcmV0dXJuIDA7XG4gIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHQpKSB7XG4gICAgYXJyYXkuc3BsaWNlKGluZGV4LCAxLCAuLi5yZXN1bHQpO1xuICAgIHJldHVybiByZXN1bHQubGVuZ3RoO1xuICB9IGVsc2Uge1xuICAgIGFycmF5LnNwbGljZShpbmRleCwgMSwgcmVzdWx0KTtcbiAgICByZXR1cm4gMTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0cmF2ZXJzZShub2RlOiBBU1R2MS5Ob2RlLCB2aXNpdG9yOiBOb2RlVmlzaXRvcik6IHZvaWQge1xuICBsZXQgcGF0aCA9IG5ldyBXYWxrZXJQYXRoKG5vZGUpO1xuICB2aXNpdE5vZGUodmlzaXRvciwgcGF0aCk7XG59XG4iXSwic291cmNlUm9vdCI6IiJ9