UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

412 lines (325 loc) 38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.OnModifierState = void 0; var _destroyable = require("@glimmer/destroyable"); var _env = require("@glimmer/env"); var _manager = require("@glimmer/manager"); var _reference = require("@glimmer/reference"); var _runtime = require("@glimmer/runtime"); var _validator = require("@glimmer/validator"); var _util = require("@glimmer/util"); function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var untouchableContext = (0, _util.buildUntouchableThis)('`on` modifier'); /* Internet Explorer 11 does not support `once` and also does not support passing `eventOptions`. In some situations it then throws a weird script error, like: ``` Could not complete the operation due to error 80020101 ``` This flag determines, whether `{ once: true }` and thus also event options in general are supported. */ var SUPPORTS_EVENT_OPTIONS = function () { try { var div = document.createElement('div'); var counter = 0; div.addEventListener('click', function () { return counter++; }, { once: true }); var event; if (typeof Event === 'function') { event = new Event('click'); } else { event = document.createEvent('Event'); event.initEvent('click', true, true); } div.dispatchEvent(event); div.dispatchEvent(event); return counter === 1; } catch (error) { return false; } }(); var OnModifierState = /*#__PURE__*/function () { function OnModifierState(element, args) { this.tag = (0, _validator.createUpdatableTag)(); this.shouldUpdate = true; this.element = element; this.args = args; } var _proto = OnModifierState.prototype; _proto.updateFromArgs = function updateFromArgs() { var args = this.args; var _reifyNamed = (0, _runtime.reifyNamed)(args.named), once = _reifyNamed.once, passive = _reifyNamed.passive, capture = _reifyNamed.capture; if (once !== this.once) { this.once = once; this.shouldUpdate = true; } if (passive !== this.passive) { this.passive = passive; this.shouldUpdate = true; } if (capture !== this.capture) { this.capture = capture; this.shouldUpdate = true; } var options; // we want to handle both `true` and `false` because both have a meaning: // https://bugs.chromium.org/p/chromium/issues/detail?id=770208 if (once !== undefined || passive !== undefined || capture !== undefined) { options = this.options = { once: once, passive: passive, capture: capture }; } else { this.options = undefined; } if (_env.DEBUG && (args.positional[0] === undefined || typeof (0, _reference.valueForRef)(args.positional[0]) !== 'string')) { throw new Error('You must pass a valid DOM event name as the first argument to the `on` modifier'); } var eventName = (0, _reference.valueForRef)(args.positional[0]); if (eventName !== this.eventName) { this.eventName = eventName; this.shouldUpdate = true; } var userProvidedCallbackReference = args.positional[1]; if (_env.DEBUG) { if (args.positional[1] === undefined) { throw new Error("You must pass a function as the second argument to the `on` modifier."); } var value = (0, _reference.valueForRef)(userProvidedCallbackReference); if (typeof value !== 'function') { throw new Error("You must pass a function as the second argument to the `on` modifier; you passed " + (value === null ? 'null' : typeof value) + ". While rendering:\n\n" + userProvidedCallbackReference.debugLabel); } } var userProvidedCallback = (0, _reference.valueForRef)(userProvidedCallbackReference); if (userProvidedCallback !== this.userProvidedCallback) { this.userProvidedCallback = userProvidedCallback; this.shouldUpdate = true; } if (_env.DEBUG && args.positional.length !== 2) { throw new Error("You can only pass two positional arguments (event name and callback) to the `on` modifier, but you provided " + args.positional.length + ". Consider using the `fn` helper to provide additional arguments to the `on` callback."); } var needsCustomCallback = SUPPORTS_EVENT_OPTIONS === false && once || /* needs manual once implementation */ _env.DEBUG && passive; /* needs passive enforcement */ if (this.shouldUpdate) { if (needsCustomCallback) { var callback = this.callback = function (event) { if (_env.DEBUG && passive) { event.preventDefault = function () { throw new Error("You marked this listener as 'passive', meaning that you must not call 'event.preventDefault()': \n\n" + userProvidedCallback); }; } if (!SUPPORTS_EVENT_OPTIONS && once) { removeEventListener(this, eventName, callback, options); } return userProvidedCallback.call(untouchableContext, event); }; } else if (_env.DEBUG) { // prevent the callback from being bound to the element this.callback = userProvidedCallback.bind(untouchableContext); } else { this.callback = userProvidedCallback; } } }; return OnModifierState; }(); exports.OnModifierState = OnModifierState; var adds = 0; var removes = 0; function removeEventListener(element, eventName, callback, options) { removes++; if (SUPPORTS_EVENT_OPTIONS) { // when options are supported, use them across the board element.removeEventListener(eventName, callback, options); } else if (options !== undefined && options.capture) { // used only in the following case: // // `{ once: true | false, passive: true | false, capture: true } // // `once` is handled via a custom callback that removes after first // invocation so we only care about capture here as a boolean element.removeEventListener(eventName, callback, true); } else { // used only in the following cases: // // * where there is no options // * `{ once: true | false, passive: true | false, capture: false } element.removeEventListener(eventName, callback); } } function addEventListener(element, eventName, callback, options) { adds++; if (SUPPORTS_EVENT_OPTIONS) { // when options are supported, use them across the board element.addEventListener(eventName, callback, options); } else if (options !== undefined && options.capture) { // used only in the following case: // // `{ once: true | false, passive: true | false, capture: true } // // `once` is handled via a custom callback that removes after first // invocation so we only care about capture here as a boolean element.addEventListener(eventName, callback, true); } else { // used only in the following cases: // // * where there is no options // * `{ once: true | false, passive: true | false, capture: false } element.addEventListener(eventName, callback); } } /** The `{{on}}` modifier lets you easily add event listeners (it uses [EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) internally). For example, if you'd like to run a function on your component when a `<button>` in the components template is clicked you might do something like: ```app/components/like-post.hbs <button {{on 'click' this.saveLike}}>Like this post!</button> ``` ```app/components/like-post.js import Component from '@glimmer/component'; import { action } from '@ember/object'; export default class LikePostComponent extends Component { saveLike = () => { // someone likes your post! // better send a request off to your server... } } ``` ### Arguments `{{on}}` accepts two positional arguments, and a few named arguments. The positional arguments are: - `event` -- the name to use when calling `addEventListener` - `callback` -- the function to be passed to `addEventListener` The named arguments are: - capture -- a `true` value indicates that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree. - once -- indicates that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked. - passive -- if `true`, indicates that the function specified by listener will never call preventDefault(). If a passive listener does call preventDefault(), the user agent will do nothing other than generate a console warning. See [Improving scrolling performance with passive listeners](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Improving_scrolling_performance_with_passive_listeners) to learn more. The callback function passed to `{{on}}` will receive any arguments that are passed to the event handler. Most commonly this would be the `event` itself. If you would like to pass additional arguments to the function you should use the `{{fn}}` helper. For example, in our example case above if you'd like to pass in the post that was being liked when the button is clicked you could do something like: ```app/components/like-post.hbs <button {{on 'click' (fn this.saveLike @post)}}>Like this post!</button> ``` In this case, the `saveLike` function will receive two arguments: the click event and the value of `@post`. ### Function Context In the example above, we used an arrow function to ensure that `likePost` is properly bound to the `items-list`, but let's explore what happens if we left out the arrow function: ```app/components/like-post.js import Component from '@glimmer/component'; export default class LikePostComponent extends Component { saveLike() { // ...snip... } } ``` In this example, when the button is clicked `saveLike` will be invoked, it will **not** have access to the component instance. In other words, it will have no `this` context, so please make sure your functions are bound (via an arrow function or other means) before passing into `on`! @method on @public */ var OnModifierManager = /*#__PURE__*/function () { function OnModifierManager() { this.SUPPORTS_EVENT_OPTIONS = SUPPORTS_EVENT_OPTIONS; } var _proto2 = OnModifierManager.prototype; _proto2.getDebugName = function getDebugName() { return 'on'; }; _proto2.create = function create(_owner, element, _state, args) { return new OnModifierState(element, args); }; _proto2.getTag = function getTag(state) { if (state === null) { return null; } return state.tag; }; _proto2.install = function install(state) { if (state === null) { return; } state.updateFromArgs(); var element = state.element, eventName = state.eventName, callback = state.callback, options = state.options; addEventListener(element, eventName, callback, options); (0, _destroyable.registerDestructor)(state, function () { return removeEventListener(element, eventName, callback, options); }); state.shouldUpdate = false; }; _proto2.update = function update(state) { if (state === null) { return; } // stash prior state for el.removeEventListener var element = state.element, eventName = state.eventName, callback = state.callback, options = state.options; state.updateFromArgs(); if (!state.shouldUpdate) { return; } // use prior state values for removal removeEventListener(element, eventName, callback, options); // read updated values from the state object addEventListener(state.element, state.eventName, state.callback, state.options); state.shouldUpdate = false; }; _proto2.getDestroyable = function getDestroyable(state) { return state; }; _createClass(OnModifierManager, [{ key: "counters", get: function get() { return { adds: adds, removes: removes }; } }]); return OnModifierManager; }(); var _default = (0, _manager.setInternalModifierManager)(new OnModifierManager(), {}); exports.default = _default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL21vZGlmaWVycy9vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLElBQU0sa0JBQWtCLEdBQUcsZ0NBQTNCLGVBQTJCLENBQTNCO0FBRUE7Ozs7Ozs7Ozs7Ozs7QUFZQSxJQUFNLHNCQUFzQixHQUFJLFlBQUs7QUFDbkMsTUFBSTtBQUNGLFFBQU0sR0FBRyxHQUFHLFFBQVEsQ0FBUixhQUFBLENBQVosS0FBWSxDQUFaO0FBQ0EsUUFBSSxPQUFPLEdBQVgsQ0FBQTtBQUNBLElBQUEsR0FBRyxDQUFILGdCQUFBLENBQUEsT0FBQSxFQUE4QixZQUFBO0FBQUEsYUFBTSxPQUFwQyxFQUE4QjtBQUE5QixLQUFBLEVBQStDO0FBQUUsTUFBQSxJQUFJLEVBQUU7QUFBUixLQUEvQztBQUVBLFFBQUEsS0FBQTs7QUFDQSxRQUFJLE9BQUEsS0FBQSxLQUFKLFVBQUEsRUFBaUM7QUFDL0IsTUFBQSxLQUFLLEdBQUcsSUFBQSxLQUFBLENBQVIsT0FBUSxDQUFSO0FBREYsS0FBQSxNQUVPO0FBQ0wsTUFBQSxLQUFLLEdBQUcsUUFBUSxDQUFSLFdBQUEsQ0FBUixPQUFRLENBQVI7QUFDQSxNQUFBLEtBQUssQ0FBTCxTQUFBLENBQUEsT0FBQSxFQUFBLElBQUEsRUFBQSxJQUFBO0FBQ0Q7O0FBRUQsSUFBQSxHQUFHLENBQUgsYUFBQSxDQUFBLEtBQUE7QUFDQSxJQUFBLEdBQUcsQ0FBSCxhQUFBLENBQUEsS0FBQTtBQUVBLFdBQU8sT0FBTyxLQUFkLENBQUE7QUFoQkYsR0FBQSxDQWlCRSxPQUFBLEtBQUEsRUFBYztBQUNkLFdBQUEsS0FBQTtBQUNEO0FBcEJILENBQWdDLEVBQWhDOztBQXVCQSxJQUFNLGVBQU4sR0FBQSxhQUFBLFlBQUE7QUFhRSxXQUFBLGVBQUEsQ0FBQSxPQUFBLEVBQUEsSUFBQSxFQUFxRDtBQVo5QyxTQUFBLEdBQUEsR0FBQSxvQ0FBQTtBQVVBLFNBQUEsWUFBQSxHQUFBLElBQUE7QUFHTCxTQUFBLE9BQUEsR0FBQSxPQUFBO0FBQ0EsU0FBQSxJQUFBLEdBQUEsSUFBQTtBQUNEOztBQWhCSCxNQUFBLE1BQUEsR0FBQSxlQUFBLENBQUEsU0FBQTs7QUFBQSxFQUFBLE1BQUEsQ0FBQSxjQUFBLEdBa0JFLFNBQUEsY0FBQSxHQUFjO0FBQUEsUUFDTixJQURNLEdBQUEsS0FBQSxJQUFBOztBQUFBLFFBQUEsV0FBQSxHQUc4Qyx5QkFBVyxJQUFJLENBSDdELEtBRzhDLENBSDlDO0FBQUEsUUFHUixJQUhRLEdBQUEsV0FBQSxDQUFBLElBQUE7QUFBQSxRQUdSLE9BSFEsR0FBQSxXQUFBLENBQUEsT0FBQTtBQUFBLFFBR1MsT0FIVCxHQUFBLFdBQUEsQ0FBQSxPQUFBOztBQUlaLFFBQUksSUFBSSxLQUFLLEtBQWIsSUFBQSxFQUF3QjtBQUN0QixXQUFBLElBQUEsR0FBQSxJQUFBO0FBQ0EsV0FBQSxZQUFBLEdBQUEsSUFBQTtBQUNEOztBQUVELFFBQUksT0FBTyxLQUFLLEtBQWhCLE9BQUEsRUFBOEI7QUFDNUIsV0FBQSxPQUFBLEdBQUEsT0FBQTtBQUNBLFdBQUEsWUFBQSxHQUFBLElBQUE7QUFDRDs7QUFFRCxRQUFJLE9BQU8sS0FBSyxLQUFoQixPQUFBLEVBQThCO0FBQzVCLFdBQUEsT0FBQSxHQUFBLE9BQUE7QUFDQSxXQUFBLFlBQUEsR0FBQSxJQUFBO0FBQ0Q7O0FBRUQsUUFuQlksT0FtQlosQ0FuQlksQ0FvQlo7QUFDQTs7QUFDQSxRQUFJLElBQUksS0FBSixTQUFBLElBQXNCLE9BQU8sS0FBN0IsU0FBQSxJQUErQyxPQUFPLEtBQTFELFNBQUEsRUFBMEU7QUFDeEUsTUFBQSxPQUFPLEdBQUcsS0FBQSxPQUFBLEdBQWU7QUFBRSxRQUFBLElBQUYsRUFBQSxJQUFBO0FBQVEsUUFBQSxPQUFSLEVBQUEsT0FBQTtBQUFpQixRQUFBLE9BQUEsRUFBQTtBQUFqQixPQUF6QjtBQURGLEtBQUEsTUFFTztBQUNMLFdBQUEsT0FBQSxHQUFBLFNBQUE7QUFDRDs7QUFFRCxRQUNFLGVBQ0MsSUFBSSxDQUFKLFVBQUEsQ0FBQSxDQUFBLE1BQUEsU0FBQSxJQUFvQyxPQUFPLDRCQUFZLElBQUksQ0FBSixVQUFBLENBQW5CLENBQW1CLENBQVosQ0FBUCxLQUZ2QyxRQUNFLENBREYsRUFHRTtBQUNBLFlBQU0sSUFBQSxLQUFBLENBQU4saUZBQU0sQ0FBTjtBQUdEOztBQUVELFFBQUksU0FBUyxHQUFHLDRCQUFZLElBQUksQ0FBSixVQUFBLENBQTVCLENBQTRCLENBQVosQ0FBaEI7O0FBQ0EsUUFBSSxTQUFTLEtBQUssS0FBbEIsU0FBQSxFQUFrQztBQUNoQyxXQUFBLFNBQUEsR0FBQSxTQUFBO0FBQ0EsV0FBQSxZQUFBLEdBQUEsSUFBQTtBQUNEOztBQUVELFFBQUksNkJBQTZCLEdBQUcsSUFBSSxDQUFKLFVBQUEsQ0FBcEMsQ0FBb0MsQ0FBcEM7O0FBRUEsUUFBQSxVQUFBLEVBQVc7QUFDVCxVQUFJLElBQUksQ0FBSixVQUFBLENBQUEsQ0FBQSxNQUFKLFNBQUEsRUFBc0M7QUFDcEMsY0FBTSxJQUFOLEtBQU0sQ0FBTix1RUFBTSxDQUFOO0FBQ0Q7O0FBRUQsVUFBSSxLQUFLLEdBQUcsNEJBQVosNkJBQVksQ0FBWjs7QUFFQSxVQUFJLE9BQUEsS0FBQSxLQUFKLFVBQUEsRUFBaUM7QUFDL0IsY0FBTSxJQUFBLEtBQUEsQ0FBQSx1RkFFRixLQUFLLEtBQUwsSUFBQSxHQUFBLE1BQUEsR0FBMEIsT0FGeEIsS0FBQSxJQUFBLHdCQUFBLEdBR3FCLDZCQUE2QixDQUh4RCxVQUFNLENBQU47QUFLRDtBQUNGOztBQUVELFFBQUksb0JBQW9CLEdBQUcsNEJBQTNCLDZCQUEyQixDQUEzQjs7QUFDQSxRQUFJLG9CQUFvQixLQUFLLEtBQTdCLG9CQUFBLEVBQXdEO0FBQ3RELFdBQUEsb0JBQUEsR0FBQSxvQkFBQTtBQUNBLFdBQUEsWUFBQSxHQUFBLElBQUE7QUFDRDs7QUFFRCxRQUFJLGNBQVMsSUFBSSxDQUFKLFVBQUEsQ0FBQSxNQUFBLEtBQWIsQ0FBQSxFQUEyQztBQUN6QyxZQUFNLElBQUEsS0FBQSxDQUFBLGlIQUM2RyxJQUFJLENBQUosVUFBQSxDQURuSCxNQUFNLEdBQU4sd0ZBQU0sQ0FBTjtBQUdEOztBQUVELFFBQUksbUJBQW1CLEdBQ3BCLHNCQUFzQixLQUF0QixLQUFBLElBQUQsSUFBQztBQUEwQztBQUMxQyxrQkFGSCxPQUFBO0FBRXNCOztBQUV0QixRQUFJLEtBQUosWUFBQSxFQUF1QjtBQUNyQixVQUFBLG1CQUFBLEVBQXlCO0FBQ3ZCLFlBQUksUUFBUSxHQUFJLEtBQUEsUUFBQSxHQUFnQixVQUFBLEtBQUEsRUFBOEI7QUFDNUQsY0FBSSxjQUFKLE9BQUEsRUFBc0I7QUFDcEIsWUFBQSxLQUFLLENBQUwsY0FBQSxHQUF1QixZQUFLO0FBQzFCLG9CQUFNLElBQUEsS0FBQSxDQUFBLHlHQUFOLG9CQUFNLENBQU47QUFERixhQUFBO0FBS0Q7O0FBRUQsY0FBSSxDQUFBLHNCQUFBLElBQUosSUFBQSxFQUFxQztBQUNuQyxZQUFBLG1CQUFtQixDQUFBLElBQUEsRUFBQSxTQUFBLEVBQUEsUUFBQSxFQUFuQixPQUFtQixDQUFuQjtBQUNEOztBQUNELGlCQUFPLG9CQUFvQixDQUFwQixJQUFBLENBQUEsa0JBQUEsRUFBUCxLQUFPLENBQVA7QUFaRixTQUFBO0FBREYsT0FBQSxNQWVPLElBQUEsVUFBQSxFQUFXO0FBQ2hCO0FBQ0EsYUFBQSxRQUFBLEdBQWdCLG9CQUFvQixDQUFwQixJQUFBLENBQWhCLGtCQUFnQixDQUFoQjtBQUZLLE9BQUEsTUFHQTtBQUNMLGFBQUEsUUFBQSxHQUFBLG9CQUFBO0FBQ0Q7QUFDRjtBQXJITCxHQUFBOztBQUFBLFNBQUEsZUFBQTtBQUFBLENBQUEsRUFBQTs7O0FBeUhBLElBQUksSUFBSSxHQUFSLENBQUE7QUFDQSxJQUFJLE9BQU8sR0FBWCxDQUFBOztBQUVBLFNBQUEsbUJBQUEsQ0FBQSxPQUFBLEVBQUEsU0FBQSxFQUFBLFFBQUEsRUFBQSxPQUFBLEVBSW1DO0FBRWpDLEVBQUEsT0FBTzs7QUFFUCxNQUFBLHNCQUFBLEVBQTRCO0FBQzFCO0FBQ0EsSUFBQSxPQUFPLENBQVAsbUJBQUEsQ0FBQSxTQUFBLEVBQUEsUUFBQSxFQUFBLE9BQUE7QUFGRixHQUFBLE1BR08sSUFBSSxPQUFPLEtBQVAsU0FBQSxJQUF5QixPQUFPLENBQXBDLE9BQUEsRUFBOEM7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBQSxPQUFPLENBQVAsbUJBQUEsQ0FBQSxTQUFBLEVBQUEsUUFBQSxFQUFBLElBQUE7QUFQSyxHQUFBLE1BUUE7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUEsT0FBTyxDQUFQLG1CQUFBLENBQUEsU0FBQSxFQUFBLFFBQUE7QUFDRDtBQUNGOztBQUVELFNBQUEsZ0JBQUEsQ0FBQSxPQUFBLEVBQUEsU0FBQSxFQUFBLFFBQUEsRUFBQSxPQUFBLEVBSW1DO0FBRWpDLEVBQUEsSUFBSTs7QUFFSixNQUFBLHNCQUFBLEVBQTRCO0FBQzFCO0FBQ0EsSUFBQSxPQUFPLENBQVAsZ0JBQUEsQ0FBQSxTQUFBLEVBQUEsUUFBQSxFQUFBLE9BQUE7QUFGRixHQUFBLE1BR08sSUFBSSxPQUFPLEtBQVAsU0FBQSxJQUF5QixPQUFPLENBQXBDLE9BQUEsRUFBOEM7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBQSxPQUFPLENBQVAsZ0JBQUEsQ0FBQSxTQUFBLEVBQUEsUUFBQSxFQUFBLElBQUE7QUFQSyxHQUFBLE1BUUE7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUEsT0FBTyxDQUFQLGdCQUFBLENBQUEsU0FBQSxFQUFBLFFBQUE7QUFDRDtBQUNGO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFzRkEsaUI7QUFBQSxXQUFBLGlCQUFBLEdBQUE7QUFDUyxTQUFBLHNCQUFBLEdBQUEsc0JBQUE7QUFxRVI7Ozs7VUFuRUMsWSxHQUFBLFNBQUEsWUFBQSxHQUFZO0FBQ1YsV0FBQSxJQUFBOzs7VUFPRixNLEdBQUEsU0FBQSxNQUFBLENBQUEsTUFBQSxFQUFBLE9BQUEsRUFBQSxNQUFBLEVBQUEsSUFBQSxFQUl5QjtBQUV2QixXQUFPLElBQUEsZUFBQSxDQUFBLE9BQUEsRUFBUCxJQUFPLENBQVA7OztVQUdGLE0sR0FBQSxTQUFBLE1BQUEsQ0FBQSxLQUFBLEVBQW9DO0FBQ2xDLFFBQUksS0FBSyxLQUFULElBQUEsRUFBb0I7QUFDbEIsYUFBQSxJQUFBO0FBQ0Q7O0FBRUQsV0FBTyxLQUFLLENBQVosR0FBQTs7O1VBR0YsTyxHQUFBLFNBQUEsT0FBQSxDQUFBLEtBQUEsRUFBcUM7QUFDbkMsUUFBSSxLQUFLLEtBQVQsSUFBQSxFQUFvQjtBQUNsQjtBQUNEOztBQUVELElBQUEsS0FBSyxDQUFMLGNBQUE7QUFMbUMsUUFPL0IsT0FQK0IsR0FPbkMsS0FQbUMsQ0FBQSxPQUFBO0FBQUEsUUFPL0IsU0FQK0IsR0FPbkMsS0FQbUMsQ0FBQSxTQUFBO0FBQUEsUUFPL0IsUUFQK0IsR0FPbkMsS0FQbUMsQ0FBQSxRQUFBO0FBQUEsUUFPQyxPQVBELEdBT25DLEtBUG1DLENBQUEsT0FBQTtBQVNuQyxJQUFBLGdCQUFnQixDQUFBLE9BQUEsRUFBQSxTQUFBLEVBQUEsUUFBQSxFQUFoQixPQUFnQixDQUFoQjtBQUVBLHlDQUFrQixLQUFsQixFQUEwQixZQUFBO0FBQUEsYUFBTSxtQkFBbUIsQ0FBQSxPQUFBLEVBQUEsU0FBQSxFQUFBLFFBQUEsRUFBbkQsT0FBbUQsQ0FBekI7QUFBMUIsS0FBQTtBQUVBLElBQUEsS0FBSyxDQUFMLFlBQUEsR0FBQSxLQUFBOzs7VUFHRixNLEdBQUEsU0FBQSxNQUFBLENBQUEsS0FBQSxFQUFvQztBQUNsQyxRQUFJLEtBQUssS0FBVCxJQUFBLEVBQW9CO0FBQ2xCO0FBRmdDLEtBQUEsQ0FLbEM7OztBQUxrQyxRQU05QixPQU44QixHQU1sQyxLQU5rQyxDQUFBLE9BQUE7QUFBQSxRQU05QixTQU44QixHQU1sQyxLQU5rQyxDQUFBLFNBQUE7QUFBQSxRQU05QixRQU44QixHQU1sQyxLQU5rQyxDQUFBLFFBQUE7QUFBQSxRQU1FLE9BTkYsR0FNbEMsS0FOa0MsQ0FBQSxPQUFBO0FBUWxDLElBQUEsS0FBSyxDQUFMLGNBQUE7O0FBRUEsUUFBSSxDQUFDLEtBQUssQ0FBVixZQUFBLEVBQXlCO0FBQ3ZCO0FBWGdDLEtBQUEsQ0FjbEM7OztBQUNBLElBQUEsbUJBQW1CLENBQUEsT0FBQSxFQUFBLFNBQUEsRUFBQSxRQUFBLEVBZmUsT0FlZixDQUFuQixDQWZrQyxDQWlCbEM7O0FBQ0EsSUFBQSxnQkFBZ0IsQ0FBQyxLQUFLLENBQU4sT0FBQSxFQUFnQixLQUFLLENBQXJCLFNBQUEsRUFBaUMsS0FBSyxDQUF0QyxRQUFBLEVBQWlELEtBQUssQ0FBdEUsT0FBZ0IsQ0FBaEI7QUFFQSxJQUFBLEtBQUssQ0FBTCxZQUFBLEdBQUEsS0FBQTs7O1VBR0YsYyxHQUFBLFNBQUEsY0FBQSxDQUFBLEtBQUEsRUFBNEM7QUFDMUMsV0FBQSxLQUFBOzs7Ozt3QkE3RFU7QUFDVixhQUFPO0FBQUUsUUFBQSxJQUFGLEVBQUEsSUFBQTtBQUFRLFFBQUEsT0FBQSxFQUFBO0FBQVIsT0FBUDtBQUNEOzs7Ozs7ZUErRFkseUNBQTJCLElBQUQsaUJBQUMsRUFBM0IsRUFBZixFQUFlLEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZWdpc3RlckRlc3RydWN0b3IgfSBmcm9tICdAZ2xpbW1lci9kZXN0cm95YWJsZSc7XG5pbXBvcnQgeyBERUJVRyB9IGZyb20gJ0BnbGltbWVyL2Vudic7XG5pbXBvcnQgeyBDYXB0dXJlZEFyZ3VtZW50cywgSW50ZXJuYWxNb2RpZmllck1hbmFnZXIsIE93bmVyIH0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbE1vZGlmaWVyTWFuYWdlciB9IGZyb20gJ0BnbGltbWVyL21hbmFnZXInO1xuaW1wb3J0IHsgdmFsdWVGb3JSZWYgfSBmcm9tICdAZ2xpbW1lci9yZWZlcmVuY2UnO1xuaW1wb3J0IHsgcmVpZnlOYW1lZCB9IGZyb20gJ0BnbGltbWVyL3J1bnRpbWUnO1xuaW1wb3J0IHsgY3JlYXRlVXBkYXRhYmxlVGFnLCBVcGRhdGFibGVUYWcgfSBmcm9tICdAZ2xpbW1lci92YWxpZGF0b3InO1xuaW1wb3J0IHsgU2ltcGxlRWxlbWVudCB9IGZyb20gJ0BzaW1wbGUtZG9tL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBidWlsZFVudG91Y2hhYmxlVGhpcyB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuXG5jb25zdCB1bnRvdWNoYWJsZUNvbnRleHQgPSBidWlsZFVudG91Y2hhYmxlVGhpcygnYG9uYCBtb2RpZmllcicpO1xuXG4vKlxuICBJbnRlcm5ldCBFeHBsb3JlciAxMSBkb2VzIG5vdCBzdXBwb3J0IGBvbmNlYCBhbmQgYWxzbyBkb2VzIG5vdCBzdXBwb3J0XG4gIHBhc3NpbmcgYGV2ZW50T3B0aW9uc2AuIEluIHNvbWUgc2l0dWF0aW9ucyBpdCB0aGVuIHRocm93cyBhIHdlaXJkIHNjcmlwdFxuICBlcnJvciwgbGlrZTpcblxuICBgYGBcbiAgQ291bGQgbm90IGNvbXBsZXRlIHRoZSBvcGVyYXRpb24gZHVlIHRvIGVycm9yIDgwMDIwMTAxXG4gIGBgYFxuXG4gIFRoaXMgZmxhZyBkZXRlcm1pbmVzLCB3aGV0aGVyIGB7IG9uY2U6IHRydWUgfWAgYW5kIHRodXMgYWxzbyBldmVudCBvcHRpb25zIGluXG4gIGdlbmVyYWwgYXJlIHN1cHBvcnRlZC5cbiovXG5jb25zdCBTVVBQT1JUU19FVkVOVF9PUFRJT05TID0gKCgpID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBsZXQgY291bnRlciA9IDA7XG4gICAgZGl2LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4gY291bnRlcisrLCB7IG9uY2U6IHRydWUgfSk7XG5cbiAgICBsZXQgZXZlbnQ7XG4gICAgaWYgKHR5cGVvZiBFdmVudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXZlbnQgPSBuZXcgRXZlbnQoJ2NsaWNrJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0V2ZW50Jyk7XG4gICAgICBldmVudC5pbml0RXZlbnQoJ2NsaWNrJywgdHJ1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgZGl2LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgIGRpdi5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcblxuICAgIHJldHVybiBjb3VudGVyID09PSAxO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufSkoKTtcblxuZXhwb3J0IGNsYXNzIE9uTW9kaWZpZXJTdGF0ZSB7XG4gIHB1YmxpYyB0YWcgPSBjcmVhdGVVcGRhdGFibGVUYWcoKTtcbiAgcHVibGljIGVsZW1lbnQ6IEVsZW1lbnQ7XG4gIHB1YmxpYyBhcmdzOiBDYXB0dXJlZEFyZ3VtZW50cztcbiAgcHVibGljIGV2ZW50TmFtZSE6IHN0cmluZztcbiAgcHVibGljIGNhbGxiYWNrITogRXZlbnRMaXN0ZW5lcjtcbiAgcHJpdmF0ZSB1c2VyUHJvdmlkZWRDYWxsYmFjayE6IEV2ZW50TGlzdGVuZXI7XG4gIHB1YmxpYyBvbmNlPzogYm9vbGVhbjtcbiAgcHVibGljIHBhc3NpdmU/OiBib29sZWFuO1xuICBwdWJsaWMgY2FwdHVyZT86IGJvb2xlYW47XG4gIHB1YmxpYyBvcHRpb25zPzogQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnM7XG4gIHB1YmxpYyBzaG91bGRVcGRhdGUgPSB0cnVlO1xuXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQ6IEVsZW1lbnQsIGFyZ3M6IENhcHR1cmVkQXJndW1lbnRzKSB7XG4gICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICB0aGlzLmFyZ3MgPSBhcmdzO1xuICB9XG5cbiAgdXBkYXRlRnJvbUFyZ3MoKTogdm9pZCB7XG4gICAgbGV0IHsgYXJncyB9ID0gdGhpcztcblxuICAgIGxldCB7IG9uY2UsIHBhc3NpdmUsIGNhcHR1cmUgfTogQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnMgPSByZWlmeU5hbWVkKGFyZ3MubmFtZWQpO1xuICAgIGlmIChvbmNlICE9PSB0aGlzLm9uY2UpIHtcbiAgICAgIHRoaXMub25jZSA9IG9uY2U7XG4gICAgICB0aGlzLnNob3VsZFVwZGF0ZSA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHBhc3NpdmUgIT09IHRoaXMucGFzc2l2ZSkge1xuICAgICAgdGhpcy5wYXNzaXZlID0gcGFzc2l2ZTtcbiAgICAgIHRoaXMuc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoY2FwdHVyZSAhPT0gdGhpcy5jYXB0dXJlKSB7XG4gICAgICB0aGlzLmNhcHR1cmUgPSBjYXB0dXJlO1xuICAgICAgdGhpcy5zaG91bGRVcGRhdGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGxldCBvcHRpb25zOiBBZGRFdmVudExpc3RlbmVyT3B0aW9ucztcbiAgICAvLyB3ZSB3YW50IHRvIGhhbmRsZSBib3RoIGB0cnVlYCBhbmQgYGZhbHNlYCBiZWNhdXNlIGJvdGggaGF2ZSBhIG1lYW5pbmc6XG4gICAgLy8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NzcwMjA4XG4gICAgaWYgKG9uY2UgIT09IHVuZGVmaW5lZCB8fCBwYXNzaXZlICE9PSB1bmRlZmluZWQgfHwgY2FwdHVyZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zID0geyBvbmNlLCBwYXNzaXZlLCBjYXB0dXJlIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBERUJVRyAmJlxuICAgICAgKGFyZ3MucG9zaXRpb25hbFswXSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB2YWx1ZUZvclJlZihhcmdzLnBvc2l0aW9uYWxbMF0pICE9PSAnc3RyaW5nJylcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1lvdSBtdXN0IHBhc3MgYSB2YWxpZCBET00gZXZlbnQgbmFtZSBhcyB0aGUgZmlyc3QgYXJndW1lbnQgdG8gdGhlIGBvbmAgbW9kaWZpZXInXG4gICAgICApO1xuICAgIH1cblxuICAgIGxldCBldmVudE5hbWUgPSB2YWx1ZUZvclJlZihhcmdzLnBvc2l0aW9uYWxbMF0pIGFzIHN0cmluZztcbiAgICBpZiAoZXZlbnROYW1lICE9PSB0aGlzLmV2ZW50TmFtZSkge1xuICAgICAgdGhpcy5ldmVudE5hbWUgPSBldmVudE5hbWU7XG4gICAgICB0aGlzLnNob3VsZFVwZGF0ZSA9IHRydWU7XG4gICAgfVxuXG4gICAgbGV0IHVzZXJQcm92aWRlZENhbGxiYWNrUmVmZXJlbmNlID0gYXJncy5wb3NpdGlvbmFsWzFdO1xuXG4gICAgaWYgKERFQlVHKSB7XG4gICAgICBpZiAoYXJncy5wb3NpdGlvbmFsWzFdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBZb3UgbXVzdCBwYXNzIGEgZnVuY3Rpb24gYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byB0aGUgXFxgb25cXGAgbW9kaWZpZXIuYCk7XG4gICAgICB9XG5cbiAgICAgIGxldCB2YWx1ZSA9IHZhbHVlRm9yUmVmKHVzZXJQcm92aWRlZENhbGxiYWNrUmVmZXJlbmNlKTtcblxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFlvdSBtdXN0IHBhc3MgYSBmdW5jdGlvbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIHRoZSBcXGBvblxcYCBtb2RpZmllcjsgeW91IHBhc3NlZCAke1xuICAgICAgICAgICAgdmFsdWUgPT09IG51bGwgPyAnbnVsbCcgOiB0eXBlb2YgdmFsdWVcbiAgICAgICAgICB9LiBXaGlsZSByZW5kZXJpbmc6XFxuXFxuJHt1c2VyUHJvdmlkZWRDYWxsYmFja1JlZmVyZW5jZS5kZWJ1Z0xhYmVsfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgdXNlclByb3ZpZGVkQ2FsbGJhY2sgPSB2YWx1ZUZvclJlZih1c2VyUHJvdmlkZWRDYWxsYmFja1JlZmVyZW5jZSkgYXMgRXZlbnRMaXN0ZW5lcjtcbiAgICBpZiAodXNlclByb3ZpZGVkQ2FsbGJhY2sgIT09IHRoaXMudXNlclByb3ZpZGVkQ2FsbGJhY2spIHtcbiAgICAgIHRoaXMudXNlclByb3ZpZGVkQ2FsbGJhY2sgPSB1c2VyUHJvdmlkZWRDYWxsYmFjaztcbiAgICAgIHRoaXMuc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoREVCVUcgJiYgYXJncy5wb3NpdGlvbmFsLmxlbmd0aCAhPT0gMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgWW91IGNhbiBvbmx5IHBhc3MgdHdvIHBvc2l0aW9uYWwgYXJndW1lbnRzIChldmVudCBuYW1lIGFuZCBjYWxsYmFjaykgdG8gdGhlIFxcYG9uXFxgIG1vZGlmaWVyLCBidXQgeW91IHByb3ZpZGVkICR7YXJncy5wb3NpdGlvbmFsLmxlbmd0aH0uIENvbnNpZGVyIHVzaW5nIHRoZSBcXGBmblxcYCBoZWxwZXIgdG8gcHJvdmlkZSBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byB0aGUgXFxgb25cXGAgY2FsbGJhY2suYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBsZXQgbmVlZHNDdXN0b21DYWxsYmFjayA9XG4gICAgICAoU1VQUE9SVFNfRVZFTlRfT1BUSU9OUyA9PT0gZmFsc2UgJiYgb25jZSkgLyogbmVlZHMgbWFudWFsIG9uY2UgaW1wbGVtZW50YXRpb24gKi8gfHxcbiAgICAgIChERUJVRyAmJiBwYXNzaXZlKTsgLyogbmVlZHMgcGFzc2l2ZSBlbmZvcmNlbWVudCAqL1xuXG4gICAgaWYgKHRoaXMuc2hvdWxkVXBkYXRlKSB7XG4gICAgICBpZiAobmVlZHNDdXN0b21DYWxsYmFjaykge1xuICAgICAgICBsZXQgY2FsbGJhY2sgPSAodGhpcy5jYWxsYmFjayA9IGZ1bmN0aW9uICh0aGlzOiBFbGVtZW50LCBldmVudCkge1xuICAgICAgICAgIGlmIChERUJVRyAmJiBwYXNzaXZlKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIGBZb3UgbWFya2VkIHRoaXMgbGlzdGVuZXIgYXMgJ3Bhc3NpdmUnLCBtZWFuaW5nIHRoYXQgeW91IG11c3Qgbm90IGNhbGwgJ2V2ZW50LnByZXZlbnREZWZhdWx0KCknOiBcXG5cXG4ke3VzZXJQcm92aWRlZENhbGxiYWNrfWBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFTVVBQT1JUU19FVkVOVF9PUFRJT05TICYmIG9uY2UpIHtcbiAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIodGhpcywgZXZlbnROYW1lLCBjYWxsYmFjaywgb3B0aW9ucyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB1c2VyUHJvdmlkZWRDYWxsYmFjay5jYWxsKHVudG91Y2hhYmxlQ29udGV4dCwgZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoREVCVUcpIHtcbiAgICAgICAgLy8gcHJldmVudCB0aGUgY2FsbGJhY2sgZnJvbSBiZWluZyBib3VuZCB0byB0aGUgZWxlbWVudFxuICAgICAgICB0aGlzLmNhbGxiYWNrID0gdXNlclByb3ZpZGVkQ2FsbGJhY2suYmluZCh1bnRvdWNoYWJsZUNvbnRleHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IHVzZXJQcm92aWRlZENhbGxiYWNrO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5sZXQgYWRkcyA9IDA7XG5sZXQgcmVtb3ZlcyA9IDA7XG5cbmZ1bmN0aW9uIHJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gIGVsZW1lbnQ6IEVsZW1lbnQsXG4gIGV2ZW50TmFtZTogc3RyaW5nLFxuICBjYWxsYmFjazogRXZlbnRMaXN0ZW5lcixcbiAgb3B0aW9ucz86IEFkZEV2ZW50TGlzdGVuZXJPcHRpb25zXG4pOiB2b2lkIHtcbiAgcmVtb3ZlcysrO1xuXG4gIGlmIChTVVBQT1JUU19FVkVOVF9PUFRJT05TKSB7XG4gICAgLy8gd2hlbiBvcHRpb25zIGFyZSBzdXBwb3J0ZWQsIHVzZSB0aGVtIGFjcm9zcyB0aGUgYm9hcmRcbiAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBjYWxsYmFjaywgb3B0aW9ucyk7XG4gIH0gZWxzZSBpZiAob3B0aW9ucyAhPT0gdW5kZWZpbmVkICYmIG9wdGlvbnMuY2FwdHVyZSkge1xuICAgIC8vIHVzZWQgb25seSBpbiB0aGUgZm9sbG93aW5nIGNhc2U6XG4gICAgLy9cbiAgICAvLyBgeyBvbmNlOiB0cnVlIHwgZmFsc2UsIHBhc3NpdmU6IHRydWUgfCBmYWxzZSwgY2FwdHVyZTogdHJ1ZSB9XG4gICAgLy9cbiAgICAvLyBgb25jZWAgaXMgaGFuZGxlZCB2aWEgYSBjdXN0b20gY2FsbGJhY2sgdGhhdCByZW1vdmVzIGFmdGVyIGZpcnN0XG4gICAgLy8gaW52b2NhdGlvbiBzbyB3ZSBvbmx5IGNhcmUgYWJvdXQgY2FwdHVyZSBoZXJlIGFzIGEgYm9vbGVhblxuICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrLCB0cnVlKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB1c2VkIG9ubHkgaW4gdGhlIGZvbGxvd2luZyBjYXNlczpcbiAgICAvL1xuICAgIC8vICogd2hlcmUgdGhlcmUgaXMgbm8gb3B0aW9uc1xuICAgIC8vICogYHsgb25jZTogdHJ1ZSB8IGZhbHNlLCBwYXNzaXZlOiB0cnVlIHwgZmFsc2UsIGNhcHR1cmU6IGZhbHNlIH1cbiAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBjYWxsYmFjayk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkRXZlbnRMaXN0ZW5lcihcbiAgZWxlbWVudDogRWxlbWVudCxcbiAgZXZlbnROYW1lOiBzdHJpbmcsXG4gIGNhbGxiYWNrOiBFdmVudExpc3RlbmVyLFxuICBvcHRpb25zPzogQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnNcbik6IHZvaWQge1xuICBhZGRzKys7XG5cbiAgaWYgKFNVUFBPUlRTX0VWRU5UX09QVElPTlMpIHtcbiAgICAvLyB3aGVuIG9wdGlvbnMgYXJlIHN1cHBvcnRlZCwgdXNlIHRoZW0gYWNyb3NzIHRoZSBib2FyZFxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrLCBvcHRpb25zKTtcbiAgfSBlbHNlIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5jYXB0dXJlKSB7XG4gICAgLy8gdXNlZCBvbmx5IGluIHRoZSBmb2xsb3dpbmcgY2FzZTpcbiAgICAvL1xuICAgIC8vIGB7IG9uY2U6IHRydWUgfCBmYWxzZSwgcGFzc2l2ZTogdHJ1ZSB8IGZhbHNlLCBjYXB0dXJlOiB0cnVlIH1cbiAgICAvL1xuICAgIC8vIGBvbmNlYCBpcyBoYW5kbGVkIHZpYSBhIGN1c3RvbSBjYWxsYmFjayB0aGF0IHJlbW92ZXMgYWZ0ZXIgZmlyc3RcbiAgICAvLyBpbnZvY2F0aW9uIHNvIHdlIG9ubHkgY2FyZSBhYm91dCBjYXB0dXJlIGhlcmUgYXMgYSBib29sZWFuXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgY2FsbGJhY2ssIHRydWUpO1xuICB9IGVsc2Uge1xuICAgIC8vIHVzZWQgb25seSBpbiB0aGUgZm9sbG93aW5nIGNhc2VzOlxuICAgIC8vXG4gICAgLy8gKiB3aGVyZSB0aGVyZSBpcyBubyBvcHRpb25zXG4gICAgLy8gKiBgeyBvbmNlOiB0cnVlIHwgZmFsc2UsIHBhc3NpdmU6IHRydWUgfCBmYWxzZSwgY2FwdHVyZTogZmFsc2UgfVxuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrKTtcbiAgfVxufVxuXG4vKipcbiAgVGhlIGB7e29ufX1gIG1vZGlmaWVyIGxldHMgeW91IGVhc2lseSBhZGQgZXZlbnQgbGlzdGVuZXJzIChpdCB1c2VzXG4gIFtFdmVudFRhcmdldC5hZGRFdmVudExpc3RlbmVyXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lcilcbiAgaW50ZXJuYWxseSkuXG5cbiAgRm9yIGV4YW1wbGUsIGlmIHlvdSdkIGxpa2UgdG8gcnVuIGEgZnVuY3Rpb24gb24geW91ciBjb21wb25lbnQgd2hlbiBhIGA8YnV0dG9uPmBcbiAgaW4gdGhlIGNvbXBvbmVudHMgdGVtcGxhdGUgaXMgY2xpY2tlZCB5b3UgbWlnaHQgZG8gc29tZXRoaW5nIGxpa2U6XG5cbiAgYGBgYXBwL2NvbXBvbmVudHMvbGlrZS1wb3N0Lmhic1xuICA8YnV0dG9uIHt7b24gJ2NsaWNrJyB0aGlzLnNhdmVMaWtlfX0+TGlrZSB0aGlzIHBvc3QhPC9idXR0b24+XG4gIGBgYFxuXG4gIGBgYGFwcC9jb21wb25lbnRzL2xpa2UtcG9zdC5qc1xuICBpbXBvcnQgQ29tcG9uZW50IGZyb20gJ0BnbGltbWVyL2NvbXBvbmVudCc7XG4gIGltcG9ydCB7IGFjdGlvbiB9IGZyb20gJ0BlbWJlci9vYmplY3QnO1xuXG4gIGV4cG9ydCBkZWZhdWx0IGNsYXNzIExpa2VQb3N0Q29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgICBzYXZlTGlrZSA9ICgpID0+IHtcbiAgICAgIC8vIHNvbWVvbmUgbGlrZXMgeW91ciBwb3N0IVxuICAgICAgLy8gYmV0dGVyIHNlbmQgYSByZXF1ZXN0IG9mZiB0byB5b3VyIHNlcnZlci4uLlxuICAgIH1cbiAgfVxuICBgYGBcblxuICAjIyMgQXJndW1lbnRzXG5cbiAgYHt7b259fWAgYWNjZXB0cyB0d28gcG9zaXRpb25hbCBhcmd1bWVudHMsIGFuZCBhIGZldyBuYW1lZCBhcmd1bWVudHMuXG5cbiAgVGhlIHBvc2l0aW9uYWwgYXJndW1lbnRzIGFyZTpcblxuICAtIGBldmVudGAgLS0gdGhlIG5hbWUgdG8gdXNlIHdoZW4gY2FsbGluZyBgYWRkRXZlbnRMaXN0ZW5lcmBcbiAgLSBgY2FsbGJhY2tgIC0tIHRoZSBmdW5jdGlvbiB0byBiZSBwYXNzZWQgdG8gYGFkZEV2ZW50TGlzdGVuZXJgXG5cbiAgVGhlIG5hbWVkIGFyZ3VtZW50cyBhcmU6XG5cbiAgLSBjYXB0dXJlIC0tIGEgYHRydWVgIHZhbHVlIGluZGljYXRlcyB0aGF0IGV2ZW50cyBvZiB0aGlzIHR5cGUgd2lsbCBiZSBkaXNwYXRjaGVkXG4gICAgdG8gdGhlIHJlZ2lzdGVyZWQgbGlzdGVuZXIgYmVmb3JlIGJlaW5nIGRpc3BhdGNoZWQgdG8gYW55IEV2ZW50VGFyZ2V0IGJlbmVhdGggaXRcbiAgICBpbiB0aGUgRE9NIHRyZWUuXG4gIC0gb25jZSAtLSBpbmRpY2F0ZXMgdGhhdCB0aGUgbGlzdGVuZXIgc2hvdWxkIGJlIGludm9rZWQgYXQgbW9zdCBvbmNlIGFmdGVyIGJlaW5nXG4gICAgYWRkZWQuIElmIHRydWUsIHRoZSBsaXN0ZW5lciB3b3VsZCBiZSBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgd2hlbiBpbnZva2VkLlxuICAtIHBhc3NpdmUgLS0gaWYgYHRydWVgLCBpbmRpY2F0ZXMgdGhhdCB0aGUgZnVuY3Rpb24gc3BlY2lmaWVkIGJ5IGxpc3RlbmVyIHdpbGwgbmV2ZXJcbiAgICBjYWxsIHByZXZlbnREZWZhdWx0KCkuIElmIGEgcGFzc2l2ZSBsaXN0ZW5lciBkb2VzIGNhbGwgcHJldmVudERlZmF1bHQoKSwgdGhlIHVzZXJcbiAgICBhZ2VudCB3aWxsIGRvIG5vdGhpbmcgb3RoZXIgdGhhbiBnZW5lcmF0ZSBhIGNvbnNvbGUgd2FybmluZy4gU2VlXG4gICAgW0ltcHJvdmluZyBzY3JvbGxpbmcgcGVyZm9ybWFuY2Ugd2l0aCBwYXNzaXZlIGxpc3RlbmVyc10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0V2ZW50VGFyZ2V0L2FkZEV2ZW50TGlzdGVuZXIjSW1wcm92aW5nX3Njcm9sbGluZ19wZXJmb3JtYW5jZV93aXRoX3Bhc3NpdmVfbGlzdGVuZXJzKVxuICAgIHRvIGxlYXJuIG1vcmUuXG5cbiAgVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHBhc3NlZCB0byBge3tvbn19YCB3aWxsIHJlY2VpdmUgYW55IGFyZ3VtZW50cyB0aGF0IGFyZSBwYXNzZWRcbiAgdG8gdGhlIGV2ZW50IGhhbmRsZXIuIE1vc3QgY29tbW9ubHkgdGhpcyB3b3VsZCBiZSB0aGUgYGV2ZW50YCBpdHNlbGYuXG5cbiAgSWYgeW91IHdvdWxkIGxpa2UgdG8gcGFzcyBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byB0aGUgZnVuY3Rpb24geW91IHNob3VsZCB1c2VcbiAgdGhlIGB7e2ZufX1gIGhlbHBlci5cblxuICBGb3IgZXhhbXBsZSwgaW4gb3VyIGV4YW1wbGUgY2FzZSBhYm92ZSBpZiB5b3UnZCBsaWtlIHRvIHBhc3MgaW4gdGhlIHBvc3QgdGhhdFxuICB3YXMgYmVpbmcgbGlrZWQgd2hlbiB0aGUgYnV0dG9uIGlzIGNsaWNrZWQgeW91IGNvdWxkIGRvIHNvbWV0aGluZyBsaWtlOlxuXG4gIGBgYGFwcC9jb21wb25lbnRzL2xpa2UtcG9zdC5oYnNcbiAgPGJ1dHRvbiB7e29uICdjbGljaycgKGZuIHRoaXMuc2F2ZUxpa2UgQHBvc3QpfX0+TGlrZSB0aGlzIHBvc3QhPC9idXR0b24+XG4gIGBgYFxuXG4gIEluIHRoaXMgY2FzZSwgdGhlIGBzYXZlTGlrZWAgZnVuY3Rpb24gd2lsbCByZWNlaXZlIHR3byBhcmd1bWVudHM6IHRoZSBjbGljayBldmVudFxuICBhbmQgdGhlIHZhbHVlIG9mIGBAcG9zdGAuXG5cbiAgIyMjIEZ1bmN0aW9uIENvbnRleHRcblxuICBJbiB0aGUgZXhhbXBsZSBhYm92ZSwgd2UgdXNlZCBhbiBhcnJvdyBmdW5jdGlvbiB0byBlbnN1cmUgdGhhdCBgbGlrZVBvc3RgIGlzXG4gIHByb3Blcmx5IGJvdW5kIHRvIHRoZSBgaXRlbXMtbGlzdGAsIGJ1dCBsZXQncyBleHBsb3JlIHdoYXQgaGFwcGVucyBpZiB3ZVxuICBsZWZ0IG91dCB0aGUgYXJyb3cgZnVuY3Rpb246XG5cbiAgYGBgYXBwL2NvbXBvbmVudHMvbGlrZS1wb3N0LmpzXG4gIGltcG9ydCBDb21wb25lbnQgZnJvbSAnQGdsaW1tZXIvY29tcG9uZW50JztcblxuICBleHBvcnQgZGVmYXVsdCBjbGFzcyBMaWtlUG9zdENvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudCB7XG4gICAgc2F2ZUxpa2UoKSB7XG4gICAgICAvLyAuLi5zbmlwLi4uXG4gICAgfVxuICB9XG4gIGBgYFxuXG4gIEluIHRoaXMgZXhhbXBsZSwgd2hlbiB0aGUgYnV0dG9uIGlzIGNsaWNrZWQgYHNhdmVMaWtlYCB3aWxsIGJlIGludm9rZWQsXG4gIGl0IHdpbGwgKipub3QqKiBoYXZlIGFjY2VzcyB0byB0aGUgY29tcG9uZW50IGluc3RhbmNlLiBJbiBvdGhlclxuICB3b3JkcywgaXQgd2lsbCBoYXZlIG5vIGB0aGlzYCBjb250ZXh0LCBzbyBwbGVhc2UgbWFrZSBzdXJlIHlvdXIgZnVuY3Rpb25zXG4gIGFyZSBib3VuZCAodmlhIGFuIGFycm93IGZ1bmN0aW9uIG9yIG90aGVyIG1lYW5zKSBiZWZvcmUgcGFzc2luZyBpbnRvIGBvbmAhXG5cbiAgQG1ldGhvZCBvblxuICBAcHVibGljXG4qL1xuY2xhc3MgT25Nb2RpZmllck1hbmFnZXIgaW1wbGVtZW50cyBJbnRlcm5hbE1vZGlmaWVyTWFuYWdlcjxPbk1vZGlmaWVyU3RhdGUgfCBudWxsLCBvYmplY3Q+IHtcbiAgcHVibGljIFNVUFBPUlRTX0VWRU5UX09QVElPTlM6IGJvb2xlYW4gPSBTVVBQT1JUU19FVkVOVF9PUFRJT05TO1xuXG4gIGdldERlYnVnTmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiAnb24nO1xuICB9XG5cbiAgZ2V0IGNvdW50ZXJzKCk6IHsgYWRkczogbnVtYmVyOyByZW1vdmVzOiBudW1iZXIgfSB7XG4gICAgcmV0dXJuIHsgYWRkcywgcmVtb3ZlcyB9O1xuICB9XG5cbiAgY3JlYXRlKFxuICAgIF9vd25lcjogT3duZXIsXG4gICAgZWxlbWVudDogU2ltcGxlRWxlbWVudCB8IEVsZW1lbnQsXG4gICAgX3N0YXRlOiBvYmplY3QsXG4gICAgYXJnczogQ2FwdHVyZWRBcmd1bWVudHNcbiAgKTogT25Nb2RpZmllclN0YXRlIHwgbnVsbCB7XG4gICAgcmV0dXJuIG5ldyBPbk1vZGlmaWVyU3RhdGUoZWxlbWVudCBhcyBFbGVtZW50LCBhcmdzKTtcbiAgfVxuXG4gIGdldFRhZyhzdGF0ZTogT25Nb2RpZmllclN0YXRlIHwgbnVsbCk6IFVwZGF0YWJsZVRhZyB8IG51bGwge1xuICAgIGlmIChzdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXRlLnRhZztcbiAgfVxuXG4gIGluc3RhbGwoc3RhdGU6IE9uTW9kaWZpZXJTdGF0ZSB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAoc3RhdGUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzdGF0ZS51cGRhdGVGcm9tQXJncygpO1xuXG4gICAgbGV0IHsgZWxlbWVudCwgZXZlbnROYW1lLCBjYWxsYmFjaywgb3B0aW9ucyB9ID0gc3RhdGU7XG5cbiAgICBhZGRFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIG9wdGlvbnMpO1xuXG4gICAgcmVnaXN0ZXJEZXN0cnVjdG9yKHN0YXRlLCAoKSA9PiByZW1vdmVFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIG9wdGlvbnMpKTtcblxuICAgIHN0YXRlLnNob3VsZFVwZGF0ZSA9IGZhbHNlO1xuICB9XG5cbiAgdXBkYXRlKHN0YXRlOiBPbk1vZGlmaWVyU3RhdGUgfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKHN0YXRlID09PSBudWxsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gc3Rhc2ggcHJpb3Igc3RhdGUgZm9yIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXJcbiAgICBsZXQgeyBlbGVtZW50LCBldmVudE5hbWUsIGNhbGxiYWNrLCBvcHRpb25zIH0gPSBzdGF0ZTtcblxuICAgIHN0YXRlLnVwZGF0ZUZyb21BcmdzKCk7XG5cbiAgICBpZiAoIXN0YXRlLnNob3VsZFVwZGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHVzZSBwcmlvciBzdGF0ZSB2YWx1ZXMgZm9yIHJlbW92YWxcbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIG9wdGlvbnMpO1xuXG4gICAgLy8gcmVhZCB1cGRhdGVkIHZhbHVlcyBmcm9tIHRoZSBzdGF0ZSBvYmplY3RcbiAgICBhZGRFdmVudExpc3RlbmVyKHN0YXRlLmVsZW1lbnQsIHN0YXRlLmV2ZW50TmFtZSwgc3RhdGUuY2FsbGJhY2ssIHN0YXRlLm9wdGlvbnMpO1xuXG4gICAgc3RhdGUuc2hvdWxkVXBkYXRlID0gZmFsc2U7XG4gIH1cblxuICBnZXREZXN0cm95YWJsZShzdGF0ZTogT25Nb2RpZmllclN0YXRlIHwgbnVsbCk6IE9uTW9kaWZpZXJTdGF0ZSB8IG51bGwge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBzZXRJbnRlcm5hbE1vZGlmaWVyTWFuYWdlcihuZXcgT25Nb2RpZmllck1hbmFnZXIoKSwge30pO1xuIl0sInNvdXJjZVJvb3QiOiIifQ==