traverse.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. let keyVisitor = typeof handler !== 'function' ? handler.keys : undefined;
  21. if (keyVisitor === undefined) return;
  22. let 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. let handler = visitor[nodeType];
  40. if (handler !== undefined) {
  41. return handler;
  42. }
  43. return visitor.All;
  44. }
  45. function visitNode(visitor, path) {
  46. let {
  47. node,
  48. parent,
  49. parentKey
  50. } = path;
  51. let handler = getNodeHandler(visitor, node.type);
  52. let enter;
  53. let exit;
  54. if (handler !== undefined) {
  55. enter = getEnterFunction(handler);
  56. exit = getExitFunction(handler);
  57. }
  58. let result;
  59. if (enter !== undefined) {
  60. result = enter(node, path);
  61. }
  62. if (result !== undefined && result !== null) {
  63. if (JSON.stringify(node) === JSON.stringify(result)) {
  64. result = undefined;
  65. } else if (Array.isArray(result)) {
  66. visitArray(visitor, result, parent, parentKey);
  67. return result;
  68. } else {
  69. let path = new WalkerPath(result, parent, parentKey);
  70. return visitNode(visitor, path) || result;
  71. }
  72. }
  73. if (result === undefined) {
  74. let keys = visitorKeys[node.type];
  75. for (let i = 0; i < keys.length; i++) {
  76. let key = keys[i]; // we know if it has child keys we can widen to a ParentNode
  77. visitKey(visitor, handler, path, key);
  78. }
  79. if (exit !== undefined) {
  80. result = exit(node, path);
  81. }
  82. }
  83. return result;
  84. }
  85. function get(node, key) {
  86. return node[key];
  87. }
  88. function set(node, key, value) {
  89. node[key] = value;
  90. }
  91. function visitKey(visitor, handler, path, key) {
  92. let {
  93. node
  94. } = path;
  95. let value = get(node, key);
  96. if (!value) {
  97. return;
  98. }
  99. let keyEnter;
  100. let keyExit;
  101. if (handler !== undefined) {
  102. let keyHandler = getKeyHandler(handler, key);
  103. if (keyHandler !== undefined) {
  104. keyEnter = getEnterFunction(keyHandler);
  105. keyExit = getExitFunction(keyHandler);
  106. }
  107. }
  108. if (keyEnter !== undefined) {
  109. if (keyEnter(node, key) !== undefined) {
  110. throw cannotReplaceOrRemoveInKeyHandlerYet(node, key);
  111. }
  112. }
  113. if (Array.isArray(value)) {
  114. visitArray(visitor, value, path, key);
  115. } else {
  116. let keyPath = new WalkerPath(value, path, key);
  117. let result = visitNode(visitor, keyPath);
  118. if (result !== undefined) {
  119. // TODO: dynamically check the results by having a table of
  120. // expected node types in value space, not just type space
  121. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  122. assignKey(node, key, value, result);
  123. }
  124. }
  125. if (keyExit !== undefined) {
  126. if (keyExit(node, key) !== undefined) {
  127. throw cannotReplaceOrRemoveInKeyHandlerYet(node, key);
  128. }
  129. }
  130. }
  131. function visitArray(visitor, array, parent, parentKey) {
  132. for (let i = 0; i < array.length; i++) {
  133. let node = array[i];
  134. let path = new WalkerPath(node, parent, parentKey);
  135. let result = visitNode(visitor, path);
  136. if (result !== undefined) {
  137. i += spliceArray(array, i, result) - 1;
  138. }
  139. }
  140. }
  141. function assignKey(node, key, value, result) {
  142. if (result === null) {
  143. throw cannotRemoveNode(value, node, key);
  144. } else if (Array.isArray(result)) {
  145. if (result.length === 1) {
  146. set(node, key, result[0]);
  147. } else {
  148. if (result.length === 0) {
  149. throw cannotRemoveNode(value, node, key);
  150. } else {
  151. throw cannotReplaceNode(value, node, key);
  152. }
  153. }
  154. } else {
  155. set(node, key, result);
  156. }
  157. }
  158. function spliceArray(array, index, result) {
  159. if (result === null) {
  160. array.splice(index, 1);
  161. return 0;
  162. } else if (Array.isArray(result)) {
  163. array.splice(index, 1, ...result);
  164. return result.length;
  165. } else {
  166. array.splice(index, 1, result);
  167. return 1;
  168. }
  169. }
  170. export default function traverse(node, visitor) {
  171. let path = new WalkerPath(node);
  172. visitNode(visitor, path);
  173. }
  174. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3N5bnRheC9saWIvdHJhdmVyc2FsL3RyYXZlcnNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLFNBQVMsU0FBVCxRQUEwQixlQUExQjtBQUdBLE9BQU8sV0FBUCxNQUFxRCxvQkFBckQ7QUFDQSxTQUNFLGdCQURGLEVBRUUsaUJBRkYsRUFHRSxvQ0FIRixRQUlPLFVBSlA7QUFLQSxPQUFPLFVBQVAsTUFBdUIsUUFBdkI7O0FBU0EsU0FBUyxnQkFBVCxDQUNFLE9BREYsRUFDZ0Q7QUFFOUMsTUFBSSxPQUFPLE9BQVAsS0FBbUIsVUFBdkIsRUFBbUM7QUFDakMsV0FBTyxPQUFQO0FBQ0QsR0FGRCxNQUVPO0FBQ0wsV0FBTyxPQUFPLENBQUMsS0FBZjtBQUNEO0FBQ0Y7O0FBUUQsU0FBUyxlQUFULENBQ0UsT0FERixFQUNnRDtBQUU5QyxNQUFJLE9BQU8sT0FBUCxLQUFtQixVQUF2QixFQUFtQztBQUNqQyxXQUFPLFNBQVA7QUFDRCxHQUZELE1BRU87QUFDTCxXQUFPLE9BQU8sQ0FBQyxJQUFmO0FBQ0Q7QUFDRjs7QUFFRCxTQUFTLGFBQVQsQ0FDRSxPQURGLEVBRUUsR0FGRixFQUVRO0FBRU4sTUFBSSxVQUFVLEdBQUcsT0FBTyxPQUFQLEtBQW1CLFVBQW5CLEdBQWdDLE9BQU8sQ0FBQyxJQUF4QyxHQUErQyxTQUFoRTtBQUNBLE1BQUksVUFBVSxLQUFLLFNBQW5CLEVBQThCO0FBRTlCLE1BQUksVUFBVSxHQUFHLFVBQVUsQ0FBQyxHQUFELENBQTNCOztBQUNBLE1BQUksVUFBVSxLQUFLLFNBQW5CLEVBQThCO0FBQzVCLFdBQU8sVUFBUDtBQUNEOztBQUNELFNBQU8sVUFBVSxDQUFDLEdBQWxCO0FBQ0Q7O0FBT0QsU0FBUyxjQUFULENBQ0UsT0FERixFQUVFLFFBRkYsRUFFcUI7QUFFbkIsTUFBSSxRQUFRLEtBQUssVUFBYixJQUEyQixRQUFRLEtBQUssT0FBNUMsRUFBcUQ7QUFDbkQsUUFBSSxPQUFPLENBQUMsT0FBWixFQUFxQjtBQUNuQjtBQUFBO0FBQUEsUUFBaUI7QUFBQSw4QkFDZixTQUFTLENBQ1AsMEZBQTBGLFFBQVEsS0FEM0YsQ0FETTtBQUloQjs7QUFFRCxhQUFPLE9BQU8sQ0FBQyxPQUFmO0FBQ0Q7QUFDRjs7QUFFRCxNQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsUUFBRCxDQUFyQjs7QUFDQSxNQUFJLE9BQU8sS0FBSyxTQUFoQixFQUEyQjtBQUN6QixXQUFRLE9BQVI7QUFDRDs7QUFDRCxTQUFPLE9BQU8sQ0FBQyxHQUFmO0FBQ0Q7O0FBRUQsU0FBUyxTQUFULENBQ0UsT0FERixFQUVFLElBRkYsRUFFcUI7QUFFbkIsTUFBSTtBQUFFLElBQUEsSUFBRjtBQUFRLElBQUEsTUFBUjtBQUFnQixJQUFBO0FBQWhCLE1BQThCLElBQWxDO0FBRUEsTUFBSSxPQUFPLEdBQXFCLGNBQWMsQ0FBQyxPQUFELEVBQVUsSUFBSSxDQUFDLElBQWYsQ0FBOUM7QUFDQSxNQUFJLEtBQUo7QUFDQSxNQUFJLElBQUo7O0FBRUEsTUFBSSxPQUFPLEtBQUssU0FBaEIsRUFBMkI7QUFDekIsSUFBQSxLQUFLLEdBQUcsZ0JBQWdCLENBQUMsT0FBRCxDQUF4QjtBQUNBLElBQUEsSUFBSSxHQUFHLGVBQWUsQ0FBQyxPQUFELENBQXRCO0FBQ0Q7O0FBRUQsTUFBSSxNQUFKOztBQUNBLE1BQUksS0FBSyxLQUFLLFNBQWQsRUFBeUI7QUFDdkIsSUFBQSxNQUFNLEdBQUcsS0FBSyxDQUFDLElBQUQsRUFBTyxJQUFQLENBQWQ7QUFDRDs7QUFFRCxNQUFJLE1BQU0sS0FBSyxTQUFYLElBQXdCLE1BQU0sS0FBSyxJQUF2QyxFQUE2QztBQUMzQyxRQUFJLElBQUksQ0FBQyxTQUFMLENBQWUsSUFBZixNQUF5QixJQUFJLENBQUMsU0FBTCxDQUFlLE1BQWYsQ0FBN0IsRUFBcUQ7QUFDbkQsTUFBQSxNQUFNLEdBQUcsU0FBVDtBQUNELEtBRkQsTUFFTyxJQUFJLEtBQUssQ0FBQyxPQUFOLENBQWMsTUFBZCxDQUFKLEVBQTJCO0FBQ2hDLE1BQUEsVUFBVSxDQUFDLE9BQUQsRUFBVSxNQUFWLEVBQWtCLE1BQWxCLEVBQTBCLFNBQTFCLENBQVY7QUFDQSxhQUFPLE1BQVA7QUFDRCxLQUhNLE1BR0E7QUFDTCxVQUFJLElBQUksR0FBRyxJQUFJLFVBQUosQ0FBZSxNQUFmLEVBQXVCLE1BQXZCLEVBQStCLFNBQS9CLENBQVg7QUFDQSxhQUFPLFNBQVMsQ0FBQyxPQUFELEVBQVUsSUFBVixDQUFULElBQTRCLE1BQW5DO0FBQ0Q7QUFDRjs7QUFFRCxNQUFJLE1BQU0sS0FBSyxTQUFmLEVBQTBCO0FBQ3hCLFFBQUksSUFBSSxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBTixDQUF0Qjs7QUFFQSxTQUFLLElBQUksQ0FBQyxHQUFHLENBQWIsRUFBZ0IsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUF6QixFQUFpQyxDQUFDLEVBQWxDLEVBQXNDO0FBQ3BDLFVBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFELENBQWQsQ0FEb0MsQ0FFcEM7O0FBQ0EsTUFBQSxRQUFRLENBQUMsT0FBRCxFQUFVLE9BQVYsRUFBbUIsSUFBbkIsRUFBeUIsR0FBekIsQ0FBUjtBQUNEOztBQUVELFFBQUksSUFBSSxLQUFLLFNBQWIsRUFBd0I7QUFDdEIsTUFBQSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUQsRUFBTyxJQUFQLENBQWI7QUFDRDtBQUNGOztBQUVELFNBQU8sTUFBUDtBQUNEOztBQUVELFNBQVMsR0FBVCxDQUNFLElBREYsRUFFRSxHQUZGLEVBRXVDO0FBRXJDLFNBQVEsSUFBSSxDQUFDLEdBQUQsQ0FBWjtBQUNEOztBQUVELFNBQVMsR0FBVCxDQUFzRCxJQUF0RCxFQUErRCxHQUEvRCxFQUF1RSxLQUF2RSxFQUFrRjtBQUNoRixFQUFBLElBQUksQ0FBQyxHQUFELENBQUosR0FBWSxLQUFaO0FBQ0Q7O0FBRUQsU0FBUyxRQUFULENBQ0UsT0FERixFQUVFLE9BRkYsRUFHRSxJQUhGLEVBSUUsR0FKRixFQUl1QztBQUVyQyxNQUFJO0FBQUUsSUFBQTtBQUFGLE1BQVcsSUFBZjtBQUVBLE1BQUksS0FBSyxHQUFHLEdBQUcsQ0FBQyxJQUFELEVBQU8sR0FBUCxDQUFmOztBQUNBLE1BQUksQ0FBQyxLQUFMLEVBQVk7QUFDVjtBQUNEOztBQUVELE1BQUksUUFBSjtBQUNBLE1BQUksT0FBSjs7QUFFQSxNQUFJLE9BQU8sS0FBSyxTQUFoQixFQUEyQjtBQUN6QixRQUFJLFVBQVUsR0FBRyxhQUFhLENBQUMsT0FBRCxFQUFVLEdBQVYsQ0FBOUI7O0FBQ0EsUUFBSSxVQUFVLEtBQUssU0FBbkIsRUFBOEI7QUFDNUIsTUFBQSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsVUFBRCxDQUEzQjtBQUNBLE1BQUEsT0FBTyxHQUFHLGVBQWUsQ0FBQyxVQUFELENBQXpCO0FBQ0Q7QUFDRjs7QUFFRCxNQUFJLFFBQVEsS0FBSyxTQUFqQixFQUE0QjtBQUMxQixRQUFJLFFBQVEsQ0FBQyxJQUFELEVBQU8sR0FBUCxDQUFSLEtBQXdCLFNBQTVCLEVBQXVDO0FBQ3JDLFlBQU0sb0NBQW9DLENBQUMsSUFBRCxFQUFPLEdBQVAsQ0FBMUM7QUFDRDtBQUNGOztBQUVELE1BQUksS0FBSyxDQUFDLE9BQU4sQ0FBYyxLQUFkLENBQUosRUFBMEI7QUFDeEIsSUFBQSxVQUFVLENBQUMsT0FBRCxFQUFVLEtBQVYsRUFBaUIsSUFBakIsRUFBdUIsR0FBdkIsQ0FBVjtBQUNELEdBRkQsTUFFTztBQUNMLFFBQUksT0FBTyxHQUFHLElBQUksVUFBSixDQUFlLEtBQWYsRUFBc0IsSUFBdEIsRUFBNEIsR0FBNUIsQ0FBZDtBQUNBLFFBQUksTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFELEVBQVUsT0FBVixDQUF0Qjs7QUFDQSxRQUFJLE1BQU0sS0FBSyxTQUFmLEVBQTBCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBLE1BQUEsU0FBUyxDQUFDLElBQUQsRUFBTyxHQUFQLEVBQVksS0FBWixFQUFtQixNQUFuQixDQUFUO0FBQ0Q7QUFDRjs7QUFFRCxNQUFJLE9BQU8sS0FBSyxTQUFoQixFQUEyQjtBQUN6QixRQUFJLE9BQU8sQ0FBQyxJQUFELEVBQU8sR0FBUCxDQUFQLEtBQXVCLFNBQTNCLEVBQXNDO0FBQ3BDLFlBQU0sb0NBQW9DLENBQUMsSUFBRCxFQUFPLEdBQVAsQ0FBMUM7QUFDRDtBQUNGO0FBQ0Y7O0FBRUQsU0FBUyxVQUFULENBQ0UsT0FERixFQUVFLEtBRkYsRUFHRSxNQUhGLEVBSUUsU0FKRixFQUkwQjtBQUV4QixPQUFLLElBQUksQ0FBQyxHQUFHLENBQWIsRUFBZ0IsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUExQixFQUFrQyxDQUFDLEVBQW5DLEVBQXVDO0FBQ3JDLFFBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFELENBQWhCO0FBQ0EsUUFBSSxJQUFJLEdBQUcsSUFBSSxVQUFKLENBQWUsSUFBZixFQUFxQixNQUFyQixFQUE2QixTQUE3QixDQUFYO0FBQ0EsUUFBSSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQUQsRUFBVSxJQUFWLENBQXRCOztBQUNBLFFBQUksTUFBTSxLQUFLLFNBQWYsRUFBMEI7QUFDeEIsTUFBQSxDQUFDLElBQUksV0FBVyxDQUFDLEtBQUQsRUFBUSxDQUFSLEVBQVcsTUFBWCxDQUFYLEdBQWdDLENBQXJDO0FBQ0Q7QUFDRjtBQUNGOztBQUVELFNBQVMsU0FBVCxDQUNFLElBREYsRUFFRSxHQUZGLEVBR0UsS0FIRixFQUlFLE1BSkYsRUFJOEI7QUFFNUIsTUFBSSxNQUFNLEtBQUssSUFBZixFQUFxQjtBQUNuQixVQUFNLGdCQUFnQixDQUFDLEtBQUQsRUFBUSxJQUFSLEVBQWMsR0FBZCxDQUF0QjtBQUNELEdBRkQsTUFFTyxJQUFJLEtBQUssQ0FBQyxPQUFOLENBQWMsTUFBZCxDQUFKLEVBQTJCO0FBQ2hDLFFBQUksTUFBTSxDQUFDLE1BQVAsS0FBa0IsQ0FBdEIsRUFBeUI7QUFDdkIsTUFBQSxHQUFHLENBQUMsSUFBRCxFQUFPLEdBQVAsRUFBWSxNQUFNLENBQUMsQ0FBRCxDQUFsQixDQUFIO0FBQ0QsS0FGRCxNQUVPO0FBQ0wsVUFBSSxNQUFNLENBQUMsTUFBUCxLQUFrQixDQUF0QixFQUF5QjtBQUN2QixjQUFNLGdCQUFnQixDQUFDLEtBQUQsRUFBUSxJQUFSLEVBQWMsR0FBZCxDQUF0QjtBQUNELE9BRkQsTUFFTztBQUNMLGNBQU0saUJBQWlCLENBQUMsS0FBRCxFQUFRLElBQVIsRUFBYyxHQUFkLENBQXZCO0FBQ0Q7QUFDRjtBQUNGLEdBVk0sTUFVQTtBQUNMLElBQUEsR0FBRyxDQUFDLElBQUQsRUFBTyxHQUFQLEVBQVksTUFBWixDQUFIO0FBQ0Q7QUFDRjs7QUFFRCxTQUFTLFdBQVQsQ0FBcUIsS0FBckIsRUFBMEMsS0FBMUMsRUFBeUQsTUFBekQsRUFBaUc7QUFDL0YsTUFBSSxNQUFNLEtBQUssSUFBZixFQUFxQjtBQUNuQixJQUFBLEtBQUssQ0FBQyxNQUFOLENBQWEsS0FBYixFQUFvQixDQUFwQjtBQUNBLFdBQU8sQ0FBUDtBQUNELEdBSEQsTUFHTyxJQUFJLEtBQUssQ0FBQyxPQUFOLENBQWMsTUFBZCxDQUFKLEVBQTJCO0FBQ2hDLElBQUEsS0FBSyxDQUFDLE1BQU4sQ0FBYSxLQUFiLEVBQW9CLENBQXBCLEVBQXVCLEdBQUcsTUFBMUI7QUFDQSxXQUFPLE1BQU0sQ0FBQyxNQUFkO0FBQ0QsR0FITSxNQUdBO0FBQ0wsSUFBQSxLQUFLLENBQUMsTUFBTixDQUFhLEtBQWIsRUFBb0IsQ0FBcEIsRUFBdUIsTUFBdkI7QUFDQSxXQUFPLENBQVA7QUFDRDtBQUNGOztBQUVELGVBQWMsU0FBVSxRQUFWLENBQW1CLElBQW5CLEVBQXFDLE9BQXJDLEVBQXlEO0FBQ3JFLE1BQUksSUFBSSxHQUFHLElBQUksVUFBSixDQUFlLElBQWYsQ0FBWDtBQUNBLEVBQUEsU0FBUyxDQUFDLE9BQUQsRUFBVSxJQUFWLENBQVQ7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExPQ0FMX0RFQlVHIH0gZnJvbSAnQGdsaW1tZXIvbG9jYWwtZGVidWctZmxhZ3MnO1xuaW1wb3J0IHsgZGVwcmVjYXRlIH0gZnJvbSAnQGdsaW1tZXIvdXRpbCc7XG5cbmltcG9ydCAqIGFzIEFTVHYxIGZyb20gJy4uL3YxL2FwaSc7XG5pbXBvcnQgdmlzaXRvcktleXMsIHsgVmlzaXRvcktleSwgVmlzaXRvcktleXMgfSBmcm9tICcuLi92MS92aXNpdG9yLWtleXMnO1xuaW1wb3J0IHtcbiAgY2Fubm90UmVtb3ZlTm9kZSxcbiAgY2Fubm90UmVwbGFjZU5vZGUsXG4gIGNhbm5vdFJlcGxhY2VPclJlbW92ZUluS2V5SGFuZGxlcllldCxcbn0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IFdhbGtlclBhdGggZnJvbSAnLi9wYXRoJztcbmltcG9ydCB7IEtleUhhbmRsZXIsIEtleVRyYXZlcnNhbCwgTm9kZUhhbmRsZXIsIE5vZGVUcmF2ZXJzYWwsIE5vZGVWaXNpdG9yIH0gZnJvbSAnLi92aXNpdG9yJztcblxuZnVuY3Rpb24gZ2V0RW50ZXJGdW5jdGlvbjxOIGV4dGVuZHMgQVNUdjEuTm9kZT4oXG4gIGhhbmRsZXI6IE5vZGVUcmF2ZXJzYWw8Tj5cbik6IE5vZGVIYW5kbGVyPE4+IHwgdW5kZWZpbmVkO1xuZnVuY3Rpb24gZ2V0RW50ZXJGdW5jdGlvbjxOIGV4dGVuZHMgQVNUdjEuTm9kZSwgSyBleHRlbmRzIFZpc2l0b3JLZXk8Tj4+KFxuICBoYW5kbGVyOiBLZXlUcmF2ZXJzYWw8TiwgSz5cbik6IEtleUhhbmRsZXI8TiwgSz4gfCB1bmRlZmluZWQ7XG5mdW5jdGlvbiBnZXRFbnRlckZ1bmN0aW9uPE4gZXh0ZW5kcyBBU1R2MS5Ob2RlLCBLIGV4dGVuZHMgVmlzaXRvcktleTxOPj4oXG4gIGhhbmRsZXI6IE5vZGVUcmF2ZXJzYWw8Tj4gfCBLZXlUcmF2ZXJzYWw8TiwgSz5cbik6IE5vZGVIYW5kbGVyPE4+IHwgS2V5SGFuZGxlcjxOLCBLPiB8IHVuZGVmaW5lZCB7XG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBoYW5kbGVyO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBoYW5kbGVyLmVudGVyIGFzIE5vZGVIYW5kbGVyPE4+IHwgS2V5SGFuZGxlcjxOLCBLPjtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRFeGl0RnVuY3Rpb248TiBleHRlbmRzIEFTVHYxLk5vZGU+KFxuICBoYW5kbGVyOiBOb2RlVHJhdmVyc2FsPE4+XG4pOiBOb2RlSGFuZGxlcjxOPiB8IHVuZGVmaW5lZDtcbmZ1bmN0aW9uIGdldEV4aXRGdW5jdGlvbjxOIGV4dGVuZHMgQVNUdjEuTm9kZSwgSyBleHRlbmRzIFZpc2l0b3JLZXk8Tj4+KFxuICBoYW5kbGVyOiBLZXlUcmF2ZXJzYWw8TiwgSz5cbik6IEtleUhhbmRsZXI8TiwgSz4gfCB1bmRlZmluZWQ7XG5mdW5jdGlvbiBnZXRFeGl0RnVuY3Rpb248TiBleHRlbmRzIEFTVHYxLk5vZGUsIEsgZXh0ZW5kcyBWaXNpdG9yS2V5PE4+PihcbiAgaGFuZGxlcjogTm9kZVRyYXZlcnNhbDxOPiB8IEtleVRyYXZlcnNhbDxOLCBLPlxuKTogTm9kZUhhbmRsZXI8Tj4gfCBLZXlIYW5kbGVyPE4sIEs+IHwgdW5kZWZpbmVkIHtcbiAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gaGFuZGxlci5leGl0IGFzIE5vZGVIYW5kbGVyPE4+IHwgS2V5SGFuZGxlcjxOLCBLPjtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRLZXlIYW5kbGVyPE4gZXh0ZW5kcyBBU1R2MS5Ob2RlLCBLIGV4dGVuZHMgVmlzaXRvcktleTxOPj4oXG4gIGhhbmRsZXI6IE5vZGVUcmF2ZXJzYWw8Tj4sXG4gIGtleTogS1xuKTogS2V5VHJhdmVyc2FsPE4sIEs+IHwgS2V5VHJhdmVyc2FsPE4sIFZpc2l0b3JLZXk8Tj4+IHwgdW5kZWZpbmVkIHtcbiAgbGV0IGtleVZpc2l0b3IgPSB0eXBlb2YgaGFuZGxlciAhPT0gJ2Z1bmN0aW9uJyA/IGhhbmRsZXIua2V5cyA6IHVuZGVmaW5lZDtcbiAgaWYgKGtleVZpc2l0b3IgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gIGxldCBrZXlIYW5kbGVyID0ga2V5VmlzaXRvcltrZXldO1xuICBpZiAoa2V5SGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGtleUhhbmRsZXIgYXMgS2V5VHJhdmVyc2FsPE4sIEs+O1xuICB9XG4gIHJldHVybiBrZXlWaXNpdG9yLkFsbDtcbn1cblxuZnVuY3Rpb24gZ2V0Tm9kZUhhbmRsZXI8TiBleHRlbmRzIEFTVHYxLk5vZGU+KFxuICB2aXNpdG9yOiBOb2RlVmlzaXRvcixcbiAgbm9kZVR5cGU6IE5bJ3R5cGUnXVxuKTogTm9kZVRyYXZlcnNhbDxOPjtcbmZ1bmN0aW9uIGdldE5vZGVIYW5kbGVyKHZpc2l0b3I6IE5vZGVWaXNpdG9yLCBub2RlVHlwZTogJ0FsbCcpOiBOb2RlVHJhdmVyc2FsPEFTVHYxLk5vZGU+O1xuZnVuY3Rpb24gZ2V0Tm9kZUhhbmRsZXI8TiBleHRlbmRzIEFTVHYxLk5vZGU+KFxuICB2aXNpdG9yOiBOb2RlVmlzaXRvcixcbiAgbm9kZVR5cGU6IE5bJ3R5cGUnXVxuKTogTm9kZVRyYXZlcnNhbDxBU1R2MS5Ob2RlPiB8IHVuZGVmaW5lZCB7XG4gIGlmIChub2RlVHlwZSA9PT0gJ1RlbXBsYXRlJyB8fCBub2RlVHlwZSA9PT0gJ0Jsb2NrJykge1xuICAgIGlmICh2aXNpdG9yLlByb2dyYW0pIHtcbiAgICAgIGlmIChMT0NBTF9ERUJVRykge1xuICAgICAgICBkZXByZWNhdGUoXG4gICAgICAgICAgYFRoZSAnUHJvZ3JhbScgdmlzaXRvciBub2RlIGlzIGRlcHJlY2F0ZWQuIFVzZSAnVGVtcGxhdGUnIG9yICdCbG9jaycgaW5zdGVhZCAobm9kZSB3YXMgJyR7bm9kZVR5cGV9JykgYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmlzaXRvci5Qcm9ncmFtIGFzIE5vZGVUcmF2ZXJzYWw8QVNUdjEuTm9kZT47XG4gICAgfVxuICB9XG5cbiAgbGV0IGhhbmRsZXIgPSB2aXNpdG9yW25vZGVUeXBlXTtcbiAgaWYgKGhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiAoaGFuZGxlciBhcyB1bmtub3duKSBhcyBOb2RlVHJhdmVyc2FsPEFTVHYxLk5vZGU+O1xuICB9XG4gIHJldHVybiB2aXNpdG9yLkFsbDtcbn1cblxuZnVuY3Rpb24gdmlzaXROb2RlPE4gZXh0ZW5kcyBBU1R2MS5Ob2RlPihcbiAgdmlzaXRvcjogTm9kZVZpc2l0b3IsXG4gIHBhdGg6IFdhbGtlclBhdGg8Tj5cbik6IEFTVHYxLk5vZGUgfCBBU1R2MS5Ob2RlW10gfCB1bmRlZmluZWQgfCBudWxsIHwgdm9pZCB7XG4gIGxldCB7IG5vZGUsIHBhcmVudCwgcGFyZW50S2V5IH0gPSBwYXRoO1xuXG4gIGxldCBoYW5kbGVyOiBOb2RlVHJhdmVyc2FsPE4+ID0gZ2V0Tm9kZUhhbmRsZXIodmlzaXRvciwgbm9kZS50eXBlKTtcbiAgbGV0IGVudGVyO1xuICBsZXQgZXhpdDtcblxuICBpZiAoaGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW50ZXIgPSBnZXRFbnRlckZ1bmN0aW9uKGhhbmRsZXIpO1xuICAgIGV4aXQgPSBnZXRFeGl0RnVuY3Rpb24oaGFuZGxlcik7XG4gIH1cblxuICBsZXQgcmVzdWx0OiBBU1R2MS5Ob2RlIHwgQVNUdjEuTm9kZVtdIHwgdW5kZWZpbmVkIHwgbnVsbCB8IHZvaWQ7XG4gIGlmIChlbnRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmVzdWx0ID0gZW50ZXIobm9kZSwgcGF0aCk7XG4gIH1cblxuICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQgJiYgcmVzdWx0ICE9PSBudWxsKSB7XG4gICAgaWYgKEpTT04uc3RyaW5naWZ5KG5vZGUpID09PSBKU09OLnN0cmluZ2lmeShyZXN1bHQpKSB7XG4gICAgICByZXN1bHQgPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgIHZpc2l0QXJyYXkodmlzaXRvciwgcmVzdWx0LCBwYXJlbnQsIHBhcmVudEtleSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgcGF0aCA9IG5ldyBXYWxrZXJQYXRoKHJlc3VsdCwgcGFyZW50LCBwYXJlbnRLZXkpO1xuICAgICAgcmV0dXJuIHZpc2l0Tm9kZSh2aXNpdG9yLCBwYXRoKSB8fCByZXN1bHQ7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGV0IGtleXMgPSB2aXNpdG9yS2V5c1tub2RlLnR5cGVdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQga2V5ID0ga2V5c1tpXSBhcyBWaXNpdG9yS2V5c1tOWyd0eXBlJ11dICYga2V5b2YgTjtcbiAgICAgIC8vIHdlIGtub3cgaWYgaXQgaGFzIGNoaWxkIGtleXMgd2UgY2FuIHdpZGVuIHRvIGEgUGFyZW50Tm9kZVxuICAgICAgdmlzaXRLZXkodmlzaXRvciwgaGFuZGxlciwgcGF0aCwga2V5KTtcbiAgICB9XG5cbiAgICBpZiAoZXhpdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXN1bHQgPSBleGl0KG5vZGUsIHBhdGgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGdldDxOIGV4dGVuZHMgQVNUdjEuTm9kZT4oXG4gIG5vZGU6IE4sXG4gIGtleTogVmlzaXRvcktleXNbTlsndHlwZSddXSAmIGtleW9mIE5cbik6IEFTVHYxLk5vZGUgfCBBU1R2MS5Ob2RlW10ge1xuICByZXR1cm4gKG5vZGVba2V5XSBhcyB1bmtub3duKSBhcyBBU1R2MS5Ob2RlIHwgQVNUdjEuTm9kZVtdO1xufVxuXG5mdW5jdGlvbiBzZXQ8TiBleHRlbmRzIEFTVHYxLk5vZGUsIEsgZXh0ZW5kcyBrZXlvZiBOPihub2RlOiBOLCBrZXk6IEssIHZhbHVlOiBOW0tdKTogdm9pZCB7XG4gIG5vZGVba2V5XSA9IHZhbHVlO1xufVxuXG5mdW5jdGlvbiB2aXNpdEtleTxOIGV4dGVuZHMgQVNUdjEuTm9kZT4oXG4gIHZpc2l0b3I6IE5vZGVWaXNpdG9yLFxuICBoYW5kbGVyOiBOb2RlVHJhdmVyc2FsPE4+LFxuICBwYXRoOiBXYWxrZXJQYXRoPE4+LFxuICBrZXk6IFZpc2l0b3JLZXlzW05bJ3R5cGUnXV0gJiBrZXlvZiBOXG4pIHtcbiAgbGV0IHsgbm9kZSB9ID0gcGF0aDtcblxuICBsZXQgdmFsdWUgPSBnZXQobm9kZSwga2V5KTtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxldCBrZXlFbnRlcjtcbiAgbGV0IGtleUV4aXQ7XG5cbiAgaWYgKGhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgIGxldCBrZXlIYW5kbGVyID0gZ2V0S2V5SGFuZGxlcihoYW5kbGVyLCBrZXkpO1xuICAgIGlmIChrZXlIYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGtleUVudGVyID0gZ2V0RW50ZXJGdW5jdGlvbihrZXlIYW5kbGVyKTtcbiAgICAgIGtleUV4aXQgPSBnZXRFeGl0RnVuY3Rpb24oa2V5SGFuZGxlcik7XG4gICAgfVxuICB9XG5cbiAgaWYgKGtleUVudGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoa2V5RW50ZXIobm9kZSwga2V5KSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBjYW5ub3RSZXBsYWNlT3JSZW1vdmVJbktleUhhbmRsZXJZZXQobm9kZSwga2V5KTtcbiAgICB9XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICB2aXNpdEFycmF5KHZpc2l0b3IsIHZhbHVlLCBwYXRoLCBrZXkpO1xuICB9IGVsc2Uge1xuICAgIGxldCBrZXlQYXRoID0gbmV3IFdhbGtlclBhdGgodmFsdWUsIHBhdGgsIGtleSk7XG4gICAgbGV0IHJlc3VsdCA9IHZpc2l0Tm9kZSh2aXNpdG9yLCBrZXlQYXRoKTtcbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIFRPRE86IGR5bmFtaWNhbGx5IGNoZWNrIHRoZSByZXN1bHRzIGJ5IGhhdmluZyBhIHRhYmxlIG9mXG4gICAgICAvLyBleHBlY3RlZCBub2RlIHR5cGVzIGluIHZhbHVlIHNwYWNlLCBub3QganVzdCB0eXBlIHNwYWNlXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgYXNzaWduS2V5KG5vZGUsIGtleSwgdmFsdWUsIHJlc3VsdCBhcyBhbnkpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChrZXlFeGl0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoa2V5RXhpdChub2RlLCBrZXkpICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IGNhbm5vdFJlcGxhY2VPclJlbW92ZUluS2V5SGFuZGxlcllldChub2RlLCBrZXkpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB2aXNpdEFycmF5KFxuICB2aXNpdG9yOiBOb2RlVmlzaXRvcixcbiAgYXJyYXk6IEFTVHYxLk5vZGVbXSxcbiAgcGFyZW50OiBXYWxrZXJQYXRoPEFTVHYxLk5vZGU+IHwgbnVsbCxcbiAgcGFyZW50S2V5OiBzdHJpbmcgfCBudWxsXG4pIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgIGxldCBub2RlID0gYXJyYXlbaV07XG4gICAgbGV0IHBhdGggPSBuZXcgV2Fsa2VyUGF0aChub2RlLCBwYXJlbnQsIHBhcmVudEtleSk7XG4gICAgbGV0IHJlc3VsdCA9IHZpc2l0Tm9kZSh2aXNpdG9yLCBwYXRoKTtcbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGkgKz0gc3BsaWNlQXJyYXkoYXJyYXksIGksIHJlc3VsdCkgLSAxO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhc3NpZ25LZXk8TiBleHRlbmRzIEFTVHYxLk5vZGUsIEsgZXh0ZW5kcyBWaXNpdG9yS2V5PE4+PihcbiAgbm9kZTogTixcbiAga2V5OiBLLFxuICB2YWx1ZTogQVNUdjEuTm9kZSxcbiAgcmVzdWx0OiBOW0tdIHwgW05bS11dIHwgbnVsbFxuKSB7XG4gIGlmIChyZXN1bHQgPT09IG51bGwpIHtcbiAgICB0aHJvdyBjYW5ub3RSZW1vdmVOb2RlKHZhbHVlLCBub2RlLCBrZXkpO1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkocmVzdWx0KSkge1xuICAgIGlmIChyZXN1bHQubGVuZ3RoID09PSAxKSB7XG4gICAgICBzZXQobm9kZSwga2V5LCByZXN1bHRbMF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocmVzdWx0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBjYW5ub3RSZW1vdmVOb2RlKHZhbHVlLCBub2RlLCBrZXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgY2Fubm90UmVwbGFjZU5vZGUodmFsdWUsIG5vZGUsIGtleSk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHNldChub2RlLCBrZXksIHJlc3VsdCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc3BsaWNlQXJyYXkoYXJyYXk6IEFTVHYxLk5vZGVbXSwgaW5kZXg6IG51bWJlciwgcmVzdWx0OiBBU1R2MS5Ob2RlIHwgQVNUdjEuTm9kZVtdIHwgbnVsbCkge1xuICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgYXJyYXkuc3BsaWNlKGluZGV4LCAxKTtcbiAgICByZXR1cm4gMDtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICBhcnJheS5zcGxpY2UoaW5kZXgsIDEsIC4uLnJlc3VsdCk7XG4gICAgcmV0dXJuIHJlc3VsdC5sZW5ndGg7XG4gIH0gZWxzZSB7XG4gICAgYXJyYXkuc3BsaWNlKGluZGV4LCAxLCByZXN1bHQpO1xuICAgIHJldHVybiAxO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRyYXZlcnNlKG5vZGU6IEFTVHYxLk5vZGUsIHZpc2l0b3I6IE5vZGVWaXNpdG9yKTogdm9pZCB7XG4gIGxldCBwYXRoID0gbmV3IFdhbGtlclBhdGgobm9kZSk7XG4gIHZpc2l0Tm9kZSh2aXNpdG9yLCBwYXRoKTtcbn1cbiJdLCJzb3VyY2VSb290IjoiIn0=