triggers.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { Trigger } from './trigger.class';
  6. /**
  7. * @record
  8. */
  9. export function ListenOptions() { }
  10. if (false) {
  11. /** @type {?|undefined} */
  12. ListenOptions.prototype.target;
  13. /** @type {?|undefined} */
  14. ListenOptions.prototype.targets;
  15. /** @type {?|undefined} */
  16. ListenOptions.prototype.triggers;
  17. /** @type {?|undefined} */
  18. ListenOptions.prototype.outsideClick;
  19. /** @type {?|undefined} */
  20. ListenOptions.prototype.outsideEsc;
  21. /** @type {?|undefined} */
  22. ListenOptions.prototype.show;
  23. /** @type {?|undefined} */
  24. ListenOptions.prototype.hide;
  25. /** @type {?|undefined} */
  26. ListenOptions.prototype.toggle;
  27. }
  28. /** @type {?} */
  29. const DEFAULT_ALIASES = {
  30. hover: ['mouseover', 'mouseout'],
  31. focus: ['focusin', 'focusout']
  32. };
  33. /* tslint:disable-next-line: no-any */
  34. /**
  35. * @param {?} triggers
  36. * @param {?=} aliases
  37. * @return {?}
  38. */
  39. export function parseTriggers(triggers, aliases = DEFAULT_ALIASES) {
  40. /** @type {?} */
  41. const trimmedTriggers = (triggers || '').trim();
  42. if (trimmedTriggers.length === 0) {
  43. return [];
  44. }
  45. /** @type {?} */
  46. const parsedTriggers = trimmedTriggers
  47. .split(/\s+/)
  48. .map((/**
  49. * @param {?} trigger
  50. * @return {?}
  51. */
  52. (trigger) => trigger.split(':')))
  53. .map((/**
  54. * @param {?} triggerPair
  55. * @return {?}
  56. */
  57. (triggerPair) => {
  58. /** @type {?} */
  59. const alias = aliases[triggerPair[0]] || triggerPair;
  60. return new Trigger(alias[0], alias[1]);
  61. }));
  62. /** @type {?} */
  63. const manualTriggers = parsedTriggers.filter((/**
  64. * @param {?} triggerPair
  65. * @return {?}
  66. */
  67. (triggerPair) => triggerPair.isManual()));
  68. if (manualTriggers.length > 1) {
  69. throw new Error('Triggers parse error: only one manual trigger is allowed');
  70. }
  71. if (manualTriggers.length === 1 && parsedTriggers.length > 1) {
  72. throw new Error('Triggers parse error: manual trigger can\'t be mixed with other triggers');
  73. }
  74. return parsedTriggers;
  75. }
  76. /**
  77. * @param {?} renderer
  78. * @param {?} target
  79. * @param {?} triggers
  80. * @param {?} showFn
  81. * @param {?} hideFn
  82. * @param {?} toggleFn
  83. * @return {?}
  84. */
  85. export function listenToTriggers(renderer,
  86. /* tslint:disable-next-line: no-any */
  87. target, triggers, showFn, hideFn, toggleFn) {
  88. /** @type {?} */
  89. const parsedTriggers = parseTriggers(triggers);
  90. /* tslint:disable-next-line: no-any */
  91. /** @type {?} */
  92. const listeners = [];
  93. if (parsedTriggers.length === 1 && parsedTriggers[0].isManual()) {
  94. return Function.prototype;
  95. }
  96. parsedTriggers.forEach((/**
  97. * @param {?} trigger
  98. * @return {?}
  99. */
  100. (trigger) => {
  101. if (trigger.open === trigger.close) {
  102. listeners.push(renderer.listen(target, trigger.open, toggleFn));
  103. return;
  104. }
  105. listeners.push(renderer.listen(target, trigger.open, showFn), renderer.listen(target, trigger.close, hideFn));
  106. }));
  107. return (/**
  108. * @return {?}
  109. */
  110. () => {
  111. listeners.forEach((/**
  112. * @param {?} unsubscribeFn
  113. * @return {?}
  114. */
  115. (unsubscribeFn) => unsubscribeFn()));
  116. });
  117. }
  118. /**
  119. * @param {?} renderer
  120. * @param {?} options
  121. * @return {?}
  122. */
  123. export function listenToTriggersV2(renderer, options) {
  124. /** @type {?} */
  125. const parsedTriggers = parseTriggers(options.triggers);
  126. /** @type {?} */
  127. const target = options.target;
  128. // do nothing
  129. if (parsedTriggers.length === 1 && parsedTriggers[0].isManual()) {
  130. return Function.prototype;
  131. }
  132. // all listeners
  133. /* tslint:disable-next-line: no-any */
  134. /** @type {?} */
  135. const listeners = [];
  136. // lazy listeners registration
  137. /** @type {?} */
  138. const _registerHide = [];
  139. /** @type {?} */
  140. const registerHide = (/**
  141. * @return {?}
  142. */
  143. () => {
  144. // add hide listeners to unregister array
  145. _registerHide.forEach((/**
  146. * @param {?} fn
  147. * @return {?}
  148. */
  149. (fn) => listeners.push(fn())));
  150. // register hide events only once
  151. _registerHide.length = 0;
  152. });
  153. // register open\close\toggle listeners
  154. parsedTriggers.forEach((/**
  155. * @param {?} trigger
  156. * @return {?}
  157. */
  158. (trigger) => {
  159. /** @type {?} */
  160. const useToggle = trigger.open === trigger.close;
  161. /** @type {?} */
  162. const showFn = useToggle ? options.toggle : options.show;
  163. if (!useToggle) {
  164. _registerHide.push((/**
  165. * @return {?}
  166. */
  167. () => renderer.listen(target, trigger.close, options.hide)));
  168. }
  169. listeners.push(renderer.listen(target, trigger.open, (/**
  170. * @return {?}
  171. */
  172. () => showFn(registerHide))));
  173. }));
  174. return (/**
  175. * @return {?}
  176. */
  177. () => {
  178. listeners.forEach((/**
  179. * @param {?} unsubscribeFn
  180. * @return {?}
  181. */
  182. (unsubscribeFn) => unsubscribeFn()));
  183. });
  184. }
  185. /**
  186. * @param {?} renderer
  187. * @param {?} options
  188. * @return {?}
  189. */
  190. export function registerOutsideClick(renderer, options) {
  191. if (!options.outsideClick) {
  192. return Function.prototype;
  193. }
  194. /* tslint:disable-next-line: no-any */
  195. return renderer.listen('document', 'click', (/**
  196. * @param {?} event
  197. * @return {?}
  198. */
  199. (event) => {
  200. if (options.target && options.target.contains(event.target)) {
  201. return undefined;
  202. }
  203. if (options.targets &&
  204. options.targets.some((/**
  205. * @param {?} target
  206. * @return {?}
  207. */
  208. target => target.contains(event.target)))) {
  209. return undefined;
  210. }
  211. options.hide();
  212. }));
  213. }
  214. /**
  215. * @param {?} renderer
  216. * @param {?} options
  217. * @return {?}
  218. */
  219. export function registerEscClick(renderer, options) {
  220. if (!options.outsideEsc) {
  221. return Function.prototype;
  222. }
  223. return renderer.listen('document', 'keyup.esc', (/**
  224. * @param {?} event
  225. * @return {?}
  226. */
  227. (event) => {
  228. if (options.target && options.target.contains(event.target)) {
  229. return undefined;
  230. }
  231. if (options.targets &&
  232. options.targets.some((/**
  233. * @param {?} target
  234. * @return {?}
  235. */
  236. target => target.contains(event.target)))) {
  237. return undefined;
  238. }
  239. options.hide();
  240. }));
  241. }
  242. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJpZ2dlcnMuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtYm9vdHN0cmFwL3V0aWxzLyIsInNvdXJjZXMiOlsidHJpZ2dlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUtBLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7OztBQUsxQyxtQ0FTQzs7O0lBUkMsK0JBQXFCOztJQUNyQixnQ0FBd0I7O0lBQ3hCLGlDQUFrQjs7SUFDbEIscUNBQXVCOztJQUN2QixtQ0FBcUI7O0lBQ3JCLDZCQUF1Qjs7SUFDdkIsNkJBQXVCOztJQUN2QiwrQkFBeUI7OztNQUdyQixlQUFlLEdBQUc7SUFDdEIsS0FBSyxFQUFFLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBQztJQUNoQyxLQUFLLEVBQUUsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDO0NBQy9COzs7Ozs7O0FBR0QsTUFBTSxVQUFVLGFBQWEsQ0FBQyxRQUFnQixFQUFFLFVBQWUsZUFBZTs7VUFDdEUsZUFBZSxHQUFHLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRTtJQUUvQyxJQUFJLGVBQWUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1FBQ2hDLE9BQU8sRUFBRSxDQUFDO0tBQ1g7O1VBRUssY0FBYyxHQUFHLGVBQWU7U0FDbkMsS0FBSyxDQUFDLEtBQUssQ0FBQztTQUNaLEdBQUc7Ozs7SUFBQyxDQUFDLE9BQWUsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBQztTQUM1QyxHQUFHOzs7O0lBQUMsQ0FBQyxXQUFxQixFQUFFLEVBQUU7O2NBQ3ZCLEtBQUssR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksV0FBVztRQUVwRCxPQUFPLElBQUksT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDLEVB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LENBQUMsTUFBTSxDQUFDLEVBQUMsRUFDN0Q7WUFDQSxPQUFPLFNBQVMsQ0FBQztTQUNsQjtRQUVELE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNqQixDQUFDLEVBQUMsQ0FBQztBQUNMLENBQUM7Ozs7OztBQUVELE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxRQUFtQixFQUNuQixPQUFzQjtJQUNyRCxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRTtRQUN2QixPQUFPLFFBQVEsQ0FBQyxTQUFTLENBQUM7S0FDM0I7SUFFRCxPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLFdBQVc7Ozs7SUFBRSxDQUFDLEtBQVUsRUFBRSxFQUFFO1FBQzdELElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDM0QsT0FBTyxTQUFTLENBQUM7U0FDbEI7UUFDRCxJQUNFLE9BQU8sQ0FBQyxPQUFPO1lBQ2YsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJOzs7O1lBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBQyxFQUM3RDtZQUNBLE9BQU8sU0FBUyxDQUFDO1NBQ2xCO1FBRUQsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2pCLENBQUMsRUFBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNvcHlyaWdodCBWYWxvciBTb2Z0d2FyZVxuICogQGNvcHlyaWdodCBBbmd1bGFyIG5nLWJvb3RzdHJhcCB0ZWFtXG4gKi9cbmltcG9ydCB7IFJlbmRlcmVyMiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVHJpZ2dlciB9IGZyb20gJy4vdHJpZ2dlci5jbGFzcyc7XG5cbi8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYW55ICovXG5leHBvcnQgdHlwZSBCc0V2ZW50Q2FsbGJhY2sgPSAoZXZlbnQ/OiBhbnkpID0+IGJvb2xlYW4gfCB2b2lkO1xuXG5leHBvcnQgaW50ZXJmYWNlIExpc3Rlbk9wdGlvbnMge1xuICB0YXJnZXQ/OiBIVE1MRWxlbWVudDtcbiAgdGFyZ2V0cz86IEhUTUxFbGVtZW50W107XG4gIHRyaWdnZXJzPzogc3RyaW5nO1xuICBvdXRzaWRlQ2xpY2s/OiBib29sZWFuO1xuICBvdXRzaWRlRXNjPzogYm9vbGVhbjtcbiAgc2hvdz86IEJzRXZlbnRDYWxsYmFjaztcbiAgaGlkZT86IEJzRXZlbnRDYWxsYmFjaztcbiAgdG9nZ2xlPzogQnNFdmVudENhbGxiYWNrO1xufVxuXG5jb25zdCBERUZBVUxUX0FMSUFTRVMgPSB7XG4gIGhvdmVyOiBbJ21vdXNlb3ZlcicsICdtb3VzZW91dCddLFxuICBmb2N1czogWydmb2N1c2luJywgJ2ZvY3Vzb3V0J11cbn07XG5cbi8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYW55ICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUcmlnZ2Vycyh0cmlnZ2Vyczogc3RyaW5nLCBhbGlhc2VzOiBhbnkgPSBERUZBVUxUX0FMSUFTRVMpOiBUcmlnZ2VyW10ge1xuICBjb25zdCB0cmltbWVkVHJpZ2dlcnMgPSAodHJpZ2dlcnMgfHwgJycpLnRyaW0oKTtcblxuICBpZiAodHJpbW1lZFRyaWdnZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHBhcnNlZFRyaWdnZXJzID0gdHJpbW1lZFRyaWdnZXJzXG4gICAgLnNwbGl0KC9cXHMrLylcbiAgICAubWFwKCh0cmlnZ2VyOiBzdHJpbmcpID0+IHRyaWdnZXIuc3BsaXQoJzonKSlcbiAgICAubWFwKCh0cmlnZ2VyUGFpcjogc3RyaW5nW10pID0+IHtcbiAgICAgIGNvbnN0IGFsaWFzID0gYWxpYXNlc1t0cmlnZ2VyUGFpclswXV0gfHwgdHJpZ2dlclBhaXI7XG5cbiAgICAgIHJldHVybiBuZXcgVHJpZ2dlcihhbGlhc1swXSwgYWxpYXNbMV0pO1xuICAgIH0pO1xuXG4gIGNvbnN0IG1hbnVhbFRyaWdnZXJzID0gcGFyc2VkVHJpZ2dlcnMuZmlsdGVyKCh0cmlnZ2VyUGFpcjogVHJpZ2dlcikgPT5cbiAgICB0cmlnZ2VyUGFpci5pc01hbnVhbCgpXG4gICk7XG5cbiAgaWYgKG1hbnVhbFRyaWdnZXJzLmxlbmd0aCA+IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyaWdnZXJzIHBhcnNlIGVycm9yOiBvbmx5IG9uZSBtYW51YWwgdHJpZ2dlciBpcyBhbGxvd2VkJyk7XG4gIH1cblxuICBpZiAobWFudWFsVHJpZ2dlcnMubGVuZ3RoID09PSAxICYmIHBhcnNlZFRyaWdnZXJzLmxlbmd0aCA+IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyaWdnZXJzIHBhcnNlIGVycm9yOiBtYW51YWwgdHJpZ2dlciBjYW5cXCd0IGJlIG1peGVkIHdpdGggb3RoZXIgdHJpZ2dlcnMnKTtcbiAgfVxuXG4gIHJldHVybiBwYXJzZWRUcmlnZ2Vycztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxpc3RlblRvVHJpZ2dlcnMocmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tYW55ICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQ6IGFueSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJzOiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93Rm46IEJzRXZlbnRDYWxsYmFjayxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGVGbjogQnNFdmVudENhbGxiYWNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9nZ2xlRm46IEJzRXZlbnRDYWxsYmFjayk6IEZ1bmN0aW9uIHtcbiAgY29uc3QgcGFyc2VkVHJpZ2dlcnMgPSBwYXJzZVRyaWdnZXJzKHRyaWdnZXJzKTtcbiAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1hbnkgKi9cbiAgY29uc3QgbGlzdGVuZXJzOiBhbnlbXSA9IFtdO1xuXG4gIGlmIChwYXJzZWRUcmlnZ2Vycy5sZW5ndGggPT09IDEgJiYgcGFyc2VkVHJpZ2dlcnNbMF0uaXNNYW51YWwoKSkge1xuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGU7XG4gIH1cblxuICBwYXJzZWRUcmlnZ2Vycy5mb3JFYWNoKCh0cmlnZ2VyOiBUcmlnZ2VyKSA9PiB7XG4gICAgaWYgKHRyaWdnZXIub3BlbiA9PT0gdHJpZ2dlci5jbG9zZSkge1xuICAgICAgbGlzdGVuZXJzLnB1c2gocmVuZGVyZXIubGlzdGVuKHRhcmdldCwgdHJpZ2dlci5vcGVuLCB0b2dnbGVGbikpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGlzdGVuZXJzLnB1c2goXG4gICAgICByZW5kZXJlci5saXN0ZW4odGFyZ2V0LCB0cmlnZ2VyLm9wZW4sIHNob3dGbiksXG4gICAgICByZW5kZXJlci5saXN0ZW4odGFyZ2V0LCB0cmlnZ2VyLmNsb3NlLCBoaWRlRm4pXG4gICAgKTtcbiAgfSk7XG5cbiAgcmV0dXJuICgpID0+IHtcbiAgICBsaXN0ZW5lcnMuZm9yRWFjaCgodW5zdWJzY3JpYmVGbjogRnVuY3Rpb24pID0+IHVuc3Vic2NyaWJlRm4oKSk7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0ZW5Ub1RyaWdnZXJzVjIocmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uczogTGlzdGVuT3B0aW9ucyk6IEZ1bmN0aW9uIHtcbiAgY29uc3QgcGFyc2VkVHJpZ2dlcnMgPSBwYXJzZVRyaWdnZXJzKG9wdGlvbnMudHJpZ2dlcnMpO1xuICBjb25zdCB0YXJnZXQgPSBvcHRpb25zLnRhcmdldDtcbiAgLy8gZG8gbm90aGluZ1xuICBpZiAocGFyc2VkVHJpZ2dlcnMubGVuZ3RoID09PSAxICYmIHBhcnNlZFRyaWdnZXJzWzBdLmlzTWFudWFsKCkpIHtcbiAgICByZXR1cm4gRnVuY3Rpb24ucHJvdG90eXBlO1xuICB9XG5cbiAgLy8gYWxsIGxpc3RlbmVyc1xuICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLWFueSAqL1xuICBjb25zdCBsaXN0ZW5lcnM6IGFueVtdID0gW107XG5cbiAgLy8gbGF6eSBsaXN0ZW5lcnMgcmVnaXN0cmF0aW9uXG4gIGNvbnN0IF9yZWdpc3RlckhpZGU6IEZ1bmN0aW9uW10gPSBbXTtcbiAgY29uc3QgcmVnaXN0ZXJIaWRlID0gKCkgPT4ge1xuICAgIC8vIGFkZCBoaWRlIGxpc3RlbmVycyB0byB1bnJlZ2lzdGVyIGFycmF5XG4gICAgX3JlZ2lzdGVySGlkZS5mb3JFYWNoKChmbjogRnVuY3Rpb24pID0+IGxpc3RlbmVycy5wdXNoKGZuKCkpKTtcbiAgICAvLyByZWdpc3RlciBoaWRlIGV2ZW50cyBvbmx5IG9uY2VcbiAgICBfcmVnaXN0ZXJIaWRlLmxlbmd0aCA9IDA7XG4gIH07XG5cbiAgLy8gcmVnaXN0ZXIgb3BlblxcY2xvc2VcXHRvZ2dsZSBsaXN0ZW5lcnNcbiAgcGFyc2VkVHJpZ2dlcnMuZm9yRWFjaCgodHJpZ2dlcjogVHJpZ2dlcikgPT4ge1xuICAgIGNvbnN0IHVzZVRvZ2dsZSA9IHRyaWdnZXIub3BlbiA9PT0gdHJpZ2dlci5jbG9zZTtcbiAgICBjb25zdCBzaG93Rm4gPSB1c2VUb2dnbGUgPyBvcHRpb25zLnRvZ2dsZSA6IG9wdGlvbnMuc2hvdztcblxuICAgIGlmICghdXNlVG9nZ2xlKSB7XG4gICAgICBfcmVnaXN0ZXJIaWRlLnB1c2goKCkgPT5cbiAgICAgICAgcmVuZGVyZXIubGlzdGVuKHRhcmdldCwgdHJpZ2dlci5jbG9zZSwgb3B0aW9ucy5oaWRlKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBsaXN0ZW5lcnMucHVzaChcbiAgICAgIHJlbmRlcmVyLmxpc3Rlbih0YXJnZXQsIHRyaWdnZXIub3BlbiwgKCkgPT4gc2hvd0ZuKHJlZ2lzdGVySGlkZSkpXG4gICAgKTtcbiAgfSk7XG5cbiAgcmV0dXJuICgpID0+IHtcbiAgICBsaXN0ZW5lcnMuZm9yRWFjaCgodW5zdWJzY3JpYmVGbjogRnVuY3Rpb24pID0+IHVuc3Vic2NyaWJlRm4oKSk7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3Rlck91dHNpZGVDbGljayhyZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IExpc3Rlbk9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zLm91dHNpZGVDbGljaykge1xuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGU7XG4gIH1cblxuICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLWFueSAqL1xuICByZXR1cm4gcmVuZGVyZXIubGlzdGVuKCdkb2N1bWVudCcsICdjbGljaycsIChldmVudDogYW55KSA9PiB7XG4gICAgaWYgKG9wdGlvbnMudGFyZ2V0ICYmIG9wdGlvbnMudGFyZ2V0LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIG9wdGlvbnMudGFyZ2V0cyAmJlxuICAgICAgb3B0aW9ucy50YXJnZXRzLnNvbWUodGFyZ2V0ID0+IHRhcmdldC5jb250YWlucyhldmVudC50YXJnZXQpKVxuICAgICkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBvcHRpb25zLmhpZGUoKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckVzY0NsaWNrKHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zOiBMaXN0ZW5PcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucy5vdXRzaWRlRXNjKSB7XG4gICAgcmV0dXJuIEZ1bmN0aW9uLnByb3RvdHlwZTtcbiAgfVxuXG4gIHJldHVybiByZW5kZXJlci5saXN0ZW4oJ2RvY3VtZW50JywgJ2tleXVwLmVzYycsIChldmVudDogYW55KSA9PiB7XG4gICAgaWYgKG9wdGlvbnMudGFyZ2V0ICYmIG9wdGlvbnMudGFyZ2V0LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIG9wdGlvbnMudGFyZ2V0cyAmJlxuICAgICAgb3B0aW9ucy50YXJnZXRzLnNvbWUodGFyZ2V0ID0+IHRhcmdldC5jb250YWlucyhldmVudC50YXJnZXQpKVxuICAgICkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBvcHRpb25zLmhpZGUoKTtcbiAgfSk7XG59XG4iXX0=