UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

389 lines (307 loc) 36.1 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"); const 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. */ const SUPPORTS_EVENT_OPTIONS = (() => { try { const div = document.createElement('div'); let counter = 0; div.addEventListener('click', () => counter++, { once: true }); let 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; } })(); class OnModifierState { constructor(element, args) { this.tag = (0, _validator.createUpdatableTag)(); this.shouldUpdate = true; this.element = element; this.args = args; } updateFromArgs() { let { args } = this; let { once, passive, capture } = (0, _runtime.reifyNamed)(args.named); 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; } let 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, passive, 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'); } let eventName = (0, _reference.valueForRef)(args.positional[0]); if (eventName !== this.eventName) { this.eventName = eventName; this.shouldUpdate = true; } let 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.`); } let 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}`); } } let 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.`); } let needsCustomCallback = SUPPORTS_EVENT_OPTIONS === false && once || /* needs manual once implementation */ _env.DEBUG && passive; /* needs passive enforcement */ if (this.shouldUpdate) { if (needsCustomCallback) { let callback = this.callback = function (event) { if (_env.DEBUG && passive) { event.preventDefault = () => { 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; } } } } exports.OnModifierState = OnModifierState; let adds = 0; let 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 */ class OnModifierManager { constructor() { this.SUPPORTS_EVENT_OPTIONS = SUPPORTS_EVENT_OPTIONS; } getDebugName() { return 'on'; } get counters() { return { adds, removes }; } create(_owner, element, _state, args) { return new OnModifierState(element, args); } getTag(state) { if (state === null) { return null; } return state.tag; } install(state) { if (state === null) { return; } state.updateFromArgs(); let { element, eventName, callback, options } = state; addEventListener(element, eventName, callback, options); (0, _destroyable.registerDestructor)(state, () => removeEventListener(element, eventName, callback, options)); state.shouldUpdate = false; } update(state) { if (state === null) { return; } // stash prior state for el.removeEventListener let { element, eventName, callback, options } = state; 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; } getDestroyable(state) { return state; } } var _default = (0, _manager.setInternalModifierManager)(new OnModifierManager(), {}); exports.default = _default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL21vZGlmaWVycy9vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBRUEsTUFBTSxrQkFBa0IsR0FBRyxnQ0FBM0IsZUFBMkIsQ0FBM0I7QUFFQTs7Ozs7Ozs7Ozs7OztBQVlBLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxNQUFLO0FBQ25DLE1BQUk7QUFDRixVQUFNLEdBQUcsR0FBRyxRQUFRLENBQVIsYUFBQSxDQUFaLEtBQVksQ0FBWjtBQUNBLFFBQUksT0FBTyxHQUFYLENBQUE7QUFDQSxJQUFBLEdBQUcsQ0FBSCxnQkFBQSxDQUFBLE9BQUEsRUFBOEIsTUFBTSxPQUFwQyxFQUFBLEVBQStDO0FBQUUsTUFBQSxJQUFJLEVBQUU7QUFBUixLQUEvQztBQUVBLFFBQUEsS0FBQTs7QUFDQSxRQUFJLE9BQUEsS0FBQSxLQUFKLFVBQUEsRUFBaUM7QUFDL0IsTUFBQSxLQUFLLEdBQUcsSUFBQSxLQUFBLENBQVIsT0FBUSxDQUFSO0FBREYsS0FBQSxNQUVPO0FBQ0wsTUFBQSxLQUFLLEdBQUcsUUFBUSxDQUFSLFdBQUEsQ0FBUixPQUFRLENBQVI7QUFDQSxNQUFBLEtBQUssQ0FBTCxTQUFBLENBQUEsT0FBQSxFQUFBLElBQUEsRUFBQSxJQUFBO0FBQ0Q7O0FBRUQsSUFBQSxHQUFHLENBQUgsYUFBQSxDQUFBLEtBQUE7QUFDQSxJQUFBLEdBQUcsQ0FBSCxhQUFBLENBQUEsS0FBQTtBQUVBLFdBQU8sT0FBTyxLQUFkLENBQUE7QUFoQkYsR0FBQSxDQWlCRSxPQUFBLEtBQUEsRUFBYztBQUNkLFdBQUEsS0FBQTtBQUNEO0FBcEJILENBQStCLEdBQS9COztBQXVCTSxNQUFBLGVBQUEsQ0FBc0I7QUFhMUIsRUFBQSxXQUFBLENBQUEsT0FBQSxFQUFBLElBQUEsRUFBcUQ7QUFaOUMsU0FBQSxHQUFB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QWdCLEtBQUssQ0FBckIsU0FBQSxFQUFpQyxLQUFLLENBQXRDLFFBQUEsRUFBaUQsS0FBSyxDQUF0RSxPQUFnQixDQUFoQjtBQUVBLElBQUEsS0FBSyxDQUFMLFlBQUEsR0FBQSxLQUFBO0FBQ0Q7O0FBRUQsRUFBQSxjQUFjLENBQUEsS0FBQSxFQUE4QjtBQUMxQyxXQUFBLEtBQUE7QUFDRDs7QUFyRW9COztlQXdFUix5Q0FBMkIsSUFBRCxpQkFBQyxFQUEzQixFQUFmLEVBQWUsQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJlZ2lzdGVyRGVzdHJ1Y3RvciB9IGZyb20gJ0BnbGltbWVyL2Rlc3Ryb3lhYmxlJztcbmltcG9ydCB7IERFQlVHIH0gZnJvbSAnQGdsaW1tZXIvZW52JztcbmltcG9ydCB7IENhcHR1cmVkQXJndW1lbnRzLCBJbnRlcm5hbE1vZGlmaWVyTWFuYWdlciwgT3duZXIgfSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IHNldEludGVybmFsTW9kaWZpZXJNYW5hZ2VyIH0gZnJvbSAnQGdsaW1tZXIvbWFuYWdlcic7XG5pbXBvcnQgeyB2YWx1ZUZvclJlZiB9IGZyb20gJ0BnbGltbWVyL3JlZmVyZW5jZSc7XG5pbXBvcnQgeyByZWlmeU5hbWVkIH0gZnJvbSAnQGdsaW1tZXIvcnVudGltZSc7XG5pbXBvcnQgeyBjcmVhdGVVcGRhdGFibGVUYWcsIFVwZGF0YWJsZVRhZyB9IGZyb20gJ0BnbGltbWVyL3ZhbGlkYXRvcic7XG5pbXBvcnQgeyBTaW1wbGVFbGVtZW50IH0gZnJvbSAnQHNpbXBsZS1kb20vaW50ZXJmYWNlJztcbmltcG9ydCB7IGJ1aWxkVW50b3VjaGFibGVUaGlzIH0gZnJvbSAnQGdsaW1tZXIvdXRpbCc7XG5cbmNvbnN0IHVudG91Y2hhYmxlQ29udGV4dCA9IGJ1aWxkVW50b3VjaGFibGVUaGlzKCdgb25gIG1vZGlmaWVyJyk7XG5cbi8qXG4gIEludGVybmV0IEV4cGxvcmVyIDExIGRvZXMgbm90IHN1cHBvcnQgYG9uY2VgIGFuZCBhbHNvIGRvZXMgbm90IHN1cHBvcnRcbiAgcGFzc2luZyBgZXZlbnRPcHRpb25zYC4gSW4gc29tZSBzaXR1YXRpb25zIGl0IHRoZW4gdGhyb3dzIGEgd2VpcmQgc2NyaXB0XG4gIGVycm9yLCBsaWtlOlxuXG4gIGBgYFxuICBDb3VsZCBub3QgY29tcGxldGUgdGhlIG9wZXJhdGlvbiBkdWUgdG8gZXJyb3IgODAwMjAxMDFcbiAgYGBgXG5cbiAgVGhpcyBmbGFnIGRldGVybWluZXMsIHdoZXRoZXIgYHsgb25jZTogdHJ1ZSB9YCBhbmQgdGh1cyBhbHNvIGV2ZW50IG9wdGlvbnMgaW5cbiAgZ2VuZXJhbCBhcmUgc3VwcG9ydGVkLlxuKi9cbmNvbnN0IFNVUFBPUlRTX0VWRU5UX09QVElPTlMgPSAoKCkgPT4ge1xuICB0cnkge1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGxldCBjb3VudGVyID0gMDtcbiAgICBkaXYuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiBjb3VudGVyKyssIHsgb25jZTogdHJ1ZSB9KTtcblxuICAgIGxldCBldmVudDtcbiAgICBpZiAodHlwZW9mIEV2ZW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBldmVudCA9IG5ldyBFdmVudCgnY2xpY2snKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnRXZlbnQnKTtcbiAgICAgIGV2ZW50LmluaXRFdmVudCgnY2xpY2snLCB0cnVlLCB0cnVlKTtcbiAgICB9XG5cbiAgICBkaXYuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgZGl2LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuXG4gICAgcmV0dXJuIGNvdW50ZXIgPT09IDE7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59KSgpO1xuXG5leHBvcnQgY2xhc3MgT25Nb2RpZmllclN0YXRlIHtcbiAgcHVibGljIHRhZyA9IGNyZWF0ZVVwZGF0YWJsZVRhZygpO1xuICBwdWJsaWMgZWxlbWVudDogRWxlbWVudDtcbiAgcHVibGljIGFyZ3M6IENhcHR1cmVkQXJndW1lbnRzO1xuICBwdWJsaWMgZXZlbnROYW1lITogc3RyaW5nO1xuICBwdWJsaWMgY2FsbGJhY2shOiBFdmVudExpc3RlbmVyO1xuICBwcml2YXRlIHVzZXJQcm92aWRlZENhbGxiYWNrITogRXZlbnRMaXN0ZW5lcjtcbiAgcHVibGljIG9uY2U/OiBib29sZWFuO1xuICBwdWJsaWMgcGFzc2l2ZT86IGJvb2xlYW47XG4gIHB1YmxpYyBjYXB0dXJlPzogYm9vbGVhbjtcbiAgcHVibGljIG9wdGlvbnM/OiBBZGRFdmVudExpc3RlbmVyT3B0aW9ucztcbiAgcHVibGljIHNob3VsZFVwZGF0ZSA9IHRydWU7XG5cbiAgY29uc3RydWN0b3IoZWxlbWVudDogRWxlbWVudCwgYXJnczogQ2FwdHVyZWRBcmd1bWVudHMpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgIHRoaXMuYXJncyA9IGFyZ3M7XG4gIH1cblxuICB1cGRhdGVGcm9tQXJncygpOiB2b2lkIHtcbiAgICBsZXQgeyBhcmdzIH0gPSB0aGlzO1xuXG4gICAgbGV0IHsgb25jZSwgcGFzc2l2ZSwgY2FwdHVyZSB9OiBBZGRFdmVudExpc3RlbmVyT3B0aW9ucyA9IHJlaWZ5TmFtZWQoYXJncy5uYW1lZCk7XG4gICAgaWYgKG9uY2UgIT09IHRoaXMub25jZSkge1xuICAgICAgdGhpcy5vbmNlID0gb25jZTtcbiAgICAgIHRoaXMuc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAocGFzc2l2ZSAhPT0gdGhpcy5wYXNzaXZlKSB7XG4gICAgICB0aGlzLnBhc3NpdmUgPSBwYXNzaXZlO1xuICAgICAgdGhpcy5zaG91bGRVcGRhdGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChjYXB0dXJlICE9PSB0aGlzLmNhcHR1cmUpIHtcbiAgICAgIHRoaXMuY2FwdHVyZSA9IGNhcHR1cmU7XG4gICAgICB0aGlzLnNob3VsZFVwZGF0ZSA9IHRydWU7XG4gICAgfVxuXG4gICAgbGV0IG9wdGlvbnM6IEFkZEV2ZW50TGlzdGVuZXJPcHRpb25zO1xuICAgIC8vIHdlIHdhbnQgdG8gaGFuZGxlIGJvdGggYHRydWVgIGFuZCBgZmFsc2VgIGJlY2F1c2UgYm90aCBoYXZlIGEgbWVhbmluZzpcbiAgICAvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD03NzAyMDhcbiAgICBpZiAob25jZSAhPT0gdW5kZWZpbmVkIHx8IHBhc3NpdmUgIT09IHVuZGVmaW5lZCB8fCBjYXB0dXJlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMgPSB7IG9uY2UsIHBhc3NpdmUsIGNhcHR1cmUgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcHRpb25zID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIERFQlVHICYmXG4gICAgICAoYXJncy5wb3NpdGlvbmFsWzBdID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHZhbHVlRm9yUmVmKGFyZ3MucG9zaXRpb25hbFswXSkgIT09ICdzdHJpbmcnKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnWW91IG11c3QgcGFzcyBhIHZhbGlkIERPTSBldmVudCBuYW1lIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0byB0aGUgYG9uYCBtb2RpZmllcidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgbGV0IGV2ZW50TmFtZSA9IHZhbHVlRm9yUmVmKGFyZ3MucG9zaXRpb25hbFswXSkgYXMgc3RyaW5nO1xuICAgIGlmIChldmVudE5hbWUgIT09IHRoaXMuZXZlbnROYW1lKSB7XG4gICAgICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgICAgIHRoaXMuc2hvdWxkVXBkYXRlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBsZXQgdXNlclByb3ZpZGVkQ2FsbGJhY2tSZWZlcmVuY2UgPSBhcmdzLnBvc2l0aW9uYWxbMV07XG5cbiAgICBpZiAoREVCVUcpIHtcbiAgICAgIGlmIChhcmdzLnBvc2l0aW9uYWxbMV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFlvdSBtdXN0IHBhc3MgYSBmdW5jdGlvbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIHRoZSBcXGBvblxcYCBtb2RpZmllci5gKTtcbiAgICAgIH1cblxuICAgICAgbGV0IHZhbHVlID0gdmFsdWVGb3JSZWYodXNlclByb3ZpZGVkQ2FsbGJhY2tSZWZlcmVuY2UpO1xuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgWW91IG11c3QgcGFzcyBhIGZ1bmN0aW9uIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgdG8gdGhlIFxcYG9uXFxgIG1vZGlmaWVyOyB5b3UgcGFzc2VkICR7XG4gICAgICAgICAgICB2YWx1ZSA9PT0gbnVsbCA/ICdudWxsJyA6IHR5cGVvZiB2YWx1ZVxuICAgICAgICAgIH0uIFdoaWxlIHJlbmRlcmluZzpcXG5cXG4ke3VzZXJQcm92aWRlZENhbGxiYWNrUmVmZXJlbmNlLmRlYnVnTGFiZWx9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCB1c2VyUHJvdmlkZWRDYWxsYmFjayA9IHZhbHVlRm9yUmVmKHVzZXJQcm92aWRlZENhbGxiYWNrUmVmZXJlbmNlKSBhcyBFdmVudExpc3RlbmVyO1xuICAgIGlmICh1c2VyUHJvdmlkZWRDYWxsYmFjayAhPT0gdGhpcy51c2VyUHJvdmlkZWRDYWxsYmFjaykge1xuICAgICAgdGhpcy51c2VyUHJvdmlkZWRDYWxsYmFjayA9IHVzZXJQcm92aWRlZENhbGxiYWNrO1xuICAgICAgdGhpcy5zaG91bGRVcGRhdGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChERUJVRyAmJiBhcmdzLnBvc2l0aW9uYWwubGVuZ3RoICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBZb3UgY2FuIG9ubHkgcGFzcyB0d28gcG9zaXRpb25hbCBhcmd1bWVudHMgKGV2ZW50IG5hbWUgYW5kIGNhbGxiYWNrKSB0byB0aGUgXFxgb25cXGAgbW9kaWZpZXIsIGJ1dCB5b3UgcHJvdmlkZWQgJHthcmdzLnBvc2l0aW9uYWwubGVuZ3RofS4gQ29uc2lkZXIgdXNpbmcgdGhlIFxcYGZuXFxgIGhlbHBlciB0byBwcm92aWRlIGFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHRoZSBcXGBvblxcYCBjYWxsYmFjay5gXG4gICAgICApO1xuICAgIH1cblxuICAgIGxldCBuZWVkc0N1c3RvbUNhbGxiYWNrID1cbiAgICAgIChTVVBQT1JUU19FVkVOVF9PUFRJT05TID09PSBmYWxzZSAmJiBvbmNlKSAvKiBuZWVkcyBtYW51YWwgb25jZSBpbXBsZW1lbnRhdGlvbiAqLyB8fFxuICAgICAgKERFQlVHICYmIHBhc3NpdmUpOyAvKiBuZWVkcyBwYXNzaXZlIGVuZm9yY2VtZW50ICovXG5cbiAgICBpZiAodGhpcy5zaG91bGRVcGRhdGUpIHtcbiAgICAgIGlmIChuZWVkc0N1c3RvbUNhbGxiYWNrKSB7XG4gICAgICAgIGxldCBjYWxsYmFjayA9ICh0aGlzLmNhbGxiYWNrID0gZnVuY3Rpb24gKHRoaXM6IEVsZW1lbnQsIGV2ZW50KSB7XG4gICAgICAgICAgaWYgKERFQlVHICYmIHBhc3NpdmUpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgYFlvdSBtYXJrZWQgdGhpcyBsaXN0ZW5lciBhcyAncGFzc2l2ZScsIG1lYW5pbmcgdGhhdCB5b3UgbXVzdCBub3QgY2FsbCAnZXZlbnQucHJldmVudERlZmF1bHQoKSc6IFxcblxcbiR7dXNlclByb3ZpZGVkQ2FsbGJhY2t9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIVNVUFBPUlRTX0VWRU5UX09QVElPTlMgJiYgb25jZSkge1xuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcih0aGlzLCBldmVudE5hbWUsIGNhbGxiYWNrLCBvcHRpb25zKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHVzZXJQcm92aWRlZENhbGxiYWNrLmNhbGwodW50b3VjaGFibGVDb250ZXh0LCBldmVudCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChERUJVRykge1xuICAgICAgICAvLyBwcmV2ZW50IHRoZSBjYWxsYmFjayBmcm9tIGJlaW5nIGJvdW5kIHRvIHRoZSBlbGVtZW50XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSB1c2VyUHJvdmlkZWRDYWxsYmFjay5iaW5kKHVudG91Y2hhYmxlQ29udGV4dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gdXNlclByb3ZpZGVkQ2FsbGJhY2s7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmxldCBhZGRzID0gMDtcbmxldCByZW1vdmVzID0gMDtcblxuZnVuY3Rpb24gcmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgZWxlbWVudDogRWxlbWVudCxcbiAgZXZlbnROYW1lOiBzdHJpbmcsXG4gIGNhbGxiYWNrOiBFdmVudExpc3RlbmVyLFxuICBvcHRpb25zPzogQWRkRXZlbnRMaXN0ZW5lck9wdGlvbnNcbik6IHZvaWQge1xuICByZW1vdmVzKys7XG5cbiAgaWYgKFNVUFBPUlRTX0VWRU5UX09QVElPTlMpIHtcbiAgICAvLyB3aGVuIG9wdGlvbnMgYXJlIHN1cHBvcnRlZCwgdXNlIHRoZW0gYWNyb3NzIHRoZSBib2FyZFxuICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrLCBvcHRpb25zKTtcbiAgfSBlbHNlIGlmIChvcHRpb25zICE9PSB1bmRlZmluZWQgJiYgb3B0aW9ucy5jYXB0dXJlKSB7XG4gICAgLy8gdXNlZCBvbmx5IGluIHRoZSBmb2xsb3dpbmcgY2FzZTpcbiAgICAvL1xuICAgIC8vIGB7IG9uY2U6IHRydWUgfCBmYWxzZSwgcGFzc2l2ZTogdHJ1ZSB8IGZhbHNlLCBjYXB0dXJlOiB0cnVlIH1cbiAgICAvL1xuICAgIC8vIGBvbmNlYCBpcyBoYW5kbGVkIHZpYSBhIGN1c3RvbSBjYWxsYmFjayB0aGF0IHJlbW92ZXMgYWZ0ZXIgZmlyc3RcbiAgICAvLyBpbnZvY2F0aW9uIHNvIHdlIG9ubHkgY2FyZSBhYm91dCBjYXB0dXJlIGhlcmUgYXMgYSBib29sZWFuXG4gICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgY2FsbGJhY2ssIHRydWUpO1xuICB9IGVsc2Uge1xuICAgIC8vIHVzZWQgb25seSBpbiB0aGUgZm9sbG93aW5nIGNhc2VzOlxuICAgIC8vXG4gICAgLy8gKiB3aGVyZSB0aGVyZSBpcyBubyBvcHRpb25zXG4gICAgLy8gKiBgeyBvbmNlOiB0cnVlIHwgZmFsc2UsIHBhc3NpdmU6IHRydWUgfCBmYWxzZSwgY2FwdHVyZTogZmFsc2UgfVxuICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhZGRFdmVudExpc3RlbmVyKFxuICBlbGVtZW50OiBFbGVtZW50LFxuICBldmVudE5hbWU6IHN0cmluZyxcbiAgY2FsbGJhY2s6IEV2ZW50TGlzdGVuZXIsXG4gIG9wdGlvbnM/OiBBZGRFdmVudExpc3RlbmVyT3B0aW9uc1xuKTogdm9pZCB7XG4gIGFkZHMrKztcblxuICBpZiAoU1VQUE9SVFNfRVZFTlRfT1BUSU9OUykge1xuICAgIC8vIHdoZW4gb3B0aW9ucyBhcmUgc3VwcG9ydGVkLCB1c2UgdGhlbSBhY3Jvc3MgdGhlIGJvYXJkXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKG9wdGlvbnMgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLmNhcHR1cmUpIHtcbiAgICAvLyB1c2VkIG9ubHkgaW4gdGhlIGZvbGxvd2luZyBjYXNlOlxuICAgIC8vXG4gICAgLy8gYHsgb25jZTogdHJ1ZSB8IGZhbHNlLCBwYXNzaXZlOiB0cnVlIHwgZmFsc2UsIGNhcHR1cmU6IHRydWUgfVxuICAgIC8vXG4gICAgLy8gYG9uY2VgIGlzIGhhbmRsZWQgdmlhIGEgY3VzdG9tIGNhbGxiYWNrIHRoYXQgcmVtb3ZlcyBhZnRlciBmaXJzdFxuICAgIC8vIGludm9jYXRpb24gc28gd2Ugb25seSBjYXJlIGFib3V0IGNhcHR1cmUgaGVyZSBhcyBhIGJvb2xlYW5cbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBjYWxsYmFjaywgdHJ1ZSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gdXNlZCBvbmx5IGluIHRoZSBmb2xsb3dpbmcgY2FzZXM6XG4gICAgLy9cbiAgICAvLyAqIHdoZXJlIHRoZXJlIGlzIG5vIG9wdGlvbnNcbiAgICAvLyAqIGB7IG9uY2U6IHRydWUgfCBmYWxzZSwgcGFzc2l2ZTogdHJ1ZSB8IGZhbHNlLCBjYXB0dXJlOiBmYWxzZSB9XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgY2FsbGJhY2spO1xuICB9XG59XG5cbi8qKlxuICBUaGUgYHt7b259fWAgbW9kaWZpZXIgbGV0cyB5b3UgZWFzaWx5IGFkZCBldmVudCBsaXN0ZW5lcnMgKGl0IHVzZXNcbiAgW0V2ZW50VGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXJdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudFRhcmdldC9hZGRFdmVudExpc3RlbmVyKVxuICBpbnRlcm5hbGx5KS5cblxuICBGb3IgZXhhbXBsZSwgaWYgeW91J2QgbGlrZSB0byBydW4gYSBmdW5jdGlvbiBvbiB5b3VyIGNvbXBvbmVudCB3aGVuIGEgYDxidXR0b24+YFxuICBpbiB0aGUgY29tcG9uZW50cyB0ZW1wbGF0ZSBpcyBjbGlja2VkIHlvdSBtaWdodCBkbyBzb21ldGhpbmcgbGlrZTpcblxuICBgYGBhcHAvY29tcG9uZW50cy9saWtlLXBvc3QuaGJzXG4gIDxidXR0b24ge3tvbiAnY2xpY2snIHRoaXMuc2F2ZUxpa2V9fT5MaWtlIHRoaXMgcG9zdCE8L2J1dHRvbj5cbiAgYGBgXG5cbiAgYGBgYXBwL2NvbXBvbmVudHMvbGlrZS1wb3N0LmpzXG4gIGltcG9ydCBDb21wb25lbnQgZnJvbSAnQGdsaW1tZXIvY29tcG9uZW50JztcbiAgaW1wb3J0IHsgYWN0aW9uIH0gZnJvbSAnQGVtYmVyL29iamVjdCc7XG5cbiAgZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGlrZVBvc3RDb21wb25lbnQgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIHNhdmVMaWtlID0gKCkgPT4ge1xuICAgICAgLy8gc29tZW9uZSBsaWtlcyB5b3VyIHBvc3QhXG4gICAgICAvLyBiZXR0ZXIgc2VuZCBhIHJlcXVlc3Qgb2ZmIHRvIHlvdXIgc2VydmVyLi4uXG4gICAgfVxuICB9XG4gIGBgYFxuXG4gICMjIyBBcmd1bWVudHNcblxuICBge3tvbn19YCBhY2NlcHRzIHR3byBwb3NpdGlvbmFsIGFyZ3VtZW50cywgYW5kIGEgZmV3IG5hbWVkIGFyZ3VtZW50cy5cblxuICBUaGUgcG9zaXRpb25hbCBhcmd1bWVudHMgYXJlOlxuXG4gIC0gYGV2ZW50YCAtLSB0aGUgbmFtZSB0byB1c2Ugd2hlbiBjYWxsaW5nIGBhZGRFdmVudExpc3RlbmVyYFxuICAtIGBjYWxsYmFja2AgLS0gdGhlIGZ1bmN0aW9uIHRvIGJlIHBhc3NlZCB0byBgYWRkRXZlbnRMaXN0ZW5lcmBcblxuICBUaGUgbmFtZWQgYXJndW1lbnRzIGFyZTpcblxuICAtIGNhcHR1cmUgLS0gYSBgdHJ1ZWAgdmFsdWUgaW5kaWNhdGVzIHRoYXQgZXZlbnRzIG9mIHRoaXMgdHlwZSB3aWxsIGJlIGRpc3BhdGNoZWRcbiAgICB0byB0aGUgcmVnaXN0ZXJlZCBsaXN0ZW5lciBiZWZvcmUgYmVpbmcgZGlzcGF0Y2hlZCB0byBhbnkgRXZlbnRUYXJnZXQgYmVuZWF0aCBpdFxuICAgIGluIHRoZSBET00gdHJlZS5cbiAgLSBvbmNlIC0tIGluZGljYXRlcyB0aGF0IHRoZSBsaXN0ZW5lciBzaG91bGQgYmUgaW52b2tlZCBhdCBtb3N0IG9uY2UgYWZ0ZXIgYmVpbmdcbiAgICBhZGRlZC4gSWYgdHJ1ZSwgdGhlIGxpc3RlbmVyIHdvdWxkIGJlIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZCB3aGVuIGludm9rZWQuXG4gIC0gcGFzc2l2ZSAtLSBpZiBgdHJ1ZWAsIGluZGljYXRlcyB0aGF0IHRoZSBmdW5jdGlvbiBzcGVjaWZpZWQgYnkgbGlzdGVuZXIgd2lsbCBuZXZlclxuICAgIGNhbGwgcHJldmVudERlZmF1bHQoKS4gSWYgYSBwYXNzaXZlIGxpc3RlbmVyIGRvZXMgY2FsbCBwcmV2ZW50RGVmYXVsdCgpLCB0aGUgdXNlclxuICAgIGFnZW50IHdpbGwgZG8gbm90aGluZyBvdGhlciB0aGFuIGdlbmVyYXRlIGEgY29uc29sZSB3YXJuaW5nLiBTZWVcbiAgICBbSW1wcm92aW5nIHNjcm9sbGluZyBwZXJmb3JtYW5jZSB3aXRoIHBhc3NpdmUgbGlzdGVuZXJzXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lciNJbXByb3Zpbmdfc2Nyb2xsaW5nX3BlcmZvcm1hbmNlX3dpdGhfcGFzc2l2ZV9saXN0ZW5lcnMpXG4gICAgdG8gbGVhcm4gbW9yZS5cblxuICBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gcGFzc2VkIHRvIGB7e29ufX1gIHdpbGwgcmVjZWl2ZSBhbnkgYXJndW1lbnRzIHRoYXQgYXJlIHBhc3NlZFxuICB0byB0aGUgZXZlbnQgaGFuZGxlci4gTW9zdCBjb21tb25seSB0aGlzIHdvdWxkIGJlIHRoZSBgZXZlbnRgIGl0c2VsZi5cblxuICBJZiB5b3Ugd291bGQgbGlrZSB0byBwYXNzIGFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIHRoZSBmdW5jdGlvbiB5b3Ugc2hvdWxkIHVzZVxuICB0aGUgYHt7Zm59fWAgaGVscGVyLlxuXG4gIEZvciBleGFtcGxlLCBpbiBvdXIgZXhhbXBsZSBjYXNlIGFib3ZlIGlmIHlvdSdkIGxpa2UgdG8gcGFzcyBpbiB0aGUgcG9zdCB0aGF0XG4gIHdhcyBiZWluZyBsaWtlZCB3aGVuIHRoZSBidXR0b24gaXMgY2xpY2tlZCB5b3UgY291bGQgZG8gc29tZXRoaW5nIGxpa2U6XG5cbiAgYGBgYXBwL2NvbXBvbmVudHMvbGlrZS1wb3N0Lmhic1xuICA8YnV0dG9uIHt7b24gJ2NsaWNrJyAoZm4gdGhpcy5zYXZlTGlrZSBAcG9zdCl9fT5MaWtlIHRoaXMgcG9zdCE8L2J1dHRvbj5cbiAgYGBgXG5cbiAgSW4gdGhpcyBjYXNlLCB0aGUgYHNhdmVMaWtlYCBmdW5jdGlvbiB3aWxsIHJlY2VpdmUgdHdvIGFyZ3VtZW50czogdGhlIGNsaWNrIGV2ZW50XG4gIGFuZCB0aGUgdmFsdWUgb2YgYEBwb3N0YC5cblxuICAjIyMgRnVuY3Rpb24gQ29udGV4dFxuXG4gIEluIHRoZSBleGFtcGxlIGFib3ZlLCB3ZSB1c2VkIGFuIGFycm93IGZ1bmN0aW9uIHRvIGVuc3VyZSB0aGF0IGBsaWtlUG9zdGAgaXNcbiAgcHJvcGVybHkgYm91bmQgdG8gdGhlIGBpdGVtcy1saXN0YCwgYnV0IGxldCdzIGV4cGxvcmUgd2hhdCBoYXBwZW5zIGlmIHdlXG4gIGxlZnQgb3V0IHRoZSBhcnJvdyBmdW5jdGlvbjpcblxuICBgYGBhcHAvY29tcG9uZW50cy9saWtlLXBvc3QuanNcbiAgaW1wb3J0IENvbXBvbmVudCBmcm9tICdAZ2xpbW1lci9jb21wb25lbnQnO1xuXG4gIGV4cG9ydCBkZWZhdWx0IGNsYXNzIExpa2VQb3N0Q29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgICBzYXZlTGlrZSgpIHtcbiAgICAgIC8vIC4uLnNuaXAuLi5cbiAgICB9XG4gIH1cbiAgYGBgXG5cbiAgSW4gdGhpcyBleGFtcGxlLCB3aGVuIHRoZSBidXR0b24gaXMgY2xpY2tlZCBgc2F2ZUxpa2VgIHdpbGwgYmUgaW52b2tlZCxcbiAgaXQgd2lsbCAqKm5vdCoqIGhhdmUgYWNjZXNzIHRvIHRoZSBjb21wb25lbnQgaW5zdGFuY2UuIEluIG90aGVyXG4gIHdvcmRzLCBpdCB3aWxsIGhhdmUgbm8gYHRoaXNgIGNvbnRleHQsIHNvIHBsZWFzZSBtYWtlIHN1cmUgeW91ciBmdW5jdGlvbnNcbiAgYXJlIGJvdW5kICh2aWEgYW4gYXJyb3cgZnVuY3Rpb24gb3Igb3RoZXIgbWVhbnMpIGJlZm9yZSBwYXNzaW5nIGludG8gYG9uYCFcblxuICBAbWV0aG9kIG9uXG4gIEBwdWJsaWNcbiovXG5jbGFzcyBPbk1vZGlmaWVyTWFuYWdlciBpbXBsZW1lbnRzIEludGVybmFsTW9kaWZpZXJNYW5hZ2VyPE9uTW9kaWZpZXJTdGF0ZSB8IG51bGwsIG9iamVjdD4ge1xuICBwdWJsaWMgU1VQUE9SVFNfRVZFTlRfT1BUSU9OUzogYm9vbGVhbiA9IFNVUFBPUlRTX0VWRU5UX09QVElPTlM7XG5cbiAgZ2V0RGVidWdOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdvbic7XG4gIH1cblxuICBnZXQgY291bnRlcnMoKTogeyBhZGRzOiBudW1iZXI7IHJlbW92ZXM6IG51bWJlciB9IHtcbiAgICByZXR1cm4geyBhZGRzLCByZW1vdmVzIH07XG4gIH1cblxuICBjcmVhdGUoXG4gICAgX293bmVyOiBPd25lcixcbiAgICBlbGVtZW50OiBTaW1wbGVFbGVtZW50IHwgRWxlbWVudCxcbiAgICBfc3RhdGU6IG9iamVjdCxcbiAgICBhcmdzOiBDYXB0dXJlZEFyZ3VtZW50c1xuICApOiBPbk1vZGlmaWVyU3RhdGUgfCBudWxsIHtcbiAgICByZXR1cm4gbmV3IE9uTW9kaWZpZXJTdGF0ZShlbGVtZW50IGFzIEVsZW1lbnQsIGFyZ3MpO1xuICB9XG5cbiAgZ2V0VGFnKHN0YXRlOiBPbk1vZGlmaWVyU3RhdGUgfCBudWxsKTogVXBkYXRhYmxlVGFnIHwgbnVsbCB7XG4gICAgaWYgKHN0YXRlID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gc3RhdGUudGFnO1xuICB9XG5cbiAgaW5zdGFsbChzdGF0ZTogT25Nb2RpZmllclN0YXRlIHwgbnVsbCk6IHZvaWQge1xuICAgIGlmIChzdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN0YXRlLnVwZGF0ZUZyb21BcmdzKCk7XG5cbiAgICBsZXQgeyBlbGVtZW50LCBldmVudE5hbWUsIGNhbGxiYWNrLCBvcHRpb25zIH0gPSBzdGF0ZTtcblxuICAgIGFkZEV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lLCBjYWxsYmFjaywgb3B0aW9ucyk7XG5cbiAgICByZWdpc3RlckRlc3RydWN0b3Ioc3RhdGUsICgpID0+IHJlbW92ZUV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lLCBjYWxsYmFjaywgb3B0aW9ucykpO1xuXG4gICAgc3RhdGUuc2hvdWxkVXBkYXRlID0gZmFsc2U7XG4gIH1cblxuICB1cGRhdGUoc3RhdGU6IE9uTW9kaWZpZXJTdGF0ZSB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAoc3RhdGUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBzdGFzaCBwcmlvciBzdGF0ZSBmb3IgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lclxuICAgIGxldCB7IGVsZW1lbnQsIGV2ZW50TmFtZSwgY2FsbGJhY2ssIG9wdGlvbnMgfSA9IHN0YXRlO1xuXG4gICAgc3RhdGUudXBkYXRlRnJvbUFyZ3MoKTtcblxuICAgIGlmICghc3RhdGUuc2hvdWxkVXBkYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gdXNlIHByaW9yIHN0YXRlIHZhbHVlcyBmb3IgcmVtb3ZhbFxuICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lLCBjYWxsYmFjaywgb3B0aW9ucyk7XG5cbiAgICAvLyByZWFkIHVwZGF0ZWQgdmFsdWVzIGZyb20gdGhlIHN0YXRlIG9iamVjdFxuICAgIGFkZEV2ZW50TGlzdGVuZXIoc3RhdGUuZWxlbWVudCwgc3RhdGUuZXZlbnROYW1lLCBzdGF0ZS5jYWxsYmFjaywgc3RhdGUub3B0aW9ucyk7XG5cbiAgICBzdGF0ZS5zaG91bGRVcGRhdGUgPSBmYWxzZTtcbiAgfVxuXG4gIGdldERlc3Ryb3lhYmxlKHN0YXRlOiBPbk1vZGlmaWVyU3RhdGUgfCBudWxsKTogT25Nb2RpZmllclN0YXRlIHwgbnVsbCB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IHNldEludGVybmFsTW9kaWZpZXJNYW5hZ2VyKG5ldyBPbk1vZGlmaWVyTWFuYWdlcigpLCB7fSk7XG4iXSwic291cmNlUm9vdCI6IiJ9